Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

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.

share|improve this question
    
Hi B3ret, please note that you should use back-ticks ` not " to mark you inline code. –  Martin Scharrer Feb 17 '11 at 19:12
    
Thanks for telling me, didn't know that. –  B3ret Feb 17 '11 at 19:23

3 Answers 3

up vote 9 down vote accepted

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.

share|improve this answer
    
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 Feb 17 '11 at 19:22
    
@B3ret: See my updated answer –  Martin Scharrer Feb 17 '11 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 Feb 17 '11 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 Oct 26 '13 at 10:28
1  
@Adriaan: The syntax is as normal: \begin{figure}[\PosNotWorking]. You used { } instead of [ ]. –  Martin Scharrer Oct 27 '13 at 23:23

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}
share|improve this answer
    
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 Feb 17 '11 at 19:07

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

share|improve this answer
    
\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 Feb 17 '11 at 19:09
    
@B3ret: It's \expandafter\figure\expandafter[\PosNotWorking], exactly like Herbert wrote it. –  Martin Scharrer Feb 17 '11 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 Feb 17 '11 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). –  Martin Scharrer Feb 17 '11 at 19:24
    
So I could write '\begingroup\expandafter\figure\expandafter[...]...\endfigure\endgroup to be safe? –  B3ret Feb 17 '11 at 19:34

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.