Skip to content

Cách Markdown hoạt động ​

Hiểu cách Markdown hoạt động có thể giúp bạn sử dụng công cụ mạnh mẽ này tốt hơn. Chương này sẽ giải thích chi tiết cách Markdown chuyển đổi từ văn bản thuần túy thành tài liệu định dạng đẹp mắt.

Quy trình làm việc cơ bản ​

Quy trình làm việc của Markdown có thể được tóm tắt thành các bước sau:

Tệp nguồn Markdown (.md) → Trình phân tích Markdown → Tài liệu HTML → Kết xuất trình duyệt

1. Viết tệp nguồn Markdown ​

Bạn sử dụng bất kỳ trình soạn thảo văn bản nào để tạo tệp .md, sử dụng cú pháp Markdown để viết nội dung:

markdown
# Tài liệu của tôi

Đây là đoạn văn**quan trọng**

## Ví dụ danh sách

- Mục 1
- Mục 2
- Mục 3

2. Xử lý trình phân tích Markdown ​

Trình phân tích đọc tệp Markdown, nhận dạng các phần tử cú pháp và chuyển đổi thành HTML tương ứng:

html
<h1>Tài liệu của tôi</h1>
<p>Đây là đoạn văn <strong>quan trọng</strong></p>
<h2>Ví dụ danh sách</h2>
<ul>
  <li>Mục 1</li>
  <li>Mục 2</li>
  <li>Mục 3</li>
</ul>

3. Kết xuất trình duyệt ​

HTML được tạo hiển thị dưới dạng tài liệu định dạng trong trình duyệt.

Cơ chế làm việc của trình phân tích ​

Phân tích từ vựng ​

Trình phân tích thực hiện phân tích từ vựng trước, chia nhỏ văn bản Markdown thành các token:

  • # được nhận dạng là token tiêu đề
  • **text** được nhận dạng là token văn bản đậm
  • - item được nhận dạng là token mục danh sách

Phân tích cú pháp ​

Sau đó thực hiện phân tích cú pháp, xây dựng Cây cú pháp trừu tượng (AST):

Tài liệu
├── Tiêu đề(cấp 1): "Tài liệu của tôi"
├── Đoạn văn
│   ├── Văn bản: "Đây là đoạn văn"
│   ├── Văn bản đậm: "quan trọng"
│   └── Văn bản: ""
├── Tiêu đề(cấp 2): "Ví dụ danh sách"
└── Danh sách không có thứ tự
    ├── Mục danh sách: "Mục 1"
    ├── Mục danh sách: "Mục 2"
    └── Mục danh sách: "Mục 3"

Tạo HTML ​

Cuối cùng duyệt qua cây cú pháp, tạo HTML đầu ra tương ứng.

Trình phân tích chính ​

CommonMark ​

  • Tiêu chuẩn - Cung cấp tiêu chuẩn phân tích Markdown thống nhất
  • Định nghĩa nghiêm ngặt - Loại bỏ sự mơ hồ giữa các triển khai khác nhau
  • Hỗ trợ rộng rãi - Được nhiều trình phân tích áp dụng

GitHub Flavored Markdown (GFM) ​

Dựa trên CommonMark, thêm:

  • Hỗ trợ bảng
  • Gạch ngang
  • Danh sách công việc
  • Nhận dạng liên kết tự động
  • Khối mã với tô sáng cú pháp

Trình phân tích khác ​

Trình phân tíchNgôn ngữĐặc điểm
markedJavaScriptNhanh, nhẹ
markdown-itJavaScriptCó thể cắm, hỗ trợ mở rộng
Python-MarkdownPythonTính năng đầy đủ, hệ thống plugin
kramdownRubyHỗ trợ nhiều định dạng đầu ra
PandocHaskellBộ chuyển đổi tài liệu phổ quát

Công cụ kết xuất ​

Kết xuất phía khách hàng ​

Phân tích Markdown trong trình duyệt theo thời gian thực:

javascript
// Sử dụng marked.js
const html = marked.parse('# Hello World');
document.body.innerHTML = html;

Ưu điểm:

  • Không cần xử lý máy chủ
  • Hiệu ứng xem trước thời gian thực
  • Giảm tải máy chủ

Nhược điểm:

  • Phụ thuộc vào JavaScript
  • Không thân thiện với SEO
  • Tải lần đầu chậm

Kết xuất phía máy chủ ​

Tạo HTML trước trên máy chủ:

javascript
// Ví dụ Node.js
const fs = require('fs');
const marked = require('marked');

const markdown = fs.readFileSync('document.md', 'utf8');
const html = marked.parse(markdown);

Ưu điểm:

  • Thân thiện với SEO
  • Tải nhanh
  • Không phụ thuộc vào JavaScript phía khách hàng

Nhược điểm:

  • Chi phí xử lý máy chủ
  • Quản lý bộ nhớ đệm phức tạp

Tạo trang web tĩnh ​

Tạo tất cả các trang trước trong quá trình build:

bash
# Sử dụng VitePress
npm run build

Ưu điểm:

  • Tốc độ tải nhanh nhất
  • SEO tốt nhất
  • Bảo mật cao
  • Dễ triển khai

Nhược điểm:

  • Hỗ trợ nội dung động hạn chế
  • Thời gian build dài

Cơ chế mở rộng ​

Hệ thống plugin ​

Nhiều trình phân tích hỗ trợ mở rộng bằng plugin:

javascript
// Ví dụ plugin markdown-it
const md = require('markdown-it')()
  .use(require('markdown-it-footnote'))
  .use(require('markdown-it-deflist'))
  .use(require('markdown-it-abbr'));

Trình kết xuất tùy chỉnh ​

javascript
// Kết xuất liên kết tùy chỉnh
const renderer = new marked.Renderer();
renderer.link = function(href, title, text) {
  return `<a href="${href}" target="_blank">${text}</a>`;
};

Tối ưu hiệu suất ​

Chiến lược bộ nhớ đệm ​

javascript
const cache = new Map();

function parseMarkdown(content) {
  const hash = generateHash(content);
  if (cache.has(hash)) {
    return cache.get(hash);
  }
  
  const result = marked.parse(content);
  cache.set(hash, result);
  return result;
}

Tải lười ​

javascript
// Chỉ phân tích nội dung trong vùng nhìn thấy
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting) {
      parseAndRender(entry.target);
    }
  });
});

Xử lý luồng ​

javascript
// Phân tích tệp lớn theo luồng
const fs = require('fs');
const { Transform } = require('stream');

const markdownTransform = new Transform({
  transform(chunk, encoding, callback) {
    const html = marked.parse(chunk.toString());
    callback(null, html);
  }
});

fs.createReadStream('large-document.md')
  .pipe(markdownTransform)
  .pipe(fs.createWriteStream('output.html'));

Vấn đề thường gặp ​

1. Vấn đề ngắt dòng ​

Các trình phân tích khác nhau có thể xử lý ngắt dòng khác nhau:

markdown
Dòng 1
Dòng 2        ← Ở đây có thể được phân tích thành cùng một đoạn văn

Dòng 1  
Dòng 2        ← Hai khoảng trắng ở cuối dòng bắt buộc ngắt dòng

Dòng 1

Dòng 2        ← Dòng trống phân cách đoạn văn

2. Trộn HTML ​

markdown
Đây là **Markdown** và <em>HTML</em> được trộn lẫn

Cần chú ý đóng và lồng các thẻ HTML chính xác

3. Thoát ký tự đặc biệt ​

markdown
Ở đây cần thoát \* và \_ ký tự

Trường hợp sử dụng thực tế ​

1. Hệ thống blog ​

Bài viết Markdown → Trình tạo trang web tĩnh → Trang web HTML

2. Trang web tài liệu ​

Tài liệu .md → VitePress/Docusaurus → Tài liệu trực tuyến

3. Tệp README ​

README.md → GitHub/GitLab → Trang chủ dự án

4. Ứng dụng ghi chú ​

Ghi chú Markdown → Kết xuất thời gian thực → Hiển thị văn bản phong phú

Bước tiếp theo ​

Bây giờ bạn đã hiểu cách Markdown hoạt động, bạn có thể:

Được xây dựng bởi www.markdownlang.com