aboutsummaryrefslogtreecommitdiff
path: root/v2/src
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--v2/src/content/pastebins/sicp-exercise-3-19.md113
l---------v2/src/content/security.txt1
l---------v2/src/content/static/atom.svg1
l---------v2/src/content/static/envelope.svg1
l---------v2/src/content/static/favicon.svg1
l---------v2/src/content/static/link.svg1
l---------v2/src/content/static/lock.svg1
l---------v2/src/content/static/public.asc.txt1
-rw-r--r--v2/src/content/static/styles.css149
-rw-r--r--v2/src/development/config.env.in5
-rwxr-xr-xv2/src/development/dynmake.sh75
-rwxr-xr-xv2/src/development/genhtml.sh332
12 files changed, 681 insertions, 0 deletions
diff --git a/v2/src/content/pastebins/sicp-exercise-3-19.md b/v2/src/content/pastebins/sicp-exercise-3-19.md
new file mode 100644
index 0000000..fd2c52b
--- /dev/null
+++ b/v2/src/content/pastebins/sicp-exercise-3-19.md
@@ -0,0 +1,113 @@
+---
+
+TITLE='SICP exercise 3.19'
+
+DATE='2021-09-02'
+
+LAYOUT='post'
+
+LANGUAGE='en'
+
+REF='sicp-exercise-3-19'
+
+---
+
+Some content here, before:
+
+```scheme
+(define (cycle? l)
+ (define (rec l x)
+ (cond
+ ((null? x) false)
+ ((eq? l x) true)
+ (true (rec l (cdr x)))))
+ (rec l (cdr l)))
+```
+
+Sample interactive session:
+
+```scheme
+scheme@(guile-user)> (define true #t)
+scheme@(guile-user)> (define false #f)
+scheme@(guile-user)>
+(define (cycle? l)
+ (define (rec l x)
+ (cond
+ ((null? x) false)
+ ((eq? l x) true)
+ (true (rec l (cdr x)))))
+ (rec l (cdr l)))
+scheme@(guile-user)> (cycle? '(1 2 3))
+$9 = #f
+scheme@(guile-user)> (cycle? (make-cycle '(1 2 3)))
+$10 = #t
+```
+
+# An h1
+
+a list:
+
+1. one
+2. two
+3. three
+
+some content.
+
+- item
+- another
+- yet another
+
+## An h2
+
+Xablau:
+
+```
+xupliu 1
+
+3
+4
+
+
+
+
+
+dez
+```
+
+Foi `wikiwiu`.
+
+a very long code block:
+
+```
+wef
+wef wef wef wef
+wef wef wef wef we fwef wef wef wef wef
+```
+
+Someone said:
+
+> Xablau, xupliu.
+
+### A repeated header
+### A repeated header
+
+a big list:
+
+1. a
+1. a
+1. a
+1. a
+1. a
+1. a
+1. a
+1. a
+1. a
+1. a
+1. a
+1. a
+1. a
+1. a
+1. a
+1. a
+1. a
+1. a
diff --git a/v2/src/content/security.txt b/v2/src/content/security.txt
new file mode 120000
index 0000000..abdf74b
--- /dev/null
+++ b/v2/src/content/security.txt
@@ -0,0 +1 @@
+.well-known/security.txt \ No newline at end of file
diff --git a/v2/src/content/static/atom.svg b/v2/src/content/static/atom.svg
new file mode 120000
index 0000000..41c6d3f
--- /dev/null
+++ b/v2/src/content/static/atom.svg
@@ -0,0 +1 @@
+../../../../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
new file mode 120000
index 0000000..bd0c577
--- /dev/null
+++ b/v2/src/content/static/envelope.svg
@@ -0,0 +1 @@
+../../../../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
new file mode 120000
index 0000000..33566ab
--- /dev/null
+++ b/v2/src/content/static/favicon.svg
@@ -0,0 +1 @@
+../../../../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
new file mode 120000
index 0000000..bf69c40
--- /dev/null
+++ b/v2/src/content/static/link.svg
@@ -0,0 +1 @@
+../../../../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
new file mode 120000
index 0000000..f9a4f33
--- /dev/null
+++ b/v2/src/content/static/lock.svg
@@ -0,0 +1 @@
+../../../../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
new file mode 120000
index 0000000..5175f38
--- /dev/null
+++ b/v2/src/content/static/public.asc.txt
@@ -0,0 +1 @@
+../../../../public.asc \ No newline at end of file
diff --git a/v2/src/content/static/styles.css b/v2/src/content/static/styles.css
new file mode 100644
index 0000000..0ec67a8
--- /dev/null
+++ b/v2/src/content/static/styles.css
@@ -0,0 +1,149 @@
+/* General declarations */
+
+body {
+ margin: 0px auto;
+ padding: 1%;
+ max-width: 750px;
+}
+
+.svg-icon {
+ vertical-align: middle;
+}
+
+
+/* Navigation header */
+
+nav a {
+ color: maroon;
+ font-size: 18px;
+ margin: 12px;
+ text-decoration: none;
+}
+
+nav ul, nav li {
+ display: inline;
+}
+
+nav ul li a {
+ color: black;
+ font-size: 14px;
+ margin: 6px;
+}
+
+
+/* Article bodies */
+
+.timestamp {
+ color: #555;
+ font-size: 14px;
+ font-style: italic;
+}
+
+blockquote {
+ font-style: italic;
+ color: dimgrey;
+ padding-left: 10px;
+ border-left: 3px solid #ccc;
+}
+
+ul.no-style {
+ list-style-type: none;
+}
+
+ul.no-style li {
+ margin: 20px 0px;
+}
+
+
+/* Footer */
+
+footer {
+ font-size: 14px;
+ margin-top: 30px;
+ padding: 12px 0px 12px 0px;
+}
+
+footer li {
+ list-style-type: none;
+ margin-top: 10px;
+}
+
+footer li a {
+ margin-left: 5px;
+ user-select: none;
+}
+
+/* Code blocks */
+
+/* The "lineno" class is the default generated by Rouge for table-row in code blocks, see:
+ https://github.com/rouge-ruby/rouge */
+.line-number, pre.lineno {
+ margin-right: 3px;
+ padding-right: 3px;
+ border-right: 1px solid;
+ border-color: hsla(0, 0%, 0%, 0.3);
+ text-align: right;
+ user-select: none;
+}
+
+.code-line {
+ padding-left: 8px;
+}
+
+.code-block {
+ padding: 6px 4px;
+ display: block;
+}
+
+.code-block, pre.highlight {
+ border: 1px solid #ccc;
+ border-radius: 10px;
+}
+
+pre {
+ overflow: auto;
+}
+
+
+/* Code block anchors */
+
+.line-number a, a.code-line-anchor {
+ color: black;
+ text-decoration: none;
+}
+
+a.code-line-anchor:hover {
+ text-decoration: underline;
+}
+
+
+/* Header anchor */
+
+.header-anchor {
+ color: black;
+ text-decoration: none;
+ display: block;
+ margin-bottom: 15px;
+}
+
+.header-anchor {
+}
+
+
+.header-anchor img {
+ margin-left: 5px;
+ visibility: hidden;
+}
+
+.header-anchor:hover img {
+ visibility: visible;
+}
+
+
+/* Plaintext code block links */
+
+.plaintext-link {
+ margin: auto auto 0 auto;
+ text-align: right;
+ font-family: monospace;
+}
diff --git a/v2/src/development/config.env.in b/v2/src/development/config.env.in
new file mode 100644
index 0000000..18d5367
--- /dev/null
+++ b/v2/src/development/config.env.in
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+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
new file mode 100755
index 0000000..a04e70e
--- /dev/null
+++ b/v2/src/development/dynmake.sh
@@ -0,0 +1,75 @@
+#!/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'
diff --git a/v2/src/development/genhtml.sh b/v2/src/development/genhtml.sh
new file mode 100755
index 0000000..953a80d
--- /dev/null
+++ b/v2/src/development/genhtml.sh
@@ -0,0 +1,332 @@
+#!/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
+# - make url_for a standalone executable
+# - config.env should depend on dynamic.mk?
+
+
+
+usage() {
+ cat <<-'EOF'
+ Usage:
+ genhtml.sh FILENAME
+ genhtml.sh -h
+ EOF
+}
+
+help() {
+ cat <<-'EOF'
+
+ Options:
+ -h, --help show this message
+
+ FILENAME the name of the input file, to also be used as
+ URL
+
+
+ Process the FILENAME, and generate a full HTML page.
+
+ The FILENAME is used to infer the output URL, by removing the
+ `src/content/` prefix, and replacing the trailing `.md` with
+ `.html`. This URL is used to build the self-referencing
+ "canonical" link, extracting plaintext snippets, etc.
+
+
+ Examples:
+
+ Generate the HTML for a pastebin:
+
+ $ sh genhtml.sh src/content/a-paste.md > src/content/a-paste.html
+ EOF
+}
+
+
+for f in "$@"; do
+ case "$f" 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))
+
+
+FILENAME="${1:-}"
+eval "$(assert-arg "$FILENAME" 'FILENAME')"
+
+
+#
+# Utility functions
+#
+
+url_for() {
+ printf '%s/%s' "$BASE_URL" "$1"
+}
+
+absolute() {
+ printf 'https://%s%s' "$FQDN" "$(cat)"
+}
+
+translate() {
+ printf '%s' "$1"
+}
+
+_() {
+ translate "$1" | html
+}
+
+SEEN_SLUGS="$(mkstemp)"
+slugify_once() {
+ SLUG="$(printf '%s' "$1" | slugify)${2:+-$2}"
+ if grep -q "^$SLUG$" "$SEEN_SLUGS"; then
+ N="${2:-0}"
+ N=$((N + 1))
+ slugify_once "$1" "$N"
+ else
+ printf '%s\n' "$SLUG" >> "$SEEN_SLUGS"
+ printf '%s' "$SLUG"
+ fi
+}
+
+extract_content() {
+ awk '
+ separator >= 2
+ /^---$/ { separator++ }
+ '
+}
+
+add_preamble() {
+ printf '%s\n%s\n' "$PREAMBLE" "$(cat -)"
+}
+
+markdown_to_html() {
+ md2html
+}
+
+extract_plaintext_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" | html -d >> "$OUT"
+ fi
+
+ if printf '%s' "$line" | grep -q '^<pre><code.*>'; then
+ IN_BLOCK=1
+ OUT="${FILENAME%.md}.html.$BLOCK_NUMBER.txt"
+ BLOCK_NUMBER=$((BLOCK_NUMBER + 1))
+ printf '%s\n' "$line" |
+ sed 's|^\(<pre><code.*>\)\(.*\)$|\2|' |
+ html -d > "$OUT"
+ fi
+ done < "$F"
+
+ BLOCK_NUMBER=0
+ while read -r line; do
+ printf '%s\n' "$line"
+
+ if [ "$line" = '</code></pre>' ]; then
+ printf '<p class="plaintext-link"><a href="%s.%s.txt">plaintext</a></p>\n' "$(url_for "$URL")" "$BLOCK_NUMBER"
+ 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 '^<h[2-6]>'; then
+ printf '%s\n' "$line"
+ continue
+ fi
+ LVL="$(printf '%s' "$line" | sed 's|^<h\(.\)>.*|\1|')"
+ HEADING="$(printf '%s' "$line" | sed 's|^<h.>\(.*\)</h.>$|\1|')"
+ SLUG="$(slugify_once "$HEADING")"
+ printf '<h%s class="header-anchor" id="%s">%s<a href="#%s" aria-hidden="true"><img class="svg-icon" src="%s" /></a></h%s>\n' \
+ "$LVL" \
+ "$SLUG" \
+ "$HEADING" \
+ "$SLUG" \
+ "$(url_for 'static/link.svg')" \
+ "$LVL"
+ done
+ )
+}
+
+emit_body() {
+ cat "$FILENAME" |
+ extract_content |
+ add_preamble |
+ markdown_to_html |
+ extract_plaintext_snippets |
+ add_line_numbers |
+ add_headings_anchors
+}
+
+
+#
+# Environment variables
+#
+
+. src/development/config.env
+
+eval "$(
+ awk '
+ /^---$/ { if (++separator > 1) exit; else next; }
+ { print }
+ ' "$FILENAME"
+)"
+
+SITE_NAME="$(_ "EuAndreh's website")"
+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
+)"
+
+
+
+#
+# Main: generate the HTML to STDOUT.
+#
+
+cat <<-EOF
+ <!DOCTYPE html>
+ <html lang="$LANGUAGE">
+ <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')" />
+
+ <title>$TITLE</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" />
+
+ <link rel="canonical" href="$(url_for "$URL" | absolute)" />
+ <meta property="og:url" content="$(url_for "$URL" | absolute)" />
+ </head>
+ <body>
+ <header>
+ <nav>
+ <ul>
+ <a href="$(url_for "$LANGUAGE/")">$(_ 'EuAndreh')</a>
+ <a href="$(url_for "$(_ 'about.html')")">$(_ 'About')</a>
+ </ul>
+ </nav>
+ <hr />
+ </header>
+ <main>
+ <article>
+ $(emit_body)
+ <hr />
+ <p class="post-footer">
+ <a href="mailto:~euandreh/public-inbox@lists.sr.ht?Subject=Re%3A%20$URI_TITLE">Comment</a>
+ and see
+ <a href="https://lists.sr.ht/~euandreh/public-inbox?search=$URI_TITLE">existing discussions</a>
+ |
+ <a href="https://euandreh.xyz/euandre.org.git/tree/$FILENAME">view source</a>
+ </p>
+ </article>
+ </main>
+ <footer>
+ <hr />
+ <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>
+ </li>
+ <li>
+ <img class="svg-icon" src="$(url_for 'static/lock.svg')" alt="$(_ 'a lock icon representing a GPG public key')" />
+ <a href="$(url_for 'static/public.asc.txt')">81F90EC3CD356060</a>
+ </li>
+ </ul>
+ <p>
+ $(translate 'The content for this site is licensed under <a rel="license" href="https://creativecommons.org/licenses/by-sa/4.0/">CC BY-SA 4.0</a>. The <a href="https://euandreh.xyz/euandre.org.git">code</a> is <a rel="license" href="https://euandreh.xyz/euandre.org.git/tree/COPYING">AGPLv3 or later</a>. Patches welcome.')
+ </p>
+ </footer>
+ </body>
+ </html>
+EOF