gbranden pushed a commit to branch master
in repository groff.
commit 97997d796944c75f2bf891d43a0444aee26ddae6
Author: G. Branden Robinson <[email protected]>
AuthorDate: Mon Feb 16 18:57:12 2026 -0600
[mm]: Fix Savannah #68052.
* contrib/mm/ m.tmac (li@pop): When popping a nested list level, restore
attribute saved in `li*mark-list!n` array to module-local string
`li*mf`, not `li*mark`; the distinction matters when lists of type
"zero" are nested, in practice that value describes only marked item
(`ML`) lists.
Fixes <https://savannah.gnu.org/bugs/?68052>. Problem introduced by me
in commit d9209295a3, 9 October 2024. Thanks to Alexis Hildebrandt for
the report. The commit characterized itself as a "trivial refactoring":
"Rename internal string `li*mark` to `li*mf`, since it can be _either_
an arbitrary string _or_ an argument to the `af` request." I'd
characterize the root cause of this problem as follows. The `LB`
macro's optional fifth argument is the *roff equivalent of an untagged
union per the foregoing. (But we're stuck with it because it's a DWB
3.3 [or earlier] mm feature.) When a list nesting level is popped, we
don't recover all of the information that the `LB` macro's internals
computed; instead we rely on stashing some. When renaming `li*mf` to
`li*mark`, I did not realize that this stashing logic needed to save the
pre-interpretation form of the "mark-or-list" argument, not a
post-interpretation, unambiguously typed string to use as the item mark.
A better implementation of `LB` would stash as many distinctly, and
unambiguously typed, data as warranted to recover necessary state when a
"pop" occurs. I predict that doing so would, in turn, make the `LI`
macro's job simpler and easier, leaving less room for bugs.
---
contrib/mm/ChangeLog | 30 ++++++++++++++++++++++++++++++
contrib/mm/m.tmac | 2 +-
2 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/contrib/mm/ChangeLog b/contrib/mm/ChangeLog
index a02bca119..3fb60c4a7 100644
--- a/contrib/mm/ChangeLog
+++ b/contrib/mm/ChangeLog
@@ -1,3 +1,33 @@
+2026-02-16 G. Branden Robinson <[email protected]>
+
+ * m.tmac (li@pop): When popping a nested list level, restore
+ attribute saved in `li*mark-list!n` array to module-local string
+ `li*mf`, not `li*mark`; the distinction matters when lists of
+ type "zero" are nested, in practice that value describes only
+ marked item (`ML`) lists.
+
+ Fixes <https://savannah.gnu.org/bugs/?68052>. Problem
+ introduced by me in commit d9209295a3, 9 October 2024. Thanks
+ to Alexis Hildebrandt for the report. The commit characterized
+ itself as a "trivial refactoring": "Rename internal string
+ `li*mark` to `li*mf`, since it can be _either_ an arbitrary
+ string _or_ an argument to the `af` request." I'd characterize
+ the root cause of this problem as follows. The `LB` macro's
+ optional fifth argument is the *roff equivalent of an untagged
+ union per the foregoing. (But we're stuck with it because it's
+ a DWB 3.3 [or earlier] mm feature.) When a list nesting level
+ is popped, we don't recover all of the information that the `LB`
+ macro's internals computed; instead we rely on stashing some.
+ When renaming `li*mf` to `li*mark`, I did not realize that this
+ stashing logic needed to save the pre-interpretation form of the
+ "mark-or-list" argument, not a post-interpretation,
+ unambiguously typed string to use as the item mark. A better
+ implementation of `LB` would stash as many distinctly, and
+ unambiguously typed, data as warranted to recover necessary
+ state when a "pop" occurs. I predict that doing so would, in
+ turn, make the `LI` macro's job simpler and easier, leaving less
+ room for bugs.
+
2026-02-16 G. Branden Robinson <[email protected]>
Add regression test for Savannah #68052. Nested marked lists
diff --git a/contrib/mm/m.tmac b/contrib/mm/m.tmac
index cfcc69891..b4b7ae554 100644
--- a/contrib/mm/m.tmac
+++ b/contrib/mm/m.tmac
@@ -2681,7 +2681,7 @@ ML, RL, VL, or LB first
.misc@pop-nr pad li*pad
.misc@pop-nr type li*type
.misc@pop-nr li-spc li*li-spc
-.ds li*mark \\*[li*mark-list!\\n[li*lvl]]
+.ds li*mf \\*[li*mark-list!\\n[li*lvl]]
..
.de LE
\\*[debug@dump-args]\\
_______________________________________________
groff-commit mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/groff-commit