# How to use nameref to refer to a section without including the output of any commands in the title of that section?

## Background (simplified)

I'm using the todonotes package to add todonotes to sections in my documents. I have created a macro to add the todonotes to sections such that they appear alongside the section's entry in the table of contents. I am also using the nameref macro from the hyperref package to refer to various sections of my document by name. Partly because of this, my macro also allows a label to be specified for the section. Here's a somewhat simplified version of the output my macro produces:

\section[{\todo{A todonote about the foo section}}{foo}]{foo}%
\label{sec:foo}


## The problem

The trouble with this is that when using the \nameref to refer to a section with a todonote contained in the title, as above, the todonote also gets attached to the reference.

### MWE:

\documentclass{article}

\usepackage{todonotes}

\begin{document}

\tableofcontents

\section{foo}
\begin{itemize}
\item A reference to the \nameref{sec:bar} section
\end{itemize}

\section[{\todo{A todonote about the bar section}}{bar}]{bar}
\label{sec:bar}
A section called bar

\section{baz}
A section called baz

\end{document}


Which produces (after three or four compiles/builds for good measure):

### What's happening:

So the call to \nameref{sec:bar} is presumably producing a reference which includes {\todo{A todonote about the bar section}}{bar} and todonotes is (correctly but undesirably) producing a duplicate todonote because of this. To clarify, I would like the reference to the bar section to be produced as just bar without the duplicate todonote.

## Approach to finding a solution

Although this is my use case, I would prefer to know how to make nameref ignore any commands within the section title as I feel this would probably be more generally useful (and not just for me).

As a side note, an alternative solution to ignoring the commands could possibly be to define some nameref-specific reference text for the section somehow. However, this is less desirable as it would require a little maintenance to keep it relevant to the section name.

-
@lockstep: Just curious, what's the notes tag intended to be used for/mean? (Is it in reference to the todonotes package?) – Staves Mar 25 '12 at 0:08
In a sense, yes, but I chose the more general tag. Feel free to replace notes with todonotes. – lockstep Mar 25 '12 at 0:10
@lockstep: Ah ok, thanks. I think I shall change it as, although todonotes shows the problem I'm having with nameref, it's not actually the cause. There may be a todonotes related solution, but it's not really a notes(-caused) problem, if that makes sense. – Staves Mar 25 '12 at 0:17
@Staves Please, keep Stefan's as the accepted answer. – egreg Mar 25 '12 at 16:40
@egreg: Although I'm not sure if this might be slightly against the consensus on accepting solutions (somewhat relevant - meta.tex.stackexchange.com/q/535/11869) I strongly agree that Stephan deserves a lot of credit. If you're saying that this is cool then I shall leave it as it (now) is, otherwise I shall accept your answer so that it will be the first a new user/visitor sees. – Staves Mar 25 '12 at 17:57

A simplified version of Stefan Lehmke's solution:

\documentclass{article}

\usepackage{etoolbox}
\usepackage{todonotes}

\makeatletter
\newcommand\@namedisablecommands{}
\pdfstringdefDisableCommands{\renewcommand#1{}}%
}
\AtBeginDocument{
\patchcmd{\T@nameref}
{\let\label\@gobble}
{\let\label\@gobble\@namedisablecommands}
{}{}
}
\makeatother



Notice the changed syntax; to keep Stefan's write

\newcommand{\addnamedisablecommand}[2]{%
\pdfstringdefDisableCommands{\renewcommand#1#2{}}%
}


After doing this, \@namedisablecommands will expand to

\renewcommand\todo[2][]{}


which will neutralize its expansion. The warning

Package hyperref Warning: Token not allowed in a PDF string (PDFDocEncoding):
(hyperref)                removing \todo' on input line 47.


is avoided by adding \todo (or other similar commands) in the disabled command list for hyperref.

-
That's really much simpler ;-) – Stephan Lehmke Mar 25 '12 at 16:34
@StephanLehmke Yours was a very good inspiration. – egreg Mar 25 '12 at 16:40
Just saw egreg's comment on the question, so leaving Stephan's answer as the accepted one. (@StephanLehmke) – Staves Mar 25 '12 at 17:33
Really neat solution! I'm very interested in finding out if the method you and @StephanLehmke propose can be extended to limiting the scope of commands other than \T@nameref. I currently have a bounty on an open question that concerns, in part, limiting the scope of a TeX macro that invokes some lua code; see tex.stackexchange.com/q/48516/5001. Any and all help would be very much appreciated. – Mico Mar 26 '12 at 13:21
I already saw your comment, but I doubt there is a connection. What we did here is a rather standard method for deactivating commands which have "moved" to a place they don't belong, because like in this case they are part of some section heading or such which gets saved by nameref. This is well-known for instance in the context of \pdfstringdefDisableCommands. Unfortunately, I don't see a connection with your case (protect macro names and arguments from search/replace). – Stephan Lehmke Mar 26 '12 at 13:34

Interestingly, \nameref seems to know there are some things which should be disabled (for instance, \label), but it doesn't offer an interface for adjusting it.

Hence, patching seems to be a solution. I repeat the full example:

\documentclass{article}

\usepackage{etoolbox}
\usepackage{todonotes}

\makeatletter
\newcommand\@namedisablecommands{}%
\newcount\@namedisablegenericmacro
{%
\expandafter\newcommand
\csname @namedisablegobble\number\@namedisablegenericmacro\endcsname
#2{}%
\global\expandafter\let
\csname @namedisablegobble\number\@namedisablegenericmacro\expandafter\endcsname
\csname @namedisablegobble\number\@namedisablegenericmacro\endcsname
\edef\@namedisablecommands{%
\unexpanded\expandafter{\@namedisablecommands}%
\let\noexpand#1\expandafter\noexpand
\csname @namedisablegobble\number\@namedisablegenericmacro\endcsname
}%
}
\AtBeginDocument
{%
\patchcmd{\T@nameref}
{\let\label\@gobble}
{\let\label\@gobble\@namedisablecommands}
{}{}%
}
\expandafter\pdfstringdefDisableCommands\expandafter
{%
\@namedisablecommands
}%
\makeatother
\begin{document}

\tableofcontents

\section{foo}
\begin{itemize}
\item A reference to the \nameref{sec:bar} section
\end{itemize}

\section[{\todo{A todonote about the bar section}}{bar}]{bar}
\label{sec:bar}
A section called bar

\section{baz}
A section called baz

\end{document}


-
+1 for mentioning that \nameref has built-in functionality to keep it from operating on certain commands, such as \label. – Mico Mar 25 '12 at 10:20
Thanks for this, I have accepted it as it does indeed solve the problem I am experiencing. Presumably this could also be expanded to ignore/gobble any number of commands? – Staves Mar 25 '12 at 12:17
@Staves: Exactly, you can iterate the patch as often as you wish. – Stephan Lehmke Mar 25 '12 at 12:21
Nice one :) Could the \let and \@gobble surrounding \todo be moved into the \addnamedisablecommand macro (around the #1)? - This works for me with \todo` it but I'm not sure if there might be ramifications with other commands and so on... – Staves Mar 25 '12 at 13:04
I thought about that, but the next step of abstraction is a lot more effort. The main complication is to handle commands with differing numbers of arguments. – Stephan Lehmke Mar 25 '12 at 13:13