📄 html.c
字号:
#include "links.h"struct list_head html_stack = {&html_stack, &html_stack};static inline int atchr(unsigned char c){ return /*isA(c) ||*/ (c > ' ' && c != '=' && c != '<' && c != '>');}int parse_element(unsigned char *e, unsigned char *eof, unsigned char **name, int *namelen, unsigned char **attr, unsigned char **end){ if (eof - e < 3 || *(e++) != '<') return -1; if (name) *name = e; if (*e == '/') e++; if (!isA(*e)) return -1; goto x1; while (isA(*e) || *e == '=') { x1: e++; if (e >= eof) return -1; } /*if ((!WHITECHAR(*e) && *e != '>' && *e != '<' && *e != '/' && *e != ':')) return -1;*/ if (name && namelen) *namelen = e - *name; while ((WHITECHAR(*e) || *e == '/' || *e == ':')) { e++; if (e >= eof) return -1; } if ((!atchr(*e) && *e != '>' && *e != '<')) return -1; if (attr) *attr = e; nextattr: while (WHITECHAR(*e)) { e++; if (e >= eof) return -1; } if ((!atchr(*e) && *e != '>' && *e != '<')) return -1; if (*e == '>' || *e == '<') goto en; while (atchr(*e)) { e++; if (e >= eof) return -1; } while (WHITECHAR(*e)) { e++; if (e >= eof) return -1; } if (*e != '=') goto endattr; goto x2; while (WHITECHAR(*e)) { x2: e++; if (e >= eof) return -1; } if (U(*e)) { unsigned char uu = *e; /*u:*/ goto x3; while (e < eof && *e != uu && *e /*(WHITECHAR(*e) || *e > ' ')*/) { x3: e++; if (e >= eof) return -1; } if (*e < ' ') return -1; e++; if (e >= eof /*|| (!WHITECHAR(*e) && *e != uu && *e != '>' && *e != '<')*/) return -1; /*if (*e == uu) goto u;*/ } else { while (!WHITECHAR(*e) && *e != '>' && *e != '<') { e++; if (e >= eof) return -1; } } while (WHITECHAR(*e)) { e++; if (e >= eof) return -1; } endattr: if (*e != '>' && *e != '<') goto nextattr; en: if (end) *end = e + (*e == '>'); return 0;}#define add_chr(s, l, c) \do { \ if (!((l) & (32 - 1))) { \ if ((unsigned)(l) > MAXINT - 32) overalloc(); \ (s) = mem_realloc((s), (l) + 32); \ } \ (s)[(l)++] = (c); \} while (0)int get_attr_val_nl = 0;/* parses html element attributes *//* e is attr pointer previously get from parse_element, DON'T PASS HERE ANY OTHER VALUE!!! *//* name is searched attribute *//* returns allocated string containing the attribute, or NULL on unsuccess */unsigned char *get_attr_val(unsigned char *e, unsigned char *name){ unsigned char *n; unsigned char *a = DUMMY; int l = 0; int f; aa: while (WHITECHAR(*e)) e++; if (*e == '>' || *e == '<') return NULL; n = name; while (*n && upcase(*e) == upcase(*n)) e++, n++; f = *n; while (atchr(*e)) f = 1, e++; while (WHITECHAR(*e)) e++; if (*e != '=') goto ea; e++; while (WHITECHAR(*e)) e++; if (!U(*e)) { while (!WHITECHAR(*e) && *e != '>' && *e != '<') { if (!f) add_chr(a, l, *e); e++; } } else { char uu = *e; /*a:*/ e++; while (*e != uu) { if (!*e) { mem_free(a); return NULL; } if (!f) { if (get_attr_val_nl == 2) goto exact; if (*e != 13) { if (*e != 9 && *e != 10) exact:add_chr(a, l, *e); else if (!get_attr_val_nl) add_chr(a, l, ' '); } } e++; } e++; /*if (*e == uu) { if (!f) add_chr(a, l, *e); goto a; }*/ } ea: if (!f) { unsigned char *b; add_chr(a, l, 0); if (strchr(a, '&')) { unsigned char *aa = a; int c = d_opt->cp; d_opt->cp = d_opt->real_cp; a = convert_string(NULL, aa, strlen(aa)); d_opt->cp = c; mem_free(aa); } while ((b = strchr(a, 1))) *b = ' '; if (get_attr_val_nl != 2) { for (b = a; *b == ' '; b++); if (b != a) memmove(a, b, strlen(b) + 1); for (b = a + strlen(a) - 1; b >= a && *b == ' '; b--) *b = 0; } set_mem_comment(a, name, strlen(name)); return a; } goto aa;}int has_attr(unsigned char *e, unsigned char *name){ char *a; if (!(a = get_attr_val(e, name))) return 0; mem_free(a); return 1;}/*unsigned char *get_url_val(unsigned char *e, unsigned char *name){ int n = 0; unsigned char *p, *q, *pp; if (!(pp = get_attr_val(e, name))) return NULL; p = pp; q = pp; while (1) { if (*p == '#') n = 1; if ((*p = *q) != ' ' || n) p++; if (!*q) break; q++; } return pp;}*/unsigned char *get_url_val(unsigned char *e, unsigned char *name){ unsigned char *a; get_attr_val_nl = 1; a = get_attr_val(e, name); get_attr_val_nl = 0; return a;}unsigned char *get_exact_attr_val(unsigned char *e, unsigned char *name){ unsigned char *a; get_attr_val_nl = 2; a = get_attr_val(e, name); get_attr_val_nl = 0; return a;}struct { unsigned short int n; char *s;} roman_tbl[] = { { 1000, "m" }, { 999, "im" },/* { 995, "vm" },*/ { 990, "xm" },/* { 950, "lm" },*/ { 900, "cm" }, { 500, "d" }, { 499, "id" },/* { 495, "vd" },*/ { 490, "xd" },/* { 450, "ld" },*/ { 400, "cd" }, { 100, "c" }, { 99, "ic" },/* { 95, "vc" },*/ { 90, "xc" }, { 50, "l" }, { 49, "il" },/* { 45, "vl" },*/ { 40, "xl" }, { 10, "x" }, { 9, "ix" }, { 5, "v" }, { 4, "iv" }, { 1, "i" }, { 0, NULL },};void roman(char *p, unsigned n){ int i = 0; if (n >= 4000) { strcpy(p, "---"); return; } if (!n) { strcpy(p, "o"); return; } p[0] = 0; while (n) { while (roman_tbl[i].n <= n) { n -= roman_tbl[i].n; strcat(p, roman_tbl[i].s); } i++; if (n && !roman_tbl[i].n) { internal("BUG in roman number convertor"); return; } }}struct color_spec { char *name; int rgb;};struct color_spec color_specs[] = { {"aliceblue", 0xF0F8FF}, {"antiquewhite", 0xFAEBD7}, {"aqua", 0x00FFFF}, {"aquamarine", 0x7FFFD4}, {"azure", 0xF0FFFF}, {"beige", 0xF5F5DC}, {"bisque", 0xFFE4C4}, {"black", 0x000000}, {"blanchedalmond", 0xFFEBCD}, {"blue", 0x0000FF}, {"blueviolet", 0x8A2BE2}, {"brown", 0xA52A2A}, {"burlywood", 0xDEB887}, {"cadetblue", 0x5F9EA0}, {"chartreuse", 0x7FFF00}, {"chocolate", 0xD2691E}, {"coral", 0xFF7F50}, {"cornflowerblue", 0x6495ED}, {"cornsilk", 0xFFF8DC}, {"crimson", 0xDC143C}, {"cyan", 0x00FFFF}, {"darkblue", 0x00008B}, {"darkcyan", 0x008B8B}, {"darkgoldenrod", 0xB8860B}, {"darkgray", 0xA9A9A9}, {"darkgreen", 0x006400}, {"darkkhaki", 0xBDB76B}, {"darkmagenta", 0x8B008B}, {"darkolivegreen", 0x556B2F}, {"darkorange", 0xFF8C00}, {"darkorchid", 0x9932CC}, {"darkred", 0x8B0000}, {"darksalmon", 0xE9967A}, {"darkseagreen", 0x8FBC8F}, {"darkslateblue", 0x483D8B}, {"darkslategray", 0x2F4F4F}, {"darkturquoise", 0x00CED1}, {"darkviolet", 0x9400D3}, {"deeppink", 0xFF1493}, {"deepskyblue", 0x00BFFF}, {"dimgray", 0x696969}, {"dodgerblue", 0x1E90FF}, {"firebrick", 0xB22222}, {"floralwhite", 0xFFFAF0}, {"forestgreen", 0x228B22}, {"fuchsia", 0xFF00FF}, {"gainsboro", 0xDCDCDC}, {"ghostwhite", 0xF8F8FF}, {"gold", 0xFFD700}, {"goldenrod", 0xDAA520}, {"gray", 0x808080}, {"green", 0x008000}, {"greenyellow", 0xADFF2F}, {"honeydew", 0xF0FFF0}, {"hotpink", 0xFF69B4}, {"indianred", 0xCD5C5C}, {"indigo", 0x4B0082}, {"ivory", 0xFFFFF0}, {"khaki", 0xF0E68C}, {"lavender", 0xE6E6FA}, {"lavenderblush", 0xFFF0F5}, {"lawngreen", 0x7CFC00}, {"lemonchiffon", 0xFFFACD}, {"lightblue", 0xADD8E6}, {"lightcoral", 0xF08080}, {"lightcyan", 0xE0FFFF}, {"lightgoldenrodyellow", 0xFAFAD2}, {"lightgreen", 0x90EE90}, {"lightgrey", 0xD3D3D3}, {"lightpink", 0xFFB6C1}, {"lightsalmon", 0xFFA07A}, {"lightseagreen", 0x20B2AA}, {"lightskyblue", 0x87CEFA}, {"lightslategray", 0x778899}, {"lightsteelblue", 0xB0C4DE}, {"lightyellow", 0xFFFFE0}, {"lime", 0x00FF00}, {"limegreen", 0x32CD32}, {"linen", 0xFAF0E6}, {"magenta", 0xFF00FF}, {"maroon", 0x800000}, {"mediumaquamarine", 0x66CDAA}, {"mediumblue", 0x0000CD}, {"mediumorchid", 0xBA55D3}, {"mediumpurple", 0x9370DB}, {"mediumseagreen", 0x3CB371}, {"mediumslateblue", 0x7B68EE}, {"mediumspringgreen", 0x00FA9A}, {"mediumturquoise", 0x48D1CC}, {"mediumvioletred", 0xC71585}, {"midnightblue", 0x191970}, {"mintcream", 0xF5FFFA}, {"mistyrose", 0xFFE4E1}, {"moccasin", 0xFFE4B5}, {"navajowhite", 0xFFDEAD}, {"navy", 0x000080}, {"oldlace", 0xFDF5E6}, {"olive", 0x808000}, {"olivedrab", 0x6B8E23}, {"orange", 0xFFA500}, {"orangered", 0xFF4500}, {"orchid", 0xDA70D6}, {"palegoldenrod", 0xEEE8AA}, {"palegreen", 0x98FB98}, {"paleturquoise", 0xAFEEEE}, {"palevioletred", 0xDB7093}, {"papayawhip", 0xFFEFD5}, {"peachpuff", 0xFFDAB9}, {"peru", 0xCD853F}, {"pink", 0xFFC0CB}, {"plum", 0xDDA0DD}, {"powderblue", 0xB0E0E6}, {"purple", 0x800080}, {"red", 0xFF0000}, {"rosybrown", 0xBC8F8F}, {"royalblue", 0x4169E1}, {"saddlebrown", 0x8B4513}, {"salmon", 0xFA8072}, {"sandybrown", 0xF4A460}, {"seagreen", 0x2E8B57}, {"seashell", 0xFFF5EE}, {"sienna", 0xA0522D}, {"silver", 0xC0C0C0}, {"skyblue", 0x87CEEB}, {"slateblue", 0x6A5ACD}, {"slategray", 0x708090}, {"snow", 0xFFFAFA}, {"springgreen", 0x00FF7F}, {"steelblue", 0x4682B4}, {"tan", 0xD2B48C}, {"teal", 0x008080}, {"thistle", 0xD8BFD8}, {"tomato", 0xFF6347}, {"turquoise", 0x40E0D0}, {"violet", 0xEE82EE}, {"wheat", 0xF5DEB3}, {"white", 0xFFFFFF}, {"whitesmoke", 0xF5F5F5}, {"yellow", 0xFFFF00}, {"yellowgreen", 0x9ACD32},};#define endof(T) ((T)+sizeof(T)/sizeof(*(T)))int decode_color(unsigned char *str, struct rgb *col){ unsigned long ch; if (*str != '#') { struct color_spec *cs; for (cs = color_specs; cs < endof(color_specs); cs++) if (!strcasecmp(cs->name, str)) { ch = cs->rgb; goto found; } str--; } str++; if (strlen(str) == 6) { char *end; ch = strtoul(str, &end, 16); if (!*end && ch < 0x1000000) {found: col->r = ch / 0x10000; col->g = ch / 0x100 % 0x100; col->b = ch % 0x100; return 0; } } return -1;}int get_color(unsigned char *a, unsigned char *c, struct rgb *rgb){ char *at; int r = -1; if (d_opt->col >= 1) if ((at = get_attr_val(a, c))) { r = decode_color(at, rgb); mem_free(at); } return r;}int get_bgcolor(unsigned char *a, struct rgb *rgb){ if (d_opt->col < 2) return -1; return get_color(a, "bgcolor", rgb);}unsigned char *get_target(unsigned char *a){ unsigned char *v = get_attr_val(a, "target"); if (v) { if (!strcasecmp(v, "_self")) { mem_free(v); v = stracpy(d_opt->framename); } } return v;}void kill_html_stack_item(struct html_element *e){ if (e->dontkill == 2) { internal("trying to kill unkillable element"); return; } if (!e || (void *)e == &html_stack) { internal("trying to free bad html element"); return; } if (e->attr.link) mem_free(e->attr.link); if (e->attr.target) mem_free(e->attr.target);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -