Skip to content

Instantly share code, notes, and snippets.

@jg-you
Last active July 7, 2020 06:05
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jg-you/aa6ce468601fc11c3d0b to your computer and use it in GitHub Desktop.
Save jg-you/aa6ce468601fc11c3d0b to your computer and use it in GitHub Desktop.
Generate TOC for a markdown file
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @author: Jean-Gabriel Young <jean.gabriel.young@gmail.com>
"""Generate TOC for a markdown file."""
import re
# Match between 1 and 4 #
section = re.compile('^\s*(#){1,4}\s?')
strip_url = re.compile('[\W_]+', re.UNICODE)
def gen_toc(markdown_file):
"""Generate TOC for a markdown file."""
toc_content = []
for l in markdown_file:
match = section.match(l)
if match is not None:
level = match.group().count('#') - 1
title = strip_url.sub(' ', section.sub('', l)).strip()
url = title.replace(' ', '-').lower()
toc_content.append((level, title, url))
toc = []
numerotation = [1, 1, 1, 1]
for item in toc_content:
toc.append(' ' * (item[0]) + str(numerotation[item[0]]) +
". " + "[" + item[1] + "](#" + item[2] + ")")
numerotation[item[0]] += 1
numerotation[item[0] + 1:] = [1] * (3 - item[0])
return toc
if __name__ == "__main__":
# Options parser.
import argparse as ap
import sys
prs = ap.ArgumentParser(description="Generate TOC for a markdown file.")
prs.add_argument('markdown_file', type=str,
help='Markdown file')
if len(sys.argv) == 1:
prs.print_help()
sys.exit(1)
args = prs.parse_args()
with open(args.markdown_file, 'r') as f:
toc = gen_toc(f)
for item in toc:
print(item)

Top level

Sub-section A

Sub-section B

Sub-sub-section B.1

Sub-section C

Sub-sub-section C.1

Sub-sub-section C.2

> python mdown_toc.py mdown_toc_example.md
1. [Top level](#top-level)
1. [Sub section A](#sub-section-a)
2. [Sub section B](#sub-section-b)
1. [Sub sub section B 1](#sub-sub-section-b-1)
3. [Sub section C](#sub-section-c)
1. [Sub sub section C 1](#sub-sub-section-c-1)
2. [Sub sub section C 2](#sub-sub-section-c-2)
@jg-you
Copy link
Author

jg-you commented Jul 6, 2020

If you then run the script, it means it will generate TOCs for all the files in there, right?

No, I setup the main to parse a single file python mdown_toc.py file.md.

You cannot run it on a single file, unless you make a separate folder with just that one test file in it, right?

See above.

Where are the TOCs stored? In a newly created file?

The TOC is generated in the shell, you can copy paste it at the top of the file.

@DutchPete
Copy link

This is my set-up.
I ran the script, python mdown_toc.py, which seems to go well.

Now, when you say "The TOC is generated in the shell, you can copy paste it at the top of the file", I assume by "shell" you mean the terminal, but it is not there.

This is what the terminal shows after running the script:

Last login: Sat Jul  4 13:04:38 on ttys000
Peters-MacBook-Air:~ peter$ cd /Volumes/NO\ NAME/Test
Peters-MacBook-Air:Test peter$ python mdown_toc.py
usage: mdown_toc.py [-h] markdown_file

Generate TOC for a markdown file.

positional arguments:
  markdown_file  Markdown file

optional arguments:
  -h, --help     show this help message and exit
Peters-MacBook-Air:Test peter$ 

as I showed in my previous reply.

So, what is not working?

@jg-you
Copy link
Author

jg-you commented Jul 7, 2020 via email

@DutchPete
Copy link

Many thanks, that worked.

In my case, running ./mdown_toc.py does not work, but python mdown_toc.py does.
Thanks also for your patience.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment