0

I'm a LaTeX newbie.

I have a custom macro called \gloss that decorates its argument in a certain way - let's say that it adds a star symbol for the purpouse of the MWE.

I have wrapped it around a \onetimegloss macro that only calls it for the first occurrence in the document.

Why doesn't it work inside \section{} and \caption{}, and it complains about an extra }, though?

(Leaving aside the fact that it would be much more convenient to use a pre-made glossary package, that is.)

\documentclass[10pt,a4paper]{article}
\usepackage{ifthen}
\newcommand{\true}{1}
\newcommand{\false}{0}

\usepackage{pifont}
\newcommand{\gloss}[1]{#1\textsuperscript{\ding{72}}}

\def\addvalue#1{\expandafter\gdef\csname    my@data@\detokenize{#1}\endcsname{\true}}

\def\usevalue#1{%
  \ifcsname my@data@\detokenize{#1}\endcsname\true\else\false\fi
}

\newcommand{\onetimegloss}[1]{
    \ifthenelse{
        \equal{\usevalue{#1}}{\true}
    }
    {#1}
    {\gloss{#1}\addvalue{#1}}
}

\begin{document}

\onetimegloss{foo}
\onetimegloss{bar}
\onetimegloss{foo}
\onetimegloss{bar}
\onetimegloss{baz}
% this outputs foo* bar* foo bar baz*

\section{\gloss{bam}}
This works ok

\section{\onetimegloss{foo}}
This breaks :(

\end{document}

This results in:

! Undefined control sequence.
<argument> \equal
{\usevalue {foo}}{\true }
l.34 \section{\onetimegloss{foo}}
The control sequence at the end of the top line
of your error message was never \def'ed. If you have
misspelled it (e.g., `\hobx'), type `I' and the correct
spelling (e.g., `I\hbox'). Otherwise just continue,
and I'll forget about whatever was undefined.
! Argument of \@tempc has an extra }.
<inserted text>
\par
l.34 \section{\onetimegloss{foo}}
I've run across a `}' that doesn't seem to match anything.
For example, `\def\a#1{...}' and `\a}' would produce
this error. If you simply proceed now, the `\par' that
I've just inserted will cause me to report a runaway
argument that might be the root of the problem. But if
your `}' was spurious, just type `2' and it will go away.
Runaway argument?
{\TE@neg }\def \@tempb {\@tempc }\ifx \@tempa \@tempb \toks@ \expandafter     \ETC.
! Paragraph ended before \@tempc was complete.
<to be read again>
\par
l.34 \section{\onetimegloss{foo}}
I suspect you've forgotten a `}', causing me to apply this
control sequence to too much text. How can we recover?
My plan is to forget the whole thing and hope for the best.
  • 2
    @Andrew Not in this case: everything is being done using \csname – Joseph Wright Jul 4 '15 at 10:26
  • 4
    The argument of section is used in more than one place. It can wander in the header and the toc. Some commands ("fragile commands") can break in this case. Either use \protect\onetimegloss{foo}, or \section[text for toc and header]{\onetimegloss{foo}}, or \DeclareRobustCommand{\onetimegloss}[1]{...}. – Ulrike Fischer Jul 4 '15 at 10:27
  • @UlrikeFischer thanks, \DeclareRobusCommand solved my problem, if you post this as an answer I'll accept it. But could you elaborate a bit on what is actually happening? Also, is it exceedingly hard to make it decorate the text in \section and \caption too? Thanks :) – Tobia Tesan Jul 4 '15 at 10:33
3

The argument of section is used in more than one place. It can wander in the header and the toc. Some commands ("fragile commands", see http://www.tex.ac.uk/cgi-bin/texfaq2html?label=protect) can break in this case.

Either use

\protect\onetimegloss{foo}

or

\section[text for toc and header]{\onetimegloss{foo}}

or define a robust command with

\DeclareRobustCommand{\onetimegloss}[1]{...}

Be aware that the first glossary call can then be in the table of contents.

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.