Annotation of mandoc/mdoc_man.c, Revision 1.30
1.30 ! schwarze 1: /* $Id: mdoc_man.c,v 1.29 2012/07/09 23:53:36 schwarze Exp $ */
1.1 schwarze 2: /*
1.11 schwarze 3: * Copyright (c) 2011, 2012 Ingo Schwarze <schwarze@openbsd.org>
1.1 schwarze 4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
1.7 kristaps 17: #ifdef HAVE_CONFIG_H
18: #include "config.h"
19: #endif
20:
1.12 schwarze 21: #include <assert.h>
1.1 schwarze 22: #include <stdio.h>
23: #include <string.h>
24:
25: #include "mandoc.h"
1.11 schwarze 26: #include "out.h"
1.4 kristaps 27: #include "man.h"
1.1 schwarze 28: #include "mdoc.h"
29: #include "main.h"
30:
1.5 kristaps 31: #define DECL_ARGS const struct mdoc_meta *m, \
1.20 schwarze 32: const struct mdoc_node *n
1.1 schwarze 33:
34: struct manact {
1.5 kristaps 35: int (*cond)(DECL_ARGS); /* DON'T run actions */
36: int (*pre)(DECL_ARGS); /* pre-node action */
37: void (*post)(DECL_ARGS); /* post-node action */
38: const char *prefix; /* pre-node string constant */
39: const char *suffix; /* post-node string constant */
1.1 schwarze 40: };
41:
1.5 kristaps 42: static int cond_body(DECL_ARGS);
1.1 schwarze 43: static int cond_head(DECL_ARGS);
1.26 schwarze 44: static void font_push(char);
45: static void font_pop(void);
1.5 kristaps 46: static void post_bd(DECL_ARGS);
1.27 schwarze 47: static void post_bf(DECL_ARGS);
1.13 schwarze 48: static void post_bk(DECL_ARGS);
1.30 ! schwarze 49: static void post_bl(DECL_ARGS);
1.5 kristaps 50: static void post_dl(DECL_ARGS);
1.1 schwarze 51: static void post_enc(DECL_ARGS);
1.28 schwarze 52: static void post_eo(DECL_ARGS);
1.17 schwarze 53: static void post_fa(DECL_ARGS);
1.29 schwarze 54: static void post_fd(DECL_ARGS);
1.26 schwarze 55: static void post_fl(DECL_ARGS);
1.16 schwarze 56: static void post_fn(DECL_ARGS);
1.17 schwarze 57: static void post_fo(DECL_ARGS);
1.26 schwarze 58: static void post_font(DECL_ARGS);
1.15 schwarze 59: static void post_in(DECL_ARGS);
1.30 ! schwarze 60: static void post_it(DECL_ARGS);
1.14 schwarze 61: static void post_lb(DECL_ARGS);
1.5 kristaps 62: static void post_nm(DECL_ARGS);
1.1 schwarze 63: static void post_percent(DECL_ARGS);
1.5 kristaps 64: static void post_pf(DECL_ARGS);
1.3 schwarze 65: static void post_sect(DECL_ARGS);
1.5 kristaps 66: static void post_sp(DECL_ARGS);
1.18 schwarze 67: static void post_vt(DECL_ARGS);
1.22 schwarze 68: static int pre_an(DECL_ARGS);
1.3 schwarze 69: static int pre_ap(DECL_ARGS);
70: static int pre_bd(DECL_ARGS);
1.27 schwarze 71: static int pre_bf(DECL_ARGS);
1.13 schwarze 72: static int pre_bk(DECL_ARGS);
1.30 ! schwarze 73: static int pre_bl(DECL_ARGS);
1.3 schwarze 74: static int pre_br(DECL_ARGS);
1.8 schwarze 75: static int pre_bx(DECL_ARGS);
1.1 schwarze 76: static int pre_dl(DECL_ARGS);
1.5 kristaps 77: static int pre_enc(DECL_ARGS);
1.26 schwarze 78: static int pre_em(DECL_ARGS);
1.17 schwarze 79: static int pre_fa(DECL_ARGS);
1.29 schwarze 80: static int pre_fd(DECL_ARGS);
1.26 schwarze 81: static int pre_fl(DECL_ARGS);
1.16 schwarze 82: static int pre_fn(DECL_ARGS);
1.17 schwarze 83: static int pre_fo(DECL_ARGS);
1.23 schwarze 84: static int pre_ft(DECL_ARGS);
1.15 schwarze 85: static int pre_in(DECL_ARGS);
1.1 schwarze 86: static int pre_it(DECL_ARGS);
1.24 schwarze 87: static int pre_lk(DECL_ARGS);
1.26 schwarze 88: static int pre_li(DECL_ARGS);
1.1 schwarze 89: static int pre_nm(DECL_ARGS);
1.25 schwarze 90: static int pre_no(DECL_ARGS);
1.1 schwarze 91: static int pre_ns(DECL_ARGS);
92: static int pre_pp(DECL_ARGS);
1.12 schwarze 93: static int pre_sm(DECL_ARGS);
1.3 schwarze 94: static int pre_sp(DECL_ARGS);
1.5 kristaps 95: static int pre_sect(DECL_ARGS);
1.26 schwarze 96: static int pre_sy(DECL_ARGS);
1.23 schwarze 97: static void pre_syn(const struct mdoc_node *);
1.18 schwarze 98: static int pre_vt(DECL_ARGS);
1.8 schwarze 99: static int pre_ux(DECL_ARGS);
1.1 schwarze 100: static int pre_xr(DECL_ARGS);
1.20 schwarze 101: static void print_word(const char *);
102: static void print_offs(const char *);
1.30 ! schwarze 103: static void print_width(const char *);
! 104: static void print_count(int *);
1.5 kristaps 105: static void print_node(DECL_ARGS);
1.1 schwarze 106:
1.3 schwarze 107: static const struct manact manacts[MDOC_MAX + 1] = {
108: { NULL, pre_ap, NULL, NULL, NULL }, /* Ap */
109: { NULL, NULL, NULL, NULL, NULL }, /* Dd */
110: { NULL, NULL, NULL, NULL, NULL }, /* Dt */
1.8 schwarze 111: { NULL, NULL, NULL, NULL, NULL }, /* Os */
1.3 schwarze 112: { NULL, pre_sect, post_sect, ".SH", NULL }, /* Sh */
113: { NULL, pre_sect, post_sect, ".SS", NULL }, /* Ss */
1.1 schwarze 114: { NULL, pre_pp, NULL, NULL, NULL }, /* Pp */
1.3 schwarze 115: { cond_body, pre_dl, post_dl, NULL, NULL }, /* D1 */
1.1 schwarze 116: { cond_body, pre_dl, post_dl, NULL, NULL }, /* Dl */
1.3 schwarze 117: { cond_body, pre_bd, post_bd, NULL, NULL }, /* Bd */
118: { NULL, NULL, NULL, NULL, NULL }, /* Ed */
1.30 ! schwarze 119: { cond_body, pre_bl, post_bl, NULL, NULL }, /* Bl */
1.3 schwarze 120: { NULL, NULL, NULL, NULL, NULL }, /* El */
1.30 ! schwarze 121: { NULL, pre_it, post_it, NULL, NULL }, /* It */
1.26 schwarze 122: { NULL, pre_em, post_font, NULL, NULL }, /* Ad */
1.22 schwarze 123: { NULL, pre_an, NULL, NULL, NULL }, /* An */
1.26 schwarze 124: { NULL, pre_em, post_font, NULL, NULL }, /* Ar */
125: { NULL, pre_sy, post_font, NULL, NULL }, /* Cd */
126: { NULL, pre_sy, post_font, NULL, NULL }, /* Cm */
127: { NULL, pre_li, post_font, NULL, NULL }, /* Dv */
128: { NULL, pre_li, post_font, NULL, NULL }, /* Er */
129: { NULL, pre_li, post_font, NULL, NULL }, /* Ev */
1.1 schwarze 130: { NULL, pre_enc, post_enc, "The \\fB",
131: "\\fP\nutility exits 0 on success, and >0 if an error occurs."
132: }, /* Ex */
1.17 schwarze 133: { NULL, pre_fa, post_fa, NULL, NULL }, /* Fa */
1.29 schwarze 134: { NULL, pre_fd, post_fd, NULL, NULL }, /* Fd */
1.26 schwarze 135: { NULL, pre_fl, post_fl, NULL, NULL }, /* Fl */
1.16 schwarze 136: { NULL, pre_fn, post_fn, NULL, NULL }, /* Fn */
1.26 schwarze 137: { NULL, pre_ft, post_font, NULL, NULL }, /* Ft */
138: { NULL, pre_sy, post_font, NULL, NULL }, /* Ic */
1.15 schwarze 139: { NULL, pre_in, post_in, NULL, NULL }, /* In */
1.26 schwarze 140: { NULL, pre_li, post_font, NULL, NULL }, /* Li */
1.1 schwarze 141: { cond_head, pre_enc, NULL, "\\- ", NULL }, /* Nd */
142: { NULL, pre_nm, post_nm, NULL, NULL }, /* Nm */
143: { cond_body, pre_enc, post_enc, "[", "]" }, /* Op */
1.8 schwarze 144: { NULL, NULL, NULL, NULL, NULL }, /* Ot */
1.26 schwarze 145: { NULL, pre_em, post_font, NULL, NULL }, /* Pa */
1.6 kristaps 146: { NULL, pre_enc, post_enc, "The \\fB",
147: "\\fP\nfunction returns the value 0 if successful;\n"
148: "otherwise the value -1 is returned and the global\n"
149: "variable \\fIerrno\\fP is set to indicate the error."
150: }, /* Rv */
1.8 schwarze 151: { NULL, NULL, NULL, NULL, NULL }, /* St */
1.26 schwarze 152: { NULL, pre_em, post_font, NULL, NULL }, /* Va */
1.18 schwarze 153: { NULL, pre_vt, post_vt, NULL, NULL }, /* Vt */
1.8 schwarze 154: { NULL, pre_xr, NULL, NULL, NULL }, /* Xr */
1.1 schwarze 155: { NULL, NULL, post_percent, NULL, NULL }, /* _%A */
156: { NULL, NULL, NULL, NULL, NULL }, /* _%B */
157: { NULL, NULL, post_percent, NULL, NULL }, /* _%D */
158: { NULL, NULL, NULL, NULL, NULL }, /* _%I */
159: { NULL, pre_enc, post_percent, "\\fI", "\\fP" }, /* %J */
160: { NULL, NULL, NULL, NULL, NULL }, /* _%N */
161: { NULL, NULL, NULL, NULL, NULL }, /* _%O */
162: { NULL, NULL, NULL, NULL, NULL }, /* _%P */
163: { NULL, NULL, NULL, NULL, NULL }, /* _%R */
164: { NULL, pre_enc, post_percent, "\"", "\"" }, /* %T */
165: { NULL, NULL, NULL, NULL, NULL }, /* _%V */
1.9 schwarze 166: { NULL, NULL, NULL, NULL, NULL }, /* Ac */
167: { cond_body, pre_enc, post_enc, "<", ">" }, /* Ao */
1.1 schwarze 168: { cond_body, pre_enc, post_enc, "<", ">" }, /* Aq */
1.8 schwarze 169: { NULL, NULL, NULL, NULL, NULL }, /* At */
1.3 schwarze 170: { NULL, NULL, NULL, NULL, NULL }, /* Bc */
1.27 schwarze 171: { NULL, pre_bf, post_bf, NULL, NULL }, /* Bf */
1.3 schwarze 172: { cond_body, pre_enc, post_enc, "[", "]" }, /* Bo */
173: { cond_body, pre_enc, post_enc, "[", "]" }, /* Bq */
1.8 schwarze 174: { NULL, pre_ux, NULL, "BSD/OS", NULL }, /* Bsx */
175: { NULL, pre_bx, NULL, NULL, NULL }, /* Bx */
176: { NULL, NULL, NULL, NULL, NULL }, /* Db */
1.9 schwarze 177: { NULL, NULL, NULL, NULL, NULL }, /* Dc */
178: { cond_body, pre_enc, post_enc, "``", "''" }, /* Do */
1.1 schwarze 179: { cond_body, pre_enc, post_enc, "``", "''" }, /* Dq */
1.28 schwarze 180: { NULL, NULL, NULL, NULL, NULL }, /* Ec */
181: { NULL, NULL, NULL, NULL, NULL }, /* Ef */
1.26 schwarze 182: { NULL, pre_em, post_font, NULL, NULL }, /* Em */
1.28 schwarze 183: { NULL, NULL, post_eo, NULL, NULL }, /* Eo */
1.8 schwarze 184: { NULL, pre_ux, NULL, "FreeBSD", NULL }, /* Fx */
1.26 schwarze 185: { NULL, pre_sy, post_font, NULL, NULL }, /* Ms */
1.25 schwarze 186: { NULL, pre_no, NULL, NULL, NULL }, /* No */
1.1 schwarze 187: { NULL, pre_ns, NULL, NULL, NULL }, /* Ns */
1.8 schwarze 188: { NULL, pre_ux, NULL, "NetBSD", NULL }, /* Nx */
189: { NULL, pre_ux, NULL, "OpenBSD", NULL }, /* Ox */
1.3 schwarze 190: { NULL, NULL, NULL, NULL, NULL }, /* Pc */
191: { NULL, NULL, post_pf, NULL, NULL }, /* Pf */
192: { cond_body, pre_enc, post_enc, "(", ")" }, /* Po */
193: { cond_body, pre_enc, post_enc, "(", ")" }, /* Pq */
1.9 schwarze 194: { NULL, NULL, NULL, NULL, NULL }, /* Qc */
1.1 schwarze 195: { cond_body, pre_enc, post_enc, "`", "'" }, /* Ql */
1.9 schwarze 196: { cond_body, pre_enc, post_enc, "\"", "\"" }, /* Qo */
197: { cond_body, pre_enc, post_enc, "\"", "\"" }, /* Qq */
198: { NULL, NULL, NULL, NULL, NULL }, /* Re */
1.1 schwarze 199: { cond_body, pre_pp, NULL, NULL, NULL }, /* Rs */
1.9 schwarze 200: { NULL, NULL, NULL, NULL, NULL }, /* Sc */
201: { cond_body, pre_enc, post_enc, "`", "'" }, /* So */
1.1 schwarze 202: { cond_body, pre_enc, post_enc, "`", "'" }, /* Sq */
1.12 schwarze 203: { NULL, pre_sm, NULL, NULL, NULL }, /* Sm */
1.26 schwarze 204: { NULL, pre_em, post_font, NULL, NULL }, /* Sx */
205: { NULL, pre_sy, post_font, NULL, NULL }, /* Sy */
206: { NULL, pre_li, post_font, NULL, NULL }, /* Tn */
1.8 schwarze 207: { NULL, pre_ux, NULL, "UNIX", NULL }, /* Ux */
1.1 schwarze 208: { NULL, NULL, NULL, NULL, NULL }, /* _Xc */
209: { NULL, NULL, NULL, NULL, NULL }, /* _Xo */
1.17 schwarze 210: { NULL, pre_fo, post_fo, NULL, NULL }, /* Fo */
211: { NULL, NULL, NULL, NULL, NULL }, /* Fc */
1.3 schwarze 212: { cond_body, pre_enc, post_enc, "[", "]" }, /* Oo */
1.9 schwarze 213: { NULL, NULL, NULL, NULL, NULL }, /* Oc */
1.13 schwarze 214: { NULL, pre_bk, post_bk, NULL, NULL }, /* Bk */
215: { NULL, NULL, NULL, NULL, NULL }, /* Ek */
1.8 schwarze 216: { NULL, pre_ux, NULL, "is currently in beta test.", NULL }, /* Bt */
217: { NULL, NULL, NULL, NULL, NULL }, /* Hf */
218: { NULL, NULL, NULL, NULL, NULL }, /* Fr */
219: { NULL, pre_ux, NULL, "currently under development.", NULL }, /* Ud */
1.14 schwarze 220: { NULL, NULL, post_lb, NULL, NULL }, /* Lb */
1.3 schwarze 221: { NULL, pre_pp, NULL, NULL, NULL }, /* Lp */
1.24 schwarze 222: { NULL, pre_lk, NULL, NULL, NULL }, /* Lk */
1.26 schwarze 223: { NULL, pre_em, post_font, NULL, NULL }, /* Mt */
1.9 schwarze 224: { cond_body, pre_enc, post_enc, "{", "}" }, /* Brq */
225: { cond_body, pre_enc, post_enc, "{", "}" }, /* Bro */
226: { NULL, NULL, NULL, NULL, NULL }, /* Brc */
1.1 schwarze 227: { NULL, NULL, NULL, NULL, NULL }, /* _%C */
1.29 schwarze 228: { NULL, NULL, NULL, NULL, NULL }, /* Es */
229: { NULL, NULL, NULL, NULL, NULL }, /* En */
1.8 schwarze 230: { NULL, pre_ux, NULL, "DragonFly", NULL }, /* Dx */
1.1 schwarze 231: { NULL, NULL, NULL, NULL, NULL }, /* _%Q */
1.3 schwarze 232: { NULL, pre_br, NULL, NULL, NULL }, /* br */
233: { NULL, pre_sp, post_sp, NULL, NULL }, /* sp */
1.1 schwarze 234: { NULL, NULL, NULL, NULL, NULL }, /* _%U */
235: { NULL, NULL, NULL, NULL, NULL }, /* _Ta */
1.3 schwarze 236: { NULL, NULL, NULL, NULL, NULL }, /* ROOT */
1.1 schwarze 237: };
238:
1.20 schwarze 239: static int outflags;
240: #define MMAN_spc (1 << 0)
1.25 schwarze 241: #define MMAN_spc_force (1 << 1)
242: #define MMAN_nl (1 << 2)
243: #define MMAN_br (1 << 3)
244: #define MMAN_sp (1 << 4)
245: #define MMAN_Sm (1 << 5)
246: #define MMAN_Bk (1 << 6)
247: #define MMAN_An_split (1 << 7)
248: #define MMAN_An_nosplit (1 << 8)
1.20 schwarze 249:
1.26 schwarze 250: static struct {
251: char *head;
252: char *tail;
253: size_t size;
254: } fontqueue;
255:
256: static void
257: font_push(char newfont)
258: {
259:
260: if (fontqueue.head + fontqueue.size <= ++fontqueue.tail) {
261: fontqueue.size += 8;
262: fontqueue.head = mandoc_realloc(fontqueue.head,
263: fontqueue.size);
264: }
265: *fontqueue.tail = newfont;
266: print_word("\\f");
267: putchar(newfont);
268: outflags &= ~MMAN_spc;
269: }
270:
271: static void
272: font_pop(void)
273: {
274:
275: if (fontqueue.tail > fontqueue.head)
276: fontqueue.tail--;
277: outflags &= ~MMAN_spc;
278: print_word("\\f");
279: putchar(*fontqueue.tail);
280: }
281:
1.1 schwarze 282: static void
1.20 schwarze 283: print_word(const char *s)
1.1 schwarze 284: {
1.5 kristaps 285:
1.21 schwarze 286: if ((MMAN_sp | MMAN_br | MMAN_nl) & outflags) {
1.5 kristaps 287: /*
288: * If we need a newline, print it now and start afresh.
289: */
1.21 schwarze 290: if (MMAN_sp & outflags)
291: printf("\n.sp\n");
292: else if (MMAN_br & outflags)
293: printf("\n.br\n");
294: else if (MMAN_nl & outflags)
295: putchar('\n');
296: outflags &= ~(MMAN_sp|MMAN_br|MMAN_nl|MMAN_spc);
1.20 schwarze 297: } else if (MMAN_spc & outflags && '\0' != s[0])
1.5 kristaps 298: /*
1.25 schwarze 299: * If we need a space, only print it if
300: * (1) it is forced by `No' or
301: * (2) what follows is not terminating punctuation or
302: * (3) what follows is longer than one character.
1.5 kristaps 303: */
1.25 schwarze 304: if (MMAN_spc_force & outflags ||
305: NULL == strchr(".,:;)]?!", s[0]) || '\0' != s[1]) {
1.20 schwarze 306: if (MMAN_Bk & outflags) {
1.13 schwarze 307: putchar('\\');
308: putchar('~');
309: } else
310: putchar(' ');
311: }
1.5 kristaps 312:
313: /*
314: * Reassign needing space if we're not following opening
315: * punctuation.
316: */
1.20 schwarze 317: if (MMAN_Sm & outflags &&
318: (('(' != s[0] && '[' != s[0]) || '\0' != s[1]))
319: outflags |= MMAN_spc;
320: else
321: outflags &= ~MMAN_spc;
1.25 schwarze 322: outflags &= ~MMAN_spc_force;
1.5 kristaps 323:
1.1 schwarze 324: for ( ; *s; s++) {
325: switch (*s) {
326: case (ASCII_NBRSP):
327: printf("\\~");
328: break;
329: case (ASCII_HYPH):
330: putchar('-');
331: break;
332: default:
1.5 kristaps 333: putchar((unsigned char)*s);
1.1 schwarze 334: break;
335: }
336: }
1.4 kristaps 337: }
338:
1.11 schwarze 339: static void
1.20 schwarze 340: print_offs(const char *v)
1.11 schwarze 341: {
342: char buf[24];
343: struct roffsu su;
344: size_t sz;
345:
346: if (NULL == v || '\0' == *v || 0 == strcmp(v, "left"))
347: sz = 0;
348: else if (0 == strcmp(v, "indent"))
349: sz = 6;
350: else if (0 == strcmp(v, "indent-two"))
351: sz = 12;
352: else if (a2roffsu(v, &su, SCALE_MAX)) {
1.20 schwarze 353: print_word(v);
1.11 schwarze 354: return;
355: } else
356: sz = strlen(v);
357:
358: snprintf(buf, sizeof(buf), "%ldn", sz);
1.20 schwarze 359: print_word(buf);
1.11 schwarze 360: }
361:
1.4 kristaps 362: void
1.30 ! schwarze 363: print_width(const char *v)
! 364: {
! 365: char buf[24];
! 366: struct roffsu su;
! 367: size_t sz;
! 368:
! 369: if (a2roffsu(v, &su, SCALE_MAX)) {
! 370: if (SCALE_EN == su.unit)
! 371: sz = su.scale;
! 372: else {
! 373: print_word(v);
! 374: return;
! 375: }
! 376: } else
! 377: sz = strlen(v);
! 378:
! 379: snprintf(buf, sizeof(buf), "%ldn", sz + 2);
! 380: print_word(buf);
! 381: }
! 382:
! 383: void
! 384: print_count(int *count)
! 385: {
! 386: char buf[12];
! 387:
! 388: snprintf(buf, sizeof(buf), "%d.", ++*count);
! 389: print_word(buf);
! 390: }
! 391:
! 392: void
1.4 kristaps 393: man_man(void *arg, const struct man *man)
394: {
395:
1.5 kristaps 396: /*
397: * Dump the keep buffer.
398: * We're guaranteed by now that this exists (is non-NULL).
399: * Flush stdout afterward, just in case.
400: */
1.4 kristaps 401: fputs(mparse_getkeep(man_mparse(man)), stdout);
1.5 kristaps 402: fflush(stdout);
1.1 schwarze 403: }
404:
405: void
406: man_mdoc(void *arg, const struct mdoc *mdoc)
407: {
408: const struct mdoc_meta *m;
409: const struct mdoc_node *n;
410:
411: m = mdoc_meta(mdoc);
412: n = mdoc_node(mdoc);
413:
1.3 schwarze 414: printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
1.5 kristaps 415: m->title, m->msec, m->date, m->os, m->vol);
1.1 schwarze 416:
1.20 schwarze 417: outflags = MMAN_nl | MMAN_Sm;
1.26 schwarze 418: if (0 == fontqueue.size) {
419: fontqueue.size = 8;
420: fontqueue.head = fontqueue.tail = mandoc_malloc(8);
421: *fontqueue.tail = 'R';
422: }
1.20 schwarze 423: print_node(m, n);
1.3 schwarze 424: putchar('\n');
1.1 schwarze 425: }
426:
427: static void
428: print_node(DECL_ARGS)
429: {
430: const struct mdoc_node *prev, *sub;
1.5 kristaps 431: const struct manact *act;
1.1 schwarze 432: int cond, do_sub;
1.5 kristaps 433:
434: /*
435: * Break the line if we were parsed subsequent the current node.
436: * This makes the page structure be more consistent.
437: */
1.1 schwarze 438: prev = n->prev ? n->prev : n->parent;
1.27 schwarze 439: if (MMAN_spc & outflags && prev && prev->line < n->line)
1.20 schwarze 440: outflags |= MMAN_nl;
1.1 schwarze 441:
1.5 kristaps 442: act = NULL;
1.1 schwarze 443: cond = 0;
444: do_sub = 1;
1.5 kristaps 445:
1.1 schwarze 446: if (MDOC_TEXT == n->type) {
1.5 kristaps 447: /*
448: * Make sure that we don't happen to start with a
449: * control character at the start of a line.
450: */
1.20 schwarze 451: if (MMAN_nl & outflags && ('.' == *n->string ||
1.5 kristaps 452: '\'' == *n->string)) {
1.20 schwarze 453: print_word("\\&");
454: outflags &= ~MMAN_spc;
1.3 schwarze 455: }
1.20 schwarze 456: print_word(n->string);
1.1 schwarze 457: } else {
1.5 kristaps 458: /*
459: * Conditionally run the pre-node action handler for a
460: * node.
461: */
1.1 schwarze 462: act = manacts + n->tok;
1.20 schwarze 463: cond = NULL == act->cond || (*act->cond)(m, n);
1.1 schwarze 464: if (cond && act->pre)
1.20 schwarze 465: do_sub = (*act->pre)(m, n);
1.1 schwarze 466: }
467:
1.5 kristaps 468: /*
469: * Conditionally run all child nodes.
470: * Note that this iterates over children instead of using
471: * recursion. This prevents unnecessary depth in the stack.
472: */
1.1 schwarze 473: if (do_sub)
474: for (sub = n->child; sub; sub = sub->next)
1.20 schwarze 475: print_node(m, sub);
1.1 schwarze 476:
1.5 kristaps 477: /*
478: * Lastly, conditionally run the post-node handler.
479: */
1.1 schwarze 480: if (cond && act->post)
1.20 schwarze 481: (*act->post)(m, n);
1.1 schwarze 482: }
483:
484: static int
485: cond_head(DECL_ARGS)
486: {
1.5 kristaps 487:
1.1 schwarze 488: return(MDOC_HEAD == n->type);
489: }
490:
491: static int
492: cond_body(DECL_ARGS)
493: {
1.5 kristaps 494:
1.1 schwarze 495: return(MDOC_BODY == n->type);
496: }
497:
498: static int
499: pre_enc(DECL_ARGS)
500: {
1.5 kristaps 501: const char *prefix;
1.1 schwarze 502:
503: prefix = manacts[n->tok].prefix;
504: if (NULL == prefix)
505: return(1);
1.20 schwarze 506: print_word(prefix);
507: outflags &= ~MMAN_spc;
1.1 schwarze 508: return(1);
509: }
510:
511: static void
512: post_enc(DECL_ARGS)
513: {
514: const char *suffix;
515:
516: suffix = manacts[n->tok].suffix;
517: if (NULL == suffix)
518: return;
1.20 schwarze 519: outflags &= ~MMAN_spc;
520: print_word(suffix);
1.26 schwarze 521: }
522:
523: static void
524: post_font(DECL_ARGS)
525: {
526:
527: font_pop();
1.1 schwarze 528: }
529:
1.5 kristaps 530: /*
531: * Used in listings (percent = %A, e.g.).
532: * FIXME: this is incomplete.
533: * It doesn't print a nice ", and" for lists.
534: */
1.1 schwarze 535: static void
536: post_percent(DECL_ARGS)
537: {
538:
1.20 schwarze 539: post_enc(m, n);
1.1 schwarze 540: if (n->next)
1.20 schwarze 541: print_word(",");
1.1 schwarze 542: else {
1.20 schwarze 543: print_word(".");
544: outflags |= MMAN_nl;
1.1 schwarze 545: }
546: }
547:
1.5 kristaps 548: /*
549: * Print before a section header.
550: */
1.1 schwarze 551: static int
1.3 schwarze 552: pre_sect(DECL_ARGS)
553: {
554:
555: if (MDOC_HEAD != n->type)
556: return(1);
1.20 schwarze 557: outflags |= MMAN_nl;
558: print_word(manacts[n->tok].prefix);
559: print_word("\"");
560: outflags &= ~MMAN_spc;
1.3 schwarze 561: return(1);
562: }
563:
1.5 kristaps 564: /*
565: * Print subsequent a section header.
566: */
1.3 schwarze 567: static void
568: post_sect(DECL_ARGS)
569: {
570:
571: if (MDOC_HEAD != n->type)
572: return;
1.20 schwarze 573: outflags &= ~MMAN_spc;
574: print_word("\"");
575: outflags |= MMAN_nl;
1.22 schwarze 576: if (MDOC_Sh == n->tok && SEC_AUTHORS == n->sec)
577: outflags &= ~(MMAN_An_split | MMAN_An_nosplit);
578: }
579:
1.23 schwarze 580: /* See mdoc_term.c, synopsis_pre() for comments. */
581: static void
582: pre_syn(const struct mdoc_node *n)
583: {
584:
585: if (NULL == n->prev || ! (MDOC_SYNPRETTY & n->flags))
586: return;
587:
588: if (n->prev->tok == n->tok &&
589: MDOC_Ft != n->tok &&
590: MDOC_Fo != n->tok &&
591: MDOC_Fn != n->tok) {
592: outflags |= MMAN_br;
593: return;
594: }
595:
596: switch (n->prev->tok) {
597: case (MDOC_Fd):
598: /* FALLTHROUGH */
599: case (MDOC_Fn):
600: /* FALLTHROUGH */
601: case (MDOC_Fo):
602: /* FALLTHROUGH */
603: case (MDOC_In):
604: /* FALLTHROUGH */
605: case (MDOC_Vt):
606: outflags |= MMAN_sp;
607: break;
608: case (MDOC_Ft):
609: if (MDOC_Fn != n->tok && MDOC_Fo != n->tok) {
610: outflags |= MMAN_sp;
611: break;
612: }
613: /* FALLTHROUGH */
614: default:
615: outflags |= MMAN_br;
616: break;
617: }
618: }
619:
1.22 schwarze 620: static int
621: pre_an(DECL_ARGS)
622: {
623:
624: switch (n->norm->An.auth) {
625: case (AUTH_split):
626: outflags &= ~MMAN_An_nosplit;
627: outflags |= MMAN_An_split;
628: return(0);
629: case (AUTH_nosplit):
630: outflags &= ~MMAN_An_split;
631: outflags |= MMAN_An_nosplit;
632: return(0);
633: default:
634: if (MMAN_An_split & outflags)
635: outflags |= MMAN_br;
636: else if (SEC_AUTHORS == n->sec &&
637: ! (MMAN_An_nosplit & outflags))
638: outflags |= MMAN_An_split;
639: return(1);
640: }
1.3 schwarze 641: }
642:
643: static int
644: pre_ap(DECL_ARGS)
645: {
646:
1.20 schwarze 647: outflags &= ~MMAN_spc;
648: print_word("'");
649: outflags &= ~MMAN_spc;
1.3 schwarze 650: return(0);
651: }
652:
653: static int
654: pre_bd(DECL_ARGS)
655: {
656:
1.21 schwarze 657: if (0 == n->norm->Bd.comp)
658: outflags |= MMAN_sp;
1.3 schwarze 659: if (DISP_unfilled == n->norm->Bd.type ||
660: DISP_literal == n->norm->Bd.type) {
1.20 schwarze 661: outflags |= MMAN_nl;
662: print_word(".nf");
1.3 schwarze 663: }
1.20 schwarze 664: outflags |= MMAN_nl;
665: print_word(".RS");
666: print_offs(n->norm->Bd.offs);
667: outflags |= MMAN_nl;
1.3 schwarze 668: return(1);
669: }
670:
671: static void
672: post_bd(DECL_ARGS)
673: {
674:
1.20 schwarze 675: outflags |= MMAN_nl;
676: print_word(".RE");
1.3 schwarze 677: if (DISP_unfilled == n->norm->Bd.type ||
678: DISP_literal == n->norm->Bd.type) {
1.20 schwarze 679: outflags |= MMAN_nl;
680: print_word(".fi");
1.3 schwarze 681: }
1.20 schwarze 682: outflags |= MMAN_nl;
1.13 schwarze 683: }
684:
685: static int
1.27 schwarze 686: pre_bf(DECL_ARGS)
687: {
688:
689: switch (n->type) {
690: case (MDOC_BLOCK):
691: return(1);
692: case (MDOC_BODY):
693: break;
694: default:
695: return(0);
696: }
697: switch (n->norm->Bf.font) {
698: case (FONT_Em):
699: font_push('I');
700: break;
701: case (FONT_Sy):
702: font_push('B');
703: break;
704: default:
705: font_push('R');
706: break;
707: }
708: return(1);
709: }
710:
711: static void
712: post_bf(DECL_ARGS)
713: {
714:
715: if (MDOC_BODY == n->type)
716: font_pop();
717: }
718:
719: static int
1.13 schwarze 720: pre_bk(DECL_ARGS)
721: {
722:
723: switch (n->type) {
724: case (MDOC_BLOCK):
725: return(1);
726: case (MDOC_BODY):
1.20 schwarze 727: outflags |= MMAN_Bk;
1.13 schwarze 728: return(1);
729: default:
730: return(0);
731: }
732: }
733:
734: static void
735: post_bk(DECL_ARGS)
736: {
737:
738: if (MDOC_BODY == n->type)
1.20 schwarze 739: outflags &= ~MMAN_Bk;
1.3 schwarze 740: }
741:
742: static int
1.30 ! schwarze 743: pre_bl(DECL_ARGS)
! 744: {
! 745:
! 746: if (LIST_enum == n->norm->Bl.type)
! 747: n->norm->Bl.count = 0;
! 748: return(1);
! 749: }
! 750:
! 751: static void
! 752: post_bl(DECL_ARGS)
! 753: {
! 754:
! 755: if (LIST_enum == n->norm->Bl.type)
! 756: n->norm->Bl.count = 0;
! 757: }
! 758:
! 759: static int
1.3 schwarze 760: pre_br(DECL_ARGS)
761: {
762:
1.21 schwarze 763: outflags |= MMAN_br;
1.3 schwarze 764: return(0);
765: }
766:
767: static int
1.8 schwarze 768: pre_bx(DECL_ARGS)
769: {
770:
771: n = n->child;
772: if (n) {
1.20 schwarze 773: print_word(n->string);
774: outflags &= ~MMAN_spc;
1.8 schwarze 775: n = n->next;
776: }
1.20 schwarze 777: print_word("BSD");
1.8 schwarze 778: if (NULL == n)
779: return(0);
1.20 schwarze 780: outflags &= ~MMAN_spc;
781: print_word("-");
782: outflags &= ~MMAN_spc;
783: print_word(n->string);
1.8 schwarze 784: return(0);
785: }
786:
787: static int
1.1 schwarze 788: pre_dl(DECL_ARGS)
789: {
790:
1.20 schwarze 791: outflags |= MMAN_nl;
792: print_word(".RS 6n");
793: outflags |= MMAN_nl;
1.1 schwarze 794: return(1);
795: }
796:
797: static void
798: post_dl(DECL_ARGS)
799: {
800:
1.20 schwarze 801: outflags |= MMAN_nl;
802: print_word(".RE");
803: outflags |= MMAN_nl;
1.16 schwarze 804: }
805:
806: static int
1.26 schwarze 807: pre_em(DECL_ARGS)
808: {
809:
810: font_push('I');
811: return(1);
1.28 schwarze 812: }
813:
814: static void
815: post_eo(DECL_ARGS)
816: {
817:
818: if (MDOC_HEAD == n->type || MDOC_BODY == n->type)
819: outflags &= ~MMAN_spc;
1.26 schwarze 820: }
821:
822: static int
1.17 schwarze 823: pre_fa(DECL_ARGS)
824: {
825:
826: if (MDOC_Fa == n->tok)
827: n = n->child;
828:
829: while (NULL != n) {
1.26 schwarze 830: font_push('I');
1.20 schwarze 831: print_node(m, n);
1.26 schwarze 832: font_pop();
1.17 schwarze 833: if (NULL != (n = n->next))
1.20 schwarze 834: print_word(",");
1.17 schwarze 835: }
836: return(0);
837: }
838:
839: static void
840: post_fa(DECL_ARGS)
841: {
842:
843: if (NULL != n->next && MDOC_Fa == n->next->tok)
1.20 schwarze 844: print_word(",");
1.29 schwarze 845: }
846:
847: static int
848: pre_fd(DECL_ARGS)
849: {
850:
851: pre_syn(n);
852: font_push('B');
853: return(1);
854: }
855:
856: static void
857: post_fd(DECL_ARGS)
858: {
859:
860: font_pop();
861: outflags |= MMAN_br;
1.17 schwarze 862: }
863:
864: static int
1.26 schwarze 865: pre_fl(DECL_ARGS)
866: {
867:
868: font_push('B');
869: print_word("-");
870: outflags &= ~MMAN_spc;
871: return(1);
872: }
873:
874: static void
875: post_fl(DECL_ARGS)
876: {
877:
878: font_pop();
1.27 schwarze 879: if (0 == n->nchild && NULL != n->next &&
880: n->next->line == n->line)
1.26 schwarze 881: outflags &= ~MMAN_spc;
882: }
883:
884: static int
1.16 schwarze 885: pre_fn(DECL_ARGS)
886: {
887:
1.23 schwarze 888: pre_syn(n);
889:
1.16 schwarze 890: n = n->child;
891: if (NULL == n)
892: return(0);
893:
1.26 schwarze 894: font_push('B');
1.20 schwarze 895: print_node(m, n);
1.26 schwarze 896: font_pop();
1.20 schwarze 897: outflags &= ~MMAN_spc;
1.26 schwarze 898: print_word("(");
1.20 schwarze 899: outflags &= ~MMAN_spc;
900: return(pre_fa(m, n->next));
1.16 schwarze 901: }
902:
903: static void
904: post_fn(DECL_ARGS)
905: {
906:
1.20 schwarze 907: print_word(")");
1.16 schwarze 908: if (MDOC_SYNPRETTY & n->flags) {
1.20 schwarze 909: print_word(";");
1.21 schwarze 910: outflags |= MMAN_br;
1.17 schwarze 911: }
912: }
913:
914: static int
915: pre_fo(DECL_ARGS)
916: {
917:
918: switch (n->type) {
1.23 schwarze 919: case (MDOC_BLOCK):
920: pre_syn(n);
921: break;
1.17 schwarze 922: case (MDOC_HEAD):
1.26 schwarze 923: font_push('B');
1.17 schwarze 924: break;
925: case (MDOC_BODY):
1.20 schwarze 926: outflags &= ~MMAN_spc;
927: print_word("(");
928: outflags &= ~MMAN_spc;
1.17 schwarze 929: break;
930: default:
931: break;
932: }
933: return(1);
934: }
935:
936: static void
937: post_fo(DECL_ARGS)
938: {
939:
940: switch (n->type) {
941: case (MDOC_HEAD):
1.26 schwarze 942: font_pop();
1.17 schwarze 943: break;
944: case (MDOC_BODY):
1.20 schwarze 945: post_fn(m, n);
1.17 schwarze 946: break;
947: default:
948: break;
1.16 schwarze 949: }
1.15 schwarze 950: }
951:
952: static int
1.23 schwarze 953: pre_ft(DECL_ARGS)
954: {
955:
956: pre_syn(n);
1.26 schwarze 957: font_push('I');
1.23 schwarze 958: return(1);
959: }
960:
961: static int
1.15 schwarze 962: pre_in(DECL_ARGS)
963: {
964:
965: if (MDOC_SYNPRETTY & n->flags) {
1.23 schwarze 966: pre_syn(n);
1.26 schwarze 967: font_push('B');
968: print_word("#include <");
969: outflags &= ~MMAN_spc;
970: } else {
971: print_word("<");
972: outflags &= ~MMAN_spc;
973: font_push('I');
974: }
1.15 schwarze 975: return(1);
976: }
977:
978: static void
979: post_in(DECL_ARGS)
980: {
981:
982: if (MDOC_SYNPRETTY & n->flags) {
1.26 schwarze 983: outflags &= ~MMAN_spc;
984: print_word(">");
985: font_pop();
1.21 schwarze 986: outflags |= MMAN_br;
1.26 schwarze 987: } else {
988: font_pop();
989: outflags &= ~MMAN_spc;
990: print_word(">");
991: }
1.1 schwarze 992: }
993:
994: static int
995: pre_it(DECL_ARGS)
996: {
997: const struct mdoc_node *bln;
998:
1.30 ! schwarze 999: switch (n->type) {
! 1000: case (MDOC_HEAD):
1.20 schwarze 1001: outflags |= MMAN_nl;
1.30 ! schwarze 1002: bln = n->parent->parent;
1.3 schwarze 1003: switch (bln->norm->Bl.type) {
1.30 ! schwarze 1004: case (LIST_item):
! 1005: if (bln->norm->Bl.comp)
! 1006: outflags |= MMAN_br;
! 1007: else
! 1008: outflags |= MMAN_sp;
! 1009: return(0);
! 1010: case (LIST_inset):
! 1011: /* FALLTHROUGH */
! 1012: case (LIST_diag):
! 1013: /* FALLTHROUGH */
! 1014: case (LIST_ohang):
! 1015: if (bln->norm->Bl.comp)
! 1016: outflags |= MMAN_br;
! 1017: else
! 1018: outflags |= MMAN_sp;
! 1019: if (bln->norm->Bl.type == LIST_diag)
! 1020: print_word(".B \"");
! 1021: else
! 1022: print_word(".R \"");
! 1023: outflags &= ~MMAN_spc;
! 1024: return(1);
1.3 schwarze 1025: case (LIST_bullet):
1.30 ! schwarze 1026: /* FALLTHROUGH */
! 1027: case (LIST_dash):
! 1028: /* FALLTHROUGH */
! 1029: case (LIST_hyphen):
! 1030: print_word(".TP");
! 1031: print_width(bln->norm->Bl.width);
! 1032: outflags |= MMAN_nl;
! 1033: font_push('B');
! 1034: if (LIST_bullet == bln->norm->Bl.type)
! 1035: print_word("o");
! 1036: else
! 1037: print_word("-");
! 1038: font_pop();
! 1039: break;
! 1040: case (LIST_enum):
! 1041: print_word(".TP");
! 1042: print_width(bln->norm->Bl.width);
! 1043: outflags |= MMAN_nl;
! 1044: print_count(&bln->norm->Bl.count);
1.20 schwarze 1045: outflags |= MMAN_nl;
1.3 schwarze 1046: break;
1047: default:
1048: if (bln->norm->Bl.width)
1.30 ! schwarze 1049: print_width(bln->norm->Bl.width);
1.3 schwarze 1050: break;
1051: }
1.20 schwarze 1052: outflags |= MMAN_nl;
1.30 ! schwarze 1053: default:
! 1054: break;
1.1 schwarze 1055: }
1056: return(1);
1.30 ! schwarze 1057: }
! 1058:
! 1059: static void
! 1060: post_it(DECL_ARGS)
! 1061: {
! 1062: const struct mdoc_node *bln;
! 1063:
! 1064: if (MDOC_HEAD == n->type) {
! 1065: bln = n->parent->parent;
! 1066: switch (bln->norm->Bl.type) {
! 1067: case (LIST_diag):
! 1068: outflags &= ~MMAN_spc;
! 1069: print_word("\\ ");
! 1070: break;
! 1071: case (LIST_ohang):
! 1072: outflags |= MMAN_br;
! 1073: break;
! 1074: default:
! 1075: break;
! 1076: }
! 1077: }
1.14 schwarze 1078: }
1079:
1080: static void
1081: post_lb(DECL_ARGS)
1082: {
1083:
1.21 schwarze 1084: if (SEC_LIBRARY == n->sec)
1085: outflags |= MMAN_br;
1.24 schwarze 1086: }
1087:
1088: static int
1089: pre_lk(DECL_ARGS)
1090: {
1091: const struct mdoc_node *link, *descr;
1092:
1093: if (NULL == (link = n->child))
1094: return(0);
1095:
1096: if (NULL != (descr = link->next)) {
1.26 schwarze 1097: font_push('I');
1.24 schwarze 1098: while (NULL != descr) {
1099: print_word(descr->string);
1100: descr = descr->next;
1101: }
1102: print_word(":");
1.26 schwarze 1103: font_pop();
1.24 schwarze 1104: }
1105:
1.26 schwarze 1106: font_push('B');
1.24 schwarze 1107: print_word(link->string);
1.26 schwarze 1108: font_pop();
1.24 schwarze 1109: return(0);
1.1 schwarze 1110: }
1111:
1112: static int
1.26 schwarze 1113: pre_li(DECL_ARGS)
1114: {
1115:
1116: font_push('R');
1117: return(1);
1118: }
1119:
1120: static int
1.1 schwarze 1121: pre_nm(DECL_ARGS)
1122: {
1123:
1.23 schwarze 1124: if (MDOC_BLOCK == n->type)
1125: pre_syn(n);
1.1 schwarze 1126: if (MDOC_ELEM != n->type && MDOC_HEAD != n->type)
1127: return(1);
1.23 schwarze 1128: if (NULL == n->child && NULL == m->name)
1129: return(0);
1.26 schwarze 1130: font_push('B');
1.1 schwarze 1131: if (NULL == n->child)
1.20 schwarze 1132: print_word(m->name);
1.1 schwarze 1133: return(1);
1134: }
1135:
1136: static void
1137: post_nm(DECL_ARGS)
1138: {
1139:
1140: if (MDOC_ELEM != n->type && MDOC_HEAD != n->type)
1141: return;
1.26 schwarze 1142: font_pop();
1.25 schwarze 1143: }
1144:
1145: static int
1146: pre_no(DECL_ARGS)
1147: {
1148:
1149: outflags |= MMAN_spc_force;
1150: return(1);
1.1 schwarze 1151: }
1152:
1153: static int
1154: pre_ns(DECL_ARGS)
1155: {
1156:
1.20 schwarze 1157: outflags &= ~MMAN_spc;
1.1 schwarze 1158: return(0);
1159: }
1160:
1.3 schwarze 1161: static void
1162: post_pf(DECL_ARGS)
1163: {
1164:
1.20 schwarze 1165: outflags &= ~MMAN_spc;
1.3 schwarze 1166: }
1167:
1.1 schwarze 1168: static int
1169: pre_pp(DECL_ARGS)
1170: {
1171:
1.20 schwarze 1172: outflags |= MMAN_nl;
1.1 schwarze 1173: if (MDOC_It == n->parent->tok)
1.20 schwarze 1174: print_word(".sp");
1.1 schwarze 1175: else
1.20 schwarze 1176: print_word(".PP");
1177: outflags |= MMAN_nl;
1.10 schwarze 1178: return(MDOC_Rs == n->tok);
1.12 schwarze 1179: }
1180:
1181: static int
1182: pre_sm(DECL_ARGS)
1183: {
1184:
1185: assert(n->child && MDOC_TEXT == n->child->type);
1186: if (0 == strcmp("on", n->child->string))
1.27 schwarze 1187: outflags |= MMAN_Sm | MMAN_spc;
1.12 schwarze 1188: else
1.20 schwarze 1189: outflags &= ~MMAN_Sm;
1.12 schwarze 1190: return(0);
1.1 schwarze 1191: }
1192:
1193: static int
1.3 schwarze 1194: pre_sp(DECL_ARGS)
1.1 schwarze 1195: {
1196:
1.20 schwarze 1197: outflags |= MMAN_nl;
1198: print_word(".sp");
1.1 schwarze 1199: return(1);
1200: }
1201:
1202: static void
1.3 schwarze 1203: post_sp(DECL_ARGS)
1.1 schwarze 1204: {
1205:
1.20 schwarze 1206: outflags |= MMAN_nl;
1.18 schwarze 1207: }
1208:
1209: static int
1.26 schwarze 1210: pre_sy(DECL_ARGS)
1211: {
1212:
1213: font_push('B');
1214: return(1);
1215: }
1216:
1217: static int
1.18 schwarze 1218: pre_vt(DECL_ARGS)
1219: {
1220:
1221: if (MDOC_SYNPRETTY & n->flags) {
1222: switch (n->type) {
1223: case (MDOC_BLOCK):
1.23 schwarze 1224: pre_syn(n);
1.18 schwarze 1225: return(1);
1226: case (MDOC_BODY):
1227: break;
1228: default:
1229: return(0);
1230: }
1231: }
1.26 schwarze 1232: font_push('I');
1.18 schwarze 1233: return(1);
1234: }
1235:
1236: static void
1237: post_vt(DECL_ARGS)
1238: {
1239:
1.19 schwarze 1240: if (MDOC_SYNPRETTY & n->flags && MDOC_BODY != n->type)
1.18 schwarze 1241: return;
1.26 schwarze 1242: font_pop();
1.1 schwarze 1243: }
1244:
1245: static int
1246: pre_xr(DECL_ARGS)
1247: {
1248:
1249: n = n->child;
1250: if (NULL == n)
1251: return(0);
1.20 schwarze 1252: print_node(m, n);
1.1 schwarze 1253: n = n->next;
1254: if (NULL == n)
1255: return(0);
1.20 schwarze 1256: outflags &= ~MMAN_spc;
1257: print_word("(");
1258: print_node(m, n);
1259: print_word(")");
1.1 schwarze 1260: return(0);
1.8 schwarze 1261: }
1262:
1263: static int
1264: pre_ux(DECL_ARGS)
1265: {
1266:
1.20 schwarze 1267: print_word(manacts[n->tok].prefix);
1.8 schwarze 1268: if (NULL == n->child)
1269: return(0);
1.20 schwarze 1270: outflags &= ~MMAN_spc;
1271: print_word("\\~");
1272: outflags &= ~MMAN_spc;
1.8 schwarze 1273: return(1);
1.1 schwarze 1274: }
CVSweb