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