I love taking notes in Markdown and lately, I've been using GitHub to write (and store) them.
There are many advantages of using GitHub: accessible on different platforms, online, offline, Markdown support, editor agnostic, versioning, simple structure (files/folders), and free.
However, one thing that is not supported out of the box is generating Table of Contents (TOC). With it, I can organize my notes differently and have many of them into a single Markdown file.
Here is how I generate the Table of Contents for my notes using GitHub Actions.
Prerequisites
- Make
- Docker
- Compose
- GitHub account
- Git
- Terminal
Implementation
My notes repository contains many files and folders but for the purpose of this blog post, I will keep everything as simple as possible. Below is the file structure of an example git repository.
$ tree -a
.
├── .git
│ ├── ...
├── Makefile
├── docker-compose.yml
├── story.md
└── package.json
The repository has one note written in Markdown called story.md
which has some random content.
# Story
## Introduction
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Praesent elementum tincidunt felis, condimentum accumsan nibh imperdiet nec.
Sed cursus justo eu purus rhoncus, id facilisis lorem semper.
## Development
Duis nunc arcu, bibendum quis turpis ut, dapibus feugiat massa.
Sed tempus tortor eget diam porta vulputate. Ut tempor iaculis suscipit.
Morbi scelerisque felis ac justo consectetur luctus.
## Conclusion
Nullam malesuada rutrum gravida. Vivamus sit amet fermentum odio.
Donec tincidunt ex odio, vitae convallis ante posuere nec.
Since generating the Table of Contents is not a default option, I searched for a generator and found DocToc, a NodeJS module.
DocToc: Generates table of contents for markdown files inside local git repository. Links are compatible with anchors generated by github or other sites.
To use DocToc, I created package.json
file and added the module as a development dependency.
{
"name": "mynotes",
"devDependencies": {
"doctoc": "^1.4.0"
}
}
I often use Docker to ensure consistency between different platforms like, in this case, my laptop and GitHub. In the docker-compose.yml
file, I defined a service named node
which will be used to install DocToc and generate the TOC using the latest NodeJS Docker image.
version: '3.7'
services:
node:
image: node
volumes:
- type: bind
source: "."
target: /opt/app
working_dir: /opt/app
The last file is Makefile
which encapsulates the Docker Compose commands. The deps
target downloads the NodeJS Docker image and installs DocToc. The generateTOC
target generates the Table of Contents with DocToc inside a NodeJS Docker container.
deps:
docker-compose pull node
docker-compose run --rm node yarn install
generateTOC:
docker-compose run --rm node yarn doctoc .
Finally, to include the TOC to my notes, I simply run make deps generateTOC
in a terminal. The story.md
file is now updated.
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
**Table of Contents** *generated with [DocToc](https://github.com/thlorenz/doctoc)*
- [Story](#story)
- [Introduction](#introduction)
- [Development](#development)
- [Conclusion](#conclusion)
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
# Story
## Introduction
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Praesent elementum tincidunt felis, condimentum accumsan nibh imperdiet nec.
Sed cursus justo eu purus rhoncus, id facilisis lorem semper.
## Development
Duis nunc arcu, bibendum quis turpis ut, dapibus feugiat massa.
Sed tempus tortor eget diam porta vulputate. Ut tempor iaculis suscipit.
Morbi scelerisque felis ac justo consectetur luctus.
## Conclusion
Nullam malesuada rutrum gravida. Vivamus sit amet fermentum odio.
Donec tincidunt ex odio, vitae convallis ante posuere nec.
Et voilà! I then commit my changes to master
, push, and view them on GitHub.
This works well on a computer where tools like Make, Docker, and Compose are installed. I could even go furter and automate the process with Git Hooks.
However, what if I write on a tablet or directly on GitHub website? The Table of Contents will likely get out of date. Wouldn't be great to get it generated no matter where the notes are written from? GitHub Actions to the rescue!
GitHub Actions
GitHub Actions makes it easy to automate all your software workflows, now with world-class CI/CD. Build, test, and deploy your code right from GitHub. Make code reviews, branch management, and issue triaging work the way you want.
Below is the structure of the example git repository with GitHub Actions included.
$ tree -a
.
├── .git
│ ├── ...
├── .github
│ └── workflows
│ └── generate_toc.yml
├── Makefile
├── docker-compose.yml
├── story.md
└── package.json
I defined a workflow in the .github/workflows/generate_toc.yml
file to generate the Table of Contents whenever I push to master
branch.
name: Generate TOC
on:
push:
branches:
- master
jobs:
generateTOC:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- name: Generate TOC
run: make deps generateTOC
- name: Auto commit
uses: stefanzweifel/git-auto-commit-action@v2.1.0
with:
commit_message: Apply automatic changes - TOC generated
branch: master
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
This workflow checks out the repository on a master
branch push event, runs the command make deps generateTOC
to generate the Table of Contents, and finally, commits the changes automatically to master
with the GitHub Action named git-auto-commit-action.
From the GitHub repository, I can see my Generate TOC workflow being executed.
And see the automated commit with the Table of Contents updated from the workflow right after I updated my notes.
Wrapping Up
I am more than happy that GitHub Actions supports Make, Docker, and Compose. I could develop and test locally some parts of my workflow, and feel confident that they will work on GitHub. And now, I can write my notes from anywhere and get the Table of Contents magically updated. This is a simple use case but there are many Actions that can just be "plug & play" to create more sophisticated workflows.
Liked this blog post? Checkout 3musketeers.io to learn more about how to build, test, and deploy your apps from anywhere, the same way!
Disclaimer: Do your own research before using this solution and do not store sensitive information in plain text on GitHub.
Top comments (0)