TeX - LaTeX Asked on April 15, 2021
I want to use the etoolbox
package to patch a certain environment; but – I only want to do it for a certain stretch of my document.
Enclosing in curly brances doesn’t work:
documentclass{article}
usepackage{etoolbox}
begin{document}
{
AtBeginEnvironment{center}{(patched start!)}
AtEndEnvironment{center}{(patched end!)}
begin{center}
In center.
end{center}
}
Out of center.
begin{center}
In center.
end{center}
end{document}
The second environment renders in the patched form as well. What should I do instead?
LaTeX environments map their begin{foo}
code to a macro foo
and their end{foo}
code to a macro endfoo
. For most environments you can thus use the classical approach to store the original meaning of a macro using let
, and then redefine foo
and endfoo
(locally) by using the original meaning in the new definition:
documentclass{article}
begin{document}
{
% Save the old meaning ...
letorigcenter=center
letorigendcenter=endcenter
% ... and assign a new one
defcenter{%
(patch A)%
origcenter
(patch B)%
}%
defendcenter{%
(patch C)%
origendcenter
(patch D)%
}%
begin{center}
In center.
end{center}
}
Out of centering.
begin{center}
In center.
end{center}
end{document}
The advantage of this method is that you can easily add material at the start and end, inside and outside the environment, respectively.
Answered by siracusa on April 15, 2021
The 2020-10-01 release of LaTeX added a new hook mechanism to the LaTeX kernel. etoolbox
now makes use of that new hook mechanism. This means that the answer provided below no longer works.
All LaTeX hooks are global and there does not appear to be a simple way to make them local. There is a way to add code only for the 'next' use of the hook, which isn't the same as a real local assignment.
documentclass{article}
usepackage{etoolbox}
newrobustcmd{AtNextBeginEnvironment}[1]{%
AddToHookNext{env/#1/begin}}
newrobustcmd{AtNextEndEnvironment}[1]{%
AddToHookNext{env/#1/end}}
begin{document}
AtNextBeginEnvironment{center}{(patched start!)}
AtNextEndEnvironment{center}{(patched end!)}
begin{center}
In center.
end{center}
Out of center.
begin{center}
In center.
end{center}
end{document}
Alternatively, the new LaTeX hooks allow you to remove code from hooks. This wouldn't happen automatically with a closing group, but might be an option depending on your use case.
The following is an attempt at replicating a local hook system by using the global hooks with a local helper macro.
documentclass{article}
usepackage{etoolbox}
newrobustcmd{LocalAtBeginEnvironment}[1]{%
ifcsundef{ltbx@local@hook@begin@#1}
{AtBeginEnvironment{#1}{csuse{ltbx@local@hook@begin@#1}}}
{}%
csappto{ltbx@local@hook@begin@#1}}
newrobustcmd{LocalAtEndEnvironment}[1]{%
ifcsundef{ltbx@local@hook@end@#1}
{AtEndEnvironment{#1}{csuse{ltbx@local@hook@end@#1}}}
{}%
csappto{ltbx@local@hook@end@#1}}
begin{document}
{
LocalAtBeginEnvironment{center}{(patched start!)}
LocalAtEndEnvironment{center}{(patched end!)}
begin{center}
In center.
end{center}
}
Out of center.
begin{center}
In center.
end{center}
end{document}
etoolbox
's document and environment hooks all work globally. Thankfully, the implementation of AtBeginEnvironment
and AtEndEnvironment
are very simple so that they can easily be copied and changed to work locally instead of globally.
We just append to the hooks (locally) with csappto
and not globally with csgappto
as in the original definitions.
documentclass{article}
usepackage{etoolbox}
newrobustcmd{LocalAtBeginEnvironment}[1]{%
csappto{@begin@#1@hook}}
newrobustcmd{LocalAtEndEnvironment}[1]{%
csappto{@end@#1@hook}}
begin{document}
{
LocalAtBeginEnvironment{center}{(patched start!)}
LocalAtEndEnvironment{center}{(patched end!)}
begin{center}
In center.
end{center}
}
Out of center.
begin{center}
In center.
end{center}
end{document}
Answered by moewe on April 15, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP