[groff] 01/01: [gropdf]: .pdfhref M fails with no -N/-D flag

2025-03-15 Thread Deri James
deri pushed a commit to branch master
in repository groff.

commit 56ac7ec46e7b408dcb259d03e9596d4cd916446c
Author: Deri James 
AuthorDate: Fri Mar 14 16:19:14 2025 +

[gropdf]: .pdfhref M fails with no -N/-D flag

The documentation for this macro has always stated that the
first word of "descriptive text" is used as the destination
name if neither -N nor -D are present.

* tmac/pdf.tmac: Do it.

Fixes bug 
---
 ChangeLog | 12 
 tmac/pdf.tmac |  2 +-
 2 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 88f7946bc..0e76d5d1b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2025-03-14  Deri James  
+
+   [gropdf]: .pdfhref M fails with no -N/-D flag
+
+   The documentation for this macro has always stated that the
+   first word of "descriptive text" is used as the destination
+   name if neither -N nor -D are present.
+
+   * tmac/pdf.tmac: Do it.
+
+   Fixes bug 
+
 2025-03-13  Deri James  
 
[gropdf]: \X'pdf: pdfpic ...' scales incorrectly
diff --git a/tmac/pdf.tmac b/tmac/pdf.tmac
index 4ee4809b1..98fa3ef0e 100644
--- a/tmac/pdf.tmac
+++ b/tmac/pdf.tmac
@@ -646,10 +646,10 @@ am solely responsible for any bugs I may have introduced 
into this file.
 .   \" if we are formatting for immediate output,
 .   \" emit PDFMARK code to establish the associated view
 .   \"
+.   ds PDFBOOKMARK.NAME \\$1
 .   ie '\\n(.z'' \{\
 .  pdf:href.sety
 .  pdfmark /Dest /\\$1 /View [\\*[PDFHREF.VIEW]] /DEST
-.  ds PDFHREF.NAME \\$1
 .  rr PDFPAGE.Y
 .  \}
 .   \"

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 12/61: [man]: Fix style nits.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 9fb3452381e811da9ecb338cb29e7f9c24fad9ac
Author: G. Branden Robinson 
AuthorDate: Fri Mar 14 23:50:39 2025 -0500

[man]: Fix style nits.

Protect "asciify" and "unformat" from hyphenation.

Quote the latter to help avoid misinterpretation when text styling is
absent.
---
 man/groff.7.man  |  4 ++--
 man/groff_diff.7.man | 10 +-
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/man/groff.7.man b/man/groff.7.man
index 8df70d755..0b10f1c58 100644
--- a/man/groff.7.man
+++ b/man/groff.7.man
@@ -8298,9 +8298,9 @@ This facility is termed
 .
 .P
 The
-.B asciify
+.B \%asciify
 and
-.B unformat
+.RB \%\[lq] unformat \[rq]
 requests reprocess diversions.
 .\" XXX: That's a weak statement.  What we need is a `for` request and
 .\" a new conditional operator that tests whether an item in a node list
diff --git a/man/groff_diff.7.man b/man/groff_diff.7.man
index 6b7891a58..94387cf53 100644
--- a/man/groff_diff.7.man
+++ b/man/groff_diff.7.man
@@ -1764,7 +1764,7 @@ request.
 .
 .
 .IP
-.B asciify
+.B \%asciify
 cannot return all items in a diversion to their source equivalent:
 nodes such as those produced by
 .BR \[rs]N[ .\|.\|.\& ]
@@ -1773,7 +1773,7 @@ so the result cannot be guaranteed to be a pure string.
 .
 Glyph parameters such as the type face and size are not preserved;
 use
-.B unformat
+.RB \%\[lq] unformat \[rq]
 to achieve that.
 .
 .
@@ -3897,7 +3897,7 @@ appends one.
 This is the same as the
 .B tr
 request except that the
-.B asciify
+.B \%asciify
 request uses the character code
 (if any)
 before the character translation.
@@ -3932,8 +3932,8 @@ Unformat the diversion
 .IR div .
 .
 Unlike
-.BR asciify ,
-.B unformat
+.BR \%asciify ,
+.RB \%\[lq] unformat \[rq]
 handles only tabs and spaces between words,
 the latter usually arising from spaces or newlines in the input.
 .

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 50/61: [troff]: Implement recursive node dumping (8b/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 5caf50d1be7ddb716e6f53e96975f1a58cefe527
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 11:34:12 2025 -0600

[troff]: Implement recursive node dumping (8b/9).

* src/roff/troff/node.h (class vline_node): Do it.  Drop pointer-to-node
  member variable and declaration of destructor.

* src/roff/troff/node.cpp (vline_node::~vline_node): Drop; our base
  class handles destruction of contained node(s).

  (vline_node::vline_node): Migrate constructors to use new base
  class.

Changes `pline` request output as follows.

-{"type": "vline_node", "diversion level": 0, "is_special_node": false, 
"vunits": 15000},
+{"type": "vline_node", "diversion level": 0, "is_special_node": false, 
"vunits": 15000, "contents": [{"type": "glyph_node", "diversion level": 0, 
"is_special_node": false, "character": "!"}]},
---
 ChangeLog   | 11 +++
 src/roff/troff/node.cpp |  9 ++---
 src/roff/troff/node.h   |  5 +
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index da6ca9347..19178b721 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2025-03-03  G. Branden Robinson 
+
+   [troff]: Derive class `vline_node` from struct `container_node`.
+
+   * src/roff/troff/node.h (class vline_node): Do it.  Drop
+   pointer-to-node member variable and declaration of destructor.
+   * src/roff/troff/node.cpp (vline_node::~vline_node): Drop; our
+   base class handles destruction of contained node(s).
+   (vline_node::vline_node): Migrate constructors to use new base
+   class.
+
 2025-03-03  G. Branden Robinson 
 
[troff]: Derive class `hline_node` from struct `container_node`.
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 78f1080cc..2080d5066 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -3234,13 +3234,13 @@ hunits hline_node::width()
 }
 
 vline_node::vline_node(vunits i, node *c, node *nxt)
-: node(nxt), x(i), nodes(c)
+: container_node(nxt, c), x(i)
 {
 }
 
 vline_node::vline_node(vunits i, node *c, statem *s,
   int divlevel, node *nxt)
-: node(nxt, s, divlevel), x(i), nodes(c)
+: container_node(nxt, s, divlevel, c), x(i)
 {
 }
 
@@ -3251,11 +3251,6 @@ void vline_node::dump_properties()
   fflush(stderr);
 }
 
-vline_node::~vline_node()
-{
-  delete nodes;
-}
-
 node *vline_node::copy()
 {
   return new vline_node(x, (nodes != 0 /* nullptr */) ? nodes->copy()
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 71a172874..2bfc3b01e 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -445,15 +445,12 @@ public:
   void dump_properties();
 };
 
-// TODO: Derive from abstract class `container_node`.
-class vline_node : public node {
+class vline_node : public container_node {
   vunits x;
-  node *nodes;
 public:
   vline_node(vunits, node *, node * /* nxt */ = 0 /* nullptr */);
   vline_node(vunits, node *, statem *, int,
 node * /* nxt */ = 0 /* nullptr */);
-  ~vline_node();
   node *copy();
   void tprint(troff_output_file *);
   hunits width();

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 10/61: [doc,man]: Fix content and style nits.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit ef5ef6bc2bfbf466d02f2e0e888efce5e818aae6
Author: G. Branden Robinson 
AuthorDate: Fri Mar 14 22:41:46 2025 -0500

[doc,man]: Fix content and style nits.

Clarify and tighten discussions of reading the rest of the input line
into request arguments (again).  Parallelize wording.  Favor active
voice over passive.
---
 doc/groff.texi.in| 108 ---
 man/groff.7.man  |  51 
 man/groff_diff.7.man |  58 ++-
 3 files changed, 124 insertions(+), 93 deletions(-)

diff --git a/doc/groff.texi.in b/doc/groff.texi.in
index 8e3fcd455..37f739cbd 100644
--- a/doc/groff.texi.in
+++ b/doc/groff.texi.in
@@ -9005,7 +9005,7 @@ hyphenation patterns with the new ones.  Invoking 
@code{hpf} or
 loaded at startup, or in a macro package), GNU @code{troff} won't
 automatically hyphenate at all.
 
-@cindex trailing spaces in file name arguments
+@cindex spaces in file name arguments
 @cindex comments, after file name arguments
 @cindex @code{hpf} request, and comments
 @cindex @code{hpfa} request, and comments
@@ -9016,7 +9016,7 @@ and
 @code{hpfa}
 requests interpret the remainder of the input line as the file name
 argument,
-including trailing spaces,
+including any spaces,
 up to a newline or comment escape sequence.
 Suffixing the file name with a comment,
 even an empty one,
@@ -11429,7 +11429,7 @@ after the character can't be suppressed since the 
neighboring character
 on the right doesn't get examined.
 @endDefreq
 
-@cindex trailing spaces in character definitions
+@cindex spaces in character definitions
 @cindex comments, after character definitions
 @cindex @code{char} request, and comments
 @cindex @code{fchar} request, and comments
@@ -11468,9 +11468,11 @@ the character is defined with empty contents.
 
 GNU
 @command{troff} @c GNU
-removes a leading neutral double quote from
-@var{contents}
-permitting initial embedded spaces,
+removes a leading neutral double quote
+@samp{"}
+from
+@var{contents},
+permitting initial embedded spaces in it,
 and reads it to the end of the input line in copy mode.
 @xref{Copy Mode}.
 
@@ -11534,9 +11536,11 @@ request, but before the already mounted special fonts.
 @xref{Character Classes}.
 
 @strong{Caution:@:}
-These requests treats the remainder of the input line
+These requests remove a leading neutral double quote
+@samp{"}
+and treat the remainder of the input line
 as their second argument,
-including trailing spaces,
+including any spaces,
 up to a newline or comment escape sequence.
 See the discussion of the
 @code{ds}
@@ -12775,7 +12779,7 @@ Gray codes are explored in \*[cite Morgan 1998].
 @c @result{} I see a big, hairy wildebeest.
 @c @endExample
 
-@cindex trailing spaces in string definitions and appendments
+@cindex spaces in string definitions and appendments
 @cindex comments, with string definitions and appendments
 @cindex @code{as} request, and comments
 @cindex @code{as1} request, and comments
@@ -12785,7 +12789,7 @@ Gray codes are explored in \*[cite Morgan 1998].
 After the formatter has read the space character that ends the first
 argument,
 it treats the remainder of the input line as the second argument,
-including trailing spaces,
+including any spaces,
 up to a newline or comment escape sequence.
 Ending string definitions
 (and appendments)
@@ -12827,8 +12831,9 @@ you can retain it while using a comment to document an 
empty string.
 The formatter removes a leading neutral double quote
 @samp{"}
 from
-@var{contents}
-to permit the embedding of leading spaces.
+@var{contents},
+permitting initial embedded spaces in it.
+@c We briefly introduce and discuss "copy mode" below.
 It interprets any other
 @samp{"}
 literally,
@@ -12836,7 +12841,7 @@ but the wise author uses the special character escape 
sequence
 @code{\[dq]}
 instead if the string
 might be interpolated as part of a macro argument;
-see @ref{Calling Macros}.
+recall @ref{Calling Macros}.
 
 @c Examples should be more accessible than Unix nerd stuff like this,
 @c but in general document authors shouldn't want to use "straight"
@@ -12933,7 +12938,7 @@ Strings can be queried (@code{length}) and modified 
(@code{chop},
 can be manipulated through renaming, removal, and aliasing (@code{rn},
 @code{rm}, @code{als}).
 
-@cindex trailing spaces in string length measurement
+@cindex spaces in string length measurement
 @cindex comments, with string length measurements
 @cindex @code{length} request, and comments
 @Defreq {length, reg [[@code{"}]@Var{contents}]}
@@ -12947,8 +12952,13 @@ in the register @var{reg}.  If @var{reg} doesn't 
exist, it is created.
 
 GNU
 @command{troff} @c GNU
-removes a leading neutral double quote from the argument to the request,
-permitting embedded leading spaces.
+removes a leading neutral double quote
+@samp{"}
+from
+@var{length},
+permitting initial embedded spaces in it,
+a

[groff] 01/61: ChangeLog: Correct erroneous entry.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit bc345d1afe5ef0f85bedb8eab7fee4dc2922d84b
Author: G. Branden Robinson 
AuthorDate: Thu Mar 13 22:57:27 2025 -0500

ChangeLog: Correct erroneous entry.

Thanks to Dave Kemper for the discussion in
.
---
 ChangeLog | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0e76d5d1b..50f30c000 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -280,21 +280,23 @@
 
 2025-02-21  G. Branden Robinson 
 
-   [troff]: Make it possible to retrieve information about a *roff
-   character without creating it as a side effect.
+   [troff]: Refactor; make *roff character lookup without
+   side-effect of creation it more explicit.  (This way it's easier
+   to withdraw GNU troff's own `dictionary` class in the future in
+   favor of an STL container.)
 
* src/roff/troff/charinfo.h (get_charinfo):
* src/roff/troff/token.h (get_char):
* src/roff/troff/input.cpp (get_charinfo_by_index): Add new
`bool` argument `lookup_only`, defaulting `false`.
* src/roff/troff/input.cpp: Use these new facilities.
-   (report_character_request): Prevent creation of each character
-   we look up.  Improve diagnostics.  Report information about
-   indexed characters (`\N'123'`) more intelligibly.
-   (remove_character): Prevent creation of each character we
-   remove.  Intelligibly report nonexistence of characters for
-   which removal is attempted.  Throw error when attempt is made to
-   remove a non-character, like `\~`.
+   (report_character_request): Explicitly prevent creation of each
+   character we look up.  Improve diagnostics.  Report information
+   about indexed characters (`\N'123'`) more intelligibly.
+   (remove_character): Explicitly prevent creation of each
+   character we remove.  Intelligibly report nonexistence of
+   characters for which removal is attempted.  Throw error when
+   attempt is made to remove a non-character, like `\~`.
 
 2025-02-21  G. Branden Robinson 
 

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 44/61: [troff]: Implement recursive node dumping (5s/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 5964a1b34a5e02b68e3fd918b878fa629a5d2347
Author: G. Branden Robinson 
AuthorDate: Tue Mar 4 06:55:27 2025 -0600

[troff]: Implement recursive node dumping (5s/9).

* src/roff/troff/node.h (class italic_corrected_node): Specialize
  (override) `dump_properties()` for this class.

* src/roff/troff/node.cpp (italic_corrected_node::dump_properties): New
  member function reports value of `hunits` property.

Changes `pline` request output as follows.

-{"type": "italic_corrected_node", "diversion level": 0, "is_special_node": 
false},
+{"type": "italic_corrected_node", "diversion level": 0, "is_special_node": 
false, "hunits": 1960},
---
 ChangeLog   | 8 
 src/roff/troff/node.cpp | 8 
 2 files changed, 16 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index b1f9b11e4..0ecf8c8fd 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2025-03-04  G. Branden Robinson 
+
+   * src/roff/troff/node.h (class italic_corrected_node):
+   Specialize (override) `dump_properties()` for this class.
+   * src/roff/troff/node.cpp
+   (italic_corrected_node::dump_properties): New member function
+   reports value of `hunits` property.
+
 2025-03-03  G. Branden Robinson 
 
* src/roff/troff/node.h (class kern_pair_node): Specialize
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 3abb6b0aa..41e4ebd1a 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -2724,6 +2724,7 @@ public:
   const char *type();
   bool causes_tprint();
   bool is_tag();
+  void dump_properties();
 };
 
 node *node::add_italic_correction(hunits *wd)
@@ -2746,6 +2747,13 @@ italic_corrected_node::italic_corrected_node(node *nn, 
hunits xx, statem *s,
   assert(nodes != 0 /* nullptr */);
 }
 
+void italic_corrected_node::dump_properties()
+{
+  node::dump_properties();
+  fprintf(stderr, ", \"hunits\": %d", x.to_units());
+  fflush(stderr);
+}
+
 italic_corrected_node::~italic_corrected_node()
 {
   delete nodes;

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 31/61: [troff]: Implement recursive node dumping (5f/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit f663aaa1b65a5189b66e2b546341f6772c417843
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 02:15:30 2025 -0600

[troff]: Implement recursive node dumping (5f/9).

* src/roff/troff/node.h (class hmotion_node): Specialize (override)
  `dump_properties()` for this class.

* src/roff/troff/node.cpp (hmotion_node::dump_properties): New member
  function reports values of `hunits`, `was_tab`, `unformat`, and
  `terminal_color` properties.

Changes `pline` request output as follows.

-{"type": "hmotion_node", "diversion level": 0, "is_special_node": false},
+{"type": "hmotion_node", "diversion level": 0, "is_special_node": false, 
"hunits": 1, "was_tab": false, "unformat": false, "terminal_color": 
"default"},
---
 ChangeLog   |  8 
 src/roff/troff/node.cpp | 11 +++
 src/roff/troff/node.h   |  1 +
 3 files changed, 20 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 708c2572a..c39e2b7a1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2025-03-03  G. Branden Robinson 
+
+   * src/roff/troff/node.h (class hmotion_node): Specialize
+   {override} `dump_properties()` for this class.
+   * src/roff/troff/node.cpp (hmotion_node::dump_properties): New
+   member function reports values of `hunits`, `was_tab`,
+   `unformat`, and `terminal_color` properties.
+
 2025-03-03  G. Branden Robinson 
 
* src/roff/troff/node.h (class vertical_size_node): Specialize
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 4a3e77b84..0573f10ac 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -3044,6 +3044,17 @@ void vertical_size_node::dump_properties()
   fflush(stderr);
 }
 
+void hmotion_node::dump_properties()
+{
+  node::dump_properties();
+  fprintf(stderr, ", \"hunits\": %d", n.to_units());
+  fprintf(stderr, ", \"was_tab\": %s", was_tab ? "true" : "false");
+  fprintf(stderr, ", \"unformat\": %s", unformat ? "true" : "false");
+  fputs(", \"terminal_color\": ", stderr);
+  col->nm.json_dump();
+  fflush(stderr);
+}
+
 node *hmotion_node::copy()
 {
   return new hmotion_node(n, was_tab, unformat, col, state, div_nest_level);
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 0a0a35f00..12654f5cc 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -375,6 +375,7 @@ public:
   node *add_self(node *, hyphen_list **);
   hyphen_list *get_hyphen_list(hyphen_list *, int *);
   hyphenation_type get_hyphenation_type();
+  void dump_properties();
 };
 
 class space_char_hmotion_node : public hmotion_node {

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 37/61: [troff]: Implement recursive node dumping (5l/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit c6ccf9ea7297f7d7cbe5edb3332e82556d28bdc7
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 03:25:06 2025 -0600

[troff]: Implement recursive node dumping (5l/9).

* src/roff/troff/node.h (class bracket_node): Specialize (override)
  `dump_properties()` for this class.

* src/roff/troff/node.cpp (bracket_node::dump_properties): New member
  function reports value of `max_width` property.

Changes `pline` request output as follows.

-{"type": "bracket_node", "diversion level": 0, "is_special_node": false},
+{"type": "bracket_node", "diversion level": 0, "is_special_node": false, 
"max_width": 5640},
---
 ChangeLog   | 7 +++
 src/roff/troff/node.cpp | 7 +++
 src/roff/troff/node.h   | 2 ++
 3 files changed, 16 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 9b85fc47e..797fe7104 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2025-03-03  G. Branden Robinson 
+
+   * src/roff/troff/node.h (class bracket_node): Specialize
+   {override} `dump_properties()` for this class.
+   * src/roff/troff/node.cpp (bracket_node::dump_properties):
+   New member function reports value of `max_width` property.
+
 2025-03-03  G. Branden Robinson 
 
* src/roff/troff/node.h (class overstrike_node): Specialize
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index f4a8d589e..51dfb458a 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -3287,6 +3287,13 @@ bracket_node::bracket_node(statem *s, int divlevel)
 {
 }
 
+void bracket_node::dump_properties()
+{
+  node::dump_properties();
+  fprintf(stderr, ", \"max_width\": %d", max_width.to_units());
+  fflush(stderr);
+}
+
 bracket_node::~bracket_node()
 {
   delete_node_list(nodes);
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 4ab5e3aa8..3a3f85f1d 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -551,6 +551,7 @@ public:
   void dump_properties();
 };
 
+// TODO: Derive from abstract class `container_node`.
 class bracket_node : public node {
   node *nodes;
   hunits max_width;
@@ -566,6 +567,7 @@ public:
   const char *type();
   bool causes_tprint();
   bool is_tag();
+  void dump_properties();
 };
 
 class device_extension_node : public node {

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 59/61: [troff]: Implement recursive node dumping (8k/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit ece4499a2aee21f0f01be8bfed2b2f50460330b4
Author: G. Branden Robinson 
AuthorDate: Sat Mar 15 15:43:34 2025 -0500

[troff]: Implement recursive node dumping (8k/9).

* src/roff/troff/node.cpp (class kern_pair_node): Add `dump_node` member
  function, overriding virtual function in `node` base class.

  (kern_pair_node::dump_node): Disclose more information, namely the
  contents of any defined nodes within.

Changes `pline` request output as follows.

-{"type": "kern_pair_node", "diversion level": 0, "is_special_node": false, 
"amount": -100},
+{"type": "kern_pair_node", "diversion level": 0, "is_special_node": false, 
"amount": -100, "n1": {"type": "glyph_node", "diversion level": 0, 
"is_special_node": false, "character": "k"}, "n2": {"type": "glyph_node", 
"diversion level": 0, "is_special_node": false, "character": "e"}},

-{"type": "dbreak_node", "diversion level": 0, "is_special_node": false, 
"none": {"type": "glyph_node", "diversion level": 0, "is_special_node": false, 
"character": "r"}, "pre": {"type": "kern_pair_node", "diversion level": 0, 
"is_special_node": false, "amount": -200}},
+{"type": "dbreak_node", "diversion level": 0, "is_special_node": false, 
"none": {"type": "glyph_node", "diversion level": 0, "is_special_node": false, 
"character": "r"}, "pre": {"type": "kern_pair_node", "diversion level": 0, 
"is_special_node": false, "amount": -200, "n1": {"type": "glyph_node", 
"diversion level": 0, "is_special_node": false, "character": "r"}, "n2": 
{"type": "glyph_node", "diversion level": 0, "is_special_node": false, "special 
character": "hy"}}},
---
 ChangeLog   |  8 
 src/roff/troff/node.cpp | 24 ++--
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index c18ed59fe..9be5d62e3 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2025-03-15  G. Branden Robinson 
+
+   * src/roff/troff/node.cpp (class kern_pair_node): Add
+   `dump_node` member function, overriding virtual function in
+   `node` base class.
+   (kern_pair_node::dump_node): Disclose more information, namely
+   the contents of any contained nodes.
+
 2025-03-15  G. Branden Robinson 
 
* src/roff/troff/node.cpp (dbreak_node::dump_node): Refactor to
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index d0448d671..f43dddb8d 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -1990,8 +1990,8 @@ public:
   void dump_node();
 };
 
-// TODO: Do not derive from `container_node`; implement custom double
-// container dumper in dump_node().
+// Not derived from `container_node`; implements custom double container
+// dumper in dump_node().
 class kern_pair_node : public node {
   hunits amount;
   node *n1;
@@ -2020,6 +2020,7 @@ public:
   bool is_tag();
   void vertical_extent(vunits *, vunits *);
   void dump_properties();
+  void dump_node();
 };
 
 // Not derived from `container_node`; implements custom triple container
@@ -2332,6 +2333,25 @@ void kern_pair_node::dump_properties()
   fflush(stderr);
 }
 
+void kern_pair_node::dump_node()
+{
+  fputc('{', stderr);
+  // Flush so that in case something goes wrong with property dumping,
+  // we know that we traversed to a new node.
+  fflush(stderr);
+  dump_properties();
+  if (n1 != 0 /* nullptr */) {
+fputs(", \"n1\": ", stderr);
+n1->dump_node();
+  }
+  if (n2 != 0 /* nullptr */) {
+fputs(", \"n2\": ", stderr);
+n2->dump_node();
+  }
+  fputc('}', stderr);
+  fflush(stderr);
+}
+
 dbreak_node::dbreak_node(node *n, node *p, statem *s, int divlevel,
 node *x)
 : node(x, s, divlevel), none(n), pre(p), post(0 /* nullptr */)

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 42/61: [troff]: Implement recursive node dumping (5q/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 4103c1e309296fe0347a05b28b4f3476c2cc7472
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 08:33:43 2025 -0600

[troff]: Implement recursive node dumping (5q/9).

* src/roff/troff/node.h (class tag_node): Specialize (override)
  `dump_properties()` for this class.

* src/roff/troff/node.cpp (tag_node::dump_properties): New member
  function reports values of `string` and `delayed` properties.

"Tag nodes", like "suppress nodes", are some of groff's blacker magic,
and are entangled with grohtml.  Given the following simple input
document:

.NH 1
Introduction
.pline
.LP
Hello tag node world.

...processed with `groff -z -ms -Thtml`, this commit changes `pline`
request output as follows.

-{"type": "tag_node", "diversion level": 0, "is_special_node": true, 
"state": ""},
+{"type": "tag_node", "diversion level": 0, "is_special_node": true, 
"state": "", "string": "x X devtag:.NH 1\n", "delayed": 
false},

It's worth noting that the "string" gets populated with a trailing
newline (this is impossible for *roff strings, but this `string` type
is implemented as a C++ class).  This may or may not be a bug, depending
on how tag appending works.  If it's not a bug, we may want to rename
this property to something other than "string" to reduce potential user
confusion.
---
 ChangeLog   | 8 
 src/roff/troff/node.cpp | 9 +
 src/roff/troff/node.h   | 1 +
 3 files changed, 18 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 5b78df7d1..fd9398e2c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2025-03-03  G. Branden Robinson 
+
+   * src/roff/troff/node.h (class tag_node): Specialize (override)
+   `dump_properties()` for this class.
+   * src/roff/troff/node.cpp (tag_node::dump_properties): New
+   member function reports values of `string` and `delayed`
+   properties.
+
 2025-03-03  G. Branden Robinson 
 
* src/roff/troff/node.h (struct width_list): Declare `dump()`
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index c9595a8a5..423fb69e0 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -4220,6 +4220,15 @@ tag_node::tag_node(string s, statem *st, int divlevel, 
int delay)
   is_special = !delay;
 }
 
+void tag_node::dump_properties()
+{
+  node::dump_properties();
+  fputs(", \"string\": ", stderr);
+  tag_string.json_dump();
+  fprintf(stderr, ", \"delayed\": %s", delayed ? "true" : "false");
+  fflush(stderr);
+}
+
 node *tag_node::copy()
 {
   return new tag_node(tag_string, state, div_nest_level, delayed);
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 1d522bb41..e16869917 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -636,6 +636,7 @@ public:
   bool causes_tprint();
   bool is_tag();
   int ends_sentence(); // three-valued Boolean :-|
+  void dump_properties();
 };
 
 struct hvpair {

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 55/61: [troff]: Implement recursive node dumping (8g/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 94325a91b6813125ee902aa743a8288725606f8c
Author: G. Branden Robinson 
AuthorDate: Sat Mar 15 13:40:08 2025 -0500

[troff]: Implement recursive node dumping (8g/9).

Derive class `overstrike_node` from struct `container_node`.

* src/roff/troff/node.h (class overstrike_node): Do it.  Drop
  pointer-to-node member variable and declaration of destructor.

* src/roff/troff/node.cpp (overstrike_node::overstrike_node): Migrate
  constructors to use new base class.

  (overstrike_node::~overstrike_node): Drop; our base class handles
  destruction of contained node(s).

Changes `pline` request output as follows.

-{"type": "overstrike_node", "diversion level": 0, "is_special_node": 
false, "max_width": 7220},
+{"type": "overstrike_node", "diversion level": 0, "is_special_node": 
false, "max_width": 7220, "contents": [{"type": "glyph_node", "diversion 
level": 0, "is_special_node": false, "character": "O"}, {"type": "glyph_node", 
"diversion level": 0, "is_special_node": false, "character": "+"}]},
---
 ChangeLog   | 12 
 src/roff/troff/node.cpp | 10 ++
 src/roff/troff/node.h   |  5 +
 3 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 21b3700b2..a4ced42df 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2025-03-15  G. Branden Robinson 
+
+   [troff]: Derive class `overstrike_node` from struct
+   `container_node`.
+
+   * src/roff/troff/node.h (class overstrike_node): Do it.  Drop
+   pointer-to-node member variable and declaration of destructor.
+   * src/roff/troff/node.cpp (overstrike_node::overstrike_node):
+   Migrate constructors to use new base class.
+   (overstrike_node::~overstrike_node): Drop; our base class
+   handles destruction of contained node(s).
+
 2025-03-15  G. Branden Robinson 
 
[troff]: Derive class `left_italic_corrected_node` from struct
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 0e899dcb4..3d485efeb 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -3299,13 +3299,12 @@ void zero_width_node::vertical_extent(vunits *min, 
vunits *max)
 }
 
 overstrike_node::overstrike_node()
-: nodes(0 /* nullptr */), max_width(H0)
+: container_node(0 /* nullptr */), max_width(H0)
 {
 }
 
 overstrike_node::overstrike_node(statem *s, int divlevel)
-: node(0 /* nullptr */, s, divlevel), nodes(0 /* nullptr */),
-  max_width(H0)
+: container_node(0 /* nullptr */, s, divlevel), max_width(H0)
 {
 }
 
@@ -3316,11 +3315,6 @@ void overstrike_node::dump_properties()
   fflush(stderr);
 }
 
-overstrike_node::~overstrike_node()
-{
-  delete_node_list(nodes);
-}
-
 node *overstrike_node::copy()
 {
   overstrike_node *on = new overstrike_node(state, div_nest_level);
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 88ac5278a..a03c02a0f 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -534,14 +534,11 @@ public:
   void dump_properties();
 };
 
-// TODO: Derive from abstract class `container_node`.
-class overstrike_node : public node {
-  node *nodes;
+class overstrike_node : public container_node {
   hunits max_width;
 public:
   overstrike_node();
   overstrike_node(statem *, int);
-  ~overstrike_node();
   node *copy();
   void tprint(troff_output_file *);
   void overstrike(node *); // add another node to be overstruck

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 32/61: [troff]: Implement recursive node dumping (5g/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 3dbbafbb58f75920f80c1fbaeef75dd14b78ec24
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 02:22:53 2025 -0600

[troff]: Implement recursive node dumping (5g/9).

* src/roff/troff/node.h (class vmotion_node): Specialize (override)
  `dump_properties()` for this class.

* src/roff/troff/node.cpp (vmotion_node::dump_properties): New member
  function reports values of `vunits` and `terminal_color` properties.

Changes `pline` request output as follows.

-{"type": "vmotion_node", "diversion level": 0, "is_special_node": false},
+{"type": "vmotion_node", "diversion level": 0, "is_special_node": false, 
"vunits": 1, "terminal_color": "default"},
---
 ChangeLog   | 8 
 src/roff/troff/node.cpp | 9 +
 src/roff/troff/node.h   | 1 +
 3 files changed, 18 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index c39e2b7a1..b3f20e1e4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2025-03-03  G. Branden Robinson 
+
+   * src/roff/troff/node.h (class vmotion_node): Specialize
+   {override} `dump_properties()` for this class.
+   * src/roff/troff/node.cpp (vmotion_node::dump_properties): New
+   member function reports values of `vunits` and `terminal_color`
+   properties.
+
 2025-03-03  G. Branden Robinson 
 
* src/roff/troff/node.h (class hmotion_node): Specialize
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 0573f10ac..4fc7c7559 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -3075,6 +3075,15 @@ vmotion_node::vmotion_node(vunits i, color *c, statem 
*s, int divlevel)
 {
 }
 
+void vmotion_node::dump_properties()
+{
+  node::dump_properties();
+  fprintf(stderr, ", \"vunits\": %d", n.to_units());
+  fputs(", \"terminal_color\": ", stderr);
+  col->nm.json_dump();
+  fflush(stderr);
+}
+
 node *vmotion_node::copy()
 {
   return new vmotion_node(n, col, state, div_nest_level);
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 12654f5cc..f3f48de3a 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -410,6 +410,7 @@ public:
   const char *type();
   bool causes_tprint();
   bool is_tag();
+  void dump_properties();
 };
 
 class hline_node : public node {

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 30/61: [troff]: Implement recursive node dumping (5e/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 4d7ff76843e8deafb40eac5d13944e2805253d92
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 02:00:47 2025 -0600

[troff]: Implement recursive node dumping (5e/9).

* src/roff/troff/node.h (class vertical_size_node): Specialize
  (override) `dump_properties()` for this class.

* src/roff/troff/node.cpp (vertical_size_node::dump_properties): New
  member function reports value of `vunits` property.

At present I don't know of a way to get a vertical size node to report
itself in debugging output; the `pline` request works only on nodes that
are in a pending output line, and nodes of this type are added only to a
`macro_diversion` object, not an output line node list.  Nevertheless
this plants a tree today whose shade we might enjoy later.
---
 ChangeLog   | 7 +++
 src/roff/troff/node.cpp | 7 +++
 src/roff/troff/node.h   | 1 +
 3 files changed, 15 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 6c38da087..708c2572a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2025-03-03  G. Branden Robinson 
+
+   * src/roff/troff/node.h (class vertical_size_node): Specialize
+   {override} `dump_properties()` for this class.
+   * src/roff/troff/node.cpp (vertical_size_node::dump_properties):
+   New member function reports value of `vunits` property.
+
 2025-03-03  G. Branden Robinson 
 
* src/roff/troff/node.h (class extra_size_node): Specialize
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 635195011..4a3e77b84 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -3037,6 +3037,13 @@ vertical_size_node::vertical_size_node(vunits i)
 {
 }
 
+void vertical_size_node::dump_properties()
+{
+  node::dump_properties();
+  fprintf(stderr, ", \"vunits\": %d", n.to_units());
+  fflush(stderr);
+}
+
 node *hmotion_node::copy()
 {
   return new hmotion_node(n, was_tab, unformat, col, state, div_nest_level);
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index aa0293145..0a0a35f00 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -338,6 +338,7 @@ public:
   const char *type();
   bool causes_tprint();
   bool is_tag();
+  void dump_properties();
 };
 
 class hmotion_node : public node {

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 29/61: [troff]: Implement recursive node dumping (5d/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit b2887c3904bce09acae9450fe3b77dd96daa92cc
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 01:55:53 2025 -0600

[troff]: Implement recursive node dumping (5d/9).

* src/roff/troff/node.h (class extra_size_node): Specialize (override)
  `dump_properties()` for this class.

* src/roff/troff/node.cpp (extra_size_node::dump_properties): New member
  function reports value of `vunits` property.

Changes `pline` request output as follows.

-{"type": "extra_size_node", "diversion level": 0, "is_special_node": 
false},
+{"type": "extra_size_node", "diversion level": 0, "is_special_node": 
false, "vunits": 3000},
---
 ChangeLog   | 7 +++
 src/roff/troff/node.cpp | 7 +++
 src/roff/troff/node.h   | 1 +
 3 files changed, 15 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index b6e6af3f2..6c38da087 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2025-03-03  G. Branden Robinson 
+
+   * src/roff/troff/node.h (class extra_size_node): Specialize
+   {override} `dump_properties()` for this class.
+   * src/roff/troff/node.cpp (extra_size_node::dump_properties):
+   New member function reports value of `vunits` property.
+
 2025-03-03  G. Branden Robinson 
 
* src/roff/troff/node.h (class diverted_copy_file_node):
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index f538344e2..635195011 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -3014,6 +3014,13 @@ extra_size_node::extra_size_node(vunits i)
 {
 }
 
+void extra_size_node::dump_properties()
+{
+  node::dump_properties();
+  fprintf(stderr, ", \"vunits\": %d", n.to_units());
+  fflush(stderr);
+}
+
 node *vertical_size_node::copy()
 {
   return new vertical_size_node(n, state, div_nest_level);
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 0c5d176d0..aa0293145 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -322,6 +322,7 @@ public:
   const char *type();
   bool causes_tprint();
   bool is_tag();
+  void dump_properties();
 };
 
 class vertical_size_node : public node {

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 38/61: [troff]: Implement recursive node dumping (5m/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit cdb50249e92622a7f34e04b180d80059847b1edd
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 03:49:06 2025 -0600

[troff]: Implement recursive node dumping (5m/9).

* src/roff/troff/node.h (class device_extension_node): Specialize
  {override} `dump_properties()` for this class.

* src/roff/troff/node.cpp (device_extension_node::dump_properties): New
  member function reports values of `tfont`, `stroke_color`, and
  `fill_color` properties.

Changes `pline` request output as follows.

-{"type": "device_extension_node", "diversion level": 0, "is_special_node": 
true},
+{"type": "device_extension_node", "diversion level": 0, "is_special_node": 
true, "tfont": "TR", "stroke_color": "default", "fill_color": "default"},
---
 ChangeLog   |  9 +
 src/roff/troff/node.cpp | 13 +
 src/roff/troff/node.h   |  1 +
 3 files changed, 23 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 797fe7104..7928e4771 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2025-03-03  G. Branden Robinson 
+
+   * src/roff/troff/node.h (class device_extension_node):
+   Specialize {override} `dump_properties()` for this class.
+   * src/roff/troff/node.cpp
+   (device_extension_node::dump_properties): New member function
+   reports values of `tfont`, `stroke_color`, and `fill_color`
+   properties.
+
 2025-03-03  G. Branden Robinson 
 
* src/roff/troff/node.h (class bracket_node): Specialize
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 51dfb458a..83df3e903 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -4073,6 +4073,19 @@ device_extension_node::device_extension_node(const macro 
&m, tfont *t,
 {
 }
 
+void device_extension_node::dump_properties()
+{
+  node::dump_properties();
+  // TODO: Implement `macro::dump()` and call it on `mac` from here.
+  fputs(", \"tfont\": ", stderr);
+  tf->get_name().json_dump();
+  fputs(", \"stroke_color\": ", stderr);
+  gcol->nm.json_dump();
+  fputs(", \"fill_color\": ", stderr);
+  fcol->nm.json_dump();
+  fflush(stderr);
+}
+
 bool device_extension_node::is_same_as(node *n)
 {
   return ((mac == static_cast(n)->mac)
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 3a3f85f1d..f4a527999 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -594,6 +594,7 @@ public:
   bool is_tag();
   int ends_sentence();
   tfont *get_tfont();
+  void dump_properties();
 };
 
 class suppress_node : public node {

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 51/61: [troff]: Implement recursive node dumping (8c/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit c0811ebb9a92d675a9ca91d3dea5d7a9e2e62e8d
Author: G. Branden Robinson 
AuthorDate: Tue Mar 4 01:38:27 2025 -0600

[troff]: Implement recursive node dumping (8c/9).

Derive class `zero_width_node` from struct `container_node`.

* src/roff/troff/node.h (class zero_width_node): Do it.  Drop
  pointer-to-node member variable and declaration of destructor.

* src/roff/troff/node.cpp (zero_width_node::~zero_width_node): Drop; our
  base class handles destruction of contained node(s).

  (zero_width_node::zero_width_node): Migrate constructors to use new
  base class.

Changes `pline` request output as follows.

-{"type": "zero_width_node", "diversion level": 0, "is_special_node": 
false},
+{"type": "zero_width_node", "diversion level": 0, "is_special_node": 
false, "contents": [{"type": "dummy_node", "diversion level": 0, 
"is_special_node": false}, {"type": "glyph_node", "diversion level": 0, 
"is_special_node": false, "character": "a"}, {"type": "glyph_node", "diversion 
level": 0, "is_special_node": false, "character": "b"}, {"type": "glyph_node", 
"diversion level": 0, "is_special_node": false, "character": "c"}, {"type": 
"hmotion_node", "diversion level": 0, "is_specia [...]
---
 ChangeLog   | 12 
 src/roff/troff/node.cpp |  9 ++---
 src/roff/troff/node.h   |  5 +
 3 files changed, 15 insertions(+), 11 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 19178b721..7094d2080 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2025-03-04  G. Branden Robinson 
+
+   [troff]: Derive class `zero_width_node` from struct
+   `container_node`.
+
+   * src/roff/troff/node.h (class zero_width_node): Do it.  Drop
+   pointer-to-node member variable and declaration of destructor.
+   * src/roff/troff/node.cpp (zero_width_node::~zero_width_node):
+   Drop; our base class handles destruction of contained node(s).
+   (zero_width_node::zero_width_node): Migrate constructors to use
+   new base class.
+
 2025-03-03  G. Branden Robinson 
 
[troff]: Derive class `vline_node` from struct `container_node`.
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 2080d5066..58c89e97d 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -3264,20 +3264,15 @@ hunits vline_node::width()
 }
 
 zero_width_node::zero_width_node(node *nd, statem *s, int divlevel)
-: node(0 /* nullptr */, s, divlevel), nodes(nd)
+: container_node(0 /* nullptr */, s, divlevel, nd)
 {
 }
 
 zero_width_node::zero_width_node(node *nd)
-: nodes(nd)
+: container_node(nd)
 {
 }
 
-zero_width_node::~zero_width_node()
-{
-  delete_node_list(nodes);
-}
-
 node *zero_width_node::copy()
 {
   return new zero_width_node(copy_node_list(nodes), state,
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 2bfc3b01e..ec7c7e9bc 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -486,13 +486,10 @@ public:
   hyphenation_type get_hyphenation_type();
 };
 
-// TODO: Derive from abstract class `container_node`.
-class zero_width_node : public node {
-  node *nodes;
+class zero_width_node : public container_node {
 public:
   zero_width_node(node *);
   zero_width_node(node *, statem *, int);
-  ~zero_width_node();
   node *copy();
   void tprint(troff_output_file *);
   void ascii_print(ascii_output_file *);

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 47/61: [troff]: Implement recursive node dumping (6/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit bf34c55b121ef2d444cfc7307639797b27f0ad0b
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 11:05:34 2025 -0600

[troff]: Implement recursive node dumping (6/9).

The property of the environment that holds the pending output line
appears to be unique in storing the elements of its node list in reverse
order.  Rename function to reflect its specialized purpose.

* src/roff/troff/node.cpp (dump_node_list): Rename this...
  (dump_node_list_in_reverse): ...to this.

* src/roff/troff/env.cpp (environment::add_char) [0]:
  (environment::dump_pending_nodes): Update call sites.
---
 ChangeLog   | 12 
 src/roff/troff/env.cpp  | 10 +-
 src/roff/troff/node.cpp |  4 ++--
 3 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 69f92871e..0f5f87dee 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2025-03-03  G. Branden Robinson 
+
+   [troff]: The property of the environment that holds the pending
+   output line appears to be unique in storing the elements of its
+   node list in reverse order.  Rename function to reflect its
+   specialized purpose.
+
+   * src/roff/troff/node.cpp (dump_node_list): Rename this...
+   (dump_node_list_in_reverse): ...to this.
+   * src/roff/troff/env.cpp (environment::add_char) [0]:
+   (environment::dump_pending_nodes): Update call sites.
+
 2025-03-04  G. Branden Robinson 
 
* src/roff/troff/node.h (class break_char_node):
diff --git a/src/roff/troff/env.cpp b/src/roff/troff/env.cpp
index 4349bba66..37dd7954c 100644
--- a/src/roff/troff/env.cpp
+++ b/src/roff/troff/env.cpp
@@ -351,7 +351,7 @@ void environment::add_char(charinfo *ci)
   start_line();
 #if 0
 fprintf(stderr, "current line is\n");
-dump_node_list(line);
+dump_node_list_in_reverse(line);
 #endif
 if (ci != hyphen_indicator_char)
   line = line->add_char(ci, this, &width_total, &space_total, &gc_np);
@@ -360,7 +360,7 @@ void environment::add_char(charinfo *ci)
   }
 #if 0
   fprintf(stderr, "now after we have added character the line is\n");
-  dump_node_list(line);
+  dump_node_list_in_reverse(line);
 #endif
   if ((!suppress_push) && gc_np) {
 if (gc_np && (gc_np->state == 0 /* nullptr */)) {
@@ -374,7 +374,7 @@ void environment::add_char(charinfo *ci)
   }
 #if 0
   fprintf(stderr, "now we have possibly added the state the line is\n");
-  dump_node_list(line);
+  dump_node_list_in_reverse(line);
 #endif
 }
 
@@ -2418,11 +2418,11 @@ void environment::dump_troff_state()
 #undef SPACES
 }
 
-extern void dump_node_list(node *);
+extern void dump_node_list_in_reverse(node *);
 
 void environment::dump_pending_nodes()
 {
-  dump_node_list(line);
+  dump_node_list_in_reverse(line);
 }
 
 statem *environment::construct_state(bool has_only_eol)
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index baebd6d95..d9f0e2a2d 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -2633,8 +2633,8 @@ void node::dump_node()
   fflush(stderr);
 }
 
-// TODO: Turn this into container_node::dump().
-void dump_node_list(node *nlist)
+// TODO: Move this into env.cpp.
+void dump_node_list_in_reverse(node *nlist)
 {
   // It's stored in reverse order already; this puts it forward again.
   std::stack reversed_node_list;

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 53/61: [troff]: Implement recursive node dumping (8e/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 613e384e5072edf8d455710be40a4d94d4b27809
Author: G. Branden Robinson 
AuthorDate: Tue Mar 4 08:33:21 2025 -0600

[troff]: Implement recursive node dumping (8e/9).

Derive class `break_char_node` from struct `container_node`.

* src/roff/troff/node.h (class break_char_node): Do it.  Drop
  pointer-to-node member variable and declaration of destructor.

* src/roff/troff/node.cpp (break_char_node::break_char_node): Migrate
  constructors to use new base class.

  (break_char_node::~break_char_node): Drop; our base class handles
  destruction of contained node(s).

Changes `pline` request output as follows.

-{"type": "break_char_node", "diversion level": 0, "is_special_node": 
false, "break code before": 2, "break code after": 0, "terminal_color": 
"default"},
+{"type": "break_char_node", "diversion level": 0, "is_special_node": 
false, "break code before": 2, "break code after": 0, "terminal_color": 
"default", "contents": [{"type": "glyph_node", "diversion level": 0, 
"is_special_node": false, "character": "-"}]},
---
 ChangeLog   | 12 
 src/roff/troff/node.cpp | 15 +++
 2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 65f58d14f..59a9e00d1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2025-03-04  G. Branden Robinson 
+
+   [troff]: Derive class `break_char_node` from struct
+   `container_node`.
+
+   * src/roff/troff/node.h (class break_char_node): Do it.  Drop
+   pointer-to-node member variable and declaration of destructor.
+   * src/roff/troff/node.cpp (break_char_node::break_char_node):
+   Migrate constructors to use new base class.
+   (break_char_node::~break_char_node): Drop; our base class
+   handles destruction of contained node(s).
+
 2025-03-04  G. Branden Robinson 
 
[troff]: Derive class `italic_corrected_node` from struct
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 398d4abab..d33d7c3b4 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -2915,9 +2915,7 @@ int italic_corrected_node::character_type()
   return nodes->character_type();
 }
 
-// TODO: Derive from abstract class `container_node`.
-class break_char_node : public node {
-  node *nodes;
+class break_char_node : public container_node {
   char break_code;
   char prev_break_code;
   color *col;
@@ -2925,7 +2923,6 @@ public:
   break_char_node(node *, int, int, color *, node * = 0 /* nullptr */);
   break_char_node(node *, int, int, color *, statem *, int,
  node * = 0 /* nullptr */);
-  ~break_char_node();
   node *copy();
   hunits width();
   vunits vertical_width();
@@ -2952,14 +2949,13 @@ public:
 };
 
 break_char_node::break_char_node(node *n, int bc, int pbc, color *c, node *x)
-: node(x), nodes(n), break_code(bc), prev_break_code(pbc), col(c)
+: container_node(x, n), break_code(bc), prev_break_code(pbc), col(c)
 {
 }
 
 break_char_node::break_char_node(node *n, int bc, int pbc, color *c,
 statem *s, int divlevel, node *x)
-: node(x, s, divlevel), nodes(n), break_code(bc), prev_break_code(pbc),
-  col(c)
+: container_node(x, s, divlevel, n), break_code(bc), prev_break_code(pbc), 
col(c)
 {
 }
 
@@ -2973,11 +2969,6 @@ void break_char_node::dump_properties()
   fflush(stderr);
 }
 
-break_char_node::~break_char_node()
-{
-  delete nodes;
-}
-
 node *break_char_node::copy()
 {
   return new break_char_node(nodes->copy(), break_code, prev_break_code,

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 54/61: [troff]: Implement recursive node dumping (8f/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 875dc87033627d3bb695ec06b1b5e2937f509a45
Author: G. Branden Robinson 
AuthorDate: Sat Mar 15 01:52:14 2025 -0500

[troff]: Implement recursive node dumping (8f/9).

Derive class `left_italic_corrected_node` from struct `container_node`.

* src/roff/troff/node.h (class left_italic_corrected_node): Do it.  Drop
  pointer-to-node member variable and declaration of destructor.

* src/roff/troff/node.cpp
  (left_italic_corrected_node::left_italic_corrected_node): Migrate
  constructors to use new base class.

  (left_italic_corrected_node::~left_italic_corrected_node): Drop; our
  base class handles destruction of contained node(s).

Changes `pline` request output as follows.

-{"type": "left_italic_corrected_node", "diversion level": 0, 
"is_special_node": false, "hunits": 1970},
+{"type": "left_italic_corrected_node", "diversion level": 0, 
"is_special_node": false, "hunits": 1970, "contents": [{"type": "glyph_node", 
"diversion level": 0, "is_special_node": false, "character": "f"}]},
---
 ChangeLog   | 14 ++
 src/roff/troff/node.cpp |  9 ++---
 src/roff/troff/node.h   |  5 +
 3 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 59a9e00d1..21b3700b2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2025-03-15  G. Branden Robinson 
+
+   [troff]: Derive class `left_italic_corrected_node` from struct
+   `container_node`.
+
+   * src/roff/troff/node.h (class left_italic_corrected_node): Do
+   it.  Drop pointer-to-node member variable and declaration of
+   destructor.
+   * src/roff/troff/node.cpp
+   (left_italic_corrected_node::left_italic_corrected_node):
+   Migrate constructors to use new base class.
+   (left_italic_corrected_node::~left_italic_corrected_node): Drop;
+   our base class handles destruction of contained node(s).
+
 2025-03-04  G. Branden Robinson 
 
[troff]: Derive class `break_char_node` from struct
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index d33d7c3b4..0e899dcb4 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -5816,14 +5816,14 @@ bool italic_corrected_node::is_tag()
 }
 
 left_italic_corrected_node::left_italic_corrected_node(node *xx)
-: node(xx), nodes(0 /* nullptr */)
+: container_node(xx)
 {
 }
 
 left_italic_corrected_node::left_italic_corrected_node(statem *s,
   int divlevel,
   node *xx)
-: node(xx, s, divlevel), nodes(0 /* nullptr */)
+: container_node(xx, s, divlevel)
 {
 }
 
@@ -5834,11 +5834,6 @@ void left_italic_corrected_node::dump_properties()
   fflush(stderr);
 }
 
-left_italic_corrected_node::~left_italic_corrected_node()
-{
-  delete nodes;
-}
-
 node *left_italic_corrected_node::merge_glyph_node(glyph_node *gn)
 {
   if (0 /* nullptr */ == nodes) {
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index ec7c7e9bc..88ac5278a 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -502,15 +502,12 @@ public:
   void vertical_extent(vunits *, vunits *);
 };
 
-// TODO: Derive from abstract class `container_node`.
-class left_italic_corrected_node : public node {
-  node *nodes;
+class left_italic_corrected_node : public container_node {
   hunits x;
 public:
   left_italic_corrected_node(node * /* xx */ = 0 /* nullptr */);
   left_italic_corrected_node(statem *, int,
 node * /* xx */ = 0 /* nullptr */);
-  ~left_italic_corrected_node();
   void tprint(troff_output_file *);
   void ascii_print(ascii_output_file *);
   void asciify(macro *);

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 28/61: [troff]: Implement recursive node dumping (5c/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 5e13a5d9f951fbd212bd7531a0a7390843277b4a
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 01:33:58 2025 -0600

[troff]: Implement recursive node dumping (5c/9).

* src/roff/troff/node.h (class diverted_copy_file_node): Specialize
  (override) `dump_properties()` for this class.

* src/roff/troff/node.cpp (diverted_copy_file_node::dump_properties):
  New member function reports value of `filename` property.

At present I don't know of a way to get a diverted copy file node to
report itself in debugging output; the `pline` request works only on
nodes that are in a pending output line, and nodes of this type are
added only to a `macro_diversion` object, not an output line node list.
Nevertheless this plants a tree today whose shade we might enjoy later.

Here's an example of what its output would look like:

{"type": "diverted_copy_file_node", "diversion level": 0, 
"is_special_node": false, "filename": "ATTIC/trf-fodder"}
---
 ChangeLog   | 8 
 src/roff/troff/node.cpp | 8 
 src/roff/troff/node.h   | 1 +
 3 files changed, 17 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index e3c46daba..b6e6af3f2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2025-03-03  G. Branden Robinson 
+
+   * src/roff/troff/node.h (class diverted_copy_file_node):
+   Specialize (override) `dump_properties()` for this class.
+   * src/roff/troff/node.cpp
+   (diverted_copy_file_node::dump_properties): New member function
+   reports value of `filename` property.
+
 2025-03-02  G. Branden Robinson 
 
* src/roff/troff/node.h (class diverted_space_node): Specialize
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index b50a7095d..f538344e2 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -3416,6 +3416,14 @@ diverted_copy_file_node::diverted_copy_file_node(symbol 
s, node *p)
 {
 }
 
+void diverted_copy_file_node::dump_properties()
+{
+  node::dump_properties();
+  fputs(", \"filename\": ", stderr);
+  filename.json_dump();
+  fflush(stderr);
+}
+
 node *diverted_copy_file_node::copy()
 {
   return new diverted_copy_file_node(filename, state, div_nest_level);
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 7045b4acc..0c5d176d0 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -308,6 +308,7 @@ public:
   const char *type();
   bool causes_tprint();
   bool is_tag();
+  void dump_properties();
 };
 
 class extra_size_node : public node {

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 61/61: [troff]: Implement recursive node dumping (9/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit df28af3adcab2f54236993e73e153bad8aff3f62
Author: G. Branden Robinson 
AuthorDate: Sat Mar 15 16:36:43 2025 -0500

[troff]: Implement recursive node dumping (9/9).

Implement dumping of device extension node contents.

* src/roff/troff/request.h (class macro): Declare `json_dump()` member
  function.

* src/roff/troff/node.cpp (device_extension_node::dump_properties): Call
  member variable `mac`'s `json_dump()` member function.

* src/roff/troff/input.cpp (class macro_header): Declare `json_dump()`
  member function.

  (macro::json_dump): New member function calls `macro_header` `p`
  member variable's `json_dump()` member function.

  (macro_header::json_dump): New member function iterates though
  `char_list` `cl` member variable's elements, calling
  `json_encode_char()` on each one.

Changes `pline` request output as follows.

-{"type": "device_extension_node", "diversion level": 0, "is_special_node": 
true, "tfont": "TR", "stroke_color": "default", "fill_color": "default"},
+{"type": "device_extension_node", "diversion level": 0, "is_special_node": 
true, "macro": "custom-command", "tfont": "TR", "stroke_color": "default", 
"fill_color": "default"},
---
 ChangeLog| 17 +
 src/roff/troff/input.cpp | 23 +++
 src/roff/troff/node.cpp  |  3 ++-
 src/roff/troff/request.h |  3 ++-
 4 files changed, 44 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 76ff7a700..89a975aae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2025-03-15  G. Branden Robinson 
+
+   [troff]: Implement dumping of device extension node contents.
+
+   * src/roff/troff/request.h (class macro): Declare `json_dump()`
+   member function.
+   * src/roff/troff/node.cpp
+   (device_extension_node::dump_properties): Call member variable
+   `mac`'s `json_dump()` member function.
+   * src/roff/troff/input.cpp (class macro_header): Declare
+   `json_dump()` member function.
+   (macro::json_dump): New member function calls `macro_header` `p`
+   member variable's `json_dump()` member function.
+   (macro_header::json_dump): New member function iterates though
+   `char_list` `cl` member variable's elements, calling
+   `json_encode_char()` on each one.
+
 2025-03-15  G. Branden Robinson 
 
[troff]: Trivially refactor.
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index 4faf6f287..9c4427f3f 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -36,6 +36,8 @@ along with this program.  If not, see 
. */
 
 #include 
 
+#include "json-encode.h" // json_encode_char()
+
 #include "troff.h"
 #include "dictionary.h"
 #include "hvunits.h"
@@ -3548,6 +3550,7 @@ public:
   node_list nl;
   macro_header() { count = 1; }
   macro_header *copy(int);
+  void json_dump();
 };
 
 macro::~macro()
@@ -3711,6 +3714,11 @@ void macro::print_size()
   errprint("%1", len);
 }
 
+void macro::json_dump()
+{
+  p->json_dump();
+}
+
 // make a copy of the first n bytes
 
 macro_header *macro_header::copy(int n)
@@ -3734,6 +3742,21 @@ macro_header *macro_header::copy(int n)
   return p;
 }
 
+void macro_header::json_dump()
+{
+  fputc('\"', stderr);
+  int macro_len = cl.length();
+  for (int i = 0; i < macro_len; i++) {
+json_char jc = json_encode_char(cl.get(i));
+// Write out its JSON representation by character by character to
+// keep libc string functions from interpreting C escape sequences.
+for (size_t j = 0; j < jc.len; j++)
+  fputc(jc.buf[j], stderr);
+  }
+  fputc('\"', stderr);
+  fflush(stderr);
+}
+
 void print_macros()
 {
   object_dictionary_iterator iter(request_dictionary);
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index b4ff2dc31..b02ce00b9 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -4148,7 +4148,8 @@ device_extension_node::device_extension_node(const macro 
&m, tfont *t,
 void device_extension_node::dump_properties()
 {
   node::dump_properties();
-  // TODO: Implement `macro::dump()` and call it on `mac` from here.
+  fputs(", \"macro\": ", stderr);
+  mac.json_dump();
   fputs(", \"tfont\": ", stderr);
   tf->get_name().json_dump();
   fputs(", \"stroke_color\": ", stderr);
diff --git a/src/roff/troff/request.h b/src/roff/troff/request.h
index 74e9e1ad4..335adb8fe 100644
--- a/src/roff/troff/request.h
+++ b/src/roff/troff/request.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2024 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2025 Free Software Foundation, Inc.
  Written by James Clark (j...@jclark.com)
 
 This file is part of groff.
@@ -70,6 +70,7 @@ public:
   bool is_diversion();
   bool is_string();
   void clear_string_flag();
+  void json_dump();
   friend class string_iterator;
   friend void chop_ma

[groff] 60/61: [troff]: Trivially refactor.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 3336497f15ba63b1a91a11afe692f1ab2fe470f4
Author: G. Branden Robinson 
AuthorDate: Sat Mar 15 15:54:11 2025 -0500

[troff]: Trivially refactor.

* src/roff/troff/node.cpp: Relocate `dump_node_list_in_reverse` function
  from here...
* src/roff/troff/env.cpp: ...to here.
---
 ChangeLog   |  8 
 src/roff/troff/env.cpp  | 27 ++-
 src/roff/troff/node.cpp | 28 
 3 files changed, 34 insertions(+), 29 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9be5d62e3..76ff7a700 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2025-03-15  G. Branden Robinson 
+
+   [troff]: Trivially refactor.
+
+   * src/roff/troff/node.cpp: Relocate `dump_node_list_in_reverse`
+   function from here...
+   * src/roff/troff/env.cpp: ...to here.
+
 2025-03-15  G. Branden Robinson 
 
* src/roff/troff/node.cpp (class kern_pair_node): Add
diff --git a/src/roff/troff/env.cpp b/src/roff/troff/env.cpp
index 37dd7954c..fb81a1dc9 100644
--- a/src/roff/troff/env.cpp
+++ b/src/roff/troff/env.cpp
@@ -2418,7 +2418,32 @@ void environment::dump_troff_state()
 #undef SPACES
 }
 
-extern void dump_node_list_in_reverse(node *);
+static void dump_node_list_in_reverse(node *nlist)
+{
+  // It's stored in reverse order already; this puts it forward again.
+  std::stack reversed_node_list;
+  node *n = nlist;
+
+  while (n != 0 /* nullptr */) {
+reversed_node_list.push(n);
+n = n->next;
+  }
+  fputc('[', stderr);
+  bool need_comma = false;
+  while (!reversed_node_list.empty()) {
+if (need_comma)
+  fputs(",\n", stderr);
+reversed_node_list.top()->dump_node();
+reversed_node_list.pop();
+need_comma = true;
+  }
+  // !need_comma implies that the list was empty.  JSON convention is to
+  // put a space between an empty pair of square brackets.
+  if (!need_comma)
+fputc(' ', stderr);
+  fputs("]\n", stderr);
+  fflush(stderr);
+}
 
 void environment::dump_pending_nodes()
 {
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index f43dddb8d..b4ff2dc31 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -2742,34 +2742,6 @@ void container_node::dump_node()
   fflush(stderr);
 }
 
-// TODO: Move this into env.cpp.
-void dump_node_list_in_reverse(node *nlist)
-{
-  // It's stored in reverse order already; this puts it forward again.
-  std::stack reversed_node_list;
-  node *n = nlist;
-
-  while (n != 0 /* nullptr */) {
-reversed_node_list.push(n);
-n = n->next;
-  }
-  fputc('[', stderr);
-  bool need_comma = false;
-  while (!reversed_node_list.empty()) {
-if (need_comma)
-  fputs(",\n", stderr);
-reversed_node_list.top()->dump_node();
-reversed_node_list.pop();
-need_comma = true;
-  }
-  // !need_comma implies that the list was empty.  JSON convention is to
-  // put a space between an empty pair of square brackets.
-  if (!need_comma)
-fputc(' ', stderr);
-  fputs("]\n", stderr);
-  fflush(stderr);
-}
-
 hunits kern_pair_node::width()
 {
   return n1->width() + n2->width() + amount;

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 27/61: [troff]: Implement recursive node dumping (5b/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit d2e5975d27ea2f1c39bddcd5cf2952ffd4ba2039
Author: G. Branden Robinson 
AuthorDate: Sun Mar 2 22:57:37 2025 -0600

[troff]: Implement recursive node dumping (5b/9).

* src/roff/troff/node.h (class diverted_space_node): Specialize
  (override) `dump_properties()` for this class.

* src/roff/troff/node.cpp (diverted_space_node::dump_properties): New
  member function reports value of `vunits` property.

At present I don't know of a way to get a diverted space node to report
itself in debugging output; the `pline` request works only on nodes that
are in a pending output line, and a diverted space node, being a form of
vertical space (and not "local" vertical motion), exists only between
output lines.  Nevertheless this plants a tree today whose shade we
might enjoy later.
---
 ChangeLog   | 8 
 src/roff/troff/node.cpp | 7 +++
 src/roff/troff/node.h   | 1 +
 3 files changed, 16 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 43b70b7af..e3c46daba 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2025-03-02  G. Branden Robinson 
+
+   * src/roff/troff/node.h (class diverted_space_node): Specialize
+   {override} `dump_properties()` for this class.
+   * src/roff/troff/node.cpp
+   (diverted_space_node::dump_properties): New member function
+   reports value of `vunits` property.
+
 2025-03-02  G. Branden Robinson 
 
* src/roff/troff/node.h (class space_node): Specialize
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 76ad72331..b50a7095d 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -3393,6 +3393,13 @@ diverted_space_node::diverted_space_node(vunits d, node 
*p)
 {
 }
 
+void diverted_space_node::dump_properties()
+{
+  node::dump_properties();
+  fprintf(stderr, ", \"vunits\": %d", n.to_units());
+  fflush(stderr);
+}
+
 node *diverted_space_node::copy()
 {
   return new diverted_space_node(n, state, div_nest_level);
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 1cad968cf..7045b4acc 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -292,6 +292,7 @@ public:
   const char *type();
   bool causes_tprint();
   bool is_tag();
+  void dump_properties();
 };
 
 class diverted_copy_file_node : public node {

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 48/61: [troff]: Implement recursive node dumping (7/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit d0886007a98ecb33857061f698c7801559c98b8c
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 11:16:08 2025 -0600

[troff]: Implement recursive node dumping (7/9).

Create new `struct container_node` for node types that contain a
(possibly singleton) list of other nodes.

* src/roff/troff/node.h (container_node): Do it.  Declare constructors
  mirroring those of `struct node` (but with an extra argument for the
  contained node list); a destructor; and virtual member function
  `dump_node()`, overriding that of `struct node`.

* src/roff/troff/node.cpp (dump_node_list): New function, a
  counterpart to `copy_node_list()` and `delete_node_list()`, walks a
  singly-linked list of nodes and directs each to dump itself.

  (container_node::container_node, container_node::~container_node)
  (container_node::dump_node): Define the foregoing.

  (container_node::~container_node): Destructor always calls
  `delete_node_list()` because some node types seem intended to contain
  only one other node, and others a list.  Unifying the destruction
  procedure seems more likely to avoid memory leaks, at a cost per
  destroyed object derived from `container_node` of an additional
  function call and a test of a pointer for nullity--but only for
  objects of classes where this wasn't already happening.
---
 ChangeLog   | 25 ++
 src/roff/troff/node.cpp | 69 +
 src/roff/troff/node.h   | 14 ++
 3 files changed, 108 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 0f5f87dee..0caffdc20 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,28 @@
+2025-03-03  G. Branden Robinson 
+
+   [troff]: Create new `struct container_node` for node types that
+   contain a {possibly singleton} list of other nodes.
+
+   * src/roff/troff/node.h (container_node): Do it.  Declare
+   constructors mirroring those of `struct node` (but with an extra
+   argument for the contained node list); a destructor; and virtual
+   member function `dump_node()`, overriding that of `struct node`.
+   * src/roff/troff/node.cpp (dump_node_list): New function, a
+   counterpart to `copy_node_list()` and `delete_node_list()`,
+   walks a singly-linked list of nodes and directs each to dump
+   itself.
+   (container_node::container_node)
+   (container_node::~container_node, container_node::dump_node):
+   Define the foregoing.
+   (container_node::~container_node): Destructor always calls
+   `delete_node_list()` because some node types seem intended to
+   contain only one other node, and others a list.  Unifying the
+   destruction procedure seems more likely to avoid memory leaks,
+   at a cost per destroyed object derived from `container_node`
+   of an additional function call and a test of a pointer for
+   nullity--but only for objects of classes where this wasn't
+   already happening.
+
 2025-03-03  G. Branden Robinson 
 
[troff]: The property of the environment that holds the pending
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index d9f0e2a2d..a8e08f6c0 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -2450,6 +2450,25 @@ void delete_node_list(node *n)
   }
 }
 
+void dump_node_list(node *n)
+{
+  bool need_comma = false;
+  fputs("\"contents\": [", stderr);
+  while (n != 0 /* nullptr */) {
+if (need_comma)
+  fputs(", ", stderr);
+n->dump_node();
+need_comma = true;
+n = n->next;
+  }
+  // !need_comma implies that the list was empty.  JSON convention is to
+  // put a space between an empty pair of square brackets.
+  if (!need_comma)
+fputc(' ', stderr);
+  fputc(']', stderr);
+  fflush(stderr);
+}
+
 node *dbreak_node::copy()
 {
   dbreak_node *p = new dbreak_node(copy_node_list(none),
@@ -2633,6 +2652,56 @@ void node::dump_node()
   fflush(stderr);
 }
 
+container_node::container_node(node *contents)
+: node(), nodes(contents)
+{
+}
+
+container_node::container_node(node *nxt, node *contents)
+: node(nxt), nodes(contents)
+{
+}
+
+// `left_italic_corrected_node` uses an initially empty container.
+container_node::container_node(node *nxt, statem *s, int divl)
+: node(nxt, s, divl), nodes(0 /* nullptr */)
+{
+}
+
+#if 0
+container_node::container_node(node *nxt, statem *s, node *contents)
+: node(nxt, s), nodes(contents)
+{
+}
+#endif
+
+container_node::container_node(node *nxt, statem *s, int divl,
+  node *contents)
+: node(nxt, s, divl), nodes(contents)
+{
+}
+
+container_node::container_node(node *nxt, statem *s, int divl,
+  bool special, node *contents)
+: node(nxt, s, divl, special), nodes(contents)
+{
+}
+
+container_node::~container_node()
+{
+  delete_node_list(nodes);
+}
+
+void c

[groff] 26/61: [troff]: Implement recursive node dumping (5a/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit fa89cbcb4e16d618d562c7a8118daa9d2b98e1e9
Author: G. Branden Robinson 
AuthorDate: Sun Mar 2 22:46:57 2025 -0600

[troff]: Implement recursive node dumping (5a/9).

* src/roff/troff/node.h (class space_node): Specialize (override)
  `dump_properties()` for this class.

* src/roff/troff/node.cpp (space_node::dump_properties): New member
  function reports value of `hunits` property.

Changes `pline` request output as follows.

-{"type": "word_space_node", "diversion level": 0, "is_special_node": 
false, "hunits": 2500}]
+{"type": "word_space_node", "diversion level": 0, "is_special_node": 
false, "hunits": 2500, "undiscardable": false, "is hyphenless breakpoint": 
false, "terminal_color": "default"}]

-{"type": "space_node", "diversion level": 0, "is_special_node": false},
+{"type": "space_node", "diversion level": 0, "is_special_node": false, 
"hunits": 0},
-{"type": "space_node", "diversion level": 0, "is_special_node": false},
+{"type": "space_node", "diversion level": 0, "is_special_node": false, 
"hunits": 0, "undiscardable": true, "is hyphenless breakpoint": true, 
"terminal_color": "default"},
---
 ChangeLog   |  7 +++
 src/roff/troff/node.cpp | 12 
 src/roff/troff/node.h   |  1 +
 3 files changed, 20 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 0da838c93..43b70b7af 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2025-03-02  G. Branden Robinson 
+
+   * src/roff/troff/node.h (class space_node): Specialize
+   {override} `dump_properties()` for this class.
+   * src/roff/troff/node.cpp (space_node::dump_properties): New
+   member function reports value of `hunits` property.
+
 2025-03-02  G. Branden Robinson 
 
* src/roff/troff/node.cpp (class charinfo_node): Declare
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index dfc451ba6..76ad72331 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -3293,6 +3293,18 @@ space_node::space_node(hunits nn, int s, int flag, color 
*c, statem *st,
 {
 }
 
+void space_node::dump_properties()
+{
+  node::dump_properties();
+  fprintf(stderr, ", \"hunits\": %d", n.to_units());
+  fprintf(stderr, ", \"undiscardable\": %s", set ? "true" : "false");
+  fprintf(stderr, ", \"is hyphenless breakpoint\": %s",
+ was_escape_colon ? "true" : "false");
+  fputs(", \"terminal_color\": ", stderr);
+  col->nm.json_dump();
+  fflush(stderr);
+}
+
 #if 0
 space_node::~space_node()
 {
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 2af7662b0..1cad968cf 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -220,6 +220,7 @@ public:
   bool causes_tprint();
   bool is_tag();
   hyphenation_type get_hyphenation_type();
+  void dump_properties();
 };
 
 struct width_list {

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 49/61: [troff]: Implement recursive node dumping (8a/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 244bf138b177e9f1d1aad1309458e437796dc4f7
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 11:23:48 2025 -0600

[troff]: Implement recursive node dumping (8a/9).

Derive class `hline_node` from struct `container_node`.

* src/roff/troff/node.h (class hline_node): Do it.  Drop pointer-to-node
  member variable and declaration of destructor.

* src/roff/troff/node.cpp (hline_node::~hline_node): Drop; our base
  class handles destruction of contained node(s).

  (hline_node::hline_node): Migrate constructors to use new base class.

Changes `pline` request output as follows.

-{"type": "hline_node", "diversion level": 0, "is_special_node": false, 
"hunits": 144},
+{"type": "hline_node", "diversion level": 0, "is_special_node": false, 
"hunits": 144, "contents": [{"type": "glyph_node", "diversion level": 0, 
"is_special_node": false, "character": "A"}]},
---
 ChangeLog   | 11 +++
 src/roff/troff/node.cpp |  9 ++---
 src/roff/troff/node.h   |  5 +
 3 files changed, 14 insertions(+), 11 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 0caffdc20..da6ca9347 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2025-03-03  G. Branden Robinson 
+
+   [troff]: Derive class `hline_node` from struct `container_node`.
+
+   * src/roff/troff/node.h (class hline_node): Do it.  Drop
+   pointer-to-node member variable and declaration of destructor.
+   * src/roff/troff/node.cpp (hline_node::~hline_node): Drop; our
+   base class handles destruction of contained node(s).
+   (hline_node::hline_node): Migrate constructors to use new base
+   class.
+
 2025-03-03  G. Branden Robinson 
 
[troff]: Create new `struct container_node` for node types that
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index a8e08f6c0..78f1080cc 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -3203,19 +3203,14 @@ node *transparent_dummy_node::copy()
   return new transparent_dummy_node;
 }
 
-hline_node::~hline_node()
-{
-  delete nodes;
-}
-
 hline_node::hline_node(hunits i, node *c, node *nxt)
-: node(nxt), x(i), nodes(c)
+: container_node(nxt, c), x(i)
 {
 }
 
 hline_node::hline_node(hunits i, node *c, statem *s, int divlevel,
   node *nxt)
-: node(nxt, s, divlevel), x(i), nodes(c)
+: container_node(nxt, s, divlevel, c), x(i)
 {
 }
 
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 37fa68d8e..71a172874 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -429,15 +429,12 @@ struct container_node : public node {
   virtual void dump_node();
 };
 
-// TODO: Derive from abstract class `container_node`.
-class hline_node : public node {
+class hline_node : public container_node {
   hunits x;
-  node *nodes;
 public:
   hline_node(hunits, node *, node * /* nxt */ = 0 /* nullptr */);
   hline_node(hunits, node *, statem *, int,
 node * /* nxt */ = 0 /* nullptr */);
-  ~hline_node();
   node *copy();
   hunits width();
   void tprint(troff_output_file *);

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 36/61: [troff]: Implement recursive node dumping (5k/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 6a79bde452a503a7e61b9c2c206ac7164ff052de
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 03:11:29 2025 -0600

[troff]: Implement recursive node dumping (5k/9).

* src/roff/troff/node.h (class overstrike_node): Specialize (override)
  `dump_properties()` for this class.

* src/roff/troff/node.cpp (overstrike_node::dump_properties): New member
  function reports value of `max_width` property.

Changes `pline` request output as follows.

-{"type": "overstrike_node", "diversion level": 0, "is_special_node": 
false},
+{"type": "overstrike_node", "diversion level": 0, "is_special_node": 
false, "max_width": 7220},
---
 ChangeLog   | 7 +++
 src/roff/troff/node.cpp | 7 +++
 src/roff/troff/node.h   | 2 ++
 3 files changed, 16 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 784a72f3e..9b85fc47e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2025-03-03  G. Branden Robinson 
+
+   * src/roff/troff/node.h (class overstrike_node): Specialize
+   {override} `dump_properties()` for this class.
+   * src/roff/troff/node.cpp (overstrike_node::dump_properties):
+   New member function reports value of `max_width` property.
+
 2025-03-03  G. Branden Robinson 
 
* src/roff/troff/node.h (class left_italic_corrected_node):
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 33aea95ab..f4a8d589e 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -3237,6 +3237,13 @@ overstrike_node::overstrike_node(statem *s, int divlevel)
 {
 }
 
+void overstrike_node::dump_properties()
+{
+  node::dump_properties();
+  fprintf(stderr, ", \"max_width\": %d", max_width.to_units());
+  fflush(stderr);
+}
+
 overstrike_node::~overstrike_node()
 {
   delete_node_list(nodes);
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 4714be33d..4ab5e3aa8 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -529,6 +529,7 @@ public:
   void dump_properties();
 };
 
+// TODO: Derive from abstract class `container_node`.
 class overstrike_node : public node {
   node *nodes;
   hunits max_width;
@@ -547,6 +548,7 @@ public:
   node *add_self(node *, hyphen_list **);
   hyphen_list *get_hyphen_list(hyphen_list *, int *);
   hyphenation_type get_hyphenation_type();
+  void dump_properties();
 };
 
 class bracket_node : public node {

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 40/61: [troff]: Implement recursive node dumping (5o/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 309a4f6c2b32e5646ca0d564b3fd4b69588086fb
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 04:27:50 2025 -0600

[troff]: Implement recursive node dumping (5o/9).

* src/roff/troff/node.h (class draw_node): Specialize (override)
  `dump_properties()` for this class.

* src/roff/troff/node.cpp (draw_node::dump_properties): New member
  function reports values of `code`, `npoints`, `font_size`,
  `stroke_color`, `fill_color`, and `point` properties.

Changes `pline` request output as follows.

-{"type": "draw_node", "diversion level": 0, "is_special_node": false},
+{"type": "draw_node", "diversion level": 0, "is_special_node": false, 
"code": "l", "npoints": 1, "font_size": 1, "stroke_color": "default", 
"fill_color": "default", "point": "(72000, 72000)"},
---
 ChangeLog   |  9 +
 src/roff/troff/node.cpp | 13 +
 src/roff/troff/node.h   |  1 +
 3 files changed, 23 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index acb820702..c4050044f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2025-03-03  G. Branden Robinson 
+
+   * src/roff/troff/node.h (class draw_node): Specialize (override)
+   `dump_properties()` for this class.
+   * src/roff/troff/node.cpp (draw_node::dump_properties): New
+   member function reports values of `code`, `npoints`,
+   `font_size`, `stroke_color`, `fill_color`, and `point`
+   properties.
+
 2025-03-03  G. Branden Robinson 
 
* src/roff/troff/node.h (class suppress_node): Specialize
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index e665e71da..facd48f88 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -4757,6 +4757,19 @@ draw_node::draw_node(char c, hvpair *p, int np, 
font_size s,
 point[i] = p[i];
 }
 
+void draw_node::dump_properties()
+{
+  node::dump_properties();
+  fprintf(stderr, ", \"code\": \"%c\"", code);
+  fprintf(stderr, ", \"npoints\": %d", npoints);
+  fprintf(stderr, ", \"font_size\": %d", sz.to_units());
+  fprintf(stderr, ", \"stroke_color\": \"%s\"", gcol->nm.contents());
+  fprintf(stderr, ", \"fill_color\": \"%s\"", fcol->nm.contents());
+  fprintf(stderr, ", \"point\": \"(%d, %d)\"",
+ point->h.to_units(), point->v.to_units());
+  fflush(stderr);
+}
+
 bool draw_node::is_same_as(node *n)
 {
   draw_node *nd = (draw_node *)n;
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index b2fc1e521..35b39d1ad 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -662,6 +662,7 @@ public:
   const char *type();
   bool causes_tprint();
   bool is_tag();
+  void dump_properties();
 };
 
 class charinfo;

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 52/61: [troff]: Implement recursive node dumping (8d/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 424b8e453aab357323984e4f6a4bad537784d54d
Author: G. Branden Robinson 
AuthorDate: Tue Mar 4 07:26:41 2025 -0600

[troff]: Implement recursive node dumping (8d/9).

Derive class `italic_corrected_node` from struct `container_node`.

* src/roff/troff/node.h (class italic_corrected_node): Do it.  Drop
  pointer-to-node member variable and declaration of destructor.

* src/roff/troff/node.cpp
  (italic_corrected_node::italic_corrected_node): Migrate constructors
  to use new base class.

  (italic_corrected_node::~italic_corrected_node): Drop; our base class
  handles destruction of contained node(s).

Changes `pline` request output as follows.

-{"type": "italic_corrected_node", "diversion level": 0, "is_special_node": 
false, "hunits": 1960},
+{"type": "italic_corrected_node", "diversion level": 0, "is_special_node": 
false, "hunits": 1960, "contents": [{"type": "glyph_node", "diversion level": 
0, "is_special_node": false, "character": "f"}]},
---
 ChangeLog   | 14 ++
 src/roff/troff/node.cpp | 12 ++--
 2 files changed, 16 insertions(+), 10 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 7094d2080..65f58d14f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2025-03-04  G. Branden Robinson 
+
+   [troff]: Derive class `italic_corrected_node` from struct
+   `container_node`.
+
+   * src/roff/troff/node.h (class italic_corrected_node): Do it.
+   Drop pointer-to-node member variable and declaration of
+   destructor.
+   * src/roff/troff/node.cpp
+   (italic_corrected_node::italic_corrected_node): Migrate
+   constructors to use new base class.
+   (italic_corrected_node::~italic_corrected_node): Drop; our base
+   class handles destruction of contained node(s).
+
 2025-03-04  G. Branden Robinson 
 
[troff]: Derive class `zero_width_node` from struct
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 58c89e97d..398d4abab 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -2771,14 +2771,11 @@ hunits dbreak_node::subscript_correction()
   return none ? none->subscript_correction() : H0;
 }
 
-// TODO: Derive from abstract class `container_node`.
-class italic_corrected_node : public node {
-  node *nodes;
+class italic_corrected_node : public container_node {
   hunits x;
 public:
   italic_corrected_node(node *, hunits, statem *, int,
node * = 0 /* nullptr */);
-  ~italic_corrected_node();
   node *copy();
   void ascii_print(ascii_output_file *);
   void asciify(macro *);
@@ -2818,7 +2815,7 @@ node *node::add_italic_correction(hunits *wd)
 
 italic_corrected_node::italic_corrected_node(node *nn, hunits xx, statem *s,
 int divlevel, node *p)
-: node(p, s, divlevel), nodes(nn), x(xx)
+: container_node(p, s, divlevel, nn), x(xx)
 {
   assert(nodes != 0 /* nullptr */);
 }
@@ -2830,11 +2827,6 @@ void italic_corrected_node::dump_properties()
   fflush(stderr);
 }
 
-italic_corrected_node::~italic_corrected_node()
-{
-  delete nodes;
-}
-
 node *italic_corrected_node::copy()
 {
   return new italic_corrected_node(nodes->copy(), x, state,

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 39/61: [troff]: Implement recursive node dumping (5n/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 45e77e894ec19a38ffa8722a76b6c9b2bdf5c7b3
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 04:08:58 2025 -0600

[troff]: Implement recursive node dumping (5n/9).

* src/roff/troff/node.h (class suppress_node): Specialize (override)
  `dump_properties()` for this class.

* src/roff/troff/node.cpp (suppress_node::dump_properties): New member
  function reports values of `is_on`, `emit_limits`, `filename` (if not
  null), `position` (if not a null character), and `image_id`
  properties.

"Suppress nodes" are some of groff's blacker magic, and are entangled
with grohtml.  Given the following simple input document:

.EQ
x = 1
.EN
.pline
Hello suppress node world.

...processed with `groff -e -Thtml` (and application of `sort -u` to
stderr), this commit changes `pline` request output as follows.

-{"type": "suppress_node", "diversion level": 0, "is_special_node": false},
-{"type": "suppress_node", "diversion level": 0, "is_special_node": true, 
"state": ""},
-{"type": "suppress_node", "diversion level": 0, "is_special_node": true},
+{"type": "suppress_node", "diversion level": 0, "is_special_node": false, 
"is_on": 0, "emit_limits": false, "image_id": 0},
+{"type": "suppress_node", "diversion level": 0, "is_special_node": false, 
"is_on": 0, "emit_limits": false, "image_id": 0},
+{"type": "suppress_node", "diversion level": 0, "is_special_node": false, 
"is_on": 1, "emit_limits": false, "image_id": 0},
+{"type": "suppress_node", "diversion level": 0, "is_special_node": false, 
"is_on": 1, "emit_limits": false, "image_id": 0},
+{"type": "suppress_node", "diversion level": 0, "is_special_node": false, 
"is_on": 1, "emit_limits": true, "image_id": 0},
+{"type": "suppress_node", "diversion level": 0, "is_special_node": false, 
"is_on": 1, "emit_limits": true, "image_id": 0},
+{"type": "suppress_node", "diversion level": 0, "is_special_node": true, 
"state": "", "is_on": 2, "emit_limits": false, "filename": "1.png", 
"position": "c", "image_id": 1},
+{"type": "suppress_node", "diversion level": 0, "is_special_node": true, 
"state": "", "is_on": 2, "emit_limits": false, "filename": "2.png", 
"position": "c", "image_id": 2},
---
 ChangeLog   | 10 ++
 src/roff/troff/node.cpp | 14 ++
 src/roff/troff/node.h   |  1 +
 3 files changed, 25 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 7928e4771..acb820702 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2025-03-03  G. Branden Robinson 
+
+   * src/roff/troff/node.h (class suppress_node): Specialize
+   {override} `dump_properties()` for this class.
+   * src/roff/troff/node.cpp
+   (suppress_node::dump_properties): New member function
+   reports values of `is_on`, `emit_limits`, `filename` (if not
+   null), `position` (if not a null character), and `image_id`
+   properties.
+
 2025-03-03  G. Branden Robinson 
 
* src/roff/troff/node.h (class device_extension_node):
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 83df3e903..e665e71da 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -4167,6 +4167,20 @@ suppress_node::suppress_node(int issue_limits, int 
on_or_off,
 {
 }
 
+void suppress_node::dump_properties()
+{
+  node::dump_properties();
+  fprintf(stderr, ", \"is_on\": %d", is_on);
+  fprintf(stderr, ", \"emit_limits\": %s",
+ emit_limits ? "true" : "false");
+  if (filename.contents() != 0 /* nullptr */)
+fprintf(stderr, ", \"filename\": \"%s\"", filename.contents());
+  if (position != '\0')
+fprintf(stderr, ", \"position\": \"%c\"", position);
+  fprintf(stderr, ", \"image_id\": %d", image_id);
+  fflush(stderr);
+}
+
 bool suppress_node::is_same_as(node *n)
 {
   return ((is_on == ((suppress_node *)n)->is_on)
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index f4a527999..b2fc1e521 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -615,6 +615,7 @@ public:
   const char *type();
   bool causes_tprint();
   bool is_tag();
+  void dump_properties();
 private:
   void put(troff_output_file *, const char *);
 };

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 57/61: [troff]: Implement recursive node dumping (8i/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 3648a3be66435e17c6cc4080e4146171b26ceca5
Author: G. Branden Robinson 
AuthorDate: Sat Mar 15 15:04:03 2025 -0500

[troff]: Implement recursive node dumping (8i/9).

* src/roff/troff/node.cpp (class ligature_node): Add `dump_node` member
  function, overriding virtual function in `node` base class.

  (ligature_node::dump_node): Disclose more information, namely the
  contents of any contained nodes.

Changes `pline` request output as follows.

-{"type": "ligature_node", "diversion level": 0, "is_special_node": false, 
"special character": "fl"},
+{"type": "ligature_node", "diversion level": 0, "is_special_node": false, 
"n1": {"type": "glyph_node", "diversion level": 0, "is_special_node": false, 
"character": "f"}, "n2": {"type": "glyph_node", "diversion level": 0, 
"is_special_node": false, "character": "l"}},
---
 ChangeLog   |  8 
 src/roff/troff/node.cpp | 24 ++--
 2 files changed, 30 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f1bcf224a..68b2d7627 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2025-03-15  G. Branden Robinson 
+
+   * src/roff/troff/node.cpp (class ligature_node): Add `dump_node`
+   member function, overriding virtual function in `node` base
+   class.
+   (ligature_node::dump_node): Disclose more information, namely
+   the contents of any contained nodes.
+
 2025-03-15  G. Branden Robinson 
 
[troff]: Derive class `bracket_node` from struct
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 6df4bccd5..c82b02517 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -1961,8 +1961,8 @@ public:
   bool is_tag();
 };
 
-// TODO: Do not derive from `container_node`; implement custom double
-// container dumper in dump_node().
+// Not derived from `container_node`; implements custom double container
+// dumper in dump_node().
 class ligature_node : public glyph_node {
   node *n1;
   node *n2;
@@ -1987,6 +1987,7 @@ public:
   const char *type();
   bool causes_tprint();
   bool is_tag();
+  void dump_node();
 };
 
 // TODO: Do not derive from `container_node`; implement custom double
@@ -2299,6 +2300,25 @@ node *ligature_node::add_self(node *n, hyphen_list **p)
   return n;
 }
 
+void ligature_node::dump_node()
+{
+  fputc('{', stderr);
+  // Flush so that in case something goes wrong with property dumping,
+  // we know that we traversed to a new node.
+  fflush(stderr);
+  node::dump_properties();
+  if (n1 != 0 /* nullptr */) {
+fputs(", \"n1\": ", stderr);
+n1->dump_node();
+  }
+  if (n2 != 0 /* nullptr */) {
+fputs(", \"n2\": ", stderr);
+n2->dump_node();
+  }
+  fputc('}', stderr);
+  fflush(stderr);
+}
+
 kern_pair_node::kern_pair_node(hunits n, node *first, node *second,
   statem* s, int divlevel, node *x)
 : node(x, s, divlevel), amount(n), n1(first), n2(second)

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 34/61: [troff]: Implement recursive node dumping (5i/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit aba02db80d377e00d9e350561f1a9addf8eb6969
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 02:48:59 2025 -0600

[troff]: Implement recursive node dumping (5i/9).

* src/roff/troff/node.h (class vline_node): Specialize (override)
  `dump_properties()` for this class.

* src/roff/troff/node.cpp (vline_node::dump_properties): New member
  function reports value of `vunits` property.

Changes `pline` request output as follows.

-{"type": "vline_node", "diversion level": 0, "is_special_node": false},
+{"type": "vline_node", "diversion level": 0, "is_special_node": false, 
"vunits": 15000},
---
 ChangeLog   | 7 +++
 src/roff/troff/node.cpp | 7 +++
 src/roff/troff/node.h   | 2 ++
 3 files changed, 16 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index c236c1a2d..5e4f16eef 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2025-03-03  G. Branden Robinson 
+
+   * src/roff/troff/node.h (class vline_node): Specialize
+   {override} `dump_properties()` for this class.
+   * src/roff/troff/node.cpp (vline_node::dump_properties): New
+   member function reports value of `vunits` property.
+
 2025-03-03  G. Branden Robinson 
 
* src/roff/troff/node.h (class hline_node): Specialize
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 276f73303..48c3fe483 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -3145,6 +3145,13 @@ vline_node::vline_node(vunits i, node *c, statem *s,
 {
 }
 
+void vline_node::dump_properties()
+{
+  node::dump_properties();
+  fprintf(stderr, ", \"vunits\": %d", x.to_units());
+  fflush(stderr);
+}
+
 vline_node::~vline_node()
 {
   delete nodes;
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 0a124521f..867616be2 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -432,6 +432,7 @@ public:
   void dump_properties();
 };
 
+// TODO: Derive from abstract class `container_node`.
 class vline_node : public node {
   vunits x;
   node *nodes;
@@ -449,6 +450,7 @@ public:
   const char *type();
   bool causes_tprint();
   bool is_tag();
+  void dump_properties();
 };
 
 class dummy_node : public node {

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 20/61: [troff]: Revise `pline` output style.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 06a1368ca954dabc07e7c45d2ac68bebb44f7b5e
Author: G. Branden Robinson 
AuthorDate: Sat Mar 15 15:13:39 2025 -0500

[troff]: Revise `pline` output style.

Use more JSON/YAML-ish syntax.  Present node properties in a consistent
order: first, general node properties (read: member variables of the
`node` abstract class); next, type-specific properties (read: member
variables of classes derived from `node`); then, general node properties
used only by MTSM/grohtml, which I hope one day to refactor away.

* src/roff/troff/node.cpp (glyph_node::dump_node)
  (node::dump_node, node::dump_node_list)
  (composite_node::dump_node)
  (dbreak_node::dump_node): Do it.

  (node::dump_node): Report the `is_special_node` Boolean property.

  (glyph_node::dump_node, composite_node::dump_node): Write string
  values with JSON-valid escaped characters.
---
 ChangeLog   |  17 +++
 src/roff/troff/node.cpp | 133 +++-
 2 files changed, 114 insertions(+), 36 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index c7512f7f4..74066b114 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,20 @@
+2025-03-02  G. Branden Robinson 
+
+   [troff]: Revise `pline` output style.  Use more JSON/YAML-ish
+   syntax.  Present node properties in a consistent order: first,
+   general node properties (read: member variables of the `node`
+   abstract class); next, type-specific properties (read: member
+   variables of classes derived from `node`); then, general node
+   properties used only by MTSM/grohtml, which I hope one day to
+   refactor away.
+
+   * src/roff/troff/node.cpp (glyph_node::dump_node)
+   (node::dump_node, node::dump_node_list)
+   (composite_node::dump_node, dbreak_node::dump_node): Do it.
+   (node::dump_node): Report the `is_special` Boolean property.
+   (glyph_node::dump_node, composite_node::dump_node): Write string
+   values with JSON-valid escaped characters.
+
 2025-03-04  G. Branden Robinson 
 
[libgroff]: Add `json_length()`, `json_extract()`, and
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 547b23953..0bd007e7b 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -2214,19 +2214,41 @@ void glyph_node::ascii_print(ascii_output_file *ascii)
 // presumably has several different solutions for this.  Pick one.
 void glyph_node::dump_node()
 {
+  fprintf(stderr, "{\"type\": \"%s\"", type());
+  // GNU troff multiplexes the distinction of ordinary vs. special
+  // characters though the special character code zero.
   unsigned char c = ci->get_ascii_code();
-  fprintf(stderr, "{type: %s, character: ", type());
-  if (c)
-fprintf(stderr, "\"%c\"", c);
-  else
-fprintf(stderr, "\"\\%s\"", ci->nm.contents());
-  if (push_state)
-fprintf(stderr, ", push_state");
+  if (c) {
+fputs(", \"character\": ", stderr);
+fputc('\"', stderr);
+// JSON-encode the (printable Basic Latin) character.
+switch (c) {
+case '"':
+case '\\':
+case '/':
+  fputc('\\', stderr);
+  // fall through
+default:
+  fputc(c, stderr);
+  break;
+}
+fputc('\"', stderr);
+  }
+  else {
+fputs(", \"special character\": ", stderr);
+ci->nm.json_dump();
+  }
+  fprintf(stderr, ", \"diversion level\": %d", div_nest_level);
+  fprintf(stderr, ", \"is_special_node\": %s",
+ is_special ? "true" : "false");
+  if (push_state) {
+fputs(", \"push_state\": ", stderr);
+push_state->display_state();
+  }
   if (state) {
-fprintf(stderr, ", state: ");
+fputs(", \"state\": ", stderr);
 state->display_state();
   }
-  fprintf(stderr, ", diversion level: %d", div_nest_level);
   fputs("}", stderr);
   fflush(stderr);
 }
@@ -2589,12 +2611,18 @@ units node::size()
 
 void node::dump_node()
 {
-  fprintf(stderr, "{type: %s", type());
-  if (push_state)
-fputs(", ", stderr);
-  if (state)
-fputs(", ", stderr);
-  fprintf(stderr, ", diversion level: %d", div_nest_level);
+  fprintf(stderr, "{\"type\": \"%s\"", type());
+  fprintf(stderr, ", \"diversion level\": %d", div_nest_level);
+  fprintf(stderr, ", \"is_special_node\": %s",
+ is_special ? "true" : "false");
+  if (push_state) {
+fputs(", \"push_state\": ", stderr);
+push_state->display_state();
+  }
+  if (state) {
+fputs(", \"state\": ", stderr);
+state->display_state();
+  }
   fputs("}", stderr);
   fflush(stderr);
 }
@@ -2604,13 +2632,14 @@ void node::dump_node_list()
   // It's stored in reverse order already; this puts it forward again.
   std::stack reversed_node_list;
   node *n = next;
-  bool need_comma = false;
 
   assert(next != 0 /* nullptr */);
   do {
 reversed_node_list.push(n);
 n = n->next;
   } while (n != 0 /* nullptr */);
+  fputc('[', stderr);
+  bool need_comma = false;

[groff] 35/61: [troff]: Implement recursive node dumping (5j/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit c1e91d2f17c1f2a03ec94c33c7b240c21f8c802f
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 03:01:59 2025 -0600

[troff]: Implement recursive node dumping (5j/9).

* src/roff/troff/node.h (class left_italic_corrected_node): Specialize
  (override) `dump_properties()` for this class.

* src/roff/troff/node.cpp (left_italic_corrected_node::dump_properties):
  New member function reports value of `hunits` property.

Changes `pline` request output as follows.

-{"type": "left_italic_corrected_node", "diversion level": 0, 
"is_special_node": false},
+{"type": "left_italic_corrected_node", "diversion level": 0, 
"is_special_node": false, "hunits": 1970},
---
 ChangeLog   | 8 
 src/roff/troff/node.cpp | 7 +++
 src/roff/troff/node.h   | 2 ++
 3 files changed, 17 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 5e4f16eef..784a72f3e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2025-03-03  G. Branden Robinson 
+
+   * src/roff/troff/node.h (class left_italic_corrected_node):
+   Specialize (override) `dump_properties()` for this class.
+   * src/roff/troff/node.cpp
+   (left_italic_corrected_node::dump_properties): New member
+   function reports value of `hunits` property.
+
 2025-03-03  G. Branden Robinson 
 
* src/roff/troff/node.h (class vline_node): Specialize
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 48c3fe483..33aea95ab 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -5662,6 +5662,13 @@ 
left_italic_corrected_node::left_italic_corrected_node(statem *s,
 {
 }
 
+void left_italic_corrected_node::dump_properties()
+{
+  node::dump_properties();
+  fprintf(stderr, ", \"hunits\": %d", x.to_units());
+  fflush(stderr);
+}
+
 left_italic_corrected_node::~left_italic_corrected_node()
 {
   delete nodes;
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 867616be2..4714be33d 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -494,6 +494,7 @@ public:
   void vertical_extent(vunits *, vunits *);
 };
 
+// TODO: Derive from abstract class `container_node`.
 class left_italic_corrected_node : public node {
   node *nodes;
   hunits x;
@@ -525,6 +526,7 @@ public:
   hyphen_list *get_hyphen_list(hyphen_list *, int *);
   node *add_self(node *, hyphen_list **);
   node *merge_glyph_node(glyph_node *);
+  void dump_properties();
 };
 
 class overstrike_node : public node {

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 11/61: doc/groff.texi.in: Recast.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 2b11926ab7d927099647f8df168cf18d48defb04
Author: G. Branden Robinson 
AuthorDate: Fri Mar 14 22:43:43 2025 -0500

doc/groff.texi.in: Recast.

Favor active voice over passive.
---
 doc/groff.texi.in | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/doc/groff.texi.in b/doc/groff.texi.in
index 37f739cbd..a53882e98 100644
--- a/doc/groff.texi.in
+++ b/doc/groff.texi.in
@@ -11887,8 +11887,8 @@ esthetics of typeset text.  @dfn{Ligatures} are 
sequences of glyphs that
 are visually connected or ``tied'', overlapping them and slightly
 altering their shapes.  @dfn{Kerning} is the adjustment of horizontal
 spacing between glyphs.  Neither is employed on terminals.@footnote{A
-monospaced font may possess glyphs for ligatures, but they are
-nevertheless seldom used to set text.}
+monospaced font may possess glyphs for ligatures, but they nevertheless
+seldom see use to set text.}
 
 Most typesetters support ligatures for the sequences `fi', `fl', `ff',
 `ffi', and `ffl', and @code{troff} does likewise.  Some fonts may

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 19/61: [libgroff]: Support object dumping in JSON (3/3).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit de62829ca4ce5a8d84a76393f43fbd9bf890f3e9
Author: G. Branden Robinson 
AuthorDate: Tue Mar 4 04:30:10 2025 -0600

[libgroff]: Support object dumping in JSON (3/3).

Support JSON dumping of `symbol`s.

Add `json_length()`, `json_extract()`, and `json_dump()` public member
functions to `symbol` class.  The enhanced node printing feature will
require them.

* src/include/symbol.h (class symbol): Declare them.
* src/libs/libgroff/symbol.cpp (symbol::json_length):
  (symbol::json_extract, symbol::json_dump): Implement them.
---
 ChangeLog| 10 ++
 src/include/symbol.h |  3 ++
 src/libs/libgroff/symbol.cpp | 80 +++-
 3 files changed, 92 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 5480dee2a..c7512f7f4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2025-03-04  G. Branden Robinson 
+
+   [libgroff]: Add `json_length()`, `json_extract()`, and
+   `json_dump()` public member functions to `symbol` class.  The
+   enhanced node printing feature will require them.
+
+   * src/include/symbol.h (class symbol): Declare them.
+   * src/libs/libgroff/symbol.cpp (symbol::json_length):
+   (symbol::json_extract, symbol::json_dump): Implement them.
+
 2025-03-04  G. Branden Robinson 
 
[libgroff]: Add `json_length()`, `json_extract()`, and
diff --git a/src/include/symbol.h b/src/include/symbol.h
index d82d7cd29..ef8805354 100644
--- a/src/include/symbol.h
+++ b/src/include/symbol.h
@@ -38,6 +38,9 @@ public:
   const char *contents() const;
   bool is_null() const;
   bool is_empty() const;
+  size_t json_length() const;
+  const char *json_extract() const;
+  void json_dump() const;
 };
 
 
diff --git a/src/libs/libgroff/symbol.cpp b/src/libs/libgroff/symbol.cpp
index 7bc8a8f4c..1ed91f359 100644
--- a/src/libs/libgroff/symbol.cpp
+++ b/src/libs/libgroff/symbol.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2024 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2025 Free Software Foundation, Inc.
  Written by James Clark (j...@jclark.com)
 
 This file is part of groff.
@@ -22,7 +22,10 @@ along with this program.  If not, see 
. */
 
 #include 
 #include  // strcat(), strcmp(), strcpy(), strlen()
+#include  // calloc()
 
+#include "cset.h" // csprint()
+#include "json-encode.h" // json_encode_char()
 #include "lib.h"
 
 #include "errarg.h"
@@ -160,6 +163,81 @@ symbol concat(symbol s1, symbol s2)
   return res;
 }
 
+// Compute length of JSON representation of object.
+size_t symbol::json_length() const
+{
+  size_t len = 0;
+  const char *p = s;
+  char ch;
+  int nextrachars = 2; // leading and trailing double quotes
+  for (size_t i = 0; p[i] != '\0'; i++, len++) {
+ch = p[i];
+// Handle the most common cases first.
+if (ch < 128) {
+  if (csprint(ch))
+   ;
+  else
+   switch (ch) {
+   case '"':
+   case '\\':
+   case '/':
+   case '\b':
+   case '\f':
+   case '\n':
+   case '\r':
+   case '\t':
+ nextrachars++;
+ break;
+   default:
+ nextrachars += 5;
+  }
+}
+else
+  nextrachars += 5;
+  }
+  return (len + nextrachars);
+}
+
+// Like `extract()`, but double-quote the string and escape characters
+// per JSON.  (Unlike groff's `string`, a `symbol` doesn't contain
+// embedded null characters.)  This string is not null-terminated!
+// Caller MUST use .json_length().  (The member variable backing us up
+// _is_ a null-terminated C string.)
+const char *symbol::json_extract() const
+{
+  const char *p = s;
+  size_t n = strlen(s);
+  size_t i;
+  char *q = static_cast(calloc(this->json_length(),
+  sizeof (char)));
+  if (q != 0 /* nullptr */) {
+char *r = q;
+*r++ = '"';
+json_char ch;
+for (i = 0; i < n; i++, p++) {
+  ch = json_encode_char(*p);
+  for (size_t j = 0; j < ch.len; j++)
+*r++ = ch.buf[j];
+}
+*r++ = '"';
+  }
+  else
+return strdup("\"\""); // so it can be free()d
+  return q;
+}
+
+// Dump symbol in JSON representation to standard error stream.
+void symbol::json_dump() const
+{
+  const char *repr = this->json_extract();
+  size_t jsonlen = this->json_length();
+  // Write it out by character to keep libc string functions from
+  // interpreting escape sequences.
+  for (size_t i = 0; i < jsonlen; i++)
+fputc(repr[i], stderr);
+  free(const_cast(repr));
+}
+
 symbol default_symbol("default");
 
 // Local Variables:

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 07/61: [doc,man]: Clarify `pcomposite` request behavior.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit bfb48acfe515ce0e4af6b351f34ca5b0f92292e2
Author: G. Branden Robinson 
AuthorDate: Fri Mar 14 20:34:55 2025 -0500

[doc,man]: Clarify `pcomposite` request behavior.

Sync language and line breaks between our Texinfo manual and groff(7)
and groff_diff(7) man pages.
---
 doc/groff.texi.in| 9 ++---
 man/groff.7.man  | 6 +-
 man/groff_diff.7.man | 6 +-
 3 files changed, 16 insertions(+), 5 deletions(-)

diff --git a/doc/groff.texi.in b/doc/groff.texi.in
index 89a83241e..d81057196 100644
--- a/doc/groff.texi.in
+++ b/doc/groff.texi.in
@@ -17662,9 +17662,12 @@ immutable and their details unknown to the formatter.
 @cindex defined composite characters, dumping (@code{pcomposite})
 @cindex composite characters, defined, dumping (@code{pcomposite})
 @cindex characters, composite, dumping defined (@code{pcomposite})
-Report, to the standard error stream, the list of defined composite
-characters.  The ``from'' code point is listed first, followed by its
-``to'' mapping.
+Report,
+to the standard error stream,
+the list of defined composite character mappings.
+Recall the @code{composite} request description in @ref{Using Symbols}.
+The ``from'' code point is listed first,
+followed by its ``to'' mapping.
 @endDefreq
 
 @Defreq {pev, }
diff --git a/man/groff.7.man b/man/groff.7.man
index 7aa77de78..49976a1de 100644
--- a/man/groff.7.man
+++ b/man/groff.7.man
@@ -4120,7 +4120,11 @@ and channel value assignments of each color
 .REQ .pcomposite
 Report,
 to the standard error stream,
-the list of defined composite characters.
+the list of defined composite character mappings.
+.
+See the
+.RB \%\[lq] composite \[rq]
+request.
 .
 The \[lq]from\[rq] code point is listed first,
 followed by its \[lq]to\[rq] mapping.
diff --git a/man/groff_diff.7.man b/man/groff_diff.7.man
index 8e806822a..839083071 100644
--- a/man/groff_diff.7.man
+++ b/man/groff_diff.7.man
@@ -3376,7 +3376,11 @@ formatter.
 .B .pcomposite
 Report,
 to the standard error stream,
-the list of defined composite characters.
+the list of defined composite character mappings.
+.
+See the
+.RB \%\[lq] composite \[rq]
+request in section \[lq]New requests\[rq] above.
 .
 The \[lq]from\[rq] code point is listed first,
 followed by its \[lq]to\[rq] mapping.

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 03/61: [doc,man]: Clarify .nn line numbering supression.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 2251bc16288fd2ecf314a465a55732ba901cdace
Author: G. Branden Robinson 
AuthorDate: Fri Mar 14 20:14:36 2025 -0500

[doc,man]: Clarify .nn line numbering supression.
---
 doc/groff.texi.in | 8 +---
 man/groff.7.man   | 5 +++--
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/doc/groff.texi.in b/doc/groff.texi.in
index f8fb2719f..65a0f19ac 100644
--- a/doc/groff.texi.in
+++ b/doc/groff.texi.in
@@ -17222,7 +17222,7 @@ output lines counted by the
 @code{nm}
 request.
 If
-@var{skip}=0,
+@var{skip} is@tie{}@samp{0},
 @c XXX: negative values accepted; check AT&T troff
 cancel suppression.
 The default is@tie{}1.
@@ -17234,8 +17234,10 @@ lines once
 @code{nm}
 enables it.
 
-The @code{.nn} register stores the count of output lines still to have
-their numbering suppressed.
+The @code{.nn} register stores the
+count of lines @c in the environment
+for which numbering is suppressed
+while output line numbering is enabled.
 
 This count is associated with the environment (@pxref{Environments}).
 @endDefreq
diff --git a/man/groff.7.man b/man/groff.7.man
index c3bffc5d4..d96f7ef35 100644
--- a/man/groff.7.man
+++ b/man/groff.7.man
@@ -6807,8 +6807,9 @@ Output line numbering is enabled in the environment 
(Boolean-valued).
 .
 .TP
 .REG .nn
-Count of output lines remaining in the environment
-to have numbering suppressed.
+Count of lines in the environment
+for which numbering is suppressed
+while output line numbering is enabled.
 .
 .TP
 .REG .ns

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 15/61: [troff]: Slightly refactor.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit f15eec72facfa080a1d3044ff39b0c345df4cb0e
Author: G. Branden Robinson 
AuthorDate: Sat Mar 15 01:51:41 2025 -0500

[troff]: Slightly refactor.

* src/roff/troff/node.h: Boolify: demote some class member variables and
  member function return types from `int` to `bool`.

  (struct node, class space_node): Update `discardable()` declaration.

  (class space_node): Update `set` and `was_escape_colon` declarations.

  (class suppress_node): Update `emit_limits` declaration.

* src/roff/troff/node.cpp (space_node::space_node): Use Boolean instead
  of integer literal in `was_escape_colon` initializer.

  (space_node::spread_space, space_node::freeze_space)
  (space_node::is_escape_colon): Use Boolean instead of integer literals
  when assigning to `bool` member variables.

  (node::discardable, space_node::discardable): Update return type.

  (space_node::discardable): Simplify expression.
---
 ChangeLog   | 20 
 src/roff/troff/node.cpp | 18 +-
 src/roff/troff/node.h   | 10 +-
 3 files changed, 34 insertions(+), 14 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 726eecd5a..c8fabbf95 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,23 @@
+2025-03-15  G. Branden Robinson 
+
+   [troff]: Slightly refactor.
+
+   * src/roff/troff/node.h: Boolify: demote some class member
+   variables and member function return types from `int` to `bool`.
+   (struct node, class space_node): Update `discardable()`
+   declaration.
+   (class space_node): Update `set` and `was_escape_colon`
+   declarations.
+   (class suppress_node): Update `emit_limits` declaration.
+   * src/roff/troff/node.cpp (space_node::space_node): Use Boolean
+   instead of integer literal in `was_escape_colon` initializer.
+   (space_node::spread_space, space_node::freeze_space)
+   (space_node::is_escape_colon): Use Boolean instead of integer
+   literals when assigning to `bool` member variables.
+   (node::discardable, space_node::discardable): Update return
+   type.
+   (space_node::discardable): Simplify expression.
+
 2025-03-15  G. Branden Robinson 
 
[troff]: Trivially refactor.
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 0c5c6ff80..547b23953 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -3257,7 +3257,7 @@ bool node::did_space_merge(hunits, hunits, hunits)
 
 
 space_node::space_node(hunits nn, color *c, node *p)
-: node(p, 0 /* nullptr */, 0), n(nn), set('\0'), was_escape_colon(0),
+: node(p, 0 /* nullptr */, 0), n(nn), set('\0'), was_escape_colon(false),
   col(c)
 {
 }
@@ -3323,7 +3323,7 @@ void space_node::spread_space(int *n_spaces, hunits 
*desired_space)
   n += extra;
 }
 *n_spaces -= 1;
-set = 1;
+set = true;
   }
 }
 
@@ -,7 +,7 @@ void node::freeze_space()
 
 void space_node::freeze_space()
 {
-  set = 1;
+  set = true;
 }
 
 void node::is_escape_colon()
@@ -3342,7 +3342,7 @@ void node::is_escape_colon()
 
 void space_node::is_escape_colon()
 {
-  was_escape_colon = 1;
+  was_escape_colon = true;
 }
 
 diverted_space_node::diverted_space_node(vunits d, statem *s,
@@ -3428,14 +3428,14 @@ int node::overlaps_vertically()
   return 0;
 }
 
-int node::discardable()
+bool node::discardable()
 {
-  return 0;
+  return false;
 }
 
-int space_node::discardable()
+bool space_node::discardable()
 {
-  return set ? 0 : 1;
+  return !set;
 }
 
 vunits node::vertical_width()
@@ -4028,7 +4028,7 @@ suppress_node::suppress_node(int on_or_off, int 
issue_limits)
 
 suppress_node::suppress_node(symbol f, char p, int id)
 : node(0 /* nullptr */, 0 /* nullptr */, 0, true), is_on(2),
-  emit_limits(0), filename(f), position(p), image_id(id)
+  emit_limits(false), filename(f), position(p), image_id(id)
 {
 }
 
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 8a08811a9..d503c2e0e 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -88,7 +88,7 @@ struct node {
   virtual hyphen_list *get_hyphen_list(hyphen_list *, int *);
   virtual void ascii_print(ascii_output_file *);
   virtual void asciify(macro *);
-  virtual int discardable();
+  virtual bool discardable();
   virtual void spread_space(int *, hunits *);
   virtual void freeze_space();
   virtual void is_escape_colon();
@@ -192,8 +192,8 @@ class space_node : public node {
 private:
 protected:
   hunits n;
-  char set;
-  char was_escape_colon;
+  bool set;
+  bool was_escape_colon;
   color *col;  /* for grotty */
   space_node(hunits, int, int, color *, statem *, int,
 node * = 0 /* nullptr */);
@@ -202,7 +202,7 @@ public:
   node *copy();
   int nspaces();
   hunits width();
-  int discardable();
+  bool discardable();
   bool did_space_merge(hunits, hunits, hunits);
   void freeze_spa

[groff] 08/61: [doc,man]: Clarify `ab` request behavior.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 09d6c1fbde4224b2da4e35bb654ce4172037893c
Author: G. Branden Robinson 
AuthorDate: Fri Mar 14 20:38:51 2025 -0500

[doc,man]: Clarify `ab` request behavior.

Use a metasyntactic variable name that we don't, elsewhere in document,
associate with `ds`-style argument handling.  (`ab` doesn't strip a
leading `"` from its argument before writing it out.)

Sync language and line breaks between our Texinfo manual and groff(7)
and groff_diff(7) man pages.
---
 doc/groff.texi.in | 14 ++
 man/groff.7.man   |  4 ++--
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/doc/groff.texi.in b/doc/groff.texi.in
index d81057196..062b424fc 100644
--- a/doc/groff.texi.in
+++ b/doc/groff.texi.in
@@ -17603,11 +17603,17 @@ allowing leading embedded spaces.
 but does not append a newline.
 @endDefreq
 
-@Defreq {ab, [@Var{message}]}
+@Defreq {ab, [@Var{terminal-message}]}
 @cindex abort (@code{ab})
-Write any @var{message} to the standard error stream (like @code{tm})
-and then abort GNU @code{troff}; that is, stop processing and terminate
-with a failure status.
+Write any
+@var{terminal-message}
+to the standard error stream
+(like
+@code{tm})
+and then abort GNU
+@command{troff}; @c GNU
+that is,
+stop processing and terminate with a failure status.
 @endDefreq
 
 @Defreq {ex, }
diff --git a/man/groff.7.man b/man/groff.7.man
index 49976a1de..fa1d38942 100644
--- a/man/groff.7.man
+++ b/man/groff.7.man
@@ -2500,10 +2500,10 @@ Abort processing;
 exit with failure status.
 .
 .TPx
-.REQ .ab message
+.REQ .ab terminal-message
 Abort processing;
 write
-.I message
+.I terminal-message
 to the standard error stream and exit with failure status.
 .
 .TPx

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 02/61: ChangeLog: Add bug-closer to entry.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit d70caf462849f9dd092088e034a263c87a25f5ec
Author: G. Branden Robinson 
AuthorDate: Fri Mar 14 20:10:49 2025 -0500

ChangeLog: Add bug-closer to entry.

Tweak format of another, to try to ensure reliable pattern matching.
---
 ChangeLog | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 50f30c000..3f526ba2b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -8,7 +8,7 @@
 
* tmac/pdf.tmac: Do it.
 
-   Fixes bug 
+   Fixes .
 
 2025-03-13  Deri James  
 
@@ -20,6 +20,8 @@
* src/devices/gropdf/gropdf.pl: No scaling if BOTH width and
height are not given.
 
+   Fixes .
+
 2025-03-05  G. Branden Robinson 
 
[troff]: Add unit tests for `devicem` request and `\Y` escape

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 56/61: [troff]: Implement recursive node dumping (8h/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit b8f941ebc44897a6ef798eb20b1d01abf81f6816
Author: G. Branden Robinson 
AuthorDate: Sat Mar 15 14:49:13 2025 -0500

[troff]: Implement recursive node dumping (8h/9).

Derive class `bracket_node` from struct `container_node`.

* src/roff/troff/node.h (class bracket_node): Do it.  Drop
  pointer-to-node member variable and declaration of destructor.

* src/roff/troff/node.cpp (bracket_node::bracket_node): Migrate
  constructors to use new base class.

  (bracket_node::~bracket_node): Drop; our base class handles
  destruction of contained node(s).

Changes `pline` request output as follows.

-{"type": "bracket_node", "diversion level": 0, "is_special_node": false, 
"max_width": 5640},
+{"type": "bracket_node", "diversion level": 0, "is_special_node": false, 
"max_width": 5640, "contents": [{"type": "glyph_node", "diversion level": 0, 
"is_special_node": false, "character": "+"}, {"type": "glyph_node", "diversion 
level": 0, "is_special_node": false, "character": "|"}, {"type": "glyph_node", 
"diversion level": 0, "is_special_node": false, "character": "+"}]},
---
 ChangeLog   | 12 
 src/roff/troff/node.cpp | 10 ++
 src/roff/troff/node.h   |  5 +
 3 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index a4ced42df..f1bcf224a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2025-03-15  G. Branden Robinson 
+
+   [troff]: Derive class `bracket_node` from struct
+   `container_node`.
+
+   * src/roff/troff/node.h (class bracket_node): Do it.  Drop
+   pointer-to-node member variable and declaration of destructor.
+   * src/roff/troff/node.cpp (bracket_node::bracket_node): Migrate
+   constructors to use new base class.
+   (bracket_node::~bracket_node): Drop; our base class handles
+   destruction of contained node(s).
+
 2025-03-15  G. Branden Robinson 
 
[troff]: Derive class `overstrike_node` from struct
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 3d485efeb..6df4bccd5 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -3343,13 +3343,12 @@ hunits overstrike_node::width()
 }
 
 bracket_node::bracket_node()
-: nodes(0 /* nullptr */), max_width(H0)
+: container_node(0 /* nullptr */), max_width(H0)
 {
 }
 
 bracket_node::bracket_node(statem *s, int divlevel)
-: node(0 /* nullptr */, s, divlevel), nodes(0 /* nullptr */),
-  max_width(H0)
+: container_node(0 /* nullptr */, s, divlevel), max_width(H0)
 {
 }
 
@@ -3360,11 +3359,6 @@ void bracket_node::dump_properties()
   fflush(stderr);
 }
 
-bracket_node::~bracket_node()
-{
-  delete_node_list(nodes);
-}
-
 node *bracket_node::copy()
 {
   bracket_node *on = new bracket_node(state, div_nest_level);
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index a03c02a0f..3a9a92b71 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -553,14 +553,11 @@ public:
   void dump_properties();
 };
 
-// TODO: Derive from abstract class `container_node`.
-class bracket_node : public node {
-  node *nodes;
+class bracket_node : public container_node {
   hunits max_width;
 public:
   bracket_node();
   bracket_node(statem *, int);
-  ~bracket_node();
   node *copy();
   void tprint(troff_output_file *);
   void bracket(node *);// add another node to be overstruck

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 58/61: [troff]: Implement recursive node dumping (8j/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 795ca938c731373342e5cd3334761f7d4bf9b698
Author: G. Branden Robinson 
AuthorDate: Sat Mar 15 15:21:59 2025 -0500

[troff]: Implement recursive node dumping (8j/9).

* src/roff/troff/node.cpp (dbreak_node::dump_node): Refactor to use new
  `dump_properties` member function of `node` base class.

Changes `pline` request output as follows.

-{"type": "dbreak_node", "none": {"type": "glyph_node", "diversion level": 
0, "is_special_node": false, "character": "r"}, "pre": {"type": 
"kern_pair_node", "diversion level": 0, "is_special_node": false, "amount": 
-200}, "diversion level": 0, "is_special_node": false},
+{"type": "dbreak_node", "diversion level": 0, "is_special_node": false, 
"none": {"type": "glyph_node", "diversion level": 0, "is_special_node": false, 
"character": "r"}, "pre": {"type": "kern_pair_node", "diversion level": 0, 
"is_special_node": false, "amount": -200}},

(Properties of the object of the base class are reported before those of
the derived class.)
---
 ChangeLog   |  5 +
 src/roff/troff/node.cpp | 19 ++-
 2 files changed, 11 insertions(+), 13 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 68b2d7627..c18ed59fe 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2025-03-15  G. Branden Robinson 
+
+   * src/roff/troff/node.cpp (dbreak_node::dump_node): Refactor to
+   use new `dump_properties` member function of `node` base class.
+
 2025-03-15  G. Branden Robinson 
 
* src/roff/troff/node.cpp (class ligature_node): Add `dump_node`
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index c82b02517..d0448d671 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -6169,7 +6169,11 @@ bool dbreak_node::is_tag()
 
 void dbreak_node::dump_node()
 {
-  fprintf(stderr, "{\"type\": \"%s\"", type());
+  fputc('{', stderr);
+  // Flush so that in case something goes wrong with property dumping,
+  // we know that we traversed to a new node.
+  fflush(stderr);
+  node::dump_properties();
   if (none != 0 /* nullptr */) {
 fputs(", \"none\": ", stderr);
 none->dump_node();
@@ -6182,18 +6186,7 @@ void dbreak_node::dump_node()
 fputs(", \"post\": ", stderr);
 post->dump_node();
   }
-  fprintf(stderr, ", \"diversion level\": %d", div_nest_level);
-  fprintf(stderr, ", \"is_special_node\": %s",
- is_special ? "true" : "false");
-  if (push_state) {
-fputs(", \"push_state\": ", stderr);
-push_state->display_state();
-  }
-  if (state) {
-fputs(", \"state\": ", stderr);
-state->display_state();
-  }
-  fputs("}", stderr);
+  fputc('}', stderr);
   fflush(stderr);
 }
 

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 43/61: [troff]: Implement recursive node dumping (5r/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit a38381dc75bfd082592334fd708c33c7ec92f2b7
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 09:05:25 2025 -0600

[troff]: Implement recursive node dumping (5r/9).

* src/roff/troff/node.h (class kern_pair_node): Specialize (override)
  `dump_properties()` for this class.

* src/roff/troff/node.cpp (kern_pair_node::dump_properties): New member
  function reports value of `amount` property.

Changes `pline` request output as follows.

-{"type": "dbreak_node", "none": {"type": "glyph_node", "diversion level": 
0, "is_special_node": false, "character": "r"}, "pre": {"type": 
"kern_pair_node", "diversion level": 0, "is_special_node": false}, "diversion 
level": 0, "is_special_node": false},
+{"type": "dbreak_node", "none": {"type": "glyph_node", "diversion level": 
0, "is_special_node": false, "character": "r"}, "pre": {"type": 
"kern_pair_node", "diversion level": 0, "is_special_node": false, "amount": 
-200}, "diversion level": 0, "is_special_node": false},
-{"type": "kern_pair_node", "diversion level": 0, "is_special_node": false},
+{"type": "kern_pair_node", "diversion level": 0, "is_special_node": false, 
"amount": -100},
---
 ChangeLog   | 7 +++
 src/roff/troff/node.cpp | 8 
 2 files changed, 15 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index fd9398e2c..b1f9b11e4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2025-03-03  G. Branden Robinson 
+
+   * src/roff/troff/node.h (class kern_pair_node): Specialize
+   {override} `dump_properties()` for this class.
+   * src/roff/troff/node.cpp (kern_pair_node::dump_properties): New
+   member function reports value of `amount` property.
+
 2025-03-03  G. Branden Robinson 
 
* src/roff/troff/node.h (class tag_node): Specialize (override)
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 423fb69e0..3abb6b0aa 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -2014,6 +2014,7 @@ public:
   bool causes_tprint();
   bool is_tag();
   void vertical_extent(vunits *, vunits *);
+  void dump_properties();
 };
 
 class dbreak_node : public node {
@@ -2298,6 +2299,13 @@ kern_pair_node::kern_pair_node(hunits n, node *first, 
node *second,
 {
 }
 
+void kern_pair_node::dump_properties()
+{
+  node::dump_properties();
+  fprintf(stderr, ", \"amount\": %d", amount.to_units());
+  fflush(stderr);
+}
+
 dbreak_node::dbreak_node(node *n, node *p, statem *s, int divlevel,
 node *x)
 : node(x, s, divlevel), none(n), pre(p), post(0 /* nullptr */)

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 14/61: [troff]: Trivially refactor.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 6a82162c00b8f355186ced62d6c725a9d240f920
Author: G. Branden Robinson 
AuthorDate: Sat Mar 15 01:15:57 2025 -0500

[troff]: Trivially refactor.

* src/roff/troff/node.cpp:
* src/roff/troff/node.h: Rename all `ch`, `n` and `list` member
  variables of node classes to `nodes` to later enable insertion of a
  `container_node` abstract class into the inheritance structure.  This
  change throws more light on a pitfall of GNU troff's class design;
  some node classes can contain other nodes by using pointers to
  `node`s, but this is done without recourse to any C++ language
  features to indicate whether such pointers are expected to be single
  elements or lists.  (Compounding the ambiguity is that `node` is
  inherently set up for use as a member of a doubly-linked list.)  Thus,
  this renaming unfortunately removes some information about class
  design intentions.  On the other hand, since only programmer knowledge
  and discipline were enforcing the singleton/list distinction already,
  the member variable names were _only_ documentary.  In the future, we
  might want to enhance some of these classes to enforce their
  containment of singleton nodes only.

* src/roff/troff/node.cpp (hline_node::copy, vline_node::copy)
  (vline_node::width, left_italic_corrected_node::width)
  (left_italic_corrected_node::skew)
  (left_italic_corrected_node::subscript_correction)
  (left_italic_corrected_node::italic_correction)
  (left_italic_corrected_node::ends_sentence)
  (left_italic_corrected_node::overlaps_horizontally)
  (left_italic_corrected_node::overlaps_vertically)
  (left_italic_corrected_node::last_char_node)
  (left_italic_corrected_node::get_tfont)
  (italic_corrected_node::skew, glyph_node::tprint)
  (glyph_node::zero_width_tprint, hline_node::tprint): Parenthesize
  (formally) complex expressions.

  (bracket_node::copy hline_node::copy, vline_node::copy)
  (reverse_node_list)
  (left_italic_corrected_node::asciify)
  (left_italic_corrected_node::copy)
  (left_italic_corrected_node::tprint)
  (left_italic_corrected_node::ascii_print)
  (left_italic_corrected_node::vertical_extent)
  (left_italic_corrected_node::get_hyphenation_type)
  (left_italic_corrected_node::add_self)
  (left_italic_corrected_node::width): Explicitly compare variable of
  pointer type to null pointer literal instead of letting it pun down to
  a Boolean.

  (glyph_node::asciify): Compare local variable of `char` type to
  character rather than integer literal.

  (overstrike_node::add_self): Rename parameter from `nodes` to
  `more_nodes`, since the former now collides with a class member
  variable.

  (space_node::space_node): Initialize member variable of `char`
  type with character rather than integer literal.
---
 ChangeLog   |  54 +++
 src/roff/troff/node.cpp | 383 +---
 src/roff/troff/node.h   |  14 +-
 3 files changed, 261 insertions(+), 190 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 9ab7041a4..726eecd5a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,57 @@
+2025-03-15  G. Branden Robinson 
+
+   [troff]: Trivially refactor.
+
+   * src/roff/troff/node.cpp:
+   * src/roff/troff/node.h: Rename all `ch`, `n` and `list` member
+   variables of node classes to `nodes` to later enable insertion
+   of a `container_node` abstract class into the inheritance
+   structure.  This change throws more light on a pitfall of GNU
+   troff's class design; some node classes can contain other nodes
+   by using pointers to `node`s, but this is done without recourse
+   to any C++ language features to indicate whether such pointers
+   are expected to be single elements or lists.  (Compounding the
+   ambiguity is that `node` is inherently set up for use as a
+   member of a doubly-linked list.)  Thus, this renaming
+   unfortunately removes some information about class design
+   intentions.  On the other hand, since only programmer knowledge
+   and discipline were enforcing the singleton/list distinction
+   already, the member variable names were _only_ documentary.  In
+   the future, we might want to enhance some of these classes to
+   enforce their containment of singleton nodes only.
+   * src/roff/troff/node.cpp (hline_node::copy, vline_node::copy)
+   (vline_node::width, left_italic_corrected_node::width)
+   (left_italic_corrected_node::skew)
+   (left_italic_corrected_node::subscript_correction)
+   (left_italic_corrected_node::italic_correction)
+   (left_italic_corrected_node::ends_sentence)
+   (left_italic_corrected_node::overlaps_horizontally)
+   (left_italic_corre

[groff] 04/61: [doc,man]: Fix imprecise troff-historical claim.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit efd62f25d749e46e58c703944352e3e924131939
Author: G. Branden Robinson 
AuthorDate: Fri Mar 14 20:21:26 2025 -0500

[doc,man]: Fix imprecise troff-historical claim.

...and annotate it.
---
 doc/groff.texi.in| 11 +--
 man/groff_diff.7.man |  9 -
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/doc/groff.texi.in b/doc/groff.texi.in
index 65a0f19ac..dde7e6528 100644
--- a/doc/groff.texi.in
+++ b/doc/groff.texi.in
@@ -18576,8 +18576,15 @@ the character escape @code{\(rs} or @code{\[rs]}, for 
``reverse
 solidus'', from its name in the @acronym{ECMA}-6 and @w{ISO 10646}
 standards.@footnote{The @code{rs} special character identifier was not
 defined in @acronym{AT&T} @code{troff}'s font description files, but is
-in those of its lineal descendant, Heirloom Doctools @code{troff}, as of
-the latter's 060716 release (July 2006).}
+in those of its descendant Heirloom Doctools @code{troff}, as of the
+latter's 060716 release (July 2006).}
+@c The foregoing once said "lineal" descendant; that appears not to be
+@c true.  Heirloom Doctools troff is based on Open Solaris troff, which
+@c descends from DWB 2.0 troff (effectively a fork).  "Lineal"
+@c descendants of DWB 2.0 troff would be DWB 3.3 and, possibly, Plan 9
+@c troff.  (The accuracy of this last claim depends on the degree of
+@c resemblance between Research Unix troff--the version maintained by
+@c Kernighan--and DWB troff, of which 3.4 was the final release.)
 
 To store an escape sequence in a diversion that is interpreted when the
 diversion is interpolated, either use the traditional @code{\!}
diff --git a/man/groff_diff.7.man b/man/groff_diff.7.man
index 7bb79f3a3..644fbb259 100644
--- a/man/groff_diff.7.man
+++ b/man/groff_diff.7.man
@@ -6372,10 +6372,17 @@ from its name in the ECMA-6 (ISO/IEC\~646) standard.
 .
 [This escape sequence is not portable to AT&T
 .IR troff , \" AT&T
-but is to its lineal descendant,
+but is to its descendant
 Heirloom Doctools
 .IR troff ,
 as of its 060716 release (July 2006).]
+.\" The foregoing once said "lineal" descendant; that appears not to be
+.\" true.  Heirloom Doctools troff is based on Open Solaris troff, which
+.\" descends from DWB 2.0 troff (effectively a fork).  "Lineal"
+.\" descendants of DWB 2.0 troff would be DWB 3.3 and, possibly, Plan 9
+.\" troff.  (The accuracy of this last claim depends on the degree of
+.\" resemblance between Research Unix troff--the version maintained by
+.\" Kernighan--and DWB troff, of which 3.4 was the final release.)
 .
 .
 .P

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 05/61: [doc,man]: Clarify AT&T/GNU adjustment behavior.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 6bd649ad63ffe9d0dadd34328ca7f88619d68806
Author: G. Branden Robinson 
AuthorDate: Fri Mar 14 20:26:25 2025 -0500

[doc,man]: Clarify AT&T/GNU adjustment behavior.

Sync language and line breaks between our Texinfo manual and
groff_diff(7) man page.
---
 doc/groff.texi.in| 16 +++-
 man/groff_diff.7.man |  8 +---
 2 files changed, 16 insertions(+), 8 deletions(-)

diff --git a/doc/groff.texi.in b/doc/groff.texi.in
index dde7e6528..aaf307797 100644
--- a/doc/groff.texi.in
+++ b/doc/groff.texi.in
@@ -18363,11 +18363,17 @@ dummy character escape sequence @code{\&} is more 
portable.
 
 @cindex adjustment to both margins, difference from @acronym{AT&T} @code{troff}
 @cindex rivers
-When adjusting to both margins, @acronym{AT&T} @code{troff} at first
-adjusts spaces starting from the right; GNU @code{troff} begins from
-the left.  Both implementations adjust spaces from opposite ends on
-alternating output lines in this adjustment mode to prevent ``rivers''
-in the text.
+When adjusting output lines to both margins,
+@acronym{AT&T}
+@command{troff} @c AT&T
+at first adjusts spaces starting from the right;
+GNU
+@command{troff} @c GNU
+begins from the left.
+Both implementations adjust spaces
+from opposite ends on alternating output lines
+in this adjustment mode
+to prevent ``rivers'' in the text.
 
 @cindex hyphenation, incompatibilities with @acronym{AT&T} @code{troff}
 GNU @command{troff} does not always hyphenate words as @acronym{AT&T}
diff --git a/man/groff_diff.7.man b/man/groff_diff.7.man
index 644fbb259..a9b9fec24 100644
--- a/man/groff_diff.7.man
+++ b/man/groff_diff.7.man
@@ -5919,7 +5919,7 @@ is more portable.
 .
 .
 .P
-When adjusting to both margins,
+When adjusting output lines to both margins,
 AT&T
 .I troff \" AT&T
 at first adjusts spaces starting from the right;
@@ -5927,8 +5927,10 @@ GNU
 .I troff \" GNU
 begins from the left.
 .
-Both implementations adjust spaces from opposite ends on alternating
-output lines to prevent \[lq]rivers\[rq] in the text.
+Both implementations adjust spaces
+from opposite ends on alternating output lines
+in this adjustment mode
+to prevent \[lq]rivers\[rq] in the text.
 .
 .
 .P

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 16/61: [libgroff]: Rationalize header file inclusions.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 1679a4a46c1bda32196299c53ccac3b4401aaf68
Author: G. Branden Robinson 
AuthorDate: Thu Mar 13 22:38:52 2025 -0500

[libgroff]: Rationalize header file inclusions.

* src/libs/libgroff/string.cpp: Include assert.h and string.h.  Annotate
  why.

Also stop cramming casts of return values up against the adjacent
expression.
---
 ChangeLog| 7 +++
 src/libs/libgroff/symbol.cpp | 5 -
 2 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index c8fabbf95..516628973 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2025-03-10  G. Branden Robinson 
+
+   Further rationalize header file inclusions.
+
+   * src/libs/libgroff/string.cpp: Include assert.h and string.h.
+   Annotate why.
+
 2025-03-15  G. Branden Robinson 
 
[troff]: Slightly refactor.
diff --git a/src/libs/libgroff/symbol.cpp b/src/libs/libgroff/symbol.cpp
index a550d8158..7bc8a8f4c 100644
--- a/src/libs/libgroff/symbol.cpp
+++ b/src/libs/libgroff/symbol.cpp
@@ -20,6 +20,9 @@ along with this program.  If not, see 
. */
 #include 
 #endif
 
+#include 
+#include  // strcat(), strcmp(), strcpy(), strlen()
+
 #include "lib.h"
 
 #include "errarg.h"
@@ -140,7 +143,7 @@ symbol::symbol(const char *p, int how)
   block_size = len > BLOCK_SIZE ? len : BLOCK_SIZE;
   block = new char [block_size];
 }
-(void)strcpy(block, p);
+(void) strcpy(block, p);
 s = *pp = block;
 block += len;
 block_size -= len;

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 09/61: [doc,man]: Clarify `.devicem` and `\Y` behavior.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 76bb52ceb8783819153a28c7d04c7476f5494dc7
Author: G. Branden Robinson 
AuthorDate: Fri Mar 14 20:54:07 2025 -0500

[doc,man]: Clarify `.devicem` and `\Y` behavior.

Sync language and line breaks between our Texinfo manual and groff(7)
and groff_diff(7) man pages.
---
 doc/groff.texi.in| 42 +++---
 man/groff.7.man  | 36 
 man/groff_diff.7.man | 22 --
 3 files changed, 63 insertions(+), 37 deletions(-)

diff --git a/doc/groff.texi.in b/doc/groff.texi.in
index 062b424fc..8e3fcd455 100644
--- a/doc/groff.texi.in
+++ b/doc/groff.texi.in
@@ -17107,23 +17107,43 @@ these produce warnings in category @samp{char}.
 
 GNU
 @command{troff}
-also permits the interpolation of macro contents
+also permits the interpolation of macro or string contents
 as a device extension command.
 
 @DefreqList {devicem, name}
 @DefescItemx {\\Y, , n, }
 @DefescItem {\\Y, (, nm, }
 @DefescListEnd {\\Y, [, name, ]}
-The @code{devicem} request and @code{\Y} escape sequence are each
-approximately equivalent to @samp{\X'\*[@var{name}]'} (one-character
-name@tie{}@var{n}, two-character name @var{nm}).  They differ from that
-construction in that the contents of the string or macro @var{name} are
-not interpreted; further, @var{name} may be a macro and thus contain
-newlines.  (There is no way to embed a newline in the arguments to
-@code{device} or @code{\X}.)  The inclusion of newlines requires an
-extension to the @acronym{AT&T} @command{troff} device-independen page
-description language; their presence confuses drivers that do not know
-about it (@pxref{Device Control Commands}).
+The
+@code{devicem}
+request and
+@code{\Y}
+escape sequence correspond to
+@samp{.device \*[@var{name}]}
+and
+@samp{\X'\*[@var{name}]'}
+(one-character
+name@tie{}@var{n},
+two-character name
+@var{nm}),
+respectively.
+They differ from their counterparts
+in that GNU
+@command{troff} @c GNU
+does not interpret the contents of the string or macro
+@var{name};
+further,
+@var{name}
+may be a macro and thus contain newlines.
+(There is no way to embed a newline in the arguments to
+@code{device}
+or
+@code{\X}.)
+The inclusion of newlines requires an extension to the @acronym{AT&T}
+@command{troff} @c AT&T
+device-independent page description language,
+and their presence confuses drivers that do not know about it
+(@pxref{Device Control Commands}).
 @endDefesc
 
 @DefreqList {tag, name}
diff --git a/man/groff.7.man b/man/groff.7.man
index fa1d38942..2eb25c7fc 100644
--- a/man/groff.7.man
+++ b/man/groff.7.man
@@ -8499,37 +8499,41 @@ or other postprocessor.
 .P
 GNU
 .I troff \" GNU
-also permits the interpolation of macro contents as a device extension
-command.
+also permits the interpolation of macro or string contents
+as a device extension command.
 .
 The
 .B devicem
-request
-and
+request and
 .B \[rs]Y
-escape sequence are each approximately equivalent to
-.RB \[lq] \[rs]X\[aq]\c
-.IB name \[aq]\c
-\[rq].
+escape sequence correspond to
+.RB \[lq] ".device \[rs]*[\c"
+.IB name ]\c
+\[rq]
+and
+.RB \[lq] \[rs]X\[aq]\[rs]*[\c
+.IB name ]\c
+\[rq],
+respectively.
 .
-They differ from that construction in that the contents of the string or
-macro
-.I name
-are not interpreted;
+They differ from their counterparts
+in that GNU
+.I troff \" GNU
+does not interpret the contents of the string or macro
+.IR name ;
 further,
 .I name
 may be a macro and thus contain newlines.
 .
-(There is no way to embed a newline
-in the arguments to
+(There is no way to embed a newline in the arguments to
 .RB \[lq] device \[rq]
 or
 .BR \[rs]X .)
 .
 The inclusion of newlines requires an extension to the AT&T
 .I troff \" AT&T
-device-independent page description language;
-their presence confuses drivers that do not know about it
+device-independent page description language,
+and their presence confuses drivers that do not know about it
 (see subsection \[lq]Device control commands\[rq] of
 .MR groff_out @MAN5EXT@ ).
 .
diff --git a/man/groff_diff.7.man b/man/groff_diff.7.man
index 839083071..fd0020a63 100644
--- a/man/groff_diff.7.man
+++ b/man/groff_diff.7.man
@@ -1252,25 +1252,27 @@ and so on.
 .BI \[rs]Y( ma
 .TQ
 .BI \[rs]Y[ mac ]
-Interpolate a macro as a device extension command.
+Interpolate a macro or string as a device extension command.
 .
 As
 .BI \[rs]X\[aq]\[rs]*[ mac ]\[aq]\c
 ,
-except the contents of
-.I mac
-are not interpreted,
-and
+except that GNU
+.I troff \" GNU
+does not interpret the contents of
+.IR mac ;
+further,
 .I mac
 can be a macro and thus contain newlines,
-whereas the argument to
-.B \[rs]X
-cannot.
+unlike the argument to
+.B \[rs]X .
 .
 This inclusion of newlines requires an extension to the AT&T
 .I troff \" AT&T
-page description language,
-and confuses postprocessors that do not know about it.
+device-independent page description language,
+and thei

[groff] 18/61: [libgroff]: Support object dumping in JSON (2/3).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit c9c316578963a07995bb6cf6a8e00d7aa7a2efed
Author: G. Branden Robinson 
AuthorDate: Tue Mar 4 03:27:09 2025 -0600

[libgroff]: Support object dumping in JSON (2/3).

Support JSON dumping of `string`s.

Add `json_length()`, `json_extract()`, and `json_dump()` public member
functions to `string` class.  The enhanced node printing feature will
require them.

* src/include/stringclass.h (class string): Declare them.

* src/libs/libgroff/string.cpp (string::json_length):
  (string::json_extract, string::json_dump): Implement them.
---
 ChangeLog| 10 ++
 src/include/stringclass.h|  5 ++-
 src/libs/libgroff/string.cpp | 86 +---
 3 files changed, 95 insertions(+), 6 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 3225d05ea..5480dee2a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2025-03-04  G. Branden Robinson 
+
+   [libgroff]: Add `json_length()`, `json_extract()`, and
+   `json_dump()` public member functions to `string` class.  The
+   enhanced node printing feature will require them.
+
+   * src/include/stringclass.h (class string): Declare them.
+   * src/libs/libgroff/string.cpp (string::json_length):
+   (string::json_extract, string::json_dump): Implement them.
+
 2025-03-15  G. Branden Robinson 
 
[libgroff]: Support dumping of some object types in JSON format.
diff --git a/src/include/stringclass.h b/src/include/stringclass.h
index 445b44152..11cc56d7b 100644
--- a/src/include/stringclass.h
+++ b/src/include/stringclass.h
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2024 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2025 Free Software Foundation, Inc.
  Written by James Clark (j...@jclark.com)
 
 This file is part of groff.
@@ -69,6 +69,9 @@ public:
   int search(const char) const;
   int find(const char *) const;
   char *extract() const;
+  size_t json_length() const;
+  const char *json_extract() const;
+  void json_dump() const;
   void remove_spaces();
   void clear();
   void move(string &);
diff --git a/src/libs/libgroff/string.cpp b/src/libs/libgroff/string.cpp
index c8d759528..739fdfe05 100644
--- a/src/libs/libgroff/string.cpp
+++ b/src/libs/libgroff/string.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2024 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2025 Free Software Foundation, Inc.
  Written by James Clark (j...@jclark.com)
 
 This file is part of groff.
@@ -21,11 +21,13 @@ along with this program.  If not, see 
. */
 #endif
 
 #include  // FILE, putc(), sprintf()
-#include  // malloc()
+#include  // calloc()
 #include  // memchr(), memcmp(), memcpy(), memmem(), memset(),
// strlen(), size_t
 
+#include "cset.h" // csprint()
 #include "lib.h"
+#include "json-encode.h" // json_encode_char()
 
 #include "stringclass.h"
 
@@ -299,8 +301,9 @@ int string::find(const char *c) const
   return (p != 0 /* nullptr */) ? (p - ptr) : -1;
 }
 
-// we silently strip nuls
-
+// Return pointer to null-terminated C string; any nulls internal to the
+// string are omitted.  The caller is responsible for `free()`ing the
+// returned storage.
 char *string::extract() const
 {
   char *p = ptr;
@@ -310,7 +313,7 @@ char *string::extract() const
   for (i = 0; i < n; i++)
 if (p[i] == '\0')
   nnuls++;
-  char *q = static_cast(malloc(n + 1 - nnuls));
+  char *q = static_cast(calloc(n + 1 - nnuls, sizeof(char)));
   if (q != 0 /* nullptr */) {
 char *r = q;
 for (i = 0; i < n; i++)
@@ -321,6 +324,79 @@ char *string::extract() const
   return q;
 }
 
+// Compute length of JSON representation of object.
+size_t string::json_length() const
+{
+  size_t n = len;
+  const char *p = ptr;
+  char ch;
+  int nextrachars = 2; // leading and trailing double quotes
+  for (size_t i = 0; i < n; i++) {
+ch = p[i];
+// Handle the most common cases first.
+if (ch < 128) {
+  if (csprint(ch))
+   ;
+  else
+   switch (ch) {
+   case '"':
+   case '\\':
+   case '/':
+   case '\b':
+   case '\f':
+   case '\n':
+   case '\r':
+   case '\t':
+ nextrachars++;
+ break;
+   default:
+ nextrachars += 5;
+  }
+}
+else
+  nextrachars += 5;
+  }
+  return (n + nextrachars);
+}
+
+// Like `extract()`, but double-quote the string and escape characters
+// per JSON and emit nulls.  This string is not null-terminated!  Caller
+// MUST use .json_length().
+const char *string::json_extract() const
+{
+  const char *p = ptr;
+  size_t n = len;
+  size_t i;
+  char *q = static_cast(calloc(this->json_length(),
+  sizeof (char)));
+  if (q != 0 /* nullptr */) {
+char *r = q;
+*r++ = '"';
+json_char ch;
+for (i = 0; i < n; i++, p++) {
+  ch = json_encode_char(*p);
+  for (siz

[groff] 21/61: [troff]: Implement recursive node dumping (1/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit ab19255d1d0f8151ba590ccf5121e816fae457a3
Author: G. Branden Robinson 
AuthorDate: Sun Mar 2 11:41:58 2025 -0600

[troff]: Implement recursive node dumping (1/9).

* src/roff/troff/node.h (struct node): Undeclare `dump_node_list()`
  virtual function.

* src/roff/troff/node.cpp (node::dump_node_list): Rename this...
  (dump_node_list): ...to this.  Instead of being a member function, it
  is now an ordinary function taking a pointer-to-node as argument.
  This is a temporary measure to keep node list dumping working.  Stop
  throwing assertion if the given node pointer is null.  Instead, we
  simply write an empty list (`[ ]`).

* src/roff/troff/env.h (class environment): Rename member function
  `dump_node_list()` to `dump_pending_nodes()`.

* src/roff/troff/env.cpp (environment::dump_node_list): Rename this...
  (environment::dump_pending_nodes): ...to this.

  (environment:add_char) [0]: Update call sites.

  (environment::dump_node_list): Rename this...
  (environment::dump_pending_nodes): ...to this.  Stop refusing to
  dump a null pointer.  Update call site as above.

This change reveals formerly hidden nodes.

Changes `pline` request output as follows.

 [{"type": "line_start_node", "diversion level": 0, "is_special_node": 
false},
 {"type": "zero_width_node", "diversion level": 0, "is_special_node": 
false},
 {"type": "glyph_node", "character": "d", "diversion level": 0, 
"is_special_node": false},
 {"type": "glyph_node", "character": "e", "diversion level": 0, 
"is_special_node": false},
-{"type": "glyph_node", "character": "f", "diversion level": 0, 
"is_special_node": false}]
+{"type": "glyph_node", "character": "f", "diversion level": 0, 
"is_special_node": false},
+{"type": "word_space_node", "diversion level": 0, "is_special_node": 
false}]
 [{"type": "line_start_node", "diversion level": 0, "is_special_node": 
false},
 {"type": "hline_node", "diversion level": 0, "is_special_node": false},
 {"type": "zero_width_node", "diversion level": 0, "is_special_node": 
false},
 {"type": "glyph_node", "character": "d", "diversion level": 0, 
"is_special_node": false, "state": ""},
 {"type": "glyph_node", "character": "e", "diversion level": 0, 
"is_special_node": false, "state": ""},
-{"type": "glyph_node", "character": "f", "diversion level": 0, 
"is_special_node": false, "state": ""}]
+{"type": "glyph_node", "character": "f", "diversion level": 0, 
"is_special_node": false, "state": ""},
+{"type": "word_space_node", "diversion level": 0, "is_special_node": 
false}]
+[ ]
 [{"type": "line_start_node", "diversion level": 0, "is_special_node": 
false},
---
 ChangeLog   | 21 +
 src/roff/troff/env.cpp  | 15 ---
 src/roff/troff/env.h|  2 +-
 src/roff/troff/node.cpp | 10 +-
 src/roff/troff/node.h   |  1 -
 5 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 74066b114..e726a2ef9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2025-03-02  G. Branden Robinson 
+
+   * src/roff/troff/node.h (struct node): Undeclare
+   `dump_node_list()` virtual function.
+   * src/roff/troff/node.cpp (node::dump_node_list): Rename this...
+   (dump_node_list): ...to this.  Instead of being a member
+   function, it is now an ordinary function taking a
+   pointer-to-node as argument.  This is a temporary measure to
+   keep node list dumping working.  Stop throwing assertion if the
+   given node pointer is null.  Instead, we simply write an empty
+   list (`[ ]`).
+   * src/roff/troff/env.h (class environment): Rename member
+   function `dump_node_list()` to `dump_pending_nodes()`.
+   * src/roff/troff/env.cpp (environment::dump_node_list): Rename
+   this...
+   (environment::dump_pending_nodes): ...to this.
+   (environment:add_char) [0]: Update call sites.
+   (environment::dump_node_list): Rename this...
+   (environment::dump_pending_nodes): ...to this.  Stop refusing to
+   dump a null pointer.  Update call site as above.
+
 2025-03-02  G. Branden Robinson 
 
[troff]: Revise `pline` output style.  Use more JSON/YAML-ish
diff --git a/src/roff/troff/env.cpp b/src/roff/troff/env.cpp
index 4abb05f56..4349bba66 100644
--- a/src/roff/troff/env.cpp
+++ b/src/roff/troff/env.cpp
@@ -351,7 +351,7 @@ void environment::add_char(charinfo *ci)
   start_line();
 #if 0
 fprintf(stderr, "current line is\n");
-line->dump_node_list();
+dump_node_list(line);
 #endif
 if (ci != hyphen_indicator_char)
   line = line->add_char(ci, this, &width_total, &space_total, &gc_np);
@@ -360,7 +360,7 @@ void environment::add_char(charinfo *ci)
   }
 #if 0
   fprintf(stderr, "now after we have added cha

[groff] 33/61: [troff]: Implement recursive node dumping (5h/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 7f88ed1d7f71e2d3266f3ecbcbc685e329ce41d1
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 02:43:05 2025 -0600

[troff]: Implement recursive node dumping (5h/9).

* src/roff/troff/node.h (class hline_node): Specialize (override)
  `dump_properties()` for this class.

* src/roff/troff/node.cpp (hline_node::dump_properties): New member
  function reports value of `hunits` property.

Changes `pline` request output as follows.

-{"type": "hline_node", "diversion level": 0, "is_special_node": false},
+{"type": "hline_node", "diversion level": 0, "is_special_node": false, 
"hunits": 144},
---
 ChangeLog   | 7 +++
 src/roff/troff/node.cpp | 7 +++
 src/roff/troff/node.h   | 2 ++
 3 files changed, 16 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index b3f20e1e4..c236c1a2d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,10 @@
+2025-03-03  G. Branden Robinson 
+
+   * src/roff/troff/node.h (class hline_node): Specialize
+   {override} `dump_properties()` for this class.
+   * src/roff/troff/node.cpp (hline_node::dump_properties): New
+   member function reports value of `hunits` property.
+
 2025-03-03  G. Branden Robinson 
 
* src/roff/troff/node.h (class vmotion_node): Specialize
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 4fc7c7559..276f73303 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -3115,6 +3115,13 @@ hline_node::hline_node(hunits i, node *c, statem *s, int 
divlevel,
 {
 }
 
+void hline_node::dump_properties()
+{
+  node::dump_properties();
+  fprintf(stderr, ", \"hunits\": %d", x.to_units());
+  fflush(stderr);
+}
+
 node *hline_node::copy()
 {
   return new hline_node(x, (nodes != 0 /* nullptr */) ? nodes->copy()
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index f3f48de3a..0a124521f 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -413,6 +413,7 @@ public:
   void dump_properties();
 };
 
+// TODO: Derive from abstract class `container_node`.
 class hline_node : public node {
   hunits x;
   node *nodes;
@@ -428,6 +429,7 @@ public:
   const char *type();
   bool causes_tprint();
   bool is_tag();
+  void dump_properties();
 };
 
 class vline_node : public node {

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 46/61: src/roff/troff/node.{h,cpp}: Annotate next steps.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 9e1b0e468eb67fb6c1d6bfa1f17bb082a77fb74b
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 09:14:15 2025 -0600

src/roff/troff/node.{h,cpp}: Annotate next steps.
---
 src/roff/troff/node.cpp | 8 
 src/roff/troff/node.h   | 1 +
 2 files changed, 9 insertions(+)

diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index e916a2bc4..baebd6d95 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -1961,6 +1961,8 @@ public:
   bool is_tag();
 };
 
+// TODO: Do not derive from `container_node`; implement custom double
+// container dumper in dump_node().
 class ligature_node : public glyph_node {
   node *n1;
   node *n2;
@@ -1987,6 +1989,8 @@ public:
   bool is_tag();
 };
 
+// TODO: Do not derive from `container_node`; implement custom double
+// container dumper in dump_node().
 class kern_pair_node : public node {
   hunits amount;
   node *n1;
@@ -2017,6 +2021,8 @@ public:
   void dump_properties();
 };
 
+// Not derived from `container_node`; implements custom triple container
+// dumper in dump_node().
 class dbreak_node : public node {
   node *none;
   node *pre;
@@ -2696,6 +2702,7 @@ hunits dbreak_node::subscript_correction()
   return none ? none->subscript_correction() : H0;
 }
 
+// TODO: Derive from abstract class `container_node`.
 class italic_corrected_node : public node {
   node *nodes;
   hunits x;
@@ -2847,6 +2854,7 @@ int italic_corrected_node::character_type()
   return nodes->character_type();
 }
 
+// TODO: Derive from abstract class `container_node`.
 class break_char_node : public node {
   node *nodes;
   char break_code;
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index e16869917..99d4f6c92 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -478,6 +478,7 @@ public:
   hyphenation_type get_hyphenation_type();
 };
 
+// TODO: Derive from abstract class `container_node`.
 class zero_width_node : public node {
   node *nodes;
 public:

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 13/61: [troff]: Improve scaling unit warning diagnostic.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 1a9af9ef8e74f2ee978b792dc63e050cf7f6c1fd
Author: G. Branden Robinson 
AuthorDate: Fri Mar 14 22:55:27 2025 -0500

[troff]: Improve scaling unit warning diagnostic.

* src/roff/troff/number.cpp (is_valid_term): When warning of an invalid
  scaling unit, report the character encountered.
---
 ChangeLog | 5 +
 src/roff/troff/number.cpp | 4 ++--
 2 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 3f526ba2b..9ab7041a4 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2025-03-14  G. Branden Robinson 
+
+   * src/roff/troff/number.cpp (is_valid_term): When warning of an
+   invalid scaling unit, report the character encountered.
+
 2025-03-14  Deri James  
 
[gropdf]: .pdfhref M fails with no -N/-D flag
diff --git a/src/roff/troff/number.cpp b/src/roff/troff/number.cpp
index f0b231cb3..c15129119 100644
--- a/src/roff/troff/number.cpp
+++ b/src/roff/troff/number.cpp
@@ -1,4 +1,4 @@
-/* Copyright (C) 1989-2024 Free Software Foundation, Inc.
+/* Copyright (C) 1989-2025 Free Software Foundation, Inc.
  Written by James Clark (j...@jclark.com)
 
 This file is part of groff.
@@ -538,7 +538,7 @@ static bool is_valid_term(units *u, int scaling_unit,
   && (strchr(SCALING_UNITS, c) != 0 /* nullptr */)) {
 switch (scaling_unit) {
 case 0:
-  warning(WARN_SCALE, "scaling unit invalid in context");
+  warning(WARN_SCALE, "scaling unit '%1' invalid in context", c);
   break;
 case 'f':
   if (c != 'f' && c != 'u') {

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 17/61: [libgroff]: Support object dumping in JSON (1/3).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit ffcca436ace531354b1e06bf5a08f51c1f15be76
Author: G. Branden Robinson 
AuthorDate: Sat Mar 15 04:26:25 2025 -0500

[libgroff]: Support object dumping in JSON (1/3).

* src/include/json-encode.h:
* src/libs/libgroff/json_encode.cpp: Add new files.

* src/libs/libgroff/libgroff.am (libgroff_a_SOURCES): Add
  "json_encode.cpp".
---
 ChangeLog | 10 +
 src/include/json-encode.h | 29 ++
 src/libs/libgroff/json_encode.cpp | 80 +++
 src/libs/libgroff/libgroff.am |  3 +-
 4 files changed, 121 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 516628973..3225d05ea 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2025-03-15  G. Branden Robinson 
+
+   [libgroff]: Support dumping of some object types in JSON format.
+
+   * src/include/json-encode.h:
+   * src/libs/libgroff/json_encode.cpp: Add new files.
+
+   * src/libs/libgroff/libgroff.am (libgroff_a_SOURCES): Add
+   "json_encode.cpp".
+
 2025-03-10  G. Branden Robinson 
 
Further rationalize header file inclusions.
diff --git a/src/include/json-encode.h b/src/include/json-encode.h
new file mode 100644
index 0..98bcbcf56
--- /dev/null
+++ b/src/include/json-encode.h
@@ -0,0 +1,29 @@
+/* Copyright (C) 2025 G. Branden Robinson
+
+This file is part of groff.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see . */
+
+struct json_char {
+  char len;
+  char buf[7]; // '\u' + '\0'
+};
+
+json_char json_encode_char(unsigned char);
+
+// Local Variables:
+// fill-column: 72
+// mode: C++
+// End:
+// vim: set cindent noexpandtab shiftwidth=2 textwidth=72:
diff --git a/src/libs/libgroff/json_encode.cpp 
b/src/libs/libgroff/json_encode.cpp
new file mode 100644
index 0..a3bc47de7
--- /dev/null
+++ b/src/libs/libgroff/json_encode.cpp
@@ -0,0 +1,80 @@
+/* Copyright (C) 2025 G. Branden Robinson
+
+This file is part of groff.
+
+groff is free software; you can redistribute it and/or modify it under
+the terms of the GNU General Public License as published by the Free
+Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+groff is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or
+FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see . */
+
+#ifdef HAVE_CONFIG_H
+#include 
+#endif
+
+#include 
+#include  // snprintf()
+
+#include "cset.h" // csprint()
+#include "json-encode.h" // json_char
+
+// Return pointer to mutable buffer representing character `c` as a JSON
+// string.  The caller must free the buffer.
+json_char json_encode_char(unsigned char c)
+{
+  assert(c < 256);
+  json_char jc;
+  // Handle the most common cases first.
+  if (csprint(c)) {
+jc.len = 1;
+jc.buf[0] = c;
+  }
+  else if (('"' == c) || ('\\' == c) || ('/' == c)) {
+jc.len = 2;
+jc.buf[0] = '\\';
+jc.buf[1] = c;
+  }
+  else if ('\b' == c) {
+jc.len = 2;
+jc.buf[0] = '\\';
+jc.buf[1] = 'b';
+  }
+  else if ('\t' == c) {
+jc.len = 2;
+jc.buf[0] = '\\';
+jc.buf[1] = 't';
+  }
+  else if ('\n' == c) {
+jc.len = 2;
+jc.buf[0] = '\\';
+jc.buf[1] = 'n';
+  }
+  else if ('\f' == c) {
+jc.len = 2;
+jc.buf[0] = '\\';
+jc.buf[1] = 'f';
+  }
+  else if ('\r' == c) {
+jc.len = 2;
+jc.buf[0] = '\\';
+jc.buf[1] = 'r';
+  }
+  else {
+jc.len = 6;
+(void) snprintf(jc.buf, sizeof jc.buf, "\\u%04X", c);
+  }
+  return jc;
+}
+
+// Local Variables:
+// fill-column: 72
+// mode: C++
+// End:
+// vim: set cindent noexpandtab shiftwidth=2 textwidth=72:
diff --git a/src/libs/libgroff/libgroff.am b/src/libs/libgroff/libgroff.am
index 36b83d5ee..f0c53a3f0 100644
--- a/src/libs/libgroff/libgroff.am
+++ b/src/libs/libgroff/libgroff.am
@@ -1,4 +1,4 @@
-# Copyright (C) 2014-2024 Free Software Foundation, Inc.
+# Copyright (C) 2014-2025 Free Software Foundation, Inc.
 #
 # This file is part of groff.
 #
@@ -44,6 +44,7 @@ libgroff_a_SOURCES = \
   src/libs/libgroff/iftoa.c \
   src/libs/libgroff/invalid.cpp \
   src/libs/libgroff/itoa.c \
+  src/libs

[groff] 22/61: [doc,man]: Revise description of `pline` output.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit eef589cae4409bbb9e6d476f3e11bc169ca7b6f0
Author: G. Branden Robinson 
AuthorDate: Wed Mar 5 09:04:44 2025 -0600

[doc,man]: Revise description of `pline` output.

...now that it's wired up to the new node dumper features.

* doc/groff.texi.in (Debugging) :
* man/groff.7.man (Request short reference) :
* man/groff_diff.7.man (New requests) : Do it.
---
 doc/groff.texi.in| 10 +++---
 man/groff.7.man  |  7 +--
 man/groff_diff.7.man |  7 +--
 3 files changed, 17 insertions(+), 7 deletions(-)

diff --git a/doc/groff.texi.in b/doc/groff.texi.in
index a53882e98..b03f371dd 100644
--- a/doc/groff.texi.in
+++ b/doc/groff.texi.in
@@ -17743,9 +17743,13 @@ asterisk (@code{*}).
 @cindex node list, of pending output line, dumping (@code{pline})
 @cindex output line, node list of pending, dumping (@code{pline})
 @cindex pending node list of output line, dumping (@code{pline})
-Report, to the standard error stream, the list of output nodes
-corresponding to the pending output line.  The list is empty if there
-are none.
+Report,
+in JSON syntax to the standard error stream,
+the list of output nodes corresponding to the pending output line.
+In JSON,
+a pair of empty brackets
+@samp{[ ]}
+represents an empty list.
 @endDefreq
 
 @Defreq {pm, }
diff --git a/man/groff.7.man b/man/groff.7.man
index 0b10f1c58..0421225ab 100644
--- a/man/groff.7.man
+++ b/man/groff.7.man
@@ -4195,10 +4195,13 @@ Change page length to
 .TPx
 .REQ .pline
 Report,
-to the standard error stream,
+in JSON syntax to the standard error stream,
 the list of output nodes corresponding to the pending output line.
 .
-The list is empty if there are none.
+In JSON,
+a pair of empty brackets
+.RB \[lq] "[ ]" \[rq]
+represents an empty list.
 .
 .TPx
 .REQ .pm
diff --git a/man/groff_diff.7.man b/man/groff_diff.7.man
index 94387cf53..516ad4b11 100644
--- a/man/groff_diff.7.man
+++ b/man/groff_diff.7.man
@@ -3415,10 +3415,13 @@ are suffixed with a tab and asterisk
 .TP
 .B .pline
 Report,
-to the standard error stream,
+in JSON syntax to the standard error stream,
 the list of output nodes corresponding to the pending output line.
 .
-The list is empty if there are none.
+In JSON,
+a pair of empty brackets
+.RB \[lq] "[ ]" \[rq]
+represents an empty list.
 .
 .
 .TP

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 41/61: [troff]: Implement recursive node dumping (5p/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 4c586f362787b23dffbf32754e17a8a6748ee9be
Author: G. Branden Robinson 
AuthorDate: Mon Mar 3 07:44:02 2025 -0600

[troff]: Implement recursive node dumping (5p/9).

* src/roff/troff/node.h (struct width_list): Declare `dump()` member
  function.

  (class word_space_node): Specialize (override) `dump_properties()` for
  this class.

* src/roff/troff/node.cpp (width_list::dump): New member function
  traverses a singly-linked of `width_list` nodes, and reports values of
  `width` and `sentence_width` properties.

  (word_space_node::dump_properties): New member function reports values
  of `width_list` (if not a null pointer) and `unformat` properties.

Changes `pline` request output as follows.

-{"type": "word_space_node", "diversion level": 0, "is_special_node": 
false, "hunits": 2500}]
+{"type": "word_space_node", "diversion level": 0, "is_special_node": 
false, "hunits": 2500, "width_list": [{ "width": 2500, "sentence_width": 2500 
}], "unformat": false}]
---
 ChangeLog   | 13 +
 src/roff/troff/node.cpp | 30 ++
 src/roff/troff/node.h   |  2 ++
 3 files changed, 45 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index c4050044f..5b78df7d1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2025-03-03  G. Branden Robinson 
+
+   * src/roff/troff/node.h (struct width_list): Declare `dump()`
+   member function.
+   (class word_space_node): Specialize (override)
+   `dump_properties()` for this class.
+   * src/roff/troff/node.cpp (width_list::dump): New member
+   function traverses a singly-linked of `width_list` nodes, and
+   reports values of `width` and `sentence_width` properties.
+   (word_space_node::dump_properties): New member function
+   reports values of `width_list` (if not a null pointer) and
+   `unformat` properties.
+
 2025-03-03  G. Branden Robinson 
 
* src/roff/troff/node.h (class draw_node): Specialize (override)
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index facd48f88..c9595a8a5 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -4622,6 +4622,25 @@ width_list::width_list(width_list *w)
 {
 }
 
+void width_list::dump()
+{
+  fputc('[', stderr);
+  bool need_comma = false;
+  fprintf(stderr, "{ \"width\": %d", width.to_units());
+  fprintf(stderr, ", \"sentence_width\": %d }",
+ sentence_width.to_units());
+  fflush(stderr);
+  width_list *n = this;
+  while (n->next != 0 /* nullptr */) {
+if (need_comma)
+  fputs(", ", stderr);
+need_comma = true;
+n = n->next;
+  }
+  fputc(']', stderr);
+  fflush(stderr);
+}
+
 word_space_node::word_space_node(hunits d, color *c, width_list *w, node *x)
 : space_node(d, c, x), orig_width(w), unformat(false)
 {
@@ -4634,6 +4653,17 @@ word_space_node::word_space_node(hunits d, int s, color 
*c,
 {
 }
 
+void word_space_node::dump_properties()
+{
+  space_node::dump_properties();
+  if (orig_width != 0 /* nullptr */) {
+fputs(", \"width_list\": ", stderr);
+orig_width->dump();
+  }
+  fprintf(stderr, ", \"unformat\": %s", unformat ? "true" : "false");
+  fflush(stderr);
+}
+
 word_space_node::~word_space_node()
 {
   width_list *w = orig_width;
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index 35b39d1ad..1d522bb41 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -229,6 +229,7 @@ struct width_list {
   width_list *next;
   width_list(hunits, hunits);
   width_list(width_list *);
+  void dump();
 };
 
 class word_space_node : public space_node {
@@ -253,6 +254,7 @@ public:
   bool did_space_merge(hunits, hunits, hunits);
   bool causes_tprint();
   bool is_tag();
+  void dump_properties();
 };
 
 class unbreakable_space_node : public word_space_node {

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 25/61: [troff]: Implement recursive node dumping (4/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit f1b2fd8cd78b68cad9fda025b3dc20aac5e06f9b
Author: G. Branden Robinson 
AuthorDate: Sun Mar 2 22:14:39 2025 -0600

[troff]: Implement recursive node dumping (4/9).

* src/roff/troff/node.cpp (class charinfo_node): Declare member function
  `dump_properties()` overriding base here...
  (class glyph_node): ...instead of here.

  (composite_node::dump_properties): Rename this...
  (charinfo_node::dump_properties): ...to this (and relocate it to
  live alongside `charinfo_node`'s other member functions).

  (class glyph_node): Undeclare member function `dump_node()`.
  (glyph_node::dump_node): Drop.  The `charinfo_node` base class
  now does everything its derived classes need.

Changes `pline` request output as follows.

-{"type": "glyph_node", "character": "d", "diversion level": 0, 
"is_special_node": false},
-{"type": "glyph_node", "character": "e", "diversion level": 0, 
"is_special_node": false},
-{"type": "glyph_node", "character": "f", "diversion level": 0, 
"is_special_node": false},
+{"type": "glyph_node", "diversion level": 0, "is_special_node": false, 
"character": "d"},
+{"type": "glyph_node", "diversion level": 0, "is_special_node": false, 
"character": "e"},
+{"type": "glyph_node", "diversion level": 0, "is_special_node": false, 
"character": "f"},
---
 ChangeLog   | 12 +++
 src/roff/troff/node.cpp | 90 +++--
 2 files changed, 46 insertions(+), 56 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index f53b11080..0da838c93 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,15 @@
+2025-03-02  G. Branden Robinson 
+
+   * src/roff/troff/node.cpp (class charinfo_node): Declare
+   member function `dump_properties()` overriding base here...
+   (class glyph_node): ...instead of here.
+   (composite_node::dump_properties): Rename this...
+   (charinfo_node::dump_properties): ...to this (and relocate it to
+   live alongside `charinfo_node`'s other member functions).
+   (class glyph_node): Undeclare member function `dump_node()`.
+   (glyph_node::dump_node): Drop.  The `charinfo_node` base class
+   now does everything its derived classes need.
+
 2025-03-02  G. Branden Robinson 
 
* src/roff/troff/node.cpp (class composite_node): Rename member
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 5b6b66b05..dfc451ba6 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -38,6 +38,7 @@ along with this program.  If not, see 
. */
 #include "charinfo.h"
 #include "input.h"
 #include "geometry.h"
+#include "json-encode.h" // json_encode_char()
 
 #include "posix.h"
 #include "nonposix.h"
@@ -1865,6 +1866,7 @@ public:
   int ends_sentence();
   int overlaps_vertically();
   int overlaps_horizontally();
+  void dump_properties();
 };
 
 charinfo_node::charinfo_node(charinfo *c, statem *s, int divlevel,
@@ -1892,6 +1894,31 @@ int charinfo_node::overlaps_vertically()
   return ci->overlaps_vertically();
 }
 
+void charinfo_node::dump_properties()
+{
+  node::dump_properties();
+  // GNU troff multiplexes the distinction of ordinary vs. special
+  // characters though the special character code zero.
+  unsigned char c = ci->get_ascii_code();
+  if (c) {
+fputs(", \"character\": ", stderr);
+// It's not a `string` or `symbol` we can `.json_dump()`, so we have
+// to write the quotation marks ourselves.
+fputc('\"', stderr);
+json_char jc = json_encode_char(c);
+// Write out its JSON representation by character by character to
+// keep libc string functions from interpreting C escape sequences.
+for (size_t i = 0; i < jc.len; i++)
+  fputc(jc.buf[i], stderr);
+fputc('\"', stderr);
+  }
+  else {
+fputs(", \"special character\": ", stderr);
+ci->nm.json_dump();
+  }
+  fflush(stderr);
+}
+
 class glyph_node : public charinfo_node {
 protected:
   tfont *tf;
@@ -1932,7 +1959,6 @@ public:
   const char *type();
   bool causes_tprint();
   bool is_tag();
-  void dump_node();
 };
 
 class ligature_node : public glyph_node {
@@ -2209,50 +2235,6 @@ void glyph_node::ascii_print(ascii_output_file *ascii)
   else
 ascii->outs(ci->nm.contents());
 }
-
-// XXX: This and `composite_node::dump_node()` are identical.  C++
-// presumably has several different solutions for this.  Pick one.
-void glyph_node::dump_node()
-{
-  fprintf(stderr, "{\"type\": \"%s\"", type());
-  // GNU troff multiplexes the distinction of ordinary vs. special
-  // characters though the special character code zero.
-  unsigned char c = ci->get_ascii_code();
-  if (c) {
-fputs(", \"character\": ", stderr);
-fputc('\"', stderr);
-// JSON-encode the (printable Basic Latin) character.
-switch (c) {
-case '"':
-case '\\':
-case '/':
-  fputc('\\', stderr);

[groff] 23/61: [troff]: Implement recursive node dumping (2/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit c16bea9bdfb2eaa9b97c806e79aff441e9795087
Author: G. Branden Robinson 
AuthorDate: Sun Mar 2 21:48:10 2025 -0600

[troff]: Implement recursive node dumping (2/9).

* src/roff/troff/node.h (struct node): Add new virtual member function,
  `dump_properties()`, to support modular composition of node dumping.
  All nodes have properties, but some dervived classes of `node` have
  _additional_ properties.  Also, we want to be able to distinguish
  property reporting from contained-node reporting, which is where
  recursion comes in.

  (node::dump_properties): Implement it.  This takes over most of the
  former function of `node::dump_node()`...

  (node::dump_node): ...which now just writes out braces `{` `}` with
  properties in between.
---
 ChangeLog   | 13 +
 src/roff/troff/node.cpp | 16 +---
 src/roff/troff/node.h   |  1 +
 3 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e726a2ef9..8d8769a3b 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2025-03-02  G. Branden Robinson 
+
+   * src/roff/troff/node.h (struct node): Add new virtual member
+   function, `dump_properties()`, to support modular composition of
+   node dumping.  All nodes have properties, but some dervived
+   classes of `node` have _additional_ properties.  Also, we want
+   to be able to distinguish property reporting from contained-node
+   reporting, which is where recursion comes in.
+   (node::dump_properties): Implement it.  This takes over most of
+   the former function of `node::dump_node()`...
+   (node::dump_node): ...which now just writes out braces `{` `}`
+   with properties in between.
+
 2025-03-02  G. Branden Robinson 
 
* src/roff/troff/node.h (struct node): Undeclare
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index e0ee14569..a3637291c 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -2609,9 +2609,9 @@ units node::size()
   return points_to_units(10);
 }
 
-void node::dump_node()
+void node::dump_properties()
 {
-  fprintf(stderr, "{\"type\": \"%s\"", type());
+  fprintf(stderr, "\"type\": \"%s\"", type());
   fprintf(stderr, ", \"diversion level\": %d", div_nest_level);
   fprintf(stderr, ", \"is_special_node\": %s",
  is_special ? "true" : "false");
@@ -2623,7 +2623,17 @@ void node::dump_node()
 fputs(", \"state\": ", stderr);
 state->display_state();
   }
-  fputs("}", stderr);
+  fflush(stderr);
+}
+
+void node::dump_node()
+{
+  fputc('{', stderr);
+  // Flush so that in case something goes wrong with property dumping,
+  // we know that we traversed to a new node.
+  fflush(stderr);
+  dump_properties();
+  fputc('}', stderr);
   fflush(stderr);
 }
 
diff --git a/src/roff/troff/node.h b/src/roff/troff/node.h
index efdcd6294..2af7662b0 100644
--- a/src/roff/troff/node.h
+++ b/src/roff/troff/node.h
@@ -116,6 +116,7 @@ struct node {
 
   virtual bool is_same_as(node *) = 0;
   virtual const char *type() = 0;
+  virtual void dump_properties();
   virtual void dump_node();
 };
 

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 24/61: [troff]: Implement recursive node dumping (3/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit d4d678e097c3e0b10d0e26f0e306012d66083daa
Author: G. Branden Robinson 
AuthorDate: Sun Mar 2 21:59:28 2025 -0600

[troff]: Implement recursive node dumping (3/9).

* src/roff/troff/node.cpp (class composite_node): Rename member function
  `dump_node()` to `dump_properties()`, altering its purpose.

  (composite_node::dump_node): Rename this...
  (composite_node::dump_properties): ...to this.  Now we override
  a different function, and can ditch repetitious code that
  reported properties of the base class.

Also drop now-stale comments.

Changes `pline` request output as follows (and as planned with
properties of the base class--except for MTSM/HTML "state"
stuff--preceding those of the derived class).

-{"type": "composite_node", "character": "\\Fl", "diversion level": 0, 
"is_special_node": false},
+{"type": "composite_node", "diversion level": 0, "is_special_node": false, 
"special character": "Fl"},
---
 ChangeLog   | 10 ++
 src/roff/troff/node.cpp | 20 +++-
 2 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index 8d8769a3b..f53b11080 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,13 @@
+2025-03-02  G. Branden Robinson 
+
+   * src/roff/troff/node.cpp (class composite_node): Rename member
+   function `dump_node()` to `dump_properties()`, altering its
+   purpose.
+   (composite_node::dump_node): Rename this...
+   (composite_node::dump_properties): ...to this.  Now we override
+   a different function, and can ditch repetitious code that
+   reported properties of the base class.
+
 2025-03-02  G. Branden Robinson 
 
* src/roff/troff/node.h (struct node): Add new virtual member
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index a3637291c..5b6b66b05 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -4390,7 +4390,7 @@ public:
   bool is_tag();
   void vertical_extent(vunits *, vunits *);
   vunits vertical_width();
-  void dump_node();
+  void dump_properties();
 };
 
 composite_node::composite_node(node *p, charinfo *c, tfont *t, statem *s,
@@ -5033,11 +5033,9 @@ void composite_node::tprint(troff_output_file *out)
 out->right(track_kern);
 }
 
-// XXX: This and `glyph_node::dump_node()` are identical.  C++
-// presumably has several different solutions for this.  Pick one.
-void composite_node::dump_node()
+void composite_node::dump_properties()
 {
-  fprintf(stderr, "{\"type\": \"%s\"", type());
+  node::dump_properties();
   // GNU troff multiplexes the distinction of ordinary vs. special
   // characters though the special character code zero.
   unsigned char c = ci->get_ascii_code();
@@ -5061,18 +5059,6 @@ void composite_node::dump_node()
 fputs(", \"special character\": ", stderr);
 ci->nm.json_dump();
   }
-  fprintf(stderr, ", \"diversion level\": %d", div_nest_level);
-  fprintf(stderr, ", \"is_special_node\": %s",
- is_special ? "true" : "false");
-  if (push_state) {
-fputs(", \"push_state\": ", stderr);
-push_state->display_state();
-  }
-  if (state) {
-fputs(", \"state\": ", stderr);
-state->display_state();
-  }
-  fputs("}", stderr);
   fflush(stderr);
 }
 

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 06/61: [doc,man]: Clarify `pnr` request behavior.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit d05117b10dc4e90eb027101040e77c85face3f63
Author: G. Branden Robinson 
AuthorDate: Fri Mar 14 20:28:25 2025 -0500

[doc,man]: Clarify `pnr` request behavior.
---
 doc/groff.texi.in| 2 +-
 man/groff.7.man  | 2 +-
 man/groff_diff.7.man | 2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/doc/groff.texi.in b/doc/groff.texi.in
index aaf307797..89a83241e 100644
--- a/doc/groff.texi.in
+++ b/doc/groff.texi.in
@@ -17708,7 +17708,7 @@ strings, and diversions with their sizes in bytes.
 @cindex dumping registers (@code{pnr})
 @cindex registers, dumping (@code{pnr})
 Report the name and value and,
-if the value is numeric,
+if its type is numeric,
 the autoincrement amount and assigned format of each register
 @var{reg},
 or,
diff --git a/man/groff.7.man b/man/groff.7.man
index d96f7ef35..7aa77de78 100644
--- a/man/groff.7.man
+++ b/man/groff.7.man
@@ -4218,7 +4218,7 @@ assigned formats of all defined registers to the standard 
error stream.
 .TPx
 .REQ .pnr "reg \fR\&.\|.\|.\&\fP"
 Report the name and value and,
-if the value is numeric,
+if its type is numeric,
 the autoincrement amount and assigned format,
 of each register
 .I reg
diff --git a/man/groff_diff.7.man b/man/groff_diff.7.man
index a9b9fec24..8e806822a 100644
--- a/man/groff_diff.7.man
+++ b/man/groff_diff.7.man
@@ -3422,7 +3422,7 @@ The list is empty if there are none.
 .BR .pnr \~[\c
 .IR reg \~.\|.\|.]
 Report the name and value and,
-if the value is numeric,
+if its type is numeric,
 the autoincrement amount and assigned format of each register
 .IR reg ,
 or,

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 45/61: [troff]: Implement recursive node dumping (5t/9).

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit af7f747eeca4bdeabac9d4d09fa1913c1efcb33b
Author: G. Branden Robinson 
AuthorDate: Tue Mar 4 08:14:36 2025 -0600

[troff]: Implement recursive node dumping (5t/9).

* src/roff/troff/node.h (class break_char_node): Specialize (override)
  `dump_properties()` for this class.

* src/roff/troff/node.cpp (break_char_node::dump_properties): New member
  function reports values of `break code before`, `break code after`,
  and `terminal_color` properties.

Changes `pline` request output as follows.

-{"type": "break_char_node", "diversion level": 0, "is_special_node": 
false},
+{"type": "break_char_node", "diversion level": 0, "is_special_node": 
false, "break code before": 2, "break code after": 0, "terminal_color": 
"default"},
---
 ChangeLog   |  9 +
 src/roff/troff/node.cpp | 11 +++
 2 files changed, 20 insertions(+)

diff --git a/ChangeLog b/ChangeLog
index 0ecf8c8fd..69f92871e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2025-03-04  G. Branden Robinson 
+
+   * src/roff/troff/node.h (class break_char_node):
+   Specialize (override) `dump_properties()` for this class.
+   * src/roff/troff/node.cpp
+   (break_char_node::dump_properties): New member function reports
+   values of `break code before`, `break code after`, and
+   `terminal_color` properties.
+
 2025-03-04  G. Branden Robinson 
 
* src/roff/troff/node.h (class italic_corrected_node):
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 41e4ebd1a..e916a2bc4 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -2879,6 +2879,7 @@ public:
   bool causes_tprint();
   bool is_tag();
   int get_break_code();
+  void dump_properties();
 };
 
 break_char_node::break_char_node(node *n, int bc, int pbc, color *c, node *x)
@@ -2893,6 +2894,16 @@ break_char_node::break_char_node(node *n, int bc, int 
pbc, color *c,
 {
 }
 
+void break_char_node::dump_properties()
+{
+  node::dump_properties();
+  fprintf(stderr, ", \"break code before\": %d", break_code);
+  fprintf(stderr, ", \"break code after\": %d", prev_break_code);
+  fputs(", \"terminal_color\": ", stderr);
+  col->nm.json_dump();
+  fflush(stderr);
+}
+
 break_char_node::~break_char_node()
 {
   delete nodes;

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit


[groff] 01/01: [troff]: Fix SEGV risk in previous commit.

2025-03-15 Thread G. Branden Robinson
gbranden pushed a commit to branch master
in repository groff.

commit 40dd5cd0587a4238f150490fdcdc794d947ede2c
Author: G. Branden Robinson 
AuthorDate: Sat Mar 15 23:03:52 2025 -0500

[troff]: Fix SEGV risk in previous commit.

* src/roff/troff/input.cpp (macro:json_dump): A `macro` object is not
  guaranteed to contain a `macro_header`; check for a null pointer and
  report an empty JSON string if there's no header.
---
 ChangeLog| 6 ++
 src/roff/troff/input.cpp | 5 -
 2 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/ChangeLog b/ChangeLog
index 89a975aae..cdf7d6500 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2025-03-15  G. Branden Robinson 
+
+   * src/roff/troff/input.cpp (macro:json_dump): A `macro` object
+   is not guaranteed to contain a `macro_header`; check for a null
+   pointer and report an empty JSON string if there's no header.
+
 2025-03-15  G. Branden Robinson 
 
[troff]: Implement dumping of device extension node contents.
diff --git a/src/roff/troff/input.cpp b/src/roff/troff/input.cpp
index 9c4427f3f..71eec4fc8 100644
--- a/src/roff/troff/input.cpp
+++ b/src/roff/troff/input.cpp
@@ -3716,7 +3716,10 @@ void macro::print_size()
 
 void macro::json_dump()
 {
-  p->json_dump();
+  if (p != 0 /* nullptr */)
+p->json_dump();
+  else
+fputs("\"\"", stderr);
 }
 
 // make a copy of the first n bytes

___
groff-commit mailing list
groff-commit@gnu.org
https://lists.gnu.org/mailman/listinfo/groff-commit