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