I am quite a documents aficionado, I take care to make sure any of my projects are well documented and easy to be used in the future, for others and me too – we all forget what we did a year ago especially the small details – that is why I feel the most important part of a project is the documentations.
My favorite document style right now is MarkDown, why is that? well:
- MarkDown is text base meant it can be read (info only) by anyone anywhere without the need for a specific software (although missing a lot of format related stuff like tables).
- The capabilities of MarkDown regarding code segments and links is very easy to perform and the result is easy to read.
- The text based give us easy version control use for the documentations + using bitbucket/github/gitlab you can easily save your entire documentation with structure with easy access.
- It is already widely used in opensource and provided high quality documentations
- Writing the document is easy and fast – My mouse does not need to move to click buttons or I need to remember multiple key combinations to remember how to do something – all is in the syntax.
At this point you might say: “But wait there are better…” – and I will not argue with you – every one with what he likes and prefer (and off curse depend on the needs)
But there is on thing that is missing from markdown is TOC (Table Of Content).
For some unknown reason phrasing engines like github does not provide TOC automatically like you can in any Wiki or Word Document.
So how can you mitigate this issues?
Well there are several solutions out there:
- Use view/edit software like Typora/MarkDown Viewer to see TOC and use it – But this will not work if your file is in
bitbucket/github/gitlab - Use editors like Visual Studio Code/Sublime to generate the TOC
- For who likes VIM editor (my personal favorite) you can use the following vim-markdown-toc
- Or use the CLI way with markdown-toc/summarizeMD
- For more examples see: Markdown to create pages and table of contents?
But wait – what if you don’t have access to any of that?
What if you can’t install any software or use and editor?
For example working with a client computer and not your own – or working on a server to document stuff (another good reason to use MarkDown)
What do you do in a situation like that?
The question above was the one that occupied me so I wrote a very mall program using bash – which will be almost anywhere you look and be (ok ok not windows – unless you have windows 10 with WSL)
So I wrote this little script to generate the TOC in bash:
#!/bin/bash MD_FILE=$1 CODE_SEGMENT=1; cat $MD_FILE | while read line do TRIMMED_LINE=`echo $line | sed 's/^[ \t]*//;s/[ \t]*$//'` ; # Get the line without spaces at the begining or the end if [[ $TRIMMED_LINE == "#"* ]] # Finding all the lines starting with # then if [[ $CODE_SEGMENT -eq 1 ]] # Making sure the # isn't part of code segment then echo $line | sed 's/^[ \t]*//;s/[ \t]*$//' ; # Print the line without start and end spaces fi else if [[ $TRIMMED_LINE == "\`\`\`"* ]] # This If toggle between code segment and regular segment then CODE_SEGMENT=$(($CODE_SEGMENT^1)) fi fi done | grep "^#" | while read line do echo -n $line |sed -e "s/[^#]//g" | sed "s/#/ /g" | head -c -2; # Print Spaces based on the amount of # - 2 spaces for each # and remove the head 2 spaces echo -n "*" ; # Print the * so this will be list echo -n " ["; # Start markdown link syntax echo -n $line |tr -d "#"|sed "s/^ //g"|sed "s/\r//g"|sed "s/\n//g"; # Print the line without # in the biggining | trimming the space in the begining | remove new line echo -n "](#" ; # Continue markdown link syntax echo -n $line | tr -d "#"| tr -d "-" | sed "s/\r//g"|sed "s/\n//g" | sed 's/^[ \t]*//;s/[ \t]*$//'| sed 's/ \+/ /g' | tr " " "-" ; # for more info See below echo ")"; done; # Detailed information about the last line: # # echo -n $line | # Print the line without new line at the end # tr -d "#"| # Remove all "#" Characters # tr -d "-" | # Remove all - characters (links does not support them) # sed "s/\r//g"|sed "s/\n//g" | # Remove the newline in the line # sed 's/^[ \t]*//;s/[ \t]*$//'| # Remove all start end end spaces # sed 's/ \+/ /g' | # Trim all multiple spaces to only one # tr " " "-" ; # Replace all the spaces with "-" (markdown link needs this)"
As you can see in the code it uses only the very basic commands so no matter in which unix based system you are probably gonna be ok with that.
To sweeten the deal I’ve also created oneliner so you can use it in the field with only copy paste
CODE_SEGMENT=1; cat <MD_FILE_NAME> | while read line; do TRIMMED_LINE=`echo $line | sed 's/^[ \t]*//;s/[ \t]*$//'` ; if [[ $TRIMMED_LINE == "#"* ]]; then if [[ $CODE_SEGMENT -eq 1 ]]; then echo $line | sed 's/^[ \t]*//;s/[ \t]*$//' ; fi else if [[ $TRIMMED_LINE == "\`\`\`"* ]]; then CODE_SEGMENT=$(($CODE_SEGMENT^1)); fi; fi; done | grep "^#" | while read line; do echo -n $line |sed -e "s/[^#]//g" | sed "s/#/ /g" | head -c -2; echo -n "*" ; echo -n " ["; echo -n $line |tr -d "#"|sed "s/^ //g"|sed "s/\r//g"|sed "s/\n//g"; echo -n "](#" ; echo -n $line | tr -d "#"| tr -d "-" | sed "s/\r//g"|sed "s/\n//g" | sed 's/^[ \t]*//;s/[ \t]*$//'| sed 's/ \+/ /g' | tr " " "-" ; echo ")"; done;
(Just remember to change <MD_FILE_NAME> with the name of the MD file)
Here is an example:
~$ cat Text.md # Header 1 ## Sub Header 1 ## Sub Header 2 ### Sub Sub Header 1 # Header 2 ``` # Some Comment in the the code ``` ### Sub Sub Header 2 ~$ CODE_SEGMENT=1; cat Text.md | while read line; do TRIMMED_LINE=`echo $line | sed 's/^[ \t]*//;s/[ \t]*$//'` ; if [[ $TRIMMED_LINE == "#"* ]]; then if [[ $CODE_SEGMENT -eq 1 ]]; then echo $line | sed 's/^[ \t]*//;s /[ \t]*$//' ; fi else if [[ $TRIMMED_LINE == "\`\`\`"* ]]; then CODE_SEGMENT=$(($CODE_SEGMENT^1)); fi; fi; done | grep "^#" | while read line; do echo -n $line |sed -e "s/[^#]//g" | sed "s/#/ /g" | head -c -2; echo -n "*" ; echo -n " [" ; echo -n $line |tr -d "#"|sed "s/^ //g"|sed "s/\r//g"|sed "s/\n//g"; echo -n "](#" ; echo -n $line | tr -d "#"| tr -d "-" | sed "s/\r//g"|sed "s/\n//g" | sed 's/^[ \t]*//;s/[ \t]*$//'| sed 's/ \+/ /g' | tr " " "-" ; echo ")"; done; * [Header 1](#Header-1) * [Sub Header 1](#Sub-Header-1) * [Sub Header 2](#Sub-Header-2) * [Sub Sub Header 1](#Sub-Sub-Header-1) * [Header 2](#Header-2) * [Sub Sub Header 2](#Sub-Sub-Header-2)
See in the example above that the script ignore comments in code segments.
Now next time you stuck and need to create a document without any way to use normal software you are one liner away from TOC in MarkDown