summaryrefslogtreecommitdiffstats
path: root/html.c
diff options
context:
space:
mode:
authorKristaps Dzonsons <kristaps@bsd.lv>2009-09-16 09:41:24 +0000
committerKristaps Dzonsons <kristaps@bsd.lv>2009-09-16 09:41:24 +0000
commit464bf99c7bec33718cdc95c963d3e5d3a28b3124 (patch)
treeef4611149e16f2ceec906cc4980285365d2d48bc /html.c
parentea228aff6a872a947bb23cd1b1405ab1d72c37e6 (diff)
downloadmandoc-464bf99c7bec33718cdc95c963d3e5d3a28b3124.tar.gz
Made tree/term/out() functions return void.
Put err() functions back into front-ends (no use making it needlessly complex).
Diffstat (limited to 'html.c')
-rw-r--r--html.c638
1 files changed, 638 insertions, 0 deletions
diff --git a/html.c b/html.c
new file mode 100644
index 00000000..a9c03184
--- /dev/null
+++ b/html.c
@@ -0,0 +1,638 @@
+/* $Id$ */
+/*
+ * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+#include <assert.h>
+#include <err.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "mdoc.h"
+#include "man.h"
+
+#define DOCTYPE "-//W3C//DTD HTML 4.01//EN"
+#define DTD "http://www.w3.org/TR/html4/strict.dtd"
+
+enum htmltag {
+ TAG_HTML,
+ TAG_HEAD,
+ TAG_BODY,
+ TAG_META,
+ TAG_TITLE,
+ TAG_DIV,
+ TAG_H1,
+ TAG_H2,
+ TAG_P,
+ TAG_SPAN,
+ TAG_LINK,
+ TAG_MAX
+};
+
+enum htmlattr {
+ ATTR_HTTPEQUIV,
+ ATTR_CONTENT,
+ ATTR_NAME,
+ ATTR_REL,
+ ATTR_HREF,
+ ATTR_TYPE,
+ ATTR_MEDIA,
+ ATTR_CLASS,
+ ATTR_MAX
+};
+
+struct htmldata {
+ char *name;
+ int flags;
+#define HTML_BLOCK (1 << 0)
+};
+
+static const struct htmldata htmltags[TAG_MAX] = {
+ {"html", HTML_BLOCK}, /* TAG_HTML */
+ {"head", HTML_BLOCK}, /* TAG_HEAD */
+ {"body", HTML_BLOCK}, /* TAG_BODY */
+ {"meta", HTML_BLOCK}, /* TAG_META */
+ {"title", HTML_BLOCK}, /* TAG_TITLE */
+ {"div", HTML_BLOCK}, /* TAG_DIV */
+ {"h1", 0}, /* TAG_H1 */
+ {"h2", 0}, /* TAG_H2 */
+ {"p", HTML_BLOCK}, /* TAG_P */
+ {"span", 0}, /* TAG_SPAN */
+ {"link", HTML_BLOCK}, /* TAG_LINK */
+};
+
+static const char *const htmlattrs[ATTR_MAX] = {
+ "http-equiv",
+ "content",
+ "name",
+ "rel",
+ "href",
+ "type",
+ "media",
+ "class"
+};
+
+struct htmlpair {
+ enum htmlattr key;
+ char *val;
+};
+
+struct html {
+ int flags;
+#define HTML_NOSPACE (1 << 0)
+};
+
+#define MDOC_ARGS const struct mdoc_meta *m, \
+ const struct mdoc_node *n, \
+ struct html *h
+#define MAN_ARGS const struct man_meta *m, \
+ const struct man_node *n, \
+ struct html *h
+struct htmlmdoc {
+ int (*pre)(MDOC_ARGS);
+ void (*post)(MDOC_ARGS);
+};
+
+static void print_gen_doctype(struct html *);
+static void print_gen_head(struct html *);
+static void print_mdoc(MDOC_ARGS);
+static void print_mdoc_head(MDOC_ARGS);
+static void print_mdoc_node(MDOC_ARGS);
+static void print_man(MAN_ARGS);
+static void print_man_head(MAN_ARGS);
+static void print_man_body(MAN_ARGS);
+static void print_otag(struct html *, enum htmltag,
+ int, const struct htmlpair *);
+static void print_ctag(struct html *, enum htmltag);
+static void print_encode(const char *);
+static void print_text(struct html *, const char *);
+static int mdoc_root_pre(MDOC_ARGS);
+static void mdoc_root_post(MDOC_ARGS);
+
+static int mdoc_nd_pre(MDOC_ARGS);
+static int mdoc_nm_pre(MDOC_ARGS);
+static void mdoc_nm_post(MDOC_ARGS);
+static int mdoc_pp_pre(MDOC_ARGS);
+static int mdoc_sh_pre(MDOC_ARGS);
+static void mdoc_sh_post(MDOC_ARGS);
+static int mdoc_ss_pre(MDOC_ARGS);
+static void mdoc_ss_post(MDOC_ARGS);
+
+static const struct htmlmdoc mdocs[MDOC_MAX] = {
+ {NULL, NULL}, /* Ap */
+ {NULL, NULL}, /* Dd */
+ {NULL, NULL}, /* Dt */
+ {NULL, NULL}, /* Os */
+ {mdoc_sh_pre, mdoc_sh_post }, /* Sh */
+ {mdoc_ss_pre, mdoc_ss_post }, /* Ss */
+ {mdoc_pp_pre, NULL}, /* Pp */
+ {NULL, NULL}, /* D1 */
+ {NULL, NULL}, /* Dl */
+ {NULL, NULL}, /* Bd */
+ {NULL, NULL}, /* Ed */
+ {NULL, NULL}, /* Bl */
+ {NULL, NULL}, /* El */
+ {NULL, NULL}, /* It */
+ {NULL, NULL}, /* Ad */
+ {NULL, NULL}, /* An */
+ {NULL, NULL}, /* Ar */
+ {NULL, NULL}, /* Cd */
+ {NULL, NULL}, /* Cm */
+ {NULL, NULL}, /* Dv */
+ {NULL, NULL}, /* Er */
+ {NULL, NULL}, /* Ev */
+ {NULL, NULL}, /* Ex */
+ {NULL, NULL}, /* Fa */
+ {NULL, NULL}, /* Fd */
+ {NULL, NULL}, /* Fl */
+ {NULL, NULL}, /* Fn */
+ {NULL, NULL}, /* Ft */
+ {NULL, NULL}, /* Ic */
+ {NULL, NULL}, /* In */
+ {NULL, NULL}, /* Li */
+ {mdoc_nd_pre, NULL}, /* Nd */
+ {mdoc_nm_pre, mdoc_nm_post}, /* Nm */
+ {NULL, NULL}, /* Op */
+ {NULL, NULL}, /* Ot */
+ {NULL, NULL}, /* Pa */
+ {NULL, NULL}, /* Rv */
+ {NULL, NULL}, /* St */
+ {NULL, NULL}, /* Va */
+ {NULL, NULL}, /* Vt */
+ {NULL, NULL}, /* Xr */
+ {NULL, NULL}, /* %A */
+ {NULL, NULL}, /* %B */
+ {NULL, NULL}, /* %D */
+ {NULL, NULL}, /* %I */
+ {NULL, NULL}, /* %J */
+ {NULL, NULL}, /* %N */
+ {NULL, NULL}, /* %O */
+ {NULL, NULL}, /* %P */
+ {NULL, NULL}, /* %R */
+ {NULL, NULL}, /* %T */
+ {NULL, NULL}, /* %V */
+ {NULL, NULL}, /* Ac */
+ {NULL, NULL}, /* Ao */
+ {NULL, NULL}, /* Aq */
+ {NULL, NULL}, /* At */
+ {NULL, NULL}, /* Bc */
+ {NULL, NULL}, /* Bf */
+ {NULL, NULL}, /* Bo */
+ {NULL, NULL}, /* Bq */
+ {NULL, NULL}, /* Bsx */
+ {NULL, NULL}, /* Bx */
+ {NULL, NULL}, /* Db */
+ {NULL, NULL}, /* Dc */
+ {NULL, NULL}, /* Do */
+ {NULL, NULL}, /* Dq */
+ {NULL, NULL}, /* Ec */
+ {NULL, NULL}, /* Ef */
+ {NULL, NULL}, /* Em */
+ {NULL, NULL}, /* Eo */
+ {NULL, NULL}, /* Fx */
+ {NULL, NULL}, /* Ms */
+ {NULL, NULL}, /* No */
+ {NULL, NULL}, /* Ns */
+ {NULL, NULL}, /* Nx */
+ {NULL, NULL}, /* Ox */
+ {NULL, NULL}, /* Pc */
+ {NULL, NULL}, /* Pf */
+ {NULL, NULL}, /* Po */
+ {NULL, NULL}, /* Pq */
+ {NULL, NULL}, /* Qc */
+ {NULL, NULL}, /* Ql */
+ {NULL, NULL}, /* Qo */
+ {NULL, NULL}, /* Qq */
+ {NULL, NULL}, /* Re */
+ {NULL, NULL}, /* Rs */
+ {NULL, NULL}, /* Sc */
+ {NULL, NULL}, /* So */
+ {NULL, NULL}, /* Sq */
+ {NULL, NULL}, /* Sm */
+ {NULL, NULL}, /* Sx */
+ {NULL, NULL}, /* Sy */
+ {NULL, NULL}, /* Tn */
+ {NULL, NULL}, /* Ux */
+ {NULL, NULL}, /* Xc */
+ {NULL, NULL}, /* Xo */
+ {NULL, NULL}, /* Fo */
+ {NULL, NULL}, /* Fc */
+ {NULL, NULL}, /* Oo */
+ {NULL, NULL}, /* Oc */
+ {NULL, NULL}, /* Bk */
+ {NULL, NULL}, /* Ek */
+ {NULL, NULL}, /* Bt */
+ {NULL, NULL}, /* Hf */
+ {NULL, NULL}, /* Fr */
+ {NULL, NULL}, /* Ud */
+ {NULL, NULL}, /* Lb */
+ {NULL, NULL}, /* Lp */
+ {NULL, NULL}, /* Lk */
+ {NULL, NULL}, /* Mt */
+ {NULL, NULL}, /* Brq */
+ {NULL, NULL}, /* Bro */
+ {NULL, NULL}, /* Brc */
+ {NULL, NULL}, /* %C */
+ {NULL, NULL}, /* Es */
+ {NULL, NULL}, /* En */
+ {NULL, NULL}, /* Dx */
+ {NULL, NULL}, /* %Q */
+ {NULL, NULL}, /* br */
+ {NULL, NULL}, /* sp */
+};
+
+
+int
+html_mdoc(void *arg, const struct mdoc *m)
+{
+ struct html *h;
+
+ h = (struct html *)arg;
+
+ print_gen_doctype(h);
+ print_otag(h, TAG_HTML, 0, NULL);
+ print_mdoc(mdoc_meta(m), mdoc_node(m), h);
+ print_ctag(h, TAG_HTML);
+ printf("\n");
+ return(1);
+}
+
+
+int
+html_man(void *arg, const struct man *m)
+{
+ struct html *h;
+
+ h = (struct html *)arg;
+
+ print_gen_doctype(h);
+ print_otag(h, TAG_HTML, 0, NULL);
+ print_man(man_meta(m), man_node(m), h);
+ print_ctag(h, TAG_HTML);
+ printf("\n");
+ return(1);
+}
+
+
+void *
+html_alloc(void)
+{
+
+ return(calloc(1, sizeof(struct html)));
+}
+
+
+void
+html_free(void *p)
+{
+
+ free(p);
+}
+
+
+static void
+print_mdoc(MDOC_ARGS)
+{
+
+ print_otag(h, TAG_HEAD, 0, NULL);
+ print_mdoc_head(m, n, h);
+ print_ctag(h, TAG_HEAD);
+ print_otag(h, TAG_BODY, 0, NULL);
+ print_mdoc_node(m, n, h);
+ print_ctag(h, TAG_BODY);
+}
+
+
+static void
+print_gen_head(struct html *h)
+{
+ struct htmlpair meta0[2];
+ struct htmlpair meta1[2];
+ struct htmlpair link[4];
+
+ meta0[0].key = ATTR_HTTPEQUIV;
+ meta0[0].val = "Content-Type";
+ meta0[1].key = ATTR_CONTENT;
+ meta0[1].val = "text/html; charest-utf-8";
+
+ meta1[0].key = ATTR_NAME;
+ meta1[0].val = "resource-type";
+ meta1[1].key = ATTR_CONTENT;
+ meta1[1].val = "document";
+
+ link[0].key = ATTR_REL;
+ link[0].val = "stylesheet";
+ link[1].key = ATTR_HREF;
+ link[1].val = "style.css";
+ link[2].key = ATTR_TYPE;
+ link[2].val = "text/css";
+ link[3].key = ATTR_MEDIA;
+ link[3].val = "all";
+
+ print_otag(h, TAG_META, 2, meta0);
+ print_otag(h, TAG_META, 2, meta1);
+ print_otag(h, TAG_LINK, 4, link);
+}
+
+
+static void
+print_mdoc_head(MDOC_ARGS)
+{
+
+ print_gen_head(h);
+ print_otag(h, TAG_TITLE, 0, NULL);
+ print_encode(m->title);
+ print_ctag(h, TAG_TITLE);
+}
+
+
+static int
+mdoc_root_pre(MDOC_ARGS)
+{
+ struct htmlpair div;
+
+ div.key = ATTR_CLASS;
+ div.val = "body";
+
+ print_otag(h, TAG_DIV, 1, &div);
+ return(1);
+}
+
+
+static void
+mdoc_root_post(MDOC_ARGS)
+{
+
+ print_ctag(h, TAG_DIV);
+}
+
+
+static int
+mdoc_ss_pre(MDOC_ARGS)
+{
+
+ if (MDOC_BODY == n->type)
+ print_otag(h, TAG_P, 0, NULL);
+ if (MDOC_HEAD == n->type)
+ print_otag(h, TAG_H2, 0, NULL);
+ return(1);
+}
+
+
+static void
+mdoc_ss_post(MDOC_ARGS)
+{
+
+ if (MDOC_BODY == n->type)
+ print_ctag(h, TAG_P);
+ if (MDOC_HEAD == n->type)
+ print_ctag(h, TAG_H2);
+}
+
+
+static int
+mdoc_pp_pre(MDOC_ARGS)
+{
+
+ print_otag(h, TAG_P, 0, NULL);
+ return(0);
+}
+
+
+static int
+mdoc_nd_pre(MDOC_ARGS)
+{
+
+ if (MDOC_BODY == n->type)
+ print_text(h, "--");
+ return(1);
+}
+
+
+static int
+mdoc_nm_pre(MDOC_ARGS)
+{
+ struct htmlpair class;
+
+ class.key = ATTR_CLASS;
+ class.val = "name";
+
+ print_otag(h, TAG_SPAN, 1, &class);
+ if (NULL == n->child)
+ print_text(h, m->name);
+
+ return(1);
+}
+
+
+static void
+mdoc_nm_post(MDOC_ARGS)
+{
+
+ print_ctag(h, TAG_SPAN);
+}
+
+
+static int
+mdoc_sh_pre(MDOC_ARGS)
+{
+
+ if (MDOC_BODY == n->type)
+ print_otag(h, TAG_P, 0, NULL);
+ if (MDOC_HEAD == n->type)
+ print_otag(h, TAG_H1, 0, NULL);
+ return(1);
+}
+
+
+static void
+mdoc_sh_post(MDOC_ARGS)
+{
+
+ if (MDOC_BODY == n->type)
+ print_ctag(h, TAG_P);
+ if (MDOC_HEAD == n->type)
+ print_ctag(h, TAG_H1);
+}
+
+
+static void
+print_mdoc_node(MDOC_ARGS)
+{
+ int child;
+
+ child = 1;
+
+ switch (n->type) {
+ case (MDOC_ROOT):
+ child = mdoc_root_pre(m, n, h);
+ break;
+ case (MDOC_TEXT):
+ print_text(h, n->string);
+ break;
+ default:
+ if (mdocs[n->tok].pre)
+ child = (*mdocs[n->tok].pre)(m, n, h);
+ break;
+ }
+
+ if (child && n->child)
+ print_mdoc_node(m, n->child, h);
+
+ switch (n->type) {
+ case (MDOC_ROOT):
+ mdoc_root_post(m, n, h);
+ break;
+ case (MDOC_TEXT):
+ break;
+ default:
+ if (mdocs[n->tok].post)
+ (*mdocs[n->tok].post)(m, n, h);
+ break;
+ }
+
+ if (n->next)
+ print_mdoc_node(m, n->next, h);
+}
+
+
+static void
+print_man(MAN_ARGS)
+{
+
+ print_otag(h, TAG_HEAD, 0, NULL);
+ print_man_head(m, n, h);
+ print_ctag(h, TAG_HEAD);
+ print_otag(h, TAG_BODY, 0, NULL);
+ print_man_body(m, n, h);
+ print_ctag(h, TAG_BODY);
+}
+
+
+static void
+print_man_head(MAN_ARGS)
+{
+
+ print_gen_head(h);
+ print_otag(h, TAG_TITLE, 0, NULL);
+ print_encode(m->title);
+ print_ctag(h, TAG_TITLE);
+}
+
+
+static void
+print_man_body(MAN_ARGS)
+{
+}
+
+
+static void
+print_encode(const char *p)
+{
+
+ printf("%s", p); /* XXX */
+}
+
+
+static void
+print_otag(struct html *h, enum htmltag tag,
+ int sz, const struct htmlpair *p)
+{
+ int i;
+
+ if ( ! (HTML_NOSPACE & h->flags))
+ if ( ! (HTML_BLOCK & htmltags[tag].flags))
+ printf(" ");
+
+ printf("<%s", htmltags[tag].name);
+ for (i = 0; i < sz; i++) {
+ printf(" %s=\"", htmlattrs[p[i].key]);
+ assert(p->val);
+ print_encode(p[i].val);
+ printf("\"");
+ }
+ printf(">");
+
+ h->flags |= HTML_NOSPACE;
+
+}
+
+
+/* ARGSUSED */
+static void
+print_ctag(struct html *h, enum htmltag tag)
+{
+
+ printf("</%s>", htmltags[tag].name);
+ if (HTML_BLOCK & htmltags[tag].flags)
+ h->flags |= HTML_NOSPACE;
+}
+
+
+/* ARGSUSED */
+static void
+print_gen_doctype(struct html *h)
+{
+
+ printf("<!DOCTYPE HTML PUBLIC \"%s\" \"%s\">\n", DOCTYPE, DTD);
+}
+
+
+static void
+print_text(struct html *h, const char *p)
+{
+
+ if (*p && 0 == *(p + 1))
+ switch (*p) {
+ case('.'):
+ /* FALLTHROUGH */
+ case(','):
+ /* FALLTHROUGH */
+ case(';'):
+ /* FALLTHROUGH */
+ case(':'):
+ /* FALLTHROUGH */
+ case('?'):
+ /* FALLTHROUGH */
+ case('!'):
+ /* FALLTHROUGH */
+ case(')'):
+ /* FALLTHROUGH */
+ case(']'):
+ /* FALLTHROUGH */
+ case('}'):
+ h->flags |= HTML_NOSPACE;
+ default:
+ break;
+ }
+
+ if ( ! (h->flags & HTML_NOSPACE))
+ printf(" ");
+ h->flags &= ~HTML_NOSPACE;
+
+ if (p)
+ print_encode(p);
+
+ if (*p && 0 == *(p + 1))
+ switch (*p) {
+ case('('):
+ /* FALLTHROUGH */
+ case('['):
+ /* FALLTHROUGH */
+ case('{'):
+ h->flags |= HTML_NOSPACE;
+ default:
+ break;
+ }
+}