lynx-dev
[Top][All Lists]
Advanced

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

lynx-dev [dev.15] fixup patch: edit TEXTAREA


From: Kim DeVaughn
Subject: lynx-dev [dev.15] fixup patch: edit TEXTAREA
Date: Fri, 29 Jan 1999 11:12:39 -0800

The attached patch fixes a couple bugs that crept into the edit
TEXTAREA feature.

Also:

 1. Thanks to a suggestion by Bela, your regular EDIT keybinding ("e"
    by default), will now bring up the editor within a TEXTAREA, so
    there's no need to "waste" a seperate keybinding (though you can
    still additionally bind the function seperately, if desired).


 2. Converts any tab chars in the edited file, to spaces in the
    TEXTAREA anchor line.  The tabstop is currently #define'd
    to the quasi-standard value of 8.  (If anyone thinks that
    needs to be user configurable, feel free to add that to the
    o(ptions) form/menu, cmd-line-arg/lynx.cfg/.lynxrc/userdefs.h,
    whatever ...

    I recommend against doing so though, as tabstops that are not
    set at 8, are a PITA to deal with, generally speaking.

    I dunno if tab chars in a TEXTAREA form are prohibited "by spec",
    or if it is just a "lynxism" that they cause rendering problems
    (as well as downstream problems with submit/etc, I think), but
    I felt I needed to do something to make lynx behave rationally if
    they are present in the edited data (quite possibly from an
    arbitrary file that one pulled into the editor).

    Filtering them to spaces, seemed the most reasonable thing to
    do.


 3. Replaces any embedded control chars with something printable (I
    chose a "." char, since it is less "intrusive" than some other
    choices, like "*", "+", "#", etc).

    As with tabs, when some of these chars *are* rendered into the
    TEXTAREA, strange things may happen.

    This shouldn't be much of a limitation, since many of these chars
    perform line-editing or system/job-control functions, when entered
    directly while one is in the TEXTAREA.  They currently cannot be
    "escaped" and entered as actual text chars, so far as I can tell.

    Anyway ... I don't know of any "legitimate" reason for them to be
    used as TEXTAREA data, so for now, you get "dots" in their place.


 4. Cleans up a few comments, and such.


I've seen a number of good comments and suggestions related to this
feature in other threads.  I have a few thoughts on these, but I'll
reply in a separate posting, a bit later.

/kim


Against 2.8.2dev.15:

diff -uNr lynx-2.8.2-dev.15+kd.orig/CHANGES lynx-2.8.2-dev.15+kd/CHANGES
--- lynx-2.8.2-dev.15+kd.orig/CHANGES   Thu Jan 28 08:31:29 1999
+++ lynx-2.8.2-dev.15+kd/CHANGES        Fri Jan 29 07:43:28 1999
@@ -24,7 +24,7 @@
   (but never used), except for some memory cleanup.  Use -DNO_RULES at compile
   time to disable - KW
 * add changes to invoke external editor on textarea, can be invoked by adding a
-  KEYMAP entry for EDITTEXT area to lynx.cfg (originally from
+  KEYMAP entry for EDITTEXTAREA to lynx.cfg (originally from
   address@hidden, but much rework) - KED
 * use HTSprintf0 in HTTCP.c - TD
 * added PARSE_STRICTPATH and PARSE_QUERY to interface of HTParse(), for
diff -uNr lynx-2.8.2-dev.15+kd.orig/src/GridText.c 
lynx-2.8.2-dev.15+kd/src/GridText.c
--- lynx-2.8.2-dev.15+kd.orig/src/GridText.c    Fri Jan 29 07:55:06 1999
+++ lynx-2.8.2-dev.15+kd/src/GridText.c Fri Jan 29 08:08:38 1999
@@ -8704,10 +8704,10 @@
 
     TextAnchor *anchor_ptr;
     TextAnchor *start_anchor = NULL;
-    TextAnchor *end_anchor  = NULL;
-    BOOLEAN    firstanchor = TRUE;
-    int        orig_cnt    = 0;
-    int        line_cnt    = 1;
+    TextAnchor *end_anchor   = NULL;
+    BOOLEAN    firstanchor  = TRUE;
+    int        orig_cnt     = 0;
+    int        line_cnt     = 1;
 
     FormInfo   *form    = form_link->form;
     char       *areaname = form->name;
@@ -8722,8 +8722,10 @@
     char       *ebuf;
     char       *tbuf = NULL;
     char       *line;
+    char       *lp;
     char       *cp;
     char       *p;
+    char       *s;
     int        len;
     int        i;
     int        n;
@@ -8761,13 +8763,13 @@
            !strcmp (anchor_ptr->input_field->name, areaname))   {
 
            if (firstanchor) {
-               firstanchor = FALSE;
+               firstanchor = FALSE;
                start_anchor = anchor_ptr;
            }
            orig_cnt++;
 
            /*
-            * Write the anchor's text to the temp edit file.
+            *  Write the anchors' text to the temp edit file.
             */
            fputs (anchor_ptr->input_field->value, fp);
            fputc ('\n', fp);
@@ -8799,13 +8801,13 @@
     free (tbuf);
 
     /*
-     * Read back the edited temp file, whacking off any trailing whitespace.
+     * Read back the edited temp file.
      */
     if (stat (ed_temp, &stat_info) < 0
      || !S_ISREG(stat_info.st_mode)
      || (size = stat_info.st_size) == 0) {
        size = 0;
-       ebuf = malloc(1);
+       ebuf = (char *) calloc (1, 1);
     } else {
        ebuf = (char *) calloc (size + 1, (sizeof(char)));
 
@@ -8819,44 +8821,80 @@
     /*
      * Nuke any blank lines from the end of the edited data.
      */
-    while ((size != 0) && isspace(ebuf[size-1]))
+    while ((size != 0) && (isspace(ebuf[size-1]) || (ebuf[size-1] == '\0')))
        ebuf[--size] = '\0';
 
     /*
      * Copy each line from the temp file into the corresponding anchor
-     * struct, removing any trailing whitespace.  Add new lines to the
-     * TEXTAREA if needed.  (Always leave the user with a blank line at
-     * the end of the TEXTAREA.)
+     *  struct, removing any trailing whitespace, expanding any embedded
+     *  tab's, and substituting a printable char for any other embedded
+     *  control chars.  Add new lines to the TEXTAREA if needed.  (Always
+     *  leave the user with a blank line at the end of the TEXTAREA.)
      */
-    if ((line = (char *) malloc (MAX_LINE)) == 0)
+    if (((line = (char *) malloc (MAX_LINE)) == 0) ||
+       ((tbuf = (char *) malloc (MAX_LINE)) == 0))
        outofmem(__FILE__, "HText_ExtEditForm");
 
     anchor_ptr = start_anchor;
     len = 0;
-    p = ebuf;
+    lp  = ebuf;
 
-    while ((line_cnt <= orig_cnt) || (*p) || ((len != 0) && (*p == '\0'))) {
+    while ((line_cnt <= orig_cnt) || (*lp) || ((len != 0) && (*lp == '\0'))) {
 
-       if ((cp = strchr (p, '\n')) != 0)
-          len = cp - p;
+       if ((cp = strchr (lp, '\n')) != 0)
+          len = cp - lp;
        else
-          len = strlen (p);
+          len = strlen (lp);
 
-       strncpy(line, "\0", MAX_LINE);
-       strncpy(line, p, len);
-
-       cp = p;
+       strncpy (line, "\0", MAX_LINE);
+       strncpy (line, lp, len);
 
        /*
         *  Whack off trailing whitespace from the line.
-        *
-        *  [maybe use isspace() here instead, too (portable ?)]
         */
-       for (size = MAX_LINE, p = line + size - 1; size != 0; p--, size--) {
-           if (isspace(*p))
-               *p = '\0';
+       for (size = MAX_LINE, p = line + (size - 1); size != 0; p--, size--) {
+           if ((isspace(*p)) || (*p == '\0'))
+              *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')) {
+                 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';
        }
 
        /*
@@ -8864,7 +8902,7 @@
         *  original TEXTAREA, we need to add some new lines, continuing
         *  until the edit buffer is empty.
         *
-        *  [cloning structs should me moved to a seperate fn(), or three]
+        *  [cloning structs could be moved to a seperate fn(), or three]
         */
        if (line_cnt > orig_cnt) {
 
@@ -8885,7 +8923,7 @@
            || (l = (HTLine     *) calloc (1, LINE_SIZE(MAX_LINE))) == 0)
                outofmem(__FILE__, "HText_ExtEditForm");
 
-          /*  Init all the fields in the new anchor.  */
+          /*  Init all the fields in the new TextAnchor.  */
           a->next             = end_anchor->next;
           a->number           = end_anchor->number;
           a->start            = end_anchor->start +
@@ -8893,7 +8931,7 @@
           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->hightext,  end_anchor->hightext);
           StrAllocCopy (a->hightext2, end_anchor->hightext2);
           a->hightext2offset  = end_anchor->hightext2offset;
           a->link_type        = end_anchor->link_type;
@@ -8902,7 +8940,7 @@
           a->inUnderline      = end_anchor->inUnderline;
           a->anchor           = end_anchor->anchor;
 
-          /*  Just the (seemingly) relevant fields in the FormInfo.    */
+          /*  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;
@@ -8911,7 +8949,7 @@
           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).  */
+          /*  Init all the fields in the new HTLine (but see the #if).   */
           l->next             = htline->next;
           l->prev             = htline;
           l->offset           = htline->offset;
@@ -8923,8 +8961,8 @@
           l->numstyles        = htline->numstyles;
 #endif
           for (i = 0; htline->data[i] != '\0'; i++)
-              l->data[i] = htline->data[i];
-          l->data[i] = '\0';
+              l->data[i]      = htline->data[i];
+          l->data[i]          = '\0';
 
           /*
            *  Link in the new TextAnchor and make it current; link in
@@ -8946,8 +8984,8 @@
        /*
         *  And do the next line, for the next anchor ...
         */
-       p = cp + len;
-       if (*p) p++;
+       lp += len;
+       if (*lp) lp++;
 
        end_anchor = anchor_ptr;
        anchor_ptr = anchor_ptr->next;
@@ -8976,14 +9014,15 @@
         HTMainText->chars += i;
     }
 
-    /*** MOVE the cursor to some logical place ... 1st/only blank line in
-     ***         the textarea seems most reasonable; lacking that, the end
-     ***         line of the textarea; lacking that ... the 1st line of the
-     ***         textarea; else leave it where it is (as we now do).
+    /*** TODO: Move the cursor to some logical place ... 1st/only trailing
+     ***       blank line in the textarea seems the most reasonable; lacking
+     ***       that, the end line of the textarea; lacking that ... the 1st
+     ***       line of the textarea; else leave it where it is (as we do now).
      ***/
 
     free (line);
     free (ebuf);
+    free (tbuf);
     LYRemoveTemp (ed_temp);
     free (ed_temp);
 
diff -uNr lynx-2.8.2-dev.15+kd.orig/src/GridText.h 
lynx-2.8.2-dev.15+kd/src/GridText.h
--- lynx-2.8.2-dev.15+kd.orig/src/GridText.h    Fri Jan 29 07:34:13 1999
+++ lynx-2.8.2-dev.15+kd/src/GridText.h Thu Jan 28 14:55:01 1999
@@ -27,6 +27,10 @@
 
 #define IsSpecialAttrChar(a)  ((a > '\002') && (a <= '\010'))
 
+#define TABSTOP 8
+#define SPACES  "        "  /* must be at least TABSTOP spaces long */
+#define SPLAT   '.'
+
 /* just for information:
 US-ASCII control characters <32 which are not defined in Unicode standard
 =00    U+0000  NULL
diff -uNr lynx-2.8.2-dev.15+kd.orig/src/LYKeymap.c 
lynx-2.8.2-dev.15+kd/src/LYKeymap.c
--- lynx-2.8.2-dev.15+kd.orig/src/LYKeymap.c    Thu Jan 28 08:31:29 1999
+++ lynx-2.8.2-dev.15+kd/src/LYKeymap.c Fri Jan 29 07:17:26 1999
@@ -607,7 +607,7 @@
 { "SWITCH_DTD",                "switch between two ways of parsing HTML" },
 { "ELGOTO",            "edit the current link's URL or ACTION and go to it" },
 { "CHANGE_LINK",       "force reset of the current link on the page" },
-{ "EDITTEXTAREA",      "use defined external editor to edit the text area" },
+{ "EDITTEXTAREA",      "use an external editor to edit a form's textarea" },
 #ifdef USE_EXTERNALS
 { "EXTERN",            "run external program with url" },
 #endif
diff -uNr lynx-2.8.2-dev.15+kd.orig/src/LYMainLoop.c 
lynx-2.8.2-dev.15+kd/src/LYMainLoop.c
--- lynx-2.8.2-dev.15+kd.orig/src/LYMainLoop.c  Fri Jan 29 09:43:59 1999
+++ lynx-2.8.2-dev.15+kd/src/LYMainLoop.c       Fri Jan 29 09:34:58 1999
@@ -4142,6 +4142,15 @@
                break;
            }
 
+           /*
+            *  If we're in a forms TEXTAREA, invoke the editor on it.
+            */
+           if (links[curdoc.link].type       == WWW_FORM_LINK_TYPE &&
+               links[curdoc.link].form->type == F_TEXTAREA_TYPE)   {
+              cmd = LYK_EDIT_TEXTAREA;
+              goto new_cmd;
+           }
+
 #ifdef DIRED_SUPPORT
            /*
             *  Allow the user to edit the link rather
@@ -4304,9 +4313,11 @@
                break;
            }
 
-               /* is curent link part of a textarea */
-           if (links[curdoc.link].type == WWW_FORM_LINK_TYPE &&
-               links[curdoc.link].form->type == F_TEXTAREA_TYPE) {
+           /*
+            *  See if the current link is in a form TEXTAREA.
+            */
+           if (links[curdoc.link].type       == WWW_FORM_LINK_TYPE &&
+               links[curdoc.link].form->type == F_TEXTAREA_TYPE)   {
 
                /* stop screen */
                stop_curses();
@@ -4317,12 +4328,8 @@
                start_curses();
                refresh_screen = TRUE;
 
-               /*
-               cmd = LYK_REFRESH;
-               goto new_cmd;
-               */
-
            } else {
+
                HTInfoMsg (NOT_IN_TEXTAREA);
            }
            break;
diff -uNr lynx-2.8.2-dev.15+kd.orig/src/structdump.h 
lynx-2.8.2-dev.15+kd/src/structdump.h
--- lynx-2.8.2-dev.15+kd.orig/src/structdump.h  Fri Jan 29 07:34:13 1999
+++ lynx-2.8.2-dev.15+kd/src/structdump.h       Thu Jan 28 15:09:12 1999
@@ -9,24 +9,24 @@
 /* usage: DUMPSTRUCT_LINK(link_ptr, "message"); */
 #define   DUMPSTRUCT_LINK(L,X) \
 CTRACE(tfp, "\n" \
-            "KED:     link_ptr=%08x  sizeof=%d  ["X"]\n" \
-            "link       struct {\n" \
-            "           *lname=%08x\n" \
-            "            lname=|%s|\n" \
-            "          *target=%08x\n" \
-            "           target=|%s|\n" \
-            "        *hightext=%08x\n" \
-            "         hightext=|%s|\n" \
-            "       *hightext2=%08x\n" \
-            "        hightext2=|%s|\n" \
-            " hightext2_offset=%d\n"   \
-            "      inUnderline=%1x\n"  \
-            "               lx=%d\n"   \
-            "               ly=%d\n"   \
-            "             type=%d\n"   \
-            "    anchor_number=%d\n"   \
-            "  anchor_line_num=%d\n"   \
-            "            *form=%08x\n" \
+            "KED:     link_ptr=0x%08x  sizeof=%d  ["X"]\n" \
+            "link       struct {\n"      \
+            "           *lname=0x%08x\n" \
+            "            lname=|%s|\n"   \
+            "          *target=0x%08x\n" \
+            "           target=|%s|\n"   \
+            "        *hightext=0x%08x\n" \
+            "         hightext=|%s|\n"   \
+            "       *hightext2=0x%08x\n" \
+            "        hightext2=|%s|\n"   \
+            " hightext2_offset=%d\n"     \
+            "      inUnderline=%1x\n"    \
+            "               lx=%d\n"     \
+            "               ly=%d\n"     \
+            "             type=%d\n"     \
+            "    anchor_number=%d\n"     \
+            "  anchor_line_num=%d\n"     \
+            "            *form=0x%08x\n" \
             "}\n", \
             (L), sizeof(*((L))), \
             (L)->lname, (L)->lname, (L)->target, (L)->target, \
@@ -39,25 +39,25 @@
 /* usage: DUMPSTRUCT_ANCHOR(anchor_ptr, "message"); */
 #define   DUMPSTRUCT_ANCHOR(A,X) \
 CTRACE(tfp, "\n" \
-            "KED:   anchor_ptr=%08x  sizeof=%d  ["X"]\n" \
-            "TextAnchor struct {\n"    \
-            "            *next=%08x\n" \
-            "           number=%d\n"   \
-            "            start=%d\n"   \
-            "         line_pos=%d\n"   \
-            "           extent=%d\n"   \
-            "         line_num=%d\n"   \
-            "        *hightext=%08x\n" \
-            "         hightext=|%s|\n" \
-            "       *hightext2=%08x\n" \
-            "        hightext2=|%s|\n" \
-            "  hightext2offset=%d\n"   \
-            "        link_type=%d\n"   \
-            "     *input_field=%08x\n" \
-            "      input_field=|%s|\n" \
-            "      show_anchor=%1x\n"  \
-            "      inUnderline=%1x\n"  \
-            "          *anchor=%08x\n" \
+            "KED:   anchor_ptr=0x%08x  sizeof=%d  ["X"]\n" \
+            "TextAnchor struct {\n"      \
+            "            *next=0x%08x\n" \
+            "           number=%d\n"     \
+            "            start=%d\n"     \
+            "         line_pos=%d\n"     \
+            "           extent=%d\n"     \
+            "         line_num=%d\n"     \
+            "        *hightext=0x%08x\n" \
+            "         hightext=|%s|\n"   \
+            "       *hightext2=0x%08x\n" \
+            "        hightext2=|%s|\n"   \
+            "  hightext2offset=%d\n"     \
+            "        link_type=%d\n"     \
+            "     *input_field=0x%08x\n" \
+            "      input_field=|%s|\n"   \
+            "      show_anchor=%1x\n"    \
+            "      inUnderline=%1x\n"    \
+            "          *anchor=0x%08x\n" \
             "}\n", \
             (A), sizeof(*((A))), \
             (A)->next, (A)->number, (A)->start, (A)->line_pos, \
@@ -72,35 +72,35 @@
 /* usage: DUMPSTRUCT_FORM(forminfo_ptr, "message"); */
 #define   DUMPSTRUCT_FORMINFO(F,X) \
 CTRACE(tfp, "\n" \
-            "KED: forminfo_ptr=%08x  sizeof=%d  ["X"]\n" \
-            "FormInfo   struct {\n"    \
-            "            *name=%08x\n" \
-            "             name=|%s|\n" \
-            "           number=%d\n"   \
-            "             type=%d\n"   \
-            "           *value=%08x\n" \
-            "            value=|%s|\n" \
-            "      *orig_value=%08x\n" \
-            "       orig_value=|%s|\n" \
-            "             size=%d\n"   \
-            "        maxlength=%d\n"   \
-            "            group=%d\n"   \
-            "        num_value=%d\n"   \
-            "           hrange=%d\n"   \
-            "           lrange=%d\n"   \
-            "     *select_list=%08x\n" \
-            "    submit_action=|%s|\n" \
-            "    submit_method=%d\n"   \
-            "   submit_enctype=|%s|\n" \
-            "     submit_title=|%s|\n" \
-            "         no_cache=%1x\n"  \
-            "  cp_submit_value=|%s|\n" \
-            "orig_submit_value=|%s|\n" \
-            "           size_l=%d\n"   \
-            "         disabled=%d\n"   \
-            "          name_cs=%d\n"   \
-            "         value_cs=%d\n"   \
-            "        accept_cs=|%s|\n" \
+            "KED: forminfo_ptr=0x%08x  sizeof=%d  ["X"]\n" \
+            "FormInfo   struct {\n"      \
+            "            *name=0x%08x\n" \
+            "             name=|%s|\n"   \
+            "           number=%d\n"     \
+            "             type=%d\n"     \
+            "           *value=0x%08x\n" \
+            "            value=|%s|\n"   \
+            "      *orig_value=0x%08x\n" \
+            "       orig_value=|%s|\n"   \
+            "             size=%d\n"     \
+            "        maxlength=%d\n"     \
+            "            group=%d\n"     \
+            "        num_value=%d\n"     \
+            "           hrange=%d\n"     \
+            "           lrange=%d\n"     \
+            "     *select_list=0x%08x\n" \
+            "    submit_action=|%s|\n"   \
+            "    submit_method=%d\n"     \
+            "   submit_enctype=|%s|\n"   \
+            "     submit_title=|%s|\n"   \
+            "         no_cache=%1x\n"    \
+            "  cp_submit_value=|%s|\n"   \
+            "orig_submit_value=|%s|\n"   \
+            "           size_l=%d\n"     \
+            "         disabled=%d\n"     \
+            "          name_cs=%d\n"     \
+            "         value_cs=%d\n"     \
+            "        accept_cs=|%s|\n"   \
             "}\n", \
             (F), sizeof(*((F))), \
             (F)->name, (F)->name, (F)->number, (F)->type, \
@@ -117,17 +117,17 @@
 /* usage: DUMPSTRUCT_LINE(htline_ptr, "message"); */
 #define   DUMPSTRUCT_LINE(L,X) \
 CTRACE(tfp, "\n" \
-            "KED: htline_ptr=%08x  sizeof=%d  ["X"]\n" \
-            "HTLine struct {\n"    \
-            "        *next=%08x\n" \
-            "        *prev=%08x\n" \
-            "       offset=%d\n"   \
-            "         size=%d\n"   \
-            "  split_after=%1x\n"  \
-            "       bullet=%1x\n"  \
-            "nodef U_C_S\n"        \
-            "       data[]=%08x\n" \
-            "         data=|%s|\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"   \
             "}\n", \
             (L), sizeof(*((L))), \
             (L)->next, (L)->prev, (L)->offset, (L)->size, (L)->split_after, \
##--eof--##

reply via email to

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