TeX - LaTeX Asked by Gooz on July 20, 2021
Suppose I define a custom command exercise
as follows.
newcounter{exercise}
newcommandexercise{%
refstepcounter{exercise}%
section*{Exercise theexercise}%
}
Now, in the following example, I want to use nameref
from the hyperref
package.
exerciselabel{ex:first}
foo
exerciselabel{ex:second}
see nameref{ex:first}
exerciselabel{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}
newcommandexercise{%
refstepcounter{exercise}%
section*{Exercise theexercise}%
}
begin{document}
exerciselabel{ex:first}
foo
exerciselabel{ex:second}
see nameref{ex:first}
exerciselabel{ex:third}
bar
end{document}
Indeed, you need to pass the expansion of theexercise
, because hyperref
doesn't do it to the title.
documentclass{article}
usepackage{hyperref}
newcounter{exercise}
newcommandexercise{%
par % just in case
refstepcounter{exercise}%
begingroupedefx{endgroup
noexpandsection*{unexpanded{Exercise} theexercise}%
}x
}
begin{document}
exerciselabel{ex:first}
foo
exerciselabel{ex:second}
see nameref{ex:first}
exerciselabel{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}
newcommandexercise{%
par % just in case
refstepcounter{exercise}%
section*{Exercise theexercise}
}
crefname{exercise}{Exercise}{Exercises}
begin{document}
exerciselabel{ex:first}
foo
exerciselabel{ex:second}
see cref{ex:first}
exerciselabel{ex:third}
bar
end{document}
The output is the same in both cases.
Can we avoid the edefx{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}
exerciselabel{ex:first}
foo
exerciselabel{ex:second}
see cref{ex:first} or nameref{ex:first}
exerciselabel{ex:third}
bar
end{document}
Note that cleveref
is not necessary, just remove the relevant calls if you prefer nameref
.
Correct answer by egreg on July 20, 2021
Get help from others!
Recent Answers
Recent Questions
© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP