diff options
-rw-r--r-- | Makefile | 22 | ||||
-rwxr-xr-x | bin/ssg | 113 | ||||
-rw-r--r-- | bin/ssg-template | 166 | ||||
-rw-r--r-- | templates/_metadata.md | 3 | ||||
-rw-r--r-- | templates/default.html | 15 | ||||
-rw-r--r-- | templates/footer.md | 1 | ||||
-rw-r--r-- | templates/head.html | 4 | ||||
-rw-r--r-- | templates/header.md | 8 |
8 files changed, 332 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..def4abd --- /dev/null +++ b/Makefile @@ -0,0 +1,22 @@ +.POSIX: + +BIN := ./bin +SRC := ./src +OUT := ./out +TMP := ./tmp +BASE_URL = https://rgoncalves.se + +.PHONY: all \ + website \ + clean + +all: clean website + +website: clean + BASE_URL=$(BASE_URL) $(BIN)/ssg + +local: clean + BASE_URL=$$PWD/$(OUT) $(BIN)/ssg + +clean: + - rm -r $(OUT) $(TMP)/* @@ -0,0 +1,113 @@ +#!/bin/sh + +TEMPLATE="templates/default.html" +STATIC_DIRS="style img" +TMP_FILE=".tmp" +SRC="src" +OUT="out" +#BASE_URL="" + +. ./bin/ssg-template + +_log() { + echo [${0}] $@ +} + +_to_html() { + # 1: filename + # stdout: content + lowdown --html-no-skiphtml --html-no-escapehtml "${1}" +} + +_install() { + # 1: filename + install -D "${TMP_FILE}" $(_get_out_path "${1}") +} + +_template_heredoc() { + echo ". ${PWD}/bin/ssg-template" > "tmp/heredoc" + echo "cat <<EOF_TEMPLATE" >> "tmp/heredoc" + cat "${1}" >> "tmp/heredoc" + echo EOF_TEMPLATE >> "tmp/heredoc" + + sh "tmp/heredoc" "${1}" > "${TMP_FILE}" + _to_html "${TMP_FILE}" > "${2}" +} + +_convert_urls() { + # file url + if ! echo "${2}" | grep "^http" >/dev/null; then + sed -i "s@href=/@href=$2/@g" "${1}" + fi + sed -i "s@<a[^>]* href=\"[/^\"]*/@<a href=\"$2/@g" "${1}" + sed -i "s@<link[^>]* href=\"[/^\"]*/@<link href=\"$2/@g" "${1}" + sed -i "s@<img[^>]* src=\"[/^\"]*/@<img src=\"$2/@g" "${1}" +} + + +main() { + local file + + # template files + for template in header footer; do + _log "> ${template}" + _to_html "templates/${template}.md" > "${TMP_FILE}" + install -D "${TMP_FILE}" "tmp/${template}.html" + done + + # markdown files + for file in $(find "${SRC}" -iname "*.md"); do + if [ "${file}" -ot $(_get_out_path "${file}") ]; then + _log "! ${file}" + continue + fi + + _log "> ${file}" + + # Metadata + _cleanup_tmp_file "tmp/metadata.html" + _render_metadata "${file}" > "tmp/metadata.html" + + # Table of content + _cleanup_tmp_file "tmp/toc.html" + if [ $(_get_value "${file}" "toc") ]; then + _render_toc "${file}" > "tmp/toc.html" + fi + + # Index of directory + _cleanup_tmp_file "tmp/index.html" + if [ $(_get_value "${file}" "index") ]; then + _render_index "${file}" > "tmp/index.html" + fi + + # Render body content + _to_html "${file}" > "tmp/body.html" + + # Erase body content with templating + if basename "${file}" | grep "^_"; then + _template_heredoc "${file}" "tmp/body.html" + fi + + # Concatenate temporary files to final page + m4 templates/default.html > "${TMP_FILE}" + install -D "${TMP_FILE}" $(_get_out_path "${file}") + done + + # html files + for file in $(find "${SRC}" -iname "*.html"); do + _log "> ${file}" + _install "${file}" + done + + # convert urls + for file in $(find "${OUT}" -iname "*.html"); do + _convert_urls "${file}" "${BASE_URL}" + done + + for dir in ${STATIC_DIRS}; do + _log "> ${dir}/" + cp -R "src/${dir}" "out/${dir}" + done +} + +main diff --git a/bin/ssg-template b/bin/ssg-template new file mode 100644 index 0000000..d246028 --- /dev/null +++ b/bin/ssg-template @@ -0,0 +1,166 @@ +#!/bin/sh + +SRC_FILE="${1}" + +_echo_ifset() { + [ ! -z "${1}" ] && echo "${1}" +} + +_get_value() { + # 1: filename + # 2: key + # stdout: value + local value=$(lowdown -T ms -X "${2}" "${1}" 2>/dev/null) + echo "${value:-${3}}" + return "${?}" +} + +_get_value_date() { + _get_value "${1}" "${2}" "1970-01-01" +} + +_get_out_path() { + # 1: filename + # stdout: filename + echo "${1}" | sed -e 's/^src/out/g' -e 's/.md$/.html/g' -e 's/_//g' +} + +_get_final_path() { + # 1: filename + # stdout: filename + _get_out_path "${1}" | sed 's/^out\///g' +} + +_get_title() { + # 1: filename + basename "${1}" | sed 's/\..*//g' | tr - " " +} + +_get_date_human() { + # 1: filename + date -j -f "%Y-%m-%d" $(_get_value_date ${1} "date") +"%B %d, %Y" +} + +_get_index_files() { + # 1: filename + local path + + path=$(_get_value "${1}" index) + find "src/${path}" -mindepth 1 -maxdepth 1 +} + +_sort_index_per_date() { + # 1: filename + local files + local file + local date + + for file in $(_get_index_files "${1}"); do + date=$(_get_value_date "${file}" "date") + files="${files} ${date}@${file}" + done + + echo ${files} | tr " " "\n" | sort -rn | cut -d "@" -f 2 +} + +_get_filetype() { + # 1: filename + local filetype + + filetype=$(ls -ld "${1}" | cut -c 1) + + case "${filetype}" in + -) + filetype="file" + ;; + d) + filetype="directory" + ;; + esac + + echo "${filetype}" +} + +_get_chapters() { + # 1: filename + grep "^#" "${1}" | sed 's/# /#_/g' +} + +_get_chapter_title() { + # 1: chapter + echo "${1}" | sed -e 's/#_//' -e 's/#//g' +} + +_parse_option() { + # 1: metadata + # 2: key + echo "${metadata}" | grep "^${2}" +} + +_cleanup_tmp_file() { + [ -f "${1}" ] && rm "${1}" +} + +_parse_metadata() { + # 1: filename + sed -n '/^$/q;p' "${file}" | grep "^.*: .*$" +} + +_render_metadata() { + # 1: filename + # 2: output + _ENABLED_METADATA="date author" + local key + local value + + echo "<ul class=\"metadata\">" + for key in ${_ENABLED_METADATA}; do + value=$(lowdown -X "${key}" "${1}" 2>/dev/null) + [ -z "${value}" ] && continue + + echo "<li>${key}: ${value}</li>" + done + echo "</ul>" +} + +_render_index() { + # 1: filename + # 2: out + # 3: path + local file + local path + local title + + echo "<ul class=\"index\">" + for file in $(_sort_index_per_date "${1}"); do + path=$(_get_final_path "${file}") + [ "${path}" = "$(_get_final_path ${1})" ] && continue + + title=$(_get_value "${file}" "title" "$(_get_title ${file})") + + cat <<-EOF + <li> + <a href="${path}">${title}</a> + <span>$(_get_date_human "${file}")</span> + </li> + EOF + done + echo "</ul>" +} + +_render_toc() { + local chapter + local chapter_title + + echo "<ul class=\"toc\">" + for chapter in $(_get_chapters "${1}"); do + chapter_title=$(_get_chapter_title "${chapter}") + + cat <<-EOF + <li> + <a href=#${chapter_title}>${chapter_title}</a> + </li> + EOF + done + echo "</ul>" +} diff --git a/templates/_metadata.md b/templates/_metadata.md new file mode 100644 index 0000000..da79be4 --- /dev/null +++ b/templates/_metadata.md @@ -0,0 +1,3 @@ +$( +pwd +) diff --git a/templates/default.html b/templates/default.html new file mode 100644 index 0000000..9156cbd --- /dev/null +++ b/templates/default.html @@ -0,0 +1,15 @@ +<html> +include(templates/head.html) +<body> + <header> + include(tmp/header.html) + </header> + sinclude(tmp/metadata.html) + sinclude(tmp/toc.html) + include(tmp/body.html) + sinclude(tmp/index.html) + <footer> + include(tmp/footer.html) + </footer> +<body> +</html> diff --git a/templates/footer.md b/templates/footer.md new file mode 100644 index 0000000..150702b --- /dev/null +++ b/templates/footer.md @@ -0,0 +1 @@ +> remember that computer sucks diff --git a/templates/head.html b/templates/head.html new file mode 100644 index 0000000..7272d63 --- /dev/null +++ b/templates/head.html @@ -0,0 +1,4 @@ +<meta charset="utf-8"> +<meta name="viewport" content="width=device-width, initial-scale=1"> +<link href="/style/style.css" rel="stylesheet" type="text/css"> +<title></title> diff --git a/templates/header.md b/templates/header.md new file mode 100644 index 0000000..4356090 --- /dev/null +++ b/templates/header.md @@ -0,0 +1,8 @@ +# [rgoncalves.se](/) + +- [wiki](/w) +- [services](/s) +- [rss](/rss.xml) +- [git](https://git.rgoncalves.se) +- [webring](https://webring.xxiivv.com/#random) +- [about](/a) |