Roberto Aloi
Roberto Aloi

Reputation: 30995

Automatic TOC in github-flavoured-markdown

Is it possible to generate an automatic Table of Contents using Github Flavoured Markdown?

Upvotes: 250

Views: 83260

Answers (21)

maksyche
maksyche

Reputation: 470

I created my own Table of Contents generator script for GitHub markdown in Python. I tried to cover all edge cases like underscores, inline code headers etc.

https://github.com/maksyche/github-md-toc-generator

Not perfect, but works for my projects.

Upvotes: 1

Dogweather
Dogweather

Reputation: 16819

GitHub will automatically create a table of contents in AsciiDoc pages. You can give it a try by (1) changing the page's type to AsciiDoc. Then (2) insert :toc: at the top of the document. Here's the result. I made this demo repo to demonstrate it:

enter image description here

Upvotes: 1

Michael Hall
Michael Hall

Reputation: 3340

Shameless "borrow" of this SO answer.

You can do this with Pandoc.

pandoc -s --toc input.md -o input_toc.md 

Note: the order of the input and output files is important here.

Upvotes: 1

Nguyen
Nguyen

Reputation: 423

Update 2022-02

In VSCode, check out extension "Markdown All in One". It will generate and update the TOC of markdown automatically.

  1. Install Extension.
  2. Place cursor at where you want to insert TOC.
  3. Run command "Markdown All in One: Create Table of Contents"
  4. Enjoy!

Upvotes: 1

Update March 2021: GitHub added an official workaround

READMEs now show a ToC like this as you scroll down into them:

enter image description here

demo: https://github.com/cirosantilli/test-git-web-interface/tree/master/d

It does not render inside the document as I wanted for better Ctrl + F, but it is better than nothing.

Also also works for non-README as well now, e.g.: https://github.com/cirosantilli/test-git-web-interface/blob/master/md.md

They also added a repository setting to enable disable that. It's so weird, who would ever want to disable it? Under https://github.com/cirosantilli/test-git-web-interface/settings Features:

Table of contents

Autogenerate table of contents for Markdown files in this repository. The table of contents will be displayed near the top of the file.

Original answer

It's not possible, except for the workarounds proposed.

I proposed Kramdown TOC extension and other possibilities to support@github.com and Steven! Ragnarök replied with the usual:

Thanks for the suggestion and links. I'll add it to our internal feature request list for the team to see.

Let's upvote this question until it happens.

Another workaround is to use Asciidoc instead of Markdown, which does render TOCs. I've moved to this approach for my content nowadays.

Upvotes: 17

Thorsten Lorenz
Thorsten Lorenz

Reputation: 11847

I created two options to generate a toc for github-flavored-markdown:

DocToc Command Line Tool (source) requires node.js

Installation:

npm install -g doctoc

Usage:

doctoc . to add table of contents to all markdown files in the current and all sub directories.

DocToc WebApp

If you want to try it online first, go to the doctoc site, paste the link of the markdown page and it will generate a table of content that you can insert at the top of your markdown file.

Github Wikis and Anchors

As Matthew Flaschen pointed out in the comments below, for its wiki pages GitHub previously didn't generate the anchors that doctoc depends on.

UPDATE: However, they fixed this issue.

Upvotes: 159

Michael Freidgeim
Michael Freidgeim

Reputation: 28511

Majority of other answers require to install some tool. I found a quick and easy online solution https://imthenachoman.github.io/nGitHubTOC.

For any markdown input it generates table of content output. You can specify minimum and maximum heading level.

The source code is located at https://github.com/imthenachoman/nGitHubTOC

Upvotes: 4

Kevin Suttle
Kevin Suttle

Reputation: 8489

Github Flavored Markdown uses RedCarpet as their Markdown engine. From the RedCarpet repo:

:with_toc_data - add HTML anchors to each header in the output HTML, to allow linking to each section.

It seems in that you'd need to get at the renderer level to set this flag, which isn't possible on Github obviously. However, the latest update to Github Pages, it seems that automatic anchoring is turned on for headers, creating linkable headings. Not exactly what you want, but it might help you create a TOC for your doc a bit easier (albeit manually).

Upvotes: 8

emazzotta
emazzotta

Reputation: 2049

There's now a GitHub Action accomplishing this:

https://github.com/marketplace/actions/toc-generator

  1. Specify location of TOC (option) e.g. README.md
<!-- START doctoc -->
<!-- END doctoc -->
  1. Setup workflow e.g. .github/workflows/toc.yml
on: push
name: TOC Generator
jobs:
  generateTOC:
    name: TOC Generator
    runs-on: ubuntu-latest
    steps:
      - uses: technote-space/toc-generator@v2

Upvotes: 1

John Eikenberry
John Eikenberry

Reputation: 1239

Here's a shell script I threw together today for this. Might need to tweak it for your needs, but it should be a good starting point.

cat README.md \
    | sed -e '/```/ r pf' -e '/```/,/```/d' \
    | grep "^#" \
    | tail -n +2 \
    | tr -d '`' \
    | sed 's/# \([a-zA-Z0-9`. -]\+\)/- [\1](#\L\1)/' \
    | awk -F'(' '{for(i=2;i<=NF;i++)if(i==2)gsub(" ","-",$i);}1' OFS='(' \
    | sed 's/^####/      /' \
    | sed 's/^###/    /' \
    | sed 's/^##/  /' \
    | sed 's/^#//'

If anyone knows a better way to do those final # replacements, please add a comment. I tried various things and wasn't happy with any, so I just brute forced it.

Upvotes: 1

Mayinx
Mayinx

Reputation: 374

For Github's Texteditor Atom check out this awesome plugin (or "package" in Atom-lingo), which generates "TOC (table of contents) of headlines from parsed markdown" files:

markdown-toc

Once installed as Atom-package you can use the shortcut ctrl-alt-c to insert a TOC based on your markdown-doc-structure at the current cursor position...

Screenshots:

enter image description here

Atom Keybindings

markdown-toc gives you the following default key-bindings to control the plugin in Atom:

  • ctrl-alt-c => create TOC at cursor position
  • ctrl-alt-u => update TOC
  • ctrl-alt-r => delete TOC

Plugin Features (from the project's README)

  • Auto linking via anchor tags, e.g. # A 1#a-1
  • Depth control [1-6] with depthFrom:1 and depthTo:6
  • Enable or disable links with withLinks:1
  • Refresh list on save with updateOnSave:1
  • Use ordered list (1. ..., 2. ...) with orderedList:0

Upvotes: 1

Mathias Dpunkt
Mathias Dpunkt

Reputation: 12184

A very convenient way to achieve a table of contents for a mardown file when working with Visual Studio Code is the extension Markdown-TOC.

It can add a toc to existing markdown files and even keep the toc up-to-date on saving.

enter image description here

Upvotes: 10

kenorb
kenorb

Reputation: 166871

Currently it's not possible using markdown syntax (see the ongoing discussion at GitHub), however you can use some external tools such as:


Alternatively use AsciiDoc instead (e.g. README.adoc), e.g.

:toc: macro
:toc-title:
:toclevels: 99
# Title

## A

### A2

## B

### B2

as suggested in this comment. Check the demo here.

Upvotes: 1

Xiaodong Qi
Xiaodong Qi

Reputation: 409

This is a not a direct answer to this question as so many people have provided workarounds. I don't think generating a TOC has been officially supported by Github yet to-date. If you want GitHub to render a Table of Contents on their GFM preview pages automatically, please participate the discussion on the official feature request issue.

Upvotes: 1

Zhuang Ma
Zhuang Ma

Reputation: 623

If you edit Markdown files with Vim, you can try this plugin vim-markdown-toc.

The usage is simple, just move your cursor to the place you want to append Table of Contents and run :GenTocGFM, done!

Screenshots:

vim-markdown-toc

Features:

  1. Generate toc for Markdown files. (Support GitHub Flavored Markdown and Redcarpet)

  2. Update existing toc.

  3. Auto update toc on save.

Upvotes: 16

Rebecca Scott
Rebecca Scott

Reputation: 2431

GitHub Pages (which is basically a wrapper for Jekyll) appears to use kramdown, which implements all of Maruku, and therefore has support for an automatically generated table of contents via atoc attribute:

* auto-gen TOC:
{:toc}

The first line just starts an unordered list and is actually thrown away.

This results in a nested set of unordered lists, using the headers in the document.

Note: this should work for GitHub Pages, not GitHub Flavored Markdown (GFM) as used in comments or wiki pages. AFAIK a solution doesn't exist for that.

Upvotes: 28

Gajus
Gajus

Reputation: 73968

Gitdown is a markdown preprocessor for Github.

Using Gitdown you can:

  • Generate Table of Contents
  • Find dead URLs and Fragment Identifiers
  • Include variables
  • Include files
  • Get file size
  • Generate Badges
  • Print Date
  • Print information about the repository itself

Gitdown streamlines common tasks associated with maintaining a documentation page for a GitHub repository.

Using it is straightforward:

var Gitdown = require('gitdown');

Gitdown
    // Gitdown flavored markdown.
    .read('.gitdown/README.md')
    // GitHub compatible markdown.
    .write('README.md');

You can either have it as a separate script or have it as part of the build script routine (such as Gulp).

Upvotes: 3

Johannes Schindelin
Johannes Schindelin

Reputation: 309

My colleague @schmiedc and I have created a GreaseMonkey script that installs a new TOC button left of the h1 button which uses the excellent markdown-js library to add/refresh a table of contents.

The advantage over solutions like doctoc is that it integrates into GitHub's wiki editor and does not need users to work on their command-line (and require users to install tools like node.js). In Chrome, it works by drag 'n dropping into the Extensions page, in Firefox you will need to install the GreaseMonkey extension.

It will work with plain markdown (i.e. it does not handle code blocks correctly, as that is a GitHub extension to markdown). Contributions welcome.

Upvotes: 1

Cory Klein
Cory Klein

Reputation: 55870

Use coryfklein/doctoc, a fork of thlorenz/doctoc that does not add "generated with DocToc" to every table of contents.

npm install -g coryfklein/doctoc

Upvotes: 2

Mika&#235;l Mayer
Mika&#235;l Mayer

Reputation: 10710

It's not automatic, but it uses Notepad++ regular expressions:

Replace all first by the second (removes all lines not having headers)

^##(#?)(#?)(.*?)$(.|\r|\n)*?(?=^##|\z)
-\1\2 [\3](#\3)\n

Then (converts headers III to spaces)

-##
        -

Then (converts headers II to spaces)

-#
    -

Then (remove unused chars at the beginning and at the end of link title)

\[ *((?:(?![ .:#!\?;]*\])[^#])*)[ #:!\?;]*\]
[\1]

Then (convert last tokens lowercase and dash instead of spaces)

\]([^ \r\n]*) ([^\r\n ]*)
]\L\1-\2

Remove unused final pounds and initial dashes:

(?:()[-:;!\?#]+$|(\]#)-)
\1\2

Remove useless chars in links:

(\].*?)(?:\(|\))
\1

And finally add parenthesis around final links:

\](?!\()(.*?)$
\]\(\1\)

And voilà! You can even put this in a global macro if you repeat it enough time.

Upvotes: 11

Nils
Nils

Reputation: 2071

It is possible to generate a webpage automatically with http://documentup.com/ from the README.md file. It's not creating a TOC, but for many it might solve the reason for wanting to create a TOC.

Another alternative to Documentup is Flatdoc: http://ricostacruz.com/flatdoc/

Upvotes: 4

Related Questions