.so u.tmac . .de @h . sp |36p . if \\n%>1 .tl ''-%-'' . sp |1i .. .de @f .sp |\\n(.pu-36p .tl ''\\*(#e'' .. . .t Hacking on the .x µ macro package .d John Ankarström . . .h What is .x µ ? .p .i µ or .i mu is a simple macro package for troff designed to abstract as little as possible from troff itself, while still providing a powerful framework for writing advanced documents. . . .h How is the source code of .x µ organized? .p If you run .c "grep -n [-]-" on the .i u.tmac source file, you are presented with an overview of .i µ 's macros: .l .eo !grep -n [-]- u.tmac .ec .p This is a sufficient summary of the entire .i µ source code, as nothing is performed outside of these macros. All initialization is performed in the .c @a macro, which is automatically called at the first invocation of any other macro. .p The above summary reflects a categorization in the macros defined by .i µ . There are internal and external macros. The former are to be used within .i u.tmac itself, while the latter are to be used in .i µ documents. Among the external macros, there are inline, environment (or block-level), hybrid and other macros. .p The inline macros all follow the same pattern. They take three arguments: the string to be formatted, an optional suffix and an optional prefix. The hybrid macros act as inline macros when given arguments; otherwise they act as environment macros. .p The environment or block-level macros generally take no arguments (except .c d ). Instead, they activate a given environment, affecting the formatting of the following text. Each environment macro is associated with a specific environment, carrying the same one-letter name as the macro itself. .p As you can see, the macros in each category are arranged alphabetically. . . .h Where is document state stored? .p Most state is stored by troff itself within the different environments. In addition, .i µ associates three extra registers with each environment: .c sp , the amount of space to be added by .c @e before an environment; .c sq , the same (except the space is not added if the new environment is identical to the previous one); and .c ti , the indentation of the first line in the .c p environment. These are stored in registers named .c @ENV_sp , .c @ENV_sq and .c @ENV_ti , where .c ENV is the name of the associated environment. .p The strings .c %env and .c %penv contain the name of the current and previous environment. .p The .c @a register is set to 1 if the document has been initialized (i.e. if .c @a has been invoked). .p The .c @m register is non-zero if .q "manual footer" mode is active. If .c @m is non-zero, .c @tf decrements it by one and exits when invoked, unless called with the .c f (force) argument. This is useful if you want to trigger the footer manually, but do not want the printed footer to trigger the footer trap again. .p .c @.t contains the absolute vertical position of the first trap following the first footnote reference on a page; it is set and used by .c ) to place the footnote trap in the correct vertical position. .c @dn contains the height of all collected footnotes on a page; it is set by .c ) and reset to zero by .c @tn . .c @n contains the total number of collected footnotes. .p Note that none of these registers and strings should be directly accessed or modified by .i µ documents.