Add markdown table-of-contents parser
This commit is contained in:
parent
94834de634
commit
d37a759e3a
89
bin/table_of_contents_markdown.awk
Executable file
89
bin/table_of_contents_markdown.awk
Executable file
|
@ -0,0 +1,89 @@
|
|||
#!/usr/bin/env -S awk -f
|
||||
# Create a table of contents for a markdown file. Respects code blocks!
|
||||
#
|
||||
# ARGS (use these with -v[name]=[value] when calling):
|
||||
# int heading : Indenting level for the "highest" heading. DEFAULT = 1
|
||||
# int table_only : Only print the table of contents. DEFAULT = 0
|
||||
#
|
||||
# EXAMPLE RUN:
|
||||
# $ table_of_contents_markdown.awk -vtable_only=1 -vheading=2 <<HERE
|
||||
# # Main
|
||||
# ## Hello
|
||||
# ### Deep header
|
||||
# ##### 2 deeper
|
||||
# #### 1 deeper
|
||||
# # Section
|
||||
# #### No way
|
||||
# HERE
|
||||
#
|
||||
# EXAMPLE OUTPUT:
|
||||
# # Table of Contents
|
||||
# 1. [Main](#main)
|
||||
# - [Hello](#hello)
|
||||
# * [Deep header](#deep-header)
|
||||
# * [2 deeper](#2-deeper)
|
||||
# * [1 deeper](#1-deeper)
|
||||
# 2. [Section](#section)
|
||||
# * [No way](#no-way)
|
||||
|
||||
# Converts a markdown heading to a pandoc style id
|
||||
# Steps:
|
||||
# 1. Convert to lowercase
|
||||
# 2. Non-word? text is removed
|
||||
# 3. Two or more hyphens in a row are converted to one
|
||||
# 4. Spaces are converted to hyphens
|
||||
# 5. If the same id has already been generated, a unique incrementing number
|
||||
# is appended, starting at 1
|
||||
#
|
||||
# *Gitlab seems to preprend for step 5 instead
|
||||
# *Github seems to skip step 4
|
||||
function heading_to_id(heading, id) {
|
||||
id = tolower(heading);
|
||||
|
||||
gsub(/[^-A-z0-9 ]/, "", id);
|
||||
gsub(/-+/, "-", id);
|
||||
gsub(/ +/, "-", id);
|
||||
|
||||
if (existing_ids[id]++)
|
||||
id = sprintf("%d-%s", existing_ids[id]-1, id);
|
||||
|
||||
return id
|
||||
}
|
||||
|
||||
BEGIN { if (heading == 0) heading = 1; }
|
||||
|
||||
/```/ { is_code_block = !is_code_block }
|
||||
|
||||
/^#+ [^ ].+$/ && !is_code_block {
|
||||
match($0, /#+/);
|
||||
heading_level = RLENGTH
|
||||
s = substr($0, RSTART+RLENGTH+1);
|
||||
|
||||
s = sprintf("[%s](#%s)", s, heading_to_id(s))
|
||||
|
||||
if (heading_level <= heading) {
|
||||
s = sprintf(" %d. %s", ++nb_heading, s);
|
||||
} else if (heading_level == heading + 1) {
|
||||
s = sprintf(" - %s", s);
|
||||
} else {
|
||||
s = " * "s
|
||||
for (i = 0; i < heading_level - heading; i++) s = " "s;
|
||||
}
|
||||
|
||||
table_of_contents[toc++] = s
|
||||
}
|
||||
|
||||
{ file[lines++] = $0 }
|
||||
|
||||
END {
|
||||
for (i = 0; i < heading; i++) printf "#";
|
||||
print " Table of Contents"
|
||||
for (t in table_of_contents)
|
||||
print table_of_contents[t]
|
||||
|
||||
if (!table_only) {
|
||||
print ""
|
||||
for (line in file)
|
||||
print file[line]
|
||||
}
|
||||
}
|
|
@ -1,3 +1,11 @@
|
|||
## Table of Contents
|
||||
1. [Git + SSH = :rocket:](#git-ssh-rocket)
|
||||
2. [Generating ssh keys for git remotes](#generating-ssh-keys-for-git-remotes)
|
||||
3. [User keys](#user-keys)
|
||||
4. [Deployment keys](#deployment-keys)
|
||||
5. [Managing multiple remotes](#managing-multiple-remotes)
|
||||
6. [Further reading](#further-reading)
|
||||
|
||||
# Git + SSH = :rocket:
|
||||
Most git remotes, codeberg and github for example, encourage the use of SSH
|
||||
keys. These are extra-secure ways to manage your project. There are generally
|
||||
|
|
|
@ -1,3 +1,20 @@
|
|||
## Table of Contents
|
||||
1. [Bash](#bash)
|
||||
* [Process priority](#process-priority)
|
||||
* [Job Control in Bash](#job-control-in-bash)
|
||||
* [Vim editing for Bash](#vim-editing-for-bash)
|
||||
* [Stop yourself from deleting files](#stop-yourself-from-deleting-files)
|
||||
* [Reusing commands](#reusing-commands)
|
||||
* [Automated interactive input](#automated-interactive-input)
|
||||
* [Bash scripting](#bash-scripting)
|
||||
* [Other Bash uses](#other-bash-uses)
|
||||
2. [Ed for terminal file editing](#ed-for-terminal-file-editing)
|
||||
3. [Awk the programming language](#awk-the-programming-language)
|
||||
- [Built in variables](#built-in-variables)
|
||||
- [Regular expression](#regular-expression)
|
||||
- [Recipes](#recipes)
|
||||
- [Advanced examples](#advanced-examples)
|
||||
|
||||
# Bash
|
||||
###### Process priority
|
||||
Since the processor must decide priority, it uses a scale from -20 through 20 to
|
||||
|
@ -317,6 +334,3 @@ to check if an element with the string's index has been initialized in the array
|
|||
$ awk '!unique[$0]++' duplicates.txt > uniques.txt
|
||||
Removes duplicate lines. This exploits awk's automatic initialization of
|
||||
variables with falsey values, 0 here, then turns that index truthy with `++`
|
||||
|
||||
|
||||
<!-- ex: set ft=markdown tw=80: -->
|
||||
|
|
Loading…
Reference in a new issue