# Environment for step by step modification of graphics

I would like to have one environment that produces the following two examples where the pictures are not animations.

I would like that the environment takes care automatically of the numbers of figures.

This for cases of figures showing step by step explications like for example the simplification of one finite Markov chain. From LaTeX point of view, I would like to only type :

\begin{stepByStep}
\step Fig.1
\step Fig.2
\step Fig.3
\step Fig.4
\end{stepByStep}

\begin{stepByStep}
\step Fig.1
\step Fig.2
\step Fig.3
\step Fig.4
\step Fig.5
\step Fig.6
\step Fig.7
\end{stepByStep}


• I am assuming that the Fig. x represent figures. How big are they? Are they all the same height, width? How are they to be positioned? – Peter Grill Mar 1 '12 at 17:37
• The figure must be centered in the hidden table or grid, and they will not have necessarly the same dimensions. – projetmbc Mar 1 '12 at 19:26
• So, is your main problem with the placement of the figures, or the arrows. It would be helpful if you could do the placement of the figures. Also, do the arrows need to be the same size, or should they stretch across between the figures? – Peter Grill Mar 1 '12 at 19:28

Here is solution that will do this for you, but with a slight modification of the syntax. You specify two steps at at time and one can be blank:

\begin{stepByStep}
\step{\FigA}{\FigB}
\step{}{\FigD}
\end{stepByStep}

\begin{stepByStep}
\step{\FigA}{\FigB}
\step{\FigC}{\FigD}
\step{\FigD}{}
\end{stepByStep}


It places the individual figures in a tabular environment and uses \tikzmark to draw the arrows in between the appropriate points. Hence, it should be able to handle figures of different heights and length, but I have not done extensive testing. Here is the output of the last case below.

## Customization:

A few parameters are defined to allow you to easily tweak this:

1. \WidthOfArrow specifies the horizontal arrow size (minimum)
2. \HeightOfArrow specifies the vertical arrow size
3. \ArrowImageSep specifies the space between arrow and image

## Notes:

• This requires two runs. Once to determine the begin and end point of the lines, and the second to draw them.
• No check is made to ensure that only the last row has a blank parameter.
• No check is made to ensure that only the appropriate parameter can be blank. For example if the second row is last, only the first parameter can be blank. But in the third row is the last one, only the second parameter can be blank.

## Further Enhancements:

• There is a slight bug in that the vertical arrow is a bit too long. I have added a kludge to fix this by setting \VerticalArrowAdjust, but this should not be needed, or at least should be able to compute the precise value.

• If this syntax won't work for you, it should be possible to adapt this to get the exact syntax you desired.

## Code:

\documentclass{article}
\usepackage[demo]{graphicx}% Add [demo] option if don't have figures
\usepackage{etoolbox}

\usepackage{tikz}
\usetikzlibrary{calc}

\newcommand*{\WidthOfArrow}{1.5cm}%  Horizontal Arrow size (minimum)
\newcommand*{\HeightOfArrow}{1.5cm}% Vertical Arrow size
\newcommand*{\ArrowImageSep}{1.5pt}% Space between arrow and image

%------------------ Should not need to adjust below this
\newlength{\VerticalSep}%
\pgfmathsetlength{\VerticalSep}{\HeightOfArrow + 2*\ArrowImageSep}%
\newtoggle{FirstRow}% No vertical arrow in this case

% We need to have the sizes of up to four pictures
\newlength{\HeightA}%
\newlength{\HeightB}%
\newlength{\HeightC}%
\newlength{\HeightD}%
\newlength{\WidthA}%
\newlength{\WidthB}%
\newlength{\WidthC}%
\newlength{\WidthD}%
\newcommand{\tikzmark}[1]{\tikz[overlay,remember picture] \node (#1) {};}

% https://tex.stackexchange.com/questions/46418/measure-and-retain-lengths-between-tabular-rows
\makeatletter
\newcommand*{\MeasureAndPlaceFigure}[3]{%#=1Fig, #2=Width, #3=Length
\setbox\z@\hbox{#1}%
\global\csname#2\endcsname\wd\z@%
\global\csname#3\endcsname\ht\z@%
}%

\newcommand*{\@stepAB}[2]{%  A --> B
\MeasureAndPlaceFigure{#1}{WidthA}{HeightA}%
\tikzmark{rightA}&&\tikzmark{leftB}%
\MeasureAndPlaceFigure{#2}{WidthB}{HeightB}%
%
\ifdim\HeightB=0pt% Need both images to have horizontal arrrow
\else%
\DrawHorizontalArrow{rightA}{leftB}%
\fi%
%
\iftoggle{FirstRow}{}{%  Vertical arrow only if NOT first row
\DrawVerticalArrow{rightC}{-\WidthC}{\HeightC}{rightA}{-\WidthA}{\HeightA}%
}%
\global\togglefalse{FirstRow}%
\let\step\@stepCD% Next invocation of \step will call stepCD
}%

\newcommand*{\@stepCD}[2]{%  C <-- D
\MeasureAndPlaceFigure{#1}{WidthC}{HeightC}%
\tikzmark{rightC}&&\tikzmark{leftD}%
\MeasureAndPlaceFigure{#2}{WidthD}{HeightD}%
\ifdim\HeightC=0pt\relax% Need both images to have horizontal arrrow
\else%
\DrawHorizontalArrow{leftD}{rightC}%
\fi%
\iftoggle{FirstRow}{}{%  Vertical arrow only if NOT first row
\DrawVerticalArrow{leftB}{\WidthB}{\HeightB}{leftD}{\WidthD}{\HeightD}%
}%
\global\togglefalse{FirstRow}%
\let\step\@stepAB% Next invocation of \step will call stepAB
}%

\let\step\@stepAB% First invocation of \step will call \@stepAB
\makeatother

\newcounter{CurrentSate}%
\newenvironment{stepByStep}{%
\setcounter{CurrentSate}{0}%
\global\toggletrue{FirstRow}% No vertical arrow until 2nd row
\begin{tabular}{@{}c@{} p{\WidthOfArrow} @{}c@{}}%
}{%
\end{tabular}%
}%

\newcommand*{\DrawHorizontalArrow}[3][]{%
\tikz[overlay,remember picture]{%
\draw[ultra thick, ->, red,
shorten <=\ArrowImageSep, shorten >=\ArrowImageSep, #1]
($(#2)$) --
($(#3)$);
}%
}%

\newcommand*{\DrawVerticalArrow}[7][]{%
\tikz[overlay,remember picture]{%
\draw[ultra thick, ->, red,
shorten <=\ArrowImageSep, shorten >=\ArrowImageSep, #1]
($(#2)+0.5*(#3,-#4+\VerticalArrowAdjust)$) --
($(#5)+0.5*(#6,#7+\VerticalArrowAdjust)$);
}%
}%

\def\FigA{\includegraphics[width=2.0cm,height=1.0cm]{images/EiffelWide}}%
\def\FigB{\includegraphics[width=1.5cm,height=3.0cm]{images/EiffelTall}}%
\def\FigC{\includegraphics[width=3.0cm,height=1.5cm]{images/EiffelWide}}%
\def\FigD{\includegraphics[width=2.0cm,height=4.0cm]{images/EiffelTall}}%

\begin{document}
\section*{Test 1}
\begin{stepByStep}
\step{\FigA}{\FigB}
\step{\FigC}{\FigD}
\end{stepByStep}
%
\section*{Test 2}
\begin{stepByStep}
\step{\FigA}{\FigB}
\step{}{\FigD}
\end{stepByStep}
%
\section*{Test 3}
\begin{stepByStep}
\step{\FigA}{\FigB}
\step{\FigC}{\FigA}
\step{\FigD}{}
\end{stepByStep}
\end{document}

• This is a very good solution. I would simplify the mark-up a bit more by having a delimited macro \step{\FigA}{\FigB} to \step{\FigA,\FigB} or even \step \FigA, \FigB;, but I guess is a matter of taste:) – Yiannis Lazarides Mar 2 '12 at 4:17
• Thanks @YiannisLazarides. Since there are cases where one of the parameters is optional, I think it would be confusing to use \step{,\FigB}. Also, based on the MWE given the user seemed to want to list them one at a time as opposed to FigA,FigB,FigC,FigD, and I attempted to get him close to that.. And agreed, definitely a matter of taste. – Peter Grill Mar 2 '12 at 4:21
• Peter -- thanks, I will be using your solution, in some notes I am preparing where I need to show a step by step approach to an activity. Really an excellent solution:) – Yiannis Lazarides Mar 2 '12 at 4:30
• @Peter Grill : thanks a lot for this solution. That's great ! – projetmbc Mar 2 '12 at 14:14