From 44e65427bf48a4f0e8ec4fa535155720bcc80cae Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Wed, 4 Sep 2019 21:47:57 +0000 Subject: nicematrix (4sep19) git-svn-id: svn://tug.org/texlive/trunk@52028 c570f23f-e606-0410-a88d-b1316a301751 --- .../doc/latex/nicematrix/nicematrix-french.pdf | Bin 300142 -> 313307 bytes .../doc/latex/nicematrix/nicematrix-french.tex | 223 ++- .../texmf-dist/doc/latex/nicematrix/nicematrix.pdf | Bin 621774 -> 656608 bytes .../source/latex/nicematrix/nicematrix.dtx | 1677 +++++++++++++------- .../texmf-dist/tex/latex/nicematrix/nicematrix.sty | 1018 +++++++----- 5 files changed, 1803 insertions(+), 1115 deletions(-) diff --git a/Master/texmf-dist/doc/latex/nicematrix/nicematrix-french.pdf b/Master/texmf-dist/doc/latex/nicematrix/nicematrix-french.pdf index e0d14dea9c1..16331f32b4a 100644 Binary files a/Master/texmf-dist/doc/latex/nicematrix/nicematrix-french.pdf and b/Master/texmf-dist/doc/latex/nicematrix/nicematrix-french.pdf differ diff --git a/Master/texmf-dist/doc/latex/nicematrix/nicematrix-french.tex b/Master/texmf-dist/doc/latex/nicematrix/nicematrix-french.tex index 70064ad807c..924e988c213 100644 --- a/Master/texmf-dist/doc/latex/nicematrix/nicematrix-french.tex +++ b/Master/texmf-dist/doc/latex/nicematrix/nicematrix-french.tex @@ -294,33 +294,9 @@ une seule ligne en pointillés sera tracée (il n'y a pas d'objets qui se superposent dans le fichier \textsc{pdf} résultant\footnote{Et il n'est pas possible de tracer une ligne \verb|\Ldots| et une ligne \verb|\Cdots| entre les mêmes cases.}). -Néanmoins, des calculs inutiles sont effectués par TeX avant qu'il ne détecte -que les deux instructions définissent la même ligne en pointillés. C'est -pourquoi l'extension \pkg{nicematrix} fournit des versions étoilées de -\verb|\Ldots|, \verb|\Cdots|, etc. : \verb|\Ldots*|, \verb|\Cdots*|, etc. Ces versions sont -simplement équivalentes à \verb|\hphantom{\ldots}|, \verb|\hphantom{\cdots}|, etc. -L'utilisateur devrait utiliser des versions étoilées à chaque fois qu'une -version classique (sans étoile) a déjà été utilisée pour la même ligne en pointillés.\par\nobreak - -\bigskip -\begin{BVerbatim}[baseline=c,boxwidth=10cm] -\begin{bNiceMatrix} -0 & \Cdots & ~emphase#\Cdots*@ & 0 \\ -\Vdots & & & \Vdots \\ -~emphase#\Vdots*@ & & & ~emphase#\Vdots*@ \\ -0 & \Cdots & ~emphase#\Cdots*@ & 0 -\end{bNiceMatrix} -\end{BVerbatim} -$\begin{bNiceMatrix} -0 & \Cdots & & 0 \\ -\Vdots & & & \\ - & & & \Vdots \\ -0 & & \Cdots & 0 -\end{bNiceMatrix}$ - \bigskip En fait, dans cet exemple, il aurait été possible de tracer la même matrice -sans commande étoilée avec le codage suivant :\par\nobreak +plus rapidement avec le codage suivant :\par\nobreak \bigskip \begin{BVerbatim}[baseline=c,boxwidth=10cm] \begin{bNiceMatrix} @@ -340,7 +316,7 @@ $\begin{bNiceMatrix} \bigskip Il y a aussi d'autres moyens de changer la taille d'une matrice. On pourrait vouloir utiliser l'argument optionnel de la commande~\verb|\\| pour l'espacement vertical et la commande~\verb|\hspace*| dans une case pour l'espacement -horizontal.\footnote{Le meilleur moyen de régler la largeur des colonnes est, de toutes manières, d'utiliser +horizontal.\footnote{On peut aussi régler la largeur des colonnes en utilisant l'environnement \verb|{NiceArray}| (ou une de ses variantes) avec une colonne de type~\verb|w| ou \verb|W|: cf. p.~\pageref{width}} @@ -412,25 +388,24 @@ a_5 & b \bigskip Par défaut, avec \pkg{nicematrix}, si nous remplaçons \verb|{pmatrix}| par \verb|{pNiceMatrix}| et \verb|\vdots| par -\verb|\Vdots| (or \verb|\Vdots*| pour la rapidité de compilation), la géométrie de la matrice n'est pas -changée.\par\nobreak +\verb|\Vdots|, la géométrie de la matrice n'est pas changée.\par\nobreak \medskip \begin{BVerbatim}[baseline=c,boxwidth=8cm] $C = \begin{pNiceMatrix} a_0 & b \\ a_1 & \Vdots \\ -a_2 & \Vdots* \\ -a_3 & \Vdots* \\ -a_4 & \Vdots* \\ +a_2 & \Vdots \\ +a_3 & \Vdots \\ +a_4 & \Vdots \\ a_5 & b \end{pNiceMatrix}$ \end{BVerbatim} $C = \begin{pNiceMatrix} a_0 & b \\ a_1 & \Vdots \\ -a_2 & \Vdots* \\ -a_3 & \Vdots* \\ -a_4 & \Vdots* \\ +a_2 & \Vdots \\ +a_3 & \Vdots \\ +a_4 & \Vdots \\ a_5 & b \end{pNiceMatrix}$ @@ -575,7 +550,7 @@ $\begin{pmatrix} \section{Les nœuds Tikz créés par l'extension nicematrix} L'extension \pkg{nicematrix} crée un nœud Tikz pour chaque case du tableau considéré. Ces nœuds sont utilisés -pour tracer les lignes en pointillés entre les cases du tableau. Toutefois, l'utilisateur peut utiliser +pour tracer les lignes en pointillés entre les cases du tableau. Toutefois, l'utilisateur peut aussi utiliser directement ces nœuds. On commence par donner un nom au tableau (avec l'option \verb|name|). Cela étant fait, les nœuds sont accessibles à travers les noms «\textsl{nom}-$i$-$j$» où \textsl{nom} est le nom donné au tableau et $i$ et $j$ les numéros de ligne et de colonne de la case considérée. @@ -680,7 +655,8 @@ usages. C'est pourquoi il est possible d'utiliser les options \verb|left-margin| ajouter de l'espace des deux côtés du tableau et aussi de l'espace dans les «nœuds larges» de la première colonne et de la dernière colonne. Dans l'exemple suivant, nous avons utilisé les options \verb|left-margin| et \verb|right-margin|. \footnote{Les options \verb|left-margin| et \verb|right-margin| prennent des dimensions comme valeurs mais, si - aucune valeur n'est donnée, c'est la valeur par défaut qui est utilisée et elle est égale à \verb|\arraycolsep|.} + aucune valeur n'est donnée, c'est la valeur par défaut qui est utilisée et elle est égale à \verb|\arraycolsep| + (par défaut, 5~pt).Il existe aussi une option \verb|margin| pour fixer à la fois \verb|left-margin| et \verb|right-margin|.} \[\begin{pNiceMatrix}[ create-extra-nodes,left-margin,right-margin, code-after = {\begin{tikzpicture} @@ -802,7 +778,7 @@ mais aussi d'autres options définies par \pkg{nicematrix} (\verb|renew-dots|, \ \vspace{1cm} -Un exemple avec un système linéaire (on a besoin de \verb|{NiceArray}| pour le trait vertical): +Un exemple avec un système linéaire (on a besoin de \verb|{NiceArray}| pour le trait vertical) \bigskip \begin{BVerbatim}[baseline=c,boxwidth=10cm] @@ -930,7 +906,9 @@ L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\ dans les colonnes extérieures et un filet vertical (spécifié par un caractère «\verb+|+» dans le préambule du tableau) ne s'étend pas dans les rangées extérieures.\footnote{Ce dernier point n'est pas valable si on a chargé, en plus de \pkg{nicematrix}, l'extension \pkg{arydshln}. Les extensions \pkg{nicematrix} et \pkg{arydshln} ne - sont pas parfaitement compatibles car \pkg{arydshln} redéfinit beaucoup de structures internes à \pkg{array}.} + sont pas parfaitement compatibles car \pkg{arydshln} redéfinit beaucoup de structures internes à \pkg{array}. Par +ailleurs, si on veut vraiment un filet qui s'étende dans la première et la dernière rangée, on peut utiliser +\verb|!{\vline}| dans le préambule à la place de \verb+|+.} \item La «première rangée» d'un environnement \verb|{pNiceArray}| porte le numéro $0$, et non $1$ (de même pour la «première colonne»). Ce numéro est utilisé, par exemple, pour les noms des nœuds Tikz (les noms de ces nœuds sont utilisés, par exemple, par la commande \verb|\line| dans le \verb|code-after|). @@ -1185,6 +1163,74 @@ a & b \\ c & d \end{pNiceMatrix}$ \end{NiceMatrixBlock} +\section{Les matrices par blocs} + +Dans les environnements de \pkg{nicematrix}, on peut utiliser la commande \verb|\Block| pour placer un élément au +centre d'un rectangle de cellules fusionnées. + +La commande \verb|\Block| doit être utilisée dans la cellule supérieure gauche du bloc avec deux arguments. Le +premier argument est la taille de ce bloc avec la syntaxe $i$\verb|-|$j$ où $i$ est le nombre de rangées et $j$ le +nombre de colonnes du bloc. Le deuxième argument, est, sans surprise, le contenu du bloc (en mode mathématique). + +\medskip +\begin{BVerbatim}[baseline=c,boxwidth=10.6cm] +\arrayrulecolor{cyan} +$\begin{bNiceArray}{CCC|C}[margin] +~emphase#\Block{3-3}{A}@ & & & 0 \\ +& \hspace*{1cm} & & \Vdots \\ +& & & 0 \\ +\hline +0 & \Cdots& 0 & 0 +\end{bNiceArray}$ +\arrayrulecolor{black} +\end{BVerbatim} +\begin{scope} +\arrayrulecolor{cyan} +$\begin{bNiceArray}{CCC|C}[margin] +\Block{3-3}{A} & & & 0 \\ +& \hspace*{1cm} & & \Vdots \\ +& & & 0 \\ +\hline +0 & \Cdots& 0 & 0 +\end{bNiceArray}$ +\arrayrulecolor{black} +\end{scope} + +\bigskip +On peut souhaiter agrandir la taille du «$A$» placé dans le bloc de l'exemple précédent. Comme il est composé en +mode mathématique, on ne peut pas directement utiliser une commande comme \verb|\large|, \verb|\Large| ou +\verb|\LARGE|. C'est pourquoi une option à mettre entre chevrons est proposée par \verb|\Block| pour spécifier du +code LaTeX qui sera inséré \emph{avant} le début du mode mathématique. + +\medskip +\begin{BVerbatim}[baseline=c,boxwidth=10.6cm] +\arrayrulecolor{cyan} +$\begin{bNiceArray}{CCC|C}[margin] +\Block{3-3}~emphase#<\Large>@{A} & & & 0 \\ +& \hspace*{1cm} & & \Vdots \\ +& & & 0 \\ +\hline +0 & \Cdots& 0 & 0 +\end{bNiceArray}$ +\arrayrulecolor{black} +\end{BVerbatim} +\begin{scope} +\arrayrulecolor{cyan} +$\begin{bNiceArray}{CCC|C}[margin] +\Block{3-3}<\Large>{A} & & & 0 \\ +& \hspace*{1cm} & & \Vdots \\ +& & & 0 \\ +\hline +0 & \Cdots& 0 & 0 +\end{bNiceArray}$ +\arrayrulecolor{black} +\end{scope} + + +\medskip +Pour des raisons techniques, il n'est pas possible d'écrire \verb|\Block{|$i$\verb|-|$j$\verb|}{<}| +(mais on peut écrire \verb|\Block{|$i$\verb|-|$j$\verb|}<>{<}| avec le résultat attendu). + \section{L'option hlines} @@ -1210,8 +1256,8 @@ c & c & b & a & e Si l'extension \pkg{siunitx} est chargée (avant ou après \pkg{nicematrix}), il est possible d'utiliser les colonnes de type \verb|S| de \pkg{siunitx} dans les environnements de \pkg{nicematrix}. L'implémentation n'utilise -explicitement aucune macro privée de \pkg{siunitx}. Les colonnes \verb|d| de \pkg{dcolumn} ne sont pas prises en -charge par \pkg{nicematrix}. +explicitement aucune macro privée de \pkg{siunitx}. Les colonnes \verb|d| de l'extension \pkg{dcolumn} ne sont pas +prises en charge par \pkg{nicematrix}. \medskip \begin{BVerbatim}[baseline = c, boxwidth = 10.5cm] @@ -1234,6 +1280,42 @@ $\begin{pNiceArray}{SCWc{1cm}C}[nullify-dots,first-row] \section{Remarques techniques} +\subsection{Intersection des lignes pointillées} + +Depuis la version 3.1 de \pkg{nicematrix}, les lignes en pointillées créées par \verb|\Cdots|, \verb|\Ldots|, +\verb|\Vdots|, etc. ne peuvent pas se croiser entre elles.\footnote{En revanche, les lignes créées par + \verb|\hdottedline|, la lettre ``\verb|:|'' dans le préambule de la matrice et la commande \verb|\line| dans le + \verb|code-after| peuvent croiser une autre ligne en pointillés.} + +Cela signifie qu'une ligne en pointillés créée par l'une des ces commandes s'arrête automatiquement quand elle +arrive à une autre ligne pointillée déjà tracée par l'une de ces commandes. Par conséquent, l'ordre dans lequel +les lignes sont tracées a son importance pour le résultat final. Voici cet ordre (c'est à dessein qu'il a été +choisi ainsi) : \verb|\Hdotsfor|, \verb|\Vdots|, \verb|\Ddots|, \verb|\Iddots|, \verb|\Cdots| and \verb|\Ldots|. + +De ce fait, on peut tracer la matrice suivante : + + +\medskip +\begin{BVerbatim}[baseline = c, boxwidth = 10.5cm] +$\begin{pNiceMatrix}[nullify-dots] +1 & 2 & 3 & \Cdots & n \\ +1 & 2 & 3 & \Cdots & n \\ +\Vdots & \Cdots & & \Hspace*{15mm} & \Vdots \\ +& \Cdots & & & \\ +& \Cdots & & & \\ +& \Cdots & & & \\ +\end{pNiceMatrix}$ +\end{BVerbatim} +$\begin{pNiceMatrix}[nullify-dots] +1 & 2 & 3 & \Cdots & n \\ +1 & 2 & 3 & \Cdots & n \\ +\Vdots & \Cdots & & \Hspace*{15mm} & \Vdots \\ +& \Cdots & & & \\ +& \Cdots & & & \\ +& \Cdots & & & \\ +\end{pNiceMatrix}$ + + \subsection{Lignes diagonales} Par défaut, toutes les lignes diagonales\footnote{On parle des lignes créées par \verb|\Ddots| et non des lignes @@ -1332,8 +1414,7 @@ la dernière case (deuxième rangée et deuxième colonne) est vide. \medskip \item Une case qui contient une commande \verb|\Ldots|, \verb|\Cdots|, \verb|\Vdots|, \verb|\Ddots| -ou \verb|\Iddots| (ou une des versions étoilées) est vide. On rappelle que ces commandes doivent être employées seules -dans une case. +ou \verb|\Iddots| est vide. On rappelle que ces commandes doivent être employées seules dans une case. \medskip @@ -1594,7 +1675,7 @@ Un exemple pour le résultant de deux polynômes : \bigskip \begin{BVerbatim} \setlength{\extrarowheight}{1mm} -\[\begin{vNiceArray}{CCCC:CCC}[columns-width=6mm] +\begin{vNiceArray}{CCCC:CCC}[columns-width=6mm] a_0 & && &b_0 & & \\ a_1 &\Ddots&& &b_1 &\Ddots& \\ \Vdots&\Ddots&& &\Vdots &\Ddots&b_0 \\ @@ -1602,7 +1683,7 @@ a_p & &&a_0 & & &b_1 \\ &\Ddots&&a_1 &b_q & &\Vdots\\ & &&\Vdots & &\Ddots& \\ & &&a_p & & &b_q -\end{vNiceArray}\] +\end{vNiceArray} \end{BVerbatim} \bigskip @@ -1621,9 +1702,11 @@ a_p & &&a_0 & & &b_1 \\ \end{scope} \vspace{2cm} -Un exemple avec un système linéaire:\par\nobreak +Un exemple avec un système linéaire (le trait vertical a été tracé en cyan avec les outils de +\pkg{colortbl}):\par\nobreak \begin{Verbatim} +\arrayrulecolor{cyan} $\begin{pNiceArray}{*6C|C}[nullify-dots,last-col,code-for-last-col={\scriptstyle}] 1 & 1 & 1 &\Cdots & & 1 & 0 & \\ 0 & 1 & 0 &\Cdots & & 0 & & L_2 \gets L_2-L_1 \\ @@ -1632,8 +1715,10 @@ $\begin{pNiceArray}{*6C|C}[nullify-dots,last-col,code-for-last-col={\scriptstyle \Vdots & & &\Ddots & & 0 & \\ 0 & & &\Cdots & 0 & 1 & 0 & L_n \gets L_n-L_1 \end{pNiceArray}$ +\arrayrulecolor{black} \end{Verbatim} +\arrayrulecolor{cyan} \[\begin{pNiceArray}{*6C|C}[nullify-dots,last-col,code-for-last-col={\scriptstyle}] 1 & 1 & 1 &\Cdots & & 1 & 0 & \\ 0 & 1 & 0 &\Cdots & & 0 & & L_2 \gets L_2-L_1 \\ @@ -1642,7 +1727,7 @@ $\begin{pNiceArray}{*6C|C}[nullify-dots,last-col,code-for-last-col={\scriptstyle \Vdots & & &\Ddots & & 0 & \\ 0 & & &\Cdots & 0 & 1 & 0 & L_n \gets L_n-L_1 \end{pNiceArray}\] - +\arrayrulecolor{black} \subsection{Largeur des colonnes} @@ -1657,7 +1742,7 @@ nous voulons la même largeur (automatique) pour toutes les colonnes. ~emphase#\begin{NiceMatrixBlock}[auto-columns-width]@ \NiceMatrixOptions{code-for-last-col = \color{blue}\scriptstyle} \setlength{\extrarowheight}{1mm} -\quad $\begin{pNiceArray}{CCCC:C}[last-col] +$\begin{pNiceArray}{CCCC:C}[last-col] 1&1&1&1&1&\\ 2&4&8&16&9&\\ 3&9&27&81&36&\\ @@ -1674,7 +1759,7 @@ nous voulons la même largeur (automatique) pour toutes les colonnes. \NiceMatrixOptions{code-for-last-col = \color{blue}\scriptstyle} \setlength{\extrarowheight}{1mm} -\quad $\begin{pNiceArray}{CCCC:C}[last-col] +\enskip $\begin{pNiceArray}{CCCC:C}[last-col] 1&1&1&1&1&\\ 2&4&8&16&9&\\ 3&9&27&81&36&\\ @@ -1996,7 +2081,7 @@ $\begin{array}{cc} & \end{Verbatim} -La matrice $B$ a une ``première rangée'' (pour $C_j$) d'où l'option \verb|first-row|. +La matrice $B$ a une «première rangée» (pour $C_j$) d'où l'option \verb|first-row|. \begin{Verbatim} \begin{bNiceArray}{C>{\strut}CCCC}[name=B,first-row] & & C_j \\ @@ -2008,7 +2093,7 @@ b_{11} & \Cdots & b_{1j} & \Cdots & b_{1n} \\ \end{bNiceArray} \\ \\ \end{Verbatim} -La matrice $A$ a une ``première colonne'' (pour $L_i$) d'où l'option \verb|first-col|. +La matrice $A$ a une «première colonne» (pour $L_i$) d'où l'option \verb|first-col|. \begin{Verbatim} \begin{bNiceArray}{CC>{\strut}CCC}[name=A,first-col] & a_{11} & \Cdots & & & a_{nn} \\ @@ -2080,42 +2165,4 @@ L_i & a_{i1} & \Cdots & a_{ik} & \Cdots & a_{in} \\ \draw [color = gray] (A-3-3) to [bend left] (B-3-3) ; \end{tikzpicture} - - - -\subsection{Matrices par blocs} - -\medskip -Dans l'exemple suivant, on utilise les «nœuds larges» pour construire une matrice par blocs (les lignes en tiretés -ont été tracées avec \pkg{arydshln}). -\begin{Verbatim} -\NiceMatrixOptions{letter-for-dotted-lines = V} -\begin{pNiceArray}{CC:CC}% ici, % est obligatoire - [create-extra-nodes, - ~emphase#code-after = { \tikz \node [fit = (1-1-large) (2-2-large), inner sep = 0 pt]@ - ~emphase# {$0_{22}$} ; }@ ] - & & a_{13} & a_{14} \\ - & & a_{23} & a_{24} \\ -\hdashline -a_{31} & a_{32} & a_{33} & a_{34} \\ -a_{41} & a_{42} & a_{34} & a_{44} -\end{pNiceArray} -\end{Verbatim} - - -\begin{scope} -\NiceMatrixOptions{letter-for-dotted-lines = V} -\[D = \begin{pNiceArray}{CC:CC}% - [create-extra-nodes, - code-after = { \tikz \node [fit = (1-1-large) (2-2-large), inner sep = 0 pt] - {$0_{22}$} ; } ] - & & a_{13} & a_{14} \\ - & & a_{23} & a_{24} \\ -\hdashline -a_{31} & a_{32} & a_{33} & a_{34} \\ -a_{41} & a_{42} & a_{34} & a_{44} -\end{pNiceArray}\] -\end{scope} - - \end{document} diff --git a/Master/texmf-dist/doc/latex/nicematrix/nicematrix.pdf b/Master/texmf-dist/doc/latex/nicematrix/nicematrix.pdf index 35745735051..11faeef7c06 100644 Binary files a/Master/texmf-dist/doc/latex/nicematrix/nicematrix.pdf and b/Master/texmf-dist/doc/latex/nicematrix/nicematrix.pdf differ diff --git a/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx b/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx index 8709af977d5..3e91e797955 100644 --- a/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx +++ b/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx @@ -15,8 +15,8 @@ % % \fi % \iffalse -\def\myfileversion{3.0} -\def\myfiledate{2019/08/15} +\def\myfileversion{3.1} +\def\myfiledate{2019/09/04} % % %<*batchfile> @@ -310,33 +310,9 @@ c & c & b & a & e % resulting \textsc{pdf}\footnote{And it's not possible to draw a |\Ldots| and a % |\Cdots| line between the same cells.}). % -% However, useless computations are performed by TeX before detecting that both -% instructions would eventually yield the same dotted line. That's why the -% package \pkg{nicematrix} provides starred versions of |\Ldots|, |\Cdots|, -% etc.: |\Ldots*|, |\Cdots*|, etc. These versions are simply equivalent to -% |\hphantom{\ldots}|, |\hphantom{\cdots}|, etc. The user should use these -% starred versions whenever a classical version has already been used for the -% same dotted line.\par\nobreak -% -% \bigskip -% \begin{BVerbatim}[baseline=c,boxwidth=10cm] -% \begin{bNiceMatrix} -% 0 & \Cdots & ~emphase#\Cdots*@ & 0 \\ -% \Vdots & & & \Vdots \\ -% ~emphase#\Vdots*@ & & & ~emphase#\Vdots*@ \\ -% 0 & \Cdots & ~emphase#\Cdots*@ & 0 -% \end{bNiceMatrix} -% \end{BVerbatim} -% $\begin{bNiceMatrix} -% 0 & \Cdots & & 0 \\ -% \Vdots & & & \\ -% & & & \Vdots \\ -% 0 & & \Cdots & 0 -% \end{bNiceMatrix}$ -% % \bigskip -% In fact, in this example, it would be possible to draw the same matrix without -% starred commands with the following code:\par\nobreak +% In fact, in this example, it would be possible to draw the same matrix more +% easily with the following code:\par\nobreak % \bigskip % \begin{BVerbatim}[baseline=c,boxwidth=10cm] % \begin{bNiceMatrix} @@ -353,12 +329,12 @@ c & c & b & a & e % 0 & & \Cdots & 0 % \end{bNiceMatrix}$ % -% \bigskip +% \bigskip e % There are also other means to change the size of the matrix. Someone might % want to use the optional argument of the command~|\\| for the vertical % dimension and a command~|\hspace*| in a cell for the horizontal -% dimension.\footnote{Nevertheless, the best way to fix the width of a column is -% to use the environment |{NiceArray}| (or one of its variants) with a column of +% dimension.\footnote{It's also possible to fix the width of a column +% by using the environment |{NiceArray}| (or one of its variants) with a column of % type~|w| or~|W|: see p.~\pageref{width}} % % However, a command~|\hspace*| might interfer with the construction of the @@ -430,25 +406,25 @@ c & c & b & a & e % % \bigskip % By default, with \pkg{nicematrix}, if we replace |{pmatrix}| by -% |{pNiceMatrix}| and |\vdots| by |\Vdots| (or |\Vdots*| for efficiency), the -% geometry of the matrix is not changed.\par\nobreak +% |{pNiceMatrix}| and |\vdots| by |\Vdots|, the geometry of the matrix is not +% changed.\par\nobreak % \medskip % \begin{BVerbatim}[baseline=c,boxwidth=8cm] % $C = \begin{pNiceMatrix} % a_0 & b \\ % a_1 & \Vdots \\ -% a_2 & \Vdots* \\ -% a_3 & \Vdots* \\ -% a_4 & \Vdots* \\ +% a_2 & \Vdots \\ +% a_3 & \Vdots \\ +% a_4 & \Vdots \\ % a_5 & b % \end{pNiceMatrix}$ % \end{BVerbatim} % $C = \begin{pNiceMatrix} % a_0 & b \\ % a_1 & \Vdots \\ -% a_2 & \Vdots* \\ -% a_3 & \Vdots* \\ -% a_4 & \Vdots* \\ +% a_2 & \Vdots \\ +% a_3 & \Vdots \\ +% a_4 & \Vdots \\ % a_5 & b % \end{pNiceMatrix}$ % @@ -706,7 +682,8 @@ c & c & b & a & e % ``large nodes'' of the first column and last column. In the following example, % we have used the options |left-margin| and |right-margin|.\footnote{The % options |left-margin| and |right-margin| take dimensions as values but, if no -% value is given, the default value is used, which is |\arraycolsep|. There is +% value is given, the default value is used, which is |\arraycolsep| (by +% default: 5~pt). There is % also an option |margin| to fix both |left-margin| and |right-margin| to the % same value.} % \[\begin{pNiceMatrix}[ @@ -966,7 +943,9 @@ c & c & b & a & e % rows.\footnote{The latter is not true when the extension \pkg{arydshln} is % loaded besides \pkg{nicematrix}. In fact, \pkg{nicematrix} and \pkg{arydhsln} % are not totally compatible because \pkg{arydshln} redefines many internals of -% \pkg{array}.} +% \pkg{array}. On another note, if one really wants a vertical rule running in +% the first and in the last row, he should use |!{\vline}| instead of \verb+|+ +% in the preamble of the array.} % \item The ``first row'' of an environment |{pNiceArray}| has the number $0$, and not % $1$. Idem for the ``first column''. This number is used for the names of the Tikz % nodes (the names of these nodes are used, for example, by the command |\line| @@ -1225,15 +1204,86 @@ c & c & b & a & e % \end{pNiceMatrix}$ % \end{NiceMatrixBlock} % +% \section{Block matrices} +% +% In the environments of \pkg{nicematrix}, it's possible to use the command +% |\Block| in order to place an element in the center of a rectangle of merged +% cells of the array. +% +% The command |\Block| must be used in the upper leftmost cell of the array with +% two arguments. The first argument is the size of the block with the syntax +% $i$\verb|-|$j$ where $i$ is the number of rows of the block and $j$ its number +% of columns. The second argument is the content of the block (composed in math mode). +% +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=10.6cm] +% \arrayrulecolor{cyan} +% $\begin{bNiceArray}{CCC|C}[margin] +% ~emphase#\Block{3-3}{A}@ & & & 0 \\ +% & \hspace*{1cm} & & \Vdots \\ +% & & & 0 \\ +% \hline +% 0 & \Cdots& 0 & 0 +% \end{bNiceArray}$ +% \arrayrulecolor{black} +% \end{BVerbatim} +% \begin{scope} +% \arrayrulecolor{cyan} +% $\begin{bNiceArray}{CCC|C}[margin] +% \Block{3-3}{A} & & & 0 \\ +% & \hspace*{1cm} & & \Vdots \\ +% & & & 0 \\ +% \hline +% 0 & \Cdots& 0 & 0 +% \end{bNiceArray}$ +% \arrayrulecolor{black} +% \end{scope} +% +% \bigskip +% One may wish raise the size of the ``$A$'' placed in the block of the previous +% example. Since this element is composed in math mode, it's not possible to use +% directly a command like |\large|, |\Large| and |\LARGE|. That's why the command +% |\Block| provides an option beetween angle brackets to specificy some TeX code +% which will be inserted before the beginning of the math mode. +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=10.6cm] +% \arrayrulecolor{cyan} +% $\begin{bNiceArray}{CCC|C}[margin] +% \Block{3-3}~emphase#<\Large>@{A} & & & 0 \\ +% & \hspace*{1cm} & & \Vdots \\ +% & & & 0 \\ +% \hline +% 0 & \Cdots& 0 & 0 +% \end{bNiceArray}$ +% \arrayrulecolor{black} +% \end{BVerbatim} +% \begin{scope} +% \arrayrulecolor{cyan} +% $\begin{bNiceArray}{CCC|C}[margin] +% \Block{3-3}<\Large>{A} & & & 0 \\ +% & \hspace*{1cm} & & \Vdots \\ +% & & & 0 \\ +% \hline +% 0 & \Cdots& 0 & 0 +% \end{bNiceArray}$ +% \arrayrulecolor{black} +% \end{scope} +% +% \medskip +% For technical reasons, you can't write |\Block{|$i$|-|$j$|}{<}|. But you can +% write |\Block{|$i$|-|$j$|}<>{<}| with the expected result. % % % \section{The option hlines} % % You can add horizontal rules between rows in the environments of % \pkg{nicematrix} with the usual command |\hline|. But, by convenience, the -% extension \pkg{nicematrix} provides the option |hlines|. With this option, all -% the horizontal rules will be drawn (excepted, of course the rule before the -% potential ``first row'' and the rule after the potential ``last row''). +% extension \pkg{nicematrix} also provides the option |hlines|. With this +% option, all the horizontal rules will be drawn (excepted, of course, the rule +% before the potential ``first row'' and the rule after the potential ``last +% row''). % % \medskip % \begin{BVerbatim}[baseline=c,boxwidth=10.6cm] @@ -1252,8 +1302,8 @@ c & c & b & a & e % If the package \pkg{siunitx} is loaded (before or after \pkg{nicematrix}), % it's possible to use the |S| column type of \pkg{siunitx} in the environments % of \pkg{nicematrix}. The implementation doesn't use explicitly any private -% macro of \pkg{siunitx}. The |d| columns of \pkg{dcolumn} are not supported by -% \pkg{nicematrix}. +% macro of \pkg{siunitx}. The |d| columns of the package \pkg{dcolumn} are not +% supported by \pkg{nicematrix}. % % % \medskip @@ -1277,6 +1327,44 @@ c & c & b & a & e % % \section{Technical remarks} % +% \subsection{Intersections of dotted lines} +% +% Since the version 3.1 of \pkg{nicematrix}, the dotted lines created by +% |\Cdots|, |\Ldots|, |\Vdots|, etc. can't intersect.\footnote{Of the contrary, +% dotted lines created by |\hdottedline|, the letter ``|:|'' in the preamble +% of the array and the command |\line| in the |code-after| can have +% intersections with other dotted lines.} +% +% That means that a dotted line created by one these commands automatically +% stops when it arrives on a dotted line already drawn. Therefore, the order in +% which dotted lines are drawn is important. Here's that order (by design) : +% |\Hdotsfor|, |\Vdots|, |\Ddots|, |\Iddots|, |\Cdots| and |\Ldots|. +% +% With this structure, it's possible to draw the following matrix. +% +% \medskip +% \begin{BVerbatim}[baseline = c, boxwidth = 10.5cm] +% $\begin{pNiceMatrix}[nullify-dots] +% 1 & 2 & 3 & \Cdots & n \\ +% 1 & 2 & 3 & \Cdots & n \\ +% \Vdots & \Cdots & & \Hspace*{15mm} & \Vdots \\ +% & \Cdots & & & \\ +% & \Cdots & & & \\ +% & \Cdots & & & \\ +% \end{pNiceMatrix}$ +% \end{BVerbatim} +% % $\begin{pNiceMatrix}[nullify-dots] +% 1 & 2 & 3 & \Cdots & n \\ +% 1 & 2 & 3 & \Cdots & n \\ +% \Vdots & \Cdots & & \Hspace*{15mm} & \Vdots \\ +% & \Cdots & & & \\ +% & \Cdots & & & \\ +% & \Cdots & & & \\ +% \end{pNiceMatrix}$ +% +% +% +% % \subsection{Diagonal lines} % % By default, all the diagonal lines\footnote{We speak of the lines created by @@ -1377,8 +1465,8 @@ c & c & b & a & e % % \medskip % \item A cell which contains a command |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots| -% or |\Iddots| and their starred versions is empty. We recall that these -% commands should be used alone in a cell. +% or |\Iddots| is empty. We recall that these commands should be used alone in a +% cell. % % \medskip % \item A cell with a command |\Hspace| (or |\Hspace*|) is empty. This command @@ -1662,9 +1750,11 @@ c & c & b & a & e % \end{scope} % % \vspace{2cm} -% An example for a linear system:\par\nobreak +% An example for a linear system (the vertical rule has been drawn in cyan with +% the tools of \pkg{colortbl}):\par\nobreak % % \begin{Verbatim} +% \arrayrulecolor{cyan} % $\begin{pNiceArray}{*6C|C}[nullify-dots,last-col,code-for-last-col={\scriptstyle}] % 1 & 1 & 1 &\Cdots & & 1 & 0 & \\ % 0 & 1 & 0 &\Cdots & & 0 & & L_2 \gets L_2-L_1 \\ @@ -1673,8 +1763,10 @@ c & c & b & a & e % \Vdots & & &\Ddots & & 0 & \\ % 0 & & &\Cdots & 0 & 1 & 0 & L_n \gets L_n-L_1 % \end{pNiceArray}$ +% \arrayrulecolor{black} % \end{Verbatim} % +% \arrayrulecolor{cyan} % \[\begin{pNiceArray}{*6C|C}[nullify-dots,last-col,code-for-last-col={\scriptstyle}] % 1 & 1 & 1 &\Cdots & & 1 & 0 & \\ % 0 & 1 & 0 &\Cdots & & 0 & & L_2 \gets L_2-L_1 \\ @@ -1683,6 +1775,7 @@ c & c & b & a & e % \Vdots & & &\Ddots & & 0 & \\ % 0 & & &\Cdots & 0 & 1 & 0 & L_n \gets L_n-L_1 % \end{pNiceArray}\] +% \arrayrulecolor{black} % % % \subsection{Width of the columns} @@ -2122,41 +2215,6 @@ c & c & b & a & e % \draw [color = gray] (A-3-3) to [bend left] (B-3-3) ; % \end{tikzpicture} % -% -% \subsection{Block matrices} -% -% \medskip -% In the following example, we use the ``large nodes'' to construct a block matrix (the dashed lines have been -% drawn with \pkg{arydshln}). -% \begin{Verbatim} -% \NiceMatrixOptions{letter-for-dotted-lines = V} -% \begin{pNiceArray}{CC:CC}[ -% create-extra-nodes, -% ~emphase#code-after = { \tikz \node [fit = (1-1-large) (2-2-large), inner sep = 0 pt]@ -% ~emphase# {$0_{22}$} ; }@ ] -% & & a_{13} & a_{14} \\ -% & & a_{23} & a_{24} \\ -% \hdashline -% a_{31} & a_{32} & a_{33} & a_{34} \\ -% a_{41} & a_{42} & a_{34} & a_{44} -% \end{pNiceArray} -% \end{Verbatim} -% -% -% \begin{scope} -% \NiceMatrixOptions{letter-for-dotted-lines = V} -% \[D = \begin{pNiceArray}{CC:CC}[ -% create-extra-nodes, -% code-after = { \tikz \node [fit = (1-1-large) (2-2-large), inner sep = 0 pt] -% {$0_{22}$} ; } ] -% & & a_{13} & a_{14} \\ -% & & a_{23} & a_{24} \\ -% \hdashline -% a_{31} & a_{32} & a_{33} & a_{34} \\ -% a_{41} & a_{42} & a_{34} & a_{44} -% \end{pNiceArray}\] -% \end{scope} -% % % % \section{Implementation} @@ -2237,6 +2295,7 @@ c & c & b & a & e % \begin{macrocode} \cs_new_protected:Npn \@@_error:n { \msg_error:nn { nicematrix } } \cs_new_protected:Npn \@@_error:nn { \msg_error:nn { nicematrix } } +\cs_new_protected:Npn \@@_error:nnn { \msg_error:nnn { nicematrix } } \cs_new_protected:Npn \@@_fatal:n { \msg_fatal:nn { nicematrix } } \cs_new_protected:Npn \@@_fatal:nn { \msg_fatal:nn { nicematrix } } \cs_new_protected:Npn \@@_msg_new:nn { \msg_new:nnn { nicematrix } } @@ -2264,10 +2323,6 @@ c & c & b & a & e { } % \end{macrocode} % -% \begin{macrocode} -\@@_msg_new:nn { Draft~mode } - { The~compilation~is~in~draft~mode:~the~dotted~lines~won't~be~drawn. } -% \end{macrocode} % % \begin{macrocode} \bool_if:NT \c_@@_draft_bool @@ -2355,34 +2410,42 @@ c & c & b & a & e % \end{macrocode} % % \bigskip -% \begin{macrocode} -\@@_msg_new:nn { Yet~in~env } - { - Environments~\{NiceArray\}~(or~\{NiceMatrix\},~etc.)~can't~be~ - nested.\\ - This~error~is~fatal. - } -% \end{macrocode} +% Consider the following code: +% \begin{Verbatim} +% $\begin{pNiceMatrix} +% a & b & c \\ +% d & e & \Vdots \\ +% f & \Cdots \\ +% g & h & i \\ +% \end{pNiceMatrix}$ +% \end{Verbatim} % -% \bigskip +% First, the dotted line created by the |\Vdots| will be drawn. The implicit +% cell in position 2-3 will be considered as ``dotted''. Then, we will have to +% draw the dotted line specified by the |\Cdots|; the final extremity of that +% line will be exactly in position 2-3 and, for that new second line, it should +% be considered as a \emph{closed} extremity (since it is dotted). However, we +% don't have the (normal) Tikz node of that node (since it's an implicit cell): +% we can't draw such a line. That's why that dotted line will be said +% \emph{impossible} and an error will be raised.\footnote{Of course, the user +% should solve the problem by adding the lacking ampersands.} % \begin{macrocode} -\@@_msg_new:nn { Outside~math~mode } - { - The~environment~\{\@currenvir\}~can~be~used~only~in~math~mode~ - (and~not~in~\token_to_str:N \vcenter).\\ - This~error~is~fatal. - } +\bool_new:N \l_@@_impossible_line_bool % \end{macrocode} -% +% +% % \bigskip -% We have to known whether if \pkg{colortbl} is loaded for the redefinition of -% |\everycr|. +% We have to know whether \pkg{colortbl} is loaded for the redefinition of +% |\everycr| and for |\vline|. % \begin{macrocode} \bool_new:N \c_@@_colortbl_loaded_bool \AtBeginDocument { \@ifpackageloaded { colortbl } - { \bool_set_true:N \c_@@_colortbl_loaded_bool } + { + \bool_set_true:N \c_@@_colortbl_loaded_bool + \cs_set_protected:Npn \@@_vline_i: { { \CT@arc@ \vline } } + } { } } % \end{macrocode} @@ -2600,18 +2663,6 @@ c & c & b & a & e % \bigskip % \subsection{The options} % -% \begin{macrocode} -\@@_msg_new:nn { Option~Transparent~suppressed } - { - The~option~'Transparent'~has~been~renamed~'transparent'.\\ - However,~you~can~go~on~for~this~time. - } -\@@_msg_new:nn { Option~RenewMatrix~suppressed } - { - The~option~'RenewMatrix'~has~been~renamed~'renew-matrix'.\\ - However,~you~can~go~on~for~this~time. - } -% \end{macrocode} % % % The token list |\l_@@_pos_env_str| will contain one of the three values |t|, @@ -2901,7 +2952,7 @@ c & c & b & a & e letter-for-dotted-lines .code:n = { \int_compare:nTF { \tl_count:n { #1 } = \c_one_int } - { \tl_set:Nx \l_@@_letter_for_dotted_lines_str { #1 } } + { \str_set:Nx \l_@@_letter_for_dotted_lines_str { #1 } } { \@@_error:n { Bad~value~for~letter~for~dotted~lines } } } , letter-for-dotted-lines .value_required:n = true , @@ -2914,53 +2965,6 @@ c & c & b & a & e % \end{macrocode} % % -% \bigskip -% \begin{macrocode} -\@@_msg_new:nn { Bad~value~for~letter~for~dotted~lines } - { - The~value~of~key~'\tl_use:N\l_keys_key_tl'~must~be~of~length~1.\\ - If~you~go~on,~it~will~be~ignored. - } -% \end{macrocode} -% -% -% \bigskip -% \begin{macrocode} -\@@_msg_new:nnn { Unknown~key~for~NiceMatrixOptions } - { - The~key~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~command~ - \token_to_str:N \NiceMatrixOptions. \\ - If~you~go~on,~it~will~be~ignored. \\ - For~a~list~of~the~available~keys,~type~H~. - } - { - The~available~keys~are~(in~alphabetic~order):~ - allow-duplicate-names,~ - code-for-first-col,~ - code-for-first-row,~ - code-for-last-col,~ - code-for-last-row,~ - exterior-arraycolsep,~ - hlines,~ - left-margin,~ - letter-for-dotted-lines,~ - nullify-dots,~ - parallelize-diags,~ - renew-dots,~ - renew-matrix,~ - right-margin,~ - and~transparent - } -% \end{macrocode} -% -% \begin{macrocode} -\@@_msg_new:nn { Option~auto~for~columns-width } - { - You~can't~give~the~value~'auto'~to~the~option~'columns-width'~here.~ - If~you~go~on,~the~option~will~be~ignored. - } -% \end{macrocode} -% % \bigskip % |\NiceMatrixOptions| is the command of the \pkg{nicematrix} package to fix % options at the document level. The scope of these specifications is the @@ -2980,48 +2984,6 @@ c & c & b & a & e { unknown .code:n = \@@_error:n { Unknown~option~for~NiceMatrix } } % \end{macrocode} % -% \begin{macrocode} -\@@_msg_new:nnn { Unknown~option~for~NiceMatrix } - { - The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~environment~ - \{NiceMatrix\}~and~its~variants. \\ - If~you~go~on,~it~will~be~ignored. \\ - For~a~list~of~the~available~options,~type~H~. - } - { - The~available~options~are~(in~alphabetic~order):~ - code-after,~ - columns-width,~ - create-extra-nodes,~ - extra-left-margin,~ - extra-right-margin,~ - hlines,~ - left-margin,~ - name,~ - nullify-dots,~ - parallelize-diags,~ - renew-dots~ - and~right-margin. - } -% \end{macrocode} -% -% \bigskip -% \begin{macrocode} -\@@_msg_new:nnn { Duplicate~name } - { - The~name~'\l_keys_value_tl'~is~already~used~and~you~shouldn't~use~ - the~same~environment~name~twice.~You~can~go~on,~but,~ - maybe,~you~will~have~incorrect~results~especially~ - if~you~use~'columns-width=auto'. \\ - For~a~list~of~the~names~already~used,~type~H~. \\ - If~you~don't~want~to~see~this~message~again,~use~the~option~ - 'allow-duplicate-names'. - } - { - The~names~already~defined~in~this~document~are:~ - \seq_use:Nnnn \g_@@_names_seq { ,~ } { ,~ } { ~and~ }. - } -% \end{macrocode} % % \bigskip % @@ -3050,37 +3012,6 @@ c & c & b & a & e } % \end{macrocode} % -% \begin{macrocode} -\@@_msg_new:nnn { Unknown~option~for~NiceArray } - { - The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~environment~ - \{NiceArray\}. \\ - If~you~go~on,~it~will~be~ignored. \\ - For~a~list~of~the~available~options,~type~H~. - } - { - The~available~options~are~(in~alphabetic~order):~ - b,~ - c,~ - code-after,~ - code-for-first-col,~ - code-for-first-row,~ - code-for-last-col,~ - code-for-last-row,~ - columns-width,~ - create-extra-nodes,~ - extra-left-margin,~ - extra-right-margin,~ - hlines,~ - left-margin,~ - name,~ - nullify-dots,~ - parallelize-diags,~ - renew-dots,~ - right-margin,~ - and~t. - } -% \end{macrocode} % % % \begin{macrocode} @@ -3096,48 +3027,15 @@ c & c & b & a & e % \end{macrocode} % % +% \subsection{Code common to \{NiceArrayWithDelims\} and \{NiceMatrix\}} +% +% The pseudo-environment |\@@_Cell:|--|\@@_end_Cell:| will be used to format the +% cells of the array. In the code, the affectations are global because this +% pseudo-environment will be used in the cells of a |\halign| (via an +% environment |{array}|). +% % \begin{macrocode} -\@@_msg_new:nnn { Unknown~option~for~pNiceArray } - { - The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~environment~ - \{\@currenvir\}. \\ - If~you~go~on,~it~will~be~ignored. \\ - For~a~list~of~the~available~options,~type~H~. - } - { - The~available~options~are~(in~alphabetic~order):~ - code-after,~ - code-for-first-col,~ - code-for-first-row,~ - code-for-last-col,~ - code-for-last-row,~ - columns-width,~ - create-extra-nodes,~ - extra-left-margin,~ - extra-right-margin,~ - first-col,~ - first-row,~ - last-col,~ - last-row,~ - hlines,~ - left-margin,~ - name,~ - nullify-dots,~ - parallelize-diags,~ - renew-dots,~ - and~right-margin. - } -% \end{macrocode} -% -% \subsection{Code common to \{NiceArrayWithDelims\} and \{NiceMatrix\}} -% -% The pseudo-environment |\@@_Cell:|--|\@@_end_Cell:| will be used to format the -% cells of the array. In the code, the affectations are global because this -% pseudo-environment will be used in the cells of a |\halign| (via an -% environment |{array}|). -% -% \begin{macrocode} -\cs_new_protected:Nn \@@_Cell: +\cs_new_protected:Nn \@@_Cell: { % \end{macrocode} % We increment |\g_@@_col_int|, which is the counter of the columns. @@ -3345,8 +3243,9 @@ c & c & b & a & e % \interitem % The argument of the following command |\@@_instruction_of_type:n| defined % below is the type of the instruction (|Cdots|, |Vdots|, |Ddots|, etc.). This -% command writes in |\g_@@_lines_to_draw_tl| the instruction that will really -% draw the line after the construction of the matrix. +% command writes in the correspondint |\g_@@_|\textsl{type}|_lines_tl| the +% instruction that will really draw the line after the construction of the +% matrix. % % \medskip % For example, for the following matrix, @@ -3356,22 +3255,22 @@ c & c & b & a & e % \begin{pNiceMatrix} % 1 & 2 & 3 & 4 \\ % 5 & \Cdots & & 6 \\ -% 7 & \Hdotsfor{2} \\ +% 7 & \Cdots \\ % \end{pNiceMatrix} % \end{BVerbatim} % $\begin{pNiceMatrix} % 1 & 2 & 3 & 4 \\ % 5 & \Cdots & & 6 \\ -% 7 & \Hdotsfor{2} \\ +% 7 & \Cdots \\ % \end{pNiceMatrix}$ % -% the content of |\g_@@_lines_to_draw_tl| will be: +% the content of |\g_@@_Cdots_lines_tl| will be: % % \begin{scope} % \color{gray} % \verb|\@@_draw_Cdots:nn {2}{2}| % -% \verb|\@@_draw_Hdotsfor:nnn {3}{2}{2}| +% \verb|\@@_draw_Cdots:nn {3}{2}| % \end{scope} % % @@ -3383,7 +3282,13 @@ c & c & b & a & e { \cs_new_protected:Npn \@@_instruction_of_type:n #1 { - \tl_gput_right:Nx \g_@@_lines_to_draw_tl +% \end{macrocode} +% It's important to use a |\tl_gput_right:cx| and not a |\tl_gput_left:cx| +% because we want the |\Ddots| lines to be drawn in the order of appearance +% in the array (for parallelisation). +% \begin{macrocode} + \tl_gput_right:cx + { g_@@_ #1 _ lines _ tl } { \use:c { @@ _ draw _ #1 : nn } { \int_use:N \g_@@_row_int } @@ -3511,7 +3416,7 @@ c & c & b & a & e \int_gset_eq:NN \g_@@_first_col_int \l_@@_first_col_int \bool_gset_eq:NN \g_@@_NiceArray_bool \l_@@_NiceArray_bool \bool_gset_eq:NN \g_@@_last_row_without_value_bool - \l_@@_last_row_without_value_bool + \l_@@_last_row_without_value_bool % \end{macrocode} % The environment |{array}| uses internally the command |\ialign| and, in % particular, this command |\ialign| sets |\everycr| to |{}|. However, we want @@ -3524,46 +3429,46 @@ c & c & b & a & e % environments that utilize |\ialign| internally (e.g.: |{substack}|)} % \begin{macrocode} \cs_set:Npn \ialign - { - \bool_if:NTF \c_@@_colortbl_loaded_bool - { - \CT@everycr - { - \noalign { \global\let\CT@row@color\relax } - \@@_everycr: - } + { + \bool_if:NTF \c_@@_colortbl_loaded_bool + { + \CT@everycr + { + \noalign { \cs_gset_eq:NN \CT@row@color \prg_do_nothing: } + \@@_everycr: + } + } + { \everycr { \@@_everycr: } } + \tabskip = \c_zero_skip + \cs_set:Npn \ialign + { + \everycr { } + \tabskip = \c_zero_skip + \halign } - { \everycr { \@@_everycr: } } - \tabskip = \c_zero_skip - \cs_set:Npn \ialign - { - \everycr { } - \tabskip = \c_zero_skip - \halign - } - \halign - } + \halign + } % \end{macrocode} % % We define the new column types |L|, |C| and |R| that must be used instead of % |l|, |c| and |r| in the preamble of |{NiceArray}|. % \begin{macrocode} \dim_compare:nNnTF \l_@@_columns_width_dim = \c_zero_dim - { - \newcolumntype L { > \@@_Cell: l < \@@_end_Cell: } - \newcolumntype C { > \@@_Cell: c < \@@_end_Cell: } - \newcolumntype R { > \@@_Cell: r < \@@_end_Cell: } - } + { + \newcolumntype L { > \@@_Cell: l < \@@_end_Cell: } + \newcolumntype C { > \@@_Cell: c < \@@_end_Cell: } + \newcolumntype R { > \@@_Cell: r < \@@_end_Cell: } + } % \end{macrocode} % If there is an option that specify that all the columns must have the same % width, the column types~|L|, |C| and~|R| are in fact defined upon the column % type~|w| of \pkg{array} which is, in fact, redefined below. % \begin{macrocode} - { - \newcolumntype L { w l { \dim_use:N \l_@@_columns_width_dim } } - \newcolumntype C { w c { \dim_use:N \l_@@_columns_width_dim } } - \newcolumntype R { w r { \dim_use:N \l_@@_columns_width_dim } } - } + { + \newcolumntype L { w l { \dim_use:N \l_@@_columns_width_dim } } + \newcolumntype C { w c { \dim_use:N \l_@@_columns_width_dim } } + \newcolumntype R { w r { \dim_use:N \l_@@_columns_width_dim } } + } % \end{macrocode} % % @@ -3577,6 +3482,7 @@ c & c & b & a & e \cs_set_eq:NN \Hspace \@@_Hspace: \cs_set_eq:NN \Hdotsfor \@@_Hdotsfor: \cs_set_eq:NN \multicolumn \@@_multicolumn:nnn + \cs_set_eq:NN \Block \@@_Block: \bool_if:NT \l_@@_renew_dots_bool { \cs_set_eq:NN \ldots \@@_Ldots @@ -3590,14 +3496,6 @@ c & c & b & a & e % \end{macrocode} % % -% The sequence |\g_@@_empty_cells_seq| will contain a list of ``empty'' cells -% (not all the empty cells of the matrix). If we want to indicate that the cell -% in row~$i$ and column~$j$ must be considered as empty, the token list -% ``|i-j|'' will be put in this sequence. -% \begin{macrocode} - \seq_gclear_new:N \g_@@_empty_cells_seq -% \end{macrocode} -% % The sequence |\g_@@_multicolumn_cells_seq| will contain the list of the cells % of the array where a command |\multicolumn{|$n$|}{...}{...}| with $n>1$ is % issued. In |\g_@@_multicolumn_sizes_seq|, the ``sizes'' (that is to say the @@ -3658,9 +3556,14 @@ c & c & b & a & e % |:|. However, this letter is used by some extensions, for example % \pkg{arydshln}. That's why it's possible to change the letter used by % \pkg{nicematrix} with the option |letter-for-dotted-lines| which changes the -% value of |\l_@@_letter_for_dotted_lines_str|. -% \begin{macrocode} - \exp_args:Nx \newcolumntype \l_@@_letter_for_dotted_lines_str +% value of |\l_@@_letter_for_dotted_lines_str|. We rescan this string (which is +% always of length~1) in particular for the case where |pdflatex| is used with +% \pkg{french-babel} (the colon is activated by \pkg{french-babel} at the +% beginning of the document). +% \begin{macrocode} + \tl_set_rescan:Nno + \l_@@_letter_for_dotted_lines_str { } \l_@@_letter_for_dotted_lines_str + \exp_args:NV \newcolumntype \l_@@_letter_for_dotted_lines_str { ! { @@ -3704,11 +3607,22 @@ c & c & b & a & e \bool_if:NT \c_@@_siunitx_loaded_bool \@@_renew_NC@rewrite@S: \int_gset:Nn \g_@@_last_vdotted_col_int { -1 } \bool_gset_false:N \g_@@_last_col_found_bool - } % \end{macrocode} % -% -% +% \medskip +% During the construction of the array, the instructions |\Cdots|, |\Ldots|, +% etc. will be written in token lists |\g_@@_Cdots_lines_tl|, etc. which will be +% executed after the construction of the array. +% \begin{macrocode} + \tl_gclear_new:N \g_@@_Cdots_lines_tl + \tl_gclear_new:N \g_@@_Ldots_lines_tl + \tl_gclear_new:N \g_@@_Vdots_lines_tl + \tl_gclear_new:N \g_@@_Ddots_lines_tl + \tl_gclear_new:N \g_@@_Iddots_lines_tl + \tl_gclear_new:N \g_@@_Hdotsfor_lines_tl + } +% \end{macrocode} +% % \bigskip % \subsection{The environment \{NiceArrayWithDelims\}} % @@ -3734,7 +3648,6 @@ c & c & b & a & e % why we use this technique in |{NiceArrayWithDelims}| and in |{NiceMatrix}|. % \begin{macrocode} \group_insert_after:N \@@_after_array: - \tl_gclear_new:N \g_@@_lines_to_draw_tl % \end{macrocode} % % We increment the counter |\g_@@_env_int| which counts the environments @@ -3815,7 +3728,7 @@ c & c & b & a & e \hbox_set:Nn \l_tmpa_box { \c_math_toggle_token - \left #1 \vcenter to 1 cm { } \right. + \left #1 \vcenter to 3 cm { } \right. \c_math_toggle_token } @@ -3824,7 +3737,7 @@ c & c & b & a & e { \dim_set_eq:NN \nulldelimiterspace \c_zero_dim \c_math_toggle_token - \left. \vcenter to 1 cm { } \right #2 + \left. \vcenter to 3 cm { } \right #2 \c_math_toggle_token } \dim_gset:Nn \g_@@_right_delim_dim { \box_wd:N \l_tmpa_box } @@ -3889,6 +3802,24 @@ c & c & b & a & e \skip_horizontal:n \g_@@_extra_right_margin_dim \hbox_set_end: % \end{macrocode} +% +% \bigskip +% +% \begin{macrocode} + \int_compare:nNnT \g_@@_last_row_int > { -2 } + { + \bool_if:NF \g_@@_last_row_without_value_bool + { + \int_compare:nNnF \g_@@_last_row_int = \g_@@_row_int + { + \@@_error:n { Wrong~last~row } + \int_gset_eq:NN \g_@@_last_row_int \g_@@_row_int + } + } + } +% \end{macrocode} +% +% % Now, we compute |\l_tmpa_dim| which is the vertical dimension of the ``first % row'' above the array (when the key |first-row| is used). % \begin{macrocode} @@ -4119,7 +4050,7 @@ c & c & b & a & e { % \end{macrocode} % With the flag |\g_@@_last_col_found_bool|, we will know that the ``last -% column'' i s really used. +% column'' is really used. % \begin{macrocode} \bool_gset_true:N \g_@@_last_col_found_bool \int_gincr:N \g_@@_col_int @@ -4300,7 +4231,6 @@ c & c & b & a & e % same as in |{array}| (for the option |renew-matrix|). % \begin{macrocode} \group_insert_after:N \@@_after_array: - \tl_gclear_new:N \g_@@_lines_to_draw_tl \int_gincr:N \g_@@_env_int \bool_if:NF \l_@@_block_auto_columns_width_bool { \dim_gzero_new:N \g_@@_max_cell_width_dim } @@ -4425,46 +4355,93 @@ c & c & b & a & e % considered cell. % \begin{macrocode} \prg_set_conditional:Npnn \@@_if_not_empty_cell:nn #1 #2 { T , TF } -% \end{macrocode} -% If the cell is an implicit cell (that is after the symbol |\\| of end of row), -% the cell must, of course, be considered as empty. It's easy to check whether we -% are in this situation considering the correspondant Tikz node. -% \begin{macrocode} { - \cs_if_free:cTF - { pgf@sh@ns@nm -\int_use:N \g_@@_env_int - \int_use:N #1 - \int_use:N #2 } - \prg_return_false: % \end{macrocode} -% We manage a list of ``empty cells'' called |\g_@@_empty_cells_seq|. In fact, -% this list is not a list of all the empty cells of the array but only those -% explicitly declared empty for some reason. It's easy to check if the current -% cell is in this list. +% First, we want to test whether the cell is in the virtual sequence of +% ``non-empty'' cells. There are several important remarks: +% \begin{itemize} +% \item we don't use a |expl3| sequence for efficiency ; +% \item the ``non-empty'' cells in this sequence are not, in fact, all the +% non-empty cells of the array: on the contrary they are only cells declared +% as non-empty for a special reason (as of now, there are only cells which are +% on a dotted line which is already drawn or which will be drawn ``just after'') ; +% \item the flag |\l_tmpa_bool| will be raised when the cell is actually on +% this virtual sequence. +% \end{itemize} % \begin{macrocode} + \bool_set_false:N \l_tmpa_bool + \cs_if_exist:cTF + { @@ _ dotted _ \int_use:N #1 - \int_use:N #2 } + \prg_return_true: { - \seq_if_in:NxTF \g_@@_empty_cells_seq { \int_use:N #1 - \int_use:N #2 } - \prg_return_false: +% \end{macrocode} +% We know that the cell is not in the virtual sequence of the ``non-empty'' +% cells. Now, we test wether the cell is a ``virtual cell'', that is to say a +% cell after the |\\| of the line of the array. It's easy to known whether a +% cell is vitual: the cell is virtual if, and only if, the corresponding Tikz +% node doesn't exist. +% \begin{macrocode} + \cs_if_free:cTF + { + pgf@sh@ns@nm - + \int_use:N \g_@@_env_int - + \int_use:N #1 - + \int_use:N #2 + } + { \prg_return_false: } + { +% \end{macrocode} +% Now, we want to test whether the cell is in the virtual sequence of +% ``empty'' cells. There are several important remarks: +% \begin{itemize} +% \item we don't use a |expl3| sequence for efficiency ; +% \item the ``empty'' cells in this sequence are not, in fact, all the +% non-empty cells of the array: on the contrary they are only cells declared +% as non-empty for a special reason ; +% \item the flag |\l_tmpa_bool| will be raised when the cell is actually on +% this virtual sequence. +% \end{itemize} +% \begin{macrocode} + \bool_set_false:N \l_tmpa_bool + \cs_if_exist:cT + { @@ _ empty _ \int_use:N #1 - \int_use:N #2 } + { + \int_compare:nNnT + { \use:c { @@ _ empty _ \int_use:N #1 - \int_use:N #2 } } + = + \g_@@_env_int + { \bool_set_true:N \l_tmpa_bool } + } + \bool_if:NTF \l_tmpa_bool + \prg_return_false: % \end{macrocode} % In the general case, we consider the width of the Tikz node corresponding to % the cell. In order to compute this width, we have to extract the coordinate of % the west and east anchors of the node. This extraction needs a command % environment |{pgfpicture}| but, in fact, nothing is drawn. % \begin{macrocode} - { - \begin { pgfpicture } + { + \begin { pgfpicture } % \end{macrocode} % We store the name of the node corresponding to the cell in |\l_tmpa_tl|. % \begin{macrocode} - \tl_set:Nx \l_tmpa_tl - { nm - \int_use:N \g_@@_env_int - \int_use:N #1 - \int_use:N #2 } - \pgfpointanchor \l_tmpa_tl { east } - \dim_gset:Nn \g_tmpa_dim \pgf@x - \pgfpointanchor \l_tmpa_tl { west } - \dim_gset:Nn \g_tmpb_dim \pgf@x - \end { pgfpicture } - \dim_compare:nNnTF - { \dim_abs:n { \g_tmpb_dim - \g_tmpa_dim } } < { 0.5 pt } - \prg_return_false: - \prg_return_true: + \tl_set:Nx \l_tmpa_tl + { + nm - + \int_use:N \g_@@_env_int - + \int_use:N #1 - + \int_use:N #2 + } + \pgfpointanchor \l_tmpa_tl { east } + \dim_gset:Nn \g_tmpa_dim \pgf@x + \pgfpointanchor \l_tmpa_tl { west } + \dim_gset:Nn \g_tmpb_dim \pgf@x + \end { pgfpicture } + \dim_compare:nNnTF + { \dim_abs:n { \g_tmpb_dim - \g_tmpa_dim } } < { 0.5 pt } + \prg_return_false: + \prg_return_true: + } } } } @@ -4486,15 +4463,6 @@ c & c & b & a & e } % \end{macrocode} % -% \begin{macrocode} -\@@_msg_new:nn { Zero~row } - { - There~is~a~problem.~Maybe~your~environment~\{\@currenvir\}~is~empty.~ - Maybe~you~have~used~l,~c~and~r~instead~of~L,~C~and~R~in~the~preamble~ - of~your~environment. \\ - If~you~go~on,~the~result~may~be~incorrect. - } -% \end{macrocode} % % \medskip % We deactivate Tikz externalization (since we use Tikz pictures with the @@ -4552,12 +4520,6 @@ c & c & b & a & e } % \end{macrocode} % -% The sequence |\g_@@_yet_drawn_seq| contains a list of lines which have been -% drawn previously in the matrix. We maintain this sequence because we don't -% want to draw two overlapping lines. -% \begin{macrocode} - \seq_gclear_new:N \g_@@_yet_drawn_seq -% \end{macrocode} % % By default, the diagonal lines will be parallelized\footnote{It's possible to % use the option |parallelize-diags| to disable this parallelization.}. There @@ -4591,23 +4553,24 @@ c & c & b & a & e % group). % \begin{macrocode} \bool_if:NT \g_@@_extra_nodes_bool \@@_create_extra_nodes: + \int_zero_new:N \l_@@_initial_i_int + \int_zero_new:N \l_@@_initial_j_int + \int_zero_new:N \l_@@_final_i_int + \int_zero_new:N \l_@@_final_j_int + \bool_set_false:N \l_@@_initial_open_bool + \bool_set_false:N \l_@@_final_open_bool % \end{macrocode} -% +% % \bigskip % Now, we really draw the lines. The code to draw the lines has been constructed -% in the token list |\g_@@_lines_to_draw_tl|. +% in the token lists |\g_@@_Vdots_lines_tl|, etc. % \begin{macrocode} - \tl_if_empty:NF \g_@@_lines_to_draw_tl - { - \int_zero_new:N \l_@@_initial_i_int - \int_zero_new:N \l_@@_initial_j_int - \int_zero_new:N \l_@@_final_i_int - \int_zero_new:N \l_@@_final_j_int - \bool_set_false:N \l_@@_initial_open_bool - \bool_set_false:N \l_@@_final_open_bool - \g_@@_lines_to_draw_tl - } - \tl_gclear:N \g_@@_lines_to_draw_tl + \g_@@_Hdotsfor_lines_tl + \g_@@_Vdots_lines_tl + \g_@@_Ddots_lines_tl + \g_@@_Iddots_lines_tl + \g_@@_Cdots_lines_tl + \g_@@_Ldots_lines_tl % \end{macrocode} % % \bigskip @@ -4680,6 +4643,14 @@ c & c & b & a & e % \begin{macrocode} \cs_new_protected:Nn \@@_find_extremities_of_line:nnnn { +% \end{macrocode} +% First, we declare the current cell as ``dotted'' because we forbide +% intersections of dotted lines. +% \begin{macrocode} + \cs_set:cpn { @@ _ dotted _ #1 - #2 } { } +% \end{macrocode} +% Initialisation of variables. +% \begin{macrocode} \int_set:Nn \l_@@_initial_i_int { #1 } \int_set:Nn \l_@@_initial_j_int { #2 } \int_set:Nn \l_@@_final_i_int { #1 } @@ -4732,13 +4703,50 @@ c & c & b & a & e \bool_set_true:N \l_@@_stop_loop_bool } % \end{macrocode} -% If we are in the matrix, we test if the cell is empty. If it's not the case, -% we stop the loop because we have found the correct values for +% If we are in the matrix, we test whether the cell is empty. If it's not the +% case, we stop the loop because we have found the correct values for % |\l_@@_final_i_int| and |\l_@@_final_j_int|. % \begin{macrocode} { - \@@_if_not_empty_cell:nnT \l_@@_final_i_int \l_@@_final_j_int + \@@_if_not_empty_cell:nnTF \l_@@_final_i_int \l_@@_final_j_int { \bool_set_true:N \l_@@_stop_loop_bool } +% \end{macrocode} +% If the case is empty, we declare that the cell as non-empty. Indeed, we will +% draw a dotted line and the cell will be on that dotted line. All the cells of +% a dotted line have to be mark as ``dotted'' because we don't want +% intersections between dotted lines. +% \begin{macrocode} + { + \cs_set:cpn + { + @@ _ dotted _ + \int_use:N \l_@@_final_i_int - + \int_use:N \l_@@_final_j_int + } + { } + } + } + } +% \end{macrocode} +% We test wether the initial extremity of the dotted line is an implicit cell +% already dotted (by another dotted line). In this case, we can't draw the line +% because we have no Tikz node at the extremity of the arrow (and we can't use +% the ``medium node'' or the ``large node'' because we should use the normal +% node since the extremity is not open). +% \begin{macrocode} + \cs_if_free:cT + { + pgf@sh@ns@nm - + \int_use:N \g_@@_env_int - + \int_use:N \l_@@_final_i_int - + \int_use:N \l_@@_final_j_int + } + { + \bool_if:NF \l_@@_final_open_bool + { + \msg_error:nnx { nicematrix } { Impossible~line } + { \int_use:N \l_@@_final_i_int } + \bool_set_true:N \l_@@_impossible_line_bool } } % \end{macrocode} @@ -4779,9 +4787,40 @@ c & c & b & a & e \bool_set_true:N \l_@@_stop_loop_bool } { - \@@_if_not_empty_cell:nnT + \@@_if_not_empty_cell:nnTF \l_@@_initial_i_int \l_@@_initial_j_int { \bool_set_true:N \l_@@_stop_loop_bool } + { + \cs_set:cpn + { + @@ _ dotted _ + \int_use:N \l_@@_initial_i_int - + \int_use:N \l_@@_initial_j_int + } + { } + } + } + } +% \end{macrocode} +% We test wether the initial extremity of the dotted line is an implicit cell +% already dotted (by another dotted line). In this case, we can't draw the line +% because we have no Tikz node at the extremity of the arrow (and we can't use +% the ``medium node'' or the ``large node'' because we should use the normal +% node since the extremity is not open). +% \begin{macrocode} + \cs_if_free:cT + { + pgf@sh@ns@nm - + \int_use:N \g_@@_env_int - + \int_use:N \l_@@_initial_i_int - + \int_use:N \l_@@_initial_j_int + } + { + \bool_if:NF \l_@@_initial_open_bool + { + \msg_error:nnx { nicematrix } { Impossible~line } + { \int_use:N \l_@@_initial_i_int } + \bool_set_true:N \l_@@_impossible_line_bool } } % \end{macrocode} @@ -4791,40 +4830,12 @@ c & c & b & a & e % ``medium node''.}. We remind that, when used once, the command % |\@@_create_extra_nodes:| becomes no-op in the current TeX group. % \begin{macrocode} - \bool_if:nT { \l_@@_initial_open_bool || \l_@@_final_open_bool } - \@@_create_extra_nodes: - } -% \end{macrocode} -% -% \interitem -% If the dotted line to draw is in the list of the previously drawn lines -% (|\g_@@_yet_drawn_seq|), we don't draw (so, we won't have overlapping lines in -% the \textsc{pdf}). The token list |\l_tmpa_tl| is the $4$-list characteristic -% of the line. -% \begin{macrocode} -\prg_set_conditional:Npnn \@@_if_yet_drawn: { F } - { - \tl_set:Nx \l_tmpa_tl - { - \int_use:N \l_@@_initial_i_int - - \int_use:N \l_@@_initial_j_int - - \int_use:N \l_@@_final_i_int - - \int_use:N \l_@@_final_j_int - } - \seq_if_in:NVTF \g_@@_yet_drawn_seq \l_tmpa_tl -% \end{macrocode} -% -% If the dotted line to draw is not in the list, we add it to the list -% |\g_@@_yet_drawn_seq|. -% \begin{macrocode} - \prg_return_true: - { - \seq_gput_left:NV \g_@@_yet_drawn_seq \l_tmpa_tl - \prg_return_false: - } + \bool_if:nT \l_@@_initial_open_bool \@@_create_extra_nodes: + \bool_if:NT \l_@@_final_open_bool \@@_create_extra_nodes: } % \end{macrocode} % +% % % \interitem % The command |\@@_retrieve_coords:nn| retrieves the Tikz coordinates of the two @@ -4870,8 +4881,12 @@ c & c & b & a & e % \begin{macrocode} \cs_new_protected:Nn \@@_draw_Ldots:nn { - \@@_find_extremities_of_line:nnnn { #1 } { #2 } \c_zero_int \c_one_int - \@@_if_yet_drawn:F \@@_actually_draw_Ldots: + \cs_if_free:cT { @@ _ dotted _ #1 - #2 } + { + \bool_set_false:N \l_@@_impossible_line_bool + \@@_find_extremities_of_line:nnnn { #1 } { #2 } \c_zero_int \c_one_int + \bool_if:NF \l_@@_impossible_line_bool \@@_actually_draw_Ldots: + } } % \end{macrocode} % @@ -4883,41 +4898,41 @@ c & c & b & a & e % \begin{macrocode} \cs_new_protected:Nn \@@_actually_draw_Ldots: { - \@@_retrieve_coords:xx - { - \bool_if:NTF \l_@@_initial_open_bool - { + \@@_retrieve_coords:xx + { + \bool_if:NTF \l_@@_initial_open_bool + { % \end{macrocode} % If a |w| node exists (created when the key |columns-width| is used), we use % the |w| node for the extremity. % \begin{macrocode} - \cs_if_exist:cTF - { - pgf@sh@ns@nm - - \int_use:N \g_@@_env_int - - \int_use:N \l_@@_initial_i_int - - \int_use:N \l_@@_initial_j_int - w - } - { - w.base~west } - { - medium.base~west } - } - { .base~east } - } + \cs_if_exist:cTF + { + pgf@sh@ns@nm + - \int_use:N \g_@@_env_int + - \int_use:N \l_@@_initial_i_int + - \int_use:N \l_@@_initial_j_int - w + } + { - w.base~west } + { - medium.base~west } + } + { .base~east } + } + { + \bool_if:NTF \l_@@_final_open_bool { - \bool_if:NTF \l_@@_final_open_bool - { - \cs_if_exist:cTF - { - pgf@sh@ns@nm - - \int_use:N \g_@@_env_int - - \int_use:N \l_@@_final_i_int - - \int_use:N \l_@@_final_j_int - w - } - { - w.base~east } - { - medium.base~east } + \cs_if_exist:cTF + { + pgf@sh@ns@nm + - \int_use:N \g_@@_env_int + - \int_use:N \l_@@_final_i_int + - \int_use:N \l_@@_final_j_int - w } - { .base~west } + { - w.base~east } + { - medium.base~east } } + { .base~west } + } \bool_if:NT \l_@@_initial_open_bool { \dim_gset_eq:NN \g_@@_y_initial_dim \g_@@_y_final_dim } \bool_if:NT \l_@@_final_open_bool @@ -4936,45 +4951,49 @@ c & c & b & a & e % \begin{macrocode} \cs_new_protected:Nn \@@_draw_Cdots:nn { - \@@_find_extremities_of_line:nnnn { #1 } { #2 } \c_zero_int \c_one_int - \@@_if_yet_drawn:F - { - \@@_retrieve_coords:xx - { - \bool_if:NTF \l_@@_initial_open_bool - { - \cs_if_exist:cTF - { - pgf@sh@ns@nm - - \int_use:N \g_@@_env_int - - \int_use:N \l_@@_initial_i_int - - \int_use:N \l_@@_initial_j_int - w + \cs_if_free:cT { @@ _ dotted _ #1 - #2 } + { + \bool_set_false:N \l_@@_impossible_line_bool + \@@_find_extremities_of_line:nnnn { #1 } { #2 } \c_zero_int \c_one_int + \bool_if:NF \l_@@_impossible_line_bool + { + \@@_retrieve_coords:xx + { + \bool_if:NTF \l_@@_initial_open_bool + { + \cs_if_exist:cTF + { + pgf@sh@ns@nm + - \int_use:N \g_@@_env_int + - \int_use:N \l_@@_initial_i_int + - \int_use:N \l_@@_initial_j_int - w + } + { - w.mid~west } + { - medium.mid~west } } - { - w.mid~west } - { - medium.mid~west } + { .mid~east } } - { .mid~east } - } - { - \bool_if:NTF \l_@@_final_open_bool { - \cs_if_exist:cTF - { - pgf@sh@ns@nm - - \int_use:N \g_@@_env_int - - \int_use:N \l_@@_final_i_int - - \int_use:N \l_@@_final_j_int - w + \bool_if:NTF \l_@@_final_open_bool + { + \cs_if_exist:cTF + { + pgf@sh@ns@nm + - \int_use:N \g_@@_env_int + - \int_use:N \l_@@_final_i_int + - \int_use:N \l_@@_final_j_int - w + } + { - w.mid~east } + { - medium.mid~east } } - { - w.mid~east } - { - medium.mid~east } + { .mid~west } } - { .mid~west } + \bool_if:NT \l_@@_initial_open_bool + { \dim_gset_eq:NN \g_@@_y_initial_dim \g_@@_y_final_dim } + \bool_if:NT \l_@@_final_open_bool + { \dim_gset_eq:NN \g_@@_y_final_dim \g_@@_y_initial_dim } + \@@_draw_tikz_line: } - \bool_if:NT \l_@@_initial_open_bool - { \dim_gset_eq:NN \g_@@_y_initial_dim \g_@@_y_final_dim } - \bool_if:NT \l_@@_final_open_bool - { \dim_gset_eq:NN \g_@@_y_final_dim \g_@@_y_initial_dim } - \@@_draw_tikz_line: } } % \end{macrocode} @@ -4987,52 +5006,57 @@ c & c & b & a & e % \begin{macrocode} \cs_new_protected:Nn \@@_draw_Vdots:nn { - \@@_find_extremities_of_line:nnnn { #1 } { #2 } \c_one_int \c_zero_int - \@@_if_yet_drawn:F - { \@@_retrieve_coords:xx - { - \bool_if:NTF \l_@@_initial_open_bool - { - medium.north~west } - { .south~west } - } - { - \bool_if:NTF \l_@@_final_open_bool - { - medium.south~west } - { .north~west } - } + \cs_if_free:cT { @@ _ dotted _ #1 - #2 } + { + \bool_set_false:N \l_@@_impossible_line_bool + \@@_find_extremities_of_line:nnnn { #1 } { #2 } \c_one_int \c_zero_int + \bool_if:NF \l_@@_impossible_line_bool + { + \@@_retrieve_coords:xx + { + \bool_if:NTF \l_@@_initial_open_bool + { - medium.north~west } + { .south~west } + } + { + \bool_if:NTF \l_@@_final_open_bool + { - medium.south~west } + { .north~west } + } % \end{macrocode} % The boolean |\l_tmpa_bool| indicates whether the column is of type |l| (|L| of % |{NiceArray}|) or may be considered as if. % \begin{macrocode} - \bool_set:Nn \l_tmpa_bool - { \dim_compare_p:nNn \g_@@_x_initial_dim = \g_@@_x_final_dim } - \@@_retrieve_coords:xx - { - \bool_if:NTF \l_@@_initial_open_bool - { - medium.north } - { .south } - } - { - \bool_if:NTF \l_@@_final_open_bool - { - medium.south } - { .north } - } + \bool_set:Nn \l_tmpa_bool + { \dim_compare_p:nNn \g_@@_x_initial_dim = \g_@@_x_final_dim } + \@@_retrieve_coords:xx + { + \bool_if:NTF \l_@@_initial_open_bool + { - medium.north } + { .south } + } + { + \bool_if:NTF \l_@@_final_open_bool + { - medium.south } + { .north } + } % \end{macrocode} % The boolean |\l_tmpb_bool| indicates whether the column is of type |c| (|C| of % |{NiceArray}|) or may be considered as if. % \begin{macrocode} - \bool_set:Nn \l_tmpb_bool - { \dim_compare_p:nNn \g_@@_x_initial_dim = \g_@@_x_final_dim } - \bool_if:NF \l_tmpb_bool - { - \dim_gset:Nn \g_@@_x_initial_dim + \bool_set:Nn \l_tmpb_bool + { \dim_compare_p:nNn \g_@@_x_initial_dim = \g_@@_x_final_dim } + \bool_if:NF \l_tmpb_bool { - \bool_if:NTF \l_tmpa_bool \dim_min:nn \dim_max:nn - \g_@@_x_initial_dim \g_@@_x_final_dim + \dim_gset:Nn \g_@@_x_initial_dim + { + \bool_if:NTF \l_tmpa_bool \dim_min:nn \dim_max:nn + \g_@@_x_initial_dim \g_@@_x_final_dim + } + \dim_gset_eq:NN \g_@@_x_final_dim \g_@@_x_initial_dim } - \dim_gset_eq:NN \g_@@_x_final_dim \g_@@_x_initial_dim + \@@_draw_tikz_line: } - \@@_draw_tikz_line: } } % \end{macrocode} @@ -5044,63 +5068,67 @@ c & c & b & a & e % \begin{macrocode} \cs_new_protected:Nn \@@_draw_Ddots:nn { - \@@_find_extremities_of_line:nnnn { #1 } { #2 } \c_one_int \c_one_int - \@@_if_yet_drawn:F + \cs_if_free:cT { @@ _ dotted _ #1 - #2 } { - \@@_retrieve_coords:xx - { - \bool_if:NTF \l_@@_initial_open_bool - { - medium.north~west } - { .south~east } - } - { - \bool_if:NTF \l_@@_final_open_bool - { - medium.south~east } - { .north~west } - } + \bool_set_false:N \l_@@_impossible_line_bool + \@@_find_extremities_of_line:nnnn { #1 } { #2 } \c_one_int \c_one_int + \bool_if:NF \l_@@_impossible_line_bool + { + \@@_retrieve_coords:xx + { + \bool_if:NTF \l_@@_initial_open_bool + { - medium.north~west } + { .south~east } + } + { + \bool_if:NTF \l_@@_final_open_bool + { - medium.south~east } + { .north~west } + } % \end{macrocode} % We have retrieved the coordinates in the usual way (they are stored in % |\g_@@_x_initial_dim|, etc.). If the parallelization of the diagonals is set, % we will have (maybe) to adjust the fourth coordinate. % \begin{macrocode} - \bool_if:NT \l_@@_parallelize_diags_bool - { - \int_incr:N \l_@@_ddots_int + \bool_if:NT \l_@@_parallelize_diags_bool + { + \int_incr:N \l_@@_ddots_int % \end{macrocode} % We test if the diagonal line is the first one (the counter |\l_@@_ddots_int| % is created for this usage). % \begin{macrocode} - \int_compare:nNnTF \l_@@_ddots_int = \c_one_int + \int_compare:nNnTF \l_@@_ddots_int = \c_one_int % \end{macrocode} % If the diagonal line is the first one, we have no adjustment of the line to do % but we store the $\Delta_x$ and the $\Delta_y$ of the line because these % values will be used to draw the others diagonal lines parallels to the first % one. % \begin{macrocode} - { - \dim_set:Nn \l_@@_delta_x_one_dim - { \g_@@_x_final_dim - \g_@@_x_initial_dim } - \dim_set:Nn \l_@@_delta_y_one_dim - { \g_@@_y_final_dim - \g_@@_y_initial_dim } - } + { + \dim_set:Nn \l_@@_delta_x_one_dim + { \g_@@_x_final_dim - \g_@@_x_initial_dim } + \dim_set:Nn \l_@@_delta_y_one_dim + { \g_@@_y_final_dim - \g_@@_y_initial_dim } + } % \end{macrocode} % If the diagonal line is not the first one, we have to adjust the second % extremity of the line by modifying the coordinate |\g_@@_y_initial_dim|. % \begin{macrocode} - { - \dim_gset:Nn \g_@@_y_final_dim { - \g_@@_y_initial_dim + - ( \g_@@_x_final_dim - \g_@@_x_initial_dim ) * - \dim_ratio:nn \l_@@_delta_y_one_dim \l_@@_delta_x_one_dim + \dim_gset:Nn \g_@@_y_final_dim + { + \g_@@_y_initial_dim + + ( \g_@@_x_final_dim - \g_@@_x_initial_dim ) * + \dim_ratio:nn \l_@@_delta_y_one_dim \l_@@_delta_x_one_dim + } } } - } % \end{macrocode} % Now, we can draw the dotted line (after a possible change of % |\g_@@_y_initial_dim|). % \begin{macrocode} - \@@_draw_tikz_line: + \@@_draw_tikz_line: + } } } % \end{macrocode} @@ -5110,39 +5138,44 @@ c & c & b & a & e % \begin{macrocode} \cs_new_protected:Nn \@@_draw_Iddots:nn { - \@@_find_extremities_of_line:nnnn { #1 } { #2 } 1 { -1 } - \@@_if_yet_drawn:F - { \@@_retrieve_coords:xx - { - \bool_if:NTF \l_@@_initial_open_bool - { - medium.north~east } - { .south~west } - } - { - \bool_if:NTF \l_@@_final_open_bool - { - medium.south~west } - { .north~east } - } - \bool_if:NT \l_@@_parallelize_diags_bool - { - \int_incr:N \l_@@_iddots_int - \int_compare:nNnTF \l_@@_iddots_int = \c_one_int + \cs_if_free:cT { @@ _ dotted _ #1 - #2 } + { + \bool_set_false:N \l_@@_impossible_line_bool + \@@_find_extremities_of_line:nnnn { #1 } { #2 } 1 { -1 } + \bool_if:NF \l_@@_impossible_line_bool + { + \@@_retrieve_coords:xx { - \dim_set:Nn \l_@@_delta_x_two_dim - { \g_@@_x_final_dim - \g_@@_x_initial_dim } - \dim_set:Nn \l_@@_delta_y_two_dim - { \g_@@_y_final_dim - \g_@@_y_initial_dim } + \bool_if:NTF \l_@@_initial_open_bool + { - medium.north~east } + { .south~west } + } + { + \bool_if:NTF \l_@@_final_open_bool + { - medium.south~west } + { .north~east } } + \bool_if:NT \l_@@_parallelize_diags_bool { - \dim_gset:Nn \g_@@_y_final_dim - { - \g_@@_y_initial_dim + - ( \g_@@_x_final_dim - \g_@@_x_initial_dim ) * - \dim_ratio:nn \l_@@_delta_y_two_dim \l_@@_delta_x_two_dim - } + \int_incr:N \l_@@_iddots_int + \int_compare:nNnTF \l_@@_iddots_int = \c_one_int + { + \dim_set:Nn \l_@@_delta_x_two_dim + { \g_@@_x_final_dim - \g_@@_x_initial_dim } + \dim_set:Nn \l_@@_delta_y_two_dim + { \g_@@_y_final_dim - \g_@@_y_initial_dim } + } + { + \dim_gset:Nn \g_@@_y_final_dim + { + \g_@@_y_initial_dim + + ( \g_@@_x_final_dim - \g_@@_x_initial_dim ) * + \dim_ratio:nn \l_@@_delta_y_two_dim \l_@@_delta_x_two_dim + } + } } + \@@_draw_tikz_line: } - \@@_draw_tikz_line: } } % \end{macrocode} @@ -5300,8 +5333,9 @@ c & c & b & a & e % \begin{macrocode} \cs_new_protected:Nn \@@_add_to_empty_cells: { - \seq_gput_right:Nx \g_@@_empty_cells_seq - { \int_use:N \g_@@_row_int - \int_use:N \g_@@_col_int } + \cs_gset:cpx + { @@ _ empty _ \int_use:N \g_@@_row_int - \int_use:N \g_@@_col_int } + { \int_use:N \g_@@_env_int } } % \end{macrocode} % @@ -5310,6 +5344,9 @@ c & c & b & a & e % |\@@_Iddots| will be linked to |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots| and % |\Iddots| in the environments |{NiceArray}| (the other environments of % \pkg{nicematrix} rely upon |{NiceArray}|). +% +% The starred versions of these commands are deprecated since version~3.1 but +% they are still available. % \begin{macrocode} \NewDocumentCommand \@@_Ldots { s } { @@ -5409,20 +5446,18 @@ c & c & b & a & e % % The command |\@@_Hdotsfor_i| is defined with the tools of \pkg{xparse} because % it has an optionnal argument. Note that such a command defined by -% |\multicolumn| is protected and that's why we have put the |\multicolumn| -% before (in the definition of |\@@_Hdotsfor:|). +% |\NewDocumentCommand| is protected and that's why we have put the +% |\multicolumn| before (in the definition of |\@@_Hdotsfor:|). % \begin{macrocode} \bool_if:NTF \c_@@_draft_bool { \NewDocumentCommand \@@_Hdotsfor_i { O { } m } - { - \prg_replicate:nn { #2 - 1 } { & \multicolumn { 1 } { C } { } } - } + { \prg_replicate:nn { #2 - 1 } { & \multicolumn { 1 } { C } { } } } } { \NewDocumentCommand \@@_Hdotsfor_i { O { } m } { - \tl_gput_right:Nx \g_@@_lines_to_draw_tl + \tl_gput_right:Nx \g_@@_Hdotsfor_lines_tl { \@@_draw_Hdotsfor:nnn { \int_use:N \g_@@_row_int } @@ -5479,6 +5514,14 @@ c & c & b & a & e \bool_if:nT { \l_@@_initial_open_bool || \l_@@_final_open_bool } \@@_create_extra_nodes: \@@_actually_draw_Ldots: +% \end{macrocode} +% We declare all the cells concerned by the |\Hdotsfor| as ``dotted'' (for the +% dotted lines created by |\Cdots|, |\Ldots|, etc., this job is done by +% |\@@_find_extremities_of_line:nnnn|). This declaration is done by defining a +% special control sequence (to nil). +% \begin{macrocode} + \int_step_inline:nnn { #2 } { #2 + #3 - 1 } + { \cs_set:cpn { @@ _ dotted _ #1 - ##1 } { } } } % \end{macrocode} % @@ -5643,14 +5686,6 @@ c & c & b & a & e % \end{macrocode} % % -% \begin{macrocode} -\@@_msg_new:nn { Use~of~:~in~first~position } - { - You~can't~use~the~column~specifier~"\l_@@_letter_for_dotted_lines_str"~in~the~ - first~position~of~the~preamble~of~the~environment~\{\@currenvir\}. \\ - If~you~go~on,~this~dotted~line~will~be~ignored. - } -% \end{macrocode} % % \bigskip % \subsection{The vertical rules} @@ -5688,19 +5723,24 @@ c & c & b & a & e { \int_compare:nNnF \g_@@_row_int = \c_zero_int { - \int_compare:nNnF \g_@@_row_int = \l_@@_last_row_int \vline + \int_compare:nNnF \g_@@_row_int = \l_@@_last_row_int + \@@_vline_i: } } { \int_compare:nNnF \g_@@_row_int = \c_zero_int { - \int_compare:nNnF \g_@@_row_int = \l_@@_last_row_int \vline + \int_compare:nNnF \g_@@_row_int = \l_@@_last_row_int + \@@_vline_i: } } } { \int_compare:nNnF \g_@@_row_int = \c_zero_int - { \int_compare:nNnF \g_@@_row_int = \l_@@_last_row_int \vline } + { + \int_compare:nNnF \g_@@_row_int = \l_@@_last_row_int + \@@_vline_i: + } } } { @@ -5709,19 +5749,29 @@ c & c & b & a & e \int_compare:nNnF \g_@@_row_int = { -1 } { \int_compare:nNnF \g_@@_row_int = { \l_@@_last_row_int - 1 } - \vline + \@@_vline_i: } } { \int_compare:nNnF \g_@@_row_int = \c_zero_int - { \int_compare:nNnF \g_@@_row_int = \l_@@_last_row_int \vline } + { + \int_compare:nNnF \g_@@_row_int = \l_@@_last_row_int + \@@_vline_i: + } } } } % \end{macrocode} -% -% % +% \medskip +% If \pkg{colortbl} is loaded, the following macro will redefined (in a +% |\AtBeginDocument|) to take into account the color fixed by |\arrayrulecolor| +% of \pkg{colortbl}. +% \begin{macrocode} +\cs_set_eq:NN \@@_vline_i: \vline +% \end{macrocode} +% +% \bigskip % \subsection{The environment \{NiceMatrixBlock\}} % % The following flag will be raised when all the columns of the environments of @@ -5787,6 +5837,9 @@ c & c & b & a & e \cs_generate_variant:Nn \dim_max:nn { v n } % \end{macrocode} % +% \bigskip +% The macro |\@@_create_extra_nodes:| must \emph{not} be used in the +% |code-after| because the |code-after| is executed in a scope of |prefix name|. % % % \bigskip @@ -5944,13 +5997,13 @@ c & c & b & a & e % We can now compute the width of the array (used by |\hdottedline|). % \begin{macrocode} \begin { tikzpicture } [ remember~picture , overlay ] - \tikz@parse@node \pgfutil@firstofone - ( nm - \int_use:N \g_@@_env_int - 1 - 1 - large .north~west ) - \dim_gset:Nn \g_tmpa_dim \pgf@x - \tikz@parse@node \pgfutil@firstofone - ( nm - \int_use:N \g_@@_env_int - 1 - - \int_use:N \g_@@_col_int - large .north~east ) - \dim_gset:Nn \g_tmpb_dim \pgf@x + \tikz@parse@node \pgfutil@firstofone + ( nm - \int_use:N \g_@@_env_int - 1 - 1 - large .north~west ) + \dim_gset:Nn \g_tmpa_dim \pgf@x + \tikz@parse@node \pgfutil@firstofone + ( nm - \int_use:N \g_@@_env_int - 1 - + \int_use:N \g_@@_col_int - large .north~east ) + \dim_gset:Nn \g_tmpb_dim \pgf@x \end { tikzpicture } \iow_now:Nn \@mainaux \ExplSyntaxOn \iow_now:Nx \@mainaux @@ -6064,6 +6117,136 @@ c & c & b & a & e % \end{macrocode} % % +% \subsection{Block matrices} +% +% The code in this section if for the construction of \emph{block matrices}. It +% has no direct link with the environment |{NiceMatrixBlock}|. +% +% The following command will be linked to |\Block| in the environments of +% \pkg{nicematrix}. We define it with |\NewExpandableDocumentCommand| of \pkg{xparse} +% because it has an optionnal argument between |<| and |>| (for TeX instructions +% put before the math mode of the label) and because it must be expandable since +% it reduces (in the case of a block of only one row) to a command +% |\multicolumn|. +% \begin{macrocode} +\NewExpandableDocumentCommand \@@_Block: { m D < > { } m } + { + \@@_Block_i #1 \q_stop { #2 } { #3 } + } +% \end{macrocode} +% +% \medskip +% The first argument of |\@@_Block:| (which is required) has a special syntax. It +% must be of the form $i$|-|$j$ where $i$ and $j$ are the size (in rows and +% columns) of the block. +% \begin{macrocode} +\cs_new:Npn \@@_Block_i #1-#2 \q_stop + { + \@@_Block_ii:nnnn { #1 } { #2 } + } +% \end{macrocode} +% +% \medskip +% Now, the arguments have been extracted: |#1| is $i$ (the number of rows of the +% block), |#2| is $j$ (the number of columns of the block), |#3| are the tokens +% to put before the math mode and |#4| is the label of the block. The following +% command must \emph{not} be protected because it contains a command +% |\multicolumn| (in the case of a block of only one row). +% \begin{macrocode} +\cs_new:Npn \@@_Block_ii:nnnn #1 #2 #3 #4 + { +% \end{macrocode} +% +% \medskip +% In the case of a block of only one row, we use a |\multicolumn| and not the +% general technique because, in this case, we want the label perfectly aligned +% with the base line of that row of the array. +% \begin{macrocode} + \int_compare:nNnTF { #1 } = 1 + { + \multicolumn { #2 } { C } { \hbox:n { #3 $#4$ } } + \@@_gobble_ampersands:n { #2 - 1 } + } + { \@@_Block_iii:nnnn { #1 } { #2 } { #3 } { #4 } } + } +% \end{macrocode} +% +% \medskip +% The command |\@@_Block_iii:nnnn| is for the case of a block of $n$~rows with $n>1$. +% \begin{macrocode} +\cs_new_protected:Npn \@@_Block_iii:nnnn #1 #2 #3 #4 + { + \bool_gset_true:N \g_@@_extra_nodes_bool +% \end{macrocode} +% We write an instruction in the |code-after|. We write the instruction in the +% beginning of the |code-after| (the |left| in |\tl_gput_left:Nx|) because we +% want the Tikz nodes corresponding of the block created \emph{before} potential +% instructions written by the user in the |code-after| (these instructions may +% use the Tikz node of the created block). +% \begin{macrocode} + \tl_gput_left:Nx \g_@@_code_after_tl + { + \@@_Block_iv:nnnnn + { \int_use:N \g_@@_row_int } + { \int_use:N \g_@@_col_int } + { \int_eval:n { \g_@@_row_int + #1 - 1 } } + { \int_eval:n { \g_@@_col_int + #2 - 1 } } + \exp_not:n { { #3 $ #4 $ } } + } + } +% \end{macrocode} +% +% \medskip +% The command |\@@_gobble_ampersands:n| will gobble $n$ ampersands (and also the +% spaces) where $n$ is the argument of the command. This command is fully expandable +% and we need this feature. +% \begin{macrocode} +\group_begin: + \char_set_catcode_letter:N \& + \cs_new:Npn \@@_gobble_ampersands:n #1 + { + \int_compare:nNnT { #1 } > 0 + { + \peek_charcode_remove_ignore_spaces:NT & + { \@@_gobble_ampersands:n { #1 - 1 } } + } + } +\group_end: +% \end{macrocode} +% +% +% \medskip +% The following command |\@@_Block_iii:nnnnn| will be used in the |code-after|. +% It's necessary to create two Tikz nodes because we want the label |#5| really +% drawn in the \emph{center} of the node. +% \begin{macrocode} +\cs_new_protected:Npn \@@_Block_iv:nnnnn #1 #2 #3 #4 #5 + { + \bool_if:nTF + { + \int_compare_p:nNn { #3 } > \g_@@_row_int + || \int_compare_p:nNn { #4 } > \g_@@_col_int + } + { \msg_error:nnnn { nicematrix } { Block~too~large } { #1 } { #2 } } + { + \begin{tikzpicture} + \node + [ + fit = ( #1 - #2 - medium . north~west ) + ( #3 - #4 - medium . south~east ) , + inner~sep = 0 pt , + ] +% \end{macrocode} +% We don't forget the name of the node because the user may wish to use it. +% \begin{macrocode} + (#1-#2) { } ; + \node at (#1-#2.center) { #5 } ; + \end{tikzpicture} + } + } +% \end{macrocode} +% +% % \subsection{We process the options} % % We process the options when the package is loaded (with |\usepackage|) but we @@ -6079,6 +6262,249 @@ c & c & b & a & e \ProcessKeysOptions { NiceMatrix } % \end{macrocode} % +% \subsection{Error messages of the package} +% +% \begin{macrocode} +\@@_msg_new:nn { Block~too~large } + { + You~try~to~draw~a~block~in~the~cell~#1-#2~of~your~matrix~but~the~matrix~is~ + too~small~for~that~block.\\ + If~you~go~on,~this~command~line~will~be~ignored. + } +% \end{macrocode} +% +% +% \begin{macrocode} +\@@_msg_new:nn { Impossible~line } + { + A~dotted~line~can't~be~drawn~because~you~have~not~put~ + all~the~ampersands~required~on~the~row~#1.\\ + If~you~go~on,~this~dotted~line~will~be~ignored. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { Wrong~last~row } + { + You~have~used~'last-row=\int_use:N \g_@@_last_row_int'~but~your~environment~ + \{\@currenvir\}~seems~to~have~\int_use:N \g_@@_row_int\ + rows~(remark~that~you~can~use~'last-row'~without~value).~If~you~go~on, + ~the~value~of~\int_use:N \g_@@_row_int\ + will~be~used~for~last~row. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { Draft~mode } + { The~compilation~is~in~draft~mode:~the~dotted~lines~won't~be~drawn. } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { Yet~in~env } + { + Environments~\{NiceArray\}~(or~\{NiceMatrix\},~etc.)~can't~be~ + nested.\\ + This~error~is~fatal. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { Outside~math~mode } + { + The~environment~\{\@currenvir\}~can~be~used~only~in~math~mode~ + (and~not~in~\token_to_str:N \vcenter).\\ + This~error~is~fatal. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { Option~Transparent~suppressed } + { + The~option~'Transparent'~has~been~renamed~'transparent'.\\ + However,~you~can~go~on~for~this~time. + } +\@@_msg_new:nn { Option~RenewMatrix~suppressed } + { + The~option~'RenewMatrix'~has~been~renamed~'renew-matrix'.\\ + However,~you~can~go~on~for~this~time. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { Bad~value~for~letter~for~dotted~lines } + { + The~value~of~key~'\tl_use:N\l_keys_key_tl'~must~be~of~length~1.\\ + If~you~go~on,~it~will~be~ignored. + } +% \end{macrocode} +% +% +% \begin{macrocode} +\@@_msg_new:nnn { Unknown~key~for~NiceMatrixOptions } + { + The~key~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~command~ + \token_to_str:N \NiceMatrixOptions. \\ + If~you~go~on,~it~will~be~ignored. \\ + For~a~list~of~the~available~keys,~type~H~. + } + { + The~available~keys~are~(in~alphabetic~order):~ + allow-duplicate-names,~ + code-for-first-col,~ + code-for-first-row,~ + code-for-last-col,~ + code-for-last-row,~ + exterior-arraycolsep,~ + hlines,~ + left-margin,~ + letter-for-dotted-lines,~ + nullify-dots,~ + parallelize-diags,~ + renew-dots,~ + renew-matrix,~ + right-margin,~ + and~transparent + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nnn { Unknown~option~for~NiceArray } + { + The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~environment~ + \{NiceArray\}. \\ + If~you~go~on,~it~will~be~ignored. \\ + For~a~list~of~the~available~options,~type~H~. + } + { + The~available~options~are~(in~alphabetic~order):~ + b,~ + c,~ + code-after,~ + code-for-first-col,~ + code-for-first-row,~ + code-for-last-col,~ + code-for-last-row,~ + columns-width,~ + create-extra-nodes,~ + extra-left-margin,~ + extra-right-margin,~ + hlines,~ + left-margin,~ + name,~ + nullify-dots,~ + parallelize-diags,~ + renew-dots,~ + right-margin,~ + and~t. + } +% \end{macrocode} +% +% +% \begin{macrocode} +\@@_msg_new:nnn { Unknown~option~for~NiceMatrix } + { + The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~environment~ + \{NiceMatrix\}~and~its~variants. \\ + If~you~go~on,~it~will~be~ignored. \\ + For~a~list~of~the~available~options,~type~H~. + } + { + The~available~options~are~(in~alphabetic~order):~ + code-after,~ + columns-width,~ + create-extra-nodes,~ + extra-left-margin,~ + extra-right-margin,~ + hlines,~ + left-margin,~ + name,~ + nullify-dots,~ + parallelize-diags,~ + renew-dots~ + and~right-margin. + } +% \end{macrocode} +% +% \medskip +% Despite its name, the following set of keys will be used for |{pNiceArray}| +% but also |{vNiceArray}|, |{VNiceArray}|, etc. but not for |{NiceArray}|. +% \begin{macrocode} +\@@_msg_new:nnn { Unknown~option~for~pNiceArray } + { + The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~environment~ + \{\@currenvir\}. \\ + If~you~go~on,~it~will~be~ignored. \\ + For~a~list~of~the~available~options,~type~H~. + } + { + The~available~options~are~(in~alphabetic~order):~ + code-after,~ + code-for-first-col,~ + code-for-first-row,~ + code-for-last-col,~ + code-for-last-row,~ + columns-width,~ + create-extra-nodes,~ + extra-left-margin,~ + extra-right-margin,~ + first-col,~ + first-row,~ + last-col,~ + last-row,~ + hlines,~ + left-margin,~ + name,~ + nullify-dots,~ + parallelize-diags,~ + renew-dots,~ + and~right-margin. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nnn { Duplicate~name } + { + The~name~'\l_keys_value_tl'~is~already~used~and~you~shouldn't~use~ + the~same~environment~name~twice.~You~can~go~on,~but,~ + maybe,~you~will~have~incorrect~results~especially~ + if~you~use~'columns-width=auto'. \\ + For~a~list~of~the~names~already~used,~type~H~. \\ + If~you~don't~want~to~see~this~message~again,~use~the~option~ + 'allow-duplicate-names'. + } + { + The~names~already~defined~in~this~document~are:~ + \seq_use:Nnnn \g_@@_names_seq { ,~ } { ,~ } { ~and~ }. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { Option~auto~for~columns-width } + { + You~can't~give~the~value~'auto'~to~the~option~'columns-width'~here.~ + If~you~go~on,~the~option~will~be~ignored. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { Zero~row } + { + There~is~a~problem.~Maybe~your~environment~\{\@currenvir\}~is~empty.~ + Maybe~you~have~used~l,~c~and~r~instead~of~L,~C~and~R~in~the~preamble~ + of~your~environment. \\ + If~you~go~on,~the~result~may~be~incorrect. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { Use~of~:~in~first~position } + { + You~can't~use~the~column~specifier~'\l_@@_letter_for_dotted_lines_str'~in~the~ + first~position~of~the~preamble~of~the~environment~\{\@currenvir\}. \\ + If~you~go~on,~this~dotted~line~will~be~ignored. + } +% \end{macrocode} +% % % \subsection{Code for \textbackslash seq_mapthread_function:NNN} % @@ -6369,17 +6795,36 @@ c & c & b & a & e % A warning is issued when the |draft| mode is used. In this case, the dotted % lines are not drawn. % -% -% \subsection*{Changes between version 2.2.1 and 2.3} +% +% \subsection*{Changes between version 2.3 and 3.0} % % Modification of |\Hdotsfor|. Now |\Hdotsfor| erases the |\vlines| (of ``"|"'') % as |\hdotsfor| does. % -% \subsection*{Changes between version 2.3 and 3.0} -% % Composition of exterior rows and columns of the four sides of the matrix (and % not only on two sides) with the options |first-row|, |last-row|, |first-col| % and |last-col|. +% +% \subsection*{Changes between version 3.0 and 3.1} +% +% Command |\Block| to draw block matrices. +% +% Error message when the user gives an incorrect value for |last-row|. +% +% A dotted line can no longer cross another dotted line (except the dotted lines +% drawn by |\cdottedline|, |:| (in the preamble of the array) and |\line| in +% |code-after|. +% +% The starred versions of |\Cdots|, |\Ldots|, etc. are now deprecated because, +% with the new implementation, they become pointless. These starred versions +% are no longer documented. +% +% The vertical rules in the matrices (drawn by \verb+|+) are now compatible with +% the color fixed by \pkg{colortbl}. +% +% Correction of a bug: it was not possible to use the colon |:| in the preamble +% of an array when |pdflatex| was used with \pkg{french-babel} (because +% \pkg{french-babel} activates the colon in the beginning of the document). % % \PrintIndex % diff --git a/Master/texmf-dist/tex/latex/nicematrix/nicematrix.sty b/Master/texmf-dist/tex/latex/nicematrix/nicematrix.sty index a8c8baaf489..82a4d074ac7 100644 --- a/Master/texmf-dist/tex/latex/nicematrix/nicematrix.sty +++ b/Master/texmf-dist/tex/latex/nicematrix/nicematrix.sty @@ -18,8 +18,8 @@ %% and version 1.3 or later is part of all distributions of %% LaTeX version 2005/12/01 or later. %% -\def\myfileversion{3.0} -\def\myfiledate{2019/08/15} +\def\myfileversion{3.1} +\def\myfiledate{2019/09/04} \RequirePackage{tikz} \usetikzlibrary{fit} \RequirePackage{expl3}[2019/02/15] @@ -38,6 +38,7 @@ \RequirePackage { xparse } [ 2018-10-17 ] \cs_new_protected:Npn \__nm_error:n { \msg_error:nn { nicematrix } } \cs_new_protected:Npn \__nm_error:nn { \msg_error:nn { nicematrix } } +\cs_new_protected:Npn \__nm_error:nnn { \msg_error:nnn { nicematrix } } \cs_new_protected:Npn \__nm_fatal:n { \msg_fatal:nn { nicematrix } } \cs_new_protected:Npn \__nm_fatal:nn { \msg_fatal:nn { nicematrix } } \cs_new_protected:Npn \__nm_msg_new:nn { \msg_new:nnn { nicematrix } } @@ -51,8 +52,6 @@ \@ifclassloaded { revtex4-2 } { \bool_set_true:N \c__nm_revtex_bool } { } -\__nm_msg_new:nn { Draft~mode } - { The~compilation~is~in~draft~mode:~the~dotted~lines~won't~be~drawn. } \bool_if:NT \c__nm_draft_bool { \msg_warning:nn { nicematrix } { Draft~mode } } \ProvideDocumentCommand \iddots { } @@ -80,23 +79,15 @@ \__nm_fatal:n { Outside~math~mode } \fi: } -\__nm_msg_new:nn { Yet~in~env } - { - Environments~\{NiceArray\}~(or~\{NiceMatrix\},~etc.)~can't~be~ - nested.\\ - This~error~is~fatal. - } -\__nm_msg_new:nn { Outside~math~mode } - { - The~environment~\{\@currenvir\}~can~be~used~only~in~math~mode~ - (and~not~in~\token_to_str:N \vcenter).\\ - This~error~is~fatal. - } +\bool_new:N \l__nm_impossible_line_bool \bool_new:N \c__nm_colortbl_loaded_bool \AtBeginDocument { \@ifpackageloaded { colortbl } - { \bool_set_true:N \c__nm_colortbl_loaded_bool } + { + \bool_set_true:N \c__nm_colortbl_loaded_bool + \cs_set_protected:Npn \__nm_vline_i: { { \CT@arc@ \vline } } + } { } } \int_new:N \l__nm_first_row_int @@ -151,16 +142,6 @@ \NC@find } } -\__nm_msg_new:nn { Option~Transparent~suppressed } - { - The~option~'Transparent'~has~been~renamed~'transparent'.\\ - However,~you~can~go~on~for~this~time. - } -\__nm_msg_new:nn { Option~RenewMatrix~suppressed } - { - The~option~'RenewMatrix'~has~been~renamed~'renew-matrix'.\\ - However,~you~can~go~on~for~this~time. - } \str_new:N \l__nm_pos_env_str \str_set:Nn \l__nm_pos_env_str c \bool_new:N \l__nm_exterior_arraycolsep_bool @@ -281,87 +262,16 @@ letter-for-dotted-lines .code:n = { \int_compare:nTF { \tl_count:n { #1 } = \c_one_int } - { \tl_set:Nx \l__nm_letter_for_dotted_lines_str { #1 } } + { \str_set:Nx \l__nm_letter_for_dotted_lines_str { #1 } } { \__nm_error:n { Bad~value~for~letter~for~dotted~lines } } } , letter-for-dotted-lines .value_required:n = true , letter-for-dotted-lines .initial:n = \c_colon_str , unknown .code:n = \__nm_error:n { Unknown~key~for~NiceMatrixOptions } } -\__nm_msg_new:nn { Bad~value~for~letter~for~dotted~lines } - { - The~value~of~key~'\tl_use:N\l_keys_key_tl'~must~be~of~length~1.\\ - If~you~go~on,~it~will~be~ignored. - } -\__nm_msg_new:nnn { Unknown~key~for~NiceMatrixOptions } - { - The~key~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~command~ - \token_to_str:N \NiceMatrixOptions. \\ - If~you~go~on,~it~will~be~ignored. \\ - For~a~list~of~the~available~keys,~type~H~. - } - { - The~available~keys~are~(in~alphabetic~order):~ - allow-duplicate-names,~ - code-for-first-col,~ - code-for-first-row,~ - code-for-last-col,~ - code-for-last-row,~ - exterior-arraycolsep,~ - hlines,~ - left-margin,~ - letter-for-dotted-lines,~ - nullify-dots,~ - parallelize-diags,~ - renew-dots,~ - renew-matrix,~ - right-margin,~ - and~transparent - } -\__nm_msg_new:nn { Option~auto~for~columns-width } - { - You~can't~give~the~value~'auto'~to~the~option~'columns-width'~here.~ - If~you~go~on,~the~option~will~be~ignored. - } \NewDocumentCommand \NiceMatrixOptions { m } { \keys_set:nn { NiceMatrix / NiceMatrixOptions } { #1 } } \keys_define:nn { NiceMatrix / NiceMatrix } { unknown .code:n = \__nm_error:n { Unknown~option~for~NiceMatrix } } -\__nm_msg_new:nnn { Unknown~option~for~NiceMatrix } - { - The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~environment~ - \{NiceMatrix\}~and~its~variants. \\ - If~you~go~on,~it~will~be~ignored. \\ - For~a~list~of~the~available~options,~type~H~. - } - { - The~available~options~are~(in~alphabetic~order):~ - code-after,~ - columns-width,~ - create-extra-nodes,~ - extra-left-margin,~ - extra-right-margin,~ - hlines,~ - left-margin,~ - name,~ - nullify-dots,~ - parallelize-diags,~ - renew-dots~ - and~right-margin. - } -\__nm_msg_new:nnn { Duplicate~name } - { - The~name~'\l_keys_value_tl'~is~already~used~and~you~shouldn't~use~ - the~same~environment~name~twice.~You~can~go~on,~but,~ - maybe,~you~will~have~incorrect~results~especially~ - if~you~use~'columns-width=auto'. \\ - For~a~list~of~the~names~already~used,~type~H~. \\ - If~you~don't~want~to~see~this~message~again,~use~the~option~ - 'allow-duplicate-names'. - } - { - The~names~already~defined~in~this~document~are:~ - \seq_use:Nnnn \g__nm_names_seq { ,~ } { ,~ } { ~and~ }. - } \keys_define:nn { NiceMatrix / NiceArray } { c .code:n = \str_set:Nn \l__nm_pos_env_str c , @@ -374,35 +284,6 @@ last-row .default:n = -1 , unknown .code:n = \__nm_error:n { Unknown~option~for~NiceArray } } -\__nm_msg_new:nnn { Unknown~option~for~NiceArray } - { - The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~environment~ - \{NiceArray\}. \\ - If~you~go~on,~it~will~be~ignored. \\ - For~a~list~of~the~available~options,~type~H~. - } - { - The~available~options~are~(in~alphabetic~order):~ - b,~ - c,~ - code-after,~ - code-for-first-col,~ - code-for-first-row,~ - code-for-last-col,~ - code-for-last-row,~ - columns-width,~ - create-extra-nodes,~ - extra-left-margin,~ - extra-right-margin,~ - hlines,~ - left-margin,~ - name,~ - nullify-dots,~ - parallelize-diags,~ - renew-dots,~ - right-margin,~ - and~t. - } \keys_define:nn { NiceMatrix / pNiceArray } { first-col .code:n = \int_zero:N \l__nm_first_col_int , @@ -412,36 +293,6 @@ last-row .default:n = -1 , unknown .code:n = \__nm_error:n { Unknown~option~for~pNiceArray } } -\__nm_msg_new:nnn { Unknown~option~for~pNiceArray } - { - The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~environment~ - \{\@currenvir\}. \\ - If~you~go~on,~it~will~be~ignored. \\ - For~a~list~of~the~available~options,~type~H~. - } - { - The~available~options~are~(in~alphabetic~order):~ - code-after,~ - code-for-first-col,~ - code-for-first-row,~ - code-for-last-col,~ - code-for-last-row,~ - columns-width,~ - create-extra-nodes,~ - extra-left-margin,~ - extra-right-margin,~ - first-col,~ - first-row,~ - last-col,~ - last-row,~ - hlines,~ - left-margin,~ - name,~ - nullify-dots,~ - parallelize-diags,~ - renew-dots,~ - and~right-margin. - } \cs_new_protected:Nn \__nm_Cell: { \int_gincr:N \g__nm_col_int @@ -580,7 +431,8 @@ { \cs_new_protected:Npn \__nm_instruction_of_type:n #1 { - \tl_gput_right:Nx \g__nm_lines_to_draw_tl + \tl_gput_right:cx + { g__nm_ #1 _ lines _ tl } { \use:c { __nm _ draw _ #1 : nn } { \int_use:N \g__nm_row_int } @@ -648,38 +500,38 @@ \int_gset_eq:NN \g__nm_first_col_int \l__nm_first_col_int \bool_gset_eq:NN \g__nm_NiceArray_bool \l__nm_NiceArray_bool \bool_gset_eq:NN \g__nm_last_row_without_value_bool - \l__nm_last_row_without_value_bool + \l__nm_last_row_without_value_bool \cs_set:Npn \ialign - { - \bool_if:NTF \c__nm_colortbl_loaded_bool + { + \bool_if:NTF \c__nm_colortbl_loaded_bool + { + \CT@everycr + { + \noalign { \cs_gset_eq:NN \CT@row@color \prg_do_nothing: } + \__nm_everycr: + } + } + { \everycr { \__nm_everycr: } } + \tabskip = \c_zero_skip + \cs_set:Npn \ialign { - \CT@everycr - { - \noalign { \global\let\CT@row@color\relax } - \__nm_everycr: - } + \everycr { } + \tabskip = \c_zero_skip + \halign } - { \everycr { \__nm_everycr: } } - \tabskip = \c_zero_skip - \cs_set:Npn \ialign - { - \everycr { } - \tabskip = \c_zero_skip - \halign - } - \halign - } + \halign + } \dim_compare:nNnTF \l__nm_columns_width_dim = \c_zero_dim - { - \newcolumntype L { > \__nm_Cell: l < \__nm_end_Cell: } - \newcolumntype C { > \__nm_Cell: c < \__nm_end_Cell: } - \newcolumntype R { > \__nm_Cell: r < \__nm_end_Cell: } - } - { - \newcolumntype L { w l { \dim_use:N \l__nm_columns_width_dim } } - \newcolumntype C { w c { \dim_use:N \l__nm_columns_width_dim } } - \newcolumntype R { w r { \dim_use:N \l__nm_columns_width_dim } } - } + { + \newcolumntype L { > \__nm_Cell: l < \__nm_end_Cell: } + \newcolumntype C { > \__nm_Cell: c < \__nm_end_Cell: } + \newcolumntype R { > \__nm_Cell: r < \__nm_end_Cell: } + } + { + \newcolumntype L { w l { \dim_use:N \l__nm_columns_width_dim } } + \newcolumntype C { w c { \dim_use:N \l__nm_columns_width_dim } } + \newcolumntype R { w r { \dim_use:N \l__nm_columns_width_dim } } + } \cs_set_eq:NN \Ldots \__nm_Ldots \cs_set_eq:NN \Cdots \__nm_Cdots \cs_set_eq:NN \Vdots \__nm_Vdots @@ -689,6 +541,7 @@ \cs_set_eq:NN \Hspace \__nm_Hspace: \cs_set_eq:NN \Hdotsfor \__nm_Hdotsfor: \cs_set_eq:NN \multicolumn \__nm_multicolumn:nnn + \cs_set_eq:NN \Block \__nm_Block: \bool_if:NT \l__nm_renew_dots_bool { \cs_set_eq:NN \ldots \__nm_Ldots @@ -699,7 +552,6 @@ \cs_set_eq:NN \dots \__nm_Ldots \cs_set_eq:NN \hdotsfor \__nm_Hdotsfor: } - \seq_gclear_new:N \g__nm_empty_cells_seq \seq_gclear_new:N \g__nm_multicolumn_cells_seq \seq_gclear_new:N \g__nm_multicolumn_sizes_seq \int_gzero_new:N \g__nm_row_int @@ -718,7 +570,9 @@ \dim_gzero_new:N \g__nm_dp_ante_last_row_dim \dim_gzero_new:N \g__nm_ht_last_row_dim \dim_gzero_new:N \g__nm_dp_last_row_dim - \exp_args:Nx \newcolumntype \l__nm_letter_for_dotted_lines_str + \tl_set_rescan:Nno + \l__nm_letter_for_dotted_lines_str { } \l__nm_letter_for_dotted_lines_str + \exp_args:NV \newcolumntype \l__nm_letter_for_dotted_lines_str { ! { @@ -736,6 +590,12 @@ \bool_if:NT \c__nm_siunitx_loaded_bool \__nm_renew_NC@rewrite@S: \int_gset:Nn \g__nm_last_vdotted_col_int { -1 } \bool_gset_false:N \g__nm_last_col_found_bool + \tl_gclear_new:N \g__nm_Cdots_lines_tl + \tl_gclear_new:N \g__nm_Ldots_lines_tl + \tl_gclear_new:N \g__nm_Vdots_lines_tl + \tl_gclear_new:N \g__nm_Ddots_lines_tl + \tl_gclear_new:N \g__nm_Iddots_lines_tl + \tl_gclear_new:N \g__nm_Hdotsfor_lines_tl } \NewDocumentEnvironment { NiceArrayWithDelims } { m m O { } m ! O { } } { @@ -746,7 +606,6 @@ \cs_if_exist:NT \tikz@library@external@loaded { \tikzset { external / export = false } } \group_insert_after:N \__nm_after_array: - \tl_gclear_new:N \g__nm_lines_to_draw_tl \int_gincr:N \g__nm_env_int \bool_if:NF \l__nm_block_auto_columns_width_bool { \dim_gzero_new:N \g__nm_max_cell_width_dim } @@ -788,7 +647,7 @@ \hbox_set:Nn \l_tmpa_box { \c_math_toggle_token - \left #1 \vcenter to 1 cm { } \right. + \left #1 \vcenter to 3 cm { } \right. \c_math_toggle_token } @@ -797,7 +656,7 @@ { \dim_set_eq:NN \nulldelimiterspace \c_zero_dim \c_math_toggle_token - \left. \vcenter to 1 cm { } \right #2 + \left. \vcenter to 3 cm { } \right #2 \c_math_toggle_token } \dim_gset:Nn \g__nm_right_delim_dim { \box_wd:N \l_tmpa_box } @@ -835,6 +694,17 @@ \skip_horizontal:n \g__nm_right_margin_dim \skip_horizontal:n \g__nm_extra_right_margin_dim \hbox_set_end: + \int_compare:nNnT \g__nm_last_row_int > { -2 } + { + \bool_if:NF \g__nm_last_row_without_value_bool + { + \int_compare:nNnF \g__nm_last_row_int = \g__nm_row_int + { + \__nm_error:n { Wrong~last~row } + \int_gset_eq:NN \g__nm_last_row_int \g__nm_row_int + } + } + } \int_compare:nNnTF \l__nm_first_row_int = \c_zero_int { \dim_compare:nNnTF @@ -1097,7 +967,6 @@ \cs_if_exist:NT \tikz@library@external@loaded { \tikzset { external / export = false } } \group_insert_after:N \__nm_after_array: - \tl_gclear_new:N \g__nm_lines_to_draw_tl \int_gincr:N \g__nm_env_int \bool_if:NF \l__nm_block_auto_columns_width_bool { \dim_gzero_new:N \g__nm_max_cell_width_dim } @@ -1169,25 +1038,51 @@ } \prg_set_conditional:Npnn \__nm_if_not_empty_cell:nn #1 #2 { T , TF } { - \cs_if_free:cTF - { pgf@sh@ns@nm -\int_use:N \g__nm_env_int - \int_use:N #1 - \int_use:N #2 } - \prg_return_false: - { - \seq_if_in:NxTF \g__nm_empty_cells_seq { \int_use:N #1 - \int_use:N #2 } - \prg_return_false: - { - \begin { pgfpicture } - \tl_set:Nx \l_tmpa_tl - { nm - \int_use:N \g__nm_env_int - \int_use:N #1 - \int_use:N #2 } - \pgfpointanchor \l_tmpa_tl { east } - \dim_gset:Nn \g_tmpa_dim \pgf@x - \pgfpointanchor \l_tmpa_tl { west } - \dim_gset:Nn \g_tmpb_dim \pgf@x - \end { pgfpicture } - \dim_compare:nNnTF - { \dim_abs:n { \g_tmpb_dim - \g_tmpa_dim } } < { 0.5 pt } + \bool_set_false:N \l_tmpa_bool + \cs_if_exist:cTF + { __nm _ dotted _ \int_use:N #1 - \int_use:N #2 } + \prg_return_true: + { + \cs_if_free:cTF + { + pgf@sh@ns@nm - + \int_use:N \g__nm_env_int - + \int_use:N #1 - + \int_use:N #2 + } + { \prg_return_false: } + { + \bool_set_false:N \l_tmpa_bool + \cs_if_exist:cT + { __nm _ empty _ \int_use:N #1 - \int_use:N #2 } + { + \int_compare:nNnT + { \use:c { __nm _ empty _ \int_use:N #1 - \int_use:N #2 } } + = + \g__nm_env_int + { \bool_set_true:N \l_tmpa_bool } + } + \bool_if:NTF \l_tmpa_bool \prg_return_false: - \prg_return_true: + { + \begin { pgfpicture } + \tl_set:Nx \l_tmpa_tl + { + nm - + \int_use:N \g__nm_env_int - + \int_use:N #1 - + \int_use:N #2 + } + \pgfpointanchor \l_tmpa_tl { east } + \dim_gset:Nn \g_tmpa_dim \pgf@x + \pgfpointanchor \l_tmpa_tl { west } + \dim_gset:Nn \g_tmpb_dim \pgf@x + \end { pgfpicture } + \dim_compare:nNnTF + { \dim_abs:n { \g_tmpb_dim - \g_tmpa_dim } } < { 0.5 pt } + \prg_return_false: + \prg_return_true: + } } } } @@ -1197,13 +1092,6 @@ \__nm_after_array_i: { \__nm_error:n { Zero~row } } } -\__nm_msg_new:nn { Zero~row } - { - There~is~a~problem.~Maybe~your~environment~\{\@currenvir\}~is~empty.~ - Maybe~you~have~used~l,~c~and~r~instead~of~L,~C~and~R~in~the~preamble~ - of~your~environment. \\ - If~you~go~on,~the~result~may~be~incorrect. - } \cs_new_protected:Nn \__nm_after_array_i: { \group_begin: @@ -1232,7 +1120,6 @@ } \iow_now:Nn \@mainaux \ExplSyntaxOff } - \seq_gclear_new:N \g__nm_yet_drawn_seq \bool_if:NT \l__nm_parallelize_diags_bool { \int_zero_new:N \l__nm_ddots_int @@ -1243,17 +1130,18 @@ \dim_zero_new:N \l__nm_delta_y_two_dim } \bool_if:NT \g__nm_extra_nodes_bool \__nm_create_extra_nodes: - \tl_if_empty:NF \g__nm_lines_to_draw_tl - { - \int_zero_new:N \l__nm_initial_i_int - \int_zero_new:N \l__nm_initial_j_int - \int_zero_new:N \l__nm_final_i_int - \int_zero_new:N \l__nm_final_j_int - \bool_set_false:N \l__nm_initial_open_bool - \bool_set_false:N \l__nm_final_open_bool - \g__nm_lines_to_draw_tl - } - \tl_gclear:N \g__nm_lines_to_draw_tl + \int_zero_new:N \l__nm_initial_i_int + \int_zero_new:N \l__nm_initial_j_int + \int_zero_new:N \l__nm_final_i_int + \int_zero_new:N \l__nm_final_j_int + \bool_set_false:N \l__nm_initial_open_bool + \bool_set_false:N \l__nm_final_open_bool + \g__nm_Hdotsfor_lines_tl + \g__nm_Vdots_lines_tl + \g__nm_Ddots_lines_tl + \g__nm_Iddots_lines_tl + \g__nm_Cdots_lines_tl + \g__nm_Ldots_lines_tl \tikzset { every~picture / .style = @@ -1270,6 +1158,7 @@ } \cs_new_protected:Nn \__nm_find_extremities_of_line:nnnn { + \cs_set:cpn { __nm _ dotted _ #1 - #2 } { } \int_set:Nn \l__nm_initial_i_int { #1 } \int_set:Nn \l__nm_initial_j_int { #2 } \int_set:Nn \l__nm_final_i_int { #1 } @@ -1306,8 +1195,32 @@ \bool_set_true:N \l__nm_stop_loop_bool } { - \__nm_if_not_empty_cell:nnT \l__nm_final_i_int \l__nm_final_j_int + \__nm_if_not_empty_cell:nnTF \l__nm_final_i_int \l__nm_final_j_int { \bool_set_true:N \l__nm_stop_loop_bool } + { + \cs_set:cpn + { + __nm _ dotted _ + \int_use:N \l__nm_final_i_int - + \int_use:N \l__nm_final_j_int + } + { } + } + } + } + \cs_if_free:cT + { + pgf@sh@ns@nm - + \int_use:N \g__nm_env_int - + \int_use:N \l__nm_final_i_int - + \int_use:N \l__nm_final_j_int + } + { + \bool_if:NF \l__nm_final_open_bool + { + \msg_error:nnx { nicematrix } { Impossible~line } + { \int_use:N \l__nm_final_i_int } + \bool_set_true:N \l__nm_impossible_line_bool } } \bool_set_false:N \l__nm_stop_loop_bool @@ -1342,29 +1255,37 @@ \bool_set_true:N \l__nm_stop_loop_bool } { - \__nm_if_not_empty_cell:nnT + \__nm_if_not_empty_cell:nnTF \l__nm_initial_i_int \l__nm_initial_j_int { \bool_set_true:N \l__nm_stop_loop_bool } + { + \cs_set:cpn + { + __nm _ dotted _ + \int_use:N \l__nm_initial_i_int - + \int_use:N \l__nm_initial_j_int + } + { } + } } } - \bool_if:nT { \l__nm_initial_open_bool || \l__nm_final_open_bool } - \__nm_create_extra_nodes: - } -\prg_set_conditional:Npnn \__nm_if_yet_drawn: { F } - { - \tl_set:Nx \l_tmpa_tl + \cs_if_free:cT { + pgf@sh@ns@nm - + \int_use:N \g__nm_env_int - \int_use:N \l__nm_initial_i_int - - \int_use:N \l__nm_initial_j_int - - \int_use:N \l__nm_final_i_int - - \int_use:N \l__nm_final_j_int + \int_use:N \l__nm_initial_j_int } - \seq_if_in:NVTF \g__nm_yet_drawn_seq \l_tmpa_tl - \prg_return_true: { - \seq_gput_left:NV \g__nm_yet_drawn_seq \l_tmpa_tl - \prg_return_false: + \bool_if:NF \l__nm_initial_open_bool + { + \msg_error:nnx { nicematrix } { Impossible~line } + { \int_use:N \l__nm_initial_i_int } + \bool_set_true:N \l__nm_impossible_line_bool + } } + \bool_if:nT \l__nm_initial_open_bool \__nm_create_extra_nodes: + \bool_if:NT \l__nm_final_open_bool \__nm_create_extra_nodes: } \cs_new_protected:Nn \__nm_retrieve_coords:nn { @@ -1390,42 +1311,46 @@ \cs_generate_variant:Nn \__nm_retrieve_coords:nn { x x } \cs_new_protected:Nn \__nm_draw_Ldots:nn { - \__nm_find_extremities_of_line:nnnn { #1 } { #2 } \c_zero_int \c_one_int - \__nm_if_yet_drawn:F \__nm_actually_draw_Ldots: + \cs_if_free:cT { __nm _ dotted _ #1 - #2 } + { + \bool_set_false:N \l__nm_impossible_line_bool + \__nm_find_extremities_of_line:nnnn { #1 } { #2 } \c_zero_int \c_one_int + \bool_if:NF \l__nm_impossible_line_bool \__nm_actually_draw_Ldots: + } } \cs_new_protected:Nn \__nm_actually_draw_Ldots: { - \__nm_retrieve_coords:xx + \__nm_retrieve_coords:xx + { + \bool_if:NTF \l__nm_initial_open_bool { - \bool_if:NTF \l__nm_initial_open_bool - { - \cs_if_exist:cTF - { - pgf@sh@ns@nm - - \int_use:N \g__nm_env_int - - \int_use:N \l__nm_initial_i_int - - \int_use:N \l__nm_initial_j_int - w - } - { - w.base~west } - { - medium.base~west } - } - { .base~east } - } + \cs_if_exist:cTF + { + pgf@sh@ns@nm + - \int_use:N \g__nm_env_int + - \int_use:N \l__nm_initial_i_int + - \int_use:N \l__nm_initial_j_int - w + } + { - w.base~west } + { - medium.base~west } + } + { .base~east } + } + { + \bool_if:NTF \l__nm_final_open_bool { - \bool_if:NTF \l__nm_final_open_bool + \cs_if_exist:cTF { - \cs_if_exist:cTF - { - pgf@sh@ns@nm - - \int_use:N \g__nm_env_int - - \int_use:N \l__nm_final_i_int - - \int_use:N \l__nm_final_j_int - w - } - { - w.base~east } - { - medium.base~east } + pgf@sh@ns@nm + - \int_use:N \g__nm_env_int + - \int_use:N \l__nm_final_i_int + - \int_use:N \l__nm_final_j_int - w } - { .base~west } + { - w.base~east } + { - medium.base~east } } + { .base~west } + } \bool_if:NT \l__nm_initial_open_bool { \dim_gset_eq:NN \g__nm_y_initial_dim \g__nm_y_final_dim } \bool_if:NT \l__nm_final_open_bool @@ -1436,162 +1361,180 @@ } \cs_new_protected:Nn \__nm_draw_Cdots:nn { - \__nm_find_extremities_of_line:nnnn { #1 } { #2 } \c_zero_int \c_one_int - \__nm_if_yet_drawn:F + \cs_if_free:cT { __nm _ dotted _ #1 - #2 } { - \__nm_retrieve_coords:xx + \bool_set_false:N \l__nm_impossible_line_bool + \__nm_find_extremities_of_line:nnnn { #1 } { #2 } \c_zero_int \c_one_int + \bool_if:NF \l__nm_impossible_line_bool { - \bool_if:NTF \l__nm_initial_open_bool + \__nm_retrieve_coords:xx { - \cs_if_exist:cTF + \bool_if:NTF \l__nm_initial_open_bool { - pgf@sh@ns@nm - - \int_use:N \g__nm_env_int - - \int_use:N \l__nm_initial_i_int - - \int_use:N \l__nm_initial_j_int - w + \cs_if_exist:cTF + { + pgf@sh@ns@nm + - \int_use:N \g__nm_env_int + - \int_use:N \l__nm_initial_i_int + - \int_use:N \l__nm_initial_j_int - w + } + { - w.mid~west } + { - medium.mid~west } } - { - w.mid~west } - { - medium.mid~west } + { .mid~east } } - { .mid~east } - } - { - \bool_if:NTF \l__nm_final_open_bool { - \cs_if_exist:cTF + \bool_if:NTF \l__nm_final_open_bool { - pgf@sh@ns@nm - - \int_use:N \g__nm_env_int - - \int_use:N \l__nm_final_i_int - - \int_use:N \l__nm_final_j_int - w + \cs_if_exist:cTF + { + pgf@sh@ns@nm + - \int_use:N \g__nm_env_int + - \int_use:N \l__nm_final_i_int + - \int_use:N \l__nm_final_j_int - w + } + { - w.mid~east } + { - medium.mid~east } } - { - w.mid~east } - { - medium.mid~east } + { .mid~west } } - { .mid~west } + \bool_if:NT \l__nm_initial_open_bool + { \dim_gset_eq:NN \g__nm_y_initial_dim \g__nm_y_final_dim } + \bool_if:NT \l__nm_final_open_bool + { \dim_gset_eq:NN \g__nm_y_final_dim \g__nm_y_initial_dim } + \__nm_draw_tikz_line: } - \bool_if:NT \l__nm_initial_open_bool - { \dim_gset_eq:NN \g__nm_y_initial_dim \g__nm_y_final_dim } - \bool_if:NT \l__nm_final_open_bool - { \dim_gset_eq:NN \g__nm_y_final_dim \g__nm_y_initial_dim } - \__nm_draw_tikz_line: } } \cs_new_protected:Nn \__nm_draw_Vdots:nn { - \__nm_find_extremities_of_line:nnnn { #1 } { #2 } \c_one_int \c_zero_int - \__nm_if_yet_drawn:F - { \__nm_retrieve_coords:xx - { - \bool_if:NTF \l__nm_initial_open_bool - { - medium.north~west } - { .south~west } - } - { - \bool_if:NTF \l__nm_final_open_bool - { - medium.south~west } - { .north~west } - } - \bool_set:Nn \l_tmpa_bool - { \dim_compare_p:nNn \g__nm_x_initial_dim = \g__nm_x_final_dim } - \__nm_retrieve_coords:xx - { - \bool_if:NTF \l__nm_initial_open_bool - { - medium.north } - { .south } - } - { - \bool_if:NTF \l__nm_final_open_bool - { - medium.south } - { .north } - } - \bool_set:Nn \l_tmpb_bool - { \dim_compare_p:nNn \g__nm_x_initial_dim = \g__nm_x_final_dim } - \bool_if:NF \l_tmpb_bool + \cs_if_free:cT { __nm _ dotted _ #1 - #2 } + { + \bool_set_false:N \l__nm_impossible_line_bool + \__nm_find_extremities_of_line:nnnn { #1 } { #2 } \c_one_int \c_zero_int + \bool_if:NF \l__nm_impossible_line_bool { - \dim_gset:Nn \g__nm_x_initial_dim + \__nm_retrieve_coords:xx + { + \bool_if:NTF \l__nm_initial_open_bool + { - medium.north~west } + { .south~west } + } + { + \bool_if:NTF \l__nm_final_open_bool + { - medium.south~west } + { .north~west } + } + \bool_set:Nn \l_tmpa_bool + { \dim_compare_p:nNn \g__nm_x_initial_dim = \g__nm_x_final_dim } + \__nm_retrieve_coords:xx + { + \bool_if:NTF \l__nm_initial_open_bool + { - medium.north } + { .south } + } { - \bool_if:NTF \l_tmpa_bool \dim_min:nn \dim_max:nn - \g__nm_x_initial_dim \g__nm_x_final_dim + \bool_if:NTF \l__nm_final_open_bool + { - medium.south } + { .north } } - \dim_gset_eq:NN \g__nm_x_final_dim \g__nm_x_initial_dim + \bool_set:Nn \l_tmpb_bool + { \dim_compare_p:nNn \g__nm_x_initial_dim = \g__nm_x_final_dim } + \bool_if:NF \l_tmpb_bool + { + \dim_gset:Nn \g__nm_x_initial_dim + { + \bool_if:NTF \l_tmpa_bool \dim_min:nn \dim_max:nn + \g__nm_x_initial_dim \g__nm_x_final_dim + } + \dim_gset_eq:NN \g__nm_x_final_dim \g__nm_x_initial_dim + } + \__nm_draw_tikz_line: } - \__nm_draw_tikz_line: } } \cs_new_protected:Nn \__nm_draw_Ddots:nn { - \__nm_find_extremities_of_line:nnnn { #1 } { #2 } \c_one_int \c_one_int - \__nm_if_yet_drawn:F + \cs_if_free:cT { __nm _ dotted _ #1 - #2 } { - \__nm_retrieve_coords:xx - { - \bool_if:NTF \l__nm_initial_open_bool - { - medium.north~west } - { .south~east } - } + \bool_set_false:N \l__nm_impossible_line_bool + \__nm_find_extremities_of_line:nnnn { #1 } { #2 } \c_one_int \c_one_int + \bool_if:NF \l__nm_impossible_line_bool { - \bool_if:NTF \l__nm_final_open_bool - { - medium.south~east } - { .north~west } - } - \bool_if:NT \l__nm_parallelize_diags_bool - { - \int_incr:N \l__nm_ddots_int - \int_compare:nNnTF \l__nm_ddots_int = \c_one_int + \__nm_retrieve_coords:xx + { + \bool_if:NTF \l__nm_initial_open_bool + { - medium.north~west } + { .south~east } + } { - \dim_set:Nn \l__nm_delta_x_one_dim - { \g__nm_x_final_dim - \g__nm_x_initial_dim } - \dim_set:Nn \l__nm_delta_y_one_dim - { \g__nm_y_final_dim - \g__nm_y_initial_dim } + \bool_if:NTF \l__nm_final_open_bool + { - medium.south~east } + { .north~west } } + \bool_if:NT \l__nm_parallelize_diags_bool { - \dim_gset:Nn \g__nm_y_final_dim + \int_incr:N \l__nm_ddots_int + \int_compare:nNnTF \l__nm_ddots_int = \c_one_int + { + \dim_set:Nn \l__nm_delta_x_one_dim + { \g__nm_x_final_dim - \g__nm_x_initial_dim } + \dim_set:Nn \l__nm_delta_y_one_dim + { \g__nm_y_final_dim - \g__nm_y_initial_dim } + } { - \g__nm_y_initial_dim + - ( \g__nm_x_final_dim - \g__nm_x_initial_dim ) * - \dim_ratio:nn \l__nm_delta_y_one_dim \l__nm_delta_x_one_dim + \dim_gset:Nn \g__nm_y_final_dim + { + \g__nm_y_initial_dim + + ( \g__nm_x_final_dim - \g__nm_x_initial_dim ) * + \dim_ratio:nn \l__nm_delta_y_one_dim \l__nm_delta_x_one_dim + } } } + \__nm_draw_tikz_line: } - \__nm_draw_tikz_line: } } \cs_new_protected:Nn \__nm_draw_Iddots:nn { - \__nm_find_extremities_of_line:nnnn { #1 } { #2 } 1 { -1 } - \__nm_if_yet_drawn:F - { \__nm_retrieve_coords:xx - { - \bool_if:NTF \l__nm_initial_open_bool - { - medium.north~east } - { .south~west } - } - { - \bool_if:NTF \l__nm_final_open_bool - { - medium.south~west } - { .north~east } - } - \bool_if:NT \l__nm_parallelize_diags_bool + \cs_if_free:cT { __nm _ dotted _ #1 - #2 } + { + \bool_set_false:N \l__nm_impossible_line_bool + \__nm_find_extremities_of_line:nnnn { #1 } { #2 } 1 { -1 } + \bool_if:NF \l__nm_impossible_line_bool { - \int_incr:N \l__nm_iddots_int - \int_compare:nNnTF \l__nm_iddots_int = \c_one_int + \__nm_retrieve_coords:xx { - \dim_set:Nn \l__nm_delta_x_two_dim - { \g__nm_x_final_dim - \g__nm_x_initial_dim } - \dim_set:Nn \l__nm_delta_y_two_dim - { \g__nm_y_final_dim - \g__nm_y_initial_dim } + \bool_if:NTF \l__nm_initial_open_bool + { - medium.north~east } + { .south~west } } { - \dim_gset:Nn \g__nm_y_final_dim - { - \g__nm_y_initial_dim + - ( \g__nm_x_final_dim - \g__nm_x_initial_dim ) * - \dim_ratio:nn \l__nm_delta_y_two_dim \l__nm_delta_x_two_dim - } + \bool_if:NTF \l__nm_final_open_bool + { - medium.south~west } + { .north~east } + } + \bool_if:NT \l__nm_parallelize_diags_bool + { + \int_incr:N \l__nm_iddots_int + \int_compare:nNnTF \l__nm_iddots_int = \c_one_int + { + \dim_set:Nn \l__nm_delta_x_two_dim + { \g__nm_x_final_dim - \g__nm_x_initial_dim } + \dim_set:Nn \l__nm_delta_y_two_dim + { \g__nm_y_final_dim - \g__nm_y_initial_dim } + } + { + \dim_gset:Nn \g__nm_y_final_dim + { + \g__nm_y_initial_dim + + ( \g__nm_x_final_dim - \g__nm_x_initial_dim ) * + \dim_ratio:nn \l__nm_delta_y_two_dim \l__nm_delta_x_two_dim + } + } } + \__nm_draw_tikz_line: } - \__nm_draw_tikz_line: } } \cs_new_protected:Nn \__nm_draw_tikz_line: @@ -1689,8 +1632,9 @@ \cs_set_eq:NN \__nm_iddots \iddots \cs_new_protected:Nn \__nm_add_to_empty_cells: { - \seq_gput_right:Nx \g__nm_empty_cells_seq - { \int_use:N \g__nm_row_int - \int_use:N \g__nm_col_int } + \cs_gset:cpx + { __nm _ empty _ \int_use:N \g__nm_row_int - \int_use:N \g__nm_col_int } + { \int_use:N \g__nm_env_int } } \NewDocumentCommand \__nm_Ldots { s } { @@ -1747,14 +1691,12 @@ \bool_if:NTF \c__nm_draft_bool { \NewDocumentCommand \__nm_Hdotsfor_i { O { } m } - { - \prg_replicate:nn { #2 - 1 } { & \multicolumn { 1 } { C } { } } - } + { \prg_replicate:nn { #2 - 1 } { & \multicolumn { 1 } { C } { } } } } { \NewDocumentCommand \__nm_Hdotsfor_i { O { } m } { - \tl_gput_right:Nx \g__nm_lines_to_draw_tl + \tl_gput_right:Nx \g__nm_Hdotsfor_lines_tl { \__nm_draw_Hdotsfor:nnn { \int_use:N \g__nm_row_int } @@ -1801,6 +1743,8 @@ \bool_if:nT { \l__nm_initial_open_bool || \l__nm_final_open_bool } \__nm_create_extra_nodes: \__nm_actually_draw_Ldots: + \int_step_inline:nnn { #2 } { #2 + #3 - 1 } + { \cs_set:cpn { __nm _ dotted _ #1 - ##1 } { } } } \cs_new_protected:Nn \__nm_line:nn { @@ -1892,12 +1836,6 @@ } } } -\__nm_msg_new:nn { Use~of~:~in~first~position } - { - You~can't~use~the~column~specifier~"\l__nm_letter_for_dotted_lines_str"~in~the~ - first~position~of~the~preamble~of~the~environment~\{\@currenvir\}. \\ - If~you~go~on,~this~dotted~line~will~be~ignored. - } \cs_new_protected:Npn \__nm_vline: { \int_compare:nNnTF \l__nm_first_col_int = \c_zero_int @@ -1908,19 +1846,24 @@ { \int_compare:nNnF \g__nm_row_int = \c_zero_int { - \int_compare:nNnF \g__nm_row_int = \l__nm_last_row_int \vline + \int_compare:nNnF \g__nm_row_int = \l__nm_last_row_int + \__nm_vline_i: } } { \int_compare:nNnF \g__nm_row_int = \c_zero_int { - \int_compare:nNnF \g__nm_row_int = \l__nm_last_row_int \vline + \int_compare:nNnF \g__nm_row_int = \l__nm_last_row_int + \__nm_vline_i: } } } { \int_compare:nNnF \g__nm_row_int = \c_zero_int - { \int_compare:nNnF \g__nm_row_int = \l__nm_last_row_int \vline } + { + \int_compare:nNnF \g__nm_row_int = \l__nm_last_row_int + \__nm_vline_i: + } } } { @@ -1929,15 +1872,19 @@ \int_compare:nNnF \g__nm_row_int = { -1 } { \int_compare:nNnF \g__nm_row_int = { \l__nm_last_row_int - 1 } - \vline + \__nm_vline_i: } } { \int_compare:nNnF \g__nm_row_int = \c_zero_int - { \int_compare:nNnF \g__nm_row_int = \l__nm_last_row_int \vline } + { + \int_compare:nNnF \g__nm_row_int = \l__nm_last_row_int + \__nm_vline_i: + } } } } +\cs_set_eq:NN \__nm_vline_i: \vline \bool_new:N \l__nm_block_auto_columns_width_bool \keys_define:nn { NiceMatrix / NiceMatrixBlock } { @@ -2060,13 +2007,13 @@ \end{tikzpicture} \cs_set:Npn \__nm_create_extra_nodes: { } \begin { tikzpicture } [ remember~picture , overlay ] - \tikz@parse@node \pgfutil@firstofone - ( nm - \int_use:N \g__nm_env_int - 1 - 1 - large .north~west ) - \dim_gset:Nn \g_tmpa_dim \pgf@x - \tikz@parse@node \pgfutil@firstofone - ( nm - \int_use:N \g__nm_env_int - 1 - - \int_use:N \g__nm_col_int - large .north~east ) - \dim_gset:Nn \g_tmpb_dim \pgf@x + \tikz@parse@node \pgfutil@firstofone + ( nm - \int_use:N \g__nm_env_int - 1 - 1 - large .north~west ) + \dim_gset:Nn \g_tmpa_dim \pgf@x + \tikz@parse@node \pgfutil@firstofone + ( nm - \int_use:N \g__nm_env_int - 1 - + \int_use:N \g__nm_col_int - large .north~east ) + \dim_gset:Nn \g_tmpb_dim \pgf@x \end { tikzpicture } \iow_now:Nn \@mainaux \ExplSyntaxOn \iow_now:Nx \@mainaux @@ -2135,7 +2082,256 @@ ] ; } +\NewExpandableDocumentCommand \__nm_Block: { m D < > { } m } + { + \__nm_Block_i #1 \q_stop { #2 } { #3 } + } +\cs_new:Npn \__nm_Block_i #1-#2 \q_stop + { + \__nm_Block_ii:nnnn { #1 } { #2 } + } +\cs_new:Npn \__nm_Block_ii:nnnn #1 #2 #3 #4 + { + \int_compare:nNnTF { #1 } = 1 + { + \multicolumn { #2 } { C } { \hbox:n { #3 $#4$ } } + \__nm_gobble_ampersands:n { #2 - 1 } + } + { \__nm_Block_iii:nnnn { #1 } { #2 } { #3 } { #4 } } + } +\cs_new_protected:Npn \__nm_Block_iii:nnnn #1 #2 #3 #4 + { + \bool_gset_true:N \g__nm_extra_nodes_bool + \tl_gput_left:Nx \g__nm_code_after_tl + { + \__nm_Block_iv:nnnnn + { \int_use:N \g__nm_row_int } + { \int_use:N \g__nm_col_int } + { \int_eval:n { \g__nm_row_int + #1 - 1 } } + { \int_eval:n { \g__nm_col_int + #2 - 1 } } + \exp_not:n { { #3 $ #4 $ } } + } + } +\group_begin: + \char_set_catcode_letter:N \& + \cs_new:Npn \__nm_gobble_ampersands:n #1 + { + \int_compare:nNnT { #1 } > 0 + { + \peek_charcode_remove_ignore_spaces:NT & + { \__nm_gobble_ampersands:n { #1 - 1 } } + } + } +\group_end: +\cs_new_protected:Npn \__nm_Block_iv:nnnnn #1 #2 #3 #4 #5 + { + \bool_if:nTF + { + \int_compare_p:nNn { #3 } > \g__nm_row_int + || \int_compare_p:nNn { #4 } > \g__nm_col_int + } + { \msg_error:nnnn { nicematrix } { Block~too~large } { #1 } { #2 } } + { + \begin{tikzpicture} + \node + [ + fit = ( #1 - #2 - medium . north~west ) + ( #3 - #4 - medium . south~east ) , + inner~sep = 0 pt , + ] + (#1-#2) { } ; + \node at (#1-#2.center) { #5 } ; + \end{tikzpicture} + } + } \ProcessKeysOptions { NiceMatrix } +\__nm_msg_new:nn { Block~too~large } + { + You~try~to~draw~a~block~in~the~cell~#1-#2~of~your~matrix~but~the~matrix~is~ + too~small~for~that~block.\\ + If~you~go~on,~this~command~line~will~be~ignored. + } +\__nm_msg_new:nn { Impossible~line } + { + A~dotted~line~can't~be~drawn~because~you~have~not~put~ + all~the~ampersands~required~on~the~row~#1.\\ + If~you~go~on,~this~dotted~line~will~be~ignored. + } +\__nm_msg_new:nn { Wrong~last~row } + { + You~have~used~'last-row=\int_use:N \g__nm_last_row_int'~but~your~environment~ + \{\@currenvir\}~seems~to~have~\int_use:N \g__nm_row_int\ + rows~(remark~that~you~can~use~'last-row'~without~value).~If~you~go~on, + ~the~value~of~\int_use:N \g__nm_row_int\ + will~be~used~for~last~row. + } +\__nm_msg_new:nn { Draft~mode } + { The~compilation~is~in~draft~mode:~the~dotted~lines~won't~be~drawn. } +\__nm_msg_new:nn { Yet~in~env } + { + Environments~\{NiceArray\}~(or~\{NiceMatrix\},~etc.)~can't~be~ + nested.\\ + This~error~is~fatal. + } +\__nm_msg_new:nn { Outside~math~mode } + { + The~environment~\{\@currenvir\}~can~be~used~only~in~math~mode~ + (and~not~in~\token_to_str:N \vcenter).\\ + This~error~is~fatal. + } +\__nm_msg_new:nn { Option~Transparent~suppressed } + { + The~option~'Transparent'~has~been~renamed~'transparent'.\\ + However,~you~can~go~on~for~this~time. + } +\__nm_msg_new:nn { Option~RenewMatrix~suppressed } + { + The~option~'RenewMatrix'~has~been~renamed~'renew-matrix'.\\ + However,~you~can~go~on~for~this~time. + } +\__nm_msg_new:nn { Bad~value~for~letter~for~dotted~lines } + { + The~value~of~key~'\tl_use:N\l_keys_key_tl'~must~be~of~length~1.\\ + If~you~go~on,~it~will~be~ignored. + } +\__nm_msg_new:nnn { Unknown~key~for~NiceMatrixOptions } + { + The~key~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~command~ + \token_to_str:N \NiceMatrixOptions. \\ + If~you~go~on,~it~will~be~ignored. \\ + For~a~list~of~the~available~keys,~type~H~. + } + { + The~available~keys~are~(in~alphabetic~order):~ + allow-duplicate-names,~ + code-for-first-col,~ + code-for-first-row,~ + code-for-last-col,~ + code-for-last-row,~ + exterior-arraycolsep,~ + hlines,~ + left-margin,~ + letter-for-dotted-lines,~ + nullify-dots,~ + parallelize-diags,~ + renew-dots,~ + renew-matrix,~ + right-margin,~ + and~transparent + } +\__nm_msg_new:nnn { Unknown~option~for~NiceArray } + { + The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~environment~ + \{NiceArray\}. \\ + If~you~go~on,~it~will~be~ignored. \\ + For~a~list~of~the~available~options,~type~H~. + } + { + The~available~options~are~(in~alphabetic~order):~ + b,~ + c,~ + code-after,~ + code-for-first-col,~ + code-for-first-row,~ + code-for-last-col,~ + code-for-last-row,~ + columns-width,~ + create-extra-nodes,~ + extra-left-margin,~ + extra-right-margin,~ + hlines,~ + left-margin,~ + name,~ + nullify-dots,~ + parallelize-diags,~ + renew-dots,~ + right-margin,~ + and~t. + } +\__nm_msg_new:nnn { Unknown~option~for~NiceMatrix } + { + The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~environment~ + \{NiceMatrix\}~and~its~variants. \\ + If~you~go~on,~it~will~be~ignored. \\ + For~a~list~of~the~available~options,~type~H~. + } + { + The~available~options~are~(in~alphabetic~order):~ + code-after,~ + columns-width,~ + create-extra-nodes,~ + extra-left-margin,~ + extra-right-margin,~ + hlines,~ + left-margin,~ + name,~ + nullify-dots,~ + parallelize-diags,~ + renew-dots~ + and~right-margin. + } +\__nm_msg_new:nnn { Unknown~option~for~pNiceArray } + { + The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~environment~ + \{\@currenvir\}. \\ + If~you~go~on,~it~will~be~ignored. \\ + For~a~list~of~the~available~options,~type~H~. + } + { + The~available~options~are~(in~alphabetic~order):~ + code-after,~ + code-for-first-col,~ + code-for-first-row,~ + code-for-last-col,~ + code-for-last-row,~ + columns-width,~ + create-extra-nodes,~ + extra-left-margin,~ + extra-right-margin,~ + first-col,~ + first-row,~ + last-col,~ + last-row,~ + hlines,~ + left-margin,~ + name,~ + nullify-dots,~ + parallelize-diags,~ + renew-dots,~ + and~right-margin. + } +\__nm_msg_new:nnn { Duplicate~name } + { + The~name~'\l_keys_value_tl'~is~already~used~and~you~shouldn't~use~ + the~same~environment~name~twice.~You~can~go~on,~but,~ + maybe,~you~will~have~incorrect~results~especially~ + if~you~use~'columns-width=auto'. \\ + For~a~list~of~the~names~already~used,~type~H~. \\ + If~you~don't~want~to~see~this~message~again,~use~the~option~ + 'allow-duplicate-names'. + } + { + The~names~already~defined~in~this~document~are:~ + \seq_use:Nnnn \g__nm_names_seq { ,~ } { ,~ } { ~and~ }. + } +\__nm_msg_new:nn { Option~auto~for~columns-width } + { + You~can't~give~the~value~'auto'~to~the~option~'columns-width'~here.~ + If~you~go~on,~the~option~will~be~ignored. + } +\__nm_msg_new:nn { Zero~row } + { + There~is~a~problem.~Maybe~your~environment~\{\@currenvir\}~is~empty.~ + Maybe~you~have~used~l,~c~and~r~instead~of~L,~C~and~R~in~the~preamble~ + of~your~environment. \\ + If~you~go~on,~the~result~may~be~incorrect. + } +\__nm_msg_new:nn { Use~of~:~in~first~position } + { + You~can't~use~the~column~specifier~'\l__nm_letter_for_dotted_lines_str'~in~the~ + first~position~of~the~preamble~of~the~environment~\{\@currenvir\}. \\ + If~you~go~on,~this~dotted~line~will~be~ignored. + } \cs_new:Npn \__nm_seq_mapthread_function:NNN #1 #2 #3 { \group_begin: -- cgit v1.2.3