lynx-dev
[Top][All Lists]
Advanced

[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

reply via email to

[Prev in Thread] Current Thread [Next in Thread]