-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathmarkdown-toc.sh
executable file
·76 lines (69 loc) · 1.99 KB
/
markdown-toc.sh
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
70
71
72
73
74
75
76
#!/usr/bin/env bash
FILE=${1:?No file was specified as first argument}
declare -a TOC
declare -A TOC_MAP
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)
# Make sure to add "-X" suffix with correct increment for headings that are repeated
INDEX=${TOC_MAP[${LINE}]}
if [[ "${INDEX}" != "" ]]; then
INDEX=$(( INDEX + 1 ))
TOC_MAP[${LINE}]=${INDEX}
echo "[${LINE#\#* }](#${LINK}-${INDEX})"
else
TOC_MAP[${LINE}]=0
echo "[${LINE#\#* }](#${LINK})"
fi
done