[Top][All Lists]
[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. */