Re: Learning man(7)
From: Zack Weinberg <hidden>
Date: 2025-05-23 16:22:45
[off topic for libc-alpha] On Sat, May 17, 2025, at 8:01 PM, G. Branden Robinson wrote:
[shameless promotion of (in part) my own work follows] I've tried hard over the past several years to make man(7) easy to acquire. I'm attaching a PDF of the groff_man_style(7) man page (rendered with the forthcoming groff 1.24), which attempts the oft- questioned objective of serving as both tutorial and a reference. I seldom receive feedback on it, which means either that it's flawless or no one reads it.
I regret to say that I think most people who attempt to read this document will give up on it after only a few sentences. It is densely written, presents its material in a sequence that doesn't make any sense to me, and frequently uses jargon that I only understand because I already know the essentials of the troff markup language. I suggest that you should look at the overall structure of the Texinfo manual (https://www.gnu.org/software/texinfo/manual/texinfo/html_node/), and reorganize your guide along similar lines. The Texinfo manual is not perfect, but it was written with a lot of care and attention put into organizing the material into a sequence that will make sense to someone who is brand new to writing documentation in a markup language. Avoid forward references to definitions of terms at almost any cost. Forward references to sections that will go into more detail on something that was just mentioned are often a good idea, but make sure enough detail was presented up front that a beginner knows enough to keep reading! Relegate information that most people don't need to know, such as the specifications of deprecated macros and the portability quirks of Solaris troff, to the very end. Whenever possible, avoid troff-specific jargon; for example, instead of talking about "input traps", which are a detail of how troff macros work internally, say something like .SH [heading-text] Set _heading-text_ as a section heading. If .SH appears by itself on a line, the next normal line of input is used as _heading-text_. Don't try to avoid repeating this language; write it out in full for every macro that has this property. In general, decompress your language; take the time to spell everything out rather than relying on words with precise definitions that readers might not already know, whether or not they are defined in the text. (Rudolf Flesch wrote two excellent books on how to do this well, *The Art of Readable Writing* and *The Art of Plain Talk*, which I recommend to everyone seeking to improve their technical writing.) Add lots and lots and lots of examples. For a concrete example of the kind of change I would suggest you make, take these sentences near the beginning: A roff document can contain control lines, which start with a dot (.) or neutral apostrophe ('). All other input lines are text lines to be formatted. A macro collects control and/or text lines to ease document composition. There is a _ton_ of implicit knowledge referenced by these sentences. Much of that knowledge does appear later in the document, but a reader who isn't already familiar with troff won't be able to get that far, because they need all that knowledge to continue reading! I would expand those sentences to all of this: The roff markup language is line-oriented; with a few exceptions, every construct consists of one or more whole input lines. As usual for Unix programs, all input lines, including the very last one, must be ended with the "newline" character, ASCII LF (U+000A); the "carriage return" character (U+000D) should not be used. Each input line of a roff document is either a _text line_ or a _control line_. Control lines start with either a dot (.) or a neutral apostrophe ('); the only difference is that control lines beginning with . sometimes force a line break in the output. Generally you should write all your control lines beginning with ., and then change dots to apostrophes only when you discover undesirable line breaks. Lines beginning with any other character are text lines. Most control lines invoke either a _macro_ or a primitive _request_, by naming the macro or request immediately after the . or the '. This will have some concrete effect on the typeset output, as we will explain throughout the rest of this guide. A control line that _doesn't_ invoke anything has no direct effect, but can still be useful; we will also discuss this more below. This is a text line. .SH \" This is a control line, invoking the SH macro. .br \" This is a control line, invoking the br request. . \" This is a control line that doesn't invoke anything. The distinction between macros and requests is usually not important unless you are writing your own "macro package." However, by convention, macros have UPPERCASE names, and primitive requests have lowercase names. Because roff is a very old markup language, the names are usually very short---one or two characters at most. (GNU groff supports longer names but other implementations do not.) Both macros and requests frequently take _arguments_, consisting of the rest of the text on the control line, after their name. For readability and ease of editing, control lines can be extended onto multiple physical input lines by putting a backslash (\, U+005C) at the very end of each input line but the last one. (This also works for text lines, but it is almost never _needed_ for text lines.) .SH Arguments to the SH macro: text of a section heading. .SS A very long subsection heading that was split onto \ two physical input lines. Backslash can also appear in the middle of a line, in which case it begins an _escape sequence_. One escape sequence already appeared in the first group of examples above: \", which begins a comment--the \" and everything after it on that input line are discarded and have no effect on the output. Thus, in those examples, the SH macro and the br request did not receive any arguments. Another escape sequence is \&, which inserts a "dummy character". It has no visible effect on the formatted output, but you can use it to begin a text line with either . or ': \&. This is a text line whose text begins with '.'. More escape sequences will be described below. For maximum portability, roff input should be restricted to ASCII; see the "Portability" section for precise details of what characters are permissible, and the "Special character escapes" section for how to typeset non-ASCII characters. GNU groff supports input in Unicode (by means of the preconv(1) helper program). Naturally, one can then remove *some* of this detail from later sections. However, keep in mind that a little bit of repetition helps to embed information in the reader's mind. I hope this is useful to you. zw