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