diff options
Diffstat (limited to 'src')
-rwxr-xr-x | src/conf | 30 | ||||
-rwxr-xr-x | src/feed | 52 | ||||
-rwxr-xr-x | src/html | 174 | ||||
-rwxr-xr-x | src/htmlbody | 4 | ||||
-rwxr-xr-x | src/mkwb.in | 12 | ||||
-rwxr-xr-x | src/sortdata | 14 | ||||
-rwxr-xr-x | src/xmlentry | 48 |
7 files changed, 334 insertions, 0 deletions
diff --git a/src/conf b/src/conf new file mode 100755 index 0000000..6aa6761 --- /dev/null +++ b/src/conf @@ -0,0 +1,30 @@ +#!/bin/sh +set -eu + + +usage() { + echo 'Usage: conf FILENAME' +} + +FILENAME="${1:-}" +eval "$(assert-arg -- "$FILENAME" 'FILENAME')" + + +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 +EOF diff --git a/src/feed b/src/feed new file mode 100755 index 0000000..f202ba6 --- /dev/null +++ b/src/feed @@ -0,0 +1,52 @@ +#!/bin/sh +set -eu + +usage() { + echo 'Usage: feed FILENAME' +} + +FILENAME="${1:-}" +eval "$(assert-arg -- "$FILENAME" 'FILENAME')" + + +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 <<EOF +<feed + xmlns="http://www.w3.org/2005/Atom" + xmlns:content="http://purl.org/rss/1.0/modules/content/" + xml:lang="$lang"> + <link href="$url_absolute" rel="self" type="application/atom+xml" /> + <link href="$collection_url_absolute" rel="alternate" type="text/html" hreflang="$lang" /> + <title>$site_name_html</title> + <subtitle>$feed_title_html</subtitle> + <id>$url_absolute</id> + <updated>$now</updated> + + <author> + <name>$author</name> + <email>$email</email> + </author> +EOF +find "$@" | + xargs cat | + sort -nr | + xargs cat +printf '</feed>\n' diff --git a/src/html b/src/html new file mode 100755 index 0000000..007fcc2 --- /dev/null +++ b/src/html @@ -0,0 +1,174 @@ +#!/bin/sh +set -eu + +usage() { + echo 'Usage: html FILENAME' +} + +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 + } + + /^<pre><code/ { + in_block = 1 + } + ' +} + +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" = '</code></pre>' ]; then + IN_BLOCK= + fi + + if [ -n "$IN_BLOCK" ]; then + printf '%s\n' "$line" | htmlesc -d >> "$OUT" + fi + + if printf '%s' "$line" | grep -q "^$INDENT<pre><code"; then + IN_BLOCK=1 + OUT="${FILENAME%.*}.html.$BLOCK_NUMBER.txt" + BLOCK_NUMBER=$((BLOCK_NUMBER + 1)) + printf '%s\n' "$line" | + sed "s|^\($INDENT<pre><code.*>\)\(.*\)$|\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" = '</code></pre>' ]; then + printf '%s<p class="plaintext-link"><a href="%s">plaintext</a></p>\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 "</tbody></table>%s\n", $0 + next + } + + match($0, /^( +<pre><code.*>)(.*)$/, a) { + printf "%s<table rules=columns class=\"code-block\"><tbody>", a[1] + + n = 1 + block_count++ + printf "<tr><td class=\"line-number\"><a id=\"B%s-L%s\" href=\"#B%s-L%s\">%s</a></td><td class=\"code-line\">%s</td></tr>\n", block_count, n, block_count, n, n, a[2] + in_block = 1 + next + } + + in_block == 1 { + n++ + printf "<tr><td class=\"line-number\"><a id=\"B%s-L%s\" href=\"#B%s-L%s\">%s</a></td><td class=\"code-line\">%s</td></tr>\n", block_count, n, block_count, n, n, $0 + next + } + + { print } + ' +} + +add_headings_anchors() ( + IFS='' + while read -r line; do + if ! printf '%s' "$line" | grep -q "^$INDENT<h[2-6]>"; then + printf '%s\n' "$line" + continue + fi + LVL="$(printf '%s' "$line" | sed "s|^$INDENT<h\(.\)>.*|\1|")" + HEADING="$(printf '%s' "$line" | sed "s|^$INDENT<h.>\(.*\)</h.>$|\1|")" + SLUG="$(slugify "$HEADING")" + printf '%s<h%s class="header-anchor" id="%s">%s<a href="#%s" aria-hidden="true"><img class="svg-icon" src="%s" /></a></h%s>\n' \ + "$INDENT" \ + "$LVL" \ + "$SLUG" \ + "$HEADING" \ + "$SLUG" \ + "${icon_link_url:?}" \ + "$LVL" + done +) + + +warn_duplicate_ids() { + F="$(mkstemp)" + tee "$F" + { + grep "^$INDENT<h[2-6] class=\"header-anchor\" id=\"" | + sed "s|^$INDENT<h[2-6] class=\"header-anchor\" id=\"\(.*\)\">.*<a href=.*$|\1|" | + sort | + uniq -c | + awk -v F="$FILENAME" '$1 != 1 { + printf "WARNING: duplicate header id: %s: %s\n", F, $2 + }' + } >&2 < "$F" + rm "$F" +} + +emit_body() { + < "${FILENAME%.*}.content" \ + markdown_to_html | + extract_plaintext_snippets | + add_line_numbers | + add_headings_anchors | + warn_duplicate_ids +} + +if [ -r "$FILENAME".prev ]; then + collection_head_prev_html="$( + printf ' <link rel="prev" type="text/html" href="%s" />' \ + "$(url-for < "$FILENAME".prev)" + )" + export collection_head_prev_html +fi + +if [ -r "$FILENAME".next ]; then + collection_head_next_html="$( + printf ' <link rel="next" type="text/html" href="%s" />' \ + "$(url-for < "$FILENAME".next)" + )" + export collection_head_next_html +fi + +envsubst < lib/preamble.html | sed '/^$/d' +emit_body | tee "${FILENAME%.*}.htmlbody" +envsubst < lib/postamble.html | sed '/^$/d' diff --git a/src/htmlbody b/src/htmlbody new file mode 100755 index 0000000..53a4485 --- /dev/null +++ b/src/htmlbody @@ -0,0 +1,4 @@ +#!/bin/sh +set -eu + +cat "${1:--}" | asciidoctor -s - diff --git a/src/mkwb.in b/src/mkwb.in new file mode 100755 index 0000000..2c698e1 --- /dev/null +++ b/src/mkwb.in @@ -0,0 +1,12 @@ +#!/bin/sh +set -eu + +usage() { + echo 'Usage: mkwb ACTION [OPTION...]' +} + +ACTION="${1:-}" +eval "$(assert-arg -- "$ACTION" 'ACTION')" +shift + +exec '@LIBEXECDIR@'/"$ACTION" "$@" diff --git a/src/sortdata b/src/sortdata new file mode 100755 index 0000000..5b0b238 --- /dev/null +++ b/src/sortdata @@ -0,0 +1,14 @@ +#!/bin/sh +set -eu + +usage() { + echo 'Usage: sortdata ENTRYPATH' +} + +ENTRYPATH="${1:-}" +eval "$(assert-arg -- "$ENTRYPATH" 'ENTRYPATH')" +. "${ENTRYPATH%.*}.conf" + +f=src/"$date_iso".sortdata +ln -frs "${ENTRYPATH%.*}.xmlentry" "$f" # FIXME: -r is no POSIX +printf '%s\n' "$f" diff --git a/src/xmlentry b/src/xmlentry new file mode 100755 index 0000000..c2458d1 --- /dev/null +++ b/src/xmlentry @@ -0,0 +1,48 @@ +#!/bin/sh +set -eu + + +usage() { + echo 'Usage: xmlentry FILENAME' +} + +FILENAME="${1:-}" +eval "$(assert-arg -- "$FILENAME" 'FILENAME')" +. "${FILENAME%.*}.conf" + + +title_html= +url_absolute= +update_xml= +cat <<EOF + <entry xml:lang="$lang"> + <title type="html"> + $title_html + </title> + <link type="text/html" rel="alternative" href="$url_absolute" title="$title_html" /> + <published> + $date_iso + </published> +$update_xml + <id> + $url_absolute + </id> + <author> + <name> + $author + </name> + <email> + $email + </email> + </author> + + <summary type="html"> +EOF + +head -n1 < "${FILENAME%.*}.htmlbody" | htmlesc +printf ' </summary>\n' +printf ' <content type="html" xml:base="%s">\n' "${url:?}" + +htmlesc < "${FILENAME%.*}.htmlbody" +printf ' </content>\n' +printf ' </entry>\n' |