diff options
-rw-r--r-- | chars.c | 59 | ||||
-rw-r--r-- | chars.in | 532 | ||||
-rw-r--r-- | html.c | 170 |
3 files changed, 448 insertions, 313 deletions
@@ -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); @@ -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, "&", 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, "—", 7) +CHAR("en", 2, "-", 1, "–", 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) @@ -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) { |