11

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?

0

3 Answers 3

7

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.

3
  • 3
    Note that counter representation through \the.. might not be numeric. As such it is better to check \value{..} instead.
    – Werner
    Jul 7, 2013 at 6:41
  • Yea! That is true.
    – Jagath
    Jul 7, 2013 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. Jul 11, 2013 at 11:35
9

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

5
  • 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. Jul 7, 2013 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? Jul 11, 2013 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. Jul 11, 2013 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. Jul 11, 2013 at 18:35
  • @StonefeatherGrubbs blackburn’s solution works inside a group as LaTeX’s counter are always set globally. Jul 11, 2013 at 18:50
6

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 
2
  • Both of your versions work properly for me in your MWE, but not plugged into my document,\; no idea why. Jul 11, 2013 at 11:44
  • @StonefeatherGrubbs: Without more knowledge regarding your actual usage, there's not much more I can say.
    – Werner
    Jul 11, 2013 at 14:13

You must log in to answer this question.

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