groff
[Top][All Lists]
Advanced

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

Re: [BUG] italics run past where they should


From: G. Branden Robinson
Subject: Re: [BUG] italics run past where they should
Date: Thu, 21 Jul 2022 11:46:22 -0500

Hi Alex,

At 2022-07-21T14:07:35+0200, Alejandro Colomar wrote:
> On 7/21/22 12:49, Alejandro Colomar wrote:
> > On 7/21/22 12:46, Alejandro Colomar wrote:
> > > On 7/21/22 11:25, G. Branden Robinson wrote:
> > > > At 2022-07-20T16:58:34+0200, Alejandro Colomar wrote:
> > > > > I'm not sure if this is a groff(1) bug, or less(1), or who
> > > > > knows...
> > > > 
> > > >  From your description I suspect a bug either in less(1) or your
> > > > terminal emulator.
> > > 
> > > Yup, I also had that feeling, but the only invariable thing in my
> > > experiments is groff(1).  However, I considered the possibility
> > > that a slightly imperfect ordering in escape sequences might be
> > > interpreted correctly normally, but incorrectly after the search
> > > does some highlighting...  Or that the combination of escape
> > > sequences used by less(1) an groff(1) might be incompatible with
> > > eachother?
> > > 
> > > I generalized the reproduction of the bug:
> > > 
> > > In any line with alternate highlighting .BI, seraching for a
> > > _whole_ italics word will trigger the bug.
> 
> And another finding:  you don't need to search for the whole
> highlighted string, searching for a string that both has the same
> highlighting across all of it and contains the last character in the
> string (i.e., the next character after the match will have the other
> highlighting) will trigger the bug, even if there are more characters
> preceeding the string with the same typeface.
>
> > And I just reproduced the other side of the bug:
> > 
> > seraching for a whole bold string will make the following italics text
> > not be italics any more.

Yes.  I have a more precise hypothesis.

You have obviously observed that these pagers highlight the match.  This
is often done by selecting the terminal's "standout" mode (this is an
ECMA-48 term).  It is defined as the most prominent form of styling
available.  This mode often combines with other styles (or "renditions")
like bold, italics, or underlining.  Inverse video (ECMA-48: "negative
image") is common and widely supported, possibly because it was cheap to
implement in hardware on monochrome terminals back in the day.

ECMA-48 also has a sequence that shuts off all special renditions.  This
is called "SGR 0".  It is so commonly used that there is a dedicated
terminfo capability for it, called "sgr0".  When the terminal gets
attributes "stuck on", as when a TUI program exits without properly
resetting the terminal state, a straightforward command cleans up the
colors, highlighting and whatnot.

$ tput sgr0

(TUI programs that exit abnormally often leave other terminal attributes
screwed up too, like leaving the cursor invisible or leaving the TTY in
the wrong mode, like "raw" instead of "cbreak".)

So I suspect what is happening is that these pagers are blindly emitting
an SGR 0 escape sequence at the end of the match.  As you're seeing,
this is wrong because attributes may already have been put in place
prior to the beginning of the match boundary, and they need to be
restored.

_If_ standout mode is what is used to mark the matches, then what these
pagers need to do when ending the match is to send the "rmso" capability
(in terminfo parlance) since "smso" was used to turn it on.

If they're doing something else to highlight the match, then they need
to unwind that carefully.  I would think they could, upon locating the
match, save all the character-cell attributes at the match's end before
emitting their match-highlighting escape sequences, then both reverse
those highlights _and_ then restore the saved attributes.  I think
ncurses has functions to help with this, attr_get() and attr_set.
(There are dedicated functions for dealing specifically with standout
mode since it is a very old part of the curses interface.  These are
standout() and standend().)

If you can persuade the pager to dump its output to a file without
noticing that it's not a TTY and thereby changing its behavior, you can
inspect the escape sequences it emits.  I did this when testing the
implementation of grotty's OSC 8 support several months ago but I don't
remember the trick I used.

Here are some examples of the capabilities I've mentioned.

$ tput sgr0 | xxd
00000000: 1b28 421b 5b6d                           .(B.[m
$ tput smso | xxd
00000000: 1b5b 376d                                .[7m
$ tput rmso | xxd
00000000: 1b5b 3237 6d                             .[27m

Sorry I don't have more to offer right now; it turns out I'm dealing
with a burst water pipe today, so my personal state is alternating
between emergency and boredom.

Regards,
Branden

Attachment: signature.asc
Description: PGP signature


reply via email to

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