Robert D. French

About Me
E-Mail
GitHub
LinkedIn
Signal
Atom Feed
blog(8) System Manager's Manual blog(8)

This is actually a pretty slick way to manage a blog. You can preview it live from inside your terminal, and publish it to httpd(8) as flat files.

You can get a feeling for this kind of writing just by compiling an existing mdoc(7) file, such as a man page, to html. Just run

$ mandoc -T html `man -w ls` > ls.html

This will generate a web page with the content of the documentation for the ls(1) command. (The magic incantation here is man -w ls, which will return the path to ls's man page: /usr/share/man/man1/ls.1.)

The default formatting leaves a lot to be desired though. Fortunately, mandoc(1) lets you inject a CSS stylesheet into the web page it produces. If you are not a designer, I recommend starting with the stylesheet at https://man.openbsd.org/mandoc.css since it already contains styles for mandoc's output:

$ ftp https://man.openbsd.org/mandoc.css
$ mandoc -T html -O style=mandoc.css `man -w ls` > ls.html

If you are not familiar with OpenBSD's ftp(1) command, think of it like a more compact version of curl: it's just something you use to download files, even if you are not using (count your blessings) an actual ftp server.

mdoc(7) was not strictly designing for blogging, so you'll need to get a little creative. Here is the scaffolding I use for new blog entries:

.Dd 2025-03-27
.Dt blog 8
.Os "Robert D. French"
.
.Sh "New blog post!"
This is the first line of my new blog post.

I have hijacked the .Os macro to insert my name. Otherwise it will just print "OpenBSD", which doesn't tell anyone anything. You may wish to insert your blog title, or a copyright notice here.

I am also slightly abusing the .Sh tag as a title. In most manual pages, you'd instead do something like this:

.Sh TITLE
New man page!
.Pp
This is the first line of my new man page.

and, in fact, if you run mandoc -T lint on the scaffolding file I proposed, it will fuss at you for violating this tradition. That's okay! Machines don't have feelings.

The other hangup here is the .Dt macro. I landed on ‘blog’ as the document "title", mostly out of a lack of creativity. For the section number, you to pick from one of the following:

  • 1: General Commands Manual
  • 2: System Calls Manual
  • 3: Library Functions Manual
  • 3p: Perl Programmers Reference Guide
  • 4: Device Drivers Manual
  • 5: File Formats Manual
  • 6: Games Manual
  • 7: Miscellaneous Information Manual
  • 8: System Manager's Manual
  • 9: Kernel Developer's Manual

I landed on 8, ‘System Manager's Manual’ because I feel that reflects the spirit of this blog. If you don't like any of those options, you could use the () function of awk(1) to replace it with something you do like:

$ mandoc -Thtml blog.mdoc \
	| awk 'BEGIN {RS=""}; {print gensub(/Games[ \n]+Manual/, "Blog Title", 1)}'

This doozy of a one-liner makes a little more sense in context: unhelpfully, mandoc will generally print the manual title across two lines when it compiles your html page. This means that we can't use something easy like sed(1).

Absolutely no reason. Markdown, AsciiDoc, and reStructuredText are all better solutions. Markdown is so much better, in fact, that mandoc can generate it for you:

$ mandoc -Tmarkdown blog.mdoc
And anyway, can Markdown give you live rendering previews for a totally unrelated medium, like your terminal emulator? Just run man ./blog.mdoc to see a monochrome, hyperlink-free approximation of your blog without having to use a new-fangled "web browser".
2025-03-27 Robert D. French