#!/usr/bin/env bash set -o errexit : ${language=en} : ${charset=utf-8} : ${viewport='width=device-width'} --language() { language=$1; } --attributes() { attributes+=" $1"; } --charset() { charset=$1; } --viewport() { viewport=$1; } preamble=(language attributes charset viewport) is-preamble-keyword() { printf '%s\n' ${preamble[*]} | grep "^$1\$" >/dev/null; } maybe-insert-preamble() if ! `is-preamble-keyword $1`; then head+=("$(printf "$charset_tag" "$charset")") head+=("$(printf "$viewport_tag" "$viewport")") maybe-insert-preamble() { :; } for x in ${preamble[*]}; do eval 'function --'$x' { echo >&2 $0: '$x' must come first; }' done; fi : ${html_tag:=''} : ${charset_tag:=''} : ${viewport_tag:=''} : ${title_tag:='%s'} : ${javascript_tag:=''} : ${stylesheet_tag:=''} --head() { head+=("$1"); } --body() { body+=("$1"); } --foot() { foot+=("$1"); } --title() { --head "$(printf "$title_tag" "$1")"; } --stylesheet() { --head "$(printf "$stylesheet_tag" "$1")"; } --javascript() { --foot "$(printf "$javascript_tag" "$1")"; } --asset() case "$1" in *.css) --stylesheet "$1";; *.js) --javascript "$1";; *) echo >&2 "$0: $1: ignoring unknown asset";; esac while read keyword words; do if [[ $keyword ]]; then keyword=$(echo $keyword | tr A-Z a-z | sed 's/:$//') [[ $words ]] || words=$keyword keyword=asset if type >&/dev/null -- "--$keyword"; then maybe-insert-preamble $keyword --$keyword "${words[@]}" elif [[ $keyword != '#' ]]; then echo >&2 "$0: unknown keyword \`$keyword'"; fi else while read line; do --body "$line"; done; fi; done maybe-insert-preamble body=("${body[@]}" "${foot[@]}") sed 's/^ *$//' < `printf "$html_tag" "$language" "$attributes"` `[[ $head ]] && printf '\n %s' "${head[@]}"` `[[ $body ]] && printf '\n %s' "${body[@]}"` EOF