📄 table.c
字号:
while (span--) { struct table_column *column = &table->columns[table->columns_count++]; column->align = align; column->valign = valign; column->width = width; column->group = group; group = 0; }}static voidset_td_width(struct table *table, int col, int width, int force){ if (col >= table->cols_x_count) { int n = table->cols_x_count; int i; int *new_cols_x; n = smart_raise(col + 1, n, sizeof(*new_cols_x), SMART_RAISE_LIMIT); if (!n && table->cols_x_count) return; if (!n) n = col + 1; new_cols_x = mem_realloc(table->cols_x, n * sizeof(*new_cols_x)); if (!new_cols_x) return; for (i = table->cols_x_count; i < n; i++) new_cols_x[i] = WIDTH_AUTO; table->cols_x_count = n; table->cols_x = new_cols_x; } if (force || table->cols_x[col] == WIDTH_AUTO) { table->cols_x[col] = width; return; } if (width == WIDTH_AUTO) return; if (width < 0 && table->cols_x[col] >= 0) { table->cols_x[col] = width; return; } if (width >= 0 && table->cols_x[col] < 0) return; table->cols_x[col] = (table->cols_x[col] + width) >> 1;}static unsigned char *skip_table(unsigned char *html, unsigned char *eof){ int level = 1; while (1) { unsigned char *name; int namelen; while (html < eof && (*html != '<' || parse_element(html, eof, &name, &namelen, NULL, &html))) html++; if (html >= eof) return eof; if (!strlcasecmp(name, namelen, "TABLE", 5)) { level++; } else if (!strlcasecmp(name, namelen, "/TABLE", 6)) { level--; if (!level) return html; } }}struct table *parse_table(unsigned char *html, unsigned char *eof, unsigned char **end, unsigned char *attr, int sh){ struct table *table; struct table_cell *cell; unsigned char *t_name, *t_attr, *en; unsigned char *l_fragment_id = NULL; color_t last_bgcolor; int t_namelen; int in_cell = 0; int l_al = ALIGN_LEFT; int l_val = VALIGN_MIDDLE; int colspan, rowspan; int group = 0; int i, j, k; int c_al = ALIGN_TR, c_val = VALIGN_TR, c_width = WIDTH_AUTO, c_span = 0; int cols, rows; int col = 0, row = -1; int maxj; *end = html; table = new_table(); if (!table) return NULL; parse_table_attributes(table, attr, sh); last_bgcolor = table->bgcolor;se: en = html;see: html = en; if (!in_cell) { add_table_bad_html_start(table, html); } while (html < eof && *html != '<') html++; if (html >= eof) { if (in_cell) CELL(table, col, row)->end = html; add_table_bad_html_end(table, 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 (!strlcasecmp(t_name, t_namelen, "TABLE", 5)) { en = skip_table(en, eof); goto see; } if (!strlcasecmp(t_name, t_namelen, "/TABLE", 6)) { if (c_span) new_columns(table, c_span, c_width, c_al, c_val, 1); if (in_cell) CELL(table, col, row)->end = html; add_table_bad_html_end(table, html); goto scan_done; } if (!strlcasecmp(t_name, t_namelen, "CAPTION", 7)) { add_table_bad_html_end(table, html); if (!table->caption.start) table->caption.start = html; goto see; } if (!strlcasecmp(t_name, t_namelen, "/CAPTION", 8)) { if (table->caption.start && !table->caption.end) table->caption.end = html; goto see; } if (!strlcasecmp(t_name, t_namelen, "COLGROUP", 8)) { if (c_span) new_columns(table, c_span, c_width, c_al, c_val, 1); add_table_bad_html_end(table, html); c_al = ALIGN_TR; c_val = VALIGN_TR; c_width = WIDTH_AUTO; get_align(t_attr, &c_al); get_valign(t_attr, &c_val); get_column_width(t_attr, &c_width, sh); c_span = get_num(t_attr, "span"); if (c_span == -1) c_span = 1; else if (c_span > HTML_MAX_COLSPAN) c_span = HTML_MAX_COLSPAN; goto see; } if (!strlcasecmp(t_name, t_namelen, "/COLGROUP", 9)) { if (c_span) new_columns(table, c_span, c_width, c_al, c_val, 1); add_table_bad_html_end(table, html); c_span = 0; c_al = ALIGN_TR; c_val = VALIGN_TR; c_width = WIDTH_AUTO; goto see; } if (!strlcasecmp(t_name, t_namelen, "COL", 3)) { int sp, width, al, val; add_table_bad_html_end(table, html); sp = get_num(t_attr, "span"); if (sp == -1) sp = 1; else if (sp > HTML_MAX_COLSPAN) sp = HTML_MAX_COLSPAN; width = c_width; al = c_al; val = c_val; get_align(t_attr, &al); get_valign(t_attr, &val); get_column_width(t_attr, &width, sh); new_columns(table, sp, width, al, val, !!c_span); c_span = 0; goto see; } /* /TR /TD /TH */ if (t_namelen == 3 && t_name[0] == '/' && toupper(t_name[1]) == 'T') { unsigned char c = toupper(t_name[2]); if (c == 'R' || c == 'D' || c == 'H') { if (c_span) new_columns(table, c_span, c_width, c_al, c_val, 1); if (in_cell) { CELL(table, col, row)->end = html; in_cell = 0; } add_table_bad_html_end(table, html); } } /* All following tags have T as first letter. */ if (toupper(t_name[0]) != 'T') goto see; /* TR */ if (t_namelen == 2 && toupper(t_name[1]) == 'R') { if (c_span) new_columns(table, c_span, c_width, c_al, c_val, 1); if (in_cell) { CELL(table, col, row)->end = html; in_cell = 0; } add_table_bad_html_end(table, html); if (group) group--; l_al = ALIGN_LEFT; l_val = VALIGN_MIDDLE; last_bgcolor = table->bgcolor; get_align(t_attr, &l_al); get_valign(t_attr, &l_val); get_bgcolor(t_attr, &last_bgcolor); mem_free_set(&l_fragment_id, get_attr_val(t_attr, "id")); row++; col = 0; goto see; } /* THEAD TBODY TFOOT */ if (t_namelen == 5 && ((!strncasecmp(&t_name[1], "HEAD", 4)) || (!strncasecmp(&t_name[1], "BODY", 4)) || (!strncasecmp(&t_name[1], "FOOT", 4)))) { if (c_span) new_columns(table, c_span, c_width, c_al, c_val, 1); add_table_bad_html_end(table, html); group = 2; } /* TD TH */ if (t_namelen != 2 || (toupper(t_name[1]) != 'D' && toupper(t_name[1]) != 'H')) goto see; if (c_span) new_columns(table, c_span, c_width, c_al, c_val, 1); add_table_bad_html_end(table, html); if (in_cell) { CELL(table, col, row)->end = html; in_cell = 0; } if (row == -1) { row = 0; col = 0; } for (;;col++) { cell = new_cell(table, col, row); if (!cell) goto see; if (!cell->is_used) break; if (cell->colspan == -1) goto see; } in_cell = 1; cell->col = col; cell->row = row; cell->is_used = 1; cell->start = en; cell->align = l_al; cell->valign = l_val; cell->fragment_id = get_attr_val(t_attr, "id"); if (!cell->fragment_id && l_fragment_id) { cell->fragment_id = l_fragment_id; l_fragment_id = NULL; } cell->is_header = (toupper(t_name[1]) == 'H'); if (cell->is_header) cell->align = ALIGN_CENTER; if (group == 1) cell->is_group = 1; if (col < table->columns_count) { if (table->columns[col].align != ALIGN_TR) cell->align = table->columns[col].align; if (table->columns[col].valign != VALIGN_TR) cell->valign = table->columns[col].valign; } cell->bgcolor = last_bgcolor; get_align(t_attr, &cell->align); get_valign(t_attr, &cell->valign); get_bgcolor(t_attr, &cell->bgcolor); colspan = get_num(t_attr, "colspan"); if (colspan == -1) colspan = 1; else if (!colspan) colspan = -1; else if (colspan > HTML_MAX_COLSPAN) colspan = HTML_MAX_COLSPAN; rowspan = get_num(t_attr, "rowspan"); if (rowspan == -1) rowspan = 1; else if (!rowspan) rowspan = -1; else if (rowspan > HTML_MAX_ROWSPAN) rowspan = HTML_MAX_ROWSPAN; cell->colspan = colspan; cell->rowspan = rowspan; if (colspan == 1) { int width = WIDTH_AUTO; get_column_width(t_attr, &width, sh); if (width != WIDTH_AUTO) set_td_width(table, col, width, 0); } cols = table->cols; for (i = 1; colspan != -1 ? i < colspan : i < cols; i++) { struct table_cell *span_cell = new_cell(table, col + i, row); if (!span_cell) goto abort; if (span_cell->is_used) { colspan = i; for (k = 0; k < i; k++) CELL(table, col + k, row)->colspan = colspan; break; } span_cell->is_used = span_cell->is_spanned = 1; span_cell->rowspan = rowspan; span_cell->colspan = colspan; span_cell->col = col; span_cell->row = row; } rows = table->rows; maxj = rowspan != -1 ? rowspan : rows; /* Out of memory prevention, limit allocated memory to HTML_MAX_CELLS_MEMORY. * Not perfect but better than nothing. */ if (maxj * i > HTML_MAX_CELLS_MEMORY / sizeof(*cell)) goto abort; for (j = 1; j < maxj; j++) { for (k = 0; k < i; k++) { struct table_cell *span_cell = new_cell(table, col + k, row + j); if (!span_cell) goto abort; if (span_cell->is_used) { int l, m; if (span_cell->col == col && span_cell->row == row) continue; for (l = 0; l < k; l++) memset(CELL(table, col + l, row + j), 0, sizeof(*span_cell)); rowspan = j; for (l = 0; l < i; l++) for (m = 0; m < j; m++) CELL(table, col + l, row + m)->rowspan = j; goto see; } span_cell->is_used = span_cell->is_spanned = 1; span_cell->rowspan = rowspan; span_cell->colspan = colspan; span_cell->col = col; span_cell->row = row; } } goto see;scan_done: *end = html; mem_free_if(l_fragment_id); for (col = 0; col < table->cols; col++) for (row = 0; row < table->rows; row++) { struct table_cell *cell = CELL(table, col, row); if (!cell->is_spanned) { if (cell->colspan == -1) cell->colspan = table->cols - col; if (cell->rowspan == -1) cell->rowspan = table->rows - row; } } if (table->rows) { table->rows_heights = mem_calloc(table->rows, sizeof(*table->rows_heights)); if (!table->rows_heights) goto abort; } else { table->rows_heights = NULL; } for (col = 0; col < table->columns_count; col++) if (table->columns[col].width != WIDTH_AUTO) set_td_width(table, col, table->columns[col].width, 1); set_td_width(table, table->cols, WIDTH_AUTO, 0); return table;abort: *end = eof; free_table(table); return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -