Annotation of mandoc/mdoc_man.c, Revision 1.10
1.10 ! schwarze 1: /* $Id: mdoc_man.c,v 1.9 2011/10/24 21:47:59 schwarze Exp $ */
1.1 schwarze 2: /*
3: * Copyright (c) 2011 Ingo Schwarze <schwarze@openbsd.org>
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.1 schwarze 21: #include <stdio.h>
22: #include <string.h>
23:
24: #include "mandoc.h"
1.4 kristaps 25: #include "man.h"
1.1 schwarze 26: #include "mdoc.h"
27: #include "main.h"
28:
1.5 kristaps 29: #define DECL_ARGS const struct mdoc_meta *m, \
30: const struct mdoc_node *n, \
31: struct mman *mm
1.1 schwarze 32:
1.5 kristaps 33: struct mman {
34: int need_space; /* next word needs prior ws */
35: int need_nl; /* next word needs prior nl */
36: };
1.1 schwarze 37:
38: struct manact {
1.5 kristaps 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.5 kristaps 46: static int cond_body(DECL_ARGS);
1.1 schwarze 47: static int cond_head(DECL_ARGS);
1.5 kristaps 48: static void post_bd(DECL_ARGS);
49: static void post_dl(DECL_ARGS);
1.1 schwarze 50: static void post_enc(DECL_ARGS);
1.5 kristaps 51: static void post_nm(DECL_ARGS);
1.1 schwarze 52: static void post_percent(DECL_ARGS);
1.5 kristaps 53: static void post_pf(DECL_ARGS);
1.3 schwarze 54: static void post_sect(DECL_ARGS);
1.5 kristaps 55: static void post_sp(DECL_ARGS);
1.3 schwarze 56: static int pre_ap(DECL_ARGS);
57: static int pre_bd(DECL_ARGS);
58: static int pre_br(DECL_ARGS);
1.8 schwarze 59: static int pre_bx(DECL_ARGS);
1.1 schwarze 60: static int pre_dl(DECL_ARGS);
1.5 kristaps 61: static int pre_enc(DECL_ARGS);
1.1 schwarze 62: static int pre_it(DECL_ARGS);
63: static int pre_nm(DECL_ARGS);
64: static int pre_ns(DECL_ARGS);
65: static int pre_pp(DECL_ARGS);
1.3 schwarze 66: static int pre_sp(DECL_ARGS);
1.5 kristaps 67: static int pre_sect(DECL_ARGS);
1.8 schwarze 68: static int pre_ux(DECL_ARGS);
1.1 schwarze 69: static int pre_xr(DECL_ARGS);
1.5 kristaps 70: static void print_word(struct mman *, const char *);
71: static void print_node(DECL_ARGS);
1.1 schwarze 72:
1.3 schwarze 73: static const struct manact manacts[MDOC_MAX + 1] = {
74: { NULL, pre_ap, NULL, NULL, NULL }, /* Ap */
75: { NULL, NULL, NULL, NULL, NULL }, /* Dd */
76: { NULL, NULL, NULL, NULL, NULL }, /* Dt */
1.8 schwarze 77: { NULL, NULL, NULL, NULL, NULL }, /* Os */
1.3 schwarze 78: { NULL, pre_sect, post_sect, ".SH", NULL }, /* Sh */
79: { NULL, pre_sect, post_sect, ".SS", NULL }, /* Ss */
1.1 schwarze 80: { NULL, pre_pp, NULL, NULL, NULL }, /* Pp */
1.3 schwarze 81: { cond_body, pre_dl, post_dl, NULL, NULL }, /* D1 */
1.1 schwarze 82: { cond_body, pre_dl, post_dl, NULL, NULL }, /* Dl */
1.3 schwarze 83: { cond_body, pre_bd, post_bd, NULL, NULL }, /* Bd */
84: { NULL, NULL, NULL, NULL, NULL }, /* Ed */
85: { NULL, NULL, NULL, NULL, NULL }, /* Bl */
86: { NULL, NULL, NULL, NULL, NULL }, /* El */
1.1 schwarze 87: { NULL, pre_it, NULL, NULL, NULL }, /* _It */
1.9 schwarze 88: { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Ad */
1.1 schwarze 89: { NULL, NULL, NULL, NULL, NULL }, /* _An */
90: { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Ar */
1.9 schwarze 91: { NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Cd */
1.1 schwarze 92: { NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Cm */
1.9 schwarze 93: { NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Dv */
94: { NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Er */
95: { NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Ev */
1.1 schwarze 96: { NULL, pre_enc, post_enc, "The \\fB",
97: "\\fP\nutility exits 0 on success, and >0 if an error occurs."
98: }, /* Ex */
99: { NULL, NULL, NULL, NULL, NULL }, /* _Fa */
100: { NULL, NULL, NULL, NULL, NULL }, /* _Fd */
101: { NULL, pre_enc, post_enc, "\\fB-", "\\fP" }, /* Fl */
102: { NULL, NULL, NULL, NULL, NULL }, /* _Fn */
103: { NULL, NULL, NULL, NULL, NULL }, /* _Ft */
1.3 schwarze 104: { NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Ic */
1.1 schwarze 105: { NULL, NULL, NULL, NULL, NULL }, /* _In */
1.9 schwarze 106: { NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Li */
1.1 schwarze 107: { cond_head, pre_enc, NULL, "\\- ", NULL }, /* Nd */
108: { NULL, pre_nm, post_nm, NULL, NULL }, /* Nm */
109: { cond_body, pre_enc, post_enc, "[", "]" }, /* Op */
1.8 schwarze 110: { NULL, NULL, NULL, NULL, NULL }, /* Ot */
111: { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Pa */
1.6 kristaps 112: { NULL, pre_enc, post_enc, "The \\fB",
113: "\\fP\nfunction returns the value 0 if successful;\n"
114: "otherwise the value -1 is returned and the global\n"
115: "variable \\fIerrno\\fP is set to indicate the error."
116: }, /* Rv */
1.8 schwarze 117: { NULL, NULL, NULL, NULL, NULL }, /* St */
1.1 schwarze 118: { NULL, NULL, NULL, NULL, NULL }, /* _Va */
119: { NULL, NULL, NULL, NULL, NULL }, /* _Vt */
1.8 schwarze 120: { NULL, pre_xr, NULL, NULL, NULL }, /* Xr */
1.1 schwarze 121: { NULL, NULL, post_percent, NULL, NULL }, /* _%A */
122: { NULL, NULL, NULL, NULL, NULL }, /* _%B */
123: { NULL, NULL, post_percent, NULL, NULL }, /* _%D */
124: { NULL, NULL, NULL, NULL, NULL }, /* _%I */
125: { NULL, pre_enc, post_percent, "\\fI", "\\fP" }, /* %J */
126: { NULL, NULL, NULL, NULL, NULL }, /* _%N */
127: { NULL, NULL, NULL, NULL, NULL }, /* _%O */
128: { NULL, NULL, NULL, NULL, NULL }, /* _%P */
129: { NULL, NULL, NULL, NULL, NULL }, /* _%R */
130: { NULL, pre_enc, post_percent, "\"", "\"" }, /* %T */
131: { NULL, NULL, NULL, NULL, NULL }, /* _%V */
1.9 schwarze 132: { NULL, NULL, NULL, NULL, NULL }, /* Ac */
133: { cond_body, pre_enc, post_enc, "<", ">" }, /* Ao */
1.1 schwarze 134: { cond_body, pre_enc, post_enc, "<", ">" }, /* Aq */
1.8 schwarze 135: { NULL, NULL, NULL, NULL, NULL }, /* At */
1.3 schwarze 136: { NULL, NULL, NULL, NULL, NULL }, /* Bc */
1.1 schwarze 137: { NULL, NULL, NULL, NULL, NULL }, /* _Bf */
1.3 schwarze 138: { cond_body, pre_enc, post_enc, "[", "]" }, /* Bo */
139: { cond_body, pre_enc, post_enc, "[", "]" }, /* Bq */
1.8 schwarze 140: { NULL, pre_ux, NULL, "BSD/OS", NULL }, /* Bsx */
141: { NULL, pre_bx, NULL, NULL, NULL }, /* Bx */
142: { NULL, NULL, NULL, NULL, NULL }, /* Db */
1.9 schwarze 143: { NULL, NULL, NULL, NULL, NULL }, /* Dc */
144: { cond_body, pre_enc, post_enc, "``", "''" }, /* Do */
1.1 schwarze 145: { cond_body, pre_enc, post_enc, "``", "''" }, /* Dq */
146: { NULL, NULL, NULL, NULL, NULL }, /* _Ec */
147: { NULL, NULL, NULL, NULL, NULL }, /* _Ef */
1.3 schwarze 148: { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Em */
1.1 schwarze 149: { NULL, NULL, NULL, NULL, NULL }, /* _Eo */
1.8 schwarze 150: { NULL, pre_ux, NULL, "FreeBSD", NULL }, /* Fx */
1.9 schwarze 151: { NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Ms */
152: { NULL, NULL, NULL, NULL, NULL }, /* No */
1.1 schwarze 153: { NULL, pre_ns, NULL, NULL, NULL }, /* Ns */
1.8 schwarze 154: { NULL, pre_ux, NULL, "NetBSD", NULL }, /* Nx */
155: { NULL, pre_ux, NULL, "OpenBSD", NULL }, /* Ox */
1.3 schwarze 156: { NULL, NULL, NULL, NULL, NULL }, /* Pc */
157: { NULL, NULL, post_pf, NULL, NULL }, /* Pf */
158: { cond_body, pre_enc, post_enc, "(", ")" }, /* Po */
159: { cond_body, pre_enc, post_enc, "(", ")" }, /* Pq */
1.9 schwarze 160: { NULL, NULL, NULL, NULL, NULL }, /* Qc */
1.1 schwarze 161: { cond_body, pre_enc, post_enc, "`", "'" }, /* Ql */
1.9 schwarze 162: { cond_body, pre_enc, post_enc, "\"", "\"" }, /* Qo */
163: { cond_body, pre_enc, post_enc, "\"", "\"" }, /* Qq */
164: { NULL, NULL, NULL, NULL, NULL }, /* Re */
1.1 schwarze 165: { cond_body, pre_pp, NULL, NULL, NULL }, /* Rs */
1.9 schwarze 166: { NULL, NULL, NULL, NULL, NULL }, /* Sc */
167: { cond_body, pre_enc, post_enc, "`", "'" }, /* So */
1.1 schwarze 168: { cond_body, pre_enc, post_enc, "`", "'" }, /* Sq */
169: { NULL, NULL, NULL, NULL, NULL }, /* _Sm */
1.3 schwarze 170: { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Sx */
171: { NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Sy */
1.9 schwarze 172: { NULL, pre_enc, post_enc, "\\fR", "\\fP" }, /* Tn */
1.8 schwarze 173: { NULL, pre_ux, NULL, "UNIX", NULL }, /* Ux */
1.1 schwarze 174: { NULL, NULL, NULL, NULL, NULL }, /* _Xc */
175: { NULL, NULL, NULL, NULL, NULL }, /* _Xo */
176: { NULL, NULL, NULL, NULL, NULL }, /* _Fo */
177: { NULL, NULL, NULL, NULL, NULL }, /* _Fc */
1.3 schwarze 178: { cond_body, pre_enc, post_enc, "[", "]" }, /* Oo */
1.9 schwarze 179: { NULL, NULL, NULL, NULL, NULL }, /* Oc */
1.1 schwarze 180: { NULL, NULL, NULL, NULL, NULL }, /* _Bk */
181: { NULL, NULL, NULL, NULL, NULL }, /* _Ek */
1.8 schwarze 182: { NULL, pre_ux, NULL, "is currently in beta test.", NULL }, /* Bt */
183: { NULL, NULL, NULL, NULL, NULL }, /* Hf */
184: { NULL, NULL, NULL, NULL, NULL }, /* Fr */
185: { NULL, pre_ux, NULL, "currently under development.", NULL }, /* Ud */
1.1 schwarze 186: { NULL, NULL, NULL, NULL, NULL }, /* _Lb */
1.3 schwarze 187: { NULL, pre_pp, NULL, NULL, NULL }, /* Lp */
1.1 schwarze 188: { NULL, NULL, NULL, NULL, NULL }, /* _Lk */
189: { NULL, NULL, NULL, NULL, NULL }, /* _Mt */
1.9 schwarze 190: { cond_body, pre_enc, post_enc, "{", "}" }, /* Brq */
191: { cond_body, pre_enc, post_enc, "{", "}" }, /* Bro */
192: { NULL, NULL, NULL, NULL, NULL }, /* Brc */
1.1 schwarze 193: { NULL, NULL, NULL, NULL, NULL }, /* _%C */
194: { NULL, NULL, NULL, NULL, NULL }, /* _Es */
195: { NULL, NULL, NULL, NULL, NULL }, /* _En */
1.8 schwarze 196: { NULL, pre_ux, NULL, "DragonFly", NULL }, /* Dx */
1.1 schwarze 197: { NULL, NULL, NULL, NULL, NULL }, /* _%Q */
1.3 schwarze 198: { NULL, pre_br, NULL, NULL, NULL }, /* br */
199: { NULL, pre_sp, post_sp, NULL, NULL }, /* sp */
1.1 schwarze 200: { NULL, NULL, NULL, NULL, NULL }, /* _%U */
201: { NULL, NULL, NULL, NULL, NULL }, /* _Ta */
1.3 schwarze 202: { NULL, NULL, NULL, NULL, NULL }, /* ROOT */
1.1 schwarze 203: };
204:
205: static void
1.5 kristaps 206: print_word(struct mman *mm, const char *s)
1.1 schwarze 207: {
1.5 kristaps 208:
209: if (mm->need_nl) {
210: /*
211: * If we need a newline, print it now and start afresh.
212: */
1.1 schwarze 213: putchar('\n');
1.5 kristaps 214: mm->need_space = 0;
215: mm->need_nl = 0;
216: } else if (mm->need_space && '\0' != s[0])
217: /*
218: * If we need a space, only print it before
219: * (1) a nonzero length word;
220: * (2) a word that is non-punctuation; and
221: * (3) if punctuation, non-terminating puncutation.
222: */
223: if (NULL == strchr(".,:;)]?!", s[0]) || '\0' != s[1])
224: putchar(' ');
225:
226: /*
227: * Reassign needing space if we're not following opening
228: * punctuation.
229: */
230: mm->need_space =
231: ('(' != s[0] && '[' != s[0]) || '\0' != s[1];
232:
1.1 schwarze 233: for ( ; *s; s++) {
234: switch (*s) {
235: case (ASCII_NBRSP):
236: printf("\\~");
237: break;
238: case (ASCII_HYPH):
239: putchar('-');
240: break;
241: default:
1.5 kristaps 242: putchar((unsigned char)*s);
1.1 schwarze 243: break;
244: }
245: }
1.4 kristaps 246: }
247:
248: void
249: man_man(void *arg, const struct man *man)
250: {
251:
1.5 kristaps 252: /*
253: * Dump the keep buffer.
254: * We're guaranteed by now that this exists (is non-NULL).
255: * Flush stdout afterward, just in case.
256: */
1.4 kristaps 257: fputs(mparse_getkeep(man_mparse(man)), stdout);
1.5 kristaps 258: fflush(stdout);
1.1 schwarze 259: }
260:
261: void
262: man_mdoc(void *arg, const struct mdoc *mdoc)
263: {
264: const struct mdoc_meta *m;
265: const struct mdoc_node *n;
1.5 kristaps 266: struct mman mm;
1.1 schwarze 267:
268: m = mdoc_meta(mdoc);
269: n = mdoc_node(mdoc);
270:
1.3 schwarze 271: printf(".TH \"%s\" \"%s\" \"%s\" \"%s\" \"%s\"",
1.5 kristaps 272: m->title, m->msec, m->date, m->os, m->vol);
1.1 schwarze 273:
1.5 kristaps 274: memset(&mm, 0, sizeof(struct mman));
275:
276: mm.need_nl = 1;
277: print_node(m, n, &mm);
1.3 schwarze 278: putchar('\n');
1.1 schwarze 279: }
280:
281: static void
282: print_node(DECL_ARGS)
283: {
284: const struct mdoc_node *prev, *sub;
1.5 kristaps 285: const struct manact *act;
1.1 schwarze 286: int cond, do_sub;
1.5 kristaps 287:
288: /*
289: * Break the line if we were parsed subsequent the current node.
290: * This makes the page structure be more consistent.
291: */
1.1 schwarze 292: prev = n->prev ? n->prev : n->parent;
1.10 ! schwarze 293: if (prev && prev->line < n->line && MDOC_Ns != prev->tok)
1.5 kristaps 294: mm->need_nl = 1;
1.1 schwarze 295:
1.5 kristaps 296: act = NULL;
1.1 schwarze 297: cond = 0;
298: do_sub = 1;
1.5 kristaps 299:
1.1 schwarze 300: if (MDOC_TEXT == n->type) {
1.5 kristaps 301: /*
302: * Make sure that we don't happen to start with a
303: * control character at the start of a line.
304: */
305: if (mm->need_nl && ('.' == *n->string ||
306: '\'' == *n->string)) {
307: print_word(mm, "\\&");
308: mm->need_space = 0;
1.3 schwarze 309: }
1.5 kristaps 310: print_word(mm, n->string);
1.1 schwarze 311: } else {
1.5 kristaps 312: /*
313: * Conditionally run the pre-node action handler for a
314: * node.
315: */
1.1 schwarze 316: act = manacts + n->tok;
1.5 kristaps 317: cond = NULL == act->cond || (*act->cond)(m, n, mm);
1.1 schwarze 318: if (cond && act->pre)
1.5 kristaps 319: do_sub = (*act->pre)(m, n, mm);
1.1 schwarze 320: }
321:
1.5 kristaps 322: /*
323: * Conditionally run all child nodes.
324: * Note that this iterates over children instead of using
325: * recursion. This prevents unnecessary depth in the stack.
326: */
1.1 schwarze 327: if (do_sub)
328: for (sub = n->child; sub; sub = sub->next)
1.5 kristaps 329: print_node(m, sub, mm);
1.1 schwarze 330:
1.5 kristaps 331: /*
332: * Lastly, conditionally run the post-node handler.
333: */
1.1 schwarze 334: if (cond && act->post)
1.5 kristaps 335: (*act->post)(m, n, mm);
1.1 schwarze 336: }
337:
338: static int
339: cond_head(DECL_ARGS)
340: {
1.5 kristaps 341:
1.1 schwarze 342: return(MDOC_HEAD == n->type);
343: }
344:
345: static int
346: cond_body(DECL_ARGS)
347: {
1.5 kristaps 348:
1.1 schwarze 349: return(MDOC_BODY == n->type);
350: }
351:
1.5 kristaps 352: /*
353: * Output a font encoding before a node, e.g., \fR.
354: * This obviously has no trailing space.
355: */
1.1 schwarze 356: static int
357: pre_enc(DECL_ARGS)
358: {
1.5 kristaps 359: const char *prefix;
1.1 schwarze 360:
361: prefix = manacts[n->tok].prefix;
362: if (NULL == prefix)
363: return(1);
1.5 kristaps 364: print_word(mm, prefix);
365: mm->need_space = 0;
1.1 schwarze 366: return(1);
367: }
368:
1.5 kristaps 369: /*
370: * Output a font encoding subsequent a node, e.g., \fP.
371: */
1.1 schwarze 372: static void
373: post_enc(DECL_ARGS)
374: {
375: const char *suffix;
376:
377: suffix = manacts[n->tok].suffix;
378: if (NULL == suffix)
379: return;
1.5 kristaps 380: mm->need_space = 0;
381: print_word(mm, suffix);
1.10 ! schwarze 382: if (MDOC_Fl == n->tok && 0 == n->nchild)
! 383: mm->need_space = 0;
1.1 schwarze 384: }
385:
1.5 kristaps 386: /*
387: * Used in listings (percent = %A, e.g.).
388: * FIXME: this is incomplete.
389: * It doesn't print a nice ", and" for lists.
390: */
1.1 schwarze 391: static void
392: post_percent(DECL_ARGS)
393: {
394:
1.5 kristaps 395: post_enc(m, n, mm);
1.1 schwarze 396: if (n->next)
1.5 kristaps 397: print_word(mm, ",");
1.1 schwarze 398: else {
1.5 kristaps 399: print_word(mm, ".");
400: mm->need_nl = 1;
1.1 schwarze 401: }
402: }
403:
1.5 kristaps 404: /*
405: * Print before a section header.
406: */
1.1 schwarze 407: static int
1.3 schwarze 408: pre_sect(DECL_ARGS)
409: {
410:
411: if (MDOC_HEAD != n->type)
412: return(1);
1.5 kristaps 413: mm->need_nl = 1;
414: print_word(mm, manacts[n->tok].prefix);
415: print_word(mm, "\"");
416: mm->need_space = 0;
1.3 schwarze 417: return(1);
418: }
419:
1.5 kristaps 420: /*
421: * Print subsequent a section header.
422: */
1.3 schwarze 423: static void
424: post_sect(DECL_ARGS)
425: {
426:
427: if (MDOC_HEAD != n->type)
428: return;
1.5 kristaps 429: mm->need_space = 0;
430: print_word(mm, "\"");
431: mm->need_nl = 1;
1.3 schwarze 432: }
433:
434: static int
435: pre_ap(DECL_ARGS)
436: {
437:
1.5 kristaps 438: mm->need_space = 0;
439: print_word(mm, "'");
440: mm->need_space = 0;
1.3 schwarze 441: return(0);
442: }
443:
444: static int
445: pre_bd(DECL_ARGS)
446: {
447:
448: if (DISP_unfilled == n->norm->Bd.type ||
449: DISP_literal == n->norm->Bd.type) {
1.5 kristaps 450: mm->need_nl = 1;
451: print_word(mm, ".nf");
1.3 schwarze 452: }
1.5 kristaps 453: mm->need_nl = 1;
1.3 schwarze 454: return(1);
455: }
456:
457: static void
458: post_bd(DECL_ARGS)
459: {
460:
461: if (DISP_unfilled == n->norm->Bd.type ||
462: DISP_literal == n->norm->Bd.type) {
1.5 kristaps 463: mm->need_nl = 1;
464: print_word(mm, ".fi");
1.3 schwarze 465: }
1.5 kristaps 466: mm->need_nl = 1;
1.3 schwarze 467: }
468:
469: static int
470: pre_br(DECL_ARGS)
471: {
472:
1.5 kristaps 473: mm->need_nl = 1;
474: print_word(mm, ".br");
475: mm->need_nl = 1;
1.3 schwarze 476: return(0);
477: }
478:
479: static int
1.8 schwarze 480: pre_bx(DECL_ARGS)
481: {
482:
483: n = n->child;
484: if (n) {
485: print_word(mm, n->string);
486: mm->need_space = 0;
487: n = n->next;
488: }
489: print_word(mm, "BSD");
490: if (NULL == n)
491: return(0);
492: mm->need_space = 0;
493: print_word(mm, "-");
494: mm->need_space = 0;
495: print_word(mm, n->string);
496: return(0);
497: }
498:
499: static int
1.1 schwarze 500: pre_dl(DECL_ARGS)
501: {
502:
1.5 kristaps 503: mm->need_nl = 1;
504: print_word(mm, ".RS 6n");
505: mm->need_nl = 1;
1.1 schwarze 506: return(1);
507: }
508:
509: static void
510: post_dl(DECL_ARGS)
511: {
512:
1.5 kristaps 513: mm->need_nl = 1;
514: print_word(mm, ".RE");
515: mm->need_nl = 1;
1.1 schwarze 516: }
517:
518: static int
519: pre_it(DECL_ARGS)
520: {
521: const struct mdoc_node *bln;
522:
523: if (MDOC_HEAD == n->type) {
1.5 kristaps 524: mm->need_nl = 1;
525: print_word(mm, ".TP");
1.1 schwarze 526: bln = n->parent->parent->prev;
1.3 schwarze 527: switch (bln->norm->Bl.type) {
528: case (LIST_bullet):
1.5 kristaps 529: print_word(mm, "4n");
530: mm->need_nl = 1;
531: print_word(mm, "\\fBo\\fP");
1.3 schwarze 532: break;
533: default:
534: if (bln->norm->Bl.width)
1.5 kristaps 535: print_word(mm, bln->norm->Bl.width);
1.3 schwarze 536: break;
537: }
1.5 kristaps 538: mm->need_nl = 1;
1.1 schwarze 539: }
540: return(1);
541: }
542:
543: static int
544: pre_nm(DECL_ARGS)
545: {
546:
547: if (MDOC_ELEM != n->type && MDOC_HEAD != n->type)
548: return(1);
1.10 ! schwarze 549: if (MDOC_SYNPRETTY & n->flags) {
! 550: mm->need_nl = 1;
! 551: print_word(mm, ".br");
! 552: mm->need_nl = 1;
! 553: }
1.5 kristaps 554: print_word(mm, "\\fB");
555: mm->need_space = 0;
1.1 schwarze 556: if (NULL == n->child)
1.5 kristaps 557: print_word(mm, m->name);
1.1 schwarze 558: return(1);
559: }
560:
561: static void
562: post_nm(DECL_ARGS)
563: {
564:
565: if (MDOC_ELEM != n->type && MDOC_HEAD != n->type)
566: return;
1.5 kristaps 567: mm->need_space = 0;
568: print_word(mm, "\\fP");
1.1 schwarze 569: }
570:
571: static int
572: pre_ns(DECL_ARGS)
573: {
574:
1.5 kristaps 575: mm->need_space = 0;
1.1 schwarze 576: return(0);
577: }
578:
1.3 schwarze 579: static void
580: post_pf(DECL_ARGS)
581: {
582:
1.5 kristaps 583: mm->need_space = 0;
1.3 schwarze 584: }
585:
1.1 schwarze 586: static int
587: pre_pp(DECL_ARGS)
588: {
589:
1.5 kristaps 590: mm->need_nl = 1;
1.1 schwarze 591: if (MDOC_It == n->parent->tok)
1.5 kristaps 592: print_word(mm, ".sp");
1.1 schwarze 593: else
1.5 kristaps 594: print_word(mm, ".PP");
595: mm->need_nl = 1;
1.10 ! schwarze 596: return(MDOC_Rs == n->tok);
1.1 schwarze 597: }
598:
599: static int
1.3 schwarze 600: pre_sp(DECL_ARGS)
1.1 schwarze 601: {
602:
1.5 kristaps 603: mm->need_nl = 1;
604: print_word(mm, ".sp");
1.1 schwarze 605: return(1);
606: }
607:
608: static void
1.3 schwarze 609: post_sp(DECL_ARGS)
1.1 schwarze 610: {
611:
1.5 kristaps 612: mm->need_nl = 1;
1.1 schwarze 613: }
614:
615: static int
616: pre_xr(DECL_ARGS)
617: {
618:
619: n = n->child;
620: if (NULL == n)
621: return(0);
1.5 kristaps 622: print_node(m, n, mm);
1.1 schwarze 623: n = n->next;
624: if (NULL == n)
625: return(0);
1.5 kristaps 626: mm->need_space = 0;
627: print_word(mm, "(");
628: print_node(m, n, mm);
629: print_word(mm, ")");
1.1 schwarze 630: return(0);
1.8 schwarze 631: }
632:
633: static int
634: pre_ux(DECL_ARGS)
635: {
636:
637: print_word(mm, manacts[n->tok].prefix);
638: if (NULL == n->child)
639: return(0);
640: mm->need_space = 0;
641: print_word(mm, "\\~");
642: mm->need_space = 0;
643: return(1);
1.1 schwarze 644: }
CVSweb