summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/nicematrix/nicematrix.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/latex/contrib/nicematrix/nicematrix.dtx')
-rw-r--r--macros/latex/contrib/nicematrix/nicematrix.dtx1661
1 files changed, 1053 insertions, 608 deletions
diff --git a/macros/latex/contrib/nicematrix/nicematrix.dtx b/macros/latex/contrib/nicematrix/nicematrix.dtx
index 8709af977d..3e91e79795 100644
--- a/macros/latex/contrib/nicematrix/nicematrix.dtx
+++ b/macros/latex/contrib/nicematrix/nicematrix.dtx
@@ -15,8 +15,8 @@
%
% \fi
% \iffalse
-\def\myfileversion{3.0}
-\def\myfiledate{2019/08/15}
+\def\myfileversion{3.1}
+\def\myfiledate{2019/09/04}
%
%
%<*batchfile>
@@ -310,33 +310,9 @@ c & c & b & a & e
% resulting \textsc{pdf}\footnote{And it's not possible to draw a |\Ldots| and a
% |\Cdots| line between the same cells.}).
%
-% However, useless computations are performed by TeX before detecting that both
-% instructions would eventually yield the same dotted line. That's why the
-% package \pkg{nicematrix} provides starred versions of |\Ldots|, |\Cdots|,
-% etc.: |\Ldots*|, |\Cdots*|, etc. These versions are simply equivalent to
-% |\hphantom{\ldots}|, |\hphantom{\cdots}|, etc. The user should use these
-% starred versions whenever a classical version has already been used for the
-% same dotted line.\par\nobreak
-%
-% \bigskip
-% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
-% \begin{bNiceMatrix}
-% 0 & \Cdots & ~emphase#\Cdots*@ & 0 \\
-% \Vdots & & & \Vdots \\
-% ~emphase#\Vdots*@ & & & ~emphase#\Vdots*@ \\
-% 0 & \Cdots & ~emphase#\Cdots*@ & 0
-% \end{bNiceMatrix}
-% \end{BVerbatim}
-% $\begin{bNiceMatrix}
-% 0 & \Cdots & & 0 \\
-% \Vdots & & & \\
-% & & & \Vdots \\
-% 0 & & \Cdots & 0
-% \end{bNiceMatrix}$
-%
% \bigskip
-% In fact, in this example, it would be possible to draw the same matrix without
-% starred commands with the following code:\par\nobreak
+% In fact, in this example, it would be possible to draw the same matrix more
+% easily with the following code:\par\nobreak
% \bigskip
% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
% \begin{bNiceMatrix}
@@ -353,12 +329,12 @@ c & c & b & a & e
% 0 & & \Cdots & 0
% \end{bNiceMatrix}$
%
-% \bigskip
+% \bigskip e
% There are also other means to change the size of the matrix. Someone might
% want to use the optional argument of the command~|\\| for the vertical
% dimension and a command~|\hspace*| in a cell for the horizontal
-% dimension.\footnote{Nevertheless, the best way to fix the width of a column is
-% to use the environment |{NiceArray}| (or one of its variants) with a column of
+% dimension.\footnote{It's also possible to fix the width of a column
+% by using the environment |{NiceArray}| (or one of its variants) with a column of
% type~|w| or~|W|: see p.~\pageref{width}}
%
% However, a command~|\hspace*| might interfer with the construction of the
@@ -430,25 +406,25 @@ c & c & b & a & e
%
% \bigskip
% By default, with \pkg{nicematrix}, if we replace |{pmatrix}| by
-% |{pNiceMatrix}| and |\vdots| by |\Vdots| (or |\Vdots*| for efficiency), the
-% geometry of the matrix is not changed.\par\nobreak
+% |{pNiceMatrix}| and |\vdots| by |\Vdots|, the geometry of the matrix is not
+% changed.\par\nobreak
% \medskip
% \begin{BVerbatim}[baseline=c,boxwidth=8cm]
% $C = \begin{pNiceMatrix}
% a_0 & b \\
% a_1 & \Vdots \\
-% a_2 & \Vdots* \\
-% a_3 & \Vdots* \\
-% a_4 & \Vdots* \\
+% a_2 & \Vdots \\
+% a_3 & \Vdots \\
+% a_4 & \Vdots \\
% a_5 & b
% \end{pNiceMatrix}$
% \end{BVerbatim}
% $C = \begin{pNiceMatrix}
% a_0 & b \\
% a_1 & \Vdots \\
-% a_2 & \Vdots* \\
-% a_3 & \Vdots* \\
-% a_4 & \Vdots* \\
+% a_2 & \Vdots \\
+% a_3 & \Vdots \\
+% a_4 & \Vdots \\
% a_5 & b
% \end{pNiceMatrix}$
%
@@ -706,7 +682,8 @@ c & c & b & a & e
% ``large nodes'' of the first column and last column. In the following example,
% we have used the options |left-margin| and |right-margin|.\footnote{The
% options |left-margin| and |right-margin| take dimensions as values but, if no
-% value is given, the default value is used, which is |\arraycolsep|. There is
+% value is given, the default value is used, which is |\arraycolsep| (by
+% default: 5~pt). There is
% also an option |margin| to fix both |left-margin| and |right-margin| to the
% same value.}
% \[\begin{pNiceMatrix}[
@@ -966,7 +943,9 @@ c & c & b & a & e
% rows.\footnote{The latter is not true when the extension \pkg{arydshln} is
% loaded besides \pkg{nicematrix}. In fact, \pkg{nicematrix} and \pkg{arydhsln}
% are not totally compatible because \pkg{arydshln} redefines many internals of
-% \pkg{array}.}
+% \pkg{array}. On another note, if one really wants a vertical rule running in
+% the first and in the last row, he should use |!{\vline}| instead of \verb+|+
+% in the preamble of the array.}
% \item The ``first row'' of an environment |{pNiceArray}| has the number $0$, and not
% $1$. Idem for the ``first column''. This number is used for the names of the Tikz
% nodes (the names of these nodes are used, for example, by the command |\line|
@@ -1225,15 +1204,86 @@ c & c & b & a & e
% \end{pNiceMatrix}$
% \end{NiceMatrixBlock}
%
+% \section{Block matrices}
+%
+% In the environments of \pkg{nicematrix}, it's possible to use the command
+% |\Block| in order to place an element in the center of a rectangle of merged
+% cells of the array.
+%
+% The command |\Block| must be used in the upper leftmost cell of the array with
+% two arguments. The first argument is the size of the block with the syntax
+% $i$\verb|-|$j$ where $i$ is the number of rows of the block and $j$ its number
+% of columns. The second argument is the content of the block (composed in math mode).
+%
+%
+% \medskip
+% \begin{BVerbatim}[baseline=c,boxwidth=10.6cm]
+% \arrayrulecolor{cyan}
+% $\begin{bNiceArray}{CCC|C}[margin]
+% ~emphase#\Block{3-3}{A}@ & & & 0 \\
+% & \hspace*{1cm} & & \Vdots \\
+% & & & 0 \\
+% \hline
+% 0 & \Cdots& 0 & 0
+% \end{bNiceArray}$
+% \arrayrulecolor{black}
+% \end{BVerbatim}
+% \begin{scope}
+% \arrayrulecolor{cyan}
+% $\begin{bNiceArray}{CCC|C}[margin]
+% \Block{3-3}{A} & & & 0 \\
+% & \hspace*{1cm} & & \Vdots \\
+% & & & 0 \\
+% \hline
+% 0 & \Cdots& 0 & 0
+% \end{bNiceArray}$
+% \arrayrulecolor{black}
+% \end{scope}
+%
+% \bigskip
+% One may wish raise the size of the ``$A$'' placed in the block of the previous
+% example. Since this element is composed in math mode, it's not possible to use
+% directly a command like |\large|, |\Large| and |\LARGE|. That's why the command
+% |\Block| provides an option beetween angle brackets to specificy some TeX code
+% which will be inserted before the beginning of the math mode.
+%
+% \medskip
+% \begin{BVerbatim}[baseline=c,boxwidth=10.6cm]
+% \arrayrulecolor{cyan}
+% $\begin{bNiceArray}{CCC|C}[margin]
+% \Block{3-3}~emphase#<\Large>@{A} & & & 0 \\
+% & \hspace*{1cm} & & \Vdots \\
+% & & & 0 \\
+% \hline
+% 0 & \Cdots& 0 & 0
+% \end{bNiceArray}$
+% \arrayrulecolor{black}
+% \end{BVerbatim}
+% \begin{scope}
+% \arrayrulecolor{cyan}
+% $\begin{bNiceArray}{CCC|C}[margin]
+% \Block{3-3}<\Large>{A} & & & 0 \\
+% & \hspace*{1cm} & & \Vdots \\
+% & & & 0 \\
+% \hline
+% 0 & \Cdots& 0 & 0
+% \end{bNiceArray}$
+% \arrayrulecolor{black}
+% \end{scope}
+%
+% \medskip
+% For technical reasons, you can't write |\Block{|$i$|-|$j$|}{<}|. But you can
+% write |\Block{|$i$|-|$j$|}<>{<}| with the expected result.
%
%
% \section{The option hlines}
%
% You can add horizontal rules between rows in the environments of
% \pkg{nicematrix} with the usual command |\hline|. But, by convenience, the
-% extension \pkg{nicematrix} provides the option |hlines|. With this option, all
-% the horizontal rules will be drawn (excepted, of course the rule before the
-% potential ``first row'' and the rule after the potential ``last row'').
+% extension \pkg{nicematrix} also provides the option |hlines|. With this
+% option, all the horizontal rules will be drawn (excepted, of course, the rule
+% before the potential ``first row'' and the rule after the potential ``last
+% row'').
%
% \medskip
% \begin{BVerbatim}[baseline=c,boxwidth=10.6cm]
@@ -1252,8 +1302,8 @@ c & c & b & a & e
% If the package \pkg{siunitx} is loaded (before or after \pkg{nicematrix}),
% it's possible to use the |S| column type of \pkg{siunitx} in the environments
% of \pkg{nicematrix}. The implementation doesn't use explicitly any private
-% macro of \pkg{siunitx}. The |d| columns of \pkg{dcolumn} are not supported by
-% \pkg{nicematrix}.
+% macro of \pkg{siunitx}. The |d| columns of the package \pkg{dcolumn} are not
+% supported by \pkg{nicematrix}.
%
%
% \medskip
@@ -1277,6 +1327,44 @@ c & c & b & a & e
%
% \section{Technical remarks}
%
+% \subsection{Intersections of dotted lines}
+%
+% Since the version 3.1 of \pkg{nicematrix}, the dotted lines created by
+% |\Cdots|, |\Ldots|, |\Vdots|, etc. can't intersect.\footnote{Of the contrary,
+% dotted lines created by |\hdottedline|, the letter ``|:|'' in the preamble
+% of the array and the command |\line| in the |code-after| can have
+% intersections with other dotted lines.}
+%
+% That means that a dotted line created by one these commands automatically
+% stops when it arrives on a dotted line already drawn. Therefore, the order in
+% which dotted lines are drawn is important. Here's that order (by design) :
+% |\Hdotsfor|, |\Vdots|, |\Ddots|, |\Iddots|, |\Cdots| and |\Ldots|.
+%
+% With this structure, it's possible to draw the following matrix.
+%
+% \medskip
+% \begin{BVerbatim}[baseline = c, boxwidth = 10.5cm]
+% $\begin{pNiceMatrix}[nullify-dots]
+% 1 & 2 & 3 & \Cdots & n \\
+% 1 & 2 & 3 & \Cdots & n \\
+% \Vdots & \Cdots & & \Hspace*{15mm} & \Vdots \\
+% & \Cdots & & & \\
+% & \Cdots & & & \\
+% & \Cdots & & & \\
+% \end{pNiceMatrix}$
+% \end{BVerbatim}
+% % $\begin{pNiceMatrix}[nullify-dots]
+% 1 & 2 & 3 & \Cdots & n \\
+% 1 & 2 & 3 & \Cdots & n \\
+% \Vdots & \Cdots & & \Hspace*{15mm} & \Vdots \\
+% & \Cdots & & & \\
+% & \Cdots & & & \\
+% & \Cdots & & & \\
+% \end{pNiceMatrix}$
+%
+%
+%
+%
% \subsection{Diagonal lines}
%
% By default, all the diagonal lines\footnote{We speak of the lines created by
@@ -1377,8 +1465,8 @@ c & c & b & a & e
%
% \medskip
% \item A cell which contains a command |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots|
-% or |\Iddots| and their starred versions is empty. We recall that these
-% commands should be used alone in a cell.
+% or |\Iddots| is empty. We recall that these commands should be used alone in a
+% cell.
%
% \medskip
% \item A cell with a command |\Hspace| (or |\Hspace*|) is empty. This command
@@ -1662,9 +1750,11 @@ c & c & b & a & e
% \end{scope}
%
% \vspace{2cm}
-% An example for a linear system:\par\nobreak
+% An example for a linear system (the vertical rule has been drawn in cyan with
+% the tools of \pkg{colortbl}):\par\nobreak
%
% \begin{Verbatim}
+% \arrayrulecolor{cyan}
% $\begin{pNiceArray}{*6C|C}[nullify-dots,last-col,code-for-last-col={\scriptstyle}]
% 1 & 1 & 1 &\Cdots & & 1 & 0 & \\
% 0 & 1 & 0 &\Cdots & & 0 & & L_2 \gets L_2-L_1 \\
@@ -1673,8 +1763,10 @@ c & c & b & a & e
% \Vdots & & &\Ddots & & 0 & \\
% 0 & & &\Cdots & 0 & 1 & 0 & L_n \gets L_n-L_1
% \end{pNiceArray}$
+% \arrayrulecolor{black}
% \end{Verbatim}
%
+% \arrayrulecolor{cyan}
% \[\begin{pNiceArray}{*6C|C}[nullify-dots,last-col,code-for-last-col={\scriptstyle}]
% 1 & 1 & 1 &\Cdots & & 1 & 0 & \\
% 0 & 1 & 0 &\Cdots & & 0 & & L_2 \gets L_2-L_1 \\
@@ -1683,6 +1775,7 @@ c & c & b & a & e
% \Vdots & & &\Ddots & & 0 & \\
% 0 & & &\Cdots & 0 & 1 & 0 & L_n \gets L_n-L_1
% \end{pNiceArray}\]
+% \arrayrulecolor{black}
%
%
% \subsection{Width of the columns}
@@ -2122,41 +2215,6 @@ c & c & b & a & e
% \draw [color = gray] (A-3-3) to [bend left] (B-3-3) ;
% \end{tikzpicture}
%
-%
-% \subsection{Block matrices}
-%
-% \medskip
-% In the following example, we use the ``large nodes'' to construct a block matrix (the dashed lines have been
-% drawn with \pkg{arydshln}).
-% \begin{Verbatim}
-% \NiceMatrixOptions{letter-for-dotted-lines = V}
-% \begin{pNiceArray}{CC:CC}[
-% create-extra-nodes,
-% ~emphase#code-after = { \tikz \node [fit = (1-1-large) (2-2-large), inner sep = 0 pt]@
-% ~emphase# {$0_{22}$} ; }@ ]
-% & & a_{13} & a_{14} \\
-% & & a_{23} & a_{24} \\
-% \hdashline
-% a_{31} & a_{32} & a_{33} & a_{34} \\
-% a_{41} & a_{42} & a_{34} & a_{44}
-% \end{pNiceArray}
-% \end{Verbatim}
-%
-%
-% \begin{scope}
-% \NiceMatrixOptions{letter-for-dotted-lines = V}
-% \[D = \begin{pNiceArray}{CC:CC}[
-% create-extra-nodes,
-% code-after = { \tikz \node [fit = (1-1-large) (2-2-large), inner sep = 0 pt]
-% {$0_{22}$} ; } ]
-% & & a_{13} & a_{14} \\
-% & & a_{23} & a_{24} \\
-% \hdashline
-% a_{31} & a_{32} & a_{33} & a_{34} \\
-% a_{41} & a_{42} & a_{34} & a_{44}
-% \end{pNiceArray}\]
-% \end{scope}
-%
%
%
% \section{Implementation}
@@ -2237,6 +2295,7 @@ c & c & b & a & e
% \begin{macrocode}
\cs_new_protected:Npn \@@_error:n { \msg_error:nn { nicematrix } }
\cs_new_protected:Npn \@@_error:nn { \msg_error:nn { nicematrix } }
+\cs_new_protected:Npn \@@_error:nnn { \msg_error:nnn { nicematrix } }
\cs_new_protected:Npn \@@_fatal:n { \msg_fatal:nn { nicematrix } }
\cs_new_protected:Npn \@@_fatal:nn { \msg_fatal:nn { nicematrix } }
\cs_new_protected:Npn \@@_msg_new:nn { \msg_new:nnn { nicematrix } }
@@ -2264,10 +2323,6 @@ c & c & b & a & e
{ }
% \end{macrocode}
%
-% \begin{macrocode}
-\@@_msg_new:nn { Draft~mode }
- { The~compilation~is~in~draft~mode:~the~dotted~lines~won't~be~drawn. }
-% \end{macrocode}
%
% \begin{macrocode}
\bool_if:NT \c_@@_draft_bool
@@ -2355,34 +2410,42 @@ c & c & b & a & e
% \end{macrocode}
%
% \bigskip
-% \begin{macrocode}
-\@@_msg_new:nn { Yet~in~env }
- {
- Environments~\{NiceArray\}~(or~\{NiceMatrix\},~etc.)~can't~be~
- nested.\\
- This~error~is~fatal.
- }
-% \end{macrocode}
+% Consider the following code:
+% \begin{Verbatim}
+% $\begin{pNiceMatrix}
+% a & b & c \\
+% d & e & \Vdots \\
+% f & \Cdots \\
+% g & h & i \\
+% \end{pNiceMatrix}$
+% \end{Verbatim}
%
-% \bigskip
+% First, the dotted line created by the |\Vdots| will be drawn. The implicit
+% cell in position 2-3 will be considered as ``dotted''. Then, we will have to
+% draw the dotted line specified by the |\Cdots|; the final extremity of that
+% line will be exactly in position 2-3 and, for that new second line, it should
+% be considered as a \emph{closed} extremity (since it is dotted). However, we
+% don't have the (normal) Tikz node of that node (since it's an implicit cell):
+% we can't draw such a line. That's why that dotted line will be said
+% \emph{impossible} and an error will be raised.\footnote{Of course, the user
+% should solve the problem by adding the lacking ampersands.}
% \begin{macrocode}
-\@@_msg_new:nn { Outside~math~mode }
- {
- The~environment~\{\@currenvir\}~can~be~used~only~in~math~mode~
- (and~not~in~\token_to_str:N \vcenter).\\
- This~error~is~fatal.
- }
+\bool_new:N \l_@@_impossible_line_bool
% \end{macrocode}
-%
+%
+%
% \bigskip
-% We have to known whether if \pkg{colortbl} is loaded for the redefinition of
-% |\everycr|.
+% We have to know whether \pkg{colortbl} is loaded for the redefinition of
+% |\everycr| and for |\vline|.
% \begin{macrocode}
\bool_new:N \c_@@_colortbl_loaded_bool
\AtBeginDocument
{
\@ifpackageloaded { colortbl }
- { \bool_set_true:N \c_@@_colortbl_loaded_bool }
+ {
+ \bool_set_true:N \c_@@_colortbl_loaded_bool
+ \cs_set_protected:Npn \@@_vline_i: { { \CT@arc@ \vline } }
+ }
{ }
}
% \end{macrocode}
@@ -2600,18 +2663,6 @@ c & c & b & a & e
% \bigskip
% \subsection{The options}
%
-% \begin{macrocode}
-\@@_msg_new:nn { Option~Transparent~suppressed }
- {
- The~option~'Transparent'~has~been~renamed~'transparent'.\\
- However,~you~can~go~on~for~this~time.
- }
-\@@_msg_new:nn { Option~RenewMatrix~suppressed }
- {
- The~option~'RenewMatrix'~has~been~renamed~'renew-matrix'.\\
- However,~you~can~go~on~for~this~time.
- }
-% \end{macrocode}
%
%
% The token list |\l_@@_pos_env_str| will contain one of the three values |t|,
@@ -2901,7 +2952,7 @@ c & c & b & a & e
letter-for-dotted-lines .code:n =
{
\int_compare:nTF { \tl_count:n { #1 } = \c_one_int }
- { \tl_set:Nx \l_@@_letter_for_dotted_lines_str { #1 } }
+ { \str_set:Nx \l_@@_letter_for_dotted_lines_str { #1 } }
{ \@@_error:n { Bad~value~for~letter~for~dotted~lines } }
} ,
letter-for-dotted-lines .value_required:n = true ,
@@ -2914,53 +2965,6 @@ c & c & b & a & e
% \end{macrocode}
%
%
-% \bigskip
-% \begin{macrocode}
-\@@_msg_new:nn { Bad~value~for~letter~for~dotted~lines }
- {
- The~value~of~key~'\tl_use:N\l_keys_key_tl'~must~be~of~length~1.\\
- If~you~go~on,~it~will~be~ignored.
- }
-% \end{macrocode}
-%
-%
-% \bigskip
-% \begin{macrocode}
-\@@_msg_new:nnn { Unknown~key~for~NiceMatrixOptions }
- {
- The~key~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~command~
- \token_to_str:N \NiceMatrixOptions. \\
- If~you~go~on,~it~will~be~ignored. \\
- For~a~list~of~the~available~keys,~type~H~<return>.
- }
- {
- The~available~keys~are~(in~alphabetic~order):~
- allow-duplicate-names,~
- code-for-first-col,~
- code-for-first-row,~
- code-for-last-col,~
- code-for-last-row,~
- exterior-arraycolsep,~
- hlines,~
- left-margin,~
- letter-for-dotted-lines,~
- nullify-dots,~
- parallelize-diags,~
- renew-dots,~
- renew-matrix,~
- right-margin,~
- and~transparent
- }
-% \end{macrocode}
-%
-% \begin{macrocode}
-\@@_msg_new:nn { Option~auto~for~columns-width }
- {
- You~can't~give~the~value~'auto'~to~the~option~'columns-width'~here.~
- If~you~go~on,~the~option~will~be~ignored.
- }
-% \end{macrocode}
-%
% \bigskip
% |\NiceMatrixOptions| is the command of the \pkg{nicematrix} package to fix
% options at the document level. The scope of these specifications is the
@@ -2980,48 +2984,6 @@ c & c & b & a & e
{ unknown .code:n = \@@_error:n { Unknown~option~for~NiceMatrix } }
% \end{macrocode}
%
-% \begin{macrocode}
-\@@_msg_new:nnn { Unknown~option~for~NiceMatrix }
- {
- The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~environment~
- \{NiceMatrix\}~and~its~variants. \\
- If~you~go~on,~it~will~be~ignored. \\
- For~a~list~of~the~available~options,~type~H~<return>.
- }
- {
- The~available~options~are~(in~alphabetic~order):~
- code-after,~
- columns-width,~
- create-extra-nodes,~
- extra-left-margin,~
- extra-right-margin,~
- hlines,~
- left-margin,~
- name,~
- nullify-dots,~
- parallelize-diags,~
- renew-dots~
- and~right-margin.
- }
-% \end{macrocode}
-%
-% \bigskip
-% \begin{macrocode}
-\@@_msg_new:nnn { Duplicate~name }
- {
- The~name~'\l_keys_value_tl'~is~already~used~and~you~shouldn't~use~
- the~same~environment~name~twice.~You~can~go~on,~but,~
- maybe,~you~will~have~incorrect~results~especially~
- if~you~use~'columns-width=auto'. \\
- For~a~list~of~the~names~already~used,~type~H~<return>. \\
- If~you~don't~want~to~see~this~message~again,~use~the~option~
- 'allow-duplicate-names'.
- }
- {
- The~names~already~defined~in~this~document~are:~
- \seq_use:Nnnn \g_@@_names_seq { ,~ } { ,~ } { ~and~ }.
- }
-% \end{macrocode}
%
% \bigskip
%
@@ -3050,37 +3012,6 @@ c & c & b & a & e
}
% \end{macrocode}
%
-% \begin{macrocode}
-\@@_msg_new:nnn { Unknown~option~for~NiceArray }
- {
- The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~environment~
- \{NiceArray\}. \\
- If~you~go~on,~it~will~be~ignored. \\
- For~a~list~of~the~available~options,~type~H~<return>.
- }
- {
- The~available~options~are~(in~alphabetic~order):~
- b,~
- c,~
- code-after,~
- code-for-first-col,~
- code-for-first-row,~
- code-for-last-col,~
- code-for-last-row,~
- columns-width,~
- create-extra-nodes,~
- extra-left-margin,~
- extra-right-margin,~
- hlines,~
- left-margin,~
- name,~
- nullify-dots,~
- parallelize-diags,~
- renew-dots,~
- right-margin,~
- and~t.
- }
-% \end{macrocode}
%
%
% \begin{macrocode}
@@ -3096,39 +3027,6 @@ c & c & b & a & e
% \end{macrocode}
%
%
-% \begin{macrocode}
-\@@_msg_new:nnn { Unknown~option~for~pNiceArray }
- {
- The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~environment~
- \{\@currenvir\}. \\
- If~you~go~on,~it~will~be~ignored. \\
- For~a~list~of~the~available~options,~type~H~<return>.
- }
- {
- The~available~options~are~(in~alphabetic~order):~
- code-after,~
- code-for-first-col,~
- code-for-first-row,~
- code-for-last-col,~
- code-for-last-row,~
- columns-width,~
- create-extra-nodes,~
- extra-left-margin,~
- extra-right-margin,~
- first-col,~
- first-row,~
- last-col,~
- last-row,~
- hlines,~
- left-margin,~
- name,~
- nullify-dots,~
- parallelize-diags,~
- renew-dots,~
- and~right-margin.
- }
-% \end{macrocode}
-%
% \subsection{Code common to \{NiceArrayWithDelims\} and \{NiceMatrix\}}
%
% The pseudo-environment |\@@_Cell:|--|\@@_end_Cell:| will be used to format the
@@ -3345,8 +3243,9 @@ c & c & b & a & e
% \interitem
% The argument of the following command |\@@_instruction_of_type:n| defined
% below is the type of the instruction (|Cdots|, |Vdots|, |Ddots|, etc.). This
-% command writes in |\g_@@_lines_to_draw_tl| the instruction that will really
-% draw the line after the construction of the matrix.
+% command writes in the correspondint |\g_@@_|\textsl{type}|_lines_tl| the
+% instruction that will really draw the line after the construction of the
+% matrix.
%
% \medskip
% For example, for the following matrix,
@@ -3356,22 +3255,22 @@ c & c & b & a & e
% \begin{pNiceMatrix}
% 1 & 2 & 3 & 4 \\
% 5 & \Cdots & & 6 \\
-% 7 & \Hdotsfor{2} \\
+% 7 & \Cdots \\
% \end{pNiceMatrix}
% \end{BVerbatim}
% $\begin{pNiceMatrix}
% 1 & 2 & 3 & 4 \\
% 5 & \Cdots & & 6 \\
-% 7 & \Hdotsfor{2} \\
+% 7 & \Cdots \\
% \end{pNiceMatrix}$
%
-% the content of |\g_@@_lines_to_draw_tl| will be:
+% the content of |\g_@@_Cdots_lines_tl| will be:
%
% \begin{scope}
% \color{gray}
% \verb|\@@_draw_Cdots:nn {2}{2}|
%
-% \verb|\@@_draw_Hdotsfor:nnn {3}{2}{2}|
+% \verb|\@@_draw_Cdots:nn {3}{2}|
% \end{scope}
%
%
@@ -3383,7 +3282,13 @@ c & c & b & a & e
{
\cs_new_protected:Npn \@@_instruction_of_type:n #1
{
- \tl_gput_right:Nx \g_@@_lines_to_draw_tl
+% \end{macrocode}
+% It's important to use a |\tl_gput_right:cx| and not a |\tl_gput_left:cx|
+% because we want the |\Ddots| lines to be drawn in the order of appearance
+% in the array (for parallelisation).
+% \begin{macrocode}
+ \tl_gput_right:cx
+ { g_@@_ #1 _ lines _ tl }
{
\use:c { @@ _ draw _ #1 : nn }
{ \int_use:N \g_@@_row_int }
@@ -3511,7 +3416,7 @@ c & c & b & a & e
\int_gset_eq:NN \g_@@_first_col_int \l_@@_first_col_int
\bool_gset_eq:NN \g_@@_NiceArray_bool \l_@@_NiceArray_bool
\bool_gset_eq:NN \g_@@_last_row_without_value_bool
- \l_@@_last_row_without_value_bool
+ \l_@@_last_row_without_value_bool
% \end{macrocode}
% The environment |{array}| uses internally the command |\ialign| and, in
% particular, this command |\ialign| sets |\everycr| to |{}|. However, we want
@@ -3524,46 +3429,46 @@ c & c & b & a & e
% environments that utilize |\ialign| internally (e.g.: |{substack}|)}
% \begin{macrocode}
\cs_set:Npn \ialign
- {
- \bool_if:NTF \c_@@_colortbl_loaded_bool
- {
- \CT@everycr
- {
- \noalign { \global\let\CT@row@color\relax }
- \@@_everycr:
- }
+ {
+ \bool_if:NTF \c_@@_colortbl_loaded_bool
+ {
+ \CT@everycr
+ {
+ \noalign { \cs_gset_eq:NN \CT@row@color \prg_do_nothing: }
+ \@@_everycr:
+ }
+ }
+ { \everycr { \@@_everycr: } }
+ \tabskip = \c_zero_skip
+ \cs_set:Npn \ialign
+ {
+ \everycr { }
+ \tabskip = \c_zero_skip
+ \halign
}
- { \everycr { \@@_everycr: } }
- \tabskip = \c_zero_skip
- \cs_set:Npn \ialign
- {
- \everycr { }
- \tabskip = \c_zero_skip
- \halign
- }
- \halign
- }
+ \halign
+ }
% \end{macrocode}
%
% We define the new column types |L|, |C| and |R| that must be used instead of
% |l|, |c| and |r| in the preamble of |{NiceArray}|.
% \begin{macrocode}
\dim_compare:nNnTF \l_@@_columns_width_dim = \c_zero_dim
- {
- \newcolumntype L { > \@@_Cell: l < \@@_end_Cell: }
- \newcolumntype C { > \@@_Cell: c < \@@_end_Cell: }
- \newcolumntype R { > \@@_Cell: r < \@@_end_Cell: }
- }
+ {
+ \newcolumntype L { > \@@_Cell: l < \@@_end_Cell: }
+ \newcolumntype C { > \@@_Cell: c < \@@_end_Cell: }
+ \newcolumntype R { > \@@_Cell: r < \@@_end_Cell: }
+ }
% \end{macrocode}
% If there is an option that specify that all the columns must have the same
% width, the column types~|L|, |C| and~|R| are in fact defined upon the column
% type~|w| of \pkg{array} which is, in fact, redefined below.
% \begin{macrocode}
- {
- \newcolumntype L { w l { \dim_use:N \l_@@_columns_width_dim } }
- \newcolumntype C { w c { \dim_use:N \l_@@_columns_width_dim } }
- \newcolumntype R { w r { \dim_use:N \l_@@_columns_width_dim } }
- }
+ {
+ \newcolumntype L { w l { \dim_use:N \l_@@_columns_width_dim } }
+ \newcolumntype C { w c { \dim_use:N \l_@@_columns_width_dim } }
+ \newcolumntype R { w r { \dim_use:N \l_@@_columns_width_dim } }
+ }
% \end{macrocode}
%
%
@@ -3577,6 +3482,7 @@ c & c & b & a & e
\cs_set_eq:NN \Hspace \@@_Hspace:
\cs_set_eq:NN \Hdotsfor \@@_Hdotsfor:
\cs_set_eq:NN \multicolumn \@@_multicolumn:nnn
+ \cs_set_eq:NN \Block \@@_Block:
\bool_if:NT \l_@@_renew_dots_bool
{
\cs_set_eq:NN \ldots \@@_Ldots
@@ -3590,14 +3496,6 @@ c & c & b & a & e
% \end{macrocode}
%
%
-% The sequence |\g_@@_empty_cells_seq| will contain a list of ``empty'' cells
-% (not all the empty cells of the matrix). If we want to indicate that the cell
-% in row~$i$ and column~$j$ must be considered as empty, the token list
-% ``|i-j|'' will be put in this sequence.
-% \begin{macrocode}
- \seq_gclear_new:N \g_@@_empty_cells_seq
-% \end{macrocode}
-%
% The sequence |\g_@@_multicolumn_cells_seq| will contain the list of the cells
% of the array where a command |\multicolumn{|$n$|}{...}{...}| with $n>1$ is
% issued. In |\g_@@_multicolumn_sizes_seq|, the ``sizes'' (that is to say the
@@ -3658,9 +3556,14 @@ c & c & b & a & e
% |:|. However, this letter is used by some extensions, for example
% \pkg{arydshln}. That's why it's possible to change the letter used by
% \pkg{nicematrix} with the option |letter-for-dotted-lines| which changes the
-% value of |\l_@@_letter_for_dotted_lines_str|.
-% \begin{macrocode}
- \exp_args:Nx \newcolumntype \l_@@_letter_for_dotted_lines_str
+% value of |\l_@@_letter_for_dotted_lines_str|. We rescan this string (which is
+% always of length~1) in particular for the case where |pdflatex| is used with
+% \pkg{french-babel} (the colon is activated by \pkg{french-babel} at the
+% beginning of the document).
+% \begin{macrocode}
+ \tl_set_rescan:Nno
+ \l_@@_letter_for_dotted_lines_str { } \l_@@_letter_for_dotted_lines_str
+ \exp_args:NV \newcolumntype \l_@@_letter_for_dotted_lines_str
{
!
{
@@ -3704,11 +3607,22 @@ c & c & b & a & e
\bool_if:NT \c_@@_siunitx_loaded_bool \@@_renew_NC@rewrite@S:
\int_gset:Nn \g_@@_last_vdotted_col_int { -1 }
\bool_gset_false:N \g_@@_last_col_found_bool
- }
% \end{macrocode}
%
-%
-%
+% \medskip
+% During the construction of the array, the instructions |\Cdots|, |\Ldots|,
+% etc. will be written in token lists |\g_@@_Cdots_lines_tl|, etc. which will be
+% executed after the construction of the array.
+% \begin{macrocode}
+ \tl_gclear_new:N \g_@@_Cdots_lines_tl
+ \tl_gclear_new:N \g_@@_Ldots_lines_tl
+ \tl_gclear_new:N \g_@@_Vdots_lines_tl
+ \tl_gclear_new:N \g_@@_Ddots_lines_tl
+ \tl_gclear_new:N \g_@@_Iddots_lines_tl
+ \tl_gclear_new:N \g_@@_Hdotsfor_lines_tl
+ }
+% \end{macrocode}
+%
% \bigskip
% \subsection{The environment \{NiceArrayWithDelims\}}
%
@@ -3734,7 +3648,6 @@ c & c & b & a & e
% why we use this technique in |{NiceArrayWithDelims}| and in |{NiceMatrix}|.
% \begin{macrocode}
\group_insert_after:N \@@_after_array:
- \tl_gclear_new:N \g_@@_lines_to_draw_tl
% \end{macrocode}
%
% We increment the counter |\g_@@_env_int| which counts the environments
@@ -3815,7 +3728,7 @@ c & c & b & a & e
\hbox_set:Nn \l_tmpa_box
{
\c_math_toggle_token
- \left #1 \vcenter to 1 cm { } \right.
+ \left #1 \vcenter to 3 cm { } \right.
\c_math_toggle_token
}
@@ -3824,7 +3737,7 @@ c & c & b & a & e
{
\dim_set_eq:NN \nulldelimiterspace \c_zero_dim
\c_math_toggle_token
- \left. \vcenter to 1 cm { } \right #2
+ \left. \vcenter to 3 cm { } \right #2
\c_math_toggle_token
}
\dim_gset:Nn \g_@@_right_delim_dim { \box_wd:N \l_tmpa_box }
@@ -3889,6 +3802,24 @@ c & c & b & a & e
\skip_horizontal:n \g_@@_extra_right_margin_dim
\hbox_set_end:
% \end{macrocode}
+%
+% \bigskip
+%
+% \begin{macrocode}
+ \int_compare:nNnT \g_@@_last_row_int > { -2 }
+ {
+ \bool_if:NF \g_@@_last_row_without_value_bool
+ {
+ \int_compare:nNnF \g_@@_last_row_int = \g_@@_row_int
+ {
+ \@@_error:n { Wrong~last~row }
+ \int_gset_eq:NN \g_@@_last_row_int \g_@@_row_int
+ }
+ }
+ }
+% \end{macrocode}
+%
+%
% Now, we compute |\l_tmpa_dim| which is the vertical dimension of the ``first
% row'' above the array (when the key |first-row| is used).
% \begin{macrocode}
@@ -4119,7 +4050,7 @@ c & c & b & a & e
{
% \end{macrocode}
% With the flag |\g_@@_last_col_found_bool|, we will know that the ``last
-% column'' i s really used.
+% column'' is really used.
% \begin{macrocode}
\bool_gset_true:N \g_@@_last_col_found_bool
\int_gincr:N \g_@@_col_int
@@ -4300,7 +4231,6 @@ c & c & b & a & e
% same as in |{array}| (for the option |renew-matrix|).
% \begin{macrocode}
\group_insert_after:N \@@_after_array:
- \tl_gclear_new:N \g_@@_lines_to_draw_tl
\int_gincr:N \g_@@_env_int
\bool_if:NF \l_@@_block_auto_columns_width_bool
{ \dim_gzero_new:N \g_@@_max_cell_width_dim }
@@ -4425,46 +4355,93 @@ c & c & b & a & e
% considered cell.
% \begin{macrocode}
\prg_set_conditional:Npnn \@@_if_not_empty_cell:nn #1 #2 { T , TF }
-% \end{macrocode}
-% If the cell is an implicit cell (that is after the symbol |\\| of end of row),
-% the cell must, of course, be considered as empty. It's easy to check whether we
-% are in this situation considering the correspondant Tikz node.
-% \begin{macrocode}
{
- \cs_if_free:cTF
- { pgf@sh@ns@nm -\int_use:N \g_@@_env_int - \int_use:N #1 - \int_use:N #2 }
- \prg_return_false:
% \end{macrocode}
-% We manage a list of ``empty cells'' called |\g_@@_empty_cells_seq|. In fact,
-% this list is not a list of all the empty cells of the array but only those
-% explicitly declared empty for some reason. It's easy to check if the current
-% cell is in this list.
+% First, we want to test whether the cell is in the virtual sequence of
+% ``non-empty'' cells. There are several important remarks:
+% \begin{itemize}
+% \item we don't use a |expl3| sequence for efficiency ;
+% \item the ``non-empty'' cells in this sequence are not, in fact, all the
+% non-empty cells of the array: on the contrary they are only cells declared
+% as non-empty for a special reason (as of now, there are only cells which are
+% on a dotted line which is already drawn or which will be drawn ``just after'') ;
+% \item the flag |\l_tmpa_bool| will be raised when the cell is actually on
+% this virtual sequence.
+% \end{itemize}
% \begin{macrocode}
+ \bool_set_false:N \l_tmpa_bool
+ \cs_if_exist:cTF
+ { @@ _ dotted _ \int_use:N #1 - \int_use:N #2 }
+ \prg_return_true:
{
- \seq_if_in:NxTF \g_@@_empty_cells_seq { \int_use:N #1 - \int_use:N #2 }
- \prg_return_false:
+% \end{macrocode}
+% We know that the cell is not in the virtual sequence of the ``non-empty''
+% cells. Now, we test wether the cell is a ``virtual cell'', that is to say a
+% cell after the |\\| of the line of the array. It's easy to known whether a
+% cell is vitual: the cell is virtual if, and only if, the corresponding Tikz
+% node doesn't exist.
+% \begin{macrocode}
+ \cs_if_free:cTF
+ {
+ pgf@sh@ns@nm -
+ \int_use:N \g_@@_env_int -
+ \int_use:N #1 -
+ \int_use:N #2
+ }
+ { \prg_return_false: }
+ {
+% \end{macrocode}
+% Now, we want to test whether the cell is in the virtual sequence of
+% ``empty'' cells. There are several important remarks:
+% \begin{itemize}
+% \item we don't use a |expl3| sequence for efficiency ;
+% \item the ``empty'' cells in this sequence are not, in fact, all the
+% non-empty cells of the array: on the contrary they are only cells declared
+% as non-empty for a special reason ;
+% \item the flag |\l_tmpa_bool| will be raised when the cell is actually on
+% this virtual sequence.
+% \end{itemize}
+% \begin{macrocode}
+ \bool_set_false:N \l_tmpa_bool
+ \cs_if_exist:cT
+ { @@ _ empty _ \int_use:N #1 - \int_use:N #2 }
+ {
+ \int_compare:nNnT
+ { \use:c { @@ _ empty _ \int_use:N #1 - \int_use:N #2 } }
+ =
+ \g_@@_env_int
+ { \bool_set_true:N \l_tmpa_bool }
+ }
+ \bool_if:NTF \l_tmpa_bool
+ \prg_return_false:
% \end{macrocode}
% In the general case, we consider the width of the Tikz node corresponding to
% the cell. In order to compute this width, we have to extract the coordinate of
% the west and east anchors of the node. This extraction needs a command
% environment |{pgfpicture}| but, in fact, nothing is drawn.
% \begin{macrocode}
- {
- \begin { pgfpicture }
+ {
+ \begin { pgfpicture }
% \end{macrocode}
% We store the name of the node corresponding to the cell in |\l_tmpa_tl|.
% \begin{macrocode}
- \tl_set:Nx \l_tmpa_tl
- { nm - \int_use:N \g_@@_env_int - \int_use:N #1 - \int_use:N #2 }
- \pgfpointanchor \l_tmpa_tl { east }
- \dim_gset:Nn \g_tmpa_dim \pgf@x
- \pgfpointanchor \l_tmpa_tl { west }
- \dim_gset:Nn \g_tmpb_dim \pgf@x
- \end { pgfpicture }
- \dim_compare:nNnTF
- { \dim_abs:n { \g_tmpb_dim - \g_tmpa_dim } } < { 0.5 pt }
- \prg_return_false:
- \prg_return_true:
+ \tl_set:Nx \l_tmpa_tl
+ {
+ nm -
+ \int_use:N \g_@@_env_int -
+ \int_use:N #1 -
+ \int_use:N #2
+ }
+ \pgfpointanchor \l_tmpa_tl { east }
+ \dim_gset:Nn \g_tmpa_dim \pgf@x
+ \pgfpointanchor \l_tmpa_tl { west }
+ \dim_gset:Nn \g_tmpb_dim \pgf@x
+ \end { pgfpicture }
+ \dim_compare:nNnTF
+ { \dim_abs:n { \g_tmpb_dim - \g_tmpa_dim } } < { 0.5 pt }
+ \prg_return_false:
+ \prg_return_true:
+ }
}
}
}
@@ -4486,15 +4463,6 @@ c & c & b & a & e
}
% \end{macrocode}
%
-% \begin{macrocode}
-\@@_msg_new:nn { Zero~row }
- {
- There~is~a~problem.~Maybe~your~environment~\{\@currenvir\}~is~empty.~
- Maybe~you~have~used~l,~c~and~r~instead~of~L,~C~and~R~in~the~preamble~
- of~your~environment. \\
- If~you~go~on,~the~result~may~be~incorrect.
- }
-% \end{macrocode}
%
% \medskip
% We deactivate Tikz externalization (since we use Tikz pictures with the
@@ -4552,12 +4520,6 @@ c & c & b & a & e
}
% \end{macrocode}
%
-% The sequence |\g_@@_yet_drawn_seq| contains a list of lines which have been
-% drawn previously in the matrix. We maintain this sequence because we don't
-% want to draw two overlapping lines.
-% \begin{macrocode}
- \seq_gclear_new:N \g_@@_yet_drawn_seq
-% \end{macrocode}
%
% By default, the diagonal lines will be parallelized\footnote{It's possible to
% use the option |parallelize-diags| to disable this parallelization.}. There
@@ -4591,23 +4553,24 @@ c & c & b & a & e
% group).
% \begin{macrocode}
\bool_if:NT \g_@@_extra_nodes_bool \@@_create_extra_nodes:
+ \int_zero_new:N \l_@@_initial_i_int
+ \int_zero_new:N \l_@@_initial_j_int
+ \int_zero_new:N \l_@@_final_i_int
+ \int_zero_new:N \l_@@_final_j_int
+ \bool_set_false:N \l_@@_initial_open_bool
+ \bool_set_false:N \l_@@_final_open_bool
% \end{macrocode}
-%
+%
% \bigskip
% Now, we really draw the lines. The code to draw the lines has been constructed
-% in the token list |\g_@@_lines_to_draw_tl|.
+% in the token lists |\g_@@_Vdots_lines_tl|, etc.
% \begin{macrocode}
- \tl_if_empty:NF \g_@@_lines_to_draw_tl
- {
- \int_zero_new:N \l_@@_initial_i_int
- \int_zero_new:N \l_@@_initial_j_int
- \int_zero_new:N \l_@@_final_i_int
- \int_zero_new:N \l_@@_final_j_int
- \bool_set_false:N \l_@@_initial_open_bool
- \bool_set_false:N \l_@@_final_open_bool
- \g_@@_lines_to_draw_tl
- }
- \tl_gclear:N \g_@@_lines_to_draw_tl
+ \g_@@_Hdotsfor_lines_tl
+ \g_@@_Vdots_lines_tl
+ \g_@@_Ddots_lines_tl
+ \g_@@_Iddots_lines_tl
+ \g_@@_Cdots_lines_tl
+ \g_@@_Ldots_lines_tl
% \end{macrocode}
%
% \bigskip
@@ -4680,6 +4643,14 @@ c & c & b & a & e
% \begin{macrocode}
\cs_new_protected:Nn \@@_find_extremities_of_line:nnnn
{
+% \end{macrocode}
+% First, we declare the current cell as ``dotted'' because we forbide
+% intersections of dotted lines.
+% \begin{macrocode}
+ \cs_set:cpn { @@ _ dotted _ #1 - #2 } { }
+% \end{macrocode}
+% Initialisation of variables.
+% \begin{macrocode}
\int_set:Nn \l_@@_initial_i_int { #1 }
\int_set:Nn \l_@@_initial_j_int { #2 }
\int_set:Nn \l_@@_final_i_int { #1 }
@@ -4732,13 +4703,50 @@ c & c & b & a & e
\bool_set_true:N \l_@@_stop_loop_bool
}
% \end{macrocode}
-% If we are in the matrix, we test if the cell is empty. If it's not the case,
-% we stop the loop because we have found the correct values for
+% If we are in the matrix, we test whether the cell is empty. If it's not the
+% case, we stop the loop because we have found the correct values for
% |\l_@@_final_i_int| and |\l_@@_final_j_int|.
% \begin{macrocode}
{
- \@@_if_not_empty_cell:nnT \l_@@_final_i_int \l_@@_final_j_int
+ \@@_if_not_empty_cell:nnTF \l_@@_final_i_int \l_@@_final_j_int
{ \bool_set_true:N \l_@@_stop_loop_bool }
+% \end{macrocode}
+% If the case is empty, we declare that the cell as non-empty. Indeed, we will
+% draw a dotted line and the cell will be on that dotted line. All the cells of
+% a dotted line have to be mark as ``dotted'' because we don't want
+% intersections between dotted lines.
+% \begin{macrocode}
+ {
+ \cs_set:cpn
+ {
+ @@ _ dotted _
+ \int_use:N \l_@@_final_i_int -
+ \int_use:N \l_@@_final_j_int
+ }
+ { }
+ }
+ }
+ }
+% \end{macrocode}
+% We test wether the initial extremity of the dotted line is an implicit cell
+% already dotted (by another dotted line). In this case, we can't draw the line
+% because we have no Tikz node at the extremity of the arrow (and we can't use
+% the ``medium node'' or the ``large node'' because we should use the normal
+% node since the extremity is not open).
+% \begin{macrocode}
+ \cs_if_free:cT
+ {
+ pgf@sh@ns@nm -
+ \int_use:N \g_@@_env_int -
+ \int_use:N \l_@@_final_i_int -
+ \int_use:N \l_@@_final_j_int
+ }
+ {
+ \bool_if:NF \l_@@_final_open_bool
+ {
+ \msg_error:nnx { nicematrix } { Impossible~line }
+ { \int_use:N \l_@@_final_i_int }
+ \bool_set_true:N \l_@@_impossible_line_bool
}
}
% \end{macrocode}
@@ -4779,9 +4787,40 @@ c & c & b & a & e
\bool_set_true:N \l_@@_stop_loop_bool
}
{
- \@@_if_not_empty_cell:nnT
+ \@@_if_not_empty_cell:nnTF
\l_@@_initial_i_int \l_@@_initial_j_int
{ \bool_set_true:N \l_@@_stop_loop_bool }
+ {
+ \cs_set:cpn
+ {
+ @@ _ dotted _
+ \int_use:N \l_@@_initial_i_int -
+ \int_use:N \l_@@_initial_j_int
+ }
+ { }
+ }
+ }
+ }
+% \end{macrocode}
+% We test wether the initial extremity of the dotted line is an implicit cell
+% already dotted (by another dotted line). In this case, we can't draw the line
+% because we have no Tikz node at the extremity of the arrow (and we can't use
+% the ``medium node'' or the ``large node'' because we should use the normal
+% node since the extremity is not open).
+% \begin{macrocode}
+ \cs_if_free:cT
+ {
+ pgf@sh@ns@nm -
+ \int_use:N \g_@@_env_int -
+ \int_use:N \l_@@_initial_i_int -
+ \int_use:N \l_@@_initial_j_int
+ }
+ {
+ \bool_if:NF \l_@@_initial_open_bool
+ {
+ \msg_error:nnx { nicematrix } { Impossible~line }
+ { \int_use:N \l_@@_initial_i_int }
+ \bool_set_true:N \l_@@_impossible_line_bool
}
}
% \end{macrocode}
@@ -4791,40 +4830,12 @@ c & c & b & a & e
% ``medium node''.}. We remind that, when used once, the command
% |\@@_create_extra_nodes:| becomes no-op in the current TeX group.
% \begin{macrocode}
- \bool_if:nT { \l_@@_initial_open_bool || \l_@@_final_open_bool }
- \@@_create_extra_nodes:
- }
-% \end{macrocode}
-%
-% \interitem
-% If the dotted line to draw is in the list of the previously drawn lines
-% (|\g_@@_yet_drawn_seq|), we don't draw (so, we won't have overlapping lines in
-% the \textsc{pdf}). The token list |\l_tmpa_tl| is the $4$-list characteristic
-% of the line.
-% \begin{macrocode}
-\prg_set_conditional:Npnn \@@_if_yet_drawn: { F }
- {
- \tl_set:Nx \l_tmpa_tl
- {
- \int_use:N \l_@@_initial_i_int -
- \int_use:N \l_@@_initial_j_int -
- \int_use:N \l_@@_final_i_int -
- \int_use:N \l_@@_final_j_int
- }
- \seq_if_in:NVTF \g_@@_yet_drawn_seq \l_tmpa_tl
-% \end{macrocode}
-%
-% If the dotted line to draw is not in the list, we add it to the list
-% |\g_@@_yet_drawn_seq|.
-% \begin{macrocode}
- \prg_return_true:
- {
- \seq_gput_left:NV \g_@@_yet_drawn_seq \l_tmpa_tl
- \prg_return_false:
- }
+ \bool_if:nT \l_@@_initial_open_bool \@@_create_extra_nodes:
+ \bool_if:NT \l_@@_final_open_bool \@@_create_extra_nodes:
}
% \end{macrocode}
%
+%
%
% \interitem
% The command |\@@_retrieve_coords:nn| retrieves the Tikz coordinates of the two
@@ -4870,8 +4881,12 @@ c & c & b & a & e
% \begin{macrocode}
\cs_new_protected:Nn \@@_draw_Ldots:nn
{
- \@@_find_extremities_of_line:nnnn { #1 } { #2 } \c_zero_int \c_one_int
- \@@_if_yet_drawn:F \@@_actually_draw_Ldots:
+ \cs_if_free:cT { @@ _ dotted _ #1 - #2 }
+ {
+ \bool_set_false:N \l_@@_impossible_line_bool
+ \@@_find_extremities_of_line:nnnn { #1 } { #2 } \c_zero_int \c_one_int
+ \bool_if:NF \l_@@_impossible_line_bool \@@_actually_draw_Ldots:
+ }
}
% \end{macrocode}
%
@@ -4883,41 +4898,41 @@ c & c & b & a & e
% \begin{macrocode}
\cs_new_protected:Nn \@@_actually_draw_Ldots:
{
- \@@_retrieve_coords:xx
- {
- \bool_if:NTF \l_@@_initial_open_bool
- {
+ \@@_retrieve_coords:xx
+ {
+ \bool_if:NTF \l_@@_initial_open_bool
+ {
% \end{macrocode}
% If a |w| node exists (created when the key |columns-width| is used), we use
% the |w| node for the extremity.
% \begin{macrocode}
- \cs_if_exist:cTF
- {
- pgf@sh@ns@nm
- - \int_use:N \g_@@_env_int
- - \int_use:N \l_@@_initial_i_int
- - \int_use:N \l_@@_initial_j_int - w
- }
- { - w.base~west }
- { - medium.base~west }
- }
- { .base~east }
- }
+ \cs_if_exist:cTF
+ {
+ pgf@sh@ns@nm
+ - \int_use:N \g_@@_env_int
+ - \int_use:N \l_@@_initial_i_int
+ - \int_use:N \l_@@_initial_j_int - w
+ }
+ { - w.base~west }
+ { - medium.base~west }
+ }
+ { .base~east }
+ }
+ {
+ \bool_if:NTF \l_@@_final_open_bool
{
- \bool_if:NTF \l_@@_final_open_bool
- {
- \cs_if_exist:cTF
- {
- pgf@sh@ns@nm
- - \int_use:N \g_@@_env_int
- - \int_use:N \l_@@_final_i_int
- - \int_use:N \l_@@_final_j_int - w
- }
- { - w.base~east }
- { - medium.base~east }
+ \cs_if_exist:cTF
+ {
+ pgf@sh@ns@nm
+ - \int_use:N \g_@@_env_int
+ - \int_use:N \l_@@_final_i_int
+ - \int_use:N \l_@@_final_j_int - w
}
- { .base~west }
+ { - w.base~east }
+ { - medium.base~east }
}
+ { .base~west }
+ }
\bool_if:NT \l_@@_initial_open_bool
{ \dim_gset_eq:NN \g_@@_y_initial_dim \g_@@_y_final_dim }
\bool_if:NT \l_@@_final_open_bool
@@ -4936,45 +4951,49 @@ c & c & b & a & e
% \begin{macrocode}
\cs_new_protected:Nn \@@_draw_Cdots:nn
{
- \@@_find_extremities_of_line:nnnn { #1 } { #2 } \c_zero_int \c_one_int
- \@@_if_yet_drawn:F
- {
- \@@_retrieve_coords:xx
- {
- \bool_if:NTF \l_@@_initial_open_bool
- {
- \cs_if_exist:cTF
- {
- pgf@sh@ns@nm
- - \int_use:N \g_@@_env_int
- - \int_use:N \l_@@_initial_i_int
- - \int_use:N \l_@@_initial_j_int - w
+ \cs_if_free:cT { @@ _ dotted _ #1 - #2 }
+ {
+ \bool_set_false:N \l_@@_impossible_line_bool
+ \@@_find_extremities_of_line:nnnn { #1 } { #2 } \c_zero_int \c_one_int
+ \bool_if:NF \l_@@_impossible_line_bool
+ {
+ \@@_retrieve_coords:xx
+ {
+ \bool_if:NTF \l_@@_initial_open_bool
+ {
+ \cs_if_exist:cTF
+ {
+ pgf@sh@ns@nm
+ - \int_use:N \g_@@_env_int
+ - \int_use:N \l_@@_initial_i_int
+ - \int_use:N \l_@@_initial_j_int - w
+ }
+ { - w.mid~west }
+ { - medium.mid~west }
}
- { - w.mid~west }
- { - medium.mid~west }
+ { .mid~east }
}
- { .mid~east }
- }
- {
- \bool_if:NTF \l_@@_final_open_bool
{
- \cs_if_exist:cTF
- {
- pgf@sh@ns@nm
- - \int_use:N \g_@@_env_int
- - \int_use:N \l_@@_final_i_int
- - \int_use:N \l_@@_final_j_int - w
+ \bool_if:NTF \l_@@_final_open_bool
+ {
+ \cs_if_exist:cTF
+ {
+ pgf@sh@ns@nm
+ - \int_use:N \g_@@_env_int
+ - \int_use:N \l_@@_final_i_int
+ - \int_use:N \l_@@_final_j_int - w
+ }
+ { - w.mid~east }
+ { - medium.mid~east }
}
- { - w.mid~east }
- { - medium.mid~east }
+ { .mid~west }
}
- { .mid~west }
+ \bool_if:NT \l_@@_initial_open_bool
+ { \dim_gset_eq:NN \g_@@_y_initial_dim \g_@@_y_final_dim }
+ \bool_if:NT \l_@@_final_open_bool
+ { \dim_gset_eq:NN \g_@@_y_final_dim \g_@@_y_initial_dim }
+ \@@_draw_tikz_line:
}
- \bool_if:NT \l_@@_initial_open_bool
- { \dim_gset_eq:NN \g_@@_y_initial_dim \g_@@_y_final_dim }
- \bool_if:NT \l_@@_final_open_bool
- { \dim_gset_eq:NN \g_@@_y_final_dim \g_@@_y_initial_dim }
- \@@_draw_tikz_line:
}
}
% \end{macrocode}
@@ -4987,52 +5006,57 @@ c & c & b & a & e
% \begin{macrocode}
\cs_new_protected:Nn \@@_draw_Vdots:nn
{
- \@@_find_extremities_of_line:nnnn { #1 } { #2 } \c_one_int \c_zero_int
- \@@_if_yet_drawn:F
- { \@@_retrieve_coords:xx
- {
- \bool_if:NTF \l_@@_initial_open_bool
- { - medium.north~west }
- { .south~west }
- }
- {
- \bool_if:NTF \l_@@_final_open_bool
- { - medium.south~west }
- { .north~west }
- }
+ \cs_if_free:cT { @@ _ dotted _ #1 - #2 }
+ {
+ \bool_set_false:N \l_@@_impossible_line_bool
+ \@@_find_extremities_of_line:nnnn { #1 } { #2 } \c_one_int \c_zero_int
+ \bool_if:NF \l_@@_impossible_line_bool
+ {
+ \@@_retrieve_coords:xx
+ {
+ \bool_if:NTF \l_@@_initial_open_bool
+ { - medium.north~west }
+ { .south~west }
+ }
+ {
+ \bool_if:NTF \l_@@_final_open_bool
+ { - medium.south~west }
+ { .north~west }
+ }
% \end{macrocode}
% The boolean |\l_tmpa_bool| indicates whether the column is of type |l| (|L| of
% |{NiceArray}|) or may be considered as if.
% \begin{macrocode}
- \bool_set:Nn \l_tmpa_bool
- { \dim_compare_p:nNn \g_@@_x_initial_dim = \g_@@_x_final_dim }
- \@@_retrieve_coords:xx
- {
- \bool_if:NTF \l_@@_initial_open_bool
- { - medium.north }
- { .south }
- }
- {
- \bool_if:NTF \l_@@_final_open_bool
- { - medium.south }
- { .north }
- }
+ \bool_set:Nn \l_tmpa_bool
+ { \dim_compare_p:nNn \g_@@_x_initial_dim = \g_@@_x_final_dim }
+ \@@_retrieve_coords:xx
+ {
+ \bool_if:NTF \l_@@_initial_open_bool
+ { - medium.north }
+ { .south }
+ }
+ {
+ \bool_if:NTF \l_@@_final_open_bool
+ { - medium.south }
+ { .north }
+ }
% \end{macrocode}
% The boolean |\l_tmpb_bool| indicates whether the column is of type |c| (|C| of
% |{NiceArray}|) or may be considered as if.
% \begin{macrocode}
- \bool_set:Nn \l_tmpb_bool
- { \dim_compare_p:nNn \g_@@_x_initial_dim = \g_@@_x_final_dim }
- \bool_if:NF \l_tmpb_bool
- {
- \dim_gset:Nn \g_@@_x_initial_dim
+ \bool_set:Nn \l_tmpb_bool
+ { \dim_compare_p:nNn \g_@@_x_initial_dim = \g_@@_x_final_dim }
+ \bool_if:NF \l_tmpb_bool
{
- \bool_if:NTF \l_tmpa_bool \dim_min:nn \dim_max:nn
- \g_@@_x_initial_dim \g_@@_x_final_dim
+ \dim_gset:Nn \g_@@_x_initial_dim
+ {
+ \bool_if:NTF \l_tmpa_bool \dim_min:nn \dim_max:nn
+ \g_@@_x_initial_dim \g_@@_x_final_dim
+ }
+ \dim_gset_eq:NN \g_@@_x_final_dim \g_@@_x_initial_dim
}
- \dim_gset_eq:NN \g_@@_x_final_dim \g_@@_x_initial_dim
+ \@@_draw_tikz_line:
}
- \@@_draw_tikz_line:
}
}
% \end{macrocode}
@@ -5044,63 +5068,67 @@ c & c & b & a & e
% \begin{macrocode}
\cs_new_protected:Nn \@@_draw_Ddots:nn
{
- \@@_find_extremities_of_line:nnnn { #1 } { #2 } \c_one_int \c_one_int
- \@@_if_yet_drawn:F
+ \cs_if_free:cT { @@ _ dotted _ #1 - #2 }
{
- \@@_retrieve_coords:xx
- {
- \bool_if:NTF \l_@@_initial_open_bool
- { - medium.north~west }
- { .south~east }
- }
- {
- \bool_if:NTF \l_@@_final_open_bool
- { - medium.south~east }
- { .north~west }
- }
+ \bool_set_false:N \l_@@_impossible_line_bool
+ \@@_find_extremities_of_line:nnnn { #1 } { #2 } \c_one_int \c_one_int
+ \bool_if:NF \l_@@_impossible_line_bool
+ {
+ \@@_retrieve_coords:xx
+ {
+ \bool_if:NTF \l_@@_initial_open_bool
+ { - medium.north~west }
+ { .south~east }
+ }
+ {
+ \bool_if:NTF \l_@@_final_open_bool
+ { - medium.south~east }
+ { .north~west }
+ }
% \end{macrocode}
% We have retrieved the coordinates in the usual way (they are stored in
% |\g_@@_x_initial_dim|, etc.). If the parallelization of the diagonals is set,
% we will have (maybe) to adjust the fourth coordinate.
% \begin{macrocode}
- \bool_if:NT \l_@@_parallelize_diags_bool
- {
- \int_incr:N \l_@@_ddots_int
+ \bool_if:NT \l_@@_parallelize_diags_bool
+ {
+ \int_incr:N \l_@@_ddots_int
% \end{macrocode}
% We test if the diagonal line is the first one (the counter |\l_@@_ddots_int|
% is created for this usage).
% \begin{macrocode}
- \int_compare:nNnTF \l_@@_ddots_int = \c_one_int
+ \int_compare:nNnTF \l_@@_ddots_int = \c_one_int
% \end{macrocode}
% If the diagonal line is the first one, we have no adjustment of the line to do
% but we store the $\Delta_x$ and the $\Delta_y$ of the line because these
% values will be used to draw the others diagonal lines parallels to the first
% one.
% \begin{macrocode}
- {
- \dim_set:Nn \l_@@_delta_x_one_dim
- { \g_@@_x_final_dim - \g_@@_x_initial_dim }
- \dim_set:Nn \l_@@_delta_y_one_dim
- { \g_@@_y_final_dim - \g_@@_y_initial_dim }
- }
+ {
+ \dim_set:Nn \l_@@_delta_x_one_dim
+ { \g_@@_x_final_dim - \g_@@_x_initial_dim }
+ \dim_set:Nn \l_@@_delta_y_one_dim
+ { \g_@@_y_final_dim - \g_@@_y_initial_dim }
+ }
% \end{macrocode}
% If the diagonal line is not the first one, we have to adjust the second
% extremity of the line by modifying the coordinate |\g_@@_y_initial_dim|.
% \begin{macrocode}
- {
- \dim_gset:Nn \g_@@_y_final_dim
{
- \g_@@_y_initial_dim +
- ( \g_@@_x_final_dim - \g_@@_x_initial_dim ) *
- \dim_ratio:nn \l_@@_delta_y_one_dim \l_@@_delta_x_one_dim
+ \dim_gset:Nn \g_@@_y_final_dim
+ {
+ \g_@@_y_initial_dim +
+ ( \g_@@_x_final_dim - \g_@@_x_initial_dim ) *
+ \dim_ratio:nn \l_@@_delta_y_one_dim \l_@@_delta_x_one_dim
+ }
}
}
- }
% \end{macrocode}
% Now, we can draw the dotted line (after a possible change of
% |\g_@@_y_initial_dim|).
% \begin{macrocode}
- \@@_draw_tikz_line:
+ \@@_draw_tikz_line:
+ }
}
}
% \end{macrocode}
@@ -5110,39 +5138,44 @@ c & c & b & a & e
% \begin{macrocode}
\cs_new_protected:Nn \@@_draw_Iddots:nn
{
- \@@_find_extremities_of_line:nnnn { #1 } { #2 } 1 { -1 }
- \@@_if_yet_drawn:F
- { \@@_retrieve_coords:xx
- {
- \bool_if:NTF \l_@@_initial_open_bool
- { - medium.north~east }
- { .south~west }
- }
- {
- \bool_if:NTF \l_@@_final_open_bool
- { - medium.south~west }
- { .north~east }
- }
- \bool_if:NT \l_@@_parallelize_diags_bool
- {
- \int_incr:N \l_@@_iddots_int
- \int_compare:nNnTF \l_@@_iddots_int = \c_one_int
+ \cs_if_free:cT { @@ _ dotted _ #1 - #2 }
+ {
+ \bool_set_false:N \l_@@_impossible_line_bool
+ \@@_find_extremities_of_line:nnnn { #1 } { #2 } 1 { -1 }
+ \bool_if:NF \l_@@_impossible_line_bool
+ {
+ \@@_retrieve_coords:xx
+ {
+ \bool_if:NTF \l_@@_initial_open_bool
+ { - medium.north~east }
+ { .south~west }
+ }
{
- \dim_set:Nn \l_@@_delta_x_two_dim
- { \g_@@_x_final_dim - \g_@@_x_initial_dim }
- \dim_set:Nn \l_@@_delta_y_two_dim
- { \g_@@_y_final_dim - \g_@@_y_initial_dim }
+ \bool_if:NTF \l_@@_final_open_bool
+ { - medium.south~west }
+ { .north~east }
}
+ \bool_if:NT \l_@@_parallelize_diags_bool
{
- \dim_gset:Nn \g_@@_y_final_dim
- {
- \g_@@_y_initial_dim +
- ( \g_@@_x_final_dim - \g_@@_x_initial_dim ) *
- \dim_ratio:nn \l_@@_delta_y_two_dim \l_@@_delta_x_two_dim
- }
+ \int_incr:N \l_@@_iddots_int
+ \int_compare:nNnTF \l_@@_iddots_int = \c_one_int
+ {
+ \dim_set:Nn \l_@@_delta_x_two_dim
+ { \g_@@_x_final_dim - \g_@@_x_initial_dim }
+ \dim_set:Nn \l_@@_delta_y_two_dim
+ { \g_@@_y_final_dim - \g_@@_y_initial_dim }
+ }
+ {
+ \dim_gset:Nn \g_@@_y_final_dim
+ {
+ \g_@@_y_initial_dim +
+ ( \g_@@_x_final_dim - \g_@@_x_initial_dim ) *
+ \dim_ratio:nn \l_@@_delta_y_two_dim \l_@@_delta_x_two_dim
+ }
+ }
}
+ \@@_draw_tikz_line:
}
- \@@_draw_tikz_line:
}
}
% \end{macrocode}
@@ -5300,8 +5333,9 @@ c & c & b & a & e
% \begin{macrocode}
\cs_new_protected:Nn \@@_add_to_empty_cells:
{
- \seq_gput_right:Nx \g_@@_empty_cells_seq
- { \int_use:N \g_@@_row_int - \int_use:N \g_@@_col_int }
+ \cs_gset:cpx
+ { @@ _ empty _ \int_use:N \g_@@_row_int - \int_use:N \g_@@_col_int }
+ { \int_use:N \g_@@_env_int }
}
% \end{macrocode}
%
@@ -5310,6 +5344,9 @@ c & c & b & a & e
% |\@@_Iddots| will be linked to |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots| and
% |\Iddots| in the environments |{NiceArray}| (the other environments of
% \pkg{nicematrix} rely upon |{NiceArray}|).
+%
+% The starred versions of these commands are deprecated since version~3.1 but
+% they are still available.
% \begin{macrocode}
\NewDocumentCommand \@@_Ldots { s }
{
@@ -5409,20 +5446,18 @@ c & c & b & a & e
%
% The command |\@@_Hdotsfor_i| is defined with the tools of \pkg{xparse} because
% it has an optionnal argument. Note that such a command defined by
-% |\multicolumn| is protected and that's why we have put the |\multicolumn|
-% before (in the definition of |\@@_Hdotsfor:|).
+% |\NewDocumentCommand| is protected and that's why we have put the
+% |\multicolumn| before (in the definition of |\@@_Hdotsfor:|).
% \begin{macrocode}
\bool_if:NTF \c_@@_draft_bool
{
\NewDocumentCommand \@@_Hdotsfor_i { O { } m }
- {
- \prg_replicate:nn { #2 - 1 } { & \multicolumn { 1 } { C } { } }
- }
+ { \prg_replicate:nn { #2 - 1 } { & \multicolumn { 1 } { C } { } } }
}
{
\NewDocumentCommand \@@_Hdotsfor_i { O { } m }
{
- \tl_gput_right:Nx \g_@@_lines_to_draw_tl
+ \tl_gput_right:Nx \g_@@_Hdotsfor_lines_tl
{
\@@_draw_Hdotsfor:nnn
{ \int_use:N \g_@@_row_int }
@@ -5479,6 +5514,14 @@ c & c & b & a & e
\bool_if:nT { \l_@@_initial_open_bool || \l_@@_final_open_bool }
\@@_create_extra_nodes:
\@@_actually_draw_Ldots:
+% \end{macrocode}
+% We declare all the cells concerned by the |\Hdotsfor| as ``dotted'' (for the
+% dotted lines created by |\Cdots|, |\Ldots|, etc., this job is done by
+% |\@@_find_extremities_of_line:nnnn|). This declaration is done by defining a
+% special control sequence (to nil).
+% \begin{macrocode}
+ \int_step_inline:nnn { #2 } { #2 + #3 - 1 }
+ { \cs_set:cpn { @@ _ dotted _ #1 - ##1 } { } }
}
% \end{macrocode}
%
@@ -5643,14 +5686,6 @@ c & c & b & a & e
% \end{macrocode}
%
%
-% \begin{macrocode}
-\@@_msg_new:nn { Use~of~:~in~first~position }
- {
- You~can't~use~the~column~specifier~"\l_@@_letter_for_dotted_lines_str"~in~the~
- first~position~of~the~preamble~of~the~environment~\{\@currenvir\}. \\
- If~you~go~on,~this~dotted~line~will~be~ignored.
- }
-% \end{macrocode}
%
% \bigskip
% \subsection{The vertical rules}
@@ -5688,19 +5723,24 @@ c & c & b & a & e
{
\int_compare:nNnF \g_@@_row_int = \c_zero_int
{
- \int_compare:nNnF \g_@@_row_int = \l_@@_last_row_int \vline
+ \int_compare:nNnF \g_@@_row_int = \l_@@_last_row_int
+ \@@_vline_i:
}
}
{
\int_compare:nNnF \g_@@_row_int = \c_zero_int
{
- \int_compare:nNnF \g_@@_row_int = \l_@@_last_row_int \vline
+ \int_compare:nNnF \g_@@_row_int = \l_@@_last_row_int
+ \@@_vline_i:
}
}
}
{
\int_compare:nNnF \g_@@_row_int = \c_zero_int
- { \int_compare:nNnF \g_@@_row_int = \l_@@_last_row_int \vline }
+ {
+ \int_compare:nNnF \g_@@_row_int = \l_@@_last_row_int
+ \@@_vline_i:
+ }
}
}
{
@@ -5709,19 +5749,29 @@ c & c & b & a & e
\int_compare:nNnF \g_@@_row_int = { -1 }
{
\int_compare:nNnF \g_@@_row_int = { \l_@@_last_row_int - 1 }
- \vline
+ \@@_vline_i:
}
}
{
\int_compare:nNnF \g_@@_row_int = \c_zero_int
- { \int_compare:nNnF \g_@@_row_int = \l_@@_last_row_int \vline }
+ {
+ \int_compare:nNnF \g_@@_row_int = \l_@@_last_row_int
+ \@@_vline_i:
+ }
}
}
}
% \end{macrocode}
-%
-%
%
+% \medskip
+% If \pkg{colortbl} is loaded, the following macro will redefined (in a
+% |\AtBeginDocument|) to take into account the color fixed by |\arrayrulecolor|
+% of \pkg{colortbl}.
+% \begin{macrocode}
+\cs_set_eq:NN \@@_vline_i: \vline
+% \end{macrocode}
+%
+% \bigskip
% \subsection{The environment \{NiceMatrixBlock\}}
%
% The following flag will be raised when all the columns of the environments of
@@ -5787,6 +5837,9 @@ c & c & b & a & e
\cs_generate_variant:Nn \dim_max:nn { v n }
% \end{macrocode}
%
+% \bigskip
+% The macro |\@@_create_extra_nodes:| must \emph{not} be used in the
+% |code-after| because the |code-after| is executed in a scope of |prefix name|.
%
%
% \bigskip
@@ -5944,13 +5997,13 @@ c & c & b & a & e
% We can now compute the width of the array (used by |\hdottedline|).
% \begin{macrocode}
\begin { tikzpicture } [ remember~picture , overlay ]
- \tikz@parse@node \pgfutil@firstofone
- ( nm - \int_use:N \g_@@_env_int - 1 - 1 - large .north~west )
- \dim_gset:Nn \g_tmpa_dim \pgf@x
- \tikz@parse@node \pgfutil@firstofone
- ( nm - \int_use:N \g_@@_env_int - 1 -
- \int_use:N \g_@@_col_int - large .north~east )
- \dim_gset:Nn \g_tmpb_dim \pgf@x
+ \tikz@parse@node \pgfutil@firstofone
+ ( nm - \int_use:N \g_@@_env_int - 1 - 1 - large .north~west )
+ \dim_gset:Nn \g_tmpa_dim \pgf@x
+ \tikz@parse@node \pgfutil@firstofone
+ ( nm - \int_use:N \g_@@_env_int - 1 -
+ \int_use:N \g_@@_col_int - large .north~east )
+ \dim_gset:Nn \g_tmpb_dim \pgf@x
\end { tikzpicture }
\iow_now:Nn \@mainaux \ExplSyntaxOn
\iow_now:Nx \@mainaux
@@ -6064,6 +6117,136 @@ c & c & b & a & e
% \end{macrocode}
%
%
+% \subsection{Block matrices}
+%
+% The code in this section if for the construction of \emph{block matrices}. It
+% has no direct link with the environment |{NiceMatrixBlock}|.
+%
+% The following command will be linked to |\Block| in the environments of
+% \pkg{nicematrix}. We define it with |\NewExpandableDocumentCommand| of \pkg{xparse}
+% because it has an optionnal argument between |<| and |>| (for TeX instructions
+% put before the math mode of the label) and because it must be expandable since
+% it reduces (in the case of a block of only one row) to a command
+% |\multicolumn|.
+% \begin{macrocode}
+\NewExpandableDocumentCommand \@@_Block: { m D < > { } m }
+ {
+ \@@_Block_i #1 \q_stop { #2 } { #3 }
+ }
+% \end{macrocode}
+%
+% \medskip
+% The first argument of |\@@_Block:| (which is required) has a special syntax. It
+% must be of the form $i$|-|$j$ where $i$ and $j$ are the size (in rows and
+% columns) of the block.
+% \begin{macrocode}
+\cs_new:Npn \@@_Block_i #1-#2 \q_stop
+ {
+ \@@_Block_ii:nnnn { #1 } { #2 }
+ }
+% \end{macrocode}
+%
+% \medskip
+% Now, the arguments have been extracted: |#1| is $i$ (the number of rows of the
+% block), |#2| is $j$ (the number of columns of the block), |#3| are the tokens
+% to put before the math mode and |#4| is the label of the block. The following
+% command must \emph{not} be protected because it contains a command
+% |\multicolumn| (in the case of a block of only one row).
+% \begin{macrocode}
+\cs_new:Npn \@@_Block_ii:nnnn #1 #2 #3 #4
+ {
+% \end{macrocode}
+%
+% \medskip
+% In the case of a block of only one row, we use a |\multicolumn| and not the
+% general technique because, in this case, we want the label perfectly aligned
+% with the base line of that row of the array.
+% \begin{macrocode}
+ \int_compare:nNnTF { #1 } = 1
+ {
+ \multicolumn { #2 } { C } { \hbox:n { #3 $#4$ } }
+ \@@_gobble_ampersands:n { #2 - 1 }
+ }
+ { \@@_Block_iii:nnnn { #1 } { #2 } { #3 } { #4 } }
+ }
+% \end{macrocode}
+%
+% \medskip
+% The command |\@@_Block_iii:nnnn| is for the case of a block of $n$~rows with $n>1$.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_Block_iii:nnnn #1 #2 #3 #4
+ {
+ \bool_gset_true:N \g_@@_extra_nodes_bool
+% \end{macrocode}
+% We write an instruction in the |code-after|. We write the instruction in the
+% beginning of the |code-after| (the |left| in |\tl_gput_left:Nx|) because we
+% want the Tikz nodes corresponding of the block created \emph{before} potential
+% instructions written by the user in the |code-after| (these instructions may
+% use the Tikz node of the created block).
+% \begin{macrocode}
+ \tl_gput_left:Nx \g_@@_code_after_tl
+ {
+ \@@_Block_iv:nnnnn
+ { \int_use:N \g_@@_row_int }
+ { \int_use:N \g_@@_col_int }
+ { \int_eval:n { \g_@@_row_int + #1 - 1 } }
+ { \int_eval:n { \g_@@_col_int + #2 - 1 } }
+ \exp_not:n { { #3 $ #4 $ } }
+ }
+ }
+% \end{macrocode}
+%
+% \medskip
+% The command |\@@_gobble_ampersands:n| will gobble $n$ ampersands (and also the
+% spaces) where $n$ is the argument of the command. This command is fully expandable
+% and we need this feature.
+% \begin{macrocode}
+\group_begin:
+ \char_set_catcode_letter:N \&
+ \cs_new:Npn \@@_gobble_ampersands:n #1
+ {
+ \int_compare:nNnT { #1 } > 0
+ {
+ \peek_charcode_remove_ignore_spaces:NT &
+ { \@@_gobble_ampersands:n { #1 - 1 } }
+ }
+ }
+\group_end:
+% \end{macrocode}
+%
+%
+% \medskip
+% The following command |\@@_Block_iii:nnnnn| will be used in the |code-after|.
+% It's necessary to create two Tikz nodes because we want the label |#5| really
+% drawn in the \emph{center} of the node.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_Block_iv:nnnnn #1 #2 #3 #4 #5
+ {
+ \bool_if:nTF
+ {
+ \int_compare_p:nNn { #3 } > \g_@@_row_int
+ || \int_compare_p:nNn { #4 } > \g_@@_col_int
+ }
+ { \msg_error:nnnn { nicematrix } { Block~too~large } { #1 } { #2 } }
+ {
+ \begin{tikzpicture}
+ \node
+ [
+ fit = ( #1 - #2 - medium . north~west )
+ ( #3 - #4 - medium . south~east ) ,
+ inner~sep = 0 pt ,
+ ]
+% \end{macrocode}
+% We don't forget the name of the node because the user may wish to use it.
+% \begin{macrocode}
+ (#1-#2) { } ;
+ \node at (#1-#2.center) { #5 } ;
+ \end{tikzpicture}
+ }
+ }
+% \end{macrocode}
+%
+%
% \subsection{We process the options}
%
% We process the options when the package is loaded (with |\usepackage|) but we
@@ -6079,6 +6262,249 @@ c & c & b & a & e
\ProcessKeysOptions { NiceMatrix }
% \end{macrocode}
%
+% \subsection{Error messages of the package}
+%
+% \begin{macrocode}
+\@@_msg_new:nn { Block~too~large }
+ {
+ You~try~to~draw~a~block~in~the~cell~#1-#2~of~your~matrix~but~the~matrix~is~
+ too~small~for~that~block.\\
+ If~you~go~on,~this~command~line~will~be~ignored.
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\@@_msg_new:nn { Impossible~line }
+ {
+ A~dotted~line~can't~be~drawn~because~you~have~not~put~
+ all~the~ampersands~required~on~the~row~#1.\\
+ If~you~go~on,~this~dotted~line~will~be~ignored.
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_msg_new:nn { Wrong~last~row }
+ {
+ You~have~used~'last-row=\int_use:N \g_@@_last_row_int'~but~your~environment~
+ \{\@currenvir\}~seems~to~have~\int_use:N \g_@@_row_int\
+ rows~(remark~that~you~can~use~'last-row'~without~value).~If~you~go~on,
+ ~the~value~of~\int_use:N \g_@@_row_int\
+ will~be~used~for~last~row.
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_msg_new:nn { Draft~mode }
+ { The~compilation~is~in~draft~mode:~the~dotted~lines~won't~be~drawn. }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_msg_new:nn { Yet~in~env }
+ {
+ Environments~\{NiceArray\}~(or~\{NiceMatrix\},~etc.)~can't~be~
+ nested.\\
+ This~error~is~fatal.
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_msg_new:nn { Outside~math~mode }
+ {
+ The~environment~\{\@currenvir\}~can~be~used~only~in~math~mode~
+ (and~not~in~\token_to_str:N \vcenter).\\
+ This~error~is~fatal.
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_msg_new:nn { Option~Transparent~suppressed }
+ {
+ The~option~'Transparent'~has~been~renamed~'transparent'.\\
+ However,~you~can~go~on~for~this~time.
+ }
+\@@_msg_new:nn { Option~RenewMatrix~suppressed }
+ {
+ The~option~'RenewMatrix'~has~been~renamed~'renew-matrix'.\\
+ However,~you~can~go~on~for~this~time.
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_msg_new:nn { Bad~value~for~letter~for~dotted~lines }
+ {
+ The~value~of~key~'\tl_use:N\l_keys_key_tl'~must~be~of~length~1.\\
+ If~you~go~on,~it~will~be~ignored.
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\@@_msg_new:nnn { Unknown~key~for~NiceMatrixOptions }
+ {
+ The~key~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~command~
+ \token_to_str:N \NiceMatrixOptions. \\
+ If~you~go~on,~it~will~be~ignored. \\
+ For~a~list~of~the~available~keys,~type~H~<return>.
+ }
+ {
+ The~available~keys~are~(in~alphabetic~order):~
+ allow-duplicate-names,~
+ code-for-first-col,~
+ code-for-first-row,~
+ code-for-last-col,~
+ code-for-last-row,~
+ exterior-arraycolsep,~
+ hlines,~
+ left-margin,~
+ letter-for-dotted-lines,~
+ nullify-dots,~
+ parallelize-diags,~
+ renew-dots,~
+ renew-matrix,~
+ right-margin,~
+ and~transparent
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_msg_new:nnn { Unknown~option~for~NiceArray }
+ {
+ The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~environment~
+ \{NiceArray\}. \\
+ If~you~go~on,~it~will~be~ignored. \\
+ For~a~list~of~the~available~options,~type~H~<return>.
+ }
+ {
+ The~available~options~are~(in~alphabetic~order):~
+ b,~
+ c,~
+ code-after,~
+ code-for-first-col,~
+ code-for-first-row,~
+ code-for-last-col,~
+ code-for-last-row,~
+ columns-width,~
+ create-extra-nodes,~
+ extra-left-margin,~
+ extra-right-margin,~
+ hlines,~
+ left-margin,~
+ name,~
+ nullify-dots,~
+ parallelize-diags,~
+ renew-dots,~
+ right-margin,~
+ and~t.
+ }
+% \end{macrocode}
+%
+%
+% \begin{macrocode}
+\@@_msg_new:nnn { Unknown~option~for~NiceMatrix }
+ {
+ The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~environment~
+ \{NiceMatrix\}~and~its~variants. \\
+ If~you~go~on,~it~will~be~ignored. \\
+ For~a~list~of~the~available~options,~type~H~<return>.
+ }
+ {
+ The~available~options~are~(in~alphabetic~order):~
+ code-after,~
+ columns-width,~
+ create-extra-nodes,~
+ extra-left-margin,~
+ extra-right-margin,~
+ hlines,~
+ left-margin,~
+ name,~
+ nullify-dots,~
+ parallelize-diags,~
+ renew-dots~
+ and~right-margin.
+ }
+% \end{macrocode}
+%
+% \medskip
+% Despite its name, the following set of keys will be used for |{pNiceArray}|
+% but also |{vNiceArray}|, |{VNiceArray}|, etc. but not for |{NiceArray}|.
+% \begin{macrocode}
+\@@_msg_new:nnn { Unknown~option~for~pNiceArray }
+ {
+ The~option~'\tl_use:N\l_keys_key_tl'~is~unknown~for~the~environment~
+ \{\@currenvir\}. \\
+ If~you~go~on,~it~will~be~ignored. \\
+ For~a~list~of~the~available~options,~type~H~<return>.
+ }
+ {
+ The~available~options~are~(in~alphabetic~order):~
+ code-after,~
+ code-for-first-col,~
+ code-for-first-row,~
+ code-for-last-col,~
+ code-for-last-row,~
+ columns-width,~
+ create-extra-nodes,~
+ extra-left-margin,~
+ extra-right-margin,~
+ first-col,~
+ first-row,~
+ last-col,~
+ last-row,~
+ hlines,~
+ left-margin,~
+ name,~
+ nullify-dots,~
+ parallelize-diags,~
+ renew-dots,~
+ and~right-margin.
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_msg_new:nnn { Duplicate~name }
+ {
+ The~name~'\l_keys_value_tl'~is~already~used~and~you~shouldn't~use~
+ the~same~environment~name~twice.~You~can~go~on,~but,~
+ maybe,~you~will~have~incorrect~results~especially~
+ if~you~use~'columns-width=auto'. \\
+ For~a~list~of~the~names~already~used,~type~H~<return>. \\
+ If~you~don't~want~to~see~this~message~again,~use~the~option~
+ 'allow-duplicate-names'.
+ }
+ {
+ The~names~already~defined~in~this~document~are:~
+ \seq_use:Nnnn \g_@@_names_seq { ,~ } { ,~ } { ~and~ }.
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_msg_new:nn { Option~auto~for~columns-width }
+ {
+ You~can't~give~the~value~'auto'~to~the~option~'columns-width'~here.~
+ If~you~go~on,~the~option~will~be~ignored.
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_msg_new:nn { Zero~row }
+ {
+ There~is~a~problem.~Maybe~your~environment~\{\@currenvir\}~is~empty.~
+ Maybe~you~have~used~l,~c~and~r~instead~of~L,~C~and~R~in~the~preamble~
+ of~your~environment. \\
+ If~you~go~on,~the~result~may~be~incorrect.
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\@@_msg_new:nn { Use~of~:~in~first~position }
+ {
+ You~can't~use~the~column~specifier~'\l_@@_letter_for_dotted_lines_str'~in~the~
+ first~position~of~the~preamble~of~the~environment~\{\@currenvir\}. \\
+ If~you~go~on,~this~dotted~line~will~be~ignored.
+ }
+% \end{macrocode}
+%
%
% \subsection{Code for \textbackslash seq_mapthread_function:NNN}
%
@@ -6369,17 +6795,36 @@ c & c & b & a & e
% A warning is issued when the |draft| mode is used. In this case, the dotted
% lines are not drawn.
%
-%
-% \subsection*{Changes between version 2.2.1 and 2.3}
+%
+% \subsection*{Changes between version 2.3 and 3.0}
%
% Modification of |\Hdotsfor|. Now |\Hdotsfor| erases the |\vlines| (of ``"|"'')
% as |\hdotsfor| does.
%
-% \subsection*{Changes between version 2.3 and 3.0}
-%
% Composition of exterior rows and columns of the four sides of the matrix (and
% not only on two sides) with the options |first-row|, |last-row|, |first-col|
% and |last-col|.
+%
+% \subsection*{Changes between version 3.0 and 3.1}
+%
+% Command |\Block| to draw block matrices.
+%
+% Error message when the user gives an incorrect value for |last-row|.
+%
+% A dotted line can no longer cross another dotted line (except the dotted lines
+% drawn by |\cdottedline|, |:| (in the preamble of the array) and |\line| in
+% |code-after|.
+%
+% The starred versions of |\Cdots|, |\Ldots|, etc. are now deprecated because,
+% with the new implementation, they become pointless. These starred versions
+% are no longer documented.
+%
+% The vertical rules in the matrices (drawn by \verb+|+) are now compatible with
+% the color fixed by \pkg{colortbl}.
+%
+% Correction of a bug: it was not possible to use the colon |:| in the preamble
+% of an array when |pdflatex| was used with \pkg{french-babel} (because
+% \pkg{french-babel} activates the colon in the beginning of the document).
%
% \PrintIndex
%