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 Nov 29 '19 at 23:33
  • One pair of braces to rule them all ;-) That did it, thanks! – U. Windl Nov 29 '19 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 Nov 30 '19 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. – Ulrich Diez Nov 30 '19 at 9:06
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}

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.