📄 html_tbl.c
字号:
*bad_html = mem_realloc(*bad_html, (*bhp + ALLOC_GR) * sizeof(struct s_e)); } lbhp = (*bad_html)[(*bhp)++].s = html; } while (html < eof && *html != '<') html++; if (html >= eof) { if (p) CELL(t, x, y)->end = html; if (lbhp) (*bad_html)[*bhp-1].e = html; goto scan_done; } if (html + 2 <= eof && (html[1] == '!' || html[1] == '?')) { html = skip_comment(html, eof); goto se; } if (parse_element(html, eof, &t_name, &t_namelen, &t_attr, &en)) { html++; goto se; } if (t_namelen == 5 && !casecmp(t_name, "TABLE", 5)) { en = skip_element(en, eof, "TABLE", 1); goto see; } if (t_namelen == 6 && !casecmp(t_name, "SCRIPT", 5)) { en = skip_element(en, eof, "SCRIPT", 0); goto see; } if (t_namelen == 6 && !casecmp(t_name, "/TABLE", 6)) { if (c_span) new_columns(t, c_span, c_width, c_al, c_val, 1); if (p) CELL(t, x, y)->end = html; if (lbhp) (*bad_html)[*bhp-1].e = html; goto scan_done; } if (t_namelen == 8 && !casecmp(t_name, "COLGROUP", 8)) { if (c_span) new_columns(t, c_span, c_width, c_al, c_val, 1); if (lbhp) (*bad_html)[*bhp-1].e = html, lbhp = NULL; c_al = AL_TR; c_val = VAL_TR; c_width = W_AUTO; get_align(t_attr, &c_al); get_valign(t_attr, &c_val); get_c_width(t_attr, &c_width, sh); if ((c_span = get_num(t_attr, "span")) == -1) c_span = 1; goto see; } if (t_namelen == 9 && !casecmp(t_name, "/COLGROUP", 9)) { if (c_span) new_columns(t, c_span, c_width, c_al, c_val, 1); if (lbhp) (*bad_html)[*bhp-1].e = html, lbhp = NULL; c_span = 0; c_al = AL_TR; c_val = VAL_TR; c_width = W_AUTO; goto see; } if (t_namelen == 3 && !casecmp(t_name, "COL", 3)) { int sp, wi, al, val; if (lbhp) (*bad_html)[*bhp-1].e = html, lbhp = NULL; if ((sp = get_num(t_attr, "span")) == -1) sp = 1; wi = c_width; al = c_al; val = c_val; get_align(t_attr, &al); get_valign(t_attr, &val); get_c_width(t_attr, &wi, sh); new_columns(t, sp, wi, al, val, !!c_span); c_span = 0; goto see; } if (t_namelen == 3 && (!casecmp(t_name, "/TR", 3) || !casecmp(t_name, "/TD", 3) || !casecmp(t_name, "/TH", 3))) { if (c_span) new_columns(t, c_span, c_width, c_al, c_val, 1); if (p) CELL(t, x, y)->end = html, p = 0; if (lbhp) (*bad_html)[*bhp-1].e = html, lbhp = NULL; } if (t_namelen == 2 && !casecmp(t_name, "TR", 2)) { if (c_span) new_columns(t, c_span, c_width, c_al, c_val, 1); if (p) CELL(t, x, y)->end = html, p = 0; if (lbhp) (*bad_html)[*bhp-1].e = html, lbhp = NULL; if (group) group--; l_al = AL_LEFT; l_val = VAL_MIDDLE; memcpy(&l_col, bgcolor, sizeof(struct rgb)); get_align(t_attr, &l_al); get_valign(t_attr, &l_val); get_bgcolor(t_attr, &l_col); y++, x = 0; goto see; } if (t_namelen == 5 && ((!casecmp(t_name, "THEAD", 5)) || (!casecmp(t_name, "TBODY", 5)) || (!casecmp(t_name, "TFOOT", 5)))) { if (c_span) new_columns(t, c_span, c_width, c_al, c_val, 1); if (lbhp) (*bad_html)[*bhp-1].e = html, lbhp = NULL; group = 2; } if (t_namelen != 2 || (casecmp(t_name, "TD", 2) && casecmp(t_name, "TH", 2))) goto see; if (c_span) new_columns(t, c_span, c_width, c_al, c_val, 1); if (lbhp) (*bad_html)[*bhp-1].e = html, lbhp = NULL; if (p) CELL(t, x, y)->end = html, p = 0; if (y == -1) y = 0, x = 0; nc: if (!(cell = new_cell(t, x, y))) goto see; if (cell->used) { if (cell->colspan == -1) goto see; x++; goto nc; } cell->mx = x; cell->my = y; cell->used = 1; cell->start = en; p = 1; cell->align = l_al; cell->valign = l_val; if ((cell->b = upcase(t_name[1]) == 'H')) cell->align = AL_CENTER; if (group == 1) cell->group = 1; if (x < t->c) { if (t->cols[x].align != AL_TR) cell->align = t->cols[x].align; if (t->cols[x].valign != VAL_TR) cell->valign = t->cols[x].valign; } memcpy(&cell->bgcolor, &l_col, sizeof(struct rgb)); get_align(t_attr, &cell->align); get_valign(t_attr, &cell->valign); get_bgcolor(t_attr, &cell->bgcolor);#ifdef G sprintf(cell->bgcolor_str, "#%02x%02x%02x", cell->bgcolor.r & 0xff, cell->bgcolor.g & 0xff, cell->bgcolor.b & 0xff);#endif if ((csp = get_num(t_attr, "colspan")) == -1) csp = 1; if (!csp) csp = -1; if ((rsp = get_num(t_attr, "rowspan")) == -1) rsp = 1; if (!rsp) rsp = -1; if (csp >= 0 && rsp >= 0 && csp * rsp > 100000) { if (csp > 10) csp = -1; if (rsp > 10) rsp = -1; } cell->colspan = csp; cell->rowspan = rsp; if (csp == 1) { int w = W_AUTO; get_c_width(t_attr, &w, sh); if (w != W_AUTO) set_td_width(t, x, w, 0); } qqq = t->x; for (i = 1; csp != -1 ? i < csp : x + i < qqq; i++) { struct table_cell *sc; if (!(sc = new_cell(t, x + i, y)) || sc->used) { csp = i; for (k = 0; k < i; k++) CELL(t, x + k, y)->colspan = csp; break; } sc->used = sc->spanned = 1; sc->rowspan = rsp; sc->colspan = csp; sc->mx = x; sc->my = y; } qqq = t->y; for (j = 1; rsp != -1 ? j < rsp : y + j < qqq; j++) { for (k = 0; k < i; k++) { struct table_cell *sc; if (!(sc = new_cell(t, x + k, y + j)) || sc->used) { int l, m; if (sc->mx == x && sc->my == y) continue; /*internal("boo");*/ for (l = 0; l < k; l++) memset(CELL(t, x + l, y + j), 0, sizeof(struct table_cell)); rsp = j; for (l = 0; l < i; l++) for (m = 0; m < j; m++) CELL(t, x + l, y + m)->rowspan = j; goto brk; } sc->used = sc->spanned = 1; sc->rowspan = rsp; sc->colspan = csp; sc->mx = x; sc->my = y; } } brk: goto see; scan_done: *end = html; for (x = 0; x < t->x; x++) for (y = 0; y < t->y; y++) { struct table_cell *c = CELL(t, x, y); if (!c->spanned) { if (c->colspan == -1) c->colspan = t->x - x; if (c->rowspan == -1) c->rowspan = t->y - y; } } if ((unsigned)t->y > MAXINT / sizeof(int)) overalloc(); t->r_heights = mem_calloc(t->y * sizeof(int)); for (x = 0; x < t->c; x++) if (t->cols[x].width != W_AUTO) set_td_width(t, x, t->cols[x].width, 1); set_td_width(t, t->x, W_AUTO, 0); return t;}void get_cell_width(char *start, char *end, int cellpd, int w, int a, int *min, int *max, int n_link, int *n_links, unsigned char *bgc){ struct part *p;#ifdef G struct g_part *gp;#endif if (min) *min = -1; if (max) *max = -1; if (n_links) *n_links = n_link; if (!F) { if (!(p = format_html_part(start, end, AL_LEFT, cellpd, w, NULL, !!a, !!a, NULL, n_link))) return; if (min) *min = p->x; if (max) *max = p->xmax; if (n_links) *n_links = p->link_num; mem_free(p);#ifdef G } else { if (!(gp = g_format_html_part(start, end, AL_LEFT, 0, w, NULL, n_link, NULL, bgc, NULL))) return; if (min) *min = gp->x; if (max) *max = gp->xmax; if (n_links) *n_links = gp->link_num; mem_free(gp);#endif } /*debug("get_cell_width: %d < %d", *min, *max);*/ /*if (min && max && *min > *max) internal("get_cell_width: %d > %d", *min, *max);*/}static inline void check_cell_widths(struct table *t){ int i, j; for (j = 0; j < t->y; j++) for (i = 0; i < t->x; i++) { int min, max; struct table_cell *c = CELL(t, i, j); if (!c->start) continue; get_cell_width(c->start, c->end, t->cellpd, 0, 0, &min, &max, c->link_num, NULL, gf_val(NULL, c->bgcolor_str)); /*if (min != c->min_width || max < c->max_width) internal("check_cell_widths failed");*/ }}#define g_c_w(cc) \do { \ struct table_cell *c = cc; \ if (!c->start) continue; \ c->link_num = nl; \ get_cell_width(c->start, c->end, t->cellpd, 0, 0, &c->min_width, &c->max_width, nl, &nl, gf_val(NULL, c->bgcolor_str));\} while (0)void get_cell_widths(struct table *t){ int nl = gf_val(t->p->link_num, t->gp->link_num); int i, j; if (!d_opt->table_order) for (j = 0; j < t->y; j++) for (i = 0; i < t->x; i++) g_c_w(CELL(t, i, j)); else for (i = 0; i < t->x; i++) for (j = 0; j < t->y; j++) g_c_w(CELL(t, i, j)); t->link_num = nl;}void dst_width(int *p, int n, int w, int *lim){ int i, s = 0, d, r; for (i = 0; i < n; i++) s += p[i]; if (s >= w) return; if (!n) return; again: d = (w - s) / n; r = (w - s) % n; w = 0; for (i = 0; i < n; i++) { p[i] += d + (i < r); if (lim && p[i] > lim[i]) w += p[i] - lim[i], p[i] = lim[i]; } if (w) { /*if (!lim) internal("bug in dst_width");*/ lim = NULL; s = 0; goto again; }}int get_vline_width(struct table *t, int col){ /* return: -1 none, 0, space, 1 line, 2 double */ int w = 0; NO_GFX; if (!col) return -1; if (t->rules == R_COLS || t->rules == R_ALL) w = t->cellsp; else if (t->rules == R_GROUPS) w = col < t->c && t->cols[col].group; if (!w && t->cellpd) w = -1; return w;}int get_hline_width(struct table *t, int row){ int w = 0; NO_GFX; if (!row) return -1; if (t->rules == R_ROWS || t->rules == R_ALL) { x: if (t->cellsp || t->vcellpd) return t->cellsp; return -1; } else if (t->rules == R_GROUPS) { int q; for (q = 0; q < t->x; q++) if (CELL(t, q, row)->group) goto x; return t->vcellpd ? 0 : -1; } if (!w && !t->vcellpd) w = -1; return w;}#ifdef Gint g_get_vline_pad(struct table *t, int col, int *plpos, int *plsize){ int pad, lpos, lsize; int border; NO_TXT; if (!col || col == t->x) { border = (!col && t->frame & F_LHS) || (col == t->x && t->frame & F_RHS) ? t->border : 0; pad = border + t->cellsp + t->cellpd; if (!col) lpos = 0, lsize = border + t->cellsp; else lpos = pad - border - t->cellsp, lsize = border + t->cellsp; } else { border = t->rules == R_COLS || t->rules == R_ALL || (t->rules == R_GROUPS && col < t->c && t->cols[col].group) ? t->border : 0; pad = 2 * t->cellpd + t->cellsp; lpos = t->cellpd; lsize = t->cellsp; } if (!border) { lsize = 0; if (!col) lpos = 0; else if (col == t->x) lpos = pad; else lpos = pad / 2; } if (plpos) *plpos = lpos; if (plsize) *plsize = lsize; return pad;}int g_get_hline_pad(struct table *t, int row, int *plpos, int *plsize){ int pad, lpos, lsize; int border; NO_TXT; if (!row || row == t->y) { border = (!row && t->frame & F_ABOVE) || (row == t->y && t->frame & F_BELOW) ? t->border : 0; pad = border + t->cellsp + t->cellpd; if (!row) lpos = 0, lsize = border + t->cellsp; else lpos = pad - border - t->cellsp, lsize = border + t->cellsp; } else { border = t->rules == R_ROWS || t->rules == R_ALL ? t->border : 0; if (t->rules == R_GROUPS) { int q; for (q = 0; q < t->x; q++) if (CELL(t, q, row)->group) { border = t->border; break; } } pad = 2 * t->cellpd + t->cellsp; lpos = t->cellpd; lsize = t->cellsp; } if (!border) { lsize = 0; if (!row) lpos = 0; else if (row == t->y) lpos = pad; else lpos = pad / 2; } if (plpos) *plpos = lpos; if (plsize) *plsize = lsize; return pad;}#endif int get_column_widths(struct table *t){ int i, j, s, ns; if ((unsigned)t->x > MAXINT / sizeof(int)) overalloc(); if (!t->min_c) t->min_c = mem_alloc(t->x * sizeof(int)); if (!t->max_c) t->max_c = mem_alloc(t->x * sizeof(int)); if (!t->w_c) t->w_c = mem_alloc(t->x * sizeof(int)); memset(t->min_c, 0, t->x * sizeof(int)); memset(t->max_c, 0, t->x * sizeof(int)); s = 1; do { ns = MAXINT; for (i = 0; i < t->x; i++) for (j = 0; j < t->y; j++) { struct table_cell *c = CELL(t, i, j); if (c->spanned || !c->used) continue; if (c->colspan + i > t->x) { /*internal("colspan out of table"); return -1;*/ continue; } if (c->colspan == s) { int k, p = 0; /*int pp = t->max_c[i];*/ int m = 0; for (k = 1; k < s; k++) { if (!F) p += get_vline_width(t, i + k) >= 0;#ifdef G else p += g_get_vline_pad(t, i + k, NULL, NULL);#endif } dst_width(t->min_c + i, s, c->min_width - p, t->max_c + i); dst_width(t->max_c + i, s, c->max_width - p - m, NULL); for (k = 0; k < s; k++) if (t->min_c[i + k] > t->max_c[i + k]) t->max_c[i + k] = t->min_c[i + k]; } else if (c->colspan > s && c->colspan < ns) ns = c->colspan; } } while ((s = ns) != MAXINT); return 0;}void get_table_width(struct table *t){ int i, vl; int min = 0, max = 0; for (i = 0; i < t->x; i++) { if (!F) vl = get_vline_width(t, i) >= 0;#ifdef G else if (i) { vl = g_get_vline_pad(t, i, NULL, NULL); } else vl = 0;#endif min += vl, max += vl; min += t->min_c[i]; if (t->xcols[i] > t->max_c[i]) max += t->xcols[i]; max += t->max_c[i]; } if (!F) { vl = (!!(t->frame & F_LHS) + !!(t->frame & F_RHS)) * !!t->border; min += vl, max += vl;#ifdef G } else { vl = g_get_vline_pad(t, 0, NULL, NULL); min += vl, max += vl; vl = g_get_vline_pad(t, t->x, NULL, NULL); min += vl, max += vl;#endif } t->min_t = min; t->max_t = max; /*if (min > max) internal("min(%d) > max(%d)", min, max);*/}void distribute_widths(struct table *t, int width){ int i; int d = width - t->min_t; int om = 0; char *u; int *w, *mx; int mmax_c = 0; t->rw = 0; if (!t->x) return; if (d < 0) { /*internal("too small width %d, required %d", width, t->min_t);*/ return; } for (i = 0; i < t->x; i++) if (t->max_c[i] > mmax_c) mmax_c = t->max_c[i]; memcpy(t->w_c, t->min_c, t->x * sizeof(int)); t->rw = width; if ((unsigned)t->x > MAXINT / sizeof(int)) overalloc(); u = mem_alloc(t->x); w = mem_alloc(t->x * sizeof(int)); mx = mem_alloc(t->x * sizeof(int));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -