How to conditionally control the width of a figure with minimal code duplication?

I am using `\iftoggle` to switch between a for-review (doublespaced, onecolumn) and photo-ready (singlespaced, twocolumn) layout.

I want to change the width of figures to be optimal for both, depending on the toggle. I'd also like to do this without having two copies of all the markup for the figures.

Essentially, I want the equivalent of this in CPP:

``````#define DRAFT 1
#if DRAFT
#define FIGWIDTH 0.45\columnwidth
#else
#define FIGWIDTH 0.9\columnwidth
#end

... lots of complex figure/subfigure crap
\includegraphics[width=FIGWIDTH]{pretty-diagram.pdf}
... etc
``````

What's the best way to do this?

-
Welcome to TeX.sx! A tip: You can use backticks ``` to mark your inline code as I did in my edit. – Joseph Wright Nov 15 '11 at 21:05
What is the name of your toggle? – Werner Nov 15 '11 at 21:05
@Werner - I just called it `review`. Why do you ask? – Mike McCracken Nov 15 '11 at 21:08
You could use something like `\newtoggle{review} \newlength{\figwidth} \iftoggle{review}{\setlength{\figwidth}{0.45\columnwidth}}{\setlength{\figwidth}‌​{0.9\columnwidth}}` and then use `width=\figwidth` in your `\includegraphics` key-value. That way, the length `\figwidth` is set according to your toggle, and used throughout your document consistently. All figures will be resized (made smaller/larger) this way though. – Werner Nov 15 '11 at 21:14
@Werner, that works great. Exactly what I needed. Thanks! I'm new to this site - should we edit my question or should you repost that comment as an 'answer'? – Mike McCracken Nov 15 '11 at 21:19

3 Answers

The `\iftoogle` macro of `etoolbox` is expandable, so you could use it directly in the width argument as long both clauses expand to a length.

You could use:

``````\includegraphics[width=\iftoggle{review}{0.45\columnwidth}{0.9\columnwidth}]{<figure>}
``````

Or use a macro for this:

``````\newcommand*{\figwidth}{\iftoggle{review}{0.45\columnwidth}{0.9\columnwidth}}
% ...
\includegraphics[width=\figwidth]{<figure>}
``````

Or if you want different factors for different figures:

``````\newcommand*{\figwidth}[2]{\iftoggle{review}{#1\columnwidth}{#2\columnwidth}}
% ...
\includegraphics[width=\figwidth{0.45}{0.9}]{<figure>}
``````

or, more general:

``````\newcommand*{\figwidth}[2]{\iftoggle{review}{#1}{#2}}
% ...
\includegraphics[width=\figwidth{0.45\columnwidth}{0.9\columnwidth}]{<figure>}
``````

Just keep the macro fully expandable, e.g. don't use an optional argument.

-

You can define a length that is toggle-specific using

``````\usepackage{etoolbox}% http://ctan.org/pkg/etoolbox
\newtoggle{review} \newlength{\figwidth}
%\settoggle{review}{true}% In "review" mode
\iftoggle{review}%
{\setlength{\figwidth}{0.45\columnwidth}}% In "review" mode/true
{\setlength{\figwidth}‌​{0.9\columnwidth}}% Not in "review" mode/false
``````

and then use

``````\includegraphics[width=\figwidth]{<figure>}
``````

for your included images.

-

ConTeXt provides a mechanism to group multiple settings for images, including `width`. I'll give a different example to illustrate this. I often use the same source to generate course notes and lecture slides. For a certain class of figures, in the slides I want the figure to scale until its width equals `\textwidth` or its height equals `\textheight`; while in the handouts I want the figure width to be less the `0.5\textwidth`. This can be done using

``````\doifmodeelse{screen}
{\defineexternalfigure[display][maxwidth=\textwidth,maxheight=\textheight,factor=max]}
{\defineexternalfigure[display][width=0.5\textwidth]}
``````

and then use

``````\externalfigure[filename][display]
``````

in the text file. Then, depending on whether `screen` mode is active or not, the `\externalfigure` command inherits the appropriate set of settings. This mechanism is more powerful that individually toggling each parameter of `\externalfigure`.

-