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