bug-texinfo
[Top][All Lists]
Advanced

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

Re: new groff output


From: Eli Zaretskii
Subject: Re: new groff output
Date: Fri, 08 Mar 2002 15:34:06 +0200

> Date: Tue, 05 Mar 2002 21:45:42 +0100 (CET)
> From: Werner LEMBERG <address@hidden>
> 
> > > But the -R switch doesn't work as expected; the various ANSI
> > > escapes are not passed through to xterm.
> > 
> > What do you see with -R?  Are the escapes stripped altogether?  Is
> > it possible that your `man' program or some program it runs strip
> > the escapes?
> 
> Sorry, the phrase `are not passed through' was possibly misleading.
> Please see the attached image; the command was `info -R grotty'.
> Running xterm, I shouldn't see the escape sequences at all but bold
> and underlined stuff.

Yes, you are right: I forgot that Info converts unprintable
characters to a printable representation, and in the process destroys
the escape sequences.

Please try the patches below.  As you see, the fix is quite hairy,
and I had only one example man page to play with.  So if you find
man pages which aren't displayed correctly under -R even with these
patches, please send me that man page (after formatting it).

Sorry for any inconvenience due to incomlpete implementation in v4.1.


2002-03-08  Eli Zaretskii  <address@hidden>

        * info/display.c (display_update_one_window): Dynamically reallocate
        printed_line[] as needed.  When under -R, ignore ANSI escapes for
        the purposes of line wrap display.  Clear the line to EOL if it
        used escape sequences.  Reallocate entry->text if the new
        printed_line is longer than screenwidth.

        * info/window.c (string_width): Don't count ANSI escape sequences
        in string width, when under -R..
        (calculate_line_starts): Don't count ANSI escape sequences in line
        width, when under -R.
        (window_get_cursor_column, window_chars_to_goal): When under -R,
        ANSI escapes don't affect the horizontal position.

        * info/info-utils.c (printed_representation): If -R is in effect,
        treat ESC as a normal character.


--- info/info-utils.c~0 Mon Aug 10 14:07:47 1998
+++ info/info-utils.c   Fri Mar  8 04:49:17 2002
@@ -443,9 +443,11 @@ printed_representation (character, hpos)
 {
   register int i = 0;
   int printable_limit = ISO_Latin_p ? 255 : 127;
-    
+
+  if (raw_escapes_p && character == '\033')
+    the_rep[i++] = character;
   /* Show CTRL-x as ^X.  */
-  if (iscntrl (character) && character < 127)
+  else if (iscntrl (character) && character < 127)
     {
       switch (character)
         {


--- info/window.c~0     Fri Jan 18 20:08:26 2002
+++ info/window.c       Fri Mar  8 05:38:52 2002
@@ -758,7 +758,20 @@ string_width (string, hpos)
 
   for (width = 0, i = 0; string[i]; i++)
     {
-      this_char_width = character_width (string[i], hpos);
+      /* Support ANSI escape sequences for -R.  */
+      if (raw_escapes_p
+         && string[i] == '\033'
+         && string[i+1] == '['
+         && isdigit (string[i+2])
+         && (string[i+3] == 'm'
+             || (isdigit (string[i+3]) && string[i+4] == 'm')))
+       {
+         while (string[i] != 'm')
+           i++;
+         this_char_width = 0;
+       }
+      else
+       this_char_width = character_width (string[i], hpos);
       width += this_char_width;
       hpos += this_char_width;
     }
@@ -830,7 +843,29 @@ calculate_line_starts (window)
             could be passed as negative integers to character_width
             and wreak havoc on some naive implementations of iscntrl.  */
           c = (unsigned char) node->contents[i];
-          cwidth = character_width (c, hpos);
+
+         /* Support ANSI escape sequences for -R.  */
+         if (raw_escapes_p
+             && c == '\033'
+             && node->contents[i+1] == '['
+             && isdigit (node->contents[i+2]))
+           {
+             if (node->contents[i+3] == 'm')
+               {
+                 i += 3;
+                 cwidth = 0;
+               }
+             else if (isdigit (node->contents[i+3])
+                      && node->contents[i+4] == 'm')
+               {
+                 i += 4;
+                 cwidth = 0;
+               }
+             else
+               cwidth = character_width (c, hpos);
+           }
+         else
+           cwidth = character_width (c, hpos);
 
           /* If this character fits within this line, just do the next one. */
           if ((hpos + cwidth) < window->width)
@@ -1009,7 +1044,23 @@ window_get_cursor_column (window)
   end = window->point - (line - window->node->contents);
 
   for (hpos = 0, i = 0; i < end; i++)
-    hpos += character_width (line[i], hpos);
+    {
+      /* Support ANSI escape sequences for -R.  */
+      if (raw_escapes_p
+         && line[i] == '\033'
+         && line[i+1] == '['
+         && isdigit (line[i+2]))
+       {
+         if (line[i+3] == 'm')
+           i += 3;
+         else if (isdigit (line[i+3]) && line[i+4] == 'm')
+           i += 4;
+         else
+           hpos += character_width (line[i], hpos);
+       }
+      else
+       hpos += character_width (line[i], hpos);
+    }
 
   return (hpos);
 }
@@ -1025,8 +1076,17 @@ window_chars_to_goal (line, goal)
 
   for (hpos = 0, i = 0; line[i] != '\n'; i++)
     {
-
-      check = hpos + character_width (line[i], hpos);
+      /* Support ANSI escape sequences for -R.  */
+      if (raw_escapes_p
+         && line[i] == '\033'
+         && line[i+1] == '['
+         && isdigit (line[i+2])
+         && (line[i+3] == 'm'
+             || (isdigit (line[i+3]) && line[i+4] == 'm')))
+       while (line[i] != 'm')
+         i++;
+      else
+       check = hpos + character_width (line[i], hpos);
 
       if (check > goal)
         break;


--- info/display.c~0    Thu Jul 24 17:13:28 1997
+++ info/display.c      Fri Mar  8 08:02:43 2002
@@ -103,6 +103,8 @@ display_update_one_window (win)
   char *printed_line;           /* Buffer for a printed line. */
   int pl_index = 0;             /* Index into PRINTED_LINE. */
   int line_index = 0;           /* Number of lines done so far. */
+  int pl_ignore = 0;           /* How many chars use zero width on screen. */
+  int allocated_win_width;
   DISPLAY_LINE **display = the_display;
 
   /* If display is inhibited, that counts as an interrupted display. */
@@ -123,7 +125,8 @@ display_update_one_window (win)
   /* Print each line in the window into our local buffer, and then
      check the contents of that buffer against the display.  If they
      differ, update the display. */
-  printed_line = (char *)xmalloc (1 + win->width);
+  allocated_win_width = win->width + 1;
+  printed_line = (char *)xmalloc (allocated_win_width);
 
   if (!win->node || !win->line_starts)
     goto done_with_node_display;
@@ -147,7 +150,7 @@ display_update_one_window (win)
         {
           if (*nodetext == '\r' || *nodetext == '\n')
             {
-              replen = win->width - pl_index;
+              replen = win->width - pl_index + pl_ignore;
             }
           else
             {
@@ -156,9 +159,26 @@ display_update_one_window (win)
             }
         }
 
+      /* Support ANSI escape sequences under -R.  */
+      if (raw_escapes_p
+         && *nodetext == '\033'
+         && nodetext[1] == '['
+         && isdigit (nodetext[2]))
+       {
+         if (nodetext[3] == 'm')
+           pl_ignore += 4;
+         else if (isdigit (nodetext[3]) && nodetext[4] == 'm')
+           pl_ignore += 5;
+       }
+      while (pl_index + 2 >= allocated_win_width - 1)
+       {
+         allocated_win_width *= 2;
+         printed_line = (char *)xrealloc (printed_line, allocated_win_width);
+       }
+
       /* If this character can be printed without passing the width of
          the line, then stuff it into the line. */
-      if (replen + pl_index < win->width)
+      if (replen + pl_index < win->width + pl_ignore)
         {
           /* Optimize if possible. */
           if (replen == 1)
@@ -189,7 +209,7 @@ display_update_one_window (win)
                  the next line.  Remember the offset of the last character
                  printed out of REP so that we can carry the character over
                  to the next line. */
-              for (i = 0; pl_index < (win->width - 1);)
+              for (i = 0; pl_index < (win->width + pl_ignore - 1);)
                 printed_line[pl_index++] = rep[i++];
               
               rep_carried_over = rep + i;
@@ -214,7 +234,9 @@ display_update_one_window (win)
 
           /* If the screen line is inversed, then we have to clear
              the line from the screen first.  Why, I don't know. */
-          if (entry->inverse)
+          if (entry->inverse
+             /* Need to erase the line if it has escape sequences.  */
+             || (raw_escapes_p && strchr (entry->text, '\033') != 0))
             {
               terminal_goto_xy (0, line_index + win->first_row);
               terminal_clear_to_eol ();
@@ -242,13 +264,21 @@ display_update_one_window (win)
               /* If the printed text didn't extend all the way to the edge
                  of the window, and text was appearing between here and the
                  edge of the window, clear from here to the end of the line. */
-              if ((pl_index < win->width && pl_index < entry->textlen) ||
-                  (entry->inverse))
+              if ((pl_index < win->width + pl_ignore
+                  && pl_index < entry->textlen)
+                 || (entry->inverse))
                 terminal_clear_to_eol ();
 
               fflush (stdout);
 
               /* Update the display text buffer. */
+             if (strlen (printed_line) > screenwidth)
+               /* printed_line[] can include more than screenwidth
+                  characters if we are under -R and there are escape
+                  sequences in it.  However, entry->text was
+                  allocated (in display_initialize_display) for
+                  screenwidth characters only.  */
+               entry->text = xrealloc (entry->text, strlen (printed_line)+1);
               strcpy (entry->text + i, printed_line + i);
               entry->textlen = pl_index;
 
@@ -274,6 +304,7 @@ display_update_one_window (win)
 
           /* Reset PL_INDEX to the start of the line. */
           pl_index = 0;
+         pl_ignore = 0;        /* this is computed per line */
 
           /* If there are characters from REP left to print, stuff them
              into the buffer now. */



reply via email to

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