[Tex/LaTex] How to use nameref to refer to a section without including the output of any commands in the title of that section

cross-referencinghyperreftodonotes

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}
\usepackage[colorlinks,linkcolor=blue]{hyperref}

\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):

A screenshot of the output from the MWE demonstrating the problem

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.

Best Answer

A simplified version of Stefan Lehmke's solution:

\documentclass{article}

\usepackage{etoolbox}
\usepackage{todonotes}
\usepackage[colorlinks,linkcolor=blue]{hyperref}

\makeatletter
\newcommand\@namedisablecommands{}
\newcommand{\addnamedisablecommand}[1]{%
  \g@addto@macro\@namedisablecommands{\renewcommand#1{}}%
  \pdfstringdefDisableCommands{\renewcommand#1{}}%
}
\AtBeginDocument{ 
  \patchcmd{\T@nameref}
  {\let\label\@gobble}
  {\let\label\@gobble\@namedisablecommands}
  {}{}
}
\makeatother

\addnamedisablecommand{\todo[2][]}

Notice the changed syntax; to keep Stefan's write

\newcommand{\addnamedisablecommand}[2]{%
  \g@addto@macro\@namedisablecommands{\renewcommand#1#2{}}%
  \pdfstringdefDisableCommands{\renewcommand#1#2{}}%
}

instead.

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.