boh 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. #!/bin/bash
  2. #
  3. # DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
  4. # Version 2, December 2004
  5. #
  6. # DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
  7. # TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
  8. #
  9. # 0. You just DO WHAT THE FUCK YOU WANT TO.
  10. #
  11. boh_help() {
  12. echo "Usage: boh COMMAND [options...]"
  13. echo "Transform your markdown documents into html"
  14. echo "Options:"
  15. echo " -s, --source [DIR] Source directory (defaults to ./)"
  16. echo " -d, --destination [DIR] Destination directory (defaults to ./_site)"
  17. echo " -l, --layouts [DIR] Layouts directory (defaults to ./_layouts)"
  18. echo "Commands:"
  19. echo " build, b Build your pages"
  20. echo " serve, server, s Serve your pages locally"
  21. echo " new Creates boh basic stuff"
  22. echo " watch Wait for changes then rebuild all the things"
  23. }
  24. boh_new() {
  25. mkdir "$destination_dir" "$layouts_dir"
  26. cat <<EOF > "$layouts_dir/default.html"
  27. <!doctype html>
  28. <html lang="en">
  29. <head>
  30. <meta charset="utf-8">
  31. <title>\$title</title>
  32. </head>
  33. <body>
  34. \$body
  35. </body>
  36. </html>
  37. EOF
  38. }
  39. boh_serve() {
  40. cd "$destination_dir"
  41. python2 -m SimpleHTTPServer $@
  42. }
  43. boh_check() {
  44. if [ ! -d "$layouts_dir" ];then
  45. >&2 echo "'$layouts_dir' directory not found. Maybe you should 'boh new'"
  46. exit 1
  47. fi
  48. type boh_markdown &> /dev/null || {
  49. >&2 echo "'markdown' is not installed"
  50. exit 1
  51. }
  52. type envsubst &> /dev/null || {
  53. >&2 echo "'envsubst' is not installed, install 'gettext' package"
  54. exit 1
  55. }
  56. }
  57. # Parse the yaml frontmatter and returns a string ready for eval
  58. # First sed extract the frontmatter
  59. # Second sed removes frontmatter's delimiter
  60. # Third sed transform yaml in shell evaluable code (lol: asd -> lol="asd")
  61. # Kudos to stackoverflow users for this magic
  62. boh_parse_frontmatter(){
  63. frontmatter=$(cat "$1" | sed -n '1{/^---/{:a N;/\n---/!ba;p}}' | sed '1d;$d' | sed -e 's/:[^:\/\/]/="/g;s/$/"/g;s/ *=/=/g')
  64. echo "$frontmatter"
  65. }
  66. boh_markdown() {
  67. cmark || Markdown.pl
  68. }
  69. boh_build() {
  70. echo "Building all the things..."
  71. rm -rf $destination_dir/*
  72. mkdir -p "$destination_dir"
  73. type boh_pre_build &> /dev/null && { boh_pre_build; }
  74. # extra "/" is used to increment the final count by 1
  75. cut_at=$(echo "/$source_dir" | fold -w 1 | grep -c /)
  76. find "$source_dir" -type f -name "*.md" | while read file
  77. do
  78. layout="default"
  79. title=$(echo "$file" | rev | cut -d / -f 1 | rev | sed s/.md//)
  80. # sed removes the yaml frontmatter
  81. body=$(cat "$file" | sed '1{/^---/{:a N;/\n---/!ba;d}}' | boh_markdown 2>/dev/null)
  82. newpath="$destination_dir/"$(echo "$file" | rev | cut -d . -f 2- | rev | cut -d / -f $cut_at-)".html"
  83. frontmatter=$(boh_parse_frontmatter "$file")
  84. if [ "$frontmatter" ];then
  85. eval "$frontmatter"
  86. fi
  87. mkdir -p "${newpath%/*}"
  88. export title body
  89. envsubst < "$layouts_dir/$layout.html" > "$newpath"
  90. unset title body
  91. done
  92. type boh_post_build &> /dev/null && { boh_post_build; }
  93. echo "Yay!"
  94. }
  95. boh_watch() {
  96. echo "watching $(pwd)"
  97. inotifywait -r -q -e close_write -m --exclude _site/ $(pwd) | while read events
  98. do
  99. boh_check
  100. boh_build
  101. done
  102. }
  103. ## defaults
  104. source_dir="./"
  105. destination_dir="./_site"
  106. layouts_dir="./_layouts"
  107. command=$1
  108. shift
  109. for arg in "$@"
  110. do
  111. case $arg in
  112. -s=*|--source=*)
  113. source_dir="${arg#*=}"
  114. source_dir="$(eval echo ${source_dir//>})"
  115. shift
  116. ;;
  117. -d=*|--destination=*)
  118. destination_dir="${arg#*=}"
  119. destination_dir="$(eval echo ${destination_dir//>})"
  120. shift
  121. ;;
  122. -l=*|--layouts=*)
  123. layouts_dir="${arg#*=}"
  124. layouts_dir="$(eval echo ${layouts_dir//>})"
  125. shift
  126. ;;
  127. *)
  128. ;;
  129. esac
  130. done
  131. if [ -f "$source_dir/boh.config" ];then
  132. source "$source_dir/boh.config"
  133. fi
  134. case $command in
  135. "build"|"b")
  136. boh_check
  137. boh_build
  138. ;;
  139. "new")
  140. boh_new
  141. ;;
  142. "serve"|"server"|"s")
  143. boh_serve $@
  144. ;;
  145. "publish")
  146. type boh_publish &> /dev/null && { boh_publish; }
  147. ;;
  148. "watch")
  149. boh_watch
  150. ;;
  151. *)
  152. boh_help
  153. ;;
  154. esac