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