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