Skip to content
πŸ› οΈToolsShed

Markdown TOC Generator

Generate a linked Table of Contents from markdown headings.

About this tool

A Markdown Table of Contents (TOC) is a navigational list at the top of a document that helps readers quickly jump to specific sections. This generator automatically extracts headings from your Markdown source and creates linked anchors compatible with GitHub, GitLab, and most Markdown renderers. It eliminates the tedious manual work of writing TOC entries and ensures links remain accurate as your document evolves.

Paste your Markdown text and click Generate to instantly create a formatted TOC with working anchor links. The tool supports customizable options: control the maximum heading depth (H1 through H6) to include, and choose your preferred bullet style (hyphens, asterisks, or plus signs). Duplicate headings are automatically detected and numbered with suffixes like #heading-1, #heading-2 to prevent anchor conflicts.

Frequently Asked Questions

Code Implementation

import re

def heading_to_anchor(text: str) -> str:
    """Convert heading text to a GitHub-Flavored Markdown anchor."""
    anchor = text.lower()
    anchor = re.sub(r"[^\w\s-]", "", anchor)   # remove punctuation (keep letters, digits, -, _)
    anchor = re.sub(r"\s+", "-", anchor.strip())  # spaces β†’ hyphens
    return anchor

def generate_toc(markdown: str, max_depth: int = 3, bullet: str = "-") -> str:
    lines = []
    seen: dict[str, int] = {}

    for line in markdown.splitlines():
        m = re.match(r"^(#{1,6})\s+(.*)", line)
        if not m:
            continue
        level = len(m.group(1))
        if level > max_depth:
            continue

        title  = m.group(2).strip()
        anchor = heading_to_anchor(title)

        # Deduplicate: second occurrence β†’ anchor-1, third β†’ anchor-2, ...
        count  = seen.get(anchor, 0)
        seen[anchor] = count + 1
        if count > 0:
            anchor = f"{anchor}-{count}"

        indent = "  " * (level - 1)
        lines.append(f"{indent}{bullet} [{title}](#{anchor})")

    return "\n".join(lines)


md = """# Getting Started
## Installation
### Prerequisites
### Install
## Configuration
## Usage
# Advanced
## Performance
## Security
"""

print(generate_toc(md, max_depth=3, bullet="-"))
# - [Getting Started](#getting-started)
#   - [Installation](#installation)
#     - [Prerequisites](#prerequisites)
#     - [Install](#install)
#   - [Configuration](#configuration)
#   - [Usage](#usage)
# - [Advanced](#advanced)
#   - [Performance](#performance)
#   - [Security](#security)

Comments & Feedback

Comments are powered by Giscus. Sign in with GitHub to leave a comment.