lynx-dev
[Top][All Lists]
Advanced

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

lynx-dev [dev16] Cleanup patch for TEXTAREA edit


From: Kim DeVaughn
Subject: lynx-dev [dev16] Cleanup patch for TEXTAREA edit
Date: Wed, 10 Feb 1999 03:22:25 -0800

Sorry for the length of this patch, which is mostly due to some
whitespace differences between -dev.15 and -dev.16.  I didn't
want to try and replicate all the little changes that I made
against the -dev.15 code that I'd been using, since I would very
likely have missed a real change, or made some typos, or some
such.

Anyway, barring bug reports, I think this is now pretty close to
the final form for the TEXTAREA external edit feature, per se.

Changes:

 1. Worked with some pathological/boundary-case pages, and fixed
    some some edges that could fail (eg, last line of document is
    also last line of a TEXTAREA, and lines are being added; page
    containing *only* a one-line TEXTAREA field; etc).  While it
    was unlikely one would run into such beasts in real life, they
    all work correctly now.  Thanks to Greg Marr and Serge Munhov
    for providing some very basic pages that I was able to easily
    modify for various test cases.

 2. Added a couple flags to the TextAnchor and HTLine struct's, to
    indicate an expansion line.  These needed to be added to allow
    for line deletion when a TEXTAREA is "reset" or shrinks (when
    we get around to tackling those tasks).

 3. The editor's cursor is now positioned on the same line in the
    edit file, as it was on when the editor was invoked (relative
    to the beginning of the TEXTAREA).  At least for those editors
    that lynx knows support initial positioning (emacs, vi, pico,
    jove, and jed for non-VMS platforms; sedt for VMS).

 4. Cleaned up and corrected a few comments; simplified a few small
    bits of code.

I am still looking for a site/page that has some "hidden" links in
it that *follow* a TEXTAREA, for testing purposes.  If you know of
one (or wish to create one), please let me know ... what *I* know
of HTML syntax, fits nicely into a small thimble, with room to spare.


Still todo:

 a. Insert a file directly into a TEXTAREA, bypassing the editor
    itself.

 b. Add a command to "grow" a TEXTAREA by some fixed, reasonable
    number of blank lines, each time it is invoked.

 c. Take care of cursor positioning on exit from the editor.

 d. Look into removing any added lines on a reset operation, as
    well as shrinking back any extraneous (now blank) lines, if
    such are present, when returning from a subsequent editor
    invocation on the same TEXTAREA.  [Doing these will be a PITA,
    since it is not easy to process strings "backwards".]

/kim


Against a clean 2.8.2dev.16:

diff -uNr lynx-2.8.2-dev.16+kd.orig/src/GridText.c 
lynx-2.8.2-dev.16+kd/src/GridText.c
--- lynx-2.8.2-dev.16+kd.orig/src/GridText.c    Mon Feb  8 02:32:59 1999
+++ lynx-2.8.2-dev.16+kd/src/GridText.c Tue Feb  9 18:50:31 1999
@@ -35,6 +35,7 @@
 #include <LYCharSets.h>
 #include <LYCharUtils.h>       /* LYUCTranslateBack... */
 #include <UCMap.h>
+#include <LYEdit.h>
 #ifdef EXP_CHARTRANS_AUTOSWITCH
 #include <UCAuto.h>
 #endif /* EXP_CHARTRANS_AUTOSWITCH */
@@ -130,6 +131,7 @@
        unsigned        size;           /* Number of characters */
        BOOL    split_after;            /* Can we split after? */
        BOOL    bullet;                 /* Do we bullet? */
+       BOOL    expansion_line;         /* TEXTAREA edit new line flag */
 #if defined(USE_COLOR_STYLE)
        HTStyleChange   styles[MAX_STYLES_ON_LINE];
        int     numstyles;
@@ -153,6 +155,7 @@
        FormInfo *              input_field;    /* Info for form links */
        BOOL                    show_anchor;    /* Show the anchor? */
        BOOL                    inUnderline;    /* context is underlined */
+       BOOL                    expansion_anch; /* TEXTAREA edit new anchor */
        HTChildAnchor *         anchor;
 } TextAnchor;
 
@@ -8705,11 +8708,11 @@
  *  be allowed to expand in the event of a tag width change (eg, 99 -> 100)
  *  as controlled by arg6 (CHOP or NOCHOP).  Arg4 is either (the address
  *  of) a value which must match, in order for the tag to be incremented,
- *  or (the address of) a 0-value, which matches any value, and will cause
+ *  or (the address of) a 0-value, which will match any value, and cause
  *  any valid tag to be incremented.  Arg2 is a pointer to the first/only
- *  Anchor that exists on the line (if any); we may need to adjust their
- *  position(s) on the line.  Arg3 when non-0 indicates the number of new
- *  digits that were added to the 2nd line in a line crossing pair.
+ *  Anchor that exists on the line; we may need to adjust their position(s)
+ *  on the line.  Arg3 when non-0 indicates the number of new digits that
+ *  were added to the 2nd line in a line crossing pair.
  *
  *  All tags fields in a line which individually match an expected new value,
  *  are incremented.  Line crossing [tags] are handled (PITA).
@@ -8720,12 +8723,12 @@
  *  any.   KED  02/03/99
  */
 PRIVATE int increment_tagged_htline ARGS6(
-       HTLine *,       ht,
+        HTLine *,       ht,
        TextAnchor *,   a,
-       int *,          lx_val,
-       int *,          old_val,
-       int,            incr,
-       int,            mode)
+       int *,          lx_val,
+       int *,          old_val,
+       int,            incr,
+       int,            mode)
 {
     char    buf[MAX_LINE];
     char  lxbuf[MAX_LINE * 2];
@@ -8747,9 +8750,10 @@
     int   pre_n;
     int   fixup = 0;
 
+
     /*
      *  Cleanup for the 2nd half of a line crosser, whose number of tag
-     *  digits grew by some number of places (usually 1, when it does
+     *  digits grew by some number of places (usually 1 when it does
      *  happen, though it *could* be more).  The tag chars were already
      *  rendered into the 2nd line of the pair, but the positioning and
      *  other effects haven't been rippled through any other anchors on
@@ -8760,177 +8764,178 @@
      *  [see comments below on line crosser caused problems]
      */
     if (*lx_val != 0) {
-       nxt_anchor = st_anchor;
-       while ((nxt_anchor) && (nxt_anchor->line_num == a->line_num)) {
-           nxt_anchor->line_pos += *lx_val;
-           nxt_anchor = nxt_anchor->next;
-       }
-       fixup  = *lx_val;
-       *lx_val = 0;
-       st_anchor = st_anchor->next;
+       nxt_anchor = st_anchor;
+       while ((nxt_anchor) && (nxt_anchor->line_num == a->line_num)) {
+          nxt_anchor->line_pos += *lx_val;
+          nxt_anchor = nxt_anchor->next;
+       }
+       fixup  = *lx_val;
+      *lx_val = 0;
+       if (st_anchor) st_anchor = st_anchor->next;
     }
 
+
     /*
      *  Walk thru the line looking for tags (ie, "[nnn]" strings).
      */
-    while (*p != '\0') {
-       if (*p != '[') {
-           *s++ = *p++;
-           continue;
+    while  (*p != '\0') {
+        if (*p != '[')  {
+          *s++ = *p++;
+          continue;
 
        } else {
-           *s++ = *p++;
-           t = p;
-           n = 0;
-           valid = TRUE;   /* p = t = byte after ']' */
+          *s++ = *p++;
+          t = p;
+          n = 0;
+          valid = TRUE;   /* p = t = byte after '[' */
+
+          /*
+           *  Make sure there are only digits between "[" and "]".
+           */
+          while  (*t != ']')  {
+              if (*t == '\0') {  /* uhoh - we have a potential line crosser */
+                 valid = FALSE;
+                 plx   = TRUE;
+                 break;
+              }
+              if (isdigit (*t++) != 0) {
+                 n++;
+                 continue;
+              } else {
+                 valid = FALSE;
+                 break;
+              }
+          }
 
-           /*
-            *  Make sure there are only digits between "[" and "]".
-            */
-           while  (*t != ']')  {
-               if (*t == '\0') {  /* uhoh - we have a potential line crosser */
-                   valid = FALSE;
-                   plx   = TRUE;
-                   break;
-               }
-               if (isdigit (*t++) != 0) {
-                   n++;
-                   continue;
-               } else {
-                   valid = FALSE;
-                   break;
-               }
-           }
+          /*
+           *  If the format is OK, we check to see if the value is what
+           *  we expect.  If not, we have a random [nn] string in the text,
+           *  and leave it alone.
+           *
+           *  [It is *possible* to have a false match here, *if* there are
+           *   two identical [nn] strings (including the numeric value of
+           *   nn), one of which is the [tag], and the other being part of
+           *   a document.  In such a case, the 1st [nn] string will get
+           *   incremented; the 2nd one won't, which makes it a 50-50 chance
+           *   of being correct, if and when such an unlikely juxitposition
+           *   of text ever occurs.  Further validation tests of the [nnn]
+           *   string are probably not possible, since little of the actual
+           *   anchor-associated-text is retained in the TextAnchor or the
+           *   FormInfo structs.  Fortunately, I think the current method is
+           *   more than adequate to weed out 99.999% of any possible false
+           *   matches, just as it stands.  Caveat emptor.]
+           */
+          if ((valid) && (n > 0)) {
+             val = atoi (p);
+             if ((val == *old_val) || (*old_val == 0)) {  /* 0 matches all */
+                if (*old_val != 0)
+                   (*old_val)++;
+                val += incr;
+                sprintf (s, "%d", val);
+                new_n = strlen (s);
+                s += new_n;
+                p += n;
 
-           /*
-            *  If the format is OK, we check to see if the value is what
-            *  we expect.  If not, we have a random [nn] string in the text,
-            *  and leave it alone.
-            *
-            *  [It is *possible* to have a false match here, *if* there are
-            *   two identical [nn] strings (including the numeric value of
-            *   nn), one of which is the [tag], and the other being part of
-            *   a document.  In such a case, the 1st [nn] string will get
-            *   incremented; the 2nd one won't, which makes it a 50-50 chance
-            *   of being correct, if and when such an unlikely juxitposition
-            *   of text ever occurs.  Further validation tests of the [nnn]
-            *   string are probably not possible, since little of the actual
-            *   anchor-associated-text is retained in the TextAnchor or the
-            *   FormInfo structs.  Fortunately, I think the current method is
-            *   more than adequate to weed out 99.99% of any possible false
-            *   matches, just as it stands.  Caveat emptor.]
-            */
-           if ((valid) && (n > 0)) {
-               val = atoi (p);
-               if ((val == *old_val) || (*old_val == 0)) {
+                /*
+                 *  If the number of digits in an existing [tag] increased
+                 *  (eg, [99] --> [100], etc), we need to "adjust" its
+                 *  horizontal position, and that of all subsequant tags
+                 *  that may be on the same line.  PITA.
+                 *
+                 *  [This seems to work as long as a tag isn't a line
+                 *   crosser; when it is, the position of anchors on either
+                 *   side of the split tag, seem to "float" and try to be
+                 *   as "centered" as possible.  Which means that simply
+                 *   incrementing the line_pos by the fixed value of the
+                 *   number of digits that got added to some tag in either
+                 *   line doesn't work quite right, and the text for (say)
+                 *   a button may get stomped on by another copy of itself,
+                 *   but offset by a few chars, when it is selected (eg,
+                 *   "Box Office" may end up looking like "BoBox Office" or
+                 *   "Box Officece", etc.
+                 *
+                 *   Dunno how to fix that behavior ATT, but at least the
+                 *   tag numbers themselves are correct.  -KED  /\oo/\ ]
+                 */
+                if (new_n -= n) {
+                   nxt_anchor = st_anchor;
+                   while ((nxt_anchor)                           &&
+                          (nxt_anchor->line_num == a->line_num)) {
+                       nxt_anchor->line_pos += new_n;
+                       nxt_anchor = nxt_anchor->next;
+                   }
+                   if (st_anchor) st_anchor = st_anchor->next;
+                }
+             }
+          }
+
+          /*
+           *  Unfortunately, valid [tag] strings *can* be split across two
+           *  lines.  Perhaps it would be best to just prevent that from
+           *  happening, but a look into that code, makes me wonder.  Anyway,
+           *  we can handle such tags without *too* much trouble in here [I
+           *  think], though since such animals are rather rare, it makes it
+           *  a bit difficult to test thoroughly (ie, Beyond here, there be
+           *  Dragons).
+           *
+           *  We use lxbuf[] to deal with the two lines involved.
+           */
+          if (plx) {
+             strcpy (lx, p);      /* <- 1st part of a possible lx'ing tag  */
+             pre_n = strlen (p);  /* count of 1st part chars in this line  */
+             strcat (lx, ht->next->data);  /* tack on NEXT line            */
+
+             t = lx;
+             n = 0;
+             valid = TRUE;
+
+             /*
+              *  Go hunting again for just digits, followed by a tag end ']'.
+              */
+             while (*t != ']') {
+                 if (isdigit (*t++) != 0) {
+                    n++;
+                    continue;
+                 } else {
+                    valid = FALSE;
+                    break;
+                 }
+             }
+
+             /*
+              *  It *looks* like a line crosser; now we value test it to
+              *  find out for sure [but see the "false match" warning,
+              *  above], and if it matches, increment it into the buffer,
+              *  along with the 2nd line's text.
+              */
+             if ((valid) && (n > 0)) {
+                val = atoi (lx);
+                if ((val == *old_val) || (*old_val == 0)) {
                    if (*old_val != 0)
-                       (*old_val)++;
+                      (*old_val)++;
                    val += incr;
-                   sprintf (s, "%d", val);
-                   new_n = strlen (s);
-                   s += new_n;
-                   p += n;
+                   sprintf (lx, "%d", val);
+                   new_n = strlen (lx);
+                   strcat (lx, strchr (ht->next->data, ']'));
 
                    /*
-                    *  If the number of digits in an existing [tag] increased
-                    *  (eg, [99] --> [100], etc), we need to "adjust" its
-                    *  horizontal position, and that of all subsequant tags
-                    *  that may be on the same line.  PITA.
-                    *
-                    *  [This seems to work as long as a tag isn't a line
-                    *   crosser; when it is, the position of anchors on either
-                    *   side of the split tag, seem to "float" and try to be
-                    *   as "centered" as possible.  Which means that simply
-                    *   incrementing the line_pos by the fixed value of the
-                    *   number of digits that got added to some tag in either
-                    *   line doesn't work quite right, and the text for (say)
-                    *   a button may get stomped on by another copy of itself,
-                    *   but offset by a few chars, when it is selected (eg,
-                    *   "Box Office" may end up looking like "BoBox Office" or
-                    *   "Box Officece", etc.
+                    *  We keep the the same number of chars from the
+                    *  adjusted tag number in the current line; any
+                    *  extra chars due to a digits increase, will be
+                    *  stuffed into the next line.
                     *
-                    *   Dunno how to fix that behavior ATT, but at least the
-                    *   tag numbers themselves are correct.  -KED  /\oo/\ ]
+                    *  Keep track of any digits added, for the next
+                    *  pass through.
                     */
-                   if (new_n -= n) {
-                       nxt_anchor = st_anchor;
-                       while ((nxt_anchor)                       &&
-                           (nxt_anchor->line_num == a->line_num)) {
-                           nxt_anchor->line_pos += new_n;
-                           nxt_anchor = nxt_anchor->next;
-                       }
-                       st_anchor = st_anchor->next;
-                   }
-               }
-           }
+                   s   = strncpy (s, lx, pre_n) + pre_n;
+                   lx += pre_n;
+                   strcpy (ht->next->data, lx);
 
-           /*
-            *  Unfortunately, valid [tag] strings *can* be split across two
-            *  lines.  Perhaps it would be best to just prevent that from
-            *  happening, but a look into that code, makes me wonder.  Anyway,
-            *  we can handle such tags without *too* much trouble in here [I
-            *  think], though since such animals are rather rare, it makes it
-            *  a bit difficult to test thoroughly (ie, Beyond here, there be
-            *  Dragons).
-            *
-            *  We use lxbuf[] to deal with the two lines involved.
-            */
-           if (plx) {
-               strcpy (lx, p);      /* <- 1st part of a possible lx'ing tag  */
-               pre_n = strlen (p);  /* count of 1st part chars in this line  */
-               strcat (lx, ht->next->data);  /* tack on NEXT line          */
-
-               t = lx;
-               n = 0;
-               valid = TRUE;
-
-               /*
-                *  Go hunting again for just digits, followed by a tag end ']'.
-                */
-               while (*t != ']') {
-                   if (isdigit (*t++) != 0) {
-                       n++;
-                       continue;
-                   } else {
-                       valid = FALSE;
-                       break;
-                   }
-               }
-
-               /*
-                *  It *looks* like a line crosser; now we value test it to
-                *  find out for sure [but see the "false match" warning,
-                *  above], and if it matches, increment it into the buffer,
-                *  along with the 2nd line's text.
-                */
-               if ((valid) && (n > 0)) {
-                   val = atoi (lx);
-                   if ((val == *old_val) || (*old_val == 0)) {
-                       if (*old_val != 0)
-                           (*old_val)++;
-                       val += incr;
-                       sprintf (lx, "%d", val);
-                       new_n = strlen (lx);
-                       strcat (lx, strchr (ht->next->data, ']'));
-
-                       /*
-                        *  We keep the the same number of chars from the
-                        *  adjusted tag number in the current line; any
-                        *  extra chars due to a digits increase, will be
-                        *  stuffed into the next line.
-                        *
-                        *  Keep track of any digits added, for the next
-                        *  pass through.
-                        */
-                       s   = strncpy (s, lx, pre_n) + pre_n;
-                       lx += pre_n;
-                       strcpy (ht->next->data, lx);
-
-                       *lx_val = new_n - n;
-                   }
-               }
-               break;  /* had an lx'er, so we're done with this line */
-           }
+                  *lx_val = new_n - n;
+                }
+             }
+             break;  /* had an lx'er, so we're done with this line */
+          }
        }
     }
 
@@ -8938,7 +8943,7 @@
 
     n = strlen (ht->data);
     if (mode == CHOP)
-       *(buf + n) = '\0';
+       *(buf + n) = '\0';
     strcpy (ht->data, buf);
 
     return (strlen (buf) - n + fixup);
@@ -8958,7 +8963,7 @@
  *  --KED  02/01/99
  */
 PUBLIC int HText_ExtEditForm ARGS1(
-          struct link *,  form_link)
+           struct link *,  form_link)
 {
     struct stat stat_info;
 
@@ -8966,13 +8971,16 @@
     FILE       *fp;
 
     TextAnchor *anchor_ptr;
-    TextAnchor *start_anchor = NULL;
-    TextAnchor *end_anchor   = NULL;
-    BOOLEAN    firstanchor  = TRUE;
-    int        entry_line   = form_link->anchor_line_num;
-    int        exit_line    = 0;
-    int        orig_cnt     = 0;
-    int        line_cnt     = 1;
+    TextAnchor *start_anchor  = NULL;
+    TextAnchor *end_anchor    = NULL;
+    BOOLEAN    firstanchor   = TRUE;
+
+    char        ed_offset[10] = "\0";
+    int         start_line;
+    int         entry_line    = form_link->anchor_line_num;
+    int         exit_line     = 0;
+    int        orig_cnt      = 0;
+    int        line_cnt      = 1;
 
     FormInfo   *form    = form_link->form;
     char       *areaname = form->name;
@@ -8991,13 +8999,14 @@
     char       *cp;
     char       *p;
     char       *s;
-    int        curr_tag;
-    int        line_adj = 0;
-    int        tag_adj  = 0;
+    int         curr_tag;
+    int         line_adj = 0;
+    int         tag_adj  = 0;
+    int         newlines = 0;
     int        len;
     int        i;
     int        n;
-    int        lx;
+    int         lx;
     size_t     size;
 
 
@@ -9035,8 +9044,9 @@
            !strcmp (anchor_ptr->input_field->name, areaname))   {
 
            if (firstanchor) {
-               firstanchor = FALSE;
+               firstanchor  = FALSE;
                start_anchor = anchor_ptr;
+               start_line   = anchor_ptr->line_num;
            }
            orig_cnt++;
 
@@ -9056,13 +9066,23 @@
     fclose (fp);
 
     CTRACE(tfp, "GridText: TEXTAREA name=|%s| dumped to tempfile\n", areaname);
+    CTRACE(tfp, "GridText: invoking editor (%s) on tempfile\n", editor);
 
     /*
-     * Go edit the TEXTAREA temp file.
+     * Go edit the TEXTAREA temp file, with the initial editor line
+     *  corresponding to the TEXTAREA line the cursor is on (if such
+     *  positioning is supported by the editor [as lynx knows it]).
      */
-    HTSprintf0 (&tbuf, "%s %s", editor, ed_temp);
+    if (((entry_line - start_line) > 0) && editor_can_position())
+#ifdef VMS
+       sprintf (ed_offset, "-%d", ((entry_line - start_line) + 1));
+    HTSprintf0 (&tbuf, "%s %s %s", editor, ed_temp, ed_offset);
+#else
+       sprintf (ed_offset, "+%d", ((entry_line - start_line) + 1));
+    HTSprintf0 (&tbuf, "%s %s %s", editor, ed_offset, ed_temp);
+#endif
 
-    LYSystem (tbuf);
+    LYSystem (tbuf);   /* finally the editor is called */
 
 #ifdef UNIX
     /*
@@ -9077,11 +9097,11 @@
     CTRACE(tfp, "GridText: returned from editor (%s)\n", editor);
 
     /*
-     * Read back the edited temp file.
+     * Read back the edited temp file into our buffer.
      */
     if ((stat (ed_temp, &stat_info) < 0)   ||
-       !S_ISREG(stat_info.st_mode)        ||
-       ((size = stat_info.st_size) == 0)) {
+       !S_ISREG(stat_info.st_mode)        ||
+        ((size = stat_info.st_size) == 0)) {
        size = 0;
        ebuf = (char *) calloc (1, 1);
     } else {
@@ -9100,9 +9120,6 @@
     while ((size != 0) && (isspace (ebuf[size-1]) || (ebuf[size-1] == '\0')))
        ebuf[--size] = '\0';
 
-    if (size == 0)
-       ebuf[0] = '\0'; 
-
     /*
      * Copy each line from the temp file into the corresponding anchor
      *  struct, removing any trailing whitespace, expanding any embedded
@@ -9133,48 +9150,57 @@
         *  Whack off trailing whitespace from the line.
         */
        for (i = len, p = line + (len - 1); i != 0; p--, i--) {
-           if (isspace(*p))
-               *p = '\0';
+           if (isspace (*p))
+              *p = '\0';
            else
-               break;
+              break;
        }
 
        if (strlen (line) != 0) {
-           /*
-            *  Expand any tab's, since they won't render properly in a
-            *  TEXTAREA.
-            *
-            *  [is that "by spec", or just a "lynxism" ? ... as may be, it
-            *   seems they may cause other problems, too ... haven't really
-            *   looked into that very deeply though]
-            */
-           p = line;
-           s = tbuf;
-
-           while (*p) {
-               if ((cp = strchr (p, '\t')) != 0) {
-                   i  = cp - p;
-                   s  = (strncpy (s, p, i))      + i;
-                   n  = TABSTOP - (i % TABSTOP);
-                   s  = (strncpy (s, SPACES, n)) + n;
-                   p += (i + 1);
-
-               } else {
-
-                   strcpy (s, p);
-                   break;
-               }
-           }
+          /*
+           *  Expand any tab's, since they won't render properly in a
+           *  TEXTAREA.
+           *
+           *  [is that "by spec", or just a "lynxism" ? ... as may be, it
+           *   seems they may cause other problems, too ... haven't really
+           *   looked into that very deeply though]
+           */
+          p = line;
+          s = tbuf;
+
+          while (*p) {
+              if ((cp = strchr (p, '\t')) != 0) {
+                 i  = cp - p;
+                 s  = (strncpy (s, p, i))      + i;
+                 n  = TABSTOP - (i % TABSTOP);
+                 s  = (strncpy (s, SPACES, n)) + n;
+                 p += (i + 1);
+
+              } else {
+
+                 strcpy (s, p);
+                 break;
+              }
+          }
 
-           /*
-            *  Replace control chars with something printable.  Note that
-            *  we leave any chars above 0x7f alone (ie, no translation is
-            *  performed ... the assumption being that the charset used in
-            *  the editor is compatible with the charset rendered by lynx).
-            */
-           for (p = line, s = tbuf; *s != '\0'; p++, s++)
-               *p = (*s < ' ') ? SPLAT : *s;
-           *p = '\0';
+          /*
+           *  Replace control chars with something printable.  Note that
+           *  we leave any chars above 0x7f alone (ie, no translation is
+           *  performed ... the assumption being that the charset used in
+           *  the editor is compatible with the charset rendered by lynx).
+           *
+           *  [At some point in time, when/if lynx ever supports multibyte
+           *   characters internally (eg, UCS-2, UCS-4, UTF-16, etc), this
+           *   kind of thing may well cause problems.  But then, supporting
+           *   such char sets will require massive changes in (most) all
+           *   parts of the lynx code, so until then, we do the rational
+           *   thing with chars that would otherwise foul the display, if
+           *   left alone.  If you're implementing multibyte character set
+           *   support, consider yourself to have been warned.]
+           */
+          for (p = line, s = tbuf; *s != '\0'; p++, s++)
+              *p = (*s < ' ') ? SPLAT : *s;
+          *p = '\0';
        }
 
 
@@ -9187,86 +9213,106 @@
         */
        if (line_cnt > orig_cnt) {
 
-           /*
-            *  Find line in the text that matches ending anchorline of
-            *  the TEXTAREA.
-            *
-            *  [Yes, Virginia ... we *do* have to go thru this for each
-            *   anchor being added, since there is NOT a 1-to-1 mapping
-            *   between anchors and htlines.  I suppose we could create
-            *   YAS (Yet Another Struct), but there are too many structs{}
-            *   floating around in here, as it is.  IMNSHO.]
-            */
-           for (htline = HTMainText->last_line->next, i = 0;
-               i != end_anchor->line_num;
-               htline = htline->next, i++);
-
-           /*
-            *  Clone and initialize the structs needed to add a new
-            *  TEXTAREA anchor.
-            */
-           if (((a = (TextAnchor *) calloc (1, sizeof(*a)))          == 0)  ||
-               ((f = (FormInfo   *) calloc (1, sizeof(*f)))          == 0)  ||
-               ((l = (HTLine     *) calloc (1, LINE_SIZE(MAX_LINE))) == 0))
-               outofmem(__FILE__, "HText_ExtEditForm");
-
-           /*  Init all the fields in the new TextAnchor.  */
-           a->next            = end_anchor->next;
-           a->number          = end_anchor->number;
-           a->start           = end_anchor->start +
+          /*
+           *  Find line in the text that matches ending anchorline of
+           *  the TEXTAREA.
+           *
+           *  [Yes, Virginia ... we *do* have to go thru this for each
+           *   anchor being added, since there is NOT a 1-to-1 mapping
+           *   between anchors and htlines.  I suppose we could create
+           *   YAS (Yet Another Struct), but there are too many structs{}
+           *   floating around in here, as it is.  IMNSHO.]
+           */
+          for (htline = HTMainText->last_line->next, i = 0;
+               end_anchor->line_num != i;            i++) {
+              htline = htline->next;
+              if (htline == HTMainText->last_line)
+                 break;
+          }
+
+          /*
+           *  Clone and initialize the structs needed to add a new
+           *  TEXTAREA anchor.
+           */
+          if (((a = (TextAnchor *) calloc (1, sizeof(*a)))          == 0)  ||
+              ((f = (FormInfo   *) calloc (1, sizeof(*f)))          == 0)  ||
+              ((l = (HTLine     *) calloc (1, LINE_SIZE(MAX_LINE))) == 0))
+             outofmem(__FILE__, "HText_ExtEditForm");
+
+          /*  Init all the fields in the new TextAnchor.                 */
+          /*  [anything "special" needed based on ->show_anchor value ?] */
+          a->next             = end_anchor->next;
+          a->number           = end_anchor->number;
+          a->start            = end_anchor->start +
                                 end_anchor->input_field->size + 1;
-           a->line_pos        = end_anchor->line_pos;
-           a->extent          = end_anchor->extent;
-           a->line_num        = end_anchor->line_num + 1;
-           StrAllocCopy (a->hightext,  end_anchor->hightext);
-           StrAllocCopy (a->hightext2, end_anchor->hightext2);
-           a->hightext2offset  = end_anchor->hightext2offset;
-           a->link_type        = end_anchor->link_type;
-           a->input_field      = f;
-           a->show_anchor      = end_anchor->show_anchor;
-           a->inUnderline      = end_anchor->inUnderline;
-           a->anchor           = end_anchor->anchor;
-
-           /*  Just the (seemingly) relevant fields in the new FormInfo.  */
-           StrAllocCopy (f->name, end_anchor->input_field->name);
-           f->number          = end_anchor->input_field->number;
-           f->type            = end_anchor->input_field->type;
-           StrAllocCopy (f->orig_value, "");
-           f->size            = end_anchor->input_field->size;
-           f->maxlength       = end_anchor->input_field->maxlength;
-           f->no_cache        = end_anchor->input_field->no_cache;
-
-           /*  Init all the fields in the new HTLine (but see the #if).   */
-           l->next            = htline->next;
-           l->prev            = htline;
-           l->offset          = htline->offset;
-           l->size            = htline->size;
-           l->split_after      = htline->split_after;
-           l->bullet          = htline->bullet;
+          a->line_pos         = end_anchor->line_pos;
+          a->extent           = end_anchor->extent;
+          a->line_num         = end_anchor->line_num + 1;
+          StrAllocCopy (a->hightext,  end_anchor->hightext);
+          StrAllocCopy (a->hightext2, end_anchor->hightext2);
+          a->hightext2offset  = end_anchor->hightext2offset;
+          a->link_type        = end_anchor->link_type;
+          a->input_field      = f;
+          a->show_anchor      = end_anchor->show_anchor;
+          a->inUnderline      = end_anchor->inUnderline;
+          a->expansion_anch   = TRUE;
+          a->anchor           = NULL;
+
+          /*  Just the (seemingly) relevant fields in the new FormInfo.  */
+          /*  [do we need to do anything "special" based on ->disabled]  */
+          StrAllocCopy (f->name, end_anchor->input_field->name);
+          f->number           = end_anchor->input_field->number;
+          f->type             = end_anchor->input_field->type;
+          StrAllocCopy (f->orig_value, "");
+          f->size             = end_anchor->input_field->size;
+          f->maxlength        = end_anchor->input_field->maxlength;
+          f->no_cache         = end_anchor->input_field->no_cache;
+          f->disabled         = end_anchor->input_field->disabled;
+
+          /*  Init all the fields in the new HTLine (but see the #if).   */
+          l->next             = htline->next;
+          l->prev             = htline;
+          l->offset           = htline->offset;
+          l->size             = htline->size;
+          l->split_after      = htline->split_after;
+          l->bullet           = htline->bullet;
+          l->expansion_line   = TRUE;
 #if defined(USE_COLOR_STYLE)
-           /* dup styles[] if needed [no need in TEXTAREA (?); leave 0's] */
-           l->numstyles        = htline->numstyles;
+          /* dup styles[] if needed [no need in TEXTAREA (?); leave 0's] */
+          l->numstyles        = htline->numstyles;
 #endif
-           strcpy (l->data,      htline->data);
-           if (keypad_mode == LINKS_AND_FORM_FIELDS_ARE_NUMBERED) {
-               a->number++;
-               curr_tag = 0;  /* 0 matches any [tag] number */
-               lx       = 0;
-               increment_tagged_htline (l, a, &lx, &curr_tag, 1, CHOP);
-           }
+          strcpy (l->data,      htline->data);
+          if (keypad_mode == LINKS_AND_FORM_FIELDS_ARE_NUMBERED) {
+             a->number++;
+             curr_tag = 0;  /* 0 matches any [tag] number */
+             lx       = 0;
+             increment_tagged_htline (l, a, &lx, &curr_tag, 1, CHOP);
+          }
 
-           /*
-            *  Link in the new TextAnchor and make it current; link in
-            *  the new HTLine.
-            */
-           end_anchor->next = a;
-           anchor_ptr = a;
+          /*
+           *  If we're at the tail end of the TextAnchor or HTLine list(s),
+           *  the new node becomes the last node.
+           */
+          if (end_anchor == HTMainText->last_anchor)
+             HTMainText->last_anchor = a;
+          if (htline == HTMainText->last_line)
+             HTMainText->last_line = l;
+
+          /*
+           *  Link in the new TextAnchor and make it current; link in
+           *  the new HTLine.
+           */
+          end_anchor->next = a;
+          anchor_ptr = a;
+
+          htline->next->prev = l;
+          htline->next = l;
+          htline = l->next;
 
-           htline->next->prev = l;
-           htline->next = l;
-           htline = l;
+          newlines++;
        }
 
+
        /*
         *  Finally copy the new line from the edit buffer into the anchor.
         */
@@ -9274,22 +9320,25 @@
 
 
        /*
-        *  And do the next line, for the next anchor ...
+        *  Keep track of 1st blank line in any trailing blank lines, for
+        *  later cursor repositioning.
         */
-       lp += len;
-       if (*lp) lp++;
-
        if (len > 0)
-           exit_line = 0;
+          exit_line = 0;
        else if (exit_line == 0)
-           exit_line = anchor_ptr->line_num;
+          exit_line = anchor_ptr->line_num;
+
+       /*
+        *  And do the next line of edited text, for the next anchor ...
+        */
+       lp += len;
+       if (*lp) lp++;
 
        end_anchor = anchor_ptr;
        anchor_ptr = anchor_ptr->next;
-       curr_tag   = anchor_ptr->number;
 
-       if (htline != NULL)
-           htline   = htline->next;
+       if (anchor_ptr)
+          curr_tag = anchor_ptr->number;
 
        line_cnt++;
     }
@@ -9306,16 +9355,24 @@
      * [dunno if the char counts really need to be done, or if we're using
      *  the exactly proper values ... seems to be OK though ...]
      */
-    if ((n = (line_cnt - 1) - orig_cnt) > 0) {
-       i = (end_anchor->input_field->size + 1) * n;
+    if (newlines > 0) {
 
-       while (anchor_ptr) {
+       CTRACE(tfp, "GridText: adjusting struct's to add %d new lines\n",
+                    newlines);
+
+        i = (end_anchor->input_field->size + 1) * newlines;
+
+       /*
+        *  [*may* need to bypass bumping ->number if ->input_field->type
+        *  is of F_HIDDEN_TYPE ... need to investigate further]
+        */
+        while (anchor_ptr) {
            if (keypad_mode == LINKS_AND_FORM_FIELDS_ARE_NUMBERED)
-              anchor_ptr->number += n;
-           anchor_ptr->line_num  += n;
+              anchor_ptr->number += newlines;
+           anchor_ptr->line_num  += newlines;
            anchor_ptr->start     += i;
-           anchor_ptr             = anchor_ptr->next;
-       }
+           anchor_ptr             = anchor_ptr->next;
+        }
        anchor_ptr = end_anchor;
 
        /*
@@ -9340,39 +9397,59 @@
         *
         *  Yes, it *can* happen, but in real life, it probably won't be
         *  seen very much ...
+        *
+        *  [This may also be an artifact of bumping into the right hand
+        *   screen edge (or RHS margin), since we don't even *think* about
+        *   relocating an anchor to the following line, when [tag] digits
+        *   expansion pushes things too far in that direction.]
         */
        if (keypad_mode == LINKS_AND_FORM_FIELDS_ARE_NUMBERED) {
-           lx = 0;
-           while (htline != HTMainText->last_line->next) {
-               while (anchor_ptr) {
-                   if ((anchor_ptr->number - n) == curr_tag)
-                       break;
-                   else
-                       anchor_ptr = anchor_ptr->next;
-               }
-               line_adj = increment_tagged_htline (htline, anchor_ptr, &lx,
-                                                  &curr_tag, n, NOCHOP);
-               htline->size += line_adj;
-               tag_adj      += line_adj;
-               htline = htline->next;
+          lx = 0;
+          while (htline != HTMainText->last_line->next) {
+
+              while (anchor_ptr) {
+                  if ((anchor_ptr->number - newlines) == curr_tag)
+                     break;
+                  else
+                     anchor_ptr = anchor_ptr->next;
+              }
+
+              if (anchor_ptr) {
+                 line_adj = increment_tagged_htline (htline,   anchor_ptr,
+                                                      &lx,      &curr_tag,
+                                                      newlines, NOCHOP);
+                 htline->size += line_adj;
+                 tag_adj      += line_adj;
+
+              } else {
+
+                 break;  /* out of anchors ... we're done */
+              }
+
+              htline = htline->next;
           }
        }
 
-       nlinks                         += n;
-       HTMainText->Lines              += n;
-       HTMainText->last_anchor_number += n;
-       HTMainText->chars              += (i + tag_adj);
+       /*
+        *  Fixup various global variables.
+        */
+       nlinks                         += newlines;
+        HTMainText->Lines              += newlines;
+       HTMainText->last_anchor_number += newlines;
+        HTMainText->chars              += (i + tag_adj);
+
+       more = TRUE;
 
-       if (n) more = TRUE;
+       CTRACE(tfp, "GridText: TextAnchor and HTLine struct's adjusted\n");
     }
 
-    CTRACE(tfp, "GridText: struct's adjusted - exiting HText_ExtEditForm()\n");
-
     free (line);
     free (ebuf);
     free (tbuf);
     LYRemoveTemp (ed_temp);
     free (ed_temp);
+
+    CTRACE(tfp, "GridText: exiting HText_ExtEditForm()\n");
 
     /*
      *  Return the offset needed to move the cursor from its current
diff -uNr lynx-2.8.2-dev.16+kd.orig/src/LYEdit.c 
lynx-2.8.2-dev.16+kd/src/LYEdit.c
--- lynx-2.8.2-dev.16+kd.orig/src/LYEdit.c      Wed Jan 13 03:37:34 1999
+++ lynx-2.8.2-dev.16+kd/src/LYEdit.c   Tue Feb  9 18:46:43 1999
@@ -15,7 +15,7 @@
 
 #include <LYLeaks.h>
 
-PRIVATE BOOLEAN editor_can_position NOARGS
+PUBLIC BOOLEAN editor_can_position NOARGS
 {
 #ifdef VMS
     return (strstr(editor, "sedt") || strstr(editor, "SEDT"));
diff -uNr lynx-2.8.2-dev.16+kd.orig/src/LYEdit.h 
lynx-2.8.2-dev.16+kd/src/LYEdit.h
--- lynx-2.8.2-dev.16+kd.orig/src/LYEdit.h      Thu Aug  6 05:28:22 1998
+++ lynx-2.8.2-dev.16+kd/src/LYEdit.h   Tue Feb  9 18:46:43 1999
@@ -5,4 +5,6 @@
 
 extern int edit_current_file PARAMS((char *newfile, int cur, int lineno));
 
+extern BOOLEAN editor_can_position NOPARAMS;
+
 #endif /* LYEDIT_H */
diff -uNr lynx-2.8.2-dev.16+kd.orig/src/structdump.h 
lynx-2.8.2-dev.16+kd/src/structdump.h
--- lynx-2.8.2-dev.16+kd.orig/src/structdump.h  Mon Feb  8 02:32:59 1999
+++ lynx-2.8.2-dev.16+kd/src/structdump.h       Tue Feb  9 18:46:43 1999
@@ -57,6 +57,7 @@
             "      input_field=|%s|\n"   \
             "      show_anchor=%1x\n"    \
             "      inUnderline=%1x\n"    \
+            "   expansion_anch=%1x\n"    \
             "          *anchor=0x%08x\n" \
             "}\n", \
             (A), sizeof(*((A))), \
@@ -64,8 +65,8 @@
             (A)->extent, (A)->line_num, \
             (A)->hightext, (A)->hightext, (A)->hightext2, (A)->hightext2, \
             (A)->hightext2offset, (A)->link_type, \
-            (A)->input_field, (A)->input_field, \
-            (A)->show_anchor, (A)->inUnderline, (A)->anchor); \
+            (A)->input_field, (A)->input_field, (A)->show_anchor, \
+            (A)->inUnderline, (A)->expansion_anch, (A)->anchor); \
 CTRACE_FLUSH(tfp);
 
 
@@ -118,20 +119,21 @@
 #define   DUMPSTRUCT_LINE(L,X) \
 CTRACE(tfp, "\n" \
             "KED: htline_ptr=0x%08x  sizeof=%d  ["X"]\n" \
-            "HTLine struct {\n"      \
-            "        *next=0x%08x\n" \
-            "        *prev=0x%08x\n" \
-            "       offset=%d\n"     \
-            "         size=%d\n"     \
-            "  split_after=%1x\n"    \
-            "       bullet=%1x\n"    \
-            "nodef U_C_S\n"          \
-            "       data[]=0x%08x\n" \
-            "         data=|%s|\n"   \
+            "HTLine  struct {\n"      \
+            "         *next=0x%08x\n" \
+            "         *prev=0x%08x\n" \
+            "        offset=%d\n"     \
+            "          size=%d\n"     \
+            "   split_after=%1x\n"    \
+            "        bullet=%1x\n"    \
+            "expansion_line=%1x\n"    \
+            "w/o U_C_S def\n"         \
+            "        data[]=0x%08x\n" \
+            "          data=|%s|\n"   \
             "}\n", \
             (L), sizeof(*((L))), \
             (L)->next, (L)->prev, (L)->offset, (L)->size, (L)->split_after, \
-            (L)->bullet, (L)->data, (L)->data); \
+            (L)->bullet, (L)->expansion_line, (L)->data, (L)->data); \
 CTRACE_FLUSH(tfp);
 
 #endif /* STRUCTDUMP_H */
##--eof--##

reply via email to

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