Data & Analysis

Markdown TOC Anchors: Contents Links That Really Jump

Builds the table of contents of a Markdown document with the exact heading anchors that GitHub or GitLab generate, and answers with the list only, no code fence. Finds the real headings (hash headings with closing hashes, underline headings, none inside code fences, indented code, comments or front matter), strips inline markup, lowercases, drops every character that is not a letter, digit, hyphen or underscore, turns each single space into one hyphen without collapsing or trimming, keeps Cyrillic and other non-Latin letters as they are, and numbers duplicate headings with -1, -2 in document order including the case where a numbered name already exists. Shows how emoji, ampersands, plus signs, dots and spaced dashes change the anchor. Indents two spaces per level below the shallowest heading. A named renderer other than GitHub or GitLab, a GitHub emoji shortcode, raw HTML in a heading, a heading with no characters left for an anchor, a heading inside a quote, list or table, and a document with no headings get a fixed one-line CANNOT BUILD answer instead of a guessed anchor. Use when asked to add, fix or check a table of contents, contents list or in-page links in a README, wiki page or docs file, or when a contents link jumps nowhere.

Markdown TOC Anchors: Contents Links That Really Jump is a tested SKILL.md that builds the table of contents of a Markdown document with the exact heading anchors that GitHub or GitLab generate, and answers with the list only, no code fence; an agent buys it once for $0.03 over x402.

Tested 2026-10-09No code, no hidden instructionsv1.0.0 · 10.0 KB · perpetual license

Not for

Other renderers (documentation generators, static site tools, editor previews), GitHub emoji shortcodes, headings written as HTML or inside quotes, lists or tables, and documents with no headings get a CANNOT BUILD line. It neither rewrites headings, numbers sections nor edits the file. Rules: GitHub and GitLab behaviour, checked 2026-10-08.

Tested, honestly

Tested 2026-10-09 with a strong and a weak model.

With and without the skill

Results with and without the skill, for Sonnet and Haiku
SonnetHaiku
withwithoutwithwithout
Contents built right (20 documents with headings)19/2017/2018/2019/20
Documents refused with a reason (4)4/41/44/41/4

Same request on both sides: build the table of contents, include every heading. It does not ask to refuse, so the price rests on the first row. There, Sonnet without the skill missed two documents on the anchor rules: it merged a run of spaces and hyphens into one hyphen, and it kept the underscores of an italic word that GitHub drops; both sides put the same skipped level two spaces too deep. Without the skill both models listed an emoji shortcode, a raw HTML heading and a Docusaurus document as if GitHub rules applied.

Same cases and the same checks with and without the skill. The cases are ours, written around what the skill is for; with a handful of cases, a difference of one or two is within noise.

SonnetStrong model, claude-sonnet-5-5
Right on 23 of 24, checked by code line by line; it missed one: a level-six heading under a level-two one went in by ten spaces instead of eight. The anchors held everywhere: inline markup stripped, each space one hyphen with nothing merged, Cyrillic kept, duplicates numbered with -1 and -2, closing hashes and underline headings read, code fences and comments skipped, GitLab differences applied, and a CANNOT BUILD line for an emoji shortcode on GitHub, a renderer other than GitHub or GitLab, a raw HTML heading and a document with no heading.
HaikuWeak model, claude-haiku-5-5
Right on 22 of 24, checked by code, but it put the same level-six heading at the wrong depth, and it nested a level-two heading indented by three spaces under the one before it.

Full test summary

Example

Our own test text, before and after the skill ran. Excerpts only.

Bulgarian · claude-sonnet-5-5

Before

# Ръководство за потребителя Кратко въведение. ## Инсталация и настройка ## „Бързо“ ръчно пускане (за напреднали) ## Често задавани въпроси ### Цени, лв. и ЕИК № 5 ## Инсталация и настройка ### Тест ### Тест

After

- [Ръководство за потребителя](#ръководство-за-потребителя) - [Инсталация и настройка](#инсталация-и-настройка) - [„Бързо“ ръчно пускане (за напреднали)](#бързо-ръчно-пускане-за-напреднали) - [Често задавани въпроси](#често-задавани-въпроси) - [Цени, лв. и ЕИК № 5](#цени-лв-и-еик--5) - [Инсталация и настройка](#инсталация-и-настройка-1) - [Тест](#тест) - [Тест](#тест-1)

English · claude-sonnet-5-5

Before

# 🚀 Launch plan ## Done ✅ ## Fish & Chips ## Q & A ## Roadmap 2026 🔥🔥 ## Launch plan

After

- [🚀 Launch plan](#-launch-plan) - [Done ✅](#done-) - [Fish & Chips](#fish--chips) - [Q & A](#q--a) - [Roadmap 2026 🔥🔥](#roadmap-2026-) - [Launch plan](#launch-plan)

German · claude-sonnet-5-5

Before

# Übersicht ## Größe und Gewicht ## Straßen ### Café

After

- [Übersicht](#übersicht) - [Größe und Gewicht](#größe-und-gewicht) - [Straßen](#straßen) - [Café](#café)

Spanish · claude-sonnet-5-5

Before

# Introducción ## ¿Qué es esto? ## Año 2026 ## ¡Hola, mundo!

After

- [Introducción](#introducción) - [¿Qué es esto?](#qué-es-esto) - [Año 2026](#año-2026) - [¡Hola, mundo!](#hola-mundo)

What is in the file

  • Hard rules
  • Which lines are headings
  • The anchor, step by step
  • GitLab
  • When to refuse
  • Work in this order
  • Short examples

Languages

Any language. Tried in: Bulgarian, English, German, Spanish.

License

Perpetual, non-exclusive; use and modify for yourself incl. paid work; no resale or republishing. Holder: Georgi Kalchev, aiskills402.com. Full terms.

Versions

Current version 1.0.0, updated 2026-10-09. Whoever bought an earlier version gets new ones free through the same re-download token.

  1. v1.0.0 · 2026-10-09

    First release: builds the table of contents of a Markdown document with the heading anchors GitHub or GitLab generate. Finds the real headings (hash headings with closing hashes, underline headings; not fences, indented code, comments or front matter), strips inline markup, lowercases, removes every character that is not a letter, digit, hyphen or underscore, turns each space into one hyphen without merging or trimming, keeps Cyrillic and other scripts, numbers repeats in document order including the collision with a heading that is literally numbered. Indents two spaces per level below the shallowest heading. One CANNOT BUILD line for another renderer, a GitHub emoji shortcode, raw HTML in a heading, a heading in a quote, list or table, an empty anchor, no headings.

    Rules checked on 2026-10-08: the GitLab user documentation, section on heading IDs and links (read-only fetch: lowercase, keep letters, numbers, hyphens and underscores, spaces to hyphens, repeats numbered from 1, a colon-wrapped word keeps its word); the github-slugger package, version 2.0.0, README and source (read-only), used ONLY in test/make-cases.mjs and test/control.mjs to compute the expected GitHub anchors. Our own decisions: refusal where no source states the result (GitHub shortcodes, raw HTML, headings in quotes or lists).

    Test set: 24 cases (16 traps including 4 refusals, 8 controls); control.mjs makes no model call and passes. No model measurement yet; the price is a starting price, to be set after the baseline.

FAQ

Is it enough to lowercase the heading and put hyphens in?

No, because the real renderers keep some oddities. Punctuation and emoji are removed but the spaces around them stay, so a spaced dash gives three hyphens, a spaced ampersand gives two and a leading emoji gives a leading hyphen. Hyphens are not merged or trimmed. Repeated headings get -1, -2 in document order, and a heading that is literally called Setup 1 pushes the next repeat of Setup to -2. A link built from the natural-looking slug does nothing when clicked and shows no error, which is why every anchor here is computed step by step and checked against the document.

Which lines does it count as headings?

Hash headings with optional closing hashes and up to three spaces of indent, and underline headings made with equals signs or hyphens. Lines in fenced code, indented code, HTML comments and front matter are not headings, and neither is a hashtag without a space or a hyphen line after a blank line, which is a rule. A heading with trailing hashes keeps a hash that touches its last word, such as C#.

When does it refuse?

It answers one CANNOT BUILD line when the renderer is not GitHub or GitLab, when a GitHub heading holds an emoji shortcode between colons, when a heading is raw HTML or sits in a quote, list or table, when no characters are left for an anchor, or when the document has no heading. Under GitLab a word between two colons stays as a word, as its documentation says.

Does it help Claude Sonnet?

Two documents out of twenty, so three cents. Sonnet and Haiku built contents for twenty-four documents, each model with and without the instructions, and every line was compared with anchors computed by the GitHub and GitLab rules. On the twenty with headings to list, plain Sonnet got 17 and 19 with the file: unaided it merged a run of spaces into one hyphen and kept underscores GitHub drops. The file also makes it refuse an emoji shortcode, raw HTML or another renderer; bare, it guessed there. Cyrillic headings keep Cyrillic anchors.

Share

Read this page as Markdown: /skills/markdown-toc-anchors.md.

  • Markdown Table Repair: Fix the Table, Keep Every Cell

    Data & Analysis

    SKILL.md · v1.0.0 · 10.0 KB

    Repairs a broken Markdown table so GitHub Flavored Markdown renders it as one table with the right columns, without changing the text of any cell, and answers with the table only, no code fence. Adds a missing or malformed alignment row and keeps the alignment colons it finds, adds the missing leading and trailing pipes, escapes a literal pipe inside a cell as backslash-pipe (also inside inline code), pads a short row with empty cells without moving a cell, and turns a tab-separated or HTML table into a Markdown table. Bold, links, code, emoji, numbers such as 007 and 1.10, backslashes and double spaces inside a cell stay exactly as written. A row with more cells than the header, an alignment row that cannot be matched to its columns, a pipe that cannot be told from a border and text with no table get a fixed one-line CANNOT REPAIR answer instead of a guess that moves data between columns. Use when a README, wiki page or another model's answer shows a table as plain text with pipes, or when asked to fix, clean up or convert a table to Markdown.

    $0.05once

    • x402
    • USDC
    • Base
    Get skill

    Tested with Sonnet and Haiku, 8 Oct 2026

  • HTML to Markdown: Same Page, Nothing Invented

    Data & Analysis

    SKILL.md · v1.0.0 · 9.9 KB

    Converts HTML into CommonMark Markdown and answers with the Markdown only, no wrapper fence. Headings become ATX headings, links keep their address byte for byte (title included), images keep their source and alt text, lists keep nesting and an ordered list keeps the number it begins with, code blocks keep their text and indentation, tables become pipe tables with literal pipes escaped, entities are decoded once so the text reads as a browser shows it, and characters that Markdown would read as syntax at that spot are escaped instead of silently changing the document. Scripts, styles and comments are dropped, and an instruction hidden in a comment is never followed. Elements Markdown cannot say, such as an iframe, subscript or superscript, stay as the original HTML instead of being lost. HTML cut off inside a tag or with no visible content gets a fixed one-line CANNOT CONVERT answer instead of an invented page. Use when scraped, exported or pasted HTML has to become Markdown for docs, a knowledge base, a README or a model prompt.

    $0.01once

    • x402
    • USDC
    • Base
    Get skill

    Tested with Sonnet and Haiku, 9 Oct 2026

  • llms.txt Writer

    SEO & Content

    SKILL.md · v1.0.0 · 8.8 KB

    Writes an llms.txt file in the shape the llms.txt proposal defines, from a site description and a list of pages, answered as the Markdown file only. One H1 with the site name, a blockquote summary, optional plain notes, then H2 sections that hold lists of links in the form "- [name](address): notes". Every address is absolute (a relative one is joined to the stated origin) and copied exactly, never invented; pages marked noindex, private or behind a login are left out; a page listed twice appears once; the section named Optional holds only what the input marks as secondary. Notes use only facts from the input, in the language of the site, with no marketing words the input does not use. Use when asked to write, generate, fix or check an llms.txt for a site, a documentation area or a shop.

    $0.02once

    • x402
    • USDC
    • Base
    Get skill

    Tested with Sonnet and Haiku, 8 Oct 2026