Annotation of mandoc/html.c, Revision 1.41
1.41 ! kristaps 1: /* $Id: html.c,v 1.40 2009/09/20 19:44:16 kristaps Exp $ */
1.1 kristaps 2: /*
1.29 kristaps 3: * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
1.1 kristaps 4: *
5: * Permission to use, copy, modify, and distribute this software for any
1.29 kristaps 6: * purpose with or without fee is hereby granted, provided that the above
7: * copyright notice and this permission notice appear in all copies.
1.1 kristaps 8: *
1.29 kristaps 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.
1.1 kristaps 16: */
1.41 ! kristaps 17: #include <sys/types.h>
1.30 kristaps 18: #include <sys/queue.h>
19:
1.1 kristaps 20: #include <assert.h>
1.33 kristaps 21: #include <ctype.h>
1.4 kristaps 22: #include <err.h>
1.29 kristaps 23: #include <stdio.h>
1.1 kristaps 24: #include <stdlib.h>
1.33 kristaps 25: #include <string.h>
1.1 kristaps 26:
1.32 kristaps 27: #include "chars.h"
1.29 kristaps 28: #include "mdoc.h"
29: #include "man.h"
1.41 ! kristaps 30: #include "out.h"
1.2 kristaps 31:
1.29 kristaps 32: #define DOCTYPE "-//W3C//DTD HTML 4.01//EN"
33: #define DTD "http://www.w3.org/TR/html4/strict.dtd"
1.8 kristaps 34:
1.33 kristaps 35: #define INDENT 5
36: #define HALFINDENT 3
37:
1.29 kristaps 38: enum htmltag {
39: TAG_HTML,
40: TAG_HEAD,
41: TAG_BODY,
42: TAG_META,
43: TAG_TITLE,
44: TAG_DIV,
45: TAG_H1,
46: TAG_H2,
47: TAG_P,
48: TAG_SPAN,
49: TAG_LINK,
1.30 kristaps 50: TAG_BR,
51: TAG_A,
1.33 kristaps 52: TAG_TABLE,
53: TAG_COL,
54: TAG_TR,
55: TAG_TD,
1.34 kristaps 56: TAG_LI,
57: TAG_UL,
58: TAG_OL,
1.41 ! kristaps 59: TAG_BASE,
1.29 kristaps 60: TAG_MAX
1.7 kristaps 61: };
62:
1.29 kristaps 63: enum htmlattr {
64: ATTR_HTTPEQUIV,
65: ATTR_CONTENT,
66: ATTR_NAME,
67: ATTR_REL,
68: ATTR_HREF,
69: ATTR_TYPE,
70: ATTR_MEDIA,
71: ATTR_CLASS,
1.33 kristaps 72: ATTR_STYLE,
73: ATTR_WIDTH,
74: ATTR_VALIGN,
1.29 kristaps 75: ATTR_MAX
1.7 kristaps 76: };
77:
1.29 kristaps 78: struct htmldata {
79: char *name;
80: int flags;
1.30 kristaps 81: #define HTML_CLRLINE (1 << 0)
82: #define HTML_NOSTACK (1 << 1)
1.29 kristaps 83: };
1.7 kristaps 84:
1.29 kristaps 85: static const struct htmldata htmltags[TAG_MAX] = {
1.30 kristaps 86: {"html", HTML_CLRLINE}, /* TAG_HTML */
87: {"head", HTML_CLRLINE}, /* TAG_HEAD */
88: {"body", HTML_CLRLINE}, /* TAG_BODY */
89: {"meta", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_META */
1.33 kristaps 90: {"title", HTML_CLRLINE}, /* TAG_TITLE */
1.30 kristaps 91: {"div", HTML_CLRLINE}, /* TAG_DIV */
1.29 kristaps 92: {"h1", 0}, /* TAG_H1 */
93: {"h2", 0}, /* TAG_H2 */
1.30 kristaps 94: {"p", HTML_CLRLINE}, /* TAG_P */
1.29 kristaps 95: {"span", 0}, /* TAG_SPAN */
1.30 kristaps 96: {"link", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_LINK */
97: {"br", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_LINK */
98: {"a", 0}, /* TAG_A */
1.33 kristaps 99: {"table", HTML_CLRLINE}, /* TAG_TABLE */
100: {"col", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_COL */
101: {"tr", HTML_CLRLINE}, /* TAG_TR */
102: {"td", HTML_CLRLINE}, /* TAG_TD */
1.34 kristaps 103: {"li", HTML_CLRLINE}, /* TAG_LI */
104: {"ul", HTML_CLRLINE}, /* TAG_UL */
105: {"ol", HTML_CLRLINE}, /* TAG_OL */
1.41 ! kristaps 106: {"base", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_BASE */
1.29 kristaps 107: };
1.10 kristaps 108:
1.29 kristaps 109: static const char *const htmlattrs[ATTR_MAX] = {
110: "http-equiv",
111: "content",
112: "name",
113: "rel",
114: "href",
115: "type",
116: "media",
1.33 kristaps 117: "class",
118: "style",
119: "width",
120: "valign",
1.29 kristaps 121: };
1.10 kristaps 122:
1.29 kristaps 123: struct htmlpair {
124: enum htmlattr key;
125: char *val;
126: };
1.10 kristaps 127:
1.30 kristaps 128: struct tag {
129: enum htmltag tag;
130: SLIST_ENTRY(tag) entry;
131: };
132:
1.37 kristaps 133: struct ord {
134: int pos;
135: const void *cookie;
136: SLIST_ENTRY(ord) entry;
137: };
138:
1.30 kristaps 139: SLIST_HEAD(tagq, tag);
1.37 kristaps 140: SLIST_HEAD(ordq, ord);
1.30 kristaps 141:
1.29 kristaps 142: struct html {
143: int flags;
144: #define HTML_NOSPACE (1 << 0)
1.30 kristaps 145: #define HTML_NEWLINE (1 << 1)
1.37 kristaps 146: struct tagq tags;
147: struct ordq ords;
1.32 kristaps 148: void *symtab;
1.41 ! kristaps 149: char *base;
! 150: char *style;
1.29 kristaps 151: };
1.10 kristaps 152:
1.29 kristaps 153: #define MDOC_ARGS const struct mdoc_meta *m, \
154: const struct mdoc_node *n, \
155: struct html *h
156: #define MAN_ARGS const struct man_meta *m, \
157: const struct man_node *n, \
158: struct html *h
159: struct htmlmdoc {
160: int (*pre)(MDOC_ARGS);
161: void (*post)(MDOC_ARGS);
162: };
1.13 kristaps 163:
1.29 kristaps 164: static void print_gen_doctype(struct html *);
165: static void print_gen_head(struct html *);
166: static void print_mdoc(MDOC_ARGS);
167: static void print_mdoc_head(MDOC_ARGS);
168: static void print_mdoc_node(MDOC_ARGS);
1.39 kristaps 169: static void print_mdoc_nodelist(MDOC_ARGS);
1.29 kristaps 170: static void print_man(MAN_ARGS);
171: static void print_man_head(MAN_ARGS);
1.30 kristaps 172: static struct tag *print_otag(struct html *, enum htmltag,
1.29 kristaps 173: int, const struct htmlpair *);
1.30 kristaps 174: static void print_tagq(struct html *, const struct tag *);
175: static void print_stagq(struct html *, const struct tag *);
1.29 kristaps 176: static void print_ctag(struct html *, enum htmltag);
1.32 kristaps 177: static void print_encode(struct html *, const char *);
178: static void print_escape(struct html *, const char **);
1.29 kristaps 179: static void print_text(struct html *, const char *);
1.32 kristaps 180: static void print_res(struct html *, const char *, int);
181: static void print_spec(struct html *, const char *, int);
1.33 kristaps 182:
1.39 kristaps 183: static void mdoc_root_post(MDOC_ARGS);
1.29 kristaps 184: static int mdoc_root_pre(MDOC_ARGS);
1.34 kristaps 185: static int mdoc_tbl_pre(MDOC_ARGS, int);
1.37 kristaps 186: static int mdoc_tbl_block_pre(MDOC_ARGS, int, int, int, int);
1.34 kristaps 187: static int mdoc_tbl_body_pre(MDOC_ARGS, int, int);
188: static int mdoc_tbl_head_pre(MDOC_ARGS, int, int);
1.29 kristaps 189:
1.41 ! kristaps 190: static int mdoc_ad_pre(MDOC_ARGS);
! 191: static int mdoc_an_pre(MDOC_ARGS);
1.37 kristaps 192: static void mdoc_aq_post(MDOC_ARGS);
193: static int mdoc_aq_pre(MDOC_ARGS);
1.31 kristaps 194: static int mdoc_ar_pre(MDOC_ARGS);
1.39 kristaps 195: static int mdoc_bd_pre(MDOC_ARGS);
1.37 kristaps 196: static void mdoc_bl_post(MDOC_ARGS);
1.33 kristaps 197: static int mdoc_bl_pre(MDOC_ARGS);
1.41 ! kristaps 198: static int mdoc_cd_pre(MDOC_ARGS);
1.34 kristaps 199: static int mdoc_d1_pre(MDOC_ARGS);
200: static void mdoc_dq_post(MDOC_ARGS);
201: static int mdoc_dq_pre(MDOC_ARGS);
1.41 ! kristaps 202: static int mdoc_dv_pre(MDOC_ARGS);
! 203: static int mdoc_fa_pre(MDOC_ARGS);
! 204: static int mdoc_fd_pre(MDOC_ARGS);
1.30 kristaps 205: static int mdoc_fl_pre(MDOC_ARGS);
1.41 ! kristaps 206: static int mdoc_fn_pre(MDOC_ARGS);
! 207: static int mdoc_ft_pre(MDOC_ARGS);
1.34 kristaps 208: static int mdoc_em_pre(MDOC_ARGS);
1.41 ! kristaps 209: static int mdoc_er_pre(MDOC_ARGS);
! 210: static int mdoc_ev_pre(MDOC_ARGS);
1.34 kristaps 211: static int mdoc_ex_pre(MDOC_ARGS);
1.33 kristaps 212: static int mdoc_it_pre(MDOC_ARGS);
1.29 kristaps 213: static int mdoc_nd_pre(MDOC_ARGS);
214: static int mdoc_nm_pre(MDOC_ARGS);
1.31 kristaps 215: static int mdoc_ns_pre(MDOC_ARGS);
1.34 kristaps 216: static void mdoc_op_post(MDOC_ARGS);
1.30 kristaps 217: static int mdoc_op_pre(MDOC_ARGS);
1.39 kristaps 218: static int mdoc_pa_pre(MDOC_ARGS);
1.29 kristaps 219: static int mdoc_pp_pre(MDOC_ARGS);
1.34 kristaps 220: static void mdoc_pq_post(MDOC_ARGS);
221: static int mdoc_pq_pre(MDOC_ARGS);
1.39 kristaps 222: static void mdoc_qq_post(MDOC_ARGS);
223: static int mdoc_qq_pre(MDOC_ARGS);
1.29 kristaps 224: static int mdoc_sh_pre(MDOC_ARGS);
1.34 kristaps 225: static void mdoc_sq_post(MDOC_ARGS);
226: static int mdoc_sq_pre(MDOC_ARGS);
1.29 kristaps 227: static int mdoc_ss_pre(MDOC_ARGS);
1.34 kristaps 228: static int mdoc_sx_pre(MDOC_ARGS);
1.41 ! kristaps 229: static int mdoc_vt_pre(MDOC_ARGS);
1.30 kristaps 230: static int mdoc_xr_pre(MDOC_ARGS);
1.33 kristaps 231: static int mdoc_xx_pre(MDOC_ARGS);
232:
233: #ifdef __linux__
1.35 kristaps 234: extern size_t strlcpy(char *, const char *, size_t);
235: extern size_t strlcat(char *, const char *, size_t);
1.33 kristaps 236: #endif
1.29 kristaps 237:
238: static const struct htmlmdoc mdocs[MDOC_MAX] = {
1.39 kristaps 239: {mdoc_pp_pre, NULL}, /* Ap */
1.29 kristaps 240: {NULL, NULL}, /* Dd */
241: {NULL, NULL}, /* Dt */
242: {NULL, NULL}, /* Os */
1.30 kristaps 243: {mdoc_sh_pre, NULL }, /* Sh */
244: {mdoc_ss_pre, NULL }, /* Ss */
1.29 kristaps 245: {mdoc_pp_pre, NULL}, /* Pp */
1.34 kristaps 246: {mdoc_d1_pre, NULL}, /* D1 */
247: {mdoc_d1_pre, NULL}, /* Dl */
1.39 kristaps 248: {mdoc_bd_pre, NULL}, /* Bd */
1.29 kristaps 249: {NULL, NULL}, /* Ed */
1.37 kristaps 250: {mdoc_bl_pre, mdoc_bl_post}, /* Bl */
1.29 kristaps 251: {NULL, NULL}, /* El */
1.33 kristaps 252: {mdoc_it_pre, NULL}, /* It */
1.41 ! kristaps 253: {mdoc_ad_pre, NULL}, /* Ad */
! 254: {mdoc_an_pre, NULL}, /* An */
1.31 kristaps 255: {mdoc_ar_pre, NULL}, /* Ar */
1.41 ! kristaps 256: {mdoc_cd_pre, NULL}, /* Cd */
! 257: {mdoc_fl_pre, NULL}, /* Cm */
! 258: {mdoc_dv_pre, NULL}, /* Dv */
! 259: {mdoc_er_pre, NULL}, /* Er */
! 260: {mdoc_ev_pre, NULL}, /* Ev */
1.34 kristaps 261: {mdoc_ex_pre, NULL}, /* Ex */
1.41 ! kristaps 262: {mdoc_fa_pre, NULL}, /* Fa */
! 263: {mdoc_fd_pre, NULL}, /* Fd */
1.30 kristaps 264: {mdoc_fl_pre, NULL}, /* Fl */
1.41 ! kristaps 265: {mdoc_fn_pre, NULL}, /* Fn */
! 266: {mdoc_ft_pre, NULL}, /* Ft */
1.29 kristaps 267: {NULL, NULL}, /* Ic */
268: {NULL, NULL}, /* In */
269: {NULL, NULL}, /* Li */
270: {mdoc_nd_pre, NULL}, /* Nd */
1.30 kristaps 271: {mdoc_nm_pre, NULL}, /* Nm */
272: {mdoc_op_pre, mdoc_op_post}, /* Op */
1.29 kristaps 273: {NULL, NULL}, /* Ot */
1.39 kristaps 274: {mdoc_pa_pre, NULL}, /* Pa */
1.29 kristaps 275: {NULL, NULL}, /* Rv */
276: {NULL, NULL}, /* St */
277: {NULL, NULL}, /* Va */
1.41 ! kristaps 278: {mdoc_vt_pre, NULL}, /* Vt */
1.30 kristaps 279: {mdoc_xr_pre, NULL}, /* Xr */
1.29 kristaps 280: {NULL, NULL}, /* %A */
281: {NULL, NULL}, /* %B */
282: {NULL, NULL}, /* %D */
283: {NULL, NULL}, /* %I */
284: {NULL, NULL}, /* %J */
285: {NULL, NULL}, /* %N */
286: {NULL, NULL}, /* %O */
287: {NULL, NULL}, /* %P */
288: {NULL, NULL}, /* %R */
289: {NULL, NULL}, /* %T */
290: {NULL, NULL}, /* %V */
291: {NULL, NULL}, /* Ac */
1.37 kristaps 292: {mdoc_aq_pre, mdoc_aq_post}, /* Ao */
293: {mdoc_aq_pre, mdoc_aq_post}, /* Aq */
1.29 kristaps 294: {NULL, NULL}, /* At */
295: {NULL, NULL}, /* Bc */
296: {NULL, NULL}, /* Bf */
297: {NULL, NULL}, /* Bo */
298: {NULL, NULL}, /* Bq */
1.33 kristaps 299: {mdoc_xx_pre, NULL}, /* Bsx */
1.29 kristaps 300: {NULL, NULL}, /* Bx */
301: {NULL, NULL}, /* Db */
302: {NULL, NULL}, /* Dc */
303: {NULL, NULL}, /* Do */
1.34 kristaps 304: {mdoc_dq_pre, mdoc_dq_post}, /* Dq */
1.29 kristaps 305: {NULL, NULL}, /* Ec */
306: {NULL, NULL}, /* Ef */
1.34 kristaps 307: {mdoc_em_pre, NULL}, /* Em */
1.29 kristaps 308: {NULL, NULL}, /* Eo */
1.33 kristaps 309: {mdoc_xx_pre, NULL}, /* Fx */
1.29 kristaps 310: {NULL, NULL}, /* Ms */
311: {NULL, NULL}, /* No */
1.31 kristaps 312: {mdoc_ns_pre, NULL}, /* Ns */
1.33 kristaps 313: {mdoc_xx_pre, NULL}, /* Nx */
314: {mdoc_xx_pre, NULL}, /* Ox */
1.29 kristaps 315: {NULL, NULL}, /* Pc */
316: {NULL, NULL}, /* Pf */
1.34 kristaps 317: {mdoc_pq_pre, mdoc_pq_post}, /* Po */
318: {mdoc_pq_pre, mdoc_pq_post}, /* Pq */
1.29 kristaps 319: {NULL, NULL}, /* Qc */
320: {NULL, NULL}, /* Ql */
1.39 kristaps 321: {mdoc_qq_pre, mdoc_qq_post}, /* Qo */
322: {mdoc_qq_pre, mdoc_qq_post}, /* Qq */
1.29 kristaps 323: {NULL, NULL}, /* Re */
324: {NULL, NULL}, /* Rs */
325: {NULL, NULL}, /* Sc */
1.34 kristaps 326: {mdoc_sq_pre, mdoc_sq_post}, /* So */
327: {mdoc_sq_pre, mdoc_sq_post}, /* Sq */
1.29 kristaps 328: {NULL, NULL}, /* Sm */
1.34 kristaps 329: {mdoc_sx_pre, NULL}, /* Sx */
1.29 kristaps 330: {NULL, NULL}, /* Sy */
331: {NULL, NULL}, /* Tn */
1.33 kristaps 332: {mdoc_xx_pre, NULL}, /* Ux */
1.29 kristaps 333: {NULL, NULL}, /* Xc */
334: {NULL, NULL}, /* Xo */
335: {NULL, NULL}, /* Fo */
336: {NULL, NULL}, /* Fc */
337: {NULL, NULL}, /* Oo */
338: {NULL, NULL}, /* Oc */
339: {NULL, NULL}, /* Bk */
340: {NULL, NULL}, /* Ek */
341: {NULL, NULL}, /* Bt */
342: {NULL, NULL}, /* Hf */
343: {NULL, NULL}, /* Fr */
344: {NULL, NULL}, /* Ud */
345: {NULL, NULL}, /* Lb */
346: {NULL, NULL}, /* Lp */
347: {NULL, NULL}, /* Lk */
348: {NULL, NULL}, /* Mt */
349: {NULL, NULL}, /* Brq */
350: {NULL, NULL}, /* Bro */
351: {NULL, NULL}, /* Brc */
352: {NULL, NULL}, /* %C */
353: {NULL, NULL}, /* Es */
354: {NULL, NULL}, /* En */
1.33 kristaps 355: {mdoc_xx_pre, NULL}, /* Dx */
1.29 kristaps 356: {NULL, NULL}, /* %Q */
357: {NULL, NULL}, /* br */
358: {NULL, NULL}, /* sp */
359: };
1.10 kristaps 360:
1.35 kristaps 361: static char buf[BUFSIZ]; /* XXX */
362:
363: #define bufcat(x) (void)strlcat(buf, (x), BUFSIZ)
364: #define bufinit() buf[0] = 0
365: #define buffmt(...) (void)snprintf(buf, BUFSIZ - 1, __VA_ARGS__)
1.33 kristaps 366:
1.30 kristaps 367: void
1.29 kristaps 368: html_mdoc(void *arg, const struct mdoc *m)
1.10 kristaps 369: {
1.29 kristaps 370: struct html *h;
1.30 kristaps 371: struct tag *t;
1.10 kristaps 372:
1.29 kristaps 373: h = (struct html *)arg;
1.10 kristaps 374:
1.29 kristaps 375: print_gen_doctype(h);
1.30 kristaps 376: t = print_otag(h, TAG_HTML, 0, NULL);
1.29 kristaps 377: print_mdoc(mdoc_meta(m), mdoc_node(m), h);
1.30 kristaps 378: print_tagq(h, t);
379:
1.29 kristaps 380: printf("\n");
1.10 kristaps 381: }
382:
1.33 kristaps 383:
1.30 kristaps 384: void
1.29 kristaps 385: html_man(void *arg, const struct man *m)
1.10 kristaps 386: {
1.29 kristaps 387: struct html *h;
1.30 kristaps 388: struct tag *t;
1.10 kristaps 389:
1.29 kristaps 390: h = (struct html *)arg;
1.10 kristaps 391:
1.29 kristaps 392: print_gen_doctype(h);
1.30 kristaps 393: t = print_otag(h, TAG_HTML, 0, NULL);
1.29 kristaps 394: print_man(man_meta(m), man_node(m), h);
1.30 kristaps 395: print_tagq(h, t);
396:
1.29 kristaps 397: printf("\n");
1.10 kristaps 398: }
399:
1.33 kristaps 400:
1.29 kristaps 401: void *
402: html_alloc(void)
1.10 kristaps 403: {
1.30 kristaps 404: struct html *h;
405:
406: if (NULL == (h = calloc(1, sizeof(struct html))))
407: return(NULL);
1.10 kristaps 408:
1.37 kristaps 409: SLIST_INIT(&h->tags);
410: SLIST_INIT(&h->ords);
411:
1.32 kristaps 412: if (NULL == (h->symtab = chars_init(CHARS_HTML))) {
413: free(h);
414: return(NULL);
415: }
1.41 ! kristaps 416:
! 417: /* h->base = xxx; */
! 418: /* h->style = xxx; */
1.30 kristaps 419: return(h);
1.29 kristaps 420: }
1.10 kristaps 421:
1.33 kristaps 422:
1.29 kristaps 423: void
424: html_free(void *p)
425: {
1.30 kristaps 426: struct tag *tag;
1.37 kristaps 427: struct ord *ord;
1.30 kristaps 428: struct html *h;
429:
430: h = (struct html *)p;
1.10 kristaps 431:
1.37 kristaps 432: while ( ! SLIST_EMPTY(&h->ords)) {
433: ord = SLIST_FIRST(&h->ords);
434: SLIST_REMOVE_HEAD(&h->ords, entry);
435: free(ord);
436: }
437:
438: while ( ! SLIST_EMPTY(&h->tags)) {
439: tag = SLIST_FIRST(&h->tags);
440: SLIST_REMOVE_HEAD(&h->tags, entry);
1.30 kristaps 441: free(tag);
442: }
1.36 kristaps 443:
444: if (h->symtab)
445: chars_free(h->symtab);
1.30 kristaps 446: free(h);
1.10 kristaps 447: }
1.2 kristaps 448:
1.33 kristaps 449:
1.29 kristaps 450: static void
451: print_mdoc(MDOC_ARGS)
1.4 kristaps 452: {
1.30 kristaps 453: struct tag *t;
1.4 kristaps 454:
1.30 kristaps 455: t = print_otag(h, TAG_HEAD, 0, NULL);
1.29 kristaps 456: print_mdoc_head(m, n, h);
1.30 kristaps 457: print_tagq(h, t);
458:
459: t = print_otag(h, TAG_BODY, 0, NULL);
1.39 kristaps 460: print_mdoc_nodelist(m, n, h);
1.30 kristaps 461: print_tagq(h, t);
1.29 kristaps 462: }
1.4 kristaps 463:
1.33 kristaps 464:
1.29 kristaps 465: static void
466: print_gen_head(struct html *h)
467: {
1.41 ! kristaps 468: struct htmlpair tag[4];
! 469:
! 470: tag[0].key = ATTR_HTTPEQUIV;
! 471: tag[0].val = "Content-Type";
! 472: tag[1].key = ATTR_CONTENT;
! 473: tag[1].val = "text/html; charset=utf-8";
! 474: print_otag(h, TAG_META, 2, tag);
! 475:
! 476: tag[0].key = ATTR_NAME;
! 477: tag[0].val = "resource-type";
! 478: tag[1].key = ATTR_CONTENT;
! 479: tag[1].val = "document";
! 480: print_otag(h, TAG_META, 2, tag);
! 481:
! 482: if (h->style) {
! 483: tag[0].key = ATTR_REL;
! 484: tag[0].val = "stylesheet";
! 485: tag[1].key = ATTR_HREF;
! 486: tag[1].val = h->style;
! 487: tag[2].key = ATTR_TYPE;
! 488: tag[2].val = "text/css";
! 489: tag[3].key = ATTR_MEDIA;
! 490: tag[3].val = "all";
! 491: print_otag(h, TAG_LINK, 4, tag);
! 492: }
! 493:
! 494: if (h->base) {
! 495: tag[0].key = ATTR_HREF;
! 496: tag[1].val = h->base;
! 497: print_otag(h, TAG_BASE, 1, tag);
! 498: }
1.4 kristaps 499: }
500:
1.33 kristaps 501:
1.30 kristaps 502: /* ARGSUSED */
1.29 kristaps 503: static void
504: print_mdoc_head(MDOC_ARGS)
1.18 kristaps 505: {
506:
1.29 kristaps 507: print_gen_head(h);
508: print_otag(h, TAG_TITLE, 0, NULL);
1.41 ! kristaps 509: print_text(h, m->title);
1.2 kristaps 510: }
511:
1.33 kristaps 512:
1.29 kristaps 513: static void
1.39 kristaps 514: print_mdoc_nodelist(MDOC_ARGS)
515: {
516:
517: print_mdoc_node(m, n, h);
518: if (n->next)
519: print_mdoc_nodelist(m, n->next, h);
520: }
521:
522:
523: static void
1.29 kristaps 524: print_mdoc_node(MDOC_ARGS)
1.2 kristaps 525: {
1.29 kristaps 526: int child;
1.30 kristaps 527: struct tag *t;
1.8 kristaps 528:
1.29 kristaps 529: child = 1;
1.37 kristaps 530: t = SLIST_FIRST(&h->tags);
1.8 kristaps 531:
1.35 kristaps 532: bufinit();
533:
1.29 kristaps 534: switch (n->type) {
535: case (MDOC_ROOT):
536: child = mdoc_root_pre(m, n, h);
1.7 kristaps 537: break;
1.29 kristaps 538: case (MDOC_TEXT):
539: print_text(h, n->string);
1.7 kristaps 540: break;
1.3 kristaps 541: default:
1.29 kristaps 542: if (mdocs[n->tok].pre)
543: child = (*mdocs[n->tok].pre)(m, n, h);
1.3 kristaps 544: break;
1.2 kristaps 545: }
546:
1.29 kristaps 547: if (child && n->child)
1.39 kristaps 548: print_mdoc_nodelist(m, n->child, h);
1.8 kristaps 549:
1.30 kristaps 550: print_stagq(h, t);
551:
1.35 kristaps 552: bufinit();
553:
1.29 kristaps 554: switch (n->type) {
555: case (MDOC_ROOT):
1.39 kristaps 556: mdoc_root_post(m, n, h);
1.7 kristaps 557: break;
1.29 kristaps 558: case (MDOC_TEXT):
1.7 kristaps 559: break;
1.3 kristaps 560: default:
1.29 kristaps 561: if (mdocs[n->tok].post)
562: (*mdocs[n->tok].post)(m, n, h);
1.3 kristaps 563: break;
564: }
1.2 kristaps 565: }
566:
1.33 kristaps 567:
1.29 kristaps 568: static void
569: print_man(MAN_ARGS)
1.9 kristaps 570: {
1.30 kristaps 571: struct tag *t;
1.9 kristaps 572:
1.30 kristaps 573: t = print_otag(h, TAG_HEAD, 0, NULL);
1.29 kristaps 574: print_man_head(m, n, h);
1.30 kristaps 575: print_tagq(h, t);
576:
577: t = print_otag(h, TAG_BODY, 0, NULL);
1.41 ! kristaps 578: /*print_man_body(m, n, h);*/
1.30 kristaps 579: print_tagq(h, t);
1.9 kristaps 580: }
581:
1.33 kristaps 582:
1.30 kristaps 583: /* ARGSUSED */
1.9 kristaps 584: static void
1.29 kristaps 585: print_man_head(MAN_ARGS)
1.9 kristaps 586: {
587:
1.29 kristaps 588: print_gen_head(h);
589: print_otag(h, TAG_TITLE, 0, NULL);
1.41 ! kristaps 590: print_text(h, m->title);
1.9 kristaps 591: }
592:
1.33 kristaps 593:
1.32 kristaps 594: static void
595: print_spec(struct html *h, const char *p, int len)
596: {
597: const char *rhs;
598: int i;
599: size_t sz;
600:
601: rhs = chars_a2ascii(h->symtab, p, (size_t)len, &sz);
602:
603: if (NULL == rhs)
604: return;
605: for (i = 0; i < (int)sz; i++)
606: putchar(rhs[i]);
607: }
608:
1.33 kristaps 609:
1.32 kristaps 610: static void
611: print_res(struct html *h, const char *p, int len)
612: {
613: const char *rhs;
614: int i;
615: size_t sz;
616:
617: rhs = chars_a2res(h->symtab, p, (size_t)len, &sz);
618:
619: if (NULL == rhs)
620: return;
621: for (i = 0; i < (int)sz; i++)
622: putchar(rhs[i]);
623: }
624:
1.33 kristaps 625:
1.32 kristaps 626: static void
627: print_escape(struct html *h, const char **p)
628: {
629: int j, type;
630: const char *wp;
631:
632: wp = *p;
633: type = 1;
634:
635: if (0 == *(++wp)) {
636: *p = wp;
637: return;
638: }
639:
640: if ('(' == *wp) {
641: wp++;
642: if (0 == *wp || 0 == *(wp + 1)) {
643: *p = 0 == *wp ? wp : wp + 1;
644: return;
645: }
646:
647: print_spec(h, wp, 2);
648: *p = ++wp;
649: return;
650:
651: } else if ('*' == *wp) {
652: if (0 == *(++wp)) {
653: *p = wp;
654: return;
655: }
656:
657: switch (*wp) {
658: case ('('):
659: wp++;
660: if (0 == *wp || 0 == *(wp + 1)) {
661: *p = 0 == *wp ? wp : wp + 1;
662: return;
663: }
664:
665: print_res(h, wp, 2);
666: *p = ++wp;
667: return;
668: case ('['):
669: type = 0;
670: break;
671: default:
672: print_res(h, wp, 1);
673: *p = wp;
674: return;
675: }
676:
677: } else if ('f' == *wp) {
678: if (0 == *(++wp)) {
679: *p = wp;
680: return;
681: }
682:
683: switch (*wp) {
684: case ('B'):
685: /* TODO */
686: break;
687: case ('I'):
688: /* TODO */
689: break;
690: case ('P'):
691: /* FALLTHROUGH */
692: case ('R'):
693: /* TODO */
694: break;
695: default:
696: break;
697: }
698:
699: *p = wp;
700: return;
701:
702: } else if ('[' != *wp) {
703: print_spec(h, wp, 1);
704: *p = wp;
705: return;
706: }
707:
708: wp++;
709: for (j = 0; *wp && ']' != *wp; wp++, j++)
710: /* Loop... */ ;
711:
712: if (0 == *wp) {
713: *p = wp;
714: return;
715: }
716:
717: if (type)
718: print_spec(h, wp - j, j);
719: else
720: print_res(h, wp - j, j);
721:
722: *p = wp;
723: }
724:
1.9 kristaps 725:
1.29 kristaps 726: static void
1.32 kristaps 727: print_encode(struct html *h, const char *p)
1.29 kristaps 728: {
1.14 kristaps 729:
1.32 kristaps 730: for (; *p; p++) {
1.34 kristaps 731: if ('\\' == *p) {
732: print_escape(h, &p);
733: continue;
734: }
735: switch (*p) {
736: case ('<'):
737: printf("<");
738: break;
739: case ('>'):
740: printf(">");
741: break;
742: case ('&'):
743: printf("&");
744: break;
745: default:
1.32 kristaps 746: putchar(*p);
1.34 kristaps 747: break;
1.32 kristaps 748: }
749: }
1.14 kristaps 750: }
751:
752:
1.30 kristaps 753: static struct tag *
1.29 kristaps 754: print_otag(struct html *h, enum htmltag tag,
755: int sz, const struct htmlpair *p)
1.14 kristaps 756: {
1.29 kristaps 757: int i;
1.30 kristaps 758: struct tag *t;
759:
760: if ( ! (HTML_NOSTACK & htmltags[tag].flags)) {
761: if (NULL == (t = malloc(sizeof(struct tag))))
762: err(EXIT_FAILURE, "malloc");
763: t->tag = tag;
1.37 kristaps 764: SLIST_INSERT_HEAD(&h->tags, t, entry);
1.30 kristaps 765: } else
766: t = NULL;
1.29 kristaps 767:
768: if ( ! (HTML_NOSPACE & h->flags))
1.30 kristaps 769: if ( ! (HTML_CLRLINE & htmltags[tag].flags))
1.29 kristaps 770: printf(" ");
771:
772: printf("<%s", htmltags[tag].name);
773: for (i = 0; i < sz; i++) {
774: printf(" %s=\"", htmlattrs[p[i].key]);
775: assert(p->val);
1.32 kristaps 776: print_encode(h, p[i].val);
1.29 kristaps 777: printf("\"");
778: }
779: printf(">");
1.14 kristaps 780:
1.29 kristaps 781: h->flags |= HTML_NOSPACE;
1.30 kristaps 782: if (HTML_CLRLINE & htmltags[tag].flags)
783: h->flags |= HTML_NEWLINE;
784: else
785: h->flags &= ~HTML_NEWLINE;
1.14 kristaps 786:
1.30 kristaps 787: return(t);
1.14 kristaps 788: }
789:
790:
791: /* ARGSUSED */
1.29 kristaps 792: static void
793: print_ctag(struct html *h, enum htmltag tag)
1.14 kristaps 794: {
795:
1.29 kristaps 796: printf("</%s>", htmltags[tag].name);
1.30 kristaps 797: if (HTML_CLRLINE & htmltags[tag].flags)
1.29 kristaps 798: h->flags |= HTML_NOSPACE;
1.30 kristaps 799: if (HTML_CLRLINE & htmltags[tag].flags)
800: h->flags |= HTML_NEWLINE;
801: else
802: h->flags &= ~HTML_NEWLINE;
1.14 kristaps 803: }
804:
805:
1.29 kristaps 806: /* ARGSUSED */
807: static void
808: print_gen_doctype(struct html *h)
1.1 kristaps 809: {
1.29 kristaps 810:
811: printf("<!DOCTYPE HTML PUBLIC \"%s\" \"%s\">\n", DOCTYPE, DTD);
1.1 kristaps 812: }
813:
814:
1.29 kristaps 815: static void
816: print_text(struct html *h, const char *p)
1.1 kristaps 817: {
818:
1.29 kristaps 819: if (*p && 0 == *(p + 1))
820: switch (*p) {
821: case('.'):
822: /* FALLTHROUGH */
823: case(','):
824: /* FALLTHROUGH */
825: case(';'):
826: /* FALLTHROUGH */
827: case(':'):
828: /* FALLTHROUGH */
829: case('?'):
830: /* FALLTHROUGH */
831: case('!'):
832: /* FALLTHROUGH */
833: case(')'):
834: /* FALLTHROUGH */
835: case(']'):
836: /* FALLTHROUGH */
837: case('}'):
838: h->flags |= HTML_NOSPACE;
1.30 kristaps 839: break;
1.29 kristaps 840: default:
841: break;
842: }
1.1 kristaps 843:
1.29 kristaps 844: if ( ! (h->flags & HTML_NOSPACE))
845: printf(" ");
1.30 kristaps 846:
1.29 kristaps 847: h->flags &= ~HTML_NOSPACE;
1.30 kristaps 848: h->flags &= ~HTML_NEWLINE;
1.1 kristaps 849:
1.29 kristaps 850: if (p)
1.32 kristaps 851: print_encode(h, p);
1.8 kristaps 852:
1.29 kristaps 853: if (*p && 0 == *(p + 1))
854: switch (*p) {
855: case('('):
856: /* FALLTHROUGH */
857: case('['):
858: /* FALLTHROUGH */
859: case('{'):
860: h->flags |= HTML_NOSPACE;
1.30 kristaps 861: break;
1.29 kristaps 862: default:
863: break;
864: }
1.1 kristaps 865: }
1.30 kristaps 866:
867:
868: static void
869: print_tagq(struct html *h, const struct tag *until)
870: {
871: struct tag *tag;
872:
1.37 kristaps 873: while ( ! SLIST_EMPTY(&h->tags)) {
874: tag = SLIST_FIRST(&h->tags);
1.30 kristaps 875: print_ctag(h, tag->tag);
1.37 kristaps 876: SLIST_REMOVE_HEAD(&h->tags, entry);
1.30 kristaps 877: free(tag);
878: if (until && tag == until)
879: return;
880: }
881: }
882:
883:
884: static void
885: print_stagq(struct html *h, const struct tag *suntil)
886: {
887: struct tag *tag;
888:
1.37 kristaps 889: while ( ! SLIST_EMPTY(&h->tags)) {
890: tag = SLIST_FIRST(&h->tags);
1.30 kristaps 891: if (suntil && tag == suntil)
892: return;
893: print_ctag(h, tag->tag);
1.37 kristaps 894: SLIST_REMOVE_HEAD(&h->tags, entry);
1.30 kristaps 895: free(tag);
896: }
897: }
898:
899:
1.39 kristaps 900: /* ARGSUSED */
901: static void
902: mdoc_root_post(MDOC_ARGS)
903: {
1.41 ! kristaps 904: struct tm tm;
! 905: struct htmlpair tag[2];
! 906: struct tag *t, *tt;
! 907: char b[BUFSIZ];
1.39 kristaps 908:
1.41 ! kristaps 909: (void)localtime_r(&m->date, &tm);
1.39 kristaps 910:
1.41 ! kristaps 911: if (0 == strftime(b, BUFSIZ - 1, "%B %e, %Y", &tm))
1.39 kristaps 912: err(EXIT_FAILURE, "strftime");
1.33 kristaps 913:
1.41 ! kristaps 914: tag[0].key = ATTR_CLASS;
! 915: tag[0].val = "footer";
! 916: tag[1].key = ATTR_STYLE;
! 917: tag[1].val = "width: 100%;";
! 918: t = print_otag(h, TAG_TABLE, 2, tag);
! 919: tt = print_otag(h, TAG_TR, 0, NULL);
1.33 kristaps 920:
1.41 ! kristaps 921: tag[0].key = ATTR_STYLE;
! 922: tag[0].val = "width: 50%;";
! 923: print_otag(h, TAG_TD, 1, tag);
1.39 kristaps 924: print_text(h, b);
1.41 ! kristaps 925: print_stagq(h, tt);
1.39 kristaps 926:
1.41 ! kristaps 927: tag[0].key = ATTR_STYLE;
! 928: tag[0].val = "width: 50%; text-align: right;";
! 929: print_otag(h, TAG_TD, 1, tag);
! 930: print_text(h, m->os);
1.39 kristaps 931: print_tagq(h, t);
932: }
933:
934:
1.30 kristaps 935: /* ARGSUSED */
936: static int
937: mdoc_root_pre(MDOC_ARGS)
938: {
1.41 ! kristaps 939: struct htmlpair tag[2];
1.39 kristaps 940: struct tag *t, *tt;
941: char b[BUFSIZ], title[BUFSIZ];
942:
943: (void)strlcpy(b, m->vol, BUFSIZ);
944:
945: if (m->arch) {
1.41 ! kristaps 946: (void)strlcat(b, " (", BUFSIZ);
! 947: (void)strlcat(b, m->arch, BUFSIZ);
! 948: (void)strlcat(b, ")", BUFSIZ);
1.39 kristaps 949: }
950:
1.41 ! kristaps 951: (void)snprintf(title, BUFSIZ - 1,
! 952: "%s(%d)", m->title, m->msec);
1.39 kristaps 953:
1.41 ! kristaps 954: tag[0].key = ATTR_CLASS;
! 955: tag[0].val = "body";
! 956: t = print_otag(h, TAG_DIV, 1, tag);
1.39 kristaps 957:
1.41 ! kristaps 958: tag[0].key = ATTR_CLASS;
! 959: tag[0].val = "header";
! 960: tag[1].key = ATTR_STYLE;
! 961: tag[1].val = "width: 100%;";
! 962: print_otag(h, TAG_TABLE, 2, tag);
! 963: tt = print_otag(h, TAG_TR, 0, NULL);
1.39 kristaps 964:
1.41 ! kristaps 965: tag[0].key = ATTR_STYLE;
! 966: tag[0].val = "width: 33%;";
! 967: print_otag(h, TAG_TD, 1, tag);
1.39 kristaps 968: print_text(h, b);
969: print_stagq(h, tt);
970:
1.41 ! kristaps 971: tag[0].key = ATTR_STYLE;
! 972: tag[0].val = "width: 33%; text-align: center;";
! 973: print_otag(h, TAG_TD, 1, tag);
1.39 kristaps 974: print_text(h, title);
975: print_stagq(h, tt);
976:
1.41 ! kristaps 977: tag[0].key = ATTR_STYLE;
! 978: tag[0].val = "width: 33%; text-align: right;";
! 979: print_otag(h, TAG_TD, 1, tag);
1.39 kristaps 980: print_text(h, b);
981: print_stagq(h, t);
1.30 kristaps 982:
983: return(1);
984: }
985:
986:
987: /* ARGSUSED */
988: static int
1.35 kristaps 989: mdoc_sh_pre(MDOC_ARGS)
1.30 kristaps 990: {
1.41 ! kristaps 991: struct htmlpair tag[2];
! 992: const struct mdoc_node *nn;
1.34 kristaps 993:
1.35 kristaps 994: if (MDOC_HEAD == n->type) {
995: tag[0].key = ATTR_CLASS;
996: tag[0].val = "sec-head";
997: print_otag(h, TAG_DIV, 1, tag);
998: print_otag(h, TAG_SPAN, 1, tag);
1.41 ! kristaps 999:
! 1000: for (nn = n->child; nn; nn = nn->next) {
! 1001: bufcat(nn->string);
! 1002: if (nn->next)
! 1003: bufcat(" ");
! 1004: }
! 1005: tag[0].key = ATTR_NAME;
! 1006: tag[0].val = buf;
! 1007: print_otag(h, TAG_A, 1, tag);
1.35 kristaps 1008: return(1);
1009: } else if (MDOC_BLOCK == n->type) {
1010: tag[0].key = ATTR_CLASS;
1011: tag[0].val = "sec-block";
1.39 kristaps 1012:
1013: if (n->prev && NULL == n->prev->body->child) {
1014: print_otag(h, TAG_DIV, 1, tag);
1015: return(1);
1016: }
1017:
1.40 kristaps 1018: bufcat("margin-top: 1em;");
1019: if (NULL == n->next)
1020: bufcat("margin-bottom: 1em;");
1021:
1.39 kristaps 1022: tag[1].key = ATTR_STYLE;
1.40 kristaps 1023: tag[1].val = buf;
1.39 kristaps 1024:
1025: print_otag(h, TAG_DIV, 2, tag);
1.35 kristaps 1026: return(1);
1027: }
1028:
1029: buffmt("margin-left: %dem;", INDENT);
1030:
1.34 kristaps 1031: tag[0].key = ATTR_CLASS;
1.35 kristaps 1032: tag[0].val = "sec-body";
1033: tag[1].key = ATTR_STYLE;
1034: tag[1].val = buf;
1035:
1036: print_otag(h, TAG_DIV, 2, tag);
1037: return(1);
1038: }
1039:
1040:
1041: /* ARGSUSED */
1042: static int
1043: mdoc_ss_pre(MDOC_ARGS)
1044: {
1.41 ! kristaps 1045: struct htmlpair tag[2];
! 1046: int i;
! 1047: const struct mdoc_node *nn;
1.35 kristaps 1048:
1049: i = 0;
1050:
1051: if (MDOC_BODY == n->type) {
1052: tag[i].key = ATTR_CLASS;
1053: tag[i++].val = "ssec-body";
1054: if (n->parent->next && n->child) {
1055: bufcat("margin-bottom: 1em;");
1056: tag[i].key = ATTR_STYLE;
1057: tag[i++].val = buf;
1058: }
1059: print_otag(h, TAG_DIV, i, tag);
1060: return(1);
1061: } else if (MDOC_BLOCK == n->type) {
1062: tag[i].key = ATTR_CLASS;
1063: tag[i++].val = "ssec-block";
1064: if (n->prev) {
1065: bufcat("margin-top: 1em;");
1066: tag[i].key = ATTR_STYLE;
1067: tag[i++].val = buf;
1068: }
1069: print_otag(h, TAG_DIV, i, tag);
1070: return(1);
1071: }
1072:
1073: buffmt("margin-left: -%dem;", INDENT - HALFINDENT);
1.34 kristaps 1074:
1.35 kristaps 1075: tag[0].key = ATTR_CLASS;
1076: tag[0].val = "ssec-head";
1.34 kristaps 1077: tag[1].key = ATTR_STYLE;
1.35 kristaps 1078: tag[1].val = buf;
1.30 kristaps 1079:
1.35 kristaps 1080: print_otag(h, TAG_DIV, 2, tag);
1081: print_otag(h, TAG_SPAN, 1, tag);
1.41 ! kristaps 1082:
! 1083: bufinit();
! 1084: for (nn = n->child; nn; nn = nn->next) {
! 1085: bufcat(nn->string);
! 1086: if (nn->next)
! 1087: bufcat(" ");
! 1088: }
! 1089: tag[0].key = ATTR_NAME;
! 1090: tag[0].val = buf;
! 1091: print_otag(h, TAG_A, 1, tag);
! 1092:
1.30 kristaps 1093: return(1);
1094: }
1095:
1096:
1097: /* ARGSUSED */
1098: static int
1099: mdoc_fl_pre(MDOC_ARGS)
1100: {
1101: struct htmlpair tag;
1102:
1103: tag.key = ATTR_CLASS;
1104: tag.val = "flag";
1105:
1106: print_otag(h, TAG_SPAN, 1, &tag);
1.41 ! kristaps 1107: if (MDOC_Fl == n->tok) {
! 1108: print_text(h, "\\-");
! 1109: h->flags |= HTML_NOSPACE;
! 1110: }
1.30 kristaps 1111: return(1);
1112: }
1113:
1114:
1115: /* ARGSUSED */
1116: static int
1117: mdoc_pp_pre(MDOC_ARGS)
1118: {
1.34 kristaps 1119: struct htmlpair tag;
1.30 kristaps 1120:
1.34 kristaps 1121: tag.key = ATTR_STYLE;
1.41 ! kristaps 1122: tag.val = "clear: both; height: 1em;";
1.35 kristaps 1123: print_otag(h, TAG_DIV, 1, &tag);
1.30 kristaps 1124: return(0);
1125: }
1126:
1127:
1128: /* ARGSUSED */
1129: static int
1130: mdoc_nd_pre(MDOC_ARGS)
1131: {
1.35 kristaps 1132: struct htmlpair tag;
1133:
1134: if (MDOC_BODY != n->type)
1135: return(1);
1.30 kristaps 1136:
1.35 kristaps 1137: /* XXX - this can contain block elements! */
1138: print_text(h, "\\(em");
1139: tag.key = ATTR_CLASS;
1140: tag.val = "desc-body";
1141: print_otag(h, TAG_SPAN, 1, &tag);
1.30 kristaps 1142: return(1);
1143: }
1144:
1145:
1146: /* ARGSUSED */
1147: static int
1148: mdoc_op_pre(MDOC_ARGS)
1149: {
1.35 kristaps 1150: struct htmlpair tag;
1151:
1152: if (MDOC_BODY != n->type)
1153: return(1);
1.30 kristaps 1154:
1.35 kristaps 1155: /* XXX - this can contain block elements! */
1156: print_text(h, "\\(lB");
1157: tag.key = ATTR_CLASS;
1158: tag.val = "opt";
1159: print_otag(h, TAG_SPAN, 1, &tag);
1.30 kristaps 1160: return(1);
1161: }
1162:
1163:
1164: /* ARGSUSED */
1165: static void
1166: mdoc_op_post(MDOC_ARGS)
1167: {
1168:
1169: if (MDOC_BODY != n->type)
1170: return;
1171: h->flags |= HTML_NOSPACE;
1172: print_text(h, "\\(rB");
1173: }
1174:
1175:
1176: static int
1177: mdoc_nm_pre(MDOC_ARGS)
1178: {
1.35 kristaps 1179: struct htmlpair tag;
1.30 kristaps 1180:
1181: if ( ! (HTML_NEWLINE & h->flags))
1.35 kristaps 1182: if (SEC_SYNOPSIS == n->sec) {
1183: tag.key = ATTR_STYLE;
1184: tag.val = "clear: both;";
1185: print_otag(h, TAG_BR, 1, &tag);
1186: }
1.30 kristaps 1187:
1.35 kristaps 1188: tag.key = ATTR_CLASS;
1189: tag.val = "name";
1.30 kristaps 1190:
1.35 kristaps 1191: print_otag(h, TAG_SPAN, 1, &tag);
1.30 kristaps 1192: if (NULL == n->child)
1193: print_text(h, m->name);
1194:
1195: return(1);
1196: }
1197:
1198:
1199: /* ARGSUSED */
1200: static int
1201: mdoc_xr_pre(MDOC_ARGS)
1202: {
1.41 ! kristaps 1203: struct htmlpair tag[2];
! 1204: const char *name, *sec;
! 1205: const struct mdoc_node *nn;
! 1206:
! 1207: nn = n->child;
! 1208: name = nn && nn->string ? nn->string : "";
! 1209: nn = nn ? nn->next : NULL;
! 1210: sec = nn && nn->string ? nn->string : "";
! 1211:
! 1212: buffmt("%s%s%s.html", name, name && sec ? "." : "", sec);
1.30 kristaps 1213:
1.35 kristaps 1214: tag[0].key = ATTR_CLASS;
1215: tag[0].val = "link-man";
1216: tag[1].key = ATTR_HREF;
1.41 ! kristaps 1217: tag[1].val = buf;
1.35 kristaps 1218: print_otag(h, TAG_A, 2, tag);
1.30 kristaps 1219:
1.41 ! kristaps 1220: nn = n->child;
! 1221: print_text(h, nn->string);
! 1222: if (NULL == (nn = nn->next))
1.30 kristaps 1223: return(0);
1224:
1225: h->flags |= HTML_NOSPACE;
1226: print_text(h, "(");
1227: h->flags |= HTML_NOSPACE;
1.41 ! kristaps 1228: print_text(h, nn->string);
1.30 kristaps 1229: h->flags |= HTML_NOSPACE;
1230: print_text(h, ")");
1231:
1232: return(0);
1233: }
1.31 kristaps 1234:
1235:
1236: /* ARGSUSED */
1237: static int
1238: mdoc_ns_pre(MDOC_ARGS)
1239: {
1240:
1241: h->flags |= HTML_NOSPACE;
1242: return(1);
1243: }
1244:
1.35 kristaps 1245:
1.31 kristaps 1246: /* ARGSUSED */
1247: static int
1248: mdoc_ar_pre(MDOC_ARGS)
1249: {
1250: struct htmlpair tag;
1251:
1252: tag.key = ATTR_CLASS;
1253: tag.val = "arg";
1254:
1255: print_otag(h, TAG_SPAN, 1, &tag);
1256: return(1);
1257: }
1.33 kristaps 1258:
1.35 kristaps 1259:
1.33 kristaps 1260: /* ARGSUSED */
1261: static int
1262: mdoc_xx_pre(MDOC_ARGS)
1263: {
1264: const char *pp;
1.35 kristaps 1265: struct htmlpair tag;
1.33 kristaps 1266:
1267: switch (n->tok) {
1268: case (MDOC_Bsx):
1269: pp = "BSDI BSD/OS";
1270: break;
1271: case (MDOC_Dx):
1272: pp = "DragonFlyBSD";
1273: break;
1274: case (MDOC_Fx):
1275: pp = "FreeBSD";
1276: break;
1277: case (MDOC_Nx):
1278: pp = "NetBSD";
1279: break;
1280: case (MDOC_Ox):
1281: pp = "OpenBSD";
1282: break;
1283: case (MDOC_Ux):
1284: pp = "UNIX";
1285: break;
1286: default:
1287: return(1);
1288: }
1289:
1.35 kristaps 1290: tag.key = ATTR_CLASS;
1291: tag.val = "unix";
1292:
1293: print_otag(h, TAG_SPAN, 1, &tag);
1.33 kristaps 1294: print_text(h, pp);
1295: return(1);
1296: }
1297:
1298:
1.35 kristaps 1299: /* ARGSUSED */
1.33 kristaps 1300: static int
1.37 kristaps 1301: mdoc_tbl_block_pre(MDOC_ARGS, int t, int w, int o, int c)
1.34 kristaps 1302: {
1303: struct htmlpair tag;
1304:
1.37 kristaps 1305: switch (t) {
1.38 kristaps 1306: case (MDOC_Column):
1307: /* FALLTHROUGH */
1.37 kristaps 1308: case (MDOC_Item):
1309: /* FALLTHROUGH */
1310: case (MDOC_Ohang):
1311: buffmt("margin-left: %dem; clear: both;", o);
1312: break;
1313: default:
1314: buffmt("margin-left: %dem; clear: both;", w + o);
1315: break;
1316: }
1.34 kristaps 1317:
1.37 kristaps 1318: if ( ! c && n->prev && n->prev->body->child)
1.35 kristaps 1319: bufcat("padding-top: 1em;");
1.34 kristaps 1320:
1321: tag.key = ATTR_STYLE;
1322: tag.val = buf;
1323: print_otag(h, TAG_DIV, 1, &tag);
1324: return(1);
1325: }
1326:
1327:
1.35 kristaps 1328: /* ARGSUSED */
1.34 kristaps 1329: static int
1330: mdoc_tbl_body_pre(MDOC_ARGS, int t, int w)
1331: {
1332:
1.37 kristaps 1333: print_otag(h, TAG_DIV, 0, NULL);
1.34 kristaps 1334: return(1);
1335: }
1336:
1337:
1.35 kristaps 1338: /* ARGSUSED */
1.34 kristaps 1339: static int
1.35 kristaps 1340: mdoc_tbl_head_pre(MDOC_ARGS, int t, int w)
1.33 kristaps 1341: {
1.34 kristaps 1342: struct htmlpair tag;
1.37 kristaps 1343: struct ord *ord;
1344: char nbuf[BUFSIZ];
1.34 kristaps 1345:
1.35 kristaps 1346: switch (t) {
1.37 kristaps 1347: case (MDOC_Item):
1.35 kristaps 1348: /* FALLTHROUGH */
1.37 kristaps 1349: case (MDOC_Ohang):
1350: print_otag(h, TAG_DIV, 0, NULL);
1351: break;
1.38 kristaps 1352: case (MDOC_Column):
1353: buffmt("min-width: %dem;", w);
1354: bufcat("clear: none;");
1355: if (n->next && MDOC_HEAD == n->next->type)
1356: bufcat("float: left;");
1357: tag.key = ATTR_STYLE;
1358: tag.val = buf;
1359: print_otag(h, TAG_DIV, 1, &tag);
1360: break;
1.37 kristaps 1361: default:
1.35 kristaps 1362: buffmt("margin-left: -%dem;", w);
1363: bufcat("clear: left;");
1364: bufcat("float: left;");
1365: bufcat("padding-right: 1em;");
1.37 kristaps 1366: tag.key = ATTR_STYLE;
1367: tag.val = buf;
1368: print_otag(h, TAG_DIV, 1, &tag);
1.34 kristaps 1369: break;
1.37 kristaps 1370: }
1371:
1372: switch (t) {
1373: case (MDOC_Diag):
1374: tag.key = ATTR_CLASS;
1375: tag.val = "diag";
1376: print_otag(h, TAG_SPAN, 1, &tag);
1377: break;
1378: case (MDOC_Enum):
1379: ord = SLIST_FIRST(&h->ords);
1380: assert(ord);
1381: nbuf[BUFSIZ - 1] = 0;
1382: (void)snprintf(nbuf, BUFSIZ - 1, "%d.", ord->pos++);
1383: print_text(h, nbuf);
1384: return(0);
1385: case (MDOC_Dash):
1386: print_text(h, "\\(en");
1387: return(0);
1388: case (MDOC_Hyphen):
1389: print_text(h, "\\-");
1390: return(0);
1391: case (MDOC_Bullet):
1392: print_text(h, "\\(bu");
1393: return(0);
1.34 kristaps 1394: default:
1395: break;
1.33 kristaps 1396: }
1397:
1.34 kristaps 1398: return(1);
1399: }
1400:
1401:
1402: static int
1403: mdoc_tbl_pre(MDOC_ARGS, int type)
1404: {
1.38 kristaps 1405: int i, w, o, c, wp;
1406: const struct mdoc_node *bl, *nn;
1.34 kristaps 1407:
1.33 kristaps 1408: bl = n->parent->parent;
1409: if (MDOC_BLOCK != n->type)
1410: bl = bl->parent;
1411:
1.34 kristaps 1412: /* FIXME: fmt_vspace() equivalent. */
1413:
1.33 kristaps 1414: assert(bl->args);
1415:
1.34 kristaps 1416: w = o = c = 0;
1.38 kristaps 1417: wp = -1;
1.34 kristaps 1418:
1419: for (i = 0; i < (int)bl->args->argc; i++)
1.33 kristaps 1420: if (MDOC_Width == bl->args->argv[i].arg) {
1421: assert(bl->args->argv[i].sz);
1.38 kristaps 1422: wp = i;
1.41 ! kristaps 1423: w = out_a2width(bl->args->argv[i].value[0]);
1.34 kristaps 1424: } else if (MDOC_Offset == bl->args->argv[i].arg) {
1425: assert(bl->args->argv[i].sz);
1.41 ! kristaps 1426: o = out_a2offs
! 1427: (bl->args->argv[i].value[0], INDENT);
1.34 kristaps 1428: } else if (MDOC_Compact == bl->args->argv[i].arg)
1429: c = 1;
1.38 kristaps 1430:
1431: if (MDOC_HEAD == n->type && MDOC_Column == type) {
1432: nn = n->parent->child;
1433: assert(nn && MDOC_HEAD == nn->type);
1434: for (i = 0; nn && nn != n; nn = nn->next, i++)
1435: /* Counter... */ ;
1436: assert(nn);
1437: if (wp >= 0 && i < (int)bl->args[wp].argv->sz)
1.41 ! kristaps 1438: w = out_a2width(bl->args->argv[wp].value[i]);
1.38 kristaps 1439: }
1.34 kristaps 1440:
1.37 kristaps 1441: switch (type) {
1442: case (MDOC_Enum):
1443: /* FALLTHROUGH */
1444: case (MDOC_Dash):
1445: /* FALLTHROUGH */
1446: case (MDOC_Hyphen):
1447: /* FALLTHROUGH */
1448: case (MDOC_Bullet):
1449: if (w < 4)
1450: w = 4;
1451: break;
1452: case (MDOC_Inset):
1453: /* FALLTHROUGH */
1454: case (MDOC_Diag):
1455: w = 1;
1456: break;
1457: default:
1458: if (0 == w)
1459: w = 10;
1460: break;
1461: }
1462:
1.34 kristaps 1463: switch (n->type) {
1464: case (MDOC_BLOCK):
1465: break;
1466: case (MDOC_HEAD):
1467: return(mdoc_tbl_head_pre(m, n, h, type, w));
1468: case (MDOC_BODY):
1469: return(mdoc_tbl_body_pre(m, n, h, type, w));
1470: default:
1471: abort();
1472: /* NOTREACHED */
1473: }
1474:
1.37 kristaps 1475: return(mdoc_tbl_block_pre(m, n, h, type, w, o, c));
1.34 kristaps 1476: }
1477:
1478:
1.41 ! kristaps 1479: /* ARGSUSED */
1.34 kristaps 1480: static int
1.37 kristaps 1481: mdoc_bl_pre(MDOC_ARGS)
1.34 kristaps 1482: {
1.37 kristaps 1483: struct ord *ord;
1.34 kristaps 1484:
1485: if (MDOC_BLOCK != n->type)
1486: return(1);
1.41 ! kristaps 1487: if (MDOC_Enum != out_a2list(n))
1.37 kristaps 1488: return(1);
1.34 kristaps 1489:
1.37 kristaps 1490: ord = malloc(sizeof(struct ord));
1491: if (NULL == ord)
1492: err(EXIT_FAILURE, "malloc");
1493: ord->cookie = n;
1494: ord->pos = 1;
1495: SLIST_INSERT_HEAD(&h->ords, ord, entry);
1.33 kristaps 1496:
1497: return(1);
1498: }
1499:
1500:
1.41 ! kristaps 1501: /* ARGSUSED */
1.37 kristaps 1502: static void
1503: mdoc_bl_post(MDOC_ARGS)
1.33 kristaps 1504: {
1.37 kristaps 1505: struct ord *ord;
1.33 kristaps 1506:
1.34 kristaps 1507: if (MDOC_BLOCK != n->type)
1.37 kristaps 1508: return;
1.41 ! kristaps 1509: if (MDOC_Enum != out_a2list(n))
1.37 kristaps 1510: return;
1.33 kristaps 1511:
1.37 kristaps 1512: ord = SLIST_FIRST(&h->ords);
1513: assert(ord);
1514: SLIST_REMOVE_HEAD(&h->ords, entry);
1515: free(ord);
1.33 kristaps 1516: }
1517:
1518:
1519: static int
1.34 kristaps 1520: mdoc_it_pre(MDOC_ARGS)
1.33 kristaps 1521: {
1.37 kristaps 1522: int type;
1.33 kristaps 1523:
1.34 kristaps 1524: if (MDOC_BLOCK == n->type)
1.41 ! kristaps 1525: type = out_a2list(n->parent->parent);
1.34 kristaps 1526: else
1.41 ! kristaps 1527: type = out_a2list(n->parent->parent->parent);
1.33 kristaps 1528:
1.37 kristaps 1529: return(mdoc_tbl_pre(m, n, h, type));
1.33 kristaps 1530: }
1.34 kristaps 1531:
1532:
1533: /* ARGSUSED */
1534: static int
1535: mdoc_ex_pre(MDOC_ARGS)
1536: {
1537: const struct mdoc_node *nn;
1538: struct tag *t;
1539: struct htmlpair tag;
1540:
1541: print_text(h, "The");
1542:
1543: tag.key = ATTR_CLASS;
1544: tag.val = "utility";
1545:
1546: for (nn = n->child; nn; nn = nn->next) {
1547: t = print_otag(h, TAG_SPAN, 1, &tag);
1548: print_text(h, nn->string);
1549: print_tagq(h, t);
1550:
1551: h->flags |= HTML_NOSPACE;
1552:
1553: if (nn->next && NULL == nn->next->next)
1554: print_text(h, ", and");
1555: else if (nn->next)
1556: print_text(h, ",");
1557: else
1558: h->flags &= ~HTML_NOSPACE;
1559: }
1560:
1561: if (n->child->next)
1562: print_text(h, "utilities exit");
1563: else
1564: print_text(h, "utility exits");
1565:
1566: print_text(h, "0 on success, and >0 if an error occurs.");
1567: return(0);
1568: }
1569:
1570:
1571: /* ARGSUSED */
1572: static int
1573: mdoc_dq_pre(MDOC_ARGS)
1574: {
1575:
1576: if (MDOC_BODY != n->type)
1577: return(1);
1578: print_text(h, "\\(lq");
1579: h->flags |= HTML_NOSPACE;
1580: return(1);
1581: }
1582:
1583:
1584: /* ARGSUSED */
1585: static void
1586: mdoc_dq_post(MDOC_ARGS)
1587: {
1588:
1589: if (MDOC_BODY != n->type)
1590: return;
1591: h->flags |= HTML_NOSPACE;
1592: print_text(h, "\\(rq");
1593: }
1594:
1595:
1596: /* ARGSUSED */
1597: static int
1598: mdoc_pq_pre(MDOC_ARGS)
1599: {
1600:
1601: if (MDOC_BODY != n->type)
1602: return(1);
1603: print_text(h, "\\&(");
1604: h->flags |= HTML_NOSPACE;
1605: return(1);
1606: }
1607:
1608:
1609: /* ARGSUSED */
1610: static void
1611: mdoc_pq_post(MDOC_ARGS)
1612: {
1613:
1614: if (MDOC_BODY != n->type)
1615: return;
1616: print_text(h, ")");
1617: }
1618:
1619:
1620: /* ARGSUSED */
1621: static int
1622: mdoc_sq_pre(MDOC_ARGS)
1623: {
1624:
1625: if (MDOC_BODY != n->type)
1626: return(1);
1627: print_text(h, "\\(oq");
1628: h->flags |= HTML_NOSPACE;
1629: return(1);
1630: }
1631:
1632:
1633: /* ARGSUSED */
1634: static void
1635: mdoc_sq_post(MDOC_ARGS)
1636: {
1637:
1638: if (MDOC_BODY != n->type)
1639: return;
1640: h->flags |= HTML_NOSPACE;
1641: print_text(h, "\\(aq");
1642: }
1643:
1644:
1645: /* ARGSUSED */
1646: static int
1647: mdoc_em_pre(MDOC_ARGS)
1648: {
1649: struct htmlpair tag;
1650:
1651: tag.key = ATTR_CLASS;
1652: tag.val = "emph";
1653:
1654: print_otag(h, TAG_SPAN, 1, &tag);
1655: return(1);
1656: }
1657:
1658:
1659: /* ARGSUSED */
1660: static int
1661: mdoc_d1_pre(MDOC_ARGS)
1662: {
1.35 kristaps 1663: struct htmlpair tag[2];
1.34 kristaps 1664:
1665: if (MDOC_BLOCK != n->type)
1666: return(1);
1667:
1.35 kristaps 1668: buffmt("margin-left: %dem;", INDENT);
1.34 kristaps 1669:
1.35 kristaps 1670: tag[0].key = ATTR_CLASS;
1671: tag[0].val = "lit-block";
1672: tag[1].key = ATTR_STYLE;
1673: tag[1].val = buf;
1.34 kristaps 1674:
1.35 kristaps 1675: print_otag(h, TAG_DIV, 2, tag);
1.34 kristaps 1676: return(1);
1677: }
1678:
1679:
1680: /* ARGSUSED */
1681: static int
1682: mdoc_sx_pre(MDOC_ARGS)
1683: {
1.41 ! kristaps 1684: struct htmlpair tag[2];
! 1685: const struct mdoc_node *nn;
! 1686:
! 1687: bufcat("#");
! 1688: for (nn = n->child; nn; nn = nn->next) {
! 1689: bufcat(nn->string);
! 1690: if (nn->next)
! 1691: bufcat(" ");
! 1692: }
1.34 kristaps 1693:
1.35 kristaps 1694: tag[0].key = ATTR_HREF;
1.41 ! kristaps 1695: tag[0].val = buf;
1.35 kristaps 1696: tag[1].key = ATTR_CLASS;
1697: tag[1].val = "link-sec";
1.34 kristaps 1698:
1.35 kristaps 1699: print_otag(h, TAG_A, 2, tag);
1.34 kristaps 1700: return(1);
1701: }
1.37 kristaps 1702:
1703:
1704: /* ARGSUSED */
1705: static int
1706: mdoc_aq_pre(MDOC_ARGS)
1707: {
1708:
1709: if (MDOC_BODY != n->type)
1710: return(1);
1711: print_text(h, "\\(la");
1712: h->flags |= HTML_NOSPACE;
1713: return(1);
1714: }
1715:
1716:
1717: /* ARGSUSED */
1718: static void
1719: mdoc_aq_post(MDOC_ARGS)
1720: {
1721:
1722: if (MDOC_BODY != n->type)
1723: return;
1724: h->flags |= HTML_NOSPACE;
1725: print_text(h, "\\(ra");
1726: }
1727:
1.39 kristaps 1728:
1729: /* ARGSUSED */
1730: static int
1731: mdoc_bd_pre(MDOC_ARGS)
1732: {
1733: struct htmlpair tag[2];
1734: int t, c, o, i;
1735: const struct mdoc_node *bl;
1736:
1737: /* FIXME: fmt_vspace() shit. */
1738:
1739: if (MDOC_BLOCK == n->type)
1740: bl = n;
1741: else if (MDOC_HEAD == n->type)
1742: return(0);
1743: else
1744: bl = n->parent;
1745:
1746: t = o = c = 0;
1747:
1748: for (i = 0; i < (int)bl->args->argc; i++)
1749: switch (bl->args->argv[i].arg) {
1750: case (MDOC_Offset):
1751: assert(bl->args->argv[i].sz);
1.41 ! kristaps 1752: o = out_a2offs
! 1753: (bl->args->argv[i].value[0], INDENT);
1.39 kristaps 1754: break;
1755: case (MDOC_Compact):
1756: c = 1;
1757: break;
1758: case (MDOC_Ragged):
1759: /* FALLTHROUGH */
1760: case (MDOC_Filled):
1761: /* FALLTHROUGH */
1762: case (MDOC_Unfilled):
1763: /* FALLTHROUGH */
1764: case (MDOC_Literal):
1765: t = bl->args->argv[i].arg;
1766: break;
1767: }
1768:
1769: if (MDOC_BLOCK == n->type) {
1770: if (o)
1771: buffmt("margin-left: %dem;", o);
1772: bufcat("margin-top: 1em;");
1773: tag[0].key = ATTR_STYLE;
1774: tag[0].val = buf;
1775: print_otag(h, TAG_DIV, 1, tag);
1776: return(1);
1777: }
1778:
1779: switch (t) {
1780: case (MDOC_Unfilled):
1781: case (MDOC_Literal):
1782: break;
1783: default:
1784: return(1);
1785: }
1786:
1787: bufcat("white-space: pre;");
1788: tag[0].key = ATTR_STYLE;
1789: tag[0].val = buf;
1790: tag[1].key = ATTR_CLASS;
1791: tag[1].val = "lit-block";
1792:
1793: print_otag(h, TAG_DIV, 2, tag);
1794:
1795: for (n = n->child; n; n = n->next) {
1796: h->flags |= HTML_NOSPACE;
1797: print_mdoc_node(m, n, h);
1798: if (n->next)
1799: print_text(h, "\n");
1800: }
1801:
1802: return(0);
1803: }
1804:
1805:
1806: /* ARGSUSED */
1807: static int
1808: mdoc_pa_pre(MDOC_ARGS)
1809: {
1810: struct htmlpair tag;
1811:
1812: tag.key = ATTR_CLASS;
1813: tag.val = "file";
1814:
1815: print_otag(h, TAG_SPAN, 1, &tag);
1816: return(1);
1817: }
1818:
1819:
1820: /* ARGSUSED */
1821: static int
1822: mdoc_qq_pre(MDOC_ARGS)
1823: {
1824:
1825: if (MDOC_BODY != n->type)
1826: return(1);
1827: print_text(h, "\\*q");
1828: h->flags |= HTML_NOSPACE;
1829: return(1);
1830: }
1831:
1832:
1833: /* ARGSUSED */
1834: static void
1835: mdoc_qq_post(MDOC_ARGS)
1836: {
1837:
1838: if (MDOC_BODY != n->type)
1839: return;
1840: h->flags |= HTML_NOSPACE;
1841: print_text(h, "\\*q");
1842: }
1.41 ! kristaps 1843:
! 1844:
! 1845: /* ARGSUSED */
! 1846: static int
! 1847: mdoc_ad_pre(MDOC_ARGS)
! 1848: {
! 1849: struct htmlpair tag;
! 1850:
! 1851: tag.key = ATTR_CLASS;
! 1852: tag.val = "addr";
! 1853: print_otag(h, TAG_SPAN, 1, &tag);
! 1854: return(1);
! 1855: }
! 1856:
! 1857:
! 1858: /* ARGSUSED */
! 1859: static int
! 1860: mdoc_an_pre(MDOC_ARGS)
! 1861: {
! 1862: struct htmlpair tag;
! 1863:
! 1864: tag.key = ATTR_CLASS;
! 1865: tag.val = "author";
! 1866: print_otag(h, TAG_SPAN, 1, &tag);
! 1867: return(1);
! 1868: }
! 1869:
! 1870:
! 1871: /* ARGSUSED */
! 1872: static int
! 1873: mdoc_cd_pre(MDOC_ARGS)
! 1874: {
! 1875: struct htmlpair tag;
! 1876:
! 1877: tag.key = ATTR_CLASS;
! 1878: tag.val = "config";
! 1879: print_otag(h, TAG_SPAN, 1, &tag);
! 1880: return(1);
! 1881: }
! 1882:
! 1883:
! 1884: /* ARGSUSED */
! 1885: static int
! 1886: mdoc_dv_pre(MDOC_ARGS)
! 1887: {
! 1888: struct htmlpair tag;
! 1889:
! 1890: tag.key = ATTR_CLASS;
! 1891: tag.val = "define";
! 1892: print_otag(h, TAG_SPAN, 1, &tag);
! 1893: return(1);
! 1894: }
! 1895:
! 1896:
! 1897: /* ARGSUSED */
! 1898: static int
! 1899: mdoc_ev_pre(MDOC_ARGS)
! 1900: {
! 1901: struct htmlpair tag;
! 1902:
! 1903: tag.key = ATTR_CLASS;
! 1904: tag.val = "env";
! 1905: print_otag(h, TAG_SPAN, 1, &tag);
! 1906: return(1);
! 1907: }
! 1908:
! 1909:
! 1910: /* ARGSUSED */
! 1911: static int
! 1912: mdoc_er_pre(MDOC_ARGS)
! 1913: {
! 1914: struct htmlpair tag;
! 1915:
! 1916: tag.key = ATTR_CLASS;
! 1917: tag.val = "errno";
! 1918: print_otag(h, TAG_SPAN, 1, &tag);
! 1919: return(1);
! 1920: }
! 1921:
! 1922:
! 1923: /* ARGSUSED */
! 1924: static int
! 1925: mdoc_fa_pre(MDOC_ARGS)
! 1926: {
! 1927: const struct mdoc_node *nn;
! 1928: struct htmlpair tag;
! 1929: struct tag *t;
! 1930:
! 1931: tag.key = ATTR_CLASS;
! 1932: tag.val = "farg";
! 1933:
! 1934: if (n->parent->tok != MDOC_Fo) {
! 1935: print_otag(h, TAG_SPAN, 1, &tag);
! 1936: return(1);
! 1937: }
! 1938:
! 1939: for (nn = n->child; nn; nn = nn->next) {
! 1940: t = print_otag(h, TAG_SPAN, 1, &tag);
! 1941: print_text(h, nn->string);
! 1942: print_tagq(h, t);
! 1943: if (nn->next)
! 1944: print_text(h, ",");
! 1945: }
! 1946:
! 1947: if (n->child && n->next && n->next->tok == MDOC_Fa)
! 1948: print_text(h, ",");
! 1949:
! 1950: return(0);
! 1951: }
! 1952:
! 1953:
! 1954: /* ARGSUSED */
! 1955: static int
! 1956: mdoc_fd_pre(MDOC_ARGS)
! 1957: {
! 1958: struct htmlpair tag;
! 1959:
! 1960: if (SEC_SYNOPSIS == n->sec) {
! 1961: if (n->next && MDOC_Fd != n->next->tok) {
! 1962: tag.key = ATTR_STYLE;
! 1963: tag.val = "margin-bottom: 1em;";
! 1964: print_otag(h, TAG_DIV, 1, &tag);
! 1965: } else
! 1966: print_otag(h, TAG_DIV, 0, NULL);
! 1967: }
! 1968:
! 1969: tag.key = ATTR_CLASS;
! 1970: tag.val = "macro";
! 1971: print_otag(h, TAG_SPAN, 1, &tag);
! 1972: return(1);
! 1973: }
! 1974:
! 1975:
! 1976: /* ARGSUSED */
! 1977: static int
! 1978: mdoc_vt_pre(MDOC_ARGS)
! 1979: {
! 1980: struct htmlpair tag;
! 1981:
! 1982: if (SEC_SYNOPSIS == n->sec) {
! 1983: if (n->next && MDOC_Vt != n->next->tok) {
! 1984: tag.key = ATTR_STYLE;
! 1985: tag.val = "margin-bottom: 1em;";
! 1986: print_otag(h, TAG_DIV, 1, &tag);
! 1987: } else
! 1988: print_otag(h, TAG_DIV, 0, NULL);
! 1989: }
! 1990:
! 1991: tag.key = ATTR_CLASS;
! 1992: tag.val = "type";
! 1993: print_otag(h, TAG_SPAN, 1, &tag);
! 1994: return(1);
! 1995: }
! 1996:
! 1997: /* ARGSUSED */
! 1998: static int
! 1999: mdoc_ft_pre(MDOC_ARGS)
! 2000: {
! 2001: struct htmlpair tag;
! 2002:
! 2003: if (SEC_SYNOPSIS == n->sec) {
! 2004: if (n->prev && MDOC_Fo == n->prev->tok) {
! 2005: tag.key = ATTR_STYLE;
! 2006: tag.val = "magin-bottom: 1em;";
! 2007: print_otag(h, TAG_DIV, 1, &tag);
! 2008: } else
! 2009: print_otag(h, TAG_DIV, 0, NULL);
! 2010: }
! 2011:
! 2012: tag.key = ATTR_CLASS;
! 2013: tag.val = "type";
! 2014: print_otag(h, TAG_SPAN, 1, &tag);
! 2015: return(1);
! 2016: }
! 2017:
! 2018:
! 2019: /* ARGSUSED */
! 2020: static int
! 2021: mdoc_fn_pre(MDOC_ARGS)
! 2022: {
! 2023: struct tag *t;
! 2024: struct htmlpair tag;
! 2025: const struct mdoc_node *nn;
! 2026:
! 2027: if (SEC_SYNOPSIS == n->sec) {
! 2028: if (n->next) {
! 2029: tag.key = ATTR_STYLE;
! 2030: tag.val = "margin-bottom: 1em";
! 2031: print_otag(h, TAG_DIV, 1, &tag);
! 2032: } else
! 2033: print_otag(h, TAG_DIV, 0, NULL);
! 2034: }
! 2035:
! 2036: tag.key = ATTR_CLASS;
! 2037: tag.val = "type";
! 2038:
! 2039: t = print_otag(h, TAG_SPAN, 1, &tag);
! 2040: print_text(h, n->child->string);
! 2041: print_tagq(h, t);
! 2042:
! 2043: h->flags |= HTML_NOSPACE;
! 2044: print_text(h, "(");
! 2045:
! 2046: for (nn = n->child->next; nn; nn = nn->next) {
! 2047: tag.key = ATTR_CLASS;
! 2048: tag.val = "farg";
! 2049: t = print_otag(h, TAG_SPAN, 1, &tag);
! 2050: print_text(h, nn->string);
! 2051: print_tagq(h, t);
! 2052: if (nn->next)
! 2053: print_text(h, ",");
! 2054: }
! 2055:
! 2056: print_text(h, ")");
! 2057:
! 2058: if (SEC_SYNOPSIS == n->sec)
! 2059: print_text(h, ";");
! 2060:
! 2061: return(0);
! 2062: }
CVSweb