# Markdown Table of Contents Maker

> Find Markdown headings outside code blocks, give each included heading an explicit collision-free anchor and download the complete document with one replaceable nested table of contents.

Use it: https://tessalor.com/en/documents/markdown-toc-maker

This tool runs entirely in the browser. Nothing entered into it is uploaded.

## How it is done

1. Normalise line endings and remove only a complete table-of-contents block and anchor lines previously generated by this tool.
2. Scan lines in order, tracking backtick and tilde fences and ignoring four-space or tab-indented code before recognising ATX and Setext headings.
3. Simplify each included heading to a lower-case Unicode slug, then append -2, -3 and later suffixes when normalised names collide.
4. Insert the exact HTML anchor before each included heading and place one marked, nested list after an opening level-one title or at the document start.

## Assumptions

- The selected shallowest level is not deeper than the selected maximum level.
- The scanner targets ordinary CommonMark ATX headings and single-line Setext headings; it is not a full extension-specific Markdown renderer.
- Raw HTML anchors are allowed by the destination renderer. A platform that strips authored HTML will also strip these explicit targets.
- Existing unmarked HTML ids and an incomplete generated marker block are treated as authored content and are never deleted.

## Inputs

| Name | Label | Type | Default | Range |
| --- | --- | --- | --- | --- |
| `document` | Markdown document | textarea | # Field notes

An introduction.

## Equipment

### Camera

## Results

### Camera

##### Lens notes |  |
| `maximumLevel` | Deepest heading level | integer | 4 | 1 to 6 |
| `minimumLevel` | Shallowest heading level | integer | 2 | 1 to 6 |
| `tocHeading` | Table of contents heading | text | Table of contents |  |

## Outputs

- `headingCount` — Headings linked (integer), primary
- `duplicateAnchors` — Duplicate anchors resolved (integer)
- `deepestLevel` — Deepest level included (integer)

## Questions

### Does Markdown define the automatic id for a heading?

No. Core Markdown defines heading structure but not a host's generated fragment slug, and duplicate suffix rules vary. This tool writes explicit ids so its links and targets are part of the same document.

### Will a heading shown inside a code example enter the table?

Not when it is inside a backtick or tilde fence, or an indented code block. The scanner tracks those blocks before testing whether a line has heading syntax.

### Can I regenerate the table after editing headings?

Yes. The generated table has start and end comments and each generated anchor has its own marker. A later run removes those marked parts and builds one current copy.

### Why might a link fail on a publishing platform?

Some platforms sanitise raw HTML and remove authored anchor elements. The Markdown remains readable, but the explicit targets require a renderer that permits ordinary inline HTML.

## Sources

- [CommonMark Specification 0.31.2](https://spec.commonmark.org/0.31.2/) — CommonMark, applies to ATX headings, Setext headings, indented code and fenced code. Retrieved 2026-08-01.
- [The id attribute](https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute) — WHATWG, applies to Explicit HTML link targets. Retrieved 2026-08-01.

## Variants

- [How do I add a table of contents to a Markdown README?](https://tessalor.com/en/documents/markdown-toc-maker/add-table-of-contents-to-readme)
- [How should duplicate Markdown headings be linked?](https://tessalor.com/en/documents/markdown-toc-maker/duplicate-markdown-heading-links)

---

Estimate, not advice. See https://tessalor.com/en/disclaimer.
Machine-readable catalogue: https://tessalor.com/api/tools.json
