commit 537a54c1497d253bea489ed32faec92b15d843d3 (patch)
parent 53aa6026e114503c141213d08e573130b7a79c2f
Author: Alex Karle <alex@alexkarle.com>
Date: Tue, 14 Dec 2021 00:35:12 -0500
Move whole site from mdoc->nihdoc, with blog post!
This is a mega commit from weeks of work on nihdoc [1] and generally
reshaping every page on the website. I'm really pleased with how it
turned out & am ready to show it to the world!
Some big changes:
- All pages are now .txt source instead of .7 mdoc, using my own
custom markup parser (to keep it all in base)
- New blog post announcing changes
- The new format meant genatom and the gopher listing needed
reworking (I think both look significantly better!)
- All blog posts moved to /blog/ to enable a breadcrumb-style
navigation. I'll set up redirects on httpd(8) to keep old links
working as expected
- All files moved into the www/ directory to match how the gopher/
directory is gopher-specific
- The source (.txt) is now being bundled in the install, so that
users (read: me) can introspect it.
- There is a new builds.sr.ht config to enable akarle.srht.site to
be a "deploy preview" of sorts (really nice to link to friends for
feedback). I don't plan on using it for alexkarle.com any time
soon due to (1) needing gopher support and (2) wanting to keep the
redirects live.
- I'm slowly moving towards recommending/linking sourcehut over
linking to git.alexkarle.com -- I'm not deprecating the latter, but
I have a feeling the former will outlive it (and I want to point
it as a viable option for readers!)
[1]: https://git.sr.ht/~akarle/nihdoc
Diffstat:
73 files changed, 1928 insertions(+), 1993 deletions(-)
diff --git a/.build.yml b/.build.yml
@@ -0,0 +1,19 @@
+# srht.site build
+image: openbsd/latest
+oauth: pages.sr.ht/PAGES:RW
+sources:
+ - https://git.sr.ht/~akarle/alexkarle.com
+ - https://git.sr.ht/~akarle/nihdoc
+environment:
+ site: akarle.srht.site
+tasks:
+- package: |
+ make -C nihdoc
+ env PATH="$PWD/nihdoc:$PATH" make -C alexkarle.com
+ cd alexkarle.com/www && tar -cvhzf ../../site.tar.gz .
+- upload: |
+ acurl -f https://pages.sr.ht/publish/$site -Fcontent=@site.tar.gz
+triggers:
+- action: email
+ condition: always
+ to: ci@alexkarle.com
diff --git a/.gitignore b/.gitignore
@@ -1,13 +1,9 @@
-# generated html from man pages
-/*.html
-/*.txt
+# generated html
+*.html
+!www/header.html
+!www/footer.html
+!www/jam-tuesday/index.html
+!www/blog/my-old-man-orig.html
-# atom feed is generated by ./bin/genatom.sh
+# atom feeds are generated
atom.xml
-gopher.atom
-
-# obj directory on OpenBSD for out-of-tree builds
-obj/
-
-# Generated sed command to touch up out-of-base Xr references
-bin/fixlinks
diff --git a/BLM.7 b/BLM.7
@@ -1,18 +0,0 @@
-.Dd July 13, 2020
-.Dt BLM 7
-.Os
-.Sh NAME
-.Nm BLM
-.Nd Black Lives Matter
-.Sh DESCRIPTION
-I meant to post about this earlier, but it's better late than never.
-.Pp
-It's become abundantly clear to me that we need serious structural changes in our country.
-I want to raise my voice in solidarity to say that Black Lives Matter.
-.Sh SEE ALSO
-.Bl -bullet -compact
-.It
-.Lk https://blacklivesmatter.com
-.It
-.Xr blog 7
-.El
diff --git a/LINKS b/LINKS
@@ -1,11 +0,0 @@
-vim.1 https://www.vim.org
-git.1 https://git-scm.com/
-mutt.1 http://mutt.org
-pass.1 https://www.passwordstore.org
-newsboat.1 https://newsboat.org
-stagit.1 https://git.codemadness.org/stagit/
-git-daemon.1 https://git-scm.com/docs/git-daemon
-gophernicus.8 https://gophernicus.org
-bombadillo.1 https://bombadillo.colorfield.space/
-lynx.1 https://lynx.invisible-island.net/
-sacc.1 https://git.fifth.space/sacc
diff --git a/Makefile b/Makefile
@@ -1,112 +1,67 @@
# alexkarle.com makefile
-#
-# a tale of two builds
-#
-# This Makefile builds both gopher://alexkarle.com (text-only) and
-# alexkarle.com (html) from the same mdoc(7) by leveraging inference
-# rules. Since this generates a LOT of derived files, it's recommended
-# to run BSD make and run `make obj` first to get an out-of-tree build.
-# GNU make should work in a pinch though!
-#
-# targets:
-# build [default] -- generates html and text in obj (OpenBSD) or $PWD
-# obj -- makes the obj/ directory for out-of-tree build on OpenBSD
-# clean -- deletes html and text artifacts
-# install -- install to $DESTDIR/{www,gopher} (default: /var/www/htdocs)
-# jams -- regenerate jam-tuesday index and stats files
-
-# gmake defines CURDIR, OpenBSD defines .CURDIR -- one should work
-DIR = $(.CURDIR)$(CURDIR)
DESTDIR = /var/www/htdocs
+CFLAGS = -g -O2 -Wall -Wpedantic -Wextra
# Variables used to determine what to build (and clean)
-HTML != echo $(DIR)/*.[1-9] | sed 's@$(DIR)/\([^\.]*\)\.[1-9]@\1.html@g'
-TEXT != echo $(DIR)/*.[1-9] | sed 's@$(DIR)/\([^\.]*\)\.[1-9]@\1.txt@g'
-SETS != find $(DIR)/jam-tuesday -name '[0-9][0-9][0-9][0-9]-*'
-NOTES != find $(DIR)/gopher/notes/all
-PHLOG != find $(DIR)/gopher/phlog
+HTML != echo www/*.txt www/blog/*.txt | sed 's@\([^\.]*\)\.txt@\1.html@g'
+SETS != find www/jam-tuesday -name '[0-9][0-9][0-9][0-9]-*'
+NOTES != find gopher/notes/all
+PHLOG != find gopher/phlog
BUILT = $(HTML) \
- $(TEXT) \
- atom.xml \
- index.html \
gopher/notes/index.gph \
- gopher.atom
-
+ gopher/phlog/atom.xml \
+ www/atom.xml
# Top level targets
.PHONY: build
build: $(BUILT)
.PHONY: jams
-jams: jam-tuesday/stats jam-tuesday/index.html
-
-obj:
- mkdir -p obj/jam-tuesday obj/bin obj/gopher/notes
+jams: gopher/jam-tuesday/stats www/jam-tuesday/index.html
.PHONY: install
install: build
- # HTML to DESTDIR/www
- install -m 755 -Dd $(DESTDIR)/www/jam-tuesday
- install -m 444 $(SETS) $(DIR)/jam-tuesday/index.html $(DESTDIR)/www/jam-tuesday
- install -m 444 *.html atom.xml $(DIR)/LICENSE $(DIR)/style.css $(DESTDIR)/www
- # Text + gopher exclusives to DESTDIR/gopher
- cd $(DIR) && pax -rw gopher $(DESTDIR)
- pax -rw gopher $(DESTDIR) # for out-of-tree builds
+ pax -rw www $(DESTDIR)
+ pax -rw gopher $(DESTDIR)
install -m 444 $(SETS) $(DESTDIR)/gopher/jam-tuesday
- install -m 444 $(DIR)/LICENSE $(DESTDIR)/gopher
- for f in *.txt; do \
- install -m 444 $$f $(DESTDIR)/gopher/blog/$$(grep $$f $(DIR)/ORDER); \
- done
- install -m 444 atom.xml $(DESTDIR)/gopher/blog
- cp $(DIR)/gopher/bin/* $(DESTDIR)/gopher/code
- for d in jam-tuesday blog code; do \
- (cat $(DIR)/gopher/$$d/index.gph; \
- $(DIR)/gopher/bin/dirlist $(DESTDIR)/gopher/$$d)\
+ install -m 444 LICENSE $(DESTDIR)/gopher
+ install -m 444 www/blog/*.txt www/atom.xml $(DESTDIR)/gopher/blog
+ install -m 444 gopher/bin/* $(DESTDIR)/gopher/code
+ for d in jam-tuesday code; do \
+ (cat gopher/$$d/index.gph; \
+ gopher/bin/dirlist $(DESTDIR)/gopher/$$d)\
> $(DESTDIR)/gopher/$$d/index.gph; \
done
- install -m 444 gopher.atom $(DESTDIR)/gopher/phlog/atom.xml
+ (cat gopher/blog/index.gph; gopher/bin/blogidx.sh) > $(DESTDIR)/gopher/blog/index.gph
.PHONY: clean
clean:
- rm -f $(BUILT) bin/fixlinks
-
+ rm -f $(BUILT)
# Individual files to build
-jam-tuesday/stats: $(SETS) bin/jam-stats.sh
- (date; echo; $(DIR)/bin/jam-stats.sh -f) > $@
-
-jam-tuesday/index.html: $(SETS) bin/jam-index.sh bin/jam-stats.sh
- $(DIR)/bin/jam-index.sh > $@
+gopher/jam-tuesday/stats: $(SETS) bin/jam-stats.sh
+ (date; echo; ./bin/jam-stats.sh -f) > $@
-index.html:
- ln -sf intro.html index.html
+www/jam-tuesday/index.html: $(SETS) bin/jam-index.sh bin/jam-stats.sh
+ ./bin/jam-index.sh > $@
-atom.xml: blog.7 bin/genatom.sh
- $(DIR)/bin/genatom.sh > $@
-
-bin/fixlinks: LINKS
- mkdir -p bin
- printf "#!/bin/sh\n# GENERATED DO NOT EDIT\nsed" > $@
- awk '{ printf " \\\n -e s#https://man.openbsd.org/%s#%s#g", $$1, $$2 } END { printf "\n" }' $(DIR)/LINKS >> $@
- chmod +x $@
+www/atom.xml: $(HTML) bin/genatom.sh
+ ./bin/genatom.sh > $@
gopher/notes/index.gph: $(NOTES)
- (cd $(DIR)/gopher/notes && $(DIR)/gopher/bin/notetag) > $@
-
-gopher.atom: $(PHLOG) gopher/bin/gophatom.sh
- $(DIR)/gopher/bin/gophatom.sh > $@
+ (cd gopher/notes && ../bin/notetag) > $@
-# Inference rules (*.txt and *.html)
-$(HTML): bin/genpost.sh bin/fixlinks
+gopher/phlog/atom.xml: $(PHLOG) gopher/bin/gophatom.sh
+ ./gopher/bin/gophatom.sh > $@
-.SUFFIXES: .7 .txt .html
-.7.html:
- @echo "mandoc -Thtml $<"
- @mandoc -Tlint -Werror $<
- @$(DIR)/bin/genpost.sh < $< > $@
+# Inference rules (*.txt -> *.html)
+$(HTML): Makefile www/header.html www/footer.html bin/gencrumbs
-.7.txt:
- @echo "mandoc -Tascii $<"
- @mandoc -Tlint -Werror $<
- @mandoc -Tascii -Owidth=72 < $< | col -b > $@
+.SUFFIXES: .txt .html
+.txt.html:
+ @echo "building $@"
+ @(cat www/header.html; \
+ ./bin/gencrumbs $@; \
+ nihdoc < $< ; \
+ cat www/footer.html) > $@
diff --git a/ORDER b/ORDER
@@ -1,18 +0,0 @@
-# file order for the text.alexkarle.com site
-001-intro.txt
-002-license.txt
-003-uses.txt
-004-jam-tuesday.txt
-101-blog.txt
-102-a-new-hope.txt
-103-domain-names.txt
-104-BLM.txt
-105-self-hosted.txt
-106-on-writing.txt
-107-my-old-man.txt
-108-use-feeds.txt
-109-creative-coding.txt
-110-text-only.txt
-111-make-obj.txt
-112-use-git.txt
-113-burrowing.txt
diff --git a/README.md b/README.md
@@ -4,32 +4,25 @@ My small corner of the internet.
www.
----
-A static site comprised of [mdoc(7)][mdoc] flavored man pages, built to
-HTML via [mandoc(1)][mandoc] (managed by [make(1)][make]).
+A small static blog powered by my own personal markup parser, [nihdoc].
-Currently hosted with OpenBSD's [httpd(8)][httpd], but any web server
-should be able to serve it up.
-
-The Makefile to build the HTML is portable between gmake and BSD make.
-On OpenBSD, running `make obj` is recommended before running `make` to
-leverage the out-of-tree build extension (see the bit about `.OBJDIR` in
-the man page!).
+Currently hosted with OpenBSD's [httpd(8)], but any web server should be
+able to serve it up.
gopher://
---------
-A pure ascii dump of the [mdoc(7)][mdoc] content of the www site, served
-over Gopher by [geomyidae(1)][geomyidae] respectively!
+A pure ascii dump of the content of the www site, served over Gopher by
+[geomyidae(1)] respectively!
-Builds via [make(1)][make] at the same time as the HTML. See above for
-instructions.
+Builds via [make(1)] at the same time as the HTML.
Also has gopher-exclusive content!
git.
----
-I use a simple setup of git-daemon for anonymous (read-only) downloads,
-ssh+git for read+write access (limited to myself) and
-[stagit(1)][stagit] to host static views into the diffs and files of
+I use a simple setup of [git-daemon(8)] for anonymous (read-only) downloads,
+ssh+git for read+write access (limited to myself) and [stagit(1)] to
+host static views into the diffs and files of
each repo.
I like the stagit approach in that it is simple, modular, and emphasizes
@@ -38,19 +31,13 @@ etc).
I use the default post-receive and create scripts that ship with the
tool (with small modifications for the installation). The logo is in
-this repo as logo.png.
-
-The content, being static, is served up with [httpd(8)][httpd] as well.
-
-I also discuss the setup in my blog posts [self-hosted(7)][self-hosted]
-and [my-old-man(7)][my-old-man].
-
-[mdoc]: https://man.openbsd.org/mdoc.7
-[mandoc]: https://man.openbsd.org/mandoc.1
-[make]: https://man.openbsd.org/make.1
-[httpd]: https://man.openbsd.org/httpd.8
-[stagit]: https://git.codemadness.org/stagit
-[git-daemon]: https://git-scm.com/docs/git-daemon
-[self-hosted]: https://alexkarle.com/self-hosted.html
-[my-old-man]: https://alexkarle.com/my-old-man.html
-[geomyidae]: http://r-36.net/scm/geomyidae
+this repo as git/logo.png.
+
+The content, being static, is served up with [httpd(8)] as well.
+
+[make(1)]: https://man.openbsd.org/make.1
+[httpd(8)]: https://man.openbsd.org/httpd.8
+[stagit(1)]: https://git.codemadness.org/stagit
+[git-daemon(8)]: https://git-scm.com/docs/git-daemon
+[geomyidae(1)]: http://r-36.net/scm/geomyidae
+[nihdoc]: https://git.sr.ht/~akarle/nihdoc
diff --git a/a-new-hope.7 b/a-new-hope.7
@@ -1,22 +0,0 @@
-.Dd December 19, 2019
-.Dt A-NEW-HOPE 7
-.Os
-.Sh NAME
-.Nm a-new-hope
-.Nd cliche first blog post?
-.Sh DESCRIPTION
-Toying with the thought of starting a website/blog.
-.Pp
-Exploring my hosting options and pleasantly surprised that
-.Lk https://fastmail.com FastMail
-has free static site hosting!
-.Pp
-Inspired by Jeff Huang's article on websites Designed to Last
-and a general desire for a simpler web.
-.Sh SEE ALSO
-.Bl -bullet -compact
-.It
-.Lk https://jeffhuang.com/designed_to_last
-.It
-.Xr blog 7
-.El
diff --git a/bin/genatom.sh b/bin/genatom.sh
@@ -4,17 +4,13 @@ set -e
REPO=$(dirname "$(dirname "$0")")
-# Find fixlinks in either bin or the out-of-tree obj build
-PATH="$REPO/bin:$REPO/obj/bin:$PATH"
-
-# All posts are a item (.It) in the list, and linked via .Xr
-POSTS=$(sed '/SEE ALSO/q' "$REPO/blog.7" | grep -A1 '\.It' | grep '\.Xr' | sed 's/^\.Xr \([^ ]*\) 7/\1/')
+POSTS=$(grep '^- ../..' "$REPO/www/blog/index.txt" | sed 's#.*/blog/\([^)]*\).*#\1#')
cat <<HEADER
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
- <title>Alex Karle's blog(7)</title>
- <link rel="alternate" type="text/html" href="https://alexkarle.com/blog.html"/>
+ <title>Alex Karle's blog</title>
+ <link rel="alternate" type="text/html" href="https://alexkarle.com/blog/index.html"/>
<id>https://alexkarle.com/atom.xml</id>
<link rel="self" type="application/atom+xml" href="https://alexkarle.com/atom.xml"/>
<author>
@@ -22,26 +18,30 @@ cat <<HEADER
</author>
HEADER
-for p in $POSTS; do
- d=$(date -juf"%b %d, %Y" +%F "$(grep '^\.Dd' "$REPO/$p.7" | cut -d' ' -f2-)")
+for post in $POSTS; do
+ p=$(basename $post .html)
+ src="$REPO/www/blog/$p.txt"
+ [ "$p" = "index" ] && continue
+
+ d=$(date -juf"%b %d, %Y" +%F \
+ "$(grep '^_Published' "$src" | sed 's/_Published: \([^_]*\)_/\1/')")
if [ -z "$printed_update" ]; then
printed_update=1
printf " %s\n" "<updated>${d}T00:00:00Z</updated>"
fi
+
+ title=$(sed -e 's/^# //' -e '1q' "$src")
cat <<ENTRY
<entry>
- <title>$p</title>
- <link rel="alternate" type="text/html" href="https://alexkarle.com/$p.html"/>
- <id>https://alexkarle.com/$p.html</id>
+ <title>$title</title>
+ <link rel="alternate" type="text/html" href="https://alexkarle.com/blog/$p.html"/>
+ <id>https://alexkarle.com/blog/$p.html</id>
<updated>${d}T00:00:00Z</updated>
<published>${d}T00:00:00Z</published>
<content type="html">
<![CDATA[
ENTRY
- # Print fragment (no need for escapes -- in CDATA
- mandoc -Thtml -O'fragment,man=%N.html;https://man.openbsd.org/%N.%S' "$REPO/$p.7" \
- | sed '/<td class="head-vol">Miscellaneous Information Manual<\/td>/d' \
- | fixlinks
+ nihdoc < "$src"
cat <<EOENTRY
]]>
</content>
diff --git a/bin/gencrumbs b/bin/gencrumbs
@@ -0,0 +1,26 @@
+#!/bin/sh
+# generate breadcrumbs
+set -e
+die() {
+ echo "$*" 1>&2
+ exit 1
+}
+
+[ -z "$1" ] && die "usage: gencrumbs FILE"
+
+REPO=$(dirname "$(dirname "$(readlink -f "$0")")")
+FILE=$(readlink -f "$1")
+
+rel=${FILE##$REPO/www}
+parts=$(echo "$rel" | sed 's#/# #g')
+
+printf "<small><code><a href=\"/\">/home/alex</a>"
+curr=""
+for p in $parts; do
+ if [ "$p" = "index.html" ]; then
+ continue
+ fi
+ curr="$curr/$p"
+ printf " / <a href=\"$curr\">$p</a>"
+done
+echo "</code></small>"
diff --git a/bin/genpost.sh b/bin/genpost.sh
@@ -1,28 +0,0 @@
-#!/bin/sh
-# genpost.sh -- reads mdoc(7) from stdin, generates HTML to stdout
-REPO=$(dirname "$(dirname "$0")")
-
-# cd into $REPO so that the includes work!
-cd $REPO
-
-# Find fixlinks in either bin or the out-of-tree obj build
-PATH="$REPO/bin:$REPO/obj/bin:$PATH"
-
-# Command Explained
-# -----------------
-# man=%N.html;man.openbsd.org -- look for files in CWD for .Xr, then link to openbsd.org
-# sed:
-# 1. Add a viewport tag for mobile
-# 2. Add lang="en" to head for accessibility
-# 3. Remove Misc Info column in header (too large on mobile)
-# 4. Add a footer with license info
-# 5. Correct various off-site links (i.e. .Xr st -> st.suckless.org instead of openbsd.org)
-mandoc -Thtml -O 'man=%N.html;https://man.openbsd.org/%N.%S,style=style.css' \
- | sed \
- -e 's#</head>#<meta name="viewport" content="width=device-width,initial-scale=1">&# ' \
- -e 's#^<html#& lang="en"#' \
- -e '/<td class="head-vol">Miscellaneous Information Manual<\/td>/d' \
- -e 's#</body>#<p class="foot-license">\
- © 2019-2021 Alex Karle | <a href="/">Home</a> | <a href="/license.html">License</a>\
-</p>\
-&#' | fixlinks
diff --git a/bin/jam-index.sh b/bin/jam-index.sh
@@ -1,7 +1,7 @@
#!/bin/sh
set -e
REPO=$(dirname "$(dirname "$0")")
-DIR="$REPO/jam-tuesday"
+DIR="$REPO/www/jam-tuesday"
# Prep for the by artist listing
ALL=$(mktemp)
@@ -10,33 +10,73 @@ for f in "$DIR"/[0-9][0-9][0-9][0-9]-*; do
done | sort -f > "$ALL"
cat <<EOM
+<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
-<link rel="stylesheet" href="/style.css" type="text/css" media="all"/>
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<!-- Inspired by https://www.swyx.io/css-100-bytes/ -->
<style>
-h1 {
- font-size: 1.6em;
- margin-top: 40px;
+html {
+ max-width: 70ch;
+ padding: 3em 1em;
+ margin: auto;
+ font-size: 1em;
+ font-family: sans-serif;
}
-h2 {
- font-size: 1.3em;
- margin-top: 32px;
- margin-bottom: 0;
+footer {
+ margin-top: 50px;
+ font-size: .8em;
}
-h3 {
- font-size: 1em;
+code { font-family: consolas, courier, monospace; }
+h1 { font-size: 1.5em; }
+h2 { font-size: 1.2em; }
+h3 { font-size: 1.1em; }
+blockquote, code pre {
+ background: #f2f2f2;
+ overflow: auto;
+ padding: 10px;
+ border: 2px solid black;
+}
+.jam-artists tr:nth-child(even) {
+ background-color: #e3e3e3;
+}
+td.jam-artists, th.jam-artists, table.jam-artists {
+ border: 1px solid black;
}
</style>
<title>Jam Tuesday Archive</title>
-<meta name="viewport" content="width=device-width,initial-scale=1">
</head>
<body>
+<small><code><a href="/">/home/alex</a> / <a href="/jam-tuesday">jam-tuesday</a></code></small>
<h1>Jam Tuesday Archive</h1>
-<p>Welcome to the archive! For more information on the project,
-refer to <a href="/jam-tuesday.html">jam-tuesday(7)</a>.</p>
+<h2>About</h2>
+<p>
+From about October 2020 up until August 2021, my brother Matt and I
+got together every Tuesday evening to play music. It started as a
+way to stay sane during the COVID quarantine, but it quickly became
+a tradition and a highlight of the week. No matter how stressful
+work was, or what was going on in the outside world, we could leave
+it all behind as we played some of our favorite tunes.
+</p>
+<p>
+At some point (woefully late), I realized it would be fun to start
+cataloging what we played.
+</p>
+<p>
+This archive includes the setlists and some play stats.
+</p>
+<p>
+There are no audio recordings (at least publicly), but there's a
+stray note here and there to "set the scene".
+</p>
+<p>
+The setlist notation is hopefully pretty straightforward. Unless
+otherwise noted, I'm on guitar and Matt's on keys (and if only one
+instrument is specified, it's me switching to it). We both
+(attempt to) sing. Sometimes we even harmonize :)
+</p>
<h2>Stats</h2>
-<hr>
EOM
"$REPO"/bin/jam-stats.sh | sed \
@@ -48,20 +88,18 @@ EOM
cat <<EOM
</ul>
<h2>Setlists</h2>
-<hr>
Updated weekly:
<ul>
EOM
for f in "$DIR"/[0-9][0-9][0-9][0-9]-*; do
name=$(basename "$f")
- echo "<li><a href=\"$name\">$name</a></li>"
+ echo "<li><a href=\"/jam-tuesday/$name\">$name</a></li>"
done
cat <<EOM
</ul>
<h2>All Songs, by Artist</h2>
-<hr>
<table class="jam-artists">
<tr><th>Artist</th><th>Song</th><th>Plays</th></tr>
EOM
diff --git a/bin/jam-stats.sh b/bin/jam-stats.sh
@@ -5,7 +5,7 @@ set -e
N=10
REPO=$(dirname "$(dirname "$0")")
-DIR="$REPO/jam-tuesday"
+DIR="$REPO/www/jam-tuesday"
TMP=$(mktemp)
num_sessions=0
for set in "$DIR"/[0-9][0-9][0-9][0-9]-*; do
diff --git a/bin/newpost b/bin/newpost
@@ -1,27 +0,0 @@
-#!/bin/sh
-set -e
-die() {
- echo "$1" 1>&2
- exit 1
-}
-
-[ -z "$1" ] && die "usage: $(basename "$0") NAME"
-
-name="$1"
-TITLE=$(printf "$name" | tr [a-z] [A-Z])
-
-cat <<EOM > "$name".7
-.Dd $(date +"%B %d, %Y")
-.Dt $TITLE 7
-.Os
-.Sh NAME
-.Nm $name
-.Nd <desc>
-.Sh DESCRIPTION
-entry
-.Sh SEE ALSO
-.Bl -bullet -compact
-.It
-.Xr blog 7
-.El
-EOM
diff --git a/blog.7 b/blog.7
@@ -1,67 +0,0 @@
-.Dd $Mdocdate$
-.Dt BLOG 7
-.Os
-.Sh NAME
-.Nm blog
-.Nd yet another weblog
-.Sh DESCRIPTION
-I don't write frequently, but when I do, it's usually about tech.
-.Pp
-If you'd like to get notifications on new articles, I publish an
-.Lk atom.xml Atom
-feed (for use with your favorite RSS/Atom client).
-.Pp
-For an up to date list of software/hardware I use, see
-.Xr uses 7 .
-.Sh POSTS
-.Bl -tag -width "XX/XX"
-.It 11/21
-.Xr burrowing 7
-- from
-.Xr text-only 7
-to gopher-only
-.It 11/21
-.Xr use-git 7
-- non-standard uses of
-.Xr git 1
-.It 09/21
-.Xr make-obj 7
-- out-of-tree builds with BSD
-.Xr make 1
-.It 09/21
-.Xr text-only 7
-- announcing text.alexkarle.com
-.It 07/21
-.Xr creative-coding 7
-- learning through creative limitation
-.It 02/21
-.Xr use-feeds 7
-- RSS/Atom feeds; what, why, and how
-.It 12/20
-.Xr my-old-man 7
-- Adventures in using
-.Xr mdoc 7
-for this site
-.It 10/20
-.Xr on-writing 7
-- On Writing Without an Audience
-.It 07/20
-.Xr self-hosted 7
-- Migrating to a Self-Hosted Site
-.It 07/20
-.Xr BLM 7
-- Black Lives Matter
-.It 03/20
-.Xr domain-names 7
-- What's in a (domain) name?
-.It 12/19
-.Xr a-new-hope 7
-- A New Hope
-.El
-.Sh SEE ALSO
-.Bl -bullet -compact
-.It
-.Xr intro 7
-.It
-.Xr jam-tuesday 7
-.El
diff --git a/burrowing.7 b/burrowing.7
@@ -1,113 +0,0 @@
-.Dd November 15, 2021
-.Dt BURROWING 7
-.Os
-.Sh NAME
-.Nm burrowing
-.Nd from
-.Xr text-only 7
-to gopher-only
-.Sh DESCRIPTION
-This past month,
-I've spent a lot of time learning about gopher.
-It's truly a fascinating alternative to the world wide web,
-not just in the content found there
-but also in terms of the protocol itself.
-.Pp
-As of this writing, I've decided to deprecate
-.Lk https://text.alexkarle.com
-in favor of serving that content (and more!) over gopher
-instead, exclusively.
-.Sh IMPLICATIONS
-This shouldn't have much impact on this
-.Xr blog 7 .
-After all,
-.Xr text-only 7
-was an experiment to begin with!
-I'll still keep publishing semi-regularly here,
-I just don't plan on maintaining a text dump via HTTP.
-.Pp
-I will, however, start publishing gopher-only content.
-There's two main reasons for this:
-.Pp
-.Bl -enum -compact
-.It
-I want to see more activity on gopher
-.It
-Gopher is easier to publish on
-.El
-.Pp
-Admittedly, number 2 is my own doing.
-I moved this blog to
-.Xr mdoc 7
-willingly
-.Xr ( my-old-man 7 )
-to learn the language.
-I've found that it slows my raw output,
-which,
-while fine for longer form pieces,
-is a pain for shorter-form thoughts.
-No regrets (I learned a ton!),
-but shorter-form thoughts do much better in plaintext!
-.Pp
-The first reason is a theme for this blog:
-be the change you want to see.
-I would love to see more content on gopher,
-so I'm taking the plunge.
-.Sh THE PITCH
-So, why gopher?
-Probably the biggest reason to explore gopher is
-the content.
-It's a parallel network totally untouched by
-commercial interests.
-You won't see a single ad.
-.Pp
-The second reason to try gopher lies in the
-protocol itself--gopher has a standardized menu
-interface, and individual gopherholes cannot
-change the way you interact with them beyond
-the standard.
-In a world where it seems every bit of the
-web's UI has been rewritten in JavaScript (looking
-at you, <div>'s that should be <button>'s),
-it's wildly refreshing
-to just have a predictable menu.
-.Pp
-So, gopher separates the interaction (menus)
-from the content (can be anything, but is usually
-plaintext).
-I think this is a cool design choice
-because it emphasizes what the gopher protocol
-is really about: fetching documents.
-.Pp
-Ultimately,
-it's hard to describe and much better experienced.
-For a quick dip,
-try out a proxy like
-.Lk https://gopherproxy.net .
-For client recommendations,
-I'd check out
-.Xr lynx 1 ,
-.Xr sacc 1 ,
-or
-.Xr bombadillo 1 .
-Bombadillo has gemini support too,
-gemini being another alternative internet protocol
-worth checking out.
-I'll likely put my stuff up there too,
-if time allows.
-.Pp
-Not sure where to start in your client?
-Go to
-.Lk gopher://alexkarle.com
-of course! :)
-.Sh SEE ALSO
-.Bl -bullet -compact
-.It
-.Xr blog 7
-.It
-.Lk https://datatracker.ietf.org/doc/html/rfc1436 RFC 1436 (Gopher)
-.It
-.Lk http://gopherproject.org
-.It
-.Lk http://gemini.circumlunar.space Gemini official site
-.El
diff --git a/creative-coding.7 b/creative-coding.7
@@ -1,71 +0,0 @@
-.Dd July 18, 2021
-.Dt CREATIVE-CODING 7
-.Os
-.Sh NAME
-.Nm creative-coding
-.Nd learning through creative limitation
-.Sh DESCRIPTION
-I was talking to a friend recently about hobby coding
-and ways to code creatively.
-In the course of that conversation,
-I was able to put a name to one of my favorite tactics:
-creative limitation.
-.Pp
-A quick internet search seems to associate the term with Phil Hansen
-and more traditional art,
-but I think it applies nicely to coding too.
-For example,
-with this site,
-I've chosen to restrict the tech stack to the OpenBSD base system.
-It wasn't the initial goal (which was to learn
-.Xr mdoc 7 ) ,
-but I quickly realized that restricting to base would give me
-a better chance to learn base.
-.Pp
-Overall, I'd call it a success.
-.Xr jam-tuesday 7
-gave me a chance to learn some
-.Xr sh 1
-and
-.Xr sed 1 ,
-.Xr blog 7
-was a chance to learn
-.Xr mdoc 7 ,
-and the site's build system helped me brush up on BSD
-.Xr make 1 .
-.Pp
-I'd encourage you to try it \(em
-set an arbitrary restriction and see where it takes you!
-Here's a few ideas to get you started:
-.Pp
-.Bl -bullet -compact
-.It
-Write your own X window manager in as few lines of code as you can
-.It
-Write a version control system with
-.Xr sh 1 ,
-.Xr diff 1 ,
-and
-.Xr patch 1
-.It
-Write a blogging engine updated via email
-.It
-Write your own templating language (and parser)
-.El
-.Pp
-The goal, for me, is to choose a challenging project that helps
-me understand a technology I use daily but may take for granted
-(windowing systems, VCS, email, parsers, etc).
-.Pp
-Restricting size helps understand what the core definition of
-a technology is.
-Building clones can help teach edge cases and design decisions one
-might otherwise overlook.
-And in all cases, it's a good chance to learn a new language!
-.Sh SEE ALSO
-.Bl -bullet -compact
-.It
-.Xr blog 7
-.It
-.Xr my-old-man 7
-.El
diff --git a/domain-names.7 b/domain-names.7
@@ -1,41 +0,0 @@
-.Dd March 24, 2020
-.Dt DOMAIN-NAMES 7
-.Os
-.Sh NAME
-.Nm domain-names
-.Nd what's in a (domain) name?
-.Sh DESCRIPTION
-I went through a phase this week of really wanting `karle.[original-tld]`.
-Not for a business.
-Not for boosting my own webpage (it doesn't really have much traffic).
-Just for me.
-.Pp
-The results were... disheartening.
-.Ss karle.org
-Registered since 2004, no website, just an email DNS record.
-WHOIS guard ensures I can't even reach out to who owns it.
-.Ss karle.com
-For sale by owner on Uniregistry.
-Ok.
-Inquired.
-Owner wants a "serious 5 figure offer".
-Next!
-.Ss karle.net
-Owned by
-.Lk https://realnames.com RealNames ,
-a business seemingly centered around buying lastname.net domains and
-charging people like me to set up an email.
-Almost brilliant enough of a business to make me forgive their scumminess.
-.Em Almost .
-Nary an option to buy it.
-.Ss Conclusion
-So here we are.
-Looks like `karle.co` for at least a little longer.
-.Pp
-.Sy Update:
-I've settled on alexkarle.com and plan to use it for the foreseeable future.
-.Sh SEE ALSO
-.Bl -bullet -compact
-.It
-.Xr blog 7
-.El
diff --git a/logo.png b/git/logo.png
Binary files differ.
diff --git a/intro.7 b/intro.7
@@ -1,38 +0,0 @@
-.Dd $Mdocdate$
-.Dt INTRO 7
-.Os
-.Sh NAME
-.Nm intro
-.Nd welcome to my personal website
-.Sh ABOUT ME
-Hi!
-I'm Alex.
-I'm a software engineer living in the Boston area.
-My current technical interests include operating systems,
-version control,
-and developer tooling,
-but I'm constantly learning new tech that I get excited about.
-Occasionally, I might write about it here on my
-.Xr blog 7 .
-.Pp
-Outside of tech, I enjoy playing music, hiking, and a good board game
-shared among friends.
-.Pp
-If you can't tell from the layout of this site, I'm a
-.Xr man 1
-page enthusiast.
-.Sh SEE ALSO
-.Bl -bullet -compact
-.It
-.Lk https://euchre.live euchre(6)
-.It
-.Xr blog 7
-.It
-.Xr jam-tuesday 7
-.It
-.Xr uses 7
-.It
-.Lk https://git.alexkarle.com projects(7)
-.El
-.Sh CONTACT
-Email: contact AT this-domain
diff --git a/jam-tuesday.7 b/jam-tuesday.7
@@ -1,37 +0,0 @@
-.Dd $Mdocdate$
-.Dt JAM-TUESDAY 7
-.Os
-.Sh NAME
-.Nm jam-tuesday
-.Nd setlists and notes from weekly jams
-.Sh DESCRIPTION
-From about October 2020 up until August 2021,
-my brother Matt and I got together every Tuesday evening to play music.
-It started as a way to stay sane during the COVID quarantine,
-but it quickly became a tradition and a highlight of the week.
-No matter how stressful work was,
-or what was going on in the outside world,
-we could leave it all behind as we played some of our favorite tunes.
-.Pp
-At some point (woefully late),
-I realized it would be fun to start cataloging what we played.
-.Pp
-The setlists and some play stats are all available in the
-.Lk /jam-tuesday/ Jam Tuesday Archive .
-.Pp
-There are no audio recordings (at least publicly),
-but there's a stray note here and there to "set the scene".
-.Pp
-The setlist notation is hopefully pretty straightforward.
-Unless otherwise noted,
-I'm on guitar and Matt's on keys
-(and if only one instrument is specified, it's me switching to it).
-We both (attempt to) sing.
-Sometimes we even harmonize :)
-.Sh SEE ALSO
-.Bl -bullet -compact
-.It
-.Xr intro 7
-.It
-.Xr blog 7
-.El
diff --git a/jam-tuesday/index.html b/jam-tuesday/index.html
@@ -1,255 +0,0 @@
-<html lang="en">
-<head>
-<meta charset="utf-8"/>
-<link rel="stylesheet" href="/style.css" type="text/css" media="all"/>
-<style>
-h1 {
- font-size: 1.6em;
- margin-top: 40px;
-}
-h2 {
- font-size: 1.3em;
- margin-top: 32px;
- margin-bottom: 0;
-}
-h3 {
- font-size: 1em;
-}
-</style>
-<title>Jam Tuesday Archive</title>
-<meta name="viewport" content="width=device-width,initial-scale=1">
-</head>
-<body>
-<h1>Jam Tuesday Archive</h1>
-<p>Welcome to the archive! For more information on the project,
-refer to <a href="/jam-tuesday.html">jam-tuesday(7)</a>.</p>
-<h2>Stats</h2>
-<hr>
-<h3>Play Stats:</h3>
-<ul>
-<li> 19 Jam Sessions</li>
-<li> 330 Songs Total</li>
-<li> 159 Unique Songs</li>
-<li> 87 Unique Artists</li>
-</ul>
-<h3>Top 10 Artists (Frequency, Name):</h3>
-<ul>
-<li> 40 The Front Bottoms</li>
-<li> 37 Peach Pit</li>
-<li> 29 Manchester Orchestra</li>
-<li> 16 Vulfpeck</li>
-<li> 16 Dr. Dog</li>
-<li> 15 The Dear Hunter</li>
-<li> 10 Atta Boy</li>
-<li> 9 Cage The Elephant</li>
-<li> 7 Lake Street Dive</li>
-<li> 7 Her's</li>
-</ul>
-<h3>Top 10 Songs (Frequency, Name):</h3>
-<ul>
-<li> 12 Twin Size Mattress, The Front Bottoms</li>
-<li> 11 Rhode Island, The Front Bottoms</li>
-<li> 11 Alrighty Aphrodite, Peach Pit</li>
-<li> 10 Shadow People, Dr. Dog</li>
-<li> 10 Brian's Movie, Peach Pit</li>
-<li> 8 The Beers, The Front Bottoms</li>
-<li> 8 Jack and Blow, Atta Boy</li>
-<li> 6 That I Miss You, Vansire</li>
-<li> 6 Lauren, Men I Trust</li>
-<li> 6 Drop the Guillotine, Peach Pit</li>
-</ul>
-<h2>Setlists</h2>
-<hr>
-Updated weekly:
-<ul>
-<li><a href="2021-03-09">2021-03-09</a></li>
-<li><a href="2021-03-16">2021-03-16</a></li>
-<li><a href="2021-03-23">2021-03-23</a></li>
-<li><a href="2021-03-30">2021-03-30</a></li>
-<li><a href="2021-04-06">2021-04-06</a></li>
-<li><a href="2021-04-13">2021-04-13</a></li>
-<li><a href="2021-04-20">2021-04-20</a></li>
-<li><a href="2021-04-27">2021-04-27</a></li>
-<li><a href="2021-05-04">2021-05-04</a></li>
-<li><a href="2021-05-18">2021-05-18</a></li>
-<li><a href="2021-05-25">2021-05-25</a></li>
-<li><a href="2021-06-01">2021-06-01</a></li>
-<li><a href="2021-06-08">2021-06-08</a></li>
-<li><a href="2021-06-15">2021-06-15</a></li>
-<li><a href="2021-06-22">2021-06-22</a></li>
-<li><a href="2021-07-06">2021-07-06</a></li>
-<li><a href="2021-07-13">2021-07-13</a></li>
-<li><a href="2021-07-20">2021-07-20</a></li>
-<li><a href="2021-07-27">2021-07-27</a></li>
-</ul>
-<h2>All Songs, by Artist</h2>
-<hr>
-<table class="jam-artists">
-<tr><th>Artist</th><th>Song</th><th>Plays</th></tr>
-<tr><td>311</td><td>Amber</td><td>1</td></tr>
-<tr><td>A Great Big Pile Of Leaves</td><td>Alligator Bop</td><td>1</td></tr>
-<tr><td>A Tribe Called Quest</td><td>Can I Kick It?</td><td>1</td></tr>
-<tr><td>Anderson .Paak</td><td>Make It Better</td><td>1</td></tr>
-<tr><td>Anderson .Paak & Bruno Mars</td><td>Leave the Door Open</td><td>1</td></tr>
-<tr><td>Atta Boy</td><td>Jack and Blow</td><td>8</td></tr>
-<tr><td></td><td>Walden Pond</td><td>2</td></tr>
-<tr><td>Bad Books</td><td>Baby Shoes</td><td>1</td></tr>
-<tr><td></td><td>Forest Whitaker</td><td>1</td></tr>
-<tr><td></td><td>It Never Stops</td><td>1</td></tr>
-<tr><td></td><td>The After Party</td><td>2</td></tr>
-<tr><td></td><td>You Wouldn't Have To Ask</td><td>1</td></tr>
-<tr><td>Beck</td><td>Loser</td><td>1</td></tr>
-<tr><td>Cage The Elephant</td><td>Cigarette Daydreams</td><td>6</td></tr>
-<tr><td></td><td>Shake Me Down</td><td>1</td></tr>
-<tr><td></td><td>Telescope</td><td>1</td></tr>
-<tr><td></td><td>Trouble</td><td>1</td></tr>
-<tr><td>Cake</td><td>Comfort Eagle</td><td>1</td></tr>
-<tr><td>Carpenters</td><td>Close To You</td><td>1</td></tr>
-<tr><td>Carrie Underwood</td><td>Before He Cheats</td><td>1</td></tr>
-<tr><td>Daniel Caesar</td><td>Japanese Denim</td><td>1</td></tr>
-<tr><td>Darwin Deez</td><td>Radar Detector</td><td>2</td></tr>
-<tr><td>Death Cab For Cutie</td><td>I Will Posess Your Heart</td><td>1</td></tr>
-<tr><td>Dojo Cat</td><td>Say So</td><td>1</td></tr>
-<tr><td>Dr. Dog</td><td>Nellie</td><td>1</td></tr>
-<tr><td></td><td>Shadow People</td><td>10</td></tr>
-<tr><td></td><td>Stranger</td><td>2</td></tr>
-<tr><td></td><td>The Beers/Shadow People</td><td>1</td></tr>
-<tr><td></td><td>The Breeze</td><td>1</td></tr>
-<tr><td></td><td>Twin Size/Shadow People/Beers</td><td>1</td></tr>
-<tr><td>Eurythmics</td><td>Sweet Dreams</td><td>1</td></tr>
-<tr><td>Eve 6</td><td>Inside Out</td><td>1</td></tr>
-<tr><td>Father John Misty</td><td>Real Love Baby</td><td>4</td></tr>
-<tr><td>Fleet Foxes</td><td>White Winter Hymnal</td><td>1</td></tr>
-<tr><td>Foo Fighters</td><td>Learn To Fly</td><td>1</td></tr>
-<tr><td></td><td>The Pretender</td><td>1</td></tr>
-<tr><td>Goo Goo Dolls</td><td>Iris</td><td>1</td></tr>
-<tr><td>Gorillaz</td><td>Feel Good Inc.</td><td>1</td></tr>
-<tr><td>Harvey Danger</td><td>Flagpole Sitta</td><td>1</td></tr>
-<tr><td>Her's</td><td>Blue Lips</td><td>6</td></tr>
-<tr><td></td><td>Cool With You</td><td>1</td></tr>
-<tr><td>Herbie Hancock</td><td>Chameleon</td><td>3</td></tr>
-<tr><td>Jay Som</td><td>Baybee</td><td>1</td></tr>
-<tr><td>Jimmy Eat World</td><td>The Middle</td><td>1</td></tr>
-<tr><td>John Mayer</td><td>Moving On and Getting Over</td><td>1</td></tr>
-<tr><td></td><td>No Such Thing</td><td>1</td></tr>
-<tr><td>Joyce Manor</td><td>Last You Heard of Me</td><td>1</td></tr>
-<tr><td>Kanye West</td><td>Golddigger</td><td>1</td></tr>
-<tr><td>Kate Bollinger</td><td>I Don't Wanna Lose</td><td>1</td></tr>
-<tr><td>Kevin Devine</td><td>Cotton Crush</td><td>1</td></tr>
-<tr><td></td><td>I Could Be With Anyone</td><td>1</td></tr>
-<tr><td>Khalid</td><td>Talk</td><td>1</td></tr>
-<tr><td>Lake Street Dive</td><td>Call Off Your Dogs</td><td>1</td></tr>
-<tr><td></td><td>Hello Goodbye</td><td>1</td></tr>
-<tr><td></td><td>Hypotheticals</td><td>5</td></tr>
-<tr><td>Lenny Kravitz</td><td>Fly Away</td><td>1</td></tr>
-<tr><td>Mac DeMarco</td><td>My Old Man</td><td>2</td></tr>
-<tr><td>Mac Miller</td><td>What's The Use</td><td>3</td></tr>
-<tr><td>Manchester Orchestra</td><td>Bed Head</td><td>3</td></tr>
-<tr><td></td><td>Everything To Nothing</td><td>1</td></tr>
-<tr><td></td><td>I Can Barely Breathe</td><td>1</td></tr>
-<tr><td></td><td>I Can Feel A Hot One</td><td>1</td></tr>
-<tr><td></td><td>I've Got Friends</td><td>4</td></tr>
-<tr><td></td><td>Keel Timing</td><td>3</td></tr>
-<tr><td></td><td>Pride</td><td>4</td></tr>
-<tr><td></td><td>Shake It Out</td><td>5</td></tr>
-<tr><td></td><td>Telepath</td><td>1</td></tr>
-<tr><td></td><td>The Only One</td><td>4</td></tr>
-<tr><td></td><td>Tony The Tiger</td><td>1</td></tr>
-<tr><td></td><td>Virgin</td><td>1</td></tr>
-<tr><td>Matt</td><td>Original</td><td>4</td></tr>
-<tr><td>Matt and Alex</td><td>Original</td><td>5</td></tr>
-<tr><td>Men I Trust</td><td>Lauren</td><td>6</td></tr>
-<tr><td>Michael Jackson</td><td>Beat It</td><td>1</td></tr>
-<tr><td></td><td>Billie Jean</td><td>1</td></tr>
-<tr><td>Modern Baseball</td><td>Tears Over Beers</td><td>2</td></tr>
-<tr><td>Modest Mouse</td><td>Float On</td><td>2</td></tr>
-<tr><td>Natalie Imbruglia</td><td>Torn</td><td>1</td></tr>
-<tr><td>No Doubt</td><td>Don't Speak</td><td>1</td></tr>
-<tr><td>Omar Apollo</td><td>The Two of Us</td><td>3</td></tr>
-<tr><td>OutKast</td><td>Ms Jackson</td><td>1</td></tr>
-<tr><td>Paper Kites</td><td>Bloom</td><td>1</td></tr>
-<tr><td>Parcels</td><td>Tieduprightnow</td><td>1</td></tr>
-<tr><td>Peach Pit</td><td>Alrighty Aphrodite</td><td>11</td></tr>
-<tr><td></td><td>Black Licorice</td><td>1</td></tr>
-<tr><td></td><td>Brian's Movie</td><td>10</td></tr>
-<tr><td></td><td>Chagu's Sideturn</td><td>2</td></tr>
-<tr><td></td><td>Drop the Guillotine</td><td>6</td></tr>
-<tr><td></td><td>Peach Pit</td><td>1</td></tr>
-<tr><td></td><td>Shampoo Bottles</td><td>2</td></tr>
-<tr><td></td><td>Techno Show</td><td>3</td></tr>
-<tr><td></td><td>Tommy's Party</td><td>1</td></tr>
-<tr><td>Phish</td><td>Character Zero</td><td>3</td></tr>
-<tr><td>Portugal. The Man</td><td>Feel It Still</td><td>1</td></tr>
-<tr><td>Prawn</td><td>Why You Always Leave A Note</td><td>1</td></tr>
-<tr><td>Radiohead</td><td>Creep</td><td>2</td></tr>
-<tr><td>Rage Against The Machine</td><td>Killing in the Name</td><td>1</td></tr>
-<tr><td>Red Hot Chili Peppers</td><td>Can't Stop</td><td>4</td></tr>
-<tr><td>Ripe</td><td>Caralee</td><td>1</td></tr>
-<tr><td></td><td>Goon Squad</td><td>1</td></tr>
-<tr><td></td><td>Pretty Dirty</td><td>1</td></tr>
-<tr><td></td><td>Talk to the Moon</td><td>1</td></tr>
-<tr><td>Robbie Hunter Band</td><td>Que Paso?</td><td>1</td></tr>
-<tr><td>Sammy Rae</td><td>Jackie Onassis</td><td>1</td></tr>
-<tr><td></td><td>Kick It To Me</td><td>2</td></tr>
-<tr><td>Santana</td><td>Smooth</td><td>1</td></tr>
-<tr><td>Stone Temple Pilots</td><td>Interstate Love Song</td><td>2</td></tr>
-<tr><td>Sublime</td><td>Doin Time</td><td>1</td></tr>
-<tr><td>Sugar Ray</td><td>Every Morning</td><td>2</td></tr>
-<tr><td>Sure Sure</td><td>Good Thing</td><td>1</td></tr>
-<tr><td>Tame Impala</td><td>The Less I Know The Better</td><td>2</td></tr>
-<tr><td>The Beatles</td><td>I've Just Seen A Face</td><td>1</td></tr>
-<tr><td></td><td>With a Little Help From My Friends</td><td>1</td></tr>
-<tr><td>The Black Keys</td><td>Tighten Up</td><td>1</td></tr>
-<tr><td>The Cars</td><td>Just What I Needed</td><td>1</td></tr>
-<tr><td>The Dear Hunter</td><td>A Sua Voz</td><td>3</td></tr>
-<tr><td></td><td>Black Sandy Beaches</td><td>1</td></tr>
-<tr><td></td><td>Deny It All</td><td>1</td></tr>
-<tr><td></td><td>Girl</td><td>1</td></tr>
-<tr><td></td><td>Misplaced Devotion</td><td>1</td></tr>
-<tr><td></td><td>Progress/Therma</td><td>2</td></tr>
-<tr><td></td><td>Red Hands</td><td>4</td></tr>
-<tr><td></td><td>The Moon/Awake</td><td>1</td></tr>
-<tr><td></td><td>What it Means to Be Alone</td><td>1</td></tr>
-<tr><td>The Eagles</td><td>Hotel California</td><td>1</td></tr>
-<tr><td>The Front Bottoms</td><td>Cough It Out</td><td>1</td></tr>
-<tr><td></td><td>Flashlight</td><td>4</td></tr>
-<tr><td></td><td>Jim Bogart</td><td>1</td></tr>
-<tr><td></td><td>Legit Tattoo Gun</td><td>2</td></tr>
-<tr><td></td><td>Rhode Island</td><td>11</td></tr>
-<tr><td></td><td>The Beers</td><td>8</td></tr>
-<tr><td></td><td>Twin Size Mattress</td><td>12</td></tr>
-<tr><td></td><td>West Virginia</td><td>1</td></tr>
-<tr><td>The Head and The Heart</td><td>Honeybee</td><td>1</td></tr>
-<tr><td></td><td>Lost In My Mind</td><td>2</td></tr>
-<tr><td></td><td>Rivers and Roads</td><td>2</td></tr>
-<tr><td>The Raconteurs</td><td>Steady As She Goes</td><td>1</td></tr>
-<tr><td>The White Stripes</td><td>We're Going To Be Friends</td><td>1</td></tr>
-<tr><td>Theo Katzman</td><td>You Could Be President</td><td>1</td></tr>
-<tr><td>Third Eye Blind</td><td>Semi Charmed Life</td><td>1</td></tr>
-<tr><td>Three Doors Down</td><td>Kryptonite</td><td>1</td></tr>
-<tr><td>Tonic</td><td>If You Could Only See</td><td>1</td></tr>
-<tr><td>Twiddle</td><td>When it Rains it Poors</td><td>1</td></tr>
-<tr><td>USERx</td><td>Headsick</td><td>1</td></tr>
-<tr><td>Vampire Weekend</td><td>Flower Moon</td><td>2</td></tr>
-<tr><td></td><td>Sunflower</td><td>4</td></tr>
-<tr><td>Vansire</td><td>That I Miss You</td><td>6</td></tr>
-<tr><td>Vulfpeck</td><td>1612</td><td>2</td></tr>
-<tr><td></td><td>Animal Spirits</td><td>1</td></tr>
-<tr><td></td><td>Aunt Leslie</td><td>3</td></tr>
-<tr><td></td><td>Baby I Don't Know Oh Oh</td><td>1</td></tr>
-<tr><td></td><td>Back Pocket</td><td>2</td></tr>
-<tr><td></td><td>LAX</td><td>1</td></tr>
-<tr><td></td><td>Love is a Beautiful Thing</td><td>1</td></tr>
-<tr><td></td><td>Outro</td><td>1</td></tr>
-<tr><td></td><td>Wait For The Moment</td><td>4</td></tr>
-<tr><td>Weezer</td><td>Buddy Holly</td><td>2</td></tr>
-<tr><td></td><td>If You're Wondering If I Want You To</td><td>1</td></tr>
-<tr><td></td><td>The World Has Turned and Left Me Here</td><td>1</td></tr>
-</table>
-<br><br>
-<p style="font-size: 0.7em">Last Updated: Thu Nov 11 21:15:31 EST 2021</p>
-<p class="foot-license">
-© 2019-2021 Alex Karle | <a href="/">Home</a> | <a href="/license.html">License</a>
-</p>
-</body>
-</html>
diff --git a/license.7 b/license.7
@@ -1,26 +0,0 @@
-.Dd $Mdocdate$
-.Dt LICENSE 7
-.Os
-.Sh NAME
-.Nm license
-.Nd copyright info for this site
-.Sh COPYRIGHT
-Except where otherwise noted,
-all content on this site is licensed under a
-Creative Commons Attribution 4.0 license (CC BY 4.0).
-.Pp
-Any code snippets, including the code used to build this site,
-are licensed under a MIT license.
-.Sh SEE ALSO
-.Bl -bullet -compact
-.It
-.Lk https://creativecommons.org/licenses/by/4.0/ CC BY 4.0
-.It
-.Lk /LICENSE MIT license
-.It
-.Lk https://git.alexkarle.com/alexkarle.com Source code for the site
-.It
-.Xr intro 7
-.It
-.Xr blog 7
-.El
diff --git a/make-obj.7 b/make-obj.7
@@ -1,156 +0,0 @@
-.Dd September 28, 2021
-.Dt MAKE-OBJ 7
-.Os
-.Sh NAME
-.Nm make-obj
-.Nd out-of-tree builds with BSD
-.Xr make 1
-.Sh DESCRIPTION
-If you've ever built parts of OpenBSD from source,
-you may know that the sequence of commands recommended by
-.Xr release 8
-is:
-.Pp
-.Bd -literal -offset indent
-$ make obj
-$ make
-# make install
-.Ed
-.Pp
-If, like me, you've forgotten the
-.Ql make obj
-step,
-you'll find yourself with many derived files in the
-current directory of whatever program you're building.
-By running
-.Ql make obj
-first,
-a directory called
-.Pa obj
-appears and the derived files
-(usually
-.Pa *.o
-files) are placed there instead.
-Cleverly, the
-.Pa obj
-directory is actually a symlink to
-another filesystem under
-.Pa /usr/obj ,
-making it truly an out-of-tree build.
-.Pp
-Up until recently,
-I understood what the
-.Ql obj
-target did and why it was useful.
-However, it wasn't until I tried to replicate it with the
-build for text.alexkarle.com
-that I discovered how it worked.
-I figured I'd document it here in case it helps anyone else.
-.Sh HOW IT WORKS
-My discovery of the inner workings of this target was a classic
-lesson in RTFM.
-After 10-15 minutes of trying to parse the makefiles in
-.Pa /usr/share/mk ,
-I finally searched for
-.Pa obj
-in the
-.Xr make 1
-man page,
-and sure enough the answer was the first hit!
-I've copied it for convenience below
-(licensed under the BSD-3 clause):
-.Pp
-.Bl -tag -offset indent
-.It Va .OBJDIR
-Path to the directory where targets are built.
-At startup,
-.Ic make
-searches for an alternate directory to place target files.
-.Ic make
-tries to
-.Xr chdir 2 into
-.Ev MAKEOBJDIR
-(or
-.Pa obj
-if
-.Ev MAKEOBJDIR
-is not defined),
-and sets
-.Va .OBJDIR
-accordingly.
-Should that fail,
-.Va .OBJDIR
-is set to
-.Va .CURDIR .
-.El
-.Pp
-With this new knowledge,
-getting an out-of-tree build was almost as simple as running
-.Ql mkdir obj
-before
-.Ql make !
-.Pp
-The one catch was that,
-having chdir'd in,
-I had to canonicalize the paths to any scripts used in the build recipes.
-For instance,
-I have a genpost.sh script in the
-.Pa bin/
-directory of this repo.
-To call it from the
-.Pa obj
-directory,
-I needed to use its absolute path via the
-.Va .CURDIR
-variable:
-.Pp
-.Dl $(.CURDIR)/bin/genpost.sh < $< > $@
-.Sh PORTABILITY
-While I mostly build my site on OpenBSD,
-it's important to me that it builds with GNU make too.
-.Pp
-Unfortunately,
-the
-.Va .OBJDIR
-chdir'ing appears to be an extension in OpenBSD's
-make (and possibly NetBSD too).
-The good news is that,
-with one more trick,
-GNU make support is easy to add
-(albeit without out-of-tree builds).
-.Pp
-The one final hack to support GNU make was to define
-a portable version of
-.Va .CURDIR .
-Since
-.Va .CURDIR
-isn't defined in GNU make (which uses
-.Va CURDIR
-instead),
-I had to define the
-.Va DIR
-variable that's the concatenation of the two:
-.Pp
-.Dl DIR = $(.CURDIR)$(CURDIR)
-.Pp
-.Sh CONCLUSION
-I hope this sheds some light on why
-.Ql make obj
-is common practice on OpenBSD as well as
-how to add similar support to your own projects!
-.Pp
-While not as flexible as GNU make's pattern matching
-inference rules (that allow builds in subdirectories),
-I find the chdir-ing into
-.Pa obj
-a cleverly simple way
-to obtain a similar end result.
-.Sh SEE ALSO
-.Bl -bullet -compact
-.It
-.Xr blog 7
-.It
-.Xr text-only 7
-.It
-.Xr my-old-man 7
-.El
diff --git a/my-old-man.7 b/my-old-man.7
@@ -1,159 +0,0 @@
-.Dd December 30, 2020
-.Dt MY-OLD-MAN 7
-.Os
-.Sh NAME
-.Nm my-old-man
-.Nd adventures in using
-.Xr mdoc 7
-as the markup for this site
-.Sh SYNOPSIS
-.Bd -literal -offset indent
-Uh oh,
-looks like,
-I'm seeing more of my old man(1) in me
- ~ Mac DeMarco (added (1) by me)
-.Ed
-.Sh DESCRIPTION
-While Mac wasn't talking about good old roff-style man pages,
-I felt his words were a fun description of my effort to move
-from a markdown based templated site to a
-.Xr mdoc 7
-based site.
-.Pp
-After pointing out that
-.Lk https://git.alexkarle.com/alexkarle.com/file/intro.7.html I really did
-rewrite my site in
-.Xr mdoc 7 ,
-you might be wondering
-.Em why
-I would do this.
-This blog post is intended to answer just that.
-.Sh WHY
-.Ss For the learning experience
-The single biggest motivator of the rewrite was that
-I like to use this site as a playground for learning new (old) technology,
-and
-.Xr mdoc 7
-was on my list of tech to learn.
-.Pp
-What better way to learn a new markup language than to port an existing
-project to use it?
-.Pp
-I had a blast transferring my old posts and coming up with a new build
-system.
-.Ss For the look
-I really enjoy a good
-.Xr man 1
-page.
-.Pp
-You've probably heard it before, but I'll say it again: one of the best
-parts of using OpenBSD is its concise and comprehensive man pages in
-the base system.
-.Pp
-There's a certain warm fuzzy feeling when you can learn something
-both without internet access and with the knowledge that it is the
-authoritative source.
-.Pp
-I want my site to be a homage to good, well thought out,
-.Xr man 1
-pages.
-.Ss Keeping it all in base
-As an OpenBSD nerd, I find a bit of joy in having a site which is built,
-deployed, and served all via the base OpenBSD system.
-.Pp
-By using
-.Xr mandoc 1
-instead of Markdown.pl, I can now build my site without any additional
-dependencies.
-.Pp
-Better yet,
-.Xr mandoc 1
-is ported to the various Linux distros I use day to day, and it is
-.Em fast .
-.Sh HOW
-If you read this far, I thought you might be interested to hear how I'm
-deploying the content.
-.Pp
-I'm a big fan of automation, so I've rigged up the site to deploy on a push
-to the master branch.
-Doing so involved two steps.
-.Ss Building the mdoc
-I created a small Makefile that builds each HTML file from each man page source.
-.Pp
-The relevant bit is the implicit suffix rule to convert each .7 file to .html:
-.Bd -literal -offset indent
-\).SUFFIXES: .7 .html
-\).7.html:
- @echo "mandoc $<"
- @mandoc -Thtml -O 'man=%N.html;https://man.openbsd.org/%N.%S,style=style.css' $< \\
- | sed 's#</head>#<meta name="viewport" content="width=device-width,initial-scale=1">&# ' \\
- > $@
-.Ed
-.Pp
-This looks crazy, but it's not too complex.
-First, know that
-.Sy $<
-is the source (the <name>.7 page), and
-.Sy $@
-is the target (the <name>.html page).
-The
-.Sy @
-prefix is a bit of magic to suppress printing the command run (so that all the
-output shown on git-push is just a single "mandoc" line for each file updated).
-.Pp
-Moving on to the mandoc command, I use the html output of mandoc via -T,
-with the -O switch specifying that linked man-page references should look
-locally first, then to point to man.openbsd.org.
-This allows me to quickly reference OpenBSD base tools and pages, while also
-using the terse
-.Sy .Xr
-macro for linking individual site pages.
-.Pp
-Finally, I use a
-.Xr sed 1
-oneliner to splice in a <meta> viewport tag for mobile
-devices.
-.Pp
-And that's really it!
-The rest is just listing the man pages I want built,
-with a phony default target depending on the html pages so that a
-.Ql make
-builds them all.
-Check out the full source
-.Lk https://git.alexkarle.com/alexkarle.com/file/Makefile.html here .
-.Ss Deploying via git hook
-Since I'm self-hosting git on the same server as the website, it's trivial to
-deploy when it receives a push by leveraging git hooks.
-.Pp
-For the unfamiliar, git hooks are simply shell scripts that are triggered by
-specific git actions.
-In this case, I used the post-receive hook to publish
-after the refs were updated via a
-.Ql git push .
-.Pp
-More specifically, I added the following to
-.Pa <git-dir>/hooks/post-receive :
-.Bd -literal -offset indent
-echo "Deploying to to /var/www/htdocs... "
-WT=/var/www/htdocs
-git -C ${dir} --work-tree=${WT} checkout -f master
-make -C ${WT}
-echo "done"
-.Ed
-.Pp
-So, on any push, it checks out the entire source tree into the webserver's content
-area and rebuilds only the necessary HTML files (thanks to
-.Xr make 1 ) .
-.Pp
-If I had files I didn't want served, I would modify it to build elsewhere and
-copy the contents to /var/www; however, I'm publishing both the source for the site
-and the git history at
-.Lk https://git.alexkarle.com ,
-so I don't see any harm to having the README.md accessible from the root.
-.Sh SEE ALSO
-.Bl -bullet -compact
-.It
-.Xr blog 7
-.It
-.Lk https://www.git-scm.com/docs/githooks git hooks
-.El
diff --git a/on-writing.7 b/on-writing.7
@@ -1,58 +0,0 @@
-.Dd October 22, 2020
-.Dt ON-WRITING 7
-.Os
-.Sh NAME
-.Nm on-writing
-.Nd thoughts on writing without an audience
-.Sh DESCRIPTION
-I wrote a blog post 3 weeks ago but never published it.
-I spent a couple hours writing, proof-reading, and rewriting, and settled to
-re-read once more in the morning and publish if I still liked it after a good
-nights sleep.
-.Pp
-I got caught up with other things, and a day or two later re-read it and
-still didn't end up publishing it.
-I didn't think it was quite right.
-I liked it well enough, but I was worried other people would judge it.
-.Pp
-But here's the irony
-\(em
-as far as I know, I have no readers.
-Publishing it is almost equivalent to shouting into the void.
-.Pp
-So why did I care so much?
-.Pp
-As I found myself thinking about how I'd revise the original post
-tonight, I realized that maybe this fear of judgment from non-existent
-(but potential future) internet strangers was a much more interesting
-topic to explore than my original musings.
-So here I am hashing it out.
-.Pp
-I think the fear of judgment comes from a mixture of seeing public figures
-have their pasts (preserved in the digital era) come back to haunt them
-combined with observing how readers can react strongly and negatively to
-posts.
-I don't plan to ever become so famous as to have a blog haunt me,
-nor do I ever expect enough readers to have overwhelmingly unpleasant
-reactions, but the fear still got to me.
-.Pp
-But I want to persevere, and that's ultimately what writing this is about.
-I'm not writing for fame or attention.
-I'm not writing to further my career or put it on my resume.
-I'm writing for me.
-For the clarity I get from expressing my thoughts, and for
-the joy I get looking back at where I was months or years ago.
-.Pp
-Why host them publicly?
-Well, I really enjoy a good tech blog, and admire a blogger or two out there.
-I want to be the change I want to see in the internet and migrate from
-centralized social networks back to a decentralized network of personal and
-self-hosted sites.
-.Pp
-And who knows, maybe one day someone will read this and have felt the same.
-I guess I'm writing for that person too.
-.Sh SEE ALSO
-.Bl -bullet -compact
-.It
-.Xr blog 7
-.El
diff --git a/self-hosted.7 b/self-hosted.7
@@ -1,98 +0,0 @@
-.Dd July 19, 2020
-.Dt SELF-HOSTED 7
-.Os
-.Sh NAME
-.Nm self-hosted
-.Nd a tale of migrating to my own server
-.Sh DESCRIPTION
-If you look at the first post
-.Xr ( a-new-hope 7 )
-on this site, you'll see that this site started as a series of static HTML
-files that I was, by hand, uploading to Fastmail via their "files" GUI.
-.Pp
-Being a total nerd for automation, I was always on the lookout for an excuse to
-migrate to my own server, where I could (over)engineer a pipeline to build my
-static content and deploy it without ever leaving the terminal.
-.Pp
-That excuse presented itself in the form of needing to get a VPS to stand up my
-hobby-project, `euchre.live`.
-If I was going to pay for a tiny VM, it was a no-brainer to move my personal
-site to it too.
-.Pp
-This turned out to be a great learning experience
-\(em
-getting hands on experience
-with reverse proxies, DNS, and a variety of operating systems and webservers
-(first hosted on Alpine Linux and migrated to OpenBSD).
-Additionally, I could self-host git repos, which has long been a nerd-goal of mine :)
-.Pp
-I plan to write a lengthier post about the joys of self-hosting in the future,
-but for now, I really just wanted to give a brief update on where I landed and
-what the current stack is.
-.Pp
-I'm currently running (in no particular order):
-.Pp
-.Bl -bullet -compact
-.It
-.Sy OS :
-OpenBSD
-.It
-.Sy Web server :
-OpenBSD's
-.Xr httpd 8
-.Bl -dash -compact
-.It
-Serves the `www.` static content
-.It
-Also serves
-.Lk https://git.alexkarle.com
-.El
-.It
-.Sy Reverse proxy :
-OpenBSD's
-.Xr relayd 8
-.Bl -dash -compact
-.It
-Used to send traffic between `euchre.live` (which uses a Mojolicious
-web server as the backend) and `alexkarle.com` based on URL
-.El
-.It
-.Sy `www` content :
-.Bl -dash -compact
-.It
-100% static content
-.It
-No metrics, ads, or tracking
-.It
-Posts and pages written in markdown
-.It
-HTML generated with a pipeline of the original `Markdown.pl` into a small
-templating Perl script that I home-rolled
-.El
-.It
-.Sy Git :
-.Bl -dash -compact
-.It
-Public repos served with
-.Xr git-daemon 1
-over the `git://` protocol
-.It
-Push access via the `ssh://` protocol
-.It
-static HTML of content generated via post-receive hook with
-.Xr stagit 1
-.El
-.El
-.Pp
-That's all for now!
-.Sh SEE ALSO
-.Bl -bullet -compact
-.It
-.Xr blog 7
-.It
-.Xr a-new-hope 7
-.It
-.Lk https://euchre.live
-.It
-.Lk https://mojolicious.org Mojolicious
-.El
diff --git a/style.css b/style.css
@@ -1,90 +0,0 @@
-/* general defaults */
-body {
- background-color: #F5F5F5;
- margin-left: 20px;
- margin-right: 20px;
- font-size: 1.3em;
- line-height: 1.3;
- font-family: monospace;
-}
-
-/* style tweaks */
-a:link { color: #0a7899; }
-a:visited { color: #033a4a; }
-code { font-size: 1em; }
-h1 { font-size: 1.1em; }
-h2 { font-size: 1em; }
-.foot-license {
- margin-top: 16px;
- font-size: .7em;
- position: static;
- bottom: 0;
-}
-
-/* override bold/italic colors within permalinks */
-a.permalink { text-decoration: none }
-b,i { color: #000000 }
-
-/* Responsive screen sizes */
-@media only screen and (min-width: 992px) {
- body {
- width: 60%;
- margin: 0 auto;
- }
-}
-@media only screen and (min-width: 600px) and (max-width: 991px) {
- body {
- width: 80%;
- margin: 0 auto;
- }
-}
-
-/* Smaller font on small screens */
-@media only screen and (max-width: 599px) {
- body { font-size: 1.1em; }
-}
-
-/* margins around head/foot */
-table.foot { margin-top: 3em; }
-table.head { margin-bottom: 3em; }
-
-/* scrollbars on the block-display content */
-div.Bd-indent {
- border-left-color: gray;
- border-left-style: solid;
- border-left-width: 2px;
- border-radius: 5px;
- padding-left: 1em;
-}
-
-.Bd > pre {
- overflow-x: auto;
-}
-
-/* Bl-tag correctly with grid for blog.7 */
-dl.Bl-tag {
- display: grid;
- grid-template-columns: max-content auto
-}
-dl.Bl-tag dd {
- margin-left: 16px;
- margin-bottom: 1em;
-}
-
-/* defaults from mandoc(1)'s inlined CSS */
-table.head, table.foot { width: 100%; }
-td.head-rtitle, td.foot-os { text-align: right; }
-.Nd, .Bf, .Op { display: inline; }
-.Pa, .Ad { font-style: italic; }
-.Ms { font-weight: bold; }
-.Bl-diag > dt { font-weight: bold; }
-code.Nm, .Fl, .Cm, .Ic, code.In, .Fd, .Fn, .Cd {
- font-weight: bold;
-}
-
-.jam-artists tr:nth-child(even) {
- background-color: #e3e3e3;
-}
-td.jam-artists, th.jam-artists, table.jam-artists {
- border: 1px solid black;
-}
diff --git a/text-only.7 b/text-only.7
@@ -1,89 +0,0 @@
-.Dd September 20, 2021
-.Dt TEXT-ONLY 7
-.Os
-.Sh NAME
-.Nm text-only
-.Nd announcing text.alexkarle.com
-.Sh DESCRIPTION
-This past week I rolled out
-.Lk https://text.alexkarle.com ,
-and I wanted to write a little bit about it!
-.Ss WHAT
-text.alexkarle.com is a text-only ascii dump of this entire site.
-It's served over HTTP, HTTPS, and Gopher to provide a wide array
-of options for accessing the content.
-.Ss WHY
-I'm a huge fan of the "small internet" and lightweight sites in general.
-Although I'm not an active participant in any of the tilde communities,
-I really appreciate the commitment to plaintext, *NIX, and simple software.
-.Pp
-At some point in my browsing of the tildeverse,
-I stumbled across Gopher and took a liking to the simple protocol.
-Surfing gopherspace is so awesomely fast and simple compared to
-the slow, ad-filled, modern web.
-Better yet, it's totally removed from the commercialization of the internet.
-No one is serving content on Gopher to make money.
-It's full of art and real, empathetic, humans.
-.Pp
-For my own part,
-I started serving an ascii dump of the
-.Xr mdoc 7
-content on this site over Gopher (via
-.Xr gophernicus 8 )
-almost 7 months ago.
-However, I was never really happy with how it was organized or generated
-(hence the lack of an announcement on the
-.Xr blog 7 ) .
-.Pp
-It was the discovery of a fellow
-.Xr mdoc 7
-website over at
-.Lk https://text.causal.agency
-that inspired me to revisit my approach to publishing a text-only
-version of this site.
-I finally replaced the scripted afterthought of a gopher
-publisher with a first class build target
-and decided to expand the offering from gopher-only to HTTP(S).
-I figured someone might prefer to browse it that way
-(maybe retro computing enthusiasts?),
-and with
-.Xr httpd 8
-already running, it came basically for free!
-.Ss HOW
-I started to write about all the "challenges" I faced in this process,
-but really these were all self-imposed problems from restricting myself
-to a POSIX subset of BSD
-.Xr make 1
-(in the name of
-.Xr creative-coding 7 ) .
-I think had I chosen either BSD make with extensions or GNU make,
-the build would have been much cleaner,
-but with a couple of hacks it's okay as is.
-.Pp
-Maybe I'll write about it someday,
-but it didn't feel worth holding up this "announcement".
-The TL;DR: I added another inference rule for *.7 -> *.txt and
-moved from a "build in tree" model (where the source tree was what was served by
-.Xr httpd 8 )
-to a "run the install target after build" model.
-The latter is necessary because POSIX inference rules only build into the
-current directory and I don't want text.alexkarle.com users to see the *.html
-there too.
-.Pp
-Of course, if you're curious to see how the bits come together,
-I publish all of the site source at
-.Lk https://git.alexkarle.com/alexkarle.com !
-.Sh UPDATE
-As of November 15, 2021, text.alexkarle.com was moved entirely to gopher.
-See
-.Xr burrowing 7
-for more info.
-.Sh SEE ALSO
-.Bl -bullet -compact
-.It
-.Xr blog 7
-.It
-.Xr my-old-man 7
-.It
-.Xr gophernicus 8
-.El
diff --git a/use-feeds.7 b/use-feeds.7
@@ -1,142 +0,0 @@
-.Dd February 9, 2021
-.Dt USE-FEEDS 7
-.Os
-.Sh NAME
-.Nm use-feeds
-.Nd RSS/Atom feeds; what are they and why you should care
-.Sh SYNOPSIS
-.Bd -literal -offset indent
-Feed the birds
-Tuppence, a bag
- ~ Mary Poppins
-.Ed
-.Sh DESCRIPTION
-I've always wanted this site to be an homage to tech that I
-enjoy using, and recently, that's included old-school RSS/Atom feeds.
-However, up until now, I had only been a feed consumer
-and had never produced my own.
-So, this past weekend I decided to hunker down and read enough
-of the spec to generate one for this site.
-.Pp
-But let's back up \(em what is a feed? Why should you care?
-.Pp
-A feed is simply a standardized listing of items a source
-(blog, vlog, newspaper, etc) has generated recently.
-Users then consume multiple feeds to get centralized notifications
-on new content.
-Think "following" on social media, but generalized for any content
-accessible on the web.
-.Pp
-The most important feature of a feed is that it has been standardized
-and is not controlled by any individual corporation.
-This ensures that users are not only free from vendor lock-in, but
-it also allows for an increasingly diverse set of clients and sources.
-.Pp
-For example, there are clients ranging from FOSS text only terminal
-clients like
-.Xr newsboat 1
-to commercial apps like
-.Lk https://feedly.com Feedly .
-And despite being drastically different UI's, their purpose is the same:
-allow you to subscribe to any number of feeds, and centralize your
-notifications.
-.Pp
-The idea is simple, but it's transformed the way I interact with the
-web.
-It saves me time in not browsing the infinite scroll that has
-become social media, and it allows me to stay up to date with smaller
-blogs that don't post frequently (cough, like yours truly, cough).
-.Pp
-Consider a new blog post on this site.
-Without a feed, you'd have to periodically check my
-.Xr blog 7
-for updates
-or hear about it through some other link aggregation or social media
-site (Hackernews, Reddit, etc).
-Adding a feed allows those who want to follow to get notifications, without
-checking other locations or having to waste time checking back periodically.
-.Pp
-So if you haven't tried a feed reader ever, go find one that suits
-your fancy and give it a try!
-In an era where user upvoted content reigns king (Reddit, Facebook, etc),
-it's really empowering as a user to decide
-.Em what
-you see updates for and to be able to check them on your own time.
-And if you're a publisher of any content, consider creating a feed for
-others to follow.
-I'll certainly appreciate it!
-.Pp
-It's never too late to take control of your digital habits,
-and using a feed reader is a good place to start.
-.Sh IMPLEMENTATION
-If you read this far, I thought you might also be interested in hearing
-not only the what and the why but also the
-.Em how .
-.Pp
-Due to the recent migration to using
-.Xr mdoc 7
-as the markup for this site (detailed in
-.Xr my-old-man 7 ) ,
-I knew that finding an off-the-shelf feed generator would be unlikely.
-Plus, with my general desire to keep the site build-able by base OpenBSD,
-I figured it was as good an excuse as any to read the spec and generate
-it myself.
-.Pp
-I ended up choosing Atom over RSS mostly based on some online opinions
-that it is a stricter standard, but I can't say much to back that up.
-What I can say is that after the initial confusion of how to escape the
-embedded HTML in the XML feed, it was pretty smooth sailing.
-.Pp
-The full implementation is in
-.Lk https://git.alexkarle.com/alexkarle.com/file/bin/genatom.sh.html genatom.sh
-and basically boils down to:
-.Pp
-.Bl -enum -compact
-.It
-.Xr grep 1
-call through the
-.Em blog.7
-file to get a list of entries and their dates
-.It
-Print the header of the XML (with newest date from 1.)
-.It
-For each item in entries, add the XML entry along with the content
-as generated by
-.Xr mandoc 1
-with the
-.Fl O Ar fragment
-option.
-This ensures the "notification" has the full post \(em
-users never even need to visit the site!
-.It
-End by printing the footer of the XML
-.El
-.Pp
-And that's it!
-The only real trick was to use
-.Lk https://en.wikipedia.org/wiki/CDATA CDATA
-sections around the entry content in the XML to escape the HTML tags.
-.Pp
-And of course, like everything else in this blog, it rebuilds on git-push
-via a call to
-.Xr make 1 .
-See the
-.Lk https://git.alexkarle.com/alexkarle.com/file/Makefile.html Makefile
-for the recipe.
-.Sh SEE ALSO
-.Bl -bullet -compact
-.It
-.Xr blog 7
-.It
-My Atom feed:
-.Lk https://alexkarle.com/atom.xml
-.It
-Wiki page on Atom:
-.Lk https://en.wikipedia.org/wiki/Atom_(Web_standard)
-.It
-Atom RFC:
-.Lk https://tools.ietf.org/html/rfc4287
-.It
-Related advocacy:
-.Lk https://atthis.link/blog/2021/rss.html
-.El
diff --git a/use-git.7 b/use-git.7
@@ -1,141 +0,0 @@
-.Dd November 07, 2021
-.Dt USE-GIT 7
-.Os
-.Sh NAME
-.Nm use-git
-.Nd non-standard uses for
-.Xr git 1
-.Sh DESCRIPTION
-In this post,
-I'm not going to teach you how to use
-.Xr git 1 .
-Instead,
-I wanted to write a quick post to encourage you to use git
-for non-conventional use cases
-(i.e. things other than source code).
-.Pp
-If perchance you're not familiar with git,
-there's a ton of good documentation out there.
-I'd recommend starting with the official and free
-.Lk https://git-scm.com/book/en/v2 Pro Git .
-Also,
-as a PSA,
-just know that git stores whole snapshots and NOT diffs.
-.Pp
-.Sh BACKGROUND
-Git is a distributed version control system,
-and this is a beautiful thing.
-I feel it's often lost on us,
-given that we use it most frequently on centralized forges
-for team collaboration (GitHub, GitLab, etc).
-.Pp
-Git being distributed means you can:
-.Pp
-.Bl -enum -compact
-.It
-Use it offline (your copy is "first class")
-.It
-Mirror it to as many places as you want
-.El
-.Pp
-In other words,
-git can be used without any dependence on a third-party
-service or company and with complete ownership of private data.
-Forges (and I recommend
-.Lk https://sourcehut.org )
-are a great place to backup your code and collaborate,
-but you don't have to use a forge to use git as a futureproof way to do what
-it does best: version your files.
-.Sh STORY TIME
-When I started my first job in tech,
-I found that it was a good habit to take personal notes.
-It was incredibly useful to quickly reference obscure CLI
-commands or system knowledge gained from pairing.
-These were things that were too small or personal to make it into
-standard documentation
-but invaluable to have on hand.
-.Pp
-My first solution was shoving them all into a directory called
-.Pa ~/notes
-as plaintext files.
-They were easy to write and reference,
-and it was simple to back them up by copying the directory
-to another drive nightly.
-.Pp
-Over time,
-the
-.Ql cp -a
-trick broke down:
-.Pp
-.Bl -bullet -compact
-.It
-Files deleted in the source prevailed in the backup
-.It
-Changes more than a day old were lost!
-.El
-.Pp
-Around the same time,
-I started getting more familiar with git,
-and it finally occurred to me:
-I could use git and still keep these notes private!
-.Pp
-Git can clone/push/pull across filesystems,
-so in the matter of minutes I solved both of my issues
-with just:
-.Bd -literal -offset indent
-# Set up the backup mirror
-$ git init --bare /backup/drive/notes.git
-
-# Put it to use!
-$ cd ~/notes
-$ git init && git add . && git commit -m "import"
-$ git remote add origin /backup/drive/notes.git
-$ git push -u origin main
-.Ed
-.Pp
-If you don't have a backup drive mounted,
-it's equally good (or better) to make the remote a repo
-accessed over SSH:
-.Bd -literal -offset indent
-# On the remote host
-user@example.com~$ git init --bare ~/notes.git
-
-# On the local host
-$ git remote add origin user@example.com:notes.git
-.Ed
-.Sh GOING FURTHER
-These days,
-I shudder at the thought of any important plaintext on my system
-that's not version-controlled somewhere.
-Too many hours are spent writing these little files,
-and it's so easy to version them,
-why risk losing any of that history?
-.Pp
-Aside from my private notes, I version:
-.Pp
-.Bl -bullet -compact
-.It
-System config files from /etc
-.It
-Personal config files (dotfiles)
-.It
-My passwords (via
-.Xr pass 1 )
-.It
-A small set of personal patches for FOSS projects I have yet to polish and upstream (a-la ports-system)
-.It
-My resume (admittedly still a DOCX from college, but versioning has really helped)
-.El
-.Pp
-In conclusion,
-my advice to anyone writing anything of importance:
-just use
-.Xr git 1 !
-.Sh SEE ALSO
-.Bl -bullet -compact
-.It
-.Xr blog 7
-.It
-.Lk https://github.blog/2020-12-17-commits-are-snapshots-not-diffs/ Commits are snapshots, not diffs
-by Derrick Stolee
-.El
diff --git a/uses.7 b/uses.7
@@ -1,129 +0,0 @@
-.Dd September 14, 2021
-.Dt USES 7
-.Os
-.Sh NAME
-.Nm uses
-.Nd list of software/hardware I use
-.Sh DESCRIPTION
-I really enjoy a good "uses" post.
-I think the first I ever stumbled across was Wes Bos',
-back when I was learning web-development.
-As someone fascinated by developer tooling,
-I loved hearing what other programmers use in their day-to-day lives.
-.Pp
-I try to keep this page up to date,
-both for my future nostalgia
-as well as for anyone else out there who enjoys the "genre".
-.Sh SOFTWARE
-.Ss Editor
-I got hooked on
-.Xr vim 1
-mid-college (~2017) and never looked back.
-It's first on this list (with a dedicated section!)
-because it was the "gateway program"
-that got me interested in developer tooling in the first place!
-If not my most important tool,
-it's definitely the most impactful.
-.Pp
-Other editors I use:
-.Pp
-.Bl -bullet -compact
-.It
-.Xr vi 1
-for system configs (super snappy on OpenBSD)
-.It
-.Xr ed 1
-for fun and for slow/serial connections (yes, really!)
-.El
-.Pp
-I try emacs every once and a while because I think Lisp is awesome
-(and far superior to VimScript),
-but I don't really dig the "run everything in emacs" approach.
-.Ss Operating System
-I've been passionate about running free and open source (FOSS)
-operating systems
-since ~2019 when I first started using Linux seriously at work.
-At some point in ~2020, I discovered OpenBSD and
-slowly started putting it on all of my personal machines.
-I'm currently running:
-.Pp
-.Bl -compact -bullet
-.It
-OpenBSD for my laptop, desktop,
-server (hosting this site \(em see
-.Xr self-hosted 7 ) ,
-and home router/firewall
-.It
-Arch Linux for work
-(needed a cutting edge kernel for newer work laptop)
-.El
-.Pp
-In the past I've also used Alpine Linux on my laptop and Debian
-on my desktop.
-.Ss Other Tools
-I'm a huge fan of command line tools for their composability and
-keyboard-centric UI. Some of my favorites include:
-.Pp
-.Bl -compact -bullet
-.It
-.Xr git 1
-for all things plaintext: notes, code, config backups, etc
-.It
-.Xr tmux 1
-for terminal scrollback, searching, copy/paste buffers, multiplexing,
-persistent sessions over dropped
-.Xr ssh 1
-connections... really a necessity!
-.It
-.Xr mutt 1
-for personal email (great for mailing lists!)
-.It
-.Xr pass 1
-for password/secret management
-.It
-.Xr sh 1
-for glueing it all together, of course!
-.El
-.Sh HARDWARE
-.Ss Keyboard
-After years of mushy laptop keyboards,
-I discovered mechanical keyboards through a coworker and
-I've been clicking and clacking happily ever since!
-.Pp
-I started off with an Ultimate Hacking Keyboard
-with Kailh browns (had to be quiet in a shared office),
-but I've been using a Keyboardio Atreus for about a year.
-I switched in a (successful!) attempt to reduce finger movement
-and strain.
-Plus, I'm a remote worker now,
-and I get to clack away at Kailh white switches,
-which is awesome.
-.Ss Laptop
-When I started really getting into Linux at work and home ~2019,
-I installed Arch on my old macbook and suffered at the hands of
-NVIDIA and poor hardware support until I ditched my macbook for
-a ThinkPad X220 (2011, i7, 2GB RAM) that I bought used for ~$130 off Ebay.
-A simple upgrade to a SSD and it runs great!
-.Pp
-I use the laptop for casual browsing and hobby coding
-(I try to ensure my hobby projects all run on old hardware!),
-but its CPU age really shows on big websites or compilations.
-.Ss Desktop
-I built my first desktop (a long standing nerd goal of mine) at the
-start of the COVID-19 pandemic in 2020 when it became clear I'd be
-working from home and my 2GB of laptop RAM wouldn't cut it.
-.Pp
-I tried (and failed) to keep the parts entirely FOSS-friendly,
-but I ended up getting a GPU that needed the AMDGPU firmware blobs
-(hard to find a fully free graphics card these days it seems).
-With a high-end CPU (AMD Ryzen 7 3700X)
-but a low-end GPU (Radeon RX 560),
-it was a reasonable price.
-And with 16GB of RAM, it handles my work environment well.
-.Sh SEE ALSO
-.Bl -bullet -compact
-.It
-.Xr blog 7
-.It
-.Lk https://wesbos.com/uses Wes Bos' uses page
-.El
diff --git a/www/LICENSE b/www/LICENSE
@@ -0,0 +1 @@
+../LICENSE
+\ No newline at end of file
diff --git a/www/blog/BLM.txt b/www/blog/BLM.txt
@@ -0,0 +1,12 @@
+# Black Lives Matter
+
+_Published: July 13, 2020_
+
+I meant to post about this earlier, but it's better late than
+never.
+
+It's become abundantly clear to me that we need serious structural
+changes in our country. I want to raise my voice in solidarity to
+say that [Black Lives Matter](https://blacklivesmatter.com).
+
+[Back to blog](/blog)
diff --git a/www/blog/a-new-hope.txt b/www/blog/a-new-hope.txt
@@ -0,0 +1,13 @@
+# A New Hope
+
+_Published: December 19, 2019_
+
+Toying with the thought of starting a website/blog.
+
+Exploring my hosting options and pleasantly surprised that
+[FastMail](https://fastmail.com) has free static site hosting!
+
+Inspired by [Jeff Huang's article](https://jeffhuang.com/designed_to_last)
+on websites Designed to Last and a general desire for a simpler web.
+
+[Back to blog](/blog)
diff --git a/www/blog/burrowing.txt b/www/blog/burrowing.txt
@@ -0,0 +1,78 @@
+# burrowing: From text-only to gopher-only
+
+_Published: November 15, 2021_
+
+## Description
+
+This past month, I've spent a lot of time learning about gopher.
+It's truly a fascinating alternative to the world wide web, not
+just in the content found there but also in terms of the protocol
+itself.
+
+As of this writing, I've decided to deprecate text.alexkarle.com
+in favor of serving that content (and more!) over gopher instead,
+exclusively.
+
+## Implications
+
+This shouldn't have much impact on this blog. After all,
+text.alexkarle.com was [an experiment](/blog/text-only.html) to begin
+with! I'll still keep publishing semi-regularly here, I just
+don't plan on maintaining a text dump via HTTP.
+
+I will, however, start publishing gopher-only content. There's two
+main reasons for this:
+
+1. I want to see more activity on gopher
+2. Gopher is easier to publish on
+
+Admittedly, number 2 is my own doing. I
+[moved this blog to `mdoc(7)`](/blog/my-old-man.html) willingly to
+learn the language. I've found that it slows my raw output,
+which, while fine for longer form pieces, is a pain for
+shorter-form thoughts. No regrets (I learned a ton!), but
+shorter-form thoughts do much better in plaintext!
+
+The first reason is a theme for this blog: be the change you want
+to see. I would love to see more content on gopher, so I'm taking
+the plunge.
+
+## The Pitch
+
+So, why gopher? Probably the biggest reason to explore gopher is
+the content. It's a parallel network totally untouched by
+commercial interests. You won't see a single ad.
+
+The second reason to try gopher lies in the protocol itself--gopher
+has a standardized menu interface, and individual gopherholes
+cannot change the way you interact with them beyond the standard.
+In a world where it seems every bit of the web's UI has been
+rewritten in JavaScript (looking at you, <div>'s that should be
+<button>'s), it's wildly refreshing to just have a predictable
+menu.
+
+So, gopher separates the interaction (menus) from the content (can
+be anything, but is usually plaintext). I think this is a cool
+design choice because it emphasizes what the gopher protocol is
+really about: fetching documents.
+
+Ultimately, it's hard to describe and much better experienced.
+For a quick dip, try out a proxy like [https://gopherproxy.net].
+For client recommendations, I'd check out
+[`lynx(1)`](https://lynx.invisible-island.net/),
+[`sacc(1)`](https://git.fifth.space/sacc), or
+[`bombadillo(1)`](https://bombadillo.colorfield.space/).
+Bombadillo has gemini support too, gemini being another
+alternative internet protocol worth checking out. I'll likely put
+my stuff up there too, if time allows.
+
+Not sure where to start in your client? Go to [gopher://alexkarle.com]
+of course! :)
+
+## See Also
+
+- [RFC 1436 (Gopher)](https://datatracker.ietf.org/doc/html/rfc1436)
+- [http://gopherproject.org]
+- [Gemini official site](https://gemini.circumlunar.space)
+
+[Back to blog](/blog)
diff --git a/www/blog/creative-coding.txt b/www/blog/creative-coding.txt
@@ -0,0 +1,44 @@
+# Learning Through Creative Limitation
+
+_Published: July 18, 2021_
+
+I was talking to a friend recently about hobby coding and ways to
+code creatively. In the course of that conversation, I was able to
+put a name to one of my favorite tactics: creative limitation.
+
+A quick internet search seems to associate the term with Phil
+Hansen and more traditional art, but I think it applies nicely to
+coding too. For example, with this site, I've chosen to restrict
+the tech stack to the OpenBSD base system. It wasn't the initial
+goal (which was to learn mdoc(7)), but I quickly realized that
+restricting to base would give me a better chance to learn base.
+
+Overall, I'd call it a success. The [Jam Tuesday](/jam-tuesday)
+setlist project gave me a chance to learn some
+[sh(1)](https://man.openbsd.org/sh.1) and
+[sed(1)](https://man.openbsd.org/sed.1), and my [blog](.)
+was a [chance to learn mdoc(7)](/blog/my-old-man.html),
+and the site's build system helped me brush up on BSD
+[make(1)](https://man.openbsd.org/make.1).
+
+I'd encourage you to try it -- set an arbitrary restriction and see
+where it takes you! Here's a few ideas to get you started:
+
+- Write your own X window manager in as few lines of code as you can
+- Write a version control system with
+ [sh(1)](https://man.openbsd.org/sh.1),
+ [diff(1)](https://man.openbsd.org/diff.1), and
+ [patch(1)](https://man.openbsd.org/sh.1)
+- Write a blogging engine updated via email
+- Write your own templating language (and parser)
+
+The goal, for me, is to choose a challenging project that helps me
+understand a technology I use daily but may take for granted
+(windowing systems, VCS, email, parsers, etc).
+
+Restricting size helps understand what the core definition of a
+technology is. Building clones can help teach edge cases and
+design decisions one might otherwise overlook. And in all cases,
+it's a good chance to learn a new language!
+
+[Back to blog](/blog)
diff --git a/www/blog/domain-names.txt b/www/blog/domain-names.txt
@@ -0,0 +1,38 @@
+# What's in a (Domain) Name
+
+_Published: March 24, 2020_
+
+I went through a phase this week of really wanting
+`karle.[original-tld]`. Not for a business. Not for boosting my
+own webpage (it doesn't really have much traffic). Just for me.
+
+The results were... disheartening.
+
+*karle.org*
+
+Registered since 2004, no website, just an email DNS record. WHOIS
+guard ensures I can't even reach out to who owns it.
+
+*karle.com*
+
+For sale by owner on Uniregistry. Ok. Inquired. Owner wants a
+"serious 5 figure offer". Next!
+
+*karle.net*
+
+Owned by [RealNames](https://realnames.com), a business seemingly
+centered around buying lastname.net domains and charging people
+like me to set up an email. Almost brilliant enough of a business
+to make me forgive their scumminess. _Almost._ Nary an option to
+buy it.
+
+
+## Conclusion
+
+So here we are. Looks like `karle.co` for at least a little
+longer.
+
+*Update:* I've settled on alexkarle.com and plan to use it for the
+foreseeable future.
+
+[Back to blog](/blog)
diff --git a/www/blog/index.txt b/www/blog/index.txt
@@ -0,0 +1,33 @@
+# yet another weblog
+
+## About
+
+I don't write frequently, but when I do, it's usually about tech.
+
+If you'd like to get notifications on new articles, I publish an
+[Atom feed](/atom.xml) (for use with your favorite RSS/Atom client).
+
+For an up to date list of software/hardware I use, see
+[my "uses" page](/uses.html).
+
+## 2021
+
+- 12/28 [Writing a Custom Markup Parser for this Site](/blog/mdoc-to-nihdoc.html)
+- 11/21 [From text-only to gopher-only](/blog/burrowing.html)
+- 11/21 [Some Non-Standard Uses of `git(1)`](/blog/use-git.html)
+- 09/21 [Out-of-tree Builds with `BSD make(1)`](/blog/make-obj.html)
+- 09/21 [Announcing text.alexkarle.com](/blog/text-only.html)
+- 07/21 [Learning Through Creative Limitation](/blog/creative-coding.html)
+- 02/21 [RSS/Atom feeds; What, Why, and How](/blog/use-feeds.html)
+
+## 2020
+
+- 12/20 [Adventures in Using `mdoc(7)` for This Site](/blog/my-old-man.html)
+- 10/20 [On Writing Without an Audience](/blog/on-writing.html)
+- 07/20 [Migrating to a Self-Hosted Site](/blog/self-hosted.html)
+- 07/20 [Black Lives Matter](/blog/BLM.html)
+- 03/20 [What's in a (Domain) Name?](/blog/domain-names.html)
+
+## 2019
+
+- 12/19 [A New Hope](/blog/a-new-hope.html)
diff --git a/www/blog/make-obj.txt b/www/blog/make-obj.txt
@@ -0,0 +1,87 @@
+# `make obj`: out-of-tree builds with BSD `make(1)`
+
+_Published: September 28, 2021_
+
+If you've ever built parts of OpenBSD from source, you may know
+that the sequence of commands recommended by
+[`release(8)`](https://man.openbsd.org/release.8) is:
+
+ $ make obj
+ $ make
+ # make install
+
+If, like me, you've forgotten the `make obj` step, you'll find
+yourself with many derived files in the current directory of
+whatever program you're building. By running `make obj` first, a
+directory called _obj_ appears and the derived files (usually \*.o
+files) are placed there instead. Cleverly, the _obj_ directory is
+actually a symlink to another filesystem under _/usr/obj_,
+making it truly an out-of-tree build.
+
+Up until recently, I understood what the `obj` target did and why
+it was useful. However, it wasn't until I tried to replicate it
+with the build for text.alexkarle.com that I discovered how it
+worked. I figured I'd document it here in case it helps anyone
+else.
+
+## How it Works
+
+My discovery of the inner workings of this target was a classic
+lesson in RTFM. After 10-15 minutes of trying to parse the
+makefiles in _/usr/share/mk_, I finally searched for _obj_ in the
+[`make(1)` man page](https://man.openbsd.org/make.1), and sure
+enough the answer was the first hit! I've copied it for
+convenience below (licensed under the BSD-3 clause):
+
+> *`.OBJDIR:`*
+> Path to the directory where targets are built. At
+> startup, make searches for an alternate directory to
+> place target files. make tries to `chdir(2)` into
+> `MAKEOBJDIR` (or obj if `MAKEOBJDIR` is not defined), and
+> sets `.OBJDIR` accordingly. Should that fail, `.OBJDIR`
+> is set to `.CURDIR`.
+
+With this new knowledge, getting an out-of-tree build was almost as
+simple as running `mkdir obj` before `make`!
+
+The one catch was that, having chdir'd in, I had to canonicalize
+the paths to any scripts used in the build recipes. For instance,
+I have a genpost.sh script in the bin/ directory of this repo. To
+call it from the obj directory, I needed to use its absolute path
+via the .CURDIR variable:
+
+ $(.CURDIR)/bin/genpost.sh < $< > $@
+
+## Portability
+
+While I mostly build my site on OpenBSD, it's important to me that
+it builds with GNU make too.
+
+Unfortunately, the `.OBJDIR` chdir'ing appears to be an extension in
+OpenBSD's make (and possibly NetBSD too). The good news is that,
+with one more trick, GNU make support is easy to add (albeit
+without out-of-tree builds).
+
+The one final hack to support GNU make was to define a portable
+version of `.CURDIR`. Since `.CURDIR` isn't defined in GNU make (which
+uses `CURDIR` instead), I had to define the `DIR` variable that's the
+concatenation of the two:
+
+ DIR = $(.CURDIR)$(CURDIR)
+
+## Conclusion
+
+I hope this sheds some light on why `make obj` is common practice
+on OpenBSD as well as how to add similar support to your own
+projects!
+
+While not as flexible as GNU make's pattern matching inference
+rules (that allow builds in subdirectories), I find the chdir-ing
+into obj a cleverly simple way to obtain a similar end result.
+
+## See Also
+
+- [text.alexkarle.com's origin story](/blog/text-only.html)
+- [writing the blog in mdoc(7)](/blog/my-old-man.html)
+
+[Back to blog](/blog)
diff --git a/www/blog/mdoc-to-nihdoc.txt b/www/blog/mdoc-to-nihdoc.txt
@@ -0,0 +1,164 @@
+# Writing a Custom Markup Parser for this Site
+
+_Published: December 28, 2021_
+
+## How it All Happened
+
+Almost exactly a year ago, I moved this site from templated
+markdown to a [static site built with `mdoc(7)`](/blog/my-old-man.html).
+I ported 5 blog posts in the process and ended up writing 7 more
+over the course of the year.
+
+While it was a success in teaching me
+[`mdoc(7)`](https://man.openbsd.org/mdoc.7), I found that it
+slowed me down a bit in authoring blog posts.
+
+Around the same time as I was feeling this slowness, I began
+actively phlogging on my [gopherhole](gopher://alexkarle.com) and
+[even started posting gopher-only content](/blog/burrowing.html).
+I really enjoyed writing plaintext posts because they are quick
+to write and, more importantly, highly durable to changes in
+technology. I can't imagine a world where one cannot open a plain
+`.txt` file and read/edit it.
+
+I got a real sense for the importance of optimizing for archival
+while browsing gopher--it's incredible to be reading textfiles
+older than me. It made me realize that I want to be sure that my
+content can survive for decades with minimal effort.
+
+So, I started thinking about how I could move my site's source
+(pre-HTML) to a more readable plaintext format. Markdown was the
+obvious choice, but I wanted to stay true to my
+[creative limitation](/blog/creative-coding.html) of keeping this
+site buildable by base OpenBSD, so I had to find another option.
+
+It was about 10 days into solving Advent of Code puzzles that I
+realized I could redirect some of the puzzling effort at the
+problem and write my own markup parser. The result, a few weeks
+later, is [`nihdoc(1)`](https://git.sr.ht/~akarle/nihdoc).
+`nihdoc(1)` (a play on the fact that markdown is *N*ot *I*nvented
+*H*ere) provides support for all the basic syntax I'd want in a
+blog post--nested lists, _inline_ *styles* and `code`, code
+blocks and block quotes, and headers. It was a blast to write,
+and I learned a lot in the process!
+
+I suspect the CSS for the blog will still change (maybe a dark
+mode? or something a little less plain), but I tried to keep the
+resulting HTML pretty bare in support of accessibility and
+portability--it should read well in screenreaders, embedded in
+RSS feeds, and more.
+
+If you want to see the source for any post, just replace the
+`.html` extension in the URL with `.txt`! For example, here's
+[this post's source](/blog/mdoc-to-nihdoc.txt).
+
+## Implementation Highlights
+
+If you read this far, I figure you might be interested in some of
+the implementation details and design decisions.
+
+### Stream Based Parsing
+
+Probably the most interesting detail of the parser is that it is
+stream-based with constant memory usage. In other words, it will
+start spitting out the input and the HTML markup as soon as it
+can decisively figure out what state it's in (i.e. has the
+paragraph ended, etc). Keeping track of this state is done with a
+handful of booleans/integers and doesn't involve storing lines in
+memory. In fact, the current implementation reads the input one
+character at a time!
+
+This is an efficiency win for large documents (not that my posts
+are that long), but was also just a fun constraint to try to code
+within. In practice, I found I was able to get support for almost
+everything I wanted (nested lists, etc) with maybe the exception of
+"bottom of the document" links that markdown allows. More on that
+later.
+
+### Balancing Ease of Implementation with Syntax
+
+One of the most interesting challenges in designing a markup
+language is settling on a syntax that's both easy-ish to
+implement (I'm a big believer in simpler = less bugs) but also
+syntactically appealing in plaintext format (after all, one of
+the main motivations was to make the source archive-ready).
+
+The best example of this was deciding how to write links.
+
+I started off with the easiest implementation, which is also the
+least appealing (IMHO). A link looked like this:
+
+ [https://alexkarle.com/blog my blog]
+
+This is super easy to parse one character at a time. In
+psuedo-code:
+
+1. If current character is *`[`*, print *`<a href="`*
+2. Print all characters (the href) until you see a space/newline
+3. Once we see the space/newline, print *`">`*
+4. Print all characters (the description) up until the `]`
+5. Once we see the *`]`*, print the closing *`</a>`*
+
+This fits really nicely into our "parse one character at a time",
+since each special character in the link corresponds to a direct
+piece of HTML to output. However, it's ugly to print links that
+have no description, such as:
+
+ [https://alexkarle.com https://alexkarle.com]
+
+To address this, the next evolution added a (stack-allocated)
+"link buffer" that would store the href as it was printed so that
+if the ']' was hit before a space/newline, it was assumed that
+the description was the href and it would print the link buffer
+in the place of the description, enabling "bare links" like so:
+
+ [https://alexkarle.com]
+
+I was about to go live on my blog with that iteration because I
+liked it _enough_, but the one thing that really bothered me was
+that it's hard to read the description after the link. To the
+plaintext reader, the description is way more important than the
+link! Especially for long links, it's distracting to have to scan
+ahead to continue a sentence.
+
+I really wanted markdown-style links like so:
+
+ [my blog](https://alexkarle.com/blog)
+
+The immediate problem was that the parser can no longer print the
+characters as it sees them, since the URL happens after the
+description in the input but needs to come before the description
+in the output. I realized however that this is a similar problem
+to the way I used the linkbuf for bare links--all I had to do was
+store the description in the buffer, and play it back after
+printing the href. It's the same amount of memory, but a tad more
+complex, since the description is allowed to have inline styles,
+so before pushing onto the link buf, we need to check for styles
+and push those too (effectively a smaller version of the main
+loop).
+
+The final form of markdown links that I'd like to support but
+can't is a "postfix link", link so:
+
+ This is a [link] in
+ a paragraph
+ ...
+ [link]: https://alexkarle.com
+
+Since the actual link could be anywhere in the document, this
+kind of parsing requires buffering potentially the whole
+document, which violates the streaming condition (which I'd like
+to keep!), so I stopped short of it.
+
+## Conclusion
+
+I hope you found this discussion of syntax, tradeoffs, and
+parsers interesting! I'm sure there's a lot more I can learn and
+improve on, but it's been a fun evolution from the `mdoc(7)` I
+started with! Check out the
+[source](https://git.sr.ht/~akarle/nihdoc) if you're curious. I
+expect it'll change rather frequently in the next few weeks, so I
+wouldn't advise depending on it yourself (but I wanted to open
+source it to share with others as a teaching tool regardless!).
+
+[Back to blog](/blog)
diff --git a/www/blog/my-old-man-orig.html b/www/blog/my-old-man-orig.html
@@ -0,0 +1,268 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+ <meta charset="utf-8"/>
+ <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
+<style>
+/* general defaults */
+body {
+ background-color: #F5F5F5;
+ margin-left: 20px;
+ margin-right: 20px;
+ font-size: 1.3em;
+ line-height: 1.3;
+ font-family: monospace;
+}
+
+/* style tweaks */
+a:link { color: #0a7899; }
+a:visited { color: #033a4a; }
+code { font-size: 1em; }
+h1 { font-size: 1.1em; }
+h2 { font-size: 1em; }
+.foot-license {
+ margin-top: 16px;
+ font-size: .7em;
+ position: static;
+ bottom: 0;
+}
+
+/* override bold/italic colors within permalinks */
+a.permalink { text-decoration: none }
+b,i { color: #000000 }
+
+/* Responsive screen sizes */
+@media only screen and (min-width: 992px) {
+ body {
+ width: 60%;
+ margin: 0 auto;
+ }
+}
+@media only screen and (min-width: 600px) and (max-width: 991px) {
+ body {
+ width: 80%;
+ margin: 0 auto;
+ }
+}
+
+/* Smaller font on small screens */
+@media only screen and (max-width: 599px) {
+ body { font-size: 1.1em; }
+}
+
+/* margins around head/foot */
+table.foot { margin-top: 3em; }
+table.head { margin-bottom: 3em; }
+
+/* scrollbars on the block-display content */
+div.Bd-indent {
+ border-left-color: gray;
+ border-left-style: solid;
+ border-left-width: 2px;
+ border-radius: 5px;
+ padding-left: 1em;
+}
+
+.Bd > pre {
+ overflow-x: auto;
+}
+
+/* Bl-tag correctly with grid for blog.7 */
+dl.Bl-tag {
+ display: grid;
+ grid-template-columns: max-content auto
+}
+dl.Bl-tag dd {
+ margin-left: 16px;
+ margin-bottom: 1em;
+}
+
+/* defaults from mandoc(1)'s inlined CSS */
+table.head, table.foot { width: 100%; }
+td.head-rtitle, td.foot-os { text-align: right; }
+.Nd, .Bf, .Op { display: inline; }
+.Pa, .Ad { font-style: italic; }
+.Ms { font-weight: bold; }
+.Bl-diag > dt { font-weight: bold; }
+code.Nm, .Fl, .Cm, .Ic, code.In, .Fd, .Fn, .Cd {
+ font-weight: bold;
+}
+</style>
+ <title>MY-OLD-MAN(7)</title>
+<meta name="viewport" content="width=device-width,initial-scale=1"></head>
+<body>
+<table class="head">
+ <tr>
+ <td class="head-ltitle">MY-OLD-MAN(7)</td>
+ <td class="head-rtitle">MY-OLD-MAN(7)</td>
+ </tr>
+</table>
+<div class="manual-text">
+<section class="Sh">
+<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
+<p class="Pp"><code class="Nm">my-old-man</code> —
+ <span class="Nd">adventures in using
+ <a class="Xr" href="https://man.openbsd.org/mdoc.7">mdoc(7)</a> as the
+ markup for this site</span></p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
+<div class="Bd Bd-indent Li">
+<pre>Uh oh,
+looks like,
+I'm seeing more of my old man(1) in me
+ ~ Mac DeMarco (added (1) by me)</pre>
+</div>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
+<p class="Pp">While Mac wasn't talking about good old roff-style man pages, I
+ felt his words were a fun description of my effort to move from a markdown
+ based templated site to a
+ <a class="Xr" href="https://man.openbsd.org/mdoc.7">mdoc(7)</a> based
+ site.</p>
+<p class="Pp" id="why">After pointing out that
+ <a class="Lk" href="https://git.alexkarle.com/alexkarle.com/file/intro.7.html">I
+ really did</a> rewrite my site in
+ <a class="Xr" href="https://man.openbsd.org/mdoc.7">mdoc(7)</a>, you might
+ be wondering <a class="permalink" href="#why"><i class="Em">why</i></a> I
+ would do this. This blog post is intended to answer just that.</p>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="WHY"><a class="permalink" href="#WHY">WHY</a></h1>
+<section class="Ss">
+<h2 class="Ss" id="For_the_learning_experience"><a class="permalink" href="#For_the_learning_experience">For
+ the learning experience</a></h2>
+<p class="Pp">The single biggest motivator of the rewrite was that I like to use
+ this site as a playground for learning new (old) technology, and
+ <a class="Xr" href="https://man.openbsd.org/mdoc.7">mdoc(7)</a> was on my
+ list of tech to learn.</p>
+<p class="Pp">What better way to learn a new markup language than to port an
+ existing project to use it?</p>
+<p class="Pp">I had a blast transferring my old posts and coming up with a new
+ build system.</p>
+</section>
+<section class="Ss">
+<h2 class="Ss" id="For_the_look"><a class="permalink" href="#For_the_look">For
+ the look</a></h2>
+<p class="Pp">I really enjoy a good
+ <a class="Xr" href="https://man.openbsd.org/man.1">man(1)</a> page.</p>
+<p class="Pp">You've probably heard it before, but I'll say it again: one of the
+ best parts of using OpenBSD is its concise and comprehensive man pages in
+ the base system.</p>
+<p class="Pp">There's a certain warm fuzzy feeling when you can learn something
+ both without internet access and with the knowledge that it is the
+ authoritative source.</p>
+<p class="Pp">I want my site to be a homage to good, well thought out,
+ <a class="Xr" href="https://man.openbsd.org/man.1">man(1)</a> pages.</p>
+</section>
+<section class="Ss">
+<h2 class="Ss" id="Keeping_it_all_in_base"><a class="permalink" href="#Keeping_it_all_in_base">Keeping
+ it all in base</a></h2>
+<p class="Pp">As an OpenBSD nerd, I find a bit of joy in having a site which is
+ built, deployed, and served all via the base OpenBSD system.</p>
+<p class="Pp">By using
+ <a class="Xr" href="https://man.openbsd.org/mandoc.1">mandoc(1)</a> instead
+ of Markdown.pl, I can now build my site without any additional
+ dependencies.</p>
+<p class="Pp" id="fast">Better yet,
+ <a class="Xr" href="https://man.openbsd.org/mandoc.1">mandoc(1)</a> is
+ ported to the various Linux distros I use day to day, and it is
+ <a class="permalink" href="#fast"><i class="Em">fast</i></a>.</p>
+</section>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="HOW"><a class="permalink" href="#HOW">HOW</a></h1>
+<p class="Pp">If you read this far, I thought you might be interested to hear
+ how I'm deploying the content.</p>
+<p class="Pp">I'm a big fan of automation, so I've rigged up the site to deploy
+ on a push to the master branch. Doing so involved two steps.</p>
+<section class="Ss">
+<h2 class="Ss" id="Building_the_mdoc"><a class="permalink" href="#Building_the_mdoc">Building
+ the mdoc</a></h2>
+<p class="Pp">I created a small Makefile that builds each HTML file from each
+ man page source.</p>
+<p class="Pp">The relevant bit is the implicit suffix rule to convert each .7
+ file to .html:</p>
+<div class="Bd Pp Bd-indent Li">
+<pre>.SUFFIXES: .7 .html
+.7.html:
+ @echo "mandoc $<"
+ @mandoc -Thtml -O 'man=%N.html;https://man.openbsd.org/%N.%S,style=style.css' $< \
+ | sed 's#</head>#<meta name="viewport" content="width=device-width,initial-scale=1">&# ' \
+ > $@</pre>
+</div>
+<p class="Pp" id="$_">This looks crazy, but it's not too complex. First, know
+ that <a class="permalink" href="#$_"><b class="Sy">$<</b></a> is the
+ source (the <name>.7 page), and
+ <a class="permalink" href="#$@"><b class="Sy" id="$@">$@</b></a> is the
+ target (the <name>.html page). The
+ <a class="permalink" href="#@"><b class="Sy" id="@">@</b></a> prefix is a
+ bit of magic to suppress printing the command run (so that all the output
+ shown on git-push is just a single "mandoc" line for each file
+ updated).</p>
+<p class="Pp" id=".Xr">Moving on to the mandoc command, I use the html output of
+ mandoc via -T, with the -O switch specifying that linked man-page references
+ should look locally first, then to point to man.openbsd.org. This allows me
+ to quickly reference OpenBSD base tools and pages, while also using the
+ terse <a class="permalink" href="#.Xr"><b class="Sy">.Xr</b></a> macro for
+ linking individual site pages.</p>
+<p class="Pp">Finally, I use a
+ <a class="Xr" href="https://man.openbsd.org/sed.1">sed(1)</a> oneliner to
+ splice in a <meta> viewport tag for mobile devices.</p>
+<p class="Pp">And that's really it! The rest is just listing the man pages I
+ want built, with a phony default target depending on the html pages so that
+ a ‘<code class="Li">make</code>’ builds them all. Check out
+ the full source
+ <a class="Lk" href="https://git.alexkarle.com/alexkarle.com/file/Makefile.html">here</a>.</p>
+</section>
+<section class="Ss">
+<h2 class="Ss" id="Deploying_via_git_hook"><a class="permalink" href="#Deploying_via_git_hook">Deploying
+ via git hook</a></h2>
+<p class="Pp">Since I'm self-hosting git on the same server as the website, it's
+ trivial to deploy when it receives a push by leveraging git hooks.</p>
+<p class="Pp">For the unfamiliar, git hooks are simply shell scripts that are
+ triggered by specific git actions. In this case, I used the post-receive
+ hook to publish after the refs were updated via a
+ ‘<code class="Li">git push</code>’.</p>
+<p class="Pp">More specifically, I added the following to
+ <span class="Pa"><git-dir>/hooks/post-receive</span>:</p>
+<div class="Bd Pp Bd-indent Li">
+<pre>echo "Deploying to to /var/www/htdocs... "
+WT=/var/www/htdocs
+git -C ${dir} --work-tree=${WT} checkout -f master
+make -C ${WT}
+echo "done"</pre>
+</div>
+<p class="Pp">So, on any push, it checks out the entire source tree into the
+ webserver's content area and rebuilds only the necessary HTML files (thanks
+ to <a class="Xr" href="https://man.openbsd.org/make.1">make(1)</a>).</p>
+<p class="Pp">If I had files I didn't want served, I would modify it to build
+ elsewhere and copy the contents to /var/www; however, I'm publishing both
+ the source for the site and the git history at
+ <a class="Lk" href="https://git.alexkarle.com">https://git.alexkarle.com</a>,
+ so I don't see any harm to having the README.md accessible from the
+ root.</p>
+</section>
+</section>
+<section class="Sh">
+<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
+ ALSO</a></h1>
+<ul class="Bl-bullet Bl-compact">
+ <li><a class="Xr" href="blog.html">blog(7)</a></li>
+ <li><a class="Lk" href="https://www.git-scm.com/docs/githooks">git
+ hooks</a></li>
+</ul>
+</section>
+</div>
+<table class="foot">
+ <tr>
+ <td class="foot-date">December 30, 2020</td>
+ <td class="foot-os">OpenBSD 7.0</td>
+ </tr>
+</table>
+<p class="foot-license">
+ © 2019-2021 Alex Karle | <a href="/">Home</a> | <a href="/license.html">License</a>
+</p>
+</body>
+</html>
diff --git a/www/blog/my-old-man.txt b/www/blog/my-old-man.txt
@@ -0,0 +1,143 @@
+# my-old-man: Adventures in using mdoc(7) as the markup for this site
+
+_Published: December 30, 2020_
+
+*Update:* As of December 2021, I've moved to a
+[new markup format](/blog/mdoc-to-nihdoc.html).
+For a glimpse at what the format discussed looks like, here's
+[the original post](/blog/my-old-man-orig.html).
+
+ Uh oh,
+ looks like,
+ I'm seeing more of my old man(1) in me
+ ~ Mac DeMarco (added (1) by me)
+
+## Description
+
+While Mac wasn't talking about good old roff-style man pages, I
+felt his words were a fun description of my effort to move from a
+markdown based templated site to a
+[`mdoc(7)`](https://man.openbsd.org/mdoc.7) based site.
+
+After pointing out that
+[I really did](https://git.sr.ht/~akarle/alexkarle.com/commit/844441fce7ac5c0364b3fe1a217da6889cb937ba)
+rewrite my site in `mdoc(7)`, you might be wondering why I would do this.
+This blog post is intended to answer just that.
+
+## Why
+
+### For the learning experience
+
+The single biggest motivator of the rewrite was that I like to use
+this site as a playground for learning new (old) technology, and
+`mdoc(7)` was on my list of tech to learn.
+
+What better way to learn a new markup language than to port an
+existing project to use it?
+
+I had a blast transferring my old posts and coming up with a new
+build system.
+
+### For the look
+
+I really enjoy a good [`man(1)`](https://man.openbsd.org/man.1) page.
+
+You've probably heard it before, but I'll say it again: one of the
+best parts of using OpenBSD is its concise and comprehensive man
+pages in the base system.
+
+There's a certain warm fuzzy feeling when you can learn something
+both without internet access and with the knowledge that it is the
+authoritative source.
+
+I want my site to be a homage to good, well thought out, `man(1)`
+pages.
+
+### Keeping it all in base
+
+As an OpenBSD nerd, I find a bit of joy in having a site which is
+built, deployed, and served all via the base OpenBSD system.
+
+By using [`mandoc(1)`](https://man.openbsd.org/mandoc.1) instead of
+Markdown.pl, I can now build my site without any additional
+dependencies.
+
+Better yet, `mandoc(1)` is ported to the various Linux distros I use
+day to day, and it is fast.
+
+## How
+
+If you read this far, I thought you might be interested to hear how
+I'm deploying the content.
+
+I'm a big fan of automation, so I've rigged up the site to deploy
+on a push to the master branch. Doing so involved two steps.
+
+### Building the mdoc
+
+I created a small Makefile that builds each HTML file from each man
+page source.
+
+The relevant bit is the implicit suffix rule to convert each `.7`
+file to `.html`:
+
+ SUFFIXES: .7 .html
+ 7.html:
+ @echo "mandoc $<"
+ @mandoc -Thtml -O 'man=%N.html;https://man.openbsd.org/%N.%S,style=style.css' $< \
+ | sed 's#</head>#<meta name="viewport" content="width=device-width,initial-scale=1">&# ' \
+ > $@
+
+This looks crazy, but it's not too complex. First, know that `$<` is
+the source (the `<name>.7` page), and `$@` is the target (the
+`<name>.html` page). The `@` prefix is a bit of magic to suppress
+printing the command run (so that all the output shown on git-push
+is just a single "mandoc" line for each file updated).
+
+Moving on to the mandoc command, I use the html output of mandoc
+via `-T,` with the `-O` switch specifying that linked man-page
+references should look locally first, then to point to
+man.openbsd.org. This allows me to quickly reference OpenBSD base
+tools and pages, while also using the terse `.Xr` macro for linking
+individual site pages.
+
+Finally, I use a `sed(1)` oneliner to splice in a <meta> viewport tag
+for mobile devices.
+
+And that's really it! The rest is just listing the man pages I
+want built, with a phony default target depending on the html pages
+so that a `make` builds them all.
+
+### Deploying via git hook
+
+Since I'm self-hosting git on the same server as the website, it's
+trivial to deploy when it receives a push by leveraging git hooks.
+
+For the unfamiliar, git hooks are simply shell scripts that are
+triggered by specific git actions. In this case, I used the
+post-receive hook to publish after the refs were updated via a `git
+push`.
+
+More specifically, I added the following to `<git-dir>/hooks/post-receive:`
+
+ echo "Deploying to to /var/www/htdocs... "
+ WT=/var/www/htdocs
+ git -C ${dir} --work-tree=${WT} checkout -f master
+ make -C ${WT}
+ echo "done"
+
+So, on any push, it checks out the entire source tree into the
+webserver's content area and rebuilds only the necessary HTML files
+(thanks to `make(1)`).
+
+If I had files I didn't want served, I would modify it to build
+elsewhere and copy the contents to `/var/www`; however, I'm
+publishing both the source for the site and the git history at
+[https://git.alexkarle.com], so I don't see any harm to having the
+README.md accessible from the root.
+
+## See Also
+
+- [githooks documentation](https://www.git-scm.com/docs/githooks)
+
+[Back to blog](/blog)
diff --git a/www/blog/on-writing.txt b/www/blog/on-writing.txt
@@ -0,0 +1,48 @@
+# Thoughts on writing without an audience
+
+_Published: October 22, 2020_
+
+I wrote a blog post 3 weeks ago but never published it. I spent a
+couple hours writing, proof-reading, and rewriting, and settled to
+re-read once more in the morning and publish if I still liked it
+after a good nights sleep.
+
+I got caught up with other things, and a day or two later re-read
+it and still didn't end up publishing it. I didn't think it was
+quite right. I liked it well enough, but I was worried other
+people would judge it.
+
+But here's the irony -- as far as I know, I have no readers.
+Publishing it is almost equivalent to shouting into the void.
+
+So why did I care so much?
+
+As I found myself thinking about how I'd revise the original post
+tonight, I realized that maybe this fear of judgment from non-
+existent (but potential future) internet strangers was a much more
+interesting topic to explore than my original musings. So here I
+am hashing it out.
+
+I think the fear of judgment comes from a mixture of seeing public
+figures have their pasts (preserved in the digital era) come back
+to haunt them combined with observing how readers can react
+strongly and negatively to posts. I don't plan to ever become so
+famous as to have a blog haunt me, nor do I ever expect enough
+readers to have overwhelmingly unpleasant reactions, but the fear
+still got to me.
+
+But I want to persevere, and that's ultimately what writing this is
+about. I'm not writing for fame or attention. I'm not writing to
+further my career or put it on my resume. I'm writing for me. For
+the clarity I get from expressing my thoughts, and for the joy I
+get looking back at where I was months or years ago.
+
+Why host them publicly? Well, I really enjoy a good tech blog, and
+admire a blogger or two out there. I want to be the change I want
+to see in the internet and migrate from centralized social networks
+back to a decentralized network of personal and self-hosted sites.
+
+And who knows, maybe one day someone will read this and have felt
+the same. I guess I'm writing for that person too.
+
+[Back to blog](/blog)
diff --git a/www/blog/self-hosted.txt b/www/blog/self-hosted.txt
@@ -0,0 +1,54 @@
+# self-hosted: A tale of migrating to my own server
+
+_Published: July 19, 2020_
+
+If you look at [the first post](/blog/a-new-hope.html) on this site, you'll
+see that this site started as a series of static HTML files that I
+was, by hand, uploading to Fastmail via their "files" GUI.
+
+Being a total nerd for automation, I was always on the lookout for
+an excuse to migrate to my own server, where I could (over)engineer
+a pipeline to build my static content and deploy it without ever
+leaving the terminal.
+
+That excuse presented itself in the form of needing to get a VPS to
+stand up my hobby-project, [`euchre.live`](https://euchre.live).
+If I was going to pay for a tiny VM, it was a no-brainer to move
+my personal site to it too.
+
+This turned out to be a great learning experience -- getting hands
+on experience with reverse proxies, DNS, and a variety of operating
+systems and webservers (first hosted on Alpine Linux and migrated
+to OpenBSD). Additionally, I could self-host git repos, which has
+long been a nerd-goal of mine :)
+
+I plan to write a lengthier post about the joys of self-hosting in
+the future, but for now, I really just wanted to give a brief
+update on where I landed and what the current stack is.
+
+I'm currently running (in no particular order):
+
+- *OS:* OpenBSD
+- *Web server:* OpenBSD's `httpd(8)`
+ - Serves the `www.` static content
+ - Also serves [https://git.alexkarle.com]
+- *Reverse proxy:* OpenBSD's `relayd(8)`
+ - Used to send traffic between [https://euchre.live] (which uses
+ a Mojolicious web server as the backend) and
+ [https://alexkarle.com] based on URL
+- *`www` content:*
+ - 100% static content
+ - No metrics, ads, or tracking
+ - Posts and pages written in markdown
+ - HTML generated with a pipeline of the original `Markdown.pl`
+ into a small templating Perl script that I home-rolled
+- *Git:*
+ - Public repos served with `git-daemon(1)` over the `git://`
+ protocol
+ - Push access via the `ssh://` protocol
+ - static HTML of content generated via post-receive hook with
+ [`stagit(1)`](https://git.codemadness.org/stagit/)
+
+That's all for now!
+
+[Back to blog](/blog)
diff --git a/www/blog/text-only.txt b/www/blog/text-only.txt
@@ -0,0 +1,70 @@
+# text-only: Announcing text.alexkarle.com
+
+_Published: September 20, 2021_
+
+This past week I rolled out [https://text.alexkarle.com], and I
+wanted to write a little bit about it!
+
+## What
+
+text.alexkarle.com is a text-only ascii dump of this entire site.
+It's served over HTTP, HTTPS, and Gopher to provide a wide array of
+options for accessing the content.
+
+## Why
+
+I'm a huge fan of the "small internet" and lightweight sites in
+general. Although I'm not an active participant in any of the
+tilde communities, I really appreciate the commitment to plaintext,
+\*NIX, and simple software.
+
+At some point in my browsing of the tildeverse, I stumbled across
+Gopher and took a liking to the simple protocol. Surfing
+gopherspace is so awesomely fast and simple compared to the slow,
+ad-filled, modern web. Better yet, it's totally removed from the
+commercialization of the internet. No one is serving content on
+Gopher to make money. It's full of art and real, empathetic,
+humans.
+
+For my own part, I started serving an ascii dump of the `mdoc(7)`
+content on this site over Gopher (via
+[`gophernicus(8)`](https://gophernicus.org)) almost 7 months ago.
+However, I was never really happy with how it was organized or
+generated (hence the lack of an announcement on the `blog(7)`).
+
+It was the discovery of a fellow `mdoc(7)` website over at
+[https://text.causal.agency] that inspired me to revisit my approach
+to publishing a text-only version of this site. I finally replaced
+the scripted afterthought of a gopher publisher with a first class
+build target and decided to expand the offering from gopher-only to
+HTTP(S). I figured someone might prefer to browse it that way
+(maybe retro computing enthusiasts?), and with `httpd(8)` already
+running, it came basically for free!
+
+## How
+
+I started to write about all the "challenges" I faced in this
+process, but really these were all self-imposed problems from
+restricting myself to a POSIX subset of BSD `make(1)` (in the name of
+[creative coding](creative-coding.html)). I think had I chosen either BSD make with
+extensions or GNU make, the build would have been much cleaner, but
+with a couple of hacks it's okay as is.
+
+Maybe I'll write about it someday, but it didn't feel worth holding
+up this "announcement". The TL;DR: I added another inference rule
+for `*.7` -> `*.txt` and moved from a "build in tree" model (where the
+source tree was what was served by `httpd(8)`) to a "run the install
+target after build" model. The latter is necessary because POSIX
+inference rules only build into the current directory and I don't
+want text.alexkarle.com users to see the `*.html` there too.
+
+Of course, if you're curious to see how the bits come together, I
+publish all of the site source at
+[https://sr.ht/~akarle/alexkarle.com]!
+
+## Update
+
+As of November 15, 2021, text.alexkarle.com was moved entirely to
+gopher. See [this blog post](/blog/burrowing.html) for more info.
+
+[Back to blog](/blog)
diff --git a/www/blog/use-feeds.txt b/www/blog/use-feeds.txt
@@ -0,0 +1,100 @@
+# RSS/Atom feeds; what are they and why you should care
+
+_Published: February 9, 2021_
+
+I've always wanted this site to be an homage to tech that I enjoy
+using, and recently, that's included old-school RSS/Atom feeds.
+However, up until now, I had only been a feed consumer and had
+never produced my own. So, this past weekend I decided to hunker
+down and read enough of the spec to generate one for this site.
+
+But let's back up -- what is a feed? Why should you care?
+
+A feed is simply a standardized listing of items a source (blog,
+vlog, newspaper, etc) has generated recently. Users then consume
+multiple feeds to get centralized notifications on new content.
+Think "following" on social media, but generalized for any content
+accessible on the web.
+
+The most important feature of a feed is that it has been
+standardized and is not controlled by any individual corporation.
+This ensures that users are not only free from vendor lock-in, but
+it also allows for an increasingly diverse set of clients and
+sources.
+
+For example, there are clients ranging from FOSS text only terminal
+clients like [`newsboat(1)`](https://newsboat.org) to commercial apps
+like [Feedly](https://feedly.com). And despite being drastically
+different UI's, their purpose is the same: allow you to subscribe
+to any number of feeds, and centralize your notifications.
+
+The idea is simple, but it's transformed the way I interact with
+the web. It saves me time in not browsing the infinite scroll that
+has become social media, and it allows me to stay up to date with
+smaller blogs that don't post frequently (cough, like yours truly,
+cough).
+
+Consider a new blog post on this site. Without a feed, you'd have
+to periodically check my `blog(7)` for updates or hear about it
+through some other link aggregation or social media site
+(Hackernews, Reddit, etc). Adding a feed allows those who want to
+follow to get notifications, without checking other locations or
+having to waste time checking back periodically.
+
+So if you haven't tried a feed reader ever, go find one that suits
+your fancy and give it a try! In an era where user upvoted content
+reigns king (Reddit, Facebook, etc), it's really empowering as a
+user to decide what you see updates for and to be able to check
+them on your own time. And if you're a publisher of any content,
+consider creating a feed for others to follow. I'll certainly
+appreciate it!
+
+It's never too late to take control of your digital habits, and
+using a feed reader is a good place to start.
+
+## Implementation
+
+If you read this far, I thought you might also be interested in
+hearing not only the what and the why but also the how.
+
+Due to the recent migration to using `mdoc(7)` as the markup for this
+site (detailed in [my-old-man(7)](/blog/my-old-man.html)), I knew that
+finding an off-the-shelf feed generator would be unlikely.
+Plus, with my general desire to keep the site build-able by base
+OpenBSD, I figured it was as good an excuse as any to read the
+spec and generate it myself.
+
+I ended up choosing Atom over RSS mostly based on some online
+opinions that it is a stricter standard, but I can't say much to
+back that up. What I can say is that after the initial confusion
+of how to escape the embedded HTML in the XML feed, it was pretty
+smooth sailing.
+
+The full implementation is in
+[genatom.sh](https://git.sr.ht/~akarle/alexkarle.com/tree/5c1fd5edca840e3ec2f8a80b8fed763d30cfa11a/item/bin/genatom.sh)
+and basically boils down to:
+
+1. `grep(1)` call through the blog.7 file to get a list of entries
+ and their dates
+2. Print the header of the XML (with newest date from 1.)
+3. For each item in entries, add the XML entry along with the
+ content as generated by `mandoc(1)` with the `-O` fragment option.
+ This ensures the "notification" has the full post -- users
+ never even need to visit the site!
+4. End by printing the footer of the XML
+
+And that's it! The only real trick was to use
+[CDATA sections](https://en.wikipedia.org/wiki/CDATA) around the entry
+content in the XML to escape the HTML tags.
+
+And of course, like everything else in this blog, it rebuilds on
+`git-push` via a call to `make(1)`.
+
+## See Also
+
+- [My Atom feed](https://alexkarle.com/atom.xml)
+- [Wiki page on Atom](https://en.wikipedia.org/wiki/Atom_(Web_standard%29)
+- [Atom RFC](https://tools.ietf.org/html/rfc4287)
+- [Related advocacy](https://atthis.link/blog/2021/rss.html)
+
+[Back to blog](/blog)
diff --git a/www/blog/use-git.txt b/www/blog/use-git.txt
@@ -0,0 +1,102 @@
+# Non-standard uses for `git(1)`
+
+_Published: November 7, 2021_
+
+In this post, I'm not going to teach you how to use
+[`git(1)`](https://git-scm.org). Instead, I wanted to write a
+quick post to encourage you to use git for non-conventional use
+cases (i.e. things other than source code).
+
+If perchance you're not familiar with git, there's a ton of good
+documentation out there. I'd recommend starting with the official
+and free [Pro Git](https://git-scm.com/book/en/v2). Also, as a PSA,
+just know that git stores whole snapshots and NOT diffs.
+
+## Background
+
+Git is a distributed version control system, and this is a
+beautiful thing. I feel it's often lost on us, given that we use
+it most frequently on centralized forges for team collaboration
+(GitHub, GitLab, etc).
+
+Git being distributed means you can:
+
+1. Use it offline (your copy is "first class")
+2. Mirror it to as many places as you want
+
+In other words, git can be used without any dependence on a third-
+party service or company and with complete ownership of private
+data. Forges (and I recommend [https://sourcehut.org]) are a great
+place to backup your code and collaborate, but you don't have to
+use a forge to use git as a futureproof way to do what it does
+best: version your files.
+
+## Story Time
+
+When I started my first job in tech, I found that it was a good
+habit to take personal notes. It was incredibly useful to quickly
+reference obscure CLI commands or system knowledge gained from
+pairing. These were things that were too small or personal to make
+it into standard documentation but invaluable to have on hand.
+
+My first solution was shoving them all into a directory called
+~/notes as plaintext files. They were easy to write and reference,
+and it was simple to back them up by copying the directory to
+another drive nightly.
+
+Over time, the `cp -a` trick broke down:
+
+- Files deleted in the source prevailed in the backup
+- Changes more than a day old were lost!
+
+Around the same time, I started getting more familiar with git, and
+it finally occurred to me: I could use git and still keep these
+notes private!
+
+Git can clone/push/pull across filesystems, so in the matter of
+minutes I solved both of my issues with just:
+
+ # Set up the backup mirror
+ $ git init --bare /backup/drive/notes.git
+
+ # Put it to use!
+ $ cd ~/notes
+ $ git init && git add . && git commit -m "import"
+ $ git remote add origin /backup/drive/notes.git
+ $ git push -u origin main
+
+If you don't have a backup drive mounted, it's equally good (or
+better) to make the remote a repo accessed over SSH:
+
+ # On the remote host
+ user@example.com~$ git init --bare ~/notes.git
+
+ # On the local host
+ $ git remote add origin user@example.com:notes.git
+
+## Going Further
+
+These days, I shudder at the thought of any important plaintext on
+my system that's not version-controlled somewhere. Too many hours
+are spent writing these little files, and it's so easy to version
+them, why risk losing any of that history?
+
+Aside from my private notes, I version:
+
+- System config files from /etc
+- Personal config files (dotfiles)
+- My passwords (via [`pass(1)`](https://passwordstore.org))
+- A small set of personal patches for FOSS projects I have yet to
+ polish and upstream (a-la ports-system)
+- My resume (admittedly still a DOCX from college, but versioning
+ has really helped)
+
+In conclusion, my advice to anyone writing anything of importance:
+just use `git(1)`!
+
+## See Also
+
+- [Commits are snapshots, not diffs](https://github.blog/2020-12-17-commits-are-snapshots-not-diffs/),
+ by Derrick Stolee
+
+[Back to blog](/blog)
diff --git a/www/footer.html b/www/footer.html
@@ -0,0 +1,5 @@
+<footer>
+ © 2019-2021 Alex Karle | <a href="/">Home</a> | <a href="/license.html">License</a>
+</footer>
+</body>
+</html>
diff --git a/www/header.html b/www/header.html
@@ -0,0 +1,32 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<!-- Inspired by https://www.swyx.io/css-100-bytes/ -->
+<style>
+html {
+ max-width: 70ch;
+ padding: 3em 1em;
+ margin: auto;
+ font-size: 1em;
+ font-family: sans-serif;
+}
+footer {
+ margin-top: 50px;
+ font-size: .8em;
+}
+code { font-family: consolas, courier, monospace; }
+h1 { font-size: 1.5em; }
+h2 { font-size: 1.2em; }
+h3 { font-size: 1.1em; }
+blockquote, pre {
+ background: #f2f2f2;
+ overflow: auto;
+ padding: 10px;
+ border: 2px solid black;
+}
+</style>
+<title>alexkarle.com</title>
+</head>
+<body>
diff --git a/www/index.txt b/www/index.txt
@@ -0,0 +1,49 @@
+# Welcome
+
+## About Me
+
+Hi! I'm Alex. I'm a software engineer living near Boston, MA.
+My current technical interests include operating systems,
+developer tooling, and small internet protocols like
+[Gopher](/blog/burrowing.html), but I'm constantly learning new
+things that I get excited about. Occasionally, I might write
+about it here on my [blog](/blog).
+
+Outside of tech, I enjoy playing music, hiking, and a good board
+game shared among friends.
+
+## About This Site
+
+This site is an ever-changing hobby project where I use the
+markup and build system as an excuse to learn and/or build new
+tools.
+
+In 2020, I [rewrote the site](/blog/my-old-man.html) as a series
+of man-pages in [`mdoc(7)`](https://man.openbsd.org/mdoc.7),
+writing new blog posts in the language and developing a toolchain
+to [support feeds](/blog/use-feeds.html), [text-only versions](/blog/text-only.html),
+and eventually a [gopher mirror](/blog/burrowing.html).
+
+At the end of 2021, I really wanted a lower-friction medium to
+blog on (akin to the plaintext I was writing on my
+[phlog](gopher://alexkarle.com/1/phlog)). Looking to keep the
+site buildable by base OpenBSD as a
+[creative limitation](/blog/creative-coding.html),
+I took the opportunity to write my own
+lightweight markup parser, [`nihdoc`](https://git.sr.ht/~akarle/nihdoc).
+[Stay tuned](/atom.xml) for more!
+
+## Projects Found Here
+
+- [yet another weblog](/blog): Thoughts on tech and life
+- [euchre.live](https://euchre.live): A Euchre web-app for my family
+- [jam-tuesday](/jam-tuesday): An archive of my jam setlists
+- [uses](/uses.html): Software and hardware that I use
+- [gopher://alexkarle.com]: my gopherhole -- phlog, notes & more!
+- [https://git.alexkarle.com]: A personal git server
+
+## Contact / Elsewhere
+
+- Email: _contact AT this-domain_
+- IRC: `akarle` on [libera.chat](https://libera.chat)
+- sourcehut: [`~akarle`](https://sr.ht/~akarle)
diff --git a/jam-tuesday/2021-03-09 b/www/jam-tuesday/2021-03-09
diff --git a/jam-tuesday/2021-03-16 b/www/jam-tuesday/2021-03-16
diff --git a/jam-tuesday/2021-03-23 b/www/jam-tuesday/2021-03-23
diff --git a/jam-tuesday/2021-03-30 b/www/jam-tuesday/2021-03-30
diff --git a/jam-tuesday/2021-04-06 b/www/jam-tuesday/2021-04-06
diff --git a/jam-tuesday/2021-04-13 b/www/jam-tuesday/2021-04-13
diff --git a/jam-tuesday/2021-04-20 b/www/jam-tuesday/2021-04-20
diff --git a/jam-tuesday/2021-04-27 b/www/jam-tuesday/2021-04-27
diff --git a/jam-tuesday/2021-05-04 b/www/jam-tuesday/2021-05-04
diff --git a/jam-tuesday/2021-05-18 b/www/jam-tuesday/2021-05-18
diff --git a/jam-tuesday/2021-05-25 b/www/jam-tuesday/2021-05-25
diff --git a/jam-tuesday/2021-06-01 b/www/jam-tuesday/2021-06-01
diff --git a/jam-tuesday/2021-06-08 b/www/jam-tuesday/2021-06-08
diff --git a/jam-tuesday/2021-06-15 b/www/jam-tuesday/2021-06-15
diff --git a/jam-tuesday/2021-06-22 b/www/jam-tuesday/2021-06-22
diff --git a/jam-tuesday/2021-07-06 b/www/jam-tuesday/2021-07-06
diff --git a/jam-tuesday/2021-07-13 b/www/jam-tuesday/2021-07-13
diff --git a/jam-tuesday/2021-07-20 b/www/jam-tuesday/2021-07-20
diff --git a/jam-tuesday/2021-07-27 b/www/jam-tuesday/2021-07-27
diff --git a/www/jam-tuesday/index.html b/www/jam-tuesday/index.html
@@ -0,0 +1,293 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+<meta charset="utf-8"/>
+<meta name="viewport" content="width=device-width,initial-scale=1">
+<!-- Inspired by https://www.swyx.io/css-100-bytes/ -->
+<style>
+html {
+ max-width: 70ch;
+ padding: 3em 1em;
+ margin: auto;
+ font-size: 1em;
+ font-family: sans-serif;
+}
+footer {
+ margin-top: 50px;
+ font-size: .8em;
+}
+code { font-family: consolas, courier, monospace; }
+h1 { font-size: 1.5em; }
+h2 { font-size: 1.2em; }
+h3 { font-size: 1.1em; }
+blockquote, code pre {
+ background: #f2f2f2;
+ overflow: auto;
+ padding: 10px;
+ border: 2px solid black;
+}
+.jam-artists tr:nth-child(even) {
+ background-color: #e3e3e3;
+}
+td.jam-artists, th.jam-artists, table.jam-artists {
+ border: 1px solid black;
+}
+</style>
+<title>Jam Tuesday Archive</title>
+</head>
+<body>
+<small><code><a href="/">/home/alex</a> / <a href="/jam-tuesday">jam-tuesday</a></code></small>
+<h1>Jam Tuesday Archive</h1>
+<h2>About</h2>
+<p>
+From about October 2020 up until August 2021, my brother Matt and I
+got together every Tuesday evening to play music. It started as a
+way to stay sane during the COVID quarantine, but it quickly became
+a tradition and a highlight of the week. No matter how stressful
+work was, or what was going on in the outside world, we could leave
+it all behind as we played some of our favorite tunes.
+</p>
+<p>
+At some point (woefully late), I realized it would be fun to start
+cataloging what we played.
+</p>
+<p>
+This archive includes the setlists and some play stats.
+</p>
+<p>
+There are no audio recordings (at least publicly), but there's a
+stray note here and there to "set the scene".
+</p>
+<p>
+The setlist notation is hopefully pretty straightforward. Unless
+otherwise noted, I'm on guitar and Matt's on keys (and if only one
+instrument is specified, it's me switching to it). We both
+(attempt to) sing. Sometimes we even harmonize :)
+</p>
+<h2>Stats</h2>
+<h3>Play Stats:</h3>
+<ul>
+<li> 19 Jam Sessions</li>
+<li> 330 Songs Total</li>
+<li> 159 Unique Songs</li>
+<li> 87 Unique Artists</li>
+</ul>
+<h3>Top 10 Artists (Frequency, Name):</h3>
+<ul>
+<li> 40 The Front Bottoms</li>
+<li> 37 Peach Pit</li>
+<li> 29 Manchester Orchestra</li>
+<li> 16 Vulfpeck</li>
+<li> 16 Dr. Dog</li>
+<li> 15 The Dear Hunter</li>
+<li> 10 Atta Boy</li>
+<li> 9 Cage The Elephant</li>
+<li> 7 Lake Street Dive</li>
+<li> 7 Her's</li>
+</ul>
+<h3>Top 10 Songs (Frequency, Name):</h3>
+<ul>
+<li> 12 Twin Size Mattress, The Front Bottoms</li>
+<li> 11 Rhode Island, The Front Bottoms</li>
+<li> 11 Alrighty Aphrodite, Peach Pit</li>
+<li> 10 Shadow People, Dr. Dog</li>
+<li> 10 Brian's Movie, Peach Pit</li>
+<li> 8 The Beers, The Front Bottoms</li>
+<li> 8 Jack and Blow, Atta Boy</li>
+<li> 6 That I Miss You, Vansire</li>
+<li> 6 Lauren, Men I Trust</li>
+<li> 6 Drop the Guillotine, Peach Pit</li>
+</ul>
+<h2>Setlists</h2>
+Updated weekly:
+<ul>
+<li><a href="/jam-tuesday/2021-03-09">2021-03-09</a></li>
+<li><a href="/jam-tuesday/2021-03-16">2021-03-16</a></li>
+<li><a href="/jam-tuesday/2021-03-23">2021-03-23</a></li>
+<li><a href="/jam-tuesday/2021-03-30">2021-03-30</a></li>
+<li><a href="/jam-tuesday/2021-04-06">2021-04-06</a></li>
+<li><a href="/jam-tuesday/2021-04-13">2021-04-13</a></li>
+<li><a href="/jam-tuesday/2021-04-20">2021-04-20</a></li>
+<li><a href="/jam-tuesday/2021-04-27">2021-04-27</a></li>
+<li><a href="/jam-tuesday/2021-05-04">2021-05-04</a></li>
+<li><a href="/jam-tuesday/2021-05-18">2021-05-18</a></li>
+<li><a href="/jam-tuesday/2021-05-25">2021-05-25</a></li>
+<li><a href="/jam-tuesday/2021-06-01">2021-06-01</a></li>
+<li><a href="/jam-tuesday/2021-06-08">2021-06-08</a></li>
+<li><a href="/jam-tuesday/2021-06-15">2021-06-15</a></li>
+<li><a href="/jam-tuesday/2021-06-22">2021-06-22</a></li>
+<li><a href="/jam-tuesday/2021-07-06">2021-07-06</a></li>
+<li><a href="/jam-tuesday/2021-07-13">2021-07-13</a></li>
+<li><a href="/jam-tuesday/2021-07-20">2021-07-20</a></li>
+<li><a href="/jam-tuesday/2021-07-27">2021-07-27</a></li>
+</ul>
+<h2>All Songs, by Artist</h2>
+<table class="jam-artists">
+<tr><th>Artist</th><th>Song</th><th>Plays</th></tr>
+<tr><td>311</td><td>Amber</td><td>1</td></tr>
+<tr><td>A Great Big Pile Of Leaves</td><td>Alligator Bop</td><td>1</td></tr>
+<tr><td>A Tribe Called Quest</td><td>Can I Kick It?</td><td>1</td></tr>
+<tr><td>Anderson .Paak</td><td>Make It Better</td><td>1</td></tr>
+<tr><td>Anderson .Paak & Bruno Mars</td><td>Leave the Door Open</td><td>1</td></tr>
+<tr><td>Atta Boy</td><td>Jack and Blow</td><td>8</td></tr>
+<tr><td></td><td>Walden Pond</td><td>2</td></tr>
+<tr><td>Bad Books</td><td>Baby Shoes</td><td>1</td></tr>
+<tr><td></td><td>Forest Whitaker</td><td>1</td></tr>
+<tr><td></td><td>It Never Stops</td><td>1</td></tr>
+<tr><td></td><td>The After Party</td><td>2</td></tr>
+<tr><td></td><td>You Wouldn't Have To Ask</td><td>1</td></tr>
+<tr><td>Beck</td><td>Loser</td><td>1</td></tr>
+<tr><td>Cage The Elephant</td><td>Cigarette Daydreams</td><td>6</td></tr>
+<tr><td></td><td>Shake Me Down</td><td>1</td></tr>
+<tr><td></td><td>Telescope</td><td>1</td></tr>
+<tr><td></td><td>Trouble</td><td>1</td></tr>
+<tr><td>Cake</td><td>Comfort Eagle</td><td>1</td></tr>
+<tr><td>Carpenters</td><td>Close To You</td><td>1</td></tr>
+<tr><td>Carrie Underwood</td><td>Before He Cheats</td><td>1</td></tr>
+<tr><td>Daniel Caesar</td><td>Japanese Denim</td><td>1</td></tr>
+<tr><td>Darwin Deez</td><td>Radar Detector</td><td>2</td></tr>
+<tr><td>Death Cab For Cutie</td><td>I Will Posess Your Heart</td><td>1</td></tr>
+<tr><td>Dojo Cat</td><td>Say So</td><td>1</td></tr>
+<tr><td>Dr. Dog</td><td>Nellie</td><td>1</td></tr>
+<tr><td></td><td>Shadow People</td><td>10</td></tr>
+<tr><td></td><td>Stranger</td><td>2</td></tr>
+<tr><td></td><td>The Beers/Shadow People</td><td>1</td></tr>
+<tr><td></td><td>The Breeze</td><td>1</td></tr>
+<tr><td></td><td>Twin Size/Shadow People/Beers</td><td>1</td></tr>
+<tr><td>Eurythmics</td><td>Sweet Dreams</td><td>1</td></tr>
+<tr><td>Eve 6</td><td>Inside Out</td><td>1</td></tr>
+<tr><td>Father John Misty</td><td>Real Love Baby</td><td>4</td></tr>
+<tr><td>Fleet Foxes</td><td>White Winter Hymnal</td><td>1</td></tr>
+<tr><td>Foo Fighters</td><td>Learn To Fly</td><td>1</td></tr>
+<tr><td></td><td>The Pretender</td><td>1</td></tr>
+<tr><td>Goo Goo Dolls</td><td>Iris</td><td>1</td></tr>
+<tr><td>Gorillaz</td><td>Feel Good Inc.</td><td>1</td></tr>
+<tr><td>Harvey Danger</td><td>Flagpole Sitta</td><td>1</td></tr>
+<tr><td>Her's</td><td>Blue Lips</td><td>6</td></tr>
+<tr><td></td><td>Cool With You</td><td>1</td></tr>
+<tr><td>Herbie Hancock</td><td>Chameleon</td><td>3</td></tr>
+<tr><td>Jay Som</td><td>Baybee</td><td>1</td></tr>
+<tr><td>Jimmy Eat World</td><td>The Middle</td><td>1</td></tr>
+<tr><td>John Mayer</td><td>Moving On and Getting Over</td><td>1</td></tr>
+<tr><td></td><td>No Such Thing</td><td>1</td></tr>
+<tr><td>Joyce Manor</td><td>Last You Heard of Me</td><td>1</td></tr>
+<tr><td>Kanye West</td><td>Golddigger</td><td>1</td></tr>
+<tr><td>Kate Bollinger</td><td>I Don't Wanna Lose</td><td>1</td></tr>
+<tr><td>Kevin Devine</td><td>Cotton Crush</td><td>1</td></tr>
+<tr><td></td><td>I Could Be With Anyone</td><td>1</td></tr>
+<tr><td>Khalid</td><td>Talk</td><td>1</td></tr>
+<tr><td>Lake Street Dive</td><td>Call Off Your Dogs</td><td>1</td></tr>
+<tr><td></td><td>Hello Goodbye</td><td>1</td></tr>
+<tr><td></td><td>Hypotheticals</td><td>5</td></tr>
+<tr><td>Lenny Kravitz</td><td>Fly Away</td><td>1</td></tr>
+<tr><td>Mac DeMarco</td><td>My Old Man</td><td>2</td></tr>
+<tr><td>Mac Miller</td><td>What's The Use</td><td>3</td></tr>
+<tr><td>Manchester Orchestra</td><td>Bed Head</td><td>3</td></tr>
+<tr><td></td><td>Everything To Nothing</td><td>1</td></tr>
+<tr><td></td><td>I Can Barely Breathe</td><td>1</td></tr>
+<tr><td></td><td>I Can Feel A Hot One</td><td>1</td></tr>
+<tr><td></td><td>I've Got Friends</td><td>4</td></tr>
+<tr><td></td><td>Keel Timing</td><td>3</td></tr>
+<tr><td></td><td>Pride</td><td>4</td></tr>
+<tr><td></td><td>Shake It Out</td><td>5</td></tr>
+<tr><td></td><td>Telepath</td><td>1</td></tr>
+<tr><td></td><td>The Only One</td><td>4</td></tr>
+<tr><td></td><td>Tony The Tiger</td><td>1</td></tr>
+<tr><td></td><td>Virgin</td><td>1</td></tr>
+<tr><td>Matt</td><td>Original</td><td>4</td></tr>
+<tr><td>Matt and Alex</td><td>Original</td><td>5</td></tr>
+<tr><td>Men I Trust</td><td>Lauren</td><td>6</td></tr>
+<tr><td>Michael Jackson</td><td>Beat It</td><td>1</td></tr>
+<tr><td></td><td>Billie Jean</td><td>1</td></tr>
+<tr><td>Modern Baseball</td><td>Tears Over Beers</td><td>2</td></tr>
+<tr><td>Modest Mouse</td><td>Float On</td><td>2</td></tr>
+<tr><td>Natalie Imbruglia</td><td>Torn</td><td>1</td></tr>
+<tr><td>No Doubt</td><td>Don't Speak</td><td>1</td></tr>
+<tr><td>Omar Apollo</td><td>The Two of Us</td><td>3</td></tr>
+<tr><td>OutKast</td><td>Ms Jackson</td><td>1</td></tr>
+<tr><td>Paper Kites</td><td>Bloom</td><td>1</td></tr>
+<tr><td>Parcels</td><td>Tieduprightnow</td><td>1</td></tr>
+<tr><td>Peach Pit</td><td>Alrighty Aphrodite</td><td>11</td></tr>
+<tr><td></td><td>Black Licorice</td><td>1</td></tr>
+<tr><td></td><td>Brian's Movie</td><td>10</td></tr>
+<tr><td></td><td>Chagu's Sideturn</td><td>2</td></tr>
+<tr><td></td><td>Drop the Guillotine</td><td>6</td></tr>
+<tr><td></td><td>Peach Pit</td><td>1</td></tr>
+<tr><td></td><td>Shampoo Bottles</td><td>2</td></tr>
+<tr><td></td><td>Techno Show</td><td>3</td></tr>
+<tr><td></td><td>Tommy's Party</td><td>1</td></tr>
+<tr><td>Phish</td><td>Character Zero</td><td>3</td></tr>
+<tr><td>Portugal. The Man</td><td>Feel It Still</td><td>1</td></tr>
+<tr><td>Prawn</td><td>Why You Always Leave A Note</td><td>1</td></tr>
+<tr><td>Radiohead</td><td>Creep</td><td>2</td></tr>
+<tr><td>Rage Against The Machine</td><td>Killing in the Name</td><td>1</td></tr>
+<tr><td>Red Hot Chili Peppers</td><td>Can't Stop</td><td>4</td></tr>
+<tr><td>Ripe</td><td>Caralee</td><td>1</td></tr>
+<tr><td></td><td>Goon Squad</td><td>1</td></tr>
+<tr><td></td><td>Pretty Dirty</td><td>1</td></tr>
+<tr><td></td><td>Talk to the Moon</td><td>1</td></tr>
+<tr><td>Robbie Hunter Band</td><td>Que Paso?</td><td>1</td></tr>
+<tr><td>Sammy Rae</td><td>Jackie Onassis</td><td>1</td></tr>
+<tr><td></td><td>Kick It To Me</td><td>2</td></tr>
+<tr><td>Santana</td><td>Smooth</td><td>1</td></tr>
+<tr><td>Stone Temple Pilots</td><td>Interstate Love Song</td><td>2</td></tr>
+<tr><td>Sublime</td><td>Doin Time</td><td>1</td></tr>
+<tr><td>Sugar Ray</td><td>Every Morning</td><td>2</td></tr>
+<tr><td>Sure Sure</td><td>Good Thing</td><td>1</td></tr>
+<tr><td>Tame Impala</td><td>The Less I Know The Better</td><td>2</td></tr>
+<tr><td>The Beatles</td><td>I've Just Seen A Face</td><td>1</td></tr>
+<tr><td></td><td>With a Little Help From My Friends</td><td>1</td></tr>
+<tr><td>The Black Keys</td><td>Tighten Up</td><td>1</td></tr>
+<tr><td>The Cars</td><td>Just What I Needed</td><td>1</td></tr>
+<tr><td>The Dear Hunter</td><td>A Sua Voz</td><td>3</td></tr>
+<tr><td></td><td>Black Sandy Beaches</td><td>1</td></tr>
+<tr><td></td><td>Deny It All</td><td>1</td></tr>
+<tr><td></td><td>Girl</td><td>1</td></tr>
+<tr><td></td><td>Misplaced Devotion</td><td>1</td></tr>
+<tr><td></td><td>Progress/Therma</td><td>2</td></tr>
+<tr><td></td><td>Red Hands</td><td>4</td></tr>
+<tr><td></td><td>The Moon/Awake</td><td>1</td></tr>
+<tr><td></td><td>What it Means to Be Alone</td><td>1</td></tr>
+<tr><td>The Eagles</td><td>Hotel California</td><td>1</td></tr>
+<tr><td>The Front Bottoms</td><td>Cough It Out</td><td>1</td></tr>
+<tr><td></td><td>Flashlight</td><td>4</td></tr>
+<tr><td></td><td>Jim Bogart</td><td>1</td></tr>
+<tr><td></td><td>Legit Tattoo Gun</td><td>2</td></tr>
+<tr><td></td><td>Rhode Island</td><td>11</td></tr>
+<tr><td></td><td>The Beers</td><td>8</td></tr>
+<tr><td></td><td>Twin Size Mattress</td><td>12</td></tr>
+<tr><td></td><td>West Virginia</td><td>1</td></tr>
+<tr><td>The Head and The Heart</td><td>Honeybee</td><td>1</td></tr>
+<tr><td></td><td>Lost In My Mind</td><td>2</td></tr>
+<tr><td></td><td>Rivers and Roads</td><td>2</td></tr>
+<tr><td>The Raconteurs</td><td>Steady As She Goes</td><td>1</td></tr>
+<tr><td>The White Stripes</td><td>We're Going To Be Friends</td><td>1</td></tr>
+<tr><td>Theo Katzman</td><td>You Could Be President</td><td>1</td></tr>
+<tr><td>Third Eye Blind</td><td>Semi Charmed Life</td><td>1</td></tr>
+<tr><td>Three Doors Down</td><td>Kryptonite</td><td>1</td></tr>
+<tr><td>Tonic</td><td>If You Could Only See</td><td>1</td></tr>
+<tr><td>Twiddle</td><td>When it Rains it Poors</td><td>1</td></tr>
+<tr><td>USERx</td><td>Headsick</td><td>1</td></tr>
+<tr><td>Vampire Weekend</td><td>Flower Moon</td><td>2</td></tr>
+<tr><td></td><td>Sunflower</td><td>4</td></tr>
+<tr><td>Vansire</td><td>That I Miss You</td><td>6</td></tr>
+<tr><td>Vulfpeck</td><td>1612</td><td>2</td></tr>
+<tr><td></td><td>Animal Spirits</td><td>1</td></tr>
+<tr><td></td><td>Aunt Leslie</td><td>3</td></tr>
+<tr><td></td><td>Baby I Don't Know Oh Oh</td><td>1</td></tr>
+<tr><td></td><td>Back Pocket</td><td>2</td></tr>
+<tr><td></td><td>LAX</td><td>1</td></tr>
+<tr><td></td><td>Love is a Beautiful Thing</td><td>1</td></tr>
+<tr><td></td><td>Outro</td><td>1</td></tr>
+<tr><td></td><td>Wait For The Moment</td><td>4</td></tr>
+<tr><td>Weezer</td><td>Buddy Holly</td><td>2</td></tr>
+<tr><td></td><td>If You're Wondering If I Want You To</td><td>1</td></tr>
+<tr><td></td><td>The World Has Turned and Left Me Here</td><td>1</td></tr>
+</table>
+<br><br>
+<p style="font-size: 0.7em">Last Updated: Tue Dec 28 16:56:08 EST 2021</p>
+<p class="foot-license">
+© 2019-2021 Alex Karle | <a href="/">Home</a> | <a href="/license.html">License</a>
+</p>
+</body>
+</html>
diff --git a/www/license.txt b/www/license.txt
@@ -0,0 +1,9 @@
+# License
+
+Except where otherwise noted, all content on this site is
+licensed under a Creative Commons Attribution 4.0 license
+[(CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/).
+
+Any code snippets, including the
+[code used to build this site](https://sr.ht/~akarle/alexkarle.com)
+are licensed under a [MIT license](/LICENSE).
diff --git a/www/uses.txt b/www/uses.txt
@@ -0,0 +1,104 @@
+# Software and hardware that I use
+
+I really enjoy a good "uses" post. I think the first I ever
+stumbled across was [Wes Bos'](https://wesbos.com/uses/), back
+when I was learning web-development. As someone fascinated by
+developer tooling, I loved hearing what other programmers use in
+their day-to-day lives.
+
+I try to keep this page up to date, both for my future nostalgia as
+well as for anyone else out there who enjoys the "genre".
+
+## Software
+
+### Editor
+
+I got hooked on [`vim(1)`](https://vim.org) mid-college (~2017)
+and never looked back. It's first on this list (with a dedicated
+section!) because it was the "gateway program" that got me
+interested in developer tooling in the first place! If not my
+most important tool, it's definitely the most impactful.
+
+Other editors I use:
+
+- [`vi(1)`](https://man.openbsd.org/vi.1) for system configs
+ (super snappy on OpenBSD)
+- [`ed(1)`](https://man.openbsd.org/ed.1) for fun and for slow/serial
+ connections (yes, really!)
+
+I try emacs every once and a while because I think Lisp is awesome
+(and far superior to VimScript), but I don't really dig the "run
+everything in emacs" approach.
+
+### Operating System
+
+I've been passionate about running free and open source (FOSS)
+operating systems since ~2019 when I first started using Linux
+seriously at work. At some point in ~2020, I discovered OpenBSD
+and slowly started putting it on all of my personal machines. I'm
+currently running:
+
+- [OpenBSD](https://openbsd.org) for my laptop, desktop, server
+ ([hosting this site](/blog/self-hosted.html)), and home router/firewall
+- [Arch Linux](https://archlinux.org) for work (needed a cutting
+ edge kernel for newer work laptop)
+
+In the past I've also used Alpine Linux on my laptop and Debian on
+my desktop.
+
+## Other Tools
+
+I'm a huge fan of command line tools for their composability and
+keyboard-centric UI. Some of my favorites include:
+
+- [`git(1)`](https://git-scm.com) for all things plaintext: notes, code,
+ config backups, etc
+- [`tmux(1)`](https://man.openbsd.org/tmux.1) for terminal scrollback,
+ searching, copy/paste buffers, multiplexing, persistent sessions over
+ dropped [`ssh(1)`](https://man.openbsd.org/ssh.1) connections...
+ really a necessity!
+- [`mutt(1)`](https://mutt.org) for personal email (great for mailing lists!)
+- [`pass(1)`](https://passwordstore.org) for password/secret management
+- [`sh(1)`](https://man.openbsd.org/sh.1) for glueing it all together, of course!
+
+## Hardware
+
+### Keyboard
+
+After years of mushy laptop keyboards, I discovered mechanical
+keyboards through a coworker and I've been clicking and clacking
+happily ever since!
+
+I started off with an [Ultimate Hacking Keyboard](https://uhk.io)
+with Kailh browns (had to be quiet in a shared office), but I've
+been using a [Keyboardio Atreus](https://shop.keyboard.io/pages/atreus)
+for about a year. I switched in a (successful!) attempt to
+reduce finger movement and strain. Plus, I'm a remote worker
+now, and I get to clack away at Kailh white switches, which is
+awesome.
+
+### Laptop
+
+When I started really getting into Linux at work and home ~2019, I
+installed Arch on my old macbook and suffered at the hands of
+NVIDIA and poor hardware support until I ditched my macbook for a
+[ThinkPad X220](https://www.thinkwiki.org/wiki/Category:X220)
+(2011, i7, 2GB RAM) that I bought used for ~$130 off Ebay. A
+simple upgrade to a SSD and it runs great!
+
+I use the laptop for casual browsing and hobby coding (I try to
+ensure my hobby projects all run on old hardware!), but its CPU age
+really shows on big websites or compilations.
+
+### Desktop
+
+I built my first desktop (a long standing nerd goal of mine) at the
+start of the COVID-19 pandemic in 2020 when it became clear I'd be
+working from home and my 2GB of laptop RAM wouldn't cut it.
+
+I tried (and failed) to keep the parts entirely FOSS-friendly, but
+I ended up getting a GPU that needed the AMDGPU firmware blobs
+(hard to find a fully free graphics card these days it seems).
+With a high-end CPU (AMD Ryzen 7 3700X) but a low-end GPU (Radeon
+RX 560), it was a reasonable price. And with 16GB of RAM, it
+handles my work environment well.