Annotation of mandoc/man_html.c, Revision 1.93
1.93 ! schwarze 1: /* $Id: man_html.c,v 1.92 2014/03/30 19:47:48 schwarze Exp $ */
1.1 kristaps 2: /*
1.87 schwarze 3: * Copyright (c) 2008-2012 Kristaps Dzonsons <kristaps@bsd.lv>
1.91 schwarze 4: * Copyright (c) 2013, 2014 Ingo Schwarze <schwarze@openbsd.org>
1.1 kristaps 5: *
6: * Permission to use, copy, modify, and distribute this software for any
7: * purpose with or without fee is hereby granted, provided that the above
8: * copyright notice and this permission notice appear in all copies.
9: *
10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17: */
1.25 kristaps 18: #ifdef HAVE_CONFIG_H
19: #include "config.h"
20: #endif
21:
1.1 kristaps 22: #include <sys/types.h>
23:
1.5 kristaps 24: #include <assert.h>
25: #include <ctype.h>
1.2 kristaps 26: #include <stdio.h>
1.1 kristaps 27: #include <stdlib.h>
1.4 kristaps 28: #include <string.h>
1.1 kristaps 29:
1.35 kristaps 30: #include "mandoc.h"
1.7 kristaps 31: #include "out.h"
1.1 kristaps 32: #include "html.h"
33: #include "man.h"
1.10 kristaps 34: #include "main.h"
1.1 kristaps 35:
1.6 kristaps 36: /* TODO: preserve ident widths. */
1.13 kristaps 37: /* FIXME: have PD set the default vspace width. */
1.6 kristaps 38:
39: #define INDENT 5
1.4 kristaps 40:
1.89 schwarze 41: #define MAN_ARGS const struct man_meta *man, \
1.3 kristaps 42: const struct man_node *n, \
1.45 kristaps 43: struct mhtml *mh, \
1.3 kristaps 44: struct html *h
45:
1.45 kristaps 46: struct mhtml {
47: int fl;
48: #define MANH_LITERAL (1 << 0) /* literal context */
49: };
50:
1.3 kristaps 51: struct htmlman {
52: int (*pre)(MAN_ARGS);
53: int (*post)(MAN_ARGS);
54: };
55:
1.93 ! schwarze 56: static void print_bvspace(struct html *,
1.74 kristaps 57: const struct man_node *);
1.3 kristaps 58: static void print_man(MAN_ARGS);
59: static void print_man_head(MAN_ARGS);
1.4 kristaps 60: static void print_man_nodelist(MAN_ARGS);
61: static void print_man_node(MAN_ARGS);
1.7 kristaps 62: static int a2width(const struct man_node *,
63: struct roffsu *);
1.8 kristaps 64: static int man_B_pre(MAN_ARGS);
1.6 kristaps 65: static int man_HP_pre(MAN_ARGS);
1.86 kristaps 66: static int man_IP_pre(MAN_ARGS);
1.8 kristaps 67: static int man_I_pre(MAN_ARGS);
1.86 kristaps 68: static int man_OP_pre(MAN_ARGS);
1.4 kristaps 69: static int man_PP_pre(MAN_ARGS);
1.9 kristaps 70: static int man_RS_pre(MAN_ARGS);
1.4 kristaps 71: static int man_SH_pre(MAN_ARGS);
1.8 kristaps 72: static int man_SM_pre(MAN_ARGS);
1.4 kristaps 73: static int man_SS_pre(MAN_ARGS);
1.90 schwarze 74: static int man_UR_pre(MAN_ARGS);
1.86 kristaps 75: static int man_alt_pre(MAN_ARGS);
76: static int man_br_pre(MAN_ARGS);
77: static int man_ign_pre(MAN_ARGS);
78: static int man_in_pre(MAN_ARGS);
79: static int man_literal_pre(MAN_ARGS);
80: static void man_root_post(MAN_ARGS);
81: static void man_root_pre(MAN_ARGS);
1.4 kristaps 82:
1.3 kristaps 83: static const struct htmlman mans[MAN_MAX] = {
1.4 kristaps 84: { man_br_pre, NULL }, /* br */
1.3 kristaps 85: { NULL, NULL }, /* TH */
1.4 kristaps 86: { man_SH_pre, NULL }, /* SH */
87: { man_SS_pre, NULL }, /* SS */
1.6 kristaps 88: { man_IP_pre, NULL }, /* TP */
1.4 kristaps 89: { man_PP_pre, NULL }, /* LP */
90: { man_PP_pre, NULL }, /* PP */
91: { man_PP_pre, NULL }, /* P */
1.5 kristaps 92: { man_IP_pre, NULL }, /* IP */
1.93 ! schwarze 93: { man_HP_pre, NULL }, /* HP */
1.8 kristaps 94: { man_SM_pre, NULL }, /* SM */
1.56 kristaps 95: { man_SM_pre, NULL }, /* SB */
1.8 kristaps 96: { man_alt_pre, NULL }, /* BI */
97: { man_alt_pre, NULL }, /* IB */
98: { man_alt_pre, NULL }, /* BR */
99: { man_alt_pre, NULL }, /* RB */
1.3 kristaps 100: { NULL, NULL }, /* R */
1.8 kristaps 101: { man_B_pre, NULL }, /* B */
102: { man_I_pre, NULL }, /* I */
103: { man_alt_pre, NULL }, /* IR */
104: { man_alt_pre, NULL }, /* RI */
1.67 schwarze 105: { man_ign_pre, NULL }, /* na */
1.4 kristaps 106: { man_br_pre, NULL }, /* sp */
1.45 kristaps 107: { man_literal_pre, NULL }, /* nf */
108: { man_literal_pre, NULL }, /* fi */
1.3 kristaps 109: { NULL, NULL }, /* RE */
1.9 kristaps 110: { man_RS_pre, NULL }, /* RS */
1.8 kristaps 111: { man_ign_pre, NULL }, /* DT */
112: { man_ign_pre, NULL }, /* UC */
1.13 kristaps 113: { man_ign_pre, NULL }, /* PD */
1.34 joerg 114: { man_ign_pre, NULL }, /* AT */
1.45 kristaps 115: { man_in_pre, NULL }, /* in */
1.51 kristaps 116: { man_ign_pre, NULL }, /* ft */
1.86 kristaps 117: { man_OP_pre, NULL }, /* OP */
1.88 schwarze 118: { man_literal_pre, NULL }, /* EX */
119: { man_literal_pre, NULL }, /* EE */
1.90 schwarze 120: { man_UR_pre, NULL }, /* UR */
121: { NULL, NULL }, /* UE */
1.92 schwarze 122: { man_ign_pre, NULL }, /* ll */
1.3 kristaps 123: };
124:
1.93 ! schwarze 125:
1.74 kristaps 126: /*
127: * Printing leading vertical space before a block.
128: * This is used for the paragraph macros.
129: * The rules are pretty simple, since there's very little nesting going
130: * on here. Basically, if we're the first within another block (SS/SH),
131: * then don't emit vertical space. If we are (RS), then do. If not the
132: * first, print it.
133: */
134: static void
135: print_bvspace(struct html *h, const struct man_node *n)
136: {
137:
138: if (n->body && n->body->child)
139: if (MAN_TBL == n->body->child->type)
140: return;
141:
142: if (MAN_ROOT == n->parent->type || MAN_RS != n->parent->tok)
143: if (NULL == n->prev)
144: return;
145:
146: print_otag(h, TAG_P, 0, NULL);
147: }
1.1 kristaps 148:
149: void
1.89 schwarze 150: html_man(void *arg, const struct man *man)
1.1 kristaps 151: {
1.45 kristaps 152: struct mhtml mh;
1.3 kristaps 153:
1.45 kristaps 154: memset(&mh, 0, sizeof(struct mhtml));
1.89 schwarze 155: print_man(man_meta(man), man_node(man), &mh, (struct html *)arg);
1.82 kristaps 156: putchar('\n');
1.3 kristaps 157: }
158:
159: static void
1.93 ! schwarze 160: print_man(MAN_ARGS)
1.3 kristaps 161: {
1.82 kristaps 162: struct tag *t, *tt;
163: struct htmlpair tag;
164:
165: PAIR_CLASS_INIT(&tag, "mandoc");
1.3 kristaps 166:
1.82 kristaps 167: if ( ! (HTML_FRAGMENT & h->oflags)) {
168: print_gen_decls(h);
169: t = print_otag(h, TAG_HTML, 0, NULL);
170: tt = print_otag(h, TAG_HEAD, 0, NULL);
1.89 schwarze 171: print_man_head(man, n, mh, h);
1.82 kristaps 172: print_tagq(h, tt);
173: print_otag(h, TAG_BODY, 0, NULL);
174: print_otag(h, TAG_DIV, 1, &tag);
1.93 ! schwarze 175: } else
1.82 kristaps 176: t = print_otag(h, TAG_DIV, 1, &tag);
1.53 kristaps 177:
1.89 schwarze 178: print_man_nodelist(man, n, mh, h);
1.3 kristaps 179: print_tagq(h, t);
180: }
181:
182: static void
183: print_man_head(MAN_ARGS)
184: {
185:
186: print_gen_head(h);
1.89 schwarze 187: assert(man->title);
188: assert(man->msec);
189: bufcat_fmt(h, "%s(%s)", man->title, man->msec);
1.3 kristaps 190: print_otag(h, TAG_TITLE, 0, NULL);
191: print_text(h, h->buf);
1.1 kristaps 192: }
1.4 kristaps 193:
194: static void
195: print_man_nodelist(MAN_ARGS)
196: {
197:
1.89 schwarze 198: print_man_node(man, n, mh, h);
1.4 kristaps 199: if (n->next)
1.89 schwarze 200: print_man_nodelist(man, n->next, mh, h);
1.4 kristaps 201: }
202:
203: static void
204: print_man_node(MAN_ARGS)
205: {
206: int child;
207: struct tag *t;
208:
209: child = 1;
1.14 kristaps 210: t = h->tags.head;
1.4 kristaps 211:
212: switch (n->type) {
1.93 ! schwarze 213: case MAN_ROOT:
1.89 schwarze 214: man_root_pre(man, n, mh, h);
1.4 kristaps 215: break;
1.93 ! schwarze 216: case MAN_TEXT:
1.65 kristaps 217: /*
218: * If we have a blank line, output a vertical space.
219: * If we have a space as the first character, break
220: * before printing the line's data.
221: */
1.63 kristaps 222: if ('\0' == *n->string) {
223: print_otag(h, TAG_P, 0, NULL);
224: return;
1.78 kristaps 225: }
226:
227: if (' ' == *n->string && MAN_LINE & n->flags)
228: print_otag(h, TAG_BR, 0, NULL);
229: else if (MANH_LITERAL & mh->fl && n->prev)
1.63 kristaps 230: print_otag(h, TAG_BR, 0, NULL);
231:
1.4 kristaps 232: print_text(h, n->string);
1.68 kristaps 233: return;
1.93 ! schwarze 234: case MAN_EQN:
1.80 kristaps 235: print_eqn(h, n->eqn);
1.69 kristaps 236: break;
1.93 ! schwarze 237: case MAN_TBL:
1.66 kristaps 238: /*
239: * This will take care of initialising all of the table
240: * state data for the first table, then tearing it down
241: * for the last one.
242: */
1.60 kristaps 243: print_tbl(h, n->span);
1.64 kristaps 244: return;
1.4 kristaps 245: default:
1.93 ! schwarze 246: /*
1.21 kristaps 247: * Close out scope of font prior to opening a macro
1.66 kristaps 248: * scope.
1.21 kristaps 249: */
1.57 kristaps 250: if (HTMLFONT_NONE != h->metac) {
251: h->metal = h->metac;
252: h->metac = HTMLFONT_NONE;
1.66 kristaps 253: }
254:
255: /*
256: * Close out the current table, if it's open, and unset
257: * the "meta" table state. This will be reopened on the
258: * next table element.
259: */
260: if (h->tblt) {
261: print_tblclose(h);
262: t = h->tags.head;
1.20 kristaps 263: }
1.4 kristaps 264: if (mans[n->tok].pre)
1.89 schwarze 265: child = (*mans[n->tok].pre)(man, n, mh, h);
1.4 kristaps 266: break;
267: }
268:
1.21 kristaps 269: if (child && n->child)
1.89 schwarze 270: print_man_nodelist(man, n->child, mh, h);
1.21 kristaps 271:
1.24 kristaps 272: /* This will automatically close out any font scope. */
1.4 kristaps 273: print_stagq(h, t);
274:
1.61 kristaps 275: switch (n->type) {
1.93 ! schwarze 276: case MAN_ROOT:
1.89 schwarze 277: man_root_post(man, n, mh, h);
1.69 kristaps 278: break;
1.93 ! schwarze 279: case MAN_EQN:
1.61 kristaps 280: break;
281: default:
282: if (mans[n->tok].post)
1.89 schwarze 283: (*mans[n->tok].post)(man, n, mh, h);
1.61 kristaps 284: break;
285: }
1.4 kristaps 286: }
287:
1.5 kristaps 288: static int
1.7 kristaps 289: a2width(const struct man_node *n, struct roffsu *su)
1.5 kristaps 290: {
291:
1.6 kristaps 292: if (MAN_TEXT != n->type)
1.7 kristaps 293: return(0);
1.11 kristaps 294: if (a2roffsu(n->string, su, SCALE_BU))
1.7 kristaps 295: return(1);
1.5 kristaps 296:
1.7 kristaps 297: return(0);
1.5 kristaps 298: }
299:
1.65 kristaps 300: static void
1.4 kristaps 301: man_root_pre(MAN_ARGS)
302: {
1.56 kristaps 303: struct htmlpair tag[3];
1.4 kristaps 304: struct tag *t, *tt;
305: char b[BUFSIZ], title[BUFSIZ];
306:
307: b[0] = 0;
1.89 schwarze 308: if (man->vol)
309: (void)strlcat(b, man->vol, BUFSIZ);
1.4 kristaps 310:
1.89 schwarze 311: assert(man->title);
312: assert(man->msec);
313: snprintf(title, BUFSIZ - 1, "%s(%s)", man->title, man->msec);
1.4 kristaps 314:
1.56 kristaps 315: PAIR_SUMMARY_INIT(&tag[0], "Document Header");
316: PAIR_CLASS_INIT(&tag[1], "head");
1.83 schwarze 317: PAIR_INIT(&tag[2], ATTR_WIDTH, "100%");
318: t = print_otag(h, TAG_TABLE, 3, tag);
319: PAIR_INIT(&tag[0], ATTR_WIDTH, "30%");
320: print_otag(h, TAG_COL, 1, tag);
321: print_otag(h, TAG_COL, 1, tag);
322: print_otag(h, TAG_COL, 1, tag);
1.56 kristaps 323:
324: print_otag(h, TAG_TBODY, 0, NULL);
1.15 kristaps 325:
1.4 kristaps 326: tt = print_otag(h, TAG_TR, 0, NULL);
327:
1.55 kristaps 328: PAIR_CLASS_INIT(&tag[0], "head-ltitle");
1.4 kristaps 329: print_otag(h, TAG_TD, 1, tag);
330: print_text(h, title);
331: print_stagq(h, tt);
332:
1.55 kristaps 333: PAIR_CLASS_INIT(&tag[0], "head-vol");
1.83 schwarze 334: PAIR_INIT(&tag[1], ATTR_ALIGN, "center");
335: print_otag(h, TAG_TD, 2, tag);
1.4 kristaps 336: print_text(h, b);
337: print_stagq(h, tt);
338:
1.55 kristaps 339: PAIR_CLASS_INIT(&tag[0], "head-rtitle");
1.83 schwarze 340: PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
341: print_otag(h, TAG_TD, 2, tag);
1.4 kristaps 342: print_text(h, title);
343: print_tagq(h, t);
344: }
345:
346: static void
347: man_root_post(MAN_ARGS)
348: {
1.56 kristaps 349: struct htmlpair tag[3];
1.4 kristaps 350: struct tag *t, *tt;
351:
1.56 kristaps 352: PAIR_SUMMARY_INIT(&tag[0], "Document Footer");
353: PAIR_CLASS_INIT(&tag[1], "foot");
1.83 schwarze 354: PAIR_INIT(&tag[2], ATTR_WIDTH, "100%");
355: t = print_otag(h, TAG_TABLE, 3, tag);
356: PAIR_INIT(&tag[0], ATTR_WIDTH, "50%");
357: print_otag(h, TAG_COL, 1, tag);
358: print_otag(h, TAG_COL, 1, tag);
1.15 kristaps 359:
1.4 kristaps 360: tt = print_otag(h, TAG_TR, 0, NULL);
361:
1.55 kristaps 362: PAIR_CLASS_INIT(&tag[0], "foot-date");
1.4 kristaps 363: print_otag(h, TAG_TD, 1, tag);
1.55 kristaps 364:
1.89 schwarze 365: assert(man->date);
366: print_text(h, man->date);
1.4 kristaps 367: print_stagq(h, tt);
368:
1.55 kristaps 369: PAIR_CLASS_INIT(&tag[0], "foot-os");
1.83 schwarze 370: PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
371: print_otag(h, TAG_TD, 2, tag);
1.55 kristaps 372:
1.89 schwarze 373: if (man->source)
374: print_text(h, man->source);
1.4 kristaps 375: print_tagq(h, t);
376: }
377:
378:
379: static int
380: man_br_pre(MAN_ARGS)
381: {
1.7 kristaps 382: struct roffsu su;
383: struct htmlpair tag;
1.4 kristaps 384:
1.7 kristaps 385: SCALE_VS_INIT(&su, 1);
386:
1.49 kristaps 387: if (MAN_sp == n->tok) {
1.75 kristaps 388: if (NULL != (n = n->child))
389: if ( ! a2roffsu(n->string, &su, SCALE_VS))
390: SCALE_VS_INIT(&su, atoi(n->string));
1.49 kristaps 391: } else
1.7 kristaps 392: su.scale = 0;
1.4 kristaps 393:
1.72 kristaps 394: bufinit(h);
1.7 kristaps 395: bufcat_su(h, "height", &su);
396: PAIR_STYLE_INIT(&tag, h);
1.4 kristaps 397: print_otag(h, TAG_DIV, 1, &tag);
1.24 kristaps 398:
1.16 kristaps 399: /* So the div isn't empty: */
400: print_text(h, "\\~");
401:
1.7 kristaps 402: return(0);
1.4 kristaps 403: }
404:
405: static int
406: man_SH_pre(MAN_ARGS)
407: {
1.54 kristaps 408: struct htmlpair tag;
1.4 kristaps 409:
1.54 kristaps 410: if (MAN_BLOCK == n->type) {
1.76 kristaps 411: mh->fl &= ~MANH_LITERAL;
1.54 kristaps 412: PAIR_CLASS_INIT(&tag, "section");
413: print_otag(h, TAG_DIV, 1, &tag);
1.4 kristaps 414: return(1);
1.54 kristaps 415: } else if (MAN_BODY == n->type)
1.4 kristaps 416: return(1);
417:
1.54 kristaps 418: print_otag(h, TAG_H1, 0, NULL);
1.4 kristaps 419: return(1);
420: }
421:
422: static int
1.8 kristaps 423: man_alt_pre(MAN_ARGS)
424: {
425: const struct man_node *nn;
1.78 kristaps 426: int i, savelit;
1.57 kristaps 427: enum htmltag fp;
428: struct tag *t;
1.8 kristaps 429:
1.93 ! schwarze 430: if ((savelit = mh->fl & MANH_LITERAL))
1.78 kristaps 431: print_otag(h, TAG_BR, 0, NULL);
432:
433: mh->fl &= ~MANH_LITERAL;
434:
1.8 kristaps 435: for (i = 0, nn = n->child; nn; nn = nn->next, i++) {
1.57 kristaps 436: t = NULL;
1.8 kristaps 437: switch (n->tok) {
1.93 ! schwarze 438: case MAN_BI:
1.57 kristaps 439: fp = i % 2 ? TAG_I : TAG_B;
1.8 kristaps 440: break;
1.93 ! schwarze 441: case MAN_IB:
1.57 kristaps 442: fp = i % 2 ? TAG_B : TAG_I;
1.8 kristaps 443: break;
1.93 ! schwarze 444: case MAN_RI:
1.57 kristaps 445: fp = i % 2 ? TAG_I : TAG_MAX;
1.8 kristaps 446: break;
1.93 ! schwarze 447: case MAN_IR:
1.57 kristaps 448: fp = i % 2 ? TAG_MAX : TAG_I;
1.8 kristaps 449: break;
1.93 ! schwarze 450: case MAN_BR:
1.57 kristaps 451: fp = i % 2 ? TAG_MAX : TAG_B;
1.8 kristaps 452: break;
1.93 ! schwarze 453: case MAN_RB:
1.57 kristaps 454: fp = i % 2 ? TAG_B : TAG_MAX;
1.8 kristaps 455: break;
456: default:
457: abort();
458: /* NOTREACHED */
459: }
460:
461: if (i)
462: h->flags |= HTML_NOSPACE;
463:
1.57 kristaps 464: if (TAG_MAX != fp)
465: t = print_otag(h, fp, 0, NULL);
466:
1.89 schwarze 467: print_man_node(man, nn, mh, h);
1.57 kristaps 468:
469: if (t)
470: print_tagq(h, t);
1.8 kristaps 471: }
472:
1.78 kristaps 473: if (savelit)
474: mh->fl |= MANH_LITERAL;
475:
1.8 kristaps 476: return(0);
477: }
478:
479: static int
1.56 kristaps 480: man_SM_pre(MAN_ARGS)
1.8 kristaps 481: {
1.93 ! schwarze 482:
1.57 kristaps 483: print_otag(h, TAG_SMALL, 0, NULL);
1.56 kristaps 484: if (MAN_SB == n->tok)
1.57 kristaps 485: print_otag(h, TAG_B, 0, NULL);
1.8 kristaps 486: return(1);
487: }
488:
489: static int
1.4 kristaps 490: man_SS_pre(MAN_ARGS)
491: {
1.54 kristaps 492: struct htmlpair tag;
1.4 kristaps 493:
1.54 kristaps 494: if (MAN_BLOCK == n->type) {
1.76 kristaps 495: mh->fl &= ~MANH_LITERAL;
1.54 kristaps 496: PAIR_CLASS_INIT(&tag, "subsection");
497: print_otag(h, TAG_DIV, 1, &tag);
1.4 kristaps 498: return(1);
1.54 kristaps 499: } else if (MAN_BODY == n->type)
1.4 kristaps 500: return(1);
501:
1.54 kristaps 502: print_otag(h, TAG_H2, 0, NULL);
1.4 kristaps 503: return(1);
504: }
505:
506: static int
507: man_PP_pre(MAN_ARGS)
508: {
509:
1.47 kristaps 510: if (MAN_HEAD == n->type)
511: return(0);
1.74 kristaps 512: else if (MAN_BLOCK == n->type)
513: print_bvspace(h, n);
1.47 kristaps 514:
1.5 kristaps 515: return(1);
516: }
517:
518: static int
519: man_IP_pre(MAN_ARGS)
520: {
521: const struct man_node *nn;
522:
1.93 ! schwarze 523: if (MAN_BODY == n->type) {
1.77 kristaps 524: print_otag(h, TAG_DD, 0, NULL);
525: return(1);
526: } else if (MAN_HEAD != n->type) {
527: print_otag(h, TAG_DL, 0, NULL);
1.6 kristaps 528: return(1);
529: }
530:
1.78 kristaps 531: /* FIXME: width specification. */
532:
1.77 kristaps 533: print_otag(h, TAG_DT, 0, NULL);
1.6 kristaps 534:
1.59 schwarze 535: /* For IP, only print the first header element. */
1.7 kristaps 536:
1.59 schwarze 537: if (MAN_IP == n->tok && n->child)
1.89 schwarze 538: print_man_node(man, n->child, mh, h);
1.27 kristaps 539:
1.59 schwarze 540: /* For TP, only print next-line header elements. */
1.6 kristaps 541:
1.91 schwarze 542: if (MAN_TP == n->tok) {
543: nn = n->child;
544: while (NULL != nn && 0 == (MAN_LINE & nn->flags))
545: nn = nn->next;
546: while (NULL != nn) {
547: print_man_node(man, nn, mh, h);
548: nn = nn->next;
549: }
550: }
1.6 kristaps 551:
552: return(0);
553: }
554:
555: static int
556: man_HP_pre(MAN_ARGS)
557: {
1.56 kristaps 558: struct htmlpair tag;
559: struct roffsu su;
560: const struct man_node *np;
1.6 kristaps 561:
1.77 kristaps 562: if (MAN_HEAD == n->type)
563: return(0);
564: else if (MAN_BLOCK != n->type)
565: return(1);
1.72 kristaps 566:
1.77 kristaps 567: np = n->head->child;
1.6 kristaps 568:
1.56 kristaps 569: if (NULL == np || ! a2width(np, &su))
570: SCALE_HS_INIT(&su, INDENT);
1.6 kristaps 571:
1.77 kristaps 572: bufinit(h);
1.5 kristaps 573:
1.77 kristaps 574: print_bvspace(h, n);
575: bufcat_su(h, "margin-left", &su);
1.56 kristaps 576: su.scale = -su.scale;
1.7 kristaps 577: bufcat_su(h, "text-indent", &su);
578: PAIR_STYLE_INIT(&tag, h);
1.77 kristaps 579: print_otag(h, TAG_P, 1, &tag);
1.4 kristaps 580: return(1);
581: }
1.86 kristaps 582:
583: static int
584: man_OP_pre(MAN_ARGS)
585: {
586: struct tag *tt;
587: struct htmlpair tag;
588:
589: print_text(h, "[");
590: h->flags |= HTML_NOSPACE;
591: PAIR_CLASS_INIT(&tag, "opt");
592: tt = print_otag(h, TAG_SPAN, 1, &tag);
593:
594: if (NULL != (n = n->child)) {
595: print_otag(h, TAG_B, 0, NULL);
596: print_text(h, n->string);
597: }
598:
599: print_stagq(h, tt);
600:
601: if (NULL != n && NULL != n->next) {
602: print_otag(h, TAG_I, 0, NULL);
603: print_text(h, n->next->string);
604: }
605:
606: print_stagq(h, tt);
607: h->flags |= HTML_NOSPACE;
608: print_text(h, "]");
609: return(0);
610: }
611:
1.8 kristaps 612: static int
613: man_B_pre(MAN_ARGS)
614: {
615:
1.57 kristaps 616: print_otag(h, TAG_B, 0, NULL);
1.8 kristaps 617: return(1);
618: }
619:
620: static int
621: man_I_pre(MAN_ARGS)
622: {
1.93 ! schwarze 623:
1.57 kristaps 624: print_otag(h, TAG_I, 0, NULL);
1.8 kristaps 625: return(1);
1.45 kristaps 626: }
627:
628: static int
629: man_literal_pre(MAN_ARGS)
630: {
631:
1.88 schwarze 632: if (MAN_fi == n->tok || MAN_EE == n->tok) {
1.45 kristaps 633: print_otag(h, TAG_BR, 0, NULL);
1.78 kristaps 634: mh->fl &= ~MANH_LITERAL;
635: } else
1.45 kristaps 636: mh->fl |= MANH_LITERAL;
637:
1.67 schwarze 638: return(0);
1.45 kristaps 639: }
640:
641: static int
642: man_in_pre(MAN_ARGS)
643: {
644:
645: print_otag(h, TAG_BR, 0, NULL);
646: return(0);
1.8 kristaps 647: }
648:
649: static int
650: man_ign_pre(MAN_ARGS)
651: {
652:
653: return(0);
654: }
1.9 kristaps 655:
656: static int
657: man_RS_pre(MAN_ARGS)
658: {
659: struct htmlpair tag;
660: struct roffsu su;
661:
662: if (MAN_HEAD == n->type)
663: return(0);
664: else if (MAN_BODY == n->type)
665: return(1);
666:
667: SCALE_HS_INIT(&su, INDENT);
1.56 kristaps 668: if (n->head->child)
1.9 kristaps 669: a2width(n->head->child, &su);
670:
1.72 kristaps 671: bufinit(h);
1.56 kristaps 672: bufcat_su(h, "margin-left", &su);
1.9 kristaps 673: PAIR_STYLE_INIT(&tag, h);
674: print_otag(h, TAG_DIV, 1, &tag);
675: return(1);
1.90 schwarze 676: }
677:
678: static int
679: man_UR_pre(MAN_ARGS)
680: {
681: struct htmlpair tag[2];
682:
683: n = n->child;
684: assert(MAN_HEAD == n->type);
685: if (n->nchild) {
686: assert(MAN_TEXT == n->child->type);
687: PAIR_CLASS_INIT(&tag[0], "link-ext");
688: PAIR_HREF_INIT(&tag[1], n->child->string);
689: print_otag(h, TAG_A, 2, tag);
690: }
691:
692: assert(MAN_BODY == n->next->type);
693: if (n->next->nchild)
694: n = n->next;
695:
696: print_man_nodelist(man, n->child, mh, h);
697:
698: return(0);
1.9 kristaps 699: }
CVSweb