Annotation of mandoc/mdoc_man.c, Revision 1.15
1.15 ! schwarze 1: /* $Id: mdoc_man.c,v 1.14 2012/07/07 14:05:40 schwarze Exp $ */
1.1 schwarze 2: /*
1.11 schwarze 3: * Copyright (c) 2011, 2012 Ingo Schwarze <schwarze@openbsd.org>
1.1 schwarze 4: *
5: * Permission to use, copy, modify, and distribute this software for any
6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
8: *
9: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16: */
1.7 kristaps 17: #ifdef HAVE_CONFIG_H
18: #include "config.h"
19: #endif
20:
1.12 schwarze 21: #include <assert.h>
1.1 schwarze 22: #include <stdio.h>
23: #include <string.h>
24:
25: #include "mandoc.h"
1.11 schwarze 26: #include "out.h"
1.4 kristaps 27: #include "man.h"
1.1 schwarze 28: #include "mdoc.h"
29: #include "main.h"
30:
1.5 kristaps 31: #define DECL_ARGS const struct mdoc_meta *m, \
32: const struct mdoc_node *n, \
33: struct mman *mm
1.1 schwarze 34:
1.5 kristaps 35: struct mman {
1.12 schwarze 36: int mode_space; /* spacing mode: 1 = on */
1.5 kristaps 37: int need_space; /* next word needs prior ws */
1.13 schwarze 38: int mode_keep; /* currently inside a keep */
1.5 kristaps 39: int need_nl; /* next word needs prior nl */
40: };
1.1 schwarze 41:
42: struct manact {
1.5 kristaps 43: int (*cond)(DECL_ARGS); /* DON'T run actions */
44: int (*pre)(DECL_ARGS); /* pre-node action */
45: void (*post)(DECL_ARGS); /* post-node action */
46: const char *prefix; /* pre-node string constant */
47: const char *suffix; /* post-node string constant */
1.1 schwarze 48: };
49:
1.5 kristaps 50: static int cond_body(DECL_ARGS);
1.1 schwarze 51: static int cond_head(DECL_ARGS);
1.5 kristaps 52: static void post_bd(DECL_ARGS);
1.13 schwarze 53: static void post_bk(DECL_ARGS);
1.5 kristaps 54: static void post_dl(DECL_ARGS);
1.1 schwarze 55: static void post_enc(DECL_ARGS);
1.15 ! schwarze 56: static void post_in(DECL_ARGS);
1.14 schwarze 57: static void post_lb(DECL_ARGS);
1.5 kristaps 58: static void post_nm(DECL_ARGS);
1.1 schwarze 59: static void post_percent(DECL_ARGS);
1.5 kristaps 60: static void post_pf(DECL_ARGS);
1.3 schwarze 61: static void post_sect(DECL_ARGS);
1.5 kristaps 62: static void post_sp(DECL_ARGS);
1.3 schwarze 63: static int pre_ap(DECL_ARGS);
64: static int pre_bd(DECL_ARGS);
1.13 schwarze 65: static int pre_bk(DECL_ARGS);
1.3 schwarze 66: static int pre_br(DECL_ARGS);
1.8 schwarze 67: static int pre_bx(DECL_ARGS);
1.1 schwarze 68: static int pre_dl(DECL_ARGS);
1.5 kristaps 69: static int pre_enc(DECL_ARGS);
1.15 ! schwarze 70: static int pre_in(DECL_ARGS);
1.1 schwarze 71: static int pre_it(DECL_ARGS);
72: static int pre_nm(DECL_ARGS);
73: static int pre_ns(DECL_ARGS);
74: static int pre_pp(DECL_ARGS);
1.12 schwarze 75: static int pre_sm(DECL_ARGS);
1.3 schwarze 76: static int pre_sp(DECL_ARGS);
1.5 kristaps 77: static int pre_sect(DECL_ARGS);
1.8 schwarze 78: static int pre_ux(DECL_ARGS);
1.1 schwarze 79: static int pre_xr(DECL_ARGS);
1.5 kristaps 80: static void print_word(struct mman *, const char *);
1.11 schwarze 81: static void print_offs(struct mman *, const char *);
1.5 kristaps 82: static void print_node(DECL_ARGS);
1.1 schwarze 83:
1.3 schwarze 84: static const struct manact manacts[MDOC_MAX + 1] = {
85: { NULL, pre_ap, NULL, NULL, NULL }, /* Ap */
86: { NULL, NULL, NULL, NULL, NULL }, /* Dd */
87: { NULL, NULL, NULL, NULL, NULL }, /* Dt */
1.8 schwarze 88: { NULL, NULL, NULL, NULL, NULL }, /* Os */
1.3 schwarze 89: { NULL, pre_sect, post_sect, ".SH", NULL }, /* Sh */
90: { NULL, pre_sect, post_sect, ".SS", NULL }, /* Ss */
1.1 schwarze 91: { NULL, pre_pp, NULL, NULL, NULL }, /* Pp */
1.3 schwarze 92: { cond_body, pre_dl, post_dl, NULL, NULL }, /* D1 */
1.1 schwarze 93: { cond_body, pre_dl, post_dl, NULL, NULL }, /* Dl */
1.3 schwarze 94: { cond_body, pre_bd, post_bd, NULL, NULL }, /* Bd */
95: { NULL, NULL, NULL, NULL, NULL }, /* Ed */
96: { NULL, NULL, NULL, NULL, NULL }, /* Bl */
97: { NULL, NULL, NULL, NULL, NULL }, /* El */
1.1 schwarze 98: { NULL, pre_it, NULL, NULL, NULL }, /* _It */
1.9 schwarze 99: { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Ad */
1.1 schwarze 100: { NULL, NULL, NULL, NULL, NULL }, /* _An */
101: { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Ar */
1.9 schwarze 102: { NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Cd */
1.1 schwarze 103: { NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Cm */
1.9 schwarze 104: { NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Dv */
105: { NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Er */
106: { NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Ev */
1.1 schwarze 107: { NULL, pre_enc, post_enc, "The \\fB",
108: "\\fP\nutility exits 0 on success, and >0 if an error occurs."
109: }, /* Ex */
110: { NULL, NULL, NULL, NULL, NULL }, /* _Fa */
111: { NULL, NULL, NULL, NULL, NULL }, /* _Fd */
112: { NULL, pre_enc, post_enc, "\\fB-", "\\fP" }, /* Fl */
113: { NULL, NULL, NULL, NULL, NULL }, /* _Fn */
114: { NULL, NULL, NULL, NULL, NULL }, /* _Ft */
1.3 schwarze 115: { NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Ic */
1.15 ! schwarze 116: { NULL, pre_in, post_in, NULL, NULL }, /* In */
1.9 schwarze 117: { NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Li */
1.1 schwarze 118: { cond_head, pre_enc, NULL, "\\- ", NULL }, /* Nd */
119: { NULL, pre_nm, post_nm, NULL, NULL }, /* Nm */
120: { cond_body, pre_enc, post_enc, "[", "]" }, /* Op */
1.8 schwarze 121: { NULL, NULL, NULL, NULL, NULL }, /* Ot */
122: { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Pa */
1.6 kristaps 123: { NULL, pre_enc, post_enc, "The \\fB",
124: "\\fP\nfunction returns the value 0 if successful;\n"
125: "otherwise the value -1 is returned and the global\n"
126: "variable \\fIerrno\\fP is set to indicate the error."
127: }, /* Rv */
1.8 schwarze 128: { NULL, NULL, NULL, NULL, NULL }, /* St */
1.1 schwarze 129: { NULL, NULL, NULL, NULL, NULL }, /* _Va */
130: { NULL, NULL, NULL, NULL, NULL }, /* _Vt */
1.8 schwarze 131: { NULL, pre_xr, NULL, NULL, NULL }, /* Xr */
1.1 schwarze 132: { NULL, NULL, post_percent, NULL, NULL }, /* _%A */
133: { NULL, NULL, NULL, NULL, NULL }, /* _%B */
134: { NULL, NULL, post_percent, NULL, NULL }, /* _%D */
135: { NULL, NULL, NULL, NULL, NULL }, /* _%I */
136: { NULL, pre_enc, post_percent, "\\fI", "\\fP" }, /* %J */
137: { NULL, NULL, NULL, NULL, NULL }, /* _%N */
138: { NULL, NULL, NULL, NULL, NULL }, /* _%O */
139: { NULL, NULL, NULL, NULL, NULL }, /* _%P */
140: { NULL, NULL, NULL, NULL, NULL }, /* _%R */
141: { NULL, pre_enc, post_percent, "\"", "\"" }, /* %T */
142: { NULL, NULL, NULL, NULL, NULL }, /* _%V */
1.9 schwarze 143: { NULL, NULL, NULL, NULL, NULL }, /* Ac */
144: { cond_body, pre_enc, post_enc, "<", ">" }, /* Ao */
1.1 schwarze 145: { cond_body, pre_enc, post_enc, "<", ">" }, /* Aq */
1.8 schwarze 146: { NULL, NULL, NULL, NULL, NULL }, /* At */
1.3 schwarze 147: { NULL, NULL, NULL, NULL, NULL }, /* Bc */
1.1 schwarze 148: { NULL, NULL, NULL, NULL, NULL }, /* _Bf */
1.3 schwarze 149: { cond_body, pre_enc, post_enc, "[", "]" }, /* Bo */
150: { cond_body, pre_enc, post_enc, "[", "]" }, /* Bq */
1.8 schwarze 151: { NULL, pre_ux, NULL, "BSD/OS", NULL }, /* Bsx */
152: { NULL, pre_bx, NULL, NULL, NULL }, /* Bx */
153: { NULL, NULL, NULL, NULL, NULL }, /* Db */
1.9 schwarze 154: { NULL, NULL, NULL, NULL, NULL }, /* Dc */
155: { cond_body, pre_enc, post_enc, "``", "''" }, /* Do */
1.1 schwarze 156: { cond_body, pre_enc, post_enc, "``", "''" }, /* Dq */
157: { NULL, NULL, NULL, NULL, NULL }, /* _Ec */
158: { NULL, NULL, NULL, NULL, NULL }, /* _Ef */
1.3 schwarze 159: { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Em */
1.1 schwarze 160: { NULL, NULL, NULL, NULL, NULL }, /* _Eo */
1.8 schwarze 161: { NULL, pre_ux, NULL, "FreeBSD", NULL }, /* Fx */
1.9 schwarze 162: { NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Ms */
163: { NULL, NULL, NULL, NULL, NULL }, /* No */
1.1 schwarze 164: { NULL, pre_ns, NULL, NULL, NULL }, /* Ns */
1.8 schwarze 165: { NULL, pre_ux, NULL, "NetBSD", NULL }, /* Nx */
166: { NULL, pre_ux, NULL, "OpenBSD", NULL }, /* Ox */
1.3 schwarze 167: { NULL, NULL, NULL, NULL, NULL }, /* Pc */
168: { NULL, NULL, post_pf, NULL, NULL }, /* Pf */
169: { cond_body, pre_enc, post_enc, "(", ")" }, /* Po */
170: { cond_body, pre_enc, post_enc, "(", ")" }, /* Pq */
1.9 schwarze 171: { NULL, NULL, NULL, NULL, NULL }, /* Qc */
1.1 schwarze 172: { cond_body, pre_enc, post_enc, "`", "'" }, /* Ql */
1.9 schwarze 173: { cond_body, pre_enc, post_enc, "\"", "\"" }, /* Qo */
174: { cond_body, pre_enc, post_enc, "\"", "\"" }, /* Qq */
175: { NULL, NULL, NULL, NULL, NULL }, /* Re */
1.1 schwarze 176: { cond_body, pre_pp, NULL, NULL, NULL }, /* Rs */
1.9 schwarze 177: { NULL, NULL, NULL, NULL, NULL }, /* Sc */
178: { cond_body, pre_enc, post_enc, "`", "'" }, /* So */
1.1 schwarze 179: { cond_body, pre_enc, post_enc, "`", "'" }, /* Sq */
1.12 schwarze 180: { NULL, pre_sm, NULL, NULL, NULL }, /* Sm */
1.3 schwarze 181: { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Sx */
182: { NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Sy */
1.9 schwarze 183: { NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Tn */
1.8 schwarze 184: { NULL, pre_ux, NULL, "UNIX", NULL }, /* Ux */
1.1 schwarze 185: { NULL, NULL, NULL, NULL, NULL }, /* _Xc */
186: { NULL, NULL, NULL, NULL, NULL }, /* _Xo */
187: { NULL, NULL, NULL, NULL, NULL }, /* _Fo */
188: { NULL, NULL, NULL, NULL, NULL }, /* _Fc */
1.3 schwarze 189: { cond_body, pre_enc, post_enc, "[", "]" }, /* Oo */
1.9 schwarze 190: { NULL, NULL, NULL, NULL, NULL }, /* Oc */
1.13 schwarze 191: { NULL, pre_bk, post_bk, NULL, NULL }, /* Bk */
192: { NULL, NULL, NULL, NULL, NULL }, /* Ek */
1.8 schwarze 193: { NULL, pre_ux, NULL, "is currently in beta test.", NULL }, /* Bt */
194: { NULL, NULL, NULL, NULL, NULL }, /* Hf */
195: { NULL, NULL, NULL, NULL, NULL }, /* Fr */
196: { NULL, pre_ux, NULL, "currently under development.", NULL }, /* Ud */
1.14 schwarze 197: { NULL, NULL, post_lb, NULL, NULL }, /* Lb */
1.3 schwarze 198: { NULL, pre_pp, NULL, NULL, NULL }, /* Lp */
1.1 schwarze 199: { NULL, NULL, NULL, NULL, NULL }, /* _Lk */
200: { NULL, NULL, NULL, NULL, NULL }, /* _Mt */
1.9 schwarze 201: { cond_body, pre_enc, post_enc, "{", "}" }, /* Brq */
202: { cond_body, pre_enc, post_enc, "{", "}" }, /* Bro */
203: { NULL, NULL, NULL, NULL, NULL }, /* Brc */
1.1 schwarze 204: { NULL, NULL, NULL, NULL, NULL }, /* _%C */
205: { NULL, NULL, NULL, NULL, NULL }, /* _Es */
206: { NULL, NULL, NULL, NULL, NULL }, /* _En */
1.8 schwarze 207: { NULL, pre_ux, NULL, "DragonFly", NULL }, /* Dx */
1.1 schwarze 208: { NULL, NULL, NULL, NULL, NULL }, /* _%Q */
1.3 schwarze 209: { NULL, pre_br, NULL, NULL, NULL }, /* br */
210: { NULL, pre_sp, post_sp, NULL, NULL }, /* sp */
1.1 schwarze 211: { NULL, NULL, NULL, NULL, NULL }, /* _%U */
212: { NULL, NULL, NULL, NULL, NULL }, /* _Ta */
1.3 schwarze 213: { NULL, NULL, NULL, NULL, NULL }, /* ROOT */
1.1 schwarze 214: };
215:
216: static void
1.5 kristaps 217: print_word(struct mman *mm, const char *s)
1.1 schwarze 218: {
1.5 kristaps 219:
220: if (mm->need_nl) {
221: /*
222: * If we need a newline, print it now and start afresh.
223: */
1.1 schwarze 224: putchar('\n');
1.5 kristaps 225: mm->need_space = 0;
226: mm->need_nl = 0;
227: } else if (mm->need_space && '\0' != s[0])
228: /*
229: * If we need a space, only print it before
230: * (1) a nonzero length word;
231: * (2) a word that is non-punctuation; and
232: * (3) if punctuation, non-terminating puncutation.
233: */
1.13 schwarze 234: if (NULL == strchr(".,:;)]?!", s[0]) || '\0' != s[1]) {
235: if (mm->mode_keep) {
236: putchar('\\');
237: putchar('~');
238: } else
239: putchar(' ');
240: }
1.5 kristaps 241:
242: /*
243: * Reassign needing space if we're not following opening
244: * punctuation.
245: */
1.12 schwarze 246: mm->need_space = mm->mode_space &&
247: (('(' != s[0] && '[' != s[0]) || '\0' != s[1]);
1.5 kristaps 248:
1.1 schwarze 249: for ( ; *s; s++) {
250: switch (*s) {
251: case (ASCII_NBRSP):
252: printf("\\~");
253: break;
254: case (ASCII_HYPH):
255: putchar('-');
256: break;
257: default:
1.5 kristaps 258: putchar((unsigned char)*s);
1.1 schwarze 259: break;
260: }
261: }
1.4 kristaps 262: }
263:
1.11 schwarze 264: static void
265: print_offs(struct mman *mm, const char *v)
266: {
267: char buf[24];
268: struct roffsu su;
269: size_t sz;
270:
271: if (NULL == v || '\0' == *v || 0 == strcmp(v, "left"))
272: sz = 0;
273: else if (0 == strcmp(v, "indent"))
274: sz = 6;
275: else if (0 == strcmp(v, "indent-two"))
276: sz = 12;
277: else if (a2roffsu(v, &su, SCALE_MAX)) {
278: print_word(mm, v);
279: return;
280: } else
281: sz = strlen(v);
282:
283: snprintf(buf, sizeof(buf), "%ldn", sz);
284: print_word(mm, buf);
285: }
286:
1.4 kristaps 287: void
288: man_man(void *arg, const struct man *man)
289: {
290:
1.5 kristaps 291: /*
292: * Dump the keep buffer.
293: * We're guaranteed by now that this exists (is non-NULL).
294: * Flush stdout afterward, just in case.
295: */
1.4 kristaps 296: fputs(mparse_getkeep(man_mparse(man)), stdout);
1.5 kristaps 297: fflush(stdout);
1.1 schwarze 298: }
299:
300: void
301: man_mdoc(void *arg, const struct mdoc *mdoc)
302: {
303: const struct mdoc_meta *m;
304: const struct mdoc_node *n;
1.5 kristaps 305: struct mman mm;
1.1 schwarze 306:
307: m = mdoc_meta(mdoc);
308: n = mdoc_node(mdoc);
309:
1.3 schwarze 310: printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
1.5 kristaps 311: m->title, m->msec, m->date, m->os, m->vol);
1.1 schwarze 312:
1.5 kristaps 313: memset(&mm, 0, sizeof(struct mman));
314:
1.12 schwarze 315: mm.mode_space = 1;
1.5 kristaps 316: mm.need_nl = 1;
317: print_node(m, n, &mm);
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.5 kristaps 325: const struct manact *act;
1.1 schwarze 326: int cond, do_sub;
1.5 kristaps 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.10 schwarze 333: if (prev && prev->line < n->line && MDOC_Ns != prev->tok)
1.5 kristaps 334: mm->need_nl = 1;
1.1 schwarze 335:
1.5 kristaps 336: act = NULL;
1.1 schwarze 337: cond = 0;
338: do_sub = 1;
1.5 kristaps 339:
1.1 schwarze 340: if (MDOC_TEXT == n->type) {
1.5 kristaps 341: /*
342: * Make sure that we don't happen to start with a
343: * control character at the start of a line.
344: */
345: if (mm->need_nl && ('.' == *n->string ||
346: '\'' == *n->string)) {
347: print_word(mm, "\\&");
348: mm->need_space = 0;
1.3 schwarze 349: }
1.5 kristaps 350: print_word(mm, n->string);
1.1 schwarze 351: } else {
1.5 kristaps 352: /*
353: * Conditionally run the pre-node action handler for a
354: * node.
355: */
1.1 schwarze 356: act = manacts + n->tok;
1.5 kristaps 357: cond = NULL == act->cond || (*act->cond)(m, n, mm);
1.1 schwarze 358: if (cond && act->pre)
1.5 kristaps 359: do_sub = (*act->pre)(m, n, mm);
1.1 schwarze 360: }
361:
1.5 kristaps 362: /*
363: * Conditionally run all child nodes.
364: * Note that this iterates over children instead of using
365: * recursion. This prevents unnecessary depth in the stack.
366: */
1.1 schwarze 367: if (do_sub)
368: for (sub = n->child; sub; sub = sub->next)
1.5 kristaps 369: print_node(m, sub, mm);
1.1 schwarze 370:
1.5 kristaps 371: /*
372: * Lastly, conditionally run the post-node handler.
373: */
1.1 schwarze 374: if (cond && act->post)
1.5 kristaps 375: (*act->post)(m, n, mm);
1.1 schwarze 376: }
377:
378: static int
379: cond_head(DECL_ARGS)
380: {
1.5 kristaps 381:
1.1 schwarze 382: return(MDOC_HEAD == n->type);
383: }
384:
385: static int
386: cond_body(DECL_ARGS)
387: {
1.5 kristaps 388:
1.1 schwarze 389: return(MDOC_BODY == n->type);
390: }
391:
1.5 kristaps 392: /*
393: * Output a font encoding before a node, e.g., \fR.
394: * This obviously has no trailing space.
395: */
1.1 schwarze 396: static int
397: pre_enc(DECL_ARGS)
398: {
1.5 kristaps 399: const char *prefix;
1.1 schwarze 400:
401: prefix = manacts[n->tok].prefix;
402: if (NULL == prefix)
403: return(1);
1.5 kristaps 404: print_word(mm, prefix);
405: mm->need_space = 0;
1.1 schwarze 406: return(1);
407: }
408:
1.5 kristaps 409: /*
410: * Output a font encoding subsequent a node, e.g., \fP.
411: */
1.1 schwarze 412: static void
413: post_enc(DECL_ARGS)
414: {
415: const char *suffix;
416:
417: suffix = manacts[n->tok].suffix;
418: if (NULL == suffix)
419: return;
1.5 kristaps 420: mm->need_space = 0;
421: print_word(mm, suffix);
1.10 schwarze 422: if (MDOC_Fl == n->tok && 0 == n->nchild)
423: mm->need_space = 0;
1.1 schwarze 424: }
425:
1.5 kristaps 426: /*
427: * Used in listings (percent = %A, e.g.).
428: * FIXME: this is incomplete.
429: * It doesn't print a nice ", and" for lists.
430: */
1.1 schwarze 431: static void
432: post_percent(DECL_ARGS)
433: {
434:
1.5 kristaps 435: post_enc(m, n, mm);
1.1 schwarze 436: if (n->next)
1.5 kristaps 437: print_word(mm, ",");
1.1 schwarze 438: else {
1.5 kristaps 439: print_word(mm, ".");
440: mm->need_nl = 1;
1.1 schwarze 441: }
442: }
443:
1.5 kristaps 444: /*
445: * Print before a section header.
446: */
1.1 schwarze 447: static int
1.3 schwarze 448: pre_sect(DECL_ARGS)
449: {
450:
451: if (MDOC_HEAD != n->type)
452: return(1);
1.5 kristaps 453: mm->need_nl = 1;
454: print_word(mm, manacts[n->tok].prefix);
455: print_word(mm, "\"");
456: mm->need_space = 0;
1.3 schwarze 457: return(1);
458: }
459:
1.5 kristaps 460: /*
461: * Print subsequent a section header.
462: */
1.3 schwarze 463: static void
464: post_sect(DECL_ARGS)
465: {
466:
467: if (MDOC_HEAD != n->type)
468: return;
1.5 kristaps 469: mm->need_space = 0;
470: print_word(mm, "\"");
471: mm->need_nl = 1;
1.3 schwarze 472: }
473:
474: static int
475: pre_ap(DECL_ARGS)
476: {
477:
1.5 kristaps 478: mm->need_space = 0;
479: print_word(mm, "'");
480: mm->need_space = 0;
1.3 schwarze 481: return(0);
482: }
483:
484: static int
485: pre_bd(DECL_ARGS)
486: {
487:
1.11 schwarze 488: if (0 == n->norm->Bd.comp) {
489: mm->need_nl = 1;
490: print_word(mm, ".sp");
491: }
1.3 schwarze 492: if (DISP_unfilled == n->norm->Bd.type ||
493: DISP_literal == n->norm->Bd.type) {
1.5 kristaps 494: mm->need_nl = 1;
495: print_word(mm, ".nf");
1.3 schwarze 496: }
1.5 kristaps 497: mm->need_nl = 1;
1.11 schwarze 498: print_word(mm, ".RS");
499: print_offs(mm, n->norm->Bd.offs);
500: mm->need_nl = 1;
1.3 schwarze 501: return(1);
502: }
503:
504: static void
505: post_bd(DECL_ARGS)
506: {
507:
1.11 schwarze 508: mm->need_nl = 1;
509: print_word(mm, ".RE");
1.3 schwarze 510: if (DISP_unfilled == n->norm->Bd.type ||
511: DISP_literal == n->norm->Bd.type) {
1.5 kristaps 512: mm->need_nl = 1;
513: print_word(mm, ".fi");
1.3 schwarze 514: }
1.5 kristaps 515: mm->need_nl = 1;
1.13 schwarze 516: }
517:
518: static int
519: pre_bk(DECL_ARGS)
520: {
521:
522: switch (n->type) {
523: case (MDOC_BLOCK):
524: return(1);
525: case (MDOC_BODY):
526: mm->mode_keep = 1;
527: return(1);
528: default:
529: return(0);
530: }
531: }
532:
533: static void
534: post_bk(DECL_ARGS)
535: {
536:
537: if (MDOC_BODY == n->type)
538: mm->mode_keep = 0;
1.3 schwarze 539: }
540:
541: static int
542: pre_br(DECL_ARGS)
543: {
544:
1.5 kristaps 545: mm->need_nl = 1;
546: print_word(mm, ".br");
547: mm->need_nl = 1;
1.3 schwarze 548: return(0);
549: }
550:
551: static int
1.8 schwarze 552: pre_bx(DECL_ARGS)
553: {
554:
555: n = n->child;
556: if (n) {
557: print_word(mm, n->string);
558: mm->need_space = 0;
559: n = n->next;
560: }
561: print_word(mm, "BSD");
562: if (NULL == n)
563: return(0);
564: mm->need_space = 0;
565: print_word(mm, "-");
566: mm->need_space = 0;
567: print_word(mm, n->string);
568: return(0);
569: }
570:
571: static int
1.1 schwarze 572: pre_dl(DECL_ARGS)
573: {
574:
1.5 kristaps 575: mm->need_nl = 1;
576: print_word(mm, ".RS 6n");
577: mm->need_nl = 1;
1.1 schwarze 578: return(1);
579: }
580:
581: static void
582: post_dl(DECL_ARGS)
583: {
584:
1.5 kristaps 585: mm->need_nl = 1;
586: print_word(mm, ".RE");
587: mm->need_nl = 1;
1.15 ! schwarze 588: }
! 589:
! 590: static int
! 591: pre_in(DECL_ARGS)
! 592: {
! 593:
! 594: if (MDOC_SYNPRETTY & n->flags) {
! 595: mm->need_nl = 1;
! 596: print_word(mm, ".br");
! 597: mm->need_nl = 1;
! 598: print_word(mm, "\\fB#include <");
! 599: } else
! 600: print_word(mm, "<\\fI");
! 601: mm->need_space = 0;
! 602: return(1);
! 603: }
! 604:
! 605: static void
! 606: post_in(DECL_ARGS)
! 607: {
! 608:
! 609: mm->need_space = 0;
! 610: if (MDOC_SYNPRETTY & n->flags) {
! 611: print_word(mm, ">\\fP");
! 612: mm->need_nl = 1;
! 613: print_word(mm, ".br");
! 614: mm->need_nl = 1;
! 615: } else
! 616: print_word(mm, "\\fP>");
1.1 schwarze 617: }
618:
619: static int
620: pre_it(DECL_ARGS)
621: {
622: const struct mdoc_node *bln;
623:
624: if (MDOC_HEAD == n->type) {
1.5 kristaps 625: mm->need_nl = 1;
626: print_word(mm, ".TP");
1.1 schwarze 627: bln = n->parent->parent->prev;
1.3 schwarze 628: switch (bln->norm->Bl.type) {
629: case (LIST_bullet):
1.5 kristaps 630: print_word(mm, "4n");
631: mm->need_nl = 1;
632: print_word(mm, "\\fBo\\fP");
1.3 schwarze 633: break;
634: default:
635: if (bln->norm->Bl.width)
1.5 kristaps 636: print_word(mm, bln->norm->Bl.width);
1.3 schwarze 637: break;
638: }
1.5 kristaps 639: mm->need_nl = 1;
1.1 schwarze 640: }
641: return(1);
1.14 schwarze 642: }
643:
644: static void
645: post_lb(DECL_ARGS)
646: {
647:
648: if (SEC_LIBRARY == n->sec) {
649: mm->need_nl = 1;
650: print_word(mm, ".br");
651: mm->need_nl = 1;
652: }
1.1 schwarze 653: }
654:
655: static int
656: pre_nm(DECL_ARGS)
657: {
658:
659: if (MDOC_ELEM != n->type && MDOC_HEAD != n->type)
660: return(1);
1.10 schwarze 661: if (MDOC_SYNPRETTY & n->flags) {
662: mm->need_nl = 1;
663: print_word(mm, ".br");
664: mm->need_nl = 1;
665: }
1.5 kristaps 666: print_word(mm, "\\fB");
667: mm->need_space = 0;
1.1 schwarze 668: if (NULL == n->child)
1.5 kristaps 669: print_word(mm, m->name);
1.1 schwarze 670: return(1);
671: }
672:
673: static void
674: post_nm(DECL_ARGS)
675: {
676:
677: if (MDOC_ELEM != n->type && MDOC_HEAD != n->type)
678: return;
1.5 kristaps 679: mm->need_space = 0;
680: print_word(mm, "\\fP");
1.1 schwarze 681: }
682:
683: static int
684: pre_ns(DECL_ARGS)
685: {
686:
1.5 kristaps 687: mm->need_space = 0;
1.1 schwarze 688: return(0);
689: }
690:
1.3 schwarze 691: static void
692: post_pf(DECL_ARGS)
693: {
694:
1.5 kristaps 695: mm->need_space = 0;
1.3 schwarze 696: }
697:
1.1 schwarze 698: static int
699: pre_pp(DECL_ARGS)
700: {
701:
1.5 kristaps 702: mm->need_nl = 1;
1.1 schwarze 703: if (MDOC_It == n->parent->tok)
1.5 kristaps 704: print_word(mm, ".sp");
1.1 schwarze 705: else
1.5 kristaps 706: print_word(mm, ".PP");
707: mm->need_nl = 1;
1.10 schwarze 708: return(MDOC_Rs == n->tok);
1.12 schwarze 709: }
710:
711: static int
712: pre_sm(DECL_ARGS)
713: {
714:
715: assert(n->child && MDOC_TEXT == n->child->type);
716: if (0 == strcmp("on", n->child->string))
717: mm->mode_space = 1;
718: else
719: mm->mode_space = 0;
720: return(0);
1.1 schwarze 721: }
722:
723: static int
1.3 schwarze 724: pre_sp(DECL_ARGS)
1.1 schwarze 725: {
726:
1.5 kristaps 727: mm->need_nl = 1;
728: print_word(mm, ".sp");
1.1 schwarze 729: return(1);
730: }
731:
732: static void
1.3 schwarze 733: post_sp(DECL_ARGS)
1.1 schwarze 734: {
735:
1.5 kristaps 736: mm->need_nl = 1;
1.1 schwarze 737: }
738:
739: static int
740: pre_xr(DECL_ARGS)
741: {
742:
743: n = n->child;
744: if (NULL == n)
745: return(0);
1.5 kristaps 746: print_node(m, n, mm);
1.1 schwarze 747: n = n->next;
748: if (NULL == n)
749: return(0);
1.5 kristaps 750: mm->need_space = 0;
751: print_word(mm, "(");
752: print_node(m, n, mm);
753: print_word(mm, ")");
1.1 schwarze 754: return(0);
1.8 schwarze 755: }
756:
757: static int
758: pre_ux(DECL_ARGS)
759: {
760:
761: print_word(mm, manacts[n->tok].prefix);
762: if (NULL == n->child)
763: return(0);
764: mm->need_space = 0;
765: print_word(mm, "\\~");
766: mm->need_space = 0;
767: return(1);
1.1 schwarze 768: }
CVSweb