gbranden pushed a commit to branch master
in repository groff.
commit 553ff83c8996d0370116450ea070233344444116
Author: G. Branden Robinson <[email protected]>
AuthorDate: Wed Sep 17 18:56:01 2025 -0500
[troff]: Refactor `asciify` internals. (1/3)
* src/roff/troff/node.cpp (glyph_node::asciify)
(kern_pair_node::asciify, dbreak_node::asciify)
(asciify_reverse_node_list, ligature_node::asciify)
(break_char_node::asciify, italic_corrected_node::asciify)
(left_italic_corrected_node::asciify)
(space_char_hmotion_node::asciify, space_node::asciify)
(word_space_node::asciify, unbreakable_space_node::asciify)
(line_start_node::asciify, vertical_size_node::asciify)
(dummy_node::asciify, transparent_dummy_node::asciify)
(tag_node::asciify, device_extension_node::asciify)
(vmotion_node::asciify, bracket_node::asciify)
(hyphen_inhibitor_node::asciify, composite_node::asciify): Stop
deleting the `this` object. I added many of these deletions recently,
but several (`glyph_node`, `kern_pair_node`, `dbreak_node`,
`ligature_node`, `break_char_node`, `italic_corrected_node`,
`left_italic_corrected_node`, `hmotion_node`,
`space_char_hmotion_node`, `space_node`, `word_space_node`,
`unbreakable_space_node`, `line_start_node`, `vertical_size_node`, and
`composite_node`) already were in groff 1.23.0, and for untold years
before--sometimes only conditionally depending on the node contents.
Why stop deleting them? Because the node list is actually list of
(potential) trees; some nodes can contain further nodes, and so on
recursively. It's difficult, and there is no need to, mark the root
of each tree in the list so that we can return to it later to delete
it; instead what we can do is have the `asciify` request walk the list
again and perform a delete operation, which due to the class hierarchy
design will automatically be a complete, recursive operation. There
is no reason _not_ to do this because the whole point of `asciify` is
to convert nodes back into some form of text; the idiomatic
application (and only one, as seen in "om.tmac" and "e.tmac") is to
convert strings or diversions into PDF bookmarks or HTML URLs that are
embedded in a document as metadata or markup, not as formatted text.
---
ChangeLog | 37 +++++++++++++++++++++++++++++++++++++
src/roff/troff/node.cpp | 28 ++--------------------------
2 files changed, 39 insertions(+), 26 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 3e6e221f4..27320028a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,40 @@
+2025-09-17 G. Branden Robinson <[email protected]>
+
+ * src/roff/troff/node.cpp (glyph_node::asciify)
+ (kern_pair_node::asciify, dbreak_node::asciify)
+ (asciify_reverse_node_list, ligature_node::asciify)
+ (break_char_node::asciify, italic_corrected_node::asciify)
+ (left_italic_corrected_node::asciify)
+ (space_char_hmotion_node::asciify, space_node::asciify)
+ (word_space_node::asciify, unbreakable_space_node::asciify)
+ (line_start_node::asciify, vertical_size_node::asciify)
+ (dummy_node::asciify, transparent_dummy_node::asciify)
+ (tag_node::asciify, device_extension_node::asciify)
+ (vmotion_node::asciify, bracket_node::asciify)
+ (hyphen_inhibitor_node::asciify, composite_node::asciify): Stop
+ deleting the `this` object. I added many of these deletions
+ recently, but several {`glyph_node`, `kern_pair_node`,
+ `dbreak_node`, `ligature_node`, `break_char_node`,
+ `italic_corrected_node`, `left_italic_corrected_node`,
+ `hmotion_node`, `space_char_hmotion_node`, `space_node`,
+ `word_space_node`, `unbreakable_space_node`, `line_start_node`,
+ `vertical_size_node`, and `composite_node`} already were in
+ groff 1.23.0, and for untold years before--sometimes only
+ conditionally depending on the node contents. Why stop deleting
+ them? Because the node list is actually list of (potential)
+ trees; some nodes can contain further nodes, and so on
+ recursively. It's difficult, and there is no need to, mark the
+ root of each tree in the list so that we can return to it later
+ to delete it; instead what we can do is have the `asciify`
+ request walk the list again and perform a delete operation,
+ which due to the class hierarchy design will automatically be a
+ complete, recursive operation. There is no reason _not_ to do
+ this because the whole point of `asciify` is to convert nodes
+ back into some form of text; the idiomatic application (and only
+ one, as seen in "om.tmac" and "e.tmac") is to convert strings or
+ diversions into PDF bookmarks or HTML URLs that are embedded in
+ a document as metadata or markup, not as formatted text.
+
2025-09-18 G. Branden Robinson <[email protected]>
* src/roff/groff/groff.am (EXTRA_DIST): Ship "throughput-file"
diff --git a/src/roff/troff/node.cpp b/src/roff/troff/node.cpp
index 147a18ec8..ce769f11d 100644
--- a/src/roff/troff/node.cpp
+++ b/src/roff/troff/node.cpp
@@ -3898,10 +3898,8 @@ void glyph_node::asciify(macro *m)
unsigned char c = ci->get_asciify_code();
if (0U == c)
c = ci->get_ascii_code();
- if (c != 0U) {
+ if (c != 0U)
m->append(c);
- delete this;
- }
else
m->append(this);
}
@@ -3915,7 +3913,6 @@ void kern_pair_node::asciify(macro *m)
if (n2 != 0 /* nullptr */)
n2->asciify(m);
n1 = n2 = 0 /* nullptr */;
- delete this;
}
static void asciify_reverse_node_list(macro *m, node *n)
@@ -3933,7 +3930,6 @@ void dbreak_node::asciify(macro *m)
assert(m != 0 /* nullptr */);
if (m != 0 /* nullptr */)
asciify_reverse_node_list(m, none);
- delete this;
}
void ligature_node::asciify(macro *m)
@@ -3945,7 +3941,6 @@ void ligature_node::asciify(macro *m)
if (n2 != 0 /* nullptr */)
n2->asciify(m);
n1 = n2 = 0 /* nullptr */;
- delete this;
}
void break_char_node::asciify(macro *m)
@@ -3953,7 +3948,6 @@ void break_char_node::asciify(macro *m)
assert(nodes != 0 /* nullptr */);
if (nodes != 0 /* nullptr */)
nodes->asciify(m);
- delete this;
}
void italic_corrected_node::asciify(macro *m)
@@ -3961,7 +3955,6 @@ void italic_corrected_node::asciify(macro *m)
assert(nodes != 0 /* nullptr */);
if (nodes != 0 /* nullptr */)
nodes->asciify(m);
- delete this;
}
void left_italic_corrected_node::asciify(macro *m)
@@ -3969,12 +3962,10 @@ void left_italic_corrected_node::asciify(macro *m)
assert(nodes != 0 /* nullptr */);
if (nodes != 0 /* nullptr */)
nodes->asciify(m);
- delete this;
}
void hmotion_node::asciify(macro *)
{
- delete this;
}
space_char_hmotion_node::space_char_hmotion_node(hunits i, color *c,
@@ -3994,70 +3985,57 @@ space_char_hmotion_node::space_char_hmotion_node(hunits
i, color *c,
void space_char_hmotion_node::asciify(macro *m)
{
m->append(' ');
- delete this;
}
void space_node::asciify(macro *)
{
- delete this;
}
void word_space_node::asciify(macro *m)
{
for (width_list *w = orig_width; w != 0 /* nullptr */; w = w->next)
m->append(' ');
- delete this;
}
void unbreakable_space_node::asciify(macro *m)
{
m->append(' ');
- delete this;
}
void line_start_node::asciify(macro *)
{
- delete this;
}
void vertical_size_node::asciify(macro *)
{
- delete this;
}
void dummy_node::asciify(macro *)
{
- delete this;
}
void transparent_dummy_node::asciify(macro *)
{
- delete this;
}
void tag_node::asciify(macro *)
{
- delete this;
}
void device_extension_node::asciify(macro *)
{
- delete this;
}
void vmotion_node::asciify(macro *)
{
- delete this;
}
void bracket_node::asciify(macro *)
{
- delete this;
}
void hyphen_inhibitor_node::asciify(macro *)
{
- delete this;
}
breakpoint *node::get_breakpoints(hunits /* width */, int /* nspaces */,
@@ -4792,10 +4770,8 @@ void composite_node::asciify(macro *m)
unsigned char c = ci->get_asciify_code();
if (0U == c)
c = ci->get_ascii_code();
- if (c != 0U) {
+ if (c != 0U)
m->append(c);
- delete this;
- }
else
m->append(this);
}
_______________________________________________
groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit