neatroff.ms: fix the order of the arguments of .hpf
[neatroff_make.git] / demo / neatroff.ms
blobac242aa1830dda6869c47b441cfbf9cc15965ab3
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 March 2018\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 The latest versions of Neatroff, its postscript postprocessor, Neatpost,
36 and its eqn preprocessor, Neateqn, are available at their \*[ps.url http://litcave.rudi.ir/ "home\ page"].
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
40 (available \*[ps.url http://litcave.rudi.ir/neatstart.pdf here])
41 explains how to set up and 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 "Macros and their arguments
129 In a macro, \\$* is replaced with macro's argument separated
130 by spaces.  \\$@ is like \\$*, but quotes the arguments as well.
131 \\$\(ha is like \\$@, except that it escapes the double quotes
132 in the arguments.
133 The arguments can be shifted with \&.shift request.
134 Neatroff also supports blank line macro (.blm) and
135 leading space macro (.lsm).
137 .MH "Text direction
138 Neatroff supports text direction to render right-to-left languages.
139 \&.<< and \&.>> requests specify text direction and \\< and \\> escape
140 sequences change it temporarily for including words in the reverse
141 direction.  The value of number registers \&.td and \&.cd indicate the
142 current text and temporary directions respectively; zero means
143 left-to-right and one means right-to-left.  Neatroff starts processing
144 text direction, after the first invocation of \&.<< or \&.>>.
146 .MH "Keshideh justification and cursive scripts
147 A new adjustment type (.ad k) allows inserting Keshideh characters
148 before justifying text with hyphenation and spaces.  Neatroff also
149 supports cursive scripts, which require connecting glyphs at their
150 cursive attachment positions, as defined in the fonts.
152 .MH "Font manipulation
153 In Neatroff, the mapping between Troff character names and glyphs in a
154 font can be modified with \&.fmap request: \(lq.fmap F C G\(rq
155 maps Troff character C to the glyph with device-specific name G for
156 font F.  When this glyph does not exist in F, Neatroff assumes that
157 the character C is not present in the font.  When G is missing, the
158 effect of \&.fmap for character C is cancelled.  Neatroff also implements
159 Groff's \&.fspecial and \&.fzoom requests: after \(lq.fspecial FN S1
160 S2 ...\(rq, when the current font is FN, the fonts S1, S2, ... are
161 assumed to be special.  Also, \(lq.fzoom FN zoom\(rq scales font FN by
162 the second argument after dividing it by 1000.
164 .MH "Colour support
165 Neatroff supports colours with .cl request and \\m[] escape sequence.
166 Unlike Groff, colours need not be defined beforehand and can be
167 specified directly.  The argument of \\m can be predefined colour
168 names (e.g. blue), predefined colour numbers (0 for black, 1 for red,
169 2 for green, 3 for yellow, 4 for blue, 5 for magenta, 6 for cyan, and
170 7 for white), #rgb and #rrggbb for specifying colours in hexadecimal
171 RGB format, #g and #gg for specifying grey with the given hexadecimal
172 level, and empty (\\m[]) for the previous colour.  The current colour
173 is available in \&.m number register.
175 .MH "Hyphenation language
176 The \&.hpf request loads hyphenation patterns, exceptions, and
177 character mappings from the addresses specified via its arguments.
178 The specified files should contain nothing but utf-8 patterns,
179 exceptions and mappings respectively (i.e. no TeX code), just like the
180 files whose names end with \&.pat.txt, \&.hyp.txt and \&.chr.txt in
181 \*[ps.url ftp://ftp.ctan.org/tex-archive/language/hyph-utf8/tex/generic/hyph-utf8/patterns/txt/ "this\ directory"]
182 for TeX.
183 The \&.hpfa request is like \&.hpf, except that it does not clear the
184 previous hyphenation patterns and exceptions.  The second and third
185 arguments of these requests are optional.  With no arguments, these
186 requests load English hyphenation patterns and exceptions.  Also the
187 \&\(lq.hcode abcd...\(rq request, assigns the hyphenation code of b to
188 a and the hyphenation code of d to c; initially all upper-case ASCII
189 letters are mapped to their lower-case forms.
191 .MH "Filled drawing objects
192 Neatroff supports Groff-style polygons and filled drawing objects (p,
193 C, E and P commands for \\D escape sequence).  In Neatroff, however,
194 there is no specific background colour; objects are filled with the
195 current colour (.m number register).  Furthermore, in Neatroff
196 the edges of polygons can be lines, arcs, or splines; a letter among the
197 arguments of \\D'p ..' specifies the type of the subsequent
198 edges: \(oql\(cq, \(oqa\(cq, and \(oq\(ti\(cq for lines, arcs,
199 and splines respectively.
201 .MH "Conditional escape sequence
202 Neatroff supports a new escape sequence for conditional interpolation:
203 the escape sequence \\?'cond@expr1@expr2@', evaluates cond (exactly as
204 if it is a \&.if condition) and interpolates expr1, if the condition
205 is true, and expr2, otherwise.  The delimiter (@ in this example) can
206 be any character that cannot be part of the condition; for numerical
207 expressions, for instance, it cannot be a digit, an operator sign, or
208 a scale indicator, unless separated from the condition with \\&.  The
209 final delimiter, and even expr2, may be omitted, thus \\?'cond@expr'
210 is valid; Neatroff interpolates expr if cond is true.
212 .MH "Neatpost-specific device commands
213 Neatroff supports \\X'rotate deg' for rotating the current page
214 around the current point.  Also \\X'eps file [width [height]]'
215 includes the given EPS file with its lower left corner at the current
216 point.  If width and height are given (in basic units), the file is
217 scaled appropriately.
220 .SH "Summary of New Requests"
221 This is the list of new request available in Neatroff compared
222 to those documented in \(lqTroff User's Manual\(rq by Ossanna
223 and Kernighan.
225 .NR "\&.ad p*" "b" "adjust" "E"
226 With values pl, pr, pb, and p, this request instructs Neatroff to perform
227 whole-paragraph line formatting.  Also, the value k enables Keshideh
228 justification (kp is the equivalent for whole-paragraph formatting).
230 .NR "\&.blm M" "\-" "disabled" "\-"
231 Specify the blank line macro.  If specified, each blank line is
232 treated as an invocation of this macro.
234 .NR "\&.chop xx" "\-" "none" "\-"
235 Remove the last character of a string register.
237 .NR "\&.cl C" "0" "previous" "E"
238 Change text colour.  The current colour is available in the number
239 register \\n(.m.  With no arguments, the previous colour is selected.
240 The format of the argument and the \\m escape sequence are described
241 in the previous section.
243 .NR "\&.co R >F" "\-" "none" "\-"
244 Copy the contents of register R into file F.
246 .NR "\&.co R <F" "\-" "none" "\-"
247 Copy the contents of register R from file F.
249 .NR "\&.char C DEF" "\-" "\-" "\-"
250 Define Troff character C.
251 If DEF is missing, previous definitions for character C are removed.
253 .NR "\&.ochar FN C DEF" "\-" "\-" "\-"
254 Define Troff character C only for font FN.
255 If DEF is missing, previous definitions
256 for character C are removed.
258 .NR "\&.eos S T" "S=\&.?!  T='"")]*" "none" "\-"
259 Specify sentence characters.  The first argument specifies
260 the characters that end a sentence and the second argument
261 specifies the characters ignored after them.
263 .NR "\&.fzoom F N" "1000" "none" "\-"
264 Magnify the given font by N/1000.
266 .NR "\&.fp N F L" "\-" "none" "\-"
267 In Neatroff, if instead of the position of the font to be mounted, N
268 is a dash, the position of the font is decided automatically: if a
269 font with the same name is already mounted, the same position is
270 reused.  Otherwise the font is mounted on the next available
271 position.
273 .NR "\&.ff F +F1 -F2" "\-" "none" "\-"
274 Enable or disable font features; the first argument specifies the
275 font and the rest of the arguments specify feature names,
276 prefixed with a plus to enable or a minus to disable.
277 When a feature is enabled, all substitution and positioning rules
278 of a font with that feature name are applied when laying out the
279 glyphs.
281 .NR "\&.ffsc F SC LN" "\-" "none" "\-"
282 Specify font's script and language.  A Neatroff font description
283 specifies a set of rules for each script and language, grouped into
284 several features.  With this request, only the rules for the specified
285 script and language are enabled.  By default, or when SC is missing,
286 all scripts are selected.  When LN is missing, the rules of the
287 default language of the selected script are enabled.
289 .NR "\&.fspecial F S1 S2" "\-" "none" "\-"
290 Set special fonts when the current font is F.
292 .NR "\&.fmap FN CH GID" "\-" "none" "\-"
293 Map Troff character CH to glyph with device dependent name GID for
294 font FN.  When gid is missing, the effect of mapping CH is cancelled.
295 Neatroff implicitly calls \&.fmap for all aliases in font descriptions
296 (character definitions whose second column is ").
298 .NR "\&.hycost N N2 N3" "0" "none" "E"
299 Change the cost of hyphenating words when adjusting lines.
300 An argument of 100 assigns to each hyphenation the cost of stretching
301 a space one hundred percent while formatting.  The second and third
302 arguments specify additional costs for two and three consecutive
303 hyphenated lines (only when formatting whole paragraphs).
305 .NR "\&.hlm n" "0" "0" "E"
306 Set the maximum number of consecutive hyphenated lines (only when
307 formatting whole paragraphs).  The current value is available via
308 \\n[.hlm].  An argument of zero or a negative number implies no
309 limitation.
311 .NR "\&.hydash C" "\\\\:\\\\(hy\\\\(en\\\\(em-\\\\-\\\\(--" "none" "\-"
312 Specify the list of characters after which words may be broken (even
313 when hyphenation is disabled) without inserting hyphens.
315 .NR "\&.hystop C" "\\\\%" "none" "\-"
316 Specify hyphenation inhibiting characters.  Words containing any of
317 the given characters are not hyphenated, unless after dashes
318 (characters specified via \&.hydash) or hyphenation indicators (\\%).
320 .NR "\&.hpf P H C" "\-" "English" "\-"
321 Set hyphenation files for patterns, exceptions, and mappings.
322 With no arguments, loads English hyphenation patterns and exceptions.
324 .NR "\&.hpfa P H C" "\-" "English" "\-"
325 Like, \&.hpf, but do not clear the previous hyphenation patterns.
327 .NR "\&.hcode abcd..." "\-" "none" "\-"
328 Assign the hyphenation code of b to a and the hyphenation code of d to c.
330 .NR "\&.in2" "0" "previous" "E"
331 Right-side indentation.  The current right-side indentation is
332 available in register \\n(.I.
334 .NR "\&.ti2" "0" "\-" "E"
335 Right-side temporary indentation.
337 .NR "\&.kn N" "1" "none" "E"
338 Enable or disable pairwise kerning (current value available through \\n[.kn]).
340 .NR "\&.lsm M" "\-" "disabled" "\-"
341 Specify the leading space macro.  If specified, for each line with
342 leading spaces, this macro is invoked.  The register \\n[lsn] holds
343 the number of leading spaces removed from the line.
345 .NR "\&.pmll N C" "0" "0" "E"
346 Set paragraph minimum line length in percentage.  To shorter lines,
347 Neatroff assigns a cost proportional to the value specified as the
348 second argument (or 100, if missing) when formatting paragraphs.
349 Number registers \\n[.pmll] and \\n[.pmllcost] store the
350 values passed to \&.pmll.
352 .NR "\&.>>  \&.<<" "left-to-right" "\-" "E"
353 Render text in left-to-right or right-to-left direction.  See the
354 first section for an explanation of escape sequences \\> and \\<.
356 .NR "\&.shift N" "\-" "N=1" "\-"
357 Shift macro arguments by N positions.
359 .NR "\&.ssh N" "0" "0" "E"
360 Set the amount stretchable spaces in formatted lines may be
361 shrunk in percentage (available through \\n[.ssh]).
363 .NR "\&.ss M N" "M=12 N=12" "none" "E"
364 The second argument sets sentence space size (available in \\n[.sss]).
366 .NR "\&.tkf FN S1 N1 S2 N2" "\-" "none" "\-"
367 Enable track kerning for font FN.  If the point size is at most
368 S1, the width of each character is increased by N1 points, if it
369 is at least S2, the width of each character is increased by N2
370 points, and if it is between S1 and S2, the width of each character
371 is increased by a value between N1 and N2, relative to the
372 difference between the current point size and S1.
375 .SH "Notes"
376 .sp -1
377 .MH "Generating the output device
378 The neatmkfn program (available at \*[ps.url http://litcave.rudi.ir/]) generates
379 Neatroff font descriptions for AFM or TrueType fonts (OpenType fonts
380 are converted to TrueType first).  It includes a script to create
381 a complete output device for Neatroff.
383 .MH "Formatting equations with neateqn
384 Neateqn is an eqn preprocessor for Neatroff.  It implements many
385 of the extensions introduced in Groff's eqn preprocessor.  It
386 can use TeX's Computer Modern-style bracket-building symbols, if
387 available.
389 .MH "The standard macro packages
390 The standard Troff macro packages and a top-level build script to
391 obtain and install Neatroff are available in neatroff_make git
392 repository (available at \*[ps.url http://litcave.rudi.ir/]).
394 .MH "Missing requests
395 A few requests of the original Troff are not implemented:
396 \&.pi, .cf, .rd, .pm, .ul, .cu, .uf, \\H, and \\S.
398 .MH "Porting and distribution
399 Given that Neatroff, neatpost and neateqn can be compiled with Neatcc,
400 porting them to other Unix variants besides Linux should not be
401 difficult.  Note that Neatroff is released under the ISC licence.
403 .MH "List of OpenType font features
404 As mentioned in previous sections, font features can be enabled and
405 disabled with \&.ff request.  For the list of OpenType features in
406 general and their descriptions, see
407 \*[ps.url "https://en.wikipedia.org/wiki/List_of_typographic_features" "this Wikipedia page"]
408 or the \*[ps.url http://www.microsoft.com/typography/OTSPEC/featurelist.htm "OpenType specification"].
411 .SH "Font Description Files"
412 The format of font description files in Neatroff, although still mostly
413 backward compatible, has been slightly changed.  The value of special,
414 spacewidth, and ligatures parameters retain their old meanings; sizes
415 and name parameters are ignored, however.  The value of the fontname
416 parameter in Neatroff specifies the device name of the font
417 (e.g. Times-Roman); neatpost uses it to map Troff fonts to postscript fonts.
418 In the charset section, the forth field is always the
419 device-specific name of the glyph (accessible with \\N escape sequence)
420 and the optional fifth field specifies glyph's code (the fourth field
421 of the original Troff).
423 In addition to the old charset section of the original Troff, Neatroff
424 supports a new syntax for defining characters and kerning pairs.  Lines
425 starting with the word \(lqchar\(rq define characters (similar to lines in
426 the charset section) and lines starting with \(lqkern\(rq specify kerning pairs.
427 For the latter, \(lqkern\(rq is followed by three tokens: the name of the
428 first glyph, the name of the second glyph, and the amount of kerning
429 between them.  Specifying the name of glyphs (the fourth field after \(lqchar\(rq)
430 instead of character names allows specifying kerning pairs for glyphs
431 not mapped to any characters (may be later with \&.fmap request) or
432 specifying kerning pairs only once for all aliases of a character.
433 Here are a few lines of a font description file for Neatroff, created
434 with neatmkfn.
436 .cc.beg
437 .ta 5 10 15 20 25
438 name R
439 fontname Times-Roman
440 spacewidth 25
441 ligatures fi fl 0
442 # the list of characters
443 char    !       33      2       exclam  33
444 char    .       25      0       period  46
445 char    A       72      2       A       65
446 char    B       67      2       B       66
447 char    C       67      2       C       67
448 # the kerning pairs
449 kern    A       C       -5
450 kern    A       period  -1
451 .cc.end
453 The width column of the character definition lines can optionally
454 include four more numbers, separated with commas, that describe the
455 bounding boxes of the glyphs.  The bounding boxes are used in the \\w
456 escape sequence; after this escape sequence, the value of the bbllx,
457 bblly, bburx and bbury number registers are modified to represent the
458 bounding box of the argument of \\w.
460 To use the advanced features present in TrueType and OpenType fonts,
461 Neatroff supports lines that define substitution and positioning
462 rules (lines starting with \(lqgsub\(rq and \(lqgpos\(rq respectively).
463 Note that unlike Heirloom Troff, which implements non-contextual
464 single-character substitutions, Neatroff implements many of the more
465 complex OpenType substitution and positioning features.  The following
466 example shows how such features are defined in Neatroff font
467 descriptions:
469 .cc.beg
470 .ta 5 10 15 20 25
471 gsub liga:latn 4 -gl1 -gl2 -gl3 +gl123
472 gpos kern:latn 2 gl1:+0+0-5+0 gl2
473 .cc.end
475 In this example, the first line defines a 3-character ligature (with
476 feature name \(lqliga\(rq and script name \(lqlatn\(rq) and the second
477 defines pairwise kerning for the pair of glyphs gl1 and gl2
478 (decreasing the horizontal advance of gl1 by 5 basic units; with
479 feature name \(lqkern\(rq and script name \(lqlatn\(rq).  The patterns
480 can be longer and more detailed, defining context or glyph groups, to
481 support OpenType features that require them; for examples, see the
482 files generated by neatmkfn.
485 .SH "Source Code Organization
486 The following figure shows where Neatroff's major
487 layers and features are implemented in its source tree.
488 .sp -1
493 # part(title, description)
494 define part { [
495 M:      box ht 0.5 wid 2.3
496 .ps 15
497         $1 at 1/2 <M.w, M.nw> + (.2, 0) ljust
498 .ps 9
499         $2 at 1/2 <M.w, M.sw> + (.2, 0) ljust
500 .ps 20
501 ] }
502 # part2(title, description)
503 define part2 { [
504 M:      box ht 0.3 wid 2.6
505 .ps 13
506         $1 ljust at M.w + (.2, 0)
507 .ps 9
508         $2 ljust at M + (-.4, 0)
509 .ps 20
510 ] }
511 .ps 20
512 lineht = .3
513 HEAD:   "\s(17\fI\fP\s0"
514         down
515         move .3
516 IN:     part("in.c", "Input handling")
517         arrow
518 CP:     part("cp.c", "Copy-mode interpretation")
519         arrow
520 TR:     part("tr.c", "Troff request/macro execution")
521         arrow
522 REN:    part("ren.c", "Rendering, traps, and diversions")
523         arrow
524 OUT:    part("out.c", "Generating Troff output")
525         "\s(17\fI\fP\s0" at HEAD + (3, 0)
526         move .3
527 REG:    part2("reg.c", "Registers and environments")
528         move down 0.2
529 FMT:    part2("wb.c", "Word buffer")
530         move same
531         part2("eval.c", "Integer expression evaluation")
532         move same
533         part2("fmt.c", "Line formatting")
534         move same
535 DEV:    part2("dev.c", "Output device")
536         move same
537 FONT:   part2("font.c", "Fonts")
538         move same
539         part2("hyph.c", "Tex hyphenation")
540         move same
541         part2("dir.c", "Text direction")