[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
lynx-dev Re: [PATCH 2.8.5-dev14] ladder in tables [Part II]
From: |
Ilya Zakharevich |
Subject: |
lynx-dev Re: [PATCH 2.8.5-dev14] ladder in tables [Part II] |
Date: |
Sat, 12 Apr 2003 18:00:55 -0700 |
User-agent: |
Mutt/1.4i |
On Tue, Mar 04, 2003 at 02:43:45AM -0800, Ilya Zakharevich wrote:
> This patch removes about 1/3 of occurences of "ladder" in tables,
>
> when
> cells
> go
> like
> this.
>
> [The complete fix requires much more work.] We skip <br> and <p> at
> the starts of the cells. However, we grant the requests for new-lines
> due to the style change - to allow structures like <ol> inside cells.
This is the second part. The first part removed unnecessary empty
lines at beginning of cells; the second part removes empty lines at
ends of cells. Also, vgrepping shows that the first part of the patch
could remove some "needed" empty lines at start of a cell - though I
could not find a case when this would happen.
> Enjoy,
> Ilya
>
Note also that suddently perl.com started to show formatted, though
with not exactly correct ofset of the first line in the cell. Like this:
[26]Safari Bookshelf
O'Reilly Network
Technologies [27].NET
[28]Apache
[29]BSD
[30]ONJava.com
Before this patch it would show completely flat.
One note: the chunk marked by FIXME_FIXME_XXXX is written for the
model of allocation of 2-8-5-14 (quite wasteful). If the model of
POOLing changed since then, please vgrep this (small) part.
Last chunk fixes a minor misprint.
--- ./src/TRSTable.h-good Tue Mar 4 01:54:00 2003
+++ ./src/TRSTable.h Sat Apr 12 00:00:00 2003
@@ -8,6 +8,7 @@
typedef struct _STable_info STable_info;
extern STable_info * Stbl_startTABLE PARAMS((short));
extern int Stbl_finishTABLE PARAMS((STable_info *));
+extern void Stbl_finishRowInTable PARAMS((STable_info *));
extern void Stbl_free PARAMS((STable_info *));
extern int Stbl_addRowToTable PARAMS((STable_info *, int, int));
extern int Stbl_addCellToTable PARAMS((STable_info *, int, int, int, int, int,
int, int));
@@ -16,6 +17,7 @@ extern int Stbl_finishCellInTable PARAMS
extern int Stbl_addColInfo PARAMS((STable_info *, int, short, BOOL));
extern int Stbl_finishColGroup PARAMS((STable_info *));
extern int Stbl_addRowGroup PARAMS((STable_info *, short));
+extern int Stbl_trimFakeRows PARAMS((STable_info *, int, int));
#define TRST_ENDCELL_ENDTD 1
#define TRST_ENDCELL_LINEBREAK 0
--- ./src/TRSTable.c-good Fri Apr 11 14:43:58 2003
+++ ./src/TRSTable.c Sat Apr 12 17:47:18 2003
@@ -182,7 +182,8 @@ struct _STable_info {
int maxpos; /* max. of max. cell pos's of any row */
int allocated_rows; /* number of rows allocated */
int allocated_sumcols; /* number of sumcols allocated */
- int ncolinfo; /* number of COL info collected */
+ int ncolinfo; /* number of COL info collected */
+ int last_reserved; /* -1 or last line with reserved cells */
STable_cellinfo * sumcols; /* for summary (max len/pos) col info */
STable_rowinfo * rows;
STable_rowinfo rowspans2eog;
@@ -249,7 +250,7 @@ PRIVATE int Stbl_finishCellInRow PARAMS(
int end_td,
int lineno,
int pos));
-PRIVATE int Stbl_finishRowInTable PARAMS((
+PRIVATE int Stbl_DOfinishRowInTable PARAMS((
STable_info * me));
PRIVATE CONST char * cellstate_s ARGS1(
@@ -288,6 +289,7 @@ PUBLIC struct _STable_info * Stbl_startT
me->pending_colgroup_align = HT_ALIGN_NONE;
me->s.x_td = -1;
me->s.icell_core = -1;
+ me->last_reserved = -1;
#ifdef EXP_NESTED_TABLES
if (nested_tables)
me->enclosing = 0;
@@ -1094,7 +1096,7 @@ PRIVATE int Stbl_reserveCellsInTable ARG
int, rowspan)
{
STable_rowinfo *rows, *row;
- int i;
+ int i, last;
if (me->nrows <= 0)
return -1; /* must already have at least one row */
@@ -1116,9 +1118,10 @@ PRIVATE int Stbl_reserveCellsInTable ARG
if (!addmem_rowinfo(me, rowspan - 1))
return 0; /* ignore silently, no free memory, may be recoverable */
- for (i = me->nrows;
- i < (rowspan == 0 ? me->allocated_rows : me->nrows + rowspan - 1);
- i++) {
+ last = (rowspan == 0 ? me->allocated_rows : me->nrows + rowspan - 1);
+ if (me->last_reserved < last)
+ me->last_reserved = last;
+ for (i = me->nrows; i < last; i++) {
if (!me->rows[i].allocated) {
me->rows[i].cells = typecallocn(STable_cellinfo, icell + colspan);
if (!me->rows[i].cells)
@@ -1168,7 +1171,7 @@ PUBLIC int Stbl_addRowToTable ARGS3(
me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].len =
s->pending_len;
s->pending_len = 0;
}
- Stbl_finishRowInTable(me);
+ Stbl_DOfinishRowInTable(me);
if (me->nrows > 0 && me->rows[me->nrows-1].Line == lineno)
me->rows[me->nrows-1].Line = -1;
s->pending_len = 0;
@@ -1242,19 +1245,20 @@ PUBLIC int Stbl_addRowToTable ARGS3(
/*
* Returns -1 on error, otherwise current number of rows.
*/
-PRIVATE int Stbl_finishRowInTable ARGS1(
+PRIVATE int Stbl_DOfinishRowInTable ARGS1(
STable_info *, me)
{
STable_rowinfo *lastrow;
STable_states * s = &me->s;
int ncells;
- CTRACE2(TRACE_TRST, (tfp, "TRST:Stbl_finishRowInTable()\n"));
+ CTRACE2(TRACE_TRST, (tfp, "TRST:Stbl_DOfinishRowInTable()\n"));
if (!me->rows || !me->nrows)
return -1; /* no row started! */
lastrow = me->rows + (me->nrows - 1);
ncells = lastrow->ncells;
- lastrow->ended = ROW_ended_by_endtr;
+ if (lastrow->ended != ROW_ended_by_splitline)
+ lastrow->ended = ROW_ended_by_endtr;
if (lastrow->ncells > 0) {
if (s->pending_len > 0)
lastrow->cells[lastrow->ncells - 1].len = s->pending_len;
@@ -1449,6 +1453,7 @@ PRIVATE int Stbl_fakeFinishCellInTable A
lastrow = me->rows + (me->nrows - 1);
prev_row = me->rows + prev_row_n;
me->allocated_rows++;
+ me->last_reserved++;
/* Insert a duplicate row after lastrow */
for (n = me->allocated_rows - me->nrows - 1; n >= 0; --n)
@@ -1633,6 +1638,8 @@ PUBLIC BOOL Stbl_at_start_of_cell ARGS3(
if (me->nrows == 0)
return TRUE;
lastrow = me->rows + (me->nrows - 1);
+ if (lastrow->ended != ROW_not_ended)
+ return FALSE; /* E.g., may be processing </tr> */
icell = lastrow->ncells - 1;
if (icell < 0)
return TRUE;
@@ -1643,6 +1650,70 @@ PUBLIC BOOL Stbl_at_start_of_cell ARGS3(
return TRUE;
}
+PUBLIC void Stbl_finishRowInTable ARGS1(
+ STable_info *, me)
+{
+ STable_rowinfo *lastrow;
+
+ CTRACE2(TRACE_TRST,
+ (tfp, "TRST:Stbl_finishRowInTable()\n"));
+ if (me->nrows <= 0)
+ return;
+ lastrow = me->rows + (me->nrows - 1);
+ if (lastrow->ended == ROW_not_ended)
+ lastrow->ended = ROW_ended_by_endtr;
+}
+
+
+/* Assumes that the current pos is at beginning of line.
+ Checks whether the last row was a fake row, and undo it if possible.
+ Returns TRUE if the last line (empty!) can be safely trimmed. */
+PUBLIC int Stbl_trimFakeRows ARGS3(
+ STable_info *, me,
+ int, lineno,
+ int, pos)
+{
+ STable_rowinfo *prevrow, *lastrow;
+ int icell;
+
+ CTRACE2(TRACE_TRST,
+ (tfp, "TRST:Stbl_trimFakeRows()\n"));
+
+ /* XXXX The logic may be much better if we support removal of
+ RESERVED cells. Until this is done, bail out early: */
+ if (me->nrows <= 0 || me->nrows <= me->last_reserved)
+ return 0;
+ lastrow = me->rows + (me->nrows - 1);
+ icell = lastrow->ncells - 1;
+ if (icell >= 0 && lastrow->cells[icell].cLine < lineno) {
+ /* The last cell start on a preceeding line; keep lastrow */
+ lastrow->ended = ROW_not_ended; /* Give it new life */
+ /* We do not use state info for a lot of things any more, so do
+ not try to do anything special here */
+ me->s.state = CS__0new; /* This is enough to revive things. */
+ me->s.x_td = lastrow->cells[lastrow->ncells - 1].pos;
+ me->s.lineno = lastrow->cells[lastrow->ncells - 1].cLine;
+ return 1;
+ }
+ if (me->nrows <= 1)
+ return 0;
+ prevrow = me->rows + (me->nrows - 2);
+ if ( prevrow->ended != ROW_ended_by_splitline) /* Lastrow non-fake */
+ return 0;
+ /* XXXX should remove duplicate RESERVED stuff too */
+ me->nrows--;
+ if (lastrow->cells && lastrow->allocated == 0) /* Moved to pool */
+ lastrow->cells = NULL;
+ lastrow->ncells = 0;
+ prevrow->ended = ROW_not_ended; /* Give it new life */
+ /* We do not use state info for a lot of things any more, so do
+ not try to do anything special here */
+ me->s.state = CS__0new;
+ me->s.x_td = prevrow->cells[prevrow->ncells - 1].pos;
+ me->s.lineno = prevrow->cells[prevrow->ncells - 1].cLine;
+ return 1;
+}
+
/*
* Returns -1 on error, otherwise 0.
*/
@@ -1869,7 +1940,7 @@ PUBLIC int Stbl_finishTABLE ARGS1(
me->rows[me->nrows-1].cells[me->rows[me->nrows-1].ncells - 1].len =
s->pending_len;
s->pending_len = 0;
}
- Stbl_finishRowInTable(me);
+ Stbl_DOfinishRowInTable(me);
/* take into account offsets on multi-line cells.
XXX We cannot do it honestly, since two cells on the same row may
participate in multi-line table entries, and we preserve only
--- ./src/GridText.c-good Tue Mar 4 02:04:10 2003
+++ ./src/GridText.c Sat Apr 12 02:55:22 2003
@@ -2669,6 +2673,32 @@ PRIVATE HTLine * insert_blanks_in_line A
return mod_line;
}
+PRIVATE void reset_cached_linedata ARGS3(
+ HText *, text,
+ char *, p,
+ unsigned, plen)
+{ /* Count funny characters */
+ int i;
+
+ text->permissible_split = ctrl_chars_on_this_line =
+ utfxtra_on_this_line = 0;
+ for (i = (plen - 1); i >= 0; i--) {
+ if (p[i] == LY_UNDERLINE_START_CHAR ||
+ p[i] == LY_UNDERLINE_END_CHAR ||
+ p[i] == LY_BOLD_START_CHAR ||
+ p[i] == LY_BOLD_END_CHAR ||
+ p[i] == LY_SOFT_HYPHEN) {
+ ctrl_chars_on_this_line++;
+ } else if (IS_UTF_EXTRA(p[i])) {
+ utfxtra_on_this_line++;
+ }
+ if (p[i] == LY_SOFT_HYPHEN && (int)text->permissible_split < i)
+ text->permissible_split = i + 1;
+ }
+ ctrl_chars_on_this_line += utfxtra_on_this_line;
+}
+
+
#if defined(USE_COLOR_STYLE)
PRIVATE HTStyleChange * skip_matched_and_correct_offsets ARGS3(
HTStyleChange *, end,
@@ -2958,20 +2988,7 @@ PRIVATE void split_line ARGS2(
plen = strlen(p);
if (plen) { /* Count funny characters */
- for (i = (plen - 1); i >= 0; i--) {
- if (p[i] == LY_UNDERLINE_START_CHAR ||
- p[i] == LY_UNDERLINE_END_CHAR ||
- p[i] == LY_BOLD_START_CHAR ||
- p[i] == LY_BOLD_END_CHAR ||
- p[i] == LY_SOFT_HYPHEN) {
- ctrl_chars_on_this_line++;
- } else if (IS_UTF_EXTRA(p[i])) {
- utfxtra_on_this_line++;
- }
- if (p[i] == LY_SOFT_HYPHEN && (int)text->permissible_split < i)
- text->permissible_split = i + 1;
- }
- ctrl_chars_on_this_line += utfxtra_on_this_line;
+ reset_cached_linedata(text, p, plen);
/* Add the data to the new line. -FM */
strcat(linedata, p);
@@ -4914,6 +4931,72 @@ PRIVATE void free_enclosed_stbl ARGS1(
#define free_enclosed_stbl(me) /* nothing */
#endif
+/* Remove trailing blank lines from the last cell. */
+PUBLIC int HText_trimCellLines ARGS1(
+ HText *, text)
+{
+ int ret = 0;
+ HTLine *lastline;
+#if defined(USE_COLOR_STYLE)
+ HTStyleChange *laststyles;
+#endif
+
+ if (!(text && text->stbl))
+ return 0;
+
+ lastline = text->last_line;
+#if defined(USE_COLOR_STYLE)
+ laststyles = lastline->styles;
+#endif
+ while ( text->last_line && text->Lines >= 1
+ && HText_LastLineSize(text, FALSE) == 0 ) {
+ /* Empty line should survive only if
+ a) It is a first line of a row;
+ b) This is not a fake row.
+ */
+ if (Stbl_trimFakeRows(text->stbl, text->Lines, text->last_line->size))
+ ret++, HText_RemoveEmptyLastLine(text);
+ else
+ break;
+ }
+
+ if (!ret)
+ return 0;
+
+#ifndef FIXME_FIXME_XXXX
+ /* De-POOL the line */
+ memcpy(lastline, text->last_line, LINE_SIZE(text->last_line->size));
+#if defined(USE_COLOR_STYLE)
+ /* De-POOL the style buffers */
+ memcpy(laststyles, lastline->styles,
+ sizeof(HTStyleChange)*lastline->numstyles);
+ lastline->styles = laststyles;
+#endif
+
+ if (text->last_line->next == text->last_line)
+ lastline->next = lastline->prev = lastline;
+ text->last_line = lastline;
+ lastline->prev->next = lastline; /* Link in new line */
+ lastline->next->prev = lastline; /* Could be same node of course */
+
+#endif /* FIXME_FIXME_XXXX */
+
+ /* Fix global state for the last line */
+ reset_cached_linedata(text, text->last_line->data,
+ text->last_line->size);
+#if 0
+ /* XXXX This is not enough. Actually we need also to clear the
+ me->in_word flag of HTML.c. Since this is not
+ possible, fake a real space. */
+ text->LastChar = (text->last_line->size
+ ? text->last_line->data[text->last_line->size - 1]
+ : ' ');
+#else
+ HText_appendCharacter(text, ' ');
+#endif
+ return ret;
+}
+
/* Finish simple table handling
* Return TRUE if the table is nested inside another table.
*/
@@ -4990,9 +5073,8 @@ PUBLIC void HText_startStblTR ARGS2(
PUBLIC void HText_endStblTR ARGS1(
HText *, me)
{
- if (!me || !me->stbl)
- return;
- /* should this do something?? */
+ if (me && me->stbl)
+ Stbl_finishRowInTable(me->stbl);
}
/* Start simple table cell
@@ -5028,6 +5110,7 @@ PUBLIC void HText_endStblTD ARGS1(
{
if (!me || !me->stbl)
return;
+ HText_trimCellLines(me);
if (Stbl_finishCellInTable(me->stbl, TRST_ENDCELL_ENDTD,
me->Lines, HText_LastLineOffset(me),
HText_LastLineSize(me,FALSE)) < 0)
HText_cancelStbl(me); /* give up */
@@ -8810,7 +8893,7 @@ PUBLIC void HText_RemoveEmptyLastLine AR
{
HTLine *line, *previous;
- if (!(text && text->Lines > 1))
+ if (!(text && text->Lines >= 1)) /* Lines is 0-based */
return;
line = text->last_line;
; To UNSUBSCRIBE: Send "unsubscribe lynx-dev" to address@hidden
- lynx-dev Re: [PATCH 2.8.5-dev14] ladder in tables [Part II],
Ilya Zakharevich <=