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 168ccd4a63SDavid du Colombier static Hchar byname[] = 178ccd4a63SDavid du Colombier { 188ccd4a63SDavid du Colombier {"AElig", 198}, 198ccd4a63SDavid du Colombier {"Aacute", 193}, 208ccd4a63SDavid du Colombier {"Acirc", 194}, 218ccd4a63SDavid du Colombier {"Agrave", 192}, 22*4ac975e2SDavid du Colombier {"Alpha", 913}, 238ccd4a63SDavid du Colombier {"Aring", 197}, 248ccd4a63SDavid du Colombier {"Atilde", 195}, 258ccd4a63SDavid du Colombier {"Auml", 196}, 26*4ac975e2SDavid du Colombier {"Beta", 914}, 278ccd4a63SDavid du Colombier {"Ccedil", 199}, 28*4ac975e2SDavid du Colombier {"Chi", 935}, 29*4ac975e2SDavid du Colombier {"Dagger", 8225}, 30*4ac975e2SDavid du Colombier {"Delta", 916}, 318ccd4a63SDavid du Colombier {"ETH", 208}, 328ccd4a63SDavid du Colombier {"Eacute", 201}, 338ccd4a63SDavid du Colombier {"Ecirc", 202}, 348ccd4a63SDavid du Colombier {"Egrave", 200}, 35*4ac975e2SDavid du Colombier {"Epsilon", 917}, 36*4ac975e2SDavid du Colombier {"Eta", 919}, 378ccd4a63SDavid du Colombier {"Euml", 203}, 38*4ac975e2SDavid du Colombier {"Gamma", 915}, 398ccd4a63SDavid du Colombier {"Iacute", 205}, 408ccd4a63SDavid du Colombier {"Icirc", 206}, 418ccd4a63SDavid du Colombier {"Igrave", 204}, 42*4ac975e2SDavid du Colombier {"Iota", 921}, 438ccd4a63SDavid du Colombier {"Iuml", 207}, 44*4ac975e2SDavid du Colombier {"Kappa", 922}, 45*4ac975e2SDavid du Colombier {"Lambda", 923}, 46*4ac975e2SDavid du Colombier {"Mu", 924}, 478ccd4a63SDavid du Colombier {"Ntilde", 209}, 48*4ac975e2SDavid du Colombier {"Nu", 925}, 49*4ac975e2SDavid du Colombier {"OElig", 338}, 508ccd4a63SDavid du Colombier {"Oacute", 211}, 518ccd4a63SDavid du Colombier {"Ocirc", 212}, 528ccd4a63SDavid du Colombier {"Ograve", 210}, 53*4ac975e2SDavid du Colombier {"Omega", 937}, 54*4ac975e2SDavid du Colombier {"Omicron", 927}, 558ccd4a63SDavid du Colombier {"Oslash", 216}, 568ccd4a63SDavid du Colombier {"Otilde", 213}, 578ccd4a63SDavid du Colombier {"Ouml", 214}, 58*4ac975e2SDavid du Colombier {"Phi", 934}, 59*4ac975e2SDavid du Colombier {"Pi", 928}, 60*4ac975e2SDavid du Colombier {"Prime", 8243}, 61*4ac975e2SDavid du Colombier {"Psi", 936}, 62*4ac975e2SDavid du Colombier {"Rho", 929}, 63*4ac975e2SDavid du Colombier {"Scaron", 352}, 64*4ac975e2SDavid du Colombier {"Sigma", 931}, 658ccd4a63SDavid du Colombier {"THORN", 222}, 66*4ac975e2SDavid du Colombier {"Tau", 932}, 67*4ac975e2SDavid du Colombier {"Theta", 920}, 688ccd4a63SDavid du Colombier {"Uacute", 218}, 698ccd4a63SDavid du Colombier {"Ucirc", 219}, 708ccd4a63SDavid du Colombier {"Ugrave", 217}, 71*4ac975e2SDavid du Colombier {"Upsilon", 933}, 728ccd4a63SDavid du Colombier {"Uuml", 220}, 73*4ac975e2SDavid du Colombier {"Xi", 926}, 748ccd4a63SDavid du Colombier {"Yacute", 221}, 75*4ac975e2SDavid du Colombier {"Yuml", 376}, 76*4ac975e2SDavid du Colombier {"Zeta", 918}, 778ccd4a63SDavid du Colombier {"aacute", 225}, 788ccd4a63SDavid du Colombier {"acirc", 226}, 798ccd4a63SDavid du Colombier {"acute", 180}, 808ccd4a63SDavid du Colombier {"aelig", 230}, 818ccd4a63SDavid du Colombier {"agrave", 224}, 82*4ac975e2SDavid du Colombier {"alefsym", 8501}, 838ccd4a63SDavid du Colombier {"alpha", 945}, 84*4ac975e2SDavid du Colombier {"amp", 38}, 85*4ac975e2SDavid du Colombier {"and", 8743}, 86*4ac975e2SDavid du Colombier {"ang", 8736}, 878ccd4a63SDavid du Colombier {"aring", 229}, 88*4ac975e2SDavid du Colombier {"asymp", 8776}, 898ccd4a63SDavid du Colombier {"atilde", 227}, 908ccd4a63SDavid du Colombier {"auml", 228}, 91*4ac975e2SDavid du Colombier {"bdquo", 8222}, 928ccd4a63SDavid du Colombier {"beta", 946}, 938ccd4a63SDavid du Colombier {"brvbar", 166}, 94*4ac975e2SDavid du Colombier {"bull", 8226}, 95*4ac975e2SDavid du Colombier {"cap", 8745}, 968ccd4a63SDavid du Colombier {"ccedil", 231}, 978ccd4a63SDavid du Colombier {"cdots", 8943}, 988ccd4a63SDavid du Colombier {"cedil", 184}, 998ccd4a63SDavid du Colombier {"cent", 162}, 1008ccd4a63SDavid du Colombier {"chi", 967}, 101*4ac975e2SDavid du Colombier {"circ", 710}, 102*4ac975e2SDavid du Colombier {"clubs", 9827}, 103*4ac975e2SDavid du Colombier {"cong", 8773}, 1048ccd4a63SDavid du Colombier {"copy", 169}, 105*4ac975e2SDavid du Colombier {"crarr", 8629}, 106*4ac975e2SDavid du Colombier {"cup", 8746}, 1078ccd4a63SDavid du Colombier {"curren", 164}, 108*4ac975e2SDavid du Colombier {"dArr", 8659}, 109*4ac975e2SDavid du Colombier {"dagger", 8224}, 110*4ac975e2SDavid du Colombier {"darr", 8595}, 1118ccd4a63SDavid du Colombier {"ddots", 8945}, 1128ccd4a63SDavid du Colombier {"deg", 176}, 1138ccd4a63SDavid du Colombier {"delta", 948}, 114*4ac975e2SDavid du Colombier {"diams", 9830}, 1158ccd4a63SDavid du Colombier {"divide", 247}, 1168ccd4a63SDavid du Colombier {"eacute", 233}, 1178ccd4a63SDavid du Colombier {"ecirc", 234}, 1188ccd4a63SDavid du Colombier {"egrave", 232}, 1198ccd4a63SDavid du Colombier {"emdash", 8212}, /* non-standard but commonly used */ 120*4ac975e2SDavid du Colombier {"empty", 8709}, 1218ccd4a63SDavid du Colombier {"emsp", 8195}, 1228ccd4a63SDavid du Colombier {"endash", 8211}, /* non-standard but commonly used */ 1238ccd4a63SDavid du Colombier {"ensp", 8194}, 1248ccd4a63SDavid du Colombier {"epsilon", 949}, 125*4ac975e2SDavid du Colombier {"equiv", 8801}, 1268ccd4a63SDavid du Colombier {"eta", 951}, 1278ccd4a63SDavid du Colombier {"eth", 240}, 1288ccd4a63SDavid du Colombier {"euml", 235}, 129*4ac975e2SDavid du Colombier {"euro", 8364}, 130*4ac975e2SDavid du Colombier {"exist", 8707}, 131*4ac975e2SDavid du Colombier {"fnof", 402}, 132*4ac975e2SDavid du Colombier {"forall", 8704}, 1338ccd4a63SDavid du Colombier {"frac12", 189}, 1348ccd4a63SDavid du Colombier {"frac14", 188}, 1358ccd4a63SDavid du Colombier {"frac34", 190}, 136*4ac975e2SDavid du Colombier {"frasl", 8260}, 1378ccd4a63SDavid du Colombier {"gamma", 947}, 138*4ac975e2SDavid du Colombier {"ge", 8805}, 139*4ac975e2SDavid du Colombier {"gt", 62}, 140*4ac975e2SDavid du Colombier {"hArr", 8660}, 141*4ac975e2SDavid du Colombier {"harr", 8596}, 142*4ac975e2SDavid du Colombier {"hearts", 9829}, 143*4ac975e2SDavid du Colombier {"hellip", 8230}, 1448ccd4a63SDavid du Colombier {"iacute", 237}, 1458ccd4a63SDavid du Colombier {"icirc", 238}, 1468ccd4a63SDavid du Colombier {"iexcl", 161}, 1478ccd4a63SDavid du Colombier {"igrave", 236}, 148*4ac975e2SDavid du Colombier {"image", 8465}, 149*4ac975e2SDavid du Colombier {"infin", 8734}, 150*4ac975e2SDavid du Colombier {"int", 8747}, 1518ccd4a63SDavid du Colombier {"iota", 953}, 1528ccd4a63SDavid du Colombier {"iquest", 191}, 153*4ac975e2SDavid du Colombier {"isin", 8712}, 1548ccd4a63SDavid du Colombier {"iuml", 239}, 1558ccd4a63SDavid du Colombier {"kappa", 954}, 156*4ac975e2SDavid du Colombier {"lArr", 8656}, 1578ccd4a63SDavid du Colombier {"lambda", 955}, 158*4ac975e2SDavid du Colombier {"lang", 9001}, 1598ccd4a63SDavid du Colombier {"laquo", 171}, 160*4ac975e2SDavid du Colombier {"larr", 8592}, 161*4ac975e2SDavid du Colombier {"lceil", 8968}, 1628ccd4a63SDavid du Colombier {"ldots", 8230}, 163*4ac975e2SDavid du Colombier {"ldquo", 8220}, 164*4ac975e2SDavid du Colombier {"le", 8804}, 165*4ac975e2SDavid du Colombier {"lfloor", 8970}, 166*4ac975e2SDavid du Colombier {"lowast", 8727}, 167*4ac975e2SDavid du Colombier {"loz", 9674}, 168*4ac975e2SDavid du Colombier {"lrm", 8206}, 169*4ac975e2SDavid du Colombier {"lsaquo", 8249}, 1708ccd4a63SDavid du Colombier {"lsquo", 8216}, 171*4ac975e2SDavid du Colombier {"lt", 60}, 1728ccd4a63SDavid du Colombier {"macr", 175}, 1738ccd4a63SDavid du Colombier {"mdash", 8212}, 1748ccd4a63SDavid du Colombier {"micro", 181}, 1758ccd4a63SDavid du Colombier {"middot", 183}, 176*4ac975e2SDavid du Colombier {"minus", 8722}, 1778ccd4a63SDavid du Colombier {"mu", 956}, 178*4ac975e2SDavid du Colombier {"nabla", 8711}, 1798ccd4a63SDavid du Colombier {"nbsp", 160}, 1808ccd4a63SDavid du Colombier {"ndash", 8211}, 181*4ac975e2SDavid du Colombier {"ne", 8800}, 182*4ac975e2SDavid du Colombier {"ni", 8715}, 1838ccd4a63SDavid du Colombier {"not", 172}, 184*4ac975e2SDavid du Colombier {"notin", 8713}, 185*4ac975e2SDavid du Colombier {"nsub", 8836}, 1868ccd4a63SDavid du Colombier {"ntilde", 241}, 1878ccd4a63SDavid du Colombier {"nu", 957}, 1888ccd4a63SDavid du Colombier {"oacute", 243}, 1898ccd4a63SDavid du Colombier {"ocirc", 244}, 190*4ac975e2SDavid du Colombier {"oelig", 339}, 1918ccd4a63SDavid du Colombier {"ograve", 242}, 192*4ac975e2SDavid du Colombier {"oline", 8254}, 1938ccd4a63SDavid du Colombier {"omega", 969}, 1948ccd4a63SDavid du Colombier {"omicron", 959}, 195*4ac975e2SDavid du Colombier {"oplus", 8853}, 196*4ac975e2SDavid du Colombier {"or", 8744}, 1978ccd4a63SDavid du Colombier {"ordf", 170}, 1988ccd4a63SDavid du Colombier {"ordm", 186}, 1998ccd4a63SDavid du Colombier {"oslash", 248}, 2008ccd4a63SDavid du Colombier {"otilde", 245}, 201*4ac975e2SDavid du Colombier {"otimes", 8855}, 2028ccd4a63SDavid du Colombier {"ouml", 246}, 2038ccd4a63SDavid du Colombier {"para", 182}, 204*4ac975e2SDavid du Colombier {"part", 8706}, 205*4ac975e2SDavid du Colombier {"permil", 8240}, 206*4ac975e2SDavid du Colombier {"perp", 8869}, 2078ccd4a63SDavid du Colombier {"phi", 966}, 2088ccd4a63SDavid du Colombier {"pi", 960}, 209*4ac975e2SDavid du Colombier {"piv", 982}, 2108ccd4a63SDavid du Colombier {"plusmn", 177}, 2118ccd4a63SDavid du Colombier {"pound", 163}, 212*4ac975e2SDavid du Colombier {"prime", 8242}, 213*4ac975e2SDavid du Colombier {"prod", 8719}, 214*4ac975e2SDavid du Colombier {"prop", 8733}, 2158ccd4a63SDavid du Colombier {"psi", 968}, 2168ccd4a63SDavid du Colombier {"quad", 8193}, 217*4ac975e2SDavid du Colombier {"quot", 34}, 218*4ac975e2SDavid du Colombier {"rArr", 8658}, 219*4ac975e2SDavid du Colombier {"radic", 8730}, 220*4ac975e2SDavid du Colombier {"rang", 9002}, 2218ccd4a63SDavid du Colombier {"raquo", 187}, 222*4ac975e2SDavid du Colombier {"rarr", 8594}, 223*4ac975e2SDavid du Colombier {"rceil", 8969}, 2248ccd4a63SDavid du Colombier {"rdquo", 8221}, 225*4ac975e2SDavid du Colombier {"real", 8476}, 2268ccd4a63SDavid du Colombier {"reg", 174}, 227*4ac975e2SDavid du Colombier {"rfloor", 8971}, 2288ccd4a63SDavid du Colombier {"rho", 961}, 229*4ac975e2SDavid du Colombier {"rlm", 8207}, 230*4ac975e2SDavid du Colombier {"rsaquo", 8250}, 2318ccd4a63SDavid du Colombier {"rsquo", 8217}, 232*4ac975e2SDavid du Colombier {"sbquo", 8218}, 233*4ac975e2SDavid du Colombier {"scaron", 353}, 234*4ac975e2SDavid du Colombier {"sdot", 8901}, 2358ccd4a63SDavid du Colombier {"sect", 167}, 2368ccd4a63SDavid du Colombier {"shy", 173}, 2378ccd4a63SDavid du Colombier {"sigma", 963}, 238*4ac975e2SDavid du Colombier {"sigmaf", 962}, 239*4ac975e2SDavid du Colombier {"sim", 8764}, 2408ccd4a63SDavid du Colombier {"sp", 8194}, 241*4ac975e2SDavid du Colombier {"spades", 9824}, 242*4ac975e2SDavid du Colombier {"sub", 8834}, 243*4ac975e2SDavid du Colombier {"sube", 8838}, 244*4ac975e2SDavid du Colombier {"sum", 8721}, 245*4ac975e2SDavid du Colombier {"sup", 8835}, 2468ccd4a63SDavid du Colombier {"sup1", 185}, 2478ccd4a63SDavid du Colombier {"sup2", 178}, 2488ccd4a63SDavid du Colombier {"sup3", 179}, 249*4ac975e2SDavid du Colombier {"supe", 8839}, 2508ccd4a63SDavid du Colombier {"szlig", 223}, 2518ccd4a63SDavid du Colombier {"tau", 964}, 252*4ac975e2SDavid du Colombier {"there4", 8756}, 2538ccd4a63SDavid du Colombier {"theta", 952}, 254*4ac975e2SDavid du Colombier {"thetasym", 977}, 2558ccd4a63SDavid du Colombier {"thinsp", 8201}, 2568ccd4a63SDavid du Colombier {"thorn", 254}, 257*4ac975e2SDavid du Colombier {"tilde", 732}, 2588ccd4a63SDavid du Colombier {"times", 215}, 2598ccd4a63SDavid du Colombier {"trade", 8482}, 260*4ac975e2SDavid du Colombier {"uArr", 8657}, 2618ccd4a63SDavid du Colombier {"uacute", 250}, 262*4ac975e2SDavid du Colombier {"uarr", 8593}, 2638ccd4a63SDavid du Colombier {"ucirc", 251}, 2648ccd4a63SDavid du Colombier {"ugrave", 249}, 2658ccd4a63SDavid du Colombier {"uml", 168}, 266*4ac975e2SDavid du Colombier {"upsih", 978}, 2678ccd4a63SDavid du Colombier {"upsilon", 965}, 2688ccd4a63SDavid du Colombier {"uuml", 252}, 2698ccd4a63SDavid du Colombier {"varepsilon", 8712}, 2708ccd4a63SDavid du Colombier {"varphi", 981}, 2718ccd4a63SDavid du Colombier {"varpi", 982}, 2728ccd4a63SDavid du Colombier {"varrho", 1009}, 2738ccd4a63SDavid du Colombier {"vdots", 8942}, 2748ccd4a63SDavid du Colombier {"vsigma", 962}, 2758ccd4a63SDavid du Colombier {"vtheta", 977}, 276*4ac975e2SDavid du Colombier {"weierp", 8472}, 2778ccd4a63SDavid du Colombier {"xi", 958}, 2788ccd4a63SDavid du Colombier {"yacute", 253}, 2798ccd4a63SDavid du Colombier {"yen", 165}, 2808ccd4a63SDavid du Colombier {"yuml", 255}, 281*4ac975e2SDavid du Colombier {"zeta", 950}, 282*4ac975e2SDavid du Colombier {"zwj", 8205}, 283*4ac975e2SDavid du Colombier {"zwnj", 8204} 2848ccd4a63SDavid du Colombier }; 2858ccd4a63SDavid du Colombier 2868ccd4a63SDavid du Colombier static Hchar byrune[nelem(byname)]; 2878ccd4a63SDavid du Colombier 2888ccd4a63SDavid du Colombier static int 2898ccd4a63SDavid du Colombier hnamecmp(const void *va, const void *vb) 2908ccd4a63SDavid du Colombier { 2918ccd4a63SDavid du Colombier Hchar *a, *b; 2928ccd4a63SDavid du Colombier 2938ccd4a63SDavid du Colombier a = (Hchar*)va; 2948ccd4a63SDavid du Colombier b = (Hchar*)vb; 2958ccd4a63SDavid du Colombier return strcmp(a->s, b->s); 2968ccd4a63SDavid du Colombier } 2978ccd4a63SDavid du Colombier 2988ccd4a63SDavid du Colombier static int 2998ccd4a63SDavid du Colombier hrunecmp(const void *va, const void *vb) 3008ccd4a63SDavid du Colombier { 3018ccd4a63SDavid du Colombier Hchar *a, *b; 3028ccd4a63SDavid du Colombier 3038ccd4a63SDavid du Colombier a = (Hchar*)va; 3048ccd4a63SDavid du Colombier b = (Hchar*)vb; 3058ccd4a63SDavid du Colombier return a->r - b->r; 3068ccd4a63SDavid du Colombier } 3078ccd4a63SDavid du Colombier 3088ccd4a63SDavid du Colombier static void 3098ccd4a63SDavid du Colombier html_init(void) 3108ccd4a63SDavid du Colombier { 3118ccd4a63SDavid du Colombier static int init; 3128ccd4a63SDavid du Colombier 3138ccd4a63SDavid du Colombier if(init) 3148ccd4a63SDavid du Colombier return; 3158ccd4a63SDavid du Colombier init = 1; 3168ccd4a63SDavid du Colombier memmove(byrune, byname, sizeof byrune); 3178ccd4a63SDavid du Colombier qsort(byname, nelem(byname), sizeof byname[0], hnamecmp); 3188ccd4a63SDavid du Colombier qsort(byrune, nelem(byrune), sizeof byrune[0], hrunecmp); 3198ccd4a63SDavid du Colombier } 3208ccd4a63SDavid du Colombier 3218ccd4a63SDavid du Colombier static Rune 3228ccd4a63SDavid du Colombier findbyname(char *s) 3238ccd4a63SDavid du Colombier { 3248ccd4a63SDavid du Colombier Hchar *h; 3258ccd4a63SDavid du Colombier int n, m, x; 3268ccd4a63SDavid du Colombier 3278ccd4a63SDavid du Colombier h = byname; 3288ccd4a63SDavid du Colombier n = nelem(byname); 3298ccd4a63SDavid du Colombier while(n > 0){ 3308ccd4a63SDavid du Colombier m = n/2; 3318ccd4a63SDavid du Colombier x = strcmp(h[m].s, s); 3328ccd4a63SDavid du Colombier if(x == 0) 3338ccd4a63SDavid du Colombier return h[m].r; 3348ccd4a63SDavid du Colombier if(x < 0){ 3358ccd4a63SDavid du Colombier h += m+1; 3368ccd4a63SDavid du Colombier n -= m+1; 3378ccd4a63SDavid du Colombier }else 3388ccd4a63SDavid du Colombier n = m; 3398ccd4a63SDavid du Colombier } 3408ccd4a63SDavid du Colombier return Runeerror; 3418ccd4a63SDavid du Colombier } 3428ccd4a63SDavid du Colombier 3438ccd4a63SDavid du Colombier static char* 3448ccd4a63SDavid du Colombier findbyrune(Rune r) 3458ccd4a63SDavid du Colombier { 3468ccd4a63SDavid du Colombier Hchar *h; 3478ccd4a63SDavid du Colombier int n, m; 3488ccd4a63SDavid du Colombier 3498ccd4a63SDavid du Colombier h = byrune; 3508ccd4a63SDavid du Colombier n = nelem(byrune); 3518ccd4a63SDavid du Colombier while(n > 0){ 3528ccd4a63SDavid du Colombier m = n/2; 3538ccd4a63SDavid du Colombier if(h[m].r == r) 3548ccd4a63SDavid du Colombier return h[m].s; 3558ccd4a63SDavid du Colombier if(h[m].r < r){ 3568ccd4a63SDavid du Colombier h += m+1; 3578ccd4a63SDavid du Colombier n -= m+1; 3588ccd4a63SDavid du Colombier }else 3598ccd4a63SDavid du Colombier n = m; 3608ccd4a63SDavid du Colombier } 3618ccd4a63SDavid du Colombier return nil; 3628ccd4a63SDavid du Colombier } 3638ccd4a63SDavid du Colombier 3648ccd4a63SDavid du Colombier void 3658ccd4a63SDavid du Colombier html_in(int fd, long *x, struct convert *out) 3668ccd4a63SDavid du Colombier { 3678ccd4a63SDavid du Colombier char buf[100], *p; 3688ccd4a63SDavid du Colombier Biobuf b; 3698ccd4a63SDavid du Colombier Rune rbuf[N]; 3708ccd4a63SDavid du Colombier Rune *r, *er; 3718ccd4a63SDavid du Colombier int c, i; 3728ccd4a63SDavid du Colombier 3738ccd4a63SDavid du Colombier USED(x); 3748ccd4a63SDavid du Colombier 3758ccd4a63SDavid du Colombier html_init(); 3768ccd4a63SDavid du Colombier r = rbuf; 3778ccd4a63SDavid du Colombier er = rbuf+N; 3788ccd4a63SDavid du Colombier Binit(&b, fd, OREAD); 3798ccd4a63SDavid du Colombier while((c = Bgetrune(&b)) != Beof){ 3808ccd4a63SDavid du Colombier if(r >= er){ 3818ccd4a63SDavid du Colombier OUT(out, rbuf, r-rbuf); 3828ccd4a63SDavid du Colombier r = rbuf; 3838ccd4a63SDavid du Colombier } 3848ccd4a63SDavid du Colombier if(c == '&'){ 3858ccd4a63SDavid du Colombier buf[0] = c; 3868ccd4a63SDavid du Colombier for(i=1; i<nelem(buf)-1;){ 3878ccd4a63SDavid du Colombier c = Bgetc(&b); 3888ccd4a63SDavid du Colombier if(c == Beof) 3898ccd4a63SDavid du Colombier break; 3908ccd4a63SDavid du Colombier buf[i++] = c; 3918ccd4a63SDavid du Colombier if(strchr("; \t\r\n", c)) 3928ccd4a63SDavid du Colombier break; 3938ccd4a63SDavid du Colombier } 3948ccd4a63SDavid du Colombier buf[i] = 0; 3958ccd4a63SDavid du Colombier if(buf[i-1] == ';'){ 3968ccd4a63SDavid du Colombier buf[i-1] = 0; 3978ccd4a63SDavid du Colombier if((c = findbyname(buf+1)) != Runeerror){ 3988ccd4a63SDavid du Colombier *r++ = c; 3998ccd4a63SDavid du Colombier continue; 4008ccd4a63SDavid du Colombier } 4018ccd4a63SDavid du Colombier buf[i-1] = ';'; 4028ccd4a63SDavid du Colombier if(buf[1] == '#'){ 4038ccd4a63SDavid du Colombier if(buf[2] == 'x') 4048ccd4a63SDavid du Colombier c = strtol(buf+3, &p, 16); 4058ccd4a63SDavid du Colombier else 4068ccd4a63SDavid du Colombier c = strtol(buf+2, &p, 10); 4078ccd4a63SDavid du Colombier if(*p != ';' || c >= NRUNE || c < 0) 4088ccd4a63SDavid du Colombier goto bad; 4098ccd4a63SDavid du Colombier *r++ = c; 4108ccd4a63SDavid du Colombier continue; 4118ccd4a63SDavid du Colombier } 4128ccd4a63SDavid du Colombier } 4138ccd4a63SDavid du Colombier bad: 4148ccd4a63SDavid du Colombier for(p=buf; p<buf+i; ){ 4158ccd4a63SDavid du Colombier p += chartorune(r++, p); 4168ccd4a63SDavid du Colombier if(r >= er){ 4178ccd4a63SDavid du Colombier OUT(out, rbuf, r-rbuf); 4188ccd4a63SDavid du Colombier r = rbuf; 4198ccd4a63SDavid du Colombier } 4208ccd4a63SDavid du Colombier } 4218ccd4a63SDavid du Colombier continue; 4228ccd4a63SDavid du Colombier } 4238ccd4a63SDavid du Colombier *r++ = c; 4248ccd4a63SDavid du Colombier } 4258ccd4a63SDavid du Colombier if(r > rbuf) 4268ccd4a63SDavid du Colombier OUT(out, rbuf, r-rbuf); 4278ccd4a63SDavid du Colombier } 4288ccd4a63SDavid du Colombier 4298ccd4a63SDavid du Colombier /* 4308ccd4a63SDavid du Colombier * use biobuf because can use more than UTFmax bytes per rune 4318ccd4a63SDavid du Colombier */ 4328ccd4a63SDavid du Colombier void 4338ccd4a63SDavid du Colombier html_out(Rune *r, int n, long *x) 4348ccd4a63SDavid du Colombier { 4358ccd4a63SDavid du Colombier char *s; 4368ccd4a63SDavid du Colombier Biobuf b; 4378ccd4a63SDavid du Colombier Rune *er; 4388ccd4a63SDavid du Colombier 4391fa40b8eSDavid du Colombier USED(x); 4408ccd4a63SDavid du Colombier html_init(); 4418ccd4a63SDavid du Colombier Binit(&b, 1, OWRITE); 4428ccd4a63SDavid du Colombier er = r+n; 4438ccd4a63SDavid du Colombier for(; r<er; r++){ 4448ccd4a63SDavid du Colombier if(*r < Runeself) 4458ccd4a63SDavid du Colombier Bputrune(&b, *r); 4468ccd4a63SDavid du Colombier else if((s = findbyrune(*r)) != nil) 4478ccd4a63SDavid du Colombier Bprint(&b, "&%s;", s); 4488ccd4a63SDavid du Colombier else 449426d2b71SDavid du Colombier Bprint(&b, "&#%d;", *r); 4508ccd4a63SDavid du Colombier } 4518ccd4a63SDavid du Colombier Bflush(&b); 4528ccd4a63SDavid du Colombier } 4538ccd4a63SDavid du Colombier 454