=================================================================== RCS file: /cvs/mandoc/html.c,v retrieving revision 1.55 retrieving revision 1.68 diff -u -p -r1.55 -r1.68 --- mandoc/html.c 2009/10/03 16:36:06 1.55 +++ mandoc/html.c 2009/10/28 05:08:17 1.68 @@ -1,4 +1,4 @@ -/* $Id: html.c,v 1.55 2009/10/03 16:36:06 kristaps Exp $ */ +/* $Id: html.c,v 1.68 2009/10/28 05:08:17 kristaps Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * @@ -15,24 +15,29 @@ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include -#include #include +#include #include #include #include +#include #include #include #include +#include "out.h" #include "chars.h" #include "html.h" +#include "main.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) @@ -75,6 +80,8 @@ static const char *const htmlattrs[ATTR_MAX] = { "width", "valign", "target", + "id", + "summary", }; #ifdef __linux__ @@ -85,7 +92,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"; @@ -95,8 +103,8 @@ html_alloc(char *outopts) if (NULL == (h = calloc(1, sizeof(struct html)))) return(NULL); - SLIST_INIT(&h->tags); - SLIST_INIT(&h->ords); + h->tags.head = NULL; + h->ords.head = NULL; if (NULL == (h->symtab = chars_init(CHARS_HTML))) { free(h); @@ -104,7 +112,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; @@ -131,15 +139,13 @@ html_free(void *p) h = (struct html *)p; - while ( ! SLIST_EMPTY(&h->ords)) { - ord = SLIST_FIRST(&h->ords); - SLIST_REMOVE_HEAD(&h->ords, entry); + while ((ord = h->ords.head) != NULL) { + h->ords.head = ord->next; free(ord); } - while ( ! SLIST_EMPTY(&h->tags)) { - tag = SLIST_FIRST(&h->tags); - SLIST_REMOVE_HEAD(&h->tags, entry); + while ((tag = h->tags.head) != NULL) { + h->tags.head = tag->next; free(tag); } @@ -351,7 +357,8 @@ print_otag(struct html *h, enum htmltag tag, if (NULL == (t = malloc(sizeof(struct tag)))) err(EXIT_FAILURE, "malloc"); t->tag = tag; - SLIST_INSERT_HEAD(&h->tags, t, entry); + t->next = h->tags.head; + h->tags.head = t; } else t = NULL; @@ -461,10 +468,9 @@ print_tagq(struct html *h, const struct tag *until) { struct tag *tag; - while ( ! SLIST_EMPTY(&h->tags)) { - tag = SLIST_FIRST(&h->tags); + while ((tag = h->tags.head) != NULL) { print_ctag(h, tag->tag); - SLIST_REMOVE_HEAD(&h->tags, entry); + h->tags.head = tag->next; free(tag); if (until && tag == until) return; @@ -477,12 +483,11 @@ print_stagq(struct html *h, const struct tag *suntil) { struct tag *tag; - while ( ! SLIST_EMPTY(&h->tags)) { - tag = SLIST_FIRST(&h->tags); + while ((tag = h->tags.head) != NULL) { if (suntil && tag == suntil) return; print_ctag(h, tag->tag); - SLIST_REMOVE_HEAD(&h->tags, entry); + h->tags.head = tag->next; free(tag); } } @@ -498,6 +503,17 @@ bufinit(struct html *h) 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) { @@ -511,11 +527,10 @@ buffmt(struct html *h, const char *fmt, ...) va_list ap; va_start(ap, fmt); - (void)vsnprintf(h->buf + h->buflen, + (void)vsnprintf(h->buf + (int)h->buflen, BUFSIZ - h->buflen - 1, fmt, ap); va_end(ap); h->buflen = strlen(h->buf); - assert('\0' == h->buf[h->buflen]); } @@ -528,7 +543,6 @@ bufncat(struct html *h, const char *p, size_t sz) (void)strncat(h->buf, p, sz); h->buflen += sz; - assert('\0' == h->buf[h->buflen]); } @@ -538,8 +552,9 @@ buffmt_includes(struct html *h, const char *name) const char *p, *pp; pp = h->base_includes; - while ((p = strchr(pp, '%'))) { - bufncat(h, pp, p - pp); + + while (NULL != (p = strchr(pp, '%'))) { + bufncat(h, pp, (size_t)(p - pp)); switch (*(p + 1)) { case('I'): bufcat(h, name); @@ -562,14 +577,16 @@ buffmt_man(struct html *h, const char *p, *pp; pp = h->base_man; - while ((p = strchr(pp, '%'))) { - bufncat(h, pp, p - pp); + + /* LINTED */ + while (NULL != (p = strchr(pp, '%'))) { + bufncat(h, pp, (size_t)(p - pp)); switch (*(p + 1)) { case('S'): - bufcat(h, sec); + bufcat(h, sec ? sec : "1"); break; case('N'): - buffmt(h, name ? name : "1"); + buffmt(h, name); break; default: bufncat(h, p, 2); @@ -579,4 +596,103 @@ buffmt_man(struct html *h, } 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); +} + + +void +html_idcpy(char *dst, const char *src, int sz) +{ + + assert(sz); + dst[0] = '\0'; + html_idcat(dst, src, sz); +} + + +void +html_idcat(char *dst, const char *src, int sz) +{ + int i; + + /* Cf. . */ + + for (i = 0; *dst != '\0' && i < sz - 1; dst++, i++) + /* Jump to end. */ ; + + for ( ; *src != '\0' && i < sz - 1; src++, i++) { + if (isalnum((u_char)*src)) { + *dst++ = *src; + continue; + } + + switch (*src) { + case (';'): + *dst++ = ';'; + break; + case ('-'): + *dst++ = '-'; + break; + case (':'): + *dst++ = ':'; + break; + case ('_'): + /* FALLTHROUGH */ + default: + *dst++ = '_'; + break; + } + } + + *dst = '\0'; }