summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chars.c59
-rw-r--r--chars.in532
-rw-r--r--html.c170
3 files changed, 448 insertions, 313 deletions
diff --git a/chars.c b/chars.c
index eaf80689..5115816c 100644
--- a/chars.c
+++ b/chars.c
@@ -21,15 +21,17 @@
#include "chars.h"
-#define ASCII_PRINT_HI 126
-#define ASCII_PRINT_LO 32
+#define PRINT_HI 126
+#define PRINT_LO 32
struct ln {
struct ln *next;
const char *code;
- const char *out;
+ const char *ascii;
+ const char *html;
size_t codesz;
- size_t outsz;
+ size_t asciisz;
+ size_t htmlsz;
int type;
#define CHARS_CHAR (1 << 0)
#define CHARS_STRING (1 << 1)
@@ -38,18 +40,19 @@ struct ln {
#define LINES_MAX 266
-#define CHAR(w, x, y, z) \
- { NULL, (w), (y), (x), (z), CHARS_CHAR },
-#define STRING(w, x, y, z) \
- { NULL, (w), (y), (x), (z), CHARS_STRING },
-#define BOTH(w, x, y, z) \
- { NULL, (w), (y), (x), (z), CHARS_BOTH },
+#define CHAR(w, x, y, z, a, b) \
+ { NULL, (w), (y), (a), (x), (z), (b), CHARS_CHAR },
+#define STRING(w, x, y, z, a, b) \
+ { NULL, (w), (y), (a), (x), (z), (b), CHARS_STRING },
+#define BOTH(w, x, y, z, a, b) \
+ { NULL, (w), (y), (a), (x), (z), (b), CHARS_BOTH },
static struct ln lines[LINES_MAX] = {
#include "chars.in"
};
struct tbl {
+ enum chars type;
struct ln **htab;
};
@@ -71,7 +74,6 @@ chars_free(void *arg)
}
-/* ARGSUSED */
void *
chars_init(enum chars type)
{
@@ -89,19 +91,14 @@ chars_init(enum chars type)
if (NULL == (tab = malloc(sizeof(struct tbl))))
err(1, "malloc");
+ tab->type = type;
- htab = calloc(ASCII_PRINT_HI - ASCII_PRINT_LO + 1,
- sizeof(struct ln **));
-
+ htab = calloc(PRINT_HI - PRINT_LO + 1, sizeof(struct ln **));
if (NULL == htab)
err(1, "malloc");
for (i = 0; i < LINES_MAX; i++) {
- assert(lines[i].codesz > 0);
- assert(lines[i].code);
- assert(lines[i].out);
-
- hash = (int)lines[i].code[0] - ASCII_PRINT_LO;
+ hash = (int)lines[i].code[0] - PRINT_LO;
if (NULL == (pp = htab[hash])) {
htab[hash] = &lines[i];
@@ -110,7 +107,6 @@ chars_init(enum chars type)
for ( ; pp->next; pp = pp->next)
/* Scan ahead. */ ;
-
pp->next = &lines[i];
}
@@ -145,7 +141,7 @@ find(struct tbl *tab, const char *p, size_t sz, size_t *rsz, int type)
assert(p);
assert(sz > 0);
- if (p[0] < ASCII_PRINT_LO || p[0] > ASCII_PRINT_HI)
+ if (p[0] < PRINT_LO || p[0] > PRINT_HI)
return(NULL);
/*
@@ -154,7 +150,7 @@ find(struct tbl *tab, const char *p, size_t sz, size_t *rsz, int type)
* to optimise for repeat hits.
*/
- hash = (int)p[0] - ASCII_PRINT_LO;
+ hash = (int)p[0] - PRINT_LO;
htab = tab->htab;
if (NULL == (pp = htab[hash]))
@@ -163,8 +159,13 @@ find(struct tbl *tab, const char *p, size_t sz, size_t *rsz, int type)
if (NULL == pp->next) {
if ( ! match(pp, p, sz, type))
return(NULL);
- *rsz = pp->outsz;
- return(pp->out);
+
+ if (CHARS_HTML == tab->type) {
+ *rsz = pp->htmlsz;
+ return(pp->html);
+ }
+ *rsz = pp->asciisz;
+ return(pp->ascii);
}
for (prev = NULL; pp; pp = pp->next) {
@@ -173,16 +174,18 @@ find(struct tbl *tab, const char *p, size_t sz, size_t *rsz, int type)
continue;
}
- /* Re-order the hash chain. */
-
if (prev) {
prev->next = pp->next;
pp->next = htab[hash];
htab[hash] = pp;
}
- *rsz = pp->outsz;
- return(pp->out);
+ if (CHARS_HTML == tab->type) {
+ *rsz = pp->htmlsz;
+ return(pp->html);
+ }
+ *rsz = pp->asciisz;
+ return(pp->ascii);
}
return(NULL);
diff --git a/chars.in b/chars.in
index 57f2dee7..e1c20013 100644
--- a/chars.in
+++ b/chars.in
@@ -30,271 +30,271 @@
* XXX - update LINES_MAX if adding more!
*/
-STRING("Am", 2, "&", 1)
-STRING("Ba", 2, "|", 1)
-STRING("Ge", 2, ">=", 2)
-STRING("Gt", 2, ">", 1)
-STRING("If", 2, "infinity", 8)
-STRING("Le", 2, "<=", 2)
-STRING("Lq", 2, "``", 2)
-STRING("Lt", 2, "<", 1)
-STRING("Na", 2, "NaN", 3)
-STRING("Ne", 2, "!=", 2)
-STRING("Pi", 2, "pi", 2)
-STRING("Pm", 2, "+-", 2)
-STRING("R", 1, "(R)", 3)
-STRING("Rq", 2, "\'\'", 2)
-STRING("Tm", 2, "tm", 2)
-STRING("left-bracket", 12, "[", 1)
-STRING("left-parenthesis", 16, "(", 1)
-STRING("left-singlequote", 16, "`", 1)
-STRING("lp", 2, "(", 1)
-STRING("q", 1, "\"", 1)
-STRING("quote-left", 10, "`", 1)
-STRING("quote-right", 11, "\'", 1)
-STRING("right-bracket", 13, "]", 1)
-STRING("right-parenthesis", 17, ")", 1)
-STRING("right-singlequote", 17, "\'", 1)
-STRING("rp", 2, ")", 1)
+STRING("Am", 2, "&", 1, "&amp;", 5)
+STRING("Ba", 2, "|", 1, "|", 0)
+STRING("Ge", 2, ">=", 2, "", 0)
+STRING("Gt", 2, ">", 1, "", 0)
+STRING("If", 2, "infinity", 8, "", 0)
+STRING("Le", 2, "<=", 2, "", 0)
+STRING("Lq", 2, "``", 2, "", 0)
+STRING("Lt", 2, "<", 1, "", 0)
+STRING("Na", 2, "NaN", 3, "", 0)
+STRING("Ne", 2, "!=", 2, "", 0)
+STRING("Pi", 2, "pi", 2, "", 0)
+STRING("Pm", 2, "+-", 2, "", 0)
+STRING("R", 1, "(R)", 3, "", 0)
+STRING("Rq", 2, "\'\'", 2, "", 0)
+STRING("Tm", 2, "tm", 2, "", 0)
+STRING("left-bracket", 12, "[", 1, "", 0)
+STRING("left-parenthesis", 16, "(", 1, "", 0)
+STRING("left-singlequote", 16, "`", 1, "", 0)
+STRING("lp", 2, "(", 1, "", 0)
+STRING("q", 1, "\"", 1, "", 0)
+STRING("quote-left", 10, "`", 1, "", 0)
+STRING("quote-right", 11, "\'", 1, "", 0)
+STRING("right-bracket", 13, "]", 1, "", 0)
+STRING("right-parenthesis", 17, ")", 1, "", 0)
+STRING("right-singlequote", 17, "\'", 1, "", 0)
+STRING("rp", 2, ")", 1, "", 0)
-BOTH("<=", 2, "<=", 2)
-BOTH(">=", 2, ">=", 2)
-BOTH("aa", 2, "\'", 1)
-BOTH("ga", 2, "`", 1)
-BOTH("lq", 2, "``", 2)
-BOTH("rq", 2, "\'\'", 2)
-BOTH("ua", 2, "^", 1)
+BOTH("<=", 2, "<=", 2, "", 0)
+BOTH(">=", 2, ">=", 2, "", 0)
+BOTH("aa", 2, "\'", 1, "", 0)
+BOTH("ga", 2, "`", 1, "", 0)
+BOTH("lq", 2, "``", 2, "", 0)
+BOTH("rq", 2, "\'\'", 2, "", 0)
+BOTH("ua", 2, "^", 1, "", 0)
-CHAR(" ", 1, " ", 1)
-CHAR("!=", 2, "!=", 2)
-CHAR("%", 1, "", 0)
-CHAR("&", 1, "", 0)
-CHAR("(=", 2, "(=", 2)
-CHAR("**", 2, "*", 1)
-CHAR("*A", 2, "A", 1)
-CHAR("*B", 2, "B", 1)
-CHAR("*C", 2, "H", 1)
-CHAR("*D", 2, "/\\", 2)
-CHAR("*E", 2, "E", 1)
-CHAR("*F", 2, "O_", 1)
-CHAR("*G", 2, "|", 1)
-CHAR("*H", 2, "O", 1)
-CHAR("*I", 2, "I", 1)
-CHAR("*K", 2, "K", 1)
-CHAR("*L", 2, "/\\", 2)
-CHAR("*M", 2, "M", 1)
-CHAR("*N", 2, "N", 1)
-CHAR("*O", 2, "O", 1)
-CHAR("*P", 2, "TT", 2)
-CHAR("*Q", 2, "Y", 1)
-CHAR("*R", 2, "P", 1)
-CHAR("*S", 2, ">", 1)
-CHAR("*T", 2, "T", 1)
-CHAR("*U", 2, "Y", 1)
-CHAR("*W", 2, "O", 1)
-CHAR("*X", 2, "X", 1)
-CHAR("*Y", 2, "H", 1)
-CHAR("*Z", 2, "Z", 1)
-CHAR("*a", 2, "a", 1)
-CHAR("*b", 2, "B", 1)
-CHAR("*c", 2, "E", 1)
-CHAR("*d", 2, "d", 1)
-CHAR("*e", 2, "e", 1)
-CHAR("*f", 2, "o", 1)
-CHAR("*g", 2, "y", 1)
-CHAR("*h", 2, "0", 1)
-CHAR("*i", 2, "i", 1)
-CHAR("*k", 2, "k", 1)
-CHAR("*l", 2, "\\", 1)
-CHAR("*m", 2, "u", 1)
-CHAR("*n", 2, "v", 1)
-CHAR("*o", 2, "o", 1)
-CHAR("*p", 2, "n", 1)
-CHAR("*q", 2, "u", 1)
-CHAR("*r", 2, "p", 1)
-CHAR("*s", 2, "o", 1)
-CHAR("*t", 2, "t", 1)
-CHAR("*u", 2, "u", 1)
-CHAR("*w", 2, "w", 1)
-CHAR("*x", 2, "x", 1)
-CHAR("*y", 2, "n", 1)
-CHAR("*z", 2, "C", 1)
-CHAR("+-", 2, "+-", 2)
-CHAR("+f", 2, "o", 1)
-CHAR("+h", 2, "0", 1)
-CHAR("+p", 2, "w", 1)
-CHAR(",C", 2, "C", 1)
-CHAR(",c", 2, "c", 1)
-CHAR("-", 1, "-", 1)
-CHAR("->", 2, "->", 2)
-CHAR("-D", 2, "D", 1)
-CHAR(".", 1, ".", 1)
-CHAR("/L", 2, "L", 1)
-CHAR("/O", 2, "O", 1)
-CHAR("/l", 2, "l", 1)
-CHAR("/o", 2, "o", 1)
-CHAR("0", 1, " ", 1)
-CHAR(":A", 2, "A", 1)
-CHAR(":E", 2, "E", 1)
-CHAR(":I", 2, "I", 1)
-CHAR(":O", 2, "O", 1)
-CHAR(":U", 2, "U", 1)
-CHAR(":a", 2, "a", 1)
-CHAR(":e", 2, "e", 1)
-CHAR(":i", 2, "i", 1)
-CHAR(":o", 2, "o", 1)
-CHAR(":u", 2, "u", 1)
-CHAR(":y", 2, "y", 1)
-CHAR("<-", 2, "<-", 2)
-CHAR("<=", 2, "<=", 2)
-CHAR("<>", 2, "<>", 2)
-CHAR("=)", 2, "=)", 2)
-CHAR("==", 2, "==", 2)
-CHAR("=~", 2, "=~", 2)
-CHAR(">=", 2, ">=", 2)
-CHAR("AE", 2, "AE", 2)
-CHAR("AN", 2, "^", 1)
-CHAR("Ah", 2, "N", 1)
-CHAR("Bq", 2, ",,", 2)
-CHAR("Cs", 2, "x", 1)
-CHAR("Do", 2, "$", 1)
-CHAR("Eu", 2, "EUR", 3)
-CHAR("Fc", 2, ">>", 2)
-CHAR("Fi", 2, "ffi", 3)
-CHAR("Fl", 2, "ffl", 3)
-CHAR("Fn", 2, "f", 1)
-CHAR("Fo", 2, "<<", 2)
-CHAR("Im", 2, "I", 1)
-CHAR("OE", 2, "OE", 2)
-CHAR("OR", 2, "v", 1)
-CHAR("Po", 2, "L", 1)
-CHAR("Re", 2, "R", 1)
-CHAR("Sd", 2, "o", 1)
-CHAR("TP", 2, "b", 1)
-CHAR("Tp", 2, "b", 1)
-CHAR("Ye", 2, "Y", 1)
-CHAR("\'", 1, "\'", 1)
-CHAR("\'A", 2, "A", 1)
-CHAR("\'E", 2, "E", 1)
-CHAR("\'I", 2, "I", 1)
-CHAR("\'O", 2, "O", 1)
-CHAR("\'U", 2, "U", 1)
-CHAR("\'a", 2, "a", 1)
-CHAR("\'e", 2, "e", 1)
-CHAR("\'i", 2, "i", 1)
-CHAR("\'o", 2, "o", 1)
-CHAR("\'u", 2, "u", 1)
-CHAR("\\", 1, "\\", 1)
-CHAR("^", 1, "", 0)
-CHAR("^A", 2, "A", 1)
-CHAR("^E", 2, "E", 1)
-CHAR("^I", 2, "I", 1)
-CHAR("^O", 2, "O", 1)
-CHAR("^U", 2, "U", 1)
-CHAR("^a", 2, "a", 1)
-CHAR("^e", 2, "e", 1)
-CHAR("^i", 2, "i", 1)
-CHAR("^o", 2, "o", 1)
-CHAR("^u", 2, "u", 1)
-CHAR("`", 1, "`", 1)
-CHAR("`A", 2, "A", 1)
-CHAR("`E", 2, "E", 1)
-CHAR("`I", 2, "I", 1)
-CHAR("`O", 2, "O", 1)
-CHAR("`U", 2, "U", 1)
-CHAR("`a", 2, "a", 1)
-CHAR("`e", 2, "e", 1)
-CHAR("`i", 2, "i", 1)
-CHAR("`o", 2, "o", 1)
-CHAR("`u", 2, "u", 1)
-CHAR("a-", 2, "-", 1)
-CHAR("a\"", 2, "\"", 1)
-CHAR("a^", 2, "^", 1)
-CHAR("aa", 2, "\'", 1)
-CHAR("ab", 2, "`", 1)
-CHAR("ac", 2, ",", 1)
-CHAR("ad", 2, "\"", 1)
-CHAR("ae", 2, "ae", 2)
-CHAR("ah", 2, "v", 1)
-CHAR("ao", 2, "o", 1)
-CHAR("ap", 2, "~", 1)
-CHAR("aq", 2, "\'", 1)
-CHAR("a~", 2, "~", 1)
-CHAR("ba", 2, "|", 1)
-CHAR("bb", 2, "|", 1)
-CHAR("bq", 2, ",", 1)
-CHAR("bu", 2, "o", 1)
-CHAR("c", 1, "", 0)
-CHAR("ca", 2, "(^)", 3)
-CHAR("ci", 2, "O", 1)
-CHAR("co", 2, "(C)", 3)
-CHAR("ct", 2, "c", 1)
-CHAR("cu", 2, "U", 1)
-CHAR("dA", 2, "v", 1)
-CHAR("da", 2, "v", 1)
-CHAR("dd", 2, "=", 1)
-CHAR("de", 2, "o", 1)
-CHAR("dg", 2, "-", 1)
-CHAR("di", 2, "-:-", 3)
-CHAR("e", 1, "\\", 1)
-CHAR("em", 2, "--", 2)
-CHAR("en", 2, "-", 1)
-CHAR("eq", 2, "=", 1)
-CHAR("es", 2, "{}", 2)
-CHAR("eu", 2, "EUR", 3)
-CHAR("fa", 2, "V", 1)
-CHAR("fc", 2, ">", 1)
-CHAR("ff", 2, "ff", 2)
-CHAR("fi", 2, "fi", 2)
-CHAR("fl", 2, "fl", 2)
-CHAR("fo", 2, "<", 1)
-CHAR("ga", 2, "`", 1)
-CHAR("gr", 2, "V", 1)
-CHAR("hA", 2, "<=>", 3)
-CHAR("ho", 2, ",", 1)
-CHAR("hy", 2, "-", 1)
-CHAR("if", 2, "oo", 2)
-CHAR("lA", 2, "<=", 2)
-CHAR("lB", 2, "[", 1)
-CHAR("lC", 2, "{", 1)
-CHAR("la", 2, "<", 1)
-CHAR("lh", 2, "<=", 2)
-CHAR("mo", 2, "E", 1)
-CHAR("mu", 2, "x", 1)
-CHAR("na", 2, "NaN", 3)
-CHAR("nm", 2, "E", 1)
-CHAR("no", 2, "~", 1)
-CHAR("oA", 2, "A", 1)
-CHAR("oa", 2, "a", 1)
-CHAR("oe", 2, "oe", 2)
-CHAR("oq", 2, "`", 1)
-CHAR("pd", 2, "a", 1)
-CHAR("pl", 2, "+", 1)
-CHAR("ps", 2, "9|", 2)
-CHAR("r!", 2, "i", 1)
-CHAR("r?", 2, "c", 1)
-CHAR("rA", 2, "=>", 2)
-CHAR("rB", 2, "]", 1)
-CHAR("rC", 2, "}", 1)
-CHAR("ra", 2, ">", 1)
-CHAR("rg", 2, "(R)", 3)
-CHAR("rh", 2, "=>", 2)
-CHAR("sc", 2, "S", 1)
-CHAR("ss", 2, "ss", 2)
-CHAR("st", 2, "-)", 2)
-CHAR("te", 2, "3", 1)
-CHAR("tf", 2, ".:.", 3)
-CHAR("tm", 2, "tm", 2)
-CHAR("ts", 2, "s", 1)
-CHAR("uA", 2, "^", 1)
-CHAR("ua", 2, "^", 1)
-CHAR("|", 1, "", 0)
-CHAR("~", 1, " ", 1)
-CHAR("~=", 2, "~=", 2)
-CHAR("~A", 2, "A", 1)
-CHAR("~N", 2, "N", 1)
-CHAR("~O", 2, "O", 1)
-CHAR("~a", 2, "a", 1)
-CHAR("~n", 2, "n", 1)
-CHAR("~o", 2, "o", 1)
-CHAR("~~", 2, "~~", 2)
+CHAR(" ", 1, " ", 1, " ", 1)
+CHAR("!=", 2, "!=", 2, "", 0)
+CHAR("%", 1, "", 0, "", 0)
+CHAR("&", 1, "", 0, "", 0)
+CHAR("(=", 2, "(=", 2, "", 0)
+CHAR("**", 2, "*", 1, "", 0)
+CHAR("*A", 2, "A", 1, "", 0)
+CHAR("*B", 2, "B", 1, "", 0)
+CHAR("*C", 2, "H", 1, "", 0)
+CHAR("*D", 2, "/\\", 2, "", 0)
+CHAR("*E", 2, "E", 1, "", 0)
+CHAR("*F", 2, "O_", 1, "", 0)
+CHAR("*G", 2, "|", 1, "", 0)
+CHAR("*H", 2, "O", 1, "", 0)
+CHAR("*I", 2, "I", 1, "", 0)
+CHAR("*K", 2, "K", 1, "", 0)
+CHAR("*L", 2, "/\\", 2, "", 0)
+CHAR("*M", 2, "M", 1, "", 0)
+CHAR("*N", 2, "N", 1, "", 0)
+CHAR("*O", 2, "O", 1, "", 0)
+CHAR("*P", 2, "TT", 2, "", 0)
+CHAR("*Q", 2, "Y", 1, "", 0)
+CHAR("*R", 2, "P", 1, "", 0)
+CHAR("*S", 2, ">", 1, "", 0)
+CHAR("*T", 2, "T", 1, "", 0)
+CHAR("*U", 2, "Y", 1, "", 0)
+CHAR("*W", 2, "O", 1, "", 0)
+CHAR("*X", 2, "X", 1, "", 0)
+CHAR("*Y", 2, "H", 1, "", 0)
+CHAR("*Z", 2, "Z", 1, "", 0)
+CHAR("*a", 2, "a", 1, "", 0)
+CHAR("*b", 2, "B", 1, "", 0)
+CHAR("*c", 2, "E", 1, "", 0)
+CHAR("*d", 2, "d", 1, "", 0)
+CHAR("*e", 2, "e", 1, "", 0)
+CHAR("*f", 2, "o", 1, "", 0)
+CHAR("*g", 2, "y", 1, "", 0)
+CHAR("*h", 2, "0", 1, "", 0)
+CHAR("*i", 2, "i", 1, "", 0)
+CHAR("*k", 2, "k", 1, "", 0)
+CHAR("*l", 2, "\\", 1, "", 0)
+CHAR("*m", 2, "u", 1, "", 0)
+CHAR("*n", 2, "v", 1, "", 0)
+CHAR("*o", 2, "o", 1, "", 0)
+CHAR("*p", 2, "n", 1, "", 0)
+CHAR("*q", 2, "u", 1, "", 0)
+CHAR("*r", 2, "p", 1, "", 0)
+CHAR("*s", 2, "o", 1, "", 0)
+CHAR("*t", 2, "t", 1, "", 0)
+CHAR("*u", 2, "u", 1, "", 0)
+CHAR("*w", 2, "w", 1, "", 0)
+CHAR("*x", 2, "x", 1, "", 0)
+CHAR("*y", 2, "n", 1, "", 0)
+CHAR("*z", 2, "C", 1, "", 0)
+CHAR("+-", 2, "+-", 2, "", 0)
+CHAR("+f", 2, "o", 1, "", 0)
+CHAR("+h", 2, "0", 1, "", 0)
+CHAR("+p", 2, "w", 1, "", 0)
+CHAR(",C", 2, "C", 1, "", 0)
+CHAR(",c", 2, "c", 1, "", 0)
+CHAR("-", 1, "-", 1, "-", 1)
+CHAR("->", 2, "->", 2, "", 0)
+CHAR("-D", 2, "D", 1, "", 0)
+CHAR(".", 1, ".", 1, "", 0)
+CHAR("/L", 2, "L", 1, "", 0)
+CHAR("/O", 2, "O", 1, "", 0)
+CHAR("/l", 2, "l", 1, "", 0)
+CHAR("/o", 2, "o", 1, "", 0)
+CHAR("0", 1, " ", 1, "", 0)
+CHAR(":A", 2, "A", 1, "", 0)
+CHAR(":E", 2, "E", 1, "", 0)
+CHAR(":I", 2, "I", 1, "", 0)
+CHAR(":O", 2, "O", 1, "", 0)
+CHAR(":U", 2, "U", 1, "", 0)
+CHAR(":a", 2, "a", 1, "", 0)
+CHAR(":e", 2, "e", 1, "", 0)
+CHAR(":i", 2, "i", 1, "", 0)
+CHAR(":o", 2, "o", 1, "", 0)
+CHAR(":u", 2, "u", 1, "", 0)
+CHAR(":y", 2, "y", 1, "", 0)
+CHAR("<-", 2, "<-", 2, "", 0)
+CHAR("<=", 2, "<=", 2, "", 0)
+CHAR("<>", 2, "<>", 2, "", 0)
+CHAR("=)", 2, "=)", 2, "", 0)
+CHAR("==", 2, "==", 2, "", 0)
+CHAR("=~", 2, "=~", 2, "", 0)
+CHAR(">=", 2, ">=", 2, "", 0)
+CHAR("AE", 2, "AE", 2, "", 0)
+CHAR("AN", 2, "^", 1, "", 0)
+CHAR("Ah", 2, "N", 1, "", 0)
+CHAR("Bq", 2, ",,", 2, "", 0)
+CHAR("Cs", 2, "x", 1, "", 0)
+CHAR("Do", 2, "$", 1, "", 0)
+CHAR("Eu", 2, "EUR", 3, "", 0)
+CHAR("Fc", 2, ">>", 2, "", 0)
+CHAR("Fi", 2, "ffi", 3, "", 0)
+CHAR("Fl", 2, "ffl", 3, "", 0)
+CHAR("Fn", 2, "f", 1, "", 0)
+CHAR("Fo", 2, "<<", 2, "", 0)
+CHAR("Im", 2, "I", 1, "", 0)
+CHAR("OE", 2, "OE", 2, "", 0)
+CHAR("OR", 2, "v", 1, "", 0)
+CHAR("Po", 2, "L", 1, "", 0)
+CHAR("Re", 2, "R", 1, "", 0)
+CHAR("Sd", 2, "o", 1, "", 0)
+CHAR("TP", 2, "b", 1, "", 0)
+CHAR("Tp", 2, "b", 1, "", 0)
+CHAR("Ye", 2, "Y", 1, "", 0)
+CHAR("\'", 1, "\'", 1, "", 0)
+CHAR("\'A", 2, "A", 1, "", 0)
+CHAR("\'E", 2, "E", 1, "", 0)
+CHAR("\'I", 2, "I", 1, "", 0)
+CHAR("\'O", 2, "O", 1, "", 0)
+CHAR("\'U", 2, "U", 1, "", 0)
+CHAR("\'a", 2, "a", 1, "", 0)
+CHAR("\'e", 2, "e", 1, "", 0)
+CHAR("\'i", 2, "i", 1, "", 0)
+CHAR("\'o", 2, "o", 1, "", 0)
+CHAR("\'u", 2, "u", 1, "", 0)
+CHAR("\\", 1, "\\", 1, "", 0)
+CHAR("^", 1, "", 0, "", 0)
+CHAR("^A", 2, "A", 1, "", 0)
+CHAR("^E", 2, "E", 1, "", 0)
+CHAR("^I", 2, "I", 1, "", 0)
+CHAR("^O", 2, "O", 1, "", 0)
+CHAR("^U", 2, "U", 1, "", 0)
+CHAR("^a", 2, "a", 1, "", 0)
+CHAR("^e", 2, "e", 1, "", 0)
+CHAR("^i", 2, "i", 1, "", 0)
+CHAR("^o", 2, "o", 1, "", 0)
+CHAR("^u", 2, "u", 1, "", 0)
+CHAR("`", 1, "`", 1, "", 0)
+CHAR("`A", 2, "A", 1, "", 0)
+CHAR("`E", 2, "E", 1, "", 0)
+CHAR("`I", 2, "I", 1, "", 0)
+CHAR("`O", 2, "O", 1, "", 0)
+CHAR("`U", 2, "U", 1, "", 0)
+CHAR("`a", 2, "a", 1, "", 0)
+CHAR("`e", 2, "e", 1, "", 0)
+CHAR("`i", 2, "i", 1, "", 0)
+CHAR("`o", 2, "o", 1, "", 0)
+CHAR("`u", 2, "u", 1, "", 0)
+CHAR("a-", 2, "-", 1, "", 0)
+CHAR("a\"", 2, "\"", 1, "", 0)
+CHAR("a^", 2, "^", 1, "", 0)
+CHAR("aa", 2, "\'", 1, "", 0)
+CHAR("ab", 2, "`", 1, "", 0)
+CHAR("ac", 2, ",", 1, "", 0)
+CHAR("ad", 2, "\"", 1, "", 0)
+CHAR("ae", 2, "ae", 2, "", 0)
+CHAR("ah", 2, "v", 1, "", 0)
+CHAR("ao", 2, "o", 1, "", 0)
+CHAR("ap", 2, "~", 1, "", 0)
+CHAR("aq", 2, "\'", 1, "", 0)
+CHAR("a~", 2, "~", 1, "", 0)
+CHAR("ba", 2, "|", 1, "", 0)
+CHAR("bb", 2, "|", 1, "", 0)
+CHAR("bq", 2, ",", 1, "", 0)
+CHAR("bu", 2, "o", 1, "", 0)
+CHAR("c", 1, "", 0, "", 0)
+CHAR("ca", 2, "(^)", 3, "", 0)
+CHAR("ci", 2, "O", 1, "", 0)
+CHAR("co", 2, "(C)", 3, "", 0)
+CHAR("ct", 2, "c", 1, "", 0)
+CHAR("cu", 2, "U", 1, "", 0)
+CHAR("dA", 2, "v", 1, "", 0)
+CHAR("da", 2, "v", 1, "", 0)
+CHAR("dd", 2, "=", 1, "", 0)
+CHAR("de", 2, "o", 1, "", 0)
+CHAR("dg", 2, "-", 1, "", 0)
+CHAR("di", 2, "-:-", 3, "", 0)
+CHAR("e", 1, "\\", 1, "", 0)
+CHAR("em", 2, "--", 2, "&#8212;", 7)
+CHAR("en", 2, "-", 1, "&#8211;", 7)
+CHAR("eq", 2, "=", 1, "", 0)
+CHAR("es", 2, "{}", 2, "", 0)
+CHAR("eu", 2, "EUR", 3, "", 0)
+CHAR("fa", 2, "V", 1, "", 0)
+CHAR("fc", 2, ">", 1, "", 0)
+CHAR("ff", 2, "ff", 2, "", 0)
+CHAR("fi", 2, "fi", 2, "", 0)
+CHAR("fl", 2, "fl", 2, "", 0)
+CHAR("fo", 2, "<", 1, "", 0)
+CHAR("ga", 2, "`", 1, "", 0)
+CHAR("gr", 2, "V", 1, "", 0)
+CHAR("hA", 2, "<=>", 3, "", 0)
+CHAR("ho", 2, ",", 1, "", 0)
+CHAR("hy", 2, "-", 1, "", 0)
+CHAR("if", 2, "oo", 2, "", 0)
+CHAR("lA", 2, "<=", 2, "", 0)
+CHAR("lB", 2, "[", 1, "[", 1)
+CHAR("lC", 2, "{", 1, "", 0)
+CHAR("la", 2, "<", 1, "", 0)
+CHAR("lh", 2, "<=", 2, "", 0)
+CHAR("mo", 2, "E", 1, "", 0)
+CHAR("mu", 2, "x", 1, "", 0)
+CHAR("na", 2, "NaN", 3, "", 0)
+CHAR("nm", 2, "E", 1, "", 0)
+CHAR("no", 2, "~", 1, "", 0)
+CHAR("oA", 2, "A", 1, "", 0)
+CHAR("oa", 2, "a", 1, "", 0)
+CHAR("oe", 2, "oe", 2, "", 0)
+CHAR("oq", 2, "`", 1, "", 0)
+CHAR("pd", 2, "a", 1, "", 0)
+CHAR("pl", 2, "+", 1, "", 0)
+CHAR("ps", 2, "9|", 2, "", 0)
+CHAR("r!", 2, "i", 1, "", 0)
+CHAR("r?", 2, "c", 1, "", 0)
+CHAR("rA", 2, "=>", 2, "", 0)
+CHAR("rB", 2, "]", 1, "]", 1)
+CHAR("rC", 2, "}", 1, "", 0)
+CHAR("ra", 2, ">", 1, "", 0)
+CHAR("rg", 2, "(R)", 3, "", 0)
+CHAR("rh", 2, "=>", 2, "", 0)
+CHAR("sc", 2, "S", 1, "", 0)
+CHAR("ss", 2, "ss", 2, "", 0)
+CHAR("st", 2, "-)", 2, "", 0)
+CHAR("te", 2, "3", 1, "", 0)
+CHAR("tf", 2, ".:.", 3, "", 0)
+CHAR("tm", 2, "tm", 2, "", 0)
+CHAR("ts", 2, "s", 1, "", 0)
+CHAR("uA", 2, "^", 1, "", 0)
+CHAR("ua", 2, "^", 1, "", 0)
+CHAR("|", 1, "", 0, "", 0)
+CHAR("~", 1, " ", 1, "", 0)
+CHAR("~=", 2, "~=", 2, "", 0)
+CHAR("~A", 2, "A", 1, "", 0)
+CHAR("~N", 2, "N", 1, "", 0)
+CHAR("~O", 2, "O", 1, "", 0)
+CHAR("~a", 2, "a", 1, "", 0)
+CHAR("~n", 2, "n", 1, "", 0)
+CHAR("~o", 2, "o", 1, "", 0)
+CHAR("~~", 2, "~~", 2, "", 0)
diff --git a/html.c b/html.c
index 4be3d55d..b2ddc289 100644
--- a/html.c
+++ b/html.c
@@ -21,6 +21,7 @@
#include <stdio.h>
#include <stdlib.h>
+#include "chars.h"
#include "mdoc.h"
#include "man.h"
@@ -107,6 +108,7 @@ struct html {
#define HTML_NOSPACE (1 << 0)
#define HTML_NEWLINE (1 << 1)
struct tagq stack;
+ void *symtab;
};
#define MDOC_ARGS const struct mdoc_meta *m, \
@@ -134,8 +136,11 @@ static struct tag *print_otag(struct html *, enum htmltag,
static void print_tagq(struct html *, const struct tag *);
static void print_stagq(struct html *, const struct tag *);
static void print_ctag(struct html *, enum htmltag);
-static void print_encode(const char *);
+static void print_encode(struct html *, const char *);
+static void print_escape(struct html *, const char **);
static void print_text(struct html *, const char *);
+static void print_res(struct html *, const char *, int);
+static void print_spec(struct html *, const char *, int);
static int mdoc_root_pre(MDOC_ARGS);
static int mdoc_ar_pre(MDOC_ARGS);
@@ -273,7 +278,6 @@ static const struct htmlmdoc mdocs[MDOC_MAX] = {
{NULL, NULL}, /* sp */
};
-
void
html_mdoc(void *arg, const struct mdoc *m)
{
@@ -290,7 +294,6 @@ html_mdoc(void *arg, const struct mdoc *m)
printf("\n");
}
-
void
html_man(void *arg, const struct man *m)
{
@@ -307,7 +310,6 @@ html_man(void *arg, const struct man *m)
printf("\n");
}
-
void *
html_alloc(void)
{
@@ -317,10 +319,13 @@ html_alloc(void)
return(NULL);
SLIST_INIT(&h->stack);
+ if (NULL == (h->symtab = chars_init(CHARS_HTML))) {
+ free(h);
+ return(NULL);
+ }
return(h);
}
-
void
html_free(void *p)
{
@@ -337,7 +342,6 @@ html_free(void *p)
free(h);
}
-
static void
print_mdoc(MDOC_ARGS)
{
@@ -353,7 +357,6 @@ print_mdoc(MDOC_ARGS)
print_tagq(h, t);
}
-
static void
print_gen_head(struct html *h)
{
@@ -385,7 +388,6 @@ print_gen_head(struct html *h)
print_otag(h, TAG_LINK, 4, link);
}
-
/* ARGSUSED */
static void
print_mdoc_head(MDOC_ARGS)
@@ -393,10 +395,9 @@ print_mdoc_head(MDOC_ARGS)
print_gen_head(h);
print_otag(h, TAG_TITLE, 0, NULL);
- print_encode(m->title);
+ print_encode(h, m->title);
}
-
/* ARGSUSED */
static void
print_mdoc_title(MDOC_ARGS)
@@ -405,7 +406,6 @@ print_mdoc_title(MDOC_ARGS)
/* TODO */
}
-
static void
print_mdoc_node(MDOC_ARGS)
{
@@ -448,7 +448,6 @@ print_mdoc_node(MDOC_ARGS)
print_mdoc_node(m, n->next, h);
}
-
static void
print_man(MAN_ARGS)
{
@@ -463,7 +462,6 @@ print_man(MAN_ARGS)
print_tagq(h, t);
}
-
/* ARGSUSED */
static void
print_man_head(MAN_ARGS)
@@ -471,10 +469,9 @@ print_man_head(MAN_ARGS)
print_gen_head(h);
print_otag(h, TAG_TITLE, 0, NULL);
- print_encode(m->title);
+ print_encode(h, m->title);
}
-
/* ARGSUSED */
static void
print_man_body(MAN_ARGS)
@@ -483,12 +480,147 @@ print_man_body(MAN_ARGS)
/* TODO */
}
+static void
+print_spec(struct html *h, const char *p, int len)
+{
+ const char *rhs;
+ int i;
+ size_t sz;
+
+ rhs = chars_a2ascii(h->symtab, p, (size_t)len, &sz);
+
+ if (NULL == rhs)
+ return;
+ for (i = 0; i < (int)sz; i++)
+ putchar(rhs[i]);
+}
+
+static void
+print_res(struct html *h, const char *p, int len)
+{
+ const char *rhs;
+ int i;
+ size_t sz;
+
+ rhs = chars_a2res(h->symtab, p, (size_t)len, &sz);
+
+ if (NULL == rhs)
+ return;
+ for (i = 0; i < (int)sz; i++)
+ putchar(rhs[i]);
+}
+
+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(const char *p)
+print_encode(struct html *h, const char *p)
{
- printf("%s", p); /* XXX */
+ for (; *p; p++) {
+ if ('\\' != *p) {
+ putchar(*p);
+ continue;
+ }
+ print_escape(h, &p);
+ }
}
@@ -515,7 +647,7 @@ print_otag(struct html *h, enum htmltag tag,
for (i = 0; i < sz; i++) {
printf(" %s=\"", htmlattrs[p[i].key]);
assert(p->val);
- print_encode(p[i].val);
+ print_encode(h, p[i].val);
printf("\"");
}
printf(">");
@@ -590,7 +722,7 @@ print_text(struct html *h, const char *p)
h->flags &= ~HTML_NEWLINE;
if (p)
- print_encode(p);
+ print_encode(h, p);
if (*p && 0 == *(p + 1))
switch (*p) {