# To unbundle, run this file echo tt.mac sed 's/.//' >tt.mac <<'//GO.SYSIN DD tt.mac' -.tr _\(em -.tr *\(** -.de UL -.if n .ul -.if n \\$3\\$1\\$2 -.if t \\$3\f3\\$1\fP\\$2 -.. -.de UC -\\$3\s-1\\$1\s+1\\$2 -.. -.de C -.if n .ul -.if n \\$3\\$1\\$2 -.if t \\$3\f3\\$1\fP\\$2 -.. -.de IT -.if t \\$3\f2\\$1\fP\\$2 -.if n .ul -.if n \\$3\\$1\\$2 -.. -.de UI -\f3\\$1\fI\\$2\fR\\$3 -.. -.de P1 -.if n .ls 1 -.nf -. use first argument as indent if present -.if \\n(.$ .DS I \\$1 -.if !\\n(.$ .DS I 5 -.ta .75i 1.5i 2.25i 3i 3.75i -.tr '\' -.. -.de P2 -.tr '' -.DE -.if n .ls 2 -.lg -.. -.if t .ds m \(mi -.if n .ds m - -.if t .ds n \(no -.if n .ds n - -.if t .ds s \v'.41m'\s+4*\s-4\v'-.41m' -.if n .ds s * -.if t .ds S \(sl -.if n .ds S / -.if t .ds d \s+4\&.\&\s-4 -.if n .ds d \&.\& -.if t .ds a \z@@ -.if n .ds a @ -.hy 14 -. 2=not last lines; 4= no -xx; 8=no xx- -.de WS -.sp \\$1 -.. -. ACCENTS say \*'e or \*`e to get e acute or e grave -.ds ' \h'\w'e'u*4/10'\z\(aa\h'-\w'e'u*4/10' -.ds e \o"e\'" -.ds ` \h'\w'e'u*4/10'\z\(ga\h'-\w'e'u*4/10' -. UMLAUT \*:u, etc. -.ds : \v'-0.6m'\h'(1u-(\\n(.fu%2u))*0.13m+0.06m'\z.\h'0.2m'\z.\h'-((1u-(\\n(.fu%2u))*0.13m+0.26m)'\v'0.6m' -. TILDE and CIRCUMFLEX -.ds ^ \\k:\h'-\\n(.fu+1u/2u*2u+\\n(.fu-1u*0.13m+0.06m'\z^\h'|\\n:u' -.ds ~ \\k:\h'-\\n(.fu+1u/2u*2u+\\n(.fu-1u*0.13m+0.06m'\z~\h'|\\n:u' -.de BD -\&\\$3\f1\\$1\h\(ts-\w\(ts\\$1\(tsu+1u\(ts\\$1\fP\\$2\& -.. -.hw semi-colon //GO.SYSIN DD tt.mac echo tt00 sed 's/.//' >tt00 <<'//GO.SYSIN DD tt00' -.RP -.....TM 76-1273-7 39199 39199-11 -.TL -A TROFF Tutorial -.AU "MH 2C-518" 6021 -Brian W. Kernighan -.AI -.MH -.OK -Typesetting -Text formatting -NROFF -.AB -.PP -.UL troff -is a text-formatting program for driving the Graphic Systems -phototypesetter on the -.UX -and -.UC GCOS -operating systems. -This device is capable of producing high quality -text; -this paper is an example of -.UL troff -output. -.PP -The phototypesetter 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. -.PP -.UL troff -allows the user full control over fonts, -sizes, and character positions, -as well as the usual features of a formatter _ -right-margin justification, automatic hyphenation, -page titling and numbering, and so on. -It also provides macros, arithmetic variables and operations, -and conditional testing, for complicated formatting tasks. -.PP -This document is an introduction to the most basic use of -.UL troff . -It presents just enough information to enable the user -to do simple formatting -tasks like making viewgraphs, -and to make incremental changes to existing packages -of -.UL troff -commands. -In most respects, the -.UC UNIX -formatter -.UL nroff -is identical to -.UL troff , -so this document also serves as a tutorial on -.UL nroff . -.AE -.CS 13 1 14 0 0 5 -.if t .2C -.nr PS 9 -.nr VS 11 //GO.SYSIN DD tt00 echo tt01 sed 's/.//' >tt01 <<'//GO.SYSIN DD tt01' -.NH -Introduction -.tr ^. -.PP -.UL troff -[1] -is a text-formatting program, -written by J. F. Ossanna, -for producing -high-quality printed output from the phototypesetter -on the -.UC UNIX -and -.UC GCOS -operating systems. -This document is an example of -.UL troff -output. -.PP -The single most important rule -of using -.UL troff -is -not to use it directly, but through some intermediary. -In many ways, -.UL troff -resembles an assembly language _ -a remarkably powerful and flexible one _ -but nonetheless 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. -.PP -For two special applications, there are programs that provide -an interface to -.UL troff -for the majority of users. -.UL eqn -[2] -provides an easy to learn language for typesetting mathematics; -the -.UL eqn -user -need know no -.UL troff -whatsoever -to typeset mathematics. -.UL tbl -[3] -provides the same convenience for producing tables of arbitrary -complexity. -.PP -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 -.UL troff . -In particular, the `\-ms' -[4] -and PWB/MM [5] -packages -for Bell Labs internal memoranda and external papers -provide most of the facilities needed -for a wide range of document preparation. -(This memo was prepared with `\-ms'.) -There are also packages for viewgraphs, -for simulating the older -.UL roff -formatters on -.UC UNIX -and -.UC GCOS , -and for other special applications. -Typically you will find these packages easier to use -than -.UL troff -once you get beyond the most trivial operations; -you should always consider them first. -.PP -In the few cases where existing packages don't do the whole job, -the solution is -.ul -not -to write an entirely new set of -.UL troff -instructions from scratch, but to make small changes -to adapt packages that already exist. -.WS -.PP -In accordance with this philosophy of letting someone else -do the work, -the part of -.UL troff -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: -.sp -.nf -.in .1i -.ta .3i -\02. Point sizes and line spacing -\03. Fonts and special characters -\04. Indents and line length -\05. Tabs -\06. Local motions: Drawing lines and characters -\07. Strings -\08. Introduction to macros -\09. Titles, pages and numbering -10. Number registers and arithmetic -11. Macros with arguments -12. Conditionals -13. Environments -14. Diversions - Appendix: Typesetter character set -.sp -.in 0 -.fi -The -.UL troff -described here is the C-language version running on -.UC UNIX -at -Murray Hill, -as documented in [1]. -.WS -.PP -To use -.UL troff -you have to prepare not only the actual text you want printed, -but some information that tells -.ul -how -you want it printed. -(Readers who use -.UL roff -will find the approach familiar.) -For -.UL troff -the text -and -the formatting information are often intertwined quite intimately. -Most commands to -.UL troff -are placed on a line separate from the text itself, -beginning with a period (one command per line). -For example, -.P1 -Some text. -^ps 14 -Some more text. -.P2 -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: -.P1 -.fi -Some text. -.ps 14 -Some more text. -.ps 10 -.P2 -.PP -Occasionally, though, -something special occurs in the middle of a line _ -to produce -.P1 -Area = \(*p\fIr\fR\|\s8\u2\d\s0 -.P2 -you have to type -.P1 -Area = \e(*p\efIr\efR\e\^|\^\es8\eu2\ed\es0 -.P2 -(which we will explain shortly). -The backslash character -.BD \e -is used -to introduce -.UL troff -commands and special characters within a line of text. //GO.SYSIN DD tt01 echo tt02 sed 's/.//' >tt02 <<'//GO.SYSIN DD tt02' -.NH -Point Sizes; Line Spacing -.PP -As mentioned above, -the command -.BD .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 \(12 inch. -There are 15 point sizes, listed below. -.P1 1 -.ps 6 -6 point: Pack my box with five dozen liquor jugs. -.ps 7 -.vs 8p -7 point: Pack my box with five dozen liquor jugs. -.vs 9p -.ps 8 -8 point: Pack my box with five dozen liquor jugs. -.vs 10p -.ps 9 -9 point: Pack my box with five dozen liquor jugs. -.vs 11p -.ps 10 -10 point: Pack my box with five dozen liquor -.vs 12p -.ps 11 -11 point: Pack my box with five dozen -.vs 14p -.ps 12 -12 point: Pack my box with five dozen -.vs 16p -.ps 14 -14 point: Pack my box with five -.vs 24p -\s1616 point\s18 18 point\s20 20 point -.vs 40p -\s2222\s24 24\s28 28\s36 36 -.ps 10 -.vs 12p -.P2 -.PP -If the number after -.BD .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 -.BD .ps , -.UL troff -reverts to the previous size, whatever it was. -.UL troff -begins with point size 10, -which is usually fine. -This document is in 9 point. -.PP -The point size can also be changed in the middle of a line -or even a word -with the in-line command -.BD \es . -To produce -.P1 -\s8UNIX\s10 runs on a \s8PDP-\s1011/45 -.P2 -type -.P1 -\es8UNIX\es10 runs on a \es8PDP-\es1011/45 -.P2 -As above, -.BD \es -should be followed by a legal point size, -except that -.BD \es0 -causes the size to revert to -its previous value. -Notice that -.BD \es1011 -can be understood correctly as `size 10, followed by an 11', if the size is legal, -but not otherwise. -Be cautious with similar constructions. -.PP -Relative size changes are also legal and useful: -.P1 -\es\-2UNIX\es+2 -.P2 -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. -.WS -.PP -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 -.BD .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, -.P1 -^ps 9 -^vs 11p -.P2 -If we changed to -.P1 -^ps 9 -^vs 9p -.P2 -.vs 9p -.ne 3 -the running text would look like this. -After a few lines, you will agree it looks a little cramped. -The right vertical spacing is partly a matter of taste, depending on how -much text you want to squeeze into a given space, -and partly a matter of traditional printing style. -By default, -.UL troff -uses 10 on 12. -.PP -.vs 14p -.ps 12 -Point size and vertical spacing make a substantial difference in the amount of text -per square inch. -This is 12 on 14. -.ne 2 -.PP -.ne 2 -.ps 6 -.vs 7p -Point size and vertical spacing make a substantial difference in the amount of text -per square inch. -For example, -10 on 12 uses about twice as much space as 7 on 8. -This is 6 on 7, which is even smaller. -It packs a lot more words per line, -but you can go blind trying to read it. -.PP -When used without arguments, -.BD .ps -and -.BD .vs -revert to the previous size and vertical spacing -respectively. -.WS -.PP -The command -.BD .sp -is used to get extra vertical space. -Unadorned, -it gives you one extra blank line (one -.BD .vs , -whatever that has been set to). -Typically, that's more or less than you want, -so -.BD .sp -can be followed by -information about how much space you want _ -.P1 -^sp 2i -.P2 -means `two inches of vertical space'. -.P1 -^sp 2p -.P2 -means `two points of vertical space'; -and -.P1 -^sp 2 -.P2 -means `two vertical spaces' _ two of whatever -.BD .vs -is set to -(this can also be made explicit with -.BD .sp\ 2v ); -.UL troff -also understands decimal fractions in most places, -so -.P1 -^sp 1.5i -.P2 -is a space of 1.5 inches. -These same scale factors can be used after -.BD .vs -to define line spacing, and in fact after most commands -that deal with physical dimensions. -.PP -It should be noted that all size numbers are converted internally -to `machine units', which are 1/432 inch -(1/6 point). -For most purposes, this is enough resolution -that you don't have to worry about the accuracy of the representation. -The situation is not quite so good vertically, -where resolution is 1/144 inch -(1/2 point). //GO.SYSIN DD tt02 echo tt03 sed 's/.//' >tt03 <<'//GO.SYSIN DD tt03' -.NH -Fonts and Special Characters -.PP -.UL troff -and the typesetter allow four different fonts at any one time. -Normally three fonts (Times roman, italic and bold) and one collection of special characters -are permanently -mounted. -.P1 2 -.ft R -abcdefghijklmnopqrstuvwxyz 0123456789 -ABCDEFGHIJKLMNOPQRSTUVWXYZ -.ft I -abcdefghijklmnopqrstuvwxyz 0123456789 -ABCDEFGHIJKLMNOPQRSTUVWXYZ -.ft B -abcdefghijklmnopqrstuvwxyz 0123456789 -ABCDEFGHIJKLMNOPQRSTUVWXYZ -.ft R -.P2 -The -greek, mathematical symbols and miscellany -of the special font are -listed in Appendix A. -.PP -.UL troff -prints in roman unless told otherwise. -To switch into bold, use -the -.BD .ft -command -.P1 -^ft B -.P2 -and for italics, -.P1 -^ft I -.P2 -To return to roman, use -.BD .ft\ R ; -to return to the previous font, -whatever it was, -use either -.BD .ft\ P -or just -.BD .ft . -The `underline' command -.P1 -^ul -.P2 -causes the next input line to print in italics. -.BD .ul -can be followed by a count to -indicate that more than one line is to be italicized. -.PP -Fonts can also be changed within a line or word -with the in-line command -.BD \ef : -.P1 -\fBbold\fIface\fR text -.P2 -is produced by -.P1 -\efBbold\efIface\efR text -.P2 -If you want to do this so the previous font, whatever it was, -is left undisturbed, insert extra -.BD \efP -commands, like this: -.P1 -\efBbold\efP\efIface\efP\efR text\efP -.P2 -Because only the immediately previous font is remembered, -you have to restore the previous font after each change -or you can lose it. -The same is true of -.BD .ps -and -.BD .vs -when used without an argument. -.PP -There are other fonts available besides the standard set, -although you can still use only four at any given time. -The command -.BD .fp -tells -.UL troff -what fonts are physically mounted on the typesetter: -.P1 -^fp 3 H -.P2 -says that the Helvetica font is mounted on position 3. -(For a complete list of fonts and what they look like, -see the -.UL troff -manual.) -Appropriate -.BD .fp -commands should appear at the beginning of your document -if you do not use the standard fonts. -.PP -It is possible to make a document relatively independent -of the actual fonts used to print it -by using font numbers instead of names; -for example, -.BD \ef3 -and -.BD .ft~3 -mean `whatever font is mounted at position 3', -and thus work for any setting. -Normal settings are roman font on 1, italic on 2, -bold on 3, -and special on 4. -.PP -There is also a way to get `synthetic' bold fonts -by overstriking letters with a slight offset. -Look at the -.BD .bd -command in [1]. -.WS -.PP -Special characters have four-character names beginning with -.BD \e( , -and they may be inserted anywhere. -For example, -.P1 -\(14 + \(12 = \(34 -.P2 -is produced by -.P1 -\e(14 + \e(12 = \e(34 -.P2 -In particular, -greek letters are all of the form -.BD \e(*\- , -where -.BD \- -is an upper or lower case roman letter -reminiscent of the greek. -Thus -to get -.P1 -\(*S(\(*a\(mu\(*b) \(-> \(if -.P2 -in bare -.UL troff -we have to type -.P1 -\e(*S(\e(*a\e(mu\e(*b) \e(\(mi> \e(if -.P2 -That line is unscrambled as follows: -.P1 -.ta 1i 2i 3i -\e(*S \(*S -( ( -\e(*a \(*a -\e(mu \(mu -\e(*b \(*b -) ) -\e(\(mi> \(-> -\e(if \(if -.P2 -A complete list of these special names occurs in Appendix A. -.PP -In -.UL eqn -[2] -the same effect can be achieved with the input -.P1 -SIGMA ( alpha times beta ) \-> inf -.P2 -which is less concise, but clearer to the uninitiated. -.PP -Notice that -each -four-character name is a single character -as far as -.UL troff -is concerned _ -the -`translate' command -.P1 -^tr \e(mi\e(em -.P2 -is perfectly clear, meaning -.P1 -^tr \(mi\(em -.P2 -that is, to translate \(mi into \(em. -.PP -Some characters are automatically translated into others: -grave \(ga and acute \(aa accents (apostrophes) become open and close single quotes -`~'; -the combination of ``...'' is generally preferable to the double quotes "...". -Similarly a typed minus sign becomes a hyphen -. -To print an explicit \- sign, use -.BD \e- . -To get a backslash printed, use -.BD \ee . //GO.SYSIN DD tt03 echo tt04 sed 's/.//' >tt04 <<'//GO.SYSIN DD tt04' -.NH -Indents and Line Lengths -.PP -.UL troff -starts with a line length of 6.5 inches, -too wide for 8\(12\(mu11 paper. -To reset the line length, -use -the -.BD .ll -command, as in -.P1 -^ll 6i -.P2 -As with -.BD .sp , -the actual length can be specified in several ways; -inches are probably the most intuitive. -.PP -The maximum line length provided by the typesetter is 7.5 inches, by the way. -To use the full width, you will have to reset the default physical left margin (``page offset''), -which is normally slightly less than one inch from the left edge -of the paper. -This is done by the -.BD .po -command. -.P1 -^po 0 -.P2 -sets the offset as far to the left as it will go. -.WS -.PP -The indent command -.BD .in -causes the left margin to be indented -by some specified amount from the page offset. -If we use -.BD .in -to move the left margin in, -and -.BD .ll -to move the right margin to the left, -we can -make offset blocks of text: -.P1 -^in 0.3i -^ll \(mi0.3i -text to be set into a block -^ll +0.3i -^in \(mi0.3i -.P2 -will create a block that looks like this: -.P1 -.fi -.ll -0.3i -Pater noster qui est in caelis sanctificetur nomen tuum; -adveniat regnum tuum; fiat voluntas tua, sicut in caelo, -et in terra. ... -Amen. -.ll +0.3i -.P2 -Notice the use of `+' and `\(mi' -to specify the amount of change. -These change the previous setting by the specified amount, -rather than just overriding it. -The distinction is quite important: -.BD .ll\ +1i -makes lines one inch longer; -.BD .ll\ 1i -makes them one inch -.ul -long. -.PP -With -.BD .in , -.BD .ll -and -.BD .po , -the previous value is used if no argument is specified. -.PP -To indent a single line, use the `temporary indent' -command -.BD .ti . -For example, all paragraphs in this memo -effectively begin with the command -.P1 -^ti 3 -.P2 -Three of what? -The default unit for -.BD .ti , -as for most horizontally oriented commands -.BD .ll , ( -.BD .in , -.BD .po ), -is ems; -an em is roughly the width of the letter `m' -in the current point size. -(Precisely, a em in size -.ul -p -is -.ul -p -points.) -Although inches are usually clearer than ems to people who don't set type -for a living, -ems have a place: -they are a measure of size that is proportional to the current point size. -If you want to make text that keeps its proportions -regardless of point size, -you should use ems for all dimensions. -Ems can be specified as scale factors directly, -as in -.BD .ti\ 2.5m . -.PP -Lines can also be indented negatively -if the indent is already positive: -.P1 -^ti \(mi0.3i -.P2 -causes the next line to be moved back three tenths of an inch. -Thus to make a decorative initial capital, -we indent the whole paragraph, then move the letter `P' back with -a -.BD .ti -command: -.P1 -.ll -0.3i -.fi -.in +.3i -.ti -0.3i -\s36\v'2'P\v'-2'\s0ater noster qui est in caelis sanctificetur -nomen tuum; -adveniat regnum tuum; -'in -.3i -fiat voluntas tua, -sicut in caelo, et in terra. ... -Amen. -.ll +0.3i -.P2 -Of course, there is also some trickery to make the `P' -bigger (just a `\es36P\es0'), -and to move it -down from its normal position -(see the section on local motions). //GO.SYSIN DD tt04 echo tt05 sed 's/.//' >tt05 <<'//GO.SYSIN DD tt05' -.NH -Tabs -.PP -Tabs -(the \s8ASCII\s0 `horizontal tab' character) -can be used to produce output in columns, -or to set the horizontal position of output. -Typically -tabs are used only in unfilled text. -Tab stops are set by default every half inch from the -current indent, -but -can be changed by the -.BD .ta -command. -To set stops every inch, for example, -.P1 -^ta 1i 2i 3i 4i 5i 6i -.P2 -.PP -Unfortunately the stops are left-justified only -(as on a typewriter), -so lining up columns of right-justified numbers can be painful. -If you have many numbers, -or if you need more complicated table layout, -.ul -don't -use -.UL troff -directly; -use the -.UL tbl -program described in [3]. -.PP -For a handful of numeric columns, you can do it this way: -Precede every number by enough blanks to make it line up -when typed. -.P1 -^nf -^ta 1i 2i 3i -\0\01\0\fItab\fR\0\0\02\0\fItab\fR\0\0\03 -\040\0\fItab\fR\0\050\0\fItab\fR\0\060 -700\0\fItab\fR\0800\0\fItab\fR\0900 -^fi -.P2 -Then change each leading blank into the string -.BD \e0 . -This is a character that does not print, but that has -the same width as a digit. -When printed, this will produce -.P1 -.ta 1i 2i 3i -\0\01 \0\02 \0\03 -\040 \050 \060 -700 800 900 -.P2 -.PP -It is also possible to fill up tabbed-over space with -some character other than blanks by setting the `tab replacement character' -with the -.BD .tc -command: -.P1 -^ta 1.5i 2.5i -^tc \e(ru (\e(ru is "\(ru") -Name \fItab\fR Age \fItab\fR -.P2 -produces -.P1 3 -.ta 1.5i 2.5i -.tc \(ru -Name Age -.tc -.P2 -To reset the tab replacement character to a blank, use -.BD .tc -with no argument. -(Lines can also be drawn with the -.BD \el -command, described in Section 6.) -.PP -.UL troff -also provides a very general mechanism called `fields' -for setting up complicated columns. -(This is used by -.UL tbl ). -We will not go into it in this paper. //GO.SYSIN DD tt05 echo tt06 sed 's/.//' >tt06 <<'//GO.SYSIN DD tt06' -.NH -Local Motions: Drawing lines and characters -.PP -Remember `Area = \(*pr\u2\d' and the big `P' -in the Paternoster. -How are they done? -.UL troff -provides a host of commands for placing characters of any size -at any place. -You can use them to draw special characters -or to tune your output for a particular appearance. -Most of these commands are straightforward, but messy to read -and tough to type correctly. -.PP -If you won't use -.UL eqn , -subscripts and superscripts are most easily done with -the half-line local motions -.BD \eu -and -.BD \ed . -To go back up the page half a point-size, insert a -.BD \eu -at the desired place; -to go down, insert a -.BD \ed . -.BD \eu \& ( -and -.BD \ed -should always -be used in pairs, as explained below.) -Thus -.P1 -Area = \e(*pr\eu2\ed -.P2 -produces -.P1 -Area = \(*pr\u2\d -.P2 -To make the `2' smaller, bracket it with -.BD \es\-2...\es0 . -Since -.BD \eu -and -.BD \ed -refer to the current point size, -be sure to put them either both inside or both outside -the size changes, -or you will get an unbalanced vertical motion. -.PP -Sometimes the space given by -.BD \eu -and -.BD \ed -isn't the right amount. -The -.BD \ev -command can be used to request an arbitrary amount of vertical motion. -The in-line command -.P1 -\ev'(amount)' -.P2 -causes motion up or down the page by the amount specified in -`(amount)'. -For example, to move the `P' down, we used -.P1 2 -.ta 1i -^in +0.6i (move paragraph in) -^ll \-0.3i (shorten lines) -^ti \-0.3i (move P back) -\ev'2'\es36P\es0\ev'\-2'ater noster qui est -in caelis ... -.P2 -A minus sign causes upward motion, while -no sign or a plus sign means down the page. -Thus -.BD \ev\(fm\-2\(fm -causes an upward vertical motion -of two line spaces. -.PP -There are many other ways to specify the amount of motion _ -.P1 -\ev'0.1i' -\ev'3p' -\ev'\-0.5m' -.P2 -and so on are all legal. -Notice that the scale specifier -.BD i -or -.BD p -or -.BD m -goes inside the quotes. -Any character can be used in place of the quotes; -this is also true of all other -.UL troff -commands described in this section. -.PP -Since -.UL troff -does not take within-the-line vertical motions into account -when figuring out where it is on the page, -output lines can have unexpected positions -if the left and right ends aren't at the same -vertical position. -Thus -.BD \ev , -like -.BD \eu -and -.BD \ed , -should always balance upward vertical motion in a line with -the same amount in the downward direction. -.PP -Arbitrary horizontal motions are also available _ -.BD \eh -is quite analogous to -.BD \ev , -except that the default scale factor is ems instead of line spaces. -As an example, -.P1 -\eh'\-0.1i' -.P2 -causes a backwards motion of a tenth of an inch. -As a practical matter, consider printing the mathematical symbol -`>>'. -The default spacing is too wide, so -.UL eqn -replaces this by -.P1 ->\eh'\-0.3m'> -.P2 -to produce >\h'-.3m'>. -.PP -Frequently -.BD \eh -is used with the `width function' -.BD \ew -to generate motions equal to the width -of some character string. -The construction -.P1 -\ew'thing' -.P2 -is a number equal to the width of `thing' in machine units -(1/432 inch). -All -.UL troff -computations are ultimately done in these units. -To move horizontally the width of an `x', -we can say -.P1 -\eh'\ew'x'u' -.P2 -As we mentioned above, -the default scale factor for -all horizontal dimensions is -.BD m , -ems, so here we must have the -.BD u -for machine units, -or the motion produced will be far too large. -.UL troff -is quite happy with the nested quotes, by the way, -so long as you don't leave any out. -.PP -As a live example of this kind of construction, -all of the command names in the text, like -.BD .sp , -were done by overstriking with a slight offset. -The commands for -.BD .sp -are -.P1 -^sp\eh'\-\ew'.sp'u'\eh'1u'.sp -.P2 -That is, put out `.sp', move left by the width of `.sp', -move right 1 unit, and print -`.sp' again. -(Of course there is a way to avoid typing that much input -for each command name, which we will discuss in Section 11.) -.WS -.PP -There are also several special-purpose -.UL troff -commands for local motion. -We have already seen -.BD \e0 , -which is an unpaddable white space -of the same width as a digit. -`Unpaddable' means that it will never be widened -or split across a line by line justification and filling. -There is also -.BD \e (blank), -.tr ^^ -which is an unpaddable character the width of a space, -.BD \e| , -which is half that width, -.BD \e^ , -which is one quarter of the width of a space, -and -.BD \e& , -which has zero width. -.tr ^. -(This last one is useful, for example, in entering -a text line which would otherwise begin with a `.'.) -.PP -The command -.BD \eo , -used like -.P1 -\eo'set of characters' -.P2 -causes (up to 9) -characters to be overstruck, -centered on the widest. -This is nice for accents, as in -.P1 2 -syst\eo"e\e(ga"me t\eo"e\e(aa"l\eo"e\e(aa"phonique -.P2 -which makes -.P1 -syst\o"e\(ga"me t\o"e\(aa"l\o"e\(aa"phonique -.P2 -The accents are -.BD \e(ga -and -.BD \e(aa , -or -.BD \e\` -and -.BD \e\' ; -remember that each is just one character to -.UL troff . -.PP -You can make your own overstrikes with another special convention, -.BD \ez , -the zero-motion command. -.BD \ezx -suppresses the normal horizontal motion -after printing the single character -.BD x , -so another character can be laid on top of it. -Although sizes can be changed within -.BD \eo , -it centers the characters on the widest, -and -there can be no horizontal or vertical motions, -so -.BD \ez -may be the only way to get what you want: -.P1 -.sp 2 -\s8\z\(sq\s14\z\(sq\s22\z\(sq\s36\(sq -.P2 -is produced by -.P1 -^sp 2 -\es8\ez\e(sq\es14\ez\e(sq\es22\ez\e(sq\es36\e(sq -.P2 -The -.BD .sp -is needed to leave room for the result. -.PP -As another example, an extra-heavy semicolon -that looks like -.P1 -\s+6\z,\v'-0.25m'.\v'0.25m'\s0 instead of ; or \s+6;\s0 -.P2 -can be constructed with a big comma and a big period above it: -.P1 -\es+6\ez,\ev'\(mi0.25m'.\ev'0.25m'\es0 -.P2 -`0.25m' is an empirical constant. -.PP -A more ornate overstrike is given by the bracketing function -.BD \eb , -which piles up characters vertically, -centered on the current baseline. -Thus we can get big brackets, -constructing them with piled-up smaller pieces: -.P1 -.sp -.ne 3 -\b'\(lt\(lk\(lb' \b'\(lc\(lf' x \b'\(rc\(rf' \b'\(rt\(rk\(rb' -.sp -.P2 -by typing in only this: -.P1 0 -\&^sp -\eb\(fm\e(lt\e(lk\e(lb\(fm \eb\(fm\e(lc\e(lf\(fm x \eb\(fm\e(rc\e(rf\(fm \eb\(fm\e(rt\e(rk\e(rb\(fm -.P2 -.PP -.UL troff -also provides a convenient facility for drawing horizontal and vertical -lines of arbitrary length with arbitrary characters. -.BD \el\(fm1i\(fm -draws a line one inch long, like this: -\l'1i'\|. -The length can be followed by -the character to use if the \(ru isn't appropriate; -.BD \el\(fm0.5i.\(fm -draws a half-inch line of dots: \l'.5i.'. -The construction -.BD \eL -is entirely analogous, -except that it draws a vertical line instead of horizontal. //GO.SYSIN DD tt06 echo tt07 sed 's/.//' >tt07 <<'//GO.SYSIN DD tt07' -.NH -Strings -.PP -Obviously if a paper contains a large number of occurrences -of an acute accent over a letter `e', -typing -.BD \eo"e\e\'" -for each \*e -would be a great nuisance. -.PP -Fortunately, -.UL troff -provides a way in which you can store an arbitrary -collection of text in a `string', -and thereafter use the string name as a shorthand -for its contents. -Strings are one of several -.UL troff -mechanisms whose judicious use -lets you type a document -with less effort and organize -it -so that extensive format changes -can be made with few editing changes. -.PP -A reference to a string is replaced by whatever -text -the string was defined as. -Strings are defined with the command -.BD .ds . -The line -.P1 -\&^ds e \eo"e\e'" -.P2 -defines the string -.BD e -to have the value -.BD \eo"e\e\'" -.PP -String names may be either one or two characters long, -and are referred to by -.BD \e*x -for one character names or -.BD \e*(xy -for two character names. -Thus to get -t\*el\*ephone, -given the definition of the string -.BD e -as above, -we can say -t\e*el\e*ephone. -.PP -If a string must begin with blanks, define it as -.P1 -\&.ds xx " text -.P2 -The double quote signals the beginning of the definition. -There is no trailing quote; -the end of the line terminates the string. -.PP -A string may actually be several lines long; -if -.UL troff -encounters a -.BD \e -at the end of -.ul -any -line, it is thrown away and the next line -added to the current one. -So you can make a long string simply by ending each line -but the last with a backslash: -.P1 -\&^ds xx this \e -is a very \e -long string -.P2 -.PP -Strings may be defined in terms of other strings, or even in terms of themselves; -we will discuss some of these possibilities later. //GO.SYSIN DD tt07 echo tt08 sed 's/.//' >tt08 <<'//GO.SYSIN DD tt08' -.NH -Introduction to Macros -.PP -Before we can go much further in -.UL troff , -we need to learn a bit about the -macro -facility. -In its simplest form, a macro is just a shorthand notation -quite similar to a string. -Suppose we want every paragraph to start -in exactly the same way _ -with a space and a temporary indent of two ems: -.P1 -^sp -^ti +2m -.P2 -Then to save typing, we would like to collapse these into -one shorthand line, -a -.UL troff -`command' like -.P1 -^PP -.P2 -that would be treated by -.UL troff -exactly as -.P1 -^sp -^ti +2m -.P2 -.BD .PP -is called a -.ul -macro. -The way we tell -.UL troff -what -.BD .PP -means is to -.ul -define -it with the -.BD .de -command: -.P1 -^de PP -^sp -^ti +2m -^^ -.P2 -The first line names the macro -(we used -.BD .PP ' ` -for `paragraph', -and upper case so it wouldn't conflict with -any name that -.UL troff -might -already know about). -The last line -.BD .. -marks the end of the definition. -In between is the text, -which is simply inserted whenever -.UL troff -sees the `command' -or macro call -.P1 -^PP -.P2 -A macro -can contain any mixture of text and formatting commands. -.PP -The definition of -.BD .PP -has to precede its first use; -undefined macros are simply ignored. -Names are restricted to one or two characters. -.PP -Using macros for commonly occurring sequences of commands -is critically important. -Not only does it save typing, -but it makes later changes much easier. -Suppose we decide that the paragraph indent is too small, -the vertical space is much too big, -and roman font should be forced. -Instead of changing the whole document, -we need only change the definition of -.BD .PP -to -something like -.P1 -^de PP \e" paragraph macro -^sp 2p -^ti +3m -^ft R -^^ -.P2 -and the change takes -effect everywhere we used -.BD .PP . -.PP -.BD \e" -is a -.UL troff -command that causes the rest of the line to be ignored. -We use it here to add comments to the macro -definition -(a wise idea once definitions get complicated). -.PP -As another example of macros, -consider these two which start and end a block of offset, -unfilled text, like most of the examples in this paper: -.P1 -^de BS \e" start indented block -^sp -^nf -^in +0.3i -^^ -^de BE \e" end indented block -^sp -^fi -^in \(mi0.3i -^^ -.P2 -Now we can surround text like -.P1 -Copy to -John Doe -Richard Roberts -Stanley Smith -.P2 -by the commands -.BD .BS -and -.BD .BE , -and it will come out as it did above. -Notice that we indented by -.BD .in\ +0.3i -instead of -.BD .in\ 0.3i . -This way we can nest our uses of -.BD .BS -and -.BD BE -to get blocks within blocks. -.PP -If later on we decide that the indent -should be 0.5i, then it is only necessary to -change the definitions of -.BD .BS -and -.BD .BE , -not the whole paper. //GO.SYSIN DD tt08 echo tt09 sed 's/.//' >tt09 <<'//GO.SYSIN DD tt09' -.NH -Titles, Pages and Numbering -.PP -This is an area where things get tougher, -because nothing is done for you automatically. -Of necessity, some of this section is a cookbook, -to be copied literally until you get some experience. -.PP -Suppose you want a title at the top of each page, -saying just -.sp 3p -.lt 2.8i -.tl '~~~~left top'center top'right top~~~~' -.lt -.sp 3p -In -.UL roff , -one can say -.P1 2 -^he 'left top'center top'right top' -^fo 'left bottom'center bottom'right bottom' -.P2 -to get headers and footers automatically on every page. -Alas, this doesn't work in -.UL troff , -a serious hardship for the novice. -Instead you have to do a lot of specification. -.PP -You have to say what the actual title is (easy); -when to print it (easy enough); -and what to do at and around the title line (harder). -Taking these in reverse order, -first we define a macro -.BD .NP -(for `new page') to process -titles and the like at the end of one page -and the beginning of the next: -.P1 -^de NP -\(fmbp -\(fmsp 0.5i -\&.tl 'left top'center top'right top' -\(fmsp 0.3i -^^ -.P2 -To make sure we're at the top of a page, -we issue a `begin page' command -.BD \(fmbp , -which causes a skip to top-of-page -(we'll explain the -.BD \(fm -shortly). -Then we space down half an inch, -print the title -(the use of -.BD .tl -should be self explanatory; later we will discuss parameterizing the titles), -space another 0.3 inches, -and we're done. -.PP -To ask for -.BD .NP -at the bottom of each page, -we have to say something like -`when the text is within an inch -of the bottom of the page, -start the processing -for a new page.' -This is done with a `when' command -.BD .wh : -.P1 -^wh \-1i NP -.P2 -(No `.' is used before NP; -this is simply the name of a macro, not a macro call.) -The minus sign means -`measure up from the bottom of the page', -so -`\-1i' means `one inch from the bottom'. -.PP -The -.BD .wh -command appears in the input outside the definition of -.BD .NP ; -typically the input would be -.P1 -^de NP -^^^ -^^ -^wh \-1i NP -.P2 -.PP -Now what happens? -As text is actually being output, -.UL troff -keeps track of its vertical position on the page, -and after a line is printed within one inch from the bottom, -the -.BD .NP -macro is activated. -(In the jargon, the -.BD .wh -command sets a -.ul -trap -at the specified place, -which is `sprung' when that point is passed.) -.BD .NP -causes a skip to the top of the next page -(that's what the -.BD \(fmbp -was for), -then prints the title with the appropriate margins. -.PP -Why -.BD \(fmbp -and -.BD \(fmsp -instead of -.BD .bp -and -.BD .sp ? -The answer is that -.BD .sp -and -.BD .bp , -like several other commands, -cause a -.ul -break -to take place. -That is, all the input text collected but not yet printed -is flushed out as soon as possible, -and the next input line is guaranteed to start -a new line of output. -If we had used -.BD .sp -or -.BD .bp -in the -.BD .NP -macro, -this would cause a break in the middle -of the current output line when a new page is started. -The effect would be to print the left-over part of that line -at the top of the page, followed by the next input line on a new output line. -This is -.ul -not -what we want. -Using -.BD \(fm -instead of -.BD . -for a command -tells -.UL troff -that -no break is to take place _ -the output line -currently being filled -should -.ul -not -be forced out before the space or new page. -.PP -The list of commands that cause a break -is short and natural: -.P1 -^bp ^br ^ce ^fi ^nf ^sp ^in ^ti -.P2 -All others cause -.ul -no -break, -regardless of whether you use a -.BD . -or a -.BD \(fm . -If you really need a break, add a -.BD .br -command at the appropriate place. -.PP -One other thing to beware of _ -if you're changing fonts or point sizes a lot, -you may find that -if you cross a page boundary -in an unexpected font or size, -your titles come out in that size and font -instead of what you intended. -Furthermore, the length of a title is independent of the current line length, -so titles will come out at the default length of 6.5 inches -unless you change it, -which is done with the -.BD .lt -command. -.PP -There are several ways to fix the problems of point sizes -and fonts in titles. -For the simplest applications, we can change -.BD .NP -to set the proper size and font for the title, -then restore the previous values, like this: -.P1 2 -.ta .8i -^de NP -\(fmbp -\(fmsp 0.5i -^ft R \e" set title font to roman -^ps 10 \e" and size to 10 point -^lt 6i \e" and length to 6 inches -^tl 'left'center'right' -^ps \e" revert to previous size -^ft P \e" and to previous font -\(fmsp 0.3i -^^ -.P2 -.PP -This version of -.BD .NP -does -.ul -not -work if the fields in the -.BD .tl -command contain size or font changes. -To cope with that -requires -.UL troff 's -`environment' mechanism, -which we will discuss in Section 13. -.PP -To get a footer at the bottom of a page, -you can modify -.BD .NP -so it does -some processing before -the -.BD \(fmbp -command, -or split the job into a footer macro invoked -at the bottom margin and a header macro invoked -at the top of the page. -These variations are left as exercises. -.WS -.PP -Output page numbers are computed automatically -as each page is produced (starting at 1), -but no numbers are printed unless you ask for them explicitly. -To get page numbers printed, -include the character -.BD % -in the -.BD .tl -line at -the position where you want the number to appear. -For example -.P1 -^tl ''- % -'' -.P2 -centers the page number inside hyphens, as on this page. -You can set the page number at any time -with either -.BD .bp\ n , -which immediately starts a new page numbered -.BD n , -or with -.BD .pn\ n , -which sets the page number for the next page -but doesn't cause a skip to the new page. -Again, -.BD .bp\ +n -sets the page number to -.BD n -more than its current value; -.BD .bp -means -.BD .bp\ +1 . //GO.SYSIN DD tt09 echo tt10 sed 's/.//' >tt10 <<'//GO.SYSIN DD tt10' -.NH -Number Registers and Arithmetic -.PP -.UL troff -has a facility for doing arithmetic, -and for defining and using variables with numeric values, -called -.ul -number registers. -Number registers, like strings and macros, can be useful in setting up a document -so it is easy to change later. -And of course they serve for any sort of arithmetic computation. -.PP -Like strings, number registers have one or two character names. -They are set by the -.BD .nr -command, -and are referenced anywhere by -.BD \enx -(one character name) or -.BD \en(xy -(two character name). -.PP -There are quite a few pre-defined number registers maintained by -.UL troff , -among them -.BD % -for the current page number; -.BD nl -for the current vertical position on the page; -.BD dy , -.BD mo -and -.BD yr -for the current day, month and year; and -.BD .s -and -.BD .f -for the current size and font. -(The font is a number from 1 to 4.) -Any of these can be used in computations like any other register, -but some, like -.BD .s -and -.BD .f , -cannot be changed with -.BD .nr . -.PP -As an example of the use of number registers, -in the -.BD \-ms -macro package [4], -most significant parameters are defined in terms of the values -of a handful of number registers. -These include the point size for text, the vertical spacing, -and the line and title lengths. -To set the point size and vertical spacing for the following paragraphs, for example, a user may say -.P1 -^nr PS 9 -^nr VS 11 -.P2 -The paragraph macro -.BD .PP -is defined (roughly) as follows: -.P1 -.ta 1i -^de PP -^ps \e\en(PS \e" reset size -^vs \e\en(VSp \e" spacing -^ft R \e" font -^sp 0.5v \e" half a line -^ti +3m -^^ -.P2 -This sets the font to Roman and the point size and line spacing -to whatever values are stored in the number registers -.BD PS -and -.BD VS . -.PP -Why are there two backslashes? -This is the eternal problem of how to quote a quote. -When -.UL troff -originally reads the macro definition, -it peels off one backslash -to see what's coming next. -To ensure that another is left in the definition when the -macro is -.ul -used, -we have to put in two backslashes in the definition. -If only one backslash is used, -point size and vertical spacing will be frozen at the time the macro -is defined, not when it is used. -.PP -Protecting by an extra layer of backslashes -is only needed for -.BD \en , -.BD \e* , -.BD \e$ -(which we haven't come to yet), -and -.BD \e -itself. -Things like -.BD \es , -.BD \ef , -.BD \eh , -.BD \ev , -and so on do not need an extra backslash, -since they are converted by -.UL troff -to an internal code immediately upon being seen. -.WS -.PP -Arithmetic expressions can appear anywhere that -a number is expected. -As a trivial example, -.P1 -^nr PS \e\en(PS\-2 -.P2 -decrements PS by 2. -Expressions can use the arithmetic operators +, \-, *, /, % (mod), -the relational operators >, >=, <, <=, =, and != (not equal), -and parentheses. -.PP -Although the arithmetic we have done so far -has been straightforward, -more complicated things are somewhat tricky. -First, -number registers hold only integers. -.UL troff -arithmetic uses truncating integer division, just like Fortran. -Second, in the absence of parentheses, -evaluation is done left-to-right -without any operator precedence -(including relational operators). -Thus -.P1 -7*\-4+3/13 -.P2 -becomes `\-1'. -Number registers can occur anywhere in an expression, -and so can scale indicators like -.BD p , -.BD i , -.BD m , -and so on (but no spaces). -Although integer division causes truncation, -each number and its scale indicator is converted -to machine units (1/432 inch) before any arithmetic is done, -so -1i/2u -evaluates to -0.5i -correctly. -.PP -The scale indicator -.BD u -often has to appear -when you wouldn't expect it _ -in particular, when arithmetic is being done -in a context that implies horizontal or vertical dimensions. -For example, -.P1 -^ll 7/2i -.P2 -would seem obvious enough _ -3\(12 inches. -Sorry. -Remember that the default units for horizontal parameters like -.BD .ll -are ems. -That's really `7 ems / 2 inches', -and when translated into machine units, it becomes zero. -How about -.P1 -^ll 7i/2 -.P2 -Sorry, still no good _ -the `2' is `2 ems', so `7i/2' is small, -although not zero. -You -.ul -must -use -.P1 -^ll 7i/2u -.P2 -So again, a safe rule is to -attach a scale indicator to every number, -even constants. -.PP -For arithmetic done within a -.BD .nr -command, -there is no implication of horizontal or vertical dimension, -so the default units are `units', -and 7i/2 and 7i/2u -mean the same thing. -Thus -.P1 -^nr ll 7i/2 -^ll \e\en(llu -.P2 -does just what you want, -so long as you -don't forget the -.BD u -on the -.BD .ll -command. //GO.SYSIN DD tt10 echo tt11 sed 's/.//' >tt11 <<'//GO.SYSIN DD tt11' -.NH -Macros with arguments -.PP -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. -.PP -Let us illustrate by defining a macro -.BD .SM -that will print its argument two points -smaller than the surrounding text. -That is, the macro call -.P1 -^SM TROFF -.P2 -will produce -.UC TROFF . -.PP -The definition of -.BD .SM -is -.P1 -^de SM -\es\-2\e\e$1\es+2 -^^ -.P2 -Within a macro definition, -the symbol -.BD \e\e$n -refers to the -.BD n th -argument -that the macro was called with. -Thus -.BD \e\e$1 -is the string to be placed in a smaller point -size when -.BD .SM -is called. -.PP -As a slightly more complicated version, the following definition of -.BD .SM -permits optional second and third arguments -that will be printed in the normal size: -.P1 -^de SM -\e\e$3\es\-2\e\e$1\es+2\e\e$2 -^^ -.P2 -Arguments not provided when the macro is called are treated -as empty, -so -.P1 -^SM TROFF ), -.P2 -produces -.UC TROFF ), -while -.P1 -^SM TROFF ). ( -.P2 -produces -.UC TROFF ). ( -It is convenient to reverse -the order of arguments because trailing punctuation -is much more common than leading. -.PP -By the way, the number of arguments that a macro was called with -is available in number register -.BD .$ . -.PP -The following macro -.BD ^BD -is the one used to make the -`bold roman' we have been using for -.UL troff -command names in text. -It combines horizontal motions, width computations, -and argument rearrangement. -.P1 2 -\&.de BD -\e&\e\e$3\ef1\e\e$1\eh'\-\ew'\e\e$1'u+1u'\e\e$1\efP\e\e$2 -\&.. -.P2 -The -.BD \eh -and -.BD \ew -commands need no extra backslash, as we discussed above. -The -.BD \e& -is there in case the argument begins with a period. -.WS -.PP -Two backslashes are needed with the -.BD \e\e$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 -.BD .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 -.P1 -^SH "Section title ..." -.P2 -(If the argument to a macro is to contain blanks, -then it must be -.ul -surrounded -by double quotes, -unlike a string, where only one leading quote is permitted.) -.PP -Here is the definition of the -.BD .SH -macro: -.P1 -.ta .75i 1.15i -^nr SH 0 \e" initialize section number -^de SH -^sp 0.3i -^ft B -^nr SH \e\en(SH+1 \e" increment number -^ps \e\en(PS\-1 \e" decrease PS -\e\en(SH. \e\e$1 \e" number. title -^ps \e\en(PS \e" restore PS -^sp 0.3i -^ft R -^^ -.P2 -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.) -.PP -We used -.BD \e\en(SH -instead of -.BD \en(SH -and -.BD \e\en(PS -instead of -.BD \en(PS . -If we had used -.BD \en(SH , -we would get the value of the register at the time the macro was -.ul -defined, -not at the time it was -.ul -used. -If that's what you want, fine, -but not here. -Similarly, -by using -.BD \e\en(PS , -we get the point size at the time the macro is called. -.WS -.PP -As an example that does not involve numbers, -recall our -.BD .NP -macro which had a -.P1 -^tl 'left'center'right' -.P2 -We could make these into parameters by using instead -.P1 -^tl '\e\e*(LT'\e\e*(CT'\e\e*(RT' -.P2 -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 -.P1 -\&^ds CT - % - -.P2 -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. //GO.SYSIN DD tt11 echo tt12 sed 's/.//' >tt12 <<'//GO.SYSIN DD tt12' -.NH -Conditionals -.PP -Suppose we want the -.BD .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 -.BD .SH -macro -whether -the section number is 1, -and add some space if it is. -The -.BD .if -command provides the conditional test -that we can add -just before the heading line is output: -.P1 4 -^if \e\en(SH=1 ^sp 2i \e" first section only -.P2 -.PP -The condition after the -.BD .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. -.PP -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 -.BD .S1 -and invoke it -if we are about to do section 1 -(as determined by an -.BD .if ). -.P1 -^de S1 ---- processing for section 1 --- -^^ -^de SH -^^^ -^if \e\en(SH=1 ^S1 -^^^ -^^ -.P2 -.PP -An alternate way is to use the -extended form of the -.BD .if , -like this: -.P1 -^if \e\en(SH=1 \e{--- processing -for section 1 ----\e} -.P2 -The braces -.BD \e{ -and -.BD \e} -must occur in the positions shown -or you will get unexpected extra lines in your output. -.UL troff -also provides -an `if-else' construction, -which we will not go into here. -.PP -A condition can be negated by preceding it with -.BD ! ; -we get the same effect as above (but less clearly) by using -.P1 -^if !\e\en(SH>1 ^S1 -.P2 -.PP -There are a handful of -other conditions that can be tested with -.BD .if . -For example, is the current page even or odd? -.P1 -^if e ^tl ''even page title'' -^if o ^tl ''odd page title'' -.P2 -gives facing pages different titles -when used inside an appropriate new page macro. -.PP -Two other conditions -are -.BD t -and -.BD n , -which tell you whether the formatter is -.UL troff -or -.UL nroff . -.P1 -^if t troff stuff ... -^if n nroff stuff ... -.P2 -.PP -Finally, string comparisons may be made in an -.BD .if : -.P1 -^if 'string1'string2' stuff -.P2 -does `stuff' if -.ul -string1 -is the same as -.ul -string2. -The character separating the strings can be anything -reasonable that is -not contained in either string. -The strings themselves can reference strings with -.BD \e* , -arguments with -.BD \e$ , -and so on. //GO.SYSIN DD tt12 echo tt13 sed 's/.//' >tt13 <<'//GO.SYSIN DD tt13' -.NH -Environments -.PP -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. -.UL troff -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. -.PP -The command -.BD .ev\ n -shifts to environment -.BD n ; -.BD n -must be 0, 1 or 2. -The command -.BD .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. -.PP -Suppose we say that the main text is processed in environment 0, -which is where -.UL troff -begins by default. -Then we can modify the new page macro -.BD .NP -to process titles in environment 1 like this: -.P1 2 -^de NP -^ev 1 \e" shift to new environment -^lt 6i \e" set parameters here -^ft R -^ps 10 -\&... any other processing ... -^ev \e" return to previous environment -^^ -.P2 -It is also possible to initialize the parameters for an environment -outside the -.BD .NP -macro, -but the version shown keeps all the processing in one place -and is thus easier to understand and change. //GO.SYSIN DD tt13 echo tt14 sed 's/.//' >tt14 <<'//GO.SYSIN DD tt14' -.NH -Diversions -.PP -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. -.PP -.UL troff -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. -.PP -The command -.BD .di\ xy -begins a diversion _ all subsequent output is collected into the macro -.BD xy -until the command -.BD .di -with no arguments is encountered. -This terminates the diversion. -The processed text is available at any time thereafter, simply -by giving the command -.P1 -^xy -.P2 -The vertical size of the last finished diversion is contained in -the built-in number register -.BD dn . -.PP -As a simple example, -suppose we want to implement a `keep-release' -operation, -so that text between the commands -.BD .KS -and -.BD .KE -will not be split across a page boundary -(as for a figure or table). -Clearly, when a -.BD .KS -is encountered, we have to begin diverting -the output so we can find out how big it is. -Then when a -.BD .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: -.P1 2 -.ta .6i -^de KS \e" start keep -^br \e" start fresh line -^ev 1 \e" collect in new environment -^fi \e" make it filled text -^di XX \e" collect in XX -^^ -.P2 -.P1 2 -.ta .6i -^de KE \e" end keep -^br \e" get last partial line -^di \e" end diversion -^if \e\en(dn>=\e\en(.t .bp \e" bp if doesn't fit -^nf \e" bring it back in no-fill -^XX \e" text -^ev \e" return to normal environment -^^ -.P2 -Recall that number register -.BD nl -is the current position -on the output page. -Since output was being diverted, this remains -at its value when the diversion started. -.BD dn -is the amount of text in the diversion; -.BD .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 -.BD .if -is satisfied, and -a -.BD .bp -is issued. -In either case, the diverted output is then brought back with -.BD .XX . -It is essential to bring it back in no-fill mode so -.UL troff -will do no further processing on it. -.PP -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. //GO.SYSIN DD tt14 echo ttack sed 's/.//' >ttack <<'//GO.SYSIN DD ttack' -.SH -Acknowledgements -.PP -I am deeply indebted to J. F. Ossanna, -the author of -.UL troff , -for his repeated patient explanations -of -fine points, -and for his continuing willingness to -adapt -.UL troff -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. -.SH -References -.LP -.IP [1] -J. F. Ossanna, -.ul -.UC NROFF/TROFF -User's Manual, -Bell Laboratories -Computing Science Technical Report 54, 1976. -.IP [2] -B. W. Kernighan, -.ul -A System for Typesetting Mathematics _ User's Guide -.ul -(Second Edition), -Bell Laboratories -Computing Science Technical Report 17, 1977. -.IP [3] -M. E. Lesk, -.ul -TBL _ A Program to Format Tables, -Bell Laboratories -Computing Science Technical Report 49, 1976. -.IP [4] -M. E. Lesk, -.ul -Typing Documents on UNIX, -Bell Laboratories, 1978. -.IP [5] -J. R. Mashey and D. W. Smith, -.ul -PWB/MM _ -.ul -Programmer's Workbench Memorandum Macros, -Bell Laboratories internal memorandum. //GO.SYSIN DD ttack echo ttcharset sed 's/.//' >ttcharset <<'//GO.SYSIN DD ttcharset' -.bp -.tr __ -.nr VS 12 -.vs 12p -.1C -.SH -Appendix A: Phototypesetter Character Set -.LP -These characters exist in roman, italic, and bold. -To get the one on the left, type the -four-character name on the right. -.sp -.ta .2i .8i 1i 1.6i 1.8i 2.4i 2.6i 3.2i 3.4i 4.0i 4.2i 4.8i 5i 5.6i 5.8i -.nf -.in 0.5i -\(ff \\(ff \(fi \\(fi \(fl \\(fl \(Fi \\(Fi \(Fl \\(Fl -\(ru \\(ru \(em \\(em \(14 \\(14 \(12 \\(12 \(34 \\(34 -\(co \\(co \(de \\(de \(dg \\(dg \(fm \\(fm \(ct \\(ct -\(rg \\(rg \(bu \\(bu \(sq \\(sq \(hy \\(hy - (In bold, \e(sq is \fB\(sq\fP.) -.sp -.in 0 -.tr ~~ -.ps 9 -.fi -The following are special-font characters: -.sp -.in 0.5i -.tr ~~ -.nf -.ta .3i 1i 1.3i 2i 2.3i 3i 3.3i -\(pl \\(pl \(mi \\(mi \(mu \\(mu \(di \\(di -\(eq \\(eq \(== \\(== \(>= \\(>= \(<= \\(<= -\(!= \\(!= \(+- \\(+- \(no \\(no \(sl \\(sl -\(ap \\(ap \(~= \\(~= \(pt \\(pt \(gr \\(gr -\(-> \\(-> \(<- \\(<- \(ua \\(ua \(da \\(da -\(is \\(is \(pd \\(pd \(if \\(if \(sr \\(sr -\(sb \\(sb \(sp \\(sp \(cu \\(cu \(ca \\(ca -\(ib \\(ib \(ip \\(ip \(mo \\(mo \(es \\(es -\(aa \\(aa \(ga \\(ga \(ci \\(ci \(bs \\(bs -\(sc \\(sc \(dd \\(dd \(lh \\(lh \(rh \\(rh -\(lt \\(lt \(rt \\(rt \(lc \\(lc \(rc \\(rc -\(lb \\(lb \(rb \\(rb \(lf \\(lf \(rf \\(rf -\(lk \\(lk \(rk \\(rk \(bv \\(bv \(ts \\(ts -\(br \\(br \(or \\(or \(ul \\(ul \(rn \\(rn -\(** \\(** -.sp -.in0 -.ps 9 -.fi -These -four -characters also have two-character names. -The \' is the apostrophe on terminals; -the \` is the other quote mark. -.sp -.in .5i -\' \e\(aa \` \e\(ga \(mi \e\(mi \_ \e\_ -.sp -.in 0 -These -characters exist only on the special font, -but they do not have four-character names: -.sp -.in .5i -.nf -.tr ^^ -" { } < > ~ ^ \e # @ -.sp -.in 0 -.fi -For greek, precede the roman letter by -.BD \e(* -to get the corresponding greek; -for example, -.BD \e(*a -is -\(*a. -.sp -.in 0.5i -.nf -.cs R 36 -abgdezyhiklmncoprstufxqw -\(*a\(*b\(*g\(*d\(*e\(*z\(*y\(*h\(*i\(*k\(*l\(*m\(*n\(*c\(*o\(*p\(*r\(*s\(*t\(*u\(*f\(*x\(*q\(*w -.sp -ABGDEZYHIKLMNCOPRSTUFXQW -\(*A\(*B\(*G\(*D\(*E\(*Z\(*Y\(*H\(*I\(*K\(*L\(*M\(*N\(*C\(*O\(*P\(*R\(*S\(*T\(*U\(*F\(*X\(*Q\(*W -.ps 9 -.cs R -.in 0 -.fi //GO.SYSIN DD ttcharset echo ttindex sed 's/.//' >ttindex <<'//GO.SYSIN DD ttindex' -.bp -.2C -.SH -Index -.LP -.ps 8 -.vs 9p -! (negating conditionals)~17 -#$ (macro argument)~16 -#*x, #(xy (invoke string macro)~14 -#b (bracketing function)~13 -#d (subscript)~11 -#f (font change)~5 -#h (horizontal motion)~12 -#nx, #n(xy (number register)~15 -#o (overstrike)~13 -#s (size change)~3 -#u (superscript)~11 -#v (vertical motion)~11 -#w (width function)~12 -#z (zero motion)~13 -\(fmcommand instead of ^command~9 -% (page number register)~10,15 -^^ (end of macro definition)~7 -^bp~9,10 -^br (break)~9 -^ce (center)~2 -^ds (define string macro)~7,14 -^fi (fill)~2 -^ft (change font)~5 -^if (conditional test)~16 -^in (indent)~6 -^lg (set ligatures~5 -^ll (line length)~6 -^nf (nofill)~2 -^nr (set number register)~14 -^pn (page number)~10 -^ps (change point size)~1,3 -^sp (space)~4 -^ss (set space size)~10 -^ta (set tab stops)~11 -^tc (set tab character)~10 -^tl (title)~9 -^tr (translate characters)~2,6 -^ul (italicize)~6 -^vs (vertical spacing)~3 -^wh (when conditional)~9,17 -accents~6,13 -apostrophes~6 -arithmetic~15 -backslash~1,3,5,14,16 -begin page (^bp)~9 -block macros (B1,B2)~8 -bold font (.ft B)~5 -boustrophedon~12 -bracketing function (##b)~13 -break (^br)~9 -break-causing commmands~9 -centering (^ce)~2 -changing fonts (^ft, #f)~5 -changing macros~15 -character set~4,5,19 -character translation (^tr)~2,6 -columnated output~10 -commands~1 -commands that cause break~9 -conditionals (^if)~16 -constant proportion~7 -default break list~9 -define macro (^de)~7 -define string macro (^ds)~14 -drawing lines~11 -em~7,11 -end of macro (^^)~7 -even page test (e)~17 -fill (^fi)~2 -fonts (^ft)~4,19 -Greek (#(*-)~5,19 -hanging indent (^ti)~12 -hints~20 -horizontal motion (#h)~12 -hp (horizontal position register)~15 -hyphen~6 -i scale indicator~4 -indent (^in)~6 -index~21 -italic font (.ft I)~4 -italicize (^ul)~6 -legal point sizes~3 -ligatures (ff,fi,fl; ^lg)~5 -line length (^ll)~6 -line spacing (^vs)~3 -local motions (#u,#d,#v,#h,#w,#o,#z,#b)~11 ff -m scale indicator~7 -machine units~4,12 -macro arguments~15 -macros~7 -macros that change~15 -multiple backslashes~14 -negating conditionals (!)~17 -new page macro (NP)~8 -nl (current vertical position register)~15 -nofill (^nf)~2 -NROFF test (n)~17 -nested quotes~12 -number registers (^nr,#n)~14 -numbered paragraphs~12 -odd page test (o)~17 -order of evaluation~14 -overstrike (#o)~13 -p scale indicator~3 -page number register (%)~10 -page numbers (^pn, ^bp)~10 -paragraph macro (PG)~7 -Paternoster~6 -point size (^ps)~1,3 -previous font (#fP, ^ft P)~5 -previous point size (#s0,^ps)~3 -quotes~6 -relative change (\(+-)~6 -ROFF~1 -ROFF header and footer~8 -Roman font (.ft R)~4 -scale indicator i~4 -scale indicator m~7 -scale indicator p~3 -scale indicator u~12 -scale indicators in arithmetic~15 -section heading macro (SC)~15 -set space size (^ss)~10 -size _ see point size -space (^sp)~4 -space between lines (^vs)~3 -special characters (#(xx)~5,19 -string macros (^ds,#*)~14 -subscripts (#d)~11 -superscripts (#u)~11 -tab character (^tc)~11 -tabs (^ta)~10 -temporary indent (^ti)~7 -titles (^tl)~8 -translate (^tr)~2,6,12 -TROFF examples~19 -TROFF test (t)~17 -truncating division~15 -type faces _ see fonts -u scale indicator~12 -underline (^ul)~6 -valid point sizes~3 -vertical motion (#v)~11 -vertical position on page~9 -vertical spacing (^vs)~3 -when (^wh)~9,17 -width function (#w)~12 -width of digits~10 -zero motion (#z)~13 //GO.SYSIN DD ttindex