TransWikia.com

How do I limit the scope of etoolbox environment patching?

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?

2 Answers

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}

enter image description here

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

Update

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}

Old answer for LaTeX released before 2020-10-01

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}

enter image description here

Answered by moewe on April 15, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP