Annotation of src/usr.bin/mandoc/mdoc_man.c, Revision 1.12
1.12 ! schwarze 1: /* $Id: mdoc_man.c,v 1.11 2012/07/07 14:04:39 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.12 ! schwarze 52: static void post_in(DECL_ARGS);
1.11 schwarze 53: static void post_lb(DECL_ARGS);
1.4 schwarze 54: static void post_nm(DECL_ARGS);
1.1 schwarze 55: static void post_percent(DECL_ARGS);
1.4 schwarze 56: static void post_pf(DECL_ARGS);
1.3 schwarze 57: static void post_sect(DECL_ARGS);
1.4 schwarze 58: static void post_sp(DECL_ARGS);
1.3 schwarze 59: static int pre_ap(DECL_ARGS);
60: static int pre_bd(DECL_ARGS);
1.10 schwarze 61: static int pre_bk(DECL_ARGS);
1.3 schwarze 62: static int pre_br(DECL_ARGS);
1.5 schwarze 63: static int pre_bx(DECL_ARGS);
1.1 schwarze 64: static int pre_dl(DECL_ARGS);
1.4 schwarze 65: static int pre_enc(DECL_ARGS);
1.12 ! schwarze 66: static int pre_in(DECL_ARGS);
1.1 schwarze 67: static int pre_it(DECL_ARGS);
68: static int pre_nm(DECL_ARGS);
69: static int pre_ns(DECL_ARGS);
70: static int pre_pp(DECL_ARGS);
1.9 schwarze 71: static int pre_sm(DECL_ARGS);
1.3 schwarze 72: static int pre_sp(DECL_ARGS);
1.4 schwarze 73: static int pre_sect(DECL_ARGS);
1.5 schwarze 74: static int pre_ux(DECL_ARGS);
1.1 schwarze 75: static int pre_xr(DECL_ARGS);
1.4 schwarze 76: static void print_word(struct mman *, const char *);
1.8 schwarze 77: static void print_offs(struct mman *, 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 */
106: { NULL, NULL, NULL, NULL, NULL }, /* _Fa */
107: { NULL, NULL, NULL, NULL, NULL }, /* _Fd */
108: { NULL, pre_enc, post_enc, "\\fB-", "\\fP" }, /* Fl */
109: { NULL, NULL, NULL, NULL, NULL }, /* _Fn */
110: { NULL, NULL, NULL, NULL, NULL }, /* _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.1 schwarze 125: { NULL, NULL, NULL, NULL, NULL }, /* _Va */
126: { NULL, NULL, NULL, 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 */
183: { NULL, NULL, NULL, 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:
212: static void
1.4 schwarze 213: print_word(struct mman *mm, const char *s)
1.1 schwarze 214: {
1.4 schwarze 215:
216: if (mm->need_nl) {
217: /*
218: * If we need a newline, print it now and start afresh.
219: */
1.1 schwarze 220: putchar('\n');
1.4 schwarze 221: mm->need_space = 0;
222: mm->need_nl = 0;
223: } else if (mm->need_space && '\0' != s[0])
224: /*
225: * If we need a space, only print it before
226: * (1) a nonzero length word;
227: * (2) a word that is non-punctuation; and
228: * (3) if punctuation, non-terminating puncutation.
229: */
1.10 schwarze 230: if (NULL == strchr(".,:;)]?!", s[0]) || '\0' != s[1]) {
231: if (mm->mode_keep) {
232: putchar('\\');
233: putchar('~');
234: } else
235: putchar(' ');
236: }
1.4 schwarze 237:
238: /*
239: * Reassign needing space if we're not following opening
240: * punctuation.
241: */
1.9 schwarze 242: mm->need_space = mm->mode_space &&
243: (('(' != s[0] && '[' != s[0]) || '\0' != s[1]);
1.4 schwarze 244:
1.1 schwarze 245: for ( ; *s; s++) {
246: switch (*s) {
247: case (ASCII_NBRSP):
248: printf("\\~");
249: break;
250: case (ASCII_HYPH):
251: putchar('-');
252: break;
253: default:
1.4 schwarze 254: putchar((unsigned char)*s);
1.1 schwarze 255: break;
256: }
257: }
258: }
259:
1.8 schwarze 260: static void
261: print_offs(struct mman *mm, const char *v)
262: {
263: char buf[24];
264: struct roffsu su;
265: size_t sz;
266:
267: if (NULL == v || '\0' == *v || 0 == strcmp(v, "left"))
268: sz = 0;
269: else if (0 == strcmp(v, "indent"))
270: sz = 6;
271: else if (0 == strcmp(v, "indent-two"))
272: sz = 12;
273: else if (a2roffsu(v, &su, SCALE_MAX)) {
274: print_word(mm, v);
275: return;
276: } else
277: sz = strlen(v);
278:
279: snprintf(buf, sizeof(buf), "%ldn", sz);
280: print_word(mm, buf);
281: }
282:
1.1 schwarze 283: void
1.4 schwarze 284: man_man(void *arg, const struct man *man)
285: {
286:
287: /*
288: * Dump the keep buffer.
289: * We're guaranteed by now that this exists (is non-NULL).
290: * Flush stdout afterward, just in case.
291: */
292: fputs(mparse_getkeep(man_mparse(man)), stdout);
293: fflush(stdout);
294: }
295:
296: void
1.1 schwarze 297: man_mdoc(void *arg, const struct mdoc *mdoc)
298: {
299: const struct mdoc_meta *m;
300: const struct mdoc_node *n;
1.4 schwarze 301: struct mman mm;
1.1 schwarze 302:
303: m = mdoc_meta(mdoc);
304: n = mdoc_node(mdoc);
305:
1.3 schwarze 306: printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
1.4 schwarze 307: m->title, m->msec, m->date, m->os, m->vol);
1.1 schwarze 308:
1.4 schwarze 309: memset(&mm, 0, sizeof(struct mman));
310:
1.9 schwarze 311: mm.mode_space = 1;
1.4 schwarze 312: mm.need_nl = 1;
313: print_node(m, n, &mm);
1.3 schwarze 314: putchar('\n');
1.1 schwarze 315: }
316:
317: static void
318: print_node(DECL_ARGS)
319: {
320: const struct mdoc_node *prev, *sub;
1.4 schwarze 321: const struct manact *act;
1.1 schwarze 322: int cond, do_sub;
1.4 schwarze 323:
324: /*
325: * Break the line if we were parsed subsequent the current node.
326: * This makes the page structure be more consistent.
327: */
1.1 schwarze 328: prev = n->prev ? n->prev : n->parent;
1.7 schwarze 329: if (prev && prev->line < n->line && MDOC_Ns != prev->tok)
1.4 schwarze 330: mm->need_nl = 1;
1.1 schwarze 331:
1.4 schwarze 332: act = NULL;
1.1 schwarze 333: cond = 0;
334: do_sub = 1;
1.4 schwarze 335:
1.1 schwarze 336: if (MDOC_TEXT == n->type) {
1.4 schwarze 337: /*
338: * Make sure that we don't happen to start with a
339: * control character at the start of a line.
340: */
341: if (mm->need_nl && ('.' == *n->string ||
342: '\'' == *n->string)) {
343: print_word(mm, "\\&");
344: mm->need_space = 0;
1.3 schwarze 345: }
1.4 schwarze 346: print_word(mm, n->string);
1.1 schwarze 347: } else {
1.4 schwarze 348: /*
349: * Conditionally run the pre-node action handler for a
350: * node.
351: */
1.1 schwarze 352: act = manacts + n->tok;
1.4 schwarze 353: cond = NULL == act->cond || (*act->cond)(m, n, mm);
1.1 schwarze 354: if (cond && act->pre)
1.4 schwarze 355: do_sub = (*act->pre)(m, n, mm);
1.1 schwarze 356: }
357:
1.4 schwarze 358: /*
359: * Conditionally run all child nodes.
360: * Note that this iterates over children instead of using
361: * recursion. This prevents unnecessary depth in the stack.
362: */
1.1 schwarze 363: if (do_sub)
364: for (sub = n->child; sub; sub = sub->next)
1.4 schwarze 365: print_node(m, sub, mm);
1.1 schwarze 366:
1.4 schwarze 367: /*
368: * Lastly, conditionally run the post-node handler.
369: */
1.1 schwarze 370: if (cond && act->post)
1.4 schwarze 371: (*act->post)(m, n, mm);
1.1 schwarze 372: }
373:
374: static int
375: cond_head(DECL_ARGS)
376: {
1.4 schwarze 377:
1.1 schwarze 378: return(MDOC_HEAD == n->type);
379: }
380:
381: static int
382: cond_body(DECL_ARGS)
383: {
1.4 schwarze 384:
1.1 schwarze 385: return(MDOC_BODY == n->type);
386: }
387:
1.4 schwarze 388: /*
389: * Output a font encoding before a node, e.g., \fR.
390: * This obviously has no trailing space.
391: */
1.1 schwarze 392: static int
393: pre_enc(DECL_ARGS)
394: {
1.4 schwarze 395: const char *prefix;
1.1 schwarze 396:
397: prefix = manacts[n->tok].prefix;
398: if (NULL == prefix)
399: return(1);
1.4 schwarze 400: print_word(mm, prefix);
401: mm->need_space = 0;
1.1 schwarze 402: return(1);
403: }
404:
1.4 schwarze 405: /*
406: * Output a font encoding subsequent a node, e.g., \fP.
407: */
1.1 schwarze 408: static void
409: post_enc(DECL_ARGS)
410: {
411: const char *suffix;
412:
413: suffix = manacts[n->tok].suffix;
414: if (NULL == suffix)
415: return;
1.4 schwarze 416: mm->need_space = 0;
417: print_word(mm, suffix);
1.7 schwarze 418: if (MDOC_Fl == n->tok && 0 == n->nchild)
419: mm->need_space = 0;
1.1 schwarze 420: }
421:
1.4 schwarze 422: /*
423: * Used in listings (percent = %A, e.g.).
424: * FIXME: this is incomplete.
425: * It doesn't print a nice ", and" for lists.
426: */
1.1 schwarze 427: static void
428: post_percent(DECL_ARGS)
429: {
430:
1.4 schwarze 431: post_enc(m, n, mm);
1.1 schwarze 432: if (n->next)
1.4 schwarze 433: print_word(mm, ",");
1.1 schwarze 434: else {
1.4 schwarze 435: print_word(mm, ".");
436: mm->need_nl = 1;
1.1 schwarze 437: }
438: }
439:
1.4 schwarze 440: /*
441: * Print before a section header.
442: */
1.1 schwarze 443: static int
1.3 schwarze 444: pre_sect(DECL_ARGS)
445: {
446:
447: if (MDOC_HEAD != n->type)
448: return(1);
1.4 schwarze 449: mm->need_nl = 1;
450: print_word(mm, manacts[n->tok].prefix);
451: print_word(mm, "\"");
452: mm->need_space = 0;
1.3 schwarze 453: return(1);
454: }
455:
1.4 schwarze 456: /*
457: * Print subsequent a section header.
458: */
1.3 schwarze 459: static void
460: post_sect(DECL_ARGS)
461: {
462:
463: if (MDOC_HEAD != n->type)
464: return;
1.4 schwarze 465: mm->need_space = 0;
466: print_word(mm, "\"");
467: mm->need_nl = 1;
1.3 schwarze 468: }
469:
470: static int
471: pre_ap(DECL_ARGS)
472: {
473:
1.4 schwarze 474: mm->need_space = 0;
475: print_word(mm, "'");
476: mm->need_space = 0;
1.3 schwarze 477: return(0);
478: }
479:
480: static int
481: pre_bd(DECL_ARGS)
482: {
483:
1.8 schwarze 484: if (0 == n->norm->Bd.comp) {
485: mm->need_nl = 1;
486: print_word(mm, ".sp");
487: }
1.3 schwarze 488: if (DISP_unfilled == n->norm->Bd.type ||
489: DISP_literal == n->norm->Bd.type) {
1.4 schwarze 490: mm->need_nl = 1;
491: print_word(mm, ".nf");
1.3 schwarze 492: }
1.4 schwarze 493: mm->need_nl = 1;
1.8 schwarze 494: print_word(mm, ".RS");
495: print_offs(mm, n->norm->Bd.offs);
496: mm->need_nl = 1;
1.3 schwarze 497: return(1);
498: }
499:
500: static void
501: post_bd(DECL_ARGS)
502: {
503:
1.8 schwarze 504: mm->need_nl = 1;
505: print_word(mm, ".RE");
1.3 schwarze 506: if (DISP_unfilled == n->norm->Bd.type ||
507: DISP_literal == n->norm->Bd.type) {
1.4 schwarze 508: mm->need_nl = 1;
509: print_word(mm, ".fi");
1.3 schwarze 510: }
1.4 schwarze 511: mm->need_nl = 1;
1.10 schwarze 512: }
513:
514: static int
515: pre_bk(DECL_ARGS)
516: {
517:
518: switch (n->type) {
519: case (MDOC_BLOCK):
520: return(1);
521: case (MDOC_BODY):
522: mm->mode_keep = 1;
523: return(1);
524: default:
525: return(0);
526: }
527: }
528:
529: static void
530: post_bk(DECL_ARGS)
531: {
532:
533: if (MDOC_BODY == n->type)
534: mm->mode_keep = 0;
1.3 schwarze 535: }
536:
537: static int
538: pre_br(DECL_ARGS)
539: {
540:
1.4 schwarze 541: mm->need_nl = 1;
542: print_word(mm, ".br");
543: mm->need_nl = 1;
1.3 schwarze 544: return(0);
545: }
546:
547: static int
1.5 schwarze 548: pre_bx(DECL_ARGS)
549: {
550:
551: n = n->child;
552: if (n) {
553: print_word(mm, n->string);
554: mm->need_space = 0;
555: n = n->next;
556: }
557: print_word(mm, "BSD");
558: if (NULL == n)
559: return(0);
560: mm->need_space = 0;
561: print_word(mm, "-");
562: mm->need_space = 0;
563: print_word(mm, n->string);
564: return(0);
565: }
566:
567: static int
1.1 schwarze 568: pre_dl(DECL_ARGS)
569: {
570:
1.4 schwarze 571: mm->need_nl = 1;
572: print_word(mm, ".RS 6n");
573: mm->need_nl = 1;
1.1 schwarze 574: return(1);
575: }
576:
577: static void
578: post_dl(DECL_ARGS)
579: {
580:
1.4 schwarze 581: mm->need_nl = 1;
582: print_word(mm, ".RE");
583: mm->need_nl = 1;
1.12 ! schwarze 584: }
! 585:
! 586: static int
! 587: pre_in(DECL_ARGS)
! 588: {
! 589:
! 590: if (MDOC_SYNPRETTY & n->flags) {
! 591: mm->need_nl = 1;
! 592: print_word(mm, ".br");
! 593: mm->need_nl = 1;
! 594: print_word(mm, "\\fB#include <");
! 595: } else
! 596: print_word(mm, "<\\fI");
! 597: mm->need_space = 0;
! 598: return(1);
! 599: }
! 600:
! 601: static void
! 602: post_in(DECL_ARGS)
! 603: {
! 604:
! 605: mm->need_space = 0;
! 606: if (MDOC_SYNPRETTY & n->flags) {
! 607: print_word(mm, ">\\fP");
! 608: mm->need_nl = 1;
! 609: print_word(mm, ".br");
! 610: mm->need_nl = 1;
! 611: } else
! 612: print_word(mm, "\\fP>");
1.1 schwarze 613: }
614:
615: static int
616: pre_it(DECL_ARGS)
617: {
618: const struct mdoc_node *bln;
619:
620: if (MDOC_HEAD == n->type) {
1.4 schwarze 621: mm->need_nl = 1;
622: print_word(mm, ".TP");
1.1 schwarze 623: bln = n->parent->parent->prev;
1.3 schwarze 624: switch (bln->norm->Bl.type) {
625: case (LIST_bullet):
1.4 schwarze 626: print_word(mm, "4n");
627: mm->need_nl = 1;
628: print_word(mm, "\\fBo\\fP");
1.3 schwarze 629: break;
630: default:
631: if (bln->norm->Bl.width)
1.4 schwarze 632: print_word(mm, bln->norm->Bl.width);
1.3 schwarze 633: break;
634: }
1.4 schwarze 635: mm->need_nl = 1;
1.1 schwarze 636: }
637: return(1);
1.11 schwarze 638: }
639:
640: static void
641: post_lb(DECL_ARGS)
642: {
643:
644: if (SEC_LIBRARY == n->sec) {
645: mm->need_nl = 1;
646: print_word(mm, ".br");
647: mm->need_nl = 1;
648: }
1.1 schwarze 649: }
650:
651: static int
652: pre_nm(DECL_ARGS)
653: {
654:
655: if (MDOC_ELEM != n->type && MDOC_HEAD != n->type)
656: return(1);
1.7 schwarze 657: if (MDOC_SYNPRETTY & n->flags) {
658: mm->need_nl = 1;
659: print_word(mm, ".br");
660: mm->need_nl = 1;
661: }
1.4 schwarze 662: print_word(mm, "\\fB");
663: mm->need_space = 0;
1.1 schwarze 664: if (NULL == n->child)
1.4 schwarze 665: print_word(mm, m->name);
1.1 schwarze 666: return(1);
667: }
668:
669: static void
670: post_nm(DECL_ARGS)
671: {
672:
673: if (MDOC_ELEM != n->type && MDOC_HEAD != n->type)
674: return;
1.4 schwarze 675: mm->need_space = 0;
676: print_word(mm, "\\fP");
1.1 schwarze 677: }
678:
679: static int
680: pre_ns(DECL_ARGS)
681: {
682:
1.4 schwarze 683: mm->need_space = 0;
1.1 schwarze 684: return(0);
685: }
686:
1.3 schwarze 687: static void
688: post_pf(DECL_ARGS)
689: {
690:
1.4 schwarze 691: mm->need_space = 0;
1.3 schwarze 692: }
693:
1.1 schwarze 694: static int
695: pre_pp(DECL_ARGS)
696: {
697:
1.4 schwarze 698: mm->need_nl = 1;
1.1 schwarze 699: if (MDOC_It == n->parent->tok)
1.4 schwarze 700: print_word(mm, ".sp");
1.1 schwarze 701: else
1.4 schwarze 702: print_word(mm, ".PP");
703: mm->need_nl = 1;
1.7 schwarze 704: return(MDOC_Rs == n->tok);
1.9 schwarze 705: }
706:
707: static int
708: pre_sm(DECL_ARGS)
709: {
710:
711: assert(n->child && MDOC_TEXT == n->child->type);
712: if (0 == strcmp("on", n->child->string))
713: mm->mode_space = 1;
714: else
715: mm->mode_space = 0;
716: return(0);
1.1 schwarze 717: }
718:
719: static int
1.3 schwarze 720: pre_sp(DECL_ARGS)
1.1 schwarze 721: {
722:
1.4 schwarze 723: mm->need_nl = 1;
724: print_word(mm, ".sp");
1.1 schwarze 725: return(1);
726: }
727:
728: static void
1.3 schwarze 729: post_sp(DECL_ARGS)
1.1 schwarze 730: {
731:
1.4 schwarze 732: mm->need_nl = 1;
1.1 schwarze 733: }
734:
735: static int
736: pre_xr(DECL_ARGS)
737: {
738:
739: n = n->child;
740: if (NULL == n)
741: return(0);
1.4 schwarze 742: print_node(m, n, mm);
1.1 schwarze 743: n = n->next;
744: if (NULL == n)
745: return(0);
1.4 schwarze 746: mm->need_space = 0;
747: print_word(mm, "(");
748: print_node(m, n, mm);
749: print_word(mm, ")");
1.1 schwarze 750: return(0);
1.5 schwarze 751: }
752:
753: static int
754: pre_ux(DECL_ARGS)
755: {
756:
757: print_word(mm, manacts[n->tok].prefix);
758: if (NULL == n->child)
759: return(0);
760: mm->need_space = 0;
761: print_word(mm, "\\~");
762: mm->need_space = 0;
763: return(1);
1.1 schwarze 764: }