Published: December 30, 2020
Update: As of December 2021, I've moved to a new markup format. For a glimpse at what the format discussed looks like, here's the original post.
Uh oh,
looks like,
I'm seeing more of my old man(1) in me
~ Mac DeMarco (added (1) by me)
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)
based site.
After pointing out that
I really did
rewrite my site in mdoc(7)
, you might be wondering why I would do this.
This blog post is intended to answer just that.
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.
I really enjoy a good 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.
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)
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.
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.
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.
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.