Annotation of src/usr.bin/mandoc/mdoc_html.c, Revision 1.62
1.62 ! schwarze 1: /* $Id: mdoc_html.c,v 1.61 2011/09/18 15:54:48 schwarze Exp $ */
1.1 schwarze 2: /*
1.48 schwarze 3: * Copyright (c) 2008, 2009, 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
1.1 schwarze 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:
19: #include <assert.h>
20: #include <ctype.h>
21: #include <stdio.h>
22: #include <stdlib.h>
23: #include <string.h>
24: #include <unistd.h>
25:
1.17 schwarze 26: #include "mandoc.h"
1.1 schwarze 27: #include "out.h"
28: #include "html.h"
29: #include "mdoc.h"
30: #include "main.h"
31:
32: #define INDENT 5
33:
34: #define MDOC_ARGS const struct mdoc_meta *m, \
35: const struct mdoc_node *n, \
36: struct html *h
37:
1.6 schwarze 38: #ifndef MIN
39: #define MIN(a,b) ((/*CONSTCOND*/(a)<(b))?(a):(b))
40: #endif
41:
1.1 schwarze 42: struct htmlmdoc {
43: int (*pre)(MDOC_ARGS);
44: void (*post)(MDOC_ARGS);
45: };
46:
47: static void print_mdoc(MDOC_ARGS);
48: static void print_mdoc_head(MDOC_ARGS);
49: static void print_mdoc_node(MDOC_ARGS);
50: static void print_mdoc_nodelist(MDOC_ARGS);
1.21 schwarze 51: static void synopsis_pre(struct html *,
52: const struct mdoc_node *);
1.1 schwarze 53:
54: static void a2width(const char *, struct roffsu *);
55: static void a2offs(const char *, struct roffsu *);
56:
57: static void mdoc_root_post(MDOC_ARGS);
58: static int mdoc_root_pre(MDOC_ARGS);
59:
60: static void mdoc__x_post(MDOC_ARGS);
61: static int mdoc__x_pre(MDOC_ARGS);
62: static int mdoc_ad_pre(MDOC_ARGS);
63: static int mdoc_an_pre(MDOC_ARGS);
64: static int mdoc_ap_pre(MDOC_ARGS);
65: static int mdoc_ar_pre(MDOC_ARGS);
66: static int mdoc_bd_pre(MDOC_ARGS);
67: static int mdoc_bf_pre(MDOC_ARGS);
1.25 schwarze 68: static void mdoc_bk_post(MDOC_ARGS);
69: static int mdoc_bk_pre(MDOC_ARGS);
1.1 schwarze 70: static int mdoc_bl_pre(MDOC_ARGS);
71: static int mdoc_bt_pre(MDOC_ARGS);
72: static int mdoc_bx_pre(MDOC_ARGS);
73: static int mdoc_cd_pre(MDOC_ARGS);
74: static int mdoc_d1_pre(MDOC_ARGS);
75: static int mdoc_dv_pre(MDOC_ARGS);
76: static int mdoc_fa_pre(MDOC_ARGS);
77: static int mdoc_fd_pre(MDOC_ARGS);
78: static int mdoc_fl_pre(MDOC_ARGS);
79: static int mdoc_fn_pre(MDOC_ARGS);
80: static int mdoc_ft_pre(MDOC_ARGS);
81: static int mdoc_em_pre(MDOC_ARGS);
82: static int mdoc_er_pre(MDOC_ARGS);
83: static int mdoc_ev_pre(MDOC_ARGS);
84: static int mdoc_ex_pre(MDOC_ARGS);
85: static void mdoc_fo_post(MDOC_ARGS);
86: static int mdoc_fo_pre(MDOC_ARGS);
87: static int mdoc_ic_pre(MDOC_ARGS);
1.34 schwarze 88: static int mdoc_igndelim_pre(MDOC_ARGS);
1.1 schwarze 89: static int mdoc_in_pre(MDOC_ARGS);
90: static int mdoc_it_pre(MDOC_ARGS);
91: static int mdoc_lb_pre(MDOC_ARGS);
92: static int mdoc_li_pre(MDOC_ARGS);
93: static int mdoc_lk_pre(MDOC_ARGS);
94: static int mdoc_mt_pre(MDOC_ARGS);
95: static int mdoc_ms_pre(MDOC_ARGS);
96: static int mdoc_nd_pre(MDOC_ARGS);
97: static int mdoc_nm_pre(MDOC_ARGS);
98: static int mdoc_ns_pre(MDOC_ARGS);
99: static int mdoc_pa_pre(MDOC_ARGS);
100: static void mdoc_pf_post(MDOC_ARGS);
1.40 schwarze 101: static int mdoc_pp_pre(MDOC_ARGS);
1.32 schwarze 102: static void mdoc_quote_post(MDOC_ARGS);
103: static int mdoc_quote_pre(MDOC_ARGS);
1.1 schwarze 104: static int mdoc_rs_pre(MDOC_ARGS);
105: static int mdoc_rv_pre(MDOC_ARGS);
106: static int mdoc_sh_pre(MDOC_ARGS);
1.26 schwarze 107: static int mdoc_sm_pre(MDOC_ARGS);
1.1 schwarze 108: static int mdoc_sp_pre(MDOC_ARGS);
109: static int mdoc_ss_pre(MDOC_ARGS);
110: static int mdoc_sx_pre(MDOC_ARGS);
111: static int mdoc_sy_pre(MDOC_ARGS);
112: static int mdoc_ud_pre(MDOC_ARGS);
113: static int mdoc_va_pre(MDOC_ARGS);
114: static int mdoc_vt_pre(MDOC_ARGS);
115: static int mdoc_xr_pre(MDOC_ARGS);
116: static int mdoc_xx_pre(MDOC_ARGS);
117:
118: static const struct htmlmdoc mdocs[MDOC_MAX] = {
119: {mdoc_ap_pre, NULL}, /* Ap */
120: {NULL, NULL}, /* Dd */
121: {NULL, NULL}, /* Dt */
122: {NULL, NULL}, /* Os */
123: {mdoc_sh_pre, NULL }, /* Sh */
124: {mdoc_ss_pre, NULL }, /* Ss */
1.40 schwarze 125: {mdoc_pp_pre, NULL}, /* Pp */
1.1 schwarze 126: {mdoc_d1_pre, NULL}, /* D1 */
127: {mdoc_d1_pre, NULL}, /* Dl */
128: {mdoc_bd_pre, NULL}, /* Bd */
129: {NULL, NULL}, /* Ed */
1.40 schwarze 130: {mdoc_bl_pre, NULL}, /* Bl */
1.1 schwarze 131: {NULL, NULL}, /* El */
132: {mdoc_it_pre, NULL}, /* It */
133: {mdoc_ad_pre, NULL}, /* Ad */
134: {mdoc_an_pre, NULL}, /* An */
135: {mdoc_ar_pre, NULL}, /* Ar */
136: {mdoc_cd_pre, NULL}, /* Cd */
137: {mdoc_fl_pre, NULL}, /* Cm */
138: {mdoc_dv_pre, NULL}, /* Dv */
139: {mdoc_er_pre, NULL}, /* Er */
140: {mdoc_ev_pre, NULL}, /* Ev */
141: {mdoc_ex_pre, NULL}, /* Ex */
142: {mdoc_fa_pre, NULL}, /* Fa */
1.21 schwarze 143: {mdoc_fd_pre, NULL}, /* Fd */
1.1 schwarze 144: {mdoc_fl_pre, NULL}, /* Fl */
145: {mdoc_fn_pre, NULL}, /* Fn */
146: {mdoc_ft_pre, NULL}, /* Ft */
147: {mdoc_ic_pre, NULL}, /* Ic */
148: {mdoc_in_pre, NULL}, /* In */
149: {mdoc_li_pre, NULL}, /* Li */
150: {mdoc_nd_pre, NULL}, /* Nd */
151: {mdoc_nm_pre, NULL}, /* Nm */
1.32 schwarze 152: {mdoc_quote_pre, mdoc_quote_post}, /* Op */
1.1 schwarze 153: {NULL, NULL}, /* Ot */
154: {mdoc_pa_pre, NULL}, /* Pa */
155: {mdoc_rv_pre, NULL}, /* Rv */
156: {NULL, NULL}, /* St */
157: {mdoc_va_pre, NULL}, /* Va */
158: {mdoc_vt_pre, NULL}, /* Vt */
159: {mdoc_xr_pre, NULL}, /* Xr */
160: {mdoc__x_pre, mdoc__x_post}, /* %A */
161: {mdoc__x_pre, mdoc__x_post}, /* %B */
162: {mdoc__x_pre, mdoc__x_post}, /* %D */
163: {mdoc__x_pre, mdoc__x_post}, /* %I */
164: {mdoc__x_pre, mdoc__x_post}, /* %J */
165: {mdoc__x_pre, mdoc__x_post}, /* %N */
166: {mdoc__x_pre, mdoc__x_post}, /* %O */
167: {mdoc__x_pre, mdoc__x_post}, /* %P */
168: {mdoc__x_pre, mdoc__x_post}, /* %R */
169: {mdoc__x_pre, mdoc__x_post}, /* %T */
170: {mdoc__x_pre, mdoc__x_post}, /* %V */
171: {NULL, NULL}, /* Ac */
1.32 schwarze 172: {mdoc_quote_pre, mdoc_quote_post}, /* Ao */
173: {mdoc_quote_pre, mdoc_quote_post}, /* Aq */
1.1 schwarze 174: {NULL, NULL}, /* At */
175: {NULL, NULL}, /* Bc */
176: {mdoc_bf_pre, NULL}, /* Bf */
1.32 schwarze 177: {mdoc_quote_pre, mdoc_quote_post}, /* Bo */
178: {mdoc_quote_pre, mdoc_quote_post}, /* Bq */
1.1 schwarze 179: {mdoc_xx_pre, NULL}, /* Bsx */
180: {mdoc_bx_pre, NULL}, /* Bx */
181: {NULL, NULL}, /* Db */
182: {NULL, NULL}, /* Dc */
1.32 schwarze 183: {mdoc_quote_pre, mdoc_quote_post}, /* Do */
184: {mdoc_quote_pre, mdoc_quote_post}, /* Dq */
1.11 schwarze 185: {NULL, NULL}, /* Ec */ /* FIXME: no space */
1.1 schwarze 186: {NULL, NULL}, /* Ef */
187: {mdoc_em_pre, NULL}, /* Em */
188: {NULL, NULL}, /* Eo */
189: {mdoc_xx_pre, NULL}, /* Fx */
1.26 schwarze 190: {mdoc_ms_pre, NULL}, /* Ms */
1.34 schwarze 191: {mdoc_igndelim_pre, NULL}, /* No */
1.1 schwarze 192: {mdoc_ns_pre, NULL}, /* Ns */
193: {mdoc_xx_pre, NULL}, /* Nx */
194: {mdoc_xx_pre, NULL}, /* Ox */
195: {NULL, NULL}, /* Pc */
1.34 schwarze 196: {mdoc_igndelim_pre, mdoc_pf_post}, /* Pf */
1.32 schwarze 197: {mdoc_quote_pre, mdoc_quote_post}, /* Po */
198: {mdoc_quote_pre, mdoc_quote_post}, /* Pq */
1.1 schwarze 199: {NULL, NULL}, /* Qc */
1.32 schwarze 200: {mdoc_quote_pre, mdoc_quote_post}, /* Ql */
201: {mdoc_quote_pre, mdoc_quote_post}, /* Qo */
202: {mdoc_quote_pre, mdoc_quote_post}, /* Qq */
1.1 schwarze 203: {NULL, NULL}, /* Re */
204: {mdoc_rs_pre, NULL}, /* Rs */
205: {NULL, NULL}, /* Sc */
1.32 schwarze 206: {mdoc_quote_pre, mdoc_quote_post}, /* So */
207: {mdoc_quote_pre, mdoc_quote_post}, /* Sq */
1.26 schwarze 208: {mdoc_sm_pre, NULL}, /* Sm */
1.1 schwarze 209: {mdoc_sx_pre, NULL}, /* Sx */
210: {mdoc_sy_pre, NULL}, /* Sy */
211: {NULL, NULL}, /* Tn */
212: {mdoc_xx_pre, NULL}, /* Ux */
213: {NULL, NULL}, /* Xc */
214: {NULL, NULL}, /* Xo */
215: {mdoc_fo_pre, mdoc_fo_post}, /* Fo */
216: {NULL, NULL}, /* Fc */
1.32 schwarze 217: {mdoc_quote_pre, mdoc_quote_post}, /* Oo */
1.1 schwarze 218: {NULL, NULL}, /* Oc */
1.25 schwarze 219: {mdoc_bk_pre, mdoc_bk_post}, /* Bk */
1.1 schwarze 220: {NULL, NULL}, /* Ek */
221: {mdoc_bt_pre, NULL}, /* Bt */
222: {NULL, NULL}, /* Hf */
223: {NULL, NULL}, /* Fr */
224: {mdoc_ud_pre, NULL}, /* Ud */
225: {mdoc_lb_pre, NULL}, /* Lb */
1.40 schwarze 226: {mdoc_pp_pre, NULL}, /* Lp */
1.1 schwarze 227: {mdoc_lk_pre, NULL}, /* Lk */
228: {mdoc_mt_pre, NULL}, /* Mt */
1.32 schwarze 229: {mdoc_quote_pre, mdoc_quote_post}, /* Brq */
230: {mdoc_quote_pre, mdoc_quote_post}, /* Bro */
1.1 schwarze 231: {NULL, NULL}, /* Brc */
232: {mdoc__x_pre, mdoc__x_post}, /* %C */
233: {NULL, NULL}, /* Es */ /* TODO */
234: {NULL, NULL}, /* En */ /* TODO */
235: {mdoc_xx_pre, NULL}, /* Dx */
236: {mdoc__x_pre, mdoc__x_post}, /* %Q */
237: {mdoc_sp_pre, NULL}, /* br */
238: {mdoc_sp_pre, NULL}, /* sp */
1.2 schwarze 239: {mdoc__x_pre, mdoc__x_post}, /* %U */
1.20 schwarze 240: {NULL, NULL}, /* Ta */
1.1 schwarze 241: };
242:
1.40 schwarze 243: static const char * const lists[LIST_MAX] = {
244: NULL,
245: "list-bul",
246: "list-col",
247: "list-dash",
248: "list-diag",
249: "list-enum",
250: "list-hang",
251: "list-hyph",
252: "list-inset",
253: "list-item",
254: "list-ohang",
255: "list-tag"
256: };
1.1 schwarze 257:
258: void
259: html_mdoc(void *arg, const struct mdoc *m)
260: {
261:
1.62 ! schwarze 262: print_mdoc(mdoc_meta(m), mdoc_node(m), (struct html *)arg);
! 263: putchar('\n');
1.1 schwarze 264: }
265:
266:
267: /*
268: * Calculate the scaling unit passed in a `-width' argument. This uses
269: * either a native scaling unit (e.g., 1i, 2m) or the string length of
270: * the value.
271: */
272: static void
273: a2width(const char *p, struct roffsu *su)
274: {
275:
276: if ( ! a2roffsu(p, su, SCALE_MAX)) {
1.40 schwarze 277: su->unit = SCALE_BU;
1.57 schwarze 278: su->scale = html_strlen(p);
1.1 schwarze 279: }
280: }
281:
282:
283: /*
1.21 schwarze 284: * See the same function in mdoc_term.c for documentation.
285: */
286: static void
287: synopsis_pre(struct html *h, const struct mdoc_node *n)
288: {
289:
1.23 schwarze 290: if (NULL == n->prev || ! (MDOC_SYNPRETTY & n->flags))
1.21 schwarze 291: return;
292:
293: if (n->prev->tok == n->tok &&
294: MDOC_Fo != n->tok &&
295: MDOC_Ft != n->tok &&
296: MDOC_Fn != n->tok) {
1.40 schwarze 297: print_otag(h, TAG_BR, 0, NULL);
1.21 schwarze 298: return;
299: }
300:
301: switch (n->prev->tok) {
302: case (MDOC_Fd):
303: /* FALLTHROUGH */
304: case (MDOC_Fn):
305: /* FALLTHROUGH */
306: case (MDOC_Fo):
307: /* FALLTHROUGH */
308: case (MDOC_In):
309: /* FALLTHROUGH */
310: case (MDOC_Vt):
1.40 schwarze 311: print_otag(h, TAG_P, 0, NULL);
1.21 schwarze 312: break;
313: case (MDOC_Ft):
314: if (MDOC_Fn != n->tok && MDOC_Fo != n->tok) {
1.40 schwarze 315: print_otag(h, TAG_P, 0, NULL);
1.21 schwarze 316: break;
317: }
318: /* FALLTHROUGH */
319: default:
1.40 schwarze 320: print_otag(h, TAG_BR, 0, NULL);
1.21 schwarze 321: break;
322: }
323: }
324:
325:
326: /*
1.1 schwarze 327: * Calculate the scaling unit passed in an `-offset' argument. This
328: * uses either a native scaling unit (e.g., 1i, 2m), one of a set of
329: * predefined strings (indent, etc.), or the string length of the value.
330: */
331: static void
332: a2offs(const char *p, struct roffsu *su)
333: {
334:
335: /* FIXME: "right"? */
336:
337: if (0 == strcmp(p, "left"))
338: SCALE_HS_INIT(su, 0);
339: else if (0 == strcmp(p, "indent"))
340: SCALE_HS_INIT(su, INDENT);
341: else if (0 == strcmp(p, "indent-two"))
342: SCALE_HS_INIT(su, INDENT * 2);
1.61 schwarze 343: else if ( ! a2roffsu(p, su, SCALE_MAX))
344: SCALE_HS_INIT(su, html_strlen(p));
1.1 schwarze 345: }
346:
347:
348: static void
349: print_mdoc(MDOC_ARGS)
350: {
1.62 ! schwarze 351: struct tag *t, *tt;
! 352: struct htmlpair tag;
! 353:
! 354: PAIR_CLASS_INIT(&tag, "mandoc");
1.1 schwarze 355:
1.62 ! schwarze 356: if ( ! (HTML_FRAGMENT & h->oflags)) {
! 357: print_gen_decls(h);
! 358: t = print_otag(h, TAG_HTML, 0, NULL);
! 359: tt = print_otag(h, TAG_HEAD, 0, NULL);
! 360: print_mdoc_head(m, n, h);
! 361: print_tagq(h, tt);
! 362: print_otag(h, TAG_BODY, 0, NULL);
! 363: print_otag(h, TAG_DIV, 1, &tag);
! 364: } else
! 365: t = print_otag(h, TAG_DIV, 1, &tag);
1.1 schwarze 366:
367: print_mdoc_nodelist(m, n, h);
368: print_tagq(h, t);
369: }
370:
371:
372: /* ARGSUSED */
373: static void
374: print_mdoc_head(MDOC_ARGS)
375: {
376:
377: print_gen_head(h);
378: bufinit(h);
1.57 schwarze 379: bufcat_fmt(h, "%s(%s)", m->title, m->msec);
1.1 schwarze 380:
1.57 schwarze 381: if (m->arch)
382: bufcat_fmt(h, " (%s)", m->arch);
1.1 schwarze 383:
384: print_otag(h, TAG_TITLE, 0, NULL);
385: print_text(h, h->buf);
386: }
387:
388:
389: static void
390: print_mdoc_nodelist(MDOC_ARGS)
391: {
392:
393: print_mdoc_node(m, n, h);
394: if (n->next)
395: print_mdoc_nodelist(m, n->next, h);
396: }
397:
398:
399: static void
400: print_mdoc_node(MDOC_ARGS)
401: {
402: int child;
403: struct tag *t;
404:
405: child = 1;
1.2 schwarze 406: t = h->tags.head;
1.1 schwarze 407:
408: switch (n->type) {
409: case (MDOC_ROOT):
410: child = mdoc_root_pre(m, n, h);
411: break;
412: case (MDOC_TEXT):
1.48 schwarze 413: /* No tables in this mode... */
414: assert(NULL == h->tblt);
1.50 schwarze 415:
416: /*
417: * Make sure that if we're in a literal mode already
418: * (i.e., within a <PRE>) don't print the newline.
419: */
1.47 schwarze 420: if (' ' == *n->string && MDOC_LINE & n->flags)
1.50 schwarze 421: if ( ! (HTML_LITERAL & h->flags))
422: print_otag(h, TAG_BR, 0, NULL);
1.56 schwarze 423: if (MDOC_DELIMC & n->flags)
424: h->flags |= HTML_NOSPACE;
1.1 schwarze 425: print_text(h, n->string);
1.56 schwarze 426: if (MDOC_DELIMO & n->flags)
427: h->flags |= HTML_NOSPACE;
1.54 schwarze 428: return;
429: case (MDOC_EQN):
1.60 schwarze 430: print_eqn(h, n->eqn);
1.55 schwarze 431: break;
1.45 schwarze 432: case (MDOC_TBL):
1.48 schwarze 433: /*
434: * This will take care of initialising all of the table
435: * state data for the first table, then tearing it down
436: * for the last one.
437: */
1.45 schwarze 438: print_tbl(h, n->span);
1.48 schwarze 439: return;
1.1 schwarze 440: default:
1.48 schwarze 441: /*
442: * Close out the current table, if it's open, and unset
443: * the "meta" table state. This will be reopened on the
444: * next table element.
445: */
446: if (h->tblt) {
447: print_tblclose(h);
448: t = h->tags.head;
449: }
450:
451: assert(NULL == h->tblt);
1.25 schwarze 452: if (mdocs[n->tok].pre && ENDBODY_NOT == n->end)
1.1 schwarze 453: child = (*mdocs[n->tok].pre)(m, n, h);
454: break;
455: }
456:
1.25 schwarze 457: if (HTML_KEEP & h->flags) {
458: if (n->prev && n->prev->line != n->line) {
459: h->flags &= ~HTML_KEEP;
460: h->flags |= HTML_PREKEEP;
461: } else if (NULL == n->prev) {
462: if (n->parent && n->parent->line != n->line) {
463: h->flags &= ~HTML_KEEP;
464: h->flags |= HTML_PREKEEP;
465: }
466: }
467: }
468:
1.1 schwarze 469: if (child && n->child)
470: print_mdoc_nodelist(m, n->child, h);
471:
472: print_stagq(h, t);
473:
474: switch (n->type) {
475: case (MDOC_ROOT):
476: mdoc_root_post(m, n, h);
1.55 schwarze 477: break;
478: case (MDOC_EQN):
1.1 schwarze 479: break;
480: default:
1.25 schwarze 481: if (mdocs[n->tok].post && ENDBODY_NOT == n->end)
1.1 schwarze 482: (*mdocs[n->tok].post)(m, n, h);
483: break;
484: }
485: }
486:
487: /* ARGSUSED */
488: static void
489: mdoc_root_post(MDOC_ARGS)
490: {
1.42 schwarze 491: struct htmlpair tag[3];
1.1 schwarze 492: struct tag *t, *tt;
493:
1.42 schwarze 494: PAIR_SUMMARY_INIT(&tag[0], "Document Footer");
495: PAIR_CLASS_INIT(&tag[1], "foot");
496: if (NULL == h->style) {
1.43 schwarze 497: PAIR_INIT(&tag[2], ATTR_WIDTH, "100%");
498: t = print_otag(h, TAG_TABLE, 3, tag);
1.42 schwarze 499: PAIR_INIT(&tag[0], ATTR_WIDTH, "50%");
500: print_otag(h, TAG_COL, 1, tag);
501: print_otag(h, TAG_COL, 1, tag);
502: } else
503: t = print_otag(h, TAG_TABLE, 2, tag);
504:
505: t = print_otag(h, TAG_TBODY, 0, NULL);
1.3 schwarze 506:
1.1 schwarze 507: tt = print_otag(h, TAG_TR, 0, NULL);
508:
1.40 schwarze 509: PAIR_CLASS_INIT(&tag[0], "foot-date");
1.1 schwarze 510: print_otag(h, TAG_TD, 1, tag);
1.40 schwarze 511:
1.53 schwarze 512: print_text(h, m->date);
1.1 schwarze 513: print_stagq(h, tt);
514:
1.40 schwarze 515: PAIR_CLASS_INIT(&tag[0], "foot-os");
1.42 schwarze 516: if (NULL == h->style) {
517: PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
518: print_otag(h, TAG_TD, 2, tag);
519: } else
520: print_otag(h, TAG_TD, 1, tag);
1.40 schwarze 521:
1.1 schwarze 522: print_text(h, m->os);
523: print_tagq(h, t);
524: }
525:
526:
527: /* ARGSUSED */
528: static int
529: mdoc_root_pre(MDOC_ARGS)
530: {
1.3 schwarze 531: struct htmlpair tag[3];
1.1 schwarze 532: struct tag *t, *tt;
533: char b[BUFSIZ], title[BUFSIZ];
534:
1.40 schwarze 535: strlcpy(b, m->vol, BUFSIZ);
1.1 schwarze 536:
537: if (m->arch) {
1.40 schwarze 538: strlcat(b, " (", BUFSIZ);
539: strlcat(b, m->arch, BUFSIZ);
540: strlcat(b, ")", BUFSIZ);
1.1 schwarze 541: }
542:
1.40 schwarze 543: snprintf(title, BUFSIZ - 1, "%s(%s)", m->title, m->msec);
1.1 schwarze 544:
1.42 schwarze 545: PAIR_SUMMARY_INIT(&tag[0], "Document Header");
546: PAIR_CLASS_INIT(&tag[1], "head");
547: if (NULL == h->style) {
548: PAIR_INIT(&tag[2], ATTR_WIDTH, "100%");
549: t = print_otag(h, TAG_TABLE, 3, tag);
550: PAIR_INIT(&tag[0], ATTR_WIDTH, "30%");
551: print_otag(h, TAG_COL, 1, tag);
552: print_otag(h, TAG_COL, 1, tag);
553: print_otag(h, TAG_COL, 1, tag);
554: } else
555: t = print_otag(h, TAG_TABLE, 2, tag);
556:
557: print_otag(h, TAG_TBODY, 0, NULL);
1.3 schwarze 558:
1.1 schwarze 559: tt = print_otag(h, TAG_TR, 0, NULL);
560:
1.40 schwarze 561: PAIR_CLASS_INIT(&tag[0], "head-ltitle");
1.1 schwarze 562: print_otag(h, TAG_TD, 1, tag);
1.40 schwarze 563:
1.1 schwarze 564: print_text(h, title);
565: print_stagq(h, tt);
566:
1.40 schwarze 567: PAIR_CLASS_INIT(&tag[0], "head-vol");
1.42 schwarze 568: if (NULL == h->style) {
569: PAIR_INIT(&tag[1], ATTR_ALIGN, "center");
570: print_otag(h, TAG_TD, 2, tag);
571: } else
572: print_otag(h, TAG_TD, 1, tag);
1.40 schwarze 573:
1.1 schwarze 574: print_text(h, b);
575: print_stagq(h, tt);
576:
1.40 schwarze 577: PAIR_CLASS_INIT(&tag[0], "head-rtitle");
1.42 schwarze 578: if (NULL == h->style) {
579: PAIR_INIT(&tag[1], ATTR_ALIGN, "right");
580: print_otag(h, TAG_TD, 2, tag);
581: } else
582: print_otag(h, TAG_TD, 1, tag);
1.40 schwarze 583:
1.1 schwarze 584: print_text(h, title);
585: print_tagq(h, t);
586: return(1);
587: }
588:
589:
590: /* ARGSUSED */
591: static int
592: mdoc_sh_pre(MDOC_ARGS)
593: {
1.40 schwarze 594: struct htmlpair tag;
1.1 schwarze 595:
1.40 schwarze 596: if (MDOC_BLOCK == n->type) {
597: PAIR_CLASS_INIT(&tag, "section");
598: print_otag(h, TAG_DIV, 1, &tag);
1.1 schwarze 599: return(1);
1.40 schwarze 600: } else if (MDOC_BODY == n->type)
1.1 schwarze 601: return(1);
602:
1.57 schwarze 603: bufinit(h);
1.59 schwarze 604: bufcat(h, "x");
1.61 schwarze 605:
606: for (n = n->child; n && MDOC_TEXT == n->type; ) {
1.57 schwarze 607: bufcat_id(h, n->string);
1.61 schwarze 608: if (NULL != (n = n->next))
1.57 schwarze 609: bufcat_id(h, " ");
1.1 schwarze 610: }
611:
1.61 schwarze 612: if (NULL == n) {
613: PAIR_ID_INIT(&tag, h->buf);
614: print_otag(h, TAG_H1, 1, &tag);
615: } else
616: print_otag(h, TAG_H1, 0, NULL);
617:
1.1 schwarze 618: return(1);
619: }
620:
621: /* ARGSUSED */
622: static int
623: mdoc_ss_pre(MDOC_ARGS)
624: {
1.40 schwarze 625: struct htmlpair tag;
1.1 schwarze 626:
1.40 schwarze 627: if (MDOC_BLOCK == n->type) {
628: PAIR_CLASS_INIT(&tag, "subsection");
629: print_otag(h, TAG_DIV, 1, &tag);
1.1 schwarze 630: return(1);
1.40 schwarze 631: } else if (MDOC_BODY == n->type)
1.1 schwarze 632: return(1);
633:
1.57 schwarze 634: bufinit(h);
1.59 schwarze 635: bufcat(h, "x");
1.61 schwarze 636:
637: for (n = n->child; n && MDOC_TEXT == n->type; ) {
1.57 schwarze 638: bufcat_id(h, n->string);
1.61 schwarze 639: if (NULL != (n = n->next))
1.57 schwarze 640: bufcat_id(h, " ");
1.1 schwarze 641: }
642:
1.61 schwarze 643: if (NULL == n) {
644: PAIR_ID_INIT(&tag, h->buf);
645: print_otag(h, TAG_H2, 1, &tag);
646: } else
647: print_otag(h, TAG_H2, 0, NULL);
648:
1.1 schwarze 649: return(1);
650: }
651:
652:
653: /* ARGSUSED */
654: static int
655: mdoc_fl_pre(MDOC_ARGS)
656: {
657: struct htmlpair tag;
658:
659: PAIR_CLASS_INIT(&tag, "flag");
1.42 schwarze 660: print_otag(h, TAG_B, 1, &tag);
1.6 schwarze 661:
662: /* `Cm' has no leading hyphen. */
663:
664: if (MDOC_Cm == n->tok)
665: return(1);
666:
667: print_text(h, "\\-");
668:
669: if (n->child)
1.1 schwarze 670: h->flags |= HTML_NOSPACE;
1.11 schwarze 671: else if (n->next && n->next->line == n->line)
672: h->flags |= HTML_NOSPACE;
1.6 schwarze 673:
1.1 schwarze 674: return(1);
675: }
676:
677:
678: /* ARGSUSED */
679: static int
680: mdoc_nd_pre(MDOC_ARGS)
681: {
682: struct htmlpair tag;
683:
684: if (MDOC_BODY != n->type)
685: return(1);
686:
687: /* XXX: this tag in theory can contain block elements. */
688:
689: print_text(h, "\\(em");
1.40 schwarze 690: PAIR_CLASS_INIT(&tag, "desc");
1.1 schwarze 691: print_otag(h, TAG_SPAN, 1, &tag);
692: return(1);
693: }
694:
695:
696: static int
697: mdoc_nm_pre(MDOC_ARGS)
698: {
1.25 schwarze 699: struct htmlpair tag;
700: struct roffsu su;
1.57 schwarze 701: int len;
1.25 schwarze 702:
1.40 schwarze 703: switch (n->type) {
704: case (MDOC_ELEM):
1.25 schwarze 705: synopsis_pre(h, n);
706: PAIR_CLASS_INIT(&tag, "name");
1.42 schwarze 707: print_otag(h, TAG_B, 1, &tag);
1.40 schwarze 708: if (NULL == n->child && m->name)
1.25 schwarze 709: print_text(h, m->name);
1.40 schwarze 710: return(1);
711: case (MDOC_HEAD):
712: print_otag(h, TAG_TD, 0, NULL);
713: if (NULL == n->child && m->name)
714: print_text(h, m->name);
715: return(1);
716: case (MDOC_BODY):
717: print_otag(h, TAG_TD, 0, NULL);
718: return(1);
719: default:
720: break;
721: }
1.25 schwarze 722:
1.40 schwarze 723: synopsis_pre(h, n);
724: PAIR_CLASS_INIT(&tag, "synopsis");
725: print_otag(h, TAG_TABLE, 1, &tag);
1.25 schwarze 726:
1.40 schwarze 727: for (len = 0, n = n->child; n; n = n->next)
728: if (MDOC_TEXT == n->type)
1.57 schwarze 729: len += html_strlen(n->string);
1.25 schwarze 730:
1.40 schwarze 731: if (0 == len && m->name)
1.57 schwarze 732: len = html_strlen(m->name);
1.1 schwarze 733:
1.40 schwarze 734: SCALE_HS_INIT(&su, (double)len);
1.57 schwarze 735: bufinit(h);
1.40 schwarze 736: bufcat_su(h, "width", &su);
737: PAIR_STYLE_INIT(&tag, h);
738: print_otag(h, TAG_COL, 1, &tag);
739: print_otag(h, TAG_COL, 0, NULL);
740: print_otag(h, TAG_TBODY, 0, NULL);
741: print_otag(h, TAG_TR, 0, NULL);
1.1 schwarze 742: return(1);
743: }
744:
745:
746: /* ARGSUSED */
747: static int
748: mdoc_xr_pre(MDOC_ARGS)
749: {
1.56 schwarze 750: struct htmlpair tag[2];
1.9 schwarze 751:
752: if (NULL == n->child)
753: return(0);
1.1 schwarze 754:
755: PAIR_CLASS_INIT(&tag[0], "link-man");
756:
757: if (h->base_man) {
758: buffmt_man(h, n->child->string,
759: n->child->next ?
760: n->child->next->string : NULL);
1.11 schwarze 761: PAIR_HREF_INIT(&tag[1], h->buf);
1.1 schwarze 762: print_otag(h, TAG_A, 2, tag);
763: } else
764: print_otag(h, TAG_A, 1, tag);
765:
1.56 schwarze 766: n = n->child;
767: print_text(h, n->string);
1.1 schwarze 768:
1.56 schwarze 769: if (NULL == (n = n->next))
1.1 schwarze 770: return(0);
771:
772: h->flags |= HTML_NOSPACE;
773: print_text(h, "(");
774: h->flags |= HTML_NOSPACE;
1.56 schwarze 775: print_text(h, n->string);
1.1 schwarze 776: h->flags |= HTML_NOSPACE;
777: print_text(h, ")");
778: return(0);
779: }
780:
781:
782: /* ARGSUSED */
783: static int
784: mdoc_ns_pre(MDOC_ARGS)
785: {
786:
1.51 schwarze 787: if ( ! (MDOC_LINE & n->flags))
788: h->flags |= HTML_NOSPACE;
1.1 schwarze 789: return(1);
790: }
791:
792:
793: /* ARGSUSED */
794: static int
795: mdoc_ar_pre(MDOC_ARGS)
796: {
797: struct htmlpair tag;
798:
799: PAIR_CLASS_INIT(&tag, "arg");
1.42 schwarze 800: print_otag(h, TAG_I, 1, &tag);
1.1 schwarze 801: return(1);
802: }
803:
804:
805: /* ARGSUSED */
806: static int
807: mdoc_xx_pre(MDOC_ARGS)
808: {
809: const char *pp;
810: struct htmlpair tag;
1.52 schwarze 811: int flags;
1.1 schwarze 812:
813: switch (n->tok) {
814: case (MDOC_Bsx):
1.37 schwarze 815: pp = "BSD/OS";
1.1 schwarze 816: break;
817: case (MDOC_Dx):
1.4 schwarze 818: pp = "DragonFly";
1.1 schwarze 819: break;
820: case (MDOC_Fx):
821: pp = "FreeBSD";
822: break;
823: case (MDOC_Nx):
824: pp = "NetBSD";
825: break;
826: case (MDOC_Ox):
827: pp = "OpenBSD";
828: break;
829: case (MDOC_Ux):
830: pp = "UNIX";
831: break;
832: default:
833: return(1);
834: }
835:
836: PAIR_CLASS_INIT(&tag, "unix");
837: print_otag(h, TAG_SPAN, 1, &tag);
1.52 schwarze 838:
1.1 schwarze 839: print_text(h, pp);
1.52 schwarze 840: if (n->child) {
841: flags = h->flags;
842: h->flags |= HTML_KEEP;
843: print_text(h, n->child->string);
844: h->flags = flags;
845: }
846: return(0);
1.1 schwarze 847: }
848:
849:
850: /* ARGSUSED */
851: static int
852: mdoc_bx_pre(MDOC_ARGS)
853: {
1.49 schwarze 854: struct htmlpair tag;
1.1 schwarze 855:
856: PAIR_CLASS_INIT(&tag, "unix");
857: print_otag(h, TAG_SPAN, 1, &tag);
858:
1.49 schwarze 859: if (NULL != (n = n->child)) {
860: print_text(h, n->string);
861: h->flags |= HTML_NOSPACE;
862: print_text(h, "BSD");
863: } else {
864: print_text(h, "BSD");
865: return(0);
866: }
1.1 schwarze 867:
1.49 schwarze 868: if (NULL != (n = n->next)) {
869: h->flags |= HTML_NOSPACE;
870: print_text(h, "-");
1.1 schwarze 871: h->flags |= HTML_NOSPACE;
1.49 schwarze 872: print_text(h, n->string);
873: }
1.1 schwarze 874:
875: return(0);
876: }
877:
1.46 schwarze 878: /* ARGSUSED */
1.1 schwarze 879: static int
1.40 schwarze 880: mdoc_it_pre(MDOC_ARGS)
1.1 schwarze 881: {
1.40 schwarze 882: struct roffsu su;
883: enum mdoc_list type;
884: struct htmlpair tag[2];
885: const struct mdoc_node *bl;
1.1 schwarze 886:
1.40 schwarze 887: bl = n->parent;
888: while (bl && MDOC_Bl != bl->tok)
889: bl = bl->parent;
1.1 schwarze 890:
1.40 schwarze 891: assert(bl);
1.1 schwarze 892:
1.44 schwarze 893: type = bl->norm->Bl.type;
1.1 schwarze 894:
1.40 schwarze 895: assert(lists[type]);
896: PAIR_CLASS_INIT(&tag[0], lists[type]);
1.1 schwarze 897:
1.57 schwarze 898: bufinit(h);
899:
1.40 schwarze 900: if (MDOC_HEAD == n->type) {
901: switch (type) {
902: case(LIST_bullet):
903: /* FALLTHROUGH */
904: case(LIST_dash):
905: /* FALLTHROUGH */
906: case(LIST_item):
907: /* FALLTHROUGH */
908: case(LIST_hyphen):
909: /* FALLTHROUGH */
910: case(LIST_enum):
911: return(0);
912: case(LIST_diag):
913: /* FALLTHROUGH */
914: case(LIST_hang):
915: /* FALLTHROUGH */
916: case(LIST_inset):
917: /* FALLTHROUGH */
918: case(LIST_ohang):
919: /* FALLTHROUGH */
920: case(LIST_tag):
1.44 schwarze 921: SCALE_VS_INIT(&su, ! bl->norm->Bl.comp);
1.40 schwarze 922: bufcat_su(h, "margin-top", &su);
923: PAIR_STYLE_INIT(&tag[1], h);
924: print_otag(h, TAG_DT, 2, tag);
1.42 schwarze 925: if (LIST_diag != type)
926: break;
927: PAIR_CLASS_INIT(&tag[0], "diag");
928: print_otag(h, TAG_B, 1, tag);
1.40 schwarze 929: break;
930: case(LIST_column):
931: break;
932: default:
933: break;
934: }
935: } else if (MDOC_BODY == n->type) {
936: switch (type) {
937: case(LIST_bullet):
938: /* FALLTHROUGH */
939: case(LIST_hyphen):
940: /* FALLTHROUGH */
941: case(LIST_dash):
942: /* FALLTHROUGH */
943: case(LIST_enum):
944: /* FALLTHROUGH */
945: case(LIST_item):
1.44 schwarze 946: SCALE_VS_INIT(&su, ! bl->norm->Bl.comp);
1.40 schwarze 947: bufcat_su(h, "margin-top", &su);
948: PAIR_STYLE_INIT(&tag[1], h);
949: print_otag(h, TAG_LI, 2, tag);
950: break;
951: case(LIST_diag):
952: /* FALLTHROUGH */
953: case(LIST_hang):
954: /* FALLTHROUGH */
955: case(LIST_inset):
956: /* FALLTHROUGH */
957: case(LIST_ohang):
958: /* FALLTHROUGH */
959: case(LIST_tag):
1.44 schwarze 960: if (NULL == bl->norm->Bl.width) {
1.40 schwarze 961: print_otag(h, TAG_DD, 1, tag);
962: break;
963: }
1.44 schwarze 964: a2width(bl->norm->Bl.width, &su);
1.40 schwarze 965: bufcat_su(h, "margin-left", &su);
966: PAIR_STYLE_INIT(&tag[1], h);
967: print_otag(h, TAG_DD, 2, tag);
968: break;
969: case(LIST_column):
1.44 schwarze 970: SCALE_VS_INIT(&su, ! bl->norm->Bl.comp);
1.40 schwarze 971: bufcat_su(h, "margin-top", &su);
972: PAIR_STYLE_INIT(&tag[1], h);
973: print_otag(h, TAG_TD, 2, tag);
974: break;
975: default:
976: break;
977: }
978: } else {
979: switch (type) {
980: case (LIST_column):
981: print_otag(h, TAG_TR, 1, tag);
982: break;
983: default:
1.1 schwarze 984: break;
1.40 schwarze 985: }
1.1 schwarze 986: }
987:
988: return(1);
989: }
990:
991: /* ARGSUSED */
992: static int
1.40 schwarze 993: mdoc_bl_pre(MDOC_ARGS)
1.1 schwarze 994: {
1.46 schwarze 995: int i;
1.40 schwarze 996: struct htmlpair tag[3];
1.1 schwarze 997: struct roffsu su;
1.42 schwarze 998: char buf[BUFSIZ];
1.1 schwarze 999:
1.57 schwarze 1000: bufinit(h);
1001:
1.40 schwarze 1002: if (MDOC_BODY == n->type) {
1.44 schwarze 1003: if (LIST_column == n->norm->Bl.type)
1.40 schwarze 1004: print_otag(h, TAG_TBODY, 0, NULL);
1005: return(1);
1.1 schwarze 1006: }
1007:
1.40 schwarze 1008: if (MDOC_HEAD == n->type) {
1.44 schwarze 1009: if (LIST_column != n->norm->Bl.type)
1.40 schwarze 1010: return(0);
1.1 schwarze 1011:
1.40 schwarze 1012: /*
1013: * For each column, print out the <COL> tag with our
1014: * suggested width. The last column gets min-width, as
1015: * in terminal mode it auto-sizes to the width of the
1016: * screen and we want to preserve that behaviour.
1017: */
1.1 schwarze 1018:
1.46 schwarze 1019: for (i = 0; i < (int)n->norm->Bl.ncols; i++) {
1.44 schwarze 1020: a2width(n->norm->Bl.cols[i], &su);
1.46 schwarze 1021: if (i < (int)n->norm->Bl.ncols - 1)
1.40 schwarze 1022: bufcat_su(h, "width", &su);
1023: else
1024: bufcat_su(h, "min-width", &su);
1025: PAIR_STYLE_INIT(&tag[0], h);
1026: print_otag(h, TAG_COL, 1, tag);
1027: }
1.1 schwarze 1028:
1.4 schwarze 1029: return(0);
1.1 schwarze 1030: }
1031:
1.40 schwarze 1032: SCALE_VS_INIT(&su, 0);
1033: bufcat_su(h, "margin-top", &su);
1034: bufcat_su(h, "margin-bottom", &su);
1035: PAIR_STYLE_INIT(&tag[0], h);
1.1 schwarze 1036:
1.44 schwarze 1037: assert(lists[n->norm->Bl.type]);
1.42 schwarze 1038: strlcpy(buf, "list ", BUFSIZ);
1.44 schwarze 1039: strlcat(buf, lists[n->norm->Bl.type], BUFSIZ);
1.42 schwarze 1040: PAIR_INIT(&tag[1], ATTR_CLASS, buf);
1.1 schwarze 1041:
1.40 schwarze 1042: /* Set the block's left-hand margin. */
1.1 schwarze 1043:
1.44 schwarze 1044: if (n->norm->Bl.offs) {
1045: a2offs(n->norm->Bl.offs, &su);
1.40 schwarze 1046: bufcat_su(h, "margin-left", &su);
1047: }
1.1 schwarze 1048:
1.44 schwarze 1049: switch (n->norm->Bl.type) {
1.40 schwarze 1050: case(LIST_bullet):
1.1 schwarze 1051: /* FALLTHROUGH */
1.40 schwarze 1052: case(LIST_dash):
1.1 schwarze 1053: /* FALLTHROUGH */
1.40 schwarze 1054: case(LIST_hyphen):
1.1 schwarze 1055: /* FALLTHROUGH */
1.40 schwarze 1056: case(LIST_item):
1.42 schwarze 1057: print_otag(h, TAG_UL, 2, tag);
1.1 schwarze 1058: break;
1.40 schwarze 1059: case(LIST_enum):
1.42 schwarze 1060: print_otag(h, TAG_OL, 2, tag);
1.1 schwarze 1061: break;
1.40 schwarze 1062: case(LIST_diag):
1063: /* FALLTHROUGH */
1064: case(LIST_hang):
1.4 schwarze 1065: /* FALLTHROUGH */
1.40 schwarze 1066: case(LIST_inset):
1.1 schwarze 1067: /* FALLTHROUGH */
1.40 schwarze 1068: case(LIST_ohang):
1.1 schwarze 1069: /* FALLTHROUGH */
1.40 schwarze 1070: case(LIST_tag):
1.42 schwarze 1071: print_otag(h, TAG_DL, 2, tag);
1.40 schwarze 1072: break;
1073: case(LIST_column):
1.42 schwarze 1074: print_otag(h, TAG_TABLE, 2, tag);
1.1 schwarze 1075: break;
1076: default:
1.40 schwarze 1077: abort();
1078: /* NOTREACHED */
1.1 schwarze 1079: }
1080:
1081: return(1);
1082: }
1083:
1084: /* ARGSUSED */
1085: static int
1086: mdoc_ex_pre(MDOC_ARGS)
1087: {
1.56 schwarze 1088: struct tag *t;
1089: struct htmlpair tag;
1090: int nchild;
1.1 schwarze 1091:
1.40 schwarze 1092: if (n->prev)
1093: print_otag(h, TAG_BR, 0, NULL);
1094:
1.1 schwarze 1095: PAIR_CLASS_INIT(&tag, "utility");
1096:
1097: print_text(h, "The");
1.56 schwarze 1098:
1099: nchild = n->nchild;
1100: for (n = n->child; n; n = n->next) {
1101: assert(MDOC_TEXT == n->type);
1102:
1.42 schwarze 1103: t = print_otag(h, TAG_B, 1, &tag);
1.56 schwarze 1104: print_text(h, n->string);
1.1 schwarze 1105: print_tagq(h, t);
1106:
1.56 schwarze 1107: if (nchild > 2 && n->next) {
1108: h->flags |= HTML_NOSPACE;
1109: print_text(h, ",");
1110: }
1.1 schwarze 1111:
1.56 schwarze 1112: if (n->next && NULL == n->next->next)
1113: print_text(h, "and");
1.1 schwarze 1114: }
1115:
1.56 schwarze 1116: if (nchild > 1)
1.1 schwarze 1117: print_text(h, "utilities exit");
1118: else
1119: print_text(h, "utility exits");
1120:
1121: print_text(h, "0 on success, and >0 if an error occurs.");
1122: return(0);
1123: }
1124:
1125:
1126: /* ARGSUSED */
1127: static int
1128: mdoc_em_pre(MDOC_ARGS)
1129: {
1130: struct htmlpair tag;
1131:
1132: PAIR_CLASS_INIT(&tag, "emph");
1133: print_otag(h, TAG_SPAN, 1, &tag);
1134: return(1);
1135: }
1136:
1137:
1138: /* ARGSUSED */
1139: static int
1140: mdoc_d1_pre(MDOC_ARGS)
1141: {
1142: struct htmlpair tag[2];
1143: struct roffsu su;
1144:
1145: if (MDOC_BLOCK != n->type)
1146: return(1);
1147:
1.40 schwarze 1148: SCALE_VS_INIT(&su, 0);
1.57 schwarze 1149: bufinit(h);
1.40 schwarze 1150: bufcat_su(h, "margin-top", &su);
1151: bufcat_su(h, "margin-bottom", &su);
1152: PAIR_STYLE_INIT(&tag[0], h);
1153: print_otag(h, TAG_BLOCKQUOTE, 1, tag);
1154:
1155: /* BLOCKQUOTE needs a block body. */
1.1 schwarze 1156:
1.43 schwarze 1157: PAIR_CLASS_INIT(&tag[0], "display");
1158: print_otag(h, TAG_DIV, 1, tag);
1159:
1160: if (MDOC_Dl == n->tok) {
1161: PAIR_CLASS_INIT(&tag[0], "lit");
1162: print_otag(h, TAG_CODE, 1, tag);
1163: }
1.40 schwarze 1164:
1.1 schwarze 1165: return(1);
1166: }
1167:
1168:
1169: /* ARGSUSED */
1170: static int
1171: mdoc_sx_pre(MDOC_ARGS)
1172: {
1.56 schwarze 1173: struct htmlpair tag[2];
1.1 schwarze 1174:
1.57 schwarze 1175: bufinit(h);
1176: bufcat(h, "#x");
1.61 schwarze 1177:
1178: for (n = n->child; n; ) {
1.57 schwarze 1179: bufcat_id(h, n->string);
1.61 schwarze 1180: if (NULL != (n = n->next))
1.57 schwarze 1181: bufcat_id(h, " ");
1.1 schwarze 1182: }
1183:
1184: PAIR_CLASS_INIT(&tag[0], "link-sec");
1.57 schwarze 1185: PAIR_HREF_INIT(&tag[1], h->buf);
1.1 schwarze 1186:
1.42 schwarze 1187: print_otag(h, TAG_I, 1, tag);
1.1 schwarze 1188: print_otag(h, TAG_A, 2, tag);
1189: return(1);
1190: }
1191:
1192:
1193: /* ARGSUSED */
1194: static int
1195: mdoc_bd_pre(MDOC_ARGS)
1196: {
1197: struct htmlpair tag[2];
1.50 schwarze 1198: int comp, sv;
1.22 schwarze 1199: const struct mdoc_node *nn;
1.1 schwarze 1200: struct roffsu su;
1201:
1.22 schwarze 1202: if (MDOC_HEAD == n->type)
1.1 schwarze 1203: return(0);
1204:
1205: if (MDOC_BLOCK == n->type) {
1.44 schwarze 1206: comp = n->norm->Bd.comp;
1.1 schwarze 1207: for (nn = n; nn && ! comp; nn = nn->parent) {
1208: if (MDOC_BLOCK != nn->type)
1209: continue;
1210: if (MDOC_Ss == nn->tok || MDOC_Sh == nn->tok)
1211: comp = 1;
1212: if (nn->prev)
1213: break;
1214: }
1.40 schwarze 1215: if ( ! comp)
1216: print_otag(h, TAG_P, 0, NULL);
1.1 schwarze 1217: return(1);
1218: }
1219:
1.40 schwarze 1220: SCALE_HS_INIT(&su, 0);
1.44 schwarze 1221: if (n->norm->Bd.offs)
1222: a2offs(n->norm->Bd.offs, &su);
1.57 schwarze 1223:
1224: bufinit(h);
1.40 schwarze 1225: bufcat_su(h, "margin-left", &su);
1226: PAIR_STYLE_INIT(&tag[0], h);
1227:
1.44 schwarze 1228: if (DISP_unfilled != n->norm->Bd.type &&
1229: DISP_literal != n->norm->Bd.type) {
1.40 schwarze 1230: PAIR_CLASS_INIT(&tag[1], "display");
1231: print_otag(h, TAG_DIV, 2, tag);
1.1 schwarze 1232: return(1);
1.40 schwarze 1233: }
1.1 schwarze 1234:
1.40 schwarze 1235: PAIR_CLASS_INIT(&tag[1], "lit display");
1236: print_otag(h, TAG_PRE, 2, tag);
1.1 schwarze 1237:
1.50 schwarze 1238: /* This can be recursive: save & set our literal state. */
1239:
1240: sv = h->flags & HTML_LITERAL;
1241: h->flags |= HTML_LITERAL;
1242:
1.1 schwarze 1243: for (nn = n->child; nn; nn = nn->next) {
1244: print_mdoc_node(m, nn, h);
1.33 schwarze 1245: /*
1246: * If the printed node flushes its own line, then we
1247: * needn't do it here as well. This is hacky, but the
1248: * notion of selective eoln whitespace is pretty dumb
1249: * anyway, so don't sweat it.
1250: */
1251: switch (nn->tok) {
1.36 schwarze 1252: case (MDOC_Sm):
1253: /* FALLTHROUGH */
1.33 schwarze 1254: case (MDOC_br):
1255: /* FALLTHROUGH */
1256: case (MDOC_sp):
1257: /* FALLTHROUGH */
1258: case (MDOC_Bl):
1.39 schwarze 1259: /* FALLTHROUGH */
1260: case (MDOC_D1):
1261: /* FALLTHROUGH */
1262: case (MDOC_Dl):
1.33 schwarze 1263: /* FALLTHROUGH */
1264: case (MDOC_Lp):
1265: /* FALLTHROUGH */
1266: case (MDOC_Pp):
1267: continue;
1268: default:
1269: break;
1270: }
1.28 schwarze 1271: if (nn->next && nn->next->line == nn->line)
1272: continue;
1.40 schwarze 1273: else if (nn->next)
1274: print_text(h, "\n");
1275:
1.28 schwarze 1276: h->flags |= HTML_NOSPACE;
1.1 schwarze 1277: }
1.50 schwarze 1278:
1279: if (0 == sv)
1280: h->flags &= ~HTML_LITERAL;
1.1 schwarze 1281:
1282: return(0);
1283: }
1284:
1285:
1286: /* ARGSUSED */
1287: static int
1288: mdoc_pa_pre(MDOC_ARGS)
1289: {
1290: struct htmlpair tag;
1291:
1292: PAIR_CLASS_INIT(&tag, "file");
1.42 schwarze 1293: print_otag(h, TAG_I, 1, &tag);
1.1 schwarze 1294: return(1);
1295: }
1296:
1297:
1298: /* ARGSUSED */
1299: static int
1300: mdoc_ad_pre(MDOC_ARGS)
1301: {
1302: struct htmlpair tag;
1303:
1304: PAIR_CLASS_INIT(&tag, "addr");
1.42 schwarze 1305: print_otag(h, TAG_I, 1, &tag);
1.1 schwarze 1306: return(1);
1307: }
1308:
1309:
1310: /* ARGSUSED */
1311: static int
1312: mdoc_an_pre(MDOC_ARGS)
1313: {
1314: struct htmlpair tag;
1315:
1316: /* TODO: -split and -nosplit (see termp_an_pre()). */
1317:
1318: PAIR_CLASS_INIT(&tag, "author");
1319: print_otag(h, TAG_SPAN, 1, &tag);
1320: return(1);
1321: }
1322:
1323:
1324: /* ARGSUSED */
1325: static int
1326: mdoc_cd_pre(MDOC_ARGS)
1327: {
1328: struct htmlpair tag;
1329:
1.21 schwarze 1330: synopsis_pre(h, n);
1.1 schwarze 1331: PAIR_CLASS_INIT(&tag, "config");
1.42 schwarze 1332: print_otag(h, TAG_B, 1, &tag);
1.1 schwarze 1333: return(1);
1334: }
1335:
1336:
1337: /* ARGSUSED */
1338: static int
1339: mdoc_dv_pre(MDOC_ARGS)
1340: {
1341: struct htmlpair tag;
1342:
1343: PAIR_CLASS_INIT(&tag, "define");
1344: print_otag(h, TAG_SPAN, 1, &tag);
1345: return(1);
1346: }
1347:
1348:
1349: /* ARGSUSED */
1350: static int
1351: mdoc_ev_pre(MDOC_ARGS)
1352: {
1353: struct htmlpair tag;
1354:
1355: PAIR_CLASS_INIT(&tag, "env");
1356: print_otag(h, TAG_SPAN, 1, &tag);
1357: return(1);
1358: }
1359:
1360:
1361: /* ARGSUSED */
1362: static int
1363: mdoc_er_pre(MDOC_ARGS)
1364: {
1365: struct htmlpair tag;
1366:
1367: PAIR_CLASS_INIT(&tag, "errno");
1368: print_otag(h, TAG_SPAN, 1, &tag);
1369: return(1);
1370: }
1371:
1372:
1373: /* ARGSUSED */
1374: static int
1375: mdoc_fa_pre(MDOC_ARGS)
1376: {
1377: const struct mdoc_node *nn;
1378: struct htmlpair tag;
1379: struct tag *t;
1380:
1381: PAIR_CLASS_INIT(&tag, "farg");
1382: if (n->parent->tok != MDOC_Fo) {
1.42 schwarze 1383: print_otag(h, TAG_I, 1, &tag);
1.1 schwarze 1384: return(1);
1385: }
1386:
1387: for (nn = n->child; nn; nn = nn->next) {
1.42 schwarze 1388: t = print_otag(h, TAG_I, 1, &tag);
1.1 schwarze 1389: print_text(h, nn->string);
1390: print_tagq(h, t);
1.56 schwarze 1391: if (nn->next) {
1392: h->flags |= HTML_NOSPACE;
1.1 schwarze 1393: print_text(h, ",");
1.56 schwarze 1394: }
1.1 schwarze 1395: }
1396:
1.56 schwarze 1397: if (n->child && n->next && n->next->tok == MDOC_Fa) {
1398: h->flags |= HTML_NOSPACE;
1.1 schwarze 1399: print_text(h, ",");
1.56 schwarze 1400: }
1.1 schwarze 1401:
1402: return(0);
1403: }
1404:
1405:
1406: /* ARGSUSED */
1407: static int
1408: mdoc_fd_pre(MDOC_ARGS)
1409: {
1.56 schwarze 1410: struct htmlpair tag[2];
1411: char buf[BUFSIZ];
1412: size_t sz;
1413: int i;
1414: struct tag *t;
1.1 schwarze 1415:
1.21 schwarze 1416: synopsis_pre(h, n);
1417:
1.56 schwarze 1418: if (NULL == (n = n->child))
1419: return(0);
1420:
1421: assert(MDOC_TEXT == n->type);
1422:
1423: if (strcmp(n->string, "#include")) {
1424: PAIR_CLASS_INIT(&tag[0], "macro");
1425: print_otag(h, TAG_B, 1, tag);
1426: return(1);
1427: }
1428:
1429: PAIR_CLASS_INIT(&tag[0], "includes");
1430: print_otag(h, TAG_B, 1, tag);
1431: print_text(h, n->string);
1432:
1433: if (NULL != (n = n->next)) {
1434: assert(MDOC_TEXT == n->type);
1435: strlcpy(buf, '<' == *n->string || '"' == *n->string ?
1436: n->string + 1 : n->string, BUFSIZ);
1437:
1438: sz = strlen(buf);
1439: if (sz && ('>' == buf[sz - 1] || '"' == buf[sz - 1]))
1440: buf[sz - 1] = '\0';
1441:
1442: PAIR_CLASS_INIT(&tag[0], "link-includes");
1443:
1444: i = 1;
1445: if (h->base_includes) {
1446: buffmt_includes(h, buf);
1447: PAIR_HREF_INIT(&tag[i], h->buf);
1448: i++;
1449: }
1450:
1451: t = print_otag(h, TAG_A, i, tag);
1452: print_text(h, n->string);
1453: print_tagq(h, t);
1454:
1455: n = n->next;
1456: }
1457:
1458: for ( ; n; n = n->next) {
1459: assert(MDOC_TEXT == n->type);
1460: print_text(h, n->string);
1461: }
1462:
1463: return(0);
1.1 schwarze 1464: }
1465:
1466:
1467: /* ARGSUSED */
1468: static int
1469: mdoc_vt_pre(MDOC_ARGS)
1470: {
1471: struct htmlpair tag;
1472:
1.21 schwarze 1473: if (MDOC_BLOCK == n->type) {
1474: synopsis_pre(h, n);
1.7 schwarze 1475: return(1);
1.21 schwarze 1476: } else if (MDOC_ELEM == n->type) {
1477: synopsis_pre(h, n);
1.7 schwarze 1478: } else if (MDOC_HEAD == n->type)
1479: return(0);
1.1 schwarze 1480:
1481: PAIR_CLASS_INIT(&tag, "type");
1482: print_otag(h, TAG_SPAN, 1, &tag);
1483: return(1);
1484: }
1485:
1486:
1487: /* ARGSUSED */
1488: static int
1489: mdoc_ft_pre(MDOC_ARGS)
1490: {
1491: struct htmlpair tag;
1492:
1.21 schwarze 1493: synopsis_pre(h, n);
1.1 schwarze 1494: PAIR_CLASS_INIT(&tag, "ftype");
1.42 schwarze 1495: print_otag(h, TAG_I, 1, &tag);
1.1 schwarze 1496: return(1);
1497: }
1498:
1499:
1500: /* ARGSUSED */
1501: static int
1502: mdoc_fn_pre(MDOC_ARGS)
1503: {
1.56 schwarze 1504: struct tag *t;
1505: struct htmlpair tag[2];
1506: char nbuf[BUFSIZ];
1507: const char *sp, *ep;
1508: int sz, i, pretty;
1.1 schwarze 1509:
1.56 schwarze 1510: pretty = MDOC_SYNPRETTY & n->flags;
1.21 schwarze 1511: synopsis_pre(h, n);
1.1 schwarze 1512:
1513: /* Split apart into type and name. */
1514: assert(n->child->string);
1515: sp = n->child->string;
1516:
1517: ep = strchr(sp, ' ');
1518: if (NULL != ep) {
1519: PAIR_CLASS_INIT(&tag[0], "ftype");
1.42 schwarze 1520: t = print_otag(h, TAG_I, 1, tag);
1.1 schwarze 1521:
1522: while (ep) {
1523: sz = MIN((int)(ep - sp), BUFSIZ - 1);
1524: (void)memcpy(nbuf, sp, (size_t)sz);
1525: nbuf[sz] = '\0';
1526: print_text(h, nbuf);
1527: sp = ++ep;
1528: ep = strchr(sp, ' ');
1529: }
1530: print_tagq(h, t);
1531: }
1532:
1533: PAIR_CLASS_INIT(&tag[0], "fname");
1.11 schwarze 1534:
1535: /*
1536: * FIXME: only refer to IDs that we know exist.
1537: */
1538:
1539: #if 0
1.23 schwarze 1540: if (MDOC_SYNPRETTY & n->flags) {
1.11 schwarze 1541: nbuf[0] = '\0';
1542: html_idcat(nbuf, sp, BUFSIZ);
1543: PAIR_ID_INIT(&tag[1], nbuf);
1544: } else {
1545: strlcpy(nbuf, "#", BUFSIZ);
1546: html_idcat(nbuf, sp, BUFSIZ);
1547: PAIR_HREF_INIT(&tag[1], nbuf);
1548: }
1549: #endif
1550:
1.42 schwarze 1551: t = print_otag(h, TAG_B, 1, tag);
1.1 schwarze 1552:
1553: if (sp) {
1.11 schwarze 1554: strlcpy(nbuf, sp, BUFSIZ);
1.1 schwarze 1555: print_text(h, nbuf);
1556: }
1557:
1558: print_tagq(h, t);
1559:
1560: h->flags |= HTML_NOSPACE;
1561: print_text(h, "(");
1.56 schwarze 1562: h->flags |= HTML_NOSPACE;
1.1 schwarze 1563:
1.57 schwarze 1564: PAIR_CLASS_INIT(&tag[0], "farg");
1.1 schwarze 1565: bufinit(h);
1566: bufcat_style(h, "white-space", "nowrap");
1567: PAIR_STYLE_INIT(&tag[1], h);
1568:
1.56 schwarze 1569: for (n = n->child->next; n; n = n->next) {
1.1 schwarze 1570: i = 1;
1.23 schwarze 1571: if (MDOC_SYNPRETTY & n->flags)
1.1 schwarze 1572: i = 2;
1.42 schwarze 1573: t = print_otag(h, TAG_I, i, tag);
1.56 schwarze 1574: print_text(h, n->string);
1.1 schwarze 1575: print_tagq(h, t);
1.56 schwarze 1576: if (n->next) {
1577: h->flags |= HTML_NOSPACE;
1.1 schwarze 1578: print_text(h, ",");
1.56 schwarze 1579: }
1.1 schwarze 1580: }
1581:
1.56 schwarze 1582: h->flags |= HTML_NOSPACE;
1.1 schwarze 1583: print_text(h, ")");
1.56 schwarze 1584:
1585: if (pretty) {
1586: h->flags |= HTML_NOSPACE;
1.1 schwarze 1587: print_text(h, ";");
1.56 schwarze 1588: }
1.1 schwarze 1589:
1590: return(0);
1591: }
1592:
1593:
1594: /* ARGSUSED */
1595: static int
1.26 schwarze 1596: mdoc_sm_pre(MDOC_ARGS)
1597: {
1598:
1599: assert(n->child && MDOC_TEXT == n->child->type);
1600: if (0 == strcmp("on", n->child->string)) {
1.36 schwarze 1601: /*
1602: * FIXME: no p->col to check. Thus, if we have
1603: * .Bd -literal
1604: * .Sm off
1605: * 1 2
1606: * .Sm on
1607: * 3
1608: * .Ed
1609: * the "3" is preceded by a space.
1610: */
1.26 schwarze 1611: h->flags &= ~HTML_NOSPACE;
1612: h->flags &= ~HTML_NONOSPACE;
1613: } else
1614: h->flags |= HTML_NONOSPACE;
1615:
1616: return(0);
1617: }
1618:
1.40 schwarze 1619: /* ARGSUSED */
1620: static int
1621: mdoc_pp_pre(MDOC_ARGS)
1622: {
1623:
1624: print_otag(h, TAG_P, 0, NULL);
1625: return(0);
1626:
1627: }
1.26 schwarze 1628:
1629: /* ARGSUSED */
1630: static int
1.1 schwarze 1631: mdoc_sp_pre(MDOC_ARGS)
1632: {
1.40 schwarze 1633: struct roffsu su;
1.1 schwarze 1634: struct htmlpair tag;
1635:
1.40 schwarze 1636: SCALE_VS_INIT(&su, 1);
1637:
1638: if (MDOC_sp == n->tok) {
1.59 schwarze 1639: if (NULL != (n = n->child))
1640: if ( ! a2roffsu(n->string, &su, SCALE_VS))
1641: SCALE_VS_INIT(&su, atoi(n->string));
1.40 schwarze 1642: } else
1643: su.scale = 0;
1.1 schwarze 1644:
1.57 schwarze 1645: bufinit(h);
1.1 schwarze 1646: bufcat_su(h, "height", &su);
1647: PAIR_STYLE_INIT(&tag, h);
1648: print_otag(h, TAG_DIV, 1, &tag);
1.40 schwarze 1649:
1.3 schwarze 1650: /* So the div isn't empty: */
1651: print_text(h, "\\~");
1652:
1653: return(0);
1.1 schwarze 1654:
1655: }
1656:
1657: /* ARGSUSED */
1658: static int
1659: mdoc_lk_pre(MDOC_ARGS)
1660: {
1.56 schwarze 1661: struct htmlpair tag[2];
1662:
1663: if (NULL == (n = n->child))
1664: return(0);
1.1 schwarze 1665:
1.56 schwarze 1666: assert(MDOC_TEXT == n->type);
1.1 schwarze 1667:
1668: PAIR_CLASS_INIT(&tag[0], "link-ext");
1.56 schwarze 1669: PAIR_HREF_INIT(&tag[1], n->string);
1670:
1.1 schwarze 1671: print_otag(h, TAG_A, 2, tag);
1672:
1.58 schwarze 1673: if (NULL == n->next)
1674: print_text(h, n->string);
1675:
1676: for (n = n->next; n; n = n->next)
1.56 schwarze 1677: print_text(h, n->string);
1.1 schwarze 1678:
1679: return(0);
1680: }
1681:
1682:
1683: /* ARGSUSED */
1684: static int
1685: mdoc_mt_pre(MDOC_ARGS)
1686: {
1.56 schwarze 1687: struct htmlpair tag[2];
1688: struct tag *t;
1.1 schwarze 1689:
1690: PAIR_CLASS_INIT(&tag[0], "link-mail");
1691:
1.56 schwarze 1692: for (n = n->child; n; n = n->next) {
1693: assert(MDOC_TEXT == n->type);
1694:
1.1 schwarze 1695: bufinit(h);
1696: bufcat(h, "mailto:");
1.56 schwarze 1697: bufcat(h, n->string);
1698:
1.10 schwarze 1699: PAIR_HREF_INIT(&tag[1], h->buf);
1.1 schwarze 1700: t = print_otag(h, TAG_A, 2, tag);
1.56 schwarze 1701: print_text(h, n->string);
1.1 schwarze 1702: print_tagq(h, t);
1703: }
1704:
1705: return(0);
1706: }
1707:
1708:
1709: /* ARGSUSED */
1710: static int
1711: mdoc_fo_pre(MDOC_ARGS)
1712: {
1.20 schwarze 1713: struct htmlpair tag;
1714: struct tag *t;
1.1 schwarze 1715:
1716: if (MDOC_BODY == n->type) {
1717: h->flags |= HTML_NOSPACE;
1718: print_text(h, "(");
1719: h->flags |= HTML_NOSPACE;
1720: return(1);
1.20 schwarze 1721: } else if (MDOC_BLOCK == n->type) {
1.21 schwarze 1722: synopsis_pre(h, n);
1.1 schwarze 1723: return(1);
1.11 schwarze 1724: }
1.1 schwarze 1725:
1.20 schwarze 1726: /* XXX: we drop non-initial arguments as per groff. */
1727:
1728: assert(n->child);
1729: assert(n->child->string);
1730:
1.1 schwarze 1731: PAIR_CLASS_INIT(&tag, "fname");
1.43 schwarze 1732: t = print_otag(h, TAG_B, 1, &tag);
1.20 schwarze 1733: print_text(h, n->child->string);
1734: print_tagq(h, t);
1735: return(0);
1.1 schwarze 1736: }
1737:
1738:
1739: /* ARGSUSED */
1740: static void
1741: mdoc_fo_post(MDOC_ARGS)
1742: {
1.21 schwarze 1743:
1.1 schwarze 1744: if (MDOC_BODY != n->type)
1745: return;
1.56 schwarze 1746: h->flags |= HTML_NOSPACE;
1.1 schwarze 1747: print_text(h, ")");
1.56 schwarze 1748: h->flags |= HTML_NOSPACE;
1.1 schwarze 1749: print_text(h, ";");
1750: }
1751:
1752:
1753: /* ARGSUSED */
1754: static int
1755: mdoc_in_pre(MDOC_ARGS)
1756: {
1.56 schwarze 1757: struct tag *t;
1758: struct htmlpair tag[2];
1759: int i;
1.1 schwarze 1760:
1.21 schwarze 1761: synopsis_pre(h, n);
1762:
1.1 schwarze 1763: PAIR_CLASS_INIT(&tag[0], "includes");
1.42 schwarze 1764: print_otag(h, TAG_B, 1, tag);
1.1 schwarze 1765:
1.56 schwarze 1766: /*
1767: * The first argument of the `In' gets special treatment as
1768: * being a linked value. Subsequent values are printed
1769: * afterward. groff does similarly. This also handles the case
1770: * of no children.
1771: */
1772:
1.23 schwarze 1773: if (MDOC_SYNPRETTY & n->flags && MDOC_LINE & n->flags)
1.1 schwarze 1774: print_text(h, "#include");
1775:
1776: print_text(h, "<");
1777: h->flags |= HTML_NOSPACE;
1778:
1.56 schwarze 1779: if (NULL != (n = n->child)) {
1780: assert(MDOC_TEXT == n->type);
1781:
1.1 schwarze 1782: PAIR_CLASS_INIT(&tag[0], "link-includes");
1.56 schwarze 1783:
1.1 schwarze 1784: i = 1;
1785: if (h->base_includes) {
1.56 schwarze 1786: buffmt_includes(h, n->string);
1.11 schwarze 1787: PAIR_HREF_INIT(&tag[i], h->buf);
1788: i++;
1.56 schwarze 1789: }
1790:
1.1 schwarze 1791: t = print_otag(h, TAG_A, i, tag);
1.56 schwarze 1792: print_text(h, n->string);
1.1 schwarze 1793: print_tagq(h, t);
1.56 schwarze 1794:
1795: n = n->next;
1.1 schwarze 1796: }
1797:
1798: h->flags |= HTML_NOSPACE;
1799: print_text(h, ">");
1.20 schwarze 1800:
1.56 schwarze 1801: for ( ; n; n = n->next) {
1802: assert(MDOC_TEXT == n->type);
1803: print_text(h, n->string);
1804: }
1805:
1.1 schwarze 1806: return(0);
1807: }
1808:
1809:
1810: /* ARGSUSED */
1811: static int
1812: mdoc_ic_pre(MDOC_ARGS)
1813: {
1814: struct htmlpair tag;
1815:
1816: PAIR_CLASS_INIT(&tag, "cmd");
1.42 schwarze 1817: print_otag(h, TAG_B, 1, &tag);
1.1 schwarze 1818: return(1);
1819: }
1820:
1821:
1822: /* ARGSUSED */
1823: static int
1824: mdoc_rv_pre(MDOC_ARGS)
1825: {
1.56 schwarze 1826: struct htmlpair tag;
1827: struct tag *t;
1828: int nchild;
1.1 schwarze 1829:
1.40 schwarze 1830: if (n->prev)
1831: print_otag(h, TAG_BR, 0, NULL);
1832:
1.56 schwarze 1833: PAIR_CLASS_INIT(&tag, "fname");
1834:
1.1 schwarze 1835: print_text(h, "The");
1836:
1.56 schwarze 1837: nchild = n->nchild;
1838: for (n = n->child; n; n = n->next) {
1839: assert(MDOC_TEXT == n->type);
1840:
1.43 schwarze 1841: t = print_otag(h, TAG_B, 1, &tag);
1.56 schwarze 1842: print_text(h, n->string);
1.1 schwarze 1843: print_tagq(h, t);
1844:
1845: h->flags |= HTML_NOSPACE;
1.56 schwarze 1846: print_text(h, "()");
1847:
1848: if (nchild > 2 && n->next) {
1849: h->flags |= HTML_NOSPACE;
1850: print_text(h, ",");
1851: }
1852:
1853: if (n->next && NULL == n->next->next)
1854: print_text(h, "and");
1.1 schwarze 1855: }
1856:
1.56 schwarze 1857: if (nchild > 1)
1.1 schwarze 1858: print_text(h, "functions return");
1859: else
1860: print_text(h, "function returns");
1861:
1862: print_text(h, "the value 0 if successful; otherwise the value "
1863: "-1 is returned and the global variable");
1864:
1865: PAIR_CLASS_INIT(&tag, "var");
1.42 schwarze 1866: t = print_otag(h, TAG_B, 1, &tag);
1.1 schwarze 1867: print_text(h, "errno");
1868: print_tagq(h, t);
1869: print_text(h, "is set to indicate the error.");
1870: return(0);
1871: }
1872:
1873:
1874: /* ARGSUSED */
1875: static int
1876: mdoc_va_pre(MDOC_ARGS)
1877: {
1878: struct htmlpair tag;
1879:
1880: PAIR_CLASS_INIT(&tag, "var");
1.42 schwarze 1881: print_otag(h, TAG_B, 1, &tag);
1.1 schwarze 1882: return(1);
1883: }
1884:
1885:
1886: /* ARGSUSED */
1887: static int
1888: mdoc_ap_pre(MDOC_ARGS)
1889: {
1890:
1891: h->flags |= HTML_NOSPACE;
1892: print_text(h, "\\(aq");
1893: h->flags |= HTML_NOSPACE;
1894: return(1);
1895: }
1896:
1897:
1898: /* ARGSUSED */
1899: static int
1900: mdoc_bf_pre(MDOC_ARGS)
1901: {
1902: struct htmlpair tag[2];
1903: struct roffsu su;
1904:
1905: if (MDOC_HEAD == n->type)
1906: return(0);
1.25 schwarze 1907: else if (MDOC_BODY != n->type)
1.1 schwarze 1908: return(1);
1909:
1.44 schwarze 1910: if (FONT_Em == n->norm->Bf.font)
1.25 schwarze 1911: PAIR_CLASS_INIT(&tag[0], "emph");
1.44 schwarze 1912: else if (FONT_Sy == n->norm->Bf.font)
1.25 schwarze 1913: PAIR_CLASS_INIT(&tag[0], "symb");
1.44 schwarze 1914: else if (FONT_Li == n->norm->Bf.font)
1.25 schwarze 1915: PAIR_CLASS_INIT(&tag[0], "lit");
1916: else
1917: PAIR_CLASS_INIT(&tag[0], "none");
1.1 schwarze 1918:
1.25 schwarze 1919: /*
1920: * We want this to be inline-formatted, but needs to be div to
1921: * accept block children.
1922: */
1.57 schwarze 1923: bufinit(h);
1.1 schwarze 1924: bufcat_style(h, "display", "inline");
1925: SCALE_HS_INIT(&su, 1);
1.25 schwarze 1926: /* Needs a left-margin for spacing. */
1927: bufcat_su(h, "margin-left", &su);
1.1 schwarze 1928: PAIR_STYLE_INIT(&tag[1], h);
1929: print_otag(h, TAG_DIV, 2, tag);
1930: return(1);
1931: }
1932:
1933:
1934: /* ARGSUSED */
1935: static int
1936: mdoc_ms_pre(MDOC_ARGS)
1937: {
1938: struct htmlpair tag;
1939:
1940: PAIR_CLASS_INIT(&tag, "symb");
1941: print_otag(h, TAG_SPAN, 1, &tag);
1942: return(1);
1943: }
1944:
1945:
1946: /* ARGSUSED */
1947: static int
1.34 schwarze 1948: mdoc_igndelim_pre(MDOC_ARGS)
1.1 schwarze 1949: {
1950:
1951: h->flags |= HTML_IGNDELIM;
1952: return(1);
1953: }
1954:
1955:
1956: /* ARGSUSED */
1957: static void
1958: mdoc_pf_post(MDOC_ARGS)
1959: {
1960:
1961: h->flags |= HTML_NOSPACE;
1962: }
1963:
1964:
1965: /* ARGSUSED */
1966: static int
1967: mdoc_rs_pre(MDOC_ARGS)
1968: {
1969: struct htmlpair tag;
1970:
1971: if (MDOC_BLOCK != n->type)
1972: return(1);
1973:
1.40 schwarze 1974: if (n->prev && SEC_SEE_ALSO == n->sec)
1975: print_otag(h, TAG_P, 0, NULL);
1.1 schwarze 1976:
1977: PAIR_CLASS_INIT(&tag, "ref");
1978: print_otag(h, TAG_SPAN, 1, &tag);
1979: return(1);
1980: }
1981:
1982:
1983:
1984: /* ARGSUSED */
1985: static int
1986: mdoc_li_pre(MDOC_ARGS)
1987: {
1988: struct htmlpair tag;
1989:
1990: PAIR_CLASS_INIT(&tag, "lit");
1.61 schwarze 1991: print_otag(h, TAG_CODE, 1, &tag);
1.1 schwarze 1992: return(1);
1993: }
1994:
1995:
1996: /* ARGSUSED */
1997: static int
1998: mdoc_sy_pre(MDOC_ARGS)
1999: {
2000: struct htmlpair tag;
2001:
2002: PAIR_CLASS_INIT(&tag, "symb");
2003: print_otag(h, TAG_SPAN, 1, &tag);
2004: return(1);
2005: }
2006:
2007:
2008: /* ARGSUSED */
2009: static int
2010: mdoc_bt_pre(MDOC_ARGS)
2011: {
2012:
2013: print_text(h, "is currently in beta test.");
2014: return(0);
2015: }
2016:
2017:
2018: /* ARGSUSED */
2019: static int
2020: mdoc_ud_pre(MDOC_ARGS)
2021: {
2022:
2023: print_text(h, "currently under development.");
2024: return(0);
2025: }
2026:
2027:
2028: /* ARGSUSED */
2029: static int
2030: mdoc_lb_pre(MDOC_ARGS)
2031: {
2032: struct htmlpair tag;
2033:
1.40 schwarze 2034: if (SEC_LIBRARY == n->sec && MDOC_LINE & n->flags && n->prev)
2035: print_otag(h, TAG_BR, 0, NULL);
2036:
1.1 schwarze 2037: PAIR_CLASS_INIT(&tag, "lib");
2038: print_otag(h, TAG_SPAN, 1, &tag);
2039: return(1);
2040: }
2041:
2042:
2043: /* ARGSUSED */
2044: static int
2045: mdoc__x_pre(MDOC_ARGS)
2046: {
1.2 schwarze 2047: struct htmlpair tag[2];
1.42 schwarze 2048: enum htmltag t;
2049:
2050: t = TAG_SPAN;
1.1 schwarze 2051:
2052: switch (n->tok) {
2053: case(MDOC__A):
1.2 schwarze 2054: PAIR_CLASS_INIT(&tag[0], "ref-auth");
1.30 schwarze 2055: if (n->prev && MDOC__A == n->prev->tok)
2056: if (NULL == n->next || MDOC__A != n->next->tok)
2057: print_text(h, "and");
1.1 schwarze 2058: break;
2059: case(MDOC__B):
1.2 schwarze 2060: PAIR_CLASS_INIT(&tag[0], "ref-book");
1.42 schwarze 2061: t = TAG_I;
1.1 schwarze 2062: break;
2063: case(MDOC__C):
1.2 schwarze 2064: PAIR_CLASS_INIT(&tag[0], "ref-city");
1.1 schwarze 2065: break;
2066: case(MDOC__D):
1.2 schwarze 2067: PAIR_CLASS_INIT(&tag[0], "ref-date");
1.1 schwarze 2068: break;
2069: case(MDOC__I):
1.2 schwarze 2070: PAIR_CLASS_INIT(&tag[0], "ref-issue");
1.42 schwarze 2071: t = TAG_I;
1.1 schwarze 2072: break;
2073: case(MDOC__J):
1.2 schwarze 2074: PAIR_CLASS_INIT(&tag[0], "ref-jrnl");
1.42 schwarze 2075: t = TAG_I;
1.1 schwarze 2076: break;
2077: case(MDOC__N):
1.2 schwarze 2078: PAIR_CLASS_INIT(&tag[0], "ref-num");
1.1 schwarze 2079: break;
2080: case(MDOC__O):
1.2 schwarze 2081: PAIR_CLASS_INIT(&tag[0], "ref-opt");
1.1 schwarze 2082: break;
2083: case(MDOC__P):
1.2 schwarze 2084: PAIR_CLASS_INIT(&tag[0], "ref-page");
1.1 schwarze 2085: break;
2086: case(MDOC__Q):
1.2 schwarze 2087: PAIR_CLASS_INIT(&tag[0], "ref-corp");
1.1 schwarze 2088: break;
2089: case(MDOC__R):
1.2 schwarze 2090: PAIR_CLASS_INIT(&tag[0], "ref-rep");
1.1 schwarze 2091: break;
2092: case(MDOC__T):
1.2 schwarze 2093: PAIR_CLASS_INIT(&tag[0], "ref-title");
1.1 schwarze 2094: break;
1.2 schwarze 2095: case(MDOC__U):
2096: PAIR_CLASS_INIT(&tag[0], "link-ref");
2097: break;
1.1 schwarze 2098: case(MDOC__V):
1.2 schwarze 2099: PAIR_CLASS_INIT(&tag[0], "ref-vol");
1.1 schwarze 2100: break;
2101: default:
2102: abort();
2103: /* NOTREACHED */
2104: }
2105:
1.2 schwarze 2106: if (MDOC__U != n->tok) {
1.42 schwarze 2107: print_otag(h, t, 1, tag);
1.2 schwarze 2108: return(1);
2109: }
2110:
2111: PAIR_HREF_INIT(&tag[1], n->child->string);
2112: print_otag(h, TAG_A, 2, tag);
1.30 schwarze 2113:
1.1 schwarze 2114: return(1);
2115: }
2116:
2117:
2118: /* ARGSUSED */
2119: static void
2120: mdoc__x_post(MDOC_ARGS)
2121: {
1.30 schwarze 2122:
2123: if (MDOC__A == n->tok && n->next && MDOC__A == n->next->tok)
2124: if (NULL == n->next->next || MDOC__A != n->next->next->tok)
2125: if (NULL == n->prev || MDOC__A != n->prev->tok)
2126: return;
1.1 schwarze 2127:
1.12 schwarze 2128: /* TODO: %U */
2129:
1.31 schwarze 2130: if (NULL == n->parent || MDOC_Rs != n->parent->tok)
2131: return;
2132:
1.56 schwarze 2133: h->flags |= HTML_NOSPACE;
1.1 schwarze 2134: print_text(h, n->next ? "," : ".");
1.25 schwarze 2135: }
2136:
2137:
2138: /* ARGSUSED */
2139: static int
2140: mdoc_bk_pre(MDOC_ARGS)
2141: {
2142:
2143: switch (n->type) {
2144: case (MDOC_BLOCK):
2145: break;
2146: case (MDOC_HEAD):
2147: return(0);
2148: case (MDOC_BODY):
1.41 schwarze 2149: if (n->parent->args || 0 == n->prev->nchild)
2150: h->flags |= HTML_PREKEEP;
1.25 schwarze 2151: break;
2152: default:
2153: abort();
2154: /* NOTREACHED */
2155: }
2156:
2157: return(1);
2158: }
2159:
2160:
2161: /* ARGSUSED */
2162: static void
2163: mdoc_bk_post(MDOC_ARGS)
2164: {
2165:
2166: if (MDOC_BODY == n->type)
2167: h->flags &= ~(HTML_KEEP | HTML_PREKEEP);
1.1 schwarze 2168: }
1.32 schwarze 2169:
2170:
2171: /* ARGSUSED */
2172: static int
2173: mdoc_quote_pre(MDOC_ARGS)
2174: {
2175: struct htmlpair tag;
2176:
2177: if (MDOC_BODY != n->type)
2178: return(1);
2179:
2180: switch (n->tok) {
2181: case (MDOC_Ao):
2182: /* FALLTHROUGH */
2183: case (MDOC_Aq):
2184: print_text(h, "\\(la");
2185: break;
2186: case (MDOC_Bro):
2187: /* FALLTHROUGH */
2188: case (MDOC_Brq):
2189: print_text(h, "\\(lC");
2190: break;
2191: case (MDOC_Bo):
2192: /* FALLTHROUGH */
2193: case (MDOC_Bq):
2194: print_text(h, "\\(lB");
2195: break;
2196: case (MDOC_Oo):
2197: /* FALLTHROUGH */
2198: case (MDOC_Op):
2199: print_text(h, "\\(lB");
1.36 schwarze 2200: h->flags |= HTML_NOSPACE;
1.32 schwarze 2201: PAIR_CLASS_INIT(&tag, "opt");
2202: print_otag(h, TAG_SPAN, 1, &tag);
2203: break;
2204: case (MDOC_Do):
2205: /* FALLTHROUGH */
2206: case (MDOC_Dq):
2207: /* FALLTHROUGH */
2208: case (MDOC_Qo):
2209: /* FALLTHROUGH */
2210: case (MDOC_Qq):
2211: print_text(h, "\\(lq");
2212: break;
2213: case (MDOC_Po):
2214: /* FALLTHROUGH */
2215: case (MDOC_Pq):
2216: print_text(h, "(");
2217: break;
2218: case (MDOC_Ql):
1.61 schwarze 2219: print_text(h, "\\(oq");
2220: h->flags |= HTML_NOSPACE;
2221: PAIR_CLASS_INIT(&tag, "lit");
2222: print_otag(h, TAG_CODE, 1, &tag);
2223: break;
1.32 schwarze 2224: case (MDOC_So):
2225: /* FALLTHROUGH */
2226: case (MDOC_Sq):
2227: print_text(h, "\\(oq");
2228: break;
2229: default:
2230: abort();
2231: /* NOTREACHED */
2232: }
2233:
2234: h->flags |= HTML_NOSPACE;
2235: return(1);
2236: }
2237:
2238:
2239: /* ARGSUSED */
2240: static void
2241: mdoc_quote_post(MDOC_ARGS)
2242: {
2243:
2244: if (MDOC_BODY != n->type)
2245: return;
2246:
2247: h->flags |= HTML_NOSPACE;
2248:
2249: switch (n->tok) {
2250: case (MDOC_Ao):
2251: /* FALLTHROUGH */
2252: case (MDOC_Aq):
2253: print_text(h, "\\(ra");
2254: break;
2255: case (MDOC_Bro):
2256: /* FALLTHROUGH */
2257: case (MDOC_Brq):
2258: print_text(h, "\\(rC");
2259: break;
2260: case (MDOC_Oo):
2261: /* FALLTHROUGH */
2262: case (MDOC_Op):
2263: /* FALLTHROUGH */
2264: case (MDOC_Bo):
2265: /* FALLTHROUGH */
2266: case (MDOC_Bq):
2267: print_text(h, "\\(rB");
2268: break;
2269: case (MDOC_Qo):
2270: /* FALLTHROUGH */
2271: case (MDOC_Qq):
2272: /* FALLTHROUGH */
2273: case (MDOC_Do):
2274: /* FALLTHROUGH */
2275: case (MDOC_Dq):
2276: print_text(h, "\\(rq");
2277: break;
2278: case (MDOC_Po):
2279: /* FALLTHROUGH */
2280: case (MDOC_Pq):
2281: print_text(h, ")");
2282: break;
2283: case (MDOC_Ql):
2284: /* FALLTHROUGH */
2285: case (MDOC_So):
2286: /* FALLTHROUGH */
2287: case (MDOC_Sq):
2288: print_text(h, "\\(aq");
2289: break;
2290: default:
2291: abort();
2292: /* NOTREACHED */
2293: }
2294: }
2295:
2296: