Annotation of src/usr.bin/mandoc/man_html.c, Revision 1.25
1.25 ! schwarze 1: /* $Id: man_html.c,v 1.24 2010/12/19 07:53:12 schwarze Exp $ */
1.1 schwarze 2: /*
1.17 schwarze 3: * Copyright (c) 2008, 2009, 2010 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: #define HALFINDENT 3
36:
37: #define MAN_ARGS const struct man_meta *m, \
38: const struct man_node *n, \
1.18 schwarze 39: struct mhtml *mh, \
1.1 schwarze 40: struct html *h
41:
1.18 schwarze 42: struct mhtml {
43: int fl;
44: #define MANH_LITERAL (1 << 0) /* literal context */
45: };
46:
1.1 schwarze 47: struct htmlman {
48: int (*pre)(MAN_ARGS);
49: int (*post)(MAN_ARGS);
50: };
51:
52: static void print_man(MAN_ARGS);
53: static void print_man_head(MAN_ARGS);
54: static void print_man_nodelist(MAN_ARGS);
55: static void print_man_node(MAN_ARGS);
56:
57: static int a2width(const struct man_node *,
58: struct roffsu *);
59:
60: static int man_alt_pre(MAN_ARGS);
61: static int man_br_pre(MAN_ARGS);
62: static int man_ign_pre(MAN_ARGS);
1.18 schwarze 63: static int man_in_pre(MAN_ARGS);
64: static int man_literal_pre(MAN_ARGS);
1.1 schwarze 65: static void man_root_post(MAN_ARGS);
66: static int man_root_pre(MAN_ARGS);
67: static int man_B_pre(MAN_ARGS);
68: static int man_HP_pre(MAN_ARGS);
69: static int man_I_pre(MAN_ARGS);
70: static int man_IP_pre(MAN_ARGS);
71: static int man_PP_pre(MAN_ARGS);
72: static int man_RS_pre(MAN_ARGS);
73: static int man_SB_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 */
90: { man_SB_pre, NULL }, /* SB */
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 */
100: { NULL, NULL }, /* na */
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.19 schwarze 111: { NULL, NULL }, /* TS */
112: { NULL, NULL }, /* TE */
1.23 schwarze 113: { man_ign_pre, NULL }, /* ft */
1.1 schwarze 114: };
115:
116:
117: void
118: html_man(void *arg, const struct man *m)
119: {
120: struct html *h;
121: struct tag *t;
1.18 schwarze 122: struct mhtml mh;
1.1 schwarze 123:
124: h = (struct html *)arg;
125:
1.5 schwarze 126: print_gen_decls(h);
1.1 schwarze 127:
1.18 schwarze 128: memset(&mh, 0, sizeof(struct mhtml));
129:
1.1 schwarze 130: t = print_otag(h, TAG_HTML, 0, NULL);
1.18 schwarze 131: print_man(man_meta(m), man_node(m), &mh, h);
1.1 schwarze 132: print_tagq(h, t);
133:
134: printf("\n");
135: }
136:
137:
138: static void
139: print_man(MAN_ARGS)
140: {
141: struct tag *t;
142:
143: t = print_otag(h, TAG_HEAD, 0, NULL);
1.18 schwarze 144: print_man_head(m, n, mh, h);
1.1 schwarze 145: print_tagq(h, t);
1.25 ! schwarze 146:
1.1 schwarze 147: t = print_otag(h, TAG_BODY, 0, NULL);
1.18 schwarze 148: print_man_nodelist(m, n, mh, h);
1.1 schwarze 149: print_tagq(h, t);
150: }
151:
152:
153: /* ARGSUSED */
154: static void
155: print_man_head(MAN_ARGS)
156: {
157:
158: print_gen_head(h);
159: bufinit(h);
1.10 schwarze 160: buffmt(h, "%s(%s)", m->title, m->msec);
1.1 schwarze 161:
162: print_otag(h, TAG_TITLE, 0, NULL);
163: print_text(h, h->buf);
164: }
165:
166:
167: static void
168: print_man_nodelist(MAN_ARGS)
169: {
170:
1.18 schwarze 171: print_man_node(m, n, mh, h);
1.1 schwarze 172: if (n->next)
1.18 schwarze 173: print_man_nodelist(m, n->next, mh, h);
1.1 schwarze 174: }
175:
176:
177: static void
178: print_man_node(MAN_ARGS)
179: {
180: int child;
181: struct tag *t;
182:
183: child = 1;
1.2 schwarze 184: t = h->tags.head;
1.1 schwarze 185:
186: bufinit(h);
187:
1.7 schwarze 188: /*
189: * FIXME: embedded elements within next-line scopes (e.g., `br'
190: * within an empty `B') will cause formatting to be forgotten
191: * due to scope closing out.
192: */
193:
1.1 schwarze 194: switch (n->type) {
195: case (MAN_ROOT):
1.18 schwarze 196: child = man_root_pre(m, n, mh, h);
1.1 schwarze 197: break;
198: case (MAN_TEXT):
199: print_text(h, n->string);
1.18 schwarze 200:
201: if (MANH_LITERAL & mh->fl)
202: print_otag(h, TAG_BR, 0, NULL);
203:
1.4 schwarze 204: return;
1.1 schwarze 205: default:
1.4 schwarze 206: /*
207: * Close out scope of font prior to opening a macro
208: * scope. Assert that the metafont is on the top of the
209: * stack (it's never nested).
210: */
211: if (h->metaf) {
212: assert(h->metaf == t);
213: print_tagq(h, h->metaf);
214: assert(NULL == h->metaf);
215: t = h->tags.head;
216: }
1.1 schwarze 217: if (mans[n->tok].pre)
1.18 schwarze 218: child = (*mans[n->tok].pre)(m, n, mh, h);
1.1 schwarze 219: break;
220: }
221:
222: if (child && n->child)
1.18 schwarze 223: print_man_nodelist(m, n->child, mh, h);
1.1 schwarze 224:
1.4 schwarze 225: /* This will automatically close out any font scope. */
1.1 schwarze 226: print_stagq(h, t);
227:
228: bufinit(h);
229:
230: switch (n->type) {
231: case (MAN_ROOT):
1.18 schwarze 232: man_root_post(m, n, mh, h);
1.1 schwarze 233: break;
234: case (MAN_TEXT):
235: break;
236: default:
237: if (mans[n->tok].post)
1.18 schwarze 238: (*mans[n->tok].post)(m, n, mh, h);
1.1 schwarze 239: break;
240: }
241: }
242:
243:
244: static int
245: a2width(const struct man_node *n, struct roffsu *su)
246: {
247:
248: if (MAN_TEXT != n->type)
249: return(0);
250: if (a2roffsu(n->string, su, SCALE_BU))
251: return(1);
252:
253: return(0);
254: }
255:
256:
257: /* ARGSUSED */
258: static int
259: man_root_pre(MAN_ARGS)
260: {
1.25 ! schwarze 261: struct htmlpair tag[2];
1.1 schwarze 262: struct tag *t, *tt;
263: char b[BUFSIZ], title[BUFSIZ];
264:
265: b[0] = 0;
266: if (m->vol)
267: (void)strlcat(b, m->vol, BUFSIZ);
268:
1.10 schwarze 269: snprintf(title, BUFSIZ - 1, "%s(%s)", m->title, m->msec);
1.1 schwarze 270:
1.25 ! schwarze 271: PAIR_CLASS_INIT(&tag[0], "head");
! 272: PAIR_SUMMARY_INIT(&tag[1], "Document Header");
! 273: t = print_otag(h, TAG_TABLE, 2, tag);
1.3 schwarze 274:
1.1 schwarze 275: tt = print_otag(h, TAG_TR, 0, NULL);
276:
1.25 ! schwarze 277: PAIR_CLASS_INIT(&tag[0], "head-ltitle");
1.1 schwarze 278: print_otag(h, TAG_TD, 1, tag);
1.25 ! schwarze 279:
1.1 schwarze 280: print_text(h, title);
281: print_stagq(h, tt);
282:
1.25 ! schwarze 283: PAIR_CLASS_INIT(&tag[0], "head-vol");
1.1 schwarze 284: print_otag(h, TAG_TD, 1, tag);
1.25 ! schwarze 285:
1.1 schwarze 286: print_text(h, b);
287: print_stagq(h, tt);
288:
1.25 ! schwarze 289: PAIR_CLASS_INIT(&tag[0], "head-rtitle");
1.1 schwarze 290: print_otag(h, TAG_TD, 1, tag);
1.25 ! schwarze 291:
1.1 schwarze 292: print_text(h, title);
293: print_tagq(h, t);
294: return(1);
295: }
296:
297:
298: /* ARGSUSED */
299: static void
300: man_root_post(MAN_ARGS)
301: {
1.25 ! schwarze 302: struct htmlpair tag[2];
1.1 schwarze 303: struct tag *t, *tt;
1.2 schwarze 304: char b[DATESIZ];
1.1 schwarze 305:
1.15 schwarze 306: if (m->rawdate)
307: strlcpy(b, m->rawdate, DATESIZ);
308: else
309: time2a(m->date, b, DATESIZ);
1.1 schwarze 310:
1.25 ! schwarze 311: PAIR_CLASS_INIT(&tag[0], "foot");
! 312: PAIR_SUMMARY_INIT(&tag[1], "Document Footer");
! 313: t = print_otag(h, TAG_TABLE, 2, tag);
1.3 schwarze 314:
1.1 schwarze 315: tt = print_otag(h, TAG_TR, 0, NULL);
316:
1.25 ! schwarze 317: PAIR_CLASS_INIT(&tag[0], "foot-date");
1.1 schwarze 318: print_otag(h, TAG_TD, 1, tag);
1.25 ! schwarze 319:
1.1 schwarze 320: print_text(h, b);
321: print_stagq(h, tt);
322:
1.25 ! schwarze 323: PAIR_CLASS_INIT(&tag[0], "foot-os");
1.1 schwarze 324: print_otag(h, TAG_TD, 1, tag);
1.25 ! schwarze 325:
1.1 schwarze 326: if (m->source)
327: print_text(h, m->source);
328: print_tagq(h, t);
329: }
330:
331:
332:
333: /* ARGSUSED */
334: static int
335: man_br_pre(MAN_ARGS)
336: {
337: struct roffsu su;
338: struct htmlpair tag;
339:
340: SCALE_VS_INIT(&su, 1);
341:
1.21 schwarze 342: if (MAN_sp == n->tok) {
1.8 schwarze 343: if (n->child)
344: a2roffsu(n->child->string, &su, SCALE_VS);
1.21 schwarze 345: } else
1.1 schwarze 346: su.scale = 0;
347:
348: bufcat_su(h, "height", &su);
349: PAIR_STYLE_INIT(&tag, h);
350: print_otag(h, TAG_DIV, 1, &tag);
1.4 schwarze 351:
1.3 schwarze 352: /* So the div isn't empty: */
353: print_text(h, "\\~");
354:
1.1 schwarze 355: return(0);
356: }
357:
358:
359: /* ARGSUSED */
360: static int
361: man_SH_pre(MAN_ARGS)
362: {
1.25 ! schwarze 363: struct htmlpair tag;
1.1 schwarze 364:
1.25 ! schwarze 365: if (MAN_BLOCK == n->type) {
! 366: PAIR_CLASS_INIT(&tag, "section");
! 367: print_otag(h, TAG_DIV, 1, &tag);
1.1 schwarze 368: return(1);
1.25 ! schwarze 369: } else if (MAN_BODY == n->type)
1.1 schwarze 370: return(1);
371:
1.25 ! schwarze 372: print_otag(h, TAG_H1, 0, NULL);
1.1 schwarze 373: return(1);
374: }
375:
376:
377: /* ARGSUSED */
378: static int
379: man_alt_pre(MAN_ARGS)
380: {
381: const struct man_node *nn;
382: struct tag *t;
383: int i;
1.4 schwarze 384: enum htmlfont fp;
1.1 schwarze 385:
386: for (i = 0, nn = n->child; nn; nn = nn->next, i++) {
387: switch (n->tok) {
388: case (MAN_BI):
1.4 schwarze 389: fp = i % 2 ? HTMLFONT_ITALIC : HTMLFONT_BOLD;
1.1 schwarze 390: break;
391: case (MAN_IB):
1.4 schwarze 392: fp = i % 2 ? HTMLFONT_BOLD : HTMLFONT_ITALIC;
1.1 schwarze 393: break;
394: case (MAN_RI):
1.4 schwarze 395: fp = i % 2 ? HTMLFONT_ITALIC : HTMLFONT_NONE;
1.1 schwarze 396: break;
397: case (MAN_IR):
1.4 schwarze 398: fp = i % 2 ? HTMLFONT_NONE : HTMLFONT_ITALIC;
1.1 schwarze 399: break;
400: case (MAN_BR):
1.4 schwarze 401: fp = i % 2 ? HTMLFONT_NONE : HTMLFONT_BOLD;
1.1 schwarze 402: break;
403: case (MAN_RB):
1.4 schwarze 404: fp = i % 2 ? HTMLFONT_BOLD : HTMLFONT_NONE;
1.1 schwarze 405: break;
406: default:
407: abort();
408: /* NOTREACHED */
409: }
410:
411: if (i)
412: h->flags |= HTML_NOSPACE;
413:
1.4 schwarze 414: /*
415: * Open and close the scope with each argument, so that
416: * internal \f escapes, which are common, are also
417: * closed out with the scope.
418: */
419: t = print_ofont(h, fp);
1.18 schwarze 420: print_man_node(m, nn, mh, h);
1.4 schwarze 421: print_tagq(h, t);
1.1 schwarze 422: }
423:
424: return(0);
425: }
426:
427:
428: /* ARGSUSED */
429: static int
430: man_SB_pre(MAN_ARGS)
431: {
432: struct htmlpair tag;
433:
1.4 schwarze 434: /* FIXME: print_ofont(). */
1.1 schwarze 435: PAIR_CLASS_INIT(&tag, "small bold");
436: print_otag(h, TAG_SPAN, 1, &tag);
437: return(1);
438: }
439:
440:
441: /* ARGSUSED */
442: static int
443: man_SM_pre(MAN_ARGS)
444: {
445: struct htmlpair tag;
446:
447: PAIR_CLASS_INIT(&tag, "small");
448: print_otag(h, TAG_SPAN, 1, &tag);
449: return(1);
450: }
451:
452:
453: /* ARGSUSED */
454: static int
455: man_SS_pre(MAN_ARGS)
456: {
1.25 ! schwarze 457: struct htmlpair tag;
1.1 schwarze 458:
1.25 ! schwarze 459: if (MAN_BLOCK == n->type) {
! 460: PAIR_CLASS_INIT(&tag, "subsection");
! 461: print_otag(h, TAG_DIV, 1, &tag);
1.1 schwarze 462: return(1);
1.25 ! schwarze 463: } else if (MAN_BODY == n->type)
1.1 schwarze 464: return(1);
465:
1.25 ! schwarze 466: print_otag(h, TAG_H2, 0, NULL);
1.1 schwarze 467: return(1);
468: }
469:
470:
471: /* ARGSUSED */
472: static int
473: man_PP_pre(MAN_ARGS)
474: {
475: struct htmlpair tag;
476: struct roffsu su;
477: int i;
478:
1.22 schwarze 479: if (MAN_BODY == n->type)
1.1 schwarze 480: return(1);
1.22 schwarze 481: if (MAN_HEAD == n->type)
482: return(0);
1.1 schwarze 483:
484: i = 0;
485:
1.4 schwarze 486: if (MAN_ROOT == n->parent->type) {
1.1 schwarze 487: SCALE_HS_INIT(&su, INDENT);
488: bufcat_su(h, "margin-left", &su);
1.4 schwarze 489: i = 1;
1.1 schwarze 490: }
1.4 schwarze 491: if (n->prev) {
1.1 schwarze 492: SCALE_VS_INIT(&su, 1);
1.4 schwarze 493: bufcat_su(h, "margin-top", &su);
494: i = 1;
1.1 schwarze 495: }
496:
497: PAIR_STYLE_INIT(&tag, h);
1.4 schwarze 498: print_otag(h, TAG_DIV, i, &tag);
1.22 schwarze 499:
1.1 schwarze 500: return(1);
501: }
502:
503:
504: /* ARGSUSED */
505: static int
506: man_IP_pre(MAN_ARGS)
507: {
508: struct roffsu su;
509: struct htmlpair tag;
510: const struct man_node *nn;
511: int width;
512:
513: /*
514: * This scattering of 1-BU margins and pads is to make sure that
515: * when text overruns its box, the subsequent text isn't flush
516: * up against it. However, the rest of the right-hand box must
517: * also be adjusted in consideration of this 1-BU space.
518: */
519:
520: if (MAN_BODY == n->type) {
521: SCALE_HS_INIT(&su, INDENT);
522: bufcat_su(h, "margin-left", &su);
523: PAIR_STYLE_INIT(&tag, h);
524: print_otag(h, TAG_DIV, 1, &tag);
525: return(1);
526: }
527:
528: nn = MAN_BLOCK == n->type ?
529: n->head->child : n->parent->head->child;
530:
531: SCALE_HS_INIT(&su, INDENT);
532: width = 0;
533:
1.7 schwarze 534: /* Width is the last token. */
535:
1.1 schwarze 536: if (MAN_IP == n->tok && NULL != nn)
537: if (NULL != (nn = nn->next)) {
538: for ( ; nn->next; nn = nn->next)
539: /* Do nothing. */ ;
540: width = a2width(nn, &su);
541: }
542:
1.7 schwarze 543: /* Width is the first token. */
544:
545: if (MAN_TP == n->tok && NULL != nn) {
546: /* Skip past non-text children. */
547: while (nn && MAN_TEXT != nn->type)
548: nn = nn->next;
549: if (nn)
550: width = a2width(nn, &su);
551: }
1.1 schwarze 552:
553: if (MAN_BLOCK == n->type) {
554: bufcat_su(h, "margin-left", &su);
555: SCALE_VS_INIT(&su, 1);
556: bufcat_su(h, "margin-top", &su);
557: bufcat_style(h, "clear", "both");
558: PAIR_STYLE_INIT(&tag, h);
559: print_otag(h, TAG_DIV, 1, &tag);
560: return(1);
561: }
562:
563: bufcat_su(h, "min-width", &su);
564: SCALE_INVERT(&su);
565: bufcat_su(h, "margin-left", &su);
566: SCALE_HS_INIT(&su, 1);
567: bufcat_su(h, "margin-right", &su);
568: bufcat_style(h, "clear", "left");
569:
570: if (n->next && n->next->child)
571: bufcat_style(h, "float", "left");
572:
573: PAIR_STYLE_INIT(&tag, h);
574: print_otag(h, TAG_DIV, 1, &tag);
575:
1.7 schwarze 576: /*
577: * Without a length string, we can print all of our children.
578: */
1.1 schwarze 579:
580: if ( ! width)
581: return(1);
1.7 schwarze 582:
583: /*
584: * When a length has been specified, we need to carefully print
585: * our child context: IP gets all children printed but the last
586: * (the width), while TP gets all children printed but the first
587: * (the width).
588: */
1.1 schwarze 589:
590: if (MAN_IP == n->tok)
591: for (nn = n->child; nn->next; nn = nn->next)
1.18 schwarze 592: print_man_node(m, nn, mh, h);
1.1 schwarze 593: if (MAN_TP == n->tok)
594: for (nn = n->child->next; nn; nn = nn->next)
1.18 schwarze 595: print_man_node(m, nn, mh, h);
1.1 schwarze 596:
597: return(0);
598: }
599:
600:
601: /* ARGSUSED */
602: static int
603: man_HP_pre(MAN_ARGS)
604: {
605: const struct man_node *nn;
606: struct htmlpair tag;
607: struct roffsu su;
608:
609: if (MAN_HEAD == n->type)
610: return(0);
611:
612: nn = MAN_BLOCK == n->type ?
613: n->head->child : n->parent->head->child;
614:
615: SCALE_HS_INIT(&su, INDENT);
616:
617: if (NULL != nn)
618: (void)a2width(nn, &su);
619:
620: if (MAN_BLOCK == n->type) {
621: bufcat_su(h, "margin-left", &su);
622: SCALE_VS_INIT(&su, 1);
623: bufcat_su(h, "margin-top", &su);
624: bufcat_style(h, "clear", "both");
625: PAIR_STYLE_INIT(&tag, h);
626: print_otag(h, TAG_DIV, 1, &tag);
627: return(1);
628: }
629:
630: bufcat_su(h, "margin-left", &su);
631: SCALE_INVERT(&su);
632: bufcat_su(h, "text-indent", &su);
633:
634: PAIR_STYLE_INIT(&tag, h);
635: print_otag(h, TAG_DIV, 1, &tag);
636: return(1);
637: }
638:
639:
640: /* ARGSUSED */
641: static int
642: man_B_pre(MAN_ARGS)
643: {
644:
1.4 schwarze 645: print_ofont(h, HTMLFONT_BOLD);
1.1 schwarze 646: return(1);
647: }
648:
649:
650: /* ARGSUSED */
651: static int
652: man_I_pre(MAN_ARGS)
653: {
1.4 schwarze 654:
655: print_ofont(h, HTMLFONT_ITALIC);
1.1 schwarze 656: return(1);
1.18 schwarze 657: }
658:
659:
660: /* ARGSUSED */
661: static int
662: man_literal_pre(MAN_ARGS)
663: {
664:
1.21 schwarze 665: if (MAN_nf == n->tok) {
1.18 schwarze 666: print_otag(h, TAG_BR, 0, NULL);
667: mh->fl |= MANH_LITERAL;
1.21 schwarze 668: } else
1.18 schwarze 669: mh->fl &= ~MANH_LITERAL;
670:
671: return(1);
672: }
673:
674:
675: /* ARGSUSED */
676: static int
677: man_in_pre(MAN_ARGS)
678: {
679:
680: print_otag(h, TAG_BR, 0, NULL);
681: return(0);
1.1 schwarze 682: }
683:
684:
685: /* ARGSUSED */
686: static int
687: man_ign_pre(MAN_ARGS)
688: {
689:
690: return(0);
691: }
692:
693:
694: /* ARGSUSED */
695: static int
696: man_RS_pre(MAN_ARGS)
697: {
698: struct htmlpair tag;
699: struct roffsu su;
700:
701: if (MAN_HEAD == n->type)
702: return(0);
703: else if (MAN_BODY == n->type)
704: return(1);
705:
706: SCALE_HS_INIT(&su, INDENT);
707: bufcat_su(h, "margin-left", &su);
708:
709: if (n->head->child) {
710: SCALE_VS_INIT(&su, 1);
711: a2width(n->head->child, &su);
712: bufcat_su(h, "margin-top", &su);
713: }
714:
715: PAIR_STYLE_INIT(&tag, h);
716: print_otag(h, TAG_DIV, 1, &tag);
717: return(1);
718: }