Generate table of contents with anchors for markdown file - Vim plugin Jul 20 2020
Vim is my preferred text editor, and I do most of my writing on markdown. If you haven't used markdown, I encourage you to try it out. Markdown is a simple markup language that is in common use on the internet for static site generators. The syntax is easy to remember; that is probably why I prefer it. One useful improvement to our markdown files is the addition of a tabel of contents. Having a table of contents on my documents is handy, but more than just having the table of content being able to navigate to the sections is even better. In this short article, I'll show you how I accomplish this by using my modified version of the vim-markdown-toc plugin.
Let's get started.
Disclaimer make sure you backup your data before you generate the table of content, I tried my best to make the anchors work correctly, but I can't assure you that the code can't cause any loss of data, use the plugin at your own risk.
Table of contents
What we would like from our table of contents
Generating the table of contents is half the battle. When I write my posts, I want the reader (and me) to be able to navigate to each section from the table of contents easily. There are a few plugins to generate the table of content, but I couldn't find one to create the anchors for each section. So, what do we do when we can't find a solution? We built it.
To generate the table of contents, I use the plugin vim-markdown-toc. I forked the project and added the new functionality, I submitted a pull request, but at the time of writing it is still pending. I suggest you use my fork, you can find it here: rderik/vim-markdown-toc.
Let me show you what I would like my table of contents to look like. Let's imagine we have the following markdown file:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# Introduction
Content
# Section One
Content
# Section two
Content
## Sub-section two - a
Content
# Section three
Content
# Conclusions
Content
After generating my table of contents, I would like to have the following:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# Introduction
Content
* [Section One](#section-one)
* [Section two](#section-two)
* [Sub-section two - a](#sub-section-two-a)
* [Section three](#section-three)
* [Conclusions](#conclusions)
<a name='section-one'></a>
# Section One
Content
<a name='section-two'></a>
# Section two
Content
<a name='sub-section-two-a'></a>
## Sub-section two - a
Content
<a name='section-three'></a>
# Section three
Content
<a name='conclusions'></a>
#Conclusions
Content
Easy enough. I'm adding the anchor in HTML because my markdowns are translated to HTML in the end, and I want it to work on my website. If you need it in another format this solution won't work without modifying the plugin. You could use pandoc(1)
if you don't want to change the plugin.
Ok, let's install and configure my fork of the plugin.
Installing and setup vim-markdown-toc
I use vim-plug to manage my vim plugins, so it's easy to instal the plugin. Add it to your .vimrc
file.
1
2
" Create Table of Content form Markdown files
Plug 'rderik/vim-markdown-toc', { 'branch': 'add-anchors-to-headings/drc2r' }
Currently is in the branch add-anchors-to-headings/drc2r
. If in the future this changes I'll update the post.
Install the Plugin.
1
:PlugInstall
Now we need to configure the plugin with the following variables:
1
2
3
" Vim markdown Table of Contents
let g:vmt_insert_anchors = 1
let g:vmt_auto_update_on_save = 1
I want my table of contents to update automatically on save, but you can do it manually if you prefer. You will have to delete the current Table of contents and generated again, with the following vim
commands.
1
2
:RemoveToc
:GenTocRedcarpet
I use Redcapret as my markdown parser, but the plugin supports others:
-
GenTocGMF
-GFM (GitHub Flavored Markdown) GenTocGitlab
- GitLabGenTocRedcarpet
- Redcarpet
That's it. You don't have to do anything else. Let's test it.
Testing the plugin
Create a markdown file, test.md
and add the following content:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Introduction
Content
# Section One
Content
# Section two
Content
## Sub-section two - a
Content
# Section three
Content
# Conclusions
Content
We are going to insert our table of contents after the content in the introduction (line 4). Go to that line and run:
1
:GenTocRedcarpet
You'll see that each generated code is wrapped inside comments:
1
2
3
<!- - vim-markdown-toc Redcarpet -->
...
<!- - vim-markdown-toc -->
The plugin needs this to identify the data it generates so it can delete it and updated it without confusion.
Ok, that's it. There you have it an easy to use table-of-content-generator for vim, that includes anchors.
Final thoughts
I hope this feature is useful for you as much as it is for me. Makes my writing process easier, and it was fun to code it. If you think someone else would benefit from it, please share. And as always, feedback is welcomed.