Annotation of mandoc/html.c, Revision 1.44
1.44 ! kristaps 1: /* $Id: html.c,v 1.43 2009/09/21 13:06:13 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.44 ! kristaps 409: char *toks[3], *v;
1.43 kristaps 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.44 ! kristaps 426: while (*outopts)
1.43 kristaps 427: switch (getsubopt(&outopts, toks, &v)) {
428: case (0):
429: h->style = v;
430: break;
431: case (1):
432: h->base = v;
433: break;
434: default:
435: break;
436: }
437:
1.30 kristaps 438: return(h);
1.29 kristaps 439: }
1.10 kristaps 440:
1.33 kristaps 441:
1.29 kristaps 442: void
443: html_free(void *p)
444: {
1.30 kristaps 445: struct tag *tag;
1.37 kristaps 446: struct ord *ord;
1.30 kristaps 447: struct html *h;
448:
449: h = (struct html *)p;
1.10 kristaps 450:
1.37 kristaps 451: while ( ! SLIST_EMPTY(&h->ords)) {
452: ord = SLIST_FIRST(&h->ords);
453: SLIST_REMOVE_HEAD(&h->ords, entry);
454: free(ord);
455: }
456:
457: while ( ! SLIST_EMPTY(&h->tags)) {
458: tag = SLIST_FIRST(&h->tags);
459: SLIST_REMOVE_HEAD(&h->tags, entry);
1.30 kristaps 460: free(tag);
461: }
1.36 kristaps 462:
463: if (h->symtab)
464: chars_free(h->symtab);
1.30 kristaps 465: free(h);
1.10 kristaps 466: }
1.2 kristaps 467:
1.33 kristaps 468:
1.43 kristaps 469: static int
470: a2list(const struct mdoc_node *n)
471: {
472: int i;
473:
474: assert(MDOC_BLOCK == n->type && MDOC_Bl == n->tok);
475: assert(n->args);
476:
477: for (i = 0; i < (int)n->args->argc; i++)
478: switch (n->args->argv[i].arg) {
479: case (MDOC_Enum):
480: /* FALLTHROUGH */
481: case (MDOC_Dash):
482: /* FALLTHROUGH */
483: case (MDOC_Hyphen):
484: /* FALLTHROUGH */
485: case (MDOC_Bullet):
486: /* FALLTHROUGH */
487: case (MDOC_Tag):
488: /* FALLTHROUGH */
489: case (MDOC_Hang):
490: /* FALLTHROUGH */
491: case (MDOC_Inset):
492: /* FALLTHROUGH */
493: case (MDOC_Diag):
494: /* FALLTHROUGH */
495: case (MDOC_Item):
496: /* FALLTHROUGH */
497: case (MDOC_Column):
498: /* FALLTHROUGH */
499: case (MDOC_Ohang):
500: return(n->args->argv[i].arg);
501: default:
502: break;
503: }
504:
505: abort();
506: /* NOTREACHED */
507: }
508:
509:
510: static int
511: a2width(const char *p)
512: {
513: int i, len;
514:
515: if (0 == (len = (int)strlen(p)))
516: return(0);
517: for (i = 0; i < len - 1; i++)
518: if ( ! isdigit((u_char)p[i]))
519: break;
520:
521: if (i == len - 1)
522: if ('n' == p[len - 1] || 'm' == p[len - 1])
523: return(atoi(p) + 2);
524:
525: return(len + 2);
526: }
527:
528:
529: static int
530: a2offs(const char *p)
531: {
532: int len, i;
533:
534: if (0 == strcmp(p, "left"))
535: return(0);
536: if (0 == strcmp(p, "indent"))
537: return(INDENT + 1);
538: if (0 == strcmp(p, "indent-two"))
539: return((INDENT + 1) * 2);
540:
541: if (0 == (len = (int)strlen(p)))
542: return(0);
543:
544: for (i = 0; i < len - 1; i++)
545: if ( ! isdigit((u_char)p[i]))
546: break;
547:
548: if (i == len - 1)
549: if ('n' == p[len - 1] || 'm' == p[len - 1])
550: return(atoi(p));
551:
552: return(len);
553: }
554:
555:
1.29 kristaps 556: static void
557: print_mdoc(MDOC_ARGS)
1.4 kristaps 558: {
1.30 kristaps 559: struct tag *t;
1.4 kristaps 560:
1.30 kristaps 561: t = print_otag(h, TAG_HEAD, 0, NULL);
1.29 kristaps 562: print_mdoc_head(m, n, h);
1.30 kristaps 563: print_tagq(h, t);
564:
565: t = print_otag(h, TAG_BODY, 0, NULL);
1.39 kristaps 566: print_mdoc_nodelist(m, n, h);
1.30 kristaps 567: print_tagq(h, t);
1.29 kristaps 568: }
1.4 kristaps 569:
1.33 kristaps 570:
1.29 kristaps 571: static void
572: print_gen_head(struct html *h)
573: {
1.41 kristaps 574: struct htmlpair tag[4];
575:
576: tag[0].key = ATTR_HTTPEQUIV;
577: tag[0].val = "Content-Type";
578: tag[1].key = ATTR_CONTENT;
579: tag[1].val = "text/html; charset=utf-8";
580: print_otag(h, TAG_META, 2, tag);
581:
582: tag[0].key = ATTR_NAME;
583: tag[0].val = "resource-type";
584: tag[1].key = ATTR_CONTENT;
585: tag[1].val = "document";
586: print_otag(h, TAG_META, 2, tag);
587:
588: if (h->style) {
589: tag[0].key = ATTR_REL;
590: tag[0].val = "stylesheet";
591: tag[1].key = ATTR_HREF;
592: tag[1].val = h->style;
593: tag[2].key = ATTR_TYPE;
594: tag[2].val = "text/css";
595: tag[3].key = ATTR_MEDIA;
596: tag[3].val = "all";
597: print_otag(h, TAG_LINK, 4, tag);
598: }
599:
600: if (h->base) {
601: tag[0].key = ATTR_HREF;
602: tag[1].val = h->base;
603: print_otag(h, TAG_BASE, 1, tag);
604: }
1.4 kristaps 605: }
606:
1.33 kristaps 607:
1.30 kristaps 608: /* ARGSUSED */
1.29 kristaps 609: static void
610: print_mdoc_head(MDOC_ARGS)
1.18 kristaps 611: {
612:
1.29 kristaps 613: print_gen_head(h);
614: print_otag(h, TAG_TITLE, 0, NULL);
1.41 kristaps 615: print_text(h, m->title);
1.2 kristaps 616: }
617:
1.33 kristaps 618:
1.29 kristaps 619: static void
1.39 kristaps 620: print_mdoc_nodelist(MDOC_ARGS)
621: {
622:
623: print_mdoc_node(m, n, h);
624: if (n->next)
625: print_mdoc_nodelist(m, n->next, h);
626: }
627:
628:
629: static void
1.29 kristaps 630: print_mdoc_node(MDOC_ARGS)
1.2 kristaps 631: {
1.29 kristaps 632: int child;
1.30 kristaps 633: struct tag *t;
1.8 kristaps 634:
1.29 kristaps 635: child = 1;
1.37 kristaps 636: t = SLIST_FIRST(&h->tags);
1.8 kristaps 637:
1.35 kristaps 638: bufinit();
639:
1.29 kristaps 640: switch (n->type) {
641: case (MDOC_ROOT):
642: child = mdoc_root_pre(m, n, h);
1.7 kristaps 643: break;
1.29 kristaps 644: case (MDOC_TEXT):
645: print_text(h, n->string);
1.7 kristaps 646: break;
1.3 kristaps 647: default:
1.29 kristaps 648: if (mdocs[n->tok].pre)
649: child = (*mdocs[n->tok].pre)(m, n, h);
1.3 kristaps 650: break;
1.2 kristaps 651: }
652:
1.29 kristaps 653: if (child && n->child)
1.39 kristaps 654: print_mdoc_nodelist(m, n->child, h);
1.8 kristaps 655:
1.30 kristaps 656: print_stagq(h, t);
657:
1.35 kristaps 658: bufinit();
659:
1.29 kristaps 660: switch (n->type) {
661: case (MDOC_ROOT):
1.39 kristaps 662: mdoc_root_post(m, n, h);
1.7 kristaps 663: break;
1.29 kristaps 664: case (MDOC_TEXT):
1.7 kristaps 665: break;
1.3 kristaps 666: default:
1.29 kristaps 667: if (mdocs[n->tok].post)
668: (*mdocs[n->tok].post)(m, n, h);
1.3 kristaps 669: break;
670: }
1.2 kristaps 671: }
672:
1.33 kristaps 673:
1.29 kristaps 674: static void
675: print_man(MAN_ARGS)
1.9 kristaps 676: {
1.30 kristaps 677: struct tag *t;
1.9 kristaps 678:
1.30 kristaps 679: t = print_otag(h, TAG_HEAD, 0, NULL);
1.29 kristaps 680: print_man_head(m, n, h);
1.30 kristaps 681: print_tagq(h, t);
682:
683: t = print_otag(h, TAG_BODY, 0, NULL);
1.41 kristaps 684: /*print_man_body(m, n, h);*/
1.30 kristaps 685: print_tagq(h, t);
1.9 kristaps 686: }
687:
1.33 kristaps 688:
1.30 kristaps 689: /* ARGSUSED */
1.9 kristaps 690: static void
1.29 kristaps 691: print_man_head(MAN_ARGS)
1.9 kristaps 692: {
693:
1.29 kristaps 694: print_gen_head(h);
695: print_otag(h, TAG_TITLE, 0, NULL);
1.41 kristaps 696: print_text(h, m->title);
1.9 kristaps 697: }
698:
1.33 kristaps 699:
1.32 kristaps 700: static void
701: print_spec(struct html *h, const char *p, int len)
702: {
703: const char *rhs;
704: int i;
705: size_t sz;
706:
707: rhs = chars_a2ascii(h->symtab, p, (size_t)len, &sz);
708:
709: if (NULL == rhs)
710: return;
711: for (i = 0; i < (int)sz; i++)
712: putchar(rhs[i]);
713: }
714:
1.33 kristaps 715:
1.32 kristaps 716: static void
717: print_res(struct html *h, const char *p, int len)
718: {
719: const char *rhs;
720: int i;
721: size_t sz;
722:
723: rhs = chars_a2res(h->symtab, p, (size_t)len, &sz);
724:
725: if (NULL == rhs)
726: return;
727: for (i = 0; i < (int)sz; i++)
728: putchar(rhs[i]);
729: }
730:
1.33 kristaps 731:
1.32 kristaps 732: static void
733: print_escape(struct html *h, const char **p)
734: {
735: int j, type;
736: const char *wp;
737:
738: wp = *p;
739: type = 1;
740:
741: if (0 == *(++wp)) {
742: *p = wp;
743: return;
744: }
745:
746: if ('(' == *wp) {
747: wp++;
748: if (0 == *wp || 0 == *(wp + 1)) {
749: *p = 0 == *wp ? wp : wp + 1;
750: return;
751: }
752:
753: print_spec(h, wp, 2);
754: *p = ++wp;
755: return;
756:
757: } else if ('*' == *wp) {
758: if (0 == *(++wp)) {
759: *p = wp;
760: return;
761: }
762:
763: switch (*wp) {
764: case ('('):
765: wp++;
766: if (0 == *wp || 0 == *(wp + 1)) {
767: *p = 0 == *wp ? wp : wp + 1;
768: return;
769: }
770:
771: print_res(h, wp, 2);
772: *p = ++wp;
773: return;
774: case ('['):
775: type = 0;
776: break;
777: default:
778: print_res(h, wp, 1);
779: *p = wp;
780: return;
781: }
782:
783: } else if ('f' == *wp) {
784: if (0 == *(++wp)) {
785: *p = wp;
786: return;
787: }
788:
789: switch (*wp) {
790: case ('B'):
791: /* TODO */
792: break;
793: case ('I'):
794: /* TODO */
795: break;
796: case ('P'):
797: /* FALLTHROUGH */
798: case ('R'):
799: /* TODO */
800: break;
801: default:
802: break;
803: }
804:
805: *p = wp;
806: return;
807:
808: } else if ('[' != *wp) {
809: print_spec(h, wp, 1);
810: *p = wp;
811: return;
812: }
813:
814: wp++;
815: for (j = 0; *wp && ']' != *wp; wp++, j++)
816: /* Loop... */ ;
817:
818: if (0 == *wp) {
819: *p = wp;
820: return;
821: }
822:
823: if (type)
824: print_spec(h, wp - j, j);
825: else
826: print_res(h, wp - j, j);
827:
828: *p = wp;
829: }
830:
1.9 kristaps 831:
1.29 kristaps 832: static void
1.32 kristaps 833: print_encode(struct html *h, const char *p)
1.29 kristaps 834: {
1.14 kristaps 835:
1.32 kristaps 836: for (; *p; p++) {
1.34 kristaps 837: if ('\\' == *p) {
838: print_escape(h, &p);
839: continue;
840: }
841: switch (*p) {
842: case ('<'):
843: printf("<");
844: break;
845: case ('>'):
846: printf(">");
847: break;
848: case ('&'):
849: printf("&");
850: break;
851: default:
1.32 kristaps 852: putchar(*p);
1.34 kristaps 853: break;
1.32 kristaps 854: }
855: }
1.14 kristaps 856: }
857:
858:
1.30 kristaps 859: static struct tag *
1.29 kristaps 860: print_otag(struct html *h, enum htmltag tag,
861: int sz, const struct htmlpair *p)
1.14 kristaps 862: {
1.29 kristaps 863: int i;
1.30 kristaps 864: struct tag *t;
865:
866: if ( ! (HTML_NOSTACK & htmltags[tag].flags)) {
867: if (NULL == (t = malloc(sizeof(struct tag))))
868: err(EXIT_FAILURE, "malloc");
869: t->tag = tag;
1.37 kristaps 870: SLIST_INSERT_HEAD(&h->tags, t, entry);
1.30 kristaps 871: } else
872: t = NULL;
1.29 kristaps 873:
874: if ( ! (HTML_NOSPACE & h->flags))
1.30 kristaps 875: if ( ! (HTML_CLRLINE & htmltags[tag].flags))
1.29 kristaps 876: printf(" ");
877:
878: printf("<%s", htmltags[tag].name);
879: for (i = 0; i < sz; i++) {
880: printf(" %s=\"", htmlattrs[p[i].key]);
881: assert(p->val);
1.32 kristaps 882: print_encode(h, p[i].val);
1.29 kristaps 883: printf("\"");
884: }
885: printf(">");
1.14 kristaps 886:
1.29 kristaps 887: h->flags |= HTML_NOSPACE;
1.30 kristaps 888: if (HTML_CLRLINE & htmltags[tag].flags)
889: h->flags |= HTML_NEWLINE;
890: else
891: h->flags &= ~HTML_NEWLINE;
1.14 kristaps 892:
1.30 kristaps 893: return(t);
1.14 kristaps 894: }
895:
896:
897: /* ARGSUSED */
1.29 kristaps 898: static void
899: print_ctag(struct html *h, enum htmltag tag)
1.14 kristaps 900: {
901:
1.29 kristaps 902: printf("</%s>", htmltags[tag].name);
1.30 kristaps 903: if (HTML_CLRLINE & htmltags[tag].flags)
1.29 kristaps 904: h->flags |= HTML_NOSPACE;
1.30 kristaps 905: if (HTML_CLRLINE & htmltags[tag].flags)
906: h->flags |= HTML_NEWLINE;
907: else
908: h->flags &= ~HTML_NEWLINE;
1.14 kristaps 909: }
910:
911:
1.29 kristaps 912: /* ARGSUSED */
913: static void
914: print_gen_doctype(struct html *h)
1.1 kristaps 915: {
1.29 kristaps 916:
917: printf("<!DOCTYPE HTML PUBLIC \"%s\" \"%s\">\n", DOCTYPE, DTD);
1.1 kristaps 918: }
919:
920:
1.29 kristaps 921: static void
922: print_text(struct html *h, const char *p)
1.1 kristaps 923: {
924:
1.29 kristaps 925: if (*p && 0 == *(p + 1))
926: switch (*p) {
927: case('.'):
928: /* FALLTHROUGH */
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: h->flags |= HTML_NOSPACE;
1.30 kristaps 945: break;
1.29 kristaps 946: default:
947: break;
948: }
1.1 kristaps 949:
1.29 kristaps 950: if ( ! (h->flags & HTML_NOSPACE))
951: printf(" ");
1.30 kristaps 952:
1.29 kristaps 953: h->flags &= ~HTML_NOSPACE;
1.30 kristaps 954: h->flags &= ~HTML_NEWLINE;
1.1 kristaps 955:
1.29 kristaps 956: if (p)
1.32 kristaps 957: print_encode(h, p);
1.8 kristaps 958:
1.29 kristaps 959: if (*p && 0 == *(p + 1))
960: switch (*p) {
961: case('('):
962: /* FALLTHROUGH */
963: case('['):
964: /* FALLTHROUGH */
965: case('{'):
966: h->flags |= HTML_NOSPACE;
1.30 kristaps 967: break;
1.29 kristaps 968: default:
969: break;
970: }
1.1 kristaps 971: }
1.30 kristaps 972:
973:
974: static void
975: print_tagq(struct html *h, const struct tag *until)
976: {
977: struct tag *tag;
978:
1.37 kristaps 979: while ( ! SLIST_EMPTY(&h->tags)) {
980: tag = SLIST_FIRST(&h->tags);
1.30 kristaps 981: print_ctag(h, tag->tag);
1.37 kristaps 982: SLIST_REMOVE_HEAD(&h->tags, entry);
1.30 kristaps 983: free(tag);
984: if (until && tag == until)
985: return;
986: }
987: }
988:
989:
990: static void
991: print_stagq(struct html *h, const struct tag *suntil)
992: {
993: struct tag *tag;
994:
1.37 kristaps 995: while ( ! SLIST_EMPTY(&h->tags)) {
996: tag = SLIST_FIRST(&h->tags);
1.30 kristaps 997: if (suntil && tag == suntil)
998: return;
999: print_ctag(h, tag->tag);
1.37 kristaps 1000: SLIST_REMOVE_HEAD(&h->tags, entry);
1.30 kristaps 1001: free(tag);
1002: }
1003: }
1004:
1005:
1.39 kristaps 1006: /* ARGSUSED */
1007: static void
1008: mdoc_root_post(MDOC_ARGS)
1009: {
1.41 kristaps 1010: struct tm tm;
1011: struct htmlpair tag[2];
1012: struct tag *t, *tt;
1013: char b[BUFSIZ];
1.39 kristaps 1014:
1.41 kristaps 1015: (void)localtime_r(&m->date, &tm);
1.39 kristaps 1016:
1.41 kristaps 1017: if (0 == strftime(b, BUFSIZ - 1, "%B %e, %Y", &tm))
1.39 kristaps 1018: err(EXIT_FAILURE, "strftime");
1.33 kristaps 1019:
1.41 kristaps 1020: tag[0].key = ATTR_CLASS;
1021: tag[0].val = "footer";
1022: tag[1].key = ATTR_STYLE;
1023: tag[1].val = "width: 100%;";
1024: t = print_otag(h, TAG_TABLE, 2, tag);
1025: tt = print_otag(h, TAG_TR, 0, NULL);
1.33 kristaps 1026:
1.41 kristaps 1027: tag[0].key = ATTR_STYLE;
1028: tag[0].val = "width: 50%;";
1029: print_otag(h, TAG_TD, 1, tag);
1.39 kristaps 1030: print_text(h, b);
1.41 kristaps 1031: print_stagq(h, tt);
1.39 kristaps 1032:
1.41 kristaps 1033: tag[0].key = ATTR_STYLE;
1034: tag[0].val = "width: 50%; text-align: right;";
1035: print_otag(h, TAG_TD, 1, tag);
1036: print_text(h, m->os);
1.39 kristaps 1037: print_tagq(h, t);
1038: }
1039:
1040:
1.30 kristaps 1041: /* ARGSUSED */
1042: static int
1043: mdoc_root_pre(MDOC_ARGS)
1044: {
1.41 kristaps 1045: struct htmlpair tag[2];
1.39 kristaps 1046: struct tag *t, *tt;
1047: char b[BUFSIZ], title[BUFSIZ];
1048:
1049: (void)strlcpy(b, m->vol, BUFSIZ);
1050:
1051: if (m->arch) {
1.41 kristaps 1052: (void)strlcat(b, " (", BUFSIZ);
1053: (void)strlcat(b, m->arch, BUFSIZ);
1054: (void)strlcat(b, ")", BUFSIZ);
1.39 kristaps 1055: }
1056:
1.41 kristaps 1057: (void)snprintf(title, BUFSIZ - 1,
1058: "%s(%d)", m->title, m->msec);
1.39 kristaps 1059:
1.41 kristaps 1060: tag[0].key = ATTR_CLASS;
1061: tag[0].val = "body";
1062: t = print_otag(h, TAG_DIV, 1, tag);
1.39 kristaps 1063:
1.41 kristaps 1064: tag[0].key = ATTR_CLASS;
1065: tag[0].val = "header";
1066: tag[1].key = ATTR_STYLE;
1067: tag[1].val = "width: 100%;";
1068: print_otag(h, TAG_TABLE, 2, tag);
1069: tt = print_otag(h, TAG_TR, 0, NULL);
1.39 kristaps 1070:
1.41 kristaps 1071: tag[0].key = ATTR_STYLE;
1072: tag[0].val = "width: 33%;";
1073: print_otag(h, TAG_TD, 1, tag);
1.39 kristaps 1074: print_text(h, b);
1075: print_stagq(h, tt);
1076:
1.41 kristaps 1077: tag[0].key = ATTR_STYLE;
1078: tag[0].val = "width: 33%; text-align: center;";
1079: print_otag(h, TAG_TD, 1, tag);
1.39 kristaps 1080: print_text(h, title);
1081: print_stagq(h, tt);
1082:
1.41 kristaps 1083: tag[0].key = ATTR_STYLE;
1084: tag[0].val = "width: 33%; text-align: right;";
1085: print_otag(h, TAG_TD, 1, tag);
1.39 kristaps 1086: print_text(h, b);
1087: print_stagq(h, t);
1.30 kristaps 1088:
1089: return(1);
1090: }
1091:
1092:
1093: /* ARGSUSED */
1094: static int
1.35 kristaps 1095: mdoc_sh_pre(MDOC_ARGS)
1.30 kristaps 1096: {
1.41 kristaps 1097: struct htmlpair tag[2];
1098: const struct mdoc_node *nn;
1.34 kristaps 1099:
1.35 kristaps 1100: if (MDOC_HEAD == n->type) {
1101: tag[0].key = ATTR_CLASS;
1102: tag[0].val = "sec-head";
1103: print_otag(h, TAG_DIV, 1, tag);
1104: print_otag(h, TAG_SPAN, 1, tag);
1.41 kristaps 1105:
1106: for (nn = n->child; nn; nn = nn->next) {
1107: bufcat(nn->string);
1108: if (nn->next)
1109: bufcat(" ");
1110: }
1111: tag[0].key = ATTR_NAME;
1112: tag[0].val = buf;
1113: print_otag(h, TAG_A, 1, tag);
1.35 kristaps 1114: return(1);
1115: } else if (MDOC_BLOCK == n->type) {
1116: tag[0].key = ATTR_CLASS;
1117: tag[0].val = "sec-block";
1.39 kristaps 1118:
1119: if (n->prev && NULL == n->prev->body->child) {
1120: print_otag(h, TAG_DIV, 1, tag);
1121: return(1);
1122: }
1123:
1.40 kristaps 1124: bufcat("margin-top: 1em;");
1125: if (NULL == n->next)
1126: bufcat("margin-bottom: 1em;");
1127:
1.39 kristaps 1128: tag[1].key = ATTR_STYLE;
1.40 kristaps 1129: tag[1].val = buf;
1.39 kristaps 1130:
1131: print_otag(h, TAG_DIV, 2, tag);
1.35 kristaps 1132: return(1);
1133: }
1134:
1135: buffmt("margin-left: %dem;", INDENT);
1136:
1.34 kristaps 1137: tag[0].key = ATTR_CLASS;
1.35 kristaps 1138: tag[0].val = "sec-body";
1139: tag[1].key = ATTR_STYLE;
1140: tag[1].val = buf;
1141:
1142: print_otag(h, TAG_DIV, 2, tag);
1143: return(1);
1144: }
1145:
1146:
1147: /* ARGSUSED */
1148: static int
1149: mdoc_ss_pre(MDOC_ARGS)
1150: {
1.41 kristaps 1151: struct htmlpair tag[2];
1152: int i;
1153: const struct mdoc_node *nn;
1.35 kristaps 1154:
1155: i = 0;
1156:
1157: if (MDOC_BODY == n->type) {
1158: tag[i].key = ATTR_CLASS;
1159: tag[i++].val = "ssec-body";
1160: if (n->parent->next && n->child) {
1161: bufcat("margin-bottom: 1em;");
1162: tag[i].key = ATTR_STYLE;
1163: tag[i++].val = buf;
1164: }
1165: print_otag(h, TAG_DIV, i, tag);
1166: return(1);
1167: } else if (MDOC_BLOCK == n->type) {
1168: tag[i].key = ATTR_CLASS;
1169: tag[i++].val = "ssec-block";
1170: if (n->prev) {
1171: bufcat("margin-top: 1em;");
1172: tag[i].key = ATTR_STYLE;
1173: tag[i++].val = buf;
1174: }
1175: print_otag(h, TAG_DIV, i, tag);
1176: return(1);
1177: }
1178:
1179: buffmt("margin-left: -%dem;", INDENT - HALFINDENT);
1.34 kristaps 1180:
1.35 kristaps 1181: tag[0].key = ATTR_CLASS;
1182: tag[0].val = "ssec-head";
1.34 kristaps 1183: tag[1].key = ATTR_STYLE;
1.35 kristaps 1184: tag[1].val = buf;
1.30 kristaps 1185:
1.35 kristaps 1186: print_otag(h, TAG_DIV, 2, tag);
1187: print_otag(h, TAG_SPAN, 1, tag);
1.41 kristaps 1188:
1189: bufinit();
1190: for (nn = n->child; nn; nn = nn->next) {
1191: bufcat(nn->string);
1192: if (nn->next)
1193: bufcat(" ");
1194: }
1195: tag[0].key = ATTR_NAME;
1196: tag[0].val = buf;
1197: print_otag(h, TAG_A, 1, tag);
1198:
1.30 kristaps 1199: return(1);
1200: }
1201:
1202:
1203: /* ARGSUSED */
1204: static int
1205: mdoc_fl_pre(MDOC_ARGS)
1206: {
1207: struct htmlpair tag;
1208:
1209: tag.key = ATTR_CLASS;
1210: tag.val = "flag";
1211:
1212: print_otag(h, TAG_SPAN, 1, &tag);
1.41 kristaps 1213: if (MDOC_Fl == n->tok) {
1214: print_text(h, "\\-");
1215: h->flags |= HTML_NOSPACE;
1216: }
1.30 kristaps 1217: return(1);
1218: }
1219:
1220:
1221: /* ARGSUSED */
1222: static int
1223: mdoc_pp_pre(MDOC_ARGS)
1224: {
1.34 kristaps 1225: struct htmlpair tag;
1.30 kristaps 1226:
1.34 kristaps 1227: tag.key = ATTR_STYLE;
1.41 kristaps 1228: tag.val = "clear: both; height: 1em;";
1.35 kristaps 1229: print_otag(h, TAG_DIV, 1, &tag);
1.30 kristaps 1230: return(0);
1231: }
1232:
1233:
1234: /* ARGSUSED */
1235: static int
1236: mdoc_nd_pre(MDOC_ARGS)
1237: {
1.35 kristaps 1238: struct htmlpair tag;
1239:
1240: if (MDOC_BODY != n->type)
1241: return(1);
1.30 kristaps 1242:
1.35 kristaps 1243: /* XXX - this can contain block elements! */
1244: print_text(h, "\\(em");
1245: tag.key = ATTR_CLASS;
1246: tag.val = "desc-body";
1247: print_otag(h, TAG_SPAN, 1, &tag);
1.30 kristaps 1248: return(1);
1249: }
1250:
1251:
1252: /* ARGSUSED */
1253: static int
1254: mdoc_op_pre(MDOC_ARGS)
1255: {
1.35 kristaps 1256: struct htmlpair tag;
1257:
1258: if (MDOC_BODY != n->type)
1259: return(1);
1.30 kristaps 1260:
1.35 kristaps 1261: /* XXX - this can contain block elements! */
1262: print_text(h, "\\(lB");
1263: tag.key = ATTR_CLASS;
1264: tag.val = "opt";
1265: print_otag(h, TAG_SPAN, 1, &tag);
1.30 kristaps 1266: return(1);
1267: }
1268:
1269:
1270: /* ARGSUSED */
1271: static void
1272: mdoc_op_post(MDOC_ARGS)
1273: {
1274:
1275: if (MDOC_BODY != n->type)
1276: return;
1277: h->flags |= HTML_NOSPACE;
1278: print_text(h, "\\(rB");
1279: }
1280:
1281:
1282: static int
1283: mdoc_nm_pre(MDOC_ARGS)
1284: {
1.35 kristaps 1285: struct htmlpair tag;
1.30 kristaps 1286:
1287: if ( ! (HTML_NEWLINE & h->flags))
1.35 kristaps 1288: if (SEC_SYNOPSIS == n->sec) {
1289: tag.key = ATTR_STYLE;
1290: tag.val = "clear: both;";
1291: print_otag(h, TAG_BR, 1, &tag);
1292: }
1.30 kristaps 1293:
1.35 kristaps 1294: tag.key = ATTR_CLASS;
1295: tag.val = "name";
1.30 kristaps 1296:
1.35 kristaps 1297: print_otag(h, TAG_SPAN, 1, &tag);
1.30 kristaps 1298: if (NULL == n->child)
1299: print_text(h, m->name);
1300:
1301: return(1);
1302: }
1303:
1304:
1305: /* ARGSUSED */
1306: static int
1307: mdoc_xr_pre(MDOC_ARGS)
1308: {
1.41 kristaps 1309: struct htmlpair tag[2];
1310: const char *name, *sec;
1311: const struct mdoc_node *nn;
1312:
1313: nn = n->child;
1314: name = nn && nn->string ? nn->string : "";
1315: nn = nn ? nn->next : NULL;
1316: sec = nn && nn->string ? nn->string : "";
1317:
1318: buffmt("%s%s%s.html", name, name && sec ? "." : "", sec);
1.30 kristaps 1319:
1.35 kristaps 1320: tag[0].key = ATTR_CLASS;
1321: tag[0].val = "link-man";
1322: tag[1].key = ATTR_HREF;
1.41 kristaps 1323: tag[1].val = buf;
1.35 kristaps 1324: print_otag(h, TAG_A, 2, tag);
1.30 kristaps 1325:
1.41 kristaps 1326: nn = n->child;
1327: print_text(h, nn->string);
1328: if (NULL == (nn = nn->next))
1.30 kristaps 1329: return(0);
1330:
1331: h->flags |= HTML_NOSPACE;
1332: print_text(h, "(");
1333: h->flags |= HTML_NOSPACE;
1.41 kristaps 1334: print_text(h, nn->string);
1.30 kristaps 1335: h->flags |= HTML_NOSPACE;
1336: print_text(h, ")");
1337:
1338: return(0);
1339: }
1.31 kristaps 1340:
1341:
1342: /* ARGSUSED */
1343: static int
1344: mdoc_ns_pre(MDOC_ARGS)
1345: {
1346:
1347: h->flags |= HTML_NOSPACE;
1348: return(1);
1349: }
1350:
1.35 kristaps 1351:
1.31 kristaps 1352: /* ARGSUSED */
1353: static int
1354: mdoc_ar_pre(MDOC_ARGS)
1355: {
1356: struct htmlpair tag;
1357:
1358: tag.key = ATTR_CLASS;
1359: tag.val = "arg";
1360:
1361: print_otag(h, TAG_SPAN, 1, &tag);
1362: return(1);
1363: }
1.33 kristaps 1364:
1.35 kristaps 1365:
1.33 kristaps 1366: /* ARGSUSED */
1367: static int
1368: mdoc_xx_pre(MDOC_ARGS)
1369: {
1370: const char *pp;
1.35 kristaps 1371: struct htmlpair tag;
1.33 kristaps 1372:
1373: switch (n->tok) {
1374: case (MDOC_Bsx):
1375: pp = "BSDI BSD/OS";
1376: break;
1377: case (MDOC_Dx):
1378: pp = "DragonFlyBSD";
1379: break;
1380: case (MDOC_Fx):
1381: pp = "FreeBSD";
1382: break;
1383: case (MDOC_Nx):
1384: pp = "NetBSD";
1385: break;
1386: case (MDOC_Ox):
1387: pp = "OpenBSD";
1388: break;
1389: case (MDOC_Ux):
1390: pp = "UNIX";
1391: break;
1392: default:
1393: return(1);
1394: }
1395:
1.35 kristaps 1396: tag.key = ATTR_CLASS;
1397: tag.val = "unix";
1398:
1399: print_otag(h, TAG_SPAN, 1, &tag);
1.33 kristaps 1400: print_text(h, pp);
1401: return(1);
1402: }
1403:
1404:
1.35 kristaps 1405: /* ARGSUSED */
1.33 kristaps 1406: static int
1.37 kristaps 1407: mdoc_tbl_block_pre(MDOC_ARGS, int t, int w, int o, int c)
1.34 kristaps 1408: {
1409: struct htmlpair tag;
1410:
1.37 kristaps 1411: switch (t) {
1.38 kristaps 1412: case (MDOC_Column):
1413: /* FALLTHROUGH */
1.37 kristaps 1414: case (MDOC_Item):
1415: /* FALLTHROUGH */
1416: case (MDOC_Ohang):
1417: buffmt("margin-left: %dem; clear: both;", o);
1418: break;
1419: default:
1420: buffmt("margin-left: %dem; clear: both;", w + o);
1421: break;
1422: }
1.34 kristaps 1423:
1.37 kristaps 1424: if ( ! c && n->prev && n->prev->body->child)
1.35 kristaps 1425: bufcat("padding-top: 1em;");
1.34 kristaps 1426:
1427: tag.key = ATTR_STYLE;
1428: tag.val = buf;
1429: print_otag(h, TAG_DIV, 1, &tag);
1430: return(1);
1431: }
1432:
1433:
1.35 kristaps 1434: /* ARGSUSED */
1.34 kristaps 1435: static int
1436: mdoc_tbl_body_pre(MDOC_ARGS, int t, int w)
1437: {
1438:
1.37 kristaps 1439: print_otag(h, TAG_DIV, 0, NULL);
1.34 kristaps 1440: return(1);
1441: }
1442:
1443:
1.35 kristaps 1444: /* ARGSUSED */
1.34 kristaps 1445: static int
1.35 kristaps 1446: mdoc_tbl_head_pre(MDOC_ARGS, int t, int w)
1.33 kristaps 1447: {
1.34 kristaps 1448: struct htmlpair tag;
1.37 kristaps 1449: struct ord *ord;
1450: char nbuf[BUFSIZ];
1.34 kristaps 1451:
1.35 kristaps 1452: switch (t) {
1.37 kristaps 1453: case (MDOC_Item):
1.35 kristaps 1454: /* FALLTHROUGH */
1.37 kristaps 1455: case (MDOC_Ohang):
1456: print_otag(h, TAG_DIV, 0, NULL);
1457: break;
1.38 kristaps 1458: case (MDOC_Column):
1459: buffmt("min-width: %dem;", w);
1460: bufcat("clear: none;");
1461: if (n->next && MDOC_HEAD == n->next->type)
1462: bufcat("float: left;");
1463: tag.key = ATTR_STYLE;
1464: tag.val = buf;
1465: print_otag(h, TAG_DIV, 1, &tag);
1466: break;
1.37 kristaps 1467: default:
1.35 kristaps 1468: buffmt("margin-left: -%dem;", w);
1469: bufcat("clear: left;");
1470: bufcat("float: left;");
1471: bufcat("padding-right: 1em;");
1.37 kristaps 1472: tag.key = ATTR_STYLE;
1473: tag.val = buf;
1474: print_otag(h, TAG_DIV, 1, &tag);
1.34 kristaps 1475: break;
1.37 kristaps 1476: }
1477:
1478: switch (t) {
1479: case (MDOC_Diag):
1480: tag.key = ATTR_CLASS;
1481: tag.val = "diag";
1482: print_otag(h, TAG_SPAN, 1, &tag);
1483: break;
1484: case (MDOC_Enum):
1485: ord = SLIST_FIRST(&h->ords);
1486: assert(ord);
1487: nbuf[BUFSIZ - 1] = 0;
1488: (void)snprintf(nbuf, BUFSIZ - 1, "%d.", ord->pos++);
1489: print_text(h, nbuf);
1490: return(0);
1491: case (MDOC_Dash):
1492: print_text(h, "\\(en");
1493: return(0);
1494: case (MDOC_Hyphen):
1495: print_text(h, "\\-");
1496: return(0);
1497: case (MDOC_Bullet):
1498: print_text(h, "\\(bu");
1499: return(0);
1.34 kristaps 1500: default:
1501: break;
1.33 kristaps 1502: }
1503:
1.34 kristaps 1504: return(1);
1505: }
1506:
1507:
1508: static int
1509: mdoc_tbl_pre(MDOC_ARGS, int type)
1510: {
1.38 kristaps 1511: int i, w, o, c, wp;
1512: const struct mdoc_node *bl, *nn;
1.34 kristaps 1513:
1.33 kristaps 1514: bl = n->parent->parent;
1515: if (MDOC_BLOCK != n->type)
1516: bl = bl->parent;
1517:
1.34 kristaps 1518: /* FIXME: fmt_vspace() equivalent. */
1519:
1.33 kristaps 1520: assert(bl->args);
1521:
1.34 kristaps 1522: w = o = c = 0;
1.38 kristaps 1523: wp = -1;
1.34 kristaps 1524:
1525: for (i = 0; i < (int)bl->args->argc; i++)
1.33 kristaps 1526: if (MDOC_Width == bl->args->argv[i].arg) {
1527: assert(bl->args->argv[i].sz);
1.38 kristaps 1528: wp = i;
1.43 kristaps 1529: w = a2width(bl->args->argv[i].value[0]);
1.34 kristaps 1530: } else if (MDOC_Offset == bl->args->argv[i].arg) {
1531: assert(bl->args->argv[i].sz);
1.43 kristaps 1532: o = a2offs(bl->args->argv[i].value[0]);
1.34 kristaps 1533: } else if (MDOC_Compact == bl->args->argv[i].arg)
1534: c = 1;
1.38 kristaps 1535:
1536: if (MDOC_HEAD == n->type && MDOC_Column == type) {
1537: nn = n->parent->child;
1538: assert(nn && MDOC_HEAD == nn->type);
1539: for (i = 0; nn && nn != n; nn = nn->next, i++)
1540: /* Counter... */ ;
1541: assert(nn);
1542: if (wp >= 0 && i < (int)bl->args[wp].argv->sz)
1.43 kristaps 1543: w = a2width(bl->args->argv[wp].value[i]);
1.38 kristaps 1544: }
1.34 kristaps 1545:
1.37 kristaps 1546: switch (type) {
1547: case (MDOC_Enum):
1548: /* FALLTHROUGH */
1549: case (MDOC_Dash):
1550: /* FALLTHROUGH */
1551: case (MDOC_Hyphen):
1552: /* FALLTHROUGH */
1553: case (MDOC_Bullet):
1554: if (w < 4)
1555: w = 4;
1556: break;
1557: case (MDOC_Inset):
1558: /* FALLTHROUGH */
1559: case (MDOC_Diag):
1560: w = 1;
1561: break;
1562: default:
1563: if (0 == w)
1564: w = 10;
1565: break;
1566: }
1567:
1.34 kristaps 1568: switch (n->type) {
1569: case (MDOC_BLOCK):
1570: break;
1571: case (MDOC_HEAD):
1572: return(mdoc_tbl_head_pre(m, n, h, type, w));
1573: case (MDOC_BODY):
1574: return(mdoc_tbl_body_pre(m, n, h, type, w));
1575: default:
1576: abort();
1577: /* NOTREACHED */
1578: }
1579:
1.37 kristaps 1580: return(mdoc_tbl_block_pre(m, n, h, type, w, o, c));
1.34 kristaps 1581: }
1582:
1583:
1.41 kristaps 1584: /* ARGSUSED */
1.34 kristaps 1585: static int
1.37 kristaps 1586: mdoc_bl_pre(MDOC_ARGS)
1.34 kristaps 1587: {
1.37 kristaps 1588: struct ord *ord;
1.34 kristaps 1589:
1590: if (MDOC_BLOCK != n->type)
1591: return(1);
1.43 kristaps 1592: if (MDOC_Enum != a2list(n))
1.37 kristaps 1593: return(1);
1.34 kristaps 1594:
1.37 kristaps 1595: ord = malloc(sizeof(struct ord));
1596: if (NULL == ord)
1597: err(EXIT_FAILURE, "malloc");
1598: ord->cookie = n;
1599: ord->pos = 1;
1600: SLIST_INSERT_HEAD(&h->ords, ord, entry);
1.33 kristaps 1601:
1602: return(1);
1603: }
1604:
1605:
1.41 kristaps 1606: /* ARGSUSED */
1.37 kristaps 1607: static void
1608: mdoc_bl_post(MDOC_ARGS)
1.33 kristaps 1609: {
1.37 kristaps 1610: struct ord *ord;
1.33 kristaps 1611:
1.34 kristaps 1612: if (MDOC_BLOCK != n->type)
1.37 kristaps 1613: return;
1.43 kristaps 1614: if (MDOC_Enum != a2list(n))
1.37 kristaps 1615: return;
1.33 kristaps 1616:
1.37 kristaps 1617: ord = SLIST_FIRST(&h->ords);
1618: assert(ord);
1619: SLIST_REMOVE_HEAD(&h->ords, entry);
1620: free(ord);
1.33 kristaps 1621: }
1622:
1623:
1624: static int
1.34 kristaps 1625: mdoc_it_pre(MDOC_ARGS)
1.33 kristaps 1626: {
1.37 kristaps 1627: int type;
1.33 kristaps 1628:
1.34 kristaps 1629: if (MDOC_BLOCK == n->type)
1.43 kristaps 1630: type = a2list(n->parent->parent);
1.34 kristaps 1631: else
1.43 kristaps 1632: type = a2list(n->parent->parent->parent);
1.33 kristaps 1633:
1.37 kristaps 1634: return(mdoc_tbl_pre(m, n, h, type));
1.33 kristaps 1635: }
1.34 kristaps 1636:
1637:
1638: /* ARGSUSED */
1639: static int
1640: mdoc_ex_pre(MDOC_ARGS)
1641: {
1642: const struct mdoc_node *nn;
1643: struct tag *t;
1644: struct htmlpair tag;
1645:
1646: print_text(h, "The");
1647:
1648: tag.key = ATTR_CLASS;
1649: tag.val = "utility";
1650:
1651: for (nn = n->child; nn; nn = nn->next) {
1652: t = print_otag(h, TAG_SPAN, 1, &tag);
1653: print_text(h, nn->string);
1654: print_tagq(h, t);
1655:
1656: h->flags |= HTML_NOSPACE;
1657:
1658: if (nn->next && NULL == nn->next->next)
1659: print_text(h, ", and");
1660: else if (nn->next)
1661: print_text(h, ",");
1662: else
1663: h->flags &= ~HTML_NOSPACE;
1664: }
1665:
1666: if (n->child->next)
1667: print_text(h, "utilities exit");
1668: else
1669: print_text(h, "utility exits");
1670:
1671: print_text(h, "0 on success, and >0 if an error occurs.");
1672: return(0);
1673: }
1674:
1675:
1676: /* ARGSUSED */
1677: static int
1678: mdoc_dq_pre(MDOC_ARGS)
1679: {
1680:
1681: if (MDOC_BODY != n->type)
1682: return(1);
1683: print_text(h, "\\(lq");
1684: h->flags |= HTML_NOSPACE;
1685: return(1);
1686: }
1687:
1688:
1689: /* ARGSUSED */
1690: static void
1691: mdoc_dq_post(MDOC_ARGS)
1692: {
1693:
1694: if (MDOC_BODY != n->type)
1695: return;
1696: h->flags |= HTML_NOSPACE;
1697: print_text(h, "\\(rq");
1698: }
1699:
1700:
1701: /* ARGSUSED */
1702: static int
1703: mdoc_pq_pre(MDOC_ARGS)
1704: {
1705:
1706: if (MDOC_BODY != n->type)
1707: return(1);
1708: print_text(h, "\\&(");
1709: h->flags |= HTML_NOSPACE;
1710: return(1);
1711: }
1712:
1713:
1714: /* ARGSUSED */
1715: static void
1716: mdoc_pq_post(MDOC_ARGS)
1717: {
1718:
1719: if (MDOC_BODY != n->type)
1720: return;
1721: print_text(h, ")");
1722: }
1723:
1724:
1725: /* ARGSUSED */
1726: static int
1727: mdoc_sq_pre(MDOC_ARGS)
1728: {
1729:
1730: if (MDOC_BODY != n->type)
1731: return(1);
1732: print_text(h, "\\(oq");
1733: h->flags |= HTML_NOSPACE;
1734: return(1);
1735: }
1736:
1737:
1738: /* ARGSUSED */
1739: static void
1740: mdoc_sq_post(MDOC_ARGS)
1741: {
1742:
1743: if (MDOC_BODY != n->type)
1744: return;
1745: h->flags |= HTML_NOSPACE;
1746: print_text(h, "\\(aq");
1747: }
1748:
1749:
1750: /* ARGSUSED */
1751: static int
1752: mdoc_em_pre(MDOC_ARGS)
1753: {
1754: struct htmlpair tag;
1755:
1756: tag.key = ATTR_CLASS;
1757: tag.val = "emph";
1758:
1759: print_otag(h, TAG_SPAN, 1, &tag);
1760: return(1);
1761: }
1762:
1763:
1764: /* ARGSUSED */
1765: static int
1766: mdoc_d1_pre(MDOC_ARGS)
1767: {
1.35 kristaps 1768: struct htmlpair tag[2];
1.34 kristaps 1769:
1770: if (MDOC_BLOCK != n->type)
1771: return(1);
1772:
1.35 kristaps 1773: buffmt("margin-left: %dem;", INDENT);
1.34 kristaps 1774:
1.35 kristaps 1775: tag[0].key = ATTR_CLASS;
1776: tag[0].val = "lit-block";
1777: tag[1].key = ATTR_STYLE;
1778: tag[1].val = buf;
1.34 kristaps 1779:
1.35 kristaps 1780: print_otag(h, TAG_DIV, 2, tag);
1.34 kristaps 1781: return(1);
1782: }
1783:
1784:
1785: /* ARGSUSED */
1786: static int
1787: mdoc_sx_pre(MDOC_ARGS)
1788: {
1.41 kristaps 1789: struct htmlpair tag[2];
1790: const struct mdoc_node *nn;
1791:
1792: bufcat("#");
1793: for (nn = n->child; nn; nn = nn->next) {
1794: bufcat(nn->string);
1795: if (nn->next)
1796: bufcat(" ");
1797: }
1.34 kristaps 1798:
1.35 kristaps 1799: tag[0].key = ATTR_HREF;
1.41 kristaps 1800: tag[0].val = buf;
1.35 kristaps 1801: tag[1].key = ATTR_CLASS;
1802: tag[1].val = "link-sec";
1.34 kristaps 1803:
1.35 kristaps 1804: print_otag(h, TAG_A, 2, tag);
1.34 kristaps 1805: return(1);
1806: }
1.37 kristaps 1807:
1808:
1809: /* ARGSUSED */
1810: static int
1811: mdoc_aq_pre(MDOC_ARGS)
1812: {
1813:
1814: if (MDOC_BODY != n->type)
1815: return(1);
1816: print_text(h, "\\(la");
1817: h->flags |= HTML_NOSPACE;
1818: return(1);
1819: }
1820:
1821:
1822: /* ARGSUSED */
1823: static void
1824: mdoc_aq_post(MDOC_ARGS)
1825: {
1826:
1827: if (MDOC_BODY != n->type)
1828: return;
1829: h->flags |= HTML_NOSPACE;
1830: print_text(h, "\\(ra");
1831: }
1832:
1.39 kristaps 1833:
1834: /* ARGSUSED */
1835: static int
1836: mdoc_bd_pre(MDOC_ARGS)
1837: {
1838: struct htmlpair tag[2];
1839: int t, c, o, i;
1840: const struct mdoc_node *bl;
1841:
1842: /* FIXME: fmt_vspace() shit. */
1843:
1844: if (MDOC_BLOCK == n->type)
1845: bl = n;
1846: else if (MDOC_HEAD == n->type)
1847: return(0);
1848: else
1849: bl = n->parent;
1850:
1851: t = o = c = 0;
1852:
1853: for (i = 0; i < (int)bl->args->argc; i++)
1854: switch (bl->args->argv[i].arg) {
1855: case (MDOC_Offset):
1856: assert(bl->args->argv[i].sz);
1.43 kristaps 1857: o = a2offs (bl->args->argv[i].value[0]);
1.39 kristaps 1858: break;
1859: case (MDOC_Compact):
1860: c = 1;
1861: break;
1862: case (MDOC_Ragged):
1863: /* FALLTHROUGH */
1864: case (MDOC_Filled):
1865: /* FALLTHROUGH */
1866: case (MDOC_Unfilled):
1867: /* FALLTHROUGH */
1868: case (MDOC_Literal):
1869: t = bl->args->argv[i].arg;
1870: break;
1871: }
1872:
1873: if (MDOC_BLOCK == n->type) {
1874: if (o)
1875: buffmt("margin-left: %dem;", o);
1876: bufcat("margin-top: 1em;");
1877: tag[0].key = ATTR_STYLE;
1878: tag[0].val = buf;
1879: print_otag(h, TAG_DIV, 1, tag);
1880: return(1);
1881: }
1882:
1883: switch (t) {
1884: case (MDOC_Unfilled):
1885: case (MDOC_Literal):
1886: break;
1887: default:
1888: return(1);
1889: }
1890:
1891: bufcat("white-space: pre;");
1892: tag[0].key = ATTR_STYLE;
1893: tag[0].val = buf;
1894: tag[1].key = ATTR_CLASS;
1895: tag[1].val = "lit-block";
1896:
1897: print_otag(h, TAG_DIV, 2, tag);
1898:
1899: for (n = n->child; n; n = n->next) {
1900: h->flags |= HTML_NOSPACE;
1901: print_mdoc_node(m, n, h);
1902: if (n->next)
1903: print_text(h, "\n");
1904: }
1905:
1906: return(0);
1907: }
1908:
1909:
1910: /* ARGSUSED */
1911: static int
1912: mdoc_pa_pre(MDOC_ARGS)
1913: {
1914: struct htmlpair tag;
1915:
1916: tag.key = ATTR_CLASS;
1917: tag.val = "file";
1918:
1919: print_otag(h, TAG_SPAN, 1, &tag);
1920: return(1);
1921: }
1922:
1923:
1924: /* ARGSUSED */
1925: static int
1926: mdoc_qq_pre(MDOC_ARGS)
1927: {
1928:
1929: if (MDOC_BODY != n->type)
1930: return(1);
1931: print_text(h, "\\*q");
1932: h->flags |= HTML_NOSPACE;
1933: return(1);
1934: }
1935:
1936:
1937: /* ARGSUSED */
1938: static void
1939: mdoc_qq_post(MDOC_ARGS)
1940: {
1941:
1942: if (MDOC_BODY != n->type)
1943: return;
1944: h->flags |= HTML_NOSPACE;
1945: print_text(h, "\\*q");
1946: }
1.41 kristaps 1947:
1948:
1949: /* ARGSUSED */
1950: static int
1951: mdoc_ad_pre(MDOC_ARGS)
1952: {
1953: struct htmlpair tag;
1954:
1955: tag.key = ATTR_CLASS;
1956: tag.val = "addr";
1957: print_otag(h, TAG_SPAN, 1, &tag);
1958: return(1);
1959: }
1960:
1961:
1962: /* ARGSUSED */
1963: static int
1964: mdoc_an_pre(MDOC_ARGS)
1965: {
1966: struct htmlpair tag;
1967:
1968: tag.key = ATTR_CLASS;
1969: tag.val = "author";
1970: print_otag(h, TAG_SPAN, 1, &tag);
1971: return(1);
1972: }
1973:
1974:
1975: /* ARGSUSED */
1976: static int
1977: mdoc_cd_pre(MDOC_ARGS)
1978: {
1979: struct htmlpair tag;
1980:
1981: tag.key = ATTR_CLASS;
1982: tag.val = "config";
1983: print_otag(h, TAG_SPAN, 1, &tag);
1984: return(1);
1985: }
1986:
1987:
1988: /* ARGSUSED */
1989: static int
1990: mdoc_dv_pre(MDOC_ARGS)
1991: {
1992: struct htmlpair tag;
1993:
1994: tag.key = ATTR_CLASS;
1995: tag.val = "define";
1996: print_otag(h, TAG_SPAN, 1, &tag);
1997: return(1);
1998: }
1999:
2000:
2001: /* ARGSUSED */
2002: static int
2003: mdoc_ev_pre(MDOC_ARGS)
2004: {
2005: struct htmlpair tag;
2006:
2007: tag.key = ATTR_CLASS;
2008: tag.val = "env";
2009: print_otag(h, TAG_SPAN, 1, &tag);
2010: return(1);
2011: }
2012:
2013:
2014: /* ARGSUSED */
2015: static int
2016: mdoc_er_pre(MDOC_ARGS)
2017: {
2018: struct htmlpair tag;
2019:
2020: tag.key = ATTR_CLASS;
2021: tag.val = "errno";
2022: print_otag(h, TAG_SPAN, 1, &tag);
2023: return(1);
2024: }
2025:
2026:
2027: /* ARGSUSED */
2028: static int
2029: mdoc_fa_pre(MDOC_ARGS)
2030: {
2031: const struct mdoc_node *nn;
2032: struct htmlpair tag;
2033: struct tag *t;
2034:
2035: tag.key = ATTR_CLASS;
2036: tag.val = "farg";
2037:
2038: if (n->parent->tok != MDOC_Fo) {
2039: print_otag(h, TAG_SPAN, 1, &tag);
2040: return(1);
2041: }
2042:
2043: for (nn = n->child; nn; nn = nn->next) {
2044: t = print_otag(h, TAG_SPAN, 1, &tag);
2045: print_text(h, nn->string);
2046: print_tagq(h, t);
2047: if (nn->next)
2048: print_text(h, ",");
2049: }
2050:
2051: if (n->child && n->next && n->next->tok == MDOC_Fa)
2052: print_text(h, ",");
2053:
2054: return(0);
2055: }
2056:
2057:
2058: /* ARGSUSED */
2059: static int
2060: mdoc_fd_pre(MDOC_ARGS)
2061: {
2062: struct htmlpair tag;
2063:
2064: if (SEC_SYNOPSIS == n->sec) {
2065: if (n->next && MDOC_Fd != n->next->tok) {
2066: tag.key = ATTR_STYLE;
2067: tag.val = "margin-bottom: 1em;";
2068: print_otag(h, TAG_DIV, 1, &tag);
2069: } else
2070: print_otag(h, TAG_DIV, 0, NULL);
2071: }
2072:
2073: tag.key = ATTR_CLASS;
2074: tag.val = "macro";
2075: print_otag(h, TAG_SPAN, 1, &tag);
2076: return(1);
2077: }
2078:
2079:
2080: /* ARGSUSED */
2081: static int
2082: mdoc_vt_pre(MDOC_ARGS)
2083: {
2084: struct htmlpair tag;
2085:
2086: if (SEC_SYNOPSIS == n->sec) {
2087: if (n->next && MDOC_Vt != n->next->tok) {
2088: tag.key = ATTR_STYLE;
2089: tag.val = "margin-bottom: 1em;";
2090: print_otag(h, TAG_DIV, 1, &tag);
2091: } else
2092: print_otag(h, TAG_DIV, 0, NULL);
2093: }
2094:
2095: tag.key = ATTR_CLASS;
2096: tag.val = "type";
2097: print_otag(h, TAG_SPAN, 1, &tag);
2098: return(1);
2099: }
2100:
2101: /* ARGSUSED */
2102: static int
2103: mdoc_ft_pre(MDOC_ARGS)
2104: {
2105: struct htmlpair tag;
2106:
2107: if (SEC_SYNOPSIS == n->sec) {
2108: if (n->prev && MDOC_Fo == n->prev->tok) {
2109: tag.key = ATTR_STYLE;
2110: tag.val = "magin-bottom: 1em;";
2111: print_otag(h, TAG_DIV, 1, &tag);
2112: } else
2113: print_otag(h, TAG_DIV, 0, NULL);
2114: }
2115:
2116: tag.key = ATTR_CLASS;
2117: tag.val = "type";
2118: print_otag(h, TAG_SPAN, 1, &tag);
2119: return(1);
2120: }
2121:
2122:
2123: /* ARGSUSED */
2124: static int
2125: mdoc_fn_pre(MDOC_ARGS)
2126: {
2127: struct tag *t;
2128: struct htmlpair tag;
2129: const struct mdoc_node *nn;
2130:
2131: if (SEC_SYNOPSIS == n->sec) {
2132: if (n->next) {
2133: tag.key = ATTR_STYLE;
2134: tag.val = "margin-bottom: 1em";
2135: print_otag(h, TAG_DIV, 1, &tag);
2136: } else
2137: print_otag(h, TAG_DIV, 0, NULL);
2138: }
2139:
2140: tag.key = ATTR_CLASS;
2141: tag.val = "type";
2142:
2143: t = print_otag(h, TAG_SPAN, 1, &tag);
2144: print_text(h, n->child->string);
2145: print_tagq(h, t);
2146:
2147: h->flags |= HTML_NOSPACE;
2148: print_text(h, "(");
2149:
2150: for (nn = n->child->next; nn; nn = nn->next) {
2151: tag.key = ATTR_CLASS;
2152: tag.val = "farg";
2153: t = print_otag(h, TAG_SPAN, 1, &tag);
2154: print_text(h, nn->string);
2155: print_tagq(h, t);
2156: if (nn->next)
2157: print_text(h, ",");
2158: }
2159:
2160: print_text(h, ")");
2161:
2162: if (SEC_SYNOPSIS == n->sec)
2163: print_text(h, ";");
2164:
2165: return(0);
2166: }
CVSweb