#!/bin/bash # Generate HTML from post Markdown source # # Copyright (C) 2019 Mike Gerwitz # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # This script accepts the file name rather than data on stdin because the # filename encodes the post date. # # Note that the `pagetitle' is set to "ignoreme"---it is not used, but is # needed to suppress the warning pandoc produces without suppressing all # warnings. # # Pandoc is used to generate the HTML and includes a (mostly) static header # and footer. Note that this duplicates the date logic in `post2meta', # because that must be run on this output, but the post must also contain # the date, and we want to do all HTML processing now. ## declare -r srcref=https://forge.mikegerwitz.com/mikegerwitz/thoughts/commits/branch/master set -euo pipefail # Pandoc output format and extensions. declare -ra ext=( markdown smart footnotes gfm_auto_identifiers fancy_lists startnum tex_math_dollars ) # Convert extensions to `+'-delimited string. pexts() { local IFS=+ echo "${ext[*]}" } # Wrap h1 in an hgroup along with the post date. # # Sometimes this script is used on things that aren't posts (e.g. normal # pages), in which case a date will be unavailable and the output will be # unchanged. hgroup-wrap() { local -r date=${1?Missing date} local -r file=${2?Missing file} # Abort if this is not a date prefix [[ $date =~ [0-9]{4}-[0-9]{2}-[0-9]{2} ]] || { cat return } local -r repo_href="$srcref/$file" local anchor printf -vanchor '%s' \ "$repo_href" \ "$date" sed '/^

a

'"$anchor"'

}' } # Pre-format Markdown files before they get to Pandoc # # These may be able to be implemented as Pandoc filters, but I haven't had # the time to research that yet. This is actually a fitting real-world # demonstration of incremental development / MVP that I'm writing about at # the time that this comment was written (MyCustomBB Part I)! prefmt() { awk ' triml { gsub( /^ +/, "" ) triml = 0 } # ties { $0 = gensub( /([^\\])~/, "\\1 ", "g" ) } { $0 = gensub( /\\~/, "~", "g" ) } # TeX-style newline removal /%$/ { gsub( /%$/, "" ) printf "%s", $0 triml = 1 next } # reference to the content of the last fence (e.g. if a previous # code block is HTML and we want to render it as an example) /^```/ { gather = !gather if ( gather ) gblock = "" } !/^```/ && gather { gblock = gblock $0 "\n" } !gather && /^ *@LASTFENCE@$/ { print gblock; next } { print } ' } # Generate HTML from post. Note that `pagetitle' is set just to suppress # Pandoc warnings about it missing; it is unused. main() { local -r file=${1?Missing file name} local -r base=$( basename "$file" .md ) local -r date=${base:0:10} pandoc -f"$( pexts )" -thtml5 \ --standalone --template src/pandoc.tpl \ --metadata pagetitle:ignoreme \ --base-header-level=1 \ -B <( src/mkheader post @__PAGE_TITLE__@ ) \ -A src/footer.tpl.htm \ < <( prefmt < "$file" ) \ | src/h12title @__PAGE_TITLE__@ \ | hgroup-wrap "$date" "$file" } main "$@"