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