Annotation of src/usr.bin/mandoc/mdoc_man.c, Revision 1.18
1.18 ! schwarze 1: /* $Id: mdoc_man.c,v 1.17 2012/07/08 13:56:27 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.4 schwarze 40: static void post_bd(DECL_ARGS);
1.10 schwarze 41: static void post_bk(DECL_ARGS);
1.4 schwarze 42: static void post_dl(DECL_ARGS);
1.1 schwarze 43: static void post_enc(DECL_ARGS);
1.14 schwarze 44: static void post_fa(DECL_ARGS);
1.13 schwarze 45: static void post_fn(DECL_ARGS);
1.14 schwarze 46: static void post_fo(DECL_ARGS);
1.12 schwarze 47: static void post_in(DECL_ARGS);
1.11 schwarze 48: static void post_lb(DECL_ARGS);
1.4 schwarze 49: static void post_nm(DECL_ARGS);
1.1 schwarze 50: static void post_percent(DECL_ARGS);
1.4 schwarze 51: static void post_pf(DECL_ARGS);
1.3 schwarze 52: static void post_sect(DECL_ARGS);
1.4 schwarze 53: static void post_sp(DECL_ARGS);
1.15 schwarze 54: static void post_vt(DECL_ARGS);
1.3 schwarze 55: static int pre_ap(DECL_ARGS);
56: static int pre_bd(DECL_ARGS);
1.10 schwarze 57: static int pre_bk(DECL_ARGS);
1.3 schwarze 58: static int pre_br(DECL_ARGS);
1.5 schwarze 59: static int pre_bx(DECL_ARGS);
1.1 schwarze 60: static int pre_dl(DECL_ARGS);
1.4 schwarze 61: static int pre_enc(DECL_ARGS);
1.14 schwarze 62: static int pre_fa(DECL_ARGS);
1.13 schwarze 63: static int pre_fn(DECL_ARGS);
1.14 schwarze 64: static int pre_fo(DECL_ARGS);
1.12 schwarze 65: static int pre_in(DECL_ARGS);
1.1 schwarze 66: static int pre_it(DECL_ARGS);
67: static int pre_nm(DECL_ARGS);
68: static int pre_ns(DECL_ARGS);
69: static int pre_pp(DECL_ARGS);
1.9 schwarze 70: static int pre_sm(DECL_ARGS);
1.3 schwarze 71: static int pre_sp(DECL_ARGS);
1.4 schwarze 72: static int pre_sect(DECL_ARGS);
1.15 schwarze 73: static int pre_vt(DECL_ARGS);
1.5 schwarze 74: static int pre_ux(DECL_ARGS);
1.1 schwarze 75: static int pre_xr(DECL_ARGS);
1.18 ! schwarze 76: static void print_word(const char *);
! 77: static void print_offs(const char *);
1.4 schwarze 78: static void print_node(DECL_ARGS);
1.1 schwarze 79:
1.3 schwarze 80: static const struct manact manacts[MDOC_MAX + 1] = {
81: { NULL, pre_ap, NULL, NULL, NULL }, /* Ap */
82: { NULL, NULL, NULL, NULL, NULL }, /* Dd */
83: { NULL, NULL, NULL, NULL, NULL }, /* Dt */
1.5 schwarze 84: { NULL, NULL, NULL, NULL, NULL }, /* Os */
1.3 schwarze 85: { NULL, pre_sect, post_sect, ".SH", NULL }, /* Sh */
86: { NULL, pre_sect, post_sect, ".SS", NULL }, /* Ss */
1.1 schwarze 87: { NULL, pre_pp, NULL, NULL, NULL }, /* Pp */
1.3 schwarze 88: { cond_body, pre_dl, post_dl, NULL, NULL }, /* D1 */
1.1 schwarze 89: { cond_body, pre_dl, post_dl, NULL, NULL }, /* Dl */
1.3 schwarze 90: { cond_body, pre_bd, post_bd, NULL, NULL }, /* Bd */
91: { NULL, NULL, NULL, NULL, NULL }, /* Ed */
92: { NULL, NULL, NULL, NULL, NULL }, /* Bl */
93: { NULL, NULL, NULL, NULL, NULL }, /* El */
1.1 schwarze 94: { NULL, pre_it, NULL, NULL, NULL }, /* _It */
1.6 schwarze 95: { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Ad */
1.1 schwarze 96: { NULL, NULL, NULL, NULL, NULL }, /* _An */
97: { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Ar */
1.6 schwarze 98: { NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Cd */
1.1 schwarze 99: { NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Cm */
1.6 schwarze 100: { NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Dv */
101: { NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Er */
102: { NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Ev */
1.1 schwarze 103: { NULL, pre_enc, post_enc, "The \\fB",
104: "\\fP\nutility exits 0 on success, and >0 if an error occurs."
105: }, /* Ex */
1.14 schwarze 106: { NULL, pre_fa, post_fa, NULL, NULL }, /* Fa */
1.1 schwarze 107: { NULL, NULL, NULL, NULL, NULL }, /* _Fd */
108: { NULL, pre_enc, post_enc, "\\fB-", "\\fP" }, /* Fl */
1.13 schwarze 109: { NULL, pre_fn, post_fn, NULL, NULL }, /* Fn */
110: { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Ft */
1.3 schwarze 111: { NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Ic */
1.12 schwarze 112: { NULL, pre_in, post_in, NULL, NULL }, /* In */
1.6 schwarze 113: { NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Li */
1.1 schwarze 114: { cond_head, pre_enc, NULL, "\\- ", NULL }, /* Nd */
115: { NULL, pre_nm, post_nm, NULL, NULL }, /* Nm */
116: { cond_body, pre_enc, post_enc, "[", "]" }, /* Op */
1.5 schwarze 117: { NULL, NULL, NULL, NULL, NULL }, /* Ot */
118: { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Pa */
1.4 schwarze 119: { NULL, pre_enc, post_enc, "The \\fB",
120: "\\fP\nfunction returns the value 0 if successful;\n"
121: "otherwise the value -1 is returned and the global\n"
122: "variable \\fIerrno\\fP is set to indicate the error."
123: }, /* Rv */
1.5 schwarze 124: { NULL, NULL, NULL, NULL, NULL }, /* St */
1.17 schwarze 125: { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Va */
1.15 schwarze 126: { NULL, pre_vt, post_vt, NULL, NULL }, /* Vt */
1.5 schwarze 127: { NULL, pre_xr, NULL, NULL, NULL }, /* Xr */
1.1 schwarze 128: { NULL, NULL, post_percent, NULL, NULL }, /* _%A */
129: { NULL, NULL, NULL, NULL, NULL }, /* _%B */
130: { NULL, NULL, post_percent, NULL, NULL }, /* _%D */
131: { NULL, NULL, NULL, NULL, NULL }, /* _%I */
132: { NULL, pre_enc, post_percent, "\\fI", "\\fP" }, /* %J */
133: { NULL, NULL, NULL, NULL, NULL }, /* _%N */
134: { NULL, NULL, NULL, NULL, NULL }, /* _%O */
135: { NULL, NULL, NULL, NULL, NULL }, /* _%P */
136: { NULL, NULL, NULL, NULL, NULL }, /* _%R */
137: { NULL, pre_enc, post_percent, "\"", "\"" }, /* %T */
138: { NULL, NULL, NULL, NULL, NULL }, /* _%V */
1.6 schwarze 139: { NULL, NULL, NULL, NULL, NULL }, /* Ac */
140: { cond_body, pre_enc, post_enc, "<", ">" }, /* Ao */
1.1 schwarze 141: { cond_body, pre_enc, post_enc, "<", ">" }, /* Aq */
1.5 schwarze 142: { NULL, NULL, NULL, NULL, NULL }, /* At */
1.3 schwarze 143: { NULL, NULL, NULL, NULL, NULL }, /* Bc */
1.1 schwarze 144: { NULL, NULL, NULL, NULL, NULL }, /* _Bf */
1.3 schwarze 145: { cond_body, pre_enc, post_enc, "[", "]" }, /* Bo */
146: { cond_body, pre_enc, post_enc, "[", "]" }, /* Bq */
1.5 schwarze 147: { NULL, pre_ux, NULL, "BSD/OS", NULL }, /* Bsx */
148: { NULL, pre_bx, NULL, NULL, NULL }, /* Bx */
149: { NULL, NULL, NULL, NULL, NULL }, /* Db */
1.6 schwarze 150: { NULL, NULL, NULL, NULL, NULL }, /* Dc */
151: { cond_body, pre_enc, post_enc, "``", "''" }, /* Do */
1.1 schwarze 152: { cond_body, pre_enc, post_enc, "``", "''" }, /* Dq */
153: { NULL, NULL, NULL, NULL, NULL }, /* _Ec */
154: { NULL, NULL, NULL, NULL, NULL }, /* _Ef */
1.3 schwarze 155: { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Em */
1.1 schwarze 156: { NULL, NULL, NULL, NULL, NULL }, /* _Eo */
1.5 schwarze 157: { NULL, pre_ux, NULL, "FreeBSD", NULL }, /* Fx */
1.6 schwarze 158: { NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Ms */
159: { NULL, NULL, NULL, NULL, NULL }, /* No */
1.1 schwarze 160: { NULL, pre_ns, NULL, NULL, NULL }, /* Ns */
1.5 schwarze 161: { NULL, pre_ux, NULL, "NetBSD", NULL }, /* Nx */
162: { NULL, pre_ux, NULL, "OpenBSD", NULL }, /* Ox */
1.3 schwarze 163: { NULL, NULL, NULL, NULL, NULL }, /* Pc */
164: { NULL, NULL, post_pf, NULL, NULL }, /* Pf */
165: { cond_body, pre_enc, post_enc, "(", ")" }, /* Po */
166: { cond_body, pre_enc, post_enc, "(", ")" }, /* Pq */
1.6 schwarze 167: { NULL, NULL, NULL, NULL, NULL }, /* Qc */
1.1 schwarze 168: { cond_body, pre_enc, post_enc, "`", "'" }, /* Ql */
1.6 schwarze 169: { cond_body, pre_enc, post_enc, "\"", "\"" }, /* Qo */
170: { cond_body, pre_enc, post_enc, "\"", "\"" }, /* Qq */
171: { NULL, NULL, NULL, NULL, NULL }, /* Re */
1.1 schwarze 172: { cond_body, pre_pp, NULL, NULL, NULL }, /* Rs */
1.6 schwarze 173: { NULL, NULL, NULL, NULL, NULL }, /* Sc */
174: { cond_body, pre_enc, post_enc, "`", "'" }, /* So */
1.1 schwarze 175: { cond_body, pre_enc, post_enc, "`", "'" }, /* Sq */
1.9 schwarze 176: { NULL, pre_sm, NULL, NULL, NULL }, /* Sm */
1.3 schwarze 177: { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Sx */
178: { NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Sy */
1.6 schwarze 179: { NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Tn */
1.5 schwarze 180: { NULL, pre_ux, NULL, "UNIX", NULL }, /* Ux */
1.1 schwarze 181: { NULL, NULL, NULL, NULL, NULL }, /* _Xc */
182: { NULL, NULL, NULL, NULL, NULL }, /* _Xo */
1.14 schwarze 183: { NULL, pre_fo, post_fo, NULL, NULL }, /* Fo */
184: { NULL, NULL, NULL, NULL, NULL }, /* Fc */
1.3 schwarze 185: { cond_body, pre_enc, post_enc, "[", "]" }, /* Oo */
1.6 schwarze 186: { NULL, NULL, NULL, NULL, NULL }, /* Oc */
1.10 schwarze 187: { NULL, pre_bk, post_bk, NULL, NULL }, /* Bk */
188: { NULL, NULL, NULL, NULL, NULL }, /* Ek */
1.5 schwarze 189: { NULL, pre_ux, NULL, "is currently in beta test.", NULL }, /* Bt */
190: { NULL, NULL, NULL, NULL, NULL }, /* Hf */
191: { NULL, NULL, NULL, NULL, NULL }, /* Fr */
192: { NULL, pre_ux, NULL, "currently under development.", NULL }, /* Ud */
1.11 schwarze 193: { NULL, NULL, post_lb, NULL, NULL }, /* Lb */
1.3 schwarze 194: { NULL, pre_pp, NULL, NULL, NULL }, /* Lp */
1.1 schwarze 195: { NULL, NULL, NULL, NULL, NULL }, /* _Lk */
196: { NULL, NULL, NULL, NULL, NULL }, /* _Mt */
1.6 schwarze 197: { cond_body, pre_enc, post_enc, "{", "}" }, /* Brq */
198: { cond_body, pre_enc, post_enc, "{", "}" }, /* Bro */
199: { NULL, NULL, NULL, NULL, NULL }, /* Brc */
1.1 schwarze 200: { NULL, NULL, NULL, NULL, NULL }, /* _%C */
201: { NULL, NULL, NULL, NULL, NULL }, /* _Es */
202: { NULL, NULL, NULL, NULL, NULL }, /* _En */
1.5 schwarze 203: { NULL, pre_ux, NULL, "DragonFly", NULL }, /* Dx */
1.1 schwarze 204: { NULL, NULL, NULL, NULL, NULL }, /* _%Q */
1.3 schwarze 205: { NULL, pre_br, NULL, NULL, NULL }, /* br */
206: { NULL, pre_sp, post_sp, NULL, NULL }, /* sp */
1.1 schwarze 207: { NULL, NULL, NULL, NULL, NULL }, /* _%U */
208: { NULL, NULL, NULL, NULL, NULL }, /* _Ta */
1.3 schwarze 209: { NULL, NULL, NULL, NULL, NULL }, /* ROOT */
1.1 schwarze 210: };
211:
1.18 ! schwarze 212: static int outflags;
! 213: #define MMAN_spc (1 << 0)
! 214: #define MMAN_nl (1 << 1)
! 215: #define MMAN_Sm (1 << 2)
! 216: #define MMAN_Bk (1 << 3)
! 217:
1.1 schwarze 218: static void
1.18 ! schwarze 219: print_word(const char *s)
1.1 schwarze 220: {
1.4 schwarze 221:
1.18 ! schwarze 222: if (MMAN_nl & outflags) {
1.4 schwarze 223: /*
224: * If we need a newline, print it now and start afresh.
225: */
1.1 schwarze 226: putchar('\n');
1.18 ! schwarze 227: outflags &= ~(MMAN_nl|MMAN_spc);
! 228: } else if (MMAN_spc & outflags && '\0' != s[0])
1.4 schwarze 229: /*
230: * If we need a space, only print it before
231: * (1) a nonzero length word;
232: * (2) a word that is non-punctuation; and
233: * (3) if punctuation, non-terminating puncutation.
234: */
1.10 schwarze 235: if (NULL == strchr(".,:;)]?!", s[0]) || '\0' != s[1]) {
1.18 ! schwarze 236: if (MMAN_Bk & outflags) {
1.10 schwarze 237: putchar('\\');
238: putchar('~');
239: } else
240: putchar(' ');
241: }
1.4 schwarze 242:
243: /*
244: * Reassign needing space if we're not following opening
245: * punctuation.
246: */
1.18 ! schwarze 247: if (MMAN_Sm & outflags &&
! 248: (('(' != s[0] && '[' != s[0]) || '\0' != s[1]))
! 249: outflags |= MMAN_spc;
! 250: else
! 251: outflags &= ~MMAN_spc;
1.4 schwarze 252:
1.1 schwarze 253: for ( ; *s; s++) {
254: switch (*s) {
255: case (ASCII_NBRSP):
256: printf("\\~");
257: break;
258: case (ASCII_HYPH):
259: putchar('-');
260: break;
261: default:
1.4 schwarze 262: putchar((unsigned char)*s);
1.1 schwarze 263: break;
264: }
265: }
266: }
267:
1.8 schwarze 268: static void
1.18 ! schwarze 269: print_offs(const char *v)
1.8 schwarze 270: {
271: char buf[24];
272: struct roffsu su;
273: size_t sz;
274:
275: if (NULL == v || '\0' == *v || 0 == strcmp(v, "left"))
276: sz = 0;
277: else if (0 == strcmp(v, "indent"))
278: sz = 6;
279: else if (0 == strcmp(v, "indent-two"))
280: sz = 12;
281: else if (a2roffsu(v, &su, SCALE_MAX)) {
1.18 ! schwarze 282: print_word(v);
1.8 schwarze 283: return;
284: } else
285: sz = strlen(v);
286:
287: snprintf(buf, sizeof(buf), "%ldn", sz);
1.18 ! schwarze 288: print_word(buf);
1.8 schwarze 289: }
290:
1.1 schwarze 291: void
1.4 schwarze 292: man_man(void *arg, const struct man *man)
293: {
294:
295: /*
296: * Dump the keep buffer.
297: * We're guaranteed by now that this exists (is non-NULL).
298: * Flush stdout afterward, just in case.
299: */
300: fputs(mparse_getkeep(man_mparse(man)), stdout);
301: fflush(stdout);
302: }
303:
304: void
1.1 schwarze 305: man_mdoc(void *arg, const struct mdoc *mdoc)
306: {
307: const struct mdoc_meta *m;
308: const struct mdoc_node *n;
309:
310: m = mdoc_meta(mdoc);
311: n = mdoc_node(mdoc);
312:
1.3 schwarze 313: printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
1.4 schwarze 314: m->title, m->msec, m->date, m->os, m->vol);
1.1 schwarze 315:
1.18 ! schwarze 316: outflags = MMAN_nl | MMAN_Sm;
! 317: print_node(m, n);
1.3 schwarze 318: putchar('\n');
1.1 schwarze 319: }
320:
321: static void
322: print_node(DECL_ARGS)
323: {
324: const struct mdoc_node *prev, *sub;
1.4 schwarze 325: const struct manact *act;
1.1 schwarze 326: int cond, do_sub;
1.4 schwarze 327:
328: /*
329: * Break the line if we were parsed subsequent the current node.
330: * This makes the page structure be more consistent.
331: */
1.1 schwarze 332: prev = n->prev ? n->prev : n->parent;
1.14 schwarze 333: if (prev && prev->line < n->line &&
334: MDOC_Fo != prev->tok && MDOC_Ns != prev->tok)
1.18 ! schwarze 335: outflags |= MMAN_nl;
1.1 schwarze 336:
1.4 schwarze 337: act = NULL;
1.1 schwarze 338: cond = 0;
339: do_sub = 1;
1.4 schwarze 340:
1.1 schwarze 341: if (MDOC_TEXT == n->type) {
1.4 schwarze 342: /*
343: * Make sure that we don't happen to start with a
344: * control character at the start of a line.
345: */
1.18 ! schwarze 346: if (MMAN_nl & outflags && ('.' == *n->string ||
1.4 schwarze 347: '\'' == *n->string)) {
1.18 ! schwarze 348: print_word("\\&");
! 349: outflags &= ~MMAN_spc;
1.3 schwarze 350: }
1.18 ! schwarze 351: print_word(n->string);
1.1 schwarze 352: } else {
1.4 schwarze 353: /*
354: * Conditionally run the pre-node action handler for a
355: * node.
356: */
1.1 schwarze 357: act = manacts + n->tok;
1.18 ! schwarze 358: cond = NULL == act->cond || (*act->cond)(m, n);
1.1 schwarze 359: if (cond && act->pre)
1.18 ! schwarze 360: do_sub = (*act->pre)(m, n);
1.1 schwarze 361: }
362:
1.4 schwarze 363: /*
364: * Conditionally run all child nodes.
365: * Note that this iterates over children instead of using
366: * recursion. This prevents unnecessary depth in the stack.
367: */
1.1 schwarze 368: if (do_sub)
369: for (sub = n->child; sub; sub = sub->next)
1.18 ! schwarze 370: print_node(m, sub);
1.1 schwarze 371:
1.4 schwarze 372: /*
373: * Lastly, conditionally run the post-node handler.
374: */
1.1 schwarze 375: if (cond && act->post)
1.18 ! schwarze 376: (*act->post)(m, n);
1.1 schwarze 377: }
378:
379: static int
380: cond_head(DECL_ARGS)
381: {
1.4 schwarze 382:
1.1 schwarze 383: return(MDOC_HEAD == n->type);
384: }
385:
386: static int
387: cond_body(DECL_ARGS)
388: {
1.4 schwarze 389:
1.1 schwarze 390: return(MDOC_BODY == n->type);
391: }
392:
1.4 schwarze 393: /*
394: * Output a font encoding before a node, e.g., \fR.
395: * This obviously has no trailing space.
396: */
1.1 schwarze 397: static int
398: pre_enc(DECL_ARGS)
399: {
1.4 schwarze 400: const char *prefix;
1.1 schwarze 401:
402: prefix = manacts[n->tok].prefix;
403: if (NULL == prefix)
404: return(1);
1.18 ! schwarze 405: print_word(prefix);
! 406: outflags &= ~MMAN_spc;
1.1 schwarze 407: return(1);
408: }
409:
1.4 schwarze 410: /*
411: * Output a font encoding subsequent a node, e.g., \fP.
412: */
1.1 schwarze 413: static void
414: post_enc(DECL_ARGS)
415: {
416: const char *suffix;
417:
418: suffix = manacts[n->tok].suffix;
419: if (NULL == suffix)
420: return;
1.18 ! schwarze 421: outflags &= ~MMAN_spc;
! 422: print_word(suffix);
1.7 schwarze 423: if (MDOC_Fl == n->tok && 0 == n->nchild)
1.18 ! schwarze 424: outflags &= ~MMAN_spc;
1.1 schwarze 425: }
426:
1.4 schwarze 427: /*
428: * Used in listings (percent = %A, e.g.).
429: * FIXME: this is incomplete.
430: * It doesn't print a nice ", and" for lists.
431: */
1.1 schwarze 432: static void
433: post_percent(DECL_ARGS)
434: {
435:
1.18 ! schwarze 436: post_enc(m, n);
1.1 schwarze 437: if (n->next)
1.18 ! schwarze 438: print_word(",");
1.1 schwarze 439: else {
1.18 ! schwarze 440: print_word(".");
! 441: outflags |= MMAN_nl;
1.1 schwarze 442: }
443: }
444:
1.4 schwarze 445: /*
446: * Print before a section header.
447: */
1.1 schwarze 448: static int
1.3 schwarze 449: pre_sect(DECL_ARGS)
450: {
451:
452: if (MDOC_HEAD != n->type)
453: return(1);
1.18 ! schwarze 454: outflags |= MMAN_nl;
! 455: print_word(manacts[n->tok].prefix);
! 456: print_word("\"");
! 457: outflags &= ~MMAN_spc;
1.3 schwarze 458: return(1);
459: }
460:
1.4 schwarze 461: /*
462: * Print subsequent a section header.
463: */
1.3 schwarze 464: static void
465: post_sect(DECL_ARGS)
466: {
467:
468: if (MDOC_HEAD != n->type)
469: return;
1.18 ! schwarze 470: outflags &= ~MMAN_spc;
! 471: print_word("\"");
! 472: outflags |= MMAN_nl;
1.3 schwarze 473: }
474:
475: static int
476: pre_ap(DECL_ARGS)
477: {
478:
1.18 ! schwarze 479: outflags &= ~MMAN_spc;
! 480: print_word("'");
! 481: outflags &= ~MMAN_spc;
1.3 schwarze 482: return(0);
483: }
484:
485: static int
486: pre_bd(DECL_ARGS)
487: {
488:
1.8 schwarze 489: if (0 == n->norm->Bd.comp) {
1.18 ! schwarze 490: outflags |= MMAN_nl;
! 491: print_word(".sp");
1.8 schwarze 492: }
1.3 schwarze 493: if (DISP_unfilled == n->norm->Bd.type ||
494: DISP_literal == n->norm->Bd.type) {
1.18 ! schwarze 495: outflags |= MMAN_nl;
! 496: print_word(".nf");
1.3 schwarze 497: }
1.18 ! schwarze 498: outflags |= MMAN_nl;
! 499: print_word(".RS");
! 500: print_offs(n->norm->Bd.offs);
! 501: outflags |= MMAN_nl;
1.3 schwarze 502: return(1);
503: }
504:
505: static void
506: post_bd(DECL_ARGS)
507: {
508:
1.18 ! schwarze 509: outflags |= MMAN_nl;
! 510: print_word(".RE");
1.3 schwarze 511: if (DISP_unfilled == n->norm->Bd.type ||
512: DISP_literal == n->norm->Bd.type) {
1.18 ! schwarze 513: outflags |= MMAN_nl;
! 514: print_word(".fi");
1.3 schwarze 515: }
1.18 ! schwarze 516: outflags |= MMAN_nl;
1.10 schwarze 517: }
518:
519: static int
520: pre_bk(DECL_ARGS)
521: {
522:
523: switch (n->type) {
524: case (MDOC_BLOCK):
525: return(1);
526: case (MDOC_BODY):
1.18 ! schwarze 527: outflags |= MMAN_Bk;
1.10 schwarze 528: return(1);
529: default:
530: return(0);
531: }
532: }
533:
534: static void
535: post_bk(DECL_ARGS)
536: {
537:
538: if (MDOC_BODY == n->type)
1.18 ! schwarze 539: outflags &= ~MMAN_Bk;
1.3 schwarze 540: }
541:
542: static int
543: pre_br(DECL_ARGS)
544: {
545:
1.18 ! schwarze 546: outflags |= MMAN_nl;
! 547: print_word(".br");
! 548: outflags |= MMAN_nl;
1.3 schwarze 549: return(0);
550: }
551:
552: static int
1.5 schwarze 553: pre_bx(DECL_ARGS)
554: {
555:
556: n = n->child;
557: if (n) {
1.18 ! schwarze 558: print_word(n->string);
! 559: outflags &= ~MMAN_spc;
1.5 schwarze 560: n = n->next;
561: }
1.18 ! schwarze 562: print_word("BSD");
1.5 schwarze 563: if (NULL == n)
564: return(0);
1.18 ! schwarze 565: outflags &= ~MMAN_spc;
! 566: print_word("-");
! 567: outflags &= ~MMAN_spc;
! 568: print_word(n->string);
1.5 schwarze 569: return(0);
570: }
571:
572: static int
1.1 schwarze 573: pre_dl(DECL_ARGS)
574: {
575:
1.18 ! schwarze 576: outflags |= MMAN_nl;
! 577: print_word(".RS 6n");
! 578: outflags |= MMAN_nl;
1.1 schwarze 579: return(1);
580: }
581:
582: static void
583: post_dl(DECL_ARGS)
584: {
585:
1.18 ! schwarze 586: outflags |= MMAN_nl;
! 587: print_word(".RE");
! 588: outflags |= MMAN_nl;
1.13 schwarze 589: }
590:
591: static int
1.14 schwarze 592: pre_fa(DECL_ARGS)
593: {
594:
595: if (MDOC_Fa == n->tok)
596: n = n->child;
597:
598: while (NULL != n) {
1.18 ! schwarze 599: print_word("\\fI");
! 600: outflags &= ~MMAN_spc;
! 601: print_node(m, n);
! 602: outflags &= ~MMAN_spc;
! 603: print_word("\\fP");
1.14 schwarze 604: if (NULL != (n = n->next))
1.18 ! schwarze 605: print_word(",");
1.14 schwarze 606: }
607: return(0);
608: }
609:
610: static void
611: post_fa(DECL_ARGS)
612: {
613:
614: if (NULL != n->next && MDOC_Fa == n->next->tok)
1.18 ! schwarze 615: print_word(",");
1.14 schwarze 616: }
617:
618: static int
1.13 schwarze 619: pre_fn(DECL_ARGS)
620: {
621:
622: n = n->child;
623: if (NULL == n)
624: return(0);
625:
626: if (MDOC_SYNPRETTY & n->flags) {
1.18 ! schwarze 627: outflags |= MMAN_nl;
! 628: print_word(".br");
! 629: outflags |= MMAN_nl;
! 630: }
! 631: print_word("\\fB");
! 632: outflags &= ~MMAN_spc;
! 633: print_node(m, n);
! 634: outflags &= ~MMAN_spc;
! 635: print_word("\\fP(");
! 636: outflags &= ~MMAN_spc;
! 637: return(pre_fa(m, n->next));
1.13 schwarze 638: }
639:
640: static void
641: post_fn(DECL_ARGS)
642: {
643:
1.18 ! schwarze 644: print_word(")");
1.13 schwarze 645: if (MDOC_SYNPRETTY & n->flags) {
1.18 ! schwarze 646: print_word(";");
! 647: outflags |= MMAN_nl;
! 648: print_word(".br");
! 649: outflags |= MMAN_nl;
1.14 schwarze 650: }
651: }
652:
653: static int
654: pre_fo(DECL_ARGS)
655: {
656:
657: switch (n->type) {
658: case (MDOC_HEAD):
659: if (MDOC_SYNPRETTY & n->flags) {
1.18 ! schwarze 660: outflags |= MMAN_nl;
! 661: print_word(".br");
! 662: outflags |= MMAN_nl;
1.14 schwarze 663: }
1.18 ! schwarze 664: print_word("\\fB");
! 665: outflags &= ~MMAN_spc;
1.14 schwarze 666: break;
667: case (MDOC_BODY):
1.18 ! schwarze 668: outflags &= ~MMAN_spc;
! 669: print_word("(");
! 670: outflags &= ~MMAN_spc;
1.14 schwarze 671: break;
672: default:
673: break;
674: }
675: return(1);
676: }
677:
678: static void
679: post_fo(DECL_ARGS)
680: {
681:
682: switch (n->type) {
683: case (MDOC_HEAD):
1.18 ! schwarze 684: outflags &= ~MMAN_spc;
! 685: print_word("\\fP");
1.14 schwarze 686: break;
687: case (MDOC_BODY):
1.18 ! schwarze 688: post_fn(m, n);
1.14 schwarze 689: break;
690: default:
691: break;
1.13 schwarze 692: }
1.12 schwarze 693: }
694:
695: static int
696: pre_in(DECL_ARGS)
697: {
698:
699: if (MDOC_SYNPRETTY & n->flags) {
1.18 ! schwarze 700: outflags |= MMAN_nl;
! 701: print_word(".br");
! 702: outflags |= MMAN_nl;
! 703: print_word("\\fB#include <");
1.12 schwarze 704: } else
1.18 ! schwarze 705: print_word("<\\fI");
! 706: outflags &= ~MMAN_spc;
1.12 schwarze 707: return(1);
708: }
709:
710: static void
711: post_in(DECL_ARGS)
712: {
713:
1.18 ! schwarze 714: outflags &= ~MMAN_spc;
1.12 schwarze 715: if (MDOC_SYNPRETTY & n->flags) {
1.18 ! schwarze 716: print_word(">\\fP");
! 717: outflags |= MMAN_nl;
! 718: print_word(".br");
! 719: outflags |= MMAN_nl;
1.12 schwarze 720: } else
1.18 ! schwarze 721: print_word("\\fP>");
1.1 schwarze 722: }
723:
724: static int
725: pre_it(DECL_ARGS)
726: {
727: const struct mdoc_node *bln;
728:
729: if (MDOC_HEAD == n->type) {
1.18 ! schwarze 730: outflags |= MMAN_nl;
! 731: print_word(".TP");
1.1 schwarze 732: bln = n->parent->parent->prev;
1.3 schwarze 733: switch (bln->norm->Bl.type) {
734: case (LIST_bullet):
1.18 ! schwarze 735: print_word("4n");
! 736: outflags |= MMAN_nl;
! 737: print_word("\\fBo\\fP");
1.3 schwarze 738: break;
739: default:
740: if (bln->norm->Bl.width)
1.18 ! schwarze 741: print_word(bln->norm->Bl.width);
1.3 schwarze 742: break;
743: }
1.18 ! schwarze 744: outflags |= MMAN_nl;
1.1 schwarze 745: }
746: return(1);
1.11 schwarze 747: }
748:
749: static void
750: post_lb(DECL_ARGS)
751: {
752:
753: if (SEC_LIBRARY == n->sec) {
1.18 ! schwarze 754: outflags |= MMAN_nl;
! 755: print_word(".br");
! 756: outflags |= MMAN_nl;
1.11 schwarze 757: }
1.1 schwarze 758: }
759:
760: static int
761: pre_nm(DECL_ARGS)
762: {
763:
764: if (MDOC_ELEM != n->type && MDOC_HEAD != n->type)
765: return(1);
1.7 schwarze 766: if (MDOC_SYNPRETTY & n->flags) {
1.18 ! schwarze 767: outflags |= MMAN_nl;
! 768: print_word(".br");
! 769: outflags |= MMAN_nl;
1.7 schwarze 770: }
1.18 ! schwarze 771: print_word("\\fB");
! 772: outflags &= ~MMAN_spc;
1.1 schwarze 773: if (NULL == n->child)
1.18 ! schwarze 774: print_word(m->name);
1.1 schwarze 775: return(1);
776: }
777:
778: static void
779: post_nm(DECL_ARGS)
780: {
781:
782: if (MDOC_ELEM != n->type && MDOC_HEAD != n->type)
783: return;
1.18 ! schwarze 784: outflags &= ~MMAN_spc;
! 785: print_word("\\fP");
1.1 schwarze 786: }
787:
788: static int
789: pre_ns(DECL_ARGS)
790: {
791:
1.18 ! schwarze 792: outflags &= ~MMAN_spc;
1.1 schwarze 793: return(0);
794: }
795:
1.3 schwarze 796: static void
797: post_pf(DECL_ARGS)
798: {
799:
1.18 ! schwarze 800: outflags &= ~MMAN_spc;
1.3 schwarze 801: }
802:
1.1 schwarze 803: static int
804: pre_pp(DECL_ARGS)
805: {
806:
1.18 ! schwarze 807: outflags |= MMAN_nl;
1.1 schwarze 808: if (MDOC_It == n->parent->tok)
1.18 ! schwarze 809: print_word(".sp");
1.1 schwarze 810: else
1.18 ! schwarze 811: print_word(".PP");
! 812: outflags |= MMAN_nl;
1.7 schwarze 813: return(MDOC_Rs == n->tok);
1.9 schwarze 814: }
815:
816: static int
817: pre_sm(DECL_ARGS)
818: {
819:
820: assert(n->child && MDOC_TEXT == n->child->type);
821: if (0 == strcmp("on", n->child->string))
1.18 ! schwarze 822: outflags |= MMAN_Sm;
1.9 schwarze 823: else
1.18 ! schwarze 824: outflags &= ~MMAN_Sm;
1.9 schwarze 825: return(0);
1.1 schwarze 826: }
827:
828: static int
1.3 schwarze 829: pre_sp(DECL_ARGS)
1.1 schwarze 830: {
831:
1.18 ! schwarze 832: outflags |= MMAN_nl;
! 833: print_word(".sp");
1.1 schwarze 834: return(1);
835: }
836:
837: static void
1.3 schwarze 838: post_sp(DECL_ARGS)
1.1 schwarze 839: {
840:
1.18 ! schwarze 841: outflags |= MMAN_nl;
1.15 schwarze 842: }
843:
844: static int
845: pre_vt(DECL_ARGS)
846: {
847:
848: if (MDOC_SYNPRETTY & n->flags) {
1.16 schwarze 849: switch (n->type) {
850: case (MDOC_BLOCK):
851: return(1);
852: case (MDOC_BODY):
853: break;
854: default:
855: return(0);
856: }
1.18 ! schwarze 857: outflags |= MMAN_nl;
! 858: print_word(".br");
! 859: outflags |= MMAN_nl;
1.15 schwarze 860: }
1.18 ! schwarze 861: print_word("\\fI");
! 862: outflags &= ~MMAN_spc;
1.15 schwarze 863: return(1);
864: }
865:
866: static void
867: post_vt(DECL_ARGS)
868: {
1.16 schwarze 869:
1.17 schwarze 870: if (MDOC_SYNPRETTY & n->flags && MDOC_BODY != n->type)
1.16 schwarze 871: return;
1.15 schwarze 872:
1.18 ! schwarze 873: outflags &= ~MMAN_spc;
! 874: print_word("\\fP");
1.15 schwarze 875: if (MDOC_SYNPRETTY & n->flags) {
1.18 ! schwarze 876: outflags |= MMAN_nl;
! 877: print_word(".br");
! 878: outflags |= MMAN_nl;
1.15 schwarze 879: }
1.1 schwarze 880: }
881:
882: static int
883: pre_xr(DECL_ARGS)
884: {
885:
886: n = n->child;
887: if (NULL == n)
888: return(0);
1.18 ! schwarze 889: print_node(m, n);
1.1 schwarze 890: n = n->next;
891: if (NULL == n)
892: return(0);
1.18 ! schwarze 893: outflags &= ~MMAN_spc;
! 894: print_word("(");
! 895: print_node(m, n);
! 896: print_word(")");
1.1 schwarze 897: return(0);
1.5 schwarze 898: }
899:
900: static int
901: pre_ux(DECL_ARGS)
902: {
903:
1.18 ! schwarze 904: print_word(manacts[n->tok].prefix);
1.5 schwarze 905: if (NULL == n->child)
906: return(0);
1.18 ! schwarze 907: outflags &= ~MMAN_spc;
! 908: print_word("\\~");
! 909: outflags &= ~MMAN_spc;
1.5 schwarze 910: return(1);
1.1 schwarze 911: }