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.

I have (made, actually) a graphic of the forepaw-print of a bear that I want to use as a flourish mark at the end of chapters and a few other places. After finishing with the image, I created a mirror version, so that I had right and left paw versions, originally to see which looked better. The thought then came that it would be fun to alternate between the two at each occurrence, letting my bear, as it were, go for a walk through my book (on it's front paws, I know; let's not carry the notion too far).

For repeated inline graphics I use \newcommand* to create a "mini-macro" that does nothing but an \includegraphic of a given image in a particular size, mostly to be included in other macros; in this case, the two are called \lbpimage and \rbpimage, and by themselves they work fine.

Now I need an intermediary macro to switch between the two. What I intended is a \newcommand, \bearpaw, that would create another command (via \renewcommand*) called \bpaw, and then run it. Referencing a counter named paw and using \ifthen, \bpawis created with the intent of running one or the other of the "mini-macros" and then resetting paw from 0 to 1 or vise versa.

Of course, to be able to use \renewcommand* the commandname needs to be pre-existing, so before \newcommand*\bearpaw I initialize \bpaw with a dummy version, \newcommand*\bpaw{foo} thus:

\documentclass[letterpaper,twoside,12pt,final]{memoir}

\usepackage{graphicx}
\usepackage{ifthen}

\newcommand*{\lbpimage}%
  {\includegraphics[width=0.548in]{lbearpaw}}

\newcommand*{\rbpimage}%
  {\includegraphics[width=0.548in]{rbearpaw}}

\newcounter{paw}%     Preset to zero by default.

\newcommand*\bpaw%
  {foo}

\newcommand*\bearpaw%
  {\ifthenelse{\equal{paw}{0}}%
    {\renewcommand*\bpaw%
      {\lbpimage%
      \setcounter{paw}{1}}}{}%
  \ifthenelse{\equal{paw}{1}}%
    {\renewcommand*\bpaw%
      {\rbpimage%
      \setcounter{paw}{0}}}{}%
  \bpaw}

\begin{document}

\bearpaw \bearpaw \bearpaw

\end{document}

And what I get is:

foo foo foo

Clearly, my conditionals aren't working as I expected. What have I done wrong?

share|improve this question

3 Answers 3

up vote 5 down vote accepted

Commands \ifthenelse and \equal can be replace with \ifnum to get the macro work successfully.

\newcommand*\bearpaw%
  {\ifnum\thepaw=0%
    \renewcommand*\bpaw%
      {\lbpimage%
      \setcounter{paw}{1}}\fi%
  \ifnum\thepaw=1%
    \renewcommand*\bpaw%
      {\rbpimage%
      \setcounter{paw}{0}}\fi%
  \bpaw}

Using this you will not need the package ifthen.

share|improve this answer
2  
Note that counter representation through \the.. might not be numeric. As such it is better to check \value{..} instead. –  Werner Jul 7 '13 at 6:41
    
Yea! That is true. –  Jagath AR Jul 7 '13 at 6:53
    
@blackburn I'd gone with Qrrbrbirlbel's solution, which worked within bearpaw used alone, but not when put inside a center environment and included in a \newcommand (I have no idea why). Yours solution works in all cases. –  Stonefeather Grubbs Jul 11 '13 at 11:35

Switching back-and-forth is easily obtained by an old-school \newif which provides a boolean switch/conditional:

enter image description here

\documentclass{article}

\usepackage{graphicx}% http://ctan.org/pkg/graphicx
\newif\ifswitchbearpaw

\newcommand*{\lbpimage}%
  {\includegraphics[width=0.548in]{example-image-a}}

\newcommand*{\rbpimage}%
  {\includegraphics[width=0.548in]{example-image-b}}

\newcounter{paw}%     Preset to zero by default.

\newcommand*\bpaw%
  {foo}

\newcommand*\bearpaw%
  {\ifswitchbearpaw\lbpimage\switchbearpawfalse\else\rbpimage\switchbearpawtrue\fi}

\begin{document}

\bearpaw \bearpaw \bearpaw

\end{document}

Since you're only toggling, there is no need for a counter test. etoolbox provides a similar means to trigger/flip a (boolean) switch.


A safer approach to the conditional macro \bearpaw would be

\makeatletter
\newcommand*\bearpaw{%
  \ifswitchbearpaw\expandafter\@firstoftwo\else\expandafter\@secondoftwo\fi%
    {\switchbearpawfalse\lbpimage}{\switchbearpawtrue‌​\rbpimage}}
\makeatother 
share|improve this answer
    
Both of your versions work properly for me in your MWE, but not plugged into my document,\; no idea why. –  Stonefeather Grubbs Jul 11 '13 at 11:44
    
@StonefeatherGrubbs: Without more knowledge regarding your actual usage, there's not much more I can say. –  Werner Jul 11 '13 at 14:13

The \equal macro compares strings (text) not integers. For that, you need to use <, = or > as in \ifthenelse{\value{paw}=0}.

Simplifying this in one \ifthenelse macro would be

\newcommand*\bearpaw{%
  \ifthenelse{\value{paw}=0}{%
    \renewcommand*\bpaw{\lbpimage\setcounter{paw}{1}}%
  }{%
    \renewcommand*\bpaw{\rbpimage\setcounter{paw}{0}}%
  }%
  \bpaw}

But as you switch only between two states, there is no need for a counter. You can use a boolean instead. I also removed the \paw macro, you can simply execute the contents directly.

I have used the demo option for the graphicx package as we do not have the images and also changed the size of the images to clearly show, that the images are alternating.

The xifthen which supersedes the old ifthen has been used instead as it improves other areas.

[x]ifthen’s \ifthenelse and \boolean macros internally uses the same tools like \newif but keeps it nesting-safe.

If you want to use this in a group but want the switching to be a global matter, you either need to use plainTeX \global\pawrighttrue and \global\pawrightfalse. The etoolbox package provides an easier interface and its macros are prependable with \global.

The difference between a “bool” and a “toggle” is explained in the manual as well as in Difference between \newbool and \newtoggle from etoolbox package.

Code

\documentclass[letterpaper,twoside,12pt,final]{memoir}

\usepackage[demo]{graphicx}
\usepackage{etoolbox}

\newcommand*{\lbpimage}%
  {\includegraphics[width=0.548in]{lbearpaw}}

\newcommand*{\rbpimage}%
  {\includegraphics[width=1.548in]{rbearpaw}}

\newtoggle{pawright}

\newcommand*\bearpaw{%
  \iftoggle{pawright}
    {\rbpimage\global\togglefalse{pawright}}
    {\lbpimage\global\toggletrue{pawright}}%
}
\newcommand*{\chapend}{\par\smallskip\begin{center}\bearpaw\end{center}}

\begin{document}
\bearpaw \quad \bearpaw \quad \bearpaw

\chapend
\chapend
\chapend
\chapend
\end{document}

Output

enter image description here

share|improve this answer
    
Triple thanks for (1) explaining my string/numeric syntax confusion and how to fix it, (2) pointing me to a better conditionals package, and (3) showing how to use xifthen to take the boolean approach (also recommended by another respondent, but using TeX commands instead). As a (Xe)(La)TeX novice, with no real programming background, I find this all most helpful. –  Stonefeather Grubbs Jul 7 '13 at 15:41
    
Well, it did work, until I tried putting it to use in the form \newcommand*{\chapend}{\par\smallskip\begin{center}\bearpaw\end{center}}. The swap never happens; all I get is left paws. I tried changing from the environment to a {\centering...} group, to see if that would make any difference, but it didn't help. Is this a fragility issue? If so, is there a way to fix it? –  Stonefeather Grubbs Jul 11 '13 at 10:44
    
I tried blackburn's solution and it survives centering, so I will use that. I am still curious as to why yours did not. –  Stonefeather Grubbs Jul 11 '13 at 11:31
    
@StonefeatherGrubbs Yes, of course. Any environment and also the {\centering …} group makes the switch local. You need to \global the change either with the plainTeX version, i.e. \gobble\pawrighttrue and \gobble\pawrightfalse, or you use the etoolbox version which can be prepended with \global. I’ll update my answer in a bit. –  Qrrbrbirlbel Jul 11 '13 at 18:35
    
@StonefeatherGrubbs blackburn’s solution works inside a group as LaTeX’s counter are always set globally. –  Qrrbrbirlbel Jul 11 '13 at 18:50

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.