hyperref
hyperref copied to clipboard
Use of \Hy@org@chapter doesn't match its definition.
The following MCE used to work with previous versions of hyperref:
\documentclass{book}
\usepackage{xpatch}
\usepackage{hyperref}
\makeatletter
\xapptocmd{\@chapter}{%
\addtocontents{foo}{\protect\addvspace{10\p@}}%
}{}{}
\makeatother
\begin{document}
\chapter{Foo}
\end{document}
but now it gives the following error:
! Use of \Hy@org@chapter doesn't match its definition.
\@chapter ...@next \Hy@org@chapter \addtocontents
{foo}{\protect \addvspace ...
l.42 \chapter{Foo}
?
Sorry I didn't notice the first hyperref's version where the problem arose.
BTW, the issue is similar with \AddToHook{cmd/@chapter/before}{...} instead of \xapptocmd{\@chapter}{...}{}{}.
Sorry no, that never worked. Not with hyperref. I get the same error with e.g. texlive 2018. Perhaps you made the patch before hyperref was loaded, then it can work, as LaTeX grabs the arguments.
Sorry for the irrelevant MCE above. Here is a relevant one, which used to work with an up to date TL 2021, but which doesn't work with an up to date TL 2022 (but, because of nameref, I guess used to work with version v7.00n of hyperref):
\documentclass{book}
\usepackage{xpatch}
\usepackage{hyperref}
\usepackage{nameref}
\makeatletter
\xapptocmd{\@chapter}{%
\addtocontents{foo}{\protect\addvspace{10\p@}}%
}{}{}
\makeatother
\begin{document}
\chapter{Foo}
\end{document}
yes, hyperref no longer loads nameref in begindocument but directly. This means that now first nameref patches \@chapter and then hyperref, where previously it was the other way round.
I don't think that your patch is good as it breaks so easily if packages are loaded in a different order. Why do you patch \@chapter so late?
Why do you patch
\@chapterso late?
Because it is done in a package of mine used with a class of mine which loads hyperref. And because this class also provides several configurations regarding cleveref (which has to be loaded after hyperref), I can't in this class rely on \AddToHook{begindocument/before}{\RequirePackage{hyperref}}.
My attempts with hooks sadly fail:
\documentclass{book}
\AddToHook{begindocument/before}{\RequirePackage{hyperref}}
\AddToHook{package/hyperref/before}
{%
\AddToHook{cmd/@chapter/before}{%
\addtocontents{foo}{\protect\addvspace{10\p@}}%
}%
}
\begin{document}
\chapter{Foo}
\end{document}
if this is for a class then why don't you patch \@chapter directly after if has been defined (probably you load book or something like that?). And why do you use \xapptocmd above instead of prepending the code? Why not
\AddToHook{cmd/@chapter/before}{%
\addtocontents{foo}{\protect\addvspace{10\p@}}%
}{}{}
if this is for a class then why don't you patch
\@chapterdirectly after if has been defined (probably you load book or something like that?).
Hmmm, quite intricate, sorry... For the documentations of each of my classes, I make use of the corresponding classes. And there are some (common) tools and settings that:
- I need for these documentations,
- I don't need (and don't want at first glance) for the classes themselves,
and that, therefore, I gathered in a package. To be more explicit, these tools are tcolorbox “theorems“ (in fact, e.g., warnings named dbwarning), the lists of which not providing by default extra vertical spaces between “theorems“ belonging to different chapters (hence, e.g. \AddToHook{cmd/@chapter/before}{\addtocontents{dbwarninglist}{\protect\addvspace{10\p@}}}.
And why do you use
\xapptocmdabove instead of prepending the code? Why not\AddToHook{cmd/@chapter/before}{% \addtocontents{foo}{\protect\addvspace{10\p@}}% }{}{}
Isn't it what I tried in https://github.com/latex3/hyperref/issues/244#issuecomment-1152651271?
And why do you use
\xapptocmdabove instead of prepending the code?
Ah, do you mean: why \xapptocmd instead of \xpretocmd? To be honest, I don't remember right now...
My attempts with hooks sadly fail:
I think you are overdoing with the hooks, it should be enough to patch the command. But it fails only because you forgot the \makeatletter
I think you are overdoing with the hooks, it should be enough to patch the command. But it fails only because you forgot the
\makeatletter
Indeed it works with \AddToHook{cmd/@chapter/before}{ but hasn't any effect. With \AddToHook{cmd/@chapter/after}{, it fails with the same kind of error:
\documentclass{book}
\RequirePackage{hyperref}
\makeatletter
\AddToHook{cmd/@chapter/after}{%
\addtocontents{foo}{\protect\addvspace{10\p@}}%
}%
\makeatother
\begin{document}
\chapter{Foo}
\end{document}
gives:
! Use of \Hy@org@chapter doesn't match its definition.
\@chapter ...fi \Hy@next \Hy@org@chapter \UseHook
{cmd/@chapter/after}
l.9 \chapter{Foo}
?
What do you mean with it has not effect? If I use an existing list, like e.g. lof it works fine for me. And no, you can not append to \@chapter, not after hyperref has been loaded. It doesn't matter if you append with \xapptocmd, the after hook, or something else. Prepending code to a command works in many case, appending is typically much more dangerous as quite often the command is still looking for arguments. See Commands that look ahead in the ltcmdhooks documentation.
What do you mean with it has not effect? If I use an existing list, like e.g. lof it works fine for me.
That's because it is provided by default for the figures. But that's not the case for the lists of tcolorbox “theorems“:
\documentclass{book}
\usepackage{xpatch}
\usepackage{tcolorbox}
% \usepackage{hyperref}
\tcbuselibrary{theorems}
\newtcbtheorem[list inside=dbwarninglist,number within=chapter]{dbwarning}{Warning}%
{}{dbwa}
% \makeatletter
% \xapptocmd{\@chapter}{%
% \addtocontents{dbwarninglist}{\protect\addvspace{10\p@}}%
% }{}{}
% \makeatother
\begin{document}
\chapter{One}
\begin{dbwarning}{Warning One One}{}
\end{dbwarning}
\begin{dbwarning}{Warning One Two}{}
\end{dbwarning}
%
\begin{figure}
\caption{Figure One One}
\end{figure}
\begin{figure}
\caption{Figure One Two}
\end{figure}
\chapter{Two}
\begin{dbwarning}{Warning Two One}{}
\end{dbwarning}
\begin{dbwarning}{Warning Two Two}{}
\end{dbwarning}
%
\begin{figure}
\caption{Figure Two One}
\end{figure}
\begin{figure}
\caption{Figure Two Two}
\end{figure}
%
\listoffigures
\tcblistof[\chapter*]{dbwarninglist}{Table of warnings}
\end{document}
And no, you can not append to
\@chapter, not after hyperref has been loaded. It doesn't matter if you append with\xapptocmd, theafterhook, or something else. Prepending code to a command works in many case, appending is typically much more dangerous as quite often the command is still looking for arguments. See Commands that look ahead in the ltcmdhooks documentation.
Too bad: it used to work with older versions of hyperref.
What do you mean with it has not effect? If I use an existing list, like e.g. lof it works fine for me.
That's because it is provided by default for the figures. But that's not the case for the lists of
tcolorbox“theorems“:
Well sure, I used lof for the test because it is already there. But if I add to your example
\makeatletter
\AddToHook{cmd/@chapter/before}{%
\addtocontents{dbwarninglist}{\protect\addvspace{10\p@}}%
}{}{}
\makeatother
I get

So where is your problem?
Too bad: it used to work with older versions of hyperref.
Yes, but as soon as any package (or a user) had loaded nameref earlier it would have broken too. So it was very fragile. If you want to patch \@chapter with \xapptocmd then do it early. Your package is probably loaded before hyperref, so do the patch directly. Don't delay it behind hyperref.
Btw: the newest hyperref allows to suppress the sectioning patches. See section 4.4 "Patches and how to suppress them" in the documentation. I actually hope that classes take this over and add the needed targets themselves so that those patches can be removed from hyperref.
[...]
So where is your problem?
I'm confused: that works perfectly. Sorry for the noise!
Too bad: it used to work with older versions of hyperref.
Yes, but as soon as any package (or a user) had loaded nameref earlier it would have broken too. So it was very fragile. If you want to patch
\@chapterwith\xapptocmdthen do it early. Your package is probably loaded beforehyperref, so do the patch directly. Don't delay it behindhyperref.
Okay.
Btw: the newest hyperref allows to suppress the sectioning patches. See section 4.4 "Patches and how to suppress them" in the documentation. I actually hope that classes take this over and add the needed targets themselves so that those patches can be removed from hyperref.
I'm sorry, but I'm not sure to understand: in the present case, what am I supposed to do?
BTW, the first sentence of this section starts with “The patches to external commands made by hyperref can be avoided in toto”: “toto”?