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