From 438014583ba2c244675d0f8d7f7f8bf9d568a7c8 Mon Sep 17 00:00:00 2001
From: EuAndreh
Date: Sun, 1 Sep 2024 09:14:28 -0300
Subject: Initial version
---
src/conf | 217 ++++++++++++++++++++++++++++++++++++----
src/feed | 60 +++++------
src/feedentry | 53 ++++++++++
src/html | 307 ++++++++++++++++++++++++++++-----------------------------
src/htmlbody | 26 ++++-
src/indexbody | 24 +++++
src/indexentry | 20 ++++
src/mkwb.in | 4 +-
src/snippets | 27 +++++
src/sortdata | 16 +--
src/xmlentry | 48 ---------
11 files changed, 536 insertions(+), 266 deletions(-)
create mode 100755 src/feedentry
create mode 100755 src/indexbody
create mode 100755 src/indexentry
create mode 100755 src/snippets
delete mode 100755 src/xmlentry
(limited to 'src')
diff --git a/src/conf b/src/conf
index 6aa6761..d132a34 100755
--- a/src/conf
+++ b/src/conf
@@ -1,30 +1,207 @@
#!/bin/sh
-set -eu
+set -euo pipefail
usage() {
- echo 'Usage: conf FILENAME'
+ echo 'Usage: conf BASECONF [GLOBALCONF FILENAME.adoc]'
}
-FILENAME="${1:-}"
+
+needs() {
+ if [ -z "${1:-}" ]; then
+ printf '%s\n' "$2" >&2
+ exit 1
+ fi
+}
+
+DATE_I='+%Y-%m-%d'
+DATE_Is="${DATE_I}T%H:%M:%S%:z"
+datex() {
+ # date(1), plus non-POSIX -d option
+ DATESTR="$1"
+ shift
+ date -d "$DATESTR" "$@"
+}
+
+dateiso() {
+ datex "$1" -u "$DATE_Is"
+}
+
+BASECONF="${1:-}"
+GLOBALCONF="${2:-}"
+FILENAME="${3:-}"
+eval "$(assert-arg -- "$BASECONF" 'BASECONF')"
+. "$(realpath -- "$BASECONF")"
+
+
+needs "${url_pre:-}" 'Missing required $url_pre (e.g. https://example.com)'
+needs "${site_name:-}" 'Missing required $site_name'
+needs "${feed_title:-}" 'Missing required $feed_title'
+needs "${feed_url:-}" 'Missing required $feed_url'
+needs "${feed_alternate_url:-}" 'Missing required $feed_alternate_url'
+
+needs "${list_addr:-}" 'Missing required $list_addr'
+needs "${discussions_url_prefix:-}" 'Missing required $discussions_url_prefix'
+
+needs "${email:-}" 'Missing required $email'
+needs "${author:-}" 'Missing required $author'
+needs "${sourcecode_url:-}" 'Missing required $sourcecode_url'
+needs "${sourcecode_url_prefix:-}" 'Missing required $sourcecode_url_prefix'
+
+
+if [ -z "$GLOBALCONF" ]; then
+ now_iso="$(dateiso "@${SOURCE_DATE_EPOCH:-$(date '+%s')}" | shesc)"
+ feed_title_html="$(printf '%s\n' "$feed_title" | htmlesc | shesc)"
+ site_name_html="$( printf '%s\n' "$site_name" | htmlesc | shesc)"
+ if [ -z "${logo_alt:-}" ]; then
+ logo_alt='The website logo'
+ fi
+ logo_alt="$(printf '%s\n' "$logo_alt" | htmlesc | shesc)"
+
+ cat <<-EOF
+ export now_iso="$now_iso"
+ export feed_title_html="$feed_title_html"
+ export site_name_html="$site_name_html"
+ export feed_url_absolute="$url_pre/$feed_url"
+ export feed_alternate_url_absolute="$url_pre/$feed_alternate_url"
+ export logo_alt="$logo_alt"
+ EOF
+ exit
+fi
+
+eval "$(assert-arg -- "$BASECONF" 'BASECONF')"
eval "$(assert-arg -- "$FILENAME" 'FILENAME')"
+. "$(realpath -- "$GLOBALCONF")"
+
+trap 'rm -f -- "$FILENAME".embedded-config' EXIT
+
+{
+ if head -n1 -- "$FILENAME" | grep -q '^////$'; then
+ awk 'sep > 1 {exit}; /^\/{4}$/ { sep++; next } { print }' \
+ "$FILENAME"
+ fi
+} > "$FILENAME".embedded-config
+. "$(realpath -- "$FILENAME".embedded-config)"
+
+is_article() {
+ printf '%s\n' "$FILENAME" | grep -qE \
+ "^${root_dir}[-a-zA-Z0-9/]*/[0-9]{4}/[0-9]{2}/[0-9]{2}/[-A-Za-z0-9]+\.adoc$"
+ #^ src /blog/d/a /1970 /01 /01/ /some-file-N4me.adoc
+}
+
+base_url() {
+ # src/sub/dirs/file.txt -> ../..
+ # src/file.txt -> .
+ printf '%s/\n' "$(dirname -- "$UNPREFIXED")" |
+ sed \
+ -e 's|[^/]*/|../|g' \
+ -e 's|/$||' \
+ -e 's|^\.\.$|.|'
+}
+
+last3dirnames() {
+ dirname -- "$UNPREFIXED" | tr '/' '\n' | tail -n3 | paste -sd-
+}
+
+datefmt() {
+ LANG=en_GB.UTF-8 datex "$1" -u '+%B %-d, %Y'
+}
+
+
+if [ -z "${root_dir:-}" ]; then
+ root_dir="$(dirname -- "$BASECONF")"
+fi
+root_dir="${root_dir%/}"
+if [ -z "${img_dir:-}" ]; then
+ img_dir=img
+fi
+img_dir="${img_dir%/}"
-date="$(dirname "${FILENAME#src/}" | tr '/' '-')"
-date_iso="$(date -ud "${date:?}" -Is)" # FIXME: non POSIX
-printf 'export date_iso="%s"\n' "$date_iso"
-
-cat <<-'EOF'
- export domain="DOMAIN"
- export email="EMAIL"
- export base_url=''
- export list_addr='~euandreh/public-inbox@lists.sr.ht'
- export mailto_uri_prefix="mailto:$list_addr?Subject=Re%3A%20"
- export discussions_url_prefix="https://lists.sr.ht/~euandreh/public-inbox?search="
- export sourcecode_url_prefix="https://$domain/git/$domain/tree/"
- export author='EuAndreh'
- export url='url1'
- export site_name='site_name1'
- export feed_article_title='Articles from papo.im'
- export lang=en
+UNPREFIXED="${FILENAME#$root_dir/}"
+
+cat "$BASECONF" "$GLOBALCONF"
+
+date_iso=
+date_formatted=
+updatedat_iso=
+updatedat_formatted=
+if is_article; then
+ date_iso="$(dateiso "$(last3dirnames)" | shesc)"
+ date_formatted="$(datefmt "$date_iso" | shesc)"
+ if [ -n "${updatedat:-}" ]; then
+ updatedat_iso="$(dateiso "$updatedat" | shesc)"
+ updatedat_formatted="$(datefmt "$updatedat_iso" | shesc)"
+ fi
+fi
+
+BASE_URL="$(base_url)"
+TITLE_RAW="$(cat -- "$FILENAME" | grep '^= .*' | head -n1 | cut -d' ' -f2-)"
+TITLEFULL_RAW="$TITLE_RAW | $site_name"
+
+if [ -z "${css_url:-}" ]; then
+ css_url="$BASE_URL/style.css"
+fi
+if [ -z "${atom_url:-}" ]; then
+ atom_url="$BASE_URL/atom.xml"
+fi
+if [ -z "${atomicon_url:-}" ]; then
+ needs "${img_dir:-}" 'Define either $atomicon_url or $img_dir'
+ atomicon_url="$BASE_URL/$img_dir/atom.svg"
+fi
+if [ -z "${favicon_url:-}" ]; then
+ needs "${img_dir:-}" 'Define either $favicon_url or $img_dir'
+ favicon_url="$BASE_URL/$img_dir/favicon.svg"
+fi
+if [ -z "${logo_url_prefix:-}" ]; then
+ needs "${img_dir:-}" 'Define either $logo_url_prefix or $img_dir'
+ logo_url_prefix="$BASE_URL/$img_dir/logo"
+fi
+if [ -z "${envelopeicon_url_prefix:-}" ]; then
+ needs "${img_dir:-}" 'Define either $envelopeicon_url_prefix or $img_dir'
+ envelopeicon_url_prefix="$BASE_URL/$img_dir/envelope"
+fi
+
+title_uri="$(printf '%s' "$TITLE_RAW" | uri)"
+comment_url="$(printf 'mailto:%s?Subject=Re%%3A%%20%s\n' "$list_addr" "$title_uri" | shesc)"
+discussions_url="$(printf '%s%s\n' "$discussions_url_prefix" "$title_uri" | shesc)"
+
+url="$(printf '%s\n' "${UNPREFIXED%.adoc}.html" | shesc)"
+
+css_url="$( printf '%s\n' "$css_url" | shesc)"
+atom_url="$( printf '%s\n' "$atom_url" | shesc)"
+atomicon_url="$( printf '%s\n' "$atomicon_url" | shesc)"
+favicon_url="$( printf '%s\n' "$favicon_url" | shesc)"
+logo_url_prefix="$( printf '%s\n' "$logo_url_prefix" | shesc)"
+envelopeicon_url_prefix="$(printf '%s\n' "$envelopeicon_url_prefix" | shesc)"
+
+source_path="$(printf '%s\n' "$FILENAME" | shesc)"
+base_url_prefix="$(printf '%s\n' "$BASE_URL" | shesc)"
+title="$( printf '%s\n' "$TITLE_RAW" | shesc)"
+title_html="$( printf '%s\n' "$TITLE_RAW" | htmlesc | shesc)"
+titlefull="$( printf '%s\n' "$TITLEFULL_RAW" | shesc)"
+titlefull_html="$(printf '%s\n' "$TITLEFULL_RAW" | htmlesc | shesc)"
+cat <<-EOF
+ export css_url="$css_url"
+ export atom_url="$atom_url"
+ export atomicon_url="$atomicon_url"
+ export favicon_url="$favicon_url"
+ export logo_url_prefix="$logo_url_prefix"
+ export envelopeicon_url_prefix="$envelopeicon_url_prefix"
+ export source_path="$source_path"
+ export url="$url"
+ export url_absolute="$url_pre/$url"
+ export base_url_prefix="$base_url_prefix"
+ export title="$title"
+ export title_html="$title_html"
+ export titlefull="$titlefull"
+ export titlefull_html="$titlefull_html"
+ export date_iso="$date_iso"
+ export date_formatted="$date_formatted"
+ export updatedat_iso="$updatedat_iso"
+ export updatedat_formatted="$updatedat_formatted"
+ export comment_url="$comment_url"
+ export discussions_url="$discussions_url"
EOF
+
+cat "$FILENAME".embedded-config
diff --git a/src/feed b/src/feed
index f202ba6..aa42899 100755
--- a/src/feed
+++ b/src/feed
@@ -1,52 +1,52 @@
#!/bin/sh
-set -eu
+set -euo pipefail
+
usage() {
- echo 'Usage: feed FILENAME'
+ echo 'Usage: feed BASECONF GLOBALCONF FILENAME.sortdata...'
}
-FILENAME="${1:-}"
-eval "$(assert-arg -- "$FILENAME" 'FILENAME')"
-
+BASECONF="${1:-}"
+GLOBALCONF="${2:-}"
+FILES="${3:-}"
+eval "$(assert-arg -- "$BASECONF" 'BASECONF')"
+eval "$(assert-arg -- "$GLOBALCONF" 'GLOBALCONF')"
+eval "$(assert-arg -- "$FILES" 'FILENAME.sortdata...')"
+. "$(realpath -- "$BASECONF")"
+. "$(realpath -- "$GLOBALCONF")"
+shift
+shift
-absolute() {
- printf 'https://domain-here.com/%s' "$(cat -)"
-}
-feed_article_title=''
-site_name=' '
-lang=en
-now="$(date -uIs)"
-url_absolute="$(printf '%s' "${FILENAME#src/}" | absolute)"
-site_name_html="$(htmlesc "${site_name:?}")"
-collection=article
-collection_url_absolute="$(printf '%s' ${lang:?}/ | absolute)"
-feed_title_html="$(eval "echo \"\$feed_${collection}_title\"" | htmlesc)"
-export now url_absolute site_name_html collection_url_absolute feed_title_html
-
-DIR="$(dirname "$FILENAME")"
-
-author=
-email=
-cat <
-
-
+ xml:lang="en">
+
+
$site_name_html
$feed_title_html
- $url_absolute
- $now
+ $feed_url_absolute
+ $now_iso
$author
$email
EOF
+}
+
+post() {
+ printf '\n'
+}
+
+pre
find "$@" |
xargs cat |
sort -nr |
+ xargs cat |
+ sed 's/\.conf$/.feedentry/' |
xargs cat
-printf '\n'
+post
diff --git a/src/feedentry b/src/feedentry
new file mode 100755
index 0000000..6299e6f
--- /dev/null
+++ b/src/feedentry
@@ -0,0 +1,53 @@
+#!/bin/sh
+set -euo pipefail
+
+
+usage() {
+ echo 'Usage: feedentry FILENAME.htmlbody'
+}
+
+FILENAME="${1:-}"
+eval "$(assert-arg -- "$FILENAME" 'FILENAME.htmlbody')"
+. "$(realpath -- "${FILENAME%.*}.conf")"
+
+
+update_xml=
+if [ -n "${updated_at:-}" ]; then
+ update_iso="$(date -ud "$updated_at" -Is)"
+ update_xml="
+ $update_iso
+ "
+fi
+
+cat <
+
+ $title_html
+
+
+
+ $date_iso
+
+$update_xml
+
+ $url_absolute
+
+
+
+ $author
+
+
+ $email
+
+
+
+
+EOF
+
+head -n5 < "$FILENAME" | htmlesc
+printf ' \n'
+printf ' \n' "${url:?}"
+
+htmlesc < "$FILENAME"
+printf ' \n'
+printf ' \n'
diff --git a/src/html b/src/html
index 007fcc2..3e100cb 100755
--- a/src/html
+++ b/src/html
@@ -1,174 +1,165 @@
#!/bin/sh
-set -eu
+set -euo pipefail
+
usage() {
- echo 'Usage: html FILENAME'
+ echo 'Usage: html FILENAME.htmlbody'
}
FILENAME="${1:-}"
-eval "$(assert-arg -- "$FILENAME" 'FILENAME')"
-
-. "${FILENAME%.*}.conf"
-
-#
-# Utility functions
-#
-
-INDENT=' '
-markdown_to_html() {
- md2html | awk -vINDENT="$INDENT" '
- BEGIN {
- in_block = 0
- }
-
- {
- if (in_block == 0) {
- printf "%s", INDENT
- }
- print
- }
-
- /^<\/code><\/pre>$/ {
- in_block = 0
- }
-
- /^
+
+ Posted on
+
+EOF
+
+ if [ -n "$updatedat_formatted" ]; then
+ cat <
+ Updated on "
+
+EOF
+ fi
+
+ cat <
+EOF
}
-extract_plaintext_snippets() (
- SNIPPETS="${FILENAME%.*}.snippets"
- printf '' > "$SNIPPETS"
- F="$(mkstemp)"
- cat > "$F"
- IFS=''
- BLOCK_NUMBER=0
- IN_BLOCK=
- while read -r line; do
- if [ "$line" = '' ]; then
- IN_BLOCK=
- fi
-
- if [ -n "$IN_BLOCK" ]; then
- printf '%s\n' "$line" | htmlesc -d >> "$OUT"
- fi
-
- if printf '%s' "$line" | grep -q "^$INDENT\)\(.*\)$|\2|" |
- htmlesc -d > "$OUT"
- printf '%s\n' "$OUT" >> "$SNIPPETS"
- fi
- done < "$F"
-
- BLOCK_NUMBER=0
- while read -r line; do
- printf '%s\n' "$line"
-
- if [ "$line" = '
' ]; then
- printf '%splaintext
\n' \
- "$INDENT" \
- "$(basename "${url_part:?}").$BLOCK_NUMBER.txt"
- BLOCK_NUMBER=$((BLOCK_NUMBER + 1))
- fi
- done < "$F"
-)
-
-add_line_numbers() {
- awk '
- /^<\/code><\/pre>$/ {
- in_block = 0
- printf "%s\n", $0
- next
- }
-
- match($0, /^( +)(.*)$/, a) {
- printf "%s", a[1]
-
- n = 1
- block_count++
- printf "| %s | %s |
\n", block_count, n, block_count, n, n, a[2]
- in_block = 1
- next
- }
-
- in_block == 1 {
- n++
- printf "| %s | %s |
\n", block_count, n, block_count, n, n, $0
- next
- }
-
- { print }
- '
-}
+h1() {
+ if [ "${custom_body:-}" = true ]; then
+ return
+ fi
-add_headings_anchors() (
- IFS=''
- while read -r line; do
- if ! printf '%s' "$line" | grep -q "^$INDENT"; then
- printf '%s\n' "$line"
- continue
- fi
- LVL="$(printf '%s' "$line" | sed "s|^$INDENT.*|\1|")"
- HEADING="$(printf '%s' "$line" | sed "s|^$INDENT\(.*\)$|\1|")"
- SLUG="$(slugify "$HEADING")"
- printf '%s\n' \
- "$INDENT" \
- "$LVL" \
- "$SLUG" \
- "$HEADING" \
- "$SLUG" \
- "${icon_link_url:?}" \
- "$LVL"
- done
-)
-
-
-warn_duplicate_ids() {
- F="$(mkstemp)"
- tee "$F"
- {
- grep "^$INDENT