diff options
Diffstat (limited to 'Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx')
-rw-r--r-- | Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx | 12480 |
1 files changed, 9503 insertions, 2977 deletions
diff --git a/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx b/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx index 04dd13a9dd6..3b7f4d278ec 100644 --- a/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx +++ b/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx @@ -1,6 +1,6 @@ % \iffalse meta-comment % -% Copyright (C) 2018-2019 by F. Pantigny +% Copyright (C) 2018-2021 by F. Pantigny % ----------------------------------- % % This file may be distributed and/or modified under the @@ -15,8 +15,8 @@ % % \fi % \iffalse -\def\myfileversion{3.14} -\def\myfiledate{2020/03/23} +\def\myfileversion{5.10} +\def\myfiledate{2021/02/05} % % %<*batchfile> @@ -26,7 +26,7 @@ \usedir{tex/latex/nicematrix} \preamble -Copyright (C) 2018-2020 by F. Pantigny +Copyright (C) 2018-2021 by F. Pantigny ----------------------------------- This file may be distributed and/or modified under the @@ -51,9 +51,8 @@ version 2005/12/01 or later. \usepackage[xetex]{geometry} \geometry{left=2.8cm,right=2.8cm,top=2.5cm,bottom=2.5cm,papersize={21cm,29.7cm}} -\usepackage{colortbl} \usepackage{tikz} -\usetikzlibrary{fit} +\usetikzlibrary{fit,patterns} \usepackage{nicematrix} \usepackage{siunitx} @@ -66,13 +65,41 @@ version 2005/12/01 or later. \titlespacing*{\section}{0pt}{6.5ex plus 1ex minus .2ex}{4.3ex plus .2ex} \titlespacing*{\subsection}{0pt}{4.5ex plus 1ex minus .2ex}{2ex plus .2ex} \usepackage{multicol} -\usepackage{arydshln} \setlength{\columnseprule}{0.4pt} \usepackage{footnotehyper} \usepackage{varwidth} +\def\LetterAt{@} \parindent 0pt \EnableCrossrefs +\makeatletter +\ExplSyntaxOn +\DoNotIndex{\begin,\end} +\DoNotIndex{\c@iRow,\c@jCol,\theiRow,\thejCol} +\DoNotIndex{\pgfpicture,\endpgfpicture,\tikzpicture,\endtikzpicture} +\DoNotIndex{\pgfpoint,\pgfnode,\pgfnodealias,\pgfcoordinate} +\DoNotIndex{\pgf@x,\pgf@y} +\DoNotIndex{\int_add:Nn,\int_case:nnTF,\int_compare:nNnTF,\int_compare:nTF, + \int_compare_p:nNn,\int_decr:N,\int_eval:n,\int_add:Nn,\int_gdecr:N,\int_gincr:N + \int_gset:Nn,\int_gset_eq:NN,\int_gzero:N,\int_gzero_new:N,\int_if_odd:nTF, + \int_max:nn,\int_new:N,\int_set:Nn,\int_set_eq:NN,\int_step_inline:nnn, + \int_step_variable:nNn,\int_step_variable:nnNn,\int_sub:Nn,\int_use:N,\int_zero:N, + \int_zero_new:N,\g_tmpa_int,\l_tmpa_int,\l_tmpb_int} +\DoNotIndex{\dim_abs:n,\dim_add:Nn,\dim_compare:nNnTF,\dim_compare_p:nNn, +\dim_const:Nn,\dim_eval:n,\dim_gadd:Nn,\dim_gset:Nn,\dim_gset_eq:NN, +\dim_gset:Nn,\dim_gset_eq:NN,\dim_gsub:Nn,\dim_gzero_new:N,\dim_max:nn, +\dim_min:nn,\dim_new:N,\dim_ration:nn,\dim_set:Nn,\dim_set_eq:NN,\dim_sub:Nn, +\dim_use:N,\dim_zero:N,\dim_zero_new:N,\g_tmpa_dim,\l_tmpa_dim,\l_tmpb_dim, +\c_zero_dim} +\DoNotIndex{\cs_new_protected:Npn,\cs_new:Npn,\cs_set_eq:NN, +\cs_set_protected:Npn} +\DoNotIndex{\bool_if:NTF,\bool_new:N,\bool_set_false:N,\bool_set_true:N,\l_tmpa_bool} +\DoNotIndex{\group_begin:,\group_end:,\c_math_toggle_token} +\DoNotIndex{\tl_set:Nn,\l_tmpa_tl} +\ExplSyntaxOff +\makeatother + + \begin{document} \DocInput{nicematrix.dtx} \end{document} @@ -85,8 +112,8 @@ version 2005/12/01 or later. % { % pdfinfo = % { -% Title = The extension 'nicematrix' , -% Subject = A LaTeX extension , +% Title = The package 'nicematrix' , +% Subject = A LaTeX package , % Author = F. Pantigny % } % } @@ -96,39 +123,13 @@ version 2005/12/01 or later. % % \begin{abstract} % The LaTeX package \pkg{nicematrix} provides new environments similar to the -% classical environments |{array}| and |{matrix}| but with some additional -% features. Among these features are the possibilities to fix the width of the -% columns and to draw continuous ellipsis dots between the cells of the array. +% classical environments |{tabular}|, |{array}| and |{matrix}| of \pkg{array} +% and \pkg{amsmath} but with extended features. % \end{abstract} % % \vspace{1cm} -% \section{Presentation} -% -% -% This package can be used with |xelatex|, |lualatex|, |pdflatex| but also by -% the classical workflow |latex|-|dvips|-|ps2pdf| (or Adobe Distiller). Two or -% three compilations may be necessary. This package requires and \textbf{loads} -% the packages \pkg{expl3}, \pkg{l3keys2e}, \pkg{xparse}, \pkg{array}, -% \pkg{amsmath}, \pkg{pgfcore} and the module \pkg{shapes} of \textsc{pgf} -% (\pkg{tikz} is \emph{not} loaded). The final user only has to load the -% extension with |\usepackage{nicematrix}|. -% -% -% \medskip -% \begin{savenotes} -% \begin{minipage}{0.6\linewidth} -% This package provides some new tools to draw mathematical matrices. The main -% features are the following: -% \begin{itemize}\setlength{\itemsep}{0pt} -% \item continuous dotted lines\footnote{If the class option |draft| is -% used, these dotted lines will not be drawn for a faster compilation.}; -% \item exterior rows and columns for labels; -% \item a control of the width of the columns. -% \end{itemize} -% \end{minipage} -% \end{savenotes} -% \hspace{1.4cm} -% $\begin{bNiceArray}{CCCC}[first-row,first-col, +% \hspace{1cm} +% $\begin{bNiceArray}{cccc}[first-row,first-col, % code-for-first-col=\color{blue}\scriptstyle, % code-for-first-row=\color{blue}\scriptstyle, % columns-width = auto] @@ -137,99 +138,1642 @@ version 2005/12/01 or later. % L_2 & a_{21} & a_{22} & \Cdots & a_{2n} \\ % \Vdots & \Vdots & \Vdots & \Ddots & \Vdots\\ % L_n & a_{n1} & a_{n2} & \Cdots & a_{nn} -% \end{bNiceArray}$ +% \end{bNiceArray}$\hspace{2cm} +% \begin{NiceTabular}{lSSSS}[code-before = \rowcolor{red!15}{1-2} \rowcolors{3}{blue!15}{}] +% \toprule +% \Block{2-1}{Product} & \multicolumn{3}{c}{dimensions (cm)} & \Block{2-1}{\rotate Price} \\ +% \cmidrule(rl){2-4} +% & L & l & h \\ +% \midrule +% small & 3 & 5.5 & 1 & 30 \\ +% standard & 5.5 & 8 & 1.5 & 50.5 \\ +% premium & 8.5 & 10.5 & 2 & 80 \\ +% extra & 8.5 & 10 & 1.5 & 85.5 \\ +% special & 12 & 12 & 0.5 & 70 \\ +% \bottomrule +% \end{NiceTabular} +% +% \vspace{1cm} +% The package \pkg{nicematrix} is entirely contained in the file +% |nicematrix.sty|. This file may be put in the current directory or in a +% |texmf| tree. However, the best is to install \pkg{nicematrix} with a TeX +% distribution as MiKTeX or TeXlive. +% +% \bigskip +% This package can be used with |xelatex|, |lualatex|, |pdflatex| but also by +% the classical workflow |latex|-|dvips|-|ps2pdf| (or Adobe Distiller). +% \textsl{However, the file nicematrix.dtx of the present documentation should +% be compiled with XeLaTeX.} +% +% \bigskip +% This package requires and \textbf{loads} the packages \pkg{l3keys2e}, +% \pkg{array}, \pkg{amsmath}, \pkg{pgfcore} and the module \pkg{shapes} of +% \textsc{pgf} (\pkg{tikz}, which is a layer over \textsc{pgf} is \emph{not} +% loaded). The final user only has to load the package with +% |\usepackage{nicematrix}|. +% +% +% \bigskip +% The idea of \pkg{nicematrix} is to create \textsc{pgf} nodes under the cells +% and the positions of the rules of the tabular created by \pkg{array} and to +% use these nodes to develop new features. As usual with \textsc{pgf}, the +% coordinates of these nodes are written in the |.aux| to be used on the next +% compilation and that's why \pkg{nicematrix} may need \textbf{several +% compilations}. % -% \medskip +% \bigskip +% Most features of \pkg{nicematrix} may be used without explicit use of +% \textsc{pgf} or Tikz (which, in fact, is not loaded by default). +% +% \bigskip % A command |\NiceMatrixOptions| is provided to fix the options (the -% scope of the options fixed by this command is the current TeX group). +% scope of the options fixed by this command is the current TeX group: they are +% semi-global). +% +% +% \bigskip +% {\bfseries \color{red} Important +% +% Since the version 5.0 of \pkg{nicematrix}, one must use the letters |l|, |c| and +% |r| in the preambles of the environments and no longer the letters |L|, |C| and +% |R|. +% +% For sake of compatibility with the previous versions, there exists an option +% |define-L-C-R| which must be used when loading \pkg{nicematrix}. +% \begin{Verbatim} +% \usepackage[define-L-C-R]{nicematrix} +% \end{Verbatim} +% } +% +% \newpage +% +% \section{The environments of this package} +% +% The package \pkg{nicematrix} defines the following new environments. +% +% \medskip +% \begin{ttfamily} +% \setlength{\tabcolsep}{3mm} +% \begin{tabular}{llll} +% \{NiceTabular\} & \{NiceArray\} & \{NiceMatrix\} \\ +% \{NiceTabular*\} & \{pNiceArray\} & \{pNiceMatrix\} \\ +% & \{bNiceArray\} & \{bNiceMatrix\} \\ +% & \{BNiceArray\} & \{BNiceMatrix\} \\ +% & \{vNiceArray\} & \{vNiceMatrix\} \\ +% & \{VNiceArray\} & \{VNiceMatrix\} +% \end{tabular} +% \end{ttfamily} % +% +% +% +% \medskip +% The environments |{NiceArray}|, |{NiceTabular}| and |{NiceTabular*}| are +% similar to the environments |{array}|, |{tabular}| and |{tabular*}| of the +% package \pkg{array} (which is loaded by \pkg{nicematrix}). +% +% \medskip +% The environments |{pNiceArray}|, |{bNiceArray}|, etc. have no equivalent in +% \pkg{array}. +% +% \medskip +% The environments |{NiceMatrix}|, |{pNiceMatrix}|, etc. are similar to the +% corresponding environments of \pkg{amsmath} (which is loaded by +% \pkg{nicematrix}): |{matrix}|, |{pmatrix}|, etc. +% +% \medskip +% All the environments of the package \pkg{nicematrix} accept, between square +% brackets, an optional list of \textsl{key=value} pairs. \textbf{There must be +% no space before the opening bracket (|[|) of this list of options.} +% +%\bigskip +% \textbf{Important} +% +% Before the version 5.0, it was mandatory to use, for technical reasons, the +% letters |L|, |C| et |R| instead of |l|, |c| et |r| in the preambles of the +% environments of \pkg{nicematrix}. If we want to be able to go on using these +% letters, \pkg{nicematrix} must be loaded with the option |define-L-C-R|. +% \begin{Verbatim} +% \usepackage[define-L-C-R]{nicematrix} +% \end{Verbatim} +% +% +% \section{The vertical space between the rows} +% +% It's well known that some rows of the arrays created by default with LaTeX +% are, by default, too close to each other. Here is a classical example. +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=9cm] +% $\begin{pmatrix} +% \frac12 & -\frac12 \\ +% \frac13 & \frac14 \\ +% \end{pmatrix}$ +% \end{BVerbatim} +% $\begin{pmatrix} +% \frac12 & -\frac12 \\ +% \frac13 & \frac14 \\ +% \end{pmatrix}$ % % \bigskip -% \textbf{An example for the continuous dotted lines} +% Inspired by the package \pkg{cellspace} which deals with that problem, the +% package \pkg{nicematrix} provides two keys |cell-space-top-limit| and +% |cell-space-bottom-limit| similar to the parameters |\cellspacetoplimit| and +% |\cellspacebottomlimit| of \pkg{cellspace}. +% +% \colorbox{yellow!50}{\bfseries{New 5.9}}\enskip +% There is also a key |cell-space-limits| to set both parameters at once. +% +% The initial value of these parameters is $0$~pt in order to have for the +% environments of \pkg{nicematrix} the same behaviour as those of \pkg{array} +% and \pkg{amsmath}. However, a value of $1$~pt would probably be a good choice +% and we suggest to set them with |\NiceMatrixOptions|.\footnote{One should +% remark that these parameters apply also to the columns of type |S| of +% \pkg{siunitx} whereas the package \pkg{cellspace} is not able to act on such +% columns of type~|S|.} % % \medskip -% \begin{minipage}{10cm} -% For example, consider the following code which uses an environment |{pmatrix}| -% of \pkg{amsmath}. +% \begin{Verbatim} +% \NiceMatrixOptions{~emphase#cell-space-limits = 1pt@} +% \end{Verbatim} +% +% \begin{BVerbatim}[baseline=c,boxwidth=9cm] +% $\begin{pNiceMatrix} +% \frac12 & -\frac12 \\ +% \frac13 & \frac14 \\ +% \end{pNiceMatrix}$ +% \end{BVerbatim} +% \begin{scope} +% \NiceMatrixOptions{cell-space-limits = 1pt} +% $\begin{pNiceMatrix} +% \frac12 & -\frac12 \\ +% \frac13 & \frac14 \\ +% \end{pNiceMatrix}$ +% \end{scope} +% +% +% % +% +% \bigskip +% \section{The vertical position of the arrays} +% +% The package \pkg{nicematrix} provides a option |baseline| for the vertical +% position of the arrays. This option takes in as value an integer which is the +% number of the row on which the array will be aligned. +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=9cm] +% $A = \begin{pNiceMatrix}[~emphase#baseline=2@] +% \frac{1}{\sqrt{1+p^2}} & p & 1-p \\ +% 1 & 1 & 1 \\ +% 1 & p & 1+p +% \end{pNiceMatrix}$ +% \end{BVerbatim} +% $A = \begin{pNiceMatrix}[baseline=2] +% \frac{1}{\sqrt{1+p^2}} & p & 1-p \\ +% 1 & 1 & 1 \\ +% 1 & p & 1+p +% \end{pNiceMatrix}$ +% +% +% \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 environments |{tabular}| and |{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 |{tabular}| or |{array}| of +% \pkg{array}, one must use |\firsthline|. +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=9cm] +% \begin{enumerate} +% \item an item % \smallskip -% \begin{BVerbatim} -% $A = \begin{pmatrix} -% 1 & \cdots & \cdots & 1 \\ -% 0 & \ddots & & \vdots \\ -% \vdots & \ddots & \ddots & \vdots \\ -% 0 & \cdots & 0 & 1 -% \end{pmatrix}$ +% \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|, |\midrule|, etc.\par\nobreak % % \smallskip -% This code composes the matrix $A$ on the right. -% \end{minipage}\hspace{1cm} -% $A = \begin{pmatrix} -% 1 &\cdots &\cdots &1 \\ -% 0 &\ddots & &\vdots \\ -% \vdots &\ddots &\ddots &\vdots \\ -% 0 &\cdots &0 &1 -% \end{pmatrix}$ +% \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} +% +% \bigskip +% It's also possible to use the key |baseline| to align a matrix on an +% horizontal rule (drawn by |\hline|). In this aim, one should give the value +% |line-|\textsl{i} where \textsl{i} is the number of the row following the +% horizontal rule. +% +% \smallskip +% \begin{Verbatim} +% \NiceMatrixOptions{cell-space-limits=1pt} +% \end{Verbatim} +% +% \smallskip +% \begin{BVerbatim}[baseline=c,boxwidth=9cm] +% $A=\begin{pNiceArray}{cc|cc}[baseline=line-3] +% \dfrac1A & \dfrac1B & 0 & 0 \\ +% \dfrac1C & \dfrac1D & 0 & 0 \\ +% \hline +% 0 & 0 & A & B \\ +% 0 & 0 & D & D \\ +% \end{pNiceArray}$ +% \end{BVerbatim} +% \begin{scope} +% \NiceMatrixOptions{cell-space-limits=1pt} +% \raisebox{-5mm}{$A=\begin{pNiceArray}{cc|cc}[baseline=line-3] +% \dfrac1A & \dfrac1B & 0 & 0 \\ +% \dfrac1C & \dfrac1D & 0 & 0 \\ +% \hline +% 0 & 0 & A & B \\ +% 0 & 0 & D & D \\ +% \end{pNiceArray}$} +% \end{scope} +% +% +% \section{The blocks} +% \label{Block} +% +% \subsection{General case} +% +% In the environments of \pkg{nicematrix}, it's possible to use the command +% |\Block| in order to place an element in the center of a rectangle of merged +% cells of the array. +% +% The command |\Block| must be used in the upper leftmost cell of the array with +% two arguments. +% +% \begin{itemize} +% \item The first argument is the size of the block with the syntax +% $i$\verb|-|$j$ where $i$ is the number of rows of the block and $j$ its number +% of columns. +% +% If this argument is empty, its default +% value is |1-1|. If the number of rows is not specified, or equal to |*|, the +% block extends until the last row (idem for the columns). % +% \item The second argument is the content of the block. It's possible to use +% |\\| in that content to have a content on several lines. In |{NiceTabular}| +% the content of the block is composed in text mode whereas, in the other +% environments, it is composed in math mode. +% \end{itemize} % +% +% \interitem +% Here is an example of utilisation of the command |\Block| in mathematical matrices. +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=10.6cm] +% $\begin{bNiceArray}{ccc|c}[margin] +% ~emphase#\Block{3-3}{A}@ & & & 0 \\ +% & \hspace*{1cm} & & \Vdots \\ +% & & & 0 \\ +% \hline +% 0 & \Cdots& 0 & 0 +% \end{bNiceArray}$ +% \end{BVerbatim} +% $\begin{bNiceArray}{ccc|c}[margin] +% \Block{3-3}{A} & & & 0 \\ +% & \hspace*{1cm} & & \Vdots \\ +% & & & 0 \\ +% \hline +% 0 & \Cdots& 0 & 0 +% \end{bNiceArray}$ +% % \bigskip +% One may wish to raise the size of the ``$A$'' placed in the block of the +% previous example. Since this element is composed in math mode, it's not +% possible to use directly a command like |\large|, |\Large| and |\LARGE|. +% That's why the command |\Block| provides an option between angle brackets to +% specify some TeX code which will be inserted before the beginning of the +% math mode.\footnote{This argument between angular brackets may also be used to +% insert a command of font such as |\bfseries| when the command |\\| is used in +% the content of the block.} +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=10.6cm] +% $\begin{bNiceArray}{ccc|c}[margin] +% \Block{3-3}~emphase#<\Large>@{A} & & & 0 \\ +% & \hspace*{1cm} & & \Vdots \\ +% & & & 0 \\ +% \hline +% 0 & \Cdots& 0 & 0 +% \end{bNiceArray}$ +% \end{BVerbatim} % \begin{scope} -% \NiceMatrixOptions{transparent} -% \begin{minipage}{10cm} -% Now, if we use the package \pkg{nicematrix} with the option \\ -% |transparent|, the same code will give the result on the right. -% \end{minipage}\hspace{1cm} -% $A = \begin{pmatrix} -% 1 & \cdots & \cdots & 1 \\ -% 0 & \ddots & & \vdots \\ -% \vdots & \ddots & \ddots & \vdots \\ -% 0 & \cdots & 0 & 1 -% \end{pmatrix}$ +% $\begin{bNiceArray}{ccc|c}[margin] +% \Block{3-3}<\Large>{A} & & & 0 \\ +% & \hspace*{1cm} & & \Vdots \\ +% & & & 0 \\ +% \hline +% 0 & \Cdots& 0 & 0 +% \end{bNiceArray}$ % \end{scope} % +% \medskip +% It's possible to set the horizontal position of the block with one of the keys +% |l|, |c| and |r|. % -% \section{The environments of this extension} % -% The extension \pkg{nicematrix} defines the following new environments. +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=10.6cm] +% $\begin{bNiceArray}{ccc|c}[margin] +% \Block~emphase#[r]@{3-3}<\LARGE>{A} & & & 0 \\ +% & \hspace*{1cm} & & \Vdots \\ +% & & & 0 \\ +% \hline +% 0 & \Cdots& 0 & 0 +% \end{bNiceArray}$ +% \end{BVerbatim} +% $\begin{bNiceArray}{ccc|c}[margin] +% \Block[r]{3-3}<\LARGE>{A} & & & 0 \\ +% & \hspace*{1cm} & & \Vdots \\ +% & & & 0 \\ +% \hline +% 0 & \Cdots& 0 & 0 +% \end{bNiceArray}$ +% +% +% \interitem +% {\bfseries One must remark that, by default, the commands |\Blocks| don't create space}. +% There is exception only for the blocks mono-row and the blocks mono-column as +% explained just below. +% +% \medskip +% In the following example, we have had to enlarge by hand the columns 2 and 3 +% (with the construction |wc{...}| of \pkg{array}). % % \medskip -% \begin{ttfamily} -% \setlength{\tabcolsep}{3mm} -% \begin{tabular}{llll} -% \{NiceMatrix\} & \{NiceArray\} & \{pNiceArray\} \\ -% \{pNiceMatrix\} & & \{bNiceArray\} \\ -% \{bNiceMatrix\} & & \{BNiceArray\} \\ -% \{BNiceMatrix\} & & \{vNiceArray\} \\ -% \{vNiceMatrix\} & & \{VNiceArray\} \\ -% \{VNiceMatrix\} & & \{NiceArrayWithDelims\} \\ +% \begin{BVerbatim} +% \begin{NiceTabular}~emphase#{cwc{2cm}wc{3cm}c}@ +% rose & tulipe & marguerite & dahlia \\ +% violette +% & \Block[draw=red,fill=red!15]{2-2}{\LARGE De très jolies fleurs} & & souci \\ +% pervenche & & & lys \\ +% arum & iris & jacinthe & muguet +% \end{NiceTabular} +% \end{BVerbatim} +% +% +% \medskip +% \begin{center} +% \begin{NiceTabular}{cwc{2cm}wc{3cm}c} +% rose & tulipe & marguerite & dahlia \\ +% violette & +% \Block[draw=red,fill=red!15]{2-2}{\LARGE De très jolies fleurs} & & souci \\ +% pervenche & & & lys \\ +% arum & iris & jacinthe & muguet +% \end{NiceTabular} +% \end{center} +% +% As we can see on this example, it's possible to fill the block by using the +% key |fill| and to draw the frame with the key |draw|\footnote{If the key +% |draw| is used without value, the default color the rules of the tabulars is +% used}. It's also possible to change the width (thickness) of that rules with +% the key |line-width|. +% +% \subsection{The mono-column blocks} +% +% The mono-column blocks have a special behaviour. +% +% \begin{itemize} +% \item The natural width of the contents of these blocks is taken into account +% for the width of the current column. +% +% \item The specification of the horizontal position provided by the type of +% column (|c|, |r| or |l|) is taken into account for the blocks. +% +% \item The specifications of font specified for the column by a construction +% |>{...}| in the preamble of the array are taken into account for the +% mono-column blocks of that column (this behaviour is probably expected). +% \end{itemize} +% +% +% \bigskip +% \begin{scope} +% \hfuzz=10cm +% \begin{BVerbatim}[baseline=c,boxwidth=12cm] +% \begin{NiceTabular}{~LetterAt{}>{\bfseries}lr~LetterAt{}} \hline +% \Block{2-1}{John} & 12 \\ +% & 13 \\ \hline +% Steph & 8 \\ \hline +% \Block{3-1}{Sarah} & 18 \\ +% & 17 \\ +% & 15 \\ \hline +% Ashley & 20 \\ \hline +% Henry & 14 \\ \hline +% \Block{2-1}{Madison} & 15 \\ +% & 19 \\ \hline +% \end{NiceTabular} +% \end{BVerbatim} +% \begin{NiceTabular}{@{}>{\bfseries}lr@{}}[baseline=c] \hline +% \Block{2-1}{John} & 12 \\ +% & 13 \\ \hline +% Steph & 8 \\ \hline +% \Block{3-1}{Sarah} & 18 \\ +% & 17 \\ +% & 15 \\ \hline +% Ashley & 20 \\ \hline +% Henry & 14 \\ \hline +% \Block{2-1}{Madison} & 15 \\ +% & 19 \\ \hline +% \end{NiceTabular} +% \end{scope} +% +% +% \subsection{The mono-row blocks} +% +% For the mono-row blocks, the natural height and depth are taken into account +% for the height and depth of the current row (as does a standard |\multicolumn| +% of LaTeX). +% +% \subsection{The mono-cell blocks} +% +% A mono-cell block inherits all the properties of the mono-row blocks and +% mono-column blocks. +% +% \medskip +% At first sight, one may think that there is no point using a mono-cell block. +% However, there are some good reasons to use such a block. +% \begin{itemize} +% \item It's possible to use the command |\\| in a (mono-cell) block. +% +% \item It's possible to use the option of horizontal alignment of the block in +% derogation of the type of column given in the preamble of the array. +% +% \item It's possible do draw a frame around the cell with the key |draw| of the +% command |\Block|.\footnote{If one wishes to color the background of a unique +% celle, there is no point using the command |\Block|: it's possible to use the +% command |\cellcolor| (when the key |colortbl-like| is used).} +% \end{itemize} +% +% \bigskip +% \begin{BVerbatim}[baseline=c,boxwidth=10cm] +% \begin{NiceTabular}{cc} +% \toprule +% Writer & ~emphase#\Block[l]{}{year\\ of birth}@ \\ +% \midrule +% Hugo & 1802 \\ +% Balzac & 1799 \\ +% \bottomrule +% \end{NiceTabular} +% \end{BVerbatim} +% \begin{NiceTabular}{cc} +% \toprule +% Writer & \Block[l]{}{year\\ of birth} \\ +% \midrule +% Hugo & 1802 \\ +% Balzac & 1799 \\ +% \bottomrule +% \end{NiceTabular} +% +% \medskip +% We recall that if the first mandatory argument of |\Block| is left blank, the +% block is mono-cell.\footnote{One may consider that the default value of the +% first mandatory argument of |\Block| is |1-1|.} +% +% +% +% +% \subsection{A small remark} +% +% One should remark that the horizontal centering of the contents of the blocks +% is correct even when an instruction such as |!{\qquad}| has been used in the +% preamble of the array in order to increase the space between two columns (this +% is not the case with |\multicolumn|). In the following example, the header +% ``First group'' is correctly centered. +% +% \medskip +% \begin{center} +% \fvset{commandchars=\~\#\+} +% \begin{BVerbatim} +% \begin{NiceTabular}{@{}c!{\qquad}ccc~emphase#!{\qquad}+ccc@{}} +% \toprule +% & ~emphase#\Block{1-3}{First group}+ & & & \Block{1-3}{Second group} \\ +% Rank & 1A & 1B & 1C & 2A & 2B & 2C \\ +% \midrule +% 1 & 0.657 & 0.913 & 0.733 & 0.830 & 0.387 & 0.893\\ +% 2 & 0.343 & 0.537 & 0.655 & 0.690 & 0.471 & 0.333\\ +% 3 & 0.783 & 0.885 & 0.015 & 0.306 & 0.643 & 0.263\\ +% 4 & 0.161 & 0.708 & 0.386 & 0.257 & 0.074 & 0.336\\ +% \bottomrule +% \end{NiceTabular} +% \end{BVerbatim} +% \end{center} +% +% \bigskip +% \begin{center} +% \begin{NiceTabular}{@{}c!{\qquad}ccc!{\qquad}ccc@{}} +% \toprule +% & \Block{1-3}{First group} & & & \Block{1-3}{Second group} \\ +% Rank & 1A & 1B & 1C & 2A & 2B & 2C \\ +% \midrule +% 1 & 0.657 & 0.913 & 0.733 & 0.830 & 0.387 & 0.893\\ +% 2 & 0.343 & 0.537 & 0.655 & 0.690 & 0.471 & 0.333\\ +% 3 & 0.783 & 0.885 & 0.015 & 0.306 & 0.643 & 0.263\\ +% 4 & 0.161 & 0.708 & 0.386 & 0.257 & 0.074 & 0.336\\ +% \bottomrule +% \end{NiceTabular} +% \end{center} +% +% +% +% \section{The rules} +% +% The usual techniques for the rules may be used in the environments of +% \pkg{nicematrix} (excepted |\vline|). However, there is some small differences +% with the classical environments. +% +% \bigskip +% \subsection{Some differences with the classical environments} +% +% \subsubsection{The vertical rules} +% +% In the environments of \pkg{nicematrix}, the vertical rules specified by +% \verb+|+ in the preambles of the environments are never broken, even by an +% incomplete row or by a double horizontal rule specified by |\hline\hline| +% (there is no need to use \pkg{hhline}). \footnote{This is the behaviour since +% the version 5.1 of \pkg{nicematrix}. Prior to that version, the behaviour was +% the standard behaviour of \pkg{array}.} +% +% \bigskip +% \begin{BVerbatim}[baseline=c,boxwidth=10cm] +% \begin{NiceTabular}{|c|c|} \hline +% First & Second \\ ~emphase#\hline\hline@ +% Peter \\ \hline +% Mary & George\\ \hline +% \end{NiceTabular} +% \end{BVerbatim} +% \begin{NiceTabular}{|c|c|}[c] \hline +% First & Second \\ \hline\hline +% Peter \\ \hline +% Mary & George \\ \hline +% \end{NiceTabular} +% +% +% \bigskip +% However, the vertical rules are not drawn in the blocks. +% +% \bigskip +% If you use \pkg{booktabs} (which provides |\toprule|, |\midrule|, +% |\bottomrule|, etc.) and if you really want to add vertical rules (which is +% not in the spirit of \pkg{booktabs}), you should notice that the vertical rules +% drawn by \pkg{nicematrix} are compatible with \pkg{booktabs}. +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=10.5cm] +% $\begin{NiceArray}{~emphase#|cccc|@} \toprule +% a & b & c & d \\ \midrule +% 1 & 2 & 3 & 4 \\ +% 1 & 2 & 3 & 4 \\ \bottomrule +% \end{NiceArray}$ +% \end{BVerbatim} +% $\begin{NiceArray}{|cccc|} +% \toprule +% a & b & c & d \\ +% \midrule +% 1 & 2 & 3 & 4 \\ +% 1 & 2 & 3 & 4 \\ +% \bottomrule +% \end{NiceArray}$ +% +% \bigskip +% However, it's still possible to define a specifier (named, for instance, |I|) +% to draw vertical rules with the standard behaviour of \pkg{array}. +% +% \begin{Verbatim} +% \newcolumntype{I}{!{\vrule}} +% \end{Verbatim} +% +% However, in this case, it is probably more clever to add a command +% |\OnlyMainNiceMatrix| (cf. p.~\pageref{OnlyMainNiceMatrix}): +% \begin{Verbatim} +% \newcolumntype{I}{!{\OnlyMainNiceMatrix{\vrule}}} +% \end{Verbatim} +% +% +% \bigskip +% \subsubsection{The command \textbackslash cline} +% +%\label{remark-cline} +% +% The horizontal and vertical rules drawn by |\hline| and the specifier +% ``\verb+|+'' make the array larger or wider by a quantity equal to the width +% of the rule (with \pkg{array} and also with \pkg{nicematrix}). +% +% \smallskip +% For historical reasons, this is not the case with the command |\cline|, as +% shown by the following example. +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=10cm] +% \setlength{\arrayrulewidth}{2pt} +% \begin{tabular}{cccc} \hline +% A&B&C&D \\ ~emphase#\cline{2-2}@ +% A&B&C&D \\ \hline % \end{tabular} -% \end{ttfamily} +% \end{BVerbatim} +% \begin{scope} +% \setlength{\arrayrulewidth}{2pt} +% \begin{tabular}[c]{cccc} +% \hline +% A&B&C&D \\ +% \cline{2-2} +% A&B&C&D \\ +% \hline +% \end{tabular} +% \end{scope} +% +% \medskip +% In the environments of \pkg{nicematrix}, this situation is corrected (it's +% still possible to go to the standard behaviour of |\cline| with the key |standard-cline|). +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=10cm] +% \setlength{\arrayrulewidth}{2pt} +% \begin{NiceTabular}{cccc} \hline +% A&B&C&D \\ ~emphase#\cline{2-2}@ +% A&B&C&D \\ \hline +% \end{NiceTabular} +% \end{BVerbatim} +% \begin{scope} +% \setlength{\arrayrulewidth}{2pt} +% \begin{NiceTabular}[c]{cccc} +% \hline +% A&B&C&D \\ +% \cline{2-2} +% A&B&C&D \\ +% \hline +% \end{NiceTabular} +% \end{scope} +% +% +% \subsection{The thickness and the color of the rules} +% +% The environments of \pkg{nicematrix} provide a key |rules/width| to set the +% width (in fact the thickness) of the rules in the current environment. In +% fact, this key merely sets the value of the length |\arrayrulewidth|. +% +% \smallskip +% It's well known that \pkg{colortbl} provides the command |\arrayrulecolor| in +% order to specify the color of the rules. +% +% \smallskip +% With \pkg{nicematrix}, it's possible to specify the color of the rules even +% when \pkg{colortbl} is not loaded. For sake of compatibility, the command is +% also named |\arrayrulecolor|. The environments of \pkg{nicematrix} also +% provide a key |rules/color| to fix the color of the rules in the current +% environment. +% +% \medskip +% \begin{scope} +% \hfuzz=10cm +% \begin{BVerbatim}[baseline=c,boxwidth=9.5cm] +% \begin{NiceTabular}{|ccc|}[~emphase#rules/color=[gray]{0.9},rules/width=1pt@] +% \hline +% rose & tulipe & lys \\ +% arum & iris & violette \\ +% muguet & dahlia & souci \\ +% \hline +% \end{NiceTabular} +% \end{BVerbatim} +% \begin{NiceTabular}{|ccc|}[rules/color=[gray]{0.9},rules/width=1pt] +% \hline +% rose & tulipe & lys \\ +% arum & iris & violette \\ +% muguet & dahlia & souci \\ +% \hline +% \end{NiceTabular} +% \end{scope} +% +% \medskip +% If one wishes to define new specifiers for columns in order to draw vertical +% rules (for example with a specific color or thicker than the standard rules), +% he should consider the command |\OnlyMainNiceMatrix| described on +% page~\pageref{OnlyMainNiceMatrix}. +% +% +% +% \subsection{The keys hlines and vlines} +% +% The key |hlines| draws all the horizontal rules and the key |vlines| draws all +% the vertical rules excepted in the blocks (and the virtual blocks determined +% by dotted lines). In fact, in the environments with delimiters (as +% |{pNiceMatrix}| or |{bNiceArray}|) the exteriors rules are not drawn (as +% expected). +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=10.6cm] +% $\begin{pNiceMatrix}[~emphase#vlines@,rules/width=0.2pt] +% 1 & 2 & 3 & 4 & 5 & 6 \\ +% 1 & 2 & 3 & 4 & 5 & 6 \\ +% 1 & 2 & 3 & 4 & 5 & 6 +% \end{pNiceMatrix}$ +% \end{BVerbatim} +% $\begin{pNiceMatrix}[vlines,rules/width=0.2pt] +% 1 & 2 & 3 & 4 & 5 & 6 \\ +% 1 & 2 & 3 & 4 & 5 & 6 \\ +% 1 & 2 & 3 & 4 & 5 & 6 +% \end{pNiceMatrix}$ +% +% +% +% \subsection{The key hvlines} +% \label{hvlines} +% +% The key |hvlines| draws all the vertical and horizontal rules (excepted +% in the blocks and the virtual blocks determined by dotted lines and excepted +% the rules corresponding of the frame of the blocks using the key |draw| which +% are drawn with their own characteristics). +% +% \medskip +% \begin{Verbatim} +% \setlength{\arrayrulewidth}{1pt} +% \begin{NiceTabular}{cccc}[~emphase#hvlines@,rules/color=blue] +% rose & tulipe & marguerite & dahlia \\ +% violette & \Block[draw=red]{2-2}{\LARGE fleurs} & & souci \\ +% pervenche & & & lys \\ +% arum & iris & jacinthe & muguet +% \end{NiceTabular} +% \end{Verbatim} +% +% \begin{center} +% \setlength{\arrayrulewidth}{1pt} +% \begin{NiceTabular}{cccc}[hvlines,rules/color=blue] +% rose & tulipe & marguerite & dahlia \\ +% violette & \Block[draw=red]{2-2}{\LARGE fleurs} & & souci \\ +% pervenche & & & lys \\ +% arum & iris & jacinthe & muguet +% \end{NiceTabular} +% \end{center} +% +% +% \subsection{The key hvlines-except-corners} +% +% The key |hvlines-except-corners| draws all the horizontal and vertical rules, +% excepted in the blocks (and the virtual blocks determined by dotted lines) and +% excepted in the empty corners. +% +% \medskip +% \begin{Verbatim} +% \begin{NiceTabular}{*{6}{c}}[~emphase#hvlines-except-corners@,cell-space-top-limit=3pt] +% & & & & A \\ +% & & A & A & A \\ +% & & & A \\ +% & & A & A & A & A \\ +% A & A & A & A & A & A \\ +% A & A & A & A & A & A \\ +% & \Block{2-2}{B} & & A \\ +% & & & A \\ +% & A & A & A \\ +% \end{NiceTabular} +% \end{Verbatim} +% % +% \begin{center} +% \begin{NiceTabular}{*{6}{c}}[hvlines-except-corners,cell-space-top-limit=3pt] +% & & & & A \\ +% & & A & A & A \\ +% & & & A \\ +% & & A & A & A & A \\ +% A & A & A & A & A & A \\ +% A & A & A & A & A & A \\ +% & \Block{2-2}{B} & & A \\ +% & & & A \\ +% & A & A & A \\ +% \end{NiceTabular} +% \end{center} +% +% As we can see, an ``empty corner'' is composed by the reunion of all the empty +% rectangles starting from the cell actually in the corner of the array. +% +% \bigskip +% It's possible to give as value to the key |\hvlines-except-corners| a list of +% the corners to take into consideration. The corners are designed by |NW|, +% |SW|, |NE| and |SE| (\emph{north west}, \emph{south west}, \emph{north east} +% and \emph{south east}). +% +% \bigskip +% \begin{BVerbatim}[boxwidth=11cm,baseline=c] +% \begin{NiceTabular}{*{6}{c}}% +% [~emphase#hvlines-except-corners=NE@,cell-space-top-limit=3pt] +% 1\\ +% 1&1\\ +% 1&2&1\\ +% 1&3&3&1\\ +% 1&4&6&4&1\\ +% 1&5&10&10&5&1 +% \end{NiceTabular} +% \end{BVerbatim} +% \begin{NiceTabular}{*{6}{c}}[c,hvlines-except-corners=NE,cell-space-top-limit=3pt] +% 1\\ +% 1&1\\ +% 1&2&1\\ +% 1&3&3&1\\ +% 1&4&6&4&1\\ +% 1&5&10&10&5&1 +% \end{NiceTabular} +% +% +% \subsection{The command \textbackslash diagbox} +% +% The command |\diagbox| (inspired by the package \pkg{diagbox}), allows, when +% it is used in a cell, to slash that cell diagonally downwards.\footnote{The +% author of this document considers that type of construction as graphically +% poor.}. +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=10cm] +% $\begin{NiceArray}{*{5}{c}}[hvlines] +% ~emphase#\diagbox{x}{y}@ & 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}$ +% \end{BVerbatim} +% $\begin{NiceArray}{*{5}{c}}[hvlines] +% \diagbox{x}{y} & 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}$ +% +% \medskip +% It's possible to use the command |\diagbox| in a |\Block|. +% +% +% \subsection{Dotted rules} +% +% +% In the environments of the package \pkg{nicematrix}, it's possible to use +% the command |\hdottedline| (provided by \pkg{nicematrix}) which is a +% counterpart of the classical commands |\hline| and |\hdashline| (the latter is +% a command of \pkg{arydshln}). +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=9.5cm] +% \begin{pNiceMatrix} +% 1 & 2 & 3 & 4 & 5 \\ +% ~emphase#\hdottedline@ +% 6 & 7 & 8 & 9 & 10 \\ +% 11 & 12 & 13 & 14 & 15 +% \end{pNiceMatrix} +% \end{BVerbatim} +% $\begin{pNiceMatrix} +% 1 & 2 & 3 & 4 & 5 \\ +% \hdottedline +% 6 & 7 & 8 & 9 & 10 \\ +% 11 & 12 & 13 & 14 & 15 +% \end{pNiceMatrix}$ +% +% +% \bigskip +% In the environments with an explicit preamble (like |{NiceTabular}|, +% |{NiceArray}|, etc.), it's possible to draw a vertical dotted line with the +% specifier ``|:|''. +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=9.5cm] +% \left(\begin{NiceArray}{cccc~emphase#:@c} +% 1 & 2 & 3 & 4 & 5 \\ +% 6 & 7 & 8 & 9 & 10 \\ +% 11 & 12 & 13 & 14 & 15 +% \end{NiceArray}\right) +% \end{BVerbatim} +% $\left(\begin{NiceArray}{cccc:c} +% 1 & 2 & 3 & 4 & 5 \\ +% 6 & 7 & 8 & 9 & 10 \\ +% 11 & 12 & 13 & 14 & 15 +% \end{NiceArray}\right)$ +% +% \bigskip +% 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|. Thus released, the letter ``|:|'' can be used otherwise +% (for example by the package \pkg{arydshln}). +% +% \bigskip +% \emph{Remark} : In the package \pkg{array} (on which the package +% \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|: cf +% p.~\pageref{remark-cline}}. In \pkg{nicematrix}, the dotted lines drawn by +% |\hdottedline| and ``|:|'' do likewise. +% +% +% +%\section{The color of the rows and columns} +% +% \subsection{Use of colortbl} +% +% We recall that the package \pkg{colortbl} can be loaded directly with +% |\usepackage{colortbl}| or by loading \pkg{xcolor} with the key |table|: +% |\usepackage[table]{xcolor}|. +% +% \medskip +% Since the package \pkg{nicematrix} is based on \pkg{array}, it's possible to +% use \pkg{colortbl} with \pkg{nicematrix}. +% +% \medskip +% However, there is two drawbacks: +% \begin{itemize} +% \item The package \pkg{colortbl} patches \pkg{array}, leading to some +% incompatibilities (for example with the command |\hdotsfor|). +% +% \item The package \pkg{colortbl} constructs the array row by row, alterning +% colored rectangles, rules and contents of the cells. The resulting +% \textsc{pdf} is difficult to interpret by some \textsc{pdf} viewers and may +% lead to artefacts on the screen. +% \begin{itemize} +% \item Some rules seem to disappear. This is because many PDF viewers give +% priority to graphical element drawn posteriorly (which is in the spirit of the +% ``painting model'' of PostScript and PDF). Concerning this problem, MuPDF +% (which is used, for instance, by SumatraPDF) gives better results than Adobe +% Reader). +% \item A thin white line may appear between two cells of the same color. This +% phenomenon occurs when each cell is colored with its own instruction |fill| +% (the PostScript operator |fill| noted |f| in PDF). This is the case with +% \pkg{colortbl}: each cell is colored on its own, even when |\columncolor| or +% |\rowcolor| is used. +% +% As for this phenomenon, Adobe Reader gives better results than MuPDF. +% \end{itemize} +% +% The package \pkg{nicematrix} provides tools to avoid those problems. +% \end{itemize} +% +% \subsection{The tools of nicematrix in the code-before} +% +% The package \pkg{nicematrix} provides some tools (independent of +% \pkg{colortbl}) to draw the colored panels first, and, then, the content +% of the cells and the rules. This strategy is more conform to the ``painting +% model'' of the formats PostScript and \textsc{pdf} and is more suitable for +% the \textsc{pdf} viewers. However, it requires several compilations. +% +% \medskip +% The extension \pkg{nicematrix} provides a key |code-before| for some code that +% will be executed before the drawing of the tabular. In this |code-before|, new +% commands are available: |\cellcolor|, |\rectanglecolor|, |\rowcolor|, +% |\columncolor|, |\rowcolors| and |\chessboardcolors|. +% \label{code-before} +% +% \medskip +% All these commands accept an optional argument (between square brackets and +% in first position) which is the color model for the specification of the colors. +% +% \medskip +% \begin{itemize} +% \item The command |\cellcolor| takes its name from the command |\cellcolor| of +% \pkg{colortbl}. +% +% This command takes in as mandatory arguments a color and a list of cells, each +% of which with the format $i$-$j$ where $i$ is the number of row and $j$ the +% number of colummn of the cell. +% % +% \medskip +% \begin{scope} +% \hfuzz=10cm +% \begin{BVerbatim}[boxwidth=10cm,baseline=c] +% \begin{NiceTabular}{|c|c|c|}[code-before = +% ~emphase#\cellcolor{red!15}{3-1,2-2,1-3}@] +% \hline +% a & b & c \\ \hline +% e & f & g \\ \hline +% h & i & j \\ \hline +% \end{NiceTabular} +% \end{BVerbatim} +% \begin{NiceTabular}{|c|c|c|}[code-before = +% \cellcolor{red!15}{3-1,2-2,1-3}] +% \hline +% a & b & c \\ \hline +% e & f & g \\ \hline +% h & i & j \\ \hline +% \end{NiceTabular} +% \end{scope} +% +% \bigskip +% \item The command |\rectanglecolor| takes three mandatory arguments. The first +% is the color. The second is the upper-left cell of the rectangle and the third +% is the lower-right cell of the rectangle. % % \medskip -% By default, the environments |{NiceMatrix}|, |{pNiceMatrix}|, |{bNiceMatrix}|, -% |{BNiceMatrix}|, |{vNiceMatrix}| and |{VNiceMatrix}| behave almost exactly as -% the corresponding environments of \pkg{amsmath}: |{matrix}|, |{pmatrix}|, -% |{bmatrix}|, |{Bmatrix}|, |{vmatrix}| and |{Vmatrix}|. +% \begin{scope} +% \hfuzz=10cm +% \begin{BVerbatim}[boxwidth=10cm,baseline=c] +% \begin{NiceTabular}{|c|c|c|}[code-before = +% ~emphase#\rectanglecolor{blue!15}{2-2}{3-3}@] +% \hline +% a & b & c \\ \hline +% e & f & g \\ \hline +% h & i & j \\ \hline +% \end{NiceTabular} +% \end{BVerbatim} +% \begin{NiceTabular}{|c|c|c|}[code-before = +% \rectanglecolor{blue!15}{2-2}{3-3}] +% \hline +% a & b & c \\ \hline +% e & f & g \\ \hline +% h & i & j \\ \hline +% \end{NiceTabular} +% \end{scope} % % +% +% \bigskip +% \item The command |\rowcolor| takes its name from the command |\rowcolor| of +% \pkg{colortbl}. Its first mandatory argument is the color and the second is a +% comma-separated list of rows or interval of rows with the form $a$-$b$ (an +% interval of the form $a$- represent all the rows from the row $a$ until the end). +% % \medskip -% The environment |{NiceArray}| is similar to the environment |{array}| of the -% package |{array}|. However, for technical reasons, in the preamble of the -% environment |{NiceArray}|, the user must use the letters |L|, |C| and~|R| -% instead of |l|, |c| and |r|. It's possible to use the constructions -% |w{...}{...}|, |W{...}{...}|\footnote{However, for the columns of type |w| and -% |W|, the cells are composed in math mode (in the environments of -% \pkg{nicematrix}) whereas in |{array}| of \pkg{array}, they are composed in -% text mode.}, "|", |>{...}|, |<{...}|, |@{...}|, |!{...}| and |*{n}{...}| but -% the letters |p|, |m| and |b| should not be used. See p.~\pageref{NiceArray} -% the section relating to |{NiceArray}|. +% \begin{scope} +% \hfuzz = 10cm +% \begin{BVerbatim}[boxwidth=9cm,baseline=c] +% $\begin{NiceArray}{lll}[hvlines, ~emphase#code-before = \rowcolor{red!15}{1,3-5,8-}@] +% a_1 & b_1 & c_1 \\ +% a_2 & b_2 & c_2 \\ +% a_3 & b_3 & c_3 \\ +% a_4 & b_4 & c_4 \\ +% a_5 & b_5 & c_5 \\ +% a_6 & b_6 & c_6 \\ +% a_7 & b_7 & c_7 \\ +% a_8 & b_8 & c_8 \\ +% a_9 & b_9 & c_9 \\ +% a_{10} & b_{10} & c_{10} \\ +% \end{NiceArray}$ +% \end{BVerbatim} +% $\begin{NiceArray}{lll}[baseline=4,hvlines, code-before = \rowcolor{red!15}{1,3-5,8-}] +% a_1 & b_1 & c_1 \\ +% a_2 & b_2 & c_2 \\ +% a_3 & b_3 & c_3 \\ +% a_4 & b_4 & c_4 \\ +% a_5 & b_5 & c_5 \\ +% a_6 & b_6 & c_6 \\ +% a_7 & b_7 & c_7 \\ +% a_8 & b_8 & c_8 \\ +% a_9 & b_9 & c_9 \\ +% a_{10} & b_{10} & c_{10} \\ +% \end{NiceArray}$ +% \end{scope} +% +% +% \bigskip +% \item The command |\columncolor| takes its name from the command +% |\columncolor| of \pkg{colortbl}. Its syntax is similar to the syntax of +% |\rowcolor|. +% +% \bigskip +% \item The command |\rowcolors| (with a \emph{s}) takes its name from the +% command |\rowcolors| of \pkg{xcolor}\footnote{The command |\rowcolors| of +% \pkg{xcolor} is available when \pkg{xcolor} is loaded with the +% option~|table|.}. The \emph{s} emphasizes the fact that there is \emph{two} +% colors. This command colors alternately the rows of the tabular with the +% tow colors (provided in second and third argument), beginning +% with the row whose number is given in first (mandatory) argument. +% +% \colorbox{yellow!30}{New 5.8}\enskip In fact, the first (mandatory) +% argument is, more generally, a comma separated list of intervals describing +% the rows involved in the action of |\rowcolors| (an interval of the form +% $i$|-| describes in fact the interval of all the rows of the tabular, +% beginning with the row~$i$). % % +% +% \bigskip +% The last argument of |\rowcolors| is an optional list of pairs key-value (the +% optional argument in the first position corresponds to the colorimetric +% space). The available keys are |cols|, |restart| and |respect-blocks|. +% \begin{itemize} +% \item \colorbox{yellow!30}{New 5.8}\enskip The key |cols| describes a +% set of columns. The command |\rowcolors| will color only the cells of these +% columns. The value is a comma-separated list of intervals of the form $i$-$j$. +% \item \colorbox{yellow!30}{New 5.8}\enskip With the key |restart|, +% each interval of rows (specified by the first mandatory argument) begins with +% the same color.\footnote{Otherwise, the color of a given row relies only upon the +% parity of its number.} +% \item With the key |respect-blocks| the ``rows'' alternately colored may extend over +% several rows if they have to incorporate blocks (created with the command |\Block|). +% \end{itemize} +% +% \medskip +% \begin{scope} +% \hfuzz=10cm +% \begin{BVerbatim}[baseline=c,boxwidth=10cm] +% \begin{NiceTabular}{clr} +% [hvlines,code-before = ~emphase#{\rowcolors{2}{blue!10}{}[cols=2-3,restart]}@] +% \Block{1-}{Results} \\ +% John & 12 \\ +% Stephen & 8 \\ +% Sarah & 18 \\ +% Ashley & 20 \\ +% Henry & 14 \\ +% Madison & 15 +% \end{NiceTabular} +% \end{BVerbatim} +% \begin{NiceTabular}{clr}[hvlines,code-before = +% {\rowcolors{2}{blue!10}{}[cols=2-3,restart]},baseline=2] +% \Block{1-}{Results} \\ +% \Block{2-1}{A}& John & 12 \\ +% & Stephen & 8 \\ +% \Block{4-1}{B}& Sarah & 18 \\ +% & Ashley & 20 \\ +% & Henry & 14 \\ +% & Madison & 15 +% \end{NiceTabular} +% \end{scope} +% +% \vspace{1cm} +% \begin{scope} +% \hfuzz=10cm +% \begin{BVerbatim}[baseline=c,boxwidth=10cm] +% \begin{NiceTabular}{lr}[hvlines,code-before = +% ~emphase#\rowcolors{1}{blue!10}{}[respect-blocks]@] +% \Block{2-1}{John} & 12 \\ +% & 13 \\ +% Steph & 8 \\ +% \Block{3-1}{Sarah} & 18 \\ +% & 17 \\ +% & 15 \\ +% Ashley & 20 \\ +% Henry & 14 \\ +% \Block{2-1}{Madison} & 15 \\ +% & 19 +% \end{NiceTabular} +% \end{BVerbatim} +% \begin{NiceTabular}{lr}[hvlines,code-before = +% \rowcolors{1}{blue!10}{}[respect-blocks],baseline=c] +% \Block{2-1}{John} & 12 \\ +% & 13 \\ +% Steph & 8 \\ +% \Block{3-1}{Sarah} & 18 \\ +% & 17 \\ +% & 15 \\ +% Ashley & 20 \\ +% Henry & 14 \\ +% \Block{2-1}{Madison} & 15 \\ +% & 19 +% \end{NiceTabular} +% \end{scope} +% +% +% \bigskip +% \item The command |\chessboardcolors| takes in as mandatory arguments two colors +% and it colors the cells of the tabular in quincunx with these colors. +% +% \medskip +% \begin{scope} +% \hfuzz=10cm +% \begin{BVerbatim}[baseline=c,boxwidth=9cm] +% $\begin{pNiceMatrix}[r,margin, ~emphase#code-before=\chessboardcolors{red!15}{blue!15}@] +% 1 & -1 & 1 \\ +% -1 & 1 & -1 \\ +% 1 & -1 & 1 +% \end{pNiceMatrix}$ +% \end{BVerbatim} +% $\begin{pNiceMatrix}[r,baseline=1, margin, code-before = \chessboardcolors{red!15}{blue!15}] +% 1 & -1 & 1 \\ +% -1 & 1 & -1 \\ +% 1 & -1 & 1 +% \end{pNiceMatrix}$ +% \end{scope} +% +% \medskip +% We have used the key |r| which aligns all the columns rightwards (cf. p.~\pageref{key-R}). +% \end{itemize} +% +% +% +% \bigskip +% One should remark that these commands are compatible with the commands of +% \pkg{booktabs} (|\toprule|, |\midrule|, |\bottomrule|, etc). +% +% \medskip +% \begin{scope} +% \hfuzz=10cm +% \begin{BVerbatim}[baseline=c,boxwidth=8.5cm] +% \begin{NiceTabular}[c]{lSSSS}% +% [code-before = \rowcolor{red!15}{1-2} \rowcolors{3}{blue!15}{}] +% ~emphase#\toprule@ +% \Block{2-1}{Product} & +% \Block{1-3}{dimensions (cm)} & & & +% \Block{2-1}{\rotate Price} \\ +% ~emphase#\cmidrule(rl){2-4}@ +% & L & l & h \\ +% ~emphase#\midrule@ +% small & 3 & 5.5 & 1 & 30 \\ +% standard & 5.5 & 8 & 1.5 & 50.5 \\ +% premium & 8.5 & 10.5 & 2 & 80 \\ +% extra & 8.5 & 10 & 1.5 & 85.5 \\ +% special & 12 & 12 & 0.5 & 70 \\ +% ~emphase#\bottomrule@ +% \end{NiceTabular} +% \end{BVerbatim} +% \begin{NiceTabular}[c]{lSSSS}[code-before = \rowcolor{red!15}{1-2} +% \rowcolors{3}{blue!15}{}] +% \toprule +% \Block{2-1}{Product} & +% \Block{1-3}{dimensions (cm)} & & & +% \Block{2-1}{\rotate Price} \\ +% \cmidrule(rl){2-4} +% & L & l & h \\ +% \midrule +% small & 3 & 5.5 & 1 & 30 \\ +% standard & 5.5 & 8 & 1.5 & 50.5 \\ +% premium & 8.5 & 10.5 & 2 & 80 \\ +% extra & 8.5 & 10 & 1.5 & 85.5 \\ +% special & 12 & 12 & 0.5 & 70 \\ +% \bottomrule +% \end{NiceTabular} +% \end{scope} +% +% \medskip +% We have used the type of column |S| of \pkg{siunitx}. +% +% +% \subsection{Color tools with the syntax of colortbl} +% +% It's possible to access the preceding tools with a syntax close to the syntax +% of \pkg{colortbl}. For that, one must use the key |colortbl-like| in the +% current environment.\footnote{As of now, this key is not available in |\NiceMatrixOptions|.} +% +% There are three commands available (they are inspired by \pkg{colortbl} but +% are \emph{independent} of \pkg{colortbl}): +% \begin{itemize} +% \item |\cellcolor| which colorizes a cell; +% \item |\rowcolor| which must be used in a cell and which colorizes the end of +% the row; +% \item |\columncolor| which must be used in the preamble of the environment +% with the same syntax as the corresponding command of +% \pkg{colortbl} (however, unlike the command |\columncolor| of \pkg{colortbl}, +% this command |\columncolor| can appear within another command, itself used in the +% preamble). +% \end{itemize} +% +% \medskip +% \begin{Verbatim} +% \NewDocumentCommand { \Blue } { } { ~emphase#\columncolor{blue!15}@ } +% \begin{NiceTabular}[colortbl-like]{>{\Blue}c>{\Blue}cc} +% \toprule +% ~emphase#\rowcolor{red!15}@ +% Last name & First name & Birth day \\ +% \midrule +% Achard & Jacques & 5 juin 1962 \\ +% Lefebvre & Mathilde & 23 mai 1988 \\ +% Vanesse & Stephany & 30 octobre 1994 \\ +% Dupont & Chantal & 15 janvier 1998 \\ +% \bottomrule +% \end{NiceTabular} +% \end{Verbatim} +% +% +% \begin{center} +% \NewDocumentCommand { \Blue } { } { \columncolor{blue!15} } +% \begin{NiceTabular}[colortbl-like]{>{\Blue}c>{\Blue}cc} +% \toprule +% \rowcolor{red!15} +% Last name & First name & Birth day \\ +% \midrule +% Achard & Jacques & 5 juin 1962 \\ +% Lefebvre & Mathilde & 23 mai 1988 \\ +% Vanesse & Stephany & 30 octobre 1994 \\ +% Dupont & Chantal & 15 janvier 1998 \\ +% \bottomrule +% \end{NiceTabular} +% \end{center} +% +% +% \section{The width of the columns} +% \label{width} +% +% In the environments with an explicit preamble (like |{NiceTabular}|, +% |{NiceArray}|, etc.), it's possible to fix the width of a given column with +% the standard letters |w| and |W| of the package \pkg{array}. +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=9cm] +% \begin{NiceTabular}{~emphase#Wc{2cm}@cc}[hvlines] +% Paris & New York & Madrid \\ +% Berlin & London & Roma \\ +% Rio & Tokyo & Oslo +% \end{NiceTabular} +% \end{BVerbatim} +% \begin{NiceTabular}{Wc{2cm}cc}[hvlines] +% Paris & New York & Madrid \\ +% Berlin & London & Roma \\ +% Rio & Tokyo & Oslo +% \end{NiceTabular} +% +% +% \bigskip +% In the environments of \pkg{nicematrix}, it's also possible to fix the \emph{minimal} +% width of all the columns of an array directly with the key |columns-width|. +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=10cm] +% $\begin{pNiceMatrix}[~emphase#columns-width = 1cm@] +% 1 & 12 & -123 \\ +% 12 & 0 & 0 \\ +% 4 & 1 & 2 +% \end{pNiceMatrix}$ +% \end{BVerbatim} +% $\begin{pNiceMatrix}[columns-width = 1cm] +% 1 & 12 & -123 \\ +% 12 & 0 & 0 \\ +% 4 & 1 & 2 +% \end{pNiceMatrix}$ +% +% \medskip +% Note that the space inserted between two columns (equal to 2 |\tabcolsep| in +% |{NiceTabular}| and to 2 |\arraycolsep| in the other environments) +% is not suppressed (of course, it's possible to suppress this space by setting +% |\tabcolsep| or |\arraycolsep| equal to $0$~pt before the environment). +% +% \bigskip +% It's possible to give the special value |auto| to the option |columns-width|: +% all the columns of the array will have a width equal to the widest cell of the +% array.\footnote{The result is achieved with only one compilation (but PGF/Tikz +% will have written informations in the |.aux| file and a message requiring a +% second compilation will appear).}\par\nobreak +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=10cm] +% $\begin{pNiceMatrix}[~emphase#columns-width = auto@] +% 1 & 12 & -123 \\ +% 12 & 0 & 0 \\ +% 4 & 1 & 2 +% \end{pNiceMatrix}$ +% \end{BVerbatim} +% $\begin{pNiceMatrix}[columns-width = auto] +% 1 & 12 & -123 \\ +% 12 & 0 & 0 \\ +% 4 & 1 & 2 +% \end{pNiceMatrix}$ +% +% \bigskip +% Without surprise, it's possible to fix the minimal width of the columns of all +% the matrices of a current scope with the command +% |\NiceMatrixOptions|.\par\nobreak +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=8.5cm] +% ~emphase#\NiceMatrixOptions{columns-width=10mm}@ +% $\begin{pNiceMatrix} +% a & b \\ c & d +% \end{pNiceMatrix} +% = +% \begin{pNiceMatrix} +% 1 & 1245 \\ 345 & 2 +% \end{pNiceMatrix}$ +% \end{BVerbatim} +% \begin{scope} +% \NiceMatrixOptions{columns-width=10mm} +% $\begin{pNiceMatrix} +% a & b \\ +% c & d +% \end{pNiceMatrix} +% = +% \begin{pNiceMatrix} +% 1 & 1245 \\ +% 345 & 2 +% \end{pNiceMatrix}$ +% \end{scope} +% +% +% \bigskip +% But it's also possible to fix a zone where all the matrices will have their +% columns of the same width, equal to the widest cell of all the matrices. This +% construction uses the environment |{NiceMatrixBlock}| with the option +% |auto-columns-width|\footnote{At this time, this is the only usage of the +% environment |{NiceMatrixBlock}| but it may have other usages in the future.}. +% The environment |{NiceMatrixBlock}| has no direct link with the command +% |\Block| presented previously in this document (cf.~p.~\pageref{Block}). +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=8.5cm] +% ~emphase#\begin{NiceMatrixBlock}[auto-columns-width]@ +% $\begin{array}{c} +% \begin{bNiceMatrix} +% 9 & 17 \\ -2 & 5 +% \end{bNiceMatrix} \\ \\ +% \begin{bNiceMatrix} +% 1 & 1245345 \\ 345 & 2 +% \end{bNiceMatrix} +% \end{array}$ +% ~emphase#\end{NiceMatrixBlock}@ +% \end{BVerbatim} +% \begin{NiceMatrixBlock}[auto-columns-width] +% $\begin{array}{c} +% \begin{bNiceMatrix} +% 9 & 17 \\ -2 & 5 +% \end{bNiceMatrix} \\ \\ +% \begin{bNiceMatrix} +% 1 & 1245345 \\ 345 & 2 +% \end{bNiceMatrix} +% \end{array}$ +% \end{NiceMatrixBlock} +% +% \medskip +% \textbf{Several compilations may be necessary to achieve the job.} +% +% +% +% \bigskip +% \section{The exterior rows and columns} +% +% The options |first-row|, |last-row|, |first-col| and |last-col| allow the +% composition of exterior rows and columns in the environments of +% \pkg{nicematrix}. +% \label{exterior} +% +% A potential ``first row'' (exterior) has the number $0$ (and not $1$). Idem +% for the potential ``first column''. +% +% \begin{Verbatim} +% $\begin{pNiceMatrix}[~emphase#first-row,last-row,first-col,last-col@] +% $\begin{pNiceMatrix}[~emphase#first-row,last-row,first-col,last-col@,nullify-dots] +% & C_1 & \Cdots & & C_4 & \\ +% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\ +% \Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\ +% & a_{31} & a_{32} & a_{33} & a_{34} & \\ +% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\ +% & C_1 & \Cdots & & C_4 & +% \end{pNiceMatrix}$ +% \end{pNiceMatrix}$ +% \end{Verbatim} +% +% \[\begin{pNiceMatrix}[first-row,last-row,first-col,last-col,nullify-dots] +% & C_1 & \Cdots & & C_4 & \\ +% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\ +% \Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\ +% & a_{31} & a_{32} & a_{33} & a_{34} & \\ +% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\ +% & C_1 & \Cdots & & C_4 & +% \end{pNiceMatrix}\] +% +% \medskip +% The dotted lines have been drawn with the tools presented p.~\pageref{Cdots}. +% +% \bigskip +% We have several remarks to do. +% \begin{itemize}[beginpenalty=10000] +% \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: they will automatically (and +% necessarily) be of type |r| for the first column and |l| for the last one. +% \item One may wonder how \pkg{nicematrix} determines the number of rows and +% columns which are needed for the composition of the ``last row'' and ``last +% column''. +% \begin{itemize} +% \item For the environments with explicit preamble, like |{NiceTabular}| and +% |{pNiceArray}|, the number of columns can obviously be computed from the +% preamble. +% +% \item When the option |light-syntax| (cf. p. \pageref{light-syntax}) is used, +% \pkg{nicematrix} has, in any case, to load the whole body of the environment +% (and that's why it's not possible to put verbatim material in the array with +% the option |light-syntax|). The analysis of this whole body gives the number +% of rows (but not the number of columns). +% +% \item In the other cases, \pkg{nicematrix} compute the number of rows and +% columns during the first compilation and write the result in the |aux| file +% for the next run. +% +% \textsl{However, it's possible to provide the number of the last row and the +% number of the last column as values of the options |last-row| and |last-col|, +% tending to an acceleration of the whole compilation of the document.} That's +% what we will do throughout the rest of the document. +% \end{itemize} +% \end{itemize} +% +% \bigskip +% It's possible to control the appearance of these rows and columns with options +% |code-for-first-row|, |code-for-last-row|, |code-for-first-col| and +% |code-for-last-col|. These options +% specify tokens that will be inserted before each cell of the corresponding row +% or column. +% +% +% \begin{Verbatim} +% \NiceMatrixOptions{~emphase#code-for-first-row@ = \color{red}, +% ~emphase#code-for-first-col@ = \color{blue}, +% ~emphase#code-for-last-row@ = \color{green}, +% ~emphase#code-for-last-col@ = \color{magenta}} +% $\begin{pNiceArray}{cc|cc}[first-row,last-row=5,first-col,last-col,nullify-dots] +% & C_1 & \Cdots & & C_4 & \\ +% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\ +% \Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\ +% \hline +% & a_{31} & a_{32} & a_{33} & a_{34} & \\ +% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\ +% & C_1 & \Cdots & & C_4 & +% \end{pNiceArray}$ +% \end{Verbatim} +% +% \begin{scope} +% \NiceMatrixOptions{code-for-first-row = \color{red}, +% code-for-first-col = \color{blue}, +% code-for-last-row = \color{green}, +% code-for-last-col = \color{magenta}} +% \begin{displaymath} +% \begin{pNiceArray}{cc|cc}[first-row,last-row=5,first-col,last-col,nullify-dots] +% & C_1 & \multicolumn1c{\Cdots} & & C_4 & \\ +% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\ +% \Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\ +% \hline +% & a_{31} & a_{32} & a_{33} & a_{34} & \\ +% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\ +% & C_1 & \multicolumn1c{\Cdots} & & C_4 & +% \end{pNiceArray} +% \end{displaymath} +% \end{scope} +% +% +% \emph{Remarks} +% \begin{itemize}[beginpenalty=10000] +% \item As shown in the previous example, the horizontal and vertical rules +% doesn't extend in the exterior rows and columns. +% +% However, if one wishes to define new specifiers for columns in order to draw +% vertical rules (for example thicker than the standard rules), he should +% consider the command |\OnlyMainNiceMatrix| described on +% page~\pageref{OnlyMainNiceMatrix}. +% +% \item A specification of color present in |code-for-first-row| also applies to +% a dotted line draw in this exterior ``first row'' (excepted if a value has +% been given to |xdots/color|). Idem for the other exterior rows and columns. +% +% \item Logically, the potential option |columns-width| (described +% p.~\pageref{width}) doesn't apply to the ``first column'' and ``last column''. +% \item For technical reasons, it's not possible to use the option of the +% command |\\| after the ``first row'' or before the ``last row'' (the placement +% of the delimiters would be wrong). +% \end{itemize} +% +% +% +% +% % \section{The continuous dotted lines} % -% Inside the environments of the extension \pkg{nicematrix}, new commands are +% \label{Cdots} +% Inside the environments of the package \pkg{nicematrix}, new commands are % 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 @@ -248,7 +1792,8 @@ version 2005/12/01 or later. % |\Iddots| diagonal ones. It's possible to change the color of these lines % with the option |color|.\footnote{It's also possible to change the color of % all theses dotted lines with the option |xdots/color| (\textsl{xdots} to -% remind that it works for |\Cdots|, |\Ldots|, |\Vdots|, etc.): cf. p. \pageref{customization}.}\par\nobreak +% remind that it works for |\Cdots|, |\Ldots|, |\Vdots|, etc.): cf. p. +% \pageref{customization}.}\par\nobreak % % \bigskip % \begin{BVerbatim}[baseline=c,boxwidth=10cm] @@ -308,10 +1853,8 @@ version 2005/12/01 or later. % \end{bNiceMatrix}$ % % \bigskip -% In the first column of this exemple, there are two instructions |\Vdots| but -% only one dotted line is drawn (there is no overlapping graphic objects in the -% resulting \textsc{pdf}\footnote{And it's not possible to draw a |\Ldots| and a -% |\Cdots| line between the same cells.}). +% In the first column of this exemple, there are two instructions |\Vdots| but, +% of course, only one dotted line is drawn. % % \bigskip % In fact, in this example, it would be possible to draw the same matrix more @@ -372,12 +1915,12 @@ version 2005/12/01 or later. % \begin{BVerbatim}[baseline=c,boxwidth=10cm] % $A = \begin{pmatrix} % h & i & j & k & l & m \\ -% x & & & & & x \\ +% x & & & & & x % \end{pmatrix}$ % \end{BVerbatim} % $A = \begin{pmatrix} % h & i & j & k & l & m \\ -% x & & & & & x \\ +% x & & & & & x % \end{pmatrix}$ % % @@ -389,12 +1932,12 @@ version 2005/12/01 or later. % \begin{BVerbatim}[baseline=c,boxwidth=10cm] % $B = \begin{pmatrix} % h & i & j & k & l & m \\ -% x & \ldots & \ldots & \ldots & \ldots & x \\ +% x & \ldots & \ldots & \ldots & \ldots & x % \end{pmatrix}$ % \end{BVerbatim} % $B = \begin{pmatrix} % h & i & j & k & l & m \\ -% x & \ldots & \ldots & \ldots & \ldots & x \\ +% x & \ldots & \ldots & \ldots & \ldots & x % \end{pmatrix}$ % % \bigskip @@ -406,12 +1949,12 @@ version 2005/12/01 or later. % \begin{BVerbatim}[baseline=c,boxwidth=10cm] % $C = \begin{pNiceMatrix} % h & i & j & k & l & m \\ -% x & \Ldots & \Ldots & \Ldots & \Ldots & x \\ +% x & \Ldots & \Ldots & \Ldots & \Ldots & x % \end{pNiceMatrix}$ % \end{BVerbatim} % $C = \begin{pNiceMatrix} % h & i & j & k & l & m \\ -% x & \Ldots & \Ldots & \Ldots & \Ldots & x \\ +% x & \Ldots & \Ldots & \Ldots & \Ldots & x % \end{pNiceMatrix}$ % % \bigskip @@ -424,24 +1967,21 @@ version 2005/12/01 or later. % \begin{BVerbatim}[baseline=c,boxwidth=10cm] % $D = \begin{pNiceMatrix}[~emphase#nullify-dots@] % h & i & j & k & l & m \\ -% x & \Ldots & & & & x \\ +% x & \Ldots & & & & x % \end{pNiceMatrix}$ % \end{BVerbatim} % $D = \begin{pNiceMatrix}[nullify-dots] % h & i & j & k & l & m \\ -% x & \Ldots & & & & x \\ +% x & \Ldots & & & & x % \end{pNiceMatrix}$ % % \medskip % The option |nullify-dots| smashes the instructions |\Ldots| (and the variants) % horizontally but also vertically. % -% \medskip -% \textbf{There must be no space before the opening bracket (|[|) of the options -% of the environment.} % % -% \subsection{The command \textbackslash Hdotsfor} +% \subsection{The commands \textbackslash Hdotsfor and \textbackslash Vdotsfor} % % Some people commonly use the command |\hdotsfor| of \pkg{amsmath} in order to % draw horizontal dotted lines in a matrix. In the environments of @@ -488,27 +2028,60 @@ version 2005/12/01 or later. % 1 & 2 & 3 & 4 & 5 % \end{pNiceMatrix}$ % -% \bigskip -% The command |\hdotsfor| of \pkg{amsmath} takes an optional argument (between -% square brackets) which is used for fine tuning of the space between two -% consecutive dots. For homogeneity, |\Hdotsfor| has also an optional argument -% but this argument is discarded silently. % % Remark: Unlike the command |\hdotsfor| of \pkg{amsmath}, the command -% |\Hdotsfor| may be used when the extension \pkg{colortbl} is loaded (but you +% |\Hdotsfor| may be used when the package \pkg{colortbl} is loaded (but you % might have problem if you use |\rowcolor| on the same row as |\Hdotsfor|). % +% \bigskip +% The package \pkg{nicematrix} also provides a command |\Vdotsfor| similar to +% |\Hdotsfor| but for the vertical dotted lines. +% \bigskip +% The following example uses both |\Hdotsfor| and |\Vdotsfor|: +% +% \begin{Verbatim}[formatcom=\small\color{gray}] +% \begin{bNiceMatrix} +% C[a_1,a_1] & \Cdots & C[a_1,a_n] +% & \hspace*{20mm} & C[a_1,a_1^{(p)}] & \Cdots & C[a_1,a_n^{(p)}] \\ +% \Vdots & \Ddots & \Vdots +% & ~emphase#\Hdotsfor{1}@ & \Vdots & \Ddots & \Vdots \\ +% C[a_n,a_1] & \Cdots & C[a_n,a_n] +% & & C[a_n,a_1^{(p)}] & \Cdots & C[a_n,a_n^{(p)}] \\ +% \rule{0pt}{15mm} & ~emphase#\Vdotsfor{1}@ & & \Ddots & & ~emphase#\Vdotsfor{1}@ \\ +% C[a_1^{(p)},a_1] & \Cdots & C[a_1^{(p)},a_n] +% & & C[a_1^{(p)},a_1^{(p)}] & \Cdots & C[a_1^{(p)},a_n^{(p)}] \\ +% \Vdots & \Ddots & \Vdots +% & ~emphase#\Hdotsfor{1}@ & \Vdots & \Ddots & \Vdots \\ +% C[a_n^{(p)},a_1] & \Cdots & C[a_n^{(p)},a_n] +% & & C[a_n^{(p)},a_1^{(p)}] & \Cdots & C[a_n^{(p)},a_n^{(p)}] +% \end{bNiceMatrix} +% \end{Verbatim} +% +% +% \[\begin{bNiceMatrix} +% C[a_1,a_1] & \Cdots & C[a_1,a_n] & \hspace*{20mm} & C[a_1,a_1^{(p)}] & \Cdots & C[a_1,a_n^{(p)}] \\ +% \Vdots & \Ddots & \Vdots & \Hdotsfor{1} & \Vdots & \Ddots & \Vdots \\ +% C[a_n,a_1] & \Cdots & C[a_n,a_n] & & C[a_n,a_1^{(p)}] & \Cdots & C[a_n,a_n^{(p)}] \\ +% \rule{0pt}{15mm} & \Vdotsfor{1} & & \Ddots & & \Vdotsfor{1} \\ +% C[a_1^{(p)},a_1] & \Cdots & C[a_1^{(p)},a_n] & & C[a_1^{(p)},a_1^{(p)}] & \Cdots & C[a_1^{(p)},a_n^{(p)}] \\ +% \Vdots & \Ddots & \Vdots & \Hdotsfor{1} & \Vdots & \Ddots & \Vdots \\ +% C[a_n^{(p)},a_1] & \Cdots & C[a_n^{(p)},a_n] & & C[a_n^{(p)},a_1^{(p)}] & \Cdots & C[a_n^{(p)},a_n^{(p)}] +% \end{bNiceMatrix}\] +% +% +% +% % \subsection{How to generate the continuous dotted lines transparently} % -% The package \pkg{nicematrix} provides an option called |transparent| for using -% existing code transparently in the environments of the \pkg{amsmath} : -% |{matrix}|, |{pmatrix}|, |{bmatrix}|, etc. In fact, this -% option is an alias for the conjonction of two options: +% Imagine you have a document with a great number of mathematical matrices with +% ellipsis. You may wish to use the dotted lines of \pkg{nicematrix} without +% having to modify the code of each matrix. It's possible with the keys. % |renew-dots| and |renew-matrix|.\footnote{The options |renew-dots|, -% |renew-matrix| and |transparent| can be fixed with the command +% |renew-matrix| can be fixed with the command % |\NiceMatrixOptions| like the other options. However, they can also be fixed -% as options of the command |\usepackage| (it's an exception for these three -% specific options.)} +% as options of the command |\usepackage|. There is also a key |transparent| +% which is an alias for the conjonction of |renew-dots| and |renew-matrix| but it +% must be considered as obsolete.} % % \smallskip % @@ -528,14 +2101,14 @@ version 2005/12/01 or later. % \end{itemize} % % \bigskip -% Therefore, with the option |transparent|, a classical code gives directly the -% ouput of \pkg{nicematrix}.\par\nobreak +% Therefore, with the keys |renew-dots| and |renew-matrix|, a classical code +% gives directly the ouput of \pkg{nicematrix}.\par\nobreak % % \bigskip % \begin{scope} -% \NiceMatrixOptions{transparent} +% \NiceMatrixOptions{renew-dots,renew-matrix} % \begin{BVerbatim}[baseline=c,boxwidth=10cm] -% ~emphase#\NiceMatrixOptions{transparent}@ +% ~emphase#\NiceMatrixOptions{renew-dots,renew-matrix}@ % \begin{pmatrix} % 1 & \cdots & \cdots & 1 \\ % 0 & \ddots & & \vdots \\ @@ -551,12 +2124,33 @@ version 2005/12/01 or later. % \end{pmatrix}$ % \end{scope} % +% \subsection{The labels of the dotted lines} +% +% The commands |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots|, |\Iddots| and |\Hdotsfor| +% (and the command |\line| in the |\CodeAfter| which is described +% p.~\pageref{line-in-code-after}) accept two optional arguments specified +% by the tokens |_| and |^| for labels positionned below and above the line. The +% arguments are composed in math mode with |\scriptstyle|. +% +% \begin{BVerbatim}[baseline=c,boxwidth=10cm] +% $\begin{bNiceMatrix} +% 1 & \hspace*{1cm} & 0 \\[8mm] +% & ~emphase#\Ddots^{n \text{ times}}@ & \\ +% 0 & & 1 +% \end{bNiceMatrix}$ +% \end{BVerbatim} +% $\begin{bNiceMatrix} +% 1 & \hspace*{1cm} & 0 \\[8mm] +% & \Ddots^{n \text{ times}} & \\ +% 0 & & 1 +% \end{bNiceMatrix}$ +% % \subsection{Customization of the dotted lines} % % \label{customization} % The dotted lines drawn by |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots|, |\Iddots| -% and |\Hdotsfor| (and by the command |\line| in the |code-after| which is described -% in p.~\pageref{line-in-code-after}) may be customized by three options (specified +% and |\Hdotsfor| (and by the command |\line| in the |\CodeAfter| which is described +% p.~\pageref{line-in-code-after}) may be customized by three options (specified % between square brackets after the command): % \begin{itemize} % \item |color|; @@ -613,7 +2207,7 @@ version 2005/12/01 or later. % % \medskip % In order to provide lines with rounded dots in the style of those provided by -% |\ldots| (at least with the \emph{Computer Modern} fonts), the extension +% |\ldots| (at least with the \emph{Computer Modern} fonts), the package % \pkg{nicematrix} embeds its own system to draw a dotted line (and this system % uses \textsc{pgf} and not Tikz). This style is called |standard| and that's % the initial value of the parameter |xdots/line-style|. @@ -649,932 +2243,594 @@ version 2005/12/01 or later. % \end{pNiceMatrix}\] % % -% -% \section{The PGF/Tikz nodes created by nicematrix} -% -% \label{name} +% \subsection{The dotted lines and the rules} % -% The package \pkg{nicematrix} creates a PGF/Tikz node for each (non-empty) cell -% of the considered array. These nodes are used to draw the dotted lines between -% the cells of the matrix. However, the user may wish to use directly these -% nodes. It's possible (if Tikz has been loaded\footnote{We remind that, since -% the version 3.13, \pkg{nicematrix} doesn't load Tikz by default by only -% \textsc{pgf} (Tikz is a layer over \textsc{pfg}).}). First, the user have to -% give a name to the array (with the key called |name|). Then, the nodes are -% accessible through the names ``\textsl{name}-$i$-$j$'' where \textsl{name} is -% the name given to the array and $i$ and $j$ the numbers of the row and the -% column of the considered cell. +% \label{dotted-and-rules} % -% \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=11cm] -% $\begin{pNiceMatrix}[name=~emphase#mymatrix@] -% 1 & 2 & 3 \\ -% 4 & 5 & 6 \\ -% 7 & 8 & 9 -% \end{pNiceMatrix}$ -% \tikz[remember picture,overlay] -% \draw ~emphase#(mymatrix-2-2)@ circle (2mm) ; -% \end{BVerbatim} -% $\begin{pNiceMatrix}[name=mymatrix] -% 1 & 2 & 3 \\ -% 4 & 5 & 6 \\ -% 7 & 8 & 9 -% \end{pNiceMatrix}$ -% \tikz[remember picture,overlay] -% \draw (mymatrix-2-2) circle (2mm) ; +% The dotted lines determine virtual blocks which have the same behaviour +% regarding the rules (the rules specified by the specifier \verb+|+ in the +% preamble and by the keys |hlines|, |vlines|, |hvlines| and +% |hvlines-except-corners| are not drawn within the blocks). % % \medskip -% Don't forget the options |remember picture| and |overlay|. -% -% \bigskip -% In the following example, we have underlined all the nodes of the matrix. -% \[\begin{pNiceMatrix}[ -% code-after = {\begin{tikzpicture} -% [every node/.style = {blend mode = multiply, -% fill = red!15, -% inner sep = 0 pt }] -% \node [fit = (1-1)] {} ; -% \node [fit = (1-3)] {} ; -% \node [fit = (2-2)] {} ; -% \node [fit = (3-1)] {} ; -% \node [fit = (3-3)] {} ; -% \node [fit = (1-2)] {} ; -% \node [fit = (2-1)] {} ; -% \node [fit = (2-3)] {} ; -% \node [fit = (3-2)] {} ; -% \end{tikzpicture}}] -% a & a + b & a + b + c \\ -% a & a & a + b \\ -% a & a & a -% \end{pNiceMatrix}\] +% \begin{BVerbatim}[baseline=c,boxwidth=10.6cm] +% $\begin{bNiceMatrix}[margin,~emphase#hvlines@] +% \Block{3-3}<\LARGE>{A} & & & 0 \\ +% & \hspace*{1cm} & & \Vdots \\ +% & & & 0 \\ +% 0 & \Cdots& 0 & 0 +% \end{bNiceMatrix}$ +% \end{BVerbatim} +% $\begin{bNiceMatrix}[margin,hvlines] +% \Block{3-3}<\LARGE>{A} & & & 0 \\ +% & \hspace*{1cm} & & \Vdots \\ +% & & & 0 \\ +% 0 & \Cdots& 0 & 0 +% \end{bNiceMatrix}$ % % -% \bigskip -% In fact, the package \pkg{nicematrix} can create ``extra nodes'': the ``medium -% nodes'' and the ``large nodes''. The first ones -% are created with the option |create-medium-nodes| and the second ones with the -% option |create-large-nodes|.\footnote{There is also an option -% |create-extra-nodes| which is an alias for the conjonction of -% |create-medium-nodes| and |create-large-nodes|.} % -% \medskip -% The names of the ``medium nodes'' are constructed by adding the suffix -% ``|-medium|'' to the names of the ``normal nodes''. In the following example, -% we have underlined the ``medium nodes''. We consider that this example is -% self-explanatory. -% \[\begin{pNiceMatrix}[ -% create-medium-nodes, -% code-after = {\begin{tikzpicture} -% [every node/.style = {fill = red!15, -% blend mode = multiply, -% inner sep = 0pt}, -% name suffix = -medium] -% \node [fit = (1-1)] {} ; -% \node [fit = (1-2)] {} ; -% \node [fit = (1-3)] {} ; -% \node [fit = (2-1)] {} ; -% \node [fit = (2-2)] {} ; -% \node [fit = (2-3)] {} ; -% \node [fit = (3-1)] {} ; -% \node [fit = (3-2)] {} ; -% \node [fit = (3-3)] {} ; -% \end{tikzpicture}}] -% a & a + b & a + b + c \\ -% a & a & a + b \\ -% a & a & a -% \end{pNiceMatrix}\] +% \section{The \textbackslash CodeAfter} % +% \label{code-after} +% The option |code-after| may be used to give some code that will be executed +% after the construction of the matrix.\footnote{There is also a key +% |code-before| described p.~\pageref{code-before}.} % % \medskip -% The names of the ``large nodes'' are constructed by adding the suffix -% ``|-large|'' to the names of the ``normal nodes''. In the following example, -% we have underlined the ``large nodes''. We consider that this example is -% self-explanatory.\footnote{There is no ``large nodes'' created in the exterior -% rows and columns (for these rows and columns, cf. p.~\pageref{exterior}).} -% -% \[\begin{pNiceMatrix}[ -% create-large-nodes, -% code-after = {\begin{tikzpicture} -% [every node/.style = {blend mode = multiply, -% inner sep = 0pt}, -% name suffix = -large] -% \node [fit = (1-1),fill = red!15] {} ; -% \node [fit = (1-3),fill = red!15] {} ; -% \node [fit = (2-2),fill = red!15] {} ; -% \node [fit = (3-1),fill = red!15] {} ; -% \node [fit = (3-3),fill = red!15] {} ; -% \node [fit = (1-2),fill = blue!15] {} ; -% \node [fit = (2-1),fill = blue!15] {} ; -% \node [fit = (2-3),fill = blue!15] {} ; -% \node [fit = (3-2),fill = blue!15] {} ; -% \end{tikzpicture}}] -% a & a + b & a + b + c \\ -% a & a & a + b \\ -% a & a & a -% \end{pNiceMatrix}\] -% +% For the legibility of the code, an alternative syntax is provided: it's +% possible to give the instructions of the |\code-after| at the end of the +% environment, after the keyword |\CodeAfter|. % % \medskip -% The ``large nodes'' of the first column and last column may appear too small -% for some usage. That's why it's possible to use the options |left-margin| and -% |right-margin| to add space on both sides of the array and also space in the -% ``large nodes'' of the first column and last column. In the following example, -% we have used the options |left-margin| and |right-margin|.\footnote{The -% options |left-margin| and |right-margin| take dimensions as values but, if no -% value is given, the default value is used, which is |\arraycolsep| (by -% default: 5~pt). There is also an option |margin| to fix both |left-margin| and -% |right-margin| to the same value.} -% \[\begin{pNiceMatrix}[ -% create-large-nodes,left-margin,right-margin, -% code-after = {\begin{tikzpicture} -% [every node/.style = {blend mode = multiply, -% inner sep = 0pt}, -% name suffix = -large] -% \node [fit = (1-1),fill = red!15] {} ; -% \node [fit = (1-3),fill = red!15] {} ; -% \node [fit = (2-2),fill = red!15] {} ; -% \node [fit = (3-1),fill = red!15] {} ; -% \node [fit = (3-3),fill = red!15] {} ; -% \node [fit = (1-2),fill = blue!15] {} ; -% \node [fit = (2-1),fill = blue!15] {} ; -% \node [fit = (2-3),fill = blue!15] {} ; -% \node [fit = (3-2),fill = blue!15] {} ; -% \end{tikzpicture}}] -% a & a + b & a + b + c \\ -% a & a & a + b \\ -% a & a & a -% \end{pNiceMatrix}\] +% Two special commands are available in the |\CodeAfter|: |line| and +% |\SubMatrix|. +% +% \subsection{The command \textbackslash line in the \textbackslash CodeAfter} % -% \medskip -% It's also possible to add more space on both side of the array with the -% options |extra-left-margin| and |extra-right-margin|. These margins are not -% incorporated in the ``large nodes''. It's possible to fix both values with the -% option |extra-margin| and, in the following example, we use |extra-margin| -% with the value $3$~pt. -% \[\begin{pNiceMatrix}[ -% create-large-nodes,margin,extra-margin=3pt, -% code-after = {\begin{tikzpicture} -% [every node/.style = {blend mode = multiply, -% inner sep = 0 pt}, -% name suffix = -large] -% \node [fit = (1-1),fill = red!15] {} ; -% \node [fit = (1-3),fill = red!15] {} ; -% \node [fit = (2-2),fill = red!15] {} ; -% \node [fit = (3-1),fill = red!15] {} ; -% \node [fit = (3-3),fill = red!15] {} ; -% \node [fit = (1-2),fill = blue!15] {} ; -% \node [fit = (2-1),fill = blue!15] {} ; -% \node [fit = (2-3),fill = blue!15] {} ; -% \node [fit = (3-2),fill = blue!15] {} ; -% \end{tikzpicture}}] -% a & a + b & a + b + c \\ -% a & a & a + b \\ -% a & a & a -% \end{pNiceMatrix}\] +% The command |\line|draws directly dotted lines between nodes. It takes two +% arguments for the two cells to rely, both of the form $i$-$j$ where is the +% number of row and $j$ is the number of column. It may be used, for example, to +% draw a dotted line between two adjacent cells. \label{line-in-code-after} % % \medskip -% In this case, if we want a control over the height of the rows, we can add a -% |\strut| in each row of the array. -% \[\begin{pNiceMatrix}[ -% create-large-nodes,left-margin,right-margin,extra-right-margin=3pt, -% extra-left-margin=3pt, -% code-after = {\begin{tikzpicture} -% [every node/.style = {blend mode = multiply, -% inner sep = 0 pt}, -% name suffix = -large] -% \node [fit = (1-1),fill = red!15] {} ; -% \node [fit = (1-3),fill = red!15] {} ; -% \node [fit = (2-2),fill = red!15] {} ; -% \node [fit = (3-1),fill = red!15] {} ; -% \node [fit = (3-3),fill = red!15] {} ; -% \node [fit = (1-2),fill = blue!15] {} ; -% \node [fit = (2-1),fill = blue!15] {} ; -% \node [fit = (2-3),fill = blue!15] {} ; -% \node [fit = (3-2),fill = blue!15] {} ; -% \end{tikzpicture}}] -% \strut a & a + b & a + b + c \\ -% \strut a & a & a + b \\ -% \strut a & a & a -% \end{pNiceMatrix}\] -% -% \bigskip -% We explain below how to fill the nodes created by \pkg{nicematrix} (cf. p. -% \pageref{highlight}). +% \begin{BVerbatim}[baseline=c,boxwidth=11cm] +% \NiceMatrixOptions{xdots/shorten = 0.6 em} +% \begin{pNiceMatrix} +% I & 0 & \Cdots &0 \\ +% 0 & I & \Ddots &\Vdots\\ +% \Vdots &\Ddots & I &0 \\ +% 0 &\Cdots & 0 &I +% ~emphase#\CodeAfter \line{2-2}{3-3}@ +% \end{pNiceMatrix} +% \end{BVerbatim} +% \begin{scope} +% \NiceMatrixOptions{xdots/shorten = 0.6 em} +% $\begin{pNiceMatrix} +% I & 0 & \Cdots &0 \\ +% 0 & I & \Ddots &\Vdots\\ +% \Vdots &\Ddots & I &0 \\ +% 0 &\Cdots & 0 &I +% \CodeAfter \line{2-2}{3-3} +% \end{pNiceMatrix}$ +% \end{scope} % -% \section{The code-after} % -% \label{code-after} -% The option |code-after| may be used to give some code that will be excuted -% after the construction of the matrix (and thus after the construction of -% all the nodes). -% -% \smallskip -% \textbf{If Tikz is loaded}\footnote{We remind that, since the version 3.13, -% \pkg{nicematrix} doesn't load Tikz by default but only \textsc{pgf} (Tikz is a -% layer over \textsc{pfg}).}, one may access to that nodes with classical Tikz -% instructions. The nodes should be designed as $i$-$j$ (without the prefix -% corresponding to the name of the environment). +% \subsection{The command \textbackslash SubMatrix in the \textbackslash CodeAfter} +% +% \label{sub-matrix} % -% Moreover, a special command, called |\line|, is available to draw directly -% dotted lines between nodes. \label{line-in-code-after} +% \colorbox{yellow!50}{\textbf{New 5.10}}\enskip +% The command |\SubMatrix| provides a way to put delimiters on an portion +% of the array considered as a submatrix. The command |\SubMatrix| takes in five +% arguments: +% \begin{itemize} +% \item the first argument is the left delimiter, which may be any extensible delimiter +% provided by LaTeX : |(|, |[|, |\{|, |\langle|, |\lgroup|, |\lfloor|, etc. but also +% the null delimiter |.|; +% \item the second argument is the upper-left corner of the submatrix with the +% syntax $i$|-|$j$ where $i$ the number of row and $j$ the number of column; +% \item the third argument is the lower-right corner with the same syntax; +% \item the fourth argument is the right delimiter; +% \item the last argument, which is optional, is a list of key-value pairs. +% \end{itemize} +% +% One should remark that the command |\SubMatrix| draws the delimiters after the +% construction of the array: no space is inserted by the command |\SubMatrix| +% itself. That's why, in the following example, we have used the key |margin| +% and you have added by hand some space between the third and fourth column with +% |@{\hspace{1.5em}}| in the preamble of the array. % % \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=13cm] -% $\begin{pNiceMatrix}[~emphase#code-after = {\line{1-1}{3-3}[color=blue]}@] -% 0 & 0 & 0 \\ -% 0 & & 0 \\ -% 0 & 0 & 0 -% \end{pNiceMatrix}$ +% \begin{scope} +% \fvset{commandchars=\~\#\+}% +% \begin{BVerbatim}[boxwidth=11cm,baseline=c] +% \[\begin{NiceArray}{ccc~emphase#@{\hspace{1.5em}}+c}% +% [cell-space-limits=2pt,~emphase#margin+] +% 1 & 1 & 1 & x \\ +% \dfrac{1}{4} & \dfrac{1}{2} & \dfrac{1}{4} & y \\ +% 1 & 2 & 3 & z +% \CodeAfter +% ~emphase#\SubMatrix({1-1}{3-3})+ +% ~emphase#\SubMatrix({1-4}{3-4})+ +% \end{NiceArray}\] % \end{BVerbatim} -% $\begin{pNiceMatrix}[code-after = {\line{1-1}{3-3}[color=blue]}] -% 0 & 0 & 0 \\ -% 0 & & 0 \\ -% 0 & 0 & 0 -% \end{pNiceMatrix}$ +% \end{scope} +% $\begin{NiceArray}{ccc@{\hspace{1.5em}}c}[cell-space-limits=2pt,margin] +% 1 & 1 & 1 & x \\ +% \dfrac{1}{4} & \dfrac{1}{2} & \dfrac{1}{4} & y \\ +% 1 & 2 & 3 & z +% \CodeAfter +% \SubMatrix({1-1}{3-3}) +% \SubMatrix({1-4}{3-4}) +% \end{NiceArray}$ % +% \bigskip +% The options of the command |\SubMatrix| are as follows: +% \begin{itemize} +% \item |left-xshift| and |right-shift| shift horizontally the delimiters (there +% exists also the key |xshift| which fixes both parameters); +% \item |extra-height| adds a quantity to the total height of the delimiters +% (height |\ht| + depth |\dp|); +% \item |delimiters-color| fixes the color of the delimiters (also +% available in |\NiceMatrixOptions|, in the environments with delimiters and as +% option of the command |\CodeAfter|); +% \item |slim| is a boolean key: when that key is in force, the horizontal +% position of the delimiters is computed by using only the contents of the cells +% of the submatrix whereas, in the general case, the position is computed by +% taking into account the cells of the whole columns implied in the submatrix +% (see example below). +% \end{itemize} % -% \section{The environment \{NiceArray\}} -% \label{NiceArray} +% These keys are also available in |\NiceMatrixOptions|, at the level of the +% environments of \pkg{nicematrix} or as option of the command |\CodeAfter| with +% the prefix |sub-matrix| which means that their names are therefore +% |sub-matrix/left-xshift|, |sub-matrix/right-xshift|, |sub-matrix/xshift|, etc. % -% The environment |{NiceArray}| is similar to the environment |{array}|. As for -% |{array}|, the mandatory argument is the preamble of the array. However, for -% technical reasons, in this preamble, the user must use the letters |L|, |C| -% and~|R|\footnote{The column types |L|, |C| and |R| are defined locally inside -% |{NiceArray}| with |\newcolumntype| of \pkg{array}. This definition overrides -% an eventual previous definition. In fact, the column types |w| and |W| are -% also redefined.} instead of |l|, |c| and |r|. It's possible -% to use the constructions |w{...}{...}|, |W{...}{...}|, "|", |>{...}|, -% |<{...}|, |@{...}|, |!{...}| and |*{n}{...}| but the letters |p|, |m| and |b| -% should not be used.\footnote{In a command |\multicolumn|, one should also use -% the letters |L|, |C|, |R|.} +% +% \bigskip +% \begin{scope} +% \fvset{commandchars=\~\#\!}% +% \begin{BVerbatim}[baseline=c,boxwidth=11cm] +% $\begin{NiceArray}{cc@{\hspace{5mm}}l}% +% [cell-space-limits=2pt] +% & & \frac12 \\ +% & & \frac14 \\[1mm] +% a & b & \frac12a+\frac14b \\ +% c & d & \frac12c+\frac14d \\ +% \CodeAfter +% \SubMatrix({1-3}{2-3}) +% \SubMatrix({3-1}{4-2}) +% \SubMatrix({3-3}{4-3}) +% \end{NiceArray}$ +% \end{BVerbatim} +% \end{scope} +% $\begin{NiceArray}{cc@{\hspace{5mm}}l}[cell-space-limits=2pt] +% & & \frac12 \\ +% & & \frac14 \\[1mm] +% a & b & \frac12a+\frac14b \\ +% c & d & \frac12c+\frac14d \\ +% \CodeAfter +% \SubMatrix({1-3}{2-3}) +% \SubMatrix({3-1}{4-2}) +% \SubMatrix({3-3}{4-3}) +% \end{NiceArray}$ % % \medskip -% 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}|. +% Here is the same example with the key |slim| used for one of the submatrices. % % \medskip +% \begin{scope} +% \fvset{commandchars=\~\#\!}% % \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 \\ +% $\begin{NiceArray}{cc@{\hspace{5mm}}l}% +% [cell-space-limits=2pt] +% & & \frac12 \\ +% & & \frac14 \\[1mm] +% a & b & \frac12a+\frac14b \\ +% c & d & \frac12c+\frac14d \\ +% \CodeAfter +% \SubMatrix({1-3}{2-3})[~emphase#slim!] +% \SubMatrix({3-1}{4-2}) +% \SubMatrix({3-3}{4-3}) % \end{NiceArray}$ % \end{BVerbatim} -% $A = -% \begin{NiceArray}{CCCC}[hvlines,baseline=2] -% 1 & 2 & 3 & 4 \\ -% 1 & 2 & 3 & 4 \\ -% 1 & 2 & 3 & 4 \\ +% \end{scope} +% $\begin{NiceArray}{cc@{\hspace{5mm}}l}[cell-space-limits=2pt] +% & & \frac12 \\ +% & & \frac14 \\[1mm] +% a & b & \frac12a+\frac14b \\ +% c & d & \frac12c+\frac14d \\ +% \CodeAfter +% \SubMatrix({1-3}{2-3})[slim] +% \SubMatrix({3-1}{4-2}) +% \SubMatrix({3-3}{4-3}) % \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}|.}). +% \bigskip +% There is also a key |name| which gives a name to the submatrix created by +% |\SubMatrix|. That name is used to created PGF/Tiks nodes: cf +% p.~\pageref{node-sub-matrix}. +% +% \section{The notes in the tabulars} +% +% \label{s:notes} +% +% \subsection{The footnotes} % % \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 +% The package \pkg{nicematrix} allows, by using \pkg{footnote} or +% \pkg{footnotehyper}, the extraction of the notes inserted by |\footnote| in +% the environments of \pkg{nicematrix} and their composition in the footpage +% with the other notes of the document. +% % \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 +% If \pkg{nicematrix} is loaded with the option |footnote| (with +% |\usepackage[footnote]{nicematrix}| or with |\PassOptionsToPackage|), the +% package \pkg{footnote} is loaded (if it is not yet loaded) and it is used to +% extract the footnotes. +% % \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 +% If \pkg{nicematrix} is loaded with the option |footnotehyper|, the package +% \pkg{footnotehyper} is loaded (if it is not yet loaded) ant it is used to +% extract footnotes. +% % \smallskip -% \item -% $\begin{NiceArray}[t]{LCCCCCC} +% Caution: The packages \pkg{footnote} and \pkg{footnotehyper} are incompatible. +% The package \pkg{footnotehyper} is the successor of the package \pkg{footnote} +% and should be used preferently. The package \pkg{footnote} has some drawbacks, +% in particular: it must be loaded after the package \pkg{xcolor} and it is not +% perfectly compatible with \pkg{hyperref}. +% +% +% \subsection{The notes of tabular} +% +% The package \pkg{nicematrix} also provides a command |\tabularnote| which gives +% the ability to specify notes that will be composed at the end of the array +% with a width of line equal to the width of the array (excepted the potential +% exterior columns). With no surprise, that command is available only in the +% environments without delimiters, that is to say |{NiceTabular}|, |{NiceArray}| +% and |{NiceMatrix}|. +% +% In fact, this command is available only if the extension \pkg{enumitem} has +% been loaded (before or after \pkg{nicematrix}). Indeed, the notes are composed +% at the end of the array with a type of list provided by the package +% \pkg{enumitem}. +% +% \begin{scope} +% \fvset{commandchars=\~\#\!} +% \begin{Verbatim} +% \begin{NiceTabular}{@{}llr@{}}[first-row,code-for-first-row = \bfseries] % \toprule -% n & 0 & 1 & 2 & 3 & 4 & 5 \\ +% Last name & First name & Birth day \\ % \midrule -% u_n & 1 & 2 & 4 & 8 & 16 & 32 \\ +% Achard\tabularnote{~emphase#Achard is an old family of the Poitou.!} +% & Jacques & 5 juin 1962 \\ +% Lefebvre\tabularnote{~emphase#The name Lefebvre is an alteration of the name Lefebure.!} +% & Mathilde & 23 mai 1988 \\ +% Vanesse & Stephany & 30 octobre 1994 \\ +% Dupont & Chantal & 15 janvier 1998 \\ % \bottomrule -% \end{NiceArray}$ -% \end{enumerate} -% \end{minipage} -% +% \end{NiceTabular} +% \end{Verbatim} +% \end{scope} % -% \vspace{1cm} -% With |{NiceArray}|, it's possible to draw vertical rules:\par\nobreak +% \begin{center} +% \begin{NiceTabular}{@{}llr@{}}[first-row,code-for-first-row = \bfseries] +% \toprule +% Last name & First name & Birth day \\ +% \midrule +% Achard\tabularnote{Achard is an old family of the Poitou.} +% & Jacques & June 5, 2005 \\ +% Lefebvre\tabularnote{The name Lefebvre is an alteration of the name Lefebure.} +% & Mathilde & January 23, 1975 \\ +% Vanesse & Stephany & October 30, 1994 \\ +% Dupont & Chantal & January 15, 1998 \\ +% \bottomrule +% \end{NiceTabular} +% \end{center} % -% \bigskip -% \begin{BVerbatim}[baseline=c,boxwidth=10cm] -% $\left[\begin{NiceArray}{CCCC|C} -% a_1 & ? & \Cdots & ? & ? \\ -% 0 & & \Ddots & \Vdots & \Vdots\\ -% \Vdots & \Ddots & \Ddots & ? \\ -% 0 & \Cdots & 0 & a_n & ? -% \end{NiceArray}\right]$ -% \end{BVerbatim} -% $\left[\begin{NiceArray}{CCCC|C} -% a_1 & ? & \Cdots & ? & ? \\ -% 0 & & \Ddots & \Vdots & \Vdots\\ -% \Vdots & \Ddots & \Ddots & ? \\ -% 0 & \Cdots & 0 & a_n & ? -% \end{NiceArray}\right]$ % % \bigskip -% In fact, there is also variants for the environment |{NiceArray}|: -% |{pNiceArray}|, |{bNiceArray}|, |{BNiceArray}|, |{vNiceArray}| and -% |{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| -% --- in |{pNiceMatrix}|, all the columns are of type |C|). +% \begin{itemize} +% \item If you have several successive commands |\tabularnote{...}| \emph{with no +% space at all between them}, the labels of the corresponding notes are composed +% together, separated by commas (this is similar to the option |multiple| of +% \pkg{footmisc} for the footnotes). % -% \bigskip -% \begin{BVerbatim}[baseline=c,boxwidth=10cm] -% $\begin{pNiceArray}{LCR} -% a_{11} & \Cdots & a_{1n} \\ -% a_{21} & & a_{2n} \\ -% \Vdots & & \Vdots \\ -% a_{n-1,1} & \Cdots & a_{n-1,n} -% \end{pNiceArray}$ -% \end{BVerbatim} -% $\begin{pNiceArray}{LCR} -% a_{11} & \Cdots & a_{1n} \\ -% a_{21} & & a_{2n} \\ -% \Vdots & & \Vdots \\ -% a_{n-1,1} & \Cdots & a_{n-1,n} -% \end{pNiceArray}$ +% \item If a command |\tabularnote{...}| is exactly at the end of a cell (with +% no space at all after), the label of the note is composed in an overlapping +% position (towards the right). This structure may provide a better alignment of +% the cells of a given column. % +% \item If the key |notes/para| is used, the notes are composed at the end of +% the array in a single paragraph (as with the key |para| of \pkg{threeparttable}). % -% \bigskip -% In fact, the environment |{pNiceArray}| and its variants are based upon a -% 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 or asymetrical delimiters. +% \item There is a key |tabularnote| which provides a way to insert some text in +% the zone of the notes before the numbered tabular notes. % -% \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=11cm] -% $\begin{~emphase#NiceArrayWithDelims@} -% {\downarrow}{\uparrow}{CCC}[margin] -% 1 & 2 & 3 \\ -% 4 & 5 & 6 \\ -% 7 & 8 & 9 \\ -% \end{~emphase#NiceArrayWithDelims@}$ -% \end{BVerbatim} -% $\begin{NiceArrayWithDelims} -% {\downarrow}{\uparrow}{CCC}[margin] -% 1 & 2 & 3 \\ -% 4 & 5 & 6 \\ -% 7 & 8 & 9 \\ -% \end{NiceArrayWithDelims}$ +% \item If the package \pkg{booktabs} has been loaded (before or after +% \pkg{nicematrix}), the key |notes/bottomrule| draws a |\bottomrule| of +% \pkg{booktabs} \emph{after} the notes. % +% \item The command |\tabularnote| may be used \emph{before} +% the environment of \pkg{nicematrix}. Thus, it's possible to use it on the +% title inserted by |\caption| in an environment |{table}| of LaTeX. % -% \bigskip -% \section{The exterior rows and columns} -% The options |first-row|, |last-row|, |first-col| and |last-col| allow the -% composition of exterior rows and columns in the environments of -% \pkg{nicematrix}. -% \label{exterior} +% \item It's possible to create a reference to a tabular note created by |\tabularnote| +% (with the usual command |\label| used after the |\tabularnote|). +% \end{itemize} +% % +% For an illustration of some of those remarks, see table +% \ref{t:tabularnote}, p.~\pageref{t:tabularnote}. This table has been composed +% with the following code. % -% A potential ``first row'' (exterior) has the number $0$ (and not $1$). Idem -% for the potential ``first column''. +% \begin{center} +% \fvset{commandchars=\~\#\!} +% \begin{BVerbatim}[formatcom=\small\color{gray}] +% \begin{table} +% \setlength{\belowcaptionskip}{1ex} +% \centering +% \caption{Use of \texttt{\textbackslash tabularnote}~emphase#\tabularnote{It's possible! +% ~emphase#to put a note in the caption.}}! +% \label{t:tabularnote} +% \begin{NiceTabular}{@{}llc@{} +% [~emphase#notes/bottomrule!, tabularnote = Some text before the notes.] +% \toprule +% Last name & First name & Length of life \\ +% \midrule +% Churchill & Wiston & 91\\ +% Nightingale~emphase#\tabularnote{Considered as the first nurse of! +% ~emphase#history.}\tabularnote{Nicknamed ``the Lady with the Lamp''.}! +% & Florence & 90 \\ +% Schoelcher & Victor & 89~emphase#\tabularnote{The label of the note is overlapping.}!\\ +% Touchet & Marie & 89 \\ +% Wallis & John & 87 \\ +% \bottomrule +% \end{NiceTabular} +% \end{table} +% \end{BVerbatim} +% \end{center} % -% \begin{Verbatim} -% $\begin{pNiceMatrix}[~emphase#first-row,last-row,first-col,last-col@] -% $\begin{pNiceMatrix}[~emphase#first-row,last-row,first-col,last-col@,nullify-dots] -% & C_1 & \Cdots & & C_4 & \\ -% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\ -% \Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\ -% & a_{31} & a_{32} & a_{33} & a_{34} & \\ -% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\ -% & C_1 & \Cdots & & C_4 & -% \end{pNiceMatrix}$ -% \end{pNiceMatrix}$ -% \end{Verbatim} % -% \[\begin{pNiceMatrix}[first-row,last-row,first-col,last-col,nullify-dots] -% & C_1 & \Cdots & & C_4 & \\ -% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\ -% \Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\ -% & a_{31} & a_{32} & a_{33} & a_{34} & \\ -% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\ -% & C_1 & \Cdots & & C_4 & -% \end{pNiceMatrix}\] +% \begin{table} +% \setlength{\belowcaptionskip}{1ex} +% \centering +% \caption{Use of \texttt{\textbackslash tabularnote}\tabularnote{It's possible +% to put a note in the caption.}} +% \label{t:tabularnote} +% \begin{NiceTabular}{@{}llc@{}}[notes/bottomrule, +% tabularnote = Some text before the notes.] +% \toprule +% Last name & First name & Length of life \\ +% \midrule +% Churchill & Wiston & 91\\ +% Nightingale\tabularnote{Considered as the first nurse of +% history.}\tabularnote{Nicknamed ``the Lady with the Lamp''.} +% & Florence & 90 \\ +% Schoelcher & Victor & 89\tabularnote{The label of the note is overlapping.}\\ +% Touchet & Marie & 89 \\ +% Wallis & John & 87 \\ +% \bottomrule +% \end{NiceTabular} +% \end{table} % % -% \bigskip -% We have several remarks to do. -% \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: they will automatically (and -% necessarily) be of type |R| for the first column and |L| for the last one. -% \item One may wonder how \pkg{nicematrix} determines the number of rows and -% columns which are needed for the composition of the ``last row'' and ``last -% column''. -% \begin{itemize} -% \item For the environments with explicit preamble, like |{NiceArray}| and -% |{pNiceArray}|, the number of columns can obviously be computed from the -% preamble. +%\subsection{Customisation of the tabular notes} % -% \item When the option |light-syntax| (cf. p. \pageref{light-syntax}) is used, -% \pkg{nicematrix} has, in any case, to load the whole body of the environment -% (and that's why it's not possible to put verbatim material in the array with -% the option |light-syntax|). The analysis of this whole body gives the number -% of rows (but not the number of columns). % -% \item In the other cases, \pkg{nicematrix} compute the number of rows and -% columns during the first compilation and write the result in the |aux| file -% for the next run. -% -% \textsl{However, it's possible to provide the number of the last row and the number of -% the last column as values of the options |last-row| and |last-col|, tending to -% an acceleration of the whole compilation of the document.} That's what we will -% do throughout the rest of the document. -% \end{itemize} +% The tabular notes can be customized with a set of keys available in +% |\NiceMatrixOptions|. The name of these keys is prefixed by |notes|. +% \begin{itemize} +% \item |notes/para| +% \item |notes/bottomrule| +% \item |notes/style| +% \item |notes/label-in-tabular| +% \item |notes/label-in-list| +% \item |notes/enumitem-keys| +% \item |notes/enumitem-keys-para| +% \item |notes/code-before| % \end{itemize} -% +% For sake of commodity, it is also possible to set these keys in +% |\NiceMatrixOptions| via a key |notes| which takes in as value a list of +% pairs \textsl{key=value} where the name of the keys need no longer be +% prefixed by |notes|: +% \begin{center} +% \begin{BVerbatim}[formatcom = \small \color{gray}] +% \NiceMatrixOptions +% { +% notes = +% { +% bottomrule , +% style = ... , +% label-in-tabular = ... , +% enumitem-keys = +% { +% labelsep = ... , +% align = ... , +% ... +% } +% } +% } +% \end{BVerbatim} +% \end{center} +% +% % \bigskip -% It's possible to control the appearance of these rows and columns with options -% |code-for-first-row|, |code-for-last-row|, |code-for-first-col| and -% |code-for-last-col|. These options -% specify tokens that will be inserted before each cell of the corresponding row -% or column. -% +% We detail these keys. % -% \begin{Verbatim} -% \NiceMatrixOptions{~emphase#code-for-first-row@ = \color{red}, -% ~emphase#code-for-first-col@ = \color{blue}, -% ~emphase#code-for-last-row@ = \color{green}, -% ~emphase#code-for-last-col@ = \color{magenta}} -% $\begin{pNiceArray}{CC|CC}[first-row,last-row=5,first-col,last-col,nullify-dots] -% & C_1 & \Cdots & & C_4 & \\ -% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\ -% \Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\ -% \hline -% & a_{31} & a_{32} & a_{33} & a_{34} & \\ -% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\ -% & C_1 & \Cdots & & C_4 & -% \end{pNiceArray}$ -% \end{Verbatim} +% \begin{itemize}[itemsep=\medskipamount] +% \item The key |notes/para| requires the composition of the notes (at the end of +% the tabular) in a single paragraph. % -% \begin{scope} -% \NiceMatrixOptions{code-for-first-row = \color{red}, -% code-for-first-col = \color{blue}, -% code-for-last-row = \color{green}, -% code-for-last-col = \color{magenta}} -% \begin{displaymath} -% \begin{pNiceArray}{CC|CC}[first-row,last-row=5,first-col,last-col,nullify-dots] -% & C_1 & \multicolumn1C{\Cdots} & & C_4 & \\ -% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\ -% \Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\ -% \hline -% & a_{31} & a_{32} & a_{33} & a_{34} & \\ -% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\ -% & C_1 & \multicolumn1C{\Cdots} & & C_4 & -% \end{pNiceArray} -% \end{displaymath} -% \end{scope} +% Initial value: |false| % +% That key is also available within a given environment. % -% \emph{Remarks} -% \begin{itemize}[beginpenalty=10000] -% \item As shown in the previous example, an horizontal rule (drawn by |\hline|) -% doesn't extend in the exterior columns and a vertical rule (specified by a -% ``\verb+|+'' in the preamble of the array) doesn't extend in the exterior -% rows.\footnote{The latter is not true when the extension \pkg{arydshln} is -% loaded besides \pkg{nicematrix}. In fact, \pkg{nicematrix} and \pkg{arydhsln} -% are not totally compatible because \pkg{arydshln} redefines many internals of -% \pkg{array}. On another hand, if one really wants a vertical rule running in -% the first and in the last row, he should use |!{\vline}| instead of \verb+|+ -% in the preamble of the array.} -% -% If one wishes to define new specifiers for columns in order to draw vertical -% rules (for example thicker than the standard rules), he should consider the -% command |\OnlyMainNiceMatrix| described on page~\pageref{OnlyMainNiceMatrix}. +% \item The key |notes/bottomrule| adds a |\bottomrule| of \pkg{booktabs} +% \emph{after} the notes. Of course, that rule is drawn only if there is really +% notes in the tabular. The package \pkg{booktabs} must have been loaded (before +% or after the package \pkg{nicematrix}). If it is not, an error is raised. % -% \item A specification of color present in |code-for-first-row| also applies to -% a dotted line draw in this exterior ``first row'' (excepted if a value has -% been given to |xdots/color|). Idem for the other exterior rows and columns. +% Initial value: |false| % -% \item Logically, the potential option |columns-width| (described -% p.~\pageref{width}) doesn't apply to the ``first column'' and ``last column''. -% \item For technical reasons, it's not possible to use the option of the -% command |\\| after the ``first row'' or before the ``last row'' (the placement -% of the delimiters would be wrong). -% \end{itemize} -% -% -% +% That key is also available within a given environment. % +% \item The key |notes/style| is a command whose argument is specified by |#1| +% and which gives the style of numerotation of the notes. That style will be +% used by |\ref| when referencing a tabular note marked with a command |\label|. +% The labels formatted by that style are used, separated by commas, when the user +% puts several consecutive commands |\tabularnote|. The marker |#1| is meant to +% be the name of a LaTeX counter. % -% \section{The dotted lines to separate rows or columns} +% Initial value: |\textit{\alph{#1}}| % +% Another possible value should be a mere |\arabic{#1}| % -% In the environments of the extension \pkg{nicematrix}, it's possible to use -% the command |\hdottedline| (provided by \pkg{nicematrix}) which is a -% counterpart of the classical commands |\hline| and |\hdashline| (the latter is -% a command of \pkg{arydshln}). +% \item The key |notes/label-in-tabular| is a command whose argument is +% specified by |#1| which is used when formatting the label of a note in the +% tabular. Internally, this number of note has already been formatted by +% |notes/style| before sent to that command. % -% \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=9.5cm] -% \begin{pNiceMatrix} -% 1 & 2 & 3 & 4 & 5 \\ -% ~emphase#\hdottedline@ -% 6 & 7 & 8 & 9 & 10 \\ -% 11 & 12 & 13 & 14 & 15 -% \end{pNiceMatrix} -% \end{BVerbatim} -% $\begin{pNiceMatrix} -% 1 & 2 & 3 & 4 & 5 \\ -% \hdottedline -% 6 & 7 & 8 & 9 & 10 \\ -% 11 & 12 & 13 & 14 & 15 -% \end{pNiceMatrix}$ +% Initial value: |\textsuperscript{#1}| % +% In French, it's a tradition of putting a small space before the label of note. +% That tuning could be acheived by the following code: +% % +% \begin{Verbatim} +% \NiceMatrixOptions{notes/label-in-tabular = \,\textsuperscript{~#1}} +% \end{Verbatim} % -% \bigskip -% In the environments with an explicit preamble (like |{NiceArray}|, etc.), it's -% possible to draw a vertical dotted line with the specifier ``|:|''. -% -% \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=9.5cm] -% \left(\begin{NiceArray}{CCCC~emphase#:@C} -% 1 & 2 & 3 & 4 & 5 \\ -% 6 & 7 & 8 & 9 & 10 \\ -% 11 & 12 & 13 & 14 & 15 -% \end{NiceArray}\right) -% \end{BVerbatim} -% $\left(\begin{NiceArray}{CCCC:C} -% 1 & 2 & 3 & 4 & 5 \\ -% 6 & 7 & 8 & 9 & 10 \\ -% 11 & 12 & 13 & 14 & 15 -% \end{NiceArray}\right)$ % +% \item The key |notes/label-in-list| is a command whose argument is specified +% by |#1| which is used when formatting the label in the list of notes at the +% end of the tabular. Internally, this number of note has already been formatted by +% |notes/style| before sent to that command. % -% \bigskip -% These dotted lines do \emph{not} extend in the potential exterior rows and -% columns. +% Initial value: |\textsuperscript{#1}| % -% -% \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=9.5cm] -% $\begin{pNiceArray}{CCC:C}[ -% first-row,last-col, -% code-for-first-row = \color{blue}\scriptstyle, -% code-for-last-col = \color{blue}\scriptstyle ] -% C_1 & C_2 & C_3 & C_4 \\ -% 1 & 2 & 3 & 4 & L_1 \\ -% 5 & 6 & 7 & 8 & L_2 \\ -% 9 & 10 & 11 & 12 & L_3 \\ -% \hdottedline -% 13 & 14 & 15 & 16 & L_4 -% \end{pNiceArray}$ -% \end{BVerbatim} -% $\begin{pNiceArray}{CCC:C}[ -% first-row,last-col, -% code-for-first-row = \color{blue}\scriptstyle, -% code-for-last-col = \color{blue}\scriptstyle ] -% C_1 & C_2 & C_3 & C_4 \\ -% 1 & 2 & 3 & 4 & L_1 \\ -% 5 & 6 & 7 & 8 & L_2 \\ -% 9 & 10 & 11 & 12 & L_3 \\ -% \hdottedline -% 13 & 14 & 15 & 16 & L_4 -% \end{pNiceArray}$ -% -% \bigskip -% 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 -% dashed line. Thus, by using |letter-for-dotted-lines|, we can use the -% vertical lines of both \pkg{arydshln} and \pkg{nicematrix}. -% -% \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=9.5cm] -% \NiceMatrixOptions{letter-for-dotted-lines = I} -% \arrayrulecolor{blue} -% \left(\begin{NiceArray}{~emphase#C|C:CIC@} -% 1 & 2 & 3 & 4 \\ -% 5 & 6 & 7 & 8 \\ -% 9 & 10 & 11 & 12 -% \end{NiceArray}\right) -% \arrayrulecolor{black} -% \end{BVerbatim} -% \begin{scope} -% \NiceMatrixOptions{letter-for-dotted-lines = I} -% \arrayrulecolor{blue} -% $\left(\begin{NiceArray}{C|C:CIC} -% 1 & 2 & 3 & 4 \\ -% 5 & 6 & 7 & 8 \\ -% 9 & 10 & 11 & 12 -% \end{NiceArray}\right)$ -% \arrayrulecolor{black} -% \end{scope} -% -% \smallskip -% We have used the command |\arrayrulecolor| (de \pkg{colortbl}) to draw in blue -% the three rules. +% In French, the labels of notes are not composed in upper position when +% composing the notes. Such behaviour could be acheived by: +% \begin{Verbatim} +% \NiceMatrixOptions{notes/label-in-list = ~#1.\nobreak\hspace{0.25em}} +% \end{Verbatim} +% The command |\nobreak| is for the event that the option |para| is used. % -% \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 by |\hdottedline| and ``|:|'' do -% likewise. % -% -% -% \section{The width of the columns} -% \label{width} +% \item The notes are composed at the end of the tabular by using internally a +% style of list of \pkg{enumitem}. % -% In the environments with an explicit preamble (like |{NiceArray}|, -% |{pNiceArray}|, etc.), it's possible to fix the width of a given column with -% the standard letters |w| and |W| of the package \pkg{array}. In the -% environments of \pkg{nicematrix}, the cells of such columns are composed in -% mathematical mode, whereas, in |{array}| of \pkg{array}, they are composed in -% text mode. -% -% \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=10cm] -% $\left(\begin{NiceArray}{~emphase#wc{1cm}@CC} -% 1 & 12 & -123 \\ -% 12 & 0 & 0 \\ -% 4 & 1 & 2 -% \end{NiceArray}\right)$ -% \end{BVerbatim} -% $\left(\begin{NiceArray}{wc{1cm}CC} -% 1 & 12 & -123 \\ -% 12 & 0 & 0 \\ -% 4 & 1 & 2 -% \end{NiceArray}\right)$ +% The key |notes/enumitem-keys| specifies a list of pairs +% \textsl{key=value} (following the specifications of \pkg{enumitem}) to +% customize that type of list. % +% Initial value:\quad |noitemsep , leftmargin = * , align = left , labelsep = 0pt| % -% \bigskip -% In the environments of \pkg{nicematrix}, it's also possible to fix the \emph{minimal} -% width of all the columns of a matrix directly with the option |columns-width|. -% -% \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=10cm] -% $\begin{pNiceMatrix}[~emphase#columns-width = 1cm@] -% 1 & 12 & -123 \\ -% 12 & 0 & 0 \\ -% 4 & 1 & 2 -% \end{pNiceMatrix}$ -% \end{BVerbatim} -% $\begin{pNiceMatrix}[columns-width = 1cm] -% 1 & 12 & -123 \\ -% 12 & 0 & 0 \\ -% 4 & 1 & 2 -% \end{pNiceMatrix}$ +% This initial value contains the specification |align = left| which requires a +% composition of the label leftwards in the box affected to that label. +% With that tuning, the notes are composed flush left, which is pleasant when +% composing tabulars in the spirit of \pkg{booktabs} (see for example the +% table \ref{t:tabularnote}, p.~\pageref{t:tabularnote}). % -% \medskip -% Note that the space inserted between two columns (equal to 2 |\arraycolsep|) -% is not suppressed (of course, it's possible to suppress this space by setting -% |\arraycolsep| equal to $0$~pt). % -% \bigskip -% It's possible to give the special value |auto| to the option |columns-width|: -% all the columns of the array will have a width equal to the widest cell of -% the array.\footnote{The result is achieved with only one compilation (but Tikz -% will have written informations in the |.aux| file and a message requiring a -% second compilation will appear).}\par\nobreak +% \item The key |notes/enumitem-keys-para| is similar to the previous one but +% corresponds to the type of list used when the option |para| is in force. Of +% course, when the option |para| is used, a list of type |inline| (as called by +% \pkg{enumitem}) is used and the pairs \textsl{key=value} should correspond to +% such a list of type |inline|. +% +% Initial value:\quad |afterlabel = \nobreak, itemjoin = \quad| +% +% +% \item The key |notes/code-before| est une token list inserted by \pkg{nicematrix} +% just before the composition of the notes at the end of the tabular. +% +% Initial value: \textsl{empty} +% +% For example, if one wishes to compose all the notes in gray and |\footnotesize|, +% he should use that key: +% \begin{Verbatim} +% \NiceMatrixOptions{notes/code-before = \footnotesize \color{gray}} +% \end{Verbatim} +% It's also possible to add |\raggedright| or |\RaggedRight| in that key (|\RaggedRight| +% is a command of \pkg{ragged2e}). +% \end{itemize} +% % -% \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=10cm] -% $\begin{pNiceMatrix}[~emphase#columns-width = auto@] -% 1 & 12 & -123 \\ -% 12 & 0 & 0 \\ -% 4 & 1 & 2 -% \end{pNiceMatrix}$ -% \end{BVerbatim} -% $\begin{pNiceMatrix}[columns-width = auto] -% 1 & 12 & -123 \\ -% 12 & 0 & 0 \\ -% 4 & 1 & 2 -% \end{pNiceMatrix}$ -% -% \bigskip -% Without surprise, it's possible to fix the minimal width of the columns of all -% the matrices of a current scope with the command -% |\NiceMatrixOptions|.\par\nobreak % -% \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=8.5cm] -% ~emphase#\NiceMatrixOptions{columns-width=10mm}@ -% $\begin{pNiceMatrix} -% a & b \\ c & d \\ -% \end{pNiceMatrix} -% = -% \begin{pNiceMatrix} -% 1 & 1245 \\ 345 & 2 \\ -% \end{pNiceMatrix}$ -% \end{BVerbatim} -% \begin{scope} -% \NiceMatrixOptions{columns-width=10mm} -% $\begin{pNiceMatrix} -% a & b \\ -% c & d \\ -% \end{pNiceMatrix} -% = -% \begin{pNiceMatrix} -% 1 & 1245 \\ -% 345 & 2 \\ -% \end{pNiceMatrix}$ -% \end{scope} -% -% % \bigskip -% But it's also possible to fix a zone where all the matrices will have their -% columns of the same width, equal to the widest cell of all the matrices. This -% construction uses the environment |{NiceMatrixBlock}| with the option -% |auto-columns-width|\footnote{At this time, this is the only usage of the -% environment |{NiceMatrixBlock}| but it may have other usages in the future.}. -% 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]@ -% $\begin{pNiceMatrix} -% a & b \\ c & d \\ -% \end{pNiceMatrix} -% = -% \begin{pNiceMatrix} -% 1 & 1245 \\ 345 & 2 \\ -% \end{pNiceMatrix}$ -% ~emphase#\end{NiceMatrixBlock}@ -% \end{BVerbatim} -% \begin{NiceMatrixBlock}[auto-columns-width] -% $\begin{pNiceMatrix} -% a & b \\ c & d \\ -% \end{pNiceMatrix} -% = -% \begin{pNiceMatrix} -% 1 & 1245 \\ 345 & 2 \\ -% \end{pNiceMatrix}$ -% \end{NiceMatrixBlock} +% For an example of customization of the tabular notes, see p.~\pageref{ex:notes}. % -% \medskip -% \textbf{Several compilations may be necessary to achieve the job.} % +% \subsection{Use of \{NiceTabular\} with threeparttable} % -% \section{Block matrices} -% \label{Block} % -% This section has no direct link with the previous one where an environment -% |{NiceMatrixBlock}| was introduced. -% -% In the environments of \pkg{nicematrix}, it's possible to use the command -% |\Block| in order to place an element in the center of a rectangle of merged -% cells of the array. +% If you wish to use the environment |{NiceTabular}| or |{NiceTabular*}| in an +% environment |{threeparttable}| of the eponymous package, you have to patch the +% environment |{threeparttable}| with the following code (with a version of +% LaTeX at least 2020/10/01). +% \begin{Verbatim}[commandchars=\~\#\!] +% \makeatletter +% \AddToHook{env/threeparttable/begin} +% {\TPT@hookin{NiceTabular}\TPT@hookin{NiceTabular*}} +% \makeatother +% \end{Verbatim} % -% The command |\Block| must be used in the upper leftmost cell of the array with -% two arguments. The first argument is the size of the block with the syntax -% $i$\verb|-|$j$ where $i$ is the number of rows of the block and $j$ its number -% of columns. The second argument is the content of the block (composed in math -% mode). A Tikz node corresponding to the merged cells is created with the name -% ``$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] -% \arrayrulecolor{cyan} -% $\begin{bNiceArray}{CCC|C}[margin] -% ~emphase#\Block{3-3}{A}@ & & & 0 \\ -% & \hspace*{1cm} & & \Vdots \\ -% & & & 0 \\ -% \hline -% 0 & \Cdots& 0 & 0 -% \end{bNiceArray}$ -% \arrayrulecolor{black} -% \end{BVerbatim} -% \begin{scope} -% \arrayrulecolor{cyan} -% $\begin{bNiceArray}{CCC|C}[margin] -% \Block{3-3}{A} & & & 0 \\ -% & \hspace*{1cm} & & \Vdots \\ -% & & & 0 \\ -% \hline -% 0 & \Cdots& 0 & 0 -% \end{bNiceArray}$ -% \arrayrulecolor{black} -% \end{scope} +% \section{Other features} % -% \bigskip -% One may wish to raise the size of the ``$A$'' placed in the block of the -% previous example. Since this element is composed in math mode, it's not -% possible to use directly a command like |\large|, |\Large| and |\LARGE|. -% That's why the command |\Block| provides an option between angle brackets to -% specify some TeX code which will be inserted before the beginning of the -% math mode. +% \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 +% of \pkg{nicematrix}. The implementation doesn't use explicitly any private +% macro of \pkg{siunitx}. +% +% % \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=10.6cm] -% \arrayrulecolor{cyan} -% $\begin{bNiceArray}{CCC|C}[margin] -% \Block{3-3}~emphase#<\Large>@{A} & & & 0 \\ -% & \hspace*{1cm} & & \Vdots \\ -% & & & 0 \\ -% \hline -% 0 & \Cdots& 0 & 0 -% \end{bNiceArray}$ -% \arrayrulecolor{black} +% \begin{BVerbatim}[baseline = c, boxwidth = 10.5cm] +% $\begin{pNiceArray}{~emphase#S@cWc{1cm}c}[nullify-dots,first-row] +% {C_1} & \Cdots & & C_n \\ +% 2.3 & 0 & \Cdots & 0 \\ +% 12.4 & \Vdots & & \Vdots \\ +% 1.45 \\ +% 7.2 & 0 & \Cdots & 0 +% \end{pNiceArray}$ % \end{BVerbatim} -% \begin{scope} -% \arrayrulecolor{cyan} -% $\begin{bNiceArray}{CCC|C}[margin] -% \Block{3-3}<\Large>{A} & & & 0 \\ -% & \hspace*{1cm} & & \Vdots \\ -% & & & 0 \\ -% \hline -% 0 & \Cdots& 0 & 0 -% \end{bNiceArray}$ -% \arrayrulecolor{black} -% \end{scope} -% -% \medskip -% For technical reasons, you can't write |\Block{|$i$|-|$j$|}{<}|. But you can -% write |\Block{|$i$|-|$j$|}<>{<}| with the expected result. -% +% $\begin{pNiceArray}{ScWc{1cm}c}[nullify-dots,first-row] +% {C_1} & \Cdots & & C_n \\ +% 2.3 & 0 & \Cdots & 0 \\ +% 12.4 & \Vdots & & \Vdots \\ +% 1.45 \\ +% 7.2 & 0 & \Cdots & 0 +% \end{pNiceArray}$ % -% \section{Advanced features} +% \medskip +% On the other hand, the |d| columns of the package \pkg{dcolumn} are not +% supported by \pkg{nicematrix}. +% % +% \subsection{Alignment option in \{NiceMatrix\}} % -% \subsection{Alignement option in NiceMatrix} +% \label{key-R} % % The environments without preamble (|{NiceMatrix}|, |{pNiceMatrix}|, -% |{bNiceMatrix}|, etc.) provide two options |l| and |r| (equivalent at |L| and -% |R|) which generate all the columns aligned leftwards (or -% rightwards).\footnote{This is a part of the functionality provided by the -% environments |{pmatrix*}|, |{bmatrix*}|, etc. of \pkg{mathtools}.} +% |{bNiceMatrix}|, etc.) provide two options |l| and |r| which generate all the +% columns aligned leftwards (or rightwards). % % % \medskip % \begin{BVerbatim}[baseline=c,boxwidth=10cm] -% $\begin{bNiceMatrix}[R] +% $\begin{bNiceMatrix}[r] % \cos x & - \sin x \\ % \sin x & \cos x % \end{bNiceMatrix}$ % \end{BVerbatim} -% $\begin{bNiceMatrix}[R] +% $\begin{bNiceMatrix}[r] % \cos x & - \sin x \\ % \sin x & \cos x % \end{bNiceMatrix}$ @@ -1598,7 +2854,7 @@ version 2005/12/01 or later. % e_1 & e_2 & e_3 \\ % 1 & 2 & 3 & e_1 \\ % 4 & 5 & 6 & e_2 \\ -% 7 & 8 & 9 & e_3 \\ +% 7 & 8 & 9 & e_3 % \end{pNiceMatrix}$ % \end{BVerbatim} % \begin{varwidth}{10cm} @@ -1609,7 +2865,7 @@ version 2005/12/01 or later. % e_1 & e_2 & e_3 \\ % 1 & 2 & 3 & e_1 \\ % 4 & 5 & 6 & e_2 \\ -% 7 & 8 & 9 & e_3 \\ +% 7 & 8 & 9 & e_3 % \end{pNiceMatrix}$ % \end{varwidth} % @@ -1626,7 +2882,7 @@ version 2005/12/01 or later. % 1 & 2 & 3 & e_1 \\ % 4 & 5 & 6 & e_2 \\ % 7 & 8 & 9 & e_3 \\ -% \text{image of } e_1 & e_2 & e_3 \\ +% \text{image of } e_1 & e_2 & e_3 % \end{pNiceMatrix}$ % \end{BVerbatim} % \begin{varwidth}{10cm} @@ -1637,7 +2893,7 @@ version 2005/12/01 or later. % 1 & 2 & 3 & e_1 \\ % 4 & 5 & 6 & e_2 \\ % 7 & 8 & 9 & e_3 \\ -% \text{image of } e_1 & e_2 & e_3 \\ +% \text{image of } e_1 & e_2 & e_3 % \end{pNiceMatrix}$ % \end{varwidth} % @@ -1647,29 +2903,29 @@ version 2005/12/01 or later. % % \label{small} % -% With the option |small|, the environments of the extension \pkg{nicematrix} +% With the option |small|, the environments of the package \pkg{nicematrix} % are composed in a way similar to the environment |{smallmatrix}| of the -% extension \pkg{amsmath} (and the environments |{psmallmatrix}|, -% |{bsmallmatrix}|, etc. of the extension \pkg{mathtools}). +% package \pkg{amsmath} (and the environments |{psmallmatrix}|, +% |{bsmallmatrix}|, etc. of the package \pkg{mathtools}). % % \bigskip % \begin{Verbatim} -% $\begin{bNiceArray}{CCCC|C}[~emphase#small@, +% $\begin{bNiceArray}{cccc|c}[~emphase#small@, % last-col, % code-for-last-col = \scriptscriptstyle, % columns-width = 3mm ] % 1 & -2 & 3 & 4 & 5 \\ % 0 & 3 & 2 & 1 & 2 & L_2 \gets 2 L_1 - L_2 \\ -% 0 & 1 & 1 & 2 & 3 & L_3 \gets L_1 + L_3 \\ +% 0 & 1 & 1 & 2 & 3 & L_3 \gets L_1 + L_3 % \end{bNiceArray}$ % \end{Verbatim} % % -% \[\begin{bNiceArray}{CCCC|C}[small, last-col, +% \[\begin{bNiceArray}{cccc|c}[small, last-col, % code-for-last-col = \scriptscriptstyle, % columns-width=3mm] % 1 & -2 & 3 & 4 & 5 \\ % 0 & 3 & 2 & 1 & 2 & L_2 \gets 2 L_1 - L_2 \\ -% 0 & 1 & 1 & 2 & 3 & L_3 \gets L_1 + L_3 \\ +% 0 & 1 & 1 & 2 & 3 & L_3 \gets L_1 + L_3 % \end{bNiceArray}\] % % @@ -1678,7 +2934,7 @@ version 2005/12/01 or later. % One should note that the environment |{NiceMatrix}| with the option |small| is % not composed \emph{exactly} as the environment |{smallmatrix}|. Indeed, all % the environments of \pkg{nicematrix} are constructed upon |{array}| (of the -% extension \pkg{array}) whereas the environment |{smallmatrix}| is constructed +% package \pkg{array}) whereas the environment |{smallmatrix}| is constructed % directly with an |\halign| of TeX. % % \medskip @@ -1699,9 +2955,10 @@ version 2005/12/01 or later. % exists) has also the number~$0$.}. Of course, the user must not change the % value of these counters which are used internally by \pkg{nicematrix}. % -% In the |code-after| (cf. p. \pageref{code-after}), |iRow| represents the total -% number of rows (excepted the potential exterior rows) and |jCol| represents -% the total number of columns (excepted the potential exterior columns). +% In the |code-before| (cf. p. \pageref{code-before}) and in the |\CodeAfter| +% (cf. p. \pageref{code-after}), |iRow| represents the total number of rows +% (excepted the potential exterior rows) and |jCol| represents the total number +% of columns (excepted the potential exterior columns). % % \medskip % \begin{BVerbatim}[baseline=c,boxwidth=10.6cm] @@ -1728,20 +2985,20 @@ version 2005/12/01 or later. % % \medskip % If LaTeX counters called |iRow| and |jCol| are defined in the document by -% extensions other than \pkg{nicematrix} (or by the user), they are shadowed in -% the environments of \pkg{nicematrix}. +% packages other than \pkg{nicematrix} (or by the final user), they are shadowed +% in the environments of \pkg{nicematrix}. % % \bigskip -% The extension \pkg{nicematrix} also provides commands in order to compose +% The package \pkg{nicematrix} also provides commands in order to compose % automatically matrices from a general pattern. These commands are -% |\pAutoNiceMatrix|, |\bAutoNiceMatrix|, |\vAutoNiceMatrix|, +% |\AutoNiceMatrix|, |\pAutoNiceMatrix|, |\bAutoNiceMatrix|, |\vAutoNiceMatrix|, % |\VAutoNiceMatrix| and |\BAutoNiceMatrix|. % -% These commands take two mandatory arguments. The first is the format of the +% These commands take in two mandatory arguments. The first is the format of the % matrix, with the syntax $n$-$p$ where $n$ is the number of rows and $p$ the % number of columns. The second argument is the pattern (it's a list of tokens % which are inserted in each cell of the constructed matrix, excepted in the -% cells of the eventual exterior rows and columns). +% cells of the potential exterior rows and columns). % % \medskip % \begin{Verbatim} @@ -1749,107 +3006,21 @@ version 2005/12/01 or later. % \end{Verbatim} % % -% $C = \pAutoNiceMatrix{3-3}{C_{\arabic{iRow},\arabic{jCol}}}$ -% -% \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| 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=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} -% $\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} +% \[C = \pAutoNiceMatrix{3-3}{C_{\arabic{iRow},\arabic{jCol}}}\] % % % \subsection{The option light-syntax} % % \label{light-syntax} -% The option |light-syntax|\footnote{This option is inspired by the extension -% \pkg{spalign} of Joseph Rabinoff.} allows the user to compose the arrays with a -% lighter syntax, which gives a more readable TeX source. +% The option |light-syntax| (inpired by the package \pkg{spalign}) allows the +% user to compose the arrays with a lighter syntax, which gives a better +% legibility of the TeX source. % % When this option is used, one should use the semicolon for the end of a row % and spaces or tabulations to separate the columns. However, as usual in the % TeX world, the spaces after a control sequence are discarded and the elements % between curly braces are considered as a whole. % -% \bigskip -% The following example has been composed with XeLaTeX with \pkg{unicode-math}, -% which allows the use of greek letters directly in the TeX source. % % \medskip % \begin{scope} @@ -1879,36 +3050,588 @@ version 2005/12/01 or later. % analyzed. The environment doesn't behave in that case as a standard % environment of LaTeX which only put TeX commands before and after the content.} % -% \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 -% of \pkg{nicematrix}. The implementation doesn't use explicitly any private -% macro of \pkg{siunitx}. +% \subsection{Color of the delimiters} +% +% For the environements with delimiters (|{pNiceArray}|, |{pNiceMatrix}|, etc.), +% it's possible to change the color of the delimiters with the key +% |delimiters-color|. +% +% \medskip +% \begin{BVerbatim}[boxwidth=12cm,baseline=c] +% $\begin{bNiceMatrix}[delimiters-color=red] +% 1 & 2 \\ +% 3 & 4 +% \end{bNiceMatrix}$ +% \end{BVerbatim} +% $\begin{bNiceMatrix}[delimiters-color=red] +% 1 & 2 \\ +% 3 & 4 +% \end{bNiceMatrix}$ +% +% +% \subsection{The environment \{NiceArrayWithDelims\}} +% +% In fact, the environment |{pNiceArray}| and its variants are based upon a +% 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 or asymetrical delimiters. +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=11cm] +% $\begin{~emphase#NiceArrayWithDelims@} +% {\downarrow}{\uparrow}{ccc}[margin] +% 1 & 2 & 3 \\ +% 4 & 5 & 6 \\ +% 7 & 8 & 9 +% \end{~emphase#NiceArrayWithDelims@}$ +% \end{BVerbatim} +% $\begin{NiceArrayWithDelims} +% {\downarrow}{\uparrow}{ccc}[margin] +% 1 & 2 & 3 \\ +% 4 & 5 & 6 \\ +% 7 & 8 & 9 +% \end{NiceArrayWithDelims}$ +% +% % +% \section{Use of Tikz with nicematrix} % +% \label{name} +% \subsection{The nodes corresponding to the contents of the cells} +% +% The package \pkg{nicematrix} creates a PGF/Tikz node for each (non-empty) cell +% of the considered array. These nodes are used to draw the dotted lines between +% the cells of the matrix (inter alia). +% +% +% \smallskip +% \textbf{Caution} : By default, no node is created in a empty cell. +% +% \smallskip +% However, it's possible to impose the creation of a node with the command |\NotEmpty|. +% \footnote{One should note that, with that command, the cell is considered as +% non-empty, which has consequencies for the continuous dotted lines (cf. +% p.~\pageref{Cdots}).} +% % \medskip -% \begin{BVerbatim}[baseline = c, boxwidth = 10.5cm] -% $\begin{pNiceArray}{~emphase#S@CWc{1cm}C}[nullify-dots,first-row] -% {C_1} & \Cdots & & C_n \\ -% 2.3 & 0 & \Cdots & 0 \\ -% 12.4 & \Vdots & & \Vdots \\ -% 1.45 \\ -% 7.2 & 0 & \Cdots & 0 -% \end{pNiceArray}$ +% The nodes of a document must have distinct names. That's why the names of the +% nodes created by \pkg{nicematrix} contains the number of the current +% environment. Indeed, the environments of \pkg{nicematrix} are numbered by a +% internal global counter. +% +% \smallskip +% In the environment with the number $n$, the node of the row $i$ and +% column~$j$ has for name |nm-|$n$|-|$i$|-|$j$. +% +% \smallskip +% The command |\NiceMatrixLastEnv| provides the number of the last environment +% of \pkg{nicematrix} (for LaTeX, it's a ``fully expandable'' command and not a +% counter). +% +% \smallskip +% However, it's advisable to use instead the key |name|. This key gives a name +% to the current environment. When the environment has a name, the nodes are +% accessible with the name ``\textsl{name}-$i$-$j$'' where \textsl{name} is the +% name given to the array and $i$ and $j$ the numbers of row and column. It's +% possible to use these nodes with \textsc{pgf} but the final user will +% probably prefer to use Tikz (which is a convenient layer upon \textsc{pgf}). +% However, one should remind that \pkg{nicematrix} doesn't load Tikz by default. +% In the following examples, we assume that Tikz has been loaded. +% +% \bigskip +% \begin{BVerbatim}[baseline=c,boxwidth=11cm] +% $\begin{pNiceMatrix}[name=~emphase#mymatrix@] +% 1 & 2 & 3 \\ +% 4 & 5 & 6 \\ +% 7 & 8 & 9 +% \end{pNiceMatrix}$ +% \tikz[remember picture,overlay] +% \draw ~emphase#(mymatrix-2-2)@ circle (2mm) ; % \end{BVerbatim} -% $\begin{pNiceArray}{SCWc{1cm}C}[nullify-dots,first-row] -% {C_1} & \Cdots & & C_n \\ -% 2.3 & 0 & \Cdots & 0 \\ -% 12.4 & \Vdots & & \Vdots \\ -% 1.45 \\ -% 7.2 & 0 & \Cdots & 0 -% \end{pNiceArray}$ +% $\begin{pNiceMatrix}[name=mymatrix] +% 1 & 2 & 3 \\ +% 4 & 5 & 6 \\ +% 7 & 8 & 9 +% \end{pNiceMatrix}$ +% \tikz[remember picture,overlay] +% \draw (mymatrix-2-2) circle (2mm) ; +% +% \medskip +% Don't forget the options |remember picture| and |overlay|. +% +% \bigskip +% In the |\CodeAfter|, the things are easier : one must refer to the nodes with +% the form $i$-$j$ (we don't have to indicate the environment which is of +% course the current environment). +% +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=11cm] +% $\begin{pNiceMatrix} +% 1 & 2 & 3 \\ +% 4 & 5 & 6 \\ +% 7 & 8 & 9 +% \CodeAfter +% \tikz \draw ~emphase#(2-2)@ circle (2mm) ; +% \end{pNiceMatrix}$ +% \end{BVerbatim} +% $\begin{pNiceMatrix} +% 1 & 2 & 3 \\ +% 4 & 5 & 6 \\ +% 7 & 8 & 9 +% \CodeAfter +% \tikz \draw (2-2) circle (2mm) ; +% \end{pNiceMatrix}$ +% +% +% \bigskip +% In the following example, we have underlined all the nodes of the matrix (we +% explain below the technic used : cf. p. \pageref{highlight}). +% +% \[\begin{pNiceMatrix}[ +% code-after = {\begin{tikzpicture} +% [every node/.style = {blend mode = multiply, +% fill = red!15, +% inner sep = 0 pt }] +% \node [fit = (1-1)] {} ; +% \node [fit = (1-3)] {} ; +% \node [fit = (2-2)] {} ; +% \node [fit = (3-1)] {} ; +% \node [fit = (3-3)] {} ; +% \node [fit = (1-2)] {} ; +% \node [fit = (2-1)] {} ; +% \node [fit = (2-3)] {} ; +% \node [fit = (3-2)] {} ; +% \end{tikzpicture}}] +% a & a + b & a + b + c \\ +% a & a & a + b \\ +% a & a & a +% \end{pNiceMatrix}\] +% +% % +% \subsection{The ``medium nodes'' and the ``large nodes''} +% +% In fact, the package \pkg{nicematrix} can create ``extra nodes'': the ``medium +% nodes'' and the ``large nodes''. The first ones +% are created with the option |create-medium-nodes| and the second ones with the +% option |create-large-nodes|.\footnote{There is also an option +% |create-extra-nodes| which is an alias for the conjonction of +% |create-medium-nodes| and |create-large-nodes|.} +% % \medskip -% On the other hand, the |d| columns of the package \pkg{dcolumn} are not -% supported by \pkg{nicematrix}. +% These nodes are not used by \pkg{nicematrix} by default, and that's why they +% are not created by default. % +% \medskip +% The names of the ``medium nodes'' are constructed by adding the suffix +% ``|-medium|'' to the names of the ``normal nodes''. In the following example, +% we have underlined the ``medium nodes''. We consider that this example is +% self-explanatory. +% \[\begin{pNiceMatrix}[ +% create-medium-nodes, +% code-after = {\begin{tikzpicture} +% [every node/.style = {fill = red!15, +% blend mode = multiply, +% inner sep = 0pt}, +% name suffix = -medium] +% \node [fit = (1-1)] {} ; +% \node [fit = (1-2)] {} ; +% \node [fit = (1-3)] {} ; +% \node [fit = (2-1)] {} ; +% \node [fit = (2-2)] {} ; +% \node [fit = (2-3)] {} ; +% \node [fit = (3-1)] {} ; +% \node [fit = (3-2)] {} ; +% \node [fit = (3-3)] {} ; +% \end{tikzpicture}}] +% a & a + b & a + b + c \\ +% a & a & a + b \\ +% a & a & a +% \end{pNiceMatrix}\] +% +% +% \medskip +% The names of the ``large nodes'' are constructed by adding the suffix +% ``|-large|'' to the names of the ``normal nodes''. In the following example, +% we have underlined the ``large nodes''. We consider that this example is +% self-explanatory.\footnote{There is no ``large nodes'' created in the exterior +% rows and columns (for these rows and columns, cf. p.~\pageref{exterior}).} +% +% \[\begin{pNiceMatrix}[ +% create-large-nodes, +% code-after = {\begin{tikzpicture} +% [every node/.style = {blend mode = multiply, +% inner sep = 0pt}, +% name suffix = -large] +% \node [fit = (1-1),fill = red!15] {} ; +% \node [fit = (1-3),fill = red!15] {} ; +% \node [fit = (2-2),fill = red!15] {} ; +% \node [fit = (3-1),fill = red!15] {} ; +% \node [fit = (3-3),fill = red!15] {} ; +% \node [fit = (1-2),fill = blue!15] {} ; +% \node [fit = (2-1),fill = blue!15] {} ; +% \node [fit = (2-3),fill = blue!15] {} ; +% \node [fit = (3-2),fill = blue!15] {} ; +% \end{tikzpicture}}] +% a & a + b & a + b + c \\ +% a & a & a + b \\ +% a & a & a +% \end{pNiceMatrix}\] +% +% +% \medskip +% The ``large nodes'' of the first column and last column may appear too small +% for some usage. That's why it's possible to use the options |left-margin| and +% |right-margin| to add space on both sides of the array and also space in the +% ``large nodes'' of the first column and last column. In the following example, +% we have used the options |left-margin| and |right-margin|.\footnote{The +% options |left-margin| and |right-margin| take dimensions as values but, if no +% value is given, the default value is used, which is |\arraycolsep| (by +% default: 5~pt). There is also an option |margin| to fix both |left-margin| and +% |right-margin| to the same value.} +% \[\begin{pNiceMatrix}[ +% create-large-nodes,left-margin,right-margin, +% code-after = {\begin{tikzpicture} +% [every node/.style = {blend mode = multiply, +% inner sep = 0pt}, +% name suffix = -large] +% \node [fit = (1-1),fill = red!15] {} ; +% \node [fit = (1-3),fill = red!15] {} ; +% \node [fit = (2-2),fill = red!15] {} ; +% \node [fit = (3-1),fill = red!15] {} ; +% \node [fit = (3-3),fill = red!15] {} ; +% \node [fit = (1-2),fill = blue!15] {} ; +% \node [fit = (2-1),fill = blue!15] {} ; +% \node [fit = (2-3),fill = blue!15] {} ; +% \node [fit = (3-2),fill = blue!15] {} ; +% \end{tikzpicture}}] +% a & a + b & a + b + c \\ +% a & a & a + b \\ +% a & a & a +% \end{pNiceMatrix}\] +% +% \medskip +% It's also possible to add more space on both side of the array with the +% options |extra-left-margin| and |extra-right-margin|. These margins are not +% incorporated in the ``large nodes''. It's possible to fix both values with the +% option |extra-margin| and, in the following example, we use |extra-margin| +% with the value $3$~pt. +% \[\begin{pNiceMatrix}[ +% create-large-nodes,margin,extra-margin=3pt, +% code-after = {\begin{tikzpicture} +% [every node/.style = {blend mode = multiply, +% inner sep = 0 pt}, +% name suffix = -large] +% \node [fit = (1-1),fill = red!15] {} ; +% \node [fit = (1-3),fill = red!15] {} ; +% \node [fit = (2-2),fill = red!15] {} ; +% \node [fit = (3-1),fill = red!15] {} ; +% \node [fit = (3-3),fill = red!15] {} ; +% \node [fit = (1-2),fill = blue!15] {} ; +% \node [fit = (2-1),fill = blue!15] {} ; +% \node [fit = (2-3),fill = blue!15] {} ; +% \node [fit = (3-2),fill = blue!15] {} ; +% \end{tikzpicture}}] +% a & a + b & a + b + c \\ +% a & a & a + b \\ +% a & a & a +% \end{pNiceMatrix}\] +% +% +% +% \bigskip +% \textbf{Be careful} : These nodes are reconstructed from the contents of the +% contents cells of the array. Usually, they do not correspond to the cells +% delimited by the rules (if we consider that these rules are drawn). +% +% \bigskip +% \begin{minipage}[c]{7.6cm} +% Here is an array composed with the following code: +% +% \medskip +% \begin{BVerbatim} +% \large +% \begin{NiceTabular}{wl{2cm}ll}[hvlines] +% fraise & amande & abricot \\ +% prune & pêche & poire \\[1ex] +% noix & noisette & brugnon +% \end{NiceTabular} +% \end{BVerbatim} +% \end{minipage} +% \hspace{0.9cm} +% \begin{scope} +% \large +% \begin{NiceTabular}[c]{wl{2cm}ll}[hvlines] +% fraise & amande & abricot \\ +% prune & pêche & poire \\[1ex] +% noix & noisette & brugnon +% \end{NiceTabular} +% \end{scope} +% +% \vspace{1cm} +% \begin{minipage}[c]{7cm} +% Here, we have colored all the cells of the array with |\chessboardcolors|. +% \end{minipage} +% \hspace{1.5cm} +% \begin{scope} +% \large +% \begin{NiceTabular}[c]{wl{2cm}ll}[hvlines,code-before = \chessboardcolors{red!15}{blue!15}] +% fraise & amande & abricot \\ +% prune & pêche & poire \\[1ex] +% noix & noisette & brugnon +% \end{NiceTabular} +% \end{scope} +% +% +% \vspace{1cm} +% \begin{minipage}[c]{7cm} +% Here are the ``large nodes'' of this array (without use of |margin| +% nor |extra-margin|). +% \end{minipage} +% \hspace{1.5cm} +% \begin{scope} +% \large +% \begin{NiceTabular}[c]{wl{2cm}ll}[hvlines, +% create-large-nodes, +% code-after = {\begin{tikzpicture} +% [every node/.style = {blend mode = multiply, +% inner sep = 0 pt}, +% name suffix = -large] +% \node [fit = (1-1),fill = red!15] {} ; +% \node [fit = (1-3),fill = red!15] {} ; +% \node [fit = (2-2),fill = red!15] {} ; +% \node [fit = (3-1),fill = red!15] {} ; +% \node [fit = (3-3),fill = red!15] {} ; +% \node [fit = (1-2),fill = blue!15] {} ; +% \node [fit = (2-1),fill = blue!15] {} ; +% \node [fit = (2-3),fill = blue!15] {} ; +% \node [fit = (3-2),fill = blue!15] {} ; +% \end{tikzpicture}}] +% fraise & amande & abricot \\ +% prune & pêche & poire \\[1ex] +% noix & noisette & brugnon +% \end{NiceTabular} +% \end{scope} +% +% +% +% +% \subsection{The ``row-nodes'' and the ``col-nodes''} +% +% The package \pkg{nicematrix} creates a PGF/Tikz node indicating the potential +% position of each horizontal rule (with the names |row-|$i$) and each vertical +% rule (with the names |col-|$j$), as described in the following figure. These +% nodes are available in the |code-before| and the |\CodeAfter|. +% \begin{center} +% \begin{NiceTabular}{ccc}[hvlines,rules/width=1pt,rules/color=gray] +% rose & tulipe & lys \\ +% arum & iris & violette \\ +% muguet & dahlia & souci +% \CodeAfter +% \tiny +% \begin{tikzpicture} +% \foreach \i in {1,2,3,4} +% { +% \fill [red] (row-\i) circle (0.5mm) ; +% \node [red,anchor=east] at (row-\i) {row-\i} ; +% } +% \foreach \j in {1,2,3,4} +% { +% \fill [blue] (col-\j) circle (0.5mm) ; +% \node [blue,anchor=north] at (col-\j) {col-\j} ; +% } +% \end{tikzpicture} +% \end{NiceTabular} +% \end{center} +% +% \bigskip +% If we use Tikz (we remind that \pkg{nicematrix} does not load Tikz by +% default), we can access (in the |code-before| and the |\CodeAfter|) to the +% intersection of the horizontal rule~$i$ and the vertical rule~$j$ with the +% syntax |(row-|$i$\verb+-|col-+$j$|)|. +% +% \medskip +% \begin{Verbatim} +% \[\begin{NiceMatrix}[ +% code-before = +% { +% ~emphase# \tikz \draw [fill = red!15] @ +% ~emphase# (row-7-|col-4) -- (row-8-|col-4) -- (row-8-|col-5) -- @ +% ~emphase# (row-9-|col-5) -- (row-9-|col-6) |- cycle ; @ +% } +% ] +% 1 \\ +% 1 & 1 \\ +% 1 & 2 & 1 \\ +% 1 & 3 & 3 & 1 \\ +% 1 & 4 & 6 & 4 & 1 \\ +% 1 & 5 & 10 & 10 & 5 & 1 \\ +% 1 & 6 & 15 & 20 & 15 & 6 & 1 \\ +% 1 & 7 & 21 & 35 & 35 & 21 & 7 & 1 \\ +% 1 & 8 & 28 & 56 & 70 & 56 & 28 & 8 & 1 +% \end{NiceMatrix}\] +% \end{Verbatim} +% \[\begin{NiceMatrix}[ +% code-before = +% { +% \tikz \draw [fill = red!15] +% (row-7-|col-4) -- (row-8-|col-4) -- (row-8-|col-5) -- +% (row-9-|col-5) -- (row-9-|col-6) |- cycle ; +% } +% ] +% 1 \\ +% 1 & 1 \\ +% 1 & 2 & 1 \\ +% 1 & 3 & 3 & 1 \\ +% 1 & 4 & 6 & 4 & 1 \\ +% 1 & 5 & 10 & 10 & 5 & 1 \\ +% 1 & 6 & 15 & 20 & 15 & 6 & 1 \\ +% 1 & 7 & 21 & 35 & 35 & 21 & 7 & 1 \\ +% 1 & 8 & 28 & 56 & 70 & 56 & 28 & 8 & 1 +% \end{NiceMatrix}\] +% +% \subsection{The nodes corresponding to the command \textbackslash SubMatrix} +% +% \label{node-sub-matrix} +% +% The command |\SubMatrix| available in the |\CodeAfter| has been described +% p.~\pageref{sub-matrix}. +% +% \smallskip +% If a command |\SubMatrix| has been used with the key |name| with an expression +% such as |name=|\textsl{\ttfamily MyName} three PGF/Tikz nodes are created +% with the names \textsl{\ttfamily MyName}|-left|, \textsl{\ttfamily MyName} and +% \textsl{\ttfamily MyName}|-right|. +% +% \smallskip +% The nodes \textsl{\ttfamily MyName}|-left| and \textsl{\ttfamily +% MyName}|-right| correspond to the delimiters left and right and the node +% \textsl{\ttfamily MyName} correspond to the submatrix itself. +% +% \medskip +% In the following example, we have highlighted these nodes (the submatrix itself has +% been created with |\SubMatrix\{{2-2}{3-3}\}|). +% +% \[\begin{pNiceMatrix} +% 121 & 23 & 345 & 345\\ +% 45 & 346 & 863 & 444\\ +% 3462 & 38458 & 34 & 294 \\ +% 34 & 7 & 78 & 309 \\ +% \CodeAfter +% \SubMatrix\{{2-2}{3-3}\}[name=A] +% \begin{tikzpicture} +% [every node/.style = {blend mode = multiply, +% inner sep = 0 pt}] +% \node [fit = (A),fill = red!15] {} ; +% \node [fit = (A-left),fill = blue!15] {} ; +% \node [fit = (A-right),fill = blue!15] {} ; +% \end{tikzpicture} +% \end{pNiceMatrix}\] +% +% \section{API for the developpers} +% +% The package \pkg{nicematrix} provides two variables which are internal but +% public\footnote{According to the LaTeX3 conventions, +% each variable with name beginning with |\g_nicematrix| ou |\l_nicematrix| is +% public and each variable with name beginning with |\g__nicematrix| or +% |\l__nicematrix| is private.}: +% \begin{itemize} +% \item |\g_nicematrix_code_before_tl| ; +% \item |\g_nicematrix_code_after_tl|. +% \end{itemize} +% +% +% \medskip +% These variables contain the code of what we have called the ``|code-before|'' +% and the ``|code-after|''. The developper can use them to add code from a cell +% of the array (the affectation must be global, allowing to exit the cell, which +% is a TeX group). +% +% \medskip +% One should remark that the use of |\g_nicematrix_code_before_tl| needs one +% compilation more (because the instructions are written on the |aux| file to be +% used during the next run). +% +% \bigskip +% \emph{Example} : We want to write a command |\hatchcell| to hatch the current +% cell (with an optional argument between brackets for the color). It's possible +% to program such command |\hatchcell| as follows, explicitely using the public +% variable |\g_nicematrix_code_before_tl| (this code requires the Tikz library +% \pkg{patterns}: |\usetikzlibrary{patterns}|). +% +% +% \begin{scope} +% \fvset{commandchars=\§\¤\μ} +% \begin{Verbatim} +%\ExplSyntaxOn +% \cs_new_protected:Nn \__pantigny_hatchcell:nnn +% { +% \begin { tikzpicture } +% \fill [ pattern = north~west~lines , pattern~color = #3 ] +% ( row - #1 -| col - #2) +% rectangle +% ( row - \int_eval:n { #1 + 1 } -| col - \int_eval:n { #2 + 1 } ) ; +% \end { tikzpicture } +% } +% +% \NewDocumentCommand \hatchcell { ! O { black } } +% { +% \tl_gput_right:Nx §emphase¤\g_nicematrix_code_before_tlμ +% { +% \__pantigny_hatchcell:nnn +% { \int_use:c { c@iRow } } +% { \int_use:c { c@jCol } } +% { #1 } +% } +% } +% \ExplSyntaxOff +% \end{Verbatim} +% \end{scope} +% +% +%\ExplSyntaxOn +% \cs_new_protected:Nn \__pantigny_hatchcell:nnn +% { +% \begin { tikzpicture } +% \fill [ pattern = north~west~lines , pattern~color = #3 ] +% ( row - #1 -| col - #2) +% rectangle +% ( row - \int_eval:n { #1 + 1 } -| col - \int_eval:n { #2 + 1 } ) ; +% \end { tikzpicture } +% } +% +% \NewDocumentCommand \hatchcell { ! O { black } } +% { +% \tl_gput_right:Nx \g_nicematrix_code_before_tl +% { +% \__pantigny_hatchcell:nnn +% { \int_use:c { c@iRow } } +% { \int_use:c { c@jCol } } +% { #1 } +% } +% } +% \ExplSyntaxOff +% +% +% \bigskip +% Here is an example of use: +% +% \medskip +% \begin{BVerbatim}[baseline=c,boxwidth=9cm] +% \begin{NiceTabular}{ccc}[hvlines] +% Tokyo & Paris & London \\ +% Roma & ~emphase#\hatchcell[blue!30]@Oslo & Miami \\ +% Los Angeles & Madrid & Roma +% \end{NiceTabular} +% \end{BVerbatim} +% \begin{NiceTabular}{ccc}[hvlines] +% Tokyo & Paris & London \\ +% Lima & \hatchcell[blue!30]Oslo & Miami \\ +% Los Angeles & Madrid & Roma +% \end{NiceTabular} % % % \section{Technical remarks} @@ -1917,10 +3640,10 @@ version 2005/12/01 or later. % % \label{OnlyMainNiceMatrix} % -% The extension \pkg{nicematrix} provides the command |\OnlyMainNiceMatrix| +% The package \pkg{nicematrix} provides the command |\OnlyMainNiceMatrix| % which is meant to be used in definitions of new column types. Its argument is % evaluated if and only if we are in the main part of the array, that is to say -% not in an eventual exterior row. +% not in an potential exterior row. % % For example, one may wish to define a new column type |?| in order to draw a % (black) heavy rule of width 1~pt. The following definition will do the @@ -1930,20 +3653,22 @@ version 2005/12/01 or later. % \newcolumntype{?}{!{\OnlyMainNiceMatrix{\vrule width 1 pt}}} % \end{Verbatim} % -% The heavy vertical rule won't extend in the exterior rows: +% The heavy vertical rule won't extend in the exterior rows.\footnote{Of course, +% such rule is defined by the classical technics of \pkg{nicematrix} and, for +% this reason, won't cross the double rules of |\hline\hline|.} % \medskip % \begin{scope} % \newcolumntype{?}{!{\OnlyMainNiceMatrix{\vrule width 1 pt}}} % % \begin{BVerbatim}[baseline = c, boxwidth = 10.5cm] -% $\begin{pNiceArray}{CC?CC}[first-row,last-row=3] +% $\begin{pNiceArray}{cc?cc}[first-row,last-row=3] % C_1 & C_2 & C_3 & C_4 \\ % a & b & c & d \\ % e & f & g & h \\ % C_1 & C_2 & C_3 & C_4 % \end{pNiceArray}$ % \end{BVerbatim} -% $\begin{pNiceArray}{CC?CC}[first-row,last-row=3] +% $\begin{pNiceArray}{cc?cc}[first-row,last-row=3] % C_1 & C_2 & C_3 & C_4 \\ % a & b & c & d \\ % e & f & g & h \\ @@ -1952,63 +3677,10 @@ version 2005/12/01 or later. % \end{scope} % % \medskip -% The specifier |?| may be used in a standard environment |{array}| (of the -% package \pkg{array}) and, in this case, the command |\OnlyMainNiceMatrix| is -% no-op. -% -% -% \subsection{Intersections of dotted lines} -% -% Since the version 3.1 of \pkg{nicematrix}, the dotted lines created by -% |\Cdots|, |\Ldots|, |\Vdots|, etc. can't intersect.\footnote{On the contrary, -% dotted lines created by |\hdottedline|, the letter ``|:|'' in the preamble -% of the array and the command |\line| in the |code-after| can have -% intersections with other dotted lines.} -% -% That means that a dotted line created by one these commands automatically -% stops when it arrives on a dotted line already drawn. Therefore, the order in -% which dotted lines are drawn is important. Here's that order (by design) : -% |\Hdotsfor|, |\Vdots|, |\Ddots|, |\Iddots|, |\Cdots| and |\Ldots|. -% -% With this structure, it's possible to draw the following matrix. -% -% \medskip -% \begin{BVerbatim}[baseline = c, boxwidth = 10.5cm] -% $\begin{pNiceMatrix}[nullify-dots] -% 1 & 2 & 3 & \Cdots & n \\ -% 1 & 2 & 3 & \Cdots & n \\ -% \Vdots & \Cdots & & \Hspace*{15mm} & \Vdots \\ -% & \Cdots & & & \\ -% & \Cdots & & & \\ -% & \Cdots & & & \\ -% \end{pNiceMatrix}$ -% \end{BVerbatim} -% % $\begin{pNiceMatrix}[nullify-dots] -% 1 & 2 & 3 & \Cdots & n \\ -% 1 & 2 & 3 & \Cdots & n \\ -% \Vdots & \Cdots & & \Hspace*{15mm} & \Vdots \\ -% & \Cdots & & & \\ -% & \Cdots & & & \\ -% & \Cdots & & & \\ -% \end{pNiceMatrix}$ -% -% \subsection{The names of the PGF nodes created by nicematrix} -% -% We have said that, when a name is given to an environment of \pkg{nicematrix}, -% it's possible to access the PGF/Tikz nodes through this name (cf. -% p.~\pageref{name}). +% This specifier |?| may be used in the standard environments |{tabular}| and +% |{array}| (of the package \pkg{array}) and, in this case, the command +% |\OnlyMainNiceMatrix| is no-op. % -% That's the recommended way to access these nodes. However, we describe now the -% internal names of these nodes. -% -% The environments created by \pkg{nicematrix} are numbered by an internal -% global counter. The command |\NiceMatrixLastEnv| provides the number of the -% last environment of \pkg{nicematrix} (for LaTeX, it's a ``fully expandable'' -% command and not a counter). -% -% For the environment of number~$n$, the node in row~$i$ and column~$j$ has the -% name |nm-|$n$|-|$i$|-|$j$. The |medium| and |large| nodes have the same name, -% suffixed by |-medium| and |-large|. % % % \subsection{Diagonal lines} @@ -2079,20 +3751,19 @@ version 2005/12/01 or later. % a+b & \Cdots & a+b & 1 % \end{pNiceMatrix}$ % -% % \end{scope} % +% It's possible to specify the instruction |\Ddots| which will be drawn first +% (and which will be used to draw the other diagonal dotted lines when the +% parallelization is in force) with the key |draw-first|: |\Ddots[draw-first]|. +% % \subsection{The ``empty'' cells} % % \label{empty-cells} % An instruction like |\Ldots|, |\Cdots|, etc. tries to determine the first -% non-empty cells on both sides. However, an empty cell is not necessarily a +% non-empty cell on both sides. However, an ``empty cell'' is not necessarily a % cell with no TeX content (that is to say a cell with no token between the two -% ampersands~|&|). Indeed, a cell which only contains |\hspace*{1cm}| may be -% considered as empty. -% -% \interitem -% For \pkg{nicematrix}, the precise rules are as follow. +% ampersands~|&|). The precise rules are as follow. % % \begin{itemize} % \item An implicit cell is empty. For example, in the following matrix: @@ -2109,6 +3780,9 @@ version 2005/12/01 or later. % \medskip % \item Each cell whose TeX ouput has a width equal to zero is empty. % +% \medskip +% \item A cell containing the command |\NotEmpty| is not empty (and a PGF/Tikz +% node) is created in that cell. % % \medskip % \item A cell with a command |\Hspace| (or |\Hspace*|) is empty. This command @@ -2134,7 +3808,7 @@ version 2005/12/01 or later. % |\hskip -\arraycolsep|\footnote{And not by inserting |@{}| on both sides of the % preamble of the array. As a consequence, the length of the |\hline| is not % modified and may appear too long, in particular when using square brackets}. -% The extension \pkg{nicematrix} does the same in all its environments, +% The package \pkg{nicematrix} does the same in all its environments, % |{NiceArray}| included. However, if the user wants the environment % |{NiceArray}| behaving by default like the environment |{array}| of % \pkg{array} (for example, when adapting an existing document) it's possible to @@ -2144,103 +3818,127 @@ version 2005/12/01 or later. % environments of \pkg{nicematrix} are not affected). % % -% \subsection{The class option draft} % -% When the class option |draft| is used, the dotted lines are not drawn, for a -% faster compilation. -% -% \subsection{A technical problem with the argument of -% \textbackslash\textbackslash} -% +% \subsection{Incompatibilities} % -% For technical, reasons, if you use the optional argument of the command |\\|, -% the vertical space added will also be added to the ``normal'' node -% corresponding at the previous node. +% The package \pkg{nicematrix} is not fully compatible with the package +% \pkg{arydshln} (because this package redefines many internal of \pkg{array}). % -% \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=11cm] -% \begin{pNiceMatrix} -% a & \frac AB \\~emphase#[2mm]@ -% b & c -% \end{pNiceMatrix} -% \end{BVerbatim} -% $\begin{pNiceMatrix}[ -% code-after = {\tikz \node [inner sep = 0pt, -% fill = red!15, -% blend mode = multiply, -% fit = (1-2) ] {} ; } ] -% a & \frac AB \\[2mm] -% b & c -% \end{pNiceMatrix}$ +% Anyway, in order to use \pkg{arydshln}, one must first free the letter ``|:|'' +% by giving a new letter for the vertical dotted rules of \pkg{nicematrix}: +% +% \begin{Verbatim} +% \NiceMatrixOptions{letter-for-dotted-lines=;} +% \end{Verbatim} % % \bigskip -% There are two solutions to solve this problem. The first solution is to use a -% TeX command to insert space between the rows. +% As of now, the package \pkg{nicematrix} is not compatible with +% \cls{aastex63}. If you want to use \pkg{nicematrix} with \cls{aastex63}, send +% me an email and I will try to solve the incompatibilies. +% +% \section{Examples} % -% \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=11cm] -% \begin{pNiceMatrix} -% a & \frac AB \\ -% ~emphase#\noalign{\kern2mm}@ -% b & c -% \end{pNiceMatrix} -% \end{BVerbatim} -% $\begin{pNiceMatrix}[ -% code-after = {\tikz \node [inner sep = 0pt, -% fill = red!15, -% blend mode = multiply, -% fit = (1-2) ] {} ; } ] -% a & \frac AB \\ -% \noalign{\kern2mm} -% b & c -% \end{pNiceMatrix}$ +% \subsection{Notes in the tabulars} % +% \label{ex:notes} % -% \bigskip -% The other solution is to use the command |\multicolumn| in the previous cell. +% The tools provided by \pkg{nicematrix} for the composition of the tabular +% notes have been presented in the section \ref{s:notes} p.~\pageref{s:notes}. % % \medskip -% \begin{BVerbatim}[baseline=c,boxwidth=11cm] -% \begin{pNiceMatrix} -% a & ~emphase#\multicolumn1C{\frac AB}@ \\[2mm] -% b & c -% \end{pNiceMatrix} -% \end{BVerbatim} -% $\begin{pNiceMatrix}[ -% code-after = {\tikz \node [inner sep = 0pt, -% fill = red!15, -% blend mode = multiply, -% fit = (1-2) ] {} ; } ] -% a & \multicolumn1C{\frac AB} \\[2mm] -% b & c -% \end{pNiceMatrix}$ +% Let's consider that we wish to number the notes of a tabular with +% stars.\footnote{Of course, it's realistic only when there is very few notes in +% the tabular.} +% +% \medskip +% First, we write a command |\stars| similar the well-known commands +% |\arabic|, |\alph|, |\Alph|, etc. which produces a number of stars equal to +% its argument \footnote{In fact: the value of its argument.} +% \begin{Verbatim} +% \ExplSyntaxOn +% \NewDocumentCommand ~emphase#\stars@ { m } +% { \prg_replicate:nn { \value { ~#1 } } { $ \star $ } } +% \ExplSyntaxOff +% \end{Verbatim} +% % +% Of course, we change the style of the labels with the key |notes/style|. +% However, it would be interesting to change also some parameters in the type of +% list used to compose the notes at the end of the tabular. +% First, we required a composition flush right for the labels with the setting +% |align=right|. +% Moreover, we want the labels to be composed on a width equal to the width of +% the widest label. The widest label is, of course, the label with the greatest +% number of stars. We know that number: it is equal to |\value{tabularnote}| +% (because |tabularnote| is the LaTeX counter used by |\tabularnote| and, +% therefore, at the end of the tabular, its value is equal to the total number +% of tabular notes). We use the key |widest*| of \pkg{enumitem} in order to +% require a width equal to that value: |widest*=\value{tabularnote}|. +% \begin{Verbatim} +% \NiceMatrixOptions +% { +% notes = +% { +% ~emphase#style = \stars{~#1} , @ +% ~emphase#enumitem-keys = @ +% ~emphase# { @ +% ~emphase# widest* = \value{tabularnote} ,@ +% ~emphase# align = right @ +% ~emphase# } @ +% } +% } +% \end{Verbatim} % % -% \subsection{Obsolete environments} -% -% The version 3.0 of \pkg{nicematrix} has introduced the environment -% |{pNiceArray}| (and its variants) with the options |first-row|, |last-row|, -% |first-col| and |last-col|. % -% Consequently the following environments present in previous versions of -% \pkg{nicematrix} are deprecated: -% % -% \begin{itemize} -% \item |{NiceArrayCwithDelims}| ; -% \item |{pNiceArrayC}|, |{bNiceArrayC}|, |{BNiceArrayC}|, |{vNiceArrayC}|, -% |{VNiceArrayC}| ; -% \item |{NiceArrayRCwithDelims}| ; -% \item |{pNiceArrayRC}|, |{bNiceArrayRC}|, |{BNiceArrayRC}|, |{vNiceArrayRC}|, -% |{VNiceArrayRC}|. -% \end{itemize} -% -% Since the version 3.12, the only way to use these environments is loading -% \pkg{nicematrix} with the option |obsolete-environments|. +% \begin{scope} +% \ExplSyntaxOn +% \NewDocumentCommand \stars { m } +% { \prg_replicate:nn { \value { #1 } } { $ \star $ } } +% \NiceMatrixOptions +% { +% notes = +% { +% style = \stars{#1} , +% enumitem-keys = +% { +% widest* = \value{tabularnote} , +% align = right +% } +% } +% } +% \ExplSyntaxOff +% \begin{Verbatim} +% \begin{NiceTabular}{~@{}llr~@{}}[first-row,code-for-first-row = \bfseries] +% \toprule +% Last name & First name & Birth day \\ +% \midrule +% Achard\tabularnote{~emphase#Achard is an old family of the Poitou.@} +% & Jacques & 5 juin 1962 \\ +% Lefebvre\tabularnote{~emphase#The name Lefebvre is an alteration of the name Lefebure.@} +% & Mathilde & 23 mai 1988 \\ +% Vanesse & Stephany & 30 octobre 1994 \\ +% Dupont & Chantal & 15 janvier 1998 \\ +% \bottomrule +% \end{NiceTabular} +% \end{Verbatim} +% +% \begin{center} +% \begin{NiceTabular}{@{}llr@{}}[first-row,code-for-first-row = \bfseries] +% \toprule +% Last name & First name & Birth day \\ +% \midrule +% Achard\tabularnote{Achard is an old family of the Poitou.} +% & Jacques & June 5, 2005 \\ +% Lefebvre\tabularnote{The name Lefebvre is an alteration of the name Lefebure.} +% & Mathilde & January 23, 1975 \\ +% Vanesse & Stephany & October 30, 1994 \\ +% Dupont & Chantal & January 15, 1998 \\ +% \bottomrule +% \end{NiceTabular} +% \end{center} +% \end{scope} % -% However, these environments will certainly be completely deleted in a future -% version of \pkg{nicematrix}. % -% \section{Examples} % % \subsection{Dotted lines} % @@ -2310,7 +4008,7 @@ version 2005/12/01 or later. % \[\begin{BNiceMatrix}[nullify-dots] % 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10\\ % 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10\\ -% \Cdots & & \multicolumn{6}{C}{10 \text{ other rows}} & \Cdots \\ +% \Cdots & & \multicolumn{6}{c}{10 \text{ other rows}} & \Cdots \\ % 1 & 2 & 3 & 4 & 5 & 6 & 7 & 8 & 9 & 10 % \end{BNiceMatrix}\] % @@ -2345,7 +4043,7 @@ version 2005/12/01 or later. % \bigskip % \begin{BVerbatim} % \setlength{\extrarowheight}{1mm} -% \[\begin{vNiceArray}{CCCC:CCC}[columns-width=6mm] +% \[\begin{vNiceArray}{cccc:ccc}[columns-width=6mm] % a_0 & && &b_0 & & \\ % a_1 &\Ddots&& &b_1 &\Ddots& \\ % \Vdots&\Ddots&& &\Vdots &\Ddots&b_0 \\ @@ -2360,7 +4058,7 @@ version 2005/12/01 or later. % % \begin{scope} % \setlength{\extrarowheight}{1mm} -% \[\begin{vNiceArray}{CCCC:CCC}[columns-width=6mm] +% \[\begin{vNiceArray}{cccc:ccc}[columns-width=6mm] % a_0 & && &b_0 & & \\ % a_1 &\Ddots&& &b_1 &\Ddots& \\ % \Vdots&\Ddots&& &\Vdots &\Ddots&b_0 \\ @@ -2372,12 +4070,10 @@ version 2005/12/01 or later. % \end{scope} % % \vspace{2cm} -% An example for a linear system (the vertical rule has been drawn in cyan with -% the tools of \pkg{colortbl}):\par\nobreak +% An example for a linear system:\par\nobreak % % \begin{Verbatim} -% \arrayrulecolor{cyan} -% $\begin{pNiceArray}{*6C|C}[nullify-dots,last-col,code-for-last-col={\scriptstyle}] +% $\begin{pNiceArray}{*6c|c}[nullify-dots,last-col,code-for-last-col=\scriptstyle] % 1 & 1 & 1 &\Cdots & & 1 & 0 & \\ % 0 & 1 & 0 &\Cdots & & 0 & & L_2 \gets L_2-L_1 \\ % 0 & 0 & 1 &\Ddots & & \Vdots & & L_3 \gets L_3-L_1 \\ @@ -2385,12 +4081,10 @@ version 2005/12/01 or later. % \Vdots & & &\Ddots & & 0 & \\ % 0 & & &\Cdots & 0 & 1 & 0 & L_n \gets L_n-L_1 % \end{pNiceArray}$ -% \arrayrulecolor{black} % \end{Verbatim} % -% \arrayrulecolor{cyan} -% \[\begin{pNiceArray}{*6C|C}[nullify-dots,last-col, -% code-for-last-col={\scriptstyle}] +% +% \[\begin{pNiceArray}{*6c|c}[nullify-dots,last-col,code-for-last-col=\scriptstyle] % 1 & 1 & 1 &\Cdots & & 1 & 0 & \\ % 0 & 1 & 0 &\Cdots & & 0 & & L_2 \gets L_2-L_1 \\ % 0 & 0 & 1 &\Ddots & & \Vdots & & L_3 \gets L_3-L_1 \\ @@ -2398,9 +4092,42 @@ version 2005/12/01 or later. % \Vdots & & &\Ddots & & 0 & \\ % 0 & & &\Cdots & 0 & 1 & 0 & L_n \gets L_n-L_1 % \end{pNiceArray}\] -% \arrayrulecolor{black} % % +% +% \subsection{Dotted lines which are no longer dotted} +% +% The option |line-style| controls the style of the lines drawn by |\Ldots|, +% |\Cdots|, etc. Thus, it's possible with these commands to draw lines which are +% not longer dotted. +% +% \begin{Verbatim} +% \NiceMatrixOptions +% {nullify-dots,code-for-first-col = \color{blue},code-for-first-col=\color{blue}} +% $\begin{pNiceMatrix}[first-row,first-col] +% & & \Ldots[line-style={solid,<->},shorten=0pt]^{n \text{ columns}} \\ +% & 1 & 1 & 1 & \Ldots & 1 \\ +% & 1 & 1 & 1 & & 1 \\ +% \Vdots[line-style={solid,<->}]_{n \text{ rows}} & 1 & 1 & 1 & & 1 \\ +% & 1 & 1 & 1 & & 1 \\ +% & 1 & 1 & 1 & \Ldots & 1 +% \end{pNiceMatrix}$ +% \end{Verbatim} +% +% +% \begin{scope} +% \NiceMatrixOptions +% {nullify-dots,code-for-first-col = \color{blue},code-for-first-row=\color{blue}} +% \[\begin{pNiceMatrix}[first-row,first-col] +% & & \Ldots[line-style={solid,<->},shorten=0pt]^{n \text{ columns}} \\ +% & 1 & 1 & 1 & \Ldots & 1 \\ +% & 1 & 1 & 1 & & 1 \\ +% \Vdots[line-style={solid,<->}]_{n \text{ rows}} & 1 & 1 & 1 & & 1 \\ +% & 1 & 1 & 1 & & 1 \\ +% & 1 & 1 & 1 & \Ldots & 1 +% \end{pNiceMatrix}\] +% \end{scope} +% % \subsection{Width of the columns} % % @@ -2412,159 +4139,144 @@ version 2005/12/01 or later. % \bigskip % \begin{BVerbatim} % ~emphase#\begin{NiceMatrixBlock}[auto-columns-width]@ -% \NiceMatrixOptions{code-for-last-col = \color{blue}\scriptstyle} +% \NiceMatrixOptions +% { last-col,code-for-last-col = \color{blue}\scriptstyle,light-syntax} % \setlength{\extrarowheight}{1mm} -% \quad $\begin{pNiceArray}{CCCC:C}[last-col] -% 1&1&1&1&1&\\ -% 2&4&8&16&9&\\ -% 3&9&27&81&36&\\ -% 4&16&64&256&100& +% $\begin{pNiceArray}{cccc:c} +% 1 1 1 1 1 {} ; +% 2 4 8 16 9 ; +% 3 9 27 81 36 ; +% 4 16 64 256 100 +% \end{pNiceArray}$ +% \medskip +% $\begin{pNiceArray}{cccc:c} +% 1 1 1 1 1 ; +% 0 2 6 14 7 { L_2 \gets -2 L_1 + L_2 } ; +% 0 6 24 78 33 { L_3 \gets -3 L_1 + L_3 } ; +% 0 12 60 252 96 { L_4 \gets -4 L_1 + L_4 } % \end{pNiceArray}$ % ... % ~emphase#\end{NiceMatrixBlock}@ % \end{BVerbatim} -% +% % \bigskip -% +% % \begin{multicols}{2} % \begin{NiceMatrixBlock}[auto-columns-width] -% \NiceMatrixOptions{code-for-last-col = \color{blue}\scriptstyle} +% \NiceMatrixOptions{last-col,code-for-last-col = \color{blue}\scriptstyle,light-syntax} % \setlength{\extrarowheight}{1mm} % -% \enskip $\begin{pNiceArray}{CCCC:C}[last-col] -% 1&1&1&1&1&\\ -% 2&4&8&16&9&\\ -% 3&9&27&81&36&\\ -% 4&16&64&256&100& +% \enskip $\begin{pNiceArray}{cccc:c} +% 1 1 1 1 1 {} ; +% 2 4 8 16 9 ; +% 3 9 27 81 36 ; +% 4 16 64 256 100 % \end{pNiceArray}$ % % \medskip % -% \enskip $\begin{pNiceArray}{CCCC:C}[last-col] -% 1&1&1&1&1&\\ -% 0&2&6&14&7&L_2\gets-2L_1+L_2 \\ -% 0&6&24&78&33&L_3\gets-3L_1+L_3 \\ -% 0&12&60&252&96&L_4\gets-4L_1+L_4 +% \enskip $\begin{pNiceArray}{cccc:c} +% 1 1 1 1 1 ; +% 0 2 6 14 7 { L_2 \gets -2 L_1 + L_2 } ; +% 0 6 24 78 33 { L_3 \gets -3 L_1 + L_3 } ; +% 0 12 60 252 96 { L_4 \gets -4 L_1 + L_4 } % \end{pNiceArray}$ % % \medskip % -% \enskip $\begin{pNiceArray}{CCCC:C}[last-col] -% 1&1&1&1&1&\\ -% 0&1&3&7&\frac72&L_2\gets\frac12L_2\\ -% 0&3&12&39&\frac{33}2&L_3\gets\frac12L_3 \\ -% 0&1&5&21&8&L_4\gets\frac1{12}L_4 +% \enskip $\begin{pNiceArray}{cccc:c} +% 1 1 1 1 1 ; +% 0 1 3 7 \frac72 { L_2 \gets \frac12 L_2 } ; +% 0 3 12 39 \frac{33}2 { L_3 \gets \frac12 L_3 } ; +% 0 1 5 21 8 { L_4 \gets \frac1{12} L_4 } % \end{pNiceArray}$ % % \medskip % -% \enskip $\begin{pNiceArray}{CCCC:C}[last-col] -% 1&1&1&1&1&\\ -% 0&1&3&7&\frac72&\\ -% 0&0&3&18&6&L_3 \gets -3L_2+L_3 \\ -% 0&0&-2&-14&-\frac92&L_4 \gets L_2-L_4 +% \enskip $\begin{pNiceArray}{cccc:c} +% 1 1 1 1 1 ; +% 0 1 3 7 \frac72 ; +% 0 0 3 18 6 { L_3 \gets -3 L_2 + L_3 } ; +% 0 0 -2 -14 -\frac92 { L_4 \gets L_2 - L_4 } % \end{pNiceArray}$ % % \medskip % -% \enskip $\begin{pNiceArray}{CCCC:C}[last-col] -% 1&1&1&1&1&\\ -% 0&1&3&7&\frac72&\\ -% 0&0&1&6&2&L_3 \gets \frac13L_3\\ -% 0&0&-2&-14&-\frac92& +% \enskip $\begin{pNiceArray}{cccc:c} +% 1 1 1 1 1 ; +% 0 1 3 7 \frac72 ; +% 0 0 1 6 2 { L_3 \gets \frac13 L_3 } ; +% 0 0 -2 -14 -\frac92 % \end{pNiceArray}$ % % \medskip % -% \enskip $\begin{pNiceArray}{CCCC:C}[last-col] -% 1&1&1&1&1&\\ -% 0&1&3&7&\frac72&\\ -% 0&0&1&6&2& \\ -% 0&0&0&-2&-\frac12 & L_4 \gets 2L_3+L_4 +% \enskip $\begin{pNiceArray}{cccc:c} +% 1 1 1 1 1 ; +% 0 1 3 7 \frac72 ; +% 0 0 1 6 2 ; +% 0 0 0 -2 -\frac12 { L_4 \gets L_3 + L_4 } % \end{pNiceArray}$ % \end{NiceMatrixBlock} % \end{multicols} +% % -% -% \subsection{How to highlight cells of the matrix} +% \subsection{How to highlight cells of a matrix} % % % \label{highlight} -% The following examples require Tikz (by default, \pkg{nicematrix} only loads -% \textsc{pgf}) and the Tikz library |fit|. The following lines in the preamble -% of your document may do the job: -% \begin{verbatim} -% \usepackage{tikz} -% \usetikzlibrary{fit} -% \end{verbatim} % % \medskip -% In order to highlight a cell of a matrix, it's possible to ``draw'' one of the -% correspondant nodes (the ``normal node'', the ``medium node'' or the ``large -% node''). In the following example, we use the ``large nodes'' of the diagonal -% of the matrix (with the Tikz key ``|name suffix|'', it's easy to use the -% ``large nodes''). +% In order to highlight a cell of a matrix, it's possible to ``draw'' that cell +% with the key |draw| of the command |\Block| (this is one of the uses of a +% mono-cell block\footnote{We recall that, if the first mandatory argument of +% the command |\Block| is left empty, that means that the block is a mono-cell block}). +% +% \label{example-CodeAfter} % -% We redraw the nodes with other nodes by using the Tikz library |fit|. Since we -% want to redraw the nodes exactly, we have to set |inner sep = 0 pt| (if we -% don't do that, the new nodes will be larger that the nodes created by -% \pkg{nicematrix}). % % \begin{Verbatim} -% $\begin{pNiceArray}{>{\strut}CCCC}% -% [create-large-nodes,margin,extra-margin = 2pt , -% code-after = {\begin{tikzpicture} -% [~emphase#name suffix = -large@, -% every node/.style = {draw, -% ~emphase#inner sep = 0 pt@}] -% \node [fit = (1-1)] {} ; -% \node [fit = (2-2)] {} ; -% \node [fit = (3-3)] {} ; -% \node [fit = (4-4)] {} ; -% \end{tikzpicture}}] -% a_{11} & a_{12} & a_{13} & a_{14} \\ -% a_{21} & a_{22} & a_{23} & a_{24} \\ -% a_{31} & a_{32} & a_{33} & a_{34} \\ -% a_{41} & a_{42} & a_{43} & a_{44} +% $\begin{pNiceArray}{>{\strut}cccc}[margin,rules/color=blue] +% ~emphase#\Block[draw]{}{a_{11}}@ & a_{12} & a_{13} & a_{14} \\ +% a_{21} & \Block[draw]{}{a_{22}} & a_{23} & a_{24} \\ +% a_{31} & a_{32} & \Block[draw]{}{a_{33}} & a_{34} \\ +% a_{41} & a_{42} & a_{43} & \Block[draw]{}{a_{44}} \\ % \end{pNiceArray}$ % \end{Verbatim} -% -% -% \[\begin{pNiceArray}{>{\strut}CCCC}[ -% create-large-nodes,margin,extra-margin = 2pt, -% code-after = {\begin{tikzpicture}[name suffix = -large, -% every node/.style = {draw, -% inner sep = 0 pt}] -% \node [fit = (1-1)] {} ; -% \node [fit = (2-2)] {} ; -% \node [fit = (3-3)] {} ; -% \node [fit = (4-4)] {} ; -% \end{tikzpicture}}] -% a_{11} & a_{12} & a_{13} & a_{14} \\ -% a_{21} & a_{22} & a_{23} & a_{24} \\ -% a_{31} & a_{32} & a_{33} & a_{34} \\ -% a_{41} & a_{42} & a_{43} & a_{44} +% \[\begin{pNiceArray}{>{\strut}cccc}[margin,rules/color=blue] +% \Block[draw]{}{a_{11}} & a_{12} & a_{13} & a_{14} \\ +% a_{21} & \Block[draw]{}{a_{22}} & a_{23} & a_{24} \\ +% a_{31} & a_{32} & \Block[draw]{}{a_{33}} & a_{34} \\ +% a_{41} & a_{42} & a_{43} & \Block[draw]{}{a_{44}} \\ % \end{pNiceArray}\] % % We should remark that the rules we have drawn are drawn \emph{after} the -% construction of the array and thus, they don't spread the cells of the -% array. We recall that, on the other side, the command |\hline|, the specifier -% ``"|"'' and the options |hlines| and |vlines| spread the cells (when the -% package \pkg{array} is loaded but, when the package \pkg{nicematrix} is -% loaded, \pkg{array} is always loaded).\footnote{On the other side, the command -% |\cline| doesn't spread the rows of the array.} +% construction of the array and thus, they don't spread the cells of the array. +% We recall that, on the other side, the command |\hline|, the specifier ``"|"'' +% and the options |hlines|, |vlines| and |hvlines| spread the +% cells.\footnote{For the command |\cline|, see the remark +% p.~\pageref{remark-cline}.} % % % \vspace{1cm} -% The package \pkg{nicematrix} is constructed upon the environment |{array}| -% and, therefore, it's possible to use the package \pkg{colortbl} in the -% environments of \pkg{nicematrix}. However, it's not always easy to do a fine -% tuning of \pkg{colortbl}. That's why we propose another method to highlight a -% row of the matrix. We create a rectangular Tikz node which encompasses the -% nodes of the second row with the Tikz library \pkg{fit}. This Tikz node is -% filled after the construction of the matrix. In order to see the text -% \emph{under} this node, we have to use transparency with the |blend mode| -% equal to |multiply|. +% It's possible to color a row with |\rowcolor| in the |code-before| (or with +% |\rowcolor| in the first cell of the row if the key |colortbl-like| is used). +% However, it's not possible to do a fine tuning. That's why we describe now a +% method to highlight a row of the matrix. We create a rectangular Tikz node +% which encompasses the nodes of the second row with the Tikz library \pkg{fit}. +% This Tikz node is filled after the construction of the matrix. In order to see +% the text \emph{under} this node, we have to use transparency with the +% |blend mode| equal to |multiply|. +% +% +% \medskip +% That example and the following ones require Tikz (by default, \pkg{nicematrix} +% only loads \textsc{pgf}) and the Tikz library |fit|. The following lines in +% the preamble of your document do the job: +% \begin{verbatim} +% \usepackage{tikz} +% \usetikzlibrary{fit} +% \end{verbatim} % % \tikzset{highlight/.style={rectangle, % fill=red!15, @@ -2582,41 +4294,22 @@ version 2005/12/01 or later. % inner sep=1pt, % fit = ~#1}} % -% $\begin{bNiceMatrix}[~emphase#code-after = {\tikz \node [highlight = (2-1) (2-3)] {} ;}@] +% +% $\begin{bNiceMatrix} % 0 & \Cdots & 0 \\ % 1 & \Cdots & 1 \\ -% 0 & \Cdots & 0 +% 0 & \Cdots & 0 \\ +% ~emphase#\CodeAfter \tikz \node [highlight = (2-1) (2-3)] {} ;@ % \end{bNiceMatrix}$ % \end{Verbatim} -% -% \[\begin{bNiceMatrix}[code-after = {\tikz \node [highlight = (2-1) (2-3)] {} ;}] +% \[\begin{bNiceMatrix} % 0 & \Cdots & 0 \\ % 1 & \Cdots & 1 \\ -% 0 & \Cdots & 0 +% 0 & \Cdots & 0 \\ +% \CodeAfter \tikz \node [highlight = (2-1) (2-3)] {} ; % \end{bNiceMatrix}\] -% -% -% \bigskip -% This code fails with |latex|-|dvips|-|ps2pdf| because Tikz for |dvips|, as for -% now, doesn't support blend modes. However, the following code, in the -% preamble, should activate blend modes in this way of compilation. -% -% -% \begin{scope} \small -% |\ExplSyntaxOn| -% -% |\makeatletter| % -% |\tl_set:Nn \l_tmpa_tl {pgfsys-dvips.def}| % -% |\tl_if_eq:NNT \l_tmpa_tl \pgfsysdriver| -% -% | {\cs_set:Npn\pgfsys@blend@mode#1{\special{ps:~/\tl_upper_case:n #1~.setblendmode}}}| -% -% |\makeatother| -% -% |\ExplSyntaxOff| -% \end{scope} % % \vspace{1cm} % We recall that, for a rectangle of merged cells (with the command |\Block|), a @@ -2628,44 +4321,38 @@ version 2005/12/01 or later. % % \medskip % \begin{BVerbatim}[baseline=c,boxwidth=11.6cm] -% $\begin{pNiceMatrix}% -% [ -% 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 +% $\begin{pNiceMatrix}[margin,create-medium-nodes] +% \Block{3-3}<\Large>{A} & & & 0 \\ +% & \hspace*{1cm} & & \Vdots \\ +% & & & 0 \\ +% 0 & \Cdots& 0 & 0 +% \CodeAfter +% \tikz \node [~emphase#highlight = (1-1-block-medium)@] {} ; % \end{pNiceMatrix}$ % \end{BVerbatim} -% $\begin{pNiceMatrix}[ -% margin, -% create-medium-nodes, -% code-after = -% { \tikz \node [highlight = (1-1-block-medium)] {} ; } -% ] +% $\begin{pNiceMatrix}[margin,create-medium-nodes] % \Block{3-3}<\Large>{A} & & & 0 \\ % & \hspace*{1cm} & & \Vdots \\ % & & & 0 \\ % 0 & \Cdots& 0 & 0 +% \CodeAfter +% \tikz \node [highlight = (1-1-block-medium)] {} ; % \end{pNiceMatrix}$ +% % % \vspace{1cm} % Consider now the following matrix which we have named |example|. % % \medskip % \begin{Verbatim} -% $\begin{pNiceArray}{CCC}[~emphase#name=example@,last-col,create-medium-nodes] +% $\begin{pNiceArray}{ccc}[~emphase#name=example@,last-col,create-medium-nodes] % a & a + b & a + b + c & L_1 \\ % a & a & a + b & L_2 \\ % a & a & a & L_3 % \end{pNiceArray}$ % \end{Verbatim} % -% \[\begin{pNiceArray}{CCC}[last-col] +% \[\begin{pNiceArray}{ccc}[last-col] % a & a + b & a + b + c & L_1 \\ % a & a & a + b & L_2 \\ % a & a & a & L_3 @@ -2706,7 +4393,7 @@ version 2005/12/01 or later. % \medskip % We obtain the following matrix. % -% \[\begin{pNiceArray}{CCC}[ +% \[\begin{pNiceArray}{ccc}[ % last-col, % code-after = {\begin{tikzpicture}[every node/.style = {fill = red!15, % blend mode = multiply, @@ -2735,7 +4422,7 @@ version 2005/12/01 or later. % \medskip % We obtain the following matrix. % -% \[\begin{pNiceArray}{CCC}[ +% \[\begin{pNiceArray}{ccc}[ % last-col, % create-medium-nodes, % code-after = {\begin{tikzpicture}[highlight/.style = {fill = red!15, @@ -2759,41 +4446,37 @@ version 2005/12/01 or later. % In the following example, we use the ``large nodes'' to highlight a zone of % the matrix.\par\nobreak % \begin{Verbatim} -% \begin{pNiceArray}{>{\strut}CCCC}% -% [create-large-nodes,margin,extra-margin=2pt, -% code-after = {\tikz \path [~emphase#name suffix = -large@, -% fill = red!15, -% blend mode = multiply] -% (1-1.north west) -% |- (2-2.north west) -% |- (3-3.north west) -% |- (4-4.north west) -% |- (4-4.south east) -% |- (1-1.north west) ; } ] -% A_{11} & A_{12} & A_{13} & A_{14} \\ -% A_{21} & A_{22} & A_{23} & A_{24} \\ -% A_{31} & A_{32} & A_{33} & A_{34} \\ -% A_{41} & A_{42} & A_{43} & A_{44} +% \begin{pNiceArray}{>{\strut}cccc}[create-large-nodes,margin,extra-margin=2pt] +% A_{11} & A_{12} & A_{13} & A_{14} \\ +% A_{21} & A_{22} & A_{23} & A_{24} \\ +% A_{31} & A_{32} & A_{33} & A_{34} \\ +% A_{41} & A_{42} & A_{43} & A_{44} +% \CodeAfter +% \tikz \path [~emphase#name suffix = -large@,fill = red!15, blend mode = multiply] +% (1-1.north west) +% |- (2-2.north west) +% |- (3-3.north west) +% |- (4-4.north west) +% |- (4-4.south east) +% |- (1-1.north west) ; % \end{pNiceArray} % \end{Verbatim} % -% \[ \begin{pNiceArray}{>{\strut}CCCC}[ -% create-large-nodes,margin,extra-margin=2pt, -% code-after = {\tikz \path [name suffix = -large, -% fill = red!15, -% blend mode = multiply] -% (1-1.north west) -% |- (2-2.north west) -% |- (3-3.north west) -% |- (4-4.north west) -% |- (4-4.south east) -% |- (1-1.north west) ; } ] -% A_{11} & A_{12} & A_{13} & A_{14} \\ -% A_{21} & A_{22} & A_{23} & A_{24} \\ -% A_{31} & A_{32} & A_{33} & A_{34} \\ -% A_{41} & A_{42} & A_{43} & A_{44} -% \end{pNiceArray}\] % +% \[\begin{pNiceArray}{>{\strut}cccc}[create-large-nodes,margin,extra-margin=2pt] +% A_{11} & A_{12} & A_{13} & A_{14} \\ +% A_{21} & A_{22} & A_{23} & A_{24} \\ +% A_{31} & A_{32} & A_{33} & A_{34} \\ +% A_{41} & A_{42} & A_{43} & A_{44} +% \CodeAfter +% \tikz \path [name suffix = -large,fill = red!15, blend mode = multiply] +% (1-1.north west) +% |- (2-2.north west) +% |- (3-3.north west) +% |- (4-4.north west) +% |- (4-4.south east) +% |- (1-1.north west) ; +% \end{pNiceArray}\] % % \subsection{Direct use of the Tikz nodes} % @@ -2822,7 +4505,7 @@ version 2005/12/01 or later. % The matrix $B$ has a ``first row'' (for $C_j$) and that's why we use the key % |first-row|. % \begin{Verbatim} -% \begin{bNiceArray}{C>{\strut}CCCC}[name=B,first-row] +% \begin{bNiceArray}{c>{\strut}cccc}[name=B,first-row] % & & C_j \\ % b_{11} & \Cdots & b_{1j} & \Cdots & b_{1n} \\ % \Vdots & & \Vdots & & \Vdots \\ @@ -2835,19 +4518,19 @@ version 2005/12/01 or later. % The matrix $A$ has a ``first column'' (for $L_i$) and that's why we use the % key |first-col|. % \begin{Verbatim} -% \begin{bNiceArray}{CC>{\strut}CCC}[name=A,first-col] +% \begin{bNiceArray}{cc>{\strut}ccc}[name=A,first-col] % & a_{11} & \Cdots & & & a_{1n} \\ % & \Vdots & & & & \Vdots \\ % L_i & a_{i1} & \Cdots & a_{ik} & \Cdots & a_{in} \\ % & \Vdots & & & & \Vdots \\ -% & a_{n1} & \Cdots & & & a_{nn} \\ +% & a_{n1} & \Cdots & & & a_{nn} % \end{bNiceArray} % & % \end{Verbatim} % % In the matrix product, the two dotted lines have an open extremity. % \begin{Verbatim} -% \begin{bNiceArray}{CC>{\strut}CCC} +% \begin{bNiceArray}{cc>{\strut}ccc} % & & & & \\ % & & \Vdots \\ % \Cdots & & c_{ij} \\ @@ -2872,7 +4555,7 @@ version 2005/12/01 or later. % \NiceMatrixOptions{nullify-dots} % $\begin{array}{cc} % & -% \begin{bNiceArray}{C>{\strut}CCCC}[name=B,first-row] +% \begin{bNiceArray}{c>{\strut}cccc}[name=B,first-row] % & & C_j \\ % b_{11} & \Cdots & b_{1j} & \Cdots & b_{1n} \\ % \Vdots & & \Vdots & & \Vdots \\ @@ -2880,7 +4563,7 @@ version 2005/12/01 or later. % & & \Vdots \\ % b_{n1} & \Cdots & b_{nj} & \Cdots & b_{nn} % \end{bNiceArray} \\ \\ -% \begin{bNiceArray}{CC>{\strut}CCC}[name=A,first-col] +% \begin{bNiceArray}{cc>{\strut}ccc}[name=A,first-col] % & a_{11} & \Cdots & & & a_{1n} \\ % & \Vdots & & & & \Vdots \\ % L_i & a_{i1} & \Cdots & a_{ik} & \Cdots & a_{in} \\ @@ -2888,7 +4571,7 @@ version 2005/12/01 or later. % & a_{n1} & \Cdots & & & a_{nn} \\ % \end{bNiceArray} % & -% \begin{bNiceArray}{CC>{\strut}CCC} +% \begin{bNiceArray}{cc>{\strut}ccc} % & & & & \\ % & & \Vdots \\ % \Cdots & & c_{ij} \\ @@ -2907,7 +4590,7 @@ version 2005/12/01 or later. % % % -% \section{Implementation} +%\section{Implementation} % % By default, the package \pkg{nicematrix} doesn't patch any existing code. % @@ -2930,10 +4613,10 @@ version 2005/12/01 or later. % % % \bigskip -% \subsection*{Declaration of the package and extensions loaded} +% \subsection*{Declaration of the package and packages loaded} % % -% The prefix |nicematrix| has been registred for this extension. +% The prefix |nicematrix| has been registred for this package. % % See: |http://mirrors.ctan.org/macros/latex/contrib/l3kernel/l3prefixes.pdf| % @@ -2945,7 +4628,6 @@ version 2005/12/01 or later. % \begin{macrocode} \RequirePackage{pgfcore} \usepgfmodule{shapes} -\RequirePackage{expl3}[2020/02/08] % \end{macrocode} % % @@ -2956,40 +4638,11 @@ version 2005/12/01 or later. {nicematrix} {\myfiledate} {\myfileversion} - {Mathematical matrices with PGF/TikZ} + {Enhanced arrays with the help of PGF/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 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 } -\DeclareOption* { } -\ProcessOptions \relax -% \end{macrocode} -% -% -% % The command for the treatment of the options of |\usepackage| is at the end of % this package for technical reasons. % @@ -2998,7 +4651,6 @@ version 2005/12/01 or later. % \begin{macrocode} \RequirePackage { array } \RequirePackage { amsmath } -\RequirePackage { xparse } [ 2018-07-01 ] % \end{macrocode} % % \bigskip @@ -3021,21 +4673,42 @@ version 2005/12/01 or later. % \bigskip % \subsection*{Technical definitions} % +% +% \medskip +% \begin{macrocode} +\bool_new:N \c_@@_in_preamble_bool +\bool_set_true:N \c_@@_in_preamble_bool +\AtBeginDocument { \bool_set_false:N \c_@@_in_preamble_bool } +% \end{macrocode} +% % \begin{macrocode} +\bool_new:N \c_@@_arydshln_loaded_bool +\bool_new:N \c_@@_booktabs_loaded_bool +\bool_new:N \c_@@_enumitem_loaded_bool \bool_new:N \c_@@_tikz_loaded_bool \AtBeginDocument { + \@ifpackageloaded { arydshln } + { \bool_set_true:N \c_@@_arydshln_loaded_bool } + { } + \@ifpackageloaded { booktabs } + { \bool_set_true:N \c_@@_booktabs_loaded_bool } + { } + \@ifpackageloaded { enumitem } + { \bool_set_true:N \c_@@_enumitem_loaded_bool } + { } \@ifpackageloaded { tikz } { % \end{macrocode} % In some constructions, we will have to use a |{pgfpicture}| which \emph{must} % be replaced by a |{tikzpicture}| if Tikz is loaded. However, this switch -% between |{pgfpicture}| |{tikzpicture}| can't be done dynamically with a -% conditional because, when the |external| Tikz library, the pair -% |\tikzpicture|-|\endtikpicture| (or |\begin{tikzpicture}-\end{tikzpicture}| -% must be statically ``visible'' (even when extenalization is not activated). +% between |{pgfpicture}| and |{tikzpicture}| can't be done dynamically with a +% conditional because, when the Tikz library |external| is loaded by the user, +% the pair |\tikzpicture|-|\endtikpicture| (or +% |\begin{tikzpicture}-\end{tikzpicture}|) must be statically ``visible'' (even +% when externalization is not activated). % -% That's why we create these token lists |\c_@@_pgfortikzpicture_tl| and +% That's why we create |\c_@@_pgfortikzpicture_tl| and % |\c_@@_endpgfortikzpicture_tl| which will be used to construct in a % |\AtBeginDocument| the correct version of some commands. % \begin{macrocode} @@ -3050,9 +4723,11 @@ version 2005/12/01 or later. } % \end{macrocode} % -% We test whether the current class is \cls{revtex4-1} or \cls{revtex4-2} -% because these classes redefines |\array| (of \pkg{array}) in a way -% incompatible with our programmation. +% We test whether the current class is \cls{revtex4-1} (deprecated) or +% \cls{revtex4-2} because these classes redefines |\array| (of \pkg{array}) in a +% way incompatible with our programmation. As of january 2021, the current +% version \cls{revtex4-2} is 4.2e (compatible with \pkg{booktabs}). +% % \begin{macrocode} \bool_new:N \c_@@_revtex_bool \@ifclassloaded { revtex4-1 } @@ -3062,25 +4737,22 @@ version 2005/12/01 or later. { \bool_set_true:N \c_@@_revtex_bool } { } % \end{macrocode} -% -% -% The following message must be defined right now because it may be used during -% the loading of the package. +% Maybe one of the previous classes will be loaded inside another class... We +% try to detect that situation. % \begin{macrocode} -\@@_msg_new:nn { Draft~mode } - { The~compilation~is~in~draft~mode:~the~dotted~lines~won't~be~drawn. } +\cs_if_exist:NT \rvtx@ifformat@geq { \bool_set_true:N \c_@@_revtex_bool } % \end{macrocode} % +% % \begin{macrocode} -\bool_if:NT \c_@@_draft_bool { \msg_warning:nn { nicematrix } { Draft~mode } } +\cs_generate_variant:Nn \tl_if_single_token_p:n { V } % \end{macrocode} % -% % \bigskip % We define a command |\iddots| similar to |\ddots| ($\ddots$) but with dots -% going forward ($\iddots$). We use |\ProvideDocumentCommand| of \pkg{xparse}, -% and so, if the command |\iddots| has already been defined (for example by the -% package \pkg{mathdots}), we don't define it again. +% going forward ($\iddots$). We use |\ProvideDocumentCommand| and so, if the +% command |\iddots| has already been defined (for example by the package +% \pkg{mathdots}), we don't define it again. % % \begin{macrocode} \ProvideDocumentCommand \iddots { } @@ -3102,6 +4774,360 @@ version 2005/12/01 or later. % This definition is a variant of the standard definition of |\ddots|. % % +% \bigskip +% In the |aux| file, we will have the references of the PGF/Tikz nodes created +% by \pkg{nicematrix}. However, when \pkg{booktabs} is used, some nodes (more +% precisely, some |row| nodes) will be defined twice because their position will +% be modified. In order to avoid an error message in this case, we will redefine +% |\pgfutil@check@rerun| in the |aux| file. +% \begin{macrocode} +\AtBeginDocument + { + \@ifpackageloaded { booktabs } + { \iow_now:Nn \@mainaux \nicematrix@redefine@check@rerun } + { } + } +\cs_set_protected:Npn \nicematrix@redefine@check@rerun + { + \cs_set_eq:NN \@@_old_pgfutil@check@rerun \pgfutil@check@rerun +% \end{macrocode} +% The new version of |\pgfutil@check@rerun| will not check the PGF nodes whose +% names start with |nm-| (which is the prefix for the nodes creates by +% \pkg{nicematrix}). +% \begin{macrocode} + \cs_set_protected:Npn \pgfutil@check@rerun ##1 ##2 + { + \str_if_eq:eeF { nm- } { \tl_range:nnn { ##1 } 1 3 } + { \@@_old_pgfutil@check@rerun { ##1 } { ##2 } } + } + } +% \end{macrocode} +% +% \bigskip +% We have to know whether \pkg{colortbl} is loaded in particular for the +% redefinition of |\everycr|. +% \begin{macrocode} +\bool_new:N \c_@@_colortbl_loaded_bool +\AtBeginDocument + { + \@ifpackageloaded { colortbl } + { \bool_set_true:N \c_@@_colortbl_loaded_bool } + { +% \end{macrocode} +% The command |\CT@arc@| is a command of \pkg{colortbl} which sets the color of +% the rules in the array. We will use it to store the instruction of color for +% the rules even if \pkg{colortbl} is not loaded. Idem for +% \begin{macrocode} + \cs_set_protected:Npn \CT@arc@ { } + \cs_set:Npn \arrayrulecolor #1 # { \CT@arc { #1 } } + \cs_set:Npn \CT@arc #1 #2 + { + \dim_compare:nNnT \baselineskip = \c_zero_dim \noalign + { \cs_gset:Npn \CT@arc@ { \color #1 { #2 } } } + } +% \end{macrocode} +% Idem for |\CT@drs@|. +% \begin{macrocode} + \cs_set_protected:Npn \CT@drsc@ { } + \cs_set:Npn \doublerulesepcolor #1 # { \CT@drs { #1 } } + \cs_set:Npn\CT@drs #1 #2 + { + \dim_compare:nNnT \baselineskip = \c_zero_dim \noalign + { \cs_gset:Npn \CT@drsc@ { \color #1 { #2 } } } + } + \cs_set:Npn \hline + { + \noalign { \ifnum 0 = `} \fi + \cs_set_eq:NN \hskip \vskip + \cs_set_eq:NN \vrule \hrule + \cs_set_eq:NN \@width \@height + { \CT@arc@ \vline } + \futurelet \reserved@a + \@xhline + } + } + } +% \end{macrocode} +% +% \bigskip +% We have to redefine |\cline| for several reasons. The command |\@@_cline| will +% be linked to |\cline| in the beginning of |{NiceArrayWithDelims}|. The +% following commands must \emph{not} be protected. +% \begin{macrocode} +\cs_set:Npn \@@_standard_cline #1 { \@@_standard_cline:w #1 \q_stop } +\cs_set:Npn \@@_standard_cline:w #1-#2 \q_stop + { + \int_compare:nNnT \l_@@_first_col_int = 0 { \omit & } + \int_compare:nNnT { #1 } > 1 { \multispan { \@@_pred:n { #1 } } & } + \multispan { \int_eval:n { #2 - #1 + 1 } } + { + \CT@arc@ + \leaders \hrule \@height \arrayrulewidth \hfill +% \end{macrocode} +% The following |\skip_horizontal:N \c_zero_dim| is to prevent a potential +% |\unskip| to delete the |\leaders|\footnote{See question 99041 on TeX +% StackExchange.} +% \begin{macrocode} + \skip_horizontal:N \c_zero_dim + } +% \end{macrocode} +% Our |\everycr| has been modified. In particular, the creation of the |row| +% node is in the |\everycr| (maybe we should put it with the incrementation of +% |\c@iRow|). Since the following |\cr| correspond to a ``false row'', we have +% to nullify |\everycr|. +% \begin{macrocode} + \everycr { } + \cr + \noalign { \skip_vertical:N -\arrayrulewidth } + } +% \end{macrocode} +% +% \bigskip +% The following version of |\cline| spreads the array of a quantity equal +% to |\arrayrulewidth| as does |\hline|. It will be loaded excepted if the key +% |standard-cline| has been used. +% \begin{macrocode} +\cs_set:Npn \@@_cline +% \end{macrocode} +% We have to act in a fully expandable way since there may be |\noalign| (in the +% |\multispan|) to detect. That's why we use |\@@_cline_i:en|. +% \begin{macrocode} + { \@@_cline_i:en \l_@@_first_col_int } +% \end{macrocode} +% The command |\cline_i:nn| has two arguments. The first is the number of the +% current column (it \emph{must} be used in that column). The second is a +% standard argument of |\cline| of the form \textsl{i}-\textsl{j}. +% \begin{macrocode} +\cs_set:Npn \@@_cline_i:nn #1 #2 { \@@_cline_i:w #1-#2 \q_stop } +\cs_set:Npn \@@_cline_i:w #1-#2-#3 \q_stop + { +% \end{macrocode} +% Now, |#1| is the number of the current column and we have to draw a line from +% the column |#2| to the column |#3| (both included). +% \begin{macrocode} + \int_compare:nNnT { #1 } < { #2 } + { \multispan { \int_eval:n { #2 - #1 } } & } + \multispan { \int_eval:n { #3 - #2 + 1 } } + { + \CT@arc@ + \leaders \hrule \@height \arrayrulewidth \hfill + \skip_horizontal:N \c_zero_dim + } +% \end{macrocode} +% You look whether there is another |\cline| to draw (the final user may put +% several |\cline|). +% \begin{macrocode} + \peek_meaning_remove_ignore_spaces:NTF \cline + { & \@@_cline_i:en { \@@_succ:n { #3 } } } + { \everycr { } \cr } + } +\cs_generate_variant:Nn \@@_cline_i:nn { e n } +% \end{macrocode} +% +% \bigskip +% The following commands are only for efficiency. They must \emph{not} be protected +% because it will be used (for instance) in names of \textsc{pgf} nodes. +% \begin{macrocode} +\cs_new:Npn \@@_succ:n #1 { \the \numexpr #1 + 1 \relax } +\cs_new:Npn \@@_pred:n #1 { \the \numexpr #1 - 1 \relax } +% \end{macrocode} +% +% \bigskip +% The following command is a small shortcut. +% \begin{macrocode} +\cs_new:Npn \@@_math_toggle_token: + { \bool_if:NF \l_@@_NiceTabular_bool \c_math_toggle_token } +% \end{macrocode} +% +% \bigskip +% \begin{macrocode} +\cs_new_protected:Npn \@@_set_CT@arc@: + { \peek_meaning:NTF [ \@@_set_CT@arc@_i: \@@_set_CT@arc@_ii: } +\cs_new_protected:Npn \@@_set_CT@arc@_i: [ #1 ] #2 \q_stop + { \cs_set:Npn \CT@arc@ { \color [ #1 ] { #2 } } } +\cs_new_protected:Npn \@@_set_CT@arc@_ii: #1 \q_stop + { \cs_set:Npn \CT@arc@ { \color { #1 } } } +% \end{macrocode} +% +% +% +% \bigskip +% \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} +\bool_new:N \c_@@_siunitx_loaded_bool +\AtBeginDocument + { + \@ifpackageloaded { siunitx } + { \bool_set_true:N \c_@@_siunitx_loaded_bool } + { } + } +% \end{macrocode} +% +% \medskip +% The command |\NC@rewrite@S| is a LaTeX command created by \pkg{siunitx} in +% connection with the |S| column. In the code of \pkg{siunitx}, this command is +% defined by: +% \begin{Verbatim}[commandchars=\~\!\+, formatcom = \small] +% \renewcommand*{\NC@rewrite@S}[1][] +% { +% \@temptokena \exp_after:wN +% { +% \tex_the:D \@temptokena +% > { \__siunitx_table_collect_begin: S {#1} } +% c +% < { \__siunitx_table_print: } +% } +% \NC@find +% } +% \end{Verbatim} +% We want to patch this command (in the environments of \pkg{nicematrix}) in +% order to have: +% \begin{Verbatim}[commandchars=\~\!\+, formatcom = \small] +% \renewcommand*{\NC@rewrite@S}[1][] +% { +% \@temptokena \exp_after:wN +% { +% \tex_the:D \@temptokena +% > { ~emphase!\@@_Cell:+ \__siunitx_table_collect_begin: S {#1} } +% ~emphase!\@@_true_c:+ +% < { \__siunitx_table_print: ~emphase!\@@_end_Cell:+ } +% } +% \NC@find +% } +% \end{Verbatim} +% However, we don't want do use explicitly any private command of \pkg{siunitx}. +% That's why we will extract the name of the two |\__siunitx...| commands by +% their position in the code of |\NC@rewrite@S|. +% +% Since the command |\NC@rewrite@S| appends some tokens to the \emph{toks} list +% |\@temptokena|, we use the LaTeX command |\NC@rewrite@S| in a group +% (|\group_begin:|--|\group_end:|) and we extract the two command names which +% are in the toks |\@temptokena|. However, this extraction can be done only +% 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 use of an +% environment of \pkg{nicematrix} with the command |\@@_adapt_S_column:|. +% \begin{macrocode} +\cs_set_protected:Npn \@@_adapt_S_column: + { + \bool_if:NT \c_@@_siunitx_loaded_bool + { + \group_begin: + \@temptokena = { } +% \end{macrocode} +% We protect |\NC@find| which is at the end of |\NC@rewrite@S|. +% \begin{macrocode} + \cs_set_eq:NN \NC@find \prg_do_nothing: + \NC@rewrite@S { } +% \end{macrocode} +% Conversion of the \emph{toks} |\@temptokena| in a token list of \pkg{expl3} +% (the toks are not supported by \pkg{expl3} but we can, nevertheless, use the +% option |V| for |\tl_gset:NV|). +% \begin{macrocode} + \tl_gset:NV \g_tmpa_tl \@temptokena + \group_end: + \tl_new:N \c_@@_table_collect_begin_tl + \tl_set:Nx \l_tmpa_tl { \tl_item:Nn \g_tmpa_tl 2 } + \tl_gset:Nx \c_@@_table_collect_begin_tl { \tl_item:Nn \l_tmpa_tl 1 } + \tl_new:N \c_@@_table_print_tl + \tl_gset:Nx \c_@@_table_print_tl { \tl_item:Nn \g_tmpa_tl { -1 } } +% \end{macrocode} +% The token lists |\c_@@_table_collect_begin_tl| and |\c_@@_table_print_tl| +% contain now the two commands of \pkg{siunitx}. +% +% \smallskip +% If the adaptation has been done, the command |\@@_adapt_S_column:| becomes +% no-op (globally). +% \begin{macrocode} + \cs_gset_eq:NN \@@_adapt_S_column: \prg_do_nothing: + } + } +% \end{macrocode} +% +% \bigskip +% The command |\@@_renew_NC@rewrite@S:| will be used in each environment of +% \pkg{nicematrix} in order to ``rewrite'' the |S| column in each environment. +% \begin{macrocode} +\AtBeginDocument + { + \bool_if:nTF { ! \c_@@_siunitx_loaded_bool } + { \cs_set_eq:NN \@@_renew_NC@rewrite@S: \prg_do_nothing: } + { + \cs_new_protected:Npn \@@_renew_NC@rewrite@S: + { + \renewcommand*{\NC@rewrite@S}[1][] + { + \@temptokena \exp_after:wN + { + \tex_the:D \@temptokena + > { \@@_Cell: \c_@@_table_collect_begin_tl S {##1} } +% \end{macrocode} +% |\@@_true_c:| will be replaced statically by |c| at the end of the construction +% of the preamble. +% \begin{macrocode} + \@@_true_c: + < { \c_@@_table_print_tl \@@_end_Cell: } + } + \NC@find + } + } + } + } +% \end{macrocode} +% +% \bigskip +% The following regex will be used to modify the preamble of the array when the +% key |colortbl-like| is used. +% \begin{macrocode} +\regex_const:Nn \c_@@_columncolor_regex { \c { columncolor } } +% \end{macrocode} +% +% \bigskip +% If the final user uses \pkg{nicematrix}, PGF/Tikz will write instruction +% |\pgfsyspdfmark| in the |aux| file. If he changes its mind and no longer loads +% \pkg{nicematrix}, an error may occur at the next compilation because of +% remanent instructions |\pgfsyspdfmark| in the |aux| file. With the following +% code, we avoid that situation. +% \begin{macrocode} +\cs_new_protected:Npn \@@_provide_pgfsyspdfmark: + { + \iow_now:Nn \@mainaux + { + \ExplSyntaxOn + \cs_if_free:NT \pgfsyspdfmark + { \cs_set_eq:NN \pgfsyspdfmark \@gobblethree } + \ExplSyntaxOff + } + \cs_gset_eq:NN \@@_provide_pgfsyspdfmark: \prg_do_nothing: + } +% \end{macrocode} +% +% \subsection*{Parameters} +% +% \bigskip +% For compatibility with versions prior to 5.0, we provide a load-time option +% |define_L_C_R|. With this option, it's possible the letters |L|, |C| and |R| +% instead of |l|, |c| and |r| in the preamble of the environments of +% \pkg{nicematrix} as it was mandatory before version~5.0. +% \begin{macrocode} +\bool_new:N \c_@@_define_L_C_R_bool +% \end{macrocode} +% +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_define_L_C_R: + { + \newcolumntype L l + \newcolumntype C c + \newcolumntype R r + } +% \end{macrocode} +% % \bigskip % The following counter will count the environments |{NiceArray}|. The value of % this counter will be used to prefix the names of the Tikz nodes created in the @@ -3109,15 +5135,37 @@ version 2005/12/01 or later. % \begin{macrocode} \int_new:N \g_@@_env_int % \end{macrocode} -% +% +% \bigskip +% The following command is only a syntaxic shortcut. It must \emph{not} be +% protected (it will be used in names of \textsc{pgf} nodes). % \begin{macrocode} \cs_new:Npn \@@_env: { nm - \int_use:N \g_@@_env_int } -\cs_new_protected:Npn \@@_qpoint: #1 +% \end{macrocode} +% +% \bigskip +% The command |\NiceMatrixLastEnv| is not used by the package \pkg{nicematrix}. +% It's only a facility given to the final user. It gives the number of the last +% environment (in fact the number of the current environment but it's meant to +% be used after the environment in order to refer to that environment --- and +% its nodes --- without having to give it a name). This command \emph{must} be +% expandable since it will be used in \pkg{pgf} nodes. +% \begin{macrocode} +\NewExpandableDocumentCommand \NiceMatrixLastEnv { } + { \int_use:N \g_@@_env_int } +% \end{macrocode} +% +% +% \bigskip +% The following command is only a syntaxic shortcut. The |q| in |qpoint| means +% \emph{quick}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_qpoint:n #1 { \pgfpointanchor { \@@_env: - #1 } { center } } % \end{macrocode} % % \bigskip -% We also define a counter to count the environments |{NiceMatrixBlock}|. +% The following counter will count the environments |{NiceMatrixBlock}|. % \begin{macrocode} \int_new:N \g_@@_NiceMatrixBlock_int % \end{macrocode} @@ -3132,6 +5180,31 @@ version 2005/12/01 or later. % \end{macrocode} % % \bigskip +% The following token list will contain the type of the current cell (|l|, |c| +% or |r|). It will be used by the blocks. +% \begin{macrocode} +\tl_new:N \l_@@_cell_type_tl +\tl_set:Nn \l_@@_cell_type_tl { c } +% \end{macrocode} +% +% \bigskip +% When there is a mono-column block (created by the command |\Block|), we want +% to take into account the width of that block for the width of the column. +% That's why we compute the width of that block in the |\g_@@_blocks_wd_dim| +% and, after the construction of the box |\l_@@_cell_box|, we change the width +% of that box to take into account the length |\g_@@_blocks_wd_dim|. +% \begin{macrocode} +\dim_new:N \g_@@_blocks_wd_dim +% \end{macrocode} +% +% \bigskip +% Idem pour the blocks mono-row. +% \begin{macrocode} +\dim_new:N \g_@@_blocks_ht_dim +\dim_new:N \g_@@_blocks_dp_dim +% \end{macrocode} +% +% \bigskip % The sequence |\g_@@_names_seq| will be the list of all the names of % environments used (via the option |name|) in the document: two environments % must not have the same name. However, it's possible to use the option @@ -3140,108 +5213,87 @@ version 2005/12/01 or later. \seq_new:N \g_@@_names_seq % \end{macrocode} % - % \bigskip % We want to know if we are in an environment of \pkg{nicematrix} because we % will raise an error if the user tries to use nested environments. % \begin{macrocode} \bool_new:N \l_@@_in_env_bool % \end{macrocode} -% % % \bigskip -% If the user uses |{NiceArray}| (and not another environment relying upon -% |{NiceArrayWithDelims}| like |{pNiceArray}|), we will raise the flag -% |\l_@@_NiceArray_bool|. We have to know that, because, in |{NiceArray}|, we -% won't use a structure with |\left| and |\right| and we will use the option of -% position (|t|, |b| or |c|). +% If the user uses |{NiceArray}| or |{NiceTabular}| the flag +% |\l_@@_NiceArray_bool| will be raised. % \begin{macrocode} \bool_new:N \l_@@_NiceArray_bool % \end{macrocode} % -% % \bigskip +% If the user uses |{NiceTabular}| or |{NiceTabular*}|, we will raise the +% following flag. % \begin{macrocode} -\cs_new_protected:Npn \@@_test_if_math_mode: - { - \if_mode_math: \else: - \@@_fatal:n { Outside~math~mode } - \fi: - } +\bool_new:N \l_@@_NiceTabular_bool % \end{macrocode} % -% -% % \bigskip -% We have to know whether \pkg{colortbl} is loaded for the redefinition of -% |\everycr| and |\vline| and for the options |hlines| and |vlines|. +% If the user uses |{NiceTabular*}|, the width of the tabular (in the first +% argument of the environment |{NiceTabular*}|) will be stored in the following +% dimension. % \begin{macrocode} -\bool_new:N \c_@@_colortbl_loaded_bool -\AtBeginDocument - { - \@ifpackageloaded { colortbl } - { - \bool_set_true:N \c_@@_colortbl_loaded_bool - \cs_set_protected:Npn \@@_vline_i: { { \CT@arc@ \vline } } - } - { } - } +\dim_new:N \l_@@_tabular_width_dim % \end{macrocode} -% +% +% \bigskip +% If the user uses an environment without preamble, we will raise the following +% flag. % \begin{macrocode} -\colorlet { nicematrix-last-col } { . } -\colorlet { nicematrix-last-row } { . } +\bool_new:N \l_@@_Matrix_bool % \end{macrocode} % % \bigskip -% The length |\l_@@_inter_dots_dim| is the distance between two dots for the -% dotted lines. The default value is 0.45~em but it will be changed if the -% option |small| is used. +% The following boolean will be raised when the command |\rotate| is used. % \begin{macrocode} -\dim_new:N \l_@@_inter_dots_dim -\dim_set:Nn \l_@@_inter_dots_dim { 0.45 em } +\bool_new:N \g_@@_rotate_bool % \end{macrocode} % % \bigskip -% The length |\l_@@_xdots_shorten_dim| is the minimal distance between a -% node (in fact an anchor of that node) and a dotted line (we say ``minimal'' -% because, by definition, a dotted line is not a continuous line and, therefore, -% this distance may vary a little). % \begin{macrocode} -\dim_new:N \l_@@_xdots_shorten_dim -\dim_set:Nn \l_@@_xdots_shorten_dim { 0.3 em } +\cs_new_protected:Npn \@@_test_if_math_mode: + { + \if_mode_math: \else: + \@@_fatal:n { Outside~math~mode } + \fi: + } % \end{macrocode} +% % % \bigskip -% The length |\l_@@_radius_dim| is the radius of the dots for the dotted lines -% (for |\hdottedline| and |\dottedline| and for all the other dotted lines when -% |line-style| is equal to |standard|, which is the initial value). The initial -% value is 0.53~pt but it will be changed if the option |small| is used (to -% 0.37~pt). +% The following colors will be used to memorize le color of the potential ``first +% col'' and the potential ``first row''. % \begin{macrocode} -\dim_new:N \l_@@_radius_dim -\dim_set:Nn \l_@@_radius_dim { 0.53 pt } +\colorlet { nicematrix-last-col } { . } +\colorlet { nicematrix-last-row } { . } % \end{macrocode} -% % \bigskip -% The name of the current environment or the current command (despite the name -% which contains \textsl{env}). +% The following string is the name of the current environment or the current +% command of \pkg{nicematrix} (despite its name which contains \textsl{env}). % \begin{macrocode} \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 +% \bigskip +% The following string will contain the word \emph{command} or +% \emph{environment} whether we are in a command of \pkg{nicematrix} or in 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 } +% \begin{macrocode} +\tl_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 which contains -% \textsl{env}). This command must \emph{not} be protected since it's used in -% error messages. +% \bigskip +% The following command will be able to reconstruct the full name of the current +% command or environment (despite its name which contains \textsl{env}). This +% command must \emph{not} be protected since it will be used in error messages +% and we have to use |\str_if_eq:VnTF| and not |\tl_if_eq:NnTF| because we need +% to be fully expandable). % \begin{macrocode} \cs_new:Npn \@@_full_name_env: { @@ -3252,35 +5304,87 @@ version 2005/12/01 or later. % \end{macrocode} % % \bigskip +% The following token list corresponds to the option |code-after| (it's also +% possible to set the value of that parameter with the keyword |\CodeAfter|). +% \begin{macrocode} +\tl_new:N \g_nicematrix_code_after_tl +% \end{macrocode} +% +% \bigskip +% The following token list has a function similar to +% |\g_nicematrix_code_after_tl| but it is used internally by \pkg{nicematrix}. +% In fact, we have to distinguish between |\g_nicematrix_code_after_tl| and +% |\g_@@_internal_code_after_tl| because we must take care of the order in which +% instructions stored in that paremeters are executed. % \begin{macrocode} \tl_new:N \g_@@_internal_code_after_tl -\tl_new:N \g_@@_code_after_tl % \end{macrocode} % -% % \bigskip -% The counters |\l_@@_save_iRow_int| and |\l_@@_save_jCol_int| will be used to -% save the values of the eventual LaTeX counters |iRow| and |jCol|. These LaTeX +% The counters |\l_@@_old_iRow_int| and |\l_@@_old_jCol_int| will be used to +% save the values of the potential LaTeX counters |iRow| and |jCol|. These LaTeX % counters will be restored at the end of the environment. % \begin{macrocode} -\int_new:N \l_@@_save_iRow_int -\int_new:N \l_@@_save_jCol_int +\int_new:N \l_@@_old_iRow_int +\int_new:N \l_@@_old_jCol_int % \end{macrocode} % % The TeX counters |\c@iRow| and |\c@jCol| will be created in the beginning of % |{NiceArrayWithDelims}| (if they don't exist previously). +% +% \bigskip +% The following token list corresponds to the key |rules/color| available +% in the environments. +% \begin{macrocode} +\tl_new:N \l_@@_rules_color_tl +% \end{macrocode} +% +% +% \bigskip +% This boolean will be used only to detect in an expandable way whether we are +% at the beginning of the (potential) column zero, in order to raise an error if +% |\Hdotsfor| is used in that column. +% \begin{macrocode} +\bool_new:N \g_@@_after_col_zero_bool +% \end{macrocode} % +% \bigskip +% A kind of false row will be inserted at the end of the array for the +% construction of the |col| nodes (and also to fix the width of the columns when +% |columns-width| is used). When this special row will be created, we will raise +% the flag |\g_@@_row_of_col_done_bool| in order to avoid some actions set in +% the redefinition of |\everycr| when the last |\cr| of the |\halign| will occur +% (after that row of |col| nodes). % \begin{macrocode} \bool_new:N \g_@@_row_of_col_done_bool % \end{macrocode} % +% \bigskip +% It's possible to use the command |\NotEmpty| to specify explicitely that a +% cell must be considered as non empty by \pkg{nicematrix} (the Tikz nodes are +% constructed only in the non empty cells). % \begin{macrocode} -\tl_new:N \l_@@_initial_suffix_tl -\tl_new:N \l_@@_initial_anchor_tl -\tl_new:N \l_@@_final_suffix_tl -\tl_new:N \l_@@_final_anchor_tl +\bool_new:N \g_@@_not_empty_cell_bool % \end{macrocode} % +% \bigskip +% |\l_@@_code_before_tl| may contain two types of informations: +% \begin{itemize} +% \item A |code-before| written in the |aux| file by a previous run. When the +% |aux| file is read, this |code-before| is stored in +% |\g_@@_code_before_|\textsl{i}|_tl| (where \textsl{i} is the number of the +% environment) and, at the beginning of the environment, it will be put in +% |\l_@@_code_before_tl|. +% \item The final user can explicitely add material in |\l_@@_code_before_tl| by +% using the key |code-before|. +% \end{itemize} +% \begin{macrocode} +\tl_new:N \l_@@_code_before_tl +\bool_new:N \l_@@_code_before_bool +% \end{macrocode} +% +% \bigskip +% The following dimensions will be used when drawing the dotted lines. % \begin{macrocode} \dim_new:N \l_@@_x_initial_dim \dim_new:N \l_@@_y_initial_dim @@ -3288,24 +5392,144 @@ version 2005/12/01 or later. \dim_new:N \l_@@_y_final_dim % \end{macrocode} % +% \bigskip +% \pkg{expl3} provides scratch dimensions |\l_tmpa_dim| and |\l_tmpb_dim|. We +% creates two other in the same spirit (if they don't exist yet: that's why we +% use |\dim_zero_new:N|). % \begin{macrocode} -\dim_new:N \l_tmpc_dim -\dim_new:N \l_tmpd_dim +\dim_zero_new:N \l_tmpc_dim +\dim_zero_new:N \l_tmpd_dim % \end{macrocode} % +% \bigskip +% Some cells will be declared as ``empty'' (for example a cell with an +% instruction |\Cdots|). % \begin{macrocode} \bool_new:N \g_@@_empty_cell_bool % \end{macrocode} % +% \bigskip +% The following dimension will be used to save the current value of +% |\arraycolsep|. +% \begin{macrocode} +\dim_new:N \@@_old_arraycolsep_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} +% +% \bigskip +% The following sequence will contain the characteristics of the blocks of the +% array, specified by the command |\Block|. Each block is represented by 6 +% components surrounded by braces: +% +% |{|\textsl{imin}|}{|\textsl{jmin}|}{|\textsl{imax}|}{|\textsl{jmax}|}{|\textsl{options}|}{|\textsl{contents}|}|. +% +% The variable is global because it will be modified in the cells of the array. +% \begin{macrocode} +\seq_new:N \g_@@_blocks_seq +% \end{macrocode} +% We also manage a sequence of the \emph{positions} of the blocks. Of course, +% it's redundant with the previous sequence, but it's for efficiency. In that +% sequence, each block is represented by only the four first components: +% |{|\textsl{imin}|}{|\textsl{jmin}|}{|\textsl{imax}|}{|\textsl{jmax}|}|. +% \begin{macrocode} +\seq_new:N \g_@@_pos_of_blocks_seq +% \end{macrocode} +% In fact, this sequence will also contain the positions of the cells with a +% |\diagbox|. The sequence |\g_@@_pos_of_blocks_seq| will be used when we will +% draw the rules (which respect the blocks). +% +% \bigskip +% We will also manage a sequence for the positions of the dotted lines. These +% dotted lines are created in the array by |\Cdots|, |\Vdots|, |\Ddots|, etc. +% However, their positions, that is to say, their extremities, will be +% determined only after the construction of the array. In this sequence, each +% item contains four components: +% |{|\textsl{imin}|}{|\textsl{jmin}|}{|\textsl{imax}|}{|\textsl{jmax}|}|. +% \begin{macrocode} +\seq_new:N \g_@@_pos_of_xdots_seq +% \end{macrocode} +% The sequence |\g_@@_pos_of_xdots_seq| will be used when we will draw the rules +% required by the key |hvlines| (these rules won't be drawn within the virtual +% blocks corresponding to the dotted lines). +% % \medskip -% The token list |\l_@@_xdots_line_style_tl| corresponds to the option |tikz| of the -% commands |\Cdots|, |\Ldots|, etc. and of the options |line-style| for the -% environments and |\NiceMatrixOptions|. The constant |\c_@@_standard_tl| will -% be used in some tests. +% The final user may decide to ``stroke'' a block (using, for example, the key +% |color=red!15| when using the command |\Block|). In that case, the rules +% specified, for instance, by |hvlines| must not be drawn around the block. +% That's why we keep the information of all that stroken blocks in the following +% sequence. % \begin{macrocode} -\tl_new:N \l_@@_xdots_line_style_tl -\tl_const:Nn \c_@@_standard_tl { standard } -\tl_set_eq:NN \l_@@_xdots_line_style_tl \c_@@_standard_tl +\seq_new:N \g_@@_pos_of_stroken_blocks_seq +% \end{macrocode} +% +% +% \medskip +% The list of the names of the potential |\SubMatrix| in the |code-after| of an +% environment. Unfortunately, that list has to be global (we have to use it +% inside the group for the options of a given |\SubMatrix|). +% \begin{macrocode} +\seq_new:N \g_@@_submatrix_names_seq +% \end{macrocode} +% +% \medskip +% We are able to determine the number of columns specified in the preamble (for +% the environments with explicit preamble, of course and without the potential +% exterior columns). +% \begin{macrocode} +\int_new:N \g_@@_static_num_of_col_int +% \end{macrocode} +% +% \medskip +% The following token lists correspond to the keys |fill| and |draw| of +% a command |\Block|. +% \begin{macrocode} +\tl_new:N \l_@@_fill_tl +\tl_new:N \l_@@_draw_tl +% \end{macrocode} +% +% \medskip +% The following token list correspond to the key |color| of the command +% |\Block|. However, as of now (v. 5.7 of \pkg{nicematrix}), the key |color| +% linked to |fill| with an error. We will give to the key |color| of |\Block| +% its new meaning in a few months (with its new definition, the key |color| will +% draw the frame with the given color but also color the content of the block +% (that is to say the text) as does the key |color| of a Tikz node). +% \begin{macrocode} +\tl_new:N \l_@@_color_tl +% \end{macrocode} +% +% \medskip +% Here is the dimension for the width of the rule when a block (created by +% |\Block|) is stroked. +% \begin{macrocode} +\dim_new:N \l_@@_line_width_dim +% \end{macrocode} +% +% \medskip +% The parameter of position of the label of a block (|c|, |r| or |l|). +% \begin{macrocode} +\tl_new:N \l_@@_pos_of_block_tl +\tl_set:Nn \l_@@_pos_of_block_tl { c } +% \end{macrocode} +% +% \medskip +% Used when the key |draw-first| is used for |\Ddots| or |\Iddots|. +% \begin{macrocode} +\bool_new:N \l_@@_draw_first_bool +% \end{macrocode} +% +% \medskip +% The blocks which use the key |-| will store their content in a box. These +% boxes are numbered with the following counter. +% \begin{macrocode} +\int_new:N \g_@@_block_box_int % \end{macrocode} % % \bigskip @@ -3321,8 +5545,7 @@ version 2005/12/01 or later. % \item \textbf{First row}\par\nobreak % The integer |\l_@@_first_row_int| is the number of the first row of the % array. The default value is $1$, but, if the option |first-row| is used, -% the value will be~$0$. As usual, the global version is for the passage in the -% |\group_insert_after:N|. +% the value will be~$0$. % \begin{macrocode} \int_new:N \l_@@_first_row_int \int_set:Nn \l_@@_first_row_int 1 @@ -3340,7 +5563,7 @@ version 2005/12/01 or later. % % \medskip % \item \textbf{Last row}\par\nobreak -% The counter |\l_@@_last_row_int| is the number of the eventual ``last row'', +% The counter |\l_@@_last_row_int| is the number of the potential ``last row'', % as specified by the key |last-row|. A value of $-2$ means that there is no % ``last row''. A value of $-1$ means that there is a ``last row'' but we don't % know the number of that row (the key |last-row| has been used without value @@ -3370,12 +5593,13 @@ version 2005/12/01 or later. % \medskip % \item \textbf{Last column}\par\nobreak % -% For the eventual ``last column'', we use an integer. A value of $-2$ means -% that there is no last column. A value of $-1$ means that there is a last -% column but we don't know its value because the user has used the option -% |last-col| without value (it's possible in an environment without preamble -% like |{pNiceMatrix}|). A value of $0$ means that the option |last-col| has -% been used in an environment with preamble (like |{pNiceArray}|). +% For the potential ``last column'', we use an integer. A value of $-2$ means +% that there is no last column. A value of $-1$ means that we are in an +% environment without preamble (e.g. |{bNiceMatrix}|) and there is a last column +% but we don't know its value because the user has used the option |last-col| +% without value. A value of $0$ means that the option |last-col| has been used +% in an environment with preamble (like |{pNiceArray}|): in this case, the key +% was necessary without argument. % \begin{macrocode} \int_new:N \l_@@_last_col_int \int_set:Nn \l_@@_last_col_int { -2 } @@ -3384,7 +5608,7 @@ version 2005/12/01 or later. % However, we have also a boolean. Consider the following code: % \begin{center} % \begin{BVerbatim} -% \begin{pNiceArray}{CC}[last-col] +% \begin{pNiceArray}{cc}[last-col] % 1 & 2 \\ % 3 & 4 % \end{pNiceArray} @@ -3398,139 +5622,204 @@ version 2005/12/01 or later. % \end{macrocode} % This boolean is set to |false| at the end of |\@@_pre_array:|. % \end{itemize} -% +% % \bigskip -% \textbf{The column S of siunitx}\par\nobreak +% \subsection*{The command \textbackslash tabularnote} % -% \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}. +% \bigskip +% The LaTeX counter |tabularnote| will be used to count the tabular notes during +% the construction of the array (this counter won't be used during the +% composition of the notes at the end of the array). You use a LaTeX counter +% because we will use |\refstepcounter| in order to have the tabular notes +% referenceable. % \begin{macrocode} -\bool_new:N \c_@@_siunitx_loaded_bool -\AtBeginDocument - { - \@ifpackageloaded { siunitx } - { \bool_set_true:N \c_@@_siunitx_loaded_bool } - { } - } +\newcounter { tabularnote } % \end{macrocode} -% -% \medskip -% The command |\NC@rewrite@S| is a LaTeX command created by \pkg{siunitx} in -% connection with the |S| column. In the code of \pkg{siunitx}, this command is -% defined by: -% \begin{Verbatim}[commandchars=\~\!\+, formatcom = \small] -% \renewcommand*{\NC@rewrite@S}[1][] -% { -% \@temptokena \exp_after:wN -% { -% \tex_the:D \@temptokena -% > { \__siunitx_table_collect_begin: S {#1} } -% c -% < { \__siunitx_table_print: } -% } -% \NC@find -% } -% \end{Verbatim} -% We want to patch this command (in the environments of \pkg{nicematrix}) in -% order to have: -% \begin{Verbatim}[commandchars=\~\!\+, formatcom = \small] -% \renewcommand*{\NC@rewrite@S}[1][] -% { -% \@temptokena \exp_after:wN -% { -% \tex_the:D \@temptokena -% > { ~emphase!\@@_Cell:+ \__siunitx_table_collect_begin: S {#1} } -% c -% < { \__siunitx_table_print: ~emphase!\@@_end_Cell:+ } -% } -% \NC@find -% } -% \end{Verbatim} -% However, we don't want do use explicitly any private command of \pkg{siunitx}. -% That's why we will extract the name of the two |\__siunitx...| commands by -% their position in the code of |\NC@rewrite@S|. % -% Since the command |\NC@rewrite@S| appends some tokens to the \emph{toks} list -% |\@temptokena|, we use the LaTeX command |\NC@rewrite@S| in a group -% (|\group_begin:|--|\group_end:|) and we extract the two command names which -% are in the toks |\@temptokena|. However, this extraction can be done only -% 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 use of an -% environment of \pkg{nicematrix} with the command |\@@_adapt_S_column:|. +% \bigskip +% We will store in the following sequence the tabular notes of a given array. % \begin{macrocode} -\cs_set_protected:Npn \@@_adapt_S_column: - { - \bool_if:NT \c_@@_siunitx_loaded_bool - { - \group_begin: - \@temptokena = { } +\seq_new:N \g_@@_tabularnotes_seq % \end{macrocode} -% We protect |\NC@find| which is at the end of |\NC@rewrite@S|. +% +% \bigskip +% However, before the actual tabular notes, it's possible to put a text +% specified by the key |tabularnote| of the environment. The token list +% |\l_@@_tabularnote_tl| corresponds to the value of that key. % \begin{macrocode} - \cs_set_eq:NN \NC@find \prg_do_nothing: - \NC@rewrite@S { } +\tl_new:N \l_@@_tabularnote_tl % \end{macrocode} -% Conversion of the \emph{toks} |\@temptokena| in a token list of \pkg{expl3} -% (the toks are not supported by \pkg{expl3} but we can, nevertheless, use the -% option |V| for |\tl_gset:NV|). +% +% \bigskip +% The following counter will be used to count the number of successive tabular +% notes such as in +% |\tabularnote{Note 1}\tabularnote{Note 2}\tabularnote{Note 3}|. +% In the tabular, the labels of those nodes are composed as a comma +% separated list (e.g. \textsuperscript{\textit{a},\textit{b},\textit{c}}). % \begin{macrocode} - \tl_gset:NV \g_tmpa_tl \@temptokena - \group_end: - \tl_new:N \c_@@_table_collect_begin_tl - \tl_set:Nx \l_tmpa_tl { \tl_item:Nn \g_tmpa_tl 2 } - \tl_gset:Nx \c_@@_table_collect_begin_tl { \tl_item:Nn \l_tmpa_tl 1 } - \tl_new:N \c_@@_table_print_tl - \tl_gset:Nx \c_@@_table_print_tl { \tl_item:Nn \g_tmpa_tl { -1 } } +\int_new:N \l_@@_number_of_notes_int % \end{macrocode} -% The token lists |\c_@@_table_collect_begin_tl| and |\c_@@_table_print_tl| -% contain now the two commands of \pkg{siunitx}. % -% \smallskip -% If the adaptation has been done, the command |\@@_adapt_S_column:| becomes -% no-op (globally). +% \bigskip +% The following function can be redefined by using the key |notes/style|. % \begin{macrocode} - \cs_gset_eq:NN \@@_adapt_S_column: \prg_do_nothing: - } - } +\cs_new:Npn \@@_notes_style:n #1 { \textit { \alph { #1 } } } +% \end{macrocode} +% +% \bigskip +% The following fonction can be redefined by using the key +% |notes/label-in-tabular|. +% \begin{macrocode} +\cs_new:Npn \@@_notes_label_in_tabular:n #1 { \textsuperscript { #1 } } % \end{macrocode} % % \bigskip -% The command |\@@_renew_NC@rewrite@S:| will be used in each environment of -% \pkg{nicematrix} in order to ``rewrite'' the |S| column in each environment -% (only if the boolean |\c_@@_siunitx_loaded_bool| is raised, of course). +% The following function can be redefined by using the key |notes/label-in-list|. +% \begin{macrocode} +\cs_new:Npn \@@_notes_label_in_list:n #1 { \textsuperscript { #1 } } +% \end{macrocode} +% +% \bigskip +% We define |\thetabularnote| because it will be used by LaTeX if the user want +% to reference a footnote which has been marked by a |\label|. The TeX group is +% for the case where the user has put an instruction such as |\color{red}| in +% |\@@_notes_style:n|. +% \begin{macrocode} +\cs_set:Npn \thetabularnote { { \@@_notes_style:n { tabularnote } } } +% \end{macrocode} +% +% \bigskip +% The tabular notes will be available for the final user only when +% \pkg{enumitem} is loaded. Indeed, the tabular notes will be composed at the end +% of the array with a list customized by \pkg{enumitem} (a list |tabularnotes| +% in the general case and a list |tabularnotes*| if the key |para| is in force). +% However, we can test whether \pkg{enumitem} has been loaded only at the +% beginning of the document (we want to allow the user to load \pkg{enumitem} +% after \pkg{nicematrix}). % \begin{macrocode} -\cs_new_protected:Npn \@@_renew_NC@rewrite@S: +\AtBeginDocument { - \renewcommand*{\NC@rewrite@S}[1][] - { - \@temptokena \exp_after:wN + \bool_if:nTF { ! \c_@@_enumitem_loaded_bool } + { + \NewDocumentCommand \tabularnote { m } + { \@@_error:n { enumitem~not~loaded } } + } + { +% \end{macrocode} +% The type of list |tabularnotes| will be used to format the tabular notes at +% the end of the array in the general case and |tabularnotes*| will be used if +% the key |para| is in force. +% \begin{macrocode} + \newlist { tabularnotes } { enumerate } { 1 } + \setlist [ tabularnotes ] { - \tex_the:D \@temptokena - > { \@@_Cell: \c_@@_table_collect_begin_tl S {##1} } - c - < { \c_@@_table_print_tl \@@_end_Cell: } + topsep = 0pt , + noitemsep , + leftmargin = * , + align = left , + labelsep = 0pt , + label = + \@@_notes_label_in_list:n { \@@_notes_style:n { tabularnotesi } } , + } + \newlist { tabularnotes* } { enumerate* } { 1 } + \setlist [ tabularnotes* ] + { + afterlabel = \nobreak , + itemjoin = \quad , + label = + \@@_notes_label_in_list:n { \@@_notes_style:n { tabularnotes*i } } } - \NC@find - } - } % \end{macrocode} % -% \bigskip -% The following command is only for efficiency. It must \emph{not} be protected -% because it will be used (for instance) in names of \textsc{pgf} nodes. +% \medskip +% The command |\tabularnote| is available in the whole document (and not only in +% the environments of \pkg{nicematrix}) because we want it to be available in +% the caption of a |{table}| (before the following |{NiceTabular}| or +% |{NiceArray}|). That's also the reason why the variables |\c@tabularnote| and +% |\g_@@_tabularnotes_seq| will be cleared at the end of the environment of +% \pkg{nicematrix} (and not at the beginning). +% +% Unfortunately, if the package \pkg{caption} is loaded, the command |\caption| +% evaluates its argument twice and since it is not aware (of course) of +% |\tabularnote|, the command |\tabularnote| is, in fact, not usable in +% |\caption| when \pkg{caption} is loaded.\footnote{We should try to find a +% solution to that problem.} % \begin{macrocode} -\cs_new:Npn \@@_succ:n #1 { \the \numexpr #1 + 1 \relax } -\cs_new:Npn \@@_pred:n #1 { \the \numexpr #1 - 1 \relax } + \NewDocumentCommand \tabularnote { m } + { + \bool_if:nTF { ! \l_@@_NiceArray_bool && \l_@@_in_env_bool } + { \@@_error:n { tabularnote~forbidden } } + { +% \end{macrocode} +% |\l_@@_number_of_notes_int| is used to count the number of successive tabular +% notes such as in +% |\tabularnote{Note 1}\tabularnote{Note 2}\tabularnote{Note 3}|. +% We will have to compose the labels of theses notes as a comma separated list +% (e.g. \textsuperscript{\emph{a},\emph{b},\emph{c}}). +% \begin{macrocode} + \int_incr:N \l_@@_number_of_notes_int +% \end{macrocode} +% We expand the content of the note at the point of use of +% |\tabularnote| as does |\footnote|. +% \begin{macrocode} + \seq_gput_right:Nn \g_@@_tabularnotes_seq { #1 } + \peek_meaning:NF \tabularnote + { +% \end{macrocode} +% If the following token is \emph{not} a |\tabularnote|, we have finished the +% sequence of successive commands |\tabularnote| and we have to format the +% labels of these tabular notes (in the array). We compose those labels in a box +% |\l_tmpa_box| because we will do a special construction in order to have this +% box in a overlapping position if we are at the end of a cell. +% \begin{macrocode} + \hbox_set:Nn \l_tmpa_box + { +% \end{macrocode} +% We remind that it is the command |\@@_notes_label_in_tabular:n| that will +% (most of the time) put the labels in a |\textsuperscript|. +% \begin{macrocode} + \@@_notes_label_in_tabular:n + { + \stepcounter { tabularnote } + \@@_notes_style:n { tabularnote } + \prg_replicate:nn { \l_@@_number_of_notes_int - 1 } + { + , + \stepcounter { tabularnote } + \@@_notes_style:n { tabularnote } + } + } + } +% \end{macrocode} +% We use |\refstepcounter| in order to have the (last) tabular note referenceable +% (with the standard command |\label|) and that's why we have to go back with a +% decrementation of the counter |tabularnote| first. +% \begin{macrocode} + \addtocounter { tabularnote } { -1 } + \refstepcounter { tabularnote } + \int_zero:N \l_@@_number_of_notes_int + \hbox_overlap_right:n { \box_use:N \l_tmpa_box } % \end{macrocode} +% If the command |\tabularnote| is used exactly at the end of the cell, the +% |\unskip| (inserted by \pkg{array}?) will delete the skip we insert now +% and the label of the footnote will be composed in an overlapping position (by +% design). +% \begin{macrocode} + \skip_horizontal:n { \box_wd:N \l_tmpa_box } + } + } + } + } + } +% \end{macrocode} +% +% % % \subsection*{Command for creation of rectangle nodes} % % -% The following command should be used in a |{pgfpicture}|. It creates an -% rectangular (empty but with a name) when the four corners are given. +% The following command should be used in a |{pgfpicture}|. It creates a +% rectangle (empty but with a name). % % |#1| is the name of the node which will be created; % |#2| and |#3| are the coordinates of one of the corner of the rectangle; @@ -3598,21 +5887,91 @@ version 2005/12/01 or later. % \bigskip % \subsection*{The options} % +% By default, the commands |\cellcolor| and |\rowcolor| are available for the +% user in the cells of the tabular (the user may use the commands provided by +% |\colortbl|). However, if the key |colortbl-like| is used, these +% commands are available. +% \begin{macrocode} +\bool_new:N \l_@@_colortbl_like_bool +% \end{macrocode} +% +% \bigskip +% By default, the behaviour of |\cline| is changed in the environments of +% \pkg{nicematrix}: a |\cline| spreads the array by an amount equal to +% |\arrayrulewidht|. It's possible to disable this feature with the key +% |\l_@@_standard_line_bool|. +% \begin{macrocode} +\bool_new:N \l_@@_standard_cline_bool +% \end{macrocode} +% +% \bigskip +% The following dimensions correspond to the options |cell-space-top-limit| and co +% (these parameters are inspired by the package \pkg{cellspace}). +% \begin{macrocode} +\dim_new:N \l_@@_cell_space_top_limit_dim +\dim_new:N \l_@@_cell_space_bottom_limit_dim +% \end{macrocode} +% +% \bigskip +% The following dimension is the distance between two dots for the dotted lines +% (when |line-style| is equal to |standard|, which is the initial value). The +% initial value is 0.45~em but it will be changed if the option |small| is used. +% \begin{macrocode} +\dim_new:N \l_@@_inter_dots_dim +\AtBeginDocument { \dim_set:Nn \l_@@_inter_dots_dim { 0.45 em } } +% \end{macrocode} +% The |\AtBeginDocument| is only a security in case \cls{revtex4-1} is used +% (even though it is obsolete). +% +% \bigskip +% The following dimension is the minimal distance between a node (in fact an +% anchor of that node) and a dotted line (we say ``minimal'' because, by +% definition, a dotted line is not a continuous line and, therefore, this +% distance may vary a little). +% \begin{macrocode} +\dim_new:N \l_@@_xdots_shorten_dim +\AtBeginDocument { \dim_set:Nn \l_@@_xdots_shorten_dim { 0.3 em } } +% \end{macrocode} +% The |\AtBeginDocument| is only a security in case \cls{revtex4-1} is used +% (even though it is obsolete). +% +% \bigskip +% The following dimension is the radius of the dots for the dotted lines (when +% |line-style| is equal to |standard|, which is the initial value). The initial +% value is 0.53~pt but it will be changed if the option |small| is used. +% \begin{macrocode} +\dim_new:N \l_@@_radius_dim +\AtBeginDocument { \dim_set:Nn \l_@@_radius_dim { 0.53 pt } } +% \end{macrocode} +% The |\AtBeginDocument| is only a security in case \cls{revtex4-1} is used +% (even if it is obsolete). +% +% +% \bigskip +% The token list |\l_@@_xdots_line_style_tl| corresponds to the option |tikz| of the +% commands |\Cdots|, |\Ldots|, etc. and of the options |line-style| for the +% environments and |\NiceMatrixOptions|. The constant |\c_@@_standard_tl| will +% be used in some tests. +% \begin{macrocode} +\tl_new:N \l_@@_xdots_line_style_tl +\tl_const:Nn \c_@@_standard_tl { standard } +\tl_set_eq:NN \l_@@_xdots_line_style_tl \c_@@_standard_tl +% \end{macrocode} +% +% \bigskip % The boolean |\l_@@_light_syntax_bool| corresponds to the option |light-syntax|. % \begin{macrocode} \bool_new:N \l_@@_light_syntax_bool % \end{macrocode} % % \bigskip -% 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. +% The string |\l_@@_baseline_tl| may contain one of the three values |t|, +% |c| or |b| as in the option of the environment |{array}|. However, it may also +% contain an integer (which represents the number of the row to which align the +% array). % \begin{macrocode} -\str_new:N \l_@@_baseline_str -\str_set:Nn \l_@@_baseline_str c +\tl_new:N \l_@@_baseline_tl +\tl_set:Nn \l_@@_baseline_tl c % \end{macrocode} % % \bigskip @@ -3633,12 +5992,36 @@ version 2005/12/01 or later. % \end{macrocode} % % \bigskip -% The flag |\l_@@_hlines_bool| corresponds to the option |\hlines| and the flag -% |\l_@@_vlines_bool| to the option |\vlines|. +% If the flag |\l_@@_vlines_bool| is raised, horizontal space will be reserved +% in the the preamble of the array (for the vertical rules) and, after the +% construction of the array, the vertical rules will be drawn. % \begin{macrocode} -\bool_new:N \l_@@_hlines_bool \bool_new:N \l_@@_vlines_bool % \end{macrocode} +% +% \bigskip +% If the flag |\l_@@_hlines_bool| is raised, vertical space will be reserved +% between the rows of the array (for the horizontal rules) and, after the +% construction of the array, the vertical rules will be drawn. +% \begin{macrocode} +\bool_new:N \l_@@_hlines_bool +% \end{macrocode} +% +% \bigskip +% The flag |\l_@@_except_corners_bool| will be raised when the key +% |except-corners| will be used. In that case, the corners will be computed +% before we draw rules and the rules won't be drawn in the corners. As expected, +% the key |hvlines-except-corners| raises the key |except-corners|. +% \begin{macrocode} +\clist_new:N \l_@@_except_corners_clist +% \end{macrocode} +% +% \begin{macrocode} +\dim_new:N \l_@@_notes_above_space_dim +\AtBeginDocument { \dim_set:Nn \l_@@_notes_above_space_dim { 1 mm } } +% \end{macrocode} +% The |\AtBeginDocument| is only a security in case \cls{revtex4-1} is used +% (even if it is obsolete). % % \bigskip % The flag |\l_@@_nullify_dots_bool| corresponds to the option |nullify-dots|. @@ -3661,7 +6044,7 @@ version 2005/12/01 or later. % % % \bigskip -% The token list |\l_@@_name_str| will contain the optional name of the +% The string |\l_@@_name_str| will contain the optional name of the % environment: this name can be used to access to the Tikz nodes created in the % array from outside the environment. % \begin{macrocode} @@ -3686,13 +6069,6 @@ version 2005/12/01 or later. \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} % % \bigskip % The dimensions |\l_@@_extra_left_margin_dim| and @@ -3720,7 +6096,13 @@ version 2005/12/01 or later. \tl_new:N \l_@@_xdots_color_tl % \end{macrocode} % -% \medskip +% \bigskip +% The following token list corresponds to the key |delimiters-color|. +% \begin{macrocode} +\tl_new:N \l_@@_delimiters_color_tl +% \end{macrocode} +% +% \bigskip % 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 @@ -3736,42 +6118,84 @@ version 2005/12/01 or later. % \end{macrocode} % % \bigskip -% First, we define a set of keys ``|NiceMatrix / Global|'' which will be used -% (with the mechanism of |.inherit:n|) by other sets of keys. % \begin{macrocode} \keys_define:nn { NiceMatrix / xdots } { line-style .code:n = - { - \bool_lazy_or:nnTF + { + \bool_lazy_or:nnTF % \end{macrocode} % We can't use |\c_@@_tikz_loaded_bool| to test whether \pkg{tikz} is loaded % because |\NiceMatrixOptions| may be used in the preamble of the document. % \begin{macrocode} - { \cs_if_exist_p:N \tikzpicture } - { \str_if_eq_p:nn { #1 } { standard } } - { \tl_set:Nn \l_@@_xdots_line_style_tl { #1 } } - { \@@_error:n { bad~option~for~line-style } } - } , + { \cs_if_exist_p:N \tikzpicture } + { \str_if_eq_p:nn { #1 } { standard } } + { \tl_set:Nn \l_@@_xdots_line_style_tl { #1 } } + { \@@_error:n { bad~option~for~line-style } } + } , line-style .value_required:n = true , color .tl_set:N = \l_@@_xdots_color_tl , color .value_required:n = true , shorten .dim_set:N = \l_@@_xdots_shorten_dim , shorten .value_required:n = true , +% \end{macrocode} +% The options |down| and |up| are not documented for the final user because he +% should use the syntax with |^| and |_|. +% \begin{macrocode} + down .tl_set:N = \l_@@_xdots_down_tl , + up .tl_set:N = \l_@@_xdots_up_tl , +% \end{macrocode} +% The key |draw-first|, which is meant to be used only with |\Ddots| and +% |\Iddots|, which be catched when |\Ddots| or |\Iddots| is used (during the +% construction of the array and not when we draw the dotted lines). +% \begin{macrocode} + draw-first .code:n = \prg_do_nothing: , unknown .code:n = \@@_error:n { Unknown~option~for~xdots } } % \end{macrocode} % -% +% +% \bigskip +% \begin{macrocode} +\keys_define:nn { NiceMatrix / rules } + { + color .tl_set:N = \l_@@_rules_color_tl , + color .value_required:n = true , + width .dim_set:N = \arrayrulewidth , + width .value_required:n = true + } +% \end{macrocode} +% +% +% \bigskip +% First, we define a set of keys ``|NiceMatrix / Global|'' which will be used +% (with the mechanism of |.inherit:n|) by other sets of keys. +% % \begin{macrocode} \keys_define:nn { NiceMatrix / Global } { + standard-cline .bool_set:N = \l_@@_standard_cline_bool , + standard-cline .default:n = true , + cell-space-top-limit .dim_set:N = \l_@@_cell_space_top_limit_dim , + cell-space-top-limit .value_required:n = true , + cell-space-bottom-limit .dim_set:N = \l_@@_cell_space_bottom_limit_dim , + cell-space-bottom-limit .value_required:n = true , + cell-space-limits .meta:n = + { + cell-space-top-limit = #1 , + cell-space-bottom-limit = #1 , + } , + cell-spaces-limits .value_required:n = true , xdots .code:n = \keys_set:nn { NiceMatrix / xdots } { #1 } , max-delimiter-width .bool_set:N = \l_@@_max_delimiter_width_bool , light-syntax .bool_set:N = \l_@@_light_syntax_bool , light-syntax .default:n = true , end-of-row .tl_set:N = \l_@@_end_of_row_tl , end-of-row .value_required:n = true , + first-col .code:n = \int_zero:N \l_@@_first_col_int , + first-row .code:n = \int_zero:N \l_@@_first_row_int , + last-row .int_set:N = \l_@@_last_row_int , + last-row .default:n = -1 , code-for-first-col .tl_set:N = \l_@@_code_for_first_col_tl , code-for-first-col .value_required:n = true , code-for-last-col .tl_set:N = \l_@@_code_for_last_col_tl , @@ -3780,27 +6204,24 @@ version 2005/12/01 or later. code-for-first-row .value_required:n = true , code-for-last-row .tl_set:N = \l_@@_code_for_last_row_tl , 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 } , + hvlines .code:n = + { + \bool_set_true:N \l_@@_vlines_bool + \bool_set_true:N \l_@@_hlines_bool + } , parallelize-diags .bool_set:N = \l_@@_parallelize_diags_bool , % \end{macrocode} % % \bigskip -% With the option |renew-dots|, the command |\cdots|, |\ldots|, |\vdots| and -% |\ddots| are redefined and behave like the commands |\Cdots|, |\Ldots|, -% |\Vdots| and |\Ddots|. +% With the option |renew-dots|, the command |\cdots|, |\ldots|, |\vdots|, +% |\ddots|, etc. are redefined and behave like the commands |\Cdots|, |\Ldots|, +% |\Vdots|, |\Ddots|, etc. % \begin{macrocode} renew-dots .bool_set:N = \l_@@_renew_dots_bool , renew-dots .value_forbidden:n = true , nullify-dots .bool_set:N = \l_@@_nullify_dots_bool , -% \end{macrocode} -% -% \bigskip -% In some circonstancies, the ``medium nodes'' are created automatically, for -% example when a dotted line has an ``open'' extremity (idem for the ``large nodes''). -% \begin{macrocode} create-medium-nodes .bool_set:N = \l_@@_medium_nodes_bool , create-large-nodes .bool_set:N = \l_@@_large_nodes_bool , create-extra-nodes .meta:n = @@ -3815,7 +6236,7 @@ version 2005/12/01 or later. extra-right-margin .dim_set:N = \l_@@_extra_right_margin_dim , extra-margin .meta:n = { extra-left-margin = #1 , extra-right-margin = #1 } , - extra-margin .value_required:n = true + extra-margin .value_required:n = true , } % \end{macrocode} % @@ -3823,10 +6244,37 @@ version 2005/12/01 or later. % We define a set of keys used by the environments of \pkg{nicematrix} (but not % by the command |\NiceMatrixOptions|). % \begin{macrocode} -\keys_define:nn { NiceMatrix / Env } - { +\keys_define:nn { NiceMatrix / Env } + { + except-corners .clist_set:N = \l_@@_except_corners_clist , + except-corners .default:n = { NW , SW , NE , SE } , + hvlines-except-corners .code:n = + { + \clist_set:Nn \l_@@_except_corners_clist { #1 } + \bool_set_true:N \l_@@_vlines_bool + \bool_set_true:N \l_@@_hlines_bool + } , + hvlines-except-corners .default:n = { NW , SW , NE , SE } , + code-before .code:n = + { + \tl_if_empty:nF { #1 } + { + \tl_put_right:Nn \l_@@_code_before_tl { #1 } + \bool_set_true:N \l_@@_code_before_bool + } + } , +% \end{macrocode} +% \bigskip +% 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 = \tl_set:Nn \l_@@_baseline_tl c , + t .code:n = \tl_set:Nn \l_@@_baseline_tl t , + b .code:n = \tl_set:Nn \l_@@_baseline_tl b , + baseline .tl_set:N = \l_@@_baseline_tl , + baseline .value_required:n = true , columns-width .code:n = - \str_if_eq:nnTF { #1 } { auto } + \tl_if_eq:nnTF { #1 } { auto } { \bool_set_true:N \l_@@_auto_columns_width_bool } { \dim_set:Nn \l_@@_columns_width_dim { #1 } } , columns-width .value_required:n = true , @@ -3834,7 +6282,7 @@ version 2005/12/01 or later. % \end{macrocode} % We test whether we are in the measuring phase of an environment of % \pkg{amsmath} (always loaded by \pkg{nicematrix}) because we want to avoid a -% fallaicous message of duplicate name in this case. +% fallacious message of duplicate name in this case. % \begin{macrocode} \legacy_if:nF { measuring@ } { @@ -3845,16 +6293,70 @@ version 2005/12/01 or later. \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 .tl_gset:N = \g_nicematrix_code_after_tl , code-after .value_required:n = true , - first-col .code:n = \int_zero:N \l_@@_first_col_int , - first-row .code:n = \int_zero:N \l_@@_first_row_int , - last-row .int_set:N = \l_@@_last_row_int , - last-row .default:n = -1 , + colortbl-like .code:n = + \bool_set_true:N \l_@@_colortbl_like_bool + \bool_set_true:N \l_@@_code_before_bool , + colortbl-like .value_forbidden:n = true } % \end{macrocode} % -% +% \begin{macrocode} +\keys_define:nn { NiceMatrix / notes } + { + para .bool_set:N = \l_@@_notes_para_bool , + para .default:n = true , + code-before .tl_set:N = \l_@@_notes_code_before_tl , + code-before .value_required:n = true , + code-after .tl_set:N = \l_@@_notes_code_after_tl , + code-after .value_required:n = true , + bottomrule .bool_set:N = \l_@@_notes_bottomrule_bool , + bottomrule .default:n = true , + style .code:n = \cs_set:Nn \@@_notes_style:n { #1 } , + style .value_required:n = true , + label-in-tabular .code:n = + \cs_set:Nn \@@_notes_label_in_tabular:n { #1 } , + label-in-tabular .value_required:n = true , + label-in-list .code:n = + \cs_set:Nn \@@_notes_label_in_list:n { #1 } , + label-in-list .value_required:n = true , + enumitem-keys .code:n = + { + \bool_if:NTF \c_@@_in_preamble_bool + { + \AtBeginDocument + { + \bool_if:NT \c_@@_enumitem_loaded_bool + { \setlist* [ tabularnotes ] { #1 } } + } + } + { + \bool_if:NT \c_@@_enumitem_loaded_bool + { \setlist* [ tabularnotes ] { #1 } } + } + } , + enumitem-keys .value_required:n = true , + enumitem-keys-para .code:n = + { + \bool_if:NTF \c_@@_in_preamble_bool + { + \AtBeginDocument + { + \bool_if:NT \c_@@_enumitem_loaded_bool + { \setlist* [ tabularnotes* ] { #1 } } + } + } + { + \bool_if:NT \c_@@_enumitem_loaded_bool + { \setlist* [ tabularnotes* ] { #1 } } + } + } , + enumitem-keys-para .value_required:n = true , + unknown .code:n = \@@_error:n { Unknown~key~for~notes } + } +% \end{macrocode} +% % \bigskip % We begin the construction of the major sets of keys (used by the different % user commands and environments). @@ -3862,28 +6364,40 @@ version 2005/12/01 or later. \keys_define:nn { NiceMatrix } { NiceMatrixOptions .inherit:n = - { - NiceMatrix / Global , - } , + { NiceMatrix / Global } , NiceMatrixOptions / xdots .inherit:n = NiceMatrix / xdots , + NiceMatrixOptions / rules .inherit:n = NiceMatrix / rules , + NiceMatrixOptions / notes .inherit:n = NiceMatrix / notes , + NiceMatrixOptions / sub-matrix .inherit:n = NiceMatrix / sub-matrix , + CodeAfter / xdots .inherit:n = NiceMatrix / xdots , NiceMatrix .inherit:n = { NiceMatrix / Global , NiceMatrix / Env , } , NiceMatrix / xdots .inherit:n = NiceMatrix / xdots , + NiceMatrix / rules .inherit:n = NiceMatrix / rules , + NiceTabular .inherit:n = + { + NiceMatrix / Global , + NiceMatrix / Env + } , + NiceTabular / xdots .inherit:n = NiceMatrix / xdots , + NiceTabular / rules .inherit:n = NiceMatrix / rules , NiceArray .inherit:n = { NiceMatrix / Global , NiceMatrix / Env , } , NiceArray / xdots .inherit:n = NiceMatrix / xdots , + NiceArray / rules .inherit:n = NiceMatrix / rules , pNiceArray .inherit:n = { NiceMatrix / Global , NiceMatrix / Env , } , - pNiceArray / xdots .inherit:n = NiceMatrix / xdots + pNiceArray / xdots .inherit:n = NiceMatrix / xdots , + pNiceArray / rules .inherit:n = NiceMatrix / rules , } % \end{macrocode} % @@ -3895,6 +6409,13 @@ version 2005/12/01 or later. % \begin{macrocode} \keys_define:nn { NiceMatrix / NiceMatrixOptions } { + delimiters-color .tl_set:N = \l_@@_delimiters_color_tl , + delimiters-color .value_required:n = true , + last-col .code:n = \tl_if_empty:nF { #1 } + { \@@_error:n { last-col~non~empty~for~NiceMatrixOptions } } + \int_zero:N \l_@@_last_col_int , + small .bool_set:N = \l_@@_small_bool , + small .value_forbidden:n = true , % \end{macrocode} % % With the option |renew-matrix|, the environment |{matrix}| of \pkg{amsmath} @@ -3903,7 +6424,15 @@ version 2005/12/01 or later. % \begin{macrocode} renew-matrix .code:n = \@@_renew_matrix: , renew-matrix .value_forbidden:n = true , - transparent .meta:n = { renew-dots , renew-matrix } , +% \end{macrocode} +% The key |transparent| is now considered as obsolete (because its name is ambiguous). +% \begin{macrocode} + transparent .code:n = + { + \@@_renew_matrix: + \bool_set_true:N \l_@@_renew_dots_bool + \@@_error:n { Key~transparent } + } , transparent .value_forbidden:n = true, % \end{macrocode} % @@ -3922,13 +6451,13 @@ version 2005/12/01 or later. % In |\NiceMatrixOptions|, the special value |auto| is not available. % \begin{macrocode} columns-width .code:n = - \str_if_eq:nnTF { #1 } { auto } + \tl_if_eq:nnTF { #1 } { auto } { \@@_error:n { Option~auto~for~columns-width } } { \dim_set:Nn \l_@@_columns_width_dim { #1 } } , % \end{macrocode} % % \bigskip -% Usually, an error is raised when the user tries to give the same to name two +% Usually, an error is raised when the user tries to give the same name to two % distincts environments of \pkg{nicematrix} (theses names are global and not % local to the current TeX scope). However, the option |allow-duplicate-names| % disables this feature. @@ -3947,15 +6476,21 @@ version 2005/12/01 or later. % \begin{macrocode} letter-for-dotted-lines .code:n = { - \int_compare:nTF { \tl_count:n { #1 } = 1 } + \tl_if_single_token:nTF { #1 } { \str_set:Nx \l_@@_letter_for_dotted_lines_str { #1 } } { \@@_error:n { Bad~value~for~letter~for~dotted~lines } } } , letter-for-dotted-lines .value_required:n = true , + notes .code:n = \keys_set:nn { NiceMatrix / notes } { #1 } , + notes .value_required:n = true , + sub-matrix .code:n = + \keys_set:nn { NiceMatrix / sub-matrix } { #1 } , + sub-matrix .value_required:n = true , unknown .code:n = \@@_error:n { Unknown~key~for~NiceMatrixOptions } } % \end{macrocode} % +% % \begin{macrocode} \str_new:N \l_@@_letter_for_dotted_lines_str \str_set_eq:NN \l_@@_letter_for_dotted_lines_str \c_colon_str @@ -3984,10 +6519,12 @@ version 2005/12/01 or later. \int_set:Nn \l_@@_last_col_int { -1 } } { \int_set:Nn \l_@@_last_col_int { #1 } } , - l .code:n = \tl_set:Nn \l_@@_type_of_col_tl L , - r .code:n = \tl_set:Nn \l_@@_type_of_col_tl R , - L .code:n = \tl_set:Nn \l_@@_type_of_col_tl L , - R .code:n = \tl_set:Nn \l_@@_type_of_col_tl R , + l .code:n = \tl_set:Nn \l_@@_type_of_col_tl l , + r .code:n = \tl_set:Nn \l_@@_type_of_col_tl r , + small .bool_set:N = \l_@@_small_bool , + small .value_forbidden:n = true , + delimiters-color .tl_set:N = \l_@@_delimiters_color_tl , + delimiters-color .value_required:n = true , unknown .code:n = \@@_error:n { Unknown~option~for~NiceMatrix } } % \end{macrocode} @@ -4003,24 +6540,23 @@ version 2005/12/01 or later. { % \end{macrocode} % -% \bigskip -% 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_@@_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 -% be used without value because the number of columns of the array can be read -% in the preamble of the array. +% be used without value because the number of columns of the array is read +% from the preamble of the array. % \begin{macrocode} + small .bool_set:N = \l_@@_small_bool , + small .value_forbidden:n = true , last-col .code:n = \tl_if_empty:nF { #1 } { \@@_error:n { last-col~non~empty~for~NiceArray } } \int_zero:N \l_@@_last_col_int , + notes / para .bool_set:N = \l_@@_notes_para_bool , + notes / para .default:n = true , + notes / bottomrule .bool_set:N = \l_@@_notes_bottomrule_bool , + notes / bottomrule .default:n = true , + tabularnote .tl_set:N = \l_@@_tabularnote_tl , + tabularnote .value_required:n = true , + delimiters-color .tl_set:N = \l_@@_delimiters_color_tl , + delimiters-color .value_required:n = true , unknown .code:n = \@@_error:n { Unknown~option~for~NiceArray } } % \end{macrocode} @@ -4035,13 +6571,32 @@ version 2005/12/01 or later. { \@@_error:n { last-col~non~empty~for~NiceArray } } \int_zero:N \l_@@_last_col_int , first-row .code:n = \int_zero:N \l_@@_first_row_int , - last-row .int_set:N = \l_@@_last_row_int , - last-row .default:n = -1 , + small .bool_set:N = \l_@@_small_bool , + small .value_forbidden:n = true , unknown .code:n = \@@_error:n { Unknown~option~for~NiceMatrix } } % \end{macrocode} % +% \bigskip +% We finalise the definition of the set of keys ``|NiceMatrix / NiceTabular|'' +% with the options specific to |{NiceTabular}|. % +% \begin{macrocode} +\keys_define:nn { NiceMatrix / NiceTabular } + { + notes / para .bool_set:N = \l_@@_notes_para_bool , + notes / para .default:n = true , + notes / bottomrule .bool_set:N = \l_@@_notes_bottomrule_bool , + notes / bottomrule .default:n = true , + tabularnote .tl_set:N = \l_@@_tabularnote_tl , + tabularnote .value_required:n = true , + last-col .code:n = \tl_if_empty:nF {#1} + { \@@_error:n { last-col~non~empty~for~NiceArray } } + \int_zero:N \l_@@_last_col_int , + unknown .code:n = \@@_error:n { Unknown~option~for~NiceTabular } + } +% \end{macrocode} +% % \bigskip % \subsection*{Important code used by \{NiceArrayWithDelims\} } % @@ -4054,6 +6609,12 @@ version 2005/12/01 or later. \cs_new_protected:Npn \@@_Cell: { % \end{macrocode} +% At the beginning of the cell, we link |\CodeAfter| to a command which do +% \emph{not} begin with |\omit| (whereas the standard version of |\CodeAfter| +% begins with |\omit|). +% \begin{macrocode} + \cs_set_eq:NN \CodeAfter \@@_CodeAfter_i:n +% \end{macrocode} % We increment |\c@jCol|, which is the counter of the columns. % \begin{macrocode} \int_gincr:N \c@jCol @@ -4068,12 +6629,15 @@ version 2005/12/01 or later. % \end{macrocode} % The content of the cell is composed in the box |\l_@@_cell_box| because we want % to compute some dimensions of the box. The |\hbox_set_end:| corresponding to -% this |\hbox_set:Nw| will be in the |\@@_end_Cell:| (and the +% this |\hbox_set:Nw| will be in the |\@@_end_Cell:| (and the potential % |\c_math_toggle_token| also). % \begin{macrocode} \hbox_set:Nw \l_@@_cell_box - \c_math_toggle_token - \bool_if:NT \l_@@_small_bool \scriptstyle + \bool_if:NF \l_@@_NiceTabular_bool + { + \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 @@ -4116,12 +6680,12 @@ version 2005/12/01 or later. \pgfrememberpicturepositiononpagetrue \pgfcoordinate { \@@_env: - row - \int_use:N \c@iRow - base } - \pgfpointorigin + { \pgfpoint \c_zero_dim { 0.5 \arrayrulewidth } } \str_if_empty:NF \l_@@_name_str { \pgfnodealias - { \@@_env: - row - \int_use:N \c@iRow - base } { \l_@@_name_str - row - \int_use:N \c@iRow - base } + { \@@_env: - row - \int_use:N \c@iRow - base } } \endpgfpicture } @@ -4132,7 +6696,7 @@ version 2005/12/01 or later. % 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. If the user uses the -% |last-row|, some lines will be dynamically added to this command. +% |last-row|, some lines of code will be dynamically added to this command. % \begin{macrocode} \cs_new_protected:Npn \@@_update_for_first_and_last_row: { @@ -4153,18 +6717,66 @@ version 2005/12/01 or later. } % \end{macrocode} % +% \begin{macrocode} +\cs_new_protected:Npn \@@_rotate_cell_box: + { + \box_rotate:Nn \l_@@_cell_box { 90 } + \int_compare:nNnT \c@iRow = \l_@@_last_row_int + { + \vbox_set_top:Nn \l_@@_cell_box + { + \vbox_to_zero:n { } + \skip_vertical:n { - \box_ht:N \@arstrutbox + 0.8 ex } + \box_use:N \l_@@_cell_box + } + } + \bool_gset_false:N \g_@@_rotate_bool + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_adjust_size_box: + { + \dim_compare:nNnT \g_@@_blocks_wd_dim > \c_zero_dim + { + \box_set_wd:Nn \l_@@_cell_box + { \dim_max:nn { \box_wd:N \l_@@_cell_box } \g_@@_blocks_wd_dim } + \dim_gzero:N \g_@@_blocks_wd_dim + } + \dim_compare:nNnT \g_@@_blocks_dp_dim > \c_zero_dim + { + \box_set_dp:Nn \l_@@_cell_box + { \dim_max:nn { \box_dp:N \l_@@_cell_box } \g_@@_blocks_dp_dim } + \dim_gzero:N \g_@@_blocks_dp_dim + } + \dim_compare:nNnT \g_@@_blocks_ht_dim > \c_zero_dim + { + \box_set_ht:Nn \l_@@_cell_box + { \dim_max:nn { \box_ht:N \l_@@_cell_box } \g_@@_blocks_ht_dim } + \dim_gzero:N \g_@@_blocks_ht_dim + } + } +% \end{macrocode} % % \begin{macrocode} \cs_new_protected:Npn \@@_end_Cell: { - \c_math_toggle_token + \@@_math_toggle_token: \hbox_set_end: + \bool_if:NT \g_@@_rotate_bool \@@_rotate_cell_box: + \@@_adjust_size_box: +% \end{macrocode} +% +% \begin{macrocode} + \box_set_ht:Nn \l_@@_cell_box + { \box_ht:N \l_@@_cell_box + \l_@@_cell_space_top_limit_dim } + \box_set_dp:Nn \l_@@_cell_box + { \box_dp:N \l_@@_cell_box + \l_@@_cell_space_bottom_limit_dim } % \end{macrocode} % % We want to compute in |\g_@@_max_cell_width_dim| the width of the widest cell % of the array (except the cells of the ``first column'' and the ``last % column''). -% % \begin{macrocode} \dim_gset:Nn \g_@@_max_cell_width_dim { \dim_max:nn \g_@@_max_cell_width_dim { \box_wd:N \l_@@_cell_box } } @@ -4188,7 +6800,7 @@ version 2005/12/01 or later. % \begin{itemize} % \item if the width of the box |\l_@@_cell_box| (created with the content of % the cell) is equal to zero, we consider the cell as empty (however, -% this is not perfect since the user may have use a |\rlap|, a |\llap| or a +% this is not perfect since the user may have used a |\rlap|, a |\llap| or a % |\mathclap| of \pkg{mathtools}. % \item the cells with a command |\Ldots| or |\Cdots|, |\Vdots|, etc., % should also be considered as empty; if |nullify-dots| is in force, there would @@ -4200,16 +6812,16 @@ version 2005/12/01 or later. % \end{itemize} % \begin{macrocode} \bool_if:NTF \g_@@_empty_cell_bool - { - \box_use_drop:N \l_@@_cell_box - \bool_gset_false:N \g_@@_empty_cell_bool - } + { \box_use_drop:N \l_@@_cell_box } { - \dim_compare:nNnTF { \box_wd:N \l_@@_cell_box } > \c_zero_dim + \bool_lazy_or:nnTF + \g_@@_not_empty_cell_bool + { \dim_compare_p:nNn { \box_wd:N \l_@@_cell_box } > \c_zero_dim } \@@_node_for_the_cell: { \box_use_drop:N \l_@@_cell_box } } \bool_gset_false:N \g_@@_empty_cell_bool + \bool_gset_false:N \g_@@_not_empty_cell_bool } % \end{macrocode} % @@ -4244,9 +6856,9 @@ version 2005/12/01 or later. % \end{macrocode} % % \interitem -% The first argument of the following command |\@@_instruction_of_type:nn| +% The second argument of the following command |\@@_instruction_of_type:nnn| % defined below is the type of the instruction (|Cdots|, |Vdots|, |Ddots|, -% etc.). The second argument is the list of options. This command writes in the +% etc.). The third argument is the list of options. This command writes in the % corresponding |\g_@@_|\textsl{type}|_lines_tl| the instruction which will % actually draw the line after the construction of the matrix. % @@ -4258,13 +6870,13 @@ version 2005/12/01 or later. % \begin{pNiceMatrix} % 1 & 2 & 3 & 4 \\ % 5 & \Cdots & & 6 \\ -% 7 & \Cdots[color=red] \\ +% 7 & \Cdots[color=red] % \end{pNiceMatrix} % \end{BVerbatim} % $\begin{pNiceMatrix} % 1 & 2 & 3 & 4 \\ % 5 & \Cdots & & 6 \\ -% 7 & \Cdots[color=red] \\ +% 7 & \Cdots[color=red] % \end{pNiceMatrix}$ % % \smallskip @@ -4280,32 +6892,25 @@ version 2005/12/01 or later. % % % \bigskip -% We begin with a test of the flag |\c_@@_draft_bool| because, if the key -% |draft| is used, the dotted lines are not drawn. +% The first argument is a boolean which indicates whether you must put the +% instruction on the left or on the right on the list of instructions. % \begin{macrocode} -\bool_if:NTF \c_@@_draft_bool - { \cs_set_protected:Npn \@@_instruction_of_type:nn #1 #2 { } } - { - \cs_new_protected:Npn \@@_instruction_of_type:nn #1 #2 - { +\cs_new_protected:Npn \@@_instruction_of_type:nnn #1 #2 #3 + { % \end{macrocode} % It's important to use a |\tl_gput_right:cx| and not a |\tl_gput_left:cx| % because we want the |\Ddots| lines to be drawn in the order of appearance % in the array (for parallelisation). % \begin{macrocode} - \tl_gput_right:cx - { g_@@_ #1 _ lines _ tl } - { - \use:c { @@ _ draw _ #1 : nnn } - { \int_use:N \c@iRow } - { \int_use:N \c@jCol } -% \end{macrocode} -% Maybe we should prevent the expansion of the list of key-value. -% \begin{macrocode} - { #2 } - } - } - } + \bool_if:nTF { #1 } \tl_gput_left:cx \tl_gput_right:cx + { g_@@_ #2 _ lines _ tl } + { + \use:c { @@ _ draw _ #2 : nnn } + { \int_use:N \c@iRow } + { \int_use:N \c@jCol } + { \exp_not:n { #3 } } + } + } % \end{macrocode} % % @@ -4316,23 +6921,41 @@ version 2005/12/01 or later. % redefinition of |\array| incompatible with our use of |\array|. % % \begin{macrocode} +\cs_new_protected:Npn \@@_revtex_array: + { + \cs_set_eq:NN \@acoll \@arrayacol + \cs_set_eq:NN \@acolr \@arrayacol + \cs_set_eq:NN \@acol \@arrayacol + \cs_set_nopar:Npn \@halignto { } + \@array@array + } +% \end{macrocode} +% +% \begin{macrocode} \cs_new_protected:Npn \@@_array: { \bool_if:NTF \c_@@_revtex_bool + \@@_revtex_array: { - \cs_set_eq:NN \@acoll \@arrayacol - \cs_set_eq:NN \@acolr \@arrayacol - \cs_set_eq:NN \@acol \@arrayacol - \cs_set:Npn \@halignto { } - \@array@array + \bool_if:NTF \l_@@_NiceTabular_bool + { \dim_set_eq:NN \col@sep \tabcolsep } + { \dim_set_eq:NN \col@sep \arraycolsep } + \dim_compare:nNnTF \l_@@_tabular_width_dim = \c_zero_dim + { \cs_set_nopar:Npn \@halignto { } } + { \cs_set_nopar:Npx \@halignto { to \dim_use:N \l_@@_tabular_width_dim } } +% \end{macrocode} +% It \pkg{colortbl} is loaded, |\@tabarray| has been redefined to incorporate +% |\CT@start|. +% \begin{macrocode} + \@tabarray } - \array % \end{macrocode} -% |\l_@@_baseline_str| may have the value |t|, |c| or |b|. However, if the value +% |\l_@@_baseline_tl| 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. +% right translation will be done further. Remark that |\str_if_eq:VnTF| is +% fully expandable and you need something fully expandable here. % \begin{macrocode} - [ \str_if_eq:VnTF \l_@@_baseline_str c c t ] + [ \str_if_eq:VnTF \l_@@_baseline_tl c c t ] } % \end{macrocode} % @@ -4341,76 +6964,156 @@ version 2005/12/01 or later. % |\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 +\cs_set_eq:NN \@@_old_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: } } -% \end{macrocode} % +% The following command creates a |row| node (and not a row of nodes!). % \begin{macrocode} -\cs_new_protected:Npn \@@_everycr_i: - { - \int_gzero:N \c@jCol +\cs_new_protected:Npn \@@_create_row_node: + { % \end{macrocode} % The |\hbox:n| (or |\hbox|) is mandatory. % \begin{macrocode} \hbox { + \bool_if:NT \l_@@_code_before_bool + { + \vtop + { + \skip_vertical:N 0.5\arrayrulewidth + \pgfsys@markposition { \@@_env: - row - \@@_succ:n \c@iRow } + \skip_vertical:N -0.5\arrayrulewidth + } + } \pgfpicture \pgfrememberpicturepositiononpagetrue \pgfcoordinate { \@@_env: - row - \@@_succ:n \c@iRow } - \pgfpointorigin + { \pgfpoint \c_zero_dim { - 0.5 \arrayrulewidth } } \str_if_empty:NF \l_@@_name_str { \pgfnodealias - { \@@_env: - row - \int_use:N \c@iRow - row } - { \l_@@_name_str - row - \int_use:N \c@iRow - row } + { \l_@@_name_str - row - \int_use:N \c@iRow } + { \@@_env: - row - \int_use:N \c@iRow } } \endpgfpicture - } + } + } % \end{macrocode} -% We add the potential horizontal lines specified by the option |hlines|. +% +% +% +% \bigskip +% The following must \emph{not} be protected because it begins with |\noalign|. +% \begin{macrocode} +\cs_new:Npn \@@_everycr: { \noalign { \@@_everycr_i: } } +% \end{macrocode} +% +% % \begin{macrocode} - \bool_if:NT \l_@@_hlines_bool +\cs_new_protected:Npn \@@_everycr_i: + { + \int_gzero:N \c@jCol + \bool_gset_false:N \g_@@_after_col_zero_bool + \bool_if:NF \g_@@_row_of_col_done_bool { + \@@_create_row_node: +% \end{macrocode} +% We don't draw the rules of the key |hlines| (or |hvlines|) but we reserve the +% vertical space for theses rules. +% \begin{macrocode} + \bool_if:NT \l_@@_hlines_bool + { % \end{macrocode} % The counter |\c@iRow| has the value $-1$ only if there is a ``first % row'' and that we are before that ``first row'', i.e. just before the % beginning of the array. % \begin{macrocode} - \int_compare:nNnT \c@iRow > { -1 } - { - \bool_if:NF \g_@@_row_of_col_done_bool + \int_compare:nNnT \c@iRow > { -1 } { \int_compare:nNnF \c@iRow = \l_@@_last_row_int - { - \bool_if:NTF \c_@@_colortbl_loaded_bool - { { \CT@arc@ \hrule height \arrayrulewidth } } - { \hrule height \arrayrulewidth } - } - } - } +% \end{macrocode} +% The command |\CT@arc@| is a command of \pkg{colortbl} which sets the color of +% the rules in the array. The package \pkg{nicematrix} uses it even if +% \pkg{colortbl} is not loaded. We use a TeX group in order to limit the scope +% of |\CT@arc@|. +% \begin{macrocode} + { \hrule height \arrayrulewidth width \c_zero_dim } + } + } } } % \end{macrocode} +% +% \bigskip +% The command |\@@_newcolumntype| is the command |\newcolumntype| of +% \pkg{array} without the warnings for redefinitions of columns types (we will +% use it to redefine the columns types |w| and |W|). +% \begin{macrocode} +\cs_set_protected:Npn \@@_newcolumntype #1 + { + \cs_set:cpn { NC @ find @ #1 } ##1 #1 { \NC@ { ##1 } } + \peek_meaning:NTF [ + { \newcol@ #1 } + { \newcol@ #1 [ 0 ] } + } +% \end{macrocode} +% +% +% \bigskip +% When the key |renew-dots| is used, the following code will be executed. +% \begin{macrocode} +\cs_set_protected:Npn \@@_renew_dots: + { + \cs_set_eq:NN \ldots \@@_Ldots + \cs_set_eq:NN \cdots \@@_Cdots + \cs_set_eq:NN \vdots \@@_Vdots + \cs_set_eq:NN \ddots \@@_Ddots + \cs_set_eq:NN \iddots \@@_Iddots + \cs_set_eq:NN \dots \@@_Ldots + \cs_set_eq:NN \hdotsfor \@@_Hdotsfor: + } +% \end{macrocode} +% +% \bigskip +% When the key |colortbl-like| is used, the following code will be executed. +% \begin{macrocode} +\cs_new_protected:Npn \@@_colortbl_like: + { + \cs_set_eq:NN \cellcolor \@@_cellcolor_tabular + \cs_set_eq:NN \rowcolor \@@_rowcolor_tabular + \cs_set_eq:NN \columncolor \@@_columncolor_preamble + } +% \end{macrocode} % % \bigskip % The following code |\@@_pre_array:| is used in |{NiceArrayWithDelims}|. It -% exists as a standalone macro only for lisibility. +% exists as a standalone macro only for legibility. % \label{prearray} % % \begin{macrocode} \cs_new_protected:Npn \@@_pre_array: { +% \end{macrocode} +% If \pkg{booktabs} is loaded, we have to patch the macro |\@BTnormal| which is +% a macro of \pkg{booktabs}. The macro |\@BTnormal| draws an horizontal rule but +% it occurs after a vertical skip done by a low level TeX command. When this +% macro |\@BTnormal| occurs, the |row| node has yet been inserted by +% \pkg{nicematrix} \emph{before} the vertical skip (and thus, at a wrong place). +% That why we decide to create a new |row| node (for the same row). We patch the +% macro |\@BTnormal| to create this |row| node. This new |row| node will +% overwrite the previous definition of that |row| node and we have managed to +% avoid the error messages of that redefinition +% \footnote{cf. |\nicematrix@redefine@check@rerun|}. +% \begin{macrocode} + \bool_if:NT \c_@@_booktabs_loaded_bool + { \tl_put_left:Nn \@BTnormal \@@_create_row_node: } \box_clear_new:N \l_@@_cell_box \cs_if_exist:NT \theiRow - { \int_set_eq:NN \l_@@_save_iRow_int \c@iRow } + { \int_set_eq:NN \l_@@_old_iRow_int \c@iRow } \int_gzero_new:N \c@iRow \cs_if_exist:NT \thejCol - { \int_set_eq:NN \l_@@_save_jCol_int \c@jCol } + { \int_set_eq:NN \l_@@_old_jCol_int \c@jCol } \int_gzero_new:N \c@jCol \normalbaselines % \end{macrocode} @@ -4422,7 +7125,7 @@ version 2005/12/01 or later. { % \end{macrocode} % \begin{macrocode} - \cs_set:Npn \arraystretch { 0.47 } + \cs_set_nopar:Npn \arraystretch { 0.47 } \dim_set:Nn \arraycolsep { 1.45 pt } } % \end{macrocode} @@ -4434,7 +7137,7 @@ version 2005/12/01 or later. % |\everycr| to |{ }| and we \emph{need} to have to change the value of % |\everycr|. % \begin{macrocode} - \cs_set:Npn \ialign + \cs_set_nopar:Npn \ialign { \bool_if:NTF \c_@@_colortbl_loaded_bool { @@ -4450,7 +7153,7 @@ version 2005/12/01 or later. % % The box |\@arstrutbox| is a box constructed in the beginning of the % environment |{array}|. The construction of that box takes into account the -% current values of |\arraystretch|\footnote{The option |small| of +% current value of |\arraystretch|\footnote{The option |small| of % \pkg{nicematrix} changes (among other) the value of |\arraystretch|. This is % done, of course, before the call of |{array}|.} and |\extrarowheight| (of % \pkg{array}). That box is inserted (via |\@arstrut|) in the beginning of each @@ -4473,56 +7176,46 @@ version 2005/12/01 or later. % \end{macrocode} % 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}|).} +% have, in the cells of the array, a clean version of |\ialign|. % \begin{macrocode} - \cs_set_eq:NN \ialign \@@_standard_ialign: + \cs_set_eq:NN \ialign \@@_old_ialign: \halign } % \end{macrocode} % -% We define the new column types |L|, |C| and |R| that must be used instead of -% |l|, |c| and |r| in the preamble of |{NiceArray}|. -% \begin{macrocode} - \newcolumntype L { > \@@_Cell: l < \@@_end_Cell: } - \newcolumntype C { > \@@_Cell: c < \@@_end_Cell: } - \newcolumntype R { > \@@_Cell: r < \@@_end_Cell: } -% \end{macrocode} % We keep in memory the old versions or |\ldots|, |\cdots|, etc. only because we % use them inside |\phantom| commands in order that the new commands |\Ldots|, % |\Cdots|, etc. give the same spacing (except when the option |nullify-dots| is % used). % \begin{macrocode} - \cs_set_eq:NN \@@_ldots \ldots - \cs_set_eq:NN \@@_cdots \cdots - \cs_set_eq:NN \@@_vdots \vdots - \cs_set_eq:NN \@@_ddots \ddots - \cs_set_eq:NN \@@_iddots \iddots - \cs_set_eq:NN \firsthline \hline - \cs_set_eq:NN \lasthline \hline + \cs_set_eq:NN \@@_old_ldots \ldots + \cs_set_eq:NN \@@_old_cdots \cdots + \cs_set_eq:NN \@@_old_vdots \vdots + \cs_set_eq:NN \@@_old_ddots \ddots + \cs_set_eq:NN \@@_old_iddots \iddots + \bool_if:NTF \l_@@_standard_cline_bool + { \cs_set_eq:NN \cline \@@_standard_cline } + { \cs_set_eq:NN \cline \@@_cline } \cs_set_eq:NN \Ldots \@@_Ldots \cs_set_eq:NN \Cdots \@@_Cdots \cs_set_eq:NN \Vdots \@@_Vdots \cs_set_eq:NN \Ddots \@@_Ddots \cs_set_eq:NN \Iddots \@@_Iddots \cs_set_eq:NN \hdottedline \@@_hdottedline: + \cs_set_eq:NN \Hline \@@_Hline: \cs_set_eq:NN \Hspace \@@_Hspace: \cs_set_eq:NN \Hdotsfor \@@_Hdotsfor: + \cs_set_eq:NN \Vdotsfor \@@_Vdotsfor: \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 - { - \cs_set_eq:NN \ldots \@@_Ldots - \cs_set_eq:NN \cdots \@@_Cdots - \cs_set_eq:NN \vdots \@@_Vdots - \cs_set_eq:NN \ddots \@@_Ddots - \cs_set_eq:NN \iddots \@@_Iddots - \cs_set_eq:NN \dots \@@_Ldots - \cs_set_eq:NN \hdotsfor \@@_Hdotsfor: - } + \cs_set_eq:NN \dotfill \@@_old_dotfill: + \cs_set_eq:NN \CodeAfter \@@_CodeAfter: + \cs_set_eq:NN \diagbox \@@_diagbox:nn + \cs_set_eq:NN \NotEmpty \@@_NotEmpty: + \bool_if:NT \l_@@_colortbl_like_bool \@@_colortbl_like: + \bool_if:NT \l_@@_renew_dots_bool \@@_renew_dots: % \end{macrocode} % % @@ -4564,115 +7257,11 @@ version 2005/12/01 or later. \cs_set_eq:NN \@ifnextchar \new@ifnextchar % \end{macrocode} % -% We nullify the definitions of the column types |w| and |W| before their -% redefinition because we want to avoid a warning in the log file for a -% redefinition of a column type. We must put |\relax| and not -% |\prg_do_nothing:|. -% \begin{macrocode} - \cs_set_eq:NN \NC@find@w \relax - \cs_set_eq:NN \NC@find@W \relax - \newcolumntype w [ 2 ] - { - > { - \hbox_set:Nw \l_@@_cell_box - \@@_Cell: - } - c - < { - \@@_end_Cell: - \hbox_set_end: -% \end{macrocode} -% The |\str_lowercase:n| is only for giving the user the ability to write -% |wC{1cm}| instead of |wc{1cm}| for homogeneity with the letters |L|, |C| and -% |R| used elsewhere in the preamble instead of |l|, |c| and |r|. -% \begin{macrocode} - \makebox [ ##2 ] [ \str_lowercase:n { ##1 } ] - { \box_use_drop:N \l_@@_cell_box } - } - } - \newcolumntype W [ 2 ] - { - > { - \hbox_set:Nw \l_@@_cell_box - \@@_Cell: - } - c - < { - \@@_end_Cell: - \hbox_set_end: - \cs_set_eq:NN \hss \hfil - \makebox [ ##2 ] [ \str_lowercase:n { ##1 } ] - { \box_use_drop:N \l_@@_cell_box } - } - } -% \end{macrocode} -% -% \bigskip -% By default, the letter used to specify a dotted line in the preamble of an -% environment of \pkg{nicematrix} (for example in |{pNiceArray}|) is the letter -% |:|. However, this letter is used by some extensions, for example -% \pkg{arydshln}. That's why it's possible to change the letter used by -% \pkg{nicematrix} with the option |letter-for-dotted-lines| which changes the -% value of |\l_@@_letter_for_dotted_lines_str|. We rescan this string (which is -% always of length~1) in particular for the case where |pdflatex| is used with -% \pkg{french-babel} (the colon is activated by \pkg{french-babel} at the -% beginning of the document). % \begin{macrocode} - \tl_set_rescan:Nno - \l_@@_letter_for_dotted_lines_str { } \l_@@_letter_for_dotted_lines_str - \exp_args:NV \newcolumntype \l_@@_letter_for_dotted_lines_str - { - ! - { + \@@_renew_NC@rewrite@S: % \end{macrocode} % -% \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} - \int_compare:nNnF \c@iRow = 0 - { - \int_compare:nNnF \c@iRow = \l_@@_last_row_int - { \skip_horizontal:N 2\l_@@_radius_dim } - } -% \end{macrocode} -% -% \medskip -% Consider the following code: -% \begin{center} -% \begin{BVerbatim} -% \begin{NiceArray}{C:CC:C} -% a & b -% c & d \\ -% e & f & g & h \\ -% i & j & k & l -% \end{NiceArray} -% \end{BVerbatim} -% \end{center} -% The first ``|:|'' in the preamble will be encountered during the first row of -% the environment |{NiceArray}| but the second one will be encountered only in -% the third row. We have to issue a command |\vdottedline:n| in the |code-after| -% only one time for each ``|:|'' in the preamble. That's why we keep a counter -% |\g_@@_last_vdotted_col_int| and with this counter, we know whether a letter -% ``|:|'' encountered during the parsing has already been taken into account in -% the |code-after|. -% \begin{macrocode} - \int_compare:nNnT \c@jCol > \g_@@_last_vdotted_col_int - { - \int_gset_eq:NN \g_@@_last_vdotted_col_int \c@jCol - \tl_gput_right:Nx \g_@@_internal_code_after_tl -% \end{macrocode} -% The command |\@@_vdottedline:n| is protected, and, therefore, won't be -% expanded before writing on |\g_@@_internal_code_after_tl|. -% \begin{macrocode} - { \@@_vdottedline:n { \int_use:N \c@jCol } } - } - } - } - \int_gzero_new:N \g_@@_last_vdotted_col_int - \bool_if:NT \c_@@_siunitx_loaded_bool \@@_renew_NC@rewrite@S: - \int_gset:Nn \g_@@_last_vdotted_col_int { -1 } \bool_gset_false:N \g_@@_last_col_found_bool % \end{macrocode} % @@ -4686,9 +7275,16 @@ version 2005/12/01 or later. \tl_gclear_new:N \g_@@_Vdots_lines_tl \tl_gclear_new:N \g_@@_Ddots_lines_tl \tl_gclear_new:N \g_@@_Iddots_lines_tl - \tl_gclear_new:N \g_@@_Hdotsfor_lines_tl - } + \tl_gclear_new:N \g_@@_HVdotsfor_lines_tl % \end{macrocode} +% +% \medskip +% \begin{macrocode} + \tl_gclear_new:N \g_nicematrix_code_before_tl + } +% \end{macrocode} +% This is the end of |\@@_pre_array:|. +% % % \bigskip % \subsection*{The environment \{NiceArrayWithDelims\}} @@ -4696,30 +7292,66 @@ version 2005/12/01 or later. % \begin{macrocode} \NewDocumentEnvironment { NiceArrayWithDelims } { m m O { } m ! O { } } { + \@@_provide_pgfsyspdfmark: + \bool_if:NT \c_@@_footnote_bool \savenotes +% \end{macrocode} +% The aim of the following |\bgroup| (the corresponding |\egroup| is, of course, +% at the end of the environment) is to be able to put an exposant to a matrix in +% a mathematical formula. +% \begin{macrocode} + \bgroup +% \end{macrocode} +% +% \bigskip +% \begin{macrocode} \tl_set:Nn \l_@@_left_delim_tl { #1 } \tl_set:Nn \l_@@_right_delim_tl { #2 } + \tl_gset:Nn \g_@@_preamble_tl { #4 } +% \end{macrocode} +% +% +% \bigskip +% +% \begin{macrocode} + \int_gzero:N \g_@@_block_box_int + \dim_zero:N \g_@@_width_last_col_dim + \dim_zero:N \g_@@_width_first_col_dim \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:NTF \l_@@_NiceTabular_bool + \mode_leave_vertical: + \@@_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} +% The command |\CT@arc@| contains the instruction of color for the rules of the +% array\footnote{e.g. |\color[rgb]{0.5,0.5,0}|}. This command is used by |\CT@arc@| but +% we use it also for compatibility with \pkg{colortbl}. But we want also to be +% able to use color for the rules of the array when \pkg{colortbl} is \emph{not} +% loaded. That's why we do the following instruction which is in the patch of +% the beginning of arrays done by \pkg{colortbl}. Of course, we restore the +% value of |\CT@arc@| at the end of our environment. +% \begin{macrocode} + \cs_gset_eq:NN \@@_old_CT@arc@ \CT@arc@ +% \end{macrocode} % -% We deactivate Tikz externalization because we will use \textsc{pgf} pictures with the -% options |overlay| and |remember picture| (or equivalent forms). +% We deactivate Tikz externalization because we will use \textsc{pgf} pictures +% with the options |overlay| and |remember picture| (or equivalent forms). We +% deactivate with |\tikzexternaldisable| and not with +% |\tikzset{external/export=false}| which is \emph{not} equivalent. % \begin{macrocode} \cs_if_exist:NT \tikz@library@external@loaded { - \tikzset { external / export = false } + \tikzexternaldisable \cs_if_exist:NT \ifstandalone { \tikzset { external / optimize = false } } } % \end{macrocode} % % We increment the counter |\g_@@_env_int| which counts the environments -% of the extension. +% of the package. % \begin{macrocode} \int_gincr:N \g_@@_env_int \bool_if:NF \l_@@_block_auto_columns_width_bool @@ -4727,14 +7359,31 @@ version 2005/12/01 or later. % \end{macrocode} % % -% We do a redefinition of |\@arrayrule| because we want that the vertical rules -% drawn by "|" in the preamble of the array don't extend in the potential -% exterior rows. +% The sequence |\g_@@_blocks_seq| will contain the carateristics of the blocks +% (specified by |\Block|) of the array. The sequence |\g_@@_pos_of_blocks_seq| +% will contain only the position of the blocks. Of course, this is redundant but +% it's for efficiency. % \begin{macrocode} - \cs_set_protected:Npn \@arrayrule { \@addtopreamble \@@_vline: } + \seq_gclear:N \g_@@_blocks_seq + \seq_gclear:N \g_@@_pos_of_blocks_seq % \end{macrocode} -% +% In fact, the sequence |\g_@@_pos_of_blocks_seq| will also contain the +% positions of the cells with a |\diagbox|. % +% \begin{macrocode} + \seq_gclear:N \g_@@_pos_of_stroken_blocks_seq + \seq_gclear:N \g_@@_pos_of_xdots_seq +% \end{macrocode} +% +% \begin{macrocode} + \tl_if_exist:cT { g_@@_code_before_ \int_use:N \g_@@_env_int _ tl } + { + \bool_set_true:N \l_@@_code_before_bool + \exp_args:NNv \tl_put_right:Nn \l_@@_code_before_tl + { g_@@_code_before_ \int_use:N \g_@@_env_int _ tl } + } +% \end{macrocode} +% % The set of keys is not exactly the same for |{NiceArray}| and for the variants % of |{NiceArray}| (|{pNiceArray}|, |{bNiceArray}|, etc.) because, for % |{NiceArray}|, we have the options |t|, |c|, |b| and |baseline|. @@ -4744,7 +7393,105 @@ version 2005/12/01 or later. { \keys_set:nn { NiceMatrix / pNiceArray } } { #3 , #5 } % \end{macrocode} +% +% \bigskip +% \begin{macrocode} + \tl_if_empty:NF \l_@@_rules_color_tl + { \exp_after:wN \@@_set_CT@arc@: \l_@@_rules_color_tl \q_stop } +% \end{macrocode} +% % +% \bigskip +% If the key |code-before| is used, we have to create the |col| nodes and the +% |row| nodes before the creation of the array. First, we have to test whether +% the size of the array has been written in the |aux| file in a previous run. In +% this case, a command |\@@_size_|{\slshape\ttfamily nb_of_env}|:| has been +% created. +% \begin{macrocode} + \bool_if:NT \l_@@_code_before_bool + { + \seq_if_exist:cT { @@_size_ \int_use:N \g_@@_env_int _ seq } + { +% \end{macrocode} +% First, we give values to the LaTeX counters |iRow| and |jCol|. We remind that, +% in the |code-before| (and in the |code-after|) they represent the numbers of +% rows and columns of the array (without the potential last row and last column). +% \begin{macrocode} + \int_zero_new:N \c@iRow + \int_set:Nn \c@iRow + { \seq_item:cn { @@_size_ \int_use:N \g_@@_env_int _ seq } 2 } + \int_zero_new:N \c@jCol + \int_set:Nn \c@jCol + { \seq_item:cn { @@_size_ \int_use:N \g_@@_env_int _ seq } 4 } +% \end{macrocode} +% We have to adjust the values of |\c@iRow| and |\c@jCol| to take into account +% the potential last row and last column. A value of $-2$ for +% |\l_@@_last_row_int| means that there is no last row. Idem for the columns. +% \begin{macrocode} + \int_compare:nNnF \l_@@_last_row_int = { -2 } + { \int_decr:N \c@iRow } + \int_compare:nNnF \l_@@_last_col_int = { -2 } + { \int_decr:N \c@jCol } +% \end{macrocode} +% +% Now, we will create all the |col| nodes and |row| nodes with the informations +% written in the |aux| file. You use the technique described in the page~1229 of +% |pgfmanual.pdf|, version~3.1.4b. +% \begin{macrocode} + \pgfsys@markposition { \@@_env: - position } + \pgfsys@getposition { \@@_env: - position } \@@_picture_position: + \pgfpicture +% \end{macrocode} +% First, the creation of the |row| nodes. +% \begin{macrocode} + \int_step_inline:nnn + { \seq_item:cn { @@_size_ \int_use:N \g_@@_env_int _ seq } 1 } + { \seq_item:cn { @@_size_ \int_use:N \g_@@_env_int _ seq } 2 + 1 } + { + \pgfsys@getposition { \@@_env: - row - ##1 } \@@_node_position: + \pgfcoordinate { \@@_env: - row - ##1 } + { \pgfpointdiff \@@_picture_position: \@@_node_position: } + } +% \end{macrocode} +% Now, the creation of the |col| nodes. +% \begin{macrocode} + \int_step_inline:nnn + { \seq_item:cn { @@_size_ \int_use:N \g_@@_env_int _ seq } 3 } + { \seq_item:cn { @@_size_ \int_use:N \g_@@_env_int _ seq } 4 + 1 } + { + \pgfsys@getposition { \@@_env: - col - ##1 } \@@_node_position: + \pgfcoordinate { \@@_env: - col - ##1 } + { \pgfpointdiff \@@_picture_position: \@@_node_position: } + } + \endpgfpicture + \group_begin: + \bool_if:NT \c_@@_tikz_loaded_bool + { + \tikzset + { + every~picture / .style = + { overlay , name~prefix = \@@_env: - } + } + } + \cs_set_eq:NN \cellcolor \@@_cellcolor + \cs_set_eq:NN \rectanglecolor \@@_rectanglecolor + \cs_set_eq:NN \rowcolor \@@_rowcolor + \cs_set_eq:NN \rowcolors \@@_rowcolors + \cs_set_eq:NN \columncolor \@@_columncolor + \cs_set_eq:NN \chessboardcolors \@@_chessboardcolors +% \end{macrocode} +% We compose the |code-before| in math mode in order to nullify the spaces put +% by the user between instructions in the |code-before|. +% \begin{macrocode} + \bool_if:NT \l_@@_NiceTabular_bool \c_math_toggle_token + \seq_clear_new:N \l_@@_colors_seq + \l_@@_code_before_tl + \@@_actually_color: + \bool_if:NT \l_@@_NiceTabular_bool \c_math_toggle_token + \group_end: + } + } +% \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 @@ -4789,11 +7536,9 @@ version 2005/12/01 or later. % % % A value of $-1$ for the counter |\l_@@_last_col_int| means that the user has -% used the option |last-col| without value (it's possible in an environment -% without preamble like |{NiceMatrix}| or |{pNiceMatrix}|), that is to say -% without specifying the number of that last column. In this case, we try to -% read that value from the |aux| file (if it has been written on a previous -% run). +% used the option |last-col| without value, that is to say without specifying +% the number of that last column. 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_col_int = { -1 } { @@ -4822,7 +7567,7 @@ version 2005/12/01 or later. % \end{macrocode} % % \medskip -% We compute the width of the two delimiters. +% We compute the width of both delimiters. % \begin{macrocode} \dim_zero_new:N \l_@@_left_delim_dim \dim_zero_new:N \l_@@_right_delim_dim @@ -4835,9 +7580,9 @@ version 2005/12/01 or later. % \end{macrocode} % The command |\bBigg@| is a command of \pkg{amsmath}. % \begin{macrocode} - \hbox_set:Nn \l_tmpa_box { $ \bBigg@ 5 #1 $ } + \hbox_set:Nn \l_tmpa_box { $ \bBigg@ 5 \l_@@_left_delim_tl $ } \dim_set:Nn \l_@@_left_delim_dim { \box_wd:N \l_tmpa_box } - \hbox_set:Nn \l_tmpa_box { $\bBigg@ 5 #2 $ } + \hbox_set:Nn \l_tmpa_box { $ \bBigg@ 5 \l_@@_right_delim_tl $ } \dim_set:Nn \l_@@_right_delim_dim { \box_wd:N \l_tmpa_box } } % \end{macrocode} @@ -4849,57 +7594,40 @@ version 2005/12/01 or later. \box_clear_new:N \l_@@_the_array_box % \end{macrocode} % -% \medskip -% We construct the preamble of the array in |\l_tmpa_tl|. +% \bigskip +% If the user has loaded |nicematrix| with the option |define-L-C-R|, he will be +% able to use |L|, |C| and |R| instead of |l|, |c| and |r| in the preambles of +% the environments of \pkg{nicematrix} (it's a compatibility mode since |L|, |C| +% and |R| were mandatory before version 5.0). % \begin{macrocode} - \tl_set:Nn \l_tmpa_tl { #4 } - \int_compare:nNnTF \l_@@_first_col_int = 0 - { \tl_put_left:NV \l_tmpa_tl \c_@@_preamble_first_col_tl } - { - \bool_lazy_all:nT - { - \l_@@_NiceArray_bool - { \bool_not_p:n \l_@@_vlines_bool } - { \bool_not_p:n \l_@@_exterior_arraycolsep_bool } - } - { \tl_put_left:Nn \l_tmpa_tl { @ { } } } - } - \int_compare:nNnTF \l_@@_last_col_int > { -1 } - { \tl_put_right:NV \l_tmpa_tl \c_@@_preamble_last_col_tl } - { - \bool_lazy_all:nT - { - \l_@@_NiceArray_bool - { \bool_not_p:n \l_@@_vlines_bool } - { \bool_not_p:n \l_@@_exterior_arraycolsep_bool } - } - { \tl_put_right:Nn \l_tmpa_tl { @ { } } } - } - \tl_put_right:Nn \l_tmpa_tl { > { \@@_error_too_much_cols: } l } + \bool_if:NT \c_@@_define_L_C_R_bool \@@_define_L_C_R: +% \end{macrocode} +% +% \bigskip +% The preamble will be constructed in |\g_@@_preamble_tl|. +% \begin{macrocode} + \@@_construct_preamble: % \end{macrocode} +% +% Now, the preamble is constructed in |\g_@@_preamble_tl| +% +% +% +% \bigskip % 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 + \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 \bool_if:NTF \l_@@_light_syntax_bool - { \begin { @@-light-syntax } } - { \begin { @@-normal-syntax } } + { \use:c { @@-light-syntax } } + { \use:c { @@-normal-syntax } } } % \end{macrocode} % @@ -4907,26 +7635,18 @@ version 2005/12/01 or later. % \begin{macrocode} { \bool_if:NTF \l_@@_light_syntax_bool - { \end { @@-light-syntax } } - { \end { @@-normal-syntax } } + { \use:c { end @@-light-syntax } } + { \use:c { end @@-normal-syntax } } \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} % 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 +% given value is correct (since we have just constructed the array, we know the % real number of rows of the array). % \begin{macrocode} \int_compare:nNnT \l_@@_last_row_int > { -2 } @@ -4942,14 +7662,19 @@ version 2005/12/01 or later. } % \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'' (exterior) has the number~$0$.} +% 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'' (exterior) +% has the number~$0$.} % \begin{macrocode} \int_gset_eq:NN \c@jCol \g_@@_col_total_int - \bool_if:nT \g_@@_last_col_found_bool { \int_gdecr:N \c@jCol } + \bool_if:nTF \g_@@_last_col_found_bool + { \int_gdecr:N \c@jCol } + { + \int_compare:nNnT \l_@@_last_col_int > { -1 } + { \@@_error:n { last~col~not~used } } + } % \end{macrocode} % % We fix also the value of |\c@iRow| and |\g_@@_row_total_int| with the @@ -4960,7 +7685,6 @@ version 2005/12/01 or later. % \end{macrocode} % % -% % \bigskip % \textbf{Now, we begin the real construction in the output flow of TeX}. First, we take % into account a potential ``first column'' (we remind that this ``first @@ -4970,78 +7694,26 @@ version 2005/12/01 or later. % \begin{macrocode} \int_compare:nNnT \l_@@_first_col_int = 0 { - \skip_horizontal:N \arraycolsep - \skip_horizontal:N \g_@@_width_first_col_dim + \skip_horizontal:N \col@sep + \skip_horizontal:N \g_@@_width_first_col_dim } % \end{macrocode} % -% The construction of the real box is different in |{NiceArray}| and in the -% other environments because, in |{NiceArray}|, we have to take into account the -% value of |baseline| and we have no delimiter to put. We begin with |{NiceArray}|. +% The construction of the real box is different when |\l_@@_NiceArray_bool| is +% true (|{NiceArray}| or |{NiceTabular}|) and in the other environments because, +% in |{NiceArray}| or |{NiceTabular}|, we have no delimiter to put (but we have +% tabular notes to put). We begin with this case. +% +% Remark that, in all cases, |@@_use_arraybox_with_notes_c:| is used. % \begin{macrocode} \bool_if:NTF \l_@@_NiceArray_bool { -% \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_case:VnF \l_@@_baseline_tl { - \pgfpicture - \@@_qpoint: { row - 1 } - \dim_gset_eq:NN \g_tmpa_dim \pgf@y - \@@_qpoint: { row - \int_use:N \c@iRow - base } - \dim_gsub:Nn \g_tmpa_dim \pgf@y - \endpgfpicture - \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 } - } - { - \str_if_eq:VnTF \l_@@_baseline_str { c } - { \box_use_drop:N \l_@@_the_array_box } - { -% \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 < \l_@@_first_row_int - || \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 |{pgfpicture}| to extract coordinates (nothing is drawn). -% \begin{macrocode} - \pgfpicture - \@@_qpoint: { row - 1 } - \dim_gset_eq:NN \g_tmpa_dim \pgf@y - \@@_qpoint: { row - \int_use:N \l_tmpa_int - base } - \dim_gsub:Nn \g_tmpa_dim \pgf@y - \endpgfpicture - \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 } - } + b \@@_use_arraybox_with_notes_b: + c \@@_use_arraybox_with_notes_c: } + \@@_use_arraybox_with_notes: } % \end{macrocode} % @@ -5062,8 +7734,8 @@ version 2005/12/01 or later. % 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 % $-1$ for |\l_@@_last_row_int| means that there is a ``last row'' but the -% number of that row is unknown (the user have not set the value with the option -% |last row|).} +% the user have not set the value with the option |last row| (and we are in the +% first compilation).} % \begin{macrocode} \int_compare:nNnTF \l_@@_last_row_int > { -2 } { @@ -5077,7 +7749,9 @@ version 2005/12/01 or later. \hbox_set:Nn \l_tmpa_box { \c_math_toggle_token - \left #1 + \tl_if_empty:NF \l_@@_delimiters_color_tl + { \color { \l_@@_delimiters_color_tl } } + \exp_after:wN \left \l_@@_left_delim_tl \vcenter { % \end{macrocode} @@ -5087,9 +7761,13 @@ version 2005/12/01 or later. \skip_vertical:N -\l_tmpa_dim \hbox { - \skip_horizontal:N -\arraycolsep - \box_use_drop:N \l_@@_the_array_box - \skip_horizontal:N -\arraycolsep + \bool_if:NTF \l_@@_NiceTabular_bool + { \skip_horizontal:N -\tabcolsep } + { \skip_horizontal:N -\arraycolsep } + \@@_use_arraybox_with_notes_c: + \bool_if:NTF \l_@@_NiceTabular_bool + { \skip_horizontal:N -\tabcolsep } + { \skip_horizontal:N -\arraycolsep } } % \end{macrocode} % We take into account the ``last row'' (we have previously computed its total @@ -5097,7 +7775,7 @@ version 2005/12/01 or later. % \begin{macrocode} \skip_vertical:N -\l_tmpb_dim } - \right #2 + \exp_after:wN \right \l_@@_right_delim_tl \c_math_toggle_token } % \end{macrocode} @@ -5109,7 +7787,7 @@ version 2005/12/01 or later. % \begin{macrocode} \bool_if:NTF \l_@@_max_delimiter_width_bool { \@@_put_box_in_flow_bis:nn { #1 } { #2 } } - \@@_put_box_in_flow: + \@@_put_box_in_flow: } % \end{macrocode} % @@ -5120,13 +7798,465 @@ version 2005/12/01 or later. \bool_if:NT \g_@@_last_col_found_bool { \skip_horizontal:N \g_@@_width_last_col_dim - \skip_horizontal:N \arraycolsep + \skip_horizontal:N \col@sep + } + \bool_if:NF \l_@@_Matrix_bool + { + \int_compare:nNnT \c@jCol < \g_@@_static_num_of_col_int + { \@@_error:n { columns~not~used } } } + \group_begin: + \globaldefs = 1 + \@@_msg_redirect_name:nn { columns~not~used } { error } + \group_end: \@@_after_array: +% \end{macrocode} +% The aim of the following |\egroup| (the corresponding |\bgroup| is, of course, +% at the beginning of the environment) is to be able to put an exposant to a matrix in +% a mathematical formula. +% \begin{macrocode} + \egroup + \bool_if:NT \c_@@_footnote_bool \endsavenotes } % \end{macrocode} % This is the end of the environment |{NiceArrayWithDelims}|. % +% \vspace{1cm} +% \subsection*{We construct the preamble of the array} +% +% The transformation of the preamble is an operation in several steps. +% +% \bigskip +% The preamble given by the final use is in |\g_@@_preamble_tl| and the modified +% version will be stored in |\g_@@_preamble_tl| also. +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_construct_preamble: + { +% \end{macrocode} +% First, we will do an ``expansion'' of the preamble with the tools of the +% package \pkg{array} itself. This ``expansion'' will expand all the constructions +% with |*| and with all column types (defined by the user or by various packages +% using |\newcolumntype|). +% +% Since we use the tools of \pkg{array} to do this expansion, we will have a +% programmation which is not in the style of \pkg{expl3}. +% +% +% \bigskip +% We redefine the column types |w| and |W|. We use |\@@_newcolumntype| instead +% of |\newcolumtype| because we don't want warnings for column types already +% defined. These redefinitions are in fact \emph{protections} of the letters |w| +% and |W|. We don't want these columns type expanded because we will do the +% patch ourselves after. We want to be able the standard column types |w| and +% |W| in potential |{tabular}| of \pkg{array} in some cells of our array. That's +% why we do those redefinitions in a TeX group. +% \begin{macrocode} + \group_begin: +% \end{macrocode} +% +% If we are in an environment without explicit preamble, we have nothing to do +% (excepted the treatment on both sides of the preamble which will be done at +% the end). +% \begin{macrocode} + \bool_if:NF \l_@@_Matrix_bool + { + \@@_newcolumntype w [ 2 ] { \@@_w: { ##1 } { ##2 } } + \@@_newcolumntype W [ 2 ] { \@@_W: { ##1 } { ##2 } } +% \end{macrocode} +% +% First, we have to store our preamble in the token register |\@temptokena| +% (those ``token registers'' are not supported by \pkg{expl3}). +% \begin{macrocode} + \exp_args:NV \@temptokena \g_@@_preamble_tl +% \end{macrocode} +% Initialisation of a flag used by \pkg{array} to detect the end of the expansion. +% \begin{macrocode} + \@tempswatrue +% \end{macrocode} +% The following line actually does the expansion (it's has been copied from +% |array.sty|). +% \begin{macrocode} + \@whilesw \if@tempswa \fi { \@tempswafalse \the \NC@list } +% \end{macrocode} +% +% +% \bigskip +% Now, we have to ``patch'' that preamble by transforming some columns. +% We will insert in the TeX flow the preamble in its actual form (that is to say +% after the ``expansion'') following by a marker |\q_stop| and we will consume +% these tokens constructing the (new form of the) preamble in +% |\g_@@_preamble_tl|. This is done recursively with the command +% |\@@_patch_preamble:n|. In the same time, we will count the columns with the +% counter |\c@jCol|. +% \begin{macrocode} + \int_gzero_new:N \c@jCol + \bool_if:NTF \l_@@_vlines_bool + { + \tl_gset:Nn \g_@@_preamble_tl + { ! { \skip_horizontal:N \arrayrulewidth } } + } + { \tl_gclear:N \g_@@_preamble_tl } +% \end{macrocode} +% The counter |\l_tmpa_int| will count the number of consecutive occurrences +% of the symbol \verb+|+. +% \begin{macrocode} + \int_zero:N \l_tmpa_int +% \end{macrocode} +% Now, we actually patch the preamble (and it is constructed in +% |\g_@@_preamble_tl|). +% \begin{macrocode} + \exp_after:wN \@@_patch_preamble:n \the \@temptokena \q_stop + \int_gset_eq:NN \g_@@_static_num_of_col_int \c@jCol + } +% \end{macrocode} +% +% \medskip +% Now, we replace |\columncolor| by |\@@_columncolor_preamble|. +% \begin{macrocode} + \bool_if:NT \l_@@_colortbl_like_bool + { + \regex_replace_all:NnN + \c_@@_columncolor_regex + { \c { @@_columncolor_preamble } } + \g_@@_preamble_tl + } +% \end{macrocode} +% +% \bigskip +% We complete the preamble with the potential ``exterior columns''. +% \begin{macrocode} + \int_compare:nNnTF \l_@@_first_col_int = 0 + { \tl_gput_left:NV \g_@@_preamble_tl \c_@@_preamble_first_col_tl } + { + \bool_lazy_all:nT + { + \l_@@_NiceArray_bool + { \bool_not_p:n \l_@@_NiceTabular_bool } + { \bool_not_p:n \l_@@_vlines_bool } + { \bool_not_p:n \l_@@_exterior_arraycolsep_bool } + } + { \tl_gput_left:Nn \g_@@_preamble_tl { @ { } } } + } + \int_compare:nNnTF \l_@@_last_col_int > { -1 } + { \tl_gput_right:NV \g_@@_preamble_tl \c_@@_preamble_last_col_tl } + { + \bool_lazy_all:nT + { + \l_@@_NiceArray_bool + { \bool_not_p:n \l_@@_NiceTabular_bool } + { \bool_not_p:n \l_@@_vlines_bool } + { \bool_not_p:n \l_@@_exterior_arraycolsep_bool } + } + { \tl_gput_right:Nn \g_@@_preamble_tl { @ { } } } + } +% \end{macrocode} +% We add a last column to raise a good error message when the user put more +% columns than allowed by its preamble. However, for technical reasons, it's not +% possible to do that in |{NiceTabular*}| (|\l_@@_tabular_width_dim|=0pt). +% \begin{macrocode} + \dim_compare:nNnT \l_@@_tabular_width_dim = \c_zero_dim + { + \tl_gput_right:Nn + \g_@@_preamble_tl + { > { \@@_error_too_much_cols: } l } + } +% \end{macrocode} +% +% \medskip +% Now, we have to close the TeX group which was opened for the redefinition of +% the columns of type |w| and |W|. +% \begin{macrocode} + \group_end: + } +% \end{macrocode} +% +% \bigskip +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_preamble:n #1 + { + \str_case:nnF { #1 } + { + c { \@@_patch_preamble_i:n #1 } + l { \@@_patch_preamble_i:n #1 } + r { \@@_patch_preamble_i:n #1 } + > { \@@_patch_preamble_ii:nn #1 } + ! { \@@_patch_preamble_ii:nn #1 } + @ { \@@_patch_preamble_ii:nn #1 } + | { \@@_patch_preamble_iii:n #1 } + p { \@@_patch_preamble_iv:nnn t #1 } + m { \@@_patch_preamble_iv:nnn c #1 } + b { \@@_patch_preamble_iv:nnn b #1 } + \@@_w: { \@@_patch_preamble_v:nnnn { } #1 } + \@@_W: { \@@_patch_preamble_v:nnnn { \cs_set_eq:NN \hss \hfil } #1 } + \@@_true_c: { \@@_patch_preamble_vi:n #1 } + ( { \@@_patch_preamble_vii:n #1 } + [ { \@@_patch_preamble_vii:n #1 } + \{ { \@@_patch_preamble_vii:n #1 } + ) { \@@_patch_preamble_viii:n #1 } + ] { \@@_patch_preamble_viii:n #1 } + \} { \@@_patch_preamble_viii:n #1 } + C { \@@_error:nn { old~column~type } #1 } + L { \@@_error:nn { old~column~type } #1 } + R { \@@_error:nn { old~column~type } #1 } + \q_stop { } + } + { + \str_if_eq:VnTF \l_@@_letter_for_dotted_lines_str { #1 } + { \@@_patch_preamble_xi:n #1 } + { + \bool_lazy_and:nnTF + { \str_if_eq_p:nn { : } { #1 } } + \c_@@_arydshln_loaded_bool + { + \tl_gput_right:Nn \g_@@_preamble_tl { : } + \@@_patch_preamble:n + } + { \@@_fatal:nn { unknown~column~type } { #1 } } + } + } + } +% \end{macrocode} +% +% \medskip +% For |c|, |l| and |r| +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_preamble_i:n #1 + { + \tl_gput_right:Nn \g_@@_preamble_tl + { + > { \@@_Cell: \tl_set:Nn \l_@@_cell_type_tl { #1 } } + #1 + < \@@_end_Cell: + } +% \end{macrocode} +% +% We increment the counter of columns and then we test for the presence of a |<|. +% \begin{macrocode} + \int_gincr:N \c@jCol + \@@_patch_preamble_x:n + } +% \end{macrocode} +% +% \medskip +% For |>|, |!| and |@| +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_preamble_ii:nn #1 #2 + { + \tl_gput_right:Nn \g_@@_preamble_tl { #1 { #2 } } + \@@_patch_preamble:n + } +% \end{macrocode} +% +% +% \medskip +% For \verb+|+ +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_preamble_iii:n #1 + { +% \end{macrocode} +% |\l_tmpa_int| is the number of successive occurrences of \verb+|+ +% \begin{macrocode} + \int_incr:N \l_tmpa_int + \@@_patch_preamble_iii_i:n + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_preamble_iii_i:n #1 + { + \str_if_eq:nnTF { #1 } | + { \@@_patch_preamble_iii:n | } + { + \tl_gput_right:Nx \g_@@_preamble_tl + { + \exp_not:N ! + { + \skip_horizontal:n + { + \dim_eval:n + { + \arrayrulewidth * \l_tmpa_int + + \doublerulesep * ( \l_tmpa_int - 1) + } + } + } + } + \tl_gput_right:Nx \g_@@_internal_code_after_tl + { \@@_vline:nn { \@@_succ:n \c@jCol } { \int_use:N \l_tmpa_int } } + \int_zero:N \l_tmpa_int + \@@_patch_preamble:n #1 + } + } +% \end{macrocode} +% +% +% \medskip +% For |p|, |m| and |b| +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_preamble_iv:nnn #1 #2 #3 + { + \tl_gput_right:Nn \g_@@_preamble_tl + { + > { + \@@_Cell: + \begin { minipage } [ #1 ] { #3 } + \mode_leave_vertical: + \arraybackslash % added in the version 5.8 + \box_use:N \@arstrutbox + } + c + < { \box_use:N \@arstrutbox \end { minipage } \@@_end_Cell: } + } +% \end{macrocode} +% We increment the counter of columns, and then we test for the presence of a |<|. +% \begin{macrocode} + \int_gincr:N \c@jCol + \@@_patch_preamble_x:n + } +% \end{macrocode} +% +% \medskip +% For |w| and |W| +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_preamble_v:nnnn #1 #2 #3 #4 + { + \tl_gput_right:Nn \g_@@_preamble_tl + { + > { + \hbox_set:Nw \l_@@_cell_box + \@@_Cell: + \tl_set:Nn \l_@@_cell_type_tl { #3 } + } + c + < { + \@@_end_Cell: + #1 + \hbox_set_end: + \bool_if:NT \g_@@_rotate_bool \@@_rotate_cell_box: + \@@_adjust_size_box: + \makebox [ #4 ] [ #3 ] { \box_use_drop:N \l_@@_cell_box } + } + } +% \end{macrocode} +% We increment the counter of columns and then we test for the presence of a |<|. +% \begin{macrocode} + \int_gincr:N \c@jCol + \@@_patch_preamble_x:n + } +% \end{macrocode} +% +% \medskip +% For |\@@_true_c:| which will appear in our redefinition of the columns of type +% |S| (of \pkg{siunitx}). +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_preamble_vi:n #1 + { + \tl_gput_right:Nn \g_@@_preamble_tl { c } +% \end{macrocode} +% We increment the counter of columns and then we test for the presence of a |<|. +% \begin{macrocode} + \int_gincr:N \c@jCol + \@@_patch_preamble_x:n + } +% \end{macrocode} +% +% \medskip +% For |(|, |[| and |\{|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_preamble_vii:n #1 + { + \bool_if:NT \l_@@_small_bool + { \@@_fatal:n { Delimiter~with~small } } +% \end{macrocode} +% If we are before the column 1, we reserve space for the left delimiter. +% \begin{macrocode} + \int_compare:nNnT \c@jCol = \c_zero_int + { \tl_gput_right:Nx \g_@@_preamble_tl { ! { \enskip } } } + \tl_gput_right:Nx \g_@@_internal_code_after_tl + { \@@_delimiter:nnn #1 { \@@_succ:n \c@jCol } \c_true_bool } + \@@_patch_preamble:n + } +% \end{macrocode} +% +% \bigskip +% For |)|, |]| and |\}|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_preamble_viii:n #1 + { + \bool_if:NT \l_@@_small_bool + { \@@_fatal:n { Delimiter~with~small } } + \tl_gput_right:Nx \g_@@_internal_code_after_tl + { \@@_delimiter:nnn #1 { \int_use:N \c@jCol } \c_false_bool } +% \end{macrocode} +% After this closing delimiter, we have to test whether there is a opening +% delimiter (we consider that there can't be a second closing delimiter) in +% order to add an horizontal space (equal to 0.5 em). +% \begin{macrocode} + \@@_patch_preamble_viii_i:n + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_preamble_viii_i:n #1 + { + \bool_lazy_any:nT + { + { \str_if_eq_p:nn { #1 } ( } + { \str_if_eq_p:nn { #1 } [ } + { \str_if_eq_p:nn { #1 } \{ } + { \str_if_eq_p:nn { #1 } \q_stop } + } + { \tl_gput_right:Nn \g_@@_preamble_tl { ! { \enskip } } } + \@@_patch_preamble:n #1 + } +% \end{macrocode} +% +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_preamble_xi:n #1 + { + \tl_gput_right:Nn \g_@@_preamble_tl + { ! { \skip_horizontal:N 2\l_@@_radius_dim } } +% \end{macrocode} +% The command |\@@_vdottedline:n| is protected, and, therefore, won't be +% expanded before writing on |\g_@@_internal_code_after_tl|. +% \begin{macrocode} + \tl_gput_right:Nx \g_@@_internal_code_after_tl + { \@@_vdottedline:n { \int_use:N \c@jCol } } + \@@_patch_preamble:n + } +% \end{macrocode} +% +% After a specifier of column, we have to test whether there is one or several +% |<{..}| because, after those potential |<{...}|, we have to insert +% |!{\skip_horizontal:N ...}| when the key |vlines| is used. +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_preamble_x:n #1 + { + \str_if_eq:nnTF { #1 } { < } + \@@_patch_preamble_ix:n + { + \bool_if:NT \l_@@_vlines_bool + { + \tl_gput_right:Nn \g_@@_preamble_tl + { ! { \skip_horizontal:N \arrayrulewidth } } + } + \@@_patch_preamble:n { #1 } + } + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_patch_preamble_ix:n #1 + { + \tl_gput_right:Nn \g_@@_preamble_tl { < { #1 } } + \@@_patch_preamble_x:n + } +% \end{macrocode} +% +% +% % \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. @@ -5139,11 +8269,237 @@ version 2005/12/01 or later. { \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 } + \tl_if_eq:NnTF \l_@@_baseline_tl { c } + { \box_use_drop:N \l_tmpa_box } + \@@_put_box_in_flow_i: + } +% \end{macrocode} +% +% \medskip +% The command |\@@_put_box_in_flow_i:| is used when the value of +% |\l_@@_baseline_tl| is different of |c| (which is the initial value and the +% most used). +% \begin{macrocode} +\cs_new_protected:Npn \@@_put_box_in_flow_i: + { + \pgfpicture + \@@_qpoint:n { row - 1 } + \dim_gset_eq:NN \g_tmpa_dim \pgf@y + \@@_qpoint:n { row - \@@_succ:n \c@iRow } + \dim_gadd:Nn \g_tmpa_dim \pgf@y + \dim_gset:Nn \g_tmpa_dim { 0.5 \g_tmpa_dim } +% \end{macrocode} +% Now, |\g_tmpa_dim| contains the $y$-value of the center of the array (the +% delimiters are centered in relation with this value). +% \begin{macrocode} + \str_if_in:NnTF \l_@@_baseline_tl { line- } + { + \int_set:Nn \l_tmpa_int + { + \str_range:Nnn + \l_@@_baseline_tl + 6 + { \tl_count:V \l_@@_baseline_tl } + } + \@@_qpoint:n { row - \int_use:N \l_tmpa_int } + } + { + \str_case:VnF \l_@@_baseline_tl + { + { t } { \int_set:Nn \l_tmpa_int 1 } + { b } { \int_set_eq:NN \l_tmpa_int \c@iRow } + } + { \int_set:Nn \l_tmpa_int \l_@@_baseline_tl } + \bool_lazy_or:nnT + { \int_compare_p:nNn \l_tmpa_int < \l_@@_first_row_int } + { \int_compare_p:nNn \l_tmpa_int > \g_@@_row_total_int } + { + \@@_error:n { bad~value~for~baseline } + \int_set:Nn \l_tmpa_int 1 + } + \@@_qpoint:n { row - \int_use:N \l_tmpa_int - base } +% \end{macrocode} +% We take into account the position of the mathematical axis. +% \begin{macrocode} + \dim_gsub:Nn \g_tmpa_dim { \fontdimen22 \textfont2 } + } + \dim_gsub:Nn \g_tmpa_dim \pgf@y +% \end{macrocode} +% Now, |\g_tmpa_dim| contains the value of the $y$ translation we have to to. +% \begin{macrocode} + \endpgfpicture + \box_move_up:nn \g_tmpa_dim { \box_use_drop:N \l_tmpa_box } \box_use_drop:N \l_tmpa_box } % \end{macrocode} % % \bigskip +% The following command is \emph{always} used by |{NiceArrayWithDelims}| (even +% if, in fact, there is no tabular notes: in fact, it's not possible to know +% whether there is tabular notes or not before the composition of the blocks). +% \begin{macrocode} +\cs_new_protected:Npn \@@_use_arraybox_with_notes_c: + { +% \end{macrocode} +% We need a |{minipage}| because we will insert a LaTeX list for the tabular +% notes (that means that a |\vtop{\hsize=...}| is not enough). +% \begin{macrocode} + \begin { minipage } [ t ] { \box_wd:N \l_@@_the_array_box } + \box_use_drop:N \l_@@_the_array_box +% \end{macrocode} +% We have to draw the blocks right now because there may be tabular notes in +% some blocks (which are not mono-column: the blocks which are mono-column +% have been composed in boxes yet)... and we have to create (potentially) the +% extra nodes before creating the blocks since there are |medium| nodes to create +% for the blocks. +% \begin{macrocode} + \@@_create_extra_nodes: + \seq_if_empty:NF \g_@@_blocks_seq \@@_draw_blocks: + \bool_lazy_or:nnT + { \int_compare_p:nNn \c@tabularnote > 0 } + { ! \tl_if_empty_p:V \l_@@_tabularnote_tl } + \@@_insert_tabularnotes: + \end { minipage } + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_insert_tabularnotes: + { + \skip_vertical:N 0.65ex +% \end{macrocode} +% The TeX group is for potential specifications in the +% |\l_@@_notes_code_before_tl|. +% \begin{macrocode} + \group_begin: + \l_@@_notes_code_before_tl + \tl_if_empty:NF \l_@@_tabularnote_tl { \l_@@_tabularnote_tl \par } +% \end{macrocode} +% We compose the tabular notes with a list of \pkg{enumitem}. The |\strut| and +% the |\unskip| are designed to give the ability to put a |\bottomrule| at the +% end of the notes with a good vertical space. +% \begin{macrocode} + \int_compare:nNnT \c@tabularnote > 0 + { + \bool_if:NTF \l_@@_notes_para_bool + { + \begin { tabularnotes* } + \seq_map_inline:Nn \g_@@_tabularnotes_seq { \item ##1 } \strut + \end { tabularnotes* } +% \end{macrocode} +% The following |\par| is mandatory for the event that the user has put +% |\footnotesize| (for example) in the |notes/code-before|. +% \begin{macrocode} + \par + } + { + \tabularnotes + \seq_map_inline:Nn \g_@@_tabularnotes_seq { \item ##1 } \strut + \endtabularnotes + } + } + \unskip + \group_end: + \bool_if:NT \l_@@_notes_bottomrule_bool + { + \bool_if:NTF \c_@@_booktabs_loaded_bool + { +% \end{macrocode} +% The two dimensions |\aboverulesep| et |\heavyrulewidth| are parameters defined +% by \pkg{booktabs}. +% \begin{macrocode} + \skip_vertical:N \aboverulesep +% \end{macrocode} +% |\CT@arc@| is the specification of color defined by \pkg{colortbl} but you use it +% even if \pkg{colortbl} is not loaded. +% \begin{macrocode} + { \CT@arc@ \hrule height \heavyrulewidth } + } + { \@@_error:n { bottomrule~without~booktabs } } + } + \l_@@_notes_code_after_tl + \seq_gclear:N \g_@@_tabularnotes_seq + \int_gzero:N \c@tabularnote + } +% \end{macrocode} +% +% \medskip +% The case of |baseline| equal to |b|. 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} +\cs_new_protected:Npn \@@_use_arraybox_with_notes_b: + { + \pgfpicture + \@@_qpoint:n { row - 1 } + \dim_gset_eq:NN \g_tmpa_dim \pgf@y + \@@_qpoint:n { row - \int_use:N \c@iRow - base } + \dim_gsub:Nn \g_tmpa_dim \pgf@y + \endpgfpicture + \dim_gadd:Nn \g_tmpa_dim \arrayrulewidth + \int_compare:nNnT \l_@@_first_row_int = 0 + { + \dim_gadd:Nn \g_tmpa_dim \g_@@_ht_row_zero_dim + \dim_gadd:Nn \g_tmpa_dim \g_@@_dp_row_zero_dim + } + \box_move_up:nn \g_tmpa_dim { \hbox { \@@_use_arraybox_with_notes_c: } } + } +% \end{macrocode} +% +% \medskip +% Now, the general case. +% \begin{macrocode} +\cs_new_protected:Npn \@@_use_arraybox_with_notes: + { +% \end{macrocode} +% We convert a value of |t| to a value of |1|. +% \begin{macrocode} + \tl_if_eq:NnT \l_@@_baseline_tl { t } + { \tl_set:Nn \l_@@_baseline_tl { 1 } } +% \end{macrocode} +% Now, we convert the value of |\l_@@_baseline_tl| (which should represent an +% integer) to an integer stored in |\l_tmpa_int|. +% \begin{macrocode} + \pgfpicture + \@@_qpoint:n { row - 1 } + \dim_gset_eq:NN \g_tmpa_dim \pgf@y + \str_if_in:NnTF \l_@@_baseline_tl { line- } + { + \int_set:Nn \l_tmpa_int + { + \str_range:Nnn + \l_@@_baseline_tl + 6 + { \tl_count:V \l_@@_baseline_tl } + } + \@@_qpoint:n { row - \int_use:N \l_tmpa_int } + } + { + \int_set:Nn \l_tmpa_int \l_@@_baseline_tl + \bool_lazy_or:nnT + { \int_compare_p:nNn \l_tmpa_int < \l_@@_first_row_int } + { \int_compare_p:nNn \l_tmpa_int > \g_@@_row_total_int } + { + \@@_error:n { bad~value~for~baseline } + \int_set:Nn \l_tmpa_int 1 + } + \@@_qpoint:n { row - \int_use:N \l_tmpa_int - base } + } + \dim_gsub:Nn \g_tmpa_dim \pgf@y + \endpgfpicture + \dim_gadd:Nn \g_tmpa_dim \arrayrulewidth + \int_compare:nNnT \l_@@_first_row_int = 0 + { + \dim_gadd:Nn \g_tmpa_dim \g_@@_ht_row_zero_dim + \dim_gadd:Nn \g_tmpa_dim \g_@@_dp_row_zero_dim + } + \box_move_up:nn \g_tmpa_dim { \hbox { \@@_use_arraybox_with_notes_c: } } + } +% \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 @@ -5166,7 +8522,7 @@ version 2005/12/01 or later. { \box_ht:N \l_tmpa_box + \box_dp:N \l_tmpa_box } { } } - \right . + \right . \c_math_toggle_token } \dim_set:Nn \l_@@_real_left_delim_dim @@ -5199,9 +8555,9 @@ version 2005/12/01 or later. % \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). +% |{@@-normal-syntax}| (whether the option |light-syntax| is in force 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 array). % \begin{macrocode} \NewDocumentEnvironment { @@-normal-syntax } { } % \end{macrocode} @@ -5212,13 +8568,12 @@ version 2005/12/01 or later. % by LaTeX for incorrect nested environments). % \begin{macrocode} { - \peek_meaning_ignore_spaces:NTF \end - { \@@_analyze_end:Nn } + \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: \g_@@_preamble_tl } } { \@@_create_col_nodes: @@ -5228,8 +8583,9 @@ version 2005/12/01 or later. % % % \bigskip -% When the key |light-syntax| is used, we use an environment which takes its whole -% body as an argument (with the specifier |b| of \pkg{xparse}). +% When the key |light-syntax| is in force, we use an environment which takes its +% whole body as an argument (with the specifier |b| of \pkg{xparse}). +% % \label{code-light-syntax} % \begin{macrocode} \NewDocumentEnvironment { @@-light-syntax } { b } { @@ -5241,14 +8597,38 @@ version 2005/12/01 or later. \tl_if_empty:nT { #1 } { \@@_fatal:n { empty~environment } } \tl_map_inline:nn { #1 } { - \tl_if_eq:nnT { ##1 } { & } + \str_if_eq:nnT { ##1 } { & } { \@@_fatal:n { ampersand~in~light-syntax } } - \tl_if_eq:nnT { ##1 } { \\ } + \str_if_eq:nnT { ##1 } { \\ } { \@@_fatal:n { double-backslash~in~light-syntax } } } % \end{macrocode} -% The body of the environment, which is stored in the argument |#1|, is now -% splitted into items (and \emph{not} tokens) +% Now, you extract the |code-after| of the body of the environment. Maybe, there +% is no command |\CodeAfter| in the body. That's why you put a marker +% |\CodeAfter| after |#1|. If there is yet a |\CodeAfter| in |#1|, this second +% (or third...) |\CodeAfter| will be catched in the value of +% |\g_nicematrix_code_after_tl|. That doesn't matter because |\CodeAfter| will +% be set to \textsl{no-op} before the execution of +% |\g_nicematrix_code_after_tl|. +% \begin{macrocode} + \@@_light_syntax_i #1 \CodeAfter \q_stop + } +% \end{macrocode} +% Now, the second part of the environment. It is empty. That's not surprising +% because we have caught the whole body of the environment with the specifier +% |b| provided by \pkg{xparse}. +% \begin{macrocode} + { } +% \end{macrocode} +% +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_light_syntax_i #1\CodeAfter #2\q_stop + { + \tl_gput_right:Nn \g_nicematrix_code_after_tl { #2 } +% \end{macrocode} +% The body of the array, which is stored in the argument |#1|, is now +% splitted into items (and \emph{not} tokens). % \begin{macrocode} \seq_gclear_new:N \g_@@_rows_seq \tl_set_rescan:Nno \l_@@_end_of_row_tl { } \l_@@_end_of_row_tl @@ -5265,7 +8645,7 @@ version 2005/12/01 or later. % 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: \g_@@_preamble_tl % \end{macrocode} % We need a global affectation because, when executing |\l_tmpa_tl|, we will % exit the first cell of the array. @@ -5277,11 +8657,10 @@ version 2005/12/01 or later. \endarray } % \end{macrocode} -% Now, the second part of the environment. It is empty. That's not surprising -% because we have caught the whole body of the environment with the specifier -% |b| provided by \pkg{xparse}. +% % \begin{macrocode} - { } +\cs_new_protected:Npn \@@_line_with_light_syntax:n #1 + { \tl_if_empty:nF { #1 } { \\ \@@_line_with_light_syntax_i:n { #1 } } } % \end{macrocode} % % \begin{macrocode} @@ -5291,22 +8670,10 @@ version 2005/12/01 or later. \seq_gset_split:Nnn \g_@@_cells_seq { ~ } { #1 } \seq_gpop_left:NN \g_@@_cells_seq \l_tmpa_tl \l_tmpa_tl - \seq_map_function:NN \g_@@_cells_seq \@@_cell_with_light_syntax:n + \seq_map_inline:Nn \g_@@_cells_seq { & ##1 } } % \end{macrocode} -% -% \begin{macrocode} -\cs_new_protected:Npn \@@_line_with_light_syntax:n #1 - { - \tl_if_empty:nF { #1 } - { \\ \@@_line_with_light_syntax_i:n { #1 } } - } -% \end{macrocode} % -% \begin{macrocode} -\cs_new_protected:Npn \@@_cell_with_light_syntax:n #1 { & #1 } -% \end{macrocode} -% % \bigskip % 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 @@ -5326,30 +8693,77 @@ version 2005/12/01 or later. % % \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 +% 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 & } + \int_compare:nNnT \l_@@_first_col_int = 0 + { + \omit + \hbox_overlap_left:n + { + \bool_if:NT \l_@@_code_before_bool + { \pgfsys@markposition { \@@_env: - col - 0 } } + \pgfpicture + \pgfrememberpicturepositiononpagetrue + \pgfcoordinate { \@@_env: - col - 0 } \pgfpointorigin + \str_if_empty:NF \l_@@_name_str + { \pgfnodealias { \l_@@_name_str - col - 0 } { \@@_env: - col - 0 } } + \endpgfpicture + \skip_horizontal:N 2\col@sep + \skip_horizontal:N \g_@@_width_first_col_dim + } + & + } \omit % \end{macrocode} % The following instruction must be put after the instruction |\omit|. % \begin{macrocode} \bool_gset_true:N \g_@@_row_of_col_done_bool % \end{macrocode} -% First, we put a ``|col|'' node on the left of the first column (of course, we +% 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} - \pgfpicture - \pgfrememberpicturepositiononpagetrue - \pgfcoordinate { \@@_env: - col - 1 } \pgfpointorigin - \str_if_empty:NF \l_@@_name_str - { \pgfnodealias { \@@_env: - col - 1 } { \l_@@_name_str - col - 1 } } - \endpgfpicture + \int_compare:nNnTF \l_@@_first_col_int = 0 + { + \bool_if:NT \l_@@_code_before_bool + { + \hbox + { + \skip_horizontal:N -0.5\arrayrulewidth + \pgfsys@markposition { \@@_env: - col - 1 } + \skip_horizontal:N 0.5\arrayrulewidth + } + } + \pgfpicture + \pgfrememberpicturepositiononpagetrue + \pgfcoordinate { \@@_env: - col - 1 } + { \pgfpoint { - 0.5 \arrayrulewidth } \c_zero_dim } + \str_if_empty:NF \l_@@_name_str + { \pgfnodealias { \l_@@_name_str - col - 1 } { \@@_env: - col - 1 } } + \endpgfpicture + } + { + \bool_if:NT \l_@@_code_before_bool + { + \hbox + { + \skip_horizontal:N 0.5\arrayrulewidth + \pgfsys@markposition { \@@_env: - col - 1 } + \skip_horizontal:N -0.5\arrayrulewidth + } + } + \pgfpicture + \pgfrememberpicturepositiononpagetrue + \pgfcoordinate { \@@_env: - col - 1 } + { \pgfpoint { 0.5 \arrayrulewidth } \c_zero_dim } + \str_if_empty:NF \l_@@_name_str + { \pgfnodealias { \l_@@_name_str - col - 1 } { \@@_env: - col - 1 } } + \endpgfpicture + } % \end{macrocode} % We compute in |\g_tmpa_skip| the common width of the columns (it's a skip and % not a dimension). We use a global variable because we are in a cell of an @@ -5359,7 +8773,7 @@ version 2005/12/01 or later. % % \smallskip % We give a default value for |\g_tmpa_skip| (|0 pt plus 1 fill|) but it will -% just after erased by a fixed value in the concerned cases. +% just after be erased by a fixed value in the concerned cases. % \begin{macrocode} \skip_gset:Nn \g_tmpa_skip { 0 pt~plus 1 fill } \bool_if:NF \l_@@_auto_columns_width_bool @@ -5370,16 +8784,26 @@ version 2005/12/01 or later. { \bool_not_p:n \l_@@_block_auto_columns_width_bool } { \skip_gset_eq:NN \g_tmpa_skip \g_@@_max_cell_width_dim } { \skip_gset_eq:NN \g_tmpa_skip \l_@@_columns_width_dim } - \skip_gadd:Nn \g_tmpa_skip { 2 \arraycolsep } + \skip_gadd:Nn \g_tmpa_skip { 2 \col@sep } } - \skip_horizontal:N \g_tmpa_skip + \skip_horizontal:N \g_tmpa_skip \hbox { + \bool_if:NT \l_@@_code_before_bool + { + \hbox + { + \skip_horizontal:N -0.5\arrayrulewidth + \pgfsys@markposition { \@@_env: - col - 2 } + \skip_horizontal:N 0.5\arrayrulewidth + } + } \pgfpicture \pgfrememberpicturepositiononpagetrue - \pgfcoordinate { \@@_env: - col - 2 } \pgfpointorigin + \pgfcoordinate { \@@_env: - col - 2 } + { \pgfpoint { - 0.5 \arrayrulewidth } \c_zero_dim } \str_if_empty:NF \l_@@_name_str - { \pgfnodealias { \@@_env: - col - 2 } { \l_@@_name_str - col - 2 } } + { \pgfnodealias { \l_@@_name_str - col - 2 } { \@@_env: - col - 2 } } \endpgfpicture } % \end{macrocode} @@ -5391,28 +8815,61 @@ version 2005/12/01 or later. { \prg_replicate:nn { \g_@@_col_total_int - 2 } } { \prg_replicate:nn { \g_@@_col_total_int - 1 } } { - & - \omit + & + \omit + \int_gincr:N \g_tmpa_int % \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_skip + \skip_horizontal:N \g_tmpa_skip + \bool_if:NT \l_@@_code_before_bool + { + \hbox + { + \skip_horizontal:N -0.5\arrayrulewidth + \pgfsys@markposition { \@@_env: - col - \@@_succ:n \g_tmpa_int } + \skip_horizontal:N 0.5\arrayrulewidth + } + } % \end{macrocode} -% We create the ``|col|'' node on the right of the current column. +% We create the |col| node on the right of the current column. % \begin{macrocode} - \pgfpicture - \pgfrememberpicturepositiononpagetrue - \pgfcoordinate { \@@_env: - col - \@@_succ:n \g_tmpa_int } - \pgfpointorigin - \str_if_empty:NF \l_@@_name_str - { - \pgfnodealias - { \@@_env: - col - \@@_succ:n \g_tmpa_int } - { \l_@@_name_str - col - \@@_succ:n \g_tmpa_int } - } - \endpgfpicture + \pgfpicture + \pgfrememberpicturepositiononpagetrue + \pgfcoordinate { \@@_env: - col - \@@_succ:n \g_tmpa_int } + { \pgfpoint { - 0.5 \arrayrulewidth } \c_zero_dim } + \str_if_empty:NF \l_@@_name_str + { + \pgfnodealias + { \l_@@_name_str - col - \@@_succ:n \g_tmpa_int } + { \@@_env: - col - \@@_succ:n \g_tmpa_int } + } + \endpgfpicture + } + \bool_if:NT \g_@@_last_col_found_bool + { + \hbox_overlap_right:n + { + % \skip_horizontal:N \col@sep + \skip_horizontal:N \g_@@_width_last_col_dim + \bool_if:NT \l_@@_code_before_bool + { + \pgfsys@markposition + { \@@_env: - col - \@@_succ:n \g_@@_col_total_int } + } + \pgfpicture + \pgfrememberpicturepositiononpagetrue + \pgfcoordinate { \@@_env: - col - \@@_succ:n \g_@@_col_total_int } + \pgfpointorigin + \str_if_empty:NF \l_@@_name_str + { + \pgfnodealias + { \l_@@_name_str - col - \@@_succ:n \g_@@_col_total_int } + { \@@_env: - col - \@@_succ:n \g_@@_col_total_int } + } + \endpgfpicture + } } \cr } @@ -5427,13 +8884,14 @@ version 2005/12/01 or later. { > { + \bool_gset_true:N \g_@@_after_col_zero_bool \@@_begin_of_row: % \end{macrocode} % 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_@@_cell_box - \c_math_toggle_token + \@@_math_toggle_token: \bool_if:NT \l_@@_small_bool \scriptstyle % \end{macrocode} % We insert |\l_@@_code_for_first_col_tl|... but we don't insert it in the @@ -5458,8 +8916,10 @@ version 2005/12/01 or later. l < { - \c_math_toggle_token + \@@_math_toggle_token: \hbox_set_end: + \bool_if:NT \g_@@_rotate_bool \@@_rotate_cell_box: + \@@_adjust_size_box: \@@_update_for_first_and_last_row: % \end{macrocode} % We actualise the width of the ``first column'' because we will use this width @@ -5480,7 +8940,8 @@ version 2005/12/01 or later. \skip_horizontal:N \l_@@_left_margin_dim \skip_horizontal:N \l_@@_extra_left_margin_dim } - \skip_horizontal:N -2\arraycolsep + \bool_gset_false:N \g_@@_empty_cell_bool + \skip_horizontal:N -2\col@sep } } % \end{macrocode} @@ -5505,7 +8966,7 @@ version 2005/12/01 or later. % have to compute some dimensions of this box. % \begin{macrocode} \hbox_set:Nw \l_@@_cell_box - \c_math_toggle_token + \@@_math_toggle_token: \bool_if:NT \l_@@_small_bool \scriptstyle % \end{macrocode} % We insert |\l_@@_code_for_last_col_tl|... but we don't insert it in the @@ -5525,8 +8986,10 @@ version 2005/12/01 or later. l < { - \c_math_toggle_token + \@@_math_toggle_token: \hbox_set_end: + \bool_if:NT \g_@@_rotate_bool \@@_rotate_cell_box: + \@@_adjust_size_box: \@@_update_for_first_and_last_row: % \end{macrocode} % We actualise the width of the ``last column'' because we will use this width @@ -5534,7 +8997,7 @@ version 2005/12/01 or later. % \begin{macrocode} \dim_gset:Nn \g_@@_width_last_col_dim { \dim_max:nn \g_@@_width_last_col_dim { \box_wd:N \l_@@_cell_box } } - \skip_horizontal:N -2\arraycolsep + \skip_horizontal:N -2\col@sep % \end{macrocode} % The content of the cell is inserted in an overlapping position. % \label{overlap-right} @@ -5549,6 +9012,7 @@ version 2005/12/01 or later. \@@_node_for_the_cell: } } + \bool_gset_false:N \g_@@_empty_cell_bool } } % \end{macrocode} @@ -5580,81 +9044,37 @@ version 2005/12/01 or later. % We create the variants of the environment |{NiceArrayWithDelims}|. % % \begin{macrocode} -\NewDocumentEnvironment { pNiceArray } { } - { - \str_if_empty:NT \g_@@_name_env_str - { \str_gset:Nn \g_@@_name_env_str { pNiceArray } } - \@@_test_if_math_mode: - \NiceArrayWithDelims ( ) - } - { \endNiceArrayWithDelims } -% \end{macrocode} -% -% \begin{macrocode} -\NewDocumentEnvironment { bNiceArray } { } - { - \str_if_empty:NT \g_@@_name_env_str - { \str_gset:Nn \g_@@_name_env_str { bNiceArray } } - \@@_test_if_math_mode: - \NiceArrayWithDelims [ ] - } - { \endNiceArrayWithDelims } -% \end{macrocode} -% -% \begin{macrocode} -\NewDocumentEnvironment { BNiceArray } { } +\cs_new_protected:Npn \@@_def_env:nnn #1 #2 #3 { - \str_if_empty:NT \g_@@_name_env_str - { \str_gset:Nn \g_@@_name_env_str { BNiceArray } } - \@@_test_if_math_mode: - \NiceArrayWithDelims \{ \} - } - { \endNiceArrayWithDelims } -% \end{macrocode} -% -% \begin{macrocode} -\NewDocumentEnvironment { vNiceArray } { } - { - \str_if_empty:NT \g_@@_name_env_str - { \str_gset:Nn \g_@@_name_env_str { vNiceArray } } - \@@_test_if_math_mode: - \NiceArrayWithDelims | | + \NewDocumentEnvironment { #1 NiceArray } { } + { + \str_if_empty:NT \g_@@_name_env_str + { \str_gset:Nn \g_@@_name_env_str { #1 NiceArray } } + \@@_test_if_math_mode: + \NiceArrayWithDelims #2 #3 + } + { \endNiceArrayWithDelims } } - { \endNiceArrayWithDelims } % \end{macrocode} % % \begin{macrocode} -\NewDocumentEnvironment { VNiceArray } { } - { - \str_if_empty:NT \g_@@_name_env_str - { \str_gset:Nn \g_@@_name_env_str { VNiceArray } } - \@@_test_if_math_mode: - \NiceArrayWithDelims \| \| - } - { \endNiceArrayWithDelims } +\@@_def_env:nnn p ( ) +\@@_def_env:nnn b [ ] +\@@_def_env:nnn B \{ \} +\@@_def_env:nnn v | | +\@@_def_env:nnn V \| \| % \end{macrocode} +% % % \bigskip % \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_@@_name_env_str { #1 NiceMatrix } - \tl_set:Nn \l_@@_type_of_col_tl C - \keys_set:nn { NiceMatrix / NiceMatrix } { ##1 } - \exp_args:Nnx \@@_begin_of_NiceMatrix:nn { #1 } \l_@@_type_of_col_tl - } - { \end { #1 NiceArray } } - } -% \end{macrocode} % % \begin{macrocode} \cs_new_protected:Npn \@@_begin_of_NiceMatrix:nn #1 #2 { - \begin { #1 NiceArray } + \bool_set_true:N \l_@@_Matrix_bool + \use:c { #1 NiceArray } { * { @@ -5662,21 +9082,59 @@ version 2005/12/01 or later. \c@MaxMatrixCols { \@@_pred:n \l_@@_last_col_int } } - #2 + { > \@@_Cell: #2 < \@@_end_Cell: } } } % \end{macrocode} % % \begin{macrocode} -\@@_define_env:n { } -\@@_define_env:n p -\@@_define_env:n b -\@@_define_env:n B -\@@_define_env:n v -\@@_define_env:n V +\clist_map_inline:nn { { } , p , b , B , v , V } + { + \NewDocumentEnvironment { #1 NiceMatrix } { ! O { } } + { + \str_gset:Nn \g_@@_name_env_str { #1 NiceMatrix } + \tl_set:Nn \l_@@_type_of_col_tl c + \keys_set:nn { NiceMatrix / NiceMatrix } { ##1 } + \exp_args:Nne \@@_begin_of_NiceMatrix:nn { #1 } \l_@@_type_of_col_tl + } + { \use:c { end #1 NiceArray } } + } % \end{macrocode} % -% +% \bigskip +% The following command will be linked to |\NotEmpty| in the environments of +% \pkg{nicematrix}. +% \begin{macrocode} +\cs_new_protected:Npn \@@_NotEmpty: + { \bool_gset_true:N \g_@@_not_empty_cell_bool } +% \end{macrocode} +% +% \bigskip +% \subsection*{The environments \{NiceTabular\} and \{NiceTabular*\}} +% +% \begin{macrocode} +\NewDocumentEnvironment { NiceTabular } { O { } m ! O { } } + { + \str_gset:Nn \g_@@_name_env_str { NiceTabular } + \keys_set:nn { NiceMatrix / NiceTabular } { #1 , #3 } + \bool_set_true:N \l_@@_NiceTabular_bool + \NiceArray { #2 } + } + { \endNiceArray } +% \end{macrocode} +% +% \bigskip +% \begin{macrocode} +\NewDocumentEnvironment { NiceTabular* } { m O { } m ! O { } } + { + \str_gset:Nn \g_@@_name_env_str { NiceTabular* } + \dim_set:Nn \l_@@_tabular_width_dim { #1 } + \keys_set:nn { NiceMatrix / NiceTabular } { #2 , #4 } + \bool_set_true:N \l_@@_NiceTabular_bool + \NiceArray { #3 } + } + { \endNiceArray } +% \end{macrocode} % % % \bigskip @@ -5762,7 +9220,47 @@ version 2005/12/01 or later. } % \end{macrocode} % +% If the key |code-before| is used, we have to write on the |aux| file the actual +% size of the array. +% \begin{macrocode} + \bool_if:NT \l_@@_code_before_bool + { + \iow_now:Nn \@mainaux \ExplSyntaxOn + \iow_now:Nx \@mainaux + { \seq_clear_new:c { @@_size _ \int_use:N \g_@@_env_int _ seq } } + \iow_now:Nx \@mainaux + { + \seq_gset_from_clist:cn { @@_size _ \int_use:N \g_@@_env_int _ seq } + { + \int_use:N \l_@@_first_row_int , + \int_use:N \g_@@_row_total_int , + \int_use:N \l_@@_first_col_int , +% \end{macrocode} +% If the user has used a key |last-row| in an environment with preamble (like +% |{pNiceArray}|) and that that last row has not been found, we have to +% increment the value because it will be decreased when used in the |code-before|. +% \begin{macrocode} + \bool_lazy_and:nnTF + { \int_compare_p:nNn \l_@@_last_col_int > { -2 } } + { \bool_not_p:n \g_@@_last_col_found_bool } + \@@_succ:n + \int_use:N + \g_@@_col_total_int + } +% \end{macrocode} +% We write also the potential content of |\g_@@_pos_of_blocks_seq| (it will be +% useful if the commands |\rowcolors| is used with the key |respect-blocks|. +% \begin{macrocode} + \seq_gset_from_clist:cn + { c_@@_pos_of_blocks_ \int_use:N \g_@@_env_int _ seq } + { \seq_use:Nnnn \g_@@_pos_of_blocks_seq , , , } + } + \iow_now:Nn \@mainaux \ExplSyntaxOff + } +% \end{macrocode} +% % +% % By default, the diagonal lines will be parallelized\footnote{It's possible to % use the option |parallelize-diags| to disable this parallelization.}. There % are two types of diagonals lines: the $|\Ddots|$ diagonals and the |\Iddots| @@ -5790,13 +9288,6 @@ version 2005/12/01 or later. % \end{macrocode} % % \begin{macrocode} - \bool_if:nTF \l_@@_medium_nodes_bool - { - \bool_if:NTF \l_@@_large_nodes_bool - \@@_create_medium_and_large_nodes: - \@@_create_medium_nodes: - } - { \bool_if:NT \l_@@_large_nodes_bool \@@_create_large_nodes: } \int_zero_new:N \l_@@_initial_i_int \int_zero_new:N \l_@@_initial_j_int \int_zero_new:N \l_@@_final_i_int @@ -5823,23 +9314,60 @@ version 2005/12/01 or later. } % \end{macrocode} % -% % \bigskip -% Now, we really draw the lines. +% Now, we actually draw the dotted lines (specified by |\Cdots|, |\Vdots|, +% etc.). % \begin{macrocode} \@@_draw_dotted_lines: % \end{macrocode} % -% We draw the vertical rules of the option |vlines| before the -% |internal-code-after| because the option |white| of a |\Block| may have to -% erase these vertical rules. +% \bigskip +% The following computes the ``corners'' (made up of empty cells) but if there +% is no corner to compute, it will do nothing. +% \begin{macrocode} + \@@_compute_corners: +% \end{macrocode} +% +% \bigskip +% The sequence |\g_@@_pos_of_blocks_seq| must be ``adjusted'' (for the case +% where the user have written something like |\Block{1-}|). +% \begin{macrocode} + \@@_adjust_pos_of_blocks_seq: +% \end{macrocode} +% +% \bigskip +% The following code is only for efficiency. We determine whether the potential +% horizontal and vertical rules are ``complete'', that is to say drawn in the +% whole array. We are sure that all the rules will be complete when there is no +% block, no virtual block (determined by a command such as |\Cdots|, |\Vdots|, +% etc.) and no corners. In that case, we switch to a shortcut version of +% |\@@_vline_i:nn| and |\@@_hline:nn|. +% \begin{macrocode} + \bool_lazy_all:nT + { + { \seq_if_empty_p:N \g_@@_pos_of_blocks_seq } + { \seq_if_empty_p:N \g_@@_pos_of_xdots_seq } + { \seq_if_empty_p:N \l_@@_empty_corner_cells_seq } + } + { + \cs_set_eq:NN \@@_vline_i:nn \@@_vline_i_complete:nn + \cs_set_eq:NN \@@_hline_i:nn \@@_hline_i_complete:nn + } + \bool_if:NT \l_@@_hlines_bool \@@_draw_hlines: + \bool_if:NT \l_@@_vlines_bool \@@_draw_vlines: +% \end{macrocode} +% % \begin{macrocode} - \bool_if:NT \l_@@_vlines_bool \@@_draw_vlines: \g_@@_internal_code_after_tl \tl_gclear:N \g_@@_internal_code_after_tl +% \end{macrocode} +% +% \bigskip +% Now, the |code-after|. +% \begin{macrocode} \bool_if:NT \c_@@_tikz_loaded_bool { - \tikzset + \tikzset { every~picture / .style = { @@ -5850,15 +9378,125 @@ version 2005/12/01 or later. } } \cs_set_eq:NN \line \@@_line - \g_@@_code_after_tl - \tl_gclear:N \g_@@_code_after_tl + \cs_set_eq:NN \SubMatrix \@@_SubMatrix +% \end{macrocode} +% When |light-syntax| is used, we insert systematically a |\CodeAfter| in the +% flow. Thus, it's possible to have two instructions |\CodeAfter| and the second +% may be in |\g_nicematrix_code_after_tl|. That's why we set +% |\Code-after| to be \textsl{no-op} now. +% \begin{macrocode} + \cs_set_eq:NN \CodeAfter \prg_do_nothing: +% \end{macrocode} +% +% We clear the list of the names of the potential |\SubMatrix| that will appear +% in the |code-after| (unfortunately, that list has to be global). +% \begin{macrocode} + \seq_gclear:N \g_@@_submatrix_names_seq +% \end{macrocode} +% And here's the |code-after|. Since the |code-after| may begin with an +% ``argument'' between square brackets of the options, we extract and treat that +% potential ``argument'' with the command |\@@_CodeAfter_keys:|. +% \begin{macrocode} + \exp_last_unbraced:NV \@@_CodeAfter_keys: \g_nicematrix_code_after_tl + \scan_stop: + \tl_gclear:N \g_nicematrix_code_after_tl \group_end: +% \end{macrocode} +% +% +% \medskip +% |\g_nicematrix_code_before_tl| is for instructions in the cells of the array such as +% |\rowcolor| and |\cellcolor| (when the key |colortbl-like| is in +% force). These instructions will be written on the |aux| file to be added to +% the |code-before| in the next run. +% \begin{macrocode} + \tl_if_empty:NF \g_nicematrix_code_before_tl + { +% \end{macrocode} +% The command |\rowcolor| in tabular will in fact use |\rectanglecolor| in order +% to follow the behaviour of |\rowcolor| of \pkg{colortbl}. That's why there may +% be a command |\rectanglecolor| in |\g_nicematrix_code_before_tl|. In order to avoid an +% error during the expansion, we define a protected version of |\rectanglecolor|. +% \begin{macrocode} + \cs_set_protected:Npn \rectanglecolor { } + \cs_set_protected:Npn \columncolor { } + \iow_now:Nn \@mainaux \ExplSyntaxOn + \iow_now:Nx \@mainaux + { + \tl_gset:cn + { g_@@_code_before_ \int_use:N \g_@@_env_int _ tl } + { \exp_not:V \g_nicematrix_code_before_tl } + } + \iow_now:Nn \@mainaux \ExplSyntaxOff + \bool_set_true:N \l_@@_code_before_bool + } +% \end{macrocode} +% +% \medskip +% \begin{macrocode} \str_gclear:N \g_@@_name_env_str \@@_restore_iRow_jCol: +% \end{macrocode} +% The command |\CT@arc@| contains the instruction of color for the rules of the +% array\footnote{e.g. |\color[rgb]{0.5,0.5,0}|}. This command is used by +% |\CT@arc@| but we use it also for compatibility with \pkg{colortbl}. But we +% want also to be able to use color for the rules of the array when +% \pkg{colortbl} is \emph{not} loaded. That's why we do the following +% instruction which is in the patch of the end of arrays done by \pkg{colortbl}. +% \begin{macrocode} + \cs_gset_eq:NN \CT@arc@ \@@_old_CT@arc@ } % \end{macrocode} % % \bigskip +% The following command will extract the potential options (between square +% brackets) at the beginning of the |code-after| (that is to say, when +% |\CodeAfter| is used, the options of that ``command'' |\CodeAfter|). +% \begin{macrocode} +\NewDocumentCommand \@@_CodeAfter_keys: { O { } } + { \keys_set:nn { NiceMatrix / CodeAfter } { #1 } } +% \end{macrocode} +% +% +% \bigskip +% We remind that the first mandatory argument of the command |\Block| is the +% size of the block with the special format $i$|-|$j$. However, the user is +% allowed to omit $i$ or $j$ (or both). This will be interpreted as: the last +% row (resp. column) of the block will be the last row (resp. column) of the +% block (without the potential exterior row---resp. column---of the array). By +% convention, this is stored in |\g_@@_pos_of_blocks_seq| (and +% |\g_@@_blocks_seq|) as a number of rows (resp. columns) for the block equal to +% 100. It's possible, after the construction of the array, to replace these +% values by the correct ones (since we know the number of rows and columns of +% the array). +% \begin{macrocode} +\cs_new_protected:Npn \@@_adjust_pos_of_blocks_seq: + { + \seq_gset_map_x:NNn \g_@@_pos_of_blocks_seq \g_@@_pos_of_blocks_seq + { \@@_adjust_pos_of_blocks_seq_i:nnnn ##1 } + } +% \end{macrocode} +% +% The following command must \emph{not} be protected. +% \begin{macrocode} +\cs_new:Npn \@@_adjust_pos_of_blocks_seq_i:nnnn #1 #2 #3 #4 + { + { #1 } + { #2 } + { + \int_compare:nNnTF { #3 } > { 99 } + { \int_use:N \c@iRow } + { #3 } + } + { + \int_compare:nNnTF { #4 } > { 99 } + { \int_use:N \c@jCol } + { #4 } + } + } +% \end{macrocode} +% +% \bigskip % We recall that, when externalization is used, |\tikzpicture| and % |\endtikzpicture| (or |\pgfpicture| and |\endpgfpicture|) must be directly % ``visible''. That's why we have to define the adequate version of @@ -5883,7 +9521,7 @@ version 2005/12/01 or later. { \pgfrememberpicturepositiononpagetrue \pgf@relevantforpicturesizefalse - \g_@@_Hdotsfor_lines_tl + \g_@@_HVdotsfor_lines_tl \g_@@_Vdots_lines_tl \g_@@_Ddots_lines_tl \g_@@_Iddots_lines_tl @@ -5896,12 +9534,15 @@ version 2005/12/01 or later. % \begin{macrocode} \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 } + \cs_if_exist:NT \theiRow { \int_gset_eq:NN \c@iRow \l_@@_old_iRow_int } + \cs_if_exist:NT \thejCol { \int_gset_eq:NN \c@jCol \l_@@_old_jCol_int } } % \end{macrocode} % +% % \bigskip +% \subsection*{We draw the dotted lines} +% % A dotted line will be said \emph{open} in one of its extremities when it stops % on the edge of the matrix and \emph{closed} otherwise. In the following % matrix, the dotted line is closed on its left extremity and open on its right. @@ -5922,7 +9563,7 @@ version 2005/12/01 or later. % \item the third argument is the $x$-value of the orientation vector of the % line; % \item the fourth argument is the $y$-value of the orientation vector of the -% line; +% line. % \end{itemize} % % This command computes: @@ -5954,7 +9595,8 @@ version 2005/12/01 or later. % \end{macrocode} % We will do two loops: one when determinating the initial cell and the other % when determinating the final cell. The boolean |\l_@@_stop_loop_bool| will be -% used to control these loops. +% used to control these loops. In the first loop, we search the ``final'' +% extremity of the line. % \begin{macrocode} \bool_set_false:N \l_@@_stop_loop_bool \bool_do_until:Nn \l_@@_stop_loop_bool @@ -5967,8 +9609,12 @@ version 2005/12/01 or later. \bool_set_false:N \l_@@_final_open_bool \int_compare:nNnTF \l_@@_final_i_int > \c@iRow { - \int_compare:nNnT { #3 } = 1 + \int_compare:nNnTF { #3 } = 1 { \bool_set_true:N \l_@@_final_open_bool } + { + \int_compare:nNnT \l_@@_final_j_int > \c@jCol + { \bool_set_true:N \l_@@_final_open_bool } + } } { \int_compare:nNnTF \l_@@_final_j_int < 1 @@ -6026,7 +9672,7 @@ version 2005/12/01 or later. % \end{macrocode} % If the case is empty, we declare that the cell as non-empty. Indeed, we will % draw a dotted line and the cell will be on that dotted line. All the cells of -% a dotted line have to be mark as ``dotted'' because we don't want +% a dotted line have to be marked as ``dotted'' because we don't want % intersections between dotted lines. We recall that the research of the % extremities of the lines are all done in the same TeX group (the group of the % environnement), even though, when the extremities are found, each line is @@ -6058,8 +9704,12 @@ version 2005/12/01 or later. \bool_set_false:N \l_@@_initial_open_bool \int_compare:nNnTF \l_@@_initial_i_int < 1 { - \int_compare:nNnT { #3 } = 1 + \int_compare:nNnTF { #3 } = 1 { \bool_set_true:N \l_@@_initial_open_bool } + { + \int_compare:nNnT \l_@@_initial_j_int = 0 + { \bool_set_true:N \l_@@_initial_open_bool } + } } { \int_compare:nNnTF \l_@@_initial_j_int < 1 @@ -6114,15 +9764,23 @@ version 2005/12/01 or later. } } } +% \end{macrocode} +% We remind the rectangle described by all the dotted lines in order to respect +% the corresponding virtual ``block'' when drawing the horizontal and vertical +% rules. +% \begin{macrocode} + \seq_gput_right:Nx \g_@@_pos_of_xdots_seq + { + { \int_use:N \l_@@_initial_i_int } + { \int_use:N \l_@@_initial_j_int } + { \int_use:N \l_@@_final_i_int } + { \int_use:N \l_@@_final_j_int } + } } % \end{macrocode} % % \medskip % \begin{macrocode} -\cs_new:Nn \@@_initial_cell: - { \@@_env: - \int_use:N \l_@@_initial_i_int - \int_use:N \l_@@_initial_j_int } -\cs_new:Nn \@@_final_cell: - { \@@_env: - \int_use:N \l_@@_final_i_int - \int_use:N \l_@@_final_j_int } \cs_new_protected:Npn \@@_set_initial_coords: { \dim_set_eq:NN \l_@@_x_initial_dim \pgf@x @@ -6135,12 +9793,24 @@ version 2005/12/01 or later. } \cs_new_protected:Npn \@@_set_initial_coords_from_anchor:n #1 { - \pgfpointanchor \@@_initial_cell: { #1 } + \pgfpointanchor + { + \@@_env: + - \int_use:N \l_@@_initial_i_int + - \int_use:N \l_@@_initial_j_int + } + { #1 } \@@_set_initial_coords: } \cs_new_protected:Npn \@@_set_final_coords_from_anchor:n #1 { - \pgfpointanchor \@@_final_cell: { #1 } + \pgfpointanchor + { + \@@_env: + - \int_use:N \l_@@_final_i_int + - \int_use:N \l_@@_final_j_int + } + { #1 } \@@_set_final_coords: } % \end{macrocode} @@ -6197,36 +9867,30 @@ version 2005/12/01 or later. { \bool_if:NTF \l_@@_initial_open_bool { - \@@_qpoint: { col - \int_use:N \l_@@_initial_j_int } + \@@_qpoint:n { col - \int_use:N \l_@@_initial_j_int } \dim_set_eq:NN \l_@@_x_initial_dim \pgf@x - \dim_add:Nn \l_@@_x_initial_dim \arraycolsep - \@@_qpoint: { row - \int_use:N \l_@@_initial_i_int - base } + \dim_add:Nn \l_@@_x_initial_dim \col@sep + \@@_qpoint:n { row - \int_use:N \l_@@_initial_i_int - base } \dim_set_eq:NN \l_@@_y_initial_dim \pgf@y } { \@@_set_initial_coords_from_anchor:n { base~east } } \bool_if:NTF \l_@@_final_open_bool { - \@@_qpoint: { col - \@@_succ:n \l_@@_final_j_int } + \@@_qpoint:n { col - \@@_succ:n \l_@@_final_j_int } \dim_set_eq:NN \l_@@_x_final_dim \pgf@x - \dim_sub:Nn \l_@@_x_final_dim \arraycolsep - \@@_qpoint: { row - \int_use:N \l_@@_final_i_int - base } + \dim_sub:Nn \l_@@_x_final_dim \col@sep + \@@_qpoint:n { row - \int_use:N \l_@@_final_i_int - base } \dim_set_eq:NN \l_@@_y_final_dim \pgf@y } { \@@_set_final_coords_from_anchor:n { base~west } } % \end{macrocode} % We raise the line of a quantity equal to the radius of the dots because we -% want the dots really ``on'' the line of texte. +% want the dots really ``on'' the line of texte. Of course, maybe we should not +% do that when the option |line-style| is used (?). % \begin{macrocode} \dim_add:Nn \l_@@_y_initial_dim \l_@@_radius_dim \dim_add:Nn \l_@@_y_final_dim \l_@@_radius_dim \@@_draw_line: -% \end{macrocode} -% The values of |\l_@@_x_initial_dim|, |\l_@@_y_initial_dim|, |\l_@@_x_final_dim|, -% |\l_@@_y_final_dim|, -% -% |\l_@@_initial_open_bool| and |\l_@@_final_open_bool| are still available -% after the |\@@_draw_line:|. -% \begin{macrocode} } % \end{macrocode} % @@ -6280,25 +9944,25 @@ version 2005/12/01 or later. { \bool_if:NTF \l_@@_initial_open_bool { - \@@_qpoint: { col - \int_use:N \l_@@_initial_j_int } + \@@_qpoint:n { col - \int_use:N \l_@@_initial_j_int } \dim_set_eq:NN \l_@@_x_initial_dim \pgf@x - \dim_add:Nn \l_@@_x_initial_dim \arraycolsep + \dim_add:Nn \l_@@_x_initial_dim \col@sep } { \@@_set_initial_coords_from_anchor:n { mid~east } } \bool_if:NTF \l_@@_final_open_bool { - \@@_qpoint: { col - \@@_succ:n \l_@@_final_j_int } + \@@_qpoint:n { col - \@@_succ:n \l_@@_final_j_int } \dim_set_eq:NN \l_@@_x_final_dim \pgf@x - \dim_sub:Nn \l_@@_x_final_dim \arraycolsep + \dim_sub:Nn \l_@@_x_final_dim \col@sep } { \@@_set_final_coords_from_anchor:n { mid~west } } \bool_lazy_and:nnTF \l_@@_initial_open_bool \l_@@_final_open_bool { - \@@_qpoint: { row - \int_use:N \l_@@_initial_i_int } + \@@_qpoint:n { row - \int_use:N \l_@@_initial_i_int } \dim_set_eq:NN \l_tmpa_dim \pgf@y - \@@_qpoint: { row - \@@_succ:n \l_@@_initial_i_int } + \@@_qpoint:n { row - \@@_succ:n \l_@@_initial_i_int } \dim_set:Nn \l_@@_y_initial_dim { ( \l_tmpa_dim + \pgf@y ) / 2 } \dim_set_eq:NN \l_@@_y_final_dim \l_@@_y_initial_dim } @@ -6309,13 +9973,6 @@ version 2005/12/01 or later. { \dim_set_eq:NN \l_@@_y_final_dim \l_@@_y_initial_dim } } \@@_draw_line: -% \end{macrocode} -% The values of |\l_@@_x_initial_dim|, |\l_@@_y_initial_dim|, |\l_@@_x_final_dim|, -% |\l_@@_y_final_dim|, -% -% |\l_@@_initial_open_bool| and |\l_@@_final_open_bool| are still available -% after the |\@@_draw_line:|. -% \begin{macrocode} } % \end{macrocode} % @@ -6325,7 +9982,6 @@ version 2005/12/01 or later. % \begin{macrocode} \cs_new_protected:Npn \@@_draw_Vdots:nnn #1 #2 #3 { - \tl_if_empty:VF \l_@@_xdots_color_tl { \color { \l_@@_xdots_color_tl } } \cs_if_free:cT { @@ _ dotted _ #1 - #2 } { \@@_find_extremities_of_line:nnnn { #1 } { #2 } 1 0 @@ -6342,6 +9998,8 @@ version 2005/12/01 or later. { \color { nicematrix-last-col } } } \keys_set:nn { NiceMatrix / xdots } { #3 } + \tl_if_empty:VF \l_@@_xdots_color_tl + { \color { \l_@@_xdots_color_tl } } \@@_actually_draw_Vdots: \group_end: } @@ -6358,12 +10016,14 @@ version 2005/12/01 or later. % \item |\l_@@_final_j_int| % \item |\l_@@_final_open_bool|. % \end{itemize} +% +% The following function is also used by |\Vdotsfor|. % \begin{macrocode} \cs_new_protected:Npn \@@_actually_draw_Vdots: { % \end{macrocode} -% The boolean |\l_tmpa_bool| indicates whether the column is of type |l| (|L| of -% |{NiceArray}|) or may be considered as if. +% The boolean |\l_tmpa_bool| indicates whether the column is of type |l| or may +% be considered as if. % \begin{macrocode} \bool_set_false:N \l_tmpa_bool \bool_lazy_or:nnF \l_@@_initial_open_bool \l_@@_final_open_bool @@ -6374,18 +10034,18 @@ version 2005/12/01 or later. { \dim_compare_p:nNn \l_@@_x_initial_dim = \l_@@_x_final_dim } } % \end{macrocode} -% Now, we try to determine whether the column is of type |c| (|C| of -% |{NiceArray}|) or may be considered as if. +% Now, we try to determine whether the column is of type |c| or may be +% considered as if. % \begin{macrocode} \bool_if:NTF \l_@@_initial_open_bool { - \@@_qpoint: { row - 1 } + \@@_qpoint:n { row - \int_use:N \l_@@_initial_i_int } \dim_set_eq:NN \l_@@_y_initial_dim \pgf@y } { \@@_set_initial_coords_from_anchor:n { south } } \bool_if:NTF \l_@@_final_open_bool { - \@@_qpoint: { row - \@@_succ:n \c@iRow } + \@@_qpoint:n { row - \@@_succ:n \l_@@_final_i_int } \dim_set_eq:NN \l_@@_y_final_dim \pgf@y } { \@@_set_final_coords_from_anchor:n { north } } @@ -6393,11 +10053,27 @@ version 2005/12/01 or later. { \bool_if:NTF \l_@@_final_open_bool { - \@@_qpoint: { col - \int_use:N \l_@@_initial_j_int } + \@@_qpoint:n { col - \int_use:N \l_@@_initial_j_int } \dim_set_eq:NN \l_tmpa_dim \pgf@x - \@@_qpoint: { col - \@@_succ:n \l_@@_initial_j_int } + \@@_qpoint:n { col - \@@_succ:n \l_@@_initial_j_int } \dim_set:Nn \l_@@_x_initial_dim { ( \pgf@x + \l_tmpa_dim ) / 2 } \dim_set_eq:NN \l_@@_x_final_dim \l_@@_x_initial_dim +% \end{macrocode} +% We may think that the final user won't use a ``last column'' which contains +% only a command |\Vdots|. However, if the |\Vdots| is in fact used to draw, not +% a dotted line, but an arrow (to indicate the number of rows of the matrix), it +% may be really encountered. +% \begin{macrocode} + \int_compare:nNnT \l_@@_last_col_int > { -2 } + { + \int_compare:nNnT \l_@@_initial_j_int = \g_@@_col_total_int + { + \dim_set_eq:NN \l_tmpa_dim \l_@@_right_margin_dim + \dim_add:Nn \l_tmpa_dim \l_@@_extra_right_margin_dim + \dim_add:Nn \l_@@_x_initial_dim \l_tmpa_dim + \dim_add:Nn \l_@@_x_final_dim \l_tmpa_dim + } + } } { \dim_set_eq:NN \l_@@_x_initial_dim \l_@@_x_final_dim } } @@ -6422,13 +10098,6 @@ version 2005/12/01 or later. } } \@@_draw_line: -% \end{macrocode} -% The values of |\l_@@_x_initial_dim|, |\l_@@_y_initial_dim|, |\l_@@_x_final_dim|, -% |\l_@@_y_final_dim|, -% -% |\l_@@_initial_open_bool| and |\l_@@_final_open_bool| are -% still available after the |\@@_draw_line:|. -% \begin{macrocode} } % \end{macrocode} % @@ -6475,17 +10144,17 @@ version 2005/12/01 or later. { \bool_if:NTF \l_@@_initial_open_bool { - \@@_qpoint: { row - \int_use:N \l_@@_initial_i_int } + \@@_qpoint:n { row - \int_use:N \l_@@_initial_i_int } \dim_set_eq:NN \l_@@_y_initial_dim \pgf@y - \@@_qpoint: { col - \int_use:N \l_@@_initial_j_int } + \@@_qpoint:n { col - \int_use:N \l_@@_initial_j_int } \dim_set_eq:NN \l_@@_x_initial_dim \pgf@x } { \@@_set_initial_coords_from_anchor:n { south~east } } \bool_if:NTF \l_@@_final_open_bool { - \@@_qpoint: { row - \@@_succ:n \l_@@_final_i_int } + \@@_qpoint:n { row - \@@_succ:n \l_@@_final_i_int } \dim_set_eq:NN \l_@@_y_final_dim \pgf@y - \@@_qpoint: { col - \@@_succ:n \l_@@_final_j_int } + \@@_qpoint:n { col - \@@_succ:n \l_@@_final_j_int } \dim_set_eq:NN \l_@@_x_final_dim \pgf@x } { \@@_set_final_coords_from_anchor:n { north~west } } @@ -6528,13 +10197,6 @@ version 2005/12/01 or later. } } \@@_draw_line: -% \end{macrocode} -% The values of |\l_@@_x_initial_dim|, |\l_@@_y_initial_dim|, |\l_@@_x_final_dim|, -% |\l_@@_y_final_dim|, -% -% |\l_@@_initial_open_bool| and |\l_@@_final_open_bool| are still available -% after the |\@@_draw_line:|. -% \begin{macrocode} } % \end{macrocode} % @@ -6579,17 +10241,17 @@ version 2005/12/01 or later. { \bool_if:NTF \l_@@_initial_open_bool { - \@@_qpoint: { row - \int_use:N \l_@@_initial_i_int } + \@@_qpoint:n { row - \int_use:N \l_@@_initial_i_int } \dim_set_eq:NN \l_@@_y_initial_dim \pgf@y - \@@_qpoint: { col - \@@_succ:n \l_@@_initial_j_int } + \@@_qpoint:n { col - \@@_succ:n \l_@@_initial_j_int } \dim_set_eq:NN \l_@@_x_initial_dim \pgf@x } { \@@_set_initial_coords_from_anchor:n { south~west } } \bool_if:NTF \l_@@_final_open_bool { - \@@_qpoint: { row - \@@_succ:n \l_@@_final_i_int } + \@@_qpoint:n { row - \@@_succ:n \l_@@_final_i_int } \dim_set_eq:NN \l_@@_y_final_dim \pgf@y - \@@_qpoint: { col - \int_use:N \l_@@_final_j_int } + \@@_qpoint:n { col - \int_use:N \l_@@_final_j_int } \dim_set_eq:NN \l_@@_x_final_dim \pgf@x } { \@@_set_final_coords_from_anchor:n { north~east } } @@ -6613,29 +10275,11 @@ version 2005/12/01 or later. } } \@@_draw_line: -% \end{macrocode} -% The values of |\l_@@_x_initial_dim|, |\l_@@_y_initial_dim|, |\l_@@_x_final_dim|, -% |\l_@@_y_final_dim|, -% -% |\l_@@_initial_open_bool| and |\l_@@_final_open_bool| are still available -% after the |\@@_draw_line:|. -% \begin{macrocode} } % \end{macrocode} % % % \bigskip -% The command |\NiceMatrixLastEnv| is not used by the package \pkg{nicematrix}. -% It's only a facility given to the final user. It gives the number of the last -% environment (in fact the number of the current environment but it's meant to -% be used after the environment in order to refer to that environment --- and -% its nodes --- without having to give it a name). -% \begin{macrocode} -\NewExpandableDocumentCommand \NiceMatrixLastEnv { } - { \int_use:N \g_@@_env_int } -% \end{macrocode} -% -% \bigskip % \subsection*{The actual instructions for drawing the dotted line with Tikz} % % The command |\@@_draw_line:| should be used in a |{pgfpicture}|. It has six @@ -6669,9 +10313,9 @@ version 2005/12/01 or later. % \begin{macrocode} \cs_new_protected:Npn \@@_draw_non_standard_dotted_line: { - \begin { scope } - \exp_args:No \@@_draw_non_standard_dotted_line:n - { \l_@@_xdots_line_style_tl , \l_@@_xdots_color_tl } + \begin { scope } + \exp_args:No \@@_draw_non_standard_dotted_line:n + { \l_@@_xdots_line_style_tl , \l_@@_xdots_color_tl } } % \end{macrocode} % We have used the fact that, in \textsc{pgf}, un color name can be put directly @@ -6682,6 +10326,16 @@ version 2005/12/01 or later. % \begin{macrocode} \cs_new_protected:Npn \@@_draw_non_standard_dotted_line:n #1 { + \@@_draw_non_standard_dotted_line:nVV + { #1 } + \l_@@_xdots_up_tl + \l_@@_xdots_down_tl + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_non_standard_dotted_line:nnn #1 #2 #3 + { \draw [ #1 , @@ -6689,19 +10343,69 @@ version 2005/12/01 or later. shorten~< = \l_@@_xdots_shorten_dim , ] ( \l_@@_x_initial_dim , \l_@@_y_initial_dim ) - -- ( \l_@@_x_final_dim , \l_@@_y_final_dim ) ; +% \end{macrocode} +% Be careful: We can't put |\c_math_toggle_token| instead of |$| in the +% following lines because we are in the contents of Tikz nodes (and they will be +% \emph{rescanned} if the Tikz library \pkg{babel} is loaded). +% \begin{macrocode} + -- node [ sloped , above ] { $ \scriptstyle #2 $ } + node [ sloped , below ] { $ \scriptstyle #3 $ } + ( \l_@@_x_final_dim , \l_@@_y_final_dim ) ; \end { scope } } +\cs_generate_variant:Nn \@@_draw_non_standard_dotted_line:nnn { n V V } % \end{macrocode} % % \bigskip % The command |\@@_draw_standard_dotted_line:| draws the line with our system of points -% (which give a dotted line with real round points). +% (which gives a dotted line with real round points). % \begin{macrocode} \cs_new_protected:Npn \@@_draw_standard_dotted_line: { - \pgfrememberpicturepositiononpagetrue - \pgf@relevantforpicturesizefalse + \bool_lazy_and:nnF + { \tl_if_empty_p:N \l_@@_xdots_up_tl } + { \tl_if_empty_p:N \l_@@_xdots_down_tl } + { + \pgfscope + \pgftransformshift + { + \pgfpointlineattime { 0.5 } + { \pgfpoint \l_@@_x_initial_dim \l_@@_y_initial_dim } + { \pgfpoint \l_@@_x_final_dim \l_@@_y_final_dim } + } + \pgftransformrotate + { + \fp_eval:n + { + atand + ( + \l_@@_y_final_dim - \l_@@_y_initial_dim , + \l_@@_x_final_dim - \l_@@_x_initial_dim + ) + } + } + \pgfnode + { rectangle } + { south } + { + \c_math_toggle_token + \scriptstyle \l_@@_xdots_up_tl + \c_math_toggle_token + } + { } + { \pgfusepath { } } + \pgfnode + { rectangle } + { north } + { + \c_math_toggle_token + \scriptstyle \l_@@_xdots_down_tl + \c_math_toggle_token + } + { } + { \pgfusepath { } } + \endpgfscope + } \group_begin: % \end{macrocode} % The dimension |\l_@@_l_dim| is the length $\ell$ of the line to draw. We use @@ -6730,7 +10434,7 @@ version 2005/12/01 or later. \bool_lazy_or:nnF { \dim_compare_p:nNn { \dim_abs:n \l_@@_l_dim } > \c_@@_max_l_dim } { \dim_compare_p:nNn \l_@@_l_dim = \c_zero_dim } - \@@_actually_draw_line: + \@@_draw_standard_dotted_line_i: \group_end: } % \end{macrocode} @@ -6740,7 +10444,7 @@ version 2005/12/01 or later. % \end{macrocode} % % \begin{macrocode} -\cs_new_protected:Npn \@@_actually_draw_line: +\cs_new_protected:Npn \@@_draw_standard_dotted_line_i: { % \end{macrocode} % The integer |\l_tmpa_int| is the number of dots of the dotted line. @@ -6771,7 +10475,7 @@ version 2005/12/01 or later. \l_@@_inter_dots_dim } } - { + { \int_set:Nn \l_tmpa_int { \dim_ratio:nn @@ -6854,68 +10558,153 @@ version 2005/12/01 or later. % \pkg{nicematrix} rely upon |{NiceArray}|). % % The starred versions of these commands are deprecated since version~3.1 but, -% as for now, they are still available with an error. +% as of now, they are still available with an error. +% +% +% \medskip +% The syntax of these commands uses the character |_| as embellishment and +% thats' why we have to insert a character |_| in the \emph{arg spec} of these +% commands. However, we don't know the future catcode of |_| in the main +% document (maybe the user will use \pkg{underscore}, and, in that case, the +% catcode is $13$ because \pkg{underscore} activates |_|). That's why these +% commands will be defined in a |\AtBeginDocument| and the \emph{arg spec} will +% be rescanned. +% % \begin{macrocode} -\NewDocumentCommand \@@_Ldots { s O { } } - { - \bool_if:nTF { #1 } - { \@@_error:n { starred~commands } } - { \@@_instruction_of_type:nn { Ldots } { #2 } } - \bool_if:NF \l_@@_nullify_dots_bool { \phantom \@@_ldots } - \bool_gset_true:N \g_@@_empty_cell_bool - } +\AtBeginDocument + { + \tl_set:Nn \l_@@_argspec_tl { O { } E { _ ^ } { { } { } } } + \tl_set_rescan:Nno \l_@@_argspec_tl { } \l_@@_argspec_tl + \exp_args:NNV \NewDocumentCommand \@@_Ldots \l_@@_argspec_tl + { + \int_compare:nNnTF \c@jCol = 0 + { \@@_error:nn { in~first~col } \Ldots } + { + \int_compare:nNnTF \c@jCol = \l_@@_last_col_int + { \@@_error:nn { in~last~col } \Ldots } + { + \@@_instruction_of_type:nnn \c_false_bool { Ldots } + { #1 , down = #2 , up = #3 } + } + } + \bool_if:NF \l_@@_nullify_dots_bool + { \phantom { \ensuremath { \@@_old_ldots } } } + \bool_gset_true:N \g_@@_empty_cell_bool + } % \end{macrocode} % % \bigskip % \begin{macrocode} -\NewDocumentCommand \@@_Cdots { s O { } } - { - \bool_if:nTF { #1 } - { \@@_error:n { starred~commands } } - { \@@_instruction_of_type:nn { Cdots } { #2 } } - \bool_if:NF \l_@@_nullify_dots_bool { \phantom \@@_cdots } - \bool_gset_true:N \g_@@_empty_cell_bool - } + \exp_args:NNV \NewDocumentCommand \@@_Cdots \l_@@_argspec_tl + { + \int_compare:nNnTF \c@jCol = 0 + { \@@_error:nn { in~first~col } \Cdots } + { + \int_compare:nNnTF \c@jCol = \l_@@_last_col_int + { \@@_error:nn { in~last~col } \Cdots } + { + \@@_instruction_of_type:nnn \c_false_bool { Cdots } + { #1 , down = #2 , up = #3 } + } + } + \bool_if:NF \l_@@_nullify_dots_bool + { \phantom { \ensuremath { \@@_old_cdots } } } + \bool_gset_true:N \g_@@_empty_cell_bool + } % \end{macrocode} % % \bigskip % \begin{macrocode} -\NewDocumentCommand \@@_Vdots { s O { } } - { - \bool_if:nTF { #1 } - { \@@_error:n { starred~commands } } - { \@@_instruction_of_type:nn { Vdots } { #2 } } - \bool_if:NF \l_@@_nullify_dots_bool { \phantom \@@_vdots } - \bool_gset_true:N \g_@@_empty_cell_bool - } + \exp_args:NNV \NewDocumentCommand \@@_Vdots \l_@@_argspec_tl + { + \int_compare:nNnTF \c@iRow = 0 + { \@@_error:nn { in~first~row } \Vdots } + { + \int_compare:nNnTF \c@iRow = \l_@@_last_row_int + { \@@_error:nn { in~last~row } \Vdots } + { + \@@_instruction_of_type:nnn \c_false_bool { Vdots } + { #1 , down = #2 , up = #3 } + } + } + \bool_if:NF \l_@@_nullify_dots_bool + { \phantom { \ensuremath { \@@_old_vdots } } } + \bool_gset_true:N \g_@@_empty_cell_bool + } % \end{macrocode} % +% % \bigskip % \begin{macrocode} -\NewDocumentCommand \@@_Ddots { s O { } } - { - \bool_if:nTF { #1 } - { \@@_error:n { starred~commands } } - { \@@_instruction_of_type:nn { Ddots } { #2 } } - \bool_if:NF \l_@@_nullify_dots_bool { \phantom \@@_ddots } - \bool_gset_true:N \g_@@_empty_cell_bool - } + \exp_args:NNV \NewDocumentCommand \@@_Ddots \l_@@_argspec_tl + { + \int_case:nnF \c@iRow + { + 0 { \@@_error:nn { in~first~row } \Ddots } + \l_@@_last_row_int { \@@_error:nn { in~last~row } \Ddots } + } + { + \int_case:nnF \c@jCol + { + 0 { \@@_error:nn { in~first~col } \Ddots } + \l_@@_last_col_int { \@@_error:nn { in~last~col } \Ddots } + } + { + \keys_set_known:nn { NiceMatrix / Ddots } { #1 } + \@@_instruction_of_type:nnn \l_@@_draw_first_bool { Ddots } + { #1 , down = #2 , up = #3 } + } + + } + \bool_if:NF \l_@@_nullify_dots_bool + { \phantom { \ensuremath { \@@_old_ddots } } } + \bool_gset_true:N \g_@@_empty_cell_bool + } % \end{macrocode} % % \bigskip % \begin{macrocode} -\NewDocumentCommand \@@_Iddots { s O { } } - { - \bool_if:nTF { #1 } - { \@@_error:n { starred~commands } } - { \@@_instruction_of_type:nn { Iddots } { #2 } } - \bool_if:NF \l_@@_nullify_dots_bool { \phantom \@@_iddots } - \bool_gset_true:N \g_@@_empty_cell_bool + \exp_args:NNV \NewDocumentCommand \@@_Iddots \l_@@_argspec_tl + { + \int_case:nnF \c@iRow + { + 0 { \@@_error:nn { in~first~row } \Iddots } + \l_@@_last_row_int { \@@_error:nn { in~last~row } \Iddots } + } + { + \int_case:nnF \c@jCol + { + 0 { \@@_error:nn { in~first~col } \Iddots } + \l_@@_last_col_int { \@@_error:nn { in~last~col } \Iddots } + } + { + \keys_set_known:nn { NiceMatrix / Ddots } { #1 } + \@@_instruction_of_type:nnn \l_@@_draw_first_bool { Iddots } + { #1 , down = #2 , up = #3 } + } + } + \bool_if:NF \l_@@_nullify_dots_bool + { \phantom { \ensuremath { \@@_old_iddots } } } + \bool_gset_true:N \g_@@_empty_cell_bool + } } % \end{macrocode} +% End of the |\AtBeginDocument|. % % % \bigskip +% Despite its name, the following set of keys will be used for |\Ddots| but also +% for |\Iddots|. +% \begin{macrocode} +\keys_define:nn { NiceMatrix / Ddots } + { + draw-first .bool_set:N = \l_@@_draw_first_bool , + draw-first .default:n = true , + draw-first .value_forbidden:n = true + } +% \end{macrocode} +% +% \bigskip % The command |\@@_Hspace:| will be linked to |\hspace| in |{NiceArray}|. % \begin{macrocode} \cs_new_protected:Npn \@@_Hspace: @@ -6933,65 +10722,120 @@ version 2005/12/01 or later. \cs_set_eq:NN \@@_old_multicolumn \multicolumn \cs_new:Npn \@@_multicolumn:nnn #1 #2 #3 { - \@@_old_multicolumn { #1 } { #2 } { #3 } - \int_compare:nNnT #1 > 1 +% \end{macrocode} +% We have to act in an expandable way since it will begin by a |\multicolumn|. +% \begin{macrocode} + \exp_args:NNe + \@@_old_multicolumn + { #1 } +% \end{macrocode} +% We will have to replace |\tl_lower_case:n| in the future since it seems to be +% deprecated. +% \begin{macrocode} + { + \exp_args:Ne \str_case:nn { \str_foldcase:n { #2 } } + { + l { > \@@_Cell: l < \@@_end_Cell: } + r { > \@@_Cell: r < \@@_end_Cell: } + c { > \@@_Cell: c < \@@_end_Cell: } + { l | } { > \@@_Cell: l < \@@_end_Cell: | } + { r | } { > \@@_Cell: r < \@@_end_Cell: | } + { c | } { > \@@_Cell: c < \@@_end_Cell: | } + { | l } { | > \@@_Cell: l < \@@_end_Cell: } + { | r } { | > \@@_Cell: r < \@@_end_Cell: } + { | c } { | > \@@_Cell: c < \@@_end_Cell: } + { | l | } { | > \@@_Cell: l < \@@_end_Cell: | } + { | r | } { | > \@@_Cell: r < \@@_end_Cell: | } + { | c | } { | > \@@_Cell: c < \@@_end_Cell: | } + } + } + { #3 } +% \end{macrocode} +% The |\peek_remove_spaces:n| is mandatory. +% \begin{macrocode} + \peek_remove_spaces:n { - \seq_gput_left:Nx \g_@@_multicolumn_cells_seq - { \int_eval:n \c@iRow - \int_use:N \c@jCol } - \seq_gput_left:Nn \g_@@_multicolumn_sizes_seq { #1 } - } - \int_gadd:Nn \c@jCol { #1 - 1 } + \int_compare:nNnT #1 > 1 + { + \seq_gput_left:Nx \g_@@_multicolumn_cells_seq + { \int_use:N \c@iRow - \int_use:N \c@jCol } + \seq_gput_left:Nn \g_@@_multicolumn_sizes_seq { #1 } + \seq_gput_right:Nx \g_@@_pos_of_blocks_seq + { + { \int_use:N \c@iRow } + { \int_use:N \c@jCol } + { \int_use:N \c@iRow } + { \int_eval:n { \c@jCol + #1 - 1 } } + } + } + \int_gadd:Nn \c@jCol { #1 - 1 } + \int_compare:nNnT \c@jCol > \g_@@_col_total_int + { \int_gset_eq:NN \g_@@_col_total_int \c@jCol } + } } % \end{macrocode} % % % \bigskip % 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 also the implicit cells of the |\Hdotsfor| (maybe we should modify -% that point). +% |{NiceArrayWithDelims}|. Tikz nodes are created also in the implicit cells of +% the |\Hdotsfor| (maybe we should modify that point). % % \medskip % This command must \emph{not} be protected since it begins with |\multicolumn|. % \begin{macrocode} \cs_new:Npn \@@_Hdotsfor: { - \multicolumn { 1 } { C } { } - \@@_Hdotsfor_i + \bool_lazy_and:nnTF + { \int_compare_p:nNn \c@jCol = 0 } + { \int_compare_p:nNn \l_@@_first_col_int = 0 } + { + \bool_if:NTF \g_@@_after_col_zero_bool + { + \multicolumn { 1 } { c } { } + \@@_Hdotsfor_i + } + { \@@_fatal:n { Hdotsfor~in~col~0 } } + } + { + \multicolumn { 1 } { c } { } + \@@_Hdotsfor_i + } } % \end{macrocode} % -% The command |\@@_Hdotsfor_i| is defined with the tools of \pkg{xparse} because -% it has an optional argument. Note that such a command defined by +% +% The command |\@@_Hdotsfor_i| is defined with |\NewDocumentCommand| because 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} -\bool_if:NTF \c_@@_draft_bool +\AtBeginDocument { + \tl_set:Nn \l_@@_argspec_tl { O { } m O { } E { _ ^ } { { } { } } } + \tl_set_rescan:Nno \l_@@_argspec_tl { } \l_@@_argspec_tl % \end{macrocode} % We don't put |!| before the last optionnal argument for homogeneity with % |\Cdots|, etc. which have only one optional argument. % \begin{macrocode} - \NewDocumentCommand \@@_Hdotsfor_i { O { } m O { } } - { \prg_replicate:nn { #2 - 1 } { & \multicolumn { 1 } { C } { } } } - } - { - \NewDocumentCommand \@@_Hdotsfor_i { O { } m O { } } + \exp_args:NNV \NewDocumentCommand \@@_Hdotsfor_i \l_@@_argspec_tl { - \tl_gput_right:Nx \g_@@_Hdotsfor_lines_tl + \tl_gput_right:Nx \g_@@_HVdotsfor_lines_tl { \@@_Hdotsfor:nnnn { \int_use:N \c@iRow } { \int_use:N \c@jCol } { #2 } - { #3 } - } - \prg_replicate:nn { #2 - 1 } { & \multicolumn { 1 } { C } { } } + { + #1 , #3 , + down = \exp_not:n { #4 } , up = \exp_not:n { #5 } + } + } + \prg_replicate:nn { #2 - 1 } { & \multicolumn { 1 } { c } { } } } } % \end{macrocode} +% Enf of |\AtBeginDocument|. % % \medskip % \begin{macrocode} @@ -7069,45 +10913,115 @@ version 2005/12/01 or later. { \cs_set:cpn { @@ _ dotted _ #1 - ##1 } { } } } % \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 }|'' +% \bigskip +% \begin{macrocode} +\AtBeginDocument + { + \tl_set:Nn \l_@@_argspec_tl { O { } m O { } E { _ ^ } { { } { } } } + \tl_set_rescan:Nno \l_@@_argspec_tl { } \l_@@_argspec_tl + \exp_args:NNV \NewDocumentCommand \@@_Vdotsfor: \l_@@_argspec_tl + { + \tl_gput_right:Nx \g_@@_HVdotsfor_lines_tl + { + \@@_Vdotsfor:nnnn + { \int_use:N \c@iRow } + { \int_use:N \c@jCol } + { #2 } + { + #1 , #3 , + down = \exp_not:n { #4 } , up = \exp_not:n { #5 } + } + } + } + } +% \end{macrocode} +% Enf of |\AtBeginDocument|. % -% 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: +\cs_new_protected:Npn \@@_Vdotsfor:nnnn #1 #2 #3 #4 { - \box_rotate:Nn \l_@@_cell_box { 90 } + \bool_set_false:N \l_@@_initial_open_bool + \bool_set_false:N \l_@@_final_open_bool % \end{macrocode} -% If we are in the last row, we want all the boxes composed with the command -% |\rotate| aligned upwards. +% For the column, it's easy. % \begin{macrocode} - \int_compare:nNnT \c@iRow = \l_@@_last_row_int + \int_set:Nn \l_@@_initial_j_int { #2 } + \int_set_eq:NN \l_@@_final_j_int \l_@@_initial_j_int +% \end{macrocode} +% For the row, it's a bit more complicated. +% \begin{macrocode} + \int_compare:nNnTF #1 = 1 { - \vbox_set_top:Nn \l_@@_cell_box + \int_set:Nn \l_@@_initial_i_int 1 + \bool_set_true:N \l_@@_initial_open_bool + } + { + \cs_if_exist:cTF { - \vbox_to_zero:n { } + pgf @ sh @ ns @ \@@_env: + - \int_eval:n { #1 - 1 } + - \int_use:N \l_@@_initial_j_int + } + { \int_set:Nn \l_@@_initial_i_int { #1 - 1 } } + { + \int_set:Nn \l_@@_initial_i_int { #1 } + \bool_set_true:N \l_@@_initial_open_bool + } + } + \int_compare:nNnTF { #1 + #3 -1 } = \c@iRow + { + \int_set:Nn \l_@@_final_i_int { #1 + #3 - 1 } + \bool_set_true:N \l_@@_final_open_bool + } + { + \cs_if_exist:cTF + { + pgf @ sh @ ns @ \@@_env: + - \int_eval:n { #1 + #3 } + - \int_use:N \l_@@_final_j_int + } + { \int_set:Nn \l_@@_final_i_int { #1 + #3 } } + { + \int_set:Nn \l_@@_final_i_int { #1 + #3 - 1 } + \bool_set_true:N \l_@@_final_open_bool + } + } % \end{macrocode} -% |0.8 ex| will be the distance between the principal part of the array and our -% element (which is composed with |\rotate|. +% % \begin{macrocode} - \skip_vertical:n { - \box_ht:N \@arstrutbox + 0.8 ex } - \box_use:N \l_@@_cell_box - } + \group_begin: + \int_compare:nNnTF { #2 } = 0 + { \color { nicematrix-first-col } } + { + \int_compare:nNnT { #2 } = \g_@@_col_total_int + { \color { nicematrix-last-col } } } + \keys_set:nn { NiceMatrix / xdots } { #4 } + \tl_if_empty:VF \l_@@_xdots_color_tl { \color { \l_@@_xdots_color_tl } } + \@@_actually_draw_Vdots: + \group_end: +% \end{macrocode} +% +% \medskip +% We declare all the cells concerned by the |\Vdotsfor| as ``dotted'' (for the +% dotted lines created by |\Cdots|, |\Ldots|, etc., this job is done by +% |\@@_find_extremities_of_line:nnnn|). This declaration is done by defining a +% special control sequence (to nil). +% \begin{macrocode} + \int_step_inline:nnn { #1 } { #1 + #3 - 1 } + { \cs_set:cpn { @@ _ dotted _ ##1 - #2 } { } } } % \end{macrocode} % +% +% \vspace{1cm} +% The command |\@@_rotate:| will be linked to |\rotate| in +% |{NiceArrayWithDelims}|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_rotate: { \bool_gset_true:N \g_@@_rotate_bool } +% \end{macrocode} +% % \bigskip % \subsection*{The command \textbackslash line accessible in code-after} % @@ -7126,46 +11040,48 @@ version 2005/12/01 or later. { \int_eval:n { #1 } - \int_eval:n { #2 } } % \end{macrocode} % +% % \medskip % With the following construction, the command |\@@_double_int_eval:n| is % applied to both arguments before the application of |\@@_line_i:nn| (the % construction uses the fact the |\@@_line_i:nn| is protected and that % |\@@_double_int_eval:n| is fully expandable). % \begin{macrocode} -\NewDocumentCommand \@@_line { O { } m m ! O { } } +\AtBeginDocument { - \group_begin: - \keys_set:nn { NiceMatrix / xdots } { #1 , #4 } - \tl_if_empty:VF \l_@@_xdots_color_tl { \color { \l_@@_xdots_color_tl } } - \use:x - { - \@@_line_i:nn - { \@@_double_int_eval:n #2 \q_stop } - { \@@_double_int_eval:n #3 \q_stop } - } - \group_end: + \tl_set:Nn \l_@@_argspec_tl { O { } m m ! O { } E { _ ^ } { { } { } } } + \tl_set_rescan:Nno \l_@@_argspec_tl { } \l_@@_argspec_tl + \exp_args:NNV \NewDocumentCommand \@@_line \l_@@_argspec_tl + { + \group_begin: + \keys_set:nn { NiceMatrix / xdots } { #1 , #4 , down = #5 , up = #6 } + \tl_if_empty:VF \l_@@_xdots_color_tl { \color { \l_@@_xdots_color_tl } } + \use:e + { + \@@_line_i:nn + { \@@_double_int_eval:n #2 \q_stop } + { \@@_double_int_eval:n #3 \q_stop } + } + \group_end: + } } % \end{macrocode} % % \begin{macrocode} -\bool_if:NTF \c_@@_draft_bool - { \cs_new_protected:Npn \@@_line_i:nn #1 #2 { } } +\cs_new_protected:Npn \@@_line_i:nn #1 #2 { - \cs_new_protected:Npn \@@_line_i:nn #1 #2 + \bool_set_false:N \l_@@_initial_open_bool + \bool_set_false:N \l_@@_final_open_bool + \bool_if:nTF { - \bool_set_false:N \l_@@_initial_open_bool - \bool_set_false:N \l_@@_final_open_bool - \bool_if:nTF - { - \cs_if_free_p:c { pgf @ sh @ ns @ \@@_env: - #1 } - || - \cs_if_free_p:c { pgf @ sh @ ns @ \@@_env: - #2 } - } - { - \@@_error:nnn { unknown~cell~for~line~in~code-after } { #1 } { #2 } - } - { \@@_draw_line_ii:nn { #1 } { #2 } } + \cs_if_free_p:c { pgf @ sh @ ns @ \@@_env: - #1 } + || + \cs_if_free_p:c { pgf @ sh @ ns @ \@@_env: - #2 } } + { + \@@_error:nnn { unknown~cell~for~line~in~code-after } { #1 } { #2 } + } + { \@@_draw_line_ii:nn { #1 } { #2 } } } % \end{macrocode} % @@ -7188,16 +11104,16 @@ version 2005/12/01 or later. % \end{macrocode} % % \bigskip -% The following command \emph{must} be protected since it's used in the -% construction of |\@@_draw_line_ii:nn|. +% The following command \emph{must} be protected (it's used in the +% construction of |\@@_draw_line_ii:nn|). % \begin{macrocode} \cs_new_protected:Npn \@@_draw_line_iii:nn #1 #2 { \pgfrememberpicturepositiononpagetrue - \pgfpointshapeborder { \@@_env: - #1 } { \@@_qpoint: { #2 } } + \pgfpointshapeborder { \@@_env: - #1 } { \@@_qpoint:n { #2 } } \dim_set_eq:NN \l_@@_x_initial_dim \pgf@x \dim_set_eq:NN \l_@@_y_initial_dim \pgf@y - \pgfpointshapeborder { \@@_env: - #2 } { \@@_qpoint: { #1 } } + \pgfpointshapeborder { \@@_env: - #2 } { \@@_qpoint:n { #1 } } \dim_set_eq:NN \l_@@_x_final_dim \pgf@x \dim_set_eq:NN \l_@@_y_final_dim \pgf@y \@@_draw_line: @@ -7209,8 +11125,498 @@ version 2005/12/01 or later. % this command because they have to do other settings (for example, the diagonal % lines must be parallelized). % +% \bigskip +% \subsection*{Colors of cells, rows and columns} +% +% We want to avoid the thin white lines that are shown in some \textsc{pdf} +% viewers (eg: with the engine MuPDF used by SumatraPDF). That's why we try to +% draw rectangles of the same color in the same instruction |\pgfusepathqfill| +% (and they will be in the same instruction |fill|---coded |f|--- in the +% resulting \textsc{pdf}). +% +% The commands |\@@_rowcolor|, |\@@_columncolor| and |\@@_rectanglecolor| +% (which are linked to |\rowcolor|, |\columncolor| and |\rectanglecolor| before +% the execution of the |code-before|) don't directly draw the corresponding +% rectangles. Instead, they store their instructions color by color: +% \begin{itemize} +% \item A sequence |\l_@@_colors_seq| will be built containing all the colors +% used by at least one of these instructions. Each \emph{color} may be prefixed +% by it color model (eg: |[gray]{0.5}|). +% \item For the color whose index in |\l_@@_colors_seq| is equal to~$i$, a list of +% instructions which use that color will be constructed in the token list +% |\l_@@_color_|$i$|_tl|. In that token list, the instructions will +% |\@@_rowcolor:n|, |\@@_columncolor:n| and |\@@_rectanglecolor:nn| +% (corresponding of |\@@_rowcolor|, |\@@_columncolor| and |\@@_rectanglecolor|). +% \end{itemize} +% +% +% bigskip +% |#1| is the color and |#2| is an instruction using that color. Despite its +% name, the command |\@@_add_to_color_seq| doesn't only add a color to +% |\l_@@_colors_seq|: it also updates the corresponding token list +% |\l_@@_color_|$i$|_tl|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_add_to_colors_seq:nn #1 #2 + { +% \end{macrocode} +% Firt, we look for the number of the color and, if it's found, we store it in +% |\l_tmpa_int|. If the color is not present in |\l_@@_colors_seq|, +% |\l_tmpa_int| will remain equal to $0$. +% \begin{macrocode} + \int_zero:N \l_tmpa_int + \seq_map_indexed_inline:Nn \l_@@_colors_seq + { \tl_if_eq:nnT { #1 } { ##2 } { \int_set:Nn \l_tmpa_int { ##1 } } } + \int_compare:nNnTF \l_tmpa_int = \c_zero_int +% \end{macrocode} +% First, the case where the color is a \emph{new} color (not in the sequence). +% \begin{macrocode} + { + \seq_put_right:Nn \l_@@_colors_seq { #1 } + \tl_set:cn { l_@@_color _ \seq_count:N \l_@@_colors_seq _ tl } { #2 } + } +% \end{macrocode} +% Now, the case where the color is \emph{not} a new color (the color is in the +% sequence at the position |\l_tmpa_int|). +% \begin{macrocode} + { \tl_put_right:cn { l_@@_color _ \int_use:N \l_tmpa_int _tl } { #2 } } + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_generate_variant:Nn \@@_add_to_colors_seq:nn { x n } +% \end{macrocode} % % \bigskip +% The macro |\@@_actually_color:| will actually fill all the rectangles, color by +% color (using the sequence |\l_@@_colors_seq| and all the token lists of the +% form |\l_@@_color_|$i$|_tl|). +% \begin{macrocode} +\cs_new_protected:Npn \@@_actually_color: + { + \pgfpicture + \pgf@relevantforpicturesizefalse + \seq_map_indexed_inline:Nn \l_@@_colors_seq + { + \color ##2 + \use:c { l_@@_color _ ##1 _tl } + \pgfusepathqfill + } + \endpgfpicture + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_set_protected:Npn \@@_cut_on_hyphen:w #1-#2\q_stop + { + \tl_set:Nn \l_tmpa_tl { #1 } + \tl_set:Nn \l_tmpb_tl { #2 } + } +% \end{macrocode} +% +% +% \bigskip +% Here is an example : |\@@_rowcolor {red!15} {1,3,5-7,10-}| +% \begin{macrocode} +\NewDocumentCommand \@@_rowcolor { O { } m m } + { + \tl_if_blank:nF { #2 } + { + \@@_add_to_colors_seq:xn + { \tl_if_blank:nF { #1 } { [ #1 ] } { #2 } } + { \@@_rowcolor:n { #3 } } + } + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_rowcolor:n #1 + { + \tl_set:Nn \l_@@_rows_tl { #1 } + \tl_set:Nn \l_@@_cols_tl { - } +% \end{macrocode} +% The command |\@@_cartesian_path:| takes in two implicit arguments: +% |\l_@@_cols_tl| and |\l_@@_row_tl|. +% \begin{macrocode} + \@@_cartesian_path: + } +% \end{macrocode} +% +% +% \bigskip +% Here an example : |\@@_columncolor:nn {red!15} {1,3,5-7,10-}| +% \begin{macrocode} +\NewDocumentCommand \@@_columncolor { O { } m m } + { + \tl_if_blank:nF { #2 } + { + \@@_add_to_colors_seq:xn + { \tl_if_blank:nF { #1 } { [ #1 ] } { #2 } } + { \@@_columncolor:n { #3 } } + } + } +% \end{macrocode} +% \begin{macrocode} +\cs_new_protected:Npn \@@_columncolor:n #1 + { + \tl_set:Nn \l_@@_rows_tl { - } + \tl_set:Nn \l_@@_cols_tl { #1 } +% \end{macrocode} +% The command |\@@_cartesian_path:| takes in two implicit arguments: +% |\l_@@_cols_tl| and |\l_@@_row_tl|. +% \begin{macrocode} + \@@_cartesian_path: + } +% \end{macrocode} +% +% +% \bigskip +% Here is an example : |\@@_rectanglecolor{red!15}{2-3}{5-6}| +% \begin{macrocode} +\NewDocumentCommand \@@_rectanglecolor { O { } m m m } + { + \tl_if_blank:nF { #2 } + { + \@@_add_to_colors_seq:xn + { \tl_if_blank:nF { #1 } { [ #1 ] } { #2 } } + { \@@_rectanglecolor:nn { #3 } { #4 } } + } + } +% \end{macrocode} +% +% \bigskip +% \begin{macrocode} +\cs_new_protected:Npn \@@_rectanglecolor:nn #1 #2 + { + \@@_cut_on_hyphen:w #1 \q_stop + \tl_clear_new:N \l_tmpc_tl + \tl_clear_new:N \l_tmpd_tl + \tl_set_eq:NN \l_tmpc_tl \l_tmpa_tl + \tl_set_eq:NN \l_tmpd_tl \l_tmpb_tl + \@@_cut_on_hyphen:w #2 \q_stop + \tl_set:Nx \l_@@_rows_tl { \l_tmpc_tl - \l_tmpa_tl } + \tl_set:Nx \l_@@_cols_tl { \l_tmpd_tl - \l_tmpb_tl } +% \end{macrocode} +% The command |\@@_cartesian_path:| takes in two implicit arguments: +% |\l_@@_cols_tl| and |\l_@@_row_tl|. +% \begin{macrocode} + \@@_cartesian_path: + } +% \end{macrocode} +% +% +% \bigskip +% Here is an example : |\@@_cellcolor[rgb]{0.5,0.5,0}{2-3,3-4,4-5,5-6}| +% \begin{macrocode} +\NewDocumentCommand \@@_cellcolor { O { } m m } + { + \clist_map_inline:nn { #3 } + { \@@_rectanglecolor [ #1 ] { #2 } { ##1 } { ##1 } } + } +% \end{macrocode} +% +% \bigskip +% \begin{macrocode} +\NewDocumentCommand \@@_chessboardcolors { O { } m m } + { + \int_step_inline:nn { \int_use:N \c@iRow } + { + \int_step_inline:nn { \int_use:N \c@jCol } + { + \int_if_even:nTF { ####1 + ##1 } + { \@@_cellcolor [ #1 ] { #2 } } + { \@@_cellcolor [ #1 ] { #3 } } + { ##1 - ####1 } + } + } + } +% \end{macrocode} +% +% +% \bigskip +% \begin{macrocode} +\keys_define:nn { NiceMatrix / rowcolors } + { + respect-blocks .bool_set:N = \l_@@_respect_blocks_bool , + respect-blocks .default:n = true , + cols .tl_set:N = \l_@@_cols_tl , + restart .bool_set:N = \l_@@_rowcolors_restart_bool , + restart .default:n = true , + unknown .code:n = \@@_error:n { Unknown~option~for~rowcolors } + } +% \end{macrocode} +% +% \medskip +% The command |\rowcolors| (accessible in the |code-before|) is inspired by the +% command |\rowcolors| of the package \pkg{xcolor} (with the option |table|). +% However, the command |\rowcolors| of \pkg{nicematrix} has \emph{not} the +% optional argument of the command |\rowcolors| of \pkg{xcolor}. Here is an +% example: |\rowcolors{1}{blue!10}{}[respect-blocks]|. +% +% |#1| (optional) is the color space ; +% |#2| is a list of intervals of rows ; +% |#3| is the first color ; +% |#4| is the second color ; +% |#5| is for the optional list of pairs key-value. +% \begin{macrocode} +\NewDocumentCommand \@@_rowcolors { O { } m m m O { } } + { +% \end{macrocode} +% The group is for the options. +% \begin{macrocode} + \group_begin: + \tl_clear_new:N \l_@@_cols_tl + \tl_set:Nn \l_@@_cols_tl { - } + \keys_set:nn { NiceMatrix / rowcolors } { #5 } +% \end{macrocode} +% The boolean |\l_tmpa_bool| will indicate whereas we are in a row of the first +% color or of the second color. +% \begin{macrocode} + \bool_set_true:N \l_tmpa_bool + \bool_lazy_and:nnT + \l_@@_respect_blocks_bool + { + \cs_if_exist_p:c + { c_@@_pos_of_blocks_ \int_use:N \g_@@_env_int _ seq } } + { +% \end{macrocode} +% We don't want to take into account a block which is completely in the ``first +% column'' of (number $0$) or in the ``last column'' and that's why we filter +% the sequence of the blocks (in a the sequence |\l_tmpa_seq|). +% \begin{macrocode} + \seq_set_eq:Nc \l_tmpb_seq + { c_@@_pos_of_blocks_ \int_use:N \g_@@_env_int _ seq } + \seq_set_filter:NNn \l_tmpa_seq \l_tmpb_seq + { \@@_not_in_exterior_p:nnnn ##1 } + } + \pgfpicture + \pgf@relevantforpicturesizefalse + \clist_map_inline:nn { #2 } + { + \tl_set:Nn \l_tmpa_tl { ##1 } + \tl_if_in:NnTF \l_tmpa_tl { - } + { \@@_cut_on_hyphen:w ##1 \q_stop } + { \tl_set:Nx \l_tmpb_tl { \int_use:N \c@iRow } } +% \end{macrocode} +% The counter |\l_tmpa_int| will be the index of the loop. +% \begin{macrocode} + \int_set:Nn \l_tmpa_int \l_tmpa_tl + \bool_if:NTF \l_@@_rowcolors_restart_bool + { \bool_set_true:N \l_tmpa_bool } + { \bool_set:Nn \l_tmpa_bool { \int_if_odd_p:n { \l_tmpa_tl } } } + \int_zero_new:N \l_tmpc_int + \int_set:Nn \l_tmpc_int \l_tmpb_tl + \int_do_until:nNnn \l_tmpa_int > \l_tmpc_int + { +% \end{macrocode} +% We will compute in |\l_tmpb_int| the last row of the ``block''. +% \begin{macrocode} + \int_set_eq:NN \l_tmpb_int \l_tmpa_int +% \end{macrocode} +% If the key |respect-blocks| is in force, we have to adjust that value (of +% course). +% \begin{macrocode} + \bool_lazy_and:nnT + \l_@@_respect_blocks_bool + { + \cs_if_exist_p:c + { c_@@_pos_of_blocks_ \int_use:N \g_@@_env_int _ seq } + } + { + \seq_set_filter:NNn \l_tmpb_seq \l_tmpa_seq + { \@@_intersect_our_row_p:nnnn ####1 } + \seq_map_inline:Nn \l_tmpb_seq { \@@_rowcolors_i:nnnn ####1 } +% \end{macrocode} +% Now, the last row of the block is computed in |\l_tmpb_int|. +% \begin{macrocode} + } + \tl_set:Nx \l_@@_rows_tl + { \int_use:N \l_tmpa_int - \int_use:N \l_tmpb_int } + \bool_if:NTF \l_tmpa_bool + { + \tl_if_blank:nF { #3 } + { + \tl_if_empty:nTF { #1 } + \color + { \color [ #1 ] } + { #3 } +% \end{macrocode} +% The command |\@@_cartesian_path:| takes in two implicit arguments: +% |\l_@@_cols_tl| and |\l_@@_row_tl|. +% \begin{macrocode} + \@@_cartesian_path: + \pgfusepathqfill + } + \bool_set_false:N \l_tmpa_bool + } + { + \tl_if_blank:nF { #4 } + { + \tl_if_empty:nTF { #1 } + \color + { \color [ #1 ] } + { #4 } +% \end{macrocode} +% The command |\@@_cartesian_path:| takes in two implicit arguments: +% |\l_@@_cols_tl| and |\l_@@_row_tl|. +% \begin{macrocode} + \@@_cartesian_path: + \pgfusepathqfill + } + \bool_set_true:N \l_tmpa_bool + } + \int_set:Nn \l_tmpa_int { \l_tmpb_int + 1 } + } + } + \endpgfpicture + \group_end: + } +% \end{macrocode} +% +% \bigskip +% \begin{macrocode} +\cs_new_protected:Npn \@@_rowcolors_i:nnnn #1 #2 #3 #4 + { + \int_compare:nNnT { #3 } > \l_tmpb_int + { \int_set:Nn \l_tmpb_int { #3 } } + } +% \end{macrocode} +% +% +% \bigskip +% \begin{macrocode} +\prg_new_conditional:Nnn \@@_not_in_exterior:nnnn p + { + \bool_lazy_or:nnTF + { \int_compare_p:nNn { #4 } = \c_zero_int } + { \int_compare_p:nNn { #2 } = { \@@_succ:n { \c@jCol } } } + \prg_return_false: + \prg_return_true: + } +% \end{macrocode} +% +% \bigskip +% The following command return |true| when the block intersects the row +% |\l_tmpa_int|. +% \begin{macrocode} +\prg_new_conditional:Nnn \@@_intersect_our_row:nnnn p + { + \bool_if:nTF + { + \int_compare_p:n { #1 <= \l_tmpa_int } + && + \int_compare_p:n { \l_tmpa_int <= #3 } + } + \prg_return_true: + \prg_return_false: + } +% \end{macrocode} +% +% +% +% \bigskip +% The following command uses two implicit arguments : |\l_@@_rows_tl| and +% |\l_@@_cols_tl| which are specifications for a set of rows and a set of +% columns. It creates a path but does \emph{not} fill it. It must be filled by +% another command after. +% \begin{macrocode} +\cs_new_protected:Npn \@@_cartesian_path: + { +% \end{macrocode} +% We begin the loop over the columns. +% \begin{macrocode} + \clist_map_inline:Nn \l_@@_cols_tl + { + \tl_set:Nn \l_tmpa_tl { ##1 } + \tl_if_in:NnTF \l_tmpa_tl { - } + { \@@_cut_on_hyphen:w ##1 \q_stop } + { \@@_cut_on_hyphen:w ##1 - ##1 \q_stop } + \tl_if_empty:NT \l_tmpa_tl { \tl_set:Nn \l_tmpa_tl { 1 } } + \tl_if_empty:NT \l_tmpb_tl + { \tl_set:Nx \l_tmpb_tl { \int_use:N \c@jCol } } + \int_compare:nNnT \l_tmpb_tl > \c@jCol + { \tl_set:Nx \l_tmpb_tl { \int_use:N \c@jCol } } + \@@_qpoint:n { col - \l_tmpa_tl } + \int_compare:nNnTF \l_@@_first_col_int = \l_tmpa_tl + { \dim_set:Nn \l_tmpc_dim { \pgf@x - 0.5 \arrayrulewidth } } + { \dim_set:Nn \l_tmpc_dim { \pgf@x + 0.5 \arrayrulewidth } } + \@@_qpoint:n { col - \@@_succ:n \l_tmpb_tl } + \dim_set:Nn \l_tmpa_dim { \pgf@x + 0.5 \arrayrulewidth } +% \end{macrocode} +% We begin the loop over the rows +% \begin{macrocode} + \clist_map_inline:Nn \l_@@_rows_tl + { + \tl_set:Nn \l_tmpa_tl { ####1 } + \tl_if_in:NnTF \l_tmpa_tl { - } + { \@@_cut_on_hyphen:w ####1 \q_stop } + { \@@_cut_on_hyphen:w ####1 - ####1 \q_stop } + \tl_if_empty:NT \l_tmpa_tl { \tl_set:Nn \l_tmpa_tl { 1 } } + \tl_if_empty:NT \l_tmpb_tl + { \tl_set:Nx \l_tmpb_tl { \int_use:N \c@iRow } } + \int_compare:nNnT \l_tmpb_tl > \c@iRow + { \tl_set:Nx \l_tmpb_tl { \int_use:N \c@iRow } } +% \end{macrocode} +% Now, the numbers of both rows are in |\l_tmpa_tl| and |\l_tmpb_tl|. +% \begin{macrocode} + \@@_qpoint:n { row - \@@_succ:n \l_tmpb_tl } + \dim_set:Nn \l_tmpb_dim { \pgf@y + 0.5 \arrayrulewidth } + \@@_qpoint:n { row - \l_tmpa_tl } + \dim_set:Nn \l_tmpd_dim { \pgf@y + 0.5 \arrayrulewidth } + \pgfpathrectanglecorners + { \pgfpoint \l_tmpc_dim \l_tmpd_dim } + { \pgfpoint \l_tmpa_dim \l_tmpb_dim } + } + } + } +% \end{macrocode} +% +% +% \bigskip +% When the user uses the key |colortbl-like|, the following command will +% be linked to |\cellcolor| in the tabular. +% \begin{macrocode} +\NewDocumentCommand \@@_cellcolor_tabular { O { } m } + { + \tl_gput_right:Nx \g_nicematrix_code_before_tl + { \cellcolor [ #1 ] { #2 } { \int_use:N \c@iRow - \int_use:N \c@jCol } } + } +% \end{macrocode} +% +% \bigskip +% When the user uses the key |colortbll-like|, the following command will +% be linked to |\rowcolor| in the tabular. +% \begin{macrocode} +\NewDocumentCommand \@@_rowcolor_tabular { O { } m } + { + \tl_gput_right:Nx \g_nicematrix_code_before_tl + { + \exp_not:N \rectanglecolor [ #1 ] { #2 } + { \int_use:N \c@iRow - \int_use:N \c@jCol } + { \int_use:N \c@iRow - \exp_not:n { \int_use:N \c@jCol } } + } + } +% \end{macrocode} +% +% \bigskip +% \begin{macrocode} +\NewDocumentCommand \@@_columncolor_preamble { O { } m } + { + \int_compare:nNnT \c@iRow = 1 + { +% \end{macrocode} +% You use |gput_left| because we want the specification of colors for the +% columns drawn before the specifications of color for the rows (and the cells). +% \begin{macrocode} + \tl_gput_left:Nx \g_nicematrix_code_before_tl + { \exp_not:N \columncolor [ #1 ] { #2 } { \int_use:N \c@jCol } } + } + } +% \end{macrocode} +% +% +% +% +% \bigskip % \subsection*{The vertical rules} % % We give to the user the possibility to define new types of columns (with @@ -7266,140 +11672,635 @@ version 2005/12/01 or later. % |\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 ``"|"''. % -% -% Remark first that the natural way to do that would be to redefine the -% specifier ``"|"'' with |\newcolumntype|: -% \begin{Verbatim}[commandchars=\~\#\+] -% \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"). +% \bigskip +% The following command will be executed in the |internal-code-after|. The rule +% will be drawn \emph{before} the column |#1|. |#2| is the number of consecutive +% occurrences of \verb+|+. +% \begin{macrocode} +\cs_new_protected:Npn \@@_vline:nn #1 #2 + { +% \end{macrocode} +% The following test is for the case where the user don't use all the columns +% specified in the preamble of the environment (for instance, a preamble of +% \verb+|c|c|c|+ but only two columns used). +% \begin{macrocode} + \int_compare:nNnT { #1 } < { \c@jCol + 2 } + { + \pgfpicture + \@@_vline_i:nn { #1 } { #2 } + \endpgfpicture + } + } +% \end{macrocode} % -% 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}|). +% \begin{macrocode} +\cs_new_protected:Npn \@@_vline_i:nn #1 #2 + { +% \end{macrocode} +% |\l_tmpa_tl| is the number of row and |\l_tmpb_tl| the number of column. When +% we have found a row corresponding to a rule to draw, we note its number in +% |\l_tmpc_tl|. +% \begin{macrocode} + \tl_set:Nx \l_tmpb_tl { #1 } + \tl_clear_new:N \l_tmpc_tl + \int_step_variable:nNn \c@iRow \l_tmpa_tl + { +% \end{macrocode} +% The boolean |\g_tmpa_bool| indicates whether the small vertical rule will be +% drawn. If we find that it is in a block (a real block, created by |\Block| or +% a virtual block corresponding to a dotted line, created by |\Cdots|, |\Vdots|, +% etc.), we will set |\g_tmpa_bool| to |false| and the small vertical rule won't +% be drawn. +% \begin{macrocode} + \bool_gset_true:N \g_tmpa_bool + \seq_map_inline:Nn \g_@@_pos_of_blocks_seq + { \@@_test_if_vline_in_block:nnnn ##1 } + \seq_map_inline:Nn \g_@@_pos_of_xdots_seq + { \@@_test_if_vline_in_block:nnnn ##1 } + \seq_map_inline:Nn \g_@@_pos_of_stroken_blocks_seq + { \@@_test_if_vline_in_stroken_block:nnnn ##1 } + \clist_if_empty:NF \l_@@_except_corners_clist + \@@_test_in_corner_v: + \bool_if:NTF \g_tmpa_bool + { + \tl_if_empty:NT \l_tmpc_tl +% \end{macrocode} +% We keep in memory that we have a rule to draw. +% \begin{macrocode} + { \tl_set_eq:NN \l_tmpc_tl \l_tmpa_tl } + } + { + \tl_if_empty:NF \l_tmpc_tl + { + \@@_vline_ii:nnnn + { #1 } + { #2 } + \l_tmpc_tl + { \int_eval:n { \l_tmpa_tl - 1 } } + \tl_clear:N \l_tmpc_tl + } + } + } + \tl_if_empty:NF \l_tmpc_tl + { + \@@_vline_ii:nnnn + { #1 } + { #2 } + \l_tmpc_tl + { \int_use:N \c@iRow } + \tl_clear:N \l_tmpc_tl + } + } +% \end{macrocode} % -% 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 in |\@@_OnlyMainNiceMatrix:n| must be effective in -% each row and not once for all when the preamble is constructed). +% \bigskip +% \begin{macrocode} +\cs_new_protected:Npn \@@_test_in_corner_v: + { + \int_compare:nNnTF \l_tmpb_tl = { \@@_succ:n \c@jCol } + { + \seq_if_in:NxT + \l_@@_empty_corner_cells_seq + { \l_tmpa_tl - \@@_pred:n \l_tmpb_tl } + { \bool_set_false:N \g_tmpa_bool } + } + { + \seq_if_in:NxT + \l_@@_empty_corner_cells_seq + { \l_tmpa_tl - \l_tmpb_tl } + { + \int_compare:nNnTF \l_tmpb_tl = 1 + { \bool_set_false:N \g_tmpa_bool } + { + \seq_if_in:NxT + \l_@@_empty_corner_cells_seq + { \l_tmpa_tl - \@@_pred:n \l_tmpb_tl } + { \bool_set_false:N \g_tmpa_bool } + } + } + } + } +% \end{macrocode} % -% \medskip +% \bigskip +% |#1| is the number of the column; |#2| is the number of vertical rules to +% draw (with potentially a color between); |#3| and |#4| are the number of the +% rows between which the rule has to be drawn. % \begin{macrocode} -\cs_new_protected:Npn \@@_vline: { \@@_OnlyMainNiceMatrix:n { \@@_vline_i: } } +\cs_new_protected:Npn \@@_vline_ii:nnnn #1 #2 #3 #4 + { + \pgfrememberpicturepositiononpagetrue + \pgf@relevantforpicturesizefalse + \@@_qpoint:n { row - #3 } + \dim_set_eq:NN \l_tmpa_dim \pgf@y + \@@_qpoint:n { col - #1 } + \dim_set_eq:NN \l_tmpb_dim \pgf@x + \@@_qpoint:n { row - \@@_succ:n { #4 } } + \dim_set_eq:NN \l_tmpc_dim \pgf@y + \bool_lazy_and:nnT + { \int_compare_p:nNn { #2 } > 1 } + { ! \tl_if_blank_p:V \CT@drsc@ } + { + \group_begin: + \CT@drsc@ + \dim_add:Nn \l_tmpa_dim { 0.5 \arrayrulewidth } + \dim_sub:Nn \l_tmpc_dim { 0.5 \arrayrulewidth } + \dim_set:Nn \l_tmpd_dim + { \l_tmpb_dim - ( \doublerulesep + \arrayrulewidth ) * ( #2 - 1 ) } + \pgfpathrectanglecorners + { \pgfpoint \l_tmpb_dim \l_tmpa_dim } + { \pgfpoint \l_tmpd_dim \l_tmpc_dim } + \pgfusepathqfill + \group_end: + } + \pgfpathmoveto { \pgfpoint \l_tmpb_dim \l_tmpa_dim } + \pgfpathlineto { \pgfpoint \l_tmpb_dim \l_tmpc_dim } + \prg_replicate:nn { #2 - 1 } + { + \dim_sub:Nn \l_tmpb_dim \arrayrulewidth + \dim_sub:Nn \l_tmpb_dim \doublerulesep + \pgfpathmoveto { \pgfpoint \l_tmpb_dim \l_tmpa_dim } + \pgfpathlineto { \pgfpoint \l_tmpb_dim \l_tmpc_dim } + } + \CT@arc@ + \pgfsetlinewidth { 1.1 \arrayrulewidth } + \pgfsetrectcap + \pgfusepathqstroke + } % \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}. +% \bigskip +% The following draws a complete vertical rule in the column |#1| (|#2| is the +% number of consecutive rules specified by the number of \verb+|+ in the +% preamble). This command will be used if there is no block in the array (and +% the key |except-corners| is not used). % \begin{macrocode} -\cs_set_eq:NN \@@_vline_i: \vline +\cs_new_protected:Npn \@@_vline_i_complete:nn #1 #2 + { \@@_vline_ii:nnnn { #1 } { #2 } 1 { \int_use:N \c@iRow } } % \end{macrocode} % % \bigskip -% The command |\@@_draw_vlines| will be executed when the user uses the option -% |vlines| (which draws all the vlines of the array). +% The command |\@@_draw_hlines:| draws all the vertical rules excepted in the +% blocks, in the virtual blocks (determined by a command such as |\Cdots|) and in +% the corners (if the key |except-corners| is used). % \begin{macrocode} \cs_new_protected:Npn \@@_draw_vlines: { - \group_begin: + \int_step_inline:nnn + { \bool_if:NTF \l_@@_NiceArray_bool 1 2 } + { \bool_if:NTF \l_@@_NiceArray_bool { \@@_succ:n \c@jCol } \c@jCol } + { \@@_vline:nn { ##1 } 1 } + } % \end{macrocode} -% The command |\CT@arc@| is a command of color from \pkg{colortbl}. +% +% +% +% \subsection*{The horizontal rules} +% +% \bigskip +% The following command will be executed in the |internal-code-after|. The rule +% will be drawn \emph{before} the row |#1|. |#2| is the number of consecutive +% occurrences of |\Hline|. % \begin{macrocode} - \bool_if:NT \c_@@_colortbl_loaded_bool \CT@arc@ - \pgfpicture - \pgfrememberpicturepositiononpagetrue - \pgf@relevantforpicturesizefalse - \pgfsetlinewidth \arrayrulewidth +\cs_new_protected:Npn \@@_hline:nn #1 #2 + { + \pgfpicture + \@@_hline_i:nn { #1 } { #2 } + \endpgfpicture + } % \end{macrocode} -% First, we compute in |\l_tmpa_dim| the height of the rules we have to draw. +% % \begin{macrocode} - \@@_qpoint: {row - 1 } - \dim_set_eq:NN \l_tmpa_dim \pgf@y - \pgfusepathqfill - \@@_qpoint: { row - \@@_succ:n \c@iRow } - \dim_sub:Nn \l_tmpa_dim \pgf@y - \pgfusepathqfill +\cs_new_protected:Npn \@@_hline_i:nn #1 #2 + { % \end{macrocode} -% We translate vertically to take into account the potential ``last row''. +% |\l_tmpa_tl| is the number of row and |\l_tmpb_tl| the number of column. Whe, +% we have found a column corresponding to a rule to draw, we note its number in +% |\l_tmpc_tl|. % \begin{macrocode} - \dim_zero:N \l_tmpb_dim - \int_compare:nNnT \l_@@_last_row_int > { -1 } + \tl_set:Nn \l_tmpa_tl { #1 } + \tl_clear_new:N \l_tmpc_tl + \int_step_variable:nNn \c@jCol \l_tmpb_tl { - \dim_set_eq:NN \l_tmpb_dim \g_@@_dp_last_row_dim - \dim_add:Nn \l_tmpb_dim \g_@@_ht_last_row_dim % \end{macrocode} -% We adjust the value of |\l_tmpa_dim| by the width of the horizontal rule just -% before the ``last row''. +% The boolean |\g_tmpa_bool| indicates whether the small horizontal rule will be +% drawn. If we find that it is in a block (a real block, created by |\Block| or +% a virtual block corresponding to a dotted line, created by |\Cdots|, |\Vdots|, +% etc.), we will set |\g_tmpa_bool| to |false| and the small horizontal rule won't +% be drawn. +% \begin{macrocode} + \bool_gset_true:N \g_tmpa_bool + \seq_map_inline:Nn \g_@@_pos_of_blocks_seq + { \@@_test_if_hline_in_block:nnnn ##1 } + \seq_map_inline:Nn \g_@@_pos_of_xdots_seq + { \@@_test_if_hline_in_block:nnnn ##1 } + \seq_map_inline:Nn \g_@@_pos_of_stroken_blocks_seq + { \@@_test_if_hline_in_stroken_block:nnnn ##1 } + \clist_if_empty:NF \l_@@_except_corners_clist \@@_test_in_corner_h: + \bool_if:NTF \g_tmpa_bool + { + \tl_if_empty:NT \l_tmpc_tl +% \end{macrocode} +% We keep in memory that we have a rule to draw. +% \begin{macrocode} + { \tl_set_eq:NN \l_tmpc_tl \l_tmpb_tl } + } + { + \tl_if_empty:NF \l_tmpc_tl + { + \@@_hline_ii:nnnn + { #1 } + { #2 } + \l_tmpc_tl + { \int_eval:n { \l_tmpb_tl - 1 } } + \tl_clear:N \l_tmpc_tl + } + } + } + \tl_if_empty:NF \l_tmpc_tl + { + \@@_hline_ii:nnnn + { #1 } + { #2 } + \l_tmpc_tl + { \int_use:N \c@jCol } + \tl_clear:N \l_tmpc_tl + } + } +% \end{macrocode} +% +% \bigskip % \begin{macrocode} - \@@_qpoint: { row - \@@_succ:n\c@iRow } - \dim_add:Nn \l_tmpa_dim \pgf@y - \@@_qpoint: { row - \@@_succ:n \g_@@_row_total_int } - \dim_sub:Nn \l_tmpa_dim \pgf@y - \dim_sub:Nn \l_tmpa_dim \l_tmpb_dim +\cs_new_protected:Npn \@@_test_in_corner_h: + { + \int_compare:nNnTF \l_tmpa_tl = { \@@_succ:n \c@iRow } + { + \seq_if_in:NxT + \l_@@_empty_corner_cells_seq + { \@@_pred:n \l_tmpa_tl - \l_tmpb_tl } + { \bool_set_false:N \g_tmpa_bool } } + { + \seq_if_in:NxT + \l_@@_empty_corner_cells_seq + { \l_tmpa_tl - \l_tmpb_tl } + { + \int_compare:nNnTF \l_tmpa_tl = 1 + { \bool_set_false:N \g_tmpa_bool } + { + \seq_if_in:NxT + \l_@@_empty_corner_cells_seq + { \@@_pred:n \l_tmpa_tl - \l_tmpb_tl } + { \bool_set_false:N \g_tmpa_bool } + } + } + } + } +% \end{macrocode} +% +% \bigskip +% |#1| is the number of the row; |#2| is the number of horizontal rules to +% draw (with potentially a color between); |#3| and |#4| are the number of the +% columns between which the rule has to be drawn. +% \begin{macrocode} +\cs_new_protected:Npn \@@_hline_ii:nnnn #1 #2 #3 #4 + { + \pgfrememberpicturepositiononpagetrue + \pgf@relevantforpicturesizefalse + \@@_qpoint:n { col - #3 } + \dim_set_eq:NN \l_tmpa_dim \pgf@x + \@@_qpoint:n { row - #1 } + \dim_set_eq:NN \l_tmpb_dim \pgf@y + \@@_qpoint:n { col - \@@_succ:n { #4 } } + \dim_set_eq:NN \l_tmpc_dim \pgf@x + \bool_lazy_and:nnT + { \int_compare_p:nNn { #2 } > 1 } + { ! \tl_if_blank_p:V \CT@drsc@ } + { + \group_begin: + \CT@drsc@ + \dim_set:Nn \l_tmpd_dim + { \l_tmpb_dim - ( \doublerulesep + \arrayrulewidth ) * ( #2 - 1 ) } + \pgfpathrectanglecorners + { \pgfpoint \l_tmpa_dim \l_tmpb_dim } + { \pgfpoint \l_tmpc_dim \l_tmpd_dim } + \pgfusepathqfill + \group_end: + } + \pgfpathmoveto { \pgfpoint \l_tmpa_dim \l_tmpb_dim } + \pgfpathlineto { \pgfpoint \l_tmpc_dim \l_tmpb_dim } + \prg_replicate:nn { #2 - 1 } + { + \dim_sub:Nn \l_tmpb_dim \arrayrulewidth + \dim_sub:Nn \l_tmpb_dim \doublerulesep + \pgfpathmoveto { \pgfpoint \l_tmpa_dim \l_tmpb_dim } + \pgfpathlineto { \pgfpoint \l_tmpc_dim \l_tmpb_dim } + } + \CT@arc@ + \pgfsetlinewidth { 1.1 \arrayrulewidth } + \pgfsetrectcap + \pgfusepathqstroke + } % \end{macrocode} % -% Now, we can draw the lines with a loop. +% \bigskip % \begin{macrocode} +\cs_new_protected:Npn \@@_hline_i_complete:nn #1 #2 + { \@@_hline_ii:nnnn { #1 } { #2 } 1 { \int_use:N \c@jCol } } +% \end{macrocode} +% +% \bigskip +% The command |\@@_draw_hlines:| draws all the horizontal rules excepted in the +% blocks (even the virtual drawn determined by commands such as |\Cdots| and in +% the corners (if the key |except-corners| is used). +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_hlines: + { \int_step_inline:nnn - { \bool_if:NTF \l_@@_NiceArray_bool 1 2 } - { \bool_if:NTF \l_@@_NiceArray_bool { \@@_succ:n \c@jCol } \c@jCol } - { - \pgfpathmoveto + { \bool_if:NTF \l_@@_NiceArray_bool 1 2 } + { \bool_if:NTF \l_@@_NiceArray_bool { \@@_succ:n \c@iRow } \c@iRow } + { \@@_hline:nn { ##1 } 1 } + } +% \end{macrocode} +% +% +% \medskip +% The command |\@@_Hline:| will be linked to |\Hline| in the environments of \pkg{nicematrix}. +% \begin{macrocode} +\cs_set:Npn \@@_Hline: { \noalign { \ifnum 0 = `} \fi \@@_Hline_i:n { 1 } } +% \end{macrocode} +% +% \medskip +% The argument of the command |\@@_Hline_i:n| is the number of successive +% |\Hline| found. +% \begin{macrocode} +\cs_set:Npn \@@_Hline_i:n #1 + { + \peek_meaning_ignore_spaces:NTF \Hline + { \@@_Hline_ii:nn { #1 + 1 } } + { \@@_Hline_iii:n { #1 } } + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_set:Npn \@@_Hline_ii:nn #1 #2 { \@@_Hline_i:n { #1 } } +% \end{macrocode} +% +% \begin{macrocode} +\cs_set:Npn \@@_Hline_iii:n #1 + { + \skip_vertical:n + { + \arrayrulewidth * ( #1 ) + + \doublerulesep * ( \int_max:nn 0 { #1 - 1 } ) + } + \tl_gput_right:Nx \g_@@_internal_code_after_tl + { \@@_hline:nn { \@@_succ:n { \c@iRow } } { #1 } } + \ifnum 0 = `{ \fi } + } +% \end{macrocode} +% +% \subsection*{The key hvlines} +% +% +% The following command tests wether the current position in the array (given by +% |\l_tmpa_tl| for the row and |\l_tmpb_tl| for the col) would provide an +% horizontal rule towards the right in the block delimited by the four arguments +% |#1|, |#2|, |#3| and |#4|. If this rule would be in the block (it must not be +% drawn), the boolean |\l_tmpa_bool| is set to |false|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_test_if_hline_in_block:nnnn #1 #2 #3 #4 + { + \bool_lazy_all:nT + { + { \int_compare_p:nNn \l_tmpa_tl > { #1 } } + { \int_compare_p:nNn \l_tmpa_tl < { #3 + 1 } } + { \int_compare_p:nNn \l_tmpb_tl > { #2 - 1 } } + { \int_compare_p:nNn \l_tmpb_tl < { #4 + 1 } } + } + { \bool_gset_false:N \g_tmpa_bool } + } +% \end{macrocode} +% +% The same for vertical rules. +% \begin{macrocode} +\cs_new_protected:Npn \@@_test_if_vline_in_block:nnnn #1 #2 #3 #4 + { + \bool_lazy_all:nT + { + { \int_compare_p:nNn \l_tmpa_tl > { #1 - 1 } } + { \int_compare_p:nNn \l_tmpa_tl < { #3 + 1 } } + { \int_compare_p:nNn \l_tmpb_tl > { #2 } } + { \int_compare_p:nNn \l_tmpb_tl < { #4 + 1 } } + } + { \bool_gset_false:N \g_tmpa_bool } + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_test_if_hline_in_stroken_block:nnnn #1 #2 #3 #4 + { + \bool_lazy_all:nT + { + { \int_compare_p:nNn \l_tmpa_tl > { #1 - 1 } } + { \int_compare_p:nNn \l_tmpa_tl < { #3 + 2 } } + { \int_compare_p:nNn \l_tmpb_tl > { #2 - 1 } } + { \int_compare_p:nNn \l_tmpb_tl < { #4 + 1 } } + } + { \bool_gset_false:N \g_tmpa_bool } + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_test_if_vline_in_stroken_block:nnnn #1 #2 #3 #4 + { + \bool_lazy_all:nT + { + { \int_compare_p:nNn \l_tmpa_tl > { #1 - 1 } } + { \int_compare_p:nNn \l_tmpa_tl < { #3 + 1 } } + { \int_compare_p:nNn \l_tmpb_tl > { #2 - 1 } } + { \int_compare_p:nNn \l_tmpb_tl < { #4 + 2 } } + } + { \bool_gset_false:N \g_tmpa_bool } + } +% \end{macrocode} +% +% \bigskip +% \subsubsection*{The key except-corners} +% +% When the key |except-corners| is raised, the rules are not drawn in the +% corners. Of course, we have to compute the corners before we begin to draw the +% rules. +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_compute_corners: + { +% \end{macrocode} +% The sequence |\l_@@_empty_corner_cells_seq| will be the sequence of all the +% empty cells (and not in a block) considered in the corners of the array. +% \begin{macrocode} + \seq_clear_new:N \l_@@_empty_corner_cells_seq + \clist_map_inline:Nn \l_@@_except_corners_clist + { + \str_case:nnF { ##1 } { - \pgfpointadd - { \@@_qpoint: { col - ##1 } } - { - \pgfpoint - { - -0.5 \arrayrulewidth - \int_compare:nNnT { ##1 } = 1 - { - \int_compare:nNnT \l_@@_first_col_int = 1 - { + \arrayrulewidth } - } - } - { \l_tmpb_dim } - } + { NW } + { \@@_compute_a_corner:nnnnnn 1 1 1 1 \c@iRow \c@jCol } + { NE } + { \@@_compute_a_corner:nnnnnn 1 \c@jCol 1 { -1 } \c@iRow 1 } + { SW } + { \@@_compute_a_corner:nnnnnn \c@iRow 1 { -1 } 1 1 \c@jCol } + { SE } + { \@@_compute_a_corner:nnnnnn \c@iRow \c@jCol { -1 } { -1 } 1 1 } + } + { \@@_error:nn { bad~corner } { ##1 } } + } + } +% \end{macrocode} +% +% +% \bigskip +% ``Computing a corner'' is determining all the empty cells (which are not in a +% block) that belong to that corner. These cells will be added to the sequence +% |\l_@@_empty_corner_cells_seq|. +% +% \medskip +% The six arguments of |\@@_compute_a_corner:nnnnnn| are as follow: +% \begin{itemize} +% \item |#1| and |#2| are the number of row and column of the cell which is +% actually in the corner; +% \item |#3| and |#4| are the steps in rows and the step in columns when moving +% from the corner; +% \item |#5| is the number of the final row when scanning the rows from the +% corner; +% \item |#6| is the number of the final column when scanning the columns from +% the corner. +% \end{itemize} +% \begin{macrocode} +\cs_new_protected:Npn \@@_compute_a_corner:nnnnnn #1 #2 #3 #4 #5 #6 + { +% \end{macrocode} +% For the explanations and the name of the variables, we consider that we are +% computing the left-upper corner. +% +% First, we try to determine which is the last empty cell (and not in a block: +% we won't add that precision any longer) in the column of number~$1$. The flag +% |\l_tmpa_bool| will be raised when a non-empty cell is found. +% \begin{macrocode} + \bool_set_false:N \l_tmpa_bool + \int_zero_new:N \l_@@_last_empty_row_int + \int_set:Nn \l_@@_last_empty_row_int { #1 } + \int_step_inline:nnnn { #1 } { #3 } { #5 } + { + \@@_test_if_cell_in_a_block:nn { ##1 } { \int_eval:n { #2 } } + \bool_lazy_or:nnTF + { + \cs_if_exist_p:c + { pgf @ sh @ ns @ \@@_env: - ##1 - \int_eval:n { #2 } } + } + \l_tmpb_bool + { \bool_set_true:N \l_tmpa_bool } + { + \bool_if:NF \l_tmpa_bool + { \int_set:Nn \l_@@_last_empty_row_int { ##1 } } } - \pgfpathlineto + } +% \end{macrocode} +% Now, you determine the last empty cell in the row of number~$1$. +% \begin{macrocode} + \bool_set_false:N \l_tmpa_bool + \int_zero_new:N \l_@@_last_empty_column_int + \int_set:Nn \l_@@_last_empty_column_int { #2 } + \int_step_inline:nnnn { #2 } { #4 } { #6 } + { + \@@_test_if_cell_in_a_block:nn { \int_eval:n { #1 } } { ##1 } + \bool_lazy_or:nnTF + \l_tmpb_bool { - \pgfpointadd - { \@@_qpoint: { col - ##1 } } + \cs_if_exist_p:c + { pgf @ sh @ ns @ \@@_env: - \int_eval:n { #1 } - ##1 } + } + { \bool_set_true:N \l_tmpa_bool } + { + \bool_if:NF \l_tmpa_bool + { \int_set:Nn \l_@@_last_empty_column_int { ##1 } } + } + } +% \end{macrocode} +% Now, we loop over the rows. +% \begin{macrocode} + \int_step_inline:nnnn { #1 } { #3 } \l_@@_last_empty_row_int + { +% \end{macrocode} +% We treat the row number |##1| with another loop. +% \begin{macrocode} + \bool_set_false:N \l_tmpa_bool + \int_step_inline:nnnn { #2 } { #4 } \l_@@_last_empty_column_int + { + \@@_test_if_cell_in_a_block:nn { ##1 } { ####1 } + \bool_lazy_or:nnTF + \l_tmpb_bool + { + \cs_if_exist_p:c + { pgf @ sh @ ns @ \@@_env: - ##1 - ####1 } + } + { \bool_set_true:N \l_tmpa_bool } { - \pgfpoint + \bool_if:NF \l_tmpa_bool { - -0.5 \arrayrulewidth - \int_compare:nNnT { ##1 } = 1 - { - \int_compare:nNnT \l_@@_first_col_int = 1 - { + \arrayrulewidth } - } - } - { \l_tmpb_dim + \l_tmpa_dim } + \int_set:Nn \l_@@_last_empty_column_int { ####1 } + \seq_put_right:Nn + \l_@@_empty_corner_cells_seq + { ##1 - ####1 } + } } } } - \pgfusepathqstroke - \endpgfpicture - \group_end: } % \end{macrocode} % +% \bigskip +% The following macro tests whether a cell is in (at least) one of +% the blocks of the array (or in a cell with a |\diagbox|). +% +% The flag |\l_tmpb_bool| will be raised if the cell |#1|-|#2| is in a block (or +% in a cell with a |\diagbox|). +% \begin{macrocode} +\cs_new_protected:Npn \@@_test_if_cell_in_a_block:nn #1 #2 + { + \int_set:Nn \l_tmpa_int { #1 } + \int_set:Nn \l_tmpb_int { #2 } + \bool_set_false:N \l_tmpb_bool + \seq_map_inline:Nn \g_@@_pos_of_blocks_seq + { \@@_test_if_cell_in_block:nnnnnnn \l_tmpa_int \l_tmpb_int ##1 } + } +% \end{macrocode} +% +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_test_if_cell_in_block:nnnnnnn #1 #2 #3 #4 #5 #6 + { + \int_compare:nNnT { #3 } < { \@@_succ:n { #1 } } + { + \int_compare:nNnT { #1 } < { \@@_succ:n { #5 } } + { + \int_compare:nNnT { #4 } < { \@@_succ:n { #2 } } + { + \int_compare:nNnT { #2 } < { \@@_succ:n { #6 } } + { \bool_set_true:N \l_tmpb_bool } + } + } + } + } +% \end{macrocode} % +% % \bigskip % \subsection*{The commands to draw dotted lines to separate columns and rows} % % These commands don't use the normal nodes, the medium nor the large nodes. -% They only use the |col|-nodes and the |row|-nodes. +% They only use the |col| nodes and the |row| nodes. % % \textbf{Horizontal dotted lines}\par\nobreak % @@ -7407,14 +12308,10 @@ version 2005/12/01 or later. % The following command must \emph{not} be protected because it's meant to be % expanded in a |\noalign|. % \begin{macrocode} -\bool_if:NTF \c_@@_draft_bool - { \cs_new:Npn \@@_hdottedline: { } } +\cs_new:Npn \@@_hdottedline: { - \cs_new:Npn \@@_hdottedline: - { - \noalign { \skip_vertical:N 2\l_@@_radius_dim } - \@@_hdottedline_i: - } + \noalign { \skip_vertical:N 2\l_@@_radius_dim } + \@@_hdottedline_i: } % \end{macrocode} % @@ -7424,7 +12321,7 @@ version 2005/12/01 or later. \cs_new_protected:Npn \@@_hdottedline_i: { % \end{macrocode} -% We write in the code-after the instruction that will eventually draw the +% We write in the code-after the instruction that will actually draw the % dotted line. It's not possible to draw this dotted line now because we don't % know the length of the line (we don't even know the number of columns). % \begin{macrocode} @@ -7444,7 +12341,9 @@ version 2005/12/01 or later. % \end{macrocode} % We recall that, when externalization is used, |\tikzpicture| and % |\endtikzpicture| (or |\pgfpicture| and |\endpgfpicture|) must be directly -% ``visible''. +% ``visible''. That's why we construct now a version of |\@@_hdottedline:n| with +% the right environment (|\begin{pgfpicture}\end{pgfpicture}| or +% |\begin{tikzpiture}...\end{tikzpicture}|). % \begin{macrocode} \cs_new_protected:Npx \@@_hdottedline:n #1 { @@ -7463,7 +12362,7 @@ version 2005/12/01 or later. \cs_new_protected:Npn \@@_hdottedline_i:n #1 { \pgfrememberpicturepositiononpagetrue - \@@_qpoint: { row - #1 } + \@@_qpoint:n { 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 ``"|"'' @@ -7489,7 +12388,7 @@ version 2005/12/01 or later. % \hline % 1 & 2 & 3 & 4 \\ % \hdottedline -% 1 & 2 & 3 & 4 \\ +% 1 & 2 & 3 & 4 % \end{bNiceMatrix} % \end{BVerbatim} % $\begin{bNiceMatrix} @@ -7497,7 +12396,7 @@ version 2005/12/01 or later. % \hline % 1 & 2 & 3 & 4 \\ % \hdottedline -% 1 & 2 & 3 & 4 \\ +% 1 & 2 & 3 & 4 % \end{bNiceMatrix}$ % % \smallskip @@ -7511,7 +12410,7 @@ version 2005/12/01 or later. % \hline % 1 & 2 & 3 & 4 \\ % \hdottedline -% 1 & 2 & 3 & 4 \\ +% 1 & 2 & 3 & 4 % \end{bNiceMatrix} % \end{BVerbatim} % $\begin{bNiceMatrix}[margin] @@ -7519,17 +12418,29 @@ version 2005/12/01 or later. % \hline % 1 & 2 & 3 & 4 \\ % \hdottedline -% 1 & 2 & 3 & 4 \\ +% 1 & 2 & 3 & 4 % \end{bNiceMatrix}$ % % \medskip % \begin{macrocode} - \@@_qpoint: { col - 1 } + \@@_qpoint:n { col - 1 } \dim_set:Nn \l_@@_x_initial_dim - { \pgf@x + \arraycolsep - \l_@@_left_margin_dim } - \@@_qpoint: { col - \@@_succ:n \c@jCol } + { + \pgf@x + +% \end{macrocode} +% We do a reduction by |\arraycolsep| for the environments with delimiters (and +% not for the other). +% \begin{macrocode} + \bool_if:NTF \l_@@_NiceArray_bool \c_zero_dim \arraycolsep + - \l_@@_left_margin_dim + } + \@@_qpoint:n { col - \@@_succ:n \c@jCol } \dim_set:Nn \l_@@_x_final_dim - { \pgf@x - \arraycolsep + \l_@@_right_margin_dim } + { + \pgf@x - + \bool_if:NTF \l_@@_NiceArray_bool \c_zero_dim \arraycolsep + + \l_@@_right_margin_dim + } % \end{macrocode} % For reasons purely aesthetic, we do an adjustment in the case of a rounded % bracket. The correction by |0.5 \l_@@_inter_dots_dim| is \emph{ad hoc} for a @@ -7544,7 +12455,7 @@ version 2005/12/01 or later. % \end{macrocode} % % \medskip -% As for now, we have no option to control the style of the lines drawn by +% As of now, we have no option to control the style of the lines drawn by % |\hdottedline| and the specifier ``|:|'' in the preamble. That's why we impose % the style |standard|. % \begin{macrocode} @@ -7561,29 +12472,25 @@ version 2005/12/01 or later. % % \medskip % \begin{macrocode} -\bool_if:nTF \c_@@_draft_bool - { \cs_new_protected:Npn \@@_vdottedline:n #1 { } } +\cs_new_protected:Npn \@@_vdottedline:n #1 { - \cs_new_protected:Npn \@@_vdottedline:n #1 - { - \bool_set_true:N \l_@@_initial_open_bool - \bool_set_true:N \l_@@_final_open_bool + \bool_set_true:N \l_@@_initial_open_bool + \bool_set_true:N \l_@@_final_open_bool % \end{macrocode} % We recall that, when externalization is used, |\tikzpicture| and % |\endtikzpicture| (or |\pgfpicture| and |\endpgfpicture|) must be directly % ``visible''. % \begin{macrocode} - \bool_if:NTF \c_@@_tikz_loaded_bool - { - \tikzpicture - \@@_vdottedline_i:n { #1 } - \endtikzpicture - } - { - \pgfpicture - \@@_vdottedline_i:n { #1 } - \endpgfpicture - } + \bool_if:NTF \c_@@_tikz_loaded_bool + { + \tikzpicture + \@@_vdottedline_i:n { #1 } + \endtikzpicture + } + { + \pgfpicture + \@@_vdottedline_i:n { #1 } + \endpgfpicture } } % \end{macrocode} @@ -7593,11 +12500,13 @@ version 2005/12/01 or later. \cs_new_protected:Npn \@@_vdottedline_i:n #1 { % \end{macrocode} -% The command |\CT@arc@| is a command of color from \pkg{colortbl}. +% The command |\CT@arc@| is a command of \pkg{colortbl} which sets the color of +% the rules in the array. The package \pkg{nicematrix} uses it even if \pkg{colortbl} is not +% loaded. % \begin{macrocode} - \bool_if:NT \c_@@_colortbl_loaded_bool \CT@arc@ + \CT@arc@ \pgfrememberpicturepositiononpagetrue - \@@_qpoint: { col - \int_eval:n { #1 + 1 } } + \@@_qpoint:n { 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 ``"|"'' @@ -7605,16 +12514,16 @@ version 2005/12/01 or later. % \begin{macrocode} \dim_set:Nn \l_@@_x_initial_dim { \pgf@x - \l_@@_radius_dim } \dim_set:Nn \l_@@_x_final_dim { \pgf@x - \l_@@_radius_dim } - \@@_qpoint: { row - 1 } + \@@_qpoint:n { 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_set:Nn \l_@@_y_initial_dim { \pgf@y - 0.5 \l_@@_inter_dots_dim } - \@@_qpoint: { row - \@@_succ:n \c@iRow } + \@@_qpoint:n { row - \@@_succ:n \c@iRow } \dim_set:Nn \l_@@_y_final_dim { \pgf@y + 0.5 \l_@@_inter_dots_dim } % \end{macrocode} -% As for now, we have no option to control the style of the lines drawn by +% As of now, we have no option to control the style of the lines drawn by % |\hdottedline| and the specifier ``|:|'' in the preamble. That's why we impose % the style |standard|. % \begin{macrocode} @@ -7623,7 +12532,7 @@ version 2005/12/01 or later. } % \end{macrocode} % -% +% % % \bigskip % \subsection*{The environment \{NiceMatrixBlock\}} @@ -7682,7 +12591,7 @@ version 2005/12/01 or later. \cs_gset:cpn { @@ _ max _ cell _ width _ \int_use:N \g_@@_NiceMatrixBlock_int } % \end{macrocode} -% For technical reasons, we have to include the width of an eventual rule on the +% For technical reasons, we have to include the width of a potential rule on the % right side of the cells. % \begin{macrocode} { \dim_eval:n { \g_@@_max_cell_width_dim + \arrayrulewidth } } @@ -7701,6 +12610,26 @@ version 2005/12/01 or later. \cs_generate_variant:Nn \dim_max:nn { v n } % \end{macrocode} % +% +% \bigskip +% The following command is called in |\@@_use_arraybox_with_notes_c:| just +% before the construction of the blocks (if the creation of medium nodes is +% required, medium nodes are also created for the blocks dans that construction +% uses the standard medium nodes). +% \begin{macrocode} +\cs_new_protected:Npn \@@_create_extra_nodes: + { + \bool_if:nTF \l_@@_medium_nodes_bool + { + \bool_if:NTF \l_@@_large_nodes_bool + \@@_create_medium_and_large_nodes: + \@@_create_medium_nodes: + } + { \bool_if:NT \l_@@_large_nodes_bool \@@_create_large_nodes: } + } +% \end{macrocode} +% +% % \bigskip % We have three macros of creation of nodes: |\@@_create_medium_nodes:|, % |\@@_create_large_nodes:| and |\@@_create_medium_and_large_nodes:|. @@ -7802,7 +12731,7 @@ version 2005/12/01 or later. \dim_compare:nNnT { \dim_use:c { l_@@_row _ \@@_i: _ min _ dim } } = \c_max_dim { - \@@_qpoint: { row - \@@_i: - base } + \@@_qpoint:n { row - \@@_i: - base } \dim_set:cn { l_@@_row _ \@@_i: _ max _ dim } \pgf@y \dim_set:cn { l_@@_row _ \@@_i: _ min _ dim } \pgf@y } @@ -7812,7 +12741,7 @@ version 2005/12/01 or later. \dim_compare:nNnT { \dim_use:c { l_@@_column _ \@@_j: _ min _ dim } } = \c_max_dim { - \@@_qpoint: { col - \@@_j: } + \@@_qpoint:n { col - \@@_j: } \dim_set:cn { l_@@_column _ \@@_j: _ max _ dim } \pgf@y \dim_set:cn { l_@@_column _ \@@_j: _ min _ dim } \pgf@y } @@ -7845,11 +12774,11 @@ version 2005/12/01 or later. % % \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 |\@@_create_medium_and_large_nodes:|). However, the +% the ``large nodes'' and not the medium ones\footnote{If we want to create +% both, we 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''. Hence, -% 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: @@ -7928,9 +12857,9 @@ version 2005/12/01 or later. \dim_set_eq:cc { l_@@_column _ \@@_succ:n \@@_j: _ min _ dim } { l_@@_column _ \@@_j: _ max _ dim } } -% \end{macrocode} +% \end{macrocode} % Here, we have to use |\dim_sub:cn| because of the number 1 in the name. -% \begin{macrocode} +% \begin{macrocode} \dim_sub:cn { l_@@_column _ 1 _ min _ dim } \l_@@_left_margin_dim @@ -7943,7 +12872,7 @@ version 2005/12/01 or later. % % % \bigskip -% The control sequence |\@@_create_nodes:| is used twice: for the construction +% The command |\@@_create_nodes:| is used twice: for the construction % of the ``medium nodes'' and for the construction of the ``large nodes''. The % nodes are constructed with the value of all the dimensions % \texttt{l_@@_row_\textsl{i}_min_dim}, \texttt{l_@@_row_\textsl{i}_max_dim}, @@ -7995,8 +12924,8 @@ version 2005/12/01 or later. % \begin{macrocode} \cs_new_protected:Npn \@@_extract_coords_values: #1 - #2 \q_stop { - \cs_set:Npn \@@_i: { #1 } - \cs_set:Npn \@@_j: { #2 } + \cs_set_nopar:Npn \@@_i: { #1 } + \cs_set_nopar:Npn \@@_j: { #2 } } % \end{macrocode} % @@ -8024,26 +12953,57 @@ version 2005/12/01 or later. % \end{macrocode} % % \bigskip -% \subsection*{Block matrices} +% \subsection*{The blocks} % -% The code in this section if for the construction of \emph{block matrices}. It -% has no direct link with the environment |{NiceMatrixBlock}|. +% The code deals with the command |\Block|. This command has no direct link with +% the environment |{NiceMatrixBlock}|. +% +% \bigskip +% The options of the command |\Block| will be analyzed first in the cell of the +% array (and once again when the block will be put in the array). +% Here is the set of keys for the first pass. +% \begin{macrocode} +\keys_define:nn { NiceMatrix / Block / FirstPass } + { + l .code:n = \tl_set:Nn \l_@@_pos_of_block_tl l , + l .value_forbidden:n = true , + r .code:n = \tl_set:Nn \l_@@_pos_of_block_tl r , + r .value_forbidden:n = true , + c .code:n = \tl_set:Nn \l_@@_pos_of_block_tl c , + c .value_forbidden:n = true , +% \end{macrocode} +% The two following lines will be uncommented when we will give to the key +% |color| its new definition. +% \begin{macrocode} + % color .tl_set:N = \l_@@_color_tl , + % color .value_required:n = true , + } +% \end{macrocode} % % -% 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 optional argument between |<| and |>| (for TeX instructions -% put before the math mode of the label) +% The following command |\@@_Block:| will be linked to |\Block| in the +% environments of \pkg{nicematrix}. We define it with +% |\NewExpandableDocumentCommand| because it has an optional argument between +% |<| and |>| (for TeX instructions put before the math mode of the label and +% before the beginning of the small array of the block). It's mandatory to use +% an expandable command. % % \begin{macrocode} -\NewDocumentCommand \@@_Block: { O { } m D < > { } m } - { \@@_Block_i #2 \q_stop { #1 } { #3 } { #4 } } +\NewExpandableDocumentCommand \@@_Block: { O { } m D < > { } m } + { +% \end{macrocode} +% If the first mandatory argument of the command (which is the size of the block +% with the syntax $i$|-|$j$) has not be provided by the user, you use |1-1| +% (that is to say a block of only one cell). +% \begin{macrocode} + \tl_if_blank:nTF { #2 } { \@@_Block_i 1-1 \q_stop } { \@@_Block_i #2 \q_stop } + { #1 } { #3 } { #4 } + } % \end{macrocode} % % \medskip -% 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. +% With the following construction, we extract the values of $i$ and $j$ in the +% first mandatory argument of the command. % \begin{macrocode} \cs_new:Npn \@@_Block_i #1-#2 \q_stop { \@@_Block_ii:nnnnn { #1 } { #2 } } % \end{macrocode} @@ -8051,201 +13011,755 @@ version 2005/12/01 or later. % \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| is the list of -% key-values, |#4| are the tokens to put before the math mode and |#5| is the -% label of the block. +% key-values, |#4| are the tokens to put before the math mode and the beginning +% of the small array of the block and |#5| is the label of the block. % \begin{macrocode} \cs_new_protected:Npn \@@_Block_ii:nnnnn #1 #2 #3 #4 #5 { % \end{macrocode} -% We write an instruction in the |code-after|. We write the instruction in the -% beginning of the |code-after| (the |left| in |\tl_gput_left:Nx|) because we -% want the Tikz nodes corresponding of the block created \emph{before} potential -% instructions written by the user in the |code-after| (these instructions may -% use the Tikz node of the created block). +% +% \medskip +% We recall that |#1| and |#2| have been extracted from the first mandatory +% argument of |\Block| (which is of the syntax $i$|-|$j$). However, the user is +% allowed to omit $i$ or $j$ (or both). We detect that situation by replacing a +% missing value by 100 (it's a convention: when the block will actually be drawn +% these values will be detected and interpreted as \emph{maximal possible value}). % \begin{macrocode} - \tl_gput_left:Nx \g_@@_internal_code_after_tl + \bool_lazy_or:nnTF + { \tl_if_blank_p:n { #1 } } + { \str_if_eq_p:nn { #1 } { * } } + { \int_set:Nn \l_tmpa_int { 100 } } + { \int_set:Nn \l_tmpa_int { #1 } } + \bool_lazy_or:nnTF + { \tl_if_blank_p:n { #2 } } + { \str_if_eq_p:nn { #2 } { * } } + { \int_set:Nn \l_tmpb_int { 100 } } + { \int_set:Nn \l_tmpb_int { #2 } } +% \end{macrocode} +% +% \begin{macrocode} + \int_compare:nNnTF \l_tmpb_int = 1 { - \@@_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 } } - { #3 } - \exp_not:n { { #4 $ #5 $ } } - } + \tl_if_empty:NTF \l_@@_cell_type_tl + { \tl_set:Nn \l_@@_pos_of_block_tl c } + { \tl_set_eq:NN \l_@@_pos_of_block_tl \l_@@_cell_type_tl } + } + { \tl_set:Nn \l_@@_pos_of_block_tl c } +% \end{macrocode} +% +% \medskip +% \begin{macrocode} + \keys_set_known:nn { NiceMatrix / Block / FirstPass } { #3 } % \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} + \tl_set:Nx \l_tmpa_tl + { + { \int_use:N \c@iRow } + { \int_use:N \c@jCol } + { \int_eval:n { \c@iRow + \l_tmpa_int - 1 } } + { \int_eval:n { \c@jCol + \l_tmpb_int - 1 } } + } +% \end{macrocode} +% Now, |\l_tmpa_tl| contains an ``object'' corresponding to the position of the +% block with four components, each of them surrounded by curly brackets: +% +% |{|\textsl{imin}|}{|\textsl{jmin}|}{|\textsl{imax}|}{|\textsl{jmax}|}|. +% +% +% \medskip +% If the block is mono-column or mono-row, we have a special treatment. That's +% why we have two macros: |\@@_Block_iv:nnnnn| and |\@@_Block_v:nnnnn| (the five +% arguments of those macros are provided by curryfication). % \begin{macrocode} - \cs_set_eq:NN \Block \@@_Block_error:nn + \bool_lazy_or:nnTF + { \int_compare_p:nNn { \l_tmpa_int } = 1 } + { \int_compare_p:nNn { \l_tmpb_int } = 1 } + { \exp_args:Nxx \@@_Block_iv:nnnnn } + { \exp_args:Nxx \@@_Block_v:nnnnn } + { \l_tmpa_int } { \l_tmpb_int } { #3 } { #4 } { #5 } } % \end{macrocode} % +% +% \bigskip +% The following macro is for the case of a |\Block| which is mono-row or +% mono-column (or both). In that case, the content of the block is composed +% right now in a box (because we have to take into account the dimensions of +% that box for the width of the current column or the height and the depth of the +% current row). However, that box will be put in the array \emph{after the +% construction of the array} (by using \textsc{pgf}). % \begin{macrocode} -\cs_new:Npn \@@_Block_error:nn #1 #2 - { - \@@_error:n { Second~Block } - \cs_set_eq:NN \Block \use:nn +\cs_new_protected:Npn \@@_Block_iv:nnnnn #1 #2 #3 #4 #5 + { + \int_gincr:N \g_@@_block_box_int + \cs_set_protected_nopar:Npn \diagbox ##1 ##2 + { + \tl_gput_right:Nx \g_@@_internal_code_after_tl + { + \@@_actually_diagbox: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 { ##1 } } { \exp_not:n { ##2 } } + } + } + \box_gclear_new:c + { g_@@_ block _ box _ \int_use:N \g_@@_block_box_int _ box } + \hbox_gset:cn + { g_@@_ block _ box _ \int_use:N \g_@@_block_box_int _ box } + { +% \end{macrocode} +% For a mono-column block, if the user has specified a color for the column in +% the preamble of the array, we want to fix that color in the box we construct. +% We do that with |\set@color| and not |\color_ensure_current:| because that +% command seems to be bugged: it doesn't work in XeLaTeX when \pkg{fontspec} is +% loaded. +% \begin{macrocode} + \tl_if_empty:NTF \l_@@_color_tl + { \int_compare:nNnT { #2 } = 1 \set@color } + { \color { \l_@@_color_tl } } + \group_begin: + \cs_set:Npn \arraystretch { 1 } + \dim_set_eq:NN \extrarowheight \c_zero_dim + #4 +% \end{macrocode} +% If the box is rotated (the key |\rotate| may be in the previous |#4|), the +% tabular used for the content of the cell will be constructed with a format +% |c|. In the other cases, the tabular will be constructed with a format equal +% to the key of position of the box. In other words: the alignement internal to +% the tabular is the same as the external alignment of the tabular (that is to +% say the position of the block in its zone of merged cells). +% \begin{macrocode} + \bool_if:NT \g_@@_rotate_bool { \tl_set:Nn \l_@@_pos_of_block_tl c } + \bool_if:NTF \l_@@_NiceTabular_bool + { + \exp_args:Nnx \begin { tabular } + { @ { } \l_@@_pos_of_block_tl @ { } } + #5 + \end { tabular } + } + { + \c_math_toggle_token + \exp_args:Nnx \begin { array } + { @ { } \l_@@_pos_of_block_tl @ { } } + #5 + \end { array } + \c_math_toggle_token + } + \group_end: + } + \bool_if:NT \g_@@_rotate_bool + { + \box_grotate:cn + { g_@@_ block _ box _ \int_use:N \g_@@_block_box_int _ box } + { 90 } + \bool_gset_false:N \g_@@_rotate_bool + } +% \end{macrocode} +% If we are in a mono-column block, we take into account the width of that block +% for the width of the column. +% \begin{macrocode} + \int_compare:nNnT { #2 } = 1 + { + \dim_gset:Nn \g_@@_blocks_wd_dim + { + \dim_max:nn + \g_@@_blocks_wd_dim + { + \box_wd:c + { g_@@_ block _ box _ \int_use:N \g_@@_block_box_int _ box } + } + } + } +% \end{macrocode} +% If we are in a mono-row block, we take into account the height and the +% depth of that block for the height and the depth of the row. +% \begin{macrocode} + \int_compare:nNnT { #1 } = 1 + { + \dim_gset:Nn \g_@@_blocks_ht_dim + { + \dim_max:nn + \g_@@_blocks_ht_dim + { + \box_ht:c + { g_@@_ block _ box _ \int_use:N \g_@@_block_box_int _ box } + } + } + \dim_gset:Nn \g_@@_blocks_dp_dim + { + \dim_max:nn + \g_@@_blocks_dp_dim + { + \box_dp:c + { g_@@_ block _ box _ \int_use:N \g_@@_block_box_int _ box } + } + } + } + \seq_gput_right:Nx \g_@@_blocks_seq + { + \l_tmpa_tl +% \end{macrocode} +% In the list of options |#3|, maybe there is a key for the horizontal alignment +% (|l|, |r| or |c|). In that case, that key has been read and stored in +% |\l_@@_pos_of_block_tl|. However, maybe there were no key of the horizontal +% alignement and that's why we put a key corresponding to the value of +% |\l_@@_pos_of_block_tl|, which is fixed by the type of current column. +% \begin{macrocode} + { \exp_not:n { #3 } , \l_@@_pos_of_block_tl } + { + \box_use_drop:c + { g_@@_ block _ box _ \int_use:N \g_@@_block_box_int _ box } + } + } } % \end{macrocode} % -% \medskip +% \bigskip +% The following macro is for the standard case, where the block is not mono-row +% and not mono-column. In that case, the content of the block is \emph{not} +% composed right now in a box. The composition in a box will be done further, +% just after the construction of the array. +% \begin{macrocode} +\cs_new_protected:Npn \@@_Block_v:nnnnn #1 #2 #3 #4 #5 + { + \seq_gput_right:Nx \g_@@_blocks_seq + { + \l_tmpa_tl + { \exp_not:n { #3 } } + \exp_not:n + { + { + \bool_if:NTF \l_@@_NiceTabular_bool + { + \group_begin: + \cs_set:Npn \arraystretch { 1 } + \dim_set_eq:NN \extrarowheight \c_zero_dim + #4 +% \end{macrocode} +% If the box is rotated (the key |\rotate| may be in the previous |#4|), the +% tabular used for the content of the cell will be constructed with a format +% |c|. In the other cases, the tabular will be constructed with a format equal +% to the key of position of the box. In other words: the alignement internal to +% the tabular is the same as the external alignment of the tabular (that is to +% say the position of the block in its zone of merged cells). +% \begin{macrocode} + \bool_if:NT \g_@@_rotate_bool + { \tl_set:Nn \l_@@_pos_of_block_tl c } + \exp_args:Nnx \begin { tabular } + { @ { } \l_@@_pos_of_block_tl @ { } } + #5 + \end { tabular } + \group_end: + } + { + \group_begin: + \cs_set:Npn \arraystretch { 1 } + \dim_set_eq:NN \extrarowheight \c_zero_dim + #4 + \bool_if:NT \g_@@_rotate_bool + { \tl_set:Nn \l_@@_pos_of_block_tl c } + \c_math_toggle_token + \exp_args:Nnx \begin { array } + { @ { } \l_@@_pos_of_block_tl @ { } } #5 \end { array } + \c_math_toggle_token + \group_end: + } + } + } + } + } +% \end{macrocode} +% +% \bigskip +% We recall that the options of the command |\Block| are analyzed twice: first +% in the cell of the array and once again when the block will be put in the +% array \emph{after the construction of the array} (by using \textsc{pgf}). +% +% \medskip % \begin{macrocode} -\keys_define:nn { NiceMatrix / Block } +\keys_define:nn { NiceMatrix / Block / SecondPass } { - 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 , + fill .tl_set:N = \l_@@_fill_tl , + fill .value_required:n = true , + draw .tl_set:N = \l_@@_draw_tl , + draw .default:n = default , +% \end{macrocode} +% The following definition for the key |color| will be deleted when we will give +% to the key |color| of the command |\Block| its new definition. It will be +% replaced by the line which is commented. +% \begin{macrocode} + color .code:n = + \@@_error:n { Key~color~for~Block } + \tl_set:Nn \l_@@_fill_tl { #1 } , + % color .code:n = \color { #1 } \tl_set:Nn \l_@@_draw_tl { #1 } , + color .value_required:n = true , + line-width .dim_set:N = \l_@@_line_width_dim , + line-width .value_required:n = true , + l .code:n = \tl_set:Nn \l_@@_pos_of_block_tl l , + l .value_forbidden:n = true , + r .code:n = \tl_set:Nn \l_@@_pos_of_block_tl r , + r .value_forbidden:n = true , + c .code:n = \tl_set:Nn \l_@@_pos_of_block_tl c , + c .value_forbidden:n = true , + unknown .code:n = \@@_error:n { Unknown~key~for~Block } } % \end{macrocode} % +% \bigskip +% The command |\@@_draw_blocks:| will draw all the blocks. This command is used +% after the construction of the array. We have to revert to a clean version of +% |\ialign| because there may be tabulars in the |\Block| instructions that will +% be composed now. +% \begin{macrocode} +\cs_new_protected:Npn \@@_draw_blocks: + { + \cs_set_eq:NN \ialign \@@_old_ialign: + \seq_map_inline:Nn \g_@@_blocks_seq { \@@_Block_iv:nnnnnn ##1 } + } +% \end{macrocode} % -% \medskip -% The following command |\@@_Block_iii:nnnnnn| will be used in the |code-after|. % \begin{macrocode} -\cs_new_protected:Npn \@@_Block_iii:nnnnnn #1 #2 #3 #4 #5 #6 +\cs_new_protected:Npn \@@_Block_iv:nnnnnn #1 #2 #3 #4 #5 #6 + { +% \end{macrocode} +% The integer |\l_@@_last_row_int| will be the last row of the block and +% |\l_@@_last_col_int| its last column. +% \begin{macrocode} + \int_zero_new:N \l_@@_last_row_int + \int_zero_new:N \l_@@_last_col_int +% \end{macrocode} +% +% We remind that the first mandatory argument of the command |\Block| is the +% size of the block with the special format $i$|-|$j$. However, the user is +% allowed to omit $i$ or $j$ (or both). This will be interpreted as: the last +% row (resp. column) of the block will be the last row (resp. column) of the +% block (without the potential exterior row---resp. column---of the array). By +% convention, this is stored in |\g_@@_blocks_seq| as a number of rows (resp. +% columns) for the block equal to 100. That's what we detect now. +% \begin{macrocode} + \int_compare:nNnTF { #3 } > { 99 } + { \int_set_eq:NN \l_@@_last_row_int \c@iRow } + { \int_set:Nn \l_@@_last_row_int { #3 } } + \int_compare:nNnTF { #4 } > { 99 } + { \int_set_eq:NN \l_@@_last_col_int \c@jCol } + { \int_set:Nn \l_@@_last_col_int { #4 } } + \bool_lazy_or:nnTF + { \int_compare_p:nNn \l_@@_last_row_int > \g_@@_row_total_int } + { \int_compare_p:nNn \l_@@_last_col_int > \g_@@_col_total_int } + { + \int_compare:nTF + { \l_@@_last_col_int <= \g_@@_static_num_of_col_int } + { + \msg_error:nnnn { nicematrix } { Block~too~large~2 } { #1 } { #2 } + \@@_msg_redirect_name:nn { Block~too~large~2 } { none } + \group_begin: + \globaldefs = 1 + \@@_msg_redirect_name:nn { columns~not~used } { none } + \group_end: + } + { \msg_error:nnnn { nicematrix } { Block~too~large~1 } { #1 } { #2 } } + } + { \@@_Block_v:nnnnnn { #1 } { #2 } { #3 } { #4 } { #5 } { #6 } } + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_Block_v:nnnnnn #1 #2 #3 #4 #5 #6 { % \end{macrocode} +% The sequence of the positions of the blocks will be used when drawing the rules +% (in fact, there is also the |\multicolumn| and the |\diagbox| in that sequence). +% \begin{macrocode} + \seq_gput_left:Nn \g_@@_pos_of_blocks_seq { { #1 } { #2 } { #3 } { #4 } } +% \end{macrocode} +% % The group is for the keys. % \begin{macrocode} \group_begin: - \keys_set:nn { NiceMatrix / Block } { #5 } + \keys_set:nn { NiceMatrix / Block / SecondPass } { #5 } % \end{macrocode} % +% % \begin{macrocode} - \bool_if:nTF - { - \int_compare_p:nNn { #3 } > \c@iRow - || \int_compare_p:nNn { #4 } > \c@jCol - } - { \msg_error:nnnn { nicematrix } { Block~too~large } { #1 } { #2 } } + \bool_lazy_or:nnT + { ! \tl_if_empty_p:N \l_@@_draw_tl } + { \dim_compare_p:nNn \l_@@_line_width_dim > \c_zero_dim } { + \tl_gput_right:Nx \g_nicematrix_code_after_tl + { + \@@_stroke_block:nnn + { \exp_not:n { #5 } } + { #1 - #2 } + { \int_use:N \l_@@_last_row_int - \int_use:N \l_@@_last_col_int } + } + \seq_gput_right:Nn \g_@@_pos_of_stroken_blocks_seq + { { #1 } { #2 } { #3 } { #4 } } + } % \end{macrocode} -% 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} - \hbox_set:Nn \l_@@_cell_box { #6 } + \tl_if_empty:NF \l_@@_fill_tl + { + \tl_gput_right:Nx \g_nicematrix_code_before_tl + { + \exp_not:N \rectanglecolor + { \exp_not:V \l_@@_fill_tl } + { #1 - #2 } + { \int_use:N \l_@@_last_row_int - \int_use:N \l_@@_last_col_int } + } + } % \end{macrocode} -% +% % \medskip -% The construction of the node corresponding to the merged cells. % \begin{macrocode} - \pgfpicture - \pgfrememberpicturepositiononpagetrue - \pgf@relevantforpicturesizefalse - \@@_qpoint: { row - #1 } - \dim_set_eq:NN \l_tmpa_dim \pgf@y - \@@_qpoint: { col - #2 } - \dim_set_eq:NN \l_tmpb_dim \pgf@x - \@@_qpoint: { row - \@@_succ:n { #3 } } - \dim_set_eq:NN \l_tmpc_dim \pgf@y - \@@_qpoint: { col - \@@_succ:n { #4 } } - \dim_set_eq:NN \l_tmpd_dim \pgf@x + \cs_set_protected_nopar:Npn \diagbox ##1 ##2 + { + \tl_gput_right:Nx \g_@@_internal_code_after_tl + { + \@@_actually_diagbox:nnnnnn + { #1 } + { #2 } + { \int_use:N \l_@@_last_row_int } + { \int_use:N \l_@@_last_col_int } + { \exp_not:n { ##1 } } { \exp_not:n { ##2 } } + } + } % \end{macrocode} % % \medskip -% The following code doesn't work for the first vertical rule. You should allow -% the option |white| if and only if the option |vlines| and |hlines| has been used. % \begin{macrocode} - \bool_if:NT \l_@@_white_bool - { - \begin { pgfscope } - \pgfsetfillcolor { white } + \hbox_set:Nn \l_@@_cell_box { #6 } + \bool_if:NT \g_@@_rotate_bool \@@_rotate_cell_box: % \end{macrocode} -% Usually, the vertical rules are \emph{before} the |col|-nodes. But there is an -% exception: if there is no ``first col'', the first vertical rule is after the -% col node.\footnote{That's true for the vertical rules drawn by ``"|"'' due to -% the conception of |{array}| (of \pkg{array}) and we have managed to have the -% same behaviour with |vlines|.} +% +% \bigskip +% Let's consider the following |{NiceTabular}|. Because of the instruction +% |!{\hspace{1cm}}| in the preamble which increases the space between the +% columns (by adding, in fact, that space to the previous column, that is to say +% the second column of the tabular), we will create \emph{two} nodes relative to +% the block: the node |1-1-block| and the node |1-1-block-short|. The latter +% will be used by \pkg{nicematrix} to put the label of the node. The first one +% won't be used explicitely. +% \begin{Verbatim} +% \begin{NiceTabular}{cc!{\hspace{1cm}}c} +% \Block{2-2}{our block} & & one \\ +% & & two \\ +% three & four & five \\ +% six & seven & eight \\ +% \end{NiceTabular} +% \end{Verbatim} % -% Since we don't want the white rectangle to erase a part of this -% first rule, we have to do an adjustment in this case. -% \emph{after} the ``col node''. +% \tikzset{highlight/.style={rectangle, +% fill=red!15, +% blend mode = multiply, +% rounded corners = 0pt, +% inner sep=0pt, +% fit = #1}} +% +% \begin{tabular}{c!{\hspace{1cm}}c} +% We highlight the node |1-1-block| +% & We highlight the node |1-1-block-short| \\[2mm] +% \begin{NiceTabular}{cc!{\hspace{1cm}}c} +% \Block{2-2}{our block} & & one \\ +% & & two \\ +% three & four & five \\ +% six & seven & eight \\ +% \CodeAfter +% \tikz \node [highlight = (1-1-block)] { } ; +% \end{NiceTabular} +% & +% \begin{NiceTabular}{cc!{\hspace{1cm}}c} +% \Block{2-2}{our block} & & one \\ +% & & two \\ +% three & four & five \\ +% six & seven & eight \\ +% \CodeAfter +% \tikz \node [highlight = (1-1-block-short)] { } ; +% \end{NiceTabular} +% \end{tabular} +% +% +% \bigskip +% The construction of the node corresponding to the merged cells. % \begin{macrocode} - \int_compare:nNnT { #2 } = 1 - { - \int_compare:nNnT \l_@@_first_col_int = 1 - { \dim_add:Nn \l_tmpb_dim \arrayrulewidth } - } - \pgfpathrectanglecorners - { \pgfpoint \l_tmpb_dim { \l_tmpa_dim - \arrayrulewidth } } - { \pgfpoint { \l_tmpd_dim - \arrayrulewidth } \l_tmpc_dim } - \pgfusepathqfill - \end { pgfscope } - } + \pgfpicture + \pgfrememberpicturepositiononpagetrue + \pgf@relevantforpicturesizefalse + \@@_qpoint:n { row - #1 } + \dim_set_eq:NN \l_tmpa_dim \pgf@y + \@@_qpoint:n { col - #2 } + \dim_set_eq:NN \l_tmpb_dim \pgf@x + \@@_qpoint:n { row - \@@_succ:n { \l_@@_last_row_int } } + \dim_set_eq:NN \l_tmpc_dim \pgf@y + \@@_qpoint:n { col - \@@_succ:n { \l_@@_last_col_int } } + \dim_set_eq:NN \l_tmpd_dim \pgf@x % \end{macrocode} % % We construct the node for the block with the name |(#1-#2-block)|. -% The function |\@@_pgf_rect_node:nnnnn| takes as arguments the name of the node +% +% The function |\@@_pgf_rect_node:nnnnn| takes in as arguments the name of the node % and the four coordinates of two opposite corner points of the rectangle. % \begin{macrocode} - \begin { pgfscope } - \exp_args:Nx \pgfset { \l_@@_tikz_tl } - \@@_pgf_rect_node:nnnnn - { \@@_env: - #1 - #2 - block } - \l_tmpb_dim \l_tmpa_dim \l_tmpd_dim \l_tmpc_dim - \end { pgfscope } + \begin { pgfscope } + \@@_pgf_rect_node:nnnnn + { \@@_env: - #1 - #2 - block } + \l_tmpb_dim \l_tmpa_dim \l_tmpd_dim \l_tmpc_dim + \end { pgfscope } +% \end{macrocode} +% +% \medskip +% We construct the |short| node. +% \begin{macrocode} + \dim_set_eq:NN \l_tmpb_dim \c_max_dim + \int_step_inline:nnn \l_@@_first_row_int \g_@@_row_total_int + { +% \end{macrocode} +% We recall that, when a cell is empty, no (normal) node is created in that +% cell. That's why we test the existence of the node before using it. +% \begin{macrocode} + \cs_if_exist:cT + { pgf @ sh @ ns @ \@@_env: - ##1 - #2 } + { + \seq_if_in:NnF \g_@@_multicolumn_cells_seq { ##1 - #2 } + { + \pgfpointanchor { \@@_env: - ##1 - #2 } { west } + \dim_set:Nn \l_tmpb_dim { \dim_min:nn \l_tmpb_dim \pgf@x } + } + } + } +% \end{macrocode} +% If all the cells of the column were empty, |\l_tmpb_dim| has still the same +% value |\c_max_dim|. In that case, you use for |\l_tmpb_dim| the value of the +% position of the vertical rule. +% \begin{macrocode} + \dim_compare:nNnT \l_tmpb_dim = \c_max_dim + { + \@@_qpoint:n { col - #2 } + \dim_set_eq:NN \l_tmpb_dim \pgf@x + } + \dim_set:Nn \l_tmpd_dim { - \c_max_dim } + \int_step_inline:nnn \l_@@_first_row_int \g_@@_row_total_int + { + \cs_if_exist:cT + { pgf @ sh @ ns @ \@@_env: - ##1 - \int_use:N \l_@@_last_col_int } + { + \seq_if_in:NnF \g_@@_multicolumn_cells_seq { ##1 - #2 } + { + \pgfpointanchor + { \@@_env: - ##1 - \int_use:N \l_@@_last_col_int } + { east } + \dim_set:Nn \l_tmpd_dim { \dim_max:nn \l_tmpd_dim \pgf@x } + } + } + } + \dim_compare:nNnT \l_tmpd_dim = { - \c_max_dim } + { + \@@_qpoint:n { col - \@@_succ:n { \l_@@_last_col_int } } + \dim_set_eq:NN \l_tmpd_dim \pgf@x + } + \@@_pgf_rect_node:nnnnn + { \@@_env: - #1 - #2 - block - short } + \l_tmpb_dim \l_tmpa_dim \l_tmpd_dim \l_tmpc_dim % \end{macrocode} -% % % \medskip % If the creation of the ``medium nodes'' is required, we create a ``medium -% node'' for the block. The function |\@@_pgf_rect_node:nnnnn| takes as +% node'' for the block. The function |\@@_pgf_rect_node:nnnnn| takes in as % arguments the name of the node and two \textsc{pgf} points. % \begin{macrocode} - \bool_if:NT \l_@@_medium_nodes_bool - { - \@@_pgf_rect_node:nnn - { \@@_env: - #1 - #2 - block - medium } - { \pgfpointanchor { \@@_env: - #1 - #2 - medium } { north~west } } - { \pgfpointanchor { \@@_env: - #3 - #4 - medium } { south~east } } - } + \bool_if:NT \l_@@_medium_nodes_bool + { + \@@_pgf_rect_node:nnn + { \@@_env: - #1 - #2 - block - medium } + { \pgfpointanchor { \@@_env: - #1 - #2 - medium } { north~west } } + { + \pgfpointanchor + { \@@_env: + - \int_use:N \l_@@_last_row_int + - \int_use:N \l_@@_last_col_int - medium + } + { south~east } + } + } % \end{macrocode} % \medskip -% Now, we will put the label of the block. +% Now, we will put the label of the block beginning with the case of a |\Block| +% of one row. % \begin{macrocode} - \int_compare:nNnTF { #1 } = { #3 } - { + \int_compare:nNnTF { #1 } = { #3 } + { +% \end{macrocode} +% We take into account the case of a block of one row in the ``first row'' or +% the ``last row''. +% \begin{macrocode} + \int_compare:nNnTF { #1 } = 0 + { \l_@@_code_for_first_row_tl } + { + \int_compare:nNnT { #1 } = \l_@@_last_row_int + \l_@@_code_for_last_row_tl + } % \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 % |\pgfcoordinate| on the baseline of the row, in the first column of the array. % Now, we retrieve the $y$-value of that node and we store it in |\l_tmpa_dim|. % \begin{macrocode} - \pgfextracty \l_tmpa_dim { \@@_qpoint: { row - #1 - base } } + \pgfextracty \l_tmpa_dim { \@@_qpoint:n { row - #1 - base } } % \end{macrocode} % We retrieve (in |\pgf@x|) the $x$-value of the center of the block. % \begin{macrocode} - \@@_qpoint: { #1 - #2 - block } + \pgfpointanchor + { \@@_env: - #1 - #2 - block - short } + { + \str_case:Vn \l_@@_pos_of_block_tl + { + c { center } + l { west } + r { east } + } + } % \end{macrocode} % We put the label of the block which has been composed in |\l_@@_cell_box|. % \begin{macrocode} - \pgftransformshift { \pgfpoint \pgf@x \l_tmpa_dim } - \pgfnode { rectangle } { base } - { \box_use_drop:N \l_@@_cell_box } { } { } - } + \pgftransformshift { \pgfpoint \pgf@x \l_tmpa_dim } + \pgfset { inner~sep = \c_zero_dim } + \pgfnode + { rectangle } + { + \str_case:Vn \l_@@_pos_of_block_tl + { + c { base } + l { base~west } + r { base~east } + } + } + { \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|). +% If the number of rows is different of $1$, we will put the label of the block +% by using the short node (the label of the block has been composed in +% |\l_@@_cell_box|). % \begin{macrocode} - { - \pgftransformshift { \@@_qpoint: { #1 - #2 - block } } - \pgfnode { rectangle } { center } - { \box_use_drop:N \l_@@_cell_box } { } { } - } - \endpgfpicture + { +% \end{macrocode} +% If we are in the first column, we must put the block as if it was with the key~|r|. +% \begin{macrocode} + \int_compare:nNnT { #2 } = 0 + { \tl_set:Nn \l_@@_pos_of_block_tl r } + \bool_if:nT \g_@@_last_col_found_bool + { + \int_compare:nNnT { #2 } = \g_@@_col_total_int + { \tl_set:Nn \l_@@_pos_of_block_tl l } + } + \pgftransformshift + { + \pgfpointanchor + { \@@_env: - #1 - #2 - block - short } + { + \str_case:Vn \l_@@_pos_of_block_tl + { + c { center } + l { west } + r { east } + } + } + } + \pgfset { inner~sep = \c_zero_dim } + \pgfnode + { rectangle } + { + \str_case:Vn \l_@@_pos_of_block_tl + { + c { center } + l { west } + r { east } + } + } + { \box_use_drop:N \l_@@_cell_box } { } { } + } + \endpgfpicture + \group_end: + } +% \end{macrocode} +% +% +% % \bigskip +% The first argument of |\@@_stroke_block:nnn| is a list of options for the +% rectangle that you will stoke. The second argument is the upper-left cell of +% the block (with, as usual, the syntex $i$|-|$j$) and the third is the last +% cell of the block (with the same syntax). +% \begin{macrocode} +\cs_new_protected:Npn \@@_stroke_block:nnn #1 #2 #3 + { + \group_begin: + \tl_clear:N \l_@@_draw_tl + \dim_set_eq:NN \l_@@_line_width_dim \arrayrulewidth + \keys_set_known:nn { NiceMatrix / BlockStroke } { #1 } + \pgfpicture + \pgfrememberpicturepositiononpagetrue + \pgf@relevantforpicturesizefalse + \tl_if_empty:NF \l_@@_draw_tl + { +% \end{macrocode} +% If the user has used the key |color| of the command |\Block| without value, +% the color fixed by |\arrayrulecolor| is used. +% \begin{macrocode} + \str_if_eq:VnTF \l_@@_draw_tl { default } + { \CT@arc@ } + { \pgfsetstrokecolor { \l_@@_draw_tl } } } + \@@_cut_on_hyphen:w #2 \q_stop + \bool_lazy_and:nnT + { \int_compare_p:n { \l_tmpa_tl <= \c@iRow } } + { \int_compare_p:n { \l_tmpb_tl <= \c@jCol } } + { + \@@_qpoint:n { row - \l_tmpa_tl } + \dim_set:Nn \l_tmpb_dim { \pgf@y } + \@@_qpoint:n { col - \l_tmpb_tl } + \dim_set:Nn \l_tmpc_dim { \pgf@x } + \@@_cut_on_hyphen:w #3 \q_stop + \int_compare:nNnT \l_tmpa_tl > \c@iRow + { \tl_set:Nx \l_tmpa_tl { \int_use:N \c@iRow } } + \int_compare:nNnT \l_tmpb_tl > \c@jCol + { \tl_set:Nx \l_tmpb_tl { \int_use:N \c@jCol } } + \@@_qpoint:n { row - \@@_succ:n \l_tmpa_tl } + \dim_set:Nn \l_tmpa_dim { \pgf@y } + \@@_qpoint:n { col - \@@_succ:n \l_tmpb_tl } + \dim_set:Nn \l_tmpd_dim { \pgf@x } + \pgfpathrectanglecorners + { \pgfpoint \l_tmpc_dim \l_tmpb_dim } + { \pgfpoint \l_tmpd_dim \l_tmpa_dim } + \pgfsetlinewidth { 1.1 \l_@@_line_width_dim } + \pgfusepathqstroke + } + \endpgfpicture \group_end: } % \end{macrocode} % +% Here is the set of keys for the command |\@@_stroke_block:nnn|. +% \begin{macrocode} +\keys_define:nn { NiceMatrix / BlockStroke } + { +% \end{macrocode} +% We will uncomment the following line when we will give to the key |color| of +% the command |\Block| its new definition. +% \begin{macrocode} + % color .tl_set:N = \l_@@_draw_tl , + draw .tl_set:N = \l_@@_draw_tl , + draw .default:n = default , + line-width .dim_set:N = \l_@@_line_width_dim , + } +% \end{macrocode} +% % \bigskip +% % \subsection*{How to draw the dotted lines transparently} % \begin{macrocode} \cs_set_protected:Npn \@@_renew_matrix: @@ -8289,7 +13803,7 @@ version 2005/12/01 or later. \int_zero_new:N \l_@@_nb_cols_int \@@_set_size:n #4 \q_stop \begin { NiceArrayWithDelims } { #1 } { #2 } - { * { \l_@@_nb_cols_int } { C } } [ #3 , #5 , #7 ] + { * { \l_@@_nb_cols_int } { c } } [ #3 , #5 , #7 ] \int_compare:nNnT \l_@@_first_row_int = 0 { \int_compare:nNnT \l_@@_first_col_int = 0 { & } @@ -8300,7 +13814,7 @@ version 2005/12/01 or later. { \int_compare:nNnT \l_@@_first_col_int = 0 { & } % \end{macrocode} -% You put |{ }| before |#6| to avoid a hasty expansion of an eventual +% You put |{ }| before |#6| to avoid a hasty expansion of a potential % |\arabic{iRow}| at the beginning of the row which would result in an incorrect % value of that |iRow| (since |iRow| is incremented in the first cell of the row % of the |\halign|). @@ -8336,10 +13850,565 @@ version 2005/12/01 or later. \@@_define_com:nnn V \| \| \@@_define_com:nnn B \{ \} % \end{macrocode} +% +% \bigskip +% We define also an command |\AutoNiceMatrix| similar to the environment |{NiceMatrix}|. +% \begin{macrocode} +\NewDocumentCommand \AutoNiceMatrix { O { } m O { } m ! O { } } + { + \group_begin: + \bool_set_true:N \l_@@_NiceArray_bool + \AutoNiceMatrixWithDelims . . { #2 } { #4 } [ #1 , #3 , #5 ] + \group_end: + } +% \end{macrocode} +% +% \bigskip +% \subsection*{The redefinition of the command \textbackslash dotfill } +% +% \begin{macrocode} +\cs_set_eq:NN \@@_old_dotfill \dotfill +\cs_new_protected:Npn \@@_dotfill: + { +% \end{macrocode} +% First, we insert |\@@_dotfill| (which is the saved version of |\dotfill|) in +% case of use of |\dotfill| ``internally'' in the cell (e.g. |\hbox to 1cm {\dotfill}|). +% \begin{macrocode} + \@@_old_dotfill + \bool_if:NT \l_@@_NiceTabular_bool + { \group_insert_after:N \@@_dotfill_ii: } + { \group_insert_after:N \@@_dotfill_i: } + } +\cs_new_protected:Npn \@@_dotfill_i: { \group_insert_after:N \@@_dotfill_ii: } +\cs_new_protected:Npn \@@_dotfill_ii: { \group_insert_after:N \@@_dotfill_iii: } +% \end{macrocode} +% Now, if the box if not empty (unfornately, we can't actually test whether the +% box is empty and that's why we only consider it's width), we insert +% |\@@_dotfill| (which is the saved version of |\dotfill|) in the cell of the +% array, and it will extend, since it is no longer in |\l_@@_cell_box|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_dotfill_iii: + { \dim_compare:nNnT { \box_wd:N \l_@@_cell_box } = \c_zero_dim \@@_old_dotfill } +% \end{macrocode} +% +% \bigskip +% \subsection*{The command \textbackslash diagbox} +% +% The command |\diagbox| will be linked to |\diagbox:nn| in the environments of +% \pkg{nicematrix}. +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_diagbox:nn #1 #2 + { + \tl_gput_right:Nx \g_@@_internal_code_after_tl + { + \@@_actually_diagbox:nnnnnn + { \int_use:N \c@iRow } + { \int_use:N \c@jCol } + { \int_use:N \c@iRow } + { \int_use:N \c@jCol } + { \exp_not:n { #1 } } + { \exp_not:n { #2 } } + } +% \end{macrocode} +% We put the cell with |\diagbox| in the sequence |\g_@@_pos_of_blocks_seq| +% because a cell with |\diagbox| must be considered as non empty by the key +% |except-corners|. +% \begin{macrocode} + \seq_gput_right:Nx \g_@@_pos_of_blocks_seq + { + { \int_use:N \c@iRow } + { \int_use:N \c@jCol } + { \int_use:N \c@iRow } + { \int_use:N \c@jCol } + } + } +% \end{macrocode} +% +% \medskip +% The command |\diagbox| is also redefined locally when we draw a block. +% +% \medskip +% The first four arguments of |\@@_actually_diagbox:nnnnnn| correspond to the +% rectangle (=block) to slash (we recall that it's possible to use |\diagbox| in +% a |\Block|). The two other are the elements to draw below and above the +% diagonal line. +% \begin{macrocode} +\cs_new_protected:Npn \@@_actually_diagbox:nnnnnn #1 #2 #3 #4 #5 #6 + { + \pgfpicture + \pgf@relevantforpicturesizefalse + \pgfrememberpicturepositiononpagetrue + \@@_qpoint:n { row - #1 } + \dim_set_eq:NN \l_tmpa_dim \pgf@y + \@@_qpoint:n { col - #2 } + \dim_set_eq:NN \l_tmpb_dim \pgf@x + \pgfpathmoveto { \pgfpoint \l_tmpb_dim \l_tmpa_dim } + \@@_qpoint:n { row - \@@_succ:n { #3 } } + \dim_set_eq:NN \l_tmpc_dim \pgf@y + \@@_qpoint:n { col - \@@_succ:n { #4 } } + \dim_set_eq:NN \l_tmpd_dim \pgf@x + \pgfpathlineto { \pgfpoint \l_tmpd_dim \l_tmpc_dim } + { +% \end{macrocode} +% The command |\CT@arc@| is a command of \pkg{colortbl} which sets the color of +% the rules in the array. The package \pkg{nicematrix} uses it even if \pkg{colortbl} is not +% loaded. +% \begin{macrocode} + \CT@arc@ + \pgfsetroundcap + \pgfusepathqstroke + } + \pgfset { inner~sep = 1 pt } + \pgfscope + \pgftransformshift { \pgfpoint \l_tmpb_dim \l_tmpc_dim } + \pgfnode { rectangle } { south~west } + { \@@_math_toggle_token: #5 \@@_math_toggle_token: } { } { } + \endpgfscope + \pgftransformshift { \pgfpoint \l_tmpd_dim \l_tmpa_dim } + \pgfnode { rectangle } { north~east } + { \@@_math_toggle_token: #6 \@@_math_toggle_token: } { } { } + \endpgfpicture + } +% \end{macrocode} +% +% +% +% +% \bigskip +% \subsection*{The keyword \textbackslash CodeAfter} +% +% +% The |code-after| (inserted with the key |code-after| or after the keyword +% |\CodeAfter| can always begin with a list of pairs \emph{key-value} between +% square brackets). Here the corresponding set of keys. +% \begin{macrocode} +\keys_define:nn { NiceMatrix / CodeAfter } + { + sub-matrix .code:n = + \keys_set:nn { NiceMatrix / sub-matrix } { #1 } , + sub-matrix .value_required:n = true , + delimiters-color .tl_set:N = \l_@@_delimiters_color_tl , + delimiters-color .value_required:n = true , + unknown .code:n = \@@_error:n { Unknown~key~for~CodeAfter } + } +% \end{macrocode} +% +% \medskip +% In fact, in this subsection, we define the user command |\CodeAfter| for the +% case of the ``normal syntax''. For the case of ``light-syntax'', see the +% definition of the environment |{@@-light-syntax}| on +% p.~\pageref{code-light-syntax}. +% +% +% \medskip +% In the environments of \pkg{nicematrix}, |\CodeAfter| will be linked to +% |\@@_CodeAfter:|. That macro must \emph{not} be protected since it begins with +% |\omit|. +% \begin{macrocode} +\cs_new:Npn \@@_CodeAfter: { \omit \@@_CodeAfter_i:n } +% \end{macrocode} +% +% \medskip +% However, in each cell of the environment, the command |\CodeAfter| will be +% linked to the following command |\@@_CodeAfter_i:n| which do \emph{not} begin +% with |\omit| (and thus, the user will be able to use |\CodeAfter| without +% error and without the need to prefix by |\omit|. +% +% \smallskip +% We have to catch everything until the end of the current environment (of +% \pkg{nicematrix}). First, we go until the next command |\end|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_CodeAfter_i:n #1 \end + { + \tl_gput_right:Nn \g_nicematrix_code_after_tl { #1 } + \@@_CodeAfter_ii:n + } +% \end{macrocode} +% +% We catch the argument of the command |\end| (in |#1|). +% \begin{macrocode} +\cs_new_protected:Npn \@@_CodeAfter_ii:n #1 + { +% \end{macrocode} +% If this is really the end of the current environment (of \pkg{nicematrix}), we +% put back the command |\end| and its argument in the TeX flow. +% \begin{macrocode} + \str_if_eq:eeTF \@currenvir { #1 } + { \end { #1 } } +% \end{macrocode} +% If this is not the |\end| we are looking for, we put those tokens in +% |\g_nicematrix_code_after_tl| and we go on searching for the next command +% |\end| with a recursive call to the command |\@@_CodeAfter:n|. +% \begin{macrocode} + { + \tl_gput_right:Nn \g_nicematrix_code_after_tl { \end { #1 } } + \@@_CodeAfter_i:n + } + } +% \end{macrocode} +% +% +% \subsection*{The delimiters in the preamble} +% +% The command |\@@_delimiter:nnn| will be used to draw delimiters inside the +% matrix when delimiters are specified in the preamble of the array. It does +% \emph{not} concern the exterior delimiters added by |{NiceArrayWithDelims}| +% (and |{pNiceArray}|, |{pNiceMatrix}|, etc.). +% +% A delimiter in the preamble of the array will write an instruction +% |\@@_delimiter:nnn| in the |\g_@@_internal_code_after_tl| (and also +% potentially add instructions in the preamble provided to |\array| in order to +% add spaces between columns). +% +% \smallskip +% The first argument is the type of delimiter (|(|, |[|, |\{|, |)|, |]| ou +% |\}|). The second argument is the number of colummn. The third argument is a +% boolean equal to |\c_true_bool| (resp. |\c_false_true|) when the delimiter +% must be put on the left (resp. right) side. +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_delimiter:nnn #1 #2 #3 + { + \pgfpicture + \pgfrememberpicturepositiononpagetrue + \pgf@relevantforpicturesizefalse +% \end{macrocode} +% +% \medskip +% |\l_@@_y_initial_dim| and |\l_@@_y_final_dim| will be the $y$-values of the +% extremities of the delimiter we will have to construct. +% \begin{macrocode} + \@@_qpoint:n { row - 1 } + \dim_set_eq:NN \l_@@_y_initial_dim \pgf@y + \@@_qpoint:n { row - \@@_succ:n \c@iRow } + \dim_set_eq:NN \l_@@_y_final_dim \pgf@y +% \end{macrocode} +% +% \medskip +% We will compute in |\l_tmpa_dim| the $x$-value where we will have to put our +% delimiter (on the left side or on the right side). +% \begin{macrocode} + \bool_if:nTF { #3 } + { \dim_set_eq:NN \l_tmpa_dim \c_max_dim } + { \dim_set:Nn \l_tmpa_dim { - \c_max_dim } } + \int_step_inline:nnn \l_@@_first_row_int \g_@@_row_total_int + { + \cs_if_exist:cT + { pgf @ sh @ ns @ \@@_env: - ##1 - #2 } + { + \pgfpointanchor + { \@@_env: - ##1 - #2 } + { \bool_if:nTF { #3 } { west } { east } } + \dim_set:Nn \l_tmpa_dim + { \bool_if:nTF { #3 } \dim_min:nn \dim_max:nn \l_tmpa_dim \pgf@x } + } + } +% \end{macrocode} +% +% +% Now we can put the delimiter with a node of \textsc{pgf}. +% \begin{macrocode} + \pgfset { inner~sep = \c_zero_dim } + \dim_zero:N \nulldelimiterspace + \pgftransformshift + { + \pgfpoint + { \l_tmpa_dim } + { ( \l_@@_y_initial_dim + \l_@@_y_final_dim + \arrayrulewidth ) / 2 } + } + \pgfnode + { rectangle } + { \bool_if:nTF { #3 } { east } { west } } + { +% \end{macrocode} +% Here is the content of the \textsc{pgf} node, that is to say the delimiter, +% constructed with its right size. +% \begin{macrocode} + \nullfont + \c_math_toggle_token + \tl_if_empty:NF \l_@@_delimiters_color_tl + { \color { \l_@@_delimiters_color_tl } } + \bool_if:nTF { #3 } { \left #1 } { \left . } + \vcenter + { + \nullfont + \hrule \@height + \dim_eval:n { \l_@@_y_initial_dim - \l_@@_y_final_dim } + \@depth \c_zero_dim + \@width \c_zero_dim + } + \bool_if:nTF { #3 } { \right . } { \right #1 } + \c_math_toggle_token + } + { } + { } + \endpgfpicture + } +% \end{macrocode} +% +% \subsection*{The command SubMatrix} +% % +% \begin{macrocode} +\keys_define:nn { NiceMatrix / sub-matrix } + { + extra-height .dim_set:N = \l_@@_submatrix_extra_height_dim , + extra-height .value_required:n = true , + left-xshift .dim_set:N = \l_@@_submatrix_left_xshift_dim , + left-xshift .value_required:n = true , + right-xshift .dim_set:N = \l_@@_submatrix_right_xshift_dim , + right-xshift .value_required:n = true , + xshift .meta:n = { left-xshift = #1, right-xshift = #1 } , + xshift .value_required:n = true , + delimiters-color .tl_set:N = \l_@@_delimiters_color_tl , + delimiters-color .value_required:n = true , + slim .bool_set:N = \l_@@_submatrix_slim_bool , + slim .default:n = true , + } +\keys_define:nn { NiceMatrix } + { + SubMatrix .inherit:n = NiceMatrix /sub-matrix , + CodeAfter / sub-matrix .inherit:n = NiceMatrix / sub-matrix + } +% \end{macrocode} +% +% \medskip +% The following keys set is for the command |\SubMatrix| itself (not the tuning +% of |\SubMatrix| that can be done elsewhere). +% \begin{macrocode} +\keys_define:nn { NiceMatrix / SubMatrix } + { + name .code:n = + \tl_if_empty:nTF { #1 } + { \@@_error:n { Invalid~name~format } } + { + \regex_match:nnTF { \A[A-Za-z][A-Za-z0-9]*\Z } { #1 } + { + \seq_if_in:NnTF \g_@@_submatrix_names_seq { #1 } + { \@@_error:nn { Duplicate~name~for~SubMatrix } { #1 } } + { + \str_set:Nn \l_@@_submatrix_name_str { #1 } + \seq_gput_right:Nn \g_@@_submatrix_names_seq { #1 } + } + } + { \@@_error:n { Invalid~name~format } } + } , + name .value_required:n = true , + unknown .code:n = \@@_error:n { Unknown~key~for~SubMatrix } + } +% \end{macrocode} +% % \bigskip -% \subsection*{We process the options} +% In the |code-after|, the following command |\@@_SubMatrix| will be linked to +% |\SubMatrix|. +% \begin{itemize} +% \item |#1| is the left delimiter; +% \item |#2| is the upper-left cell of the matrix with the format $i$-$j$; +% \item |#2| is the lower-right cell of the matrix with the format $i$-$j$; +% \item |#4| is the right delimiter; +% \item |#5| is the list of options of the command. +% \end{itemize} +% \begin{macrocode} +\NewDocumentCommand \@@_SubMatrix { m m m m ! O { } } + { + \group_begin: +% \end{macrocode} +% The command |\@@_cut_on_hyphen:w| cuts on the hyphen an argument of the form +% $i$-$j$. The value of $i$ is stored in |\l_tmpa_tl| and the value of $j$ is +% stored in |\l_tmpb_tl|. +% \begin{macrocode} + \@@_cut_on_hyphen:w #3 \q_stop + \tl_clear_new:N \l_tmpc_tl + \tl_clear_new:N \l_tmpd_tl + \tl_set_eq:NN \l_tmpc_tl \l_tmpa_tl + \tl_set_eq:NN \l_tmpd_tl \l_tmpb_tl + \@@_cut_on_hyphen:w #2 \q_stop + \bool_lazy_or:nnTF + { \int_compare_p:nNn \l_tmpc_tl > \g_@@_row_total_int } + { \int_compare_p:nNn \l_tmpd_tl > \g_@@_col_total_int } + { \@@_error:n { SubMatrix~too~large } } + { + \dim_zero_new:N \l_@@_submatrix_extra_height_dim + \dim_zero_new:N \l_@@_submatrix_left_xshift_dim + \dim_zero_new:N \l_@@_submatrix_right_xshift_dim + \str_clear_new:N \l_@@_submatrix_name_str + \keys_set:nn { NiceMatrix / SubMatrix } { #5 } + \pgfpicture + \pgfrememberpicturepositiononpagetrue + \pgf@relevantforpicturesizefalse + \pgfset { inner~sep = \c_zero_dim } + \dim_set_eq:NN \l_@@_x_initial_dim \c_max_dim + \dim_set:Nn \l_@@_x_final_dim { - \c_max_dim } +% \end{macrocode} +% The last value of |\int_step_inline:nnn| is provided by currifycation. +% \begin{macrocode} + \bool_if:NTF \l_@@_submatrix_slim_bool + { \int_step_inline:nnn \l_tmpa_tl \l_tmpc_tl } + { \int_step_inline:nnn \l_@@_first_row_int \g_@@_row_total_int } + { + \cs_if_exist:cT + { pgf @ sh @ ns @ \@@_env: - ##1 - \l_tmpb_tl } + { + \pgfpointanchor { \@@_env: - ##1 - \l_tmpb_tl } { west } + \dim_set:Nn \l_@@_x_initial_dim + { \dim_min:nn \l_@@_x_initial_dim \pgf@x } + } + \cs_if_exist:cT + { pgf @ sh @ ns @ \@@_env: - ##1 - \l_tmpd_tl } + { + \pgfpointanchor { \@@_env: - ##1 - \l_tmpd_tl } { east } + \dim_set:Nn \l_@@_x_final_dim + { \dim_max:nn \l_@@_x_final_dim \pgf@x } + } + } + \@@_qpoint:n { row - \l_tmpa_tl - base } + \dim_set:Nn \l_@@_y_initial_dim + { \pgf@y + ( \box_ht:N \strutbox + \extrarowheight ) * \arraystretch } + \@@_qpoint:n { row - \l_tmpc_tl - base } + \dim_set:Nn \l_@@_y_final_dim + { \pgf@y - ( \box_dp:N \strutbox ) * \arraystretch } + \int_step_inline:nnn \l_@@_first_col_int \g_@@_col_total_int + { + \cs_if_exist:cT + { pgf @ sh @ ns @ \@@_env: - \l_tmpa_tl - ##1 } + { + \pgfpointanchor { \@@_env: - \l_tmpa_tl - ##1 } { north } + \dim_set:Nn \l_@@_y_initial_dim + { \dim_max:nn \l_@@_y_initial_dim \pgf@y } + } + \cs_if_exist:cT + { pgf @ sh @ ns @ \@@_env: - \l_tmpc_tl - ##1 } + { + \pgfpointanchor { \@@_env: - \l_tmpc_tl - ##1 } { south } + \dim_set:Nn \l_@@_y_final_dim + { \dim_min:nn \l_@@_y_final_dim \pgf@y } + } + } + \dim_set:Nn \l_tmpa_dim + { + \l_@@_y_initial_dim - \l_@@_y_final_dim + + \l_@@_submatrix_extra_height_dim - \arrayrulewidth + } + \dim_set_eq:NN \nulldelimiterspace \c_zero_dim +% \end{macrocode} +% +% \medskip +% If the key |name| has been used for the command |\SubMatrix|, we create a PGF +% node with that name for the submatrix (this node does not take into account +% the delimiters that we will put after). +% \begin{macrocode} + \str_if_empty:NF \l_@@_submatrix_name_str + { + \@@_pgf_rect_node:nnnnn \l_@@_submatrix_name_str + \l_@@_x_initial_dim \l_@@_y_initial_dim + \l_@@_x_final_dim \l_@@_y_final_dim + } +% \end{macrocode} % +% \medskip +% Now, we deal with the left delimiter. Of course, the environment +% |{pgfscope}| is for the |\pgftransformshift|. +% \begin{macrocode} + \begin { pgfscope } + \pgftransformshift + { + \pgfpoint + { \l_@@_x_initial_dim - \l_@@_submatrix_left_xshift_dim } + { ( \l_@@_y_initial_dim + \l_@@_y_final_dim ) / 2 } + } + \str_if_empty:NTF \l_@@_submatrix_name_str + { \@@_node_left:nn #1 { } } + { \@@_node_left:nn #1 { \@@_env: - \l_@@_submatrix_name_str - left } } + \end { pgfscope } +% \end{macrocode} +% +% \medskip +% Now, we deal with the right delimiter. +% \begin{macrocode} + \pgftransformshift + { + \pgfpoint + { \l_@@_x_final_dim + \l_@@_submatrix_right_xshift_dim } + { ( \l_@@_y_initial_dim + \l_@@_y_final_dim ) / 2 } + } + \str_if_empty:NTF \l_@@_submatrix_name_str + { \@@_node_right:nn #4 { } } + { + \@@_node_right:nn #4 { \@@_env: - \l_@@_submatrix_name_str - right } + } + \endpgfpicture + } + \group_end: + } +% \end{macrocode} +% +% \medskip +% The command |\@@_node_left:nn| puts the left delimiter with the correct size. +% The argument |#1| is the delimiter to put. The argument |#2| is the name we +% will give to this PGF node (if the key |name| has been used in |\SubMatrix|). +% \begin{macrocode} +\cs_new_protected:Npn \@@_node_left:nn #1 #2 + { + \pgfnode + { rectangle } + { east } + { + \nullfont + \c_math_toggle_token + \tl_if_empty:NF \l_@@_delimiters_color_tl + { \color { \l_@@_delimiters_color_tl } } + \left #1 + \vcenter + { + \nullfont + \hrule \@height \l_tmpa_dim + \@depth \c_zero_dim + \@width \c_zero_dim + } + \right . + \c_math_toggle_token + } + { #2 } + { } + } +% \end{macrocode} +% +% \medskip +% The command |\@@_node_right:nn| puts the right delimiter with the correct size. +% The argument |#1| is the delimiter to put. The argument |#2| is the name we +% will give to this PGF node (if the key |name| has been used in |\SubMatrix|). +% \begin{macrocode} +\cs_new_protected:Npn \@@_node_right:nn #1 #2 + { + \pgfnode + { rectangle } + { west } + { + \nullfont + \c_math_toggle_token + \tl_if_empty:NF \l_@@_delimiters_color_tl + { \color { \l_@@_delimiters_color_tl } } + \left . + \vcenter + { + \nullfont + \hrule \@height \l_tmpa_dim + \@depth \c_zero_dim + \@width \c_zero_dim + } + \right #1 + \c_math_toggle_token + } + { #2 } + { } + } +% \end{macrocode} +% +% \bigskip +% \subsection*{We process the options at package loading} +% +% % We process the options when the package is loaded (with |\usepackage|) but we % recommend to use |\NiceMatrixOptions| instead. % @@ -8349,59 +14418,149 @@ version 2005/12/01 or later. % % Of course, the command |\NiceMatrix| must be defined before such an % instruction is executed. +% +% \medskip +%% \medskip +% The boolean |\g_@@_footnotehyper_bool| will indicate if the option +% |footnotehyper| is used. +% \begin{macrocode} +\bool_new:N \c_@@_footnotehyper_bool +% \end{macrocode} +% +% \medskip +% The boolean |\c_@@_footnote_bool| will indicate if the option |footnote| is +% used, but quicky, it will also be set to |true| if the option |footnotehyper| +% is used. +% \begin{macrocode} +\bool_new:N \c_@@_footnote_bool +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nnn { Unknown~option~for~package } + { + The~key~'\l_keys_key_str'~is~unknown. \\ + If~you~go~on,~it~will~be~ignored. \\ + For~a~list~of~the~available~keys,~type~H~<return>. + } + { + The~available~keys~are~(in~alphabetic~order):~ + define-L-C-R,~ + footnote,~ + footnotehyper,~ + renew-dots,~and + renew-matrix. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { Key~transparent } + { + The~key~'transparent'~is~now~obsolete~(because~it's~name~ + is~not~clear).~You~should~use~the~conjonction~of~'renew-dots'~ + and~'renew-matrix'.~However,~you~can~go~on. + } +% \end{macrocode} +% % \begin{macrocode} -\bool_new:N \c_@@_obsolete_environments_bool \keys_define:nn { NiceMatrix / Package } { + define-L-C-R .bool_set:N = \c_@@_define_L_C_R_bool , + define-L-C-R .default:n = true , renew-dots .bool_set:N = \l_@@_renew_dots_bool , renew-dots .value_forbidden:n = true , renew-matrix .code:n = \@@_renew_matrix: , renew-matrix .value_forbidden:n = true , - transparent .meta:n = { renew-dots , renew-matrix } , + transparent .code:n = + { + \@@_renew_matrix: + \bool_set_true:N \l_@@_renew_dots_bool + \@@_error:n { Key~transparent } + } , transparent .value_forbidden:n = true, - obsolete-environments .bool_set:N = \c_@@_obsolete_environments_bool , - obsolete-environments .value_forbidden:n = true , - obsolete-environments .default:n = true , - starred-commands .code:n = - \@@_msg_redirect_name:nn { starred~commands } { none } , - starred-commands .value_forbidden:n = true , - + footnote .bool_set:N = \c_@@_footnote_bool , + footnotehyper .bool_set:N = \c_@@_footnotehyper_bool , + unknown .code:n = \@@_error:n { Unknown~option~for~package } } \ProcessKeysOptions { NiceMatrix / Package } % \end{macrocode} % % \bigskip -% \subsection*{Error messages of the package} +% \begin{macrocode} +\@@_msg_new:nn { footnote~with~footnotehyper~package } + { + You~can't~use~the~option~'footnote'~because~the~package~ + footnotehyper~has~already~been~loaded.~ + If~you~want,~you~can~use~the~option~'footnotehyper'~and~the~footnotes~ + within~the~environments~of~nicematrix~will~be~extracted~with~the~tools~ + of~the~package~footnotehyper.\\ + If~you~go~on,~the~package~footnote~won't~be~loaded. + } +% \end{macrocode} % -% 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 } } +\@@_msg_new:nn { footnotehyper~with~footnote~package } + { + You~can't~use~the~option~'footnotehyper'~because~the~package~ + footnote~has~already~been~loaded.~ + If~you~want,~you~can~use~the~option~'footnote'~and~the~footnotes~ + within~the~environments~of~nicematrix~will~be~extracted~with~the~tools~ + of~the~package~footnote.\\ + If~you~go~on,~the~package~footnotehyper~won't~be~loaded. + } +% \end{macrocode} +% +% \medskip +% \begin{macrocode} +\bool_if:NT \c_@@_footnote_bool + { +% \end{macrocode} +% The class \cls{beamer} has its own system to extract footnotes and that's why +% we have nothing to do if \cls{beamer} is used. +% \begin{macrocode} + \@ifclassloaded { beamer } + { \bool_set_false:N \c_@@_footnote_bool } + { + \@ifpackageloaded { footnotehyper } + { \@@_error:n { footnote~with~footnotehyper~package } } + { \usepackage { footnote } } } - \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 +\bool_if:NT \c_@@_footnotehyper_bool + { +% \end{macrocode} +% The class \cls{beamer} has its own system to extract footnotes and that's why +% we have nothing to do if \cls{beamer} is used. +% \begin{macrocode} + \@ifclassloaded { beamer } + { \bool_set_false:N \c_@@_footnote_bool } + { + \@ifpackageloaded { footnote } + { \@@_error:n { footnotehyper~with~footnote~package } } + { \usepackage { footnotehyper } } + } + \bool_set_true:N \c_@@_footnote_bool } % \end{macrocode} -% +% The flag |\c_@@_footnote_bool| is raised and so, we will only have to test +% |\c_@@_footnote_bool| in order to know if we have to insert an environment +% |{savenotes}|. +% +% +% \bigskip +% \subsection*{Error messages of the package} +% % \begin{macrocode} -\@@_set_seq_of_str_from_clist:Nn \c_@@_types_of_matrix_seq +\seq_new:N \c_@@_types_of_matrix_seq +\seq_set_from_clist:Nn \c_@@_types_of_matrix_seq { NiceMatrix , pNiceMatrix , bNiceMatrix , vNiceMatrix, BNiceMatrix, VNiceMatrix } +\seq_set_map_x:NNn \c_@@_types_of_matrix_seq \c_@@_types_of_matrix_seq + { \tl_to_str:n { #1 } } % \end{macrocode} % % \bigskip @@ -8415,9 +14574,12 @@ version 2005/12/01 or later. { \seq_if_in:NVTF \c_@@_types_of_matrix_seq \g_@@_name_env_str { - \int_compare:nNnTF \l_@@_last_col_int = { -1 } + \int_compare:nNnTF \l_@@_last_col_int = { -2 } { \@@_fatal:n { too~much~cols~for~matrix } } - { \@@_fatal:n { too~much~cols~for~matrix~with~last~col } } + { + \bool_if:NF \l_@@_last_col_without_value_bool + { \@@_fatal:n { too~much~cols~for~matrix~with~last~col } } + } } { \@@_fatal:n { too~much~cols~for~array } } } @@ -8427,8 +14589,8 @@ version 2005/12/01 or later. % \begin{macrocode} \cs_new:Npn \@@_message_hdotsfor: { - \tl_if_empty:VF \g_@@_Hdotsfor_lines_tl - { ~Maybe~your~use~of~\token_to_str:N \Hdotsfor\ is~incorrect.} + \tl_if_empty:VF \g_@@_HVdotsfor_lines_tl + { ~Maybe~your~use~of~\token_to_str:N \Hdotsfor\ is~incorrect.} } % \end{macrocode} % @@ -8438,8 +14600,8 @@ version 2005/12/01 or later. { You~try~to~use~more~columns~than~allowed~by~your~ \@@_full_name_env:.\@@_message_hdotsfor:\ The~maximal~number~of~ - columns~is~\int_eval:n { \l_@@_last_col_int - 1 }~(plus~the~potential~ - exterior~ones).~This~error~is~fatal. + columns~is~\int_eval:n { \l_@@_last_col_int - 1 }~(plus~the~ + exterior~columns).~This~error~is~fatal. } % \end{macrocode} % @@ -8451,7 +14613,7 @@ version 2005/12/01 or later. \@@_full_name_env:.\@@_message_hdotsfor:\ Recall~that~the~maximal~ number~of~columns~for~a~matrix~is~fixed~by~the~LaTeX~counter~ 'MaxMatrixCols'.~Its~actual~value~is~\int_use:N \c@MaxMatrixCols.~ - This~error~is~fatal. + This~error~is~fatal. } % \end{macrocode} % @@ -8464,34 +14626,113 @@ version 2005/12/01 or later. { You~try~to~use~more~columns~than~allowed~by~your~ \@@_full_name_env:.\@@_message_hdotsfor:\ The~maximal~number~of~columns~is~ - \int_eval:n { \c@jCol - 1 }~(plus~the~potential~exterior~ones).~ + \int_use:N \g_@@_static_num_of_col_int\ + ~(plus~the~potential~exterior~ones).~ This~error~is~fatal. } % \end{macrocode} % -% +% \begin{macrocode} +\@@_msg_new:nn { last~col~not~used } + { + The~key~'last-col'~is~in~force~but~you~have~not~used~that~last~column~ + in~your~\@@_full_name_env:.~However,~you~can~go~on. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { columns~not~used } + { + The~preamble~of~your~\@@_full_name_env:\ announces~\int_use:N + \g_@@_static_num_of_col_int\ columns~but~you~use~only~\int_use:N \c@jCol.\\ + You~can~go~on~but~the~columns~you~did~not~used~won't~be~created. + } +% \end{macrocode} +% +% +% \begin{macrocode} +\@@_msg_new:nn { in~first~col } + { + You~can't~use~the~command~#1 in~the~first~column~(number~0)~of~the~array.\\ + If~you~go~on,~this~command~will~be~ignored. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { in~last~col } + { + You~can't~use~the~command~#1 in~the~last~column~(exterior)~of~the~array.\\ + If~you~go~on,~this~command~will~be~ignored. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { in~first~row } + { + You~can't~use~the~command~#1 in~the~first~row~(number~0)~of~the~array.\\ + If~you~go~on,~this~command~will~be~ignored. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { in~last~row } + { + You~can't~use~the~command~#1 in~the~last~row~(exterior)~of~the~array.\\ + If~you~go~on,~this~command~will~be~ignored. + } +% \end{macrocode} +% +% % \begin{macrocode} \@@_msg_new:nn { bad~option~for~line-style } { Since~you~haven't~loaded~Tikz,~the~only~value~you~can~give~to~'line-style'~ - is~'standard'.~If~you~go~on,~this~option~will~be~ignored. + is~'standard'.~If~you~go~on,~this~key~will~be~ignored. } % \end{macrocode} % % \begin{macrocode} \@@_msg_new:nn { Unknown~option~for~xdots } { - As~for~now~there~is~only~three~options~available~here:~'color',~'line-style'~ + As~for~now~there~is~only~three~key~available~here:~'color',~'line-style'~ and~'shorten'~(and~you~try~to~use~'\l_keys_key_str').~If~you~go~on,~ - this~option~will~be~ignored. + this~key~will~be~ignored. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { Unknown~option~for~rowcolors } + { + As~for~now~there~is~only~two~keys~available~here:~'cols'~and~'respect-blocks'~ + (and~you~try~to~use~'\l_keys_key_str').~If~you~go~on,~ + this~key~will~be~ignored. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { Key~color~for~Block } + { + The~key~'color'~for~the~command~\token_to_str:N \Block\ + is~deprecated:~you~should~use~'fill'~instead.\\ + You~can~go~on~for~this~time~but~remember~that~that~key~ + will~be~deleted~in~a~future~version. } % \end{macrocode} % % \begin{macrocode} \@@_msg_new:nn { ampersand~in~light-syntax } { - You~can't~use~an~ampersand~(\token_to_str &)~to~separate~columns~because - ~you~have~used~the~option~'light-syntax'.~This~error~is~fatal. + You~can't~use~an~ampersand~(\token_to_str:N &)~to~separate~columns~because~ + ~you~have~used~the~key~'light-syntax'.~This~error~is~fatal. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { SubMatrix~too~large } + { + Your~command~\token_to_str:N \SubMatrix\ + can't~be~drawn~because~your~matrix~is~too~small.\\ + If~you~go~on,~this~command~will~be~ignored. } % \end{macrocode} % @@ -8499,22 +14740,29 @@ version 2005/12/01 or later. \@@_msg_new:nn { double-backslash~in~light-syntax } { You~can't~use~\token_to_str:N \\~to~separate~rows~because~you~have~used~ - the~option~'light-syntax'.~You~must~use~the~character~'\l_@@_end_of_row_tl'~ - (set~by~the~option~'end-of-row').~This~error~is~fatal. + the~key~'light-syntax'.~You~must~use~the~character~'\l_@@_end_of_row_tl'~ + (set~by~the~key~'end-of-row').~This~error~is~fatal. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { standard-cline~in~document } + { + The~key~'standard-cline'~is~available~only~in~the~preamble.\\ + If~you~go~on~this~command~will~be~ignored. } % \end{macrocode} % % \begin{macrocode} -\@@_msg_new:nn { starred~commands } +\@@_msg_new:nn { old~column~type } { - The~starred~versions~of~\token_to_str:N \Cdots,~\token_to_str:N \Ldots,~ - \token_to_str:N \Vdots,~\token_to_str:N\Ddots\ and~\token_to_str:N\Iddots\ - are~deprecated.~However,~you~can~go~on~for~this~time.~If~you~don't~want~to~ - see~this~error~we~should~load~'nicematrix'~with~the~option~ - 'starred-commands'. + The~column~type~'#1'~is~no~longer~defined~in~'nicematrix'.~ + Since~version~5.0,~you~have~to~use~'l',~'c'~and~'r'~instead~of~'L',~ + 'C'~and~'R'.~You~can~also~use~the~key~'define-L-C-R'.\\ + This~error~is~fatal. } % \end{macrocode} -% +% % \begin{macrocode} \@@_msg_new:nn { bad~value~for~baseline } { @@ -8525,12 +14773,13 @@ version 2005/12/01 or later. } % \end{macrocode} % -% -% \begin{macrocode} -\@@_msg_new:nn { Second~Block } +% \begin{macrocode} +\@@_msg_new:nn { Invalid~name~format } { - 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. + You~can't~give~the~name~'\l_keys_value_tl'~to~a~\token_to_str:N + \SubMatrix.\\ + A~name~must~be~accepted~by~the~regular~expression~[A-Za-z][A-Za-z0-9]*.\\ + If~you~go~on,~this~key~will~be~ignored. } % \end{macrocode} % @@ -8540,6 +14789,15 @@ version 2005/12/01 or later. % \end{macrocode} % % \begin{macrocode} +\@@_msg_new:nn { Delimiter~with~small } + { + You~can't~put~a~delimiter~in~the~preamble~of~your~\@@_full_name_env:\ + because~the~key~'small'~is~in~force.\\ + This~error~is~fatal. + } +% \end{macrocode} +% +% \begin{macrocode} \@@_msg_new:nn { unknown~cell~for~line~in~code-after } { Your~command~\token_to_str:N\line\{#1\}\{#2\}~in~the~'code-after'~ @@ -8548,11 +14806,54 @@ version 2005/12/01 or later. } % \end{macrocode} % -% +% +% \begin{macrocode} +\@@_msg_new:nnn { Duplicate~name~for~SubMatrix } + { + The~name~'#1'~is~already~used~for~a~\token_to_str:N \SubMatrix\ + in~this~\@@_full_name_env:.\\ + If~you~go~on,~this~key~will~be~ignored.\\ + For~a~list~of~the~names~already~used,~type~H~<return>. + } + { + The~names~already~defined~in~this~\@@_full_name_env:\ are:~ + \seq_use:Nnnn \g_@@_submatrix_names_seq { ~and~ } { ,~ } { ~and~ }. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { Hdotsfor~in~col~0 } + { + You~can't~use~\token_to_str:N \Hdotsfor\ in~an~exterior~column~of~ + the~array.~This~error~is~fatal. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { bad~corner } + { + #1~is~an~incorrect~specification~for~a~corner~(in~the~keys~ + 'except-corners'~and~'hvlines-except-corners').~The~available~ + values~are:~NW,~SW,~NE~and~SE.\\ + If~you~go~on,~this~specification~of~corner~will~be~ignored. + } +% \end{macrocode} +% % \begin{macrocode} \@@_msg_new:nn { last-col~non~empty~for~NiceArray } { - In~the~\@@_full_name_env:,~you~must~use~the~option~ + In~the~\@@_full_name_env:,~you~must~use~the~key~ + 'last-col'~without~value.\\ + However,~you~can~go~on~for~this~time~ + (the~value~'\l_keys_value_tl'~will~be~ignored). + } +% \end{macrocode} +% +% +% \begin{macrocode} +\@@_msg_new:nn { last-col~non~empty~for~NiceMatrixOptions } + { + In~\NiceMatrixoptions,~you~must~use~the~key~ 'last-col'~without~value.\\ However,~you~can~go~on~for~this~time~ (the~value~'\l_keys_value_tl'~will~be~ignored). @@ -8561,16 +14862,65 @@ version 2005/12/01 or later. % % % \begin{macrocode} -\@@_msg_new:nn { Block~too~large } +\@@_msg_new:nn { Block~too~large~1 } { You~try~to~draw~a~block~in~the~cell~#1-#2~of~your~matrix~but~the~matrix~is~ too~small~for~that~block. \\ + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { Block~too~large~2 } + { + The~preamble~of~your~\@@_full_name_env:\ announces~\int_use:N + \g_@@_static_num_of_col_int\ + columns~but~you~use~only~\int_use:N \c@jCol\ and~that's~why~a~block~ + specified~in~the~cell~#1-#2~can't~be~drawn.~You~should~add~some~ampersands~ + (&)~at~the~end~of~the~first~row~of~your~ + \@@_full_name_env:.\\ + If~you~go~on,this~block~and~maybe~others~will~be~ignored. + } +% \end{macrocode} +% +% +% \begin{macrocode} +\@@_msg_new:nn { unknown~column~type } + { + The~column~type~'#1'~in~your~\@@_full_name_env:\ + is~unknown. \\ + This~error~is~fatal. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { tabularnote~forbidden } + { + You~can't~use~the~command~\token_to_str:N\tabularnote\ + ~in~a~\@@_full_name_env:.~This~command~is~available~only~in~ + \{NiceTabular\},~\{NiceArray\}~and~\{NiceMatrix\}. \\ If~you~go~on,~this~command~will~be~ignored. } % \end{macrocode} % +% \begin{macrocode} +\@@_msg_new:nn { bottomrule~without~booktabs } + { + You~can't~use~the~key~'tabular/bottomrule'~because~you~haven't~ + loaded~'booktabs'.\\ + If~you~go~on,~this~key~will~be~ignored. + } +% \end{macrocode} % % \begin{macrocode} +\@@_msg_new:nn { enumitem~not~loaded } + { + You~can't~use~the~command~\token_to_str:N\tabularnote\ + ~because~you~haven't~loaded~'enumitem'.\\ + If~you~go~on,~this~command~will~be~ignored. + } +% \end{macrocode} +% +% \begin{macrocode} \@@_msg_new:nn { Wrong~last~row } { You~have~used~'last-row=\int_use:N \l_@@_last_row_int'~but~your~ @@ -8584,10 +14934,7 @@ version 2005/12/01 or later. % % \begin{macrocode} \@@_msg_new:nn { Yet~in~env } - { - Environments~\{NiceArray\}~(or~\{NiceMatrix\},~etc.)~can't~be~nested.\\ - This~error~is~fatal. - } + { Environments~of~nicematrix~can't~be~nested.\\ This~error~is~fatal. } % \end{macrocode} % % \begin{macrocode} @@ -8602,23 +14949,87 @@ version 2005/12/01 or later. % \begin{macrocode} \@@_msg_new:nn { Bad~value~for~letter~for~dotted~lines } { - The~value~of~key~'\tl_use:N\l_keys_key_str'~must~be~of~length~1.\\ + The~value~of~key~'\l_keys_key_str'~must~be~of~length~1.\\ If~you~go~on,~it~will~be~ignored. } % \end{macrocode} % +% +% \begin{macrocode} +\@@_msg_new:nnn { Unknown~key~for~Block } + { + The~key~'\l_keys_key_str'~is~unknown~for~the~command~\token_to_str:N + \Block.\\ If~you~go~on,~it~will~be~ignored. \\ + For~a~list~of~the~available~keys,~type~H~<return>. + } + { + The~available~keys~are~(in~alphabetic~order):~-,~c,~draw,~fill,~l,~ + line-width~and~r. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nnn { Unknown~key~for~CodeAfter } + { + The~key~'\l_keys_key_str'~is~unknown.\\ + If~you~go~on,~it~will~be~ignored. \\ + For~a~list~of~the~available~keys~in~\token_to_str:N + \CodeAfter,~type~H~<return>. + } + { + The~available~keys~are~(in~alphabetic~order):~ + delimiters-color,~ + sub-matrix~(several~subkeys)~ + and~xdots~(several~subkeys).~ + The~latter~is~for~the~command~\token_to_str:N \line. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nn { Unknown~key~for~SubMatrix } + { + The~key~'\l_keys_key_str'~is~unknown.\\ + The~only~keys~available~here~are~'delimiters-color',~'extra-height',~ + 'left-xshift',~'name',~'right-xshift',~'slim'~and~'xshift'.\\ + If~you~go~on,~this~key~will~be~ignored. \\ + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nnn { Unknown~key~for~notes } + { + The~key~'\l_keys_key_str'~is~unknown.\\ + If~you~go~on,~it~will~be~ignored. \\ + For~a~list~of~the~available~keys~about~notes,~type~H~<return>. + } + { + The~available~keys~are~(in~alphabetic~order):~ + bottomrule,~ + code-after,~ + code-before,~ + enumitem-keys,~ + enumitem-keys-para,~ + para,~ + label-in-list,~ + label-in-tabular~and~ + style. + } +% \end{macrocode} % % \begin{macrocode} \@@_msg_new:nnn { Unknown~key~for~NiceMatrixOptions } { - The~key~'\tl_use:N\l_keys_key_str'~is~unknown~for~the~command~ + The~key~'\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~<return>. + For~a~list~of~the~*principal*~available~keys,~type~H~<return>. } { - The~available~options~are~(in~alphabetic~order):~ + The~available~keys~are~(in~alphabetic~order):~ allow-duplicate-names,~ + cell-space-bottom-limit,~ + cell-space-limits,~ + cell-space-top-limit,~ code-for-first-col,~ code-for-first-row,~ code-for-last-col,~ @@ -8626,65 +15037,76 @@ version 2005/12/01 or later. create-extra-nodes,~ create-medium-nodes,~ create-large-nodes,~ + delimiters-color,~ end-of-row,~ - exterior-arraycolsep,~ + first-col,~ + first-row,~ hlines,~ hvlines,~ + hvlines-except-corners,~ + last-col,~ + last-row,~ left-margin,~ letter-for-dotted-lines,~ light-syntax,~ + notes~(several~subkeys),~ nullify-dots,~ - parallelize-diags,~ renew-dots,~ renew-matrix,~ right-margin,~ small,~ - transparent,~ + sub-matrix~(several~subkeys), vlines,~ - xdots/color,~ - xdots/shorten~and~ - xdots/line-style. + xdots~(several~subkeys). } % \end{macrocode} % % \begin{macrocode} \@@_msg_new:nnn { Unknown~option~for~NiceArray } { - The~option~'\tl_use:N\l_keys_key_str'~is~unknown~for~the~environment~ + The~key~'\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~<return>. + For~a~list~of~the~*principal*~available~keys,~type~H~<return>. } { - The~available~options~are~(in~alphabetic~order):~ + The~available~keys~are~(in~alphabetic~order):~ b,~ baseline,~ c,~ + cell-space-bottom-limit,~ + cell-space-limits,~ + cell-space-top-limit,~ code-after,~ code-for-first-col,~ code-for-first-row,~ code-for-last-col,~ code-for-last-row,~ + colortbl-like,~ columns-width,~ create-extra-nodes,~ create-medium-nodes,~ create-large-nodes,~ - end-of-row,~ + delimiters-color,~ extra-left-margin,~ extra-right-margin,~ first-col,~ first-row,~ hlines,~ hvlines,~ + hvlines-except-corners,~ last-col,~ last-row,~ left-margin,~ light-syntax,~ name,~ + notes/bottomrule,~ + notes/para,~ nullify-dots,~ - parallelize-diags,~ renew-dots,~ right-margin,~ + rules/color,~ + rules/width,~ small,~ t,~ vlines,~ @@ -8697,45 +15119,108 @@ version 2005/12/01 or later. % \medskip % This error message is used for the set of keys |NiceMatrix/NiceMatrix| and % |NiceMatrix/pNiceArray| (but not by |NiceMatrix/NiceArray| because, for this -% set of keys, there is also the options |t|, |c| and~|b|). +% set of keys, there is also the keys |t|, |c| and~|b|). % \begin{macrocode} \@@_msg_new:nnn { Unknown~option~for~NiceMatrix } { - The~option~'\tl_use:N\l_keys_key_str'~is~unknown~for~the~ + The~key~'\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~<return>. + For~a~list~of~the~*principal*~available~keys,~type~H~<return>. } { - The~available~options~are~(in~alphabetic~order):~ + The~available~keys~are~(in~alphabetic~order):~ + b,~ + baseline,~ + c,~ + cell-space-bottom-limit,~ + cell-space-limits,~ + cell-space-top-limit,~ code-after,~ code-for-first-col,~ code-for-first-row,~ code-for-last-col,~ code-for-last-row,~ + colortbl-like,~ columns-width,~ create-extra-nodes,~ create-medium-nodes,~ create-large-nodes,~ - end-of-row,~ + delimiters-color,~ extra-left-margin,~ extra-right-margin,~ first-col,~ first-row,~ hlines,~ hvlines,~ - l~(=L),~ + hvlines-except-corners,~ + l,~ last-col,~ last-row,~ left-margin,~ light-syntax,~ name,~ nullify-dots,~ - parallelize-diags,~ - r~(=R),~ + r,~ renew-dots,~ right-margin,~ + rules/color,~ + rules/width,~ small,~ + t,~ + vlines,~ + xdots/color,~ + xdots/shorten~and~ + xdots/line-style. + } +% \end{macrocode} +% +% \begin{macrocode} +\@@_msg_new:nnn { Unknown~option~for~NiceTabular } + { + The~key~'\l_keys_key_str'~is~unknown~for~the~environment~ + \{NiceTabular\}. \\ + If~you~go~on,~it~will~be~ignored. \\ + For~a~list~of~the~*principal*~available~keys,~type~H~<return>. + } + { + The~available~keys~are~(in~alphabetic~order):~ + b,~ + baseline,~ + c,~ + cell-space-bottom-limit,~ + cell-space-limits,~ + cell-space-top-limit,~ + code-after,~ + code-for-first-col,~ + code-for-first-row,~ + code-for-last-col,~ + code-for-last-row,~ + colortbl-like,~ + columns-width,~ + create-extra-nodes,~ + create-medium-nodes,~ + create-large-nodes,~ + extra-left-margin,~ + extra-right-margin,~ + first-col,~ + first-row,~ + hlines,~ + hvlines,~ + hvlines-except-corners,~ + last-col,~ + last-row,~ + left-margin,~ + light-syntax,~ + name,~ + notes/bottomrule,~ + notes/para,~ + nullify-dots,~ + renew-dots,~ + right-margin,~ + rules/color,~ + rules/width,~ + t,~ vlines,~ xdots/color,~ xdots/shorten~and~ @@ -8751,129 +15236,38 @@ version 2005/12/01 or later. the~same~environment~name~twice.~You~can~go~on,~but,~ maybe,~you~will~have~incorrect~results~especially~ if~you~use~'columns-width=auto'.~If~you~don't~want~to~see~this~ - message~again,~use~the~option~'allow-duplicate-names'.\\ + message~again,~use~the~key~'allow-duplicate-names'~in~ + '\token_to_str:N \NiceMatrixOptions'.\\ For~a~list~of~the~names~already~used,~type~H~<return>. \\ } { The~names~already~defined~in~this~document~are:~ - \seq_use:Nnnn \g_@@_names_seq { ,~ } { ,~ } { ~and~ }. + \seq_use:Nnnn \g_@@_names_seq { ~and~ } { ,~ } { ~and~ }. } % \end{macrocode} % % \begin{macrocode} \@@_msg_new:nn { Option~auto~for~columns-width } { - You~can't~give~the~value~'auto'~to~the~option~'columns-width'~here.~ - If~you~go~on,~the~option~will~be~ignored. + You~can't~give~the~value~'auto'~to~the~key~'columns-width'~here.~ + If~you~go~on,~the~key~will~be~ignored. } % \end{macrocode} % -% \begin{macrocode} -\@@_msg_new:nn { Zero~row } - { - 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} -% -% -% \bigskip -% \subsection*{Obsolete environments} -% -% The following environments are loaded only when the package \pkg{nicematrix} -% has been loaded with the option |obsolete-environments|. However, they will be -% completly deleted in a future version. -% -% \begin{macrocode} -\bool_if:NT \c_@@_obsolete_environments_bool - { - \NewDocumentEnvironment { pNiceArrayC } { } - { - \int_zero:N \l_@@_last_col_int - \pNiceArray - } - { \endpNiceArray } - \NewDocumentEnvironment { bNiceArrayC } { } - { - \int_zero:N \l_@@_last_col_int - \bNiceArray - } - { \endbNiceArray } - \NewDocumentEnvironment { BNiceArrayC } { } - { - \int_zero:N \l_@@_last_col_int - \BNiceArray - } - { \endBNiceArray } - \NewDocumentEnvironment { vNiceArrayC } { } - { - \int_zero:N \l_@@_last_col_int - \vNiceArray - } - { \endvNiceArray } - \NewDocumentEnvironment { VNiceArrayC } { } - { - \int_zero:N \l_@@_last_col_int - \VNiceArray - } - { \endVNiceArray } - \NewDocumentEnvironment { pNiceArrayRC } { } - { - \int_zero:N \l_@@_last_col_int - \int_zero:N \l_@@_first_row_int - \pNiceArray - } - { \endpNiceArray } - \NewDocumentEnvironment { bNiceArrayRC } { } - { - \int_zero:N \l_@@_last_col_int - \int_zero:N \l_@@_first_row_int - \bNiceArray - } - { \endbNiceArray } - \NewDocumentEnvironment { BNiceArrayRC } { } - { - \int_zero:N \l_@@_last_col_int - \int_zero:N \l_@@_first_row_int - \BNiceArray - } - { \endBNiceArray } - \NewDocumentEnvironment { vNiceArrayRC } { } - { - \int_zero:N \l_@@_last_col_int - \int_zero:N \l_@@_first_row_int - \vNiceArray - } - { \endvNiceArray } - \NewDocumentEnvironment { VNiceArrayRC } { } - { - \int_zero:N \l_@@_last_col_int - \int_zero:N \l_@@_first_row_int - \VNiceArray - } - { \endVNiceArray } - \NewDocumentEnvironment { NiceArrayCwithDelims } { } - { - \int_zero:N \l_@@_last_col_int - \NiceArrayWithDelims - } - { \endNiceArrayWithDelims } - \NewDocumentEnvironment { NiceArrayRCwithDelims } { } - { - \int_zero:N \l_@@_last_col_int - \int_zero:N \l_@@_first_row_int - \NiceArrayWithDelims - } - { \endNiceArrayWithDelims } - } -% \end{macrocode} -% -% +% % % \vspace{1cm} % \section{History} % +% The successive versions of the file |nicematrix.sty| provided by TeXLive are available on the +% \textsc{svn} server of TeXLive: +% +% { +% \small +% \url{https:www.tug.org/svn/texlive/trunk/Master/texmf-dist/tex/latex/nicematrix/nicematrix.sty} +% } +% +% % \subsection*{Changes between versions 1.0 and 1.1} % % The dotted lines are no longer drawn with Tikz nodes but with Tikz circles @@ -8932,13 +15326,11 @@ version 2005/12/01 or later. % TeX StackExchange\footnote{cf. % |tex.stackexchange.com/questions/450841/tikz-externalize-and-nicematrix-package|}, % Tikz externalization is now deactivated in the environments of the -% extension \pkg{nicematrix}.\footnote{Before this version, there was an error +% package \pkg{nicematrix}.\footnote{Before this version, there was an error % when using \pkg{nicematrix} with Tikz externalization. In any case, it's not % possible to externalize the Tikz elements constructed by \pkg{nicematrix} % because they use the options |overlay| and |remember picture|.} % -% \subsection*{Changes between version 2.1 and 2.1.2} -% Option |draft|: with this option, the dotted lines are not drawn (quicker). % % \subsection*{Changes between version 2.1.2 and 2.1.3} % @@ -8946,7 +15338,7 @@ version 2005/12/01 or later. % the ``main matrix'' (not in the exterior column), the cells in the exterior % column are considered as outside the matrix. That means that it's possible to % do the following matrix with only a |\Cdots| command (and a single |\Vdots|). -% \[\begin{pNiceArray}{Wc{5mm}CWc{5mm}}[first-row,last-col] +% \[\begin{pNiceArray}{Wc{5mm}cWc{5mm}}[first-row,last-col] % & C_j & \\ % \mbox{\Large $0$} & \Vdots & \mbox{\Large $0$} \\ % \strut & a & \Cdots & L_i \\ @@ -8991,9 +15383,6 @@ version 2005/12/01 or later. % % Option |hlines|. % -% A warning is issued when the |draft| mode is used. In this case, the dotted -% lines are not drawn. -% % % \subsection*{Changes between version 2.3 and 3.0} % @@ -9121,7 +15510,7 @@ version 2005/12/01 or later. % $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 +% If the user tries 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 @@ -9148,13 +15537,148 @@ version 2005/12/01 or later. % The code of \pkg{nicematrix} no longer uses Tikz but only \textsc{pgf}. By % default, Tikz is \emph{not} loaded by \pkg{nicematrix}. % -% \subsection*{Changes between versions 3.12 and 3.13} +% \subsection*{Changes between versions 3.13 and 3.14} % -% Correction of a bug (question 60761504 on |stakoverflow|). +% Correction of a bug (question 60761504 on |stackoverflow|). % -% Best error messages when the user uses |&| or |\\| when |light-syntax| is in +% Better error messages when the user uses |&| or |\\| when |light-syntax| is in % force. % +% \subsection*{Changes between versions 3.14 and 3.15} +% +% It's possible to put labels on the dotted lines drawn by |\Ldots|, |\Cdots|, +% |\Vdots|, |\Ddots|, |\Iddots|, |\Hdotsfor| and the command |\line| in the +% |code-after| with the tokens |_| and |^|. +% +% The option |baseline| is now available in all the environments of +% \pkg{nicematrix}. Before, it was available only in |{NiceArray}|. +% +% New keyword |\CodeAfter| (in the environments of \pkg{nicematrix}). +% +% +% \subsection*{Changes between versions 3.15 and 4.0} +% +% New environment |{NiceTabular}| +% +% Commands to color cells, rows and columns with a perfect result in the \textsc{pdf}. +% +% \subsection*{Changes between versions 4.0 and 4.1} +% +% New keys |cell-space-top-limit| and |cell-space-bottom-limit| +% +% New command |\diagbox| +% +% The key |hvline| don't draw rules in the blocks (commands |\Block|) and in the +% virtual blocks corresponding to the dotted lines. +% +% \subsection*{Changes between versions 4.1 and 4.2} +% +% It's now possible to write |\begin{pNiceMatrix}a&b\\c&d\end{pNiceMatrix}^2| +% with the expected result. +% +% \subsection*{Changes between versions 4.2 and 4.3} +% +% The horizontal centering of the content of a |\Block| is correct even when an +% instruction such as |!{\qquad}| is used in the preamble of the array. +% +% It's now possible to use the command |\Block| in the ``last row''. +% +% \subsection*{Changes between versions 4.3 and 4.4} +% +% New key |hvlines-except-corners|. +% +% \subsection*{Changes between versions 4.4 and 5.0} +% +% Use of the standard column types |l|, |c| and |r| instead of |L|, |C| and |R|. +% +% It's now possible to use the command |\diagbox| in a |\Block|. +% +% Command |\tabularnote| +% +% \subsection*{Changes between versions 5.0 and 5.1} +% +% The vertical rules specified by \verb+|+ in the preamble are not broken by +% |\hline\hline| (and other). +% +% Environment |{NiceTabular*}| +% +% Command |\Vdotsfor| similar to |\Hdotsfor| +% +% The variable |\g_nicematrix_code_after_tl| is now public. +% +% \subsection*{Changes between versions 5.1 and 5.2} +% +% The vertical rules specified by \verb+|+ or \verb+||+ in the preamble respect +% the blocks. +% +% Key |respect-blocks| for |\rowcolors| (with a \emph{s}) in the |code-before|. +% +% The variable |\g_nicematrix_code_before_tl| is now public. +% +% The key |baseline| can take in as value of the form \textsl{line-i} to align +% the |\hline| in the row \textsl{i}. +% +% The key |hvlines-except-corners| may take in as value a list of corners (eg: NW,SE). +% +% \subsection*{Changes between versions 5.2 and 5.3} +% +% Keys |c|, |r| and |l| for the command |\Block|. +% +% It's possible to use the key |draw-first| with |\Ddots| and |\Iddots| to +% specify which dotted line will be drawn first (the other lines will be drawn +% parallel to that one if parallelization is activated). +% +% \subsection*{Changes between versions 5.3 and 5.4} +% +% Key |tabularnote|. +% +% Different behaviour for the mono-column blocks. +% +% \subsection*{Changes between versions 5.4 and 5.5} +% +% The user must never put |\omit| before |\CodeAfter|. +% +% Correction of a bug: the tabular notes |\tabularnotes| were not composed when +% present in a block (except a mono-column block). +% +% \subsection*{Changes between versions 5.5 and 5.6} +% +% Different behaviour for the mono-row blocks. +% +% New command |\NotEmpty|. +% +% \subsection*{Changes between versions 5.6 and 5.7} +% +% New key |delimiters-color| +% +% Keys |fill|, |draw| and |line-width| for the command |\Block|. +% +% \subsection*{Changes between versions 5.7 and 5.8} +% +% Keys |cols| and |restart| of the command |\rowcolors| in the |code-before|. +% +% Modification of the behaviour of |\\| in the columns of type |p|, |m| or |b| +% (for a behaviour similar to the environments of \pkg{array}). +% +% Better error messages for the command |\Block|. +% +% \subsection*{Changes between versions 5.8 and 5.9} +% +% Correction of a bug: in the previous versions, it was not possible to use the +% key |line-style| for the continuous dotted lines when the Tikz library |babel| +% was loaded. +% +% New key |cell-space-limits|. +% +% \subsection*{Changes between versions 5.9 and 5.10} +% +% New command |\SubMatrix| available in the |\CodeAfter|. +% +% It's possible to provide options (between brackets) to the command |\CodeAfter|. +% +% A (non fatal) error is raised when the key |transparent|, which is +% deprecated, is used. +% % \PrintIndex % % \tableofcontents @@ -9163,6 +15687,8 @@ version 2005/12/01 or later. % Local Variables: % TeX-fold-mode: t % TeX-fold-preserve-comments: nil +% flyspell-mode: nil % fill-column: 80 % End: + |