From 4736ac744a8c914e0d5ced1d157e017a385bbf43 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Sat, 29 Feb 2020 03:02:30 +0000 Subject: CTAN sync 202002290302 --- macros/latex/contrib/nicematrix/nicematrix.dtx | 2530 +++++++++++++++--------- 1 file changed, 1573 insertions(+), 957 deletions(-) (limited to 'macros/latex/contrib/nicematrix/nicematrix.dtx') diff --git a/macros/latex/contrib/nicematrix/nicematrix.dtx b/macros/latex/contrib/nicematrix/nicematrix.dtx index 2752f0dd6f..9e446e9d48 100644 --- a/macros/latex/contrib/nicematrix/nicematrix.dtx +++ b/macros/latex/contrib/nicematrix/nicematrix.dtx @@ -15,8 +15,8 @@ % % \fi % \iffalse -\def\myfileversion{3.11} -\def\myfiledate{2020/02/07} +\def\myfileversion{3.12} +\def\myfiledate{2020/02/28} % % %<*batchfile> @@ -55,16 +55,6 @@ version 2005/12/01 or later. \usepackage{nicematrix} \usepackage{siunitx} -\newbox\ExampleOne - -\setbox\ExampleOne\hbox{$\begin{NiceArray}{|*{4}{C|}}[hlines,first-row,first-col] - & e & a & b & c \\ -e & e & a & b & c \\ -a & a & e & c & b \\ -b & b & c & e & a \\ -c & c & b & a & e -\end{NiceArray}$} - \NewDocumentEnvironment {scope} {} {} {} \def\interitem{\vspace{7mm plus 2 mm minus 3mm}} @@ -118,7 +108,7 @@ c & c & b & a & e % 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}|. +% final user only has to load the extension with |\usepackage{nicematrix}|. % % % \medskip @@ -240,10 +230,10 @@ c & c & b & a & e % defined: |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots|, and |\Iddots|. These commands % are intended to be used in place of |\dots|, |\cdots|, |\vdots|, |\ddots| and % |\iddots|.\footnote{The command |\iddots|, defined in \pkg{nicematrix}, is a -% variant of |\ddots| with dots going forward: \smash{$\iddots$}. If |mathdots| -% is loaded, the version of |mathdots| is used. It corresponds to the command -% |\adots| of \pkg{unicode-math}.} -% \newcounter{fniddots} +% variant of |\ddots| with dots going forward. If |mathdots| is loaded, the +% version of |mathdots| is used. It corresponds to the command |\adots| of +% \pkg{unicode-math}.} +% \newcounter{fniddots} % \setcounter{fniddots}{\thefootnote} % % \smallskip @@ -590,7 +580,7 @@ c & c & b & a & e % % 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 dependant of the current font). For an example, +% recommended to use a unit dependent of the current font). For an example, % cf.~p.~\pageref{permutation}. % % @@ -834,13 +824,109 @@ c & c & b & a & e % the letters |L|, |C|, |R|.} % % \medskip -% The environment |{NiceArray}| accepts the classical options |t|, |c| and |b| -% of |{array}| but also other options defined by \pkg{nicematrix} (|renew-dots|, -% |columns-width|, etc.). +% The environment |{NiceArray}| accepts the options available for +% |{pNiceMatrix}| and its variants but also a option |baseline| whose value is +% an integer which indicates the number of the row whose baseline is used +% as baseline for the environment |{NiceArray}|. +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=11cm] +% $A = +% \begin{NiceArray}{CCCC}[hvlines,~emphase#baseline=2@] +% 1 & 2 & 3 & 4 \\ +% 1 & 2 & 3 & 4 \\ +% 1 & 2 & 3 & 4 \\ +% \end{NiceArray}$ +% \end{BVerbatim} +% $A = +% \begin{NiceArray}{CCCC}[hvlines,baseline=2] +% 1 & 2 & 3 & 4 \\ +% 1 & 2 & 3 & 4 \\ +% 1 & 2 & 3 & 4 \\ +% \end{NiceArray}$ +% +% \small +% (The option |hvlines| is presented further: cf. p. \pageref{hvlines}.) +% +% \medskip +% It's also possible to use the option |baseline| with one of the special values +% |t|, |c| or |b|. These letters may also be used absolutely like the option of +% the environment |{array}| of \pkg{array}. The initial value of |baseline| is~|c|. +% +% +% \medskip +% In the following example, we use the option |t| (equivalent to |baseline=t|) +% immediately after an |\item| of list. One should remark that the presence of +% a |\hline| at the beginning of the array doesn't prevent the alignment of the +% baseline with the baseline of the first row (with |{array}| of \pkg{array}, +% one must use |\firsthline|\footnote{It's also possible to use |\firsthline| +% with |{NiceArray}|.}). +% +% \smallskip +% \begin{BVerbatim}[baseline=c,boxwidth=9cm] +% \begin{enumerate} +% \item an item +% \smallskip +% \item \renewcommand{\arraystretch}{1.2} +% $\begin{NiceArray}~emphase#[t]@{LCCCCCC} +% \hline +% n & 0 & 1 & 2 & 3 & 4 & 5 \\ +% u_n & 1 & 2 & 4 & 8 & 16 & 32 +% \hline +% \end{NiceArray}$ +% \end{enumerate} +% \end{BVerbatim} +% \begin{minipage}{5cm} +% \begin{enumerate} +% \item an item +% \smallskip +% \item \renewcommand{\arraystretch}{1.2} +% $\begin{NiceArray}[t]{LCCCCCC} +% \hline +% n & 0 & 1 & 2 & 3 & 4 & 5 \\ +% u_n & 1 & 2 & 4 & 8 & 16 & 32 \\ +% \hline +% \end{NiceArray}$ +% \end{enumerate} +% \end{minipage} +% +% \medskip +% However, it's also possible to use the tools of \pkg{booktabs}: |\toprule|, +% |\bottomrule| and |\midrule|.\par\nobreak % +% \smallskip +% \begin{BVerbatim}[baseline=c,boxwidth=9cm] +% \begin{enumerate} +% \item an item +% \smallskip +% \item +% $\begin{NiceArray}[t]{LCCCCCC} +% ~emphase#\toprule@ +% n & 0 & 1 & 2 & 3 & 4 & 5 \\ +% ~emphase#\midrule@ +% u_n & 1 & 2 & 4 & 8 & 16 & 32 +% ~emphase#\bottomrule@ +% \end{NiceArray}$ +% \end{enumerate} +% \end{BVerbatim} +% \begin{minipage}{5cm} +% \begin{enumerate} +% \item an item +% \smallskip +% \item +% $\begin{NiceArray}[t]{LCCCCCC} +% \toprule +% n & 0 & 1 & 2 & 3 & 4 & 5 \\ +% \midrule +% u_n & 1 & 2 & 4 & 8 & 16 & 32 \\ +% \bottomrule +% \end{NiceArray}$ +% \end{enumerate} +% \end{minipage} +% % % \vspace{1cm} -% An example with a linear system (we need |{NiceArray}| for the vertical rule): +% With |{NiceArray}|, it's possible to draw vertical rules:\par\nobreak % % \bigskip % \begin{BVerbatim}[baseline=c,boxwidth=10cm] @@ -861,7 +947,7 @@ c & c & b & a & e % \bigskip % In fact, there is also variants for the environment |{NiceArray}|: % |{pNiceArray}|, |{bNiceArray}|, |{BNiceArray}|, |{vNiceArray}| and -% |{VNiceArray}|. +% |{VNiceArray}|. The key |baseline| is not available for these environments. % % In the following example, we use an environment |{pNiceArray}| (we don't use % |{pNiceMatrix}| because we want to use the types |L| and |R| @@ -889,19 +975,19 @@ c & c & b & a & e % more general environment, called |{NiceArrayWithDelims}|. The first two % mandatory arguments of this environment are the left and right delimiters used % in the construction of the matrix. It's possible to use -% |{NiceArrayWithDelims}| if we want to use atypical delimiters. +% |{NiceArrayWithDelims}| if we want to use atypical or asymetrical delimiters. % % \medskip % \begin{BVerbatim}[baseline=c,boxwidth=11cm] % $\begin{~emphase#NiceArrayWithDelims@} -% {\downarrow}{\downarrow}{CCC} +% {\downarrow}{\uparrow}{CCC}[margin] % 1 & 2 & 3 \\ % 4 & 5 & 6 \\ % 7 & 8 & 9 \\ % \end{~emphase#NiceArrayWithDelims@}$ % \end{BVerbatim} % $\begin{NiceArrayWithDelims} -% {\downarrow}{\downarrow}{CCC} +% {\downarrow}{\uparrow}{CCC}[margin] % 1 & 2 & 3 \\ % 4 & 5 & 6 \\ % 7 & 8 & 9 \\ @@ -944,9 +1030,8 @@ c & c & b & a & e % \begin{itemize} % \item For the environments with an explicit preamble (i.e. |{NiceArray}| and % its variants), no letter must be given in that preamble for the potential -% first column and the potential last column: the first column will be -% automatically (and necessarily) of type |R| and the last column will be -% automatically of % type |L|. +% first column and the potential last column: they will automatically (and +% necessarily) be of type |R| for the first column and |L| for the last one. % \item In an environment with an explicit preamble, the option |last-col| must % be used \emph{without} value: the number of columns will be automatically % computed from the preamble of the array. @@ -1104,7 +1189,7 @@ c & c & b & a & e % It's possible to change in \pkg{nicematrix} the letter used to specify a % vertical dotted line with the option |letter-for-dotted-lines| available in % |\NiceMatrixOptions|. For example, in this document, we have loaded the -% extension \pkg{arydshln} which uses the letter ``:'' to specify a vertical +% extension \pkg{arydshln} which uses the letter ``|:|'' to specify a vertical % dashed line. Thus, by using |letter-for-dotted-lines|, we can use the % vertical lines of both \pkg{arydshln} and \pkg{nicematrix}. % @@ -1126,6 +1211,16 @@ c & c & b & a & e % \end{NiceArray}\right)$ % \end{scope} % +% \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 +% likewise. +% +% +% % \section{The width of the columns} % \label{width} % @@ -1225,9 +1320,11 @@ c & c & b & a & e % But it's also possible to fix a zone where all the matrices will have their % columns of the same width, equal to the widest cell of all the matrices. This % construction uses the environment |{NiceMatrixBlock}| with the option -% |auto-columns-width|.\footnote{At this time, this is the only usage of the -% environment |{NiceMatrixBlock}| but it may have other usages in the future.} -% +% |auto-columns-width|\footnote{At this time, this is the only usage of the +% environment |{NiceMatrixBlock}| but it may have other usages in the future.}. +% The environment |{NiceMatrixBlock}| has no direct link with the command +% |\Block| presented just below (cf.~p.~\pageref{Block}). +% % \medskip % \begin{BVerbatim}[baseline=c,boxwidth=8.5cm] % ~emphase#\begin{NiceMatrixBlock}[auto-columns-width]@ @@ -1255,6 +1352,7 @@ c & c & b & a & e % % % \section{Block matrices} +% \label{Block} % % This section has no direct link with the previous one where an environment % |{NiceMatrixBlock}| was introduced. @@ -1268,8 +1366,13 @@ c & c & b & a & e % $i$\verb|-|$j$ where $i$ is the number of rows of the block and $j$ its number % of columns. The second argument is the content of the block (composed in math % mode). A Tikz node corresponding to the merged cells is created with the name -% ``\textsl{name}-$i$-$j$'' where \textsl{name} is the name given to the array. +% ``$i$-$j$-block''. If the user has required the creation of the ``medium +% nodes'', a node of this type is also created with a name suffixed by +% |-medium|. % +% \medskip +% In the following examples, we use the command |\arrayrulecolor| of +% \pkg{colortbl}. % % \medskip % \begin{BVerbatim}[baseline=c,boxwidth=10.6cm] @@ -1300,7 +1403,7 @@ c & c & b & a & e % previous example. Since this element is composed in math mode, it's not % possible to use directly a command like |\large|, |\Large| and |\LARGE|. % That's why the command |\Block| provides an option between angle brackets to -% specificy some TeX code which will be inserted before the beginning of the +% specify some TeX code which will be inserted before the beginning of the % math mode. % % \medskip @@ -1334,6 +1437,41 @@ c & c & b & a & e % % \section{Advanced features} % +% \subsection{The command \textbackslash rotate} +% +% The package \pkg{nicematrix} provides a command |\rotate|. When used in the +% beginning of a cell, this command composes the contents of the cell after a +% rotation of 90° in the direct sens. +% +% In the following command, we use that command in the |code-for-first-row|. +% +%\bigskip +% +% \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] +% 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} +% \NiceMatrixOptions% +% {code-for-first-row = \scriptstyle\rotate \text{image of }, +% code-for-last-col = \scriptstyle } +% \begin{minipage}{3cm} +% $\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{minipage} +% \end{scope} +% % \subsection{The option small} % % With the option |small|, the environments of the extension \pkg{nicematrix} @@ -1383,8 +1521,8 @@ c & c & b & a & e % % 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 col\footnote{We recall that the first row (if it exists) has the -% number~$0$ and that the first col (if it exists) has also the number~$0$.}. +% 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}. % @@ -1436,27 +1574,90 @@ c & c & b & a & e % % $C = \pAutoNiceMatrix{3-3}{C_{\arabic{iRow},\arabic{jCol}}}$ % -% \subsection{The option hlines} +% \subsection{The options hlines, vlines and hvlines} % +% \label{hvlines} % You can add horizontal rules between rows in the environments of -% \pkg{nicematrix} with the usual command |\hline|. But, by convenience, the -% extension \pkg{nicematrix} also provides the option |hlines|. With this -% option, all the horizontal rules will be drawn (excepted, of course, the rule -% before the potential ``first row'' and the rule after the potential ``last -% row''). +% \pkg{nicematrix} with the usual command |\hline| and you can use the specifier +% ``"|"'' to add vertical rules. However, by convenience, the extension +% \pkg{nicematrix} also provides the option |hlines| (resp. |vlines|) which will +% draw all the horizontal (resp. vertical) rules (excepted, of course, the +% exterior rules corresponding to the exterior rows and columns). The key +% |hvlines| is an alias for the conjonction for the keys |hlines| et |vlines|. +% +% % \medskip +% In the following example, we use the command |\arrayrulecolor| of +% \pkg{colortbl}. % % \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=10.6cm] -% $\begin{NiceArray}{|*{4}{C|}}[~emphase#hlines@,first-row,first-col] +% \begin{BVerbatim}[baseline=c,boxwidth=11cm] +% \arrayrulecolor{cyan} +% $\begin{NiceArray}{CCCC}% +% [~emphase#hvlines@,first-row,first-col] +% % & e & a & b & c \\ +% e & e & a & b & c \\ +% a & a & e & c & b \\ +% b & b & c & e & a \\ +% c & c & b & a & e +% \end{NiceArray}$ +% \arrayrulecolor{black} +% \end{BVerbatim} +% \arrayrulecolor{cyan} +% $\begin{NiceArray}{CCCC}[hvlines,first-row,first-col] % & e & a & b & c \\ % e & e & a & b & c \\ % a & a & e & c & b \\ % b & b & c & e & a \\ % c & c & b & a & e % \end{NiceArray}$ +% \arrayrulecolor{black} +% +% \bigskip +% However, there is a difference between the key |vlines| and the use of +% the specifier ``"|"'' in the preamble of the environment: the rules drawn by +% |vlines| completely cross the double-rules drawn by |\hline\hline|. +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=11.5cm] +% $\begin{NiceArray}{CCCC}[vlines] \hline +% a & b & c & d \\ \hline \hline +% 1 & 2 & 3 & 4 \\ +% 1 & 2 & 3 & 4 \\ \hline +% \end{NiceArray}$ % \end{BVerbatim} -% \raise-5mm\box\ExampleOne -% +% $\begin{NiceArray}{CCCC}[vlines] +% \hline +% a & b & c & d \\ +% \hline \hline +% 1 & 2 & 3 & 4 \\ +% 1 & 2 & 3 & 4 \\ +% \hline +% \end{NiceArray}$ +% +% \bigskip +% For the environments with delimiters (for example |{pNiceArray}| or +% |{pNiceMatrix}|), the option |vlines| don't draw vertical rules on both sides, +% where are the delimiters (fortunately). +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=10.6cm] +% \setlength{\arrayrulewidth}{0.2pt} +% $\begin{pNiceMatrix}[vlines] +% 1 & 2 & 3 & 4 & 5 & 6 \\ +% 1 & 2 & 3 & 4 & 5 & 6 \\ +% 1 & 2 & 3 & 4 & 5 & 6 \\ +% \end{pNiceMatrix}$ +% \end{BVerbatim} +% \begin{scope} +% \setlength{\arrayrulewidth}{0.2pt} +% $\begin{pNiceMatrix}[vlines] +% 1 & 2 & 3 & 4 & 5 & 6 \\ +% 1 & 2 & 3 & 4 & 5 & 6 \\ +% 1 & 2 & 3 & 4 & 5 & 6 \\ +% \end{pNiceMatrix}$ +% \end{scope} +% +% % \subsection{The option light-syntax} % % The option |light-syntax|\footnote{This option is inspired by the extension @@ -1494,7 +1695,7 @@ c & c & b & a & e % It's possible to change the character used to mark the end of rows with the % option |end-of-row|. As said before, the initial value is a semicolon. % -% \subsection{Utilisation of the column type S of siunitx} +% \subsection{Use of the column type S of siunitx} % % If the package \pkg{siunitx} is loaded (before or after \pkg{nicematrix}), % it's possible to use the |S| column type of \pkg{siunitx} in the environments @@ -1538,7 +1739,8 @@ c & c & b & a & e % not in an eventual exterior row. % % For example, one may wish to define a new column type |?| in order to draw a -% thick rule of width 1~pt. The following definition will do the job: +% (black) thick 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}}} @@ -1859,11 +2061,10 @@ c & c & b & a & e % |{VNiceArrayRC}|. % \end{itemize} % -% Since the version 3.8, an error is raised when one of these environments is -% used. It's still possible to use these environments by loading +% Since the version 3.12, the only way to use these environments is loading % \pkg{nicematrix} with the option |obsolete-environments|. % -% However, these environments will probably be completely deleted in a future +% However, these environments will certainly be completely deleted in a future % version of \pkg{nicematrix}. % % \section{Examples} @@ -2185,6 +2386,14 @@ c & c & b & a & e % a_{41} & a_{42} & a_{43} & a_{44} % \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.} +% % % \vspace{1cm} % The package \pkg{nicematrix} is constructed upon the environment |{array}| @@ -2249,25 +2458,35 @@ c & c & b & a & e % |\ExplSyntaxOff| % \end{scope} % -% \vspace{1cm} +% \vspace{1cm} % We recall that, for a rectangle of merged cells (with the command |\Block|), a -% Tikz node is created for the set of merged cells with the name $i$|-|$j$ where -% $i$ and $j$ are the number of the row and the number of the column of the -% upper left cell (where the command |\Block| has been issued). +% Tikz node is created for the set of merged cells with the name +% $i$|-|$j$-|block| where $i$ and $j$ are the number of the row and the number +% of the column of the upper left cell (where the command |\Block| has been +% issued). If the user has required the creation of the |medium| nodes, a node +% of this type is also created with a name suffixed by |-medium|. % % \medskip % \begin{BVerbatim}[baseline=c,boxwidth=11.6cm] % $\begin{pNiceMatrix}% -% [margin, -% code-after = { \tikz \node [~emphase#highlight = (1-1)@] {} ; } ] +% [ +% margin, +% create-medium-nodes, +% code-after = +% { \tikz \node [~emphase#highlight = (1-1-block-medium)@] {} ; } +% ] % \Block{3-3}<\Large>{A} & & & 0 \\ % & \hspace*{1cm} & & \Vdots \\ % & & & 0 \\ % 0 & \Cdots& 0 & 0 % \end{pNiceMatrix}$ % \end{BVerbatim} -% $\begin{pNiceMatrix}[margin, -% code-after = { \tikz \node [highlight = (1-1)] {} ; } ] +% $\begin{pNiceMatrix}[ +% margin, +% create-medium-nodes, +% code-after = +% { \tikz \node [highlight = (1-1-block-medium)] {} ; } +% ] % \Block{3-3}<\Large>{A} & & & 0 \\ % & \hspace*{1cm} & & \Vdots \\ % & & & 0 \\ @@ -2416,13 +2635,13 @@ c & c & b & a & e % \end{pNiceArray}\] % % -% \subsection{Direct utilisation of the Tikz nodes} +% \subsection{Direct use of the Tikz nodes} % % In the following example, we illustrate the mathematical product of two % matrices. % % \medskip -% The utilisation of |{NiceMatrixBlock}| with the option |auto-columns-width| +% The use of |{NiceMatrixBlock}| with the option |auto-columns-width| % gives the same width for all the columns and, therefore, a perfect alignment % of the two superposed matrices. % \begin{Verbatim} @@ -2550,8 +2769,14 @@ c & c & b & a & e % |\halign|. % % -% \subsection{Declaration of the package and extensions loaded} +% \bigskip +% \subsection*{Declaration of the package and extensions loaded} +% % +% The prefix |nicematrix| has been registred for this extension. +% +% See: |http://mirrors.ctan.org/macros/latex/contrib/l3kernel/l3prefixes.pdf| +% %<@@=nicematrix> % % \bigskip @@ -2563,7 +2788,7 @@ c & c & b & a & e % \begin{macrocode} \RequirePackage{tikz} \usetikzlibrary{fit} -\RequirePackage{expl3}[2019/07/01] +\RequirePackage{expl3}[2020/02/08] % \end{macrocode} % % We give the traditionnal declaration of a package written with |expl3|: @@ -2576,10 +2801,28 @@ c & c & b & a & e {Mathematical matrices with TikZ} % \end{macrocode} % +% +% \medskip +% The version of 2020/02/08 of \pkg{expl3} has replaced |\l_keys_key_tl| by +% |\l_keys_key_str|. We have immediately changed in this file. Now, you test the +% existence of |\l_keys_key_str| in order to detect whether the version of LaTeX +% used by the final user is up to date. +% \begin{macrocode} +\msg_new:nnn { nicematrix } { expl3~too~old } + { + Your~version~of~LaTeX~(especially~expl3)~is~too~old.~ + You~can~go~on~but~you~will~probably~have~other~errors~ + if~you~use~the~functionalities~of~nicematrix. + } +\cs_if_exist:NF \l_keys_key_str + { \msg_error:nn { nicematrix } { expl3~too~old } } +% \end{macrocode} +% +% % \bigskip -% We test if the class option |draft| has been used. In this case, we raise the -% flag |\c_@@_draft_bool| because we won't draw the dotted lines if the option -% |draft| is used. +% We test the class option |draft|. In this case, we raise the flag +% |\c_@@_draft_bool| because we won't draw the dotted lines if the option +% |draft| is used. % \begin{macrocode} \bool_new:N \c_@@_draft_bool \DeclareOption { draft } { \bool_set_true:N \c_@@_draft_bool } @@ -2606,7 +2849,7 @@ c & c & b & a & e \cs_new_protected:Npn \@@_error:nn { \msg_error:nnn { nicematrix } } \cs_new_protected:Npn \@@_error:nnn { \msg_error:nnnn { nicematrix } } \cs_new_protected:Npn \@@_fatal:n { \msg_fatal:nn { nicematrix } } -\cs_new_protected:Npn \@@_fatal:nn { \msg_fatal:nn { nicematrix } } +\cs_new_protected:Npn \@@_fatal:nn { \msg_fatal:nnn { nicematrix } } \cs_new_protected:Npn \@@_msg_new:nn { \msg_new:nnn { nicematrix } } \cs_new_protected:Npn \@@_msg_new:nnn { \msg_new:nnnn { nicematrix } } % \end{macrocode} @@ -2617,7 +2860,8 @@ c & c & b & a & e % \end{macrocode} % % -% \subsection{Technical definitions} +% \bigskip +% \subsection*{Technical definitions} % % 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 @@ -2657,12 +2901,14 @@ c & c & b & a & e { \mathinner { - \mkern 1 mu - \raise \p@ \hbox:n { . } - \mkern 2 mu - \raise 4 \p@ \hbox:n { . } - \mkern 2 mu - \raise 7 \p@ \vbox { \kern 7 pt \hbox:n { . } } \mkern 1 mu + \tex_mkern:D 1 mu + \box_move_up:nn { 1 pt } { \hbox:n { . } } + \tex_mkern:D 2 mu + \box_move_up:nn { 4 pt } { \hbox:n { . } } + \tex_mkern:D 2 mu + \box_move_up:nn { 7 pt } + { \vbox:n { \kern 7 pt \hbox:n { . } } } + \tex_mkern:D 1 mu } } % \end{macrocode} @@ -2756,10 +3002,10 @@ c & c & b & a & e \bool_new:N \l_@@_impossible_line_bool % \end{macrocode} % -% +% % \bigskip % We have to know whether \pkg{colortbl} is loaded for the redefinition of -% |\everycr| and for |\vline|. +% |\everycr| and |\vline| and for the options |hlines| and |vlines|. % \begin{macrocode} \bool_new:N \c_@@_colortbl_loaded_bool \AtBeginDocument @@ -2773,6 +3019,14 @@ c & c & b & a & e } % \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 } +% \end{macrocode} % % \bigskip % The length |\l_@@_inter_dots_dim| is the distance between two dots for the @@ -2795,20 +3049,40 @@ c & c & b & a & e % % \bigskip % The length |\l_@@_radius_dim| is the radius of the dots for the dotted lines. -% The default value is 0.34~pt but it will be changed if the option |small| is -% used. +% The default 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 (will be used only -% in the error messages). +% The name of the current environment or the current command (despite the name). % \begin{macrocode} -\str_new:N \g_@@_type_env_str +\str_new:N \g_@@_name_env_str % \end{macrocode} -% +% +% The string |\g_@@_com_or_env_str| will contain the word \emph{command} or +% \emph{environment} whether we are in a command of \pkg{nicematrix} or a an +% environment of \pkg{nicematrix}. The default value is \emph{environment}. +% \begin{macrocode} +\str_new:N \g_@@_com_or_env_str +\str_set:Nn \g_@@_com_or_env_str { environment } +% \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. +% \begin{macrocode} +\cs_new:Npn \@@_full_name_env: + { + \str_if_eq:VnTF \g_@@_com_or_env_str { command } + { command \space \c_backslash_str \g_@@_name_env_str } + { environment \space \{ \g_@@_name_env_str \} } + } +% \end{macrocode} +% +% \bigskip % \begin{macrocode} \tl_new:N \g_@@_code_after_tl % \end{macrocode} @@ -2824,11 +3098,17 @@ c & c & b & a & e % \end{macrocode} % % The TeX counters |\c@iRow| and |\c@jCol| will be created in the beginning of -% the environment |{NiceArrayWithDelims}| (if they don't exist previously). +% |{NiceArrayWithDelims}| (if they don't exist previously). +% +% \begin{macrocode} +\bool_new:N \g_@@_row_of_col_done_bool +% \end{macrocode} % +% % \bigskip -% \subsubsection{Variables for the exterior rows and columns} +% \textbf{Variables for the exterior rows and columns}\par\nobreak % +% \medskip % The keys for the exterior rows and columns are |first-row|, |first-col|, % |last-row| and |last-col|. However, internally, these keys are not coded in a % similar way. @@ -2907,9 +3187,9 @@ c & c & b & a & e % \end{itemize} % % \bigskip -% \subsubsection{The column S of siunitx} +% \textbf{The column S of siunitx}\par\nobreak % -% +% \medskip % We want to know whether the package \pkg{siunitx} is loaded and, if it is % loaded, we redefine the |S| columns of \pkg{siunitx}. % \begin{macrocode} @@ -2965,7 +3245,7 @@ c & c & b & a & e % when \pkg{siunitx} is loaded (and it may be loaded after \pkg{nicematrix}) % and, in fact, after the beginning of the document --- because some % instructions of \pkg{siunitx} are executed in a |\AtBeginDocument|). That's -% why this extraction will be done only at the first utilisation of an +% why this extraction will be done only at the first use of an % environment of \pkg{nicematrix} with the command |\@@_adapt_S_column:|. % \begin{macrocode} \cs_set_protected:Npn \@@_adapt_S_column: @@ -2975,9 +3255,8 @@ c & c & b & a & e % 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, in this document, we compose a matrix in the box |\ExampleOne| before -% loading \pkg{arydshln} (because \pkg{arydshln} is not totally compatible with -% \pkg{nicematrix}).} +% 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 { @@ -3036,7 +3315,7 @@ c & c & b & a & e % % % \bigskip -% \subsection{The options} +% \subsection*{The options} % % The boolean |\l_@@_light_syntax_bool| corresponds to the option |light-syntax|. % \begin{macrocode} @@ -3044,15 +3323,15 @@ c & c & b & a & e % \end{macrocode} % % \bigskip -% The token list |\l_@@_pos_env_str| will contain one of the three values |t|, +% The token list |\l_@@_baseline_str| will contain one of the three values |t|, % |c| or |b| and will indicate the position of the environment as in the option % of the environment |{array}|. For the environment |{pNiceMatrix}|, % |{pNiceArray}| and their variants, the value will programmatically be fixed to % |c|. For the environment |{NiceArray}|, however, the three values |t|, |c| and % |b| are possible. % \begin{macrocode} -\str_new:N \l_@@_pos_env_str -\str_set:Nn \l_@@_pos_env_str c +\str_new:N \l_@@_baseline_str +\str_set:Nn \l_@@_baseline_str c % \end{macrocode} % % \bigskip @@ -3073,9 +3352,11 @@ c & c & b & a & e % \end{macrocode} % % \bigskip -% The flag |\l_@@_hlines_bool| corresponds to the option |\hlines|. +% The flag |\l_@@_hlines_bool| corresponds to the option |\hlines| and the flag +% |\l_@@_vlines_bool| to the option |\vlines|. % \begin{macrocode} \bool_new:N \l_@@_hlines_bool +\bool_new:N \l_@@_vlines_bool % \end{macrocode} % % \bigskip @@ -3117,11 +3398,17 @@ c & c & b & a & e % \end{macrocode} % % \bigskip -% The dimensions |\l_@@_left_margin_dim| and |\l_@@_right_margin_dim| correspond -% to the options |left-margin| and |right-margin|. +% The dimension |\l_@@_left_margin_dim| correspondto the option |left-margin| +% (idem for the right margin). % \begin{macrocode} \dim_new:N \l_@@_left_margin_dim \dim_new:N \l_@@_right_margin_dim +% \end{macrocode} +% +% \bigskip +% The following dimensions will be used internally to compute the width of the +% potential ``first column'' and ``last column''. +% \begin{macrocode} \dim_new:N \g_@@_width_last_col_dim \dim_new:N \g_@@_width_first_col_dim % \end{macrocode} @@ -3144,6 +3431,20 @@ c & c & b & a & e \tl_set:Nn \l_@@_end_of_row_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 +% option |columns-width| or the option |auto-columns-width| of the environment +% |{NiceMatrixBlock}|). However, even if we use the same type of delimiters, the +% width of the delimiters may be different from an array to another because the +% width of the delimiter is fonction of its size. That's why we create an option +% called |max-delimiter-width| which will give to the delimiters the width of +% a delimiter (of the same type) of big size. The following boolean corresponds +% to this option. +% \begin{macrocode} +\bool_new:N \l_@@_max_delimiter_width_bool +% \end{macrocode} % % \bigskip % First, we define a set of keys ``|NiceMatrix / Global|'' which will be used @@ -3151,6 +3452,7 @@ c & c & b & a & e % \begin{macrocode} \keys_define:nn { NiceMatrix / Global } { + 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 , @@ -3167,6 +3469,8 @@ c & c & b & a & e code-for-last-row .value_required:n = true , small .bool_set:N = \l_@@_small_bool , hlines .bool_set:N = \l_@@_hlines_bool , + vlines .bool_set:N = \l_@@_vlines_bool , + hvlines .meta:n = { hlines , vlines } , parallelize-diags .bool_set:N = \l_@@_parallelize_diags_bool , % \end{macrocode} % @@ -3213,13 +3517,14 @@ c & c & b & a & e { \dim_set:Nn \l_@@_columns_width_dim { #1 } } , columns-width .value_required:n = true , name .code:n = - \unless \ifmeasuring@ - \str_set:Nn \l_tmpa_str { #1 } - \seq_if_in:NVTF \g_@@_names_seq \l_tmpa_str - { \@@_error:nn { Duplicate~name } { #1 } } - { \seq_gput_left:NV \g_@@_names_seq \l_tmpa_str } - \str_set_eq:NN \l_@@_name_str \l_tmpa_str - \fi , + \legacy_if:nF { measuring@ } + { + \str_set:Nn \l_tmpa_str { #1 } + \seq_if_in:NVTF \g_@@_names_seq \l_tmpa_str + { \@@_error:nn { Duplicate~name } { #1 } } + { \seq_gput_left:NV \g_@@_names_seq \l_tmpa_str } + \str_set_eq:NN \l_@@_name_str \l_tmpa_str + } , name .value_required:n = true , code-after .tl_gset:N = \g_@@_code_after_tl , code-after .value_required:n = true , @@ -3275,10 +3580,8 @@ c & c & b & a & e % \begin{macrocode} renew-matrix .code:n = \@@_renew_matrix: , renew-matrix .value_forbidden:n = true , - RenewMatrix .code:n = \@@_error:n { Option~RenewMatrix~suppressed } , transparent .meta:n = { renew-dots , renew-matrix } , transparent .value_forbidden:n = true, - Transparent .code:n = \@@_error:n { Option~Transparent~suppressed } , % \end{macrocode} % % @@ -3321,7 +3624,7 @@ c & c & b & a & e % \begin{macrocode} letter-for-dotted-lines .code:n = { - \int_compare:nTF { \tl_count:n { #1 } = \c_one_int } + \int_compare:nTF { \tl_count:n { #1 } = 1 } { \str_set:Nx \l_@@_letter_for_dotted_lines_str { #1 } } { \@@_error:n { Bad~value~for~letter~for~dotted~lines } } } , @@ -3378,9 +3681,11 @@ c & c & b & a & e % The options |c|, |t| and |b| of the environment |{NiceArray}| have the same % meaning as the option of the classical environment |{array}|. % \begin{macrocode} - c .code:n = \str_set:Nn \l_@@_pos_env_str c , - t .code:n = \str_set:Nn \l_@@_pos_env_str t , - b .code:n = \str_set:Nn \l_@@_pos_env_str b , + c .code:n = \str_set:Nn \l_@@_baseline_str c , + t .code:n = \str_set:Nn \l_@@_baseline_str t , + b .code:n = \str_set:Nn \l_@@_baseline_str b , + baseline .tl_set:N = \l_@@_baseline_str , + baseline .value_required:n = true , % \end{macrocode} % % In the environments |{NiceArray}| and its variants, the option |last-col| must @@ -3411,7 +3716,8 @@ c & c & b & a & e % \end{macrocode} % % -% \subsection{Important code used by \{NiceArrayWithDelims\} } +% \bigskip +% \subsection*{Important code used by \{NiceArrayWithDelims\} } % % The pseudo-environment |\@@_Cell:|--|\@@_end_Cell:| will be used to format the % cells of the array. In the code, the affectations are global because this @@ -3419,7 +3725,7 @@ c & c & b & a & e % environment |{array}|). % % \begin{macrocode} -\cs_new_protected:Nn \@@_Cell: +\cs_new_protected:Npn \@@_Cell: { % \end{macrocode} % We increment |\c@jCol|, which is the counter of the columns. @@ -3430,29 +3736,30 @@ c & c & b & a & e % the |\everycr| because some packages, like \pkg{arydshln}, create special rows % in the |\halign| that we don't want to take into account. % \begin{macrocode} - \int_compare:nNnT \c@jCol = \c_one_int + \int_compare:nNnT \c@jCol = 1 { - \int_compare:nNnT \l_@@_first_col_int = \c_one_int + \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_tmpa_box| because we want +% 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 % this |\hbox_set:Nw| will be in the |\@@_end_Cell:| (and the % |\c_math_toggle_token| also). % \begin{macrocode} - \hbox_set:Nw \l_tmpa_box + \hbox_set:Nw \l_@@_cell_box \c_math_toggle_token \bool_if:NT \l_@@_small_bool \scriptstyle % \end{macrocode} % % We will call \emph{corners} of the matrix the cases which are at the % intersection of the exterior rows and exterior columns (of course, the four -% corners doesn't always exist simultaneously). The codes -% |\l_@@_code_for_first_row_tl| and \emph{al} don't apply in the corners of the -% matrix. +% corners doesn't always exist simultaneously). +% +% The codes |\l_@@_code_for_first_row_tl| and \emph{al} don't apply in the +% corners of the matrix. % \begin{macrocode} \int_compare:nNnTF \c@iRow = 0 { \int_compare:nNnT \c@jCol > 0 \l_@@_code_for_first_row_tl } @@ -3465,15 +3772,17 @@ c & c & b & a & e % % \interitem % The following macro |\@@_begin_of_row| is usually used in the cell -% number~$1$ of the array. However, when the key |first-col| is used, -% |\@@_begin_of_row| is executed in the cell number~$0$ of the array. +% number~$1$ of the row. However, when the key |first-col| is used, +% |\@@_begin_of_row| is executed in the cell number~$0$ of the row. % \begin{macrocode} -\cs_new_protected:Nn \@@_begin_of_row: +\cs_new_protected:Npn \@@_begin_of_row: { \int_gincr:N \c@iRow \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 ) ; } % \end{macrocode} % @@ -3481,31 +3790,31 @@ c & c & b & a & e % \interitem % The following code is used in each cell of the array. It actualises quantities % that, at the end of the array, will give informations about the vertical -% dimension of the two first rows and the two last rows. +% dimension of the two first rows and the two last rows. If the user uses the +% |last-row|, some lines will be dynamically added to this command. % \begin{macrocode} -\cs_new_protected:Npn \@@_actualization_for_first_and_last_row: +\cs_new_protected:Npn \@@_update_for_first_and_last_row: { - \int_compare:nNnT \c@iRow = 0 + \int_compare:nNnTF \c@iRow = 0 { \dim_gset:Nn \g_@@_dp_row_zero_dim - { \dim_max:nn \g_@@_dp_row_zero_dim { \box_dp:N \l_tmpa_box } } + { \dim_max:nn \g_@@_dp_row_zero_dim { \box_dp:N \l_@@_cell_box } } \dim_gset:Nn \g_@@_ht_row_zero_dim - { \dim_max:nn \g_@@_ht_row_zero_dim { \box_ht:N \l_tmpa_box } } + { \dim_max:nn \g_@@_ht_row_zero_dim { \box_ht:N \l_@@_cell_box } } } - \int_compare:nNnT \c@iRow = \c_one_int - { - \dim_gset:Nn \g_@@_ht_row_one_dim - { \dim_max:nn \g_@@_ht_row_one_dim { \box_ht:N \l_tmpa_box } } + { + \int_compare:nNnT \c@iRow = 1 + { + \dim_gset:Nn \g_@@_ht_row_one_dim + { \dim_max:nn \g_@@_ht_row_one_dim { \box_ht:N \l_@@_cell_box } } + } } - \dim_gset:Nn \g_@@_ht_last_row_dim - { \dim_max:nn \g_@@_ht_last_row_dim { \box_ht:N \l_tmpa_box } } - \dim_gset:Nn \g_@@_dp_last_row_dim - { \dim_max:nn \g_@@_dp_last_row_dim { \box_dp:N \l_tmpa_box } } } % \end{macrocode} -% +% +% % \begin{macrocode} -\cs_new_protected:Nn \@@_end_Cell: +\cs_new_protected:Npn \@@_end_Cell: { \c_math_toggle_token \hbox_set_end: @@ -3517,12 +3826,12 @@ c & c & b & a & e % % \begin{macrocode} \dim_gset:Nn \g_@@_max_cell_width_dim - { \dim_max:nn \g_@@_max_cell_width_dim { \box_wd:N \l_tmpa_box } } + { \dim_max:nn \g_@@_max_cell_width_dim { \box_wd:N \l_@@_cell_box } } % \end{macrocode} % % The following computations are for the ``first row'' and the ``last row''. % \begin{macrocode} - \@@_actualization_for_first_and_last_row: + \@@_update_for_first_and_last_row: % \end{macrocode} % % Now, we can create the Tikz node of the cell. @@ -3548,9 +3857,7 @@ c & c & b & a & e \int_use:N \c@jCol } ] - \bgroup - \box_use:N \l_tmpa_box - \egroup ; + { \box_use_drop:N \l_@@_cell_box } ; } % \end{macrocode} % @@ -3561,19 +3868,18 @@ c & c & b & a & e % % \bigskip % In the environment |{NiceArrayWithDelims}|, we will have to redefine the -% column types |w| and |W|. These definitions are rather long because we have to -% construct the |w|-nodes in these columns. 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. -% \begin{macrocode} -\cs_new_protected:Nn \@@_renewcolumntype:nn +% 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. +% \begin{macrocode} +\cs_new_protected:Npn \@@_renewcolumntype:nn #1 #2 { \newcolumntype #1 [ 2 ] { > { - \hbox_set:Nw \l_tmpa_box + \hbox_set:Nw \l_@@_cell_box \@@_Cell: } c @@ -3581,23 +3887,7 @@ c & c & b & a & e \@@_end_Cell: \hbox_set_end: #2 - \tikz [ remember~picture ] - \node - [ - name = nm - \int_use:N \g_@@_env_int - - \int_use:N \c@iRow - - \int_use:N \c@jCol - w, - alias = - \str_if_empty:NF \l_@@_name_str - { - \l_@@_name_str - - \int_use:N \c@iRow - - \int_use:N \c@jCol - w - } , - inner~sep = \c_zero_dim , - ] - { \makebox [ ##2 ] [ ##1 ] { \box_use:N \l_tmpa_box } } - ; + \makebox [ ##2 ] [ ##1 ] { \box_use_drop:N \l_@@_cell_box } } } } @@ -3608,7 +3898,7 @@ c & c & b & a & e % 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 really draw the line after the construction of the +% instruction which will actually draw the line after the construction of the % matrix. % % \medskip @@ -3684,25 +3974,44 @@ c & c & b & a & e } \array % \end{macrocode} -% |\l_@@_pos_env_str| may have the value |t|, |c| or |b|. +% |\l_@@_baseline_str| may have the value |t|, |c| or |b|. However, if the value +% is |b|, we compose the |\array| (of \pkg{array}) with the option |t| and the +% right translation will be done further. % \begin{macrocode} - [ \l_@@_pos_env_str ] + [ \str_if_eq:VnTF \l_@@_baseline_str c c t ] } % \end{macrocode} % -% +% \medskip +% We keep in memory the standard version of |\ialign| because we will redefine +% |\ialign| in the environment |{NiceArrayWithDelims}| but restore the standard +% version for use in the cells of the array. +% \begin{macrocode} +\cs_set_eq:NN \@@_standard_ialign: \ialign +% \end{macrocode} % % \bigskip % The following must \emph{not} be protected because it begins with |\noalign|. % \begin{macrocode} -\cs_new:Npn \@@_everycr: - { \noalign { \@@_everycr_i: } } +\cs_new:Npn \@@_everycr: { \noalign { \@@_everycr_i: } } % \end{macrocode} % % \begin{macrocode} \cs_new_protected:Npn \@@_everycr_i: { \int_gzero:N \c@jCol +% \end{macrocode} +% The |\hbox:n| is mandatory. +% \begin{macrocode} + \hbox:n + { + \tikz [ remember~picture ] + \coordinate + ( nm - \int_use:N \g_@@_env_int - row - \int_eval:n { \c@iRow + 1 } ) ; + } +% \end{macrocode} +% We add the potential horizontal lines specified by the option |hlines|. +% \begin{macrocode} \bool_if:NT \l_@@_hlines_bool { % \end{macrocode} @@ -3712,10 +4021,14 @@ c & c & b & a & e % \begin{macrocode} \int_compare:nNnT \c@iRow > { -1 } { - \int_compare:nNnF \c@iRow = \l_@@_last_row_int - { - \hrule \@height \arrayrulewidth - \skip_vertical:n { - \arrayrulewidth } + \bool_if:NF \g_@@_row_of_col_done_bool + { + \int_compare:nNnF \c@iRow = \l_@@_last_row_int + { + \bool_if:NTF \c_@@_colortbl_loaded_bool + { { \CT@arc@ \hrule height \arrayrulewidth } } + { \hrule height \arrayrulewidth } + } } } } @@ -3730,6 +4043,7 @@ c & c & b & a & e % \begin{macrocode} \cs_new_protected:Npn \@@_pre_array: { + \box_clear_new:N \l_@@_cell_box \cs_if_exist:NT \theiRow { \int_set_eq:NN \l_@@_save_iRow_int \c@iRow } \int_gzero_new:N \c@iRow @@ -3804,18 +4118,13 @@ c & c & b & a & e \dim_gzero_new:N \g_@@_dp_last_row_dim \dim_gset:Nn \g_@@_dp_last_row_dim { \box_dp:N \@arstrutbox } % \end{macrocode} -% After its first utilisation, the definition of |\ialign| will revert +% After its first use, the definition of |\ialign| will revert % automatically to its default definition. With this programmation, we will % have, in the cells of the array, a clean version of |\ialign|.\footnote{The % user will probably not employ directly |\ialign| in the array... but more % likely environments that utilize |\ialign| internally (e.g.: |{substack}|).} % \begin{macrocode} - \cs_set:Npn \ialign - { - \everycr { } - \tabskip = \c_zero_skip - \halign - } + \cs_set_eq:NN \ialign \@@_standard_ialign: \halign } % \end{macrocode} @@ -3829,6 +4138,8 @@ c & c & b & a & e % \end{macrocode} % % \begin{macrocode} + \cs_set_eq:NN \firsthline \hline + \cs_set_eq:NN \lasthline \hline \cs_set_eq:NN \Ldots \@@_Ldots \cs_set_eq:NN \Cdots \@@_Cdots \cs_set_eq:NN \Vdots \@@_Vdots @@ -3839,6 +4150,7 @@ c & c & b & a & e \cs_set_eq:NN \Hdotsfor \@@_Hdotsfor: \cs_set_eq:NN \multicolumn \@@_multicolumn:nnn \cs_set_eq:NN \Block \@@_Block: + \cs_set_eq:NN \rotate \@@_rotate: \cs_set_eq:NN \OnlyMainNiceMatrix \@@_OnlyMainNiceMatrix:n \bool_if:NT \l_@@_renew_dots_bool { @@ -3919,18 +4231,18 @@ c & c & b & a & e { ! { - \skip_horizontal:n { 0.53 pt } % \end{macrocode} -% If the array is an array with all the columns of the same width, we don't ask -% for the creation of the extra nodes because we will use the ``|col|'' nodes -% for the vertical dotted line. +% +% \medskip +% The following code 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} - \bool_if:nF + \int_compare:nNnF \c@iRow = 0 { - \l_@@_auto_columns_width_bool - || \dim_compare_p:nNn \l_@@_columns_width_dim > \c_zero_dim + \int_compare:nNnF \c@iRow = \l_@@_last_row_int + { \skip_horizontal:n { 2 \l_@@_radius_dim } } } - { \bool_gset_true:N \g_@@_large_nodes_bool } % \end{macrocode} % % \medskip @@ -3986,24 +4298,24 @@ c & c & b & a & e % \end{macrocode} % % \bigskip -% \subsection{The environment \{NiceArrayWithDelims\}} +% \subsection*{The environment \{NiceArrayWithDelims\}} % % \begin{macrocode} \NewDocumentEnvironment { NiceArrayWithDelims } { m m O { } m ! O { } } { - \str_if_empty:NT \g_@@_type_env_str - { - \str_gset:Nn \g_@@_type_env_str - { environment ~ { NiceArrayWithDelims } } - } + \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 } } \@@_adapt_S_column: \@@_test_if_math_mode: \bool_if:NT \l_@@_in_env_bool { \@@_fatal:n { Yet~in~env } } \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. +% +% Since we use Tikz pictures with the options |overlay| and |remember picture|, +% there would be errors). % \begin{macrocode} \cs_if_exist:NT \tikz@library@external@loaded { @@ -4038,13 +4350,24 @@ c & c & b & a & e { \keys_set:nn { NiceMatrix / pNiceArray } } { #3 , #5 } % \end{macrocode} -% +% +% % A value of $-1$ for the counter |\l_@@_last_row_int| means that the user has % used the option |last-row| without value, that is to say without specifying % the number of that last row. In this case, we try to read that value from the % |aux| file (if it has been written on a previous run). % % \begin{macrocode} + \int_compare:nNnT \l_@@_last_row_int > { -2 } + { + \tl_put_right:Nn \@@_update_for_first_and_last_row: + { + \dim_gset:Nn \g_@@_ht_last_row_dim + { \dim_max:nn \g_@@_ht_last_row_dim { \box_ht:N \l_@@_cell_box } } + \dim_gset:Nn \g_@@_dp_last_row_dim + { \dim_max:nn \g_@@_dp_last_row_dim { \box_dp:N \l_@@_cell_box } } + } + } \int_compare:nNnT \l_@@_last_row_int = { -1 } { \bool_set_true:N \l_@@_last_row_without_value_bool @@ -4070,8 +4393,7 @@ c & c & b & a & e } % \end{macrocode} % -% The code in |\@@_pre_array:| is used only by |{NiceArrayWithDelims}|. It -% exists only for historical reasons. We should change that. +% The code in |\@@_pre_array:| is used only by |{NiceArrayWithDelims}|. % \begin{macrocode} \@@_pre_array: % \end{macrocode} @@ -4079,32 +4401,30 @@ c & c & b & a & e % \medskip % We compute the width of the two delimiters. % \begin{macrocode} - \dim_gzero_new:N \g_@@_left_delim_dim - \dim_gzero_new:N \g_@@_right_delim_dim + \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 \g_@@_left_delim_dim { 2 \arraycolsep } - \dim_gset:Nn \g_@@_right_delim_dim { 2 \arraycolsep } + \dim_gset:Nn \l_@@_left_delim_dim { 2 \arraycolsep } + \dim_gset:Nn \l_@@_right_delim_dim { 2 \arraycolsep } } { - \group_begin: - \dim_set_eq:NN \nulldelimiterspace \c_zero_dim \hbox_set:Nn \l_tmpa_box { \c_math_toggle_token \left #1 \vcenter to 3 cm { } \right. \c_math_toggle_token } - \dim_gset:Nn \g_@@_left_delim_dim { \box_wd:N \l_tmpa_box } + \dim_set:Nn \l_@@_left_delim_dim + { \box_wd:N \l_tmpa_box - \nulldelimiterspace } \hbox_set:Nn \l_tmpa_box { - \dim_set_eq:NN \nulldelimiterspace \c_zero_dim \c_math_toggle_token \left. \vcenter to 3 cm { } \right #2 \c_math_toggle_token } - \dim_gset:Nn \g_@@_right_delim_dim { \box_wd:N \l_tmpa_box } - \group_end: + \dim_set:Nn \l_@@_right_delim_dim + { \box_wd:N \l_tmpa_box - \nulldelimiterspace } } % \end{macrocode} % @@ -4122,27 +4442,44 @@ c & c & b & a & e \int_compare:nNnTF \l_@@_first_col_int = 0 { \tl_put_left:NV \l_tmpa_tl \c_@@_preamble_first_col_tl } { - \bool_if:NT \l_@@_NiceArray_bool - { - \bool_if:NF \l_@@_exterior_arraycolsep_bool - { \tl_put_left:Nn \l_tmpa_tl { @ { } } } + \bool_if:nT + { + \l_@@_NiceArray_bool + && ! \l_@@_vlines_bool + && ! \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 \l_@@_NiceArray_bool - { - \bool_if:NF \l_@@_exterior_arraycolsep_bool - { \tl_put_right:Nn \l_tmpa_tl { @ { } } } + \bool_if:nT + { + \l_@@_NiceArray_bool + && ! \l_@@_vlines_bool + && ! \l_@@_exterior_arraycolsep_bool } + { \tl_put_right:Nn \l_tmpa_tl { @ { } } } } + \tl_put_right:Nn \l_tmpa_tl { > { \@@_error_too_much_cols: } l } % \end{macrocode} % Here is the beginning of the box which will contain the array. The % |\hbox_set_end:| corresponding to this |\hbox_set:Nw| will be in the second % part of the environment (and the closing |\c_math_toggle_token| also). % \begin{macrocode} \hbox_set:Nw \l_@@_the_array_box +% \end{macrocode} +% If the key |\vlines| is used, we increase |\arraycolsep| by +% |0.5\arrayrulewidth| in order to reserve space for the width of the vertical +% rules drawn with Tikz after the end of the array. However, the first +% |\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 + { + \dim_add:Nn \arraycolsep { 0.5 \arrayrulewidth } + \skip_horizontal:n { 0.5 \arrayrulewidth } + } \skip_horizontal:n \l_@@_left_margin_dim \skip_horizontal:n \l_@@_extra_left_margin_dim \c_math_toggle_token @@ -4161,13 +4498,22 @@ c & c & b & a & e \c_math_toggle_token \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 +% rules drawn with Tikz after the end of the array. However, the last +% |\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 } } \hbox_set_end: % \end{macrocode} -% Now, the box containing the array is constructed (in |\l_@@_the_array_box|). -% However, we have some computations to do before inserting that box in the TeX -% flow (mainly because the exterior columns are in overlapping positions). +% End of the construction of the array (in the box |\l_@@_the_array_box|). % % \bigskip +% It the user has used the key |last-row| with a value, we control that the +% given value is correct (since we have just contructed the array, we know the +% real number of rows of the array). % \begin{macrocode} \int_compare:nNnT \l_@@_last_row_int > { -2 } { @@ -4181,6 +4527,25 @@ c & c & b & a & e } } % \end{macrocode} +% +% Now, the definition of |\c@jCol| and +% |\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$.} +% \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 } +% \end{macrocode} +% +% We fix also the value of |\c@iRow| and |\g_@@_row_total_int| with the +% same principle. +% \begin{macrocode} + \int_gset_eq:NN \g_@@_row_total_int \c@iRow + \int_compare:nNnT \l_@@_last_row_int > { -1 } { \int_gdecr:N \c@iRow } +% \end{macrocode} +% +% % % \bigskip % \textbf{Now, we begin the real construction in the output flow of TeX}. First, we take @@ -4203,24 +4568,76 @@ c & c & b & a & e % \begin{macrocode} \bool_if:NTF \l_@@_NiceArray_bool { - \int_compare:nNnTF \l_@@_first_row_int = 0 +% \end{macrocode} +% Remember that, when the key |b| is used, the |\array| (of \pkg{array}) is +% constructed with the option |t| (and not |b|). Now, we do the translation to +% take into account the option |b|. +% \begin{macrocode} + \str_if_eq:VnTF \l_@@_baseline_str { b } { - \str_if_eq:VnT \l_@@_pos_env_str { t } - { - \box_move_up:nn { \g_@@_dp_row_zero_dim + \g_@@_ht_row_one_dim } - } + \begin { tikzpicture } + \@@_extract_coords:w ( nm - \int_use:N \g_@@_env_int - 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 + ) + \dim_gsub:Nn \g_tmpa_dim \pgf@y + \end { tikzpicture } + \int_compare:nNnT \l_@@_first_row_int = 0 + { + \dim_gadd:Nn \g_tmpa_dim + { \g_@@_ht_row_zero_dim + \g_@@_dp_row_zero_dim } + } + \box_move_up:nn \g_tmpa_dim { \box_use_drop:N \l_@@_the_array_box } } - { - \int_compare:nNnT \l_@@_last_row_int > 0 + { + \str_if_eq:VnTF \l_@@_baseline_str { c } + { \box_use_drop:N \l_@@_the_array_box } { - \str_if_eq:VnT \l_@@_pos_env_str { b } +% \end{macrocode} +% We convert a value of |t| to a value of |1|. +% \begin{macrocode} + \str_if_eq:VnT \l_@@_baseline_str { t } + { \str_set:Nn \l_@@_baseline_str { 1 } } +% \end{macrocode} +% Now, we convert the value of |\l_@@_baseline_str| (which should represent an +% integer) to an integer stored in |\l_tmpa_int|. +% \begin{macrocode} + \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 > \g_@@_row_total_int + } + { + \@@_error:n { bad~value~for~baseline } + \int_set:Nn \l_tmpa_int 1 + } +% \end{macrocode} +% We use a |{tikzpicture}| to extract coordinates (nothing is drawn). +% \begin{macrocode} + \begin { tikzpicture } + \@@_extract_coords:w + ( nm - \int_use:N \g_@@_env_int - 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 + ) + \dim_gsub:Nn \g_tmpa_dim \pgf@y + \end { tikzpicture } + \int_compare:nNnT \l_@@_first_row_int = 0 { - \box_move_down:nn - { \g_@@_ht_last_row_dim + \g_@@_dp_ante_last_row_dim } + \dim_gadd:Nn \g_tmpa_dim + { \g_@@_ht_row_zero_dim + \g_@@_dp_row_zero_dim } } + \box_move_up:nn \g_tmpa_dim + { \box_use_drop:N \l_@@_the_array_box } } } - { \box_use_drop:N \l_@@_the_array_box } } % \end{macrocode} % @@ -4236,6 +4653,7 @@ c & c & b & a & e } { \dim_zero:N \l_tmpa_dim } % \end{macrocode} +% % We compute |\l_tmpb_dim| which is the total height of the ``last row'' % below the array (when the key |last-row| is used). A value of $-2$ for % |\l_@@_last_row_int| means that there is no ``last row''.\footnote{A value of @@ -4278,50 +4696,132 @@ c & c & b & a & e \right #2 \c_math_toggle_token } - \box_set_ht:Nn \l_tmpa_box { \box_ht:N \l_tmpa_box + \l_tmpa_dim } - \box_set_dp:Nn \l_tmpa_box { \box_dp:N \l_tmpa_box + \l_tmpb_dim } - \box_use_drop:N \l_tmpa_box +% \end{macrocode} +% Now, the box |\l_tmpa_box| is created with the correct delimiters. +% +% \smallskip +% We will put the box in the TeX flow. However, we have a small work to do +% when the option |max-delimiter-width| is used. +% \begin{macrocode} + \bool_if:NTF \l_@@_max_delimiter_width_bool + { \@@_put_box_in_flow_bis:nn { #1 } { #2 } } + \@@_put_box_in_flow: } % \end{macrocode} +% % We take into account a potential ``last column'' (this ``last column'' has % been constructed in an overlapping position and we have computed its width in % |\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 - \skip_horizontal:n \arraycolsep - } + { \skip_horizontal:n { \g_@@_width_last_col_dim + \arraycolsep } } \@@_after_array: } % \end{macrocode} % This is the end of the environment |{NiceArrayWithDelims}|. % -% -% \interitem -% The construction of the array in the environment |{NiceArrayWithDelims}| is, -% in fact, done by the environment |{@@-light-syntax}| or by the environment -% |{@@-normal-syntax}| (whether the option |light-syntax| is used or not). When -% the key |light-syntax| is not used, the construction is a standard -% environment (and, thus, it's possible to use verbatim in the arrray). +% \bigskip +% The command |\@@_put_box_in_flow:| puts the box |\l_tmpa_box| (which contains +% the array) in the flow. It is used for the environments with delimiters. +% First, we have to modify the height and the depth to take back into account +% the potential exterior rows (the total height of the first row has been +% computed in |\l_tmpa_dim| and the total height of the potential last row in +% |\l_tmpb_dim|). +% \begin{macrocode} +\cs_new_protected:Npn \@@_put_box_in_flow: + { + \box_set_ht:Nn \l_tmpa_box { \box_ht:N \l_tmpa_box + \l_tmpa_dim } + \box_set_dp:Nn \l_tmpa_box { \box_dp:N \l_tmpa_box + \l_tmpb_dim } + \box_use_drop:N \l_tmpa_box + } +% \end{macrocode} +% +% \bigskip +% The command |\@@_put_box_in_flow_bis:| is used when the option +% |max-delimiter-width| is used because, in this case, we have to adjust the +% widths of the delimiters. The arguments |#1| and |#2| are the delimiters +% specified by the user. +% \begin{macrocode} +\cs_new_protected:Npn \@@_put_box_in_flow_bis:nn #1 #2 + { +% \end{macrocode} +% We will compute the real width of both delimiters used. +% \begin{macrocode} + \dim_zero_new:N \l_@@_real_left_delim_dim + \dim_zero_new:N \l_@@_real_right_delim_dim + \hbox_set:Nn \l_tmpb_box + { + \c_math_toggle_token + \left #1 + \vcenter + { + \vbox_to_ht:nn + { \box_ht:N \l_tmpa_box + \box_dp:N \l_tmpa_box } + { } + } + \right . + \c_math_toggle_token + } + \dim_set:Nn \l_@@_real_left_delim_dim + { \box_wd:N \l_tmpb_box - \nulldelimiterspace } + \hbox_set:Nn \l_tmpb_box + { + \c_math_toggle_token + \left . + \vbox_to_ht:nn + { \box_ht:N \l_tmpa_box + \box_dp:N \l_tmpa_box } + { } + \right #2 + \c_math_toggle_token + } + \dim_set:Nn \l_@@_real_right_delim_dim + { \box_wd:N \l_tmpb_box - \nulldelimiterspace } +% \end{macrocode} +% +% 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 } + \@@_put_box_in_flow: + \skip_horizontal:n { \l_@@_right_delim_dim - \l_@@_real_right_delim_dim } + } +% \end{macrocode} +% +% \interitem +% The construction of the array in the environment |{NiceArrayWithDelims}| is, +% in fact, done by the environment |{@@-light-syntax}| or by the environment +% |{@@-normal-syntax}| (whether the option |light-syntax| is used or not). When +% the key |light-syntax| is not used, the construction is a standard +% environment (and, thus, it's possible to use verbatim in the arrray). % \begin{macrocode} \NewDocumentEnvironment { @@-normal-syntax } { } % \end{macrocode} +% First, we test whether the environment is empty. If it is empty, we raise a +% fatal error (it's only a security). In order to detect whether it is empty, we +% test whether the next token is |\end| and, if it's the case, we test if this +% is the end of the environment (if it is not, an standard error will be raised +% by LaTeX for incorrect nested environments). +% \begin{macrocode} + { + \peek_meaning_ignore_spaces:NTF \end + { \@@_analyze_end:Nn } +% \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 } + { \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-column-width| of the environment +% |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_row_of_col_nodes: + \@@_create_col_nodes: \endarray } % \end{macrocode} @@ -4334,6 +4834,12 @@ c & c & b & a & e \NewDocumentEnvironment { @@-light-syntax } { b } { % \end{macrocode} +% First, we test whether the environment is empty. It's only a security. Of +% 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} @@ -4352,7 +4858,7 @@ c & c & b & a & e \seq_gpop_left:NN \g_@@_rows_seq \l_tmpa_tl \exp_args:NV \@@_line_with_light_syntax_i:n \l_tmpa_tl \seq_map_function:NN \g_@@_rows_seq \@@_line_with_light_syntax:n - \@@_create_row_of_col_nodes: + \@@_create_col_nodes: \endarray } % \end{macrocode} @@ -4387,102 +4893,106 @@ c & c & b & a & e % \end{macrocode} % % \bigskip -% The command |\@@_create_row_of_col_nodes:| will construct the potential last -% row. That last row (when it is created) is a false row used to fix the width -% of the columns (when the array is constructed with an option whhich specify -% the width of the columns) and create the |col|-nodes (that nodes will be used -% by |\vdottedline| for instance). +% The following command is used by the code which detects whether the +% environment is empty (we raise a fatal error in this case: it's only a +% security). % \begin{macrocode} -\cs_new:Npn \@@_create_row_of_col_nodes: +\cs_new_protected:Npn \@@_analyze_end:Nn #1 #2 { - \bool_if:nT - { - \l_@@_auto_columns_width_bool - || \dim_compare_p:nNn \l_@@_columns_width_dim > \c_zero_dim - } - { - \crcr - \int_compare:nNnT \l_@@_first_col_int = 0 { \omit & } - \omit + \str_if_eq:VnT \g_@@_name_env_str { #2 } + { \@@_fatal:n { empty~environment } } +% \end{macrocode} +% We reput in the stream the |\end{...}| we have extracted and the user will +% have an error for incorrect nested environments. +% \begin{macrocode} + \end { #2 } + } +% \end{macrocode} +% +% \bigskip +% The command |\@@_create_col_nodes:| will construct a special last row. +% That last row is a false row used to create the |col|-nodes and to fix the +% width of the columns (when the array is constructed with an option which +% specify the width of the columns). +% \begin{macrocode} +\cs_new:Npn \@@_create_col_nodes: + { + \crcr + \int_compare:nNnT \c@iRow = 0 { \@@_fatal:n { Zero~row } } + \int_compare:nNnT \l_@@_first_col_int = 0 { \omit & } + \omit +% \end{macrocode} +% The following instruction must be put after the instructions |\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} - \skip_horizontal:N \arraycolsep - \tikz [ remember~picture , overlay ] - \coordinate [ name = nm - \int_use:N \g_@@_env_int - col - 0 ] ; - \skip_horizontal:n { - \arraycolsep } + \tikz [ remember~picture ] + \coordinate ( nm - \int_use:N \g_@@_env_int - col - 1 ) ; % \end{macrocode} -% We compute in |\g_tmpa_dim| the common width of the columns. 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_dim|, -% like all the affectations, must be done after the |\omit| of the cell. +% 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. % \begin{macrocode} + \bool_if:nTF + { + \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 } { - \dim_gset:Nn \g_tmpa_dim + \skip_gset:Nn \g_tmpa_skip { \g_@@_max_cell_width_dim + 2 \arraycolsep } } { - \dim_gset:Nn \g_tmpa_dim + \skip_gset:Nn \g_tmpa_skip { \l_@@_columns_width_dim + 2 \arraycolsep } - } - \skip_horizontal:N \g_tmpa_dim - \tikz [ remember~picture , overlay ] - \coordinate [ name = nm - \int_use:N \g_@@_env_int - col - 1 ] ; + } + } + { \skip_gset:Nn \g_tmpa_skip { 0 pt~plus 1 fill } } + \skip_horizontal:N \g_tmpa_skip + \hbox:n + { + \tikz [ remember~picture ] + \coordinate ( nm - \int_use:N \g_@@_env_int - col - 2 ) ; + } % \end{macrocode} % We begin a loop over the columns. The integer |\g_tmpa_int| will be the -% number of the current column. This integer is not used to fix the -% width of the column (since all the columns have the same width equal to -% |\g_@@_tmpa_dim|) but for the Tikz nodes. -% \begin{macrocode} - \int_gset:Nn \g_tmpa_int 1 - \bool_if:nTF \g_@@_last_col_found_bool - { \prg_replicate:nn { \g_@@_col_total_int - 3 } } - { \prg_replicate:nn { \g_@@_col_total_int - 2 } } - { - & - \omit +% number of the current column. This integer is used for the Tikz nodes. +% \begin{macrocode} + \int_gset:Nn \g_tmpa_int 1 + \bool_if:NTF \g_@@_last_col_found_bool + { \prg_replicate:nn { \g_@@_col_total_int - 2 } } + { \prg_replicate:nn { \g_@@_col_total_int - 1 } } + { + & + \omit % \end{macrocode} % The incrementation of the counter |\g_tmpa_int| must be done after the |\omit| % of the cell. % \begin{macrocode} - \int_gincr:N \g_tmpa_int - \skip_horizontal:N \g_tmpa_dim + \int_gincr:N \g_tmpa_int + \skip_horizontal:N \g_tmpa_skip % \end{macrocode} -% We create a ``|col|'' node on the right of the current column. +% We create the ``|col|'' node on the right of the current column. % \begin{macrocode} - \@@_create_col_node: - } -% \end{macrocode} -% For the last column, we want a special treatment because of the final -% |\arraycolsep|. -% \begin{macrocode} - & - \omit - \int_gincr:N \g_tmpa_int - \skip_horizontal:N \g_tmpa_dim - \skip_horizontal:n { - \arraycolsep } - \@@_create_col_node: - \skip_horizontal:N \arraycolsep + \tikz [ remember~picture ] + \coordinate + ( + nm - \int_use:N \g_@@_env_int - + col - \int_eval:n { \g_tmpa_int + 1 } + ) ; } - } -% \end{macrocode} -% -% \bigskip -% \begin{macrocode} -\cs_new_protected:Npn \@@_create_col_node: - { - \tikz [ remember~picture , overlay ] - \coordinate - [ - name = nm - \int_use:N \g_@@_env_int - - col - \int_use:N \g_tmpa_int - ] ; + \cr } % \end{macrocode} % @@ -4497,10 +5007,10 @@ c & c & b & a & e { \@@_begin_of_row: % \end{macrocode} -% The contents of the cell is constructed in the box |\l_tmpa_box| because we +% The contents of the cell is constructed in the box |\l_@@_cell_box| because we % have to compute some dimensions of this box. % \begin{macrocode} - \hbox_set:Nw \l_tmpa_box + \hbox_set:Nw \l_@@_cell_box \c_math_toggle_token \bool_if:NT \l_@@_small_bool \scriptstyle % \end{macrocode} @@ -4519,12 +5029,16 @@ c & c & b & a & e } { \l_@@_code_for_first_col_tl } } +% \end{macrocode} +% Be careful: despite this letter |l| the cells of the ``first column'' are +% composed in a |R| manner since they are composed in a |\hbox_overlap_left:n|. +% \begin{macrocode} l < { \c_math_toggle_token \hbox_set_end: - \@@_actualization_for_first_and_last_row: + \@@_update_for_first_and_last_row: % \end{macrocode} % We actualise the width of the ``first column'' because we will use this width % after the construction of the array. @@ -4533,7 +5047,7 @@ c & c & b & a & e { \dim_max:nn \g_@@_width_first_col_dim - { \box_wd:N \l_tmpa_box } + { \box_wd:N \l_@@_cell_box } } % \end{macrocode} % The content of the cell is inserted in an overlapping position. @@ -4564,10 +5078,10 @@ c & c & b & a & e 0 } ] - { \box_use:N \l_tmpa_box } ; + { \box_use_drop:N \l_@@_cell_box } ; \skip_horizontal:n { - \g_@@_left_delim_dim + + \l_@@_left_delim_dim + \l_@@_left_margin_dim + \l_@@_extra_left_margin_dim } @@ -4597,7 +5111,7 @@ c & c & b & a & e % The contents of the cell is constructed in the box |\l_tmpa_box| because we % have to compute some dimensions of this box. % \begin{macrocode} - \hbox_set:Nw \l_tmpa_box + \hbox_set:Nw \l_@@_cell_box \c_math_toggle_token \bool_if:NT \l_@@_small_bool \scriptstyle % \end{macrocode} @@ -4621,7 +5135,7 @@ c & c & b & a & e { \c_math_toggle_token \hbox_set_end: - \@@_actualization_for_first_and_last_row: + \@@_update_for_first_and_last_row: % \end{macrocode} % We actualise the width of the ``last column'' because we will use this width % after the construction of the array. @@ -4630,7 +5144,7 @@ c & c & b & a & e { \dim_max:nn \g_@@_width_last_col_dim - { \box_wd:N \l_tmpa_box } + { \box_wd:N \l_@@_cell_box } } \skip_horizontal:n { - 2 \arraycolsep } % \end{macrocode} @@ -4641,7 +5155,7 @@ c & c & b & a & e { \skip_horizontal:n { - \g_@@_right_delim_dim + + \l_@@_right_delim_dim + \l_@@_right_margin_dim + \l_@@_extra_right_margin_dim } @@ -4668,7 +5182,7 @@ c & c & b & a & e \int_use:N \c@jCol } ] - { \box_use:N \l_tmpa_box } ; + { \box_use_drop:N \l_@@_cell_box } ; } } } @@ -4684,8 +5198,8 @@ c & c & b & a & e \NewDocumentEnvironment { NiceArray } { } { \bool_set_true:N \l_@@_NiceArray_bool - \str_if_empty:NT \g_@@_type_env_str - { \str_gset:Nn \g_@@_type_env_str { environment ~ { NiceArray } } } + \str_if_empty:NT \g_@@_name_env_str + { \str_gset:Nn \g_@@_name_env_str { NiceArray } } % \end{macrocode} % We put . and . for the delimiters but, in fact, that doesn't matter because % these arguments won't be used in |{NiceArrayWithDelims}| (because the flag @@ -4704,8 +5218,8 @@ c & c & b & a & e % \begin{macrocode} \NewDocumentEnvironment { pNiceArray } { } { - \str_if_empty:NT \g_@@_type_env_str - { \str_gset:Nn \g_@@_type_env_str { environment ~ { pNiceArray } } } + \str_if_empty:NT \g_@@_name_env_str + { \str_gset:Nn \g_@@_name_env_str { pNiceArray } } \@@_test_if_math_mode: \NiceArrayWithDelims ( ) } @@ -4715,8 +5229,8 @@ c & c & b & a & e % \begin{macrocode} \NewDocumentEnvironment { bNiceArray } { } { - \str_if_empty:NT \g_@@_type_env_str - { \str_gset:Nn \g_@@_type_env_str { environment ~ { bNiceArray } } } + \str_if_empty:NT \g_@@_name_env_str + { \str_gset:Nn \g_@@_name_env_str { bNiceArray } } \@@_test_if_math_mode: \NiceArrayWithDelims [ ] } @@ -4726,8 +5240,8 @@ c & c & b & a & e % \begin{macrocode} \NewDocumentEnvironment { BNiceArray } { } { - \str_if_empty:NT \g_@@_type_env_str - { \str_gset:Nn \g_@@_type_env_str { environment ~ { BNiceArray } } } + \str_if_empty:NT \g_@@_name_env_str + { \str_gset:Nn \g_@@_name_env_str { BNiceArray } } \@@_test_if_math_mode: \NiceArrayWithDelims \{ \} } @@ -4737,8 +5251,8 @@ c & c & b & a & e % \begin{macrocode} \NewDocumentEnvironment { vNiceArray } { } { - \str_if_empty:NT \g_@@_type_env_str - { \str_gset:Nn \g_@@_type_env_str { environment ~ { vNiceArray } } } + \str_if_empty:NT \g_@@_name_env_str + { \str_gset:Nn \g_@@_name_env_str { vNiceArray } } \@@_test_if_math_mode: \NiceArrayWithDelims | | } @@ -4748,8 +5262,8 @@ c & c & b & a & e % \begin{macrocode} \NewDocumentEnvironment { VNiceArray } { } { - \str_if_empty:NT \g_@@_type_env_str - { \str_gset:Nn \g_@@_type_env_str { environment ~ { VNiceArray } } } + \str_if_empty:NT \g_@@_name_env_str + { \str_gset:Nn \g_@@_name_env_str { VNiceArray } } \@@_test_if_math_mode: \NiceArrayWithDelims \| \| } @@ -4757,14 +5271,14 @@ c & c & b & a & e % \end{macrocode} % % \bigskip -% \subsection{The environment \{NiceMatrix\} and its variants} +% \subsection*{The environment \{NiceMatrix\} and its variants} % % \begin{macrocode} \cs_new_protected:Npn \@@_define_env:n #1 { \NewDocumentEnvironment { #1 NiceMatrix } { ! O { } } { - \str_gset:Nn \g_@@_type_env_str { environment ~ { #1 NiceMatrix } } + \str_gset:Nn \g_@@_name_env_str { #1 NiceMatrix } \keys_set:nn { NiceMatrix / NiceMatrix } { ##1 } \begin { #1 NiceArray } { @@ -4792,7 +5306,7 @@ c & c & b & a & e % % % \bigskip -% \subsection{How to know whether a cell is ``empty''} +% \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 @@ -4893,49 +5407,22 @@ c & c & b & a & e % \end{macrocode} % % -% \subsection{After the construction of the array} -% -% -% \begin{macrocode} -\cs_new_protected:Nn \@@_after_array: - { - \int_compare:nNnTF \c@iRow > 0 - \@@_after_array_i: - { - \@@_error:n { Zero~row } - \@@_restore_iRow_jCol: - } - } -% \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). +% We deactivate Tikz externalization. +% +% Since we use Tikz pictures with the options |overlay| and |remember picture|, +% there would be errors. % \begin{macrocode} -\cs_new_protected:Nn \@@_after_array_i: +\cs_new_protected:Npn \@@_after_array: { \group_begin: \cs_if_exist:NT \tikz@library@external@loaded { \tikzset { external / export = false } } % \end{macrocode} -% Now, the definition of |\c@jCol| and -% |\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$.} -% \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 } -% \end{macrocode} -% -% We fix also the value of |\c@iRow| and |\g_@@_row_total_int| with the -% same principle. -% \begin{macrocode} - \int_gset_eq:NN \g_@@_row_total_int \c@iRow - \int_compare:nNnT \l_@@_last_row_int > { -1 } - { \int_gsub:Nn \c@iRow \c_one_int } -% \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. @@ -4995,10 +5482,9 @@ c & c & b & a & e % 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 the booleans -% |\l_@@_medium_nodes_bool| and |\l_@@_large_nodes_bool| but theses booleans are -% converted into the global version |\g_@@_medium_nodes_bool| and -% |\g_@@_large_nodes_bool| before the creation of the array). +% |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 { @@ -5037,6 +5523,8 @@ c & c & b & a & e \g_@@_Ldots_lines_tl % \end{macrocode} % +% +% % \bigskip % Now, the |code-after|. % \begin{macrocode} @@ -5049,17 +5537,71 @@ c & c & b & a & e name~prefix = nm - \int_use:N \g_@@_env_int - } } + \bool_if:NT \l_@@_vlines_bool \@@_draw_vlines: \cs_set_eq:NN \line \@@_line:nn \g_@@_code_after_tl \tl_gclear:N \g_@@_code_after_tl \group_end: - \str_gclear:N \g_@@_type_env_str + \str_gclear:N \g_@@_name_env_str \@@_restore_iRow_jCol: } % \end{macrocode} % +% \bigskip +% \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@ + \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 } + { + \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 + } +% \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 { \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: + } +% \end{macrocode} +% +% +% \bigskip % \begin{macrocode} -\cs_new_protected:Nn \@@_restore_iRow_jCol: +\cs_new_protected:Npn \@@_restore_iRow_jCol: { \cs_if_exist:NT \theiRow { \int_gset_eq:NN \c@iRow \l_@@_save_iRow_int } \cs_if_exist:NT \thejCol { \int_gset_eq:NN \c@jCol \l_@@_save_jCol_int } @@ -5076,7 +5618,7 @@ c & c & b & a & e % 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, if it exists, the |w|-node. +% ``medium node'' or the |col|-node. % \[ \begin{pNiceMatrix}[create-medium-nodes, % code-after = {\begin{tikzpicture} % \node [highlight = (2-1)] {} ; @@ -5114,7 +5656,7 @@ c & c & b & a & e % \end{itemize} % % \begin{macrocode} -\cs_new_protected:Nn \@@_find_extremities_of_line:nnnn +\cs_new_protected:Npn \@@_find_extremities_of_line:nnnn #1 #2 #3 #4 { % \end{macrocode} % First, we declare the current cell as ``dotted'' because we forbide @@ -5203,9 +5745,8 @@ c & c & b & a & e % \end{macrocode} % We test wether the initial extremity of the dotted line is an implicit cell % already dotted (by another dotted line). In this case, we can't draw the line -% because we have no Tikz node at the extremity of the arrow (and we can't use -% the ``medium node'' or the ``large node'' because we should use the normal -% node since the extremity is not open). +% because we have no Tikz node at the extremity of the arrow. +% % \begin{macrocode} \cs_if_free:cT { @@ -5275,11 +5816,9 @@ c & c & b & a & e } } % \end{macrocode} -% We test wether the initial extremity of the dotted line is an implicit cell +% 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 (and we can't use -% the ``medium node'' or the ``large node'' because we should use the normal -% node since the extremity is not open). +% because we have no Tikz node at the extremity of the arrow. % \begin{macrocode} \cs_if_free:cT { @@ -5298,12 +5837,12 @@ c & c & b & a & e } % \end{macrocode} % If we have at least one open extremity, we create the ``medium nodes'' in the -% matrix\footnote{We should change this. Indeed, for an open extremity of an -% \emph{horizontal} dotted line, we use the |w|-node, if, it exists, and not the -% ``medium node''.}. We remind that, when used once, the command -% |\@@_create_medium_nodes:| becomes no-op in the current TeX group. +% 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_@@_initial_open_bool \@@_create_medium_nodes: \bool_if:NT \l_@@_final_open_bool \@@_create_medium_nodes: } % \end{macrocode} @@ -5321,25 +5860,31 @@ c & c & b & a & e % 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 |\g_@@_x_initial_dim|, |\g_@@_y_initial_dim|, -% |\g_@@_x_final_dim|, |\g_@@_y_final_dim|. These variables are global for -% technical reasons: we have to do an affectation in an environment -% |{tikzpicture}|. +% 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}|. % \begin{macrocode} -\cs_new_protected:Nn \@@_retrieve_coords:nn +\cs_new_protected:Npn \@@_retrieve_coords:nn #1 #2 { \dim_gzero_new:N \g_@@_x_initial_dim \dim_gzero_new:N \g_@@_y_initial_dim \dim_gzero_new:N \g_@@_x_final_dim \dim_gzero_new:N \g_@@_y_final_dim \begin { tikzpicture } [ remember~picture ] - \tikz@parse@node \pgfutil@firstofone + \@@_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 - \tikz@parse@node \pgfutil@firstofone + \@@_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 ) @@ -5351,96 +5896,69 @@ c & c & b & a & e % \end{macrocode} % % \interitem -% For the horizontal lines with open extremities, we must take into account the -% ``|col|'' nodes created in the environments which have a fixed width of the -% columns. The following command will recompute the $x$-value of the extremities -% in this case (erasing the value computed in |\@@_retrieve_coords:nn|). +% 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:Nn \@@_adjust_with_col_nodes: +\cs_new_protected:Npn \@@_adjust_with_col_nodes: { \bool_if:NT \l_@@_initial_open_bool { - \cs_if_exist:cT - { pgf@sh@ns@nm - \int_use:N \g_@@_env_int - col - 0 } - { - \begin { tikzpicture } [ remember~picture ] - \tikz@parse@node \pgfutil@firstofone - ( nm - \int_use:N \g_@@_env_int - col - 0 ) - \dim_gset:Nn \g_@@_x_initial_dim \pgf@x - \end { tikzpicture } - } - } + \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 { - \cs_if_exist:cT - { - pgf@sh@ns@nm - \int_use:N \g_@@_env_int - col - - \int_use:N \c@jCol - } - { - \begin { tikzpicture } [ remember~picture ] - \tikz@parse@node \pgfutil@firstofone - ( nm - \int_use:N \g_@@_env_int - col - \int_use:N \c@jCol ) - \dim_gset:Nn \g_@@_x_final_dim \pgf@x - \end { tikzpicture } - } - } + \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 } + } } % \end{macrocode} % % \interitem % \begin{macrocode} -\cs_new_protected:Nn \@@_draw_Ldots:nn +\cs_new_protected:Npn \@@_draw_Ldots:nn #1 #2 { \cs_if_free:cT { @@ _ dotted _ #1 - #2 } { \bool_set_false:N \l_@@_impossible_line_bool - \@@_find_extremities_of_line:nnnn { #1 } { #2 } 0 \c_one_int + \@@_find_extremities_of_line:nnnn { #1 } { #2 } 0 1 \bool_if:NF \l_@@_impossible_line_bool \@@_actually_draw_Ldots: } } % \end{macrocode} % % \medskip -% The command |\@@_actually_draw_Ldots:| draws the |Ldots| line using -% |\l_@@_initial_i_int|, |\l_@@_initial_j_int|, |\l_@@_initial_open_bool|, -% |\l_@@_final_i_int|, |\l_@@_final_j_int| and |\l_@@_final_open_bool|. We have -% a dedicated command because if is used also by |\Hdotsfor|. +% The command |\@@_actually_draw_Ldots:| draws the |Ldots| line using the +% following variables: +% \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} +% +% We have a dedicated command because it is used also by |\Hdotsfor|. % \begin{macrocode} -\cs_new_protected:Nn \@@_actually_draw_Ldots: +\cs_new_protected:Npn \@@_actually_draw_Ldots: { \@@_retrieve_coords:xx { \bool_if:NTF \l_@@_initial_open_bool - { -% \end{macrocode} -% If a |w|-node exists we use the |w|-node for the extremity. -% \begin{macrocode} - \cs_if_exist:cTF - { - pgf@sh@ns@nm - - \int_use:N \g_@@_env_int - - \int_use:N \l_@@_initial_i_int - - \int_use:N \l_@@_initial_j_int - w - } - { - w.base~west } - { - medium.base~west } - } - { .base~east } + { - medium.base~west } + { .base~east } } { \bool_if:NTF \l_@@_final_open_bool - { - \cs_if_exist:cTF - { - pgf@sh@ns@nm - - \int_use:N \g_@@_env_int - - \int_use:N \l_@@_final_i_int - - \int_use:N \l_@@_final_j_int - w - } - { - w.base~east } - { - medium.base~east } - } + { - medium.base~east } { .base~west } } \@@_adjust_with_col_nodes: @@ -5460,43 +5978,23 @@ c & c & b & a & e % % \bigskip % \begin{macrocode} -\cs_new_protected:Nn \@@_draw_Cdots:nn +\cs_new_protected:Npn \@@_draw_Cdots:nn #1 #2 { \cs_if_free:cT { @@ _ dotted _ #1 - #2 } { \bool_set_false:N \l_@@_impossible_line_bool - \@@_find_extremities_of_line:nnnn { #1 } { #2 } 0 \c_one_int + \@@_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 - { - \cs_if_exist:cTF - { - pgf@sh@ns@nm - - \int_use:N \g_@@_env_int - - \int_use:N \l_@@_initial_i_int - - \int_use:N \l_@@_initial_j_int - w - } - { - w.mid~west } - { - medium.mid~west } - } + { - medium.mid~west } { .mid~east } } { \bool_if:NTF \l_@@_final_open_bool - { - \cs_if_exist:cTF - { - pgf@sh@ns@nm - - \int_use:N \g_@@_env_int - - \int_use:N \l_@@_final_i_int - - \int_use:N \l_@@_final_j_int - w - } - { - w.mid~east } - { - medium.mid~east } - } + { - medium.mid~east } { .mid~west } } \@@_adjust_with_col_nodes: @@ -5516,12 +6014,12 @@ c & c & b & a & e % command |\@@_retrieve_coords:nn| in the arguments |T| and |F| of the % \pkg{expl3} commands (why?). % \begin{macrocode} -\cs_new_protected:Nn \@@_draw_Vdots:nn +\cs_new_protected:Npn \@@_draw_Vdots:nn #1 #2 { \cs_if_free:cT { @@ _ dotted _ #1 - #2 } { \bool_set_false:N \l_@@_impossible_line_bool - \@@_find_extremities_of_line:nnnn { #1 } { #2 } \c_one_int 0 + \@@_find_extremities_of_line:nnnn { #1 } { #2 } 1 0 \bool_if:NF \l_@@_impossible_line_bool { \@@_retrieve_coords:xx @@ -5578,12 +6076,12 @@ c & c & b & a & e % 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. % \begin{macrocode} -\cs_new_protected:Nn \@@_draw_Ddots:nn +\cs_new_protected:Npn \@@_draw_Ddots:nn #1 #2 { \cs_if_free:cT { @@ _ dotted _ #1 - #2 } { \bool_set_false:N \l_@@_impossible_line_bool - \@@_find_extremities_of_line:nnnn { #1 } { #2 } \c_one_int \c_one_int + \@@_find_extremities_of_line:nnnn { #1 } { #2 } 1 1 \bool_if:NF \l_@@_impossible_line_bool { \@@_retrieve_coords:xx @@ -5609,7 +6107,7 @@ c & c & b & a & e % We test if the diagonal line is the first one (the counter |\l_@@_ddots_int| % is created for this usage). % \begin{macrocode} - \int_compare:nNnTF \l_@@_ddots_int = \c_one_int + \int_compare:nNnTF \l_@@_ddots_int = 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 @@ -5648,7 +6146,7 @@ c & c & b & a & e % \bigskip % We draw the |\Iddots| diagonals in the same way. % \begin{macrocode} -\cs_new_protected:Nn \@@_draw_Iddots:nn +\cs_new_protected:Npn \@@_draw_Iddots:nn #1 #2 { \cs_if_free:cT { @@ _ dotted _ #1 - #2 } { @@ -5670,7 +6168,7 @@ c & c & b & a & e \bool_if:NT \l_@@_parallelize_diags_bool { \int_incr:N \l_@@_iddots_int - \int_compare:nNnTF \l_@@_iddots_int = \c_one_int + \int_compare:nNnTF \l_@@_iddots_int = 1 { \dim_set:Nn \l_@@_delta_x_two_dim { \g_@@_x_final_dim - \g_@@_x_initial_dim } @@ -5705,7 +6203,7 @@ c & c & b & a & e % \end{macrocode} % % \bigskip -% \subsection{The actual instructions for drawing the dotted line with Tikz} +% \subsection*{The actual instructions for drawing the dotted line with Tikz} % % The command |\@@_draw_tikz_line:| draws the line using four implicit % arguments: @@ -5715,7 +6213,7 @@ c & c & b & a & e % first affectation was in an instruction |\tikz|. % % \begin{macrocode} -\cs_new_protected:Nn \@@_draw_tikz_line: +\cs_new_protected:Npn \@@_draw_tikz_line: { % \end{macrocode} % The dimension |\l_@@_l_dim| is the length $\ell$ of the line to draw. We use @@ -5777,7 +6275,7 @@ c & c & b & a & e \int_set:Nn \l_tmpa_int { \dim_ratio:nn - { \l_@@_l_dim - ( \l_@@_dotted_lines_margin_dim * 2 ) } + { \l_@@_l_dim - ( 2 \l_@@_dotted_lines_margin_dim ) } \l_@@_inter_dots_dim } } @@ -5811,10 +6309,9 @@ c & c & b & a & e { \bool_if:NTF \l_@@_final_open_bool 2 1 } } % \end{macrocode} -% In the loop over the dots (|\int_step_inline:nnnn|), the dimensions -% |\g_@@_x_initial_dim| and |\g_@@_y_initial_dim| will be used for the -% coordinates of the dots. But, before the loop, we must move until the -% first dot. +% 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, +% before the loop, we must move until the first dot. % % \begin{macrocode} \dim_gadd:Nn \g_@@_x_initial_dim @@ -5822,20 +6319,16 @@ c & c & b & a & e ( \g_@@_x_final_dim - \g_@@_x_initial_dim ) * \dim_ratio:nn { \l_@@_l_dim - \l_@@_inter_dots_dim * \l_tmpa_int } - { \l_@@_l_dim * 2 } + { 2 \l_@@_l_dim } * \l_tmpb_int } -% \end{macrocode} -% (In a multiplication of a dimension and an integer, the integer must always be -% put in second position.) -% \begin{macrocode} \dim_gadd:Nn \g_@@_y_initial_dim { ( \g_@@_y_final_dim - \g_@@_y_initial_dim ) * \dim_ratio:nn { \l_@@_l_dim - \l_@@_inter_dots_dim * \l_tmpa_int } - { \l_@@_l_dim * 2 } * - \l_tmpb_int + { 2 \l_@@_l_dim } + * \l_tmpb_int } \begin { tikzpicture } [ overlay ] \int_step_inline:nnn 0 \l_tmpa_int @@ -5852,7 +6345,8 @@ c & c & b & a & e } % \end{macrocode} % -% \subsection{User commands available in the new environments} +% \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). @@ -5865,12 +6359,10 @@ c & c & b & a & e % \end{macrocode} % % \interitem -% The command |\@@_add_to_empty_cells:| adds the current cell to -% |\g_@@_empty_cells_seq| which is the list of the empty cells (the cells -% explicitly declared ``empty'': there may be, of course, other empty cells in -% the matrix). +% 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:Nn \@@_add_to_empty_cells: +\cs_new_protected:Npn \@@_add_to_empty_cells: { \cs_gset:cpx { @@ _ empty _ \int_use:N \c@iRow - \int_use:N \c@jCol } @@ -5939,7 +6431,7 @@ c & c & b & a & e % \bigskip % The command |\@@_Hspace:| will be linked to |\hspace| in |{NiceArray}|. % \begin{macrocode} -\cs_new_protected:Nn \@@_Hspace: +\cs_new_protected:Npn \@@_Hspace: { \@@_add_to_empty_cells: \hspace @@ -5967,14 +6459,15 @@ c & c & b & a & e % % % \bigskip -% The command |\@@_Hdotsfor| will be linked to |\Hdotsfor| in |{NiceArray}|. -% This command uses an optional argument like |\hdotsfor| but this argument is -% discarded (in |\hdotsfor|, this argument is used for fine tuning of the space -% between two consecutive dots). Tikz nodes are created for all the cells of -% the array, even the implicit cells of the |\Hdotsfor|. +% The command |\@@_Hdotsfor| will be linked to |\Hdotsfor| in +% |{NiceArrayWithDelims}|. This command uses an optional argument (as does +% |\hdotsfor|) but this argument is discarded (in |\hdotsfor|, this argument is +% used for fine tuning of the space between two consecutive dots). Tikz nodes +% are created for all the cells of the array, even the implicit cells of the +% |\Hdotsfor|. % % \medskip -% This command must not be protected since it begins with |\multicolumn|. +% This command must \emph{not} be protected since it begins with |\multicolumn|. % \begin{macrocode} \cs_new:Npn \@@_Hdotsfor: { @@ -5984,7 +6477,7 @@ c & c & b & a & e % \end{macrocode} % % The command |\@@_Hdotsfor_i| is defined with the tools of \pkg{xparse} because -% it has an optionnal argument. Note that such a command defined by +% it has an optional argument. Note that such a command defined by % |\NewDocumentCommand| is protected and that's why we have put the % |\multicolumn| before (in the definition of |\@@_Hdotsfor:|). % \begin{macrocode} @@ -5998,10 +6491,10 @@ c & c & b & a & e { \tl_gput_right:Nx \g_@@_Hdotsfor_lines_tl { - \@@_draw_Hdotsfor:nnn - { \int_use:N \c@iRow } + \@@_Hdotsfor:nnn + { \int_use:N \c@iRow } { \int_use:N \c@jCol } - { #2 } + { #2 } } \prg_replicate:nn { #2 - 1 } { & \multicolumn { 1 } { C } { } } } @@ -6010,7 +6503,7 @@ c & c & b & a & e % % \medskip % \begin{macrocode} -\cs_new_protected:Nn \@@_draw_Hdotsfor:nnn +\cs_new_protected:Npn \@@_Hdotsfor:nnn #1 #2 #3 { \bool_set_false:N \l_@@_initial_open_bool \bool_set_false:N \l_@@_final_open_bool @@ -6032,7 +6525,7 @@ c & c & b & a & e \@@_if_not_empty_cell:nnTF \l_@@_initial_i_int \l_tmpa_int { \int_set:Nn \l_@@_initial_j_int { #2 - 1 } } { - \int_set:Nn \l_@@_initial_j_int {#2} + \int_set:Nn \l_@@_initial_j_int { #2 } \bool_set_true:N \l_@@_initial_open_bool } } @@ -6052,8 +6545,23 @@ c & c & b & a & e } \bool_if:nT { \l_@@_initial_open_bool || \l_@@_final_open_bool } \@@_create_medium_nodes: - \@@_actually_draw_Ldots: % \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: + \group_end: +% \end{macrocode} +% +% \medskip % We declare all the cells concerned by the |\Hdotsfor| as ``dotted'' (for the % dotted lines created by |\Cdots|, |\Ldots|, etc., this job is done by % |\@@_find_extremities_of_line:nnnn|). This declaration is done by defining a @@ -6065,11 +6573,28 @@ c & c & b & a & e % \end{macrocode} % % +% \bigskip +% The control sequence |\@@_rotate:| will be linked to |\rotate| in +% |{NiceArrayWithDelims}|. +% +% The command will exit three levels of groups in order +% to execute the command +% +% \qquad ``|\box_rotate:Nn \l_@@_cell_box { 90 }|'' +% +% just after the construction of the box |\l_@@_cell_box|. +% \begin{macrocode} +\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 } } +% \end{macrocode} % -% \subsection{The command \textbackslash line accessible in code-after} +% \bigskip +% \subsection*{The command \textbackslash line accessible in code-after} % % In the |code-after|, the command |\@@_line:nn| will be linked to |\line|. This -% command takes two arguments which are the specification of two cells in the +% command takes two arguments which are the specifications of two cells in the % array (in the format $i$-$j$) and draws a dotted line between these cells. % % \medskip @@ -6101,7 +6626,7 @@ c & c & b & a & e % \end{macrocode} % % \begin{macrocode} -\cs_new_protected:Nn \@@_line_i:nn +\cs_new_protected:Npn \@@_line_i:nn #1 #2 { \bool_if:NF \c_@@_draft_bool { @@ -6120,10 +6645,10 @@ c & c & b & a & e { \begin { tikzpicture } \path~(#1)~--~(#2)~node[at~start]~(i)~{}~node[at~end]~(f)~{} ; - \tikz@parse@node \pgfutil@firstofone ( i ) + \@@_extract_coords:w ( i ) \dim_gset:Nn \g_@@_x_initial_dim \pgf@x \dim_gset:Nn \g_@@_y_initial_dim \pgf@y - \tikz@parse@node \pgfutil@firstofone ( f ) + \@@_extract_coords:w ( f ) \dim_gset:Nn \g_@@_x_final_dim \pgf@x \dim_gset:Nn \g_@@_y_final_dim \pgf@y \end { tikzpicture } @@ -6142,251 +6667,93 @@ c & c & b & a & e % this command because they have to do other settings (for example, the diagonal % lines must be parallelized). % -% \bigskip -% \subsection{The commands to draw dotted lines to separate columns and rows} % -% The command |\hdottedline| draws an horizontal dotted line to separate two -% rows. Similarly, the letter ``:'' in the preamble draws a vertical dotted line -% (the letter can be changed with the option |letter-for-dotted-lines|). Both -% mechanisms write instructions in the |code-after|. The actual instructions in -% the |code-after| use the commands |\@@_hdottedline:n| and |\@@_vdottedline:n|. -% % \bigskip -% We want the horizontal lines at the same position\footnote{In fact, almost the -% same position because of the width of the line: the width of a dotted line is -% not the same as the width of a line created by |\hline|.} as the line created -% by |\hline| (or |\hdashline| of \pkg{arydshln}). That's why we use a -% |\noalign| to insert a box with a |\dotfill|. +% \subsection*{The vertical rules} % -% -% -% \medskip -% Some extensions, like the extension \pkg{doc}, do a redefinition of the -% command |\dotfill| of LaTeX. That's why we define a command |\@@_dotfill:| as -% we wish. We test whether we are in draft mode because, in this case, we don't -% draw the dotted lines. -% \begin{macrocode} -\bool_if:NTF \c_@@_draft_bool - { \cs_set_eq:NN \@@_dotfill: \prg_do_nothing: } - { - \cs_set:Npn \@@_dotfill: - { -% \end{macrocode} -% If the option |small| is used, we change the space between dots (we can't -% use |\l_@@_inter_dots_dim| which will be set after the construction of the -% array). We can't put the |\bool_if:NT| in the first argument of -% |\hbox_to_wd:nn| because |\cleaders| is a special TeX primitive. +% We give to the user the possibility to define new types of columns (with +% |\newcolumntype| of \pkg{array}) for special vertical rules (\emph{e.g.} rules +% thicker than the standard ones) which will not extend in the potential +% exterior rows of the array. +% +% We provide the command |\OnlyMainNiceMatrix| in that goal. However, that +% command must be no-op outside the environments of \pkg{nicematrix} (and so the +% user will be allowed to use the same new type of column in the environments +% of \pkg{nicematrix} and in the standard environments of \pkg{array}). +% +% That's why we provide first a global definition of |\OnlyMainNiceMatrix|. % \begin{macrocode} - \bool_if:NT \l_@@_small_bool - { \dim_set:Nn \l_@@_inter_dots_dim { 0.25 em } } - \cleaders - \hbox_to_wd:nn - { \l_@@_inter_dots_dim } - { - \c_math_toggle_token - \bool_if:NT \l_@@_small_bool \scriptstyle - \hss . \hss - \c_math_toggle_token - } - \hfill - } - } +\cs_set_eq:NN \OnlyMainNiceMatrix \use:n % \end{macrocode} -% -% This command must \emph{not} be protected because it starts with |\noalign|. +% +% \medskip +% Another definition of |\OnlyMainNiceMatrix| will be linked to the command in +% the environments of \pkg{nicematrix}. Here is that definition, called +% |\@@_OnlyMainNiceMatrix:n|. +% % \begin{macrocode} -\cs_new:Npn \@@_hdottedline: - { - \noalign +\cs_new_protected:Npn \@@_OnlyMainNiceMatrix:n #1 + { + \int_compare:nNnTF \l_@@_first_col_int = 0 + { \@@_OnlyMainNiceMatrix_i:n { #1 } } { - \bool_gset_true:N \g_@@_large_nodes_bool - \cs_if_exist:cTF { @@_width_ \int_use:N \g_@@_env_int } - { \dim_set_eq:Nc \l_tmpa_dim { @@_width_ \int_use:N \g_@@_env_int } } - { \dim_set:Nn \l_tmpa_dim { 5 mm } } - \hbox_overlap_right:n + \int_compare:nNnTF \c@jCol = 0 { - \bool_if:nT - { - \l_@@_NiceArray_bool - && - ! \l_@@_exterior_arraycolsep_bool - && - \int_compare_p:nNn \l_@@_first_col_int > 0 - } - { \skip_horizontal:n { - \arraycolsep } } - \hbox_to_wd:nn - { - \l_tmpa_dim + 2 \arraycolsep - - \l_@@_left_margin_dim - \l_@@_right_margin_dim - } - \@@_dotfill: + \int_compare:nNnF \c@iRow = { -1 } + { \int_compare:nNnF \c@iRow = { \l_@@_last_row_int - 1 } { #1 } } } - } - } + { \@@_OnlyMainNiceMatrix_i:n { #1 } } + } + } % \end{macrocode} +% This definition may seem complicated by we must remind that the number of row +% |\c@iRow| is incremented in the first cell of the row, \emph{after} an +% potential vertical rule on the left side of the first cell. % -% \bigskip -% \begin{macrocode} -\cs_new_protected:Nn \@@_vdottedline:n +% \smallskip +% The command |\@@_OnlyMainNiceMatrix_i:n| is only a short-cut which is used +% twice in the above command. This command must \emph{not} be protected. +% % \begin{macrocode} +\cs_new_protected:Npn \@@_OnlyMainNiceMatrix_i:n #1 { -% \end{macrocode} -% We should allow the letter ``|:|'' in the first position of the preamble -% but that would need a special programmation. -% \begin{macrocode} - \int_compare:nNnTF #1 = 0 - { \@@_error:n { Use~of~:~in~first~position } } - { - \bool_if:NF \c_@@_draft_bool - { - \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 -% \end{macrocode} -% If a ``|col|'' node exists (if the array has been constructed with a fixed -% width of column), we use it. -% \begin{macrocode} - \cs_if_exist:cTF - { pgf@sh@ns@nm -\int_use:N \g_@@_env_int - col - #1 } - { - \begin { tikzpicture } [ remember~picture ] - \tikz@parse@node\pgfutil@firstofone - ( col - #1 ) - \dim_gset:Nn \g_@@_x_initial_dim \pgf@x - \dim_gset:Nn \g_@@_x_final_dim \pgf@x - \dim_gset:Nn \g_@@_y_final_dim \pgf@y - \end { tikzpicture } - \dim_gset:Nn \g_@@_y_initial_dim { - \c_max_dim } - \int_step_inline:nn \c@jCol - { - \begin { tikzpicture } [ remember~picture ] - \tikz@parse@node\pgfutil@firstofone - ( 1 - ##1 . north~east ) - \dim_gset:Nn \g_@@_y_initial_dim - { \dim_max:nn \g_@@_y_initial_dim \pgf@y } - \end { tikzpicture } - } - } -% \end{macrocode} -% If not, we use the ``large node''. -% \begin{macrocode} - { - \begin { tikzpicture } [ remember~picture ] - \tikz@parse@node\pgfutil@firstofone - ( 1 - #1 - large .north~east ) - \dim_gset:Nn \g_@@_x_initial_dim \pgf@x - \dim_gset:Nn \g_@@_y_initial_dim \pgf@y - \tikz@parse@node\pgfutil@firstofone - ( \int_use:N \c@iRow - #1 - large .south~east ) - \dim_gset:Nn \g_@@_x_final_dim \pgf@x - \dim_gset:Nn \g_@@_y_final_dim \pgf@y - \end { tikzpicture } -% \end{macrocode} -% However, if the previous column was constructed with a letter |w|, we use the -% |w|-nodes (and we erase the previous computation of the $x$-value of the -% vertical dotted line). -% \begin{macrocode} - \cs_if_exist:cT - { pgf@sh@ns@nm -\int_use:N \g_@@_env_int - 1 - #1 - w } - { - \begin { tikzpicture } [ remember~picture ] - \tikz@parse@node\pgfutil@firstofone - ( 1 - #1 - w .north~east ) - \dim_gset:Nn \g_@@_x_initial_dim \pgf@x - \tikz@parse@node\pgfutil@firstofone - ( \int_use:N \c@iRow - #1 - w .south~east ) - \dim_gset:Nn \g_@@_x_final_dim \pgf@x - \end { tikzpicture } - \dim_gadd:Nn \g_@@_x_initial_dim \arraycolsep - \dim_gadd:Nn \g_@@_x_final_dim \arraycolsep - } - } - \@@_draw_tikz_line: - } - } + \int_compare:nNnF \c@iRow = 0 + { \int_compare:nNnF \c@iRow = \l_@@_last_row_int { #1 } } } % \end{macrocode} +% Remember that |\c@iRow| is not always inferior to |\l_@@_last_row_int| because +% |\l_@@_last_row_int| may be equal to $-2$ or $-1$ (we can't write +% |\int_compare:nNnT \c@iRow < \l_@@_last_row_int|). % +% +% \medskip +% In fact, independently of |\OnlyMainNiceMatrix|, which is a convenience given +% to the user, we have to modify the behaviour of the standard specifier ``"|"''. % -% \bigskip -% \subsection{The vertical rules} -% -% We don't want that a vertical rule drawn by the specifier ``"|"'' extends -% in the eventual ``first row'' and ``last row'' of the array. % -% The natural way to do that would be to redefine the specifier ``"|"'' -% with |\newcolumntype|: +% Remark first that the natural way to do that would be to redefine the +% specifier ``"|"'' with |\newcolumntype|: % \begin{Verbatim}[commandchars=\~\#\+] -% \newcolumntype { | } -% { ! { \int_compare:nNnF \c@iRow = 0 \vline } } +% \newcolumntype { | } { ! { \OnlyMainNiceMatrix \vline } } % \end{Verbatim} % % However, this code fails if the user uses "\DefineShortVerb{\|}" of % \pkg{fancyvrb}. Moreover, it would not be able to deal correctly with two % consecutive specifiers ``"|"'' (in a preambule like "ccc||ccc"). % -% That's why we will do a redefinition of the macro |\@arrayrule| of \pkg{array} -% and this redefinition will add |\@@_vline:| instead of |\vline| to the -% preamble. +% That's why we have done a redefinition of the macro |\@arrayrule| of +% \pkg{array} and this redefinition will add |\@@_vline:| instead of |\vline| to +% the preamble (that definition is in the beginning of |{NiceArrayWithDelims}|). % % Here is the definition of |\@@_vline:|. This definition \emph{must} be % protected because you don't want that macro expanded during the construction -% of the preamble (the tests must be effective in each row and not once when the -% preamble is constructed). -% \begin{macrocode} -\cs_new_protected:Npn \@@_vline: - { - \int_compare:nNnTF \l_@@_first_col_int = 0 - { - \int_compare:nNnTF \c@jCol = 0 - { - \int_compare:nNnTF \l_@@_first_row_int = 0 - { - \int_compare:nNnF \c@iRow = 0 - { - \int_compare:nNnF \c@iRow = \l_@@_last_row_int - \@@_vline_i: - } - } - { - \int_compare:nNnF \c@iRow = 0 - { - \int_compare:nNnF \c@iRow = \l_@@_last_row_int - \@@_vline_i: - } - } - } - { - \int_compare:nNnF \c@iRow = 0 - { - \int_compare:nNnF \c@iRow = \l_@@_last_row_int - \@@_vline_i: - } - } - } - { - \int_compare:nNnTF \c@jCol = 0 - { - \int_compare:nNnF \c@iRow = { -1 } - { - \int_compare:nNnF \c@iRow = { \l_@@_last_row_int - 1 } - \@@_vline_i: - } - } - { - \int_compare:nNnF \c@iRow = 0 - { - \int_compare:nNnF \c@iRow = \l_@@_last_row_int - \@@_vline_i: - } - } - } - } -% \end{macrocode} +% of the preamble (the tests in |\@@_OnlyMainNiceMatrix:n| must be effective in +% each row and not once for all when the preamble is constructed). % % \medskip +% \begin{macrocode} +\cs_new_protected:Npn \@@_vline: { \@@_OnlyMainNiceMatrix:n { \@@_vline_i: } } +% \end{macrocode} +% % If \pkg{colortbl} is loaded, the following macro will be redefined (in a % |\AtBeginDocument|) to take into account the color fixed by |\arrayrulecolor| % of \pkg{colortbl}. @@ -6395,35 +6762,129 @@ c & c & b & a & e % \end{macrocode} % % \bigskip -% We give now the definition of |\OnlyMainNiceMatrix|. Internally, it is not -% used by \pkg{nicematrix}. It's only a facility given to the final user, which -% may be useful in the definitions of new columns types (with |\newcolumntype|). +% \subsection*{The commands to draw dotted lines to separate columns and rows} % -% \smallskip -% First, we give the definition of |\OnlyMainNiceMatrix| in the general case: -% it's no-op (thus, a definition of column type may be used outside the -% environments of \pkg{nicematrix}, in |{array}|, etc.). +% These commands don't use the normal nodes, the medium nor the large nodes. +% They only use the |col|-nodes and the |row|-nodes. +% +% \textbf{Horizontal dotted lines}\par\nobreak +% +% \medskip +% The following command must \emph{not} be protected because it's meant to be +% expanded in a |\noalign|. % \begin{macrocode} -\cs_set_eq:NN \OnlyMainNiceMatrix \use:n +\cs_new:Npn \@@_hdottedline: + { + \bool_if:NF \c_@@_draft_bool + { + \noalign{ \skip_vertical:n { 2 \l_@@_radius_dim } } + \@@_hdottedline_i: + } + } +% \end{macrocode} +% +% \medskip +% On the other side, the following command should be protected. +% \begin{macrocode} +\cs_new_protected:Npn \@@_hdottedline_i: + { +% \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). +% \begin{macrocode} + \tl_gput_right:Nx \g_@@_code_after_tl + { \@@_hdottedline:n { \int_use:N \c@iRow } } + } % \end{macrocode} % +% % \medskip -% Now, we give the definition of |\OnlyMainNiceMatrix| which will be used -% in the environments of \pkg{nicematrix}. This command -% |\@@_OnlyMainNiceMatrix:n| will be linked to |\OnlyMainNiceMatrix| in -% |\@@_pre_array:|. This command is ``fully expandable'' and that's why we have -% not protected it, even tough this characteristic will probably not be used. +% The command |\@@_hdottedline:n| is the command written in the |code-after| +% 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:Npn \@@_OnlyMainNiceMatrix:n #1 +\cs_new_protected:Npn \@@_hdottedline:n #1 { - \int_compare:nNnF \c@iRow = 0 - { \int_compare:nNnF \c@iRow = \l_@@_last_row_int { #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 ) +% \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: + } +% \end{macrocode} +% +% +% +% \bigskip +% \textbf{Vertical dotted lines}\par\nobreak +% +% \medskip +% \begin{macrocode} +\cs_new_protected:Npn \@@_vdottedline:n #1 + { +% \end{macrocode} +% We should allow the letter ``|:|'' in the first position of the preamble +% but that would need a special programmation. +% \begin{macrocode} + \int_compare:nNnTF #1 = 0 + { \@@_error:n { Use~of~:~in~first~position } } + { \bool_if:NF \c_@@_draft_bool { \@@_vdottedline_i:n { #1 } } } } % \end{macrocode} % +% \medskip +% \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} +% 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 ) +% \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: + } +% \end{macrocode} +% +% % % \bigskip -% \subsection{The environment \{NiceMatrixBlock\}} +% \subsection*{The environment \{NiceMatrixBlock\}} % % The following flag will be raised when all the columns of the environments of % the block must have the same width in ``auto'' mode. @@ -6485,8 +6946,8 @@ c & c & b & a & e } % \end{macrocode} % -% -% \subsection{The extra nodes} +% \bigskip +% \subsection*{The extra nodes} % % First, two variants of the functions |\dim_min:nn| and |\dim_max:nn|. % \begin{macrocode} @@ -6495,10 +6956,10 @@ c & c & b & a & e % \end{macrocode} % % \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. +% 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. % % \bigskip % We have to compute the mathematical coordinates of the ``medium nodes''. These @@ -6509,6 +6970,7 @@ c & c & b & a & e % \bigskip % The command |\@@_computations_for_medium_nodes:| must be used in a % |{tikzpicture}|. +% % \medskip % For each row $i$, we compute two dimensions % \texttt{l_@@_row_\textsl{i}_min_dim} and \texttt{l_@@_row_\textsl{i}_max_dim}. @@ -6555,14 +7017,15 @@ c & c & b & a & e % implicit ampersands |&|). In this case, of course, we don't update the % dimensions we want to compute. % \begin{macrocode} - { \cs_if_exist:cT + { + \cs_if_exist:cT { pgf@sh@ns@nm - \int_use:N \g_@@_env_int - \@@_i: - \@@_j: } % \end{macrocode} % We retrieve the coordinates of the anchor |south west| of the (normal) node of % the cell ($i$-$j$). They will be stored in |\pgf@x| and |\pgf@y|. % \begin{macrocode} { - \tikz@parse@node \pgfutil@firstofone + \@@_extract_coords:w ( nm - \int_use:N \g_@@_env_int - \@@_i: - \@@_j: .south~west ) \dim_set:cn { l_@@_row_\@@_i: _min_dim} @@ -6576,7 +7039,7 @@ c & c & b & a & e % We retrieve the coordinates of the anchor |north east| of the (normal) node of % the cell ($i$-$j$). They will be stored in |\pgf@x| and |\pgf@y|. % \begin{macrocode} - \tikz@parse@node \pgfutil@firstofone + \@@_extract_coords:w ( nm - \int_use:N \g_@@_env_int - \@@_i: - \@@_j: .north~east ) \dim_set:cn { l_@@_row _ \@@_i: _ max_dim } { \dim_max:vn { l_@@_row _ \@@_i: _ max_dim } \pgf@y } @@ -6620,10 +7083,10 @@ c & c & b & a & e % \medskip % The command |\@@_create_large_nodes:| must be used when we want to create only % the ``large nodes'' and not the medium ones (if we want to create both, we -% have to use the command |\@@_create_medium_and_large_nodes:|). However, the +% have to use |\@@_create_medium_and_large_nodes:|). However, the % computation of the mathematical coordinates of the ``large nodes'' needs the -% computation of the mathematical coordinates of the ``medium nodes''. That's -% why we use first |\@@_computations_for_medium_nodes:| and then the command +% computation of the mathematical coordinates of the ``medium nodes''. Hence, +% we use first |\@@_computations_for_medium_nodes:| and then the command % |\@@_computations_for_large_nodes:|. % \begin{macrocode} \cs_new_protected:Npn \@@_create_large_nodes: @@ -6634,7 +7097,6 @@ c & c & b & a & e \tikzset { name~suffix = -large } \@@_create_nodes: \end { tikzpicture } - \@@_compute_width_of_array: \cs_set_protected:Npn \@@_create_large_nodes: { } \cs_set_protected:Npn \@@_create_medium_and_large_nodes: { \@@_create_medium_nodes: } @@ -6656,9 +7118,7 @@ c & c & b & a & e \@@_computations_for_large_nodes: \tikzset { name~suffix = -large } \@@_create_nodes: - \@@_compute_width_of_array: \end { tikzpicture } - \@@_compute_width_of_array: \cs_set_protected:Npn \@@_create_medium_and_large_nodes: { } \cs_set_protected:Npn \@@_create_medium_nodes: { } \cs_set_protected:Npn \@@_create_large_nodes: { } @@ -6780,37 +7240,10 @@ c & c & b & a & e } % \end{macrocode} % -% -% -% \medskip -% We can now compute the width of the array (used by |\hdottedline|). We should -% modify this point because it's a waste to construct all the ``large nodes'' only -% for computing the width of the array. -% \begin{macrocode} -\cs_new_protected:Npn \@@_compute_width_of_array: - { - \begin { tikzpicture } [ remember~picture , overlay ] - \tikz@parse@node \pgfutil@firstofone - ( nm - \int_use:N \g_@@_env_int - 1 - 1 - large .north~west ) - \dim_gset:Nn \g_tmpa_dim \pgf@x - \tikz@parse@node \pgfutil@firstofone - ( nm - \int_use:N \g_@@_env_int - 1 - - \int_use:N \c@jCol - large .north~east ) - \dim_gset:Nn \g_tmpb_dim \pgf@x - \end { tikzpicture } - \iow_now:Nn \@mainaux \ExplSyntaxOn - \iow_now:Nx \@mainaux - { - \cs_gset:cpn { @@_width_ \int_use:N \g_@@_env_int } - { \dim_eval:n { \g_tmpb_dim - \g_tmpa_dim } } - } - \iow_now:Nn \@mainaux \ExplSyntaxOff - } -% \end{macrocode} % % \bigskip % \begin{macrocode} -\cs_new_protected:Npn \@@_extract_coords: #1 - #2 \q_stop +\cs_new_protected:Npn \@@_extract_coords_values: #1 - #2 \q_stop { \cs_set:Npn \@@_i: { #1 } \cs_set:Npn \@@_j: { #2 } @@ -6822,9 +7255,9 @@ c & c & b & a & e % issued in the format $i$|-|$j$ and the second is the value of~$n$ (the length % of the ``multi-cell''). % \begin{macrocode} -\cs_new_protected:Nn \@@_node_for_multicolumn:nn +\cs_new_protected:Npn \@@_node_for_multicolumn:nn #1 #2 { - \@@_extract_coords: #1 \q_stop + \@@_extract_coords_values: #1 \q_stop \coordinate ( @@~south~west ) at ( \dim_use:c { l_@@_column _ \@@_j: _ min _ dim } , @@ -6849,58 +7282,40 @@ c & c & b & a & e } % \end{macrocode} % -% -% \subsection{Block matrices} +% \bigskip +% \subsection*{Block matrices} % % The code in this section if for the construction of \emph{block matrices}. It % has no direct link with the environment |{NiceMatrixBlock}|. +% % % The following command will be linked to |\Block| in the environments of % \pkg{nicematrix}. We define it with |\NewDocumentCommand| of \pkg{xparse} -% because it has an optionnal argument between |<| and |>| (for TeX instructions +% because it has an optional argument between |<| and |>| (for TeX instructions % put before the math mode of the label) % % \begin{macrocode} -\NewDocumentCommand \@@_Block: { m D < > { } m } - { \@@_Block_i #1 \q_stop { #2 } { #3 } } +\NewDocumentCommand \@@_Block: { O { } m D < > { } m } + { \@@_Block_i #2 \q_stop { #1 } { #3 } { #4 } } % \end{macrocode} % % \medskip -% The first argument of |\@@_Block:| (which is required) has a special syntax. -% It must be of the form $i$|-|$j$ where $i$ and $j$ are the size (in rows and -% columns) of the block. +% The first mandatory argument of |\@@_Block:| has a special syntax. It must be +% of the form $i$|-|$j$ where $i$ and $j$ are the size (in rows and columns) of +% the block. % \begin{macrocode} -\cs_new:Npn \@@_Block_i #1-#2 \q_stop { \@@_Block_ii:nnnn { #1 } { #2 } } +\cs_new:Npn \@@_Block_i #1-#2 \q_stop { \@@_Block_ii:nnnnn { #1 } { #2 } } % \end{macrocode} % % \medskip % Now, the arguments have been extracted: |#1| is $i$ (the number of rows of the -% block), |#2| is $j$ (the number of columns of the block), |#3| are the tokens -% to put before the math mode and |#4| is the label of the block. The following -% command must \emph{not} be protected because it contains a command -% |\multicolumn| (in the case of a block of only one row). +% block), |#2| is $j$ (the number of columns of the block), |#3| is the list of +% key-values, |#4| are the tokens to put before the math mode and |#5| is the +% label of the block. % \begin{macrocode} -\cs_new:Npn \@@_Block_ii:nnnn #1 #2 #3 #4 +\cs_new_protected:Npn \@@_Block_ii:nnnnn #1 #2 #3 #4 #5 { % \end{macrocode} -% -% \medskip -% In the case of a block of only one row, we create a special node of shape -% |coordinate| in order to remember the $y$-value of the baseline of the current -% row. -% \begin{macrocode} - \int_compare:nNnT { #1 } = 1 - { - \begin { tikzpicture } [ remember~picture , baseline ] - \coordinate - ( nm - \int_use:N \g_@@_env_int - - Block - - \int_use:N \c@iRow - - \int_use:N \c@jCol ) ; - \end { tikzpicture } - } - \bool_gset_true:N \g_@@_medium_nodes_bool -% \end{macrocode} % We write an instruction in the |code-after|. We write the instruction in the % beginning of the |code-after| (the |left| in |\tl_gput_left:Nx|) because we % want the Tikz nodes corresponding of the block created \emph{before} potential @@ -6909,23 +7324,57 @@ c & c & b & a & e % \begin{macrocode} \tl_gput_left:Nx \g_@@_code_after_tl { - \@@_Block_iii:nnnnn + \@@_Block_iii:nnnnnn { \int_use:N \c@iRow } { \int_use:N \c@jCol } { \int_eval:n { \c@iRow + #1 - 1 } } { \int_eval:n { \c@jCol + #2 - 1 } } - \exp_not:n { { #3 $ #4 $ } } + { #3 } + \exp_not:n { { #4 $ #5 $ } } } +% \end{macrocode} +% It's not allowed to use the command |\Block| twice in the same cell of the +% array. That's why, at the first use, we link the command |\Block| +% to a special version. The scope of this link is the cell of the array. +% \begin{macrocode} + \cs_set_eq:NN \Block \@@_Block_error:nn } % \end{macrocode} % +% \begin{macrocode} +\cs_new:Npn \@@_Block_error:nn #1 #2 + { + \@@_error:n { Second~Block } + \cs_set_eq:NN \Block \use:nn + } +% \end{macrocode} % +% \medskip +% \begin{macrocode} +\keys_define:nn { NiceMatrix / Block } + { + tikz .tl_set:N = \l_@@_tikz_tl , + tikz .value_required:n = true , + white .bool_set:N = \l_@@_white_bool , + white .default:n = true , + white .value_forbidden:n = true , + } +% \end{macrocode} +% % % \medskip -% The following command |\@@_Block_iii:nnnnn| will be used in the |code-after|. +% The following command |\@@_Block_iii:nnnnnn| will be used in the |code-after|. % \begin{macrocode} -\cs_new_protected:Npn \@@_Block_iii:nnnnn #1 #2 #3 #4 #5 +\cs_new_protected:Npn \@@_Block_iii:nnnnnn #1 #2 #3 #4 #5 #6 { +% \end{macrocode} +% The group is for the keys. +% \begin{macrocode} + \group_begin: + \keys_set:nn { NiceMatrix / Block } { #5 } +% \end{macrocode} +% +% \begin{macrocode} \bool_if:nTF { \int_compare_p:nNn { #3 } > \c@iRow @@ -6934,59 +7383,118 @@ c & c & b & a & e { \msg_error:nnnn { nicematrix } { Block~too~large } { #1 } { #2 } } { % \end{macrocode} -% If the block has only one row, we have to do a special work in order to have -% the contains of the node aligned with the contents of the other rows of the array. -% +% We put the contents of the cell in the box |\l_@@_cell_box| because we want +% the command |\rotate| used in the content to be able to rotate the box. % \begin{macrocode} - \int_compare:nNnTF { #1 } = { #3 } - { - \begin { tikzpicture } + \hbox_set:Nn \l_@@_cell_box { #6 } +% \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|. +% \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 } ) + \dim_set_eq:NN \l_tmpa_dim \pgf@y + \@@_extract_coords:w ( col - \int_eval:n { #4 + 1 } ) + \dim_set_eq:NN \l_tmpb_dim \pgf@x + \coordinate ( two ) at ( \l_tmpb_dim , \l_tmpa_dim ) ; +% \end{macrocode} +% +% \begin{macrocode} + \bool_if:NT \l_@@_white_bool + { + \fill [ white , line~width = 0 pt] + ( [ yshift = -\arrayrulewidth ] one ) + rectangle + ( [ xshift = -\arrayrulewidth ] two ) ; + } % \end{macrocode} -% First, we compute in |\l_tmpa_dim| the $y$-value of the baseline of the row. -% We have constructed a special node of shape |coordinate| in this order. +% +% 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} - \tikz@parse@node \pgfutil@firstofone (Block-#1-#2) - \dim_set:Nn \l_tmpa_dim \pgf@y - \node + \use:x + { + \exp_not:N \node [ - fit = ( #1 - #2 - medium . north~west ) - ( #3 - #4 - medium . south~east ) , + fit = ( one ) ( two ) , inner~sep = 0 pt , + \l_@@_tikz_tl ] - (#1-#2) { } ; + } % \end{macrocode} -% With the following instruction, we retrieve the $x$-value and the $y$-value of -% the center of the block. We will only use the $x$-value, available in |\pgf@x|. +% 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. % \begin{macrocode} - \tikz@parse@node \pgfutil@firstofone (#1-#2) - \path (\pgf@x,\l_tmpa_dim) node [ anchor = base ] { #5 } ; - \end { tikzpicture } - } + (#1-#2-block) { } ; % \end{macrocode} -% If the number of rows is different of $1$, it's necessary to create two Tikz -% nodes because we want the label |#5| really drawn in the \emph{center} of the node. +% +% \medskip +% If the creation of the ``medium nodes'' is required, we create a ``medium +% node'' for the block. % \begin{macrocode} + \bool_if:NT \l_@@_medium_nodes_bool { - \begin { tikzpicture } - \node - [ - fit = ( #1 - #2 - medium . north~west ) + \node + [ + fit = ( #1 - #2 - medium . north~west ) ( #3 - #4 - medium . south~east ) , inner~sep = 0 pt , - ] + ] + (#1-#2-block-medium) { } ; + } % \end{macrocode} -% We don't forget the name of the node because the user may wish to use it. +% \medskip +% Now, we will put the label of the block. % \begin{macrocode} - (#1-#2) { } ; - \node at (#1-#2.center) { #5 } ; - \end { tikzpicture } - } + \int_compare:nNnTF { #1 } = { #3 } + { +% \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. +% 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 +% \end{macrocode} +% We retrieve (in |\pgf@x|) the $x$-value of the center of the block. +% \begin{macrocode} + \@@_extract_coords:w (#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 } ; + } +% \end{macrocode} +% +% \medskip +% If the number of rows is different of $1$, we put the label of the block in +% 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 } } + \group_end: } % \end{macrocode} -% % -% \subsection{How to draw the dotted lines transparently} +% \bigskip +% \subsection*{How to draw the dotted lines transparently} % \begin{macrocode} \cs_set_protected:Npn \@@_renew_matrix: { @@ -7009,8 +7517,8 @@ c & c & b & a & e % \end{macrocode} % % -% \medskip -% \subsection{Automatic arrays} +% \bigskip +% \subsection*{Automatic arrays} % % % \begin{macrocode} @@ -7063,12 +7571,12 @@ c & c & b & a & e { \cs_set_protected:cpn { #1 AutoNiceMatrix } { - \str_gset:Nx \g_@@_type_env_str - { command ~ \c_backslash_str #1 AutoNiceMatrix } + \str_gset:Nx \g_@@_name_env_str { #1 AutoNiceMatrix } \AutoNiceMatrixWithDelims { #2 } { #3 } } } % \end{macrocode} +% % \begin{macrocode} \@@_define_com:nnn p ( ) \@@_define_com:nnn b [ ] @@ -7077,8 +7585,8 @@ c & c & b & a & e \@@_define_com:nnn B \{ \} % \end{macrocode} % -% \medskip -% \subsection{We process the options} +% \bigskip +% \subsection*{We process the options} % % We process the options when the package is loaded (with |\usepackage|) but we % recommend to use |\NiceMatrixOptions| instead. @@ -7104,9 +7612,113 @@ c & c & b & a & e \ProcessKeysOptions { NiceMatrix / Package } % \end{macrocode} % -% \subsection{Error messages of the package} +% \bigskip +% \subsection*{Error messages of the package} % +% The following command converts all the elements of a sequence (which are token +% lists) into strings. +% \begin{macrocode} +\cs_new_protected:Npn \@@_convert_to_str_seq:N #1 + { + \seq_clear:N \l_tmpa_seq + \seq_map_inline:Nn #1 + { + \seq_put_left:Nx \l_tmpa_seq { \tl_to_str:n { ##1 } } + } + \seq_set_eq:NN #1 \l_tmpa_seq + } +% \end{macrocode} +% +% The following command creates a sequence of strings (|str|) from a |clist|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_set_seq_of_str_from_clist:Nn #1 #2 + { + \seq_set_from_clist:Nn #1 { #2 } + \@@_convert_to_str_seq:N #1 + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_set_seq_of_str_from_clist:Nn \c_@@_types_of_matrix_seq + { + NiceMatrix , + pNiceMatrix , bNiceMatrix , vNiceMatrix, BNiceMatrix, VNiceMatrix + } +% \end{macrocode} +% +% \bigskip +% If the user uses too much columns, the command |\@@_error_too_much_cols:| is +% executed. This command raises an error but try to give the best information to +% the user in the error message. The command |\seq_if_in:NVTF| is not expandable +% and that's why we can't put it in the error message itself. We have to do the +% test before the |\@@_fatal:n|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_error_too_much_cols: + { + \seq_if_in:NVTF \c_@@_types_of_matrix_seq \g_@@_name_env_str + { + \int_compare:nNnTF \l_@@_last_col_int = { -1 } + { \@@_fatal:n { too~much~cols~for~matrix } } + { \@@_fatal:n { too~much~cols~for~matrix~with~last~col } } + } + { \@@_fatal:n { too~much~cols~for~array } } + } +% \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~ + 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. + } +% \end{macrocode} +% +% \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).~ + This~error~is~fatal. + } +% \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.\\ + If~you~go~on,~a~value~of~1~will~be~used. + } +% \end{macrocode} % +% +% \begin{macrocode} +\@@_msg_new:nn { Second~Block } + { + You~can't~use~\token_to_str:N \Block\ twice~in~the~same~cell~of~the~array.\\ + If~you~go~on,~this~command~(and~the~other)~will~be~ignored. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { empty~environment } + { Your~\@@_full_name_env:\ is~empty.~This~error~is~fatal. } +% \end{macrocode} % % \begin{macrocode} \@@_msg_new:nn { unknown~cell~for~line~in~code-after } @@ -7121,7 +7733,7 @@ c & c & b & a & e % \begin{macrocode} \@@_msg_new:nn { last-col~non~empty~for~NiceArray } { - In~the~\g_@@_type_env_str,~you~must~use~the~option~ + In~the~\@@_full_name_env:,~you~must~use~the~option~ 'last-col'~without~value.\\ However,~you~can~go~on~for~this~time~ (the~value~'\l_keys_value_tl'~will~be~ignored). @@ -7131,7 +7743,7 @@ c & c & b & a & e % \begin{macrocode} \@@_msg_new:nn { last-col~empty~for~NiceMatrix } { - In~the~\g_@@_type_env_str, you~can't~use~the~option~ + In~the~\@@_full_name_env:, you~can't~use~the~option~ 'last-col'~without~value.~You~must~give~the~number~of~that~last~column.\\ If~you~go~on~this~option~will~be~ignored. } @@ -7141,7 +7753,7 @@ c & c & b & a & e \@@_msg_new:nn { Block~too~large } { You~try~to~draw~a~block~in~the~cell~#1-#2~of~your~matrix~but~the~matrix~is~ - too~small~for~that~block.\\ + too~small~for~that~block. \\ If~you~go~on,~this~command~will~be~ignored. } % \end{macrocode} @@ -7160,7 +7772,7 @@ c & c & b & a & e \@@_msg_new:nn { Wrong~last~row } { You~have~used~'last-row=\int_use:N \l_@@_last_row_int'~but~your~ - \g_@@_type_env_str\ seems~to~have~\int_use:N \c@iRow \ rows.~ + \@@_full_name_env:\ seems~to~have~\int_use:N \c@iRow \ rows.~ If~you~go~on,~the~value~of~\int_use:N \c@iRow \ will~be~used~for~ last~row.~You~can~avoid~this~problem~by~using~'last-row'~ without~value~(more~compilations~might~be~necessary). @@ -7179,32 +7791,16 @@ c & c & b & a & e % \begin{macrocode} \@@_msg_new:nn { Outside~math~mode } { - The~\g_@@_type_env_str\ can~be~used~only~in~math~mode~ + The~\@@_full_name_env:\ can~be~used~only~in~math~mode~ (and~not~in~\token_to_str:N \vcenter).\\ This~error~is~fatal. } % \end{macrocode} % % \begin{macrocode} -\@@_msg_new:nn { Option~Transparent~suppressed } - { - The~option~'Transparent'~has~been~renamed~'transparent'.\\ - If~you~go~on~this~command~will~be~ignored. - } -% \end{macrocode} -% -% \begin{macrocode} -\@@_msg_new:nn { Option~RenewMatrix~suppressed } - { - The~option~'RenewMatrix'~has~been~renamed~'renew-matrix'.\\ - If~you~go~on~this~command~will~be~ignored. - } -% \end{macrocode} -% -% \begin{macrocode} \@@_msg_new:nn { Bad~value~for~letter~for~dotted~lines } { - The~value~of~key~'\tl_use:N\l_keys_key_tl'~must~be~of~length~1.\\ + The~value~of~key~'\tl_use:N\l_keys_key_str'~must~be~of~length~1.\\ If~you~go~on,~it~will~be~ignored. } % \end{macrocode} @@ -7213,7 +7809,7 @@ c & c & b & a & e % \begin{macrocode} \@@_msg_new:nnn { Unknown~key~for~NiceMatrixOptions } { - The~key~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~command~ + The~key~'\tl_use:N\l_keys_key_str'~is~unknown~for~the~command~ \token_to_str:N \NiceMatrixOptions. \\ If~you~go~on,~it~will~be~ignored. \\ For~a~list~of~the~available~keys,~type~H~. @@ -7232,6 +7828,7 @@ c & c & b & a & e end-of-row,~ exterior-arraycolsep,~ hlines,~ + hvlines,~ left-margin,~ letter-for-dotted-lines,~ light-syntax,~ @@ -7241,14 +7838,15 @@ c & c & b & a & e renew-matrix,~ right-margin,~ small,~ - and~transparent + transparent~ + and~vlines. } % \end{macrocode} % % \begin{macrocode} \@@_msg_new:nnn { Unknown~option~for~NiceArray } { - The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~environment~ + The~option~'\tl_use:N\l_keys_key_str'~is~unknown~for~the~environment~ \{NiceArray\}. \\ If~you~go~on,~it~will~be~ignored. \\ For~a~list~of~the~available~options,~type~H~. @@ -7256,6 +7854,7 @@ c & c & b & a & e { The~available~options~are~(in~alphabetic~order):~ b,~ + baseline,~ c,~ code-after,~ code-for-first-col,~ @@ -7273,6 +7872,7 @@ c & c & b & a & e first-col,~ first-row,~ hlines,~ + hvlines,~ last-col,~ last-row,~ left-margin,~ @@ -7283,7 +7883,8 @@ c & c & b & a & e renew-dots,~ right-margin,~ small,~ - and~t. + t,~ + and~vlines. } % \end{macrocode} % @@ -7294,8 +7895,8 @@ c & c & b & a & e % \begin{macrocode} \@@_msg_new:nnn { Unknown~option~for~NiceMatrix } { - The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~ - \g_@@_type_env_str. \\ + The~option~'\tl_use:N\l_keys_key_str'~is~unknown~for~the~ + \@@_full_name_env:. \\ If~you~go~on,~it~will~be~ignored. \\ For~a~list~of~the~available~options,~type~H~. } @@ -7317,6 +7918,7 @@ c & c & b & a & e first-col,~ first-row,~ hlines,~ + hvlines,~ last-col,~ last-row,~ left-margin,~ @@ -7326,7 +7928,8 @@ c & c & b & a & e parallelize-diags,~ renew-dots,~ right-margin,~ - and~small. + small,~ + and~vlines. } % \end{macrocode} % @@ -7358,10 +7961,9 @@ c & c & b & a & e % \begin{macrocode} \@@_msg_new:nn { Zero~row } { - There~is~a~problem.~Maybe~your~\g_@@_type_env_str\ is~empty.~ - Maybe~you~have~used~l,~c~and~r~instead~of~L,~C~and~R~in~the~preamble~ - of~your~environment. \\ - If~you~go~on,~the~result~may~be~incorrect. + There~is~a~problem.~Maybe~you~have~used~l,~c~and~r~instead~of~L,~C~ + and~R~in~the~preamble~of~your~environment. \\ + This~error~is~fatal. } % \end{macrocode} % @@ -7369,29 +7971,28 @@ c & c & b & a & e \@@_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~\g_@@_type_env_str. \\ + first~position~of~the~preamble~of~the~\@@_full_name_env:. \\ If~you~go~on,~this~dotted~line~will~be~ignored. } % \end{macrocode} % -% -% \subsection{Obsolete environments} +% \bigskip +% \subsection*{Obsolete environments} % % \begin{macrocode} \@@_msg_new:nn { Obsolete~environment } { - The~environment~\{\@currenvir\}~is~obsolete.~We~should~use~#1~instead.~ - However,~you~can~go~on~for~this~time.~ - If~you~don't~want~to~see~this~error~again,~you~should~load~'nicematrix'~ - with~the~option~'obsolete-environments'. + The~environment~\{\@currenvir\}~is~obsolete.~You~should~use~#1~instead.~ + However,~it's~still~possible~to~use~the~environment~\{\@currenvir\}~(for~ + a~few~months)~by~loading~'nicematrix'~with~the~option~ + 'obsolete-environments'. } % \end{macrocode} % % \begin{macrocode} \NewDocumentEnvironment { pNiceArrayC } { } { - \@@_error:nn { Obsolete~environment } - { the~option~'last-col' } + \@@_fatal:nn { Obsolete~environment } { the~option~'last-col' } \int_zero:N \l_@@_last_col_int \pNiceArray } @@ -7401,8 +8002,7 @@ c & c & b & a & e % \begin{macrocode} \NewDocumentEnvironment { bNiceArrayC } { } { - \@@_error:nn { Obsolete~environment } - { the~option~'last-col' } + \@@_fatal:nn { Obsolete~environment } { the~option~'last-col' } \int_zero:N \l_@@_last_col_int \bNiceArray } @@ -7412,8 +8012,7 @@ c & c & b & a & e % \begin{macrocode} \NewDocumentEnvironment { BNiceArrayC } { } { - \@@_error:nn { Obsolete~environment } - { the~option~'last-col' } + \@@_fatal:nn { Obsolete~environment } { the~option~'last-col' } \int_zero:N \l_@@_last_col_int \BNiceArray } @@ -7423,8 +8022,7 @@ c & c & b & a & e % \begin{macrocode} \NewDocumentEnvironment { vNiceArrayC } { } { - \@@_error:nn { Obsolete~environment } - { the~option~'last-col' } + \@@_fatal:nn { Obsolete~environment } { the~option~'last-col' } \int_zero:N \l_@@_last_col_int \vNiceArray } @@ -7434,8 +8032,7 @@ c & c & b & a & e % \begin{macrocode} \NewDocumentEnvironment { VNiceArrayC } { } { - \@@_error:nn { Obsolete~environment } - { the~option~'last-col' } + \@@_fatal:nn { Obsolete~environment } { the~option~'last-col' } \int_zero:N \l_@@_last_col_int \VNiceArray } @@ -7445,7 +8042,7 @@ c & c & b & a & e % \begin{macrocode} \NewDocumentEnvironment { pNiceArrayRC } { } { - \@@_error:nn { Obsolete~environment } + \@@_fatal:nn { Obsolete~environment } { the~options~'last-col'~and~'first-row' } \int_zero:N \l_@@_last_col_int \int_zero:N \l_@@_first_row_int @@ -7457,7 +8054,7 @@ c & c & b & a & e % \begin{macrocode} \NewDocumentEnvironment { bNiceArrayRC } { } { - \@@_error:nn { Obsolete~environment } + \@@_fatal:nn { Obsolete~environment } { the~options~'last-col'~and~'first-row' } \int_zero:N \l_@@_last_col_int \int_zero:N \l_@@_first_row_int @@ -7469,7 +8066,7 @@ c & c & b & a & e % \begin{macrocode} \NewDocumentEnvironment { BNiceArrayRC } { } { - \@@_error:nn { Obsolete~environment } + \@@_fatal:nn { Obsolete~environment } { the~options~'last-col'~and~'first-row' } \int_zero:N \l_@@_last_col_int \int_zero:N \l_@@_first_row_int @@ -7481,7 +8078,7 @@ c & c & b & a & e % \begin{macrocode} \NewDocumentEnvironment { vNiceArrayRC } { } { - \@@_error:nn { Obsolete~environment } + \@@_fatal:nn { Obsolete~environment } { the~options~'last-col'~and~'first-row' } \int_zero:N \l_@@_last_col_int \int_zero:N \l_@@_first_row_int @@ -7493,7 +8090,7 @@ c & c & b & a & e % \begin{macrocode} \NewDocumentEnvironment { VNiceArrayRC } { } { - \@@_error:nn { Obsolete~environment } + \@@_fatal:nn { Obsolete~environment } { the~options~'last-col'~and~'first-row' } \int_zero:N \l_@@_last_col_int \int_zero:N \l_@@_first_row_int @@ -7505,7 +8102,7 @@ c & c & b & a & e % \begin{macrocode} \NewDocumentEnvironment { NiceArrayCwithDelims } { } { - \@@_error:nn { Obsolete~environment } + \@@_fatal:nn { Obsolete~environment } { the~option~'last-col' } \int_zero:N \l_@@_last_col_int \NiceArrayWithDelims @@ -7516,7 +8113,7 @@ c & c & b & a & e % \begin{macrocode} \NewDocumentEnvironment { NiceArrayRCwithDelims } { } { - \@@_error:nn { Obsolete~environment } + \@@_fatal:nn { Obsolete~environment } { the~options~'last-col'~and~'first-row' } \int_zero:N \l_@@_last_col_int \int_zero:N \l_@@_first_row_int @@ -7665,9 +8262,9 @@ c & c & b & a & e % % Error message when the user gives an incorrect value for |last-row|. % -% A dotted line can no longer cross another dotted line (except the dotted lines -% drawn by |\cdottedline|, the symbol |:| (in the preamble of the array) and -% |\line| in |code-after|. +% 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|). % % The starred versions of |\Cdots|, |\Ldots|, etc. are now deprecated because, % with the new implementation, they become pointless. These starred versions @@ -7763,6 +8360,25 @@ c & c & b & a & e % % Correction of a bug linked to |first-row| and |last-row|. % +% \subsection*{Changes between versions 3.11 and 3.12} +% +% Command |\rotate| in the cells of the array. +% +% Options |vlines|, |hlines| and |hvlines|. +% +% Option |baseline| pour |{NiceArray}| (uniquement). +% +% 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 +% $i$|-|$j$|-block| and, if the creation of the ``medium nodes'' is required, a +% node $i$|-|$j$|-block-medium| is created. +% +% If the user try to use more columns than allowed by its environment, an error +% is raised by nicematrix (instead of a low-level error). +% +% The package must be loaded with the option |obsolete-environments| if we want +% to use the deprecated environments. +% % \PrintIndex % % \tableofcontents -- cgit v1.2.3