2 * Most functions and variables in neatroff are prefixed with tokens
3 * that indicate their purpose, such as:
5 * + tr_xyz: the implementation of troff request .xyz (mostly tr.c)
6 * + in_xyz: input layer (in.c)
7 * + cp_xyz: copy-mode interpretation layer (cp.c)
8 * + ren_xyz: rendering characters into lines (ren.c)
9 * + out_xyz: output layer for generating troff output (out.c)
10 * + dev_xyz: output devices (dev.c)
11 * + num_xyz: number registers (reg.c)
12 * + str_xyz: string registers (reg.c)
13 * + env_xyz: environments (reg.c)
14 * + eval_xyz: integer expression evaluation (eval.c)
15 * + font_xyz: fonts (font.c)
16 * + sbuf_xyz: variable length string buffers (sbuf.c)
17 * + wb_xyz: word buffers (wb.c)
18 * + adj_xyz: line adjustment buffers (adj.c)
19 * + n_xyz: builtin number register xyz
20 * + c_xyz: characters for requests like hc and mc
24 /* predefined array limits */
25 #define PATHLEN 1024 /* path length */
26 #define NFILES 16 /* number of input files */
27 #define NFONTS 32 /* number of fonts */
28 #define NGLYPHS 1024 /* glyphs in fonts */
29 #define NLIGS 128 /* number of font ligatures */
30 #define NKERNS 1024 /* number of font kerning pairs */
31 #define FNLEN 32 /* font name length */
32 #define NMLEN 32 /* macro/register/environment/glyph name length */
33 #define GNLEN NMLEN /* glyph name length */
34 #define RNLEN NMLEN /* register/macro name */
35 #define ILNLEN 1000 /* line limit of input files */
36 #define LNLEN 4000 /* line buffer length (ren.c/out.c) */
37 #define NWORDS 256 /* number of words in line buffer */
38 #define NARGS 16 /* number of macro arguments */
39 #define NPREV 16 /* environment stack depth */
40 #define NTRAPS 1024 /* number of traps per page */
41 #define NIES 128 /* number of nested .ie commands */
42 #define NTABS 16 /* number of tab stops */
43 #define NCMAPS 512 /* number of character translations (.tr) */
44 #define NSSTR 32 /* number of nested sstr_push() calls */
45 #define NFIELDS 32 /* number of fields */
46 #define MAXFRAC 100000 /* maximum value of the fractional part */
47 #define LIGLEN 4 /* length of ligatures */
48 #define NCDEFS 128 /* number of character definitions (.char) */
50 /* converting scales */
51 #define SC_IN (dev_res) /* inch in units */
52 #define SC_PT (SC_IN / 72) /* point in units */
53 #define SC_EM (n_s * SC_IN / 72)
55 /* escape sequences */
56 #define ESC_Q "bCDhHlLNoSvwxX" /* \X'ccc' quoted escape sequences */
57 #define ESC_P "*fgkmns" /* \Xc \X(cc \X[ccc] escape sequences */
59 #define MIN(a, b) ((a) < (b) ? (a) : (b))
60 #define MAX(a, b) ((a) < (b) ? (b) : (a))
61 #define LEN(a) (sizeof(a) / sizeof((a)[0]))
63 /* special characters */
64 extern int c_ec
; /* escape character (\) */
65 extern int c_cc
; /* basic control character (.) */
66 extern int c_c2
; /* no-break control character (') */
67 #define c_ni 4 /* non-interpreted copy-mode escape */
68 #define c_hc env_hc()/* hyphenation character */
69 #define c_mc env_mc()/* margin character (.mc) */
72 #define c_bp "\\:" /* zero-width word break point */
74 /* number registers */
75 int num_get(int id
, int inc
);
76 void num_set(int id
, int val
);
77 void num_inc(int id
, int val
);
79 char *num_str(int id
);
80 char *num_getfmt(int id
);
81 void num_setfmt(int id
, char *fmt
);
83 int eval(char *s
, int unit
);
84 int eval_up(char **s
, int unit
);
85 int eval_re(char *s
, int orig
, int unit
);
87 /* string registers */
88 void str_set(int id
, char *s
);
89 void str_dset(int id
, void *d
);
90 char *str_get(int id
);
91 void *str_dget(int id
);
93 void str_rn(int src
, int dst
);
95 /* saving and restoring registers before and after printing diverted lines */
102 struct adj
*env_adj(void);
107 int tab_next(int pos
);
108 int tab_type(int pos
);
110 /* device related variables */
117 char id
[GNLEN
]; /* device-dependent glyph identifier */
118 char name
[GNLEN
]; /* the first character mapped to this glyph */
119 struct font
*font
; /* glyph font */
120 int wid
; /* character width */
121 int type
; /* character type; ascender/descender */
122 int llx
, lly
, urx
, ury
; /* character bounding box */
127 char fontname
[FNLEN
];
128 struct glyph glyphs
[NGLYPHS
];
132 int cs
, bd
; /* for .cs and .bd requests */
133 /* charset section characters */
134 char c
[NGLYPHS
][GNLEN
]; /* character names in charset */
135 struct glyph
*g
[NGLYPHS
]; /* character glyphs in charset */
136 struct glyph
*g_map
[NGLYPHS
]; /* character remapped via font_map() */
137 int n
; /* number of characters in charset */
138 /* glyph table based on the first character of their id fields in glyphs[] */
139 int ghead
[256]; /* glyph list heads */
140 int gnext
[NGLYPHS
]; /* next item in glyph lists */
141 /* character table based on the first character of glyph names in c[] */
142 int chead
[256]; /* character list heads */
143 int cnext
[NGLYPHS
]; /* next item in character lists */
144 /* font ligatures (lg*) */
145 char lg
[NLIGS
][LIGLEN
* GNLEN
]; /* ligatures */
146 int lgn
; /* number of ligatures in lg[] */
147 /* kerning pair table per glyph (kn*) */
148 int knhead
[NGLYPHS
]; /* kerning pairs of glyphs[] */
149 int knnext
[NKERNS
]; /* next item in knhead[] list */
150 int knpair
[NKERNS
]; /* kerning pair 2nd glyphs */
151 int knval
[NKERNS
]; /* font pairwise kerning value */
152 int knn
; /* number of kerning pairs */
155 /* output device functions */
156 int dev_open(char *dir
, char *dev
);
157 void dev_close(void);
158 int dev_mnt(int pos
, char *id
, char *name
);
159 int dev_pos(char *id
);
160 struct font
*dev_font(int pos
);
161 int dev_fontpos(struct font
*fn
);
162 void dev_setcs(int fn
, int cs
);
163 int dev_getcs(int fn
);
164 void dev_setbd(int fn
, int bd
);
165 int dev_getbd(int fn
);
167 /* font-related functions */
168 struct font
*font_open(char *path
);
169 void font_close(struct font
*fn
);
170 struct glyph
*font_glyph(struct font
*fn
, char *id
);
171 struct glyph
*font_find(struct font
*fn
, char *name
);
172 int font_lig(struct font
*fn
, char **c
, int n
);
173 int font_kern(struct font
*fn
, char *c1
, char *c2
);
174 int font_islig(struct font
*fn
, char *s
);
175 int font_map(struct font
*fn
, char *name
, struct glyph
*gl
);
176 int font_mapped(struct font
*fn
, char *name
);
178 /* glyph handling functions */
179 struct glyph
*dev_glyph(char *c
, int fn
);
180 int charwid(int fn
, int sz
, int wid
);
181 int spacewid(int fn
, int sz
);
183 /* convert wid in device unitwidth size to size sz */
184 #define DEVWID(sz, wid) (((wid) * (sz) + (dev_uwid / 2)) / dev_uwid)
186 /* different layers of neatroff */
187 int in_next(void); /* input layer */
188 int cp_next(void); /* copy-mode layer */
189 int tr_next(void); /* troff layer */
191 void in_push(char *s
, char **args
);
192 void in_pushnl(char *s
, char **args
);
193 void in_so(char *path
); /* .so request */
194 void in_nx(char *path
); /* .nx request */
195 void in_ex(void); /* .ex request */
196 void in_lf(char *path
, int ln
); /* .lf request */
197 void in_queue(char *path
); /* queue the given input file */
198 char *in_arg(int i
); /* look up argument */
199 int in_nargs(void); /* number of arguments */
200 void in_back(int c
); /* push back input character */
201 int in_top(void); /* the first pushed-back character */
202 char *in_filename(void); /* current filename */
203 int in_lnum(void); /* current line number */
205 void cp_blk(int skip
); /* skip or read the next line or block */
206 void cp_wid(int enable
); /* control inlining \w requests */
207 #define cp_back in_back /* cp.c is stateless */
208 void tr_first(void); /* read until the first non-command line */
210 /* variable length string buffer */
212 char *s
; /* allocated buffer */
213 int sz
; /* buffer size */
214 int n
; /* length of the string stored in s */
217 void sbuf_init(struct sbuf
*sbuf
);
218 void sbuf_done(struct sbuf
*sbuf
);
219 char *sbuf_buf(struct sbuf
*sbuf
);
220 void sbuf_add(struct sbuf
*sbuf
, int c
);
221 void sbuf_append(struct sbuf
*sbuf
, char *s
);
222 void sbuf_printf(struct sbuf
*sbuf
, char *s
, ...);
223 void sbuf_putnl(struct sbuf
*sbuf
);
224 void sbuf_cut(struct sbuf
*sbuf
, int n
);
225 int sbuf_len(struct sbuf
*sbuf
);
226 int sbuf_empty(struct sbuf
*sbuf
);
231 int f
, s
, m
; /* the last output font and size */
232 int r_f
, r_s
, r_m
; /* current font and size; use n_f and n_s if -1 */
233 int part
; /* partial input (\c) */
234 int els_neg
, els_pos
; /* extra line spacing */
235 int h
, v
; /* buffer vertical and horizontal positions */
236 int ct
, sb
, st
; /* \w registers */
237 int llx
, lly
, urx
, ury
; /* bounding box */
238 int icleft_ll
; /* len after the pending left italic correction */
239 /* saving previous characters added via wb_put() */
240 char prev_c
[LIGLEN
][GNLEN
];
241 int prev_l
[LIGLEN
]; /* sbuf_len(&wb->sbuf) before wb_put() calls */
242 int prev_h
[LIGLEN
]; /* wb->h before wb_put() calls */
243 int prev_n
; /* number of characters in prev_c[] */
244 int prev_ll
; /* sbuf_len(&wb->sbuf) after the last wb_put() */
247 void wb_init(struct wb
*wb
);
248 void wb_done(struct wb
*wb
);
249 void wb_hmov(struct wb
*wb
, int n
);
250 void wb_vmov(struct wb
*wb
, int n
);
251 void wb_els(struct wb
*wb
, int els
);
252 void wb_etc(struct wb
*wb
, char *x
);
253 void wb_put(struct wb
*wb
, char *c
);
254 void wb_putexpand(struct wb
*wb
, char *c
);
255 int wb_part(struct wb
*wb
);
256 void wb_setpart(struct wb
*wb
);
257 void wb_drawl(struct wb
*wb
, int c
, int h
, int v
);
258 void wb_drawc(struct wb
*wb
, int c
, int r
);
259 void wb_drawe(struct wb
*wb
, int c
, int h
, int v
);
260 void wb_drawa(struct wb
*wb
, int c
, int h1
, int v1
, int h2
, int v2
);
261 void wb_drawxbeg(struct wb
*wb
, int c
);
262 void wb_drawxdot(struct wb
*wb
, int h
, int v
);
263 void wb_drawxend(struct wb
*wb
);
264 void wb_italiccorrection(struct wb
*wb
);
265 void wb_italiccorrectionleft(struct wb
*wb
);
266 void wb_cat(struct wb
*wb
, struct wb
*src
);
267 int wb_hyph(char *word
, int w
, struct wb
*w1
, struct wb
*w2
, int flg
);
268 int wb_wid(struct wb
*wb
);
269 int wb_empty(struct wb
*wb
);
270 int wb_eos(struct wb
*wb
);
271 void wb_wconf(struct wb
*wb
, int *ct
, int *st
, int *sb
,
272 int *llx
, int *lly
, int *urx
, int *ury
);
273 int wb_lig(struct wb
*wb
, char *c
);
274 int wb_kern(struct wb
*wb
, char *c
);
275 void wb_reset(struct wb
*wb
);
276 char *wb_buf(struct wb
*wb
);
278 /* character translation (.tr) */
279 void cmap_add(char *c1
, char *c2
);
280 char *cmap_map(char *c
);
281 /* character definition (.char) */
282 char *cdef_map(char *c
, int fn
);
283 int cdef_expand(struct wb
*wb
, char *c
, int fn
);
285 /* hyphenation flags */
286 #define HY_MASK 0x0f /* enable hyphenation */
287 #define HY_LAST 0x02 /* do not hyphenate last lines */
288 #define HY_FINAL2 0x04 /* do not hyphenate the final two characters */
289 #define HY_FIRST2 0x08 /* do not hyphenate the first two characters */
290 #define HY_ANY 0x10 /* break at any possible position */
292 void hyphenate(char *hyphs
, char *word
, int flg
);
300 struct adj
*adj_alloc(void);
301 void adj_free(struct adj
*adj
);
302 int adj_fill(struct adj
*adj
, int ad_b
, int fill
, int hyph
, struct sbuf
*dst
,
303 int *li
, int *ll
, int *els_neg
, int *els_pos
);
304 int adj_full(struct adj
*adj
, int fill
);
305 int adj_empty(struct adj
*adj
, int fill
);
306 int adj_wid(struct adj
*adj
);
307 void adj_swid(struct adj
*adj
, int swid
);
308 void adj_wb(struct adj
*adj
, struct wb
*wb
);
309 void adj_nl(struct adj
*adj
);
310 void adj_sp(struct adj
*adj
);
311 void adj_nonl(struct adj
*adj
);
314 int render(void); /* the main loop */
315 int ren_parse(struct wb
*wb
, char *c
);
316 int ren_char(struct wb
*wb
, int (*next
)(void), void (*back
)(int));
317 int ren_wid(int (*next
)(void), void (*back
)(int));
318 void ren_tl(int (*next
)(void), void (*back
)(int));
319 void ren_hline(struct wb
*wb
, int l
, char *c
); /* horizontal line */
320 void ren_hlcmd(struct wb
*wb
, char *arg
); /* \l */
321 void ren_vlcmd(struct wb
*wb
, char *arg
); /* \L */
322 void ren_bcmd(struct wb
*wb
, char *arg
); /* \b */
323 void ren_ocmd(struct wb
*wb
, char *arg
); /* \o */
324 void ren_dcmd(struct wb
*wb
, char *arg
); /* \D */
327 void out_line(char *s
); /* output rendered line */
328 void out(char *s
, ...); /* output troff cmd */
331 void tr_ab(char **args
);
332 void tr_bp(char **args
);
333 void tr_br(char **args
);
334 void tr_ce(char **args
);
335 void tr_ch(char **args
);
336 void tr_cl(char **args
);
337 void tr_di(char **args
);
338 void tr_divbeg(char **args
);
339 void tr_divend(char **args
);
340 void tr_dt(char **args
);
341 void tr_em(char **args
);
342 void tr_ev(char **args
);
343 void tr_fc(char **args
);
344 void tr_fi(char **args
);
345 void tr_fp(char **args
);
346 void tr_fspecial(char **args
);
347 void tr_ft(char **args
);
348 void tr_hw(char **args
);
349 void tr_in(char **args
);
350 void tr_ll(char **args
);
351 void tr_mk(char **args
);
352 void tr_ne(char **args
);
353 void tr_nf(char **args
);
354 void tr_ns(char **args
);
355 void tr_os(char **args
);
356 void tr_pn(char **args
);
357 void tr_ps(char **args
);
358 void tr_rs(char **args
);
359 void tr_rt(char **args
);
360 void tr_sp(char **args
);
361 void tr_sv(char **args
);
362 void tr_ta(char **args
);
363 void tr_ti(char **args
);
364 void tr_wh(char **args
);
365 void tr_eject(char **args
);
370 void errmsg(char *msg
, ...);
371 void errdie(char *msg
);
373 int utf8next(char *s
, int (*next
)(void));
374 int utf8read(char **s
, char *d
);
375 int utf8one(char *s
);
376 int charnext(char *c
, int (*next
)(void), void (*back
)(int));
377 int charread(char **s
, char *c
);
378 int charnext_delim(char *c
, int (*next
)(void), void (*back
)(int), char *delim
);
379 void charnext_str(char *d
, char *c
);
380 void argnext(char *d
, int cmd
, int (*next
)(void), void (*back
)(int));
381 void argread(char **sp
, char *d
, int cmd
);
382 int escread(char **s
, char *d
);
383 /* string streams; nested next()/back() interface for string buffers */
384 void sstr_push(char *s
);
385 char *sstr_pop(void);
387 void sstr_back(int c
);
389 /* internal commands */
390 #define TR_DIVBEG "\07<" /* diversion begins */
391 #define TR_DIVEND "\07>" /* diversion ends */
392 #define TR_EJECT "\07P" /* page eject */
394 /* mapping register, macro and environment names to indices */
395 #define NREGS 4096 /* maximum number of mapped names */
396 #define DOTMAP(c2) (c2) /* optimized mapping for ".x" names */
398 int map(char *s
); /* map name s to an index */
399 char *map_name(int id
); /* return the name mapped to id */
402 #define CLR_R(c) (((c) >> 16) & 0xff)
403 #define CLR_G(c) (((c) >> 8) & 0xff)
404 #define CLR_B(c) ((c) & 0xff)
405 #define CLR_RGB(r, g, b) (((r) << 16) | ((g) << 8) | (b))
407 char *clr_str(int c
);
408 int clr_get(char *s
);
410 /* builtin number registers; n_X for .X register */
411 #define n_a (*nreg(DOTMAP('a')))
412 #define n_cp (*nreg(DOTMAP('C')))
413 #define n_d (*nreg(DOTMAP('d')))
414 #define n_f (*nreg(DOTMAP('f')))
415 #define n_h (*nreg(DOTMAP('h')))
416 #define n_i (*nreg(DOTMAP('i')))
417 #define n_it (*nreg(map(".it"))) /* .it trap macro */
418 #define n_itn (*nreg(map(".itn"))) /* .it lines left */
419 #define n_j (*nreg(DOTMAP('j')))
420 #define n_l (*nreg(DOTMAP('l')))
421 #define n_L (*nreg(DOTMAP('L')))
422 #define n_n (*nreg(DOTMAP('n')))
423 #define n_nI (*nreg(map(".nI"))) /* i for .nm */
424 #define n_nm (*nreg(map(".nm"))) /* .nm enabled */
425 #define n_nM (*nreg(map(".nM"))) /* m for .nm */
426 #define n_nn (*nreg(map(".nn"))) /* remaining .nn */
427 #define n_nS (*nreg(map(".nS"))) /* s for .nm */
428 #define n_m (*nreg(DOTMAP('m')))
429 #define n_mc (*nreg(map(".mc"))) /* .mc enabled */
430 #define n_mcn (*nreg(map(".mcn"))) /* .mc distance */
431 #define n_o (*nreg(DOTMAP('o')))
432 #define n_p (*nreg(DOTMAP('p')))
433 #define n_s (*nreg(DOTMAP('s')))
434 #define n_u (*nreg(DOTMAP('u')))
435 #define n_v (*nreg(DOTMAP('v')))
436 #define n_ct (*nreg(map("ct")))
437 #define n_dl (*nreg(map("dl")))
438 #define n_dn (*nreg(map("dn")))
439 #define n_ln (*nreg(map("ln")))
440 #define n_nl (*nreg(map("nl")))
441 #define n_sb (*nreg(map("sb")))
442 #define n_st (*nreg(map("st")))
443 #define n_pg (*nreg(map("%"))) /* % */
444 #define n_lb (*nreg(map(".b0"))) /* input line beg */
445 #define n_ce (*nreg(map(".ce"))) /* .ce remaining */
446 #define n_f0 (*nreg(map(".f0"))) /* last .f */
447 #define n_lg (*nreg(map(".lg"))) /* .lg mode */
448 #define n_hy (*nreg(map(".hy"))) /* .hy mode */
449 #define n_i0 (*nreg(map(".i0"))) /* last .i */
450 #define n_ti (*nreg(map(".ti"))) /* pending .ti */
451 #define n_kn (*nreg(map(".kern"))) /* .kn mode */
452 #define n_l0 (*nreg(map(".l0"))) /* last .l */
453 #define n_L0 (*nreg(map(".L0"))) /* last .L */
454 #define n_m0 (*nreg(map(".m0"))) /* last .m */
455 #define n_mk (*nreg(map(".mk"))) /* .mk internal register */
456 #define n_na (*nreg(map(".na"))) /* .na mode */
457 #define n_ns (*nreg(map(".ns"))) /* .ns mode */
458 #define n_o0 (*nreg(map(".o0"))) /* last .o */
459 #define n_ss (*nreg(map(".ss"))) /* .ss value */
460 #define n_s0 (*nreg(map(".s0"))) /* last .s */
461 #define n_sv (*nreg(map(".sv"))) /* .sv value */
462 #define n_lt (*nreg(map(".lt"))) /* .lt value */
463 #define n_t0 (*nreg(map(".lt0"))) /* previous .lt value */
464 #define n_v0 (*nreg(map(".v0"))) /* last .v */
465 #define n_llx (*nreg(map("bbllx"))) /* \w bounding box */
466 #define n_lly (*nreg(map("bblly"))) /* \w bounding box */
467 #define n_urx (*nreg(map("bburx"))) /* \w bounding box */
468 #define n_ury (*nreg(map("bbury"))) /* \w bounding box */
470 /* functions for implementing read-only registers */
471 int f_nexttrap(void); /* .t */
472 int f_divreg(void); /* .z */
473 int f_hpos(void); /* .k */