#! /bin/bash set -e # Executable command for markdown declare -r MARKDOWN_BIN="markdown -f fencedcode,autolink,alphalist,autolink,footnote,definitionlist" # Directory for input/output declare -r INPUT_DIR=${INPUT_DIR:?ENV \"INPUT_DIR\" is not set} declare -r OUTPUT_DIR=${OUTPUT_DIR:?ENV \"OUTPUT_DIR\" is not set} declare -r ASSET_DIR=${ASSET_DIR:-`pwd`/assets} declare -r TEMPLATE_DIR=${TEMPLATE_DIR:-`pwd`/templates} declare -r RSSFILE=feed.rss declare -r HOST=${HOST:?} # functions {{{ # add indent for each line except
 {{{

indent() {
  indent="$(printf "%${1}s")"
  sed "/^$/ !s/^/${indent}/; /
/!b; :pre; N; /<\/pre>/!b pre"
}

# }}}
# print comment block {{{
comment_block() {
  [ "$comment" = true ] || return 0
  <<-COMMENT cat
	
[Comment on this page]
COMMENT } # }}} # generate html by heredoc from .md file and templates {{{ html() { <<-END_OF_HTML sed '1d;$d' $(echo "$HEAD" | { [ -z "${title}" ] && cat || sed "/^ */c \ \ <title>${title}"; } ) ${HEADER}

$(${MARKDOWN_BIN} | indent 4)
$(comment_block | indent 2)

${FOOTER} END_OF_HTML } # }}} # list of latest posts in markdown format {{{ latest_posts() { (IFS=$'\n'; echo "${index_list[*]}") | sort -r | head -20 | while read date path title; do echo "- [$title](/$path)" done } # }}} # process frontmatter {{{ get_frontmatter() { sed -n '1 {//q; s/"//g; s/://p' } check_frontmatter() { unset title public index type date draft # define local variables for frontmatter while read key value; do export ${key,,}="$value" done <<<"$(get_frontmatter)" # don't process draft after function call test "$draft" != "" && return 1 # skip making index in some cases test "$title" = "" && return 0 test "$public" = false && return 0 test "$index" = false && return 0 test "$type" = demo && return 0 iso8601=$(date --iso --date "${date:-NULL}" 2>/dev/null) test "$iso8601" = "" && return 0 # put frontmatter info into variable "index" if title and date are valid index_list+=("$iso8601 $path $title") } # }}} # remove SGML comments but keep the top one as frontmatter {{{ ignore_comment() { sed '1! { /^$/ d }' } # }}} # RSS Feed {{{ get_channel_item() { path=${1#${OUTPUT_DIR}} <<-ITEM cat $(grep -Po '.+' ${1} | head -1) https://${HOST}${path} $(md5sum ${1} | cut -d' ' -f1) $(date --rfc-email -r ${1}) ITEM } make_rss() { # Use modified time to get latest html files items="$( ls -1t $OUTPUT_DIR/**/**html \ | head -10 \ | while read html_file; do get_channel_item $html_file done \ | indent 2 \ )" <<-RSS cat Dummy Website https://${HOST} $global_description zh-tw $(date --rfc-email) https://www.rssboard.org/rss-specification ${items} RSS } # }}} # }}} # prepare directory for outputs {{{ mkdir -p $OUTPUT_DIR/ rm -rf $OUTPUT_DIR/** ln -s $ASSET_DIR/* $OUTPUT_DIR/ # }}} # content of templates {{{ declare -r HEAD="$(cat $TEMPLATE_DIR/head.html)" declare -r HEADER="$(<$TEMPLATE_DIR/header.html indent 2)" declare -r FOOTER="$(<$TEMPLATE_DIR/footer.html indent 2)" declare -r INDEX_TEMPLATE="$(cat $TEMPLATE_DIR/index.md)" index_list=() # }}} # for each markdown file {{{ files="$(find "$INPUT_DIR" -type f -name '*md')" total=$(wc -l <<<"$files") declare -i counter for file in $files; do # set variables path=$(<<<"$file" sed "s#^${INPUT_DIR}/##; s/\.md$//").html; mkdir -p $(dirname $OUTPUT_DIR/$path) content="$(<${file} ignore_comment)" # use frontmatter to decide making html file or not <<<"$content" check_frontmatter || continue # log echo -e "\033[1K\r$((counter+=1))/$total \t\t processing $path" # add original content to $OUTPUT_DIR # and generate html file with

echo "$content" \ | tee $OUTPUT_DIR/${file#${INPUT_DIR}/} \ | { [ -n "$title" ] && echo "# $title"; cat; } \ | html >$OUTPUT_DIR/$path # Set modified time for index/RSS mtime='@0' [ ! "$public" = false ] && [ -n "$iso8601" ] && mtime="$iso8601" touch -m -d "$mtime" $OUTPUT_DIR/$path unset h1 comment done echo # }}} # make index.html {{{ echo -en "Making\t\tindex.html" export title="" { echo "${INDEX_TEMPLATE}" echo -e '

\n\n' latest_posts } \ | tee $OUTPUT_DIR/index.md \ | html >$OUTPUT_DIR/index.html touch -m -d @0 $OUTPUT_DIR/index.html echo -e "\tgenerated" # }}} # make RSS file {{{ echo -en "Making\t\tRSS" make_rss >$OUTPUT_DIR/$RSSFILE echo -e "\t\tgenerated" # }}} # vim: fdm=marker fdl=0