bugGNU roff - Bugs: bug #55799, [troff] -a output does not heed...

 
 

bug #55799: [troff] -a output does not heed .char definitions

Submitter:  Dave <barx>
Submitted:  Thu 28 Feb 2019 10:31:55 PM UTC
   
 
Category:  Core Severity:  3 - Normal
Item Group:  Incorrect behaviour Status:  Fixed
Privacy:  Public Assigned to:  gbranden
Open/Closed:  Closed Planned Release:  1.24.0
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Wed 19 Mar 2025 05:27:47 AM UTC, comment #7: 


commit 6a7f51677fb78c59b6398431118c212070d92e5e
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
Date:   Mon Mar 17 01:04:21 2025 -0500

    [groff]: Regression-test Savannah #55799.

    * src/roff/groff/tests/composite-nodes-produce-approximate-output.sh: Do
      it.
    * src/roff/groff/groff.am (groff_TESTS): Run test.

    Test fails at this commit.

commit 3d249f79fd662e0e033ee1dc564f242b1a753e3c
Author: G. Branden Robinson <g.branden.robinson@gmail.com>
Date:   Mon Mar 17 01:19:54 2025 -0500

    [troff]: Fix Savannah #55799 (`-a` opt + `char`).

    * src/roff/troff/node.cpp (composite_node::ascii_print): When rendering
      a composite node for approximate output, traverse into it and write
      its nodes' representations in forward order.

    Fixes <https://savannah.gnu.org/bugs/?55799>.  Thanks to Dave Kemper for
    the report.  Problem appears to date back to groff's birth.


G. Branden Robinson <gbranden>
Group administrator
Wed 19 Mar 2025 02:35:06 AM UTC, comment #6: 

comment #5:

> Alternative fix.


This fix works for me.  Thanks!

Dave <barx>
Group Member
Mon 17 Mar 2025 06:58:45 AM UTC, comment #5: 

Alternative fix.


diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index e4fb3717b..4bc0bf751 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -4680,12 +4680,7 @@ void composite_node::asciify(macro *m)

 void composite_node::ascii_print(ascii_output_file *ascii)
 {
-  unsigned char c = ci->get_ascii_code();
-  if (c != 0)
-    ascii->outc(c);
-  else
-    ascii->outs(ci->nm.contents());
-
+  ascii_print_reverse_node_list(ascii, nodes);
 }


G. Branden Robinson <gbranden>
Group administrator
Mon 17 Mar 2025 06:28:03 AM UTC, comment #4: 

Oh, silly me, GNU troff already had a function for this, `ascii_print_reverse_node_list()`.

I'll simplify.

G. Branden Robinson <gbranden>
Group administrator
Mon 17 Mar 2025 05:51:59 AM UTC, comment #3: 

This looks like it does the trick.


$ git stash show -p 0
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index e4fb3717b..7b756e3a5 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -4680,12 +4680,17 @@ void composite_node::asciify(macro *m)

 void composite_node::ascii_print(ascii_output_file *ascii)
 {
-  unsigned char c = ci->get_ascii_code();
-  if (c != 0)
-    ascii->outc(c);
-  else
-    ascii->outs(ci->nm.contents());
-
+  // It's stored in reverse order already; this puts it forward again.
+  std::stack<node *> reversed_node_list;
+  node *n = nodes;
+  while (n != 0 /* nullptr */) {
+    reversed_node_list.push(n);
+    n = n->next;
+  }
+  while (!reversed_node_list.empty()) {
+    reversed_node_list.top()->ascii_print(ascii);
+    reversed_node_list.pop();
+  }
 }

 hyphen_list *composite_node::get_hyphen_list(hyphen_list *tail, int *count)


G. Branden Robinson <gbranden>
Group administrator
Mon 17 Mar 2025 04:05:20 AM UTC, comment #2: 

Now that we've got Advancing Dumping Technologyâ„¢ in groff Git's master branch, we can obtain some insight into what's going on.


$ printf ".char a z\nplan\n.pline\n" | groff -z 2>&1 | jq
[
  {
    "type": "line_start_node",
    "diversion level": 0,
    "is_special_node": false
  },
  {
    "type": "glyph_node",
    "diversion level": 0,
    "is_special_node": false,
    "character": "p"
  },
  {
    "type": "glyph_node",
    "diversion level": 0,
    "is_special_node": false,
    "character": "l"
  },
  {
    "type": "composite_node",
    "diversion level": 0,
    "is_special_node": false,
    "character": "a"
  },
  {
    "type": "glyph_node",
    "diversion level": 0,
    "is_special_node": false,
    "character": "n"
  },
  {
    "type": "word_space_node",
    "diversion level": 0,
    "is_special_node": false,
    "hunits": 2500,
    "undiscardable": false,
    "is hyphenless breakpoint": false,
    "terminal_color": "default",
    "width_list": [
      {
        "width": 2500,
        "sentence_width": 2500
      }
    ],
    "unformat": false
  }
]


That redefined 'a' is not a `glyph_node`, but a `composite_node`.

And it also seems not to contain anything!  Huh.  Even having just written the code to handle this, I'm surprised.  Maybe I overlooked making `composite_node` derive from `container_node`?

Anyway, we *can* verify that it's got an unusual property.


$ printf ".char a z\nplan\n.pchar a\n" | ./build/test-groff -z
character 'a'
  is not translated
  has a macro: "z"
  special translation: 0
  hyphenation code: 97
  flags: 0
  ASCII code: 97
  asciify code: 0
  is found
  is transparently translatable
  is not translatable as input
  mode: normal


Interesting to me that while as rendered, this "a" will look like "z", the hyphenation system will still treat it like "a".  But that seems okay.  If you want to change its hyphenation code, too, the `hcode` request hangs on the pegboard in easy reach.

G. Branden Robinson <gbranden>
Group administrator
Sat 24 Jun 2023 03:43:05 PM UTC, comment #1: 

Heirloom troff has also implemented the .char request (recognized when using -x2 or higher), and its -a output works as expected.

$ printf ".char a z\nplan\n" | heirloom-troff -a -x2
plzn

$ printf ".char a z\nplan\n" | groff -a
<beginning of page>
plan


Dave <barx>
Group Member
Thu 28 Feb 2019 10:31:55 PM UTC, original submission:  

When the .char request is used in groff 1.22.4, correct output is produced for PostScript or TTY:

printf ".char a z\nplan\n" | nroff | grep pl.n
printf ".char a z\nplan\n" | groff | grep pl.n

But incorrect output is produced for ASCII approximation via -a:

printf ".char a z\nplan\n" | groff -a | grep pl.n

Dave <barx>
Group Member

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -email is unavailable- added by gbranden (Posted a comment)
  • -email is unavailable- added by barx (Submitted the item)
  •  

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Follow 7 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2025-03-19 gbranden StatusIn Progress Fixed
        Open/ClosedOpen Closed
        Planned ReleaseNone 1.24.0
    2025-03-17 gbranden StatusConfirmed In Progress
        Assigned toNone gbranden
    2025-03-17 gbranden Summary-a output does not heed .char definitions [troff] -a output does not heed .char definitions
    2025-03-17 gbranden StatusNone Confirmed

    Back to the top

    Powered by Savane 3.14-962f.
    Corresponding source code