Skip to main content

Generate table of contents in Markdown files based on headings

Project description

mark-toc

EditorConfig-enabled pre-commit-enabled Python-3.10+ CodeStyle-ruff pre-commit-hook-included

A Python tool which creates a Table of Contents for a Markdown document using the headings in the document as in-document hypertext link references.

Contents

Installing

It is recommended to install mark-toc either:

Once you have uv installed, you can use it to install mark-toc as follows:

uv tool install mark-toc

How to Use

For a summary of all the available options:

uv tool run mark-toc --help

Or, with the uvx shortcut:

uvx mark-toc --help

Or, if you prefer to call the script directly:

/path/to/mark-toc --help

[!TIP]

There are a number of different ways to run tools that are delivered as Python modules. For the remainder of this document, we will use uvx mark-toc to mean whichever one you prefer for your Python installation and operating environment.

How Does It Work?

mark-toc uses jiggerypokery to interpret and create "pseudo-comments" in the document text which are not rendered in most flavors of Markdown, including GitHub-flavored Markdown.

[!IMPORTANT]

mark-toc only handles the "atx"-style headings beginning with #, not the "setext"-style using "underlines" with = or -.

To insert a table of contents in your document, add the following text, at the beginning of an otherwise blank line and surrounded by blank lines, in the spot where you want the table of contents to appear:

[toc]: #

This is the "table of contents token". For example:

# README

This is the README.

[toc]: #

## More Info

...

Alternatively, you can use a "begin table of contents token" with a matching "end table of contents token":

[begintoc]: #
...
[endtoc]: #

Anything between the "begin" and "end" tokens will be replaced with the generated table of contents.

How Does It Really Work?

The "table of contents token" and begin/end tokens use the link reference definitions feature of Markdown to insert a link definition that is not intended to be referred to anywhere in the document.

As the CommonMark Spec notes:

A link reference definition does not correspond to a structural element of a document. Instead, it defines a label which can be used in reference links and reference-style images elsewhere in the document.

A link consisting of only # is a valid HTML hyperlink target; it refers to an empty fragment in the current document.

Example

This README contains begin/end tokens and serves as an example. You may need to view the "raw" source to see them.

Generating the Table of Contents

Once the token is in your Markdown file, run this script to generate a new document which includes a table of contents in place of the token. For example:

uvx mark-toc INPUTFILE.md

The result is printed to the standard output.

You can rerun this tool using a resulting document as the input, and the existing table of contents will be replaced by a new one in the output.

Heading Levels

By default, mark-toc includes all headings (except for the one starting the table of contents itself) in the resulting table of contents, and it prints the Contents heading as a top-level heading:

# Contents

However, it is not uncommon for Markdown documents on GitHub (like this README, for example) to use a "top-level" heading as the title of the document, and only second-level headings or greater throughout the rest of the document.

You can control what level the Contents heading appears at using the --heading-level option:

uvx mark-toc --heading-level 2 INPUTFILE.md

This results in:

## Contents

You can also control the "lowest" level of headings included in the table of contents using --skip-level. For example, to skip top-level headings, use;

uvx mark-toc --skip-level 1 INPUTFILE.md

This will omit all headings that start with a single # character from the table of contents.

Combined, this looks like:

uvx mark-toc --heading-level 2 --skip-level 1

or:

uvx mark-toc -H 2 -S 1

More Options

mark-toc has more options. There's built-in help:

uvx mark-toc --help

Pre-Commit Hook

mark-toc has built-in support for use with pre-commit as a pre-commit hook. Simply add the following repo and hook to the repos stanza in your .pre-commit-config.yaml:

  - repo: https://github.com/jmknoble/mark-toc
    rev: v0.4.2
    hooks:
      - id: mark-toc

This uses the --pre-commit option to modify Markdown files in place and emit a message when a file is changed.

You can add arguments to the hook using the args keyword; for example:

  - repo: https://github.com/jmknoble/mark-toc
    rev: v0.4.2
    hooks:
      - id: mark-toc
        args: ['--heading-level', '2', '--skip-level', '1']

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mark_toc-0.4.2.tar.gz (36.4 kB view details)

Uploaded Source

Built Distribution

mark_toc-0.4.2-py3-none-any.whl (17.3 kB view details)

Uploaded Python 3

File details

Details for the file mark_toc-0.4.2.tar.gz.

File metadata

  • Download URL: mark_toc-0.4.2.tar.gz
  • Upload date:
  • Size: 36.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for mark_toc-0.4.2.tar.gz
Algorithm Hash digest
SHA256 272604f7c90c3edbe911bf5ad5e2d9170341ef673185991c3d18ed69007c8392
MD5 564a00a74d3335017126bf15bb4b379f
BLAKE2b-256 765a55a57a84e8f38da9c98c54dfbd858b9c6a5c70105744527c5b3bf754d7e4

See more details on using hashes here.

Provenance

The following attestation bundles were made for mark_toc-0.4.2.tar.gz:

Publisher: build.yaml on jmknoble/mark-toc

Attestations:

File details

Details for the file mark_toc-0.4.2-py3-none-any.whl.

File metadata

  • Download URL: mark_toc-0.4.2-py3-none-any.whl
  • Upload date:
  • Size: 17.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for mark_toc-0.4.2-py3-none-any.whl
Algorithm Hash digest
SHA256 decf5f6f40524778cb8197fd280669999972b8ea1ff39e2d63405f6dba526055
MD5 4a8226a5dbeae9296ab1a4bbf8d0336a
BLAKE2b-256 f60cf0a560ba35ecdbccf61cbfe6d47ac05ea5c9efb09dd78d7432f09d0e0da0

See more details on using hashes here.

Provenance

The following attestation bundles were made for mark_toc-0.4.2-py3-none-any.whl:

Publisher: build.yaml on jmknoble/mark-toc

Attestations:

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page