2 /* Copyright (C) 1989, 1990, 1991, 1992, 2003, 2007
3 Free Software Foundation, Inc.
4 Written by James Clark (jjc@jclark.com)
6 This file is part of groff.
8 groff is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 2, or (at your option) any later
13 groff is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
18 You should have received a copy of the GNU General Public License along
19 with groff; see the file COPYING. If not, write to the Free Software
20 Foundation, 51 Franklin St - Fifth Floor, Boston, MA 02110-1301, USA. */
32 struct map entity_table
[] = {
33 // Classic troff special characters
34 {"%", "­"}, // ISOnum
35 {"'", "´"}, // ISOdia
36 {"!=", "≠"}, // ISOtech
37 {"**", "∗"}, // ISOtech
38 {"*a", "α"}, // ISOgrk3
40 {"*b", "β"}, // ISOgrk3
42 {"*d", "δ"}, // ISOgrk3
43 {"*D", "Δ"}, // ISOgrk3
44 {"*e", "ε"}, // ISOgrk3
46 {"*f", "φ"}, // ISOgrk3
47 {"*F", "Φ"}, // ISOgrk3
48 {"*g", "γ"}, // ISOgrk3
49 {"*G", "Γ"}, // ISOgrk3
50 {"*h", "θ"}, // ISOgrk3
51 {"*H", "Θ"}, // ISOgrk3
52 {"*i", "ι"}, // ISOgrk3
54 {"*k", "κ"}, // ISOgrk3
56 {"*l", "&lamda;"}, // ISOgrk3
57 {"*L", "Λ"}, // ISOgrk3
58 {"*m", "μ"}, // ISOgrk3
60 {"*n", "ν"}, // ISOgrk3
64 {"*p", "π"}, // ISOgrk3
65 {"*P", "Π"}, // ISOgrk3
66 {"*q", "ψ"}, // ISOgrk3
67 {"*Q", "Ψ"}, // ISOgrk3
68 {"*r", "ρ"}, // ISOgrk3
70 {"*s", "σ"}, // ISOgrk3
71 {"*S", "Σ"}, // ISOgrk3
72 {"*t", "τ"}, // ISOgrk3
73 {"*T", "Τ"}, // ISOgrk3
74 {"*u", "υ"}, // ISOgrk3
75 {"*U", "Υ"}, // ISOgrk3
76 {"*w", "ω"}, // ISOgrk3
77 {"*W", "Ω"}, // ISOgrk3
78 {"*x", "χ"}, // ISOgrk3
79 {"*X", "Χ"}, // ISOgrk3
80 {"*y", "η"}, // ISOgrk3
81 {"*Y", "Η"}, // ISOgrk3
82 {"*z", "ζ"}, // ISOgrk3
83 {"*Z", "Ζ"}, // ISOgrk3
84 {"+-", "±"}, // ISOnum
85 {"->", "→"}, // ISOnum
86 {"12", "½"}, // ISOnum
87 {"14", "¼"}, // ISOnum
88 {"34", "¾"}, // ISOnum
89 {"<-", "←"}, // ISOnum
90 {"==", "≡"}, // ISOtech
91 {"Fi", "ffi"}, // ISOpub
92 {"Fl", "ffl"}, // ISOpub
93 {"aa", "´"}, // ISOdia
94 {"ap", "∼"}, // ISOtech
95 {"bl", "&phonexb;"}, // ISOpub
96 {"br", "│"}, // ISObox
97 {"bs", "☎"}, // ISOpub (for the Bell logo)
98 {"bu", "•"}, // ISOpub
99 {"bv", "|"}, // ISOnum
100 {"ca", "∩"}, // ISOtech
101 {"ci", "○"}, // ISOpub
102 {"co", "©"}, // ISOnum
103 {"ct", "¢"}, // ISOnum
104 {"cu", "∪"}, // ISOtech
105 {"da", "↓"}, // ISOnum
106 {"de", "°"}, // ISOnum
107 {"dg", "†"}, // ISOpub
108 {"dd", "‡"}, // ISOpub
109 {"di", "÷"}, // ISOnum
110 {"em", "—"}, // ISOpub
111 {"eq", "="}, // ISOnum
112 {"es", "∅"}, // ISOamso
113 {"ff", "ff"}, // ISOpub
114 {"fi", "fi"}, // ISOpub
115 {"fl", "fl"}, // ISOpub
116 {"fm", "′"}, // ISOtech
117 {"ge", "≥"}, // ISOtech
118 {"gr", "∇"}, // ISOtech
119 {"hy", "‐"}, // ISOnum
120 {"ib", "⊆"}, // ISOtech
121 {"if", "∞"}, // ISOtech
122 {"ip", "⊇"}, // ISOtech
123 {"is", "∫"}, // ISOtech
124 {"le", "≤"}, // ISOtech
125 // Some pile characters go here
126 {"mi", "−"}, // ISOtech
127 {"mo", "∈"}, // ISOtech
128 {"mu", "×"}, // ISOnum
129 {"no", "¬"}, // ISOnum
130 {"or", "|"}, // ISOnum
131 {"pl", "+"}, // ISOnum
132 {"pt", "∝"}, // ISOtech
133 {"rg", "™"}, // ISOnum
134 // More pile characters go here
135 {"rn", "¯"}, // ISOdia
136 {"ru", "_"}, // ISOnum
137 {"sb", "⊂"}, // ISOtech
138 {"sc", "§"}, // ISOnum
140 {"sp", "⊃"}, // ISOtech
141 {"sq", "▪"}, // ISOpub
142 {"sr", "√"}, // ISOtech
143 {"ts", "ς"}, // ISOgrk3
144 {"ua", "↑"}, // ISOnum
146 {"~=", "≅"}, // ISOtech
147 // Extended specials supported by groff; see groff_char(7).
148 // These are listed in the order they occur on that man page.
149 {"-D", "Ð"}, // ISOlat: Icelandic uppercase eth
150 {"Sd", "ð"}, // ISOlat1: Icelandic lowercase eth
151 {"TP", "Þ"}, // ISOlat1: Icelandic uppercase thorn
152 {"Tp", "þ"}, // ISOlat1: Icelandic lowercase thorn
153 {"ss", "ß"}, // ISOlat1
155 // ff, fi, fl, ffi, ffl from old troff go here
156 {"AE", "Æ"}, // ISOlat1
157 {"ae", "æ"}, // ISOlat1
158 {"OE", "Œ"}, // ISOlat2
159 {"oe", "œ"}, // ISOlat2
160 {"IJ", "ij"}, // ISOlat2: Dutch IJ ligature
161 {"ij", "IJ"}, // ISOlat2: Dutch ij ligature
162 {".i", "ı"}, // ISOlat2,ISOamso
163 {".j", "&jnodot;"}, // ISOamso (undocumented but in 1.19)
164 // Accented characters
165 {"'A", "Á"}, // ISOlat1
166 {"'C", "Ć"}, // ISOlat2
167 {"'E", "É"}, // ISOlat1
168 {"'I", "Í"}, // ISOlat1
169 {"'O", "Ó"}, // ISOlat1
170 {"'U", "Ú"}, // ISOlat1
171 {"'Y", "Ý"}, // ISOlat1
172 {"'a", "á"}, // ISOlat1
173 {"'c", "ć"}, // ISOlat2
174 {"'e", "é"}, // ISOlat1
175 {"'i", "í"}, // ISOlat1
176 {"'o", "ó"}, // ISOlat1
177 {"'u", "ú"}, // ISOlat1
178 {"'y", "ý"}, // ISOlat1
179 {":A", "Ä"}, // ISOlat1
180 {":E", "Ë"}, // ISOlat1
181 {":I", "Ï"}, // ISOlat1
182 {":O", "Ö"}, // ISOlat1
183 {":U", "Ü"}, // ISOlat1
184 {":Y", "Ÿ"}, // ISOlat2
185 {":a", "ä"}, // ISOlat1
186 {":e", "ë"}, // ISOlat1
187 {":i", "ï"}, // ISOlat1
188 {":o", "ö"}, // ISOlat1
189 {":u", "ü"}, // ISOlat1
190 {":y", "ÿ"}, // ISOlat1
191 {"^A", "Â"}, // ISOlat1
192 {"^E", "Ê"}, // ISOlat1
193 {"^I", "Î"}, // ISOlat1
194 {"^O", "Ô"}, // ISOlat1
195 {"^U", "Û"}, // ISOlat1
196 {"^a", "â"}, // ISOlat1
197 {"^e", "ê"}, // ISOlat1
198 {"^i", "î"}, // ISOlat1
199 {"^o", "ô"}, // ISOlat1
200 {"^u", "û"}, // ISOlat1
201 {"`A", "À"}, // ISOlat1
202 {"`E", "È"}, // ISOlat1
203 {"`I", "Ì"}, // ISOlat1
204 {"`O", "Ò"}, // ISOlat1
205 {"`U", "Ù"}, // ISOlat1
206 {"`a", "à"}, // ISOlat1
207 {"`e", "è"}, // ISOlat1
208 {"`i", "ì"}, // ISOlat1
209 {"`o", "ò"}, // ISOlat1
210 {"`u", "ù"}, // ISOlat1
211 {"~A", "Ã"}, // ISOlat1
212 {"~N", "Ñ"}, // ISOlat1
213 {"~O", "Õ"}, // ISOlat1
214 {"~a", "ã"}, // ISOlat1
215 {"~n", "ñ"}, // ISOlat1
216 {"~o", "õ"}, // ISOlat1
217 {"vS", "Š"}, // ISOlat2
218 {"vs", "š"}, // ISOlat2
219 {"vZ", "Ž"}, // ISOlat2
220 {"vz", "ž"}, // ISOlat2
221 {",C", "Ç"}, // ISOlat1
222 {",c", "ç"}, // ISOlat1
223 {"/L", "Ł"}, // ISOlat2: Polish L with a slash
224 {"/l", "ł"}, // ISOlat2: Polish l with a slash
225 {"/O", "Ø"}, // ISOlat1
226 {"/o", "ø"}, // ISOlat1
227 {"oA", "Å"}, // ISOlat1
228 {"oa", "å"}, // ISOlat1
230 {"a\"","˝"}, // ISOdia: double acute accent (Hungarian umlaut)
231 {"a-", "¯"}, // ISOdia: macron or bar accent
232 {"a.", "˙"}, // ISOdia: dot above
233 {"a^", "ˆ"}, // ISOdia: circumflex accent
234 {"aa", "´"}, // ISOdia: acute accent
235 {"ga", "`"}, // ISOdia: grave accent
236 {"ab", "˘"}, // ISOdia: breve accent
237 {"ac", "¸"}, // ISOdia: cedilla accent
238 {"ad", "¨"}, // ISOdia: umlaut or dieresis
239 {"ah", "ˇ"}, // ISOdia: caron (aka hacek accent)
240 {"ao", "˚"}, // ISOdia: ring or circle accent
241 {"a~", "˜"}, // ISOdia: tilde accent
242 {"ho", "˛"}, // ISOdia: hook or ogonek accent
243 {"ha", "^"}, // ASCII circumflex, hat, caret
244 {"ti", "~"}, // ASCII tilde, large tilde
246 {"Bq", "‚"}, // ISOpub: low double comma quote
247 {"bq", "„"}, // ISOpub: low single comma quote
248 {"lq", "“"}, // ISOnum
249 {"rq", "”"}, // ISOpub
250 {"oq", "‘"}, // ISOnum: single open quote
251 {"cq", "’"}, // ISOnum: single closing quote (ASCII 39)
252 {"aq", "&zerosp;'"}, // apostrophe quote
253 {"dq", "\""}, // double quote (ASCII 34)
254 {"Fo", "«"}, // ISOnum
255 {"Fc", "»"}, // ISOnum
259 {"r!", "¡"}, // ISOnum
260 {"r?", "¿"}, // ISOnum
261 // Old troff \(em goes here
262 {"en", "–"}, // ISOpub: en dash
263 // Old troff \(hy goes here
265 {"lB", "["}, // ISOnum: left (square) bracket
266 {"rB", "]"}, // ISOnum: right (square) bracket
267 {"lC", "{"}, // ISOnum: left (curly) brace
268 {"rC", "}"}, // ISOnum: right (curly) brace
269 {"la", "⟨"}, // ISOtech: left angle bracket
270 {"ra", "⟩"}, // ISOtech: right angle bracket
271 // Old troff \(bv goes here
272 // Bracket-pile characters could go here.
274 // Old troff \(<- and \(-> go here
275 {"<>", "↔"}, // ISOamsa
276 {"da", "↓"}, // ISOnum
277 {"ua", "↑"}, // ISOnum
278 {"lA", "⇐"}, // ISOtech
279 {"rA", "⇒"}, // ISOtech
280 {"hA", "⇔"}, // ISOtech: horizontal double-headed arrow
281 {"dA", "⇓"}, // ISOamsa
282 {"uA", "⇑"}, // ISOamsa
283 {"vA", "⇕"}, // ISOamsa: vertical double-headed double arrow
286 {"-h", "ℏ"}, // ISOamso: h-bar (Planck's constant)
287 // Old troff \(or goes here
288 {"ba", "|"}, // ISOnum
289 // Old troff \(br, \{u, \(ul, \(bv go here
290 {"bb", "¦"}, // ISOnum
292 {"rs", "\"}, // ISOnum
294 // Old troff \(ci, \(bu, \(dd, \(dg go here
295 {"lz", "◊"}, // ISOpub
296 // Old troff sq goes here
297 {"ps", "¶"}, // ISOnum: paragraph or pilcrow sign
298 {"sc", "§"}, // ISOnum (in old troff)
299 // Old troff \(lh, \{h go here
300 {"at", "@"}, // ISOnum
301 {"sh", "#"}, // ISOnum
303 {"OK", "✓"}, // ISOpub
305 // Old troff \(co, \{g go here
306 {"tm", "™"}, // ISOnum
308 {"Do", "$"}, // ISOnum
309 {"ct", "¢"}, // ISOnum
312 {"Ye", "¥"}, // ISOnum
313 {"Po", "£"}, // ISOnum
314 {"Cs", "¤"}, // ISOnum: currency sign
315 {"Fn", "&fnof"}, // ISOtech
317 // Old troff de goes here
318 {"%0", "‰"}, // ISOtech: per thousand, per mille sign
319 // Old troff \(fm goes here
320 {"sd", "″"}, // ISOtech
321 {"mc", "µ"}, // ISOnum
322 {"Of", "ª"}, // ISOnum
323 {"Om", "º"}, // ISOnum
325 {"AN", "∧"}, // ISOtech
326 {"OR", "∨"}, // ISOtech
327 // Old troff \(no goes here
328 {"te", "∃"}, // ISOtech: there exists, existential quantifier
329 {"fa", "∀"}, // ISOtech: for all, universal quantifier
330 {"st", "&bepsi"}, // ISOamsr: such that
331 {"3d", "∴"}, // ISOtech
332 {"tf", "∴"}, // ISOtech
333 // Mathematical symbols
334 // Old troff "12", "14", "34" goes here
335 {"S1", "¹"}, // ISOnum
336 {"S2", "²"}, // ISOnum
337 {"S3", "³"}, // ISOnum
338 // Old troff \(pl", \-, \(+- go here
339 {"t+-", "±"}, // ISOnum
340 {"-+", "∓"}, // ISOtech
341 {"pc", "·"}, // ISOnum
342 {"md", "·"}, // ISOnum
343 // Old troff \(mu goes here
344 {"tmu", "×"}, // ISOnum
345 {"c*", "⊗"}, // ISOamsb: multiply sign in a circle
346 {"c+", "⊕"}, // ISOamsb: plus sign in a circle
347 // Old troff \(di goes here
348 {"tdi", "÷"}, // ISOnum
349 {"f/", "―"}, // ISOnum: horizintal bar for fractions
350 // Old troff \(** goes here
351 {"<=", "≤"}, // ISOtech
352 {">=", "≥"}, // ISOtech
353 {"<<", "≪"}, // ISOamsr
354 {">>", "≫"}, // ISOamsr
355 {"!=", "≠"}, // ISOtech
356 // Old troff \(eq and \(== go here
357 {"=~", "≅"}, // ISOamsr
358 // Old troff \(ap goes here
359 {"~~", "≈"}, // ISOtech
360 // This appears to be an error in the groff table.
361 // It clashes with the Bell Labs use of ~= for a congruence sign
362 // {"~=", "≈"}, // ISOamsr
363 // Old troff \(pt, \(es, \(mo go here
364 {"nm", "∉"}, // ISOtech
365 {"nb", "⊄"}, // ISOamsr
366 {"nc", "⊅"}, // ISOamsn
367 {"ne", "≢"}, // ISOamsn
368 // Old troff \(sb, \(sp, \(ib, \(ip, \(ca, \(cu go here
369 {"/_", "∠"}, // ISOamso
370 {"pp", "⊥"}, // ISOtech
371 // Old troff \(is goes here
372 {"sum", "∑"}, // ISOamsb
373 {"product", "∏"}, // ISOamsb
374 {"gr", "∇"}, // ISOtech
375 // Old troff \(sr. \{n, \(if go here
376 {"Ah", "ℵ"}, // ISOtech
377 {"Im", "ℑ"}, // ISOamso: Fraktur I, imaginary
378 {"Re", "ℜ"}, // ISOamso: Fraktur R, real
379 {"wp", "℘"}, // ISOamso
380 {"pd", "∂"}, // ISOtech: partial differentiation sign
381 // Their table duplicates the Greek letters here.
382 // We list only the variant forms here, mapping them into
383 // the ISO Greek 4 variants (which may or may not be correct :-()
384 {"+f", "&b.phiv;"}, // ISOgrk4: variant phi
385 {"+h", "&b.thetas;"}, // ISOgrk4: variant theta
386 {"+p", "&b.omega;"}, // ISOgrk4: variant pi, looking like omega
388 {"CL", "♣"}, // ISOpub: club suit
389 {"SP", "♠"}, // ISOpub: spade suit
390 {"HE", "♥"}, // ISOpub: heart suit
391 {"DI", "♦"}, // ISOpub: diamond suit
394 const char *special_to_entity(const char *sp
)
397 for (mp
= entity_table
;
398 mp
< entity_table
+ sizeof(entity_table
)/sizeof(entity_table
[0]);
400 if (strcmp(mp
->from
, sp
) == 0)
406 class char_box
: public simple_box
{
411 char_box(unsigned char);
415 int left_is_italic();
416 int right_is_italic();
418 void handle_char_type(int, int);
421 class special_char_box
: public simple_box
{
424 special_char_box(const char *);
429 void handle_char_type(int, int);
444 const char *spacing_type_table
[] = {
457 const int DIGIT_TYPE
= 0;
458 const int LETTER_TYPE
= 1;
460 const char *font_type_table
[] = {
472 char_info::char_info()
473 : spacing_type(ORDINARY_TYPE
), font_type(DIGIT_TYPE
)
477 static char_info char_table
[256];
479 declare_ptable(char_info
)
480 implement_ptable(char_info
)
482 PTABLE(char_info
) special_char_table
;
484 static int get_special_char_spacing_type(const char *ch
)
486 char_info
*p
= special_char_table
.lookup(ch
);
487 return p
? p
->spacing_type
: ORDINARY_TYPE
;
490 static int get_special_char_font_type(const char *ch
)
492 char_info
*p
= special_char_table
.lookup(ch
);
493 return p
? p
->font_type
: DIGIT_TYPE
;
496 static void set_special_char_type(const char *ch
, int st
, int ft
)
498 char_info
*p
= special_char_table
.lookup(ch
);
500 p
= new char_info
[1];
501 special_char_table
.define(ch
, p
);
504 p
->spacing_type
= st
;
509 void init_char_table()
511 set_special_char_type("pl", s_binary
, -1);
512 set_special_char_type("mi", s_binary
, -1);
513 set_special_char_type("eq", s_relation
, -1);
514 set_special_char_type("<=", s_relation
, -1);
515 set_special_char_type(">=", s_relation
, -1);
516 char_table
['}'].spacing_type
= s_closing
;
517 char_table
[')'].spacing_type
= s_closing
;
518 char_table
[']'].spacing_type
= s_closing
;
519 char_table
['{'].spacing_type
= s_opening
;
520 char_table
['('].spacing_type
= s_opening
;
521 char_table
['['].spacing_type
= s_opening
;
522 char_table
[','].spacing_type
= s_punctuation
;
523 char_table
[';'].spacing_type
= s_punctuation
;
524 char_table
[':'].spacing_type
= s_punctuation
;
525 char_table
['.'].spacing_type
= s_punctuation
;
526 char_table
['>'].spacing_type
= s_relation
;
527 char_table
['<'].spacing_type
= s_relation
;
528 char_table
['*'].spacing_type
= s_binary
;
529 for (int i
= 0; i
< 256; i
++)
531 char_table
[i
].font_type
= LETTER_TYPE
;
534 static int lookup_spacing_type(const char *type
)
536 for (int i
= 0; spacing_type_table
[i
] != 0; i
++)
537 if (strcmp(spacing_type_table
[i
], type
) == 0)
542 static int lookup_font_type(const char *type
)
544 for (int i
= 0; font_type_table
[i
] != 0; i
++)
545 if (strcmp(font_type_table
[i
], type
) == 0)
550 void box::set_spacing_type(char *type
)
552 int t
= lookup_spacing_type(type
);
554 error("unrecognised type `%1'", type
);
560 char_box::char_box(unsigned char cc
)
561 : c(cc
), next_is_italic(0), prev_is_italic(0)
563 spacing_type
= char_table
[c
].spacing_type
;
566 void char_box::hint(unsigned flags
)
568 if (flags
& HINT_PREV_IS_ITALIC
)
570 if (flags
& HINT_NEXT_IS_ITALIC
)
574 void char_box::output()
576 if (output_format
== troff
) {
577 int font_type
= char_table
[c
].font_type
;
578 if (font_type
!= LETTER_TYPE
)
579 printf("\\f[%s]", current_roman_font
);
581 fputs("\\,", stdout
);
583 fputs("\\e", stdout
);
587 fputs("\\/", stdout
);
589 fputs("\\&", stdout
); // suppress ligaturing and kerning
590 if (font_type
!= LETTER_TYPE
)
591 fputs("\\fP", stdout
);
593 else if (output_format
== mathml
) {
596 else if (char_table
[c
].spacing_type
)
610 else if (char_table
[c
].spacing_type
)
617 int char_box::left_is_italic()
619 int font_type
= char_table
[c
].font_type
;
620 return font_type
== LETTER_TYPE
;
623 int char_box::right_is_italic()
625 int font_type
= char_table
[c
].font_type
;
626 return font_type
== LETTER_TYPE
;
629 int char_box::is_char()
634 void char_box::debug_print()
644 special_char_box::special_char_box(const char *t
)
647 spacing_type
= get_special_char_spacing_type(s
);
650 special_char_box::~special_char_box()
655 void special_char_box::output()
657 if (output_format
== troff
) {
658 int font_type
= get_special_char_font_type(s
);
659 if (font_type
!= LETTER_TYPE
)
660 printf("\\f[%s]", current_roman_font
);
661 printf("\\,\\[%s]\\/", s
);
662 if (font_type
!= LETTER_TYPE
)
665 else if (output_format
== mathml
) {
666 const char *entity
= special_to_entity(s
);
668 printf("<mo>%s</mo>", entity
);
670 printf("<merror>unknown eqn/troff special char %s</merror>", s
);
674 int special_char_box::is_char()
679 void special_char_box::debug_print()
681 fprintf(stderr
, "\\[%s]", s
);
685 void char_box::handle_char_type(int st
, int ft
)
688 char_table
[c
].spacing_type
= st
;
690 char_table
[c
].font_type
= ft
;
693 void special_char_box::handle_char_type(int st
, int ft
)
695 set_special_char_type(s
, st
, ft
);
698 void set_char_type(const char *type
, char *ch
)
701 int st
= lookup_spacing_type(type
);
702 int ft
= lookup_font_type(type
);
703 if (st
< 0 && ft
< 0) {
704 error("bad character type `%1'", type
);
708 box
*b
= split_text(ch
);
709 b
->handle_char_type(st
, ft
);
713 /* We give primes special treatment so that in ``x' sub 2'', the ``2''
714 will be tucked under the prime */
716 class prime_box
: public pointer_box
{
721 int compute_metrics(int style
);
723 void compute_subscript_kern();
725 void handle_char_type(int, int);
728 box
*make_prime_box(box
*pp
)
730 return new prime_box(pp
);
733 prime_box::prime_box(box
*pp
) : pointer_box(pp
)
735 pb
= new special_char_box("fm");
738 prime_box::~prime_box()
743 int prime_box::compute_metrics(int style
)
745 int res
= p
->compute_metrics(style
);
746 pb
->compute_metrics(style
);
747 printf(".nr " WIDTH_FORMAT
" 0\\n[" WIDTH_FORMAT
"]"
748 "+\\n[" WIDTH_FORMAT
"]\n",
749 uid
, p
->uid
, pb
->uid
);
750 printf(".nr " HEIGHT_FORMAT
" \\n[" HEIGHT_FORMAT
"]"
751 ">?\\n[" HEIGHT_FORMAT
"]\n",
752 uid
, p
->uid
, pb
->uid
);
753 printf(".nr " DEPTH_FORMAT
" \\n[" DEPTH_FORMAT
"]"
754 ">?\\n[" DEPTH_FORMAT
"]\n",
755 uid
, p
->uid
, pb
->uid
);
759 void prime_box::compute_subscript_kern()
761 p
->compute_subscript_kern();
762 printf(".nr " SUB_KERN_FORMAT
" 0\\n[" WIDTH_FORMAT
"]"
763 "+\\n[" SUB_KERN_FORMAT
"]>?0\n",
764 uid
, pb
->uid
, p
->uid
);
767 void prime_box::output()
773 void prime_box::handle_char_type(int st
, int ft
)
775 p
->handle_char_type(st
, ft
);
776 pb
->handle_char_type(st
, ft
);
779 void prime_box::debug_print()
785 box
*split_text(char *text
)
795 b
= new special_char_box("pl");
798 b
= new special_char_box("mi");
801 b
= new special_char_box("eq");
804 b
= new special_char_box("fm");
808 b
= new special_char_box("<=");
815 b
= new special_char_box(">=");
822 lex_error("bad escape");
835 b
= new special_char_box(buf
);
838 lex_error("bad escape");
842 lex_error("bad escape");
849 while (*s
!= ']' && *s
!= '\0')
852 lex_error("bad escape");
855 b
= new special_char_box(ch
);
865 char *escape_start
= s
- 2;
872 for (++s
; *s
!= '\0' && *s
!= ']'; s
++)
877 lex_error("bad escape");
880 char *buf
= new char[s
- escape_start
+ 1];
881 memcpy(buf
, escape_start
, s
- escape_start
);
882 buf
[s
- escape_start
] = '\0';
883 b
= new quoted_text_box(buf
);
893 b
= new special_char_box(buf
);
897 b
= new special_char_box("ga");
900 b
= new special_char_box("aa");
904 b
= new char_box('\\');
914 b
= new quoted_text_box(strsave(buf
));
918 lex_error("unquoted escape");
919 b
= new quoted_text_box(strsave(s
- 2));
931 b
= new quoted_text_box(0);
932 b
= new prime_box(b
);
939 lb
= new list_box(fb
);
952 return new quoted_text_box(0);