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