TransWikia.com

Etoolbox's patchcmd can't find search pattern due to hyperref package

TeX - LaTeX Asked by Croisillon on May 15, 2021

I use the report class and I have learned from other questions on this site (like Remove spacing between per-chapter figures in LoF) how I can adjust the spacing between per-chapter figures in the LoF. I would like to change the traditional

addtocontents{lof}{protectaddvspace{10p@}}

in the report.cls file to

addtocontents{lof}{protectaddvspace{15p@}} by using this patch :

makeatletter
patchcmd{@chapter}%
  {addtocontents{lof}{protectaddvspace{10p@}}}% <search>
  {addtocontents{lof}{protectaddvspace{15p@}}}% <replace>
  {}{}% <success><failure>
makeatother

However, by issuing tracingpatches I can see the following :

[debug] analyzing '@chapter'
[debug] ++ control sequence is defined
[debug] ++ control sequence is a macro
[debug] ++ macro can be retokenized cleanly
[debug] -- search pattern not found in replacement text

Am I doing something wrong ? I don’t understand why patchcmd can’t find the specified code. For the record, there are 3 other patches in my document (not modifying @chapter) and they all work well.

Edit: While preparing a MWE, I realized that the package hyperref is the culprit, since removing it solves the problem.

documentclass[12pt,twoside,openright]{report}

usepackage[utf8]{inputenc}
usepackage[T1]{fontenc}
usepackage[french]{babel}
usepackage{lmodern}
usepackage{microtype}

usepackage{etoolbox}

usepackage[pdftex,colorlinks,linkcolor=blue,citecolor=red]{hyperref}

%----------------------- Patch -----------------------
tracingpatches
makeatletter
patchcmd{@chapter}%        
  {addtocontents{lof}{protectaddvspace{10p@}}}% <search>
  {addtocontents{lof}{protectaddvspace{15p@}}}% <replace>
  {}{}% <success><failure>
makeatother
%-----------------------------------------------------


begin{document}
listoffigures
chapter{A chapter}
begin{figure}caption{A figure}end{figure}
begin{figure}caption{A figure}end{figure}
chapter{A chapter}
begin{figure}caption{A figure}end{figure}
begin{figure}caption{A figure}end{figure}
appendix
chapter{A chapter}
addtocontents{lof}{protectaddvspace{10pt}}%
begin{figure}caption{A figure}end{figure}
begin{figure}caption{A figure}end{figure}
end{document}

Is there a way to fix this ? I need to keep loading the hyperref package.

One Answer

hyperref has to define a great many internal commands to do its thing.

In this case the original definition of @chapter is saved to Hy@org@chapter by hyperref, @chapter is then redefined to do some linking and then calls Hy@org@chapter.

So the solution here is to patch Hy@org@chapter instead of @chapter when hyperref is loaded.

documentclass[12pt,twoside,openright]{report}

usepackage[utf8]{inputenc}
usepackage[T1]{fontenc}
usepackage[french]{babel}
usepackage{lmodern}
usepackage{microtype}

usepackage{etoolbox}

usepackage[pdftex,colorlinks,linkcolor=blue,citecolor=red]{hyperref}

%----------------------- Patch -----------------------
tracingpatches
makeatletter
patchcmd{Hy@org@chapter}%        
  {addtocontents{lof}{protectaddvspace{10p@}}}% <search>
  {addtocontents{lof}{protectaddvspace{15p@}}}% <replace>
  {}{}% <success><failure>
makeatother
%-----------------------------------------------------


begin{document}
listoffigures
chapter{A chapter}
begin{figure}caption{A figure}end{figure}
begin{figure}caption{A figure}end{figure}
chapter{A chapter}
begin{figure}caption{A figure}end{figure}
begin{figure}caption{A figure}end{figure}
appendix
chapter{A chapter}
addtocontents{lof}{protectaddvspace{10pt}}%
begin{figure}caption{A figure}end{figure}
begin{figure}caption{A figure}end{figure}
end{document}

gives

larger spaces

and

[debug] tracing patchcmd on input line 16
[debug] analyzing 'Hy@org@chapter'
[debug] ++ control sequence is defined
[debug] ++ control sequence is a macro
[debug] ++ macro can be retokenized cleanly
[debug] ++ search pattern found in replacement text
[debug] ++ patching possible
[debug] == retokenizing macro now

Alternatively, you can try to get your patch in before hyperref applies its redefinitions.

documentclass[12pt,twoside,openright]{report}

usepackage{etoolbox}

%----------------------- Patch -----------------------
tracingpatches
makeatletter
patchcmd{@chapter}%        
  {addtocontents{lof}{protectaddvspace{10p@}}}% <search>
  {addtocontents{lof}{protectaddvspace{15p@}}}% <replace>
  {}{}% <success><failure>
makeatother
%-----------------------------------------------------

usepackage[utf8]{inputenc}
usepackage[T1]{fontenc}
usepackage[french]{babel}
usepackage{lmodern}
usepackage{microtype}

usepackage[pdftex,colorlinks,linkcolor=blue,citecolor=red]{hyperref}



begin{document}
listoffigures
chapter{A chapter}
begin{figure}caption{A figure}end{figure}
begin{figure}caption{A figure}end{figure}
chapter{A chapter}
begin{figure}caption{A figure}end{figure}
begin{figure}caption{A figure}end{figure}
appendix
chapter{A chapter}
addtocontents{lof}{protectaddvspace{10pt}}%
begin{figure}caption{A figure}end{figure}
begin{figure}caption{A figure}end{figure}
end{document}

Thanks to David Carlisle for suggesting that in the comments.

Correct answer by moewe on May 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