=================================================================== RCS file: /cvs/mandoc/html.c,v retrieving revision 1.100 retrieving revision 1.117 diff -u -p -r1.100 -r1.117 --- mandoc/html.c 2010/05/25 12:37:20 1.100 +++ mandoc/html.c 2010/12/17 08:17:40 1.117 @@ -1,6 +1,6 @@ -/* $Id: html.c,v 1.100 2010/05/25 12:37:20 kristaps Exp $ */ +/* $Id: html.c,v 1.117 2010/12/17 08:17:40 kristaps Exp $ */ /* - * Copyright (c) 2008, 2009 Kristaps Dzonsons + * Copyright (c) 2008, 2009, 2010 Kristaps Dzonsons * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above @@ -35,8 +35,6 @@ #include "html.h" #include "main.h" -#define UNCONST(a) ((void *)(uintptr_t)(const void *)(a)) - struct htmldata { const char *name; int flags; @@ -59,12 +57,18 @@ static const struct htmldata htmltags[TAG_MAX] = { {"br", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_BR */ {"a", 0}, /* TAG_A */ {"table", HTML_CLRLINE}, /* TAG_TABLE */ + {"tbody", HTML_CLRLINE}, /* TAG_TBODY */ {"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 */ + {"dl", HTML_CLRLINE}, /* TAG_DL */ + {"dt", HTML_CLRLINE}, /* TAG_DT */ + {"dd", HTML_CLRLINE}, /* TAG_DD */ + {"blockquote", HTML_CLRLINE}, /* TAG_BLOCKQUOTE */ + {"p", HTML_CLRLINE | HTML_NOSTACK | HTML_AUTOCLOSE}, /* TAG_P */ }; static const char *const htmlfonts[HTMLFONT_MAX] = { @@ -90,7 +94,8 @@ static const char *const htmlattrs[ATTR_MAX] = { "summary", }; -static void print_spec(struct html *, const char *, size_t); +static void print_spec(struct html *, enum roffdeco, + 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 *); @@ -117,12 +122,11 @@ ml_alloc(char *outopts, enum htmltype type) h = calloc(1, sizeof(struct html)); if (NULL == h) { perror(NULL); - exit(EXIT_FAILURE); + exit((int)MANDOCLEVEL_SYSERR); } h->type = type; h->tags.head = NULL; - h->ords.head = NULL; h->symtab = chars_init(CHARS_HTML); while (outopts && *outopts) @@ -163,16 +167,10 @@ void html_free(void *p) { struct tag *tag; - struct ord *ord; struct html *h; h = (struct html *)p; - while ((ord = h->ords.head) != NULL) { - h->ords.head = ord->next; - free(ord); - } - while ((tag = h->tags.head) != NULL) { h->tags.head = tag->next; free(tag); @@ -217,30 +215,41 @@ print_gen_head(struct html *h) static void -print_spec(struct html *h, const char *p, size_t len) +print_spec(struct html *h, enum roffdeco d, const char *p, size_t len) { + int cp; const char *rhs; size_t sz; - rhs = chars_a2ascii(h->symtab, p, len, &sz); - - if (NULL == rhs) + if ((cp = chars_spec2cp(h->symtab, p, len)) > 0) { + printf("&#%d;", cp); return; - fwrite(rhs, 1, sz, stdout); + } else if (-1 == cp && DECO_SSPECIAL == d) { + fwrite(p, 1, len, stdout); + return; + } else if (-1 == cp) + return; + + if (NULL != (rhs = chars_spec2str(h->symtab, p, len, &sz))) + fwrite(rhs, 1, sz, stdout); } static void print_res(struct html *h, const char *p, size_t len) { + int cp; const char *rhs; size_t sz; - rhs = chars_a2res(h->symtab, p, len, &sz); - - if (NULL == rhs) + if ((cp = chars_res2cp(h->symtab, p, len)) > 0) { + printf("&#%d;", cp); return; - fwrite(rhs, 1, sz, stdout); + } else if (-1 == cp) + return; + + if (NULL != (rhs = chars_res2str(h->symtab, p, len, &sz))) + fwrite(rhs, 1, sz, stdout); } @@ -336,8 +345,10 @@ print_encode(struct html *h, const char *p, int norecu case (DECO_RESERVED): print_res(h, seq, sz); break; + case (DECO_SSPECIAL): + /* FALLTHROUGH */ case (DECO_SPECIAL): - print_spec(h, seq, sz); + print_spec(h, deco, seq, sz); break; case (DECO_PREVIOUS): /* FALLTHROUGH */ @@ -386,7 +397,7 @@ print_otag(struct html *h, enum htmltag tag, t = malloc(sizeof(struct tag)); if (NULL == t) { perror(NULL); - exit(EXIT_FAILURE); + exit((int)MANDOCLEVEL_SYSERR); } t->tag = tag; t->next = h->tags.head; @@ -395,9 +406,21 @@ print_otag(struct html *h, enum htmltag tag, t = NULL; if ( ! (HTML_NOSPACE & h->flags)) - if ( ! (HTML_CLRLINE & htmltags[tag].flags)) - putchar(' '); + if ( ! (HTML_CLRLINE & htmltags[tag].flags)) { + /* Manage keeps! */ + if ( ! (HTML_KEEP & h->flags)) { + if (HTML_PREKEEP & h->flags) + h->flags |= HTML_KEEP; + putchar(' '); + } else + printf(" "); + } + if ( ! (h->flags & HTML_NONOSPACE)) + h->flags &= ~HTML_NOSPACE; + else + h->flags |= HTML_NOSPACE; + /* Print out the tag name and attributes. */ printf("<%s", htmltags[tag].name); @@ -426,6 +449,10 @@ print_otag(struct html *h, enum htmltag tag, putchar('>'); h->flags |= HTML_NOSPACE; + + if ((HTML_AUTOCLOSE | HTML_CLRLINE) & htmltags[tag].flags) + putchar('\n'); + return(t); } @@ -486,11 +513,11 @@ print_doctype(struct html *h) void -print_text(struct html *h, const char *p) +print_text(struct html *h, const char *word) { - if (*p && 0 == *(p + 1)) - switch (*p) { + if (word[0] && '\0' == word[1]) + switch (word[0]) { case('.'): /* FALLTHROUGH */ case(','): @@ -513,19 +540,29 @@ print_text(struct html *h, const char *p) break; } - if ( ! (h->flags & HTML_NOSPACE)) - putchar(' '); + if ( ! (HTML_NOSPACE & h->flags)) { + /* Manage keeps! */ + if ( ! (HTML_KEEP & h->flags)) { + if (HTML_PREKEEP & h->flags) + h->flags |= HTML_KEEP; + putchar(' '); + } else + printf(" "); + } - assert(p); - if ( ! print_encode(h, p, 0)) - h->flags &= ~HTML_NOSPACE; + assert(word); + if ( ! print_encode(h, word, 0)) + if ( ! (h->flags & HTML_NONOSPACE)) + h->flags &= ~HTML_NOSPACE; + h->flags &= ~HTML_IGNDELIM; + /* * Note that we don't process the pipe: the parser sees it as * punctuation, but we don't in terms of typography. */ - if (*p && 0 == *(p + 1)) - switch (*p) { + if (word[0] && '\0' == word[1]) + switch (word[0]) { case('('): /* FALLTHROUGH */ case('['): @@ -720,11 +757,11 @@ bufcat_su(struct html *h, const char *p, const struct break; } - if (su->pt) - buffmt(h, "%s: %f%s;", p, v, u); - else - /* LINTED */ - buffmt(h, "%s: %d%s;", p, (int)v, u); + /* + * XXX: the CSS spec isn't clear as to which types accept + * integer or real numbers, so we just make them all decimals. + */ + buffmt(h, "%s: %.2f%s;", p, v, u); }