18ccd4a63SDavid du Colombier #include <u.h>
28ccd4a63SDavid du Colombier #include <libc.h>
38ccd4a63SDavid du Colombier #include <bio.h>
48ccd4a63SDavid du Colombier #include "hdr.h"
58ccd4a63SDavid du Colombier #include "conv.h"
68ccd4a63SDavid du Colombier
78ccd4a63SDavid du Colombier typedef struct Hchar Hchar;
88ccd4a63SDavid du Colombier struct Hchar
98ccd4a63SDavid du Colombier {
108ccd4a63SDavid du Colombier char *s;
118ccd4a63SDavid du Colombier Rune r;
128ccd4a63SDavid du Colombier };
138ccd4a63SDavid du Colombier
148ccd4a63SDavid du Colombier /* <, >, ", & intentionally omitted */
158ccd4a63SDavid du Colombier
16*2cba34c7SDavid du Colombier /*
17*2cba34c7SDavid du Colombier * Names beginning with _ are names we recognize
18*2cba34c7SDavid du Colombier * (without the underscore) but will not generate,
19*2cba34c7SDavid du Colombier * because they are nonstandard.
20*2cba34c7SDavid du Colombier */
218ccd4a63SDavid du Colombier static Hchar byname[] =
228ccd4a63SDavid du Colombier {
238ccd4a63SDavid du Colombier {"AElig", 198},
248ccd4a63SDavid du Colombier {"Aacute", 193},
258ccd4a63SDavid du Colombier {"Acirc", 194},
268ccd4a63SDavid du Colombier {"Agrave", 192},
274ac975e2SDavid du Colombier {"Alpha", 913},
288ccd4a63SDavid du Colombier {"Aring", 197},
298ccd4a63SDavid du Colombier {"Atilde", 195},
308ccd4a63SDavid du Colombier {"Auml", 196},
314ac975e2SDavid du Colombier {"Beta", 914},
328ccd4a63SDavid du Colombier {"Ccedil", 199},
334ac975e2SDavid du Colombier {"Chi", 935},
344ac975e2SDavid du Colombier {"Dagger", 8225},
354ac975e2SDavid du Colombier {"Delta", 916},
368ccd4a63SDavid du Colombier {"ETH", 208},
378ccd4a63SDavid du Colombier {"Eacute", 201},
388ccd4a63SDavid du Colombier {"Ecirc", 202},
398ccd4a63SDavid du Colombier {"Egrave", 200},
404ac975e2SDavid du Colombier {"Epsilon", 917},
414ac975e2SDavid du Colombier {"Eta", 919},
428ccd4a63SDavid du Colombier {"Euml", 203},
434ac975e2SDavid du Colombier {"Gamma", 915},
448ccd4a63SDavid du Colombier {"Iacute", 205},
458ccd4a63SDavid du Colombier {"Icirc", 206},
468ccd4a63SDavid du Colombier {"Igrave", 204},
474ac975e2SDavid du Colombier {"Iota", 921},
488ccd4a63SDavid du Colombier {"Iuml", 207},
494ac975e2SDavid du Colombier {"Kappa", 922},
504ac975e2SDavid du Colombier {"Lambda", 923},
514ac975e2SDavid du Colombier {"Mu", 924},
528ccd4a63SDavid du Colombier {"Ntilde", 209},
534ac975e2SDavid du Colombier {"Nu", 925},
544ac975e2SDavid du Colombier {"OElig", 338},
558ccd4a63SDavid du Colombier {"Oacute", 211},
568ccd4a63SDavid du Colombier {"Ocirc", 212},
578ccd4a63SDavid du Colombier {"Ograve", 210},
584ac975e2SDavid du Colombier {"Omega", 937},
594ac975e2SDavid du Colombier {"Omicron", 927},
608ccd4a63SDavid du Colombier {"Oslash", 216},
618ccd4a63SDavid du Colombier {"Otilde", 213},
628ccd4a63SDavid du Colombier {"Ouml", 214},
634ac975e2SDavid du Colombier {"Phi", 934},
644ac975e2SDavid du Colombier {"Pi", 928},
654ac975e2SDavid du Colombier {"Prime", 8243},
664ac975e2SDavid du Colombier {"Psi", 936},
674ac975e2SDavid du Colombier {"Rho", 929},
684ac975e2SDavid du Colombier {"Scaron", 352},
694ac975e2SDavid du Colombier {"Sigma", 931},
708ccd4a63SDavid du Colombier {"THORN", 222},
714ac975e2SDavid du Colombier {"Tau", 932},
724ac975e2SDavid du Colombier {"Theta", 920},
738ccd4a63SDavid du Colombier {"Uacute", 218},
748ccd4a63SDavid du Colombier {"Ucirc", 219},
758ccd4a63SDavid du Colombier {"Ugrave", 217},
764ac975e2SDavid du Colombier {"Upsilon", 933},
778ccd4a63SDavid du Colombier {"Uuml", 220},
784ac975e2SDavid du Colombier {"Xi", 926},
798ccd4a63SDavid du Colombier {"Yacute", 221},
804ac975e2SDavid du Colombier {"Yuml", 376},
814ac975e2SDavid du Colombier {"Zeta", 918},
828ccd4a63SDavid du Colombier {"aacute", 225},
838ccd4a63SDavid du Colombier {"acirc", 226},
848ccd4a63SDavid du Colombier {"acute", 180},
858ccd4a63SDavid du Colombier {"aelig", 230},
868ccd4a63SDavid du Colombier {"agrave", 224},
874ac975e2SDavid du Colombier {"alefsym", 8501},
888ccd4a63SDavid du Colombier {"alpha", 945},
894ac975e2SDavid du Colombier {"amp", 38},
904ac975e2SDavid du Colombier {"and", 8743},
914ac975e2SDavid du Colombier {"ang", 8736},
928ccd4a63SDavid du Colombier {"aring", 229},
934ac975e2SDavid du Colombier {"asymp", 8776},
948ccd4a63SDavid du Colombier {"atilde", 227},
958ccd4a63SDavid du Colombier {"auml", 228},
964ac975e2SDavid du Colombier {"bdquo", 8222},
978ccd4a63SDavid du Colombier {"beta", 946},
988ccd4a63SDavid du Colombier {"brvbar", 166},
994ac975e2SDavid du Colombier {"bull", 8226},
1004ac975e2SDavid du Colombier {"cap", 8745},
1018ccd4a63SDavid du Colombier {"ccedil", 231},
1028ccd4a63SDavid du Colombier {"cdots", 8943},
1038ccd4a63SDavid du Colombier {"cedil", 184},
1048ccd4a63SDavid du Colombier {"cent", 162},
1058ccd4a63SDavid du Colombier {"chi", 967},
1064ac975e2SDavid du Colombier {"circ", 710},
1074ac975e2SDavid du Colombier {"clubs", 9827},
1084ac975e2SDavid du Colombier {"cong", 8773},
1098ccd4a63SDavid du Colombier {"copy", 169},
1104ac975e2SDavid du Colombier {"crarr", 8629},
1114ac975e2SDavid du Colombier {"cup", 8746},
1128ccd4a63SDavid du Colombier {"curren", 164},
1134ac975e2SDavid du Colombier {"dArr", 8659},
1144ac975e2SDavid du Colombier {"dagger", 8224},
1154ac975e2SDavid du Colombier {"darr", 8595},
1168ccd4a63SDavid du Colombier {"ddots", 8945},
1178ccd4a63SDavid du Colombier {"deg", 176},
1188ccd4a63SDavid du Colombier {"delta", 948},
1194ac975e2SDavid du Colombier {"diams", 9830},
1208ccd4a63SDavid du Colombier {"divide", 247},
1218ccd4a63SDavid du Colombier {"eacute", 233},
1228ccd4a63SDavid du Colombier {"ecirc", 234},
1238ccd4a63SDavid du Colombier {"egrave", 232},
124*2cba34c7SDavid du Colombier {"_emdash", 8212}, /* non-standard but commonly used */
1254ac975e2SDavid du Colombier {"empty", 8709},
1268ccd4a63SDavid du Colombier {"emsp", 8195},
127*2cba34c7SDavid du Colombier {"_endash", 8211}, /* non-standard but commonly used */
1288ccd4a63SDavid du Colombier {"ensp", 8194},
1298ccd4a63SDavid du Colombier {"epsilon", 949},
1304ac975e2SDavid du Colombier {"equiv", 8801},
1318ccd4a63SDavid du Colombier {"eta", 951},
1328ccd4a63SDavid du Colombier {"eth", 240},
1338ccd4a63SDavid du Colombier {"euml", 235},
1344ac975e2SDavid du Colombier {"euro", 8364},
1354ac975e2SDavid du Colombier {"exist", 8707},
1364ac975e2SDavid du Colombier {"fnof", 402},
1374ac975e2SDavid du Colombier {"forall", 8704},
1388ccd4a63SDavid du Colombier {"frac12", 189},
1398ccd4a63SDavid du Colombier {"frac14", 188},
1408ccd4a63SDavid du Colombier {"frac34", 190},
1414ac975e2SDavid du Colombier {"frasl", 8260},
1428ccd4a63SDavid du Colombier {"gamma", 947},
1434ac975e2SDavid du Colombier {"ge", 8805},
1444ac975e2SDavid du Colombier {"gt", 62},
1454ac975e2SDavid du Colombier {"hArr", 8660},
1464ac975e2SDavid du Colombier {"harr", 8596},
1474ac975e2SDavid du Colombier {"hearts", 9829},
1484ac975e2SDavid du Colombier {"hellip", 8230},
1498ccd4a63SDavid du Colombier {"iacute", 237},
1508ccd4a63SDavid du Colombier {"icirc", 238},
1518ccd4a63SDavid du Colombier {"iexcl", 161},
1528ccd4a63SDavid du Colombier {"igrave", 236},
1534ac975e2SDavid du Colombier {"image", 8465},
1544ac975e2SDavid du Colombier {"infin", 8734},
1554ac975e2SDavid du Colombier {"int", 8747},
1568ccd4a63SDavid du Colombier {"iota", 953},
1578ccd4a63SDavid du Colombier {"iquest", 191},
1584ac975e2SDavid du Colombier {"isin", 8712},
1598ccd4a63SDavid du Colombier {"iuml", 239},
1608ccd4a63SDavid du Colombier {"kappa", 954},
1614ac975e2SDavid du Colombier {"lArr", 8656},
1628ccd4a63SDavid du Colombier {"lambda", 955},
1634ac975e2SDavid du Colombier {"lang", 9001},
1648ccd4a63SDavid du Colombier {"laquo", 171},
1654ac975e2SDavid du Colombier {"larr", 8592},
1664ac975e2SDavid du Colombier {"lceil", 8968},
167*2cba34c7SDavid du Colombier {"_ldots", 8230},
1684ac975e2SDavid du Colombier {"ldquo", 8220},
1694ac975e2SDavid du Colombier {"le", 8804},
1704ac975e2SDavid du Colombier {"lfloor", 8970},
1714ac975e2SDavid du Colombier {"lowast", 8727},
1724ac975e2SDavid du Colombier {"loz", 9674},
1734ac975e2SDavid du Colombier {"lrm", 8206},
1744ac975e2SDavid du Colombier {"lsaquo", 8249},
1758ccd4a63SDavid du Colombier {"lsquo", 8216},
1764ac975e2SDavid du Colombier {"lt", 60},
1778ccd4a63SDavid du Colombier {"macr", 175},
1788ccd4a63SDavid du Colombier {"mdash", 8212},
1798ccd4a63SDavid du Colombier {"micro", 181},
1808ccd4a63SDavid du Colombier {"middot", 183},
1814ac975e2SDavid du Colombier {"minus", 8722},
1828ccd4a63SDavid du Colombier {"mu", 956},
1834ac975e2SDavid du Colombier {"nabla", 8711},
1848ccd4a63SDavid du Colombier {"nbsp", 160},
1858ccd4a63SDavid du Colombier {"ndash", 8211},
1864ac975e2SDavid du Colombier {"ne", 8800},
1874ac975e2SDavid du Colombier {"ni", 8715},
1888ccd4a63SDavid du Colombier {"not", 172},
1894ac975e2SDavid du Colombier {"notin", 8713},
1904ac975e2SDavid du Colombier {"nsub", 8836},
1918ccd4a63SDavid du Colombier {"ntilde", 241},
1928ccd4a63SDavid du Colombier {"nu", 957},
1938ccd4a63SDavid du Colombier {"oacute", 243},
1948ccd4a63SDavid du Colombier {"ocirc", 244},
1954ac975e2SDavid du Colombier {"oelig", 339},
1968ccd4a63SDavid du Colombier {"ograve", 242},
1974ac975e2SDavid du Colombier {"oline", 8254},
1988ccd4a63SDavid du Colombier {"omega", 969},
1998ccd4a63SDavid du Colombier {"omicron", 959},
2004ac975e2SDavid du Colombier {"oplus", 8853},
2014ac975e2SDavid du Colombier {"or", 8744},
2028ccd4a63SDavid du Colombier {"ordf", 170},
2038ccd4a63SDavid du Colombier {"ordm", 186},
2048ccd4a63SDavid du Colombier {"oslash", 248},
2058ccd4a63SDavid du Colombier {"otilde", 245},
2064ac975e2SDavid du Colombier {"otimes", 8855},
2078ccd4a63SDavid du Colombier {"ouml", 246},
2088ccd4a63SDavid du Colombier {"para", 182},
2094ac975e2SDavid du Colombier {"part", 8706},
2104ac975e2SDavid du Colombier {"permil", 8240},
2114ac975e2SDavid du Colombier {"perp", 8869},
2128ccd4a63SDavid du Colombier {"phi", 966},
2138ccd4a63SDavid du Colombier {"pi", 960},
2144ac975e2SDavid du Colombier {"piv", 982},
2158ccd4a63SDavid du Colombier {"plusmn", 177},
2168ccd4a63SDavid du Colombier {"pound", 163},
2174ac975e2SDavid du Colombier {"prime", 8242},
2184ac975e2SDavid du Colombier {"prod", 8719},
2194ac975e2SDavid du Colombier {"prop", 8733},
2208ccd4a63SDavid du Colombier {"psi", 968},
2218ccd4a63SDavid du Colombier {"quad", 8193},
2224ac975e2SDavid du Colombier {"quot", 34},
2234ac975e2SDavid du Colombier {"rArr", 8658},
2244ac975e2SDavid du Colombier {"radic", 8730},
2254ac975e2SDavid du Colombier {"rang", 9002},
2268ccd4a63SDavid du Colombier {"raquo", 187},
2274ac975e2SDavid du Colombier {"rarr", 8594},
2284ac975e2SDavid du Colombier {"rceil", 8969},
2298ccd4a63SDavid du Colombier {"rdquo", 8221},
2304ac975e2SDavid du Colombier {"real", 8476},
2318ccd4a63SDavid du Colombier {"reg", 174},
2324ac975e2SDavid du Colombier {"rfloor", 8971},
2338ccd4a63SDavid du Colombier {"rho", 961},
2344ac975e2SDavid du Colombier {"rlm", 8207},
2354ac975e2SDavid du Colombier {"rsaquo", 8250},
2368ccd4a63SDavid du Colombier {"rsquo", 8217},
2374ac975e2SDavid du Colombier {"sbquo", 8218},
2384ac975e2SDavid du Colombier {"scaron", 353},
2394ac975e2SDavid du Colombier {"sdot", 8901},
2408ccd4a63SDavid du Colombier {"sect", 167},
2418ccd4a63SDavid du Colombier {"shy", 173},
2428ccd4a63SDavid du Colombier {"sigma", 963},
2434ac975e2SDavid du Colombier {"sigmaf", 962},
2444ac975e2SDavid du Colombier {"sim", 8764},
245*2cba34c7SDavid du Colombier {"_sp", 8194},
2464ac975e2SDavid du Colombier {"spades", 9824},
2474ac975e2SDavid du Colombier {"sub", 8834},
2484ac975e2SDavid du Colombier {"sube", 8838},
2494ac975e2SDavid du Colombier {"sum", 8721},
2504ac975e2SDavid du Colombier {"sup", 8835},
2518ccd4a63SDavid du Colombier {"sup1", 185},
2528ccd4a63SDavid du Colombier {"sup2", 178},
2538ccd4a63SDavid du Colombier {"sup3", 179},
2544ac975e2SDavid du Colombier {"supe", 8839},
2558ccd4a63SDavid du Colombier {"szlig", 223},
2568ccd4a63SDavid du Colombier {"tau", 964},
2574ac975e2SDavid du Colombier {"there4", 8756},
2588ccd4a63SDavid du Colombier {"theta", 952},
2594ac975e2SDavid du Colombier {"thetasym", 977},
2608ccd4a63SDavid du Colombier {"thinsp", 8201},
2618ccd4a63SDavid du Colombier {"thorn", 254},
2624ac975e2SDavid du Colombier {"tilde", 732},
2638ccd4a63SDavid du Colombier {"times", 215},
2648ccd4a63SDavid du Colombier {"trade", 8482},
2654ac975e2SDavid du Colombier {"uArr", 8657},
2668ccd4a63SDavid du Colombier {"uacute", 250},
2674ac975e2SDavid du Colombier {"uarr", 8593},
2688ccd4a63SDavid du Colombier {"ucirc", 251},
2698ccd4a63SDavid du Colombier {"ugrave", 249},
2708ccd4a63SDavid du Colombier {"uml", 168},
2714ac975e2SDavid du Colombier {"upsih", 978},
2728ccd4a63SDavid du Colombier {"upsilon", 965},
2738ccd4a63SDavid du Colombier {"uuml", 252},
274*2cba34c7SDavid du Colombier {"_varepsilon", 8712},
2758ccd4a63SDavid du Colombier {"varphi", 981},
276*2cba34c7SDavid du Colombier {"_varpi", 982},
2778ccd4a63SDavid du Colombier {"varrho", 1009},
2788ccd4a63SDavid du Colombier {"vdots", 8942},
279*2cba34c7SDavid du Colombier {"_vsigma", 962},
280*2cba34c7SDavid du Colombier {"_vtheta", 977},
2814ac975e2SDavid du Colombier {"weierp", 8472},
2828ccd4a63SDavid du Colombier {"xi", 958},
2838ccd4a63SDavid du Colombier {"yacute", 253},
2848ccd4a63SDavid du Colombier {"yen", 165},
2858ccd4a63SDavid du Colombier {"yuml", 255},
2864ac975e2SDavid du Colombier {"zeta", 950},
2874ac975e2SDavid du Colombier {"zwj", 8205},
2884ac975e2SDavid du Colombier {"zwnj", 8204}
2898ccd4a63SDavid du Colombier };
2908ccd4a63SDavid du Colombier
2918ccd4a63SDavid du Colombier static Hchar byrune[nelem(byname)];
2928ccd4a63SDavid du Colombier
2938ccd4a63SDavid du Colombier static int
hnamecmp(const void * va,const void * vb)2948ccd4a63SDavid du Colombier hnamecmp(const void *va, const void *vb)
2958ccd4a63SDavid du Colombier {
2968ccd4a63SDavid du Colombier Hchar *a, *b;
2978ccd4a63SDavid du Colombier
2988ccd4a63SDavid du Colombier a = (Hchar*)va;
2998ccd4a63SDavid du Colombier b = (Hchar*)vb;
3008ccd4a63SDavid du Colombier return strcmp(a->s, b->s);
3018ccd4a63SDavid du Colombier }
3028ccd4a63SDavid du Colombier
3038ccd4a63SDavid du Colombier static int
hrunecmp(const void * va,const void * vb)3048ccd4a63SDavid du Colombier hrunecmp(const void *va, const void *vb)
3058ccd4a63SDavid du Colombier {
3068ccd4a63SDavid du Colombier Hchar *a, *b;
3078ccd4a63SDavid du Colombier
3088ccd4a63SDavid du Colombier a = (Hchar*)va;
3098ccd4a63SDavid du Colombier b = (Hchar*)vb;
3108ccd4a63SDavid du Colombier return a->r - b->r;
3118ccd4a63SDavid du Colombier }
3128ccd4a63SDavid du Colombier
3138ccd4a63SDavid du Colombier static void
html_init(void)3148ccd4a63SDavid du Colombier html_init(void)
3158ccd4a63SDavid du Colombier {
3168ccd4a63SDavid du Colombier static int init;
317*2cba34c7SDavid du Colombier int i;
3188ccd4a63SDavid du Colombier
3198ccd4a63SDavid du Colombier if(init)
3208ccd4a63SDavid du Colombier return;
3218ccd4a63SDavid du Colombier init = 1;
3228ccd4a63SDavid du Colombier memmove(byrune, byname, sizeof byrune);
323*2cba34c7SDavid du Colombier
324*2cba34c7SDavid du Colombier /* Eliminate names we aren't allowed to generate. */
325*2cba34c7SDavid du Colombier for(i=0; i<nelem(byrune); i++){
326*2cba34c7SDavid du Colombier if(byrune[i].s[0] == '_'){
327*2cba34c7SDavid du Colombier byrune[i].r = Runeerror;
328*2cba34c7SDavid du Colombier byname[i].s++;
329*2cba34c7SDavid du Colombier }
330*2cba34c7SDavid du Colombier }
331*2cba34c7SDavid du Colombier
3328ccd4a63SDavid du Colombier qsort(byname, nelem(byname), sizeof byname[0], hnamecmp);
3338ccd4a63SDavid du Colombier qsort(byrune, nelem(byrune), sizeof byrune[0], hrunecmp);
3348ccd4a63SDavid du Colombier }
3358ccd4a63SDavid du Colombier
3368ccd4a63SDavid du Colombier static Rune
findbyname(char * s)3378ccd4a63SDavid du Colombier findbyname(char *s)
3388ccd4a63SDavid du Colombier {
3398ccd4a63SDavid du Colombier Hchar *h;
3408ccd4a63SDavid du Colombier int n, m, x;
3418ccd4a63SDavid du Colombier
3428ccd4a63SDavid du Colombier h = byname;
3438ccd4a63SDavid du Colombier n = nelem(byname);
3448ccd4a63SDavid du Colombier while(n > 0){
3458ccd4a63SDavid du Colombier m = n/2;
3468ccd4a63SDavid du Colombier x = strcmp(h[m].s, s);
3478ccd4a63SDavid du Colombier if(x == 0)
3488ccd4a63SDavid du Colombier return h[m].r;
3498ccd4a63SDavid du Colombier if(x < 0){
3508ccd4a63SDavid du Colombier h += m+1;
3518ccd4a63SDavid du Colombier n -= m+1;
3528ccd4a63SDavid du Colombier }else
3538ccd4a63SDavid du Colombier n = m;
3548ccd4a63SDavid du Colombier }
3558ccd4a63SDavid du Colombier return Runeerror;
3568ccd4a63SDavid du Colombier }
3578ccd4a63SDavid du Colombier
3588ccd4a63SDavid du Colombier static char*
findbyrune(Rune r)3598ccd4a63SDavid du Colombier findbyrune(Rune r)
3608ccd4a63SDavid du Colombier {
3618ccd4a63SDavid du Colombier Hchar *h;
3628ccd4a63SDavid du Colombier int n, m;
3638ccd4a63SDavid du Colombier
364*2cba34c7SDavid du Colombier if(r == Runeerror)
365*2cba34c7SDavid du Colombier return nil;
3668ccd4a63SDavid du Colombier h = byrune;
3678ccd4a63SDavid du Colombier n = nelem(byrune);
3688ccd4a63SDavid du Colombier while(n > 0){
3698ccd4a63SDavid du Colombier m = n/2;
3708ccd4a63SDavid du Colombier if(h[m].r == r)
3718ccd4a63SDavid du Colombier return h[m].s;
3728ccd4a63SDavid du Colombier if(h[m].r < r){
3738ccd4a63SDavid du Colombier h += m+1;
3748ccd4a63SDavid du Colombier n -= m+1;
3758ccd4a63SDavid du Colombier }else
3768ccd4a63SDavid du Colombier n = m;
3778ccd4a63SDavid du Colombier }
3788ccd4a63SDavid du Colombier return nil;
3798ccd4a63SDavid du Colombier }
3808ccd4a63SDavid du Colombier
3818ccd4a63SDavid du Colombier void
html_in(int fd,long * x,struct convert * out)3828ccd4a63SDavid du Colombier html_in(int fd, long *x, struct convert *out)
3838ccd4a63SDavid du Colombier {
3848ccd4a63SDavid du Colombier char buf[100], *p;
3858ccd4a63SDavid du Colombier Biobuf b;
3868ccd4a63SDavid du Colombier Rune rbuf[N];
3878ccd4a63SDavid du Colombier Rune *r, *er;
3888ccd4a63SDavid du Colombier int c, i;
3898ccd4a63SDavid du Colombier
3908ccd4a63SDavid du Colombier USED(x);
3918ccd4a63SDavid du Colombier
3928ccd4a63SDavid du Colombier html_init();
3938ccd4a63SDavid du Colombier r = rbuf;
3948ccd4a63SDavid du Colombier er = rbuf+N;
3958ccd4a63SDavid du Colombier Binit(&b, fd, OREAD);
3968ccd4a63SDavid du Colombier while((c = Bgetrune(&b)) != Beof){
3978ccd4a63SDavid du Colombier if(r >= er){
3988ccd4a63SDavid du Colombier OUT(out, rbuf, r-rbuf);
3998ccd4a63SDavid du Colombier r = rbuf;
4008ccd4a63SDavid du Colombier }
4018ccd4a63SDavid du Colombier if(c == '&'){
4028ccd4a63SDavid du Colombier buf[0] = c;
4038ccd4a63SDavid du Colombier for(i=1; i<nelem(buf)-1;){
4048ccd4a63SDavid du Colombier c = Bgetc(&b);
4058ccd4a63SDavid du Colombier if(c == Beof)
4068ccd4a63SDavid du Colombier break;
4078ccd4a63SDavid du Colombier buf[i++] = c;
4088ccd4a63SDavid du Colombier if(strchr("; \t\r\n", c))
4098ccd4a63SDavid du Colombier break;
4108ccd4a63SDavid du Colombier }
4118ccd4a63SDavid du Colombier buf[i] = 0;
4128ccd4a63SDavid du Colombier if(buf[i-1] == ';'){
4138ccd4a63SDavid du Colombier buf[i-1] = 0;
4148ccd4a63SDavid du Colombier if((c = findbyname(buf+1)) != Runeerror){
4158ccd4a63SDavid du Colombier *r++ = c;
4168ccd4a63SDavid du Colombier continue;
4178ccd4a63SDavid du Colombier }
4188ccd4a63SDavid du Colombier buf[i-1] = ';';
4198ccd4a63SDavid du Colombier if(buf[1] == '#'){
4208ccd4a63SDavid du Colombier if(buf[2] == 'x')
4218ccd4a63SDavid du Colombier c = strtol(buf+3, &p, 16);
4228ccd4a63SDavid du Colombier else
4238ccd4a63SDavid du Colombier c = strtol(buf+2, &p, 10);
4248ccd4a63SDavid du Colombier if(*p != ';' || c >= NRUNE || c < 0)
4258ccd4a63SDavid du Colombier goto bad;
4268ccd4a63SDavid du Colombier *r++ = c;
4278ccd4a63SDavid du Colombier continue;
4288ccd4a63SDavid du Colombier }
4298ccd4a63SDavid du Colombier }
4308ccd4a63SDavid du Colombier bad:
4318ccd4a63SDavid du Colombier for(p=buf; p<buf+i; ){
4328ccd4a63SDavid du Colombier p += chartorune(r++, p);
4338ccd4a63SDavid du Colombier if(r >= er){
4348ccd4a63SDavid du Colombier OUT(out, rbuf, r-rbuf);
4358ccd4a63SDavid du Colombier r = rbuf;
4368ccd4a63SDavid du Colombier }
4378ccd4a63SDavid du Colombier }
4388ccd4a63SDavid du Colombier continue;
4398ccd4a63SDavid du Colombier }
4408ccd4a63SDavid du Colombier *r++ = c;
4418ccd4a63SDavid du Colombier }
4428ccd4a63SDavid du Colombier if(r > rbuf)
4438ccd4a63SDavid du Colombier OUT(out, rbuf, r-rbuf);
444ec46fab0SDavid du Colombier OUT(out, rbuf, 0);
4458ccd4a63SDavid du Colombier }
4468ccd4a63SDavid du Colombier
4478ccd4a63SDavid du Colombier /*
4488ccd4a63SDavid du Colombier * use biobuf because can use more than UTFmax bytes per rune
4498ccd4a63SDavid du Colombier */
4508ccd4a63SDavid du Colombier void
html_out(Rune * r,int n,long * x)4518ccd4a63SDavid du Colombier html_out(Rune *r, int n, long *x)
4528ccd4a63SDavid du Colombier {
4538ccd4a63SDavid du Colombier char *s;
4548ccd4a63SDavid du Colombier Biobuf b;
4558ccd4a63SDavid du Colombier Rune *er;
4568ccd4a63SDavid du Colombier
4571fa40b8eSDavid du Colombier USED(x);
4588ccd4a63SDavid du Colombier html_init();
4598ccd4a63SDavid du Colombier Binit(&b, 1, OWRITE);
4608ccd4a63SDavid du Colombier er = r+n;
4618ccd4a63SDavid du Colombier for(; r<er; r++){
4628ccd4a63SDavid du Colombier if(*r < Runeself)
4638ccd4a63SDavid du Colombier Bputrune(&b, *r);
4648ccd4a63SDavid du Colombier else if((s = findbyrune(*r)) != nil)
4658ccd4a63SDavid du Colombier Bprint(&b, "&%s;", s);
4668ccd4a63SDavid du Colombier else
467426d2b71SDavid du Colombier Bprint(&b, "&#%d;", *r);
4688ccd4a63SDavid du Colombier }
4698ccd4a63SDavid du Colombier Bflush(&b);
4708ccd4a63SDavid du Colombier }
4718ccd4a63SDavid du Colombier
472