12

Why is the following minimal example not working?

I.e., what do I need to do, in order to define the float placement specifier of a figure within a macro? (I know that I should use \newcommand, but in the "full" example the error is part of an involved "superfigure" command. \newcommand is not working too btw.)

\documentclass{scrreprt}
\usepackage{blindtext}

\def\PosNotWorking{h}
\def\FramboxNotWorking{5cm}
\def\CaptionWorking{Caption is working.}

\begin{document}

\Blindtext[1]

\begin{figure}[\PosNotWorking]
  \centering
    \framebox[5cm]{My special figure. (Pos: \PosNotWorking)}        
    \caption{\CaptionWorking}
\end{figure}

\Blindtext[1]

\end{document}

If I compile this, the figure is at the top (default behaviour). If I enter \figure[h] instead of \figure[\PosNotWorking], the figure is of course between the two paragraphs.

0

3 Answers 3

12

The optional argument is not expanded, but used inside a loop which checks every containing letter. In your case it sees only the macro not the included letter. However, if you want to simply change the default positioning you can do this by redefining \fps@figure (for tables \fps@table):

\makeatletter
% Make all figure use 'h' position by default:
\def\fps@figure{h}
\makeatother

If you don't want to change it globally AND still want to use a \begin{figure} environment you could use \edef to expand it first:

\documentclass{scrreprt}
\usepackage[english]{babel}
\usepackage{blindtext}

\def\PosNowWorking{h}
\def\FramboxNotWorking{5cm}
\def\CaptionWorking{Caption is working.}

\begin{document}

\Blindtext[1]

\edef\efigure{\noexpand\begin{figure}[\PosNowWorking]}%
\efigure
  \centering
    \framebox[5cm]{My special figure. (Pos: \PosNowWorking)}        
    \caption{\CaptionWorking}
\end{figure}

\Blindtext[1]

\end{document}

or:

\def\efigure{\begin{figure}}%
\expandafter\efigure\expandafter[\PosNowWorking]

Or redefine the figure environment to expand its optional argument first:

\let\origfigure\figure
\let\endorigfigure\endfigure
\renewenvironment{figure}[1][h]{%
   \expandafter\origfigure\expandafter[#1]%
}{%
   \endorigfigure
}

This way you can also easily set h as default value or put \PosNowWorking in there.

5
  • Thanks. No I don't want to set the default. I want to hand the position over to a "superfigure" using the keyval package.
    – B3ret
    Commented Feb 17, 2011 at 19:22
  • @B3ret: See my updated answer Commented Feb 17, 2011 at 19:33
  • The second thing is perfect for me. I set h default anyway using the xkeyval package. Your answer is more elaborate, so I switched the checkmark to you.
    – B3ret
    Commented Feb 17, 2011 at 19:44
  • @MartinScharrer The \edef solution works great! Though I think the last one would be more elegant. Unfortunately, I can't seem to get it to work. If I put the redefinition in the preamble of the document, how should I call the new figure environment? The command \begin{figure}{\PosNotWorking} does not seem to work.
    – Adriaan
    Commented Oct 26, 2013 at 10:28
  • 1
    @Adriaan: The syntax is as normal: \begin{figure}[\PosNotWorking]. You used { } instead of [ ]. Commented Oct 27, 2013 at 23:23
2

Redefine the \begin{figure} and end{figure} as shown below:

\documentclass{article}
\usepackage[english,ngerman]{babel}
\usepackage{blindtext}

\def\beginmyfigure#1{\begin{figure}[#1]}
\def\endmyfigure{\end{figure}}

\def\FramboxNotWorking{5cm}
\def\CaptionWorking{Caption is working.}

\begin{document}

\Blindtext[1]

\beginmyfigure{b}
  \centering
    \framebox[5cm]{My special figure. (Pos: )}        
    \caption{\CaptionWorking}
\endmyfigure

\Blindtext[1]

\end{document}
1
  • Unfortunately that is not an option. The above was just an minimal example. I really need the figures environment. The real stuff I'm working on has for example subfigures, it should float for sure too.
    – B3ret
    Commented Feb 17, 2011 at 19:07
1

try it this way;

\documentclass{scrreprt}
\usepackage[english]{babel}
\usepackage{blindtext}

\def\PosNotWorking{h}
\def\FramboxNotWorking{5cm}
\def\CaptionWorking{Caption is working.}

\begin{document}

\Blindtext[1]

\expandafter\figure\expandafter[\PosNotWorking]
  \centering
    \framebox[5cm]{My special figure. (Pos: \PosNotWorking)}        
    \caption{\CaptionWorking}
\endfigure

\Blindtext[1]

\end{document}

The optional argument isn't expanded by default

6
  • \expandafter\figure[\PosNotWorking] -> not working, \figure\expandafter[\PosNotWorking] -> puts an additional [h] before the fbox, but does not change the floating, \figure[\expandafter\PosNotWorking] -> not working. Thanks anyway.
    – B3ret
    Commented Feb 17, 2011 at 19:09
  • @B3ret: It's \expandafter\figure\expandafter[\PosNotWorking], exactly like Herbert wrote it. Commented Feb 17, 2011 at 19:13
  • You two are right. I did \expandafter\begin{figure}\expandafter[\PosNotWorking] instead of what you said. Is there any difference between \begin{figure} and \figure?
    – B3ret
    Commented Feb 17, 2011 at 19:18
  • @B4ret: In short \begin{xxx} opens a group (like \begingroup) and then calls \xxx. Note that \expandafter only jumps over one token (e.g. macro, brace or letter). \figure is one token, \begin{figure} are nine (1 macro, 2 braces, 6 letters). Commented Feb 17, 2011 at 19:24
  • So I could write '\begingroup\expandafter\figure\expandafter[...]...\endfigure\endgroup to be safe?
    – B3ret
    Commented Feb 17, 2011 at 19:34

You must log in to answer this question.

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