diff options
Diffstat (limited to '')
30 files changed, 714 insertions, 264 deletions
diff --git a/v2/src/bin/absolute b/v2/src/bin/absolute index ae25b43..6434219 100755 --- a/v2/src/bin/absolute +++ b/v2/src/bin/absolute @@ -62,6 +62,6 @@ done shift $((OPTIND - 1)) -. src/development/config.env +. src/lib/base-conf -printf 'https://%s%s' "$FQDN" "$(cat)" +printf 'https://%s%s' "$domain" "$(cat)" diff --git a/v2/src/bin/extract b/v2/src/bin/extract deleted file mode 100755 index 7bbcba7..0000000 --- a/v2/src/bin/extract +++ /dev/null @@ -1,133 +0,0 @@ -#!/bin/sh -set -eu - - -usage() { - cat <<-'EOF' - Usage: - extract -t TYPE FILENAME - extract -h - EOF -} - -help() { - cat <<-'EOF' - - Options: - -t TYPE the type of extraction to perform ("content" or "env") - -h, --help show this message - - FILENAME the name of the input file, also to be used as - URL. - - - Separate the content from the "frontmatter", and emit the - selected one, given the FILENAME. - - - Examples: - - Get the content: - - $ extract -t content src/file.md > src/file.entry-content - - - Get the "frontmatter": - - $ extract -t env src/f.md > src/f.entry-env - EOF -} - - -for flag in "$@"; do - case "$flag" in - --) - break - ;; - --help) - usage - help - exit - ;; - *) - ;; - esac -done - -TYPE='' -while getopts 't:h' flag; do - case "$flag" in - t) - TYPE="$OPTARG" - ;; - h) - usage - help - exit - ;; - *) - usage >&2 - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) - - -FILENAME="${1:-}" -eval "$(assert-arg "$FILENAME" 'FILENAME')" -eval "$(assert-arg "$TYPE" '-t TYPE')" - - -case "$TYPE" in - content) - . "${FILENAME%.md}.entry-env" - printf '%s\n' "$PREAMBLE" - awk ' - separator >= 2 - /^---$/ { separator++ } - ' "$FILENAME" - ;; - env) - cat src/development/config.env - awk ' - /^---$/ { - if (++separator > 1) { - exit - } else { - next - } - } - - { print } - ' "$FILENAME" - printf "FILENAME='%s'\n" "$FILENAME" - cat <<-'REAL_EOF' - TITLE="${TITLE:-$SITE_NAME}" - - URI_TITLE="$(printf '%s' "$TITLE" | uri)" - - URL="$( - printf '%s' "$FILENAME" | - sed \ - -e 's|^src/content/||' \ - -e 's|md$|html|' - )" - - PREAMBLE="$(cat <<EOF - # $TITLE - - <p class="timestamp"> - Posted on <time datetime="$DATE">$(LANG="$LANGUAGE" date -d "$DATE" "$DATE_FMT")</time> - </p> - EOF - )" - REAL_EOF - ;; - *) - printf 'Bad value for TYPE: "%s".\n\n' \ - "$TYPE" >&2 - usage >&2 - exit 2 - ;; -esac diff --git a/v2/src/bin/makemake b/v2/src/bin/makemake new file mode 100755 index 0000000..f4ab87a --- /dev/null +++ b/v2/src/bin/makemake @@ -0,0 +1,137 @@ +#!/bin/sh +set -eu + + +usage() { + cat <<-'EOF' + Usage: + makemake + makemake -h + EOF +} + +help() { + cat <<-'EOF' + + Options: + -h, --help show this message + + + Generate make(1) code for later evaluation by make(1). What + this scripts does is fill the gap where make(1) can't handle + globs and dynamic dependencies, and uses some ad-hoc scripts + to generate those. + EOF +} + +for flag in "$@"; do + case "$flag" in + --) + break + ;; + --help) + usage + help + exit + ;; + *) + ;; + esac +done + +while getopts 'h' flag; do + case "$flag" in + h) + usage + help + exit + ;; + *) + usage >&2 + exit 2 + ;; + esac +done +shift $((OPTIND - 1)) + + + +varlist() { + printf '%s = \\\n' "$1" + sed \ + -e 's/^/ /' \ + -e 's/$/ \\/' + printf '\n' +} + +html_deps() { + "$@" | sed 's/^\(.*\)\.md$/\1.conf \1.content: \1.md/' + "$@" | sed 's/^\(.*\)\.md$/\1.html: \1.conf \1.content/' + printf '\n' +} + + +content_mds() { + find src/content/"$1"/ -type f -name '*.md' +} + +RESOURCES=' +pastebins +tils +' + +EXTENSIONS=' +.md +.conf +.content +.prehtml +.posthtml +.html +' + +for r in $RESOURCES; do + content_mds "$r" | varlist "$r".md + for e in $EXTENSIONS; do + if [ "$e" = '.md' ]; then + continue + fi + printf '%s%s = $(%s.md:.md=%s)\n' "$r" "$e" "$r" "$e" + done + printf '%s =' "$r" + for e in $EXTENSIONS; do + if [ "$e" = '.md' ]; then + continue + fi + printf ' $(%s%s)' "$r" "$e" + done + printf '\n' + html_deps content_mds "$r" + printf '\n' +done + +all_resources() { + echo $RESOURCES | tr ' ' '\n' +} + +all_vars() { + EXT="$1" + all_resources | + sed 's|^|$(|' | + sed "s|$|$EXT)|" | + varlist all-generated"$EXT" +} + +for e in $EXTENSIONS; do + all_vars "$e" +done +all_vars '' + + +git ls-files | + grep -v '^src/content/' | + varlist 'non-content' + +git ls-files src/content/ | + grep -v '\.md$' | + grep -Ev "src/content/($(all_resources | paste -sd'|'))/" | + varlist 'static-content' diff --git a/v2/src/bin/url-for b/v2/src/bin/url-for index 025a546..c31ff84 100755 --- a/v2/src/bin/url-for +++ b/v2/src/bin/url-for @@ -1,7 +1,6 @@ #!/bin/sh set -eu - usage() { cat <<-'EOF' Usage: @@ -69,9 +68,12 @@ while getopts 'h' flag; do done shift $((OPTIND - 1)) +. src/development/lib.sh + + FILE="${1:-}" -eval "$(assert-arg "$FILE" 'FILE')" +eval "$(assert_arg "$FILE" 'FILE')" -. src/development/config.env +. src/lib/base-conf -printf '%s/%s' "$BASE_URL" "$FILE" +printf '%s%s' "${base_url:-/}" "$FILE" diff --git a/v2/src/content/.well-known/security.txt b/v2/src/content/.well-known/security.txt new file mode 100644 index 0000000..dd35c49 --- /dev/null +++ b/v2/src/content/.well-known/security.txt @@ -0,0 +1,4 @@ +Contact: mailto:eu@euandre.org +Encryption: https://euandre.org/public.asc.txt +Expires: 2024-07-15T00:00:00z +Preferred-Languages: en, pt diff --git a/v2/src/content/favicon.svg b/v2/src/content/favicon.svg new file mode 120000 index 0000000..313dcc5 --- /dev/null +++ b/v2/src/content/favicon.svg @@ -0,0 +1 @@ +../../../static/lord-favicon.svg
\ No newline at end of file diff --git a/v2/src/content/pastebins/raku-tuple-type-annotation.md b/v2/src/content/pastebins/raku-tuple-type-annotation.md new file mode 100644 index 0000000..3d5ff34 --- /dev/null +++ b/v2/src/content/pastebins/raku-tuple-type-annotation.md @@ -0,0 +1,37 @@ +--- + +title: Raku tuple type annotation + +date: 2019-12-29 + +layout: post + +lang: en + +ref: raku-tuple-type-annotation + +--- + +```perl +# Single Str return value: this works +sub f1(Str $in --> Str) { + $in; +} + +# Tuple of Str as return value: this works +sub f2(Str $in) { + ($in, $in); +} + +# Tuple of Str as return value with type annotation: this doesn't works +sub f2(Str $in --> (Str, Str)) { + ($in, $in); +} +``` + +Error log is: + +```perl +===SORRY!=== Error while compiling /path/to/my/file +Malformed return value +``` diff --git a/v2/src/content/pastebins/sicp-exercise-3-19.md b/v2/src/content/pastebins/sicp-exercise-3-19.md index fd2c52b..8834889 100644 --- a/v2/src/content/pastebins/sicp-exercise-3-19.md +++ b/v2/src/content/pastebins/sicp-exercise-3-19.md @@ -1,14 +1,14 @@ --- -TITLE='SICP exercise 3.19' +title: SICP exercise 3.19 -DATE='2021-09-02' +date: 2021-09-02 -LAYOUT='post' +layout: post -LANGUAGE='en' +lang: en -REF='sicp-exercise-3-19' +id: sicp-exercise-3-19 --- diff --git a/v2/src/content/public.asc.txt b/v2/src/content/public.asc.txt new file mode 100644 index 0000000..533b54c --- /dev/null +++ b/v2/src/content/public.asc.txt @@ -0,0 +1,86 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +LsPdAc9FGcUNEy+/AlLpM1Y= +=2ZCp +-----END PGP PUBLIC KEY BLOCK----- diff --git a/v2/src/content/static/atom.svg b/v2/src/content/static/atom.svg deleted file mode 120000 index 41c6d3f..0000000 --- a/v2/src/content/static/atom.svg +++ /dev/null @@ -1 +0,0 @@ -../../../../static/atom.svg
\ No newline at end of file diff --git a/v2/src/content/static/envelope.svg b/v2/src/content/static/envelope.svg deleted file mode 120000 index bd0c577..0000000 --- a/v2/src/content/static/envelope.svg +++ /dev/null @@ -1 +0,0 @@ -../../../../static/envelope.svg
\ No newline at end of file diff --git a/v2/src/content/static/favicon.svg b/v2/src/content/static/favicon.svg deleted file mode 120000 index 33566ab..0000000 --- a/v2/src/content/static/favicon.svg +++ /dev/null @@ -1 +0,0 @@ -../../../../static/lord-favicon.svg
\ No newline at end of file diff --git a/v2/src/content/static/link.svg b/v2/src/content/static/link.svg deleted file mode 120000 index bf69c40..0000000 --- a/v2/src/content/static/link.svg +++ /dev/null @@ -1 +0,0 @@ -../../../../static/link.svg
\ No newline at end of file diff --git a/v2/src/content/static/lock.svg b/v2/src/content/static/lock.svg deleted file mode 120000 index f9a4f33..0000000 --- a/v2/src/content/static/lock.svg +++ /dev/null @@ -1 +0,0 @@ -../../../../static/lock.svg
\ No newline at end of file diff --git a/v2/src/content/static/public.asc.txt b/v2/src/content/static/public.asc.txt deleted file mode 120000 index 5175f38..0000000 --- a/v2/src/content/static/public.asc.txt +++ /dev/null @@ -1 +0,0 @@ -../../../../public.asc
\ No newline at end of file diff --git a/v2/src/content/static/styles.css b/v2/src/content/style.css index 0ec67a8..0ec67a8 100644 --- a/v2/src/content/static/styles.css +++ b/v2/src/content/style.css diff --git a/v2/src/content/tils/lisp-three-way-conditional.md b/v2/src/content/tils/lisp-three-way-conditional.md new file mode 100644 index 0000000..f53451b --- /dev/null +++ b/v2/src/content/tils/lisp-three-way-conditional.md @@ -0,0 +1,63 @@ +--- + +title: Three-way conditional for number signs on Lisp + +date: 2021-04-24 3 + +updated_at: 2021-08-14 + +layout: post + +lang: en + +ref: three-way-conditional-for-number-signs-on-lisp + +--- + +A useful macro from Paul Graham's [On Lisp][on-lisp] book: + +```lisp +(defmacro nif (expr pos zero neg) + (let ((g (gensym))) + `(let ((,g ,expr)) + (cond ((plusp ,g) ,pos) + ((zerop ,g) ,zero) + (t ,neg))))) +``` + +After I looked at this macro, I started seeing opportunities to using it in many places, and yet I didn't see anyone else using it. + +The latest example I can think of is section 1.3.3 of [Structure and Interpretation of Computer Programs][sicp], which I was reading recently: + +```scheme +(define (search f neg-point pos-point) + (let ((midpoint (average neg-point pos-point))) + (if (close-enough? neg-point post-point) + midpoint + (let ((test-value (f midpoint))) + (cond ((positive? test-value) + (search f neg-point midpoint)) + ((negative? test-value) + (search f midpoint pos-point)) + (else midpoint)))))) +``` + +Not that the book should introduce such macro this early, but I couldn't avoid feeling bothered by not using the `nif` macro, which could even remove the need for the intermediate `test-value` variable: + +```scheme +(define (search f neg-point pos-point) + (let ((midpoint (average neg-point pos-point))) + (if (close-enough? neg-point post-point) + midpoint + (nif (f midpoint) + (search f neg-point midpoint) + (midpoint) + (search f midpoint pos-point))))) +``` + +It also avoids `cond`'s extra clunky parentheses for grouping, which is unnecessary but built-in. + +As a macro, I personally feel it tilts the balance towards expressivenes despite its extra cognitive load toll. + +[on-lisp]: http://www.paulgraham.com/onlisptext.html +[sicp]: https://mitpress.mit.edu/sites/default/files/sicp/index.html diff --git a/v2/src/development/config.env.in b/v2/src/development/config.env.in deleted file mode 100644 index ca2afe7..0000000 --- a/v2/src/development/config.env.in +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh - -SITE_NAME="EuAndreh's website" -FQDN='@FQDN@' -BASE_URL='@BASE_URL@' -DATE_FMT='+%B %-d, %Y' diff --git a/v2/src/development/dynmake.sh b/v2/src/development/dynmake.sh deleted file mode 100755 index 126c211..0000000 --- a/v2/src/development/dynmake.sh +++ /dev/null @@ -1,79 +0,0 @@ -#!/bin/sh -set -eu - - -usage() { - cat <<-'EOF' - Usage: - dynmake.sh - dynmake.sh -h - EOF -} - -help() { - cat <<-'EOF' - - Options: - -h, --help show this message - - - Generate make(1) code for later evaluation by make(1). What - this scripts does is fill the gap where make(1) can't handle - globs and dynamic dependencies, and uses some ad-hoc scripts - to generate those. - EOF -} - -for flag in "$@"; do - case "$flag" in - --) - break - ;; - --help) - usage - help - exit - ;; - *) - ;; - esac -done - -while getopts 'h' flag; do - case "$flag" in - h) - usage - help - exit - ;; - *) - usage >&2 - exit 2 - ;; - esac -done -shift $((OPTIND - 1)) - - - -varlist() { - sed -e 's/^/ /' \ - -e 's/$/ \\/' -} - - -# -# Pastebins -# - -pastebins() { - find src/content/pastebins/ -name '*.md' -} - -printf 'pastebins.md = \\\n' -pastebins | varlist -printf '\n' - -pastebins | sed 's/^\(.*\)\.md$/\1.html: \1.entry-env/' -pastebins | sed 's/^\(.*\)\.md$/\1.html: \1.entry-content/' -pastebins | sed 's/^\(.*\)\.md$/\1.entry-content: \1.entry-env/' diff --git a/v2/src/development/genhtml.sh b/v2/src/development/genhtml.sh index a1e8afb..cb8fd73 100755 --- a/v2/src/development/genhtml.sh +++ b/v2/src/development/genhtml.sh @@ -1,21 +1,6 @@ #!/bin/sh set -eu -# FIXMEs: -# - feeds -# - link to next and/or previous in <head> -# - translation support -# - validate input variables: regex for date (same as _plugins/linter.rb) -# - `date -d` isn't POSIX -# - parse commonmark and use a custom HTML emitter over <pre><code> regex -# - handle mixture of personal scripts -# - sitemap? How does it even work? -# - dark mode -# - generate security.txt dynamically -# - config.env should depend on dynamic.mk? - - - usage() { cat <<-'EOF' Usage: @@ -81,12 +66,13 @@ while getopts 'h' flag; do done shift $((OPTIND - 1)) +. src/development/lib.sh FILENAME="${1:-}" -eval "$(assert-arg "$FILENAME" 'FILENAME')" +eval "$(assert_arg "$FILENAME" 'FILENAME')" -. "${FILENAME%.md}.entry-env" +. "${FILENAME%.md}.conf" # # Utility functions @@ -216,28 +202,28 @@ emit_body() { cat <<-EOF <!DOCTYPE html> - <html lang="$LANGUAGE"> + <html lang="$lang"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> - <link rel="stylesheet" type="text/css" href="$(url-for 'static/styles.css')" /> - <link rel="icon" type="image/svg+xml" href="$(url-for 'static/favicon.svg')" /> + <link rel="stylesheet" type="text/css" href="$style_url" /> + <link rel="icon" type="image/svg+xml" href="$favicon_url" /> - <title>$TITLE</title> + <title>$$title_html</title> <meta name="author" content="EuAndreh" /> - <meta property="og:site_name" content="$SITE_NAME" /> - <meta property="og:locale" content="$LANGUAGE" /> - <meta property="og:title" content="$TITLE" /> + <meta property="og:site_name" content="$site_name" /> + <meta property="og:locale" content="$lang" /> + <meta property="og:title" content="$title_html" /> - <link rel="canonical" href="$(url-for "$URL" | absolute)" /> - <meta property="og:url" content="$(url-for "$URL" | absolute)" /> + <link rel="canonical" href="$url" /> + <meta property="og:url" content="$url" /> </head> <body> <header> <nav> <ul> - <a href="$(url-for "$LANGUAGE/")">EuAndreh</a> + <a href="$(url-for "$lang/")">EuAndreh</a> <a href="$(url-for 'about.html')">About</a> </ul> </nav> @@ -245,8 +231,19 @@ cat <<-EOF </header> <main> <article> - $(emit_body) + \$(emit_body) <hr /> +EOF +exit + + +.md.rehtml: + F="$<"; . "$${F%.md}.conf"; envsubst < src/lib/reamble."$$lang".html > $@ + +.md.osthtml: + F="$<"; . "$${F%.md}.conf"; envsubst < src/lib/ostamble."$$lang".html > $@ + + <p class="post-footer"> <a href="mailto:~euandreh/public-inbox@lists.sr.ht?Subject=Re%3A%20$URI_TITLE">Comment</a> and see @@ -261,7 +258,7 @@ cat <<-EOF <ul> <li> <img class="svg-icon" src="$(url-for 'static/envelope.svg')" alt="a envelope icon representing an email address" /> - <a href="mailto:eu@euandre.org">eu@euandre.org</a> + <a href="mailto:$email">$email</a> </li> <li> <img class="svg-icon" src="$(url-for 'static/lock.svg')" alt="a lock icon representing a GPG public key" /> @@ -275,3 +272,16 @@ cat <<-EOF </body> </html> EOF + +# FIXMEs: +# - feeds +# - link to next and/or previous in <head> +# - translation support +# - validate input variables: regex for date (same as _plugins/linter.rb) +# - `date -d` isn't POSIX +# - parse commonmark and use a custom HTML emitter over <pre><code> regex +# - handle mixture of personal scripts +# - sitemap? How does it even work? +# - dark mode +# - generate security.txt dynamically +# - config.env should depend on dynamic.mk? diff --git a/v2/src/development/getconf.sh b/v2/src/development/getconf.sh new file mode 100755 index 0000000..dd623f7 --- /dev/null +++ b/v2/src/development/getconf.sh @@ -0,0 +1,119 @@ +#!/bin/sh +set -eu + + +usage() { + cat <<-'EOF' + Usage: + src/development/getconf.sh FILENAME + src/development/getconf.sh -h + EOF +} + +help() { + cat <<-'EOF' + + Options: + -h, --help show this message + + FILENAME the name of the input file, also to be used as + URL. + + + Separate the content from the "frontmatter", and emit the + selected one, given the FILENAME. + + + Examples: + + Get the "frontmatter" of src/f.conf: + + $ src/development/getconf.sh src/f.md > src/f.conf + EOF +} + + +for flag in "$@"; do + case "$flag" in + --) + break + ;; + --help) + usage + help + exit + ;; + *) + ;; + esac +done + +while getopts 'h' flag; do + case "$flag" in + h) + usage + help + exit + ;; + *) + usage >&2 + exit 2 + ;; + esac +done +shift $((OPTIND - 1)) + +. src/development/lib.sh + +FILENAME="${1:-}" +eval "$(assert_arg "$FILENAME" 'FILENAME')" + + +escape() { + sed 's|\([`"$]\)|\\\1|g' +} + +{ + cat src/lib/base-conf | tee "$FILENAME".tmp + DELIMITER=0 + while read -r line; do + if [ "$line" = '---' ]; then + DELIMITER=$((DELIMITER + 1)) + continue + fi + if [ "$DELIMITER" = 2 ]; then + break + fi + if [ -z "$line" ]; then + continue + fi + + KEY="$( printf '%s' "$line" | cut -d: -f1)" + VALUE="$(printf '%s' "$line" | cut -d: -f2- | sed 's|^ ||' | escape)" + printf '%s="%s"\n' "$KEY" "$VALUE" + done < "$FILENAME" | tee -a "$FILENAME".tmp + . "$FILENAME".tmp + + cat src/lib/base."$lang".conf + . src/lib/base."$lang".conf + + title="${title:-"$site_name"}" + url_part="$(printf '%s' "${FILENAME%.md}.html" | sed 's|^src/content/||')" + + printf 'title="%s"\n' "$(printf '%s' "$title" | escape)" + printf 'title_html="%s"\n' "$(printf '%s' "$title" | htmlesc | escape)" + printf 'filename="%s"\n' "$FILENAME" + printf 'url_part="%s"\n' "$url_part" + printf 'url="%s"\n' "$(url-for "$url_part" | absolute)" + printf 'date_formatted="%s"\n' "$(LANG="$lang" date -d "$date" +"$date_fmt" | escape)" + printf 'mailto_uri="%s%s"\n' "$mailto_uri_prefix" "$(uri "$title")" + printf 'discussions_url="%s%s"\n' "$discussions_url_prefix" "$(uri "$title")" + printf 'sourcecode_url="%s%s"\n' "$sourcecode_url_prefix" "$FILENAME" + + printf 'lang_url="%s"\n' "$(url-for "$lang"/)" + + printf 'style_url="%s"\n' "$(url-for 'style.css')" + printf 'favicon_url="%s"\n' "$(url-for 'favicon.svg')" + + rm -f "$FILENAME".tmp +} | grep . | sed 's|^|export |' diff --git a/v2/src/development/lib.sh b/v2/src/development/lib.sh new file mode 100644 index 0000000..9d183f9 --- /dev/null +++ b/v2/src/development/lib.sh @@ -0,0 +1,33 @@ +#!/bin/sh + +assert_arg() { + if [ -z "$1" ]; then + printf 'Missing %s.\n\n' "$2" >&2 + cat <<-'EOF' + usage >&2 + exit 2 + EOF + fi +} + +uuid() { + od -xN20 /dev/urandom | + head -n1 | + awk '{OFS="-"; print $2$3,$4,$5,$6,$7$8$9}' +} + +tmpname() { + echo "${TMPDIR:-/tmp}/uuid-tmpname with spaces.$(uuid)" +} + +mkstemp() { + name="$(tmpname)" + touch "$name" + echo "$name" +} + +mkdtemp() { + name="$(tmpname)" + mkdir "$name" + echo "$name" +} diff --git a/v2/src/development/security-txt.sh.in b/v2/src/development/security-txt.sh.in new file mode 100755 index 0000000..8f6613f --- /dev/null +++ b/v2/src/development/security-txt.sh.in @@ -0,0 +1,82 @@ +#!/bin/sh +set -eu + +usage() { + cat <<-'EOF' + Usage: + src/development/security-txt.sh + src/development/security-txt.sh -h + EOF +} + +help() { + cat <<-'EOF' + + + Options: + -h, --help show this message + + + Generate the RFC 9116 "security.txt" file from data in the + repository. + + + Examples: + + Just run it: + + $ sh src/development/security-txt.sh > .well-known/security.txt + EOF +} + + +for flag in "$@"; do + case "$flag" in + --) + break + ;; + --help) + usage + help + exit + ;; + *) + ;; + esac +done + +while getopts 'h' flag; do + case "$flag" in + h) + usage + help + exit + ;; + *) + usage >&2 + exit 2 + esac +done +shift $((OPTIND - 1)) + + + +EXPIRES="$( + LANG=C.UTF-8 gpg --list-key eu@euandre.org | + awk '/^pub/ { print substr($(NF), 1, 10) }' +)T00:00:00z" + +LANGS="en$( + echo po/??.po | + sed 's|\.po$||' | + sed 's|^po/|, |' | + paste -sd, +)" + + +cat <<-EOF + Contact: mailto:@EMAIL@ + Encryption: https://@DOMAIN@/public.asc.txt + Expires: $EXPIRES + Preferred-Languages: $LANGS +EOF diff --git a/v2/src/lib/base-conf.in b/v2/src/lib/base-conf.in new file mode 100644 index 0000000..a33755a --- /dev/null +++ b/v2/src/lib/base-conf.in @@ -0,0 +1,9 @@ +site_name="EuAndreh's website" +domain='@DOMAIN@' +email='@EMAIL@' +base_url='' +lang=en +list_addr='~euandreh/public-inbox@lists.sr.ht' +mailto_uri_prefix="mailto:$list_addr?Subject=Re%3A%20" +discussions_url_prefix="https://lists.sr.ht/~euandreh/public-inbox?search=" +sourcecode_url_prefix="https://$domain/git/$domain/tree/" diff --git a/v2/src/lib/base.en.conf b/v2/src/lib/base.en.conf new file mode 100644 index 0000000..89344fb --- /dev/null +++ b/v2/src/lib/base.en.conf @@ -0,0 +1,3 @@ +date_fmt='%B %-d, %Y' + +site_name="EuAndreh's website" diff --git a/v2/src/lib/base.pt.conf b/v2/src/lib/base.pt.conf new file mode 100644 index 0000000..89344fb --- /dev/null +++ b/v2/src/lib/base.pt.conf @@ -0,0 +1,3 @@ +date_fmt='%B %-d, %Y' + +site_name="EuAndreh's website" diff --git a/v2/src/lib/postamble.en.html b/v2/src/lib/postamble.en.html new file mode 100644 index 0000000..485d81c --- /dev/null +++ b/v2/src/lib/postamble.en.html @@ -0,0 +1,7 @@ +<p> + <a href="@mailto_uri@">Comment</a> + and see + <a href="@discussions_url@">existing discussions</a> + | + <a href="@sourcecode_url@">view source</a> +</p> diff --git a/v2/src/lib/postamble.pt.html b/v2/src/lib/postamble.pt.html new file mode 100644 index 0000000..2e65735 --- /dev/null +++ b/v2/src/lib/postamble.pt.html @@ -0,0 +1,5 @@ +<p> + <a href="@mailto_uri@">Comment</a> and see <a +href="@discussions_url@">existing discussions</a> | <a +href="@sourcecode_url@">view source</a> +</p> diff --git a/v2/src/lib/preamble.en.html b/v2/src/lib/preamble.en.html new file mode 100644 index 0000000..9ea6780 --- /dev/null +++ b/v2/src/lib/preamble.en.html @@ -0,0 +1,37 @@ +<!DOCTYPE html> +<html lang="$lang"> + <head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <link rel="stylesheet" type="text/css" href="$style_url" /> + <link rel="icon" type="image/svg+xml" href="$favicon_url" /> + + <title>$(htmlesc "$title")</title> + + <meta name="author" content="EuAndreh" /> + <meta property="og:site_name" content="$site_name" /> + <meta property="og:locale" content="$lang" /> + <meta property="og:title" content="$title_html" /> + + <link rel="canonical" href="$url" /> + <meta property="og:url" content="$url" /> + </head> + <body> + <header> + <nav> + <ul> + <a href="$lang_url">EuAndreh</a> + <a href="$(url-for 'about.html')">About</a> + </ul> + </nav> + <hr /> + </header> + <main> + <article> + <h1> + $title_html + </h1> + <p class="timestamp"> + Posted on <time datetime="$date">$date_formatted</time> + </p> +EOF diff --git a/v2/src/lib/preamble.pt.html b/v2/src/lib/preamble.pt.html new file mode 100644 index 0000000..9800470 --- /dev/null +++ b/v2/src/lib/preamble.pt.html @@ -0,0 +1,36 @@ +<!DOCTYPE html> +<html lang="$lang"> + <head> + <meta charset="UTF-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <link rel="stylesheet" type="text/css" href="$style_url" /> + <link rel="icon" type="image/svg+xml" href="$favicon_url" /> + + <title>$(htmlesc "$title")</title> + + <meta name="author" content="EuAndreh" /> + <meta property="og:site_name" content="$site_name" /> + <meta property="og:locale" content="$lang" /> + <meta property="og:title" content="$title_html" /> + + <link rel="canonical" href="$url" /> + <meta property="og:url" content="$url" /> + </head> + <body> + <header> + <nav> + <ul> + <a href="$lang_url">EuAndreh</a> <a href="$(url-for 'about.html')">About</a> + </ul> + </nav> + <hr /> + </header> + <main> + <article> + <h1> + $title_html + </h1> + <p class="timestamp"> + Posted on <time datetime="$date">$date_formatted</time> + </p> +EOF |