about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorCase Duckworth2022-05-19 11:49:53 -0500
committerCase Duckworth2022-05-19 11:49:53 -0500
commitaf52a71c9b2d6d66ff00fb39386d8d7a5330b2b0 (patch)
treed5cfca7f6ce469b45bf4c38e4d53ae22d7bfff0a
downloadhat-trick-af52a71c9b2d6d66ff00fb39386d8d7a5330b2b0.tar.gz
hat-trick-af52a71c9b2d6d66ff00fb39386d8d7a5330b2b0.zip
Initial commit
I'm doing content + generation in this ... who knows if it's smart, lol.
-rw-r--r--.gitignore2
-rw-r--r--Makefile88
-rwxr-xr-xht.awk79
-rwxr-xr-xht.sh66
-rw-r--r--ideas.org8
-rw-r--r--src/_foot.htm6
-rw-r--r--src/_head.htm14
-rw-r--r--src/_index.htm7
-rw-r--r--src/beans.html21
-rw-r--r--src/favicon.ht15
-rw-r--r--src/gcl/index.html21
-rw-r--r--src/shameless-self-promotion/index.html11
-rw-r--r--src/static/casa.css32
-rw-r--r--src/static/rss.xml27
-rw-r--r--tmpl.index.htm16
-rw-r--r--tmpl.page.htm8
16 files changed, 421 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..af8a313 --- /dev/null +++ b/.gitignore
@@ -0,0 +1,2 @@
1.tmp
2build/
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..5b3cadd --- /dev/null +++ b/Makefile
@@ -0,0 +1,88 @@
1## HAT TRICK -*- tab-width: 8; -*-
2# (C) 2022 C. Duckworth
3
4UPLOAD_TARGET = hetzner:/var/www/acdw.casa/
5
6SITE_TITLE = acdw.casa
7
8INPUT = src
9BUILD = build
10LASTB = .last_build
11
12HTAWK = ./ht.awk
13HTSH = ./ht.sh
14HTMK = ht.mk
15HT = ${HTAWK} ${HTSH} ${HTMK}
16
17T = .tmp
18TMK = $T/mk
19TPG = $T/ps
20
21PTMPL = tmpl.page.htm
22PTMPC = \
23 <title>$$(title)</title> \
24 $$(body)
25PTMPR = \
26 $$hb: $$ht ; \
27 ${HTAWK} < '$$ht' | \
28 env HTTMP='$T' HTENV='$T/\$$<.env' HTOUT='\$$@' \
29 ${HTSH} '${PTMPL}' > '\$$@'
30
31ITMPL = tmpl.index.htm
32ITMPC = \
33 <title>${SITE_TITLE}</title> \
34 <ul id="idx"> \
35 $$(for p in "$T"/*.env; do \
36 . "$$p"; \
37 print "<li><a href=\"$$HTOUT\">$$(title)</a></li>"; \
38 done) \
39 </ul>
40ITMPR = \
41 index.html: ${ITMPL} $$(cat ${TPG}); \
42 env HTTMP='$T' HTOUT='\$$@' \
43 ${HTSH} "${ITMPL}" < /dev/null > '\$$@'
44
45TMPL = ${PTMPL} ${ITMPL}
46BUILD_INPUTS = ${INPUT}/* ${TMPL} ${HT}
47
48${BUILD}: ${BUILD_INPUTS}
49 @touch ${LASTB}
50 @mkdir -p ${BUILD}
51 cp -a ${BUILD_INPUTS} $@
52 ${MAKE} -C $@ -f ${HTMK} build
53
54${HTMK}: Makefile ${INPUT}/*.ht $T
55 @printf '%s' 'Generating "$@"...'
56 @: > '$@'
57 @: > '${TPG}'
58
59 @for ht in $$(find ${INPUT} -type f -name '*.ht'); do \
60 ht="$$(echo "$$ht" | sed 's#${INPUT}/##')"; \
61 hb="$${ht}ml"; \
62 printf '%s ' "$$hb" >> "${TPG}"; \
63 printf '%s\n' "${PTMPR}"; \
64 done >> '$@'
65
66 @printf '%s\n' "${ITMPR}" >> '$@'
67 @printf "build: $$(cat ${TPG}) index.html" >> '$@'
68 @printf '%s\n' 'done'
69
70$T: ; mkdir -p "$@"
71${PTMPL}: ; printf '${PTMPC}' > '$@'
72${ITMPL}: ; printf '${ITMPC}' > '$@'
73
74.PHONY: clean clean-build nuke
75clean: ; -rm -rf ${BUILD} ${HTMK} $T ${LASTB}
76clean-build:
77 rm -rf '${BUILD}/$T'
78 for file in ${BUILD}/*; do \
79 case "$$file" in \
80 *.ht|*.sh|*.htm|*.mk|*.awk) rm -rf "$$file" ;; \
81 esac \
82 done
83nuke: clean ; -rm ${TMPL}
84
85.PHONY: publish
86publish: build clean-build
87 scp -r ${BUILD}/* '${UPLOAD_TARGET}'; \
88
diff --git a/ht.awk b/ht.awk new file mode 100755 index 0000000..5328361 --- /dev/null +++ b/ht.awk
@@ -0,0 +1,79 @@
1#!/usr/bin/awk -f
2# HAT TRICK
3# (C) 2022 C. Duckworth
4
5# ht.awk converts mostly-html (with some conveniences) to actual html
6
7function bufpush(s) {
8 BUF = BUF (BUF ? "\n" : "") s;
9}
10
11function buflush() {
12 if (BUF) print BUF;
13 BUF = "";
14 if (tag && (tag != "html")) print "</" tag ">";
15}
16
17function esc(t) {
18 gsub(/&/, "\\&amp;", t);
19 gsub(/</, "\\&lt;", t);
20 gsub(/>/, "\\&gt;", t);
21 return t;
22}
23
24/^;/ { sub(/^;/,""); print "<!--", esc($0), "-->"; next; }
25
26/^</ { # Raw HTML
27 if (! (tag == "html")) tag = "html";
28 bufpush($0);
29 next;
30}
31
32/^=>/ { # Links (Gemini-style)
33 link = "<a href=\"" esc($2) "\">" esc($3);
34 for (i=4;i<=NF;i++) link = link " " esc($i);
35 link = link "</a>";
36 bufpush(link);
37 next;
38}
39
40/^-/ { # Unordered lists
41 if (! (tag == "ul")) tag = "ul";
42 esc($0);
43 sub(/^-[ \t]*/, "<li>");
44}
45
46/^[0-9]+\./ { # Ordered lists
47 if (! (tag == "ol")) tag = "ol";
48 esc($0);
49 sub(/^[0-9]+\.[ \t]/, "<li>");
50}
51
52/^>/ { # Blockquotes
53 if (! (tag == "blockquote")) tag = "blockquote";
54 sub(/^>[ \t]*/,"");
55 esc($0);
56}
57
58/^#+/ { # Headers
59 match($0, /^#+/);
60 if (! (tag == "h" RLENGTH)) {
61 buflush();
62 tag = "h" RLENGTH;
63 }
64 sub(/^#+[ \t]*/,"");
65 esc($0);
66}
67
68/^$/ {
69 buflush();
70 tag = "";
71}
72
73/./ {
74 if (! tag) tag = "p";
75 if (! BUF) bufpush("<" tag ">");
76 bufpush($0);
77}
78
79END { buflush(); }
diff --git a/ht.sh b/ht.sh new file mode 100755 index 0000000..de58fe1 --- /dev/null +++ b/ht.sh
@@ -0,0 +1,66 @@
1#!/bin/sh
2# HAT TRICK
3# (C) 2022 C. Duckworth
4
5[ "x$DEBUG" = "xYES" ] && set -x
6
7: "${HTDAT:=$(date +%s)}"
8: "${HTTMP:=/tmp/ht}"; mkdir -p "$HTTMP"
9: "${HTENV:=$HTTMP/env-$HTDAT.sh}"
10: "${HTBOD:=$HTTMP/bod-$HTDAT.txt}"
11export HTDAT HTTMP HTENV HTBOD
12
13HT_TMPL_COUNT=1
14HT_TMPL_PRE=:
15
16print() { # print STRING...
17 ## A sane version of `echo`.
18 printf '%s\n' "$*"
19}
20
21htt() { # htt FILES...
22 # Like `cat`, but with templating.
23 ht_end="ht_main_$HTDAT_$HT_TMPL_COUNT" # be extra double sure
24 eval "$(print "cat <<$ht_end"; cat "$@"; print; print "$ht_end")"
25 HT_TMPL_COUNT=$(expr $HT_TMPL_COUNT + 1)
26}
27
28ht_build_env() { # ht_build_env FILE...
29 print "body() { cat \"$HTBOD\"; }" > "$HTENV"
30 while read -r line; do
31 case "$line" in
32 *@@*:*@@*) # "simple" metadata; just a string
33 print "$line" |
34 sed 's/.*@@\([^:]*\): \?\(.*\)@@.*/\1() { print "\2"; }/'
35 ;;
36 *@@*::*@@*) # "complex" metadata: can be anything
37 print "$line" |
38 sed 's/.*@@\([^:]*\):: \?\(.*\)@@.*/\1() { \2 ; }/'
39 ;;
40 esac >> "$HTENV"
41 # Still print the line to the body (no need to escape or w/e)
42 print "$line" >> "$HTBOD"
43 done
44 env | grep '^HT' | sort | uniq >> "$HTENV"
45}
46
47ht_main() { # main TEMPLATE < INPUT
48 ## Apply TEMPLATE to INPUT and print it.
49 # TEMPLATE will be interpreted as a heredoc.
50 if [ $# -eq 0 ]; then
51 print "ht.sh TEMPLATE < INPUT" >&2
52 exit 1
53 fi
54
55 eval "ht_build_env; . \"$HTENV\"; print \"\$(htt \"\$@\")\";";
56}
57
58# To keep this POSIX-compliant, we can't use a bashism like
59# [[ "$0" == # "$BASH_SOURCE[0]" ]]. However, there are still ways to guess
60# whether the user is sourcing this file as a library or executing it as a
61# script.
62
63case "$0" in
64 *ht.sh) ht_main "$@" ;;
65 *) print "Sourcing ht.sh" ;;
66esac
diff --git a/ideas.org b/ideas.org new file mode 100644 index 0000000..27b15e5 --- /dev/null +++ b/ideas.org
@@ -0,0 +1,8 @@
1#+TITLE: ideas for hat-trick
2
3* Syntax: ht.awk
4
5It'd be great to have a format that could triple into HTML, Gemini, and Gopher. Gemini-like, line-based syntax would be easiest to work with, i think.
6
7The current separation into paragraphs with blocks is a good idea. Also, starting a line with ~<~ /within/ a paragraph could be a good signal that the following is HTML code. Maybe auto-close the tag?
8
diff --git a/src/_foot.htm b/src/_foot.htm new file mode 100644 index 0000000..287b2ba --- /dev/null +++ b/src/_foot.htm
@@ -0,0 +1,6 @@
1<footer>
2 $(case "$(title)" in ("") ;; (*) print "<a href=\"./index.html\">back</a>" ;; esac)
3 <span id="copyright">(C) 2022 C. Duckworth</span>
4</footer>
5</body>
6</html>
diff --git a/src/_head.htm b/src/_head.htm new file mode 100644 index 0000000..762965e --- /dev/null +++ b/src/_head.htm
@@ -0,0 +1,14 @@
1<!DOCTYPE html>
2<html lang="en">
3 <head>
4 <meta charset="utf-8">
5 <meta http-equiv="x-ua-compatible" content="ie=edge">
6 <meta name="viewport"
7 content="width=device-width,initial-scale=1,shrink=to-fit=no">
8 <title>$(title)</title>
9 <link rel="shortcut icon"
10 href="data:image/gif;base64,R0lGODdhEAAQAIAAAAByL8zAGiwAAAAAEAAQAAACK4wNqQsX+1hD6kiaXKxQb+ZZYChmpGNinfpxV/q02dzUrx1L+Lzlp60LFgAAOw==" />
11 <link rel="stylesheet" type="text/css" href="static/casa.css">
12 <link rel="alternate" type="application/atom+xml" href="static/rss.xml">
13 </head>
14 <body>
diff --git a/src/_index.htm b/src/_index.htm new file mode 100644 index 0000000..6b7b809 --- /dev/null +++ b/src/_index.htm
@@ -0,0 +1,7 @@
1<p>Ahoy! This here is my little home-away-from-home on the interwebs.
2 I'm currently experimenting with a custom little <abbr title="static site generator">SSG</abbr>
3 I'm calling <strong>HAT TRICK</strong>.
4 I should probably throw the source up somewhere, but I haven't yet.
5</p>
6
7
diff --git a/src/beans.html b/src/beans.html new file mode 100644 index 0000000..ff89934 --- /dev/null +++ b/src/beans.html
@@ -0,0 +1,21 @@
1html,body {
2 min-height: 100vh;
3 margin:0; padding: 0;
4}
5
6html {
7 font: 18px serif;
8 background: #385180;
9}
10
11body {
12 max-width: 79ch;
13 padding: 0 2ch;
14 margin: 0 auto;
15 background: #405990;
16 color: white;
17}
18
19a {
20 color: yellow;
21}
diff --git a/src/favicon.ht b/src/favicon.ht new file mode 100644 index 0000000..b9df118 --- /dev/null +++ b/src/favicon.ht
@@ -0,0 +1,15 @@
1;@@title: Embedded data-url favicon@@
2
3You might notice that I have a <b>new favicon</b> on this site.
4I didn't want to make a whole nother request, so I took a page from
5=> http://flower.codes/2022/05/10/disabling-favicon.html flower.codes
6(who disabled their favicon completely) and made my favicon a <code>data</code> uri.
7
8I thought it might be complicated, but it was really pretty ding dang easy.
9I found an easy-to-use
10=> https://www.adminbooster.com/tool/data_uri file-to-data-uri converter tool
11and uploaded a little image I made in the
12<abbr title="GNU Image Manipulation Program">GIMP</abbr>. I tried PNG and GIF.
13GIF was much smaller, so that's what I went with.
14
15Anyway, now you should see a little house on the tab you've loaded this on! Yay.
diff --git a/src/gcl/index.html b/src/gcl/index.html new file mode 100644 index 0000000..3357702 --- /dev/null +++ b/src/gcl/index.html
@@ -0,0 +1,21 @@
1<!DOCTYPE html>
2<html>
3 <head>
4 <meta charset="utf-8">
5 <title>Good Choices License</title>
6 <style>
7 body{max-width:78ch;padding:2ch;margin:auto;font:24px serif;}
8 h1{font-size:2em;}
9 </style>
10 </head>
11 <body>
12 <h1>Good Choices License</h1>
13 <p>Everyone is permitted to do whatever they like with this software
14 without limitation. This software comes without any warranty
15 whatsoever, but with two pieces of advice:</p>
16 <ul>
17 <li>Be kind to yourself.</li>
18 <li>Make good choices.</li>
19 </ul>
20 </body>
21</html>
diff --git a/src/shameless-self-promotion/index.html b/src/shameless-self-promotion/index.html new file mode 100644 index 0000000..f4c5710 --- /dev/null +++ b/src/shameless-self-promotion/index.html
@@ -0,0 +1,11 @@
1<html>
2 <head>
3 <title>Shameless self-promotion!</title>
4 </head>
5 <body>
6 <h1>shameless</h1>
7 <h2>self</h2>
8 <h3>promotion</h3>
9 <p>what can i say, i'm a cool guy.</p>
10 </body>
11</html>
diff --git a/src/static/casa.css b/src/static/casa.css new file mode 100644 index 0000000..36bdda0 --- /dev/null +++ b/src/static/casa.css
@@ -0,0 +1,32 @@
1html {
2 min-height: 100vh;
3 margin:0; padding: 0;
4}
5
6html {
7 font: 18px serif;
8}
9
10body {
11 max-width: 79ch;
12 margin: 0 auto;
13 padding: 0 2ch;
14 background: #385180;
15 color: white;
16}
17
18main {
19 max-width: 79ch;
20 padding: 2ch;
21 margin: auto;
22 background: #405990;
23}
24
25a {
26 color: yellow;
27}
28
29footer {
30 text-align: right;
31 padding: 1ch 0;
32}
diff --git a/src/static/rss.xml b/src/static/rss.xml new file mode 100644 index 0000000..44617d8 --- /dev/null +++ b/src/static/rss.xml
@@ -0,0 +1,27 @@
1<?xml version="1.0" encoding="UTF-8" ?>
2<rss version="2.0">
3<channel>
4 <title>Acdw's Casa</title>
5 <description>My casa, in the middle of the web</description>
6 <link>https://acdw.casa</link>
7 <copyright>2022 Case Duckworth</copyright>
8 <lastBuildDate>2022-03-03</lastBuildDate>
9 <pubDate>2022-03-03</pubDate>
10 <ttl>1800</ttl>
11
12 <item>
13 <title>And we're live</title>
14 <description>Hi basement</description>
15 <link>https://acdw.casa/</link>
16 <pubDate>2022-03-03</pubDate>
17 </item>
18
19 <item>
20 <title>Good Choices License</title>
21 <description>A license for people</description>
22 <link>https://acdw.casa/gcl/</link>
23 <pubDate>2022-05-13</pubDate>
24 </item>
25
26</channel>
27</rss>
diff --git a/tmpl.index.htm b/tmpl.index.htm new file mode 100644 index 0000000..dc90a4d --- /dev/null +++ b/tmpl.index.htm
@@ -0,0 +1,16 @@
1$(sed 's#$(title)#acdw.casa#' _head.htm)
2<header>
3 <h1>mi casa es su casa</h1>
4</header>
5<main>
6 <section id="welcome">
7 $(htt _index.htm)
8 </section>
9 <section id="pages">
10 <h2>pages here</h2>
11 <ul>
12 $(set -x;for p in ".tmp"/*.env; do . "$p"; print "<li><a href=\"$HTOUT\">$(title)</a></li>"; done)
13 </ul>
14 </section>
15</main>
16$(htt _foot.htm)
diff --git a/tmpl.page.htm b/tmpl.page.htm new file mode 100644 index 0000000..4165681 --- /dev/null +++ b/tmpl.page.htm
@@ -0,0 +1,8 @@
1$(htt _head.htm)
2 <header>
3 <h1>$(title)</h1>
4 </header>
5 <main>
6 $(body)
7 </main>
8$(htt _foot.htm)