diff options
author | Karl Berry <karl@freefriends.org> | 2017-11-06 21:58:05 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2017-11-06 21:58:05 +0000 |
commit | 9b3715d6ade58a41883a912d6c01e1e502645323 (patch) | |
tree | 4330c6b99cdc0e6c53a151d0c239f1081ee1d896 /Master | |
parent | 713a738c1b7e7ed5eacd4ebfdab7c34b0325c08f (diff) |
witharrows (6nov17)
git-svn-id: svn://tug.org/texlive/trunk@45707 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r-- | Master/texmf-dist/doc/latex/witharrows/README.md | 4 | ||||
-rw-r--r-- | Master/texmf-dist/doc/latex/witharrows/witharrows.pdf | bin | 124003 -> 209455 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/witharrows/witharrows.tex | 785 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/witharrows/witharrows.dtx | 2098 | ||||
-rw-r--r-- | Master/texmf-dist/source/latex/witharrows/witharrows.ins | 47 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/witharrows/witharrows.sty | 792 |
6 files changed, 2509 insertions, 1217 deletions
diff --git a/Master/texmf-dist/doc/latex/witharrows/README.md b/Master/texmf-dist/doc/latex/witharrows/README.md index 10ca27cb4f7..7b5f7d31398 100644 --- a/Master/texmf-dist/doc/latex/witharrows/README.md +++ b/Master/texmf-dist/doc/latex/witharrows/README.md @@ -1,4 +1,4 @@ -The LaTeX extension witharrows is distributed under the LPPL 1.3 license. +The LaTeX extension witharrows is distributed under the LPPL 1.3 license. This extension has been written by F. Pantigny (fpantigny at wanadoo point fr). @@ -6,4 +6,4 @@ This extension is entirely contained in a single file : witharrows.sty The extension witharrows gives a LaTeX environment {WithArrows} which is similar to the environment {aligned} of amsmath but which gives the possibility to draw arrows -on the right side of the equations for explanations.
\ No newline at end of file +on the right side of the equations for explanations. diff --git a/Master/texmf-dist/doc/latex/witharrows/witharrows.pdf b/Master/texmf-dist/doc/latex/witharrows/witharrows.pdf Binary files differindex fe3b4175df5..e0d50a7fc31 100644 --- a/Master/texmf-dist/doc/latex/witharrows/witharrows.pdf +++ b/Master/texmf-dist/doc/latex/witharrows/witharrows.pdf diff --git a/Master/texmf-dist/doc/latex/witharrows/witharrows.tex b/Master/texmf-dist/doc/latex/witharrows/witharrows.tex deleted file mode 100644 index 675da4518ee..00000000000 --- a/Master/texmf-dist/doc/latex/witharrows/witharrows.tex +++ /dev/null @@ -1,785 +0,0 @@ -% This document is compatible with the following workflows : -% pdflatex, -% xelatex (with xdvipdfmx), -% latex --> dvips --> ps2pdf (or Adobe Distiller). -\documentclass{article} - -\usepackage{ifxetex} - -\ifxetex - \usepackage{xltxtra} -\else - \usepackage{expl3} - \usepackage{xparse} - \usepackage[T1]{fontenc} -\fi - -\usepackage{xspace} - - -\usepackage[dvipsnames]{xcolor} - -\usepackage{lmodern} - -\ifxetex - \usepackage[xetex]{geometry} -\else - \usepackage{geometry} -\fi - -\geometry{papersize={16.5cm,24cm},total={12.5cm,21cm},headheight=13.2pt,includeheadfoot,twoside,centering} - - -\usepackage{tikz} -\usetikzlibrary{calc} -\usetikzlibrary{arrows.meta} -\usetikzlibrary{bending} -\usetikzlibrary{decorations.pathreplacing} - - -\usepackage{footnote} - -\usepackage{witharrows} - -\usepackage{fancyvrb} -\usepackage{mathtools} - - -% this following lines only for this document - -\usepackage{amsfonts} - -\def\interitem{\vskip 7mm plus 2 mm minus 3mm} -\def\emphase#1{{\color{RoyalPurple}#1}} -\fvset{commandchars=\~\#\@,formatcom={\color{gray}}} -\DeclareMathOperator{\re}{Re} -\let\group\begingroup - - -\begin{document} - - -\parindent0pt - -\title{Extension witharrows, v. 1.0} - -\author{Fran\c cois Pantigny} - -\date{2017/08/17} - -\maketitle - - - -\begin{abstract} -The LaTeX package \verb|witharrows| gives an environment \verb|{WithArrows}| which is similar to environment -\verb|{aligned}| of \verb|amsmath| (and \verb|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 uses Tikz to draw the arrows. It can be used with \verb|xelatex|, \verb|pdflatex| but also by the -classical workflow \verb|latex|-\verb|dvips|-\verb|ps2pdf| (or Distiller). Two compilations may be necessary. - -\medskip -This package gives an environment \verb|{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 \verb|\Arrow| on the ligne from which it starts. The command \verb|\Arrow| -can be used anywhere on the line but the best way is to put it at the end. - - -\medskip -The ends of the lines of the tabular can be coded by \verb|\\| but also by \verb|\cr| (like in the command -\verb|\halign| of TeX). In fact, in an environment \verb|{WithArrows}|, the command \verb|\\| has no option for the -spacing between rows like in many environments of LaTeX. - - - - -\section{Options for the shape of the arrows} - -The commande \verb|\Arrow| has several options. These options can be put between square brackets, before, or after -the mandatory argument. - -The option \verb|jump| gives the number of lines the arrow must jump (the default value is, of course,~$1$) -\footnote{It's not possible to give a non-positive value to \texttt{jump}. See below the way to draw an arrow which -goes backwards.} -% -\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 line. -% -\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 \verb|xoffset| shift the arrows to the right (we usually don't want the arrows to be stucked -on the text). The default value of \verb|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 \verb|\Arrow| has an option -\verb|tikz| which can be used to give to the arrow (in fact, the command \verb|\path| of Tikz) the options -proposed by Tikz for such an arrow. The following example gives an blue thick arrow. -% -\begin{Verbatim} -$\begin{WithArrows} -A & = (a+1)^2 \Arrow[~emphase#tikz={blue,thick}@]{we expand} \\ - & = a^2 + 2a + 1 -\end{WithArrows}$ -\end{Verbatim} - -$\begin{WithArrows} -A & = (a+1)^2 \Arrow[tikz={blue,thick}]{we expand} \\ - & = a^2 + 2a + 1 -\end{WithArrows}$ - - - -\interitem -It's also possible to change the arrowheadss. For example, we can draw an arrow which goes backwards -with the Tikz option~\verb|<-|. -% -\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 \verb|-|. -% -\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 ``\verb|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}$ - - - -\interitem -One of the most useful options is ``\verb|text width|'' to control the with 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 -\verb|\bfseries|, \verb|\large| or \verb|\sffamily| at the beginning of the text. But, by default, the texts -are composed with a combination of \verb|\small| and \verb|\itshape|. When adding \verb|\bfseries| at the beginning -of the text, we won't suppress the \verb|\small| and the \verb|\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 \verb|\\| 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 \verb|\\| (like in a environment \verb|{tabular}|). That's why -Tikz gives a option \verb|font| to modify the font of the whole text. Nevertheless, if we use the option -\verb|tikz={font={\bfseries}}|, the default specification of \verb|\small| and \verb|\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 \verb|font| the value -\verb|{\itshape\small\bfseries}|. - - - - -\interitem -Almost all the options can be given directly to the environment \verb|WithArrows| (between square brackets). -In this case, they apply to all the arrows of the environment. -% -\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 \verb|{WithArrows}| has an option \verb|displaystyle|. With this option, all the elements are -composed in \verb|\displaystyle| (like in an environment \verb|{aligned}| of \verb|amsmath|). - -\medskip -Without the option \verb|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 \verb|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 -Almost all the options can also be set at the document level with the command \verb|\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 \verb|{WithArrows}| composed in \verb|\displaystyle| with blue -arrows, we can write \verb|\WithArrowsOptions{displaystyle,tikz=blue}|.\footnote{It's also possible to give the - options directly when loading the package, \emph{i.e.} with the command \texttt{\string\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{group} -\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{group} - - -\interitem -The command \verb|\Arrow| is recognized only in the environments \verb|{WithArrows}|. If we have a command -\verb|\Arrow| previously defined, it's possible to go on using it outside the environments \verb|{WithArrows}|. - -However, a previouly defined command \verb|\Arrow| may still be useful in a environment \verb|{WithArrows}|. If we -want to use it in such an environment, it's possible to change the name of the command \verb|\Arrow| of the package -\verb|witharrows| : there is an option \verb|CommandName| for this purpose. The new name of the command must be -given to the option \emph{without} the leading backslash. -% -\begin{Verbatim} -\def\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{group} -\def\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{group} - - -\interitem -It's possible to use directly the nodes created by \verb|{WithArrows}| (see below) with explicit Tikz instructions -(in order, for example, to draw something that can't be drawn with the command \verb|\Arrow|). That's why a style -for the tips of the arrows has be created : \verb|TipsOfWithArrows|. By using this style, we will have homogeneous -tips for the arrows of the document. - -Therefore, if we want to modify the tips of the arrows of \verb|{WithArrows}|, we have to modify the style -\verb|TipsOfWithArrows|. -% -\begin{Verbatim} -\tikzset{TipsOfWithArrows/.style= { > = {Latex[scale=1.2,bend]}} } -\end{Verbatim} - - - - -\section{Precise positioning of the arrows} - - -The environment \verb|{WithArrows}| defines, during the composition of the array, two series of nodes materialized in -red in the following example.\footnote{The option \texttt{shownodes} can be used to materialize the nodes.} - -\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}.\footnote{The names of the Tikz nodes created by \texttt{\{WithArrows\}} are \texttt{wa-}$n$\texttt{-l} and - \texttt{wa-}$n$\texttt{-r} where $n$~is the number of the line. It's possible to refer to these Tikz nodes after the - environment (one should use the options \texttt{remember picture} and \texttt{overlay} and also - \texttt{TipsOfWithArrows} and \texttt{->} in order to have the same arrowheads).} - -By default, the arrows use the right nodes. We will say that they are in \verb|rr| mode ($r$ for \emph{right}). -These arrows are \verb|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 -\verb|lr|, \verb|rl| and \verb|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 \verb|{WithArrows}| gives also a \verb|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 remplace $y_0$ by its value.}\\ -& \Longleftrightarrow 2xK'x^{\frac32} = x^{\frac12} \Arrow{simplification of the $x$}\\ -& \Longleftrightarrow K' = \tfrac1{2x²} \Arrow{antiderivation}\\ -& \Longleftrightarrow K = -\tfrac1{2x} -\end{WithArrows}$ - - -\bigskip -If desired, the option \verb|group| can be given to the command \verb|WithArrowsOptions| so that it will become the -default value. - - -\section{Comparison with the environment \{aligned\}} - - - -\verb|{WithArrows}| bears similarities with the environment \verb|{aligned}| of the extension -\verb|amsmath|. These are only similarities because \verb|{WithArrows}| has not been written upon the environment -\verb|{aligned}|. - -In paticular, the command \verb|\\| of the end of line has no option to change the row spacings. In fact, this -command \verb|\\| can be replaced, in a environment \verb|{WithArrows}| by a \verb|\cr| of TeX. That's what we will -do in the balance of this document. - - - - -\interitem -If desired, it's possible to change the spacing between two given lines by putting a command -\verb|\vspace| in a \verb|\noalign| (which is a low level command of TeX to insert extraordinary elements between -the lines of an array). -% -\begin{Verbatim} -$\begin{WithArrows} -A & = (a+1)^2 \Arrow{we expand} \cr -~emphase#\noalign{\vspace{3mm}}@ - & = a^2 + 2a + 1 -\end{WithArrows}$ -\end{Verbatim} - -$\begin{WithArrows} -A & = (a+1)^2 \Arrow{we expand} \cr -\noalign{\vspace{3mm}} - & = a^2 + 2a + 1 -\end{WithArrows}$ - - -\interitem -In the environments of \verb|amsmath|, the spacing between lines is fixed by a parameter called -\verb|\jot| and that's also the case for the environment \verb|{WithArrows}|. An option \verb|jot| has been given -to the environment \verb|{WithArrows}| in order to change the value of this parameter \verb|\jot| for an given environment. -% -\begin{Verbatim} -$\begin{WithArrows}[displaystyle,~emphase#jot=2mm@] -F & = \frac12G \Arrow{we expand}\cr - & = H + \frac12K \Arrow{we go on}\cr - & = K -\end{WithArrows}$ -\end{Verbatim} - -$\begin{WithArrows}[displaystyle,jot=2mm] -F & = \frac12G \Arrow{we expand}\cr - & = H + \frac12K \Arrow{we go on}\cr - & = K -\end{WithArrows}$ - - -\interitem -Like the environment \verb|{aligned}|, \verb|{WithArrows}| has an option of placement which can assume the values -\verb|t|, \verb|c| or \verb|b|. However, the default value is not \verb|c| but \verb|t|. If desired, it's possible -to have the \verb|c| value as the default with the command \verb|WithArrowsOptions{c}| at the beginning of the document. -% -\begin{Verbatim} -~emphase#Et donc\enskip@ -$\begin{WithArrows} -A & = (a+1)^2 \Arrow{we expand} \cr - & = a^2 + 2a + 1 -\end{WithArrows}$ -\end{Verbatim} - -Et donc\enskip -$\begin{WithArrows} -A & = (a+1)^2 \Arrow{we expand} \cr - & = a^2 + 2a + 1 -\end{WithArrows}$ - -\bigskip -The value \verb|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}\cr -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}\cr -g(x) & = 5x^2-5x+6 -\end{WithArrows} -\right.$ - - -\interitem -Unlike \verb|{aligned}|, the environment \verb|{WithArrows}| uses \verb|\textstyle| by default. - -Once again, it's possible to change this behaviour with \verb|WithArrowsOptions| : - -\quad \verb|WithArrowsOptions{displaystyle}|. - - -\smallskip -The following example is composed with \verb|{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 \verb|{WithArrows}[c,displaystyle]|. The results are stricly identical.\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{Examples} - -It's possible to use the environment \verb|{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} \cr -& f(x)^2 \ge g(x)^2 \Arrow{by moving to left side} \cr -& f(x)^2 - g(x)^2 \ge 0 -\end{WithArrows}$ -\end{Verbatim} - -$\begin{WithArrows} -&f(x) \ge g(x) \Arrow{by squaring both sides} \cr -& f(x)^2 \ge g(x)^2 \Arrow{by moving to left side} \cr -& f(x)^2 - g(x)^2 \ge 0 -\end{WithArrows}$ - - -\interitem -Here is an example with a loop flow. -% -\begin{Verbatim}[formatcom=\small\color{gray}] -$\begin{WithArrows}[tikz={font={\tiny}}] -a.\;& f \text{ est continuous on } E -\Arrow{(1)}\Arrow[tikz=<-,jump=4,xoffset=1cm]{(5)}\cr -b.\;& f \text{ est continuous in } 0 -\Arrow{(2)}\cr -c.\;& f \text{ is bounded on the unit sphere} -\Arrow{(3)}\cr -d.\;& \exists K > 0\quad \forall x \in E\quad \|f(x)\| \le K \|x\| -\Arrow{(4)}\cr -e.\;& f \text{ is lipschitzian} -\end{WithArrows}$ -\end{Verbatim} - -$\begin{WithArrows}[tikz={font={\tiny}}] -a.\;& f \text{ est continuous on } E -\Arrow{(1)}\Arrow[tikz=<-,jump=4,xoffset=1cm]{(5)}\cr -b.\;& f \text{ est continuous in } 0 -\Arrow{(2)}\cr -c.\;& f \text{ is bounded on the unit sphere} -\Arrow{(3)}\cr -d.\;& \exists K > 0\quad \forall x \in E\quad \|f(x)\| \le K \|x\| -\Arrow{(4)}\cr -e.\;& f \text{ is lipschitzian} -\end{WithArrows}$ - -\interitem -The option \verb|font| of Tikz contains in fact a list of tokens which will be placed at the beginning of the text. - -These tokens can be true commands for a changement of font (like \verb|\bfseries| or \verb|\sffamily|) but can also -be, in fact, any TeX command. - -In the following example, the argument of \verb|font| is the token list \verb|\tiny\counter| where -\verb|\counter| is a command which increment a counter previously defined and display its new value. Thus, the -arrows are automatically numbered. -% -\begin{Verbatim}[formatcom=\small\color{gray}] -\newcounter{MyCounter} -\newcommand{\counter}{\stepcounter{MyCounter}\theMyCounter.} -$\begin{WithArrows}[tikz={~emphase#font={\tiny\counter}@}] -A(x) -& = B(x) \Arrow{} \cr -& = C(x) \Arrow{} \cr -& = C(x) \Arrow{} \cr -& = E(x) \Arrow{} \cr -& = F(x) \Arrow{} \cr -& = G(x) -\end{WithArrows}$ -\end{Verbatim} - -\begin{group} -\newcounter{MyCounter} -\newcommand{\counter}{\stepcounter{MyCounter}\theMyCounter.} -$\begin{WithArrows}[tikz={font={\tiny\counter}}] -A(x) -& = B(x) \Arrow{} \cr -& = C(x) \Arrow{} \cr -& = C(x) \Arrow{} \cr -& = E(x) \Arrow{} \cr -& = F(x) \Arrow{} \cr -& = G(x) -\end{WithArrows}$ -\end{group} - - - -\end{document} - - - - - diff --git a/Master/texmf-dist/source/latex/witharrows/witharrows.dtx b/Master/texmf-dist/source/latex/witharrows/witharrows.dtx new file mode 100644 index 00000000000..d1806821106 --- /dev/null +++ b/Master/texmf-dist/source/latex/witharrows/witharrows.dtx @@ -0,0 +1,2098 @@ +% \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.1} +\def\myfiledate{2017/11/06} +%<package>\RequirePackage{l3keys2e} +%<package>\ProvidesExplPackage +%<package> {witharrows} +%<package> {\myfiledate} +%<package> {\myfileversion} +%<package> {Draws arrows for explanations on the right} +% +% +%<*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 +%</batchfile> +% +%<@@=wa> +%<*driver> +\documentclass{l3doc} % load fancyvrb, amsmath, array, color, etc. +\usepackage{xltxtra} +\usepackage{lmodern} +\usepackage{geometry} +\usepackage[dvipsnames]{xcolor} % color is already loaded with l3doc (?) +\geometry{left=2.8cm,right=2.8cm,top=2.5cm,bottom=2.5cm,papersize={21cm,29.7cm}} +\usepackage{tikz} +\usetikzlibrary{calc,arrows.meta,bending} +\usepackage{footnote} +\usepackage{witharrows} +\usepackage{mathtools} +\usepackage{amsfonts} +\NewDocumentEnvironment {scope} {} {} {} +\def\interitem{\vskip 7mm plus 2 mm minus 3mm} +\def\emphase#1{{\color{RoyalPurple}#1}} +\fvset{commandchars=\~\#\@,formatcom={\color{gray}}} +\DeclareMathOperator{\re}{Re} +\parindent 0pt +\DisableCrossrefs +\begin{document} +\DocInput{witharrows.dtx} +\end{document} +%</driver> +% \fi +% \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} gives 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}, \pkg{footnote}\footnote{The package footnote is used to extract the notes +% from the environments \texttt{\{WithArrows\}}.} and \pkg{tikz}. The following Tikz libraries are also required : +% \pkg{calc}, \pkg{arrows.meta} and \pkg{bending}. +% +% \bigskip +% This package gives 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 ligne from which it starts. The command |\Arrow| can be +% used anywhere on the line but the best way is to put it at the end. +% +% +% \section{Options for the shape of the arrows} +% +% The commande |\Arrow| has several options. These options can be put between square brackets, before, or after the +% mandatory argument. +% +% The option |jump| gives the number of lines the arrow must jump (the default value is, of course,~$1$) +% \footnote{It's not possible to give a non-positive value to \texttt{jump}. See below the way to draw an arrow +% which goes backwards.} +% % +% \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 line. +% % +% \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| shift 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 blue thick arrow. +% % +% \begin{Verbatim} +% $\begin{WithArrows} +% A & = (a+1)^2 \Arrow[~emphase#tikz={blue,thick}@]{we expand} \\ +% & = a^2 + 2a + 1 +% \end{WithArrows}$ +% \end{Verbatim} +% +% $\begin{WithArrows} +% A & = (a+1)^2 \Arrow[tikz={blue,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~|<-|. +% % +% \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}$ +% +% \interitem +% One of the most useful options is ``|text width|'' to control the with 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 a 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 applies also to the nested environments +% \texttt{\{WithArrows\}} with the notable exception of \texttt{interline}.} +% % +% \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 +% 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{It's also possible to give the options directly when +% loading the package, \emph{i.e.} with the command \texttt{\string\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} +% \def\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} +% \def\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 +% It's possible to use directly the nodes created by |{WithArrows}| with explicit Tikz instructions (in order, for +% example, to draw something that can't be drawn with the command |\Arrow|). That's why a style for the tips of the +% arrows has be created : |TipsOfWithArrows|. By using this style, we will have homogeneous tips for the arrows of +% the document. +% +% Therefore, if we want to modify the tips of the arrows of |{WithArrows}|, we have to modify the style +% |TipsOfWithArrows|. +% % +% \begin{Verbatim} +% \tikzset{TipsOfWithArrows/.style= { > = {Latex[scale=1.2,bend]}} } +% \end{Verbatim} +% +% The names of the Tikz nodes created by \pkg{witharrows} in the whole document are explained below. +% +% +% \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 \texttt{shownodes} can be used to materialize the nodes.} +% +% \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}. +% +% % The names of the Tikz nodes created by \texttt{\{WithArrows\}} are \texttt{wa-}$n$\texttt{-l} and +% % \texttt{wa-}$n$\texttt{-r} where $n$~is the number of the line. It's possible to refer to these Tikz nodes after +% % the environment (one should use the options \texttt{remember picture} and \texttt{overlay} and also +% % \texttt{TipsOfWithArrows} and \texttt{->} in order to have the same arrowheads). +% +% 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 +% If desired, the option |group| can be given to the command |\WithArrowsOptions| so that it will become the default +% value. +% +% +% \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 environment \pkg{amsmath}.} +% +% \interitem +% As in the environments of \pkg{amsmath}, it's possible to change the spacing between two given lines 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 lines 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 \texttt{\string\jot} with the environment +% \texttt{\{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} +% ~emphase#Et donc\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 \texttt{amsmath} older than the 5~nov.~2016, an thin space was added on the left of an environment +% \texttt{\{aligned\}}. The new versions do not add this space and neither do \texttt{\{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{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}$ +% +% +% \subsection{MoveEqLeft} +% +% It's possible to use |\MoveEqLeft| of \pkg{mathtools} (if we don't want ampersand on the firt line) : +% % +% \begin{Verbatim}[formatcom=\small\color{gray}] +% $\begin{WithArrows}[jot=2mm] +% ~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}[jot=2mm] +% \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}$ +% +% +% +% \subsection{Nested environments} +% +% +% The environments |{WithArrows}| can be nested. In this case, the options given to the encompassing environment +% applies also to the inner ones (with the notable exception of |interline|). +% % +% \begin{Verbatim}[formatcom=\small\color{gray}] +% $~emphase#\begin{WithArrows}@[tikz=blue] +% \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 équation}\\ +% x+2y & = 0 +% ~emphase#\end{WithArrows}@\right. \\ +% & \Leftrightarrow x+2y=0 +% ~emphase#\end{WithArrows}@$ +% \end{Verbatim} +% +% $\begin{WithArrows}[tikz=blue] +% \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}$ +% +% +% +% \subsection{A loop flow} +% +% Here is an example with a loop flow.\par\nobreak +% % +% \begin{Verbatim}[formatcom=\small\color{gray}] +% $\begin{WithArrows}[tikz={font={\tiny}}] +% a.\;& f \text{ est continuous on } E +% \Arrow{(1)}\Arrow[tikz=<-,jump=4,xoffset=1cm]{(5)}\\ +% b.\;& f \text{ est continuous in } 0 +% \Arrow{(2)}\\ +% c.\;& f \text{ is bounded on the unit sphere} +% \Arrow{(3)}\\ +% d.\;& \exists K > 0\quad \forall x \in E\quad \|f(x)\| \le K \|x\| +% \Arrow{(4)}\\ +% e.\;& f \text{ is lipschitzian} +% \end{WithArrows}$ +% \end{Verbatim} +% +% $\begin{WithArrows}[tikz={font={\tiny}}] +% a.\;& f \text{ est continuous on } E +% \Arrow{(1)}\Arrow[tikz=<-,jump=4,xoffset=1cm]{(5)}\\ +% b.\;& f \text{ est continuous in } 0 +% \Arrow{(2)}\\ +% c.\;& f \text{ is bounded on the unit sphere} +% \Arrow{(3)}\\ +% d.\;& \exists K > 0\quad \forall x \in E\quad \|f(x)\| \le K \|x\| +% \Arrow{(4)}\\ +% e.\;& f \text{ is lipschitzian} +% \end{WithArrows}$ +% +% +% \subsection{Automatic numerotation} +% +% The option |font| of Tikz contains in fact a list of tokens which will be placed at the beginning of the text. +% +% These tokens can be true commands for a change of font (like |\bfseries| or |\sffamily|) but can also be, in +% fact, any TeX command. +% +% In the following example, the argument of |font| is the token list |\tiny\counter| where |\counter| is a command +% which increment a counter previously defined and display its new value. Thus, the arrows are automatically +% numbered. +% % +% \begin{Verbatim}[formatcom=\small\color{gray}] +% \newcounter{MyCounter} +% \newcommand{\counter}{\stepcounter{MyCounter}\theMyCounter.} +% $\begin{WithArrows}[tikz={~emphase#font={\tiny\counter}@}] +% A(x) +% & = B(x) \Arrow{} \\ +% & = C(x) \Arrow{} \\ +% & = C(x) \Arrow{} \\ +% & = E(x) \Arrow{} \\ +% & = F(x) \Arrow{} \\ +% & = G(x) +% \end{WithArrows}$ +% \end{Verbatim} +% +% \begin{scope} +% \newcounter{MyCounter} +% \newcommand{\counter}{\stepcounter{MyCounter}\theMyCounter.} +% $\begin{WithArrows}[tikz={font={\tiny\counter}}] +% A(x) +% & = B(x) \Arrow{} \\ +% & = C(x) \Arrow{} \\ +% & = C(x) \Arrow{} \\ +% & = E(x) \Arrow{} \\ +% & = F(x) \Arrow{} \\ +% & = G(x) +% \end{WithArrows}$ +% \end{scope} +% +% +% \section{An technical remark about the names of the nodes} +% +% Environments |{WithArrows}| can be nested, and, therefore, we have a ``nesting tree'' for the environments +% |{WithArrows}| of the whole document. This nesting tree is used to give a unique name to each node in the +% document. +% +% \smallskip +% The Tikz name of a node created by \pkg{witharrows} is prefixed by |wa-|. Then, we have a list of numbers with +% give the position in the nesting tree and the number of the line 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 \texttt{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}\] +% +% \bigskip +% The command |\WithArrowsLastEnv| gives the number of the last environment of level~$0$. For example, we can draw +% an arrow from the node \texttt{wa-\WithArrowsLastEnv-1} to the node \texttt{wa-\WithArrowsLastEnv-2-1} with the +% following Tikz command.\footnote{The command \texttt{\string\WithArrowsLastEnv} is \emph{fully expandable} and +% thus, can be used directly in the name of a Tikz node.} +% +% \begin{Verbatim} +% \begin{tikzpicture}[remember picture,overlay,->,TipsOfWithArrows] +% \draw (wa-\WithArrowsLastEnv-1-r) to (wa-\WithArrowsLastEnv-2-1-r) ; +% \end{tikzpicture} +% \end{Verbatim} +% +% \section{Implementation} +% +% \subsection{Some extensions are loaded} +% +% This package is written in \pkg{expl3}. +% \begin{macrocode} +\RequirePackage{expl3} +% \end{macrocode} +% +% \bigskip +% The package \pkg{xparse} will be used to define the environment |{WithArrows}| and the document-level commands +% (|\Arrow|, |\WithArrowsOptions| ans |\WithArrowsLastEnv|). +% \begin{macrocode} +\RequirePackage{xparse} +% \end{macrocode} +% +% \bigskip +% The arrows are drawn with Tikz and that's why \pkg{tikz} is required with some libraries. +% \begin{macrocode} +\RequirePackage{tikz} +\usetikzlibrary{calc,arrows.meta,bending} +% \end{macrocode} +% +% \bigskip +% The package \pkg{footnote} will be used to extract footnotes. +% \begin{macrocode} +\RequirePackage{footnote} +% \end{macrocode} +% +% \subsection{Some technical definitions} +% +% We define a Tikz style |wa_node_style| for the nodes that will be created in the |\halign|. +% \begin{macrocode} +\tikzstyle{@@_node_style}=[rectangle, + inner~sep = 0 pt, + minimum~height = 3 pt, + minimum~width = 0pt, + 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 +% 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{TipsOfWithArrows/.style= { > = {Straight~Barb[scale=1.2,bend]}} } +% \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} (\emph{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:Npn \spread@equation{\openup\jot + \cs_set_eq:NN \spread@equation \prg_do_nothing}} +% \end{macrocode} +% +% +% \subsection{Variables} +% +% \bigskip +% The following sequence is the position of the last environment |{WithArrows}| in the tree of the imbricated +% 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 of the |\halign|. +% \begin{macrocode} +\skip_new:N \l_@@_interline_skip +% \end{macrocode} +% +% \bigskip +% If the following flag is raised, then the user can use more than two columns. +% \begin{macrocode} +\bool_new:N \l_@@_MoreColumns_bool +% \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_int +% \end{macrocode} +% \bigskip +% The following flag indicates if the beginning of the arrow use a |r| option (if not, it's a |l| option). +% \begin{macrocode} +\bool_new:N \l_@@_initial_r_bool +\bool_set_true:N \l_@@_initial_r_bool +% \end{macrocode} +% +% \bigskip +% The following flag indicates if the end of the arrow use a |r| option (if not, it's a |l| option). +% \begin{macrocode} +\bool_new:N \l_@@_final_r_bool +\bool_set_true:N \l_@@_final_r_bool +% \end{macrocode} +% +% \bigskip +% The following flag indicates if the arrow use a |i| option (in this case, the options |l| and |r| for the +% ends are meaningless). +% \begin{macrocode} +\bool_new:N \l_@@_i_bool +% \end{macrocode} +% +% \bigskip +% The following dimension is the value of the translation of the whole arrow to the right (of course, it's a +% dimension and not a skip). +% \begin{macrocode} +\dim_new:N \l_@@_xoffset_dim +\dim_set:Nn \l_@@_xoffset_dim {3mm} +% \end{macrocode} +% +% \bigskip +% If the following flag is raised, the nodes will be drawn in red (useful for debugging). +% \begin{macrocode} +\bool_new:N \l_@@_shownodes_bool +% \end{macrocode} +% +% \bigskip +% If the following flag is raised, the name of the ``right nodes'' will be shown in the document (useful for +% debugging). +% \begin{macrocode} +\bool_new:N \l_@@_shownodenames_bool +% \end{macrocode} +% +% \bigskip +% If the following flag is raised, the elements of the |\halign| will be composed with |\displaystyle| : +% \begin{macrocode} +\bool_new:N \l_@@_displaystyle_bool +% \end{macrocode} +% +% \bigskip +% The following token list variable will contains the \pkg{Tikz} options used to draw the arrows. +% \begin{macrocode} +\tl_clear_new:N \l_@@_options_tikz_tl +% \end{macrocode} +% +% At each possible level for the options (\emph{global}, \emph{env} or \emph{local} : see below), the new values +% will be appended on the right of this token list. +% +% \bigskip +% The following flag will be raised when a key controling position of the arrow has been set in the same list of +% keys (this is useful in order to raise an error if two incompatibles keys are specified at the same level). +% \begin{macrocode} +\bool_new:N \l_@@_position_key_already_set_bool +% \end{macrocode} +% This flag is set to |false| each time we have to process a list of options. +% +% \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_@@_stack_counter_arrows_seq +\int_new:N \g_@@_arrow_int +\seq_new:N \g_@@_stack_counter_lines_seq +\int_new:N \g_@@_line_int +\seq_new:N \g_@@_stack_counter_lines_bis_seq +\int_new:N \g_@@_line_bis_int +% \end{macrocode} + +% +% \subsection{The definition of the options} +% There are three levels where options can be set : +% \begin{itemize} +% \item with |\WithArrowsOptions{...}| : this level will be called \emph{global} level; +% \item with |\begin{WithArrows}[...]| : this level will be called \emph{env} level; +% \item with |\Arrow[...]| : this level will be called \emph{local} level. +% \end{itemize} +% +% That's why there is three groups of keys named |global|, |env| and |local|. +% +% \bigskip +% Before each |\keys_set_groups:nnn|, we execute a |\keys_set_filter:nnn| with group |secondary|. Thus, an +% unknown key will raise an error. Furthermore, the \emph{primary} keys (those which are not in the group +% |secondary|) will be set first : it's useful to raise an error if, for example, keys |i| and +% |group| are set at the same level (which is incoherent). +% +% \bigskip +% \begin{macrocode} +\keys_define:nn {WithArrows} +% \end{macrocode} +% +% \medskip +% 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 this key is the only key of a dedicated group also named +% |jump|. +% \begin{macrocode} + { jump .groups:n = {jump,secondary}, + 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 options |t|, |c| and |b| indicate if we will create a |\vtop|, a |\vcenter| of a |\vbox|. This information is +% stored in the variable |\l_@@_pos_int|. +% \begin{macrocode} + t .groups:n = {global,env,secondary}, + t .code:n = {\int_set:Nn \l_@@_pos_int 0}, + t .value_forbidden:n = true, + c .groups:n = {global,env,secondary}, + c .code:n = {\int_set:Nn \l_@@_pos_int 1}, + c .value_forbidden:n = true, + b .groups:n = {global,env,secondary}, + b .code:n = {\int_set:Nn \l_@@_pos_int 2}, + b .value_forbidden:n = true, +% \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 .groups:n = {global,env,secondary}, + MoreColumns .bool_set:N = \l_@@_MoreColumns_bool, + MoreColumns .default:n = true, + MoreColumns .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 .groups:n = {global,env,secondary}, + CommandName .tl_set:N = \l_@@_CommandName_tl, + CommandName .initial:n = {Arrow}, + CommandName .value_required:n = true, +% \end{macrocode} +% +% \bigskip +% With the option |displaystyle|, all the elements of the environment will be composed in |\displaystyle|. +% \begin{macrocode} + displaystyle .groups:n = {global,env,secondary}, + displaystyle .bool_set:N = \l_@@_displaystyle_bool, +% \end{macrocode} + % +% \bigskip +% With the option |shownodes|, the nodes will be drawn in red (useful only for debugging). +% \begin{macrocode} + shownodes .groups:n = {global,env,secondary}, + shownodes .bool_set:N = \l_@@_shownodes_bool, + shownodes .default:n = true, +% \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 .groups:n = {global,env,secondary}, + shownodenames .bool_set:N = \l_@@_shownodenames_bool, + shownodenames .default:n = true, +% \end{macrocode} +% +% \bigskip +% The option |jot| can be used to change the value of the LaTeX parameter |\jot|. If we put this option in the +% |global| group, the use of this option in |\WithArrowsOptions| will change |\jot| for the whole document (at +% least the current TeX group) and not only for the |{WithArrows}| environments. This is certainly not what the +% user wants. That's why the option |jot| is not in the group |global|. It's interesting to note that |\jot| is a +% dimension and not a skip (=glue). +% +% \begin{macrocode} + jot .groups:n = {env,secondary}, + jot .dim_set:N = \jot, + jot .value_required:n = true, +% \end{macrocode} +% +% \bigskip +% The option |interline| gives the vertical skip (=glue) inserted between two lines (independently of |\jot|). By +% design, this option has a particular behaviour : it applies only to an environment and doesn't apply to the +% nested environments. +% \begin{macrocode} + interline .groups:n = {env,secondary}, + interline .skip_set:N = \l_@@_interline_skip, + interline .initial:n = \c_zero_skip, + interline .value_required:n = true, +% \end{macrocode} +% +% \bigskip +% The option |xoffset| change the $x$-offset of the arrows (towards the right). It's a dimension and not a skip. +% \begin{macrocode} + xoffset .groups:n = {global,env,local,secondary}, + xoffset .dim_set:N = \l_@@_xoffset_dim, + xoffset .value_required:n = true, +% \end{macrocode} +% +% \bigskip +% 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} + tikz .groups:n = {global,env,local,secondary}, + tikz .code:n = {\tl_put_right:Nn \l_@@_options_tikz_tl {,#1}}, + tikz .value_required:n = true, +% \end{macrocode} +% +% \bigskip +% The following options can be used to specify the position of the arrows. We control that a previous specification +% of position has not been set at the same level of option. This is done with the help of the flag +% |\l_@@_position_key_already_set_bool|. +% \begin{macrocode} + ll .groups:n = {global,env,local,secondary}, + ll .value_forbidden:n = true, + ll .default:n = true, + ll .code:n = {\bool_if:NT \l_@@_position_key_already_set_bool + {\msg_error:nn {witharrows} + {Two~options~are~incompatible}} + \bool_if:NT \l_@@_group_bool + {\msg_error:nn {witharrows} + {Option~incompatible~with~group}} + \bool_set_true:N \l_@@_position_key_already_set_bool + \bool_set_false:N \l_@@_initial_r_bool + \bool_set_false:N \l_@@_final_r_bool + \bool_set_false:N \l_@@_i_bool }, +% \end{macrocode} +% +% \begin{macrocode} + lr .groups:n = {global,env,local,secondary}, + lr .value_forbidden:n = true, + lr .default:n = true, + lr .code:n = {\bool_if:NT \l_@@_position_key_already_set_bool + {\msg_error:nn {witharrows} + {Two~options~are~incompatible}} + \bool_if:NT \l_@@_group_bool + {\msg_error:nn {witharrows} + {Option~incompatible~with~group}} + \bool_set_true:N \l_@@_position_key_already_set_bool + \bool_set_false:N \l_@@_initial_r_bool + \bool_set_true:N \l_@@_final_r_bool + \bool_set_false:N \l_@@_i_bool}, +% \end{macrocode} +% +% \begin{macrocode} + rl .groups:n = {global,env,local,secondary}, + rl .value_forbidden:n = true, + rl .default:n = true, + rl .code:n = {\bool_if:NT \l_@@_position_key_already_set_bool + {\msg_error:nn {witharrows} + {Two~options~are~incompatible}} + \bool_if:NT \l_@@_group_bool + {\msg_error:nn {witharrows} + {Option~incompatible~with~group}} + \bool_set_true:N \l_@@_position_key_already_set_bool + \bool_set_true:N \l_@@_initial_r_bool + \bool_set_false:N \l_@@_final_r_bool + \bool_set_false:N \l_@@_i_bool}, +% \end{macrocode} +% +% \begin{macrocode} + rr .groups:n = {global,env,local,secondary}, + rr .value_forbidden:n = true, + rr .default:n = true, + rr .code:n = {\bool_if:NT \l_@@_position_key_already_set_bool + {\msg_error:nn {witharrows} + {Two~options~are~incompatible}} + \bool_if:NT \l_@@_group_bool + {\msg_error:nn {witharrows} + {Option~incompatible~with~group}} + \bool_set_true:N \l_@@_position_key_already_set_bool + \bool_set_true:N \l_@@_initial_r_bool + \bool_set_true:N \l_@@_final_r_bool + \bool_set_false:N \l_@@_i_bool}, +% \end{macrocode} +% +% \bigskip +% With option |i| (for \emph{intermediate}), the arrow will be drawn on the leftmost position compatible with all +% the lines between the starting line and the final line of the arrow. +% \begin{macrocode} + i .groups:n = {global,env,local,secondary}, + i .code:n = {\bool_if:NT \l_@@_position_key_already_set_bool + {\msg_error:nn {witharrows} + {Two~options~are~incompatible}} + \bool_if:NT \l_@@_group_bool + {\msg_error:nn {witharrows} + {Option~incompatible~with~group}} + \bool_set_true:N \l_@@_position_key_already_set_bool + \bool_set_true:N \l_@@_i_bool}, + i .value_forbidden:n = true, + i .default:n = true, +% \end{macrocode} +% +% \bigskip +% With the option |group|, \emph{all} the arrows of the environment are grouped on a same vertical line and at a +% leftmost position. Of course, this option is not available at the local level. +% +% This key is not in the |secondary| group. Thus, it will be set first during the |\keys_set_filter:nnn| and an +% incompatibility like, for example, |[i,group]| will be detected (with a non fatal error). +% \begin{macrocode} + group .groups:n = {global,env}, + group .bool_set:N = \l_@@_group_bool, + group .value_forbidden:n = true +} +% \end{macrocode} +% +% \bigskip +% We process the options when the package is loaded (with |\usepackage|) but we recommend to use |\WithArrowOptions| instead. +% \begin{macrocode} +\ProcessKeysOptions {WithArrows} +% \end{macrocode} +% +% \bigskip +% |\WithArrowsOptions| is the command of the \pkg{witharrows} package to fix options at the document level. +% \begin{macrocode} +\NewDocumentCommand \WithArrowsOptions {m} + {\bool_set_false:N \l_@@_position_key_already_set_bool + \keys_set_filter:nnn {WithArrows} {secondary} {#1} + \keys_set_groups:nnn {WithArrows} {global} {#1}} +% \end{macrocode} +% +% +% \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{}} + {\tl_if_eq:noF {WithArrows} {\@currenvir} + {\msg_error:nn {witharrows} {Arrow~used~outside~{WithArrows}~environment}} +% \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 +% group |jump| with only one key (the key |jump|). +% \begin{macrocode} + \int_zero_new:N \l_@@_jump_int + \int_set:Nn \l_@@_jump_int 1 + \keys_set_groups:nnn {WithArrows} {jump} {#1,#3} +% \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:Nnn \l_tmpa_prop {options} {#1,#3} +% \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_tl _\int_use:N\g_@@_arrow_int _prop} + \prop_gset_eq:cN + {g_@@_arrow_\l_@@_prefix_tl _\int_use:N\g_@@_arrow_int _prop} + \l_tmpa_prop + } +% \end{macrocode} +% +% +% \subsection{The environnement \{WithArrows\}} +% +% +% The environment |{WithArrows}| starts with the initialisation of the three counters |\g_@@_arrow_int|, +% |\g_@@_line_int| dans |\g_@@_line_bis_int|. However, we have to save their previous values with the three stacks +% created for this end. +% \begin{macrocode} +\NewDocumentEnvironment {WithArrows} {O{}} + { \seq_gput_right:NV \g_@@_stack_counter_arrows_seq \g_@@_arrow_int + \int_gzero:N \g_@@_arrow_int + \seq_gput_right:NV \g_@@_stack_counter_lines_seq \g_@@_line_int + \int_gzero:N \g_@@_line_int + \seq_gput_right:NV \g_@@_stack_counter_lines_bis_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 + \tl_clear_new:N \l_@@_prefix_tl + \tl_set:Nx \l_@@_prefix_tl {\seq_use:Nnnn \l_tmpa_seq {-} {-} {-}} +% \end{macrocode} +% +% + +% +% \bigskip +% The environment |{WithArrows}| must be used in math mode. +% \begin{macrocode} + \reverse_if:N \if_mode_math: + \msg_error:nn {witharrows} {{WithArrows}~used~outside~math~mode} + \fi +% \end{macrocode} +% +% \bigskip +% We extract the footnotes of the environments |{WithArrows}| with the pair |\savenotes-\spewnotes| of the +% extension \pkg{footnote} (of course, we have put a |\spewnotes| at the end of the environment). +% \begin{macrocode} + \savenotes +% \end{macrocode} +% +% \bigskip +% We define the command |\\| to be the command |\@@_cr:| (defined below). +% \begin{macrocode} + \cs_set_eq:NN \\ \@@_cr: + \mathsurround = \c_zero_dim +% \end{macrocode} +% +% \bigskip +% These three 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 flag |\l_@@_position_key_already_set_bool| is set to false before the treatment of the options of the +% environment. It will be raised if a key indicating the position of the arrows is found. Thus, we can detect +% incompatible keys. +% \begin{macrocode} + \bool_set_false:N \l_@@_position_key_already_set_bool +% \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 \texttt{interline} of a environment doesn't apply +% in the nested environments.} +% \begin{macrocode} + \skip_zero:N \l_@@_interline_skip +% \end{macrocode} +% +% \bigskip +% The following code in order to raise an error if a key is unknown. +% \begin{macrocode} + \keys_set_filter:nnn {WithArrows} {secondary} {#1} +% \end{macrocode} +% +% \bigskip +% We process the options given at the \emph{env} level, that is to say in the option of the |{WithArrows}| environment. +% \begin{macrocode} + \keys_set_groups:nnn {WithArrows} {env} {#1} +% \end{macrocode} +% +% \bigskip +% If the user has given a value for the option |CommandName| (at the global or at the \emph{env} 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} +% +% \bigskip +% The environment begins with a |\vtop|, a |\vcenter| or a |\vbox|\footnote{Notice that the use of +% \texttt{\string\vtop} seems color-safe here...} depending of the value of |\l_@@_pos_int| (usually 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_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 + \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} + \tikz[remember~picture] + \node [@@_node_style] + (wa-\tl_use:N\l_@@_prefix_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} + \tikz[remember~picture,label~position=right] + \node [@@_node_style] + (wa-\tl_use:N\l_@@_prefix_tl-\int_use:N\g_@@_line_int-r) {} ; + \bool_if:NT \l_@@_shownodenames_bool + {\hbox_overlap_right:n {\small wa-\tl_use:N\l_@@_prefix_tl + -\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} + && \bool_if:NF \l_@@_MoreColumns_bool + {\msg_error:nn {witharrows} {Third~column~in~a~{WithArrows}~environment}} + $\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 +% \end{macrocode} +% +% \bigskip +% 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 with |\@@_draw_arrows:| (a special macro has +% been written for lisibility of the code). +% \begin{macrocode} + \int_compare:nNnT \g_@@_arrow_int > 0 + \@@_draw_arrows: +% \end{macrocode} +% +% \bigskip +% We use |\spewnotes| of \pkg{footnote} to spew the footnotes of the environment (a |\savenotes| has been put at +% the beginning of the environment). +% \begin{macrocode} + \spewnotes +% \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 fonction |\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_@@_stack_counter_arrows_seq {\l_tmpa_tl} + \int_gset:Nn \g_@@_arrow_int {\l_tmpa_tl} + \seq_gpop_right:NN \g_@@_stack_counter_lines_seq \l_tmpa_tl + \int_gset:Nn \g_@@_line_int {\l_tmpa_tl} + \seq_gpop_right:NN \g_@@_stack_counter_lines_bis_seq \l_tmpa_tl + \int_gset:Nn \g_@@_line_bis_int {\l_tmpa_tl} + } +% \end{macrocode} +% That's the end of the environment |{WithArrows}|. +% +% \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_set_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_set_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: + \cr\noalign{\skip_vertical:n {#1 + \l_@@_interline_skip} + \scan_stop:}} +% \end{macrocode} +% According of the documentation of \pkg{expl3}, the previous addition in ``|#1 + \l_@@_interline_skip|'' is really +% an addition of skips (=glues). +% +% \subsection{We draw the arrows} +% +% The following code is necessary because we will have to expand an argument exactly 3 times. +% \begin{macrocode} +\cs_generate_variant:Nn \keys_set_groups:nnn {nno} +\cs_new_protected:Nn \keys_set_groups_WithArrows_local: + {\keys_set_groups:nno {WithArrows} {local}} +% \end{macrocode} +% +% \bigskip +% \begin{macrocode} +\cs_generate_variant:Nn \keys_set_filter:nnn {nno} +\cs_new_protected:Nn \keys_set_filter_WithArrows_secondary: + {\keys_set_filter:nno {WithArrows} {secondary}} +% \end{macrocode} +% +% \bigskip +% \begin{macrocode} +\cs_new_protected:Nn \@@_draw_arrows: + { +% \end{macrocode} +% +% \medskip +% If the option |group| is used (for the whole document --- with |\WithArrowsOptions| --- or for the current environment), +% we have to compute the $x$-value common to all the arrows. This work is done by the command +% |\@@_x_computation_for_option_group:| and the computed $x$-value is store in |\g_@@_x_dim| (we use a global +% variable for technical reasons). +% \begin{macrocode} + \bool_if:NT \l_@@_group_bool + \@@_x_computation_for_option_group: +% \end{macrocode} +% +% \bigskip +% We begin a loop over the arrows of the environment. The variable |\l_@@_arrow_int| (local in the environment +% |{WithArrows}|) will be used as index for the loop. The number of arrows in the environment is |\g_@@_arrow_int|. +% This variable was a counter incremented when an arrows is encountered during the construction of the |\halign|. +% After the end of the |\halign|, |g_@@_arrow_int| is the number of arrows in the environment. +% \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. +% +% \smallskip +% If the arrow ends after the last line of the environment, we raise an error. +% \begin{macrocode} + \prop_get:cnN {g_@@_arrow_\l_@@_prefix_tl _\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_tl _\int_use:N\l_@@_arrow_int _prop} + {final} \l_tmpa_tl + \int_set:Nn \l_@@_final_int {\l_tmpa_tl} + \int_compare:nNnT \l_@@_final_int > \g_@@_line_int + {\msg_error:nn {witharrows} {Too~few~lines~for~an~arrow}} +% \end{macrocode} +% +% \bigskip +% We begin an TeX group which will contains the options local to the current arrow. We declare ``undefined'' the +% key |group| because it's not possible to have a |group| key for an individual arrow. +% \begin{macrocode} + \group_begin: + \keys_define:nn {WithArrows} {group .undefine:} + \bool_set_false:N \l_@@_position_key_already_set_bool +% \end{macrocode} +% +% \bigskip +% We process the options of the current arrow. The third argument de |\keys_set_groups:nnn| 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_tl + _\int_use:N\l_@@_arrow_int _prop} {options} \l_tmpa_tl + \exp_args:NNo \exp_args:No \keys_set_filter_WithArrows_secondary: {\l_tmpa_tl} + \exp_args:NNo \exp_args:No \keys_set_groups_WithArrows_local: {\l_tmpa_tl} +% \end{macrocode} +% +% \bigskip +% In case of option |i|, we have to compute the $x$-value of the arrow (which is vertical). This work is done by +% the command |\@@_x_computation_for_option_i:| and the computed $x$-value is stored in |g_@@_x_dim| (the same +% variable used when the option |group| is used). +% \begin{macrocode} + \bool_if:NT \l_@@_i_bool + \@@_x_computation_for_option_i: +% \end{macrocode} +% +% \bigskip +% |\l_@@_initial_tl| contains the name of the Tikz node from which the arrow starts (in normal cases... +% because with option |group| or option |i|, the point will perhaps have an other $x$-value --- but always the +% same |y|-value). Idem for |\l_@@_final_tl|. +% \begin{macrocode} + \tl_set:Nx \l_@@_initial_tl + {wa-\tl_use:N\l_@@_prefix_tl-\int_use:N\l_@@_initial_int- + \bool_if:NTF\l_@@_initial_r_bool rl} + \tl_set:Nx \l_@@_final_tl + {wa-\tl_use:N\l_@@_prefix_tl-\int_use:N\l_@@_final_int- + \bool_if:NTF\l_@@_final_r_bool rl . north} +% \end{macrocode} +% We use ``|. 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 +% We can now draw the arrow in a |{tikzpicture}| : +% \begin{macrocode} + \begin{tikzpicture}[remember~picture, + overlay, + align=left, + auto=left, + font = {\small\itshape}, + TipsOfWithArrows, + ->, + looseness=1, + bend~left=45] +% \end{macrocode} +% +% Of course, the arrow is drawn with the command |\draw| of Tikz. The syntax for this command is : +% +% \qquad |\draw| $(x_1,y_1)$ |to node| (\textsl{name}) |{|\textsl{contents}|}| $(x_2,y_2)$ +% +% The surprising aspect of this syntax is the position of \textsl{contents} which is the label of the arrow. +% +% We give a name to the node (\textsl{name} in the previous syntax) but, in fact, we don't use it in the extension +% |witharrows|. +% +% |\p1| and |\p2| are the two ends of the arrow (in fact, if the option |i| or the option |group| is used, it's not +% exactly the two ends of the arrow because, in this case, this abscissa used is the value previously calculated in +% |g_@@_x_dim|). +% +% The ability to define |\p1| and |\p2| is given by the library |calc| of Tikz. When |\p1| and |\p2| are defined, +% the $x$-value and $y$-value of these two points can be read in |\x1|, |\x2|, |\y1| and |\y2|. This is the way to +% have the coordinates of a node defined in Tikz. +% \begin{macrocode} + \prop_get:cnN {g_@@_arrow_\l_@@_prefix_tl _\int_use:N\l_@@_arrow_int _prop} + {label} \l_tmpa_tl + \draw \exp_after:wN [\l_@@_options_tikz_tl] + let \p1 = (\tl_use:N \l_@@_initial_tl), + \p2 = (\tl_use:N \l_@@_final_tl) in + (\bool_if:nTF {\l_@@_group_bool || \l_@@_i_bool} + {\dim_use:N \g_@@_x_dim + \dim_use:N \l_@@_xoffset_dim, \y1} + {\x1 + \dim_use:N \l_@@_xoffset_dim, \y1} ) +% \end{macrocode} +% There are two ways to give the content of the node : the classical way, with curly braces, and the option ``node +% contents''. However, both are not strictly equivalent : when |\usetikzlibrary{babel}| is used, the tokens of the +% contents are rescanned in the first way but not in the second. We don't want the tokens to be rescanned (because +% this would lead to an error due of the characters |_| and |:| of the \pkg{expl3} syntax) and that's why we use +% the second method. \footnote{cf. : +% |tex.stackexchange.com/questions/298177/how-to-get-around-a-problem-with-usetikzlibrarybabel|} +% \begin{macrocode} + to node [node~contents = {\tl_use:N \l_tmpa_tl}] {} + (\bool_if:nTF {\l_@@_group_bool || \l_@@_i_bool} + {\dim_use:N \g_@@_x_dim + \dim_use:N \l_@@_xoffset_dim, \y2} + {\x2 + \dim_use:N \l_@@_xoffset_dim, \y2} ) ; + \end{tikzpicture} +% \end{macrocode} +% +% \smallskip +% We close the TeX group opened for the options given to |\Arrow[...]| (local level of the options). +% \begin{macrocode} + \group_end: + \int_incr:N \l_@@_arrow_int + } + } +% \end{macrocode} +% +% \bigskip +% We want to compute the $x$-value for the current arrow which has option |i| (and therefore is vertical). +% This value will be computed in |\g_@@_x_dim| (which is global for technical reasons : we have to do assignments in +% a Tikz command). +% \begin{macrocode} +\cs_new_protected:Nn \@@_x_computation_for_option_i: + {\dim_gzero_new:N \g_@@_x_dim +% \end{macrocode} +% +% \medskip +% First, we calculate the initial value for |\g_@@_x_dim|. In this loop, 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} + \tikz[remember~picture] + \path let \p1 = (wa-\tl_use:N\l_@@_prefix_tl-\int_use:N\l_@@_initial_int-l) + in \pgfextra {\dim_gset:Nn \g_@@_x_dim {\x1}} ; +% \end{macrocode} +% A global assignment is necessary because of Tikz. +% +% Then, we will loop to determine the maximal length of all 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 +% |\@@_x_computation_for_option_group:| +% \begin{macrocode} + \@@_x_computation_analyze_lines_between: + } +% \end{macrocode} +% +% +% \bigskip +% The command |\@@_x_computation_analyze_lines_between:| will analyse the lines between between |\l_@@_initial_int| +% and |\l_@@_final_int| in order to modify |\g_@@_x_dim| in consequence. More precisely, we will increase +% |\g_@@_x_dim| if we find a line longer than the current value of |\g_@@_x_dim|. +% \begin{macrocode} +\cs_new_protected:Nn \@@_x_computation_analyze_lines_between: + {\int_compare:nNnT \l_@@_final_int > \g_@@_line_int + {\msg_error:nn {witharrows} {Too~few~lines~for~an~arrow}} +% \end{macrocode} +% +% We begin a loop with |\l_tmpa_int| as index. In this loop, 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} + \int_set:Nn \l_tmpa_int \l_@@_initial_int + \int_until_do:nNnn \l_tmpa_int > \l_@@_final_int + {\tikz[remember~picture] + \path let \p1 = (wa-\tl_use:N\l_@@_prefix_tl-\int_use:N\l_tmpa_int-l) + in \pgfextra {\dim_gset:Nn \g_@@_x_dim {\dim_max:nn \g_@@_x_dim {\x1}}} ; + \int_incr:N \l_tmpa_int + } + } +% \end{macrocode} +% +% +% \bigskip +% We want to compute the $x$-value for the current environment which has option |group| (and therefore all arrows are +% vertical at the same abscissa). Once again, the value will be computed in |\g_@@_x_dim|. +% +% \begin{macrocode} +\cs_new_protected:Nn \@@_x_computation_for_option_group: + {\dim_gzero_new:N \g_@@_x_dim +% \end{macrocode} +% +% \medskip +% First, we calculate the initial value for |\g_@@_x_dim|. In this loop, we use a Tikz command, but, once again, +% nothing is drawn. We use this Tikz command only to read the abscissa of a Tikz node. +% \begin{macrocode} + \prop_get:cnN {g_@@_arrow_\l_@@_prefix_tl _1_prop} {initial} \l_tmpa_tl + \tikz[remember~picture] + \path let \p1 = (wa-\tl_use:N\l_@@_prefix_tl-\tl_use:N\l_tmpa_tl-l) + in \pgfextra {\dim_gset:Nn \g_@@_x_dim {\x1}} ; +% \end{macrocode} +% A global assignment is necessary because of Tikz. +% +% Then, we loop to determine the maximal length of all the lines concerned by the arrows of the environment. +% \begin{macrocode} + \int_set:Nn \l_@@_arrow_int 1 + \int_until_do:nNnn \l_@@_arrow_int > \g_@@_arrow_int + { +% \end{macrocode} +% \smallskip +% |\l_@@_initial_int| is the line number from which the arrow starts and |\l_@@_final_int| is the line number to which +% the arrow ends. +% \begin{macrocode} + \prop_get:cnN {g_@@_arrow_\l_@@_prefix_tl _\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_tl _\int_use:N\l_@@_arrow_int _prop} + {final} \l_tmpa_tl + \int_set:Nn \l_@@_final_int {\l_tmpa_tl} +% \end{macrocode} +% +% \smallskip +% |\@@_x_computation_analyze_lines_between:| will compute between lines |\l_@@_initial_int| and |\l_@@_final_int|. +% \begin{macrocode} + \@@_x_computation_analyze_lines_between: + \int_incr:N \l_@@_arrow_int + } + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_generate_variant:Nn \int_compare:nNnT {cNnT} +\cs_generate_variant:Nn \tl_if_eq:nnF {noF} +% \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$. This macro is fully +% expandable and, thus, can be used directly in the name of a Tikz node. +% \begin{macrocode} +\NewDocumentCommand \WithArrowsLastEnv {} + {\int_use:N \g_@@_last_env_int} +% \end{macrocode} +% +% \subsection{The error messages of the package} +% \begin{macrocode} +\msg_new:nnn {witharrows} + {Third~column~in~a~{WithArrows}~environment} + {By~default,~a~\{WithArrows\}~environment~can~only~have~two~columns.~ + Maybe~you~have~forgotten~a~newline~symbol.~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} + {Arrow~used~outside~{WithArrows}~environment} + {The~command~\string\Arrow\space~should~be~used~only~directly~ + in~\{WithArrows\}~environment~and~not~in~a~subenvironment.~However,~you~ + can~go~on.} +% \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~ + \string\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} + {There~is~at~least~an~arrow~that~can't~be~drawn~because~it~arrives~after~the~ + last~line~of~the~environment.} +% \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} + {Option~incompatible~with~group} + {You~try~to~use~the~option~"\tl_use:N\l_keys_key_tl"~while~ + you~are~using~the~option~"group".~It's~incompatible.~You~can~go~on~ignoring~ + this~option~"\tl_use:N\l_keys_key_tl"~and~"group"~will~be~used.} +% \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~with~an~option~previously~set.~ + If~you~go~on,~I~will~overwrite~the~previous~option.} +% \end{macrocode} +% +% \begin{macrocode} +\msg_new:nnnn {witharrows} + {All~lines~must~have~an~ampersand} + {All~lines~of~an~environment~\{WithArrows\}~must~have~an~second~column~ + (because~the~nodes~are~created~in~the~second~column).~You~can~go~on~but~maybe~ + you~will~have~an~pgf~error~for~an~undefined~shape.} + {The~ampersand~can~be~implicit~ + (e.g.~if~you~use~\string\MoveEqLeft\space~of~mathtools).} +% \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 +% \endinput +% +% Local Variables: +% TeX-fold-mode: nil +% End: diff --git a/Master/texmf-dist/source/latex/witharrows/witharrows.ins b/Master/texmf-dist/source/latex/witharrows/witharrows.ins new file mode 100644 index 00000000000..8e3a891c4dc --- /dev/null +++ b/Master/texmf-dist/source/latex/witharrows/witharrows.ins @@ -0,0 +1,47 @@ +%% +%% 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. +%% +\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 +\generate{\file{witharrows.sty}{\from{witharrows.dtx}{package}}} +\Msg{*********************************************************} +\Msg{*} +\Msg{* To finish the installation you have to move the} +\Msg{* following file into a directory searched by TeX:} +\Msg{*} +\Msg{* \space\space witharrows.sty} +\Msg{*} +\Msg{* To produce the documentation run the file witharrows.dtx} +\Msg{* through XeLaTeX.} +\Msg{*} +\Msg{* Happy TeXing!} +\Msg{*********************************************************} +\endbatchfile + diff --git a/Master/texmf-dist/tex/latex/witharrows/witharrows.sty b/Master/texmf-dist/tex/latex/witharrows/witharrows.sty index c3bd9a31d67..5f9619ed32c 100644 --- a/Master/texmf-dist/tex/latex/witharrows/witharrows.sty +++ b/Master/texmf-dist/tex/latex/witharrows/witharrows.sty @@ -1,341 +1,328 @@ -% This work may be distributed and 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://mirrors.ctan.org/help/Catalogue/licenses.lppl.html -% and version 1.3 or later is part of all distributions of LaTeX -% version 2005/12/01 or later. - - -% The author of this work is F. Pantigny (fpantigny at wanadoo point fr) - -\NeedsTeXFormat{LaTeX2e}[1994/06/01] - - +%% +%% This is file `witharrows.sty', +%% generated with the docstrip utility. +%% +%% The original source files were: +%% +%% witharrows.dtx (with options: `package') +%% +%% 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. +%% +\def\myfileversion{1.1} +\def\myfiledate{2017/11/06} \RequirePackage{l3keys2e} - \ProvidesExplPackage - {WithArrows} - {2017/08/09} - {1.0} - {Draws arrows for explanations on the right side of a alignment.} - - + {witharrows} + {\myfiledate} + {\myfileversion} + {Draws arrows for explanations on the right} \RequirePackage{expl3} \RequirePackage{xparse} - \RequirePackage{tikz} -\usetikzlibrary{calc} -\usetikzlibrary{arrows.meta} -\usetikzlibrary{bending} - - - +\usetikzlibrary{calc,arrows.meta,bending} \RequirePackage{footnote} - - - -% There is a style for the tips of arrow because someone will use this style -% if he wants draw an arrow directly with a Tikz command in his document (probably using the Tikz nodes created by -% {WithArrows} in the \halign. -\tikzset{TipsOfWithArrows/.style= { > = {Straight~Barb[scale=1.2,bend]}} } - - -% The following variables are for the options ; these options can be set at 3 levels : see the groups of keys defined in -% the \keys_define:nn comand below. - -% if the beginning of the arrow use a "r" option (if not, it's a "l" option) -\bool_new:N \l_wa_initial_r_bool -\bool_set_true:N \l_wa_initial_r_bool - -% if the end of the arrow use a "r" option (if not, it's à "l" option) -\bool_new:N \l_wa_final_r_bool -\bool_set_true:N \l_wa_final_r_bool - -% if the arrow use a "i" option (in this case the options "l" and "r" for the ends are meaningless) -\bool_new:N \l_wa_i_bool -\bool_set_false:N \l_wa_i_bool - -% to translate the whole arrow to the right -\dim_new:N \l_wa_xoffset_dim -\dim_set:Nn \l_wa_xoffset_dim {3mm} - -% to indicate if the nodes will be drawn (in red) ; useful only for debugging -\bool_new:N \l_wa_shownodes_bool -\bool_set_false:N \l_wa_shownodes_bool - -% to indiate if the elements of the \halign will be composed with \displaystyle -\bool_new:N \l_wa_displaystyle_bool -\bool_set_false:N \l_wa_displaystyle_bool - -% will contains the Tikz options used to draw the arrow -\tl_clear_new:N \l_wa_options_tikz_tl -% At each possible level for the options ("global", "env" or "local : see below), the new values will be appended -% on the right of the token list \l_wa_options_tikz_tl - -% will be raised when a key controling position of the arrow has been set in the same list of key -% useful in order to raise an error if 2 incompatibles keys are specified at the same level -\bool_new:N \l_wa_position_key_already_set_bool -\bool_set_false:N \l_wa_position_key_already_set_bool - -% This Tikz style is for the nodes created automatically in the \halign. -\tikzstyle{wa_node_style}=[rectangle, +\tikzstyle{__wa_node_style}=[rectangle, inner~sep = 0 pt, minimum~height = 3 pt, minimum~width = 0pt, - red, % red... but will be drawn only if shownodes=true - \bool_if:NT \l_wa_shownodes_bool {draw}] - - - -% There are 3 levels where keys can be set : -% with \WithArrowsOptions{...} : this level will be called "global" level ; -% with \begin{WithArrows}[...] : this level will be called "env" level ; -% with \Arrow[...] : this level will be called "local" level. - -% That's why there is 3 groups of keys named "global", "env" and "local". - -% Before each \keys_set_groups:nnn, we execute a \keys_set_filter:nnn with group "secondary" -% Thus, an unknown key will raise an error. Furthermore, the "primary" keys (those which are not in the -% group "secondary") will be set first : it's useful to raise an error if, for example, keys "i" and "group" -% are set at the same level (which is incoherent). - -% There is also the group named "jump" (with only one key : "jump") for technical reasons. -\keys_define:nn {WithArrows} - { % the key named "jump" will be extracted in the \Arrow command - jump .groups:n = {jump,secondary}, - 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, - % - % 0 = t = \vtop , 1 = c = \vcenter, 2 = b = \vbox - pos .groups:n = {global,env,secondary}, - pos .int_set:N = \l_wa_pos_int, - pos .initial:n = 0, - pos .value_required:n = true, - % - t .groups:n = {global,env,kown}, - t .meta:n = {pos=0}, - c .groups:n = {global,env,kown}, - c .meta:n = {pos=1}, - b .groups:n = {global,env,kown}, - b .meta:n = {pos=2}, - % - % if the user wants to give a new name to the \Arrow command (and the name \Arrow remains free) + red, + \bool_if:NT \l__wa_shownodes_bool {draw}] +\tikzset{TipsOfWithArrows/.style= { > = {Straight~Barb[scale=1.2,bend]}} } +\cs_if_free:NT \spread@equation + {\cs_set:Npn \spread@equation{\openup\jot + \cs_set_eq:NN \spread@equation \prg_do_nothing}} +\seq_new:N \g__wa_position_in_the_tree_seq +\seq_gput_right:Nn \g__wa_position_in_the_tree_seq 1 +\int_new:N \g__wa_last_env_int +\skip_new:N \l__wa_interline_skip +\bool_new:N \l__wa_MoreColumns_bool +\int_new:N \l__wa_pos_int +\bool_new:N \l__wa_initial_r_bool +\bool_set_true:N \l__wa_initial_r_bool +\bool_new:N \l__wa_final_r_bool +\bool_set_true:N \l__wa_final_r_bool +\bool_new:N \l__wa_i_bool +\dim_new:N \l__wa_xoffset_dim +\dim_set:Nn \l__wa_xoffset_dim {3mm} +\bool_new:N \l__wa_shownodes_bool +\bool_new:N \l__wa_shownodenames_bool +\bool_new:N \l__wa_displaystyle_bool +\tl_clear_new:N \l__wa_options_tikz_tl +\bool_new:N \l__wa_position_key_already_set_bool +\seq_new:N \g__wa_stack_counter_arrows_seq +\int_new:N \g__wa_arrow_int +\seq_new:N \g__wa_stack_counter_lines_seq +\int_new:N \g__wa_line_int +\seq_new:N \g__wa_stack_counter_lines_bis_seq +\int_new:N \g__wa_line_bis_int + +\keys_define:nn {WithArrows} + { jump .groups:n = {jump,secondary}, + jump .code:n = {\int_set:Nn \l__wa_jump_int {#1} + \int_compare:nNnF \l__wa_jump_int > 0 + {\msg_error:nn {witharrows} + {The~option~"jump"~must~be~non~negative}}}, + jump .value_required:n = true, + t .groups:n = {global,env,secondary}, + t .code:n = {\int_set:Nn \l__wa_pos_int 0}, + t .value_forbidden:n = true, + c .groups:n = {global,env,secondary}, + c .code:n = {\int_set:Nn \l__wa_pos_int 1}, + c .value_forbidden:n = true, + b .groups:n = {global,env,secondary}, + b .code:n = {\int_set:Nn \l__wa_pos_int 2}, + b .value_forbidden:n = true, + MoreColumns .groups:n = {global,env,secondary}, + MoreColumns .bool_set:N = \l__wa_MoreColumns_bool, + MoreColumns .default:n = true, + MoreColumns .value_forbidden:n = true, CommandName .groups:n = {global,env,secondary}, - CommandName .tl_set:N = \l_wa_CommandName_tl, + CommandName .tl_set:N = \l__wa_CommandName_tl, CommandName .initial:n = {Arrow}, CommandName .value_required:n = true, - % displaystyle .groups:n = {global,env,secondary}, - displaystyle .bool_set:N = \l_wa_displaystyle_bool, - displaystyle .value_forbidden:n = true, - % + displaystyle .bool_set:N = \l__wa_displaystyle_bool, % shownodes .groups:n = {global,env,secondary}, - shownodes .bool_set:N = \l_wa_shownodes_bool, + shownodes .bool_set:N = \l__wa_shownodes_bool, shownodes .default:n = true, - shownodes .value_forbidden:n = true, - % - jot .groups:n = {env,secondary}, % don't put "global" - jot .dim_set:N = \jot, % \jot is a LaTeX parameter for the distance between 2 lines in displaymath + shownodenames .groups:n = {global,env,secondary}, + shownodenames .bool_set:N = \l__wa_shownodenames_bool, + shownodenames .default:n = true, + jot .groups:n = {env,secondary}, + jot .dim_set:N = \jot, jot .value_required:n = true, - % + interline .groups:n = {env,secondary}, + interline .skip_set:N = \l__wa_interline_skip, + interline .initial:n = \c_zero_skip, + interline .value_required:n = true, xoffset .groups:n = {global,env,local,secondary}, - xoffset .dim_set:N = \l_wa_xoffset_dim, - xoffset .value_required:n = true, - % + xoffset .dim_set:N = \l__wa_xoffset_dim, + xoffset .value_required:n = true, tikz .groups:n = {global,env,local,secondary}, - tikz .code:n = {\tl_put_right:Nn \l_wa_options_tikz_tl {,#1}}, + tikz .code:n = {\tl_put_right:Nn \l__wa_options_tikz_tl {,#1}}, tikz .value_required:n = true, - % ll .groups:n = {global,env,local,secondary}, - ll .value_forbidden:n = true, + ll .value_forbidden:n = true, ll .default:n = true, - ll .code:n = {\bool_if:NT \l_wa_position_key_already_set_bool - {\msg_error:nn {WithArrows} {Two~options~are~incompatible}} - \bool_if:NT \l_wa_group_bool - {\msg_error:nn {WithArrows} {Option~incompatible~with~group}} - \bool_set_true:N \l_wa_position_key_already_set_bool - \bool_set_false:N \l_wa_initial_r_bool - \bool_set_false:N \l_wa_final_r_bool - \bool_set_false:N \l_wa_i_bool }, - % + ll .code:n = {\bool_if:NT \l__wa_position_key_already_set_bool + {\msg_error:nn {witharrows} + {Two~options~are~incompatible}} + \bool_if:NT \l__wa_group_bool + {\msg_error:nn {witharrows} + {Option~incompatible~with~group}} + \bool_set_true:N \l__wa_position_key_already_set_bool + \bool_set_false:N \l__wa_initial_r_bool + \bool_set_false:N \l__wa_final_r_bool + \bool_set_false:N \l__wa_i_bool }, lr .groups:n = {global,env,local,secondary}, lr .value_forbidden:n = true, - lr .default:n = true, - lr .code:n = {\bool_if:NT \l_wa_position_key_already_set_bool - {\msg_error:nn {WithArrows} {Two~options~are~incompatible}} - \bool_if:NT \l_wa_group_bool - {\msg_error:nn {WithArrows} {Option~incompatible~with~group}} - \bool_set_true:N \l_wa_position_key_already_set_bool - \bool_set_false:N \l_wa_initial_r_bool - \bool_set_true:N \l_wa_final_r_bool - \bool_set_false:N \l_wa_i_bool}, - % + lr .default:n = true, + lr .code:n = {\bool_if:NT \l__wa_position_key_already_set_bool + {\msg_error:nn {witharrows} + {Two~options~are~incompatible}} + \bool_if:NT \l__wa_group_bool + {\msg_error:nn {witharrows} + {Option~incompatible~with~group}} + \bool_set_true:N \l__wa_position_key_already_set_bool + \bool_set_false:N \l__wa_initial_r_bool + \bool_set_true:N \l__wa_final_r_bool + \bool_set_false:N \l__wa_i_bool}, rl .groups:n = {global,env,local,secondary}, rl .value_forbidden:n = true, - rl .default:n = true, - rl .code:n = {\bool_if:NT \l_wa_position_key_already_set_bool - {\msg_error:nn {WithArrows} {Two~options~are~incompatible}} - \bool_if:NT \l_wa_group_bool - {\msg_error:nn {WithArrows} {Option~incompatible~with~group}} - \bool_set_true:N \l_wa_position_key_already_set_bool - \bool_set_true:N \l_wa_initial_r_bool - \bool_set_false:N \l_wa_final_r_bool - \bool_set_false:N \l_wa_i_bool}, - % + rl .default:n = true, + rl .code:n = {\bool_if:NT \l__wa_position_key_already_set_bool + {\msg_error:nn {witharrows} + {Two~options~are~incompatible}} + \bool_if:NT \l__wa_group_bool + {\msg_error:nn {witharrows} + {Option~incompatible~with~group}} + \bool_set_true:N \l__wa_position_key_already_set_bool + \bool_set_true:N \l__wa_initial_r_bool + \bool_set_false:N \l__wa_final_r_bool + \bool_set_false:N \l__wa_i_bool}, rr .groups:n = {global,env,local,secondary}, rr .value_forbidden:n = true, - rr .default:n = true, - rr .code:n = {\bool_if:NT \l_wa_position_key_already_set_bool - {\msg_error:nn {WithArrows} {Two~options~are~incompatible}} - \bool_if:NT \l_wa_group_bool - {\msg_error:nn {WithArrows} {Option~incompatible~with~group}} - \bool_set_true:N \l_wa_position_key_already_set_bool - \bool_set_true:N \l_wa_initial_r_bool - \bool_set_true:N \l_wa_final_r_bool - \bool_set_false:N \l_wa_i_bool}, - % + rr .default:n = true, + rr .code:n = {\bool_if:NT \l__wa_position_key_already_set_bool + {\msg_error:nn {witharrows} + {Two~options~are~incompatible}} + \bool_if:NT \l__wa_group_bool + {\msg_error:nn {witharrows} + {Option~incompatible~with~group}} + \bool_set_true:N \l__wa_position_key_already_set_bool + \bool_set_true:N \l__wa_initial_r_bool + \bool_set_true:N \l__wa_final_r_bool + \bool_set_false:N \l__wa_i_bool}, i .groups:n = {global,env,local,secondary}, - i .code:n = {\bool_if:NT \l_wa_position_key_already_set_bool - {\msg_error:nn {WithArrows} {Two~options~are~incompatible}} - \bool_if:NT \l_wa_group_bool - {\msg_error:nn {WithArrows} {Option~incompatible~with~group}} - \bool_set_true:N \l_wa_position_key_already_set_bool - \bool_set_true:N \l_wa_i_bool}, + i .code:n = {\bool_if:NT \l__wa_position_key_already_set_bool + {\msg_error:nn {witharrows} + {Two~options~are~incompatible}} + \bool_if:NT \l__wa_group_bool + {\msg_error:nn {witharrows} + {Option~incompatible~with~group}} + \bool_set_true:N \l__wa_position_key_already_set_bool + \bool_set_true:N \l__wa_i_bool}, i .value_forbidden:n = true, i .default:n = true, - % - % indicate if all the arrows of an environment are grouped - % volontary not in "secondary" group : thus, if will be set first during the \keys_set_filter:nnn - group .groups:n = {global,env}, - group .bool_set:N = \l_wa_group_bool, + group .groups:n = {global,env}, + group .bool_set:N = \l__wa_group_bool, group .value_forbidden:n = true } - - - - - \ProcessKeysOptions {WithArrows} - - -% \WithArrowsOptions is the command of the WithArrows package to fix options at the document level \NewDocumentCommand \WithArrowsOptions {m} - {\bool_set_false:N \l_wa_position_key_already_set_bool - \keys_set_filter:nnn {WithArrows} {secondary} {#1} % in order to raise an error if a key is unknown + {\bool_set_false:N \l__wa_position_key_already_set_bool + \keys_set_filter:nnn {WithArrows} {secondary} {#1} \keys_set_groups:nnn {WithArrows} {global} {#1}} - - - +\NewDocumentCommand \__wa_Arrow {O{} m O{}} + {\tl_if_eq:noF {WithArrows} {\@currenvir} + {\msg_error:nn {witharrows} {Arrow~used~outside~{WithArrows}~environment}} + \int_gincr:N \g__wa_arrow_int + \int_zero_new:N \l__wa_jump_int + \int_set:Nn \l__wa_jump_int 1 + \keys_set_groups:nnn {WithArrows} {jump} {#1,#3} + \prop_put:NnV \l_tmpa_prop {initial} \g__wa_line_int + \int_set:Nn \l_tmpa_int {\g__wa_line_int + \l__wa_jump_int} + \prop_put:NnV \l_tmpa_prop {final} \l_tmpa_int + \prop_put:Nnn \l_tmpa_prop {options} {#1,#3} + \prop_put:Nnn \l_tmpa_prop {label} {#2} + \prop_gclear_new:c + {g__wa_arrow_\l__wa_prefix_tl _\int_use:N\g__wa_arrow_int _prop} + \prop_gset_eq:cN + {g__wa_arrow_\l__wa_prefix_tl _\int_use:N\g__wa_arrow_int _prop} + \l_tmpa_prop + } \NewDocumentEnvironment {WithArrows} {O{}} - {\reverse_if:N \if_mode_math: - \msg_error:nn {WithArrows} {WithArrows~used~outside~math~mode} + { \seq_gput_right:NV \g__wa_stack_counter_arrows_seq \g__wa_arrow_int + \int_gzero:N \g__wa_arrow_int + \seq_gput_right:NV \g__wa_stack_counter_lines_seq \g__wa_line_int + \int_gzero:N \g__wa_line_int + \seq_gput_right:NV \g__wa_stack_counter_lines_bis_seq \g__wa_line_bis_int + \int_gzero:N \g__wa_line_bis_int + \seq_gput_right:Nn \g__wa_position_in_the_tree_seq 1 + \seq_set_eq:NN \l_tmpa_seq \g__wa_position_in_the_tree_seq + \seq_pop_right:NN \l_tmpa_seq \l_tmpa_tl + \tl_clear_new:N \l__wa_prefix_tl + \tl_set:Nx \l__wa_prefix_tl {\seq_use:Nnnn \l_tmpa_seq {-} {-} {-}} + + \reverse_if:N \if_mode_math: + \msg_error:nn {witharrows} {{WithArrows}~used~outside~math~mode} \fi - \savenotes % to extract the footnotes of the environment {WithArrows} - \m@th - \def\\{\cr} - % - \int_gzero_new:N \g_wa_line_int % to count the lines in the \halign - % - % to count the arrows created in the environment - \int_gzero_new:N \g_wa_arrow_int - % - % these 3 counters will be used later as variables - \int_zero_new:N \l_initial_int - \int_zero_new:N \l_final_int - \int_zero_new:N \l_arrow_int - % - \bool_set_false:N \l_wa_position_key_already_set_bool - \keys_set_filter:nnn {WithArrows} {secondary} {#1} % in order to raise an error if a key is unknown + \savenotes + \cs_set_eq:NN \\ \__wa_cr: + \mathsurround = \c_zero_dim + \int_zero_new:N \l__wa_initial_int + \int_zero_new:N \l__wa_final_int + \int_zero_new:N \l__wa_arrow_int + \bool_set_false:N \l__wa_position_key_already_set_bool + \skip_zero:N \l__wa_interline_skip + \keys_set_filter:nnn {WithArrows} {secondary} {#1} \keys_set_groups:nnn {WithArrows} {env} {#1} - % - \cs_set:cpn \l_wa_CommandName_tl {\wa_Arrow} % new name for \Arrow command in {WithArrows} environments - % - \int_case:nnF \l_wa_pos_int % is fixed via the options t, c or b + \cs_set_eq:cN \l__wa_CommandName_tl \__wa_Arrow + \int_case:nn \l__wa_pos_int {0 {\vtop} 1 {\vcenter} 2 {\vbox}} - {\msg_error:nn {WithArrows} {Bad~value~for~option~pos}} \bgroup - \openup\jot + \spread@equation \ialign\bgroup - \int_gincr:N \g_wa_line_int % will be used for the names of the 2 nodes of the line + \int_gincr:N \g__wa_line_int \strut\hfil - $\bool_if:NT \l_wa_displaystyle_bool \displaystyle {##}$ - & - $\bool_if:NT \l_wa_displaystyle_bool \displaystyle {{}##}$ - % - % we create a first node (the "left node" of the line) - \tikz[remember~picture] - \node [wa_node_style] (wa-\int_use:N\g_wa_line_int-l) {} ; + $\bool_if:NT \l__wa_displaystyle_bool \displaystyle {##}$ + & + \int_gincr:N \g__wa_line_bis_int + $\bool_if:NT \l__wa_displaystyle_bool \displaystyle {{}##}$ + \tikz[remember~picture] + \node [__wa_node_style] + (wa-\tl_use:N\l__wa_prefix_tl-\int_use:N\g__wa_line_int-l) {} ; \hfil - % we create a second node (the "right node" of the line) - \tikz[remember~picture] - \node [wa_node_style] (wa-\int_use:N\g_wa_line_int-r) {} ; + \tikz[remember~picture,label~position=right] + \node [__wa_node_style] + (wa-\tl_use:N\l__wa_prefix_tl-\int_use:N\g__wa_line_int-r) {} ; + \bool_if:NT \l__wa_shownodenames_bool + {\hbox_overlap_right:n {\small wa-\tl_use:N\l__wa_prefix_tl + -\int_use:N\g__wa_line_int}} + && \bool_if:NF \l__wa_MoreColumns_bool + {\msg_error:nn {witharrows} {Third~column~in~a~{WithArrows}~environment}} + $\bool_if:NT \l__wa_displaystyle_bool \displaystyle {##}$ \cr } - {\crcr % - \egroup% end of halign - \egroup% end of vtop (or \vcenter or \vbox) - % - \int_compare:nNnT \g_wa_arrow_int > 0 % If there is really arrows... - \wa_draw_arrows: % ...we draw these arrows. + {\crcr + \egroup + \egroup + \int_compare:nNnT \g__wa_line_bis_int < \g__wa_line_int + {\msg_error:nn {witharrows} {All~lines~must~have~an~ampersand}} + \int_compare:nNnT \g__wa_arrow_int > 0 + \__wa_draw_arrows: \spewnotes + \seq_gpop_right:NN \g__wa_position_in_the_tree_seq \l_tmpa_tl + \seq_gpop_right:NN \g__wa_position_in_the_tree_seq \l_tmpa_tl + \seq_gput_right:Nx \g__wa_position_in_the_tree_seq {\int_eval:n {\l_tmpa_tl + 1}} + \int_compare:nNnT {\seq_count:N \g__wa_position_in_the_tree_seq} = 1 + {\int_gincr:N \g__wa_last_env_int} + \seq_gpop_right:NN \g__wa_stack_counter_arrows_seq {\l_tmpa_tl} + \int_gset:Nn \g__wa_arrow_int {\l_tmpa_tl} + \seq_gpop_right:NN \g__wa_stack_counter_lines_seq \l_tmpa_tl + \int_gset:Nn \g__wa_line_int {\l_tmpa_tl} + \seq_gpop_right:NN \g__wa_stack_counter_lines_bis_seq \l_tmpa_tl + \int_gset:Nn \g__wa_line_bis_int {\l_tmpa_tl} } - - - -% le following code is necessary because we whill have to expand un argument exactly 3 times +\cs_set_protected:Nn \__wa_cr: + {\scan_stop: + \group_align_safe_begin: + \peek_meaning_remove:NTF * \__wa_cr_i: \__wa_cr_i:} +\cs_set_protected:Nn \__wa_cr_i: + {\peek_meaning:NTF [ {\__wa_cr_ii:} {\__wa_cr_ii:[\c_zero_dim]} } +\cs_new_protected:Npn \__wa_cr_ii:[#1] + {\group_align_safe_end: + \cr\noalign{\skip_vertical:n {#1 + \l__wa_interline_skip} + \scan_stop:}} \cs_generate_variant:Nn \keys_set_groups:nnn {nno} -\cs_new:Nn \keys_set_groups_WithArrows_local: {\keys_set_groups:nno {WithArrows} {local}} - +\cs_new_protected:Nn \keys_set_groups_WithArrows_local: + {\keys_set_groups:nno {WithArrows} {local}} \cs_generate_variant:Nn \keys_set_filter:nnn {nno} -\cs_new:Nn \keys_set_filter_WithArrows_secondary: {\keys_set_filter:nno {WithArrows} {secondary}} - -\cs_new:Nn \wa_draw_arrows: - {% - % if the option "group" is used in the current environment - \bool_if:NT \l_wa_group_bool - \wa_x_computation_for_option_group: % will compute \g_wa_x_dim which is the abscissa of all the arrows - % - % loop over the arrows created in the environment : the arrows will be drawn - \int_set:Nn \l_arrow_int 1 - \int_until_do:nNnn \l_arrow_int > \g_wa_arrow_int % g_wa_arrow_int is the total number of arrows +\cs_new_protected:Nn \keys_set_filter_WithArrows_secondary: + {\keys_set_filter:nno {WithArrows} {secondary}} +\cs_new_protected:Nn \__wa_draw_arrows: + { + \bool_if:NT \l__wa_group_bool + \__wa_x_computation_for_option_group: + \int_set:Nn \l__wa_arrow_int 1 + \int_until_do:nNnn \l__wa_arrow_int > \g__wa_arrow_int { - % \l_initial_int is the line number from which the arrow starts - \int_set:Nn \l_initial_int {\int_use:c {wa_initial\int_use:N\l_arrow_int}} - % - % \l_final_int is the line number to which the arrow ends - \int_set:Nn \l_final_int {\int_use:c {wa_final\int_use:N\l_arrow_int}} - % - \int_compare:nNnT \l_final_int > \g_wa_line_int - {\msg_error:nn {WithArrows} {Too~few~lines~for~an~arrow}} - % - \group_begin: % for the options given in \Arrow[...] ("local level" of the options) + \prop_get:cnN {g__wa_arrow_\l__wa_prefix_tl _\int_use:N\l__wa_arrow_int _prop} + {initial} \l_tmpa_tl + \int_set:Nn \l__wa_initial_int {\l_tmpa_tl} + \prop_get:cnN {g__wa_arrow_\l__wa_prefix_tl _\int_use:N\l__wa_arrow_int _prop} + {final} \l_tmpa_tl + \int_set:Nn \l__wa_final_int {\l_tmpa_tl} + \int_compare:nNnT \l__wa_final_int > \g__wa_line_int + {\msg_error:nn {witharrows} {Too~few~lines~for~an~arrow}} + \group_begin: \keys_define:nn {WithArrows} {group .undefine:} - \bool_set_false:N \l_wa_position_key_already_set_bool - % the third argument de \keys_set_groups:nnn must be expanded exactly three times - % a x-expansion is not possible because there can be tokens like \bfseries in the option "font" - \exp_args:NNo \exp_args:No \keys_set_filter_WithArrows_secondary: {\use:c {wa_options\int_use:N\l_arrow_int}} - \exp_args:NNo \exp_args:No \keys_set_groups_WithArrows_local: {\use:c {wa_options\int_use:N\l_arrow_int}} - % - % In case of option "i", we have to compute the abscissa of the arrow (which is vertical). - \bool_if:NT \l_wa_i_bool - \wa_x_computation_for_option_i: % the abscissa is computed in \g_wa_x_dim - % - % \l_initial_tl contains the name of the Tikz node from which the arrow starts (in normal cases... - % because with option "group" or option "i", the point will perhaps have an other x-value --- but always the - % same y-value). - \tl_set:Nx \l_initial_tl {wa-\int_use:N\l_initial_int-\bool_if:NTF\l_wa_initial_r_bool rl} - % - % \l_final_tl contains the name of the Tikz node to which the arrow ends (in normal cases : with option - % "group" or option "i", the point will perhaps have an other x-value but always the same y-value) - \tl_set:Nx \l_final_tl {wa-\int_use:N\l_final_int-\bool_if:NTF\l_wa_final_r_bool rl . north} - % ". north" because we want a small gap between two consecutive arrows - % + \bool_set_false:N \l__wa_position_key_already_set_bool + \prop_get:cnN {g__wa_arrow_\l__wa_prefix_tl + _\int_use:N\l__wa_arrow_int _prop} {options} \l_tmpa_tl + \exp_args:NNo \exp_args:No \keys_set_filter_WithArrows_secondary: {\l_tmpa_tl} + \exp_args:NNo \exp_args:No \keys_set_groups_WithArrows_local: {\l_tmpa_tl} + \bool_if:NT \l__wa_i_bool + \__wa_x_computation_for_option_i: + \tl_set:Nx \l__wa_initial_tl + {wa-\tl_use:N\l__wa_prefix_tl-\int_use:N\l__wa_initial_int- + \bool_if:NTF\l__wa_initial_r_bool rl} + \tl_set:Nx \l__wa_final_tl + {wa-\tl_use:N\l__wa_prefix_tl-\int_use:N\l__wa_final_int- + \bool_if:NTF\l__wa_final_r_bool rl . north} \begin{tikzpicture}[remember~picture, overlay, align=left, @@ -345,161 +332,106 @@ ->, looseness=1, bend~left=45] - \draw \exp_after:wN [\l_wa_options_tikz_tl] - % \p1 and \p2 are the two ends of the arrow (in fact, not exactly in case of options "group" or "i") - let \p1 = (\tl_use:N \l_initial_tl), - \p2 = (\tl_use:N \l_final_tl) in - (\bool_if:nTF {\l_wa_group_bool || \l_wa_i_bool} - {\dim_use:N \g_wa_x_dim + \dim_use:N \l_wa_xoffset_dim, \y1} - {\x1 + \dim_use:N \l_wa_xoffset_dim, \y1} ) - to node (wa-a-\int_use:N\l_arrow_int) % in fact, this name will not be used by WithArrows - {\tl_use:c {wa_label\int_use:N\l_arrow_int}} - (\bool_if:nTF {\l_wa_group_bool || \l_wa_i_bool} - {\dim_use:N \g_wa_x_dim + \dim_use:N \l_wa_xoffset_dim, \y2} - {\x2 + \dim_use:N \l_wa_xoffset_dim, \y2} ) ; + \prop_get:cnN {g__wa_arrow_\l__wa_prefix_tl _\int_use:N\l__wa_arrow_int _prop} + {label} \l_tmpa_tl + \draw \exp_after:wN [\l__wa_options_tikz_tl] + let \p1 = (\tl_use:N \l__wa_initial_tl), + \p2 = (\tl_use:N \l__wa_final_tl) in + (\bool_if:nTF {\l__wa_group_bool || \l__wa_i_bool} + {\dim_use:N \g__wa_x_dim + \dim_use:N \l__wa_xoffset_dim, \y1} + {\x1 + \dim_use:N \l__wa_xoffset_dim, \y1} ) + to node [node~contents = {\tl_use:N \l_tmpa_tl}] {} + (\bool_if:nTF {\l__wa_group_bool || \l__wa_i_bool} + {\dim_use:N \g__wa_x_dim + \dim_use:N \l__wa_xoffset_dim, \y2} + {\x2 + \dim_use:N \l__wa_xoffset_dim, \y2} ) ; \end{tikzpicture} - \group_end: % for the options given to \Arrow[...] ("local level" of the options) - \int_incr:N \l_arrow_int - } % end of the loop over the arrows : all arrows are drawn + \group_end: + \int_incr:N \l__wa_arrow_int + } } - - -% We want to compute the x-value for the current environment which has option "group" (and therefore all arrows are -% vertical at the same abscissa). This value will be computed in \g_wa_x_dim (which is global for technical reasons : -% we have to do assignments in a \tikz command). -\cs_new:Nn \wa_x_computation_for_option_group: - {\dim_gzero_new:N \g_wa_x_dim - % - % first, we calculate the initial value for \g_wa_x_dim - % in this \tikz command, nothing is drawn : we only want to read the abscissa of a Tikz node - \tikz[remember~picture] - \path let \p1 = (wa-\int_use:c{wa_initial1}-l) % "let" is given by the Tikz library "calc" - in \pgfextra {\dim_gset:Nn \g_wa_x_dim {\x1}} ; % a global assignment is necessary because of \tikz - % - % Then, we loop to determine the maximal length of all the lines concerned by the arrows of the environment. - \int_set:Nn \l_arrow_int 1 - \int_until_do:nNnn \l_arrow_int > \g_wa_arrow_int % g_wa_arrow_int is the total number of arrows - { % \l_initial_int is the line number from which the arrow starts - \int_set:Nn \l_initial_int {\int_use:c {wa_initial\int_use:N\l_arrow_int}} - % - % \l_final_int is the line number to which the arrow ends - \int_set:Nn \l_final_int {\int_use:c {wa_final\int_use:N\l_arrow_int}} - % - \wa_x_computation_analyze_lines_between: %... between lines \l_initial_int and \l_final_int - % - \int_incr:N \l_arrow_int - } % end of the loop over the arrows of the environment - } - - -% We want to compute the x-value for the current arrow which has option "i" (and therefore is vertical). -% This value will be computed in \g_wa_x_dim (which is global for technical reasons : we have to do assignments in -% a \tikz command). -\cs_new:Nn \wa_x_computation_for_option_i: - {\dim_gzero_new:N \g_wa_x_dim - % First, we calculate the initial value for \g_wa_x_dim. - % In the next \tikz command, nothing is drawn : we only want to read a abscissa of a Tikz node. +\cs_new_protected:Nn \__wa_x_computation_for_option_i: + {\dim_gzero_new:N \g__wa_x_dim \tikz[remember~picture] - \path let \p1 = (wa-\int_use:N\l_initial_int-l) % "let" is given by the Tikz library "calc" - in \pgfextra {\dim_gset:Nn \g_wa_x_dim {\x1}} ; % a global assignment is necessary because of \tikz - % - \wa_x_computation_analyze_lines_between: %... between lines \l_initial_int and \l_final_int + \path let \p1 = (wa-\tl_use:N\l__wa_prefix_tl-\int_use:N\l__wa_initial_int-l) + in \pgfextra {\dim_gset:Nn \g__wa_x_dim {\x1}} ; + \__wa_x_computation_analyze_lines_between: } - - - - -% We analyse lines between \l_initial_int and \l_final_int in order to modify \g_wa_x_dim in consequence. -% More precisely, we will increase \g_wa_x_dim if we find a line longer than the current value of \g_wa_x_dim. -\cs_new:Nn \wa_x_computation_analyze_lines_between: - {\int_compare:nNnT \l_final_int > \g_wa_line_int - {\msg_error:nn {WithArrows} {Too~few~lines~for~an~arrow}} - % - % \l_tmpa_int will be the index of the loop - \int_set:Nn \l_tmpa_int \l_initial_int - \int_until_do:nNnn \l_tmpa_int > \l_final_int - {% in the next \tikz command, nothing is drawn : we only want to read the abscissa of a Tikz node - \tikz[remember~picture] - \path let \p1 = (wa-\int_use:N\l_tmpa_int-l) - in \pgfextra {\dim_gset:Nn \g_wa_x_dim {\dim_max:nn \g_wa_x_dim {\x1}}} ; % \gset because of \tikz +\cs_new_protected:Nn \__wa_x_computation_analyze_lines_between: + {\int_compare:nNnT \l__wa_final_int > \g__wa_line_int + {\msg_error:nn {witharrows} {Too~few~lines~for~an~arrow}} + \int_set:Nn \l_tmpa_int \l__wa_initial_int + \int_until_do:nNnn \l_tmpa_int > \l__wa_final_int + {\tikz[remember~picture] + \path let \p1 = (wa-\tl_use:N\l__wa_prefix_tl-\int_use:N\l_tmpa_int-l) + in \pgfextra {\dim_gset:Nn \g__wa_x_dim {\dim_max:nn \g__wa_x_dim {\x1}}} ; \int_incr:N \l_tmpa_int - } % loop on the lines between \l_initial_int et \l_final_int - } - - - + } + } +\cs_new_protected:Nn \__wa_x_computation_for_option_group: + {\dim_gzero_new:N \g__wa_x_dim + \prop_get:cnN {g__wa_arrow_\l__wa_prefix_tl _1_prop} {initial} \l_tmpa_tl + \tikz[remember~picture] + \path let \p1 = (wa-\tl_use:N\l__wa_prefix_tl-\tl_use:N\l_tmpa_tl-l) + in \pgfextra {\dim_gset:Nn \g__wa_x_dim {\x1}} ; + \int_set:Nn \l__wa_arrow_int 1 + \int_until_do:nNnn \l__wa_arrow_int > \g__wa_arrow_int + { + \prop_get:cnN {g__wa_arrow_\l__wa_prefix_tl _\int_use:N\l__wa_arrow_int _prop} + {initial} \l_tmpa_tl + \int_set:Nn \l__wa_initial_int {\l_tmpa_tl} + \prop_get:cnN {g__wa_arrow_\l__wa_prefix_tl _\int_use:N\l__wa_arrow_int _prop} + {final} \l_tmpa_tl + \int_set:Nn \l__wa_final_int {\l_tmpa_tl} + \__wa_x_computation_analyze_lines_between: + \int_incr:N \l__wa_arrow_int + } + } \cs_generate_variant:Nn \int_compare:nNnT {cNnT} - -\cs_generate_variant:Nn \tl_if_eq:nnF {onF} - - -% The next command has a strange name, but, in fact, usually, we will have \let\Arrow\wa_Arrow ; -% The user can use the CommandName option if he wants an other name for the command called \Arrow by default. -% It's useful if the user already has a command named "\Arrow" he still wants to use. -\NewDocumentCommand \wa_Arrow {O{} m O{}} - {\tl_if_eq:onF {\@currenvir} {WithArrows} - {\msg_fatal:nn {WithArrows} {Arrow~used~outside~{WithArrows}~environment}} - % - % \g_wa_arrow_int counts the arrows in the environment - \int_gincr:N \g_wa_arrow_int - % - % we decide to extract immediatly the key "jump" in ordre to compute the end line ; - \int_zero_new:N \l_jump_int - \int_set:Nn \l_jump_int 1 - \keys_set_groups:nnn {WithArrows} {jump} {#1,#3} % "jump" is the only key of the group "jump" - % - % to stock the informations of the considered arrow (in four variables) ; - % these informations will be used when the arrow will be really drawn - \int_gzero_new:c {wa_initial\int_use:N\g_wa_arrow_int} - \int_gset_eq:cN {wa_initial\int_use:N\g_wa_arrow_int} \g_wa_line_int - % - \int_gzero_new:c {wa_final\int_use:N\g_wa_arrow_int} - \int_gset:cn {wa_final\int_use:N\g_wa_arrow_int} {\g_wa_line_int + \l_jump_int} - % - \tl_gclear_new:c {wa_options\int_use:N\g_wa_arrow_int} - \tl_gset:cn {wa_options\int_use:N\g_wa_arrow_int} {#1,#3} - % - \tl_gclear_new:c {wa_label\int_use:N\g_wa_arrow_int} - \tl_gset:cn {wa_label\int_use:N\g_wa_arrow_int} {#2} - % - } - - - -\msg_new:nnn {WithArrows} +\cs_generate_variant:Nn \tl_if_eq:nnF {noF} +\bigskip +\NewDocumentCommand \WithArrowsLastEnv {} + {\int_use:N \g__wa_last_env_int} +\msg_new:nnn {witharrows} + {Third~column~in~a~{WithArrows}~environment} + {By~default,~a~\{WithArrows\}~environment~can~only~have~two~columns.~ + Maybe~you~have~forgotten~a~newline~symbol.~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.} +\msg_new:nnn {witharrows} {Arrow~used~outside~{WithArrows}~environment} - {Arrow~command~should~be~used~only~directly~in~\{WithArrows\}~environment\\ - and~not~in~a~subenvironment.} - -\msg_new:nnn {WithArrows} + {The~command~\string\Arrow\space~should~be~used~only~directly~ + in~\{WithArrows\}~environment~and~not~in~a~subenvironment.~However,~you~ + can~go~on.} +\msg_new:nnn {witharrows} {The~option~"jump"~must~be~non~negative} - {You~can't~use~a~stricly~negative~value~for~the~option~"jump"~of~command~Arrow\\ - You~can~create~an~arrow~going~backwards~with~the~option~"<-"~of~Tikz.} - -\msg_new:nnn {WithArrows} + {You~can't~use~a~strictly~negative~value~for~the~option~"jump"~of~command~ + \string\Arrow.~ You~can~create~an~arrow~going~backwards~with~ + the~option~"<-"~of~Tikz.} +\msg_new:nnn {witharrows} {Too~few~lines~for~an~arrow} - {There~is~at~least~an~arrow~that~can't~be~drawn~because~it~arrives~after~the\\ + {There~is~at~least~an~arrow~that~can't~be~drawn~because~it~arrives~after~the~ last~line~of~the~environment.} - -\msg_new:nnn {WithArrows} - {Bad~value~for~option~pos} - {The~option~"pos"~of~the~environment~\{WithArrows\}~must~be~equal~to\\ - 0,~1,~or~2.} - -\msg_new:nnn {WithArrows} - {WithArrows~used~outside~math~mode} - {The~environment~WithArrows~must~be~used~only~in~math~mode.} - -\msg_new:nnn {WithArrows} +\msg_new:nnn {witharrows} + {{WithArrows}~used~outside~math~mode} + {The~environment~\{WithArrows\}~should~be~used~only~in~math~mode.~ + Nevertheless,~you~can~go~on.} +\msg_new:nnn {witharrows} {Option~incompatible~with~group} - {You~try~to~use~the~option~"\tl_use:N\l_keys_key_tl"~while~you~are~using~the~option~"group".\\ - It's~incompatible.~You~can~go~on~ignoring~this~option~"\tl_use:N\l_keys_key_tl"~and~"group"~will~be~used.} - - -\msg_new:nnn {WithArrows} + {You~try~to~use~the~option~"\tl_use:N\l_keys_key_tl"~while~ + you~are~using~the~option~"group".~It's~incompatible.~You~can~go~on~ignoring~ + this~option~"\tl_use:N\l_keys_key_tl"~and~"group"~will~be~used.} +\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\\ - with~an~option~previously~set.~If~you~go~on,~it~will~overwrite~the~previous~option.} - - -\endinput
\ No newline at end of file + {You~try~to~use~the~option~"\tl_use:N\l_keys_key_tl"~but~ + this~option~is~incompatible~with~an~option~previously~set.~ + If~you~go~on,~I~will~overwrite~the~previous~option.} +\msg_new:nnnn {witharrows} + {All~lines~must~have~an~ampersand} + {All~lines~of~an~environment~\{WithArrows\}~must~have~an~second~column~ + (because~the~nodes~are~created~in~the~second~column).~You~can~go~on~but~maybe~ + you~will~have~an~pgf~error~for~an~undefined~shape.} + {The~ampersand~can~be~implicit~ + (e.g.~if~you~use~\string\MoveEqLeft\space~of~mathtools).} +\endinput +%% +%% End of file `witharrows.sty'. |