Annotation of mandoc/man_html.c, Revision 1.144
1.144 ! schwarze 1: /* $Id: man_html.c,v 1.143 2017/06/08 12:54:58 schwarze Exp $ */
1.1 kristaps 2: /*
1.104 kristaps 3: * Copyright (c) 2008-2012, 2014 Kristaps Dzonsons <kristaps@bsd.lv>
1.122 schwarze 4: * Copyright (c) 2013, 2014, 2015, 2017 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: *
1.113 schwarze 10: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
1.1 kristaps 11: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
1.113 schwarze 12: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
1.1 kristaps 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: #include "config.h"
19:
1.1 kristaps 20: #include <sys/types.h>
21:
1.5 kristaps 22: #include <assert.h>
23: #include <ctype.h>
1.2 kristaps 24: #include <stdio.h>
1.1 kristaps 25: #include <stdlib.h>
1.4 kristaps 26: #include <string.h>
1.1 kristaps 27:
1.94 schwarze 28: #include "mandoc_aux.h"
1.144 ! schwarze 29: #include "mandoc.h"
1.113 schwarze 30: #include "roff.h"
1.105 schwarze 31: #include "man.h"
1.7 kristaps 32: #include "out.h"
1.1 kristaps 33: #include "html.h"
1.10 kristaps 34: #include "main.h"
1.1 kristaps 35:
1.13 kristaps 36: /* FIXME: have PD set the default vspace width. */
1.6 kristaps 37:
38: #define INDENT 5
1.4 kristaps 39:
1.115 schwarze 40: #define MAN_ARGS const struct roff_meta *man, \
1.114 schwarze 41: const struct roff_node *n, \
1.3 kristaps 42: struct html *h
43:
44: struct htmlman {
45: int (*pre)(MAN_ARGS);
46: int (*post)(MAN_ARGS);
47: };
48:
1.93 schwarze 49: static void print_bvspace(struct html *,
1.114 schwarze 50: const struct roff_node *);
1.3 kristaps 51: static void print_man_head(MAN_ARGS);
1.4 kristaps 52: static void print_man_nodelist(MAN_ARGS);
53: static void print_man_node(MAN_ARGS);
1.132 schwarze 54: static int fillmode(struct html *, int);
1.114 schwarze 55: static int a2width(const struct roff_node *,
1.7 kristaps 56: struct roffsu *);
1.8 kristaps 57: static int man_B_pre(MAN_ARGS);
1.6 kristaps 58: static int man_HP_pre(MAN_ARGS);
1.86 kristaps 59: static int man_IP_pre(MAN_ARGS);
1.8 kristaps 60: static int man_I_pre(MAN_ARGS);
1.86 kristaps 61: static int man_OP_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.4 kristaps 64: static int man_SH_pre(MAN_ARGS);
1.8 kristaps 65: static int man_SM_pre(MAN_ARGS);
1.4 kristaps 66: static int man_SS_pre(MAN_ARGS);
1.90 schwarze 67: static int man_UR_pre(MAN_ARGS);
1.86 kristaps 68: static int man_alt_pre(MAN_ARGS);
69: static int man_ign_pre(MAN_ARGS);
70: static int man_in_pre(MAN_ARGS);
71: static void man_root_post(MAN_ARGS);
72: static void man_root_pre(MAN_ARGS);
1.4 kristaps 73:
1.136 schwarze 74: static const struct htmlman __mans[MAN_MAX - MAN_TH] = {
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.93 schwarze 83: { man_HP_pre, NULL }, /* HP */
1.8 kristaps 84: { man_SM_pre, NULL }, /* SM */
1.56 kristaps 85: { man_SM_pre, NULL }, /* SB */
1.8 kristaps 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.132 schwarze 95: { NULL, NULL }, /* nf */
96: { NULL, NULL }, /* fi */
1.3 kristaps 97: { NULL, NULL }, /* RE */
1.9 kristaps 98: { man_RS_pre, NULL }, /* RS */
1.8 kristaps 99: { man_ign_pre, NULL }, /* DT */
100: { man_ign_pre, NULL }, /* UC */
1.13 kristaps 101: { man_ign_pre, NULL }, /* PD */
1.34 joerg 102: { man_ign_pre, NULL }, /* AT */
1.45 kristaps 103: { man_in_pre, NULL }, /* in */
1.86 kristaps 104: { man_OP_pre, NULL }, /* OP */
1.132 schwarze 105: { NULL, NULL }, /* EX */
106: { NULL, NULL }, /* EE */
1.90 schwarze 107: { man_UR_pre, NULL }, /* UR */
108: { NULL, NULL }, /* UE */
1.3 kristaps 109: };
1.136 schwarze 110: static const struct htmlman *const mans = __mans - MAN_TH;
1.3 kristaps 111:
1.93 schwarze 112:
1.74 kristaps 113: /*
114: * Printing leading vertical space before a block.
115: * This is used for the paragraph macros.
116: * The rules are pretty simple, since there's very little nesting going
117: * on here. Basically, if we're the first within another block (SS/SH),
118: * then don't emit vertical space. If we are (RS), then do. If not the
119: * first, print it.
120: */
121: static void
1.114 schwarze 122: print_bvspace(struct html *h, const struct roff_node *n)
1.74 kristaps 123: {
124:
125: if (n->body && n->body->child)
1.113 schwarze 126: if (n->body->child->type == ROFFT_TBL)
1.74 kristaps 127: return;
128:
1.113 schwarze 129: if (n->parent->type == ROFFT_ROOT || n->parent->tok != MAN_RS)
1.74 kristaps 130: if (NULL == n->prev)
131: return;
132:
1.103 kristaps 133: print_paragraph(h);
1.74 kristaps 134: }
1.1 kristaps 135:
136: void
1.116 schwarze 137: html_man(void *arg, const struct roff_man *man)
1.1 kristaps 138: {
1.117 schwarze 139: struct html *h;
1.126 schwarze 140: struct tag *t;
1.82 kristaps 141:
1.117 schwarze 142: h = (struct html *)arg;
1.3 kristaps 143:
1.126 schwarze 144: if ((h->oflags & HTML_FRAGMENT) == 0) {
1.82 kristaps 145: print_gen_decls(h);
1.126 schwarze 146: print_otag(h, TAG_HTML, "");
147: t = print_otag(h, TAG_HEAD, "");
1.132 schwarze 148: print_man_head(&man->meta, man->first, h);
1.126 schwarze 149: print_tagq(h, t);
1.122 schwarze 150: print_otag(h, TAG_BODY, "");
1.126 schwarze 151: }
1.53 kristaps 152:
1.132 schwarze 153: man_root_pre(&man->meta, man->first, h);
1.127 schwarze 154: t = print_otag(h, TAG_DIV, "c", "manual-text");
1.132 schwarze 155: print_man_nodelist(&man->meta, man->first->child, h);
1.127 schwarze 156: print_tagq(h, t);
1.132 schwarze 157: man_root_post(&man->meta, man->first, h);
1.126 schwarze 158: print_tagq(h, NULL);
1.3 kristaps 159: }
160:
161: static void
162: print_man_head(MAN_ARGS)
163: {
1.123 schwarze 164: char *cp;
1.3 kristaps 165:
166: print_gen_head(h);
1.123 schwarze 167: mandoc_asprintf(&cp, "%s(%s)", man->title, man->msec);
1.122 schwarze 168: print_otag(h, TAG_TITLE, "");
1.123 schwarze 169: print_text(h, cp);
170: free(cp);
1.1 kristaps 171: }
1.4 kristaps 172:
173: static void
174: print_man_nodelist(MAN_ARGS)
175: {
176:
1.110 schwarze 177: while (n != NULL) {
1.132 schwarze 178: print_man_node(man, n, h);
1.110 schwarze 179: n = n->next;
180: }
1.4 kristaps 181: }
182:
183: static void
184: print_man_node(MAN_ARGS)
185: {
1.132 schwarze 186: static int want_fillmode = MAN_fi;
187: static int save_fillmode;
188:
189: struct tag *t;
1.4 kristaps 190: int child;
191:
1.132 schwarze 192: /*
193: * Handle fill mode switch requests up front,
194: * they would just cause trouble in the subsequent code.
195: */
196:
197: switch (n->tok) {
198: case MAN_nf:
199: case MAN_EX:
200: want_fillmode = MAN_nf;
201: return;
202: case MAN_fi:
203: case MAN_EE:
204: want_fillmode = MAN_fi;
205: if (fillmode(h, 0) == MAN_fi)
206: print_otag(h, TAG_BR, "");
207: return;
208: default:
209: break;
210: }
211:
212: /* Set up fill mode for the upcoming node. */
1.4 kristaps 213:
214: switch (n->type) {
1.132 schwarze 215: case ROFFT_BLOCK:
216: save_fillmode = 0;
217: /* Some block macros suspend or cancel .nf. */
218: switch (n->tok) {
219: case MAN_TP: /* Tagged paragraphs */
220: case MAN_IP: /* temporarily disable .nf */
221: case MAN_HP: /* for the head. */
222: save_fillmode = want_fillmode;
223: /* FALLTHROUGH */
224: case MAN_SH: /* Section headers */
225: case MAN_SS: /* permanently cancel .nf. */
226: want_fillmode = MAN_fi;
227: /* FALLTHROUGH */
228: case MAN_PP: /* These have no head. */
229: case MAN_LP: /* They will simply */
230: case MAN_P: /* reopen .nf in the body. */
231: case MAN_RS:
232: case MAN_UR:
233: fillmode(h, MAN_fi);
234: break;
235: default:
236: break;
237: }
238: break;
239: case ROFFT_TBL:
240: fillmode(h, MAN_fi);
241: break;
242: case ROFFT_ELEM:
243: /*
244: * Some in-line macros produce tags and/or text
245: * in the handler, so they require fill mode to be
246: * configured up front just like for text nodes.
247: * For the others, keep the traditional approach
248: * of doing the same, for now.
249: */
250: fillmode(h, want_fillmode);
251: break;
1.113 schwarze 252: case ROFFT_TEXT:
1.132 schwarze 253: if (fillmode(h, want_fillmode) == MAN_fi &&
254: want_fillmode == MAN_fi &&
1.142 schwarze 255: n->flags & NODE_LINE && *n->string == ' ' &&
256: (h->flags & HTML_NONEWLINE) == 0)
1.122 schwarze 257: print_otag(h, TAG_BR, "");
1.132 schwarze 258: if (*n->string != '\0')
259: break;
260: print_paragraph(h);
261: return;
262: default:
263: break;
264: }
265:
266: /* Produce output for this node. */
267:
268: child = 1;
269: switch (n->type) {
270: case ROFFT_TEXT:
271: t = h->tag;
1.4 kristaps 272: print_text(h, n->string);
1.130 schwarze 273: break;
1.113 schwarze 274: case ROFFT_EQN:
1.132 schwarze 275: t = h->tag;
1.80 kristaps 276: print_eqn(h, n->eqn);
1.69 kristaps 277: break;
1.113 schwarze 278: case ROFFT_TBL:
1.66 kristaps 279: /*
280: * This will take care of initialising all of the table
281: * state data for the first table, then tearing it down
282: * for the last one.
283: */
1.60 kristaps 284: print_tbl(h, n->span);
1.64 kristaps 285: return;
1.4 kristaps 286: default:
1.93 schwarze 287: /*
1.21 kristaps 288: * Close out scope of font prior to opening a macro
1.66 kristaps 289: * scope.
1.21 kristaps 290: */
1.57 kristaps 291: if (HTMLFONT_NONE != h->metac) {
292: h->metal = h->metac;
293: h->metac = HTMLFONT_NONE;
1.66 kristaps 294: }
295:
296: /*
297: * Close out the current table, if it's open, and unset
298: * the "meta" table state. This will be reopened on the
299: * next table element.
300: */
1.132 schwarze 301: if (h->tblt)
1.66 kristaps 302: print_tblclose(h);
1.132 schwarze 303:
304: t = h->tag;
1.137 schwarze 305: if (n->tok < ROFF_MAX) {
1.138 schwarze 306: roff_html_pre(h, n);
1.141 schwarze 307: child = 0;
1.137 schwarze 308: break;
309: }
310:
311: assert(n->tok >= MAN_TH && n->tok < MAN_MAX);
1.4 kristaps 312: if (mans[n->tok].pre)
1.132 schwarze 313: child = (*mans[n->tok].pre)(man, n, h);
314:
315: /* Some block macros resume .nf in the body. */
316: if (save_fillmode && n->type == ROFFT_BODY)
317: want_fillmode = save_fillmode;
318:
1.4 kristaps 319: break;
320: }
321:
1.21 kristaps 322: if (child && n->child)
1.132 schwarze 323: print_man_nodelist(man, n->child, h);
1.21 kristaps 324:
1.24 kristaps 325: /* This will automatically close out any font scope. */
1.132 schwarze 326: print_stagq(h, t);
327:
328: if (fillmode(h, 0) == MAN_nf &&
329: n->next != NULL && n->next->flags & NODE_LINE)
330: print_endline(h);
331: }
332:
333: /*
334: * MAN_nf switches to no-fill mode, MAN_fi to fill mode.
335: * Other arguments do not switch.
336: * The old mode is returned.
337: */
338: static int
339: fillmode(struct html *h, int want)
340: {
341: struct tag *pre;
342: int had;
1.4 kristaps 343:
1.132 schwarze 344: for (pre = h->tag; pre != NULL; pre = pre->next)
345: if (pre->tag == TAG_PRE)
346: break;
347:
348: had = pre == NULL ? MAN_fi : MAN_nf;
1.130 schwarze 349:
1.132 schwarze 350: if (want && want != had) {
351: if (want == MAN_nf)
352: print_otag(h, TAG_PRE, "");
353: else
354: print_tagq(h, pre);
355: }
356: return had;
1.4 kristaps 357: }
358:
1.5 kristaps 359: static int
1.114 schwarze 360: a2width(const struct roff_node *n, struct roffsu *su)
1.5 kristaps 361: {
1.113 schwarze 362: if (n->type != ROFFT_TEXT)
1.119 schwarze 363: return 0;
1.143 schwarze 364: return a2roffsu(n->string, su, SCALE_EN) != NULL;
1.5 kristaps 365: }
366:
1.65 kristaps 367: static void
1.4 kristaps 368: man_root_pre(MAN_ARGS)
369: {
370: struct tag *t, *tt;
1.94 schwarze 371: char *title;
1.4 kristaps 372:
1.89 schwarze 373: assert(man->title);
374: assert(man->msec);
1.94 schwarze 375: mandoc_asprintf(&title, "%s(%s)", man->title, man->msec);
1.4 kristaps 376:
1.122 schwarze 377: t = print_otag(h, TAG_TABLE, "c", "head");
378: tt = print_otag(h, TAG_TR, "");
1.4 kristaps 379:
1.122 schwarze 380: print_otag(h, TAG_TD, "c", "head-ltitle");
1.4 kristaps 381: print_text(h, title);
382: print_stagq(h, tt);
383:
1.122 schwarze 384: print_otag(h, TAG_TD, "c", "head-vol");
1.95 schwarze 385: if (NULL != man->vol)
386: print_text(h, man->vol);
1.4 kristaps 387: print_stagq(h, tt);
388:
1.122 schwarze 389: print_otag(h, TAG_TD, "c", "head-rtitle");
1.4 kristaps 390: print_text(h, title);
391: print_tagq(h, t);
1.94 schwarze 392: free(title);
1.4 kristaps 393: }
394:
395: static void
396: man_root_post(MAN_ARGS)
397: {
398: struct tag *t, *tt;
399:
1.122 schwarze 400: t = print_otag(h, TAG_TABLE, "c", "foot");
401: tt = print_otag(h, TAG_TR, "");
1.55 kristaps 402:
1.122 schwarze 403: print_otag(h, TAG_TD, "c", "foot-date");
1.89 schwarze 404: print_text(h, man->date);
1.4 kristaps 405: print_stagq(h, tt);
406:
1.122 schwarze 407: print_otag(h, TAG_TD, "c", "foot-os");
1.115 schwarze 408: if (man->os)
409: print_text(h, man->os);
1.4 kristaps 410: print_tagq(h, t);
411: }
412:
413: static int
414: man_SH_pre(MAN_ARGS)
415: {
1.134 schwarze 416: char *id;
417:
418: if (n->type == ROFFT_HEAD) {
419: id = html_make_id(n);
420: print_otag(h, TAG_H1, "cTi", "Sh", id);
1.135 schwarze 421: if (id != NULL)
422: print_otag(h, TAG_A, "chR", "selflink", id);
1.134 schwarze 423: free(id);
424: }
1.119 schwarze 425: return 1;
1.4 kristaps 426: }
427:
428: static int
1.8 kristaps 429: man_alt_pre(MAN_ARGS)
430: {
1.114 schwarze 431: const struct roff_node *nn;
1.130 schwarze 432: int i;
1.57 kristaps 433: enum htmltag fp;
434: struct tag *t;
1.8 kristaps 435:
436: for (i = 0, nn = n->child; nn; nn = nn->next, i++) {
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: }
459:
460: if (i)
461: h->flags |= HTML_NOSPACE;
462:
1.130 schwarze 463: if (fp != TAG_MAX)
1.122 schwarze 464: t = print_otag(h, fp, "");
1.57 kristaps 465:
1.130 schwarze 466: print_text(h, nn->string);
1.57 kristaps 467:
1.130 schwarze 468: if (fp != TAG_MAX)
1.57 kristaps 469: print_tagq(h, t);
1.8 kristaps 470: }
1.119 schwarze 471: return 0;
1.8 kristaps 472: }
473:
474: static int
1.56 kristaps 475: man_SM_pre(MAN_ARGS)
1.8 kristaps 476: {
1.122 schwarze 477: print_otag(h, TAG_SMALL, "");
1.56 kristaps 478: if (MAN_SB == n->tok)
1.122 schwarze 479: print_otag(h, TAG_B, "");
1.119 schwarze 480: return 1;
1.8 kristaps 481: }
482:
483: static int
1.4 kristaps 484: man_SS_pre(MAN_ARGS)
485: {
1.134 schwarze 486: char *id;
487:
488: if (n->type == ROFFT_HEAD) {
489: id = html_make_id(n);
490: print_otag(h, TAG_H2, "cTi", "Ss", id);
1.135 schwarze 491: if (id != NULL)
492: print_otag(h, TAG_A, "chR", "selflink", id);
1.134 schwarze 493: free(id);
494: }
1.119 schwarze 495: return 1;
1.4 kristaps 496: }
497:
498: static int
499: man_PP_pre(MAN_ARGS)
500: {
501:
1.113 schwarze 502: if (n->type == ROFFT_HEAD)
1.119 schwarze 503: return 0;
1.113 schwarze 504: else if (n->type == ROFFT_BLOCK)
1.74 kristaps 505: print_bvspace(h, n);
1.47 kristaps 506:
1.119 schwarze 507: return 1;
1.5 kristaps 508: }
509:
510: static int
511: man_IP_pre(MAN_ARGS)
512: {
1.114 schwarze 513: const struct roff_node *nn;
1.5 kristaps 514:
1.113 schwarze 515: if (n->type == ROFFT_BODY) {
1.129 schwarze 516: print_otag(h, TAG_DD, "c", "It-tag");
1.119 schwarze 517: return 1;
1.113 schwarze 518: } else if (n->type != ROFFT_HEAD) {
1.129 schwarze 519: print_otag(h, TAG_DL, "c", "Bl-tag");
1.119 schwarze 520: return 1;
1.6 kristaps 521: }
522:
1.78 kristaps 523: /* FIXME: width specification. */
524:
1.129 schwarze 525: print_otag(h, TAG_DT, "c", "It-tag");
1.6 kristaps 526:
1.59 schwarze 527: /* For IP, only print the first header element. */
1.7 kristaps 528:
1.59 schwarze 529: if (MAN_IP == n->tok && n->child)
1.132 schwarze 530: print_man_node(man, n->child, h);
1.27 kristaps 531:
1.59 schwarze 532: /* For TP, only print next-line header elements. */
1.6 kristaps 533:
1.91 schwarze 534: if (MAN_TP == n->tok) {
535: nn = n->child;
1.121 schwarze 536: while (NULL != nn && 0 == (NODE_LINE & nn->flags))
1.91 schwarze 537: nn = nn->next;
538: while (NULL != nn) {
1.132 schwarze 539: print_man_node(man, nn, h);
1.91 schwarze 540: nn = nn->next;
541: }
542: }
1.6 kristaps 543:
1.119 schwarze 544: return 0;
1.6 kristaps 545: }
546:
547: static int
548: man_HP_pre(MAN_ARGS)
549: {
1.122 schwarze 550: struct roffsu sum, sui;
1.114 schwarze 551: const struct roff_node *np;
1.6 kristaps 552:
1.113 schwarze 553: if (n->type == ROFFT_HEAD)
1.119 schwarze 554: return 0;
1.113 schwarze 555: else if (n->type != ROFFT_BLOCK)
1.119 schwarze 556: return 1;
1.72 kristaps 557:
1.77 kristaps 558: np = n->head->child;
1.6 kristaps 559:
1.122 schwarze 560: if (np == NULL || !a2width(np, &sum))
561: SCALE_HS_INIT(&sum, INDENT);
1.6 kristaps 562:
1.122 schwarze 563: sui.unit = sum.unit;
564: sui.scale = -sum.scale;
1.5 kristaps 565:
1.77 kristaps 566: print_bvspace(h, n);
1.127 schwarze 567: print_otag(h, TAG_DIV, "csului", "Pp", &sum, &sui);
1.119 schwarze 568: return 1;
1.4 kristaps 569: }
1.86 kristaps 570:
571: static int
572: man_OP_pre(MAN_ARGS)
573: {
574: struct tag *tt;
575:
576: print_text(h, "[");
577: h->flags |= HTML_NOSPACE;
1.128 schwarze 578: tt = print_otag(h, TAG_SPAN, "c", "Op");
1.86 kristaps 579:
580: if (NULL != (n = n->child)) {
1.122 schwarze 581: print_otag(h, TAG_B, "");
1.86 kristaps 582: print_text(h, n->string);
583: }
584:
585: print_stagq(h, tt);
586:
587: if (NULL != n && NULL != n->next) {
1.122 schwarze 588: print_otag(h, TAG_I, "");
1.86 kristaps 589: print_text(h, n->next->string);
590: }
591:
592: print_stagq(h, tt);
593: h->flags |= HTML_NOSPACE;
594: print_text(h, "]");
1.119 schwarze 595: return 0;
1.86 kristaps 596: }
597:
1.8 kristaps 598: static int
599: man_B_pre(MAN_ARGS)
600: {
1.122 schwarze 601: print_otag(h, TAG_B, "");
1.119 schwarze 602: return 1;
1.8 kristaps 603: }
604:
605: static int
606: man_I_pre(MAN_ARGS)
607: {
1.122 schwarze 608: print_otag(h, TAG_I, "");
1.119 schwarze 609: return 1;
1.45 kristaps 610: }
611:
612: static int
613: man_in_pre(MAN_ARGS)
614: {
1.122 schwarze 615: print_otag(h, TAG_BR, "");
1.119 schwarze 616: return 0;
1.8 kristaps 617: }
618:
619: static int
620: man_ign_pre(MAN_ARGS)
621: {
622:
1.119 schwarze 623: return 0;
1.8 kristaps 624: }
1.9 kristaps 625:
626: static int
627: man_RS_pre(MAN_ARGS)
628: {
629: struct roffsu su;
630:
1.113 schwarze 631: if (n->type == ROFFT_HEAD)
1.119 schwarze 632: return 0;
1.113 schwarze 633: else if (n->type == ROFFT_BODY)
1.119 schwarze 634: return 1;
1.9 kristaps 635:
636: SCALE_HS_INIT(&su, INDENT);
1.56 kristaps 637: if (n->head->child)
1.9 kristaps 638: a2width(n->head->child, &su);
639:
1.122 schwarze 640: print_otag(h, TAG_DIV, "sul", &su);
1.119 schwarze 641: return 1;
1.90 schwarze 642: }
643:
644: static int
645: man_UR_pre(MAN_ARGS)
646: {
647: n = n->child;
1.113 schwarze 648: assert(n->type == ROFFT_HEAD);
1.120 schwarze 649: if (n->child != NULL) {
1.113 schwarze 650: assert(n->child->type == ROFFT_TEXT);
1.134 schwarze 651: print_otag(h, TAG_A, "cTh", "Lk", n->child->string);
1.90 schwarze 652: }
653:
1.113 schwarze 654: assert(n->next->type == ROFFT_BODY);
1.120 schwarze 655: if (n->next->child != NULL)
1.90 schwarze 656: n = n->next;
657:
1.132 schwarze 658: print_man_nodelist(man, n->child, h);
1.90 schwarze 659:
1.119 schwarze 660: return 0;
1.9 kristaps 661: }
CVSweb