diff options
-rw-r--r-- | Makefile | 14 | ||||
-rw-r--r-- | bin/func | 187 | ||||
-rwxr-xr-x | bin/ssg | 127 | ||||
-rw-r--r-- | bin/ssg-template | 194 | ||||
-rw-r--r-- | src/index.md | 2 | ||||
-rw-r--r-- | src/style/style.css | 10 | ||||
-rw-r--r-- | templates/_metadata.md | 3 | ||||
-rw-r--r-- | templates/default | 15 | ||||
-rw-r--r-- | templates/default.footer | 3 | ||||
-rw-r--r-- | templates/default.head (renamed from templates/head.html) | 2 | ||||
-rw-r--r-- | templates/default.header | 10 | ||||
-rw-r--r-- | templates/default.html | 15 | ||||
-rw-r--r-- | templates/footer.md | 1 | ||||
-rw-r--r-- | templates/header.md | 8 | ||||
-rw-r--r-- | templates/none | 6 | ||||
-rw-r--r-- | templates/none.html | 9 |
16 files changed, 250 insertions, 356 deletions
@@ -1,12 +1,7 @@ .POSIX: -BIN := ./bin -SRC := ./src -OUT := ./out -TMP := ./tmp REMOTE := root@dc0 REMOTE_DIR := /var/www/htdocs/rgoncalves.se -BASE_URL = https://rgoncalves.se .PHONY: all \ website \ @@ -14,15 +9,12 @@ BASE_URL = https://rgoncalves.se all: clean website -local: clean - BASE_URL=$$PWD/$(OUT) $(BIN)/ssg - website: clean - BASE_URL=$(BASE_URL) $(BIN)/ssg + ./bin/ssg deploy: website - rsync -e ssh -avz --delete $(OUT)/ $(REMOTE):$(REMOTE_DIR) + rsync -e ssh -avz --delete out / $(REMOTE):$(REMOTE_DIR) ssh $(REMOTE) chown -R www:www $(REMOTE_DIR) clean: - - rm -r $(OUT) $(TMP)/* + - rm -r out tmp diff --git a/bin/func b/bin/func new file mode 100644 index 0000000..af81d92 --- /dev/null +++ b/bin/func @@ -0,0 +1,187 @@ +#!/bin/sh + +media_dir="media" +src_dir="src" +tmp_dir="tmp" +out_dir="out" + +tmp_file="${tmp_dir}/tmp" + +__get_value() { + # 1: filename + # 2: Attribute name + # Retrieve and return the key/value of a lowdown source file. + lowdown -T ms -X "${2}" "${1}" 2>/dev/null +} + +__get_value_title() { + # 1: filename + # Get the title of a file and return a safe string. + local _title + + _title="$(__get_value ${1} title || true)" + if [ "${_title}" = "" ]; then + _title="$(basename ${1} | + rev | + cut -d "." -f 2 | + rev | + sed 's/-/ /g')" + fi + + echo "${_title}" +} + +__get_value_date() { + # 1: filename + # Get the date of a file and return a safe string. + local _date + + _date="$(__get_value ${1} date || true)" + if [ "${_date}" = "" ]; then + _date="1970-01-01" + fi + + echo "${_date}" +} + +__get_value_date_human() { + # 1: filename + # Get a human readable date from a file and return a safe string. + __get_value_date "${1}" | xargs date -j -f "%Y-%m-%d" +"%B %d, %Y" +} + +__get_out_filename() { + # 1: filename + # Convert the source filename to its output destination. + local _filename + + _filename="${1}" + + if $(__get_value "${1}" draft || false); then + _filename="$(dirname ${1})/$(basename ${1} | sha256).html" + fi + + echo "${_filename}" | + sed 's/.md$/.html/g' | + sed "s/${src_dir}/${out_dir}/g" +} + +__get_final_filename() { + # 1: filename + # Convert the source filename to its final filename for a webserver. + __get_out_filename "${1}" | cut -d "/" -f 2- +} + +__list_files() { + # 1: directory + # List all regular files in a directory and its subdirectories. + find "${1}" -type f +} + +__list_files_date() { + # 1: directory + local _files + local _file + local _tmp_file + + _files=$(__list_files "${1}") + _tmp_file="${tmp_file}.list_files_date" + + cp /dev/null "${_tmp_file}" + + for _file in ${_files}; do + echo "$(__get_value_date ${_file})" "${_file}" >> "${_tmp_file}" + done + + sort -r "${_tmp_file}" | cut -d " " -f 2- +} + +__install() { + # 1: filename + # Copy a file to the output directory. + install -D -m 0644 "${1}" "${2}" +} + +__lowdown() { + # Output a file to html + lowdown --html-no-skiphtml --html-no-escapehtml "${1}" +} + +__apply_template() { + # 1: template name or default + m4 "templates/${1:-default}" +} + +__generate_index_line() { + # 1: filename where index will be displayed + # 2: filename contained in line + local _show_date + + _show_date="$(__get_value ${1} index_date || echo false)" + + if "${_show_date}"; then + cat <<-EOF + <span> + $(__get_value_date_human ${2}) + </span> + EOF + fi + + cat <<-EOF + <a href="$(__get_final_filename ${2})"> + $(__get_value_title ${2}) + </a> + EOF +} + +__generate_index() { + # 1: filename + # Generate and output to stdout the index of a file. + local _file + local _index_dir + + _index_dir="${src_dir}/$(__get_value "${1}" index)" + [ -f "${_index_dir}" ] && _index_dir=$(dirname "${_index_dir}") + [ ! -d "${_index_dir}" ] && return + + echo "<ul class=\"index\">" + + for _file in $(__list_files_date "${_index_dir}"); do + [ "${1}" = "${_file}" ] && continue + __get_value "${_file}" "draft" >/dev/null && continue + + echo "<li>" + __generate_index_line "${1}" "${_file}" + echo "</li>" + done + + echo "</ul>" +} + +__handle_md() { + # 1: filename + # Handle markdown files. + __lowdown "${1}" > "${tmp_file}.body" + + if [ ! "$(__get_value ${1} index)" = "" ]; then + __generate_index "${1}" > "${tmp_file}.index" + else + [ -f "${tmp_file}.index" ] && rm "${tmp_file}.index" + fi + + __apply_template "$(__get_value ${1} template)" > "${tmp_file}" + __install "${tmp_file}" "$(__get_out_filename ${1})" +} + +__handle() { + # 1: filename + # Handle file depending on its filename and filetype. + case "${1}" in + *.md) + __handle_md "${1}" + ;; + *) + __install "${1}" "$(__get_out_filename ${1})" + ;; + esac +} @@ -1,117 +1,24 @@ #!/bin/sh -TEMPLATE="templates/default.html" -STATIC_DIRS="style img" -TMP_FILE=".tmp" -SRC="src" -OUT="out" -#BASE_URL="" +. $(dirname "${0}")/func -. ./bin/ssg-template +set -xe -_log() { - echo [${0}] "$@" -} +# Check if the working directory is valid. +echo "${0}" | grep '^./bin/ssg$' -_to_html() { - # 1: filename - # stdout: content - lowdown --html-no-skiphtml --html-no-escapehtml "${1}" -} +src_files="$(__list_files ${src_dir})" +dirs="${media_dir} \ + ${src_dir} \ + ${tmp_dir} \ + ${out_dir}" -_install() { - # 1: filename - install -D "${TMP_FILE}" $(_get_out_path "${1}") -} +# Ensure directories exist. +for dir in ${dirs}; do + [ ! -d "${dir}" ] && mkdir "${dir}" +done -_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 - local out_path - - # 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 - out_path=$(_get_out_path "${file}") - - if [ "${file}" -ot "${out_path}" ]; 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 - template=$(_get_value "${file}" "template") - template="${template:-default}" - m4 "templates/${template}.html" > "${TMP_FILE}" - install -D "${TMP_FILE}" "${out_path}" - 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 +# Generate output files from sources. +for src_file in ${src_files}; do + __handle "${src_file}" +done diff --git a/bin/ssg-template b/bin/ssg-template deleted file mode 100644 index eacf2ae..0000000 --- a/bin/ssg-template +++ /dev/null @@ -1,194 +0,0 @@ -#!/bin/sh - -SRC_FILE="${1}" - -_echo_ifset() { - [ ! -z "${1}" ] && echo "${1}" -} - -_get_value() { - # 1: filename - # 2: key - # stdout: value - local value - local ret - - value=$(lowdown -T ms -X "${2}" "${1}" 2>/dev/null) - ret="${?}" - - echo "${value:-${3}}" - - return "${ret}" -} - -_get_value_date() { - _get_value "${1}" "${2}" "1970-01-01" -} - -_get_out_path() { - # 1: filename - # stdout: filename - local path - - path=$(echo "${1}" | sed -e 's/^src/out/g' -e 's/.md$/.html/g' -e 's/_//g') - - if _get_value "${1}" "draft" >/dev/null; then - path="$(dirname ${path})/$(echo ${path} | sha1).html" - fi - - echo "${path}" -} - -_get_final_path() { - # 1: filename - # stdout: filename - _get_out_path "${1}" | sed 's/^out\///g' -} - -_get_title() { - # 1: filename - local title - local file_title - - file_title=$(basename "${1}" | sed 's/\..*//g' | tr - " ") - title=$(_get_value "${1}" "title" "${file_title}") - - echo "${title}" -} - -_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 - local key - local value - local title - - # _ENABLED_METADATA="date author" - title=$(_get_value "${1}" "title") - - 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>" - - if [ "${title}" ]; then - echo "<h1>${title}</h1>" - fi -} - -_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 - _get_value "${file}" "draft" >/dev/null && continue - - title=$(_get_value "${file}" "title" "$(_get_title ${file})") - - echo "<li>" - if _get_value "${1}" "index_show_date" >/dev/null; then - echo "<span>$(_get_date_human ${file})</span>" - fi - echo "<a href=\"${path}\">${title}</a>" - echo "</li>" - 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/src/index.md b/src/index.md index d5e8563..4308dfb 100644 --- a/src/index.md +++ b/src/index.md @@ -1,3 +1,3 @@ toc: true index: b -index_show_date: true +index_date: true diff --git a/src/style/style.css b/src/style/style.css index f011167..8c17ae3 100644 --- a/src/style/style.css +++ b/src/style/style.css @@ -88,11 +88,11 @@ p code { blockquote { margin-inline-end: 0; - margin-inline-start: 20%; + margin-inline-start: 0; + background-color: #cccccc; } blockquote * { - background-color: yellow; font-style: italic; } @@ -101,6 +101,10 @@ blockquote p { margin-block-end: 0; } +footer blockquote { + background-color: yellow; +} + footer { margin-top: 16em; } @@ -109,7 +113,7 @@ footer blockquote { margin-inline-start: 0; } -@media only screen and (max-width: 100ch) { +@media only screen and (max-width: 72ch) { * { text-align: left; } diff --git a/templates/_metadata.md b/templates/_metadata.md deleted file mode 100644 index da79be4..0000000 --- a/templates/_metadata.md +++ /dev/null @@ -1,3 +0,0 @@ -$( -pwd -) diff --git a/templates/default b/templates/default new file mode 100644 index 0000000..38de71d --- /dev/null +++ b/templates/default @@ -0,0 +1,15 @@ +<html> +include(templates/default.head) +<body> + <header> + include(templates/default.header) + </header> + sinclude(tmp/tmp.metadata) + sinclude(tmp/tmp.toc) + include(tmp/tmp.body) + sinclude(tmp/tmp.index) + <footer> + include(templates/default.footer) + </footer> +<body> +</html> diff --git a/templates/default.footer b/templates/default.footer new file mode 100644 index 0000000..f41001a --- /dev/null +++ b/templates/default.footer @@ -0,0 +1,3 @@ +<blockquote> +remember that computer sucks +</blockquote> diff --git a/templates/head.html b/templates/default.head index 7272d63..ca312c9 100644 --- a/templates/head.html +++ b/templates/default.head @@ -1,4 +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> +<title>rgoncalves.se</title> diff --git a/templates/default.header b/templates/default.header new file mode 100644 index 0000000..d646b91 --- /dev/null +++ b/templates/default.header @@ -0,0 +1,10 @@ +<h1><a href="/">rgoncalves.se</a></h1> + +<ul> + <li><a href="/w">wiki</a></li> + <li><a href="/s">services</a></li> + <li><a href="/rss.xml">rss</a></li> + <li><a href="https://git.rgoncalves.se">git</a></li> + <li><a href="https://webring.xxiivv.com/#random">webring</a></li> + <li><a href="/a">about</a></li> +</ul> diff --git a/templates/default.html b/templates/default.html deleted file mode 100644 index 9156cbd..0000000 --- a/templates/default.html +++ /dev/null @@ -1,15 +0,0 @@ -<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 deleted file mode 100644 index 150702b..0000000 --- a/templates/footer.md +++ /dev/null @@ -1 +0,0 @@ -> remember that computer sucks diff --git a/templates/header.md b/templates/header.md deleted file mode 100644 index 4356090..0000000 --- a/templates/header.md +++ /dev/null @@ -1,8 +0,0 @@ -# [rgoncalves.se](/) - -- [wiki](/w) -- [services](/s) -- [rss](/rss.xml) -- [git](https://git.rgoncalves.se) -- [webring](https://webring.xxiivv.com/#random) -- [about](/a) diff --git a/templates/none b/templates/none new file mode 100644 index 0000000..a125d9e --- /dev/null +++ b/templates/none @@ -0,0 +1,6 @@ +<html> +include(templates/default.head) +<body> + include(tmp/tmp.body) +<body> +</html> diff --git a/templates/none.html b/templates/none.html deleted file mode 100644 index f75fb33..0000000 --- a/templates/none.html +++ /dev/null @@ -1,9 +0,0 @@ -<html> -include(templates/head.html) -<body> - sinclude(tmp/metadata.html) - sinclude(tmp/toc.html) - include(tmp/body.html) - sinclude(tmp/index.html) -<body> -</html> |