TransWikia.com

How to hypertarget a numbered section?

TeX - LaTeX Asked on April 26, 2021

I want to hypertarget some of my sections. I know I could label them or hypertarget right before them, but this is part of a larger framework and I don’t want to treat the case where the target happens to be a section title differently.
Here is my minimal example, it works with section* but it doesn’t with section. Why?

documentclass[a4paper,12pt]{article}
usepackage[pdfstartview=FitH]{hyperref}
usepackage{bookmark}
begin{document}

section*{onehypertarget{sec:one}{}}
bookmark[dest=sec:one]{sec one}

section{twohypertarget{sec:two}{}}
bookmark[dest=sec:two]{sec two}

end{document}

ps: fantastic, neither hypertarget nor section are valid tags. somebody please insert something useful in there.

edit: incorparating texorpdfstring the above minimal example works, but as ususal it was too minimal, my production code doesnt compile. i created a minimal example closer to the real use, it creates a correct file but with a lot of error messages, the terrible anonymous undefined control sequence on the line the macro is used. how can i debug this error message? can someone tell me what is wrong with the code?

documentclass[a4paper,12pt]{article}
usepackage{amsmath}
usepackage[pdfstartview=FitH]{hyperref}
usepackage[atend]{bookmark}
newcounter{nops}
makeatletter
newcommand{nopimpl}{stepcounter{nops}Hy@raisedlink{hypertarget{noparabic{nops}}{}}begingroupedefx{endgroupnoexpandBookmarkAtEnd{noexpandbookmark[dest=noparabic{nops}]{page arabic{nops}}}}x}
newcommand{nop}{texorpdfstring{iffirstchoice@nopimplfi}{}}
makeatother
begin{document}

section{onenop}
section{twonop}

end{document}

edit2: thanks again. now those errors are gone, but in the real file there is a toc, and the toc items get their own target. how can i prevent that?

also how come robustness is only a matter of declaration? i thought it should be a property of the code that is to be executed. if i can simply declare stuff robust, why doesnt latex make everything robust?

documentclass[a4paper,12pt]{article}
usepackage{amsmath}
usepackage[pdfstartview=FitH]{hyperref}
usepackage[atend]{bookmark}
newcounter{nops}
makeatletter
DeclareRobustCommand{nopimpl}{stepcounter{nops}Hy@raisedlink{hypertarget{noparabic{nops}}{}}begingroupedefx{endgroupnoexpandBookmarkAtEnd{noexpandbookmark[dest=noparabic{nops}]{page arabic{nops}}}}x}
DeclareRobustCommand{nop}{texorpdfstring{iffirstchoice@nopimplfi}{}}
makeatother
begin{document}
tableofcontents
section{onenop}
section{twonop}
end{document}

2 Answers

The content of normal sectioning macros like section is called a moving argument because it also moves from its normal location to other places, namely the table of contents and to the PDF bookmark sidebar. For this is is written to some auxiliary files (.aux, .out) and is expanded in this process. Only robust macros which don't mind getting expanded work here and other fragile macros must be protected by placing protect before them. Also some material is not allowed in PDF bookmarks (e.g. some math symbols). The hyperref package provides texorpdfstring{<tex>}{<pdf>} which can be used to select different text for the document and PDF bookmarks. So you could use section{twotexorpdfstring{protecthypertarget{sec:two}{}}{}} to only have the hypertarget in the document but not in the PDF bookmark where it doesn't make sense. Another option is to use the optional argument of section to provide an alternative text for the ToC and PDF bookmarks.

documentclass[a4paper,12pt]{article}
usepackage[pdfstartview=FitH]{hyperref}
usepackage{bookmark}
begin{document}

section*{onehypertarget{sec:one}{}}
bookmark[dest=sec:one]{sec one}

section{twotexorpdfstring{protecthypertarget{sec:two}{}}{}}
bookmark[dest=sec:two]{sec two}

section[three]{threehypertarget{sec:three}{}}
bookmark[dest=sec:three]{sec three}

end{document}

To answer your updated answer:
As mentioned all macros used in moving arguments must be robust to not cause trouble. This can be achieved by using protect in front of it, i.e. section{oneprotectnop} or by defining nop robust from the start by using DeclareRobustCommand instead of newcommand. One problem is that the nop will also be used in the ToC, so you should define nop first to be empty and redefine it after the tableofcontents. You could use g@addto@macro to add the definition code to this macro.

documentclass[a4paper,12pt]{article}
usepackage{amsmath}
usepackage[pdfstartview=FitH]{hyperref}
usepackage[atend]{bookmark}
newcounter{nops}
makeatletter
DeclareRobustCommand{nopimpl}{stepcounter{nops}Hy@raisedlink{hypertarget{noparabic{nops}}{}}begingroupedefx{endgroupnoexpandBookmarkAtEnd{noexpandbookmark[dest=noparabic{nops}]{page arabic{nops}}}}x}
newcommand{nop}{}
g@addto@macro{tableofcontents}{DeclareRobustCommand{nop}{texorpdfstring{iffirstchoice@nopimplfi}{}}}

makeatother
begin{document}
tableofcontents

section{onenop}
section{twonop}

end{document}

You might also just define some macro mysection[2]{section[#1]{#1#2} and use it like mysection{section text}{nop}. This would avoid some of the trouble.

Correct answer by Martin Scharrer on April 26, 2021

try this one: section[two]{twohypertarget{sec:two}{}}

Answered by user2478 on April 26, 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