Next: , Previous: , Up: ms Page Layout   [Contents][Index]


4.6.6.5 Creating a table of contents

Because roff formatters process their input in a single pass, material on page 50, for example, cannot influence what appears on page 1—this poses a challenge for a table of contents at its traditional location in front matter, if you wish to avoid manually maintaining it. ms enables the collection of material to be presented in the table of contents as it appears, saving its page number along with it, and then emitting the collected contents on demand toward the end of the document. The table of contents can then be resequenced to its desired location by physically rearranging the pages of a printed document, or as part of post-processing—with a sed(1) script to reorder the pages in troff’s output, with pdfjam(1), or with gropdf(1)’s ‘.pdfswitchtopage’ feature, for example.

Define an entry to appear in the table of contents by bracketing its text between calls to the XS and XE macros. A typical application is to call them immediately after NH or SH and repeat the heading text within them. The XA macro, used within ‘.XS’/‘.XE’ pairs, supplements an entry—for instance, when it requires multiple output lines, whether because a heading is too long to fit or because style dictates that page numbers not be repeated. You may wish to indent the text thus wrapped to correspond to its heading depth; this can be done in the entry text by prefixing it with tabs or horizontal motion escape sequences, or by providing a second argument to the XA macro. XS and XA automatically associate the page number where they are called with the text following them, but they accept arguments to override this behavior. At the end of the document, call TC or PX to emit the table of contents; TC resets the page number to ‘i’ (Roman numeral one), and then calls PX. All of these macros are Berkeley extensions.

Macro: .XS [page-number]
Macro: .XA [page-number [indentation]]
Macro: .XE

Begin, supplement, and end a table of contents entry. Each entry is associated with page-number (otherwise the current page number); a page-number of ‘no’ prevents a leader and page number from being emitted for that entry. Use of XA within XS/XE is optional; it can be repeated. If indentation is present, a supplemental entry is indented by that amount; ens are assumed if no unit is indicated. Text on input lines between XS and XE is stored for later recall by PX.

Macro: .PX [no]

Switch to single-column layout. Unless no is specified, center and interpolate the TOC string in bold and two points larger than the body text. Emit the table of contents entries.

Macro: .TC [no]

Set the page number to 1, the page number format to lowercase Roman numerals, and call PX (with a no argument, if present).

Here’s an example of typical ms table of contents preparation. We employ horizontal escape sequences \h to indent the entries by sectioning depth.

.NH 1
Introduction
.XS
Introduction
.XE

.NH 2
Methodology
.XS
\h'2n'Methodology
.XA
\h'4n'Fassbinder's Approach
\h'4n'Kahiu's Approach
.XE

.NH 1
Findings
.XS
Findings
.XE

.TC

The remaining features in this subsubsection are GNU extensions. groff ms obviates the need to repeat heading text after XS calls. Call XN and XH after NH and SH, respectively.

Macro: .XN heading-text
Macro: .XH depth heading-text

Format heading-text and create a corresponding table of contents entry. XN computes the indentation from the depth of the preceding NH call; XH requires a depth argument to do so.

groff ms encourages customization of table of contents entry production.

Macro: .XN-REPLACEMENT heading-text
Macro: .XH-REPLACEMENT depth heading-text

These hook macros implement XN and XH, respectively. They call XN-INIT and pass their heading-text arguments to XH-UPDATE-TOC.

Macro: .XN-INIT
Macro: .XH-UPDATE-TOC depth heading-text

The XN-INIT hook macro does nothing by default. XH-UPDATE-TOC brackets heading-text with XS and XE calls, indenting it by 2 ens per level of depth beyond the first.

We could therefore produce a table of contents similar to that in the previous example with fewer macro calls. (The difference is that this input follows the “Approach” entries with leaders and page numbers.)

.NH 1
.XN Introduction

.NH 2
.XN Methodology
.XH 3 "Fassbinder's Approach"
.XH 3 "Kahiu's Approach"

.NH 1
.XN Findings

To get the section number of the numbered headings into the table of contents entries, we might define XN-REPLACEMENT as follows. (We obtain the heading depth from groff ms’s internal register nh*hl.)

.de XN-REPLACEMENT
.XN-INIT
.XH-UPDATE-TOC \\n[nh*hl] \\$@
\&\\*[SN] \\$*
..

You can change the style of the leader that bridges each table of contents entry with its page number; define the TC-LEADER special character by using the char request. A typical leader combines the dot glyph ‘.’ with a horizontal motion escape sequence to spread the dots. The width of the page number field is stored in the TC-MARGIN register.


Next: , Previous: , Up: ms Page Layout   [Contents][Index]