% \iffalse meta-comment % % Copyright (C) 2017 by F. Pantigny % ----------------------------------- % % This file may be distributed and/or modified under the % conditions of the LaTeX Project Public License, either version 1.3 % of this license or (at your option) any later version. % The latest version of this license is in: % % http://www.latex-project.org/lppl.txt % % and version 1.3 or later is part of all distributions of LaTeX % version 2005/12/01 or later. % % \fi % \iffalse \def\myfileversion{1.7} \def\myfiledate{2018/07/18} % % %<*batchfile> \begingroup \input l3docstrip.tex \keepsilent \usedir{tex/latex/witharrows} \preamble Copyright (C) 2017 by F. Pantigny ----------------------------------- This file may be distributed and/or modified under the conditions of the LaTeX Project Public License, either version 1.3 of this license or (at your option) any later version. The latest version of this license is in: http://www.latex-project.org/lppl.txt and version 1.3 or later is part of all distributions of LaTeX version 2005/12/01 or later. \endpreamble \askforoverwritefalse \endgroup % % %<@@=wa> %<*driver> \documentclass[dvipsnames]{l3doc}% dvipsnames is for xcolor (loaded by Tikz, loaded by witharrows) \usepackage{xltxtra} \usepackage{geometry} \geometry{left=2.8cm,right=2.8cm,top=2.5cm,bottom=2.5cm,papersize={21cm,29.7cm}} \usepackage[footnotehyper]{witharrows} \usetikzlibrary{calc} \usepackage{mathtools} \usepackage{amsfonts} \usepackage[only,llbracket,rrbracket]{stmaryrd} \NewDocumentEnvironment {scope} {} {} {} \def\interitem{\vskip 7mm plus 2 mm minus 3mm} \def\emphase{\bgroup\color{RoyalPurple}\let\next=} \fvset{commandchars=\~\#\@,formatcom={\color{gray}}} \DeclareMathOperator{\re}{Re} \parindent 0pt \DisableCrossrefs \begin{document} \DocInput{witharrows.dtx} \end{document} % % \fi % \VerbatimFootnotes % \title{The package \pkg{witharrows}\thanks{This document corresponds to the version~\myfileversion\space of \pkg{witharrows}, % at the date of~\myfiledate.}} \author{F. Pantigny \\ \texttt{fpantigny@wanadoo.fr}} % % \maketitle % % \begin{abstract} % The LaTeX package \pkg{witharrows} provides an environment |{WithArrows}| which is similar to environment % |{aligned}| of \pkg{amsmath} (and \pkg{mathtools}) but gives the possibility to draw arrows on the right side of % the alignment. These arrows are usually used to give explanations concerning the mathematical calculus presented. % \end{abstract} % % % \vskip1cm % This package can be used with |xelatex|, |lualatex|, |pdflatex| but also by the classical workflow % |latex|-|dvips|-|ps2pdf| (or Adobe Distiller). Two compilations may be necessary. This package requires the % packages \pkg{expl3}, \pkg{xparse} and \pkg{tikz}. The following Tikz libraries \pkg{arrows.meta} and % \pkg{bending} are also required. % % \bigskip % This package provides an environment |{WithArrows}| to construct alignments of equations with arrows for the % explanations on the right side: % % % \begin{Verbatim} % $\begin{WithArrows} % A & = (a+1)^2 ~emphase#\Arrow{we expand}@ \\ % & = a^2 + 2a + 1 % \end{WithArrows}$ % \end{Verbatim} % % $\begin{WithArrows} % A & = (a+1)^2 \Arrow{we expand} \\ % & = a^2 + 2a + 1 % \end{WithArrows}$ % % % % \medskip % The arrow has been drawn with the command |\Arrow| on the row from which it starts. The command |\Arrow| must be used % in the second column (the best way is to put it at the end of the second cell of the row as in the previous example). % % \medskip % The environment |{WithArrows}| bears similarities with the environment |{aligned}| of |amsmath| (and % |mathtools|). The extension \pkg{witharrows} also provides an environment |{DispWithArrows}| which is similar to % the environment |{align}| of |amsmath|: cf. p. \pageref{DispWithArrows}. % % % \section{Options for the shape of the arrows} % % The command |\Arrow| has several options. These options can be put between square brackets, before, or after the % mandatory argument. % % The option |jump| gives the number\footnote{It's not possible to give a non-positive value to |jump|. See % below (p.~\pageref{Backwards}) the way to draw an arrow which goes backwards.} of rows the arrow must jump (the % default value is, of course,~$1$). % % % \begin{Verbatim} % $\begin{WithArrows} % A & = \bigl((a+b)+1\bigr)^2 \Arrow[~emphase#jump=2@]{we expand} \\ % & = (a+b)^2 + 2(a+b) +1 \\ % & = a^2 + 2ab + b^2 + 2a + 2b +1 % \end{WithArrows}$ % \end{Verbatim} % % % % $\begin{WithArrows} % A & = \bigl((a+b)+1\bigr)^2 \Arrow[jump=2]{we expand} \\ % & = (a+b)^2 + 2(a+b) +1 \\ % & = a^2 + 2ab + b^2 + 2a + 2b +1 % \end{WithArrows}$ % % % \interitem % It's possible to put several arrows which start from the same row. % % % \begin{Verbatim} % $\begin{WithArrows} % A & = \bigl((a+b)+1\bigr)^2 ~emphase#\Arrow{}\Arrow{}[jump=2]@ \\ % & = (a+b)^2 + 2(a+b) +1 \\ % & = a^2 + 2ab + b^2 + 2a + 2b +1 % \end{WithArrows}$ % \end{Verbatim} % % $\begin{WithArrows} % A & = \bigl((a+b)+1\bigr)^2 \Arrow{}\Arrow{}[jump=2] \\ % & = (a+b)^2 + 2(a+b) +1 \\ % & = a^2 + 2ab + b^2 + 2a + 2b +1 % \end{WithArrows}$ % % \interitem % The option |xoffset| shifts the arrows to the right (we usually don't want the arrows to be stucked on the text). % The default value of |xoffset| is $3$~mm. % % \begin{Verbatim} % $\begin{WithArrows} % A & = \bigl((a+b)+1\bigr)^2 % \Arrow[~emphase#xoffset=1cm@]{with \texttt{xoffset=1cm}} \\ % & = (a+b)^2 + 2(a+b) +1 % \end{WithArrows}$ % \end{Verbatim} % % $\begin{WithArrows} % A & = \bigl((a+b)+1\bigr)^2 % \Arrow[xoffset=1cm]{with \texttt{xoffset=1cm}} \\ % & = (a+b)^2 + 2(a+b) +1 % \end{WithArrows}$ % % % \interitem % The arrows are drawn with Tikz. That's why the command |\Arrow| has an option |tikz| which can be used to give to % the arrow (in fact, the command |\path| of Tikz) the options proposed by Tikz for such an arrow. The following % example gives an thick arrow. % % % \begin{Verbatim} % $\begin{WithArrows} % A & = (a+1)^2 \Arrow[~emphase#tikz=thick@]{we expand} \\ % & = a^2 + 2a + 1 % \end{WithArrows}$ % \end{Verbatim} % % $\begin{WithArrows} % A & = (a+1)^2 \Arrow[tikz=thick]{we expand} \\ % & = a^2 + 2a + 1 % \end{WithArrows}$ % % \interitem % It's also possible to change the arrowheads. For example, we can draw an arrow which goes backwards with the Tikz % option~|<-|. % \label{Backwards} % % \begin{Verbatim} % $\begin{WithArrows} % A & = (a+1)^2 \Arrow~emphase#[tikz=<-]@{we factorize} \\ % & = a^2 + 2a + 1 % \end{WithArrows}$ % \end{Verbatim} % % $\begin{WithArrows} % A & = (a+1)^2 \Arrow[tikz=<-]{we factorize} \\ % & = a^2 + 2a + 1 % \end{WithArrows}$ % % \interitem % It's also possible to suppress both tips of the arrow with the Tikz option |-|. % % % \begin{Verbatim} % $\begin{WithArrows} % A & = (a+1)^2 \Arrow[~emphase#tikz=-@]{very classical} \\ % & = a^2 + 2a + 1 % \end{WithArrows}$ % \end{Verbatim} % % $\begin{WithArrows} % A & = (a+1)^2 \Arrow[tikz=-]{very classical} \\ % & = a^2 + 2a + 1 % \end{WithArrows}$ % % \interitem % In order to have straight arrows instead of curved ones, we must use the Tikz option ``|bend left = 0|''. % % % \begin{Verbatim} % $\begin{WithArrows} % A & = (a+1)^2 \Arrow~emphase#[tikz={bend left=0}]@{we expand} \\ % & = a^2 + 2a + 1 % \end{WithArrows}$ % \end{Verbatim} % % $\begin{WithArrows} % A & = (a+1)^2 \Arrow[tikz={bend left=0}]{we expand} \\ % & = a^2 + 2a + 1 % \end{WithArrows}$ % % \smallskip % In fact, it's possible to change more drastically the shape or the arrows with the option |TikzCode| presented % p.~\pageref{TikzCode}. % % \interitem % One of the most useful options is ``|text width|'' to control the width of the text associated to the arrow. % % % \begin{Verbatim} % $\begin{WithArrows} % A & = \bigl((a+b)+1\bigr)^2 % \Arrow[jump=2,~emphase#tikz={text width=5.3cm}@]{We have done...} \\ % & = (a+b)^2 + 2(a+b) +1 \\ % & = a^2 + 2ab + b^2 + 2a + 2b +1 % \end{WithArrows}$ % \end{Verbatim} % % $\begin{WithArrows} % A & = \bigl((a+b)+1\bigr)^2 % \Arrow[jump=2,tikz={text width=5.3cm}]{We have done a two-stages expansion but it would have been clever % to expand with the multinomial theorem.} \\ % & = (a+b)^2 + 2(a+b) +1 \\ % & = a^2 + 2ab + b^2 + 2a + 2b +1 % \end{WithArrows}$ % % \interitem % If we want to change the font of the text associated to the arrow, we can, of course, put a command like % |\bfseries|, |\large| or |\sffamily| at the beginning of the text. But, by default, the texts are composed with a % combination of |\small| and |\itshape|. When adding |\bfseries| at the beginning of the text, we won't suppress % the |\small| and the |\itshape| and we will consequently have a text in a bold, italic and small font. % % % \begin{Verbatim} % $\begin{WithArrows} % A & = (a+1)^2 \Arrow{~emphase#\bfseries@ we expand} \\ % & = a^2 + 2a + 1 % \end{WithArrows}$ % \end{Verbatim} % % $\begin{WithArrows} % A & = (a+1)^2 \Arrow{\bfseries we expand} \\ % & = a^2 + 2a + 1 % \end{WithArrows}$ % % \interitem % If we put commands |\\| in the text to force newlines, a command of font placed in the beginning of the text will % have effect only until the first command |\\| (like in an environment |{tabular}|). That's why Tikz gives a option % |font| to modify the font of the whole text. Nevertheless, if we use the option |tikz={font={\bfseries}}|, the % default specification of |\small| and |\itshape| will be overwritten. % % % \begin{Verbatim} % $\begin{WithArrows} % A & = (a+1)^2 \Arrow[~emphase#tikz={font={\bfseries}}@]{we expand} \\ % & = a^2 + 2a + 1 % \end{WithArrows}$ % \end{Verbatim} % % $\begin{WithArrows} % A & = (a+1)^2 \Arrow[tikz={font={\bfseries}}]{we expand} \\ % & = a^2 + 2a + 1 % \end{WithArrows}$ % % \medskip % If we want exactly the same result as previously, we have to give to the option |font| the value % |{\itshape\small\bfseries}|. % % % \interitem % Almost all the options can be given directly to the environment |{WithArrows}| (between square brackets). In this % case, they apply to all the arrows of the environment.\footnote{They also apply to the nested environments % |{WithArrows}| (with the logical exceptions of |interline|, |CodeBefore| and |CodeAfter|).} % % % \begin{Verbatim} % $\begin{WithArrows}[~emphase#tikz=blue@] % A & = \bigl((a+b)+1\bigr)^2 \Arrow{First expansion.} \\ % & = (a+b)^2 + 2(a+b) +1 \Arrow{Second expansion.} \\ % & = a^2 + 2ab + b^2 + 2a + 2b +1 % \end{WithArrows}$ % \end{Verbatim} % % $\begin{WithArrows}[tikz=blue] % A & = \bigl((a+b)+1\bigr)^2 \Arrow{First expansion.} \\ % & = (a+b)^2 + 2(a+b) +1 \Arrow{Second expansion.} \\ % & = a^2 + 2ab + b^2 + 2a + 2b +1 % \end{WithArrows}$ % % % \interitem % The environment |{WithArrows}| has an option |displaystyle|. With this option, all the elements are composed in % |\displaystyle| (like in an environment |{aligned}| of \pkg{amsmath}). % % \medskip % Without the option |displaystyle|: % % % \begin{Verbatim} % $\begin{WithArrows} % \int_0^1 (x+1)^2 dx % & = \int_0^1 (x^2+2x+1) dx % \Arrow{linearity of integration} \\ % & = \int_0^1 x^2 dx + 2 \int_0^1 x dx + \int_0^1 dx \\ % & = \frac13 + 2\frac12 + 1 \\ % & = \frac73 % \end{WithArrows}$ % \end{Verbatim} % % $\begin{WithArrows} % \int_0^1 (x+1)^2 dx % & = \int_0^1 (x^2+2x+1) dx % \Arrow{linearity of integration} \\ % & = \int_0^1 x^2 dx + 2 \int_0^1 x dx + \int_0^1 dx \\ % & = \frac13 + 2\frac12 + 1 \\ % & = \frac73 % \end{WithArrows}$ % % % \medskip % The same example with the option |displaystyle|:\par\nobreak % % $\begin{WithArrows}[displaystyle] % \int_0^1 (x+1)^2 dx % & = \int_0^1 (x^2+2x+1) dx % \Arrow{linearity of integration} \\ % & = \int_0^1 x^2 dx + 2 \int_0^1 x dx + \int_0^1 dx \\ % & = \frac13 + 2\frac12 + 1 \\ % & = \frac73 % \end{WithArrows}$ % % \interitem % The version 1.3 of \pkg{witharrows} give two options for a fine tuning of the arrows: % % \begin{itemize} % \item the option |ystart| set the vertical distance between the base line of the text and the start of the arrow % (default value: 0.4 ex); % \item the option |ygap| set the vertical distance between two consecutive arrows (default value: 0.4~ex). % \end{itemize} % % % \bigskip % $\begin{WithArrows}[interline=1mm] % (\cos x + \sin x)^2 & = \cos^2 x +2 \cos x \sin x + \sin^2 x\Arrow{}\tikz[remember picture] \coordinate (A) ; \\ % & = \cos^2x + \sin^2x + 2\sin x\cos x \Arrow{} \\ % & = 1 + \sin(2x) % \end{WithArrows}$ % % \begin{tikzpicture}[remember picture,overlay,blue] % \draw (wa-\WithArrowsLastEnv-1-r.south) to ++(1,0) coordinate (B) to ++(0.1,0) ;; % \draw (A) to ++(1,0) coordinate (C) to ++(0.1,0) ;; % \draw (B) -- (C) ; % \draw[<-] (B) to ++(0,0.2) ; % \draw[<-] (C) to ++(0,-0.2) ; % \path (C) node[right=1mm] {\texttt{ystart}} ; % \draw (wa-\WithArrowsLastEnv-2-r.north) to ++(3,0) coordinate (E) to ++(0.1,0); % \draw (wa-\WithArrowsLastEnv-2-r.south) to ++(3,0) coordinate (F) to ++(0.1,0); % \draw (E) -- (F) ; % \draw[<-] (E) to ++(0,0.2) ; % \draw[<-] (F) to ++(0,-0.2) ; % \path (F) node[right=1mm] {\texttt{ygap}} ; % \end{tikzpicture} % % % \bigskip % \emph{Remark}: It's also possible to use the options ``|shorten <|'' and ``|shorten >|'' of Tikz (via the option % |tikz| of \pkg{witharrows}). % % % \interitem % Almost all the options can also be set at the document level with the command |\WithArrowsOptions|. In this case, % the scope of the declarations is the current TeX group (these declarations are ``semi-global''). For example, if % we want all the environments |{WithArrows}| composed in |\displaystyle| with blue arrows, we can write % |\WithArrowsOptions{displaystyle,tikz=blue}|.\footnote{Since version 1.4 of \pkg{witharrows}, it's no longer possible % to give these options directly when loading the package, \emph{i.e.} with the command |\usepackage| in the preamble.} % % \begin{Verbatim} % ~emphase#\WithArrowsOptions{displaystyle,tikz=blue}@ % $\begin{WithArrows} % \sum_{i=1}^n (x_i+1)^2 % & = \sum_{i=1}^n (x_i^2+2x_i+1) \Arrow{by linearity}\\ % & = \sum_{i=1}^n x_i^2 + 2\sum_{i=1}^nx_i+ n % \end{WithArrows}$ % \end{Verbatim} % % \begin{scope} % \WithArrowsOptions{displaystyle,tikz=blue} % $\begin{WithArrows} % \sum_{i=1}^n (x_i+1)^2 % & = \sum_{i=1}^n (x_i^2+2x_i+1) \Arrow{by linearity}\\ % & = \sum_{i=1}^n x_i^2 + 2\sum_{i=1}^nx_i+ n % \end{WithArrows}$ % \end{scope} % % % \interitem % The command |\Arrow| is recognized only in the environments |{WithArrows}|. If we have a command |\Arrow| % previously defined, it's possible to go on using it outside the environments |{WithArrows}|. % % However, a previouly defined command |\Arrow| may still be useful in an environment |{WithArrows}|. If we want to % use it in such an environment, it's possible to change the name of the command |\Arrow| of the package % \pkg{witharrows}: there is an option |CommandName| for this purpose. The new name of the command must be given to % the option \emph{without} the leading backslash. % % % \begin{Verbatim} % \NewDocumentCommand {\Arrow} {} {\longmapsto} % $\begin{WithArrows}[~emphase#CommandName=Explanation@] % f & = \bigl(x \Arrow (x+1)^2\bigr) % ~emphase#\Explanation{we work directly on fonctions}@\\ % & = \bigl(x \Arrow x^2+2x+1\bigr) % \end{WithArrows}$ % \end{Verbatim} % % % \begin{scope} % \NewDocumentCommand {\Arrow} {} {\longmapsto} % $\begin{WithArrows}[CommandName=Explanation] % f & = \bigl(x \Arrow (x+1)^2\bigr) % \Explanation{we work directly on fonctions}\\ % & = \bigl(x \Arrow x^2+2x+1\bigr) % \end{WithArrows}$ % \end{scope} % % % \interitem % The environment |{WithArrows}| gives also two options |CodeBefore| and |CodeAfter| for LaTeX code that will be % executed at the beginning and at the end of the environment. Theses options are not designed to be hooks (they % are avalaible only at the environment level and they are not applied to the nested environments). % % % \begin{Verbatim} % $\begin{WithArrows}[~emphase#CodeBefore = \color{blue}@] % A & = (a+b)^2 \Arrow{we expand} \\ % & = a^2 + 2ab + b^2 % \end{WithArrows}$ % \end{Verbatim} % % $\begin{WithArrows}[CodeBefore = \color{blue}] % A & = (a+b)^2 \Arrow{we expand} \\ % & = a^2 + 2ab + b^2 % \end{WithArrows}$ % % \medskip % Special commands are available in |CodeAfter| : a command |\NbLines| which gives the number of lines (=rows) of % the current environment (this is a command and not a counter), a special form of the command |\Arrow| and the % command |\MultiArrow| : these commands are described in the section concerning the nested environments, % p.~\pageref{NestedEnv}. % % % \section{Precise positioning of the arrows} % % % The environment |{WithArrows}| defines, during the composition of the array, two series of nodes materialized in % red in the following example.\footnote{The option |shownodes| can be used to materialize the nodes. The % nodes are in fact Tikz nodes of shape ``rectangle'', but with zero width. An arrow between two nodes starts at % the \emph{south} anchor of the first node and arrives at the \emph{north} anchor of the second node.} % % \smallskip % $\begin{WithArrows}[displaystyle,shownodes] % I % & = \int_{\frac{\pi}4}^0 \ln\Bigl(1+\tan\left(\tfrac{\pi}4-u\right)\Bigr)(-d u) \\ % & = \int_0^{\frac{\pi}4} \ln\Bigl(1+\tan\left(\tfrac{\pi}4-u\right)\Bigr)d u \\ % & = \int_0^{\frac{\pi}4}\ln\left(1+\frac{1-\tan u}{1+\tan u}\right)\, d u \\ % & =\int_0^{\frac{\pi}4}\ln\left(\frac{1+\tan u+1-\tan u}{1+\tan u}\right) d u \\ % & =\int_0^{\frac{\pi}4} \ln\left(\frac2{1+\tan u}\right)\, d u\\ % & =\int_0^{\frac{\pi}4}\bigl(\ln2-\ln(1+\tan u)\bigr)\, d u \\ % & =\frac{\pi}4\ln2-\int_0^{\frac{\pi}4}\ln(1+\tan u)\, d u \\ % & =\frac{\pi}4\ln2-I % \end{WithArrows}$ % % \bigskip % The nodes of the left are at the end of each line of text. These nodes will be called \emph{left nodes}. The % nodes of the right side are aligned vertically on the right side of the array. These nodes will be called % \emph{right nodes}. % % By default, the arrows use the right nodes. We will say that they are in |rr| mode ($r$ for \emph{right}). These % arrows are |vertical| (we will say that an arrow is \emph{vertical} when its two ends have the same abscissa). % % % \smallskip % However, it's possible to use the left nodes, or a combination of left and right nodes, with one of the options % |lr|, |rl| and |ll| ($l$ for \emph{left}). Those arrows are, usually, not vertical. % % % Therefore % $\begin{WithArrows}[displaystyle] % I % & = \int_{\frac{\pi}4}^0 \ln\Bigl(1+\tan\left(\tfrac{\pi}4-u\right)\Bigr)(-d u) % \Arrow[lr]{This arrow uses the \texttt{lr} option.}\\ % & = \int_0^{\frac{\pi}4} \ln\Bigl(1+\tan\left(\tfrac{\pi}4-u\right)\Bigr)d u \\ % & = \int_0^{\frac{\pi}4}\ln\left(1+\frac{1-\tan u}{1+\tan u}\right)\, d u \\ % & =\int_0^{\frac{\pi}4}\ln\left(\frac{1+\tan u+1-\tan u}{1+\tan u}\right) d u % \Arrow[ll,jump=2,tikz={text width = 5cm}]{This arrow uses a \texttt{ll} option and a \texttt{jump} equal to $2$}\\ % & =\int_0^{\frac{\pi}4} \ln\left(\frac2{1+\tan u}\right)\, d u\\ % & =\int_0^{\frac{\pi}4}\bigl(\ln2-\ln(1+\tan u)\bigr)\, d u \\ % & =\frac{\pi}4\ln2-\int_0^{\frac{\pi}4}\ln(1+\tan u)\, d u \\ % & =\frac{\pi}4\ln2-I % \end{WithArrows}$ % % % % \interitem % There is also an option called \texttt{i} ($i$ for \emph{intermediate}). With this option, the arrow is vertical % and at the leftmost position. % % \begin{Verbatim} % $\begin{WithArrows} % (a+b)(a+ib)(a-b)(a-ib) % & = (a+b)(a-b)\cdot(a+ib)(a-ib) \\ % & = (a^2-b^2)(a^2+b^2) \Arrow~emphase#[i]@{because $(x-y)(x+y)=x^2-y^2$}\\ % & = a^4-b^4 % \end{WithArrows}$ % \end{Verbatim} % % $\begin{WithArrows} % (a+b)(a+ib)(a-b)(a-ib) % & = (a+b)(a-b)\cdot(a+ib)(a-ib) \\ % & = (a^2-b^2)(a^2+b^2) \Arrow[i]{because $(x-y)(x+y)=x^2-y^2$}\\ % & = a^4-b^4 % \end{WithArrows}$ % % % \interitem % The environment |{WithArrows}| gives also a |group| option. With this option, \emph{all} the arrows of the % environment are grouped on a same vertical line and at a leftmost position. % % % \begin{Verbatim}[formatcom=\small\color{gray}] % $\begin{WithArrows}[~emphase#displaystyle,group@] % 2xy'-3y=\sqrt x % & \Longleftrightarrow 2x(K'y_0+Ky_0')-3Ky_0 = \sqrt x \\ % & \Longleftrightarrow 2xK'y_0 + K(2xy_0'-3y_0) = \sqrt x \\ % & \Longleftrightarrow 2x K'y_0 = \sqrt x \Arrow{...}\\ % ... % \end{WithArrows}$ % \end{Verbatim} % % % $\begin{WithArrows}[displaystyle,group] % 2xy'-3y=\sqrt x % & \Longleftrightarrow 2x(K'y_0+Ky_0')-3Ky_0 = \sqrt x \\ % & \Longleftrightarrow 2xK'y_0 + K(2xy_0'-3y_0) = \sqrt x \\ % & \Longleftrightarrow 2x K'y_0 = \sqrt x \Arrow{We replace $y_0$ by its value.}\\ % & \Longleftrightarrow 2xK'x^{\frac32} = x^{\frac12} \Arrow{simplification of the $x$}\\ % & \Longleftrightarrow K' = \tfrac1{2x^2} \Arrow{antiderivation}\\ % & \Longleftrightarrow K = -\tfrac1{2x} % \end{WithArrows}$ % % % \bigskip % The environment |{WithArrows}| gives also a |groups| option (with a \emph{s} in the name). With this option, the % arrows are divided into several ``groups''. Each group is a set of connected\footnote{More precisely: for each % arrow $a$, we note $i(a)$ the number of its initial row and $f(a)$ the number of its final line ; for two arrows % $a$ and $b$, we say that $a \sim b$ when % $\llbracket i(a),f(a)\rrbracket \cap \llbracket i(b),f(b)\rrbracket \neq \varnothing$ ; the groups are the % equivalence classes of the transitive closure of $\sim$.} arrows. All the arrows of a given group are grouped on % a same vertical line and at a leftmost position. % % \bigskip % $\begin{WithArrows}[groups] % A & = B \Arrow{one} \\ % & = C+D \Arrow{two} \\ % & = D' \\ % & = E+F+G+H+I \\ % & = K + L + M \Arrow{three}\\ % & = N \Arrow{four}\\ % & = O % \end{WithArrows}$ % % \bigskip % If desired, the option |group| or the option |groups| can be given to the command |\WithArrowsOptions| so that it will become % the default value. In this case, it's still possible to come back to the default behaviour for a given % environment |{WithArrows}| with the option |rr|: |\begin{WithArrows}{rr}| % % % \section{Comparison with the environment \{aligned\}} % % |{WithArrows}| bears similarities with the environment |{aligned}| of the extension \pkg{amsmath}. These are only % similarities because |{WithArrows}| has not been written upon the environment |{aligned}|.\footnote{In fact, it's % possible to use the package \pkg{witharrows} without the package \pkg{amsmath}.} % % \interitem % As in the environments of \pkg{amsmath}, it's possible to change the spacing between two given rows with the % option of the command |\\| of end of line (it's also possible to use |\\*| but is has exactly the same effect as % |\\| since an environment |{WithArrows}| is always unbreakable). % % % \begin{Verbatim} % $\begin{WithArrows} % A & = (a+1)^2 \Arrow{we expand} ~emphase#\\[2ex]@ % & = a^2 + 2a + 1 % \end{WithArrows}$ % \end{Verbatim} % % $\begin{WithArrows} % A & = (a+1)^2 \Arrow{we expand} \\*[2ex] % \noalign{\vspace{3mm}} % & = a^2 + 2a + 1 % \end{WithArrows}$ % % % \interitem % In the environments of \pkg{amsmath} (or \pkg{mathtools}), the spacing between rows is fixed by a parameter % called |\jot| (it's a dimension and not a skip). That's also the case for the environment |{WithArrows}|. An % option |jot| has been given to the environment |{WithArrows}| in order to change the value of this parameter % |\jot| for an given environment.\footnote{It's also possible to change |\jot| with the environment |{spreadlines}| % of \pkg{mathtools}.} % % % \begin{Verbatim} % $\begin{WithArrows}[displaystyle,~emphase#jot=2ex@] % F & = \frac12G \Arrow{we expand}\\ % & = H + \frac12K \Arrow{we go on}\\ % & = K % \end{WithArrows}$ % \end{Verbatim} % % % $\begin{WithArrows}[displaystyle,jot=2ex] % F & = \frac12G \Arrow{we expand}\\ % & = H + \frac12K \Arrow{we go on}\\ % & = K % \end{WithArrows}$ % % % \bigskip % However, this new value of |\jot| will also be used in other alignments included in the % environment~|{WithArrows}|: % % % \begin{Verbatim} % $\begin{WithArrows}[jot=2ex] % \varphi(x,y) = 0 & \Leftrightarrow (x+y)^2 + (x+2y)^2 = 0 % \Arrow{$x$ and $y$ are real}\\ % & \Leftrightarrow \left\{ % \begin{aligned} % x+y & = 0 \\ % x+2y & = 0 % \end{aligned} % \right. % \end{WithArrows}$ % \end{Verbatim} % % % $\begin{WithArrows}[jot=2ex] % \varphi(x,y) = 0 & \Leftrightarrow (x+y)^2 + (x+2y)^2 = 0 % \Arrow{$x$ and $y$ are real}\\ % & \Leftrightarrow \left\{ % \begin{aligned} % x+y & = 0 \\ % x+2y & = 0 % \end{aligned} % \right. % \end{WithArrows}$ % % \bigskip % Maybe this doesn't correspond to the desired outcome. That's why an option |interline| is proposed. It's possible % to use a skip (=glue) for this option. % % % \begin{Verbatim} % $\begin{WithArrows}[~emphase#interline=2ex@] % \varphi(x,y) = 0 & \Leftrightarrow (x+y)^2 + (x+2y)^2 = 0 % \Arrow{$x$ and $y$ are real}\\ % & \Leftrightarrow \left\{ % \begin{aligned} % x+y & = 0 \\ % x+2y & = 0 \\ % \end{aligned} % \right. % \end{WithArrows}$ % \end{Verbatim} % % % $\begin{WithArrows}[interline=2ex] % \varphi(x,y) = 0 & \Leftrightarrow (x+y)^2 + (x+2y)^2 = 0 % \Arrow{$x$ and $y$ are real}\\ % & \Leftrightarrow \left\{ % \begin{aligned} % x+y & = 0 \\ % x+2y & = 0 \\ % \end{aligned} % \right. % \end{WithArrows}$ % % % \interitem % Like the environment |{aligned}|, |{WithArrows}| has an option of placement which can assume the values |t|, |c| % or |b|. However, the default value is not |c| but |t|. If desired, it's possible to have the |c| value as the % default with the command |\WithArrowsOptions{c}| at the beginning of the document. % % % \begin{Verbatim} % So\enskip % $\begin{WithArrows} % A & = (a+1)^2 \Arrow{we expand} \\ % & = a^2 + 2a + 1 % \end{WithArrows}$ % \end{Verbatim} % % So\enskip % $\begin{WithArrows} % A & = (a+1)^2 \Arrow{we expand} \\ % & = a^2 + 2a + 1 % \end{WithArrows}$ % % \bigskip % The value |c| may be useful, for example, if we want to add curly braces: % % \smallskip % \begin{Verbatim} % On pose\enskip $~emphase#\left\{@ % \begin{WithArrows}[~emphase#c@] % f(x) & = 3x^3+2x^2-x+4 % \Arrow[tikz=-]{both are polynoms}\\ % g(x) & = 5x^2-5x+6 % \end{WithArrows} % ~emphase#\right.@$ % \end{Verbatim} % % % On pose\enskip $\left\{ % \begin{WithArrows}[c] % f(x) & = 3x^3+2x^2-x+4 % \Arrow[tikz=-]{both are polynoms}\\ % g(x) & = 5x^2-5x+6 % \end{WithArrows} % \right.$ % % % \interitem % Unlike |{aligned}|, the environment |{WithArrows}| uses |\textstyle| by default. % % Once again, it's possible to change this behaviour with |\WithArrowsOptions|: % % \quad |\WithArrowsOptions{displaystyle}|. % % % \smallskip % The following example is composed with |{aligned}|:\par\nobreak % % \smallskip % $\left\{ % \begin{aligned} % \sum_{i=1}^n (x_i+1)^2 % & = \sum_{i=1}^n (x_i^2 + 2x_i+1) \\ % & = \sum_{i=1}^n x_i^2 + 2 \sum_{i=1}^nx_i + n % \end{aligned} % \right.$ % % % \medskip % The following is composed with |{WithArrows}[c,displaystyle]|. The results are stricly identical.\footnote{In % versions of \pkg{amsmath} older than the 5~nov.~2016, an thin space was added on the left of an environment % |{aligned}|. The new versions do not add this space and neither do |{WithArrows}|.}\par\nobreak % % \smallskip % $\left\{ % \begin{WithArrows}[c,displaystyle] % \sum_{i=1}^n (x_i+1)^2 % & = \sum_{i=1}^n (x_i^2 + 2x_i+1) \\ % & = \sum_{i=1}^n x_i^2 + 2 \sum_{i=1}^nx_i + n % \end{WithArrows} % \right.$ % % % \section{Arrows in nested environments} % % \label{NestedEnv} % % The environments |{WithArrows}| can be nested. In this case, the options given to the encompassing environment % applies also to the inner ones (with logical exceptions for |interline|, |CodeBefore| and |CodeAfter|). The % command |Arrow| can be used as usual in each environment |{WithArrows}|. % % \begin{Verbatim}[formatcom=\small\color{gray}] % $~emphase#\begin{WithArrows}@ % \varphi(x,y)=0 % & \Leftrightarrow (x+2y)^2+(2x+4y)^2 = 0 \Arrow{the numbers are real}\\ % & \Leftrightarrow % \left\{~emphase#\begin{WithArrows}@[c] % x+2y & = 0 \\ % 2x+4y & = 0 % ~emphase#\end{WithArrows}@\right. \\ % & \Leftrightarrow % \left\{~emphase#\begin{WithArrows}@[c] % x+2y & = 0 \Arrow[tikz=-]{the same equation}\\ % x+2y & = 0 % ~emphase#\end{WithArrows}@\right. \\ % & \Leftrightarrow x+2y=0 % ~emphase#\end{WithArrows}@$ % \end{Verbatim} % % $\begin{WithArrows} % \varphi(x,y)=0 % & \Leftrightarrow (x+2y)^2+(2x+4y)^2 = 0 \Arrow{the numbers are real}\\ % & \Leftrightarrow % \left\{\begin{WithArrows}[c] % x+2y & = 0 \\ % 2x+4y & = 0 % \end{WithArrows}\right. \\ % & \Leftrightarrow % \left\{\begin{WithArrows}[c] % x+2y & = 0 \Arrow[tikz=-]{the same equation}\\ % x+2y & = 0 % \end{WithArrows}\right. \\ % & \Leftrightarrow x+2y=0 % \end{WithArrows}$ % % \bigskip % However, one may want to draw an arrow between rows that are not in the same environment. For example, one may want % to draw the following arrow : % % \bigskip % $\begin{WithArrows}[CodeAfter = {\Arrow[v]{1-2}{2-2}{Division by $2$}}] % \varphi(x,y)=0 % & \Leftrightarrow (x+2y)^2+(2x+4y)^2 = 0 \\ % & \Leftrightarrow % \left\{\begin{WithArrows}[c] % x+2y & = 0 \\ % 2x+4y & = 0 % \end{WithArrows}\right. \\ % & \Leftrightarrow % \left\{\begin{WithArrows}[c] % x+2y & = 0 \\ % x+2y & = 0 % \end{WithArrows}\right. \\ % & \Leftrightarrow x+2y=0 % \end{WithArrows}$ % % % \bigskip % Such a construction is possible by using |\Arrow| in the |CodeAfter| option. Indeed, in |CodeAfter|, a special % version of |\Arrow| is available (we will call it ``|\Arrow| in |CodeAfter|''). % % \smallskip % A command |\Arrow| in |CodeAfter| takes three arguments : % \begin{itemize} % \item a specification of the start row of the arrow ; % \item a specification of the end row of the arrow ; % \item the label of the arrow. % \end{itemize} % As usual, it's also possible to give options within square brackets before or after the three arguments. However, % these options are limited (see below). % % \bigskip % The specification of the row is constructed with the position of the concerned environment in the nesting tree, % followed (after an hyphen) by the number of the row. % % \bigskip % In the previous example, there are two environments |{WithArrows}| nested in the main environment |{WithArrows}|. % % $\begin{WithArrows}[TikzCode = {\path (#1) to node {#3} (#2) ; }] % \varphi(x,y)=0 % & \Leftrightarrow (x+2y)^2+(2x+4y)^2 = 0 \\ % & \Leftrightarrow \color{blue} % \left\{\begin{WithArrows}[c] % x+2y & = 0 \Arrow{environment number 1}\\ % 2x+4y & = 0 % \end{WithArrows}\right. \\ % & \Leftrightarrow \color{red} % \left\{\begin{WithArrows}[c] % x+2y & = 0 \Arrow{environment number 2}\\ % x+2y & = 0 % \end{WithArrows}\right. \\ % & \Leftrightarrow x+2y=0 % \end{WithArrows}$ % % \bigskip % The arrow we want to draw starts in the row~$2$ of the sub-environment number~$1$ (and therefore, the % specification is |1-2|) and ends in the row~$2$ of the sub-environment number~$2$ (and therefore, the % specification is |2-2|). We can draw the arrow with the following command |\Arrow| in |CodeAfter| : % \begin{Verbatim} % $\begin{WithArrows}[~emphase#CodeAfter = {\Arrow{1-2}{2-2}{Division by $2$}}@] % \varphi(x,y)=0 % & \Leftrightarrow (x+2y)^2+(2x+4y)^2 = 0 \\ % ......... % \end{WithArrows}$ % \end{Verbatim} % % $\begin{WithArrows}[CodeAfter = {\Arrow{1-2}{2-2}{Division by $2$}}] % \varphi(x,y)=0 % & \Leftrightarrow (x+2y)^2+(2x+4y)^2 = 0 \\ % & \Leftrightarrow % \left\{\begin{WithArrows}[c] % x+2y & = 0 \\ % 2x+4y & = 0 % \end{WithArrows}\right. \\ % & \Leftrightarrow % \left\{\begin{WithArrows}[c] % x+2y & = 0 \\ % x+2y & = 0 % \end{WithArrows}\right. \\ % & \Leftrightarrow x+2y=0 % \end{WithArrows}$ % % \bigskip % The options allowed for a command |\Arrow| in |CodeAfter| are : |ll|, |lr|, |rl|, |rr|, |v|, |xoffset|, |tikz| % and |TikzCode|. Except |v|, which is specific to |\Arrow| in |CodeAfter|, all these options have their usual % meaning. % % With the option |v|, the arrow drawn is vertical to an abscissa computed with the start row and the end row % only : the intermediate lines are not taken into account unlike with the option |i|. Currently, the option |i| is % not available for the command~|\Arrow| in |CodeAfter|. However, it's always possible to translate an arrow with % |xoffset| (or |xshift| of Tikz). % \begin{Verbatim} % $\begin{WithArrows}[CodeAfter = {\Arrow~emphase#[v]@{1-2}{2-2}{Division by $2$}}] % \varphi(x,y)=0 % & \Leftrightarrow (x+2y)^2+(2x+4y)^2 = 0 \\ % ......... % \end{WithArrows}$ % \end{Verbatim} % % $\begin{WithArrows}[CodeAfter = {\Arrow[v]{1-2}{2-2}{Division by $2$}}] % \varphi(x,y)=0 % & \Leftrightarrow (x+2y)^2+(2x+4y)^2 = 0 \\ % & \Leftrightarrow % \left\{\begin{WithArrows}[c] % x+2y & = 0 \\ % 2x+4y & = 0 % \end{WithArrows}\right. \\ % & \Leftrightarrow % \left\{\begin{WithArrows}[c] % x+2y & = 0 \\ % x+2y & = 0 % \end{WithArrows}\right. \\ % & \Leftrightarrow x+2y=0 % \end{WithArrows}$ % % % \interitem % The package \pkg{witharrows} gives also another command available only in |CodeAfter| : the command % |\MultiArrow|. This command draws a ``rak''. The list of the rows of the environment concerned by this rak are % given in the first argument of the command |\MultiArrow|. This list is given with the syntax of the list in a % |\foreach| command of \pkg{pgfkeys}. % % % \begin{Verbatim} % $\begin{WithArrows}[tikz = rounded corners, % CodeAfter = {~emphase#\MultiArrow{1,...,4}{text}@}] % A & = B \\ % & = C \\ % & = D \\ % & = E \\ % & = F % \end{WithArrows}$ % \end{Verbatim} % % % $\begin{WithArrows}[tikz = rounded corners, % CodeAfter = {\MultiArrow{1,...,4}{text}}] % A & = B \\ % & = C \\ % & = D \\ % & = E \\ % & = F % \end{WithArrows}$ % % \medskip % As of now, there is no option available for the command |\MultiArrow| (maybe in a future release). % % % \bigskip % \section{Arrows from outside environments \{WithArrows\}} % % If someone wants to draw arrows from outside the environments |{WithArrows}|, he can use the Tikz nodes created % in the environments. % % The Tikz name of a node created by \pkg{witharrows} is prefixed by |wa-|. Then, we have a list of numbers which % give the position in the nesting tree and the row number in the environment. At the end, we have the suffixe |l| % for a ``left node'' and |r| for a ``right node''. % % \smallskip % For illustrative purposes, we give an example of nested environments |{WithArrows}|, and, for each ``right % node'', the name of that node.\footnote{There is an option |shownodenames| to show the names of these nodes.} % % \medskip % \[\begin{WithArrows}[shownodes,shownodenames] % A & \vartriangleleft B+B+B+B+B+B+B+B+B+B+B+B+B \\ % & \vartriangleleft \left\{ % \begin{WithArrows}[c] % C & \vartriangleleft D \\ % E & \vartriangleleft F % \end{WithArrows} % \right. \\ % & \vartriangleleft % \left\{ % \begin{WithArrows}[c] % G & \vartriangleleft H+H+H+H+H+H+H \\ % I & \vartriangleleft % \left\{ % \begin{WithArrows} % J &\vartriangleleft K \\ % L &\vartriangleleft M % \end{WithArrows} % \right. % \end{WithArrows} % \right. \\ % & \vartriangleleft % \left\{ % \begin{WithArrows}[c] % N & \vartriangleleft O \\ % P & \vartriangleleft Q % \end{WithArrows} % \right. % \end{WithArrows}\] % % \medskip % The package \pkg{witharrows} provides some tools facilitating the use of these nodes : % \begin{itemize} % \item the command |\WithArrowsLastEnv| gives the number of the last environment of level~$0$ ; % % \item a name can be given to a given environment with the option |name| and, in this case, the nodes created in % the environment will have aliases constructed with this name ; % % \item the Tikz style |WithArrows/arrow| is the style used by \pkg{witharrows} when drawing an arrow\footnote{More % precisely, this style is given to the Tikz option ``|every path|'' before drawing the arrow with the code of the % option |TikzCode|. This style is modified (in TeX scopes) by the option |tikz| of \pkg{witharrows}.} ; % % \item the Tikz style |WithArrows/arrow/tips| is the style for the style of the arrow (loaded by |WithArrows/arrow|). % \end{itemize} % % For example, we can draw an arrow from \texttt{wa-\WithArrowsLastEnv-2-1-2-r.south} to % \texttt{wa-\WithArrowsLastEnv-3-2-r.north} with the following Tikz command (requires the Tikz library |calc|). % % \begin{Verbatim} % \begin{tikzpicture}[remember picture,overlay] % \draw [WithArrows/arrow] % ($(wa-\WithArrowsLastEnv-2-1-2-r.south)+(3mm,0)$) % to ($(wa-\WithArrowsLastEnv-3-2-r.north)+(3mm,0)$) ; % \end{tikzpicture} % \end{Verbatim} % % \[\begin{WithArrows} % A & \vartriangleleft B+B+B+B+B+B+B+B+B+B+B+B+B \\ % & \vartriangleleft \left\{ % \begin{WithArrows}[c] % C & \vartriangleleft D \\ % E & \vartriangleleft F % \end{WithArrows} % \right. \\ % & \vartriangleleft % \left\{ % \begin{WithArrows}[c] % G & \vartriangleleft H+H+H+H+H+H+H \\ % I & \vartriangleleft % \left\{ % \begin{WithArrows} % J &\vartriangleleft K \\ % L &\vartriangleleft M % \end{WithArrows} % \right. % \end{WithArrows} % \right. \\ % & \vartriangleleft % \left\{ % \begin{WithArrows}[c] % N & \vartriangleleft O \\ % P & \vartriangleleft Q % \end{WithArrows} % \right. % \end{WithArrows}\] % % \begin{tikzpicture}[remember picture,overlay] % \draw [WithArrows/arrow] % ($(wa-\WithArrowsLastEnv-2-1-2-r.south)+(3mm,0)$) % to ($(wa-\WithArrowsLastEnv-3-2-r.north)+(3mm,0)$) ; % \end{tikzpicture} % % \medskip % In this case, it would be easier to use a command |\Arrow| in |CodeAfter| but this is an example to explain how % the Tikz nodes created by \pkg{witharrows} can be used. % % \bigskip % In the following example, we create two environments |{WithArrows}| named ``|first|'' and ``|second|'' and we % draw a line between a node of the first and a node of the second. % % \begin{Verbatim} % $\begin{WithArrows}[~emphase#name=first@] % A & = B \\ % & = C % \end{WithArrows}$ % % \bigskip % $\begin{WithArrows}[~emphase#name=second@] % A' & = B' \\ % & = C' % \end{WithArrows}$ % % \begin{tikzpicture}[remember picture,overlay] % \draw [WithArrows/arrow] % ($(~emphase#first@-1-r.south)+(3mm,0)$) % to ($(~emphase#second@-1-r.north)+(3mm,0)$) ; % \end{tikzpicture} % \end{Verbatim} % % % \begin{center} % $\begin{WithArrows}[name=first] % A & = B \\ % & = C % \end{WithArrows}$ % % \bigskip % $\begin{WithArrows}[name=second] % A' & = B' \\ % & = C' % \end{WithArrows}$ % \end{center} % % \begin{tikzpicture}[remember picture,overlay] % \draw [WithArrows/arrow] % ($(first-1-r.south)+(3mm,0)$) % to ($(second-1-r.north)+(3mm,0)$) ; % \end{tikzpicture} % % \section{The environment \{DispWithArrows\}} % \label{DispWithArrows} % % As previously said, the environment |{WithArrows}| bears similarities with the environment |{aligned}| of % |amsmath| (and |mathtools|). This extension also provides an environment |{DispWithArrows}| which is similar to % the environments |{align}| and |{flalign}| of |amsmath|. % % \medskip % The environment |{DispWithArrows}| must be used \emph{outside} math mode. % \begin{Verbatim} % \begin{~emphase#DispWithArrows@} % A & = (a+1)^2 \Arrow{we expand} \\ % & = a^2 + 2a + 1 % \end{~emphase#DispWithArrows@} % \end{Verbatim} % % \begin{DispWithArrows} % A & = (a+1)^2 \Arrow{we expand} \\ % & = a^2 + 2a + 1 % \end{DispWithArrows} % % \medskip % It's possible to use the command |\notag| (or |\nonumber|) to suppress a tag. % % It's possible to use the command |\tag| to put a special tag (e.g. $\star$).\footnote{If \pkg{amsmath} (or % \pkg{mathtools}) is loaded, it's also possible to use |\tag*| which, as in \pkg{amsmath}, typesets the tag % without the parenthesis.} % % It's also possible to put a label to the line of an equation with the command |\label|. % % These commands must be in the second column of the environment. % \begin{Verbatim} % \begin{DispWithArrows} % A & = (a+1)^2 \Arrow{we expand} ~emphase#\notag@ \\ % & = a^2 + 2a + 1 ~emphase#\tag{$\star$} \label{my-equation}@ % \end{DispWithArrows} % \end{Verbatim} % % \begin{DispWithArrows} % A & = (a+1)^2 \Arrow{we expand} \notag \\ % & = a^2 + 2a + 1 \tag{$\star$} \label{my-equation} % \end{DispWithArrows} % A link to the equation \eqref{my-equation}. This link has been composed with |\eqref{my-equation}| (the command % |\eqref| is a command of \pkg{amsmath}). % % \medskip % It's also possible to suppress all the numbers with the option |notag| (or |nonumber|), at the global or % environment level. There is also an environment |{DispWithArrows*}| which suppresses all the numbers. % \begin{Verbatim} % \begin{~emphase#DispWithArrows*@} % A & = (a+1)^2 \Arrow{we expand} \\ % & = a^2 + 2a + 1 % \end{~emphase#DispWithArrows*@} % \end{Verbatim} % % \begin{DispWithArrows*} % A & = (a+1)^2 \Arrow{we expand} \\ % & = a^2 + 2a + 1 % \end{DispWithArrows*} % % \medskip % With the option |fleqn|, the environment is composed flush left (in a way similar to the option |fleqn| of the % class \cls{article}). In this case, the left margin can be controlled with the option |mathindent| (with a name % inspired by the parameter |\mathindent| of standard LaTeX). The default value of this parameter is 25~pt. % % \begin{Verbatim} % \begin{DispWithArrows}[~emphase#fleqn,mathindent = 1cm@] % A & = (a+1)^2 \Arrow{we expand} \\ % & = a^2 + 2a + 1 % \end{DispWithArrows} % \end{Verbatim} % % \begin{DispWithArrows}[fleqn,mathindent = 1cm] % A & = (a+1)^2 \Arrow{we expand} \\ % & = a^2 + 2a + 1 % \end{DispWithArrows} % % \medskip % \emph{Remark} : By design, the option |fleqn| of \pkg{witharrows} is independant of the option |fleqn| of LaTeX. % Indeed, since the environments of \pkg{witharrows} are meant to be used with arrows on the right side, the % user may want to use \pkg{witharrows} with the option |fleqn| (in order to have more space on the right of the % equations for the arrows) while still centering the classical equations. % % \bigskip % If the package \pkg{amsmath} is loaded, it's possible to use the command |\intertext| in the environments % |{DispWithArrows}| and |{DispWithArrows*}| (and even the |\intertext| of \pkg{nccmath} if this package is loaded). % % If the option |leqno| is used (for the document or when the package \pkg{amsmath} is loaded), the labels will be % composed on the left also for the environments |{DispWithArrows}| et |{DispWithArrows*}|. % % \bigskip % The environment |{DispWithArrows}| is similar to the environment |{align}| of \pkg{amsmath}. However, % |{DispWithArrows}| is not constructed upon |{align}| (in fact, it's possible \pkg{witharrows} without % \pkg{amsmath}). % % There are differences between |{DispWithArrows}| and |{align}|. The environment |{DispWithArrows}| allows only 2 % columns. With |{DispWithArrows}|, there is no control of a collision between an equation and its tag. An % environment |{DispWithArrows}| is always unbreakable (even with |\allowdisplaybreaks| of \pkg{amsmath}). The % commands |\label|, |\tag|, |\notag|, |\nonumber| are allowed only in the second column. The labels of % |{DispWithArrows}| are not always drawn by \pkg{showkeys}. % \begin{bfseries} % Last but not least, by default, the elements of a \texttt{\{DispWithArrows\}} are composed in \texttt{textstyle} and not in % \texttt{displaystyle} (it's possible to change this point with the option \texttt{displaystyle}). % \end{bfseries} % % \section{Advanced features} % % % \subsection{The option TikzCode : how to change the shape of the arrows} % % \label{TikzCode} % % The option |TikzCode| allows the user to change the shape of the arrows. % % \smallskip % The value of this option must be a valid Tikz drawing instruction (with the final semi-colon) with three markers % |#1|, |#2| and |#3| for the start point, the end point and the label of the arrow. % % \bigskip % By default, the value is the following : % % \smallskip % \qquad \verb|\draw (#1) to node {#3} (#2) ;| % % % \bigskip % In the following example, we replace this default path by a path with three segments (and the node overwriting % the second segment). % \begin{Verbatim} % \begin{WithArrows}[ygap=5pt,interline=4mm, % ~emphase#TikzCode = {\draw[rounded corners]@ % ~emphase# (~#1) -- ($(~#1) + (5mm,0)$)@ % ~emphase# -- node[circle,@ % ~emphase# draw,@ % ~emphase# auto = false,@ % ~emphase# fill = gray!50,@ % ~emphase# inner sep = 1pt] {\tiny ~#3}@ % ~emphase# ($(~#2) + (5mm,0)$)@ % ~emphase# -- (~#2) ; }@] % E & \Longleftrightarrow 3 (2x+4) = 6 \Arrow{$\div 3$} \\ % & \Longleftrightarrow 2x+4 = 2 \Arrow{$-4$} \\ % & \Longleftrightarrow 2x = -2 \Arrow{$\div 2$} \\ % & \Longleftrightarrow x = -1 % \end{WithArrows} % \end{Verbatim} % % % \[\begin{WithArrows}[ygap=5pt, % interline=4mm, % TikzCode = {\draw[rounded corners] % (#1) % -- % ($(#1) + (5mm,0)$) % -- node[circle, % draw, % auto=false, % fill=gray!50, % inner sep = 1pt] {\tiny #3} % ($(#2) + (5mm,0)$) % -- % (#2) ; }] % E & \Longleftrightarrow 3 (2x+4) = 6 % \Arrow{$\div 3$}\\ % & \Longleftrightarrow 2x+4 = 2 % \Arrow{$-4$}\\ % & \Longleftrightarrow 2x = -2 % \Arrow{$\div 2$} \\ % & \Longleftrightarrow 2x = -1 % \end{WithArrows}\] % % \bigskip % \subsection{Footnotes in the environments of witharrows} % % If you want to put footnotes in an environment |{WithArrows}| or |{DispWithArrows}|, you can use a pair % |\footnotemark|--|\footnotetext|. % % \smallskip % It's also possible to extract the footnotes with the help of the package \pkg{footnote} or the package \pkg{footnotehyper}. % % \smallskip % If \pkg{witharrows} is loaded with the option |footnote| (with |\usepackage[footnote]{witharrows}| or with % |\PassOptionsToPackage|), the package \pkg{footnote} is loaded (if it is not yet loaded) and it is used to % extract the footnotes. % % \smallskip % If \pkg{witharrows} is loaded with the option |footnotehyper|, the package \pkg{footnotehyper} is loaded (if it % is not yet loaded) ant it is used to extract footnotes. % % \smallskip % Caution: The packages \pkg{footnote} and \pkg{footnotehyper} are incompatible. The package \pkg{footnotehyper} is the % successor of the package \pkg{footnote} and should be used preferently. The package \pkg{footnote} has some % drawbacks, in particular: it must be loaded after the package \pkg{xcolor} and it is not perfectly compatible % with \pkg{hyperref}. % % \medskip % In this document, the package \pkg{witharrows} has been loaded with the option |footnotehyper| and we give an % example with a footnote in the label of an arrow: % % \smallskip % $\begin{WithArrows} % A & = (a+b)^2 % \Arrow{We expand\,\footnote{A footnote.}} \\ % & = a^2+b^2+2ab % \end{WithArrows}$ % % % \section{Examples} % % \subsection{With only one column} % % It's possible to use the environment |{WithArrows}| with making use of the left column only, or the right column % only. % % % \begin{Verbatim} % $\begin{WithArrows} % &f(x) \ge g(x) \Arrow{by squaring both sides} \\ % & f(x)^2 \ge g(x)^2 \Arrow{by moving to left side} \\ % & f(x)^2 - g(x)^2 \ge 0 % \end{WithArrows}$ % \end{Verbatim} % % $\begin{WithArrows} % &f(x) \ge g(x) \Arrow{by squaring both sides} \\ % & f(x)^2 \ge g(x)^2 \Arrow{by moving to left side} \\ % & f(x)^2 - g(x)^2 \ge 0 % \end{WithArrows}$ % % \bigskip % \subsection{MoveEqLeft} % % It's possible to use |\MoveEqLeft| of \pkg{mathtools} (if we don't want ampersand on the first line): % % % \begin{Verbatim}[formatcom=\small\color{gray}] % $\begin{WithArrows}[interline=0.5ex] % ~emphase#\MoveEqLeft@ \arccos(x) = \arcsin \frac45 + \arcsin \frac5{13} % \Arrow{because both are in $[-\frac{\pi}2,\frac{\pi}2]$} \\ % & \Leftrightarrow x = \sin\left(\arcsin\frac45 + \arcsin\frac5{13}\right) \\ % & \Leftrightarrow x = \frac45\cos\arcsin\frac5{13} + \frac5{13} \cos\arcsin\frac45 % \Arrow{$\forall x \in [-1,1], \cos(\arcsin x) = \sqrt{1-x^2}$} \\ % & \Leftrightarrow x = \frac45\sqrt{1-\bigl(\frac5{13}\bigr)^2} % + \frac5{13}\sqrt{1-\bigl(\frac45\bigr)^2} % \end{WithArrows}$ % \end{Verbatim} % % % \medskip % $\begin{WithArrows}[interline=0.5ex] % \MoveEqLeft \arccos(x) = \arcsin \frac45 + \arcsin \frac5{13} % \Arrow{because both are in $[-\frac{\pi}2,\frac{\pi}2]$} \\ % & \Leftrightarrow x = \sin\left(\arcsin\frac45 + \arcsin\frac5{13}\right) \\ % & \Leftrightarrow x = \frac45\cos\arcsin\frac5{13} + \frac5{13} \cos\arcsin\frac45 % \Arrow{$\forall x \in [-1,1], \cos(\arcsin x) = \sqrt{1-x^2}$} \\ % & \Leftrightarrow x = \frac45\sqrt{1-\bigl(\frac5{13}\bigr)^2} % + \frac5{13}\sqrt{1-\bigl(\frac45\bigr)^2} % \end{WithArrows}$ % % % \bigskip % \subsection{Modifying the shape of the nodes} % % It's possible to change the shape of the labels, which are Tikz nodes, by modifying the key ``|every node|'' of % Tikz. % % \begin{Verbatim} % \begin{WithArrows}[% % interline = 4mm, % tikz = {~emphase#every node/.style = {circle,@ % ~emphase# draw,@ % ~emphase# auto = false,@ % ~emphase# fill = gray!50,@ % ~emphase# inner sep = 1pt,@ % ~emphase# font = \tiny}@}] % E & \Longleftrightarrow 3 (2x+4) = 6 % \Arrow{$\div 3$}\\ % & \Longleftrightarrow 2x+4 = 2 % \Arrow{$-4$}\\ % & \Longleftrightarrow 2x = -2 % \Arrow{$\div 2$} \\ % & \Longleftrightarrow 2x = -1 % \end{WithArrows} % \end{Verbatim} % % \[\begin{WithArrows}[% % interline = 4mm, % tikz = {every node/.style = {circle, % draw, % auto = false, % fill = gray!50, % inner sep = 1pt, % font = \tiny}}] % E & \Longleftrightarrow 3 (2x+4) = 6 % \Arrow{$\div 3$}\\ % & \Longleftrightarrow 2x+4 = 2 % \Arrow{$-4$}\\ % & \Longleftrightarrow 2x = -2 % \Arrow{$\div 2$} \\ % & \Longleftrightarrow 2x = -1 % \end{WithArrows}\] % % % \bigskip % \subsection{Examples with the option TikzCode} % % We recall that the option |TikzCode| is the Tikz code used by \pkg{witharrows} to draw the arrows. % % \smallskip % The value by defaut of |TikzCode| is \verb|\draw (#1) to node {#3} (#2) ;| where the three markers |#1|, |#2| and % |#3| represent the start raw, the end raw and the label of the arrow. % % % \bigskip % \subsubsection{Example 1} % In the following example, we define the value of |TikzCode| with two instructions |\path| : the first instruction % draws the arrow itself and the second puts the label in a Tikz node in the rectangle delimited by the arrow. % % \begin{Verbatim} % $\begin{WithArrows}[ % displaystyle, % ygap = 2mm, % ystart = 0mm, % ~emphase#TikzCode = {\path[draw] (~#1) -- ++(4.5cm,0) |- (~#2) ;@ % ~emphase# \path (~#1) -- (~#2) @ % ~emphase# node[text width = 4.2cm, right, midway] {~#3} ;}@] % S_n % & = \frac1n \sum_{k=0}^{n-1}\cos\bigl(\tfrac{\pi}2\cdot\tfrac kn\bigr) % ........... % \end{Verbatim} % % % \bigskip % $\begin{WithArrows}[ % displaystyle, % ygap = 2mm, % ystart = 0mm, % TikzCode = {\path[draw] (#1) -- ++(4.5cm,0) |- (#2) ; % \path (#1) -- (#2) % node[text width = 4.2cm, right, midway] {#3} ;}] % S_n % & = \frac1n \sum_{k=0}^{n-1}\cos\bigl(\tfrac{\pi}2\cdot\tfrac kn\bigr) % \Arrow{$\cos x = \Re(e^{ix})$}\\ % & = \frac1n\sum_{k=0}^{n-1} \Re\left(e^{i\frac{k\pi}{2n}}\right) % \Arrow{$\Re(z+z')=\Re(z)+\Re(z')$}\\ % & = \frac1n \Re\left(\sum_{k=0}^{n-1} e^{i\frac{k\pi}{2n}}\right) % \Arrow{$\exp$ is a morphism for $\times$ et $+$} \\ % & = \frac1n \Re \left(\sum_{k=0}^{n-1}\bigl(e^{i\frac{\pi}{2n}}\bigr)^k\right) % \Arrow{sum of terms of a geometric progression of ratio $e^{i\frac{2\pi}n}$}\\ % & = \frac1n \Re \left( \frac{1-\bigl(e^{i\frac{\pi}{2n}}\bigr)^n}{1-e^{i\frac{\pi}{2n}}}\right)\\ % & = \frac1n \Re \left(\frac{1-i}{1-e^{i\frac{\pi}{2n}}}\right) % \end{WithArrows}$ % % \bigskip % \subsubsection{Example 2} % % In the following example, we change the shape of the arrow depending on wether the start raw is longer than the % end row or not. This example requires the Tikz library \pkg{calc}. % % \begin{Verbatim} % \begin{WithArrows}[ll,interline=5mm,xoffset=5mm, % ~emphase#TikzCode = {\draw[rounded corners,@ % ~emphase# every node/.style = {circle,@ % ~emphase# draw,@ % ~emphase# auto = false,@ % ~emphase# inner sep = 1pt,@ % ~emphase# fill = gray!50,@ % ~emphase# font = \tiny }]@ % ~emphase# let \p1 = (~#1),@ % ~emphase# \p2 = (~#2)@ % ~emphase# in \ifdim \x1 > \x2@ % ~emphase# (\p1) -- node {~#3} (\x1,\y2) -- (\p2)@ % ~emphase# \else@ % ~emphase# (\p1) -- (\x2,\y1) -- node {~#3} (\p2)@ % ~emphase# \fi ;}@] % E & \Longleftrightarrow \frac{(x+4)}3 + \frac{5x+3}5 = 7 % \Arrow{$\times 15$}\\ % & \Longleftrightarrow 5(x+4) + 3(5x+3) = 105 \\ % & \Longleftrightarrow 5x+20 + 15x+9 = 105 \\ % & \Longleftrightarrow 20x+29 = 105 % \Arrow{$-29$}\\ % & \Longleftrightarrow 20x = 76 % \Arrow{$\div 20$}\\ % & \Longleftrightarrow x = \frac{38}{10} % \end{WithArrows} % \end{Verbatim} % % % \[\begin{WithArrows}[ll,interline=5mm,xoffset=5mm, % TikzCode = {\draw[rounded corners, % every node/.style = {circle, % draw, % auto = false, % inner sep = 1pt, % fill = gray!50, % font = \tiny}] % let \p1 = (#1), % \p2 = (#2) % in \ifdim \x1 > \x2 % (\p1) -- node {#3} (\x1,\y2) -- (\p2) % \else % (\p1) -- (\x2,\y1) -- node {#3} (\p2) % \fi ;}] % E & \Longleftrightarrow \frac{(x+4)}3 + \frac{5x+3}5 = 7 % \Arrow{$\times 15$}\\ % & \Longleftrightarrow 5(x+4) + 3(5x+3) = 105 \\ % & \Longleftrightarrow 5x+20 + 15x+9 = 105 \\ % & \Longleftrightarrow 20x+29 = 105 % \Arrow{$-29$}\\ % & \Longleftrightarrow 20x = 76 % \Arrow{$\div 20$}\\ % & \Longleftrightarrow x = \frac{38}{10} % \end{WithArrows}\] % % % % \subsection{Automatic numbered loop} % % Assume we want to draw a loop of numbered arrows. In this purpose, it's possible to write a dedicated command % |\NumberedLoop| which will do the job when used in |CodeAfter|. In the following example, we write this command % with |\NewDocumentCommand| of \pkg{xparse} and |\foreach| of \pkg{pgffor} (both packages are loaded when % \pkg{witharrows} is loaded). % % \begin{Verbatim} % \NewDocumentCommand \NumberedLoop {} % {\foreach \j in {2,...,\NbLines} % { \pgfmathtruncatemacro{\i}{\j-1} % \Arrow[rr]{\i}{\j}{\i} } % \Arrow[rr,xoffset=1cm,tikz=<-]{1}{\NbLines}{\NbLines}} % \end{Verbatim} % % The command |\NbLines| is a command available in |CodeAfter| which gives the total number of lines (=rows) of the % current environment (it's a command and not a counter). % % % \bigskip % \begin{Verbatim} % $\begin{WithArrows}[~emphase#CodeAfter = {\NumberedLoop}@] % a.\;& f \text{ est continuous on } E \\ % b.\;& f \text{ est continuous in } 0 \\ % c.\;& f \text{ is bounded on the unit sphere} \\ % d.\;& \exists K > 0\quad \forall x \in E\quad \|f(x)\| \le K \|x\| \\ % e.\;& f \text{ is lipschitzian} % \end{WithArrows}$ % \end{Verbatim} % % \bigskip % \begin{scope} % \NewDocumentCommand \NumberedLoop {} % {\foreach \j in {2,...,\NbLines} % { \pgfmathtruncatemacro{\i}{\j-1} % \Arrow[rr]{\i}{\j}{\i} } % \Arrow[rr,xoffset=1cm,tikz=<-]{1}{\NbLines}{\NbLines}} % % % $\begin{WithArrows}[CodeAfter = {\NumberedLoop}] % a.\;& f \text{ est continuous on } E \\ % b.\;& f \text{ est continuous in } 0 \\ % c.\;& f \text{ is bounded on the unit sphere} \\ % d.\;& \exists K > 0\quad \forall x \in E\quad \|f(x)\| \le K \|x\| \\ % e.\;& f \text{ is lipschitzian} % \end{WithArrows}$ % % % \bigskip % As usual, it's possible to change the characteristic of both arrows and nodes with the option |tikz|. However, if % we want to change the style to have, for example, numbers in parenthesis, the best way is to change the value % of |TikzCode|: % % \begin{Verbatim} % TikzCode = {\draw (~#1) to node {\footnotesize (~#3)} (~#2) ;} % \end{Verbatim} % % \WithArrowsOptions{TikzCode = {\draw (#1) to node {\footnotesize (#3)} (#2) ;}} % % $\begin{WithArrows}[CodeAfter = {\NumberedLoop}] % a.\;& f \text{ est continuous on } E \\ % b.\;& f \text{ est continuous in } 0 \\ % c.\;& f \text{ is bounded on the unit sphere} \\ % d.\;& \exists K > 0\quad \forall x \in E\quad \|f(x)\| \le K \|x\| \\ % e.\;& f \text{ is lipschitzian} \\ % \end{WithArrows}$ % % \end{scope} % % \section{Implementation} % % \subsection{Declaration of the package and extensions loaded} % % % First, \pkg{tikz} and some Tikz libraries are loaded before the |\ProvidesExplPackage|. % They are loaded this way because |\usetikzlibrary| in |expl3| code fails.\footnote{cf. % |tex.stackexchange.com/questions/57424/using-of-usetikzlibrary-in-an-expl3-package-fails|} % % \begin{macrocode} \RequirePackage{tikz} \usetikzlibrary{arrows.meta,bending} % \end{macrocode} % % \bigskip % Then, we can give the traditionnal declaration of a package written with |expl3|: % \begin{macrocode} \RequirePackage{l3keys2e} \ProvidesExplPackage {witharrows} {\myfiledate} {\myfileversion} {Draws arrows for explanations on the right} % \end{macrocode} % % \bigskip % The package \pkg{xparse} will be used to define the environments |{WithArrows}|, |{DispWithArrows}|, % |{DispWithArrows*}| and the document-level commands |\Arrow| and |\WithArrowsOptions|. % \begin{macrocode} \RequirePackage{xparse} % \end{macrocode} % % \bigskip % \subsection{The packages footnote and footnotehyper} % % A few options can be given to the package \pkg{witharrows} when it is loaded (with |\usepackage|, % |\RequirePackage| or |\PassOptionsToPackage|). Currently (version \myfileversion), there are two such options: % |footnote| and |footnotehyper|. With the option |footnote|, \pkg{witharrows} loads \pkg{footnote} and uses it to % extract the footnotes from the environments |{WithArrows}|. Idem for the option |footnotehyper|. % % \medskip % The boolean |\g_@@_footnotehyper_bool| will indicate if the option |footnotehyper| is used. % \begin{macrocode} \bool_new:N \g_@@_footnotehyper_bool % \end{macrocode} % % \medskip % The boolean |\g_@@_footnote_bool| will indicate if the option |footnote| is used, but quicky, it will also be set % to |true| if the option |footnotehyper| is used. % \begin{macrocode} \bool_new:N \g_@@_footnote_bool % \end{macrocode} % % \medskip % We define a set of keys |WithArrows/package| for these options. However, first, we define a ``level of options'' % |\l_@@_level_int| even if, in the version \myfileversion{} of \pkg{witharrows}, this integer is not used by the % options of the set |WithArrows/package|. % \begin{macrocode} \int_new:N \l_@@_level_int % \end{macrocode} % % \begin{macrocode} \keys_define:nn {WithArrows/package} {footnote .bool_gset:N = \g_@@_footnote_bool, footnotehyper .bool_gset:N = \g_@@_footnotehyper_bool} % \end{macrocode} % % \bigskip % We process the options when the package is loaded (with |\usepackage|). % \begin{macrocode} \ProcessKeysOptions {WithArrows/package} % \end{macrocode} % % \medskip % \begin{macrocode} \msg_new:nnn {witharrows} {Option~incompatible~with~Beamer} {The~option~"\tl_use:N \l_keys_key_tl"\ is~incompatible~ with~Beamer~because~Beamer~has~its~own~system~to~extract~footnotes.} % \end{macrocode} % % \begin{macrocode} \msg_new:nnn {witharrows} {footnote~with~footnotehyper~package} {You~can't~use~the~option~footnote~because~the~package~ footnotehyper~has~already~been~loaded.~ If~you~want,~you~can~use~the~option~"footnotehyper"~and~the~footnotes~ within~the~environments~{WithArrows}~will~be~extracted~with~the~tools~ of~the~package~footnotehyper.} % \end{macrocode} % % \begin{macrocode} \msg_new:nnn {witharrows} {footnotehyper~with~footnote~package} {You~can't~use~the~option~"footnotehyper"~because~the~package~ footnote~has~already~been~loaded.~ If~you~want,~you~can~use~the~option~"footnote"~and~the~footnotes~ within~the~environments~{WithArrows}~will~be~extracted~with~the~tools~ of~the~package~footnote.} % \end{macrocode} % % \medskip % \begin{macrocode} \bool_if:NT \g_@@_footnote_bool {\@ifclassloaded {beamer} {\msg_fatal:nn {witharrows} {Option~incompatible~with~Beamer}} {} \@ifpackageloaded{footnotehyper} {\msg_fatal:nn {witharrows} {footnote~with~footnotehyper~package}} {} \usepackage{footnote}} % \end{macrocode} % % \begin{macrocode} \bool_if:NT \g_@@_footnotehyper_bool {\@ifclassloaded {beamer} {\msg_fatal:nn {witharrows} {Option~incompatible~with~Beamer}} {} \@ifpackageloaded{footnote} {\msg_fatal:nn {witharrows} {footnotehyper~with~footnote~package}} {} \usepackage{footnotehyper} \bool_gset_true:N \g_@@_footnote_bool} % \end{macrocode} % The flag |\g_@@_footnote_bool| is raised and so, we will only have to test |\g_@@_footnote_bool| in order to % known if we have to insert an environnement |{savenotes}| (see the definition of environnement |{WithArrows}|). % % \bigskip % \subsection{Some technical definitions} % % We define a Tikz style |@@_node_style| for the nodes that will be created in the |\halign|. The nodes are Tikz % nodes of shape ``rectangle'' but with zero width. An arrow between two nodes starts from the \emph{south} anchor % of the first node and arrives at the \emph{north} anchor of the second node. % \begin{macrocode} \tikzset{@@_node_style/.style= { above = \l_@@_ystart_dim, inner~sep = 0 pt, minimum~width = 0pt, minimum~height = \l_@@_ygap_dim, red, \bool_if:NT \l_@@_shownodes_bool {draw} }} % \end{macrocode} % The color of the nodes is red, but in fact, the nodes will be drawn only when the option |shownodes| is used % (this option is useful for debugging). % % % \bigskip % The style |@@_standard| is load in standard in the |{tikzpicture}| we need. The names of the nodes are prefixed by % |wa| (by security) but also by a prefix which is the position-in-the-tree of the nested environments. % \begin{macrocode} \tikzset{@@_standard/.style= { remember~picture, overlay, name~prefix = wa-\l_@@_prefix_str- }} % \end{macrocode} % % \bigskip % We also define a style for the tips of arrow. The final user of the extension \pkg{witharrows} will use this % style if he wants to draw an arrow directly with a Tikz command in his document (probably using the Tikz nodes % created by |{WithArrows}| in the |\halign|). % \begin{macrocode} \tikzset{WithArrows/arrow/tips/.style = { > = {Straight~Barb[scale=1.2,bend]} }} % \end{macrocode} % % \bigskip % \begin{macrocode} \tikzset{WithArrows/arrow/.style = { align = left, auto = left, font = {\small\itshape}, WithArrows/arrow/tips, bend~left = 45, -> }} % \end{macrocode} % % \bigskip % In order to increase the interline in the environments |{WithArrows}|, we will use the command |\spread@equation| % of \pkg{amsmath}. When used, this command becomes no-op (in the current TeX group). Therefore, it will be % possible to use the environments of \pkg{amsmath} (e.g. |{aligned}|) in an environment |{WithArrows}|. % % Nevertheless, we want the extension \pkg{witharrows} available without \pkg{amsmath}. That's why we give a % definition of |\spread@equation| (this definition will be loaded only if \pkg{amsmath} --- or \pkg{mathtools} --- has % not been loaded yet). % \begin{macrocode} \cs_if_free:NT \spread@equation {\cs_set_protected:Npn \spread@equation {\openup\jot \cs_set_protected:Npn \spread@equation {}}} % \end{macrocode} % Don't put |\cs_set_eq:NN \spread@equation \prog_do_nothing:| in the last line because this would raise errors % with nested environments. % % % \bigskip % \subsection{Variables} % % The boolean |\l_@@_in_witharrows_bool| will be raised if (and only if) we are in an environment |{WithArrows}| % (and not in an environment |{DispWithArrows}| or |{DispWithArrows*}|). % \begin{macrocode} \bool_new:N \l_@@_in_witharrows_bool % \end{macrocode} % % The following sequence is the position of the last environment |{WithArrows}| in the tree of the nested % environments |{WithArrows}|. % \begin{macrocode} \seq_new:N \g_@@_position_in_the_tree_seq \seq_gput_right:Nn \g_@@_position_in_the_tree_seq 1 % \end{macrocode} % % \bigskip % The following counter will give the number of the last environment |{WithArrows}| of level~$0$. This % counter will be used only in the definition of |\WithArrowsLastEnv|. % \begin{macrocode} \int_new:N \g_@@_last_env_int % \end{macrocode} % % \bigskip % The following skip (=glue) is the vertical space inserted between two lines (=rows) of the |\halign|. % \begin{macrocode} \skip_new:N \l_@@_interline_skip % \end{macrocode} % % \bigskip % The following integer indicates the position of the box that will be created: 0 (=|t|=|\vtop|), 1~(=|c|=|\vcenter|) or 2 (=|b|=|\vbox|). % \begin{macrocode} \int_new:N \l_@@_pos_env_int % \end{macrocode} % % \bigskip % \begin{macrocode} \dim_new:N \l_@@_xoffset_dim \dim_set:Nn \l_@@_xoffset_dim {3mm} % \end{macrocode} % % \bigskip % The integer |\l_@@_pos_arrows_int| indicates the position of the arrows with the following code (the option |v| % is accessible only for the arrows in |CodeAfter| where the options |i|, |group| et |groups| are not available). % % \begin{center} % \begin{tabular}{l} % \begin{tabular}{@{}l*8c@{}} % \toprule % option & |rr| & |ll| & |rl| & |lr| & |v| & |i| & |group| & |groups| \\ % \midrule % |\l_@@_pos_arrows_int| & $0$ & $1$ & $2$ & $3$ & $4$ & $5$ & $6$ & $7$ \\ % \bottomrule % \end{tabular} \\ % \footnotesize The option |v| can be used only in |\Arrow| in |CodeAfter| (see below). % \end{tabular} % \end{center} % % \begin{macrocode} \int_new:N \l_@@_pos_arrows_int % \end{macrocode} % % \medskip % When we scan a list of options, we want to be able to raise an error if two options of position of the arrows % are present. That's why we keep the code of the first option of position in a variable called % |\l_@@_previous_pos_arrows_int|. This variable will be set to $-1$ each time we start the scanning of a list of options. % % \begin{macrocode} \int_new:N \l_@@_previous_pos_arrows_int % \end{macrocode} % % \bigskip % % At each possible level for the options (\emph{global}, \emph{environment} or \emph{local}: see below), the new % values will be appended on the right of this token list. % % \bigskip % The dimension |\g_@@_x_dim| will be used to compute the $x$-value for some vertical arrows when one of the % options |i|, |group| and |groups| (values 5, 6 and 7 of |\l_@@_pos_arrows_int|) is used. % \begin{macrocode} \dim_new:N \g_@@_x_dim % \end{macrocode} % % \bigskip % In the |\halign| of an environment |{WithArrows}|, we will have to use three counters: % \begin{itemize} % \item |\g_@@_arrow_int| to count the arrows created in the environment ; % \item |\g_@@_line_int| to count the lines of the |\halign| ; % \item |\g_@@_line_bis_int| to count the lines of the |\halign| which have a second column.\footnote{This counter % is used in order to raise an error if there is a line without the second column (such an situation could raise a % \textsc{pgf} error for an undefined node).} % \end{itemize} % % These three counters will be incremented in a cell of the |\halign| and, therefore, the incrementation must be % global. However, we want to be able to include a |{WithArrows}| in another |{WithArrows}|. To do so, we must % restore the previous value of these counters at the end of an environment |{WithArrows}| and we decide to manage % a stack for each of these counters. % \begin{macrocode} \seq_new:N \g_@@_arrow_int_seq \int_new:N \g_@@_arrow_int \seq_new:N \g_@@_line_int_seq \int_new:N \g_@@_line_int \seq_new:N \g_@@_line_bis_int_seq \int_new:N \g_@@_line_bis_int % \end{macrocode} % % \bigskip % The token list |\l_@@_name_tl| will contain the name of the environment (given with the option |name|). This name % will be used to create aliases for the names of the nodes. % \begin{macrocode} \tl_new:N \l_@@_name_tl % \end{macrocode} % % \bigskip % The boolean |\l_@@_notag_bool| will be used in |{DispWithArrows}|. In particular, it will be raised when the % command |\notag| is used. % \begin{macrocode} \bool_new:N \l_@@_notag_bool % \end{macrocode} % % \bigskip % The token list |\l_@@_tag_tl| will contain the argument of the command |\tag|. % \begin{macrocode} \tl_new:N \l_@@_tag_tl % \end{macrocode} % % \bigskip % The boolean |\l_@@_tag_star_bool| will be raised if the user uses the command |\tag| with a star. % \begin{macrocode} \bool_new:N \l_@@_tag_star_bool % \end{macrocode} % % \bigskip % The command |\@@_label:n| will be linked to |\label| in the second column of the |\halign| of the environment % |{DispWithArrows}|. This command will store its argument in the token list |\l_@@_label_tl|. % \begin{macrocode} \tl_new:N \l_@@_label_tl \cs_set:Nn \@@_label:n {\tl_set:Nn \l_@@_label_tl {#1}} % \end{macrocode} % % % \bigskip % The boolean |\l_@@_fleqn_bool| indicates wether the environments |{DispWithArrows}| must be composed flush left or % centered. It corresponds to the option |fleqn|. % \begin{macrocode} \bool_new:N \l_@@_fleqn_bool % \end{macrocode} % % \bigskip % The dimension |\l_@@_mathindent_dim| is used only by the environments |{DispWithArrows}| : it's the left margin of % the environments |{DispWithArrows}| if the environment |{DispWithArrows}| is composed flush left (option |fleqn|). % \begin{macrocode} \dim_new:N \l_@@_mathindent_dim \dim_set:Nn \l_@@_mathindent_dim {25pt} % \end{macrocode} % % % \bigskip % \subsection{The definition of the options} % % There are four levels where options can be set: % \begin{itemize} % \item with |\usepackage[...]{witharrows}|: this level will be called \emph{package} level (number~$0$); % \item with |\WithArrowsOptions{...}|: this level will be called \emph{global} level (number~$1$); % \item with |\begin{WithArrows}[...]|: this level will be called \emph{environment} level (number~$2$); % \item with |\Arrow[...]| (included in |CodeAfter|): this level will be called \emph{local} level (number~$3$). % \end{itemize} % % \bigskip % The level is specified in the variable |\l_@@_level_int| and the code attached to the options can use this % information to alter its actions. % % \medskip % \begin{macrocode} \int_set:Nn \l_@@_level_int 1 % \end{macrocode} % % \bigskip % We start with a submodule which will be loaded only at the global or the environment level. % % \medskip % The options |t|, |c| and |b| indicate if we will create a |\vtop|, a |\vcenter| or a |\vbox|. This information is % stored in the variable |\l_@@_pos_env_int|. Of course, they are available only in |{WithArrows}| and not in % |{DispWithArrows}| or |{DispWithArrows*}| % \begin{macrocode} \keys_define:nn {WithArrows/GlobalOrEnv} { t .code:n = {\bool_if:NTF \l_@@_in_witharrows_bool {\int_set:Nn \l_@@_pos_env_int 0} {\msg_error:nn {witharrows} {Option~will~be~ignored}}}, t .value_forbidden:n = true, c .code:n = {\bool_if:NTF \l_@@_in_witharrows_bool {\int_set:Nn \l_@@_pos_env_int 1} {\msg_error:nn {witharrows} {Option~will~be~ignored}}}, c .value_forbidden:n = true, b .code:n = {\bool_if:NTF \l_@@_in_witharrows_bool {\int_set:Nn \l_@@_pos_env_int 2} {\msg_error:nn {witharrows} {Option~will~be~ignored}}}, b .value_forbidden:n = true, % \end{macrocode} % % \bigskip % The gap between two consecutive arrows. % \begin{macrocode} ygap .dim_set:N = \l_@@_ygap_dim, ygap .value_required:n = true, ygap .initial:n = 0.4 ex, % \end{macrocode} % % \bigskip % The vertical position of the start point of an arrow. % \begin{macrocode} ystart .dim_set:N = \l_@@_ystart_dim, ystart .value_required:n = true, ystart .initial:n = 0.4 ex, % \end{macrocode} % % \bigskip % Usually, the number of columns in a |{WithArrows}| environment is limited to 2. Nevertheless, it's possible to % have more columns with the option |MoreColumns|. % \begin{macrocode} MoreColumns .code:n = { \msg_redirect_name:nnn {witharrows} {Third~column~in~an~environment~{WithArrows}} {none} }, MoreColumns .value_forbidden:n = true, % \end{macrocode} % % % \bigskip % By default, an error message is raised if there is a line without ampersand (|&|). However, it's possible to % suppress this error with the option |AllowLineWithoutAmpersand|. % \begin{macrocode} AllowLineWithoutAmpersand .code:n = { \msg_redirect_name:nnn {witharrows} {All~lines~must~have~an~ampersand} {none} }, AllowLineWithoutAmpersand .value_forbidden:n = true, % \end{macrocode} % % \bigskip % If the user wants to give a new name to the |\Arrow| command (and the name |\Arrow| remains free). % \begin{macrocode} CommandName .tl_set:N = \l_@@_CommandName_tl, CommandName .initial:n = Arrow , CommandName .value_required:n = true, % \end{macrocode} % % \bigskip % \begin{macrocode} TikzCode .tl_set:N = \l_@@_tikz_code_tl, TikzCode .initial:n = \draw~(#1)~to~node{#3}~(#2)~; , TikzCode .value_required:n = true, % \end{macrocode} % % \bigskip % With the option |displaystyle|, the environments will be composed in |\displaystyle|. % \begin{macrocode} displaystyle .bool_set:N = \l_@@_displaystyle_bool, displaystyle .initial:n = false, % \end{macrocode} % % \bigskip % With the option |shownodes|, the nodes will be drawn in red (useful only for debugging). % \begin{macrocode} shownodes .bool_set:N = \l_@@_shownodes_bool, shownodes .initial:n = false, % \end{macrocode} % % \bigskip % With the option |shownodenames|, the name of the ``right nodes'' will be written in the document (useful only % for debugging). % \begin{macrocode} shownodenames .bool_set:N = \l_@@_shownodenames_bool, shownodenames .initial:n = false, % \end{macrocode} % % \bigskip % With the option |group|, \emph{all} the arrows of the environment are vertical with the same abscissa and at a % leftmost position. % \begin{macrocode} group .code:n = {\int_compare:nNnT \l_@@_previous_pos_arrows_int > {-1} {\msg_error:nn {witharrows} {Two~options~are~incompatible}} \int_set:Nn \l_@@_previous_pos_arrows_int 6 \int_set:Nn \l_@@_pos_arrows_int 6} , group .value_forbidden:n = true, % \end{macrocode} % % \bigskip % With the option |groups| (with a \emph{s}), the arrows of the environment are divided in groups by an argument of % connexity, and, in each group, the arrows are vertical with the same abscissa and at a leftmost position. When % the option |group| or |groups| is used, it's not possible to another option of position like |ll|, |lr|, etc. % for a individual key. % \begin{macrocode} groups .code:n = {\int_compare:nNnT \l_@@_previous_pos_arrows_int > {-1} {\msg_error:nn {witharrows} {Two~options~are~incompatible}} \int_set:Nn \l_@@_previous_pos_arrows_int 7 \int_set:Nn \l_@@_pos_arrows_int 7} , groups .value_forbidden:n = true, % \end{macrocode} % % \bigskip % The option |CodeBefore| gives a code that is executed at the beginning of the environment |{WithArrows}| (after % the eventual |\begin{savenotes}|). % \begin{macrocode} CodeBefore .code:n = {\int_compare:nNnTF \l_@@_level_int = 1 {\msg_error:nn {witharrows} {Option~will~be~ignored}} {\tl_put_right:Nn \l_@@_code_before_tl {#1}}} , CodeBefore .value_required:n = true, % \end{macrocode} % % \bigskip % The option |CodeAfter| gives a code that is executed at the end of the environment |{WithArrows}| (after the % eventual |\end{savenotes}|). % \begin{macrocode} CodeAfter .code:n = {\int_compare:nNnTF \l_@@_level_int = 1 {\msg_error:nn {witharrows} {Option~will~be~ignored}} {\tl_put_right:Nn \l_@@_code_after_tl {#1}}} , CodeAfter .value_required:n = true, % \end{macrocode} % % \bigskip % The option |name| is a name given to the environment. If this option is used, the nodes created in the % environment will have aliases constructed with this name (and it will be easier to use these nodes from outside % the environment). % \begin{macrocode} name .code:n = {\int_compare:nNnTF \l_@@_level_int = 1 {\msg_error:nn {witharrows} {Option~will~be~ignored}} {\tl_set:Nn \l_@@_name_tl {#1}}} , name .value_required:n = true, % \end{macrocode} % % \bigskip % The option |fleqn| indicates wether the environments |{DispWithArrows}| are composed centered or flush left. % \begin{macrocode} fleqn .code:n = {\bool_if:NTF \l_@@_in_witharrows_bool {\msg_error:nn {witharrows} {Option~will~be~ignored}} {\tl_if_eq:nnTF {#1} {true} {\bool_set_true:N \l_@@_fleqn_bool} {\bool_set_false:N \l_@@_fleqn_bool}}}, fleqn .default:n = true, % \end{macrocode} % % \bigskip % The option |mathindent| is the left margin of the environments |{DispWithArrows}| when the option |fleqn| is used. % \begin{macrocode} mathindent .code:n = {\bool_if:NTF \l_@@_in_witharrows_bool {\msg_error:nn {witharrows} {Option~will~be~ignored}} {\dim_set:Nn \l_@@_mathindent_dim {#1}}}, mathindent .value_required:n = true, % \end{macrocode} % % \bigskip % The option |notag| indicates wether the environments |{DispWithArrows}| will be without tags (like |{DispWithArrows*}|). % \begin{macrocode} notag .code:n = {\bool_if:NTF \l_@@_in_witharrows_bool {\msg_error:nn {witharrows} {Option~will~be~ignored}} {\tl_if_eq:nnTF {#1} {true} {\bool_set_true:N \l_@@_notag_bool} {\bool_set_false:N \l_@@_notag_bool}}}, notag .default:n = true, nonumber .meta:n = notag, unknown .code:n = \msg_error:nn {witharrows} {Option~unknown} } % \end{macrocode} % % % \bigskip % Then we define the main module called |WithArrows/General| which will be loaded at all the levels. % % \medskip % The option |tikz| gives Tikz parameters that will be given to the arrow when it is drawn (more precisely, the % parameters will be given to the command |\path| of Tikz). % \begin{macrocode} \keys_define:nn {WithArrows/General} {tikz .code:n = \tikzset {WithArrows/arrow/.append~style = {#1}}, tikz .initial:n = {}, tikz .value_required:n = true, % \end{macrocode} % % \bigskip % The other options are for the position of the arrows. The treatment is the same for the options |ll|, |rr|, |lr|, % |lr| and |i| and that's why a dedicated fonction |\@@_analyze_option_position:n| has been written (see below). % \begin{macrocode} rr .value_forbidden:n = true, rr .code:n = \@@_analyze_option_position:n 0 , ll .value_forbidden:n = true, ll .code:n = \@@_analyze_option_position:n 1 , rl .value_forbidden:n = true, rl .code:n = \@@_analyze_option_position:n 2 , lr .value_forbidden:n = true, lr .code:n = \@@_analyze_option_position:n 3 , i .value_forbidden:n = true, i .code:n = \@@_analyze_option_position:n 5 , % \end{macrocode} % % \bigskip % The option |xoffset| change the $x$-offset of the arrows (towards the right). It's a dimension and not a skip. % It's not possible to change the value of this parameter for a individual arrow if the option |group| or the % option |groups| is used. When we will treat an individual arrow, we will give it the option % |tikz={xshift=\l_@@_xoffset_dim}| (we can't to it at the global or the environment level because the Tikz options % |xshift| are cumulative. % % \begin{macrocode} xoffset .code:n = {\bool_if:nTF {\int_compare_p:nNn \l_@@_level_int = 3 && \int_compare_p:nNn \l_@@_pos_arrows_int > 5} {\msg_error:nn {witharrows} {Option~incompatible~with~"group(s)"}} {\dim_set:Nn \l_@@_xoffset_dim {#1}}} , xoffset .value_required:n = true, % \end{macrocode} % % \bigskip % The option |jot| exists for compatibility. It changes directly the value of the parameter |\jot|, which is a % LaTeX parameter and not a parameter specific to \pkg{witharrows}. It's allowed only at the level of the % environment (maybe we should suppress completely this option in the future). % \begin{macrocode} jot .code:n = {\int_compare:nNnTF \l_@@_level_int = 2 {\dim_set:Nn \jot {#1}} {\msg_error:nn {witharrows} {Option~will~be~ignored}}} , jot .value_required:n = true, % \end{macrocode} % % \bigskip % The option |interline| gives the vertical skip (=glue) inserted between two lines (independently of |\jot|). It's % accepted only at the level of the environment (this last point is a kind of security). Futhermore, this option has a % particular behaviour: it applies only to the current environment and doesn't apply to the nested environments. % \begin{macrocode} interline .code:n = {\int_compare:nNnTF \l_@@_level_int = 2 {\skip_set:Nn \l_@@_interline_skip {#1}} {\msg_error:nn {witharrows} {Option~will~be~ignored}}} , interline .value_required:n = true, % \end{macrocode} % % \bigskip % Eventually, a key |jump| (see below) and a key for unknown keys. % \begin{macrocode} jump .code:n = \msg_error:nn {witharrows} {Option~will~be~ignored} , unknown .code:n = \msg_error:nn {witharrows} {Option~unknown} } % \end{macrocode} % % \bigskip % The key |jump| indicates the number of lines jumped by the arrow (1 by default). This key will be extracted when % the command |\Arrow| will be executed. That's why there is a special module for this key. The key |jump| is % extracted in the command |\Arrow| because we want to compute right away the final line of the arrow (this will be % useful for the options |group| and |groups|). % \begin{macrocode} \keys_define:nn {WithArrows/jump} {jump .code:n = {\int_set:Nn \l_@@_jump_int {#1} \int_compare:nNnF \l_@@_jump_int > 0 {\msg_error:nn {witharrows} {The~option~"jump"~must~be~non~negative}}} , jump .value_required:n = true} % \end{macrocode} % % \bigskip % The following command is for technical reasons. It's used for the following options of position: |ll|, % |lr|, |rl|, |rr| and |i|. The argument is the corresponding code for the position of the arrows. % \begin{macrocode} \cs_new_protected:Nn \@@_analyze_option_position:n {\int_compare:nNnT \l_@@_previous_pos_arrows_int > {-1} {\msg_error:nn {witharrows} {Two~options~are~incompatible}} \int_set:Nn \l_@@_previous_pos_arrows_int {#1} % \end{macrocode} % % It's not possible to use one of the considered options at the level of an arrow (level~2) when the option |group| % or the option |groups| is used. However, if we are at the level of an environment, it's possible to override a % previous option |group| or |groups| (this previous option |group| or |groups| would necessarily have been set at % a global level by |\WithArrowsOptions|). % \begin{macrocode} \bool_if:nTF { \int_compare_p:nNn \l_@@_level_int = 3 && \int_compare_p:nNn \l_@@_pos_arrows_int > 5} {\msg_error:nn {witharrows} {Option~incompatible~with~"group(s)"}} {\int_set:Nn \l_@@_pos_arrows_int {#1}}} % \end{macrocode} % % % \bigskip % |\WithArrowsOptions| is the command of the \pkg{witharrows} package to fix options at the document level. % \begin{macrocode} \NewDocumentCommand \WithArrowsOptions {m} {\int_set:Nn \l_@@_previous_pos_arrows_int {-1} \keys_set_known:nnN {WithArrows/General} {#1} \l_tmpa_tl \keys_set:nV {WithArrows/GlobalOrEnv} \l_tmpa_tl} % \end{macrocode} % % % \bigskip % \subsection{The command Arrow} % % In fact, the internal command is not named |\Arrow| but |\@@_Arrow|. Usually, at the beginning of an environment % |{WithArrows}|, |\Arrow| is set to be equivalent to |\@@_Arrow|. However, the user can change the name with the % option |CommandName| and the user command for |\@@_Arrow| will be different. This mechanism can be useful when % the user has already a command named |\Arrow| he wants to still be able to use in the environment |{WithArrows}|. % % \medskip % \begin{macrocode} \NewDocumentCommand \@@_Arrow {O{} m O{}} { % \end{macrocode} % % The counter |\g_@@_arrow_int| counts the arrows in the environment. The incrementation must be global (|gincr|) % because the command |\Arrow| will be used in the cell of a |\halign|. It's recalled that we manage a stack for % this counter. % \begin{macrocode} \int_gincr:N \g_@@_arrow_int % \end{macrocode} % % We decide to extract immediatly the key |jump| in order to compute the end line. That's the reason why there is a % module |WithArrows/jump| with this sole key. The remainded key-value pairs are stored in |\l_tmpa_tl| and will be % stored further in the properly list of the arrow. % \begin{macrocode} \int_zero_new:N \l_@@_jump_int \int_set:Nn \l_@@_jump_int 1 \keys_set_known:nnN {WithArrows/jump} {#1,#3} \l_tmpa_tl % \end{macrocode} % % \medskip % We will construct a global property list to store the informations of the considered arrow. The four fields of % this property list are ``initial'', ``final'', ``options'' and ``label''. % % \smallskip % \begin{enumerate} % \item First, the line from which the arrow starts: % \begin{macrocode} \prop_put:NnV \l_tmpa_prop {initial} \g_@@_line_int % \end{macrocode} % % \item The line where the arrow ends (that's why it was necessary to extract the key |jump|): % \begin{macrocode} \int_set:Nn \l_tmpa_int {\g_@@_line_int + \l_@@_jump_int} \prop_put:NnV \l_tmpa_prop {final} \l_tmpa_int % \end{macrocode} % % \item All the options of the arrow (it's a token list): % \begin{macrocode} \prop_put:NnV \l_tmpa_prop {options} \l_tmpa_tl % \end{macrocode} % % \item The label of the arrow (it's also a token list): % \begin{macrocode} \prop_put:Nnn \l_tmpa_prop {label} {#2} % \end{macrocode} % \end{enumerate} % % The property list has been created in a local variable for convenience. Now, it will be stored in a global % variable indicating both the position-in-the-tree and the number of the arrow. % % \begin{macrocode} \prop_gclear_new:c {g_@@_arrow_\l_@@_prefix_str _\int_use:N\g_@@_arrow_int _prop} \prop_gset_eq:cN {g_@@_arrow_\l_@@_prefix_str _\int_use:N\g_@@_arrow_int _prop} \l_tmpa_prop } % \end{macrocode} % % \medskip % \begin{macrocode} \cs_new_protected:Nn \@@_Arrow_first_column: % \end{macrocode} % All messages of LaTeX3 must be \emph{fully expandable} and that's why we do the affectation (necessary for a % comparison) before the |\msg_error:nn|. % \begin{macrocode} {\tl_set:Nn \l_tmpa_tl {Arrow} \msg_error:nn {witharrows} {Arrow~in~first~column} \@@_Arrow} % \end{macrocode} % % % \bigskip % \subsection{The environment \{WithArrows\}} % % The command |\@@_pre_environement:| is a code common to the environments |{WithArrows}| and |{DispWithArrows}|. % The argument is the options given to the environment. % \begin{macrocode} \cs_new_protected:Nn \@@_pre_environment:n % \end{macrocode} % % First the initialisation of the three counters |\g_@@_arrow_int|, % |\g_@@_line_int| and |\g_@@_line_bis_int|. However, we have to save their previous values with the three stacks % created for this end. % \begin{macrocode} { \seq_gput_right:NV \g_@@_arrow_int_seq \g_@@_arrow_int \int_gzero:N \g_@@_arrow_int \seq_gput_right:NV \g_@@_line_int_seq \g_@@_line_int \int_gzero:N \g_@@_line_int \seq_gput_right:NV \g_@@_line_bis_int_seq \g_@@_line_bis_int \int_gzero:N \g_@@_line_bis_int % \end{macrocode} % % \bigskip % We also have to update the position on the nesting tree. % \begin{macrocode} \seq_gput_right:Nn \g_@@_position_in_the_tree_seq 1 % \end{macrocode} % % The nesting tree is used to create a prefix which will be used in the names of the Tikz nodes and in the names of % the arrows (each arrow is a property list of four fields). If we are in the second environment |{WithArrows}| % nested in the third environment |{WithArrows}| of the document, the prefix will be |3-2| (although the position % in the tree is $[3,2,1]$ since such a position always ends with a~$1$). First, we do a copy of the % position-in-the-tree and then we pop the last element of this copy (in order to drop the last~$1$). % \begin{macrocode} \seq_set_eq:NN \l_tmpa_seq \g_@@_position_in_the_tree_seq \seq_pop_right:NN \l_tmpa_seq \l_tmpa_tl \str_clear_new:N \l_@@_prefix_str \str_set:Nx \l_@@_prefix_str {\seq_use:Nnnn \l_tmpa_seq {-} {-} {-}} % \end{macrocode} % % \bigskip % We define the command |\\| to be the command |\@@_cr:| (defined below). % \begin{macrocode} \cs_set_eq:NN \\ \@@_cr: \dim_zero:N \mathsurround % \end{macrocode} % % \bigskip % These counters will be used later as variables. % \begin{macrocode} \int_zero_new:N \l_@@_initial_int \int_zero_new:N \l_@@_final_int \int_zero_new:N \l_@@_arrow_int % \end{macrocode} % % \bigskip % The value corresponding to the key |interline| is put to zero before the treatment of the options of the % environment.\footnote{It's recalled that, by design, the option |interline| of an environment doesn't apply % in the nested environments.} % \begin{macrocode} \skip_zero:N \l_@@_interline_skip % \end{macrocode} % % \bigskip % The value corresponding to the key |CodeBefore| is put to nil before the treatment of the options of the % environment, because, of course, we don't want the code executed at the beginning of all the nested % environments~|{WithArrows}|. Idem for |CodeAfter|. % \begin{macrocode} \tl_clear_new:N \l_@@_code_before_tl \tl_clear_new:N \l_@@_code_after_tl % \end{macrocode} % \bigskip % We process the options given to the |{WithArrows}| environment. The level of options is set to 1. % \begin{macrocode} \int_set:Nn \l_@@_previous_pos_arrows_int {-1} \int_set:Nn \l_@@_level_int 2 \keys_set_known:nnN {WithArrows/General} {#1} \l_tmpa_tl \keys_set:nV {WithArrows/GlobalOrEnv} \l_tmpa_tl % \end{macrocode} % % \bigskip % If the option |footnote| or the option |footnotehyper| is used, then we extract the footnotes with an environment % |{savenotes}| (of the package \pkg{footnote} or the package \pkg{footnotehyper}). % \begin{macrocode} \bool_if:NT \g_@@_footnote_bool {\begin{savenotes}} % \end{macrocode} % % \bigskip % We execute the code |\l_@@_code_before_tl| of the option |CodeBefore| of the environment after the eventual % |\begin{savenotes}| and, symetricaly, we will execute the |\l_@@_code_after_tl| before the eventual % |\end{savenotes}| (we have a good reason for the last point : we want to extract the footnotes of the arrows % executed in the |CodeAfter|). % \begin{macrocode} \l_@@_code_before_tl % \end{macrocode} % % \bigskip % If the user has given a value for the option |CommandName| (at the global or at the \emph{environment} level), a % command with this name is defined locally in the environment with meaning |\@@_Arrow|. The default value of the % option |CommandName| is ``|Arrow|'' and thus, by default, the name of the command will be |\Arrow|. % \begin{macrocode} \cs_set_eq:cN \l_@@_CommandName_tl \@@_Arrow} % \end{macrocode} % This is the end of |\@@_pre_environment:n|. % % % \bigskip % Now, we begin the environment |{WithArrows}|. % \begin{macrocode} \NewDocumentEnvironment {WithArrows} {O{}} { \bool_set_true:N \l_@@_in_witharrows_bool \reverse_if:N \if_mode_math: \msg_error:nn {witharrows} {{WithArrows}~used~outside~math~mode} \fi: \cs_set:Npn \notag {\msg_error:nnn {witharrows} {Command~not~allowed~in~{WithArrows}} {\notag}} \cs_set:Npn \nonumber {\msg_error:nnn {witharrows} {Command~not~allowed~in~{WithArrows}} {\nonumber}} \cs_set:Npn \tag ##1 {\msg_error:nnn {witharrows} {Command~not~allowed~in~{WithArrows}} {\tag}} \cs_set:Npn \label ##1 {\msg_error:nnn {witharrows} {Command~not~allowed~in~{WithArrows}} {\label}} \@@_pre_environment:n {#1} % \end{macrocode} % \bigskip % The environment begins with a |\vtop|, a |\vcenter| or a |\vbox|\footnote{Notice that the use of % |\vtop| seems color-safe here...} depending of the value of |\l_@@_pos_env_int| (fixed by the options % |t|, |c| or |b|). The environment |{WithArrows}| must be used in math mode\footnote{An error is raised if the % environment is used outside math mode.} and therefore, we can use |\vcenter|. % \begin{macrocode} \int_case:nn \l_@@_pos_env_int {0 {\vtop} 1 {\vcenter} 2 {\vbox}} \bgroup % \end{macrocode} % % \bigskip % The command |\spread@equation| is the command used by \pkg{amsmath} in the beginning of an alignment to fix the % interline. When used, it becomes no-op. However, it's possible to use \pkg{witharrows} without \pkg{amsmath} % since we have redefined |\spread@equation| (if it is not defined yet). % \begin{macrocode} \spread@equation % \end{macrocode} % % \bigskip % We begin the |\halign| and the preamble. % \begin{macrocode} \ialign\bgroup % \end{macrocode} % % \bigskip % We increment the counter |\g_@@_line_int| which will be used in the names of the Tikz nodes created in the array. % This incrementation must be global (|gincr|) because we are in the cell of a |\halign|. It's recalled that we % manage a stack for this counter. % \begin{macrocode} \int_gincr:N \g_@@_line_int \cs_set_eq:cN \l_@@_CommandName_tl \@@_Arrow_first_column: \strut\hfil $\bool_if:NT \l_@@_displaystyle_bool \displaystyle {##}$ & % \end{macrocode} % % \bigskip % In the second column, we increment the counter |\g_@@_line_bis_int| because we want to count the lines with a % second column and raise an error if there is lines without a second column. Once again, the incrementation must % be global and it's recalled that we manage a stack for this counter too. % \begin{macrocode} \int_gincr:N \g_@@_line_bis_int $\bool_if:NT \l_@@_displaystyle_bool \displaystyle {{}##}$ % \end{macrocode} % % \bigskip % We create the ``left node'' of the line (when using macros in Tikz node names, the macros have to be fully % expandable: here, |\tl_use:N| and |\int_use:N| are fully expandable). % \begin{macrocode} \tl_if_empty:NTF \l_@@_name_tl {\tikz [remember~picture,overlay] \node [@@_node_style, name = wa-\l_@@_prefix_str-\int_use:N\g_@@_line_int-l] {} ;} % \end{macrocode} % If the environment |{WithArrows}| has a name (given with the option |name|), the node has also an alias % constructed with this name. % \begin{macrocode} {\tikz [remember~picture,overlay] \node [@@_node_style, name = wa-\l_@@_prefix_str-\int_use:N\g_@@_line_int-l, alias = \l_@@_name_tl-\int_use:N\g_@@_line_int-l] {} ;} \hfil % \end{macrocode} % % \bigskip % Now, after the |\hfil|, we create the ``right node'' and, if the option |shownodenames| is raised, the name of % the node is written in the document (useful for debugging). % \begin{macrocode} \tl_if_empty:NTF \l_@@_name_tl {\tikz [remember~picture,overlay] \node [@@_node_style, name = wa-\l_@@_prefix_str-\int_use:N\g_@@_line_int-r] {} ;} {\tikz [remember~picture,overlay] \node [@@_node_style, name = wa-\l_@@_prefix_str-\int_use:N\g_@@_line_int-r, alias = \l_@@_name_tl-\int_use:N\g_@@_line_int-r] {} ;} \bool_if:NT \l_@@_shownodenames_bool {\hbox_overlap_right:n {\small wa-\l_@@_prefix_str -\int_use:N\g_@@_line_int}} % \end{macrocode} % % \bigskip % Usually, the |\halign| of an environment |{WithArrows}| will have exactly two columns. Nevertheless, if the user % wants to use more columns (without arrows) it's possible with the option |MoreColumns|. % \begin{macrocode} && \msg_error:nn {witharrows} {Third~column~in~an~environment~{WithArrows}} $\bool_if:NT \l_@@_displaystyle_bool \displaystyle {##}$ \cr } % \end{macrocode} % % \bigskip % We begin the second part of the environment |{WithArrows}|. We have two |\egroup|\,: one for the % |\halign| and one for the |\vtop| (or |\vcenter| or |\vbox|). % \begin{macrocode} {\crcr \egroup \egroup \@@_post_environment:} % \end{macrocode} % This is the end of the environment |{WithArrows}|. % % % \bigskip % The command |\@@_post_environment:| is a code common to the second part of the environment |{WithArrows}| and the % environment |{DispWithArrows}|. % \begin{macrocode} \cs_new_protected:Nn \@@_post_environment: % \end{macrocode} % If there is a line without the second column, we raise an error (a line without the second column could generate % an \textsc{pgf} error for an unknown node since the nodes are created in the second column). % \begin{macrocode} {\int_compare:nNnT \g_@@_line_bis_int < \g_@@_line_int {\msg_error:nn {witharrows} {All~lines~must~have~an~ampersand}} % \end{macrocode} % % \bigskip % It there is really arrows in the environment, we draw the arrows: % \begin{itemize} % \item if neither option |group| or |groups| is used, we can draw directly ; % \item if option |group| or option |groups| is used (|\l_@@_pos_arrows_int| > 5), we have to draw the % arrows group by group ; the macro |\@@_draw_arrows:| does the work. % \end{itemize} % % \begin{macrocode} \int_compare:nNnT \g_@@_arrow_int > 0 {\int_compare:nNnTF \l_@@_pos_arrows_int > 5 \@@_draw_arrows: {\@@_draw_arrows:nn 1 \g_@@_arrow_int}} % \end{macrocode} % % \bigskip % We will execute the code specified in the option |CodeAfter|, after some settings. % \begin{macrocode} \group_begin: \tikzset{every~picture/.style = @@_standard} % \end{macrocode} % The command |\NbLines| is not used by \pkg{witharrows}. It's only a convenience given to the user. % \begin{macrocode} \cs_set:Npn \NbLines {\int_use:N \g_@@_line_int} % \end{macrocode} % The command |\MultiArrow| is available in |CodeAfter|, and we have a special version of |\Arrow|, called % ``|\Arrow| in |CodeAfter|'' in the documentation.\footnote{As for now, |\MultiArrow| has no option, and that's % why its internal name is a name of \pkg{expl3} with the signature |:nn| whereas |\Arrow| in |CodeAfter| provides % options and has the name of a function defined with |\NewDocumentCommand|.} % \begin{macrocode} \cs_set_eq:NN \MultiArrow \@@_MultiArrow:nn \cs_set_eq:cN \l_@@_CommandName_tl \@@_Arrow_code_after \l_@@_code_after_tl \group_end: % \end{macrocode} % % \bigskip % If the option |footnote| or the option |footnotehyper| is used, then we extract the footnotes with an environment % |{footnote}| (of the package \pkg{footnote} or the package \pkg{footnotehyper}). % \begin{macrocode} \bool_if:NT \g_@@_footnote_bool {\end{savenotes}} % \end{macrocode} % % \bigskip % We update the position-in-the-tree. First, we drop the last component and then we increment the last element. % \begin{macrocode} \seq_gpop_right:NN \g_@@_position_in_the_tree_seq \l_tmpa_tl \seq_gpop_right:NN \g_@@_position_in_the_tree_seq \l_tmpa_tl \seq_gput_right:Nx \g_@@_position_in_the_tree_seq {\int_eval:n {\l_tmpa_tl+1}} % \end{macrocode} % % \bigskip % We update the value of the counter |\g_@@_last_env_int|. This counter is used only by the user function % |\WithArrowsLastEnv|. % \begin{macrocode} \int_compare:nNnT {\seq_count:N \g_@@_position_in_the_tree_seq} = 1 {\int_gincr:N \g_@@_last_env_int} % \end{macrocode} % % \bigskip % Finally, we restore the previous values of the three counters |\g_@@_arrow_int|, |\g_@@_line_int| and % |\g_@@_line_bis_int|. It is recalled that we manage three stacks in order to be able to do such a restoration. % \begin{macrocode} \seq_gpop_right:NN \g_@@_arrow_int_seq {\l_tmpa_tl} \int_gset:Nn \g_@@_arrow_int {\l_tmpa_tl} \seq_gpop_right:NN \g_@@_line_int_seq \l_tmpa_tl \int_gset:Nn \g_@@_line_int {\l_tmpa_tl} \seq_gpop_right:NN \g_@@_line_bis_int_seq \l_tmpa_tl \int_gset:Nn \g_@@_line_bis_int {\l_tmpa_tl} } % \end{macrocode} % That's the end of the command |\@@_post_environment:|. % % \bigskip % We give now the definition of |\@@_cr:| which is the definition of |\\| in an environment |{WithArrows}|. The two % \pkg{expl3} commands |\group_align_safe_begin:| and |\group_align_safe_end:| are specifically designed for this % purpose: test the token that follows in a |\halign| structure. % % First, we remove an eventual token |*| since the commands |\\| and |\\*| are equivalent in an environment % |{WithArrows}| (an environment |{WithArrows}|, like an environment |{aligned}| of \pkg{amsmath}, is always unbreakable). % \begin{macrocode} \cs_new_protected:Nn \@@_cr: {\scan_stop: \group_align_safe_begin: \peek_meaning_remove:NTF * \@@_cr_i: \@@_cr_i:} % \end{macrocode} % % \medskip % Then, we peek the next token to see if it's a |[|. In this case, the command |\\| has an optional argument which % is the vertical skip (=glue) to put. % \begin{macrocode} \cs_new_protected:Nn \@@_cr_i: {\peek_meaning:NTF [ {\@@_cr_ii:} {\@@_cr_ii:[\c_zero_dim]} } \cs_new_protected:Npn \@@_cr_ii:[#1] {\group_align_safe_end: % \end{macrocode} % For the environment |{DispWithArrows}|, the behaviour of |\\| is different because we add the third column which % is the column for the tag (number of the equation). % \begin{macrocode} \bool_if:NF \l_@@_in_witharrows_bool {\bool_if:NTF \l_@@_notag_bool % \end{macrocode} % If there is no tag to put, we use as well the third column because you want to raise an error if the user uses % more than two columns. % \begin{macrocode} {&} { % \end{macrocode} % Here, we can't use |\refstepcounter{equation}| (even the |\refstepcounter| modified by |\hyperref|) because if % the user has issued a |\tag| command, we have to use |\l_@@_tag_tl| and not |\theequation|. That's why we do the % incrementation of the counter ``manually'' and, the, we insert some code inspired by the code of |\refstepcounter|. % \begin{macrocode} \tl_if_empty:NT \l_@@_tag_tl {\int_gincr:N \c@equation} % \end{macrocode} % % We store in |\g_tmpa_tl| the tag we will have to compose at the end in the line. We use a global variable because % we will use it in the \emph{next} cell (after the |&|). % \begin{macrocode} \cs_gset:Npx \g_tmpa_tl {\tl_if_empty:NTF \l_@@_tag_tl \theequation \l_@@_tag_tl} \tl_if_empty:NF \l_@@_label_tl { % \end{macrocode} % The following code is inspired from the definition of |\refstepcounter| in |source2e|. % \begin{macrocode} \cs_set_eq:NN \@currentlabel \g_tmpa_tl % \end{macrocode} % The following code is inspired from the redefinition of |\refstepcounter| done by \pkg{hyperref}. It is executed % only if \pkg{hyperref} has been loaded. % \begin{macrocode} \cs_if_exist:NT \hyper@refstepcounter {\cs_set:Npn \This@name {equation} \hyper@refstepcounter{equation}} % \end{macrocode} % Now, we can issue the command |\label|. % \begin{macrocode} \@@_old_label {\l_@@_label_tl}} % \end{macrocode} % We store the boolean |\l_@@_tag_star_bool| in the global variable |\g_tmpa_bool| because we will use it in the % \emph{next} cell (after the |&|). % \begin{macrocode} \bool_gset_eq:NN \g_tmpa_bool \l_@@_tag_star_bool & \cs_set_eq:NN \theequation \g_tmpa_tl \bool_if:NT \g_tmpa_bool {\cs_set:Npn \tagform@ {}} % \end{macrocode} % We use |\@eqnnum| (we recall that there are two definitions of |\@eqnnum|, a standard definition and another, loaded % if the option |\leqno| is used). % \begin{macrocode} \hbox_overlap_left:n \@eqnnum }} \cr\noalign{\skip_vertical:n {#1 + \l_@@_interline_skip} \scan_stop:}} % \end{macrocode} % According to the documentation of \pkg{expl3}, the previous addition in ``|#1 + \l_@@_interline_skip|'' is really % an addition of skips (=glues). % % \bigskip % \subsection{The environment \{DispWithArrows\}} % % % For the environment |{DispWithArrows}|, the construction is a construction of the type: % % |\[\vcenter{\halign to \displaywith {...}}\]| % % The purpose of the |\vcenter| is to have an environment unbreakable. % % \bigskip % \begin{macrocode} \NewDocumentEnvironment {DispWithArrows} {O{}} { % \end{macrocode} % The command |\intertext@| is a command of \pkg{amsmath} which loads the definition of |\intertext| (if it is % loaded, the package \pkg{nccmath} gives a new defintion of |\intertext@|). % \begin{macrocode} \cs_if_exist_use:N \intertext@ \if_mode_math: \msg_error:nn {witharrows} {{DispWithArrows}~used~in~math~mode} \fi: \bool_set_false:N \l_@@_in_witharrows_bool \@@_pre_environment:n {#1} % \end{macrocode} % We use a |\vcenter| in order to prevent page breaks in the environment. % \begin{macrocode} \begin{displaymath} \vcenter \bgroup \spread@equation \bool_if:NTF \l_@@_fleqn_bool {\tabskip = \c_zero_skip} {\tabskip = 0 pt plus 1000 pt minus 1000 pt} % \end{macrocode} % If \pkg{amsmath} is loaded, the LaTeX version of |\label| is stored in |\ltx@label|. If not, it's, of course, % stored in |\label|. We store this definition of |\label| because we will redefine |\label| in the environment. % \begin{macrocode} \cs_if_exist:NTF \ltx@label {\cs_set_eq:NN \_@@_old_label \ltx@label} {\cs_set_eq:NN \_@@_old_label \label} \cs_set:Npn \notag {\msg_error:nnn {witharrows} {Command~not~allowed~in~{DispWithArrows}} {\notag}} \cs_set:Npn \nonumber {\msg_error:nnn {witharrows} {Command~not~allowed~in~{DispWithArrows}} {\nonumber}} \cs_set:Npn \tag ##1 {\msg_error:nnn {witharrows} {Command~not~allowed~in~{DispWithArrows}} {\tag}} \cs_set:Npn \label ##1 {\msg_error:nnn {witharrows} {Command~not~allowed~in~{DispWithArrows}} {\label}} \halign to \displaywidth \bgroup \int_gincr:N \g_@@_line_int \cs_set_eq:cN \l_@@_CommandName_tl \@@_Arrow_first_column: \strut \bool_if:NT \l_@@_fleqn_bool {\hspace{\l_@@_mathindent_dim}} \hfil $\bool_if:NT \l_@@_displaystyle_bool \displaystyle {##}$ \tabskip = \c_zero_skip & \cs_set:Npn \notag {\bool_set_true:N \l_@@_notag_bool} \cs_set_eq:NN \nonumber \notag \cs_set_eq:NN \tag \@@_tag \cs_set_eq:NN \label \@@_label:n $\bool_if:NT \l_@@_displaystyle_bool \displaystyle {{}##}$ \tabskip = 0 pt plus 1000 pt minus 1000 pt \int_gincr:N \g_@@_line_bis_int \tl_if_empty:NTF \l_@@_name_tl {\tikz [remember~picture,overlay] \node [_@@_node_style, name = wa-\l_@@_prefix_str-\int_use:N\g_@@_line_int-l] {} ;} {\tikz [remember~picture,overlay] \node [_@@_node_style, name = wa-\l_@@_prefix_str-\int_use:N\g_@@_line_int-l, alias = \l_@@_name_tl-\int_use:N\g_@@_line_int-l] {} ;} \hfil \tl_if_empty:NTF \l_@@_name_tl {\tikz [remember~picture,overlay] \node [_@@_node_style, name = wa-\l_@@_prefix_str-\int_use:N\g_@@_line_int-r] {} ;} {\tikz [remember~picture,overlay] \node [_@@_node_style, name = wa-\l_@@_prefix_str-\int_use:N\g_@@_line_int-r, alias = \l_@@_name_tl-\int_use:N\g_@@_line_int-r] {} ;} \bool_if:NT \l_@@_shownodenames_bool {\hbox_overlap_right:n {\small wa-\l_@@_prefix_str -\int_use:N\g_@@_line_int}} & ## \tabskip = \c_zero_skip && \msg_error:nn {witharrows} {Third~column~in~an~environment~{DispWithArrows}} \iffalse ## \fi \cr} {\\ % \end{macrocode} % The following |\egroup| is for the |\halign|. % \begin{macrocode} \egroup % \end{macrocode} % The following |\egroup| is for the |\vcenter| (aimed to prevent page breaks). % \begin{macrocode} \egroup \end{displaymath} \@@_post_environment: \ignorespacesafterend } % \end{macrocode} % % % \bigskip % The command |\@@_tag| will be linked to |\tag| in the environment |{DispWithArrows}|. % \begin{macrocode} \NewDocumentCommand \@@_tag {sm} {\bool_set_false:N \l_@@_notag_bool \tl_set:Nn \l_@@_tag_tl {#2} \bool_set:Nn \l_@@_tag_star_bool {#1} % \end{macrocode} % The starred version |\tag*| can't be use if \pkg{amsmath} has not been loaded because this version does the job % by desactivating the command |\tagform@| inserted by \pkg{amsmath} in the (two versions of the) command % |\@eqnnum|.\footnote{There are two versions of |@eqnnum|, a standard version and a version for the option |leqno|.} % \begin{macrocode} \bool_if:nT {#1 && ! \cs_if_exist_p:N \tagform@} { \msg_error:nn {witharrows} {tag*~without~amsmath} } } % \end{macrocode} % % % \bigskip % With the environment |{DispWithArrows*}|, the equations are not numbered. % \begin{macrocode} \NewDocumentEnvironment {DispWithArrows*} {} {\WithArrowsOptions{notag} \DispWithArrows} {\endDispWithArrows} % \end{macrocode} % % \bigskip % \subsection{We draw the arrows} % % \bigskip % |\@@_draw_arrows:| draws the arrows when the option |group| or the option |groups| is used. In both cases, we have % to compute the $x$-value of a group of arrows before actually drawing the arrows of that group. The arrows will % actually be drawn by the macro |\@@_draw_arrows:nn|. % % \begin{macrocode} \cs_new_protected:Nn \@@_draw_arrows: { \group_begin: % \end{macrocode} % % \bigskip % |\l_@@_first_arrow_of_group_int| will be the first arrow of the current group. % % |\l_@@_first_line_of_group_int| will be the first line involved in the group of arrows (equal to the initial line % of the first arrow of the group because the option |jump| is always positive). % % |\l_@@_last_line_of_group_int| will be the last line involved in the group (impossible to guess in advance). % \begin{macrocode} \int_zero_new:N \l_@@_first_arrow_of_group_int \int_zero_new:N \l_@@_first_line_of_group_int \int_zero_new:N \l_@@_last_line_of_group_int \bool_set_true:N \l_@@_new_group_bool % \end{macrocode} % % \bigskip % We begin a loop over all the arrows of the environment. Inside this loop, if a group is finished, we will draw % the lines of that group. % \begin{macrocode} \int_set:Nn \l_@@_arrow_int 1 \int_until_do:nNnn \l_@@_arrow_int > \g_@@_arrow_int { % \end{macrocode} % % \bigskip % We extract from the property list of the current arrow the fields ``initial'' and ``final'' and we store these % values in |\l_@@_initial_int| and |\l_@@_final_int|. However, we have to do a conversion because the components % of a property list are token lists. % \begin{macrocode} \prop_get:cnN {g_@@_arrow_\l_@@_prefix_str _\int_use:N\l_@@_arrow_int _prop} {initial} \l_tmpa_tl \int_set:Nn \l_@@_initial_int {\l_tmpa_tl} \prop_get:cnN {g_@@_arrow_\l_@@_prefix_str _\int_use:N\l_@@_arrow_int _prop} {final} \l_tmpa_tl \int_set:Nn \l_@@_final_int {\l_tmpa_tl} % \end{macrocode} % % \bigskip % We test if the previous arrow was in fact the last arrow of a group. In this case, we have to draw all the arrows % of that group (with the $x$-value computed in |\g_@@_x_dim|). % \begin{macrocode} \bool_if:nT { \int_compare_p:nNn \l_@@_pos_arrows_int = 7 && \int_compare_p:nNn \l_@@_arrow_int > 1 && \int_compare_p:nNn \l_@@_initial_int > \l_@@_last_line_of_group_int} {\@@_draw_arrows:nn \l_@@_first_arrow_of_group_int {\l_@@_arrow_int - 1} \bool_set_true:N \l_@@_new_group_bool} % \end{macrocode} % % \bigskip % The flag |\l_@@_new_group_bool| indicates if we have to begin a new group of arrows. In fact, we have to begin a % new group in two circonstancies: if we are at the first arrow of the environment (that's why the flag is raised % before the beginning of the loop) an if we have just finished a group (that's why the flag is raised in the % previous conditionnal). At the beginning of a group, we have to initialize four variables: % |\l_@@_first_arrow_int|, |\l_@@_first_line_of_group_int|, |\l_@@_last_line_of_group| and |\g_@@_x_dim| (global % for technical reasons). The last two will evolve during the construction of the group. % \begin{macrocode} \bool_if:nTF \l_@@_new_group_bool {\bool_set_false:N \l_@@_new_group_bool \int_set:Nn \l_@@_first_arrow_of_group_int \l_@@_arrow_int \int_set:Nn \l_@@_first_line_of_group_int \l_@@_initial_int \int_set:Nn \l_@@_last_line_of_group_int \l_@@_final_int \begin{tikzpicture} [@@_standard] \tikz@parse@node\pgfutil@firstofone (\int_use:N\l_@@_initial_int-l) \dim_gset:Nn \g_@@_x_dim \pgf@x \end{tikzpicture} } % \end{macrocode} % % \bigskip % If we are not at the beginning of a new group, we actualize |\l_@@_last_line_of_group_int|. % \begin{macrocode} {\int_set:Nn \l_@@_last_line_of_group_int {\int_max:nn \l_@@_last_line_of_group_int \l_@@_final_int}} % \end{macrocode} % % \bigskip % We update the current $x$-value (in |\g_@@_x_dim|) even if we are at the beginning of a group. Indeed, the % previous initialisation of |\g_@@_x_dim| only considers the initial line of the arrows and now we consider all % the lines between the initial and the final line. This is done with |\@@_update_x_value:nn|. We have written a % command for this because it is also used with the option |i| (|\l_@@_pos_arrows_int| = 5). % \begin{macrocode} \@@_update_x_value:nn \l_@@_initial_int \l_@@_final_int % \end{macrocode} % % \bigskip % Incrementation of the index of the loop (and end of the loop). % \begin{macrocode} \int_incr:N \l_@@_arrow_int } % \end{macrocode} % % \bigskip % After the last arrow of the environment, we have to draw the last group of arrows. % \begin{macrocode} \@@_draw_arrows:nn \l_@@_first_arrow_of_group_int \g_@@_arrow_int \group_end: } % \end{macrocode} % % \bigskip % The following code is necessary because we will have to expand an argument exactly 3 times. % \begin{macrocode} \cs_generate_variant:Nn \keys_set:nn {no} \cs_new_protected:Nn \@@_keys_set: {\keys_set:no {WithArrows/General}} % \end{macrocode} % % % \bigskip % The macro |\@@_draw_arrows:nn| draws all the arrows whose numbers are between |#1| and |#2|. |#1| and |#2| % must be expressions that expands to an integer (they are expanded in the beginning of the macro). % \begin{macrocode} \cs_new_protected:Nn \@@_draw_arrows:nn {\group_begin: \int_zero_new:N \l_@@_first_arrow_int \int_set:Nn \l_@@_first_arrow_int {#1} \int_zero_new:N \l_@@_last_arrow_int \int_set:Nn \l_@@_last_arrow_int {#2} % \end{macrocode} % % % \bigskip % We begin a loop over the arrows we have to draw. The variable |\l_@@_arrow_int| (local in the environment % |{WithArrows}|) will be used as index for the loop. % \begin{macrocode} \int_set:Nn \l_@@_arrow_int \l_@@_first_arrow_int \int_until_do:nNnn \l_@@_arrow_int > \l_@@_last_arrow_int { % \end{macrocode} % % \bigskip % We extract from the property list of the current arrow the fields ``initial'' and ``final'' and we store these % values in |\l_@@_initial_int| and |\l_@@_final_int|. However, we have to do a conversion because the components % of a property list are token lists. % % \begin{macrocode} \prop_get:cnN {g_@@_arrow_\l_@@_prefix_str _\int_use:N\l_@@_arrow_int _prop} {initial} \l_tmpa_tl \int_set:Nn \l_@@_initial_int {\l_tmpa_tl} \prop_get:cnN {g_@@_arrow_\l_@@_prefix_str _\int_use:N\l_@@_arrow_int _prop} {final} \l_tmpa_tl \int_set:Nn \l_@@_final_int {\l_tmpa_tl} % \end{macrocode} % % \bigskip % If the arrow ends after the last line of the environment, we raise an error (we recall that, after the % construction of the |\halign|, |\g_@@_line_int| is the total number of lines of the environment). If the initial % node or the final node doesn't exist, we also raise an error.\footnote{This case occurs if the considered line % has no ampersand. In fact, we raise an error if there is such a line in the |\halign|, but, nonetheless, we consider % the case where the user goes on and we try to avoid other errors.} % \begin{macrocode} \int_compare:nNnTF \l_@@_final_int > \g_@@_line_int {\msg_error:nn {witharrows} {Too~few~lines~for~an~arrow}} {\cs_if_free:cTF {pgf@sh@ns@wa-\l_@@_prefix_str-\int_use:N\l_@@_initial_int-l} { \msg_error:nn {witharrows} {A~PGF~node~doesn't~exist} } {\cs_if_free:cTF {pgf@sh@ns@wa-\l_@@_prefix_str-\int_use:N\l_@@_final_int-l} { \msg_error:nn {witharrows} {A~PGF~node~doesn't~exist} } {\@@_draw_arrows_i:}}} \int_incr:N \l_@@_arrow_int } \group_end: } % \end{macrocode} % % \bigskip % The macro |\@@_draw_arrows_i:| is only for the lisibility of the code. This macro will draw the current arrow % if the arrow is not impossible (that is to say if the Tikz node exists). The first |\group_begin:| is for the % options of the arrow. % \begin{macrocode} \cs_new:Nn \@@_draw_arrows_i: {\group_begin: \int_set:Nn \l_@@_previous_pos_arrows_int {-1} \int_set:Nn \l_@@_level_int 3 % \end{macrocode} % % \bigskip % We process the options of the current arrow. The second argument of |\keys_set:nn| must be expanded exactly % three times. An x-expansion is not possible because there can be tokens like |\bfseries| in the option |font| of % the option |tikz|. This expansion is a bit tricky. % \begin{macrocode} \prop_get:cnN {g_@@_arrow_\l_@@_prefix_str _\int_use:N\l_@@_arrow_int _prop} {options} \l_tmpa_tl \exp_args:NNo \exp_args:No \@@_keys_set: {\l_tmpa_tl,tikz={xshift = \l_@@_xoffset_dim}} % \end{macrocode} % % % We create two booleans to indicate the position of the initial node and final node of the arrow in cases of % options |rr|, |rl|, |lr| or |ll|: % \begin{macrocode} \bool_set_false:N \l_@@_initial_r_bool \bool_set_false:N \l_@@_final_r_bool \int_case:nn \l_@@_pos_arrows_int {0 {\bool_set_true:N \l_@@_initial_r_bool \bool_set_true:N \l_@@_final_r_bool} 2 {\bool_set_true:N \l_@@_initial_r_bool} 3 {\bool_set_true:N \l_@@_final_r_bool}} % \end{macrocode} % % \bigskip % \begin{center} % \begin{tabular}{l} % \begin{tabular}{@{}l*8c@{}} % \toprule % option & |rr| & |ll| & |rl| & |lr| & |v| & |i| & |group| & |groups| \\ % \midrule % |\l_@@_pos_arrows_int| & $0$ & $1$ & $2$ & $3$ & $4$ & $5$ & $6$ & $7$ \\ % \bottomrule % \end{tabular} \\ % \footnotesize The option |v| can be used only in |\Arrow| in |CodeAfter| (see below). % \end{tabular} % \end{center} % % \bigskip % In case of option |i| (|\l_@@_pos_arrows_int| = 5), we have to compute the $x$-value of the arrow (which is % vertical). The computed $x$-value is stored in |\g_@@_x_dim| (the same variable used when the option |group| or % the option |groups| is used). This variable is global for technical reasons: we have to do assignments in a Tikz % node. % \begin{macrocode} \int_compare:nNnT \l_@@_pos_arrows_int = 5 { % \end{macrocode} % % \medskip % First, we calculate the initial value for |\g_@@_x_dim|. We use a Tikz command, but, in fact, nothing is drawn. % We use this Tikz command only to read the abscissa of a Tikz node. % \begin{macrocode} \begin{tikzpicture} [@@_standard] \tikz@parse@node\pgfutil@firstofone (\int_use:N\l_@@_initial_int-l) \dim_gset:Nn \g_@@_x_dim \pgf@x \end{tikzpicture} % \end{macrocode} % A global assignment is necessary because of Tikz. % % Then, we will loop to determine the maximal length of the lines between the lines |\l_@@_initial_int| and % |\l_@@_final_int|... but we have written a command dedicated to this work because it will also be used in % |\@@_draw_arrows:|. % \begin{macrocode} \@@_update_x_value:nn \l_@@_initial_int \l_@@_final_int } % \end{macrocode} % % \bigskip % |\l_@@_initial_tl| contains the name of the Tikz node from which the arrow starts (in normal cases... % because with the option |i|, |group| and |groups|, the point will perhaps have another $x$-value --- but always the % same $y$-value). Idem for |\l_@@_final_tl|. % \begin{macrocode} \tl_set:Nx \l_@@_initial_tl {\int_use:N\l_@@_initial_int-\bool_if:NTF\l_@@_initial_r_bool rl .south} \tl_set:Nx \l_@@_final_tl {\int_use:N\l_@@_final_int-\bool_if:NTF\l_@@_final_r_bool rl .north} % \end{macrocode} % We use ``|.south|'' and ``|.north|'' because we want a small gap between two consecutive arrows (and the Tikz % nodes created have the shape of small vertical segments: use option |shownodes| to visualize the nodes). % % \bigskip % The label of the arrow will is stored in |\l_tmpa_tl|. % \begin{macrocode} \prop_get:cnN {g_@@_arrow_\l_@@_prefix_str _\int_use:N\l_@@_arrow_int _prop} {label} \l_tmpa_tl % \end{macrocode} % % \bigskip % We have to compute the coordinates of the extremities of the arrow. We retrieve the coordinates in |\g_tmpa_tl| % and |\g_tmpb_tl|. This extraction of the coordinates is necessary because we must give coordinates and not nodes % (even anchored) to |\@@_draw_arrow:nnn| to have the |xshift| correct. % \begin{macrocode} \int_compare:nNnTF \l_@@_pos_arrows_int < 5 {\begin{tikzpicture} [@@_standard] \tikz@scan@one@point\pgfutil@firstofone(\l_@@_initial_tl) \tl_gset:Nx \g_tmpa_tl {\dim_use:N\pgf@x,\dim_use:N\pgf@y} \tikz@scan@one@point\pgfutil@firstofone(\l_@@_final_tl) \tl_gset:Nx \g_tmpb_tl {\dim_use:N\pgf@x,\dim_use:N\pgf@y} \end{tikzpicture} } % \end{macrocode} % % If we use option |i| or |group| or |groups|, we use the abscissa specially computed in |\g_@@_x_dim|. % \begin{macrocode} {\begin{tikzpicture} [@@_standard] \tikz@scan@one@point\pgfutil@firstofone (\l_@@_initial_tl) \tl_gset:Nx \g_tmpa_tl {\dim_use:N \g_@@_x_dim , \dim_use:N \pgf@y} \tikz@scan@one@point\pgfutil@firstofone (\l_@@_final_tl) \tl_gset:Nx \g_tmpb_tl {\dim_use:N \g_@@_x_dim , \dim_use:N \pgf@y} \end{tikzpicture}} % \end{macrocode} % % \bigskip % Eventually, we can draw the arrow with the code in |\l_@@_tikz_code_tl|. We recall that the value by default for % this token list is :\enskip ``\verb|\draw (#1) to node {#3} (#2) ;|''. This value can be modified % with the option |TikzCode|. We use the variant |\@@_draw_arrow:nno| of the macro |\@@_draw_arrow:nnn| because of % the characters \emph{underscore} in the name |\l_tmpa_tl| : if the user uses the Tikz library |babel|, the third % argument of the command |\@@_draw_arrow:nno| will be rescanned because this third argument will be in the % argument of a command |node| of an instruction |\draw| of Tikz... and we will have an error because of the % characters \emph{underscore}.\footnote{There were other solutions : use another name without \emph{underscore} % (like \Verb|\ltmpatl|) or use the package \pkg{underscore} (with this package, the characters \emph{underscore} % will be rescanned without errors, even in text mode).} % \begin{macrocode} \@@_draw_arrow:nno {\g_tmpa_tl} {\g_tmpb_tl} {\l_tmpa_tl} % \end{macrocode} % % \smallskip % We close the TeX group opened for the options given to |\Arrow[...]| (local level of the options). % \begin{macrocode} \group_end: } % \end{macrocode} % % % \bigskip % The function |@@_tmpa:nnn| will draw the arrow. It's merely an environment |{tikzpicture}|. However, the Tikz % instruction in this environment must be inserted from |\l_@@_tikz_code_tl| with the markers |#1|, |#2| and |#3|. % That's why we create a function |\@@_def_function_tmpa:n| which will create the function |\@@_tmpa:nnn|. % \begin{macrocode} \cs_new_protected:Nn \@@_def_function_tmpa:n {\cs_set:Nn \@@_tmpa:nnn {\begin{tikzpicture}[@@_standard,every~path/.style = {WithArrows/arrow}] #1 \end{tikzpicture}}} % \end{macrocode} % % \medskip % When we draw the arrow (with |\@@_draw_arrow:nnn|), we create first the function |\@@_tmpa:nnn| and, then, we use % the function |\@@_tmpa:nnn| : % \begin{macrocode} \cs_new_protected:Nn \@@_draw_arrow:nnn {\exp_args:No \@@_def_function_tmpa:n \l_@@_tikz_code_tl \@@_tmpa:nnn {#1} {#2} {#3} } \cs_generate_variant:Nn \@@_draw_arrow:nnn {nno} % \end{macrocode} % % % \bigskip % The command |\@@_update_x_value:nn| will analyze the lines\footnote{If a line has no ampersand, this line is % ignored. In fact, we raise an error if there is a line without ampersand but, nonetheless, we consider the case % where the user goes on and we try to avoid other errors.} between |#1| and |#2| in order to modify % |\g_@@_x_dim| in consequence. More precisely, |\g_@@_x_dim| is increased if a line longer than the current value % of |\g_@@_x_dim| is found. |\@@_update_x_value:nn| is used in |\@@_draw_arrows:| (for options |group| and % |groups|) and in |\@@_draw_arrows:nn| (for option |i|). % \begin{macrocode} \cs_new_protected:Nn \@@_update_x_value:nn {\int_step_inline:nnnn {#1} \c_one {#2} {\cs_if_exist:cT {pgf@sh@ns@wa-\l_@@_prefix_str-##1-l} {\begin{tikzpicture} [@@_standard] \tikz@scan@one@point\pgfutil@firstofone (##1-l) \dim_gset:Nn \g_@@_x_dim {\dim_max:nn \g_@@_x_dim \pgf@x} \end{tikzpicture} } } } % \end{macrocode} % % % \bigskip % The command |\WithArrowsLastEnv| is not used by the package \pkg{witharrows}. It's only a facility given to the % final user. It gives the number of the last environment |{WithArrows}| at level~$0$ (to the sens of the nested % environments). This macro is fully expandable and, thus, can be used directly in the name of a Tikz node. % \begin{macrocode} \cs_new:Npn \WithArrowsLastEnv {\int_use:N \g_@@_last_env_int} % \end{macrocode} % % \bigskip % \subsection{The command Arrow in CodeAfter} % % The option |CodeAfter| is an option of the environment |{WithArrows}| (this option is only available at the % environment level). In the option |CodeAfter|, one can use the command |Arrow| but it's a special version of the % command |Arrow|. For this special version (internally called |\@@_Arrow_code_after|), we define a special set of % keys called |WithArrows/CodeAfter|. % % \begin{macrocode} \keys_define:nn {WithArrows/CodeAfter} {tikz .code:n = \tikzset {WithArrows/arrow/.append~style = {#1}} , tikz .value_required:n = true, rr .value_forbidden:n = true, rr .code:n = \@@_analyze_option_position:n 0 , ll .value_forbidden:n = true, ll .code:n = \@@_analyze_option_position:n 1 , rl .value_forbidden:n = true, rl .code:n = \@@_analyze_option_position:n 2 , lr .value_forbidden:n = true, lr .code:n = \@@_analyze_option_position:n 3 , v .value_forbidden:n = true, v .code:n = \@@_analyze_option_position:n 4 , TikzCode .tl_set:N = \l_@@_tikz_code_tl, TikzCode .value_required:n = true, xoffset .dim_set:N = \l_@@_xoffset_dim, xoffset .value_required:n = true} % \end{macrocode} % % % \bigskip % \begin{macrocode} \NewDocumentCommand \@@_Arrow_code_after {O{} mmm O{}} {\int_set:Nn \l_@@_pos_arrows_int 1 \int_set:Nn \l_@@_previous_pos_arrows_int {-1} \group_begin: % \end{macrocode} % Even if |\Arrow| in |CodeAfter| has its own set of options (|WithArrows/CodeAfter|), we set the level of the % options to~$3$ (as with the classical command |\Arrow|) because of the error messages. % \begin{macrocode} \int_set:Nn \l_@@_level_int 3 \keys_set:nn {WithArrows/CodeAfter} {#1,#5,tikz={xshift = \l_@@_xoffset_dim}} \bool_set_false:N \l_@@_initial_r_bool \bool_set_false:N \l_@@_final_r_bool \int_case:nn \l_@@_pos_arrows_int {0 {\bool_set_true:N \l_@@_initial_r_bool \bool_set_true:N \l_@@_final_r_bool} 2 {\bool_set_true:N \l_@@_initial_r_bool} 3 {\bool_set_true:N \l_@@_final_r_bool}} % \end{macrocode} % We test wether the two Tikz nodes |(#2-l)| and |(#3-l)| really exist. If not, the arrow won't be drawn. % \begin{macrocode} \cs_if_free:cTF {pgf@sh@ns@wa-\l_@@_prefix_str-#2-l} {\msg_error:nnx {witharrows} {Wrong~line~specification~in~Arrow} {#2}} {\cs_if_free:cTF {pgf@sh@ns@wa-\l_@@_prefix_str-#3-l} {\msg_error:nnx {witharrows} {Wrong~line~specification~in~Arrow} {#3}} {\int_compare:nNnTF \l_@@_pos_arrows_int = 4 {\begin{tikzpicture} [@@_standard] \tikz@scan@one@point\pgfutil@firstofone(#2-l.south) \dim_set_eq:NN \l_tmpa_dim \pgf@x \dim_set_eq:NN \l_tmpb_dim \pgf@y \tikz@scan@one@point\pgfutil@firstofone(#3-l.north) \dim_set:Nn \l_tmpa_dim {\dim_max:nn \l_tmpa_dim \pgf@x} \tl_gset:Nx \g_tmpa_tl {\dim_use:N \l_tmpa_dim , \dim_use:N \l_tmpb_dim} \tl_gset:Nx \g_tmpb_tl {\dim_use:N \l_tmpa_dim , \dim_use:N \pgf@y} \end{tikzpicture} } {\begin{tikzpicture} [@@_standard] \tikz@scan@one@point\pgfutil@firstofone (#2-\bool_if:NTF\l_@@_initial_r_bool rl .south) \tl_gset:Nx \g_tmpa_tl {\dim_use:N \pgf@x , \dim_use:N \pgf@y} \tikz@scan@one@point\pgfutil@firstofone (#3-\bool_if:NTF\l_@@_final_r_bool rl .north) \tl_gset:Nx \g_tmpb_tl {\dim_use:N \pgf@x , \dim_use:N \pgf@y} \end{tikzpicture}} \@@_draw_arrow:nnn {\g_tmpa_tl} {\g_tmpb_tl} {#4} }} \group_end: } % \end{macrocode} % % % \bigskip % \subsection{MultiArrow} % The command |\@@_MultiArrow:nn| will be linked to |\MultiArrow| when the |CodeAfter| is executed. % % \begin{macrocode} \cs_new_protected:Nn \@@_MultiArrow:nn { % \end{macrocode} % The user of the command |\MultiArrow| (in |CodeAfter|) will be able to specify the list of lines with the same % syntax as the loop |\foreach| of \pkg{pgffor}. That's why we construct a ``clist'' of \pkg{expl3} from the % specification of list given by the user. The construction of the ``clist'' must be global in order to exit the % |\foreach| and that's why we construct the list in |\g_tmpa_clist|. % \begin{macrocode} \foreach \x in {#1} {\cs_if_free:cTF {pgf@sh@ns@wa-\l_@@_prefix_str-\x-l} {\msg_error:nnx {witharrows} {Wrong~line~specification~in~MultiArrow} {\x}} {\clist_gput_right:Nx \g_tmpa_clist {\x}}} % \end{macrocode} % We sort the list |\g_tmpa_clist| because we want to extract the minimum and the maximum. % \begin{macrocode} \int_compare:nNnTF {\clist_count:N \g_tmpa_clist} < 2 {\msg_error:nn {witharrows} {Too~small~specification~for~MultiArrow}} {\clist_sort:Nn \g_tmpa_clist {\int_compare:nNnTF {##1} > {##2} {\sort_return_swapped:} {\sort_return_same:}} % \end{macrocode} % We extract the minimum in |\l_tmpa_tl| (it must be a integer but we store it in a token list of \pkg{expl3}). % \begin{macrocode} \clist_pop:NN \g_tmpa_clist \l_tmpa_tl % \end{macrocode} % % We extract the maximum in |\l_tmpb_tl|. The remaining list (in |\g_tmpa_clist| will be sorted in decreasing order % but never mind...). % \begin{macrocode} \clist_reverse:N \g_tmpa_clist \clist_pop:NN \g_tmpa_clist \l_tmpb_tl % \end{macrocode} % % We draw the teeth of the rak (except the first one and the last one) with the auxiliary function % |\@@_MultiArrow_i:n|. This auxiliary fonction is necessary to expand the specification of the list in the % |\foreach| loop. The first and the last teeth of the rak can't be drawn the same way as the others (think, for % example, to the case of the option ``rounded corners'' is used). % \begin{macrocode} \exp_args:Nx \@@_MultiArrow_i:n {\g_tmpa_clist} % \end{macrocode} % % Now, we draw the rest of the structure. % \begin{macrocode} \begin{tikzpicture}[@@_standard,every~path/.style={WithArrows/arrow}] \draw [<->] ($(\l_tmpa_tl-r.south)+(\l_@@_xoffset_dim,0)$) -- ++(5mm,0) -- node {#2} ($(\l_tmpb_tl-r.south)+(\l_@@_xoffset_dim+5mm,0)$) -- ($(\l_tmpb_tl-r.south)+(\l_@@_xoffset_dim,0)$) ; \end{tikzpicture} } } \cs_new_protected:Nn \@@_MultiArrow_i:n {\begin{tikzpicture}[@@_standard,every~path/.style={WithArrows/arrow}] \foreach \k in {#1} {\draw[<-] ($(\k-r.south)+(\l_@@_xoffset_dim,0)$) -- ++(5mm,0) ;} ; \end{tikzpicture}} % \end{macrocode} % % % \bigskip % \subsection{The error messages of the package} % \begin{macrocode} \msg_new:nnn {witharrows} {Third~column~in~an~environment~{WithArrows}} {By~default,~an~environment~\{WithArrows\}~can~only~have~two~columns.~ Maybe~you~have~forgotten~a~\str_use:N \c_backslash_str \str_use:N \c_backslash_str.~If~you~really~want~more~than~two~columns,~ you~should~use~the~option~"MoreColumns"~at~a~global~level~or~for~ an~environment.~However,~you~can~go~one~for~this~time.} % \end{macrocode} % % \begin{macrocode} \msg_new:nnn {witharrows} {Third~column~in~an~environment~{DispWithArrows}} {An~environment~\{DispWithArrows\}~or~\{DispWithArrows*\}~can~only~have~two~columns.~ If~you~go~on,~you~may~have~an~incorrect~output.} % \end{macrocode} % % \begin{macrocode} \msg_new:nnn {witharrows} {The~option~"jump"~must~be~non~negative} {You~can't~use~a~strictly~negative~value~for~the~option~"jump"~of~command~ \token_to_str:N\Arrow.~ You~can~create~an~arrow~going~backwards~with~ the~option~"<-"~of~Tikz.} % \end{macrocode} % % \begin{macrocode} \msg_new:nnn {witharrows} {Too~few~lines~for~an~arrow} {An~arrow~specified~in~line~\int_use:N \l_@@_initial_int\ can't~be~drawn~ because~it~arrives~after~the~last~line~of~the~environment~(remind~that~ the~command~\token_to_str:N\Arrow\ must~be~in~the~*start*~line~ of~the~arrow).~If~you~go~on,~this~arrow~will~be~ignored.} % \end{macrocode} % % \begin{macrocode} \msg_new:nnn {witharrows} {{WithArrows}~used~outside~math~mode} {The~environment~\{WithArrows\}~should~be~used~only~in~math~mode.~ Nevertheless,~you~can~go~on.} % \end{macrocode} % % \begin{macrocode} \msg_new:nnn {witharrows} {{DispWithArrows}~used~in~math~mode} {The~environment~\{DispWithArrows\}~should~be~used~only~outside~math~mode.~ If~you~go~on,~you~will~have~other~errors.} % \end{macrocode} % % \begin{macrocode} \msg_new:nnn {witharrows} {Two~options~are~incompatible} {You~try~to~use~the~option~"\tl_use:N\l_keys_key_tl"~but~ this~option~is~incompatible~or~redundant~with~the~option~" \int_case:nn\l_@@_previous_pos_arrows_int {0 {rr} 1 {ll} 2 {rl} 3 {lr} 4 {v} 5 {i} 6 {group} 7 {groups}}"~ previously~set~in~the~same~ \int_case:nn\l_@@_level_int {1 {command~\token_to_str:N\WithArrowsOptions} 2 {declaration~of~options~of~the~environment~\{WithArrows\}} 3 {command~\token_to_str:N\Arrow}}.~ If~you~go~on,~I~will~overwrite~the~first~option.} % \end{macrocode} % % \begin{macrocode} \msg_new:nnnn {witharrows} {All~lines~must~have~an~ampersand} {All~lines~of~an~environment~\{WithArrows\}~should~have~an~second~column~ (because~the~nodes~are~created~in~the~second~column).~However,~you~can~go~but~you~will~ have~an~error~if~one~of~your~arrows~needs~an~PGF~node~absent~by~lack~of~ampersand.~ If~you~don't~want~to~see~this~message~again,~you~can~use~the~option~ AllowLineWithoutAmpersand.} {Moreover, the~ampersand~can~be~implicit~ (e.g.~if~you~use~\token_to_str:N\MoveEqLeft\ of~mathtools).} % \end{macrocode} % % \begin{macrocode} \msg_new:nnn {witharrows} {Option~incompatible~with~"group(s)"} {You~try~to~use~the~option~"\tl_use:N\l_keys_key_tl"~while~ you~are~using~the~option~" \int_compare:nNnTF \l_@@_pos_arrows_int = 5 {group} {groups}".~ It's~incompatible.~You~can~go~on~ignoring~this~option~ "\tl_use:N\l_keys_key_tl"~but~you~should~correct~your~code.} % \end{macrocode} % % \begin{macrocode} \msg_new:nnn {witharrows} {Option~will~be~ignored} {The~option~"\tl_use:N\l_keys_key_tl"~can't~be~used~here.~ If~you~go~on,~it~will~be~ignored.} % \end{macrocode} % % % \begin{macrocode} \msg_new:nnn {witharrows} {Option~unknown} {The~option~"\tl_use:N\l_keys_key_tl"~is~unknown~or~ meaningless~in~the~context.~If~you~go~on,~it~will~be~ignored.} % \end{macrocode} % % \begin{macrocode} \msg_new:nnn {witharrows} {Arrow~in~first~column} {You~should~not~use~the~command~\token_to_str:N\Arrow\ \tl_if_eq:NNF \l_@@_CommandName_tl \l_tmpa_tl {(renamed~in~\str_use:N \c_backslash_str \tl_use:N \l_@@_CommandName_tl)~} ~in~the~first~column~but~only~in~the~second~column.~ This~is~a~restriction~of~the~version~1.3~of~the~ package~witharrows~(in~the~aim~of~developping~further~ ~a~new~functionality~with~\token_to_str:N\Arrow\ in~the~ first~column).\\ However~you~can~go~on~for~this~time.} % \end{macrocode} % % \begin{macrocode} \msg_new:nnn {witharrows} {Wrong~line~specification~in~Arrow} {The~specification~of~line~"#1"~you~use~in~\token_to_str:N\Arrow\ ~doesn't~exist.\\ If~you~go~on,~the~arrow~will~be~ignored.} % \end{macrocode} % % \begin{macrocode} \msg_new:nnn {witharrows} {Wrong~line~specification~in~MultiArrow} {The~specification~of~line~"#1"~doesn't~exist.\\ If~you~go~on,~it~will~be~ignored~for~\token_to_str:N \MultiArrow.} % \end{macrocode} % % % \begin{macrocode} \msg_new:nnn {witharrows} {Too~small~specification~for~MultiArrow} {The~specification~of~lines~you~gave~to~\token_to_str:N \MultiArrow\ is~too~small:~we~need~at~least~two~lines.~If~you~go~on,~the~ command~\token_to_str:N\MultiArrow\ ~will~be~ignored.} % \end{macrocode} % % \begin{macrocode} \msg_new:nnn {witharrows} {A~PGF~node~doesn't~exist} {A~PGF~node~necessary~to~draw~an~arrow~doesn't~exist~ because~you~didn't~put~an~ampersand~in~the~corresponding~line.~ If~you~go~on,~the~arrow~will~be~ignored.} % \end{macrocode} % % % \begin{macrocode} \msg_new:nnn {witharrows} {tag*~without~amsmath} {We~can't~use~\token_to_str:N\tag*~because~you~haven't~load~amsmath~ (or~mathtools).~If~you~go~on,~the~command~\token_to_str:N\tag\ will~be~used~instead.} % \end{macrocode} % % % \begin{macrocode} \msg_new:nnn {witharrows} {Command~not~allowed~in~{DispWithArrows}} {The~command~\token_to_str:N #1 is~not~allowed~in~the~first~column~of~\{DispWithArrows\}~but~ only~in~the~second~column~(and,~of~course,~in~the~ environments~of~amsmath).~If~you~go~on,~this~command~will~be~ignored.} % \end{macrocode} % % \begin{macrocode} \msg_new:nnn {witharrows} {Command~not~allowed~in~{WithArrows}} {The~command~\token_to_str:N #1 is~not~allowed~in~\{WithArrows\}~but~is~allowed~in~the~second~ column~of~\{DispWithArrows\}~(and,~of~course,~in~the~ environments~of~amsmath).~If~you~go~on,~this~command~will~be~ignored.} % \end{macrocode} % \section{History} % % \subsection{Changes between versions 1.0 and 1.1} % % Option for the command |\\| and option |interline| % % Compatibility with |\usetikzlibrary{babel}| % % Possibility of nested environments |{WithArrows}| % % Better error messages % % Creation of a \textsc{dtx} file % % \subsection{Changes between versions 1.1 and 1.2} % % The package \pkg{witharrows} can now be loaded without having loaded previously \pkg{tikz} and the libraries % |arrow.meta| and |bending| (this extension and these libraries are loaded silently by \pkg{witharrows}). % % New option |groups| (with a \emph{s}) % % Better error messages % % \subsection{Changes between versions 1.2 and 1.3} % % New options |ygap| and |ystart| for fine tuning. % % Minor bugs. % % \subsection{Changes between versions 1.3 and 1.4} % % The package \pkg{footnote} is no longer loaded by default. Instead, two options |footnote| and |footnotehyper| have % been added. In particular, \pkg{witharrows} becomes compatible with \cls{beamer}. % % \subsection{Changes between versions 1.4 and 1.5} % % The Tikz code used to draw the arrows can be changed with the option |TikzCode|. % % Two new options |CodeBefore| and |CodeAfter| have been added at the environment level. % % A special version of |\Arrow| is available in |CodeAfter| in order to draw arrows in nested environments. % % A command |\MultiArrow| is available in |CodeAfter| to draw arrows of other shapes. % % \subsection{Changes between versions 1.5 and 1.6} % % The code has been improved to be faster and the Tikz library |calc| is no longer required. % % A new option |name| is available for the environments |{WithArrows}|. % % \subsubsection{Changes between 1.6 and 1.6.1} % % Correction of a bug that leads to incompatibility with |\usetikzlibrary{babel}|. % % \subsection{Changes between 1.6.1 and 1.7} % % New environment |{DispWithArrows}|. % \endinput % % Local Variables: % TeX-fold-mode: nil % End: