aboutsummaryrefslogtreecommitdiffstats
path: root/table.c.0
diff options
context:
space:
mode:
Diffstat (limited to 'table.c.0')
-rw-r--r--table.c.02878
1 files changed, 0 insertions, 2878 deletions
diff --git a/table.c.0 b/table.c.0
deleted file mode 100644
index f3cacb1..0000000
--- a/table.c.0
+++ /dev/null
@@ -1,2878 +0,0 @@
-/* -*- mode: c; c-basic-offset: 4; tab-width: 8; -*- */
-/* $Id: table.c.0,v 1.1 2001/11/08 05:15:52 a-ito Exp $ */
-/*
- * HTML table
- */
-#include <sys/types.h>
-#include <stdio.h>
-#include <string.h>
-#include <math.h>
-#ifdef __EMX__
-#include <strings.h>
-#endif /* __EMX__ */
-
-#include "fm.h"
-#include "html.h"
-#include "parsetag.h"
-#include "Str.h"
-#include "myctype.h"
-
-#ifdef KANJI_SYMBOLS
-static char *rule[] =
-{"¨«", "¨§", "¨¨", "¨£", "¨©", "¨¢", "¨¤", "07", "¨ª", "¨¦", "¨¡", "0B", "¨¥", "0D", "0E", " "};
-static char *ruleB[] =
-{"00", "¨·", "¨¸", "¨®", "¨¹", "¨­", "¨¯", "07", "¨º", "¨±", "¨¬", "0B", "¨°", "0D", "0E", " "};
-#define TN_VERTICALBAR "¨¢"
-#define HORIZONTALBAR "¨¬"
-#define RULE_WIDTH 2
-#else /* not KANJI_SYMBOLS */
-static char *rule[] =
-{
- "<_RULE TYPE=0>+</_RULE>",
- "<_RULE TYPE=1>+</_RULE>",
- "<_RULE TYPE=2>+</_RULE>",
- "<_RULE TYPE=3>+</_RULE>",
- "<_RULE TYPE=4>+</_RULE>",
- "<_RULE TYPE=5>|</_RULE>",
- "<_RULE TYPE=6>+</_RULE>",
- "<_RULE TYPE=7>07</_RULE>",
- "<_RULE TYPE=8>+</_RULE>",
- "<_RULE TYPE=9>+</_RULE>",
- "<_RULE TYPE=10>-</_RULE>",
- "<_RULE TYPE=11>0B</_RULE>",
- "<_RULE TYPE=12>+</_RULE>",
- "<_RULE TYPE=13>0D</_RULE>",
- "<_RULE TYPE=14>0E</_RULE>",
- "<_RULE TYPE=15> </_RULE>"};
-static char **ruleB = rule;
-#define TN_VERTICALBAR "<_RULE TYPE=5>|</_RULE>"
-#define HORIZONTALBAR "<_RULE TYPE=10>-</_RULE>"
-#define RULE_WIDTH 1
-#endif /* not KANJI_SYMBOLS */
-
-#define RULE(mode) (((mode)==BORDER_THICK)?ruleB:rule)
-#define TK_VERTICALBAR(mode) (RULE(mode)[5])
-
-#define BORDERWIDTH 2
-#define BORDERHEIGHT 1
-#define NOBORDERWIDTH 1
-#define NOBORDERHEIGHT 0
-
-#define HTT_X 1
-#define HTT_Y 2
-#define HTT_ALIGN 0x30
-#define HTT_LEFT 0x00
-#define HTT_CENTER 0x10
-#define HTT_RIGHT 0x20
-#define HTT_TRSET 0x40
-#ifdef NOWRAP
-#define HTT_NOWRAP 4
-#endif /* NOWRAP */
-#define TAG_IS(s,tag,len) (strncasecmp(s,tag,len)==0&&(s[len] == '>' || IS_SPACE((int)s[len])))
-
-#ifndef max
-#define max(a,b) ((a) > (b) ? (a) : (b))
-#endif /* not max */
-#ifndef min
-#define min(a,b) ((a) > (b) ? (b) : (a))
-#endif /* not min */
-#ifndef abs
-#define abs(a) ((a) >= 0. ? (a) : -(a))
-#endif /* not abs */
-
-#ifdef MATRIX
-#ifndef MESCHACH
-#include "matrix.c"
-#endif /* not MESCHACH */
-#endif /* MATRIX */
-
-#ifdef MATRIX
-int correct_table_matrix(struct table *, int, int, int, double);
-void set_table_matrix(struct table *, int);
-#endif /* MATRIX */
-
-#ifdef MATRIX
-static double
-weight(int x)
-{
-
- if (x < COLS)
- return (double) x;
- else
- return COLS * (log((double) x / COLS) + 1.);
-}
-
-static double
-weight2(int a)
-{
- return (double) a / COLS * 4 + 1.;
-}
-
-#define sigma_td(a) (0.5*weight2(a)) /* <td width=...> */
-#define sigma_td_nw(a) (32*weight2(a)) /* <td ...> */
-#define sigma_table(a) (0.25*weight2(a)) /* <table width=...> */
-#define sigma_table_nw(a) (2*weight2(a)) /* <table...> */
-#else /* not MATRIX */
-#define LOG_MIN 1.0
-static double
-weight3(int x)
-{
- if (x < 0.1)
- return 0.1;
- if (x < LOG_MIN)
- return (double) x;
- else
- return LOG_MIN * (log((double) x / LOG_MIN) + 1.);
-}
-#endif /* not MATRIX */
-
-static int
-dsort_index(short e1, short *ent1, short e2, short *ent2, int base,
- char *index, int nent)
-{
- int n = nent;
- int k = 0;
-
- int e = e1 * base + e2;
- while (n > 0) {
- int nn = n / 2;
- int idx = index[k + nn];
- int ne = ent1[idx] * base + ent2[idx];
- if (ne == e) {
- k += nn;
- break;
- }
- else if (ne < e) {
- n -= nn + 1;
- k += nn + 1;
- }
- else {
- n = nn;
- }
- }
- return k;
-}
-
-static int
-fsort_index(double e, double *ent, char *index, int nent)
-{
- int n = nent;
- int k = 0;
-
- while (n > 0) {
- int nn = n / 2;
- int idx = index[k + nn];
- double ne = ent[idx];
- if (ne == e) {
- k += nn;
- break;
- }
- else if (ne > e) {
- n -= nn + 1;
- k += nn + 1;
- }
- else {
- n = nn;
- }
- }
- return k;
-}
-
-static void
-dv2sv(double *dv, short *iv, int size)
-{
- int i, k, iw;
- char *index;
- double *edv;
- double w = 0., x;
-
- index = NewAtom_N(char, size);
- edv = NewAtom_N(double, size);
- for (i = 0; i < size; i++) {
- iv[i] = ceil(dv[i]);
- edv[i] = (double) iv[i] - dv[i];
- }
-
- w = 0.;
- for (k = 0; k < size; k++) {
- x = edv[k];
- w += x;
- i = fsort_index(x, edv, index, k);
- if (k > i)
- bcopy(index + i, index + i + 1, k - i);
- index[i] = k;
- }
- iw = min((int) (w + 0.5), size);
- if (iw == 0)
- return;
- x = edv[(int) index[iw - 1]];
- for (i = 0; i < size; i++) {
- k = index[i];
- if (i >= iw && abs(edv[k] - x) > 1e-6)
- break;
- iv[k]--;
- }
-}
-
-static int
-table_colspan(struct table *t, int row, int col)
-{
- int i;
- for (i = col + 1; i <= t->maxcol && (t->tabattr[row][i] & HTT_X); i++);
- return i - col;
-}
-
-static int
-table_rowspan(struct table *t, int row, int col)
-{
- int i;
- if (!t->tabattr[row])
- return 0;
- for (i = row + 1; i <= t->maxrow && t->tabattr[i] &&
- (t->tabattr[i][col] & HTT_Y); i++);
- return i - row;
-}
-
-static int
-minimum_cellspacing(int border_mode)
-{
- switch (border_mode) {
- case BORDER_THIN:
- case BORDER_THICK:
- case BORDER_NOWIN:
- return RULE_WIDTH;
- case BORDER_NONE:
- return 1;
- default:
- /* not reached */
- return 0;
- }
-}
-
-static int
-table_border_width(struct table *t)
-{
- switch (t->border_mode) {
- case BORDER_THIN:
- case BORDER_THICK:
- return t->maxcol * t->cellspacing + 2 * (RULE_WIDTH + t->cellpadding);
- case BORDER_NOWIN:
- case BORDER_NONE:
- return t->maxcol * t->cellspacing;
- default:
- /* not reached */
- return 0;
- }
-}
-
-struct table *
-newTable()
-{
- struct table *t;
- int i, j;
-
- t = New(struct table);
- t->max_rowsize = MAXROW;
- t->tabdata = New_N(TextList **, MAXROW);
- t->tabattr = New_N(table_attr *, MAXROW);
- t->tabheight = NewAtom_N(short, MAXROW);
-#ifdef ID_EXT
- t->tabidvalue = New_N(Str *, MAXROW);
- t->tridvalue = New_N(Str, MAXROW);
-#endif /* ID_EXT */
-
- for (i = 0; i < MAXROW; i++) {
- t->tabdata[i] = NULL;
- t->tabattr[i] = 0;
- t->tabheight[i] = 0;
-#ifdef ID_EXT
- t->tabidvalue[i] = NULL;
- t->tridvalue[i] = NULL;
-#endif /* ID_EXT */
- }
- for (j = 0; j < MAXCOL; j++) {
- t->tabwidth[j] = 0;
- t->minimum_width[j] = 0;
- t->fixed_width[j] = 0;
- }
- t->cell.maxcell = -1;
- t->cell.icell = -1;
- t->tabcontentssize = 0;
- t->indent = 0;
- t->ntable = 0;
- t->tables_size = 0;
- t->tables = NULL;
-#ifdef MATRIX
- t->matrix = NULL;
- t->vector = NULL;
-#endif /* MATRIX */
- t->linfo.prev_ctype = PC_ASCII;
- t->linfo.prev_spaces = -1;
- t->linfo.prevchar = ' ';
- t->trattr = 0;
-
- t->status = R_ST_NORMAL;
- t->suspended_input = Strnew();
- t->caption = Strnew();
-#ifdef ID_EXT
- t->id = NULL;
-#endif
- return t;
-}
-
-static void
-check_row(struct table *t, int row)
-{
- int i, r;
- TextList ***tabdata;
- table_attr **tabattr;
- short *tabheight;
-#ifdef ID_EXT
- Str **tabidvalue;
- Str *tridvalue;
-#endif /* ID_EXT */
-
- if (row >= t->max_rowsize) {
- r = max(t->max_rowsize * 2, row + 1);
- tabdata = New_N(TextList **, r);
- tabattr = New_N(table_attr *, r);
- tabheight = New_N(short, r);
-#ifdef ID_EXT
- tabidvalue = New_N(Str *, r);
- tridvalue = New_N(Str, r);
-#endif /* ID_EXT */
- for (i = 0; i < t->max_rowsize; i++) {
- tabdata[i] = t->tabdata[i];
- tabattr[i] = t->tabattr[i];
- tabheight[i] = t->tabheight[i];
-#ifdef ID_EXT
- tabidvalue[i] = t->tabidvalue[i];
- tridvalue[i] = t->tridvalue[i];
-#endif /* ID_EXT */
- }
- for (; i < r; i++) {
- tabdata[i] = NULL;
- tabattr[i] = NULL;
- tabheight[i] = 0;
-#ifdef ID_EXT
- tabidvalue[i] = NULL;
- tridvalue[i] = NULL;
-#endif /* ID_EXT */
- }
- t->tabdata = tabdata;
- t->tabattr = tabattr;
- t->tabheight = tabheight;
-#ifdef ID_EXT
- t->tabidvalue = tabidvalue;
- t->tridvalue = tridvalue;
-#endif /* ID_EXT */
- t->max_rowsize = r;
- }
-
- if (t->tabdata[row] == NULL) {
- t->tabdata[row] = New_N(TextList *, MAXCOL);
- t->tabattr[row] = NewAtom_N(table_attr, MAXCOL);
-#ifdef ID_EXT
- t->tabidvalue[row] = New_N(Str, MAXCOL);
-#endif /* ID_EXT */
- for (i = 0; i < MAXCOL; i++) {
- t->tabdata[row][i] = NULL;
- t->tabattr[row][i] = 0;
-#ifdef ID_EXT
- t->tabidvalue[row][i] = NULL;
-#endif /* ID_EXT */
- }
- }
-}
-
-void
-pushdata(struct table *t, int row, int col, char *data)
-{
- check_row(t, row);
- if (t->tabdata[row][col] == NULL)
- t->tabdata[row][col] = newTextList();
-
- pushText(t->tabdata[row][col], data);
-}
-
-int visible_length_offset = 0;
-int
-visible_length(char *str)
-{
- int len = 0;
- int status = R_ST_NORMAL;
- int prev_status = status;
- Str tagbuf = Strnew();
- char *t, *r2;
- struct parsed_tagarg *t_arg, *tt;
- int amp_len;
-
- t = str;
- while (*str) {
- prev_status = status;
- len += next_status(*str, &status);
- if (status == R_ST_TAG0) {
- Strclear(tagbuf);
- Strcat_char(tagbuf, *str);
- }
- else if (status == R_ST_TAG || status == R_ST_DQUOTE || status == R_ST_QUOTE || status == R_ST_EQL) {
- Strcat_char(tagbuf, *str);
- }
- else if (status == R_ST_AMP) {
- if (prev_status == R_ST_NORMAL) {
- Strclear(tagbuf);
- amp_len = 0;
- }
- else {
- Strcat_char(tagbuf, *str);
- len++;
- amp_len++;
- }
- }
- else if (status == R_ST_NORMAL && prev_status == R_ST_AMP) {
- Strcat_char(tagbuf, *str);
- r2 = tagbuf->ptr;
- t = getescapecmd(&r2);
- len += strlen(t) - 1 - amp_len;
- if (*r2 != '\0') {
- str -= strlen(r2);
- }
- }
- else if (status == R_ST_NORMAL && ST_IS_REAL_TAG(prev_status)) {
- Strcat_char(tagbuf, *str);
- if (TAG_IS(tagbuf->ptr, "<img", 4)) {
- int anchor_len = 0;
- t_arg = parse_tag(tagbuf->ptr + 5);
- for (tt = t_arg; tt; tt = tt->next) {
- if (strcasecmp(tt->arg, "src") == 0 && tt->value && anchor_len == 0) {
- r2 = tt->value + strlen(tt->value) - 1;
- while (tt->value < r2 && *r2 != '/')
- r2--;
- if (*r2 == '/')
- r2++;
- while (*r2 && *r2 != '.') {
- r2++;
- anchor_len++;
- }
- anchor_len += 2;
- }
- else if (strcasecmp(tt->arg, "alt") == 0 && tt->value) {
- anchor_len = strlen(tt->value) + 1;
- break;
- }
- }
- len += anchor_len;
- }
- else if (TAG_IS(tagbuf->ptr, "<input", 6)) {
- int width = 20;
- int valuelen = 1;
- int input_type = FORM_INPUT_TEXT;
- t_arg = parse_tag(tagbuf->ptr + 7);
- for (tt = t_arg; tt; tt = tt->next) {
- if (strcasecmp(tt->arg, "type") == 0 && tt->value) {
- input_type = formtype(tt->value);
- }
- else if (strcasecmp(tt->arg, "value") == 0 && tt->value) {
- valuelen = strlen(tt->value);
- }
- else if (strcasecmp(tt->arg, "width") == 0 && tt->value) {
- width = atoi(tt->value);
- }
- }
- switch (input_type) {
- case FORM_INPUT_TEXT:
- case FORM_INPUT_FILE:
- case FORM_INPUT_PASSWORD:
- len += width + 2;
- break;
- case FORM_INPUT_SUBMIT:
- case FORM_INPUT_RESET:
- case FORM_INPUT_IMAGE:
- case FORM_INPUT_BUTTON:
- len += valuelen + 2;
- break;
- case FORM_INPUT_CHECKBOX:
- case FORM_INPUT_RADIO:
- len += 3;
- }
- }
- else if (TAG_IS(tagbuf->ptr, "<textarea", 9)) {
- int width = 20;
- t_arg = parse_tag(tagbuf->ptr + 7);
- for (tt = t_arg; tt; tt = tt->next) {
- if (strcasecmp(tt->arg, "cols") == 0 && tt->value) {
- width = atoi(tt->value);
- }
- }
- len += width + 2;
- }
- else if (TAG_IS(tagbuf->ptr, "<option", 7))
- len += 3;
- }
- else if (*str == '\t') {
- len--;
- do {
- len++;
- } while ((visible_length_offset + len) % Tabstop != 0);
- }
- str++;
- }
- if (status == R_ST_AMP) {
- r2 = tagbuf->ptr;
- t = getescapecmd(&r2);
- len += strlen(t) - 1 - amp_len;
- if (*r2 != '\0') {
- len += strlen(r2);
- }
- }
- return len;
-}
-
-int
-maximum_visible_length(char *str)
-{
- int maxlen, len;
- char *p;
-
- for (p = str; *p && *p != '\t'; p++);
-
- visible_length_offset = 0;
- maxlen = visible_length(str);
-
- if (*p == '\0')
- return maxlen;
-
- for (visible_length_offset = 1; visible_length_offset < Tabstop;
- visible_length_offset++) {
- len = visible_length(str);
- if (maxlen < len) {
- maxlen = len;
- break;
- }
- }
- return maxlen;
-}
-
-char *
-align(char *str, int width, int mode)
-{
- int i, l, l1, l2;
- Str buf = Strnew();
-
- if (str == NULL || *str == '\0') {
- for (i = 0; i < width; i++)
- Strcat_char(buf, ' ');
- return buf->ptr;
- }
- l = width - visible_length(str);
- switch (mode) {
- case ALIGN_CENTER:
- l1 = l / 2;
- l2 = l - l1;
- for (i = 0; i < l1; i++)
- Strcat_char(buf, ' ');
- Strcat_charp(buf, str);
- for (i = 0; i < l2; i++)
- Strcat_char(buf, ' ');
- return buf->ptr;
- case ALIGN_LEFT:
- Strcat_charp(buf, str);
- for (i = 0; i < l; i++)
- Strcat_char(buf, ' ');
- return buf->ptr;
- case ALIGN_RIGHT:
- for (i = 0; i < l; i++)
- Strcat_char(buf, ' ');
- Strcat_charp(buf, str);
- return buf->ptr;
- }
- return Strnew_charp(str)->ptr;
-}
-
-void
-print_item(struct table *t,
- int row, int col, int width,
- Str buf)
-{
- int alignment;
- char *p;
-
- if (t->tabdata[row])
- p = popText(t->tabdata[row][col]);
- else
- p = NULL;
-
- if (p != NULL) {
- check_row(t, row);
- alignment = ALIGN_CENTER;
- if ((t->tabattr[row][col] & HTT_ALIGN) == HTT_LEFT)
- alignment = ALIGN_LEFT;
- else if ((t->tabattr[row][col] & HTT_ALIGN) == HTT_RIGHT)
- alignment = ALIGN_RIGHT;
- else if ((t->tabattr[row][col] & HTT_ALIGN) == HTT_CENTER)
- alignment = ALIGN_CENTER;
- Strcat_charp(buf, align(p, width, alignment));
- }
- else
- Strcat_charp(buf, align(NULL, width, ALIGN_CENTER));
-}
-
-
-#define T_TOP 0
-#define T_MIDDLE 1
-#define T_BOTTOM 2
-
-void
-print_sep(struct table *t,
- int row, int type, int maxcol,
- Str buf)
-{
- int forbid;
- char **rulep;
- int i, j, k, l, m;
-
-#if defined(__EMX__)&&!defined(JP_CHARSET)
- if(CodePage==850){
- ruleB = ruleB850;
- rule = rule850;
- }
-#endif
- if (row >= 0)
- check_row(t, row);
- check_row(t, row + 1);
- if ((type == T_TOP || type == T_BOTTOM) && t->border_mode == BORDER_THICK) {
- rulep = ruleB;
- }
- else {
- rulep = rule;
- }
- forbid = 1;
- if (type == T_TOP)
- forbid |= 2;
- else if (type == T_BOTTOM)
- forbid |= 8;
- else if (t->tabattr[row + 1][0] & HTT_Y) {
- forbid |= 4;
- }
- if (t->border_mode != BORDER_NOWIN)
- Strcat_charp(buf, RULE(t->border_mode)[forbid]);
- for (i = 0; i <= maxcol; i++) {
- forbid = 10;
- if (type != T_BOTTOM && (t->tabattr[row + 1][i] & HTT_Y)) {
- if (t->tabattr[row + 1][i] & HTT_X) {
- goto do_last_sep;
- }
- else {
- for (k = row; k >= 0 && t->tabattr[k] && (t->tabattr[k][i] & HTT_Y); k--);
- m = t->tabwidth[i] + 2 * t->cellpadding;
- for (l = i + 1; l <= t->maxcol && (t->tabattr[row][l] & HTT_X); l++)
- m += t->tabwidth[l] + t->cellspacing;
- print_item(t, k, i, m, buf);
- }
- }
- else {
- for (j = 0; j < t->tabwidth[i] + 2 * t->cellpadding; j += RULE_WIDTH) {
- Strcat_charp(buf, rulep[forbid]);
- }
- }
- do_last_sep:
- if (i < maxcol) {
- forbid = 0;
- if (type == T_TOP)
- forbid |= 2;
- else if (t->tabattr[row][i + 1] & HTT_X) {
- forbid |= 2;
- }
- if (type == T_BOTTOM)
- forbid |= 8;
- else {
- if (t->tabattr[row + 1][i + 1] & HTT_X) {
- forbid |= 8;
- }
- if (t->tabattr[row + 1][i + 1] & HTT_Y) {
- forbid |= 4;
- }
- if (t->tabattr[row + 1][i] & HTT_Y) {
- forbid |= 1;
- }
- }
- if (forbid != 15) /* forbid==15 means 'no rule at all' */
- Strcat_charp(buf, rulep[forbid]);
- }
- }
- forbid = 4;
- if (type == T_TOP)
- forbid |= 2;
- if (type == T_BOTTOM)
- forbid |= 8;
- if (t->tabattr[row + 1][maxcol] & HTT_Y) {
- forbid |= 1;
- }
- if (t->border_mode != BORDER_NOWIN)
- Strcat_charp(buf, RULE(t->border_mode)[forbid]);
- Strcat_charp(buf, "<eol>");
-}
-
-static int
-get_spec_cell_width(struct table *tbl, int row, int col)
-{
- int i, w;
-
- w = tbl->tabwidth[col];
- for (i = col + 1; i <= tbl->maxcol; i++) {
- check_row(tbl, row);
- if (tbl->tabattr[row][i] & HTT_X)
- w += tbl->tabwidth[i] + tbl->cellspacing;
- else
- break;
- }
- return w;
-}
-
-void
-do_refill(struct table *tbl, int row, int col)
-{
- TextList *orgdata;
- TextListItem *l;
- struct readbuffer obuf;
- struct html_feed_environ h_env;
- struct environment envs[MAX_ENV_LEVEL];
-
- if (tbl->tabdata[row] == NULL ||
- tbl->tabdata[row][col] == NULL)
- return;
- orgdata = tbl->tabdata[row][col];
- tbl->tabdata[row][col] = newTextList();
-
- init_henv(&h_env, &obuf, envs, MAX_ENV_LEVEL, tbl->tabdata[row][col],
- tbl->tabwidth[col], 0);
- h_env.limit = get_spec_cell_width(tbl, row, col);
- for (l = orgdata->first; l != NULL; l = l->next) {
- if (TAG_IS(l->ptr, "<dummy_table", 12)) {
- struct parsed_tagarg *t_arg, *t;
- int id = -1;
- t_arg = parse_tag(l->ptr + 12);
- for (t = t_arg; t; t = t->next) {
- if (!strcasecmp(t->arg, "id") && t->value) {
- id = atoi(t->value);
- break;
- }
- }
- if (id >= 0) {
- int alignment;
- TextListItem *ti;
- save_fonteffect(&h_env, h_env.obuf);
- flushline(&h_env, &obuf, 0, 0, h_env.limit);
-
- if (RB_GET_ALIGN(h_env.obuf) == RB_CENTER)
- alignment = ALIGN_CENTER;
- else if (RB_GET_ALIGN(h_env.obuf) == RB_RIGHT)
- alignment = ALIGN_RIGHT;
- else
- alignment = ALIGN_LEFT;
-
- if (alignment == ALIGN_LEFT) {
- appendTextList(h_env.buf, tbl->tables[id].buf);
- }
- else {
- for (ti = tbl->tables[id].buf->first; ti != NULL; ti = ti->next) {
- pushText(h_env.buf, align(ti->ptr, h_env.limit, alignment));
- }
- }
- restore_fonteffect(&h_env, h_env.obuf);
- }
- }
- else
- HTMLlineproc1(l->ptr, &h_env);
- }
- flushline(&h_env, &obuf, 0, 0, h_env.limit);
-}
-
-static void
-check_cell_width(short *tabwidth, short *cellwidth,
- short *col, short *colspan, short maxcell,
- char *index, int space, int dir)
-{
- int i, j, k, bcol, ecol;
- int swidth, width;
-
- for (k = 0; k <= maxcell; k++) {
- j = index[k];
- if (cellwidth[j] <= 0)
- continue;
- bcol = col[j];
- ecol = bcol + colspan[j];
- swidth = 0;
- for (i = bcol; i < ecol; i++)
- swidth += tabwidth[i];
-
- width = cellwidth[j] - (colspan[j] - 1) * space;
- if (width > swidth) {
- int w = (width - swidth) / colspan[j];
- int r = (width - swidth) % colspan[j];
- for (i = bcol; i < ecol; i++)
- tabwidth[i] += w;
- /* dir {0: horizontal, 1: vertical} */
- if (dir == 1 && r > 0)
- r = colspan[j];
- for (i = 1; i <= r; i++)
- tabwidth[ecol - i]++;
- }
- }
-}
-
-void
-check_minimum_width(struct table *t, short *tabwidth)
-{
- int i;
- struct table_cell *cell = &t->cell;
-
- for (i = 0; i <= t->maxcol; i++) {
- if (tabwidth[i] < t->minimum_width[i])
- tabwidth[i] = t->minimum_width[i];
- }
-
- check_cell_width(tabwidth, cell->minimum_width, cell->col, cell->colspan,
- cell->maxcell, cell->index, t->cellspacing, 0);
-}
-
-void
-check_maximum_width(struct table *t)
-{
- struct table_cell *cell = &t->cell;
-#ifdef MATRIX
- int i, j, bcol, ecol;
- int swidth, width;
-
- cell->necell = 0;
- for (j = 0; j <= cell->maxcell; j++) {
- bcol = cell->col[j];
- ecol = bcol + cell->colspan[j];
- swidth = 0;
- for (i = bcol; i < ecol; i++)
- swidth += t->tabwidth[i];
-
- width = cell->width[j] - (cell->colspan[j] - 1) * t->cellspacing;
- if (width > swidth) {
- cell->eindex[cell->necell] = j;
- cell->necell++;
- }
- }
-#else /* not MATRIX */
- check_cell_width(t->tabwidth, cell->width, cell->col, cell->colspan,
- cell->maxcell, cell->index, t->cellspacing, 0);
- check_minimum_width(t, t->tabwidth);
-#endif /* not MATRIX */
-}
-
-
-#ifdef MATRIX
-static int
-recalc_width(int old, int delta, double rat)
-{
- double w = rat * old;
- double ww = (double) delta;
- if (w > 0.) {
- if (ww < 0.)
- ww = 0.;
- ww += 0.2;
- }
- else {
- if (ww > 0.)
- ww = 0.;
- ww -= 1.0;
- }
- if (w > ww)
- return (int) (ww / rat);
- return old;
-}
-
-static int
-check_compressible_cell(struct table *t, MAT * minv,
- short *newwidth, short *swidth, short *cwidth,
- int totalwidth,
- int icol, int icell, double sxx, int corr)
-{
- struct table_cell *cell = &t->cell;
- int i, j, k, m, bcol, ecol;
- int delta, dmax, dmin, owidth;
- double sxy;
-
- if (sxx < 10.)
- return corr;
-
- if (icol >= 0) {
- owidth = newwidth[icol];
- delta = newwidth[icol] - t->tabwidth[icol];
- bcol = icol;
- ecol = bcol + 1;
- }
- else if (icell >= 0) {
- owidth = swidth[icell];
- delta = swidth[icell] - cwidth[icell];
- bcol = cell->col[icell];
- ecol = bcol + cell->colspan[icell];
- }
- else {
- owidth = totalwidth;
- delta = totalwidth;
- bcol = 0;
- ecol = t->maxcol + 1;
- }
-
- dmin = delta;
- dmax = 0;
- for (k = 0; k <= cell->maxcell; k++) {
- int bcol1, ecol1;
- if (dmin <= 0)
- return corr;
- j = cell->index[k];
- if (icol < 0 && j == icell)
- continue;
- bcol1 = cell->col[j];
- ecol1 = bcol1 + cell->colspan[j];
- sxy = 0.;
- for (m = bcol1; m < ecol1; m++) {
- for (i = bcol; i < ecol; i++)
- sxy += m_entry(minv, i, m);
- }
- if (fabs(delta * sxy / sxx) < 0.5)
- continue;
- if (sxy > 0.)
- dmin = recalc_width(dmin, swidth[j] - cwidth[j], sxy / sxx);
- else
- dmax = recalc_width(dmax, swidth[j] - cwidth[j], sxy / sxx);
- }
- for (m = 0; m <= t->maxcol; m++) {
- if (dmin <= 0)
- return corr;
- if (icol >= 0 && m == icol)
- continue;
- sxy = 0.;
- for (i = bcol; i < ecol; i++)
- sxy += m_entry(minv, i, m);
- if (fabs(delta * sxy / sxx) < 0.5)
- continue;
- if (sxy > 0.)
- dmin = recalc_width(dmin, newwidth[m] - t->tabwidth[m], sxy / sxx);
- else
- dmax = recalc_width(dmax, newwidth[m] - t->tabwidth[m], sxy / sxx);
- }
- if (dmax > 0 && dmin > dmax)
- dmin = dmax;
- if (dmin > 1) {
- correct_table_matrix(t, bcol, ecol - bcol, owidth - dmin, 1.);
- corr++;
- }
- return corr;
-}
-
-#define MAX_ITERATION 3
-int
-check_table_width(struct table *t, short *newwidth, MAT * minv, int itr)
-{
- int i, j, k, m, bcol, ecol;
- int corr = 0;
- struct table_cell *cell = &t->cell;
-#ifdef __GNUC__
- short orgwidth[t->maxcol + 1];
- short cwidth[cell->maxcell + 1], swidth[cell->maxcell + 1];
-#else /* __GNUC__ */
- short orgwidth[MAXCOL];
- short cwidth[MAXCELL], swidth[MAXCELL];
-#endif /* __GNUC__ */
- int twidth;
- double sxy, *Sxx, stotal;
-
- twidth = 0;
- stotal = 0.;
- for (i = 0; i <= t->maxcol; i++) {
- twidth += newwidth[i];
- stotal += m_entry(minv, i, i);
- for (m = 0; m < i; m++) {
- stotal += 2 * m_entry(minv, i, m);
- }
- }
-
- Sxx = NewAtom_N(double, cell->maxcell + 1);
- for (k = 0; k <= cell->maxcell; k++) {
- j = cell->index[k];
- bcol = cell->col[j];
- ecol = bcol + cell->colspan[j];
- swidth[j] = 0;
- for (i = bcol; i < ecol; i++)
- swidth[j] += newwidth[i];
- cwidth[j] = cell->width[j] - (cell->colspan[j] - 1) * t->cellspacing;
- Sxx[j] = 0.;
- for (i = bcol; i < ecol; i++) {
- Sxx[j] += m_entry(minv, i, i);
- for (m = bcol; m <= ecol; m++) {
- if (m < i)
- Sxx[j] += 2 * m_entry(minv, i, m);
- }
- }
- }
-
- /* compress table */
- corr = check_compressible_cell(t, minv, newwidth, swidth, cwidth, twidth,
- -1, -1, stotal, corr);
- if (itr < MAX_ITERATION && corr > 0)
- return corr;
-
- /* compress multicolumn cell */
- for (k = cell->maxcell; k >= 0; k--) {
- j = cell->index[k];
- corr = check_compressible_cell(t, minv, newwidth, swidth, cwidth, twidth,
- -1, j, Sxx[j], corr);
- if (itr < MAX_ITERATION && corr > 0)
- return corr;
- }
-
- /* compress single column cell */
- for (i = 0; i <= t->maxcol; i++) {
- corr = check_compressible_cell(t, minv, newwidth, swidth, cwidth, twidth,
- i, -1, m_entry(minv, i, i), corr);
- if (itr < MAX_ITERATION && corr > 0)
- return corr;
- }
-
-
- for (i = 0; i <= t->maxcol; i++)
- orgwidth[i] = newwidth[i];
-
- check_minimum_width(t, newwidth);
-
- for (i = 0; i <= t->maxcol; i++) {
- double sx = sqrt(m_entry(minv, i, i));
- if (sx < 0.1)
- continue;
- if (orgwidth[i] < t->minimum_width[i] &&
- newwidth[i] == t->minimum_width[i]) {
- double w = (sx > 0.5) ? 0.5 : sx * 0.2;
- sxy = 0.;
- for (m = 0; m <= t->maxcol; m++) {
- if (m == i)
- continue;
- sxy += m_entry(minv, i, m);
- }
- if (sxy <= 0.) {
- correct_table_matrix(t, i, 1, t->minimum_width[i], w);
- corr++;
- }
- }
- }
-
- for (k = 0; k <= cell->maxcell; k++) {
- int nwidth = 0, mwidth;
- double sx;
-
- j = cell->index[k];
- sx = sqrt(Sxx[j]);
- if (sx < 0.1)
- continue;
- bcol = cell->col[j];
- ecol = bcol + cell->colspan[j];
- for (i = bcol; i < ecol; i++)
- nwidth += newwidth[i];
- mwidth = cell->minimum_width[j] - (cell->colspan[j] - 1) * t->cellspacing;
- if (mwidth > swidth[j] && mwidth == nwidth) {
- double w = (sx > 0.5) ? 0.5 : sx * 0.2;
-
- sxy = 0.;
- for (i = bcol; i < ecol; i++) {
- for (m = 0; m <= t->maxcol; m++) {
- if (m >= bcol && m < ecol)
- continue;
- sxy += m_entry(minv, i, m);
- }
- }
- if (sxy <= 0.) {
- correct_table_matrix(t, bcol, cell->colspan[j], mwidth, w);
- corr++;
- }
- }
- }
-
- if (itr >= MAX_ITERATION)
- return 0;
- else
- return corr;
-}
-
-#else /* not MATRIX */
-void
-set_table_width(struct table *t, short *newwidth, int maxwidth)
-{
- int i, j, k, bcol, ecol;
- struct table_cell *cell = &t->cell;
- char *fixed;
- int swidth, fwidth, width, nvar;
- double s;
- double *dwidth;
- int try_again;
-
- fixed = NewAtom_N(char, t->maxcol + 1);
- bzero(fixed, t->maxcol + 1);
- dwidth = NewAtom_N(double, t->maxcol + 1);
-
- for (i = 0; i <= t->maxcol; i++) {
- dwidth[i] = 0.0;
- if (t->fixed_width[i] < 0) {
- t->fixed_width[i] = -t->fixed_width[i] * maxwidth / 100;
- }
- if (t->fixed_width[i] > 0) {
- newwidth[i] = t->fixed_width[i];
- fixed[i] = 1;
- }
- else
- newwidth[i] = 0;
- if (newwidth[i] < t->minimum_width[i])
- newwidth[i] = t->minimum_width[i];
- }
-
- for (k = 0; k <= cell->maxcell; k++) {
- j = cell->index[k];
- bcol = cell->col[j];
- ecol = bcol + cell->colspan[j];
-
- if (cell->fixed_width[j] < 0)
- cell->fixed_width[j] = -cell->fixed_width[j] * maxwidth / 100;
-
- swidth = 0;
- fwidth = 0;
- nvar = 0;
- for (i = bcol; i < ecol; i++) {
- if (fixed[i]) {
- fwidth += newwidth[i];
- }
- else {
- swidth += newwidth[i];
- nvar++;
- }
- }
- width = max(cell->fixed_width[j], cell->minimum_width[j])
- - (cell->colspan[j] - 1) * t->cellspacing;
- if (nvar > 0 && width > fwidth + swidth) {
- s = 0.;
- for (i = bcol; i < ecol; i++) {
- if (!fixed[i])
- s += weight3(t->tabwidth[i]);
- }
- for (i = bcol; i < ecol; i++) {
- if (!fixed[i])
- dwidth[i] = (width - fwidth) * weight3(t->tabwidth[i]) / s;
- else
- dwidth[i] = (double) newwidth[i];
- }
- dv2sv(dwidth, newwidth, cell->colspan[j]);
- if (cell->fixed_width[j] > 0) {
- for (i = bcol; i < ecol; i++)
- fixed[i] = 1;
- }
- }
- }
-
- do {
- nvar = 0;
- swidth = 0;
- fwidth = 0;
- for (i = 0; i <= t->maxcol; i++) {
- if (fixed[i]) {
- fwidth += newwidth[i];
- }
- else {
- swidth += newwidth[i];
- nvar++;
- }
- }
- width = maxwidth - t->maxcol * t->cellspacing;
- if (nvar == 0 || width <= fwidth + swidth)
- break;
-
- s = 0.;
- for (i = 0; i <= t->maxcol; i++) {
- if (!fixed[i])
- s += weight3(t->tabwidth[i]);
- }
- for (i = 0; i <= t->maxcol; i++) {
- if (!fixed[i])
- dwidth[i] = (width - fwidth) * weight3(t->tabwidth[i]) / s;
- else
- dwidth[i] = (double) newwidth[i];
- }
- dv2sv(dwidth, newwidth, t->maxcol + 1);
-
- try_again = 0;
- for (i = 0; i <= t->maxcol; i++) {
- if (!fixed[i]) {
- if (newwidth[i] > t->tabwidth[i]) {
- newwidth[i] = t->tabwidth[i];
- fixed[i] = 1;
- try_again = 1;
- }
- else if (newwidth[i] < t->minimum_width[i]) {
- newwidth[i] = t->minimum_width[i];
- fixed[i] = 1;
- try_again = 1;
- }
- }
- }
- } while (try_again);
-}
-#endif /* not MATRIX */
-
-void
-check_table_height(struct table *t)
-{
- int i, j, k;
- struct {
- short row[MAXCELL];
- short rowspan[MAXCELL];
- char index[MAXCELL];
- short maxcell;
- short height[MAXCELL];
- } cell;
- int space;
-
- cell.maxcell = -1;
-
- for (j = 0; j <= t->maxrow; j++) {
- if (!t->tabattr[j])
- continue;
- for (i = 0; i <= t->maxcol; i++) {
- int t_dep, rowspan;
- if (t->tabattr[j][i] & (HTT_X | HTT_Y))
- continue;
-
- if (t->tabdata[j][i] == NULL)
- t_dep = 0;
- else
- t_dep = t->tabdata[j][i]->nitem;
-
- rowspan = table_rowspan(t, j, i);
- if (rowspan > 1) {
- int c = cell.maxcell + 1;
- k = dsort_index(rowspan, cell.rowspan,
- j, cell.row, t->maxrow + 1,
- cell.index, c);
- if (k <= cell.maxcell) {
- int idx = cell.index[k];
- if (cell.row[idx] == j &&
- cell.rowspan[idx] == rowspan)
- c = idx;
- }
- if (c > cell.maxcell && c < MAXCELL) {
- cell.maxcell++;
- cell.row[cell.maxcell] = j;
- cell.rowspan[cell.maxcell] = rowspan;
- cell.height[cell.maxcell] = 0;
- if (cell.maxcell > k)
- bcopy(cell.index + k, cell.index + k + 1, cell.maxcell - k);
- cell.index[k] = cell.maxcell;
- }
- if (c <= cell.maxcell && c >= 0 &&
- cell.height[c] < t_dep) {
- cell.height[c] = t_dep;
- continue;
- }
- }
- if (t->tabheight[j] < t_dep)
- t->tabheight[j] = t_dep;
- }
- }
-
- switch (t->border_mode) {
- case BORDER_THIN:
- case BORDER_THICK:
- case BORDER_NOWIN:
- space = 1;
- break;
- case BORDER_NONE:
- space = 0;
- }
- check_cell_width(t->tabheight, cell.height, cell.row, cell.rowspan,
- cell.maxcell, cell.index, space, 1);
-}
-
-int
-get_table_width(struct table *t, short *orgwidth, short *cellwidth,
- int check_minimum)
-{
-#ifdef __GNUC__
- short newwidth[t->maxcol + 1];
-#else /* not __GNUC__ */
- short newwidth[MAXCOL];
-#endif /* not __GNUC__ */
- int i;
- int swidth;
- struct table_cell *cell = &t->cell;
-
- for (i = 0; i <= t->maxcol; i++)
- newwidth[i] = max(orgwidth[i], 0);
-
- check_cell_width(newwidth, cellwidth, cell->col, cell->colspan,
- cell->maxcell, cell->index, t->cellspacing, 0);
- if (check_minimum)
- check_minimum_width(t, newwidth);
-
- swidth = 0;
- for (i = 0; i <= t->maxcol; i++) {
- swidth += newwidth[i];
- }
- swidth += table_border_width(t);
- return swidth;
-}
-
-#define minimum_table_width(t)\
-(get_table_width(t,t->minimum_width,t->cell.minimum_width,0))
-#define maximum_table_width(t)\
- (get_table_width(t,t->tabwidth,t->cell.width,0))
-#define fixed_table_width(t)\
- (get_table_width(t,t->fixed_width,t->cell.fixed_width,1))
-
-void
-renderCoTable(struct table *tbl)
-{
- struct readbuffer obuf;
- struct html_feed_environ h_env;
- struct environment envs[MAX_ENV_LEVEL];
- struct table *t;
- int i, j, col, row, b_width;
- int width, nwidth, indent, maxwidth;
-#ifdef __GNUC__
- short newwidth[tbl->maxcol + 1];
-#else /* not __GNUC__ */
- short newwidth[MAXCOL];
-#endif /* not __GNUC__ */
-
- for (i = 0; i <= tbl->maxcol; i++)
- newwidth[i] = tbl->tabwidth[i];
-
- for (i = 0; i < tbl->ntable; i++) {
- t = tbl->tables[i].ptr;
- col = tbl->tables[i].col;
- row = tbl->tables[i].row;
- indent = tbl->tables[i].indent;
-
- init_henv(&h_env, &obuf, envs, MAX_ENV_LEVEL, tbl->tables[i].buf,
- tbl->tabwidth[col], indent);
- nwidth = newwidth[col];
- check_row(tbl, row);
- b_width = 0;
- for (j = col + 1; j <= tbl->maxcol; j++) {
- if (tbl->tabattr[row][j] & HTT_X) {
- h_env.limit += tbl->tabwidth[j];
- nwidth += newwidth[j];
- b_width += tbl->cellspacing;
- }
- else
- break;
- }
- h_env.limit += b_width;
-#ifndef TABLE_EXPAND
- if (t->total_width == 0)
- maxwidth = h_env.limit - indent;
- else if (t->total_width > 0)
- maxwidth = t->total_width;
- else
- maxwidth = t->total_width = -t->total_width *
- get_spec_cell_width(tbl, row, col) / 100;
-#else
- maxwidth = h_env.limit - indent;
- if (t->total_width > 0) {
- double r = ((double) maxwidth) / t->total_width;
- struct table_cell *cell = &t->cell;
-
- for (j = 0; j <= t->maxcol; j++) {
- if (t->fixed_width[j] > 0)
- t->fixed_width[j] = (int) (r * t->fixed_width[j]);
- }
- for (j = 0; j <= cell->maxcell; j++) {
- if (cell->fixed_width[j] > 0)
- cell->fixed_width[j] = (int) (r * cell->fixed_width[j]);
- }
- t->total_width = maxwidth;
- }
-#endif /* TABLE_EXPAND */
- renderTable(t, maxwidth, &h_env);
- width = t->total_width - b_width + indent;
- if (width > nwidth) {
- int cell = tbl->tables[i].cell;
- if (cell < 0) {
- newwidth[col] = width;
- }
- else {
- int ecol = col + tbl->cell.colspan[cell];
- int w = (width - nwidth) / tbl->cell.colspan[cell];
- int r = (width - nwidth) % tbl->cell.colspan[cell];
- for (j = col; j < ecol; j++)
- newwidth[j] += w;
- for (j = 1; j <= r; j++)
- newwidth[ecol - j]++;
- }
- }
- t = NULL;
- }
- for (i = 0; i <= tbl->maxcol; i++)
- tbl->tabwidth[i] = newwidth[i];
-}
-
-static void
-make_caption(struct table *t, struct html_feed_environ *h_env)
-{
- struct html_feed_environ henv;
- struct readbuffer obuf;
- struct environment envs[MAX_ENV_LEVEL];
- TextList *tl;
- Str tmp;
-
- if (t->caption->length <= 0)
- return;
-
- if (t->total_width <= 0)
- t->total_width = h_env->limit;
-
- init_henv(&henv, &obuf, envs, MAX_ENV_LEVEL, newTextList(), t->total_width,
- h_env->envs[h_env->envc].indent);
- HTMLlineproc1("<center>", &henv);
- HTMLlineproc1(t->caption->ptr, &henv);
- HTMLlineproc1("</center>", &henv);
-
- tl = henv.buf;
-
- if (tl->nitem > 0) {
- TextListItem *ti;
- tmp = Strnew_charp("<pre for_table>");
- for (ti = tl->first; ti != NULL; ti = ti->next) {
- Strcat_charp(tmp, ti->ptr);
- Strcat_char(tmp, '\n');
- }
- Strcat_charp(tmp, "</pre>");
- HTMLlineproc1(tmp->ptr, h_env);
- }
-}
-
-void
-renderTable(struct table *t,
- int max_width,
- struct html_feed_environ *h_env)
-{
- int i, j, w, r, h;
- Str renderbuf = Strnew();
- short new_tabwidth[MAXCOL];
-#ifdef MATRIX
- int itr;
- VEC *newwidth;
- MAT *mat, *minv;
- PERM *pivot;
-#endif /* MATRIX */
- int maxheight = 0;
- Str vrulea, vruleb, vrulec;
-#ifdef ID_EXT
- Str idtag;
-#endif /* ID_EXT */
-
- if (t->maxcol < 0) {
- make_caption(t, h_env);
- return;
- }
-
- max_width -= table_border_width(t);
-
- if (max_width <= 0)
- max_width = 1;
-
- check_maximum_width(t);
-
-#ifdef MATRIX
- if (t->maxcol == 0) {
- if (t->tabwidth[0] > max_width)
- t->tabwidth[0] = max_width;
- if (t->total_width > 0)
- t->tabwidth[0] = max_width;
- else if (t->fixed_width[0] > 0)
- t->tabwidth[0] = t->fixed_width[0];
- if (t->tabwidth[0] < t->minimum_width[0])
- t->tabwidth[0] = t->minimum_width[0];
- }
- else {
- set_table_matrix(t, max_width);
-
- itr = 0;
- mat = m_get(t->maxcol + 1, t->maxcol + 1);
- pivot = px_get(t->maxcol + 1);
- newwidth = v_get(t->maxcol + 1);
- minv = m_get(t->maxcol + 1, t->maxcol + 1);
- do {
- m_copy(t->matrix, mat);
- LUfactor(mat, pivot);
- LUsolve(mat, pivot, t->vector, newwidth);
- dv2sv(newwidth->ve, new_tabwidth, t->maxcol + 1);
- LUinverse(mat, pivot, minv);
-#ifdef TABLE_DEBUG
- fprintf(stderr, "max_width=%d\n", max_width);
- fprintf(stderr, "minimum : ");
- for (i = 0; i <= t->maxcol; i++)
- fprintf(stderr, "%2d ", t->minimum_width[i]);
- fprintf(stderr, "\ndecided : ");
- for (i = 0; i <= t->maxcol; i++)
- fprintf(stderr, "%2d ", new_tabwidth[i]);
- fprintf(stderr, "\n");
-#endif /* TABLE_DEBUG */
- itr++;
-
- } while (check_table_width(t, new_tabwidth, minv, itr));
- v_free(newwidth);
- px_free(pivot);
- m_free(mat);
- m_free(minv);
- m_free(t->matrix);
- v_free(t->vector);
- for (i = 0; i <= t->maxcol; i++) {
- t->tabwidth[i] = new_tabwidth[i];
- }
- }
-#else /* not MATRIX */
- set_table_width(t, new_tabwidth, max_width);
- for (i = 0; i <= t->maxcol; i++) {
- t->tabwidth[i] = new_tabwidth[i];
- }
-#endif /* not MATRIX */
-
- renderCoTable(t);
- check_minimum_width(t, t->tabwidth);
-
- t->total_width = 0;
- for (i = 0; i <= t->maxcol; i++) {
- if (t->border_mode != BORDER_NONE && t->tabwidth[i] % RULE_WIDTH == 1)
- t->tabwidth[i]++;
- t->total_width += t->tabwidth[i];
- }
-
- t->total_width += table_border_width(t);
-
- for (i = 0; i <= t->maxcol; i++) {
- for (j = 0; j <= t->maxrow; j++) {
- check_row(t, j);
- if (t->tabattr[j][i] & HTT_Y)
- continue;
- do_refill(t, j, i);
- }
- }
-
- check_table_height(t);
-
- /* table output */
- make_caption(t, h_env);
-
- HTMLlineproc1("<pre for_table>", h_env);
-#ifdef ID_EXT
- if (t->id != NULL) {
- idtag = Sprintf("<_id id=\"%s\">", (t->id)->ptr);
- HTMLlineproc1(idtag->ptr, h_env);
- }
-#endif /* ID_EXT */
- switch (t->border_mode) {
- case BORDER_THIN:
- case BORDER_THICK:
- renderbuf = Strnew();
- print_sep(t, -1, T_TOP, t->maxcol, renderbuf);
- HTMLlineproc1(renderbuf->ptr, h_env);
- maxheight += 1;
- break;
- }
- vruleb = Strnew();
- switch (t->border_mode) {
- case BORDER_THIN:
- case BORDER_THICK:
- vrulea = Strnew();
- vrulec = Strnew();
- Strcat_charp(vrulea, TK_VERTICALBAR(t->border_mode));
- for (i = 0; i < t->cellpadding; i++) {
- Strcat_char(vrulea, ' ');
- Strcat_char(vruleb, ' ');
- Strcat_char(vrulec, ' ');
- }
- Strcat_charp(vrulec, TK_VERTICALBAR(t->border_mode));
- case BORDER_NOWIN:
-#if defined(__EMX__)&&!defined(JP_CHARSET)
- Strcat_charp(vruleb, CodePage==850?"³":TN_VERTICALBAR);
-#else
- Strcat_charp(vruleb, TN_VERTICALBAR);
-#endif
- for (i = 0; i < t->cellpadding; i++)
- Strcat_char(vruleb, ' ');
- break;
- case BORDER_NONE:
- for (i = 0; i < t->cellspacing; i++)
- Strcat_char(vruleb, ' ');
- }
-
- for (r = 0; r <= t->maxrow; r++) {
- for (h = 0; h < t->tabheight[r]; h++) {
- renderbuf = Strnew();
- if (t->border_mode == BORDER_THIN || t->border_mode == BORDER_THICK)
- Strcat(renderbuf, vrulea);
-#ifdef ID_EXT
- if (t->tridvalue[r] != NULL && h == 0) {
- idtag = Sprintf("<_id id=\"%s\">", (t->tridvalue[r])->ptr);
- Strcat(renderbuf, idtag);
- }
-#endif /* ID_EXT */
- for (i = 0; i <= t->maxcol; i++) {
- check_row(t, r);
-#ifdef ID_EXT
- if (t->tabidvalue[r][i] != NULL && h == 0) {
- idtag = Sprintf("<_id id=\"%s\">", (t->tabidvalue[r][i])->ptr);
- Strcat(renderbuf, idtag);
- }
-#endif /* ID_EXT */
- if (!(t->tabattr[r][i] & HTT_X)) {
- w = t->tabwidth[i];
- for (j = i + 1;
- j <= t->maxcol && (t->tabattr[r][j] & HTT_X);
- j++)
- w += t->tabwidth[j] + t->cellspacing;
- if (t->tabattr[r][i] & HTT_Y) {
- for (j = r - 1;
- j >= 0 && t->tabattr[j] && (t->tabattr[j][i] & HTT_Y);
- j--);
- print_item(t, j, i, w, renderbuf);
- }
- else
- print_item(t, r, i, w, renderbuf);
- }
- if (i < t->maxcol && !(t->tabattr[r][i + 1] & HTT_X))
- Strcat(renderbuf, vruleb);
- }
- switch (t->border_mode) {
- case BORDER_THIN:
- case BORDER_THICK:
- Strcat(renderbuf, vrulec);
- Strcat_charp(renderbuf, "<eol>");
- maxheight += 1;
- break;
- case BORDER_NONE:
- case BORDER_NOWIN:
- Strcat_charp(renderbuf, "<eol>");
- break;
- }
- HTMLlineproc1(renderbuf->ptr, h_env);
- }
- if (r < t->maxrow && t->border_mode != BORDER_NONE) {
- renderbuf = Strnew();
- print_sep(t, r, T_MIDDLE, t->maxcol, renderbuf);
- HTMLlineproc1(renderbuf->ptr, h_env);
- }
- maxheight += t->tabheight[r];
- }
- if (t->border_mode == BORDER_THIN || t->border_mode == BORDER_THICK) {
- renderbuf = Strnew();
- print_sep(t, t->maxrow, T_BOTTOM, t->maxcol, renderbuf);
- HTMLlineproc1(renderbuf->ptr, h_env);
- maxheight += 1;
- }
- if (maxheight == 0)
- HTMLlineproc1(" <eol>", h_env);
- HTMLlineproc1("</pre>", h_env);
-}
-
-
-struct table *
-begin_table(int border, int spacing, int padding)
-{
- struct table *t;
- int mincell = minimum_cellspacing(border);
-
- t = newTable();
- t->row = t->col = -1;
- t->maxcol = -1;
- t->maxrow = -1;
- t->border_mode = border;
- t->flag = 0;
- if (border == BORDER_NOWIN)
- t->flag |= TBL_EXPAND_OK;
- t->cellspacing = max(spacing, mincell);
- switch (border) {
- case BORDER_THIN:
- case BORDER_THICK:
- case BORDER_NOWIN:
- t->cellpadding = (t->cellspacing - mincell) / 2;
- break;
- case BORDER_NONE:
- t->cellpadding = t->cellspacing - mincell;
- }
-
- if (padding > t->cellpadding)
- t->cellpadding = padding;
-
- switch (border) {
- case BORDER_THIN:
- case BORDER_THICK:
- case BORDER_NOWIN:
- t->cellspacing = 2 * t->cellpadding + mincell;
- break;
- case BORDER_NONE:
- t->cellspacing = t->cellpadding + mincell;
- }
- return t;
-}
-
-static void
-check_minimum0(struct table *t, int min)
-{
- int i, w, ww;
- struct table_cell *cell;
-
- if (t->col < 0)
- return;
- if (t->tabwidth[t->col] < 0)
- return;
- check_row(t, t->row);
- w = table_colspan(t, t->row, t->col);
- min += t->indent;
- if (w == 1)
- ww = min;
- else {
- cell = &t->cell;
- ww = 0;
- if (cell->icell >= 0 && cell->minimum_width[cell->icell] < min)
- cell->minimum_width[cell->icell] = min;
- }
- for (i = t->col;
- i <= t->maxcol && (i == t->col || (t->tabattr[t->row][i] & HTT_X));
- i++) {
- if (t->minimum_width[i] < ww)
- t->minimum_width[i] = ww;
- }
-}
-
-static int
-setwidth0(struct table *t, struct table_mode *mode)
-{
- int w;
- int width = t->tabcontentssize;
- struct table_cell *cell = &t->cell;
-
- if (t->col < 0)
- return -1;
- if (t->tabwidth[t->col] < 0)
- return -1;
- check_row(t, t->row);
- if (t->linfo.prev_spaces > 0)
- width -= t->linfo.prev_spaces;
- w = table_colspan(t, t->row, t->col);
- if (w == 1) {
- if (t->tabwidth[t->col] < width)
- t->tabwidth[t->col] = width;
- }
- else if (cell->icell >= 0) {
- if (cell->width[cell->icell] < width)
- cell->width[cell->icell] = width;
- }
- return width;
-}
-
-static void
-setwidth(struct table *t, struct table_mode *mode)
-{
- int width = setwidth0(t, mode);
- if (width < 0)
- return;
-#ifdef NOWRAP
- if (t->tabattr[t->row][t->col] & HTT_NOWRAP)
- check_minimum0(t, width);
-#endif /* NOWRAP */
- if (mode->pre_mode & (TBLM_NOBR | TBLM_PRE | TBLM_PRE_INT) &&
- mode->nobr_offset >= 0)
- check_minimum0(t, width - mode->nobr_offset);
-}
-
-static void
-addcontentssize(struct table *t, int width)
-{
-
- if (t->col < 0)
- return;
- if (t->tabwidth[t->col] < 0)
- return;
- check_row(t, t->row);
- t->tabcontentssize += width;
-}
-
-static void
-clearcontentssize(struct table *t, struct table_mode *mode)
-{
- mode->nobr_offset = 0;
- t->linfo.prev_spaces = -1;
- t->linfo.prevchar = ' ';
- t->tabcontentssize = 0;
-}
-
-void
-check_rowcol(struct table *tbl)
-{
- if (!(tbl->flag & TBL_IN_ROW)) {
- tbl->flag |= TBL_IN_ROW;
- tbl->row++;
- if (tbl->row > tbl->maxrow)
- tbl->maxrow = tbl->row;
- tbl->col = -1;
- }
- if (tbl->row == -1)
- tbl->row = 0;
- if (tbl->col == -1)
- tbl->col = 0;
-
- for (;; tbl->row++) {
- check_row(tbl, tbl->row);
- for (; tbl->col < MAXCOL &&
- tbl->tabattr[tbl->row][tbl->col] & (HTT_X | HTT_Y);
- tbl->col++);
- if (tbl->col < MAXCOL)
- break;
- tbl->col = 0;
- }
- if (tbl->row > tbl->maxrow)
- tbl->maxrow = tbl->row;
- if (tbl->col > tbl->maxcol)
- tbl->maxcol = tbl->col;
-
- tbl->flag |= TBL_IN_COL;
-}
-
-int
-skip_space(struct table *t, char *line, struct table_linfo *linfo,
- int checkminimum)
-{
- int skip = 0, s = linfo->prev_spaces;
- Lineprop ctype = linfo->prev_ctype, prev_ctype;
- char prevchar = linfo->prevchar;
- int w = (linfo->prev_spaces == -1) ? 0 : linfo->length;
- int min = 1;
-
- if (*line == '<' && line[strlen(line) - 1] == '>') {
- if (checkminimum)
- check_minimum0(t, visible_length(line));
- return 0;
- }
-
- while (*line) {
- char c = *line, *save = line;
- int ec = '\0', len = 1, wlen = 1;
- prev_ctype = ctype;
- ctype = get_ctype(c, prev_ctype);
- if (min < w)
- min = w;
- if (ctype == PC_ASCII && IS_SPACE(c)) {
- w = 0;
- s++;
- }
- else {
- if (c == '&') {
- ec = getescapechar(&line);
- if (ec) {
- c = ec;
- if (IS_CNTRL(ec))
- ctype = PC_CTRL;
- else
- ctype = PC_ASCII;
- len = strlen(conv_latin1(ec));
- wlen = line - save;
- }
- }
- if (prevchar && is_boundary(prevchar, prev_ctype, c, ctype)) {
- w = len;
- }
- else {
- w += len;
- }
- if (s > 0) {
-#ifdef JP_CHARSET
- if (ctype == PC_KANJI1 && prev_ctype == PC_KANJI2)
- skip += s;
- else
-#endif /* JP_CHARSET */
- skip += s - 1;
- }
- s = 0;
- }
- prevchar = c;
- line = save + wlen;
- }
- if (s > 1) {
- skip += s - 1;
- linfo->prev_spaces = 1;
- }
- else {
- linfo->prev_spaces = s;
- }
- linfo->prev_ctype = ctype;
- linfo->prevchar = prevchar;
-
- if (checkminimum) {
- if (min < w)
- min = w;
- linfo->length = w;
- check_minimum0(t, min);
- }
- return skip;
-}
-
-#define TAG_ACTION_NONE 0
-#define TAG_ACTION_FEED 1
-#define TAG_ACTION_TABLE 2
-#define TAG_ACTION_N_TABLE 3
-
-static int
-feed_table_tag(struct table *tbl, char *line, struct table_mode *mode, int width)
-{
- int cmd;
- char *s_line;
- struct table_cell *cell = &tbl->cell;
- struct parsed_tagarg *t_arg, *t;
- int colspan, rowspan;
- int col, prev_col;
- int i, j, k, v, v0, w, id, status;
- Str tok, tmp, anchor;
- table_attr align;
-
- s_line = line;
- cmd = gethtmlcmd(&s_line, &status);
-
- if (mode->pre_mode & TBLM_IGNORE) {
- switch (cmd) {
- case HTML_N_STYLE:
- mode->pre_mode &= ~TBLM_STYLE;
- case HTML_N_SCRIPT:
- mode->pre_mode &= ~TBLM_SCRIPT;
- default:
- return TAG_ACTION_NONE;
- }
- }
-
-#ifdef MENU_SELECT
- /* failsafe: a tag other than <option></option>and </select> in *
- * <select> environment is regarded as the end of <select>. */
- if (mode->pre_mode & TBLM_INSELECT) {
- switch (cmd) {
- case HTML_TABLE:
- case HTML_N_TABLE:
- case HTML_TR:
- case HTML_N_TR:
- case HTML_TD:
- case HTML_N_TD:
- case HTML_TH:
- case HTML_N_TH:
- case HTML_THEAD:
- case HTML_N_THEAD:
- case HTML_TBODY:
- case HTML_N_TBODY:
- case HTML_TFOOT:
- case HTML_N_TFOOT:
- case HTML_COLGROUP:
- case HTML_N_COLGROUP:
- case HTML_COL:
- mode->pre_mode &= ~TBLM_INSELECT;
- tmp = process_n_select();
- feed_table1(tbl, tmp, mode, width);
- }
- }
-#endif /* MENU_SELECT */
-
- switch (cmd) {
- case HTML_TABLE:
- return TAG_ACTION_TABLE;
- case HTML_N_TABLE:
- return TAG_ACTION_N_TABLE;
- case HTML_TR:
- if (tbl->col >= 0 && tbl->tabcontentssize > 0)
- setwidth(tbl, mode);
- clearcontentssize(tbl, mode);
- mode->caption = 0;
- mode->indent_level = 0;
- mode->nobr_level = 0;
- mode->mode_level = 0;
- mode->pre_mode = 0;
- tbl->col = -1;
- tbl->row++;
- tbl->flag |= TBL_IN_ROW;
- tbl->indent = 0;
- align = 0;
- t_arg = parse_tag(line + 3);
- for (t = t_arg; t; t = t->next) {
- if (!strcasecmp(t->arg, "align") && t->value) {
- if (!strcasecmp(t->value, "left"))
- align = (HTT_LEFT | HTT_TRSET);
- else if (!strcasecmp(t->value, "right"))
- align = (HTT_RIGHT | HTT_TRSET);
- else if (!strcasecmp(t->value, "center"))
- align = (HTT_CENTER | HTT_TRSET);
- }
-#ifdef ID_EXT
- if (!strcasecmp(t->arg, "id") && t->value) {
- tbl->tridvalue[tbl->row] = Strnew_charp(t->value);
- }
-#endif /* ID_EXT */
- }
- tbl->trattr = align;
- break;
- case HTML_TH:
- case HTML_TD:
- prev_col = tbl->col;
- if (tbl->col >= 0 && tbl->tabcontentssize > 0)
- setwidth(tbl, mode);
- clearcontentssize(tbl, mode);
- mode->caption = 0;
- mode->indent_level = 0;
- mode->nobr_level = 0;
- mode->mode_level = 0;
- mode->pre_mode = 0;
- tbl->flag |= TBL_IN_COL;
- tbl->linfo.prev_spaces = -1;
- tbl->linfo.prevchar = ' ';
- tbl->linfo.prev_ctype = PC_ASCII;
- tbl->indent = 0;
- if (tbl->row == -1) {
- /* for broken HTML... */
- tbl->row = -1;
- tbl->col = -1;
- tbl->maxrow = tbl->row;
- }
- if (tbl->col == -1) {
- if (!(tbl->flag & TBL_IN_ROW)) {
- tbl->row++;
- tbl->flag |= TBL_IN_ROW;
- }
- if (tbl->row > tbl->maxrow)
- tbl->maxrow = tbl->row;
- }
- tbl->col++;
- check_row(tbl, tbl->row);
- while (tbl->tabattr[tbl->row][tbl->col]) {
- tbl->col++;
- }
- if (tbl->col > MAXCOL - 1) {
- tbl->col = prev_col;
- return TAG_ACTION_NONE;
- }
- if (tbl->col > tbl->maxcol) {
- tbl->maxcol = tbl->col;
- }
- tbl->height = 0;
- t_arg = parse_tag(line + 3);
- colspan = rowspan = 1;
- v = 0;
- if (tbl->trattr & HTT_TRSET)
- align = (tbl->trattr & HTT_ALIGN);
- else if (cmd == HTML_TH)
- align = HTT_CENTER;
- else
- align = HTT_LEFT;
- for (t = t_arg; t; t = t->next) {
- if (!strcasecmp(t->arg, "rowspan") && t->value) {
- rowspan = atoi(t->value);
- if ((tbl->row + rowspan) >= tbl->max_rowsize)
- check_row(tbl, tbl->row + rowspan);
- }
- else if (!strcasecmp(t->arg, "colspan") && t->value) {
- colspan = atoi(t->value);
- if ((tbl->col + colspan) >= MAXCOL) {
- /* Can't expand column */
- colspan = MAXCOL - tbl->col;
- }
- }
- else if (!strcasecmp(t->arg, "align") && t->value) {
- if (!strcasecmp(t->value, "left"))
- align = HTT_LEFT;
- else if (!strcasecmp(t->value, "right"))
- align = HTT_RIGHT;
- else if (!strcasecmp(t->value, "center"))
- align = HTT_CENTER;
- }
-#ifdef NOWRAP
- else if (!strcasecmp(t->arg, "nowrap"))
- tbl->tabattr[tbl->row][tbl->col] |= HTT_NOWRAP;
-#endif /* NOWRAP */
- else if (!strcasecmp(t->arg, "width") && t->value) {
- if (IS_DIGIT(*t->value)) {
- v = atoi(t->value);
- if (v == 0)
- v = 1;
- else if (v < 0)
- v = 0;
- if (t->value[strlen(t->value) - 1] == '%') {
- v = -v;
- }
- else {
-#ifdef TABLE_EXPAND
- v = max(v / tbl->ppc, 1);
-#else /* not TABLE_EXPAND */
- v = v / PIXEL_PER_CHAR;
-#endif /* not TABLE_EXPAND */
- }
- }
- else
- continue;
-#ifdef ID_EXT
- }
- else if (!strcasecmp(t->arg, "id") && t->value) {
- tbl->tabidvalue[tbl->row][tbl->col] = Strnew_charp(t->value);
-#endif /* ID_EXT */
- }
- }
-#ifdef NOWRAP
- if (v != 0) {
- /* NOWRAP and WIDTH= conflicts each other */
- tbl->tabattr[tbl->row][tbl->col] &= ~HTT_NOWRAP;
- }
-#endif /* NOWRAP */
- tbl->tabattr[tbl->row][tbl->col] &= ~HTT_ALIGN;
- tbl->tabattr[tbl->row][tbl->col] |= align;
- if (colspan > 1) {
- col = tbl->col;
-
- cell->icell = cell->maxcell + 1;
- k = dsort_index(colspan, cell->colspan, col, cell->col, MAXCOL,
- cell->index, cell->icell);
- if (k <= cell->maxcell) {
- i = cell->index[k];
- if (cell->col[i] == col &&
- cell->colspan[i] == colspan)
- cell->icell = i;
- }
- if (cell->icell > cell->maxcell && cell->icell < MAXCELL) {
- cell->maxcell++;
- cell->col[cell->maxcell] = col;
- cell->colspan[cell->maxcell] = colspan;
- cell->width[cell->maxcell] = 0;
- cell->minimum_width[cell->maxcell] = 0;
- cell->fixed_width[cell->maxcell] = 0;
- if (cell->maxcell > k)
- bcopy(cell->index + k, cell->index + k + 1, cell->maxcell - k);
- cell->index[k] = cell->maxcell;
- }
- if (cell->icell > cell->maxcell)
- cell->icell = -1;
- }
- if (v != 0) {
- if (colspan == 1) {
- v0 = tbl->fixed_width[tbl->col];
- if (v0 == 0 || (v0 > 0 && v > v0) || (v0 < 0 && v < v0)) {
-#ifdef TABLE_DEBUG
- fprintf(stderr, "width(%d) = %d\n", tbl->col, v);
-#endif /* TABLE_DEBUG */
- tbl->fixed_width[tbl->col] = v;
- }
- }
- else if (cell->icell >= 0) {
- v0 = cell->fixed_width[cell->icell];
- if (v0 == 0 || (v0 > 0 && v > v0) || (v0 < 0 && v < v0))
- cell->fixed_width[cell->icell] = v;
- }
- }
- for (i = 0; i < rowspan; i++) {
- check_row(tbl, tbl->row + i);
- for (j = 0; j < colspan; j++) {
- tbl->tabattr[tbl->row + i][tbl->col + j] &= ~(HTT_X | HTT_Y);
- tbl->tabattr[tbl->row + i][tbl->col + j] |=
- ((i > 0) ? HTT_Y : 0) | ((j > 0) ? HTT_X : 0);
- if (tbl->col + j > tbl->maxcol) {
- tbl->maxcol = tbl->col + j;
- }
- }
- if (tbl->row + i > tbl->maxrow) {
- tbl->maxrow = tbl->row + i;
- }
- }
- break;
- case HTML_N_TR:
- setwidth(tbl, mode);
- tbl->col = -1;
- tbl->flag &= ~(TBL_IN_ROW | TBL_IN_COL);
- return TAG_ACTION_NONE;
- case HTML_N_TH:
- case HTML_N_TD:
- setwidth(tbl, mode);
- tbl->flag &= ~TBL_IN_COL;
-#ifdef TABLE_DEBUG
- {
- TextListItem *it;
- int i = tbl->col, j = tbl->row;
- fprintf(stderr, "(a) row,col: %d, %d\n", j, i);
- if (tbl->tabdata[j] && tbl->tabdata[j][i]) {
- for (it = tbl->tabdata[j][i]->first; it; it = it->next)
- fprintf(stderr, " [%s] \n", it->ptr);
- }
- }
-#endif
- return TAG_ACTION_NONE;
- case HTML_P:
- case HTML_BR:
- case HTML_DT:
- case HTML_DD:
- case HTML_CENTER:
- case HTML_N_CENTER:
- case HTML_DIV:
- case HTML_N_DIV:
- case HTML_H:
- case HTML_N_H:
- check_rowcol(tbl);
- pushdata(tbl, tbl->row, tbl->col, line);
- setwidth(tbl, mode);
- clearcontentssize(tbl, mode);
- if (cmd == HTML_DD)
- addcontentssize(tbl, tbl->indent);
- break;
- case HTML_DL:
- case HTML_BLQ:
- case HTML_OL:
- case HTML_UL:
- check_rowcol(tbl);
- pushdata(tbl, tbl->row, tbl->col, line);
- setwidth(tbl, mode);
- clearcontentssize(tbl, mode);
- mode->indent_level++;
- if (mode->indent_level <= MAX_INDENT_LEVEL)
- tbl->indent += INDENT_INCR;
- if (cmd == HTML_BLQ) {
- check_minimum0(tbl, 0);
- addcontentssize(tbl, tbl->indent);
- }
- break;
- case HTML_N_DL:
- case HTML_N_BLQ:
- case HTML_N_OL:
- case HTML_N_UL:
- if (mode->indent_level > 0) {
- check_rowcol(tbl);
- pushdata(tbl, tbl->row, tbl->col, line);
- setwidth(tbl, mode);
- clearcontentssize(tbl, mode);
- mode->indent_level--;
- if (mode->indent_level < MAX_INDENT_LEVEL)
- tbl->indent -= INDENT_INCR;
- }
- break;
- case HTML_LI:
- check_rowcol(tbl);
- pushdata(tbl, tbl->row, tbl->col, line);
- setwidth(tbl, mode);
- clearcontentssize(tbl, mode);
- check_minimum0(tbl, 0);
- addcontentssize(tbl, tbl->indent);
- break;
- case HTML_PRE:
- case HTML_LISTING:
- case HTML_XMP:
- setwidth(tbl, mode);
- check_rowcol(tbl);
- clearcontentssize(tbl, mode);
- pushdata(tbl, tbl->row, tbl->col, line);
- mode->pre_mode |= TBLM_PRE;
- mode->mode_level++;
- break;
- case HTML_N_PRE:
- case HTML_N_LISTING:
- case HTML_N_XMP:
- setwidth(tbl, mode);
- check_rowcol(tbl);
- clearcontentssize(tbl, mode);
- pushdata(tbl, tbl->row, tbl->col, line);
- if (mode->mode_level > 0)
- mode->mode_level--;
- if (mode->mode_level == 0)
- mode->pre_mode &= ~TBLM_PRE;
- tbl->linfo.prev_spaces = 0;
- tbl->linfo.prevchar = '\0';
- tbl->linfo.prev_ctype = PC_ASCII;
- break;
- case HTML_NOBR:
- check_rowcol(tbl);
- pushdata(tbl, tbl->row, tbl->col, line);
- if (!(mode->pre_mode & TBLM_NOBR)) {
- mode->nobr_offset = -1;
- mode->pre_mode |= TBLM_NOBR;
- }
- mode->nobr_level++;
- break;
- case HTML_WBR:
- check_rowcol(tbl);
- pushdata(tbl, tbl->row, tbl->col, line);
- mode->nobr_offset = -1;
- break;
- case HTML_N_NOBR:
- if (mode->nobr_level > 0)
- mode->nobr_level--;
- check_rowcol(tbl);
- pushdata(tbl, tbl->row, tbl->col, line);
- if (mode->nobr_level == 0)
- mode->pre_mode &= ~TBLM_NOBR;
- break;
- case HTML_PRE_INT:
- check_rowcol(tbl);
- pushdata(tbl, tbl->row, tbl->col, line);
- if (!(mode->pre_mode & TBLM_PRE_INT)) {
- mode->nobr_offset = -1;
- mode->pre_mode |= TBLM_PRE_INT;
- }
- tbl->linfo.prev_spaces = 0;
- break;
- case HTML_N_PRE_INT:
- check_rowcol(tbl);
- pushdata(tbl, tbl->row, tbl->col, line);
- mode->pre_mode &= ~TBLM_PRE_INT;
- break;
- case HTML_IMG:
- tok = process_img(parse_tag(line + 3));
- feed_table1(tbl, tok, mode, width);
- break;
-#ifdef NEW_FORM
- case HTML_FORM:
- process_form(parse_tag(line));
- break;
- case HTML_N_FORM:
- process_n_form();
- break;
-#else /* not NEW_FORM */
- case HTML_FORM:
- case HTML_N_FORM:
- check_rowcol(tbl);
- pushdata(tbl, tbl->row, tbl->col, "<br>");
- setwidth(tbl, mode);
- clearcontentssize(tbl, mode);
- if (line[1] == '/') {
- tok = Strnew_charp("</form_int ");
- Strcat_charp(tok, line + 6);
- }
- else {
- tok = Strnew_charp("<form_int ");
- Strcat_charp(tok, line + 5);
- }
- pushdata(tbl, tbl->row, tbl->col, tok->ptr);
- break;
-#endif /* not NEW_FORM */
- case HTML_INPUT:
- tmp = process_input(parse_tag(line + 6));
- feed_table1(tbl, tmp, mode, width);
- break;
- case HTML_SELECT:
- t_arg = parse_tag(line + 7);
- tmp = process_select(t_arg);
- feed_table1(tbl, tmp, mode, width);
-#ifdef MENU_SELECT
- if (!tag_exists(t_arg, "multiple")) /* non-multiple select */
- mode->pre_mode |= TBLM_INSELECT;
-#endif /* MENU_SELECT */
- break;
- case HTML_N_SELECT:
-#ifdef MENU_SELECT
- mode->pre_mode &= ~TBLM_INSELECT;
-#endif /* MENU_SELECT */
- tmp = process_n_select();
- feed_table1(tbl, tmp, mode, width);
- break;
- case HTML_OPTION:
- tmp = process_option(parse_tag(line + 7));
- if (tmp)
- feed_table1(tbl, tmp, mode, width);
-#ifdef MENU_SELECT
- else
- feed_select(line);
-#endif /* MENU_SELECT */
- break;
- case HTML_TEXTAREA:
- w = 0;
- check_rowcol(tbl);
- if (tbl->col + 1 <= tbl->maxcol &&
- tbl->tabattr[tbl->row][tbl->col + 1] & HTT_X) {
- if (cell->icell >= 0 && cell->fixed_width[cell->icell] > 0)
- w = cell->fixed_width[cell->icell];
- }
- else {
- if (tbl->fixed_width[tbl->col] > 0)
- w = tbl->fixed_width[tbl->col];
- }
- tmp = process_textarea(parse_tag(line + 9), w);
- feed_table1(tbl, tmp, mode, width);
- mode->pre_mode |= TBLM_INTXTA;
- break;
- case HTML_N_TEXTAREA:
- mode->pre_mode &= ~TBLM_INTXTA;
- tmp = process_n_textarea();
- feed_table1(tbl, tmp, mode, width);
- break;
- case HTML_A:
- anchor = NULL;
- check_rowcol(tbl);
- t_arg = parse_tag(line + 2);
- i = 0;
- for (t = t_arg; t; t = t->next) {
- if (strcasecmp(t->arg, "href") == 0 && t->value) {
- anchor = Strnew_charp(t->value);
- }
- else if (strcasecmp(t->arg, "hseq") == 0 && t->value) {
- i = atoi(t->value);
- }
- }
- if (i == 0 && anchor) {
- Str tmp = process_anchor(line);
- pushdata(tbl, tbl->row, tbl->col, tmp->ptr);
- if (mode->pre_mode & (TBLM_PRE | TBLM_NOBR))
- addcontentssize(tbl, 1);
- else
- check_minimum0(tbl, 1);
- setwidth(tbl, mode);
- }
- else {
- pushdata(tbl, tbl->row, tbl->col, line);
- }
- break;
- case HTML_DEL:
- case HTML_N_DEL:
- case HTML_INS:
- case HTML_N_INS:
- pushdata(tbl, tbl->row, tbl->col, line);
- i = 5;
- check_minimum0(tbl, i);
- addcontentssize(tbl, i);
- setwidth(tbl, mode);
- break;
- case HTML_DUMMY_TABLE:
- id = -1;
- w = 0;
- t_arg = parse_tag(line + 12);
- for (t = t_arg; t; t = t->next) {
- if (!strcasecmp(t->arg, "id") && t->value) {
- id = atoi(t->value);
- }
- else if (!strcasecmp(t->arg, "width") && t->value) {
- w = atoi(t->value);
- }
- }
- if (id >= 0) {
- setwidth(tbl, mode);
- check_rowcol(tbl);
- pushdata(tbl, tbl->row, tbl->col, line);
- clearcontentssize(tbl, mode);
- addcontentssize(tbl, maximum_table_width(tbl->tables[id].ptr));
- check_minimum0(tbl, minimum_table_width(tbl->tables[id].ptr));
- if (w > 0)
- check_minimum0(tbl, w);
- else
- check_minimum0(tbl, fixed_table_width(tbl->tables[id].ptr));
- setwidth0(tbl, mode);
- clearcontentssize(tbl, mode);
- }
- break;
- case HTML_CAPTION:
- mode->caption = 1;
- break;
- case HTML_N_CAPTION:
- mode->caption = 0;
- break;
- case HTML_THEAD:
- case HTML_N_THEAD:
- case HTML_TBODY:
- case HTML_N_TBODY:
- case HTML_TFOOT:
- case HTML_N_TFOOT:
- case HTML_COLGROUP:
- case HTML_N_COLGROUP:
- case HTML_COL:
- break;
- case HTML_SCRIPT:
- mode->pre_mode |= TBLM_SCRIPT;
- break;
- case HTML_STYLE:
- mode->pre_mode |= TBLM_STYLE;
- break;
- default:
- /* unknown tag: put into table */
- return TAG_ACTION_FEED;
- }
- return TAG_ACTION_NONE;
-}
-
-
-int
-feed_table(struct table *tbl, char **tline, struct table_mode *mode, int width)
-{
- int i;
- char *line;
- char *p;
- Str tok, tmp;
- struct table_linfo *linfo = &tbl->linfo;
-
- if (*tline == NULL || **tline == '\0')
- return -1;
-
- tok = Strnew();
- if (tbl->suspended_input->length > 0) {
- Strcat_charp(tbl->suspended_input, *tline);
- *tline = tbl->suspended_input->ptr;
- tbl->suspended_input = Strnew();
- tbl->status = R_ST_NORMAL;
- }
- while (read_token(tok, tline, &tbl->status, mode->pre_mode & TBLM_PREMODE, 0)) {
- if (ST_IS_COMMENT(tbl->status)) {
- continue;
- }
- else if (tbl->status != R_ST_NORMAL) {
- /* line ended within tag */
- int l = tok->length;
- if (tok->ptr[l - 1] == '\n') {
- Strchop(tok);
- if (ST_IS_REAL_TAG(tbl->status))
- Strcat_char(tok, ' ');
- }
- tbl->suspended_input = Strdup(tok);
- return -1;
- }
- line = tok->ptr;
- if (mode->caption && !TAG_IS(line, "</caption", 9)) {
- Strcat(tbl->caption, tok);
- continue;
- }
- if (*line == '<') {
- int action = feed_table_tag(tbl, line, mode, width);
- if (action == TAG_ACTION_NONE)
- continue;
- else if (action == TAG_ACTION_N_TABLE)
- return 0;
- else if (action == TAG_ACTION_TABLE) {
- *tline -= tok->length;
- return 1;
- }
- }
- if (mode->pre_mode & TBLM_IGNORE)
- continue;
- if (mode->pre_mode & TBLM_INTXTA) {
- feed_textarea(line);
- continue;
- }
-#ifdef MENU_SELECT
- if (mode->pre_mode & TBLM_INSELECT) {
- feed_select(line);
- continue;
- }
-#endif /* MENU_SELECT */
- /* convert &...; if it is latin-1 character */
- if (!(*line == '<' && line[strlen(line) - 1] == '>') &&
- strchr(line, '&') != NULL) {
- tmp = Strnew();
- for (p = line; *p;) {
- char *q, *r;
- if (*p == '&') {
- if (!strncasecmp(p, "&amp;", 5) ||
- !strncasecmp(p, "&gt;", 4) ||
- !strncasecmp(p, "&lt;", 4)) {
- /* do not convert */
- Strcat_char(tmp, *p);
- p++;
- }
- else {
- q = p;
- r = getescapecmd(&p);
- if (r != NULL && ((*r & 0x80) || IS_CNTRL(*r))) {
- /* latin-1 character */
- Strcat_charp(tmp, r);
- }
- else {
- Strcat_char(tmp, *q);
- p = q + 1;
- }
- }
- }
- else {
- Strcat_char(tmp, *p);
- p++;
- }
- }
- line = tmp->ptr;
- }
- if (!(mode->pre_mode & (TBLM_PRE | TBLM_PRE_INT))) {
- if (!(tbl->flag & TBL_IN_COL)) {
- linfo->prev_spaces = -1;
- linfo->prev_ctype = PC_ASCII;
- }
- if (linfo->prev_spaces != 0)
- while (IS_SPACE(*line))
- line++;
- if (*line == '\0')
- continue;
- check_rowcol(tbl);
- if (mode->pre_mode & TBLM_NOBR && mode->nobr_offset < 0)
- mode->nobr_offset = tbl->tabcontentssize;
-
- /* count of number of spaces skipped in normal mode */
- i = skip_space(tbl, line, linfo, !(mode->pre_mode & TBLM_NOBR));
- addcontentssize(tbl, visible_length(line) - i);
- setwidth(tbl, mode);
- }
- else {
- /* <pre> mode or something like it */
- check_rowcol(tbl);
- if (mode->pre_mode & TBLM_PRE_INT && mode->nobr_offset < 0)
- mode->nobr_offset = tbl->tabcontentssize;
- i = maximum_visible_length(line);
- addcontentssize(tbl, i);
- setwidth(tbl, mode);
- if (!(mode->pre_mode & TBLM_PRE_INT)) {
- p = line + strlen(line) - 1;
- if (*p == '\r' || *p == '\n')
- clearcontentssize(tbl, mode);
- }
- }
- pushdata(tbl, tbl->row, tbl->col, line);
- }
- if (ST_IS_COMMENT(tbl->status))
- return 2;
- else
- return -1;
-}
-
-void
-feed_table1(struct table *tbl, Str tok, struct table_mode *mode, int width)
-{
- char *p;
- if (!tok)
- return;
- p = tok->ptr;
- feed_table(tbl, &p, mode, width);
-}
-
-void
-pushTable(struct table *tbl, struct table *tbl1)
-{
- int col;
- int row;
-
- check_rowcol(tbl);
- col = tbl->col;
- row = tbl->row;
-
- if (tbl->ntable >= tbl->tables_size) {
- struct table_in *tmp;
- tbl->tables_size += MAX_TABLE_N;
- tmp = New_N(struct table_in, tbl->tables_size);
- if (tbl->tables)
-#ifdef __CYGWIN__
- bcopy((const char *) tbl->tables, (char *) tmp, (size_t) tbl->ntable * sizeof(struct table_in));
-#else /* not __CYGWIN__ */
- bcopy(tbl->tables, tmp, tbl->ntable * sizeof(struct table_in));
-#endif /* not __CYGWIN__ */
- tbl->tables = tmp;
- }
-
- tbl->tables[tbl->ntable].ptr = tbl1;
- tbl->tables[tbl->ntable].col = col;
- tbl->tables[tbl->ntable].row = row;
- tbl->tables[tbl->ntable].indent = tbl->indent;
- tbl->tables[tbl->ntable].buf = newTextList();
- check_row(tbl, row);
- if (col + 1 <= tbl->maxcol &&
- tbl->tabattr[row][col + 1] & HTT_X)
- tbl->tables[tbl->ntable].cell = tbl->cell.icell;
- else
- tbl->tables[tbl->ntable].cell = -1;
- tbl->ntable++;
-}
-
-#ifdef MATRIX
-int
-correct_table_matrix(struct table *t, int col, int cspan, int a, double b)
-{
- int i, j;
- int ecol = col + cspan;
- double w = 1. / (b * b);
-
- for (i = col; i < ecol; i++) {
- v_add_val(t->vector, i, w * a);
- for (j = i; j < ecol; j++) {
- m_add_val(t->matrix, i, j, w);
- m_set_val(t->matrix, j, i, m_entry(t->matrix, i, j));
- }
- }
- return i;
-}
-
-static void
-correct_table_matrix2(struct table *t, int col, int cspan, double s, double b)
-{
- int i, j;
- int ecol = col + cspan;
- int size = t->maxcol + 1;
- double w = 1. / (b * b);
- double ss;
-
- for (i = 0; i < size; i++) {
- for (j = i; j < size; j++) {
- if (i >= col && i < ecol && j >= col && j < ecol)
- ss = (1. - s) * (1. - s);
- else if ((i >= col && i < ecol) || (j >= col && j < ecol))
- ss = -(1. - s) * s;
- else
- ss = s * s;
- m_add_val(t->matrix, i, j, w * ss);
- }
- }
-}
-
-static void
-correct_table_matrix3(struct table *t, int col, char *flags, double s, double b)
-{
- int i, j;
- double ss;
- int size = t->maxcol + 1;
- double w = 1. / (b * b);
- int flg = (flags[col] == 0);
-
- for (i = 0; i < size; i++) {
- if (!((flg && flags[i] == 0) || (!flg && flags[i] != 0)))
- continue;
- for (j = i; j < size; j++) {
- if (!((flg && flags[j] == 0) || (!flg && flags[j] != 0)))
- continue;
- if (i == col && j == col)
- ss = (1. - s) * (1. - s);
- else if (i == col || j == col)
- ss = -(1. - s) * s;
- else
- ss = s * s;
- m_add_val(t->matrix, i, j, w * ss);
- }
- }
-}
-
-static void
-set_table_matrix0(struct table *t, int maxwidth)
-{
- int size = t->maxcol + 1;
- int i, j, k, bcol, ecol;
- int swidth, width, a;
- double w0, w1, w, s, b;
-#ifdef __GNUC__
- double we[size];
- char expand[size];
-#else /* not __GNUC__ */
- double we[MAXCOL];
- char expand[MAXCOL];
-#endif /* not __GNUC__ */
- struct table_cell *cell = &t->cell;
-
- w0 = 0.;
- for (i = 0; i < size; i++) {
- we[i] = weight(t->tabwidth[i]);
- w0 += we[i];
- }
- if (w0 <= 0.)
- w0 = 1.;
-
- if (cell->necell == 0) {
- for (i = 0; i < size; i++) {
- s = we[i] / w0;
- b = sigma_td_nw((int) (s * maxwidth));
- correct_table_matrix2(t, i, 1, s, b);
- }
- return;
- }
-
- bzero(expand, size);
-
- for (k = 0; k < cell->necell; k++) {
- j = cell->eindex[k];
- bcol = cell->col[j];
- ecol = bcol + cell->colspan[j];
- swidth = 0;
- for (i = bcol; i < ecol; i++) {
- swidth += t->tabwidth[i];
- expand[i]++;
- }
- width = cell->width[j] - (cell->colspan[j] - 1) * t->cellspacing;
- w = weight(width);
- w1 = 0.;
- for (i = bcol; i < ecol; i++)
- w1 += we[i];
- s = w / (w0 + w - w1);
- a = (int) (s * maxwidth);
- b = sigma_td_nw(a);
- correct_table_matrix2(t, bcol, cell->colspan[j], s, b);
- }
-
- w1 = 0.;
- for (i = 0; i < size; i++)
- if (expand[i] == 0)
- w1 += we[i];
- for (i = 0; i < size; i++) {
- if (expand[i] == 0) {
- s = we[i] / max(w1, 1.);
- b = sigma_td_nw((int) (s * maxwidth));
- }
- else {
- s = we[i] / max(w0 - w1, 1.);
- b = sigma_td_nw(maxwidth);
- }
- correct_table_matrix3(t, i, expand, s, b);
- }
-}
-
-void
-set_table_matrix(struct table *t, int width)
-{
- int size = t->maxcol + 1;
- int i, j;
- double b, s;
- int a;
- struct table_cell *cell = &t->cell;
-
- if (size < 1)
- return;
-
- t->matrix = m_get(size, size);
- t->vector = v_get(size);
- for (i = 0; i < size; i++) {
- for (j = i; j < size; j++)
- m_set_val(t->matrix, i, j, 0.);
- v_set_val(t->vector, i, 0.);
- }
-
- for (i = 0; i < size; i++) {
- if (t->fixed_width[i] > 0) {
- a = max(t->fixed_width[i], t->minimum_width[i]);
- b = sigma_td(a);
- correct_table_matrix(t, i, 1, a, b);
- }
- else if (t->fixed_width[i] < 0) {
- s = -(double) t->fixed_width[i] / 100.;
- b = sigma_td((int) (s * width));
- correct_table_matrix2(t, i, 1, s, b);
- }
- }
-
- for (j = 0; j <= cell->maxcell; j++) {
- if (cell->fixed_width[j] > 0) {
- a = max(cell->fixed_width[j], cell->minimum_width[j]);
- b = sigma_td(a);
- correct_table_matrix(t, cell->col[j],
- cell->colspan[j], a, b);
- }
- else if (cell->fixed_width[j] < 0) {
- s = -(double) cell->fixed_width[j] / 100.;
- b = sigma_td((int) (s * width));
- correct_table_matrix2(t, cell->col[j],
- cell->colspan[j], s, b);
- }
- }
-
- set_table_matrix0(t, width);
-
- if (t->total_width > 0) {
- b = sigma_table(width);
- }
- else {
- b = sigma_table_nw(width);
- }
- correct_table_matrix(t, 0, size, width, b);
-}
-#endif /* MATRIX */