diff options
Diffstat (limited to 'Master/texmf-dist/source')
-rw-r--r-- | Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx | 3825 |
1 files changed, 2253 insertions, 1572 deletions
diff --git a/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx b/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx index 9e446e9d488..ede600b7d78 100644 --- a/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx +++ b/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx @@ -15,8 +15,8 @@ % % \fi % \iffalse -\def\myfileversion{3.12} -\def\myfiledate{2020/02/28} +\def\myfileversion{3.13} +\def\myfiledate{2020/03/15} % % %<*batchfile> @@ -52,6 +52,8 @@ version 2005/12/01 or later. \geometry{left=2.8cm,right=2.8cm,top=2.5cm,bottom=2.5cm,papersize={21cm,29.7cm}} \usepackage{colortbl} +\usepackage{tikz} +\usetikzlibrary{fit} \usepackage{nicematrix} \usepackage{siunitx} @@ -67,7 +69,7 @@ version 2005/12/01 or later. \usepackage{arydshln} \setlength{\columnseprule}{0.4pt} \usepackage{footnotehyper} -\usepackage{unicode-math} +\usepackage{varwidth} \parindent 0pt \EnableCrossrefs @@ -107,8 +109,9 @@ version 2005/12/01 or later. % the classical workflow |latex|-|dvips|-|ps2pdf| (or Adobe Distiller). Two or % three compilations may be necessary. This package requires and \textbf{loads} % the packages \pkg{expl3}, \pkg{l3keys2e}, \pkg{xparse}, \pkg{array}, -% \pkg{amsmath} and \pkg{tikz}. It also loads the Tikz library \pkg{fit}. The -% final user only has to load the extension with |\usepackage{nicematrix}|. +% \pkg{amsmath}, \pkg{pgfcore} and the module \pkg{shapes} of \textsc{pgf} +% (\pkg{tikz} is \emph{not} loaded). The final user only has to load the +% extension with |\usepackage{nicematrix}|. % % % \medskip @@ -242,22 +245,25 @@ version 2005/12/01 or later. % ``non-empty cell'' is given below (cf. p.~\pageref{empty-cells}).} on both % sides of the current cell. Of course, for |\Ldots| and |\Cdots|, it's an % horizontal line; for |\Vdots|, it's a vertical line and for |\Ddots| and -% |\Iddots| diagonal ones.\par\nobreak +% |\Iddots| diagonal ones. It's possible to change the color of these lines +% with the option |color|.\footnote{It's also possible to change the color of +% all theses dotted lines with the option |xdots/color| (\textsl{xdots} to +% remind that it works for |\Cdots|, |\Ldots|, |\Vdots|, etc.)}\par\nobreak % % \bigskip % \begin{BVerbatim}[baseline=c,boxwidth=10cm] % \begin{bNiceMatrix} -% a_1 & \Cdots & & & a_1 \\ -% \Vdots & a_2 & \Cdots & & a_2 \\ -% & \Vdots & \Ddots \\ +% a_1 & \Cdots & & & a_1 \\ +% \Vdots & a_2 & \Cdots & & a_2 \\ +% & \Vdots & \Ddots[color=red] \\ % \\ % a_1 & a_2 & & & a_n % \end{bNiceMatrix} % \end{BVerbatim} % $\begin{bNiceMatrix} -% a_1 & \Cdots & & & a_1 \\ -% \Vdots & a_2 & \Cdots & & a_2 \\ -% & \Vdots & \Ddots \\ +% a_1 & \Cdots & & & a_1 \\ +% \Vdots & a_2 & \Cdots & & a_2 \\ +% & \Vdots & \Ddots[color=red] \\ % \\ % a_1 & a_2 & & & a_n % \end{bNiceMatrix}$ @@ -357,109 +363,78 @@ version 2005/12/01 or later. % \end{bNiceMatrix}$ % % \subsection{The option nullify-dots} +% % % Consider the following matrix composed classicaly with the environment -% |{pmatrix}| of \pkg{amsmath}.\par\nobreak -% +% \verb|{pmatrix}| of \pkg{amsmath}.\par\nobreak +% % \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=8cm] +% \begin{BVerbatim}[baseline=c,boxwidth=10cm] % $A = \begin{pmatrix} -% a_0 & b \\ -% a_1 & \\ -% a_2 & \\ -% a_3 & \\ -% a_4 & \\ -% a_5 & b +% h & i & j & k & l & m \\ +% x & & & & & x \\ % \end{pmatrix}$ % \end{BVerbatim} % $A = \begin{pmatrix} -% a_0 & b \\ -% a_1 & \\ -% a_2 & \\ -% a_3 & \\ -% a_4 & \\ -% a_5 & b +% h & i & j & k & l & m \\ +% x & & & & & x \\ % \end{pmatrix}$ % % % \bigskip -% If we add |\vdots| instructions in the second column, the geometry of the +% If we add \verb|\ldots| instructions in the second row, the geometry of the % matrix is modified.\par\nobreak % % \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=8cm] +% \begin{BVerbatim}[baseline=c,boxwidth=10cm] % $B = \begin{pmatrix} -% a_0 & b \\ -% a_1 & \vdots \\ -% a_2 & \vdots \\ -% a_3 & \vdots \\ -% a_4 & \vdots \\ -% a_5 & b +% h & i & j & k & l & m \\ +% x & \ldots & \ldots & \ldots & \ldots & x \\ % \end{pmatrix}$ % \end{BVerbatim} % $B = \begin{pmatrix} -% a_0 & b \\ -% a_1 & \vdots \\ -% a_2 & \vdots \\ -% a_3 & \vdots \\ -% a_4 & \vdots \\ -% a_5 & b +% h & i & j & k & l & m \\ +% x & \ldots & \ldots & \ldots & \ldots & x \\ % \end{pmatrix}$ % % \bigskip -% By default, with \pkg{nicematrix}, if we replace |{pmatrix}| by -% |{pNiceMatrix}| and |\vdots| by |\Vdots|, the geometry of the matrix is not +% By default, with \pkg{nicematrix}, if we replace \verb|{pmatrix}| by +% \verb|{pNiceMatrix}| and \verb|\ldots| by \verb|\Ldots|, the geometry of the matrix is not % changed.\par\nobreak % % \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=8cm] +% \begin{BVerbatim}[baseline=c,boxwidth=10cm] % $C = \begin{pNiceMatrix} -% a_0 & b \\ -% a_1 & \Vdots \\ -% a_2 & \Vdots \\ -% a_3 & \Vdots \\ -% a_4 & \Vdots \\ -% a_5 & b +% h & i & j & k & l & m \\ +% x & \Ldots & \Ldots & \Ldots & \Ldots & x \\ % \end{pNiceMatrix}$ % \end{BVerbatim} % $C = \begin{pNiceMatrix} -% a_0 & b \\ -% a_1 & \Vdots \\ -% a_2 & \Vdots \\ -% a_3 & \Vdots \\ -% a_4 & \Vdots \\ -% a_5 & b +% h & i & j & k & l & m \\ +% x & \Ldots & \Ldots & \Ldots & \Ldots & x \\ % \end{pNiceMatrix}$ % % \bigskip % However, one may prefer the geometry of the first matrix $A$ and would like to -% have such a geometry with a dotted line in the second column. It's possible by -% using the option |nullify-dots| (and only one instruction |\Vdots| is +% have such a geometry with a dotted line in the second row. It's possible by +% using the option \verb|nullify-dots| (and only one instruction \verb|\Ldots| is % necessary).\par\nobreak % % \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=8cm] +% \begin{BVerbatim}[baseline=c,boxwidth=10cm] % $D = \begin{pNiceMatrix}[~emphase#nullify-dots@] -% a_0 & b \\ -% a_1 & \Vdots \\ -% a_2 & \\ -% a_3 & \\ -% a_4 & \\ -% a_5 & b +% h & i & j & k & l & m \\ +% x & \Ldots & & & & x \\ % \end{pNiceMatrix}$ % \end{BVerbatim} % $D = \begin{pNiceMatrix}[nullify-dots] -% a_0 & b \\ -% a_1 & \Vdots \\ -% a_2 & \\ -% a_3 & \\ -% a_4 & \\ -% a_5 & b +% h & i & j & k & l & m \\ +% x & \Ldots & & & & x \\ % \end{pNiceMatrix}$ % % \medskip % The option |nullify-dots| smashes the instructions |\Ldots| (and the variants) -% vertically but also horizontally. +% horizontally but also vertically. % % \medskip % \textbf{There must be no space before the opening bracket (|[|) of the options @@ -576,25 +551,118 @@ version 2005/12/01 or later. % \end{pmatrix}$ % \end{scope} % -% \subsection{Fine tuning of the dotted lines} +% \subsection{Customization of the dotted lines} % -% The distance between a node and the end of a dotted line is set by -% |dotted-lines-margin|. The initial value of this key is $0.3$~em (it's -% recommended to use a unit dependent of the current font). For an example, -% cf.~p.~\pageref{permutation}. +% The dotted lines drawn by |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots|, |\Iddots| +% and |\Hdotsfor| (and by the command |\line| in the |code-after| which is described +% in p.~\pageref{line-in-code-after}) may be customized by three options (specified +% between square brackets after the command): +% \begin{itemize} +% \item |color|; +% \item |shorten|; +% \item |line-style|. +% \end{itemize} +% +% These options may also be fixed with |\NiceMatrixOptions| or at the level of a +% given environment but, in those cases, they must be prefixed by |xdots|, and, +% thus have for names: +% \begin{itemize} +% \item |xdots/color|; +% \item |xdots/shorten|; +% \item |xdots/line-style|. +% \end{itemize} +% +% For the clarity of the explanations, we will use those names. +% +% \bigskip +% \textbf{The option xdots/color}\par\nobreak +% +% \smallskip +% The option |xdots/color| fixes the color or the dotted line. However, one should +% remark that the dotted lines drawn in the exterior rows and columns have a +% special treatment: cf. p.~\pageref{exterior}. % +% \bigskip +% \textbf{The option xdots/shorten}\par\nobreak +% +% \smallskip +% The option |xdots/shorten| fixes the margin of both extremities of the line. +% The name is derived from the options ``|shorten >|'' and ``|shorten <|'' of +% Tikz but one should notice that \pkg{nicematrix} only provides +% |xdots/shorten|. The initial value of this parameter is 0.3~em (it is +% recommanded to use a unit of length dependent of the current font). % -% \section{The Tikz nodes created by nicematrix} +% \bigskip +% \textbf{The option xdots/line-style}\par\nobreak +% +% \smallskip +% It should be pointed that, by default, the lines drawn by Tikz with the +% parameter |dotted| are composed of square dots (and not rounded +% ones).\footnote{The first reason of this behaviour is that the \textsc{pdf} +% format includes a description for dashed lines. The lines specified with this +% descriptor are displayed very efficiently by the \textsc{pdf} readers. It's +% easy, starting from these dashed lines, +% to create a line composed by square dots whereas a line of rounded dots needs +% a specification of each dot in the \textsc{pdf} file.} +% +% \begin{BVerbatim}[baseline=c,boxwidth=9cm] +% \tikz \draw [dotted] (0,0) -- (5,0) ; +% \end{BVerbatim} +% \tikz \draw [dotted] (0,0) -- (5,0) ; +% +% \medskip +% In order to provide lines with rounded dots in the style of those provided by +% |\ldots| (at least with the \emph{Computer Modern} fonts), the extension +% \pkg{nicematrix} embeds its own system to draw a dotted line (and this system +% uses \textsc{pgf} and not Tikz). This style is called |standard| and that's +% the initial value of the parameter |xdots/line-style|. +% +% However (when Tikz is loaded) it's possible to use for |xdots/line-style| any style +% provided by Tikz, that is to say any sequence of options provided by Tikz for +% the Tizk pathes (with the exception of ``|color|'', ``|shorten >|'' and +% ``|shorten <|''). +% +% \medskip +% Here is for example a tridiagonal matrix with the style |loosely dotted|:\par\nobreak +% +% \medskip +% \begin{BVerbatim}[baseline=c] +% $\begin{pNiceMatrix}[nullify-dots,~emphase#xdots/line-style=loosely dotted@] +% a & b & 0 & & \Cdots & 0 \\ +% b & a & b & \Ddots & & \Vdots \\ +% 0 & b & a & \Ddots & & \\ +% & \Ddots & \Ddots & \Ddots & & 0 \\ +% \Vdots & & & & & b \\ +% 0 & \Cdots & & 0 & b & a +% \end{pNiceMatrix}$ +% \end{BVerbatim} +% +% +% \[\begin{pNiceMatrix}[nullify-dots,xdots/line-style=loosely dotted] +% a & b & 0 & & \Cdots & 0 \\ +% b & a & b & \Ddots & & \Vdots \\ +% 0 & b & a & \Ddots & & \\ +% & \Ddots & \Ddots & \Ddots & & 0 \\ +% \Vdots & & & & & b \\ +% 0 & \Cdots & & 0 & b & a +% \end{pNiceMatrix}\] +% +% +% +% \section{The PGF/Tikz nodes created by nicematrix} % % \label{name} % -% The package \pkg{nicematrix} creates a Tikz node for each cell of the -% considered array. These nodes are used to draw the dotted lines between the -% cells of the matrix. However, the user may wish to use directly these nodes. -% It's possible. First, the user have to give a name to the array (with the key -% called |name|). Then, the nodes are accessible through the names -% ``\textsl{name}-$i$-$j$'' where \textsl{name} is the name given to the array -% and $i$ and $j$ the numbers of the row and the column of the considered cell. +% The package \pkg{nicematrix} creates a PGF/Tikz node for each (non-empty) cell +% of the considered array. These nodes are used to draw the dotted lines between +% the cells of the matrix. However, the user may wish to use directly these +% nodes. It's possible (if Tikz has been loaded\footnote{We remind that, since +% the version 3.13, \pkg{nicematrix} doesn't load Tikz by default by only +% \textsc{pgf} (Tikz is a layer over \textsc{pfg}).}). First, the user have to +% give a name to the array (with the key called |name|). Then, the nodes are +% accessible through the names ``\textsl{name}-$i$-$j$'' where \textsl{name} is +% the name given to the array and $i$ and $j$ the numbers of the row and the +% column of the considered cell. % % \medskip % \begin{BVerbatim}[baseline=c,boxwidth=11cm] @@ -619,14 +687,25 @@ version 2005/12/01 or later. % % \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} +% \[\begin{pNiceMatrix}[ +% code-after = {\begin{tikzpicture} +% [every node/.style = {blend mode = multiply, +% fill = red!15, +% inner sep = 0 pt }] +% \node [fit = (1-1)] {} ; +% \node [fit = (1-3)] {} ; +% \node [fit = (2-2)] {} ; +% \node [fit = (3-1)] {} ; +% \node [fit = (3-3)] {} ; +% \node [fit = (1-2)] {} ; +% \node [fit = (2-1)] {} ; +% \node [fit = (2-3)] {} ; +% \node [fit = (3-2)] {} ; +% \end{tikzpicture}}] % a & a + b & a + b + c \\ % a & a & a + b \\ % a & a & a % \end{pNiceMatrix}\] -% \end{scope} % % % \bigskip @@ -647,7 +726,7 @@ version 2005/12/01 or later. % code-after = {\begin{tikzpicture} % [every node/.style = {fill = red!15, % blend mode = multiply, -% inner sep = -\pgflinewidth/2}, +% inner sep = 0pt}, % name suffix = -medium] % \node [fit = (1-1)] {} ; % \node [fit = (1-2)] {} ; @@ -676,7 +755,7 @@ version 2005/12/01 or later. % create-large-nodes, % code-after = {\begin{tikzpicture} % [every node/.style = {blend mode = multiply, -% inner sep = -\pgflinewidth/2}, +% inner sep = 0pt}, % name suffix = -large] % \node [fit = (1-1),fill = red!15] {} ; % \node [fit = (1-3),fill = red!15] {} ; @@ -708,7 +787,7 @@ version 2005/12/01 or later. % create-large-nodes,left-margin,right-margin, % code-after = {\begin{tikzpicture} % [every node/.style = {blend mode = multiply, -% inner sep = -\pgflinewidth/2}, +% inner sep = 0pt}, % name suffix = -large] % \node [fit = (1-1),fill = red!15] {} ; % \node [fit = (1-3),fill = red!15] {} ; @@ -735,7 +814,7 @@ version 2005/12/01 or later. % create-large-nodes,margin,extra-margin=3pt, % code-after = {\begin{tikzpicture} % [every node/.style = {blend mode = multiply, -% inner sep = -\pgflinewidth/2}, +% inner sep = 0 pt}, % name suffix = -large] % \node [fit = (1-1),fill = red!15] {} ; % \node [fit = (1-3),fill = red!15] {} ; @@ -760,7 +839,7 @@ version 2005/12/01 or later. % extra-left-margin=3pt, % code-after = {\begin{tikzpicture} % [every node/.style = {blend mode = multiply, -% inner sep = -\pgflinewidth/2}, +% inner sep = 0 pt}, % name suffix = -large] % \node [fit = (1-1),fill = red!15] {} ; % \node [fit = (1-3),fill = red!15] {} ; @@ -783,25 +862,30 @@ version 2005/12/01 or later. % % \section{The code-after} % +% \label{code-after} % The option |code-after| may be used to give some code that will be excuted -% after the construction of the matrix (and, hence, after the construction of -% all the Tikz nodes). +% after the construction of the matrix (and thus after the construction of +% all the nodes). % -% 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). +% \smallskip +% \textbf{If Tikz is loaded}\footnote{We remind that, since the version 3.13, +% \pkg{nicematrix} doesn't load Tikz by default but only \textsc{pgf} (Tikz is a +% layer over \textsc{pfg}).}, one may access to that nodes with classical Tikz +% instructions. The nodes should be designed as $i$-$j$ (without the prefix +% corresponding to the name of the environment). % -% Moreover, 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. \label{line-in-code-after} % % \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=12cm] -% $\begin{pNiceMatrix}[~emphase#code-after = \line{1-1}{3-3}@] +% \begin{BVerbatim}[baseline=c,boxwidth=13cm] +% $\begin{pNiceMatrix}[~emphase#code-after = {\line{1-1}{3-3}[color=blue]}@] % 0 & 0 & 0 \\ % 0 & & 0 \\ % 0 & 0 & 0 % \end{pNiceMatrix}$ % \end{BVerbatim} -% $\begin{pNiceMatrix}[code-after = \line{1-1}{3-3}] +% $\begin{pNiceMatrix}[code-after = {\line{1-1}{3-3}[color=blue]}] % 0 & 0 & 0 \\ % 0 & & 0 \\ % 0 & 0 & 0 @@ -1001,30 +1085,34 @@ version 2005/12/01 or later. % \pkg{nicematrix}. % \label{exterior} % -% A potential first row has the number $0$ (and not $1$). Idem for the potential -% first column. In general cases, one must specify the number of the last row -% and the number of the last column as values of |last-row| and |last-col|. +% A potential ``first row'' (exterior) has the number $0$ (and not $1$). Idem +% for the potential ``first column''. In general cases, one must specify the +% number of the last row and the number of the last column as values of +% |last-row| and |last-col|. % % \begin{Verbatim} % $\begin{pNiceMatrix}[~emphase#first-row,last-row=5,first-col,last-col=5@] -% & C_1 & C_2 & C_3 & C_4 & \\ -% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\ -% L_2 & a_{21} & a_{22} & a_{23} & a_{24} & L_2 \\ -% L_3 & a_{31} & a_{32} & a_{33} & a_{34} & L_3 \\ -% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\ -% & C_1 & C_2 & C_3 & C_4 & +% $\begin{pNiceMatrix}[~emphase#first-row,last-row=5,first-col,last-col=5@,nullify-dots] +% & C_1 & \Cdots & & C_4 & \\ +% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\ +% \Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\ +% & a_{31} & a_{32} & a_{33} & a_{34} & \\ +% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\ +% & C_1 & \Cdots & & C_4 & +% \end{pNiceMatrix}$ % \end{pNiceMatrix}$ % \end{Verbatim} % -% \[\begin{pNiceMatrix}[first-row,last-row=5,first-col,last-col=5] -% & C_1 & C_2 & C_3 & C_4 & \\ -% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\ -% L_2 & a_{21} & a_{22} & a_{23} & a_{24} & L_2 \\ -% L_3 & a_{31} & a_{32} & a_{33} & a_{34} & L_3 \\ -% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\ -% & C_1 & C_2 & C_3 & C_4 & +% \[\begin{pNiceMatrix}[first-row,last-row=5,first-col,last-col=5,nullify-dots] +% & C_1 & \Cdots & & C_4 & \\ +% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\ +% \Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\ +% & a_{31} & a_{32} & a_{33} & a_{34} & \\ +% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\ +% & C_1 & \Cdots & & C_4 & % \end{pNiceMatrix}\] % +% % \bigskip % We have several remarks to do. % \begin{itemize} @@ -1055,14 +1143,14 @@ version 2005/12/01 or later. % ~emphase#code-for-first-col@ = \color{blue}, % ~emphase#code-for-last-row@ = \color{green}, % ~emphase#code-for-last-col@ = \color{magenta}} -% $\begin{pNiceArray}{CC|CC}[first-row,last-row,first-col,last-col] -% & C_1 & C_2 & C_3 & C_4 & \\ -% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\ -% L_2 & a_{21} & a_{22} & a_{23} & a_{24} & L_2 \\ +% $\begin{pNiceArray}{CC|CC}[first-row,last-row,first-col,last-col,nullify-dots] +% & C_1 & \Cdots & & C_4 & \\ +% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\ +% \Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\ % \hline -% L_3 & a_{31} & a_{32} & a_{33} & a_{34} & L_3 \\ -% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\ -% & C_1 & C_2 & C_3 & C_4 & +% & a_{31} & a_{32} & a_{33} & a_{34} & \\ +% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\ +% & C_1 & \Cdots & & C_4 & % \end{pNiceArray}$ % \end{Verbatim} % @@ -1071,15 +1159,17 @@ version 2005/12/01 or later. % code-for-first-col = \color{blue}, % code-for-last-row = \color{green}, % code-for-last-col = \color{magenta}} -% \[\begin{pNiceArray}{CC|CC}[first-row,last-row,first-col,last-col] -% & C_1 & \multicolumn1C{C_2} & C_3 & C_4 & \\ -% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\ -% L_2 & a_{21} & a_{22} & a_{23} & a_{24} & L_2 \\ +% \begin{displaymath} +% \begin{pNiceArray}{CC|CC}[first-row,last-row,first-col,last-col,nullify-dots] +% & C_1 & \multicolumn1C{\Cdots} & & C_4 & \\ +% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\ +% \Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\ % \hline -% L_3 & a_{31} & a_{32} & a_{33} & a_{34} & L_3 \\ -% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\ -% & C_1 & \multicolumn1C{C_2} & C_3 & C_4 & -% \end{pNiceArray}\] +% & a_{31} & a_{32} & a_{33} & a_{34} & \\ +% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\ +% & C_1 & \multicolumn1C{\Cdots} & & C_4 & +% \end{pNiceArray} +% \end{displaymath} % \end{scope} % % @@ -1099,6 +1189,10 @@ version 2005/12/01 or later. % rules (for example thicker than the standard rules), he should consider the % command |\OnlyMainNiceMatrix| described on page~\pageref{OnlyMainNiceMatrix}. % +% \item A specification of color present in |code-for-first-row| also applies to +% a dotted line draw in this exterior ``first row'' (excepted if a value has +% been given to |xdots/color|). Idem for the other exterior rows and columns. +% % \item Logically, the potential option |columns-width| (described % p.~\pageref{width}) doesn't apply to the ``first column'' and ``last column''. % \item For technical reasons, it's not possible to use the option of the @@ -1116,7 +1210,7 @@ version 2005/12/01 or later. % In the environments of the extension \pkg{nicematrix}, it's possible to use % the command |\hdottedline| (provided by \pkg{nicematrix}) which is a % counterpart of the classical commands |\hline| and |\hdashline| (the latter is -% a command of\pkg{arydshln}). +% a command of \pkg{arydshln}). % % \medskip % \begin{BVerbatim}[baseline=c,boxwidth=9.5cm] @@ -1195,28 +1289,36 @@ version 2005/12/01 or later. % % \medskip % \begin{BVerbatim}[baseline=c,boxwidth=9.5cm] -% \NiceMatrixOptions{letter-for-dotted-lines = V} -% \left(\begin{NiceArray}{~emphase#C|C:CVC@} +% \NiceMatrixOptions{letter-for-dotted-lines = I} +% \arrayrulecolor{blue} +% \left(\begin{NiceArray}{~emphase#C|C:CIC@} % 1 & 2 & 3 & 4 \\ % 5 & 6 & 7 & 8 \\ % 9 & 10 & 11 & 12 % \end{NiceArray}\right) +% \arrayrulecolor{black} % \end{BVerbatim} % \begin{scope} -% \NiceMatrixOptions{letter-for-dotted-lines = V} -% $\left(\begin{NiceArray}{C|C:CVC} +% \NiceMatrixOptions{letter-for-dotted-lines = I} +% \arrayrulecolor{blue} +% $\left(\begin{NiceArray}{C|C:CIC} % 1 & 2 & 3 & 4 \\ % 5 & 6 & 7 & 8 \\ % 9 & 10 & 11 & 12 % \end{NiceArray}\right)$ +% \arrayrulecolor{black} % \end{scope} +% +% \smallskip +% We have used the command |\arrayrulecolor| (de \pkg{colortbl}) to draw in blue +% the three rules. % % \bigskip % \emph{Remark} : In the extension \pkg{array} (on which the extension % \pkg{nicematrix} relies), horizontal and vertical rules make the array larger % or wider by a quantity equal to the width of the rule\footnote{In fact, this % is true only for |\hline| and ``"|"'' but not for |\cline|.}. In -% \pkg{nicematrix}, the dotted lines drawn |\hdottedline| and ``|:|'' do +% \pkg{nicematrix}, the dotted lines drawn by |\hdottedline| and ``|:|'' do % likewise. % % @@ -1226,7 +1328,10 @@ version 2005/12/01 or later. % % In the environments with an explicit preamble (like |{NiceArray}|, % |{pNiceArray}|, etc.), it's possible to fix the width of a given column with -% the standard letters |w| and |W| of the package \pkg{array}. +% the standard letters |w| and |W| of the package \pkg{array}. In the +% environments of \pkg{nicematrix}, the cells of such columns are composed in +% mathematical mode, whereas, in |{array}| of \pkg{array}, they are composed in +% text mode. % % \medskip % \begin{BVerbatim}[baseline=c,boxwidth=10cm] @@ -1244,8 +1349,8 @@ version 2005/12/01 or later. % % % \bigskip -% In the environments of \pkg{nicematrix}, it's also possible to fix the width -% of all the columns of a matrix directly with the option |columns-width|. +% In the environments of \pkg{nicematrix}, it's also possible to fix the \emph{minimal} +% width of all the columns of a matrix directly with the option |columns-width|. % % \medskip % \begin{BVerbatim}[baseline=c,boxwidth=10cm] @@ -1288,8 +1393,9 @@ version 2005/12/01 or later. % \end{pNiceMatrix}$ % % \bigskip -% Without surprise, it's possible to fix the width of the columns of all the -% matrices of a current scope with the command |\NiceMatrixOptions|.\par\nobreak +% Without surprise, it's possible to fix the minimal 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] @@ -1437,6 +1543,29 @@ version 2005/12/01 or later. % % \section{Advanced features} % +% +% \subsection{Alignement option in NiceMatrix} +% +% The environments without preamble (|{NiceMatrix}|, |{pNiceMatrix}|, +% |{bNiceMatrix}|, etc.) provide two options |l| and |r| (equivalent at |L| and +% |R|) which generate all the columns aligned leftwards (or +% rightwards).\footnote{This is a part of the functionality provided by the +% environments |{pmatrix*}|, |{bmatrix*}|, etc. of \pkg{mathtools}.} +% +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=10cm] +% $\begin{bNiceMatrix}[R] +% \cos x & - \sin x \\ +% \sin x & \cos x +% \end{bNiceMatrix}$ +% \end{BVerbatim} +% $\begin{bNiceMatrix}[R] +% \cos x & - \sin x \\ +% \sin x & \cos x +% \end{bNiceMatrix}$ +% +% % \subsection{The command \textbackslash rotate} % % The package \pkg{nicematrix} provides a command |\rotate|. When used in the @@ -1447,33 +1576,63 @@ version 2005/12/01 or later. % %\bigskip % -% \begin{BVerbatim}[baseline=c,boxwidth=12cm] +%\begin{BVerbatim}[baseline=c,boxwidth=12cm] % \NiceMatrixOptions% % {code-for-first-row = \scriptstyle ~emphase#\rotate@ \text{image of }, % code-for-last-col = \scriptstyle } -% $\begin{pNiceMatrix}[first-row,last-col=4] +% $A = \begin{pNiceMatrix}[first-row,last-col=4] +% e_1 & e_2 & e_3 \\ +% 1 & 2 & 3 & e_1 \\ +% 4 & 5 & 6 & e_2 \\ +% 7 & 8 & 9 & e_3 \\ +% \end{pNiceMatrix}$ +% \end{BVerbatim} +% \begin{varwidth}{10cm} +% \NiceMatrixOptions% +% {code-for-first-row = \scriptstyle\rotate \text{image of }, +% code-for-last-col = \scriptstyle } +% $ A = \begin{pNiceMatrix}[first-row,last-col=4] % e_1 & e_2 & e_3 \\ % 1 & 2 & 3 & e_1 \\ % 4 & 5 & 6 & e_2 \\ % 7 & 8 & 9 & e_3 \\ % \end{pNiceMatrix}$ -% \end{BVerbatim} -% \begin{scope} +% \end{varwidth} +% +% \bigskip +% If the command |\rotate| is used in the ``last row'' (exterior to the matrix), +% the corresponding elements are aligned upwards as shown below. +% +% \bigskip +% \begin{BVerbatim}[baseline=c,boxwidth=12cm] % \NiceMatrixOptions% -% {code-for-first-row = \scriptstyle\rotate \text{image of }, +% {code-for-last-row = \scriptstyle ~emphase#\rotate@ , % code-for-last-col = \scriptstyle } -% \begin{minipage}{3cm} -% $\begin{pNiceMatrix}[first-row,last-col=4] -% e_1 & e_2 & e_3 \\ +% $A = \begin{pNiceMatrix}[last-row,last-col=4] % 1 & 2 & 3 & e_1 \\ % 4 & 5 & 6 & e_2 \\ % 7 & 8 & 9 & e_3 \\ +% \text{image of } e_1 & e_2 & e_3 \\ % \end{pNiceMatrix}$ -% \end{minipage} -% \end{scope} +% \end{BVerbatim} +% \begin{varwidth}{10cm} +% \NiceMatrixOptions% +% {code-for-last-row = \scriptstyle\rotate , +% code-for-last-col = \scriptstyle }% +% $A = \begin{pNiceMatrix}[last-row,last-col=4] +% 1 & 2 & 3 & e_1 \\ +% 4 & 5 & 6 & e_2 \\ +% 7 & 8 & 9 & e_3 \\ +% \text{image of } e_1 & e_2 & e_3 \\ +% \end{pNiceMatrix}$ +% \end{varwidth} +% +% % % \subsection{The option small} % +% \label{small} +% % With the option |small|, the environments of the extension \pkg{nicematrix} % are composed in a way similar to the environment |{smallmatrix}| of the % extension \pkg{amsmath} (and the environments |{psmallmatrix}|, @@ -1521,10 +1680,14 @@ version 2005/12/01 or later. % % In the cells of the array, it's possible to use the LaTeX counters |iRow| and % |jCol| which represent the number of the current row and the number of the -% current column\footnote{We recall that the first row (if it exists) has the -% number~$0$ and that the first column (if it exists) has also the number~$0$.}. -% Of course, the user must not change the value of these counters which are used -% internally by \pkg{nicematrix}. +% current column\footnote{We recall that the exterior ``first row'' (if it +% exists) has the number~$0$ and that the exterior ``first column'' (if it +% exists) has also the number~$0$.}. Of course, the user must not change the +% value of these counters which are used internally by \pkg{nicematrix}. +% +% In the |code-after| (cf. p. \pageref{code-after}), |iRow| represents the total +% number of rows (excepted the potential exterior rows) and |jCol| represents +% the total number of columns (excepted the potential exterior columns). % % \medskip % \begin{BVerbatim}[baseline=c,boxwidth=10.6cm] @@ -1675,20 +1838,18 @@ version 2005/12/01 or later. % % \medskip % \begin{scope} -% \def\alpha{$α$} -% \def\beta{$β$} % \begin{BVerbatim}[baseline=c,boxwidth=10cm] % $\begin{bNiceMatrix}[~emphase#light-syntax@,first-row,first-col] -% {} ~alpha ~beta ; -% ~alpha 2\cos ~alpha {\cos ~alpha + \cos ~beta} ; -% ~beta \cos ~alpha+\cos ~beta { 2 \cos ~beta } +% {} a b ; +% a 2\cos a {\cos a + \cos b} ; +% b \cos a+\cos b { 2 \cos b } % \end{bNiceMatrix}$ % \end{BVerbatim} % \end{scope} % $\begin{bNiceMatrix}[light-syntax,first-row,first-col] -% {} α β ; -% α 2\cos α {\cos α + \cos β} ; -% β \cos α+\cos β { 2 \cos β } +% {} a b ; +% a 2\cos a {\cos a + \cos b} ; +% b \cos a+\cos b { 2 \cos b } % \end{bNiceMatrix}$ % % \medskip @@ -1739,14 +1900,14 @@ version 2005/12/01 or later. % not in an eventual exterior row. % % For example, one may wish to define a new column type |?| in order to draw a -% (black) thick rule of width 1~pt. The following definition will do the +% (black) heavy rule of width 1~pt. The following definition will do the % job\footnote{The command |\vrule| is a TeX (and not LaTeX) command.}: % % \begin{Verbatim} % \newcolumntype{?}{!{\OnlyMainNiceMatrix{\vrule width 1 pt}}} % \end{Verbatim} % -% The thick vertical rule won't extend in the exterior rows: +% The heavy vertical rule won't extend in the exterior rows: % \medskip % \begin{scope} % \newcolumntype{?}{!{\OnlyMainNiceMatrix{\vrule width 1 pt}}} @@ -1808,10 +1969,10 @@ version 2005/12/01 or later. % & \Cdots & & & \\ % \end{pNiceMatrix}$ % -% \subsection{The names of the Tikz nodes created by nicematrix} +% \subsection{The names of the PGF nodes created by nicematrix} % % We have said that, when a name is given to an environment of \pkg{nicematrix}, -% it's possible to access the Tikz nodes through this name (cf. +% it's possible to access the PGF/Tikz nodes through this name (cf. % p.~\pageref{name}). % % That's the recommended way to access these nodes. However, we describe now the @@ -1823,8 +1984,8 @@ version 2005/12/01 or later. % command and not a counter). % % For the environment of number~$n$, the node in row~$i$ and column~$j$ has the -% name |nm-|$n$|-|$i$|-|$j$. The |medium| and |large| have the same name, suffixed by -% |-medium| and |-large|. +% name |nm-|$n$|-|$i$|-|$j$. The |medium| and |large| nodes have the same name, +% suffixed by |-medium| and |-large|. % % % \subsection{Diagonal lines} @@ -1840,7 +2001,7 @@ version 2005/12/01 or later. % \medskip % In the following examples, the first |\Ddots| instruction is written in color: % -% \medskip +% % \medskip % \begin{scope} % \begin{minipage}{9.5cm} % Example with parallelization (default): @@ -1904,7 +2065,7 @@ version 2005/12/01 or later. % An instruction like |\Ldots|, |\Cdots|, etc. tries to determine the first % non-empty cells on both sides. However, an 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 +% ampersands~|&|). Indeed, a cell which only contains |\hspace*{1cm}| may be % considered as empty. % % \interitem @@ -1923,12 +2084,8 @@ version 2005/12/01 or later. % the last cell (second row and second column) is empty. % % \medskip -% \item Each cell whose TeX ouput has a width less than 0.5~pt is empty. +% \item Each cell whose TeX ouput has a width equal to zero is empty. % -% \medskip -% \item A cell which contains a command |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots| -% or |\Iddots| is empty. We recall that these commands should be used alone in a -% cell. % % \medskip % \item A cell with a command |\Hspace| (or |\Hspace*|) is empty. This command @@ -1948,33 +2105,26 @@ version 2005/12/01 or later. % |{amsmath}|, we can read: {\itshape The extra space of |\arraycolsep| that % \pkg{array} adds on each side is a waste so we remove it [in |{matrix}|] % (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@{}}...\end{array}|.}. -% The environment |{matrix}| of \pkg{amsmath} and its variants (|{pmatrix}|, -% |{vmatrix}|, etc.) of \pkg{amsmath} prefer to delete these spaces with -% explicit instructions |\hskip -\arraycolsep|. The extension \pkg{nicematrix} -% does the same in all its environments, |{NiceArray}| included. However, if the -% user wants the environment |{NiceArray}| behaving by default like the -% environment |{array}| of \pkg{array} (for example, when adapting an existing -% document) it's possible to control this behaviour with the option -% |exterior-arraycolsep|, set by the command |\NiceMatrixOptions|. With this -% option, exterior spaces of length |\arraycolsep| will be inserted in the -% environments |{NiceArray}| (the other environments of \pkg{nicematrix} are not -% affected). +% harder task).}}. The environment |{matrix}| of +% \pkg{amsmath} and its variants (|{pmatrix}|, |{vmatrix}|, etc.) of +% \pkg{amsmath} prefer to delete these spaces with explicit instructions +% |\hskip -\arraycolsep|\footnote{And not by inserting |@{}| on both sides of the +% preamble of the array. As a consequence, the length of the |\hline| is not +% modified and may appear too long, in particular when using square brackets}. +% The extension \pkg{nicematrix} does the same in all its environments, +% |{NiceArray}| included. However, if the user wants the environment +% |{NiceArray}| behaving by default like the environment |{array}| of +% \pkg{array} (for example, when adapting an existing document) it's possible to +% control this behaviour with the option |exterior-arraycolsep|, set by the +% command |\NiceMatrixOptions|. With this option, exterior spaces of length +% |\arraycolsep| will be inserted in the environments |{NiceArray}| (the other +% environments of \pkg{nicematrix} are not affected). % % % \subsection{The class option draft} % -% The package \pkg{nicematrix} is rather slow when drawing the dotted lines -% (generated by |\Cdots|, |\Ldots|, |\Ddots|, etc. but also by |\hdottedline| or -% the specifier |:|).\footnote{The main reason is that we want dotted lines with -% round dots (and not square dots) with the same space on both extremities of -% the lines. To achieve this goal, we have to construct our own system of dotted -% lines.} -% -% That's why, when the class option |draft| is used, the dotted lines are not -% drawn, for a faster compilation. +% When the class option |draft| is used, the dotted lines are not drawn, for a +% faster compilation. % % \subsection{A technical problem with the argument of % \textbackslash\textbackslash} @@ -2071,39 +2221,14 @@ version 2005/12/01 or later. % % \subsection{Dotted lines} % -% \medskip -% A tridiagonal matrix: -% -% \bigskip -% \begin{BVerbatim}[baseline=c] -% $\begin{pNiceMatrix}[nullify-dots] -% a & b & 0 & & \Cdots & 0 \\ -% b & a & b & \Ddots & & \Vdots \\ -% 0 & b & a & \Ddots & & \\ -% & \Ddots & \Ddots & \Ddots & & 0 \\ -% \Vdots & & & & & b \\ -% 0 & \Cdots & & 0 & b & a -% \end{pNiceMatrix}$ -% \end{BVerbatim} -% \hspace{1.5cm} -% $\begin{pNiceMatrix}[nullify-dots] -% a & b & 0 & & \Cdots & 0 \\ -% b & a & b & \Ddots & & \Vdots \\ -% 0 & b & a & \Ddots & & \\ -% & \Ddots & \Ddots & \Ddots & & 0 \\ -% \Vdots & & & & & b \\ -% 0 & \Cdots & & 0 & b & a -% \end{pNiceMatrix}$ -% -% \vspace{2cm} % % A permutation matrix (as an example, we have raised the value of -% |dotted-lines-margin|). +% |xdots/shorten|). % % \label{permutation} % \bigskip % \begin{BVerbatim}[baseline=c] -% $\begin{pNiceMatrix}[~emphase#dotted-lines-margin=0.6em@] +% $\begin{pNiceMatrix}[~emphase#xdots/shorten=0.6em@] % 0 & 1 & 0 & & \Cdots & 0 \\ % \Vdots & & & \Ddots & & \Vdots \\ % & & & \Ddots & & \\ @@ -2113,7 +2238,7 @@ version 2005/12/01 or later. % \end{pNiceMatrix}$ % \end{BVerbatim} % \hspace{2.5cm} -% $\begin{pNiceMatrix}[dotted-lines-margin=0.6em] +% $\begin{pNiceMatrix}[xdots/shorten=0.6em] % 0 & 1 & 0 & & \Cdots & 0 \\ % \Vdots & & & \Ddots & & \Vdots \\ % & & & \Ddots & & \\ @@ -2124,11 +2249,12 @@ version 2005/12/01 or later. % % \vspace{2cm} % -% An example with |\Iddots|: \par\nobreak +% An example with |\Iddots|. We have raised even more the value of +% |xdots/shorten|.\par\nobreak % % \bigskip % \begin{BVerbatim}[baseline=c] -% $\begin{pNiceMatrix} +% $\begin{pNiceMatrix}[~emphase#xdots/shorten=0.9em@] % 1 & \Cdots & & 1 \\ % \Vdots & & & 0 \\ % & ~emphase#\Iddots@ & ~emphase#\Iddots@ & \Vdots \\ @@ -2136,7 +2262,7 @@ version 2005/12/01 or later. % \end{pNiceMatrix}$ % \end{BVerbatim} % \hspace{4cm} -% $\begin{pNiceMatrix} +% $\begin{pNiceMatrix}[xdots/shorten=0.9em] % 1 & \Cdots & & 1 \\ % \Vdots & & & 0 \\ % & \Iddots & \Iddots & \Vdots \\ @@ -2339,7 +2465,16 @@ version 2005/12/01 or later. % % \subsection{How to highlight cells of the matrix} % +% % \label{highlight} +% The following examples require Tikz (by default, \pkg{nicematrix} only loads +% \textsc{pgf}) and the Tikz library |fit|. The following lines in the preamble +% of your document may do the job: +% \begin{verbatim} +% \usepackage{tikz} +% \usetikzlibrary{fit} +% \end{verbatim} +% % \medskip % In order to highlight a cell of a matrix, it's possible to ``draw'' one of the % correspondant nodes (the ``normal node'', the ``medium node'' or the ``large @@ -2347,8 +2482,10 @@ version 2005/12/01 or later. % 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|. +% We redraw the nodes with other nodes by using the Tikz library |fit|. Since we +% want to redraw the nodes exactly, we have to set |inner sep = 0 pt| (if we +% don't do that, the new nodes will be larger that the nodes created by +% \pkg{nicematrix}). % % \begin{Verbatim} % $\begin{pNiceArray}{>{\strut}CCCC}% @@ -2356,7 +2493,7 @@ version 2005/12/01 or later. % code-after = {\begin{tikzpicture} % [~emphase#name suffix = -large@, % every node/.style = {draw, -% ~emphase#inner sep = -\pgflinewidth/2@}] +% ~emphase#inner sep = 0 pt@}] % \node [fit = (1-1)] {} ; % \node [fit = (2-2)] {} ; % \node [fit = (3-3)] {} ; @@ -2374,7 +2511,7 @@ version 2005/12/01 or later. % create-large-nodes,margin,extra-margin = 2pt, % code-after = {\begin{tikzpicture}[name suffix = -large, % every node/.style = {draw, -% inner sep = -\pgflinewidth/2}] +% inner sep = 0 pt}] % \node [fit = (1-1)] {} ; % \node [fit = (2-2)] {} ; % \node [fit = (3-3)] {} ; @@ -2387,12 +2524,12 @@ version 2005/12/01 or later. % \end{pNiceArray}\] % % We should remark that the rules we have drawn are drawn \emph{after} the -% construction of the array and, hence, they don't spread the cells of the -% array. We recall that, on the other side, the command |\hline| and the -% specifier ``"|"'' spread the cells (when the package \pkg{array} is loaded -% but, when the package \pkg{nicematrix} is loaded, \pkg{array} is always -% loaded).\footnote{On the other side, the command |\cline| doesn't spread the -% rows of the array.} +% construction of the array and thus, they don't spread the cells of the +% array. We recall that, on the other side, the command |\hline|, the specifier +% ``"|"'' and the options |hlines| and |vlines| spread the cells (when the +% package \pkg{array} is loaded but, when the package \pkg{nicematrix} is +% loaded, \pkg{array} is always loaded).\footnote{On the other side, the command +% |\cline| doesn't spread the rows of the array.} % % % \vspace{1cm} @@ -2494,7 +2631,7 @@ version 2005/12/01 or later. % \end{pNiceMatrix}$ % % \vspace{1cm} -% Considerer now the following matrix which we have named |example|. +% Consider now the following matrix which we have named |example|. % % \medskip % \begin{Verbatim} @@ -2663,12 +2800,12 @@ version 2005/12/01 or later. % |first-row|. % \begin{Verbatim} % \begin{bNiceArray}{C>{\strut}CCCC}[name=B,first-row] -% & & C_j \\ -% b_{11} & \Cdots & b_{1j} & \Cdots & b_{1n} \\ -% \Vdots & & \Vdots & & \Vdots \\ -% & & b_{kj} \\ -% & & \Vdots \\ -% b_{n1} & \Cdots & b_{nj} & \Cdots & b_{nn} +% & & C_j \\ +% b_{11} & \Cdots & b_{1j} & \Cdots & b_{1n} \\ +% \Vdots & & \Vdots & & \Vdots \\ +% & & b_{kj} \\ +% & & \Vdots \\ +% b_{n1} & \Cdots & b_{nj} & \Cdots & b_{nn} % \end{bNiceArray} \\ \\ % \end{Verbatim} % @@ -2676,11 +2813,11 @@ version 2005/12/01 or later. % key |first-col|. % \begin{Verbatim} % \begin{bNiceArray}{CC>{\strut}CCC}[name=A,first-col] -% & a_{11} & \Cdots & & & a_{1n} \\ -% & \Vdots & & & & \Vdots \\ +% & a_{11} & \Cdots & & & a_{1n} \\ +% & \Vdots & & & & \Vdots \\ % L_i & a_{i1} & \Cdots & a_{ik} & \Cdots & a_{in} \\ -% & \Vdots & & & & \Vdots \\ -% & a_{n1} & \Cdots & & & a_{nn} \\ +% & \Vdots & & & & \Vdots \\ +% & a_{n1} & \Cdots & & & a_{nn} \\ % \end{bNiceArray} % & % \end{Verbatim} @@ -2688,9 +2825,9 @@ version 2005/12/01 or later. % In the matrix product, the two dotted lines have an open extremity. % \begin{Verbatim} % \begin{bNiceArray}{CC>{\strut}CCC} -% & & & & \\ -% & & \Vdots \\ -% \Cdots & & c_{ij} \\ +% & & & & \\ +% & & \Vdots \\ +% \Cdots & & c_{ij} \\ % \\ % \\ % \end{bNiceArray} @@ -2778,27 +2915,25 @@ version 2005/12/01 or later. % See: |http://mirrors.ctan.org/macros/latex/contrib/l3kernel/l3prefixes.pdf| % %<@@=nicematrix> -% -% \bigskip -% First, \pkg{tikz} and the Tikz library |fit| are loaded before the -% |\ProvidesExplPackage|. They are loaded this way because |\usetikzlibrary| in -% |expl3| code fails.\footnote{cf. -% |tex.stackexchange.com/questions/57424/using-of-usetikzlibrary-in-an-expl3-package-fails|} % +% \bigskip +% First, we load \pkg{pgfcore} and the module \pkg{shapes}. We do so because +% it's not possible to use |\usepgfmodule| in |\ExplSyntaxOn|. % \begin{macrocode} -\RequirePackage{tikz} -\usetikzlibrary{fit} +\RequirePackage{pgfcore} +\usepgfmodule{shapes} \RequirePackage{expl3}[2020/02/08] % \end{macrocode} +% % -% We give the traditionnal declaration of a package written with |expl3|: +% We give the traditional declaration of a package written with |expl3|: % \begin{macrocode} \RequirePackage{l3keys2e} \ProvidesExplPackage {nicematrix} {\myfiledate} {\myfileversion} - {Mathematical matrices with TikZ} + {Mathematical matrices with PGF/TikZ} % \end{macrocode} % % @@ -2836,7 +2971,7 @@ version 2005/12/01 or later. % this package for technical reasons. % % \bigskip -% We load \pkg{array} and \pkg{amsmath}. +% We load some packages. % \begin{macrocode} \RequirePackage { array } \RequirePackage { amsmath } @@ -2863,6 +2998,35 @@ version 2005/12/01 or later. % \bigskip % \subsection*{Technical definitions} % +% \begin{macrocode} +\bool_new:N \c_@@_tikz_loaded_bool +\AtBeginDocument + { + \@ifpackageloaded { tikz } + { +% \end{macrocode} +% In some constructions, we will have to use a |{pgfpicture}| which \emph{must} +% be replaced by a |{tikzpicture}| if Tikz is loaded. However, this switch +% between |{pgfpicture}| |{tikzpicture}| can't be done dynamically with a +% conditional because, when the |external| Tikz library, the pair +% |\tikzpicture|-|\endtikpicture| (or |\begin{tikzpicture}-\end{tikzpicture}| +% must be statically ``visible'' (even when extenalization is not activated). +% +% That's why we create these token lists |\c_@@_pgfortikzpicture_tl| and +% |\c_@@_endpgfortikzpicture_tl| which will be used to construct in a +% |\AtBeginDocument| the correct version of some commands. +% \begin{macrocode} + \bool_set_true:N \c_@@_tikz_loaded_bool + \tl_const:Nn \c_@@_pgfortikzpicture_tl { \exp_not:N \tikzpicture } + \tl_const:Nn \c_@@_endpgfortikzpicture_tl { \exp_not:N \endtikzpicture } + } + { + \tl_const:Nn \c_@@_pgfortikzpicture_tl { \exp_not:N \pgfpicture } + \tl_const:Nn \c_@@_endpgfortikzpicture_tl { \exp_not:N \endpgfpicture } + } + } +% \end{macrocode} +% % We test whether the current class is \cls{revtex4-1} or \cls{revtex4-2} % because these classes redefines |\array| (of \pkg{array}) in a way % incompatible with our programmation. @@ -2885,8 +3049,7 @@ version 2005/12/01 or later. % \end{macrocode} % % \begin{macrocode} -\bool_if:NT \c_@@_draft_bool - { \msg_warning:nn { nicematrix } { Draft~mode } } +\bool_if:NT \c_@@_draft_bool { \msg_warning:nn { nicematrix } { Draft~mode } } % \end{macrocode} % % @@ -2924,6 +3087,12 @@ version 2005/12/01 or later. \int_new:N \g_@@_env_int % \end{macrocode} % +% \begin{macrocode} +\cs_new:Npn \@@_env: { nm - \int_use:N \g_@@_env_int } +\cs_new_protected:Npn \@@_qpoint: #1 + { \pgfpointanchor { \@@_env: - #1 } { center } } +% \end{macrocode} +% % \bigskip % We also define a counter to count the environments |{NiceMatrixBlock}|. % \begin{macrocode} @@ -2978,29 +3147,6 @@ version 2005/12/01 or later. } % \end{macrocode} % -% \bigskip -% Consider the following code: -% \begin{Verbatim} -% $\begin{pNiceMatrix} -% a & b & c \\ -% d & e & \Vdots \\ -% f & \Cdots \\ -% g & h & i \\ -% \end{pNiceMatrix}$ -% \end{Verbatim} -% -% First, the dotted line created by the |\Vdots| will be drawn. The implicit -% cell in position 2-3 will be considered as ``dotted''. Then, we will have to -% draw the dotted line specified by the |\Cdots|; the final extremity of that -% line will be exactly in position 2-3 and, for that new second line, it should -% be considered as a \emph{closed} extremity (since it is dotted). However, we -% don't have the (normal) Tikz node of that node (since it's an implicit cell): -% we can't draw such a line. That's why that dotted line will be said -% \emph{impossible} and an error will be raised.\footnote{Of course, the user -% should solve the problem by adding the lacking ampersands.} -% \begin{macrocode} -\bool_new:N \l_@@_impossible_line_bool -% \end{macrocode} % % % \bigskip @@ -3019,13 +3165,9 @@ version 2005/12/01 or later. } % \end{macrocode} % -% \bigskip -% We have put a argument |w| (\emph{weird}) for the following function because -% its argument should be a specifier of \pkg{pgf} point between rounded -% brackets. % \begin{macrocode} -\cs_set_protected:Npn \@@_extract_coords:w - { \tikz@parse@node \pgfutil@firstofone } +\colorlet { nicematrix-last-col } { . } +\colorlet { nicematrix-last-row } { . } % \end{macrocode} % % \bigskip @@ -3038,26 +3180,29 @@ version 2005/12/01 or later. % \end{macrocode} % % \bigskip -% The length |\l_@@_dotted_lines_margin_dim| is the minimal distance between a +% The length |\l_@@_xdots_shorten_dim| is the minimal distance between a % node (in fact an anchor of that node) and a dotted line (we say ``minimal'' % because, by definition, a dotted line is not a continuous line and, therefore, % this distance may vary a little). % \begin{macrocode} -\dim_new:N \l_@@_dotted_lines_margin_dim -\dim_set:Nn \l_@@_dotted_lines_margin_dim { 0.3 em } +\dim_new:N \l_@@_xdots_shorten_dim +\dim_set:Nn \l_@@_xdots_shorten_dim { 0.3 em } % \end{macrocode} % % \bigskip -% The length |\l_@@_radius_dim| is the radius of the dots for the dotted lines. -% The default value is 0.53~pt but it will be changed if the option |small| is -% used (to 0.37~pt). +% The length |\l_@@_radius_dim| is the radius of the dots for the dotted lines +% (for |\hdottedline| and |\dottedline| and for all the other dotted lines when +% |line-style| is equal to |standard|, which is the initial value). The initial +% value is 0.53~pt but it will be changed if the option |small| is used (to +% 0.37~pt). % \begin{macrocode} \dim_new:N \l_@@_radius_dim \dim_set:Nn \l_@@_radius_dim { 0.53 pt } % \end{macrocode} % % \bigskip -% The name of the current environment or the current command (despite the name). +% The name of the current environment or the current command (despite the name +% which contains \textsl{env}). % \begin{macrocode} \str_new:N \g_@@_name_env_str % \end{macrocode} @@ -3071,8 +3216,9 @@ version 2005/12/01 or later. % \end{macrocode} % % The following control sequence will be able to reconstruct the full name of -% the current command or environment (despite the name). This command must -% \emph{not} be protected since it's used in error messages. +% the current command or environment (despite the name which contains +% \textsl{env}). This command must \emph{not} be protected since it's used in +% error messages. % \begin{macrocode} \cs_new:Npn \@@_full_name_env: { @@ -3084,6 +3230,7 @@ version 2005/12/01 or later. % % \bigskip % \begin{macrocode} +\tl_new:N \g_@@_internal_code_after_tl \tl_new:N \g_@@_code_after_tl % \end{macrocode} % @@ -3104,7 +3251,40 @@ version 2005/12/01 or later. \bool_new:N \g_@@_row_of_col_done_bool % \end{macrocode} % +% \begin{macrocode} +\tl_new:N \l_@@_initial_suffix_tl +\tl_new:N \l_@@_initial_anchor_tl +\tl_new:N \l_@@_final_suffix_tl +\tl_new:N \l_@@_final_anchor_tl +% \end{macrocode} +% +% \begin{macrocode} +\dim_new:N \l_@@_x_initial_dim +\dim_new:N \l_@@_y_initial_dim +\dim_new:N \l_@@_x_final_dim +\dim_new:N \l_@@_y_final_dim +% \end{macrocode} +% +% \begin{macrocode} +\dim_new:N \l_tmpc_dim +\dim_new:N \l_tmpd_dim +% \end{macrocode} % +% \begin{macrocode} +\bool_new:N \g_@@_empty_cell_bool +% \end{macrocode} +% +% \medskip +% The token list |\l_@@_xdots_line_style_tl| corresponds to the option |tikz| of the +% commands |\Cdots|, |\Ldots|, etc. and of the options |line-style| for the +% environments and |\NiceMatrixOptions|. The constant |\c_@@_standard_tl| will +% be used in some tests. +% \begin{macrocode} +\tl_new:N \l_@@_xdots_line_style_tl +\tl_const:Nn \c_@@_standard_tl { standard } +\tl_set_eq:NN \l_@@_xdots_line_style_tl \c_@@_standard_tl +% \end{macrocode} +% % \bigskip % \textbf{Variables for the exterior rows and columns}\par\nobreak % @@ -3250,14 +3430,6 @@ version 2005/12/01 or later. % \begin{macrocode} \cs_set_protected:Npn \@@_adapt_S_column: { -% \end{macrocode} -% In the preamble of the LaTeX document, the boolean |\c_@@_siunitx_loaded_bool| -% won't be known. That's why we test the existence of -% |\c_@@_siunitx_loaded_bool| and not its value.\footnote{Indeed, -% \pkg{nicematrix} may be used in the preamble of the LaTeX document. For -% example, you can compose a matrix in a box before the loading of -% \pkg{arydshln} (not totally compatible with \pkg{nicematrix}).} -% \begin{macrocode} \bool_if:NT \c_@@_siunitx_loaded_bool { \group_begin: @@ -3313,6 +3485,12 @@ version 2005/12/01 or later. } % \end{macrocode} % +% \bigskip +% The following command is only for efficiency. It must \emph{not} be protected +% because it will be used (for instance) in names of \textsc{pgf} nodes. +% \begin{macrocode} +\cs_new:Npn \@@_succ:N #1 { \the \numexpr #1 + 1 \relax } +% \end{macrocode} % % \bigskip % \subsection*{The options} @@ -3392,14 +3570,14 @@ version 2005/12/01 or later. % ``medium nodes'' are created in the array. Idem for the ``large nodes''. % \begin{macrocode} \bool_new:N \l_@@_medium_nodes_bool -\bool_new:N \g_@@_medium_nodes_bool \bool_new:N \l_@@_large_nodes_bool -\bool_new:N \g_@@_large_nodes_bool % \end{macrocode} % % \bigskip -% The dimension |\l_@@_left_margin_dim| correspondto the option |left-margin| -% (idem for the right margin). +% The dimension |\l_@@_left_margin_dim| correspond to the option |left-margin|. +% Idem for the right margin. These parameters are involved in the creation of +% the ``medium nodes'' but also in the placement of the delimiters and the +% drawing of the horizontal dotted lines (|\hdottedline|). % \begin{macrocode} \dim_new:N \l_@@_left_margin_dim \dim_new:N \l_@@_right_margin_dim @@ -3432,6 +3610,14 @@ version 2005/12/01 or later. % \end{macrocode} % % \medskip +% The following parameter is for the color the dotted lines drawn by |\Cdots|, +% |\Ldots|, |\Vdots|, |\Ddots|, |\Iddots| and |\Hdotsfor| but \emph{not} the +% dotted lines drawn by |\hdottedline| and ``|:|''. +% \begin{macrocode} +\tl_new:N \l_@@_xdots_color_tl +% \end{macrocode} +% +% \medskip % Sometimes, we want to have several arrays vertically juxtaposed in order to % have an alignment of the columns of these arrays. To acheive this goal, one % may wish to use the same width for all the columns (for example with the @@ -3450,11 +3636,35 @@ version 2005/12/01 or later. % First, we define a set of keys ``|NiceMatrix / Global|'' which will be used % (with the mechanism of |.inherit:n|) by other sets of keys. % \begin{macrocode} +\keys_define:nn { NiceMatrix / xdots } + { + line-style .code:n = + { + \bool_lazy_or:nnTF +% \end{macrocode} +% We can't use |\c_@@_tikz_loaded_bool| to test whether \pkg{tikz} is loaded +% because |\NiceMatrixOptions| may be used in the preamble of the document. +% \begin{macrocode} + { \cs_if_exist_p:N \tikzpicture } + { \str_if_eq_p:nn { #1 } { standard } } + { \tl_set:Nn \l_@@_xdots_line_style_tl { #1 } } + { \@@_error:n { bad~option~for~line-style } } + } , + line-style .value_required:n = true , + color .tl_set:N = \l_@@_xdots_color_tl , + color .value_required:n = true , + shorten .dim_set:N = \l_@@_xdots_shorten_dim , + shorten .value_required:n = true , + unknown .code:n = \@@_error:n { Unknown~option~for~xdots } + } +% \end{macrocode} +% +% +% \begin{macrocode} \keys_define:nn { NiceMatrix / Global } { + xdots .code:n = \keys_set:nn { NiceMatrix / xdots } { #1 } , max-delimiter-width .bool_set:N = \l_@@_max_delimiter_width_bool , - dotted-lines-margin .dim_set:N = \l_@@_dotted_lines_margin_dim , - dotted-lines-margin .value_required:n = true , light-syntax .bool_set:N = \l_@@_light_syntax_bool , light-syntax .default:n = true , end-of-row .tl_set:N = \l_@@_end_of_row_tl , @@ -3501,7 +3711,8 @@ version 2005/12/01 or later. extra-left-margin .dim_set:N = \l_@@_extra_left_margin_dim , extra-right-margin .dim_set:N = \l_@@_extra_right_margin_dim , extra-margin .meta:n = - { extra-left-margin = #1 , extra-right-margin = #1 } + { extra-left-margin = #1 , extra-right-margin = #1 } , + extra-margin .value_required:n = true } % \end{macrocode} % @@ -3517,6 +3728,11 @@ version 2005/12/01 or later. { \dim_set:Nn \l_@@_columns_width_dim { #1 } } , columns-width .value_required:n = true , name .code:n = +% \end{macrocode} +% We test whether we are in the measuring phase of an environment of +% \pkg{amsmath} (always loaded by \pkg{nicematrix}) because we want to avoid a +% fallaicous message of duplicate name in this case. +% \begin{macrocode} \legacy_if:nF { measuring@ } { \str_set:Nn \l_tmpa_str { #1 } @@ -3543,24 +3759,28 @@ version 2005/12/01 or later. \keys_define:nn { NiceMatrix } { NiceMatrixOptions .inherit:n = - { + { NiceMatrix / Global , } , + NiceMatrixOptions / xdots .inherit:n = NiceMatrix / xdots , NiceMatrix .inherit:n = { NiceMatrix / Global , - NiceMatrix / Env + NiceMatrix / Env , } , + NiceMatrix / xdots .inherit:n = NiceMatrix / xdots , NiceArray .inherit:n = { NiceMatrix / Global , NiceMatrix / Env , } , + NiceArray / xdots .inherit:n = NiceMatrix / xdots , pNiceArray .inherit:n = { NiceMatrix / Global , NiceMatrix / Env , - } + } , + pNiceArray / xdots .inherit:n = NiceMatrix / xdots } % \end{macrocode} % @@ -3629,10 +3849,6 @@ version 2005/12/01 or later. { \@@_error:n { Bad~value~for~letter~for~dotted~lines } } } , letter-for-dotted-lines .value_required:n = true , -% \end{macrocode} -% -% \bigskip -% \begin{macrocode} unknown .code:n = \@@_error:n { Unknown~key~for~NiceMatrixOptions } } % \end{macrocode} @@ -3662,6 +3878,10 @@ version 2005/12/01 or later. last-col .code:n = \tl_if_empty:nTF {#1} { \@@_error:n { last-col~empty~for~NiceMatrix } } { \int_set:Nn \l_@@_last_col_int { #1 } } , + l .code:n = \tl_set:Nn \l_@@_type_of_col_tl L , + r .code:n = \tl_set:Nn \l_@@_type_of_col_tl R , + L .code:n = \tl_set:Nn \l_@@_type_of_col_tl L , + R .code:n = \tl_set:Nn \l_@@_type_of_col_tl R , unknown .code:n = \@@_error:n { Unknown~option~for~NiceMatrix } } % \end{macrocode} @@ -3737,12 +3957,8 @@ version 2005/12/01 or later. % in the |\halign| that we don't want to take into account. % \begin{macrocode} \int_compare:nNnT \c@jCol = 1 - { - \int_compare:nNnT \l_@@_first_col_int = 1 - \@@_begin_of_row: - } - \int_gset:Nn \g_@@_col_total_int - { \int_max:nn \g_@@_col_total_int \c@jCol } + { \int_compare:nNnT \l_@@_first_col_int = 1 \@@_begin_of_row: } + \int_gset:Nn \g_@@_col_total_int { \int_max:nn \g_@@_col_total_int \c@jCol } % \end{macrocode} % The content of the cell is composed in the box |\l_@@_cell_box| because we want % to compute some dimensions of the box. The |\hbox_set_end:| corresponding to @@ -3762,10 +3978,19 @@ version 2005/12/01 or later. % corners of the matrix. % \begin{macrocode} \int_compare:nNnTF \c@iRow = 0 - { \int_compare:nNnT \c@jCol > 0 \l_@@_code_for_first_row_tl } + { + \int_compare:nNnT \c@jCol > 0 + { + \l_@@_code_for_first_row_tl + \xglobal \colorlet { nicematrix-first-row } { . } + } + } { \int_compare:nNnT \c@iRow = \l_@@_last_row_int - \l_@@_code_for_last_row_tl + { + \l_@@_code_for_last_row_tl + \xglobal \colorlet { nicematrix-last-row } { . } + } } } % \end{macrocode} @@ -3781,8 +4006,18 @@ version 2005/12/01 or later. \dim_gset_eq:NN \g_@@_dp_ante_last_row_dim \g_@@_dp_last_row_dim \dim_gset:Nn \g_@@_dp_last_row_dim { \box_dp:N \@arstrutbox } \dim_gset:Nn \g_@@_ht_last_row_dim { \box_ht:N \@arstrutbox } - \tikz [ remember~picture , baseline ] \coordinate - ( nm - \int_use:N \g_@@_env_int - row - \int_use:N \c@iRow - base ) ; + \pgfpicture + \pgfrememberpicturepositiononpagetrue + \pgfcoordinate + { \@@_env: - row - \int_use:N \c@iRow - base } + \pgfpointorigin + \str_if_empty:NF \l_@@_name_str + { + \pgfnodealias + { \@@_env: - row - \int_use:N \c@iRow - base } + { \l_@@_name_str - row - \int_use:N \c@iRow - base } + } + \endpgfpicture } % \end{macrocode} % @@ -3834,72 +4069,80 @@ version 2005/12/01 or later. \@@_update_for_first_and_last_row: % \end{macrocode} % -% Now, we can create the Tikz node of the cell. +% \medskip +% If the cell is empty, or may be considered as if, we must not create the +% \textsc{pgf} node, for two reasons: +% \begin{itemize} +% \item it's a waste of time since such a node would be rather pointless; +% \item we test the existence of these nodes in order to determine whether a +% cell is empty when we search the extremities of a dotted line. +% \end{itemize} +% However, it's very difficult to determine whether a cell is empty. As of now, +% we use the following technic: +% \begin{itemize} +% \item if the width of the box |\l_@@_cell_box| (created with the content of +% the cell) is equal to zero, we consider the cell as empty (however, +% this is not perfect since the user may have use a |\rlap|, a |\llap| or a +% |\mathclap| of \pkg{mathtools}. +% \item the cells with a command |\Ldots| or |\Cdots|, |\Vdots|, etc., +% should also be considered as empty; if |nullify-dots| is in force, there would +% be nothing to do (in this case the previous commands only write an instruction +% in a kind of |code-after|); however, if |nullify-dots| is not in force, a +% phantom of |\ldots|, |\cdots|, |\vdots| is inserted and its width is not equal +% to zero; that's why these commands raise a boolean |\g_@@_empty_cell_bool| and +% we begin by testing this boolean. +% \end{itemize} % \begin{macrocode} - \tikz - [ - remember~picture , - inner~sep = \c_zero_dim , - minimum~width = \c_zero_dim , - baseline - ] - \node - [ - anchor = base , - name = nm - \int_use:N \g_@@_env_int - - \int_use:N \c@iRow - - \int_use:N \c@jCol , - alias = - \str_if_empty:NF \l_@@_name_str - { - \l_@@_name_str - - \int_use:N \c@iRow - - \int_use:N \c@jCol - } - ] - { \box_use_drop:N \l_@@_cell_box } ; + \bool_if:NTF \g_@@_empty_cell_bool + { + \box_use_drop:N \l_@@_cell_box + \bool_gset_false:N \g_@@_empty_cell_bool + } + { + \dim_compare:nNnTF { \box_wd:N \l_@@_cell_box } > \c_zero_dim + \@@_node_for_the_cell: + { \box_use_drop:N \l_@@_cell_box } + } + \bool_gset_false:N \g_@@_empty_cell_bool } % \end{macrocode} -% -% -% \begin{macrocode} -\cs_generate_variant:Nn \dim_set:Nn { N x } -% \end{macrocode} % -% \bigskip -% In the environment |{NiceArrayWithDelims}|, we will have to redefine the -% column types |w| and |W|. The redefinition of these two column types are very -% close and that's why we use a macro |\@@_renewcolumntype:nn|. The first -% argument is the type of the column (|w| or |W|) and the second argument is a -% code inserted at a special place and which is the only difference between the -% two definitions. +% \medskip +% The following command creates the \textsc{pgf} name of the node with, of +% course, |\l_@@_cell_box| as the content. % \begin{macrocode} -\cs_new_protected:Npn \@@_renewcolumntype:nn #1 #2 +\cs_new_protected:Npn \@@_node_for_the_cell: { - \newcolumntype #1 [ 2 ] + \pgfpicture + \pgfsetbaseline \c_zero_dim + \pgfrememberpicturepositiononpagetrue + \pgfset { - > { - \hbox_set:Nw \l_@@_cell_box - \@@_Cell: - } - c - < { - \@@_end_Cell: - \hbox_set_end: - #2 - \makebox [ ##2 ] [ ##1 ] { \box_use_drop:N \l_@@_cell_box } - } + inner~sep = \c_zero_dim , + minimum~width = \c_zero_dim + } + \pgfnode + { rectangle } + { base } + { \box_use_drop:N \l_@@_cell_box } + { \@@_env: - \int_use:N \c@iRow - \int_use:N \c@jCol } + { } + \str_if_empty:NF \l_@@_name_str + { + \pgfnodealias + { \l_@@_name_str - \int_use:N \c@iRow - \int_use:N \c@jCol } + { \@@_env: - \int_use:N \c@iRow - \int_use:N \c@jCol } } + \endpgfpicture } % \end{macrocode} % -% % \interitem -% The argument of the following command |\@@_instruction_of_type:n| defined -% below is the type of the instruction (|Cdots|, |Vdots|, |Ddots|, etc.). This -% command writes in the corresponding |\g_@@_|\textsl{type}|_lines_tl| the -% instruction which will actually draw the line after the construction of the -% matrix. +% The first argument of the following command |\@@_instruction_of_type:nn| +% defined below is the type of the instruction (|Cdots|, |Vdots|, |Ddots|, +% etc.). The second argument is the list of options. This command writes in the +% corresponding |\g_@@_|\textsl{type}|_lines_tl| the instruction which will +% actually draw the line after the construction of the matrix. % % \medskip % For example, for the following matrix, @@ -3909,13 +4152,13 @@ version 2005/12/01 or later. % \begin{pNiceMatrix} % 1 & 2 & 3 & 4 \\ % 5 & \Cdots & & 6 \\ -% 7 & \Cdots \\ +% 7 & \Cdots[color=red] \\ % \end{pNiceMatrix} % \end{BVerbatim} % $\begin{pNiceMatrix} % 1 & 2 & 3 & 4 \\ % 5 & \Cdots & & 6 \\ -% 7 & \Cdots \\ +% 7 & \Cdots[color=red] \\ % \end{pNiceMatrix}$ % % \smallskip @@ -3924,19 +4167,20 @@ version 2005/12/01 or later. % \smallskip % \begin{scope} % \color{gray} -% \verb|\@@_draw_Cdots:nn {2}{2}| +% \verb|\@@_draw_Cdots:nnn {2}{2}{}| % -% \verb|\@@_draw_Cdots:nn {3}{2}| +% \verb|\@@_draw_Cdots:nnn {3}{2}{color=red}| % \end{scope} % -% +% +% \bigskip % We begin with a test of the flag |\c_@@_draft_bool| because, if the key % |draft| is used, the dotted lines are not drawn. % \begin{macrocode} \bool_if:NTF \c_@@_draft_bool - { \cs_set_protected:Npn \@@_instruction_of_type:n #1 { } } + { \cs_set_protected:Npn \@@_instruction_of_type:nn #1 #2 { } } { - \cs_new_protected:Npn \@@_instruction_of_type:n #1 + \cs_new_protected:Npn \@@_instruction_of_type:nn #1 #2 { % \end{macrocode} % It's important to use a |\tl_gput_right:cx| and not a |\tl_gput_left:cx| @@ -3946,9 +4190,13 @@ version 2005/12/01 or later. \tl_gput_right:cx { g_@@_ #1 _ lines _ tl } { - \use:c { @@ _ draw _ #1 : nn } + \use:c { @@ _ draw _ #1 : nnn } { \int_use:N \c@iRow } { \int_use:N \c@jCol } +% \end{macrocode} +% Maybe we should prevent the expansion of the list of key-value. +% \begin{macrocode} + { #2 } } } } @@ -4001,13 +4249,21 @@ version 2005/12/01 or later. { \int_gzero:N \c@jCol % \end{macrocode} -% The |\hbox:n| is mandatory. +% The |\hbox:n| (or |\hbox|) is mandatory. % \begin{macrocode} - \hbox:n + \hbox { - \tikz [ remember~picture ] - \coordinate - ( nm - \int_use:N \g_@@_env_int - row - \int_eval:n { \c@iRow + 1 } ) ; + \pgfpicture + \pgfrememberpicturepositiononpagetrue + \pgfcoordinate { \@@_env: - row - \@@_succ:N \c@iRow } + \pgfpointorigin + \str_if_empty:NF \l_@@_name_str + { + \pgfnodealias + { \@@_env: - row - \int_use:N \c@iRow - row } + { \l_@@_name_str - row - \int_use:N \c@iRow - row } + } + \endpgfpicture } % \end{macrocode} % We add the potential horizontal lines specified by the option |hlines|. @@ -4066,15 +4322,6 @@ version 2005/12/01 or later. % \end{macrocode} % % -% \medskip -% We switch to a global version of the |\l_@@_medium_nodes_bool| and -% |\l_@@_large_nodes_bool| because these booleans may be raised in cells of the -% array (for exemple in commands |\Block|). -% \begin{macrocode} - \bool_gset_eq:NN \g_@@_medium_nodes_bool \l_@@_medium_nodes_bool - \bool_gset_eq:NN \g_@@_large_nodes_bool \l_@@_large_nodes_bool -% \end{macrocode} -% % \bigskip % The environment |{array}| uses internally the command |\ialign|. We change the % definition of |\ialign| for several reasons. In particular, |\ialign| sets @@ -4136,8 +4383,16 @@ version 2005/12/01 or later. \newcolumntype C { > \@@_Cell: c < \@@_end_Cell: } \newcolumntype R { > \@@_Cell: r < \@@_end_Cell: } % \end{macrocode} -% -% \begin{macrocode} +% We keep in memory the old versions or |\ldots|, |\cdots|, etc. only because we +% use them inside |\phantom| commands in order that the new commands |\Ldots|, +% |\Cdots|, etc. give the same spacing (except when the option |nullify-dots| is +% used). +% \begin{macrocode} + \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 \firsthline \hline \cs_set_eq:NN \lasthline \hline \cs_set_eq:NN \Ldots \@@_Ldots @@ -4210,8 +4465,40 @@ version 2005/12/01 or later. % \begin{macrocode} \cs_set_eq:NN \NC@find@w \relax \cs_set_eq:NN \NC@find@W \relax - \@@_renewcolumntype:nn w { } - \@@_renewcolumntype:nn W { \cs_set_eq:NN \hss \hfil } + \newcolumntype w [ 2 ] + { + > { + \hbox_set:Nw \l_@@_cell_box + \@@_Cell: + } + c + < { + \@@_end_Cell: + \hbox_set_end: +% \end{macrocode} +% The |\str_lowercase:n| is only for giving the user the ability to write +% |wC{1cm}| instead of |wc{1cm}| for homogeneity with the letters |L|, |C| and +% |R| used elsewhere in the preamble instead of |l|, |c| and |r|. +% \begin{macrocode} + \makebox [ ##2 ] [ \str_lowercase:n { ##1 } ] + { \box_use_drop:N \l_@@_cell_box } + } + } + \newcolumntype W [ 2 ] + { + > { + \hbox_set:Nw \l_@@_cell_box + \@@_Cell: + } + c + < { + \@@_end_Cell: + \hbox_set_end: + \cs_set_eq:NN \hss \hfil + \makebox [ ##2 ] [ \str_lowercase:n { ##1 } ] + { \box_use_drop:N \l_@@_cell_box } + } + } % \end{macrocode} % % \bigskip @@ -4241,7 +4528,7 @@ version 2005/12/01 or later. \int_compare:nNnF \c@iRow = 0 { \int_compare:nNnF \c@iRow = \l_@@_last_row_int - { \skip_horizontal:n { 2 \l_@@_radius_dim } } + { \skip_horizontal:N 2\l_@@_radius_dim } } % \end{macrocode} % @@ -4268,10 +4555,10 @@ version 2005/12/01 or later. \int_compare:nNnT \c@jCol > \g_@@_last_vdotted_col_int { \int_gset_eq:NN \g_@@_last_vdotted_col_int \c@jCol - \tl_gput_right:Nx \g_@@_code_after_tl + \tl_gput_right:Nx \g_@@_internal_code_after_tl % \end{macrocode} % The command |\@@_vdottedline:n| is protected, and, therefore, won't be -% expanded before writing on |\g_@@_code_after_tl|. +% expanded before writing on |\g_@@_internal_code_after_tl|. % \begin{macrocode} { \@@_vdottedline:n { \int_use:N \c@jCol } } } @@ -4303,6 +4590,8 @@ version 2005/12/01 or later. % \begin{macrocode} \NewDocumentEnvironment { NiceArrayWithDelims } { m m O { } m ! O { } } { + \tl_set:Nn \l_@@_left_delim_tl { #1 } + \tl_set:Nn \l_@@_right_delim_tl { #2 } \bool_gset_false:N \g_@@_row_of_col_done_bool \str_if_empty:NT \g_@@_name_env_str { \str_gset:Nn \g_@@_name_env_str { NiceArrayWithDelims } } @@ -4312,10 +4601,8 @@ version 2005/12/01 or later. \bool_set_true:N \l_@@_in_env_bool % \end{macrocode} % -% We deactivate Tikz externalization. -% -% Since we use Tikz pictures with the options |overlay| and |remember picture|, -% there would be errors). +% We deactivate Tikz externalization because we will use \textsc{pgf} pictures with the +% options |overlay| and |remember picture| (or equivalent forms). % \begin{macrocode} \cs_if_exist:NT \tikz@library@external@loaded { @@ -4333,6 +4620,7 @@ version 2005/12/01 or later. { \dim_gzero_new:N \g_@@_max_cell_width_dim } % \end{macrocode} % +% % We do a redefinition of |\@arrayrule| because we want that the vertical rules % drawn by "|" in the preamble of the array don't extend in the potential % exterior rows. @@ -4343,7 +4631,7 @@ version 2005/12/01 or later. % % The set of keys is not exactly the same for |{NiceArray}| and for the variants % of |{NiceArray}| (|{pNiceArray}|, |{bNiceArray}|, etc.) because, for -% |{NiceArray}|, we have the options |t|, |c| and |b|. +% |{NiceArray}|, we have the options |t|, |c|, |b| and |baseline|. % \begin{macrocode} \bool_if:NTF \l_@@_NiceArray_bool { \keys_set:nn { NiceMatrix / NiceArray } } @@ -4404,27 +4692,18 @@ version 2005/12/01 or later. \dim_zero_new:N \l_@@_left_delim_dim \dim_zero_new:N \l_@@_right_delim_dim \bool_if:NTF \l_@@_NiceArray_bool - { + { \dim_gset:Nn \l_@@_left_delim_dim { 2 \arraycolsep } \dim_gset:Nn \l_@@_right_delim_dim { 2 \arraycolsep } } { - \hbox_set:Nn \l_tmpa_box - { - \c_math_toggle_token - \left #1 \vcenter to 3 cm { } \right. - \c_math_toggle_token - } - \dim_set:Nn \l_@@_left_delim_dim - { \box_wd:N \l_tmpa_box - \nulldelimiterspace } - \hbox_set:Nn \l_tmpa_box - { - \c_math_toggle_token - \left. \vcenter to 3 cm { } \right #2 - \c_math_toggle_token - } - \dim_set:Nn \l_@@_right_delim_dim - { \box_wd:N \l_tmpa_box - \nulldelimiterspace } +% \end{macrocode} +% The command |\bBigg@| is a command of \pkg{amsmath}. +% \begin{macrocode} + \hbox_set:Nn \l_tmpa_box { $ \bBigg@ 5 #1 $ } + \dim_set:Nn \l_@@_left_delim_dim { \box_wd:N \l_tmpa_box } + \hbox_set:Nn \l_tmpa_box { $\bBigg@ 5 #2 $ } + \dim_set:Nn \l_@@_right_delim_dim { \box_wd:N \l_tmpa_box } } % \end{macrocode} % @@ -4442,22 +4721,22 @@ version 2005/12/01 or later. \int_compare:nNnTF \l_@@_first_col_int = 0 { \tl_put_left:NV \l_tmpa_tl \c_@@_preamble_first_col_tl } { - \bool_if:nT + \bool_lazy_all:nT { - \l_@@_NiceArray_bool - && ! \l_@@_vlines_bool - && ! \l_@@_exterior_arraycolsep_bool + \l_@@_NiceArray_bool + { \bool_not_p:n \l_@@_vlines_bool } + { \bool_not_p:n \l_@@_exterior_arraycolsep_bool } } { \tl_put_left:Nn \l_tmpa_tl { @ { } } } } \int_compare:nNnTF \l_@@_last_col_int > { -1 } { \tl_put_right:NV \l_tmpa_tl \c_@@_preamble_last_col_tl } { - \bool_if:nT + \bool_lazy_all:nT { - \l_@@_NiceArray_bool - && ! \l_@@_vlines_bool - && ! \l_@@_exterior_arraycolsep_bool + \l_@@_NiceArray_bool + { \bool_not_p:n \l_@@_vlines_bool } + { \bool_not_p:n \l_@@_exterior_arraycolsep_bool } } { \tl_put_right:Nn \l_tmpa_tl { @ { } } } } @@ -4475,13 +4754,13 @@ version 2005/12/01 or later. % |\arraycolsep| is used once (between columns, |\arraycolsep| is used twice). % That's why we add a |0.5\arrayrulewidth| more. % \begin{macrocode} - \bool_if:NT \l_@@_vlines_bool + \bool_if:NT \l_@@_vlines_bool { \dim_add:Nn \arraycolsep { 0.5 \arrayrulewidth } - \skip_horizontal:n { 0.5 \arrayrulewidth } + \skip_horizontal:N 0.5\arrayrulewidth } - \skip_horizontal:n \l_@@_left_margin_dim - \skip_horizontal:n \l_@@_extra_left_margin_dim + \skip_horizontal:N \l_@@_left_margin_dim + \skip_horizontal:N \l_@@_extra_left_margin_dim \c_math_toggle_token \bool_if:NTF \l_@@_light_syntax_bool { \begin { @@-light-syntax } } @@ -4496,8 +4775,8 @@ version 2005/12/01 or later. { \end { @@-light-syntax } } { \end { @@-normal-syntax } } \c_math_toggle_token - \skip_horizontal:n \l_@@_right_margin_dim - \skip_horizontal:n \l_@@_extra_right_margin_dim + \skip_horizontal:N \l_@@_right_margin_dim + \skip_horizontal:N \l_@@_extra_right_margin_dim % \end{macrocode} % If the key |\vlines| is used, we have increased |\arraycolsep| by % |0.5\arrayrulewidth| in order to reserve space for the width of the vertical @@ -4505,7 +4784,7 @@ version 2005/12/01 or later. % |\arraycolsep| is used once (between columns, |\arraycolsep| is used twice). % That's we add a |0.5 \arrayrulewidth| more. % \begin{macrocode} - \bool_if:NT \l_@@_vlines_bool { \skip_horizontal:n { 0.5 \arrayrulewidth } } + \bool_if:NT \l_@@_vlines_bool { \skip_horizontal:N 0.5\arrayrulewidth } \hbox_set_end: % \end{macrocode} % End of the construction of the array (in the box |\l_@@_the_array_box|). @@ -4532,7 +4811,7 @@ version 2005/12/01 or later. % |\g_@@_col_total_int| change: |\c@jCol| will be the number of % columns without the ``last column''; |\g_@@_col_total_int| will be the % number of columns with this ``last column''.\footnote{We remind that the -% potential ``first column'' has the number~$0$.} +% potential ``first column'' (exterior) has the number~$0$.} % \begin{macrocode} \int_gset_eq:NN \c@jCol \g_@@_col_total_int \bool_if:nT \g_@@_last_col_found_bool { \int_gdecr:N \c@jCol } @@ -4556,15 +4835,14 @@ version 2005/12/01 or later. % \begin{macrocode} \int_compare:nNnT \l_@@_first_col_int = 0 { - \skip_horizontal:n \arraycolsep - \skip_horizontal:n \g_@@_width_first_col_dim + \skip_horizontal:N \arraycolsep + \skip_horizontal:N \g_@@_width_first_col_dim } % \end{macrocode} % -% The construction of the real box is different in |{NiceArray}| and in its -% variants (|{pNiceArray}|, etc.) because, in |{NiceArray}|, we have to take -% into account the option of position (|t|, |c| or |b|). We begin with -% |{NiceArray}|. +% The construction of the real box is different in |{NiceArray}| and in the +% other environments because, in |{NiceArray}|, we have to take into account the +% value of |baseline| and we have no delimiter to put. We begin with |{NiceArray}|. % \begin{macrocode} \bool_if:NTF \l_@@_NiceArray_bool { @@ -4575,16 +4853,12 @@ version 2005/12/01 or later. % \begin{macrocode} \str_if_eq:VnTF \l_@@_baseline_str { b } { - \begin { tikzpicture } - \@@_extract_coords:w ( nm - \int_use:N \g_@@_env_int - row - 1 ) + \pgfpicture + \@@_qpoint: { row - 1 } \dim_gset_eq:NN \g_tmpa_dim \pgf@y - \@@_extract_coords:w - ( - nm - \int_use:N \g_@@_env_int - - row - \int_use:N \c@iRow - base - ) + \@@_qpoint: { row - \int_use:N \c@iRow - base } \dim_gsub:Nn \g_tmpa_dim \pgf@y - \end { tikzpicture } + \endpgfpicture \int_compare:nNnT \l_@@_first_row_int = 0 { \dim_gadd:Nn \g_tmpa_dim @@ -4608,7 +4882,7 @@ version 2005/12/01 or later. \int_set:Nn \l_tmpa_int \l_@@_baseline_str \bool_if:nT { - \int_compare_p:nNn \l_tmpa_int < 0 + \int_compare_p:nNn \l_tmpa_int < \l_@@_first_row_int || \int_compare_p:nNn \l_tmpa_int > \g_@@_row_total_int } { @@ -4616,19 +4890,14 @@ version 2005/12/01 or later. \int_set:Nn \l_tmpa_int 1 } % \end{macrocode} -% We use a |{tikzpicture}| to extract coordinates (nothing is drawn). +% We use a |{pgfpicture}| to extract coordinates (nothing is drawn). % \begin{macrocode} - \begin { tikzpicture } - \@@_extract_coords:w - ( nm - \int_use:N \g_@@_env_int - row - 1 ) + \pgfpicture + \@@_qpoint: { row - 1 } \dim_gset_eq:NN \g_tmpa_dim \pgf@y - \@@_extract_coords:w - ( - nm - \int_use:N \g_@@_env_int - - row - \int_use:N \l_tmpa_int- base - ) + \@@_qpoint: { row - \int_use:N \l_tmpa_int - base } \dim_gsub:Nn \g_tmpa_dim \pgf@y - \end { tikzpicture } + \endpgfpicture \int_compare:nNnT \l_@@_first_row_int = 0 { \dim_gadd:Nn \g_tmpa_dim @@ -4648,8 +4917,8 @@ version 2005/12/01 or later. { \int_compare:nNnTF \l_@@_first_row_int = 0 { - \dim_set:Nn \l_tmpa_dim - { \g_@@_dp_row_zero_dim + \g_@@_ht_row_zero_dim } + \dim_set_eq:NN \l_tmpa_dim \g_@@_dp_row_zero_dim + \dim_add:Nn \l_tmpa_dim \g_@@_ht_row_zero_dim } { \dim_zero:N \l_tmpa_dim } % \end{macrocode} @@ -4663,8 +4932,8 @@ version 2005/12/01 or later. % \begin{macrocode} \int_compare:nNnTF \l_@@_last_row_int > { -2 } { - \dim_set:Nn \l_tmpb_dim - { \g_@@_ht_last_row_dim + \g_@@_dp_last_row_dim } + \dim_set_eq:NN \l_tmpb_dim \g_@@_ht_last_row_dim + \dim_add:Nn \l_tmpb_dim \g_@@_dp_last_row_dim } { \dim_zero:N \l_tmpb_dim } % \end{macrocode} @@ -4678,20 +4947,20 @@ version 2005/12/01 or later. { % \end{macrocode} % We take into account the ``first row'' (we have previously computed its total -% height in |\l_tmpa_dim|). +% height in |\l_tmpa_dim|). The |\hbox:n| (or |\hbox|) is necessary here. % \begin{macrocode} - \skip_vertical:n { - \l_tmpa_dim } - \hbox:n - { - \skip_horizontal:n { - \arraycolsep } + \skip_vertical:N -\l_tmpa_dim + \hbox + { + \skip_horizontal:N -\arraycolsep \box_use_drop:N \l_@@_the_array_box - \skip_horizontal:n { - \arraycolsep } + \skip_horizontal:N -\arraycolsep } % \end{macrocode} % We take into account the ``last row'' (we have previously computed its total % height in |\l_tmpb_dim|). % \begin{macrocode} - \skip_vertical:n { - \l_tmpb_dim } + \skip_vertical:N -\l_tmpb_dim } \right #2 \c_math_toggle_token @@ -4714,7 +4983,10 @@ version 2005/12/01 or later. % |\g_@@_width_last_col_dim|: see p.~\pageref{overlap-right}). % \begin{macrocode} \bool_if:NT \g_@@_last_col_found_bool - { \skip_horizontal:n { \g_@@_width_last_col_dim + \arraycolsep } } + { + \skip_horizontal:N \g_@@_width_last_col_dim + \skip_horizontal:N \arraycolsep + } \@@_after_array: } % \end{macrocode} @@ -4781,9 +5053,11 @@ version 2005/12/01 or later. % Now, we can put the box in the TeX flow with the horizontal adjustments on % both sides. % \begin{macrocode} - \skip_horizontal:n { \l_@@_left_delim_dim - \l_@@_real_left_delim_dim } + \skip_horizontal:N \l_@@_left_delim_dim + \skip_horizontal:N -\l_@@_real_left_delim_dim \@@_put_box_in_flow: - \skip_horizontal:n { \l_@@_right_delim_dim - \l_@@_real_right_delim_dim } + \skip_horizontal:N \l_@@_right_delim_dim + \skip_horizontal:N -\l_@@_real_right_delim_dim } % \end{macrocode} % @@ -4812,15 +5086,6 @@ version 2005/12/01 or later. { \exp_args:NV \@@_array: \l_tmpa_tl } } { -% \end{macrocode} -% -% If all the columns must have the same width (if the user has used the option -% |columns-width| or the option |auto-columns-width| of the environment -% |{NiceMatrixBlock}|), we will add a row in the array to fix the width of the -% columns and construct the ``|col|'' nodes |nm-|\textsl{a}|-col-|\textsl{j} -% (these nodes will be used by the horizontal open dotted lines and by the -% commands |\@@_vdottedline:n|). We have written a dedicated function for that job. -% \begin{macrocode} \@@_create_col_nodes: \endarray } @@ -4838,12 +5103,7 @@ version 2005/12/01 or later. % course, this test is more easy than the similar test for the ``normal syntax'' % because we have the whole body of the environment in |#1|. % \begin{macrocode} - \tl_if_empty:nT { #1 } { \@@_fatal:n { empty~environment } } -% \end{macrocode} -% Here is the call to |\array| (we have a dedicated macro |\@@_array:| because -% of compatibility with the classes \cls{revtex4-1} and \cls{revtex4-2}). -% \begin{macrocode} - \exp_args:NV \@@_array: \l_tmpa_tl + \tl_if_empty:nT { #1 } { \@@_fatal:n { empty~environment } } % \end{macrocode} % The body of the environment, which is stored in the argument |#1|, is now % splitted into items (and \emph{not} tokens) @@ -4852,6 +5112,19 @@ version 2005/12/01 or later. \tl_set_rescan:Nno \l_@@_end_of_row_tl { } \l_@@_end_of_row_tl \exp_args:NNV \seq_gset_split:Nnn \g_@@_rows_seq \l_@@_end_of_row_tl { #1 } % \end{macrocode} +% If the environment uses the option |last-row| without value (i.e. without +% saying the number of the rows), we have now the opportunity to know that +% value. We do it, and so, if the token list |\l_@@_code_for_last_row_tl| is not +% empty, we will use directly where it should be. +% \begin{macrocode} + \int_compare:nNnT \l_@@_last_row_int = { -1 } + { \int_set:Nn \l_@@_last_row_int { \seq_count:N \g_@@_rows_seq } } +% \end{macrocode} +% Here is the call to |\array| (we have a dedicated macro |\@@_array:| because +% of compatibility with the classes \cls{revtex4-1} and \cls{revtex4-2}). +% \begin{macrocode} + \exp_args:NV \@@_array: \l_tmpa_tl +% \end{macrocode} % We need a global affectation because, when executing |\l_tmpa_tl|, we will % exit the first cell of the array. % \begin{macrocode} @@ -4922,48 +5195,50 @@ version 2005/12/01 or later. \int_compare:nNnT \l_@@_first_col_int = 0 { \omit & } \omit % \end{macrocode} -% The following instruction must be put after the instructions |\omit|. +% The following instruction must be put after the instruction |\omit|. % \begin{macrocode} \bool_gset_true:N \g_@@_row_of_col_done_bool % \end{macrocode} % First, we put a ``|col|'' node on the left of the first column (of course, we % have to do that \emph{after} the |\omit|). % \begin{macrocode} - \tikz [ remember~picture ] - \coordinate ( nm - \int_use:N \g_@@_env_int - col - 1 ) ; + \pgfpicture + \pgfrememberpicturepositiononpagetrue + \pgfcoordinate { \@@_env: - col - 1 } \pgfpointorigin + \str_if_empty:NF \l_@@_name_str + { \pgfnodealias { \@@_env: - col - 1 } { \l_@@_name_str - col - 1 } } + \endpgfpicture % \end{macrocode} % We compute in |\g_tmpa_skip| the common width of the columns (it's a skip and % not a dimension). We use a global variable because we are in a cell of an % |\halign| and because we have to use this variable in other cells (of the same % row). The affectation of |\g_tmpa_skip|, like all the affectations, must be % done after the |\omit| of the cell. +% +% \smallskip +% We give a default value for |\g_tmpa_skip| (|0 pt plus 1 fill|) but it will +% just after erased by a fixed value in the concerned cases. % \begin{macrocode} - \bool_if:nTF + \skip_gset:Nn \g_tmpa_skip { 0 pt~plus 1 fill } + \bool_if:NF \l_@@_auto_columns_width_bool + { \dim_compare:nNnT \l_@@_columns_width_dim > \c_zero_dim } { - \l_@@_auto_columns_width_bool - || \dim_compare_p:nNn \l_@@_columns_width_dim > \c_zero_dim - } - { - \bool_if:nTF - { - \l_@@_auto_columns_width_bool - && ! \l_@@_block_auto_columns_width_bool - } - { - \skip_gset:Nn \g_tmpa_skip - { \g_@@_max_cell_width_dim + 2 \arraycolsep } - } - { - \skip_gset:Nn \g_tmpa_skip - { \l_@@_columns_width_dim + 2 \arraycolsep } - } + \bool_lazy_and:nnTF + \l_@@_auto_columns_width_bool + { \bool_not_p:n \l_@@_block_auto_columns_width_bool } + { \skip_gset_eq:NN \g_tmpa_skip \g_@@_max_cell_width_dim } + { \skip_gset_eq:NN \g_tmpa_skip \l_@@_columns_width_dim } + \skip_gadd:Nn \g_tmpa_skip { 2 \arraycolsep } } - { \skip_gset:Nn \g_tmpa_skip { 0 pt~plus 1 fill } } \skip_horizontal:N \g_tmpa_skip - \hbox:n + \hbox { - \tikz [ remember~picture ] - \coordinate ( nm - \int_use:N \g_@@_env_int - col - 2 ) ; + \pgfpicture + \pgfrememberpicturepositiononpagetrue + \pgfcoordinate { \@@_env: - col - 2 } \pgfpointorigin + \str_if_empty:NF \l_@@_name_str + { \pgfnodealias { \@@_env: - col - 2 } { \l_@@_name_str - col - 2 } } + \endpgfpicture } % \end{macrocode} % We begin a loop over the columns. The integer |\g_tmpa_int| will be the @@ -4985,12 +5260,17 @@ version 2005/12/01 or later. % \end{macrocode} % We create the ``|col|'' node on the right of the current column. % \begin{macrocode} - \tikz [ remember~picture ] - \coordinate - ( - nm - \int_use:N \g_@@_env_int - - col - \int_eval:n { \g_tmpa_int + 1 } - ) ; + \pgfpicture + \pgfrememberpicturepositiononpagetrue + \pgfcoordinate { \@@_env: - col - \@@_succ:N \g_tmpa_int } + \pgfpointorigin + \str_if_empty:NF \l_@@_name_str + { + \pgfnodealias + { \@@_env: - col - \@@_succ:N \g_tmpa_int } + { \l_@@_name_str - col - \@@_succ:N \g_tmpa_int } + } + \endpgfpicture } \cr } @@ -5017,17 +5297,17 @@ version 2005/12/01 or later. % We insert |\l_@@_code_for_first_col_tl|... but we don't insert it in the % potential ``first row'' and in the potential ``last row''. % \begin{macrocode} - \bool_if:nT + \bool_lazy_and:nnT + { \int_compare_p:nNn \c@iRow > 0 } { - \int_compare_p:nNn \c@iRow > 0 - && - ( - \int_compare_p:nNn \l_@@_last_row_int < 0 - || - \int_compare_p:nNn \c@iRow < \l_@@_last_row_int - ) + \bool_lazy_or_p:nn + { \int_compare_p:nNn \l_@@_last_row_int < 0 } + { \int_compare_p:nNn \c@iRow < \l_@@_last_row_int } + } + { + \l_@@_code_for_first_col_tl + \xglobal \colorlet { nicematrix-first-col } { . } } - { \l_@@_code_for_first_col_tl } } % \end{macrocode} % Be careful: despite this letter |l| the cells of the ``first column'' are @@ -5044,49 +5324,21 @@ version 2005/12/01 or later. % after the construction of the array. % \begin{macrocode} \dim_gset:Nn \g_@@_width_first_col_dim - { - \dim_max:nn - \g_@@_width_first_col_dim - { \box_wd:N \l_@@_cell_box } - } + { \dim_max:nn \g_@@_width_first_col_dim { \box_wd:N \l_@@_cell_box } } % \end{macrocode} % The content of the cell is inserted in an overlapping position. % \label{overlap-left} % \begin{macrocode} \hbox_overlap_left:n { - \tikz - [ - remember~picture , - inner~sep = \c_zero_dim , - minimum~width = \c_zero_dim , - baseline - ] - \node - [ - anchor = base , - name = - nm - - \int_use:N \g_@@_env_int - - \int_use:N \c@iRow - - 0 , - alias = - \str_if_empty:NF \l_@@_name_str - { - \l_@@_name_str - - \int_use:N \c@iRow - - 0 - } - ] - { \box_use_drop:N \l_@@_cell_box } ; - \skip_horizontal:n - { - \l_@@_left_delim_dim + - \l_@@_left_margin_dim + - \l_@@_extra_left_margin_dim - } + \dim_compare:nNnTF { \box_wd:N \l_@@_cell_box } > \c_zero_dim + \@@_node_for_the_cell: + { \box_use_drop:N \l_@@_cell_box } + \skip_horizontal:N \l_@@_left_delim_dim + \skip_horizontal:N \l_@@_left_margin_dim + \skip_horizontal:N \l_@@_extra_left_margin_dim } - \skip_horizontal:n { - 2 \arraycolsep } + \skip_horizontal:N -2\arraycolsep } } % \end{macrocode} @@ -5118,17 +5370,16 @@ version 2005/12/01 or later. % We insert |\l_@@_code_for_last_col_tl|... but we don't insert it in the % potential ``first row'' and in the potential ``last row''. % \begin{macrocode} - \bool_if:nT + \int_compare:nNnT \c@iRow > 0 { - \int_compare_p:nNn \c@iRow > 0 - && - ( - \int_compare_p:nNn \l_@@_last_row_int < 0 - || - \int_compare_p:nNn \c@iRow < \l_@@_last_row_int - ) + \bool_lazy_or:nnT + { \int_compare_p:nNn \l_@@_last_row_int < 0 } + { \int_compare_p:nNn \c@iRow < \l_@@_last_row_int } + { + \l_@@_code_for_last_col_tl + \xglobal \colorlet { nicematrix-last-col } { . } + } } - { \l_@@_code_for_last_col_tl } } l < @@ -5141,48 +5392,21 @@ version 2005/12/01 or later. % after the construction of the array. % \begin{macrocode} \dim_gset:Nn \g_@@_width_last_col_dim - { - \dim_max:nn - \g_@@_width_last_col_dim - { \box_wd:N \l_@@_cell_box } - } - \skip_horizontal:n { - 2 \arraycolsep } + { \dim_max:nn \g_@@_width_last_col_dim { \box_wd:N \l_@@_cell_box } } + \skip_horizontal:N -2\arraycolsep % \end{macrocode} % The content of the cell is inserted in an overlapping position. % \label{overlap-right} % \begin{macrocode} \hbox_overlap_right:n { - \skip_horizontal:n - { - \l_@@_right_delim_dim + - \l_@@_right_margin_dim + - \l_@@_extra_right_margin_dim + \dim_compare:nNnT { \box_wd:N \l_@@_cell_box } > \c_zero_dim + { + \skip_horizontal:N \l_@@_right_delim_dim + \skip_horizontal:N \l_@@_right_margin_dim + \skip_horizontal:N \l_@@_extra_right_margin_dim + \@@_node_for_the_cell: } - \tikz - [ - remember~picture , - inner~sep = \c_zero_dim , - minimum~width = \c_zero_dim , - baseline - ] - \node - [ - anchor = base , - name = - nm - - \int_use:N \g_@@_env_int - - \int_use:N \c@iRow - - \int_use:N \c@jCol , - alias = - \str_if_empty:NF \l_@@_name_str - { - \l_@@_name_str - - \int_use:N \c@iRow - - \int_use:N \c@jCol - } - ] - { \box_use_drop:N \l_@@_cell_box } ; } } } @@ -5212,8 +5436,7 @@ version 2005/12/01 or later. % % % \interitem -% We create the variants of the environment |{NiceArrayWithDelims}|. These -% variants exist since the version 3.0 of \pkg{nicematrix}. +% We create the variants of the environment |{NiceArrayWithDelims}|. % % \begin{macrocode} \NewDocumentEnvironment { pNiceArray } { } @@ -5279,23 +5502,31 @@ version 2005/12/01 or later. \NewDocumentEnvironment { #1 NiceMatrix } { ! O { } } { \str_gset:Nn \g_@@_name_env_str { #1 NiceMatrix } + \tl_set:Nn \l_@@_type_of_col_tl C \keys_set:nn { NiceMatrix / NiceMatrix } { ##1 } - \begin { #1 NiceArray } - { - * - { - \int_compare:nNnTF \l_@@_last_col_int = { -1 } - \c@MaxMatrixCols - { \int_eval:n { \l_@@_last_col_int - 1 } } - } - C - } + \exp_args:Nnx \@@_begin_of_NiceMatrix:nn { #1 } \l_@@_type_of_col_tl } { \end { #1 NiceArray } } } % \end{macrocode} % % \begin{macrocode} +\cs_new_protected:Npn \@@_begin_of_NiceMatrix:nn #1 #2 + { + \begin { #1 NiceArray } + { + * + { + \int_compare:nNnTF \l_@@_last_col_int = { -1 } + \c@MaxMatrixCols + { \int_eval:n { \l_@@_last_col_int - 1 } } + } + #2 + } + } +% \end{macrocode} +% +% \begin{macrocode} \@@_define_env:n { } \@@_define_env:n p \@@_define_env:n b @@ -5305,130 +5536,36 @@ version 2005/12/01 or later. % \end{macrocode} % % -% \bigskip -% \subsection*{How to know whether a cell is ``empty''} -% -% The conditionnal |\@@_if_not_empty_cell:nnT| tests whether 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 , TF } - { -% \end{macrocode} -% First, we want to test whether the cell is in the virtual sequence of -% ``non-empty'' cells. There are several important remarks: -% \begin{itemize} -% \item we don't use a |expl3| sequence for efficiency; -% \item the ``non-empty'' cells in this sequence are not, in fact, all the -% non-empty cells of the array: on the contrary they are only cells declared -% as non-empty for a special reason (as of now, there are only cells which are -% on a dotted line which is already drawn or which will be drawn ``just -% after''); -% \item the flag |\l_tmpa_bool| will be raised when the cell is actually on -% this virtual sequence. -% \end{itemize} -% \begin{macrocode} - \bool_set_false:N \l_tmpa_bool - \cs_if_exist:cTF - { @@ _ dotted _ \int_use:N #1 - \int_use:N #2 } - \prg_return_true: - { -% \end{macrocode} -% We know that the cell is not in the virtual sequence of the ``non-empty'' -% cells. Now, we test wether the cell is a ``virtual cell'', that is to say a -% cell after the |\\| of the line of the array. It's easy to known whether a -% cell is vitual: the cell is virtual if, and only if, the corresponding Tikz -% node doesn't exist. -% \begin{macrocode} - \cs_if_free:cTF - { - pgf@sh@ns@nm - - \int_use:N \g_@@_env_int - - \int_use:N #1 - - \int_use:N #2 - } - { \prg_return_false: } - { -% \end{macrocode} -% Now, we want to test whether the cell is in the virtual sequence of -% ``empty'' cells. There are several important remarks: -% \begin{itemize} -% \item we don't use a |expl3| sequence for efficiency ; -% \item the ``empty'' cells in this sequence are not, in fact, all the -% non-empty cells of the array: on the contrary they are only cells declared -% as non-empty for a special reason ; -% \item the flag |\l_tmpa_bool| will be raised when the cell is actually on -% this virtual sequence. -% \end{itemize} -% \begin{macrocode} - \bool_set_false:N \l_tmpa_bool - \cs_if_exist:cT - { @@ _ empty _ \int_use:N #1 - \int_use:N #2 } - { - \int_compare:nNnT - { \use:c { @@ _ empty _ \int_use:N #1 - \int_use:N #2 } } - = - \g_@@_env_int - { \bool_set_true:N \l_tmpa_bool } - } - \bool_if:NTF \l_tmpa_bool - \prg_return_false: -% \end{macrocode} -% In the general case, we consider the width of the Tikz node corresponding to -% the cell. In order to compute this width, we have to extract the coordinate of -% the west and east anchors of the node. This extraction needs a command -% environment |{pgfpicture}| but, in fact, nothing is drawn. -% \begin{macrocode} - { - \begin { pgfpicture } -% \end{macrocode} -% We store the name of the node corresponding to the cell in |\l_tmpa_tl|. -% \begin{macrocode} - \tl_set:Nx \l_tmpa_tl - { - nm - - \int_use:N \g_@@_env_int - - \int_use:N #1 - - \int_use:N #2 - } - \pgfpointanchor \l_tmpa_tl { east } - \dim_gset:Nn \g_tmpa_dim \pgf@x - \pgfpointanchor \l_tmpa_tl { west } - \dim_gset:Nn \g_tmpb_dim \pgf@x - \end { pgfpicture } - \dim_compare:nNnTF - { \dim_abs:n { \g_tmpb_dim - \g_tmpa_dim } } < { 0.5 pt } - \prg_return_false: - \prg_return_true: - } - } - } - } -% \end{macrocode} % % % \bigskip % \subsection*{After the construction of the array} % -% -% \medskip -% We deactivate Tikz externalization. -% -% Since we use Tikz pictures with the options |overlay| and |remember picture|, -% there would be errors. +% \medskip % \begin{macrocode} \cs_new_protected:Npn \@@_after_array: { \group_begin: - \cs_if_exist:NT \tikz@library@external@loaded - { \tikzset { external / export = false } } % \end{macrocode} % -% In the user has used the option |last-row| without value, we write in the -% |aux| file the number of that last row for the next run. +% If a last column is announced in the options, but without the value (because +% we are in an environment with preamble, it's time to fix the real value of +% |\l_@@_last_col_int|). +% \begin{macrocode} + \int_compare:nNnT \l_@@_last_col_int = 0 + { + \bool_if:NT \g_@@_last_col_found_bool + { \dim_set_eq:NN \l_@@_last_col_int \g_@@_col_total_int } + } +% \end{macrocode} +% +% It's also time to give to |\l_@@_last_row_int| its real value. But, if the +% user had used the option |last-row| without value, we write in the |aux| file +% the number of that last row for the next run. % \begin{macrocode} \bool_if:NT \l_@@_last_row_without_value_bool { + \dim_set_eq:NN \l_@@_last_row_int \g_@@_row_total_int \iow_now:Nn \@mainaux \ExplSyntaxOn \iow_now:Nx \@mainaux { @@ -5461,38 +5598,32 @@ version 2005/12/01 or later. % \begin{macrocode} \bool_if:NT \l_@@_parallelize_diags_bool { - \int_zero_new:N \l_@@_ddots_int - \int_zero_new:N \l_@@_iddots_int + \int_gzero_new:N \g_@@_ddots_int + \int_gzero_new:N \g_@@_iddots_int % \end{macrocode} % -% The dimensions |\l_@@_delta_x_one_dim| and |\l_@@_delta_y_one_dim| will +% The dimensions |\g_@@_delta_x_one_dim| and |\g_@@_delta_y_one_dim| will % contain the $\Delta_x$ and $\Delta_y$ of the first |\Ddots| diagonal. We have % to store these values in order to draw the others |\Ddots| diagonals parallel -% to the first one. Similarly |\l_@@_delta_x_two_dim| and -% |\l_@@_delta_y_two_dim| are the $\Delta_x$ and $\Delta_y$ of the first +% to the first one. Similarly |\g_@@_delta_x_two_dim| and +% |\g_@@_delta_y_two_dim| are the $\Delta_x$ and $\Delta_y$ of the first % |\Iddots| diagonal. % \begin{macrocode} - \dim_zero_new:N \l_@@_delta_x_one_dim - \dim_zero_new:N \l_@@_delta_y_one_dim - \dim_zero_new:N \l_@@_delta_x_two_dim - \dim_zero_new:N \l_@@_delta_y_two_dim + \dim_gzero_new:N \g_@@_delta_x_one_dim + \dim_gzero_new:N \g_@@_delta_y_one_dim + \dim_gzero_new:N \g_@@_delta_x_two_dim + \dim_gzero_new:N \g_@@_delta_y_two_dim } % \end{macrocode} % -% The booleans |\g_@@_medium_nodes_bool| and |\g_@@_large_nodes_bool| may be -% raised directly in cells of the array (for example in commands |\Block|) but -% also because the user has used the options |create-medium-nodes| and -% |create-large-nodes| (these options raise |\l_@@_medium_nodes_bool| and -% |\l_@@_large_nodes_bool| but theses booleans are converted into the global -% versions before the creation of the array). % \begin{macrocode} - \bool_if:nTF \g_@@_medium_nodes_bool + \bool_if:nTF \l_@@_medium_nodes_bool { - \bool_if:NTF \g_@@_large_nodes_bool + \bool_if:NTF \l_@@_large_nodes_bool \@@_create_medium_and_large_nodes: \@@_create_medium_nodes: } - { \bool_if:NT \g_@@_large_nodes_bool \@@_create_large_nodes: } + { \bool_if:NT \l_@@_large_nodes_bool \@@_create_large_nodes: } \int_zero_new:N \l_@@_initial_i_int \int_zero_new:N \l_@@_initial_j_int \int_zero_new:N \l_@@_final_i_int @@ -5502,43 +5633,50 @@ version 2005/12/01 or later. % \end{macrocode} % % If the option |small| is used, the values |\l_@@_radius_dim| and -% |\l_@@_inter_dots_dim| (used to draw the dotted lines) are changed. +% |\l_@@_inter_dots_dim| (used to draw the dotted lines created by +% |\hdottedline| and |\vdotteline| and also for all the other dotted lines when +% |line-style| is equal to |standard|, which is the initial value) are changed. % \begin{macrocode} \bool_if:NT \l_@@_small_bool { \dim_set:Nn \l_@@_radius_dim { 0.37 pt } \dim_set:Nn \l_@@_inter_dots_dim { 0.25 em } +% \end{macrocode} +% The dimension |\l_@@_xdots_shorten_dim| corresponds to the option +% |xdots/shorten| available to the user. That's why we give a new value +% according to the current value, and not a absolute value. +% \begin{macrocode} + \dim_set:Nn \l_@@_xdots_shorten_dim { 0.6 \l_@@_xdots_shorten_dim } } % \end{macrocode} % +% % \bigskip -% Now, we really draw the lines. The code to draw the lines has been constructed -% in the token lists |\g_@@_Vdots_lines_tl|, etc. +% Now, we really draw the lines. % \begin{macrocode} - \g_@@_Hdotsfor_lines_tl - \g_@@_Vdots_lines_tl - \g_@@_Ddots_lines_tl - \g_@@_Iddots_lines_tl - \g_@@_Cdots_lines_tl - \g_@@_Ldots_lines_tl + \@@_draw_dotted_lines: % \end{macrocode} -% % -% -% \bigskip -% Now, the |code-after|. +% We draw the vertical rules of the option |vlines| before the +% |internal-code-after| because the option |white| of a |\Block| may have to +% erase these vertical rules. % \begin{macrocode} - \tikzset - { - every~picture / .style = + \bool_if:NT \l_@@_vlines_bool \@@_draw_vlines: + \g_@@_internal_code_after_tl + \tl_gclear:N \g_@@_internal_code_after_tl + \bool_if:NT \c_@@_tikz_loaded_bool + { + \tikzset { - overlay , - remember~picture , - name~prefix = nm - \int_use:N \g_@@_env_int - - } + every~picture / .style = + { + overlay , + remember~picture , + name~prefix = \@@_env: - + } + } } - \bool_if:NT \l_@@_vlines_bool \@@_draw_vlines: - \cs_set_eq:NN \line \@@_line:nn + \cs_set_eq:NN \line \@@_line \g_@@_code_after_tl \tl_gclear:N \g_@@_code_after_tl \group_end: @@ -5548,56 +5686,38 @@ version 2005/12/01 or later. % \end{macrocode} % % \bigskip +% We recall that, when externalization is used, |\tikzpicture| and +% |\endtikzpicture| (or |\pgfpicture| and |\endpgfpicture|) must be directly +% ``visible''. That's why we have to define the adequate version of +% |\@@_draw_dotted_lines:| whether Tikz is loaded or not (in that case, only +% \textsc{pgf} is loaded). % \begin{macrocode} -\cs_new_protected:Npn \@@_draw_vlines: +\AtBeginDocument { - \group_begin: -% \end{macrocode} -% The command |\CT@arc@| is a command of color from \pkg{colortbl}. -% \begin{macrocode} - \bool_if:NT \c_@@_colortbl_loaded_bool \CT@arc@ - \begin { tikzpicture } [ line~width = \arrayrulewidth ] -% \end{macrocode} -% First, we compute in |\l_tmpa_dim| the height of the rules we have to draw. -% \begin{macrocode} - \@@_extract_coords:w ( row - 1 ) - \dim_set_eq:NN \l_tmpa_dim \pgf@y - \@@_extract_coords:w ( row - \int_eval:n { \c@iRow + 1 } ) - \dim_set:Nn \l_tmpa_dim { \l_tmpa_dim - \pgf@y } -% \end{macrocode} -% We translate vertically to take into account the potential ``last row''. -% \begin{macrocode} - \dim_zero:N \l_tmpb_dim - \int_compare:nNnT \l_@@_last_row_int > { -1 } + \cs_new_protected:Npx \@@_draw_dotted_lines: { - \dim_set:Nn \l_tmpb_dim - { \g_@@_dp_last_row_dim + \g_@@_ht_last_row_dim } -% \end{macrocode} -% We adjust the value of |\l_tmpa_dim| by the width of the horizontal rule just -% before the ``last row''. -% \begin{macrocode} - \@@_extract_coords:w ( row - \int_eval:n { \c@iRow + 1 } ) - \dim_add:Nn \l_tmpa_dim \pgf@y - \@@_extract_coords:w ( row - \int_eval:n { \g_@@_row_total_int + 1 } ) - \dim_sub:Nn \l_tmpa_dim \pgf@y - \dim_sub:Nn \l_tmpa_dim \l_tmpb_dim - } + \c_@@_pgfortikzpicture_tl + \@@_draw_dotted_lines_i: + \c_@@_endpgfortikzpicture_tl + } + } % \end{macrocode} % -% Now, we can draw the lines with a loop. +% The following command \emph{must} be protected because it will appear in the +% construction of the command |\@@_draw_dotted_lines:|. % \begin{macrocode} - \int_step_inline:nnn - { \bool_if:NTF \l_@@_NiceArray_bool 1 2 } - { \bool_if:NTF \l_@@_NiceArray_bool { \c@jCol + 1 } \c@jCol } - { - \draw ( col - ##1 ) ++ ( 0 , \dim_use:N \l_tmpb_dim ) - -- ++ ( 0 , \dim_use:N \l_tmpa_dim ) ; - } - \end { tikzpicture } - \group_end: +\cs_new_protected:Npn \@@_draw_dotted_lines_i: + { + \pgfrememberpicturepositiononpagetrue + \pgf@relevantforpicturesizefalse + \g_@@_Hdotsfor_lines_tl + \g_@@_Vdots_lines_tl + \g_@@_Ddots_lines_tl + \g_@@_Iddots_lines_tl + \g_@@_Cdots_lines_tl + \g_@@_Ldots_lines_tl } % \end{macrocode} -% % % \bigskip % \begin{macrocode} @@ -5617,18 +5737,6 @@ version 2005/12/01 or later. % 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'' or the |col|-node. -% \[ \begin{pNiceMatrix}[create-medium-nodes, -% code-after = {\begin{tikzpicture} -% \node [highlight = (2-1)] {} ; -% \node [highlight = (2-3-medium) ] {}; -% \end{tikzpicture} -% }] -% a+b+c & a+b & a\\ -% a & \Cdots \\ -% a & a+b & a+b+c -% \end{pNiceMatrix}\] % % % \bigskip @@ -5706,12 +5814,11 @@ version 2005/12/01 or later. \bool_if:NTF \l_@@_final_open_bool % \end{macrocode} % If we are outside the matrix, we have found the extremity of the dotted line -% and it's a \emph{open} extremity. +% and it's an \emph{open} extremity. % \begin{macrocode} { % \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). +% We do a step backwards. % \begin{macrocode} \int_sub:Nn \l_@@_final_i_int { #3 } \int_sub:Nn \l_@@_final_j_int { #4 } @@ -5723,48 +5830,49 @@ version 2005/12/01 or later. % |\l_@@_final_i_int| and |\l_@@_final_j_int|. % \begin{macrocode} { - \@@_if_not_empty_cell:nnTF \l_@@_final_i_int \l_@@_final_j_int - { \bool_set_true:N \l_@@_stop_loop_bool } + \cs_if_exist:cTF + { + @@ _ dotted _ + \int_use:N \l_@@_final_i_int - + \int_use:N \l_@@_final_j_int + } + { + \int_sub:Nn \l_@@_final_i_int { #3 } + \int_sub:Nn \l_@@_final_j_int { #4 } + \bool_set_true:N \l_@@_final_open_bool + \bool_set_true:N \l_@@_stop_loop_bool + } + { + \cs_if_exist:cTF + { + pgf @ sh @ ns @ \@@_env: + - \int_use:N \l_@@_final_i_int + - \int_use:N \l_@@_final_j_int + } + { \bool_set_true:N \l_@@_stop_loop_bool } % \end{macrocode} % If the case is empty, we declare that the cell as non-empty. Indeed, we will % draw a dotted line and the cell will be on that dotted line. All the cells of % a dotted line have to be mark as ``dotted'' because we don't want -% intersections between dotted lines. +% intersections between dotted lines. We recall that the research of the +% extremities of the lines are all done in the same TeX group (the group of the +% environnement), even though, when the extremities are found, each line is +% drawn in a TeX group that we will open for the options of the line. % \begin{macrocode} - { - \cs_set:cpn { - @@ _ dotted _ - \int_use:N \l_@@_final_i_int - - \int_use:N \l_@@_final_j_int - } - { } + \cs_set:cpn + { + @@ _ dotted _ + \int_use:N \l_@@_final_i_int - + \int_use:N \l_@@_final_j_int + } + { } + } } } } % \end{macrocode} -% We test wether the initial extremity of the dotted line is an implicit cell -% already dotted (by another dotted line). In this case, we can't draw the line -% because we have no Tikz node at the extremity of the arrow. % -% \begin{macrocode} - \cs_if_free:cT - { - pgf@sh@ns@nm - - \int_use:N \g_@@_env_int - - \int_use:N \l_@@_final_i_int - - \int_use:N \l_@@_final_j_int - } - { - \bool_if:NF \l_@@_final_open_bool - { - \msg_error:nnx { nicematrix } { Impossible~line } - { \int_use:N \l_@@_final_i_int } - \bool_set_true:N \l_@@_impossible_line_bool - } - } -% \end{macrocode} -% % \interitem % For |\l_@@_initial_i_int| and |\l_@@_initial_j_int| the programmation is % similar to the previous one. @@ -5801,142 +5909,106 @@ version 2005/12/01 or later. \bool_set_true:N \l_@@_stop_loop_bool } { - \@@_if_not_empty_cell:nnTF - \l_@@_initial_i_int \l_@@_initial_j_int - { \bool_set_true:N \l_@@_stop_loop_bool } + \cs_if_exist:cTF + { + @@ _ dotted _ + \int_use:N \l_@@_initial_i_int - + \int_use:N \l_@@_initial_j_int + } + { + \int_add:Nn \l_@@_initial_i_int { #3 } + \int_add:Nn \l_@@_initial_j_int { #4 } + \bool_set_true:N \l_@@_initial_open_bool + \bool_set_true:N \l_@@_stop_loop_bool + } { - \cs_set:cpn + \cs_if_exist:cTF { - @@ _ dotted _ - \int_use:N \l_@@_initial_i_int - - \int_use:N \l_@@_initial_j_int + pgf @ sh @ ns @ \@@_env: + - \int_use:N \l_@@_initial_i_int + - \int_use:N \l_@@_initial_j_int + } + { \bool_set_true:N \l_@@_stop_loop_bool } + { + \cs_set:cpn + { + @@ _ dotted _ + \int_use:N \l_@@_initial_i_int - + \int_use:N \l_@@_initial_j_int + } + { } } - { } - } - } - } -% \end{macrocode} -% We test whether the initial extremity of the dotted line is an implicit cell -% already dotted (by another dotted line). In this case, we can't draw the line -% because we have no Tikz node at the extremity of the arrow. -% \begin{macrocode} - \cs_if_free:cT - { - pgf@sh@ns@nm - - \int_use:N \g_@@_env_int - - \int_use:N \l_@@_initial_i_int - - \int_use:N \l_@@_initial_j_int - } - { - \bool_if:NF \l_@@_initial_open_bool - { - \msg_error:nnx { nicematrix } { Impossible~line } - { \int_use:N \l_@@_initial_i_int } - \bool_set_true:N \l_@@_impossible_line_bool + } } } + } % \end{macrocode} -% If we have at least one open extremity, we create the ``medium nodes'' in the -% matrix but we should change that because, for an open extremity on the left or -% the right side of the array, we actually use the |col|-nodes. -% We remind that, when used once, the command |\@@_create_medium_nodes:| becomes -% no-op in the current TeX group. -% \begin{macrocode} - \bool_if:NT \l_@@_initial_open_bool \@@_create_medium_nodes: - \bool_if:NT \l_@@_final_open_bool \@@_create_medium_nodes: - } -% \end{macrocode} -% -% -% -% \interitem -% The command |\@@_retrieve_coords:nn| retrieves the Tikz coordinates of the two -% extremities of the dotted line we will have to draw \footnote{In fact, with -% diagonal lines, or vertical lines in columns of type |L| or |R|, an 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 suffix and -% the anchor that must be used for the two nodes. -% -% The coordinates are stored in four variables: -% \begin{itemize} -% \item |\g_@@_x_initial_dim| -% \item |\g_@@_y_initial_dim| -% \item |\g_@@_x_final_dim| -% \item |\g_@@_y_final_dim|. -% \end{itemize} % -% These variables are global for technical reasons: we have to do an affectation -% in an environment |{tikzpicture}|. +% \medskip % \begin{macrocode} -\cs_new_protected:Npn \@@_retrieve_coords:nn #1 #2 +\cs_new:Nn \@@_initial_cell: + { \@@_env: - \int_use:N \l_@@_initial_i_int - \int_use:N \l_@@_initial_j_int } +\cs_new:Nn \@@_final_cell: + { \@@_env: - \int_use:N \l_@@_final_i_int - \int_use:N \l_@@_final_j_int } +\cs_new_protected:Npn \@@_set_initial_coords: { - \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 ] - \@@_extract_coords:w - ( nm - \int_use:N \g_@@_env_int - - \int_use:N \l_@@_initial_i_int - - \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 - \@@_extract_coords:w - ( nm - \int_use:N \g_@@_env_int - - \int_use:N \l_@@_final_i_int - - \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 { x x } -% \end{macrocode} -% -% \interitem -% For the horizontal lines with open extremities, we take into account the -% ``|col|'' nodes. The following command will recompute the $x$-value of the -% extremities in this case (erasing the value computed in -% |\@@_retrieve_coords:nn|). -% \begin{macrocode} -\cs_new_protected:Npn \@@_adjust_with_col_nodes: + \dim_set_eq:NN \l_@@_x_initial_dim \pgf@x + \dim_set_eq:NN \l_@@_y_initial_dim \pgf@y + } +\cs_new_protected:Npn \@@_set_final_coords: { - \bool_if:NT \l_@@_initial_open_bool - { - \begin { tikzpicture } [ remember~picture ] - \@@_extract_coords:w ( nm - \int_use:N \g_@@_env_int - col - 1 ) - \dim_gset:Nn \g_@@_x_initial_dim \pgf@x - \end { tikzpicture } - } - \bool_if:NT \l_@@_final_open_bool - { - \begin { tikzpicture } [ remember~picture ] - \@@_extract_coords:w - ( nm - \int_use:N \g_@@_env_int - col - \int_eval:n { \c@jCol + 1 } ) - \dim_gset:Nn \g_@@_x_final_dim \pgf@x - \end { tikzpicture } - } + \dim_set_eq:NN \l_@@_x_final_dim \pgf@x + \dim_set_eq:NN \l_@@_y_final_dim \pgf@y + } +\cs_new_protected:Npn \@@_set_initial_coords_from_anchor:n #1 + { + \pgfpointanchor \@@_initial_cell: { #1 } + \@@_set_initial_coords: + } +\cs_new_protected:Npn \@@_set_final_coords_from_anchor:n #1 + { + \pgfpointanchor \@@_final_cell: { #1 } + \@@_set_final_coords: } % \end{macrocode} % % \interitem +% The first and the second arguments are the coordinates of the cell where the +% command has been issued. The third argument is the list of the options. % \begin{macrocode} -\cs_new_protected:Npn \@@_draw_Ldots:nn #1 #2 +\cs_new_protected:Npn \@@_draw_Ldots:nnn #1 #2 #3 { \cs_if_free:cT { @@ _ dotted _ #1 - #2 } { - \bool_set_false:N \l_@@_impossible_line_bool \@@_find_extremities_of_line:nnnn { #1 } { #2 } 0 1 - \bool_if:NF \l_@@_impossible_line_bool \@@_actually_draw_Ldots: +% \end{macrocode} +% The previous command may have changed the current environment by marking some +% cells as ``dotted'', but, fortunately, it is outside the group for the options +% of the line. +% \begin{macrocode} + \group_begin: + \int_compare:nNnTF { #1 } = 0 + { \color { nicematrix-first-row } } + { +% \end{macrocode} +% We remind that, when there is a ``last row'' |\l_@@_last_row_int| will always +% be (after the construction of the array) the number of that ``last row'' even +% if the option |last-row| has been used without value. +% \begin{macrocode} + \int_compare:nNnT { #1 } = \l_@@_last_row_int + { \color { nicematrix-last-row } } + } + \keys_set:nn { NiceMatrix / xdots } { #3 } + \tl_if_empty:VF \l_@@_xdots_color_tl { \color { \l_@@_xdots_color_tl } } + \@@_actually_draw_Ldots: + \group_end: } } % \end{macrocode} % +% % \medskip -% The command |\@@_actually_draw_Ldots:| draws the |Ldots| line using the -% following variables: +% The command |\@@_actually_draw_Ldots:| has the following implicit arguments: % \begin{itemize} % \item |\l_@@_initial_i_int| % \item |\l_@@_initial_j_int| @@ -5946,128 +6018,244 @@ version 2005/12/01 or later. % \item |\l_@@_final_open_bool|. % \end{itemize} % -% We have a dedicated command because it is used also by |\Hdotsfor|. +% The following function is also used by |\Hdotsfor|. % \begin{macrocode} \cs_new_protected:Npn \@@_actually_draw_Ldots: { - \@@_retrieve_coords:xx - { - \bool_if:NTF \l_@@_initial_open_bool - { - medium.base~west } - { .base~east } + \bool_if:NTF \l_@@_initial_open_bool + { + \@@_qpoint: { col - \int_use:N \l_@@_initial_j_int } + \dim_set_eq:NN \l_@@_x_initial_dim \pgf@x + \dim_add:Nn \l_@@_x_initial_dim \arraycolsep + \@@_qpoint: { row - \int_use:N \l_@@_initial_i_int - base } + \dim_set_eq:NN \l_@@_y_initial_dim \pgf@y } + { \@@_set_initial_coords_from_anchor:n { base~east } } + \bool_if:NTF \l_@@_final_open_bool { - \bool_if:NTF \l_@@_final_open_bool - { - medium.base~east } - { .base~west } + \@@_qpoint: { col - \@@_succ:N \l_@@_final_j_int } + \dim_set_eq:NN \l_@@_x_final_dim \pgf@x + \dim_sub:Nn \l_@@_x_final_dim \arraycolsep + \@@_qpoint: { row - \int_use:N \l_@@_final_i_int - base } + \dim_set_eq:NN \l_@@_y_final_dim \pgf@y } - \@@_adjust_with_col_nodes: - \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 } + { \@@_set_final_coords_from_anchor:n { base~west } } % \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.53 pt } - \dim_gadd:Nn \g_@@_y_final_dim { 0.53 pt } - \@@_draw_tikz_line: + \dim_add:Nn \l_@@_y_initial_dim \l_@@_radius_dim + \dim_add:Nn \l_@@_y_final_dim \l_@@_radius_dim + \@@_draw_line: +% \end{macrocode} +% The values of |\l_@@_x_initial_dim|, |\l_@@_y_initial_dim|, |\l_@@_x_final_dim|, +% |\l_@@_y_final_dim|, +% +% |\l_@@_initial_open_bool| and |\l_@@_final_open_bool| are still available +% after the |\@@_draw_line:|. +% \begin{macrocode} } % \end{macrocode} % -% \bigskip +% \interitem +% The first and the second arguments are the coordinates of the cell where the +% command has been issued. The third argument is the list of the options. % \begin{macrocode} -\cs_new_protected:Npn \@@_draw_Cdots:nn #1 #2 +\cs_new_protected:Npn \@@_draw_Cdots:nnn #1 #2 #3 { \cs_if_free:cT { @@ _ dotted _ #1 - #2 } { - \bool_set_false:N \l_@@_impossible_line_bool \@@_find_extremities_of_line:nnnn { #1 } { #2 } 0 1 - \bool_if:NF \l_@@_impossible_line_bool - { - \@@_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 } - } - \@@_adjust_with_col_nodes: - \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} +% The previous command may have changed the current environment by marking some +% cells as ``dotted'', but, fortunately, it is outside the group for the options +% of the line. +% \begin{macrocode} + \group_begin: + \int_compare:nNnTF { #1 } = 0 + { \color { nicematrix-first-row } } + { +% \end{macrocode} +% We remind that, when there is a ``last row'' |\l_@@_last_row_int| will always +% be (after the construction of the array) the number of that ``last row'' even +% if the option |last-row| has been used without value. +% \begin{macrocode} + \int_compare:nNnT { #1 } = \l_@@_last_row_int + { \color { nicematrix-last-row } } + } + \keys_set:nn { NiceMatrix / xdots } { #3 } + \tl_if_empty:VF \l_@@_xdots_color_tl { \color { \l_@@_xdots_color_tl } } + \@@_actually_draw_Cdots: + \group_end: } } % \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?). +% \medskip +% The command |\@@_actually_draw_Cdots:| has the following implicit arguments: +% \begin{itemize} +% \item |\l_@@_initial_i_int| +% \item |\l_@@_initial_j_int| +% \item |\l_@@_initial_open_bool| +% \item |\l_@@_final_i_int| +% \item |\l_@@_final_j_int| +% \item |\l_@@_final_open_bool|. +% \end{itemize} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_actually_draw_Cdots: + { + \bool_if:NTF \l_@@_initial_open_bool + { + \@@_qpoint: { col - \int_use:N \l_@@_initial_j_int } + \dim_set_eq:NN \l_@@_x_initial_dim \pgf@x + \dim_add:Nn \l_@@_x_initial_dim \arraycolsep + } + { \@@_set_initial_coords_from_anchor:n { mid~east } } + \bool_if:NTF \l_@@_final_open_bool + { + \@@_qpoint: { col - \@@_succ:N \l_@@_final_j_int } + \dim_set_eq:NN \l_@@_x_final_dim \pgf@x + \dim_sub:Nn \l_@@_x_final_dim \arraycolsep + } + { \@@_set_final_coords_from_anchor:n { mid~west } } + \bool_lazy_and:nnTF + \l_@@_initial_open_bool + \l_@@_final_open_bool + { + \@@_qpoint: { row - \int_use:N \l_@@_initial_i_int } + \dim_set_eq:NN \l_tmpa_dim \pgf@y + \@@_qpoint: { row - \@@_succ:N \l_@@_initial_i_int } + \dim_set:Nn \l_@@_y_initial_dim { ( \l_tmpa_dim + \pgf@y ) / 2 } + \dim_set_eq:NN \l_@@_y_final_dim \l_@@_y_initial_dim + } + { + \bool_if:NT \l_@@_initial_open_bool + { \dim_set_eq:NN \l_@@_y_initial_dim \l_@@_y_final_dim } + \bool_if:NT \l_@@_final_open_bool + { \dim_set_eq:NN \l_@@_y_final_dim \l_@@_y_initial_dim } + } + \@@_draw_line: +% \end{macrocode} +% The values of |\l_@@_x_initial_dim|, |\l_@@_y_initial_dim|, |\l_@@_x_final_dim|, +% |\l_@@_y_final_dim|, +% +% |\l_@@_initial_open_bool| and |\l_@@_final_open_bool| are still available +% after the |\@@_draw_line:|. +% \begin{macrocode} + } +% \end{macrocode} +% +% +% The first and the second arguments are the coordinates of the cell where the +% command has been issued. The third argument is the list of the options. % \begin{macrocode} -\cs_new_protected:Npn \@@_draw_Vdots:nn #1 #2 +\cs_new_protected:Npn \@@_draw_Vdots:nnn #1 #2 #3 { + \tl_if_empty:VF \l_@@_xdots_color_tl { \color { \l_@@_xdots_color_tl } } \cs_if_free:cT { @@ _ dotted _ #1 - #2 } { - \bool_set_false:N \l_@@_impossible_line_bool \@@_find_extremities_of_line:nnnn { #1 } { #2 } 1 0 - \bool_if:NF \l_@@_impossible_line_bool - { - \@@_retrieve_coords:xx - { - \bool_if:NTF \l_@@_initial_open_bool - { - medium.north~west } - { .south~west } - } - { - \bool_if:NTF \l_@@_final_open_bool - { - medium.south~west } - { .north~west } - } +% \end{macrocode} +% The previous command may have changed the current environment by marking some +% cells as ``dotted'', but, fortunately, it is outside the group for the options +% of the line. +% \begin{macrocode} + \group_begin: + \int_compare:nNnTF { #2 } = 0 + { \color { nicematrix-first-col } } + { + \int_compare:nNnT { #2 } = \l_@@_last_col_int + { \color { nicematrix-last-col } } + } + \keys_set:nn { NiceMatrix / xdots } { #3 } + \@@_actually_draw_Vdots: + \group_end: + } + } +% \end{macrocode} +% +% \bigskip +% The command |\@@_actually_draw_Vdots:| has the following implicit arguments: +% \begin{itemize} +% \item |\l_@@_initial_i_int| +% \item |\l_@@_initial_j_int| +% \item |\l_@@_initial_open_bool| +% \item |\l_@@_final_i_int| +% \item |\l_@@_final_j_int| +% \item |\l_@@_final_open_bool|. +% \end{itemize} +% \begin{macrocode} +\cs_new_protected:Npn \@@_actually_draw_Vdots: + { % \end{macrocode} % The boolean |\l_tmpa_bool| indicates whether the column is of type |l| (|L| of % |{NiceArray}|) or may be considered as if. % \begin{macrocode} - \bool_set:Nn \l_tmpa_bool - { \dim_compare_p:nNn \g_@@_x_initial_dim = \g_@@_x_final_dim } - \@@_retrieve_coords:xx - { - \bool_if:NTF \l_@@_initial_open_bool - { - medium.north } - { .south } - } - { - \bool_if:NTF \l_@@_final_open_bool - { - medium.south } - { .north } - } + \bool_set_false:N \l_tmpa_bool + \bool_lazy_or:nnF \l_@@_initial_open_bool \l_@@_final_open_bool + { + \@@_set_initial_coords_from_anchor:n { south~west } + \@@_set_final_coords_from_anchor:n { north~west } + \bool_set:Nn \l_tmpa_bool + { \dim_compare_p:nNn \l_@@_x_initial_dim = \l_@@_x_final_dim } + } % \end{macrocode} -% The boolean |\l_tmpb_bool| indicates whether the column is of type |c| (|C| of +% Now, we try to determine whether the column is of type |c| (|C| of % |{NiceArray}|) or may be considered as if. +% \begin{macrocode} + \bool_if:NTF \l_@@_initial_open_bool + { + \@@_qpoint: { row - 1 } + \dim_set_eq:NN \l_@@_y_initial_dim \pgf@y + } + { \@@_set_initial_coords_from_anchor:n { south } } + \bool_if:NTF \l_@@_final_open_bool + { + \@@_qpoint: { row - \@@_succ:N \c@iRow } + \dim_set_eq:NN \l_@@_y_final_dim \pgf@y + } + { \@@_set_final_coords_from_anchor:n { north } } + \bool_if:NTF \l_@@_initial_open_bool + { + \bool_if:NTF \l_@@_final_open_bool + { + \@@_qpoint: { col - \int_use:N \l_@@_initial_j_int } + \dim_set_eq:NN \l_tmpa_dim \pgf@x + \@@_qpoint: { col - \@@_succ:N \l_@@_initial_j_int } + \dim_set:Nn \l_@@_x_initial_dim { ( \pgf@x + \l_tmpa_dim ) / 2 } + \dim_set_eq:NN \l_@@_x_final_dim \l_@@_x_initial_dim + } + { \dim_set_eq:NN \l_@@_x_initial_dim \l_@@_x_final_dim } + } + { + \bool_if:NTF \l_@@_final_open_bool + { \dim_set_eq:NN \l_@@_x_final_dim \l_@@_x_initial_dim } + { +% \end{macrocode} +% Now the case where both extremities are closed. The first conditional tests +% whether the column is of type |c| (|C| of |{NiceArray}|) or may be considered +% as if. % \begin{macrocode} - \bool_set:Nn \l_tmpb_bool - { \dim_compare_p:nNn \g_@@_x_initial_dim = \g_@@_x_final_dim } - \bool_if:NF \l_tmpb_bool + \dim_compare:nNnF \l_@@_x_initial_dim = \l_@@_x_final_dim { - \dim_gset:Nn \g_@@_x_initial_dim + \dim_set:Nn \l_@@_x_initial_dim { \bool_if:NTF \l_tmpa_bool \dim_min:nn \dim_max:nn - \g_@@_x_initial_dim \g_@@_x_final_dim + \l_@@_x_initial_dim \l_@@_x_final_dim } - \dim_gset_eq:NN \g_@@_x_final_dim \g_@@_x_initial_dim + \dim_set_eq:NN \l_@@_x_final_dim \l_@@_x_initial_dim } - \@@_draw_tikz_line: - } + } } + \@@_draw_line: +% \end{macrocode} +% The values of |\l_@@_x_initial_dim|, |\l_@@_y_initial_dim|, |\l_@@_x_final_dim|, +% |\l_@@_y_final_dim|, +% +% |\l_@@_initial_open_bool| and |\l_@@_final_open_bool| are +% still available after the |\@@_draw_line:|. +% \begin{macrocode} } % \end{macrocode} % @@ -6075,118 +6263,190 @@ version 2005/12/01 or later. % For the diagonal lines, the situation is a bit more complicated because, by % default, we parallelize the diagonals lines. The first diagonal line is drawn % and then, all the other diagonal lines are drawn parallel to the first one. +% +% The first and the second arguments are the coordinates of the cell where the +% command has been issued. The third argument is the list of the options. % \begin{macrocode} -\cs_new_protected:Npn \@@_draw_Ddots:nn #1 #2 +\cs_new_protected:Npn \@@_draw_Ddots:nnn #1 #2 #3 { \cs_if_free:cT { @@ _ dotted _ #1 - #2 } { - \bool_set_false:N \l_@@_impossible_line_bool \@@_find_extremities_of_line:nnnn { #1 } { #2 } 1 1 - \bool_if:NF \l_@@_impossible_line_bool - { - \@@_retrieve_coords:xx - { - \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} +% The previous command may have changed the current environment by marking some +% cells as ``dotted'', but, fortunately, it is outside the group for the options +% of the line. +% \begin{macrocode} + \group_begin: + \keys_set:nn { NiceMatrix / xdots } { #3 } + \tl_if_empty:VF \l_@@_xdots_color_tl { \color { \l_@@_xdots_color_tl } } + \@@_actually_draw_Ddots: + \group_end: + } + } +% \end{macrocode} +% +% \bigskip +% The command |\@@_actually_draw_Ddots:| has the following implicit arguments: +% \begin{itemize} +% \item |\l_@@_initial_i_int| +% \item |\l_@@_initial_j_int| +% \item |\l_@@_initial_open_bool| +% \item |\l_@@_final_i_int| +% \item |\l_@@_final_j_int| +% \item |\l_@@_final_open_bool|. +% \end{itemize} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_actually_draw_Ddots: + { + \bool_if:NTF \l_@@_initial_open_bool + { + \@@_qpoint: { row - \int_use:N \l_@@_initial_i_int } + \dim_set_eq:NN \l_@@_y_initial_dim \pgf@y + \@@_qpoint: { col - \int_use:N \l_@@_initial_j_int } + \dim_set_eq:NN \l_@@_x_initial_dim \pgf@x + } + { \@@_set_initial_coords_from_anchor:n { south~east } } + \bool_if:NTF \l_@@_final_open_bool + { + \@@_qpoint: { row - \@@_succ:N \l_@@_final_i_int } + \dim_set_eq:NN \l_@@_y_final_dim \pgf@y + \@@_qpoint: { col - \@@_succ:N \l_@@_final_j_int } + \dim_set_eq:NN \l_@@_x_final_dim \pgf@x + } + { \@@_set_final_coords_from_anchor:n { 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, +% |\l_@@_x_initial_dim|, etc.). If the parallelization of the diagonals is set, % we will have (maybe) to adjust the fourth coordinate. % \begin{macrocode} - \bool_if:NT \l_@@_parallelize_diags_bool - { - \int_incr:N \l_@@_ddots_int + \bool_if:NT \l_@@_parallelize_diags_bool + { + \int_gincr:N \g_@@_ddots_int % \end{macrocode} -% We test if the diagonal line is the first one (the counter |\l_@@_ddots_int| +% We test if the diagonal line is the first one (the counter |\g_@@_ddots_int| % is created for this usage). % \begin{macrocode} - \int_compare:nNnTF \l_@@_ddots_int = 1 + \int_compare:nNnTF \g_@@_ddots_int = 1 % \end{macrocode} % If the diagonal line is the first one, we have no adjustment of the line to do % but we store the $\Delta_x$ and the $\Delta_y$ of the line because these % values will be used to draw the others diagonal lines parallels to the first % one. % \begin{macrocode} - { - \dim_set:Nn \l_@@_delta_x_one_dim - { \g_@@_x_final_dim - \g_@@_x_initial_dim } - \dim_set:Nn \l_@@_delta_y_one_dim - { \g_@@_y_final_dim - \g_@@_y_initial_dim } - } + { + \dim_gset:Nn \g_@@_delta_x_one_dim + { \l_@@_x_final_dim - \l_@@_x_initial_dim } + \dim_gset:Nn \g_@@_delta_y_one_dim + { \l_@@_y_final_dim - \l_@@_y_initial_dim } + } % \end{macrocode} % If the diagonal line is not the first one, we have to adjust the second -% extremity of the line by modifying the coordinate |\g_@@_y_initial_dim|. +% extremity of the line by modifying the coordinate |\l_@@_x_initial_dim|. % \begin{macrocode} - { - \dim_gset:Nn \g_@@_y_final_dim - { - \g_@@_y_initial_dim + - ( \g_@@_x_final_dim - \g_@@_x_initial_dim ) * - \dim_ratio:nn \l_@@_delta_y_one_dim \l_@@_delta_x_one_dim - } - } + { + \dim_set:Nn \l_@@_y_final_dim + { + \l_@@_y_initial_dim + + ( \l_@@_x_final_dim - \l_@@_x_initial_dim ) * + \dim_ratio:nn \g_@@_delta_y_one_dim \g_@@_delta_x_one_dim } -% \end{macrocode} -% Now, we can draw the dotted line (after a possible change of -% |\g_@@_y_initial_dim|). -% \begin{macrocode} - \@@_draw_tikz_line: } } + \@@_draw_line: +% \end{macrocode} +% The values of |\l_@@_x_initial_dim|, |\l_@@_y_initial_dim|, |\l_@@_x_final_dim|, +% |\l_@@_y_final_dim|, +% +% |\l_@@_initial_open_bool| and |\l_@@_final_open_bool| are still available +% after the |\@@_draw_line:|. +% \begin{macrocode} } % \end{macrocode} % % \bigskip % We draw the |\Iddots| diagonals in the same way. +% +% The first and the second arguments are the coordinates of the cell where the +% command has been issued. The third argument is the list of the options. % \begin{macrocode} -\cs_new_protected:Npn \@@_draw_Iddots:nn #1 #2 +\cs_new_protected:Npn \@@_draw_Iddots:nnn #1 #2 #3 { \cs_if_free:cT { @@ _ dotted _ #1 - #2 } { - \bool_set_false:N \l_@@_impossible_line_bool \@@_find_extremities_of_line:nnnn { #1 } { #2 } 1 { -1 } - \bool_if:NF \l_@@_impossible_line_bool - { - \@@_retrieve_coords:xx - { - \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 +% \end{macrocode} +% The previous command may have changed the current environment by marking some +% cells as ``dotted'', but, fortunately, it is outside the group for the options +% of the line. +% \begin{macrocode} + \group_begin: + \keys_set:nn { NiceMatrix / xdots } { #3 } + \tl_if_empty:VF \l_@@_xdots_color_tl { \color { \l_@@_xdots_color_tl } } + \@@_actually_draw_Iddots: + \group_end: + } + } +% \end{macrocode} +% +% \bigskip +% The command |\@@_actually_draw_Iddots:| has the following implicit arguments: +% \begin{itemize} +% \item |\l_@@_initial_i_int| +% \item |\l_@@_initial_j_int| +% \item |\l_@@_initial_open_bool| +% \item |\l_@@_final_i_int| +% \item |\l_@@_final_j_int| +% \item |\l_@@_final_open_bool|. +% \end{itemize} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_actually_draw_Iddots: + { + \bool_if:NTF \l_@@_initial_open_bool + { + \@@_qpoint: { row - \int_use:N \l_@@_initial_i_int } + \dim_set_eq:NN \l_@@_y_initial_dim \pgf@y + \@@_qpoint: { col - \@@_succ:N \l_@@_initial_j_int } + \dim_set_eq:NN \l_@@_x_initial_dim \pgf@x + } + { \@@_set_initial_coords_from_anchor:n { south~west } } + \bool_if:NTF \l_@@_final_open_bool + { + \@@_qpoint: { row - \@@_succ:N \l_@@_final_i_int } + \dim_set_eq:NN \l_@@_y_final_dim \pgf@y + \@@_qpoint: { col - \int_use:N \l_@@_final_j_int } + \dim_set_eq:NN \l_@@_x_final_dim \pgf@x + } + { \@@_set_final_coords_from_anchor:n { north~east } } + \bool_if:NT \l_@@_parallelize_diags_bool + { + \int_gincr:N \g_@@_iddots_int + \int_compare:nNnTF \g_@@_iddots_int = 1 + { + \dim_gset:Nn \g_@@_delta_x_two_dim + { \l_@@_x_final_dim - \l_@@_x_initial_dim } + \dim_gset:Nn \g_@@_delta_y_two_dim + { \l_@@_y_final_dim - \l_@@_y_initial_dim } + } + { + \dim_set:Nn \l_@@_y_final_dim { - \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 - } - } + \l_@@_y_initial_dim + + ( \l_@@_x_final_dim - \l_@@_x_initial_dim ) * + \dim_ratio:nn \g_@@_delta_y_two_dim \g_@@_delta_x_two_dim } - \@@_draw_tikz_line: } } + \@@_draw_line: +% \end{macrocode} +% The values of |\l_@@_x_initial_dim|, |\l_@@_y_initial_dim|, |\l_@@_x_final_dim|, +% |\l_@@_y_final_dim|, +% +% |\l_@@_initial_open_bool| and |\l_@@_final_open_bool| are still available +% after the |\@@_draw_line:|. +% \begin{macrocode} } % \end{macrocode} % @@ -6205,95 +6465,153 @@ version 2005/12/01 or later. % \bigskip % \subsection*{The actual instructions for drawing the dotted line with Tikz} % -% The command |\@@_draw_tikz_line:| draws the line using four implicit -% arguments: +% The command |\@@_draw_line:| should be used in a |{pgfpicture}|. It has six +% implicit arguments: +% +% \begin{itemize} +% \item |\l_@@_x_initial_dim| +% \item |\l_@@_y_initial_dim| +% \item |\l_@@_x_final_dim| +% \item |\l_@@_y_final_dim| +% \item |\l_@@_initial_open_bool| +% \item |\l_@@_final_open_bool| +% \end{itemize} +% % -% \quad |\g_@@_x_initial_dim|, |\g_@@_y_initial_dim|, |\g_@@_x_final_dim| and -% |\g_@@_y_final_dim|. These variables are global for technical reasons: their -% first affectation was in an instruction |\tikz|. % % \begin{macrocode} -\cs_new_protected:Npn \@@_draw_tikz_line: +\cs_new_protected:Npn \@@_draw_line: + { + \pgfrememberpicturepositiononpagetrue + \pgf@relevantforpicturesizefalse + \tl_if_eq:NNTF \l_@@_xdots_line_style_tl \c_@@_standard_tl + \@@_draw_standard_dotted_line: + \@@_draw_non_standard_dotted_line: + } +% \end{macrocode} +% +% \medskip +% We have to do a special construction with |\exp_args:NV| to be able to put in +% the list of options in the correct place in the Tikz instruction. +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_non_standard_dotted_line: + { + \begin { scope } + \exp_args:No \@@_draw_non_standard_dotted_line:n + { \l_@@_xdots_line_style_tl , \l_@@_xdots_color_tl } + } +% \end{macrocode} +% We have used the fact that, in \textsc{pgf}, un color name can be put directly +% in a list of options (that's why we have put diredtly |\l_@@_xdots_color_tl|). +% +% \smallskip +% The argument of |\@@_draw_non_standard_dotted_line:n| is, in fact, the list of options. +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_non_standard_dotted_line:n #1 + { + \draw + [ + #1 , + shorten~> = \l_@@_xdots_shorten_dim , + shorten~< = \l_@@_xdots_shorten_dim , + ] + ( \l_@@_x_initial_dim , \l_@@_y_initial_dim ) + -- ( \l_@@_x_final_dim , \l_@@_y_final_dim ) ; + \end { scope } + } +% \end{macrocode} +% +% \bigskip +% The command |\@@_draw_standard_dotted_line:| draws the line with our system of points +% (which give a dotted line with real round points). +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_standard_dotted_line: { + \pgfrememberpicturepositiononpagetrue + \pgf@relevantforpicturesizefalse + \group_begin: % \end{macrocode} % The dimension |\l_@@_l_dim| is the length $\ell$ of the line to draw. We use % the floating point reals of \pkg{expl3} to compute this length. % \begin{macrocode} - \dim_zero_new:N \l_@@_l_dim - \dim_set:Nn \l_@@_l_dim - { - \fp_to_dim:n - { - sqrt - ( - ( \dim_use:N \g_@@_x_final_dim - - \dim_use:N \g_@@_x_initial_dim - ) ^ 2 - + - ( \dim_use:N \g_@@_y_final_dim - - \dim_use:N \g_@@_y_initial_dim - ) ^ 2 - ) - } - } + \dim_zero_new:N \l_@@_l_dim + \dim_set:Nn \l_@@_l_dim + { + \fp_to_dim:n + { + sqrt + ( + ( \l_@@_x_final_dim - \l_@@_x_initial_dim ) ^ 2 + + + ( \l_@@_y_final_dim - \l_@@_y_initial_dim ) ^ 2 + ) + } + } % \end{macrocode} % We draw only if the length is not equal to zero (in fact, in the first -% compilation, the length may be equal to zero). +% compilation, the length may be equal to zero when the command |\line| is used). +% \begin{macrocode} + \dim_compare:nNnF \l_@@_l_dim = \c_zero_dim \@@_actually_draw_line: + \group_end: + } +% \end{macrocode} +% +% % \begin{macrocode} - \dim_compare:nNnF \l_@@_l_dim = \c_zero_dim +\cs_new_protected:Npn \@@_actually_draw_line: + { % \end{macrocode} % The integer |\l_tmpa_int| is the number of dots of the dotted line. % \begin{macrocode} + \bool_if:NTF \l_@@_initial_open_bool { - \bool_if:NTF \l_@@_initial_open_bool + \bool_if:NTF \l_@@_final_open_bool { - \bool_if:NTF \l_@@_final_open_bool + \int_set:Nn \l_tmpa_int + { \dim_ratio:nn \l_@@_l_dim \l_@@_inter_dots_dim } + } + { + \int_set:Nn \l_tmpa_int { - \int_set:Nn \l_tmpa_int - { \dim_ratio:nn \l_@@_l_dim \l_@@_inter_dots_dim } - } - { - \int_set:Nn \l_tmpa_int - { - \dim_ratio:nn - { \l_@@_l_dim - \l_@@_dotted_lines_margin_dim } - \l_@@_inter_dots_dim - } + \dim_ratio:nn + { \l_@@_l_dim - \l_@@_xdots_shorten_dim } + \l_@@_inter_dots_dim } } + } + { + \bool_if:NTF \l_@@_final_open_bool { - \bool_if:NTF \l_@@_final_open_bool + \int_set:Nn \l_tmpa_int { - \int_set:Nn \l_tmpa_int - { - \dim_ratio:nn - { \l_@@_l_dim - \l_@@_dotted_lines_margin_dim } - \l_@@_inter_dots_dim - } + \dim_ratio:nn + { \l_@@_l_dim - \l_@@_xdots_shorten_dim } + \l_@@_inter_dots_dim } + } + { + \int_set:Nn \l_tmpa_int { - \int_set:Nn \l_tmpa_int - { - \dim_ratio:nn - { \l_@@_l_dim - ( 2 \l_@@_dotted_lines_margin_dim ) } - \l_@@_inter_dots_dim - } + \dim_ratio:nn + { \l_@@_l_dim - ( 2 \l_@@_xdots_shorten_dim ) } + \l_@@_inter_dots_dim } } + } % \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_ratio:nn \l_@@_inter_dots_dim \l_@@_l_dim - } - \dim_set:Nn \l_tmpb_dim - { - ( \g_@@_y_final_dim - \g_@@_y_initial_dim ) * - \dim_ratio:nn \l_@@_inter_dots_dim \l_@@_l_dim - } + \dim_set:Nn \l_tmpa_dim + { + ( \l_@@_x_final_dim - \l_@@_x_initial_dim ) * + \dim_ratio:nn \l_@@_inter_dots_dim \l_@@_l_dim + } + \dim_set:Nn \l_tmpb_dim + { + ( \l_@@_y_final_dim - \l_@@_y_initial_dim ) * + \dim_ratio:nn \l_@@_inter_dots_dim \l_@@_l_dim + } % \end{macrocode} % % The length $\ell$ is the length of the dotted line. We note $\Delta$ the @@ -6302,73 +6620,50 @@ version 2005/12/01 or later. % 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 } - } + \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, the dimensions |\g_@@_x_initial_dim| and -% |\g_@@_y_initial_dim| will be used for the coordinates of the dots. But, +% In the loop over the dots, the dimensions |\l_@@_x_initial_dim| and +% |\l_@@_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 ) * - \dim_ratio:nn - { \l_@@_l_dim - \l_@@_inter_dots_dim * \l_tmpa_int } - { 2 \l_@@_l_dim } - * \l_tmpb_int - } - \dim_gadd:Nn \g_@@_y_initial_dim - { - ( \g_@@_y_final_dim - \g_@@_y_initial_dim ) * - \dim_ratio:nn - { \l_@@_l_dim - \l_@@_inter_dots_dim * \l_tmpa_int } - { 2 \l_@@_l_dim } - * \l_tmpb_int - } - \begin { tikzpicture } [ overlay ] - \int_step_inline:nnn 0 \l_tmpa_int - { - \pgfpathcircle - { \pgfpoint { \g_@@_x_initial_dim } { \g_@@_y_initial_dim } } - { \l_@@_radius_dim } - \pgfusepath { fill } - \dim_gadd:Nn \g_@@_x_initial_dim \l_tmpa_dim - \dim_gadd:Nn \g_@@_y_initial_dim \l_tmpb_dim - } - \end { tikzpicture } + \dim_gadd:Nn \l_@@_x_initial_dim + { + ( \l_@@_x_final_dim - \l_@@_x_initial_dim ) * + \dim_ratio:nn + { \l_@@_l_dim - \l_@@_inter_dots_dim * \l_tmpa_int } + { 2 \l_@@_l_dim } + * \l_tmpb_int + } + \dim_gadd:Nn \l_@@_y_initial_dim + { + ( \l_@@_y_final_dim - \l_@@_y_initial_dim ) * + \dim_ratio:nn + { \l_@@_l_dim - \l_@@_inter_dots_dim * \l_tmpa_int } + { 2 \l_@@_l_dim } + * \l_tmpb_int } + \pgf@relevantforpicturesizefalse + \int_step_inline:nnn 0 \l_tmpa_int + { + \pgfpathcircle + { \pgfpoint \l_@@_x_initial_dim \l_@@_y_initial_dim } + { \l_@@_radius_dim } + \dim_add:Nn \l_@@_x_initial_dim \l_tmpa_dim + \dim_add:Nn \l_@@_y_initial_dim \l_tmpb_dim + } + \pgfusepathqfill } % \end{macrocode} % % \bigskip % \subsection*{User commands available in the new environments} % -% We give new names for the commands |\ldots|, |\cdots|, |\vdots| and |\ddots| -% because these commands will be redefined (if the option |renew-dots| is used). -% \begin{macrocode} -\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 -% \end{macrocode} -% -% \interitem -% The command |\@@_add_to_empty_cells:| declares the current cell as empty. For -% efficiency, this is done by creating a special control sequence. -% \begin{macrocode} -\cs_new_protected:Npn \@@_add_to_empty_cells: - { - \cs_gset:cpx - { @@ _ empty _ \int_use:N \c@iRow - \int_use:N \c@jCol } - { \int_use:N \g_@@_env_int } - } -% \end{macrocode} % % \interitem % The commands |\@@_Ldots|, |\@@_Cdots|, |\@@_Vdots|, |\@@_Ddots| and @@ -6376,54 +6671,64 @@ version 2005/12/01 or later. % |\Iddots| in the environments |{NiceArray}| (the other environments of % \pkg{nicematrix} rely upon |{NiceArray}|). % -% The starred versions of these commands are deprecated since version~3.1 but -% they are still available. +% The starred versions of these commands are deprecated since version~3.1 but, +% as for now, they are still available with an error. % \begin{macrocode} -\NewDocumentCommand \@@_Ldots { s } +\NewDocumentCommand \@@_Ldots { s O { } } { - \bool_if:nF { #1 } { \@@_instruction_of_type:n { Ldots } } + \bool_if:nTF { #1 } + { \@@_error:n { starred~commands } } + { \@@_instruction_of_type:nn { Ldots } { #2 } } \bool_if:NF \l_@@_nullify_dots_bool { \phantom \@@_ldots } - \@@_add_to_empty_cells: + \bool_gset_true:N \g_@@_empty_cell_bool } % \end{macrocode} % % \bigskip % \begin{macrocode} -\NewDocumentCommand \@@_Cdots { s } +\NewDocumentCommand \@@_Cdots { s O { } } { - \bool_if:nF { #1 } { \@@_instruction_of_type:n { Cdots } } + \bool_if:nTF { #1 } + { \@@_error:n { starred~commands } } + { \@@_instruction_of_type:nn { Cdots } { #2 } } \bool_if:NF \l_@@_nullify_dots_bool { \phantom \@@_cdots } - \@@_add_to_empty_cells: + \bool_gset_true:N \g_@@_empty_cell_bool } % \end{macrocode} % % \bigskip % \begin{macrocode} -\NewDocumentCommand \@@_Vdots { s } +\NewDocumentCommand \@@_Vdots { s O { } } { - \bool_if:nF { #1 } { \@@_instruction_of_type:n { Vdots } } + \bool_if:nTF { #1 } + { \@@_error:n { starred~commands } } + { \@@_instruction_of_type:nn { Vdots } { #2 } } \bool_if:NF \l_@@_nullify_dots_bool { \phantom \@@_vdots } - \@@_add_to_empty_cells: + \bool_gset_true:N \g_@@_empty_cell_bool } % \end{macrocode} % % \bigskip % \begin{macrocode} -\NewDocumentCommand \@@_Ddots { s } +\NewDocumentCommand \@@_Ddots { s O { } } { - \bool_if:nF { #1 } { \@@_instruction_of_type:n { Ddots } } + \bool_if:nTF { #1 } + { \@@_error:n { starred~commands } } + { \@@_instruction_of_type:nn { Ddots } { #2 } } \bool_if:NF \l_@@_nullify_dots_bool { \phantom \@@_ddots } - \@@_add_to_empty_cells: + \bool_gset_true:N \g_@@_empty_cell_bool } % \end{macrocode} % % \bigskip % \begin{macrocode} -\NewDocumentCommand \@@_Iddots { s } +\NewDocumentCommand \@@_Iddots { s O { } } { - \bool_if:nF { #1 } { \@@_instruction_of_type:n { Iddots } } + \bool_if:nTF { #1 } + { \@@_error:n { starred~commands } } + { \@@_instruction_of_type:nn { Iddots } { #2 } } \bool_if:NF \l_@@_nullify_dots_bool { \phantom \@@_iddots } - \@@_add_to_empty_cells: + \bool_gset_true:N \g_@@_empty_cell_bool } % \end{macrocode} % @@ -6433,7 +6738,7 @@ version 2005/12/01 or later. % \begin{macrocode} \cs_new_protected:Npn \@@_Hspace: { - \@@_add_to_empty_cells: + \bool_gset_true:N \g_@@_empty_cell_bool \hspace } % \end{macrocode} @@ -6483,18 +6788,23 @@ version 2005/12/01 or later. % \begin{macrocode} \bool_if:NTF \c_@@_draft_bool { - \NewDocumentCommand \@@_Hdotsfor_i { O { } m } +% \end{macrocode} +% We don't put |!| before the last optionnal argument for homogeneity with +% |\Cdots|, etc. which have only one optional argument. +% \begin{macrocode} + \NewDocumentCommand \@@_Hdotsfor_i { O { } m O { } } { \prg_replicate:nn { #2 - 1 } { & \multicolumn { 1 } { C } { } } } } { - \NewDocumentCommand \@@_Hdotsfor_i { O { } m } + \NewDocumentCommand \@@_Hdotsfor_i { O { } m O { } } { \tl_gput_right:Nx \g_@@_Hdotsfor_lines_tl { - \@@_Hdotsfor:nnn + \@@_Hdotsfor:nnnn { \int_use:N \c@iRow } { \int_use:N \c@jCol } { #2 } + { #3 } } \prg_replicate:nn { #2 - 1 } { & \multicolumn { 1 } { C } { } } } @@ -6503,7 +6813,7 @@ version 2005/12/01 or later. % % \medskip % \begin{macrocode} -\cs_new_protected:Npn \@@_Hdotsfor:nnn #1 #2 #3 +\cs_new_protected:Npn \@@_Hdotsfor:nnnn #1 #2 #3 #4 { \bool_set_false:N \l_@@_initial_open_bool \bool_set_false:N \l_@@_final_open_bool @@ -6511,7 +6821,7 @@ version 2005/12/01 or later. % For the row, it's easy. % \begin{macrocode} \int_set:Nn \l_@@_initial_i_int { #1 } - \int_set:Nn \l_@@_final_i_int { #1 } + \int_set_eq:NN \l_@@_final_i_int \l_@@_initial_i_int % \end{macrocode} % For the column, it's a bit more complicated. % \begin{macrocode} @@ -6521,8 +6831,12 @@ version 2005/12/01 or later. \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 + \cs_if_exist:cTF + { + pgf @ sh @ ns @ \@@_env: + - \int_use:N \l_@@_initial_i_int + - \int_eval:n { #2 - 1 } + } { \int_set:Nn \l_@@_initial_j_int { #2 - 1 } } { \int_set:Nn \l_@@_initial_j_int { #2 } @@ -6535,29 +6849,31 @@ version 2005/12/01 or later. \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 + \cs_if_exist:cTF + { + pgf @ sh @ ns @ \@@_env: + - \int_use:N \l_@@_final_i_int + - \int_eval:n { #2 + #3 } + } { \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_medium_nodes: % \end{macrocode} % -% \medskip -% The command |\@@_adjust_with_col_nodes:| is used in the command -% |\@@_actually_draw_Ldots:| in order to recompute the $x$-value of -% the initial point and the $x$-value of the final point with the exact position -% of the left side and the right side of the array (these informations are in -% the |col|-node. However, we don't want this operation with the dotted lines -% drawn by |\Hdotsfor|. That's why we deactivate locally this command. % \begin{macrocode} \group_begin: - \cs_set:Npn \@@_adjust_with_col_nodes: { } - \@@_actually_draw_Ldots: + \int_compare:nNnTF { #1 } = 0 + { \color { nicematrix-first-row } } + { + \int_compare:nNnT { #1 } = \g_@@_row_total_int + { \color { nicematrix-last-row } } + } + \keys_set:nn { NiceMatrix / xdots } { #4 } + \tl_if_empty:VF \l_@@_xdots_color_tl { \color { \l_@@_xdots_color_tl } } + \@@_actually_draw_Ldots: \group_end: % \end{macrocode} % @@ -6587,7 +6903,27 @@ version 2005/12/01 or later. \cs_new_protected:Npn \@@_rotate: { \group_insert_after:N \@@_rotate_i: } \cs_new_protected:Npn \@@_rotate_i: { \group_insert_after:N \@@_rotate_ii: } \cs_new_protected:Npn \@@_rotate_ii: { \group_insert_after:N \@@_rotate_iii: } -\cs_new_protected:Npn \@@_rotate_iii: { \box_rotate:Nn \l_@@_cell_box { 90 } } +\cs_new_protected:Npn \@@_rotate_iii: + { + \box_rotate:Nn \l_@@_cell_box { 90 } +% \end{macrocode} +% If we are in the last row, we want all the boxes composed with the command +% |\rotate| aligned upwards. +% \begin{macrocode} + \int_compare:nNnT \c@iRow = \l_@@_last_row_int + { + \vbox_set_top:Nn \l_@@_cell_box + { + \vbox_to_zero:n { } +% \end{macrocode} +% |0.8 ex| will be the distance between the principal part of the array and our +% element (which is composed with |\rotate|. +% \begin{macrocode} + \skip_vertical:n { - \box_ht:N \@arstrutbox + 0.8 ex } + \box_use:N \l_@@_cell_box + } + } + } % \end{macrocode} % % \bigskip @@ -6614,54 +6950,78 @@ version 2005/12/01 or later. % construction uses the fact the |\@@_line_i:nn| is protected and that % |\@@_double_int_eval:n| is fully expandable). % \begin{macrocode} -\cs_new_protected:Npn \@@_line:nn #1 #2 +\NewDocumentCommand \@@_line { O { } m m ! O { } } { - \use:x - { - \@@_line_i:nn - { \@@_double_int_eval:n #1 \q_stop } - { \@@_double_int_eval:n #2 \q_stop } - } + \group_begin: + \keys_set:nn { NiceMatrix / xdots } { #1 , #4 } + \tl_if_empty:VF \l_@@_xdots_color_tl { \color { \l_@@_xdots_color_tl } } + \use:x + { + \@@_line_i:nn + { \@@_double_int_eval:n #2 \q_stop } + { \@@_double_int_eval:n #3 \q_stop } + } + \group_end: } % \end{macrocode} % % \begin{macrocode} -\cs_new_protected:Npn \@@_line_i:nn #1 #2 +\bool_if:NTF \c_@@_draft_bool + { \cs_new_protected:Npn \@@_line_i:nn #1 #2 { } } { - \bool_if:NF \c_@@_draft_bool + \cs_new_protected:Npn \@@_line_i:nn #1 #2 { - \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 \bool_set_false:N \l_@@_initial_open_bool \bool_set_false:N \l_@@_final_open_bool \bool_if:nTF { - \cs_if_exist_p:c { pgf@sh@ns@nm - \int_use:N \g_@@_env_int - #1 } - && - \cs_if_exist_p:c { pgf@sh@ns@nm - \int_use:N \g_@@_env_int - #2 } - } - { - \begin { tikzpicture } - \path~(#1)~--~(#2)~node[at~start]~(i)~{}~node[at~end]~(f)~{} ; - \@@_extract_coords:w ( i ) - \dim_gset:Nn \g_@@_x_initial_dim \pgf@x - \dim_gset:Nn \g_@@_y_initial_dim \pgf@y - \@@_extract_coords:w ( f ) - \dim_gset:Nn \g_@@_x_final_dim \pgf@x - \dim_gset:Nn \g_@@_y_final_dim \pgf@y - \end { tikzpicture } - \@@_draw_tikz_line: + \cs_if_free_p:c { pgf @ sh @ ns @ \@@_env: - #1 } + || + \cs_if_free_p:c { pgf @ sh @ ns @ \@@_env: - #2 } } { - \@@_error:nnn { unknown~cell~for~line~in~code-after } - { #1 } { #2 } - } + \@@_error:nnn { unknown~cell~for~line~in~code-after } { #1 } { #2 } + } + { \@@_draw_line_ii:nn { #1 } { #2 } } + } + } +% \end{macrocode} +% +% \begin{macrocode} +\AtBeginDocument + { + \cs_new_protected:Npx \@@_draw_line_ii:nn #1 #2 + { +% \end{macrocode} +% We recall that, when externalization is used, |\tikzpicture| and +% |\endtikzpicture| (or |\pgfpicture| and |\endpgfpicture|) must be directly +% ``visible'' and that why we do this static construction of the command +% |\@@_draw_line_ii:|. +% \begin{macrocode} + \c_@@_pgfortikzpicture_tl + \@@_draw_line_iii:nn { #1 } { #2 } + \c_@@_endpgfortikzpicture_tl } } % \end{macrocode} % +% \bigskip +% The following command \emph{must} be protected since it's used in the +% construction of |\@@_draw_line_ii:nn|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_line_iii:nn #1 #2 + { + \pgfrememberpicturepositiononpagetrue + \pgfpointshapeborder { \@@_env: - #1 } { \@@_qpoint: { #2 } } + \dim_set_eq:NN \l_@@_x_initial_dim \pgf@x + \dim_set_eq:NN \l_@@_y_initial_dim \pgf@y + \pgfpointshapeborder { \@@_env: - #2 } { \@@_qpoint: { #1 } } + \dim_set_eq:NN \l_@@_x_final_dim \pgf@x + \dim_set_eq:NN \l_@@_y_final_dim \pgf@y + \@@_draw_line: + } +% \end{macrocode} +% % % The commands |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots|, and |\Iddots| don't use % this command because they have to do other settings (for example, the diagonal @@ -6762,6 +7122,98 @@ version 2005/12/01 or later. % \end{macrocode} % % \bigskip +% The command |\@@_draw_vlines| will be executed when the user uses the option +% |vlines| (which draws all the vlines of the array). +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_vlines: + { + \group_begin: +% \end{macrocode} +% The command |\CT@arc@| is a command of color from \pkg{colortbl}. +% \begin{macrocode} + \bool_if:NT \c_@@_colortbl_loaded_bool \CT@arc@ + \pgfpicture + \pgfrememberpicturepositiononpagetrue + \pgf@relevantforpicturesizefalse + \pgfsetlinewidth \arrayrulewidth +% \end{macrocode} +% First, we compute in |\l_tmpa_dim| the height of the rules we have to draw. +% \begin{macrocode} + \@@_qpoint: {row - 1 } + \dim_set_eq:NN \l_tmpa_dim \pgf@y + \pgfusepathqfill + \@@_qpoint: { row - \@@_succ:N \c@iRow } + \dim_sub:Nn \l_tmpa_dim \pgf@y + \pgfusepathqfill +% \end{macrocode} +% We translate vertically to take into account the potential ``last row''. +% \begin{macrocode} + \dim_zero:N \l_tmpb_dim + \int_compare:nNnT \l_@@_last_row_int > { -1 } + { + \dim_set_eq:NN \l_tmpb_dim \g_@@_dp_last_row_dim + \dim_add:Nn \l_tmpb_dim \g_@@_ht_last_row_dim +% \end{macrocode} +% We adjust the value of |\l_tmpa_dim| by the width of the horizontal rule just +% before the ``last row''. +% \begin{macrocode} + \@@_qpoint: { row - \@@_succ:N\c@iRow } + \dim_add:Nn \l_tmpa_dim \pgf@y + \@@_qpoint: { row - \@@_succ:N \g_@@_row_total_int } + \dim_sub:Nn \l_tmpa_dim \pgf@y + \dim_sub:Nn \l_tmpa_dim \l_tmpb_dim + } +% \end{macrocode} +% +% Now, we can draw the lines with a loop. +% \begin{macrocode} + \int_step_inline:nnn + { \bool_if:NTF \l_@@_NiceArray_bool 1 2 } + { \bool_if:NTF \l_@@_NiceArray_bool { \@@_succ:N \c@jCol } \c@jCol } + { + \pgfpathmoveto + { + \pgfpointadd + { \@@_qpoint: { col - ##1 } } + { + \pgfpoint + { + -0.5 \arrayrulewidth + \int_compare:nNnT { ##1 } = 1 + { + \int_compare:nNnT \l_@@_first_col_int = 1 + { + \arrayrulewidth } + } + } + { \l_tmpb_dim } + } + } + \pgfpathlineto + { + \pgfpointadd + { \@@_qpoint: { col - ##1 } } + { + \pgfpoint + { + -0.5 \arrayrulewidth + \int_compare:nNnT { ##1 } = 1 + { + \int_compare:nNnT \l_@@_first_col_int = 1 + { + \arrayrulewidth } + } + } + { \l_tmpb_dim + \l_tmpa_dim } + } + } + } + \pgfusepathqstroke + \endpgfpicture + \group_end: + } +% \end{macrocode} +% +% +% \bigskip % \subsection*{The commands to draw dotted lines to separate columns and rows} % % These commands don't use the normal nodes, the medium nor the large nodes. @@ -6773,11 +7225,12 @@ version 2005/12/01 or later. % The following command must \emph{not} be protected because it's meant to be % expanded in a |\noalign|. % \begin{macrocode} -\cs_new:Npn \@@_hdottedline: +\bool_if:NTF \c_@@_draft_bool + { \cs_new:Npn \@@_hdottedline: { } } { - \bool_if:NF \c_@@_draft_bool + \cs_new:Npn \@@_hdottedline: { - \noalign{ \skip_vertical:n { 2 \l_@@_radius_dim } } + \noalign { \skip_vertical:N 2\l_@@_radius_dim } \@@_hdottedline_i: } } @@ -6791,9 +7244,9 @@ version 2005/12/01 or later. % \end{macrocode} % We write in the code-after the instruction that will eventually draw the % dotted line. It's not possible to draw this dotted line now because we don't -% known the length of the line (we don't even know the number of columns). +% know the length of the line (we don't even know the number of columns). % \begin{macrocode} - \tl_gput_right:Nx \g_@@_code_after_tl + \tl_gput_right:Nx \g_@@_internal_code_after_tl { \@@_hdottedline:n { \int_use:N \c@iRow } } } % \end{macrocode} @@ -6804,29 +7257,117 @@ version 2005/12/01 or later. % that will actually draw the dotted line. Its argument is the number of the row % \emph{before} which we will draw the row. % \begin{macrocode} -\cs_new_protected:Npn \@@_hdottedline:n #1 +\AtBeginDocument + { +% \end{macrocode} +% We recall that, when externalization is used, |\tikzpicture| and +% |\endtikzpicture| (or |\pgfpicture| and |\endpgfpicture|) must be directly +% ``visible''. +% \begin{macrocode} + \cs_new_protected:Npx \@@_hdottedline:n #1 + { + \bool_set_true:N \exp_not:N \l_@@_initial_open_bool + \bool_set_true:N \exp_not:N \l_@@_final_open_bool + \c_@@_pgfortikzpicture_tl + \@@_hdottedline_i:n { #1 } + \c_@@_endpgfortikzpicture_tl + } + } +% \end{macrocode} +% +% The following command \emph{must} be protected since it is used in the +% construction of |\@@_hdottedline:n|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_hdottedline_i:n #1 { - \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 - \bool_set_true:N \l_@@_initial_open_bool - \bool_set_true:N \l_@@_final_open_bool - \begin { tikzpicture } [ remember~picture ] - \@@_extract_coords:w ( row - #1 ) + \pgfrememberpicturepositiononpagetrue + \@@_qpoint: { row - #1 } % \end{macrocode} % We do a translation par |-\l_@@_radius_dim| because we want the dotted line to % have exactly the same position as a vertical rule drawn by ``"|"'' % (considering the rule having a width equal to the diameter of the dots). % \begin{macrocode} - \dim_gset:Nn \g_@@_y_initial_dim { \pgf@y - \l_@@_radius_dim } - \dim_gset:Nn \g_@@_y_final_dim { \pgf@y - \l_@@_radius_dim } - \@@_extract_coords:w ( col - 1 ) - \dim_gset:Nn \g_@@_x_initial_dim \pgf@x - \@@_extract_coords:w ( col - \int_eval:n { \c@jCol + 1 } ) - \dim_gset:Nn \g_@@_x_final_dim \pgf@x - \end { tikzpicture } - \@@_draw_tikz_line: + \dim_set_eq:NN \l_@@_y_initial_dim \pgf@y + \dim_sub:Nn \l_@@_y_initial_dim \l_@@_radius_dim + \dim_set_eq:NN \l_@@_y_final_dim \l_@@_y_initial_dim +% \end{macrocode} +% +% \medskip +% The dotted line will be extended if the user uses |margin| (or |left-margin| +% and |right-margin|). +% +% \smallskip +% The aim is that, by standard the dotted line fits between square brackets +% (|\hline| doesn't). +% +% \smallskip +% \begin{BVerbatim}[baseline=c,boxwidth=10cm] +% \begin{bNiceMatrix} +% 1 & 2 & 3 & 4 \\ +% \hline +% 1 & 2 & 3 & 4 \\ +% \hdottedline +% 1 & 2 & 3 & 4 \\ +% \end{bNiceMatrix} +% \end{BVerbatim} +% $\begin{bNiceMatrix} +% 1 & 2 & 3 & 4 \\ +% \hline +% 1 & 2 & 3 & 4 \\ +% \hdottedline +% 1 & 2 & 3 & 4 \\ +% \end{bNiceMatrix}$ +% +% \smallskip +% But, if the user uses |margin|, the dotted line extends to have the same width +% as a |\hline|. +% +% \smallskip +% \begin{BVerbatim}[baseline=c,boxwidth=10cm] +% \begin{bNiceMatrix}[margin] +% 1 & 2 & 3 & 4 \\ +% \hline +% 1 & 2 & 3 & 4 \\ +% \hdottedline +% 1 & 2 & 3 & 4 \\ +% \end{bNiceMatrix} +% \end{BVerbatim} +% $\begin{bNiceMatrix}[margin] +% 1 & 2 & 3 & 4 \\ +% \hline +% 1 & 2 & 3 & 4 \\ +% \hdottedline +% 1 & 2 & 3 & 4 \\ +% \end{bNiceMatrix}$ +% +% \medskip +% \begin{macrocode} + \@@_qpoint: { col - 1 } + \dim_set:Nn \l_@@_x_initial_dim + { \pgf@x + \arraycolsep - \l_@@_left_margin_dim } + \@@_qpoint: { col - \@@_succ:N \c@jCol } + \dim_set:Nn \l_@@_x_final_dim + { \pgf@x - \arraycolsep + \l_@@_right_margin_dim } +% \end{macrocode} +% For reasons purely aesthetic, we do an adjustment in the case of a rounded +% bracket. The correction by |0.5 \l_@@_inter_dots_dim| is \emph{ad hoc} for a +% better result. +% \begin{macrocode} + \tl_set:Nn \l_tmpa_tl { ( } + \tl_if_eq:NNF \l_@@_left_delim_tl \l_tmpa_tl + { \dim_gadd:Nn \l_@@_x_initial_dim { 0.5 \l_@@_inter_dots_dim } } + \tl_set:Nn \l_tmpa_tl { ) } + \tl_if_eq:NNF \l_@@_right_delim_tl \l_tmpa_tl + { \dim_gsub:Nn \l_@@_x_final_dim { 0.5 \l_@@_inter_dots_dim } } +% \end{macrocode} +% +% \medskip +% As for now, we have no option to control the style of the lines drawn by +% |\hdottedline| and the specifier ``|:|'' in the preamble. That's why we impose +% the style |standard|. +% \begin{macrocode} + \tl_set_eq:NN \l_@@_xdots_line_style_tl \c_@@_standard_tl + \@@_draw_line: } % \end{macrocode} % @@ -6835,17 +7376,33 @@ version 2005/12/01 or later. % \bigskip % \textbf{Vertical dotted lines}\par\nobreak % +% % \medskip % \begin{macrocode} -\cs_new_protected:Npn \@@_vdottedline:n #1 +\bool_if:nTF \c_@@_draft_bool + { \cs_new_protected:Npn \@@_vdottedline:n #1 { } } { + \cs_new_protected:Npn \@@_vdottedline:n #1 + { + \bool_set_true:N \l_@@_initial_open_bool + \bool_set_true:N \l_@@_final_open_bool % \end{macrocode} -% We should allow the letter ``|:|'' in the first position of the preamble -% but that would need a special programmation. +% We recall that, when externalization is used, |\tikzpicture| and +% |\endtikzpicture| (or |\pgfpicture| and |\endpgfpicture|) must be directly +% ``visible''. % \begin{macrocode} - \int_compare:nNnTF #1 = 0 - { \@@_error:n { Use~of~:~in~first~position } } - { \bool_if:NF \c_@@_draft_bool { \@@_vdottedline_i:n { #1 } } } + \bool_if:NTF \c_@@_tikz_loaded_bool + { + \tikzpicture + \@@_vdottedline_i:n { #1 } + \endtikzpicture + } + { + \pgfpicture + \@@_vdottedline_i:n { #1 } + \endpgfpicture + } + } } % \end{macrocode} % @@ -6853,31 +7410,34 @@ version 2005/12/01 or later. % \begin{macrocode} \cs_new_protected:Npn \@@_vdottedline_i:n #1 { - \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 - \bool_set_true:N \l_@@_initial_open_bool - \bool_set_true:N \l_@@_final_open_bool - \begin { tikzpicture } [ remember~picture ] - \@@_extract_coords:w ( col - \int_eval:n { #1 + 1 } ) +% \end{macrocode} +% The command |\CT@arc@| is a command of color from \pkg{colortbl}. +% \begin{macrocode} + \bool_if:NT \c_@@_colortbl_loaded_bool \CT@arc@ + \pgfrememberpicturepositiononpagetrue + \@@_qpoint: { col - \int_eval:n { #1 + 1 } } % \end{macrocode} % We do a translation par |-\l_@@_radius_dim| because we want the dotted line to % have exactly the same position as a vertical rule drawn by ``"|"'' % (considering the rule having a width equal to the diameter of the dots). % \begin{macrocode} - \dim_gset:Nn \g_@@_x_initial_dim { \pgf@x - \l_@@_radius_dim } - \dim_gset:Nn \g_@@_x_final_dim { \pgf@x - \l_@@_radius_dim } - \@@_extract_coords:w ( row - 1 ) + \dim_set:Nn \l_@@_x_initial_dim { \pgf@x - \l_@@_radius_dim } + \dim_set:Nn \l_@@_x_final_dim { \pgf@x - \l_@@_radius_dim } + \@@_qpoint: { row - 1 } % \end{macrocode} % We arbitrary decrease the height of the dotted line by a quantity equal to % |\l_@@_inter_dots_dim| in order to improve the visual impact. % \begin{macrocode} - \dim_gset:Nn \g_@@_y_initial_dim { \pgf@y - ( \l_@@_inter_dots_dim / 2 ) } - \@@_extract_coords:w ( row - \int_eval:n { \c@iRow + 1 } ) - \dim_gset:Nn \g_@@_y_final_dim { \pgf@y + ( \l_@@_inter_dots_dim / 2 ) } - \end { tikzpicture } - \@@_draw_tikz_line: + \dim_set:Nn \l_@@_y_initial_dim { \pgf@y - 0.5 \l_@@_inter_dots_dim } + \@@_qpoint: { row - \@@_succ:N \c@iRow } + \dim_set:Nn \l_@@_y_final_dim { \pgf@y + 0.5 \l_@@_inter_dots_dim } +% \end{macrocode} +% As for now, we have no option to control the style of the lines drawn by +% |\hdottedline| and the specifier ``|:|'' in the preamble. That's why we impose +% the style |standard|. +% \begin{macrocode} + \tl_set_eq:NN \l_@@_xdots_line_style_tl \c_@@_standard_tl + \@@_draw_line: } % \end{macrocode} % @@ -6918,8 +7478,8 @@ version 2005/12/01 or later. { \cs_if_exist:cT { @@_max_cell_width_ \int_use:N \g_@@_NiceMatrixBlock_int } { - \dim_set:Nx \l_@@_columns_width_dim - { \use:c { @@_max_cell_width _ \int_use:N \g_@@_NiceMatrixBlock_int } } + \exp_args:NNc \dim_set:Nn \l_@@_columns_width_dim + { @@_max_cell_width _ \int_use:N \g_@@_NiceMatrixBlock_int } } } } @@ -6939,7 +7499,11 @@ version 2005/12/01 or later. { \cs_gset:cpn { @@ _ max _ cell _ width _ \int_use:N \g_@@_NiceMatrixBlock_int } - { \dim_use:N \g_@@_max_cell_width_dim } +% \end{macrocode} +% For technical reasons, we have to include the width of an eventual rule on the +% right side of the cells. +% \begin{macrocode} + { \dim_eval:n { \g_@@_max_cell_width_dim + \arrayrulewidth } } } \iow_now:Nn \@mainaux \ExplSyntaxOff } @@ -6957,9 +7521,8 @@ version 2005/12/01 or later. % % \bigskip % We have three macros of creation of nodes: |\@@_create_medium_nodes:|, -% |\@@_create_large_nodes:| and |\@@_create_medium_and_large_nodes:|. They must -% \emph{not} be used in the |code-after| because the |code-after| is executed in -% a scope of |prefix name| of Tikz. +% |\@@_create_large_nodes:| and |\@@_create_medium_and_large_nodes:|. +% % % \bigskip % We have to compute the mathematical coordinates of the ``medium nodes''. These @@ -6969,7 +7532,7 @@ version 2005/12/01 or later. % % \bigskip % The command |\@@_computations_for_medium_nodes:| must be used in a -% |{tikzpicture}|. +% |{pgfpicture}|. % % \medskip % For each row $i$, we compute two dimensions @@ -7019,15 +7582,15 @@ version 2005/12/01 or later. % \begin{macrocode} { \cs_if_exist:cT - { pgf@sh@ns@nm - \int_use:N \g_@@_env_int - \@@_i: - \@@_j: } + { pgf @ sh @ ns @ \@@_env: - \@@_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} { - \@@_extract_coords:w - ( nm - \int_use:N \g_@@_env_int - - \@@_i: - \@@_j: .south~west ) + \pgfpointanchor + { \@@_env: - \@@_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: } @@ -7039,8 +7602,9 @@ version 2005/12/01 or later. % 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} - \@@_extract_coords:w - ( nm - \int_use:N \g_@@_env_int - \@@_i: - \@@_j: .north~east ) + \pgfpointanchor + { \@@_env: - \@@_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: } @@ -7057,25 +7621,22 @@ version 2005/12/01 or later. % % \bigskip % Here is the command |\@@_create_medium_nodes:|. When this command is used, the -% ``medium nodes'' are created. These nodes won't be constructed twice because -% when used once, this command becomes no-op. +% ``medium nodes'' are created. % % \begin{macrocode} \cs_new_protected:Npn \@@_create_medium_nodes: { - \begin { tikzpicture } [ remember~picture , overlay ] + \pgfpicture + \pgfrememberpicturepositiononpagetrue + \pgf@relevantforpicturesizefalse \@@_computations_for_medium_nodes: - \tikzset { name~suffix = -medium } % \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|). +% because this command will also be used for the creation of the ``large nodes''. % \begin{macrocode} + \tl_set:Nn \l_@@_suffix_tl { -medium } \@@_create_nodes: - \end { tikzpicture } - \cs_set_protected:Npn \@@_create_medium_nodes: { } - \cs_set_protected:Npn \@@_create_medium_and_large_nodes: - { \@@_create_large_nodes: } + \endpgfpicture } % \end{macrocode} % @@ -7091,37 +7652,34 @@ version 2005/12/01 or later. % \begin{macrocode} \cs_new_protected:Npn \@@_create_large_nodes: { - \begin { tikzpicture } [ remember~picture , overlay ] + \pgfpicture + \pgfrememberpicturepositiononpagetrue + \pgf@relevantforpicturesizefalse \@@_computations_for_medium_nodes: \@@_computations_for_large_nodes: - \tikzset { name~suffix = -large } + \tl_set:Nn \l_@@_suffix_tl { - large } \@@_create_nodes: - \end { tikzpicture } - \cs_set_protected:Npn \@@_create_large_nodes: { } - \cs_set_protected:Npn \@@_create_medium_and_large_nodes: - { \@@_create_medium_nodes: } + \endpgfpicture } % \end{macrocode} % % \begin{macrocode} \cs_new_protected:Npn \@@_create_medium_and_large_nodes: { - \begin { tikzpicture } [ remember~picture , overlay ] + \pgfpicture + \pgfrememberpicturepositiononpagetrue + \pgf@relevantforpicturesizefalse \@@_computations_for_medium_nodes: % \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|). +% because this command will also be used for the creation of the ``large nodes''. % \begin{macrocode} - \tikzset { name~suffix = -medium } + \tl_set:Nn \l_@@_suffix_tl { - medium } \@@_create_nodes: \@@_computations_for_large_nodes: - \tikzset { name~suffix = -large } - \@@_create_nodes: - \end { tikzpicture } - \cs_set_protected:Npn \@@_create_medium_and_large_nodes: { } - \cs_set_protected:Npn \@@_create_medium_nodes: { } - \cs_set_protected:Npn \@@_create_large_nodes: { } + \tl_set:Nn \l_@@_suffix_tl { - large } + \@@_create_nodes: + \endpgfpicture } % \end{macrocode} % @@ -7169,12 +7727,15 @@ version 2005/12/01 or later. \dim_set_eq:cc { l_@@_column _ \int_eval:n { \@@_j: + 1 } _ min _ dim } { l_@@_column _ \@@_j: _ max _ dim } } +% \end{macrocode} +% Here, we have to use |\dim_sub:cn| because of the number 1 in the name. +% \begin{macrocode} \dim_sub:cn { l_@@_column _ 1 _ min _ dim } \l_@@_left_margin_dim \dim_add:cn - { l_@@_column _ \int_use:N \c@jCol _ max _ dim } - \l_@@_right_margin_dim + { l_@@_column _ \int_use:N \c@jCol _ max _ dim } + \l_@@_right_margin_dim } % \end{macrocode} % @@ -7189,42 +7750,30 @@ version 2005/12/01 or later. % \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. +% +% The function also uses |\l_@@_suffix_tl| (|-medium| or |-large|). % \begin{macrocode} \cs_new_protected:Npn \@@_create_nodes: { \int_step_variable:nnNn \l_@@_first_row_int \g_@@_row_total_int \@@_i: { \int_step_variable:nnNn \l_@@_first_col_int \g_@@_col_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. +% We draw the rectangular node for the cell (|\@@_i|-|\@@_j|). % \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} - \node - [ - node~contents = { } , - fit = ( @@~south~west ) ( @@~north~east ) , - inner~sep = \c_zero_dim , - name = nm - \int_use:N \g_@@_env_int - \@@_i: - \@@_j: , - alias = - \str_if_empty:NF \l_@@_name_str - { \l_@@_name_str - \@@_i: - \@@_j: } - ] - ; + \@@_pgf_rect_node:nnnnn + { \@@_env: - \@@_i: - \@@_j: \l_@@_suffix_tl } + { \dim_use:c { l_@@_column_ \@@_j: _min_dim } } + { \dim_use:c { l_@@_row_ \@@_i: _min_dim } } + { \dim_use:c { l_@@_column_ \@@_j: _max_dim } } + { \dim_use:c { l_@@_row_ \@@_i: _max_dim } } + \str_if_empty:NF \l_@@_name_str + { + \pgfnodealias + { \l_@@_name_str - \@@_i: - \@@_j: \l_@@_suffix_tl } + { \@@_env: - \@@_i: - \@@_j: \l_@@_suffix_tl } + } } } % \end{macrocode} @@ -7258,27 +7807,18 @@ version 2005/12/01 or later. \cs_new_protected:Npn \@@_node_for_multicolumn:nn #1 #2 { \@@_extract_coords_values: #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 } - ) ; - \node - [ - node~contents = { } , - fit = ( @@~south~west ) ( @@~north~east ) , - inner~sep = \c_zero_dim , - name = nm - \int_use:N \g_@@_env_int - \@@_i: - \@@_j: , - alias = - \str_if_empty:NF \l_@@_name_str - { \l_@@_name_str - \@@_i: - \@@_j: } - ] - ; + \@@_pgf_rect_node:nnnnn + { \@@_env: - \@@_i: - \@@_j: \l_@@_suffix_tl } + { \dim_use:c { l_@@_column _ \@@_j: _ min _ dim } } + { \dim_use:c { l_@@_row _ \@@_i: _ min _ dim } } + { \dim_use:c { l_@@_column _ \int_eval:n { \@@_j: +#2-1 } _ max _ dim } } + { \dim_use:c { l_@@_row _ \@@_i: _ max _ dim } } + \str_if_empty:NF \l_@@_name_str + { + \pgfnodealias + { \l_@@_name_str - \@@_i: - \@@_j: \l_@@_suffix_tl } + { \int_use:N \g_@@_env_int - \@@_i: - \@@_j: \l_@@_suffix_tl} + } } % \end{macrocode} % @@ -7322,7 +7862,7 @@ version 2005/12/01 or later. % instructions written by the user in the |code-after| (these instructions may % use the Tikz node of the created block). % \begin{macrocode} - \tl_gput_left:Nx \g_@@_code_after_tl + \tl_gput_left:Nx \g_@@_internal_code_after_tl { \@@_Block_iii:nnnnnn { \int_use:N \c@iRow } @@ -7390,70 +7930,77 @@ version 2005/12/01 or later. % \end{macrocode} % % \medskip -% The construction of the node corresponding to the merged cells. First, we -% construct |\coordinate| corresponding to the upper-left and the lower-right -% corners of the cell. They are called |one| and |two|. +% The construction of the node corresponding to the merged cells. % \begin{macrocode} - \begin { tikzpicture } - \int_set:Nn \l_tmpa_int { #1 } - \int_decr:N \l_tmpa_int - \int_set:Nn \l_tmpb_int { #2 } - \int_decr:N \l_tmpb_int - \@@_extract_coords:w ( row - \int_eval:n { \l_tmpa_int + 1 } ) - \dim_set_eq:NN \l_tmpa_dim \pgf@y - \@@_extract_coords:w ( col - \int_eval:n { \l_tmpb_int + 1 } ) - \dim_set_eq:NN \l_tmpb_dim \pgf@x - \coordinate ( one ) at ( \l_tmpb_dim , \l_tmpa_dim ) ; - \@@_extract_coords:w ( row - \int_eval:n { #3 + 1 } ) + \pgfpicture + \pgfrememberpicturepositiononpagetrue + \pgf@relevantforpicturesizefalse + \@@_qpoint: { row - #1 } \dim_set_eq:NN \l_tmpa_dim \pgf@y - \@@_extract_coords:w ( col - \int_eval:n { #4 + 1 } ) + \@@_qpoint: { col - #2 } \dim_set_eq:NN \l_tmpb_dim \pgf@x - \coordinate ( two ) at ( \l_tmpb_dim , \l_tmpa_dim ) ; + \@@_qpoint: { row - \@@_succ:N #3 } + \dim_set_eq:NN \l_tmpc_dim \pgf@y + \@@_qpoint: { col - \@@_succ:N #4 } + \dim_set_eq:NN \l_tmpd_dim \pgf@x % \end{macrocode} -% +% +% \medskip +% The following code doesn't work for the first vertical rule. You should allow +% the option |white| if and only if the option |vlines| and |hlines| has been used. % \begin{macrocode} \bool_if:NT \l_@@_white_bool { - \fill [ white , line~width = 0 pt] - ( [ yshift = -\arrayrulewidth ] one ) - rectangle - ( [ xshift = -\arrayrulewidth ] two ) ; + \begin { pgfscope } + \pgfsetfillcolor { white } +% \end{macrocode} +% Usually, the vertical rules are \emph{before} the |col|-nodes. But there is an +% exception: if there is no ``first col'', the first vertical rule is after the +% col node.\footnote{That's true for the vertical rules drawn by ``"|"'' due to +% the conception of |{array}| (of \pkg{array}) and we have managed to have the +% same behaviour with |vlines|.} +% +% Since we don't want the white rectangle to erase a part of this +% first rule, we have to do an adjustment in this case. +% \emph{after} the ``col node''. +% \begin{macrocode} + \int_compare:nNnT { #2 } = 1 + { + \int_compare:nNnT \l_@@_first_col_int = 1 + { \dim_add:Nn \l_tmpb_dim \arrayrulewidth } + } + \pgfpathrectanglecorners + { \pgfpoint \l_tmpb_dim { \l_tmpa_dim - \arrayrulewidth } } + { \pgfpoint { \l_tmpd_dim - \arrayrulewidth } \l_tmpc_dim } + \pgfusepathqfill + \end { pgfscope } } % \end{macrocode} % -% Now, we can construct the real node fitting the nodes |one| and |two|. -% We have to insert |\l_@@_tikz_tl| in the list of the options and that's why we -% use |\use:x|. -% \begin{macrocode} - \use:x - { - \exp_not:N \node - [ - fit = ( one ) ( two ) , - inner~sep = 0 pt , - \l_@@_tikz_tl - ] - } -% \end{macrocode} -% The node of the block has a name |(#1-#2-block)| and we will use it internally just -% after to put the label of the block. +% We construct the node for the block with the name |(#1-#2-block)|. +% The function |\@@_pgf_rect_node:nnnnn| takes as arguments the name of the node +% and the four coordinates of two opposite corner points of the rectangle. % \begin{macrocode} - (#1-#2-block) { } ; + \begin { pgfscope } + \exp_args:Nx \pgfset { \l_@@_tikz_tl } + \@@_pgf_rect_node:nnnnn + { \@@_env: - #1 - #2 - block } + \l_tmpb_dim \l_tmpa_dim \l_tmpd_dim \l_tmpc_dim + \end { pgfscope } % \end{macrocode} +% % % \medskip % If the creation of the ``medium nodes'' is required, we create a ``medium -% node'' for the block. +% node'' for the block. The function |\@@_pgf_rect_node:nnnnn| takes as +% arguments the name of the node and two \textsc{pgf} points. % \begin{macrocode} \bool_if:NT \l_@@_medium_nodes_bool { - \node - [ - fit = ( #1 - #2 - medium . north~west ) - ( #3 - #4 - medium . south~east ) , - inner~sep = 0 pt , - ] - (#1-#2-block-medium) { } ; + \@@_pgf_rect_node:nnn + { \@@_env: - #1 - #2 - block - medium } + { \pgfpointanchor { \@@_env: - #1 - #2 - medium } { north~west } } + { \pgfpointanchor { \@@_env: - #3 - #4 - medium } { south~east } } } % \end{macrocode} % \medskip @@ -7464,20 +8011,20 @@ version 2005/12/01 or later. % \end{macrocode} % If the block has only one row, we want the label of the block perfectly % aligned on the baseline of the row. That's why we have constructed a -% |\coordinate| on the baseline of the row, in the first column of the array. +% |\pgfcoordinate| on the baseline of the row, in the first column of the array. % Now, we retrieve the $y$-value of that node and we store it in |\l_tmpa_dim|. % \begin{macrocode} - \@@_extract_coords:w (row-#1-base) - \dim_set_eq:NN \l_tmpa_dim \pgf@y + \pgfextracty \l_tmpa_dim { \@@_qpoint: { row - #1 - base } } % \end{macrocode} % We retrieve (in |\pgf@x|) the $x$-value of the center of the block. % \begin{macrocode} - \@@_extract_coords:w (#1-#2-block) + \@@_qpoint: { #1 - #2 - block } % \end{macrocode} % We put the label of the block which has been composed in |\l_@@_cell_box|. % \begin{macrocode} - \path (\pgf@x,\l_tmpa_dim) node [ anchor = base ] - { \box_use_drop:N \l_@@_cell_box } ; + \pgftransformshift { \pgfpoint \pgf@x \l_tmpa_dim } + \pgfnode { rectangle } { base } + { \box_use_drop:N \l_@@_cell_box } { } { } } % \end{macrocode} % @@ -7486,8 +8033,12 @@ version 2005/12/01 or later. % the center of the node (the label of the block has been composed in % |\l_@@_cell_box|). % \begin{macrocode} - { \node at (#1-#2-block.center) { \box_use_drop:N \l_@@_cell_box } ; } - \end { tikzpicture } + { + \pgftransformshift { \@@_qpoint: { #1 - #2 - block } } + \pgfnode { rectangle } { center } + { \box_use_drop:N \l_@@_cell_box } { } { } + } + \endpgfpicture } \group_end: } @@ -7607,7 +8158,12 @@ version 2005/12/01 or later. transparent .meta:n = { renew-dots , renew-matrix } , transparent .value_forbidden:n = true, obsolete-environments .code:n = - \@@_msg_redirect_name:nn { Obsolete~environment } { none } + \@@_msg_redirect_name:nn { Obsolete~environment } { none } , + obsolete-environments .value_forbidden:n = true, + starred-commands .code:n = + \@@_msg_redirect_name:nn { starred~commands } { none } , + starred-commands .value_forbidden:n = true , + } \ProcessKeysOptions { NiceMatrix / Package } % \end{macrocode} @@ -7665,43 +8221,87 @@ version 2005/12/01 or later. } % \end{macrocode} % +% The following command must \emph{not} be protected since it's used in an error message. +% \begin{macrocode} +\cs_new:Npn \@@_message_hdotsfor: + { + \tl_if_empty:VF \g_@@_Hdotsfor_lines_tl + { ~Maybe~your~use~of~\token_to_str:N \Hdotsfor\ is~incorrect.} + } +% \end{macrocode} % +% % \begin{macrocode} \@@_msg_new:nn { too~much~cols~for~matrix~with~last~col } { You~try~to~use~more~columns~than~allowed~by~your~ - \@@_full_name_env:.~The~maximal~number~of~columns~is~ - \int_eval:n { \l_@@_last_col_int - 1 }~(plus~the~potential~ + \@@_full_name_env:.\@@_message_hdotsfor:\ The~maximal~number~of~ + columns~is~\int_eval:n { \l_@@_last_col_int - 1 }~(plus~the~potential~ exterior~ones).~This~error~is~fatal. } % \end{macrocode} % -% +% % \begin{macrocode} \@@_msg_new:nn { too~much~cols~for~matrix } { You~try~to~use~more~columns~than~allowed~by~your~ - \@@_full_name_env:.~ Recall~that~the~maximal~number~of~columns~ - for~a~matrix~is~fixed~by~the~LaTeX~counter~'MaxMatrixCols'.~ - Its~actual~value~is~\int_use:N \c@MaxMatrixCols.~This~error~is~fatal. + \@@_full_name_env:.\@@_message_hdotsfor:\ Recall~that~the~maximal~ + number~of~columns~for~a~matrix~is~fixed~by~the~LaTeX~counter~ + 'MaxMatrixCols'.~Its~actual~value~is~\int_use:N \c@MaxMatrixCols.~ + This~error~is~fatal. } % \end{macrocode} % +% \medskip +% For the following message, remind that the test is not done after the +% construction of the array but in each row. That's why we have to put +% |\c@jCol-1| and not |\c@jCol|. % \begin{macrocode} \@@_msg_new:nn { too~much~cols~for~array } { You~try~to~use~more~columns~than~allowed~by~your~ - \@@_full_name_env:.~The~maximal~number~of~columns~is~ - \int_use:N \c@jCol\space (plus~the~potential~exterior~ones).~ + \@@_full_name_env:.\@@_message_hdotsfor:\ The~maximal~number~of~columns~is~ + \int_eval:n { \c@jCol - 1 }~(plus~the~potential~exterior~ones).~ This~error~is~fatal. } % \end{macrocode} % +% +% \begin{macrocode} +\@@_msg_new:nn { bad~option~for~line-style } + { + Since~you~haven't~loaded~Tikz,~the~only~value~you~can~give~to~'line-style'~ + is~'standard'.~If~you~go~on,~this~option~will~be~ignored. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { Unknown~option~for~xdots } + { + As~for~now~there~is~only~three~options~available~here:~'color',~'line-style'~ + and~'shorten'~(and~you~try~to~use~'\l_keys_key_str').~If~you~go~on,~ + this~option~will~be~ignored. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { starred~commands } + { + The~starred~versions~of~\token_to_str:N \Cdots,~\token_to_str:N \Ldots,~ + \token_to_str:N \Vdots,~\token_to_str:N\Ddots\ and~\token_to_str:N\Iddots\ + are~deprecated.~However,~you~can~go~on~for~this~time.~If~you~don't~want~to~ + see~this~error~we~should~load~'nicematrix'~with~the~option~ + 'starred-commands'. + } +% \end{macrocode} +% % \begin{macrocode} \@@_msg_new:nn { bad~value~for~baseline } { - The~value~you~gave~to~'baseline'~(\int_use:N \l_tmpa_int)~is~not~ - valid.\\ + The~value~given~to~'baseline'~(\int_use:N \l_tmpa_int)~is~not~ + valid.~The~value~must~be~between~\int_use:N \l_@@_first_row_int\ and~ + \int_use:N \g_@@_row_total_int\ or~equal~to~'t',~'c'~or~'b'.\\ If~you~go~on,~a~value~of~1~will~be~used. } % \end{macrocode} @@ -7724,7 +8324,7 @@ version 2005/12/01 or later. \@@_msg_new:nn { unknown~cell~for~line~in~code-after } { Your~command~\token_to_str:N\line\{#1\}\{#2\}~in~the~'code-after'~ - can't~be~executed~because~a~Tikz~node~doesn't~exist.\\ + can't~be~executed~because~a~cell~doesn't~exist.\\ If~you~go~on~this~command~will~be~ignored. } % \end{macrocode} @@ -7760,15 +8360,6 @@ version 2005/12/01 or later. % % % \begin{macrocode} -\@@_msg_new:nn { Impossible~line } - { - A~dotted~line~can't~be~drawn~because~you~have~not~put~ - all~the~ampersands~required~on~the~row~#1.\\ - If~you~go~on,~this~dotted~line~will~be~ignored. - } -% \end{macrocode} -% -% \begin{macrocode} \@@_msg_new:nn { Wrong~last~row } { You~have~used~'last-row=\int_use:N \l_@@_last_row_int'~but~your~ @@ -7824,7 +8415,6 @@ version 2005/12/01 or later. create-extra-nodes,~ create-medium-nodes,~ create-large-nodes,~ - dotted-lines-margin,~ end-of-row,~ exterior-arraycolsep,~ hlines,~ @@ -7838,8 +8428,11 @@ version 2005/12/01 or later. renew-matrix,~ right-margin,~ small,~ - transparent~ - and~vlines. + transparent,~ + vlines,~ + xdots/color,~ + xdots/shorten~and~ + xdots/line-style. } % \end{macrocode} % @@ -7865,7 +8458,6 @@ version 2005/12/01 or later. create-extra-nodes,~ create-medium-nodes,~ create-large-nodes,~ - dotted-lines-margin,~ end-of-row,~ extra-left-margin,~ extra-right-margin,~ @@ -7884,7 +8476,10 @@ version 2005/12/01 or later. right-margin,~ small,~ t,~ - and~vlines. + vlines,~ + xdots/color,~ + xdots/shorten~and~ + xdots/line-style. } % \end{macrocode} % @@ -7911,7 +8506,6 @@ version 2005/12/01 or later. create-extra-nodes,~ create-medium-nodes,~ create-large-nodes,~ - dotted-lines-margin,~ end-of-row,~ extra-left-margin,~ extra-right-margin,~ @@ -7919,6 +8513,7 @@ version 2005/12/01 or later. first-row,~ hlines,~ hvlines,~ + l~(=L),~ last-col,~ last-row,~ left-margin,~ @@ -7926,10 +8521,14 @@ version 2005/12/01 or later. name,~ nullify-dots,~ parallelize-diags,~ + r~(=R),~ renew-dots,~ right-margin,~ small,~ - and~vlines. + vlines,~ + xdots/color,~ + xdots/shorten~and~ + xdots/line-style. } % \end{macrocode} % @@ -7967,14 +8566,6 @@ version 2005/12/01 or later. } % \end{macrocode} % -% \begin{macrocode} -\@@_msg_new:nn { Use~of~:~in~first~position } - { - You~can't~use~the~column~specifier~'\l_@@_letter_for_dotted_lines_str'~in~the~ - first~position~of~the~preamble~of~the~\@@_full_name_env:. \\ - If~you~go~on,~this~dotted~line~will~be~ignored. - } -% \end{macrocode} % % \bigskip % \subsection*{Obsolete environments} @@ -8122,6 +8713,75 @@ version 2005/12/01 or later. { \endNiceArrayWithDelims } % \end{macrocode} % +% +% \subsection*{Command for creation of rectangle nodes} +% +% +% The following command should be used in a |{pgfpicture}|. It creates an +% rectangular (empty but with a name) when the four corners are given. +% +% |#1| is the name of the node which will be created; +% |#2| and |#3| are the coordinates of one of the corner of the rectangle; +% |#4| and |#5| are the coordinates of the opposite corner. +% \begin{macrocode} +\cs_new_protected:Npn \@@_pgf_rect_node:nnnnn #1 #2 #3 #4 #5 + { + \begin { pgfscope } + \pgfset + { + outer~sep = \c_zero_dim , + inner~sep = \c_zero_dim , + minimum~size = \c_zero_dim + } + \pgftransformshift { \pgfpoint { 0.5 * ( #2 + #4 ) } { 0.5 * ( #3 + #5 ) } } + \pgfnode + { rectangle } + { center } + { + \vbox_to_ht:nn + { \dim_abs:n { #5 - #3 } } + { + \vfill + \hbox_to_wd:nn { \dim_abs:n { #4 - #2 } } { } + } + } + { #1 } + { } + \end { pgfscope } + } +% \end{macrocode} +% +% \medskip +% The command |\@@_pgf_rect_node:nnn| is a variant of |\@@_pgr_rect_node:nnnn|: +% it takes two \textsc{pgf} points as arguments instead of the four dimensions +% which are the coordinates. +% \begin{macrocode} +\cs_new_protected:Npn \@@_pgf_rect_node:nnn #1 #2 #3 + { + \begin { pgfscope } + \pgfset + { + outer~sep = \c_zero_dim , + inner~sep = \c_zero_dim , + minimum~size = \c_zero_dim + } + \pgftransformshift { \pgfpointscale { 0.5 } { \pgfpointadd { #2 } { #3 } } } + \pgfpointdiff { #3 } { #2 } + \pgfgetlastxy \l_tmpa_dim \l_tmpb_dim + \pgfnode + { rectangle } + { center } + { + \vbox_to_ht:nn + { \dim_abs:n { \l_tmpb_dim } } + { \vfill \hbox_to_wd:nn { \dim_abs:n { \l_tmpa_dim } } { } } + } + { #1 } + { } + \end { pgfscope } + } +% \end{macrocode} +% % % \vspace{1cm} % \section{History} @@ -8201,7 +8861,7 @@ version 2005/12/01 or later. % \[\begin{pNiceArray}{Wc{5mm}CWc{5mm}}[first-row,last-col] % & C_j & \\ % \mbox{\Large $0$} & \Vdots & \mbox{\Large $0$} \\ -% & \strut a & \Cdots & L_i \\ +% \strut & a & \Cdots & L_i \\ % \mbox{\Large $0$} & & \mbox{\Large $0$} \\ % \end{pNiceArray}\] % @@ -8263,18 +8923,18 @@ version 2005/12/01 or later. % Error message when the user gives an incorrect value for |last-row|. % % A dotted line can no longer cross another dotted line (excepted the dotted -% lines drawn by |\cdottedline|, the symbol |:| (in the preamble of the array) and -% |\line| in |code-after|). +% lines drawn by |\cdottedline|, the symbol ``|:|'' (in the preamble of the +% array) and |\line| in |code-after|). % % The starred versions of |\Cdots|, |\Ldots|, etc. are now deprecated because, % with the new implementation, they become pointless. These starred versions % are no longer documented. % -% The vertical rules in the matrices (drawn by "|") are now compatible with +% The vertical rules in the matrices (drawn by ``"|"'') are now compatible with % the color fixed by \pkg{colortbl}. % -% Correction of a bug: it was not possible to use the colon |:| in the preamble -% of an array when |pdflatex| was used with \pkg{french-babel} (because +% Correction of a bug: it was not possible to use the colon ``|:|'' in the +% preamble of an array when |pdflatex| was used with \pkg{french-babel} (because % \pkg{french-babel} activates the colon in the beginning of the document). % % @@ -8366,7 +9026,7 @@ version 2005/12/01 or later. % % Options |vlines|, |hlines| and |hvlines|. % -% Option |baseline| pour |{NiceArray}| (uniquement). +% Option |baseline| pour |{NiceArray}| (not for the other environments). % % The name of the Tikz nodes created by the command |\Block| has changed: when % the command has been issued in the cell $i$|-|$j$, the name is @@ -8379,6 +9039,27 @@ version 2005/12/01 or later. % The package must be loaded with the option |obsolete-environments| if we want % to use the deprecated environments. % +% \subsection*{Changes between versions 3.12 and 3.13} +% +% The behaviour of the command |\rotate| is improved when used in the ``last +% row''. +% +% The option |dotted-lines-margin| has been renamed in |xdots/shorten| and the +% options |xdots/color| and |xdots/line-style| have been added for a complete +% customization of the dotted lines. +% +% In the environments without preamble (|{NiceMatrix}|, |{pNiceMatrix}|, etc.), +% it's possible to use the options |l| (=|L|) or |r| (=|R|) to specify the type +% of the columns. +% +% The starred versions of the commands |\Cdots|, |\Ldots|, |\Vdots|, |\Ddots| +% and |\Iddots| are deprecated since the version 3.1 of \pkg{nicematrix}. Now, +% one should load \pkg{nicematrix} with the option |starred-commands| to avoid +% an error at the compilation. +% +% The code of \pkg{nicematrix} no longer uses Tikz but only \textsc{pgf}. By +% default, Tikz is \emph{not} loaded by \pkg{nicematrix}. +% % \PrintIndex % % \tableofcontents |