diff options
Diffstat (limited to 'src/html')
-rwxr-xr-x | src/html | 174 |
1 files changed, 174 insertions, 0 deletions
diff --git a/src/html b/src/html new file mode 100755 index 0000000..007fcc2 --- /dev/null +++ b/src/html @@ -0,0 +1,174 @@ +#!/bin/sh +set -eu + +usage() { + echo 'Usage: html FILENAME' +} + +FILENAME="${1:-}" +eval "$(assert-arg -- "$FILENAME" 'FILENAME')" + +. "${FILENAME%.*}.conf" + +# +# Utility functions +# + +INDENT=' ' +markdown_to_html() { + md2html | awk -vINDENT="$INDENT" ' + BEGIN { + in_block = 0 + } + + { + if (in_block == 0) { + printf "%s", INDENT + } + print + } + + /^<\/code><\/pre>$/ { + in_block = 0 + } + + /^<pre><code/ { + in_block = 1 + } + ' +} + +extract_plaintext_snippets() ( + SNIPPETS="${FILENAME%.*}.snippets" + printf '' > "$SNIPPETS" + F="$(mkstemp)" + cat > "$F" + IFS='' + BLOCK_NUMBER=0 + IN_BLOCK= + while read -r line; do + if [ "$line" = '</code></pre>' ]; then + IN_BLOCK= + fi + + if [ -n "$IN_BLOCK" ]; then + printf '%s\n' "$line" | htmlesc -d >> "$OUT" + fi + + if printf '%s' "$line" | grep -q "^$INDENT<pre><code"; then + IN_BLOCK=1 + OUT="${FILENAME%.*}.html.$BLOCK_NUMBER.txt" + BLOCK_NUMBER=$((BLOCK_NUMBER + 1)) + printf '%s\n' "$line" | + sed "s|^\($INDENT<pre><code.*>\)\(.*\)$|\2|" | + htmlesc -d > "$OUT" + printf '%s\n' "$OUT" >> "$SNIPPETS" + fi + done < "$F" + + BLOCK_NUMBER=0 + while read -r line; do + printf '%s\n' "$line" + + if [ "$line" = '</code></pre>' ]; then + printf '%s<p class="plaintext-link"><a href="%s">plaintext</a></p>\n' \ + "$INDENT" \ + "$(basename "${url_part:?}").$BLOCK_NUMBER.txt" + BLOCK_NUMBER=$((BLOCK_NUMBER + 1)) + fi + done < "$F" +) + +add_line_numbers() { + awk ' + /^<\/code><\/pre>$/ { + in_block = 0 + printf "</tbody></table>%s\n", $0 + next + } + + match($0, /^( +<pre><code.*>)(.*)$/, a) { + printf "%s<table rules=columns class=\"code-block\"><tbody>", a[1] + + n = 1 + block_count++ + printf "<tr><td class=\"line-number\"><a id=\"B%s-L%s\" href=\"#B%s-L%s\">%s</a></td><td class=\"code-line\">%s</td></tr>\n", block_count, n, block_count, n, n, a[2] + in_block = 1 + next + } + + in_block == 1 { + n++ + printf "<tr><td class=\"line-number\"><a id=\"B%s-L%s\" href=\"#B%s-L%s\">%s</a></td><td class=\"code-line\">%s</td></tr>\n", block_count, n, block_count, n, n, $0 + next + } + + { print } + ' +} + +add_headings_anchors() ( + IFS='' + while read -r line; do + if ! printf '%s' "$line" | grep -q "^$INDENT<h[2-6]>"; then + printf '%s\n' "$line" + continue + fi + LVL="$(printf '%s' "$line" | sed "s|^$INDENT<h\(.\)>.*|\1|")" + HEADING="$(printf '%s' "$line" | sed "s|^$INDENT<h.>\(.*\)</h.>$|\1|")" + SLUG="$(slugify "$HEADING")" + printf '%s<h%s class="header-anchor" id="%s">%s<a href="#%s" aria-hidden="true"><img class="svg-icon" src="%s" /></a></h%s>\n' \ + "$INDENT" \ + "$LVL" \ + "$SLUG" \ + "$HEADING" \ + "$SLUG" \ + "${icon_link_url:?}" \ + "$LVL" + done +) + + +warn_duplicate_ids() { + F="$(mkstemp)" + tee "$F" + { + grep "^$INDENT<h[2-6] class=\"header-anchor\" id=\"" | + sed "s|^$INDENT<h[2-6] class=\"header-anchor\" id=\"\(.*\)\">.*<a href=.*$|\1|" | + sort | + uniq -c | + awk -v F="$FILENAME" '$1 != 1 { + printf "WARNING: duplicate header id: %s: %s\n", F, $2 + }' + } >&2 < "$F" + rm "$F" +} + +emit_body() { + < "${FILENAME%.*}.content" \ + markdown_to_html | + extract_plaintext_snippets | + add_line_numbers | + add_headings_anchors | + warn_duplicate_ids +} + +if [ -r "$FILENAME".prev ]; then + collection_head_prev_html="$( + printf ' <link rel="prev" type="text/html" href="%s" />' \ + "$(url-for < "$FILENAME".prev)" + )" + export collection_head_prev_html +fi + +if [ -r "$FILENAME".next ]; then + collection_head_next_html="$( + printf ' <link rel="next" type="text/html" href="%s" />' \ + "$(url-for < "$FILENAME".next)" + )" + export collection_head_next_html +fi + +envsubst < lib/preamble.html | sed '/^$/d' +emit_body | tee "${FILENAME%.*}.htmlbody" +envsubst < lib/postamble.html | sed '/^$/d' |