+#include <unistd.h>
+
+#include "mandoc.h"
+#include "out.h"
+#include "chars.h"
+#include "html.h"
+#include "main.h"
+
+struct htmldata {
+ const char *name;
+ int flags;
+#define HTML_CLRLINE (1 << 0)
+#define HTML_NOSTACK (1 << 1)
+#define HTML_AUTOCLOSE (1 << 2) /* Tag has auto-closure. */
+};
+
+static const struct htmldata htmltags[TAG_MAX] = {
+ {"html", HTML_CLRLINE}, /* TAG_HTML */
+ {"head", HTML_CLRLINE}, /* TAG_HEAD */
+ {"body", HTML_CLRLINE}, /* TAG_BODY */
+ {"meta", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_META */
+ {"title", HTML_CLRLINE}, /* TAG_TITLE */
+ {"div", HTML_CLRLINE}, /* TAG_DIV */
+ {"h1", 0}, /* TAG_H1 */
+ {"h2", 0}, /* TAG_H2 */
+ {"span", 0}, /* TAG_SPAN */
+ {"link", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_LINK */
+ {"br", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_BR */
+ {"a", 0}, /* TAG_A */
+ {"table", HTML_CLRLINE}, /* TAG_TABLE */
+ {"col", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_COL */
+ {"tr", HTML_CLRLINE}, /* TAG_TR */
+ {"td", HTML_CLRLINE}, /* TAG_TD */
+ {"li", HTML_CLRLINE}, /* TAG_LI */
+ {"ul", HTML_CLRLINE}, /* TAG_UL */
+ {"ol", HTML_CLRLINE}, /* TAG_OL */
+};
+
+static const char *const htmlfonts[HTMLFONT_MAX] = {
+ "roman",
+ "bold",
+ "italic"
+};
+
+static const char *const htmlattrs[ATTR_MAX] = {
+ "http-equiv",
+ "content",
+ "name",
+ "rel",
+ "href",
+ "type",
+ "media",
+ "class",
+ "style",
+ "width",
+ "valign",
+ "target",
+ "id",
+ "summary",
+};
+
+static void print_spec(struct html *, const char *, size_t);
+static void print_res(struct html *, const char *, size_t);
+static void print_ctag(struct html *, enum htmltag);
+static void print_doctype(struct html *);
+static void print_xmltype(struct html *);
+static int print_encode(struct html *, const char *, int);
+static void print_metaf(struct html *, enum roffdeco);
+static void print_attr(struct html *,
+ const char *, const char *);
+static void *ml_alloc(char *, enum htmltype);
+
+
+static void *
+ml_alloc(char *outopts, enum htmltype type)
+{
+ struct html *h;
+ const char *toks[4];
+ char *v;
+
+ toks[0] = "style";
+ toks[1] = "man";
+ toks[2] = "includes";
+ toks[3] = NULL;
+
+ h = calloc(1, sizeof(struct html));
+ if (NULL == h) {
+ perror(NULL);
+ exit(EXIT_FAILURE);
+ }
+
+ h->type = type;
+ h->tags.head = NULL;
+ h->ords.head = NULL;
+ h->symtab = chars_init(CHARS_HTML);
+
+ while (outopts && *outopts)
+ switch (getsubopt(&outopts, UNCONST(toks), &v)) {
+ case (0):
+ h->style = v;
+ break;
+ case (1):
+ h->base_man = v;
+ break;
+ case (2):
+ h->base_includes = v;
+ break;
+ default:
+ break;
+ }
+
+ return(h);
+}
+
+void *
+html_alloc(char *outopts)
+{