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ệt1. 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:
# 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 32. 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:
<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ích | Ngôn ngữ | Đặc điểm |
|---|---|---|
| marked | JavaScript | Nhanh, nhẹ |
| markdown-it | JavaScript | Có thể cắm, hỗ trợ mở rộng |
| Python-Markdown | Python | Tính năng đầy đủ, hệ thống plugin |
| kramdown | Ruby | Hỗ trợ nhiều định dạng đầu ra |
| Pandoc | Haskell | Bộ 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:
// 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ủ:
// 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:
# 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:
// 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
// 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
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
// 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
// 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:
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ăn2. Trộn HTML
Đây là **Markdown** và <em>HTML</em> được trộn lẫnCần chú ý đóng và lồng các thẻ HTML chính xác
3. Thoát ký tự đặc biệt
Ở đâ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 HTML2. Trang web tài liệu
Tài liệu .md → VitePress/Docusaurus → Tài liệu trực tuyến3. Tệp README
README.md → GitHub/GitLab → Trang chủ dự án4. Ứ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ể: