⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 html_tbl.c

📁 ELinks is an advanced and well-established feature-rich text mode web (HTTP/FTP/..) browser. ELinks
💻 C
📖 第 1 页 / 共 4 页
字号:
			*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 + -