diff options
author | EuAndreh <eu@euandre.org> | 2023-04-05 16:14:00 -0300 |
---|---|---|
committer | EuAndreh <eu@euandre.org> | 2023-04-05 16:14:00 -0300 |
commit | 24e24b49fb6375189cfa527a113eb965087a293a (patch) | |
tree | fc75f8267a22f6473432ee6b07c4013561c303dc /v2/src/bin/html | |
parent | v2: Recove h[2-6] anchor link and icon (diff) | |
download | euandre.org-24e24b49fb6375189cfa527a113eb965087a293a.tar.gz euandre.org-24e24b49fb6375189cfa527a113eb965087a293a.tar.xz |
v2: Support Atom feeds and collection translations
Diffstat (limited to 'v2/src/bin/html')
-rwxr-xr-x | v2/src/bin/html | 219 |
1 files changed, 219 insertions, 0 deletions
diff --git a/v2/src/bin/html b/v2/src/bin/html new file mode 100755 index 0000000..7e6809c --- /dev/null +++ b/v2/src/bin/html @@ -0,0 +1,219 @@ +#!/bin/sh +set -eu + +usage() { + cat <<-'EOF' + Usage: + html FILENAME + html -h + EOF +} + +help() { + cat <<-'EOF' + + + Options: + -h, --help show this message + + FILENAME the name of the input file .md file + + + Process the FILENAME, and generate a full HTML page. + + + Examples: + + Generate the HTML for a pastebin: + + $ html src/a-paste.md > src/a-paste.html + EOF +} + + +for f in "$@"; do + case "$f" in + --) + break + ;; + --help) + usage + help + exit + ;; + *) + ;; + esac +done + +while getopts 'h' flag; do + case "$flag" in + h) + usage + help + exit + ;; + *) + usage >&2 + exit 2 + ;; + esac +done +shift $((OPTIND - 1)) + +. src/lib.sh + +FILENAME="${1:-}" +eval "$(assert_arg "$FILENAME" 'FILENAME')" + + +# shellcheck source=/dev/null +. "${FILENAME%.md}.conf" + +# +# Utility functions +# + +SEEN_SLUGS="$(mkstemp)" +slugify_once() { + SLUG="$(printf '%s' "$1" | slugify)${2:+-$2}" + if grep -q "^$SLUG$" "$SEEN_SLUGS"; then + N="${2:-0}" + N=$((N + 1)) + slugify_once "$1" "$N" + else + printf '%s\n' "$SLUG" >> "$SEEN_SLUGS" + printf '%s' "$SLUG" + fi +} + +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%.md}.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%.md}.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_once "$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 + ) +} + +emit_body() { + < "${FILENAME%.md}.content" \ + markdown_to_html | + extract_plaintext_snippets | + add_line_numbers | + add_headings_anchors +} + +envsubst < src/lib/preamble.html +emit_body | tee "${FILENAME%.md}.htmlbody" +envsubst < src/lib/postamble.html |