tags:

views:

373

answers:

3

I've been using \begin{figure} ... \end{figure} throughout my LaTeX document, but the default styling is ugly; namely, the figures are all left-aligned. Is there a way to redefine the "figure" environment so it automatically inserts some centering commands such as like this?: \begin{figure} \begin{center} \end{center} \end{figure}

Sure, I could use \newenvironment to define a "cfigure" environment, but that's undesirable. I don't want to go through and change all my "figures" to "cfigures" (and then later realise I wanted all the figures to be right-aligned and have to rename them all to "rfigures"). I could use \renewenvironment, but then I'd have to dig through the LaTeX source to find what the "figure" environment was originally defined as copy/paste it in.

I almost found what I wanted at this blog post, but the example there was for a command, not an environment.

+4  A: 
\let\oldfigure\figure
\def\figure{\oldfigure\centering}

Another solution which works with the optional arguments.

Fixed.

\let\oldfigure\figure
\let\oldendfigure\endfigure
\def\figure{\begingroup \oldfigure}
\def\endfigure{\centering \oldendfigure \endgroup}

Fixed 2. It does work well with any options and any rules and \par inside.

\makeatletter
\let\oldfigure\figure
\def\figure{\@ifnextchar[\figure@i \figure@ii}
\def\figure@i[#1]{\oldfigure[#1]\centering}
\def\figure@ii{\oldfigure\centering}
\makeatother
Alexey Malistov
This doesn't work, because figure takes an optional argument (like [htbp] that will be broken by this redefinition.
Will Robertson
Ummm... Right. I'll rethink
Alexey Malistov
Hmmm, have you tested your new solution? Doesn't seem to work for me.
Will Robertson
(By the way, I made the same mistake when I first started redefining the environment `;)` )
Will Robertson
The second solution doesn't work for me either. The figures aren't being centered. Does anyone have any ideas?
exclipy
Fixed. It is necessary to move "\centering" down.
Alexey Malistov
Still won't work for input like `\begin{figure}\rule{4em}{4em}\par\rule{4em}{4em}\end{figure}`; this only applies `\centering` to the last paragraph. Also, you don't need the groups.
Will Robertson
**Fixed 2.** Now it works.
Alexey Malistov
Aha :) Well done.
Will Robertson
+3  A: 

As noted in another answer, you can't do the old trick of prepending commands to the end of the \figure macro because that will mess up the optional argument processing.

If an environment doesn't have arguments then it will work fine, but otherwise there's no straightforward way of doing this.

For your problem with the figures, try loading the floatrow package:

\usepackage{floatrow}

If will centre the content of your figures automatically.

Update: If you don't want to load a package, here's some code that will also do it. Note that it's specific to the figure environment, but the basic theme is: copy the original definition, parsing arguments the same way, then add whatever code you need at the end.

\makeatletter
\renewenvironment{figure}[1][\fps@figure]{
  \edef\@tempa{\noexpand\@float{figure}[#1]} 
  \@tempa\centering
}{
  \end@float
}
\makeatother

The \edef is required to fully expand \fps@figure before it's passed to the \@float macro.

Will Robertson
I did ask for a solution that doesn't involve copying the definition, but I tried this anyway and got an undefined command "\fps".
exclipy
I explained why it's impossible to do it (in this case) without copying the definition. You need to add `\makeatletter`...`\makeatother` around the code (I added this to my example) when (re)defining commands containing `@`.
Will Robertson
A: 

How about:

\newenvironment{centeredfigure}{\begin{figure}\begin{center}}{\end{center}\end{figure}}

Note: untested.

Martijn
There's nothing wrong with this approach but you should use `\centering` instead of the `center` environment, because the latter adds additional vertical padding that isn't necessary.
Will Robertson
good point. I've been trying to avoid this myself. Thanks!
Martijn
As I said in my question, I don't want to redefine it under another name.
exclipy