#! /bin/bash set -e # Executable command for markdown markdown_bin="markdown -f fencedcode,autolink,alphalist,autolink,footnote,definitionlist" # Directory for input/output input_dir=${input_dir:?ENV \"input_dir\" is not set} output_dir=${output_dir:?ENV \"output_dir\" is not set} assets_dir=${assets_dir:-`pwd`/assets} template_dir=${template_dir:-`pwd`/templates} # 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 } # }}} # use heredoc to generate html from .md file and templates {{{ html() { <<-END_OF_HTML sed '1d;$d' ${head} ${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 } # }}} # print frontmatter from markdown file with format: " " {{{ get_frontmatter() { sed -n '1 {//q; s/"//g; s/://p' } # }}} # process frontmatter {{{ add_index() { unset title public index date draft # define local variables for frontmatter while read key value; do local -r $key="$value" done <<<"$(get_frontmatter)" # don't process draft after function call test "$draft" != "" && return 1 # skip making index in some cases test "$public" = false && return 0 test "$index" = false && return 0 test "$type" = demo && return 0 test "$title" = "" && 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 }' } # }}} # Generate the feed file {{{ make_rss() { echo -n "Making RSS " rssfile=$blog_feed.$RANDOM while [[ -f $rssfile ]]; do rssfile=$blog_feed.$RANDOM; done { pubdate=$(LC_ALL=C date +"$date_format_full") cat <<-EOF ' ' Dummy Websitehttps://topo.tw/index.xml" $global_descriptionen" $pubdate" $pubdate" " EOF n=0 while IFS='' read -r i; do is_boilerplate_file "$i" && continue ((n >= number_of_feed_articles)) && break # max 10 items echo -n "." 1>&3 echo '' get_post_title "$i" echo '$global_url/${i#./}" echo "$global_url/$i" echo "$(get_post_author "$i")" echo "$(LC_ALL=C date -r "$i" +"$date_format_full")" n=$(( n + 1 )) done < <(ls -t ./*.html) echo '' } 3>&1 >"$rssfile" echo "" mv "$rssfile" "$blog_feed" chmod 644 "$blog_feed" } # }}} # }}} # prepare directory for outputs {{{ mkdir -p $output_dir/ rm -rf $output_dir/** ln -s $assets_dir/* $output_dir/ # }}} # content of templates {{{ head="$(cat $template_dir/head.html)" header="$(cat $template_dir/header.html | indent 2)" footer="$(cat $template_dir/footer.html | indent 2)" index_list=() index_template="$(cat $template_dir/index.md)" # }}} # 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" add_index || continue # log echo -e "\033[1K\r$((counter+=1))/$total \t\t processing $path" # make html file for draft h1="$(<<<"$content" get_frontmatter | sed -n 's/^title *//p')" comment="$(<<<"$content" get_frontmatter | sed -n 's/^comment *//p')" # add original content to $output_dir # and generate html file with

echo "$content" \ | tee $output_dir/${file#${input_dir}/} \ | { [ -n "$h1" ] && echo "# $h1"; cat; } \ | html >$output_dir/$path unset h1 comment done echo # }}} # make index.html {{{ { echo "${index_template}" echo -e '

\n\n' latest_posts } \ | tee $output_dir/index.md \ | html >$output_dir/index.html echo -e index.html "\t" generated # }}} # make index.xml {{{ # }}}