2

I wrote some commands, recently adding some convenience command \FS to add figure sources:

\newcommand{\FS}[1]{%
\protect\\{\protect\scriptsize{}Bildquelle: #1}}

I don't know whether this is correct (all those \protect), but it seems to work inside \caption. Unfortunately I tried to improve the command, adding an optional parameter:

\newcommand{\FS}[2][Bildquelle]{%
\protect\ifthenelse{\equal{#1}{}}%
\protect\\{\protect\scriptsize{}#2}
\protect\\{\protect\scriptsize{}#1: #2}}

When using the variant with no optional parameter specified, the effect is that expanded #2 is output, followed by expanded Bildquelle: #2 (Actually even when specifying the optional parameter the output is duplicated as described). For example:

Example showing duplicate expanded <code>#2</code>

I'm not deep enough into TeX to to able to fix the problem myself, even after reading those answers on \protect. How should the command be written?

4
  • 1
    Try \newcommand{\FS}[2][Bildquelle]{% \protect\ifthenelse{\equal{#1}{}}{% \protect\\{\protect\scriptsize{}#2}}{% \protect\\{\protect\scriptsize{}#1: #2}}}.
    – user194703
    Commented Nov 29, 2019 at 23:33
  • One pair of braces to rule them all ;-) That did it, thanks!
    – U. Windl
    Commented Nov 29, 2019 at 23:40
  • Is \DeclareRobustCommand available in all environments, or do I need spacial packages for it? My LaTeX knowledge is a bit outdated...
    – U. Windl
    Commented Nov 30, 2019 at 1:31
  • @U.Windl I just deleted my answer (which also cancelled any reputation-gainings) as it is obsolete: As I overlooked and as egreg pointed out in a comment to my answer, commands defined in terms of \newcommand are already made robust in case of having an optional argument. Thus all the \DeclareRobustCommand-thingies shown in my (now deleted) answer aren't needed at all. Sorry for the noise. Commented Nov 30, 2019 at 9:06

1 Answer 1

4

Note that \ifthenelse{<condition>}{<true>}{<false>} requires <true> and <false> to be grouped. If not, the two tokens following the <condition> are assumed to denote <true> and <false>. In your setup, <true> is \protect and \\ is <false>. You were probably looking for something like

\newcommand{\FS}[2][Bildquelle]{%
  \protect\ifthenelse{\equal{#1}{}}%
    {\protect\\{\protect\scriptsize{}#2}}
    {\protect\\{\protect\scriptsize{}#1: #2}}}

Using the conditional test in How to check if a macro value is empty or will not create text with plain TeX conditionals?, you can instead define \FS to be

\newcommand{\FS}[2][Bildquelle]{%
  \\
  \scriptsize
  \if\relax\detokenize{#1}\relax\else
    #1: 
  \fi
  #2%
}

Here's a complete minimal example of the use:

enter image description here

\documentclass{article}

\usepackage{caption}

\newcommand{\FS}[2][Bildquelle]{%
  \\
  \scriptsize
  \if\relax\detokenize{#1}\relax\else
    #1: 
  \fi
  #2%
}

\begin{document}

\begin{figure}
  \caption{Some caption. \FS{abc}}
  \caption{Another caption. \FS[abc]{def}}
  \caption{Final caption. \FS[]{ghi}}
\end{figure}

\end{document}

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .