html_tbl.c
来自「this is the file used to browse web」· C语言 代码 · 共 1,263 行 · 第 1/3 页
C
1,263 行
#include "links.h"#define AL_TR -1#define VAL_TR -1#define VAL_TOP 0#define VAL_MIDDLE 1#define VAL_BOTTOM 2#define W_AUTO -1#define W_REL -2#define F_VOID 0#define F_ABOVE 1#define F_BELOW 2#define F_HSIDES 3#define F_LHS 4#define F_RHS 8#define F_VSIDES 12#define F_BOX 15#define R_NONE 0#define R_ROWS 1#define R_COLS 2#define R_ALL 3#define R_GROUPS 4void get_align(char *attr, int *a){ char *al; if ((al = get_attr_val(attr, "align"))) { if (!(strcasecmp(al, "left"))) *a = AL_LEFT; if (!(strcasecmp(al, "right"))) *a = AL_RIGHT; if (!(strcasecmp(al, "center"))) *a = AL_CENTER; if (!(strcasecmp(al, "justify"))) *a = AL_BLOCK; if (!(strcasecmp(al, "char"))) *a = AL_RIGHT; /* NOT IMPLEMENTED */ mem_free(al); }}void get_valign(char *attr, int *a){ char *al; if ((al = get_attr_val(attr, "valign"))) { if (!(strcasecmp(al, "top"))) *a = VAL_TOP; if (!(strcasecmp(al, "middle"))) *a = VAL_MIDDLE; if (!(strcasecmp(al, "bottom"))) *a = VAL_BOTTOM; if (!(strcasecmp(al, "baseline"))) *a = VAL_TOP; /* NOT IMPLEMENTED */ mem_free(al); }}void get_c_width(char *attr, int *w, int sh){ char *al; if ((al = get_attr_val(attr, "width"))) { if (*al && al[strlen(al) - 1] == '*') { char *en; unsigned long n; al[strlen(al) - 1] = 0; n = strtoul(al, &en, 10); if (n < 10000 && !*en) *w = W_REL - n; } else { int p = get_width(attr, "width", sh); if (p >= 0) *w = p; } mem_free(al); }}#define INIT_X 8#define INIT_Y 8struct table_cell { int used; int spanned; int mx, my; unsigned char *start; unsigned char *end; int align; int valign; int b; struct rgb bgcolor; int group; int colspan; int rowspan; int min_width; int max_width; int x_width; int height; int xpos, ypos, xw, yw; int link_num;};struct table_column { int group; int align; int valign; int width;};struct table { struct part *p; int x, y; int rx, ry; int border, cellpd, vcellpd, cellsp; int frame, rules, width, wf; int *min_c, *max_c; int *w_c; int rw; int min_t, max_t; struct table_cell *cells; int c, rc; struct table_column *cols; int xc; int *xcols; int *r_heights; int rh; int link_num;};#define CELL(t, x, y) (&(t)->cells[(y) * (t)->rx + (x)])unsigned char frame_table[81] = { 0x00, 0xb3, 0xba, 0xc4, 0xc0, 0xd3, 0xcd, 0xd4, 0xc8, 0xc4, 0xd9, 0xbd, 0xc4, 0xc1, 0xd0, 0xcd, 0xd4, 0xc8, 0xcd, 0xbe, 0xbc, 0xcd, 0xbe, 0xbc, 0xcd, 0xcf, 0xca, 0xb3, 0xb3, 0xba, 0xda, 0xc3, 0xd3, 0xd5, 0xc6, 0xc8, 0xbf, 0xb4, 0xbd, 0xc2, 0xc5, 0xd0, 0xd5, 0xc6, 0xc8, 0xb8, 0xb5, 0xbc, 0xb8, 0xb5, 0xbc, 0xd1, 0xd8, 0xca, 0xba, 0xba, 0xba, 0xd6, 0xd6, 0xc7, 0xc9, 0xc9, 0xcc, 0xb7, 0xb7, 0xb6, 0xd2, 0xd2, 0xd7, 0xc9, 0xc9, 0xcc, 0xbb, 0xbb, 0xb9, 0xbb, 0xbb, 0xb9, 0xcb, 0xcb, 0xce,};unsigned char hline_table[3] = { 0x20, 0xc4, 0xcd };unsigned char vline_table[3] = { 0x20, 0xb3, 0xba };struct table *new_table(){ struct table *t; t = mem_alloc(sizeof(struct table)); memset(t, 0, sizeof(struct table)); t->p = NULL; t->x = t->y = 0; t->rx = INIT_X; t->ry = INIT_Y; t->cells = mem_alloc(INIT_X * INIT_Y * sizeof(struct table_cell)); memset(t->cells, 0, INIT_X * INIT_Y * sizeof(struct table_cell)); t->c = 0; t->rc = INIT_X; t->cols = mem_alloc(INIT_X * sizeof(struct table_column)); memset(t->cols, 0, INIT_X * sizeof(struct table_column)); t->xcols = DUMMY; t->xc = 0; t->r_heights = DUMMY; return t;}void free_table(struct table *t){ if (t->min_c) mem_free(t->min_c); if (t->max_c) mem_free(t->max_c); if (t->w_c) mem_free(t->w_c); mem_free(t->r_heights); mem_free(t->cols); mem_free(t->xcols); mem_free(t->cells); mem_free(t);}void expand_cells(struct table *t, int x, int y){ int i, j; if (x >= t->x) { if (t->x) { for (i = 0; i < t->y; i++) if (CELL(t, t->x - 1, i)->colspan == -1) { for (j = t->x; j <= x; j++) { CELL(t, j, i)->used = 1; CELL(t, j, i)->spanned = 1; CELL(t, j, i)->rowspan = CELL(t, t->x - 1, i)->rowspan; CELL(t, j, i)->colspan = -1; CELL(t, j, i)->mx = CELL(t, t->x - 1, i)->mx; CELL(t, j, i)->my = CELL(t, t->x - 1, i)->my; } } } t->x = x + 1; } if (y >= t->y) { if (t->y) { for (i = 0; i < t->x; i++) if (CELL(t, i, t->y - 1)->rowspan == -1) { for (j = t->y; j <= y; j++) { CELL(t, i, j)->used = 1; CELL(t, i, j)->spanned = 1; CELL(t, i, j)->rowspan = -1; CELL(t, i, j)->colspan = CELL(t, i, t->y - 1)->colspan; CELL(t, i, j)->mx = CELL(t, i, t->y - 1)->mx; CELL(t, i, j)->my = CELL(t, i, t->y - 1)->my; } } } t->y = y + 1; }}struct table_cell *new_cell(struct table *t, int x, int y){ struct table nt; int i, j; if (x < t->x && y < t->y) goto ret; rep: if (x < t->rx && y < t->ry) { expand_cells(t, x, y); goto ret; } nt.rx = t->rx; nt.ry = t->ry; while (x >= nt.rx) { if ((unsigned)nt.rx > MAXINT / 2) overalloc(); nt.rx *= 2; } while (y >= nt.ry) { if ((unsigned)nt.ry > MAXINT / 2) overalloc(); nt.ry *= 2; } if ((unsigned)nt.rx * (unsigned)nt.ry / (unsigned)nt.rx != (unsigned)nt.ry) overalloc(); if ((unsigned)nt.rx * (unsigned)nt.ry > MAXINT / sizeof(struct table_cell)) overalloc(); nt.cells = mem_alloc(nt.rx * nt.ry * sizeof(struct table_cell)); memset(nt.cells, 0, nt.rx * nt.ry * sizeof(struct table_cell)); for (i = 0; i < t->x; i++) for (j = 0; j < t->y; j++) memcpy(CELL(&nt, i, j), CELL(t, i, j), sizeof(struct table_cell)); mem_free(t->cells); t->cells = nt.cells; t->rx = nt.rx; t->ry = nt.ry; goto rep; ret: return CELL(t, x, y);}void new_columns(struct table *t, int span, int width, int align, int valign, int group){ if ((unsigned)t->c + (unsigned)span > MAXINT) overalloc(); if (t->c + span > t->rc) { int n = t->rc; struct table_column *nc; while (t->c + span > n) { if ((unsigned)n > MAXINT / 2) overalloc(); n *= 2; } if ((unsigned)n > MAXINT / sizeof(struct table_column)) overalloc(); nc = mem_realloc(t->cols, n * sizeof(struct table_column)); t->rc = n; t->cols = nc; } while (span--) { t->cols[t->c].align = align; t->cols[t->c].valign = valign; t->cols[t->c].width = width; t->cols[t->c++].group = group; group = 0; }}void set_td_width(struct table *t, int x, int width, int f){ if (x >= t->xc) { int n = t->xc ? t->xc : 1; int i; int *nc; while (x >= n) { if ((unsigned)n > MAXINT / 2) overalloc(); n *= 2; } if ((unsigned)n > MAXINT / sizeof(int)) overalloc(); nc = mem_realloc(t->xcols, n * sizeof(int)); for (i = t->xc; i < n; i++) nc[i] = W_AUTO; t->xc = n; t->xcols = nc; } if (t->xcols[x] == W_AUTO || f) { set: t->xcols[x] = width; return; } if (width == W_AUTO) return; if (width < 0 && t->xcols[x] >= 0) goto set; if (width >= 0 && t->xcols[x] < 0) return; t->xcols[x] = (t->xcols[x] + width) / 2;}unsigned char *skip_table(unsigned char *html, unsigned char *eof){ int level = 1; unsigned char *name; int namelen; r: while (html < eof && (*html != '<' || parse_element(html, eof, &name, &namelen, NULL, &html))) html++; if (html >= eof) return eof; if (namelen == 5 && !casecmp(name, "TABLE", 5)) level++; if (namelen == 6 && !casecmp(name, "/TABLE", 6)) if (!--level) return html; goto r;}struct s_e { unsigned char *s, *e;};struct table *parse_table(unsigned char *html, unsigned char *eof, unsigned char **end, struct rgb *bgcolor, int sh, struct s_e **bad_html, int *bhp){ int qqq; struct table *t; struct table_cell *cell; unsigned char *t_name, *t_attr, *en; int t_namelen; int x = 0, y = -1; int p = 0; unsigned char *lbhp = NULL; int l_al = AL_LEFT; int l_val = VAL_MIDDLE; int csp, rsp; int group = 0; int i, j, k; struct rgb l_col; int c_al = AL_TR, c_val = VAL_TR, c_width = W_AUTO, c_span = 0; memcpy(&l_col, bgcolor, sizeof(struct rgb)); *end = html; if (bad_html) { *bad_html = DUMMY; *bhp = 0; } if (!(t = new_table())) return NULL; se: en = html; see: html = en; if (bad_html && !p && !lbhp) { if (!(*bhp & (ALLOC_GR-1))) { if ((unsigned)*bhp > MAXINT / sizeof(struct s_e) - ALLOC_GR) overalloc(); *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_table(en, eof); 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);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?