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 \*\_ 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