0

Some time ago I used user Werner's solution provided here:

https://tex.stackexchange.com/a/582389

in one of my own documents. Specifically, the goal was to make the part number and the part title in the table of contents appear centered and on separate lines, instead of how it is by default (aligned left and all on one line). The solution worked perfectly.

Unfortunately, the machine I used to originally produce the document recently died, forcing me to get a new machine and do a fresh install of LaTeX (TeXstudio with MiKTeX).

Now, when I try to build the same document again, the above solution no longer works and the part title appears as it normally does by default. If it's relevant, I last successfully built the document on my previous machine - when Werner's solution worked fine - about two weeks ago.

To diagnose the problem (yet unsolved) I compiled Werner's MWE verbatim and this is the output:

enter image description here

Observe how, unlike Werner's output, the part is not centered and appears entirely on one line.

I have attempted to use various TeX engines (pdfLaTeX, XeLaTeX, etc.) but all give the same output. Otherwise, unless I did something without realising it, I am using TeXstudio and MiKTeX as they were installed with no re-configuration. I have, however, installed various packages (quite a lot - it's a big document, a book, so I'd prefer not to list them all unless necessary) which were used as part of the original document. They didn't create this problem before, so I don't know why they would be causing problems now.

I believe I have identified the problem as being something wrong with \patchcmd. I inserted \tracingpatches into Werner's solution as follows:

...
% \parts in ToC
\renewcommand{\cftpartfont}{\large\bfseries\ttfamily}
\makeatletter
\tracingpatches
% \patchcmd{<cmd>}{<search>}{<replace>}{<success>}{<failure>}
...

which gives the output:

[debug] tracing \patchcmd on input line 11
[debug] analyzing '\H@old@part'
[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

So it would seem that the search pattern (or the replacement text?) from Werner's solution is no longer valid. Why this is, I have no idea.

At this point, I am at a loss. I have attempted to see how \H@old@part is defined in hyperref but failed to find the search pattern in the code and otherwise I am not skilled enough with TeX to know what else to search for.

Please can someone help solve this problem? If possible, in addition to a solution, I would be grateful for extra details on what exactly has caused this problem.

P.s. I realise there may be alternative methods of accomplishing my goal, but I would appreciate a solution to this particular problem.

tex_user_
  • 3
  • 1
  • Werner's solution from your link worked fine in my system also MikTeX dist. This is pdfTeX, Version 3.141592653-2.6-1.40.24 (MiKTeX 22.3) and hyperref.sty 2022-02-21 v7.00n – Simon Dispa Oct 26 '22 at 04:56
  • @SimonDispa this is the dist I'm using: This is XeTeX, Version 3.141592653-2.6-0.999994 (MiKTeX 22.10) (preloaded format=xelatex 2022.10.26) 26 OCT 2022 05:16 and hyperref 2022-09-22 v7.00t – tex_user_ Oct 26 '22 at 05:00
  • Add \listfiles before \documentclass{book} and look at the end of the .log file the version of hyperref . Mine says hyperref.sty 2022-02-21 v7.00n Hypertext links for LaTeX. I tried also with This is XeTeX, Version 3.141592653-2.6-0.999994 (MiKTeX 22.3) – Simon Dispa Oct 26 '22 at 05:02
  • @SimonDispa just updated my previous comment with it, here it is also hyperref.sty 2022-09-22 v7.00t – tex_user_ Oct 26 '22 at 05:05
  • 1
    Your are using a newer version of hyperref.Lets wait for other comments – Simon Dispa Oct 26 '22 at 05:07
  • OK, thanks for participating by the way I appreciate it. – tex_user_ Oct 26 '22 at 05:10
  • Well that is the problem with patching internal commands: there is no garanty that such patches work for the eternity. hyperref no longer delays the loading of nameref, and so it is now nameref which patches first. Either patch \NR@part or patch \@part before loading hyperref. Better would be to find a lasting solution which doesn't rely on patching. – Ulrike Fischer Oct 26 '22 at 07:10
  • @UlrikeFischer Thank you very much! I changed the patch to now modify \@part and put it immediately before loading hyperref and now it works exactly like it did before - correctly. I will keep in mind your suggestion to avoid patching, but for now I'll stick with this solution as there is more to how I have used this patch than Werner's simple MWE (I only required the principle of it). P.s. I would happily upvote you but I don't see any option to do that: unfortunately, I think I don't yet have enough reputation to vote. – tex_user_ Oct 26 '22 at 07:44
  • I will add an answer that you can accept. – Ulrike Fischer Oct 26 '22 at 07:44

1 Answers1

2

Well that is the problem with patching internal commands: there is no garanty that such patches work for the eternity.

The reason that the patch no longer works is that hyperref no longer delays the loading of nameref, and so it is now nameref which patches first. Either patch \NR@part or (probably better as there is work under the way to remove the patches from nameref and hyperref anyway) patch \@part before loading hyperref.

Also add a failure command so that you get an error (and so a warning) if the patch fails again:

\patchcmd{\@part}% 
  {\thepart\hspace{1em}#1}% <search>
  {\protect\setpartToC{\thepart}{#1}}% <replace>
  {}{\ERROR}% <success><failure 

Better would be to find a lasting solution which doesn't rely on patching

Ulrike Fischer
  • 327,261