As brewdo (my tool for sandboxing package management tool Homebrew) expanded and gained more and more options, it became more important for me to document it in an easy-to-use way. Since it’s a command line tool, that meant a man page.
But while the tools for making classic man pages are powerful, they’re also, how shall I say it… historical? And definitely not things I use every day. Thankfully, there’s a modern option that gets me from zero to man page without having to think about skills I left in the dust long ago.
Man Pages 101
For those of you not familiar with man pages, it’s worth an quick explanation and exploration before you dive in. Man pages date back to the early days of Unix and, to this day, are the standard for online documentation in Unix-like systems such as OS X and Linux.
If you’re on one of those systems, open up a terminal and type man man to see the man page for the man program, your gateway to all the online documentation in man page form.
You can use man in this way to see man pages for lots of command-line software. Many users look for a man page first for command-line tools—so time spent on a man page is well-spent.
Getting up and Ronning
Ryan Tomayko’s Ronn is a fantastic, zero-fuss formatter that takes the ubiquitous Markdown format and establishes additional conventions to enable the creation of a rich man page. I use Markdown every day, from code review comments to READMEs to Stack Overflow Q&A, so I don’t have to switch mental gears to work on man pages.
Installing Ronn is quite simple—it’s available as a RubyGem named ronn. I installed my copy with gem install --user-install ronn, following the pattern I use with most RubyGem-based tools I use across all my projects. Generic installation instructions are part of the Ronn distribution.
Once Ronn is installed, it’s time to create your Ronn-based man page. You can create the entirety of this man page in any text editor; I use Vim.
You should follow a specific naming convention with the file you create—it’ll make processing your man page much easier later. For our example (a program called hello in section 1 of the manual), we’ll name our Ronn file hello.1.ronn.
Structuring our Man Page
Ronn man pages are structured similarly to standard Markdown documents. They start off with the top-level header, which contains the name of the program being documented and the manual section it’s in (both of which should match your filename), plus a short description.
hello(1) -- greets the world, or another arbitrary target ====
The remaining sections of the man page are broken up by second-level headers, titled (as is standard with man pages) in all caps. Man pages always have a synopsis section next that explains the syntax users need to use to use our program:
## SYNOPSIS `hello` [<target>]
Here, we’re using the standard Markdown backtick syntax for command text to represent the command name. The square brackets are convention for an optional argument, and Ronn will see the angle brackets surrounding target and format that text as a placeholder for a program argument.
A description section typically follows, which describes your program in free-form text. Note the use of the man page convention to refer to ourselves as hello(1) here—Ronn will format that appropriately and, in its HTML output, turn it into a link to another man page.
## DESCRIPTION hello(1) is a program that greets either - the entire world, if <target> is not supplied, or - an arbitrary person, group, or other target.
The Meat in the Middle
Having got the standard prerequisites out of the way, the middle of the man page is up to you. Many man pages will have an examples section. You can use standard Markdown code block indentation for your examples:
## EXAMPLES To greet the entire world (note: the world's reciprocal behavior is undefined): hello To greet the reader of this post and make them feel welcome: hello 'Spin reader'
A exit status (or, if you’re feeling particularly old-school, diagnostics) section is very helpful to scripters wanting to make use of your program from another program:
## DIAGNOSTICS Returns 0 on successful greeting.
If you want to refer to one section of your man page from another, Ronn has you covered here as well. You can use Markdown implicit links to go between sections like so:
hello(1) is incapable of failing because it's so darn cheery. See [DIAGNOSTICS].
Wrapping it Up
Man pages traditionally end with Author and See-Also sections to provide credit and contact information as well as references to other documentation. Ronn is smart enough to do the right thing yet again here, formatting email addresses between angle brackets as well as references to other man pages appropriately—and, again, will make nice links in the HTML output should you choose to use it.
You can also use standard Markdown link syntax to link to external resources:
## AUTHOR Matt Behrens <email@example.com> ## SEE ALSO goodbye(1) [Easy man page creation with Ronn](https://spin.atomicobject.com/2015/05/06/easy-man-page-creation-ronn)
Getting a Man Page
Now that all that’s done, you can generate your man page (and, optionally, HTML output):
Ronn will create hello.1 and hello.1.html. The former is your man page and can be installed into the appropriate directory on the man command’s search path (e.g. /usr/local/man/man1). The latter is HTML you can put anywhere the HTML version of your man page is useful.
I like to take this one step further by adding instructions to my project’s Makefile to build the man page (and not the HTML) for me:
RONN = ronn MANPAGE = hello.1 $(MANPAGE): $(MANPAGE).ronn $(RONN) -r $<
You can see this in action in the Makefile for brewdo. Since the man page is the first target, I simply need to type make before committing documentation changes. (I commit the man page because it’s a deliverable, ready to install in the target system without Ronn being installed.)
Ronn’s home page includes:
- The man page for ronn(1), detailing all the ways you can use Ronn
- The ronn-format(7) man page, documenting the formatting options available with Ronn
There’s also the Ronn on GitHub, including source for the ronn(1) and ronn-format(7) man pages.
And check out the Ronn source for the man page for brewdo(1).