Type `**done**` in a GitHub comment, and it appears as **done**. Add `#` to a README line, and it becomes a heading. Paste the same text elsewhere, and a table may collapse into pipes and dashes. These moments share one idea; understanding it makes them feel predictable. Markdown is plain text that programs convert into HTML (HyperText Markup Language), which browsers display. This article explains why Markdown exists, how renderers process it, why its meaning varies by context, and when it’s unsuitable. ## A Syntax and a Tool Markdown is both a plain-text formatting syntax and a [Perl software tool][df-markdown] that converts it to HTML. John Gruber developed it with Aaron Swartz in 2004, according to the [CommonMark project's history][commonmark]. The original script's final release, Markdown 1.0.1, dates to 17 December 2004. Today the word mostly means the syntax, and dozens of other programs read the same conventions. Here is a short Markdown document: ```markdown ## Release notes The import job is **faster** and skips *empty* rows. * Fixed the date parser. * Added a `--dry-run` flag. Read the [full changelog][changelog]. [changelog]: https://example.com/changelog ``` Even if you've never seen Markdown, you can read it, and Gruber designed it so you could. ## Why Markdown Exists Before Markdown, web writing meant hand-coding HTML or using a rich text editor. HTML hides words in tags: bolding one word yields `The import job is faster.`, while a list requires opening, item, and closing tags. Editors conceal tags but produce markup that's hard to read, compare, or fix. Gruber drew on familiar plain-text formatting. His syntax documentation identifies [plain-text email][df-syntax] as the main inspiration, where people used `*emphasis*` and dashes for lists before renderers supported them. Earlier text-to-HTML filters, including Setext, atx, Textile, and reStructuredText, also influenced it. His strict goal: Markdown files should work as plain text, ready to publish without looking marked up. This explains most of Markdown's choices. A `#` heading and blank-line paragraph break should remain clear in the source, even without rendering. ## How Markdown Works A Markdown file is document source code: a parser builds its structure, and a renderer converts it to HTML. Since most tools combine both, the whole tool is often called a renderer. CommonMark implementations use two broad parsing passes, following the [strategy the CommonMark spec describes][commonmark-spec]: * **Blocks first.** It divides text into blocks—headings, paragraphs, lists, quotes, and code—using blank lines, leading `#` characters, list markers, and indentation to mark boundaries. * **Inlines second.** Within each block, it detects inline structures—emphasis, links, code, and images—marked by `*`, backticks, and square brackets. The two passes build a nested document tree of headings, paragraphs, and inline pieces, which the renderer writes as HTML. The pipeline looks like this: ```mermaid flowchart TB A["Markdown file (plain text)"] --> B["Block pass: headings, paragraphs, lists, code"] B --> C["Inline pass: emphasis, links, code spans"] C --> D["Document tree"] D --> E["HTML"] E --> F["Browser shows the page"] ``` Render the release notes above to get roughly this: ```html
The import job is faster and skips empty rows.
--dry-run flag.Read the full changelog.
``` The source’s final line, `[changelog]: https://...`, is omitted because the renderer treats it as a definition and uses it wherever `[changelog]` appears. A recipe is a useful analogy: Markdown is the readable recipe card, the renderer is the cook, and HTML is the plated dish. Give two cooks the same card, and their dishes will look alike but differ in details. ## Why Markdown Has Flavors Gruber documented the syntax through prose and examples, not a formal grammar, leaving gaps—such as whether lists could follow paragraphs without a blank line or how many spaces nested them. Renderer authors answered differently. The CommonMark project says Gruber's description [does not specify the syntax unambiguously][commonmark]. By 2014, dozens of implementations had diverged: a document could render differently on GitHub wiki and Pandoc. Since 2014, CommonMark has provided a clear specification and self-checking test suite. Its latest version is [0.31.2, dated 28 January 2024][commonmark-spec]. Flavors add features to the shared core that the original lacked: * **GitHub Flavored Markdown (GFM).** GitHub's spec is a [strict superset of CommonMark][gfm], adding tables, task lists (`- [ ]`), strikethrough, bare-URL autolinks, and filtering risky raw HTML tags like `