hyph: read the correct file for the second argument of .hpf
[neatroff.git] / roff.h
blobe80b885b7529b1fb81078052fe707172c10e0164
1 /*
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 * + dict_xyz: dictionaries (dict.c)
18 * + wb_xyz: word buffers (wb.c)
19 * + fmt_xyz: line formatting buffers (fmt.c)
20 * + n_xyz: builtin number register xyz
21 * + c_xyz: characters for requests like hc and mc
25 /* predefined array limits */
26 #define PATHLEN 1024 /* path length */
27 #define NFILES 16 /* number of input files */
28 #define NFONTS 32 /* number of fonts */
29 #define NGLYPHS 1024 /* glyphs in fonts */
30 #define NLIGS 128 /* number of font ligatures */
31 #define NKERNS 1024 /* number of font kerning pairs */
32 #define FNLEN 32 /* font name length */
33 #define NMLEN 32 /* macro/register/environment/glyph name length */
34 #define GNLEN NMLEN /* glyph name length */
35 #define RNLEN NMLEN /* register/macro name */
36 #define ILNLEN 1000 /* line limit of input files */
37 #define LNLEN 4000 /* line buffer length (ren.c/out.c) */
38 #define NWORDS 1024 /* number of queued words in formatting buffer */
39 #define NLINES 32 /* number of queued lines in formatting buffer */
40 #define NARGS 16 /* number of macro arguments */
41 #define NPREV 16 /* environment stack depth */
42 #define NTRAPS 1024 /* number of traps per page */
43 #define NIES 128 /* number of nested .ie commands */
44 #define NTABS 16 /* number of tab stops */
45 #define NCMAPS 512 /* number of character translations (.tr) */
46 #define NSSTR 32 /* number of nested sstr_push() calls */
47 #define NFIELDS 32 /* number of fields */
48 #define MAXFRAC 100000 /* maximum value of the fractional part */
49 #define LIGLEN 4 /* length of ligatures */
50 #define NCDEFS 128 /* number of character definitions (.char) */
51 #define NHYPHS 16384 /* hyphenation dictionary/patterns (.hw) */
52 #define NHYPHSWORD 16 /* number of hyphenations per word */
53 #define NHCODES 512 /* number of .hcode characters */
54 #define WORDLEN 256 /* word length (for hyph.c) */
56 /* converting scales */
57 #define SC_IN (dev_res) /* inch in units */
58 #define SC_PT (SC_IN / 72) /* point in units */
59 #define SC_EM (n_s * SC_IN / 72)
61 /* escape sequences */
62 #define ESC_Q "bCDhHlLNoRSvwxX?" /* \X'ccc' quoted escape sequences */
63 #define ESC_P "*fgkmns" /* \Xc \X(cc \X[ccc] escape sequences */
65 #define MIN(a, b) ((a) < (b) ? (a) : (b))
66 #define MAX(a, b) ((a) < (b) ? (b) : (a))
67 #define LEN(a) (sizeof(a) / sizeof((a)[0]))
69 /* special characters */
70 extern int c_ec; /* escape character (\) */
71 extern int c_cc; /* basic control character (.) */
72 extern int c_c2; /* no-break control character (') */
73 #define c_ni 4 /* non-interpreted copy-mode escape */
74 #define c_hc env_hc()/* hyphenation character */
75 #define c_mc env_mc()/* margin character (.mc) */
76 #define c_tc env_tc()
77 #define c_lc env_lc()
78 #define c_bp "\\:" /* zero-width word break point */
80 /* number registers */
81 int num_get(int id, int inc);
82 void num_set(int id, int val);
83 void num_inc(int id, int val);
84 void num_del(int id);
85 char *num_str(int id);
86 char *num_getfmt(int id);
87 void num_setfmt(int id, char *fmt);
88 int *nreg(int id);
89 int eval(char *s, int unit);
90 int eval_up(char **s, int unit);
91 int eval_re(char *s, int orig, int unit);
93 /* string registers */
94 void str_set(int id, char *s);
95 void str_dset(int id, void *d);
96 char *str_get(int id);
97 void *str_dget(int id);
98 void str_rm(int id);
99 void str_rn(int src, int dst);
101 /* saving and restoring registers before and after printing diverted lines */
102 void odiv_beg(void);
103 void odiv_end(void);
105 /* enviroments */
106 void env_init(void);
107 void env_done(void);
108 struct fmt *env_fmt(void);
109 struct wb *env_wb(void);
110 char *env_hc(void);
111 char *env_mc(void);
112 char *env_tc(void);
113 char *env_lc(void);
114 int tab_next(int pos);
115 int tab_type(int pos);
117 /* dictionary */
118 struct dict {
119 int *head;
120 char **key;
121 long *val;
122 int *next;
123 int size;
124 int n;
125 char *buf; /* buffer for keys */
126 int buflen;
127 int level2; /* use two characters for hashing */
128 long notfound; /* the value returned for missing keys */
131 void dict_init(struct dict *d, int size, long notfound, int dupkeys, int level2);
132 void dict_done(struct dict *d);
133 void dict_put(struct dict *d, char *key, long val);
134 long dict_get(struct dict *d, char *key);
135 long dict_pop(struct dict *d, char *key);
136 int dict_idx(struct dict *d, char *key);
137 char *dict_key(struct dict *d, int idx);
138 long dict_val(struct dict *d, int idx);
139 long dict_prefix(struct dict *d, char *key, int *idx);
141 /* device related variables */
142 extern int dev_res;
143 extern int dev_uwid;
144 extern int dev_hor;
145 extern int dev_ver;
147 struct glyph {
148 char id[GNLEN]; /* device-dependent glyph identifier */
149 char name[GNLEN]; /* the first character mapped to this glyph */
150 struct font *font; /* glyph font */
151 int wid; /* character width */
152 int type; /* character type; ascender/descender */
153 int llx, lly, urx, ury; /* character bounding box */
156 struct font {
157 char name[FNLEN];
158 char fontname[FNLEN];
159 struct glyph glyphs[NGLYPHS];
160 int nglyphs;
161 int spacewid;
162 int special;
163 int cs, bd; /* for .cs and .bd requests */
164 struct dict gdict; /* mapping from glyphs[i].id to i */
165 /* charset section characters */
166 char c[NGLYPHS][GNLEN]; /* character names in charset */
167 struct glyph *g[NGLYPHS]; /* character glyphs in charset */
168 struct glyph *g_map[NGLYPHS]; /* character remapped via font_map() */
169 int n; /* number of characters in charset */
170 struct dict cdict; /* mapping from c[i] to i */
171 /* font ligatures (lg*) */
172 char lg[NLIGS][LIGLEN * GNLEN]; /* ligatures */
173 int lgn; /* number of ligatures in lg[] */
174 /* kerning pair table per glyph (kn*) */
175 int knhead[NGLYPHS]; /* kerning pairs of glyphs[] */
176 int knnext[NKERNS]; /* next item in knhead[] list */
177 int knpair[NKERNS]; /* kerning pair 2nd glyphs */
178 int knval[NKERNS]; /* font pairwise kerning value */
179 int knn; /* number of kerning pairs */
182 /* output device functions */
183 int dev_open(char *dir, char *dev);
184 void dev_close(void);
185 int dev_mnt(int pos, char *id, char *name);
186 int dev_pos(char *id);
187 struct font *dev_font(int pos);
188 int dev_fontpos(struct font *fn);
189 void dev_setcs(int fn, int cs);
190 int dev_getcs(int fn);
191 void dev_setbd(int fn, int bd);
192 int dev_getbd(int fn);
194 /* font-related functions */
195 struct font *font_open(char *path);
196 void font_close(struct font *fn);
197 struct glyph *font_glyph(struct font *fn, char *id);
198 struct glyph *font_find(struct font *fn, char *name);
199 int font_lig(struct font *fn, char **c, int n);
200 int font_kern(struct font *fn, char *c1, char *c2);
201 int font_islig(struct font *fn, char *s);
202 int font_map(struct font *fn, char *name, struct glyph *gl);
203 int font_mapped(struct font *fn, char *name);
205 /* glyph handling functions */
206 struct glyph *dev_glyph(char *c, int fn);
207 int charwid(int fn, int sz, int wid);
209 /* convert wid in device unitwidth size to size sz */
210 #define DEVWID(sz, wid) (((wid) * (sz) + (dev_uwid / 2)) / dev_uwid)
211 /* the amount of word and sentence space for the given font and size */
212 #define N_SS(fn, sz) (charwid((fn), (sz), (dev_font(fn)->spacewid * n_ss + 6) / 12))
213 #define N_SSS(fn, sz) (charwid((fn), (sz), (dev_font(fn)->spacewid * n_sss + 6) / 12))
215 /* different layers of neatroff */
216 int in_next(void); /* input layer */
217 int cp_next(void); /* copy-mode layer */
218 int tr_next(void); /* troff layer */
220 void in_push(char *s, char **args);
221 void in_so(char *path); /* .so request */
222 void in_nx(char *path); /* .nx request */
223 void in_ex(void); /* .ex request */
224 void in_lf(char *path, int ln); /* .lf request */
225 void in_queue(char *path); /* queue the given input file */
226 char *in_arg(int i); /* look up argument */
227 int in_nargs(void); /* number of arguments */
228 void in_back(int c); /* push back input character */
229 int in_top(void); /* the first pushed-back character */
230 char *in_filename(void); /* current filename */
231 int in_lnum(void); /* current line number */
233 void cp_blk(int skip); /* skip or read the next line or block */
234 void cp_copymode(int mode); /* do not interpret \w and \E */
235 #define cp_back in_back /* cp.c is stateless */
236 int tr_nextreq(void); /* read the next troff request */
238 /* variable length string buffer */
239 struct sbuf {
240 char *s; /* allocated buffer */
241 int sz; /* buffer size */
242 int n; /* length of the string stored in s */
245 void sbuf_init(struct sbuf *sbuf);
246 void sbuf_done(struct sbuf *sbuf);
247 char *sbuf_buf(struct sbuf *sbuf);
248 void sbuf_add(struct sbuf *sbuf, int c);
249 void sbuf_append(struct sbuf *sbuf, char *s);
250 void sbuf_printf(struct sbuf *sbuf, char *s, ...);
251 void sbuf_putnl(struct sbuf *sbuf);
252 void sbuf_cut(struct sbuf *sbuf, int n);
253 int sbuf_len(struct sbuf *sbuf);
254 int sbuf_empty(struct sbuf *sbuf);
256 /* word buffer */
257 struct wb {
258 struct sbuf sbuf;
259 int f, s, m; /* the last output font and size */
260 int r_f, r_s, r_m; /* current font and size; use n_f and n_s if -1 */
261 int part; /* partial input (\c) */
262 int els_neg, els_pos; /* extra line spacing */
263 int h, v; /* buffer vertical and horizontal positions */
264 int ct, sb, st; /* \w registers */
265 int llx, lly, urx, ury; /* bounding box */
266 int icleft_ll; /* len after the pending left italic correction */
267 /* saving previous characters added via wb_put() */
268 char prev_c[LIGLEN][GNLEN];
269 int prev_l[LIGLEN]; /* sbuf_len(&wb->sbuf) before wb_put() calls */
270 int prev_h[LIGLEN]; /* wb->h before wb_put() calls */
271 int prev_n; /* number of characters in prev_c[] */
272 int prev_ll; /* sbuf_len(&wb->sbuf) after the last wb_put() */
275 void wb_init(struct wb *wb);
276 void wb_done(struct wb *wb);
277 void wb_hmov(struct wb *wb, int n);
278 void wb_vmov(struct wb *wb, int n);
279 void wb_els(struct wb *wb, int els);
280 void wb_etc(struct wb *wb, char *x);
281 void wb_put(struct wb *wb, char *c);
282 void wb_putexpand(struct wb *wb, char *c);
283 int wb_part(struct wb *wb);
284 void wb_setpart(struct wb *wb);
285 void wb_drawl(struct wb *wb, int c, int h, int v);
286 void wb_drawc(struct wb *wb, int c, int r);
287 void wb_drawe(struct wb *wb, int c, int h, int v);
288 void wb_drawa(struct wb *wb, int c, int h1, int v1, int h2, int v2);
289 void wb_drawxbeg(struct wb *wb, int c);
290 void wb_drawxdot(struct wb *wb, int h, int v);
291 void wb_drawxend(struct wb *wb);
292 void wb_italiccorrection(struct wb *wb);
293 void wb_italiccorrectionleft(struct wb *wb);
294 void wb_cat(struct wb *wb, struct wb *src);
295 void wb_catstr(struct wb *wb, char *beg, char *end);
296 int wb_hyphmark(char *word, int *hyidx, int *hyins);
297 int wb_hyph(char *word, int *hyidx, int flg);
298 int wb_wid(struct wb *wb);
299 int wb_dashwid(struct wb *wb);
300 int wb_empty(struct wb *wb);
301 int wb_eos(struct wb *wb);
302 void wb_wconf(struct wb *wb, int *ct, int *st, int *sb,
303 int *llx, int *lly, int *urx, int *ury);
304 int wb_lig(struct wb *wb, char *c);
305 int wb_kern(struct wb *wb, char *c);
306 void wb_reset(struct wb *wb);
307 char *wb_buf(struct wb *wb);
308 void wb_fnszget(struct wb *wb, int *fn, int *sz, int *m);
309 void wb_fnszset(struct wb *wb, int fn, int sz, int m);
311 /* character translation (.tr) */
312 void cmap_add(char *c1, char *c2);
313 char *cmap_map(char *c);
314 /* character definition (.char) */
315 char *cdef_map(char *c, int fn);
316 int cdef_expand(struct wb *wb, char *c, int fn);
318 /* hyphenation flags */
319 #define HY_LAST 0x02 /* do not hyphenate last lines */
320 #define HY_FINAL2 0x04 /* do not hyphenate the final two characters */
321 #define HY_FIRST2 0x08 /* do not hyphenate the first two characters */
323 void hyphenate(char *hyphs, char *word, int flg);
324 void hyph_init(void);
326 /* adjustment types */
327 #define AD_C 0 /* center */
328 #define AD_L 1 /* adjust left margin (flag) */
329 #define AD_R 2 /* adjust right margin (flag) */
330 #define AD_B 3 /* adjust both margin (mask) */
331 #define AD_P 4 /* paragraph-at-once adjustment (flag) */
333 /* line formatting */
334 struct fmt *fmt_alloc(void);
335 void fmt_free(struct fmt *fmt);
336 int fmt_wid(struct fmt *fmt);
337 void fmt_space(struct fmt *fmt);
338 void fmt_suppressnl(struct fmt *fmt);
339 int fmt_word(struct fmt *fmt, struct wb *wb);
340 int fmt_newline(struct fmt *fmt);
341 int fmt_fillreq(struct fmt *f);
342 int fmt_br(struct fmt *fmt);
343 int fmt_fill(struct fmt *fmt);
344 int fmt_morelines(struct fmt *fmt);
345 int fmt_morewords(struct fmt *fmt);
346 int fmt_nextline(struct fmt *fmt, struct sbuf *sbuf, int *w,
347 int *li, int *ll, int *els_neg, int *els_pos);
349 /* rendering */
350 int render(void); /* the main loop */
351 int ren_parse(struct wb *wb, char *c);
352 int ren_char(struct wb *wb, int (*next)(void), void (*back)(int));
353 int ren_wid(int (*next)(void), void (*back)(int));
354 void ren_tl(int (*next)(void), void (*back)(int));
355 void ren_hline(struct wb *wb, int l, char *c); /* horizontal line */
356 void ren_hlcmd(struct wb *wb, char *arg); /* \l */
357 void ren_vlcmd(struct wb *wb, char *arg); /* \L */
358 void ren_bcmd(struct wb *wb, char *arg); /* \b */
359 void ren_ocmd(struct wb *wb, char *arg); /* \o */
360 void ren_dcmd(struct wb *wb, char *arg); /* \D */
362 /* out.c */
363 void out_line(char *s); /* output rendered line */
364 void out(char *s, ...); /* output troff cmd */
366 /* troff commands */
367 void tr_ab(char **args);
368 void tr_bp(char **args);
369 void tr_br(char **args);
370 void tr_ce(char **args);
371 void tr_ch(char **args);
372 void tr_cl(char **args);
373 void tr_di(char **args);
374 void tr_divbeg(char **args);
375 void tr_divend(char **args);
376 void tr_dt(char **args);
377 void tr_em(char **args);
378 void tr_ev(char **args);
379 void tr_fc(char **args);
380 void tr_fi(char **args);
381 void tr_fp(char **args);
382 void tr_fspecial(char **args);
383 void tr_ft(char **args);
384 void tr_hcode(char **args);
385 void tr_hpf(char **args);
386 void tr_hpfa(char **args);
387 void tr_hw(char **args);
388 void tr_in(char **args);
389 void tr_ll(char **args);
390 void tr_mk(char **args);
391 void tr_ne(char **args);
392 void tr_nf(char **args);
393 void tr_ns(char **args);
394 void tr_os(char **args);
395 void tr_pn(char **args);
396 void tr_ps(char **args);
397 void tr_rs(char **args);
398 void tr_rt(char **args);
399 void tr_sp(char **args);
400 void tr_sv(char **args);
401 void tr_ta(char **args);
402 void tr_ti(char **args);
403 void tr_wh(char **args);
404 void tr_popren(char **args);
406 void tr_init(void);
407 int tr_readargs(char **args, struct sbuf *sbuf,
408 int (*next)(void), void (*back)(int));
410 /* helpers */
411 void errmsg(char *msg, ...);
412 void errdie(char *msg);
413 void *xmalloc(long len);
414 int utf8len(int c);
415 int utf8next(char *s, int (*next)(void));
416 int utf8read(char **s, char *d);
417 int utf8one(char *s);
418 int charnext(char *c, int (*next)(void), void (*back)(int));
419 int charread(char **s, char *c);
420 int charnext_delim(char *c, int (*next)(void), void (*back)(int), char *delim);
421 int charread_delim(char **s, char *c, char *delim);
422 void charnext_str(char *d, char *c);
423 void argnext(char *d, int cmd, int (*next)(void), void (*back)(int));
424 void argread(char **sp, char *d, int cmd);
425 int escread(char **s, char *d);
426 /* string streams; nested next()/back() interface for string buffers */
427 void sstr_push(char *s);
428 char *sstr_pop(void);
429 int sstr_next(void);
430 void sstr_back(int c);
432 /* internal commands */
433 #define TR_DIVBEG "\07<" /* diversion begins */
434 #define TR_DIVEND "\07>" /* diversion ends */
435 #define TR_POPREN "\07P" /* exit render_rec() */
437 /* mapping register, macro and environment names to indices */
438 #define NREGS 4096 /* maximum number of mapped names */
439 #define DOTMAP(c2) (c2) /* optimized mapping for ".x" names */
441 int map(char *s); /* map name s to an index */
442 char *map_name(int id); /* return the name mapped to id */
444 /* colors */
445 #define CLR_R(c) (((c) >> 16) & 0xff)
446 #define CLR_G(c) (((c) >> 8) & 0xff)
447 #define CLR_B(c) ((c) & 0xff)
448 #define CLR_RGB(r, g, b) (((r) << 16) | ((g) << 8) | (b))
450 char *clr_str(int c);
451 int clr_get(char *s);
453 /* builtin number registers; n_X for .X register */
454 #define n_a (*nreg(DOTMAP('a')))
455 #define n_cp (*nreg(DOTMAP('C')))
456 #define n_d (*nreg(DOTMAP('d')))
457 #define n_f (*nreg(DOTMAP('f')))
458 #define n_h (*nreg(DOTMAP('h')))
459 #define n_i (*nreg(DOTMAP('i')))
460 #define n_it (*nreg(map(".it"))) /* .it trap macro */
461 #define n_itn (*nreg(map(".itn"))) /* .it lines left */
462 #define n_j (*nreg(DOTMAP('j')))
463 #define n_l (*nreg(DOTMAP('l')))
464 #define n_L (*nreg(DOTMAP('L')))
465 #define n_n (*nreg(DOTMAP('n')))
466 #define n_nI (*nreg(map(".nI"))) /* i for .nm */
467 #define n_nm (*nreg(map(".nm"))) /* .nm enabled */
468 #define n_nM (*nreg(map(".nM"))) /* m for .nm */
469 #define n_nn (*nreg(map(".nn"))) /* remaining .nn */
470 #define n_nS (*nreg(map(".nS"))) /* s for .nm */
471 #define n_m (*nreg(DOTMAP('m')))
472 #define n_mc (*nreg(map(".mc"))) /* .mc enabled */
473 #define n_mcn (*nreg(map(".mcn"))) /* .mc distance */
474 #define n_o (*nreg(DOTMAP('o')))
475 #define n_p (*nreg(DOTMAP('p')))
476 #define n_s (*nreg(DOTMAP('s')))
477 #define n_u (*nreg(DOTMAP('u')))
478 #define n_v (*nreg(DOTMAP('v')))
479 #define n_ct (*nreg(map("ct")))
480 #define n_dl (*nreg(map("dl")))
481 #define n_dn (*nreg(map("dn")))
482 #define n_ln (*nreg(map("ln")))
483 #define n_nl (*nreg(map("nl")))
484 #define n_sb (*nreg(map("sb")))
485 #define n_st (*nreg(map("st")))
486 #define n_pg (*nreg(map("%"))) /* % */
487 #define n_lb (*nreg(map(".b0"))) /* input line beg */
488 #define n_ce (*nreg(map(".ce"))) /* .ce remaining */
489 #define n_f0 (*nreg(map(".f0"))) /* last .f */
490 #define n_lg (*nreg(map(".lg"))) /* .lg mode */
491 #define n_hy (*nreg(map(".hy"))) /* .hy mode */
492 #define n_hyp (*nreg(map(".hyp"))) /* hyphenation penalty */
493 #define n_i0 (*nreg(map(".i0"))) /* last .i */
494 #define n_ti (*nreg(map(".ti"))) /* pending .ti */
495 #define n_kn (*nreg(map(".kern"))) /* .kn mode */
496 #define n_l0 (*nreg(map(".l0"))) /* last .l */
497 #define n_L0 (*nreg(map(".L0"))) /* last .L */
498 #define n_m0 (*nreg(map(".m0"))) /* last .m */
499 #define n_mk (*nreg(map(".mk"))) /* .mk internal register */
500 #define n_na (*nreg(map(".na"))) /* .na mode */
501 #define n_ns (*nreg(map(".ns"))) /* .ns mode */
502 #define n_o0 (*nreg(map(".o0"))) /* last .o */
503 #define n_ss (*nreg(map(".ss"))) /* word space (.ss) */
504 #define n_sss (*nreg(map(".sss"))) /* sentence space (.ss) */
505 #define n_ssh (*nreg(map(".ssh"))) /* word space compression (.ssh) */
506 #define n_s0 (*nreg(map(".s0"))) /* last .s */
507 #define n_sv (*nreg(map(".sv"))) /* .sv value */
508 #define n_lt (*nreg(map(".lt"))) /* .lt value */
509 #define n_t0 (*nreg(map(".lt0"))) /* previous .lt value */
510 #define n_v0 (*nreg(map(".v0"))) /* last .v */
511 #define n_llx (*nreg(map("bbllx"))) /* \w bounding box */
512 #define n_lly (*nreg(map("bblly"))) /* \w bounding box */
513 #define n_urx (*nreg(map("bburx"))) /* \w bounding box */
514 #define n_ury (*nreg(map("bbury"))) /* \w bounding box */
516 /* functions for implementing read-only registers */
517 int f_nexttrap(void); /* .t */
518 int f_divreg(void); /* .z */
519 int f_hpos(void); /* .k */