LaTeXML
LaTeXML copied to clipboard
more correct emulation of \box and \copy primitives
Fixes #2412 .
Two key upgrades:
- deeply clone the box returned during
\copy - for
\box, add a newremoveValuemethod in State, which (idempotently) unbinds the nearest binding of a value in the undo table.
This gets the tests discussed in the issue to pass, and matches the pgf rendering in the PDF build (really great diagnostic by @xworld21 !)
I would need a second opinion by @brucemiller on whether this kind of "removeValue" method makes sense for latexml's State. Its code is inspired by the global assignment mode of assign_internal, which will unbind all values in all frames, and then assign a value on the cleaned up 1-element stack.
I am wondering if many of the current uses of AssignValue($key, undef) are meant as this RemoveValue behavior, which could motivate changing local uses of assign_internal with undef to also unbind from the nearest assigned frame -- without creating a new method.
Edit: Another direction for refining the code is to add a 'local' vs 'global' argument for removeValue, to indicate whether one or all bindings should be deleted.
But I am feeling confident I am following the \box unbind semantics accurately now, as explained in the TeXbook. What was missing was unbinding the actual assignment - we were adding a local undef assignment, while also keeping the original assignment in place, when it happened in a higher frame.
Thoughts?
I really need to think about what TeX is really doing, conceptually, to choose a good name & API. I expect that whatever this is should be kept fairly internal, and not exported to Package, since except for this special case of a box, removing a value is almost certainly not what you'll want to do.
The cloning is curious for a different reason. It's only needed since adjustBoxColor_internal (unwisely?) modifies the boxes in place; and that's different than TeX, because we've diverged from TeX by embedding color into the Font, and embedded the Font into the box. (TeX handles color via a much different hack).
Ah, not quite there; As mentioned in some other issue, there's the problem of when Black actually should have meant "current color". Consider this variant of your tests:
\setbox\myboxC\vbox{{\color{black}Black, stays black, then black.}}
\copy\myboxC
{\color{red}\copy\myboxC}
\copy\myboxC
I'm suspecting that perhaps Font's $DEFCOLOR should be undef, rather than Black (and maybe many other Black, as well), but that'll involve tracking a number of surprises.