summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2018-02-14 00:06:17 +0000
committerKarl Berry <karl@freefriends.org>2018-02-14 00:06:17 +0000
commit1bf53a1df338cff0bfd274cd81f5fe2c4b64ad6e (patch)
tree844294a6f01f4765de014895565f19ad3d1ee14f
parent84a8ae7611e78c584fa28e9b48879fc2aa02646a (diff)
nicematrix (13feb18)
git-svn-id: svn://tug.org/texlive/trunk@46627 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r--Master/texmf-dist/doc/latex/nicematrix/README.md9
-rw-r--r--Master/texmf-dist/doc/latex/nicematrix/nicematrix.pdfbin0 -> 139518 bytes
-rw-r--r--Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx1487
-rw-r--r--Master/texmf-dist/source/latex/nicematrix/nicematrix.ins47
-rw-r--r--Master/texmf-dist/tex/latex/nicematrix/nicematrix.sty386
-rwxr-xr-xMaster/tlpkg/bin/tlpkg-ctan-check2
-rw-r--r--Master/tlpkg/tlpsrc/collection-mathscience.tlpsrc1
-rw-r--r--Master/tlpkg/tlpsrc/nicematrix.tlpsrc0
8 files changed, 1931 insertions, 1 deletions
diff --git a/Master/texmf-dist/doc/latex/nicematrix/README.md b/Master/texmf-dist/doc/latex/nicematrix/README.md
new file mode 100644
index 00000000000..8aefad15a5a
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/nicematrix/README.md
@@ -0,0 +1,9 @@
+The LaTeX extension nicematrix is distributed under the LPPL 1.3 license.
+
+This extension has been written by F. Pantigny (fpantigny@wanadoo.fr).
+
+This extension is entirely contained in a single file : nicematrix.sty
+
+The LaTeX package nicematrix gives an environment NiceMatrix which is similar to environment
+matrix of mathtools but gives the possibility to draw beautiful ellipis dots between the cells
+of the matrix. \ No newline at end of file
diff --git a/Master/texmf-dist/doc/latex/nicematrix/nicematrix.pdf b/Master/texmf-dist/doc/latex/nicematrix/nicematrix.pdf
new file mode 100644
index 00000000000..0f80f3f17d4
--- /dev/null
+++ b/Master/texmf-dist/doc/latex/nicematrix/nicematrix.pdf
Binary files differ
diff --git a/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx b/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx
new file mode 100644
index 00000000000..bead31a579d
--- /dev/null
+++ b/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx
@@ -0,0 +1,1487 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2017 by F. Pantigny
+% -----------------------------------
+%
+% This file may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% of this license or (at your option) any later version.
+% The latest version of this license is in:
+%
+% http://www.latex-project.org/lppl.txt
+%
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% \fi
+% \iffalse
+\def\myfileversion{1.0}
+\def\myfiledate{2018/02/13}
+%
+%
+%<*batchfile>
+\begingroup
+\input l3docstrip.tex
+\keepsilent
+\usedir{tex/latex/nicematrix}
+\preamble
+
+Copyright (C) 2017 by F. Pantigny
+-----------------------------------
+
+This file may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either version 1.3
+of this license or (at your option) any later version.
+The latest version of this license is in:
+
+http://www.latex-project.org/lppl.txt
+
+and version 1.3 or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+\endpreamble
+\askforoverwritefalse
+\endgroup
+%</batchfile>
+%
+%<@@=nm>
+%<*driver>
+\documentclass{l3doc} % load fancyvrb, amsmath, array, color, etc.
+\VerbatimFootnotes
+\usepackage{xltxtra}
+\usepackage{lmodern}
+\usepackage{geometry}
+\usepackage[dvipsnames]{xcolor} % color is already loaded with l3doc (?)
+\geometry{left=2.8cm,right=2.8cm,top=2.5cm,bottom=2.5cm,papersize={21cm,29.7cm}}
+\usepackage{mathtools}
+\usepackage{amsfonts}
+\usepackage{stmaryrd}
+\usepackage{nicematrix}
+\NewDocumentEnvironment {scope} {} {} {}
+\def\interitem{\vskip 7mm plus 2 mm minus 3mm}
+\def\emphase#1{{\color{RoyalPurple}#1}}
+\fvset{commandchars=\~\#\@,formatcom={\color{gray}}}
+\parindent 0pt
+\DisableCrossrefs
+\begin{document}
+\DocInput{nicematrix.dtx}
+\end{document}
+%</driver>
+% \fi
+% \title{The package \pkg{nicematrix}\thanks{This document corresponds to the version~\myfileversion\space of \pkg{nicematrix},
+% at the date of~\myfiledate.}} \author{F. Pantigny \\ \texttt{fpantigny@wanadoo.fr}}
+%
+% \maketitle
+%
+% \begin{abstract}
+% The LaTeX package \pkg{nicematrix} gives an environment |{NiceMatrix}| which is similar to the environment
+% |{matrix}| but gives the possibility to draw ellipis dots between the cells of the matrix.
+% \end{abstract}
+%
+% \vspace{1cm}
+% \section{Presentation}
+%
+% This package can be used with |xelatex|, |lualatex|, |pdflatex| but also by the classical workflow
+% |latex|-|dvips|-|ps2pdf| (or Adobe Distiller). Two compilations may be necessary. This package requires the
+% packages \pkg{expl3}, \pkg{l3keys2e}, \pkg{xparse}, \pkg{array}, \pkg{mathtools} and \pkg{tikz}. The Tikz
+% libraries \pkg{calc} and \pkg{math} are also required.
+%
+% \medskip
+% The package \pkg{nicematrix} aims to draw beautiful matrices in a way almost transparent for the user.
+%
+% \medskip
+% Consider, for exemple, the matrix\enskip
+% $A = \begin{pmatrix}
+% 1 &\cdots &\cdots &1 \\
+% 0 &\ddots & &\vdots \\
+% \vdots &\ddots &\ddots &\vdots \\
+% 0 &\cdots &0 &1
+% \end{pmatrix}$
+%
+% \medskip
+% Usually, when using LaTeX and \pkg{amsmath} (or \pkg{mathtools}), such a matrix is composed with an environment
+% |{pmatrix}| and the following code:
+% \begin{Verbatim}
+% $A = \begin{pmatrix}
+% 1 & \cdots & \cdots & 1 \\
+% 0 & \ddots & & \vdots \\
+% \vdots & \ddots & \ddots & \vdots \\
+% 0 & \cdots & 0 & 1
+% \end{pmatrix}$
+% \end{Verbatim}
+%
+% \medskip
+% If we load the package \pkg{nicematrix} with the option |Transparent|, the same code will give the
+% following result:
+%
+% \begin{scope}
+% \NiceMatrixOptions{Transparent}
+% \[A = \begin{pmatrix}
+% 1 & \cdots & \cdots & 1 \\
+% 0 & \ddots & & \vdots \\
+% \vdots & \ddots & \ddots & \vdots \\
+% 0 & \cdots & 0 & 1
+% \end{pmatrix}\]
+% \end{scope}
+%
+% \medskip
+% The dotted lines are drawn with Tikz. Two compilations may be necessary.
+%
+%
+% \section{How to use nicematrix for new code}
+%
+% \subsection{The environment NiceMatrix and its variants}
+%
+% The package \pkg{nicematrix} gives six new environments |{NiceMatrix}|, |{pNiceMatrix}|, |{bNiceMatrix}|,
+% |{BNiceMatrix}|, |{vNiceMatrix}| and |{VNiceMatrix}|. By default, these environments behave almost exactly as the
+% corresponding environments of \pkg{amsmath} (and \pkg{mathtools}): |{matrix}|, |{pmatrix}|, |{bmatrix}|,
+% |{Bmatrix}|, |{vmatrix}| and |{Vmatrix}|.
+%
+% \smallskip
+% Inside these environments, five new commands are defined: |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots| and |\Iddots|.
+% These commands are intended to be used in place of |\dots|, |\cdots|, |\vdots|, |\ddots| and
+% |\iddots|.\footnote{The command |\iddots|, defined in \pkg{nicematrix}, is a variant of
+% |\ddots| with dots going forward: \smash{$\iddots$}. If |mathdots| is loaded, the version of |mathdots| is used.}
+%
+% \smallskip
+% Each of them must be used alone in the cell of the array and it draws a dotted line between the first non-empty
+% cells\footnote{The precise definition of a ``non-empty cell'' is given below.} on both sides of the current cell.
+% Of course, for |\Ldots| and |\Cdots|, it's an horizontal line; for |\Vdots|, it's a vertical line and for
+% |\Ddots| and |\Iddots| diagonals ones.\par\nobreak
+% \bigskip
+% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
+% \begin{bNiceMatrix}
+% a_1 & \Cdots & & & a_1 \\
+% \Vdots & a_2 & \Cdots & & a_2 \\
+% & \Vdots & \Ddots \\
+% \\
+% a_1 & a_2 & & & a_n \\
+% \end{bNiceMatrix}
+% \end{BVerbatim}
+% $\begin{bNiceMatrix}
+% a_1 & \Cdots & & & a_1 \\
+% \Vdots & a_2 & \Cdots & & a_2 \\
+% & \Vdots & \Ddots \\
+% \\
+% a_1 & a_2 & & & a_n \\
+% \end{bNiceMatrix}$
+%
+% \interitem
+% In order to represent the null matrix, one can use the following codage:\par\nobreak
+% \bigskip
+% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
+% \begin{bNiceMatrix}
+% 0 & \Cdots & 0 \\
+% \Vdots & & \Vdots \\
+% 0 & \Cdots & 0
+% \end{bNiceMatrix}
+% \end{BVerbatim}
+% $\begin{bNiceMatrix}
+% 0 & \Cdots & 0 \\
+% \Vdots & & \Vdots \\
+% 0 & \Cdots & 0
+% \end{bNiceMatrix}$
+%
+% \bigskip
+% However, one may want a larger matrix. Usually, in such a case, the users of LaTeX add a new row and a new
+% column. It's possible to use the same method with \pkg{nicematrix}:\par\nobreak
+% \bigskip
+% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
+% \begin{bNiceMatrix}
+% 0 & \Cdots & \Cdots & 0 \\
+% \Vdots & & & \Vdots \\
+% \Vdots & & & \Vdots \\
+% 0 & \Cdots & \Cdots & 0
+% \end{bNiceMatrix}
+% \end{BVerbatim}
+% $\begin{bNiceMatrix}
+% 0 & \Cdots & \Cdots & 0 \\
+% \Vdots & & & \Vdots \\
+% \Vdots & & & \Vdots \\
+% 0 & \Cdots & \Cdots & 0
+% \end{bNiceMatrix}$
+%
+% \bigskip
+% In the first column of this exemple, there are two instructions |\Vdots| but only one dotted line is drawn (there
+% is no overlapping graphic objects in the resulting \textsc{pdf}).
+%
+% 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
+% \bigskip
+% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
+% \begin{bNiceMatrix}
+% 0 & \Cdots & & 0 \\
+% \Vdots & & & \\
+% & & & \Vdots \\
+% 0 & & \Cdots & 0
+% \end{bNiceMatrix}
+% \end{BVerbatim}
+% $\begin{bNiceMatrix}
+% 0 & \Cdots & & 0 \\
+% \Vdots & & & \\
+% & & & \Vdots \\
+% 0 & & \Cdots & 0
+% \end{bNiceMatrix}$
+%
+% \bigskip
+% 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.
+% However, a command~|\hspace*| might interfer with the construction of the dotted lines. That's why the package
+% \pkg{nicematrix} provides a command~|\Hspace| which is a variant of |\hspace| transparent for the dotted lines of
+% \pkg{nicematrix}.\par\nobreak
+% \bigskip
+% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
+% \begin{bNiceMatrix}
+% 0 & \Cdots & ~emphase#\Hspace*{1cm}@ & 0 \\
+% \Vdots & & & \Vdots \\~emphase#[1cm]@
+% 0 & \Cdots & & 0
+% \end{bNiceMatrix}
+% \end{BVerbatim}
+% $\begin{bNiceMatrix}
+% 0 & \Cdots & \Hspace*{1cm} & 0 \\
+% \Vdots & & & \Vdots \\[1cm]
+% 0 & \Cdots & & 0
+% \end{bNiceMatrix}$
+%
+% \vskip1cm
+% \subsection{The option NullifyDots}
+%
+% Consider the following matrix composed classicaly with the environment |{pmatrix}|.\par\nobreak
+% \medskip
+% \begin{BVerbatim}[baseline=c,boxwidth=7cm]
+% $A = \begin{pmatrix}
+% a_0 & b \\
+% a_1 & \\
+% a_2 & \\
+% a_3 & \\
+% a_4 & \\
+% a_5 & b
+% \end{pmatrix}$
+% \end{BVerbatim}
+% $A = \begin{pmatrix}
+% a_0 & b \\
+% a_1 & \\
+% a_2 & \\
+% a_3 & \\
+% a_4 & \\
+% a_5 & b
+% \end{pmatrix}$
+%
+%
+% \bigskip
+% If we add |\vdots| instructions in the second column, the geometry of the matrix is modified.\par\nobreak
+% \medskip
+% \begin{BVerbatim}[baseline=c,boxwidth=7cm]
+% $B = \begin{pmatrix}
+% a_0 & b \\
+% a_1 & \vdots \\
+% a_2 & \vdots \\
+% a_3 & \vdots \\
+% a_4 & \vdots \\
+% a_5 & b
+% \end{pmatrix}$
+% \end{BVerbatim}
+% $B = \begin{pmatrix}
+% a_0 & b \\
+% a_1 & \vdots \\
+% a_2 & \vdots \\
+% a_3 & \vdots \\
+% a_4 & \vdots \\
+% a_5 & b
+% \end{pmatrix}$
+%
+% \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
+% \medskip
+% \begin{BVerbatim}[baseline=c,boxwidth=7cm]
+% $C = \begin{pNiceMatrix}
+% a_0 & b \\
+% a_1 & \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_5 & b
+% \end{pNiceMatrix}$
+%
+% \bigskip
+% However, one may prefer the geometry of the first matrix $A$ and would like to have such a geometry with a dotted
+% line in the second column. It's possible by using the option |NullifyDots| (and only one instruction |\Vdots| is
+% necessary).\par\nobreak
+% \medskip
+% \begin{BVerbatim}[baseline=c,boxwidth=7cm]
+% ~emphase#\NiceMatrixOptions{NullifyDots}@
+% $D = \begin{pNiceMatrix}
+% a_0 & b \\
+% a_1 & \Vdots \\
+% a_2 & \\
+% a_3 & \\
+% a_4 & \\
+% a_5 & b
+% \end{pNiceMatrix}$
+% \end{BVerbatim}
+% {\NiceMatrixOptions{NullifyDots}
+% $D = \begin{pNiceMatrix}
+% a_0 & b \\
+% a_1 & \Vdots \\
+% a_2 & \\
+% a_3 & \\
+% a_4 & \\
+% a_5 & b
+% \end{pNiceMatrix}$}
+%
+% \medskip
+% The option |NullifyDots| smashes the instructions |\Ldots| (and the variants) vertically but also horizontally.
+%
+% \section{How to use nicematrix for existing code}
+%
+% The package \pkg{nicematrix} provides an option called |Transparent| for using existing code transparently (this
+% option --- and the others --- can be set with the |\usepackage| command but \pkg{nicematrix} provides also a
+% dedicated command called |\NiceMatrixOptions|).
+%
+% In fact, this option is an alias for the conjonction of two options : |RenewDots| and |RenewMatrix|.
+%
+% \smallskip
+%
+% \begin{itemize}
+% \item The option |RenewDots|\par\nobreak
+% With this option, the commands |\ldots|, |\cdots|, |\vdots|, |\ddots| and |\iddots|\footnote{The command
+% |\iddots| is not a command of LaTeX but is defined by the package \pkg{nicematrix}. If |mathdots| is loaded, the
+% version of |mathdots| is used.} are redefined within the environments |{NiceMatrix}| and behave like |\Ldots|,
+% |\Cdots|, |\Vdots|, |\Ddots| and |\Iddots|; the command |\dots| (``automatic dots'' of |amsmath| --- and
+% |mathtools|) is also redefined to behave like |\Ldots|.
+%
+% \item The option |RenewMatrix|\par\nobreak
+% With this option, the environment |{matrix}| is redefined and behave like |{NiceMatrix}|, and so on for the five
+% variants.
+% \end{itemize}
+%
+% \bigskip
+% Therefore, with the option |Transparent|, a classical code gives directly the ouput of \pkg{nicematrix}.\par\nobreak
+% \bigskip
+% \begin{BVerbatim}[baseline=c]
+% ~emphase#\NiceMatrixOptions{Transparent}@
+% \begin{pmatrix}
+% 1 & \cdots & \cdots & 1 \\
+% 0 & \ddots & & \vdots \\
+% \vdots & \ddots & \ddots & \vdots \\
+% 0 & \cdots & 0 & 1
+% \end{pmatrix}
+% \end{BVerbatim}
+% \hspace{2cm}
+% \begin{scope}
+% \NiceMatrixOptions{Transparent}
+% $\begin{pmatrix}
+% 1 & \cdots & \cdots & 1 \\
+% 0 & \ddots & & \vdots \\
+% \vdots & \ddots & \ddots & \vdots \\
+% 0 & \cdots & 0 & 1
+% \end{pmatrix}$
+% \end{scope}
+%
+%
+% \section{Technical remarks}
+%
+% \subsection{Diagonal lines}
+%
+% By default, all the diagonal lines of a same matrix are ``parallelized''. That means that the first diagonal line
+% is drawn and, then, the other lines are drawn parallel to the first one (by rotation around the left-most
+% extremity of the line). That's why the position of the instructions |\Ddots| in the matrix can have a marked
+% effect on the final result.
+%
+% \medskip
+% In the following examples, the first |\Ddots| instruction is written in color:
+%
+% \medskip
+% \begin{scope}
+% \begin{minipage}{9.5cm}
+% Example with parallelization (default):
+% \begin{Verbatim}
+% $A = \begin{pNiceMatrix}
+% 1 & \Cdots & & 1 \\
+% a+b & ~emphase#\Ddots@~ & & \Vdots \\
+% \Vdots & \Ddots & & \\
+% a+b & \Cdots & a+b & 1
+% \end{pNiceMatrix}$
+% \end{Verbatim}
+% \end{minipage}
+% $A = \begin{pNiceMatrix}
+% 1 & \Cdots & & 1 \\
+% a+b & \Ddots & & \Vdots \\
+% \Vdots & \Ddots & & \\
+% a+b & \Cdots & a+b & 1
+% \end{pNiceMatrix}$
+%
+% \bigskip
+% \NiceMatrixOptions{ParallelizeDiagonals=true}%
+% \begin{minipage}{9.5cm}
+% % \begin{Verbatim}
+% $A = \begin{pNiceMatrix}
+% 1 & \Cdots & & 1 \\
+% a+b & & & \Vdots \\
+% \Vdots & ~emphase#\Ddots@~ & \Ddots & \\
+% a+b & \Cdots & a+b & 1
+% \end{pNiceMatrix}$
+% \end{Verbatim}
+% \end{minipage}
+% $A = \begin{pNiceMatrix}
+% 1 & \Cdots & & 1 \\
+% a+b & & & \Vdots \\
+% \Vdots & \Ddots & \Ddots & \\
+% a+b & \Cdots & a+b & 1
+% \end{pNiceMatrix}$
+%
+% \bigskip
+% It's possible to turn off the parallelization with the option |ParallelizeDiagonals| set to |false|: \par\nobreak
+%
+% \medskip
+% \NiceMatrixOptions{ParallelizeDiagonals=false}%
+% \begin{minipage}{9.5cm}
+% The same example without parallelization:\\
+% |\NiceMatrixOptions{ParallelizeDiagonals=false}|.
+% \end{minipage}
+% $A = \begin{pNiceMatrix}
+% 1 & \Cdots & & 1 \\
+% a+b & \Ddots & & \Vdots \\
+% \Vdots & \Ddots & & \\
+% a+b & \Cdots & a+b & 1
+% \end{pNiceMatrix}$
+%
+%
+% \end{scope}
+%
+% \vskip1cm
+% \subsection{The ``empty'' cells}
+%
+% An instruction like |\Ldots|, |\Cdots|, etc. tries to determine the first non-empty cell on both sides. However,
+% a empty cell is not necessarily a cell with no TeX content (that is to say a cell with no token between the two
+% ampersands~|&|). Indeed, a cell with contents |\hspace*{1cm}| may be considered as empty.
+%
+% \interitem
+% For \pkg{nicematrix}, the precise rules are as follow.
+%
+% \begin{itemize}
+% \item An implicit cell is empty. For example, in the following matrix:
+%
+% \begin{Verbatim}
+% \begin{pmatrix}
+% a & b \\
+% c \\
+% \end{pmatrix}
+% \end{Verbatim}
+%
+% the last cell (second row and second column) is empty.
+%
+% \medskip
+% \item Each cell whose TeX ouput has a width less than 0.5~pt is empty.
+%
+% \medskip
+% \item A cell which contains a command |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots| or |\Iddots| and their starred
+% versions is empty. We recall that theses commands should be used alone in a cell.
+%
+% \medskip
+% \item A cell with a command |\Hspace| (or |\Hspace*|) is empty. This command |\Hspace| is a command defined by
+% the package \pkg{nicematrix} with the same meaning that |\hspace| except that the cell where it is used is
+% considered as empty. This command can be used to fix the width of some columns of the matrix without interfering
+% with \pkg{nicematrix}.
+% % \end{itemize}
+%
+% \interitem
+% A dotted line must be delimited by two non-empty cells. If it's not possible to find one of these cells whitin
+% the boudaries of the matrix, an error is issued and the instruction is ignored.
+%
+%
+%
+% \section{Examples}
+%
+%
+% \bigskip
+% A tridiagonal matrix :
+%
+% \bigskip
+% \begin{BVerbatim}[baseline=c]
+% \NiceMatrixOptions{NullifyDots}
+% $\begin{pNiceMatrix}
+% a & b & 0 & & \Cdots & 0 \\
+% b & a & b & \Ddots & & \Vdots \\
+% 0 & b & a & \Ddots & & \\
+% & \Ddots & \Ddots & \Ddots & & 0 \\
+% \Vdots & & & & & b \\
+% 0 & \Cdots & & 0 & b & a
+% \end{pNiceMatrix}$
+% \end{BVerbatim}
+% \hspace{1.5cm}
+% \begin{scope}
+% \NiceMatrixOptions{NullifyDots}
+% $\begin{pNiceMatrix}
+% a & b & 0 & & \Cdots & 0 \\
+% b & a & b & \Ddots & & \Vdots \\
+% 0 & b & a & \Ddots & & \\
+% & \Ddots & \Ddots & \Ddots & & 0 \\
+% \Vdots & & & & & b \\
+% 0 & \Cdots & & 0 & b & a
+% \end{pNiceMatrix}$
+% \end{scope}
+%
+% \vspace{2cm}
+%
+% A permutation matrix :
+%
+% \bigskip
+% \begin{BVerbatim}[baseline=c]
+% $\begin{pNiceMatrix}
+% 0 & 1 & 0 & & \Cdots & 0 \\
+% \Vdots & & & \Ddots & & \Vdots \\
+% & & & \Ddots & & \\
+% & & & \Ddots & & 0 \\
+% 0 & 0 & & & & 1 \\
+% 1 & 0 & & \Cdots & & 0
+% \end{pNiceMatrix}$
+% \end{BVerbatim}
+% \hspace{2.5cm}
+% $\begin{pNiceMatrix}
+% 0 & 1 & 0 & & \Cdots & 0 \\
+% \Vdots & & & \Ddots & & \Vdots \\
+% & & & \Ddots & & \\
+% & & & \Ddots & & 0 \\
+% 0 & 0 & & & & 1 \\
+% 1 & 0 & & \Cdots & & 0
+% \end{pNiceMatrix}$
+%
+% \vspace{2cm}
+%
+% An example with |\Iddots|:
+%
+% \bigskip
+% \begin{BVerbatim}[baseline=c]
+% $\begin{pNiceMatrix}
+% 1 & \Cdots & & 1 \\
+% \Vdots & & & 0 \\
+% & ~emphase#\Iddots@ & ~emphase#\Iddots@ & \Vdots \\
+% 1 & 0 & \Cdots & 0
+% \end{pNiceMatrix}$
+% \end{BVerbatim}
+% \hspace{4cm}
+% $\begin{pNiceMatrix}
+% 1 & \Cdots & & 1 \\
+% \Vdots & & & 0 \\
+% & \Iddots & \Iddots & \Vdots \\
+% 1 & 0 & \Cdots & 0
+% \end{pNiceMatrix}$
+%
+%
+%
+% \vspace{1cm}
+%
+% \section{Implementation}
+%
+% \subsection{Declaration of the package and extensions loaded}
+%
+%
+% First, Tikz and the Tikz libraries \pkg{calc} and \pkg{math} are loaded before the |\ProvidesExplPackage|. They
+% are loaded this way because |\usetikzlibrary| in |expl3| code fails.\footnote{cf.
+% |tex.stackexchange.com/questions/57424/using-of-usetikzlibrary-in-an-expl3-package-fails|}
+%
+% \begin{macrocode}
+\RequirePackage{tikz}
+\usetikzlibrary{calc,math}
+% \end{macrocode}
+%
+% \bigskip
+% Then, we can give the traditionnal declaration of a package written with |expl3|:
+% \begin{macrocode}
+\RequirePackage{l3keys2e}
+\ProvidesExplPackage
+ {nicematrix}
+ {\myfiledate}
+ {\myfileversion}
+ {Draws nice dotted lines in matrix environments}
+% \end{macrocode}
+%
+% The command for the treatment of the options of |\usepackage| is at the end of this package for technical reasons.
+%
+% \bigskip
+% We load \pkg{array} and \pkg{mathtools} (\pkg{mathtools} may be considered as the successor of \pkg{amsmath}).
+% \begin{macrocode}
+\RequirePackage{array}
+\RequirePackage{mathtools}
+% \end{macrocode}
+%
+% \bigskip
+% The package \pkg{xparse} will be used to define the environment |{NiceMatrix}|, its variants and the
+% document-level commands (|\NiceMatrixOptions|, etc.).
+% \begin{macrocode}
+\RequirePackage{xparse}
+% \end{macrocode}
+%
+% \bigskip
+% \subsection{Technical definitions}
+%
+% First, we define a command |\iddots| similar to |\ddots| ($\ddots$) but with dots going forward ($\iddots$). We
+% use |\ProvideDocumentCommand|, and so, if the command |\iddots| has already been defined (for example by the
+% package \pkg{mathdots}), we don't define it again.
+%
+% \begin{macrocode}
+\ProvideDocumentCommand \iddots {}
+ {\mathinner{\mkern 1mu
+ \raise 1pt \hbox{.}
+ \mkern 2mu
+ \raise 4pt\hbox{.}
+ \mkern 2mu
+ \raise7pt \vbox{\kern 7pt
+ \hbox{.}}
+ \mkern1mu}}
+% \end{macrocode}
+%
+% This definition is a variant of the standard definition of |\ddots|.
+%
+% \bigskip
+% In the environment |{NiceMatrix}|, the command |\multicolumn| will be linked to the following command
+% |\@@_multicolumn:| but only if the option |RenewMatrix| is not set. Indeed, if the option |RenewMatrix| is used,
+% we want to let the possibility to the user to use |\multicolumn| (or |\hdotsfor| of \pkg{amsmath}) in some
+% matrices without dotted lines and to have the automatic dotted lines of \pkg{nicematrix} in other matrices.
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_multicolumn:nn
+ {\msg_error:nn {nicematrix} {multicolumn~forbidden}}
+% \end{macrocode}
+% This command |\@@_multicolumn:nn| takes two arguments, and therefore, the first two arguments of |\column| will
+% be gobbled.
+%
+% \bigskip
+% The following counter will count the environments |{NiceMatrix}|. The value of this counter will be used to
+% prefix the names of the Tikz nodes created in the matrix.
+% \begin{macrocode}
+\int_new:N \g_@@_env_int
+% \end{macrocode}
+%
+% \bigskip
+% \subsection{The options}
+%
+% The flag |\l_@@_parallelize_diags_bool| controls wether the diagonals are parallelized. The default
+% is~|true|.
+% \begin{macrocode}
+\bool_new:N \l_@@_parallelize_diags_bool
+\bool_set_true:N \l_@@_parallelize_diags_bool
+% \end{macrocode}
+%
+% \bigskip
+% The flag |\l_@@_nullify_dots_bool| corresponds to the option |NullifyDots|. When the flag is down, the
+% instructions like |\vdots| are inserted within a |\hphantom| (and so the constructed matrix has exactly the same
+% size as a matrix constructed with the classical |{matrix}| and |\ldots|, |\vdots|, etc.)
+% \begin{macrocode}
+\bool_new:N \l_@@_nullify_dots_bool
+% \end{macrocode}
+%
+% \bigskip
+% The flag |\l_@@_renew_matrix_bool| will be raised if the option |RenewMatrix| is used.
+% \begin{macrocode}
+\bool_new:N \l_@@_renew_matrix_bool
+% \end{macrocode}
+%
+% \bigskip
+% We define a set of options which will be used with the command |NiceMatrixOptions|.
+% \begin{macrocode}
+\keys_define:nn {NiceMatrix}
+ {ParallelizeDiagonals .bool_set:N = \l_@@_parallelize_diags_bool,
+ ParallelizeDiagonals .default:n = true,
+% \end{macrocode}
+%
+% \bigskip
+% With the option |RenewDots|, the command |\cdots|, |\ldots|, |\vdots| and |\ddots| are redefined and behave like the
+% commands |\Cdots|, |\Ldots|, |\Vdots| and |\Ddots|.
+% \begin{macrocode}
+ RenewDots .bool_set:N = \l_@@_renew_dots_bool,
+ RenewDots .default:n = true,
+% \end{macrocode}
+%
+% \bigskip
+% With the option |RenewMatrix|, the environment |{matrix}| of \pkg{amsmath} and its variants are redefined to
+% behave like the environment |{NiceMatrix}| and its variants.
+% \begin{macrocode}
+ RenewMatrix .code:n = {\cs_set_eq:NN \env@matrix \NiceMatrix
+ \bool_set_true:N \l_@@_renew_matrix_bool},
+ RenewMatrix .default:n = true,
+ Transparent .meta:n = {RenewDots,RenewMatrix},
+ Transparent .value_forbidden:n = true,
+% \end{macrocode}
+%
+% \bigskip
+% Without the option |NullifyDots|, the instructions like |\vdots| are inserted within a
+% |\hphantom| (and so the constructed matrix has exactly the same size as a matrix constructed with the
+% classical |{matrix}| and |\ldots|, |\vdots|, etc.). This option is set by default.
+% \begin{macrocode}
+ NullifyDots .bool_set:N = \l_@@_nullify_dots_bool ,
+ NullifyDots .default:n = true}
+% \end{macrocode}
+%
+% \bigskip
+% |\NiceMatrixOptions| is the command of the \pkg{nicematrix} package to fix options at the document level. The
+% scope of these specification is the current TeX group.
+% \begin{macrocode}
+\NewDocumentCommand \NiceMatrixOptions {m}
+ {\keys_set:nn {NiceMatrix} {#1}}
+% \end{macrocode}
+%
+% \bigskip
+% \subsection{The main functions}
+%
+% The pseudo-environment |\@@_Cell:|--|\@@_end_Cell:| is used to format the cells of the array (except the cells of
+% the first column: see below).
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_Cell:
+ {
+% \end{macrocode}
+% We increment |\g_@@_column_int|, which is the counter of the columns. We need a global affectation because this
+% command will be used in the cell of a |\halign| (via an environment |{array}|).
+% \begin{macrocode}
+ \int_gincr:N \g_@@_column_int
+% \end{macrocode}
+% At the end of the array, the counter |\g_@@_nb_column_int| will contain the total number of columns of the array
+% (even if all the lines don't have the same number of ampersands).
+% \begin{macrocode}
+ \int_gset:Nn \g_@@_nb_column_int {\int_max:nn \g_@@_nb_column_int \g_@@_column_int}
+% \end{macrocode}
+% We create a Tikz node for the current cell of the array.
+% \begin{macrocode}
+ \tikz[remember~picture, inner~sep = 0pt, minimum~width = 0pt, baseline]
+ \node [anchor=base] (nm-\int_use:N \g_@@_env_int-
+ \int_use:N \g_@@_line_int-
+ \int_use:N \g_@@_column_int)
+ \bgroup $} % $
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_end_Cell:
+ {$\egroup ;} % $
+% \end{macrocode}
+%
+% \interitem
+% The pseudo-environment |\@@_Cell_First_Column:|--|\@@_end_Cell:| is used to format the cells of the first column
+% of the array. For such a column, we have to increment the counter of the lines (|\g_@@_line_int|) and to
+% initialize the counter of the columns (|\g_@@_column_int|).
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_Cell_First_Column:
+ {\int_gincr:N \g_@@_line_int
+ \int_gset:Nn \g_@@_column_int 0
+ \@@_Cell:}
+% \end{macrocode}
+%
+%
+% \interitem
+% The environment |{NiceMatrix}| is the main environment of the package |nicematrix|. This environment creates an
+% array similar to the array created by the environment |{matrix}| of \pkg{amsmath} but with Tikz nodes for each
+% cell of the matrix.
+% \begin{macrocode}
+\NewDocumentEnvironment {NiceMatrix} {}
+ {
+% \end{macrocode}
+% We use a |\aftergroup| to execute |\@@_draw_lines| at the end of the environment (all the LaTeX environments are
+% TeX groups). With this technic, the second part of the environment is the same that the second part of the
+% environment |{matrix}| of \pkg{amsmath}. Therefore, it's easier to redefine the environment |{matrix}| (when the
+% option |RenewMatrix| is used).
+% \begin{macrocode}
+ \aftergroup \@@_draw_lines:
+% \end{macrocode}
+%
+% The commands |\Ldots|, |\Cdots|, etc. will be defined only within the environment |{NiceMatrix}|.
+% \begin{macrocode}
+ \cs_set_eq:NN \Ldots \@@_Ldots
+ \cs_set_eq:NN \Cdots \@@_Cdots
+ \cs_set_eq:NN \Vdots \@@_Vdots
+ \cs_set_eq:NN \Ddots \@@_Ddots
+ \cs_set_eq:NN \Iddots \@@_Iddots
+ \cs_set_eq:NN \Hspace \@@_Hspace:
+ \cs_set_eq:NN \NiceMatrixEndPoint \@@_NiceMatrixEndPoint:
+ \bool_if:NF \l_@@_renew_matrix_bool
+ {\cs_set_eq:NN \multicolumn \@@_multicolumn:nn}
+% \end{macrocode}
+% If the option |RenewDots| is used, we redefine the commands |\ldots|, |\cdots|, etc.
+% \begin{macrocode}
+ \bool_if:NT \l_@@_renew_dots_bool
+ {\cs_set_eq:NN \ldots \@@_Ldots
+ \cs_set_eq:NN \cdots \@@_Cdots
+ \cs_set_eq:NN \vdots \@@_Vdots
+ \cs_set_eq:NN \ddots \@@_Ddots
+ \cs_set_eq:NN \iddots \@@_Iddots
+ \cs_set_eq:NN \dots \@@_Ldots}
+% \end{macrocode}
+%
+% We increment the counter |\g_@@_env_int| which counts the environments |{NiceMatrix}|.
+% \begin{macrocode}
+ \int_gincr:N \g_@@_env_int
+% \end{macrocode}
+%
+% The sequence |\g_@@_empty_cells_seq| will contains a list of ``empty'' cells (not all the empty cells of the
+% matrix). If we want to indicate that the cell in line~$i$ and line~$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 counter |\g_@@_instruction_int| will count the instructions (|\Cdots|, |\Vdots|, |\Ddots|, etc.) in the matrix.
+% \begin{macrocode}
+ \int_gzero_new:N \g_@@_instruction_int
+% \end{macrocode}
+% The counter |\g_@@_line_int| will be used to count the lines of the array. At the end of the environment
+% |{array}|, this counter will give the total number of lines of the matrix.
+% \begin{macrocode}
+ \int_gzero_new:N \g_@@_line_int
+% \end{macrocode}
+% The counter |\g_@@_column_int| will be used to count the colums of the array. Since we want to known the total
+% number of columns of the matrix, we also create a counter |\g_@@_nb_column_int|. These counters are updated in
+% the command |\@@_Cell:| executed at the beginning of each cell.
+% \begin{macrocode}
+ \int_gzero_new:N \g_@@_column_int
+ \int_gzero_new:N \g_@@_nb_column_int
+% \end{macrocode}
+% The next two lines are the same as in the command |\env@matrix| of \pkg{amsmath} on which all the matrix
+% constructions are built.
+% \begin{macrocode}
+ \hskip -\arraycolsep
+ \cs_set_eq:NN \@ifnextchar \new@ifnextchar
+% \end{macrocode}
+% Eventually, the environment |{NiceMatrix}| is defined upon the environment |{array}|. We maintain the
+% signification of the counter |\c@MaxMatrixCols| of \pkg{amsmath}.
+% \begin{macrocode}
+ \int_set:Nn \l_tmpa_int {\c@MaxMatrixCols - 1}
+ \array{>{\@@_Cell_First_Column:}c<{\@@_end_Cell:}
+ *\l_tmpa_int{>{\@@_Cell:}c<{\@@_end_Cell:}}}}
+% \end{macrocode}
+% \bigskip
+% The second part of the environment |{NiceMatrix}| is the same as the second part of the environment |{matrix}| of
+% \pkg{amsmath}. However, at the end of the environment, the instruction |\@@_draw_lines:| will
+% be executed because we have put a ``|\aftergroup \@@_draw_lines:|'' in the beginning of the environment
+% (therefore, it's possible to implement the option |RenewMatrix| with |\cs_set_eq:NN \env@matrix \NiceMatrix|).
+% \begin{macrocode}
+ {\endarray
+ \hskip -\arraycolsep}
+% \end{macrocode}
+%
+% \interitem
+% We create the variants of the environment |{NiceMatrix}|.
+% \begin{macrocode}
+\NewDocumentEnvironment {pNiceMatrix} {}
+ {\left(\begin{NiceMatrix}}
+ {\end{NiceMatrix}\right)}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\NewDocumentEnvironment {bNiceMatrix} {}
+ {\left[\begin{NiceMatrix}}
+ {\end{NiceMatrix}\right]}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\NewDocumentEnvironment {BNiceMatrix} {}
+ {\left\{\begin{NiceMatrix}}
+ {\end{BNiceMatrix}\right\}}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\NewDocumentEnvironment {vNiceMatrix} {}
+ {\left\lvert\begin{NiceMatrix}}
+ {\end{BNiceMatrix}\right\rvert}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\NewDocumentEnvironment {VNiceMatrix} {}
+ {\left\lVert\begin{NiceMatrix}}
+ {\end{BNiceMatrix}\right\rVert}
+% \end{macrocode}
+%
+% \interitem
+% The conditionnal |\@@_if_not_empty_cell:nnT| test wether a cell is empty. The first two arguments must be LaTeX3
+% counters for the row and the column of the considered cell.
+% \begin{macrocode}
+\prg_set_conditional:Npnn \@@_if_not_empty_cell:nn #1#2 {T}
+% \end{macrocode}
+% If the cell is a 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 wether we are in this situation considering the correspondant Tikz node.
+% \begin{macrocode}
+ {\cs_if_exist:cTF {pgf@sh@ns@nm-
+ \int_use:N \g_@@_env_int-
+ \int_use:N #1-
+ \int_use:N #2}
+% \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 explicitely declared empty for some reason. It's easy to check if the
+% current cell is in this list.
+% \begin{macrocode}
+ {\seq_if_in:NxTF \g_@@_empty_cells_seq
+ {\int_use:N #1-\int_use:N #2}
+ {\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 |\tikz| but, in fact, nothing is drawn.
+% \begin{macrocode}
+ {\tikz[remember~picture]
+ \path let \p1 = (nm-
+ \int_use:N \g_@@_env_int-
+ \int_use:N #1-
+ \int_use:N #2.east),
+ \p2 = (nm-
+ \int_use:N \g_@@_env_int-
+ \int_use:N #1-
+ \int_use:N #2.west)
+ in \pgfextra {\dim_gset:Nn \g_tmpa_dim {\x1}
+ \dim_gset:Nn \g_tmpb_dim {\x2}} ;
+% \end{macrocode}
+% We compute in |\g_tmpa_dim| the width of the Tikz node.
+% \begin{macrocode}
+ \dim_gsub:Nn \g_tmpa_dim \g_tmpb_dim
+ \dim_compare:nNnTF {\dim_abs:n \g_tmpa_dim} < {0.5 pt}
+ {\prg_return_false:}
+ {\prg_return_true:}}}
+ {\prg_return_false:}
+ }
+% \end{macrocode}
+%
+% \interitem
+% For each drawing instruction in the matrix (like |\Cdots|, etc.), we create a global property list to store the
+% informations corresponding to the instruction. Such an property list will have three fields:
+% \begin{itemize}
+% \item a field ``type'' with the type of the instruction (|cdots|, |vdots|, |ddots|, etc.);
+% \item a field ``line'' with the number of the line of the matrix where the instruction appeared;
+% \item a field ``column'' with the number of the column of the matrix where the instruction appeared.
+% \end{itemize}
+%
+% \interitem
+% The argument of the following command |\@@_instruction_of_type:n| is the type of the instruction (|cdots|,
+% |vdots|, |ddots|, etc.). This command creates the corresponding property list.
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_instruction_of_type:n
+% \end{macrocode}
+% First, we increment the counter of the instructions (this counter is initialized in the beginning of the
+% environment |{NiceMatrix}|). This incrementation is global because the command will be used in the cell of a |\halign|).
+% \begin{macrocode}
+ {\int_gincr:N \g_@@_instruction_int
+ \prop_put:Nnn \l_tmpa_prop {type} {#1}
+ \prop_put:NnV \l_tmpa_prop {line} \g_@@_line_int
+ \prop_put:NnV \l_tmpa_prop {column} \g_@@_column_int
+% \end{macrocode}
+% The property list has been created in a local variable for convenience. Now, it will be stored in a
+% global variable indicating the number of the instruction.
+% \begin{macrocode}
+ \prop_gclear_new:c
+ {g_@@_instruction_\int_use:N\g_@@_instruction_int _prop}
+ \prop_gset_eq:cN
+ {g_@@_instruction_\int_use:N\g_@@_instruction_int _prop}
+ \l_tmpa_prop
+ }
+% \end{macrocode}
+%
+%
+% \bigskip
+% \subsection{We draw the lines in the matrix}
+
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_draw_lines:
+ {
+% \end{macrocode}
+%
+% The sequence |\l_@@_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_clear_new:N \l_@@_yet_drawn_seq
+% \end{macrocode}
+%
+%
+% The following variables will be used further.
+% \begin{macrocode}
+ \int_zero_new:N \l_@@_type_int
+ \int_zero_new:N \l_@@_line_int
+ \int_zero_new:N \l_@@_column_int
+ \int_zero_new:N \l_@@_di_int
+ \int_zero_new:N \l_@@_dj_int
+% \end{macrocode}
+%
+% By befault, the diagonal lines will be parallelized\footnote{It's possible to use the option
+% |ParallelizeDiagonals| to disable this parallelization.}. There are two types of diagonals lines: the $|\Ddots|$
+% diagonals and the |\Iddots| diagonals. We have to count the both types in order to known wether a diagonal is the
+% first of its type in the current |{NiceMatrix}| environment.
+% \begin{macrocode}
+ \bool_if:NT \l_@@_parallelize_diags_bool
+ {\int_zero_new:N \l_@@_ddots_int
+ \int_zero_new:N \l_@@_iddots_int
+% \end{macrocode}
+%
+% The dimensions |\l_@@_delta_x_one_dim| and |\l_@@_delta_y_one_dim| will contains the $\Delta_x$ and $\Delta_y$ of the
+% first |\Ddots| diagonal. We have to store these values in order to draw the others |\Ddots| diagonals parallel to
+% the first one. Similarly |\l_@@_delta_x_two_dim| and |\l_@@_delta_y_two_dim| are the $\Delta_x$ and $\Delta_y$ of
+% the first |\Iddots| diagonal.
+% \begin{macrocode}
+ \dim_zero_new:N \l_@@_delta_x_one_dim
+ \dim_zero_new:N \l_@@_delta_y_one_dim
+ \dim_zero_new:N \l_@@_delta_x_two_dim
+ \dim_zero_new:N \l_@@_delta_y_two_dim}
+% \end{macrocode}
+%
+% \interitem
+% The counter |\l_@@_instruction_int| will be the index of the loop over the instructions. The first value is~$1$.
+% \begin{macrocode}
+ \int_zero_new:N \l_@@_instruction_int
+ \int_incr:N \l_@@_instruction_int
+% \end{macrocode}
+%
+% \interitem
+% We begin the loop over the instructions (the incrementation is at the end of the loop).
+% \begin{macrocode}
+ \int_until_do:nNnn \l_@@_instruction_int > \g_@@_instruction_int
+ {
+% \end{macrocode}
+%
+% \interitem
+% We extract from the property list of the current instruction the fields ``type'', ``line'' and ``column''and we
+% store these values. We have to do a conversion because the components of a property list are token lists (and not
+% integers).
+% \begin{macrocode}
+ \prop_get:cnN {g_@@_instruction_\int_use:N \l_@@_instruction_int _prop}
+ {type} \l_tmpa_tl
+ \int_set:Nn \l_@@_type_int {\l_tmpa_tl}
+ \prop_get:cnN {g_@@_instruction_\int_use:N \l_@@_instruction_int _prop}
+ {line} \l_tmpa_tl
+ \int_set:Nn \l_@@_line_int {\l_tmpa_tl}
+ \prop_get:cnN {g_@@_instruction_\int_use:N \l_@@_instruction_int _prop}
+ {column} \l_tmpa_tl
+ \int_set:Nn \l_@@_column_int {\l_tmpa_tl}
+% \end{macrocode}
+%
+% \interitem
+% We fix the values of |\l_@@_di_int| and |\l_@@_dj_int| which indicate the direction of the dotted line to draw in
+% the matrix.
+% \begin{macrocode}
+ \int_case:nn \l_@@_type_int
+ { 0 {\int_set:Nn \l_@@_di_int 0
+ \int_set:Nn \l_@@_dj_int 1}
+ 1 {\int_set:Nn \l_@@_di_int 0
+ \int_set:Nn \l_@@_dj_int 1}
+ 2 {\int_set:Nn \l_@@_di_int 1
+ \int_set:Nn \l_@@_dj_int 0}
+ 3 {\int_set:Nn \l_@@_di_int 1
+ \int_set:Nn \l_@@_dj_int 1}
+ 4 {\int_set:Nn \l_@@_di_int 1
+ \int_set:Nn \l_@@_dj_int {-1}}}
+% \end{macrocode}
+%
+% \interitem
+% An instruction for a dotted line must have a initial cell and a final cell which are both not empty. If it's not
+% the case, the instruction is said \emph{impossible}. An error will be raised if an impossible instruction is
+% encountered.
+% \begin{macrocode}
+ \bool_if_exist:NTF \l_@@_impossible_instruction_bool
+ {\bool_set_false:N \l_@@_impossible_instruction_bool}
+ {\bool_new:N \l_@@_impossible_instruction_bool}
+% \end{macrocode}
+%
+% \interitem
+% We will determine |\l_@@_final_i_int| and |\l_@@_final_j_int| which will be the ``coordinates'' of the end of the
+% dotted line we have to draw.
+% \begin{macrocode}
+ \int_zero_new:N \l_@@_final_i_int
+ \int_zero_new:N \l_@@_final_j_int
+ \int_set:Nn \l_@@_final_i_int \l_@@_line_int
+ \int_set:Nn \l_@@_final_j_int \l_@@_column_int
+ \bool_if_exist:NTF \l_@@_stop_loop_bool
+ {\bool_set_false:N \l_@@_stop_loop_bool}
+ {\bool_new:N \l_@@_stop_loop_bool}
+ \bool_do_until:Nn \l_@@_stop_loop_bool
+ {\int_add:Nn \l_@@_final_i_int \l_@@_di_int
+ \int_add:Nn \l_@@_final_j_int \l_@@_dj_int
+% \end{macrocode}
+% We test if we are still in the matrix.
+% \begin{macrocode}
+ \bool_if:nTF { \int_compare_p:nNn \l_@@_final_i_int < 1
+ || \int_compare_p:nNn \l_@@_final_i_int > \g_@@_line_int
+ || \int_compare_p:nNn \l_@@_final_j_int < 1
+ || \int_compare_p:nNn \l_@@_final_j_int > \g_@@_nb_column_int}
+% \end{macrocode}
+% If we are outside the matrix, the instruction is impossible and, of course, we stop the loop.
+% \begin{macrocode}
+ {\bool_set_true:N \l_@@_impossible_instruction_bool
+ \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 |\l_@@_final_i_int| and |\l_@@_final_j_int|.
+% \begin{macrocode}
+ {\@@_if_not_empty_cell:nnT \l_@@_final_i_int \l_@@_final_j_int
+ {\bool_set_true:N \l_@@_stop_loop_bool}}
+ }
+% \end{macrocode}
+%
+% \interitem
+% We will determine |\l_@@_initial_i_int| and |\l_@@_initial_j_int| which will be the ``coordinates'' of the
+% beginning of the dotted line we have to draw. The programmation is similar to the previous one.
+% \begin{macrocode}
+ \int_zero_new:N \l_@@_initial_i_int
+ \int_zero_new:N \l_@@_initial_j_int
+ \int_set:Nn \l_@@_initial_i_int \l_@@_line_int
+ \int_set:Nn \l_@@_initial_j_int \l_@@_column_int
+% \end{macrocode}
+% If we known that the instruction is impossible (because it was not possible to found the correct value for
+% |\l_@@_final_i_int| and |\l_@@_final_j_int|), we don't do this loop.
+% \begin{macrocode}
+ \bool_set_eq:NN \l_@@_stop_loop_bool \l_@@_impossible_instruction_bool
+ \bool_do_until:Nn \l_@@_stop_loop_bool
+ {\int_sub:Nn \l_@@_initial_i_int \l_@@_di_int
+ \int_sub:Nn \l_@@_initial_j_int \l_@@_dj_int
+ \bool_if:nTF
+ { \int_compare_p:nNn \l_@@_initial_i_int < 1
+ || \int_compare_p:nNn \l_@@_initial_i_int > \g_@@_line_int
+ || \int_compare_p:nNn \l_@@_initial_j_int < 1
+ || \int_compare_p:nNn \l_@@_initial_j_int > \g_@@_nb_column_int}
+ {\bool_set_true:N \l_@@_impossible_instruction_bool
+ \bool_set_true:N \l_@@_stop_loop_bool}
+ {\@@_if_not_empty_cell:nnT \l_@@_initial_i_int \l_@@_initial_j_int
+ {\bool_set_true:N \l_@@_stop_loop_bool}}
+ }
+% \end{macrocode}
+%
+% \interitem
+% Now, we can determine wether we have to draw a line.
+% If the line is impossible, of course, we won't draw any line.
+% \begin{macrocode}
+ \bool_if:NTF \l_@@_impossible_instruction_bool
+ {\msg_error:nn {nicematrix} {Impossible~instruction}}
+% \end{macrocode}
+%
+% If the dotted line to draw is in the list of the previously drawn lines (|\l_@@_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$-uplet
+% characteristic of the line.
+% \begin{macrocode}
+ {\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:NVF \l_@@_yet_drawn_seq \l_tmpa_tl
+% \end{macrocode}
+%
+% If the dotted line to draw is not in the list, we add it the list |\l_@@_yet_drawn_seq|.
+% \begin{macrocode}
+ {\seq_put_left:NV \l_@@_yet_drawn_seq \l_tmpa_tl
+% \end{macrocode}
+%
+% \medskip
+% The four following variables are global because we will have to do affectations in a Tikz instruction (in order
+% to extract the coordinates of two extremities of the line to draw).
+% \begin{macrocode}
+ \dim_zero_new:N \g_@@_x_initial_dim
+ \dim_zero_new:N \g_@@_y_initial_dim
+ \dim_zero_new:N \g_@@_x_final_dim
+ \dim_zero_new:N \g_@@_y_final_dim
+% \end{macrocode}
+%
+%
+% We draw the line.
+% \begin{macrocode}
+ \int_case:nn \l_@@_type_int
+ {0 \@@_draw_ldots_line:
+ 1 \@@_draw_cdots_line:
+ 2 \@@_draw_vdots_line:
+ 3 \@@_draw_ddots_line:
+ 4 \@@_draw_iddots_line:}}}
+% \end{macrocode}
+%
+% \bigskip
+% Incrementation of the index of the loop (and end of the loop).
+% \begin{macrocode}
+ \int_incr:N \l_@@_instruction_int
+ }
+}
+% \end{macrocode}
+%
+%
+% \interitem
+% The command |\@@_retrieve_coords:nn| retrieves the Tikz coordinates of the two extremities of the dotted line we
+% will have to draw \footnote{In fact, with diagonals lines, a adjustment of one of the coordinates may be done.}.
+% This command has four implicit arguments which are |\l_@@_initial_i_int|, |\l_@@_initial_j_int|,
+% |\l_@@_final_i_int| and |\l_@@_final_j_int|.
+%
+% The two arguments of the command |\@@_retrieve_coords:nn| are the anchors that must be used for the two nodes.
+% These anchors must be given with the point (e.g.: |.north|, |.south|, etc.).
+%
+% The coordinates are stored in |\g_@@_x_initial_dim|, |\g_@@_y_initial_dim|, |\g_@@_x_final_dim|,
+% |\g_@@_y_final_dim|. These variables are global for technical reasons: we have to do an affectation in a Tikz
+% picture.
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_retrieve_coords:nn
+ {\tikz[remember~picture]
+ \path let \p1 = (nm-\int_use:N \g_@@_env_int-
+ \int_use:N \l_@@_initial_i_int-
+ \int_use:N \l_@@_initial_j_int #1),
+ \p2 = (nm-\int_use:N \g_@@_env_int-
+ \int_use:N \l_@@_final_i_int-
+ \int_use:N \l_@@_final_j_int #2)
+ in \pgfextra {\dim_gset:Nn \g_@@_x_initial_dim {\x1}
+ \dim_gset:Nn \g_@@_y_initial_dim {\y1}
+ \dim_gset:Nn \g_@@_x_final_dim {\x2}
+ \dim_gset:Nn \g_@@_y_final_dim {\y2}} ; }
+% \end{macrocode}
+%
+% \interitem
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_draw_ldots_line:
+ {\@@_retrieve_coords:nn {.south~east} {.south~west}
+ \@@_draw_tikz_line:}
+% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_draw_cdots_line:
+ {\@@_retrieve_coords:nn {.mid~east} {.mid~west}
+ \@@_draw_tikz_line:}
+% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_draw_vdots_line:
+ {\@@_retrieve_coords:nn {.south} {.north}
+ \@@_draw_tikz_line:}
+% \end{macrocode}
+%
+% \interitem
+% For the diagonal lines, the situation is a bit more complicated because, by default, we parallelize the diagonals
+% lines. The first diagonal line is drawn and then, all the other diagonal lines are drawn parallel to the first
+% one.
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_draw_ddots_line:
+ {\@@_retrieve_coords:nn {.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
+% \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 = 1
+% \end{macrocode}
+% If the diagonal line is the first one, we have no adjustment of the line to do but we store the $\Delta_x$ and the
+% $\Delta_y$ of the line because these values will be used to draw the others diagonal lines parallels to the first one.
+% \begin{macrocode}
+ {\dim_set:Nn \l_@@_delta_x_one_dim {\g_@@_x_final_dim - \g_@@_x_initial_dim }
+ \dim_set:Nn \l_@@_delta_y_one_dim {\g_@@_y_final_dim - \g_@@_y_initial_dim }}
+% \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 }}}
+% \end{macrocode}
+% Now, we can draw the dotted line (after a possible change of |\g_@@_y_initial_dim|).
+% \begin{macrocode}
+ \@@_draw_tikz_line:}
+% \end{macrocode}
+%
+% \bigskip
+% We draw the |\Iddots| diagonals in the same way.
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_draw_iddots_line:
+ {\_@@_retrieve_coords:nn {.south~west} {.north~east}
+ \bool_if:NT \l_@@_parallelize_diags_bool
+ {\int_incr:N \l_@@_iddots_int
+ \int_compare:nNnTF \l_@@_iddots_int = 1
+ {\dim_set:Nn \l_@@_delta_x_two_dim {\g_@@_x_final_dim - \g_@@_x_initial_dim }
+ \dim_set:Nn \l_@@_delta_y_two_dim {\g_@@_y_final_dim - \g_@@_y_initial_dim }}
+ {\dim_gset:Nn \g_@@_y_final_dim
+ {\g_@@_y_initial_dim +
+ (\g_@@_x_final_dim - \g_@@_x_initial_dim)
+ * \dim_ratio:nn \l_@@_delta_y_two_dim \l_@@_delta_x_two_dim }}}
+ \@@_draw_tikz_line:}
+% \end{macrocode}
+%
+% \bigskip
+% \subsection{The actual instructions for drawing the dotted line with Tikz}
+%
+% The command |\@@_draw_tikz_line:| draws the line using four implicit arguments:
+%
+% \quad |\g_@@_x_initial_dim|, |\g_@@_y_initial_dim|, |\g_@@_x_final_dim| and |\g_@@_y_final_dim|.
+
+% These variables are global for technical reasons: we have to do affectations in an instruction |\tikz|.
+%
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_draw_tikz_line:
+ {\begin{tikzpicture}[overlay]
+ \tikzmath{
+ coordinate~\a , \b ;
+ real~\l, \x, \d ;
+ integer~\n ;
+ \a = (\g_@@_x_initial_dim, \g_@@_y_initial_dim) ;
+ \b = (\g_@@_x_final_dim, \g_@@_y_final_dim) ;
+ \l = veclen(\bx-\ax,\by-\ay) ;
+ \n = (\l - 0.54em)/(0.45em) ;
+ \x = (\l - \n*0.45em)/(2*\l) ;
+ \d = 0.45em / \l ;
+ if~\n>0
+ then~{ for~\k in~{0,...,\n}
+ { {\node at ($(\a)!\x+\k*\d!(\b)$) {.} ; } ; } ;
+ } ;
+ }
+ \end{tikzpicture}}
+% \end{macrocode}
+%
+% \bigskip
+% \subsection{User commands available in environments {NiceMatrix}}
+%
+% We give new names for the commands |\ldots|, |\cdots|, |\vdots| and |\ddots| because these commands will be
+% redefined (if the option |RenewDots| is used).
+% \begin{macrocode}
+\cs_set_eq:NN \@@_ldots \ldots
+\cs_set_eq:NN \@@_cdots \cdots
+\cs_set_eq:NN \@@_vdots \vdots
+\cs_set_eq:NN \@@_ddots \ddots
+\cs_set_eq:NN \@@_iddots \iddots
+% \end{macrocode}
+%
+% \interitem
+% The command |\@@_add_to_empty_cells:| adds the current cell to |\g_@@_empty_cells_seq| which is the list of the
+% empty cells (the cells explicitly declared ``empty'': there may be, of course, other empty cells in the matrix).
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_add_to_empty_cells:
+ {\seq_gput_right:Nx \g_@@_empty_cells_seq
+ {\int_use:N \g_@@_line_int-
+ \int_use:N \g_@@_column_int}}
+% \end{macrocode}
+%
+% \interitem
+% The commands |\@@_Ldots|, |\@@_Cdots|, |\@@_Vdots|, |\@@_Ddots| and |\@@_Iddots| will be linked to |\Ldots|,
+% |\Cdots|, |\Vdots|, |\Ddots| and |\Iddots| in the environment |{NiceMatrix}|.
+% \begin{macrocode}
+\NewDocumentCommand \@@_Ldots {s}
+ {\IfBooleanF {#1} {\@@_instruction_of_type:n 0}
+ \bool_if:NF \l_@@_nullify_dots_bool {\phantom \@@_ldots}
+ \@@_add_to_empty_cells:}
+% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+\NewDocumentCommand \@@_Cdots {s}
+ {\IfBooleanF {#1} {\@@_instruction_of_type:n 1}
+ \bool_if:NF \l_@@_nullify_dots_bool {\phantom \@@_cdots}
+ \@@_add_to_empty_cells:}
+% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+\NewDocumentCommand \@@_Vdots {s}
+ {\IfBooleanF {#1} {\@@_instruction_of_type:n 2}
+ \bool_if:NF \l_@@_nullify_dots_bool {\phantom \@@_vdots}
+ \@@_add_to_empty_cells:}
+% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+\NewDocumentCommand \@@_Ddots {s}
+ {\IfBooleanF {#1} {\@@_instruction_of_type:n 3}
+ \bool_if:NF \l_@@_nullify_dots_bool {\phantom \@@_ddots}
+ \@@_add_to_empty_cells:}
+% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+\NewDocumentCommand \@@_Iddots {s}
+ {\IfBooleanF {#1} {\@@_instruction_of_type:n 4}
+ \bool_if:NF \l_@@_nullify_dots_bool {\phantom \@@_iddots}
+ \@@_add_to_empty_cells:}
+% \end{macrocode}
+%
+%
+% \bigskip
+% The command |\@@_Hspace:| will be linked to |\hspace| in the environment |{NiceMatrix}|.
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_Hspace:
+ {\@@_add_to_empty_cells:
+ \hspace}
+% \end{macrocode}
+%
+% \bigskip
+% The command |\@@_NiceMatrixEndPoint:| will be linked to |\NiceMatrixEndPoint| in the environment |{NiceMatrix}|.
+% \begin{macrocode}
+\cs_new_protected:Nn \@@_NiceMatrixEndPoint:
+ {\kern 0.5pt}
+% \end{macrocode}
+%
+% \bigskip
+% \subsection{We process the options}
+%
+% We process the options when the package is loaded (with |\usepackage|) but we recommend to use
+% |\NiceMatrixOptions| instead.
+%
+% We must process these options after the definition of the environment |{NiceMatrix}| because the option
+% |RenewMatrix| execute the code |\cs_set_eq:NN \env@matrix \NiceMatrix|.
+%
+% Of course, the command |\NiceMatrix| must be defined before such an instruction is executed.
+% \begin{macrocode}
+\ProcessKeysOptions {NiceMatrix}
+% \end{macrocode}
+%
+%
+% \bigskip
+% \subsection{The error messages}
+% \begin{macrocode}
+\msg_new:nnnn {nicematrix}
+ {Impossible~instruction}
+ {It's~not~possible~to~execute~the~instruction~
+ \int_case:nn \l_@@_type_int
+ {0 {\token_to_str:N \Ldots}
+ 1 {\token_to_str:N \Cdots}
+ 2 {\token_to_str:N \Vdots}
+ 3 {\token_to_str:N \Ddots}}~in~the~line~\int_use:N\l_@@_line_int\
+ ~and~the~column~\int_use:N\l_@@_column_int\space of~the~matrix~
+ because~it's~impossible~to~find~one~of~its~extremities~
+ (both~extremities~must~be~non~empty~cells~of~the~matrix).~
+ If~you~go~on,~the~instruction~will~be~ignored.}
+ {You~can~specify~a~end~of~line~on~a~empty~cell~
+ with~\token_to_str:N \NiceMatrixEndPoint.}
+% \end{macrocode}
+%
+% \begin{macrocode}
+\msg_new:nnn {nicematrix}
+ {multicolumn~forbidden}
+ {The~command~\token_to_str:N \multicolumn\
+ is~forbidden~in~the~environment~\{NiceMatrix\}~
+ and~its~variants.~The~command~\token_to_str:N \hdotsfor\
+ of~amsmath~is~also~forbidden~since~it~uses~
+ \token_to_str:N \multicolumn.~You~can~go~on~but~your~line~will~
+ probably~be~wrong.}
+% \end{macrocode}
+%
+% \endinput
+%
+% Local Variables:
+% TeX-fold-mode: nil
+% End:
diff --git a/Master/texmf-dist/source/latex/nicematrix/nicematrix.ins b/Master/texmf-dist/source/latex/nicematrix/nicematrix.ins
new file mode 100644
index 00000000000..ce8a59e12b8
--- /dev/null
+++ b/Master/texmf-dist/source/latex/nicematrix/nicematrix.ins
@@ -0,0 +1,47 @@
+%%
+%% Copyright (C) 2017 by F. Pantigny
+%%
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either
+%% version 1.3 of this license or (at your option) any later
+%% version. The latest version of this license is in:
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% and version 1.3 or later is part of all distributions of
+%% LaTeX version 2005/12/01 or later.
+%%
+\input l3docstrip.tex
+\keepsilent
+\usedir{tex/latex/nicematrix}
+\preamble
+
+Copyright (C) 2017 by F. Pantigny
+
+This file may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either
+version 1.3 of this license or (at your option) any later
+version. The latest version of this license is in:
+
+ http://www.latex-project.org/lppl.txt
+
+and version 1.3 or later is part of all distributions of
+LaTeX version 2005/12/01 or later.
+
+\endpreamble
+\generate{\file{nicematrix.sty}{\from{nicematrix.dtx}{package}}}
+\Msg{*********************************************************}
+\Msg{*}
+\Msg{* To finish the installation you have to move the}
+\Msg{* following file into a directory searched by TeX:}
+\Msg{*}
+\Msg{* \space\space nicematrix.sty}
+\Msg{*}
+\Msg{* To produce the documentation run the file nicematrix.dtx}
+\Msg{* through XeLaTeX.}
+\Msg{*}
+\Msg{* Happy TeXing!}
+\Msg{*********************************************************}
+\endbatchfile
+
diff --git a/Master/texmf-dist/tex/latex/nicematrix/nicematrix.sty b/Master/texmf-dist/tex/latex/nicematrix/nicematrix.sty
new file mode 100644
index 00000000000..d0c2e771cc6
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/nicematrix/nicematrix.sty
@@ -0,0 +1,386 @@
+%%
+%% This is file `nicematrix.sty',
+%% generated with the docstrip utility.
+%%
+%% The original source files were:
+%%
+%% nicematrix.dtx (with options: `package')
+%%
+%% Copyright (C) 2017 by F. Pantigny
+%%
+%% This file may be distributed and/or modified under the
+%% conditions of the LaTeX Project Public License, either
+%% version 1.3 of this license or (at your option) any later
+%% version. The latest version of this license is in:
+%%
+%% http://www.latex-project.org/lppl.txt
+%%
+%% and version 1.3 or later is part of all distributions of
+%% LaTeX version 2005/12/01 or later.
+%%
+\def\myfileversion{1.0}
+\def\myfiledate{2018/02/13}
+\RequirePackage{tikz}
+\usetikzlibrary{calc,math}
+\RequirePackage{l3keys2e}
+\ProvidesExplPackage
+ {nicematrix}
+ {\myfiledate}
+ {\myfileversion}
+ {Draws nice dotted lines in matrix environments}
+\RequirePackage{array}
+\RequirePackage{mathtools}
+\RequirePackage{xparse}
+\ProvideDocumentCommand \iddots {}
+ {\mathinner{\mkern 1mu
+ \raise 1pt \hbox{.}
+ \mkern 2mu
+ \raise 4pt\hbox{.}
+ \mkern 2mu
+ \raise7pt \vbox{\kern 7pt
+ \hbox{.}}
+ \mkern1mu}}
+\cs_new_protected:Nn \__nm_multicolumn:nn
+ {\msg_error:nn {nicematrix} {multicolumn~forbidden}}
+\int_new:N \g__nm_env_int
+\bool_new:N \l__nm_parallelize_diags_bool
+\bool_set_true:N \l__nm_parallelize_diags_bool
+\bool_new:N \l__nm_nullify_dots_bool
+\bool_new:N \l__nm_renew_matrix_bool
+\keys_define:nn {NiceMatrix}
+ {ParallelizeDiagonals .bool_set:N = \l__nm_parallelize_diags_bool,
+ ParallelizeDiagonals .default:n = true,
+ RenewDots .bool_set:N = \l__nm_renew_dots_bool,
+ RenewDots .default:n = true,
+ RenewMatrix .code:n = {\cs_set_eq:NN \env@matrix \NiceMatrix
+ \bool_set_true:N \l__nm_renew_matrix_bool},
+ RenewMatrix .default:n = true,
+ Transparent .meta:n = {RenewDots,RenewMatrix},
+ Transparent .value_forbidden:n = true,
+ NullifyDots .bool_set:N = \l__nm_nullify_dots_bool ,
+ NullifyDots .default:n = true}
+\NewDocumentCommand \NiceMatrixOptions {m}
+ {\keys_set:nn {NiceMatrix} {#1}}
+\cs_new_protected:Nn \__nm_Cell:
+ {
+ \int_gincr:N \g__nm_column_int
+ \int_gset:Nn \g__nm_nb_column_int {\int_max:nn \g__nm_nb_column_int \g__nm_column_int}
+ \tikz[remember~picture, inner~sep = 0pt, minimum~width = 0pt, baseline]
+ \node [anchor=base] (nm-\int_use:N \g__nm_env_int-
+ \int_use:N \g__nm_line_int-
+ \int_use:N \g__nm_column_int)
+ \bgroup $} % $
+\cs_new_protected:Nn \__nm_end_Cell:
+ {$\egroup ;} % $
+\cs_new_protected:Nn \__nm_Cell_First_Column:
+ {\int_gincr:N \g__nm_line_int
+ \int_gset:Nn \g__nm_column_int 0
+ \__nm_Cell:}
+\NewDocumentEnvironment {NiceMatrix} {}
+ {
+ \aftergroup \__nm_draw_lines:
+ \cs_set_eq:NN \Ldots \__nm_Ldots
+ \cs_set_eq:NN \Cdots \__nm_Cdots
+ \cs_set_eq:NN \Vdots \__nm_Vdots
+ \cs_set_eq:NN \Ddots \__nm_Ddots
+ \cs_set_eq:NN \Iddots \__nm_Iddots
+ \cs_set_eq:NN \Hspace \__nm_Hspace:
+ \cs_set_eq:NN \NiceMatrixEndPoint \__nm_NiceMatrixEndPoint:
+ \bool_if:NF \l__nm_renew_matrix_bool
+ {\cs_set_eq:NN \multicolumn \__nm_multicolumn:nn}
+ \bool_if:NT \l__nm_renew_dots_bool
+ {\cs_set_eq:NN \ldots \__nm_Ldots
+ \cs_set_eq:NN \cdots \__nm_Cdots
+ \cs_set_eq:NN \vdots \__nm_Vdots
+ \cs_set_eq:NN \ddots \__nm_Ddots
+ \cs_set_eq:NN \iddots \__nm_Iddots
+ \cs_set_eq:NN \dots \__nm_Ldots}
+ \int_gincr:N \g__nm_env_int
+ \seq_gclear_new:N \g__nm_empty_cells_seq
+ \int_gzero_new:N \g__nm_instruction_int
+ \int_gzero_new:N \g__nm_line_int
+ \int_gzero_new:N \g__nm_column_int
+ \int_gzero_new:N \g__nm_nb_column_int
+ \hskip -\arraycolsep
+ \cs_set_eq:NN \@ifnextchar \new@ifnextchar
+ \int_set:Nn \l_tmpa_int {\c@MaxMatrixCols - 1}
+ \array{>{\__nm_Cell_First_Column:}c<{\__nm_end_Cell:}
+ *\l_tmpa_int{>{\__nm_Cell:}c<{\__nm_end_Cell:}}}}
+ {\endarray
+ \hskip -\arraycolsep}
+\NewDocumentEnvironment {pNiceMatrix} {}
+ {\left(\begin{NiceMatrix}}
+ {\end{NiceMatrix}\right)}
+\NewDocumentEnvironment {bNiceMatrix} {}
+ {\left[\begin{NiceMatrix}}
+ {\end{NiceMatrix}\right]}
+\NewDocumentEnvironment {BNiceMatrix} {}
+ {\left\{\begin{NiceMatrix}}
+ {\end{BNiceMatrix}\right\}}
+\NewDocumentEnvironment {vNiceMatrix} {}
+ {\left\lvert\begin{NiceMatrix}}
+ {\end{BNiceMatrix}\right\rvert}
+\NewDocumentEnvironment {VNiceMatrix} {}
+ {\left\lVert\begin{NiceMatrix}}
+ {\end{BNiceMatrix}\right\rVert}
+\prg_set_conditional:Npnn \__nm_if_not_empty_cell:nn #1#2 {T}
+ {\cs_if_exist:cTF {pgf@sh@ns@nm-
+ \int_use:N \g__nm_env_int-
+ \int_use:N #1-
+ \int_use:N #2}
+ {\seq_if_in:NxTF \g__nm_empty_cells_seq
+ {\int_use:N #1-\int_use:N #2}
+ {\prg_return_false:}
+ {\tikz[remember~picture]
+ \path let \p1 = (nm-
+ \int_use:N \g__nm_env_int-
+ \int_use:N #1-
+ \int_use:N #2.east),
+ \p2 = (nm-
+ \int_use:N \g__nm_env_int-
+ \int_use:N #1-
+ \int_use:N #2.west)
+ in \pgfextra {\dim_gset:Nn \g_tmpa_dim {\x1}
+ \dim_gset:Nn \g_tmpb_dim {\x2}} ;
+ \dim_gsub:Nn \g_tmpa_dim \g_tmpb_dim
+ \dim_compare:nNnTF {\dim_abs:n \g_tmpa_dim} < {0.5 pt}
+ {\prg_return_false:}
+ {\prg_return_true:}}}
+ {\prg_return_false:}
+ }
+\cs_new_protected:Nn \__nm_instruction_of_type:n
+ {\int_gincr:N \g__nm_instruction_int
+ \prop_put:Nnn \l_tmpa_prop {type} {#1}
+ \prop_put:NnV \l_tmpa_prop {line} \g__nm_line_int
+ \prop_put:NnV \l_tmpa_prop {column} \g__nm_column_int
+ \prop_gclear_new:c
+ {g__nm_instruction_\int_use:N\g__nm_instruction_int _prop}
+ \prop_gset_eq:cN
+ {g__nm_instruction_\int_use:N\g__nm_instruction_int _prop}
+ \l_tmpa_prop
+ }
+
+\cs_new_protected:Nn \__nm_draw_lines:
+ {
+ \seq_clear_new:N \l__nm_yet_drawn_seq
+ \int_zero_new:N \l__nm_type_int
+ \int_zero_new:N \l__nm_line_int
+ \int_zero_new:N \l__nm_column_int
+ \int_zero_new:N \l__nm_di_int
+ \int_zero_new:N \l__nm_dj_int
+ \bool_if:NT \l__nm_parallelize_diags_bool
+ {\int_zero_new:N \l__nm_ddots_int
+ \int_zero_new:N \l__nm_iddots_int
+ \dim_zero_new:N \l__nm_delta_x_one_dim
+ \dim_zero_new:N \l__nm_delta_y_one_dim
+ \dim_zero_new:N \l__nm_delta_x_two_dim
+ \dim_zero_new:N \l__nm_delta_y_two_dim}
+ \int_zero_new:N \l__nm_instruction_int
+ \int_incr:N \l__nm_instruction_int
+ \int_until_do:nNnn \l__nm_instruction_int > \g__nm_instruction_int
+ {
+ \prop_get:cnN {g__nm_instruction_\int_use:N \l__nm_instruction_int _prop}
+ {type} \l_tmpa_tl
+ \int_set:Nn \l__nm_type_int {\l_tmpa_tl}
+ \prop_get:cnN {g__nm_instruction_\int_use:N \l__nm_instruction_int _prop}
+ {line} \l_tmpa_tl
+ \int_set:Nn \l__nm_line_int {\l_tmpa_tl}
+ \prop_get:cnN {g__nm_instruction_\int_use:N \l__nm_instruction_int _prop}
+ {column} \l_tmpa_tl
+ \int_set:Nn \l__nm_column_int {\l_tmpa_tl}
+ \int_case:nn \l__nm_type_int
+ { 0 {\int_set:Nn \l__nm_di_int 0
+ \int_set:Nn \l__nm_dj_int 1}
+ 1 {\int_set:Nn \l__nm_di_int 0
+ \int_set:Nn \l__nm_dj_int 1}
+ 2 {\int_set:Nn \l__nm_di_int 1
+ \int_set:Nn \l__nm_dj_int 0}
+ 3 {\int_set:Nn \l__nm_di_int 1
+ \int_set:Nn \l__nm_dj_int 1}
+ 4 {\int_set:Nn \l__nm_di_int 1
+ \int_set:Nn \l__nm_dj_int {-1}}}
+ \bool_if_exist:NTF \l__nm_impossible_instruction_bool
+ {\bool_set_false:N \l__nm_impossible_instruction_bool}
+ {\bool_new:N \l__nm_impossible_instruction_bool}
+ \int_zero_new:N \l__nm_final_i_int
+ \int_zero_new:N \l__nm_final_j_int
+ \int_set:Nn \l__nm_final_i_int \l__nm_line_int
+ \int_set:Nn \l__nm_final_j_int \l__nm_column_int
+ \bool_if_exist:NTF \l__nm_stop_loop_bool
+ {\bool_set_false:N \l__nm_stop_loop_bool}
+ {\bool_new:N \l__nm_stop_loop_bool}
+ \bool_do_until:Nn \l__nm_stop_loop_bool
+ {\int_add:Nn \l__nm_final_i_int \l__nm_di_int
+ \int_add:Nn \l__nm_final_j_int \l__nm_dj_int
+ \bool_if:nTF { \int_compare_p:nNn \l__nm_final_i_int < 1
+ || \int_compare_p:nNn \l__nm_final_i_int > \g__nm_line_int
+ || \int_compare_p:nNn \l__nm_final_j_int < 1
+ || \int_compare_p:nNn \l__nm_final_j_int > \g__nm_nb_column_int}
+ {\bool_set_true:N \l__nm_impossible_instruction_bool
+ \bool_set_true:N \l__nm_stop_loop_bool}
+ {\__nm_if_not_empty_cell:nnT \l__nm_final_i_int \l__nm_final_j_int
+ {\bool_set_true:N \l__nm_stop_loop_bool}}
+ }
+ \int_zero_new:N \l__nm_initial_i_int
+ \int_zero_new:N \l__nm_initial_j_int
+ \int_set:Nn \l__nm_initial_i_int \l__nm_line_int
+ \int_set:Nn \l__nm_initial_j_int \l__nm_column_int
+ \bool_set_eq:NN \l__nm_stop_loop_bool \l__nm_impossible_instruction_bool
+ \bool_do_until:Nn \l__nm_stop_loop_bool
+ {\int_sub:Nn \l__nm_initial_i_int \l__nm_di_int
+ \int_sub:Nn \l__nm_initial_j_int \l__nm_dj_int
+ \bool_if:nTF
+ { \int_compare_p:nNn \l__nm_initial_i_int < 1
+ || \int_compare_p:nNn \l__nm_initial_i_int > \g__nm_line_int
+ || \int_compare_p:nNn \l__nm_initial_j_int < 1
+ || \int_compare_p:nNn \l__nm_initial_j_int > \g__nm_nb_column_int}
+ {\bool_set_true:N \l__nm_impossible_instruction_bool
+ \bool_set_true:N \l__nm_stop_loop_bool}
+ {\__nm_if_not_empty_cell:nnT \l__nm_initial_i_int \l__nm_initial_j_int
+ {\bool_set_true:N \l__nm_stop_loop_bool}}
+ }
+ \bool_if:NTF \l__nm_impossible_instruction_bool
+ {\msg_error:nn {nicematrix} {Impossible~instruction}}
+ {\tl_set:Nx \l_tmpa_tl {\int_use:N \l__nm_initial_i_int-
+ \int_use:N \l__nm_initial_j_int-
+ \int_use:N \l__nm_final_i_int-
+ \int_use:N \l__nm_final_j_int}
+ \seq_if_in:NVF \l__nm_yet_drawn_seq \l_tmpa_tl
+ {\seq_put_left:NV \l__nm_yet_drawn_seq \l_tmpa_tl
+ \dim_zero_new:N \g__nm_x_initial_dim
+ \dim_zero_new:N \g__nm_y_initial_dim
+ \dim_zero_new:N \g__nm_x_final_dim
+ \dim_zero_new:N \g__nm_y_final_dim
+ \int_case:nn \l__nm_type_int
+ {0 \__nm_draw_ldots_line:
+ 1 \__nm_draw_cdots_line:
+ 2 \__nm_draw_vdots_line:
+ 3 \__nm_draw_ddots_line:
+ 4 \__nm_draw_iddots_line:}}}
+ \int_incr:N \l__nm_instruction_int
+ }
+}
+\cs_new_protected:Nn \__nm_retrieve_coords:nn
+ {\tikz[remember~picture]
+ \path let \p1 = (nm-\int_use:N \g__nm_env_int-
+ \int_use:N \l__nm_initial_i_int-
+ \int_use:N \l__nm_initial_j_int #1),
+ \p2 = (nm-\int_use:N \g__nm_env_int-
+ \int_use:N \l__nm_final_i_int-
+ \int_use:N \l__nm_final_j_int #2)
+ in \pgfextra {\dim_gset:Nn \g__nm_x_initial_dim {\x1}
+ \dim_gset:Nn \g__nm_y_initial_dim {\y1}
+ \dim_gset:Nn \g__nm_x_final_dim {\x2}
+ \dim_gset:Nn \g__nm_y_final_dim {\y2}} ; }
+\cs_new_protected:Nn \__nm_draw_ldots_line:
+ {\__nm_retrieve_coords:nn {.south~east} {.south~west}
+ \__nm_draw_tikz_line:}
+\cs_new_protected:Nn \__nm_draw_cdots_line:
+ {\__nm_retrieve_coords:nn {.mid~east} {.mid~west}
+ \__nm_draw_tikz_line:}
+\cs_new_protected:Nn \__nm_draw_vdots_line:
+ {\__nm_retrieve_coords:nn {.south} {.north}
+ \__nm_draw_tikz_line:}
+\cs_new_protected:Nn \__nm_draw_ddots_line:
+ {\__nm_retrieve_coords:nn {.south~east} {.north~west}
+ \bool_if:NT \l__nm_parallelize_diags_bool
+ {\int_incr:N \l__nm_ddots_int
+ \int_compare:nNnTF \l__nm_ddots_int = 1
+ {\dim_set:Nn \l__nm_delta_x_one_dim {\g__nm_x_final_dim - \g__nm_x_initial_dim }
+ \dim_set:Nn \l__nm_delta_y_one_dim {\g__nm_y_final_dim - \g__nm_y_initial_dim }}
+ {\dim_gset:Nn \g__nm_y_final_dim
+ {\g__nm_y_initial_dim +
+ (\g__nm_x_final_dim - \g__nm_x_initial_dim)
+ * \dim_ratio:nn \l__nm_delta_y_one_dim \l__nm_delta_x_one_dim }}}
+ \__nm_draw_tikz_line:}
+\cs_new_protected:Nn \__nm_draw_iddots_line:
+ {\__nm_retrieve_coords:nn {.south~west} {.north~east}
+ \bool_if:NT \l__nm_parallelize_diags_bool
+ {\int_incr:N \l__nm_iddots_int
+ \int_compare:nNnTF \l__nm_iddots_int = 1
+ {\dim_set:Nn \l__nm_delta_x_two_dim {\g__nm_x_final_dim - \g__nm_x_initial_dim }
+ \dim_set:Nn \l__nm_delta_y_two_dim {\g__nm_y_final_dim - \g__nm_y_initial_dim }}
+ {\dim_gset:Nn \g__nm_y_final_dim
+ {\g__nm_y_initial_dim +
+ (\g__nm_x_final_dim - \g__nm_x_initial_dim)
+ * \dim_ratio:nn \l__nm_delta_y_two_dim \l__nm_delta_x_two_dim }}}
+ \__nm_draw_tikz_line:}
+
+\cs_new_protected:Nn \__nm_draw_tikz_line:
+ {\begin{tikzpicture}[overlay]
+ \tikzmath{
+ coordinate~\a , \b ;
+ real~\l, \x, \d ;
+ integer~\n ;
+ \a = (\g__nm_x_initial_dim, \g__nm_y_initial_dim) ;
+ \b = (\g__nm_x_final_dim, \g__nm_y_final_dim) ;
+ \l = veclen(\bx-\ax,\by-\ay) ;
+ \n = (\l - 0.54em)/(0.45em) ;
+ \x = (\l - \n*0.45em)/(2*\l) ;
+ \d = 0.45em / \l ;
+ if~\n>0
+ then~{ for~\k in~{0,...,\n}
+ { {\node at ($(\a)!\x+\k*\d!(\b)$) {.} ; } ; } ;
+ } ;
+ }
+ \end{tikzpicture}}
+\cs_set_eq:NN \__nm_ldots \ldots
+\cs_set_eq:NN \__nm_cdots \cdots
+\cs_set_eq:NN \__nm_vdots \vdots
+\cs_set_eq:NN \__nm_ddots \ddots
+\cs_set_eq:NN \__nm_iddots \iddots
+\cs_new_protected:Nn \__nm_add_to_empty_cells:
+ {\seq_gput_right:Nx \g__nm_empty_cells_seq
+ {\int_use:N \g__nm_line_int-
+ \int_use:N \g__nm_column_int}}
+\NewDocumentCommand \__nm_Ldots {s}
+ {\IfBooleanF {#1} {\__nm_instruction_of_type:n 0}
+ \bool_if:NF \l__nm_nullify_dots_bool {\phantom \__nm_ldots}
+ \__nm_add_to_empty_cells:}
+\NewDocumentCommand \__nm_Cdots {s}
+ {\IfBooleanF {#1} {\__nm_instruction_of_type:n 1}
+ \bool_if:NF \l__nm_nullify_dots_bool {\phantom \__nm_cdots}
+ \__nm_add_to_empty_cells:}
+\NewDocumentCommand \__nm_Vdots {s}
+ {\IfBooleanF {#1} {\__nm_instruction_of_type:n 2}
+ \bool_if:NF \l__nm_nullify_dots_bool {\phantom \__nm_vdots}
+ \__nm_add_to_empty_cells:}
+\NewDocumentCommand \__nm_Ddots {s}
+ {\IfBooleanF {#1} {\__nm_instruction_of_type:n 3}
+ \bool_if:NF \l__nm_nullify_dots_bool {\phantom \__nm_ddots}
+ \__nm_add_to_empty_cells:}
+\NewDocumentCommand \__nm_Iddots {s}
+ {\IfBooleanF {#1} {\__nm_instruction_of_type:n 4}
+ \bool_if:NF \l__nm_nullify_dots_bool {\phantom \__nm_iddots}
+ \__nm_add_to_empty_cells:}
+\cs_new_protected:Nn \__nm_Hspace:
+ {\__nm_add_to_empty_cells:
+ \hspace}
+\cs_new_protected:Nn \__nm_NiceMatrixEndPoint:
+ {\kern 0.5pt}
+\ProcessKeysOptions {NiceMatrix}
+\msg_new:nnnn {nicematrix}
+ {Impossible~instruction}
+ {It's~not~possible~to~execute~the~instruction~
+ \int_case:nn \l__nm_type_int
+ {0 {\token_to_str:N \Ldots}
+ 1 {\token_to_str:N \Cdots}
+ 2 {\token_to_str:N \Vdots}
+ 3 {\token_to_str:N \Ddots}}~in~the~line~\int_use:N\l__nm_line_int\
+ ~and~the~column~\int_use:N\l__nm_column_int\space of~the~matrix~
+ because~it's~impossible~to~find~one~of~its~extremities~
+ (both~extremities~must~be~non~empty~cells~of~the~matrix).~
+ If~you~go~on,~the~instruction~will~be~ignored.}
+ {You~can~specify~a~end~of~line~on~a~empty~cell~
+ with~\token_to_str:N \NiceMatrixEndPoint.}
+\msg_new:nnn {nicematrix}
+ {multicolumn~forbidden}
+ {The~command~\token_to_str:N \multicolumn\
+ is~forbidden~in~the~environment~\{NiceMatrix\}~
+ and~its~variants.~The~command~\token_to_str:N \hdotsfor\
+ of~amsmath~is~also~forbidden~since~it~uses~
+ \token_to_str:N \multicolumn.~You~can~go~on~but~your~line~will~
+ probably~be~wrong.}
+\endinput
+%%
+%% End of file `nicematrix.sty'.
diff --git a/Master/tlpkg/bin/tlpkg-ctan-check b/Master/tlpkg/bin/tlpkg-ctan-check
index aa49e705774..568e3984743 100755
--- a/Master/tlpkg/bin/tlpkg-ctan-check
+++ b/Master/tlpkg/bin/tlpkg-ctan-check
@@ -450,7 +450,7 @@ my @TLP_working = qw(
newcommand newenviron newfile newlfm newpx newsletr newspaper
newtx newtxsf newtxtt newunicodechar newvbtm
newverbs nextpage
- nfssext-cfr nicefilelist niceframe niceframe-type1 nicetext
+ nfssext-cfr nicefilelist niceframe niceframe-type1 nicematrix nicetext
nih nihbiosketch
nimbus15 nkarta nlctdoc
nmbib noconflict nodetree noindentafter noitcrul nolbreaks
diff --git a/Master/tlpkg/tlpsrc/collection-mathscience.tlpsrc b/Master/tlpkg/tlpsrc/collection-mathscience.tlpsrc
index 113c05ae53c..c185ef4cfb2 100644
--- a/Master/tlpkg/tlpsrc/collection-mathscience.tlpsrc
+++ b/Master/tlpkg/tlpsrc/collection-mathscience.tlpsrc
@@ -110,6 +110,7 @@ depend multiobjective
depend mychemistry
depend natded
depend nath
+depend nicematrix
depend nuc
depend nucleardata
depend objectz
diff --git a/Master/tlpkg/tlpsrc/nicematrix.tlpsrc b/Master/tlpkg/tlpsrc/nicematrix.tlpsrc
new file mode 100644
index 00000000000..e69de29bb2d
--- /dev/null
+++ b/Master/tlpkg/tlpsrc/nicematrix.tlpsrc