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