neatroff.ms: neatmkfn/gen.sh no longer converts OTF to TTF
[neatroff_make.git] / demo / neatroff.ms
blob4bd9346bdfda3fa48aa81601f07ad742d7065a04
1 .\" PSTITLE: Neatroff Introduction
2 .so neat__.ms
3 .ds en.cl "#237
4 .post.info Title "Neatroff Introduction"
5 .post.info Author "Ali Gholami Rudi"
6 .de MH
7 .       sp
8 .       LP
9 .       ne 2
10 \m[#237]\fI\\$1\fP\m[]
11 .       IP
13 .de NR
14 .       sp
15 .       LP
16 .       ne 2
17 .       ta 4.5i 6iR
18 .       nf
19 .       lg 0
20 \f(CB\m[#237]\\$1\m0\fP \s-3\m[#237]\fB\\$2\fP  \fB\\$4\m0\fP
21 .       lg 1
22 .       IP
24 .HD
25 .TL
26 \s+8Neatroff\m0\s-8
27 .AU
28 \fIAli Gholami Rudi\fP
29 .ce
30 \s-3\fIUpdated in April 2018\s+3\fP\&
31 .sp 3
32 Neatroff is a new implementation of Troff typesetting system in C
33 programming language, which tries to address, as neatly as possible,
34 some of the shortcomings of the original Troff based on the ideas and
35 features available in Plan 9 Troff, Heirloom Troff, and Groff.
36 The latest versions of Neatroff, its PostScript and PDF post-processor,
37 Neatpost, and its eqn preprocessor, Neateqn,
38 are available at their home page (\*[post.url http://litcave.rudi.ir/ link]).
39 This document enumerates Neatroff's features, its new requests, and
40 its differences compared to other Troff implementations.  On the other
41 hand, the document \(lqGetting Started with Neatroff\(rq
42 (\*[post.url http://litcave.rudi.ir/neatstart.pdf link])
43 explains how to set up and use Neatroff.
45 .bp
46 .SH "Noteworthy Features"
47 The following list describes the main extensions of Neatroff compared
48 to the original Troff (many of these extensions are available in
49 Groff and Heirloom Troff as well).  The number register \&.neat,
50 which is always one in Neatroff, can be used to distinguish Neatroff
51 from other Troff implementations.
53 .MH "UTF-8 encoding
54 In Neatroff, input files and characters, glyph names, ligatures,
55 hyphenation patterns and dictionary, as well as quoted escape sequence
56 delimiters and arguments of commands like .tr, .hc, .tc, .lc, .mc, and
57 \&.fc are in UTF-8 encoding.
59 .MH "Long macro, register, and environment names
60 When not in compatibility mode (activated with -C command line option or the .cp
61 request, as in Groff), Neatroff supports long macro, register, and environment
62 names.  It also supports Groff-style escape sequences with long arguments
63 (for \\[], \\*[], \\$[], \\f[], \\g[], \\k[], \\m[], \\n[], and \\s[])
64 and interpolating string registers with arguments (\\*[xyz arg1 arg2 ...]).
65 Note that like Groff, Neatroff supports named environments and
66 is not limited to original Troff's three fixed environments.
68 .MH "Advanced font features, ligature, and pairwise kerning
69 Neatroff and Neatmkfn (which generates Neatroff's font descriptions)
70 support many of the advanced font features available in OpenType
71 fonts.  In a font, a set of substitution and positioning rules may be
72 specified, which are grouped into several features and scripts.  In
73 Neatroff, features can be enabled with \&.ff and the active script and
74 language can be selected with \&.ffsc.
75 Neatmkfn supports PostScript Type 1 fonts, TrueType fonts (TTF), and
76 OpenType fonts (OTF).  For the latter, however, it cannot extract
77 glyph bounding boxes, which is used by the Neateqn preprocessor.
78 Therefore, if an OpenType font is supposed to be used in Neateqn
79 blocks, it should be converted to TrueType first.
81 .MH "Whole paragraph text formatting
82 Neatroff supports filling whole paragraphs at once, to achieve
83 more uniform word spacing.  Like Heirloom Troff, the \&.ad request
84 accepts arguments p or pb, pl, and pr, which are equivalent to b, l,
85 and r, except that the filling is done for whole paragraphs, i.e.,
86 words are collected until a line break is issued.
87 This inevitably changes the behaviour of some requests and traps: several
88 lines may be collected and ready to be output while executing them.
89 For the end macro, Troff invokes the macro specified
90 with \&.em request without flushing the last incomplete line.
91 Neatroff follows the same behaviour even when formatting whole
92 paragraphs and does not write any of the collected lines to the output.
93 Since after the end macro no new page is started, collected lines may
94 be unexpectedly written to the end of the last page of the document.
95 To change that, the end macro can invoke the \&.br request.
96 For requests that cause break, using \(aq as the control character
97 prevents writing any line of the collected paragraph to the output,
98 as expected.
99 The exception to this rule is \(aqbr, which formats the words
100 collected so far and outputs all resulting lines except the final
101 incomplete line (this is useful, for instance, for footnotes, which
102 should be inserted in the same page).
104 .MH "Paragraph formatting algorithm
105 For deciding at what points to break a paragraph into lines, Neatroff
106 assigns a cost to each possible outcome: a cost of 100 is assigned to
107 each stretchable space that has to be stretched 100 percent.  The cost
108 grows quadratically and the cost of stretching a space 200 percent is 400.
109 There are requests that adjust the algorithm Neatroff uses for
110 performing paragraph formatting.
111 The \&.hycost request changes the cost of hyphenating words.  The
112 default value is zero.
113 The \\j escape sequence, as in Heirloom Troff, specifies the extra
114 cost of line break after a word; for instance, in \(lqHello\\j'10000'
115 world\(rq, the words are not split by the line breaking algorithm,
116 unless absolutely necessary (i.e., if other options are more costly).
117 The escape sequence \\\(ti introduces non-breakable stretchable space.
118 Also, to prevent paragraphs with
119 very short last lines, the \&.pmll (paragraph minimum line length)
120 sets the minimum length of a formatted line, specified as a
121 percentage of \\n(.l; \(lq.pmll 15\(rq, for instance, ensures that
122 the length of last line of each paragraph is at least 15% of its other
123 lines; otherwise, a cost proportional to the value specified
124 as its second argument is added.
126 .MH "Controlling word spaces
127 The \&.ssh request sets the amount (in percentage) by which the
128 stretchable spaces in a line may be shrunk while formatting lines.
129 The default value is zero.
130 Also, the second
131 argument of \&.ss request specifies sentence space, as in Groff or
132 Heirloom Troff.
134 .MH "Macros and their arguments
135 In a macro, \\$* is replaced with macro's argument separated
136 by spaces.  \\$@ is like \\$*, but quotes the arguments as well.
137 \\$\(ha is like \\$@, except that it escapes the double quotes
138 in the arguments.
139 The arguments can be shifted with \&.shift request.
140 Neatroff also supports blank line macro (.blm) and
141 leading space macro (.lsm).
143 .MH "Text direction
144 Neatroff supports text direction to render right-to-left languages.
145 \&.<< and \&.>> requests specify text direction and \\< and \\> escape
146 sequences change it temporarily for including words in the reverse
147 direction.  The value of number registers \&.td and \&.cd indicate the
148 current text and temporary directions respectively; zero means
149 left-to-right and one means right-to-left.  Neatroff starts processing
150 text direction, after the first invocation of \&.<< or \&.>>.
152 .MH "Keshideh justification and cursive scripts
153 A new adjustment type (.ad k) allows inserting Keshideh characters
154 before justifying text with hyphenation and spaces.  Neatroff also
155 supports cursive scripts, which require connecting glyphs at their
156 cursive attachment positions, as defined in the fonts.
158 .MH "Font manipulation
159 In Neatroff, the mapping between Troff character names and glyphs in a
160 font can be modified with \&.fmap request: \(lq.fmap F C G\(rq
161 maps Troff character C to the glyph with device-specific name G for
162 font F.  When this glyph does not exist in F, Neatroff assumes that
163 the character C is not present in the font.  When G is missing, the
164 effect of \&.fmap for character C is cancelled.  Neatroff also implements
165 Groff's \&.fspecial and \&.fzoom requests: after \(lq.fspecial FN S1
166 S2 ...\(rq, when the current font is FN, the fonts S1, S2, ... are
167 assumed to be special.  Also, \(lq.fzoom FN zoom\(rq scales font FN by
168 the second argument after dividing it by 1000.
170 .MH "Colour support
171 Neatroff supports colours with .cl request and \\m[] escape sequence.
172 Unlike Groff, colours need not be defined beforehand and can be
173 specified directly.  The argument of \\m can be predefined colour
174 names (e.g. blue), predefined colour numbers (0 for black, 1 for red,
175 2 for green, 3 for yellow, 4 for blue, 5 for magenta, 6 for cyan, and
176 7 for white), #rgb and #rrggbb for specifying colours in hexadecimal
177 RGB format, #g and #gg for specifying grey with the given hexadecimal
178 level, and empty (\\m[]) for the previous colour.  The current colour
179 is available in \&.m number register.
181 .MH "Hyphenation language
182 The \&.hpf request loads hyphenation patterns, exceptions, and
183 character mappings from the addresses specified via its arguments.
184 The specified files should contain nothing but utf-8 patterns,
185 exceptions and mappings respectively (i.e. no TeX code), just like the
186 files whose names end with \&.pat.txt, \&.hyp.txt and \&.chr.txt in
187 CTAN for TeX (\*[post.url ftp://ftp.ctan.org/tex-archive/language/hyph-utf8/tex/generic/hyph-utf8/patterns/txt/ link]).
188 The \&.hpfa request is like \&.hpf, except that it does not clear the
189 previous hyphenation patterns and exceptions.  The second and third
190 arguments of these requests are optional.  With no arguments, these
191 requests load English hyphenation patterns and exceptions.  Also the
192 \&\(lq.hcode abcd...\(rq request, assigns the hyphenation code of b to
193 a and the hyphenation code of d to c; initially all upper-case ASCII
194 letters are mapped to their lower-case forms.
196 .MH "Filled drawing objects
197 Neatroff supports Groff-style polygons and filled drawing objects (p,
198 C, E and P commands for \\D escape sequence).  In Neatroff, however,
199 there is no specific background colour; objects are filled with the
200 current colour (.m number register).  Furthermore, in Neatroff
201 the edges of polygons can be lines, arcs, or splines; a letter among the
202 arguments of \\D'p ..' specifies the type of the subsequent
203 edges: \(oql\(cq, \(oqa\(cq, and \(oq\(ti\(cq for lines, arcs,
204 and splines respectively.
206 .MH "Conditional escape sequence
207 Neatroff supports a new escape sequence for conditional interpolation:
208 the escape sequence \\?'cond@expr1@expr2@', evaluates cond (exactly as
209 if it is a \&.if condition) and interpolates expr1, if the condition
210 is true, and expr2, otherwise.  The delimiter (@ in this example) can
211 be any character that cannot be part of the condition; for numerical
212 expressions, for instance, it cannot be a digit, an operator sign, or
213 a scale indicator, unless separated from the condition with \\&.  The
214 final delimiter, and even expr2, may be omitted, thus \\?'cond@expr'
215 is valid; Neatroff interpolates expr if cond is true.
217 .MH "Neatpost-specific device commands
218 Neatpost can produce both PostScript and PDF.  The escape sequences
219 \\X'eps img.eps [width [height]]' and \\X'pdf img.pdf [width [height]]'
220 in Neatroff instruct Neatpost to include the given EPS or PDF file;
221 the former works only when the output is PostScript and the latter
222 when the output is PDF.  They include the given EPS/PDF file with its
223 lower left corner at the current point.  If the width or height are
224 given (in basic units), the image is scaled appropriately.  Neatroff
225 also supports \\X'rotate deg' for rotating the current page around the
226 current point.
228 .MH "Helper Macro Packages
229 In addition to the standard Troff macro packages, such as -ms, -mm,
230 and -me, which are imported from Plan 9 Troff, Neatroff comes with a
231 few convenient helper macro packages as follows (these macros are
232 included in neatroff_make): for drawing simple tables without the tbl
233 preprocessor -mtbl, for including EPS and PDF images -meps, for
234 drawing simple charts and graphs -mgr, for floating objects -mkeep.
235 Some Groff-specific macros are implemented in -mgnu, such as open,
236 opena, close, write, pso, and mso.  Also, -men and -mfa include
237 -ms-like macros for creating short English and Farsi documents.
240 .SH "Summary of New Requests"
241 This is the list of new requests available in Neatroff compared
242 to those documented in \(lqTroff User's Manual\(rq by Ossanna
243 and Kernighan.
245 .NR "\&.ad p*" "b" "adjust" "E"
246 With values pl, pr, pb, and p, this request instructs Neatroff to perform
247 whole-paragraph line formatting.  Also, the value k enables Keshideh
248 justification (kp is the equivalent for whole-paragraph formatting).
250 .NR "\&.blm M" "\-" "disabled" "\-"
251 Specify the blank line macro.  If specified, each blank line is
252 treated as an invocation of this macro.
254 .NR "\&.chop R" "\-" "none" "\-"
255 Remove the last character of a string register.
257 .NR "\&.cl C" "0" "previous" "E"
258 Change text colour.  The current colour is available in the number
259 register \\n(.m.  With no arguments, the previous colour is selected.
260 The format of the argument and the \\m escape sequence are described
261 in the previous section.
263 .NR "\&.co SRC DST" "\-" "none" "\-"
264 Copy the contents of register SRC into register DST.
266 .NR "\&.co+ SRC DST" "\-" "none" "\-"
267 Append the contents of register SRC to register DST.
269 .NR "\&.co> R F" "\-" "none" "\-"
270 Copy the contents of register R into file F.
272 .NR "\&.co< R F" "\-" "none" "\-"
273 Read the contents of register R from file F.
275 .NR "\&.char C DEF" "\-" "\-" "\-"
276 Define Troff character C.
277 If DEF is missing, previous definitions for character C are removed.
279 .NR "\&.ochar FN C DEF" "\-" "\-" "\-"
280 Define Troff character C only for font FN.
281 If DEF is missing, previous definitions
282 for character C are removed.
284 .NR "\&.rchar C" "\-" "\-" "\-"
285 Remove the definition of character C.
287 .NR "\&.eos S T" "S=\&.?!  T='"")]*" "none" "\-"
288 Specify sentence characters.  The first argument specifies
289 the characters that end a sentence and the second argument
290 specifies the characters ignored after them.
292 .NR "\&.fzoom F N" "1000" "none" "\-"
293 Magnify the given font by N/1000.
295 .NR "\&.fp N F L" "\-" "none" "\-"
296 In Neatroff, if instead of the position of the font to be mounted, N
297 is a dash, the position of the font is decided automatically: if a
298 font with the same name is already mounted, the same position is
299 reused.  Otherwise the font is mounted on the next available
300 position.
302 .NR "\&.ff F +F1 -F2" "\-" "none" "\-"
303 Enable or disable font features; the first argument specifies the
304 font and the rest of the arguments specify feature names,
305 prefixed with a plus to enable or a minus to disable.
306 When a feature is enabled, all substitution and positioning rules
307 of a font with that feature name are applied when laying out the
308 glyphs.
310 .NR "\&.ffsc F SC LN" "\-" "none" "\-"
311 Specify font's script and language.  A Neatroff font description
312 specifies a set of rules for each script and language, grouped into
313 several features.  With this request, only the rules for the specified
314 script and language are enabled.  By default, or when SC is missing,
315 all scripts are selected.  When LN is missing, the rules of the
316 default language of the selected script are enabled.
318 .NR "\&.fspecial F S1 S2" "\-" "none" "\-"
319 Set special fonts when the current font is F.
321 .NR "\&.fmap FN CH GID" "\-" "none" "\-"
322 Map Troff character CH to glyph with device dependent name GID for
323 font FN.  When gid is missing, the effect of mapping CH is cancelled.
324 Neatroff implicitly calls \&.fmap for all aliases in font descriptions
325 (character definitions whose second column is ").
327 .NR "\&.hycost N N2 N3" "0" "none" "E"
328 Change the cost of hyphenating words when adjusting lines.
329 An argument of 100 assigns to each hyphenation the cost of stretching
330 a space one hundred percent while formatting.  The second and third
331 arguments specify additional costs for two and three consecutive
332 hyphenated lines (only when formatting whole paragraphs).
334 .NR "\&.hlm n" "0" "0" "E"
335 Set the maximum number of consecutive hyphenated lines (only when
336 formatting whole paragraphs).  The current value is available via
337 \\n[.hlm].  An argument of zero or a negative number implies no
338 limitation.
340 .NR "\&.hydash C" "\\\\:\\\\(hy\\\\(en\\\\(em-\\\\-\\\\(--" "none" "\-"
341 Specify the list of characters after which words may be broken (even
342 when hyphenation is disabled) without inserting hyphens.
344 .NR "\&.hystop C" "\\\\%" "none" "\-"
345 Specify hyphenation inhibiting characters.  Words containing any of
346 the given characters are not hyphenated, unless after dashes
347 (characters specified via \&.hydash) or hyphenation indicators (\\%).
349 .NR "\&.hpf P H C" "\-" "English" "\-"
350 Set hyphenation files for patterns, exceptions, and mappings.
351 With no arguments, loads English hyphenation patterns and exceptions.
353 .NR "\&.hpfa P H C" "\-" "English" "\-"
354 Like, \&.hpf, but do not clear the previous hyphenation patterns.
356 .NR "\&.hcode abcd..." "\-" "none" "\-"
357 Assign the hyphenation code of b to a and the hyphenation code of d to c.
359 .NR "\&.in2" "0" "previous" "E"
360 Right-side indentation.  The current right-side indentation is
361 available in register \\n(.I.
363 .NR "\&.ti2" "0" "\-" "E"
364 Right-side temporary indentation.
366 .NR "\&.kn N" "1" "none" "E"
367 Enable or disable pairwise kerning (current value available through \\n[.kn]).
369 .NR "\&.lsm M" "\-" "disabled" "\-"
370 Specify the leading space macro.  If specified, for each line with
371 leading spaces, this macro is invoked.  The register \\n[lsn] holds
372 the number of leading spaces removed from the line.
374 .NR "\&.pmll N C" "0" "0" "E"
375 Set paragraph minimum line length in percentage.  To shorter lines,
376 Neatroff assigns a cost proportional to the value specified as the
377 second argument (or 100, if missing) when formatting paragraphs.
378 Number registers \\n[.pmll] and \\n[.pmllcost] store the
379 values passed to \&.pmll.
381 .NR "\&.>>  \&.<<" "left-to-right" "\-" "E"
382 Render text in left-to-right or right-to-left direction.  See the
383 first section for an explanation of escape sequences \\> and \\<.
385 .NR "\&.shift N" "\-" "N=1" "\-"
386 Shift macro arguments by N positions.
388 .NR "\&.ssh N" "0" "0" "E"
389 Set the amount stretchable spaces in formatted lines may be
390 shrunk in percentage (available through \\n[.ssh]).
392 .NR "\&.ss M N" "M=12 N=12" "none" "E"
393 The second argument sets sentence space size (available in \\n[.sss]).
395 .NR "\&.tkf FN S1 N1 S2 N2" "\-" "none" "\-"
396 Enable track kerning for font FN.  If the point size is at most
397 S1, the width of each character is increased by N1 points, if it
398 is at least S2, the width of each character is increased by N2
399 points, and if it is between S1 and S2, the width of each character
400 is increased by a value between N1 and N2, relative to the
401 difference between the current point size and S1.
404 .SH "Notes"
405 .sp -1
406 .MH "The standard macro packages
407 The standard Troff macro packages and a top-level build script to
408 obtain and install Neatroff are available in neatroff_make git
409 repository (\*[post.url http://litcave.rudi.ir/ link]).
410 \(lqGetting Started with Neatroff\(rq (\*[post.url http://litcave.rudi.ir/neatstart.pdf link])
411 explains how to use this repository.
413 .MH "Formatting equations with Neateqn
414 Neateqn is an eqn preprocessor for Neatroff.  It implements many
415 of the extensions introduced in Groff's eqn preprocessor.  It
416 can use TeX's Computer Modern-style bracket-building symbols, if
417 available.
418 \(lqTypesetting Mathematics with Neateqn\(rq (\*[post.url http://litcave.rudi.ir/neateqn.pdf link])
419 introduces Neateqn.
421 .MH "Generating the output device
422 The Neatmkfn program (\*[post.url https://github.com/aligrudi/neatmkfn link])
423 generates Neatroff font descriptions for AFM, TrueType, and OpenType fonts.
424 It includes a script to create a complete output device for Neatroff.
426 .MH "Missing requests
427 A few requests of the original Troff are not implemented:
428 \&.pi, .cf, .rd, .pm, .ul, .cu, .uf, \\H, and \\S.
430 .MH "Porting and distribution
431 Given that Neatroff, Neatpost, Neatmkfn, and Neateqn can be compiled
432 with Neatcc, porting them to other Unix variants besides Linux should
433 not be difficult.  Note that Neatroff is released under the ISC
434 licence.
436 .MH "List of OpenType font features
437 As mentioned in previous sections, font features can be enabled and
438 disabled with \&.ff request.  For the list of OpenType features in
439 general and their descriptions, see
440 the list of typographic features in Wikipedia (\*[post.url https://en.wikipedia.org/wiki/List_of_typographic_features link])
441 or OpenType specification (\*[post.url http://www.microsoft.com/typography/OTSPEC/featurelist.htm link]).
444 .SH "Font Description Files"
445 The format of font description files in Neatroff, although still mostly
446 backward compatible, has been slightly changed.  The value of special,
447 spacewidth, and ligatures parameters retain their old meanings; sizes
448 and name parameters are ignored, however.  The value of the fontname
449 parameter in Neatroff specifies the device name of the font
450 (e.g. Times-Roman); Neatpost uses it to map Troff fonts to PostScript fonts.
451 In the charset section, the forth field is always the
452 device-specific name of the glyph (accessible with \\N escape sequence)
453 and the optional fifth field specifies glyph's code (the fourth field
454 of the original Troff).
456 In addition to the old charset section of the original Troff, Neatroff
457 supports a new syntax for defining characters and kerning pairs.  Lines
458 starting with the word \(lqchar\(rq define characters (similar to lines in
459 the charset section) and lines starting with \(lqkern\(rq specify kerning pairs.
460 For the latter, \(lqkern\(rq is followed by three tokens: the name of the
461 first glyph, the name of the second glyph, and the amount of kerning
462 between them.  Specifying the name of glyphs (the fourth field after \(lqchar\(rq)
463 instead of character names allows specifying kerning pairs for glyphs
464 not mapped to any characters (may be later with \&.fmap request) or
465 specifying kerning pairs only once for all aliases of a character.
466 Here are a few lines of a font description file for Neatroff, created
467 with Neatmkfn.
469 .cc.beg
470 .ta 5 10 15 20 25
471 name R
472 fontname Times-Roman
473 spacewidth 25
474 ligatures fi fl 0
475 # the list of characters
476 char    !       33      2       exclam  33
477 char    .       25      0       period  46
478 char    A       72      2       A       65
479 char    B       67      2       B       66
480 char    C       67      2       C       67
481 # the kerning pairs
482 kern    A       C       -5
483 kern    A       period  -1
484 .cc.end
486 The width column of the character definition lines can optionally
487 include four more numbers, separated with commas, that describe the
488 bounding boxes of the glyphs.  The bounding boxes are used in the \\w
489 escape sequence; after this escape sequence, the value of the bbllx,
490 bblly, bburx and bbury number registers are modified to represent the
491 bounding box of the argument of \\w.
493 To use the advanced features present in TrueType and OpenType fonts,
494 Neatroff supports lines that define substitution and positioning
495 rules (lines starting with \(lqgsub\(rq and \(lqgpos\(rq respectively).
496 Note that unlike Heirloom Troff, which implements non-contextual
497 single-character substitutions, Neatroff implements many of the more
498 complex OpenType substitution and positioning features.  The following
499 example shows how such features are defined in Neatroff font
500 descriptions:
502 .cc.beg
503 .ta 5 10 15 20 25
504 gsub liga:latn 4 -gl1 -gl2 -gl3 +gl123
505 gpos kern:latn 2 gl1:+0+0-5+0 gl2
506 .cc.end
508 In this example, the first line defines a 3-character ligature (with
509 feature name \(lqliga\(rq and script name \(lqlatn\(rq) and the second
510 defines pairwise kerning for the pair of glyphs gl1 and gl2
511 (decreasing the horizontal advance of gl1 by 5 basic units; with
512 feature name \(lqkern\(rq and script name \(lqlatn\(rq).  The patterns
513 can be longer and more detailed, defining context or glyph groups, to
514 support OpenType features that require them; for examples, see the
515 files generated by Neatmkfn.
518 .SH "Source Code Organization
519 The following figure shows where Neatroff's major
520 layers and features are implemented in its source tree.
521 .sp -1
526 # part(title, description)
527 define part { [
528 M:      box ht 0.5 wid 2.3
529 .ps 15
530         $1 at 1/2 <M.w, M.nw> + (.2, 0) ljust
531 .ps 9
532         $2 at 1/2 <M.w, M.sw> + (.2, 0) ljust
533 .ps 20
534 ] }
535 # part2(title, description)
536 define part2 { [
537 M:      box ht 0.3 wid 2.6
538 .ps 13
539         $1 ljust at M.w + (.2, 0)
540 .ps 9
541         $2 ljust at M + (-.4, 0)
542 .ps 20
543 ] }
544 .ps 20
545 lineht = .3
546 HEAD:   "\s(17\fI\fP\s0"
547         down
548         move .3
549 IN:     part("in.c", "Input handling")
550         arrow
551 CP:     part("cp.c", "Copy-mode interpretation")
552         arrow
553 TR:     part("tr.c", "Troff request/macro execution")
554         arrow
555 REN:    part("ren.c", "Rendering, traps, and diversions")
556         arrow
557 OUT:    part("out.c", "Generating Troff output")
558         "\s(17\fI\fP\s0" at HEAD + (3, 0)
559         move .3
560 REG:    part2("reg.c", "Registers and environments")
561         move down 0.2
562 FMT:    part2("wb.c", "Word buffer")
563         move same
564         part2("eval.c", "Integer expression evaluation")
565         move same
566         part2("fmt.c", "Line formatting")
567         move same
568 DEV:    part2("dev.c", "Output device")
569         move same
570 FONT:   part2("font.c", "Fonts")
571         move same
572         part2("hyph.c", "Tex hyphenation")
573         move same
574         part2("dir.c", "Text direction")