lynx-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

lynx-dev [PATCH 2.8.4dev.16] Allow line breaks in TRST


From: Ilya Zakharevich
Subject: lynx-dev [PATCH 2.8.4dev.16] Allow line breaks in TRST
Date: Sun, 21 Jan 2001 18:07:49 -0500
User-agent: Mutt/1.2.5i

This patch enables <BR> and <P> in TRSTables.  The table still need to fit
into the screen width without line wrapping.  A tiny bit of additional work
may be needed to allow tables-inside-tables too; then any table should
be rendable as a table after an appropriate screen resizing.

This patch also should make around 70% of TRSTable.c unreachable.  A lot of
simplification can be made, and most of the current convoluted hackery may
be removed.

Since this algorithm tries to align *all* the display lines of the
table, in some rare cases it may need larger screen width than the old
algorithm (the old algorithm ignores all but one of the display lines
corresponding to the given <TR></TR> - and in most cases just gives up
for the whole table if a multiline cell is but of the simplest form).

Enjoy,
Ilya

P.S.  My previous TRSTable.c patch was mislabeled as one for dev10.
      In fact it is for dev16 too.

P.P.S. With keyboard navigation which may now be customized to become
       almost tolerable, https support, and better table support lynx
       is now very close to being usable by a general public.

       The only one thing missing is file upload.  What keeps it being
       1/3-implemented for so long?

--- ./src/TRSTable.c-as-sent    Sun Jan 21 01:29:46 2001
+++ ./src/TRSTable.c    Sun Jan 21 17:30:18 2001
@@ -28,6 +28,10 @@
                              value means cell was reserved by ROWSPAN */
 #define EOCOLG (-2)    /* sumcols' Line field isn't used for line info, this
                              special value means end of COLGROUP */
+#ifndef NO_AGRESSIVE_NEWROW
+#  define NO_AGRESSIVE_NEWROW  0
+#endif
+
 typedef enum {
     CS_invalid = -1,           /* cell "before the first",
                                   or empty lines after [ce]bc,
@@ -992,6 +996,8 @@ PRIVATE int Stbl_finishCellInRow ARGS5(
 #endif /* MEGA_COMMENTOUT */
     s->state = newstate;
     ret = lastcell->len;
+    if (ret == -1 && pos == 0)
+       ret = 0; /* XXXX Hack to allow trailing <P> in multiline cells. */
 
 /*    lastcell->len = pos - lastcell->pos; */
   trace_and_return:
@@ -1288,6 +1294,143 @@ PRIVATE int get_remaining_colspan ARGS5(
     return colspan;
 }
 
+PRIVATE int Stbl_fakeFinishCellInTable ARGS4(
+    STable_info *,     me,
+    STable_rowinfo *,  lastrow,
+    int,               lineno,
+    int,               finishing)      /* Processing finish or start */
+{
+    STable_states * s = &me->s;
+    int fake = 0;
+    
+    switch (s->state) {                        /* We care only about trailing 
<BR> */
+    case CS_invalid:
+    case CS__0new:
+    case CS__0ef:
+    case CS__0cf:
+    case CS__new:
+    case CS__cbc:
+    case CS__ef:
+    case CS__cf:
+    default:
+       /* <BR></TD> may produce these (XXXX instead of CS__cbf?).  But if
+          finishing==0, the caller already checked that we are on a
+          different line.  */
+       if (finishing==0)
+           fake = 1;
+       break;          /* Either can't happen, or may be ignored */
+    case CS__eb:
+    case CS__0eb:
+    case CS__0cb:
+    case CS__cb:
+       fake = 1;
+       break;
+    }
+    if (fake) {
+       /* The previous action we did was putting a linebreak.  Now we
+          want to put another one.  Fake necessary
+          </TD></TR><TR><TD></TD><TD> (and possibly </TD>) instead. */
+       int ncells = lastrow->ncells;
+       int i;
+       int al = lastrow->alignment;
+       int cs = lastrow->cells[lastrow->ncells - 1].colspan;
+       int rs = 1;                     /* XXXX How to find rowspan? */
+       int ih = 0;                     /* XXXX How to find is_header? */
+       int end_td = 1;
+       int need_reserved = 0;
+       int prev_reserved_last = -1;
+       STable_rowinfo *prev_row = lastrow;
+
+       CTRACE((tfp, "TRST:Stbl_fakeFinishCellInTable(lineno=%d, finishing=%d) 
START FAKING\n",
+               lineno, finishing));
+
+       if (finishing)
+           /* Fake </TD> at BOL */
+           Stbl_finishCellInRow(lastrow, s, end_td, lineno, 0);
+
+       /* Fake </TR> at BOL */
+       /* Stbl_finishCellInTable(lineno, 0, 0);*/ /* Needed? */
+
+       /* Fake <TR> at BOL */
+       Stbl_addRowToTable(me, al, lineno);
+       lastrow = me->rows + (me->nrows - 1);
+       for (i = 0; i < lastrow->allocated; i++)
+           if (lastrow->cells[i].alignment == RESERVEDCELL) {
+               need_reserved = 1;
+               break;
+           }
+       for (i = ncells; i < prev_row->allocated; i++)
+           if (prev_row->cells[i].alignment == RESERVEDCELL)
+               prev_reserved_last = i;
+       if (need_reserved || prev_reserved_last >= 0) {
+           /* Oups, we are going to stomp over a line which somebody
+              cares about already, or the previous line had reserved
+              cells which were not skipped over.
+
+              Remember that STable_rowinfo is about logical (TR)
+              table lines, not displayed lines.  We need to duplicate
+              the reservation structure when we fake new logical lines.  */
+           int prev_row_n = prev_row - me->rows;
+           STable_rowinfo *rows = realloc(me->rows,
+                                          (me->allocated_rows + 1)
+                                          * sizeof(STable_rowinfo));
+           int need_cells = prev_reserved_last + 1;
+
+           if (!rows)
+               return 1; /* ignore silently, no free memory, may be 
recoverable */
+
+           CTRACE((tfp, "TRST:Stbl_fakeFinishCellInTable REALLOC ROWSPAN\n"));
+           me->rows = rows;
+           lastrow = me->rows + (me->nrows - 1);
+           prev_row = me->rows + prev_row_n;
+           me->allocated_rows++;
+
+           /* Insert a duplicate row after lastrow */
+           memmove(lastrow+1, lastrow,
+                   sizeof(STable_rowinfo)*(me->allocated_rows - me->nrows));
+
+           /* Ignore cells, they belong to the next row now */
+           lastrow->allocated = 0;
+           lastrow->cells = 0;
+           if (need_cells) {
+               lastrow->cells = typecallocn(STable_cellinfo, need_cells);
+               /* ignore silently, no free memory, may be recoverable */
+               if (!lastrow->cells)
+                   return 1;
+               lastrow->allocated = need_cells;
+               memcpy(lastrow->cells, prev_row->cells, 
+                      lastrow->allocated * sizeof(STable_cellinfo));
+
+               i = -1;
+               while (++i < ncells) {
+                   /* Stbl_addCellToTable grants RESERVEDCELL, but we do not
+                      want this action for fake cells.
+                      XXX Maybe always fake RESERVEDCELL instead of explicitly
+                      creating/destroying cells?  */
+                   if (lastrow->cells[i].alignment == RESERVEDCELL)
+                       lastrow->cells[i].alignment = HT_LEFT;
+               }
+           }
+       }
+
+       /* Fake <TD></TD>...<TD> (and maybe a </TD>) at BOL. */
+       CTRACE((tfp, "TRST:Stbl_fakeFinishCellInTable FAKE %d elts%s\n",
+               ncells, (finishing ? ", last unfinished" : "")));
+       i = 0;
+       while (++i <= ncells) {
+           /* XXXX A lot of args may be wrong... */
+           Stbl_addCellToTable(me, (i==ncells ? cs : 1), rs, al, ih,
+                               lineno, 0);
+           if (!finishing || (i != ncells))
+               Stbl_finishCellInRow(lastrow, s, end_td, lineno, 0);
+       }
+       CTRACE((tfp, "TRST:Stbl_fakeFinishCellInTable(lineno=%d) FINISH 
FAKING\n",
+               lineno));
+       return 1;
+    }
+    return 0;
+}
+
 /*
  * Returns -1 on error, otherwise 0.
  */
@@ -1316,6 +1459,14 @@ PUBLIC int Stbl_addCellToTable ARGS7(
     Stbl_finishCellInTable(me, YES,
                           lineno, pos);
     lastrow = me->rows + (me->nrows - 1);
+
+    /* If the last cell was finished by <BR></TD>, we need to fake an
+       appropriate amount of cells */
+    if (!NO_AGRESSIVE_NEWROW && pos == 0 && lastrow->ncells > 0
+       && lastrow->cells[lastrow->ncells-1].cLine != lineno) {
+       if (Stbl_fakeFinishCellInTable(me, lastrow, lineno, 0))
+           lastrow = me->rows + (me->nrows - 1);
+    }
     if (colspan == 0) {
        colspan = get_remaining_colspan(lastrow, me->sumcols, me->ncolinfo,
                                        colspan, me->ncols);
@@ -1436,6 +1587,13 @@ PUBLIC int Stbl_finishCellInTable ARGS4(
        return icell;
     if (s->x_td == -1)
        return end_td ? -1 : 0;
+
+    if (!NO_AGRESSIVE_NEWROW && pos) {
+       if (Stbl_fakeFinishCellInTable(me, lastrow, lineno, 1)) {
+           lastrow = me->rows + (me->nrows - 1);
+           icell = lastrow->ncells - 1;
+       }
+    }
     len = Stbl_finishCellInRow(lastrow, s, end_td, lineno, pos);
     if (len == -1)
        return len;

; To UNSUBSCRIBE: Send "unsubscribe lynx-dev" to address@hidden

reply via email to

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