rivet: a simple static site generator
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

215 lines
5.8 KiB

1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
  1. #!/bin/sh
  2. # Copyright (c) 2020 Alessandro Mauri
  3. #
  4. # Permission is hereby granted, free of charge, to any person obtaining a copy
  5. # of this software and associated documentation files (the "Software"), to deal
  6. # in the Software without restriction, including without limitation the rights
  7. # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. # copies of the Software, and to permit persons to whom the Software is
  9. # furnished to do so, subject to the following conditions:
  10. #
  11. # The above copyright notice and this permission notice shall be included in all
  12. # copies or substantial portions of the Software.
  13. #
  14. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. # SOFTWARE.
  21. set -e
  22. unset SKIP_FOOTER
  23. unset SKIP_HEADER
  24. unset SKIP_LIST
  25. unset VERBOSE
  26. unset PRINT_HELP
  27. unset SKIP_SITEMAP
  28. usage() {
  29. printf "Usage: rivet [-hovelfsu] [-p string] [-o destdir] srcdir domain\n"
  30. printf "\t-h: prints this message\n"
  31. printf "\t-o [destdir]: specifies the output direcotory to be [destdir]\n"
  32. printf "\t-p: [string]: Rename the \"Pages\" section to [string]\n"
  33. printf "\t-v: Makes the script verbose\n"
  34. printf "\t-e: Do not prepend _header.html to .html files\n"
  35. printf "\t-f: Do not prepend _footer.html to .html files\n"
  36. printf "\t-l: Do not generate \"Pages\" section in index.html\n"
  37. printf "\t-s: Do not generate sitemap.xml\n"
  38. printf "\t-u: Makes all references to the url 'http' instead of 'https'\n"
  39. exit 2
  40. }
  41. convert() {
  42. tmpfile="tmpconvfile.tmp"
  43. infile="$1"
  44. outfile="${infile%???}.html"
  45. cp "$infile" "$tmpfile"
  46. # TODO: convert links to .md to .html
  47. lowdown -s -Thtml -o "$outfile" "$tmpfile"
  48. rm -f "$tmpfile" "$infile"
  49. }
  50. # Check dependencies
  51. if ! command -v lowdown > /dev/null; then
  52. echo "lowdown is not installed"
  53. exit
  54. fi
  55. destdir='dst'
  56. prefix='https'
  57. linksec='Pages'
  58. while getopts 'o:vhelfsup:' c
  59. do
  60. case "$c" in
  61. o) destdir=${OPTARG%%\/} ;;
  62. v) VERBOSE=true ;;
  63. h) PRINT_HELP=true ;;
  64. e) SKIP_HEADER=true ;;
  65. l) SKIP_LIST=true ;;
  66. f) SKIP_FOOTER=true ;;
  67. s) SKIP_SITEMAP=true ;;
  68. u) prefix='http' ;;
  69. p) linksec="$OPTARG" ;;
  70. *) ;;
  71. esac
  72. done
  73. shift $((OPTIND - 1))
  74. if ! [ "$1" ] || ! [ "$2" ]; then
  75. echo "Not enough arguments"
  76. usage
  77. fi
  78. src="$1"
  79. srcdir=${src%%\/}
  80. unset src
  81. headerfile=$srcdir/_header.html
  82. footerfile=$srcdir/_footer.html
  83. filelist=filelist.tmp
  84. # Check if index.md is present
  85. if ! [ -e "$srcdir"/index.md ]; then
  86. echo "Missing index.md in $srcdir"
  87. exit 1
  88. fi
  89. # Check header and footer files
  90. if ! [ -e "$headerfile" ]; then
  91. echo "Missing _header.html in $srcdir"
  92. exit 1
  93. fi
  94. if ! [ -e "$footerfile" ]; then
  95. echo "Missing _footer.html in $srcdir"
  96. exit 1
  97. fi
  98. # Remove junk from {header,footer} files
  99. sed -i 's/<header.*>//' "$headerfile"
  100. sed -i 's/<\/header>//' "$headerfile"
  101. sed -i 's/<footer.*>//' "$footerfile"
  102. sed -i 's/<\/footer>//' "$footerfile"
  103. # Remove any junk from the domain eg. [https://]domain.com[/]
  104. url="$(echo "$2" |
  105. sed -e 's/^https*:\/\///' |
  106. sed -e 's/\/$//' |
  107. sed -e 's/[]\/$*.^[]/\\&/g')"
  108. if [ "$PRINT_HELP" ]; then
  109. usage
  110. fi
  111. if [ "$VERBOSE" ]; then
  112. set -x
  113. fi
  114. if ! [ -d "$srcdir" ]; then
  115. echo "Error: missing source direcotry"
  116. usage
  117. fi
  118. rm -rf "$destdir"
  119. mkdir -p "$destdir"
  120. cp -r "$srcdir"/* "$destdir"
  121. rm -f "$destdir"/_header.html "$destdir"/_footer.html
  122. # Generate an ordered (by open time) file list
  123. find "$srcdir" -type f -name "*.md" -exec ls -1t {} + > "$filelist"
  124. sed -i "s,^\/*[^\/]*\/,$destdir/," "$filelist"
  125. # Convert markdown files
  126. while IFS="" read -r file; do
  127. convert "$file"
  128. done < "$filelist"
  129. sed -i 's/\.md$/\.html/' "$filelist"
  130. # Prepare the header
  131. if ! [ "$SKIP_HEADER" ]; then
  132. find "$destdir" -name "*.html" |
  133. while IFS="" read -r file; do
  134. sed -i "/<head>/r $headerfile" "$file"
  135. done
  136. fi
  137. # Prepate the footer
  138. if ! [ "$SKIP_FOOTER" ]; then
  139. tmpfoot="tmpfootfile.tmp"
  140. cp "$footerfile" "$tmpfoot"
  141. sed -i '1s/^/<footer>/' "$tmpfoot"
  142. echo '</footer>' >> "$tmpfoot"
  143. find "$destdir" -name "*.html" |
  144. while IFS="" read -r file; do
  145. sed -i "/<\/body>/r $tmpfoot" "$file"
  146. done
  147. rm -f "$tmpfoot"
  148. fi
  149. # Prepare the sitemap & file list
  150. if ! [ "$SKIP_SITEMAP" ] || ! [ "$SKIP_LIST" ]; then
  151. linklist="linklist.tmp"
  152. rm -f "$linklist" "$destdir"/sitemap.xml
  153. while IFS="" read -r file; do
  154. echo "${file#$destdir/}" >> "$linklist"
  155. done < "$filelist"
  156. if ! [ "$SKIP_LIST" ]; then
  157. tmpfile="linkindex.tmp"
  158. rm -f "$tmpfile"
  159. cat << EOF >> "$tmpfile"
  160. <div id="map">
  161. <h2 id="Pages">$linksec</h2>
  162. EOF
  163. while IFS="" read -r line; do
  164. if echo "$line" | grep -q 'index\.html'; then
  165. continue
  166. fi
  167. title="$(grep -e '^<title>.*<\/title>' "$destdir"/"$line" |
  168. sed -e 's/<title>//' -e 's/<\/title>//')"
  169. if ! [ "$title" ] || echo "$title" | grep -q 'Untitled article'; then
  170. title=${line%?????}
  171. fi
  172. printf "<p><a href=\"%s\">%s</a></p>\n" "$line" "$title" >> "$tmpfile"
  173. done < "$linklist"
  174. echo '</div>' >> "$tmpfile"
  175. sed -i '/<\/body>/i REPLACE' "$destdir"/index.html
  176. sed -i "/^REPLACE/r $tmpfile" "$destdir"/index.html
  177. sed -i 's/^REPLACE//' "$destdir"/index.html
  178. rm -f "$tmpfile"
  179. fi
  180. if ! [ "$SKIP_SITEMAP" ]; then
  181. sed -i -e "s/^/$prefix:\/\/$url\//" "$linklist"
  182. cat << EOF >> "$destdir"/sitemap.xml
  183. <?xml version="1.0" encoding="UTF-8"?>
  184. <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  185. </urlset>
  186. EOF
  187. while IFS="" read -r line; do
  188. sed -i "/<\/urlset>/i \
  189. <url><loc>$line<\/loc><\/url>" "$destdir"/sitemap.xml
  190. done < "$linklist"
  191. sed -i 's/^<url>/\t<url>/' "$destdir"/sitemap.xml
  192. fi
  193. rm -f "$linklist" "$filelist"
  194. fi
  195. exit