[bug #61561] [grotty] 'sgr' device control command takes effect only at page breaks

2021-11-26 Thread G. Branden Robinson
Follow-up Comment #7, bug #61561 (project groff):

Whoops.  I made an error.  The think I thought I could break, doesn't break. 
That's good.  But my other points stand.

Here's the wrong part.

[comment #6 comment #6:]
> It occurs to me that you could break this by enabling SGR (the default),
going nuts with SGR character attributes, and then contriving to disable SGR
in the midst of the page, which, as we've seen, won't actually turn anything
off in the terminal.  When the page bottom is hit, all the logic that cleans
up character attribute state will be skipped, because you're in nice, clean
legacy output mode.  Let's see.
> 
> Input:
> 
> $ cat EXPERIMENTS/grotty-make-a-mess.groff
> .fcolor magenta
> .gcolor white
> .ft BI
> obnoxious\X'tty: sgr'
> .bp
> still obnoxious\[em]ha ha ha
> 

I forgot to put a (space and) '0' after the 'sgr' above, so I didn't actually
do anything at all.  My brain itched momentarily regarding why I got only
_one_ debugging output diagnostic instead of two, but I didn't pay attention.

> Yup.

Nope.  :P

> In other words, most of the logic quoted above should have been moved into
`update_options()` or, even better, its own function, called from  there _and_
`end_page()`.

Terminal output would have to be refactored to handle this.  grotty(1) really
outputs a page at a time instead of a line at a time, which changes the
analysis a bit.

If we look earlier in `end_page()`, we see this.


 750   for (int i = 0; i < last_line; i++) { 
 751 tty_glyph *p = lines[i];
 752 lines[i] = 0;   
 753 tty_glyph *g = 0;   
 754 while (p) { 
 755   tty_glyph *tem = p->next; 
 756   p->next = g;  
 757   g = p;
 758   p = tem;  
 759 }   


...and then a whole bunch more logic to format the output with the currently
configured text attributes.

Like I said, this doesn't change much.  But I incorrectly deduced that
grotty(1) has for 20 years been susceptible to the SGR-switching tomfoolery I
attempted in the quoted comment--it has not been.

Sadly grotty(1)'s page-at-a-time approach to output is nowhere documented; it
might explain the otherwise mysterious claims sprinkled around our Texinfo
manual and maybe some other places that GNU nroff can't be used interactively
as Unix nroff could (`.rd` again).  Even that claim is too strong--a while
back I updated groff(1) to illustrate how you can run groff -T utf8 as a REPL
and I've used it that way frequently since I started participating in its
development.

Page-at-a-time layout even for terminal devices is indeed more consistent with
troff and reflects the grand unification strategy that GNU roff undertook in
the first place.  It's not clear to me exactly what was lost.  It would be
nice to have a model document that works under Unix nroff but not GNU troff as
a result of this change.

Okay, I need to stop procrastinating and read some ncurses man pages...   





___

Reply to this item at:

  

___
  Message sent via Savannah
  https://savannah.gnu.org/




[bug #61561] [grotty] 'sgr' device control command takes effect only at page breaks

2021-11-26 Thread G. Branden Robinson
Update of bug #61561 (project groff):

  Status:   Need Info => Confirmed  

___

Follow-up Comment #6:

[comment #3 comment #3:]

> It seems that the state of SGR at the bottom of the page (when it gets
ejected?) is the one that wins.
> I'll see if I can find in the code how the fonts get re-initialized, or what
exactly is going on there.

Okay, here it is.  grotty's `end_page()` is huge--nearly 200 lines.  Near the
end of it we have the following nearly 100 lines of undoing all the possible
character attributes (bold, underlining, color, etc.) that might have been
applied.


 790   if (hpos > p->hpos) { 
 791 do {
 792   putchar('\b');
 793   hpos--;   
 794 } while (hpos > p->hpos);   
 795   } 
 796   else {
 797 if (want_horizontal_tabs) { 
 798   for (;;) {
 799 int next_tab_pos = ((hpos + TAB_WIDTH) / TAB_WIDTH) *
TAB_WIDTH;
 800 if (next_tab_pos > p->hpos) 
 801   break;
 802 if (is_continuously_underlining)
 803   make_underline(p->w); 
 804 else if (!use_overstriking_drawing_scheme   
 805  && is_underlining) {   
 806   if (do_sgr_italics)   
 807 putstring(SGR_NO_ITALIC);   
 808   else if (do_reverse_video)
 809 putstring(SGR_NO_REVERSE);  
 810   else  
 811 putstring(SGR_NO_UNDERLINE);
 812   is_underlining = false;   
 813 }   
 814 putchar('\t');  
 815 hpos = next_tab_pos;
 816   } 
 817 }   
 818 for (; hpos < p->hpos; hpos++) {
 819   if (is_continuously_underlining)  
 820 make_underline(p->w);   
 821   else if (!use_overstriking_drawing_scheme && is_underlining) {
 822 if (do_sgr_italics) 
 823   putstring(SGR_NO_ITALIC); 
 824 else if (do_reverse_video)  
 825   putstring(SGR_NO_REVERSE);
 826 else
 827   putstring(SGR_NO_UNDERLINE);  
 828 is_underlining = false;
 829   }
 830   putchar(' ');
 831 }
 832   }
 833   assert(hpos == p->hpos);
 834   if (p->mode & COLOR_CHANGE) {
 835 if (!use_overstriking_drawing_scheme) {
 836   if (p->fore_color_idx != curr_fore_idx) {
 837 put_color(p->fore_color_idx, 0);
 838 curr_fore_idx = p->fore_color_idx;
 839   }
 840   if (p->back_color_idx != curr_back_idx) {
 841 put_color(p->back_color_idx, 1);
 842 curr_back_idx = p->back_color_idx;
 843   }
 844 }
 845 continue;
 846   }
 847   if (p->mode & UNDERLINE_MODE)
 848 make_underline(p->w);
 849   else if (!use_overstriking_drawing_scheme && is_underlining) {
 850 if (do_sgr_italics)
 851   putstring(SGR_NO_ITALIC);
 852 else if (do_reverse_video)
 853   putstring(SGR_NO_REVERSE);
 854 else
 855   putstring(SGR_NO_UNDERLINE);
 856 is_underlining = false;
 857   }
 858   if (p->mode & BOLD_MODE)
 859 make_bold(p->code, p->w);
 860   else if (!use_overstriking_drawing_scheme && is_boldfacing) {
 861 putstring(SGR_NO_BOLD);
 862 is_boldfacing = false;
 863   }
 864   if (!use_overstriking_drawing_scheme) {

[bug #61561] [grotty] 'sgr' device control command takes effect only at page breaks

2021-11-25 Thread G. Branden Robinson
Follow-up Comment #5, bug #61561 (project groff):


[comment #4 comment #4:]
> Yes...on the mailing list named an idea

Comrade Stalin got a hold of that comment somehow...

It was Steffen who did aforementioned naming.

___

Reply to this item at:

  

___
  Message sent via Savannah
  https://savannah.gnu.org/




[bug #61561] [grotty] 'sgr' device control command takes effect only at page breaks

2021-11-25 Thread G. Branden Robinson
Follow-up Comment #4, bug #61561 (project groff):

> Not sure about you, but I see a perfect opportunity to put a
currently-useless bit of kruft to good use by repurposing it to toggle
“real” italics, Fraktur, dimmed text, strikeouts, and any other
spiffy-looking but fundamentally useless effect for terminals that happen to
support such nicer-looking effects:
[...]
> I might be leaning too strongly on my expectations as a part-time Emacs
user, whose graphical mode brings out these pleasant-looking effects in text
I'm normally used to reading in very spartan settings.

Yes...on the mailing list named an idea I've hinted at before (in doc/ms.ms):
having grotty use available system resources to determine these matters
instead of installing its own bespoke configuration system.

The terminfo library.

I can understand why this road wasn't taken 20 years ago: ncurses had only
been under Thomas Dickey's official maintenance for a couple of years after
mercurial stewardship by others and an erratic release history, there were
still a lot of S-Lang partisans touting its superiority on scant evidence, and
people were still clinging to termcap as somehow preferable on any basis to
terminfo.

But we're in a better world now.

What I don't know is exactly how we want to preserve the ability to ignore
certain terminal capabilities.  I expect people to be surprised if underlines
in nroff documents suddenly turn into real italics.  Some will be _pleasantly_
surprised, but not all.

I need to learn how capability cancellation would be achieved at runtime.  I
have the atom of knowledge that in a terminfo description, you suffix a
capability name with '@' to cancel it, but not much more.  There is the
question of what we tell our users.  More command-line options and environment
variables, or tell them to override terminfo?  The latter would be a surprise
too.  Even if it turns out to be the architecturally correct solution (which I
suspect), we would need a period of transition as a considerable number of our
users discover that terminal capabilities are even a thing that exists in Unix
systems (look at all the fancy programs and scripts that blast ECMA-48 color
attribute escape sequences completely unconditionally, without checking
anything or caring what's going to have to process them).

Having seem npm run, I have a pretty good guess who some of those people
are...

___

Reply to this item at:

  

___
  Message sent via Savannah
  https://savannah.gnu.org/




[bug #61561] [grotty] 'sgr' device control command takes effect only at page breaks

2021-11-25 Thread G. Branden Robinson
Update of bug #61561 (project groff):

  Status:None => Need Info  
 Assigned to:None => gbranden   
 Summary: [grotty] 'sgr' device control command seems to
simply not work => [grotty] 'sgr' device control command takes effect only at
page breaks

___

Follow-up Comment #3:

Good news!  The feature isn't _quite_ as broken as I thought.

I noticed that even with groff -P-c, SGR sequences were getting enabled
seemingly instantly, in spite of the option being initially honored.

You _can_ dynamically change SGR enablement within a document.

At a page break.

Not a word break.  Not an output line flush.

Not even after vertical space.

A page break.

It seems that the state of SGR at the bottom of the page (when it gets
ejected?) is the one that wins.

This doesn't really change my mind about the non-usefulness of the
feature--almost anybody who wants dynamic control of overstriking vs. SGR
sequences is going to want finer-grained resolution than this--but it does
partially invalidate my analysis.  I'll see if I can find in the code how the
fonts get re-initialized, or what exactly is going on there.

Here's input and a hex dump from an instrumented groff Git HEAD.  (The output
in the initial report was from Debian's groff 1.22.4.)


$ cat EXPERIMENTS/grotty-smaller-sgr.groff 
.de Ts
test
\fRR\fBB\fII\f(BIX\fRR
.br
..
init
.br
.ft B
.Ts
.ft I
.Ts
.bp
\X'tty: sgr'\c
.ft B
.Ts
.bp
\X'tty: sgr 0'\c
.ft B
.Ts


I encourage the reader to substitute 'fl', 'sp', or any request of their
choice for those 'bp's.


$ ./build/test-groff -b -ww -P-c -Tascii EXPERIMENTS/grotty-smaller-sgr.groff
|xxd
grotty: debug: turning overstriking drawing scheme ON
grotty::59: debug: turning overstriking drawing scheme OFF
grotty::86: debug: turning overstriking drawing scheme ON
: 696e 6974 0a74 0874 6508 6573 0873 7408  init.t.te.es.st.
0010: 7420 5242 0842 5f08 495f 0858 0858 520a  t RB.B_.I_.X.XR.
0020: 5f08 745f 0865 5f08 735f 0874 2052 4208  _.t_.e_.s_.t RB.
0030: 425f 0849 5f08 5808 5852 0a0a 0a0a 0a0a  B_.I_.X.XR..
0040: 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a  
0050: 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a  
0060: 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a  
0070: 0a0a 0a0a 0a0a 0a0a 0a0a 1b5b 316d 7465  ...[1mte
0080: 7374 201b 5b32 326d 521b 5b31 6d42 1b5b  st .[22mR.[1mB.[
0090: 346d 1b5b 3232 6d49 1b5b 316d 581b 5b32  4m.[22mI.[1mX.[2
00a0: 346d 1b5b 3232 6d52 0a0a 0a0a 0a0a 0a0a  4m.[22mR
00b0: 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a  
00c0: 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a  
00d0: 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a  
00e0: 0a0a 0a0a 0a0a 0a0a 0a0a 7408 7465 0865  ..t.te.e
00f0: 7308 7374 0874 2052 4208 425f 0849 5f08  s.st.t RB.B_.I_.
0100: 5808 5852 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a  X.XR
0110: 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a  
0120: 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a  
0130: 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a 0a0a  
0140: 0a0a 0a0a 0a0a   ..


___

Reply to this item at:

  

___
  Message sent via Savannah
  https://savannah.gnu.org/