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