Markdown Table of Contents Generator
A linked table of contents from a Markdown document’s headings — ATX and setext, code fences skipped — with GitHub-style anchors, chosen levels and numbering.
A nested bullet, numbered or plain list of links to every heading in the levels you chose, anchors that match GitHub’s (with -1, -2 for repeats), section numbers if wanted, and notes on skipped levels.
Example: ## Intro twice and ### Sub `code` give [Intro](#intro), [Intro](#intro-1) and [Sub code](#sub-code); "## Café & Bar!" links to #café--bar; a #### after a ## nests one step, numbered 3.1.
Headings in,
links out.
Which headings are found, how anchors are built, and how the list nests.
Headings
ATX headings (# to ######, optional closing hashes) and setext headings (a line underlined with === or ---) are collected, per CommonMark. Fenced code blocks (``` or ~~~) and YAML front matter are skipped, so a # inside code is not a heading. Inline markup — `code`, **bold**, [links](…) — is stripped from the heading text.
Anchors
GitHub’s rule: lower-case, punctuation removed except hyphens and underscores, every space turned into a hyphen (so "Café & Bar!" becomes café--bar), and repeated headings suffixed -1, -2 … in document order. Other renderers differ on accents, emoji and duplicates; check one link on your platform.
Nesting
Entries are indented by level between the bounds you set; a heading that skips a level (h2 → h4) nests one step, not two, and section numbers follow that nesting. The first h1 is treated as the title and skipped unless you include it. Nothing leaves the browser; the same four anonymous usage counts as the rest of the site apply.
SOURCES
- GitHub heading anchors: lower-case, punctuation removed except - and _, each space → -, duplicates suffixed -1, -2 …; ATX and setext headings per CommonMark, fenced code and front matter skipped
Last reviewed 21 September 2026. How results are checked: How we verify.