Metadata-Version: 2.3
Name: mark-toc
Version: 0.4.1
Summary: Generate table of contents in Markdown files based on headings
Project-URL: Repository, https://github.com/jmknoble/mark-toc
Author-email: jmknoble <jmknoble@pobox.com>
License: MIT License
        
        Copyright (c) 2017-2024 Jim Knoble
        
        Permission is hereby granted, free of charge, to any person obtaining a copy
        of this software and associated documentation files (the "Software"), to deal
        in the Software without restriction, including without limitation the rights
        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        copies of the Software, and to permit persons to whom the Software is
        furnished to do so, subject to the following conditions:
        
        The above copyright notice and this permission notice shall be included in all
        copies or substantial portions of the Software.
        
        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
        SOFTWARE.
License-File: LICENSE
Keywords: cli,development,markdown,pre-commit,table of contents,text
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Environment :: Other Environment
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Information Technology
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Topic :: Software Development
Classifier: Topic :: Utilities
Requires-Python: >=3.10
Requires-Dist: argcomplete>=1.12.3
Description-Content-Type: text/markdown

# mark-toc

[![EditorConfig-enabled](https://img.shields.io/badge/EditorConfig-enabled-brightgreen?logo=EditorConfig&logoColor=white)](https://editorconfig.org/)
[![pre-commit-enabled](https://img.shields.io/badge/pre--commit-enabled-brightgreen?logo=pre-commit&logoColor=white)](https://github.com/pre-commit/pre-commit)
[![Python-3.6+](https://img.shields.io/badge/Python-3.6+-informational?logo=Python&logoColor=white)](https://www.python.org)
[![CodeStyle-black](https://img.shields.io/badge/CodeStyle-black-informational)](https://github.com/psf/black)
[![pre-commit-hook-included](https://img.shields.io/badge/pre--commit--hook-included-brightgreen?logo=pre-commit&logoColor=white)](#pre-commit-hook)


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.

[begintoc]: #

## Contents

- [Installing](#installing)
- [How to Use](#how-to-use)
- [How Does It Work?](#how-does-it-work)
    - [How Does It Really Work?](#how-does-it-really-work)
    - [Example](#example)
- [Generating the Table of Contents](#generating-the-table-of-contents)
    - [Heading Levels](#heading-levels)
    - [More Options](#more-options)
- [Pre-Commit Hook](#pre-commit-hook)

[endtoc]: # (Generated by mark-toc pre-commit hook)


## Installing

It is recommended to install **mark-toc** either:

- In its own virtual environment (for example, using [uv][]), or
- As a [pre-commit hook](#pre-commit-hook)

Once you have [uv installed][uv-install], 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][CommonMark], 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:

```markdown
# 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:

```markdown
# 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:

```markdown
## 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 sinle `#` character from the
table of contents.

Combined, this looks lik:

    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`:

```yaml
  - repo: https://github.com/jmknoble/mark-toc
    rev: v0.4.0
    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:

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


 [CommonMark]: https://commonmark.org/
 [CommonMark Spec]: https://spec.commonmark.org/
 [GitHub-flavored Markdown]: https://github.github.com/gfm/
 [link reference definitions]: https://spec.commonmark.org/0.29/#link-reference-definitions
 [pre-commit]: https://pre-commit.com/
 [uv]: https://github.com/astral-sh/uv
 [uv-install]: https://docs.astral.sh/uv/getting-started/installation
 [README]: README.md
