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