=================================================================== RCS file: /cvsrepo/anoncvs/cvs/src/usr.bin/mandoc/html.c,v retrieving revision 1.4 retrieving revision 1.5 diff -c -r1.4 -r1.5 *** src/usr.bin/mandoc/html.c 2009/12/23 22:30:17 1.4 --- src/usr.bin/mandoc/html.c 2009/12/24 02:08:14 1.5 *************** *** 1,4 **** ! /* $Id: html.c,v 1.4 2009/12/23 22:30:17 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * --- 1,4 ---- ! /* $Id: html.c,v 1.5 2009/12/24 02:08:14 schwarze Exp $ */ /* * Copyright (c) 2008, 2009 Kristaps Dzonsons * *************** *** 66,72 **** {"base", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_BASE */ }; ! static const char *const htmlattrs[ATTR_MAX] = { "http-equiv", "content", "name", --- 66,78 ---- {"base", HTML_CLRLINE | HTML_NOSTACK}, /* TAG_BASE */ }; ! static const char *const htmlfonts[HTMLFONT_MAX] = { ! "roman", ! "bold", ! "italic" ! }; ! ! static const char *const htmlattrs[ATTR_MAX] = { "http-equiv", "content", "name", *************** *** 83,88 **** --- 89,102 ---- "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 int print_encode(struct html *, const char *, int); + static void print_metaf(struct html *, enum roffdeco); + + void * html_alloc(char *outopts) { *************** *** 182,193 **** static void ! print_spec(struct html *h, const char *p, int len) { const char *rhs; size_t sz; ! rhs = chars_a2ascii(h->symtab, p, (size_t)len, &sz); if (NULL == rhs) return; --- 196,207 ---- static void ! print_spec(struct html *h, const char *p, size_t len) { const char *rhs; size_t sz; ! rhs = chars_a2ascii(h->symtab, p, len, &sz); if (NULL == rhs) return; *************** *** 196,207 **** static void ! print_res(struct html *h, const char *p, int len) { const char *rhs; size_t sz; ! rhs = chars_a2res(h->symtab, p, (size_t)len, &sz); if (NULL == rhs) return; --- 210,221 ---- static void ! print_res(struct html *h, const char *p, size_t len) { const char *rhs; size_t sz; ! rhs = chars_a2res(h->symtab, p, len, &sz); if (NULL == rhs) return; *************** *** 209,319 **** } ! static void ! print_escape(struct html *h, const char **p) { ! int j, type; ! const char *wp; ! wp = *p; ! type = 1; ! if (0 == *(++wp)) { ! *p = wp; ! return; ! } ! if ('(' == *wp) { ! wp++; ! if (0 == *wp || 0 == *(wp + 1)) { ! *p = 0 == *wp ? wp : wp + 1; ! return; ! } ! print_spec(h, wp, 2); ! *p = ++wp; ! return; - } else if ('*' == *wp) { - if (0 == *(++wp)) { - *p = wp; - return; - } ! switch (*wp) { ! case ('('): ! wp++; ! if (0 == *wp || 0 == *(wp + 1)) { ! *p = 0 == *wp ? wp : wp + 1; ! return; ! } ! print_res(h, wp, 2); ! *p = ++wp; ! return; ! case ('['): ! type = 0; ! break; ! default: ! print_res(h, wp, 1); ! *p = wp; ! return; ! } ! ! } else if ('f' == *wp) { ! if (0 == *(++wp)) { ! *p = wp; ! return; ! } ! ! switch (*wp) { ! case ('B'): ! /* TODO */ ! break; ! case ('I'): ! /* TODO */ ! break; ! case ('P'): ! /* FALLTHROUGH */ ! case ('R'): ! /* TODO */ ! break; ! default: ! break; ! } ! ! *p = wp; ! return; ! ! } else if ('[' != *wp) { ! print_spec(h, wp, 1); ! *p = wp; ! return; } ! wp++; ! for (j = 0; *wp && ']' != *wp; wp++, j++) ! /* Loop... */ ; ! ! if (0 == *wp) { ! *p = wp; ! return; ! } ! ! if (type) ! print_spec(h, wp - j, j); ! else ! print_res(h, wp - j, j); ! ! *p = wp; } ! static void ! print_encode(struct html *h, const char *p) { size_t sz; for (; *p; p++) { sz = strcspn(p, "\\<>&"); --- 223,284 ---- } ! struct tag * ! print_ofont(struct html *h, enum htmlfont font) { ! struct htmlpair tag; ! h->metal = h->metac; ! h->metac = font; ! /* FIXME: DECO_ROMAN should just close out preexisting. */ ! if (h->metaf && h->tags.head == h->metaf) ! print_tagq(h, h->metaf); ! PAIR_CLASS_INIT(&tag, htmlfonts[font]); ! h->metaf = print_otag(h, TAG_SPAN, 1, &tag); ! return(h->metaf); ! } ! static void ! print_metaf(struct html *h, enum roffdeco deco) ! { ! enum htmlfont font; ! switch (deco) { ! case (DECO_PREVIOUS): ! font = h->metal; ! break; ! case (DECO_ITALIC): ! font = HTMLFONT_ITALIC; ! break; ! case (DECO_BOLD): ! font = HTMLFONT_BOLD; ! break; ! case (DECO_ROMAN): ! font = HTMLFONT_NONE; ! break; ! default: ! abort(); ! /* NOTREACHED */ } ! (void)print_ofont(h, font); } ! static int ! print_encode(struct html *h, const char *p, int norecurse) { size_t sz; + int len, nospace; + const char *seq; + enum roffdeco deco; + nospace = 0; + for (; *p; p++) { sz = strcspn(p, "\\<>&"); *************** *** 321,339 **** p += /* LINTED */ sz; ! if ('\\' == *p) { ! print_escape(h, &p); continue; } else if ('\0' == *p) break; ! if ('<' == *p) ! printf("<"); ! else if ('>' == *p) ! printf(">"); ! else if ('&' == *p) ! printf("&"); } } --- 286,335 ---- p += /* LINTED */ sz; ! if ('<' == *p) { ! printf("<"); continue; + } else if ('>' == *p) { + printf(">"); + continue; + } else if ('&' == *p) { + printf("&"); + continue; } else if ('\0' == *p) break; ! seq = ++p; ! len = a2roffdeco(&deco, &seq, &sz); ! ! switch (deco) { ! case (DECO_RESERVED): ! print_res(h, seq, sz); ! break; ! case (DECO_SPECIAL): ! print_spec(h, seq, sz); ! break; ! case (DECO_PREVIOUS): ! /* FALLTHROUGH */ ! case (DECO_BOLD): ! /* FALLTHROUGH */ ! case (DECO_ITALIC): ! /* FALLTHROUGH */ ! case (DECO_ROMAN): ! if (norecurse) ! break; ! print_metaf(h, deco); ! break; ! default: ! break; ! } ! ! p += len - 1; ! ! if (DECO_NOSPACE == deco && '\0' == *(p + 1)) ! nospace = 1; } + + return(nospace); } *************** *** 364,385 **** for (i = 0; i < sz; i++) { printf(" %s=\"", htmlattrs[p[i].key]); assert(p->val); ! print_encode(h, p[i].val); putchar('\"'); } putchar('>'); h->flags |= HTML_NOSPACE; - if (HTML_CLRLINE & htmltags[tag].flags) - h->flags |= HTML_NEWLINE; - else - h->flags &= ~HTML_NEWLINE; - return(t); } - /* ARGSUSED */ static void print_ctag(struct html *h, enum htmltag tag) { --- 360,375 ---- for (i = 0; i < sz; i++) { printf(" %s=\"", htmlattrs[p[i].key]); assert(p->val); ! (void)print_encode(h, p[i].val, 1); putchar('\"'); } putchar('>'); h->flags |= HTML_NOSPACE; return(t); } static void print_ctag(struct html *h, enum htmltag tag) { *************** *** 387,396 **** printf("", htmltags[tag].name); if (HTML_CLRLINE & htmltags[tag].flags) { h->flags |= HTML_NOSPACE; - h->flags |= HTML_NEWLINE; putchar('\n'); ! } else ! h->flags &= ~HTML_NEWLINE; } --- 377,384 ---- printf("", htmltags[tag].name); if (HTML_CLRLINE & htmltags[tag].flags) { h->flags |= HTML_NOSPACE; putchar('\n'); ! } } *************** *** 436,447 **** if ( ! (h->flags & HTML_NOSPACE)) putchar(' '); ! h->flags &= ~HTML_NOSPACE; ! h->flags &= ~HTML_NEWLINE; - if (p) - print_encode(h, p); - if (*p && 0 == *(p + 1)) switch (*p) { case('('): --- 424,433 ---- if ( ! (h->flags & HTML_NOSPACE)) putchar(' '); ! assert(p); ! if ( ! print_encode(h, p, 0)) ! h->flags &= ~HTML_NOSPACE; if (*p && 0 == *(p + 1)) switch (*p) { case('('): *************** *** 463,468 **** --- 449,456 ---- struct tag *tag; while ((tag = h->tags.head) != NULL) { + if (tag == h->metaf) + h->metaf = NULL; print_ctag(h, tag->tag); h->tags.head = tag->next; free(tag); *************** *** 480,485 **** --- 468,475 ---- while ((tag = h->tags.head) != NULL) { if (suntil && tag == suntil) return; + if (tag == h->metaf) + h->metaf = NULL; print_ctag(h, tag->tag); h->tags.head = tag->next; free(tag);