#!/bin/bash # # DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE # Version 2, December 2004 # # DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE # TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION # # 0. You just DO WHAT THE FUCK YOU WANT TO. # boh_help() { echo "Usage: boh COMMAND [options...]" echo "Transform your markdown documents into html" echo "Options:" echo " -s, --source [DIR] Source directory (defaults to ./)" echo " -d, --destination [DIR] Destination directory (defaults to ./_site)" echo " -l, --layouts [DIR] Layouts directory (defaults to ./_layouts)" echo "Commands:" echo " build, b Build your pages" echo " serve, server, s Serve your pages locally" echo " new Creates boh basic stuff" echo " watch Wait for changes then rebuild all the things" } boh_new() { mkdir "$destination_dir" "$layouts_dir" cat < "$layouts_dir/default.html" \$title \$body EOF } boh_serve() { cd "$destination_dir" python2 -m SimpleHTTPServer $@ } boh_check() { if [ ! -d "$layouts_dir" ];then >&2 echo "'$layouts_dir' directory not found. Maybe you should 'boh new'" exit 1 fi type boh_markdown &> /dev/null || { >&2 echo "'markdown' is not installed" exit 1 } type envsubst &> /dev/null || { >&2 echo "'envsubst' is not installed, install 'gettext' package" exit 1 } } # Parse the yaml frontmatter and returns a string ready for eval # First sed extract the frontmatter # Second sed removes frontmatter's delimiter # Third sed transform yaml in shell evaluable code (lol: asd -> lol="asd") # Kudos to stackoverflow users for this magic boh_parse_frontmatter(){ frontmatter=$(cat "$1" | sed -n '1{/^---/{:a N;/\n---/!ba;p}}' | sed '1d;$d' | sed -e 's/:[^:\/\/]/="/g;s/$/"/g;s/ *=/=/g') echo "$frontmatter" } boh_markdown() { cmark || Markdown.pl } boh_build() { echo "Building all the things..." rm -rf $destination_dir/* mkdir -p "$destination_dir" type boh_pre_build &> /dev/null && { boh_pre_build; } # extra "/" is used to increment the final count by 1 cut_at=$(echo "/$source_dir" | fold -w 1 | grep -c /) find "$source_dir" -type f -name "*.md" | while read file do layout="default" title=$(echo "$file" | rev | cut -d / -f 1 | rev | sed s/.md//) # sed removes the yaml frontmatter body=$(cat "$file" | sed '1{/^---/{:a N;/\n---/!ba;d}}' | boh_markdown 2>/dev/null) newpath="$destination_dir/"$(echo "$file" | rev | cut -d . -f 2- | rev | cut -d / -f $cut_at-)".html" frontmatter=$(boh_parse_frontmatter "$file") if [ "$frontmatter" ];then eval "$frontmatter" fi mkdir -p "${newpath%/*}" export title body envsubst < "$layouts_dir/$layout.html" > "$newpath" unset title body done type boh_post_build &> /dev/null && { boh_post_build; } echo "Yay!" } boh_watch() { echo "watching $(pwd)" inotifywait -r -q -e close_write -m --exclude _site/ $(pwd) | while read events do boh_check boh_build done } ## defaults source_dir="./" destination_dir="./_site" layouts_dir="./_layouts" command=$1 shift for arg in "$@" do case $arg in -s=*|--source=*) source_dir="${arg#*=}" source_dir="$(eval echo ${source_dir//>})" shift ;; -d=*|--destination=*) destination_dir="${arg#*=}" destination_dir="$(eval echo ${destination_dir//>})" shift ;; -l=*|--layouts=*) layouts_dir="${arg#*=}" layouts_dir="$(eval echo ${layouts_dir//>})" shift ;; *) ;; esac done if [ -f "$source_dir/boh.config" ];then source "$source_dir/boh.config" fi case $command in "build"|"b") boh_check boh_build ;; "new") boh_new ;; "serve"|"server"|"s") boh_serve $@ ;; "publish") type boh_publish &> /dev/null && { boh_publish; } ;; "watch") boh_watch ;; *) boh_help ;; esac