CruxDevCruxDev Tools Studio Prompts
text Utility • Zero-Server Privacy • 100% Client-Side

Markdown Table of Contents Generator

Generate a linked table of contents for any Markdown file or README with GitHub-compatible heading anchors, depth limits and bullet or numbered style.

Overview

Builds a linked table of contents for a Markdown file or GitHub README. It reads every heading, creates the same anchor slugs GitHub or GitLab generate, numbers duplicate headings, and outputs a nested bullet or numbered list you can copy or insert straight into the document between toc markers. Your Markdown is processed in the browser.

How It Works

Paste Markdown or open a .md file and the table of contents updates live. Choose the heading levels to include, from H1 to H6, the anchor style for GitHub or GitLab, two or four spaces of indentation, and bullets or numbers. By default the first H1 is skipped because it is usually the title, and so is a heading called Table of Contents. Insert into document writes the list into your Markdown, ready to copy or download as README.md.

Step-by-Step Usage Guide

  1. Paste your README or open a Markdown file.
  2. Set the from and to heading levels, for example H2 to H3.
  3. Choose GitHub or GitLab anchors, the indent width and bullets or numbers.
  4. Check the heading count under the list to confirm nothing was missed.
  5. Copy the list, or click Insert into document and download the updated README.md.

Technical Specifications & Standards

Headings are found the way a CommonMark parser finds them. ATX headings start with one to six # characters and may have closing hashes, which are removed; setext headings are a line of text underlined with = for level one or - for level two. Lines inside ``` or ~~~ fenced code blocks, indented code blocks and YAML front matter are ignored, so a # comment in a shell example never ends up in the list. Inline Markdown is stripped from the heading text: links and images keep their label, and backticks, bold, italics and strikethrough markers are removed, so the entry reads as the heading renders. Anchors follow GitHub's algorithm: lowercase the text, delete punctuation other than hyphens and underscores, and turn each space into a hyphen, which is why Usage & Examples becomes #usage--examples with two hyphens. The second heading with the same slug gets -1, the third -2. GitLab mode also collapses repeated hyphens. The list is indented relative to the shallowest included level, and inserting wraps it in <!-- toc --> and <!-- tocstop --> comments so a second run replaces the old list.

Targeted Use Cases

  • Adding a clickable contents section to a long GitHub README.
  • Keeping the contents of project documentation in sync after renaming sections.
  • Generating a numbered outline of a Markdown design document or RFC.
  • Building navigation for a GitLab wiki page with GitLab-style anchors.

Notes & Gotchas

  • Limit the list to H2 and H3 for READMEs; deeper levels make the contents longer than the sections.
  • Keep the toc and tocstop markers in the file so regenerating replaces the list in place.
  • Rename duplicate headings such as two FAQ sections, because numbered anchors change when sections move.
  • Regenerate after every heading rename, since the anchor is derived from the heading text.

Frequently Asked Questions

How do I add a table of contents to a GitHub README?

Paste the README, keep GitHub anchors and the H2 to H3 range, click Insert into document, then copy the result back into README.md. GitHub turns each heading into an anchor with the same slug, so every link jumps to its section.

Why does my anchor have two hyphens?

GitHub deletes punctuation but keeps the spaces on either side of it, and each space becomes a hyphen. A heading like Install & Run therefore links to #install--run, and this generator matches that exactly.

Are headings inside code blocks included?

No. Lines inside fenced code blocks marked with backticks or tildes, indented code blocks and YAML front matter are skipped, so comments that start with # in shell or Python examples never become entries.

What happens with two headings that have the same text?

The first keeps the plain slug and later ones get -1, -2 and so on, the same numbering GitHub uses, so each entry still points at the right section.

Can I update an existing table of contents?

Yes. If the document already contains <!-- toc --> and <!-- tocstop --> (or <!-- /toc -->) comments, inserting replaces everything between them. Otherwise the list goes after the first H1 heading, or at the top when there is none.

Related tools

  • README Generator - Scaffold professional README.md files with badges, sections, and table of contents from a form.
  • Markdown Preview - Write Markdown with live side-by-side HTML preview. Supports GFM tables, code blocks, and more.
  • Markdown → HTML Converter - Convert Markdown to clean HTML. Preview rendered output and copy the raw HTML.
  • Markdown Table Generator - Build Markdown tables visually with column alignment control and copy-ready GFM output.
  • HTML Table Extractor (→ CSV / JSON / Markdown) - Paste HTML and pull every table out as clean CSV, JSON, or a Markdown table - header detection, captions, and multi-table picking included.
  • HTML to Markdown Converter - Convert HTML into clean GitHub-flavored Markdown - headings, links, images, lists, code blocks, and tables - with Markdown-significant characters safely escaped.