.so k.tmac .mediasize letter . .de @h . sp |36p . if \\n%>1 .tl ''-%-'' . sp |1i .. .de @f .sp |\\n(.pu-36p .tl ''\\*(#e'' .. . .t Hacking on the .z mk macro package .d John Ankarström . . .h What is .z mk ? .p .i Mk 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 .z mk organized? .p If you run .c "grep -n [-]-" on the .i k.tmac source file, you are presented with an overview of .i mk 's macros: .l .eo !grep -n [-]- k.tmac .ec .p This is a sufficient summary of the entire .i mk 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 mk . There are internal and external macros. The former are to be used within .i k.tmac itself, while the latter are to be used in .i mk documents. Among the external macros, there are inline, environment (or block-level) 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. .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 mk 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 ." "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 mk documents.