# Pass a command as optional argument of environment

Sorry for the beginner question, but I'd like to know if there is a robust way to do what the title says. The following MWE

\documentclass{book}

\usepackage[demo]{graphicx}
\newcommand{\myoptions}{h!tb}

\begin{document}

\begin{figure}[\myoptions]
\centering
\includegraphics[width=0.5\textwidth]{whatever}
\caption[Short caption citing something]{Long caption.}
\label{fig:whatever}
\end{figure}

\end{document}


gives the error ! LaTeX Error: Unknown float option '\'..

Actually I found a workaround (in my actual document the \figure environment is used by a new command that takes many parameters needed to define a figure and puts them inside \figure), but it gives problems with \cite command inside short caption, that's why I'm looking for a robust solution.

SOLUTION

Here is the solution to this question, that was given as a comment to the accepted answer:

\documentclass{book}

\usepackage[demo]{graphicx}
\newcommand{\myoptions}{h!tb}

\def\tmp#1{\begin{figure}[#1]}% use tmp, in the form below, as many times as needed

\begin{document}

\expandafter\tmp\expandafter{\myoptions}
\centering
\includegraphics[width=0.5\textwidth]{whatever}
\caption[Short caption citing something]{Long caption.}
\label{fig:whatever}
\end{figure}

\end{document}

• There are some technical issues why it doesn't work (it has never been supported syntax in latex2e) but you should never need to do this anyway. the optional argument (and especially !) are for one-off special cases where you need to fine-tune and over-ride the defaults. there should never be a need to automate over-riding the default. If the default for a document type should be htb then define fps@figure to be htb and then no optional argument is needed to set that. – David Carlisle Sep 28 '15 at 11:35
• How do I set fps@figure to some value? – mmj Sep 28 '15 at 14:12
• \makeatletter (or be inside a package file) then \renewcommand\fps@figure{htp} – David Carlisle Sep 28 '15 at 14:15
• Your "follow up" edit is impossible to understand. The optional argument of figure has no effect on the optional argument of \cite. But if you want help with that do not edit the question to ask an unrelated question, ask a new question and with a new the example demonstrate the error for which you want to get help – David Carlisle Sep 28 '15 at 14:19
• @DavidCarlisle I agree, I deleted the follow up, and posted another question about the problem of citation in short caption: tex.stackexchange.com/q/269972/28685 – mmj Sep 28 '15 at 19:26

The fact that you get an error in the texlive 2015 release but not earlier ones is due to it including fixes from the old fixltx2e package.

In earlier releases

\newcommand{\myoptions}{h!tb}
\begin{figure}[\myoptions]


Then \myoptions is not expanded and is just taken as the sequence of options \,m,y,o,p,t,i,o,n,s unknown options were silently ignored so this is equivalent to [pt] not, as you might expect from the definition, to [h!tb].

\newcommand{\foo}{h!tb}
\begin{figure}[\foo]


then since no legal option is included (just\, f and two o), the figure is not allowed anywhere and so will always go to the end of the document or \clearpage.

The change in the 2015/01/01 release is that an error is raised for undefined float placement options so here you get an error on \.

• Any clue on how to make \myoptions expand before \begin{figure} so that it can be used as an argument? – mmj Sep 30 '15 at 0:25
• @mmj yes, although as I said in a comment on the question you should never need to do this. \def\tmp#1{\begin{figure}[#1]}\expandafter\tmp\expandafter{\myoptions} would work though. – David Carlisle Sep 30 '15 at 6:47

This is due to an undocumented feature of the most recent release of LaTeX, since running the example with TeX Live 2014 doesn't raise the error. But no error doesn't mean it worked.

Building on the code I proposed for Referring to delimiter separated arguments in new commands, here's a possibility, where the placement options are in leading position.

\documentclass{article}

\usepackage{graphicx}
\usepackage{xparse}

\NewDocumentCommand{\myfigure}{O{!htbp}mommo}{%
\begin{figure}[#1]
\centering
\includegraphics[width=#5]{#2}
\IfNoValueTF{#3}{\caption{#4}}{\caption[{#3}]{#4}}
\IfValueT{#6}{\label{#6}}
\end{figure}
}

\begin{document}

\listoffigures

\section{Test}

Text

\myfigure{example-image-a}[Short]{Long}{.4\textwidth}

\myfigure{example-image-b}{Long2}{.4\textwidth}[label1]

Text

\myfigure[p]{example-image-c}{Long2}{.8\textwidth}[label2]

\end{document}


In order to answer the “abstract” question, a robust way for passing the macro as the optional argument is to reset \fps@figure:

\begingroup\makeatletter\let\fps@figure\myoptions\makeatother
\begin{figure}
...
\end{figure}
\endgroup


Of course, this would be hidden in some macro:

\newcommand\myoptions{!htbp}

\makeatletter
\newcommand{\myfigure}[<n>]{%
\begingroup\let\fps@figure\myoptions
\begin{figure}
...
\end{figure}
\endgroup
}
\makeatother


In case you want to have !htbp as default placement specifier for all figure environments, just issue

\makeatletter
\renewcommand*{\fps@figure}{!htbp}
\makeatother

• Glad to know that this behaviour is due to a bug. Unfortunately the solution you propose still has the problem that \cite commands in short caption are ignored (while argument of \cite is displayed in list of figures as text). The strange is that if in the new command you use \begin{figure} instead of \begin{figure}[#1], citing in short caption works. – mmj Sep 28 '15 at 10:57
• @mmy actually this isn't a bug (or really a change in behaviour). – David Carlisle Sep 28 '15 at 11:36
• @mmj I added \cite in both the short and the long captions and I have no problem whatsoever. – egreg Sep 28 '15 at 15:27
• @egreg I tracked down the specific problem of citation in short caption, I posted another question: tex.stackexchange.com/q/269972/28685 – mmj Sep 28 '15 at 19:25