# 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##&# ' \ > $@ This looks crazy, but it's not too complex. First, know that `$<` is the source (the `.7` page), and `$@` is the target (the `.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 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 `/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)