📄 html.c
字号:
d++; } fp->parent = html_top.frameset; if (fp->n) html_top.frameset = special_f(ff, SP_FRAMESET, fp); mem_free(fp); f: mem_free(c);}*/void html_link(unsigned char *a){ unsigned char *name, *url, *title; if ((name = get_attr_val(a, "type"))) { if (strcasecmp(name, "text/html")) { mem_free(name); return; } mem_free(name); } if (!(url = get_url_val(a, "href"))) return; if (!(name = get_attr_val(a, "rel"))) if (!(name = get_attr_val(a, "rev"))) if (!(name = get_attr_val(a, "ref"))) name = stracpy(url); if (!strcasecmp(name, "stylesheet") || !strcasecmp(name, "alternate stylesheet") || !strcasecmp(name, "made") || !strcasecmp(name, "icon") || !strcasecmp(name, "shortcut icon") || !strcasecmp(name, "apple-touch-icon") || !strcasecmp(name, "meta") || !strcasecmp(name, "pingback") || !strcasecmp(name, "File-List") || !casecmp(name, "schema", 6)) goto skip; if ((title = get_attr_val(a, "title"))) { add_to_strn(&name, ": "); add_to_strn(&name, title); mem_free(title); } put_link_line("Link: ", name, url, format.target_base); skip: mem_free(name); mem_free(url);}struct element_info { char *name; void (*func)(unsigned char *); int linebreak; int nopair;};struct element_info elements[] = { {"SPAN", html_span, 0, 0}, {"B", html_bold, 0, 0}, {"STRONG", html_bold, 0, 0}, {"DFN", html_bold, 0, 0}, {"I", html_italic, 0, 0}, {"Q", html_italic, 0, 0}, {"CITE", html_italic, 0, 0}, {"EM", html_italic, 0, 0}, {"ABBR", html_italic, 0, 0}, {"U", html_underline, 0, 0}, {"S", html_underline, 0, 0}, {"STRIKE", html_underline, 0, 0}, {"FIXED", html_fixed, 0, 0}, {"CODE", html_fixed, 0, 0}, {"FONT", html_font, 0, 0}, {"A", html_a, 0, 2}, {"IMG", html_img, 0, 1}, {"BASE", html_base, 0, 1}, {"BASEFONT", html_font, 0, 1}, {"BODY", html_body, 0, 0},/* {"HEAD", html_skip, 0, 0},*/ {"TITLE", html_title, 0, 0}, {"SCRIPT", html_skip, 0, 0}, {"STYLE", html_skip, 0, 0}, {"BR", html_br, 1, 1}, {"DIV", html_linebrk, 1, 0}, {"CENTER", html_center, 1, 0}, {"CAPTION", html_center, 1, 0}, {"P", html_p, 2, 2}, {"HR", html_hr, 2, 1}, {"H1", html_center, 2, 2}, {"H2", html_h2, 2, 2}, {"H3", html_h3, 2, 2}, {"H4", html_h4, 2, 2}, {"H5", html_h5, 2, 2}, {"H6", html_h6, 2, 2}, {"BLOCKQUOTE", html_blockquote,2, 0}, {"ADDRESS", html_address, 2, 0}, {"PRE", html_pre, 2, 0}, {"LISTING", html_pre, 2, 0}, {"UL", html_ul, 1, 0}, {"DIR", html_ul, 1, 0}, {"MENU", html_ul, 1, 0}, {"OL", html_ol, 1, 0}, {"LI", html_li, 1, 3}, {"DL", html_dl, 1, 0}, {"DT", html_dt, 1, 1}, {"DD", html_dd, 1, 1}, {"TABLE", html_table, 2, 0}, {"TR", html_tr, 1, 0}, {"TD", html_td, 0, 0}, {"TH", html_th, 0, 0}, {"FORM", html_form, 1, 0}, {"INPUT", html_input, 0, 1}, {"TEXTAREA", html_textarea, 0, 1}, {"SELECT", html_select, 0, 0}, {"OPTION", html_option, 1, 1}, {"BUTTON", html_button, 0, 0}, {"LINK", html_link, 1, 1}, {"IFRAME", html_iframe, 1, 1}, {"FRAME", html_frame, 1, 1}, {"FRAMESET", html_frameset, 1, 0}, {"NOFRAMES", html_noframes, 0, 0}, {NULL, NULL, 0, 0},};unsigned char *skip_comment(unsigned char *html, unsigned char *eof){ int comm = html + 4 <= eof && html[2] == '-' && html[3] == '-'; html += comm ? 4 : 2; while (html < eof) { if (!comm && html[0] == '>') return html + 1; if (comm && html + 2 <= eof && html[0] == '-' && html[1] == '-') { html += 2; while (html < eof && *html == '-') html++; while (html < eof && WHITECHAR(*html)) html++; if (html >= eof) return eof; if (*html == '>') return html + 1; continue; } html++; } return eof;}void process_head(unsigned char *head){ unsigned char *r, *p; if ((r = parse_http_header(head, "Refresh", NULL))) { if ((p = parse_header_param(r, "URL")) || (p = parse_header_param(r, ""))) { put_link_line("Refresh: ", p, p, d_opt->framename); mem_free(p); } mem_free(r); }}int qd(unsigned char *html, unsigned char *eof, int *len){ int l; *len = 1; if (html >= eof) { internal("qd: out of data, html == %p, eof == %p", html, eof); return -1; } if (html[0] != '&') return html[0]; if (html + 1 >= eof) return -1; if (html[1] != '#') return -1; for (l = 2; l < 10 && html + l < eof; l++) if (html[l] == ';') { int n = get_entity_number(html + 2, l - 2); if (n >= 0) { *len = l + 1; return n; } break; } return -1;}void parse_html(unsigned char *html, unsigned char *eof, int (*put_chars)(void *, unsigned char *, int), void (*line_break)(void *), void *(*special)(void *, int, ...), void *f, unsigned char *head){ /*unsigned char *start = html;*/ unsigned char *lt; putsp = -1; line_breax = table_level ? 2 : 1; pos = 0; was_br = 0; put_chars_f = put_chars; line_break_f = line_break; special_f = special; ff = f; eoff = eof; if (head) process_head(head); set_lt: put_chars_f = put_chars; line_break_f = line_break; special_f = special; ff = f; eoff = eof; lt = html; while (html < eof) { unsigned char *name, *attr, *end; int namelen; struct element_info *ei; int inv; if (WHITECHAR(*html) && par_format.align != AL_NO) { unsigned char *h = html; /*if (putsp == -1) { while (html < eof && WHITECHAR(*html)) html++; goto set_lt; } putsp = 0;*/ while (h < eof && WHITECHAR(*h)) h++; if (h + 1 < eof && h[0] == '<' && h[1] == '/') { if (!parse_element(h, eof, &name, &namelen, &attr, &end)) { put_chrs(lt, html - lt, put_chars, f); lt = html = h; if (!html_top.invisible) putsp = 1; goto element; } } html++; if (!(pos + (html-lt-1))) goto skip_w; /* ??? */ if (*(html - 1) == ' ') { if (html < eof && !WHITECHAR(*html)) continue; /* BIG performance win; not sure if it doesn't cause any bug */ put_chrs(lt, html - lt, put_chars, f); } else { put_chrs(lt, html - 1 - lt, put_chars, f); put_chrs(" ", 1, put_chars, f); } skip_w: while (html < eof && WHITECHAR(*html)) html++; /*putsp = -1;*/ goto set_lt; put_sp: put_chrs(" ", 1, put_chars, f); /*putsp = -1;*/ } if (par_format.align == AL_NO && (*html < 32 || *html == '&')) { int l; int q = qd(html, eof, &l); putsp = 0; if (q == 9) { put_chrs(lt, html - lt, put_chars, f); put_chrs(" ", 8 - pos % 8, put_chars, f); html += l; goto set_lt; } else if (q == 13 || q == 10) { put_chrs(lt, html - lt, put_chars, f); next_break: html += l; if (q == 13 && html < eof - 1 && qd(html, eof, &l) == 10) html += l; ln_break(1, line_break, f); if (html >= eof) goto set_lt; q = qd(html, eof, &l); if (q == 13 || q == 10) { line_breax = 0; goto next_break; } goto set_lt; } } if (*html < ' ') { /*if (putsp == 1) goto put_sp; putsp = 0;*/ put_chrs(lt, html - lt, put_chars, f); put_chrs(".", 1, put_chars, f); html++; goto set_lt; } if (html + 2 <= eof && html[0] == '<' && (html[1] == '!' || html[1] == '?') && !d_opt->plain) { /*if (putsp == 1) goto put_sp; putsp = 0;*/ put_chrs(lt, html - lt, put_chars, f); html = skip_comment(html, eof); goto set_lt; } if (*html != '<' || d_opt->plain || parse_element(html, eof, &name, &namelen, &attr, &end)) { /*if (putsp == 1) goto put_sp; putsp = 0;*/ html++; continue; } element: inv = *name == '/'; name += inv; namelen -= inv; if (!inv && putsp == 1 && !html_top.invisible) goto put_sp; put_chrs(lt, html - lt, put_chars, f); if (par_format.align != AL_NO) if (!inv && !putsp) { unsigned char *ee = end; unsigned char *nm; while (!parse_element(ee, eof, &nm, NULL, NULL, &ee)) if (*nm == '/') goto ng; if (ee < eof && WHITECHAR(*ee)) { /*putsp = -1;*/ put_chrs(" ", 1, put_chars, f); } ng:; } html = end; for (ei = elements; ei->name; ei++) { if (ei->name && (strlen(ei->name) != (size_t)namelen || casecmp(ei->name, name, namelen))) continue; if (!inv) { char *a; ln_break(ei->linebreak, line_break, f); if (ei->name && ((a = get_attr_val(attr, "id")))) { special(f, SP_TAG, a); mem_free(a); } if (!html_top.invisible) { int a = par_format.align == AL_NO; struct par_attrib pa = par_format; if (ei->func == html_table && d_opt->tables && table_level < HTML_MAX_TABLE_LEVEL) { format_table(attr, html, eof, &html, f); ln_break(2, line_break, f); goto set_lt; } if (ei->func == html_select) { if (!do_html_select(attr, html, eof, &html, f)) goto set_lt; } if (ei->func == html_textarea) { do_html_textarea(attr, html, eof, &html, f); goto set_lt; } if (ei->nopair == 2 || ei->nopair == 3) { struct html_element *e; if (ei->nopair == 2) { foreach(e, html_stack) { if (e->dontkill) break; if (e->linebreak || !ei->linebreak) break; } } else foreach(e, html_stack) { if (e->linebreak && !ei->linebreak) break; if (e->dontkill) break; if (e->namelen == namelen && !casecmp(e->name, name, e->namelen)) break; } if (e->namelen == namelen && !casecmp(e->name, name, e->namelen)) { while (e->prev != (void *)&html_stack) kill_html_stack_item(e->prev); if (e->dontkill != 2) kill_html_stack_item(e); } } if (ei->nopair != 1) { html_stack_dup(); html_top.name = name; html_top.namelen = namelen; html_top.options = attr; html_top.linebreak = ei->linebreak; } if (ei->func) ei->func(attr); if (ei->func != html_br) was_br = 0; if (a) par_format = pa; } } else { struct html_element *e, *ff; int lnb = 0; int xxx = 0; was_br = 0; if (ei->nopair == 1 || ei->nopair == 3) break; /*debug_stack();*/ foreach(e, html_stack) { if (e->linebreak && !ei->linebreak && ei->name) xxx = 1; if (e->namelen != namelen || casecmp(e->name, name, e->namelen)) { if (e->dontkill) break; else continue; } if (xxx) { kill_html_stack_item(e); break; } for (ff = e; ff != (void *)&html_stack; ff = ff->prev) if (ff->linebreak > lnb) lnb = ff->linebreak; ln_break(lnb, line_break, f); while (e->prev != (void *)&html_stack) kill_html_stack_item(e->prev); kill_html_stack_item(e); break; } /*debug_stack();*/ } goto set_lt; } goto set_lt; /* unreachable */ } put_chrs(lt, html - lt, put_chars, f); ln_break(1, line_break, f); putsp = -1; pos = 0; /*line_breax = 1;*/ was_br = 0;}int get_image_map(unsigned char *head, unsigned char *s, unsigned char *eof, unsigned char *tag, struct menu_item **menu, struct memory_list **ml, unsigned char *href_base, unsigned char *target_base, int to, int def, int hdef){ unsigned char *name, *attr, *al, *label, *href, *target; int namelen, lblen; struct link_def *ld; struct menu_item *nm; int nmenu = 0; int i; unsigned char *hd = init_str(); int hdl = 0; struct conv_table *ct; if (head) add_to_str(&hd, &hdl, head); scan_http_equiv(s, eof, &hd, &hdl, NULL); ct = get_convert_table(hd, to, def, NULL, NULL, hdef); mem_free(hd); *menu = mem_alloc(sizeof(struct menu_item)); memset(*menu, 0, sizeof(struct menu_item)); /*(*menu)->text = NULL;*/ se: while (s < eof && *s != '<') { sp: s++; } if (s >= eof) { mem_free(*menu); return -1; } if (s + 2 <= eof && (s[1] == '!' || s[1] == '?')) { s = skip_comment(s, eof); goto se; } if (parse_element(s, eof, &name, &namelen, &attr, &s)) goto sp; if (namelen != 3 || casecmp(name, "MAP", 3)) goto se; if (tag && *tag) { if (!(al = get_attr_val(attr, "name"))) goto se; if (strcasecmp(al, tag)) { mem_free(al); goto se; } mem_free(al); } *ml = getml(NULL); se2: while (s < eof && *s != '<') { sp2: s++; } if (s >= eof) { freeml(*ml); mem_free(*menu); return -1; } if (s + 2 <= eof && (s[1] == '!' || s[1] == '?')) { s = skip_comment(s, eof); goto se2; } if (parse_element(s, eof, &name, &namelen, &attr, &s)) goto sp2; if (namelen == 1 && !casecmp(name, "A", 1)) { unsigned char *ss; label = init_str(); lblen = 0; se3: ss = s; while (ss < eof && *ss != '<') ss++; if (ss >= eof) { mem_free(label); freeml(*ml); mem_free(*menu); return -1; } add_bytes_to_str(&label, &lblen, s, ss - s); s = ss; if (s + 2 <= eof && (s[1] == '!' || s[1] == '?')) { s = skip_comment(s, eof); goto se3; } if (parse_element(s, eof, NULL, NULL, NULL, &ss)) goto se3; if (!((namelen == 1 && !casecmp(name, "A", 1)) || (namelen == 2 && !casecmp(name, "/A", 2)) || (namelen == 3 && !casecmp(name, "MAP", 3)) || (namelen == 4 && !casecmp(name, "/MAP", 4)) || (namelen == 4 && !casecmp(name, "AREA", 4)) || (namelen == 5 && !casecmp(name, "/AREA", 5)))) { s = ss; goto se3; } } else if (namelen == 4 && !casecmp(name, "AREA", 4)) { unsigned char *l = get_attr_val(attr, "alt"); if (l) label = convert_string(ct, l, strlen(l)), mem_free(l); else label = NULL; } else if (namelen == 4 && !casecmp(nam
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -