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