9. Styling

.ig ## can be used to specify settings that are relevant only when Troff2page is used on a document, e.g., stylesheet changes. Troff2page uses the output-stream CSS to write out its default style information. The user can also append to this stream. E.g.,

    .ig ##
    CSS:write([[
        h1,h2,h3,h4,h5,h6 {
            color: #9b3d3d; /* terracotta pink */
        }
    ]])
    .##

This renders the section headers with a foreground color of terracotta pink4.

Troff2page makes available many CSS classes that you can modify in this manner to change the look of your web pages. For instance, the HTML element for the document title has class title. Here’s a way to get a more happening, Asciidoctor-like title:

    .ig ##
    CSS:write([[
      h1.title {
          color: #333333;
          padding-bottom: 10px;
          border-bottom: 1px solid #dddddf;
      }
    ]])
    .##

Of course, these CSS mods don’t affect the groff output, but they do affect the printed output if you choose to print from the browser! To prevent any CSS mods from leaking into the browser-mediated printout, wrap them inside @media screen.

Colophon

By default, Troff2page places a colophon at the bottom right of the first page. The colophon mentions: (1) the last-modification time of the document; and (2) the Troff2page version used for the conversion. Either or both can be suppressed via CSS.

To suppress the mention of Troff2page,

    .colophon .advertisement {
      display: none;
    }

To suppress the entire colophon,

    .colophon {
      display: none;
    }

Troff2page calculates the last-mod time by choosing the timestamp of the newest of the source documents that make up the document. Only user content is considered; macro and auxiliary files are not.

To specify a document timestamp without regard to the actual mod times of the files in it, use the -ms macros .ND or .DA. Troff2page doesn’t distinguish between them, but groff does. .ND is probably what you want for both typesetters. (groff doesn’t really have any notion of the last-mod date anyway: It simply uses the date that it was called on. I.e., last-creation-of-printed-output date.)

For web pages, note that if either macro is called with an argument, that argument is used as the last-mod date, overriding the value that Troff2page would have determined.

If no argument is given, the colophon doesn’t include the “Last modified” line at all, something that can also be accomplished via the CSS fragment:

    .colophon .lastmod {
      display: none;
    }

As a special case, for man pages, Troff2page (like groff -man) takes the third argument of the titling macro .TH as the last-mod date. If there isn’t a third argument, the colophon won’t mention any date.

Glyph substitution

CSS isn’t the only way to style your document: Interesting glyphs offer another approach. Troff2page, like groff, allows you to use UTF-8 characters, either directly or via escape sequences of the form \[uxxxx_yyyy...], where the xxxx and yyyy are hex numbers in uppercase. xxxx is the code point of the base glyph, and each optional _yyyy is a code point for a combining diacritic.

Thus U+00E9 LATIN SMALL LETTER E WITH ACUTE (é) can be entered (1) directly as é; (2) as the Unicode escape \[u00E9]; or (3) as the Unicode combining escape \[u0065_0301], because U+0065 is LATIN SMALL LETTER E and U+0301 is COMBINING ACUTE ACCENT.

The .char request is a convenient way to transliterate a character available in your text editor to something available in either your groff and/or browser font. E.g., the plain pilcrow or paraph character U+00B6 PILCROW SIGN (¶) is commonly available while text editing, because it’s 8-bit ascii. In contrast, the fancier U+2761 CURVED STEM PARAGRAPH SIGN ORNAMENT (❡) may not be present. To automatically transliterate the former to the latter:

    .char \[u00B6] \[u2761]

Usually, this works on the browser (because UTF-8 encoding is widespread), but fails for print, as the typical text font in groff does not have a glyph at code point U+2761. groff does have the glyph in its Zapf Dingbats (ZD) font but at a different code point, which you can snag using a further .char call:

    .if !\n[.troff2page] \{\
      .char \[u2761] \f(ZD\N'161'\fP
    .\}

Here’s a more elaborate use case: You may want to use U+2621 CAUTION SIGN and U+26A0 WARNING SIGN rather than the pedestrian “CAUTION” and “WARNING” for admonition titles.

                 

Unfortunately, while these usually work well on browsers, the fonts used by groff for printing almost always won’t recognize them. (You could use fallback fonts, but often they test groff’s capacity, and it’s not worth loading them only for a couple of exotic glyphs.) A more reasonable workaround is to conditionally translate special characters into their boring equivalents for print:

    .if !\n[.troff2page] \{\
    .  char \[u2621] \fBCAUTION\fP
    .  char \[u26A0] \fBWARNING\fP
    .\}

If you used color and sizing to jazz up the icons, and you don’t want these apply to the non-icon versions (or if you want to modify the latter in a different way), trivial admonition macros may be written that expand differently for HTML and print, e.g.,

    .de CAUTION
    .  if \n[.troff2page] \{\
    .    \M[yellow]\s+4\fB\[u2621]\fP\s0\M[]
    .  \}
    .  el \fBCAUTION\fP
    ..

    .de WARNING
    .  if \n[.troff2page] \{\
    .    \M[red]\m[white]\s+4\fB\[u26A0]\fP\s0\m[]\M[]
    .  \}
    .  el \fBWARNING\fP
    ..

Typing verbatim \ in displays

The display used above brings up another use-case for glyph translation, even when (and especially if) no exotic characters are desired. The display shows the backslash (\) character, which is also the default escape character for groff.

A display environment could be fenced by a pair of macros .EX/.EE defined as follows:

    .de EX
    .  LD
    .  ft C
    ..
    .
    .de EE
    .  DE
    ..

We could use the escape sequence \e in our input to stand for a backslash, but especially in an extended display containing verbatim code, we would like to input the backslash as-is and have groff and Troff2page temporarily suspend its escape effect. We could do this by having our .EX/.EE macros implicitly turn the escape character off when entering the display and back on when exiting it. The requests for these actions are .eo and .ec respectively:

    .de EX
    .  LD
    .  ft C
    .  eo
    ..
    .
    .de EE
    .  ec
    .  DE
    ..

We then use the macros .EX and .EE around the code text to display it, in monospace font and with the escape character temporarily disabled. (An improved version of these macros are provided in pca-verb.tmac.)

This works for short displays that are entirely within a page (we’re talking printed pages via groff now, not HTML pages). The various traps that spring into action when groff breaks at a page rely on the escape character being active, and these will start failing catastrophically when our display straddles a page boundary.

One way out is to force code displays to never cross a page boundary by using groff’s “keep” macros .KS or .KF or the keep versions of the display macros (e.g., .DS L rather than .LD). Please see the groff docs for more info about these macros. The problem then becomes what to do with large page-crossing displays. This is almost unavoidable in computer technical prose.

Unicode glyph substitution offers another way out. The Unicode characters U+29F9 BIG REVERSE SOLIDUS and U+FE68 SMALL REVERSE SOLIDUS are passable replacements for the regular backslash (U+005C REVERSE SOLIDUS). You can enter these substitute backslashes with text-editor macros fairly easily.5

So now your displayed code has something that looks like a backslash, at least on browsers, but it most probably fails for print, because the print font lacks the exotic character. Even in the browser, close is no cigar: Somebody cutting and pasting your code is in for a nasty surprise. You really do want the real backslash in there even on the HTML page, but you don’t want to disable groff’s escape character. Glyph substitution to the rescue:

    .char \[u29F9] \[u005C]

This lets you type the exotic backslash in your source but have groff and Troff2page convert it into the regular backslash when it lands on the page. Note there is no requirement that the font used by groff or the browser actually have the exotic backslash glyph at that Unicode position! You still have to type the exotic backslash, so you do require a competent text editor with a Unicode font.

\ in a section heading

This and the previous section’s headings both have a verbatim backslash in the heading. Glyph substitution works fine here.

However, if you use \e, there is a situation to watch out for. If you're using the .ToC macro, and this particular heading happens to be eligible to go into the ToC, then the escape fails as it goes through a groff diversion.

To remedy this, enclose the problem areas of the heading with a pair of \?s. (In fact, you can be conservative and enclose the entire heading.) Unfortunately, you should take care to do this only for headings meant for the ToC. Wrapping \? around a non-ToC heading will cause the heading to disappear!

While glyph substitution doesn't have this problem, note that this is a pervasive problem for all escapes, including font-changing escapes, so this trick is good to keep handy.

These problems are groff-specific. Troff2page will cleanly process the heading, ToC or no ToC, and whether or not you use \?.


4 The color names and values for terracotta pink and Venetian red are courtesy Resene Paints.

5 In the Vim editor, for instance, adding the command exec 'dig \\' 0x29F9 to your vimrc lets you use the digraph \\ to enter U+29F9.