=================================================================== RCS file: /cvs/mandoc/html.c,v retrieving revision 1.54 retrieving revision 1.63 diff -u -p -r1.54 -r1.63 --- mandoc/html.c 2009/10/03 15:26:26 1.54 +++ mandoc/html.c 2009/10/13 10:21:24 1.63 @@ -1,4 +1,4 @@ -/* $Id: html.c,v 1.54 2009/10/03 15:26:26 kristaps Exp $ */ +/* $Id: html.c,v 1.63 2009/10/13 10:21:24 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -20,18 +20,23 @@ #include #include #include +#include +#include #include #include #include +#include "out.h" #include "chars.h" #include "html.h" +#define UNCONST(a) ((void *)(uintptr_t)(const void *)(a)) + #define DOCTYPE "-//W3C//DTD HTML 4.01//EN" #define DTD "http://www.w3.org/TR/html4/strict.dtd" struct htmldata { - char *name; + const char *name; int flags; #define HTML_CLRLINE (1 << 0) #define HTML_NOSTACK (1 << 1) @@ -74,6 +79,7 @@ static const char *const htmlattrs[ATTR_MAX] = { "width", "valign", "target", + "id", }; #ifdef __linux__ @@ -84,7 +90,8 @@ void * html_alloc(char *outopts) { struct html *h; - char *toks[4], *v; + const char *toks[4]; + char *v; toks[0] = "style"; toks[1] = "man"; @@ -103,7 +110,7 @@ html_alloc(char *outopts) } while (outopts && *outopts) - switch (getsubopt(&outopts, toks, &v)) { + switch (getsubopt(&outopts, UNCONST(toks), &v)) { case (0): h->style = v; break; @@ -142,8 +149,6 @@ html_free(void *p) free(tag); } - if (h->buf) - free(h->buf); if (h->symtab) chars_free(h->symtab); @@ -486,4 +491,161 @@ print_stagq(struct html *h, const struct tag *suntil) SLIST_REMOVE_HEAD(&h->tags, entry); free(tag); } +} + + +void +bufinit(struct html *h) +{ + + h->buf[0] = '\0'; + h->buflen = 0; +} + + +void +bufcat_style(struct html *h, const char *key, const char *val) +{ + + bufcat(h, key); + bufncat(h, ":", 1); + bufcat(h, val); + bufncat(h, ";", 1); +} + + +void +bufcat(struct html *h, const char *p) +{ + + bufncat(h, p, strlen(p)); +} + + +void +buffmt(struct html *h, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + (void)vsnprintf(h->buf + (int)h->buflen, + BUFSIZ - h->buflen - 1, fmt, ap); + va_end(ap); + h->buflen = strlen(h->buf); +} + + +void +bufncat(struct html *h, const char *p, size_t sz) +{ + + if (h->buflen + sz > BUFSIZ - 1) + sz = BUFSIZ - 1 - h->buflen; + + (void)strncat(h->buf, p, sz); + h->buflen += sz; +} + + +void +buffmt_includes(struct html *h, const char *name) +{ + const char *p, *pp; + + pp = h->base_includes; + + while (NULL != (p = strchr(pp, '%'))) { + bufncat(h, pp, (size_t)(p - pp)); + switch (*(p + 1)) { + case('I'): + bufcat(h, name); + break; + default: + bufncat(h, p, 2); + break; + } + pp = p + 2; + } + if (pp) + bufcat(h, pp); +} + + +void +buffmt_man(struct html *h, + const char *name, const char *sec) +{ + const char *p, *pp; + + pp = h->base_man; + + /* LINTED */ + while (NULL != (p = strchr(pp, '%'))) { + bufncat(h, pp, (size_t)(p - pp)); + switch (*(p + 1)) { + case('S'): + bufcat(h, sec ? sec : "1"); + break; + case('N'): + buffmt(h, name); + break; + default: + bufncat(h, p, 2); + break; + } + pp = p + 2; + } + if (pp) + bufcat(h, pp); +} + + +void +bufcat_su(struct html *h, const char *p, const struct roffsu *su) +{ + double v; + const char *u; + + v = su->scale; + + switch (su->unit) { + case (SCALE_CM): + u = "cm"; + break; + case (SCALE_IN): + u = "in"; + break; + case (SCALE_PC): + u = "pc"; + break; + case (SCALE_PT): + u = "pt"; + break; + case (SCALE_EM): + u = "em"; + break; + case (SCALE_MM): + if (0 == (v /= 100)) + v = 1; + u = "em"; + break; + case (SCALE_EN): + u = "ex"; + break; + case (SCALE_BU): + u = "ex"; + break; + case (SCALE_VS): + u = "em"; + break; + default: + u = "ex"; + break; + } + + if (su->pt) + buffmt(h, "%s: %f%s;", p, v, u); + else + /* LINTED */ + buffmt(h, "%s: %d%s;", p, (int)v, u); }