date and time created 80/10/30 00:35:38 by mckusick
[unix-history] / .ref-BSD-3 / usr / doc / trofftut / tt10
CommitLineData
8340f87c
BJ
1.NH
2Number Registers and Arithmetic
3.PP
4.UL troff
5has a facility for doing arithmetic,
6and for defining and using variables with numeric values,
7called
8.ul
9number registers.
10Number registers, like strings and macros, can be useful in setting up a document
11so it is easy to change later.
12And of course they serve for any sort of arithmetic computation.
13.PP
14Like strings, number registers have one or two character names.
15They are set by the
16.BD .nr
17command,
18and are referenced anywhere by
19.BD \enx
20(one character name) or
21.BD \en(xy
22(two character name).
23.PP
24There are quite a few pre-defined number registers maintained by
25.UL troff ,
26among them
27.BD %
28for the current page number;
29.BD nl
30for the current vertical position on the page;
31.BD dy ,
32.BD mo
33and
34.BD yr
35for the current day, month and year; and
36.BD .s
37and
38.BD .f
39for the current size and font.
40(The font is a number from 1 to 4.)
41Any of these can be used in computations like any other register,
42but some, like
43.BD .s
44and
45.BD .f ,
46cannot be changed with
47.BD .nr .
48.PP
49As an example of the use of number registers,
50in the
51.BD \-ms
52macro package [4],
53most significant parameters are defined in terms of the values
54of a handful of number registers.
55These include the point size for text, the vertical spacing,
56and the line and title lengths.
57To set the point size and vertical spacing for the following paragraphs, for example, a user may say
58.P1
59^nr PS 9
60^nr VS 11
61.P2
62The paragraph macro
63.BD .PP
64is defined (roughly) as follows:
65.P1
66.ta 1i
67^de PP
68^ps \e\en(PS \e" reset size
69^vs \e\en(VSp \e" spacing
70^ft R \e" font
71^sp 0.5v \e" half a line
72^ti +3m
73^^
74.P2
75This sets the font to Roman and the point size and line spacing
76to whatever values are stored in the number registers
77.BD PS
78and
79.BD VS .
80.PP
81Why are there two backslashes?
82This is the eternal problem of how to quote a quote.
83When
84.UL troff
85originally reads the macro definition,
86it peels off one backslash
87to see what's coming next.
88To ensure that another is left in the definition when the
89macro is
90.ul
91used,
92we have to put in two backslashes in the definition.
93If only one backslash is used,
94point size and vertical spacing will be frozen at the time the macro
95is defined, not when it is used.
96.PP
97Protecting by an extra layer of backslashes
98is only needed for
99.BD \en ,
100.BD \e* ,
101.BD \e$
102(which we haven't come to yet),
103and
104.BD \e
105itself.
106Things like
107.BD \es ,
108.BD \ef ,
109.BD \eh ,
110.BD \ev ,
111and so on do not need an extra backslash,
112since they are converted by
113.UL troff
114to an internal code immediately upon being seen.
115.WS
116.PP
117Arithmetic expressions can appear anywhere that
118a number is expected.
119As a trivial example,
120.P1
121^nr PS \e\en(PS\-2
122.P2
123decrements PS by 2.
124Expressions can use the arithmetic operators +, \-, *, /, % (mod),
125the relational operators >, >=, <, <=, =, and != (not equal),
126and parentheses.
127.PP
128Although the arithmetic we have done so far
129has been straightforward,
130more complicated things are somewhat tricky.
131First,
132number registers hold only integers.
133.UL troff
134arithmetic uses truncating integer division, just like Fortran.
135Second, in the absence of parentheses,
136evaluation is done left-to-right
137without any operator precedence
138(including relational operators).
139Thus
140.P1
1417*\-4+3/13
142.P2
143becomes `\-1'.
144Number registers can occur anywhere in an expression,
145and so can scale indicators like
146.BD p ,
147.BD i ,
148.BD m ,
149and so on (but no spaces).
150Although integer division causes truncation,
151each number and its scale indicator is converted
152to machine units (1/432 inch) before any arithmetic is done,
153so
1541i/2u
155evaluates to
1560.5i
157correctly.
158.PP
159The scale indicator
160.BD u
161often has to appear
162when you wouldn't expect it _
163in particular, when arithmetic is being done
164in a context that implies horizontal or vertical dimensions.
165For example,
166.P1
167^ll 7/2i
168.P2
169would seem obvious enough _
1703\(12 inches.
171Sorry.
172Remember that the default units for horizontal parameters like
173.BD .ll
174are ems.
175That's really `7 ems / 2 inches',
176and when translated into machine units, it becomes zero.
177How about
178.P1
179^ll 7i/2
180.P2
181Sorry, still no good _
182the `2' is `2 ems', so `7i/2' is small,
183although not zero.
184You
185.ul
186must
187use
188.P1
189^ll 7i/2u
190.P2
191So again, a safe rule is to
192attach a scale indicator to every number,
193even constants.
194.PP
195For arithmetic done within a
196.BD .nr
197command,
198there is no implication of horizontal or vertical dimension,
199so the default units are `units',
200and 7i/2 and 7i/2u
201mean the same thing.
202Thus
203.P1
204^nr ll 7i/2
205^ll \e\en(llu
206.P2
207does just what you want,
208so long as you
209don't forget the
210.BD u
211on the
212.BD .ll
213command.