From caa30dd45d3ae76405a7f4ecc9641521c1fb8895 Mon Sep 17 00:00:00 2001 From: Johannes Herman Date: Mon, 16 Mar 2026 11:14:21 +0100 Subject: initial --- bin/categories | 12 ++++ bin/make | 48 +++++++++++++ bin/makepage | 36 ++++++++++ bin/makewritindex | 53 +++++++++++++++ bin/markup | 198 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 347 insertions(+) create mode 100755 bin/categories create mode 100755 bin/make create mode 100755 bin/makepage create mode 100755 bin/makewritindex create mode 100755 bin/markup (limited to 'bin') diff --git a/bin/categories b/bin/categories new file mode 100755 index 0000000..49b9d22 --- /dev/null +++ b/bin/categories @@ -0,0 +1,12 @@ +#!/bin/awk -f + +FNR == 2 { + sub(/^;[ ]*/, "") + for (i = 1; i <= NF; i++) + seen[$i] = 1 +} + +END { + for (w in seen) + printf "%s\n", w +} diff --git a/bin/make b/bin/make new file mode 100755 index 0000000..3d9c6fd --- /dev/null +++ b/bin/make @@ -0,0 +1,48 @@ +#!/bin/sh -eu + +. ./config + +title() { + [ -z "$1" ] && echo "$TITLE" && return + echo "${1##*/} - $TITLE" +} + +mkdir -p "$DIR_BUILD" + +echo ">> Building content" + +find "$DIR_CONTENT" -type f -name "*.$EXT_WRITINGS" | while read -r file; do + base=${file#"$DIR_CONTENT"/} + name=${base%."$EXT_WRITINGS"} + + outdir="$DIR_BUILD/$name" + if [ "$name" = "index" ]; then + output=$DIR_BUILD/index.html + name="" + else + output="$outdir/index.html" + mkdir -p "$outdir" + fi + + case "$name" in + *"${DIR_WRITINGS##*/}"*) name="$(sed -n '1s/^; //p' "$file")" ;; + esac + echo " $output" + markup < "$file" | makepage "$(title "$name")" > "$output" + +done + +echo ">> Generating writings indexes" + +mkdir -p "$DIR_WRITINGS_DST" +echo " $DIR_WRITINGS_DST/index.html" +makewritindex | makepage "$(title writings)" > "$DIR_WRITINGS_DST/index.html" + +for c in $(categories "$DIR_WRITINGS"/*."$EXT_WRITINGS"); do + mkdir -p "$DIR_WRITINGS_DST/$c" + echo " $DIR_WRITINGS_DST/$c/index.html" + makewritindex "$c" | makepage "$(title "#$c")" > "$DIR_WRITINGS_DST/$c/index.html" +done + +echo ">> Copying static content" +cp -rv "$DIR_STATIC"/* "$DIR_BUILD" | sed -E "s/.*-> '(.*)'/ \1/" diff --git a/bin/makepage b/bin/makepage new file mode 100755 index 0000000..386f0de --- /dev/null +++ b/bin/makepage @@ -0,0 +1,36 @@ +#!/bin/sh -eu + +. ./config + +title="${1:-$TITLE}" +content=$(cat) + +awk \ + -v title="$title" \ + -v content="$content" \ + -v header="$TEMP_HEAD" \ + -v footer="$TEMP_FOOT" \ + ' +function replace(str, pat, rep, out, parts, n, i) { + n = split(str, parts, pat) + out = parts[1] + for (i = 2; i <= n; i++) + out = out rep parts[i] + return out +} + +BEGIN { + while ((getline line < header) > 0) hbuf = hbuf line "\n" + close(header) + while ((getline line < footer) > 0) fbuf = fbuf line "\n" + close(footer) +} + +{ + line = $0 + line = replace(line, "{{TITLE}}", title) + line = replace(line, "{{CONTENT}}", content) + line = replace(line, "{{HEADER}}", hbuf) + line = replace(line, "{{FOOTER}}", fbuf) + print line +}' "$TEMP_PAGE" diff --git a/bin/makewritindex b/bin/makewritindex new file mode 100755 index 0000000..5562c85 --- /dev/null +++ b/bin/makewritindex @@ -0,0 +1,53 @@ +#!/bin/sh -e + +. ./config + +writings_by_cat() { + for file in "$DIR_WRITINGS"/*."$EXT_WRITINGS"; do + case "$(sed -n '2p' "$file") " in + *" $1 "*) echo "$file" ;; + esac + done +} + +if [ -z "$1" ]; then + cats="$(categories "$DIR_WRITINGS"/*."$EXT_WRITINGS")" + writings="$DIR_WRITINGS/*.$EXT_WRITINGS" + all=1 +else + cats="$1" + writings="$(writings_by_cat "$1")" +fi + +writings=$(for f in $writings; do + date="$(date -d "$(sed -n '3s/^; //p' "$f")" "+%s")" + printf '%s %s\n' "$date" "$f" +done | sort -rn | cut -f2 -d' ') + +cat < +$([ -z "$all" ] && echo "#all") +$(for c in $cats; do echo "#$c"; done) + +" diff --git a/bin/markup b/bin/markup new file mode 100755 index 0000000..5b2ca88 --- /dev/null +++ b/bin/markup @@ -0,0 +1,198 @@ +#!/bin/gawk -f + +BEGIN { + list = "" + quote = 0 + code = 0 +} + +function handle_meta( i, n, cats, link) +{ + if ($0 ~ /^; /) { + if (meta_count == 0) { + } else if (meta_count == 1) { + sub(/^; /, "") + n = split($0, cats, " ") + printf "" + } else if (meta_count == 2) { + sub(/^; /, "") + print "

" $0 "

" + } + meta_count++ + next + } +} +function handle_list_item(condition, type) +{ + if ($0 ~ condition) { + if (list != type) { + if (list != "") print "" + print "<" type ">" + list = type + } + sub(condition, "") + print "
  • " $0 "
  • " + next + } +} + +function handle_quote() +{ + if ($0 == "\"\"\"") { + if (quote == 0) { + print "
    " + quote = 1 + } else { + print "
    " + quote = 0 + } + next + } +} + +function handle_codeblock() +{ + if ($0 ~ /^'''/) { + if (code == 0) { + if (list != "") { + print "" + list = "" + } + print "
    "
    +            code = 1
    +        } else {
    +            print "
    " + code = 0 + } + next + } + + if (code == 1) { + gsub(/&/, "\\&") + gsub(//, "\\>") + print + next + } +} + +function inline(delim, tag, escaped, pattern) +{ + escaped = delim + gsub(/\*/, "\\*", escaped) + gsub(/\./, "\\.", escaped) + + pattern = escaped "([^" escaped "]+)" escaped + while (match($0, pattern)) { + $0 = substr($0, 1, RSTART-1) \ + "<" tag ">" substr($0, RSTART+length(delim), \ + RLENGTH-length(delim)*2) "" \ + substr($0, RSTART+RLENGTH) + } +} + +function inline_link(pattern, result, pre, arr) +{ + pattern = "\\[([^]]+)\\]\\(([^)]+)\\)" + result = "" + while (match($0, pattern, arr)) { + pre = substr($0, 1, RSTART-1) + result = result pre "" arr[1] "" + $0 = substr($0, RSTART+RLENGTH) + } + $0 = result $0 +} + +function inline_image(pattern, result, pre, arr) +{ + pattern = "!\\[([^]]+)\\]\\(([^)]+)\\)" + result = "" + while (match($0, pattern, arr)) { + pre = substr($0, 1, RSTART-1) + result = result pre "" "\""" "" + $0 = substr($0, RSTART+RLENGTH) + } + $0 = result $0 +} + +function inline_footnote_ref(pattern, result, pre, arr) +{ + pattern = ".\\[\\^([^]]+)\\]" + result = "" + while (match($0, pattern, arr)) { + pre = substr($0, 1, RSTART) + result = result pre "" arr[1] "" + $0 = substr($0, RSTART+RLENGTH) + } + $0 = result $0 +} + +function handle_header(i, level) +{ + if ($0 ~ /^#+[ ]/) { + level = 0 + while (substr($0, level+1, 1) == "#") level++ + sub(/^#+[ ]+/, "") + print "" $0 "" + next + } +} + +function handle_footnote(pattern, arr) +{ + pattern = "^\\[\\^([^]]+)\\]:[ ]*(.*)" + if (match($0, pattern, arr)) { + if (footnote != 1) { + print "
      " + footnote = 1 + } + print "
    1. " arr[2] \ + "
    2. " + list = "ol" + next + } +} + +{ + handle_meta() + handle_quote() + handle_codeblock() + + inline("**", "b") + inline("*", "em") + inline("--", "s") + inline("'''", "code") + + inline_image() + inline_link() + + inline_footnote_ref() + + handle_list_item("^- ", "ul") + handle_list_item("^[0-9]+\\.[ ]+", "ol") + handle_footnote() + + if (list != "") { + print "" + list = "" + } + + handle_header() + + if ($0 != "") { + print "

      " $0 "

      " + } +} + +END { + if (list != "") + print "" +} -- cgit v1.2.3