Annotation of mandoc/mdoc_man.c, Revision 1.8
1.8 ! schwarze 1: /* $Id: mdoc_man.c,v 1.7 2011/10/08 12:47:40 kristaps 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 */
88: { NULL, NULL, NULL, NULL, NULL }, /* _Ad */
89: { NULL, NULL, NULL, NULL, NULL }, /* _An */
90: { NULL, pre_enc, post_enc, "\\fI", "\\fP" }, /* Ar */
91: { NULL, NULL, NULL, NULL, NULL }, /* _Cd */
92: { NULL, pre_enc, post_enc, "\\fB", "\\fP" }, /* Cm */
93: { NULL, NULL, NULL, NULL, NULL }, /* _Dv */
94: { NULL, NULL, NULL, NULL, NULL }, /* _Er */
95: { NULL, NULL, NULL, NULL, NULL }, /* _Ev */
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 */
106: { NULL, NULL, NULL, NULL, NULL }, /* _Li */
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 */
132: { NULL, NULL, NULL, NULL, NULL }, /* _Ac */
133: { NULL, NULL, NULL, NULL, NULL }, /* _Ao */
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.1 schwarze 143: { NULL, NULL, NULL, NULL, NULL }, /* _Dc */
144: { NULL, NULL, NULL, NULL, NULL }, /* _Do */
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.1 schwarze 151: { NULL, NULL, NULL, NULL, NULL }, /* _Ms */
152: { NULL, NULL, NULL, NULL, NULL }, /* _No */
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.1 schwarze 160: { NULL, NULL, NULL, NULL, NULL }, /* _Qc */
161: { cond_body, pre_enc, post_enc, "`", "'" }, /* Ql */
162: { NULL, NULL, NULL, NULL, NULL }, /* _Qo */
163: { NULL, NULL, NULL, NULL, NULL }, /* _Qq */
164: { NULL, NULL, NULL, NULL, NULL }, /* _Re */
165: { cond_body, pre_pp, NULL, NULL, NULL }, /* Rs */
166: { NULL, NULL, NULL, NULL, NULL }, /* _Sc */
167: { NULL, NULL, NULL, NULL, NULL }, /* _So */
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.1 schwarze 172: { NULL, NULL, NULL, NULL, NULL }, /* _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.1 schwarze 179: { NULL, NULL, NULL, NULL, NULL }, /* _Oc */
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 */
190: { NULL, NULL, NULL, NULL, NULL }, /* _Brq */
191: { NULL, NULL, NULL, NULL, NULL }, /* _Bro */
192: { NULL, NULL, NULL, NULL, NULL }, /* _Brc */
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;
293: if (prev && prev->line < n->line)
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.1 schwarze 382: }
383:
1.5 kristaps 384: /*
385: * Used in listings (percent = %A, e.g.).
386: * FIXME: this is incomplete.
387: * It doesn't print a nice ", and" for lists.
388: */
1.1 schwarze 389: static void
390: post_percent(DECL_ARGS)
391: {
392:
1.5 kristaps 393: post_enc(m, n, mm);
1.1 schwarze 394: if (n->next)
1.5 kristaps 395: print_word(mm, ",");
1.1 schwarze 396: else {
1.5 kristaps 397: print_word(mm, ".");
398: mm->need_nl = 1;
1.1 schwarze 399: }
400: }
401:
1.5 kristaps 402: /*
403: * Print before a section header.
404: */
1.1 schwarze 405: static int
1.3 schwarze 406: pre_sect(DECL_ARGS)
407: {
408:
409: if (MDOC_HEAD != n->type)
410: return(1);
1.5 kristaps 411: mm->need_nl = 1;
412: print_word(mm, manacts[n->tok].prefix);
413: print_word(mm, "\"");
414: mm->need_space = 0;
1.3 schwarze 415: return(1);
416: }
417:
1.5 kristaps 418: /*
419: * Print subsequent a section header.
420: */
1.3 schwarze 421: static void
422: post_sect(DECL_ARGS)
423: {
424:
425: if (MDOC_HEAD != n->type)
426: return;
1.5 kristaps 427: mm->need_space = 0;
428: print_word(mm, "\"");
429: mm->need_nl = 1;
1.3 schwarze 430: }
431:
432: static int
433: pre_ap(DECL_ARGS)
434: {
435:
1.5 kristaps 436: mm->need_space = 0;
437: print_word(mm, "'");
438: mm->need_space = 0;
1.3 schwarze 439: return(0);
440: }
441:
442: static int
443: pre_bd(DECL_ARGS)
444: {
445:
446: if (DISP_unfilled == n->norm->Bd.type ||
447: DISP_literal == n->norm->Bd.type) {
1.5 kristaps 448: mm->need_nl = 1;
449: print_word(mm, ".nf");
1.3 schwarze 450: }
1.5 kristaps 451: mm->need_nl = 1;
1.3 schwarze 452: return(1);
453: }
454:
455: static void
456: post_bd(DECL_ARGS)
457: {
458:
459: if (DISP_unfilled == n->norm->Bd.type ||
460: DISP_literal == n->norm->Bd.type) {
1.5 kristaps 461: mm->need_nl = 1;
462: print_word(mm, ".fi");
1.3 schwarze 463: }
1.5 kristaps 464: mm->need_nl = 1;
1.3 schwarze 465: }
466:
467: static int
468: pre_br(DECL_ARGS)
469: {
470:
1.5 kristaps 471: mm->need_nl = 1;
472: print_word(mm, ".br");
473: mm->need_nl = 1;
1.3 schwarze 474: return(0);
475: }
476:
477: static int
1.8 ! schwarze 478: pre_bx(DECL_ARGS)
! 479: {
! 480:
! 481: n = n->child;
! 482: if (n) {
! 483: print_word(mm, n->string);
! 484: mm->need_space = 0;
! 485: n = n->next;
! 486: }
! 487: print_word(mm, "BSD");
! 488: if (NULL == n)
! 489: return(0);
! 490: mm->need_space = 0;
! 491: print_word(mm, "-");
! 492: mm->need_space = 0;
! 493: print_word(mm, n->string);
! 494: return(0);
! 495: }
! 496:
! 497: static int
1.1 schwarze 498: pre_dl(DECL_ARGS)
499: {
500:
1.5 kristaps 501: mm->need_nl = 1;
502: print_word(mm, ".RS 6n");
503: mm->need_nl = 1;
1.1 schwarze 504: return(1);
505: }
506:
507: static void
508: post_dl(DECL_ARGS)
509: {
510:
1.5 kristaps 511: mm->need_nl = 1;
512: print_word(mm, ".RE");
513: mm->need_nl = 1;
1.1 schwarze 514: }
515:
516: static int
517: pre_it(DECL_ARGS)
518: {
519: const struct mdoc_node *bln;
520:
521: if (MDOC_HEAD == n->type) {
1.5 kristaps 522: mm->need_nl = 1;
523: print_word(mm, ".TP");
1.1 schwarze 524: bln = n->parent->parent->prev;
1.3 schwarze 525: switch (bln->norm->Bl.type) {
526: case (LIST_bullet):
1.5 kristaps 527: print_word(mm, "4n");
528: mm->need_nl = 1;
529: print_word(mm, "\\fBo\\fP");
1.3 schwarze 530: break;
531: default:
532: if (bln->norm->Bl.width)
1.5 kristaps 533: print_word(mm, bln->norm->Bl.width);
1.3 schwarze 534: break;
535: }
1.5 kristaps 536: mm->need_nl = 1;
1.1 schwarze 537: }
538: return(1);
539: }
540:
541: static int
542: pre_nm(DECL_ARGS)
543: {
544:
545: if (MDOC_ELEM != n->type && MDOC_HEAD != n->type)
546: return(1);
1.5 kristaps 547: print_word(mm, "\\fB");
548: mm->need_space = 0;
1.1 schwarze 549: if (NULL == n->child)
1.5 kristaps 550: print_word(mm, m->name);
1.1 schwarze 551: return(1);
552: }
553:
554: static void
555: post_nm(DECL_ARGS)
556: {
557:
558: if (MDOC_ELEM != n->type && MDOC_HEAD != n->type)
559: return;
1.5 kristaps 560: mm->need_space = 0;
561: print_word(mm, "\\fP");
1.1 schwarze 562: }
563:
564: static int
565: pre_ns(DECL_ARGS)
566: {
567:
1.5 kristaps 568: mm->need_space = 0;
1.1 schwarze 569: return(0);
570: }
571:
1.3 schwarze 572: static void
573: post_pf(DECL_ARGS)
574: {
575:
1.5 kristaps 576: mm->need_space = 0;
1.3 schwarze 577: }
578:
1.1 schwarze 579: static int
580: pre_pp(DECL_ARGS)
581: {
582:
1.5 kristaps 583: mm->need_nl = 1;
1.1 schwarze 584: if (MDOC_It == n->parent->tok)
1.5 kristaps 585: print_word(mm, ".sp");
1.1 schwarze 586: else
1.5 kristaps 587: print_word(mm, ".PP");
588: mm->need_nl = 1;
1.1 schwarze 589: return(1);
590: }
591:
592: static int
1.3 schwarze 593: pre_sp(DECL_ARGS)
1.1 schwarze 594: {
595:
1.5 kristaps 596: mm->need_nl = 1;
597: print_word(mm, ".sp");
1.1 schwarze 598: return(1);
599: }
600:
601: static void
1.3 schwarze 602: post_sp(DECL_ARGS)
1.1 schwarze 603: {
604:
1.5 kristaps 605: mm->need_nl = 1;
1.1 schwarze 606: }
607:
608: static int
609: pre_xr(DECL_ARGS)
610: {
611:
612: n = n->child;
613: if (NULL == n)
614: return(0);
1.5 kristaps 615: print_node(m, n, mm);
1.1 schwarze 616: n = n->next;
617: if (NULL == n)
618: return(0);
1.5 kristaps 619: mm->need_space = 0;
620: print_word(mm, "(");
621: print_node(m, n, mm);
622: print_word(mm, ")");
1.1 schwarze 623: return(0);
1.8 ! schwarze 624: }
! 625:
! 626: static int
! 627: pre_ux(DECL_ARGS)
! 628: {
! 629:
! 630: print_word(mm, manacts[n->tok].prefix);
! 631: if (NULL == n->child)
! 632: return(0);
! 633: mm->need_space = 0;
! 634: print_word(mm, "\\~");
! 635: mm->need_space = 0;
! 636: return(1);
1.1 schwarze 637: }
CVSweb