summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2018-08-12 21:56:33 +0000
committerKarl Berry <karl@freefriends.org>2018-08-12 21:56:33 +0000
commitd08faae51fbb21827ca2fe7b782112631fff7b53 (patch)
tree4b36b617fb7ebb2297a5e625f9009cffb255a7f2 /Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx
parentc5cd7647637baac5ca1d069899d554886c675b5f (diff)
nicematrix (12aug18)
git-svn-id: svn://tug.org/texlive/trunk@48395 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx')
-rw-r--r--Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx2673
1 files changed, 1794 insertions, 879 deletions
diff --git a/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx b/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx
index 18b1e89ad3a..753cebb6e9b 100644
--- a/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx
+++ b/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx
@@ -1,6 +1,6 @@
% \iffalse meta-comment
%
-% Copyright (C) 2017 by F. Pantigny
+% Copyright (C) 2017-2018 by F. Pantigny
% -----------------------------------
%
% This file may be distributed and/or modified under the
@@ -15,8 +15,8 @@
%
% \fi
% \iffalse
-\def\myfileversion{2.0}
-\def\myfiledate{2018/07/06}
+\def\myfileversion{2.1}
+\def\myfiledate{2018/08/12}
%
%
%<*batchfile>
@@ -44,7 +44,7 @@ version 2005/12/01 or later.
\endgroup
%</batchfile>
%
-%<@@=nicem>
+%<@@=nm>
%<*driver>
\documentclass[dvipsnames]{l3doc}% dvipsnames is for xcolor (loaded by Tikz, loaded by nicematrix)
\VerbatimFootnotes
@@ -62,7 +62,10 @@ version 2005/12/01 or later.
\titlespacing*{\subsection}{0pt}{4.5ex plus 1ex minus .2ex}{2ex plus .2ex}
\usepackage{multicol}
\setlength{\columnseprule}{0.4pt}
+\usepackage{colortbl}
+\usepackage{arydshln}
\parindent 0pt
+
\DisableCrossrefs
\begin{document}
\DocInput{nicematrix.dtx}
@@ -87,12 +90,9 @@ version 2005/12/01 or later.
%
% This package can be used with |xelatex|, |lualatex|, |pdflatex| but also by the classical workflow
% |latex|-|dvips|-|ps2pdf| (or Adobe Distiller). Two or three compilations may be necessary. This package requires
-% and loads the packages \pkg{expl3}, \pkg{l3keys2e}, \pkg{xparse}, \pkg{array}, \pkg{mathtools} and \pkg{tikz}.
+% and loads the packages \pkg{expl3}, \pkg{l3keys2e}, \pkg{xparse}, \pkg{array}, \pkg{amsmath} and \pkg{tikz}. It
+% also loads the Tikz library \pkg{fit}.
%
-% \tikzset{highlight/.style={rectangle,
-% fill=red!15,
-% blend mode = multiply,
-% inner sep=1pt}}
%
%
% \medskip
@@ -110,14 +110,12 @@ version 2005/12/01 or later.
% \begin{bNiceArrayRC}{CCCC}%
% [code-for-last-col=\color{blue}\scriptstyle,
% code-for-first-row=\color{blue}\scriptstyle,
-% code-after = {\tikz \node [highlight,fit = (0-1) (0-4)] {};
-% \tikz \node [highlight,fit = (1-5) (4-5)] {};},
% columns-width = auto]
% C_1 & C_2 & \Cdots & C_n \\
% a_{11} & a_{12} & \Cdots & a_{1n} & L_1 \\
% a_{21} & a_{22} & \Cdots & a_{2n} & L_2 \\
% \Vdots & \Vdots & \Ddots & \Vdots & \Vdots \\
-% a_{n1} & a_{n2} & \Cdots & a_{nn} & L_n \\
+% a_{n1} & a_{n2} & \Cdots & a_{nn} & L_n
% \end{bNiceArrayRC}
% }$
%
@@ -131,8 +129,7 @@ version 2005/12/01 or later.
%
% \medskip
% \begin{minipage}{10cm}
-% For example, consider the following code which uses an environment |{pmatrix}| of \pkg{amsmath} (or
-% \pkg{mathtools}).
+% For example, consider the following code which uses an environment |{pmatrix}| of \pkg{amsmath}.
%
% \smallskip
% \begin{BVerbatim}
@@ -169,7 +166,6 @@ version 2005/12/01 or later.
% 0 & \cdots & 0 & 1
% \end{pmatrix}$
% \end{scope}
-%
%
%
% \section{The environments of this extension}
@@ -192,8 +188,8 @@ version 2005/12/01 or later.
%
% \medskip
% By default, the environments |{NiceMatrix}|, |{pNiceMatrix}|, |{bNiceMatrix}|, |{BNiceMatrix}|, |{vNiceMatrix}|
-% and |{VNiceMatrix}| behave almost exactly as the corresponding environments of \pkg{amsmath} (and
-% \pkg{mathtools}): |{matrix}|, |{pmatrix}|, |{bmatrix}|, |{Bmatrix}|, |{vmatrix}| and |{Vmatrix}|.
+% and |{VNiceMatrix}| behave almost exactly as the corresponding environments of \pkg{amsmath}:
+% |{matrix}|, |{pmatrix}|, |{bmatrix}|, |{Bmatrix}|, |{vmatrix}| and |{Vmatrix}|.
%
%
% \medskip
@@ -284,7 +280,8 @@ version 2005/12/01 or later.
%
% \bigskip
% In the first column of this exemple, there are two instructions |\Vdots| but only one dotted line is drawn (there
-% is no overlapping graphic objects in the resulting \textsc{pdf}).
+% is no overlapping graphic objects in the 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|,
@@ -353,7 +350,7 @@ version 2005/12/01 or later.
%
% Consider the following matrix composed classicaly with the environment |{pmatrix}|.\par\nobreak
% \medskip
-% \begin{BVerbatim}[baseline=c,boxwidth=7cm]
+% \begin{BVerbatim}[baseline=c,boxwidth=8cm]
% $A = \begin{pmatrix}
% a_0 & b \\
% a_1 & \\
@@ -376,7 +373,7 @@ version 2005/12/01 or later.
% \bigskip
% If we add |\vdots| instructions in the second column, the geometry of the matrix is modified.\par\nobreak
% \medskip
-% \begin{BVerbatim}[baseline=c,boxwidth=7cm]
+% \begin{BVerbatim}[baseline=c,boxwidth=8cm]
% $B = \begin{pmatrix}
% a_0 & b \\
% a_1 & \vdots \\
@@ -399,7 +396,7 @@ version 2005/12/01 or later.
% 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
% \medskip
-% \begin{BVerbatim}[baseline=c,boxwidth=7cm]
+% \begin{BVerbatim}[baseline=c,boxwidth=8cm]
% $C = \begin{pNiceMatrix}
% a_0 & b \\
% a_1 & \Vdots \\
@@ -423,7 +420,7 @@ version 2005/12/01 or later.
% line in the second column. It's possible by using the option |nullify-dots| (and only one instruction |\Vdots| is
% necessary).\par\nobreak
% \medskip
-% \begin{BVerbatim}[baseline=c,boxwidth=7cm]
+% \begin{BVerbatim}[baseline=c,boxwidth=8cm]
% $D = \begin{pNiceMatrix}[~emphase#nullify-dots@]
% a_0 & b \\
% a_1 & \Vdots \\
@@ -449,10 +446,11 @@ version 2005/12/01 or later.
% \subsection{The command Hdotsfor}
%
% Some people commonly use the command |\hdotsfor| of \pkg{amsmath} in order to draw horizontal dotted lines in a
-% matrix. In the environments of \pkg{nicematrix}, they should use instead the command |\Hdotsfor| and they will
-% have the same style of dotted lines. We recommand not to use this command in new code since it's more coherent to
-% use exclusively |\Cdots|, |\Vdots|, |\Ddots|, etc. However, it can be useful in adapting existing code,
-% especially when using the option |transparent| (see below).
+% matrix. In the environments of \pkg{nicematrix}, one should use instead |\Hdotsfor| in order to draw dotted lines similar
+% to the other dotted lines drawn by the package \pkg{nicematrix}.
+%
+% As with the other commands of \pkg{nicematrix} (like |\Cdots|, |\Ldots|, |\Vdots|, etc.), the dotted line drawn
+% with |\Hdotsfor| extends until the contents of the cells on both sides.
%
% \medskip
% \begin{BVerbatim}[baseline=c,boxwidth=7cm]
@@ -470,9 +468,29 @@ version 2005/12/01 or later.
% 1 & 2 & 3 & 4 & 5 \\
% \end{pNiceMatrix}$
%
+% \bigskip
+% However, if these cells are empty, the dotted line extends only in the cells specified by the argument of
+% |\Hdotsfor| (by design).
+%
% \medskip
+% \begin{BVerbatim}[baseline=c,boxwidth=7cm]
+% $\begin{pNiceMatrix}
+% 1 & 2 & 3 & 4 & 5 \\
+% & ~emphase#\Hdotsfor{3}@ \\
+% 1 & 2 & 3 & 4 & 5 \\
+% 1 & 2 & 3 & 4 & 5 \\
+% \end{pNiceMatrix}$
+% \end{BVerbatim}
+% $\begin{pNiceMatrix}
+% 1 & 2 & 3 & 4 & 5 \\
+% & \Hdotsfor{3} \\
+% 1 & 2 & 3 & 4 & 5 \\
+% 1 & 2 & 3 & 4 & 5 \\
+% \end{pNiceMatrix}$
+%
+% \bigskip
% The command |\hdotsfor| of \pkg{amsmath} takes an optional argument (between square brackets) which is
-% used for fine tuning of the space beetween two consecutive dots. For homogeneity, the command |\Hdotsfor| has
+% used for fine tuning of the space beetween two consecutive dots. For homogeneity, |\Hdotsfor| has
% also an optional argument but this argument is discarded silently.
%
% \subsection{How to generate the continuous dotted lines transparently}
@@ -492,7 +510,7 @@ version 2005/12/01 or later.
% |\iddots| is not a command of LaTeX but is defined by the package \pkg{nicematrix}. If |mathdots| is loaded, the
% version of |mathdots| is used.} and |\hdotsfor| are redefined within the environments provided by \pkg{nicematrix}
% and behave like |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots|, |\Iddots| and |\Hdotsfor|; the command |\dots| (``automatic
-% dots'' of |amsmath| --- and |mathtools|) is also redefined to behave like |\Ldots|.
+% dots'' of |amsmath|) is also redefined to behave like |\Ldots|.
%
% \item The option |renew-matrix|\par\nobreak
% With this option, the environment |{matrix}| is redefined and behave like |{NiceMatrix}|, and so on for the five
@@ -520,122 +538,6 @@ version 2005/12/01 or later.
% 0 & \cdots & 0 & 1
% \end{pmatrix}$
% \end{scope}
-%
-% \section{The width of the columns}
-% \label{width}
-%
-% In the environments with an explicit preamble (like |{NiceArray}|, |{pNiceArrayC}|, etc.), It's possible to fix the
-% width of a given column with the standard letters |w| and |W| of the package \pkg{array}.
-%
-% \medskip
-% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
-% $\left(\begin{NiceArray}{~emphase#wc{1cm}@CC}
-% 1 & 12 & -123 \\
-% 12 & 0 & 0 \\
-% 4 & 1 & 2
-% \end{NiceArray}\right)$
-% \end{BVerbatim}
-% $\left(\begin{NiceArray}{wc{1cm}CC}
-% 1 & 12 & -123 \\
-% 12 & 0 & 0 \\
-% 4 & 1 & 2
-% \end{NiceArray}\right)$
-%
-%
-% \bigskip
-% It's also possible to fix the width of all the columns of a matrix directly with the option |columns-width| (in
-% all the environments of \pkg{nicematrix}).
-%
-% \medskip
-% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
-% $\begin{pNiceMatrix}[~emphase#columns-width = 1cm@]
-% 1 & 12 & -123 \\
-% 12 & 0 & 0 \\
-% 4 & 1 & 2
-% \end{pNiceMatrix}$
-% \end{BVerbatim}
-% $\begin{pNiceMatrix}[columns-width = 1cm]
-% 1 & 12 & -123 \\
-% 12 & 0 & 0 \\
-% 4 & 1 & 2
-% \end{pNiceMatrix}$
-%
-% \medskip
-% Note that the space inserted between two columns (equal to 2 |\arraycolsep|) is not suppressed.
-%
-% \bigskip
-% It's possible to give the value |auto| to the option |columns-width|: all the columns of the array will
-% have a width equal to the widest cell of the array. \textbf{Two or three compilations may be necessary.}\par\nobreak
-% \medskip
-% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
-% $\begin{pNiceMatrix}[~emphase#columns-width = auto@]
-% 1 & 12 & -123 \\
-% 12 & 0 & 0 \\
-% 4 & 1 & 2
-% \end{pNiceMatrix}$
-% \end{BVerbatim}
-% $\begin{pNiceMatrix}[columns-width = auto]
-% 1 & 12 & -123 \\
-% 12 & 0 & 0 \\
-% 4 & 1 & 2
-% \end{pNiceMatrix}$
-%
-% \bigskip
-% It's possible to fix the width of the columns of all the matrices of a current scope with the command
-% |\NiceMatrixOptions|.\par\nobreak
-% \medskip
-% \begin{BVerbatim}[baseline=c,boxwidth=8.5cm]
-% ~emphase#\NiceMatrixOptions{columns-width=10mm}@
-% $\begin{pNiceMatrix}
-% a & b \\ c & d \\
-% \end{pNiceMatrix}
-% =
-% \begin{pNiceMatrix}
-% 1 & 1245 \\ 345 & 2 \\
-% \end{pNiceMatrix}$
-% \end{BVerbatim}
-% \begin{scope}
-% \NiceMatrixOptions{columns-width=10mm}
-% $\begin{pNiceMatrix}
-% a & b \\
-% c & d \\
-% \end{pNiceMatrix}
-% =
-% \begin{pNiceMatrix}
-% 1 & 1245 \\
-% 345 & 2 \\
-% \end{pNiceMatrix}$
-% \end{scope}
-%
-%
-% \bigskip
-% But it's also possible to fix a zone where all the matrices will have their columns of the same width, equal to
-% the widest cell of all the matrices. This construction uses the environment |{NiceMatrixBlock}| with the option
-% |auto-columns-width|.\footnote{At this time, this is the only usage of the environment |{NiceMatrixBlock}| but
-% it may have other usages in the future.}
-%
-% \medskip
-% \begin{BVerbatim}[baseline=c,boxwidth=8.5cm]
-% ~emphase#\begin{NiceMatrixBlock}[auto-columns-width]@
-% $\begin{pNiceMatrix}
-% a & b \\ c & d \\
-% \end{pNiceMatrix}
-% =
-% \begin{pNiceMatrix}
-% 1 & 1245 \\ 345 & 2 \\
-% \end{pNiceMatrix}$
-% ~emphase#\end{NiceMatrixBlock}@
-% \end{BVerbatim}
-% \begin{NiceMatrixBlock}[auto-columns-width]
-% $\begin{pNiceMatrix}
-% a & b \\ c & d \\
-% \end{pNiceMatrix}
-% =
-% \begin{pNiceMatrix}
-% 1 & 1245 \\ 345 & 2 \\
-% \end{pNiceMatrix}$
-% \end{NiceMatrixBlock}
-%
%
% \section{The Tikz nodes created by nicematrix}
%
@@ -663,10 +565,157 @@ version 2005/12/01 or later.
% \tikz[remember picture,overlay]
% \draw (mymatrix-2-2) circle (2mm) ;
%
-%
% \medskip
% Don't forget the options |remember picture| and |overlay|.
%
+% \bigskip
+% In the following example, we have underlined all the nodes of the matrix.
+% \begin{scope}
+% \tikzset{every node/.style = {fill = red!15, inner sep = 0pt}}
+% \[\begin{pNiceMatrix}
+% a & a + b & a + b + c \\
+% a & a & a + b \\
+% a & a & a
+% \end{pNiceMatrix}\]
+% \end{scope}
+%
+%
+% \bigskip
+% In fact, the package \pkg{nicematrix} can create ``extra nodes''. These new nodes are created if the option
+% |create-extra-nodes| is used. There are two series of extra nodes: the ``medium nodes'' and the ``large nodes''.
+%
+% \medskip
+% The names of the ``medium nodes'' are constructed by adding the suffix ``|-medium|'' to the names of the ``normal
+% nodes''. In the following example, we have underlined the ``medium nodes''. We consider that this example is self-explanatory.
+% \[\begin{pNiceMatrix}
+% [create-extra-nodes,
+% code-after = {\begin{tikzpicture}%
+% [every node/.style = {fill = red!15,
+% blend mode = multiply,
+% inner sep = -\pgflinewidth/2},
+% name suffix = -medium]
+% \node [fit = (1-1)] {} ;
+% \node [fit = (1-2)] {} ;
+% \node [fit = (1-3)] {} ;
+% \node [fit = (2-1)] {} ;
+% \node [fit = (2-2)] {} ;
+% \node [fit = (2-3)] {} ;
+% \node [fit = (3-1)] {} ;
+% \node [fit = (3-2)] {} ;
+% \node [fit = (3-3)] {} ;
+% \end{tikzpicture}}]
+% a & a + b & a + b + c \\
+% a & a & a + b \\
+% a & a & a
+% \end{pNiceMatrix}\]
+%
+%
+% \medskip
+% The names of the ``large nodes'' are constructed by adding the suffix ``|-large|'' to the names of the ``normal
+% nodes''. In the following example, we have underlined the ``large nodes''. We consider that this example is
+% self-explanatory.\footnote{In the environments like |{pNiceArrayC}| and |{pNiceArrayRC}|, there is not ``large
+% nodes'' created in the exterior row and column.}
+%
+% \[\begin{pNiceMatrix}
+% [create-extra-nodes,
+% code-after = {\begin{tikzpicture}%
+% [every node/.style = {blend mode = multiply,
+% inner sep = -\pgflinewidth/2},
+% name suffix = -large]
+% \node [fit = (1-1),fill = red!15] {} ;
+% \node [fit = (1-3),fill = red!15] {} ;
+% \node [fit = (2-2),fill = red!15] {} ;
+% \node [fit = (3-1),fill = red!15] {} ;
+% \node [fit = (3-3),fill = red!15] {} ;
+% \node [fit = (1-2),fill = blue!15] {} ;
+% \node [fit = (2-1),fill = blue!15] {} ;
+% \node [fit = (2-3),fill = blue!15] {} ;
+% \node [fit = (3-2),fill = blue!15] {} ;
+% \end{tikzpicture}}]
+% a & a + b & a + b + c \\
+% a & a & a + b \\
+% a & a & a
+% \end{pNiceMatrix}\]
+%
+%
+% \medskip
+% The ``large nodes'' of the first column and last column may appear too small for some usage. That's why it's
+% possible to use the options |left-margin| and |right-margin| to add space on both sides of the array and also
+% space in the ``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|.}
+% \[\begin{pNiceMatrix}
+% [create-extra-nodes,left-margin,right-margin,
+% code-after = {\begin{tikzpicture}%
+% [every node/.style = {blend mode = multiply,
+% inner sep = -\pgflinewidth/2},
+% name suffix = -large]
+% \node [fit = (1-1),fill = red!15] {} ;
+% \node [fit = (1-3),fill = red!15] {} ;
+% \node [fit = (2-2),fill = red!15] {} ;
+% \node [fit = (3-1),fill = red!15] {} ;
+% \node [fit = (3-3),fill = red!15] {} ;
+% \node [fit = (1-2),fill = blue!15] {} ;
+% \node [fit = (2-1),fill = blue!15] {} ;
+% \node [fit = (2-3),fill = blue!15] {} ;
+% \node [fit = (3-2),fill = blue!15] {} ;
+% \end{tikzpicture}}]
+% a & a + b & a + b + c \\
+% a & a & a + b \\
+% a & a & a
+% \end{pNiceMatrix}\]
+%
+% \medskip
+% It's also possible to add more space on both side of the array with the options |extra-left-margin| and
+% |extra-right-margin|. These margins are not incorporated in the ``large nodes''. In the following example, we
+% have used |extra-left-margin| and |extra-right-margin| with the value $3$~pt.
+% \[\begin{pNiceMatrix}
+% [create-extra-nodes,left-margin,right-margin,extra-right-margin=3pt,extra-left-margin=3pt,
+% code-after = {\begin{tikzpicture}%
+% [every node/.style = {blend mode = multiply,
+% inner sep = -\pgflinewidth/2},
+% name suffix = -large]
+% \node [fit = (1-1),fill = red!15] {} ;
+% \node [fit = (1-3),fill = red!15] {} ;
+% \node [fit = (2-2),fill = red!15] {} ;
+% \node [fit = (3-1),fill = red!15] {} ;
+% \node [fit = (3-3),fill = red!15] {} ;
+% \node [fit = (1-2),fill = blue!15] {} ;
+% \node [fit = (2-1),fill = blue!15] {} ;
+% \node [fit = (2-3),fill = blue!15] {} ;
+% \node [fit = (3-2),fill = blue!15] {} ;
+% \end{tikzpicture}}]
+% a & a + b & a + b + c \\
+% a & a & a + b \\
+% a & a & a
+% \end{pNiceMatrix}\]
+%
+% \medskip
+% In this case, if we want a control over the height of the rows, we can add a |\strut| in each row of the array.
+% \[\begin{pNiceMatrix}
+% [create-extra-nodes,left-margin,right-margin,extra-right-margin=3pt,extra-left-margin=3pt,
+% code-after = {\begin{tikzpicture}%
+% [every node/.style = {blend mode = multiply,
+% inner sep = -\pgflinewidth/2},
+% name suffix = -large]
+% \node [fit = (1-1),fill = red!15] {} ;
+% \node [fit = (1-3),fill = red!15] {} ;
+% \node [fit = (2-2),fill = red!15] {} ;
+% \node [fit = (3-1),fill = red!15] {} ;
+% \node [fit = (3-3),fill = red!15] {} ;
+% \node [fit = (1-2),fill = blue!15] {} ;
+% \node [fit = (2-1),fill = blue!15] {} ;
+% \node [fit = (2-3),fill = blue!15] {} ;
+% \node [fit = (3-2),fill = blue!15] {} ;
+% \end{tikzpicture}}]
+% \strut a & a + b & a + b + c \\
+% \strut a & a & a + b \\
+% \strut a & a & a
+% \end{pNiceMatrix}\]
+%
+% \bigskip
+% We explain below how to fill the nodes created by \pkg{nicematrix}.
+%
% \section{The code-after}
%
% The option |code-after| may be used to give some code that will be excuted after the construction of the matrix
@@ -675,7 +724,7 @@ version 2005/12/01 or later.
% In the |code-after|, the Tikz nodes should be accessed by a name of the form $i$-$j$ (without the prefix of the
% name of the environment).
%
-% Morevover, a special command, called |\line| is available to draw directly dotted lines between nodes.
+% Moreover, a special command, called |\line| is available to draw directly dotted lines between nodes.
%
% \medskip
% \begin{BVerbatim}[baseline=c,boxwidth=12cm]
@@ -700,7 +749,8 @@ version 2005/12/01 or later.
% |L|, |C| and~|R|\footnote{The column types |L|, |C| and |R| are defined locally inside |{NiceArray}| with
% |\newcolumntype| of \pkg{array}. This definition overrides an eventual previous definition.} instead of |l|, |c|
% and |r|. It's possible to use the constructions \verb|w{...}{...}|, \verb|W{...}{...}|, \verb+|+, |>{...}|,
-% |<{...}|, |@{...}|, |!{...}| and |*{n}{...}| but the letters |p|, |m| and |b| should not be used.
+% |<{...}|, |@{...}|, |!{...}| and |*{n}{...}| but the letters |p|, |m| and |b| should not be used.\footnote{In a
+% command |\multicolumn|, one should also use the letters |L|, |C|, |R|.}
%
% \medskip
% The environment |{NiceArray}| accepts the classical options |t|, |c| and |b| of |{array}| but also other options
@@ -755,7 +805,7 @@ version 2005/12/01 or later.
%
% The environment |{pNiceArrayC}| takes a mandatory argument which is the preamble of the array. The types
% of columns available are the same as for the environment |{NiceArray}|. \textbf{However, no specification must be
-% given for the last column.} It will automatically (and necessarily) be a column~|L| column.
+% given for the last column.} It will automatically (and necessarily) be a |L|~column.
%
% A special option, called |code-for-last-col|, specifies tokens that will be inserted before each cell of the last
% column. The option |columns-width| doesn't apply to this external column.
@@ -785,7 +835,7 @@ version 2005/12/01 or later.
%
% \bigskip
% In fact, the environment |{pNiceArrayC}| and its variants are based upon an more general environment, called
-% |{NiceArrayCwithDelims}|. The first two mandatory arguments of this environment are the left and right delimiter
+% |{NiceArrayCwithDelims}|. The first two mandatory arguments of this environment are the left and right delimiters
% used in the construction of the matrix. It's possible to use |{NiceArrayCwithDelims}| if we want to use atypical
% delimiters.
%
@@ -815,10 +865,6 @@ version 2005/12/01 or later.
% environment |{pNiceArrayC}|, no specification must be given for the last column (it will automatically be a |L|
% column).
%
-% For technical reasons, the key |columns-width| is mandatory, with an numerical value (e.g. 1~cm) or with
-% the special value |auto|. This implies that all the columns of an environment |{pNiceArrayRC}| have necessarily
-% the same width.
-%
% A special option, called |code-for-first-row|, specifies tokens that will be inserted before each cell of the
% first row.
%
@@ -826,8 +872,8 @@ version 2005/12/01 or later.
% \begin{BVerbatim}[baseline=c,boxwidth=11cm]
% $\begin{pNiceArrayRC}{CCC}%
% [columns-width = auto,
-% code-for-first-row = {\color{blue}},
-% code-for-last-col = {\color{blue}}]
+% code-for-first-row = \color{blue},
+% code-for-last-col = \color{blue}]
% C_1 & C_2 & C_3 \\
% 1 & 2 & 3 & L_1\\
% 4 & 5 & 6 & L_2\\
@@ -835,27 +881,25 @@ version 2005/12/01 or later.
% \end{pNiceArrayRC}$
% \end{BVerbatim}
% $\begin{pNiceArrayRC}{CCC}[columns-width=auto,
-% code-for-first-row = {\color{blue}},
-% code-for-last-col = {\color{blue}}]
+% code-for-first-row = \color{blue},
+% code-for-last-col = \color{blue}]
% C_1 & C_2 & C_3 \\
% 1 & 2 & 3 & L_1 \\
% 4 & 5 & 6 & L_2 \\
% 7 & 8 & 9 & L_3 \\
% \end{pNiceArrayRC}$
%
-%
-% \bigskip
-% For technical reasons, the first line of the array (which will be composed ``above'' the main matrix)
-% must \emph{not} contain the command |\\| and no verbatim material.
%
% \bigskip
% The first row of an environment |{pNiceArrayRC}| has the number $0$, and not $1$. This number is used for the
% names of the Tikz nodes (the names of these nodes are used, for example, by the command |\line| in |code-after|).
%
+% For technical reasons, it's not possible to use the option of the command |\\| after the first row (the placement
+% of the delimiters would be wrong).
%
% \bigskip
% In fact, the environment |{pNiceArrayRC}| and its variants are based upon an more general environment, called
-% |{NiceArrayRCwithDelims}|. The first two mandatory arguments of this environment are the left and right delimiter
+% |{NiceArrayRCwithDelims}|. The first two mandatory arguments of this environment are the left and right delimiters
% used in the construction of the matrix. It's possible to use |{NiceArrayRCwithDelims}| if we want to use atypical
% delimiters.
%
@@ -877,8 +921,186 @@ version 2005/12/01 or later.
% 7 & 8 & 9
% \end{NiceArrayRCwithDelims}$
%
+%
+% \bigskip
+% If we want to write a linear system, we can use the following code, with a preamble \verb+CCC|C+:
+%
+% \medskip
+% \begin{BVerbatim}[baseline=c,boxwidth=11cm]
+% $\begin{pNiceArrayRC}{~emphase#CCC|C@}
+% C_1 & \Cdots & C_n \\
+% a_{11} & \Cdots & a_{1n} & b_1 \\
+% \Vdots & & \Vdots & \Vdots \\
+% a_{n1} & \Cdots & a_{nn} & b_n \\
+% \end{pNiceArrayRC}$
+% \end{BVerbatim}
+% $\begin{pNiceArrayRC}{CCC|C}
+% C_1 & \Cdots & C_n \\
+% a_{11} & \Cdots & a_{1n} & b_1 \\
+% \Vdots & & \Vdots & \Vdots \\
+% a_{n1} & \Cdots & a_{nn} & b_n \\
+% \end{pNiceArrayRC}$
+%
+% \medskip
+% The resultat may seem disappointing. It's possible to suppress the vertical rule in the first row with the
+% command |\multicolumn| in order to ``reconstruct'' the cell.
+%
+%
+% \bigskip
+% \begin{BVerbatim}[baseline=c,boxwidth=11cm]
+% $\begin{pNiceArrayRC}{CCC|C}
+% C_1 & \Cdots & ~emphase#\multicolumn{1}{C}{C_n}@ \\
+% a_{11} & \Cdots & a_{1n} & b_1 \\
+% \Vdots & & \Vdots & \Vdots \\
+% a_{n1} & \Cdots & a_{nn} & b_n \\
+% \end{pNiceArrayRC}$
+% \end{BVerbatim}
+% $\begin{pNiceArrayRC}{CCC|C}
+% C_1 & \Cdots & \multicolumn{1}{C}{C_n} \\
+% a_{11} & \Cdots & a_{1n} & b_1 \\
+% \Vdots & & \Vdots & \Vdots \\
+% a_{n1} & \Cdots & a_{nn} & b_n
+% \end{pNiceArrayRC}$
+%
+% \bigskip
+% On the other side, we may remark that an horizontal line (with |\hline| or |\hdashline| of \pkg{arydshln})
+% doesn't extend in the ``exterior column'' of an environment like |{pNiceArrayC}| or |{pNiceArrayRC}|.
+%
+% \medskip
+% \begin{BVerbatim}[baseline=c,boxwidth=11cm]
+% $\begin{pNiceArrayC}{CCC}
+% a_{11} & \Cdots & a_{1n} & L_1 \\
+% \Vdots & & \Vdots & \Vdots \\
+% a_{n1} & \Cdots & a_{nn} & L_n \\
+% ~emphase#\hdashline@
+% S_1 & \Cdots & S_n \\
+% \end{pNiceArrayC}$
+% \end{BVerbatim}
+% $\begin{pNiceArrayC}{CCC}
+% a_{11} & \Cdots & a_{1n} & L_1 \\
+% \Vdots & & \Vdots & \Vdots \\
+% a_{n1} & \Cdots & a_{nn} & L_n \\
+% \hdashline
+% S_1 & \Cdots & S_n \\
+% \end{pNiceArrayC}$
%
+%
+% \section{The width of the columns}
+% \label{width}
+%
+% In the environments with an explicit preamble (like |{NiceArray}|, |{pNiceArrayC}|, |{pNiceArrayRC}|, etc.), it's
+% possible to fix the width of a given column with the standard letters |w| and |W| of the package \pkg{array}.
%
+% \medskip
+% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
+% $\left(\begin{NiceArray}{~emphase#wc{1cm}@CC}
+% 1 & 12 & -123 \\
+% 12 & 0 & 0 \\
+% 4 & 1 & 2
+% \end{NiceArray}\right)$
+% \end{BVerbatim}
+% $\left(\begin{NiceArray}{wc{1cm}CC}
+% 1 & 12 & -123 \\
+% 12 & 0 & 0 \\
+% 4 & 1 & 2
+% \end{NiceArray}\right)$
+%
+%
+% \bigskip
+% It's also possible to fix the width of all the columns of a matrix directly with the option |columns-width| (in
+% all the environments of \pkg{nicematrix}).
+%
+% \medskip
+% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
+% $\begin{pNiceMatrix}[~emphase#columns-width = 1cm@]
+% 1 & 12 & -123 \\
+% 12 & 0 & 0 \\
+% 4 & 1 & 2
+% \end{pNiceMatrix}$
+% \end{BVerbatim}
+% $\begin{pNiceMatrix}[columns-width = 1cm]
+% 1 & 12 & -123 \\
+% 12 & 0 & 0 \\
+% 4 & 1 & 2
+% \end{pNiceMatrix}$
+%
+% \medskip
+% Note that the space inserted between two columns (equal to 2 |\arraycolsep|) is not suppressed.
+%
+% \bigskip
+% It's possible to give the value |auto| to the option |columns-width|: all the columns of the array will
+% have a width equal to the widest cell of the array. \textbf{Two or three compilations may be necessary.}\par\nobreak
+% \medskip
+% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
+% $\begin{pNiceMatrix}[~emphase#columns-width = auto@]
+% 1 & 12 & -123 \\
+% 12 & 0 & 0 \\
+% 4 & 1 & 2
+% \end{pNiceMatrix}$
+% \end{BVerbatim}
+% $\begin{pNiceMatrix}[columns-width = auto]
+% 1 & 12 & -123 \\
+% 12 & 0 & 0 \\
+% 4 & 1 & 2
+% \end{pNiceMatrix}$
+%
+% \bigskip
+% It's possible to fix the width of the columns of all the matrices of a current scope with the command
+% |\NiceMatrixOptions|.\par\nobreak
+% \medskip
+% \begin{BVerbatim}[baseline=c,boxwidth=8.5cm]
+% ~emphase#\NiceMatrixOptions{columns-width=10mm}@
+% $\begin{pNiceMatrix}
+% a & b \\ c & d \\
+% \end{pNiceMatrix}
+% =
+% \begin{pNiceMatrix}
+% 1 & 1245 \\ 345 & 2 \\
+% \end{pNiceMatrix}$
+% \end{BVerbatim}
+% \begin{scope}
+% \NiceMatrixOptions{columns-width=10mm}
+% $\begin{pNiceMatrix}
+% a & b \\
+% c & d \\
+% \end{pNiceMatrix}
+% =
+% \begin{pNiceMatrix}
+% 1 & 1245 \\
+% 345 & 2 \\
+% \end{pNiceMatrix}$
+% \end{scope}
+%
+%
+% \bigskip
+% But it's also possible to fix a zone where all the matrices will have their columns of the same width, equal to
+% the widest cell of all the matrices. This construction uses the environment |{NiceMatrixBlock}| with the option
+% |auto-columns-width|.\footnote{At this time, this is the only usage of the environment |{NiceMatrixBlock}| but
+% it may have other usages in the future.}
+%
+% \medskip
+% \begin{BVerbatim}[baseline=c,boxwidth=8.5cm]
+% ~emphase#\begin{NiceMatrixBlock}[auto-columns-width]@
+% $\begin{pNiceMatrix}
+% a & b \\ c & d \\
+% \end{pNiceMatrix}
+% =
+% \begin{pNiceMatrix}
+% 1 & 1245 \\ 345 & 2 \\
+% \end{pNiceMatrix}$
+% ~emphase#\end{NiceMatrixBlock}@
+% \end{BVerbatim}
+% \begin{NiceMatrixBlock}[auto-columns-width]
+% $\begin{pNiceMatrix}
+% a & b \\ c & d \\
+% \end{pNiceMatrix}
+% =
+% \begin{pNiceMatrix}
+% 1 & 1245 \\ 345 & 2 \\
+% \end{pNiceMatrix}$
+% \end{NiceMatrixBlock}
+%
+%
% \section{Technical remarks}
%
% \subsection{Diagonal lines}
@@ -951,11 +1173,9 @@ version 2005/12/01 or later.
%
% \subsection{The ``empty'' cells}
%
-% An instruction like |\Ldots|, |\Cdots|, etc. tries to determine the first non-empty cell on both
-% sides\footnote{If \pkg{nicematrix} can't find these cells, an error |Imposible instruction| is raised. Nevertheless,
-% with the option |silent|, these instructions are discarded silently.}. However, a empty cell is not necessarily a
-% cell with no TeX content (that is to say a cell with no token between the two ampersands~|&|). Indeed, a cell
-% with contents |\hspace*{1cm}| may be considered as empty.
+% An instruction like |\Ldots|, |\Cdots|, etc. tries to determine the first non-empty cells on both sides. However,
+% a empty cell is not necessarily a cell with no TeX content (that is to say a cell with no token between the two
+% ampersands~|&|). Indeed, a cell with contents |\hspace*{1cm}| may be considered as empty.
%
% \interitem
% For \pkg{nicematrix}, the precise rules are as follow.
@@ -977,7 +1197,7 @@ version 2005/12/01 or later.
%
% \medskip
% \item A cell which contains a command |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots| or |\Iddots| and their starred
-% versions is empty. We recall that theses commands should be used alone in a cell.
+% versions 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 |\Hspace| is a command defined by
@@ -986,9 +1206,6 @@ version 2005/12/01 or later.
% with \pkg{nicematrix}.
% % \end{itemize}
%
-% \interitem
-% A dotted line must be delimited by two non-empty cells. If it's not possible to find one of these cells whitin
-% the boundaries of the matrix, an error is issued and the instruction is ignored.
%
% \subsection{The option exterior-arraycolsep}
%
@@ -999,17 +1216,96 @@ version 2005/12/01 or later.
% (perhaps we should instead remove it from array in general, but that's a harder task).} It's possible to suppress
% these spaces for a given environment |{array}| with a construction like |\begin{array}{@{}ccccc@{}}|.}
%
-% The environment |{matrix}| and its variants (|{pmatrix}|, |{vmatrix}|, etc.) of \pkg{amsmath} and \pkg{mathtools}
-% prefer to delete these spaces with explicit instructions |\hskip -\arraycolsep| and |{NiceArray}| does likewise.
+% The environment |{matrix}| and its variants (|{pmatrix}|, |{vmatrix}|, etc.) of \pkg{amsmath} prefer to delete
+% these spaces with explicit instructions |\hskip -\arraycolsep| and |{NiceArray}| does likewise.
%
-% However, the user can change this behaviour with the boolean option |exterior-arraycolsep|. With this option,
-% |{NiceArray}| will insert the same horizontal spaces as the environment |{array}|. This
-% option can be set for a given environment or globally with the command |\NiceMatrixOptions|.
+% However, the user can change this behaviour with the boolean option |exterior-arraycolsep| of the command
+% |\NiceMatrixOptions|. With this option, |{NiceArray}| will insert the same horizontal spaces as the environment
+% |{array}|.
%
+% This option is also for ``compatibility'' since the package \pkg{nicematrix} provides a more precise control with
+% the options |left-margin|, |right-margin|, |extra-left-margin| and |extra-right-margin|.
+%
+%
+% \subsection{A technical problem with the argument of \textbackslash\textbackslash}
+%
+% For technical, reasons, if you use the optional argument of the command |\\|, the vertical space added will also
+% be added to the ``normal'' node corresponding at the previous node.
+%
+% \medskip
+% \begin{BVerbatim}[baseline=c,boxwidth=11cm]
+% \begin{pNiceMatrix}
+% a & \frac AB \\~emphase#[2mm]@
+% b & c
+% \end{pNiceMatrix}
+% \end{BVerbatim}
+% $\begin{pNiceMatrix}
+% [code-after = {\tikz \node [inner sep = 0pt,
+% fill = red!15,
+% blend mode = multiply,
+% fit = (1-2) ] {} ; } ]
+% a & \frac AB \\[2mm]
+% b & c
+% \end{pNiceMatrix}$
+%
+% \bigskip
+% There are two solutions to solve this problem. The first solution is to use a TeX command to insert space between
+% the rows.
+%
+% \medskip
+% \begin{BVerbatim}[baseline=c,boxwidth=11cm]
+% \begin{pNiceMatrix}
+% a & \frac AB \\
+% ~emphase#\noalign{\kern2mm}@
+% b & c
+% \end{pNiceMatrix}
+% \end{BVerbatim}
+% $\begin{pNiceMatrix}
+% [code-after = {\tikz \node [inner sep = 0pt,
+% fill = red!15,
+% blend mode = multiply,
+% fit = (1-2) ] {} ; } ]
+% a & \frac AB \\
+% \noalign{\kern2mm}
+% b & c
+% \end{pNiceMatrix}$
%
-% \section{Examples}
%
% \bigskip
+% The other solution is to use the command |\multicolumn| in the previous cell.
+%
+% \medskip
+% \begin{BVerbatim}[baseline=c,boxwidth=11cm]
+% \begin{pNiceMatrix}
+% a & ~emphase#\multicolumn1C{\frac AB}@ \\[2mm]
+% b & c
+% \end{pNiceMatrix}
+% \end{BVerbatim}
+% $\begin{pNiceMatrix}
+% [code-after = {\tikz \node [inner sep = 0pt,
+% fill = red!15,
+% blend mode = multiply,
+% fit = (1-2) ] {} ; } ]
+% a & \multicolumn1C{\frac AB} \\[2mm]
+% b & c
+% \end{pNiceMatrix}$
+%
+%
+% \subsection{A remark concerning a bug of Tikz}
+%
+% Due to a bug in Tikz, the construction |-- cycle| in a Tikz path is incompatible with the use of |name prefix|
+% and |name suffix|.\footnote{cf. |tex.stackexchange.com/questions/327007/tikz-fill-not-being-drawn-using-named-coordinates|}
+%
+% \bigskip
+% Since |name prefix| is implicitly used in the |code-after| of \pkg{nicematrix}, it's not
+% possible to use |-- cycle| in |code-after|.
+%
+%
+% \section{Examples}
+%
+% \subsection{Dotted lines}
+%
+% \medskip
% A tridiagonal matrix:
%
% \bigskip
@@ -1060,8 +1356,7 @@ version 2005/12/01 or later.
%
% \vspace{2cm}
%
-% An example with |\Iddots|:
-%
+% An example with |\Iddots|: \par\nobreak
% \bigskip
% \begin{BVerbatim}[baseline=c]
% $\begin{pNiceMatrix}
@@ -1079,29 +1374,72 @@ version 2005/12/01 or later.
% 1 & 0 & \Cdots & 0
% \end{pNiceMatrix}$
%
-% \vspace{2cm}
%
-% An example for the resultant of two polynoms :
+% \vspace{2cm}
+% An example with |\multicolumn|:\par\nobreak
+% \bigskip
+% \begin{BVerbatim}
+% \begin{pNiceMatrix}[nullify-dots]
+% 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10\\
+% 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10\\
+% \Cdots & & ~emphase#\multicolumn{6}{C}{10 \text{ other rows}}@ & \Cdots \\
+% 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10
+% \end{pNiceMatrix}
+% \end{BVerbatim}
+%
+% \bigskip
+% \[\begin{pNiceMatrix}[nullify-dots]
+% 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10\\
+% 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10\\
+% \Cdots & & \multicolumn{6}{C}{10 \text{ other rows}} & \Cdots \\
+% 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10
+% \end{pNiceMatrix}\]
+%
+% \vspace{2cm}
+% An example with |\Hdotsfor|:\par\nobreak
+% \bigskip
+% \begin{BVerbatim}[baseline=c,boxwidth=11cm]
+% \begin{pNiceMatrix}[nullify-dots]
+% 0 & 1 & 1 & 1 & 1 & 0 \\
+% 0 & 1 & 1 & 1 & 1 & 0 \\
+% \Vdots & ~emphase#\Hdotsfor{4}@ & \Vdots \\
+% & ~emphase#\Hdotsfor{4}@ & \\
+% & ~emphase#\Hdotsfor{4}@ & \\
+% & ~emphase#\Hdotsfor{4}@ & \\
+% 0 & 1 & 1 & 1 & 1 & 0
+% \end{pNiceMatrix}
+% \end{BVerbatim}
+% $\begin{pNiceMatrix}[nullify-dots]
+% 0 & 1 & 1 & 1 & 1 & 0 \\
+% 0 & 1 & 1 & 1 & 1 & 0 \\
+% \Vdots & \Hdotsfor{4} & \Vdots \\
+% & \Hdotsfor{4} & \\
+% & \Hdotsfor{4} & \\
+% & \Hdotsfor{4} & \\
+% 0 & 1 & 1 & 1 & 1 & 0
+% \end{pNiceMatrix}$
%
+% \vspace{2cm}
+% An example for the resultant of two polynoms (the dashed line has been drawn with \pkg{arydshln}):\par\nobreak
% \bigskip
% \begin{BVerbatim}
% \setlength{\extrarowheight}{1mm}
-% \[\begin{vNiceMatrix}[columns-width=6mm]
-% a_0 & && &b_0 & & \\
-% a_1 &\Ddots && &b_1 &\Ddots & \\
-% \Vdots &\Ddots && &\Vdots &\Ddots &b_0 \\
-% a_p & &&a_0 & & &b_1 \\
-% &\Ddots &&a_1 &b_q & &\Vdots\\
-% & &&\Vdots & &\Ddots & \\
-% & &&a_p & & &b_q \\
-% \end{vNiceMatrix}\]
+% \[\begin{NiceArray}{|CCCC:CCC|}[columns-width=6mm]
+% a_0 & && &b_0 & & \\
+% a_1 &\Ddots&& &b_1 &\Ddots& \\
+% \Vdots&\Ddots&& &\Vdots &\Ddots&b_0 \\
+% a_p & &&a_0 & & &b_1 \\
+% &\Ddots&&a_1 &b_q & &\Vdots\\
+% & &&\Vdots & &\Ddots& \\
+% & &&a_p & & &b_q \\
+% \end{NiceArray}\]
% \end{BVerbatim}
%
% \bigskip
%
% \begin{scope}
% \setlength{\extrarowheight}{1mm}
-% \[\begin{vNiceMatrix}[columns-width=6mm]
+% \[\begin{NiceArray}{|CCCC:CCC|}[columns-width=6mm]
% a_0 & && &b_0 & & \\
% a_1 &\Ddots&& &b_1 &\Ddots& \\
% \Vdots&\Ddots&& &\Vdots &\Ddots&b_0 \\
@@ -1109,12 +1447,14 @@ version 2005/12/01 or later.
% &\Ddots&&a_1 &b_q & &\Vdots\\
% & &&\Vdots & &\Ddots& \\
% & &&a_p & & &b_q \\
-% \end{vNiceMatrix}\]
+% \end{NiceArray}\]
% \end{scope}
%
%
-% \vspace{2cm}
-% In the following example, we use the environment |{NiceMatrixBlock}| with the option |auto-columns-width| because
+% \subsection{Width of the columns}
+%
+% \medskip
+% In the following example, we use |{NiceMatrixBlock}| with the option |auto-columns-width| because
% we want the same automatic width for all the columns of the matrices.
%
% \bigskip
@@ -1193,32 +1533,104 @@ version 2005/12/01 or later.
% \end{NiceMatrixBlock}
% \end{multicols}
%
-% \vspace{2cm}
+%
+% \subsection{How to highlight cells of the matrix}
+%
+% \medskip
+% In order to highlight a cell of a matrix, it's possible to ``draw'' one of the correspond nodes (the ``normal
+% node'', the ``medium node'' or the ``large node''). In the following example, we use the ``large nodes'' of the
+% diagonal of the matrix (with the Tikz key ``|name suffix|'', it's easy to use the ``large nodes''). In order to
+% have the continuity of the lines, we have to set |inner sep = -\pgflinewidth/2|.
+%
+% \begin{Verbatim}
+% $\left(\,\begin{NiceArray}{>{\strut}CCCC}
+% [create-extra-nodes,left-margin,right-margin,
+% code-after = {\begin{tikzpicture}
+% [~emphase#name suffix = -large@,
+% every node/.style = {draw,
+% ~emphase#inner sep = -\pgflinewidth/2@}]
+% \node [fit = (1-1)] {} ;
+% \node [fit = (2-2)] {} ;
+% \node [fit = (3-3)] {} ;
+% \node [fit = (4-4)] {} ;
+% \end{tikzpicture}}]
+% a_{11} & a_{12} & a_{13} & a_{14} \\
+% a_{21} & a_{22} & a_{23} & a_{24} \\
+% a_{31} & a_{32} & a_{33} & a_{34} \\
+% a_{41} & a_{42} & a_{43} & a_{44}
+% \end{NiceArray}\,\right)$
+% \end{Verbatim}
%
-% In the following example, we want to highlight a row of the matrix. To do so, we create a rectangular Tikz node
-% which encompasses the nodes of the second row with the Tikz library |fit|. This Tikz node is filled
-% after the construction of the matrix. In order to see the text \emph{under} this node, we have to use
-% transparency with the |blend mode| equal to |multiply|.
+%
+% \[\left(\,\begin{NiceArray}{>{\strut}CCCC}
+% [create-extra-nodes,left-margin,right-margin,
+% code-after = {\begin{tikzpicture}[name suffix = -large,
+% every node/.style = {draw,
+% inner sep = -\pgflinewidth/2}]
+% \node [fit = (1-1)] {} ;
+% \node [fit = (2-2)] {} ;
+% \node [fit = (3-3)] {} ;
+% \node [fit = (4-4)] {} ;
+% \end{tikzpicture}}]
+% a_{11} & a_{12} & a_{13} & a_{14} \\
+% a_{21} & a_{22} & a_{23} & a_{24} \\
+% a_{31} & a_{32} & a_{33} & a_{34} \\
+% a_{41} & a_{42} & a_{43} & a_{44}
+% \end{NiceArray}\,\right)\]
%
+%
+% \vspace{1cm}
+% The package \pkg{nicematrix} is constructed upon the environment |{array}| and, therefore, it's possible to use
+% the package \pkg{colortbl} in the environments of \pkg{nicematrix}.
+%
+% \medskip
+% \begin{BVerbatim}[baseline=c]
+% $\begin{bNiceMatrix}
+% 0 & \Cdots & 0 \\
+% ~emphase#\rowcolor{red!15}@ 1 & \Cdots & 1 \\
+% 0 & \Cdots & 0 \\
+% \end{bNiceMatrix}$
+% \end{BVerbatim}
+% \hspace{2cm}
+% $\begin{bNiceMatrix}
+% 0 & \Cdots & 0 \\
+% \rowcolor{red!15} 1 & \Cdots & 1 \\
+% 0 & \Cdots & 0 \\
+% \end{bNiceMatrix}$
+%
+% \medskip
+% The result may be disappointing. We therefore propose another method to highlight a row of the matrix. We
+% create a rectangular Tikz node which encompasses the nodes of the second row with the Tikz library \pkg{fit}. This
+% Tikz node is filled after the construction of the matrix. In order to see the text \emph{under} this node, we
+% have to use transparency with the |blend mode| equal to |multiply|. Warning: some \textsc{pdf} readers are not
+% able to render transparency correctly.
+%
+% \tikzset{highlight/.style={rectangle,
+% fill=red!15,
+% blend mode = multiply,
+% rounded corners = 0.5 mm,
+% inner sep=1pt}}
+%
% \medskip
% \begin{Verbatim}
% \tikzset{highlight/.style={rectangle,
% fill=red!15,
% ~emphase#blend mode = multiply@,
+% rounded corners = 0.5 mm,
% inner sep=1pt}}
%
-% $\begin{pNiceMatrix}[~emphase#code-after = {\tikz \node[highlight, fit = (2-1) (2-3)] {} ;}@]
+% $\begin{bNiceMatrix}[~emphase#code-after = {\tikz \node[highlight, fit = (2-1) (2-3)] {} ;}@]
% 0 & \Cdots & 0 \\
% 1 & \Cdots & 1 \\
% 0 & \Cdots & 0 \\
-% \end{pNiceMatrix}$
+% \end{bNiceMatrix}$
% \end{Verbatim}
%
-% \[\begin{pNiceMatrix}[code-after = {\tikz \node[highlight, fit = (2-1) (2-3)] {} ;}]
+% \[\begin{bNiceMatrix}[code-after = {\tikz \node[highlight, fit = (2-1) (2-3)] {} ;}]
% 0 & \Cdots & 0 \\
% 1 & \Cdots & 1 \\
% 0 & \Cdots & 0 \\
-% \end{pNiceMatrix}\]
+% \end{bNiceMatrix}\]
%
%
% \bigskip
@@ -1226,7 +1638,7 @@ version 2005/12/01 or later.
% following code, in the preamble, should activate blend modes in this way of compilation.
%
%
-%
+% \begin{scope} \small
% |\ExplSyntaxOn|
%
% |\makeatletter|
@@ -1240,6 +1652,173 @@ version 2005/12/01 or later.
% |\makeatother|
%
% |\ExplSyntaxOff|
+% \end{scope}
+%
+% \vspace{1cm}
+% Considerer now the following matrix which we have named |example|.
+%
+% \medskip
+% \begin{Verbatim}
+% $\begin{pNiceArrayC}{CCC}[~emphase#name=example@,create-extra-nodes]
+% a & a + b & a + b + c & L_1\\
+% a & a & a + b & L_2 \\
+% a & a & a & L_3
+% \end{pNiceArrayC}$
+% \end{Verbatim}
+%
+% \[\begin{pNiceArrayC}{CCC}
+% a & a + b & a + b + c & L_1\\
+% a & a & a + b & L_2 \\
+% a & a & a & L_3
+% \end{pNiceArrayC}\]
+%
+% \bigskip
+% If we want to highlight each row of this matrix, we can use the previous technique three times.
+%
+% \begin{Verbatim}
+% \tikzset{myoptions/.style={remember picture,
+% overlay,
+% name prefix = example-,
+% every node/.style = {fill = red!15,
+% blend mode = multiply,
+% inner sep = 0pt}}}
+% \end{Verbatim}
+%
+%
+% \tikzset{myoptions/.style={remember picture,
+% overlay,
+% name prefix = example-,
+% every node/.style = {fill = red!15,
+% blend mode = multiply,
+% inner sep = 0pt}}}
+%
+% \begin{Verbatim}
+% \begin{tikzpicture}[myoptions]
+% \node [fit = (1-1) (1-3)] {} ;
+% \node [fit = (2-1) (2-3)] {} ;
+% \node [fit = (3-1) (3-3)] {} ;
+% \end{tikzpicture}
+% \end{Verbatim}
+%
+% \medskip
+% We obtain the following matrix.
+%
+% \[\begin{pNiceArrayC}{CCC}
+% [create-extra-nodes,
+% code-after = {\begin{tikzpicture}[every node/.style = {fill = red!15,
+% blend mode = multiply,
+% inner sep = 0pt}]
+% \node [fit = (1-1) (1-3)] {} ;
+% \node [fit = (2-1) (2-3)] {} ;
+% \node [fit = (3-1) (3-3)] {} ;
+% \end{tikzpicture}}]
+% a & a + b & a + b + c & L_1\\
+% a & a & a + b & L_2 \\
+% a & a & a & L_3
+% \end{pNiceArrayC}\]
+%
+% \medskip
+% The result may seem disappointing. We can improve it by using the ``medium nodes'' instead of the ``normal nodes''.
+%
+% \begin{Verbatim}
+% \begin{tikzpicture}[myoptions, ~emphase#name suffix = -medium@]
+% \node [fit = (1-1) (1-3)] {} ;
+% \node [fit = (2-1) (2-3)] {} ;
+% \node [fit = (3-1) (3-3)] {} ;
+% \end{tikzpicture}
+% \end{Verbatim}
+%
+% \medskip
+% We obtain the following matrix.
+%
+% \[\begin{pNiceArrayC}{CCC}
+% [create-extra-nodes,
+% code-after = {\begin{tikzpicture}[every node/.style = {fill = red!15,
+% blend mode = multiply,
+% inner sep = 0pt},
+% name suffix = -medium]
+% \node [fit = (1-1) (1-3)] {} ;
+% \node [fit = (2-1) (2-3)] {} ;
+% \node [fit = (3-1) (3-3)] {} ;
+% \end{tikzpicture}}]
+% a & a + b & a + b + c & L_1\\
+% a & a & a + b & L_2 \\
+% a & a & a & L_3
+% \end{pNiceArrayC}\]
+%
+%
+% \vspace{1cm}
+%
+% In the following example, we use the ``large nodes'' to highlight a zone of the matrix.\par\nobreak
+% \begin{Verbatim}
+% \left(\,\begin{NiceArray}{>{\strut}CCCC}
+% [create-extra-nodes,left-margin,right-margin,
+% code-after = {\tikz \path [~emphase#name suffix = -large@,
+% fill = red!15,
+% blend mode = multiply]
+% (1-1.north west)
+% |- (2-2.north west)
+% |- (3-3.north west)
+% |- (4-4.north west)
+% |- (4-4.south east)
+% |- (1-1.north west) ; } ]
+% A_{11} & A_{12} & A_{13} & A_{14} \\
+% A_{21} & A_{22} & A_{23} & A_{24} \\
+% A_{31} & A_{32} & A_{33} & A_{34} \\
+% A_{41} & A_{42} & A_{43} & A_{44}
+% \end{NiceArray}\,\right)
+% \end{Verbatim}
+%
+% \[\left(\,\begin{NiceArray}{>{\strut}CCCC}
+% [create-extra-nodes,left-margin,right-margin,
+% code-after = {\tikz \path [name suffix = -large,
+% fill = red!15,
+% blend mode = multiply]
+% (1-1.north west)
+% |- (2-2.north west)
+% |- (3-3.north west)
+% |- (4-4.north west)
+% |- (4-4.south east)
+% |- (1-1.north west) ; } ]
+% A_{11} & A_{12} & A_{13} & A_{14} \\
+% A_{21} & A_{22} & A_{23} & A_{24} \\
+% A_{31} & A_{32} & A_{33} & A_{34} \\
+% A_{41} & A_{42} & A_{43} & A_{44}
+% \end{NiceArray}\,\right)\]
+%
+%
+% \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}
+% \left(\begin{NiceArray}{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{NiceArray}\right)
+% \end{Verbatim}
+%
+%
+% \[D = \left(\begin{NiceArray}{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{NiceArray}\right)\]
+%
+%
+%
%
% \section{Implementation}
%
@@ -1248,8 +1827,7 @@ version 2005/12/01 or later.
% \smallskip
% However, when the option |renew-dots| is used, the commands |\cdots|, |\ldots|, |\dots|, |\vdots|, |\ddots| and
% |\iddots| are redefined in the environments provided by \pkg{nicematrix} as explained previously. In the same way,
-% if the option |renew-matrix| is used, the environment |{matrix}| of \pkg{amsmath} (and \pkg{mathtools}) is
-% redefined.
+% if the option |renew-matrix| is used, the environment |{matrix}| of \pkg{amsmath} is redefined.
%
% \smallskip
% On the other hand, the environment |{array}| is never redefined.
@@ -1264,6 +1842,16 @@ version 2005/12/01 or later.
%
% \subsection{Declaration of the package and extensions loaded}
%
+% First, \pkg{tikz} and the Tikz library |fit| are loaded before the |\ProvidesExplPackage|.
+% They are loaded this way because |\usetifkzlibrary| in |expl3| code fails.\footnote{cf.
+% |tex.stackexchange.com/questions/57424/using-of-usetikzlibrary-in-an-expl3-package-fails|}
+%
+%
+% \begin{macrocode}
+\RequirePackage{tikz}
+\usetikzlibrary{fit}
+% \end{macrocode}
+%
% We give the traditionnal declaration of a package written with |expl3|:
% \begin{macrocode}
\RequirePackage{l3keys2e}
@@ -1271,28 +1859,42 @@ version 2005/12/01 or later.
{nicematrix}
{\myfiledate}
{\myfileversion}
- {Draws nice dotted lines in matrix environments}
+ {Several features to improve the typesetting of mathematical matrices with TikZ}
% \end{macrocode}
%
% The command for the treatment of the options of |\usepackage| is at the end of this package for technical reasons.
%
% \bigskip
-% We load \pkg{array}, \pkg{mathtools} (\pkg{mathtools} may be considered as the successor of \pkg{amsmath}) and \pkg{tikz}.
+% We load \pkg{array} and \pkg{amsmath}.
% \begin{macrocode}
\RequirePackage{array}
-\RequirePackage{mathtools}
-\RequirePackage{tikz}
+\RequirePackage{amsmath}
% \end{macrocode}
%
% \bigskip
% The package \pkg{xparse} will be used to define the environment |{NiceMatrix}|, its variants and the
% document-level commands (|\NiceMatrixOptions|, etc.).
-% \begin{macrocode}
+% \begin{macrocode}
\RequirePackage{xparse}
% \end{macrocode}
%
% \subsection{Technical definitions}
+%
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_msg_error:n
+ {\msg_error:nn {nicematrix} {#1}}
+\cs_new_protected:Nn \@@_msg_error:nn
+ {\msg_error:nn {nicematrix} {#1} {#2}}
+% \end{macrocode}
%
+% \medskip
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_bool_new:N
+ {\bool_if_exist:NTF #1
+ {\bool_set_false:N #1}
+ {\bool_new:N #1}}
+% \end{macrocode}
+%
% First, we define a command |\iddots| similar to |\ddots| ($\ddots$) but with dots going forward ($\iddots$). We
% use |\ProvideDocumentCommand| of \pkg{xparse}, and so, if the command |\iddots| has already been defined (for
% example by the package \pkg{mathdots}), we don't define it again.
@@ -1311,17 +1913,6 @@ version 2005/12/01 or later.
%
% This definition is a variant of the standard definition of |\ddots|.
%
-% \bigskip
-% In the environment |{NiceMatrix}|, the command |\multicolumn| will be linked to the following command
-% |\@@_multicolumn:nn| but only if the option |renew-matrix| is not set. Indeed, if the option |renew-matrix| is used,
-% we want to let the possibility to the user to use |\multicolumn| in some matrices without dotted lines and to
-% have the automatic dotted lines of \pkg{nicematrix} in other matrices.
-% \begin{macrocode}
-\cs_new_protected:Nn \@@_multicolumn:nn
- {\msg_error:nn {nicematrix} {Multicolumn~forbidden}}
-% \end{macrocode}
-% This command |\@@_multicolumn:nn| takes two arguments, and therefore, the first two arguments of |\column| will
-% be gobbled.
%
% \bigskip
% The following counter will count the environments |{NiceArray}|. The value of this counter will be used to
@@ -1339,47 +1930,40 @@ version 2005/12/01 or later.
%
% \bigskip
% The sequence |\g_@@_names_seq| will be the list of all the names of environments used (via the option |name|) in
-% the document : two environments must not have the same name.
+% the document: two environments must not have the same name.
% \begin{macrocode}
\seq_new:N \g_@@_names_seq
% \end{macrocode}
%
% \bigskip
-% The integer |\l_@@_number_of_first_row_int| is the number of the first row of the array. With a value of $0$ (the
-% default), the first row of the array will have the number~$1$. Within the environment |{NiceArrayRC}|, we will give
-% the value $-1$ to |\l_@@_number_of_first_row_int| and, therefore, the first row of the array will have the number~$0$.
+% The integer |\l_@@_nb_first_row_int| is the number of the first row of the array. The default value is $1$, but,
+% in the environments like |{pNiceArrayRC}|, the value will be~$0$.
% \begin{macrocode}
-\int_new:N \l_@@_number_of_first_row_int
+\int_new:N \l_@@_nb_first_row_int
+\int_set:Nn \l_@@_nb_first_row_int 1
% \end{macrocode}
%
% \bigskip
-% The flag |\l_@@_direct_NiceArray_bool| will indicate if the current environment |{NiceArray}| is ``direct'' : that
-% means that it is not encompassed in another environment of the extension \pkg{nicematrix} like |{NiceMatrix}| or
-% |{pNiceArrayC}|.
+% The flag |\l_@@_exterior_column_bool| will indicate if we are in an environment of the type of |{pNiceArrayC}| or
+% |{pNiceArrayRC}|. It will be used for the creation of the ``large nodes''.
% \begin{macrocode}
-\bool_new:N \l_@@_direct_NiceArray_bool
-\bool_set_true:N \l_@@_direct_NiceArray_bool
+\bool_new:N \l_@@_exterior_column_bool
% \end{macrocode}
%
-% \bigskip
-% The token list |\l_@@_code_for_cell_tl| is a code that will be inserted in the beginning of each cell of the
-% array (before the symbol |$| of the mathematical mode).
-% \begin{macrocode}
-\tl_new:N \l_@@_code_for_cell_tl
-% \end{macrocode}
-%
+% \bigskip
% \subsection{The options}
%
% The token list |\l_@@_pos_env_tl| will contain one of the three values |t|, |c| or |b| and will indicate the
-% position of the environment as in the option of the environment |{array}|. For the environment |{NiceMatrix}|
-% (and its variants) and |{pNiceArrayC}| (and its variants), the value will programmatically be fixed to |c|. For the
+% position of the environment as in the option of the environment |{array}|. For the environment |{pNiceMatrix}|,
+% |{pNiceArrayC}|,|{pNiceArrayRC}| and their variants, the value will programmatically be fixed to |c|. For the
% environment |{NiceArray}|, however, the three values |t|, |c| and |b| are possible.
% \begin{macrocode}
\tl_new:N \l_@@_pos_env_tl
\tl_set:Nn \l_@@_pos_env_tl c
% \end{macrocode}
%
-% The boolean |\l_@@_exterior_arraycolsep_bool| corresponds to the option |exterior-arraycolsep|. If this option is
+% \bigskip
+% The flag |\l_@@_exterior_arraycolsep_bool| corresponds to the option |exterior-arraycolsep|. If this option is
% set, a space equal to |\arraycolsep| will be put on both sides of an environment |{NiceArray}| (but neither for
% |{NiceMatrix}|, |{pNiceArrayC}|, |{pNiceArrayRC}| and their variants even if these environments rely upon |{NiceArray}|).
% \begin{macrocode}
@@ -1402,11 +1986,6 @@ version 2005/12/01 or later.
\bool_new:N \l_@@_nullify_dots_bool
% \end{macrocode}
%
-% \bigskip
-% The flag |\l_@@_renew_matrix_bool| will be raised if the option |renew-matrix| is used.
-% \begin{macrocode}
-\bool_new:N \l_@@_renew_matrix_bool
-% \end{macrocode}
%
% \bigskip
% The following flag will be used when the current options specify that all the columns of the array must have the
@@ -1423,14 +2002,44 @@ version 2005/12/01 or later.
\tl_new:N \l_@@_code_for_last_col_tl
% \end{macrocode}
%
-
% \bigskip
-% The token list |\g_@@_name_tl| will contain the optional name of the environment : this name can be used to
-% access to the Tikz nodes created in the array from outside the environment. This variable is global for technical
-% reasons (some commands will be executed in an |\aftergroup| because we don't want to patch the commands of the
-% package \pkg{array}).
+% We don't want to patch any existing code. That's why some code must be executed in a |\aftergroup|. That's why
+% the parameters used in that code must be transfered outside the current group. To do this, we copy those
+% quantities in global variables just before the |\aftergroup|. Therefore, for those quantities, we have two
+% parameters, one local and one global. For example, we have |\l_@@_name_tl| and |\g_@@_name_tl|.
+%
+% \bigskip
+% The token list |\l_@@_name_tl| will contain the optional name of the environment: this name can be used to
+% access to the Tikz nodes created in the array from outside the environment.
% \begin{macrocode}
\tl_new:N \g_@@_name_tl
+\tl_new:N \l_@@_name_tl
+% \end{macrocode}
+%
+% \bigskip
+% The boolean |\l_@@_extra_nodes_bool| will be used to indicate wether the ``medium nodes'' and ``large nodes'' are
+% created in the array.
+% \begin{macrocode}
+\bool_new:N \l_@@_extra_nodes_bool
+\bool_new:N \g_@@_extra_nodes_bool
+% \end{macrocode}
+%
+% \bigskip
+% The dimensions |\l_@@_left_margin_dim| and |\l_@@_right_margin_dim| correspond to the options |left-margin| and |right-margin|.
+% \begin{macrocode}
+\dim_new:N \l_@@_left_margin_dim
+\dim_new:N \l_@@_right_margin_dim
+\dim_new:N \g_@@_left_margin_dim
+\dim_new:N \g_@@_right_margin_dim
+% \end{macrocode}
+%
+% \bigskip
+% The dimensions |\l_@@_extra_left_margin_dim| and |\l_@@_extra_right_margin_dim| correspond to the options
+% |extra-left-margin| and |extra-right-margin|.
+% \begin{macrocode}
+\dim_new:N \l_@@_extra_left_margin_dim
+\dim_new:N \l_@@_extra_right_margin_dim
+\dim_new:N \g_@@_extra_right_margin_dim
% \end{macrocode}
%
% \bigskip
@@ -1458,8 +2067,7 @@ version 2005/12/01 or later.
% With the option |renew-matrix|, the environment |{matrix}| of \pkg{amsmath} and its variants are redefined to
% behave like the environment |{NiceMatrix}| and its variants.
% \begin{macrocode}
- renew-matrix .code:n = {\cs_set_eq:NN \env@matrix \NiceMatrix
- \bool_set_true:N \l_@@_renew_matrix_bool},
+ renew-matrix .code:n = \@@_renew_matrix:,
renew-matrix .value_forbidden:n = true,
RenewMatrix .meta:n = renew-matrix,
transparent .meta:n = {renew-dots,renew-matrix},
@@ -1477,17 +2085,6 @@ version 2005/12/01 or later.
NullifyDots .meta:n = nullify-dots,
% \end{macrocode}
%
-%
-% \bigskip
-% With the option |silent|, no error is generated for the impossible instructions. This option can be useful when
-% adapting an existing code.
-% \begin{macrocode}
- silent .code:n = {\msg_redirect_name:nnn {nicematrix}
- {Impossible~instruction}
- {none}} ,
- silent .value_forbidden:n = true,
- Silent .meta:n = silent,
-% \end{macrocode}
%
% \bigskip
% The following option is only for the environment |{pNiceArrayC}| and its variants. It will contain code inserted
@@ -1507,20 +2104,33 @@ version 2005/12/01 or later.
% \end{macrocode}
%
% \bigskip
-% If the option |columns-width| is used, all the columns will have the same width. In |\NiceMatrixOptions|, the
-% special value |auto| is not available.
+% If the option |columns-width| is used, all the columns will have the same width.
+%
+% In |\NiceMatrixOptions|, the special value |auto| is not available.
% \begin{macrocode}
- columns-width .code:n = \str_if_eq:nnTF {#1} {auto}
- {\msg_error:nn {nicematrix}
- {Option~auto~for~columns-width}}
- {\dim_set:Nn \l_@@_columns_width_dim {#1}},
+ columns-width .code:n = \str_if_eq:nnTF {#1} {auto}
+ {\@@_msg_error:n {Option~auto~for~columns-width}}
+ {\dim_set:Nn \l_@@_columns_width_dim {#1}},
% \end{macrocode}
%
% \bigskip
% \begin{macrocode}
- unknown .code:n = \msg_error:nn {nicematrix} {Unknown~key~for~NiceMatrixOptions}}
+ create-extra-nodes .bool_set:N = \l_@@_extra_nodes_bool,
+ create-extra-nodes .default:n = true,
% \end{macrocode}
%
+% \bigskip
+% \begin{macrocode}
+ left-margin .dim_set:N = \l_@@_left_margin_dim,
+ left-margin .default:n = \arraycolsep,
+ right-margin .dim_set:N = \l_@@_right_margin_dim,
+ right-margin .default:n = \arraycolsep,
+% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+ unknown .code:n = \@@_msg_error:n {Unknown~key~for~NiceMatrixOptions}}
+% \end{macrocode}
% \begin{macrocode}
\msg_new:nnnn {nicematrix}
{Unknown~key~for~NiceMatrixOptions}
@@ -1531,10 +2141,12 @@ version 2005/12/01 or later.
{The~available~keys~are~(in~alphabetic~order):~
code-for-last-col,~
exterior-arraycolsep,~
+ left-margin,~
nullify-dots,~
parallelize-diags,~
renew-dots,~
- renew-matrix~
+ renew-matrix,~
+ right-margin,~
and~transparent}
% \end{macrocode}
%
@@ -1564,7 +2176,7 @@ version 2005/12/01 or later.
nullify-dots .bool_set:N = \l_@@_nullify_dots_bool ,
nullify-dots .default:n = true,
% \end{macrocode}
-% The option |columns-width| is the width of the columns it we want the same width for all the columns of the
+% The option |columns-width| is the width of the columns if we want the same width for all the columns of the
% array. A value of 0~pt means that the width of the column will be the natural width of the column.
% \begin{macrocode}
columns-width .code:n = \str_if_eq:nnTF {#1} {auto}
@@ -1572,20 +2184,30 @@ version 2005/12/01 or later.
\l_@@_auto_columns_width_bool}
{\dim_set:Nn \l_@@_columns_width_dim {#1}},
name .code:n = {\seq_if_in:NnTF \g_@@_names_seq {#1}
- {\msg_error:nnn {nicematrix}
- {Duplicate~name}
- {#1}}
+ {\@@_msg_error:nn {Duplicate~name} {#1}}
{\seq_gput_left:Nn \g_@@_names_seq {#1}}
- \tl_gset:Nn \g_@@_name_tl {#1}},
+ \tl_set:Nn \l_@@_name_tl {#1}},
name .value_required:n = true,
-% \end{macrocode}
-% Since we don't want to modify or patch any existing code, the ``code after'' will be inserted with an
-% |\aftergroup|. Thus, we can't use a local variable for the ``code after'' and that's why we use a global variable.
-% \begin{macrocode}
- code-after .tl_gset:N = \g_@@_code_after_tl,
+ code-after .tl_set:N = \l_@@_code_after_tl,
code-after .initial:n = \c_empty_tl,
code-after .value_required:n = true,
- unknown .code:n = \msg_error:nn {nicematrix} {Unknown~option~for~NiceMatrix}}
+% \end{macrocode}
+%
+% The key |create-extra-nodes| indicates wether the ``medium nodes'' and ``large nodes'' will be created for each
+% cell of the array.
+% \begin{macrocode}
+ create-extra-nodes .bool_set:N = \l_@@_extra_nodes_bool,
+ create-extra-nodes .default:n = true,
+% \end{macrocode}
+%
+% \begin{macrocode}
+ left-margin .dim_set:N = \l_@@_left_margin_dim,
+ left-margin .default:n = \arraycolsep,
+ right-margin .dim_set:N = \l_@@_right_margin_dim,
+ right-margin .default:n = \arraycolsep,
+ extra-left-margin .dim_set:N = \l_@@_extra_left_margin_dim,
+ extra-right-margin .dim_set:N = \l_@@_extra_right_margin_dim,
+ unknown .code:n = \@@_msg_error:n {Unknown~option~for~NiceMatrix}}
% \end{macrocode}
%
% \begin{macrocode}
@@ -1598,14 +2220,32 @@ version 2005/12/01 or later.
{The~available~options~are~(in~alphabetic~order):~
code-after,~
columns-width,~
+ create-extra-nodes,~
+ extra-left-margin,~
+ extra-right-margin,~
+ left~margin,~
name,~
nullify-dots,~
- parallelize-diags~
- and~renew-dots.}
+ parallelize-diags,~
+ renew-dots~
+ and~right-margin.}
% \end{macrocode}
%
% \bigskip
% \begin{macrocode}
+\msg_new:nnnn {nicematrix}
+ {Duplicate~name}
+ {The~name~"#1"~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~<return>.}
+ {The~names~already~defined~in~this~document~are:~
+ \seq_use:Nnnn~\g_@@_names_seq~{,~} {,~} {~and~}.}
+% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
\keys_define:nn {NiceMatrix/NiceArray}
{parallelize-diags .bool_set:N = \l_@@_parallelize_diags_bool,
parallelize-diags .default:n = true,
@@ -1613,18 +2253,14 @@ version 2005/12/01 or later.
renew-dots .default:n = true,
nullify-dots .bool_set:N = \l_@@_nullify_dots_bool ,
nullify-dots .default:n = true,
- exterior-arraycolsep .bool_set:N = \l_@@_exterior_arraycolsep_bool ,
- exterior-arraycolsep .default:n = true,
- columns-width .code:n = \str_if_eq:nnTF {#1} {auto}
- {\bool_set_true:N \l_@@_auto_columns_width_bool}
- {\dim_set:Nn \l_@@_columns_width_dim {#1}},
+ columns-width .code:n = \str_if_eq:nnTF {#1} {auto}
+ {\bool_set_true:N \l_@@_auto_columns_width_bool}
+ {\dim_set:Nn \l_@@_columns_width_dim {#1}},
columns-width .value_required:n = true,
name .code:n = {\seq_if_in:NnTF \g_@@_names_seq {#1}
- {\msg_error:nnn {nicematrix}
- {Duplicate~name}
- {#1}}
+ {\@@_msg_error:nn {Duplicate~name} {#1}}
{\seq_gput_left:Nn \g_@@_names_seq {#1}}
- \tl_gset:Nn \g_@@_name_tl {#1}},
+ \tl_set:Nn \l_@@_name_tl {#1}},
name .value_required:n = true,
% \end{macrocode}
%
@@ -1635,10 +2271,18 @@ version 2005/12/01 or later.
c .code:n = \tl_set:Nn \l_@@_pos_env_tl c,
t .code:n = \tl_set:Nn \l_@@_pos_env_tl t,
b .code:n = \tl_set:Nn \l_@@_pos_env_tl b,
- code-after .tl_gset:N = \g_@@_code_after_tl,
+ code-after .tl_set:N = \l_@@_code_after_tl,
code-after .initial:n = \c_empty_tl,
code-after .value_required:n = true,
- unknown .code:n = \msg_error:nn {nicematrix} {Unknown~option~for~NiceArray}}
+ create-extra-nodes .bool_set:N = \l_@@_extra_nodes_bool,
+ create-extra-nodes .default:n = true,
+ left-margin .dim_set:N = \l_@@_left_margin_dim,
+ left-margin .default:n = \arraycolsep,
+ right-margin .dim_set:N = \l_@@_right_margin_dim,
+ right-margin .default:n = \arraycolsep,
+ extra-left-margin .dim_set:N = \l_@@_extra_left_margin_dim,
+ extra-right-margin .dim_set:N = \l_@@_extra_right_margin_dim,
+ unknown .code:n = \@@_msg_error:n {Unknown~option~for~NiceArray}}
% \end{macrocode}
%
% \begin{macrocode}
@@ -1652,33 +2296,43 @@ version 2005/12/01 or later.
b,~
c,~
code-after,~
+ create-extra-nodes,~
columns-width,~
- exterior-arraycolsep,~
+ extra-left-margin,~
+ extra-right-margin,~
+ left-margin,~
name,~
nullify-dots,~
parallelize-diags,~
- renew-dots~
+ renew-dots,~
+ right-margin,~
and~t.}
% \end{macrocode}
%
% \subsection{The environments \{NiceArray\} and \{NiceMatrix\}}
%
-% The pseudo-environment |\@@_Cell:n|--|\@@_end_Cell:| will be used to format the cells of the array. In the code,
+% 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}|).
%
-% The argument of |\@@_Cell:n| is a letter |l|, |c| or |r| that describes the type of column: we store this letter
-% at the end of |\g_@@_preamble_aux_tl| (see the redefinition of |\ialign| in the environment |{NiceArray}| for
-% explanations).
% \begin{macrocode}
-\cs_new_protected:Nn \@@_Cell:n
- {\tl_gput_right:Nn \g_@@_preamble_aux_tl {#1}
+\cs_new_protected:Nn \@@_Cell:
+ {
% \end{macrocode}
% We increment |\g_@@_column_int|, which is the counter of the columns.
% \begin{macrocode}
\int_gincr:N \g_@@_column_int
+% \end{macrocode}
+% Now, we increment the counter of the rows. We don't do this incrementation in the |\everycr| because some
+% packages, like \pkg{arydsln}, creates special rows in the |\halign| that we don't want to take into account.
+% \begin{macrocode}
+ \int_compare:nNnT \g_@@_column_int = 1
+ {\int_gincr:N \g_@@_row_int}
+ \int_gset:Nn \g_@@_column_total_int
+ {\int_max:nn \g_@@_column_total_int \g_@@_column_int}
\hbox_set:Nw \l_tmpa_box $ % $
- \l_@@_code_for_cell_tl }
+ \int_compare:nNnT \g_@@_row_int = 0
+ \l_@@_code_for_first_row_tl}
% \end{macrocode}
%
% \begin{macrocode}
@@ -1692,20 +2346,31 @@ version 2005/12/01 or later.
% \begin{macrocode}
\dim_gset:Nn \g_@@_max_cell_width_dim
{\dim_max:nn \g_@@_max_cell_width_dim {\box_wd:N \l_tmpa_box}}
- \tl_if_empty:NTF \g_@@_name_tl
- {\tikz[remember~picture, inner~sep = 0pt, minimum~width = 0pt, baseline]
- \node [anchor = base,
- name = nm-\int_use:N \g_@@_env_int-
- \int_use:N \g_@@_row_int-
- \int_use:N \g_@@_column_int] }
- {\tikz[remember~picture, inner~sep = 0pt, minimum~width = 0pt, baseline]
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+ \int_compare:nNnT \g_@@_row_int = 0
+ {\dim_gset:Nn \g_@@_max_dp_row_zero_dim
+ {\dim_max:nn \g_@@_max_dp_row_zero_dim {\box_dp:N \l_tmpa_box}}
+ \dim_gset:Nn \g_@@_max_ht_row_zero_dim
+ {\dim_max:nn \g_@@_max_ht_row_zero_dim {\box_ht:N \l_tmpa_box}}}
+ \int_compare:nNnT \g_@@_row_int = 1
+ {\dim_gset:Nn \g_@@_max_ht_row_one_dim
+ {\dim_max:nn \g_@@_max_ht_row_one_dim {\box_ht:N \l_tmpa_box}}}
+% \end{macrocode}
+%
+% Now, we can create the Tikz node of the cell.
+% \begin{macrocode}
+ \tikz[remember~picture, inner~sep = 0pt, minimum~width = 0pt, baseline]
\node [anchor = base,
name = nm-\int_use:N \g_@@_env_int-
\int_use:N \g_@@_row_int-
\int_use:N \g_@@_column_int,
- alias = \tl_use:N \g_@@_name_tl-
- \int_use:N \g_@@_row_int-
- \int_use:N \g_@@_column_int] }
+ alias = \tl_if_empty:NF \l_@@_name_tl
+ {\tl_use:N \l_@@_name_tl-
+ \int_use:N \g_@@_row_int-
+ \int_use:N \g_@@_column_int} ]
\bgroup
\box_use:N \l_tmpa_box
\egroup ;}
@@ -1732,22 +2397,21 @@ version 2005/12/01 or later.
% Here's the definition of |{NiceMatrix}|:
% \begin{macrocode}
\NewDocumentEnvironment {NiceMatrix} {O{}}
- {\bool_set_false:N \l_@@_direct_NiceArray_bool
- \tl_gclear:N \g_@@_code_after_tl
- \keys_set:nn {NiceMatrix/NiceMatrix} {#1}
+ {\keys_set:nn {NiceMatrix/NiceMatrix} {#1}
\tl_set:Nn \l_@@_pos_env_tl c
\bool_set_false:N \l_@@_exterior_arraycolsep_bool
\NiceArray{*\c@MaxMatrixCols{C}}
}
{\endarray
- \skip_horizontal:n {-\arraycolsep}}
+ \skip_horizontal:n {-\arraycolsep}
+ \skip_horizontal:n {\g_@@_right_margin_dim + \g_@@_extra_right_margin_dim}}
% \end{macrocode}
%
% \interitem
% For the definition of |{NiceArray}| (just below), we have the following constraints:
% \begin{itemize}
% \item we must use |\array| in the first part of |{NiceArray}| and, therefore, |\endarray| in the second part;
-% \item we have to put a |\aftergroup \@@_draw_lines:| in the first part of |{NiceArray}| so that |\@@_draw_lines|
+% \item we have to put a |\aftergroup \@@_after_array:| in the first part of |{NiceArray}| so that |\@@_draw_lines|
% will be executed at the end of the current environment (either |{NiceArray}| or |{NiceMatrix}|).
% \end{itemize}
%
@@ -1755,15 +2419,25 @@ version 2005/12/01 or later.
\cs_generate_variant:Nn \dim_set:Nn {Nx}
% \end{macrocode}
%
+%
+% \bigskip
+% \begin{macrocode}
+\msg_new:nnn {nicematrix}
+ {We~are~yet~in~an~environment~NiceArray}
+ {Environments~\{NiceArray\}~(or~\{NiceMatrix\},~etc.)~can't~be~
+ nested.~We~can~go~on,~but,~maybe,~you~will~have~errors~or~an~incorrect~
+ result.}
+% \end{macrocode}
% \bigskip
% First, we test if we are yet in an environment |{NiceArray}| (nested environment are forbidden). It's easy to
% test whether we are in an environment |{NiceArray}| : a special command |\@@_in_NiceArray:| is defined.
% \begin{macrocode}
\NewDocumentEnvironment {NiceArray} {O{} m O{}}
{\cs_if_exist:NT \@@_in_NiceArray:
- {\msg_error:nn {nicematrix} {We~are~yet~in~an~environment~NiceArray}}
+ {\@@_msg_error:n {We~are~yet~in~an~environment~NiceArray}}
\cs_set:Npn \@@_in_NiceArray: {--Void--}
- \aftergroup \@@_draw_lines:
+ \aftergroup \@@_after_array:
+ \tl_gclear_new:N \g_@@_lines_to_draw_tl
% \end{macrocode}
%
% We increment the counter |\g_@@_env_int| which counts the environments |{NiceArray}|.
@@ -1772,12 +2446,15 @@ version 2005/12/01 or later.
\bool_if:NF \l_@@_block_auto_columns_width_bool
{\dim_gzero_new:N \g_@@_max_cell_width_dim}
% \end{macrocode}
-% Maybe, an encompassing environment |{NiceMatrix}| or |{pNiceArrayC}| (for example) has already set the value for
-% |\g_@@_code_after_tl| (via the option |code-after|) and we don't want to erase this value. Thanks to the flag
-% |\l_@@_direct_NiceArray_bool|, it's possible.
+%
+% For the following variables, maybe we should create it only if we use the environment |{pNiceArrayRC}| or its variants.
+% \begin{macrocode}
+ \dim_gzero_new:N \g_@@_max_dp_row_zero_dim
+ \dim_gzero_new:N \g_@@_max_ht_row_zero_dim
+ \dim_gzero_new:N \g_@@_max_ht_row_one_dim
+% \end{macrocode}
+%
% \begin{macrocode}
- \bool_if:NT \l_@@_direct_NiceArray_bool
- {\tl_gclear:N \g_@@_code_after_tl}
\keys_set:nn {NiceMatrix/NiceArray} {#1,#3}
% \end{macrocode}
%
@@ -1796,36 +2473,35 @@ version 2005/12/01 or later.
% |_@@_name_cell_width|{\ttfamily\slshape name} (the value will be the correct value even if the number of the
% environment has changed (for example because the user has created or deleted an environment before the current one).
% \begin{macrocode}
- \tl_if_empty:NF \g_@@_name_tl
- {\cs_if_free:cF {_@@_max_cell_width_\g_@@_name_tl}
+ \tl_if_empty:NF \l_@@_name_tl
+ {\cs_if_free:cF {_@@_max_cell_width_\l_@@_name_tl}
{\dim_set:Nx \l_@@_columns_width_dim
- {\use:c {_@@_max_cell_width_\g_@@_name_tl}}}}
+ {\use:c {_@@_max_cell_width_\l_@@_name_tl}}}}
}
% \end{macrocode}
+% We don't want to patch any code and that's why some code is excuted in a |\aftergroup|. In particular, in this
+% |\aftergroup|, we will have to know the value of some parameters like |\l_@@_extra_nodes_bool|. That's why we transit via a global
+% version for some variables.
+% \begin{macrocode}
+ \bool_gset_eq:NN \g_@@_extra_nodes_bool \l_@@_extra_nodes_bool
+ \dim_gset_eq:NN \g_@@_left_margin_dim \l_@@_left_margin_dim
+ \dim_gset_eq:NN \g_@@_right_margin_dim \l_@@_right_margin_dim
+ \dim_gset_eq:NN \g_@@_extra_right_margin_dim \l_@@_extra_right_margin_dim
+ \tl_gset_eq:NN \g_@@_code_after_tl \l_@@_code_after_tl
+ \tl_gset_eq:NN \g_@@_name_tl \l_@@_name_tl
+% \end{macrocode}
% The environment |{array}| uses internally the command |\ialign| and, in particular, this command |\ialign| sets
-% |\everycr| to |{}|. However, we want to use |\everycr| in our array (in particular to increment |\g_@@_row_int|).
+% |\everycr| to |{}|. However, we want to use |\everycr| in our array.
% The solution is to give to |\ialign| a new definition (giving to |\everycr| the value we want)
% that will revert automatically to its default definition after the first utilisation.\footnote{With this programmation, we will
% have, in the cells of the array, a clean version of |\ialign|. That's necessary: the user will probably not employ directly
% |\ialign| in the array... but more likely environments that utilize |\ialign| internally (e.g.: |{substack}|)}
% \begin{macrocode}
\cs_set:Npn \ialign
- {\everycr{\noalign{\int_gincr:N \g_@@_row_int
- \int_gzero:N \g_@@_column_int
-% \end{macrocode}
-% We want to have the preamble of the array in |\g_@@_preamble_tl| at the end of the array. However, some rows of the array
-% may be shorter (that is to say without all the ampersands) and it's not possible to know which row will be the
-% longest. That's why, during the construction of a row, we retrieve the corresponding preamble in
-% |\g_@@_preamble_aux_tl|. At the end of the array, we are sure that the longest value will be the real preamble of
-% the array (stored in |\g_@@_preamble_tl|).
-% \begin{macrocode}
- \int_compare:nNnT {\tl_count:N \g_@@_preamble_aux_tl}
- > {\tl_count:N \g_@@_preamble_tl}
- {\tl_gset_eq:NN \g_@@_preamble_tl \g_@@_preamble_aux_tl}
- \tl_gclear:N \g_@@_preamble_aux_tl}}
- \skip_zero:N \tabskip
+ {\everycr{\noalign{\int_gzero:N \g_@@_column_int}}
+ \tabskip = \c_zero_skip
\cs_set:Npn \ialign {\everycr{}
- \skip_zero:N \tabskip
+ \tabskip = \c_zero_skip
\halign}
\halign}
% \end{macrocode}
@@ -1834,9 +2510,9 @@ version 2005/12/01 or later.
% |{NiceArray}|.
% \begin{macrocode}
\dim_compare:nNnTF \l_@@_columns_width_dim = \c_zero_dim
- {\newcolumntype{L}{>{\@@_Cell:n l}l<{\@@_end_Cell:}}
- \newcolumntype{C}{>{\@@_Cell:n c}c<{\@@_end_Cell:}}
- \newcolumntype{R}{>{\@@_Cell:n r}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 array which is, in fact, redefined below.
@@ -1857,14 +2533,14 @@ version 2005/12/01 or later.
% \begin{macrocode}
\newcolumntype{w}[2]
{>{\hbox_set:Nw \l_tmpa_box
- \@@_Cell:n ##1}
+ \@@_Cell:}
c
<{\@@_end_Cell:
\hbox_set_end:
\makebox[##2][##1]{\box_use:N \l_tmpa_box}}}
\newcolumntype{W}[2]
{>{\hbox_set:Nw \l_tmpa_box
- \@@_Cell:n ##1}
+ \@@_Cell:}
c
<{\@@_end_Cell:
\hbox_set_end:
@@ -1880,29 +2556,19 @@ version 2005/12/01 or later.
\cs_set_eq:NN \Ddots \@@_Ddots
\cs_set_eq:NN \Iddots \@@_Iddots
\cs_set_eq:NN \Hspace \@@_Hspace:
- \cs_set_eq:NN \NiceMatrixEndPoint \@@_NiceMatrixEndPoint:
\cs_set_eq:NN \Hdotsfor \@@_Hdotsfor
+ \cs_set_eq:NN \multicolumn \@@_multicolumn:nnn
\bool_if:NT \l_@@_renew_dots_bool
{\cs_set_eq:NN \ldots \@@_Ldots
\cs_set_eq:NN \cdots \@@_Cdots
\cs_set_eq:NN \vdots \@@_Vdots
\cs_set_eq:NN \ddots \@@_Ddots
\cs_set_eq:NN \iddots \@@_Iddots
+ \cs_set_eq:NN \dots \@@_Ldots
\cs_set_eq:NN \hdotsfor \@@_Hdotsfor}
- \bool_if:NF \l_@@_renew_matrix_bool
- {\cs_set_eq:NN \multicolumn \@@_multicolumn:nn}
% \end{macrocode}
%
%
-% We have to remind the types of the columns (|l|, |c| or |r|) because we will use this information when we will
-% draw the vertical dotted lines. That's why we store the types of the columns in |\g_@@_preamble_tl| (for example,
-% if the preamble of |{NiceArray}| is |L*4{C}R|, the final value of |\g_@@_preamble_tl| will be |lccccr| if the
-% user really uses the six columns).
-% \begin{macrocode}
- \tl_clear_new:N \g_@@_preamble_tl
- \tl_clear_new:N \g_@@_preamble_aux_tl
-% \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.
@@ -1910,23 +2576,30 @@ version 2005/12/01 or later.
\seq_gclear_new:N \g_@@_empty_cells_seq
% \end{macrocode}
%
-% The counter |\g_@@_instruction_int| will count the instructions (|\Cdots|, |\Vdots|, |\Ddots|, etc.) in the matrix.
+% 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 values of $n$) correspondant will be stored. These lists will be used for the creation of the ``medium nodes''
+% (if they are created).
% \begin{macrocode}
- \int_gzero_new:N \g_@@_instruction_int
+ \seq_gclear_new:N \g_@@_multicolumn_cells_seq
+ \seq_gclear_new:N \g_@@_multicolumn_sizes_seq
% \end{macrocode}
+%
%
% The counter |\g_@@_row_int| will be used to count the rows of the array (its incrementation will be in
-% |\everycr|). At the end of the environment |{array}|, this counter will give the total number of rows of the matrix.
+% the first cell of the row). At the end of the environment |{array}|, this counter will give the total number of
+% rows of the matrix.
% \begin{macrocode}
\int_gzero_new:N \g_@@_row_int
- \int_gset_eq:NN \g_@@_row_int \l_@@_number_of_first_row_int
+ \int_gset:Nn \g_@@_row_int {\l_@@_nb_first_row_int - 1}
% \end{macrocode}
%
-% The counter |\g_@@_column_int| will be used to count the columns of the array (it will be set to zero in
-% |\everycr|). This counter is updated in the command |\@@_Cell:n| executed at the beginning of each cell. At the
-% end of the array (in the beginning of |\@@_draw_lines:|), it will be set to the total number of columns of the array.
+% The counter |\g_@@_column_int| will be used to count the columns of the array. Since we want to
+% know the total number of columns of the matrix, we also create a counter |\g_@@_column_total_int|.
+% These counters are updated in the command |\@@_Cell:| executed at the beginning of each cell.
% \begin{macrocode}
\int_gzero_new:N \g_@@_column_int
+ \int_gzero_new:N \g_@@_column_total_int
\cs_set_eq:NN \@ifnextchar \new@ifnextchar
% \end{macrocode}
%
@@ -1939,7 +2612,12 @@ version 2005/12/01 or later.
{\skip_horizontal:n {-\arraycolsep}}
% \end{macrocode}
%
-% Eventually, the environment |{NiceArray}| is defined upon the environment |{array}|. The token list |l_@@_pos_tl|
+% \begin{macrocode}
+ \skip_horizontal:n {\l_@@_left_margin_dim + \l_@@_extra_left_margin_dim}
+% \end{macrocode}
+%
+%
+% Eventually, the environment |{NiceArray}| is defined upon the environment |{array}|. The token list |\l_@@_pos_tl|
% will contain one of the values |t|, |c| or |b|.
% \begin{macrocode}
\array[\l_@@_pos_env_tl]{#2}}
@@ -1949,7 +2627,8 @@ version 2005/12/01 or later.
% \begin{macrocode}
{\endarray
\bool_if:NF \l_@@_exterior_arraycolsep_bool
- {\skip_horizontal:n {-\arraycolsep}}}
+ {\skip_horizontal:n {-\arraycolsep}}
+ \skip_horizontal:n {\g_@@_right_margin_dim + \g_@@_extra_right_margin_dim}}
% \end{macrocode}
%
%
@@ -1996,22 +2675,22 @@ version 2005/12/01 or later.
\cs_new_protected:Nn \@@_write_max_cell_width:
{\bool_if:NF \l_@@_block_auto_columns_width_bool
{\iow_now:Nn \@mainaux {\ExplSyntaxOn}
- \iow_now:Nx \@mainaux {\cs_gset:cpn {_@@_max_cell_width_\int_use:N \g_@@_env_int}
- {\dim_use:N \g_@@_max_cell_width_dim} }
+ \iow_now:Nx \@mainaux {\cs_gset:cpn
+ {@@_max_cell_width_\int_use:N \g_@@_env_int}
+ {\dim_use:N \g_@@_max_cell_width_dim} }
% \end{macrocode}
-% If the environment has a name, we also create an alias named |\_@@_max_cell_width_|{\ttfamily\slshape name}.
+% If the environment has a name, we also create an alias named |\@@_max_cell_width_|{\ttfamily\slshape name}.
% \begin{macrocode}
- \iow_now:Nx \@mainaux {\cs_gset:cpn {_@@_max_cell_width_\g_@@_name_tl}
+ \iow_now:Nx \@mainaux {\cs_gset:cpn {@@_max_cell_width_\g_@@_name_tl}
{\dim_use:N \g_@@_max_cell_width_dim} }
- \iow_now:Nn \@mainaux {\ExplSyntaxOff}}
- \tl_gclear:N \g_@@_name_tl}
+ \iow_now:Nn \@mainaux {\ExplSyntaxOff}}}
% \end{macrocode}
%
% \interitem
% The conditionnal |\@@_if_not_empty_cell:nnT| tests wether a cell is empty. The first two arguments must be LaTeX3
% counters for the row and the column of the considered cell.
% \begin{macrocode}
-\prg_set_conditional:Npnn \@@_if_not_empty_cell:nn #1#2 {T}
+\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 wether we are in this situation considering the correspondant Tikz node.
@@ -2045,83 +2724,76 @@ version 2005/12/01 or later.
\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:}
+ \prg_return_false:
+ \prg_return_true:
}}
- {\prg_return_false:}
+ \prg_return_false:
}
% \end{macrocode}
%
% \interitem
-% For each drawing instruction in the matrix (like |\Cdots|, etc.), we create a global property list to store the
-% informations corresponding to the instruction. Such an property list will have three fields:
-% \begin{itemize}
-% \item a field ``type'' with the type of the instruction (|cdots|, |vdots|, |ddots|, etc.);
-% \item a field ``row'' with the number of the row of the matrix where the instruction appeared;
-% \item a field ``column'' with the number of the column of the matrix where the instruction appeared.
-% \end{itemize}
+% The argument of the following command |\@@_instruction_of_type:n| 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.
%
-% \interitem
-% The argument of the following command |\@@_instruction_of_type:n| is the type of the instruction (|cdots|,
-% |vdots|, |ddots|, etc.). This command creates the corresponding property list.
+% \medskip
+% For example, for the following matrix,
+%
+% \smallskip
+% \begin{BVerbatim}[baseline=c,boxwidth=11cm]
+% \begin{pNiceMatrix}
+% 1 & 2 & 3 & 4 \\
+% 5 & \Cdots & & 6 \\
+% 7 & \Hdotsfor{2} \\
+% \end{pNiceMatrix}
+% \end{BVerbatim}
+% $\begin{pNiceMatrix}
+% 1 & 2 & 3 & 4 \\
+% 5 & \Cdots & & 6 \\
+% 7 & \Hdotsfor{2} \\
+% \end{pNiceMatrix}$
+%
+% the content of |\g_@@_lines_to_draw_tl| will be:
+%
+% \begin{scope}
+% \color{gray}
+% \verb|\@@_draw_Cdots:nn {2}{2}|
+%
+% \verb|\@@_draw_Hdotsfor:nnn {3}{2}{2}|
+% \end{scope}
+%
% \begin{macrocode}
\cs_new_protected:Nn \@@_instruction_of_type:n
-% \end{macrocode}
-% First, we increment the counter of the instructions (this counter is initialized in the beginning of the
-% environment |{NiceMatrix}|). This incrementation is global because the command will be used in the cell of a |\halign|).
-% \begin{macrocode}
- {\int_gincr:N \g_@@_instruction_int
- \prop_put:Nnn \l_tmpa_prop {type} {#1}
- \prop_put:NnV \l_tmpa_prop {row} \g_@@_row_int
- \prop_put:NnV \l_tmpa_prop {column} \g_@@_column_int
-% \end{macrocode}
-% The property list has been created in a local variable for convenience. Now, it will be stored in a
-% global variable indicating the number of the instruction.
-% \begin{macrocode}
- \prop_gclear_new:c
- {g_@@_instruction_\int_use:N\g_@@_instruction_int _prop}
- \prop_gset_eq:cN
- {g_@@_instruction_\int_use:N\g_@@_instruction_int _prop}
- \l_tmpa_prop
- }
+ {\tl_gput_right:Nx \g_@@_lines_to_draw_tl
+ {\exp_not:c {@@_draw_#1:nn}
+ {\int_use:N \g_@@_row_int}
+ {\int_use:N \g_@@_column_int}}}
% \end{macrocode}
%
%
-% \subsection{We draw the lines in the matrix}
+% \subsection{After the construction of the array}
%
% \begin{macrocode}
-\cs_new_protected:Nn \@@_draw_lines:
+\cs_new_protected:Nn \@@_after_array:
{
% \end{macrocode}
-% The last |\cr| in the array has incremented the counter |\g_@@_row_int|. That's why we decrement it to have the
-% real number of rows.
-% \begin{macrocode}
- \int_decr:N \g_@@_row_int
-% \end{macrocode}
-% The counter |\g_@@_column_int| will now be the total number of columns in the array.
+% Now, the definition of the counters |\g_@@_column_int| and |\g_@@_column_total_int| change: |\g_@@_column_int|
+% will be the number of columns without the exterior column (in an environment like |{pNiceArrayC}|) and
+% |\g_@@_column_total_int| will be the number of columns with this exterior column.
% \begin{macrocode}
- \int_set:Nn \g_@@_column_int {\tl_count:N \g_@@_preamble_tl}
+ \int_gset_eq:NN \g_@@_column_int \g_@@_column_total_int
+ \bool_if:NT \l_@@_exterior_column_bool {\int_gdecr:N \g_@@_column_int}
% \end{macrocode}
%
-% The sequence |\l_@@_yet_drawn_seq| contains a list of lines which have been drawn previously in the matrix. We
+% 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_clear_new:N \l_@@_yet_drawn_seq
+ \seq_gclear_new:N \g_@@_yet_drawn_seq
% \end{macrocode}
%
-%
-% The following variables will be used further.
-% \begin{macrocode}
- \int_zero_new:N \l_@@_type_int
- \int_zero_new:N \l_@@_row_int
- \int_zero_new:N \l_@@_column_int
- \int_zero_new:N \l_@@_di_int
- \int_zero_new:N \l_@@_dj_int
-% \end{macrocode}
-%
-% By befault, the diagonal lines will be parallelized\footnote{It's possible to use the option
+% By default, the diagonal lines will be parallelized\footnote{It's possible to use the option
% |parallelize-diags| to disable this parallelization.}. There are two types of diagonals lines: the $|\Ddots|$
-% diagonals and the |\Iddots| diagonals. We have to count both types in order to known wether a diagonal is the
+% diagonals and the |\Iddots| diagonals. We have to count both types in order to know wether a diagonal is the
% first of its type in the current |{NiceArray}| environment.
% \begin{macrocode}
\bool_if:NT \l_@@_parallelize_diags_bool
@@ -2139,185 +2811,179 @@ version 2005/12/01 or later.
\dim_zero_new:N \l_@@_delta_x_two_dim
\dim_zero_new:N \l_@@_delta_y_two_dim}
% \end{macrocode}
-%
-% \interitem
-% The counter |\l_@@_instruction_int| will be the index of the loop over the instructions. The first value is~$1$.
+%
+% If the user has used the option |create-extra-nodes|, the ``medium nodes'' and ``large nodes'' are created. We
+% recall that the command |\@@_create_extra_nodes:|, when used once, becomes no-op (in the current TeX group).
% \begin{macrocode}
- \int_zero_new:N \l_@@_instruction_int
- \int_incr:N \l_@@_instruction_int
+ \bool_if:NT \g_@@_extra_nodes_bool \@@_create_extra_nodes:
% \end{macrocode}
-%
-% \interitem
-% We begin the loop over the instructions (the incrementation is at the end of the loop).
+%
+% \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|.
% \begin{macrocode}
- \int_until_do:nNnn \l_@@_instruction_int > \g_@@_instruction_int
- {
+ \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_new:N \l_@@_initial_open_bool
+ \@@_bool_new:N \l_@@_final_open_bool
+ \g_@@_lines_to_draw_tl}
+ \tl_gclear:N \g_@@_lines_to_draw_tl
% \end{macrocode}
%
-% \interitem
-% We extract from the property list of the current instruction the fields ``type'', ``row'' and ``column'' and we
-% store these values. We have to do a conversion because the components of a property list are token lists (and not
-% integers).
+% \bigskip
+% Now, the |code-after|.
% \begin{macrocode}
- \prop_get:cnN {g_@@_instruction_\int_use:N \l_@@_instruction_int _prop}
- {type} \l_tmpa_tl
- \int_set:Nn \l_@@_type_int {\l_tmpa_tl}
- \prop_get:cnN {g_@@_instruction_\int_use:N \l_@@_instruction_int _prop}
- {row} \l_tmpa_tl
- \int_set:Nn \l_@@_row_int {\l_tmpa_tl}
- \prop_get:cnN {g_@@_instruction_\int_use:N \l_@@_instruction_int _prop}
- {column} \l_tmpa_tl
- \int_set:Nn \l_@@_column_int {\l_tmpa_tl}
+ \group_begin:
+ \tikzset{every~picture/.style = {overlay,
+ remember~picture,
+ name~prefix = nm-\int_use:N \g_@@_env_int-}}
+ \cs_set_eq:NN \line \@@_line:nn
+ \g_@@_code_after_tl
+ \group_end:}
% \end{macrocode}
%
-% \interitem
-% We fix the values of |\l_@@_di_int| and |\l_@@_dj_int| which indicate the direction of the dotted line to draw in
-% the matrix.
-% \begin{macrocode}
- \int_case:nn \l_@@_type_int
- { 0 {\int_set:Nn \l_@@_di_int 0
- \int_set:Nn \l_@@_dj_int 1}
- 1 {\int_set:Nn \l_@@_di_int 0
- \int_set:Nn \l_@@_dj_int 1}
- 2 {\int_set:Nn \l_@@_di_int 1
- \int_set:Nn \l_@@_dj_int 0}
- 3 {\int_set:Nn \l_@@_di_int 1
- \int_set:Nn \l_@@_dj_int 1}
- 4 {\int_set:Nn \l_@@_di_int 1
- \int_set:Nn \l_@@_dj_int {-1}}}
-% \end{macrocode}
+% \bigskip
+% A dotted line will be said \emph{open} in one of its extremity when it stops on the edge of the matrix and \emph{closed}
+% otherwise. In the following matrix, the dotted line is closed on its left extremity and open on its right.
+% \[ \begin{pNiceMatrix}
+% a+b+c & a+b & a\\
+% a & \Cdots \\
+% a & a+b & a+b+c
+% \end{pNiceMatrix}\]
+% For a closed extremity, we use the normal node and for a open one, we use the ``medium node'' (the medium and
+% large nodes are created with |\@@_create_extra_nodes:| if they have not been created yet).
+% \[ \begin{pNiceMatrix}[code-after = {\begin{tikzpicture}
+% \node [highlight, fit={(2-1)}] {} ;
+% \node [highlight, fit={(2-3-medium)}] {} ;
+% \end{tikzpicture}
+% }]
+% a+b+c & a+b & a\\
+% a & \Cdots \\
+% a & a+b & a+b+c
+% \end{pNiceMatrix}\]
%
-% \interitem
-% An instruction for a dotted line must have a initial cell and a final cell which are both not empty. If it's not
-% the case, the instruction is said \emph{impossible}. An error will be raised if an impossible instruction is
-% encountered.
-% \begin{macrocode}
- \bool_if_exist:NTF \l_@@_impossible_instruction_bool
- {\bool_set_false:N \l_@@_impossible_instruction_bool}
- {\bool_new:N \l_@@_impossible_instruction_bool}
-% \end{macrocode}
+%
+% \bigskip
+% The command |\@@_find_extremities_of_line:nnnn| takes four arguments:
%
-% \interitem
-% We will determine |\l_@@_final_i_int| and |\l_@@_final_j_int| which will be the ``coordinates'' of the end of the
-% dotted line we have to draw.
-% \begin{macrocode}
- \int_zero_new:N \l_@@_final_i_int
- \int_zero_new:N \l_@@_final_j_int
- \int_set:Nn \l_@@_final_i_int \l_@@_row_int
- \int_set:Nn \l_@@_final_j_int \l_@@_column_int
- \bool_if_exist:NTF \l_@@_stop_loop_bool
- {\bool_set_false:N \l_@@_stop_loop_bool}
- {\bool_new:N \l_@@_stop_loop_bool}
+% \begin{itemize}
+% \item the first argument is the row of the cell where the command was issued;
+% \item the second argument is the column of the cell where the command was issued;
+% \item the third argument is the $x$-value of the orientation vector of the line;
+% \item the fourth argument is the $y$-value the orientation vector of the line;
+% \end{itemize}
+%
+% This command computes:
+%
+% \begin{itemize}
+% \item |\l_@@_initial_i_int| and |\l_@@_initial_j_int| which are the coordinates of one extremity of the line;
+% \item |\l_@@_final_i_int| and |\l_@@_final_j_int| which are the coordinates of the other extremity of the line;
+% \item |\l_@@_initial_open_bool| and |\l_@@_final_open_bool| to indicate wether the extremities are open or not.
+% \end{itemize}
+%
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_find_extremities_of_line:nnnn
+ {\int_set:Nn \l_@@_initial_i_int {#1}
+ \int_set:Nn \l_@@_initial_j_int {#2}
+ \int_set:Nn \l_@@_final_i_int {#1}
+ \int_set:Nn \l_@@_final_j_int {#2}
+ \bool_set_false:N \l_@@_initial_open_bool
+ \bool_set_false:N \l_@@_final_open_bool
+% \end{macrocode}
+% We will do two loops: one when determinating the initial cell and the other when determinating the final cell.
+% The boolean |\l_@@_stop_loop_bool| will be used to control these loops.
+% \begin{macrocode}
+ \@@_bool_new:N \l_@@_stop_loop_bool
\bool_do_until:Nn \l_@@_stop_loop_bool
- {\int_add:Nn \l_@@_final_i_int \l_@@_di_int
- \int_add:Nn \l_@@_final_j_int \l_@@_dj_int
+ {\int_add:Nn \l_@@_final_i_int {#3}
+ \int_add:Nn \l_@@_final_j_int {#4}
% \end{macrocode}
% We test if we are still in the matrix.
% \begin{macrocode}
- \bool_if:nTF { \int_compare_p:nNn \l_@@_final_i_int < \l_@@_number_of_first_row_int
- || \int_compare_p:nNn \l_@@_final_i_int > \g_@@_row_int
- || \int_compare_p:nNn \l_@@_final_j_int < 1
- || \int_compare_p:nNn \l_@@_final_j_int > \g_@@_column_int}
+ \bool_if:nTF { \int_compare_p:nNn
+ \l_@@_final_i_int < {\l_@@_nb_first_row_int - 1}
+ || \int_compare_p:nNn
+ \l_@@_final_i_int > \g_@@_row_int
+ || \int_compare_p:nNn
+ \l_@@_final_j_int < 1
+ || \int_compare_p:nNn
+ \l_@@_final_j_int > \g_@@_column_total_int}
% \end{macrocode}
-% If we are outside the matrix, the instruction is impossible and, of course, we stop the loop.
+% If we are outside the matrix, we have found the extremity of the dotted line and it's a \emph{open} extremity.
% \begin{macrocode}
- {\bool_set_true:N \l_@@_impossible_instruction_bool
+ {\bool_set_true:N \l_@@_final_open_bool
+% \end{macrocode}
+% We do a step backwards because we will draw the dotted line upon the last cell in the matrix (we will use the
+% ``medium node'' of this cell).
+% \begin{macrocode}
+ \int_sub:Nn \l_@@_final_i_int {#3}
+ \int_sub:Nn \l_@@_final_j_int {#4}
\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 |\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:nnT
+ \l_@@_final_i_int
+ \l_@@_final_j_int
{\bool_set_true:N \l_@@_stop_loop_bool}}
}
% \end{macrocode}
%
% \interitem
-% We will determine |\l_@@_initial_i_int| and |\l_@@_initial_j_int| which will be the ``coordinates'' of the
-% beginning of the dotted line we have to draw. The programmation is similar to the previous one.
-% \begin{macrocode}
- \int_zero_new:N \l_@@_initial_i_int
- \int_zero_new:N \l_@@_initial_j_int
- \int_set:Nn \l_@@_initial_i_int \l_@@_row_int
- \int_set:Nn \l_@@_initial_j_int \l_@@_column_int
-% \end{macrocode}
-% If we know that the instruction is impossible (because it was not possible to found the correct value for
-% |\l_@@_final_i_int| and |\l_@@_final_j_int|), we don't do this loop.
+% For |\l_@@_initial_i_int| and |\l_@@_initial_j_int| the programmation is similar to the previous one.
% \begin{macrocode}
- \bool_set_eq:NN \l_@@_stop_loop_bool \l_@@_impossible_instruction_bool
+ \bool_set_false:N \l_@@_stop_loop_bool
\bool_do_until:Nn \l_@@_stop_loop_bool
- {\int_sub:Nn \l_@@_initial_i_int \l_@@_di_int
- \int_sub:Nn \l_@@_initial_j_int \l_@@_dj_int
+ {\int_sub:Nn \l_@@_initial_i_int {#3}
+ \int_sub:Nn \l_@@_initial_j_int {#4}
\bool_if:nTF
- { \int_compare_p:nNn \l_@@_initial_i_int < \l_@@_number_of_first_row_int
- || \int_compare_p:nNn \l_@@_initial_i_int > \g_@@_row_int
- || \int_compare_p:nNn \l_@@_initial_j_int < 1
- || \int_compare_p:nNn \l_@@_initial_j_int > \g_@@_column_int}
- {\bool_set_true:N \l_@@_impossible_instruction_bool
+ { \int_compare_p:nNn
+ \l_@@_initial_i_int < \l_@@_nb_first_row_int
+ || \int_compare_p:nNn
+ \l_@@_initial_i_int > \g_@@_row_int
+ || \int_compare_p:nNn
+ \l_@@_initial_j_int < 1
+ || \int_compare_p:nNn
+ \l_@@_initial_j_int > \g_@@_column_total_int}
+ {\bool_set_true:N \l_@@_initial_open_bool
+ \int_add:Nn \l_@@_initial_i_int {#3}
+ \int_add:Nn \l_@@_initial_j_int {#4}
\bool_set_true:N \l_@@_stop_loop_bool}
- {\@@_if_not_empty_cell:nnT \l_@@_initial_i_int \l_@@_initial_j_int
+ {\@@_if_not_empty_cell:nnT
+ \l_@@_initial_i_int
+ \l_@@_initial_j_int
{\bool_set_true:N \l_@@_stop_loop_bool}}
}
% \end{macrocode}
-%
-% \interitem
-% Now, we can determine wether we have to draw a line.
-% If the line is impossible, of course, we won't draw any line.
+% If we have at least one open extremity, we create the ``medium nodes'' in the matrix (in the case of an open
+% extremity, the dotted line uses the ``medium node'' of the last empty cell). We remind that, when used once, the
+% command |\@@_create_extra_nodes:| becomes no-op in the current TeX group.
% \begin{macrocode}
- \bool_if:NTF \l_@@_impossible_instruction_bool
- {\msg_error:nn {nicematrix} {Impossible~instruction}}
+ \bool_if:nT {\l_@@_initial_open_bool || \l_@@_final_open_bool}
+ \@@_create_extra_nodes: }
% \end{macrocode}
%
-% If the dotted line to draw is in the list of the previously drawn lines (|\l_@@_yet_drawn_seq|), we don't draw
+% \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$-uplet
% 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:NVF \l_@@_yet_drawn_seq \l_tmpa_tl
+ \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 the list |\l_@@_yet_drawn_seq|.
+% If the dotted line to draw is not in the list, we add it to the list |\g_@@_yet_drawn_seq|.
% \begin{macrocode}
- {\seq_put_left:NV \l_@@_yet_drawn_seq \l_tmpa_tl
-% \end{macrocode}
-%
-% \medskip
-% The four following variables are global because we will have to do affectations in a Tikz instruction (in order
-% to extract the coordinates of two extremities of the line to draw).
-% \begin{macrocode}
- \dim_zero_new:N \g_@@_x_initial_dim
- \dim_zero_new:N \g_@@_y_initial_dim
- \dim_zero_new:N \g_@@_x_final_dim
- \dim_zero_new:N \g_@@_y_final_dim
-% \end{macrocode}
-%
-%
-% We draw the line.
-% \begin{macrocode}
- \int_case:nn \l_@@_type_int
- {0 \@@_draw_ldots_line:
- 1 \@@_draw_cdots_line:
- 2 \@@_draw_vdots_line:
- 3 \@@_draw_ddots_line:
- 4 \@@_draw_iddots_line:}}}
-% \end{macrocode}
-%
-% \bigskip
-% Incrementation of the index of the loop (and end of the loop).
-% \begin{macrocode}
- \int_incr:N \l_@@_instruction_int
- }
- \group_begin:
- \tikzset{every~picture/.style = {overlay,
- remember~picture,
- name~prefix = nm-\int_use:N \g_@@_env_int-}}
- \cs_set_eq:NN \line \@@_line:nn
- \g_@@_code_after_tl
- \group_end:
-}
+ {\prg_return_true:}
+ {\seq_gput_left:NV \g_@@_yet_drawn_seq \l_tmpa_tl
+ \prg_return_false:}}
% \end{macrocode}
%
%
@@ -2327,74 +2993,123 @@ version 2005/12/01 or later.
% adjustment of one of the coordinates may be done.}. This command has four implicit arguments which are
% |\l_@@_initial_i_int|, |\l_@@_initial_j_int|, |\l_@@_final_i_int| and |\l_@@_final_j_int|.
%
-% The two arguments of the command |\@@_retrieve_coords:nn| are the anchors that must be used for the two nodes.
+% The two arguments of the command |\@@_retrieve_coords:nn| are the prefix and the anchor that must be used for the
+% two nodes.
%
% The coordinates are stored in |\g_@@_x_initial_dim|, |\g_@@_y_initial_dim|, |\g_@@_x_final_dim|,
% |\g_@@_y_final_dim|. These variables are global for technical reasons: we have to do an affectation in an
-% environment |{pgfpicture}|.
+% environment |{tikzpicture}|.
% \begin{macrocode}
\cs_new_protected:Nn \@@_retrieve_coords:nn
- {\begin{tikzpicture}[remember~picture]
+ {\dim_gzero_new:N \g_@@_x_initial_dim
+ \dim_gzero_new:N \g_@@_y_initial_dim
+ \dim_gzero_new:N \g_@@_x_final_dim
+ \dim_gzero_new:N \g_@@_y_final_dim
+ \begin{tikzpicture}[remember~picture]
\tikz@parse@node\pgfutil@firstofone
(nm-\int_use:N \g_@@_env_int-
\int_use:N \l_@@_initial_i_int-
- \int_use:N \l_@@_initial_j_int.#1)
+ \int_use:N \l_@@_initial_j_int #1)
\dim_gset:Nn \g_@@_x_initial_dim \pgf@x
\dim_gset:Nn \g_@@_y_initial_dim \pgf@y
\tikz@parse@node\pgfutil@firstofone
(nm-\int_use:N \g_@@_env_int-
\int_use:N \l_@@_final_i_int-
- \int_use:N \l_@@_final_j_int.#2)
+ \int_use:N \l_@@_final_j_int #2)
\dim_gset:Nn \g_@@_x_final_dim \pgf@x
\dim_gset:Nn \g_@@_y_final_dim \pgf@y
\end{tikzpicture} }
+\cs_generate_variant:Nn \@@_retrieve_coords:nn {xx}
% \end{macrocode}
%
% \interitem
% \begin{macrocode}
-\cs_new_protected:Nn \@@_draw_ldots_line:
- {\@@_retrieve_coords:nn {south~east} {south~west}
- \@@_draw_tikz_line:}
-% \end{macrocode}
-%
-% \bigskip
-% \begin{macrocode}
-\cs_new_protected:Nn \@@_draw_cdots_line:
- {\@@_retrieve_coords:nn {mid~east} {mid~west}
- \@@_draw_tikz_line:}
-% \end{macrocode}
-%
-% \bigskip
-% For the vertical dotted lines, there is a problem because we want really vertical lines. If the type of the
-% column is |c| (from a type |C| in |{NiceArray}|), all the Tikz nodes of the column have the same $x$-value for the
-% anchors |south| and |north|. However, if the type of the column is |l| or |r| (from a type |L| or |R| in
-% |{NiceArray}|), the geometric line from the anchors |south| and |north| would probably not be really vertical.
-% That's why we need to known the type of the column and that's why we have constructed a token list
-% |\g_@@_preamble_tl| to store the types (|l|, |c| or |r|) of all the columns.
-% \begin{macrocode}
-\cs_new_protected:Nn \@@_draw_vdots_line:
- {\@@_retrieve_coords:nn {south} {north}
-% \end{macrocode}
-% We store in |\t_tmpa_tl| the type of the column (|l|, |c| or |r|).
-% \begin{macrocode}
- \tl_set:Nx \l_tmpa_tl {\tl_item:Nn \g_@@_preamble_tl \l_@@_initial_j_int}
+\cs_new_protected:Nn \@@_draw_Ldots:nn
+ {\@@_find_extremities_of_line:nnnn {#1} {#2} 0 1
+ \@@_if_yet_drawn:F \@@_actually_draw_Ldots:}
% \end{macrocode}
-% If the column is of type |l|, we will draw the dotted line on the left-most abscissa.
+%
+% \medskip
+% The command |\@@_actually_draw_Ldots:| actually draws the |Ldots| line using |\l_@@_initial_i_int|,
+% |\l_@@_initial_j_int|, |\l_@@_initial_open_bool|, |\l_@@_final_i_int|, |\l_@@_final_j_int| and
+% |\l_@@_final_open_bool|. We have a dedicated command because if is used also by |\Hdotsfor|.
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_actually_draw_Ldots:
+ {\@@_retrieve_coords:xx {\bool_if:NTF \l_@@_initial_open_bool
+ {-medium.base~west}
+ {.base~east}}
+ {\bool_if:NTF \l_@@_final_open_bool
+ {-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
+ {\dim_gset_eq:NN \g_@@_y_final_dim \g_@@_y_initial_dim }
+% \end{macrocode}
+% We raise the line of a quantity equal to the radius of the dots because we want the dots really ``on'' the line
+% of texte.
+% \begin{macrocode}
+ \dim_gadd:Nn \g_@@_y_initial_dim {0.53pt}
+ \dim_gadd:Nn \g_@@_y_final_dim {0.53pt}
+ \@@_draw_tikz_line:}
+% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_draw_Cdots:nn
+ {\@@_find_extremities_of_line:nnnn {#1} {#2} 0 1
+ \@@_if_yet_drawn:F
+ {\@@_retrieve_coords:xx {\bool_if:NTF \l_@@_initial_open_bool
+ {-medium.mid~west}
+ {.mid~east}}
+ {\bool_if:NTF \l_@@_final_open_bool
+ {-medium.mid~east}
+ {.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:}}
+% \end{macrocode}
+%
+% \bigskip
+% For the vertical dots, we have to distinguish different instances because we want really vertical lines. Be
+% careful: it's not possible to insert the command |\@@_retrieve_coords:nn| in the arguments |T| and |F| of the
+% \pkg{expl3} commands (why?).
% \begin{macrocode}
- \str_if_eq:VnT \l_tmpa_tl {l}
- {\dim_set:Nn \g_@@_x_initial_dim {\dim_min:nn \g_@@_x_initial_dim \g_@@_x_final_dim}
- \dim_set_eq:NN \g_@@_x_final_dim \g_@@_x_initial_dim}
-% \end{macrocode}
-% If the column is of type |r|, we will draw the dotted line on the right-most abscissa.
+\cs_new_protected:Nn \@@_draw_Vdots:nn
+ {\@@_find_extremities_of_line:nnnn {#1} {#2} 1 0
+ \@@_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}}
+% \end{macrocode}
+% The boolean |\l_tmpa_bool| indicates wether the column is of type |l| (|L| of |{NiceArray}|) or may be considered
+% as if.
% \begin{macrocode}
- \str_if_eq:VnT \l_tmpa_tl {r}
- {\dim_set:Nn \g_@@_x_initial_dim {\dim_max:nn \g_@@_x_initial_dim \g_@@_x_final_dim}
- \dim_set_eq:NN \g_@@_x_final_dim \g_@@_x_initial_dim}
-% \end{macrocode}
-% Now, the coordinates of the line to draw are computed in |\g_@@_x_initial_dim|, |\g_@@_y_initial_dim|,
-% |\g_@@_x_final_dim| and |\g_@@_y_final_dim|. We can draw the line with |\l_@@_draw_tikz_line:| as usual.
+ \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 wether the column is of type |c| (|C| of |{NiceArray}|) or may be considered
+% as if.
% \begin{macrocode}
- \@@_draw_tikz_line:}
+ \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_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}
+ \@@_draw_tikz_line:}}
% \end{macrocode}
%
% \interitem
@@ -2402,8 +3117,15 @@ version 2005/12/01 or later.
% lines. The first diagonal line is drawn and then, all the other diagonal lines are drawn parallel to the first
% one.
% \begin{macrocode}
-\cs_new_protected:Nn \@@_draw_ddots_line:
- {\@@_retrieve_coords:nn {south~east} {north~west}
+\cs_new_protected:Nn \@@_draw_Ddots: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~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.
@@ -2431,24 +3153,31 @@ version 2005/12/01 or later.
% \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}
%
% \bigskip
% We draw the |\Iddots| diagonals in the same way.
% \begin{macrocode}
-\cs_new_protected:Nn \@@_draw_iddots_line:
- {\@@_retrieve_coords:nn {south~west} {north~east}
- \bool_if:NT \l_@@_parallelize_diags_bool
- {\int_incr:N \l_@@_iddots_int
- \int_compare:nNnTF \l_@@_iddots_int = 1
- {\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:}
+\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 = 1
+ {\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:}}
% \end{macrocode}
%
% \bigskip
@@ -2482,30 +3211,57 @@ version 2005/12/01 or later.
% \end{macrocode}
% The integer |\l_tmpa_int| is the number of dots of the dotted line.
% \begin{macrocode}
- {\int_set:Nn \l_tmpa_int {\dim_ratio:nn {\l_@@_l_dim - 0.54em}
- {0.45em}}
+ {\bool_if:NTF \l_@@_initial_open_bool
+ {\bool_if:NTF \l_@@_final_open_bool
+ {\int_set:Nn \l_tmpa_int
+ {\dim_ratio:nn {\l_@@_l_dim} {0.45em}}}
+ {\int_set:Nn \l_tmpa_int
+ {\dim_ratio:nn {\l_@@_l_dim - 0.3em} {0.45em}}}}
+ {\bool_if:NTF \l_@@_final_open_bool
+ {\int_set:Nn \l_tmpa_int
+ {\dim_ratio:nn {\l_@@_l_dim - 0.3em} {0.45em}}}
+ {\int_set:Nn \l_tmpa_int
+ {\dim_ratio:nn {\l_@@_l_dim - 0.6em} {0.45em}}}}
% \end{macrocode}
% The dimensions |\l_tmpa_dim| and |\l_tmpb_dim| are the coordinates of the vector between two dots in the
% dotted line.
% \begin{macrocode}
- \dim_set:Nn \l_tmpa_dim { (\g_@@_x_final_dim - \g_@@_x_initial_dim)
+ \dim_set:Nn \l_tmpa_dim {(\g_@@_x_final_dim - \g_@@_x_initial_dim)
* \dim_ratio:nn {0.45em} \l_@@_l_dim}
- \dim_set:Nn \l_tmpb_dim { (\g_@@_y_final_dim - \g_@@_y_initial_dim)
+ \dim_set:Nn \l_tmpb_dim {(\g_@@_y_final_dim - \g_@@_y_initial_dim)
* \dim_ratio:nn {0.45em} \l_@@_l_dim}
% \end{macrocode}
+%
+% The length $\ell$ is the length of the dotted line. We note $\Delta$ the length between two dots and $n$ the
+% number of intervals between dots. We note $\delta = \frac12(\ell - n \Delta)$.
+% The distance between the initial extremity of the line and the first dot will be equal to $k\cdot\delta$ where
+% $k=0$, $1$ or $2$. We first compute this number $k$ in |\l_tmpb_int|.
+% \begin{macrocode}
+ \int_set:Nn \l_tmpb_int
+ {\bool_if:NTF \l_@@_initial_open_bool
+ {\bool_if:NTF \l_@@_final_open_bool 1 0}
+ {\bool_if:NTF \l_@@_final_open_bool 2 1}}
+% \end{macrocode}
% In the loop over the dots (|\int_step_inline:nnnn|), the dimensions |\g_@@_x_initial_dim| and
-% |\g_@@_y_initial_dim| will be used for the coordinates of the dots.
+% |\g_@@_y_initial_dim| will be used for the coordinates of the dots. But, before the loop, we must move until the
+% first dot.
+%
% \begin{macrocode}
\dim_gadd:Nn \g_@@_x_initial_dim
- { (\g_@@_x_final_dim - \g_@@_x_initial_dim)
+ { (\g_@@_x_final_dim - \g_@@_x_initial_dim)
* \dim_ratio:nn {\l_@@_l_dim - 0.45 em * \l_tmpa_int}
- {\l_@@_l_dim * 2}}
+ {\l_@@_l_dim * 2}
+ * \l_tmpb_int}
+% \end{macrocode}
+% (In a multiplication of a dimension and an integer, the integer must always be put in second position.)
+% \begin{macrocode}
\dim_gadd:Nn \g_@@_y_initial_dim
- { (\g_@@_y_final_dim - \g_@@_y_initial_dim)
+ { (\g_@@_y_final_dim - \g_@@_y_initial_dim)
* \dim_ratio:nn {\l_@@_l_dim - 0.45 em * \l_tmpa_int}
- {\l_@@_l_dim * 2}}
+ {\l_@@_l_dim * 2}
+ * \l_tmpb_int}
\begin{tikzpicture}[overlay]
- \int_step_inline:nnn 0 \l_tmpa_int
+ \int_step_inline:nnnn 0 1 \l_tmpa_int
{ \pgfpathcircle{\pgfpoint{\g_@@_x_initial_dim}
{\g_@@_y_initial_dim}}
{0.53pt}
@@ -2544,7 +3300,7 @@ version 2005/12/01 or later.
% \pkg{nicematrix} rely upon |{NiceArray}|).
% \begin{macrocode}
\NewDocumentCommand \@@_Ldots {s}
- {\IfBooleanF {#1} {\@@_instruction_of_type:n 0}
+ {\bool_if:nF {#1} {\@@_instruction_of_type:n {Ldots}}
\bool_if:NF \l_@@_nullify_dots_bool {\phantom \@@_ldots}
\@@_add_to_empty_cells:}
% \end{macrocode}
@@ -2552,7 +3308,7 @@ version 2005/12/01 or later.
% \bigskip
% \begin{macrocode}
\NewDocumentCommand \@@_Cdots {s}
- {\IfBooleanF {#1} {\@@_instruction_of_type:n 1}
+ {\bool_if:nF {#1} {\@@_instruction_of_type:n {Cdots}}
\bool_if:NF \l_@@_nullify_dots_bool {\phantom \@@_cdots}
\@@_add_to_empty_cells:}
% \end{macrocode}
@@ -2560,7 +3316,7 @@ version 2005/12/01 or later.
% \bigskip
% \begin{macrocode}
\NewDocumentCommand \@@_Vdots {s}
- {\IfBooleanF {#1} {\@@_instruction_of_type:n 2}
+ {\bool_if:nF {#1} {\@@_instruction_of_type:n {Vdots}}
\bool_if:NF \l_@@_nullify_dots_bool {\phantom \@@_vdots}
\@@_add_to_empty_cells:}
% \end{macrocode}
@@ -2568,7 +3324,7 @@ version 2005/12/01 or later.
% \bigskip
% \begin{macrocode}
\NewDocumentCommand \@@_Ddots {s}
- {\IfBooleanF {#1} {\@@_instruction_of_type:n 3}
+ {\bool_if:nF {#1} {\@@_instruction_of_type:n {Ddots}}
\bool_if:NF \l_@@_nullify_dots_bool {\phantom \@@_ddots}
\@@_add_to_empty_cells:}
% \end{macrocode}
@@ -2576,7 +3332,7 @@ version 2005/12/01 or later.
% \bigskip
% \begin{macrocode}
\NewDocumentCommand \@@_Iddots {s}
- {\IfBooleanF {#1} {\@@_instruction_of_type:n 4}
+ {\bool_if:nF {#1} {\@@_instruction_of_type:n {Iddots}}
\bool_if:NF \l_@@_nullify_dots_bool {\phantom \@@_iddots}
\@@_add_to_empty_cells:}
% \end{macrocode}
@@ -2590,47 +3346,73 @@ version 2005/12/01 or later.
\hspace}
% \end{macrocode}
%
+%
% \bigskip
-% The command |\@@_NiceMatrixEndPoint:| will be linked to |\NiceMatrixEndPoint| in |{NiceArray}|.
+% In the environment |{NiceArray}|, the command |\multicolumn| will be linked to the following command
+% |\@@_multicolumn:nnn|.
% \begin{macrocode}
-\cs_new_protected:Nn \@@_NiceMatrixEndPoint:
- {\kern 0.5pt}
+\cs_set_eq:NN \@@_old_multicolumn \multicolumn
+\cs_new:Nn \@@_multicolumn:nnn
+ {\@@_old_multicolumn{#1}{#2}{#3}
+ \int_compare:nNnT #1 > 1
+ {\seq_gput_left:Nx \g_@@_multicolumn_cells_seq
+ {\int_eval:n {\g_@@_row_int} -
+ \int_use:N \g_@@_column_int}
+ \seq_gput_left:Nn \g_@@_multicolumn_sizes_seq {#1}}
+ \int_gadd:Nn \g_@@_column_int {#1-1}}
% \end{macrocode}
%
+%
% \bigskip
-% The command |\@@_Hdotsfor| will be linked to |\Hdotsfor| in |{NiceArray}|. This command uses an optionnal
+% The command |\@@_Hdotsfor| will be linked to |\Hdotsfor| in |{NiceArray}|. This command uses an optional
% argument like |\hdotsfor| but this argument is discarded (in |\hdotsfor|, this argument is used for fine tuning
% of the space beetween two consecutive dots).
+% Tikz nodes are created for all the cells of the array, even the implicit cells of the |\Hdotsfor|.
% \begin{macrocode}
-\NewDocumentCommand \@@_Hdotsfor {O{} m}
+\NewDocumentCommand {\@@_Hdotsfor} {O{} m}
+ {\tl_gput_right:Nx \g_@@_lines_to_draw_tl
+ {\exp_not:N \@@_draw_Hdotsfor:nnn
+ {\int_use:N \g_@@_row_int}
+ {\int_use:N \g_@@_column_int}
+ {#2}}
+ \prg_replicate:nn {#2-1} {&}}
% \end{macrocode}
-% First, we store in the |code-after| (that is in |\g_@@_code_after_tl|) a command |\line| to draw the dotted line
-% after the construction of the matrix.
+%
+% \medskip
% \begin{macrocode}
- {\int_set:Nn \l_tmpa_int {\g_@@_column_int - 1}
- \int_set:Nn \l_tmpb_int {\g_@@_column_int + #2}
- \tl_gput_right:Nx \g_@@_code_after_tl
- {\exp_not:N \line {\int_use:N\g_@@_row_int-\int_use:N\l_tmpa_int}
- {\int_use:N\g_@@_row_int-\int_use:N\l_tmpb_int}}
+\cs_new_protected:Nn \@@_draw_Hdotsfor:nnn
+ {\bool_set_false:N \l_@@_initial_open_bool
+ \bool_set_false:N \l_@@_final_open_bool
% \end{macrocode}
-% Then, we insert the correct number of ampersands (|&|).
+% For the row, it's easy.
% \begin{macrocode}
- \prg_replicate:nn {#2-1} {&}}
+ \int_set:Nn \l_@@_initial_i_int {#1}
+ \int_set:Nn \l_@@_final_i_int {#1}
% \end{macrocode}
-% Tikz nodes are created for all the cells of the array, even the implicit cells of the |\Hdotsfor|.
-%
-% \subsection{We process the options}
-%
-% We process the options when the package is loaded (with |\usepackage|) but we recommend to use
-% |\NiceMatrixOptions| instead.
-%
-% We must process these options after the definition of the environment |{NiceMatrix}| because the option
-% |renew-matrix| execute the code |\cs_set_eq:NN \env@matrix \NiceMatrix|.
-%
-% Of course, the command |\NiceMatrix| must be defined before such an instruction is executed.
+% For the column, it's a bit more complicated.
% \begin{macrocode}
-\ProcessKeysOptions {NiceMatrix}
+ \int_compare:nNnTF #2 = 1
+ {\int_set:Nn \l_@@_initial_j_int 1
+ \bool_set_true:N \l_@@_initial_open_bool}
+ {\int_set:Nn \l_tmpa_int {#2-1}
+ \@@_if_not_empty_cell:nnTF \l_@@_initial_i_int \l_tmpa_int
+ {\int_set:Nn \l_@@_initial_j_int {#2-1}}
+ {\int_set:Nn \l_@@_initial_j_int {#2}
+ \bool_set_true:N \l_@@_initial_open_bool}}
+ \int_compare:nNnTF {#2+#3-1} = \g_@@_column_int
+ {\int_set:Nn \l_@@_final_j_int {#2+#3-1}
+ \bool_set_true:N \l_@@_final_open_bool}
+ {\int_set:Nn \l_tmpa_int {#2+#3}
+ \@@_if_not_empty_cell:nnTF \l_@@_final_i_int \l_tmpa_int
+ {\int_set:Nn \l_@@_final_j_int {#2+#3}}
+ {\int_set:Nn \l_@@_final_j_int {#2+#3-1}
+ \bool_set_true:N \l_@@_final_open_bool}}
+ \bool_if:nT {\l_@@_initial_open_bool || \l_@@_final_open_bool}
+ \@@_create_extra_nodes:
+ \@@_actually_draw_Ldots:}
% \end{macrocode}
+%
+%
%
% \subsection{The command \textbackslash line accessible in code-after}
%
@@ -2657,54 +3439,7 @@ version 2005/12/01 or later.
% The commands |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots|, |\Iddots| don't use this command because they have to do
% other settings (for example, the diagonal lines must be parallelized).
%
-% \subsection{The error messages}
-% \begin{macrocode}
-\msg_new:nnnn {nicematrix}
- {Impossible~instruction}
- {It's~not~possible~to~execute~the~instruction~
- \int_case:nn \l_@@_type_int
- {0 {\token_to_str:N \Ldots}
- 1 {\token_to_str:N \Cdots}
- 2 {\token_to_str:N \Vdots}
- 3 {\token_to_str:N \Ddots}}~in~the~row~\int_use:N\l_@@_row_int\
- ~and~the~column~\int_use:N\l_@@_column_int\space of~the~matrix~
- because~it's~impossible~to~find~one~of~its~extremities~
- (both~extremities~must~be~non~empty~cells~of~the~matrix).~
- If~you~go~on,~the~instruction~will~be~ignored.}
- {You~can~specify~an~end~of~line~on~a~empty~cell~
- with~\token_to_str:N \NiceMatrixEndPoint.}
-% \end{macrocode}
-%
-% \begin{macrocode}
-\msg_new:nnn {nicematrix}
- {Multicolumn~forbidden}
- {The~command~\token_to_str:N \multicolumn\
- is~forbidden~in~the~environment~\{\@currenvir\}~
- and~its~variants.~The~command~\token_to_str:N \hdotsfor\
- of~amsmath~is~also~forbidden~since~it~uses~
- \token_to_str:N \multicolumn\ ~(but~you~can~use~\token_to_str:N \Hdotsfor\
- ~instead).~You~can~go~on~but~your~matrix~may~be~wrong.}
-% \end{macrocode}
-%
-% \begin{macrocode}
-\msg_new:nnn {nicematrix}
- {We~are~yet~in~an~environment~NiceArray}
- {Environments~\{NiceArray\}~(or~\{NiceMatrix\},~etc.)~can't~be~
- nested.~We~can~go~on,~but,~maybe,~you~will~have~errors~or~an~incorrect~
- result.}
-% \end{macrocode}
%
-% \begin{macrocode}
-\msg_new:nnnn {nicematrix}
- {Duplicate~name}
- {The~name~"#1"~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~<return>.}
- {The~names~already~defined~in~this~document~are:~
- \seq_use:Nnnn~\g_@@_names_seq~{,~} {,~} {~and~}.}
-% \end{macrocode}
%
% \subsection{The environment \{NiceMatrixBlock\}}
%
@@ -2718,9 +3453,10 @@ version 2005/12/01 or later.
% As of now, there is only one option available for the environment |{NiceMatrixBlock}|.
% \begin{macrocode}
\keys_define:nn {NiceMatrix/NiceMatrixBlock}
- {auto-columns-width .code:n = {\bool_set_true:N \l_@@_block_auto_columns_width_bool
- \dim_gzero_new:N \g_@@_max_cell_width_dim
- \bool_set_true:N \l_@@_auto_columns_width_bool}}
+ {auto-columns-width .code:n =
+ {\bool_set_true:N \l_@@_block_auto_columns_width_bool
+ \dim_gzero_new:N \g_@@_max_cell_width_dim
+ \bool_set_true:N \l_@@_auto_columns_width_bool}}
% \end{macrocode}
%
% \bigskip
@@ -2738,9 +3474,9 @@ version 2005/12/01 or later.
% \begin{macrocode}
{\bool_if:NT \l_@@_block_auto_columns_width_bool
{\iow_now:Nn \@mainaux {\ExplSyntaxOn}
- \int_step_inline:nnn \l_@@_first_env_block_int \g_@@_env_int
+ \int_step_inline:nnnn \l_@@_first_env_block_int 1 \g_@@_env_int
{\iow_now:Nx \@mainaux
- {\cs_gset:cpn {_@@_max_cell_width_##1}
+ {\cs_gset:cpn {@@_max_cell_width_##1}
{\dim_use:N \g_@@_max_cell_width_dim}}}
\iow_now:Nn \@mainaux {\ExplSyntaxOff}}}
% \end{macrocode}
@@ -2769,16 +3505,22 @@ version 2005/12/01 or later.
{\dim_set:Nn \l_@@_columns_width_dim {#1}},
columns-width .value_required:n = true,
name .code:n = {\seq_if_in:NnTF \g_@@_names_seq {#1}
- {\msg_error:nnn {nicematrix}
- {Duplicate~name}
- {#1}}
+ {\@@_msg_error:nn {Duplicate~name} {#1}}
{\seq_gput_left:Nn \g_@@_names_seq {#1}}
- \tl_gset:Nn \g_@@_name_tl {#1}},
+ \tl_set:Nn \l_@@_name_tl {#1}},
name .value_required:n = true,
- code-after .tl_gset:N = \g_@@_code_after_tl,
- code-after .initial:n = \c_empty_tl,
+ code-after .tl_set:N = \l_@@_code_after_tl,
+ code-after .initial:n = \c_empty_tl,
code-after .value_required:n = true,
- unknown .code:n = \msg_error:nn {nicematrix} {Unknown~option~for~NiceArrayC}}
+ create-extra-nodes .bool_set:N = \l_@@_extra_nodes_bool,
+ create-extra-nodes .default:n = true,
+ left-margin .dim_set:N = \l_@@_left_margin_dim,
+ left-margin .default:n = \arraycolsep,
+ right-margin .dim_set:N = \l_@@_right_margin_dim,
+ right-margin .default:n = \arraycolsep,
+ extra-left-margin .dim_set:N = \l_@@_extra_left_margin_dim,
+ extra-right-margin .dim_set:N = \l_@@_extra_right_margin_dim,
+ unknown .code:n = \@@_msg_error:n {Unknown~option~for~NiceArrayC}}
% \end{macrocode}
%
% \begin{macrocode}
@@ -2792,10 +3534,15 @@ version 2005/12/01 or later.
code-after,~
code-for-last-col,~
columns-width,~
+ create-extra-nodes,~
+ extra-left-margin,~
+ extra-right-margin,~
+ left-margin,~
name,~
nullify-dots,~
parallelize-diags~
- and~renew-dots.}
+ renew-dots~
+ and~right-margin.}
% \end{macrocode}
%
% \bigskip
@@ -2809,7 +3556,7 @@ version 2005/12/01 or later.
% |{NiceArrayRCwithDelims}|.
% \begin{macrocode}
\cs_new_protected:Nn \@@_NiceArrayC:n
- {
+ {\bool_set_true:N \l_@@_exterior_column_bool
\begin{NiceArray}
% \end{macrocode}
% The beginning of the preamble is the argument of the environment |{pNiceArrayC}|.
@@ -2822,21 +3569,18 @@ version 2005/12/01 or later.
% |\hbox_set:Nw \l_tmpa_box| ... |\hbox_set_end:|.
% \begin{macrocode}
>{\int_gincr:N \g_@@_column_int
+ \int_gset:Nn \g_@@_column_total_int
+ {\int_max:nn \g_@@_column_total_int \g_@@_column_int}
\hbox_set:Nw \l_tmpa_box
- \tl_if_empty:NTF \g_@@_name_tl
- {\tikz[remember~picture, inner~sep = 0pt, minimum~width = 0pt, baseline]
- \node [anchor=base,
- name = nm-\int_use:N \g_@@_env_int-
- \int_use:N \g_@@_row_int-
- \int_use:N \g_@@_column_int] }
- {\tikz[remember~picture, inner~sep = 0pt, minimum~width = 0pt, baseline]
+ \tikz[remember~picture, inner~sep=0pt, minimum~width=0pt, baseline]
\node [anchor=base,
name = nm-\int_use:N \g_@@_env_int-
\int_use:N \g_@@_row_int-
\int_use:N \g_@@_column_int,
- alias = \g_@@_name_tl-
- \int_use:N \g_@@_row_int-
- \int_use:N \g_@@_column_int] }
+ alias = \tl_if_empty:NF \l_@@_name_tl
+ {\l_@@_name_tl-
+ \int_use:N \g_@@_row_int-
+ \int_use:N \g_@@_column_int}]
\bgroup $ % $
\l_@@_code_for_last_col_tl
}
@@ -2852,25 +3596,24 @@ version 2005/12/01 or later.
\dim_gset:Nn \g_@@_width_last_col_dim
{\dim_max:nn \g_@@_width_last_col_dim
{\box_wd:N \l_tmpa_box}}
- \tl_gput_right:Nn \g_@@_preamble_aux_tl {#1}
\skip_horizontal:n {-2\arraycolsep}
% \end{macrocode}
% The content of the cell is inserted in an overlapping position.
% \begin{macrocode}
\hbox_overlap_right:n
- {\skip_horizontal:n {2\arraycolsep}
+ {\skip_horizontal:n
+ { 2\arraycolsep + \l_@@_right_margin_dim
+ + \l_@@_extra_right_margin_dim}
\box_use:N \l_tmpa_box}}}}
% \end{macrocode}
% This ends the preamble of the array that will be constructed (a rather long preamble, indeed).
%
% \bigskip
-% All the environments of the type of |{pNiceArrayC}| will be constructed over |{NiceArrayCwithDelims}|. The first
+% The environments of the type of |{pNiceArrayC}| will be constructed over |{NiceArrayCwithDelims}|. The first
% two arguments of this environment are the left and the right delimiter.
% \begin{macrocode}
\NewDocumentEnvironment{NiceArrayCwithDelims} {mm O{} m O{}}
- {\bool_set_false:N \l_@@_direct_NiceArray_bool
- \tl_gclear:N \g_@@_code_after_tl
- \dim_gzero_new:N \g_@@_width_last_col_dim
+ {\dim_gzero_new:N \g_@@_width_last_col_dim
\keys_set:nn {NiceMatrix/NiceArrayC} {#3,#5}
\bool_set_false:N \l_@@_exterior_arraycolsep_bool
\tl_set:Nn \l_@@_pos_env_tl c
@@ -2921,64 +3664,6 @@ version 2005/12/01 or later.
%
% The code in this section can be removed without affecting the previous code.
%
-% \medskip
-%
-% If the environment is used with the option |columns-width=auto|, the construction
-%
-% \begin{Verbatim}
-% \begin{pNiceArrayRC}{~slshape#preamble@}[columns-width=auto]
-% ~slshape#first row@ \\
-% ~slshape#second row@ \\
-% ~slshape#third row@ \\
-% ~slshape#etc.@ \\
-% \end{pNiceArrayRC}
-% \end{Verbatim}
-%
-% is transformed in the following construction :
-%
-% \begin{Verbatim}
-% \begin{NiceMatrixBlock}[auto-columns-width]
-% \vbox{\hbox{\hphantom{~slshape#an open parenthesis@}
-% $\begin{NiceArray}{~slshape#preamble@}
-% ~slshape#first row@ \\
-% \end{NiceArray}$}
-% \hbox{$\begin{pNiceArrayC}{~slshape#preamble@}
-% ~slshape#second row@ \\
-% ~slshape#third row@ \\
-% ~slshape#etc.@ \\
-% \end{pNiceArrayC}$}}
-% \end{NiceMatrixBlock}
-% \end{Verbatim}
-%
-%
-% \bigskip
-% If the environment is used with a numerical value for the option |columns-width|, the construction
-%
-% \begin{Verbatim}
-% \begin{pNiceArrayRC}{~slshape#preamble@}[columns-width=~slshape#value@]
-% ~slshape#first row@ \\
-% ~slshape#second row@ \\
-% ~slshape#third row@ \\
-% ~slshape#etc.@ \\
-% \end{pNiceArrayRC}
-% \end{Verbatim}
-%
-% is transformed in the following contruction :
-%
-% \begin{Verbatim}
-% \NiceMatrixOptions{columns-width=~slshape#value@}
-% \vbox{\hbox{~slshape#skip of the width of a parenthesis@
-% $\begin{NiceArray}{~slshape#preamble@}
-% ~slshape#first row@ \\
-% \end{NiceArray}$}
-% \hbox{$\begin{pNiceArrayC}{~slshape#preamble@}
-% ~slshape#second row@ \\
-% ~slshape#third row@ \\
-% ~slshape#etc.@ \\
-% \end{pNiceArrayC}$}}
-% \end{Verbatim}
-%
-% (in the group created by the environment).
%
% \bigskip
% \begin{macrocode}
@@ -2992,15 +3677,25 @@ version 2005/12/01 or later.
code-for-first-row .tl_set:N = \l_@@_code_for_first_row_tl,
code-for-last-col .tl_set:N = \l_@@_code_for_last_col_tl,
code-for-last-col .value_required:n = true,
- columns-width .tl_set:N = \l_@@_columns_width_tl,
+ columns-width .code:n = \str_if_eq:nnTF {#1} {auto}
+ {\bool_set_true:N
+ \l_@@_auto_columns_width_bool}
+ {\dim_set:Nn \l_@@_columns_width_dim {#1}},
+ columns-width .value_required:n = true,
name .code:n = {\seq_if_in:NnTF \g_@@_names_seq {#1}
- {\msg_error:nnn {nicematrix}
- {Duplicate~name}
- {#1}}
+ {\@@_msg_error:nn {Duplicate~name} {#1}}
{\seq_gput_left:Nn \g_@@_names_seq {#1}}
- \tl_gset:Nn \l_@@_name_tl {#1}},
- code-after .tl_set:N = \l_@@_code_after_tl,
- unknown .code:n = \msg_error:nn {nicematrix} {Unknown~option~for~NiceArrayRC}}
+ \tl_set:Nn \l_@@_name_tl {#1}},
+ code-after .tl_set:N = \l_@@_code_after_tl,
+ create-extra-nodes .bool_set:N = \l_@@_extra_nodes_bool,
+ create-extra-nodes .default:n = true,
+ left-margin .dim_set:N = \l_@@_left_margin_dim,
+ left-margin .default:n = \arraycolsep,
+ right-margin .dim_set:N = \l_@@_right_margin_dim,
+ right-margin .default:n = \arraycolsep,
+ extra-left-margin .dim_set:N = \l_@@_extra_left_margin_dim,
+ extra-right-margin .dim_set:N = \l_@@_extra_right_margin_dim,
+ unknown .code:n = \@@_msg_error:n {Unknown~option~for~NiceArrayRC}}
% \end{macrocode}
%
% \begin{macrocode}
@@ -3014,83 +3709,55 @@ version 2005/12/01 or later.
code-after,~
code-for-last-col,~
code-for-first-row,~
- columns-width~(in~fact~mandatory),~
+ columns-width,~
+ create-extra-nodes,~
+ extra-left-margin,~
+ extra-right-margin,~
+ left~margin,~
name,~
nullify-dots,~
- parallelize-diags~
- and~renew-dots.}
+ parallelize-diags,~
+ renew-dots~
+ and~right~margin.}
% \end{macrocode}
%
-% \begin{macrocode}
-\msg_new:nnn {nicematrix}
- {The~key~columns-width~is~mandatory}
- {In~the~environment~\{\@currenvir\}~you~must~use~the~
- key~"columns-width"~either~with~a~numerical~value~
- or~the~special~value~"auto".\\
- If~you~go~on,~the~value~"auto"~will~be~used~for~
- "columns-width".}
-% \end{macrocode}
%
% The first and the second argument of the environment |{NiceArrayRCwithDelims}| are the delimiters which will be
% used in the array. Usually, the final user will not use directly this environment |{NiceArrayRCwithDelims}|
% because he will use one of the variants |{pNiceArrayRC}|, |{vNiceArrayRC}|, etc.
+%
% \begin{macrocode}
-\NewDocumentEnvironment{NiceArrayRCwithDelims} {mm O{} m O{}}
- {\tl_clear_new:N \l_@@_columns_width_tl
- \tl_clear_new:N \l_@@_name_tl
- \tl_clear_new:N \l_@@_code_after_tl
- \keys_set:nn {NiceMatrix/NiceArrayRC} {#3,#5}
- \tl_gset_eq:NN \g_@@_name_tl \l_@@_name_tl
- \tl_if_empty:NT \l_@@_columns_width_tl
- {\msg_error:nn {nicematrix} {The~key~columns-width~is~mandatory}
- \tl_set:Nn \l_@@_columns_width_tl {auto}}
- \str_if_eq:nVTF {auto} \l_@@_columns_width_tl
- {\begin{NiceMatrixBlock}[auto-columns-width]}
- {\NiceMatrixOptions{columns-width = \l_@@_columns_width_tl} }
- \vbox\bgroup\hbox\bgroup
-% \end{macrocode}
-% Here, it would be possible to use a |\hphantom| but we prefer to use \pkg{expl3} instructions.
-% \begin{macrocode}
- \hbox_set:Nn \l_tmpa_box {$\left#1\vbox_to_ht:nn{2cm}{}\right.$}
- \skip_horizontal:n {\box_wd:N \l_tmpa_box - \nulldelimiterspace}
-% \end{macrocode}
-% We give the value $-1$ to |\l_@@_number_of_first_row_int| and, therefore, the first row of the array will have
-% the number $0$ (the final user will use this value when using, for example, the command |\line| in |code-after|).
-% \begin{macrocode}
- \int_set:Nn \l_@@_number_of_first_row_int {-1}
- \tl_set_eq:NN \l_@@_code_for_cell_tl \l_@@_code_for_first_row_tl
-% \end{macrocode}
-% We read staticly the first row of the array given by the user because we will use the first row to
-% construct an environment |{NiceArray}|. \emph{We read until the first control sequence} |\\|. Therefore, it's not
-% possible to use a sub-array with this control sequence in the first row of the array.
-% \begin{macrocode}
- \cs_set:Npn \@@_replace_first_line ##1\\{
- $\begin{NiceArray}{*\c@MaxMatrixCols{C}}
- ##1
- \end{NiceArray}$
- \egroup \hbox\bgroup
-% \end{macrocode}
-% We decrement the number of the environment because we want the same number for both constructed environments.
-% \begin{macrocode}
- \int_gdecr:N \g_@@_env_int
- \tl_gset_eq:NN \g_@@_name_tl \l_@@_name_tl
- \tl_gset_eq:NN \g_@@_code_after_tl \l_@@_code_after_tl
- \bool_set_false:N \l_@@_direct_NiceArray_bool
- \dim_gzero_new:N \g_@@_width_last_col_dim
- \bool_set_false:N \l_@@_exterior_arraycolsep_bool
- \tl_set:Nn \l_@@_pos_env_tl c
- $\left#1 % $
+\NewDocumentEnvironment {NiceArrayRCwithDelims} {mm O{} m O{}}
+ {\int_zero:N \l_@@_nb_first_row_int
+ \dim_gzero_new:N \g_@@_width_last_col_dim
+ \keys_set:nn {NiceMatrix/NiceArrayRC} {#3,#5}
+ \bool_set_false:N \l_@@_exterior_arraycolsep_bool
+ \tl_set:Nn \l_@@_pos_env_tl c
+ \box_clear_new:N \l_@@_the_array_box
+ \hbox_set:Nw \l_@@_the_array_box
+ $ % $
\@@_NiceArrayC:n {#4}}
- \@@_replace_first_line
+ { \end{NiceArray}
+ $ % $
+ \hbox_set_end:
+ \dim_set:Nn \l_tmpa_dim
+ { ( \dim_max:nn {12pt}
+ {\g_@@_max_ht_row_one_dim + \g_@@_max_dp_row_zero_dim})
+ + \g_@@_max_ht_row_zero_dim
+ - \g_@@_max_ht_row_one_dim }
+ \hbox_set:Nn \l_tmpa_box
+ {$ % $
+ \left#1
+ \vcenter {\skip_vertical:n {- \l_tmpa_dim}
+ \box_use_drop:N \l_@@_the_array_box}
+ \right#2
+ $ % $
+ \skip_horizontal:n \g_@@_width_last_col_dim}
+ \box_set_ht:Nn \l_tmpa_box {\box_ht:N \l_tmpa_box + \l_tmpa_dim}
+ \box_use_drop:N \l_tmpa_box
}
- {\end{NiceArray}
- \right#2$ % $
- \skip_horizontal:n \g_@@_width_last_col_dim
- \egroup\egroup
- \str_if_eq:nVT {auto} \l_@@_columns_width_tl
- {\end{NiceMatrixBlock}} }
% \end{macrocode}
-%
+%
% \bigskip
% In the following environments, we don't use the form with |\begin{...}| and |\end{...}| because we use
% |\@currenvir| in the error message for an unknown option.
@@ -3125,13 +3792,256 @@ version 2005/12/01 or later.
% \end{macrocode}
%
%
+% \subsection{The extra nodes}
+%
+% First, two variants of the functions |\dim_min:nn| and |\dim_max:nn|.
+% \begin{macrocode}
+\cs_generate_variant:Nn \dim_min:nn {vn}
+\cs_generate_variant:Nn \dim_max:nn {vn}
+% \end{macrocode}
+%
+%
+%
+% \bigskip
+% For each row $i$, we compute two dimensions \texttt{l_@@_row_\textsl{i}_min_dim} and
+% \texttt{l_@@_row_\textsl{i}_max_dim}. The dimension \texttt{l_@@_row_\textsl{i}_min_dim} is the minimal
+% $y$-value of all the cells of the row~$i$. The dimension \texttt{l_@@_row_\textsl{i}_max_dim} is the maximal
+% $y$-value of all the cells of the row~$i$.
+%
+% Similarly, for each column $j$, we compute two dimensions \texttt{l_@@_column_\textsl{j}_min_dim} and
+% \texttt{l_@@_column_\textsl{j}_max_dim}. The dimension \texttt{l_@@_column_\textsl{j}_min_dim} is the minimal
+% $x$-value of all the cells of the column~$j$. The dimension \texttt{l_@@_column_\textsl{j}_max_dim} is the maximal
+% $x$-value of all the cells of the column~$j$.
+%
+% Since these dimensions will be computed as maximum or minimum, we initialize them to |\c_max_dim| or |-\c_max_dim|.
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_create_extra_nodes:
+ {\begin{tikzpicture}[remember~picture,overlay]
+ \int_step_variable:nnnNn \l_@@_nb_first_row_int 1 \g_@@_row_int \@@_i
+ {\dim_zero_new:c {l_@@_row_\@@_i _min_dim}
+ \dim_set_eq:cN {l_@@_row_\@@_i _min_dim} \c_max_dim
+ \dim_zero_new:c {l_@@_row_\@@_i _max_dim}
+ \dim_set:cn {l_@@_row_\@@_i _max_dim} {-\c_max_dim}}
+ \int_step_variable:nnnNn 1 1 \g_@@_column_total_int \@@_j
+ {\dim_zero_new:c {l_@@_column_\@@_j _min_dim}
+ \dim_set_eq:cN {l_@@_column_\@@_j _min_dim} \c_max_dim
+ \dim_zero_new:c {l_@@_column_\@@_j _max_dim}
+ \dim_set:cn {l_@@_column_\@@_j _max_dim} {-\c_max_dim}}
+% \end{macrocode}
+% We begin the two nested loops over the rows and the columns of the array.
+% \begin{macrocode}
+ \int_step_variable:nnnNn \l_@@_nb_first_row_int 1 \g_@@_row_int \@@_i
+ {\int_step_variable:nnnNn 1 1 \g_@@_column_total_int \@@_j
+% \end{macrocode}
+% Maybe the cell ($i$-$j$) is an implicit cell (that is to say a cell after implicit ampersands |&|). In this case,
+% of course, we don't update the dimensions we want to compute.
+% \begin{macrocode}
+ {\cs_if_exist:cT {pgf@sh@ns@nm-\int_use:N \g_@@_env_int-\@@_i-\@@_j}
+% \end{macrocode}
+% We retrieve the coordinates of the anchor |south west| of the (normal) node of the cell ($i$-$j$). They will be
+% stored in |\pgf@x| and |\pgf@y|.
+% \begin{macrocode}
+ {\tikz@parse@node \pgfutil@firstofone
+ (nm-\int_use:N \g_@@_env_int-\@@_i-\@@_j.south~west)
+ \dim_set:cn {l_@@_row_\@@_i _min_dim}
+ {\dim_min:vn {l_@@_row_\@@_i _min_dim} \pgf@y}
+ \seq_if_in:NxF \g_@@_multicolumn_cells_seq {\@@_i-\@@_j}
+ {\dim_set:cn {l_@@_column_\@@_j _min_dim}
+ {\dim_min:vn {l_@@_column_\@@_j _min_dim} \pgf@x}}
+% \end{macrocode}
+% We retrieve the coordinates of the anchor |north east| of the (normal) node of the cell ($i$-$j$). They will be
+% stored in |\pgf@x| and |\pgf@y|.
+% \begin{macrocode}
+ \tikz@parse@node \pgfutil@firstofone
+ (nm-\int_use:N \g_@@_env_int-\@@_i-\@@_j.north~east)
+ \dim_set:cn {l_@@_row_\@@_i _max_dim}
+ {\dim_max:vn {l_@@_row_\@@_i _max_dim} \pgf@y}
+ \seq_if_in:NxF \g_@@_multicolumn_cells_seq {\@@_i-\@@_j}
+ {\dim_set:cn {l_@@_column_\@@_j _max_dim}
+ {\dim_max:vn {l_@@_column_\@@_j _max_dim} \pgf@x}}}
+ }}
+% \end{macrocode}
+% Now, we can create the ``medium nodes''. We use a command |\@@_create_nodes:| because this command will also be used
+% for the creation of the ``large nodes'' (after changing the value of |name-suffix|).
+% \begin{macrocode}
+ \tikzset{name~suffix = -medium}
+ \@@_create_nodes:
+% \end{macrocode}
+%
+% \bigskip
+% For ``large nodes'', the eventual ``first row'' and ``last column'' (in environments like |{pNiceArrayRC}|) don't
+% interfer. That's why the loop over the rows will start at 1 and the loop over the columns will stop at
+% $|\g_@@_column_int|$ (and not |\g_@@_column_total_int|).\footnote{We recall that |\g_@@_column_total_int| is
+% equal to |\g_@@_column_int| except if there is an exterior column. In this case, |\g_@@_column_total_int| is equal
+% to |\g_@@_column_int|${}+1$.}
+% \begin{macrocode}
+ \int_set:Nn \l_@@_nb_first_row_int 1
+% \end{macrocode}
+% We have to change the values of all the dimensions \texttt{l_@@_row_\textsl{i}_min_dim},
+% \texttt{l_@@_row_\textsl{i}_max_dim}, \texttt{l_@@_column_\textsl{j}_min_dim} and
+% \texttt{l_@@_column_\textsl{j}_max_dim}.
+% \begin{macrocode}
+ \int_step_variable:nnnNn 1 1 {\g_@@_row_int-1} \@@_i
+ {\dim_set:cn {l_@@_row_\@@_i _min_dim}
+ {( \dim_use:c {l_@@_row_\@@_i _min_dim}
+ + \dim_use:c {l_@@_row_\int_eval:n{\@@_i+1}_max_dim}) / 2}
+ \dim_set_eq:cc {l_@@_row_\int_eval:n{\@@_i+1}_max_dim}
+ {l_@@_row_\@@_i _min_dim} }
+ \int_step_variable:nnnNn 1 1 {\g_@@_column_int-1} \@@_j
+ {\dim_set:cn {l_@@_column_\@@_j _max_dim}
+ {( \dim_use:c {l_@@_column_\@@_j _max_dim}
+ + \dim_use:c {l_@@_column_\int_eval:n{\@@_j+1}_min_dim}) / 2}
+ \dim_set_eq:cc {l_@@_column_\int_eval:n{\@@_j+1}_min_dim}
+ {l_@@_column_\@@_j _max_dim} }
+ \dim_sub:cn {l_@@_column_1_min_dim} \g_@@_left_margin_dim
+ \dim_add:cn {l_@@_column_\int_use:N \g_@@_column_int _max_dim}
+ \g_@@_right_margin_dim
+% \end{macrocode}
+% Now, we can actually create the ``large nodes''.
+% \begin{macrocode}
+ \tikzset{name~suffix = -large}
+ \@@_create_nodes:
+ \end{tikzpicture}
+% \end{macrocode}
+%
+% \medskip
+% When used once, the command |\@@_create_extra_nodes:| must become no-op (in the current TeX group). That's why we
+% put a nullification of the command.
+% \begin{macrocode}
+ \cs_set:Nn \@@_create_extra_nodes: {}}
+% \end{macrocode}
+%
+%
+% \bigskip
+% The control sequence |\@@_create_nodes:| is used twice: for the construction of the ``medium nodes'' and for the
+% construction of the ``large nodes''. The nodes are constructed with the value of all the dimensions
+% \texttt{l_@@_row_\textsl{i}_min_dim}, \texttt{l_@@_row_\textsl{i}_max_dim},
+% \texttt{l_@@_column_\textsl{j}_min_dim} and \texttt{l_@@_column_\textsl{j}_max_dim}. Between the
+% construction of the ``medium nodes'' and the ``large nodes'', the values of these dimensions are changed.
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_create_nodes:
+ {\int_step_variable:nnnNn \l_@@_nb_first_row_int 1 \g_@@_row_int \@@_i
+ {\int_step_variable:nnnNn 1 1 \g_@@_column_total_int \@@_j
+% \end{macrocode}
+% We create two ponctual nodes for the extremities of a diagonal of the rectangular node we want to create. These
+% nodes |(@@~south~west)| and |(@@~north~east)| are not available for the user of \pkg{nicematrix}. That's why
+% their names are independent of the row and the column. In the two nested loops, they will be overwritten until the
+% last cell.
+% \begin{macrocode}
+ {\coordinate (@@~south~west)
+ at (\dim_use:c {l_@@_column_\@@_j _min_dim},
+ \dim_use:c {l_@@_row_\@@_i _min_dim}) ;
+ \coordinate (@@~north~east)
+ at (\dim_use:c {l_@@_column_\@@_j _max_dim},
+ \dim_use:c {l_@@_row_\@@_i _max_dim}) ;
+% \end{macrocode}
+% We can eventually draw the rectangular node for the cell (|\@@_i|-|\@@_j|). This node is created with the Tikz library
+% \pkg{fit}. Don't forget that the Tikz option |name suffix| has been set to |-medium| or |-large|.
+% \begin{macrocode}
+ \draw node [fit = {(@@~south~west) (@@~north~east)},
+ inner~sep=0pt,
+ name = nm-\int_use:N \g_@@_env_int-\@@_i-\@@_j,
+ alias = \tl_if_empty:NF \g_@@_name_tl
+ {\tl_use:N \g_@@_name_tl-\@@_i-\@@_j}]
+ {} ;
+ }
+ }
+% \end{macrocode}
+% Now, we create the nodes for the cells of the |\multicolumn|. We recall that we have stored in
+% |\g_@@_multicolumn_cells_seq| the list of the cells where a |\multicolumn{|$n$|}{...}{...}| with $n$>1 was issued
+% and in |\g_@@_multicolumn_sizes_seq| the correspondant values of $n$.
+% \begin{macrocode}
+ \@@_seq_mapthread_function:NNN \g_@@_multicolumn_cells_seq
+ \g_@@_multicolumn_sizes_seq
+ \@@_node_for_multicolumn:nn
+ }
+% \end{macrocode}
+%
+%
+%
+% \begin{macrocode}
+\cs_set:Npn \@@_extract_coords: #1-#2\q_stop{\cs_set:Npn \@@_i {#1}
+ \cs_set:Npn \@@_j {#2}}
+% \end{macrocode}
+%
+% The command |\@@_node_for_multicolumn:nn| takes two arguments. The first is the position of the cell where the
+% command |\multicolumn{|$n$|}{...}{...}| was issued in the format $i$|-|$j$ and the second is the value of~$n$ (the
+% length of the ``multi-cell'').
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_node_for_multicolumn:nn
+ {\@@_extract_coords: #1\q_stop
+ \coordinate (@@~south~west)
+ at (\dim_use:c {l_@@_column_\@@_j _min_dim},
+ \dim_use:c {l_@@_row_\@@_i _min_dim}) ;
+ \coordinate (@@~north~east)
+ at (\dim_use:c {l_@@_column_\int_eval:n{\@@_j+#2-1}_max_dim},
+ \dim_use:c {l_@@_row_\@@_i _max_dim}) ;
+ \draw node [fit = {(@@~south~west) (@@~north~east)},
+ inner~sep=0pt,
+ name = nm-\int_use:N \g_@@_env_int-\@@_i-\@@_j,
+ alias = \tl_if_empty:NF \g_@@_name_tl
+ {\tl_use:N \g_@@_name_tl-\@@_i-\@@_j}]
+ {} ;
+ }
+% \end{macrocode}
+%
+%
+% \subsection{We process the options}
+%
+% We process the options when the package is loaded (with |\usepackage|) but we recommend to use
+% |\NiceMatrixOptions| instead.
+%
+% We must process these options after the definition of the environment |{NiceMatrix}| because the option
+% |renew-matrix| execute the code |\cs_set_eq:NN \env@matrix \NiceMatrix|.
+%
+% Of course, the command |\NiceMatrix| must be defined before such an instruction is executed.
+% \begin{macrocode}
+\ProcessKeysOptions {NiceMatrix}
+% \end{macrocode}
+%
+% \subsection{Code for \texttt{seq_mapthread_function:NNN}}
+%
+% In |\@@_create_nodes:| (used twice in |\@@_create_extra_nodes:| to create the ``medium nodes'' and ``large
+% nodes''), we want to use |\seq_mapthread_function:NNN| which is in \pkg{l3candidates}). For security, we define a
+% function |\@@_seq_mapthread_function:NNN|. We will delete the following code when |\seq_mapthread_function:NNN|
+% will be in \pkg{l3seq}.
+% \begin{macrocode}
+\cs_new:Npn \@@_seq_mapthread_function:NNN #1#2#3
+ {\group_begin:
+% \end{macrocode}
+% In the group, we can use |\seq_pop:NN| safely.
+% \begin{macrocode}
+ \int_step_inline:nnnn 1 1 {\seq_count:N #1}
+ {\seq_pop:NN #1 \l_tmpa_tl
+ \seq_pop:NN #2 \l_tmpb_tl
+ \exp_args:NVV #3 \l_tmpa_tl \l_tmpb_tl}
+ \group_end:
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_set:Nn \@@_renew_matrix:
+ {\RenewDocumentEnvironment {pmatrix} {}
+ {\begin{pNiceMatrix}}
+ {\end{pNiceMatrix}}
+ \RenewDocumentEnvironment {vmatrix} {}
+ {\begin{vNiceMatrix}}
+ {\end{vNiceMatrix}}
+ \RenewDocumentEnvironment {Vmatrix} {}
+ {\begin{VNiceMatrix}}
+ {\end{VNiceMatrix}}
+ \RenewDocumentEnvironment {bmatrix} {}
+ {\begin{bNiceMatrix}}
+ {\end{bNiceMatrix}}
+ \RenewDocumentEnvironment {Bmatrix} {}
+ {\begin{BNiceMatrix}}
+ {\end{BNiceMatrix}}}
+% \end{macrocode}
%
% \section{History}
%
% \subsection{Changes between versions 1.0 and 1.1}
%
-% Option |silent| (with this option, the impossible instructions are discarded silently).
-%
% The dotted lines are no longer drawn with Tikz nodes but with Tikz circles (for efficiency).
%
% Modification of the code which is now twice faster.
@@ -3144,8 +4054,6 @@ version 2005/12/01 or later.
%
% New environment |{pNiceArrayC}| and its variants.
%
-% We decrement |\g_@@_row_int| in |\@@_draw_lines:| to have the exact number of rows.
-%
% Correction of a bug in the definition of |{BNiceMatrix}|, |{vNiceMatrix}| and |{VNiceMatrix}| (in fact, it was a
% typo).
%
@@ -3166,9 +4074,16 @@ version 2005/12/01 or later.
% \subsection{Changes between version 1.4 and 2.0}
%
% The versions 1.0 to 1.4 of \pkg{nicematrix} were focused on the continuous dotted lines whereas the version 2.0 of
-% \pkg{nicematrix} provides differents features to improve the typesetting of mathematical matrices.
+% \pkg{nicematrix} provides different features to improve the typesetting of mathematical matrices.
+%
+% \subsection{Changes between version 2.0 and 2.1}
+%
+% New implementation of the environment |{pNiceArrayRC}|. With this new implementation, there is no restriction on
+% the width of the columns.
%
+% The package \pkg{nicematrix} no longer loads \pkg{mathtools} but only \pkg{amsmath}.
%
+% Creation of ``medium nodes'' and ``large nodes''.
% \endinput
% Local Variables:
% TeX-fold-mode: nil