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