Annotation of src/usr.bin/mandoc/man_html.c, Revision 1.42
1.42 ! schwarze 1: /* $Id: man_html.c,v 1.41 2011/09/18 10:25:28 schwarze Exp $ */
1.1 schwarze 2: /*
1.29 schwarze 3: * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
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: */
17: #include <sys/types.h>
18:
19: #include <assert.h>
20: #include <ctype.h>
21: #include <stdio.h>
22: #include <stdlib.h>
23: #include <string.h>
24:
1.14 schwarze 25: #include "mandoc.h"
1.1 schwarze 26: #include "out.h"
27: #include "html.h"
28: #include "man.h"
29: #include "main.h"
30:
31: /* TODO: preserve ident widths. */
1.2 schwarze 32: /* FIXME: have PD set the default vspace width. */
1.1 schwarze 33:
34: #define INDENT 5
35:
36: #define MAN_ARGS const struct man_meta *m, \
37: const struct man_node *n, \
1.18 schwarze 38: struct mhtml *mh, \
1.1 schwarze 39: struct html *h
40:
1.18 schwarze 41: struct mhtml {
42: int fl;
43: #define MANH_LITERAL (1 << 0) /* literal context */
44: };
45:
1.1 schwarze 46: struct htmlman {
47: int (*pre)(MAN_ARGS);
48: int (*post)(MAN_ARGS);
49: };
50:
1.39 schwarze 51: static void print_bvspace(struct html *,
52: const struct man_node *);
1.1 schwarze 53: static void print_man(MAN_ARGS);
54: static void print_man_head(MAN_ARGS);
55: static void print_man_nodelist(MAN_ARGS);
56: static void print_man_node(MAN_ARGS);
57:
58: static int a2width(const struct man_node *,
59: struct roffsu *);
60:
61: static int man_alt_pre(MAN_ARGS);
62: static int man_br_pre(MAN_ARGS);
63: static int man_ign_pre(MAN_ARGS);
1.18 schwarze 64: static int man_in_pre(MAN_ARGS);
65: static int man_literal_pre(MAN_ARGS);
1.1 schwarze 66: static void man_root_post(MAN_ARGS);
1.38 schwarze 67: static void man_root_pre(MAN_ARGS);
1.1 schwarze 68: static int man_B_pre(MAN_ARGS);
69: static int man_HP_pre(MAN_ARGS);
70: static int man_I_pre(MAN_ARGS);
71: static int man_IP_pre(MAN_ARGS);
72: static int man_PP_pre(MAN_ARGS);
73: static int man_RS_pre(MAN_ARGS);
74: static int man_SH_pre(MAN_ARGS);
75: static int man_SM_pre(MAN_ARGS);
76: static int man_SS_pre(MAN_ARGS);
77:
78: static const struct htmlman mans[MAN_MAX] = {
79: { man_br_pre, NULL }, /* br */
80: { NULL, NULL }, /* TH */
81: { man_SH_pre, NULL }, /* SH */
82: { man_SS_pre, NULL }, /* SS */
83: { man_IP_pre, NULL }, /* TP */
84: { man_PP_pre, NULL }, /* LP */
85: { man_PP_pre, NULL }, /* PP */
86: { man_PP_pre, NULL }, /* P */
87: { man_IP_pre, NULL }, /* IP */
88: { man_HP_pre, NULL }, /* HP */
89: { man_SM_pre, NULL }, /* SM */
1.26 schwarze 90: { man_SM_pre, NULL }, /* SB */
1.1 schwarze 91: { man_alt_pre, NULL }, /* BI */
92: { man_alt_pre, NULL }, /* IB */
93: { man_alt_pre, NULL }, /* BR */
94: { man_alt_pre, NULL }, /* RB */
95: { NULL, NULL }, /* R */
96: { man_B_pre, NULL }, /* B */
97: { man_I_pre, NULL }, /* I */
98: { man_alt_pre, NULL }, /* IR */
99: { man_alt_pre, NULL }, /* RI */
1.34 schwarze 100: { man_ign_pre, NULL }, /* na */
1.1 schwarze 101: { man_br_pre, NULL }, /* sp */
1.18 schwarze 102: { man_literal_pre, NULL }, /* nf */
103: { man_literal_pre, NULL }, /* fi */
1.1 schwarze 104: { NULL, NULL }, /* RE */
105: { man_RS_pre, NULL }, /* RS */
106: { man_ign_pre, NULL }, /* DT */
107: { man_ign_pre, NULL }, /* UC */
1.2 schwarze 108: { man_ign_pre, NULL }, /* PD */
1.13 schwarze 109: { man_ign_pre, NULL }, /* AT */
1.18 schwarze 110: { man_in_pre, NULL }, /* in */
1.23 schwarze 111: { man_ign_pre, NULL }, /* ft */
1.1 schwarze 112: };
113:
1.39 schwarze 114: /*
115: * Printing leading vertical space before a block.
116: * This is used for the paragraph macros.
117: * The rules are pretty simple, since there's very little nesting going
118: * on here. Basically, if we're the first within another block (SS/SH),
119: * then don't emit vertical space. If we are (RS), then do. If not the
120: * first, print it.
121: */
122: static void
123: print_bvspace(struct html *h, const struct man_node *n)
124: {
125:
126: if (n->body && n->body->child)
127: if (MAN_TBL == n->body->child->type)
128: return;
129:
130: if (MAN_ROOT == n->parent->type || MAN_RS != n->parent->tok)
131: if (NULL == n->prev)
132: return;
133:
134: print_otag(h, TAG_P, 0, NULL);
135: }
1.1 schwarze 136:
137: void
138: html_man(void *arg, const struct man *m)
139: {
140: struct html *h;
141: struct tag *t;
1.18 schwarze 142: struct mhtml mh;
1.1 schwarze 143:
144: h = (struct html *)arg;
145:
1.5 schwarze 146: print_gen_decls(h);
1.1 schwarze 147:
1.18 schwarze 148: memset(&mh, 0, sizeof(struct mhtml));
149:
1.1 schwarze 150: t = print_otag(h, TAG_HTML, 0, NULL);
1.18 schwarze 151: print_man(man_meta(m), man_node(m), &mh, h);
1.1 schwarze 152: print_tagq(h, t);
153:
154: printf("\n");
155: }
156:
157: static void
158: print_man(MAN_ARGS)
159: {
160: struct tag *t;
161:
162: t = print_otag(h, TAG_HEAD, 0, NULL);
1.18 schwarze 163: print_man_head(m, n, mh, h);
1.1 schwarze 164: print_tagq(h, t);
1.25 schwarze 165:
1.1 schwarze 166: t = print_otag(h, TAG_BODY, 0, NULL);
1.18 schwarze 167: print_man_nodelist(m, n, mh, h);
1.1 schwarze 168: print_tagq(h, t);
169: }
170:
171:
172: /* ARGSUSED */
173: static void
174: print_man_head(MAN_ARGS)
175: {
176:
177: print_gen_head(h);
1.38 schwarze 178: bufcat_fmt(h, "%s(%s)", m->title, m->msec);
1.1 schwarze 179: print_otag(h, TAG_TITLE, 0, NULL);
180: print_text(h, h->buf);
181: }
182:
183:
184: static void
185: print_man_nodelist(MAN_ARGS)
186: {
187:
1.18 schwarze 188: print_man_node(m, n, mh, h);
1.1 schwarze 189: if (n->next)
1.18 schwarze 190: print_man_nodelist(m, n->next, mh, h);
1.1 schwarze 191: }
192:
193:
194: static void
195: print_man_node(MAN_ARGS)
196: {
197: int child;
198: struct tag *t;
199:
200: child = 1;
1.2 schwarze 201: t = h->tags.head;
1.1 schwarze 202:
203: switch (n->type) {
204: case (MAN_ROOT):
1.38 schwarze 205: man_root_pre(m, n, mh, h);
1.1 schwarze 206: break;
207: case (MAN_TEXT):
1.38 schwarze 208: /*
209: * If we have a blank line, output a vertical space.
210: * If we have a space as the first character, break
211: * before printing the line's data.
212: */
1.31 schwarze 213: if ('\0' == *n->string) {
214: print_otag(h, TAG_P, 0, NULL);
215: return;
1.40 schwarze 216: }
217:
218: if (' ' == *n->string && MAN_LINE & n->flags)
219: print_otag(h, TAG_BR, 0, NULL);
220: else if (MANH_LITERAL & mh->fl && n->prev)
1.31 schwarze 221: print_otag(h, TAG_BR, 0, NULL);
222:
1.1 schwarze 223: print_text(h, n->string);
1.36 schwarze 224: return;
225: case (MAN_EQN):
1.41 schwarze 226: print_eqn(h, n->eqn);
1.37 schwarze 227: break;
1.29 schwarze 228: case (MAN_TBL):
1.33 schwarze 229: /*
230: * This will take care of initialising all of the table
231: * state data for the first table, then tearing it down
232: * for the last one.
233: */
1.29 schwarze 234: print_tbl(h, n->span);
1.32 schwarze 235: return;
1.1 schwarze 236: default:
1.4 schwarze 237: /*
238: * Close out scope of font prior to opening a macro
1.33 schwarze 239: * scope.
1.4 schwarze 240: */
1.27 schwarze 241: if (HTMLFONT_NONE != h->metac) {
242: h->metal = h->metac;
243: h->metac = HTMLFONT_NONE;
1.33 schwarze 244: }
245:
246: /*
247: * Close out the current table, if it's open, and unset
248: * the "meta" table state. This will be reopened on the
249: * next table element.
250: */
251: if (h->tblt) {
252: print_tblclose(h);
253: t = h->tags.head;
1.4 schwarze 254: }
1.1 schwarze 255: if (mans[n->tok].pre)
1.18 schwarze 256: child = (*mans[n->tok].pre)(m, n, mh, h);
1.1 schwarze 257: break;
258: }
259:
260: if (child && n->child)
1.18 schwarze 261: print_man_nodelist(m, n->child, mh, h);
1.1 schwarze 262:
1.4 schwarze 263: /* This will automatically close out any font scope. */
1.1 schwarze 264: print_stagq(h, t);
265:
266: switch (n->type) {
267: case (MAN_ROOT):
1.18 schwarze 268: man_root_post(m, n, mh, h);
1.37 schwarze 269: break;
270: case (MAN_EQN):
1.1 schwarze 271: break;
272: default:
273: if (mans[n->tok].post)
1.18 schwarze 274: (*mans[n->tok].post)(m, n, mh, h);
1.1 schwarze 275: break;
276: }
277: }
278:
279:
280: static int
281: a2width(const struct man_node *n, struct roffsu *su)
282: {
283:
284: if (MAN_TEXT != n->type)
285: return(0);
286: if (a2roffsu(n->string, su, SCALE_BU))
287: return(1);
288:
289: return(0);
290: }
291:
292:
293: /* ARGSUSED */
1.38 schwarze 294: static void
1.1 schwarze 295: man_root_pre(MAN_ARGS)
296: {
1.26 schwarze 297: struct htmlpair tag[3];
1.1 schwarze 298: struct tag *t, *tt;
299: char b[BUFSIZ], title[BUFSIZ];
300:
301: b[0] = 0;
302: if (m->vol)
303: (void)strlcat(b, m->vol, BUFSIZ);
304:
1.10 schwarze 305: snprintf(title, BUFSIZ - 1, "%s(%s)", m->title, m->msec);
1.1 schwarze 306:
1.26 schwarze 307: PAIR_SUMMARY_INIT(&tag[0], "Document Header");
308: PAIR_CLASS_INIT(&tag[1], "head");
309: if (NULL == h->style) {
310: PAIR_INIT(&tag[2], ATTR_WIDTH, "100%");
311: t = print_otag(h, TAG_TABLE, 3, tag);
312: PAIR_INIT(&tag[0], ATTR_WIDTH, "30%");
313: print_otag(h, TAG_COL, 1, tag);
314: print_otag(h, TAG_COL, 1, tag);
315: print_otag(h, TAG_COL, 1, tag);
316: } else
317: t = print_otag(h, TAG_TABLE, 2, tag);
318:
319: print_otag(h, TAG_TBODY, 0, NULL);
1.3 schwarze 320:
1.1 schwarze 321: tt = print_otag(h, TAG_TR, 0, NULL);
322:
1.25 schwarze 323: PAIR_CLASS_INIT(&tag[0], "head-ltitle");
1.1 schwarze 324: print_otag(h, TAG_TD, 1, tag);
1.25 schwarze 325:
1.1 schwarze 326: print_text(h, title);
327: print_stagq(h, tt);
328:
1.25 schwarze 329: PAIR_CLASS_INIT(&tag[0], "head-vol");
1.26 schwarze 330: if (NULL == h->style) {
331: PAIR_INIT(&tag[1], ATTR_ALIGN, "center");
332: print_otag(h, TAG_TD, 2, tag);
333: } else
334: print_otag(h, TAG_TD, 1, tag);
1.25 schwarze 335:
1.1 schwarze 336: print_text(h, b);
337: print_stagq(h, tt);
338:
1.25 schwarze 339: PAIR_CLASS_INIT(&tag[0], "head-rtitle");
1.26 schwarze 340: if (NULL == h->style) {
341: PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
342: print_otag(h, TAG_TD, 2, tag);
343: } else
344: print_otag(h, TAG_TD, 1, tag);
1.25 schwarze 345:
1.1 schwarze 346: print_text(h, title);
347: print_tagq(h, t);
348: }
349:
350:
351: /* ARGSUSED */
352: static void
353: man_root_post(MAN_ARGS)
354: {
1.26 schwarze 355: struct htmlpair tag[3];
1.1 schwarze 356: struct tag *t, *tt;
357:
1.26 schwarze 358: PAIR_SUMMARY_INIT(&tag[0], "Document Footer");
359: PAIR_CLASS_INIT(&tag[1], "foot");
360: if (NULL == h->style) {
361: PAIR_INIT(&tag[2], ATTR_WIDTH, "100%");
362: t = print_otag(h, TAG_TABLE, 3, tag);
363: PAIR_INIT(&tag[0], ATTR_WIDTH, "50%");
364: print_otag(h, TAG_COL, 1, tag);
365: print_otag(h, TAG_COL, 1, tag);
366: } else
367: t = print_otag(h, TAG_TABLE, 2, tag);
1.3 schwarze 368:
1.1 schwarze 369: tt = print_otag(h, TAG_TR, 0, NULL);
370:
1.25 schwarze 371: PAIR_CLASS_INIT(&tag[0], "foot-date");
1.1 schwarze 372: print_otag(h, TAG_TD, 1, tag);
1.25 schwarze 373:
1.35 schwarze 374: print_text(h, m->date);
1.1 schwarze 375: print_stagq(h, tt);
376:
1.25 schwarze 377: PAIR_CLASS_INIT(&tag[0], "foot-os");
1.26 schwarze 378: if (NULL == h->style) {
379: PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
380: print_otag(h, TAG_TD, 2, tag);
381: } else
382: print_otag(h, TAG_TD, 1, tag);
1.25 schwarze 383:
1.1 schwarze 384: if (m->source)
385: print_text(h, m->source);
386: print_tagq(h, t);
387: }
388:
389:
390: /* ARGSUSED */
391: static int
392: man_br_pre(MAN_ARGS)
393: {
394: struct roffsu su;
395: struct htmlpair tag;
396:
397: SCALE_VS_INIT(&su, 1);
398:
1.21 schwarze 399: if (MAN_sp == n->tok) {
1.39 schwarze 400: if (NULL != (n = n->child))
401: if ( ! a2roffsu(n->string, &su, SCALE_VS))
402: SCALE_VS_INIT(&su, atoi(n->string));
1.21 schwarze 403: } else
1.1 schwarze 404: su.scale = 0;
405:
1.38 schwarze 406: bufinit(h);
1.1 schwarze 407: bufcat_su(h, "height", &su);
408: PAIR_STYLE_INIT(&tag, h);
409: print_otag(h, TAG_DIV, 1, &tag);
1.4 schwarze 410:
1.3 schwarze 411: /* So the div isn't empty: */
412: print_text(h, "\\~");
413:
1.1 schwarze 414: return(0);
415: }
416:
417: /* ARGSUSED */
418: static int
419: man_SH_pre(MAN_ARGS)
420: {
1.25 schwarze 421: struct htmlpair tag;
1.1 schwarze 422:
1.25 schwarze 423: if (MAN_BLOCK == n->type) {
1.39 schwarze 424: mh->fl &= ~MANH_LITERAL;
1.25 schwarze 425: PAIR_CLASS_INIT(&tag, "section");
426: print_otag(h, TAG_DIV, 1, &tag);
1.1 schwarze 427: return(1);
1.25 schwarze 428: } else if (MAN_BODY == n->type)
1.1 schwarze 429: return(1);
430:
1.25 schwarze 431: print_otag(h, TAG_H1, 0, NULL);
1.1 schwarze 432: return(1);
433: }
434:
435: /* ARGSUSED */
436: static int
437: man_alt_pre(MAN_ARGS)
438: {
439: const struct man_node *nn;
1.40 schwarze 440: int i, savelit;
1.27 schwarze 441: enum htmltag fp;
442: struct tag *t;
1.1 schwarze 443:
1.40 schwarze 444: if ((savelit = mh->fl & MANH_LITERAL))
445: print_otag(h, TAG_BR, 0, NULL);
446:
447: mh->fl &= ~MANH_LITERAL;
448:
1.1 schwarze 449: for (i = 0, nn = n->child; nn; nn = nn->next, i++) {
1.27 schwarze 450: t = NULL;
1.1 schwarze 451: switch (n->tok) {
452: case (MAN_BI):
1.27 schwarze 453: fp = i % 2 ? TAG_I : TAG_B;
1.1 schwarze 454: break;
455: case (MAN_IB):
1.27 schwarze 456: fp = i % 2 ? TAG_B : TAG_I;
1.1 schwarze 457: break;
458: case (MAN_RI):
1.27 schwarze 459: fp = i % 2 ? TAG_I : TAG_MAX;
1.1 schwarze 460: break;
461: case (MAN_IR):
1.27 schwarze 462: fp = i % 2 ? TAG_MAX : TAG_I;
1.1 schwarze 463: break;
464: case (MAN_BR):
1.27 schwarze 465: fp = i % 2 ? TAG_MAX : TAG_B;
1.1 schwarze 466: break;
467: case (MAN_RB):
1.27 schwarze 468: fp = i % 2 ? TAG_B : TAG_MAX;
1.1 schwarze 469: break;
470: default:
471: abort();
472: /* NOTREACHED */
473: }
474:
475: if (i)
476: h->flags |= HTML_NOSPACE;
477:
1.27 schwarze 478: if (TAG_MAX != fp)
479: t = print_otag(h, fp, 0, NULL);
480:
1.18 schwarze 481: print_man_node(m, nn, mh, h);
1.27 schwarze 482:
483: if (t)
484: print_tagq(h, t);
1.1 schwarze 485: }
486:
1.40 schwarze 487: if (savelit)
488: mh->fl |= MANH_LITERAL;
489:
1.1 schwarze 490: return(0);
491: }
492:
493: /* ARGSUSED */
494: static int
1.26 schwarze 495: man_SM_pre(MAN_ARGS)
1.1 schwarze 496: {
497:
1.27 schwarze 498: print_otag(h, TAG_SMALL, 0, NULL);
1.26 schwarze 499: if (MAN_SB == n->tok)
1.27 schwarze 500: print_otag(h, TAG_B, 0, NULL);
1.1 schwarze 501: return(1);
502: }
503:
504: /* ARGSUSED */
505: static int
506: man_SS_pre(MAN_ARGS)
507: {
1.25 schwarze 508: struct htmlpair tag;
1.1 schwarze 509:
1.25 schwarze 510: if (MAN_BLOCK == n->type) {
1.39 schwarze 511: mh->fl &= ~MANH_LITERAL;
1.25 schwarze 512: PAIR_CLASS_INIT(&tag, "subsection");
513: print_otag(h, TAG_DIV, 1, &tag);
1.1 schwarze 514: return(1);
1.25 schwarze 515: } else if (MAN_BODY == n->type)
1.1 schwarze 516: return(1);
517:
1.25 schwarze 518: print_otag(h, TAG_H2, 0, NULL);
1.1 schwarze 519: return(1);
520: }
521:
522: /* ARGSUSED */
523: static int
524: man_PP_pre(MAN_ARGS)
525: {
526:
1.22 schwarze 527: if (MAN_HEAD == n->type)
528: return(0);
1.39 schwarze 529: else if (MAN_BLOCK == n->type)
530: print_bvspace(h, n);
1.22 schwarze 531:
1.1 schwarze 532: return(1);
533: }
534:
535: /* ARGSUSED */
536: static int
537: man_IP_pre(MAN_ARGS)
538: {
539: const struct man_node *nn;
540:
541: if (MAN_BODY == n->type) {
1.40 schwarze 542: print_otag(h, TAG_DD, 0, NULL);
543: return(1);
544: } else if (MAN_HEAD != n->type) {
545: print_otag(h, TAG_DL, 0, NULL);
1.1 schwarze 546: return(1);
547: }
548:
1.40 schwarze 549: /* FIXME: width specification. */
1.7 schwarze 550:
1.40 schwarze 551: print_otag(h, TAG_DT, 0, NULL);
1.1 schwarze 552:
1.28 schwarze 553: /* For IP, only print the first header element. */
1.1 schwarze 554:
1.28 schwarze 555: if (MAN_IP == n->tok && n->child)
556: print_man_node(m, n->child, mh, h);
1.7 schwarze 557:
1.28 schwarze 558: /* For TP, only print next-line header elements. */
1.1 schwarze 559:
560: if (MAN_TP == n->tok)
1.28 schwarze 561: for (nn = n->child; nn; nn = nn->next)
562: if (nn->line > n->line)
563: print_man_node(m, nn, mh, h);
1.1 schwarze 564:
565: return(0);
566: }
567:
568: /* ARGSUSED */
569: static int
570: man_HP_pre(MAN_ARGS)
571: {
1.26 schwarze 572: struct htmlpair tag;
573: struct roffsu su;
574: const struct man_node *np;
1.1 schwarze 575:
1.40 schwarze 576: if (MAN_HEAD == n->type)
577: return(0);
578: else if (MAN_BLOCK != n->type)
579: return(1);
1.38 schwarze 580:
1.40 schwarze 581: np = n->head->child;
1.1 schwarze 582:
1.26 schwarze 583: if (NULL == np || ! a2width(np, &su))
584: SCALE_HS_INIT(&su, INDENT);
1.1 schwarze 585:
1.40 schwarze 586: bufinit(h);
1.1 schwarze 587:
1.40 schwarze 588: print_bvspace(h, n);
589: bufcat_su(h, "margin-left", &su);
1.26 schwarze 590: su.scale = -su.scale;
1.1 schwarze 591: bufcat_su(h, "text-indent", &su);
592: PAIR_STYLE_INIT(&tag, h);
1.40 schwarze 593: print_otag(h, TAG_P, 1, &tag);
1.1 schwarze 594: return(1);
595: }
596:
597: /* ARGSUSED */
598: static int
599: man_B_pre(MAN_ARGS)
600: {
601:
1.27 schwarze 602: print_otag(h, TAG_B, 0, NULL);
1.1 schwarze 603: return(1);
604: }
605:
606: /* ARGSUSED */
607: static int
608: man_I_pre(MAN_ARGS)
609: {
1.4 schwarze 610:
1.27 schwarze 611: print_otag(h, TAG_I, 0, NULL);
1.1 schwarze 612: return(1);
1.18 schwarze 613: }
614:
615: /* ARGSUSED */
616: static int
617: man_literal_pre(MAN_ARGS)
618: {
619:
1.40 schwarze 620: if (MAN_nf != n->tok) {
1.18 schwarze 621: print_otag(h, TAG_BR, 0, NULL);
1.40 schwarze 622: mh->fl &= ~MANH_LITERAL;
623: } else
1.18 schwarze 624: mh->fl |= MANH_LITERAL;
625:
1.34 schwarze 626: return(0);
1.18 schwarze 627: }
628:
629: /* ARGSUSED */
630: static int
631: man_in_pre(MAN_ARGS)
632: {
633:
634: print_otag(h, TAG_BR, 0, NULL);
635: return(0);
1.1 schwarze 636: }
637:
638: /* ARGSUSED */
639: static int
640: man_ign_pre(MAN_ARGS)
641: {
642:
643: return(0);
644: }
645:
646: /* ARGSUSED */
647: static int
648: man_RS_pre(MAN_ARGS)
649: {
650: struct htmlpair tag;
651: struct roffsu su;
652:
653: if (MAN_HEAD == n->type)
654: return(0);
655: else if (MAN_BODY == n->type)
656: return(1);
657:
658: SCALE_HS_INIT(&su, INDENT);
1.26 schwarze 659: if (n->head->child)
1.1 schwarze 660: a2width(n->head->child, &su);
661:
1.38 schwarze 662: bufinit(h);
1.26 schwarze 663: bufcat_su(h, "margin-left", &su);
1.1 schwarze 664: PAIR_STYLE_INIT(&tag, h);
665: print_otag(h, TAG_DIV, 1, &tag);
666: return(1);
667: }