official-images/toc.sh

75 lines
1.7 KiB
Bash
Executable file

#!/usr/bin/env bash
set -Eeuo pipefail
self="$(basename "$0")"
usage() {
cat <<-EOU
usage: $self path/to/README.md
eg: $self README.md
WARNING: if README.md has the TOC-replacement comments,
README.md.bak will be clobbered and the TOC will be inserted
EOU
}
readme="${1:-}"
if ! shift || [ ! -f "$readme" ]; then usage >&2; exit 1; fi
toc="$(
gawk '
# ignore comments in code blocks, which are not headers but look like them
/^```/ { ignore = !ignore }
/^#/ && !ignore {
level = length($1)
$1 = ""
gsub(/^[[:space:]]|[[:space:]]$/, "")
++levelCounter[level]
for (i in levelCounter) {
if (i > level) {
levelCounter[i] = 0
}
}
prefix = levelCounter[level] ".\t"
for (i = 1; i < level; ++i) {
prefix = "\t" prefix
}
# https://github.com/thlorenz/anchor-markdown-header/blob/56f77a232ab1915106ad1746b99333bf83ee32a2/anchor-markdown-header.js#L20-L30
hash = tolower($0)
gsub(/ /, "-", hash)
gsub(/[\/?!:\[\]`.,()*"'"'"';{}+=<>~\$|#@&–—]/, "", hash)
gsub(/[。?!,、;:“”【】()〔〕[]﹃﹄“ ”‘’﹁﹂—…-~《》〈〉「」]/, "", hash)
printf "%s[%s](#%s)\n", prefix, $0, hash
}
' "$readme"
)"
toFile="${readme}.bak"
gawk -v toFile="$toFile" -v toc="$toc" '
BEGIN { printf "" > toFile }
/^<!-- AUTOGENERATED TOC -->$/ {
inToc = !inToc
seenToc = 1
if (inToc) {
print >> toFile
print "" >> toFile
print toc >> toFile
print "" >> toFile
print >> toFile
}
next
}
!inToc { print >> toFile }
END { if (!seenToc) { close(toFile); printf "" > toFile } }
' "$readme"
if [ -s "$toFile" ]; then
mv "$toFile" "$readme"
else
rm "$toFile"
echo "$toc"
fi