1

Suppose I define a custom command \exercise as follows.

\newcounter{exercise}
\newcommand\exercise{%
    \refstepcounter{exercise}%
    \section*{Exercise \theexercise}%
}

Now, in the following example, I want to use \nameref from the hyperref package.

\exercise\label{ex:first}
foo

\exercise\label{ex:second}
see \nameref{ex:first}

\exercise\label{ex:third}
bar

This produces "see Exercise 2" instead of "see Exercise 1". It seems like the 'unexpanded' text is used, expanding into the current counter value. How can I make sure that \nameref{ex:first} produces "Exercise 1"?

(Of course, I could just use Exercise~\ref{ex:first}, but this is more error-prone. And, in the future, I may want to replace "exercise" by "problem" without having to find and replace all occurences in my document.)


Full example:

\documentclass{article}

\usepackage{hyperref}

\newcounter{exercise}
\newcommand\exercise{%
    \refstepcounter{exercise}%
    \section*{Exercise \theexercise}%
}

\begin{document}

\exercise\label{ex:first}
foo

\exercise\label{ex:second}
see \nameref{ex:first}

\exercise\label{ex:third}
bar

\end{document}
2
  • 1
    As al sys on the site please provide a full but minimal example not sniplets like this. A full but minimal example enables others to copy and test your exact code and not like here we we have to add a lot of code to even test your problem, code that might be different than yours – daleif Nov 3 '20 at 5:25
  • 1
    @daleif I added a full example – Gooz Nov 3 '20 at 12:39
1

Indeed, you need to pass the expansion of \theexercise, because hyperref doesn't do it to the title.

\documentclass{article}
\usepackage{hyperref}

\newcounter{exercise}
\newcommand\exercise{%
  \par % just in case
  \refstepcounter{exercise}%
  \begingroup\edef\x{\endgroup
    \noexpand\section*{\unexpanded{Exercise} \theexercise}%
  }\x
}

\begin{document}

\exercise\label{ex:first}
foo

\exercise\label{ex:second}
see \nameref{ex:first}

\exercise\label{ex:third}
bar

\end{document}

This is the (abridged) contents of the .aux file:

\newlabel{ex:first}{{1}{1}{Exercise 1}{section*.1}{}}
\newlabel{ex:second}{{2}{1}{Exercise 2}{section*.2}{}}
\newlabel{ex:third}{{3}{1}{Exercise 3}{section*.3}{}}

It was

\newlabel{ex:first}{{1}{1}{Exercise \theexercise }{section*.1}{}}
\newlabel{ex:second}{{2}{1}{Exercise \theexercise }{section*.2}{}}
\newlabel{ex:third}{{3}{1}{Exercise \theexercise }{section*.3}{}}

with your code.

Note. Why \unexpanded{Exercise}? In the particular case it is obviously unnecessary, but it would be for the German “Übung”.


You might use cleveref instead.

\documentclass{article}
\usepackage{hyperref}
\usepackage[nameinlink]{cleveref}

\newcounter{exercise}
\newcommand\exercise{%
  \par % just in case
  \refstepcounter{exercise}%
  \section*{Exercise \theexercise}
}
\crefname{exercise}{Exercise}{Exercises}

\begin{document}

\exercise\label{ex:first}
foo

\exercise\label{ex:second}
see \cref{ex:first}

\exercise\label{ex:third}
bar

\end{document}

The output is the same in both cases.

enter image description here

Can we avoid the \edef\x{\endgroup trick? Yes, of course.

\documentclass{article}
%\usepackage{xparse} % not needed for LaTeX 2020-10-01 or later
\usepackage{hyperref}
\usepackage[nameinlink]{cleveref}

\ExplSyntaxOn
\NewDocumentCommand{\exercise}{}
 {
  \gooz_exercise:ne { \exercisename } { \theexercise }
 }
\cs_new_protected:Nn \gooz_exercise:nn
 {
  \par % just in case
  \refstepcounter{exercise}
  \section*{#1~#2}
 }
\cs_generate_variant:Nn \gooz_exercise:nn { ne }
\ExplSyntaxOff

\newcommand{\exercisename}{Exercise}
\newcounter{exercise}
\crefname{exercise}{\exercisename}{\exercisename s}

\begin{document}

\exercise\label{ex:first}
foo

\exercise\label{ex:second}
see \cref{ex:first} or \nameref{ex:first}

\exercise\label{ex:third}
bar

\end{document}

Note that cleveref is not necessary, just remove the relevant calls if you prefer \nameref.

6
  • if nameref expands or not depends on the option used for gettitlestring. With \PassOptionsToPackage{expand}{gettitlestring} the title is expanded (naturally at the costs that fragile stuff can break). – Ulrike Fischer Nov 3 '20 at 10:31
  • @UlrikeFischer Since what ends up in titles is not known, I'd be wary of using that option. – egreg Nov 3 '20 at 10:39
  • imho it is not really problematic: titles have to be more or less expandable anyway for the bookmarks, and you can control the expansion. See also tex.stackexchange.com/a/66255/2388 – Ulrike Fischer Nov 3 '20 at 10:44
  • 1
    wouldn't it be better to use a numbered section and then just arrange that the heading formatting puts the number last rather than first, rather than using an unnumbered heading and forcing the expansion of the number? (Just leaving it as an exercise for the reader:-) – David Carlisle Nov 3 '20 at 12:39
  • 1
    @Gooz If you forget a blank line before \exercise, the \refstepcounter would be executed as part of the preceding paragraph and probably set an improper anchor. – egreg Nov 3 '20 at 12:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.