diff options
author | Karl Berry <karl@freefriends.org> | 2019-09-04 21:47:57 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2019-09-04 21:47:57 +0000 |
commit | 44e65427bf48a4f0e8ec4fa535155720bcc80cae (patch) | |
tree | 6e46bed91c6b9a9d1fae298fbc59a6262bcc3e86 /Master/texmf-dist/source | |
parent | 9c2d59c2078da9c770a3e1015d0c10f2bcf9a990 (diff) |
nicematrix (4sep19)
git-svn-id: svn://tug.org/texlive/trunk@52028 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source')
-rw-r--r-- | Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx | 1661 |
1 files changed, 1053 insertions, 608 deletions
diff --git a/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx b/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx index 8709af977d5..3e91e797955 100644 --- a/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx +++ b/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx @@ -15,8 +15,8 @@ % % \fi % \iffalse -\def\myfileversion{3.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 % |