Markdown Preview

Write Markdown and see the rendered result as you type. Raw HTML is shown as text rather than executed, and the document never leaves your browser.

All processing happens in your browser. Nothing is uploaded.

标题

这是一段带 粗体斜体行内代码 的文字。

  • 列表项一
  • 列表项二
  • 已完成的任务

引用的内容

列 A列 B
12
const x = 1;

链接

54Words
169Characters
1Headings
1 minReading time

Outline

  • 标题

Raw HTML written inside your Markdown is shown as text rather than rendered. That is deliberate: a preview tool that executes the HTML you paste is a ready-made XSS, and pasted Markdown often comes from somewhere you do not control. Every tag in the output is produced by the parser itself.

Link and image addresses are checked against a protocol allowlist, so javascript: and data: URLs are left as plain text instead of becoming clickable.

How to use

  1. Type or paste Markdown on the left; the preview updates as you type.
  2. On a narrow screen the two panes stack vertically.
  3. Copy HTML takes the fragment; Download HTML saves a complete styled file.
  4. Tick Show generated HTML to inspect the exact output.

About rendering Markdown safely

Markdown was designed to be readable as plain text and to convert cleanly to HTML. The part that is easy to overlook is that the original specification allows raw HTML inside the document — by design, as an escape hatch for things Markdown cannot express. That escape hatch is also the problem.

A preview tool takes text from wherever you paste it and inserts the result into the page as HTML. If raw HTML passes through, then pasting a document containing <script> or <img onerror=...> executes that code in your browser, in the context of the site you are on. This is not hypothetical: it is the standard way Markdown renderers get compromised, and it has produced real vulnerabilities in comment systems, wikis and note-taking apps.

This tool takes the simple position: escape everything first, then apply Markdown syntax. Every angle bracket in your input becomes visible text before any parsing happens, so every tag in the output was generated by the parser itself. Nothing you type can become a tag. The cost is that raw HTML passthrough is not supported, which is a real limitation if that is what you needed — but for a preview tool it is the right trade.

Escaping alone is not enough, though, and this is where a lot of otherwise careful implementations slip. Consider [click me](javascript:alert(1)). There is no tag here for escaping to catch — the syntax is valid Markdown, and a naive renderer produces <a href="javascript:alert(1)">, which runs on click. The defence is a protocol allowlist on link and image addresses: only http, https, mailto, tel, anchors and relative paths are allowed through, and anything else stays as plain text. An allowlist rather than a blocklist matters here, because a blocklist has to anticipate every variation an attacker might try — mixed case, a tab inside the protocol name, a leading null byte — while an allowlist simply does not recognise any of them.

Frequently asked questions

Why is my HTML shown as text instead of being rendered?

Because rendering it would be a security hole. Markdown allows raw HTML, and a preview tool that executes whatever HTML you paste is a ready-made cross-site scripting vulnerability — the Markdown you paste often comes from somewhere you do not control: a README, a chat message, a document someone sent you. This parser escapes every character of the input first and only then applies Markdown syntax, so every tag in the output is one it generated itself. If you need raw HTML passthrough, this is the wrong tool, and that is a deliberate position rather than a missing feature.

Why did my link not become clickable?

Link and image addresses go through a protocol allowlist — http, https, mailto, tel, anchors and relative paths. Anything else, including javascript: and data:, stays as plain text. This blocks the classic [click me](javascript:...) trick, which escaping alone does not: escaping stops tags, not a script hidden in an href.

Is my document uploaded?

No. Parsing happens in your browser and nothing is transmitted. This matters more than it might seem — Markdown is what people write drafts, internal docs and unpublished posts in.

Which Markdown flavour is supported?

The commonly used subset: headings, bold, italic, strikethrough, inline code, fenced code blocks, blockquotes, ordered and unordered lists, task lists, tables, horizontal rules, links, images and autolinks. Deliberately not supported are raw HTML, footnotes, definition lists and reference-style links. Full CommonMark has over six hundred specification test cases; this covers what people actually type, and says so rather than claiming completeness it does not have.

Can I get the HTML out?

Yes — Copy HTML gives you the fragment, and Download HTML gives you a complete standalone file with basic styling included. Tick Show generated HTML to see exactly what the parser produced.

How is reading time calculated?

200 words per minute for Latin text and 300 characters per minute for CJK, added together for mixed documents. It counts the Markdown source, so syntax characters are excluded from the word count but the estimate is still rough — treat it as the difference between a short read and a long one, not a precise figure.