|
|
1.1 root 1: ...\" Thu May 22 16:54:35 EDT 1986
2: .de UC
3: \&\\$3\s-2\\$1\s+2\&\\$2
4: ..
5: .fp 1 PA
6: .fp 2 PI
7: .fp 3 PB
8: .nr dT 8 \" tab stops this far apart in .P1/.P2
9: .hy 14 \" set hyphenation: 2=not last lines; 4= no -xx; 8=no xx-
10: .\"
11: .\"
12: .ND "Revised, March, 1982"
13: .TR 97
14: ....TM 80-1272-8 39199 39199-11
15: .TL
16: A Typesetter-independent TROFF
17: .AU "MH 2C-518" 6021
18: Brian W. Kernighan
19: .AI
20: .MH
21: .AB
22: .PP
23: Although
24: .UC TROFF
25: has been the mainstay of document preparation
26: at Bell Labs for several years,
27: it has heretofore been very dependent
28: on one particular typesetter,
29: the Graphic Systems CAT.
30: .PP
31: This paper describes conversion of
32: .UC TROFF
33: to deal with a wide class of typesetters.
34: .PP
35: Some of these typesetters provide many more facilities
36: than the CAT does.
37: Typical extra features include
38: more sizes and fonts,
39: larger alphabets,
40: and the ability to
41: create new characters
42: and to draw graphical objects.
43: The paper describes the enhancements that permit
44: .UC TROFF
45: to take advantage of some
46: of these capabilities as well.
47: .AE
48: .CS 12 1 13 0 0 2
49: .NH
50: A Bit of History
51: .LP
52: .QS
53: ``I will be speaking today about work in progress,
54: instead of completed research;
55: this was not my original intention when I chose the subject
56: of this lecture,
57: but the fact is I couldn't get my
58: computer programs working in time.''
59: .sp .5
60: .ta 4i
61: Donald E. Knuth
62: .[
63: %A Donald E. Knuth
64: %T Mathematical typography
65: %J Bulletin (New Series) of the American Mathematical Society
66: %V 1
67: %N 2
68: %D 1979
69: .]
70: .QE
71: .PP
72: The
73: .UC TROFF
74: text formatter
75: .[
76: %A J. F. Ossanna
77: %T NROFF/TROFF User's Manual
78: %D October 1976
79: %R Comp. Sci. Tech. Rep. 54
80: %I Bell Laboratories
81: %C Murray Hill, NJ
82: .]
83: was originally written by the late Joe Ossanna
84: in about 1973, in assembly language for the PDP-11.
85: .UC NROFF , (
86: which drives terminals instead of a typesetter,
87: is essentially identical to
88: .UC TROFF ;
89: we will use
90: .UC TROFF '' ``
91: as a generic term hence\%forth.)
92: It was rewritten in C around 1975,
93: and underwent slow but steady evolution until
94: Ossanna's death late in 1977.
95: .PP
96: In spite of some obvious deficiencies
97: \(em a rebarbative input syntax,
98: mysterious and undocumented properties in some areas,
99: and a voracious appetite for computer resources
100: (especially when used with macro packages and preprocessors like
101: .UC EQN
102: and
103: .UC TBL )
104: \(em
105: .UC TROFF
106: has been the basis of document preparation at
107: Bell Labs for some years,
108: and is likely to remain so for years to come.
109: .PP
110: Early in 1979,
111: the Computing Science Research Center
112: decided to acquire a new typesetter,
113: primarily because of our interests in typesetting graphics.
114: At the same time,
115: the Murray Hill Computer Center
116: began to investigate the possibility of replacing their
117: family of aging CAT's
118: with a new, high-performance typesetter,
119: simply to keep up with their rapidly expanding load.
120: .PP
121: My first thought
122: (a thought shared by many others)
123: was that this would be a glorious opportunity
124: to replace
125: .UC TROFF
126: with a new formatting language:
127: better designed,
128: easier to work with,
129: and of course much faster.
130: This remains a desirable goal,
131: but, after quite a bit of thought spread over several
132: years,
133: I am still not really much closer to a better design,
134: let alone an implementation.
135: Furthermore,
136: a great deal of software depends on
137: .UC TROFF
138: \(em
139: the preprocessors, the macro packages,
140: and of course all of their documentation and our accumulated expertise.
141: Tossing this aside is not something to be done lightly.
142: .PP
143: Accordingly, in the spring of 1979,
144: I set about to modify
145: .UC TROFF
146: so that it would run hence\%forth without change
147: on a variety of typesetters.
148: The ground rule was that
149: .UC TROFF
150: should retain its current specifications,
151: so that existing software like
152: .UC EQN ,
153: .UC TBL
154: and the macro packages would continue to work with it.
155: .PP
156: Since much of the rest of this paper
157: is encrusted with details that could appeal only to
158: maintainers or masochists,
159: I will give here a brief summary of what has been done.
160: Non-specialists can stop reading at the end of the section.
161: .PP
162: .UC TROFF
163: is highly dependent on the Graphic Systems CAT typesetter,
164: not just in details of code
165: but also in many aspects of its design.
166: The language design issues have been largely ignored
167: (few are truly fundamental),
168: while the code has been modified
169: so that dependencies are either eliminated
170: or at least parameterized.
171: .PP
172: .UC TROFF
173: originally had parameters of the typesetter
174: compiled into the code,
175: often in non-obvious ways.
176: The new version reads a parameter file
177: each time it is invoked, to
178: set values for machine resolution,
179: legal sizes, fonts and characters,
180: character widths
181: and the like.
182: .PP
183: .UC TROFF
184: output used to be binary device codes
185: specific to the CAT and arcane beyond description.
186: The output of the new version is
187: .UC ASCII
188: characters
189: in a simple and (I hope) universal language
190: that describes where each character is to be placed
191: and in what size and font.
192: A post-processor must be written for each typesetter
193: to convert this typesetter-independent language
194: into specific codes for that typesetter.
195: Post-processors currently exist
196: for the CAT,
197: the Mergenthaler Linotron 202,
198: the Autologic APS-5,
199: the Tektronix 4014 terminal,
200: The Imagen Canon laser printer,
201: Versatec printers,
202: and a bit-map terminal.
203: New ones can generally be written in less than a day;
204: they share much of their code with previous ones.
205: .PP
206: The new output language contains information that is not readily
207: identifiable in the older output.
208: Most notably, the beginning of each page and line
209: is marked,
210: so post-processors can do device-specific optimizations
211: such as sorting the data vertically or printing it boustrophedonically,
212: independently of
213: .UC TROFF .
214: .PP
215: Since actual output is done by a post-processor,
216: not
217: .UC TROFF ,
218: new capabilities for graphics have been easy to add.
219: .UC TROFF
220: now recognizes commands for drawing diagonal lines,
221: circles, ellipses, circular arcs,
222: and quadratic B-splines;
223: these are used in the
224: PIC
225: .[
226: %A Brian W. Kernighan
227: %T PIC \(em A Crude Graphics Language for Typesetting
228: %R Comp. Sci. Tech. Rep. 85
229: %I Bell Laboratories
230: %C Murray Hill, NJ
231: %O Also in SIGPLAN Symposium on Text Manipulation, Portland, June 1981.
232: .]
233: and
234: IDEAL
235: .[
236: %A Christopher J. Van Wyk
237: %T A Graphics Typesetting Language
238: %R SIGPLAN Symposium on Text Manipulation, Portland
239: %D June, 1981
240: .]
241: languages.
242: .PP
243: A number of limitations have been eased or eliminated.
244: A document may have an arbitrary number of fonts on any page
245: (if the output device permits it, of course).
246: Fonts may be accessed merely by naming them;
247: ``mounting'' is no longer necessary.
248: Character \H'8'height\H'10' and \S'-10'sl\S'0'a\S'10'nt\S'0' may be set
249: independently of width.
250: .PP
251: The new
252: .UC TROFF
253: is about 1000 bytes larger in instruction space
254: and 13000 bytes larger in data space
255: (thus guaranteeing that it will not run on
256: PDP-11/40 style machines).
257: It runs about as fast as the original version,
258: though
259: a simple improvement that I made could be retrofitted into
260: the earlier version to keep it about 20% faster.
261: The post-processors are not included in these time comparisons;
262: they typically take 10-20% of the
263: .UC TROFF
264: time.
265: .NH
266: Typesetter Dependencies
267: .PP
268: .UC TROFF
269: turns out to be surprisingly dependent on
270: the Graphic Systems CAT,
271: not just in the code but in its design.
272: .PP
273: Some of the design dependencies are pretty obvious.
274: For example, the CAT provides four fonts
275: (of 102 characters each) and 15 sizes.
276: The specific sizes
277: are wired into the syntax of the language:
278: since the CAT has no sizes larger than 36 points,
279: .CW \es46
280: can be uniquely decoded as a 4-point
281: .CW 6 ,
282: while
283: .CW \es36
284: is simply a switch into size 36.
285: .PP
286: .UC TROFF
287: makes the assumption that there are four fonts,
288: three of which are physically isomorphic
289: (that is, the same characters appear in the same position in each)
290: and one ``special'' font
291: that is logically a part of each of the others.
292: The reserved font name
293: .CW S
294: finds its way into several commands
295: and receives special treatment in a variety of contexts.
296: .PP
297: Some commands have the basic resolution of the
298: CAT wired into their definition;
299: for example, the units of the
300: .CW .ss
301: command (which sets the size of the inter-word spacing)
302: are 36th's of an em,
303: because the CAT typesetter itself works in those units.
304: .PP
305: Some command line options reflect idiosyncrasies of the CAT.
306: For example, the option
307: .CW -p
308: requests that the output all be printed in one size;
309: since the CAT is excruciatingly slow at changing point sizes,
310: this
311: prints an approximation to final output
312: comparatively quickly.
313: The
314: .CW -g
315: option causes font information to appear in the output file
316: for the benefit of the operations staff at the Murray Hill
317: Computer Center.
318: .PP
319: At the same time,
320: there are myriad places
321: where the characteristics of the CAT are an integral part of
322: the code for
323: .UC TROFF .
324: Some of these are quite evident;
325: others are subtle indeed.
326: .PP
327: The most obvious instance is the internal encoding of
328: a character.
329: Within
330: .UC TROFF ,
331: objects are passed around as 16 bit quantities.
332: There are two fundamental objects \(em
333: printable characters and motions.
334: An object looks like this:
335: .TS
336: center;
337: cw(2) cw(8) cw(4) cw(2) cw(16)
338: |c0|c0|c0|c0|c0|.
339: 1 4 2 1 8
340: _
341: .ft CW
342: m s f z c
343: .ft
344: _
345: .TE
346: If the
347: .CW m
348: bit is a 1, the object represents a motion;
349: if it is zero, the object is something to be printed.
350: In that case,
351: .CW s
352: is the size (actually an index into a table of legal sizes),
353: .CW f
354: is the font,
355: .CW z
356: is the zero-motion bit
357: (i.e., no space after printing),
358: and
359: .CW c
360: is the character.
361: If the high order bit of
362: .CW c
363: is set,
364: the character is to be looked up in a table of
365: special names
366: (for example,
367: .CW 0200
368: is the hyphen
369: .CW \e(hy );
370: otherwise it is
371: .UC ASCII .
372: Furthermore,
373: if
374: .CW c
375: is less than octal 40 or greater than octal 370,
376: the character is actually some encoded control function
377: or very special character
378: such as
379: .CW \ee
380: or
381: .CW \e{ .
382: .PP
383: Clearly the tight packing makes it utterly impossible
384: to add another size or font \(em
385: there are no bits left over.
386: It also implies limits on the number of characters
387: in a font and on the number of special names
388: (names of the form
389: .CW \e(xx ).
390: .PP
391: Motions are encoded as
392: .TS
393: center;
394: cw(2) cw(2) cw(2) cw(26)
395: |c0|c0|c0|c0|.
396: 1 1 1 13
397: _
398: .ft CW
399: m v n mag
400: .ft
401: _
402: .TE
403: .CW m
404: is the ``motion bit'', which is 1 for a motion,
405: .CW v
406: is 1 for a vertical motion,
407: and
408: .CW n
409: is 1 for a negative motion.
410: The remaining 13 bits give the magnitude.
411: Since there are only 13 bits,
412: the maximum amount of motion is
413: 8191 machine units.
414: With the CAT's resolution of 432 units per inch,
415: this is a generous 19 inches.
416: But for the Linotron 202 (resolution 972/inch),
417: it is only 8.5 inches.
418: .PP
419: Within the code,
420: certain character values are used in tests and assignments
421: without identification.
422: For instance the octal value
423: .CW 0200
424: is used (without identification) as a hyphen.
425: But of course the mask
426: .CW 0200
427: also occurs many times.
428: As might be imagined, it takes some study to determine whether
429: any particular
430: .CW 0200
431: is a hyphen or a mask.
432: .PP
433: The basic resolution of the CAT is 432 units per inch
434: horizontally and 144 vertically.
435: Character widths are given as the number of units at size 6 points.
436: There are 72 points in an inch.
437: Thus the program contains as magic numbers
438: every factor of 432,
439: and \(+-1 from each factor as well.
440: .PP
441: Finally,
442: .UC TROFF
443: is simply a big program (at least by my standards) \(em
444: about 7000 lines of virtually uncommented C.
445: (I am indebted to Lorinda Cherry for a new version of the C beautifier
446: that made
447: the code legible, if not comprehensible.)
448: It was implemented before the recent additions to C,
449: so there are no
450: .CW typedef 's
451: to distinguish among the various kinds of integers,
452: relatively few macros with arguments,
453: no internal
454: .CW static
455: variables,
456: and a startling number of global variables
457: with two-character names.
458: .PP
459: None of these remarks should be taken as denigrating
460: Ossanna's accomplishment with
461: .UC TROFF .
462: It has proven a remarkably robust tool,
463: taking unbelievable abuse from a variety of preprocessors
464: and being forced into uses that were never conceived of
465: in the original design,
466: all with considerable grace under fire.
467: .NH
468: Modifying TROFF
469: .PP
470: The first step was to widen the 16-bit internal representation of a character
471: to 32 bits, to accommodate more sizes and fonts.
472: The current representation is
473: .TS
474: center;
475: cw(2) cw(14) cw(16) cw(2) cw(30)
476: |c0|c0|c0|c0|c0|.
477: 1 7 8 1 15
478: _
479: .ft CW
480: z s f m c
481: .ft
482: _
483: .TE
484: If
485: .CW m
486: is 1, bits 16 and 17 are
487: .CW v
488: and
489: .CW n .
490: Access to this representation is entirely through
491: macros;
492: for example, a macro called
493: .CW cbits
494: fetches the character bits,
495: another called
496: .CW setsfbits
497: sets the size and font bits, and so on.
498: .PP
499: This stage took several weeks of meticulous checking,
500: since it was necessary to examine every integer
501: constant, variable and function in the program
502: to decide whether it was being used to store
503: an internal character.
504: These are now all identified and
505: .CW typedef 'd
506: for future reference.
507: .PP
508: Widening 16 bits to 32 turns out to be quite costly on the PDP-11,
509: since the program must process
510: .CW long
511: integers instead of short ones.
512: The result is approximately a 25% increase in program size
513: and perhaps 25% increase in run time.
514: Furthermore the temporary file in which
515: .UC TROFF
516: keeps its macro and string definitions doubles in size
517: (to 256k bytes).
518: .PP
519: Note that at this stage the program has not been changed in any fundamental
520: way \(em
521: it still generates CAT output,
522: so a bit-for-bit regression test against the original version can be performed after each change.
523: This proved to be very important for maintaining sanity
524: in both program and programmer.
525: .NH
526: Dynamic Machine Parameters
527: .PP
528: The next step was to find all the the numbers in the program that depend
529: on the CAT and replace them by variables.
530: This also contributed marginally to slower execution,
531: since many values and expressions that were constants now became variables.
532: .PP
533: With parameters identified as such,
534: the next step was
535: to make it possible to load a description of
536: the typesetter each time
537: .UC TROFF
538: is run, rather than creating a compiled version for each typesetter.
539: Accordingly, a set of description files was designed and created
540: for each typesetter and each font.
541: The description really comes in two pieces \(em
542: a table describing parameters of the machine,
543: and a table of widths for each font.
544: To illustrate, here is the parameter file for the CAT:
545: .P1 .2i
546: # Graphic Systems CAT-4
547: res 432
548: hor 1
549: vert 3
550: unitwidth 6
551: sizes 6 7 8 9 10 11 12 14 16 18 20 22 24 28 36 0
552: fonts 4 R I B S
553: charset
554: \e| \e^ \e- \e_
555: hy bu sq em ru 14 12 34 mi fi fl ff Fi Fl de dg sc fm aa ga
556: ul sl *a *b *g *d *e *z *y *h *i *k *l *m *n *c *o *p *r *s
557: *t *u *f *x *q *w *A *B *G *D *E *Z *Y *H *I *K *L *M *N *C
558: *O *P *R *S *T *U *F *X *Q *W sr ts rn >= <= == ~= ap != ->
559: <- ua da eq mu di +- cu ca sb sp ib ip if pd gr no is pt es
560: mo pl rg co br ct dd rh lh ** bs or ci lt lb rt rb lk rk bv
561: lf rf lc rc
562: .P2
563: A
564: .CW #
565: introduces a comment.
566: .CW res
567: is the machine resolution in units per inch.
568: .CW hor
569: and
570: .CW vert
571: give the minimum number of machine units that it is possible
572: to move in the corresponding direction.
573: .CW unitwidth
574: specifies the point size at which the character widths map directly
575: into machine units.
576: .CW sizes
577: lists the set of legal point sizes,
578: terminated by a zero.
579: .CW fonts
580: lists the default set of fonts
581: (which can be overridden by subsequent
582: .CW .fp
583: commands).
584: .CW charset
585: introduces the set of legitimate special names
586: (names of the form
587: .CW \e(xx ,
588: including some special cases like
589: .CW \e| ).
590: .PP
591: For comparison, here is the description file for the
592: Mergenthaler Linotron 202.
593: The 202 has many more sizes and fonts than the CAT,
594: and quite a few more characters as well.
595: (The 202 actually permits nearly 250 sizes;
596: no use has yet been found for most of them.)
597: .P1
598: # Mergenthaler Linotron 202
599: fonts 10 R I B BI H HB HK PO CH S
600: sizes 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
601: 21 22 23 24 25 26 27 28 29 30 32 34 36 38 40
602: 45 50 55 60 66 72 78 84 90 96 102 108 0
603: res 972
604: hor 1
605: vert 2
606: unitwidth 4
607: paperwidth 7500
608: charset
609: \e| \e^ \e- \e_
610: ** *C *D *F *G *H *L *P *Q *S *W *a *b *c *d *e *f *g *h
611: *i *k *l *m *n *p *q *r *s *t *w *x *y *z +- -> <- <=
612: == >= L. Sl al aa ap b0 br bs bu bv ca
613: cd ci co ct cu dd de dg di em eq es fe fm ga gr hy
614: ib if ip is l. lh ma mi mo mu no or pd pl pp pt rg rh ru
615: sb sc sl sp sq sr tm tp ts ~= ~~ ul rn en
616: lf rf lc rc lt rt lb rb lk rk != ua da 12 fa te ma fe
617: hc .. ob bx *o *u b9 14 34 ss vr
618: .P2
619: .CW paperwidth
620: specifies the maximum width of paper in units,
621: overriding the default 7\(34".
622: .PP
623: In addition to this description file (one per typesetter),
624: there is one file per font that lists properties of that font.
625: Here is part of the description of Times Roman
626: for the CAT:
627: .P1
628: # Times Roman for CAT-4
629: name R
630: internalname 1
631: ligatures ff fi fl ffi ffl 0
632: charset
633: \e| 6 0 0
634: \e^ 3 0 0
635: a 17 0 025
636: b 20 2 012
637: c 16 0 027
638: d 20 2 011
639: e 18 0 031
640: f 13 2 014
641: \&...
642: ! 12 2 0145
643: & 28 2 050
644: ( 16 2 0132
645: ) 16 2 0133
646: * 16 0 0122
647: + 36 0 0143
648: , 12 0 047
649: hy 13 0 040 hyphen
650: - " =hy
651: \e- 36 0 0123
652: \&. 10 0 044
653: de 15 0 0136 degree
654: dg 20 0 0137 dagger
655: fm 8 0 0150
656: rg 20 0 0141
657: co 20 0 0153
658: ct 19 0 0127
659: \&...
660: .P2
661: .PP
662: The
663: .CW name
664: is the external
665: .UC TROFF
666: name, one or two characters,
667: as used in
668: .CW .ft
669: and
670: .CW \ef
671: commands.
672: The internal name is not used by
673: .UC TROFF
674: itself, but is necessary for the postprocessors.
675: If the font has
676: ligatures, they are listed.
677: It is possible to set the width of the space for each font
678: separately with the
679: .CW spacewidth
680: command,
681: not illustrated here.
682: There is also a keyword
683: .CW special
684: to indicate that the font is a ``special'' font \(em
685: one that is to be searched if the regular font
686: does not contain the character requested.
687: There is no limit on the number of special fonts,
688: but they should be listed last in the
689: .CW fonts
690: part of the description file.
691: .PP
692: The four columns of data are
693: the character name,
694: its width,
695: its ascender/descender information
696: (1 \(-> descender, 2 \(-> ascender, 3 \(-> both),
697: and the actual typesetter code required to print it.
698: When the point size is
699: .CW unitwidth ,
700: the width
701: is the character width in machine units.
702: If the name is a single character,
703: it is taken simply as a normal
704: .UC ASCII
705: character.
706: Two or more characters
707: indicate a name of the form
708: .CW \e(xx ;
709: there are a handful of historical exceptions like
710: .CW \e- .
711: A width of
712: .CW \&"
713: indicates that the character is a synonym for the
714: immediately preceding character,
715: as in
716: .CW -
717: and
718: .CW hy
719: above.
720: Comments may follow the four data fields.
721: .PP
722: There are significant advantages to having the font and typesetter
723: descriptions merely text files that can be edited easily,
724: but it is too time-consuming to load all this
725: .UC ASCII
726: information
727: each time
728: .UC TROFF
729: is invoked.
730: Thus a separate program called
731: .CW makedev
732: is used to compile
733: it into a binary file that can be read by
734: .UC TROFF
735: in a single read.
736: When
737: .UC TROFF
738: is invoked,
739: an argument of the form
740: .CW -Txxx
741: tells it to load the description file for typesetter
742: .CW xxx
743: from a standard directory.
744: .PP
745: Descriptions for the default fonts are compiled into the description file;
746: if a new font is requested by a
747: .CW .fp
748: command,
749: its description data replaces the original values.
750: The
751: .CW .ft
752: command has been modified so that if the requested font
753: is not currently ``mounted'',
754: its description data will be placed in the hidden
755: font position 0.
756: Since there is only one such position,
757: each new non-standard font overlays the previous one.
758: This mechanism is intended to make
759: occasional use of non-standard fonts easy;
760: the
761: .CW .fp
762: mechanism remains necessary for other purposes.
763: .PP
764: The notion of special fonts has been generalized somewhat \(em
765: rather than a single special font,
766: there can be several.
767: The algorithm currently used is to search for each character
768: on the current font;
769: if it is not found there, then the special fonts are searched
770: in order (as given in the description file).
771: Other than that,
772: the treatment of special fonts is essentially unchanged.
773: .PP
774: At this stage in the modifications to
775: .UC TROFF ,
776: all internal arithmetic is done in terms of
777: the resolution of the specified typesetter.
778: The character set and character widths are defined by
779: the values loaded from the font description.
780: Indeed, the mapping from character name to what gets printed
781: is determined by this table \(em
782: fonts are no longer all isomorphic.
783: .PP
784: Although it is certainly convenient for testing during
785: program development,
786: it is not clear that loading the font information for
787: the typesetter each time
788: .UC TROFF
789: is invoked is the right way to operate in an environment
790: that supports only a single kind of typesetter.
791: In a production mode it might be desirable to compile in
792: the default information for the standard typesetter.
793: .NH
794: Output Language
795: .PP
796: The final step is to modify the output of
797: .UC TROFF
798: so that it is typesetter-independent.
799: The new version of
800: .UC TROFF
801: produces output that is not intended to go directly to
802: a typesetter.
803: Rather, it is more or less independent of any typesetter,
804: except that the numbers in it have been computed on the
805: basis of the resolution specified in the description
806: file for the intended typesetter.
807: .PP
808: The output language is simple:
809: .P1
810: .ta .7i
811: s\f2n\fP size in points
812: f\f2n\fP font as number from 1 to \f2n\fP
813: c\f2x\fP ASCII character \f2x\fP
814: C\f2xy\fP character \e(\f2xy\fP; terminate \f2xy\fP by white space
815: H\f2n\fP go to absolute horizontal position \f2n\fP. (\f2n\fP > 0)
816: V\f2n\fP go to absolute vertical position \f2n\fP (down is positive)
817: h\f2n\fP go \f2n\fP units horizontally (to the right; \f2n\fP > 0)
818: v\f2n\fP go \f2n\fP units vertically (down; \f2n\fP > 0)
819: \f2nnc\fP move right \f2nn\fP, then print \f2c\fP (\f2nn\fP is exactly 2 digits!)
820: n\f2b a\fP end of line (information only -- no action needed)
821: \f2b\fP = space before line, \f2a\fP = after
822: w paddable word space (information only -- no action needed)
823: p\f2n\fP new page \f2n\fP begins -- set V to 0
824: x ...\en device control functions
825: D ...\en drawing functions (graphics)
826: .P2
827: Encoding small horizontal motions followed by a character as
828: .I nnc
829: shrinks the output file size by about 35%
830: and run-time by about 15%.
831: .PP
832: The device control and graphics commands are intended as open-ended
833: families, to be expanded as needed.
834: .P1
835: .ta .7i
836: x i init
837: x T \f2s\fP name of typesetter is \f2s\fP
838: x r \f2n h v\fP resolution is \f2n\fP/inch, \f2h\fP = minimum horizontal motion, \f2v\fP = min vert
839: x p pause (can restart)
840: x s stop -- done forever
841: x t generate trailer
842: x f \f2n s\fP font position \f2n\fP contains font \f2s\fP
843: x H \f2n\fP set character height to \f2n\fP
844: x S \f2n\fP set slant to \f2n\fP
845: .P2
846: Subcommands like
847: .CW i '' ``
848: are often spelled out like
849: .CW init ''. ``
850: .PP
851: The drawing functions are
852: .P1
853: .ta 1i
854: Dl \f2dh dv\fP draw line from current position by \f2dh dv\fP
855: Dc \f2d\fP draw circle of diameter \f2d\fP with left side here
856: De \f2d1 d2\fP draw ellipse of diameters \f2d1 d2\fP
857: Da \f2dh1 dv1 dh2 dv2\fP
858: draw arc from current position to \f2dh1+dh2 dv1+dv2\fP,
859: center at \f2dh1 dv1\fP from current position
860: D~ \f2dh1 dv1 dh2 dv2 ...\fP
861: draw B-spline from current position to \f2dh1 dv1\fP,
862: then to \f2dh2 dv2\fP, then to ...
863: .P2
864: In all of these, \f2dh dv\fP is an increment on the current horizontal and
865: vertical position,
866: with down and right positive.
867: .PP
868: Blanks, tabs and newlines may occur as separators
869: in the input, and are mandatory to separate constructions
870: that would otherwise be confused.
871: .PP
872: To illustrate, the following is the output from the input
873: .P1
874: hello
875: \&.br
876: \&.ps 20
877: \&.ft H
878: goodbye
879: .P2
880: using
881: .CW -Tcat :
882: .P1
883: x T cat
884: x res 432 1 3
885: x init
886: x font 1 R
887: x font 2 I
888: x font 3 B
889: x font 4 S
890: V0
891: p1
892: s10
893: f1
894: H416
895: V72
896: ch
897: 35e30l17l17on72 0
898: x font 0 H
899: f1
900: H416
901: f0
902: s20
903: V144
904: cg
905: 70o70o70d73b73y67en72 0
906: x trailer
907: V4752
908: x stop
909: .P2
910: Here is the same output from the 202.
911: Notice how the numbers are more than twice as big,
912: reflecting the higher resolution of the 202.
913: Also notice that the font
914: .CW H
915: is a standard font on the 202 so no special loading is needed
916: to switch to it.
917: .P1
918: x T 202
919: x res 972 1 2
920: x init
921: x font 1 R
922: x font 2 I
923: x font 3 B
924: x font 4 BI
925: x font 5 H
926: x font 6 HB
927: x font 7 HK
928: x font 8 PO
929: x font 9 CH
930: x font 10 S
931: V0
932: p1
933: s10
934: f1
935: H936
936: V156
937: ch
938: 73e63l35l35on156 0
939: H936
940: f5
941: s20
942: V312
943: cg
944: h150co
945: h150co
946: h150cd
947: h150cb
948: h150cy
949: h135ce
950: n156 0
951: x trailer
952: V10692
953: x stop
954: .P2
955: .PP
956: The output is guaranteed to be
957: .UC ASCII ,
958: and thus amenable to processing by all the normal
959: Unix
960: tools.
961: The language is simple \(em
962: it is straightforward to write a prototype driver
963: for a particular typesetter,
964: especially when one can steal an existing one
965: as a model,
966: although it may take some effort to make one of production quality.
967: This form also demystifies
968: .UC TROFF
969: output
970: and makes it possible for anyone to write other programs
971: to process or generate it.
972: .PP
973: On the other hand,
974: it is about twice as voluminous as the output intended for
975: the CAT.
976: Cleverness (or sacrificing
977: .UC ASCII -ness)
978: could bring
979: it down to not much more than one byte per character printed,
980: but so far I have not felt this to be very important.
981: .PP
982: There is not really much to say about the post-processors.
983: .UC D202
984: drives the 202,
985: .UC DCAT
986: drives the CAT (although not very efficiently \(em
987: the vital boustrophedon and size-sorting features are not there),
988: .UC DAPS
989: drives the APS-5,
990: .UC DCAN
991: drives the Canon,
992: and
993: .UC TC
994: (notice the parallel name structure)
995: drives the Tektronix 4014.
996: There are also rough and ready drivers for other display terminals.
997: .PP
998: Since it is easy to identify page and line boundaries,
999: some drivers are able to offer useful features
1000: that were not feasible with the older
1001: .UC TROFF .
1002: For example,
1003: .UC TC
1004: permits the user to ask for specific pages by number,
1005: and to skip back and forth in the document.
1006: .UC D202
1007: displays the output page number on the operator's control panel and will also
1008: stop at specified pages if requested.
1009: An experimental postprocessor
1010: called
1011: .UC DSORT
1012: sorts the intermediate language by vertical position,
1013: to minimize vertical motion;
1014: it is intended for printing complicated
1015: .UC PIC
1016: diagrams and for circuit diagrams produced by
1017: .UC PLTROFF .
1018: .UC PLTROFF \& (
1019: converts the standard Unix
1020: plot language into
1021: .UC TROFF
1022: commands.)
1023: All of the post-processors can scan their input relatively quickly
1024: to print only selected pages.
1025: .NH
1026: New Things
1027: .PP
1028: During the process of making these changes to
1029: .UC TROFF ,
1030: I have made some changes to the program
1031: that are visible to users
1032: (thus violating the avowed goal of keeping it compatible).
1033: .PP
1034: Some changes are simply the easing of restrictions.
1035: For example,
1036: there is no longer any limit on the number of fonts
1037: that can occur on a page
1038: (if one's typesetter is up to it),
1039: nor does the
1040: .CW .fp
1041: command that requests ``mounting'' a new font
1042: have to occur only at the beginning.
1043: Furthermore, a font may be accessed merely by naming it \(em
1044: the command
1045: .P1
1046: \ef(ARBell Laboratories\efP
1047: .P2
1048: will produce
1049: .P1
1050: \f(ARBell Laboratories\fP
1051: .P2
1052: (The font
1053: .CW AR
1054: is Avant-Garde Book.
1055: Obviously two-letter font names will have to go.)
1056: .PP
1057: Character sets can be sensibly defined
1058: since they no longer have to all be isomorphic.
1059: Thus, for example, on the 202 the ``printout'' font
1060: .P1
1061: This one
1062: .P2
1063: includes a complete
1064: .UC ASCII
1065: alphabet.
1066: All of the characters have the same width,
1067: even the word space
1068: (defined by the
1069: .CW spacewidth
1070: attribute in the font description file).
1071: Thus this font is suitable for printing program listings
1072: without any special precautions.
1073: On the other hand,
1074: some fonts are rather small,
1075: containing only a handful of characters.
1076: .PP
1077: Larger and smaller point sizes are available,
1078: although there are still some limitations.
1079: For example,
1080: .CW \es72
1081: is still parsed as a 7 point
1082: .CW 2 ,
1083: since changing this would affect at least
1084: .UC EQN
1085: and probably other programs as well.
1086: (Sadly,
1087: .UC EQN
1088: had to be changed
1089: anyway \(em
1090: it also accepts an option of the form
1091: .CW -Txxx .)
1092: But
1093: .CW .ps\ 72
1094: works fine:
1095: each input size is mapped into the closest legal size
1096: for the current typesetter.
1097: Fractional point sizes are not allowed
1098: and may never be.
1099: .PP
1100: Character height and slant may be set independently of character
1101: width, for those typesetters that allow these operations.
1102: .CW \eH'n'
1103: sets the character height to
1104: .CW n
1105: points,
1106: .CW \eH'\(+-n'
1107: sets it to
1108: .CW \(+-n
1109: from the current point size,
1110: and
1111: .CW \eH'0'
1112: restores it to normal height.
1113: .CW \eS'n'
1114: sets the slant to
1115: .CW n
1116: degrees positive or negative;
1117: if
1118: .CW n
1119: is zero, slanting is turned off.
1120: .PP
1121: Some obsolete commands have been eliminated
1122: (e.g.,
1123: .CW .fz ,
1124: .CW .li ;
1125: the command line options for constant-size printing and
1126: suppressing boustrophedon;
1127: all code related to
1128: .UC GCOS ).
1129: .PP
1130: A new command
1131: .CW .sy
1132: has been added to permit calling another program from
1133: within
1134: .UC TROFF :
1135: .P1
1136: \&.sy \f2command line \fP
1137: .P2
1138: causes
1139: .I "command line"
1140: to be executed.
1141: The output is
1142: .I not
1143: automatically collected anywhere,
1144: but the new number register
1145: .CW \en($$
1146: (the process id of the
1147: .UC TROFF
1148: process)
1149: can be used
1150: to create unique file names
1151: to be picked up with subsequent
1152: .CW .so
1153: commands.
1154: The built-in string
1155: .CW \e*(.T
1156: contains the name of the current typesetter
1157: obtained from the
1158: .CW -T
1159: argument or its default.
1160: .NH
1161: Graphics Commands
1162: .PP
1163: The most significant new facility is the ability to draw
1164: simple graphical objects
1165: \(em diagonal lines, circles, ellipses, arcs, and splines \(em
1166: in
1167: .UC TROFF .
1168: .PP
1169: The new graphical commands are
1170: .P1
1171: .ta 1i
1172: \eD'l\f2 dh dv\fP' draw line from current position by \f2dh, dv\fP
1173: \eD'c\f2 d\fP' draw circle of diameter \f2d\fP with left side at current position
1174: \eD'e\f2 d1 d2\fP' draw ellipse of diameters \f2d1 d2\fP
1175: \eD'a\f2 dh1 dv1 dh2 dv2\fP'
1176: draw arc from current position to \f2dh1+dh2 dv1+dv2\fP,
1177: with center at \f2dh1 dv1\fP from current position
1178: \eD'~\f2 dh1 dv1 dh2 dv2 ...\fP'
1179: draw B-spline from current position by \f2dh1 dv1\fP
1180: then by \f2dh2 dv2\fP, then by \f2dh2, dv2\fP, then ...
1181: .P2
1182: For example, the input
1183: .CW "\eD'e0.2i 0.1i'"
1184: draws the ellipse
1185: \D'e.2i .1i'\|,
1186: and the input
1187: .CW "\eD'l.2i -.1i'\eD'l.1i .1i'"
1188: will draw the line
1189: \D'l.2i -.1i'\D'l.1i .1i'\|.
1190: The position after a graphical object has been drawn is
1191: at its ``end'', where for circles and ellipses, the end
1192: is at the right side.
1193: As with other commands,
1194: default units are ems horizontally and line spaces vertically.
1195: .PP
1196: Realistically, these commands are not intended for direct use,
1197: but for preprocessors like
1198: .UC PIC
1199: and
1200: .UC IDEAL .
1201: .PP
1202: The output generated by these commands is shown in the
1203: discussion of
1204: the
1205: .UC TROFF
1206: output language in an earlier section.
1207: Rather than drawing the shape in
1208: .UC TROFF ,
1209: a command with the proper parameters is passed through to the device
1210: post-processor,
1211: which does whatever it can with the request.
1212: .NH
1213: Loose Ends
1214: .PP
1215: This version of
1216: .UC TROFF
1217: has been in use
1218: since September of 1979.
1219: Most of our experience with it has been on the
1220: 202 and Tektronix scopes, but the CAT and APS-5 drivers have been
1221: exercised to some degree.
1222: .PP
1223: As mentioned, there are some obvious things that could
1224: be improved or that remain to be added.
1225: For instance,
1226: .UC TROFF 's
1227: bracket-building function
1228: .CW \eb
1229: really ought to be implemented by postprocessor,
1230: so that typesetters like the 202 can draw a character like
1231: \v'1'\H'48'{\H'10'\v'-1' directly instead of synthesizing it from pieces.
1232: It also appears to be necessary to add ``modes''
1233: to permit graphical objects to be dotted, dashed, etc.
1234: .PP
1235: Efficiency is always a problem,
1236: and is likely to be so forever,
1237: especially with the proliferation of preprocessors
1238: generating ever more complicated input.
1239: Small improvements (perhaps 10 percent)
1240: can be had from artifices like better table searching.
1241: Placing the temporary file upon which
1242: .UC TROFF
1243: stores macro definitions in memory is good for another 10-20 percent
1244: on machines like the
1245: .UC VAX
1246: that have enough memory.
1247: But no order-of-magnitude speedup is likely without a gross revision
1248: of the basic design.
1249: .PP
1250: It is clear that
1251: .UC TROFF
1252: ought to be replaced by something better,
1253: but, as I said above,
1254: it is far from clear how to do the job
1255: a lot better.
1256: So for better or worse,
1257: .UC TROFF
1258: is likely to be with us for a long time.
1259: .SH
1260: Acknowledgements
1261: .PP
1262: I am deeply indebted to Ken Thompson and Joe Condon,
1263: without whose efforts in taming the Mergenthaler Linotron 202
1264: the
1265: .UC TROFF
1266: modifications discussed here would be irrelevant.
1267: Thompson also provided most of the character-generating software.
1268: I am also grateful to Chris Van Wyk for the line and circle drawing
1269: algorithms and to Theo Pavlidis for the spline algorithm
1270: used by all the postprocessors.
1271: .[
1272: $LIST$
1273: .]
1274: .sp 100
1275: .SH
1276: Appendix: Summary of Language Changes
1277: .PP
1278: This appendix enumerates the changes to the
1279: .UC TROFF
1280: language since the last printing of
1281: the
1282: manual.
1283: .SH
1284: Command line arguments
1285: .PP
1286: The argument
1287: .CW -Txxx
1288: loads parameters and character definitions for typesetter
1289: .CW xxx ,
1290: which at the moment is typically one of
1291: .CW 202 ,
1292: .CW aps
1293: or
1294: .CW cat .
1295: .PP
1296: .CW -Fxxx
1297: causes font information to be loaded from
1298: directory
1299: .CW xxx
1300: instead of the default
1301: .CW /usr/lib/font/dev202 .
1302: .SH
1303: Graphics commands
1304: .PP
1305: As described in section 7.
1306: .SH
1307: Other new commands
1308: .PP
1309: .CW .sy
1310: .I commandline
1311: executes the command, then returns.
1312: Output is not captured anyplace.
1313: .PP
1314: .CW .cf
1315: .I file
1316: copies
1317: .I file
1318: into the
1319: .UC TROFF
1320: output file at this point, uninterpreted.
1321: Havoc ensues unless the motions in the file
1322: restore current horizontal and vertical position.
1323: This command hasn't been used much,
1324: and is probably a bad idea anyway.
1325: .PP
1326: .CW .pi
1327: .I program
1328: (pipe the output into
1329: .I program )
1330: now works in
1331: .UC TROFF
1332: as well as
1333: .UC NROFF ,
1334: since it makes somewhat more sense to allow it.
1335: .PP
1336: .CW \eH'n'
1337: sets the character height to
1338: .CW n
1339: points.
1340: A height of the form
1341: .I \(+-n
1342: is an increment on the current point size;
1343: a height of zero restores the height to the point size.
1344: .PP
1345: .CW \eS'n'
1346: sets the slant to
1347: .CW n
1348: degrees.
1349: .I n
1350: may be negative.
1351: .PP
1352: The number register
1353: .CW $$
1354: contains the process id of the
1355: .UC TROFF
1356: process.
1357: .PP
1358: The string
1359: .CW .T
1360: contains the name of the current typesetter
1361: (e.g.,
1362: .CW 202 ,
1363: .CW aps ,
1364: .CW cat ).
1365: .PP
1366: The
1367: .CW .fp
1368: command accepts a third argument that causes the
1369: data for the font to be loaded from that directory.
1370: This has been added as a first step to allowing dynamic character definitions.
1371: .PP
1372: The
1373: .CW .ft
1374: command causes the named font to be loaded on font position 0
1375: (which is in all other ways inaccessible) if the font exists and is not currently mounted
1376: by default or by
1377: a
1378: .CW .fp
1379: command.
1380: The font must be still or again in position 0 when the line is printed.
1381: .PP
1382: Transparent mode
1383: .CW \e! ) (
1384: has been fixed so that transparent output actually appears
1385: in the output;
1386: thus special commands can be passed through to postprocessors
1387: by witchcraft like
1388: .P1
1389: \&.if "\e*(.T"202" \e!x ...
1390: .P2
1391: (If this makes no sense to you,
1392: you shouldn't be using it anyway.)
1393: .SH
1394: Deletions
1395: .PP
1396: The
1397: .CW .fz
1398: and
1399: .CW .li
1400: commands are no more.
1401: The
1402: .CW -p ,
1403: .CW -g
1404: and
1405: .CW +n
1406: command line arguments have also been eliminated,
1407: as has the
1408: .CW hp
1409: number register.
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.