A TROFF Tutorial Brian W. Kernighan (updated for 4.3BSD by Mark Seiden) _t_r_o_f_f is a text-formatting program for typesetting on the operat- ing system. This device is capable of producing high quality text; this paper is an example of _t_r_o_f_f output. The photo- typesetter itself normally runs with four fonts, containing roman, italic and bold letters (as on this page), a full greek alphabet, and a substantial number of special characters and mathematical symbols. Characters can be printed in a range of sizes, and placed anywhere on the page. _t_r_o_f_f allows the user full control over fonts, sizes, and character positions, as well as the usual features of a formatter - right-margin justifica- tion, automatic hyphenation, page titling and numbering, and so on. It also provides macros, arithmetic variables and opera- tions, and conditional testing, for complicated formatting tasks. This document is an introduction to the most basic use of _t_r_o_f_f. It presents just enough information to enable the user to do sim- ple formatting tasks like making viewgraphs, and to make incre- mental changes to existing packages of _t_r_o_f_f commands. In most respects, the UNIX formatter _n_r_o_f_f and a more recent version (_d_e_v_i_c_e-_i_n_d_e_p_e_n_d_e_n_t _t_r_o_f_f) are identical to the version described here, so this document also serves as a tutorial for them as well. Introduction _t_r_o_f_f [1] is a text-formatting program, written ori- ginally by J. F. Ossanna, for producing high-quality printed out- put from the phototypesetter on the UNIX operating system. This document is an example of _t_r_o_f_f output. The single most impor- tant rule of using _t_r_o_f_f is not to use it directly, but through some intermediary. In many ways, _t_r_o_f_f resembles an assembly language - a remarkably powerful and flexible one - but nonethe- less such that many operations must be specified at a level of detail and in a form that is too hard for most people to use effectively. For two special applications, there are programs that provide an interface to _t_r_o_f_f for the majority of users. _e_q_n [2] provides an easy to learn language for typesetting mathematics; the _e_q_n user need know no _t_r_o_f_f whatsoever to typeset mathematics. _t_b_l [3] provides the same convenience for producing tables of arbitrary complexity. For producing straight text (which may well contain mathematics or tables), there are a number of `macro packages' that define formatting rules and operations for specific styles of documents, and reduce the amount of direct contact with _t_r_o_f_f. In particular, the `-ms' [4], PWB/MM [5], and `-me' [6] packages for internal memoranda and external papers provide most of the facilities needed for a wide range of document preparation.|- |- Most Berkeley Unix sites only have -ms and -me. (This memo was prepared with `-ms'.) There are also packages for viewgraphs, for simulating the older _r_o_f_f formatters, and for other special applications. Typically you will find these packages easier to use than _t_r_o_f_f once you get beyond the most trivial operations; you should always con- sider them first. In the few cases where existing packages don't do the whole job, the solution is _n_o_t to write an entirely new set of _t_r_o_f_f instructions from scratch, but to make small changes to adapt packages that already exist. In accordance with this philosophy of letting someone else do the work, the part of _t_r_o_f_f described here is only a small part of the whole, although it tries to concentrate on the more useful parts. In any case, there is no attempt to be complete. Rather, the emphasis is on showing how to do simple things, and how to make incremental changes to what already exists. The contents of the remaining sections are: 2.Point sizes and line spacing 3.Fonts and special characters 4.Indents and line length 5.Tabs 6.Local motions: Drawing lines and characters 7.Strings 8.Introduction to macros 9.Titles, pages and numbering 10.Number registers and arithmetic 11.Macros with arguments 12.Conditionals 13.Environments 14.Diversions Appendix: Typesetter character set The _t_r_o_f_f described here is the C-language version supplied with UNIX Version 7 and 32V as documented in [1]. To use _t_r_o_f_f you have to prepare not only the actual text you want printed, but some information that tells _h_o_w you want it printed. (Readers who use _r_o_f_f will find the approach familiar.) For _t_r_o_f_f the text and the formatting information are often intertwined quite intimately. Most commands to _t_r_o_f_f are placed on a line separate from the text itself, beginning with a period (one command per line). For example, Some text. .ps 14 Some more text. will change the `point size', that is, the size of the letters being printed, to `14 point' (one point is 1/72 inch) like this: Some text. Some more text. Occasionally, though, something spe- cial occurs in the middle of a line - to produce Area = J_r82 9you have to type Area = \(*p\fIr\fR\|\s8\u2\d\s0 (which we will explain shortly). The backslash character \\ is used to introduce _t_r_o_f_f commands and special characters within a line of text. Point Sizes; Line Spacing As mentioned above, the command .ps.ps sets the point size. One point is 1/72 inch, so 6-point characters are at most 1/12 inch high, and 36-point characters are 1/2 inch. There are 15 point sizes, listed below. 6 point: Pack my box with five dozen liquor jugs. 87 point: Pack my box with five dozen liquor jugs. 88 point: Pack my box with five dozen liquor jugs. 9 point: Pack my box with five dozen liquor jugs. 10 point: Pack my box with five dozen liquor 11 point: Pack my box with five dozen 12 point: Pack my box with five dozen 914 point: Pack my box with five 16 point 18 point 20 point 922 24 28 36 If the number after .ps.ps is not one of these legal sizes, it is rounded up to the next valid value, with a maximum of 36. If no number follows .ps.ps, _t_r_o_f_f reverts to the previous size, whatever it was. _t_r_o_f_f begins with point size 10, which is usually fine. The original of this document (on 8.5 by 11 inch paper) is in 9 point. The point size can also be changed in the middle of a line or even a word with the in-line command \s\s. To produce UNIX runs on a PDP-11/45 type \s8UNIX\s10 runs on a \s8PDP-\s1011/45 As above, \s\s should be followed by a legal point size, except that \s0\s0 causes the size to revert to its previous value. Notice that \s1011\s1011 can be understood correctly as `size 10, followed by an 11', if the size is legal, but not otherwise. Be cautious with similar constructions. Relative size changes are also legal and useful: \s-2UNIX\s+2 temporarily decreases the size, whatever it is, by two points, then restores it. Relative size changes have the advantage that the size difference is independent of the starting size of the document. The amount of the relative change is restricted to a single digit. The other parameter that determines what the type looks like is the spacing between lines, which is set independently of the point size. Vertical spacing is measured from the bottom of one line to the bottom of the next. The command to control vertical spacing is .vs.vs. For running text, it is usually best to set the vertical spacing about 20% bigger than the character size. For example, so far in this document, we have used ``9 on 11'', that is, .ps 9 .vs 11p If we changed to .ps 9 .vs 9p 8the running text would look like this. 98After a few lines, you will agree it looks a little cramped. 98The right vertical spacing is partly a matter of taste, depending on how 98much text you want to squeeze into a given space, 98and partly a matter of traditional printing style. 98By default, 98_t_r_o_f_f 98uses 10 on 12. 9Point size and vertical spacing make a substantial difference in the amount of text per square inch. This is 12 on 14. 8Point size and vertical spacing make a substantial difference in the amount of text 98per square inch. 98For example, 9810 on 12 uses about twice as much space as 7 on 8. 98This is 6 on 7, which is even smaller. 98It packs a lot more words per line, 98but you can go blind trying to read it. 98When used without arguments, 98.ps.ps 98and 98.vs.vs 98revert to the previous size and vertical spacing 98respectively. 998The command 98.sp.sp 98is used to get extra vertical space. 98Unadorned, 98it gives you one extra blank line (one 98.vs.vs, 98whatever that has been set to). 98Typically, that's more or less than you want, 98so 98.sp.sp 98can be followed by 98information about how much space you want - 98.sp 2i 8means `two inches of vertical space'. 98.sp 2p 8means `two points of vertical space'; 98and 98.sp 2 8means `two vertical spaces' - two of whatever 98.vs.vs 98is set to 98(this can also be made explicit with 98.sp 2v.sp 2v); 98_t_r_o_f_f 98also understands decimal fractions in most places, 98so 98.sp 1.5i 8is a space of 1.5 inches. 98These same scale factors can be used after 98.vs.vs 98to define line spacing, and in fact after most commands 98that deal with physical dimensions. 98It should be noted that all size numbers are converted internally 98to `machine units', which are 1/432 inch 98(1/6 point). 98For most purposes, this is enough resolution 98that you don't have to worry about the accuracy of the representation. 98The situation is not quite so good vertically, 98where resolution is 1/144 inch 98(1/2 point). 98Fonts and Special Characters 98_t_r_o_f_f 98and the typesetter allow four different fonts at any one time. 98Normally three fonts (Times roman, italic and bold) and one collection of special characters 98are permanently 98mounted. 98abcdefghijklmnopqrstuvwxyz 0123456789 8ABCDEFGHIJKLMNOPQRSTUVWXYZ 8_a_b_c_d_e_f_g_h_i_j_k_l_m_n_o_p_q_r_s_t_u_v_w_x_y_z _0_1_2_3_4_5_6_7_8_9 8_A_B_C_D_E_F_G_H_I_J_K_L_M_N_O_P_Q_R_S_T_U_V_W_X_Y_Z 8abcdefghijklmnopqrstuvwxyz 0123456789 8ABCDEFGHIJKLMNOPQRSTUVWXYZ 8The 98greek, mathematical symbols and miscellany 98of the special font are 98listed in Appendix A. 98_t_r_o_f_f 98prints in roman unless told otherwise. 98To switch into bold, use 98the 98.ft.ft 98command 98.ft B 8and for italics, 98.ft I 8To return to roman, use 98.ft R.ft R; 98to return to the previous font, 98whatever it was, 98use either 98.ft P.ft P 98or just 98.ft.ft. 98The `underline' command 98.ul 8causes the next input line to print in italics. 98.ul.ul 98can be followed by a count to 98indicate that more than one line is to be italicized. 98Fonts can also be changed within a line or word 98with the in-line command 98\f\f: 98bold_f_a_c_e text 8is produced by 98\fBbold\fIface\fR text 8If you want to do this so the previous font, whatever it was, 98is left undisturbed, insert extra 98\fP\fP 98commands, like this: 98\fBbold\fP\fIface\fP\fR text\fP 8Because only the immediately previous font is remembered, 98you have to restore the previous font after each change 98or you can lose it. 98The same is true of 98.ps.ps 98and 98.vs.vs 98when used without an argument. 98There are other fonts available besides the standard set, 98although you can still use only four at any given time. 98The command 98.fp.fp 98tells 98_t_r_o_f_f 98what fonts are physically mounted on the typesetter: 98.fp 3 H 8says that the Helvetica font is mounted on position 3. 98(The complete list of font sizes and styles depends on 98your typesetter or laser printer.) 98Appropriate 98.fp.fp 98commands should appear at the beginning of your document 98if you do not use the standard fonts. 98It is possible to make a document relatively independent 98of the actual fonts used to print it 98by using font numbers instead of names; 98for example, 98\f3\f3 98and 98.ft 3.ft 3 98mean `whatever font is mounted at position 3', 98and thus work for any setting. 98Normal settings are roman font on 1, italic on 2, 98bold on 3, 98and special on 4. 98There is also a way to get `synthetic' bold fonts 98by overstriking letters with a slight offset. 98Look at the 98.bd.bd 98command in [1]. 998Special characters have four-character names beginning with 98\(\(, 98and they may be inserted anywhere. 98For example, 981/4 + 1/2 = 3/4 8is produced by 98\(14 + \(12 = \(34 8In particular, 98greek letters are all of the form 98\(*-\(*-, 98where 98-- 98is an upper or lower case roman letter 98reminiscent of the greek. 98Thus 98to get 98R(AxB) -> oo 8in bare 98_t_r_o_f_f 98we have to type 98\(*S(\(*a\(mu\(*b) \(-> \(if 8That line is unscrambled as follows: 98\(*S R 8( ( 8\(*a A 8\(mu x 8\(*b B 8) ) 8\(-> -> 8\(if oo 8A complete list of these special names occurs in Appendix A. 98In 98_e_q_n 98[2] 98the same effect can be achieved with the input 98SIGMA ( alpha times beta ) -> inf 8which is less concise, but clearer to the uninitiated. 98Notice that 98each 98four-character name is a single character 98as far as 98_t_r_o_f_f 98is concerned - 98the 98`translate' command 98.tr \(mi\(em 8is perfectly clear, meaning 98.tr -- 8that is, to translate - into -. 98Some characters are automatically translated into others: 98grave ` and acute ' accents (apostrophes) become open and close single quotes 98`'; 98the combination of ``...'' is generally preferable to the double quotes "...". 98Similarly a typed minus sign becomes a hyphen -. 98To print an explicit - sign, use 98\-\-. 98To get a backslash printed, use 98\e\e. 98Indents and Line Lengths 98_t_r_o_f_f 98starts with a line length of 6.5 inches, 98which some people think is too wide for 81/2x11 paper. 98To reset the line length, 98use 98the 98.ll.ll 98command, as in 98.ll 6i 8As with 98.sp.sp, 98the actual length can be specified in several ways; 98inches are probably the most intuitive. 98The maximum line length provided by the typesetter is 7.5 inches, by the way. 98To use the full width, you will have to reset the default physical left margin (``page offset''), 98which is normally slightly less than one inch from the left edge 98of the paper. 98This is done by the 98.po.po 98command. 98.po 0 8sets the offset as far to the left as it will go. 998The indent command 98.in.in 98causes the left margin to be indented 98by some specified amount from the page offset. 98If we use 98.in.in 98to move the left margin in, 98and 98.ll.ll 98to move the right margin to the left, 98we can 98make offset blocks of text: 98.in 0.3i 8.ll -0.3i 8text to be set into a block 8.ll +0.3i 8.in -0.3i 8will create a block that looks like this: 98Pater noster qui est in caelis sanctificetur nomen tuum; 8adveniat regnum tuum; fiat voluntas tua, sicut in caelo, et in 8terra. ... Amen. Notice the use of `+' and `-' to specify 98the amount of change. These change the previous setting by the 98specified amount, rather than just overriding it. The distinc- 98tion is quite important: .ll +1i.ll +1i makes lines one inch longer; 98.ll 1i.ll 1i makes them one inch _l_o_n_g. With .in.in, .ll.ll and .po.po, the pre- 98vious value is used if no argument is specified. To indent a 98single line, use the `temporary indent' command .ti.ti. For example, 98all paragraphs in this memo effectively begin with the command 8.ti 3 8Three of what? 98The default unit for 98.ti.ti, 98as for most horizontally oriented commands 98(.ll.ll, 98.in.in, 98.po.po), 98is ems; 98an em is roughly the width of the letter `m' 98in the current point size. 98(Precisely, a em in size 98_p 98is 98_p 98points.) 98Although inches are usually clearer than ems to people who don't set type 98for a living, 98ems have a place: 98they are a measure of size that is proportional to the current point size. 98If you want to make text that keeps its proportions 98regardless of point size, 98you should use ems for all dimensions. 98Ems can be specified as scale factors directly, 98as in 98.ti 2.5m.ti 2.5m. 98Lines can also be indented negatively 98if the indent is already positive: 98.ti -0.3i 8causes the next line to be moved back three tenths of an inch. 98Thus to make a decorative initial capital, 98we indent the whole paragraph, then move the letter `P' back with 98a 98.ti.ti 98command: 98 P7ater noster qui est in caelis sanctificetur nomen tuum; 8 adveniat regnum tuum; fiat voluntas tua, sicut in caelo, et 8in terra. ... Amen. Of course, there is also some trickery 98to make the `P' bigger (just a `\s36P\s0'), and to move it down 98from its normal position (see the section on local motions). 98Tabs Tabs (the ASCII `horizontal tab' character) can be used to 98produce output in columns, or to set the horizontal position of 98output. Typically tabs are used only in unfilled text. Tab 98stops are set by default every half inch from the current indent, 98but can be changed by the .ta.ta command. To set stops every inch, 98for example, 8.ta 1i 2i 3i 4i 5i 6i 8Unfortunately the stops are left-justified only 98(as on a typewriter), 98so lining up columns of right-justified numbers can be painful. 98If you have many numbers, 98or if you need more complicated table layout, 98_d_o_n'_t 98use 98_t_r_o_f_f 98directly; 98use the 98_t_b_l 98program described in [3]. 98For a handful of numeric columns, you can do it this way: 98Precede every number by enough blanks to make it line up 98when typed. 98.nf 8.ta 1i 2i 3i 8 1 _t_a_b 2 _t_a_b 3 8 40 _t_a_b 50 _t_a_b 60 8700 _t_a_b 800 _t_a_b 900 8.fi 8Then change each leading blank into the string 98\0\0. 98This is a character that does not print, but that has 98the same width as a digit. 98When printed, this will produce 98 1 2 3 8 40 50 60 8700 800 900 8It is also possible to fill up tabbed-over space with 98some character other than blanks by setting the `tab replacement character' 98with the 98.tc.tc 98command: 98.ta 1.5i 2.5i 8.tc \(ru (\(ru is "_") 8Name _t_a_b Age _t_a_b 8produces 98Name___________ Age _____ 8To reset the tab replacement character to a blank, use 98.tc.tc 98with no argument. 98(Lines can also be drawn with the 98\l\l 98command, described in Section 6.) 98_t_r_o_f_f 98also provides a very general mechanism called `fields' 98for setting up complicated columns. 98(This is used by 98_t_b_l). 98We will not go into it in this paper. 98Local Motions: Drawing lines and characters 98Remember `Area = Jr829' and the big `P' 98in the Paternoster. 98How are they done? 98_t_r_o_f_f 98provides a host of commands for placing characters of any size 98at any place. 98You can use them to draw special characters 98or to tune your output for a particular appearance. 98Most of these commands are straightforward, but messy to read 98and tough to type correctly. 98If you won't use 98_e_q_n, 98subscripts and superscripts are most easily done with 98the half-line local motions 98\u\u 98and 98\d\d. 98To go back up the page half a point-size, insert a 98\u\u 98at the desired place; 98to go down, insert a 98\d\d. 98(\u\u 98and 98\d\d 98should always 98be used in pairs, as explained below.) 98Thus 98Area = \(*pr\u2\d 8produces 98Area = Jr82 To make the `2' smaller, bracket it with 98\s-2...\s0\s-2...\s0. 98Since 98\u\u 98and 98\d\d 98refer to the current point size, 98be sure to put them either both inside or both outside 98the size changes, 98or you will get an unbalanced vertical motion. 98Sometimes the space given by 98\u\u 98and 98\d\d 98isn't the right amount. 98The 98\v\v 98command can be used to request an arbitrary amount of vertical motion. 98The in-line command 98\v'(amount)' 8causes motion up or down the page by the amount specified in 98`(amount)'. 98For example, to move the `P' down, we used 98.in +0.6i (move paragraph in) 8.ll -0.3i (shorten lines) 8.ti -0.3i (move P back) 8\v'2'\s36P\s0\v'-2'ater noster qui est 8in caelis ... 8A minus sign causes upward motion, while 98no sign or a plus sign means down the page. 98Thus 98\v'-2'\v'-2' 98causes an upward vertical motion 98of two line spaces. 98There are many other ways to specify the amount of motion - 98\v'0.1i' 8\v'3p' 8\v'-0.5m' 8and so on are all legal. 98Notice that the scale specifier 98ii 98or 98pp 98or 98mm 98goes inside the quotes. 98Any character can be used in place of the quotes; 98this is also true of all other 98_t_r_o_f_f 98commands described in this section. 98Since 98_t_r_o_f_f 98does not take within-the-line vertical motions into account 98when figuring out where it is on the page, 98output lines can have unexpected positions 98if the left and right ends aren't at the same 98vertical position. 98Thus 98\v\v, 98like 98\u\u 98and 98\d\d, 98should always balance upward vertical motion in a line with 98the same amount in the downward direction. 98Arbitrary horizontal motions are also available - 98\h\h 98is quite analogous to 98\v\v, 98except that the default scale factor is ems instead of line spaces. 98As an example, 98\h'-0.1i' 8causes a backwards motion of a tenth of an inch. 98As a practical matter, consider printing the mathematical symbol 98`>>'. 98The default spacing is too wide, so 98_e_q_n 98replaces this by 98>\h'-0.3m'> 8to produce >>. 98Frequently 98\h\h 98is used with the `width function' 98\w\w 98to generate motions equal to the width 98of some character string. 98The construction 98\w'thing' 8is a number equal to the width of `thing' in machine units 98(1/432 inch). 98All 98_t_r_o_f_f 98computations are ultimately done in these units. 98To move horizontally the width of an `x', 98we can say 98\h'\w'x'u' 8As we mentioned above, 98the default scale factor for 98all horizontal dimensions is 98mm, 98ems, so here we must have the 98uu 98for machine units, 98or the motion produced will be far too large. 98_t_r_o_f_f 98is quite happy with the nested quotes, by the way, 98so long as you don't leave any out. 98As a live example of this kind of construction, 98all of the command names in the text, like 98.sp.sp, 98were done by overstriking with a slight offset. 98The commands for 98.sp.sp 98are 98.sp\h'-\w'.sp'u'\h'1u'.sp 8That is, put out `.sp', move left by the width of `.sp', 98move right 1 unit, and print 98`.sp' again. 98(Of course there is a way to avoid typing that much input 98for each command name, which we will discuss in Section 11.) 998There are also several special-purpose 98_t_r_o_f_f 98commands for local motion. 98We have already seen 98\0\0, 98which is an unpaddable white space 98of the same width as a digit. 98`Unpaddable' means that it will never be widened 98or split across a line by line justification and filling. 98There is also 98\\(blank), 98which is an unpaddable character the width of a space, 98\|\|, 98which is half that width, 98\^\^, 98which is one quarter of the width of a space, 98and 98\&\&, 98which has zero width. 98(This last one is useful, for example, in entering 98a text line which would otherwise begin with a `.'.) 98The command 98\o\o, 98used like 98\o'set of characters' 8causes (up to 9) 98characters to be overstruck, 98centered on the widest. 98This is nice for accents, as in 98syst\o"e\(ga"me t\o"e\(aa"l\o"e\(aa"phonique 8which makes 98syste`me te'le'phonique 8The accents are 98\(ga\(ga 98and 98\(aa\(aa, 98or 98\`\` 98and 98\'\'; 98remember that each is just one character to 98_t_r_o_f_f. 98You can make your own overstrikes with another special convention, 98\z\z, 98the zero-motion command. 98\zx\zx 98suppresses the normal horizontal motion 98after printing the single character 98xx, 98so another character can be laid on top of it. 98Although sizes can be changed within 98\o\o, 98it centers the characters on the widest, 98and 98there can be no horizontal or vertical motions, 98so 98\z\z 98may be the only way to get what you want: 9 8[][][][] 8is produced by 98.sp 2 8\s8\z\(sq\s14\z\(sq\s22\z\(sq\s36\(sq 8The 98.sp.sp 98is needed to leave room for the result. 98As another example, an extra-heavy semicolon 98that looks like 98,. instead of ; or ; 8can be constructed with a big comma and a big period above it: 98\s+6\z,\v'-0.25m'.\v'0.25m'\s0 8`0.25m' is an experimentally-derived constant. 98A more ornate overstrike is given by the bracketing function 98\b\b, 98which piles up characters vertically, 98centered on the current baseline. 98Thus we can get big brackets, 98constructing them with piled-up smaller pieces: 9987| | |78 |99|8 x8 |99|78 |99|99| 88by typing in only this: 98.sp 8\b'\(lt\(lk\(lb' \b'\(lc\(lf' x \b'\(rc\(rf' \b'\(rt\(rk\(rb' 8_t_r_o_f_f 98also provides a convenient facility for drawing horizontal and vertical 98lines of arbitrary length with arbitrary characters. 98\l'1i'\l'1i' 98draws a line one inch long, like this: 98__________. 98The length can be followed by 98the character to use if the _ isn't appropriate; 98\l'0.5i.'\l'0.5i.' 98draws a half-inch line of dots: ...... 98The construction 98\L\L 98is entirely analogous, 98except that it draws a vertical line instead of horizontal. 98Strings 98Obviously if a paper contains a large number of occurrences 98of an acute accent over a letter `e', 98typing 98\o"e\'"\o"e\'" 98for each e' 98would be a great nuisance. 98Fortunately, 98_t_r_o_f_f 98provides a way in which you can store an arbitrary 98collection of text in a `string', 98and thereafter use the string name as a shorthand 98for its contents. 98Strings are one of several 98_t_r_o_f_f 98mechanisms whose judicious use 98lets you type a document 98with less effort and organize 98it 98so that extensive format changes 98can be made with few editing changes. 98A reference to a string is replaced by whatever 98text 98the string was defined as. 98Strings are defined with the command 98.ds.ds. 98The line 98.ds e \o"e\'" 8defines the string 98ee 98to have the value 98\o"e\'"\o"e\'" 98String names may be either one or two characters long, 98and are referred to by 98\*x\*x 98for one character names or 98\*(xy\*(xy 98for two character names. 98Thus to get 98te'le'phone, 98given the definition of the string 98ee 98as above, 98we can say 98t\*el\*ephone. 98If a string must begin with blanks, define it as 98.ds xx " text 8The double quote signals the beginning of the definition. 98There is no trailing quote; 98the end of the line terminates the string. 98A string may actually be several lines long; 98if 98_t_r_o_f_f 98encounters a 98\\ 98at the end of 98_a_n_y 98line, it is thrown away and the next line 98added to the current one. 98So you can make a long string simply by ending each line 98but the last with a backslash: 98.ds xx this \ 8is a very \ 8long string 8Strings may be defined in terms of other strings, or even in terms of themselves; 98we will discuss some of these possibilities later. 98Introduction to Macros 98Before we can go much further in 98_t_r_o_f_f, 98we need to learn a bit about the 98macro 98facility. 98In its simplest form, a macro is just a shorthand notation 98quite similar to a string. 98Suppose we want every paragraph to start 98in exactly the same way - 98with a space and a temporary indent of two ems: 98.sp 8.ti +2m 8Then to save typing, we would like to collapse these into 98one shorthand line, 98a 98_t_r_o_f_f 98`command' like 98.PP 8that would be treated by 98_t_r_o_f_f 98exactly as 98.sp 8.ti +2m 8.PP.PP 98is called a 98_m_a_c_r_o. 98The way we tell 98_t_r_o_f_f 98what 98.PP.PP 98means is to 98_d_e_f_i_n_e 98it with the 98.de.de 98command: 98.de PP 8.sp 8.ti +2m 8.. 8The first line names the macro 98(we used 98`.PP.PP' 98for `paragraph', 98and upper case so it wouldn't conflict with 98any name that 98_t_r_o_f_f 98might 98already know about). 98The last line 98.... 98marks the end of the definition. 98In between is the text, 98which is simply inserted whenever 98_t_r_o_f_f 98sees the `command' 98or macro call 98.PP 8A macro 98can contain any mixture of text and formatting commands. 98The definition of 98.PP.PP 98has to precede its first use; 98undefined macros are simply ignored. 98Names are restricted to one or two characters. 98Using macros for commonly occurring sequences of commands 98is critically important. 98Not only does it save typing, 98but it makes later changes much easier. 98Suppose we decide that the paragraph indent is too small, 98the vertical space is much too big, 98and roman font should be forced. 98Instead of changing the whole document, 98we need only change the definition of 98.PP.PP 98to 98something like 98.de PP \" paragraph macro 8.sp 2p 8.ti +3m 8.ft R 8.. 8and the change takes 98effect everywhere we used 98.PP.PP. 98\"\" 98is a 98_t_r_o_f_f 98command that causes the rest of the line to be ignored. 98We use it here to add comments to the macro 98definition 98(a wise idea once definitions get complicated). 98As another example of macros, 98consider these two which start and end a block of offset, 98unfilled text, like most of the examples in this paper: 98.de BS \" start indented block 8.sp 8.nf 8.in +0.3i 8.. 8.de BE \" end indented block 8.sp 8.fi 8.in -0.3i 8.. 8Now we can surround text like 98Copy to 8John Doe 8Richard Roberts 8Stanley Smith 8by the commands 98.BS.BS 98and 98.BE.BE, 98and it will come out as it did above. 98Notice that we indented by 98.in +0.3i.in +0.3i 98instead of 98.in 0.3i.in 0.3i. 98This way we can nest our uses of 98.BS.BS 98and 98BEBE 98to get blocks within blocks. 98If later on we decide that the indent 98should be 0.5i, then it is only necessary to 98change the definitions of 98.BS.BS 98and 98.BE.BE, 98not the whole paper. 98Titles, Pages and Numbering 98This is an area where things get tougher, 98because nothing is done for you automatically. 98Of necessity, some of this section is a cookbook, 98to be copied literally until you get some experience. 98Suppose you want a title at the top of each page, 98saying just 98left top center topright top 8In 98_r_o_f_f, 98one can say 98.he 'left top'center top'right top' 8.fo 'left bottom'center bottom'right bottom' 8to get headers and footers automatically on every page. 98Alas, this doesn't work so easily in 98_t_r_o_f_f, 98a serious hardship for the novice. 98Instead you have to do a lot of specification (or use 98a macro package, which makes it effortless). 98You have to say what the actual title is (easy); 98when to print it (easy enough); 98and what to do at and around the title line (harder). 98Taking these in reverse order, 98first we define a macro 98.NP.NP 98(for `new page') to process 98titles and the like at the end of one page 98and the beginning of the next: 98.de NP 8'bp 8'sp 0.5i 8.tl 'left top'center top'right top' 8'sp 0.3i 8.. 8To make sure we're at the top of a page, 98we issue a `begin page' command 98'bp'bp, 98which causes a skip to top-of-page 98(we'll explain the 98'' 98shortly). 98Then we space down half an inch, 98print the title 98(the use of 98.tl.tl 98should be self explanatory; later we will discuss parameterizing the titles), 98space another 0.3 inches, 98and we're done. 98To ask for 98.NP.NP 98at the bottom of each page, 98we have to say something like 98`when the text is within an inch 98of the bottom of the page, 98start the processing 98for a new page.' 98This is done with a `when' command 98.wh.wh: 98.wh -1i NP 8(No `.' is used before NP; 98this is simply the name of a macro, not a macro call.) 98The minus sign means 98`measure up from the bottom of the page', 98so 98`-1i' means `one inch from the bottom'. 98The 98.wh.wh 98command appears in the input outside the definition of 98.NP.NP; 98typically the input would be 98.de NP 8... 8.. 8.wh -1i NP 8Now what happens? 98As text is actually being output, 98_t_r_o_f_f 98keeps track of its vertical position on the page, 98and after a line is printed within one inch from the bottom, 98the 98.NP.NP 98macro is activated. 98(In the jargon, the 98.wh.wh 98command sets a 98_t_r_a_p 98at the specified place, 98which is `sprung' when that point is passed.) 98.NP.NP 98causes a skip to the top of the next page 98(that's what the 98'bp'bp 98was for), 98then prints the title with the appropriate margins. 98Why 98'bp'bp 98and 98'sp'sp 98instead of 98.bp.bp 98and 98.sp.sp? 98The answer is that 98.sp.sp 98and 98.bp.bp, 98like several other commands, 98cause a 98_b_r_e_a_k 98to take place. 98That is, all the input text collected but not yet printed 98is flushed out as soon as possible, 98and the next input line is guaranteed to start 98a new line of output. 98If we had used 98.sp.sp 98or 98.bp.bp 98in the 98.NP.NP 98macro, 98this would cause a break in the middle 98of the current output line when a new page is started. 98The effect would be to print the left-over part of that line 98at the top of the page, followed by the next input line on a new output line. 98This is 98_n_o_t 98what we want. 98Using 98'' 98instead of 98.. 98for a command 98tells 98_t_r_o_f_f 98that 98no break is to take place - 98the output line 98currently being filled 98should 98_n_o_t 98be forced out before the space or new page. 98The list of commands that cause a break 98is short and natural: 98.bp .br .ce .fi .nf .sp .in .ti 8All others cause 98_n_o 98break, 98regardless of whether you use a 98.. 98or a 98''. 98If you really need a break, add a 98.br.br 98command at the appropriate place. 98One other thing to beware of - 98if you're changing fonts or point sizes a lot, 98you may find that 98if you cross a page boundary 98in an unexpected font or size, 98your titles come out in that size and font 98instead of what you intended. 98Furthermore, the length of a title is independent of the current line length, 98so titles will come out at the default length of 6.5 inches 98unless you change it, 98which is done with the 98.lt.lt 98command. 98There are several ways to fix the problems of point sizes 98and fonts in titles. 98For the simplest applications, we can change 98.NP.NP 98to set the proper size and font for the title, 98then restore the previous values, like this: 98.de NP 8'bp 8'sp 0.5i 8.ft R \" set title font to roman 8.ps 10 \" and size to 10 point 8.lt 6i \" and length to 6 inches 8.tl 'left'center'right' 8.ps \" revert to previous size 8.ft P \" and to previous font 8'sp 0.3i 8.. 8This version of 98.NP.NP 98does 98_n_o_t 98work if the fields in the 98.tl.tl 98command contain size or font changes. 98To cope with that 98requires 98_t_r_o_f_f'_s 98`environment' mechanism, 98which we will discuss in Section 13. 98To get a footer at the bottom of a page, 98you can modify 98.NP.NP 98so it does 98some processing before 98the 98'bp'bp 98command, 98or split the job into a footer macro invoked 98at the bottom margin and a header macro invoked 98at the top of the page. 98These variations are left as exercises. 998Output page numbers are computed automatically 98as each page is produced (starting at 1), 98but no numbers are printed unless you ask for them explicitly. 98To get page numbers printed, 98include the character 98%% 98in the 98.tl.tl 98line at 98the position where you want the number to appear. 98For example 98.tl ''- % -'' 8centers the page number inside hyphens, as on this page. 98You can set the page number at any time 98with either 98.bp n.bp n, 98which immediately starts a new page numbered 98nn, 98or with 98.pn n.pn n, 98which sets the page number for the next page 98but doesn't cause a skip to the new page. 98Again, 98.bp +n.bp +n 98sets the page number to 98nn 98more than its current value; 98.bp.bp 98means 98.bp +1.bp +1. 9 Macros with arguments The next step is to define macros that can change from one use to the next according to parameters supplied as arguments. To make this work, we need two things: first, when we define the macro, we have to indicate that some parts of it will be provided as arguments when the macro is called. Then when the macro is called we have to provide actual arguments to be plugged into the definition. Let us illustrate by defining a macro .SM.SM that will print its argument two points smaller than the surrounding text. That is, the macro call ^SM TROFF will produce TROFF. The definition of .SM.SM is ^de SM \s-2\\$1\s+2 ^^ Within a macro definition, the symbol \\$n\\$n refers to the nnth argument that the macro was called with. Thus \\$1\\$1 is the string to be placed in a smaller point size when .SM.SM is called. As a slightly more complicated version, the following definition of .SM.SM permits optional second and third arguments that will be printed in the normal size: ^de SM \\$3\s-2\\$1\s+2\\$2 ^^ Arguments not provided when the macro is called are treated as empty, so ^SM TROFF ), produces TROFF), while ^SM TROFF ). ( produces (TROFF). It is convenient to reverse the order of arguments because trailing punctuation is much more common than leading. By the way, the number of arguments that a macro was called with is available in number register .$.$. The following macro ^BD^BD is the one used to make the `bold roman' we have been using for _t_r_o_f_f command names in text. It combines horizontal motions, width computations, and argument rearrangement. .de BD \&\\$3\f1\\$1\h'-\w'\\$1'u+1u'\\$1\fP\\$2 .. The \h\h and \w\w commands need no extra backslash, as we discussed above. The \&\& is there in case the argument begins with a period. Two backslashes are needed with the \\$n\\$n commands, though, to protect one of them when the macro is being defined. Perhaps a second example will make this clearer. Consider a macro called .SH.SH which produces section headings rather like those in this paper, with the sections numbered automatically, and the title in bold in a smaller size. The use is ^SH "Section title ..." (If the argument to a macro is to contain blanks, then it must be _s_u_r_r_o_u_n_d_e_d by double quotes, unlike a string, where only one leading quote is permitted.) Here is the definition of the .SH.SH macro: ^nr SH 0 \" initialize section number ^de SH ^sp 0.3i ^ft B ^nr SH \\n(SH+1\" increment number ^ps \\n(PS-1\" decrease PS \\n(SH. \\$1\" number. title ^ps \\n(PS \" restore PS ^sp 0.3i ^ft R ^^ The section number is kept in number register SH, which is incremented each time just before it is used. (A number register may have the same name as a macro without conflict but a string may not.) We used \\n(SH\\n(SH instead of \n(SH\n(SH and \\n(PS\\n(PS instead of \n(PS\n(PS. If we had used \n(SH\n(SH, we would get the value of the register at the time the macro was _d_e_f_i_n_e_d, not at the time it was _u_s_e_d. If that's what you want, fine, but not here. Similarly, by using \\n(PS\\n(PS, we get the point size at the time the macro is called. As an example that does not involve numbers, recall our .NP.NP macro which had a ^tl 'left'center'right' We could make these into parameters by using instead ^tl '\\*(LT'\\*(CT'\\*(RT' so the title comes from three strings called LT, CT and RT. If these are empty, then the title will be a blank line. Normally CT would be set with something like ^ds CT - % - to give just the page number between hyphens (as on the top of this page), but a user could supply private definitions for any of the strings. Conditionals Suppose we want the .SH.SH macro to leave two extra inches of space just before section 1, but nowhere else. The cleanest way to do that is to test inside the .SH.SH macro whether the section number is 1, and add some space if it is. The .if.if command provides the conditional test that we can add just before the heading line is output: ^if \\n(SH=1 ^sp 2i \" first section only The condition after the .if.if can be any arithmetic or logical expression. If the condition is logically true, or arithmetically greater than zero, the rest of the line is treated as if it were text - here a command. If the condition is false, or zero or negative, the rest of the line is skipped. It is possible to do more than one command if a condition is true. Suppose several operations are to be done before section 1. One possibility is to define a macro .S1.S1 and invoke it if we are about to do section 1 (as determined by an .if.if). ^de S1 --- processing for section 1 --- ^^ ^de SH ^^^ ^if \\n(SH=1 ^S1 ^^^ ^^ An alternate way is to use the extended form of the .if.if, like this: ^if \\n(SH=1 \{--- processing for section 1 ----\} The braces \{\{ and \}\} must occur in the positions shown or you will get unexpected extra lines in your output. _t_r_o_f_f also provides an `if-else' construction, which we will not go into here. A condition can be negated by preceding it with !!; we get the same effect as above (but less clearly) by using ^if !\\n(SH>1 ^S1 There are a handful of other conditions that can be tested with .if.if. For example, is the current page even or odd? ^if o ^tl 'odd page title''- % -' ^if e ^tl '- % -''even page title' gives facing pages different titles and page numbers on the outside edge when used inside an appropriate new page macro. Two other conditions are tt and nn, which tell you whether the formatter is _t_r_o_f_f or _n_r_o_f_f. ^if t troff stuff ... ^if n nroff stuff ... Finally, string comparisons may be made in an .if.if: ^if 'string1'string2' stuff does `stuff' if _s_t_r_i_n_g_1 is the same as _s_t_r_i_n_g_2. The character separating the strings can be anything reasonable that is not contained in either string. The strings themselves can reference strings with \*\*, arguments with \$\$, and so on. Environments As we mentioned, there is a potential problem when going across a page boundary: parameters like size and font for a page title may well be different from those in effect in the text when the page boundary occurs. _t_r_o_f_f provides a very general way to deal with this and similar situations. There are three `environments', each of which has independently settable versions of many of the parameters associated with processing, including size, font, line and title lengths, fill/nofill mode, tab stops, and even partially collected lines. Thus the titling problem may be readily solved by processing the main text in one environment and titles in a separate one with its own suitable parameters. The command .ev n.ev n shifts to environment nn; nn must be 0, 1 or 2. The command .ev.ev with no argument returns to the previous environment. Environment names are maintained in a stack, so calls for different environments may be nested and unwound consistently. Suppose we say that the main text is processed in environment 0, which is where _t_r_o_f_f begins by default. Then we can modify the new page macro .NP.NP to process titles in environment 1 like this: ^de NP ^ev 1 \" shift to new environment ^lt 6i \" set parameters here ^ft R ^ps 10 ... any other processing ... ^ev \" return to previous environment ^^ It is also possible to initialize the parameters for an environment outside the .NP.NP macro, but the version shown keeps all the processing in one place and is thus easier to understand and change. Diversions There are numerous occasions in page layout when it is necessary to store some text for a period of time without actually printing it. Footnotes are the most obvious example: the text of the footnote usually appears in the input well before the place on the page where it is to be printed is reached. In fact, the place where it is output normally depends on how big it is, which implies that there must be a way to process the footnote at least enough to decide its size without printing it. _t_r_o_f_f provides a mechanism called a diversion for doing this processing. Any part of the output may be diverted into a macro instead of being printed, and then at some convenient time the macro may be put back into the input. The command .di xy.di xy begins a diversion - all subsequent output is collected into the macro xyxy until the command .di.di with no arguments is encountered. This terminates the diversion. The processed text is available at any time thereafter, simply by giving the command ^xy The vertical size of the last finished diversion is contained in the built-in number register dndn. As a simple example, suppose we want to implement a `keep-release' operation, so that text between the commands .KS.KS and .KE.KE will not be split across a page boundary (as for a figure or table). Clearly, when a .KS.KS is encountered, we have to begin diverting the output so we can find out how big it is. Then when a .KE.KE is seen, we decide whether the diverted text will fit on the current page, and print it either there if it fits, or at the top of the next page if it doesn't. So: ^de KS\" start keep ^br \" start fresh line ^ev 1 \" collect in new environment ^fi \" make it filled text ^di XX\" collect in XX ^^ ^de KE\" end keep ^br \" get last partial line ^di \" end diversion ^if \\n(dn>=\\n(.t .bp \" bp if doesn't fit ^nf \" bring it back in no-fill ^XX \" text ^ev \" return to normal environment ^^ Recall that number register nlnl is the current position on the output page. Since output was being diverted, this remains at its value when the diversion started. dndn is the amount of text in the diversion; .t.t (another built-in register) is the distance to the next trap, which we assume is at the bottom margin of the page. If the diversion is large enough to go past the trap, the .if.if is satisfied, and a .bp.bp is issued. In either case, the diverted output is then brought back with .XX.XX. It is essential to bring it back in no-fill mode so _t_r_o_f_f will do no further processing on it. This is not the most general keep-release, nor is it robust in the face of all conceivable inputs, but it would require more space than we have here to write it in full generality. This section is not intended to teach everything about diversions, but to sketch out enough that you can read existing macro packages with some comprehension. Acknowledgements I am deeply indebted to J. F. Ossanna, the author of _t_r_o_f_f, for his repeated patient explanations of fine points, and for his continuing willingness to adapt _t_r_o_f_f to make other uses easier. I am also grateful to Jim Blinn, Ted Dolotta, Doug McIlroy, Mike Lesk and Joel Sturman for helpful comments on this paper. References J. F. Ossanna, _N_R_O_F_F/_T_R_O_F_F User's Manual, Bell Laboratories Computing Science Technical Report 54, 1976. B. W. Kernighan, _A _S_y_s_t_e_m _f_o_r _T_y_p_e_s_e_t_t_i_n_g _M_a_t_h_e_m_a_t_i_c_s - _U_s_e_r'_s _G_u_i_d_e (_S_e_c_o_n_d _E_d_i_t_i_o_n), Bell Laboratories Computing Science Technical Report 17, 1977. M. E. Lesk, _T_B_L - _A _P_r_o_g_r_a_m _t_o _F_o_r_m_a_t _T_a_b_l_e_s, Bell Laboratories Computing Science Technical Report 49, 1976. M. E. Lesk, _T_y_p_i_n_g _D_o_c_u_m_e_n_t_s _o_n _U_N_I_X, Bell Laboratories, 1978. J. R. Mashey and D. W. Smith, _P_W_B/_M_M - _P_r_o_g_r_a_m_m_e_r'_s _W_o_r_k_- _b_e_n_c_h _M_e_m_o_r_a_n_d_u_m _M_a_c_r_o_s, Bell Laboratories internal memorandum. Eric P. Allman, _W_r_i_t_i_n_g _P_a_p_e_r_s _w_i_t_h _N_R_O_F_F _u_s_i_n_g -_m_e, University of California, Berkeley. Appendix A: Phototypesetter Character Set (APS-5) These charac- ters exist in roman, italic, and bold. To get the one on the left, type the four-character name on the right. ff \(ff fi \(fi fl \(fl ffi \(Fiffl\(Fl _ \(ru - \(em 1/4 \(14 1/2 \(12 3/4 \(34 8c9 \(co 8o9 \(de |- \(dg ' \(fm c/ \(ct 8r9 \(rg o+ \(bu [] \(sq - \(hy (In bold, \(sq is [].) The following are special-font characters: + \(pl - \(mi x \(mu / \(di = \(eq =_ \(== >_ \(>= <_ \(<= =/ \(!= +_ \(+- _ \(no / \(sl 9~8 \(ap =~ \(~= \(pt [ \(gr -> \(-> <- \(<- |^ \(ua \(da ^ \(is ] \(pd oo \(if \(sr \(sb \(sp U \(cu \(ca \(ib \(ip \(mo \(es ' \(aa ` \(ga O \(ci \(bs \(sc |= \(dd <= \(lh => \(rh | \(lt | \(rt | \(lc | \(rc | \(lb | \(rb | \(lf | \(rf | \(lk | \(rk | \(bv \(ts | \(br | \(or _ \(ul \(rn * \(** These four characters also have two-character names. The ' is the apostrophe on terminals; the ` is the other quote mark. ' \' ` \` - \- _ \_ These characters exist only on the special font, but they do not have four-character names: " { } < > ~ ^ \ # @ For greek, precede the roman letter by \(*\(* to get the correspond- ing greek; for example, \(*a\(*a is A. abgdezyhiklmncoprstufxqw AB\DSQNOikLM@XoJKYIvUxVC ABGDEZYHIKLMNCOPRSTUFXQW ABGWEZHTIKEMNOPPRTYFXHZ Index 8! (negating conditionals) 17 8#$ (macro argument) 16 8#*x, #(xy (invoke string macro) 14 8#b (bracketing function) 13 8#d (subscript) 11 8#f (font change) 5 8#h (horizontal motion) 12 8#nx, #n(xy (number register) 15 8#o (overstrike) 13 8#s (size change) 3 8#u (superscript) 11 8#v (vertical motion) 11 8#w (width function) 12 8#z (zero motion) 13 8'command instead of ^command 9 8% (page number register) 10,15 8^^ (end of macro definition) 7 8^bp 9,10 8^br (break) 9 8^ce (center) 2 8^ds (define string macro) 7,14 8^fi (fill) 2 8^ft (change font) 5 8^if (conditional test) 16 8^in (indent) 6 8^lg (set ligatures 5 8^ll (line length) 6 8^nf (nofill) 2 8^nr (set number register) 14 8^pn (page number) 10 8^ps (change point size) 1,3 8^sp (space) 4 8^ss (set space size) 10 8^ta (set tab stops) 11 8^tc (set tab character) 10 8^tl (title) 9 8^tr (translate characters) 2,6 8^ul (italicize) 6 8^vs (vertical spacing) 3 8^wh (when conditional) 9,17 8accents 6,13 8apostrophes 6 8arithmetic 15 8backslash 1,3,5,14,16 8begin page (^bp) 9 8block macros (B1,B2) 8 8bold font (.ft B) 5 8boustrophedon 12 8bracketing function (##b) 13 8break (^br) 9 8break-causing commmands 9 8centering (^ce) 2 8changing fonts (^ft, #f) 5 8changing macros 15 8character set 4,5,19 8character translation (^tr) 2,6 8columnated output 10 8commands 1 8commands that cause break 9 8conditionals (^if) 16 8constant proportion 7 8default break list 9 8define macro (^de) 7 8define string macro (^ds) 14 8drawing lines 11 8em 7,11 8end of macro (^^) 7 8even page test (e) 17 8fill (^fi) 2 8fonts (^ft) 4,19 8Greek (#(*-) 5,19 8hanging indent (^ti) 12 8hints 20 8horizontal motion (#h) 12 8hp (horizontal position register) 15 8hyphen 6 8i scale indicator 4 8indent (^in) 6 8index 21 8italic font (.ft I) 4 8italicize (^ul) 6 8legal point sizes 3 8ligatures (ff,fi,fl; ^lg) 5 8line length (^ll) 6 8line spacing (^vs) 3 8local motions (#u,#d,#v,#h,#w,#o,#z,#b) 11 ff 8m scale indicator 7 8machine units 4,12 8macro arguments 15 8macros 7 8macros that change 15 8multiple backslashes 14 8negating conditionals (!) 17 8new page macro (NP) 8 8nl (current vertical position register) 15 8nofill (^nf) 2 8NROFF test (n) 17 8nested quotes 12 8number registers (^nr,#n) 14 8numbered paragraphs 12 8odd page test (o) 17 8order of evaluation 14 8overstrike (#o) 13 8p scale indicator 3 8page number register (%) 10 8page numbers (^pn, ^bp) 10 8paragraph macro (PG) 7 8Paternoster 6 8point size (^ps) 1,3 8previous font (#fP, ^ft P) 5 8previous point size (#s0,^ps) 3 8quotes 6 8relative change (+_) 6 8ROFF 1 8ROFF header and footer 8 8Roman font (.ft R) 4 8scale indicator i 4 8scale indicator m 7 8scale indicator p 3 8scale indicator u 12 8scale indicators in arithmetic 15 8section heading macro (SC) 15 8set space size (^ss) 10 8size - see point size 8space (^sp) 4 8space between lines (^vs) 3 8special characters (#(xx) 5,19 8string macros (^ds,#*) 14 8subscripts (#d) 11 8superscripts (#u) 11 8tab character (^tc) 11 8tabs (^ta) 10 8temporary indent (^ti) 7 8titles (^tl) 8 8translate (^tr) 2,6,12 8TROFF examples 19 8TROFF test (t) 17 8truncating division 15 8type faces - see fonts 8u scale indicator 12 8underline (^ul) 6 8valid point sizes 3 8vertical motion (#v) 11 8vertical position on page 9 8vertical spacing (^vs) 3 8when (^wh) 9,17 8width function (#w) 12 8width of digits 10 8zero motion (#z) 13 9