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 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
#!/usr/bin/bash
# from https://github.com/Lirt/markdown-toc-bash
# MIT license
FILE=${1:?No file was specified as first argument}
declare -a TOC
CODE_BLOCK=0
CODE_BLOCK_REGEX='^```'
HEADING_REGEX='^#{1,}'
while read -r LINE; do
# Treat code blocks
if [[ "${LINE}" =~ $CODE_BLOCK_REGEX ]]; then
# Ignore things until we see code block ending
CODE_BLOCK=$((CODE_BLOCK + 1))
if [[ "${CODE_BLOCK}" -eq 2 ]]; then
# We hit the closing code block
CODE_BLOCK=0
fi
continue
fi
# Treat normal line
if [[ "${CODE_BLOCK}" == 0 ]]; then
# If we see heading, we save it to ToC map
if [[ "${LINE}" =~ ${HEADING_REGEX} ]]; then
TOC+=("${LINE}")
fi
fi
done < <(grep -v '## Table of Contents' "${FILE}")
echo -e "## Table of Contents\n"
for LINE in "${TOC[@]}"; do
case "${LINE}" in
'#####'*)
echo -n " - "
;;
'####'*)
echo -n " - "
;;
'###'*)
echo -n " - "
;;
'##'*)
echo -n " - "
;;
'#'*)
echo -n "- "
;;
esac
LINK=${LINE}
# Detect markdown links in heading and remove link part from them
if grep -qE "\[.*\]\(.*\)" <<< "${LINK}"; then
LINK=$(sed 's/\(\]\)\((.*)\)/\1/' <<< "${LINK}")
fi
# Special characters (besides '-') in page links in markdown
# are deleted and spaces are converted to dashes
LINK=$(tr -dc "[:alnum:] _-" <<< "${LINK}")
LINK=${LINK/ /}
LINK=${LINK// /-}
LINK=${LINK,,}
LINK=$(tr -s "-" <<< "${LINK}")
# Print in format [Very Special Heading](#very-special-heading)
echo "[${LINE#\#* }](#${LINK})"
done
|