texlive[54330] Master/texmf-dist: nicematrix (15mar20)

commits+karl at tug.org commits+karl at tug.org
Sun Mar 15 22:32:14 CET 2020


Revision: 54330
          http://tug.org/svn/texlive?view=revision&revision=54330
Author:   karl
Date:     2020-03-15 22:32:14 +0100 (Sun, 15 Mar 2020)
Log Message:
-----------
nicematrix (15mar20)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/nicematrix/nicematrix-french.pdf
    trunk/Master/texmf-dist/doc/latex/nicematrix/nicematrix-french.tex
    trunk/Master/texmf-dist/doc/latex/nicematrix/nicematrix.pdf
    trunk/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx
    trunk/Master/texmf-dist/tex/latex/nicematrix/nicematrix.sty

Modified: trunk/Master/texmf-dist/doc/latex/nicematrix/nicematrix-french.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/nicematrix/nicematrix-french.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/nicematrix/nicematrix-french.tex	2020-03-15 21:32:00 UTC (rev 54329)
+++ trunk/Master/texmf-dist/doc/latex/nicematrix/nicematrix-french.tex	2020-03-15 21:32:14 UTC (rev 54330)
@@ -8,15 +8,18 @@
 \geometry{left=2.8cm,right=2.8cm,top=2.5cm,bottom=2.5cm,papersize={21cm,29.7cm}}
 
 \usepackage{amsmath}
-\usepackage{color}
+
 \usepackage{array}
 \usepackage{colortbl}
 \usepackage{nicematrix}
+\usepackage{tikz}
+\usetikzlibrary{fit}
+
+
 \usepackage{enumitem}
 
 \usepackage{siunitx}
 
-\usepackage{unicode-math}
 
 \usepackage{arydshln}
 \usepackage{verbatim}
@@ -44,6 +47,8 @@
 
 \usepackage{booktabs}
 
+\usepackage{varwidth}
+
 \usepackage[hyperfootnotes = false]{hyperref}
 
 \hypersetup
@@ -90,9 +95,9 @@
 Cette extension peut être utilisée avec |xelatex|, |lualatex| et |pdflatex| mais aussi avec le cheminement
 classique |latex|-|dvips|-|ps2pdf| (ou Adobe Distiller). Deux ou trois compilations successives peuvent être
 nécessaires. Cette extension nécessite et charge les extensions \pkg{expl3}, \pkg{l3keys2e}, \pkg{xparse},
-\pkg{array}, \pkg{amsmath} et \pkg{tikz}. Elle charge aussi la bibliothèque Tikz \pkg{fit}. L'utilisateur final n'a
-qu'à charger l'extension \pkg{nicematrix} avec l'instruction habituelle :
-|\usepackage{nicematrix}|. 
+\pkg{array}, \pkg{amsmath} et \pkg{pgfcore} ainsi que le module \pkg{shapes} de \textsc{pgf} (l'extension
+\pkg{tikz} n'est \emph{pas} chargée). L'utilisateur final n'a qu'à charger l'extension \pkg{nicematrix} avec
+l'instruction habituelle : |\usepackage{nicematrix}|.
 
 
 
@@ -115,11 +120,11 @@
                           code-for-first-col=\color{blue}\scriptstyle,
                           code-for-first-row=\color{blue}\scriptstyle,
                           columns-width = auto]
-       & C_1     & C_2     & \Cdots  & C_n  \\
-L_1    & a_{11}  & a_{12}  & \Cdots & a_{1n} \\
-L_2    & a_{21}  & a_{22}  & \Cdots & a_{2n} \\
-\Vdots & \Vdots & \Vdots & \Ddots & \Vdots\\
-L_n    & a_{n1}  & a_{n2}  & \Cdots & a_{nn} 
+       & C_1     & C_2    & \Cdots  & C_n    \\
+L_1    & a_{11}  & a_{12}  & \Cdots  & a_{1n} \\
+L_2    & a_{21}  & a_{22}  & \Cdots  & a_{2n} \\
+\Vdots & \Vdots & \Vdots  & \Ddots  & \Vdots \\
+L_n    & a_{n1}  & a_{n2}  & \Cdots  & a_{nn} 
 \end{bNiceArray}$
 
 
@@ -229,26 +234,32 @@
 entre les premières cases non vides\footnote{La définition précise de ce qui est considéré comme une «case vide»
   est donnée plus loin (cf. p.~\pageref{empty-cells}).} situées de part et d'autre de la case courante. Bien
 entendu, pour |\Ldots| et |\Cdots|, c'est une ligne horizontale ; pour |\Vdots|, c'est une ligne verticale et pour
-|\Ddots| et |\Iddots|, ce sont des lignes diagonales.\par\nobreak
+|\Ddots| et |\Iddots|, ce sont des lignes diagonales. On peut changer la couleur d'une ligne avec
+l'option~|color|.\footnote{Il est aussi possible de changer la couleur de toutes ces lignes pointillées avec
+  l'option |xdots/color| (\textsl{xdots} pour rappeler que cela s'applique à |\Cdots|, |\Ldots|, |Vdots|, etc.)
+}\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      & \Cdots &        & & a_1     \\
+\Vdots   & a_2    & \Cdots & & a_2     \\
+         & \Vdots & \Ddots[color=red] \\
 \\
 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      & \Cdots &        & & a_1   \\
+\Vdots   & a_2    & \Cdots & & a_2   \\
+         & \Vdots & \Ddots[color=red] \\
 \\
 a_1      & a_2    &        & & a_n 
 \end{bNiceMatrix}$
 
+
+
+
 \interitem
 Pour représenter la matrice nulle, on peut choisir d'utiliser le codage suivant :\par\nobreak
 
@@ -343,102 +354,70 @@
 \pkg{amsmath}.\par\nobreak
 
 \medskip
-\begin{BVerbatim}[baseline=c,boxwidth=8cm]
+\begin{BVerbatim}[baseline=c,boxwidth=10cm]
 $A = \begin{pmatrix}
-a_0 & b \\
-a_1 &   \\
-a_2 &   \\
-a_3 &   \\
-a_4 &   \\
-a_5 & b
+h & i & j & k & l & m \\
+x &   &   &   &   & x \\
 \end{pmatrix}$
 \end{BVerbatim}
 $A = \begin{pmatrix}
-a_0 & b \\
-a_1 &   \\
-a_2 &   \\
-a_3 &   \\
-a_4 &   \\
-a_5 & b
+h & i & j & k & l & m \\
+x   &     &     &    &     & x \\
 \end{pmatrix}$
 
 
 \bigskip
-Si nous ajoutons des instructions |\vdots| dans la seconde colonne, la géométrie de la matrice est
+Si nous ajoutons des instructions |\ldots| dans la seconde rangée, la géométrie de la matrice est
 modifiée.\par\nobreak
 
 \medskip
-\begin{BVerbatim}[baseline=c,boxwidth=8cm]
+\begin{BVerbatim}[baseline=c,boxwidth=10cm]
 $B = \begin{pmatrix}
-a_0 & b      \\
-a_1 & \vdots \\
-a_2 & \vdots \\
-a_3 & \vdots \\
-a_4 & \vdots \\
-a_5 & b
+h & i & j & k & l & m \\
+x & \ldots & \ldots  & \ldots & \ldots & x \\
 \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
+h & i & j & k & l & m \\
+x   & \ldots   & \ldots  & \ldots & \ldots & x \\
 \end{pmatrix}$
 
 \bigskip
-Par défaut, avec \pkg{nicematrix}, si nous remplaçons |{pmatrix}| par |{pNiceMatrix}| et |\vdots| par |\Vdots|, la
+Par défaut, avec \pkg{nicematrix}, si nous remplaçons |{pmatrix}| par |{pNiceMatrix}| et |\ldots| par |\Ldots|, la
 géométrie de la matrice n'est pas changée.\par\nobreak
 
 \medskip
-\begin{BVerbatim}[baseline=c,boxwidth=8cm]
+\begin{BVerbatim}[baseline=c,boxwidth=10cm]
 $C = \begin{pNiceMatrix}
-a_0 & b       \\
-a_1 & \Vdots  \\
-a_2 & \Vdots \\
-a_3 & \Vdots \\
-a_4 & \Vdots \\
-a_5 & b
+h & i & j & k & l & m \\
+x & \Ldots & \Ldots & \Ldots & \Ldots & x \\
 \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
+h & i & j & k & l & m \\
+x & \Ldots & \Ldots  & \Ldots & \Ldots & x \\
 \end{pNiceMatrix}$
 
 \bigskip
 On pourrait toutefois préférer la géométrie de la première matrice $A$ et vouloir avoir la même géométrie avec une
-ligne en pointillés continue dans la seconde colonne. C'est possible en utilisant l'option |nullify-dots| (et une
-seule instruction |\Vdots| suffit).\par\nobreak
+ligne en pointillés continue dans la seconde rangée. C'est possible en utilisant l'option |nullify-dots| (et une
+seule instruction |\Ldots| suffit).\par\nobreak
 
 \medskip
-\begin{BVerbatim}[baseline=c,boxwidth=8cm]
+\begin{BVerbatim}[baseline=c,boxwidth=10cm]
 $D = \begin{pNiceMatrix}[~emphase#nullify-dots@]
-a_0 & b      \\
-a_1 & \Vdots \\
-a_2 &        \\
-a_3 &        \\
-a_4 &        \\
-a_5 & b
+h & i & j & k & l & m \\
+x & \Ldots & & & & x \\
 \end{pNiceMatrix}$
 \end{BVerbatim}
 $D = \begin{pNiceMatrix}[nullify-dots]
-a_0 & b      \\
-a_1 & \Vdots \\
-a_2 &        \\
-a_3 &        \\
-a_4 &        \\
-a_5 & b
+h & i & j & k & l & m \\
+x & \Ldots & &  &  & x \\
 \end{pNiceMatrix}$
 
 \medskip
-L'option |nullify-dots| «smashe» les instructions |\Ldots| (et ses variantes) verticalement mais aussi
-horizontalement.
+L'option |nullify-dots| «smashe» les instructions |\Ldots| (et ses variantes) horizontalement mais aussi
+verticalement.
 
 \medskip
 {\bfseries Il doit n'y avoir aucun espace devant le crochet ouvrant (|[|) des options de l'environnement.}
@@ -548,21 +527,109 @@
 \end{scope}
 
 
-\subsection{Réglage fin des lignes en pointillés}
+\subsection{Personnalisation des lignes en pointillés}
 
-L'écart entre un nœud et l'extrémité d'une ligne en pointillés est fixée par |dotted-lines-margin|. La valeur
-initiale de cette clé est de $0.3$~em (il est conseillé d'utiliser une unité de mesure dépendante de la fonte
-courante). Pour un exemple, voir p.~\pageref{permutation}.
+Les lignes pointillées tracées par |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots|, |\Idots| et |\Hdotsfor| (ainsi que par la
+commande |\line| dans le |code-after| décrite p.~\pageref{line-in-code-after}) peuvent être
+paramétrées par trois options (que l'on met entre crochets après la commande) :
+%
+\begin{itemize}
+\item |color| ;
+\item |shorten| ; 
+\item |line-style|.
+\end{itemize}
 
+Ces options peuvent aussi être fixées avec |\NiceMatrixOption| ou bien au niveau d'un environnement mais elles
+doivent alors être préfixées par |xdots|, ce qui fait que leurs noms deviennent :
+%
+\begin{itemize}
+\item |xdots/color| ;
+\item |xdots/shorten| ; 
+\item |xdots/line-style|.
+\end{itemize}
+%
+Pour la clarté, dans la suite, on utilisera ces noms-là.
 
+\bigskip
+\textbf{L'option xdots/color}\par\nobreak
 
-\section{Les nœuds Tikz créés par l'extension nicematrix}
+\smallskip
+L'option |xdots/color| indique bien entendu la couleur de la ligne tracée. On remarquera néanmoins que les lignes
+tracées dans les rangées et colonnes extérieures (décrites plus loin) bénificient d'un régime spécial : cf.
+p.~\pageref{exterior}.
 
+
+\bigskip
+\textbf{L'option xdots/shorten}\par\nobreak
+
+\smallskip
+L'option |xdots/shorten| indique la marge qui est laissée aux deux extrémités de la ligne. Le nom s'inspire des options
+«|shorten >|» et «|shorten <|» de Tikz, mais il faut remarquer que \pkg{nicematrix} ne propose que |xdots/shorten|.
+La valeur initiale de ce paramètre est de $0.3$~em (il est conseillé d'utiliser une unité de mesure dépendante de
+la fonte courante).
+
+
+\bigskip
+\textbf{L'option xdots/line-style}\par\nobreak
+
+\smallskip
+Il faut savoir que, par défaut, les lignes de Tikz tracées avec le paramètre |dotted| sont composées de points
+carrés et non pas ronds.\footnote{La raison de départ est que le format \textsc{pdf} comporte un système de description
+  de lignes en tiretés, qui, puisqu'il est incorporé dans le \textsc{pdf}, est affiché très rapidement par les
+  lecteurs de \textsc{pdf}. Il est facile à partir de ce type de ligne de créer des lignes de points carrés alors
+  qu'une ligne de points ronds doit être construite explicitement point par point.}
+
+\begin{BVerbatim}[baseline=c,boxwidth=9cm]
+\tikz \draw [dotted] (0,0) -- (5,0) ;
+\end{BVerbatim}
+\tikz \draw [dotted] (0,0) -- (5,0) ;
+
+\bigskip
+Voulant proposer des lignes avec des points ronds dans le style de celui de |\ldots| (au moins celui des fontes
+\emph{Computer Modern}), l'extension \pkg{nicematrix} contient en interne son propre système de ligne en pointillés
+(qui, au passage n'utilise que \pkg{pgf} et non \pkg{tikz}). Ce style est appelé le style |standard|. Cette valeur
+est la valeur initiale du paramètre |xdots/line-style|.
+
+\bigskip
+Néanmoins (quand Tikz est chargé), on peut utiliser pour |xdots/line-style| n'importe quel style proposé par Tikz,
+c'est-à-dire n'importe quelle suite d'options Tikz applicables à un chemin (à l'exception de «|color|», 
+«|shorten >|» et «|shorten <|»). 
+
+\medskip
+Voici par exemple une matrice tridiagonale avec le style |loosely dotted| :\par\nobreak
+
+\medskip
+\begin{BVerbatim}[baseline=c]
+$\begin{pNiceMatrix}[nullify-dots,~emphase#xdots/line-style=loosely dotted@]
+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}
+
+
+\[\begin{pNiceMatrix}[nullify-dots,xdots/line-style=loosely dotted]
+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}\]
+
+
+\section{Les nœuds PGF-Tikz créés par l'extension nicematrix}
+
 \label{name}
 
-L'extension \pkg{nicematrix} crée un nœud Tikz pour chaque case du tableau considéré. Ces nœuds sont utilisés pour
-tracer les lignes en pointillés entre les cases du tableau. Toutefois, l'utilisateur peut aussi utiliser
-directement ces nœuds. On commence par donner un nom au tableau (avec l'option |name|). Cela étant fait, les nœuds
+L'extension \pkg{nicematrix} crée un nœud PGF-Tikz pour chaque case (non vide) du tableau considéré. Ces nœuds sont
+utilisés pour tracer les lignes en pointillés entre les cases du tableau. Toutefois, l'utilisateur peut aussi
+utiliser directement ces nœuds (s'il a chargé Tikz\footnote{On rappelle que depuis la version 3.13,
+  \pkg{nicematrix} ne charge plus Tikz par défaut, mais seulement \textsc{pgf} (Tikz est une surcouche de
+  \textsc{pgf}).}). On commence par donner un nom au tableau (avec l'option |name|). Cela étant fait, les nœuds
 sont accessibles à travers les noms «\textsl{nom}-$i$-$j$» où \textsl{nom} est le nom donné au tableau et $i$ et
 $j$ les numéros de rangée et de colonne de la case considérée.
 
@@ -589,14 +656,25 @@
 
 \bigskip
 Dans l'exemple suivant, nous avons surligné toutes les cases de la matrice.
-\begin{scope}
-\tikzset{every node/.style = {fill = red!15, inner sep = 0pt}}
-\[\begin{pNiceMatrix}
+\[\begin{pNiceMatrix}[
+ code-after = {\begin{tikzpicture}
+                  [every node/.style = {blend mode = multiply,
+                                        inner sep = 0 pt ,
+                                        fill = red!15}]
+               \node [fit = (1-1)] {} ;
+               \node [fit = (1-3)] {} ;
+               \node [fit = (2-2)] {} ;
+               \node [fit = (3-1)] {} ;
+               \node [fit = (3-3)] {} ;
+               \node [fit = (1-2)] {} ;
+               \node [fit = (2-1)] {} ;
+               \node [fit = (2-3)] {} ;
+               \node [fit = (3-2)] {} ;
+               \end{tikzpicture}}]
 a & a + b & a + b + c \\
 a & a     & a + b  \\
 a & a     & a 
 \end{pNiceMatrix}\]
-\end{scope}
 
 
 \bigskip
@@ -615,7 +693,7 @@
  code-after = {\begin{tikzpicture}
                   [every node/.style = {fill = red!15,
                                         blend mode = multiply,
-                                        inner sep = -\pgflinewidth/2},
+                                        inner sep = 0 pt},
                    name suffix = -medium]
                \node [fit = (1-1)] {} ;
                \node [fit = (1-2)] {} ;
@@ -643,7 +721,7 @@
  create-large-nodes,
  code-after = {\begin{tikzpicture}
                   [every node/.style = {blend mode = multiply,
-                                        inner sep = -\pgflinewidth/2},
+                                        inner sep = 0 pt},
                    name suffix = -large]
                \node [fit = (1-1),fill = red!15] {} ;
                \node [fit = (1-3),fill = red!15] {} ;
@@ -673,7 +751,7 @@
  create-large-nodes,left-margin,right-margin,
  code-after = {\begin{tikzpicture}
                   [every node/.style = {blend mode = multiply,
-                                        inner sep = -\pgflinewidth/2},
+                                        inner sep = 0 pt},
                    name suffix = -large]
                \node [fit = (1-1),fill = red!15] {} ;
                \node [fit = (1-3),fill = red!15] {} ;
@@ -698,7 +776,7 @@
  create-large-nodes,left-margin,right-margin,extra-right-margin=3pt,extra-left-margin=3pt,
  code-after = {\begin{tikzpicture}
                   [every node/.style = {blend mode = multiply,
-                                        inner sep = -\pgflinewidth/2},
+                                        inner sep = 0 pt},
                    name suffix = -large]
                \node [fit = (1-1),fill = red!15] {} ;
                \node [fit = (1-3),fill = red!15] {} ;
@@ -722,7 +800,7 @@
  create-large-nodes,left-margin,right-margin,extra-right-margin=3pt,extra-left-margin=3pt,
  code-after = {\begin{tikzpicture}
                   [every node/.style = {blend mode = multiply,
-                                        inner sep = -\pgflinewidth/2},
+                                        inner sep = 0 pt},
                    name suffix = -large]
                \node [fit = (1-1),fill = red!15] {} ;
                \node [fit = (1-3),fill = red!15] {} ;
@@ -744,30 +822,34 @@
 
 \section{Le code-after}
 
-L'option |code-after| peut être utilisée pour indiquer du code qui sera exécuté après la construction de la matrice
-(et donc, en particulier, après la construction de tous les nœuds).
+\label{code-after}
 
-Dans le |code-after|, les nœuds Tikz doivent être désignés sous la forme $i$-$j$ (sans le préfixe correspondant au
-nom de l'environnement).
+L'option |code-after| peut être utilisée pour indiquer du code qui sera exécuté après la construction de la matrice,
+et donc, en particulier, après la construction de tous les nœuds.
 
+\textbf{Si on a chargé Tikz}\footnote{On rappelle que depuis la version 3.13, \pkg{nicematrix} ne charge plus Tikz
+  par défaut, mais seulement \textsc{pgf} (Tikz est une surcouche de \textsc{pgf}).}, on peut accéder à ces nœuds
+avec des instructions Tikz classiques. Les nœuds devront être désignés sous la forme $i$-$j$ (sans le préfixe
+correspondant au nom de l'environnement).
+
 De plus, une commande spéciale, nommée |\line| est disponible pour tracer directement des lignes en pointillés
 entre les nœuds).
+\label{line-in-code-after}
 
 \medskip
-\begin{BVerbatim}[baseline=c,boxwidth=12cm]
-$\begin{pNiceMatrix}[~emphase#code-after = \line{1-1}{3-3}@]
+\begin{BVerbatim}[baseline=c,boxwidth=13cm]
+$\begin{pNiceMatrix}[~emphase#code-after = {\line{1-1}{3-3}[color=blue]}@]
 0 & 0 & 0 \\
 0 &   & 0 \\
 0 & 0 & 0 
 \end{pNiceMatrix}$
 \end{BVerbatim}
-$\begin{pNiceMatrix}[code-after = \line{1-1}{3-3}]
+$\begin{pNiceMatrix}[code-after = {\line{1-1}{3-3}[color=blue]}]
 0 & 0 & 0 \\
 0 &   & 0 \\
 0 & 0 & 0 
 \end{pNiceMatrix}$
 
-
 \section{L'environnement \{NiceArray\}}
 \label{NiceArray}
 
@@ -804,7 +886,7 @@
 \end{NiceArray}$
 
 \smallskip
-L'option |hvlines| est présentée plus loin (cf. p. \pageref{hvlines}).
+L'option |hvlines| utilisée dans cet exemple est présentée plus loin (cf. p. \pageref{hvlines}).
 
 \medskip
 L'option |baseline| peut aussi prendre les trois valeurs spéciales |t|, |c| et |b|. Ces trois lettres peuvent aussi
@@ -818,7 +900,7 @@
 rangée (avec |{array}| de {array}, il faut utiliser |\firsthline|\footnote{On peut aussi utiliser |\firsthline|
   avec |{NiceArray}|.}).
 
-
+\smallskip
 \begin{BVerbatim}[baseline=c,boxwidth=9cm]
 \begin{enumerate}
 \item un item
@@ -962,28 +1044,28 @@
 |first-row|, |last-row|, |first-col| et |last-col|.
 \label{exterior}
 
-Si elle est présente, la première rangée est numérotée par $0$ (et non $1$). Il en est de même pour la première
-colonne. Dans le cas général, on doit spécifier le numéro de la dernière rangée et de la dernière colonne comme
-valeurs des options |last-row| et |last-col| (si elles sont présentes).
+Si elle est présente, la «première rangée» (extérieure) est numérotée par $0$ (et non $1$). Il en est de même pour
+la «première rangée». Dans le cas général, on doit spécifier le numéro de la dernière rangée et de la dernière
+colonne comme valeurs des options |last-row| et |last-col| (si elles sont présentes).
 
 \begin{Verbatim}
-$\begin{pNiceMatrix}[~emphase#first-row,last-row=5,first-col,last-col=5@]
-    & C_1    & C_2    & C_3    & C_4    &     \\
-L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\
-L_2 & a_{21} & a_{22} & a_{23} & a_{24} & L_2 \\
-L_3 & a_{31} & a_{32} & a_{33} & a_{34} & L_3 \\
-L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\
-    & C_1    & C_2    & C_3    & C_4    &     
+$\begin{pNiceMatrix}[~emphase#first-row,last-row=5,first-col,last-col=5@,nullify-dots]
+       & C_1    & \Cdots &        & C_4    &        \\
+L_1    & a_{11} & a_{12} & a_{13} & a_{14} & L_1    \\
+\Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\
+       & a_{31} & a_{32} & a_{33} & a_{34} &        \\
+L_4    & a_{41} & a_{42} & a_{43} & a_{44} & L_4    \\
+       & C_1    & \Cdots &        & C_4    &     
 \end{pNiceMatrix}$
 \end{Verbatim}
 %
-\[\begin{pNiceMatrix}[first-row,last-row=5,first-col,last-col=5]
-    & C_1    & C_2    & C_3    & C_4    &     \\
-L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\
-L_2 & a_{21} & a_{22} & a_{23} & a_{24} & L_2 \\
-L_3 & a_{31} & a_{32} & a_{33} & a_{34} & L_3 \\
-L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\
-    & C_1    & C_2    & C_3    & C_4    &     
+\[\begin{pNiceMatrix}[first-row,last-row=5,first-col,last-col=5,nullify-dots]
+       & C_1    & \Cdots &        & C_4    &        \\
+L_1    & a_{11} & a_{12} & a_{13} & a_{14} & L_1    \\
+\Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\
+       & a_{31} & a_{32} & a_{33} & a_{34} &        \\
+L_4    & a_{41} & a_{42} & a_{43} & a_{44} & L_4    \\
+       & C_1    & \Cdots &        & C_4    &     
 \end{pNiceMatrix}\]
 
 \bigskip
@@ -1017,14 +1099,14 @@
                    ~emphase#code-for-first-col@ = \color{blue},
                    ~emphase#code-for-last-row@ = \color{green},
                    ~emphase#code-for-last-col@ = \color{magenta}}
-$\begin{pNiceArray}{CC|CC}[first-row,last-row,first-col,last-col]
-    & C_1    & C_2    & C_3    & C_4    &     \\
-L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\
-L_2 & a_{21} & a_{22} & a_{23} & a_{24} & L_2 \\
+$\begin{pNiceArray}{CC|CC}[first-row,last-row,first-col,last-col,nullify-dots]
+       & C_1    & \Cdots &        & C_4    &        \\
+L_1    & a_{11} & a_{12} & a_{13} & a_{14} & L_1    \\
+\Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\
 \hline
-L_3 & a_{31} & a_{32} & a_{33} & a_{34} & L_3 \\
-L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\
-    & C_1    & C_2    & C_3    & C_4    &     
+       & a_{31} & a_{32} & a_{33} & a_{34} &        \\
+L_4    & a_{41} & a_{42} & a_{43} & a_{44} & L_4    \\
+       & C_1    & \Cdots &        & C_4    &     
 \end{pNiceArray}$
 \end{Verbatim}
 %
@@ -1034,14 +1116,14 @@
                    code-for-last-row = \color{green},
                    code-for-last-col = \color{magenta}}
 \begin{displaymath}
-\begin{pNiceArray}{CC|CC}[first-row,last-row,first-col,last-col]
-    & C_1    & \multicolumn1C{C_2}    & C_3    & C_4    &     \\
-L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\
-L_2 & a_{21} & a_{22} & a_{23} & a_{24} & L_2 \\
+\begin{pNiceArray}{CC|CC}[first-row,last-row,first-col,last-col,nullify-dots]
+       & C_1    & \multicolumn1C{\Cdots} &        & C_4    &        \\
+L_1    & a_{11} & a_{12} & a_{13} & a_{14} & L_1    \\
+\Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\
 \hline
-L_3 & a_{31} & a_{32} & a_{33} & a_{34} & L_3 \\
-L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\
-    & C_1    & \multicolumn1C{C_2}    & C_3    & C_4    &     
+       & a_{31} & a_{32} & a_{33} & a_{34} &        \\
+L_4    & a_{41} & a_{42} & a_{43} & a_{44} & L_4    \\
+       & C_1    & \multicolumn1C{\Cdots} &        & C_4    &     
 \end{pNiceArray}
 \end{displaymath}
 \end{scope}
@@ -1060,6 +1142,8 @@
 
 Si on veut définir de nouveaux spécificateurs de colonnes pour des filets (par exemple plus épais), on aura
 peut-être intérêt à utiliser la commande |\OnlyMainNiceMatrix| décrite p.~\pageref{OnlyMainNiceMatrix}.
+\item Une spécification de couleur présente dans |code-for-first-row| s'applique à une ligne pointillée tracée
+dans cette «première rangée» (sauf si une valeur a été donnée à |xdots/color|). Idem pour les autres.
 \item Sans surprise, une éventuelle option |columns-width| (décrite p.~\pageref{width}) ne s'applique pas à la
 «première colonne» ni à la «dernière colonne».
 \item Pour des raisons techniques, il n'est pas possible d'utiliser l'option de la commande |\\| après la
@@ -1114,7 +1198,7 @@
 
 
 \bigskip
-Ces lignes en pointillés ne s'étendent pas dans les rangées et colonnes extérieures.
+Ces lignes en pointillés ne s'étendent pas dans les rangées et colonnes extérieures.\par\nobreak
 
 
 \medskip
@@ -1153,27 +1237,35 @@
 
 \medskip
 \begin{BVerbatim}[baseline=c,boxwidth=9.5cm]
-\NiceMatrixOptions{letter-for-dotted-lines = V}
-\begin{pNiceArray}{~emphase#C|C:CVC@}
+\NiceMatrixOptions{letter-for-dotted-lines = I}
+\arrayrulecolor{blue}
+\begin{pNiceArray}{~emphase#C|C:CIC@}
 1 & 2 & 3 & 4 \\
 5 & 6 & 7 & 8 \\
 9 & 10 & 11 & 12
 \end{pNiceArray}
+\arrayrulecolor{black}
 \end{BVerbatim}
 \begin{scope}
-\NiceMatrixOptions{letter-for-dotted-lines = V}
-$\begin{pNiceArray}{C|C:CVC}
+\arrayrulecolor{blue}
+\NiceMatrixOptions{letter-for-dotted-lines = I}
+$\begin{pNiceArray}{C|C:CIC}
 1 & 2 & 3 & 4 \\
 5 & 6 & 7 & 8 \\
 9 & 10 & 11 & 12
 \end{pNiceArray}$
+\arrayrulecolor{black}
 \end{scope}
 
+\smallskip
+On a utilisé |\arrayrulecolor| de \pkg{colortbl} pour colorier les trois traits.
+
+
 \bigskip
 \emph{Remarque} : Quand l'extension \pkg{array} (sur laquelle s'appuie \pkg{nicematrix}) est chargée, les traits
 verticaux et horizontaux que l'on insère rendent le tableau plus large ou plus long d'une quantité égale à la
-largeur du trait\footnote{En fait, cela est vrai pour |\hline| et ``\verb+|+'' mais pas pour |\cline|.}. Avec
-\pkg{nicematrix}, les lignes en pointillés tracées par |\hdottedline| et ``|:|'' ont le même effet.
+largeur du trait\footnote{En fait, cela est vrai pour |\hline| et «\verb+|+» mais pas pour |\cline|.}. Avec
+\pkg{nicematrix}, les lignes en pointillés tracées par |\hdottedline| et «|:|» ont le même effet.
 
 \section{La largeur des colonnes}
 \label{width}
@@ -1199,8 +1291,8 @@
 
 
 \bigskip
-Dans les environnements de \pkg{nicematrix}, il est aussi possible de fixer la largeur de toutes les colonnes de la
-matrice directement avec l'option |columns-width|.
+Dans les environnements de \pkg{nicematrix}, il est aussi possible de fixer la largeur \emph{minimale} de toutes
+les colonnes de la matrice directement avec l'option |columns-width|.
 
 \medskip
 \begin{BVerbatim}[baseline=c,boxwidth=10cm]
@@ -1241,8 +1333,8 @@
 \end{pNiceMatrix}$
 
 \bigskip
-Sans surprise, il est possible de fixer la largeur de toutes les colonnes de toutes les matrices dans une certaine
-portion de document avec la commande |\NiceMatrixOptions|.\par\nobreak
+Sans surprise, il est possible de fixer la largeur minimale de toutes les colonnes de toutes les matrices dans une
+certaine portion de document avec la commande |\NiceMatrixOptions|.\par\nobreak
 
 \medskip
 \begin{BVerbatim}[baseline=c,boxwidth=8.5cm]
@@ -1385,6 +1477,28 @@
 
 \section{Fonctionnalités avancées}
 
+\subsection{Option d'alignement dans NiceMatrix}
+
+Les environnements sans préambule (|{NiceMatrix}|, |{pNiceMatrix}|, |{bNiceMatrix}|, etc.) proposent les options
+|l| et |r| (possédant |L| et |R| comme alias) qui imposent des colonnes alignées à gauche ou à
+droite.\footnote{Cela reprend une partie des fonctionnalités proposées par les environnements |{pmatrix*}|,
+  |{bmatrix*}|, etc. de \pkg{mathtools}.}
+
+\medskip
+\begin{BVerbatim}[baseline=c,boxwidth=10cm]
+$\begin{bNiceMatrix}[R]
+\cos x & - \sin x \\
+\sin x & \cos x 
+\end{bNiceMatrix}$
+\end{BVerbatim}
+$\begin{bNiceMatrix}[R]
+\cos x & - \sin x \\
+\sin x & \cos x 
+\end{bNiceMatrix}$
+
+
+
+
 \subsection{La commande \textbackslash rotate}
 
 Utilisée au début d'une case, la commande |\rotate| (fournie par \pkg{nicematrix}) compose le contenu après une 
@@ -1398,7 +1512,7 @@
 \NiceMatrixOptions%
  {code-for-first-row = \scriptstyle ~emphase#\rotate@ \text{image de },
   code-for-last-col = \scriptstyle }
-$\begin{pNiceMatrix}[first-row,last-col=4]
+$A = \begin{pNiceMatrix}[first-row,last-col=4]
 e_1 & e_2 & e_3       \\
 1   & 2   & 3   & e_1 \\
 4   & 5   & 6   & e_2 \\
@@ -1405,25 +1519,51 @@
 7   & 8   & 9   & e_3 \\
 \end{pNiceMatrix}$
 \end{BVerbatim}
-%
-\begin{scope}
+\begin{varwidth}{10cm}
 \NiceMatrixOptions%
  {code-for-first-row = \scriptstyle\rotate \text{image de },
   code-for-last-col = \scriptstyle }
-\begin{minipage}{3cm}
-$\begin{pNiceMatrix}[first-row,last-col=4]
+$ A = \begin{pNiceMatrix}[first-row,last-col=4]
 e_1 & e_2 & e_3 \\
 1   & 2   & 3  & e_1 \\
 4   & 5   & 6  & e_2 \\
 7   & 8   & 9  & e_3 \\
 \end{pNiceMatrix}$
-\end{minipage}
-\end{scope}
+\end{varwidth}
 
+\bigskip
+Si la commande |\rotate| est utilisée dans la ``dernière rangée'' (extérieure à la matrice), les éléments qui
+subissent cette rotation sont alignés vers le haut.
 
+\bigskip
+\begin{BVerbatim}[baseline=c,boxwidth=12cm]
+\NiceMatrixOptions%
+ {code-for-last-row = \scriptstyle ~emphase#\rotate@ ,
+  code-for-last-col = \scriptstyle }
+$A = \begin{pNiceMatrix}[last-row,last-col=4]
+1   & 2   & 3   & e_1 \\
+4   & 5   & 6   & e_2 \\
+7   & 8   & 9   & e_3 \\
+\text{image de } e_1 & e_2 & e_3 \\
+\end{pNiceMatrix}$
+\end{BVerbatim}
+\begin{varwidth}{10cm}
+\NiceMatrixOptions%
+ {code-for-last-row = \scriptstyle\rotate ,
+  code-for-last-col = \scriptstyle }%
+$A = \begin{pNiceMatrix}[last-row,last-col=4]
+1   & 2   & 3  & e_1 \\
+4   & 5   & 6  & e_2 \\
+7   & 8   & 9  & e_3 \\
+\text{image de } e_1 & e_2 & e_3 \\
+\end{pNiceMatrix}$
+\end{varwidth}
 
+
 \subsection{L'option small}
 
+\label{small}
+
 Avec l'option |small|, les environnements de l'extension \pkg{nicematrix} sont composés d'une manière proche de ce
 que propose l'environnement |{smallmatrix}| de l'\pkg{amsmath} (et les environnements |{psmallmatrix}|,
 |{bsmallmatrix}|, etc. de \pkg{mathtools}).
@@ -1471,6 +1611,9 @@
 Bien entendu, l'utilisateur ne doit pas modifier les valeurs de ces compteurs qui sont utilisés en interne par
 \pkg{nicematrix}.
 
+Dans le |code-after| (cf. p. \pageref{code-after}), |iRow| représente le nombre total de rangées (hors éventuelles
+rangées extérieures) et |jCol| le nombre total de colonnes (hors potentielles colonnes extérieures).
+
 \medskip
 \begin{BVerbatim}[baseline=c,boxwidth=10.6cm]
 $\begin{pNiceMatrix}%
@@ -1581,7 +1724,7 @@
 \end{NiceArray}$
 
 \bigskip
-Dans le cas d'un environnement avec délimiteurs (par exemple |{pNiceArray}| ou |pNiceMatrix|), l'option |vlines| ne
+Dans le cas d'un environnement avec délimiteurs (par exemple |{pNiceArray}| ou |{pNiceMatrix}|), l'option |vlines| ne
 trace pas de filets verticaux au niveau des deux délimiteurs (bien entendu).
 
 \medskip
@@ -1612,29 +1755,24 @@
 l'extension \pkg{spalign} de Joseph Rabinoff.} permet d'alléger la saisie des matrices, ainsi que leur lisibilité dans le source TeX.
 Lorsque cette option est activée, on doit utiliser le point-virgule comme marqueur de fin de rangée et séparer les
 colonnes par des espaces. On remarquera toutefois que, comme souvent dans le monde TeX, les espaces après les
-séquences de contrôles ne sont pas comptées et que les éléments entre accolades sont considérés comme un tout.
+séquences de contrôle ne sont pas comptées et que les éléments entre accolades sont considérés comme un tout.
 
-\bigskip
-L'exemple suivant a été composé avec XeLaTeX en utilisant \pkg{unicode-math}, ce qui permet d'utiliser directement
-les lettres grecques en Unicode.
 
 \medskip
 \begin{scope}
-\def\alpha{$α$}
-\def\beta{$β$}
 \begin{BVerbatim}[baseline=c,boxwidth=10cm]
 $\begin{bNiceMatrix}[~emphase#light-syntax@,first-row,first-col]
-{} ~alpha             ~beta                 ;
-~alpha  2\cos ~alpha       {\cos ~alpha + \cos ~beta} ;
-~beta \cos ~alpha+\cos ~beta  { 2 \cos ~beta }
+{} a             b                 ;
+a  2\cos a       {\cos a + \cos b} ;
+b \cos a+\cos b  { 2 \cos b }
 \end{bNiceMatrix}$
 \end{BVerbatim}
 \end{scope}
 % 
 $\begin{bNiceMatrix}[light-syntax,first-row,first-col]
-{} α             β                 ;
-α  2\cos α       {\cos α + \cos β} ;
-β \cos α+\cos β  { 2 \cos β }
+{} a             b                 ;
+a  2\cos a       {\cos a + \cos b} ;
+b \cos a+\cos b  { 2 \cos b }
 \end{bNiceMatrix}$
 
 \medskip
@@ -1725,10 +1863,10 @@
 lignes sont tracées a son importance pour le résultat final. Voici cet ordre (c'est à dessein qu'il a été choisi
 ainsi) : |\Hdotsfor|, |\Vdots|, |\Ddots|, |\Iddots|, |\Cdots| et |\Ldots|.
 
-De ce fait, on peut tracer la matrice suivante :
+\medskip
+De ce fait, on peut tracer la matrice suivante :\par\nobreak
 
-
-\medskip
+\smallskip
 \begin{BVerbatim}[baseline = c, boxwidth = 10.5cm]
 $\begin{pNiceMatrix}[nullify-dots]
 1 & 2 & 3 & \Cdots & n \\
@@ -1749,12 +1887,13 @@
 \end{pNiceMatrix}$
 
 
-\subsection{Le nom des nœuds Tikz créés par nicematrix}
 
-Les nœuds Tikz créés par \pkg{nicematrix} peuvent être utilisés hors des environnements de \pkg{nicematrix} après
-avoir nommé l'environnement concerné avec l'option |name| (cf. p.~\pageref{name}). Il s'agit là de la méthode
-conseillée mais on décrit néanmoins maintenant le nom Tikz interne de ces nœuds. 
+\subsection{Le nom des nœuds PGF créés par nicematrix}
 
+Les nœuds PGF-Tikz créés par \pkg{nicematrix} peuvent être utilisés hors des environnements de \pkg{nicematrix}
+après avoir nommé l'environnement concerné avec l'option |name| (cf. p.~\pageref{name}). Il s'agit là de la méthode
+conseillée mais on décrit néanmoins maintenant le nom Tikz interne de ces nœuds.
+
 Les environnements créés par \pkg{nicematrix} sont numérotés par un compteur global interne. La commande
 |\NiceMatrixLastEnv| donne le numéro du dernier de ces environnements (pour LaTeX, il s'agit d'une commande —
 complètement développable — et non d'un compteur).
@@ -1829,6 +1968,7 @@
 \end{pNiceMatrix}$
 
 
+
 \end{scope}
 
 \subsection{Les cases «vides»}
@@ -1855,14 +1995,9 @@
 la dernière case (deuxième rangée et deuxième colonne) est vide.
 
 \medskip
-\item Chaque case avec un rendu par TeX de largeur inférieure à 0.5~pt est vide.
+\item Chaque case avec un rendu par TeX de largeur nulle est vide.
 
 \medskip
-\item Une case qui contient une commande |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots| ou |\Iddots| est vide. On rappelle
-que ces commandes doivent être employées seules dans une case.
-
-
-\medskip
 \item Une case avec une commande |\Hspace| (ou |\Hspace*|) est vide. Cette commande |\Hspace| est une commande
 définie par l'extension \pkg{nicematrix} avec la même signification que |\hspace| excepté que la case où cette
 commande est utilisée est considérée comme vide. Cette commande peut être utilisée pour fixer la largeur des
@@ -1878,26 +2013,21 @@
 l'environnement |{array}| n'était probablement pas une bonne idée\footnote{Dans la documentation de |{amsmath}|, on
   peut lire : {\itshape The extra space of |\arraycolsep| that \pkg{array} adds on each side is a waste so we
     remove it [in |{matrix}|] (perhaps we should instead remove it from array in general, but that's a harder
-    task).} Il est possible de supprimer les espaces pour un environnement |{array}| donné par une construction du
-  type |\begin{array}{@{}ccccc@{}}...\end{array}|.}. L'environnement |{matrix}| et ses variantes (|{pmatrix}|,
-|{vmatrix}|, etc.) de \pkg{amsmath} préfèrent supprimer ces espaces avec des instructions explicites
-|\hskip -\arraycolsep|. L'extension \pkg{nicematrix} fait de même dans \emph{tous} ses environnements y compris
-l'environnement |{NiceArray}|. Néanmoins, si l'utilisateur souhaite que l'environnement |{NiceArray}| se comporte
-par défaut comme l'environnement |{array}| de \pkg{array} (par exemple pour faciliter l'adaptation d'un document
-existant), il peut contrôler ce comportement avec l'option |exterior-arraycolsep| accessible via la commande
-|\NiceMatrixOptions|. Avec cette option, des espaces extérieurs de longueur |\arraycolsep| seront insérés dans les
-environnements |{NiceArray}| (les autres environnements de l'extension \pkg{nicematrix} ne sont pas affectés).
+    task).}}. L'environnement |{matrix}| et ses variantes (|{pmatrix}|,
+|{vmatrix}|, etc.) de \pkg{amsmath} préfèrent supprimer ces espaces avec des instructions explicites 
+|\hskip -\arraycolsep|\footnote{Et non en insérant |@{}| de part et d'autre du préambule, ce qui fait que la
+  longueur des |\hline| n'est pas modifiée et elle peut paraître trop longue, surtout avec des crochets.}.
+L'extension \pkg{nicematrix} fait de même dans \emph{tous} ses environnements y compris l'environnement
+|{NiceArray}|. Néanmoins, si l'utilisateur souhaite que l'environnement |{NiceArray}| se comporte par défaut comme
+l'environnement |{array}| de \pkg{array} (par exemple pour faciliter l'adaptation d'un document existant), il peut
+contrôler ce comportement avec l'option |exterior-arraycolsep| accessible via la commande |\NiceMatrixOptions|.
+Avec cette option, des espaces extérieurs de longueur |\arraycolsep| seront insérés dans les environnements
+|{NiceArray}| (les autres environnements de l'extension \pkg{nicematrix} ne sont pas affectés).
 
 
 \subsection{L'option de classe draft}
 
-L'extension \pkg{nicematrix} est relativement lente pour tracer les lignes en pointillés (créées par |\Cdots|,
-|\Ldots|, |\Ddots|, etc. mais aussi par le spécificateur «|:|»).\footnote{La principale raison est que nous voulons
-  des lignes en pointillés avec des points ronds et non carrés. Pour atteindre ce but, il a fallu construire notre
-  propre système de lignes en pointillés.}
-
-
-C'est pourquoi, avec l'option de classe |draft|, les lignes en pointillés ne sont pas tracées, pour accélérer la
+Quand l'option de classe |draft| est utilisée, les lignes en pointillés ne sont pas tracées, pour accélérer la
 compilation.
 
 
@@ -1994,41 +2124,15 @@
 
 \subsection{Lignes en pointillés}
 
-\medskip
-Une matrice tridiagonale :\par\nobreak
 
-\bigskip
-\begin{BVerbatim}[baseline=c]
-$\begin{pNiceMatrix}[nullify-dots]
-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{pNiceMatrix}[nullify-dots]
-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}$
+Une matrice de permutation.\par\nobreak
 
-\vspace{2cm}
+À titre d'exemple, on a augmenté la valeur du paramètre |xdots/shorten|.\par\nobreak 
 
-Une matrice de permutation. 
 
-À titre d'exemple, on a augmenté la valeur du paramètre |dotted-lines-margin|.
-
-\label{permutation}
-
 \bigskip
 \begin{BVerbatim}[baseline=c]
-$\begin{pNiceMatrix}[~emphase#dotted-lines-margin=6em@]
+$\begin{pNiceMatrix}[~emphase#xdots/shorten=6em@]
 0       & 1 & 0 &        & \Cdots &   0    \\
 \Vdots  &   &   & \Ddots &        & \Vdots \\
         &   &   & \Ddots &        &        \\
@@ -2038,7 +2142,7 @@
 \end{pNiceMatrix}$
 \end{BVerbatim}
 \hspace{2.5cm}
-$\begin{pNiceMatrix}[dotted-lines-margin=0.6em]
+$\begin{pNiceMatrix}[xdots/shorten=0.6em]
 0       & 1 & 0 &        & \Cdots &   0    \\
 \Vdots  &   &   & \Ddots &        & \Vdots \\
         &   &   & \Ddots &        &        \\
@@ -2049,10 +2153,10 @@
 
 \vspace{2cm}
 
-Un exemple avec |\Iddots|: \par\nobreak
+Un exemple avec |\Iddots|. On a augmenté encore davantage la valeur de |xdots/shorten|.\par\nobreak
 \bigskip
 \begin{BVerbatim}[baseline=c]
-$\begin{pNiceMatrix}
+$\begin{pNiceMatrix}[~emphase#xdots/shorten = 0.9em@]
 1       & \Cdots  &         & 1      \\
 \Vdots  &         &         & 0      \\
         & ~emphase#\Iddots@ & ~emphase#\Iddots@ & \Vdots \\
@@ -2060,7 +2164,7 @@
 \end{pNiceMatrix}$
 \end{BVerbatim}
 \hspace{4cm}
-$\begin{pNiceMatrix}
+$\begin{pNiceMatrix}[xdots/shorten = 0.9em]
 1       & \Cdots  &         & 1      \\
 \Vdots  &         &         & 0      \\
         & \Iddots & \Iddots & \Vdots \\
@@ -2262,11 +2366,25 @@
 \label{highlight}
 
 \medskip
+Les exemples suivants nécessitent d'avoir chargé Tikz (\pkg{nicematrix} ne charge que \textsc{pgf}) ainsi que la
+bibliothèque Tikz |fit|, ce qui peut se faire avec les deux instructions suivantes dans le préambule du document :
+
+\begin{verbatim}
+\usepackage{tikz}
+\usetikzlibrary{fit}
+\end{verbatim}
+
+
+
+\medskip
 Pour mettre en évidence une case, il est possible de «dessiner» l'un des nœuds (le «nœud normal», le «nœud moyen»
 ou le «nœud large»). Dans l'exemple suivant, on utilise les «nœuds larges» de la diagonale de la matrice (avec la
-clé de Tikz «|name suffix|», il est facile d'utiliser les «nœuds larges»). Pour avoir la continuité des lignes, on
-doit fixer |inner sep = -\pgflinewidth/2|.
+clé de Tikz «|name suffix|», il est facile d'utiliser les «nœuds larges»). 
 
+Nous redessinons les nœuds avec de nouveaux nœuds en utilisant la bibliothèque \pkg{fit} de Tikz. Comme nous
+voulons recréer des nœuds identiques aux premiers, nous devons fixer |inner sep = 0pt| (si on ne fait
+pas cela, les nouveaux nœuds seront plus grands que les nœuds d'origine créés par \pkg{nicematrix}).
+
 \begin{Verbatim}
 $\begin{pNiceArray}{>{\strut}CCCC}%
    [create-large-nodes,margin,extra-margin=2pt,
@@ -2273,7 +2391,7 @@
     code-after = {\begin{tikzpicture}
                      [~emphase#name suffix = -large@,
                       every node/.style = {draw,
-                                           ~emphase#inner sep = -\pgflinewidth/2@}]
+                                           ~emphase#inner sep = 0pt@}]
                      \node [fit = (1-1)] {} ; 
                      \node [fit = (2-2)] {} ; 
                      \node [fit = (3-3)] {} ; 
@@ -2291,7 +2409,7 @@
     create-large-nodes,margin,extra-margin=2pt,
     code-after = {\begin{tikzpicture}[name suffix = -large,
                                       every node/.style = {draw,
-                                                           inner sep = -\pgflinewidth/2}]
+                                                           inner sep = 0pt}]
                      \node [fit = (1-1)] {} ; 
                      \node [fit = (2-2)] {} ; 
                      \node [fit = (3-3)] {} ; 
@@ -2304,9 +2422,10 @@
 \end{pNiceArray}\]
 %
 On remarquera que les traits que l'on vient de tracer sont dessinés \emph{après} la matrice sans modifier la
-position des composantes de celle-ci. En revanche, les traits tracés par |\hline| ou le spécificateur ``\verb+|+"'' 
-«écartent» les composantes de la matrice (quand l'extension \pkg{array} est chargée, ce qui est toujours le cas
-avec \pkg{nicematrix}).\footnote{En revanche les traits tracés par |\ncline| n'écartent pas les lignes de la matrice.}
+position des composantes de celle-ci. En revanche, les traits tracés par |\hline|, le spécificateur «\verb+|+» ou
+les options |hlines| et |vlines| «écartent» les composantes de la matrice (quand l'extension \pkg{array} est
+chargée, ce qui est toujours le cas avec \pkg{nicematrix}).\footnote{En revanche les traits tracés par |\ncline|
+  n'écartent pas les lignes de la matrice.}
 
 \vspace{1cm}
 
@@ -2553,7 +2672,7 @@
 Dans l'exemple suivant, on souhaite illustrer le produit mathématique de deux matrices.
 
 \medskip
-L'utilisation de |{NiceMatrixBlock}| avec l'option |auto-columns-width| va permettre que toutes les colonnes aient
+L'utilisation de |{NiceMatrixBlock}| avec l'option |auto-columns-width| va permettre que toutes les colonnes aient 
 la même largeur ce qui permettra un alignement des deux matrices superposées.
 \begin{Verbatim}
 \begin{NiceMatrixBlock}[auto-columns-width]
@@ -2572,11 +2691,11 @@
 La matrice $B$ a une «première rangée» (pour $C_j$) d'où l'option |first-row|.
 \begin{Verbatim}
 \begin{bNiceArray}{C>{\strut}CCCC}[name=B,first-row]
-      &        & C_j \\
-b_{11} & \Cdots & b_{1j} & \Cdots & b_{1n} \\
-\Vdots &       & \Vdots &       & \Vdots \\
-       &       & b_{kj}  \\
-       &       & \Vdots \\
+       &          & ~emphase#C_j@                      \\
+b_{11} & \Cdots   & b_{1j} & \Cdots & b_{1n} \\
+\Vdots &          & \Vdots &        & \Vdots \\
+       &          & b_{kj}                   \\
+       &          & \Vdots                   \\
  b_{n1}  & \Cdots & b_{nj} & \Cdots & b_{nn} 
 \end{bNiceArray} \\ \\
 \end{Verbatim}
@@ -2584,11 +2703,11 @@
 La matrice $A$ a une «première colonne» (pour $L_i$) d'où l'option |first-col|.
 \begin{Verbatim}
 \begin{bNiceArray}{CC>{\strut}CCC}[name=A,first-col]
-    & a_{11} & \Cdots &  &  & a_{1n} \\
-    & \Vdots &       &  &  & \Vdots \\
-L_i & a_{i1} & \Cdots & a_{ik} & \Cdots & a_{in} \\
-    & \Vdots &       &  &  & \Vdots \\
-    & a_{n1} & \Cdots &  &  & a_{nn} \\
+    & a_{11} & \Cdots &        &        & a_{1n} \\
+    & \Vdots &        &        &        & \Vdots \\
+~emphase#L_i@ & a_{i1} & \Cdots & a_{ik} & \Cdots & a_{in} \\
+    & \Vdots &        &        &        & \Vdots \\
+    & a_{n1} & \Cdots &        &        & a_{nn} \\
 \end{bNiceArray}
 & 
 \end{Verbatim}
@@ -2596,9 +2715,9 @@
 Dans la matrice produit, on remarquera que les lignes en pointillés sont «semi-ouvertes».
 \begin{Verbatim}
 \begin{bNiceArray}{CC>{\strut}CCC}
-       &         & & & \\
-       &         & \Vdots \\
-\Cdots &         & c_{ij}  \\
+       & &        & & \\
+       & & \Vdots     \\
+\Cdots & & c_{ij}     \\
 \\
 \\
 \end{bNiceArray} 
@@ -2614,8 +2733,8 @@
  \draw [color = gray] (A-3-3) to [bend left] (B-3-3) ; 
 \end{tikzpicture}
 \end{Verbatim}
- 
 
+
 \begin{NiceMatrixBlock}[auto-columns-width]
 \NiceMatrixOptions{nullify-dots}
 $\begin{array}{cc}
@@ -2637,9 +2756,9 @@
 \end{bNiceArray}
 & 
 \begin{bNiceArray}{CC>{\strut}CCC}
-       &         & & & \\
-       &         & \Vdots \\
-\Cdots &         & c_{ij}  \\
+       &  &        & & \\
+       &  & \Vdots     \\
+\Cdots &  & c_{ij}      \\
 \\
 \\
 \end{bNiceArray} 

Modified: trunk/Master/texmf-dist/doc/latex/nicematrix/nicematrix.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx	2020-03-15 21:32:00 UTC (rev 54329)
+++ trunk/Master/texmf-dist/source/latex/nicematrix/nicematrix.dtx	2020-03-15 21:32:14 UTC (rev 54330)
@@ -15,8 +15,8 @@
 %
 % \fi
 % \iffalse
-\def\myfileversion{3.12}
-\def\myfiledate{2020/02/28}
+\def\myfileversion{3.13}
+\def\myfiledate{2020/03/15}
 %
 %
 %<*batchfile>
@@ -52,6 +52,8 @@
 \geometry{left=2.8cm,right=2.8cm,top=2.5cm,bottom=2.5cm,papersize={21cm,29.7cm}}
 
 \usepackage{colortbl}
+\usepackage{tikz}
+\usetikzlibrary{fit}
 \usepackage{nicematrix}
 \usepackage{siunitx}
 
@@ -67,7 +69,7 @@
 \usepackage{arydshln}
 \setlength{\columnseprule}{0.4pt}
 \usepackage{footnotehyper}
-\usepackage{unicode-math}
+\usepackage{varwidth}
 \parindent 0pt
 
 \EnableCrossrefs
@@ -107,8 +109,9 @@
 % the classical workflow |latex|-|dvips|-|ps2pdf| (or Adobe Distiller). Two or
 % three compilations may be necessary. This package requires and \textbf{loads}
 % the packages \pkg{expl3}, \pkg{l3keys2e}, \pkg{xparse}, \pkg{array},
-% \pkg{amsmath} and \pkg{tikz}. It also loads the Tikz library \pkg{fit}. The
-% final user only has to load the extension with |\usepackage{nicematrix}|. 
+% \pkg{amsmath}, \pkg{pgfcore} and the module \pkg{shapes} of \textsc{pgf}
+% (\pkg{tikz} is \emph{not} loaded). The final user only has to load the
+% extension with |\usepackage{nicematrix}|.
 %
 %
 % \medskip
@@ -242,22 +245,25 @@
 % ``non-empty cell'' is given below (cf. p.~\pageref{empty-cells}).} 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| diagonal ones.\par\nobreak 
+% |\Iddots| diagonal ones. It's possible to change the color of these lines
+% with the option |color|.\footnote{It's also possible to change the color of
+% all theses dotted lines with the option |xdots/color| (\textsl{xdots} to
+% remind that it works for |\Cdots|, |\Ldots|, |\Vdots|, etc.)}\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      & \Cdots &        & & a_1    \\
+% \Vdots   & a_2    & \Cdots & & a_2    \\
+%          & \Vdots & \Ddots[color=red] \\
 % \\
 % 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      & \Cdots &        & & a_1    \\
+% \Vdots   & a_2    & \Cdots & & a_2    \\
+%          & \Vdots & \Ddots[color=red] \\
 % \\
 % a_1      & a_2    &        & & a_n 
 % \end{bNiceMatrix}$
@@ -357,109 +363,78 @@
 % \end{bNiceMatrix}$
 % 
 % \subsection{The option nullify-dots}
+% 
 %
 % Consider the following matrix composed classicaly with the environment
-% |{pmatrix}| of \pkg{amsmath}.\par\nobreak 
-% 
+% \verb|{pmatrix}| of \pkg{amsmath}.\par\nobreak 
+%
 % \medskip
-% \begin{BVerbatim}[baseline=c,boxwidth=8cm]
+% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
 % $A = \begin{pmatrix}
-% a_0 & b \\
-% a_1 &   \\
-% a_2 &   \\
-% a_3 &   \\
-% a_4 &   \\
-% a_5 & b
+% h & i & j & k & l & m \\
+% x &   &   &   &   & x \\
 % \end{pmatrix}$
 % \end{BVerbatim}
 % $A = \begin{pmatrix}
-% a_0 & b \\
-% a_1 &   \\
-% a_2 &   \\
-% a_3 &   \\
-% a_4 &   \\
-% a_5 & b
+% h & i & j & k & l & m \\
+% x   &     &     &    &     & x \\
 % \end{pmatrix}$
 %
 %
 % \bigskip
-% If we add |\vdots| instructions in the second column, the geometry of the
+% If we add \verb|\ldots| instructions in the second row, the geometry of the
 % matrix is modified.\par\nobreak
 %
 % \medskip
-% \begin{BVerbatim}[baseline=c,boxwidth=8cm]
+% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
 % $B = \begin{pmatrix}
-% a_0 & b      \\
-% a_1 & \vdots \\
-% a_2 & \vdots \\
-% a_3 & \vdots \\
-% a_4 & \vdots \\
-% a_5 & b
+% h & i & j & k & l & m \\
+% x & \ldots & \ldots  & \ldots & \ldots & x \\
 % \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
+% h & i & j & k & l & m \\
+% x   & \ldots   & \ldots  & \ldots & \ldots & x \\
 % \end{pmatrix}$
 %
 % \bigskip
-% By default, with \pkg{nicematrix}, if we replace |{pmatrix}| by
-% |{pNiceMatrix}| and |\vdots| by |\Vdots|, the geometry of the matrix is not
+% By default, with \pkg{nicematrix}, if we replace \verb|{pmatrix}| by
+% \verb|{pNiceMatrix}| and \verb|\ldots| by \verb|\Ldots|, the geometry of the matrix is not
 % changed.\par\nobreak 
 %
 % \medskip
-% \begin{BVerbatim}[baseline=c,boxwidth=8cm]
+% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
 % $C = \begin{pNiceMatrix}
-% a_0 & b       \\
-% a_1 & \Vdots  \\
-% a_2 & \Vdots  \\
-% a_3 & \Vdots  \\
-% a_4 & \Vdots  \\
-% a_5 & b
+% h & i & j & k & l & m \\
+% x & \Ldots & \Ldots & \Ldots & \Ldots & x \\
 % \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
+% h & i & j & k & l & m \\
+% x & \Ldots & \Ldots  & \Ldots & \Ldots & x \\
 % \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 |nullify-dots| (and only one instruction |\Vdots| is
+% have such a geometry with a dotted line in the second row. It's possible by
+% using the option \verb|nullify-dots| (and only one instruction \verb|\Ldots| is
 % necessary).\par\nobreak 
 %
 % \medskip
-% \begin{BVerbatim}[baseline=c,boxwidth=8cm]
+% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
 % $D = \begin{pNiceMatrix}[~emphase#nullify-dots@]
-% a_0 & b      \\
-% a_1 & \Vdots \\
-% a_2 &        \\
-% a_3 &        \\
-% a_4 &        \\
-% a_5 & b
+% h & i & j & k & l & m \\
+% x & \Ldots & & & & x \\
 % \end{pNiceMatrix}$
 % \end{BVerbatim}
 % $D = \begin{pNiceMatrix}[nullify-dots]
-% a_0 & b      \\
-% a_1 & \Vdots \\
-% a_2 &        \\
-% a_3 &        \\
-% a_4 &        \\
-% a_5 & b
+% h & i & j & k & l & m \\
+% x & \Ldots & &  &  & x \\
 % \end{pNiceMatrix}$
 %
 % \medskip
 % The option |nullify-dots| smashes the instructions |\Ldots| (and the variants)
-% vertically but also horizontally.
+% horizontally but also vertically.
 %
 % \medskip
 % \textbf{There must be no space before the opening bracket (|[|) of the options
@@ -576,25 +551,118 @@
 % \end{pmatrix}$
 % \end{scope}
 % 
-% \subsection{Fine tuning of the dotted lines}
+% \subsection{Customization of the dotted lines}
 %  
-% The distance between a node and the end of a dotted line is set by
-% |dotted-lines-margin|. The initial value of this key is $0.3$~em (it's
-% recommended to use a unit dependent of the current font). For an example,
-% cf.~p.~\pageref{permutation}.
+% The dotted lines drawn by |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots|, |\Iddots|
+% and |\Hdotsfor| (and by the command |\line| in the |code-after| which is described
+% in p.~\pageref{line-in-code-after}) may be customized by three options (specified
+% between square brackets after the command):
+% \begin{itemize}
+% \item |color|;
+% \item |shorten|;
+% \item |line-style|.
+% \end{itemize}
+%
+% These options may also be fixed with |\NiceMatrixOptions| or at the level of a
+% given environment but, in those cases, they must be prefixed by |xdots|, and,
+% thus have for names:
+% \begin{itemize}
+% \item |xdots/color|;
+% \item |xdots/shorten|;
+% \item |xdots/line-style|.
+% \end{itemize}
+%
+% For the clarity of the explanations, we will use those names.
+%
+% \bigskip
+% \textbf{The option xdots/color}\par\nobreak
+%
+% \smallskip 
+% The option |xdots/color| fixes the color or the dotted line. However, one should
+% remark that the dotted lines drawn in the exterior rows and columns have a
+% special treatment: cf. p.~\pageref{exterior}.
 % 
+% \bigskip
+% \textbf{The option xdots/shorten}\par\nobreak
+%
+% \smallskip
+% The option |xdots/shorten| fixes the margin of both extremities of the line.
+% The name is derived from the options ``|shorten >|'' and ``|shorten <|'' of
+% Tikz but one should notice that \pkg{nicematrix} only provides
+% |xdots/shorten|. The initial value of this parameter is 0.3~em (it is
+% recommanded to use a unit of length dependent of the current font).
 % 
-% \section{The Tikz nodes created by nicematrix}
+% \bigskip
+% \textbf{The option xdots/line-style}\par\nobreak
 % 
+% \smallskip
+% It should be pointed that, by default, the lines drawn by Tikz with the
+% parameter |dotted| are composed of square dots (and not rounded
+% ones).\footnote{The first reason of this behaviour is that the \textsc{pdf}
+% format includes a description for dashed lines. The lines specified with this
+% descriptor are displayed very efficiently by the \textsc{pdf} readers. It's
+% easy, starting from these dashed lines,
+% to create a line composed by square dots whereas a line of rounded dots needs
+% a specification of each dot in the \textsc{pdf} file.}
+% 
+% \begin{BVerbatim}[baseline=c,boxwidth=9cm]
+% \tikz \draw [dotted] (0,0) -- (5,0) ;
+% \end{BVerbatim}
+% \tikz \draw [dotted] (0,0) -- (5,0) ;
+%
+% \medskip
+% In order to provide lines with rounded dots in the style of those provided by
+% |\ldots| (at least with the \emph{Computer Modern} fonts), the extension
+% \pkg{nicematrix} embeds its own system to draw a dotted line (and this system
+% uses \textsc{pgf} and not Tikz). This style is called |standard| and that's
+% the initial value of the parameter |xdots/line-style|.
+%
+% However (when Tikz is loaded) it's possible to use for |xdots/line-style| any style
+% provided by Tikz, that is to say any sequence of options provided by Tikz for
+% the Tizk pathes (with the exception of ``|color|'', ``|shorten >|'' and
+% ``|shorten <|'').
+%
+% \medskip
+% Here is for example a tridiagonal matrix with the style |loosely dotted|:\par\nobreak
+%
+% \medskip
+% \begin{BVerbatim}[baseline=c]
+% $\begin{pNiceMatrix}[nullify-dots,~emphase#xdots/line-style=loosely dotted@]
+% 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}
+%
+%
+% \[\begin{pNiceMatrix}[nullify-dots,xdots/line-style=loosely dotted]
+% 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}\]
+%
+%
+% 
+% \section{The PGF/Tikz nodes created by nicematrix}
+% 
 % \label{name}
 %
-% The package \pkg{nicematrix} creates a Tikz node for each cell of the
-% considered array. These nodes are used to draw the dotted lines between the
-% cells of the matrix. However, the user may wish to use directly these nodes.
-% It's possible. First, the user have to give a name to the array (with the key
-% called |name|). Then, the nodes are accessible through the names
-% ``\textsl{name}-$i$-$j$'' where \textsl{name} is the name given to the array
-% and $i$ and $j$ the numbers of the row and the column of the considered cell.
+% The package \pkg{nicematrix} creates a PGF/Tikz node for each (non-empty) cell
+% of the considered array. These nodes are used to draw the dotted lines between
+% the cells of the matrix. However, the user may wish to use directly these
+% nodes. It's possible (if Tikz has been loaded\footnote{We remind that, since
+% the version 3.13, \pkg{nicematrix} doesn't load Tikz by default by only
+% \textsc{pgf} (Tikz is a layer over \textsc{pfg}).}). First, the user have to
+% give a name to the array (with the key called |name|). Then, the nodes are
+% accessible through the names ``\textsl{name}-$i$-$j$'' where \textsl{name} is
+% the name given to the array and $i$ and $j$ the numbers of the row and the
+% column of the considered cell.
 % 
 % \medskip
 % \begin{BVerbatim}[baseline=c,boxwidth=11cm]
@@ -619,14 +687,25 @@
 %
 % \bigskip
 % In the following example, we have underlined all the nodes of the matrix.
-% \begin{scope}
-% \tikzset{every node/.style = {fill = red!15, inner sep = 0pt}}
-% \[\begin{pNiceMatrix}
+% \[\begin{pNiceMatrix}[
+%  code-after = {\begin{tikzpicture}
+%                   [every node/.style = {blend mode = multiply,
+%                                         fill = red!15,
+%                                         inner sep = 0 pt }]
+%                \node [fit = (1-1)] {} ;
+%                \node [fit = (1-3)] {} ;
+%                \node [fit = (2-2)] {} ;
+%                \node [fit = (3-1)] {} ;
+%                \node [fit = (3-3)] {} ;
+%                \node [fit = (1-2)] {} ;
+%                \node [fit = (2-1)] {} ;
+%                \node [fit = (2-3)] {} ;
+%                \node [fit = (3-2)] {} ;
+%                \end{tikzpicture}}]
 % a & a + b & a + b + c \\
 % a & a     & a + b  \\
 % a & a     & a 
 % \end{pNiceMatrix}\]
-% \end{scope}
 % 
 %
 % \bigskip
@@ -647,7 +726,7 @@
 %  code-after = {\begin{tikzpicture}
 %                   [every node/.style = {fill = red!15,
 %                                         blend mode = multiply,
-%                                         inner sep = -\pgflinewidth/2},
+%                                         inner sep = 0pt},
 %                    name suffix = -medium]
 %                \node [fit = (1-1)] {} ;
 %                \node [fit = (1-2)] {} ;
@@ -676,7 +755,7 @@
 %  create-large-nodes,
 %  code-after = {\begin{tikzpicture}
 %                   [every node/.style = {blend mode = multiply,
-%                                         inner sep = -\pgflinewidth/2},
+%                                         inner sep = 0pt},
 %                    name suffix = -large]
 %                \node [fit = (1-1),fill = red!15] {} ;
 %                \node [fit = (1-3),fill = red!15] {} ;
@@ -708,7 +787,7 @@
 %  create-large-nodes,left-margin,right-margin,
 %  code-after = {\begin{tikzpicture}
 %                   [every node/.style = {blend mode = multiply,
-%                                         inner sep = -\pgflinewidth/2},
+%                                         inner sep = 0pt},
 %                    name suffix = -large]
 %                \node [fit = (1-1),fill = red!15] {} ;
 %                \node [fit = (1-3),fill = red!15] {} ;
@@ -735,7 +814,7 @@
 %  create-large-nodes,margin,extra-margin=3pt,
 %  code-after = {\begin{tikzpicture}
 %                   [every node/.style = {blend mode = multiply,
-%                                         inner sep = -\pgflinewidth/2},
+%                                         inner sep = 0 pt},
 %                    name suffix = -large]
 %                \node [fit = (1-1),fill = red!15] {} ;
 %                \node [fit = (1-3),fill = red!15] {} ;
@@ -760,7 +839,7 @@
 %  extra-left-margin=3pt,
 %  code-after = {\begin{tikzpicture}
 %                   [every node/.style = {blend mode = multiply,
-%                                         inner sep = -\pgflinewidth/2},
+%                                         inner sep = 0 pt},
 %                    name suffix = -large]
 %                \node [fit = (1-1),fill = red!15] {} ;
 %                \node [fit = (1-3),fill = red!15] {} ;
@@ -783,25 +862,30 @@
 %
 % \section{The code-after}
 %
+% \label{code-after}
 % The option |code-after| may be used to give some code that will be excuted
-% after the construction of the matrix (and, hence, after the construction of
-% all the Tikz nodes).
+% after the construction of the matrix (and thus after the construction of
+% all the nodes).
 %
-% In the |code-after|, the Tikz nodes should be accessed by a name of the form
-% $i$-$j$ (without the prefix of the name of the environment).
+% \smallskip
+% \textbf{If Tikz is loaded}\footnote{We remind that, since the version 3.13,
+% \pkg{nicematrix} doesn't load Tikz by default but only \textsc{pgf} (Tikz is a
+% layer over \textsc{pfg}).}, one may access to that nodes with classical Tikz
+% instructions. The nodes should be designed as $i$-$j$ (without the prefix
+% corresponding to the name of the environment).
 %
-% Moreover, a special command, called |\line| is available to draw directly
-% dotted lines between nodes.
+% Moreover, a special command, called |\line|, is available to draw directly
+% dotted lines between nodes. \label{line-in-code-after}
 %
 % \medskip
-% \begin{BVerbatim}[baseline=c,boxwidth=12cm]
-% $\begin{pNiceMatrix}[~emphase#code-after = \line{1-1}{3-3}@]
+% \begin{BVerbatim}[baseline=c,boxwidth=13cm]
+% $\begin{pNiceMatrix}[~emphase#code-after = {\line{1-1}{3-3}[color=blue]}@]
 % 0 & 0 & 0 \\
 % 0 &   & 0 \\
 % 0 & 0 & 0 
 % \end{pNiceMatrix}$
 % \end{BVerbatim}
-% $\begin{pNiceMatrix}[code-after = \line{1-1}{3-3}]
+% $\begin{pNiceMatrix}[code-after = {\line{1-1}{3-3}[color=blue]}]
 % 0 & 0 & 0 \\
 % 0 &   & 0 \\
 % 0 & 0 & 0 
@@ -1001,30 +1085,34 @@
 % \pkg{nicematrix}. 
 % \label{exterior}
 %
-% A potential first row has the number $0$ (and not $1$). Idem for the potential
-% first column. In general cases, one must specify the number of the last row
-% and the number of the last column as values of |last-row| and |last-col|.
+% A potential ``first row'' (exterior) has the number $0$ (and not $1$). Idem
+% for the potential ``first column''. In general cases, one must specify the
+% number of the last row and the number of the last column as values of
+% |last-row| and |last-col|.
 % 
 % \begin{Verbatim}
 % $\begin{pNiceMatrix}[~emphase#first-row,last-row=5,first-col,last-col=5@]
-%     & C_1    & C_2    & C_3    & C_4    &     \\
-% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\
-% L_2 & a_{21} & a_{22} & a_{23} & a_{24} & L_2 \\
-% L_3 & a_{31} & a_{32} & a_{33} & a_{34} & L_3 \\
-% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\
-%     & C_1    & C_2    & C_3    & C_4    &     
+% $\begin{pNiceMatrix}[~emphase#first-row,last-row=5,first-col,last-col=5@,nullify-dots]
+%        & C_1    & \Cdots &        & C_4    &        \\
+% L_1    & a_{11} & a_{12} & a_{13} & a_{14} & L_1    \\
+% \Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\
+%        & a_{31} & a_{32} & a_{33} & a_{34} &        \\
+% L_4    & a_{41} & a_{42} & a_{43} & a_{44} & L_4    \\
+%        & C_1    & \Cdots &        & C_4    &     
 % \end{pNiceMatrix}$
+% \end{pNiceMatrix}$
 % \end{Verbatim}
 %
-% \[\begin{pNiceMatrix}[first-row,last-row=5,first-col,last-col=5]
-%     & C_1    & C_2    & C_3    & C_4    &     \\
-% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\
-% L_2 & a_{21} & a_{22} & a_{23} & a_{24} & L_2 \\
-% L_3 & a_{31} & a_{32} & a_{33} & a_{34} & L_3 \\
-% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\
-%     & C_1    & C_2    & C_3    & C_4    &     
+% \[\begin{pNiceMatrix}[first-row,last-row=5,first-col,last-col=5,nullify-dots]
+%        & C_1    & \Cdots &        & C_4    &        \\
+% L_1    & a_{11} & a_{12} & a_{13} & a_{14} & L_1    \\
+% \Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\
+%        & a_{31} & a_{32} & a_{33} & a_{34} &        \\
+% L_4    & a_{41} & a_{42} & a_{43} & a_{44} & L_4    \\
+%        & C_1    & \Cdots &        & C_4    &     
 % \end{pNiceMatrix}\]
 %
+%
 % \bigskip
 % We have several remarks to do.
 % \begin{itemize}
@@ -1055,14 +1143,14 @@
 %                    ~emphase#code-for-first-col@ = \color{blue},
 %                    ~emphase#code-for-last-row@ = \color{green},
 %                    ~emphase#code-for-last-col@ = \color{magenta}}
-% $\begin{pNiceArray}{CC|CC}[first-row,last-row,first-col,last-col]
-%     & C_1    & C_2    & C_3    & C_4    &     \\
-% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\
-% L_2 & a_{21} & a_{22} & a_{23} & a_{24} & L_2 \\
+% $\begin{pNiceArray}{CC|CC}[first-row,last-row,first-col,last-col,nullify-dots]
+%        & C_1    & \Cdots &        & C_4    &        \\
+% L_1    & a_{11} & a_{12} & a_{13} & a_{14} & L_1    \\
+% \Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\
 % \hline
-% L_3 & a_{31} & a_{32} & a_{33} & a_{34} & L_3 \\
-% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\
-%     & C_1    & C_2    & C_3    & C_4    &     
+%        & a_{31} & a_{32} & a_{33} & a_{34} &        \\
+% L_4    & a_{41} & a_{42} & a_{43} & a_{44} & L_4    \\
+%        & C_1    & \Cdots &        & C_4    &     
 % \end{pNiceArray}$
 % \end{Verbatim}
 %
@@ -1071,15 +1159,17 @@
 %                    code-for-first-col = \color{blue},
 %                    code-for-last-row = \color{green},
 %                    code-for-last-col = \color{magenta}}
-% \[\begin{pNiceArray}{CC|CC}[first-row,last-row,first-col,last-col]
-%     & C_1    & \multicolumn1C{C_2}    & C_3    & C_4    &     \\
-% L_1 & a_{11} & a_{12} & a_{13} & a_{14} & L_1 \\
-% L_2 & a_{21} & a_{22} & a_{23} & a_{24} & L_2 \\
+% \begin{displaymath}
+% \begin{pNiceArray}{CC|CC}[first-row,last-row,first-col,last-col,nullify-dots]
+%        & C_1    & \multicolumn1C{\Cdots} &        & C_4    &        \\
+% L_1    & a_{11} & a_{12} & a_{13} & a_{14} & L_1    \\
+% \Vdots & a_{21} & a_{22} & a_{23} & a_{24} & \Vdots \\
 % \hline
-% L_3 & a_{31} & a_{32} & a_{33} & a_{34} & L_3 \\
-% L_4 & a_{41} & a_{42} & a_{43} & a_{44} & L_4 \\
-%     & C_1    & \multicolumn1C{C_2}    & C_3    & C_4    &     
-% \end{pNiceArray}\]
+%        & a_{31} & a_{32} & a_{33} & a_{34} &        \\
+% L_4    & a_{41} & a_{42} & a_{43} & a_{44} & L_4    \\
+%        & C_1    & \multicolumn1C{\Cdots} &        & C_4    &     
+% \end{pNiceArray}
+% \end{displaymath}
 % \end{scope}
 %
 %
@@ -1099,6 +1189,10 @@
 % rules (for example thicker than the standard rules), he should consider the
 % command |\OnlyMainNiceMatrix| described on page~\pageref{OnlyMainNiceMatrix}.
 %
+% \item A specification of color present in |code-for-first-row| also applies to
+% a dotted line draw in this exterior ``first row'' (excepted if a value has
+% been given to |xdots/color|). Idem for the other exterior rows and columns.
+%
 % \item Logically, the potential option |columns-width| (described
 % p.~\pageref{width}) doesn't apply to the ``first column'' and ``last column''.
 % \item For technical reasons, it's not possible to use the option of the
@@ -1116,7 +1210,7 @@
 % In the environments of the extension \pkg{nicematrix}, it's possible to use
 % the command |\hdottedline| (provided by \pkg{nicematrix}) which is a
 % counterpart of the classical commands |\hline| and |\hdashline| (the latter is
-% a command of\pkg{arydshln}).
+% a command of \pkg{arydshln}).
 %
 % \medskip
 % \begin{BVerbatim}[baseline=c,boxwidth=9.5cm]
@@ -1195,21 +1289,29 @@
 % 
 % \medskip
 % \begin{BVerbatim}[baseline=c,boxwidth=9.5cm]
-% \NiceMatrixOptions{letter-for-dotted-lines = V}
-% \left(\begin{NiceArray}{~emphase#C|C:CVC@}
+% \NiceMatrixOptions{letter-for-dotted-lines = I}
+% \arrayrulecolor{blue}
+% \left(\begin{NiceArray}{~emphase#C|C:CIC@}
 % 1 & 2 & 3 & 4 \\
 % 5 & 6 & 7 & 8 \\
 % 9 & 10 & 11 & 12
 % \end{NiceArray}\right)
+% \arrayrulecolor{black}
 % \end{BVerbatim}
 % \begin{scope}
-% \NiceMatrixOptions{letter-for-dotted-lines = V}
-% $\left(\begin{NiceArray}{C|C:CVC}
+% \NiceMatrixOptions{letter-for-dotted-lines = I}
+% \arrayrulecolor{blue}
+% $\left(\begin{NiceArray}{C|C:CIC}
 % 1 & 2 & 3 & 4 \\
 % 5 & 6 & 7 & 8 \\
 % 9 & 10 & 11 & 12
 % \end{NiceArray}\right)$
+% \arrayrulecolor{black}
 % \end{scope}
+% 
+% \smallskip
+% We have used the command |\arrayrulecolor| (de \pkg{colortbl}) to draw in blue
+% the three rules.
 %
 % \bigskip
 % \emph{Remark} : In the extension \pkg{array} (on which the extension
@@ -1216,7 +1318,7 @@
 % \pkg{nicematrix} relies), horizontal and vertical rules make the array larger
 % or wider by a quantity equal to the width of the rule\footnote{In fact, this
 % is true only for |\hline| and ``"|"'' but not for |\cline|.}. In
-% \pkg{nicematrix}, the dotted lines drawn |\hdottedline| and ``|:|'' do
+% \pkg{nicematrix}, the dotted lines drawn by |\hdottedline| and ``|:|'' do
 % likewise. 
 %
 % 
@@ -1226,7 +1328,10 @@
 %
 % In the environments with an explicit preamble (like |{NiceArray}|,
 % |{pNiceArray}|, etc.), it's possible to fix the  width of a given column with
-% the standard letters |w| and |W| of the package \pkg{array}. 
+% the standard letters |w| and |W| of the package \pkg{array}. In the
+% environments of \pkg{nicematrix}, the cells of such columns are composed in
+% mathematical mode, whereas, in |{array}| of \pkg{array}, they are composed in
+% text mode.
 % 
 % \medskip
 % \begin{BVerbatim}[baseline=c,boxwidth=10cm]
@@ -1244,8 +1349,8 @@
 %
 %
 % \bigskip
-% In the environments of \pkg{nicematrix}, it's also possible to fix the width
-% of all the columns of a matrix directly with the option |columns-width|.
+% In the environments of \pkg{nicematrix}, it's also possible to fix the \emph{minimal}
+% width of all the columns of a matrix directly with the option |columns-width|.
 % 
 % \medskip
 % \begin{BVerbatim}[baseline=c,boxwidth=10cm]
@@ -1288,8 +1393,9 @@
 % \end{pNiceMatrix}$
 % 
 % \bigskip
-% Without surprise, it's possible to fix the width of the columns of all the
-% matrices of a current scope with the command |\NiceMatrixOptions|.\par\nobreak
+% Without surprise, it's possible to fix the minimal width of the columns of all
+% the matrices of a current scope with the command
+% |\NiceMatrixOptions|.\par\nobreak
 %
 % \medskip
 % \begin{BVerbatim}[baseline=c,boxwidth=8.5cm]
@@ -1437,6 +1543,29 @@
 % 
 % \section{Advanced features}
 %
+%
+% \subsection{Alignement option in NiceMatrix}
+%
+% The environments without preamble (|{NiceMatrix}|, |{pNiceMatrix}|,
+% |{bNiceMatrix}|, etc.) provide two options |l| and |r| (equivalent at |L| and
+% |R|) which generate all the columns aligned leftwards (or
+% rightwards).\footnote{This is a part of the functionality provided by the
+% environments |{pmatrix*}|, |{bmatrix*}|, etc. of \pkg{mathtools}.}
+% 
+%
+% \medskip
+% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
+% $\begin{bNiceMatrix}[R]
+% \cos x & - \sin x \\
+% \sin x & \cos x 
+% \end{bNiceMatrix}$
+% \end{BVerbatim}
+% $\begin{bNiceMatrix}[R]
+% \cos x & - \sin x \\
+% \sin x & \cos x 
+% \end{bNiceMatrix}$
+%
+%
 % \subsection{The command \textbackslash rotate}
 %
 % The package \pkg{nicematrix} provides a command |\rotate|. When used in the
@@ -1447,33 +1576,63 @@
 %
 %\bigskip
 %
-% \begin{BVerbatim}[baseline=c,boxwidth=12cm]
+%\begin{BVerbatim}[baseline=c,boxwidth=12cm]
 % \NiceMatrixOptions%
 %  {code-for-first-row = \scriptstyle ~emphase#\rotate@ \text{image of },
 %   code-for-last-col = \scriptstyle }
-% $\begin{pNiceMatrix}[first-row,last-col=4]
+% $A = \begin{pNiceMatrix}[first-row,last-col=4]
+% e_1 & e_2 & e_3       \\
+% 1   & 2   & 3   & e_1 \\
+% 4   & 5   & 6   & e_2 \\
+% 7   & 8   & 9   & e_3 \\
+% \end{pNiceMatrix}$
+% \end{BVerbatim}
+% \begin{varwidth}{10cm}
+% \NiceMatrixOptions%
+%  {code-for-first-row = \scriptstyle\rotate \text{image of },
+%   code-for-last-col = \scriptstyle }
+% $ A = \begin{pNiceMatrix}[first-row,last-col=4]
 % e_1 & e_2 & e_3 \\
 % 1   & 2   & 3  & e_1 \\
 % 4   & 5   & 6  & e_2 \\
 % 7   & 8   & 9  & e_3 \\
 % \end{pNiceMatrix}$
-% \end{BVerbatim}
-% \begin{scope}
+% \end{varwidth}
+%
+% \bigskip
+% If the command |\rotate| is used in the ``last row'' (exterior to the matrix),
+% the corresponding elements are aligned upwards as shown below.
+%
+% \bigskip
+% \begin{BVerbatim}[baseline=c,boxwidth=12cm]
 % \NiceMatrixOptions%
-%  {code-for-first-row = \scriptstyle\rotate \text{image of },
+%  {code-for-last-row = \scriptstyle ~emphase#\rotate@ ,
 %   code-for-last-col = \scriptstyle }
-% \begin{minipage}{3cm}
-% $\begin{pNiceMatrix}[first-row,last-col=4]
-% e_1 & e_2 & e_3       \\
+% $A = \begin{pNiceMatrix}[last-row,last-col=4]
 % 1   & 2   & 3   & e_1 \\
 % 4   & 5   & 6   & e_2 \\
 % 7   & 8   & 9   & e_3 \\
+% \text{image of } e_1 & e_2 & e_3 \\
 % \end{pNiceMatrix}$
-% \end{minipage}
-% \end{scope}
+% \end{BVerbatim}
+% \begin{varwidth}{10cm}
+% \NiceMatrixOptions%
+%  {code-for-last-row = \scriptstyle\rotate ,
+%   code-for-last-col = \scriptstyle }%
+% $A = \begin{pNiceMatrix}[last-row,last-col=4]
+% 1   & 2   & 3  & e_1 \\
+% 4   & 5   & 6  & e_2 \\
+% 7   & 8   & 9  & e_3 \\
+% \text{image of } e_1 & e_2 & e_3 \\
+% \end{pNiceMatrix}$
+% \end{varwidth}
 %
+%
+%
 % \subsection{The option small}
 %
+% \label{small}
+% 
 % With the option |small|, the environments of the extension \pkg{nicematrix}
 % are composed in a way similar to the environment |{smallmatrix}| of the
 % extension \pkg{amsmath} (and the environments |{psmallmatrix}|,
@@ -1521,11 +1680,15 @@
 %
 % In the cells of the array, it's possible to use the LaTeX counters |iRow| and
 % |jCol| which represent the number of the current row and the number of the
-% current column\footnote{We recall that the first row (if it exists) has the
-% number~$0$ and that the first column (if it exists) has also the number~$0$.}.
-% Of course, the user must not change the value of these counters which are used
-% internally by \pkg{nicematrix}.
+% current column\footnote{We recall that the exterior ``first row'' (if it
+% exists) has the number~$0$ and that the exterior ``first column'' (if it
+% exists) has also the number~$0$.}. Of course, the user must not change the
+% value of these counters which are used internally by \pkg{nicematrix}.
 %
+% In the |code-after| (cf. p. \pageref{code-after}), |iRow| represents the total
+% number of rows (excepted the potential exterior rows) and |jCol| represents
+% the total number of columns (excepted the potential exterior columns).
+%
 % \medskip
 % \begin{BVerbatim}[baseline=c,boxwidth=10.6cm]
 % $\begin{pNiceMatrix}% don't forget the %
@@ -1675,20 +1838,18 @@
 %
 % \medskip
 % \begin{scope}
-% \def\alpha{$α$}
-% \def\beta{$β$}
 % \begin{BVerbatim}[baseline=c,boxwidth=10cm]
 % $\begin{bNiceMatrix}[~emphase#light-syntax@,first-row,first-col]
-% {} ~alpha             ~beta                 ;
-% ~alpha  2\cos ~alpha       {\cos ~alpha + \cos ~beta} ;
-% ~beta \cos ~alpha+\cos ~beta  { 2 \cos ~beta }
+% {} a             b                 ;
+% a  2\cos a       {\cos a + \cos b} ;
+% b \cos a+\cos b  { 2 \cos b }
 % \end{bNiceMatrix}$
 % \end{BVerbatim}
 % \end{scope}
 % $\begin{bNiceMatrix}[light-syntax,first-row,first-col]
-% {} α             β                 ;
-% α  2\cos α       {\cos α + \cos β} ;
-% β \cos α+\cos β  { 2 \cos β }
+% {} a             b                 ;
+% a  2\cos a       {\cos a + \cos b} ;
+% b \cos a+\cos b  { 2 \cos b }
 % \end{bNiceMatrix}$
 %
 % \medskip
@@ -1739,7 +1900,7 @@
 % not in an eventual exterior row. 
 %
 % For example, one may wish to define a new column type |?| in order to draw a
-% (black) thick rule of width 1~pt. The following definition will do the
+% (black) heavy rule of width 1~pt. The following definition will do the
 % job\footnote{The command |\vrule| is a TeX (and not LaTeX) command.}:
 %
 % \begin{Verbatim}
@@ -1746,7 +1907,7 @@
 % \newcolumntype{?}{!{\OnlyMainNiceMatrix{\vrule width 1 pt}}}
 % \end{Verbatim}
 %
-% The thick vertical rule won't extend in the exterior rows:
+% The heavy vertical rule won't extend in the exterior rows:
 % \medskip
 % \begin{scope}
 % \newcolumntype{?}{!{\OnlyMainNiceMatrix{\vrule width 1 pt}}}
@@ -1808,10 +1969,10 @@
 % & \Cdots & & &  \\
 % \end{pNiceMatrix}$
 % 
-% \subsection{The names of the Tikz nodes created by nicematrix}
+% \subsection{The names of the PGF nodes created by nicematrix}
 % 
 % We have said that, when a name is given to an environment of \pkg{nicematrix},
-% it's possible to access the Tikz nodes through this name (cf.
+% it's possible to access the PGF/Tikz nodes through this name (cf.
 % p.~\pageref{name}).
 %
 % That's the recommended way to access these nodes. However, we describe now the
@@ -1823,8 +1984,8 @@
 % command and not a counter).
 % 
 % For the environment of number~$n$, the node in row~$i$ and column~$j$ has the
-% name |nm-|$n$|-|$i$|-|$j$. The |medium| and |large| have the same name, suffixed by
-% |-medium| and |-large|.
+% name |nm-|$n$|-|$i$|-|$j$. The |medium| and |large| nodes have the same name,
+% suffixed by |-medium| and |-large|.
 % 
 % 
 % \subsection{Diagonal lines} 
@@ -1840,7 +2001,7 @@
 % \medskip
 % In the following examples, the first |\Ddots| instruction is written in color:
 % 
-% \medskip
+% % \medskip
 % \begin{scope}
 % \begin{minipage}{9.5cm}
 % Example with parallelization (default):
@@ -1904,7 +2065,7 @@
 % An instruction like |\Ldots|, |\Cdots|, etc. tries to determine the first
 % non-empty cells on both sides. However, an empty cell is not necessarily a
 % 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
+% ampersands~|&|). Indeed, a cell which only contains |\hspace*{1cm}| may be
 % considered as empty.
 %
 % \interitem
@@ -1923,12 +2084,8 @@
 % 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.
+% \item Each cell whose TeX ouput has a width equal to zero is empty.
 %
-% \medskip
-% \item A cell which contains a command |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots|
-% 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
@@ -1948,33 +2105,26 @@
 % |{amsmath}|, we can read: {\itshape The extra space of |\arraycolsep| that
 % \pkg{array} adds on each side is a waste so we remove it [in |{matrix}|]
 % (perhaps we should instead remove it from array in general, but that's a
-% harder task).} It's possible to suppress these spaces for a given environment
-% |{array}| with a construction like
-% |\begin{array}{@{}ccccc@{}}...\end{array}|.}. 
-% The environment |{matrix}| of \pkg{amsmath} and its variants (|{pmatrix}|,
-% |{vmatrix}|, etc.) of \pkg{amsmath} prefer to delete these spaces with
-% explicit instructions |\hskip -\arraycolsep|. The extension \pkg{nicematrix}
-% does the same in all its environments, |{NiceArray}| included. However, if the
-% user wants the environment |{NiceArray}| behaving by default like the
-% environment |{array}| of \pkg{array} (for example, when adapting an existing
-% document) it's possible to control this behaviour with the option
-% |exterior-arraycolsep|, set by the command |\NiceMatrixOptions|. With this
-% option, exterior spaces of length |\arraycolsep| will be inserted in the
-% environments |{NiceArray}| (the other environments of \pkg{nicematrix} are not
-% affected). 
+% harder task).}}. The environment |{matrix}| of
+% \pkg{amsmath} and its variants (|{pmatrix}|, |{vmatrix}|, etc.) of
+% \pkg{amsmath} prefer to delete these spaces with explicit instructions 
+% |\hskip -\arraycolsep|\footnote{And not by inserting |@{}| on both sides of the
+% preamble of the array. As a consequence, the length of the |\hline| is not
+% modified and may appear too long, in particular when using square brackets}.
+% The extension \pkg{nicematrix} does the same in all its environments,
+% |{NiceArray}| included. However, if the user wants the environment
+% |{NiceArray}| behaving by default like the environment |{array}| of
+% \pkg{array} (for example, when adapting an existing document) it's possible to
+% control this behaviour with the option |exterior-arraycolsep|, set by the
+% command |\NiceMatrixOptions|. With this option, exterior spaces of length
+% |\arraycolsep| will be inserted in the environments |{NiceArray}| (the other
+% environments of \pkg{nicematrix} are not affected).
 %
 %
 % \subsection{The class option draft}
 %
-% The package \pkg{nicematrix} is rather slow when drawing the dotted lines
-% (generated by |\Cdots|, |\Ldots|, |\Ddots|, etc. but also by |\hdottedline| or
-% the specifier |:|).\footnote{The main reason is that we want dotted lines with
-% round dots (and not square dots) with the same space on both extremities of
-% the lines. To achieve this goal, we have to construct our own system of dotted
-% lines.} 
-%
-% That's why, when the class option |draft| is used, the dotted lines are not
-% drawn, for a faster compilation. 
+% When the class option |draft| is used, the dotted lines are not drawn, for a
+% faster compilation.
 % 
 % \subsection{A technical problem with the argument of
 % \textbackslash\textbackslash}
@@ -2071,39 +2221,14 @@
 %
 % \subsection{Dotted lines}
 %
-% \medskip
-% A tridiagonal matrix:
-% 
-% \bigskip
-% \begin{BVerbatim}[baseline=c]
-% $\begin{pNiceMatrix}[nullify-dots]
-% 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{pNiceMatrix}[nullify-dots]
-% 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}$
 %
-% \vspace{2cm}
-%
 % A permutation matrix (as an example, we have raised the value of
-% |dotted-lines-margin|). 
+% |xdots/shorten|). 
 %
 % \label{permutation}
 % \bigskip
 % \begin{BVerbatim}[baseline=c]
-% $\begin{pNiceMatrix}[~emphase#dotted-lines-margin=0.6em@]
+% $\begin{pNiceMatrix}[~emphase#xdots/shorten=0.6em@]
 % 0       & 1 & 0 &        & \Cdots &   0    \\
 % \Vdots  &   &   & \Ddots &        & \Vdots \\
 %         &   &   & \Ddots &        &        \\
@@ -2113,7 +2238,7 @@
 % \end{pNiceMatrix}$
 % \end{BVerbatim}
 % \hspace{2.5cm}
-% $\begin{pNiceMatrix}[dotted-lines-margin=0.6em]
+% $\begin{pNiceMatrix}[xdots/shorten=0.6em]
 % 0       & 1 & 0 &        & \Cdots &   0    \\
 % \Vdots  &   &   & \Ddots &        & \Vdots \\
 %         &   &   & \Ddots &        &        \\
@@ -2124,11 +2249,12 @@
 %
 % \vspace{2cm}
 %
-% An example with |\Iddots|: \par\nobreak
+% An example with |\Iddots|. We have raised even more the value of
+% |xdots/shorten|.\par\nobreak 
 %
 % \bigskip
 % \begin{BVerbatim}[baseline=c]
-% $\begin{pNiceMatrix}
+% $\begin{pNiceMatrix}[~emphase#xdots/shorten=0.9em@]
 % 1       & \Cdots  &         & 1      \\
 % \Vdots  &         &         & 0      \\
 %         & ~emphase#\Iddots@ & ~emphase#\Iddots@ & \Vdots \\
@@ -2136,7 +2262,7 @@
 % \end{pNiceMatrix}$
 % \end{BVerbatim}
 % \hspace{4cm}
-% $\begin{pNiceMatrix}
+% $\begin{pNiceMatrix}[xdots/shorten=0.9em] 
 % 1       & \Cdots  &         & 1      \\
 % \Vdots  &         &         & 0      \\
 %         & \Iddots & \Iddots & \Vdots \\
@@ -2339,7 +2465,16 @@
 % 
 % \subsection{How to highlight cells of the matrix}
 %
+%
 % \label{highlight}
+% The following examples require Tikz (by default, \pkg{nicematrix} only loads
+% \textsc{pgf}) and the Tikz library |fit|. The following lines in the preamble
+% of your document may do the job:
+% \begin{verbatim}
+% \usepackage{tikz}
+% \usetikzlibrary{fit}
+% \end{verbatim}
+% 
 % \medskip
 % In order to highlight a cell of a matrix, it's possible to ``draw'' one of the
 % correspondant nodes (the ``normal node'', the ``medium node'' or the ``large
@@ -2347,8 +2482,10 @@
 % of the matrix (with the Tikz key ``|name suffix|'', it's easy to use the
 % ``large nodes''). 
 %
-% In order to have the continuity of the lines, we have to set
-%  |inner sep = -\pgflinewidth/2|.
+% We redraw the nodes with other nodes by using the Tikz library |fit|. Since we
+% want to redraw the nodes exactly, we have to set |inner sep = 0 pt| (if we
+% don't do that, the new nodes will be larger that the nodes created by
+% \pkg{nicematrix}). 
 %
 % \begin{Verbatim}
 % $\begin{pNiceArray}{>{\strut}CCCC}%
@@ -2356,7 +2493,7 @@
 %     code-after = {\begin{tikzpicture}
 %                      [~emphase#name suffix = -large@,
 %                       every node/.style = {draw,
-%                                            ~emphase#inner sep = -\pgflinewidth/2@}]
+%                                            ~emphase#inner sep = 0 pt@}]
 %                      \node [fit = (1-1)] {} ; 
 %                      \node [fit = (2-2)] {} ; 
 %                      \node [fit = (3-3)] {} ; 
@@ -2374,7 +2511,7 @@
 %     create-large-nodes,margin,extra-margin = 2pt,
 %     code-after = {\begin{tikzpicture}[name suffix = -large,
 %                                       every node/.style = {draw,
-%                                                            inner sep = -\pgflinewidth/2}]
+%                                                            inner sep = 0 pt}]
 %                      \node [fit = (1-1)] {} ; 
 %                      \node [fit = (2-2)] {} ; 
 %                      \node [fit = (3-3)] {} ; 
@@ -2387,12 +2524,12 @@
 % \end{pNiceArray}\]
 % 
 % We should remark that the rules we have drawn are drawn \emph{after} the
-% construction of the array and, hence, they don't spread the cells of the
-% array. We recall that, on the other side, the command |\hline| and the
-% specifier ``"|"'' spread the cells (when the package \pkg{array} is loaded
-% but, when the package \pkg{nicematrix} is loaded, \pkg{array} is always
-% loaded).\footnote{On the other side, the command |\cline| doesn't spread the
-% rows of the array.}
+% construction of the array and thus, they don't spread the cells of the
+% array. We recall that, on the other side, the command |\hline|, the specifier
+% ``"|"'' and the options |hlines| and |vlines| spread the cells (when the
+% package \pkg{array} is loaded but, when the package \pkg{nicematrix} is
+% loaded, \pkg{array} is always loaded).\footnote{On the other side, the command
+% |\cline| doesn't spread the rows of the array.}
 % 
 %
 % \vspace{1cm}
@@ -2494,7 +2631,7 @@
 % \end{pNiceMatrix}$
 % 
 % \vspace{1cm}
-% Considerer now the following matrix which we have named |example|.
+% Consider now the following matrix which we have named |example|.
 %
 % \medskip
 % \begin{Verbatim}
@@ -2663,12 +2800,12 @@
 % |first-row|. 
 % \begin{Verbatim}
 % \begin{bNiceArray}{C>{\strut}CCCC}[name=B,first-row]
-%       &        & C_j \\
-% b_{11} & \Cdots & b_{1j} & \Cdots & b_{1n} \\
-% \Vdots &       & \Vdots &       & \Vdots \\
-%        &       & b_{kj}  \\
-%        &       & \Vdots \\
-%  b_{n1}  & \Cdots & b_{nj} & \Cdots & b_{nn} 
+%         &        & C_j                      \\
+% b_{11}  & \Cdots & b_{1j} & \Cdots & b_{1n} \\
+% \Vdots  &        & \Vdots &        & \Vdots \\
+%         &        & b_{kj}                   \\
+%         &        & \Vdots                   \\
+%  b_{n1} & \Cdots & b_{nj} & \Cdots & b_{nn} 
 % \end{bNiceArray} \\ \\
 % \end{Verbatim}
 %
@@ -2676,11 +2813,11 @@
 % key |first-col|.
 % \begin{Verbatim}
 % \begin{bNiceArray}{CC>{\strut}CCC}[name=A,first-col]
-%     & a_{11} & \Cdots &  &  & a_{1n} \\
-%     & \Vdots &       &  &  & \Vdots \\
+%     & a_{11} & \Cdots &        &        & a_{1n} \\
+%     & \Vdots &        &        &        & \Vdots \\
 % L_i & a_{i1} & \Cdots & a_{ik} & \Cdots & a_{in} \\
-%     & \Vdots &       &  &  & \Vdots \\
-%     & a_{n1} & \Cdots &  &  & a_{nn} \\
+%     & \Vdots &        &        &        & \Vdots \\
+%     & a_{n1} & \Cdots &        &        & a_{nn} \\
 % \end{bNiceArray}
 % & 
 % \end{Verbatim}
@@ -2688,9 +2825,9 @@
 % In the matrix product, the two dotted lines have an open extremity.
 % \begin{Verbatim}
 % \begin{bNiceArray}{CC>{\strut}CCC}
-%        &         & & & \\
-%        &         & \Vdots \\
-% \Cdots &         & c_{ij}  \\
+%        & &        & & \\
+%        & & \Vdots     \\
+% \Cdots & & c_{ij}     \\
 % \\
 % \\
 % \end{bNiceArray} 
@@ -2778,20 +2915,18 @@
 % See: |http://mirrors.ctan.org/macros/latex/contrib/l3kernel/l3prefixes.pdf|
 % 
 %<@@=nicematrix>
-%
+% 
 % \bigskip
-% First, \pkg{tikz} and the Tikz library |fit| 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|}  
-% 
+% First, we load \pkg{pgfcore} and the module \pkg{shapes}. We do so because
+% it's not possible to use |\usepgfmodule| in |\ExplSyntaxOn|.
 %    \begin{macrocode}
-\RequirePackage{tikz}
-\usetikzlibrary{fit}
+\RequirePackage{pgfcore}
+\usepgfmodule{shapes}
 \RequirePackage{expl3}[2020/02/08]
 %    \end{macrocode}
+%
 % 
-% We give the traditionnal declaration of a package written with |expl3|:
+% We give the traditional declaration of a package written with |expl3|:
 %    \begin{macrocode}
 \RequirePackage{l3keys2e}
 \ProvidesExplPackage
@@ -2798,7 +2933,7 @@
   {nicematrix}
   {\myfiledate}
   {\myfileversion}
-  {Mathematical matrices with TikZ}
+  {Mathematical matrices with PGF/TikZ}
 %    \end{macrocode}
 % 
 %
@@ -2836,7 +2971,7 @@
 % this package for technical reasons. 
 % 
 % \bigskip
-% We load \pkg{array} and \pkg{amsmath}.
+% We load some packages.
 %    \begin{macrocode}
 \RequirePackage { array }
 \RequirePackage { amsmath }
@@ -2863,6 +2998,35 @@
 % \bigskip
 % \subsection*{Technical  definitions}
 %
+%    \begin{macrocode}
+\bool_new:N \c_@@_tikz_loaded_bool
+\AtBeginDocument
+  {
+    \@ifpackageloaded { tikz }
+      { 
+%    \end{macrocode}
+% In some constructions, we will have to use a |{pgfpicture}| which \emph{must}
+% be replaced by a |{tikzpicture}| if Tikz is loaded. However, this switch
+% between |{pgfpicture}| |{tikzpicture}| can't be done dynamically with a
+% conditional because, when the |external| Tikz library, the pair
+% |\tikzpicture|-|\endtikpicture| (or |\begin{tikzpicture}-\end{tikzpicture}|
+% must be statically ``visible'' (even when extenalization is not activated).
+%
+% That's why we create these token lists |\c_@@_pgfortikzpicture_tl| and
+% |\c_@@_endpgfortikzpicture_tl| which will be used to construct in a
+% |\AtBeginDocument| the correct version of some commands.
+%    \begin{macrocode}
+        \bool_set_true:N \c_@@_tikz_loaded_bool 
+        \tl_const:Nn \c_@@_pgfortikzpicture_tl { \exp_not:N \tikzpicture }
+        \tl_const:Nn \c_@@_endpgfortikzpicture_tl { \exp_not:N \endtikzpicture }
+      }
+      { 
+        \tl_const:Nn \c_@@_pgfortikzpicture_tl { \exp_not:N \pgfpicture }
+        \tl_const:Nn \c_@@_endpgfortikzpicture_tl { \exp_not:N \endpgfpicture }
+      }
+  }
+%    \end{macrocode}
+% 
 % We test whether the current class is \cls{revtex4-1} or \cls{revtex4-2}
 % because these classes redefines |\array| (of \pkg{array}) in a way
 % incompatible with our programmation.
@@ -2885,8 +3049,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\bool_if:NT \c_@@_draft_bool 
-  { \msg_warning:nn { nicematrix }  { Draft~mode } }
+\bool_if:NT \c_@@_draft_bool { \msg_warning:nn { nicematrix }  { Draft~mode } }
 %    \end{macrocode}
 % 
 %
@@ -2924,6 +3087,12 @@
 \int_new:N \g_@@_env_int
 %    \end{macrocode}
 % 
+%    \begin{macrocode}
+\cs_new:Npn \@@_env: { nm - \int_use:N \g_@@_env_int } 
+\cs_new_protected:Npn \@@_qpoint: #1 
+  { \pgfpointanchor { \@@_env: - #1 } { center } } 
+%    \end{macrocode}
+% 
 % \bigskip
 % We also define a counter to count the environments |{NiceMatrixBlock}|.
 %    \begin{macrocode}
@@ -2978,29 +3147,6 @@
   }
 %    \end{macrocode}
 %
-% \bigskip
-% Consider the following code:
-% \begin{Verbatim}
-% $\begin{pNiceMatrix}
-% a & b & c \\
-% d & e & \Vdots \\
-% f & \Cdots \\
-% g & h & i \\
-% \end{pNiceMatrix}$
-% \end{Verbatim}
-%
-% 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}
-\bool_new:N \l_@@_impossible_line_bool
-%    \end{macrocode}
 % 
 % 
 % \bigskip
@@ -3019,13 +3165,9 @@
   }
 %    \end{macrocode}
 %
-% \bigskip
-% We have put a argument |w| (\emph{weird}) for the following function because
-% its argument should be a specifier of \pkg{pgf} point between rounded
-% brackets. 
 %    \begin{macrocode}
-\cs_set_protected:Npn \@@_extract_coords:w
-  { \tikz at parse@node \pgfutil at firstofone }
+\colorlet { nicematrix-last-col } { . }
+\colorlet { nicematrix-last-row } { . }
 %    \end{macrocode}
 % 
 % \bigskip
@@ -3038,19 +3180,21 @@
 %    \end{macrocode}
 %
 % \bigskip
-% The length |\l_@@_dotted_lines_margin_dim| is the minimal distance between a
+% The length |\l_@@_xdots_shorten_dim| is the minimal distance between a
 % node (in fact an anchor of that node) and a dotted line (we say ``minimal''
 % because, by definition, a dotted line is not a continuous line and, therefore,
 % this distance may vary a little).
 %    \begin{macrocode}
-\dim_new:N \l_@@_dotted_lines_margin_dim
-\dim_set:Nn \l_@@_dotted_lines_margin_dim { 0.3 em }
+\dim_new:N \l_@@_xdots_shorten_dim
+\dim_set:Nn \l_@@_xdots_shorten_dim { 0.3 em }
 %    \end{macrocode}
 % 
 % \bigskip
-% The length |\l_@@_radius_dim| is the radius of the dots for the dotted lines.
-% The default value is 0.53~pt but it will be changed if the option |small| is
-% used (to 0.37~pt).
+% The length |\l_@@_radius_dim| is the radius of the dots for the dotted lines
+% (for |\hdottedline| and |\dottedline| and for all the other dotted lines when
+% |line-style| is equal to |standard|, which is the initial value). The initial
+% value is 0.53~pt but it will be changed if the option |small| is used (to
+% 0.37~pt).
 %    \begin{macrocode}
 \dim_new:N \l_@@_radius_dim
 \dim_set:Nn \l_@@_radius_dim { 0.53 pt }
@@ -3057,7 +3201,8 @@
 %    \end{macrocode}
 %
 % \bigskip
-% The name of the current environment or the current command (despite the name).
+% The name of the current environment or the current command (despite the name
+% which contains \textsl{env}).
 %    \begin{macrocode}
 \str_new:N \g_@@_name_env_str
 %    \end{macrocode}
@@ -3071,8 +3216,9 @@
 %    \end{macrocode}
 % 
 % The following control sequence will be able to reconstruct the full name of
-% the current command or environment (despite the name). This command must
-% \emph{not} be protected since it's used in error messages.
+% the current command or environment (despite the name which contains
+% \textsl{env}). This command must \emph{not} be protected since it's used in
+% error messages.
 %    \begin{macrocode}
 \cs_new:Npn \@@_full_name_env:
   { 
@@ -3084,6 +3230,7 @@
 % 
 % \bigskip
 %    \begin{macrocode}
+\tl_new:N \g_@@_internal_code_after_tl
 \tl_new:N \g_@@_code_after_tl
 %    \end{macrocode}
 % 
@@ -3104,7 +3251,40 @@
 \bool_new:N \g_@@_row_of_col_done_bool
 %    \end{macrocode}
 % 
+%    \begin{macrocode}
+\tl_new:N \l_@@_initial_suffix_tl 
+\tl_new:N \l_@@_initial_anchor_tl 
+\tl_new:N \l_@@_final_suffix_tl 
+\tl_new:N \l_@@_final_anchor_tl 
+%    \end{macrocode}
+% 
+%    \begin{macrocode}
+\dim_new:N \l_@@_x_initial_dim
+\dim_new:N \l_@@_y_initial_dim
+\dim_new:N \l_@@_x_final_dim
+\dim_new:N \l_@@_y_final_dim
+%    \end{macrocode}
+% 
+%    \begin{macrocode}
+\dim_new:N \l_tmpc_dim
+\dim_new:N \l_tmpd_dim
+%    \end{macrocode}
 %
+%    \begin{macrocode}
+\bool_new:N \g_@@_empty_cell_bool
+%    \end{macrocode}
+% 
+% \medskip
+% The token list |\l_@@_xdots_line_style_tl| corresponds to the option |tikz| of the
+% commands |\Cdots|, |\Ldots|, etc. and of the options |line-style| for the
+% environments and |\NiceMatrixOptions|. The constant |\c_@@_standard_tl| will
+% be used in some tests.
+%    \begin{macrocode}
+\tl_new:N \l_@@_xdots_line_style_tl
+\tl_const:Nn \c_@@_standard_tl { standard }
+\tl_set_eq:NN \l_@@_xdots_line_style_tl \c_@@_standard_tl
+%    \end{macrocode}
+% 
 % \bigskip
 % \textbf{Variables for the exterior rows and columns}\par\nobreak
 %
@@ -3250,14 +3430,6 @@
 %    \begin{macrocode}
 \cs_set_protected:Npn \@@_adapt_S_column:
   {
-%    \end{macrocode}
-% In the preamble of the LaTeX document, the boolean |\c_@@_siunitx_loaded_bool|
-% won't be known. That's why we test the existence of
-% |\c_@@_siunitx_loaded_bool| and not its value.\footnote{Indeed,
-% \pkg{nicematrix} may be used in the preamble of the LaTeX document. For
-% example, you can compose a matrix in a box before the loading of
-% \pkg{arydshln} (not totally compatible with \pkg{nicematrix}).} 
-%    \begin{macrocode}   
     \bool_if:NT \c_@@_siunitx_loaded_bool
       { 
         \group_begin:
@@ -3313,6 +3485,12 @@
   }
 %    \end{macrocode}
 % 
+% \bigskip
+% The following command is only for efficiency. It must \emph{not} be protected
+% because it will be used (for instance) in names of \textsc{pgf} nodes.
+%    \begin{macrocode}
+\cs_new:Npn \@@_succ:N #1 { \the \numexpr #1 + 1 \relax }
+%    \end{macrocode}
 % 
 % \bigskip 
 % \subsection*{The options}
@@ -3392,14 +3570,14 @@
 % ``medium nodes'' are created in the array. Idem for the ``large nodes''.
 %    \begin{macrocode}
 \bool_new:N \l_@@_medium_nodes_bool
-\bool_new:N \g_@@_medium_nodes_bool
 \bool_new:N \l_@@_large_nodes_bool
-\bool_new:N \g_@@_large_nodes_bool
 %    \end{macrocode}
 %
 % \bigskip
-% The dimension |\l_@@_left_margin_dim| correspondto the option |left-margin|
-% (idem for the right margin).
+% The dimension |\l_@@_left_margin_dim| correspond to the option |left-margin|.
+% Idem for the right margin. These parameters are involved in the creation of
+% the ``medium nodes'' but also in the placement of the delimiters and the
+% drawing of the horizontal dotted lines (|\hdottedline|).
 %    \begin{macrocode}
 \dim_new:N \l_@@_left_margin_dim
 \dim_new:N \l_@@_right_margin_dim
@@ -3432,6 +3610,14 @@
 %    \end{macrocode}
 %
 % \medskip
+% The following parameter is for the color the dotted lines drawn by |\Cdots|,
+% |\Ldots|, |\Vdots|, |\Ddots|, |\Iddots| and |\Hdotsfor| but \emph{not} the
+% dotted lines drawn by |\hdottedline| and ``|:|''.
+%    \begin{macrocode} 
+\tl_new:N \l_@@_xdots_color_tl
+%    \end{macrocode}
+% 
+% \medskip
 % Sometimes, we want to have several arrays vertically juxtaposed in order to
 % have an alignment of the columns of these arrays. To acheive this goal, one
 % may wish to use the same width for all the columns (for example with the
@@ -3450,11 +3636,35 @@
 % First, we define a set of keys ``|NiceMatrix / Global|'' which will be used
 % (with the mechanism of |.inherit:n|) by other sets of keys.
 %    \begin{macrocode}
+\keys_define:nn { NiceMatrix / xdots }
+  {
+    line-style .code:n = 
+     { 
+       \bool_lazy_or:nnTF 
+%    \end{macrocode}
+% We can't use |\c_@@_tikz_loaded_bool| to test whether \pkg{tikz} is loaded
+% because |\NiceMatrixOptions| may be used in the preamble of the document.
+%    \begin{macrocode}
+        { \cs_if_exist_p:N \tikzpicture }
+        { \str_if_eq_p:nn { #1 } { standard } }
+        { \tl_set:Nn \l_@@_xdots_line_style_tl { #1 } } 
+        { \@@_error:n { bad~option~for~line-style } } 
+     } ,
+    line-style .value_required:n = true ,
+    color .tl_set:N = \l_@@_xdots_color_tl ,
+    color .value_required:n = true ,
+    shorten .dim_set:N = \l_@@_xdots_shorten_dim ,
+    shorten .value_required:n = true ,
+    unknown .code:n = \@@_error:n { Unknown~option~for~xdots } 
+  }
+%    \end{macrocode}
+%
+% 
+%    \begin{macrocode}
 \keys_define:nn { NiceMatrix / Global }
   {
+    xdots .code:n = \keys_set:nn { NiceMatrix / xdots } { #1 } , 
     max-delimiter-width .bool_set:N = \l_@@_max_delimiter_width_bool ,
-    dotted-lines-margin .dim_set:N = \l_@@_dotted_lines_margin_dim ,
-    dotted-lines-margin .value_required:n = true ,
     light-syntax .bool_set:N = \l_@@_light_syntax_bool ,
     light-syntax .default:n = true , 
     end-of-row .tl_set:N = \l_@@_end_of_row_tl ,
@@ -3501,7 +3711,8 @@
     extra-left-margin .dim_set:N = \l_@@_extra_left_margin_dim ,
     extra-right-margin .dim_set:N = \l_@@_extra_right_margin_dim ,
     extra-margin .meta:n = 
-      { extra-left-margin = #1 , extra-right-margin = #1 } 
+      { extra-left-margin = #1 , extra-right-margin = #1 } ,
+    extra-margin .value_required:n = true 
   }
 %    \end{macrocode}
 %
@@ -3517,6 +3728,11 @@
         { \dim_set:Nn \l_@@_columns_width_dim { #1 } } , 
     columns-width .value_required:n = true ,
     name .code:n = 
+%    \end{macrocode}
+% We test whether we are in the measuring phase of an environment of
+% \pkg{amsmath} (always loaded by \pkg{nicematrix}) because we want to avoid a
+% fallaicous message of duplicate name in this case.
+%    \begin{macrocode}
       \legacy_if:nF { measuring@ }
         {
           \str_set:Nn \l_tmpa_str { #1 }
@@ -3543,24 +3759,28 @@
 \keys_define:nn { NiceMatrix }
   { 
     NiceMatrixOptions .inherit:n = 
-      {  
+      { 
         NiceMatrix / Global ,
       } ,
+    NiceMatrixOptions / xdots .inherit:n = NiceMatrix / xdots ,
     NiceMatrix .inherit:n = 
       { 
         NiceMatrix / Global ,
-        NiceMatrix / Env 
+        NiceMatrix / Env ,
       } ,
+    NiceMatrix / xdots .inherit:n = NiceMatrix / xdots ,
     NiceArray .inherit:n = 
       { 
         NiceMatrix / Global ,
         NiceMatrix / Env ,
       } ,
+    NiceArray / xdots .inherit:n = NiceMatrix / xdots ,
     pNiceArray .inherit:n = 
       { 
         NiceMatrix / Global ,
         NiceMatrix / Env ,
-      } 
+      } ,
+    pNiceArray / xdots .inherit:n = NiceMatrix / xdots 
   }
 %    \end{macrocode}
 % 
@@ -3629,10 +3849,6 @@
           { \@@_error:n { Bad~value~for~letter~for~dotted~lines } } 
       } ,
     letter-for-dotted-lines .value_required:n = true ,
-%    \end{macrocode}
-%
-% \bigskip
-%    \begin{macrocode}
     unknown .code:n  = \@@_error:n { Unknown~key~for~NiceMatrixOptions } 
   }
 %    \end{macrocode}
@@ -3662,6 +3878,10 @@
     last-col .code:n = \tl_if_empty:nTF {#1}
                          { \@@_error:n { last-col~empty~for~NiceMatrix } }
                          { \int_set:Nn \l_@@_last_col_int { #1 } } ,
+    l .code:n = \tl_set:Nn \l_@@_type_of_col_tl L ,
+    r .code:n = \tl_set:Nn \l_@@_type_of_col_tl R ,
+    L .code:n = \tl_set:Nn \l_@@_type_of_col_tl L ,
+    R .code:n = \tl_set:Nn \l_@@_type_of_col_tl R ,
     unknown .code:n = \@@_error:n { Unknown~option~for~NiceMatrix } 
   }
 %    \end{macrocode}
@@ -3737,12 +3957,8 @@
 % in the |\halign| that we don't want to take into account. 
 %    \begin{macrocode}
     \int_compare:nNnT \c at jCol = 1
-      { 
-        \int_compare:nNnT \l_@@_first_col_int = 1
-          \@@_begin_of_row: 
-      }
-    \int_gset:Nn \g_@@_col_total_int 
-      { \int_max:nn \g_@@_col_total_int \c at jCol }
+      { \int_compare:nNnT \l_@@_first_col_int = 1 \@@_begin_of_row: }
+    \int_gset:Nn \g_@@_col_total_int { \int_max:nn \g_@@_col_total_int \c at jCol }
 %    \end{macrocode}
 % The content of the cell is composed in the box |\l_@@_cell_box| because we want
 % to compute some dimensions of the box. The |\hbox_set_end:| corresponding to
@@ -3762,10 +3978,19 @@
 % corners of the matrix.
 %    \begin{macrocode}
     \int_compare:nNnTF \c at iRow = 0 
-      { \int_compare:nNnT \c at jCol > 0 \l_@@_code_for_first_row_tl }
+      { 
+        \int_compare:nNnT \c at jCol > 0 
+          { 
+            \l_@@_code_for_first_row_tl 
+            \xglobal \colorlet { nicematrix-first-row } { . }
+          }
+      }
       {
         \int_compare:nNnT \c at iRow = \l_@@_last_row_int
-          \l_@@_code_for_last_row_tl 
+          {
+            \l_@@_code_for_last_row_tl 
+            \xglobal \colorlet { nicematrix-last-row } { . }
+          }
       }
   }
 %    \end{macrocode}
@@ -3781,8 +4006,18 @@
     \dim_gset_eq:NN \g_@@_dp_ante_last_row_dim \g_@@_dp_last_row_dim 
     \dim_gset:Nn \g_@@_dp_last_row_dim { \box_dp:N \@arstrutbox }
     \dim_gset:Nn \g_@@_ht_last_row_dim { \box_ht:N \@arstrutbox }
-    \tikz [ remember~picture , baseline ] \coordinate 
-      ( nm - \int_use:N \g_@@_env_int - row - \int_use:N \c at iRow - base ) ; 
+    \pgfpicture 
+    \pgfrememberpicturepositiononpagetrue
+    \pgfcoordinate 
+      { \@@_env: - row - \int_use:N \c at iRow - base } 
+      \pgfpointorigin 
+    \str_if_empty:NF \l_@@_name_str
+      {
+        \pgfnodealias 
+          { \@@_env: - row - \int_use:N \c at iRow - base } 
+          { \l_@@_name_str - row - \int_use:N \c at iRow - base } 
+      }
+    \endpgfpicture
   }
 %    \end{macrocode}
 % 
@@ -3834,72 +4069,80 @@
     \@@_update_for_first_and_last_row:
 %    \end{macrocode}
 % 
-% Now, we can create the Tikz node of the cell.
+% \medskip
+% If the cell is empty, or may be considered as if, we must not create the
+% \textsc{pgf} node, for two reasons:
+% \begin{itemize}
+% \item it's a waste of time since such a node would be rather pointless;
+% \item we test the existence of these nodes in order to determine whether a
+% cell is empty when we search the extremities of a dotted line.
+% \end{itemize}
+% However, it's very difficult to determine whether a cell is empty. As of now,
+% we use the following technic:
+% \begin{itemize}
+% \item if the width of the box |\l_@@_cell_box| (created with the content of
+% the cell) is equal to zero, we consider the cell as empty (however,
+% this is not perfect since the user may have use a |\rlap|, a |\llap| or a
+% |\mathclap| of \pkg{mathtools}.
+% \item the cells with a command |\Ldots| or |\Cdots|, |\Vdots|, etc.,
+% should also be considered as empty; if |nullify-dots| is in force, there would
+% be nothing to do (in this case the previous commands only write an instruction
+% in a kind of |code-after|); however, if |nullify-dots| is not in force, a
+% phantom of |\ldots|, |\cdots|, |\vdots| is inserted and its width is not equal
+% to zero; that's why these commands raise a boolean |\g_@@_empty_cell_bool| and
+% we begin by testing this boolean.
+% \end{itemize}
 %    \begin{macrocode}
-    \tikz 
-      [ 
-        remember~picture , 
-        inner~sep = \c_zero_dim , 
-        minimum~width = \c_zero_dim , 
-        baseline 
-      ]
-    \node 
-      [
-        anchor = base ,
-        name = nm - \int_use:N \g_@@_env_int -
-                    \int_use:N \c at iRow -
-                    \int_use:N \c at jCol ,
-        alias = 
-          \str_if_empty:NF \l_@@_name_str
-            { 
-              \l_@@_name_str -
-              \int_use:N \c at iRow -
-              \int_use:N \c at jCol
-            } 
-      ] 
-    { \box_use_drop:N \l_@@_cell_box } ;
+    \bool_if:NTF \g_@@_empty_cell_bool
+      { 
+        \box_use_drop:N \l_@@_cell_box 
+        \bool_gset_false:N \g_@@_empty_cell_bool
+      }
+      {
+        \dim_compare:nNnTF { \box_wd:N \l_@@_cell_box } > \c_zero_dim
+          \@@_node_for_the_cell:
+          { \box_use_drop:N \l_@@_cell_box }
+      }
+    \bool_gset_false:N \g_@@_empty_cell_bool
   } 
 %    \end{macrocode}
-%
 % 
+% \medskip
+% The following command creates the \textsc{pgf} name of the node with, of
+% course, |\l_@@_cell_box| as the content.
 %    \begin{macrocode}
-\cs_generate_variant:Nn \dim_set:Nn { N x }
-%    \end{macrocode}
-% 
-% \bigskip
-% In the environment |{NiceArrayWithDelims}|, we will have to redefine the
-% column types |w| and |W|. The redefinition of these two column types are very
-% close and that's why we use a macro |\@@_renewcolumntype:nn|. The first
-% argument is the type of the column (|w| or |W|) and the second argument is a
-% code inserted at a special place and which is the only difference between the
-% two definitions.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_renewcolumntype:nn #1 #2
+\cs_new_protected:Npn \@@_node_for_the_cell:
   {
-    \newcolumntype #1 [ 2 ]
+    \pgfpicture 
+    \pgfsetbaseline \c_zero_dim
+    \pgfrememberpicturepositiononpagetrue
+    \pgfset
       {
-        > {
-            \hbox_set:Nw \l_@@_cell_box
-            \@@_Cell:
-          }
-        c
-        < {
-            \@@_end_Cell:
-            \hbox_set_end:
-            #2
-            \makebox [ ##2 ] [ ##1 ] { \box_use_drop:N \l_@@_cell_box } 
-          }
+        inner~sep = \c_zero_dim , 
+        minimum~width = \c_zero_dim 
       }
+    \pgfnode 
+      { rectangle } 
+      { base } 
+      { \box_use_drop:N \l_@@_cell_box }
+      { \@@_env: - \int_use:N \c at iRow - \int_use:N \c at jCol }
+      { }
+    \str_if_empty:NF \l_@@_name_str
+      {
+        \pgfnodealias
+          { \l_@@_name_str - \int_use:N \c at iRow - \int_use:N \c at jCol }
+          { \@@_env: - \int_use:N \c at iRow - \int_use:N \c at jCol } 
+      }
+    \endpgfpicture
   }
 %    \end{macrocode}
 % 
-% 
 % \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 the corresponding |\g_@@_|\textsl{type}|_lines_tl| the
-% instruction which will actually draw the line after the construction of the 
-% matrix. 
+% The first argument of the following command |\@@_instruction_of_type:nn|
+% defined below is the type of the instruction (|Cdots|, |Vdots|, |Ddots|,
+% etc.). The second argument is the list of options. This command writes in the
+% corresponding |\g_@@_|\textsl{type}|_lines_tl| the instruction which will
+% actually draw the line after the construction of the matrix.
 %
 % \medskip
 % For example, for the following matrix,
@@ -3909,13 +4152,13 @@
 % \begin{pNiceMatrix}
 % 1 & 2 & 3 & 4 \\
 % 5 & \Cdots & & 6 \\
-% 7 & \Cdots \\
+% 7 & \Cdots[color=red] \\
 % \end{pNiceMatrix}
 % \end{BVerbatim}
 % $\begin{pNiceMatrix}
 % 1 & 2 & 3 & 4 \\
 % 5 & \Cdots & & 6 \\
-% 7 & \Cdots \\
+% 7 & \Cdots[color=red] \\
 % \end{pNiceMatrix}$
 %
 % \smallskip
@@ -3924,19 +4167,20 @@
 % \smallskip
 % \begin{scope}
 % \color{gray}
-% \verb|\@@_draw_Cdots:nn {2}{2}|
+% \verb|\@@_draw_Cdots:nnn {2}{2}{}|
 %
-% \verb|\@@_draw_Cdots:nn {3}{2}|
+% \verb|\@@_draw_Cdots:nnn {3}{2}{color=red}|
 % \end{scope} 
 % 
-%
+% 
+% \bigskip
 % We begin with a test of the flag |\c_@@_draft_bool| because, if the key
 % |draft| is used, the dotted lines are not drawn.
 %    \begin{macrocode}
 \bool_if:NTF \c_@@_draft_bool
-  { \cs_set_protected:Npn \@@_instruction_of_type:n #1 { } }
+  { \cs_set_protected:Npn \@@_instruction_of_type:nn #1 #2 { } }
   {
-    \cs_new_protected:Npn \@@_instruction_of_type:n #1
+    \cs_new_protected:Npn \@@_instruction_of_type:nn #1 #2
       { 
 %    \end{macrocode}
 % It's important to use a |\tl_gput_right:cx| and not a |\tl_gput_left:cx|
@@ -3946,9 +4190,13 @@
         \tl_gput_right:cx 
           { g_@@_ #1 _ lines _ tl }
           { 
-            \use:c { @@ _ draw _ #1 : nn } 
+            \use:c { @@ _ draw _ #1 : nnn }
               { \int_use:N \c at iRow } 
               { \int_use:N \c at jCol }
+%    \end{macrocode}
+% Maybe we should prevent the expansion of the list of key-value.
+%    \begin{macrocode}
+              { #2 } 
           }
       }  
   }
@@ -4001,13 +4249,21 @@
   { 
     \int_gzero:N \c at jCol 
 %    \end{macrocode}
-% The |\hbox:n| is mandatory.
+% The |\hbox:n| (or |\hbox|) is mandatory.
 %    \begin{macrocode}
-    \hbox:n
+    \hbox
       {
-        \tikz [ remember~picture ] 
-        \coordinate
-        ( nm - \int_use:N \g_@@_env_int - row - \int_eval:n { \c at iRow + 1 } ) ;  
+        \pgfpicture 
+        \pgfrememberpicturepositiononpagetrue
+        \pgfcoordinate { \@@_env: - row - \@@_succ:N \c at iRow }  
+          \pgfpointorigin 
+        \str_if_empty:NF \l_@@_name_str
+          {
+            \pgfnodealias 
+              { \@@_env: - row - \int_use:N \c at iRow - row } 
+              { \l_@@_name_str - row - \int_use:N \c at iRow - row } 
+          }   
+        \endpgfpicture  
       }
 %    \end{macrocode}
 % We add the potential horizontal lines specified by the option |hlines|.
@@ -4066,15 +4322,6 @@
 %    \end{macrocode}
 %
 % 
-% \medskip
-% We switch to a global version of the |\l_@@_medium_nodes_bool| and
-% |\l_@@_large_nodes_bool| because these booleans may be raised in cells of the
-% array (for exemple in commands |\Block|).
-%    \begin{macrocode}
-    \bool_gset_eq:NN \g_@@_medium_nodes_bool \l_@@_medium_nodes_bool
-    \bool_gset_eq:NN \g_@@_large_nodes_bool \l_@@_large_nodes_bool
-%    \end{macrocode}
-%
 % \bigskip
 % The environment |{array}| uses internally the command |\ialign|. We change the
 % definition of |\ialign| for several reasons. In particular, |\ialign| sets
@@ -4136,8 +4383,16 @@
     \newcolumntype C { > \@@_Cell: c < \@@_end_Cell: }
     \newcolumntype R { > \@@_Cell: r < \@@_end_Cell: }
 %    \end{macrocode}    
-%
+% We keep in memory the old versions or |\ldots|, |\cdots|, etc. only because we
+% use them inside |\phantom| commands in order that the new commands |\Ldots|,
+% |\Cdots|, etc. give the same spacing (except when the option |nullify-dots| is
+% used). 
 %    \begin{macrocode}
+    \cs_set_eq:NN \@@_ldots \ldots
+    \cs_set_eq:NN \@@_cdots \cdots
+    \cs_set_eq:NN \@@_vdots \vdots
+    \cs_set_eq:NN \@@_ddots \ddots
+    \cs_set_eq:NN \@@_iddots \iddots
     \cs_set_eq:NN \firsthline \hline
     \cs_set_eq:NN \lasthline \hline
     \cs_set_eq:NN \Ldots \@@_Ldots
@@ -4210,9 +4465,41 @@
 %    \begin{macrocode}
     \cs_set_eq:NN \NC at find@w \relax
     \cs_set_eq:NN \NC at find@W \relax
-    \@@_renewcolumntype:nn w { }
-    \@@_renewcolumntype:nn W { \cs_set_eq:NN \hss \hfil }
+    \newcolumntype w [ 2 ]
+      {
+        > {
+            \hbox_set:Nw \l_@@_cell_box
+            \@@_Cell:
+          }
+        c
+        < {
+            \@@_end_Cell:
+            \hbox_set_end:
 %    \end{macrocode}
+% The |\str_lowercase:n| is only for giving the user the ability to write
+% |wC{1cm}| instead of |wc{1cm}| for homogeneity with the letters |L|, |C| and
+% |R| used elsewhere in the preamble instead of |l|, |c| and |r|.
+%    \begin{macrocode}
+            \makebox [ ##2 ] [ \str_lowercase:n { ##1 } ] 
+               { \box_use_drop:N \l_@@_cell_box }  
+          }
+      }
+    \newcolumntype W [ 2 ]
+      {
+        > {
+            \hbox_set:Nw \l_@@_cell_box
+            \@@_Cell:
+          }
+        c
+        < {
+            \@@_end_Cell:
+            \hbox_set_end:
+            \cs_set_eq:NN \hss \hfil
+            \makebox [ ##2 ] [ \str_lowercase:n { ##1 } ] 
+              { \box_use_drop:N \l_@@_cell_box } 
+          }
+      }
+%    \end{macrocode}
 %                               
 % \bigskip
 % By default, the letter used to specify a dotted line in the preamble of an
@@ -4241,7 +4528,7 @@
             \int_compare:nNnF \c at iRow = 0 
               { 
                 \int_compare:nNnF \c at iRow = \l_@@_last_row_int
-                  { \skip_horizontal:n { 2 \l_@@_radius_dim } }
+                  { \skip_horizontal:N 2\l_@@_radius_dim }
               }
 %    \end{macrocode}
 %
@@ -4268,10 +4555,10 @@
             \int_compare:nNnT \c at jCol > \g_@@_last_vdotted_col_int
               {
                 \int_gset_eq:NN \g_@@_last_vdotted_col_int \c at jCol
-                \tl_gput_right:Nx \g_@@_code_after_tl
+                \tl_gput_right:Nx \g_@@_internal_code_after_tl
 %    \end{macrocode}
 % The command |\@@_vdottedline:n| is protected, and, therefore, won't be
-% expanded before writing on |\g_@@_code_after_tl|.
+% expanded before writing on |\g_@@_internal_code_after_tl|.
 %    \begin{macrocode}
                   { \@@_vdottedline:n { \int_use:N \c at jCol } }
               }
@@ -4303,6 +4590,8 @@
 %    \begin{macrocode}
 \NewDocumentEnvironment { NiceArrayWithDelims } { m m O { } m ! O { } }
   { 
+    \tl_set:Nn \l_@@_left_delim_tl { #1 }
+    \tl_set:Nn \l_@@_right_delim_tl { #2 }
     \bool_gset_false:N \g_@@_row_of_col_done_bool
     \str_if_empty:NT \g_@@_name_env_str 
       { \str_gset:Nn \g_@@_name_env_str { NiceArrayWithDelims } } 
@@ -4312,10 +4601,8 @@
     \bool_set_true:N \l_@@_in_env_bool
 %    \end{macrocode}
 %
-% We deactivate Tikz externalization. 
-%
-% Since we use Tikz pictures with the options |overlay| and |remember picture|,
-% there would be errors).
+% We deactivate Tikz externalization because we will use \textsc{pgf} pictures with the
+% options |overlay| and |remember picture| (or equivalent forms).
 %    \begin{macrocode}
     \cs_if_exist:NT \tikz at library@external at loaded
       {
@@ -4333,6 +4620,7 @@
       { \dim_gzero_new:N \g_@@_max_cell_width_dim }
 %    \end{macrocode}
 %
+% 
 % We do a redefinition of |\@arrayrule| because we want that the vertical rules
 % drawn by "|" in the preamble of the array don't extend in the potential
 % exterior rows.
@@ -4343,7 +4631,7 @@
 %
 % The set of keys is not exactly the same for |{NiceArray}| and for the variants
 % of |{NiceArray}| (|{pNiceArray}|, |{bNiceArray}|, etc.) because, for
-% |{NiceArray}|, we have the options |t|, |c| and |b|.
+% |{NiceArray}|, we have the options |t|, |c|, |b| and |baseline|.
 %    \begin{macrocode}
     \bool_if:NTF \l_@@_NiceArray_bool 
       { \keys_set:nn { NiceMatrix / NiceArray } }
@@ -4404,27 +4692,18 @@
     \dim_zero_new:N \l_@@_left_delim_dim
     \dim_zero_new:N \l_@@_right_delim_dim
     \bool_if:NTF \l_@@_NiceArray_bool
-      {
+      { 
         \dim_gset:Nn \l_@@_left_delim_dim { 2 \arraycolsep }
         \dim_gset:Nn \l_@@_right_delim_dim { 2 \arraycolsep }
       }
       { 
-        \hbox_set:Nn \l_tmpa_box
-          {
-            \c_math_toggle_token
-            \left #1 \vcenter to 3 cm { } \right.
-            \c_math_toggle_token
-          }
-        \dim_set:Nn \l_@@_left_delim_dim 
-          { \box_wd:N \l_tmpa_box - \nulldelimiterspace }
-        \hbox_set:Nn \l_tmpa_box
-          {
-            \c_math_toggle_token
-            \left. \vcenter to 3 cm { } \right #2
-            \c_math_toggle_token
-          }
-        \dim_set:Nn \l_@@_right_delim_dim 
-          { \box_wd:N \l_tmpa_box - \nulldelimiterspace }
+%    \end{macrocode}
+% The command |\bBigg@| is a command of \pkg{amsmath}.
+%    \begin{macrocode}
+        \hbox_set:Nn \l_tmpa_box { $ \bBigg@ 5 #1 $ }
+        \dim_set:Nn \l_@@_left_delim_dim { \box_wd:N \l_tmpa_box }
+        \hbox_set:Nn \l_tmpa_box { $\bBigg@ 5 #2 $ }
+        \dim_set:Nn \l_@@_right_delim_dim { \box_wd:N \l_tmpa_box }
       }
 %    \end{macrocode}
 % 
@@ -4442,11 +4721,11 @@
     \int_compare:nNnTF \l_@@_first_col_int = 0
       { \tl_put_left:NV \l_tmpa_tl \c_@@_preamble_first_col_tl }
       {
-        \bool_if:nT 
+        \bool_lazy_all:nT 
           { 
-                 \l_@@_NiceArray_bool 
-            && ! \l_@@_vlines_bool 
-            && ! \l_@@_exterior_arraycolsep_bool
+            \l_@@_NiceArray_bool 
+            { \bool_not_p:n \l_@@_vlines_bool } 
+            { \bool_not_p:n \l_@@_exterior_arraycolsep_bool }
           }
           { \tl_put_left:Nn \l_tmpa_tl { @ { } } }
       }
@@ -4453,11 +4732,11 @@
     \int_compare:nNnTF \l_@@_last_col_int > { -1 }
       { \tl_put_right:NV \l_tmpa_tl \c_@@_preamble_last_col_tl }
       { 
-        \bool_if:nT 
+        \bool_lazy_all:nT
           { 
-                 \l_@@_NiceArray_bool 
-            && ! \l_@@_vlines_bool 
-            && ! \l_@@_exterior_arraycolsep_bool
+            \l_@@_NiceArray_bool 
+            { \bool_not_p:n \l_@@_vlines_bool }
+            { \bool_not_p:n \l_@@_exterior_arraycolsep_bool }
           }
           { \tl_put_right:Nn \l_tmpa_tl { @ { } } }
       }
@@ -4475,13 +4754,13 @@
 % |\arraycolsep| is used once (between columns, |\arraycolsep| is used twice).
 % That's why we add a |0.5\arrayrulewidth| more.
 %    \begin{macrocode}
-     \bool_if:NT \l_@@_vlines_bool
+    \bool_if:NT \l_@@_vlines_bool
       { 
         \dim_add:Nn \arraycolsep { 0.5 \arrayrulewidth } 
-        \skip_horizontal:n { 0.5 \arrayrulewidth } 
+        \skip_horizontal:N  0.5\arrayrulewidth  
       }
-    \skip_horizontal:n \l_@@_left_margin_dim 
-    \skip_horizontal:n \l_@@_extra_left_margin_dim 
+    \skip_horizontal:N \l_@@_left_margin_dim 
+    \skip_horizontal:N \l_@@_extra_left_margin_dim 
     \c_math_toggle_token
     \bool_if:NTF \l_@@_light_syntax_bool
       { \begin { @@-light-syntax } }
@@ -4496,8 +4775,8 @@
       { \end { @@-light-syntax } }
       { \end { @@-normal-syntax } }
     \c_math_toggle_token
-    \skip_horizontal:n \l_@@_right_margin_dim 
-    \skip_horizontal:n \l_@@_extra_right_margin_dim 
+    \skip_horizontal:N \l_@@_right_margin_dim 
+    \skip_horizontal:N \l_@@_extra_right_margin_dim 
 %    \end{macrocode}
 % If the key |\vlines| is used, we have increased |\arraycolsep| by
 % |0.5\arrayrulewidth| in order to reserve space for the width of the vertical
@@ -4505,7 +4784,7 @@
 % |\arraycolsep| is used once (between columns, |\arraycolsep| is used twice).
 % That's we add a |0.5 \arrayrulewidth| more.
 %    \begin{macrocode}
-    \bool_if:NT \l_@@_vlines_bool { \skip_horizontal:n { 0.5 \arrayrulewidth } } 
+    \bool_if:NT \l_@@_vlines_bool { \skip_horizontal:N 0.5\arrayrulewidth } 
     \hbox_set_end:
 %    \end{macrocode}
 % End of the construction of the array (in the box |\l_@@_the_array_box|).
@@ -4532,7 +4811,7 @@
 % |\g_@@_col_total_int| change: |\c at jCol| will be the number of
 % columns without the ``last column''; |\g_@@_col_total_int| will be the
 % number of columns with this ``last column''.\footnote{We remind that the
-% potential ``first column'' has the number~$0$.}
+% potential ``first column'' (exterior) has the number~$0$.}
 %    \begin{macrocode}
     \int_gset_eq:NN \c at jCol \g_@@_col_total_int
     \bool_if:nT \g_@@_last_col_found_bool { \int_gdecr:N \c at jCol } 
@@ -4556,15 +4835,14 @@
 %    \begin{macrocode}
     \int_compare:nNnT \l_@@_first_col_int = 0
       { 
-        \skip_horizontal:n \arraycolsep
-        \skip_horizontal:n \g_@@_width_first_col_dim 
+        \skip_horizontal:N \arraycolsep
+        \skip_horizontal:N \g_@@_width_first_col_dim 
       }
 %    \end{macrocode}
 %
-% The construction of the real box is different in |{NiceArray}| and in its
-% variants (|{pNiceArray}|, etc.) because, in |{NiceArray}|, we have to take
-% into account the option of position (|t|, |c| or |b|). We begin with
-% |{NiceArray}|. 
+% The construction of the real box is different in |{NiceArray}| and in the
+% other environments because, in |{NiceArray}|, we have to take into account the
+% value of |baseline| and we have no delimiter to put. We begin with |{NiceArray}|.
 %    \begin{macrocode}
     \bool_if:NTF \l_@@_NiceArray_bool
       { 
@@ -4575,16 +4853,12 @@
 %    \begin{macrocode}
         \str_if_eq:VnTF \l_@@_baseline_str { b }
           { 
-           \begin { tikzpicture }
-             \@@_extract_coords:w ( nm - \int_use:N \g_@@_env_int - row - 1 ) 
+           \pgfpicture
+             \@@_qpoint: { row - 1 } 
              \dim_gset_eq:NN \g_tmpa_dim \pgf at y
-             \@@_extract_coords:w 
-               ( 
-                 nm - \int_use:N \g_@@_env_int - 
-                 row - \int_use:N \c at iRow - base
-               ) 
+             \@@_qpoint: { row - \int_use:N \c at iRow - base }
              \dim_gsub:Nn \g_tmpa_dim \pgf at y
-           \end { tikzpicture }
+           \endpgfpicture
            \int_compare:nNnT \l_@@_first_row_int = 0 
              {
                \dim_gadd:Nn \g_tmpa_dim 
@@ -4608,7 +4882,7 @@
                 \int_set:Nn \l_tmpa_int \l_@@_baseline_str
                 \bool_if:nT
                   { 
-                       \int_compare_p:nNn \l_tmpa_int < 0 
+                       \int_compare_p:nNn \l_tmpa_int < \l_@@_first_row_int
                     || \int_compare_p:nNn \l_tmpa_int > \g_@@_row_total_int 
                   }
                   { 
@@ -4616,19 +4890,14 @@
                     \int_set:Nn \l_tmpa_int 1
                   }
 %    \end{macrocode}
-% We use a |{tikzpicture}| to extract coordinates (nothing is drawn).
+% We use a |{pgfpicture}| to extract coordinates (nothing is drawn).
 %    \begin{macrocode}
-                \begin { tikzpicture }
-                \@@_extract_coords:w 
-                  ( nm - \int_use:N \g_@@_env_int - row - 1 ) 
+                \pgfpicture
+                \@@_qpoint: { row - 1 } 
                 \dim_gset_eq:NN \g_tmpa_dim \pgf at y
-                \@@_extract_coords:w 
-                  ( 
-                    nm - \int_use:N \g_@@_env_int - 
-                    row - \int_use:N \l_tmpa_int- base 
-                  )
+                \@@_qpoint: { row - \int_use:N \l_tmpa_int - base }
                 \dim_gsub:Nn \g_tmpa_dim \pgf at y
-                \end { tikzpicture }
+                \endpgfpicture
                 \int_compare:nNnT \l_@@_first_row_int = 0 
                   {
                     \dim_gadd:Nn \g_tmpa_dim 
@@ -4648,8 +4917,8 @@
       {
         \int_compare:nNnTF \l_@@_first_row_int = 0
           { 
-            \dim_set:Nn \l_tmpa_dim 
-              { \g_@@_dp_row_zero_dim + \g_@@_ht_row_zero_dim } 
+            \dim_set_eq:NN \l_tmpa_dim \g_@@_dp_row_zero_dim 
+            \dim_add:Nn \l_tmpa_dim \g_@@_ht_row_zero_dim 
           } 
           { \dim_zero:N \l_tmpa_dim }
 %    \end{macrocode}
@@ -4663,8 +4932,8 @@
 %    \begin{macrocode}
         \int_compare:nNnTF \l_@@_last_row_int > { -2 }
           {
-            \dim_set:Nn \l_tmpb_dim
-              { \g_@@_ht_last_row_dim + \g_@@_dp_last_row_dim }
+            \dim_set_eq:NN \l_tmpb_dim \g_@@_ht_last_row_dim 
+            \dim_add:Nn \l_tmpb_dim \g_@@_dp_last_row_dim 
           }
           { \dim_zero:N \l_tmpb_dim }
 %    \end{macrocode}
@@ -4678,20 +4947,20 @@
               { 
 %    \end{macrocode}
 % We take into account the ``first row'' (we have previously computed its total
-% height in |\l_tmpa_dim|).
+% height in |\l_tmpa_dim|). The |\hbox:n| (or |\hbox|) is necessary here.
 %    \begin{macrocode}
-                \skip_vertical:n { - \l_tmpa_dim }
-                \hbox:n 
-                  { 
-                    \skip_horizontal:n { - \arraycolsep }
+                \skip_vertical:N -\l_tmpa_dim 
+                \hbox
+                  {
+                    \skip_horizontal:N -\arraycolsep 
                     \box_use_drop:N \l_@@_the_array_box
-                    \skip_horizontal:n { - \arraycolsep }
+                    \skip_horizontal:N -\arraycolsep 
                   }
 %    \end{macrocode}
 % We take into account the ``last row'' (we have previously computed its total
 % height in |\l_tmpb_dim|).
 %    \begin{macrocode}
-                \skip_vertical:n { - \l_tmpb_dim }
+                \skip_vertical:N -\l_tmpb_dim 
               }
             \right #2 
             \c_math_toggle_token
@@ -4714,7 +4983,10 @@
 % |\g_@@_width_last_col_dim|: see p.~\pageref{overlap-right}).
 %    \begin{macrocode}           
     \bool_if:NT \g_@@_last_col_found_bool 
-      { \skip_horizontal:n { \g_@@_width_last_col_dim + \arraycolsep } } 
+      { 
+        \skip_horizontal:N \g_@@_width_last_col_dim 
+        \skip_horizontal:N \arraycolsep 
+      }
     \@@_after_array:
   }
 %    \end{macrocode}
@@ -4781,9 +5053,11 @@
 % Now, we can put the box in the TeX flow with the horizontal adjustments on
 % both sides.
 %    \begin{macrocode}
-    \skip_horizontal:n { \l_@@_left_delim_dim - \l_@@_real_left_delim_dim }
+    \skip_horizontal:N  \l_@@_left_delim_dim 
+    \skip_horizontal:N -\l_@@_real_left_delim_dim 
     \@@_put_box_in_flow:
-    \skip_horizontal:n { \l_@@_right_delim_dim - \l_@@_real_right_delim_dim }   
+    \skip_horizontal:N \l_@@_right_delim_dim 
+    \skip_horizontal:N -\l_@@_real_right_delim_dim 
   }
 %    \end{macrocode}
 % 
@@ -4812,15 +5086,6 @@
       { \exp_args:NV \@@_array: \l_tmpa_tl }
   }
   { 
-%    \end{macrocode}
-%
-% If all the columns must have the same width (if the user has used the option
-% |columns-width| or the option |auto-columns-width| of the environment
-% |{NiceMatrixBlock}|), we will add a row in the array to fix the width of the
-% columns and construct the ``|col|'' nodes |nm-|\textsl{a}|-col-|\textsl{j}
-% (these nodes will be used by the horizontal open dotted lines and by the
-% commands |\@@_vdottedline:n|). We have written a dedicated function for that job.
-%    \begin{macrocode}
     \@@_create_col_nodes:
     \endarray 
   }
@@ -4838,13 +5103,8 @@
 % course, this test is more easy than the similar test for the ``normal syntax''
 % because we have the whole body of the environment in |#1|.
 %    \begin{macrocode}
-     \tl_if_empty:nT { #1 } { \@@_fatal:n { empty~environment } }
+    \tl_if_empty:nT { #1 } { \@@_fatal:n { empty~environment } }
 %    \end{macrocode}
-% Here is the call to |\array| (we have a dedicated macro |\@@_array:| because
-% of compatibility with the classes \cls{revtex4-1} and \cls{revtex4-2}).
-%    \begin{macrocode}
-    \exp_args:NV \@@_array: \l_tmpa_tl 
-%    \end{macrocode}
 % The body of the environment, which is stored in the argument |#1|, is now
 % splitted into items (and \emph{not} tokens) 
 %    \begin{macrocode}
@@ -4852,6 +5112,19 @@
     \tl_set_rescan:Nno \l_@@_end_of_row_tl { } \l_@@_end_of_row_tl
     \exp_args:NNV \seq_gset_split:Nnn \g_@@_rows_seq \l_@@_end_of_row_tl { #1 } 
 %    \end{macrocode}
+% If the environment uses the option |last-row| without value (i.e. without
+% saying the number of the rows), we have now the opportunity to know that
+% value. We do it, and so, if the token list |\l_@@_code_for_last_row_tl| is not
+% empty, we will use directly where it should be.
+%    \begin{macrocode}
+    \int_compare:nNnT \l_@@_last_row_int = { -1 }
+      { \int_set:Nn \l_@@_last_row_int { \seq_count:N \g_@@_rows_seq } }
+%    \end{macrocode}
+% Here is the call to |\array| (we have a dedicated macro |\@@_array:| because
+% of compatibility with the classes \cls{revtex4-1} and \cls{revtex4-2}).
+%    \begin{macrocode}
+    \exp_args:NV \@@_array: \l_tmpa_tl 
+%    \end{macrocode}
 % We need a global affectation because, when executing |\l_tmpa_tl|, we will
 % exit the first cell of the array.
 %    \begin{macrocode}
@@ -4922,7 +5195,7 @@
     \int_compare:nNnT \l_@@_first_col_int = 0 { \omit & }
     \omit
 %    \end{macrocode}
-% The following instruction must be put after the instructions |\omit|.
+% The following instruction must be put after the instruction |\omit|.
 %    \begin{macrocode}
     \bool_gset_true:N \g_@@_row_of_col_done_bool
 %    \end{macrocode}
@@ -4929,8 +5202,12 @@
 % First, we put a ``|col|'' node on the left of the first column (of course, we
 % have to do that \emph{after} the |\omit|).
 %    \begin{macrocode}
-    \tikz [ remember~picture ]
-      \coordinate ( nm - \int_use:N \g_@@_env_int - col - 1 ) ;
+    \pgfpicture 
+    \pgfrememberpicturepositiononpagetrue
+    \pgfcoordinate { \@@_env: - col - 1 } \pgfpointorigin 
+    \str_if_empty:NF \l_@@_name_str
+      { \pgfnodealias { \@@_env: - col - 1 } { \l_@@_name_str - col - 1 } }  
+    \endpgfpicture
 %    \end{macrocode}
 % We compute in |\g_tmpa_skip| the common width of the columns (it's a skip and
 % not a dimension). We use a global variable because we are in a cell of an
@@ -4937,33 +5214,31 @@
 % |\halign| and because we have to use this variable in other cells (of the same
 % row). The affectation of |\g_tmpa_skip|, like all the affectations, must be
 % done after the |\omit| of the cell.
+%
+% \smallskip
+% We give a default value for |\g_tmpa_skip| (|0 pt plus 1 fill|) but it will
+% just after erased by a fixed value in the concerned cases.
 %    \begin{macrocode}
-    \bool_if:nTF
+    \skip_gset:Nn \g_tmpa_skip { 0 pt~plus 1 fill } 
+    \bool_if:NF \l_@@_auto_columns_width_bool
+      { \dim_compare:nNnT \l_@@_columns_width_dim > \c_zero_dim }
       {
-        \l_@@_auto_columns_width_bool
-        || \dim_compare_p:nNn \l_@@_columns_width_dim > \c_zero_dim 
+        \bool_lazy_and:nnTF 
+          \l_@@_auto_columns_width_bool 
+          { \bool_not_p:n \l_@@_block_auto_columns_width_bool }
+          { \skip_gset_eq:NN \g_tmpa_skip \g_@@_max_cell_width_dim } 
+          { \skip_gset_eq:NN \g_tmpa_skip \l_@@_columns_width_dim } 
+        \skip_gadd:Nn \g_tmpa_skip { 2 \arraycolsep } 
       }
-      {
-        \bool_if:nTF 
-          { 
-            \l_@@_auto_columns_width_bool 
-            && ! \l_@@_block_auto_columns_width_bool 
-          }
-          { 
-            \skip_gset:Nn \g_tmpa_skip
-              { \g_@@_max_cell_width_dim + 2 \arraycolsep } 
-          }
-          { 
-            \skip_gset:Nn \g_tmpa_skip
-              { \l_@@_columns_width_dim + 2 \arraycolsep } 
-          } 
-      }
-      { \skip_gset:Nn \g_tmpa_skip { 0 pt~plus 1 fill } }
     \skip_horizontal:N \g_tmpa_skip
-    \hbox:n
+    \hbox
       { 
-        \tikz [ remember~picture ]
-          \coordinate ( nm - \int_use:N \g_@@_env_int - col - 2 ) ;
+        \pgfpicture 
+        \pgfrememberpicturepositiononpagetrue
+        \pgfcoordinate { \@@_env: - col - 2 } \pgfpointorigin 
+        \str_if_empty:NF \l_@@_name_str
+          { \pgfnodealias { \@@_env: - col - 2 } { \l_@@_name_str - col - 2 } } 
+        \endpgfpicture
       }
 %    \end{macrocode}
 % We begin a loop over the columns. The integer |\g_tmpa_int| will be the
@@ -4985,12 +5260,17 @@
 %    \end{macrocode}
 % We create the ``|col|'' node on the right of the current column.
 %    \begin{macrocode}
-         \tikz [ remember~picture ]
-           \coordinate             
-             ( 
-               nm - \int_use:N \g_@@_env_int - 
-               col - \int_eval:n { \g_tmpa_int + 1 }
-             ) ;  
+         \pgfpicture
+           \pgfrememberpicturepositiononpagetrue
+           \pgfcoordinate { \@@_env: - col - \@@_succ:N \g_tmpa_int } 
+             \pgfpointorigin 
+           \str_if_empty:NF \l_@@_name_str
+             {
+               \pgfnodealias 
+                 { \@@_env: - col - \@@_succ:N \g_tmpa_int } 
+                 { \l_@@_name_str - col - \@@_succ:N \g_tmpa_int }
+             }   
+         \endpgfpicture  
       }
     \cr
   }
@@ -5017,17 +5297,17 @@
 % We insert |\l_@@_code_for_first_col_tl|... but we don't insert it in the
 % potential ``first row'' and in the potential ``last row''.
 %    \begin{macrocode}
-        \bool_if:nT
+        \bool_lazy_and:nnT
+          { \int_compare_p:nNn \c at iRow > 0 }
           {
-            \int_compare_p:nNn \c at iRow > 0 
-            && 
-            (
-              \int_compare_p:nNn \l_@@_last_row_int < 0
-              ||
-              \int_compare_p:nNn \c at iRow < \l_@@_last_row_int
-            )
+            \bool_lazy_or_p:nn
+              { \int_compare_p:nNn \l_@@_last_row_int < 0 }
+              { \int_compare_p:nNn \c at iRow < \l_@@_last_row_int }
           }
-          { \l_@@_code_for_first_col_tl }
+          { 
+            \l_@@_code_for_first_col_tl 
+            \xglobal \colorlet { nicematrix-first-col } { . }
+          }
       }
 %    \end{macrocode}
 % Be careful: despite this letter |l| the cells of the ``first column'' are
@@ -5044,11 +5324,7 @@
 % after the construction of the array.
 %    \begin{macrocode}
         \dim_gset:Nn \g_@@_width_first_col_dim
-          { 
-            \dim_max:nn 
-              \g_@@_width_first_col_dim
-              { \box_wd:N \l_@@_cell_box }
-          }
+          { \dim_max:nn \g_@@_width_first_col_dim { \box_wd:N \l_@@_cell_box } }
 %    \end{macrocode}
 % The content of the cell is inserted in an overlapping position.
 % \label{overlap-left}
@@ -5055,38 +5331,14 @@
 %    \begin{macrocode}
         \hbox_overlap_left:n
           { 
-            \tikz 
-              [ 
-                remember~picture , 
-                inner~sep = \c_zero_dim , 
-                minimum~width = \c_zero_dim , 
-                baseline
-              ]
-            \node 
-              [ 
-                anchor = base ,
-                name = 
-                  nm -
-                  \int_use:N \g_@@_env_int -
-                  \int_use:N \c at iRow -
-                  0 ,
-                alias = 
-                  \str_if_empty:NF \l_@@_name_str
-                    { 
-                      \l_@@_name_str -
-                      \int_use:N \c at iRow -
-                      0
-                    }
-              ]
-              { \box_use_drop:N \l_@@_cell_box } ; 
-            \skip_horizontal:n
-              { 
-                \l_@@_left_delim_dim + 
-                \l_@@_left_margin_dim + 
-                \l_@@_extra_left_margin_dim
-              }
+            \dim_compare:nNnTF { \box_wd:N \l_@@_cell_box } > \c_zero_dim
+              \@@_node_for_the_cell:
+              { \box_use_drop:N \l_@@_cell_box }
+            \skip_horizontal:N \l_@@_left_delim_dim
+            \skip_horizontal:N \l_@@_left_margin_dim 
+            \skip_horizontal:N \l_@@_extra_left_margin_dim
           }
-        \skip_horizontal:n { - 2 \arraycolsep } 
+        \skip_horizontal:N -2\arraycolsep 
       }
   }
 %    \end{macrocode}
@@ -5118,17 +5370,16 @@
 % We insert |\l_@@_code_for_last_col_tl|... but we don't insert it in the
 % potential ``first row'' and in the potential ``last row''.
 %    \begin{macrocode}
-        \bool_if:nT
+        \int_compare:nNnT \c at iRow > 0 
           {
-            \int_compare_p:nNn \c at iRow > 0 
-            && 
-            (
-              \int_compare_p:nNn \l_@@_last_row_int < 0
-              ||
-              \int_compare_p:nNn \c at iRow < \l_@@_last_row_int
-            )
+            \bool_lazy_or:nnT
+              { \int_compare_p:nNn \l_@@_last_row_int < 0 }
+              { \int_compare_p:nNn \c at iRow < \l_@@_last_row_int }
+              { 
+                \l_@@_code_for_last_col_tl 
+                \xglobal \colorlet { nicematrix-last-col } { . }
+              }  
           }
-          { \l_@@_code_for_last_col_tl }
       }
     l
     < 
@@ -5141,12 +5392,8 @@
 % after the construction of the array.
 %    \begin{macrocode}
         \dim_gset:Nn \g_@@_width_last_col_dim
-           { 
-             \dim_max:nn 
-               \g_@@_width_last_col_dim
-               { \box_wd:N \l_@@_cell_box }
-           }
-        \skip_horizontal:n { - 2 \arraycolsep }
+          { \dim_max:nn \g_@@_width_last_col_dim { \box_wd:N \l_@@_cell_box } }
+        \skip_horizontal:N -2\arraycolsep 
 %    \end{macrocode}
 % The content of the cell is inserted in an overlapping position.
 % \label{overlap-right}
@@ -5153,36 +5400,13 @@
 %    \begin{macrocode}
         \hbox_overlap_right:n
           { 
-            \skip_horizontal:n
-              { 
-                \l_@@_right_delim_dim + 
-                \l_@@_right_margin_dim + 
-                \l_@@_extra_right_margin_dim
+            \dim_compare:nNnT { \box_wd:N \l_@@_cell_box } > \c_zero_dim
+              {
+                \skip_horizontal:N \l_@@_right_delim_dim 
+                \skip_horizontal:N \l_@@_right_margin_dim 
+                \skip_horizontal:N \l_@@_extra_right_margin_dim
+                \@@_node_for_the_cell:
               }
-            \tikz 
-              [ 
-                remember~picture , 
-                inner~sep = \c_zero_dim , 
-                minimum~width = \c_zero_dim , 
-                baseline
-              ]
-            \node 
-              [ 
-                anchor = base ,
-                name = 
-                  nm -
-                  \int_use:N \g_@@_env_int -
-                  \int_use:N \c at iRow -
-                  \int_use:N \c at jCol ,
-                alias = 
-                  \str_if_empty:NF \l_@@_name_str
-                    { 
-                      \l_@@_name_str -
-                      \int_use:N \c at iRow -
-                      \int_use:N \c at jCol
-                    }
-              ]
-              { \box_use_drop:N \l_@@_cell_box } ; 
           } 
       }
   }
@@ -5212,8 +5436,7 @@
 %               
 % 
 % \interitem
-% We create the variants of the environment |{NiceArrayWithDelims}|. These
-% variants exist since the version 3.0 of \pkg{nicematrix}.
+% We create the variants of the environment |{NiceArrayWithDelims}|. 
 %
 %   \begin{macrocode}
 \NewDocumentEnvironment { pNiceArray } { }
@@ -5279,17 +5502,9 @@
     \NewDocumentEnvironment { #1 NiceMatrix } { ! O { } }
       {
         \str_gset:Nn \g_@@_name_env_str { #1 NiceMatrix } 
+        \tl_set:Nn \l_@@_type_of_col_tl C
         \keys_set:nn { NiceMatrix / NiceMatrix } { ##1 }
-        \begin { #1 NiceArray } 
-          { 
-            * 
-              { 
-                \int_compare:nNnTF \l_@@_last_col_int = { -1 }  
-                  \c at MaxMatrixCols
-                  { \int_eval:n { \l_@@_last_col_int - 1 } }
-              } 
-              C 
-          } 
+        \exp_args:Nnx \@@_begin_of_NiceMatrix:nn { #1 } \l_@@_type_of_col_tl 
       }
       { \end { #1 NiceArray } }
   }
@@ -5296,6 +5511,22 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
+\cs_new_protected:Npn \@@_begin_of_NiceMatrix:nn #1 #2
+  {
+    \begin { #1 NiceArray } 
+      { 
+        * 
+          { 
+            \int_compare:nNnTF \l_@@_last_col_int = { -1 }  
+              \c at MaxMatrixCols
+              { \int_eval:n { \l_@@_last_col_int - 1 } }
+          } 
+          #2
+      } 
+  }
+%    \end{macrocode}
+% 
+%    \begin{macrocode}
 \@@_define_env:n { }
 \@@_define_env:n p 
 \@@_define_env:n b 
@@ -5305,130 +5536,36 @@
 %    \end{macrocode}
 %
 % 
-% \bigskip
-% \subsection*{How to know whether a cell is ``empty''}
 %
-% The conditionnal |\@@_if_not_empty_cell:nnT| tests whether a cell is empty.
-% The first two arguments must be LaTeX3 counters for the row and the column of
-% the considered cell. 
-%    \begin{macrocode}
-\prg_set_conditional:Npnn \@@_if_not_empty_cell:nn #1 #2 { T , TF }
-  { 
-%    \end{macrocode}
-% 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:
-      { 
-%    \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 at sh@ns at 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 }
-%    \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 at x
-                \pgfpointanchor \l_tmpa_tl { west }
-                \dim_gset:Nn \g_tmpb_dim \pgf at x
-                \end { pgfpicture } 
-                \dim_compare:nNnTF 
-                  { \dim_abs:n { \g_tmpb_dim - \g_tmpa_dim } } < { 0.5 pt }
-                  \prg_return_false:
-                  \prg_return_true:
-              }
-          }
-      }
-  }
-%    \end{macrocode}
-%
 % 
 % \bigskip
 % \subsection*{After the construction of the array}
 %
-%
-% \medskip
-% We deactivate Tikz externalization. 
-% 
-% Since we use Tikz pictures with the options |overlay| and |remember picture|,
-% there would be errors.
+% \medskip 
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_after_array:
   { 
     \group_begin:
-    \cs_if_exist:NT \tikz at library@external at loaded
-      { \tikzset { external / export = false } } 
 %    \end{macrocode}
 %
-% In the user has used the option |last-row| without value, we write in the
-% |aux| file the number of that last row for the next run.
+% If a last column is announced in the options, but without the value (because
+% we are in an environment with preamble, it's time to fix the real value of
+% |\l_@@_last_col_int|).
 %    \begin{macrocode}
+    \int_compare:nNnT \l_@@_last_col_int = 0
+      {
+        \bool_if:NT \g_@@_last_col_found_bool
+          { \dim_set_eq:NN \l_@@_last_col_int \g_@@_col_total_int }
+      }
+%    \end{macrocode}
+% 
+% It's also time to give to |\l_@@_last_row_int| its real value. But, if the
+% user had used the option |last-row| without value, we write in the |aux| file
+% the number of that last row for the next run.
+%    \begin{macrocode}
     \bool_if:NT \l_@@_last_row_without_value_bool
       {
+        \dim_set_eq:NN \l_@@_last_row_int \g_@@_row_total_int
         \iow_now:Nn \@mainaux \ExplSyntaxOn 
         \iow_now:Nx \@mainaux 
           { 
@@ -5461,38 +5598,32 @@
 %    \begin{macrocode}
     \bool_if:NT \l_@@_parallelize_diags_bool
       { 
-        \int_zero_new:N \l_@@_ddots_int
-        \int_zero_new:N \l_@@_iddots_int
+        \int_gzero_new:N \g_@@_ddots_int
+        \int_gzero_new:N \g_@@_iddots_int
 %    \end{macrocode}
 %
-% The dimensions |\l_@@_delta_x_one_dim| and |\l_@@_delta_y_one_dim| will
+% The dimensions |\g_@@_delta_x_one_dim| and |\g_@@_delta_y_one_dim| will
 % contain 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
+% to the first one. Similarly |\g_@@_delta_x_two_dim| and
+% |\g_@@_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
+        \dim_gzero_new:N \g_@@_delta_x_one_dim
+        \dim_gzero_new:N \g_@@_delta_y_one_dim
+        \dim_gzero_new:N \g_@@_delta_x_two_dim
+        \dim_gzero_new:N \g_@@_delta_y_two_dim
       }
 %    \end{macrocode}
 %
-% The booleans |\g_@@_medium_nodes_bool| and |\g_@@_large_nodes_bool| may be
-% raised directly in cells of the array (for example in commands |\Block|) but
-% also because the user has used the options |create-medium-nodes| and
-% |create-large-nodes| (these options raise |\l_@@_medium_nodes_bool| and
-% |\l_@@_large_nodes_bool| but theses booleans are converted into the global
-% versions before the creation of the array).
 %    \begin{macrocode}
-    \bool_if:nTF \g_@@_medium_nodes_bool
+    \bool_if:nTF \l_@@_medium_nodes_bool
       { 
-        \bool_if:NTF \g_@@_large_nodes_bool
+        \bool_if:NTF \l_@@_large_nodes_bool
           \@@_create_medium_and_large_nodes:
           \@@_create_medium_nodes:
       }
-      { \bool_if:NT \g_@@_large_nodes_bool \@@_create_large_nodes: }
+      { \bool_if:NT \l_@@_large_nodes_bool \@@_create_large_nodes: }
     \int_zero_new:N \l_@@_initial_i_int
     \int_zero_new:N \l_@@_initial_j_int
     \int_zero_new:N \l_@@_final_i_int
@@ -5502,43 +5633,50 @@
 %    \end{macrocode}
 %
 % If the option |small| is used, the values |\l_@@_radius_dim| and
-% |\l_@@_inter_dots_dim| (used to draw the dotted lines) are changed.
+% |\l_@@_inter_dots_dim| (used to draw the dotted lines created by
+% |\hdottedline| and |\vdotteline| and also for all the other dotted lines when
+% |line-style| is equal to |standard|, which is the initial value) are changed.
 %    \begin{macrocode}     
     \bool_if:NT \l_@@_small_bool 
       { 
         \dim_set:Nn \l_@@_radius_dim { 0.37 pt }
         \dim_set:Nn \l_@@_inter_dots_dim { 0.25 em } 
+%    \end{macrocode}
+% The dimension |\l_@@_xdots_shorten_dim| corresponds to the option
+% |xdots/shorten| available to the user. That's why we give a new value
+% according to the current value, and not a absolute value.
+%    \begin{macrocode}
+        \dim_set:Nn \l_@@_xdots_shorten_dim { 0.6 \l_@@_xdots_shorten_dim }
       }
 %    \end{macrocode}
 %
+%
 % \bigskip
-% Now, we really draw the lines. The code to draw the lines has been constructed
-% in the token lists |\g_@@_Vdots_lines_tl|, etc.
+% Now, we really draw the lines. 
 %    \begin{macrocode}
-    \g_@@_Hdotsfor_lines_tl
-    \g_@@_Vdots_lines_tl
-    \g_@@_Ddots_lines_tl
-    \g_@@_Iddots_lines_tl
-    \g_@@_Cdots_lines_tl
-    \g_@@_Ldots_lines_tl
+    \@@_draw_dotted_lines:
 %    \end{macrocode}
-%
 % 
-% 
-% \bigskip
-% Now, the |code-after|.
+% We draw the vertical rules of the option |vlines| before the
+% |internal-code-after| because the option |white| of a |\Block| may have to
+% erase these vertical rules.
 %    \begin{macrocode}
-    \tikzset 
-      { 
-        every~picture / .style = 
+    \bool_if:NT \l_@@_vlines_bool \@@_draw_vlines:
+    \g_@@_internal_code_after_tl
+    \tl_gclear:N \g_@@_internal_code_after_tl
+    \bool_if:NT \c_@@_tikz_loaded_bool
+      {  
+        \tikzset 
           { 
-            overlay ,
-            remember~picture ,
-            name~prefix = nm - \int_use:N \g_@@_env_int - 
-          }
+            every~picture / .style = 
+              { 
+                overlay ,
+                remember~picture ,
+                name~prefix = \@@_env: - 
+              }
+          }  
       }
-    \bool_if:NT \l_@@_vlines_bool \@@_draw_vlines:
-    \cs_set_eq:NN \line \@@_line:nn
+    \cs_set_eq:NN \line \@@_line
     \g_@@_code_after_tl 
     \tl_gclear:N \g_@@_code_after_tl
     \group_end:
@@ -5548,56 +5686,38 @@
 %    \end{macrocode}
 %
 % \bigskip
+% We recall that, when externalization is used, |\tikzpicture| and
+% |\endtikzpicture| (or |\pgfpicture| and |\endpgfpicture|) must be directly
+% ``visible''. That's why we have to define the adequate version of
+% |\@@_draw_dotted_lines:| whether Tikz is loaded or not (in that case, only
+% \textsc{pgf} is loaded).
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_draw_vlines:
+\AtBeginDocument
   {
-    \group_begin:
-%    \end{macrocode}
-% The command |\CT at arc@| is a command of color from \pkg{colortbl}.
-%    \begin{macrocode}
-    \bool_if:NT \c_@@_colortbl_loaded_bool \CT at arc@
-    \begin { tikzpicture } [ line~width = \arrayrulewidth ]
-%    \end{macrocode}
-% First, we compute in |\l_tmpa_dim| the height of the rules we have to draw.
-%    \begin{macrocode}
-    \@@_extract_coords:w ( row - 1 )
-    \dim_set_eq:NN \l_tmpa_dim \pgf at y
-    \@@_extract_coords:w ( row - \int_eval:n { \c at iRow + 1 } ) 
-    \dim_set:Nn \l_tmpa_dim { \l_tmpa_dim - \pgf at y  }
-%    \end{macrocode}
-% We translate vertically to take into account the potential ``last row''. 
-%    \begin{macrocode}
-    \dim_zero:N \l_tmpb_dim
-    \int_compare:nNnT \l_@@_last_row_int > { -1 }
+    \cs_new_protected:Npx \@@_draw_dotted_lines:
       {
-        \dim_set:Nn \l_tmpb_dim 
-          { \g_@@_dp_last_row_dim + \g_@@_ht_last_row_dim }  
+        \c_@@_pgfortikzpicture_tl
+        \@@_draw_dotted_lines_i:
+        \c_@@_endpgfortikzpicture_tl
+      }
+  }
 %    \end{macrocode}
-% We adjust the value of |\l_tmpa_dim| by the width of the horizontal rule just 
-% before the ``last row''.
-%    \begin{macrocode}
-        \@@_extract_coords:w ( row - \int_eval:n { \c at iRow + 1 } )
-        \dim_add:Nn \l_tmpa_dim \pgf at y
-        \@@_extract_coords:w ( row - \int_eval:n { \g_@@_row_total_int + 1 } ) 
-        \dim_sub:Nn \l_tmpa_dim \pgf at y
-        \dim_sub:Nn \l_tmpa_dim \l_tmpb_dim
-       }
-%    \end{macrocode}
 %
-% Now, we can draw the lines with a loop. 
+% The following command \emph{must} be protected because it will appear in the
+% construction of the command |\@@_draw_dotted_lines:|.
 %    \begin{macrocode}
-    \int_step_inline:nnn 
-      { \bool_if:NTF \l_@@_NiceArray_bool 1 2 } 
-      { \bool_if:NTF \l_@@_NiceArray_bool { \c at jCol + 1 } \c at jCol } 
-      { 
-        \draw ( col - ##1 ) ++ ( 0 , \dim_use:N \l_tmpb_dim ) 
-                         -- ++ ( 0 , \dim_use:N \l_tmpa_dim ) ; 
-      }
-    \end { tikzpicture }
-    \group_end:
+\cs_new_protected:Npn \@@_draw_dotted_lines_i:
+  {
+    \pgfrememberpicturepositiononpagetrue
+    \pgf at relevantforpicturesizefalse
+    \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
 %    \begin{macrocode}
@@ -5617,18 +5737,6 @@
 % a & \Cdots \\
 % a & a+b & a+b+c
 % \end{pNiceMatrix}\]
-% For a closed extremity, we use the normal node and for a open one, we use the
-% ``medium node'' or the |col|-node.
-% \[ \begin{pNiceMatrix}[create-medium-nodes,
-%                        code-after = {\begin{tikzpicture} 
-%                                      \node [highlight = (2-1)] {} ;
-%                                      \node [highlight = (2-3-medium) ] {};
-%                                      \end{tikzpicture}
-%                                    }]
-% a+b+c & a+b & a\\
-% a & \Cdots \\
-% a & a+b & a+b+c
-% \end{pNiceMatrix}\]
 %
 % 
 % \bigskip
@@ -5706,12 +5814,11 @@
         \bool_if:NTF \l_@@_final_open_bool 
 %    \end{macrocode}
 % If we are outside the matrix, we have found the extremity of the dotted line
-% and it's a \emph{open} extremity. 
+% and it's an \emph{open} extremity. 
 %    \begin{macrocode}
           { 
 %    \end{macrocode}
-% We do a step backwards because we will draw the dotted line upon the last cell
-% in the matrix (we will use the ``medium node'' of this cell).
+% We do a step backwards.
 %    \begin{macrocode}  
             \int_sub:Nn \l_@@_final_i_int { #3 }
             \int_sub:Nn \l_@@_final_j_int { #4 }
@@ -5723,48 +5830,49 @@
 % |\l_@@_final_i_int| and |\l_@@_final_j_int|. 
 %    \begin{macrocode}
           { 
-            \@@_if_not_empty_cell:nnTF \l_@@_final_i_int \l_@@_final_j_int
-              { \bool_set_true:N \l_@@_stop_loop_bool }
+            \cs_if_exist:cTF
+              { 
+                @@ _ dotted _ 
+                \int_use:N \l_@@_final_i_int - 
+                \int_use:N \l_@@_final_j_int 
+              }
+              {
+                \int_sub:Nn \l_@@_final_i_int { #3 }
+                \int_sub:Nn \l_@@_final_j_int { #4 }
+                \bool_set_true:N \l_@@_final_open_bool
+                \bool_set_true:N \l_@@_stop_loop_bool
+              }
+              { 
+                \cs_if_exist:cTF 
+                  { 
+                    pgf @ sh @ ns @ \@@_env: 
+                    - \int_use:N \l_@@_final_i_int 
+                    - \int_use:N \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.
+% intersections between dotted lines. We recall that the research of the
+% extremities of the lines are all done in the same TeX group (the group of the
+% environnement), even though, when the extremities are found, each line is
+% drawn in a TeX group that we will open for the options of the line.
 %    \begin{macrocode} 
-              { 
-                \cs_set:cpn 
                   { 
-                    @@ _ dotted _
-                    \int_use:N \l_@@_final_i_int - 
-                    \int_use:N \l_@@_final_j_int 
-                  } 
-                  { }
+                    \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.
 %
-%    \begin{macrocode}
-    \cs_if_free:cT 
-      { 
-        pgf at sh@ns at 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}
-% 
 % \interitem
 % For |\l_@@_initial_i_int| and |\l_@@_initial_j_int| the programmation is
 % similar to the previous one.
@@ -5801,142 +5909,106 @@
             \bool_set_true:N \l_@@_stop_loop_bool
           }
           { 
-            \@@_if_not_empty_cell:nnTF 
-              \l_@@_initial_i_int \l_@@_initial_j_int
-              { \bool_set_true:N \l_@@_stop_loop_bool }
+            \cs_if_exist:cTF
+              { 
+                @@ _ dotted _ 
+                \int_use:N \l_@@_initial_i_int - 
+                \int_use:N \l_@@_initial_j_int 
+              }
               {
-                \cs_set:cpn 
+                \int_add:Nn \l_@@_initial_i_int { #3 }
+                \int_add:Nn \l_@@_initial_j_int { #4 }
+                \bool_set_true:N \l_@@_initial_open_bool
+                \bool_set_true:N \l_@@_stop_loop_bool
+              }
+              {
+                \cs_if_exist:cTF 
                   { 
-                    @@ _ dotted _ 
-                    \int_use:N \l_@@_initial_i_int - 
-                    \int_use:N \l_@@_initial_j_int 
+                    pgf @ sh @ ns @ \@@_env: 
+                    - \int_use:N \l_@@_initial_i_int 
+                    - \int_use:N \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 whether the initial extremity of the dotted line is an implicit cell
-% already dotted (by another dotted line). In this case, we can't draw the line
-% because we have no Tikz node at the extremity of the arrow.
-%    \begin{macrocode}
-    \cs_if_free:cT 
-      { 
-        pgf at sh@ns at 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}
-% If we have at least one open extremity, we create the ``medium nodes'' in the
-% matrix but we should change that because, for an open extremity on the left or
-% the right side of the array, we actually use the |col|-nodes.
-% We remind that, when used once, the command |\@@_create_medium_nodes:| becomes
-% no-op in the current TeX group.  
-%    \begin{macrocode}
-    \bool_if:NT \l_@@_initial_open_bool \@@_create_medium_nodes: 
-    \bool_if:NT \l_@@_final_open_bool \@@_create_medium_nodes: 
-  }
-%    \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
-% diagonal lines, or vertical lines in columns of type |L| or |R|, an 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 suffix and
-% the anchor that must be used for the two nodes. 
-%
-% The coordinates are stored in four variables:
-% \begin{itemize} 
-% \item |\g_@@_x_initial_dim|
-% \item |\g_@@_y_initial_dim|
-% \item |\g_@@_x_final_dim|
-% \item |\g_@@_y_final_dim|. 
-% \end{itemize}
-% 
-% These variables are global for technical reasons: we have to do an affectation
-% in an environment |{tikzpicture}|.
+% \medskip
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_retrieve_coords:nn #1 #2
+\cs_new:Nn \@@_initial_cell: 
+  { \@@_env: - \int_use:N \l_@@_initial_i_int - \int_use:N \l_@@_initial_j_int }  
+\cs_new:Nn \@@_final_cell: 
+  { \@@_env: - \int_use:N \l_@@_final_i_int - \int_use:N \l_@@_final_j_int }  
+\cs_new_protected:Npn \@@_set_initial_coords:
   { 
-    \dim_gzero_new:N \g_@@_x_initial_dim 
-    \dim_gzero_new:N \g_@@_y_initial_dim 
-    \dim_gzero_new:N \g_@@_x_final_dim 
-    \dim_gzero_new:N \g_@@_y_final_dim
-    \begin { tikzpicture } [ remember~picture ]
-      \@@_extract_coords:w
-        ( nm - \int_use:N \g_@@_env_int -
-               \int_use:N \l_@@_initial_i_int -
-               \int_use:N \l_@@_initial_j_int #1 )
-      \dim_gset:Nn \g_@@_x_initial_dim \pgf at x
-      \dim_gset:Nn \g_@@_y_initial_dim \pgf at y
-      \@@_extract_coords:w
-        ( nm - \int_use:N \g_@@_env_int -
-               \int_use:N \l_@@_final_i_int -
-               \int_use:N \l_@@_final_j_int #2 )
-      \dim_gset:Nn \g_@@_x_final_dim \pgf at x
-      \dim_gset:Nn \g_@@_y_final_dim \pgf at y
-    \end { tikzpicture } 
+    \dim_set_eq:NN \l_@@_x_initial_dim \pgf at x
+    \dim_set_eq:NN \l_@@_y_initial_dim \pgf at y
   }
-\cs_generate_variant:Nn \@@_retrieve_coords:nn { x x }
-%    \end{macrocode}
-%
-% \interitem 
-% For the horizontal lines with open extremities, we take into account the
-% ``|col|'' nodes. The following command will recompute the $x$-value of the
-% extremities in this case (erasing the value computed in
-% |\@@_retrieve_coords:nn|).
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_adjust_with_col_nodes:
+\cs_new_protected:Npn \@@_set_final_coords:
   { 
-    \bool_if:NT \l_@@_initial_open_bool
-      { 
-        \begin { tikzpicture } [ remember~picture ]
-        \@@_extract_coords:w ( nm - \int_use:N \g_@@_env_int - col - 1 ) 
-        \dim_gset:Nn \g_@@_x_initial_dim \pgf at x
-        \end { tikzpicture }
-      }   
-    \bool_if:NT \l_@@_final_open_bool
-      { 
-        \begin { tikzpicture } [ remember~picture ]
-        \@@_extract_coords:w 
-          ( nm - \int_use:N \g_@@_env_int - col - \int_eval:n { \c at jCol + 1 } ) 
-        \dim_gset:Nn \g_@@_x_final_dim \pgf at x
-        \end { tikzpicture }
-      }
+    \dim_set_eq:NN \l_@@_x_final_dim \pgf at x
+    \dim_set_eq:NN \l_@@_y_final_dim \pgf at y
   }
+\cs_new_protected:Npn \@@_set_initial_coords_from_anchor:n #1
+  {
+    \pgfpointanchor \@@_initial_cell: { #1 } 
+    \@@_set_initial_coords:
+  }
+\cs_new_protected:Npn \@@_set_final_coords_from_anchor:n #1
+  {
+    \pgfpointanchor \@@_final_cell: { #1 } 
+    \@@_set_final_coords:
+  }
 %    \end{macrocode}
 %
 % \interitem
+% The first and the second arguments are the coordinates of the cell where the
+% command has been issued. The third argument is the list of the options.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_draw_Ldots:nn #1 #2 
+\cs_new_protected:Npn \@@_draw_Ldots:nnn #1 #2 #3
   { 
     \cs_if_free:cT { @@ _ dotted _ #1 - #2 }
       {
-        \bool_set_false:N \l_@@_impossible_line_bool
         \@@_find_extremities_of_line:nnnn { #1 } { #2 } 0 1
-        \bool_if:NF \l_@@_impossible_line_bool \@@_actually_draw_Ldots:
+%    \end{macrocode}
+% The previous command may have changed the current environment by marking some
+% cells as ``dotted'', but, fortunately, it is outside the group for the options
+% of the line.
+%    \begin{macrocode}
+        \group_begin:
+          \int_compare:nNnTF { #1 } = 0
+            { \color { nicematrix-first-row } }
+            { 
+%    \end{macrocode}
+% We remind that, when there is a ``last row'' |\l_@@_last_row_int| will always
+% be (after the construction of the array) the number of that ``last row'' even
+% if the option |last-row| has been used without value.
+%    \begin{macrocode}
+              \int_compare:nNnT { #1 } = \l_@@_last_row_int
+                { \color { nicematrix-last-row } }
+            }
+          \keys_set:nn { NiceMatrix / xdots } { #3 }
+          \tl_if_empty:VF \l_@@_xdots_color_tl { \color { \l_@@_xdots_color_tl } }
+          \@@_actually_draw_Ldots:
+        \group_end:
       }
   }
 %    \end{macrocode}
 % 
+% 
 % \medskip
-% The command |\@@_actually_draw_Ldots:| draws the |Ldots| line using the
-% following variables:
+% The command |\@@_actually_draw_Ldots:| has the following implicit arguments: 
 % \begin{itemize}
 % \item |\l_@@_initial_i_int|
 % \item |\l_@@_initial_j_int|
@@ -5946,128 +6018,244 @@
 % \item |\l_@@_final_open_bool|. 
 % \end{itemize}
 %
-% We have a dedicated command because it is used also by |\Hdotsfor|. 
+% The following function is also used by |\Hdotsfor|. 
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_actually_draw_Ldots:
   { 
-    \@@_retrieve_coords:xx 
-      { 
-        \bool_if:NTF \l_@@_initial_open_bool
-          { - medium.base~west }
-          { .base~east }
+    \bool_if:NTF \l_@@_initial_open_bool
+      {
+        \@@_qpoint: { col - \int_use:N \l_@@_initial_j_int }
+        \dim_set_eq:NN \l_@@_x_initial_dim \pgf at x 
+        \dim_add:Nn \l_@@_x_initial_dim \arraycolsep 
+        \@@_qpoint: { row - \int_use:N \l_@@_initial_i_int - base }
+        \dim_set_eq:NN \l_@@_y_initial_dim \pgf at y
       }
+      { \@@_set_initial_coords_from_anchor:n { base~east } }
+    \bool_if:NTF \l_@@_final_open_bool
       {
-        \bool_if:NTF \l_@@_final_open_bool
-          { - medium.base~east }
-          { .base~west }
+        \@@_qpoint: { col - \@@_succ:N \l_@@_final_j_int }
+        \dim_set_eq:NN \l_@@_x_final_dim \pgf at x 
+        \dim_sub:Nn \l_@@_x_final_dim \arraycolsep 
+        \@@_qpoint: { row - \int_use:N \l_@@_final_i_int - base }
+        \dim_set_eq:NN \l_@@_y_final_dim \pgf at y
       }
-    \@@_adjust_with_col_nodes:
-    \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 }
+      { \@@_set_final_coords_from_anchor:n { base~west } } 
 %    \end{macrocode}
 % We raise the line of a quantity equal to the radius of the dots because we
 % want the dots really ``on'' the line of texte.
 %    \begin{macrocode}
-    \dim_gadd:Nn \g_@@_y_initial_dim { 0.53 pt }
-    \dim_gadd:Nn \g_@@_y_final_dim { 0.53 pt }
-    \@@_draw_tikz_line:
+    \dim_add:Nn \l_@@_y_initial_dim \l_@@_radius_dim
+    \dim_add:Nn \l_@@_y_final_dim \l_@@_radius_dim
+    \@@_draw_line:
+%    \end{macrocode}
+% The values of |\l_@@_x_initial_dim|, |\l_@@_y_initial_dim|, |\l_@@_x_final_dim|,
+% |\l_@@_y_final_dim|,
+%
+% |\l_@@_initial_open_bool| and |\l_@@_final_open_bool| are still available
+% after the |\@@_draw_line:|.
+%    \begin{macrocode}
   }
 %    \end{macrocode}
 %
-% \bigskip
+% \interitem
+% The first and the second arguments are the coordinates of the cell where the
+% command has been issued. The third argument is the list of the options.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_draw_Cdots:nn #1 #2
+\cs_new_protected:Npn \@@_draw_Cdots:nnn #1 #2 #3
   { 
     \cs_if_free:cT { @@ _ dotted _ #1 - #2 }
       {
-        \bool_set_false:N \l_@@_impossible_line_bool
         \@@_find_extremities_of_line:nnnn { #1 } { #2 } 0 1
-        \bool_if:NF \l_@@_impossible_line_bool
-          {
-            \@@_retrieve_coords:xx 
-              { 
-                \bool_if:NTF \l_@@_initial_open_bool
-                  { - medium.mid~west }
-                  { .mid~east }
-              }
-              {
-                \bool_if:NTF \l_@@_final_open_bool
-                  { - medium.mid~east }
-                  { .mid~west }
-              }
-            \@@_adjust_with_col_nodes:
-            \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}
+% The previous command may have changed the current environment by marking some
+% cells as ``dotted'', but, fortunately, it is outside the group for the options
+% of the line.
+%    \begin{macrocode}
+        \group_begin:
+          \int_compare:nNnTF { #1 } = 0
+            { \color { nicematrix-first-row } }
+            { 
+%    \end{macrocode}
+% We remind that, when there is a ``last row'' |\l_@@_last_row_int| will always
+% be (after the construction of the array) the number of that ``last row'' even
+% if the option |last-row| has been used without value.
+%    \begin{macrocode}
+              \int_compare:nNnT { #1 } = \l_@@_last_row_int
+                { \color { nicematrix-last-row } }
+            }
+          \keys_set:nn { NiceMatrix / xdots } { #3 }
+          \tl_if_empty:VF \l_@@_xdots_color_tl { \color { \l_@@_xdots_color_tl } }
+          \@@_actually_draw_Cdots: 
+        \group_end:
       }
   }
 %    \end{macrocode}
 %
-% \bigskip
-% For the vertical dots, we have to distinguish different instances because we
-% want really vertical lines. Be careful: it's not possible to insert the
-% command |\@@_retrieve_coords:nn| in the arguments |T| and |F| of the
-% \pkg{expl3} commands (why?). 
+% \medskip
+% The command |\@@_actually_draw_Cdots:| has the following implicit arguments: 
+% \begin{itemize}
+% \item |\l_@@_initial_i_int|
+% \item |\l_@@_initial_j_int|
+% \item |\l_@@_initial_open_bool|
+% \item |\l_@@_final_i_int|
+% \item |\l_@@_final_j_int| 
+% \item |\l_@@_final_open_bool|. 
+% \end{itemize}
+%
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_actually_draw_Cdots:
+  {
+    \bool_if:NTF \l_@@_initial_open_bool
+      { 
+        \@@_qpoint: { col - \int_use:N \l_@@_initial_j_int } 
+        \dim_set_eq:NN \l_@@_x_initial_dim \pgf at x 
+        \dim_add:Nn \l_@@_x_initial_dim \arraycolsep 
+      }
+      { \@@_set_initial_coords_from_anchor:n { mid~east } }
+    \bool_if:NTF \l_@@_final_open_bool
+      { 
+        \@@_qpoint: { col - \@@_succ:N \l_@@_final_j_int }
+        \dim_set_eq:NN \l_@@_x_final_dim \pgf at x 
+        \dim_sub:Nn \l_@@_x_final_dim \arraycolsep 
+      }
+      { \@@_set_final_coords_from_anchor:n { mid~west } }
+    \bool_lazy_and:nnTF
+      \l_@@_initial_open_bool 
+      \l_@@_final_open_bool 
+      {
+        \@@_qpoint: { row - \int_use:N \l_@@_initial_i_int }
+        \dim_set_eq:NN \l_tmpa_dim \pgf at y
+        \@@_qpoint: { row - \@@_succ:N \l_@@_initial_i_int }
+        \dim_set:Nn \l_@@_y_initial_dim { ( \l_tmpa_dim + \pgf at y ) / 2 } 
+        \dim_set_eq:NN \l_@@_y_final_dim \l_@@_y_initial_dim
+      }     
+      {
+        \bool_if:NT \l_@@_initial_open_bool
+          { \dim_set_eq:NN \l_@@_y_initial_dim \l_@@_y_final_dim }
+        \bool_if:NT \l_@@_final_open_bool
+          { \dim_set_eq:NN \l_@@_y_final_dim \l_@@_y_initial_dim }
+      }
+    \@@_draw_line:
+%    \end{macrocode}
+% The values of |\l_@@_x_initial_dim|, |\l_@@_y_initial_dim|, |\l_@@_x_final_dim|,
+% |\l_@@_y_final_dim|, 
+%
+% |\l_@@_initial_open_bool| and |\l_@@_final_open_bool| are still available
+% after the |\@@_draw_line:|.
+%    \begin{macrocode}
+  } 
+%    \end{macrocode}
+%
+%
+% The first and the second arguments are the coordinates of the cell where the
+% command has been issued. The third argument is the list of the options.
 %    \begin{macrocode}      
-\cs_new_protected:Npn \@@_draw_Vdots:nn #1 #2
+\cs_new_protected:Npn \@@_draw_Vdots:nnn #1 #2 #3
   { 
+    \tl_if_empty:VF \l_@@_xdots_color_tl { \color { \l_@@_xdots_color_tl } }
     \cs_if_free:cT { @@ _ dotted _ #1 - #2 }
       {
-        \bool_set_false:N \l_@@_impossible_line_bool
         \@@_find_extremities_of_line:nnnn { #1 } { #2 } 1 0
-        \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 previous command may have changed the current environment by marking some
+% cells as ``dotted'', but, fortunately, it is outside the group for the options
+% of the line.
+%    \begin{macrocode}
+        \group_begin:
+          \int_compare:nNnTF { #2 } = 0 
+            { \color { nicematrix-first-col } }
+            {
+              \int_compare:nNnT { #2 } = \l_@@_last_col_int
+                { \color { nicematrix-last-col } }
+            }
+          \keys_set:nn { NiceMatrix / xdots } { #3 }
+          \@@_actually_draw_Vdots:
+        \group_end:
+      }
+  }
+%    \end{macrocode}
+%
+% \bigskip
+% The command |\@@_actually_draw_Vdots:| has the following implicit arguments: 
+% \begin{itemize}
+% \item |\l_@@_initial_i_int|
+% \item |\l_@@_initial_j_int|
+% \item |\l_@@_initial_open_bool|
+% \item |\l_@@_final_i_int|
+% \item |\l_@@_final_j_int| 
+% \item |\l_@@_final_open_bool|. 
+% \end{itemize}
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_actually_draw_Vdots:
+  {
+%    \end{macrocode}
 % The boolean |\l_tmpa_bool| indicates whether the column is of type |l| (|L| of
 % |{NiceArray}|) or may be considered as if.
 %    \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_false:N \l_tmpa_bool 
+    \bool_lazy_or:nnF \l_@@_initial_open_bool \l_@@_final_open_bool 
+      {
+        \@@_set_initial_coords_from_anchor:n { south~west } 
+        \@@_set_final_coords_from_anchor:n { north~west } 
+        \bool_set:Nn \l_tmpa_bool 
+          { \dim_compare_p:nNn \l_@@_x_initial_dim = \l_@@_x_final_dim }
+      }
 %    \end{macrocode}
-% The boolean |\l_tmpb_bool| indicates whether the column is of type |c| (|C| of
+% Now, we try to determine whether the column is of type |c| (|C| of
 % |{NiceArray}|) or may be considered as if.
+%    \begin{macrocode}
+    \bool_if:NTF \l_@@_initial_open_bool
+      { 
+        \@@_qpoint: { row - 1 }
+        \dim_set_eq:NN \l_@@_y_initial_dim \pgf at y
+      }
+      { \@@_set_initial_coords_from_anchor:n { south } }
+    \bool_if:NTF \l_@@_final_open_bool
+      { 
+        \@@_qpoint: { row - \@@_succ:N \c at iRow }
+        \dim_set_eq:NN \l_@@_y_final_dim \pgf at y 
+      }
+      { \@@_set_final_coords_from_anchor:n { north } }     
+    \bool_if:NTF \l_@@_initial_open_bool
+      {
+        \bool_if:NTF \l_@@_final_open_bool
+          {
+            \@@_qpoint: { col - \int_use:N \l_@@_initial_j_int }
+            \dim_set_eq:NN \l_tmpa_dim \pgf at x
+            \@@_qpoint: { col - \@@_succ:N \l_@@_initial_j_int }
+            \dim_set:Nn \l_@@_x_initial_dim { ( \pgf at x + \l_tmpa_dim ) / 2 } 
+            \dim_set_eq:NN \l_@@_x_final_dim \l_@@_x_initial_dim
+          }
+          { \dim_set_eq:NN \l_@@_x_initial_dim \l_@@_x_final_dim }
+      }
+      {
+        \bool_if:NTF \l_@@_final_open_bool
+          { \dim_set_eq:NN \l_@@_x_final_dim \l_@@_x_initial_dim }
+          {
+%    \end{macrocode}
+% Now the case where both extremities are closed. The first conditional tests
+% 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_compare:nNnF \l_@@_x_initial_dim = \l_@@_x_final_dim 
               { 
-                \dim_gset:Nn \g_@@_x_initial_dim
+                \dim_set:Nn \l_@@_x_initial_dim
                   { 
                     \bool_if:NTF \l_tmpa_bool \dim_min:nn \dim_max:nn
-                      \g_@@_x_initial_dim \g_@@_x_final_dim
+                      \l_@@_x_initial_dim \l_@@_x_final_dim
                   }
-                \dim_gset_eq:NN \g_@@_x_final_dim \g_@@_x_initial_dim
+                \dim_set_eq:NN \l_@@_x_final_dim \l_@@_x_initial_dim
               }
-            \@@_draw_tikz_line:
-          }
+          }   
       }
+    \@@_draw_line:
+%    \end{macrocode}
+% The values of |\l_@@_x_initial_dim|, |\l_@@_y_initial_dim|, |\l_@@_x_final_dim|,
+% |\l_@@_y_final_dim|, 
+%
+% |\l_@@_initial_open_bool| and |\l_@@_final_open_bool| are
+% still available after the |\@@_draw_line:|. 
+%    \begin{macrocode}
   }
 %    \end{macrocode}
 %
@@ -6075,39 +6263,72 @@
 % 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.
+%
+% The first and the second arguments are the coordinates of the cell where the
+% command has been issued. The third argument is the list of the options.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_draw_Ddots:nn #1 #2
+\cs_new_protected:Npn \@@_draw_Ddots:nnn #1 #2 #3
   { 
     \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~west }
-                  { .south~east }
-              } 
-              { 
-                \bool_if:NTF \l_@@_final_open_bool
-                  { - medium.south~east }
-                  { .north~west }
-              }
 %    \end{macrocode}
+% The previous command may have changed the current environment by marking some
+% cells as ``dotted'', but, fortunately, it is outside the group for the options
+% of the line.
+%    \begin{macrocode}
+        \group_begin:
+          \keys_set:nn { NiceMatrix / xdots } { #3 }
+          \tl_if_empty:VF \l_@@_xdots_color_tl { \color { \l_@@_xdots_color_tl } }
+          \@@_actually_draw_Ddots:
+        \group_end:
+      }
+  }
+%    \end{macrocode}
+%
+% \bigskip
+% The command |\@@_actually_draw_Ddots:| has the following implicit arguments: 
+% \begin{itemize}
+% \item |\l_@@_initial_i_int|
+% \item |\l_@@_initial_j_int|
+% \item |\l_@@_initial_open_bool|
+% \item |\l_@@_final_i_int|
+% \item |\l_@@_final_j_int| 
+% \item |\l_@@_final_open_bool|. 
+% \end{itemize}
+%
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_actually_draw_Ddots:
+  {
+    \bool_if:NTF \l_@@_initial_open_bool
+      {
+        \@@_qpoint: { row - \int_use:N \l_@@_initial_i_int }
+        \dim_set_eq:NN \l_@@_y_initial_dim \pgf at y
+        \@@_qpoint: { col - \int_use:N \l_@@_initial_j_int }
+        \dim_set_eq:NN \l_@@_x_initial_dim \pgf at x
+      }
+      { \@@_set_initial_coords_from_anchor:n { south~east } }
+    \bool_if:NTF \l_@@_final_open_bool
+      {
+        \@@_qpoint: { row - \@@_succ:N \l_@@_final_i_int }
+        \dim_set_eq:NN \l_@@_y_final_dim \pgf at y
+        \@@_qpoint: { col - \@@_succ:N \l_@@_final_j_int }
+        \dim_set_eq:NN \l_@@_x_final_dim \pgf at x
+      }
+      { \@@_set_final_coords_from_anchor:n { 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,
+% |\l_@@_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_gincr:N \g_@@_ddots_int
 %    \end{macrocode}
-% We test if the diagonal line is the first one (the counter |\l_@@_ddots_int|
+% We test if the diagonal line is the first one (the counter |\g_@@_ddots_int|
 % is created for this usage). 
 %    \begin{macrocode}
-                \int_compare:nNnTF \l_@@_ddots_int = 1
+        \int_compare:nNnTF \g_@@_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
@@ -6114,79 +6335,118 @@
 % 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_gset:Nn \g_@@_delta_x_one_dim 
+              { \l_@@_x_final_dim - \l_@@_x_initial_dim }
+            \dim_gset:Nn \g_@@_delta_y_one_dim 
+              { \l_@@_y_final_dim - \l_@@_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|.
+% extremity of the line by modifying the coordinate |\l_@@_x_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_set:Nn \l_@@_y_final_dim          
+              { 
+                \l_@@_y_initial_dim +
+                ( \l_@@_x_final_dim - \l_@@_x_initial_dim ) * 
+                \dim_ratio:nn \g_@@_delta_y_one_dim \g_@@_delta_x_one_dim 
               }
+          }
+      }
+    \@@_draw_line:
 %    \end{macrocode}
-% Now, we can draw the dotted line (after a possible change of
-% |\g_@@_y_initial_dim|). 
+% The values of |\l_@@_x_initial_dim|, |\l_@@_y_initial_dim|, |\l_@@_x_final_dim|,
+% |\l_@@_y_final_dim|, 
+%
+% |\l_@@_initial_open_bool| and |\l_@@_final_open_bool| are still available
+% after the |\@@_draw_line:|.
 %    \begin{macrocode}
-            \@@_draw_tikz_line:
-          }
-      }
   }
 %    \end{macrocode}
 %
 % \bigskip
 % We draw the |\Iddots| diagonals in the same way.
+%
+% The first and the second arguments are the coordinates of the cell where the
+% command has been issued. The third argument is the list of the options.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_draw_Iddots:nn #1 #2
+\cs_new_protected:Npn \@@_draw_Iddots:nnn #1 #2 #3 
   {
     \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 
+%    \end{macrocode}
+% The previous command may have changed the current environment by marking some
+% cells as ``dotted'', but, fortunately, it is outside the group for the options
+% of the line.
+%    \begin{macrocode}
+        \group_begin:
+          \keys_set:nn { NiceMatrix / xdots } { #3 }
+          \tl_if_empty:VF \l_@@_xdots_color_tl { \color { \l_@@_xdots_color_tl } }
+          \@@_actually_draw_Iddots:
+        \group_end:
+      }
+  }
+%    \end{macrocode}
+%
+% \bigskip
+% The command |\@@_actually_draw_Iddots:| has the following implicit arguments: 
+% \begin{itemize}
+% \item |\l_@@_initial_i_int|
+% \item |\l_@@_initial_j_int|
+% \item |\l_@@_initial_open_bool|
+% \item |\l_@@_final_i_int|
+% \item |\l_@@_final_j_int| 
+% \item |\l_@@_final_open_bool|. 
+% \end{itemize}
+%
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_actually_draw_Iddots:
+  {
+    \bool_if:NTF \l_@@_initial_open_bool
+      {
+        \@@_qpoint: { row - \int_use:N \l_@@_initial_i_int }
+        \dim_set_eq:NN \l_@@_y_initial_dim \pgf at y
+        \@@_qpoint: { col - \@@_succ:N \l_@@_initial_j_int }
+        \dim_set_eq:NN \l_@@_x_initial_dim \pgf at x
+      }
+      { \@@_set_initial_coords_from_anchor:n { south~west } }
+    \bool_if:NTF \l_@@_final_open_bool
+      {
+        \@@_qpoint: { row - \@@_succ:N \l_@@_final_i_int }
+        \dim_set_eq:NN \l_@@_y_final_dim \pgf at y
+        \@@_qpoint: { col - \int_use:N \l_@@_final_j_int }
+        \dim_set_eq:NN \l_@@_x_final_dim \pgf at x
+      }
+      { \@@_set_final_coords_from_anchor:n { north~east } } 
+    \bool_if:NT \l_@@_parallelize_diags_bool
+      { 
+        \int_gincr:N \g_@@_iddots_int
+        \int_compare:nNnTF \g_@@_iddots_int = 1
+          { 
+            \dim_gset:Nn \g_@@_delta_x_two_dim 
+              { \l_@@_x_final_dim - \l_@@_x_initial_dim }
+            \dim_gset:Nn \g_@@_delta_y_two_dim 
+              { \l_@@_y_final_dim - \l_@@_y_initial_dim }
+          }
+          { 
+            \dim_set:Nn \l_@@_y_final_dim
               { 
-                \bool_if:NTF \l_@@_initial_open_bool
-                  { - medium.north~east }
-                  { .south~west }
-              } 
-              { 
-                \bool_if:NTF \l_@@_final_open_bool
-                  { - medium.south~west }
-                  { .north~east }
+                \l_@@_y_initial_dim +
+                ( \l_@@_x_final_dim - \l_@@_x_initial_dim ) *
+                \dim_ratio:nn \g_@@_delta_y_two_dim \g_@@_delta_x_two_dim 
               }
-            \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:
           }
       }
+    \@@_draw_line:
+%    \end{macrocode}
+% The values of |\l_@@_x_initial_dim|, |\l_@@_y_initial_dim|, |\l_@@_x_final_dim|,
+% |\l_@@_y_final_dim|, 
+%
+% |\l_@@_initial_open_bool| and |\l_@@_final_open_bool| are still available
+% after the |\@@_draw_line:|.
+%    \begin{macrocode}
   }
 %    \end{macrocode}
 %
@@ -6205,95 +6465,153 @@
 % \bigskip
 % \subsection*{The actual instructions for drawing the dotted line with Tikz}
 %
-% The command |\@@_draw_tikz_line:| draws the line using four implicit
-% arguments:  
+% The command |\@@_draw_line:| should be used in a |{pgfpicture}|. It has six
+% 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: their
-% first affectation was in an instruction |\tikz|. 
+% \begin{itemize}
+% \item |\l_@@_x_initial_dim| 
+% \item |\l_@@_y_initial_dim| 
+% \item |\l_@@_x_final_dim|
+% \item |\l_@@_y_final_dim|
+% \item |\l_@@_initial_open_bool|
+% \item |\l_@@_final_open_bool|
+% \end{itemize}
 %
+%
+%
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_draw_tikz_line:
+\cs_new_protected:Npn \@@_draw_line:
+  {
+    \pgfrememberpicturepositiononpagetrue
+    \pgf at relevantforpicturesizefalse
+    \tl_if_eq:NNTF \l_@@_xdots_line_style_tl \c_@@_standard_tl
+      \@@_draw_standard_dotted_line:
+      \@@_draw_non_standard_dotted_line:
+  }
+%    \end{macrocode}
+% 
+% \medskip
+% We have to do a special construction with |\exp_args:NV| to be able to put in
+% the list of options in the correct place in the Tikz instruction.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_draw_non_standard_dotted_line:
   { 
+     \begin { scope }
+     \exp_args:No \@@_draw_non_standard_dotted_line:n 
+       { \l_@@_xdots_line_style_tl , \l_@@_xdots_color_tl } 
+  }
 %    \end{macrocode}
+% We have used the fact that, in \textsc{pgf}, un color name can be put directly
+% in a list of options (that's why we have put diredtly |\l_@@_xdots_color_tl|).
+%
+% \smallskip
+% The argument of |\@@_draw_non_standard_dotted_line:n| is, in fact, the list of options.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_draw_non_standard_dotted_line:n #1
+  {
+    \draw 
+      [ 
+        #1 , 
+        shorten~> = \l_@@_xdots_shorten_dim , 
+        shorten~< = \l_@@_xdots_shorten_dim , 
+      ]
+          ( \l_@@_x_initial_dim , \l_@@_y_initial_dim )
+       -- ( \l_@@_x_final_dim , \l_@@_y_final_dim ) ;
+    \end { scope }
+  }
+%    \end{macrocode}
+% 
+% \bigskip
+% The command |\@@_draw_standard_dotted_line:| draws the line with our system of points
+% (which give a dotted line with real round points).
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_draw_standard_dotted_line: 
+  { 
+    \pgfrememberpicturepositiononpagetrue
+    \pgf at relevantforpicturesizefalse
+    \group_begin:
+%    \end{macrocode}
 % The dimension |\l_@@_l_dim| is the length $\ell$ of the line to draw. We use
 % the floating point reals of \pkg{expl3} to compute this length.
 %    \begin{macrocode}
-    \dim_zero_new:N \l_@@_l_dim
-    \dim_set:Nn \l_@@_l_dim
-      { 
-        \fp_to_dim:n 
-          { 
-            sqrt 
-             ( 
-               (   \dim_use:N \g_@@_x_final_dim 
-                 - \dim_use:N \g_@@_x_initial_dim 
-               ) ^ 2
-                  +
-               (   \dim_use:N \g_@@_y_final_dim 
-                 - \dim_use:N \g_@@_y_initial_dim
-               ) ^ 2 
-             )
-          }
-      }
+      \dim_zero_new:N \l_@@_l_dim
+      \dim_set:Nn \l_@@_l_dim
+        { 
+          \fp_to_dim:n 
+            { 
+              sqrt 
+               ( 
+                 ( \l_@@_x_final_dim - \l_@@_x_initial_dim ) ^ 2
+                    +
+                 ( \l_@@_y_final_dim - \l_@@_y_initial_dim ) ^ 2 
+               )
+            }
+        }
 %    \end{macrocode}
 % We draw only if the length is not equal to zero (in fact, in the first
-% compilation, the length may be equal to zero). 
+% compilation, the length may be equal to zero when the command |\line| is used). 
 %    \begin{macrocode}
-    \dim_compare:nNnF \l_@@_l_dim = \c_zero_dim
+      \dim_compare:nNnF \l_@@_l_dim = \c_zero_dim \@@_actually_draw_line: 
+    \group_end:
+  } 
 %    \end{macrocode}
+%
+%
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_actually_draw_line:
+  { 
+%    \end{macrocode}
 % The integer |\l_tmpa_int| is the number of dots of the dotted line.
 %    \begin{macrocode}
+    \bool_if:NTF \l_@@_initial_open_bool
       { 
-        \bool_if:NTF \l_@@_initial_open_bool
+        \bool_if:NTF \l_@@_final_open_bool
           { 
-            \bool_if:NTF \l_@@_final_open_bool
+            \int_set:Nn \l_tmpa_int 
+              { \dim_ratio:nn \l_@@_l_dim \l_@@_inter_dots_dim }
+          }
+          { 
+            \int_set:Nn \l_tmpa_int 
               { 
-                \int_set:Nn \l_tmpa_int 
-                  { \dim_ratio:nn \l_@@_l_dim \l_@@_inter_dots_dim }
+                \dim_ratio:nn 
+                  { \l_@@_l_dim - \l_@@_xdots_shorten_dim } 
+                  \l_@@_inter_dots_dim 
               }
+          }
+      }
+      { 
+        \bool_if:NTF \l_@@_final_open_bool
+          { 
+            \int_set:Nn \l_tmpa_int 
               { 
-                \int_set:Nn \l_tmpa_int 
-                  { 
-                    \dim_ratio:nn 
-                      { \l_@@_l_dim - \l_@@_dotted_lines_margin_dim } 
-                      \l_@@_inter_dots_dim 
-                  }
+                \dim_ratio:nn 
+                  { \l_@@_l_dim - \l_@@_xdots_shorten_dim } 
+                  \l_@@_inter_dots_dim 
               }
           }
           { 
-            \bool_if:NTF \l_@@_final_open_bool
+            \int_set:Nn \l_tmpa_int 
               { 
-                \int_set:Nn \l_tmpa_int 
-                  { 
-                    \dim_ratio:nn 
-                      { \l_@@_l_dim - \l_@@_dotted_lines_margin_dim } 
-                      \l_@@_inter_dots_dim 
-                  }
+                \dim_ratio:nn 
+                  { \l_@@_l_dim - ( 2 \l_@@_xdots_shorten_dim ) } 
+                  \l_@@_inter_dots_dim
               }
-              { 
-                \int_set:Nn \l_tmpa_int 
-                  { 
-                    \dim_ratio:nn 
-                      { \l_@@_l_dim - ( 2 \l_@@_dotted_lines_margin_dim ) } 
-                      \l_@@_inter_dots_dim
-                  }
-              }
           }
+      }
 %    \end{macrocode}
 % The dimensions |\l_tmpa_dim| and |\l_tmpb_dim| are the coordinates of the
 % vector between two dots in the dotted line.
 %    \begin{macrocode}
-        \dim_set:Nn \l_tmpa_dim 
-          { 
-            ( \g_@@_x_final_dim - \g_@@_x_initial_dim ) *
-            \dim_ratio:nn \l_@@_inter_dots_dim \l_@@_l_dim 
-          }
-        \dim_set:Nn \l_tmpb_dim 
-          { 
-            ( \g_@@_y_final_dim - \g_@@_y_initial_dim ) *
-            \dim_ratio:nn \l_@@_inter_dots_dim \l_@@_l_dim
-          }
+    \dim_set:Nn \l_tmpa_dim 
+      { 
+        ( \l_@@_x_final_dim - \l_@@_x_initial_dim ) *
+        \dim_ratio:nn \l_@@_inter_dots_dim \l_@@_l_dim 
+      }
+    \dim_set:Nn \l_tmpb_dim 
+      { 
+        ( \l_@@_y_final_dim - \l_@@_y_initial_dim ) *
+        \dim_ratio:nn \l_@@_inter_dots_dim \l_@@_l_dim
+      }
 %    \end{macrocode}
 %
 % The length $\ell$ is the length of the dotted line. We note $\Delta$ the
@@ -6302,46 +6620,44 @@
 % extremity of the line and the first dot will be equal to $k\cdot\delta$ where 
 % $k=0$, $1$ or $2$. We first compute this number $k$ in |\l_tmpb_int|.
 %    \begin{macrocode}
-        \int_set:Nn \l_tmpb_int
-          { 
-            \bool_if:NTF \l_@@_initial_open_bool
-              { \bool_if:NTF \l_@@_final_open_bool 1 0 }
-              { \bool_if:NTF \l_@@_final_open_bool 2 1 }
-          }
+    \int_set:Nn \l_tmpb_int
+      { 
+        \bool_if:NTF \l_@@_initial_open_bool
+          { \bool_if:NTF \l_@@_final_open_bool 1 0 }
+          { \bool_if:NTF \l_@@_final_open_bool 2 1 }
+      }
 %    \end{macrocode}
-% In the loop over the dots, the dimensions |\g_@@_x_initial_dim| and
-% |\g_@@_y_initial_dim| will be used for the coordinates of the dots. But,
+% In the loop over the dots, the dimensions |\l_@@_x_initial_dim| and
+% |\l_@@_y_initial_dim| will be used for the coordinates of the dots. But,
 % before the loop, we must move until the first dot.
 %
 %    \begin{macrocode}
-        \dim_gadd:Nn \g_@@_x_initial_dim
-          {  
-            ( \g_@@_x_final_dim - \g_@@_x_initial_dim ) *
-            \dim_ratio:nn 
-            { \l_@@_l_dim - \l_@@_inter_dots_dim * \l_tmpa_int }
-            { 2 \l_@@_l_dim }
-            * \l_tmpb_int
-          }
-        \dim_gadd:Nn \g_@@_y_initial_dim 
-          {   
-            ( \g_@@_y_final_dim - \g_@@_y_initial_dim ) * 
-            \dim_ratio:nn 
-              { \l_@@_l_dim - \l_@@_inter_dots_dim * \l_tmpa_int } 
-              { 2 \l_@@_l_dim } 
-            * \l_tmpb_int
-          }
-        \begin { tikzpicture } [ overlay ]
-          \int_step_inline:nnn 0 \l_tmpa_int
-            { 
-              \pgfpathcircle 
-                { \pgfpoint { \g_@@_x_initial_dim } { \g_@@_y_initial_dim } }
-                { \l_@@_radius_dim }
-              \pgfusepath { fill }
-              \dim_gadd:Nn \g_@@_x_initial_dim \l_tmpa_dim
-              \dim_gadd:Nn \g_@@_y_initial_dim \l_tmpb_dim 
-            }
-        \end { tikzpicture } 
+    \dim_gadd:Nn \l_@@_x_initial_dim
+      {  
+        ( \l_@@_x_final_dim - \l_@@_x_initial_dim ) *
+        \dim_ratio:nn 
+          { \l_@@_l_dim - \l_@@_inter_dots_dim * \l_tmpa_int }
+          { 2 \l_@@_l_dim }
+        * \l_tmpb_int
       }
+    \dim_gadd:Nn \l_@@_y_initial_dim 
+      {   
+        ( \l_@@_y_final_dim - \l_@@_y_initial_dim ) * 
+        \dim_ratio:nn 
+          { \l_@@_l_dim - \l_@@_inter_dots_dim * \l_tmpa_int } 
+          { 2 \l_@@_l_dim } 
+        * \l_tmpb_int
+      }
+    \pgf at relevantforpicturesizefalse
+    \int_step_inline:nnn 0 \l_tmpa_int
+      { 
+        \pgfpathcircle 
+          { \pgfpoint \l_@@_x_initial_dim \l_@@_y_initial_dim } 
+          { \l_@@_radius_dim }
+        \dim_add:Nn \l_@@_x_initial_dim \l_tmpa_dim
+        \dim_add:Nn \l_@@_y_initial_dim \l_tmpb_dim
+      }
+    \pgfusepathqfill
   }
 %    \end{macrocode}
 %
@@ -6348,28 +6664,7 @@
 % \bigskip
 % \subsection*{User commands available in the new environments}
 %
-% We give new names for the commands |\ldots|, |\cdots|, |\vdots| and |\ddots|
-% because these commands will be redefined (if the option |renew-dots| is used).
-%    \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:| declares the current cell as empty. For
-% efficiency, this is done by creating a special control sequence.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_add_to_empty_cells:
-  { 
-    \cs_gset:cpx 
-      { @@ _ empty _ \int_use:N \c at iRow - \int_use:N \c at jCol } 
-      { \int_use:N \g_@@_env_int }
-  }
-%    \end{macrocode}
-%
 % \interitem 
 % The commands |\@@_Ldots|, |\@@_Cdots|, |\@@_Vdots|, |\@@_Ddots| and
 % |\@@_Iddots| will be linked to |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots| and
@@ -6376,54 +6671,64 @@
 % |\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.
+% The starred versions of these commands are deprecated since version~3.1 but,
+% as for now, they are still available with an error.
 %    \begin{macrocode}
-\NewDocumentCommand \@@_Ldots { s }
+\NewDocumentCommand \@@_Ldots { s O { } }
   { 
-    \bool_if:nF { #1 } { \@@_instruction_of_type:n { Ldots } }
+    \bool_if:nTF { #1 } 
+      { \@@_error:n { starred~commands } }
+      { \@@_instruction_of_type:nn { Ldots } { #2 } }
     \bool_if:NF \l_@@_nullify_dots_bool { \phantom \@@_ldots }
-    \@@_add_to_empty_cells:
+    \bool_gset_true:N \g_@@_empty_cell_bool
   }
 %    \end{macrocode}
 %
 % \bigskip
 %    \begin{macrocode}
-\NewDocumentCommand \@@_Cdots { s }
+\NewDocumentCommand \@@_Cdots { s O { } }
   { 
-    \bool_if:nF { #1 } { \@@_instruction_of_type:n { Cdots } }
+    \bool_if:nTF { #1 } 
+      { \@@_error:n { starred~commands } }
+      { \@@_instruction_of_type:nn { Cdots } { #2 } }
     \bool_if:NF \l_@@_nullify_dots_bool { \phantom \@@_cdots }
-    \@@_add_to_empty_cells:
+    \bool_gset_true:N \g_@@_empty_cell_bool
   }
 %    \end{macrocode}
 %
 % \bigskip
 %    \begin{macrocode}
-\NewDocumentCommand \@@_Vdots { s }
+\NewDocumentCommand \@@_Vdots { s O { } }
   {
-    \bool_if:nF { #1 } { \@@_instruction_of_type:n { Vdots } }
+    \bool_if:nTF { #1 } 
+      { \@@_error:n { starred~commands } }
+      { \@@_instruction_of_type:nn { Vdots } { #2 } }
     \bool_if:NF \l_@@_nullify_dots_bool { \phantom \@@_vdots }
-    \@@_add_to_empty_cells:
+    \bool_gset_true:N \g_@@_empty_cell_bool
   }
 %    \end{macrocode}
 %
 % \bigskip
 %    \begin{macrocode}
-\NewDocumentCommand \@@_Ddots { s }
+\NewDocumentCommand \@@_Ddots { s O { } }
   { 
-    \bool_if:nF { #1 } { \@@_instruction_of_type:n { Ddots } }
+    \bool_if:nTF { #1 } 
+      { \@@_error:n { starred~commands } }
+      { \@@_instruction_of_type:nn { Ddots } { #2 } }
     \bool_if:NF \l_@@_nullify_dots_bool { \phantom \@@_ddots }
-    \@@_add_to_empty_cells:
+    \bool_gset_true:N \g_@@_empty_cell_bool
   }
 %    \end{macrocode}
 %
 % \bigskip
 %    \begin{macrocode}
-\NewDocumentCommand \@@_Iddots { s }
+\NewDocumentCommand \@@_Iddots { s O { } }
   { 
-    \bool_if:nF { #1 } { \@@_instruction_of_type:n { Iddots } }
+    \bool_if:nTF { #1 } 
+      { \@@_error:n { starred~commands } }
+      { \@@_instruction_of_type:nn { Iddots } { #2 } }
     \bool_if:NF \l_@@_nullify_dots_bool { \phantom \@@_iddots }
-    \@@_add_to_empty_cells:
+    \bool_gset_true:N \g_@@_empty_cell_bool
   }
 %    \end{macrocode}
 %
@@ -6433,7 +6738,7 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_Hspace:
   { 
-   \@@_add_to_empty_cells:
+   \bool_gset_true:N \g_@@_empty_cell_bool
    \hspace
   }
 %    \end{macrocode}
@@ -6483,18 +6788,23 @@
 %    \begin{macrocode}
 \bool_if:NTF \c_@@_draft_bool
   {
-    \NewDocumentCommand \@@_Hdotsfor_i { O { }  m }
+%    \end{macrocode}
+% We don't put |!| before the last optionnal argument for homogeneity with
+% |\Cdots|, etc. which have only one optional argument.
+%    \begin{macrocode}
+    \NewDocumentCommand \@@_Hdotsfor_i { O { }  m O {  } }
       { \prg_replicate:nn { #2 - 1 } { & \multicolumn { 1 } { C } { } } } 
   }
   {
-    \NewDocumentCommand \@@_Hdotsfor_i { O { }  m }
+    \NewDocumentCommand \@@_Hdotsfor_i { O { } m O { } }
       {
         \tl_gput_right:Nx \g_@@_Hdotsfor_lines_tl
           {
-            \@@_Hdotsfor:nnn 
+            \@@_Hdotsfor:nnnn 
               { \int_use:N \c at iRow } 
               { \int_use:N \c at jCol } 
               { #2 }  
+              { #3 }
           }
         \prg_replicate:nn { #2 - 1 } { & \multicolumn { 1 } { C } { } }
       } 
@@ -6503,7 +6813,7 @@
 % 
 % \medskip
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_Hdotsfor:nnn #1 #2 #3
+\cs_new_protected:Npn \@@_Hdotsfor:nnnn #1 #2 #3 #4
   { 
     \bool_set_false:N \l_@@_initial_open_bool
     \bool_set_false:N \l_@@_final_open_bool
@@ -6511,7 +6821,7 @@
 % For the row, it's easy.
 %    \begin{macrocode}
     \int_set:Nn \l_@@_initial_i_int { #1 }
-    \int_set:Nn \l_@@_final_i_int { #1 }
+    \int_set_eq:NN \l_@@_final_i_int \l_@@_initial_i_int
 %    \end{macrocode}
 % For the column, it's a bit more complicated.
 %    \begin{macrocode}
@@ -6521,8 +6831,12 @@
         \bool_set_true:N \l_@@_initial_open_bool
       }
       {
-        \int_set:Nn \l_tmpa_int { #2 - 1 }
-        \@@_if_not_empty_cell:nnTF \l_@@_initial_i_int \l_tmpa_int
+        \cs_if_exist:cTF 
+          { 
+            pgf @ sh @ ns @ \@@_env: 
+            - \int_use:N \l_@@_initial_i_int
+            - \int_eval:n { #2 - 1 }
+          }
           { \int_set:Nn \l_@@_initial_j_int { #2 - 1 } }
           { 
             \int_set:Nn \l_@@_initial_j_int { #2 }
@@ -6535,8 +6849,12 @@
         \bool_set_true:N \l_@@_final_open_bool
       }
       {
-        \int_set:Nn \l_tmpa_int { #2 + #3 }
-        \@@_if_not_empty_cell:nnTF \l_@@_final_i_int \l_tmpa_int
+        \cs_if_exist:cTF 
+          { 
+            pgf @ sh @ ns @ \@@_env: 
+            - \int_use:N \l_@@_final_i_int
+            - \int_eval:n { #2 + #3 }
+          }
           { \int_set:Nn \l_@@_final_j_int { #2 + #3 } }
           { 
             \int_set:Nn \l_@@_final_j_int { #2 + #3 - 1 }
@@ -6543,21 +6861,19 @@
             \bool_set_true:N \l_@@_final_open_bool
           }
       }
-    \bool_if:nT { \l_@@_initial_open_bool || \l_@@_final_open_bool }
-      \@@_create_medium_nodes: 
 %    \end{macrocode}
 %
-% \medskip
-% The command |\@@_adjust_with_col_nodes:| is used in the command
-% |\@@_actually_draw_Ldots:| in order to recompute the $x$-value of
-% the initial point and the $x$-value of the final point with the exact position
-% of the left side and the right side of the array (these informations are in
-% the |col|-node. However, we don't want this operation with the dotted lines
-% drawn by |\Hdotsfor|. That's why we deactivate locally this command.
 %    \begin{macrocode}
     \group_begin:
-      \cs_set:Npn \@@_adjust_with_col_nodes: { }
-      \@@_actually_draw_Ldots:
+    \int_compare:nNnTF { #1 } = 0
+      { \color { nicematrix-first-row } }
+      { 
+        \int_compare:nNnT { #1 } = \g_@@_row_total_int
+          { \color { nicematrix-last-row } }
+      }
+    \keys_set:nn { NiceMatrix / xdots } { #4 }
+    \tl_if_empty:VF \l_@@_xdots_color_tl { \color { \l_@@_xdots_color_tl } }
+    \@@_actually_draw_Ldots:
     \group_end:
 %    \end{macrocode}
 %
@@ -6587,8 +6903,28 @@
 \cs_new_protected:Npn \@@_rotate: { \group_insert_after:N \@@_rotate_i: }
 \cs_new_protected:Npn \@@_rotate_i: { \group_insert_after:N \@@_rotate_ii: }
 \cs_new_protected:Npn \@@_rotate_ii: { \group_insert_after:N \@@_rotate_iii: } 
-\cs_new_protected:Npn \@@_rotate_iii: { \box_rotate:Nn \l_@@_cell_box { 90 } }
+\cs_new_protected:Npn \@@_rotate_iii: 
+  { 
+    \box_rotate:Nn \l_@@_cell_box { 90 } 
 %    \end{macrocode}
+% If we are in the last row, we want all the boxes composed with the command
+% |\rotate| aligned upwards.
+%    \begin{macrocode}
+    \int_compare:nNnT \c at iRow = \l_@@_last_row_int 
+      { 
+        \vbox_set_top:Nn \l_@@_cell_box 
+          { 
+            \vbox_to_zero:n { }
+%    \end{macrocode}
+% |0.8 ex| will be the distance between the principal part of the array and our
+% element (which is composed with |\rotate|.
+%    \begin{macrocode}
+            \skip_vertical:n { - \box_ht:N \@arstrutbox + 0.8 ex } 
+            \box_use:N \l_@@_cell_box 
+          } 
+      }
+  }
+%    \end{macrocode}
 %
 % \bigskip
 % \subsection*{The command \textbackslash line accessible in code-after}
@@ -6614,55 +6950,79 @@
 % construction uses the fact the |\@@_line_i:nn| is protected and that
 % |\@@_double_int_eval:n| is fully expandable).
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_line:nn #1 #2
+\NewDocumentCommand \@@_line { O { } m m ! O { } }
   {
-    \use:x
-      {
-        \@@_line_i:nn 
-          { \@@_double_int_eval:n #1 \q_stop }
-          { \@@_double_int_eval:n #2 \q_stop }
-      }
+    \group_begin:
+    \keys_set:nn { NiceMatrix / xdots } { #1 , #4 }
+    \tl_if_empty:VF \l_@@_xdots_color_tl { \color { \l_@@_xdots_color_tl } } 
+      \use:x
+        {
+          \@@_line_i:nn 
+            { \@@_double_int_eval:n #2 \q_stop }
+            { \@@_double_int_eval:n #3 \q_stop }
+        }
+    \group_end:
   }
 %    \end{macrocode}
 % 
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_line_i:nn #1 #2
+\bool_if:NTF \c_@@_draft_bool
+  { \cs_new_protected:Npn \@@_line_i:nn #1 #2  { } }
   {
-    \bool_if:NF \c_@@_draft_bool
+    \cs_new_protected:Npn \@@_line_i:nn #1 #2
       {
-        \dim_zero_new:N \g_@@_x_initial_dim
-        \dim_zero_new:N \g_@@_y_initial_dim
-        \dim_zero_new:N \g_@@_x_final_dim
-        \dim_zero_new:N \g_@@_y_final_dim
         \bool_set_false:N \l_@@_initial_open_bool
         \bool_set_false:N \l_@@_final_open_bool
         \bool_if:nTF
           {
-            \cs_if_exist_p:c { pgf at sh@ns at nm - \int_use:N \g_@@_env_int - #1 }  
-            && 
-            \cs_if_exist_p:c { pgf at sh@ns at nm - \int_use:N \g_@@_env_int - #2 } 
+            \cs_if_free_p:c { pgf @ sh @ ns @ \@@_env: - #1 }  
+              || 
+            \cs_if_free_p:c { pgf @ sh @ ns @ \@@_env: - #2 } 
           }
-          {
-            \begin { tikzpicture }
-              \path~(#1)~--~(#2)~node[at~start]~(i)~{}~node[at~end]~(f)~{} ;
-              \@@_extract_coords:w ( i )
-              \dim_gset:Nn \g_@@_x_initial_dim \pgf at x
-              \dim_gset:Nn \g_@@_y_initial_dim \pgf at y
-              \@@_extract_coords:w ( f )
-              \dim_gset:Nn \g_@@_x_final_dim \pgf at x
-              \dim_gset:Nn \g_@@_y_final_dim \pgf at y
-            \end { tikzpicture }  
-            \@@_draw_tikz_line:
-          }
           { 
-            \@@_error:nnn { unknown~cell~for~line~in~code-after } 
-              { #1 } { #2 }
-          }
+            \@@_error:nnn { unknown~cell~for~line~in~code-after } { #1 } { #2 }
+          } 
+          { \@@_draw_line_ii:nn { #1 } { #2 } }
       }
   }
 %    \end{macrocode}
+%
+%    \begin{macrocode}
+\AtBeginDocument
+  {
+    \cs_new_protected:Npx \@@_draw_line_ii:nn #1 #2
+      {
+%    \end{macrocode}
+% We recall that, when externalization is used, |\tikzpicture| and
+% |\endtikzpicture| (or |\pgfpicture| and |\endpgfpicture|) must be directly
+% ``visible'' and that why we do this static construction of the command
+% |\@@_draw_line_ii:|. 
+%    \begin{macrocode}
+        \c_@@_pgfortikzpicture_tl
+        \@@_draw_line_iii:nn { #1 } { #2 }
+        \c_@@_endpgfortikzpicture_tl
+      }
+  }
+%    \end{macrocode}
 % 
+% \bigskip
+% The following command \emph{must} be protected since it's used in the
+% construction of |\@@_draw_line_ii:nn|.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_draw_line_iii:nn #1 #2 
+  {
+    \pgfrememberpicturepositiononpagetrue
+    \pgfpointshapeborder { \@@_env: - #1 } { \@@_qpoint: { #2 } }
+    \dim_set_eq:NN \l_@@_x_initial_dim \pgf at x
+    \dim_set_eq:NN \l_@@_y_initial_dim \pgf at y
+    \pgfpointshapeborder { \@@_env: - #2 } { \@@_qpoint: { #1 } }
+    \dim_set_eq:NN \l_@@_x_final_dim \pgf at x
+    \dim_set_eq:NN \l_@@_y_final_dim \pgf at y
+    \@@_draw_line:
+  }
+%    \end{macrocode}
 % 
+% 
 % The commands |\Ldots|, |\Cdots|, |\Vdots|, |\Ddots|, and |\Iddots| don't use
 % this command because they have to do other settings (for example, the diagonal
 % lines must be parallelized). 
@@ -6762,6 +7122,98 @@
 %    \end{macrocode}
 %
 % \bigskip
+% The command |\@@_draw_vlines| will be executed when the user uses the option
+% |vlines| (which draws all the vlines of the array).
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_draw_vlines:
+  {
+    \group_begin:
+%    \end{macrocode}
+% The command |\CT at arc@| is a command of color from \pkg{colortbl}.
+%    \begin{macrocode}
+    \bool_if:NT \c_@@_colortbl_loaded_bool \CT at arc@
+    \pgfpicture 
+    \pgfrememberpicturepositiononpagetrue
+    \pgf at relevantforpicturesizefalse
+    \pgfsetlinewidth \arrayrulewidth 
+%    \end{macrocode}
+% First, we compute in |\l_tmpa_dim| the height of the rules we have to draw.
+%    \begin{macrocode}
+    \@@_qpoint: {row - 1 }
+    \dim_set_eq:NN \l_tmpa_dim \pgf at y
+    \pgfusepathqfill
+    \@@_qpoint: { row - \@@_succ:N \c at iRow } 
+    \dim_sub:Nn \l_tmpa_dim \pgf at y 
+    \pgfusepathqfill
+%    \end{macrocode}
+% We translate vertically to take into account the potential ``last row''. 
+%    \begin{macrocode}
+    \dim_zero:N \l_tmpb_dim
+    \int_compare:nNnT \l_@@_last_row_int > { -1 }
+      {
+        \dim_set_eq:NN \l_tmpb_dim \g_@@_dp_last_row_dim 
+        \dim_add:Nn \l_tmpb_dim \g_@@_ht_last_row_dim 
+%    \end{macrocode}
+% We adjust the value of |\l_tmpa_dim| by the width of the horizontal rule just 
+% before the ``last row''.
+%    \begin{macrocode}
+        \@@_qpoint: { row - \@@_succ:N\c at iRow } 
+        \dim_add:Nn \l_tmpa_dim \pgf at y
+        \@@_qpoint: { row - \@@_succ:N \g_@@_row_total_int } 
+        \dim_sub:Nn \l_tmpa_dim \pgf at y
+        \dim_sub:Nn \l_tmpa_dim \l_tmpb_dim
+       }
+%    \end{macrocode}
+%
+% Now, we can draw the lines with a loop. 
+%    \begin{macrocode}
+    \int_step_inline:nnn 
+      { \bool_if:NTF \l_@@_NiceArray_bool 1 2 } 
+      { \bool_if:NTF \l_@@_NiceArray_bool { \@@_succ:N \c at jCol } \c at jCol } 
+      {          
+        \pgfpathmoveto
+          {
+            \pgfpointadd
+              { \@@_qpoint: { col - ##1 } }
+              { 
+                \pgfpoint 
+                  { 
+                    -0.5 \arrayrulewidth 
+                    \int_compare:nNnT { ##1 } = 1
+                      { 
+                        \int_compare:nNnT \l_@@_first_col_int = 1
+                          { + \arrayrulewidth }
+                      }
+                  } 
+                  { \l_tmpb_dim } 
+              }
+          }
+        \pgfpathlineto
+          {
+            \pgfpointadd
+              { \@@_qpoint: { col - ##1 } }
+              { 
+                \pgfpoint 
+                  { 
+                    -0.5 \arrayrulewidth 
+                    \int_compare:nNnT { ##1 } = 1
+                      { 
+                        \int_compare:nNnT \l_@@_first_col_int = 1
+                          { + \arrayrulewidth }
+                      }
+                  } 
+                  { \l_tmpb_dim + \l_tmpa_dim } 
+              }
+          }
+      }
+    \pgfusepathqstroke
+    \endpgfpicture
+    \group_end:
+  }
+%    \end{macrocode}
+%
+%
+% \bigskip
 % \subsection*{The commands to draw dotted lines to separate columns and rows}
 %
 % These commands don't use the normal nodes, the medium nor the large nodes.
@@ -6773,11 +7225,12 @@
 % The following command must \emph{not} be protected because it's meant to be
 % expanded in a |\noalign|.
 %    \begin{macrocode}
-\cs_new:Npn \@@_hdottedline:
+\bool_if:NTF \c_@@_draft_bool
+  { \cs_new:Npn \@@_hdottedline: { } }
   {
-    \bool_if:NF \c_@@_draft_bool
+    \cs_new:Npn \@@_hdottedline: 
       {
-        \noalign{ \skip_vertical:n { 2 \l_@@_radius_dim } }
+        \noalign { \skip_vertical:N 2\l_@@_radius_dim } 
         \@@_hdottedline_i:
       }
   }
@@ -6791,9 +7244,9 @@
 %    \end{macrocode}
 % We write in the code-after the instruction that will eventually draw the
 % dotted line.  It's not possible to draw this dotted line now because we don't
-% known the length of the line (we don't even know the number of columns).
+% know the length of the line (we don't even know the number of columns).
 %    \begin{macrocode}
-    \tl_gput_right:Nx \g_@@_code_after_tl 
+    \tl_gput_right:Nx \g_@@_internal_code_after_tl
       { \@@_hdottedline:n { \int_use:N \c at iRow } } 
   }
 %    \end{macrocode}
@@ -6804,29 +7257,117 @@
 % that will actually draw the dotted line. Its argument is the number of the row
 % \emph{before} which we will draw the row.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_hdottedline:n #1
+\AtBeginDocument
   {
-    \dim_zero_new:N \g_@@_x_initial_dim
-    \dim_zero_new:N \g_@@_y_initial_dim
-    \dim_zero_new:N \g_@@_x_final_dim
-    \dim_zero_new:N \g_@@_y_final_dim
-    \bool_set_true:N \l_@@_initial_open_bool 
-    \bool_set_true:N \l_@@_final_open_bool 
-    \begin { tikzpicture } [ remember~picture ]
-      \@@_extract_coords:w ( row - #1 )
 %    \end{macrocode}
+% We recall that, when externalization is used, |\tikzpicture| and
+% |\endtikzpicture| (or |\pgfpicture| and |\endpgfpicture|) must be directly
+% ``visible''. 
+%    \begin{macrocode}
+    \cs_new_protected:Npx \@@_hdottedline:n #1
+      {
+        \bool_set_true:N \exp_not:N \l_@@_initial_open_bool 
+        \bool_set_true:N \exp_not:N \l_@@_final_open_bool 
+        \c_@@_pgfortikzpicture_tl
+        \@@_hdottedline_i:n { #1 }
+        \c_@@_endpgfortikzpicture_tl
+      }
+  }
+%    \end{macrocode}
+% 
+% The following command \emph{must} be protected since it is used in the
+% construction of |\@@_hdottedline:n|.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_hdottedline_i:n #1
+  {
+    \pgfrememberpicturepositiononpagetrue
+    \@@_qpoint: { row - #1 } 
+%    \end{macrocode}
 % We do a translation par |-\l_@@_radius_dim| because we want the dotted line to
 % have exactly the same position as a vertical rule drawn by ``"|"''
 % (considering the rule having a width equal to the diameter of the dots).
 %    \begin{macrocode}
-      \dim_gset:Nn \g_@@_y_initial_dim { \pgf at y - \l_@@_radius_dim }
-      \dim_gset:Nn \g_@@_y_final_dim { \pgf at y - \l_@@_radius_dim }
-      \@@_extract_coords:w ( col - 1 )
-      \dim_gset:Nn \g_@@_x_initial_dim \pgf at x
-      \@@_extract_coords:w ( col - \int_eval:n { \c at jCol + 1 } )
-      \dim_gset:Nn \g_@@_x_final_dim \pgf at x
-    \end { tikzpicture }
-    \@@_draw_tikz_line:
+    \dim_set_eq:NN \l_@@_y_initial_dim \pgf at y 
+    \dim_sub:Nn \l_@@_y_initial_dim \l_@@_radius_dim 
+    \dim_set_eq:NN \l_@@_y_final_dim \l_@@_y_initial_dim
+%    \end{macrocode}
+% 
+% \medskip
+% The dotted line will be extended if the user uses |margin| (or |left-margin|
+% and |right-margin|).
+%
+% \smallskip
+% The aim is that, by standard the dotted line fits between square brackets
+% (|\hline| doesn't).
+%
+% \smallskip
+% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
+% \begin{bNiceMatrix}
+% 1 & 2 & 3 & 4 \\
+% \hline 
+% 1 & 2 & 3 & 4 \\
+% \hdottedline 
+% 1 & 2 & 3 & 4 \\
+% \end{bNiceMatrix}
+% \end{BVerbatim}
+% $\begin{bNiceMatrix}
+% 1 & 2 & 3 & 4 \\
+% \hline 
+% 1 & 2 & 3 & 4 \\
+% \hdottedline 
+% 1 & 2 & 3 & 4 \\
+% \end{bNiceMatrix}$
+%
+% \smallskip
+% But, if the user uses |margin|, the dotted line extends to have the same width
+% as a |\hline|.
+% 
+% \smallskip
+% \begin{BVerbatim}[baseline=c,boxwidth=10cm]
+% \begin{bNiceMatrix}[margin]
+% 1 & 2 & 3 & 4 \\
+% \hline 
+% 1 & 2 & 3 & 4 \\
+% \hdottedline 
+% 1 & 2 & 3 & 4 \\
+% \end{bNiceMatrix}
+% \end{BVerbatim}
+% $\begin{bNiceMatrix}[margin]
+% 1 & 2 & 3 & 4 \\
+% \hline 
+% 1 & 2 & 3 & 4 \\
+% \hdottedline 
+% 1 & 2 & 3 & 4 \\
+% \end{bNiceMatrix}$
+%
+% \medskip
+%    \begin{macrocode}
+    \@@_qpoint: { col - 1 } 
+    \dim_set:Nn \l_@@_x_initial_dim 
+      { \pgf at x + \arraycolsep - \l_@@_left_margin_dim } 
+    \@@_qpoint: { col - \@@_succ:N \c at jCol } 
+    \dim_set:Nn \l_@@_x_final_dim 
+      { \pgf at x - \arraycolsep + \l_@@_right_margin_dim }
+%    \end{macrocode}
+% For reasons purely aesthetic, we do an adjustment in the case of a rounded
+% bracket. The correction by |0.5 \l_@@_inter_dots_dim| is \emph{ad hoc} for a
+% better result.
+%    \begin{macrocode}
+    \tl_set:Nn \l_tmpa_tl { ( }
+    \tl_if_eq:NNF \l_@@_left_delim_tl \l_tmpa_tl
+      { \dim_gadd:Nn \l_@@_x_initial_dim  { 0.5 \l_@@_inter_dots_dim } }
+    \tl_set:Nn \l_tmpa_tl { ) }
+    \tl_if_eq:NNF \l_@@_right_delim_tl \l_tmpa_tl
+      { \dim_gsub:Nn \l_@@_x_final_dim { 0.5 \l_@@_inter_dots_dim } }
+%    \end{macrocode}
+%
+% \medskip
+% As for now, we have no option to control the style of the lines drawn by
+% |\hdottedline| and the specifier ``|:|'' in the preamble. That's why we impose
+% the style |standard|.
+%    \begin{macrocode}
+    \tl_set_eq:NN \l_@@_xdots_line_style_tl \c_@@_standard_tl
+    \@@_draw_line:
   }
 %    \end{macrocode}
 %
@@ -6835,17 +7376,33 @@
 % \bigskip
 % \textbf{Vertical dotted lines}\par\nobreak
 %
+%
 % \medskip
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_vdottedline:n #1
+\bool_if:nTF \c_@@_draft_bool
+  { \cs_new_protected:Npn \@@_vdottedline:n #1 { } }
   {
+    \cs_new_protected:Npn \@@_vdottedline:n #1
+      {
+        \bool_set_true:N \l_@@_initial_open_bool 
+        \bool_set_true:N \l_@@_final_open_bool 
 %    \end{macrocode}
-% We should allow the letter ``|:|'' in the first position of the preamble 
-% but that would need a special programmation.
+% We recall that, when externalization is used, |\tikzpicture| and
+% |\endtikzpicture| (or |\pgfpicture| and |\endpgfpicture|) must be directly
+% ``visible''. 
 %    \begin{macrocode}
-    \int_compare:nNnTF #1 = 0
-      { \@@_error:n { Use~of~:~in~first~position } }
-      { \bool_if:NF \c_@@_draft_bool { \@@_vdottedline_i:n { #1 } } }
+        \bool_if:NTF \c_@@_tikz_loaded_bool
+          {
+            \tikzpicture
+            \@@_vdottedline_i:n { #1 }
+            \endtikzpicture
+          }
+          {
+            \pgfpicture
+            \@@_vdottedline_i:n { #1 }
+            \endpgfpicture
+          }
+      }
   }
 %    \end{macrocode}
 %
@@ -6853,31 +7410,34 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_vdottedline_i:n #1
   {
-    \dim_zero_new:N \g_@@_x_initial_dim
-    \dim_zero_new:N \g_@@_y_initial_dim
-    \dim_zero_new:N \g_@@_x_final_dim
-    \dim_zero_new:N \g_@@_y_final_dim
-    \bool_set_true:N \l_@@_initial_open_bool 
-    \bool_set_true:N \l_@@_final_open_bool 
-    \begin { tikzpicture } [ remember~picture ]
-      \@@_extract_coords:w ( col - \int_eval:n { #1 + 1 } )
 %    \end{macrocode}
+% The command |\CT at arc@| is a command of color from \pkg{colortbl}.
+%    \begin{macrocode}
+    \bool_if:NT \c_@@_colortbl_loaded_bool \CT at arc@
+    \pgfrememberpicturepositiononpagetrue
+    \@@_qpoint: { col - \int_eval:n { #1 + 1 } } 
+%    \end{macrocode}
 % We do a translation par |-\l_@@_radius_dim| because we want the dotted line to
 % have exactly the same position as a vertical rule drawn by ``"|"''
 % (considering the rule having a width equal to the diameter of the dots).
 %    \begin{macrocode}
-      \dim_gset:Nn \g_@@_x_initial_dim { \pgf at x - \l_@@_radius_dim }
-      \dim_gset:Nn \g_@@_x_final_dim { \pgf at x - \l_@@_radius_dim }
-      \@@_extract_coords:w ( row - 1 )
+    \dim_set:Nn \l_@@_x_initial_dim { \pgf at x - \l_@@_radius_dim }
+    \dim_set:Nn \l_@@_x_final_dim { \pgf at x - \l_@@_radius_dim }
+    \@@_qpoint: { row - 1 } 
 %    \end{macrocode}
 % We arbitrary decrease the height of the dotted line by a quantity equal to
 % |\l_@@_inter_dots_dim| in order to improve the visual impact.
 %    \begin{macrocode}
-      \dim_gset:Nn \g_@@_y_initial_dim { \pgf at y - ( \l_@@_inter_dots_dim / 2 ) }  
-      \@@_extract_coords:w ( row - \int_eval:n { \c at iRow + 1 } )
-      \dim_gset:Nn \g_@@_y_final_dim { \pgf at y + ( \l_@@_inter_dots_dim / 2 ) } 
-    \end { tikzpicture }
-    \@@_draw_tikz_line:
+    \dim_set:Nn \l_@@_y_initial_dim { \pgf at y - 0.5 \l_@@_inter_dots_dim }  
+    \@@_qpoint: { row - \@@_succ:N \c at iRow } 
+    \dim_set:Nn \l_@@_y_final_dim { \pgf at y + 0.5 \l_@@_inter_dots_dim } 
+%    \end{macrocode}
+% As for now, we have no option to control the style of the lines drawn by
+% |\hdottedline| and the specifier ``|:|'' in the preamble. That's why we impose
+% the style |standard|.
+%    \begin{macrocode}
+    \tl_set_eq:NN \l_@@_xdots_line_style_tl \c_@@_standard_tl
+    \@@_draw_line:
   }
 %    \end{macrocode}
 % 
@@ -6918,8 +7478,8 @@
       {
         \cs_if_exist:cT { @@_max_cell_width_ \int_use:N \g_@@_NiceMatrixBlock_int }
           {
-            \dim_set:Nx \l_@@_columns_width_dim
-              { \use:c { @@_max_cell_width _ \int_use:N \g_@@_NiceMatrixBlock_int } }
+            \exp_args:NNc \dim_set:Nn \l_@@_columns_width_dim
+              { @@_max_cell_width _ \int_use:N \g_@@_NiceMatrixBlock_int } 
           } 
       }
   }
@@ -6939,7 +7499,11 @@
           { 
             \cs_gset:cpn 
               { @@ _ max _ cell _ width _ \int_use:N \g_@@_NiceMatrixBlock_int } 
-              { \dim_use:N \g_@@_max_cell_width_dim }
+%    \end{macrocode}
+% For technical reasons, we have to include the width of an eventual rule on the
+% right side of the cells.
+%    \begin{macrocode}
+              { \dim_eval:n { \g_@@_max_cell_width_dim + \arrayrulewidth } }
           }
         \iow_now:Nn \@mainaux \ExplSyntaxOff
       }
@@ -6957,10 +7521,9 @@
 %
 % \bigskip
 % We have three macros of creation of nodes: |\@@_create_medium_nodes:|,
-% |\@@_create_large_nodes:| and |\@@_create_medium_and_large_nodes:|. They must
-% \emph{not} be used in the |code-after| because the |code-after| is executed in
-% a scope of |prefix name| of Tikz.
+% |\@@_create_large_nodes:| and |\@@_create_medium_and_large_nodes:|. 
 %
+%
 % \bigskip
 % We have to compute the mathematical coordinates of the ``medium nodes''. These
 % mathematical coordinates are also used to compute the mathematical coordinates
@@ -6969,7 +7532,7 @@
 % 
 % \bigskip
 % The command |\@@_computations_for_medium_nodes:| must be used in a
-% |{tikzpicture}|. 
+% |{pgfpicture}|.
 %
 % \medskip
 % For each row $i$, we compute two dimensions
@@ -7019,15 +7582,15 @@
 %    \begin{macrocode}
           { 
             \cs_if_exist:cT 
-              { pgf at sh@ns at nm - \int_use:N \g_@@_env_int - \@@_i: - \@@_j: }
+              { pgf @ sh @ ns @ \@@_env: - \@@_i: - \@@_j: }
 %    \end{macrocode}
 % We retrieve the coordinates of the anchor |south west| of the (normal) node of
 % the cell ($i$-$j$). They will be stored in |\pgf at x| and |\pgf at y|.
 %    \begin{macrocode}
               {
-                \@@_extract_coords:w 
-                  ( nm - \int_use:N \g_@@_env_int 
-                       - \@@_i: - \@@_j: .south~west )
+                \pgfpointanchor
+                  { \@@_env: - \@@_i: - \@@_j: } 
+                  { south~west }
                 \dim_set:cn { l_@@_row_\@@_i: _min_dim}
                   { \dim_min:vn { l_@@_row _ \@@_i: _min_dim } \pgf at y }  
                 \seq_if_in:NxF \g_@@_multicolumn_cells_seq { \@@_i: - \@@_j: }
@@ -7039,8 +7602,9 @@
 % We retrieve the coordinates of the anchor |north east| of the (normal) node of
 % the cell ($i$-$j$). They will be stored in |\pgf at x| and |\pgf at y|.
 %    \begin{macrocode}
-                \@@_extract_coords:w 
-                  ( nm - \int_use:N \g_@@_env_int - \@@_i: - \@@_j: .north~east )
+                \pgfpointanchor
+                  { \@@_env: - \@@_i: - \@@_j: } 
+                  { north~east }
                 \dim_set:cn { l_@@_row _ \@@_i: _ max_dim }
                   { \dim_max:vn { l_@@_row _ \@@_i: _ max_dim } \pgf at y }
                 \seq_if_in:NxF \g_@@_multicolumn_cells_seq { \@@_i: - \@@_j: }
@@ -7057,25 +7621,22 @@
 %
 % \bigskip
 % Here is the command |\@@_create_medium_nodes:|. When this command is used, the
-% ``medium nodes'' are created. These nodes won't be constructed twice because
-% when used once, this command becomes no-op.
+% ``medium nodes'' are created. 
 %
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_create_medium_nodes:
   {
-    \begin { tikzpicture } [ remember~picture , overlay ]
+    \pgfpicture
+      \pgfrememberpicturepositiononpagetrue
+      \pgf at relevantforpicturesizefalse
       \@@_computations_for_medium_nodes:
-      \tikzset { name~suffix = -medium }
 %    \end{macrocode}
 % Now, we can create the ``medium nodes''. We use a command |\@@_create_nodes:|
-% because this command will also be used for the creation of the ``large nodes''
-% (after changing the value of |name-suffix|). 
+% because this command will also be used for the creation of the ``large nodes''.
 %    \begin{macrocode} 
+      \tl_set:Nn \l_@@_suffix_tl { -medium }
       \@@_create_nodes:
-      \end { tikzpicture }
-    \cs_set_protected:Npn \@@_create_medium_nodes: { }
-    \cs_set_protected:Npn \@@_create_medium_and_large_nodes: 
-      { \@@_create_large_nodes: }
+      \endpgfpicture
   }
 %    \end{macrocode}
 % 
@@ -7091,15 +7652,14 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_create_large_nodes:
   {
-    \begin { tikzpicture } [ remember~picture , overlay ]
+    \pgfpicture 
+      \pgfrememberpicturepositiononpagetrue
+      \pgf at relevantforpicturesizefalse
       \@@_computations_for_medium_nodes:
       \@@_computations_for_large_nodes:
-      \tikzset { name~suffix = -large }
+      \tl_set:Nn \l_@@_suffix_tl { - large }
       \@@_create_nodes:
-    \end { tikzpicture }
-    \cs_set_protected:Npn \@@_create_large_nodes: { }
-    \cs_set_protected:Npn \@@_create_medium_and_large_nodes: 
-      { \@@_create_medium_nodes: }
+    \endpgfpicture
   }
 %    \end{macrocode}
 %
@@ -7106,22 +7666,20 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_create_medium_and_large_nodes:
   {
-    \begin { tikzpicture } [ remember~picture , overlay ]
+    \pgfpicture 
+      \pgfrememberpicturepositiononpagetrue
+      \pgf at relevantforpicturesizefalse
       \@@_computations_for_medium_nodes:
 %    \end{macrocode}
 % Now, we can create the ``medium nodes''. We use a command |\@@_create_nodes:|
-% because this command will also be used for the creation of the ``large nodes''
-% (after changing the value of |name-suffix|). 
+% because this command will also be used for the creation of the ``large nodes''.
 %    \begin{macrocode} 
-      \tikzset { name~suffix = -medium }
+      \tl_set:Nn \l_@@_suffix_tl { - medium }
       \@@_create_nodes:
       \@@_computations_for_large_nodes:
-      \tikzset { name~suffix = -large }
-      \@@_create_nodes:
-    \end { tikzpicture }
-    \cs_set_protected:Npn \@@_create_medium_and_large_nodes: { }
-    \cs_set_protected:Npn \@@_create_medium_nodes: { }
-    \cs_set_protected:Npn \@@_create_large_nodes: { }
+      \tl_set:Nn \l_@@_suffix_tl { - large }
+      \@@_create_nodes: 
+    \endpgfpicture
   }
 %    \end{macrocode}
 %
@@ -7169,12 +7727,15 @@
         \dim_set_eq:cc { l_@@_column _ \int_eval:n { \@@_j: + 1 } _ min _ dim }
           { l_@@_column _ \@@_j: _ max _ dim } 
       }
+%     \end{macrocode}
+% Here, we have to use |\dim_sub:cn| because of the number 1 in the name.
+%     \begin{macrocode}
     \dim_sub:cn 
       { l_@@_column _ 1 _ min _ dim } 
       \l_@@_left_margin_dim
     \dim_add:cn 
-      { l_@@_column _ \int_use:N \c at jCol _ max _ dim } 
-      \l_@@_right_margin_dim
+      { l_@@_column _ \int_use:N \c at jCol _ max _ dim }
+      \l_@@_right_margin_dim  
   }
 %    \end{macrocode}
 %
@@ -7189,6 +7750,8 @@
 % \texttt{l_@@_column_\textsl{j}_max_dim}. Between the construction of the
 % ``medium nodes'' and the ``large nodes'', the values of these dimensions are
 % changed. 
+%
+% The function also uses |\l_@@_suffix_tl| (|-medium| or |-large|).
 %     \begin{macrocode}
 \cs_new_protected:Npn \@@_create_nodes:
   { 
@@ -7195,36 +7758,22 @@
     \int_step_variable:nnNn \l_@@_first_row_int \g_@@_row_total_int \@@_i:
       { 
         \int_step_variable:nnNn \l_@@_first_col_int \g_@@_col_total_int \@@_j:
-%    \end{macrocode}
-% We create two ponctual nodes for the extremities of a diagonal of the
-% rectangular node we want to create. These nodes |(@@~south~west)| and
-% |(@@~north~east)| are not available for the user of \pkg{nicematrix}. That's
-% why their names are independent of the row and the column. In the two nested
-% loops, they will be overwritten until the last cell.
-%    \begin{macrocode}
           {
-            \coordinate ( @@~south~west ) 
-               at ( \dim_use:c { l_@@_column_ \@@_j: _min_dim } ,
-                    \dim_use:c { l_@@_row_ \@@_i: _min_dim } ) ; 
-            \coordinate ( @@~north~east ) 
-               at ( \dim_use:c { l_@@_column_ \@@_j: _max_dim } ,
-                    \dim_use:c { l_@@_row_ \@@_i: _max_dim } ) ; 
 %    \end{macrocode}
-% We can eventually draw the rectangular node for the cell (|\@@_i|-|\@@_j|).
-% This node is created with the Tikz library \pkg{fit}. Don't forget that the
-% Tikz option |name suffix| has been set to |-medium| or |-large|. 
+% We draw the rectangular node for the cell (|\@@_i|-|\@@_j|).
 %    \begin{macrocode}
-            \node
-              [ 
-                node~contents = { } ,
-                fit = ( @@~south~west ) ( @@~north~east )  ,
-                inner~sep = \c_zero_dim ,
-                name = nm - \int_use:N \g_@@_env_int - \@@_i: - \@@_j: ,
-                alias = 
-                  \str_if_empty:NF \l_@@_name_str 
-                    { \l_@@_name_str - \@@_i: - \@@_j: }
-              ] 
-              ; 
+            \@@_pgf_rect_node:nnnnn
+              { \@@_env: - \@@_i: - \@@_j: \l_@@_suffix_tl } 
+              { \dim_use:c { l_@@_column_ \@@_j: _min_dim } }
+              { \dim_use:c { l_@@_row_ \@@_i: _min_dim } }
+              { \dim_use:c { l_@@_column_ \@@_j: _max_dim } }
+              { \dim_use:c { l_@@_row_ \@@_i: _max_dim } }
+            \str_if_empty:NF \l_@@_name_str
+              {
+                \pgfnodealias
+                  { \l_@@_name_str - \@@_i: - \@@_j: \l_@@_suffix_tl }
+                  { \@@_env: - \@@_i: - \@@_j: \l_@@_suffix_tl }
+              }
           }
       }
 %    \end{macrocode}
@@ -7258,27 +7807,18 @@
 \cs_new_protected:Npn \@@_node_for_multicolumn:nn #1 #2
   { 
     \@@_extract_coords_values: #1 \q_stop
-    \coordinate ( @@~south~west ) at
-      (
-        \dim_use:c { l_@@_column _ \@@_j: _ min _ dim } ,
-        \dim_use:c { l_@@_row _ \@@_i: _ min _ dim } 
-      ) ; 
-    \coordinate ( @@~north~east ) at
-      ( 
-        \dim_use:c { l_@@_column _ \int_eval:n { \@@_j: + #2 - 1 } _ max _ dim} ,
-        \dim_use:c { l_@@_row _ \@@_i: _ max _ dim } 
-      ) ; 
-    \node 
-      [ 
-        node~contents = { } ,
-        fit = ( @@~south~west ) ( @@~north~east ) ,
-        inner~sep = \c_zero_dim ,
-        name = nm - \int_use:N \g_@@_env_int - \@@_i: - \@@_j: ,
-        alias = 
-          \str_if_empty:NF \l_@@_name_str 
-            { \l_@@_name_str - \@@_i: - \@@_j: }
-      ] 
-      ; 
+    \@@_pgf_rect_node:nnnnn
+      { \@@_env: - \@@_i: - \@@_j: \l_@@_suffix_tl }
+      { \dim_use:c { l_@@_column _ \@@_j: _ min _ dim } }
+      { \dim_use:c { l_@@_row _ \@@_i: _ min _ dim } }
+      { \dim_use:c { l_@@_column _ \int_eval:n { \@@_j: +#2-1 } _ max _ dim } }  
+      { \dim_use:c { l_@@_row _ \@@_i: _ max _ dim } }
+    \str_if_empty:NF \l_@@_name_str
+      {
+        \pgfnodealias
+          { \l_@@_name_str - \@@_i: - \@@_j: \l_@@_suffix_tl }
+          { \int_use:N \g_@@_env_int - \@@_i: - \@@_j: \l_@@_suffix_tl}
+      }
   }
 %    \end{macrocode}
 %
@@ -7322,7 +7862,7 @@
 % 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
+    \tl_gput_left:Nx \g_@@_internal_code_after_tl
       {
         \@@_Block_iii:nnnnnn
           { \int_use:N \c at iRow }
@@ -7390,70 +7930,77 @@
 %    \end{macrocode}
 %
 % \medskip
-% The construction of the node corresponding to the merged cells. First, we
-% construct |\coordinate| corresponding to the upper-left and the lower-right
-% corners of the cell. They are called |one| and |two|.
+% The construction of the node corresponding to the merged cells.
 %    \begin{macrocode}
-        \begin { tikzpicture }   
-          \int_set:Nn \l_tmpa_int { #1 }
-          \int_decr:N \l_tmpa_int
-          \int_set:Nn \l_tmpb_int { #2 }
-          \int_decr:N \l_tmpb_int 
-          \@@_extract_coords:w ( row - \int_eval:n { \l_tmpa_int + 1 } )
+        \pgfpicture 
+          \pgfrememberpicturepositiononpagetrue
+          \pgf at relevantforpicturesizefalse
+          \@@_qpoint: { row - #1 } 
           \dim_set_eq:NN \l_tmpa_dim \pgf at y
-          \@@_extract_coords:w ( col - \int_eval:n { \l_tmpb_int + 1 } )
+          \@@_qpoint: { col - #2 } 
           \dim_set_eq:NN \l_tmpb_dim \pgf at x
-          \coordinate ( one ) at ( \l_tmpb_dim , \l_tmpa_dim ) ;
-          \@@_extract_coords:w ( row - \int_eval:n { #3 + 1 } )
-          \dim_set_eq:NN \l_tmpa_dim \pgf at y
-          \@@_extract_coords:w ( col - \int_eval:n { #4 + 1 } )
-          \dim_set_eq:NN \l_tmpb_dim \pgf at x
-          \coordinate ( two ) at ( \l_tmpb_dim , \l_tmpa_dim ) ;
+          \@@_qpoint: { row - \@@_succ:N #3 } 
+          \dim_set_eq:NN \l_tmpc_dim \pgf at y
+          \@@_qpoint: { col - \@@_succ:N #4 } 
+          \dim_set_eq:NN \l_tmpd_dim \pgf at x
 %    \end{macrocode}
-%
+% 
+% \medskip
+% The following code doesn't work for the first vertical rule. You should allow
+% the option |white| if and only if the option |vlines| and |hlines| has been used.
 %    \begin{macrocode}
           \bool_if:NT \l_@@_white_bool
             {
-              \fill [ white , line~width = 0 pt] 
-                ( [ yshift = -\arrayrulewidth ] one ) 
-                rectangle 
-                ( [ xshift = -\arrayrulewidth ] two ) ; 
+              \begin { pgfscope }
+              \pgfsetfillcolor { white }
+%    \end{macrocode}
+% Usually, the vertical rules are \emph{before} the |col|-nodes. But there is an
+% exception: if there is no ``first col'', the first vertical rule is after the
+% col node.\footnote{That's true for the vertical rules drawn by ``"|"'' due to
+% the conception of |{array}| (of \pkg{array}) and we have managed to have the
+% same behaviour with |vlines|.}
+% 
+% Since we don't want the white rectangle to erase a part of this
+% first rule, we have to do an adjustment in this case.
+% \emph{after} the ``col node''. 
+%    \begin{macrocode}
+              \int_compare:nNnT { #2 } = 1
+                { 
+                  \int_compare:nNnT \l_@@_first_col_int = 1 
+                    { \dim_add:Nn \l_tmpb_dim \arrayrulewidth }
+                }
+              \pgfpathrectanglecorners 
+                { \pgfpoint \l_tmpb_dim { \l_tmpa_dim - \arrayrulewidth } } 
+                { \pgfpoint { \l_tmpd_dim - \arrayrulewidth } \l_tmpc_dim }
+              \pgfusepathqfill
+              \end { pgfscope }
             }
 %    \end{macrocode}
 %
-% Now, we can construct the real node fitting the nodes |one| and |two|.
-% We have to insert |\l_@@_tikz_tl| in the list of the options and that's why we
-% use |\use:x|.
+% We construct the node for the block with the name |(#1-#2-block)|.
+% The function |\@@_pgf_rect_node:nnnnn| takes as arguments the name of the node
+% and the four coordinates of two opposite corner points of the rectangle.
 %    \begin{macrocode}
-          \use:x 
-            { 
-              \exp_not:N \node 
-                [ 
-                  fit = ( one ) ( two ) ,
-                  inner~sep = 0 pt ,
-                  \l_@@_tikz_tl
-                ] 
-            }  
+          \begin { pgfscope }
+          \exp_args:Nx \pgfset { \l_@@_tikz_tl }
+          \@@_pgf_rect_node:nnnnn
+            { \@@_env: - #1 - #2 - block }
+            \l_tmpb_dim \l_tmpa_dim \l_tmpd_dim \l_tmpc_dim 
+          \end { pgfscope }
 %    \end{macrocode}
-% The node of the block has a name |(#1-#2-block)| and we will use it internally just
-% after to put the label of the block.
-%    \begin{macrocode}
-            (#1-#2-block) { } ;
-%    \end{macrocode}
+%
 % 
 % \medskip
 % If the creation of the ``medium nodes'' is required, we create a ``medium
-% node'' for the block. 
+% node'' for the block. The function |\@@_pgf_rect_node:nnnnn| takes as
+% arguments the name of the node and two \textsc{pgf} points.
 %    \begin{macrocode}
         \bool_if:NT \l_@@_medium_nodes_bool
           {
-            \node
-              [
-                fit = ( #1 - #2 - medium . north~west )
-                      ( #3 - #4 - medium . south~east ) ,
-                inner~sep = 0 pt ,
-              ]
-              (#1-#2-block-medium) { } ;
+            \@@_pgf_rect_node:nnn
+              { \@@_env: - #1 - #2 - block - medium }
+              { \pgfpointanchor { \@@_env: - #1 - #2 - medium } { north~west } }
+              { \pgfpointanchor { \@@_env: - #3 - #4 - medium } { south~east } } 
           }
 %    \end{macrocode}
 % \medskip
@@ -7464,20 +8011,20 @@
 %    \end{macrocode}
 % If the block has only one row, we want the label of the block perfectly
 % aligned on the baseline of the row. That's why we have constructed a
-% |\coordinate| on the baseline of the row, in the first column of the array.
+% |\pgfcoordinate| on the baseline of the row, in the first column of the array.
 % Now, we retrieve the $y$-value of that node and we store it in |\l_tmpa_dim|.
 %    \begin{macrocode}
-              \@@_extract_coords:w (row-#1-base) 
-              \dim_set_eq:NN \l_tmpa_dim \pgf at y
+            \pgfextracty \l_tmpa_dim { \@@_qpoint: { row - #1 - base } }
 %    \end{macrocode}
 % We retrieve (in |\pgf at x|) the $x$-value of the center of the block.
 %    \begin{macrocode}
-              \@@_extract_coords:w (#1-#2-block) 
+            \@@_qpoint: { #1 - #2 - block } 
 %    \end{macrocode}
 % We put the label of the block which has been composed in |\l_@@_cell_box|.
 %    \begin{macrocode}
-              \path (\pgf at x,\l_tmpa_dim) node [ anchor = base ] 
-                { \box_use_drop:N \l_@@_cell_box } ; 
+            \pgftransformshift { \pgfpoint \pgf at x \l_tmpa_dim }
+            \pgfnode { rectangle } { base } 
+              { \box_use_drop:N \l_@@_cell_box } { } { }
           }
 %    \end{macrocode}
 %
@@ -7486,8 +8033,12 @@
 % the center of the node (the label of the block has been composed in
 % |\l_@@_cell_box|). 
 %    \begin{macrocode}
-          { \node at (#1-#2-block.center) { \box_use_drop:N \l_@@_cell_box } ; }   
-        \end { tikzpicture }
+          { 
+            \pgftransformshift { \@@_qpoint: { #1 - #2 - block } }
+            \pgfnode { rectangle } { center } 
+              { \box_use_drop:N \l_@@_cell_box } { } { }
+          }   
+        \endpgfpicture
       }
     \group_end:
   }
@@ -7607,7 +8158,12 @@
     transparent .meta:n = { renew-dots , renew-matrix } ,
     transparent .value_forbidden:n = true,
     obsolete-environments .code:n = 
-      \@@_msg_redirect_name:nn { Obsolete~environment } { none }
+      \@@_msg_redirect_name:nn { Obsolete~environment } { none } ,
+        obsolete-environments .value_forbidden:n = true,
+    starred-commands .code:n = 
+      \@@_msg_redirect_name:nn { starred~commands } { none } ,
+    starred-commands .value_forbidden:n = true ,
+
   }
 \ProcessKeysOptions { NiceMatrix / Package }
 %    \end{macrocode}
@@ -7665,43 +8221,87 @@
   }
 %    \end{macrocode}
 % 
+% The following command must \emph{not} be protected since it's used in an error message.
+%    \begin{macrocode}
+\cs_new:Npn \@@_message_hdotsfor:
+  {
+    \tl_if_empty:VF \g_@@_Hdotsfor_lines_tl
+     { ~Maybe~your~use~of~\token_to_str:N \Hdotsfor\ is~incorrect.}
+  }
+%    \end{macrocode}
 % 
+%
 %    \begin{macrocode}
 \@@_msg_new:nn { too~much~cols~for~matrix~with~last~col }
   { 
     You~try~to~use~more~columns~than~allowed~by~your~
-    \@@_full_name_env:.~The~maximal~number~of~columns~is~ 
-    \int_eval:n { \l_@@_last_col_int - 1 }~(plus~the~potential~
+    \@@_full_name_env:.\@@_message_hdotsfor:\ The~maximal~number~of~
+    columns~is~\int_eval:n { \l_@@_last_col_int - 1 }~(plus~the~potential~
     exterior~ones).~This~error~is~fatal. 
   }
 %    \end{macrocode}
 % 
-%
+% 
 %    \begin{macrocode}
 \@@_msg_new:nn { too~much~cols~for~matrix }
   { 
     You~try~to~use~more~columns~than~allowed~by~your~
-    \@@_full_name_env:.~ Recall~that~the~maximal~number~of~columns~
-    for~a~matrix~is~fixed~by~the~LaTeX~counter~'MaxMatrixCols'.~ 
-    Its~actual~value~is~\int_use:N \c at MaxMatrixCols.~This~error~is~fatal.  
+    \@@_full_name_env:.\@@_message_hdotsfor:\ Recall~that~the~maximal~
+    number~of~columns~for~a~matrix~is~fixed~by~the~LaTeX~counter~
+    'MaxMatrixCols'.~Its~actual~value~is~\int_use:N \c at MaxMatrixCols.~
+    This~error~is~fatal.  
   }
 %    \end{macrocode}
 %
+% \medskip
+% For the following message, remind that the test is not done after the
+% construction of the array but in each row. That's why we have to put
+% |\c at jCol-1| and not |\c at jCol|.
 %    \begin{macrocode}
 \@@_msg_new:nn { too~much~cols~for~array }
   { 
     You~try~to~use~more~columns~than~allowed~by~your~
-    \@@_full_name_env:.~The~maximal~number~of~columns~is~ 
-    \int_use:N \c at jCol\space (plus~the~potential~exterior~ones).~
+    \@@_full_name_env:.\@@_message_hdotsfor:\ The~maximal~number~of~columns~is~ 
+    \int_eval:n { \c at jCol - 1 }~(plus~the~potential~exterior~ones).~
     This~error~is~fatal.
   }
 %    \end{macrocode}
 %
+%  
+%    \begin{macrocode}  
+\@@_msg_new:nn { bad~option~for~line-style }
+  {
+    Since~you~haven't~loaded~Tikz,~the~only~value~you~can~give~to~'line-style'~
+    is~'standard'.~If~you~go~on,~this~option~will~be~ignored.
+  }
+%    \end{macrocode}
+%
 %    \begin{macrocode}
+\@@_msg_new:nn { Unknown~option~for~xdots } 
+  {
+    As~for~now~there~is~only~three~options~available~here:~'color',~'line-style'~
+    and~'shorten'~(and~you~try~to~use~'\l_keys_key_str').~If~you~go~on,~
+    this~option~will~be~ignored.
+  }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\@@_msg_new:nn { starred~commands }
+  {
+    The~starred~versions~of~\token_to_str:N \Cdots,~\token_to_str:N \Ldots,~
+    \token_to_str:N \Vdots,~\token_to_str:N\Ddots\ and~\token_to_str:N\Iddots\ 
+    are~deprecated.~However,~you~can~go~on~for~this~time.~If~you~don't~want~to~
+    see~this~error~we~should~load~'nicematrix'~with~the~option~
+    'starred-commands'.
+  }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \@@_msg_new:nn { bad~value~for~baseline }
   {
-    The~value~you~gave~to~'baseline'~(\int_use:N \l_tmpa_int)~is~not~
-    valid.\\
+    The~value~given~to~'baseline'~(\int_use:N \l_tmpa_int)~is~not~
+    valid.~The~value~must~be~between~\int_use:N \l_@@_first_row_int\ and~
+    \int_use:N \g_@@_row_total_int\ or~equal~to~'t',~'c'~or~'b'.\\
     If~you~go~on,~a~value~of~1~will~be~used.
   }
 %    \end{macrocode}
@@ -7724,7 +8324,7 @@
 \@@_msg_new:nn { unknown~cell~for~line~in~code-after }
   {
     Your~command~\token_to_str:N\line\{#1\}\{#2\}~in~the~'code-after'~
-    can't~be~executed~because~a~Tikz~node~doesn't~exist.\\
+    can't~be~executed~because~a~cell~doesn't~exist.\\
     If~you~go~on~this~command~will~be~ignored.
   }
 %    \end{macrocode}
@@ -7760,15 +8360,6 @@
 %
 % 
 %    \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 \l_@@_last_row_int'~but~your~
@@ -7824,7 +8415,6 @@
     create-extra-nodes,~
     create-medium-nodes,~
     create-large-nodes,~
-    dotted-lines-margin,~
     end-of-row,~
     exterior-arraycolsep,~
     hlines,~
@@ -7838,8 +8428,11 @@
     renew-matrix,~
     right-margin,~
     small,~
-    transparent~
-    and~vlines.
+    transparent,~
+    vlines,~
+    xdots/color,~
+    xdots/shorten~and~
+    xdots/line-style.
   }
 %    \end{macrocode}
 %
@@ -7865,7 +8458,6 @@
     create-extra-nodes,~
     create-medium-nodes,~
     create-large-nodes,~
-    dotted-lines-margin,~
     end-of-row,~
     extra-left-margin,~
     extra-right-margin,~
@@ -7884,7 +8476,10 @@
     right-margin,~
     small,~
     t,~
-    and~vlines.
+    vlines,~
+    xdots/color,~
+    xdots/shorten~and~
+    xdots/line-style.
   }
 %    \end{macrocode}
 %
@@ -7911,7 +8506,6 @@
     create-extra-nodes,~
     create-medium-nodes,~
     create-large-nodes,~
-    dotted-lines-margin,~
     end-of-row,~
     extra-left-margin,~
     extra-right-margin,~
@@ -7919,6 +8513,7 @@
     first-row,~
     hlines,~
     hvlines,~
+    l~(=L),~
     last-col,~
     last-row,~
     left-margin,~
@@ -7926,10 +8521,14 @@
     name,~
     nullify-dots,~
     parallelize-diags,~
+    r~(=R),~
     renew-dots,~
     right-margin,~
     small,~
-    and~vlines.
+    vlines,~
+    xdots/color,~
+    xdots/shorten~and~
+    xdots/line-style.
   }
 %    \end{macrocode}
 %
@@ -7967,14 +8566,6 @@
   }
 %    \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~\@@_full_name_env:. \\
-    If~you~go~on,~this~dotted~line~will~be~ignored.
-  }
-%    \end{macrocode}
 %
 % \bigskip
 % \subsection*{Obsolete environments}
@@ -8122,7 +8713,76 @@
   { \endNiceArrayWithDelims }
 %    \end{macrocode}
 %
+%
+% \subsection*{Command for creation of rectangle nodes}
+%
 % 
+% The following command should be used in a |{pgfpicture}|. It creates an
+% rectangular (empty but with a name) when the four corners are given.
+% 
+% |#1| is the name of the node which will be created;
+% |#2| and |#3| are the coordinates of one of the corner of the rectangle;
+% |#4| and |#5| are the coordinates of the opposite corner.
+%   \begin{macrocode}
+\cs_new_protected:Npn \@@_pgf_rect_node:nnnnn #1 #2 #3 #4 #5
+  {
+    \begin { pgfscope }
+    \pgfset
+      {
+        outer~sep = \c_zero_dim ,
+        inner~sep = \c_zero_dim ,
+        minimum~size = \c_zero_dim 
+      }
+    \pgftransformshift { \pgfpoint { 0.5 * ( #2 + #4 ) } { 0.5 * ( #3 + #5 ) } } 
+    \pgfnode
+      { rectangle }
+      { center }
+      { 
+        \vbox_to_ht:nn 
+          { \dim_abs:n { #5 - #3 } }
+          { 
+            \vfill
+            \hbox_to_wd:nn { \dim_abs:n { #4 - #2 } } { }
+          }   
+      }
+      { #1 }
+      { }
+    \end { pgfscope }
+  } 
+%    \end{macrocode}
+%
+% \medskip
+% The command |\@@_pgf_rect_node:nnn| is a variant of |\@@_pgr_rect_node:nnnn|:
+% it takes two \textsc{pgf} points as arguments instead of the four dimensions
+% which are the coordinates.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_pgf_rect_node:nnn #1 #2 #3
+  {
+    \begin { pgfscope }
+    \pgfset
+      {
+        outer~sep = \c_zero_dim ,
+        inner~sep = \c_zero_dim ,
+        minimum~size = \c_zero_dim 
+      }
+    \pgftransformshift { \pgfpointscale { 0.5 } { \pgfpointadd { #2 } { #3 } } } 
+    \pgfpointdiff { #3 } { #2 }
+    \pgfgetlastxy \l_tmpa_dim \l_tmpb_dim 
+    \pgfnode
+      { rectangle }
+      { center }
+      { 
+        \vbox_to_ht:nn 
+          { \dim_abs:n { \l_tmpb_dim } }
+          { \vfill \hbox_to_wd:nn { \dim_abs:n { \l_tmpa_dim } } { } } 
+      }
+      { #1 }
+      { }
+    \end { pgfscope }
+  }
+%    \end{macrocode}
+%
+% 
 % \vspace{1cm}
 % \section{History}
 %
@@ -8201,7 +8861,7 @@
 % \[\begin{pNiceArray}{Wc{5mm}CWc{5mm}}[first-row,last-col]
 % & C_j & \\
 % \mbox{\Large $0$} & \Vdots & \mbox{\Large $0$} \\
-%              & \strut a & \Cdots &  L_i \\
+% \strut            & a & \Cdots &  L_i \\
 % \mbox{\Large $0$} &  & \mbox{\Large $0$} \\
 % \end{pNiceArray}\]
 %
@@ -8263,18 +8923,18 @@
 % Error message when the user gives an incorrect value for |last-row|.
 %
 % A dotted line can no longer cross another dotted line (excepted the dotted
-% lines drawn by |\cdottedline|, the symbol |:| (in the preamble of the array) and
-% |\line| in |code-after|). 
+% lines drawn by |\cdottedline|, the symbol ``|:|'' (in the preamble of the
+% array) and |\line| in |code-after|).
 %
 % The starred versions of |\Cdots|, |\Ldots|, etc. are now deprecated because,
 % with the new implementation, they become pointless. These starred versions
 % are no longer documented.
 % 
-% The vertical rules in the matrices (drawn by "|") are now compatible with
+% The vertical rules in the matrices (drawn by ``"|"'') 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
+% 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).
 % 
 %
@@ -8366,7 +9026,7 @@
 %
 % Options |vlines|, |hlines| and |hvlines|.
 %
-% Option |baseline| pour |{NiceArray}| (uniquement).
+% Option |baseline| pour |{NiceArray}| (not for the other environments).
 %
 % The name of the Tikz nodes created by the command |\Block| has changed: when
 % the command has been issued in the cell $i$|-|$j$, the name is
@@ -8379,6 +9039,27 @@
 % The package must be loaded with the option |obsolete-environments| if we want
 % to use the deprecated environments.
 %
+% \subsection*{Changes between versions 3.12 and 3.13}
+%
+% The behaviour of the command |\rotate| is improved when used in the ``last
+% row''.
+%
+% The option |dotted-lines-margin| has been renamed in |xdots/shorten| and the
+% options |xdots/color| and |xdots/line-style| have been added for a complete
+% customization of the dotted lines.
+%
+% In the environments without preamble (|{NiceMatrix}|, |{pNiceMatrix}|, etc.),
+% it's possible to use the options |l| (=|L|) or |r| (=|R|) to specify the type
+% of the columns.
+%
+% The starred versions of the commands |\Cdots|, |\Ldots|, |\Vdots|, |\Ddots|
+% and |\Iddots| are deprecated since the version 3.1 of \pkg{nicematrix}. Now,
+% one should load \pkg{nicematrix} with the option |starred-commands| to avoid
+% an error at the compilation.
+%
+% The code of \pkg{nicematrix} no longer uses Tikz but only \textsc{pgf}. By
+% default, Tikz is \emph{not} loaded by \pkg{nicematrix}.
+%
 % \PrintIndex
 % 
 % \tableofcontents

Modified: trunk/Master/texmf-dist/tex/latex/nicematrix/nicematrix.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/nicematrix/nicematrix.sty	2020-03-15 21:32:00 UTC (rev 54329)
+++ trunk/Master/texmf-dist/tex/latex/nicematrix/nicematrix.sty	2020-03-15 21:32:14 UTC (rev 54330)
@@ -18,10 +18,10 @@
 %% and version 1.3 or later is part of all distributions of
 %% LaTeX version 2005/12/01 or later.
 %% 
-\def\myfileversion{3.12}
-\def\myfiledate{2020/02/28}
-\RequirePackage{tikz}
-\usetikzlibrary{fit}
+\def\myfileversion{3.13}
+\def\myfiledate{2020/03/15}
+\RequirePackage{pgfcore}
+\usepgfmodule{shapes}
 \RequirePackage{expl3}[2020/02/08]
 \RequirePackage{l3keys2e}
 \ProvidesExplPackage
@@ -28,7 +28,7 @@
   {nicematrix}
   {\myfiledate}
   {\myfileversion}
-  {Mathematical matrices with TikZ}
+  {Mathematical matrices with PGF/TikZ}
 \msg_new:nnn { nicematrix } { expl3~too~old }
   {
     Your~version~of~LaTeX~(especially~expl3)~is~too~old.~
@@ -53,6 +53,20 @@
 \cs_new_protected:Npn \__nicematrix_msg_new:nnn { \msg_new:nnnn { nicematrix } }
 \cs_new_protected:Npn \__nicematrix_msg_redirect_name:nn
   { \msg_redirect_name:nnn { nicematrix } }
+\bool_new:N \c__nicematrix_tikz_loaded_bool
+\AtBeginDocument
+  {
+    \@ifpackageloaded { tikz }
+      {
+        \bool_set_true:N \c__nicematrix_tikz_loaded_bool
+        \tl_const:Nn \c__nicematrix_pgfortikzpicture_tl { \exp_not:N \tikzpicture }
+        \tl_const:Nn \c__nicematrix_endpgfortikzpicture_tl { \exp_not:N \endtikzpicture }
+      }
+      {
+        \tl_const:Nn \c__nicematrix_pgfortikzpicture_tl { \exp_not:N \pgfpicture }
+        \tl_const:Nn \c__nicematrix_endpgfortikzpicture_tl { \exp_not:N \endpgfpicture }
+      }
+  }
 \bool_new:N \c__nicematrix_revtex_bool
 \@ifclassloaded { revtex4-1 }
   { \bool_set_true:N \c__nicematrix_revtex_bool }
@@ -62,8 +76,7 @@
   { }
 \__nicematrix_msg_new:nn { Draft~mode }
   { The~compilation~is~in~draft~mode:~the~dotted~lines~won't~be~drawn. }
-\bool_if:NT \c__nicematrix_draft_bool
-  { \msg_warning:nn { nicematrix }  { Draft~mode } }
+\bool_if:NT \c__nicematrix_draft_bool { \msg_warning:nn { nicematrix }  { Draft~mode } }
 \ProvideDocumentCommand \iddots { }
   {
     \mathinner
@@ -79,6 +92,9 @@
       }
   }
 \int_new:N \g__nicematrix_env_int
+\cs_new:Npn \__nicematrix_env: { nm - \int_use:N \g__nicematrix_env_int }
+\cs_new_protected:Npn \__nicematrix_qpoint: #1
+  { \pgfpointanchor { \__nicematrix_env: - #1 } { center } }
 \int_new:N \g__nicematrix_NiceMatrixBlock_int
 \dim_new:N \l__nicematrix_columns_width_dim
 \seq_new:N \g__nicematrix_names_seq
@@ -91,7 +107,6 @@
       \__nicematrix_fatal:n { Outside~math~mode }
     \fi:
   }
-\bool_new:N \l__nicematrix_impossible_line_bool
 \bool_new:N \c__nicematrix_colortbl_loaded_bool
 \AtBeginDocument
   {
@@ -102,12 +117,12 @@
       }
       { }
   }
-\cs_set_protected:Npn \__nicematrix_extract_coords:w
-  { \tikz at parse@node \pgfutil at firstofone }
+\colorlet { nicematrix-last-col } { . }
+\colorlet { nicematrix-last-row } { . }
 \dim_new:N \l__nicematrix_inter_dots_dim
 \dim_set:Nn \l__nicematrix_inter_dots_dim { 0.45 em }
-\dim_new:N \l__nicematrix_dotted_lines_margin_dim
-\dim_set:Nn \l__nicematrix_dotted_lines_margin_dim { 0.3 em }
+\dim_new:N \l__nicematrix_xdots_shorten_dim
+\dim_set:Nn \l__nicematrix_xdots_shorten_dim { 0.3 em }
 \dim_new:N \l__nicematrix_radius_dim
 \dim_set:Nn \l__nicematrix_radius_dim { 0.53 pt }
 \str_new:N \g__nicematrix_name_env_str
@@ -119,10 +134,25 @@
       { command \space \c_backslash_str \g__nicematrix_name_env_str }
       { environment \space \{ \g__nicematrix_name_env_str \} }
   }
+\tl_new:N \g__nicematrix_internal_code_after_tl
 \tl_new:N \g__nicematrix_code_after_tl
 \int_new:N \l__nicematrix_save_iRow_int
 \int_new:N \l__nicematrix_save_jCol_int
 \bool_new:N \g__nicematrix_row_of_col_done_bool
+\tl_new:N \l__nicematrix_initial_suffix_tl
+\tl_new:N \l__nicematrix_initial_anchor_tl
+\tl_new:N \l__nicematrix_final_suffix_tl
+\tl_new:N \l__nicematrix_final_anchor_tl
+\dim_new:N \l__nicematrix_x_initial_dim
+\dim_new:N \l__nicematrix_y_initial_dim
+\dim_new:N \l__nicematrix_x_final_dim
+\dim_new:N \l__nicematrix_y_final_dim
+\dim_new:N \l_tmpc_dim
+\dim_new:N \l_tmpd_dim
+\bool_new:N \g__nicematrix_empty_cell_bool
+\tl_new:N \l__nicematrix_xdots_line_style_tl
+\tl_const:Nn \c__nicematrix_standard_tl { standard }
+\tl_set_eq:NN \l__nicematrix_xdots_line_style_tl \c__nicematrix_standard_tl
 \int_new:N \l__nicematrix_first_row_int
 \int_set:Nn \l__nicematrix_first_row_int 1
 \int_new:N \l__nicematrix_first_col_int
@@ -172,6 +202,7 @@
         \NC at find
       }
   }
+\cs_new:Npn \__nicematrix_succ:N #1 { \the \numexpr #1 + 1 \relax }
 \bool_new:N \l__nicematrix_light_syntax_bool
 \str_new:N \l__nicematrix_baseline_str
 \str_set:Nn \l__nicematrix_baseline_str c
@@ -184,9 +215,7 @@
 \bool_new:N \l__nicematrix_auto_columns_width_bool
 \str_new:N \l__nicematrix_name_str
 \bool_new:N \l__nicematrix_medium_nodes_bool
-\bool_new:N \g__nicematrix_medium_nodes_bool
 \bool_new:N \l__nicematrix_large_nodes_bool
-\bool_new:N \g__nicematrix_large_nodes_bool
 \dim_new:N \l__nicematrix_left_margin_dim
 \dim_new:N \l__nicematrix_right_margin_dim
 \dim_new:N \g__nicematrix_width_last_col_dim
@@ -195,12 +224,29 @@
 \dim_new:N \l__nicematrix_extra_right_margin_dim
 \tl_new:N \l__nicematrix_end_of_row_tl
 \tl_set:Nn \l__nicematrix_end_of_row_tl { ; }
+\tl_new:N \l__nicematrix_xdots_color_tl
 \bool_new:N \l__nicematrix_max_delimiter_width_bool
+\keys_define:nn { NiceMatrix / xdots }
+  {
+    line-style .code:n =
+     {
+       \bool_lazy_or:nnTF
+        { \cs_if_exist_p:N \tikzpicture }
+        { \str_if_eq_p:nn { #1 } { standard } }
+        { \tl_set:Nn \l__nicematrix_xdots_line_style_tl { #1 } }
+        { \__nicematrix_error:n { bad~option~for~line-style } }
+     } ,
+    line-style .value_required:n = true ,
+    color .tl_set:N = \l__nicematrix_xdots_color_tl ,
+    color .value_required:n = true ,
+    shorten .dim_set:N = \l__nicematrix_xdots_shorten_dim ,
+    shorten .value_required:n = true ,
+    unknown .code:n = \__nicematrix_error:n { Unknown~option~for~xdots }
+  }
 \keys_define:nn { NiceMatrix / Global }
   {
+    xdots .code:n = \keys_set:nn { NiceMatrix / xdots } { #1 } ,
     max-delimiter-width .bool_set:N = \l__nicematrix_max_delimiter_width_bool ,
-    dotted-lines-margin .dim_set:N = \l__nicematrix_dotted_lines_margin_dim ,
-    dotted-lines-margin .value_required:n = true ,
     light-syntax .bool_set:N = \l__nicematrix_light_syntax_bool ,
     light-syntax .default:n = true ,
     end-of-row .tl_set:N = \l__nicematrix_end_of_row_tl ,
@@ -234,7 +280,8 @@
     extra-left-margin .dim_set:N = \l__nicematrix_extra_left_margin_dim ,
     extra-right-margin .dim_set:N = \l__nicematrix_extra_right_margin_dim ,
     extra-margin .meta:n =
-      { extra-left-margin = #1 , extra-right-margin = #1 }
+      { extra-left-margin = #1 , extra-right-margin = #1 } ,
+    extra-margin .value_required:n = true
   }
 \keys_define:nn { NiceMatrix / Env }
   {
@@ -266,21 +313,25 @@
       {
         NiceMatrix / Global ,
       } ,
+    NiceMatrixOptions / xdots .inherit:n = NiceMatrix / xdots ,
     NiceMatrix .inherit:n =
       {
         NiceMatrix / Global ,
-        NiceMatrix / Env
+        NiceMatrix / Env ,
       } ,
+    NiceMatrix / xdots .inherit:n = NiceMatrix / xdots ,
     NiceArray .inherit:n =
       {
         NiceMatrix / Global ,
         NiceMatrix / Env ,
       } ,
+    NiceArray / xdots .inherit:n = NiceMatrix / xdots ,
     pNiceArray .inherit:n =
       {
         NiceMatrix / Global ,
         NiceMatrix / Env ,
-      }
+      } ,
+    pNiceArray / xdots .inherit:n = NiceMatrix / xdots
   }
 \keys_define:nn { NiceMatrix / NiceMatrixOptions }
   {
@@ -314,6 +365,10 @@
     last-col .code:n = \tl_if_empty:nTF {#1}
                          { \__nicematrix_error:n { last-col~empty~for~NiceMatrix } }
                          { \int_set:Nn \l__nicematrix_last_col_int { #1 } } ,
+    l .code:n = \tl_set:Nn \l__nicematrix_type_of_col_tl L ,
+    r .code:n = \tl_set:Nn \l__nicematrix_type_of_col_tl R ,
+    L .code:n = \tl_set:Nn \l__nicematrix_type_of_col_tl L ,
+    R .code:n = \tl_set:Nn \l__nicematrix_type_of_col_tl R ,
     unknown .code:n = \__nicematrix_error:n { Unknown~option~for~NiceMatrix }
   }
 \keys_define:nn { NiceMatrix / NiceArray }
@@ -343,20 +398,25 @@
   {
     \int_gincr:N \c at jCol
     \int_compare:nNnT \c at jCol = 1
-      {
-        \int_compare:nNnT \l__nicematrix_first_col_int = 1
-          \__nicematrix_begin_of_row:
-      }
-    \int_gset:Nn \g__nicematrix_col_total_int
-      { \int_max:nn \g__nicematrix_col_total_int \c at jCol }
+      { \int_compare:nNnT \l__nicematrix_first_col_int = 1 \__nicematrix_begin_of_row: }
+    \int_gset:Nn \g__nicematrix_col_total_int { \int_max:nn \g__nicematrix_col_total_int \c at jCol }
     \hbox_set:Nw \l__nicematrix_cell_box
     \c_math_toggle_token
     \bool_if:NT \l__nicematrix_small_bool \scriptstyle
     \int_compare:nNnTF \c at iRow = 0
-      { \int_compare:nNnT \c at jCol > 0 \l__nicematrix_code_for_first_row_tl }
       {
+        \int_compare:nNnT \c at jCol > 0
+          {
+            \l__nicematrix_code_for_first_row_tl
+            \xglobal \colorlet { nicematrix-first-row } { . }
+          }
+      }
+      {
         \int_compare:nNnT \c at iRow = \l__nicematrix_last_row_int
-          \l__nicematrix_code_for_last_row_tl
+          {
+            \l__nicematrix_code_for_last_row_tl
+            \xglobal \colorlet { nicematrix-last-row } { . }
+          }
       }
   }
 \cs_new_protected:Npn \__nicematrix_begin_of_row:
@@ -365,8 +425,18 @@
     \dim_gset_eq:NN \g__nicematrix_dp_ante_last_row_dim \g__nicematrix_dp_last_row_dim
     \dim_gset:Nn \g__nicematrix_dp_last_row_dim { \box_dp:N \@arstrutbox }
     \dim_gset:Nn \g__nicematrix_ht_last_row_dim { \box_ht:N \@arstrutbox }
-    \tikz [ remember~picture , baseline ] \coordinate
-      ( nm - \int_use:N \g__nicematrix_env_int - row - \int_use:N \c at iRow - base ) ;
+    \pgfpicture
+    \pgfrememberpicturepositiononpagetrue
+    \pgfcoordinate
+      { \__nicematrix_env: - row - \int_use:N \c at iRow - base }
+      \pgfpointorigin
+    \str_if_empty:NF \l__nicematrix_name_str
+      {
+        \pgfnodealias
+          { \__nicematrix_env: - row - \int_use:N \c at iRow - base }
+          { \l__nicematrix_name_str - row - \int_use:N \c at iRow - base }
+      }
+    \endpgfpicture
   }
 \cs_new_protected:Npn \__nicematrix_update_for_first_and_last_row:
   {
@@ -392,58 +462,54 @@
     \dim_gset:Nn \g__nicematrix_max_cell_width_dim
       { \dim_max:nn \g__nicematrix_max_cell_width_dim { \box_wd:N \l__nicematrix_cell_box } }
     \__nicematrix_update_for_first_and_last_row:
-    \tikz
-      [
-        remember~picture ,
-        inner~sep = \c_zero_dim ,
-        minimum~width = \c_zero_dim ,
-        baseline
-      ]
-    \node
-      [
-        anchor = base ,
-        name = nm - \int_use:N \g__nicematrix_env_int -
-                    \int_use:N \c at iRow -
-                    \int_use:N \c at jCol ,
-        alias =
-          \str_if_empty:NF \l__nicematrix_name_str
-            {
-              \l__nicematrix_name_str -
-              \int_use:N \c at iRow -
-              \int_use:N \c at jCol
-            }
-      ]
-    { \box_use_drop:N \l__nicematrix_cell_box } ;
+    \bool_if:NTF \g__nicematrix_empty_cell_bool
+      {
+        \box_use_drop:N \l__nicematrix_cell_box
+        \bool_gset_false:N \g__nicematrix_empty_cell_bool
+      }
+      {
+        \dim_compare:nNnTF { \box_wd:N \l__nicematrix_cell_box } > \c_zero_dim
+          \__nicematrix_node_for_the_cell:
+          { \box_use_drop:N \l__nicematrix_cell_box }
+      }
+    \bool_gset_false:N \g__nicematrix_empty_cell_bool
   }
-\cs_generate_variant:Nn \dim_set:Nn { N x }
-\cs_new_protected:Npn \__nicematrix_renewcolumntype:nn #1 #2
+\cs_new_protected:Npn \__nicematrix_node_for_the_cell:
   {
-    \newcolumntype #1 [ 2 ]
+    \pgfpicture
+    \pgfsetbaseline \c_zero_dim
+    \pgfrememberpicturepositiononpagetrue
+    \pgfset
       {
-        > {
-            \hbox_set:Nw \l__nicematrix_cell_box
-            \__nicematrix_Cell:
-          }
-        c
-        < {
-            \__nicematrix_end_Cell:
-            \hbox_set_end:
-            #2
-            \makebox [ ##2 ] [ ##1 ] { \box_use_drop:N \l__nicematrix_cell_box }
-          }
+        inner~sep = \c_zero_dim ,
+        minimum~width = \c_zero_dim
       }
+    \pgfnode
+      { rectangle }
+      { base }
+      { \box_use_drop:N \l__nicematrix_cell_box }
+      { \__nicematrix_env: - \int_use:N \c at iRow - \int_use:N \c at jCol }
+      { }
+    \str_if_empty:NF \l__nicematrix_name_str
+      {
+        \pgfnodealias
+          { \l__nicematrix_name_str - \int_use:N \c at iRow - \int_use:N \c at jCol }
+          { \__nicematrix_env: - \int_use:N \c at iRow - \int_use:N \c at jCol }
+      }
+    \endpgfpicture
   }
 \bool_if:NTF \c__nicematrix_draft_bool
-  { \cs_set_protected:Npn \__nicematrix_instruction_of_type:n #1 { } }
+  { \cs_set_protected:Npn \__nicematrix_instruction_of_type:nn #1 #2 { } }
   {
-    \cs_new_protected:Npn \__nicematrix_instruction_of_type:n #1
+    \cs_new_protected:Npn \__nicematrix_instruction_of_type:nn #1 #2
       {
         \tl_gput_right:cx
           { g__nicematrix_ #1 _ lines _ tl }
           {
-            \use:c { __nicematrix _ draw _ #1 : nn }
+            \use:c { __nicematrix _ draw _ #1 : nnn }
               { \int_use:N \c at iRow }
               { \int_use:N \c at jCol }
+              { #2 }
           }
       }
   }
@@ -465,11 +531,19 @@
 \cs_new_protected:Npn \__nicematrix_everycr_i:
   {
     \int_gzero:N \c at jCol
-    \hbox:n
+    \hbox
       {
-        \tikz [ remember~picture ]
-        \coordinate
-        ( nm - \int_use:N \g__nicematrix_env_int - row - \int_eval:n { \c at iRow + 1 } ) ;
+        \pgfpicture
+        \pgfrememberpicturepositiononpagetrue
+        \pgfcoordinate { \__nicematrix_env: - row - \__nicematrix_succ:N \c at iRow }
+          \pgfpointorigin
+        \str_if_empty:NF \l__nicematrix_name_str
+          {
+            \pgfnodealias
+              { \__nicematrix_env: - row - \int_use:N \c at iRow - row }
+              { \l__nicematrix_name_str - row - \int_use:N \c at iRow - row }
+          }
+        \endpgfpicture
       }
     \bool_if:NT \l__nicematrix_hlines_bool
       {
@@ -502,8 +576,6 @@
         \cs_set:Npn \arraystretch { 0.47 }
         \dim_set:Nn \arraycolsep { 1.45 pt }
       }
-    \bool_gset_eq:NN \g__nicematrix_medium_nodes_bool \l__nicematrix_medium_nodes_bool
-    \bool_gset_eq:NN \g__nicematrix_large_nodes_bool \l__nicematrix_large_nodes_bool
     \cs_set:Npn \ialign
       {
         \bool_if:NTF \c__nicematrix_colortbl_loaded_bool
@@ -533,6 +605,11 @@
     \newcolumntype L { > \__nicematrix_Cell: l < \__nicematrix_end_Cell: }
     \newcolumntype C { > \__nicematrix_Cell: c < \__nicematrix_end_Cell: }
     \newcolumntype R { > \__nicematrix_Cell: r < \__nicematrix_end_Cell: }
+    \cs_set_eq:NN \__nicematrix_ldots \ldots
+    \cs_set_eq:NN \__nicematrix_cdots \cdots
+    \cs_set_eq:NN \__nicematrix_vdots \vdots
+    \cs_set_eq:NN \__nicematrix_ddots \ddots
+    \cs_set_eq:NN \__nicematrix_iddots \iddots
     \cs_set_eq:NN \firsthline \hline
     \cs_set_eq:NN \lasthline \hline
     \cs_set_eq:NN \Ldots \__nicematrix_Ldots
@@ -565,8 +642,35 @@
     \cs_set_eq:NN \@ifnextchar \new at ifnextchar
     \cs_set_eq:NN \NC at find@w \relax
     \cs_set_eq:NN \NC at find@W \relax
-    \__nicematrix_renewcolumntype:nn w { }
-    \__nicematrix_renewcolumntype:nn W { \cs_set_eq:NN \hss \hfil }
+    \newcolumntype w [ 2 ]
+      {
+        > {
+            \hbox_set:Nw \l__nicematrix_cell_box
+            \__nicematrix_Cell:
+          }
+        c
+        < {
+            \__nicematrix_end_Cell:
+            \hbox_set_end:
+            \makebox [ ##2 ] [ \str_lowercase:n { ##1 } ]
+               { \box_use_drop:N \l__nicematrix_cell_box }
+          }
+      }
+    \newcolumntype W [ 2 ]
+      {
+        > {
+            \hbox_set:Nw \l__nicematrix_cell_box
+            \__nicematrix_Cell:
+          }
+        c
+        < {
+            \__nicematrix_end_Cell:
+            \hbox_set_end:
+            \cs_set_eq:NN \hss \hfil
+            \makebox [ ##2 ] [ \str_lowercase:n { ##1 } ]
+              { \box_use_drop:N \l__nicematrix_cell_box }
+          }
+      }
     \tl_set_rescan:Nno
       \l__nicematrix_letter_for_dotted_lines_str { } \l__nicematrix_letter_for_dotted_lines_str
     \exp_args:NV \newcolumntype \l__nicematrix_letter_for_dotted_lines_str
@@ -576,12 +680,12 @@
             \int_compare:nNnF \c at iRow = 0
               {
                 \int_compare:nNnF \c at iRow = \l__nicematrix_last_row_int
-                  { \skip_horizontal:n { 2 \l__nicematrix_radius_dim } }
+                  { \skip_horizontal:N 2\l__nicematrix_radius_dim }
               }
             \int_compare:nNnT \c at jCol > \g__nicematrix_last_vdotted_col_int
               {
                 \int_gset_eq:NN \g__nicematrix_last_vdotted_col_int \c at jCol
-                \tl_gput_right:Nx \g__nicematrix_code_after_tl
+                \tl_gput_right:Nx \g__nicematrix_internal_code_after_tl
                   { \__nicematrix_vdottedline:n { \int_use:N \c at jCol } }
               }
           }
@@ -599,6 +703,8 @@
  }
 \NewDocumentEnvironment { NiceArrayWithDelims } { m m O { } m ! O { } }
   {
+    \tl_set:Nn \l__nicematrix_left_delim_tl { #1 }
+    \tl_set:Nn \l__nicematrix_right_delim_tl { #2 }
     \bool_gset_false:N \g__nicematrix_row_of_col_done_bool
     \str_if_empty:NT \g__nicematrix_name_env_str
       { \str_gset:Nn \g__nicematrix_name_env_str { NiceArrayWithDelims } }
@@ -658,22 +764,10 @@
         \dim_gset:Nn \l__nicematrix_right_delim_dim { 2 \arraycolsep }
       }
       {
-        \hbox_set:Nn \l_tmpa_box
-          {
-            \c_math_toggle_token
-            \left #1 \vcenter to 3 cm { } \right.
-            \c_math_toggle_token
-          }
-        \dim_set:Nn \l__nicematrix_left_delim_dim
-          { \box_wd:N \l_tmpa_box - \nulldelimiterspace }
-        \hbox_set:Nn \l_tmpa_box
-          {
-            \c_math_toggle_token
-            \left. \vcenter to 3 cm { } \right #2
-            \c_math_toggle_token
-          }
-        \dim_set:Nn \l__nicematrix_right_delim_dim
-          { \box_wd:N \l_tmpa_box - \nulldelimiterspace }
+        \hbox_set:Nn \l_tmpa_box { $ \bBigg@ 5 #1 $ }
+        \dim_set:Nn \l__nicematrix_left_delim_dim { \box_wd:N \l_tmpa_box }
+        \hbox_set:Nn \l_tmpa_box { $\bBigg@ 5 #2 $ }
+        \dim_set:Nn \l__nicematrix_right_delim_dim { \box_wd:N \l_tmpa_box }
       }
     \box_clear_new:N \l__nicematrix_the_array_box
     \tl_set:Nn \l_tmpa_tl { #4 }
@@ -680,11 +774,11 @@
     \int_compare:nNnTF \l__nicematrix_first_col_int = 0
       { \tl_put_left:NV \l_tmpa_tl \c__nicematrix_preamble_first_col_tl }
       {
-        \bool_if:nT
+        \bool_lazy_all:nT
           {
-                 \l__nicematrix_NiceArray_bool
-            && ! \l__nicematrix_vlines_bool
-            && ! \l__nicematrix_exterior_arraycolsep_bool
+            \l__nicematrix_NiceArray_bool
+            { \bool_not_p:n \l__nicematrix_vlines_bool }
+            { \bool_not_p:n \l__nicematrix_exterior_arraycolsep_bool }
           }
           { \tl_put_left:Nn \l_tmpa_tl { @ { } } }
       }
@@ -691,23 +785,23 @@
     \int_compare:nNnTF \l__nicematrix_last_col_int > { -1 }
       { \tl_put_right:NV \l_tmpa_tl \c__nicematrix_preamble_last_col_tl }
       {
-        \bool_if:nT
+        \bool_lazy_all:nT
           {
-                 \l__nicematrix_NiceArray_bool
-            && ! \l__nicematrix_vlines_bool
-            && ! \l__nicematrix_exterior_arraycolsep_bool
+            \l__nicematrix_NiceArray_bool
+            { \bool_not_p:n \l__nicematrix_vlines_bool }
+            { \bool_not_p:n \l__nicematrix_exterior_arraycolsep_bool }
           }
           { \tl_put_right:Nn \l_tmpa_tl { @ { } } }
       }
     \tl_put_right:Nn \l_tmpa_tl { > { \__nicematrix_error_too_much_cols: } l }
     \hbox_set:Nw \l__nicematrix_the_array_box
-     \bool_if:NT \l__nicematrix_vlines_bool
+    \bool_if:NT \l__nicematrix_vlines_bool
       {
         \dim_add:Nn \arraycolsep { 0.5 \arrayrulewidth }
-        \skip_horizontal:n { 0.5 \arrayrulewidth }
+        \skip_horizontal:N  0.5\arrayrulewidth
       }
-    \skip_horizontal:n \l__nicematrix_left_margin_dim
-    \skip_horizontal:n \l__nicematrix_extra_left_margin_dim
+    \skip_horizontal:N \l__nicematrix_left_margin_dim
+    \skip_horizontal:N \l__nicematrix_extra_left_margin_dim
     \c_math_toggle_token
     \bool_if:NTF \l__nicematrix_light_syntax_bool
       { \begin { __nicematrix-light-syntax } }
@@ -718,9 +812,9 @@
       { \end { __nicematrix-light-syntax } }
       { \end { __nicematrix-normal-syntax } }
     \c_math_toggle_token
-    \skip_horizontal:n \l__nicematrix_right_margin_dim
-    \skip_horizontal:n \l__nicematrix_extra_right_margin_dim
-    \bool_if:NT \l__nicematrix_vlines_bool { \skip_horizontal:n { 0.5 \arrayrulewidth } }
+    \skip_horizontal:N \l__nicematrix_right_margin_dim
+    \skip_horizontal:N \l__nicematrix_extra_right_margin_dim
+    \bool_if:NT \l__nicematrix_vlines_bool { \skip_horizontal:N 0.5\arrayrulewidth }
     \hbox_set_end:
     \int_compare:nNnT \l__nicematrix_last_row_int > { -2 }
       {
@@ -739,23 +833,19 @@
     \int_compare:nNnT \l__nicematrix_last_row_int > { -1 } { \int_gdecr:N \c at iRow }
     \int_compare:nNnT \l__nicematrix_first_col_int = 0
       {
-        \skip_horizontal:n \arraycolsep
-        \skip_horizontal:n \g__nicematrix_width_first_col_dim
+        \skip_horizontal:N \arraycolsep
+        \skip_horizontal:N \g__nicematrix_width_first_col_dim
       }
     \bool_if:NTF \l__nicematrix_NiceArray_bool
       {
         \str_if_eq:VnTF \l__nicematrix_baseline_str { b }
           {
-           \begin { tikzpicture }
-             \__nicematrix_extract_coords:w ( nm - \int_use:N \g__nicematrix_env_int - row - 1 )
+           \pgfpicture
+             \__nicematrix_qpoint: { row - 1 }
              \dim_gset_eq:NN \g_tmpa_dim \pgf at y
-             \__nicematrix_extract_coords:w
-               (
-                 nm - \int_use:N \g__nicematrix_env_int -
-                 row - \int_use:N \c at iRow - base
-               )
+             \__nicematrix_qpoint: { row - \int_use:N \c at iRow - base }
              \dim_gsub:Nn \g_tmpa_dim \pgf at y
-           \end { tikzpicture }
+           \endpgfpicture
            \int_compare:nNnT \l__nicematrix_first_row_int = 0
              {
                \dim_gadd:Nn \g_tmpa_dim
@@ -772,7 +862,7 @@
                 \int_set:Nn \l_tmpa_int \l__nicematrix_baseline_str
                 \bool_if:nT
                   {
-                       \int_compare_p:nNn \l_tmpa_int < 0
+                       \int_compare_p:nNn \l_tmpa_int < \l__nicematrix_first_row_int
                     || \int_compare_p:nNn \l_tmpa_int > \g__nicematrix_row_total_int
                   }
                   {
@@ -779,17 +869,12 @@
                     \__nicematrix_error:n { bad~value~for~baseline }
                     \int_set:Nn \l_tmpa_int 1
                   }
-                \begin { tikzpicture }
-                \__nicematrix_extract_coords:w
-                  ( nm - \int_use:N \g__nicematrix_env_int - row - 1 )
+                \pgfpicture
+                \__nicematrix_qpoint: { row - 1 }
                 \dim_gset_eq:NN \g_tmpa_dim \pgf at y
-                \__nicematrix_extract_coords:w
-                  (
-                    nm - \int_use:N \g__nicematrix_env_int -
-                    row - \int_use:N \l_tmpa_int- base
-                  )
+                \__nicematrix_qpoint: { row - \int_use:N \l_tmpa_int - base }
                 \dim_gsub:Nn \g_tmpa_dim \pgf at y
-                \end { tikzpicture }
+                \endpgfpicture
                 \int_compare:nNnT \l__nicematrix_first_row_int = 0
                   {
                     \dim_gadd:Nn \g_tmpa_dim
@@ -803,14 +888,14 @@
       {
         \int_compare:nNnTF \l__nicematrix_first_row_int = 0
           {
-            \dim_set:Nn \l_tmpa_dim
-              { \g__nicematrix_dp_row_zero_dim + \g__nicematrix_ht_row_zero_dim }
+            \dim_set_eq:NN \l_tmpa_dim \g__nicematrix_dp_row_zero_dim
+            \dim_add:Nn \l_tmpa_dim \g__nicematrix_ht_row_zero_dim
           }
           { \dim_zero:N \l_tmpa_dim }
         \int_compare:nNnTF \l__nicematrix_last_row_int > { -2 }
           {
-            \dim_set:Nn \l_tmpb_dim
-              { \g__nicematrix_ht_last_row_dim + \g__nicematrix_dp_last_row_dim }
+            \dim_set_eq:NN \l_tmpb_dim \g__nicematrix_ht_last_row_dim
+            \dim_add:Nn \l_tmpb_dim \g__nicematrix_dp_last_row_dim
           }
           { \dim_zero:N \l_tmpb_dim }
         \hbox_set:Nn \l_tmpa_box
@@ -819,14 +904,14 @@
             \left #1
             \vcenter
               {
-                \skip_vertical:n { - \l_tmpa_dim }
-                \hbox:n
+                \skip_vertical:N -\l_tmpa_dim
+                \hbox
                   {
-                    \skip_horizontal:n { - \arraycolsep }
+                    \skip_horizontal:N -\arraycolsep
                     \box_use_drop:N \l__nicematrix_the_array_box
-                    \skip_horizontal:n { - \arraycolsep }
+                    \skip_horizontal:N -\arraycolsep
                   }
-                \skip_vertical:n { - \l_tmpb_dim }
+                \skip_vertical:N -\l_tmpb_dim
               }
             \right #2
             \c_math_toggle_token
@@ -836,7 +921,10 @@
           \__nicematrix_put_box_in_flow:
       }
     \bool_if:NT \g__nicematrix_last_col_found_bool
-      { \skip_horizontal:n { \g__nicematrix_width_last_col_dim + \arraycolsep } }
+      {
+        \skip_horizontal:N \g__nicematrix_width_last_col_dim
+        \skip_horizontal:N \arraycolsep
+      }
     \__nicematrix_after_array:
   }
 \cs_new_protected:Npn \__nicematrix_put_box_in_flow:
@@ -876,9 +964,11 @@
       }
     \dim_set:Nn \l__nicematrix_real_right_delim_dim
       { \box_wd:N \l_tmpb_box - \nulldelimiterspace }
-    \skip_horizontal:n { \l__nicematrix_left_delim_dim - \l__nicematrix_real_left_delim_dim }
+    \skip_horizontal:N  \l__nicematrix_left_delim_dim
+    \skip_horizontal:N -\l__nicematrix_real_left_delim_dim
     \__nicematrix_put_box_in_flow:
-    \skip_horizontal:n { \l__nicematrix_right_delim_dim - \l__nicematrix_real_right_delim_dim }
+    \skip_horizontal:N \l__nicematrix_right_delim_dim
+    \skip_horizontal:N -\l__nicematrix_real_right_delim_dim
   }
 \NewDocumentEnvironment { __nicematrix-normal-syntax } { }
   {
@@ -892,11 +982,13 @@
   }
 \NewDocumentEnvironment { __nicematrix-light-syntax } { b }
   {
-     \tl_if_empty:nT { #1 } { \__nicematrix_fatal:n { empty~environment } }
-    \exp_args:NV \__nicematrix_array: \l_tmpa_tl
+    \tl_if_empty:nT { #1 } { \__nicematrix_fatal:n { empty~environment } }
     \seq_gclear_new:N \g__nicematrix_rows_seq
     \tl_set_rescan:Nno \l__nicematrix_end_of_row_tl { } \l__nicematrix_end_of_row_tl
     \exp_args:NNV \seq_gset_split:Nnn \g__nicematrix_rows_seq \l__nicematrix_end_of_row_tl { #1 }
+    \int_compare:nNnT \l__nicematrix_last_row_int = { -1 }
+      { \int_set:Nn \l__nicematrix_last_row_int { \seq_count:N \g__nicematrix_rows_seq } }
+    \exp_args:NV \__nicematrix_array: \l_tmpa_tl
     \seq_gpop_left:NN \g__nicematrix_rows_seq \l_tmpa_tl
     \exp_args:NV \__nicematrix_line_with_light_syntax_i:n \l_tmpa_tl
     \seq_map_function:NN \g__nicematrix_rows_seq \__nicematrix_line_with_light_syntax:n
@@ -931,34 +1023,32 @@
     \int_compare:nNnT \l__nicematrix_first_col_int = 0 { \omit & }
     \omit
     \bool_gset_true:N \g__nicematrix_row_of_col_done_bool
-    \tikz [ remember~picture ]
-      \coordinate ( nm - \int_use:N \g__nicematrix_env_int - col - 1 ) ;
-    \bool_if:nTF
+    \pgfpicture
+    \pgfrememberpicturepositiononpagetrue
+    \pgfcoordinate { \__nicematrix_env: - col - 1 } \pgfpointorigin
+    \str_if_empty:NF \l__nicematrix_name_str
+      { \pgfnodealias { \__nicematrix_env: - col - 1 } { \l__nicematrix_name_str - col - 1 } }
+    \endpgfpicture
+    \skip_gset:Nn \g_tmpa_skip { 0 pt~plus 1 fill }
+    \bool_if:NF \l__nicematrix_auto_columns_width_bool
+      { \dim_compare:nNnT \l__nicematrix_columns_width_dim > \c_zero_dim }
       {
-        \l__nicematrix_auto_columns_width_bool
-        || \dim_compare_p:nNn \l__nicematrix_columns_width_dim > \c_zero_dim
+        \bool_lazy_and:nnTF
+          \l__nicematrix_auto_columns_width_bool
+          { \bool_not_p:n \l__nicematrix_block_auto_columns_width_bool }
+          { \skip_gset_eq:NN \g_tmpa_skip \g__nicematrix_max_cell_width_dim }
+          { \skip_gset_eq:NN \g_tmpa_skip \l__nicematrix_columns_width_dim }
+        \skip_gadd:Nn \g_tmpa_skip { 2 \arraycolsep }
       }
-      {
-        \bool_if:nTF
-          {
-            \l__nicematrix_auto_columns_width_bool
-            && ! \l__nicematrix_block_auto_columns_width_bool
-          }
-          {
-            \skip_gset:Nn \g_tmpa_skip
-              { \g__nicematrix_max_cell_width_dim + 2 \arraycolsep }
-          }
-          {
-            \skip_gset:Nn \g_tmpa_skip
-              { \l__nicematrix_columns_width_dim + 2 \arraycolsep }
-          }
-      }
-      { \skip_gset:Nn \g_tmpa_skip { 0 pt~plus 1 fill } }
     \skip_horizontal:N \g_tmpa_skip
-    \hbox:n
+    \hbox
       {
-        \tikz [ remember~picture ]
-          \coordinate ( nm - \int_use:N \g__nicematrix_env_int - col - 2 ) ;
+        \pgfpicture
+        \pgfrememberpicturepositiononpagetrue
+        \pgfcoordinate { \__nicematrix_env: - col - 2 } \pgfpointorigin
+        \str_if_empty:NF \l__nicematrix_name_str
+          { \pgfnodealias { \__nicematrix_env: - col - 2 } { \l__nicematrix_name_str - col - 2 } }
+        \endpgfpicture
       }
     \int_gset:Nn \g_tmpa_int 1
     \bool_if:NTF \g__nicematrix_last_col_found_bool
@@ -969,12 +1059,17 @@
          \omit
          \int_gincr:N \g_tmpa_int
          \skip_horizontal:N \g_tmpa_skip
-         \tikz [ remember~picture ]
-           \coordinate
-             (
-               nm - \int_use:N \g__nicematrix_env_int -
-               col - \int_eval:n { \g_tmpa_int + 1 }
-             ) ;
+         \pgfpicture
+           \pgfrememberpicturepositiononpagetrue
+           \pgfcoordinate { \__nicematrix_env: - col - \__nicematrix_succ:N \g_tmpa_int }
+             \pgfpointorigin
+           \str_if_empty:NF \l__nicematrix_name_str
+             {
+               \pgfnodealias
+                 { \__nicematrix_env: - col - \__nicematrix_succ:N \g_tmpa_int }
+                 { \l__nicematrix_name_str - col - \__nicematrix_succ:N \g_tmpa_int }
+             }
+         \endpgfpicture
       }
     \cr
   }
@@ -986,17 +1081,17 @@
         \hbox_set:Nw \l__nicematrix_cell_box
         \c_math_toggle_token
         \bool_if:NT \l__nicematrix_small_bool \scriptstyle
-        \bool_if:nT
+        \bool_lazy_and:nnT
+          { \int_compare_p:nNn \c at iRow > 0 }
           {
-            \int_compare_p:nNn \c at iRow > 0
-            &&
-            (
-              \int_compare_p:nNn \l__nicematrix_last_row_int < 0
-              ||
-              \int_compare_p:nNn \c at iRow < \l__nicematrix_last_row_int
-            )
+            \bool_lazy_or_p:nn
+              { \int_compare_p:nNn \l__nicematrix_last_row_int < 0 }
+              { \int_compare_p:nNn \c at iRow < \l__nicematrix_last_row_int }
           }
-          { \l__nicematrix_code_for_first_col_tl }
+          {
+            \l__nicematrix_code_for_first_col_tl
+            \xglobal \colorlet { nicematrix-first-col } { . }
+          }
       }
     l
     <
@@ -1005,45 +1100,17 @@
         \hbox_set_end:
         \__nicematrix_update_for_first_and_last_row:
         \dim_gset:Nn \g__nicematrix_width_first_col_dim
-          {
-            \dim_max:nn
-              \g__nicematrix_width_first_col_dim
-              { \box_wd:N \l__nicematrix_cell_box }
-          }
+          { \dim_max:nn \g__nicematrix_width_first_col_dim { \box_wd:N \l__nicematrix_cell_box } }
         \hbox_overlap_left:n
           {
-            \tikz
-              [
-                remember~picture ,
-                inner~sep = \c_zero_dim ,
-                minimum~width = \c_zero_dim ,
-                baseline
-              ]
-            \node
-              [
-                anchor = base ,
-                name =
-                  nm -
-                  \int_use:N \g__nicematrix_env_int -
-                  \int_use:N \c at iRow -
-                  0 ,
-                alias =
-                  \str_if_empty:NF \l__nicematrix_name_str
-                    {
-                      \l__nicematrix_name_str -
-                      \int_use:N \c at iRow -
-                      0
-                    }
-              ]
-              { \box_use_drop:N \l__nicematrix_cell_box } ;
-            \skip_horizontal:n
-              {
-                \l__nicematrix_left_delim_dim +
-                \l__nicematrix_left_margin_dim +
-                \l__nicematrix_extra_left_margin_dim
-              }
+            \dim_compare:nNnTF { \box_wd:N \l__nicematrix_cell_box } > \c_zero_dim
+              \__nicematrix_node_for_the_cell:
+              { \box_use_drop:N \l__nicematrix_cell_box }
+            \skip_horizontal:N \l__nicematrix_left_delim_dim
+            \skip_horizontal:N \l__nicematrix_left_margin_dim
+            \skip_horizontal:N \l__nicematrix_extra_left_margin_dim
           }
-        \skip_horizontal:n { - 2 \arraycolsep }
+        \skip_horizontal:N -2\arraycolsep
       }
   }
 \tl_const:Nn \c__nicematrix_preamble_last_col_tl
@@ -1057,17 +1124,16 @@
         \hbox_set:Nw \l__nicematrix_cell_box
           \c_math_toggle_token
           \bool_if:NT \l__nicematrix_small_bool \scriptstyle
-        \bool_if:nT
+        \int_compare:nNnT \c at iRow > 0
           {
-            \int_compare_p:nNn \c at iRow > 0
-            &&
-            (
-              \int_compare_p:nNn \l__nicematrix_last_row_int < 0
-              ||
-              \int_compare_p:nNn \c at iRow < \l__nicematrix_last_row_int
-            )
+            \bool_lazy_or:nnT
+              { \int_compare_p:nNn \l__nicematrix_last_row_int < 0 }
+              { \int_compare_p:nNn \c at iRow < \l__nicematrix_last_row_int }
+              {
+                \l__nicematrix_code_for_last_col_tl
+                \xglobal \colorlet { nicematrix-last-col } { . }
+              }
           }
-          { \l__nicematrix_code_for_last_col_tl }
       }
     l
     <
@@ -1076,44 +1142,17 @@
         \hbox_set_end:
         \__nicematrix_update_for_first_and_last_row:
         \dim_gset:Nn \g__nicematrix_width_last_col_dim
-           {
-             \dim_max:nn
-               \g__nicematrix_width_last_col_dim
-               { \box_wd:N \l__nicematrix_cell_box }
-           }
-        \skip_horizontal:n { - 2 \arraycolsep }
+          { \dim_max:nn \g__nicematrix_width_last_col_dim { \box_wd:N \l__nicematrix_cell_box } }
+        \skip_horizontal:N -2\arraycolsep
         \hbox_overlap_right:n
           {
-            \skip_horizontal:n
+            \dim_compare:nNnT { \box_wd:N \l__nicematrix_cell_box } > \c_zero_dim
               {
-                \l__nicematrix_right_delim_dim +
-                \l__nicematrix_right_margin_dim +
-                \l__nicematrix_extra_right_margin_dim
+                \skip_horizontal:N \l__nicematrix_right_delim_dim
+                \skip_horizontal:N \l__nicematrix_right_margin_dim
+                \skip_horizontal:N \l__nicematrix_extra_right_margin_dim
+                \__nicematrix_node_for_the_cell:
               }
-            \tikz
-              [
-                remember~picture ,
-                inner~sep = \c_zero_dim ,
-                minimum~width = \c_zero_dim ,
-                baseline
-              ]
-            \node
-              [
-                anchor = base ,
-                name =
-                  nm -
-                  \int_use:N \g__nicematrix_env_int -
-                  \int_use:N \c at iRow -
-                  \int_use:N \c at jCol ,
-                alias =
-                  \str_if_empty:NF \l__nicematrix_name_str
-                    {
-                      \l__nicematrix_name_str -
-                      \int_use:N \c at iRow -
-                      \int_use:N \c at jCol
-                    }
-              ]
-              { \box_use_drop:N \l__nicematrix_cell_box } ;
           }
       }
   }
@@ -1170,19 +1209,24 @@
     \NewDocumentEnvironment { #1 NiceMatrix } { ! O { } }
       {
         \str_gset:Nn \g__nicematrix_name_env_str { #1 NiceMatrix }
+        \tl_set:Nn \l__nicematrix_type_of_col_tl C
         \keys_set:nn { NiceMatrix / NiceMatrix } { ##1 }
-        \begin { #1 NiceArray }
+        \exp_args:Nnx \__nicematrix_begin_of_NiceMatrix:nn { #1 } \l__nicematrix_type_of_col_tl
+      }
+      { \end { #1 NiceArray } }
+  }
+\cs_new_protected:Npn \__nicematrix_begin_of_NiceMatrix:nn #1 #2
+  {
+    \begin { #1 NiceArray }
+      {
+        *
           {
-            *
-              {
-                \int_compare:nNnTF \l__nicematrix_last_col_int = { -1 }
-                  \c at MaxMatrixCols
-                  { \int_eval:n { \l__nicematrix_last_col_int - 1 } }
-              }
-              C
+            \int_compare:nNnTF \l__nicematrix_last_col_int = { -1 }
+              \c at MaxMatrixCols
+              { \int_eval:n { \l__nicematrix_last_col_int - 1 } }
           }
+          #2
       }
-      { \end { #1 NiceArray } }
   }
 \__nicematrix_define_env:n { }
 \__nicematrix_define_env:n p
@@ -1190,63 +1234,17 @@
 \__nicematrix_define_env:n B
 \__nicematrix_define_env:n v
 \__nicematrix_define_env:n V
-\prg_set_conditional:Npnn \__nicematrix_if_not_empty_cell:nn #1 #2 { T , TF }
+\cs_new_protected:Npn \__nicematrix_after_array:
   {
-    \bool_set_false:N \l_tmpa_bool
-    \cs_if_exist:cTF
-      { __nicematrix _ dotted _ \int_use:N #1 - \int_use:N #2 }
-      \prg_return_true:
+    \group_begin:
+    \int_compare:nNnT \l__nicematrix_last_col_int = 0
       {
-        \cs_if_free:cTF
-          {
-            pgf at sh@ns at nm -
-            \int_use:N \g__nicematrix_env_int -
-            \int_use:N #1 -
-            \int_use:N #2
-          }
-          { \prg_return_false: }
-          {
-            \bool_set_false:N \l_tmpa_bool
-            \cs_if_exist:cT
-              { __nicematrix _ empty _ \int_use:N #1 - \int_use:N #2 }
-              {
-                \int_compare:nNnT
-                  { \use:c { __nicematrix _ empty _ \int_use:N #1 - \int_use:N #2 } }
-                  =
-                  \g__nicematrix_env_int
-                { \bool_set_true:N \l_tmpa_bool }
-              }
-            \bool_if:NTF \l_tmpa_bool
-              \prg_return_false:
-              {
-                \begin { pgfpicture }
-                \tl_set:Nx \l_tmpa_tl
-                   {
-                     nm -
-                     \int_use:N \g__nicematrix_env_int -
-                     \int_use:N #1 -
-                     \int_use:N #2
-                   }
-                \pgfpointanchor \l_tmpa_tl { east }
-                \dim_gset:Nn \g_tmpa_dim \pgf at x
-                \pgfpointanchor \l_tmpa_tl { west }
-                \dim_gset:Nn \g_tmpb_dim \pgf at x
-                \end { pgfpicture }
-                \dim_compare:nNnTF
-                  { \dim_abs:n { \g_tmpb_dim - \g_tmpa_dim } } < { 0.5 pt }
-                  \prg_return_false:
-                  \prg_return_true:
-              }
-          }
+        \bool_if:NT \g__nicematrix_last_col_found_bool
+          { \dim_set_eq:NN \l__nicematrix_last_col_int \g__nicematrix_col_total_int }
       }
-  }
-\cs_new_protected:Npn \__nicematrix_after_array:
-  {
-    \group_begin:
-    \cs_if_exist:NT \tikz at library@external at loaded
-      { \tikzset { external / export = false } }
     \bool_if:NT \l__nicematrix_last_row_without_value_bool
       {
+        \dim_set_eq:NN \l__nicematrix_last_row_int \g__nicematrix_row_total_int
         \iow_now:Nn \@mainaux \ExplSyntaxOn
         \iow_now:Nx \@mainaux
           {
@@ -1265,20 +1263,20 @@
       }
     \bool_if:NT \l__nicematrix_parallelize_diags_bool
       {
-        \int_zero_new:N \l__nicematrix_ddots_int
-        \int_zero_new:N \l__nicematrix_iddots_int
-        \dim_zero_new:N \l__nicematrix_delta_x_one_dim
-        \dim_zero_new:N \l__nicematrix_delta_y_one_dim
-        \dim_zero_new:N \l__nicematrix_delta_x_two_dim
-        \dim_zero_new:N \l__nicematrix_delta_y_two_dim
+        \int_gzero_new:N \g__nicematrix_ddots_int
+        \int_gzero_new:N \g__nicematrix_iddots_int
+        \dim_gzero_new:N \g__nicematrix_delta_x_one_dim
+        \dim_gzero_new:N \g__nicematrix_delta_y_one_dim
+        \dim_gzero_new:N \g__nicematrix_delta_x_two_dim
+        \dim_gzero_new:N \g__nicematrix_delta_y_two_dim
       }
-    \bool_if:nTF \g__nicematrix_medium_nodes_bool
+    \bool_if:nTF \l__nicematrix_medium_nodes_bool
       {
-        \bool_if:NTF \g__nicematrix_large_nodes_bool
+        \bool_if:NTF \l__nicematrix_large_nodes_bool
           \__nicematrix_create_medium_and_large_nodes:
           \__nicematrix_create_medium_nodes:
       }
-      { \bool_if:NT \g__nicematrix_large_nodes_bool \__nicematrix_create_large_nodes: }
+      { \bool_if:NT \l__nicematrix_large_nodes_bool \__nicematrix_create_large_nodes: }
     \int_zero_new:N \l__nicematrix_initial_i_int
     \int_zero_new:N \l__nicematrix_initial_j_int
     \int_zero_new:N \l__nicematrix_final_i_int
@@ -1289,24 +1287,25 @@
       {
         \dim_set:Nn \l__nicematrix_radius_dim { 0.37 pt }
         \dim_set:Nn \l__nicematrix_inter_dots_dim { 0.25 em }
+        \dim_set:Nn \l__nicematrix_xdots_shorten_dim { 0.6 \l__nicematrix_xdots_shorten_dim }
       }
-    \g__nicematrix_Hdotsfor_lines_tl
-    \g__nicematrix_Vdots_lines_tl
-    \g__nicematrix_Ddots_lines_tl
-    \g__nicematrix_Iddots_lines_tl
-    \g__nicematrix_Cdots_lines_tl
-    \g__nicematrix_Ldots_lines_tl
-    \tikzset
+    \__nicematrix_draw_dotted_lines:
+    \bool_if:NT \l__nicematrix_vlines_bool \__nicematrix_draw_vlines:
+    \g__nicematrix_internal_code_after_tl
+    \tl_gclear:N \g__nicematrix_internal_code_after_tl
+    \bool_if:NT \c__nicematrix_tikz_loaded_bool
       {
-        every~picture / .style =
+        \tikzset
           {
-            overlay ,
-            remember~picture ,
-            name~prefix = nm - \int_use:N \g__nicematrix_env_int -
+            every~picture / .style =
+              {
+                overlay ,
+                remember~picture ,
+                name~prefix = \__nicematrix_env: -
+              }
           }
       }
-    \bool_if:NT \l__nicematrix_vlines_bool \__nicematrix_draw_vlines:
-    \cs_set_eq:NN \line \__nicematrix_line:nn
+    \cs_set_eq:NN \line \__nicematrix_line
     \g__nicematrix_code_after_tl
     \tl_gclear:N \g__nicematrix_code_after_tl
     \group_end:
@@ -1313,36 +1312,26 @@
     \str_gclear:N \g__nicematrix_name_env_str
     \__nicematrix_restore_iRow_jCol:
   }
-\cs_new_protected:Npn \__nicematrix_draw_vlines:
+\AtBeginDocument
   {
-    \group_begin:
-    \bool_if:NT \c__nicematrix_colortbl_loaded_bool \CT at arc@
-    \begin { tikzpicture } [ line~width = \arrayrulewidth ]
-    \__nicematrix_extract_coords:w ( row - 1 )
-    \dim_set_eq:NN \l_tmpa_dim \pgf at y
-    \__nicematrix_extract_coords:w ( row - \int_eval:n { \c at iRow + 1 } )
-    \dim_set:Nn \l_tmpa_dim { \l_tmpa_dim - \pgf at y  }
-    \dim_zero:N \l_tmpb_dim
-    \int_compare:nNnT \l__nicematrix_last_row_int > { -1 }
+    \cs_new_protected:Npx \__nicematrix_draw_dotted_lines:
       {
-        \dim_set:Nn \l_tmpb_dim
-          { \g__nicematrix_dp_last_row_dim + \g__nicematrix_ht_last_row_dim }
-        \__nicematrix_extract_coords:w ( row - \int_eval:n { \c at iRow + 1 } )
-        \dim_add:Nn \l_tmpa_dim \pgf at y
-        \__nicematrix_extract_coords:w ( row - \int_eval:n { \g__nicematrix_row_total_int + 1 } )
-        \dim_sub:Nn \l_tmpa_dim \pgf at y
-        \dim_sub:Nn \l_tmpa_dim \l_tmpb_dim
-       }
-    \int_step_inline:nnn
-      { \bool_if:NTF \l__nicematrix_NiceArray_bool 1 2 }
-      { \bool_if:NTF \l__nicematrix_NiceArray_bool { \c at jCol + 1 } \c at jCol }
-      {
-        \draw ( col - ##1 ) ++ ( 0 , \dim_use:N \l_tmpb_dim )
-                         -- ++ ( 0 , \dim_use:N \l_tmpa_dim ) ;
+        \c__nicematrix_pgfortikzpicture_tl
+        \__nicematrix_draw_dotted_lines_i:
+        \c__nicematrix_endpgfortikzpicture_tl
       }
-    \end { tikzpicture }
-    \group_end:
   }
+\cs_new_protected:Npn \__nicematrix_draw_dotted_lines_i:
+  {
+    \pgfrememberpicturepositiononpagetrue
+    \pgf at relevantforpicturesizefalse
+    \g__nicematrix_Hdotsfor_lines_tl
+    \g__nicematrix_Vdots_lines_tl
+    \g__nicematrix_Ddots_lines_tl
+    \g__nicematrix_Iddots_lines_tl
+    \g__nicematrix_Cdots_lines_tl
+    \g__nicematrix_Ldots_lines_tl
+  }
 \cs_new_protected:Npn \__nicematrix_restore_iRow_jCol:
   {
     \cs_if_exist:NT \theiRow { \int_gset_eq:NN \c at iRow \l__nicematrix_save_iRow_int }
@@ -1387,34 +1376,38 @@
             \bool_set_true:N \l__nicematrix_stop_loop_bool
           }
           {
-            \__nicematrix_if_not_empty_cell:nnTF \l__nicematrix_final_i_int \l__nicematrix_final_j_int
-              { \bool_set_true:N \l__nicematrix_stop_loop_bool }
+            \cs_if_exist:cTF
               {
-                \cs_set:cpn
+                __nicematrix _ dotted _
+                \int_use:N \l__nicematrix_final_i_int -
+                \int_use:N \l__nicematrix_final_j_int
+              }
+              {
+                \int_sub:Nn \l__nicematrix_final_i_int { #3 }
+                \int_sub:Nn \l__nicematrix_final_j_int { #4 }
+                \bool_set_true:N \l__nicematrix_final_open_bool
+                \bool_set_true:N \l__nicematrix_stop_loop_bool
+              }
+              {
+                \cs_if_exist:cTF
                   {
-                    __nicematrix _ dotted _
-                    \int_use:N \l__nicematrix_final_i_int -
-                    \int_use:N \l__nicematrix_final_j_int
+                    pgf @ sh @ ns @ \__nicematrix_env:
+                    - \int_use:N \l__nicematrix_final_i_int
+                    - \int_use:N \l__nicematrix_final_j_int
                   }
-                  { }
+                  { \bool_set_true:N \l__nicematrix_stop_loop_bool }
+                  {
+                    \cs_set:cpn
+                      {
+                        __nicematrix _ dotted _
+                        \int_use:N \l__nicematrix_final_i_int -
+                        \int_use:N \l__nicematrix_final_j_int
+                      }
+                      { }
+                  }
               }
           }
       }
-    \cs_if_free:cT
-      {
-        pgf at sh@ns at nm -
-        \int_use:N \g__nicematrix_env_int -
-        \int_use:N \l__nicematrix_final_i_int -
-        \int_use:N \l__nicematrix_final_j_int
-      }
-      {
-        \bool_if:NF \l__nicematrix_final_open_bool
-          {
-            \msg_error:nnx { nicematrix } { Impossible~line }
-              { \int_use:N \l__nicematrix_final_i_int }
-            \bool_set_true:N \l__nicematrix_impossible_line_bool
-          }
-      }
     \bool_set_false:N \l__nicematrix_stop_loop_bool
     \bool_do_until:Nn \l__nicematrix_stop_loop_bool
       {
@@ -1447,415 +1440,500 @@
             \bool_set_true:N \l__nicematrix_stop_loop_bool
           }
           {
-            \__nicematrix_if_not_empty_cell:nnTF
-              \l__nicematrix_initial_i_int \l__nicematrix_initial_j_int
-              { \bool_set_true:N \l__nicematrix_stop_loop_bool }
+            \cs_if_exist:cTF
               {
-                \cs_set:cpn
+                __nicematrix _ dotted _
+                \int_use:N \l__nicematrix_initial_i_int -
+                \int_use:N \l__nicematrix_initial_j_int
+              }
+              {
+                \int_add:Nn \l__nicematrix_initial_i_int { #3 }
+                \int_add:Nn \l__nicematrix_initial_j_int { #4 }
+                \bool_set_true:N \l__nicematrix_initial_open_bool
+                \bool_set_true:N \l__nicematrix_stop_loop_bool
+              }
+              {
+                \cs_if_exist:cTF
                   {
-                    __nicematrix _ dotted _
-                    \int_use:N \l__nicematrix_initial_i_int -
-                    \int_use:N \l__nicematrix_initial_j_int
+                    pgf @ sh @ ns @ \__nicematrix_env:
+                    - \int_use:N \l__nicematrix_initial_i_int
+                    - \int_use:N \l__nicematrix_initial_j_int
                   }
-                  { }
+                  { \bool_set_true:N \l__nicematrix_stop_loop_bool }
+                  {
+                    \cs_set:cpn
+                      {
+                        __nicematrix _ dotted _
+                        \int_use:N \l__nicematrix_initial_i_int -
+                        \int_use:N \l__nicematrix_initial_j_int
+                      }
+                      { }
+                  }
               }
           }
       }
-    \cs_if_free:cT
-      {
-        pgf at sh@ns at nm -
-        \int_use:N \g__nicematrix_env_int -
-        \int_use:N \l__nicematrix_initial_i_int -
-        \int_use:N \l__nicematrix_initial_j_int
-      }
-      {
-        \bool_if:NF \l__nicematrix_initial_open_bool
-          {
-            \msg_error:nnx { nicematrix } { Impossible~line }
-              { \int_use:N \l__nicematrix_initial_i_int }
-            \bool_set_true:N \l__nicematrix_impossible_line_bool
-          }
-      }
-    \bool_if:NT \l__nicematrix_initial_open_bool \__nicematrix_create_medium_nodes:
-    \bool_if:NT \l__nicematrix_final_open_bool \__nicematrix_create_medium_nodes:
   }
-\cs_new_protected:Npn \__nicematrix_retrieve_coords:nn #1 #2
+\cs_new:Nn \__nicematrix_initial_cell:
+  { \__nicematrix_env: - \int_use:N \l__nicematrix_initial_i_int - \int_use:N \l__nicematrix_initial_j_int }
+\cs_new:Nn \__nicematrix_final_cell:
+  { \__nicematrix_env: - \int_use:N \l__nicematrix_final_i_int - \int_use:N \l__nicematrix_final_j_int }
+\cs_new_protected:Npn \__nicematrix_set_initial_coords:
   {
-    \dim_gzero_new:N \g__nicematrix_x_initial_dim
-    \dim_gzero_new:N \g__nicematrix_y_initial_dim
-    \dim_gzero_new:N \g__nicematrix_x_final_dim
-    \dim_gzero_new:N \g__nicematrix_y_final_dim
-    \begin { tikzpicture } [ remember~picture ]
-      \__nicematrix_extract_coords:w
-        ( nm - \int_use:N \g__nicematrix_env_int -
-               \int_use:N \l__nicematrix_initial_i_int -
-               \int_use:N \l__nicematrix_initial_j_int #1 )
-      \dim_gset:Nn \g__nicematrix_x_initial_dim \pgf at x
-      \dim_gset:Nn \g__nicematrix_y_initial_dim \pgf at y
-      \__nicematrix_extract_coords:w
-        ( nm - \int_use:N \g__nicematrix_env_int -
-               \int_use:N \l__nicematrix_final_i_int -
-               \int_use:N \l__nicematrix_final_j_int #2 )
-      \dim_gset:Nn \g__nicematrix_x_final_dim \pgf at x
-      \dim_gset:Nn \g__nicematrix_y_final_dim \pgf at y
-    \end { tikzpicture }
+    \dim_set_eq:NN \l__nicematrix_x_initial_dim \pgf at x
+    \dim_set_eq:NN \l__nicematrix_y_initial_dim \pgf at y
   }
-\cs_generate_variant:Nn \__nicematrix_retrieve_coords:nn { x x }
-\cs_new_protected:Npn \__nicematrix_adjust_with_col_nodes:
+\cs_new_protected:Npn \__nicematrix_set_final_coords:
   {
-    \bool_if:NT \l__nicematrix_initial_open_bool
+    \dim_set_eq:NN \l__nicematrix_x_final_dim \pgf at x
+    \dim_set_eq:NN \l__nicematrix_y_final_dim \pgf at y
+  }
+\cs_new_protected:Npn \__nicematrix_set_initial_coords_from_anchor:n #1
+  {
+    \pgfpointanchor \__nicematrix_initial_cell: { #1 }
+    \__nicematrix_set_initial_coords:
+  }
+\cs_new_protected:Npn \__nicematrix_set_final_coords_from_anchor:n #1
+  {
+    \pgfpointanchor \__nicematrix_final_cell: { #1 }
+    \__nicematrix_set_final_coords:
+  }
+\cs_new_protected:Npn \__nicematrix_draw_Ldots:nnn #1 #2 #3
+  {
+    \cs_if_free:cT { __nicematrix _ dotted _ #1 - #2 }
       {
-        \begin { tikzpicture } [ remember~picture ]
-        \__nicematrix_extract_coords:w ( nm - \int_use:N \g__nicematrix_env_int - col - 1 )
-        \dim_gset:Nn \g__nicematrix_x_initial_dim \pgf at x
-        \end { tikzpicture }
+        \__nicematrix_find_extremities_of_line:nnnn { #1 } { #2 } 0 1
+        \group_begin:
+          \int_compare:nNnTF { #1 } = 0
+            { \color { nicematrix-first-row } }
+            {
+              \int_compare:nNnT { #1 } = \l__nicematrix_last_row_int
+                { \color { nicematrix-last-row } }
+            }
+          \keys_set:nn { NiceMatrix / xdots } { #3 }
+          \tl_if_empty:VF \l__nicematrix_xdots_color_tl { \color { \l__nicematrix_xdots_color_tl } }
+          \__nicematrix_actually_draw_Ldots:
+        \group_end:
       }
-    \bool_if:NT \l__nicematrix_final_open_bool
+  }
+\cs_new_protected:Npn \__nicematrix_actually_draw_Ldots:
+  {
+    \bool_if:NTF \l__nicematrix_initial_open_bool
       {
-        \begin { tikzpicture } [ remember~picture ]
-        \__nicematrix_extract_coords:w
-          ( nm - \int_use:N \g__nicematrix_env_int - col - \int_eval:n { \c at jCol + 1 } )
-        \dim_gset:Nn \g__nicematrix_x_final_dim \pgf at x
-        \end { tikzpicture }
+        \__nicematrix_qpoint: { col - \int_use:N \l__nicematrix_initial_j_int }
+        \dim_set_eq:NN \l__nicematrix_x_initial_dim \pgf at x
+        \dim_add:Nn \l__nicematrix_x_initial_dim \arraycolsep
+        \__nicematrix_qpoint: { row - \int_use:N \l__nicematrix_initial_i_int - base }
+        \dim_set_eq:NN \l__nicematrix_y_initial_dim \pgf at y
       }
+      { \__nicematrix_set_initial_coords_from_anchor:n { base~east } }
+    \bool_if:NTF \l__nicematrix_final_open_bool
+      {
+        \__nicematrix_qpoint: { col - \__nicematrix_succ:N \l__nicematrix_final_j_int }
+        \dim_set_eq:NN \l__nicematrix_x_final_dim \pgf at x
+        \dim_sub:Nn \l__nicematrix_x_final_dim \arraycolsep
+        \__nicematrix_qpoint: { row - \int_use:N \l__nicematrix_final_i_int - base }
+        \dim_set_eq:NN \l__nicematrix_y_final_dim \pgf at y
+      }
+      { \__nicematrix_set_final_coords_from_anchor:n { base~west } }
+    \dim_add:Nn \l__nicematrix_y_initial_dim \l__nicematrix_radius_dim
+    \dim_add:Nn \l__nicematrix_y_final_dim \l__nicematrix_radius_dim
+    \__nicematrix_draw_line:
   }
-\cs_new_protected:Npn \__nicematrix_draw_Ldots:nn #1 #2
+\cs_new_protected:Npn \__nicematrix_draw_Cdots:nnn #1 #2 #3
   {
     \cs_if_free:cT { __nicematrix _ dotted _ #1 - #2 }
       {
-        \bool_set_false:N \l__nicematrix_impossible_line_bool
         \__nicematrix_find_extremities_of_line:nnnn { #1 } { #2 } 0 1
-        \bool_if:NF \l__nicematrix_impossible_line_bool \__nicematrix_actually_draw_Ldots:
+        \group_begin:
+          \int_compare:nNnTF { #1 } = 0
+            { \color { nicematrix-first-row } }
+            {
+              \int_compare:nNnT { #1 } = \l__nicematrix_last_row_int
+                { \color { nicematrix-last-row } }
+            }
+          \keys_set:nn { NiceMatrix / xdots } { #3 }
+          \tl_if_empty:VF \l__nicematrix_xdots_color_tl { \color { \l__nicematrix_xdots_color_tl } }
+          \__nicematrix_actually_draw_Cdots:
+        \group_end:
       }
   }
-\cs_new_protected:Npn \__nicematrix_actually_draw_Ldots:
+\cs_new_protected:Npn \__nicematrix_actually_draw_Cdots:
   {
-    \__nicematrix_retrieve_coords:xx
+    \bool_if:NTF \l__nicematrix_initial_open_bool
       {
-        \bool_if:NTF \l__nicematrix_initial_open_bool
-          { - medium.base~west }
-          { .base~east }
+        \__nicematrix_qpoint: { col - \int_use:N \l__nicematrix_initial_j_int }
+        \dim_set_eq:NN \l__nicematrix_x_initial_dim \pgf at x
+        \dim_add:Nn \l__nicematrix_x_initial_dim \arraycolsep
       }
+      { \__nicematrix_set_initial_coords_from_anchor:n { mid~east } }
+    \bool_if:NTF \l__nicematrix_final_open_bool
       {
-        \bool_if:NTF \l__nicematrix_final_open_bool
-          { - medium.base~east }
-          { .base~west }
+        \__nicematrix_qpoint: { col - \__nicematrix_succ:N \l__nicematrix_final_j_int }
+        \dim_set_eq:NN \l__nicematrix_x_final_dim \pgf at x
+        \dim_sub:Nn \l__nicematrix_x_final_dim \arraycolsep
       }
-    \__nicematrix_adjust_with_col_nodes:
-    \bool_if:NT \l__nicematrix_initial_open_bool
-      { \dim_gset_eq:NN \g__nicematrix_y_initial_dim \g__nicematrix_y_final_dim }
-    \bool_if:NT \l__nicematrix_final_open_bool
-      { \dim_gset_eq:NN \g__nicematrix_y_final_dim \g__nicematrix_y_initial_dim }
-    \dim_gadd:Nn \g__nicematrix_y_initial_dim { 0.53 pt }
-    \dim_gadd:Nn \g__nicematrix_y_final_dim { 0.53 pt }
-    \__nicematrix_draw_tikz_line:
+      { \__nicematrix_set_final_coords_from_anchor:n { mid~west } }
+    \bool_lazy_and:nnTF
+      \l__nicematrix_initial_open_bool
+      \l__nicematrix_final_open_bool
+      {
+        \__nicematrix_qpoint: { row - \int_use:N \l__nicematrix_initial_i_int }
+        \dim_set_eq:NN \l_tmpa_dim \pgf at y
+        \__nicematrix_qpoint: { row - \__nicematrix_succ:N \l__nicematrix_initial_i_int }
+        \dim_set:Nn \l__nicematrix_y_initial_dim { ( \l_tmpa_dim + \pgf at y ) / 2 }
+        \dim_set_eq:NN \l__nicematrix_y_final_dim \l__nicematrix_y_initial_dim
+      }
+      {
+        \bool_if:NT \l__nicematrix_initial_open_bool
+          { \dim_set_eq:NN \l__nicematrix_y_initial_dim \l__nicematrix_y_final_dim }
+        \bool_if:NT \l__nicematrix_final_open_bool
+          { \dim_set_eq:NN \l__nicematrix_y_final_dim \l__nicematrix_y_initial_dim }
+      }
+    \__nicematrix_draw_line:
   }
-\cs_new_protected:Npn \__nicematrix_draw_Cdots:nn #1 #2
+\cs_new_protected:Npn \__nicematrix_draw_Vdots:nnn #1 #2 #3
   {
+    \tl_if_empty:VF \l__nicematrix_xdots_color_tl { \color { \l__nicematrix_xdots_color_tl } }
     \cs_if_free:cT { __nicematrix _ dotted _ #1 - #2 }
       {
-        \bool_set_false:N \l__nicematrix_impossible_line_bool
-        \__nicematrix_find_extremities_of_line:nnnn { #1 } { #2 } 0 1
-        \bool_if:NF \l__nicematrix_impossible_line_bool
-          {
-            \__nicematrix_retrieve_coords:xx
-              {
-                \bool_if:NTF \l__nicematrix_initial_open_bool
-                  { - medium.mid~west }
-                  { .mid~east }
-              }
-              {
-                \bool_if:NTF \l__nicematrix_final_open_bool
-                  { - medium.mid~east }
-                  { .mid~west }
-              }
-            \__nicematrix_adjust_with_col_nodes:
-            \bool_if:NT \l__nicematrix_initial_open_bool
-              { \dim_gset_eq:NN \g__nicematrix_y_initial_dim \g__nicematrix_y_final_dim }
-            \bool_if:NT \l__nicematrix_final_open_bool
-              { \dim_gset_eq:NN \g__nicematrix_y_final_dim \g__nicematrix_y_initial_dim }
-            \__nicematrix_draw_tikz_line:
-          }
+        \__nicematrix_find_extremities_of_line:nnnn { #1 } { #2 } 1 0
+        \group_begin:
+          \int_compare:nNnTF { #2 } = 0
+            { \color { nicematrix-first-col } }
+            {
+              \int_compare:nNnT { #2 } = \l__nicematrix_last_col_int
+                { \color { nicematrix-last-col } }
+            }
+          \keys_set:nn { NiceMatrix / xdots } { #3 }
+          \__nicematrix_actually_draw_Vdots:
+        \group_end:
       }
   }
-\cs_new_protected:Npn \__nicematrix_draw_Vdots:nn #1 #2
+\cs_new_protected:Npn \__nicematrix_actually_draw_Vdots:
   {
-    \cs_if_free:cT { __nicematrix _ dotted _ #1 - #2 }
+    \bool_set_false:N \l_tmpa_bool
+    \bool_lazy_or:nnF \l__nicematrix_initial_open_bool \l__nicematrix_final_open_bool
       {
-        \bool_set_false:N \l__nicematrix_impossible_line_bool
-        \__nicematrix_find_extremities_of_line:nnnn { #1 } { #2 } 1 0
-        \bool_if:NF \l__nicematrix_impossible_line_bool
+        \__nicematrix_set_initial_coords_from_anchor:n { south~west }
+        \__nicematrix_set_final_coords_from_anchor:n { north~west }
+        \bool_set:Nn \l_tmpa_bool
+          { \dim_compare_p:nNn \l__nicematrix_x_initial_dim = \l__nicematrix_x_final_dim }
+      }
+    \bool_if:NTF \l__nicematrix_initial_open_bool
+      {
+        \__nicematrix_qpoint: { row - 1 }
+        \dim_set_eq:NN \l__nicematrix_y_initial_dim \pgf at y
+      }
+      { \__nicematrix_set_initial_coords_from_anchor:n { south } }
+    \bool_if:NTF \l__nicematrix_final_open_bool
+      {
+        \__nicematrix_qpoint: { row - \__nicematrix_succ:N \c at iRow }
+        \dim_set_eq:NN \l__nicematrix_y_final_dim \pgf at y
+      }
+      { \__nicematrix_set_final_coords_from_anchor:n { north } }
+    \bool_if:NTF \l__nicematrix_initial_open_bool
+      {
+        \bool_if:NTF \l__nicematrix_final_open_bool
           {
-            \__nicematrix_retrieve_coords:xx
+            \__nicematrix_qpoint: { col - \int_use:N \l__nicematrix_initial_j_int }
+            \dim_set_eq:NN \l_tmpa_dim \pgf at x
+            \__nicematrix_qpoint: { col - \__nicematrix_succ:N \l__nicematrix_initial_j_int }
+            \dim_set:Nn \l__nicematrix_x_initial_dim { ( \pgf at x + \l_tmpa_dim ) / 2 }
+            \dim_set_eq:NN \l__nicematrix_x_final_dim \l__nicematrix_x_initial_dim
+          }
+          { \dim_set_eq:NN \l__nicematrix_x_initial_dim \l__nicematrix_x_final_dim }
+      }
+      {
+        \bool_if:NTF \l__nicematrix_final_open_bool
+          { \dim_set_eq:NN \l__nicematrix_x_final_dim \l__nicematrix_x_initial_dim }
+          {
+            \dim_compare:nNnF \l__nicematrix_x_initial_dim = \l__nicematrix_x_final_dim
               {
-                \bool_if:NTF \l__nicematrix_initial_open_bool
-                  { - medium.north~west }
-                  { .south~west }
-              }
-              {
-                \bool_if:NTF \l__nicematrix_final_open_bool
-                  { - medium.south~west }
-                  { .north~west }
-              }
-            \bool_set:Nn \l_tmpa_bool
-              { \dim_compare_p:nNn \g__nicematrix_x_initial_dim = \g__nicematrix_x_final_dim }
-            \__nicematrix_retrieve_coords:xx
-              {
-                \bool_if:NTF \l__nicematrix_initial_open_bool
-                  { - medium.north }
-                  { .south }
-              }
-              {
-                \bool_if:NTF \l__nicematrix_final_open_bool
-                  { - medium.south }
-                  { .north }
-              }
-            \bool_set:Nn \l_tmpb_bool
-              { \dim_compare_p:nNn \g__nicematrix_x_initial_dim = \g__nicematrix_x_final_dim }
-            \bool_if:NF \l_tmpb_bool
-              {
-                \dim_gset:Nn \g__nicematrix_x_initial_dim
+                \dim_set:Nn \l__nicematrix_x_initial_dim
                   {
                     \bool_if:NTF \l_tmpa_bool \dim_min:nn \dim_max:nn
-                      \g__nicematrix_x_initial_dim \g__nicematrix_x_final_dim
+                      \l__nicematrix_x_initial_dim \l__nicematrix_x_final_dim
                   }
-                \dim_gset_eq:NN \g__nicematrix_x_final_dim \g__nicematrix_x_initial_dim
+                \dim_set_eq:NN \l__nicematrix_x_final_dim \l__nicematrix_x_initial_dim
               }
-            \__nicematrix_draw_tikz_line:
           }
       }
+    \__nicematrix_draw_line:
   }
-\cs_new_protected:Npn \__nicematrix_draw_Ddots:nn #1 #2
+\cs_new_protected:Npn \__nicematrix_draw_Ddots:nnn #1 #2 #3
   {
     \cs_if_free:cT { __nicematrix _ dotted _ #1 - #2 }
       {
-        \bool_set_false:N \l__nicematrix_impossible_line_bool
         \__nicematrix_find_extremities_of_line:nnnn { #1 } { #2 } 1 1
-        \bool_if:NF \l__nicematrix_impossible_line_bool
+        \group_begin:
+          \keys_set:nn { NiceMatrix / xdots } { #3 }
+          \tl_if_empty:VF \l__nicematrix_xdots_color_tl { \color { \l__nicematrix_xdots_color_tl } }
+          \__nicematrix_actually_draw_Ddots:
+        \group_end:
+      }
+  }
+\cs_new_protected:Npn \__nicematrix_actually_draw_Ddots:
+  {
+    \bool_if:NTF \l__nicematrix_initial_open_bool
+      {
+        \__nicematrix_qpoint: { row - \int_use:N \l__nicematrix_initial_i_int }
+        \dim_set_eq:NN \l__nicematrix_y_initial_dim \pgf at y
+        \__nicematrix_qpoint: { col - \int_use:N \l__nicematrix_initial_j_int }
+        \dim_set_eq:NN \l__nicematrix_x_initial_dim \pgf at x
+      }
+      { \__nicematrix_set_initial_coords_from_anchor:n { south~east } }
+    \bool_if:NTF \l__nicematrix_final_open_bool
+      {
+        \__nicematrix_qpoint: { row - \__nicematrix_succ:N \l__nicematrix_final_i_int }
+        \dim_set_eq:NN \l__nicematrix_y_final_dim \pgf at y
+        \__nicematrix_qpoint: { col - \__nicematrix_succ:N \l__nicematrix_final_j_int }
+        \dim_set_eq:NN \l__nicematrix_x_final_dim \pgf at x
+      }
+      { \__nicematrix_set_final_coords_from_anchor:n { north~west } }
+    \bool_if:NT \l__nicematrix_parallelize_diags_bool
+      {
+        \int_gincr:N \g__nicematrix_ddots_int
+        \int_compare:nNnTF \g__nicematrix_ddots_int = 1
           {
-            \__nicematrix_retrieve_coords:xx
+            \dim_gset:Nn \g__nicematrix_delta_x_one_dim
+              { \l__nicematrix_x_final_dim - \l__nicematrix_x_initial_dim }
+            \dim_gset:Nn \g__nicematrix_delta_y_one_dim
+              { \l__nicematrix_y_final_dim - \l__nicematrix_y_initial_dim }
+          }
+          {
+            \dim_set:Nn \l__nicematrix_y_final_dim
               {
-                \bool_if:NTF \l__nicematrix_initial_open_bool
-                  { - medium.north~west }
-                  { .south~east }
+                \l__nicematrix_y_initial_dim +
+                ( \l__nicematrix_x_final_dim - \l__nicematrix_x_initial_dim ) *
+                \dim_ratio:nn \g__nicematrix_delta_y_one_dim \g__nicematrix_delta_x_one_dim
               }
-              {
-                \bool_if:NTF \l__nicematrix_final_open_bool
-                  { - medium.south~east }
-                  { .north~west }
-              }
-            \bool_if:NT \l__nicematrix_parallelize_diags_bool
-              {
-                \int_incr:N \l__nicematrix_ddots_int
-                \int_compare:nNnTF \l__nicematrix_ddots_int = 1
-                  {
-                    \dim_set:Nn \l__nicematrix_delta_x_one_dim
-                      { \g__nicematrix_x_final_dim - \g__nicematrix_x_initial_dim }
-                    \dim_set:Nn \l__nicematrix_delta_y_one_dim
-                      { \g__nicematrix_y_final_dim - \g__nicematrix_y_initial_dim }
-                  }
-                  {
-                    \dim_gset:Nn \g__nicematrix_y_final_dim
-                      {
-                        \g__nicematrix_y_initial_dim +
-                        ( \g__nicematrix_x_final_dim - \g__nicematrix_x_initial_dim ) *
-                        \dim_ratio:nn \l__nicematrix_delta_y_one_dim \l__nicematrix_delta_x_one_dim
-                      }
-                  }
-              }
-            \__nicematrix_draw_tikz_line:
           }
       }
+    \__nicematrix_draw_line:
   }
-\cs_new_protected:Npn \__nicematrix_draw_Iddots:nn #1 #2
+\cs_new_protected:Npn \__nicematrix_draw_Iddots:nnn #1 #2 #3
   {
     \cs_if_free:cT { __nicematrix _ dotted _ #1 - #2 }
       {
-        \bool_set_false:N \l__nicematrix_impossible_line_bool
         \__nicematrix_find_extremities_of_line:nnnn { #1 } { #2 } 1 { -1 }
-        \bool_if:NF \l__nicematrix_impossible_line_bool
+        \group_begin:
+          \keys_set:nn { NiceMatrix / xdots } { #3 }
+          \tl_if_empty:VF \l__nicematrix_xdots_color_tl { \color { \l__nicematrix_xdots_color_tl } }
+          \__nicematrix_actually_draw_Iddots:
+        \group_end:
+      }
+  }
+\cs_new_protected:Npn \__nicematrix_actually_draw_Iddots:
+  {
+    \bool_if:NTF \l__nicematrix_initial_open_bool
+      {
+        \__nicematrix_qpoint: { row - \int_use:N \l__nicematrix_initial_i_int }
+        \dim_set_eq:NN \l__nicematrix_y_initial_dim \pgf at y
+        \__nicematrix_qpoint: { col - \__nicematrix_succ:N \l__nicematrix_initial_j_int }
+        \dim_set_eq:NN \l__nicematrix_x_initial_dim \pgf at x
+      }
+      { \__nicematrix_set_initial_coords_from_anchor:n { south~west } }
+    \bool_if:NTF \l__nicematrix_final_open_bool
+      {
+        \__nicematrix_qpoint: { row - \__nicematrix_succ:N \l__nicematrix_final_i_int }
+        \dim_set_eq:NN \l__nicematrix_y_final_dim \pgf at y
+        \__nicematrix_qpoint: { col - \int_use:N \l__nicematrix_final_j_int }
+        \dim_set_eq:NN \l__nicematrix_x_final_dim \pgf at x
+      }
+      { \__nicematrix_set_final_coords_from_anchor:n { north~east } }
+    \bool_if:NT \l__nicematrix_parallelize_diags_bool
+      {
+        \int_gincr:N \g__nicematrix_iddots_int
+        \int_compare:nNnTF \g__nicematrix_iddots_int = 1
           {
-            \__nicematrix_retrieve_coords:xx
+            \dim_gset:Nn \g__nicematrix_delta_x_two_dim
+              { \l__nicematrix_x_final_dim - \l__nicematrix_x_initial_dim }
+            \dim_gset:Nn \g__nicematrix_delta_y_two_dim
+              { \l__nicematrix_y_final_dim - \l__nicematrix_y_initial_dim }
+          }
+          {
+            \dim_set:Nn \l__nicematrix_y_final_dim
               {
-                \bool_if:NTF \l__nicematrix_initial_open_bool
-                  { - medium.north~east }
-                  { .south~west }
+                \l__nicematrix_y_initial_dim +
+                ( \l__nicematrix_x_final_dim - \l__nicematrix_x_initial_dim ) *
+                \dim_ratio:nn \g__nicematrix_delta_y_two_dim \g__nicematrix_delta_x_two_dim
               }
-              {
-                \bool_if:NTF \l__nicematrix_final_open_bool
-                  { - medium.south~west }
-                  { .north~east }
-              }
-            \bool_if:NT \l__nicematrix_parallelize_diags_bool
-              {
-                \int_incr:N \l__nicematrix_iddots_int
-                \int_compare:nNnTF \l__nicematrix_iddots_int = 1
-                  {
-                    \dim_set:Nn \l__nicematrix_delta_x_two_dim
-                      { \g__nicematrix_x_final_dim - \g__nicematrix_x_initial_dim }
-                    \dim_set:Nn \l__nicematrix_delta_y_two_dim
-                      { \g__nicematrix_y_final_dim - \g__nicematrix_y_initial_dim }
-                  }
-                  {
-                    \dim_gset:Nn \g__nicematrix_y_final_dim
-                       {
-                         \g__nicematrix_y_initial_dim +
-                         ( \g__nicematrix_x_final_dim - \g__nicematrix_x_initial_dim ) *
-                         \dim_ratio:nn \l__nicematrix_delta_y_two_dim \l__nicematrix_delta_x_two_dim
-                       }
-                  }
-              }
-            \__nicematrix_draw_tikz_line:
           }
       }
+    \__nicematrix_draw_line:
   }
 \NewExpandableDocumentCommand \NiceMatrixLastEnv { }
   { \int_use:N \g__nicematrix_env_int }
-\cs_new_protected:Npn \__nicematrix_draw_tikz_line:
+\cs_new_protected:Npn \__nicematrix_draw_line:
   {
-    \dim_zero_new:N \l__nicematrix_l_dim
-    \dim_set:Nn \l__nicematrix_l_dim
+    \pgfrememberpicturepositiononpagetrue
+    \pgf at relevantforpicturesizefalse
+    \tl_if_eq:NNTF \l__nicematrix_xdots_line_style_tl \c__nicematrix_standard_tl
+      \__nicematrix_draw_standard_dotted_line:
+      \__nicematrix_draw_non_standard_dotted_line:
+  }
+\cs_new_protected:Npn \__nicematrix_draw_non_standard_dotted_line:
+  {
+     \begin { scope }
+     \exp_args:No \__nicematrix_draw_non_standard_dotted_line:n
+       { \l__nicematrix_xdots_line_style_tl , \l__nicematrix_xdots_color_tl }
+  }
+\cs_new_protected:Npn \__nicematrix_draw_non_standard_dotted_line:n #1
+  {
+    \draw
+      [
+        #1 ,
+        shorten~> = \l__nicematrix_xdots_shorten_dim ,
+        shorten~< = \l__nicematrix_xdots_shorten_dim ,
+      ]
+          ( \l__nicematrix_x_initial_dim , \l__nicematrix_y_initial_dim )
+       -- ( \l__nicematrix_x_final_dim , \l__nicematrix_y_final_dim ) ;
+    \end { scope }
+  }
+\cs_new_protected:Npn \__nicematrix_draw_standard_dotted_line:
+  {
+    \pgfrememberpicturepositiononpagetrue
+    \pgf at relevantforpicturesizefalse
+    \group_begin:
+      \dim_zero_new:N \l__nicematrix_l_dim
+      \dim_set:Nn \l__nicematrix_l_dim
+        {
+          \fp_to_dim:n
+            {
+              sqrt
+               (
+                 ( \l__nicematrix_x_final_dim - \l__nicematrix_x_initial_dim ) ^ 2
+                    +
+                 ( \l__nicematrix_y_final_dim - \l__nicematrix_y_initial_dim ) ^ 2
+               )
+            }
+        }
+      \dim_compare:nNnF \l__nicematrix_l_dim = \c_zero_dim \__nicematrix_actually_draw_line:
+    \group_end:
+  }
+\cs_new_protected:Npn \__nicematrix_actually_draw_line:
+  {
+    \bool_if:NTF \l__nicematrix_initial_open_bool
       {
-        \fp_to_dim:n
+        \bool_if:NTF \l__nicematrix_final_open_bool
           {
-            sqrt
-             (
-               (   \dim_use:N \g__nicematrix_x_final_dim
-                 - \dim_use:N \g__nicematrix_x_initial_dim
-               ) ^ 2
-                  +
-               (   \dim_use:N \g__nicematrix_y_final_dim
-                 - \dim_use:N \g__nicematrix_y_initial_dim
-               ) ^ 2
-             )
+            \int_set:Nn \l_tmpa_int
+              { \dim_ratio:nn \l__nicematrix_l_dim \l__nicematrix_inter_dots_dim }
           }
+          {
+            \int_set:Nn \l_tmpa_int
+              {
+                \dim_ratio:nn
+                  { \l__nicematrix_l_dim - \l__nicematrix_xdots_shorten_dim }
+                  \l__nicematrix_inter_dots_dim
+              }
+          }
       }
-    \dim_compare:nNnF \l__nicematrix_l_dim = \c_zero_dim
       {
-        \bool_if:NTF \l__nicematrix_initial_open_bool
+        \bool_if:NTF \l__nicematrix_final_open_bool
           {
-            \bool_if:NTF \l__nicematrix_final_open_bool
+            \int_set:Nn \l_tmpa_int
               {
-                \int_set:Nn \l_tmpa_int
-                  { \dim_ratio:nn \l__nicematrix_l_dim \l__nicematrix_inter_dots_dim }
+                \dim_ratio:nn
+                  { \l__nicematrix_l_dim - \l__nicematrix_xdots_shorten_dim }
+                  \l__nicematrix_inter_dots_dim
               }
-              {
-                \int_set:Nn \l_tmpa_int
-                  {
-                    \dim_ratio:nn
-                      { \l__nicematrix_l_dim - \l__nicematrix_dotted_lines_margin_dim }
-                      \l__nicematrix_inter_dots_dim
-                  }
-              }
           }
           {
-            \bool_if:NTF \l__nicematrix_final_open_bool
+            \int_set:Nn \l_tmpa_int
               {
-                \int_set:Nn \l_tmpa_int
-                  {
-                    \dim_ratio:nn
-                      { \l__nicematrix_l_dim - \l__nicematrix_dotted_lines_margin_dim }
-                      \l__nicematrix_inter_dots_dim
-                  }
+                \dim_ratio:nn
+                  { \l__nicematrix_l_dim - ( 2 \l__nicematrix_xdots_shorten_dim ) }
+                  \l__nicematrix_inter_dots_dim
               }
-              {
-                \int_set:Nn \l_tmpa_int
-                  {
-                    \dim_ratio:nn
-                      { \l__nicematrix_l_dim - ( 2 \l__nicematrix_dotted_lines_margin_dim ) }
-                      \l__nicematrix_inter_dots_dim
-                  }
-              }
           }
-        \dim_set:Nn \l_tmpa_dim
-          {
-            ( \g__nicematrix_x_final_dim - \g__nicematrix_x_initial_dim ) *
-            \dim_ratio:nn \l__nicematrix_inter_dots_dim \l__nicematrix_l_dim
-          }
-        \dim_set:Nn \l_tmpb_dim
-          {
-            ( \g__nicematrix_y_final_dim - \g__nicematrix_y_initial_dim ) *
-            \dim_ratio:nn \l__nicematrix_inter_dots_dim \l__nicematrix_l_dim
-          }
-        \int_set:Nn \l_tmpb_int
-          {
-            \bool_if:NTF \l__nicematrix_initial_open_bool
-              { \bool_if:NTF \l__nicematrix_final_open_bool 1 0 }
-              { \bool_if:NTF \l__nicematrix_final_open_bool 2 1 }
-          }
-        \dim_gadd:Nn \g__nicematrix_x_initial_dim
-          {
-            ( \g__nicematrix_x_final_dim - \g__nicematrix_x_initial_dim ) *
-            \dim_ratio:nn
-            { \l__nicematrix_l_dim - \l__nicematrix_inter_dots_dim * \l_tmpa_int }
-            { 2 \l__nicematrix_l_dim }
-            * \l_tmpb_int
-          }
-        \dim_gadd:Nn \g__nicematrix_y_initial_dim
-          {
-            ( \g__nicematrix_y_final_dim - \g__nicematrix_y_initial_dim ) *
-            \dim_ratio:nn
-              { \l__nicematrix_l_dim - \l__nicematrix_inter_dots_dim * \l_tmpa_int }
-              { 2 \l__nicematrix_l_dim }
-            * \l_tmpb_int
-          }
-        \begin { tikzpicture } [ overlay ]
-          \int_step_inline:nnn 0 \l_tmpa_int
-            {
-              \pgfpathcircle
-                { \pgfpoint { \g__nicematrix_x_initial_dim } { \g__nicematrix_y_initial_dim } }
-                { \l__nicematrix_radius_dim }
-              \pgfusepath { fill }
-              \dim_gadd:Nn \g__nicematrix_x_initial_dim \l_tmpa_dim
-              \dim_gadd:Nn \g__nicematrix_y_initial_dim \l_tmpb_dim
-            }
-        \end { tikzpicture }
       }
+    \dim_set:Nn \l_tmpa_dim
+      {
+        ( \l__nicematrix_x_final_dim - \l__nicematrix_x_initial_dim ) *
+        \dim_ratio:nn \l__nicematrix_inter_dots_dim \l__nicematrix_l_dim
+      }
+    \dim_set:Nn \l_tmpb_dim
+      {
+        ( \l__nicematrix_y_final_dim - \l__nicematrix_y_initial_dim ) *
+        \dim_ratio:nn \l__nicematrix_inter_dots_dim \l__nicematrix_l_dim
+      }
+    \int_set:Nn \l_tmpb_int
+      {
+        \bool_if:NTF \l__nicematrix_initial_open_bool
+          { \bool_if:NTF \l__nicematrix_final_open_bool 1 0 }
+          { \bool_if:NTF \l__nicematrix_final_open_bool 2 1 }
+      }
+    \dim_gadd:Nn \l__nicematrix_x_initial_dim
+      {
+        ( \l__nicematrix_x_final_dim - \l__nicematrix_x_initial_dim ) *
+        \dim_ratio:nn
+          { \l__nicematrix_l_dim - \l__nicematrix_inter_dots_dim * \l_tmpa_int }
+          { 2 \l__nicematrix_l_dim }
+        * \l_tmpb_int
+      }
+    \dim_gadd:Nn \l__nicematrix_y_initial_dim
+      {
+        ( \l__nicematrix_y_final_dim - \l__nicematrix_y_initial_dim ) *
+        \dim_ratio:nn
+          { \l__nicematrix_l_dim - \l__nicematrix_inter_dots_dim * \l_tmpa_int }
+          { 2 \l__nicematrix_l_dim }
+        * \l_tmpb_int
+      }
+    \pgf at relevantforpicturesizefalse
+    \int_step_inline:nnn 0 \l_tmpa_int
+      {
+        \pgfpathcircle
+          { \pgfpoint \l__nicematrix_x_initial_dim \l__nicematrix_y_initial_dim }
+          { \l__nicematrix_radius_dim }
+        \dim_add:Nn \l__nicematrix_x_initial_dim \l_tmpa_dim
+        \dim_add:Nn \l__nicematrix_y_initial_dim \l_tmpb_dim
+      }
+    \pgfusepathqfill
   }
-\cs_set_eq:NN \__nicematrix_ldots \ldots
-\cs_set_eq:NN \__nicematrix_cdots \cdots
-\cs_set_eq:NN \__nicematrix_vdots \vdots
-\cs_set_eq:NN \__nicematrix_ddots \ddots
-\cs_set_eq:NN \__nicematrix_iddots \iddots
-\cs_new_protected:Npn \__nicematrix_add_to_empty_cells:
+\NewDocumentCommand \__nicematrix_Ldots { s O { } }
   {
-    \cs_gset:cpx
-      { __nicematrix _ empty _ \int_use:N \c at iRow - \int_use:N \c at jCol }
-      { \int_use:N \g__nicematrix_env_int }
-  }
-\NewDocumentCommand \__nicematrix_Ldots { s }
-  {
-    \bool_if:nF { #1 } { \__nicematrix_instruction_of_type:n { Ldots } }
+    \bool_if:nTF { #1 }
+      { \__nicematrix_error:n { starred~commands } }
+      { \__nicematrix_instruction_of_type:nn { Ldots } { #2 } }
     \bool_if:NF \l__nicematrix_nullify_dots_bool { \phantom \__nicematrix_ldots }
-    \__nicematrix_add_to_empty_cells:
+    \bool_gset_true:N \g__nicematrix_empty_cell_bool
   }
-\NewDocumentCommand \__nicematrix_Cdots { s }
+\NewDocumentCommand \__nicematrix_Cdots { s O { } }
   {
-    \bool_if:nF { #1 } { \__nicematrix_instruction_of_type:n { Cdots } }
+    \bool_if:nTF { #1 }
+      { \__nicematrix_error:n { starred~commands } }
+      { \__nicematrix_instruction_of_type:nn { Cdots } { #2 } }
     \bool_if:NF \l__nicematrix_nullify_dots_bool { \phantom \__nicematrix_cdots }
-    \__nicematrix_add_to_empty_cells:
+    \bool_gset_true:N \g__nicematrix_empty_cell_bool
   }
-\NewDocumentCommand \__nicematrix_Vdots { s }
+\NewDocumentCommand \__nicematrix_Vdots { s O { } }
   {
-    \bool_if:nF { #1 } { \__nicematrix_instruction_of_type:n { Vdots } }
+    \bool_if:nTF { #1 }
+      { \__nicematrix_error:n { starred~commands } }
+      { \__nicematrix_instruction_of_type:nn { Vdots } { #2 } }
     \bool_if:NF \l__nicematrix_nullify_dots_bool { \phantom \__nicematrix_vdots }
-    \__nicematrix_add_to_empty_cells:
+    \bool_gset_true:N \g__nicematrix_empty_cell_bool
   }
-\NewDocumentCommand \__nicematrix_Ddots { s }
+\NewDocumentCommand \__nicematrix_Ddots { s O { } }
   {
-    \bool_if:nF { #1 } { \__nicematrix_instruction_of_type:n { Ddots } }
+    \bool_if:nTF { #1 }
+      { \__nicematrix_error:n { starred~commands } }
+      { \__nicematrix_instruction_of_type:nn { Ddots } { #2 } }
     \bool_if:NF \l__nicematrix_nullify_dots_bool { \phantom \__nicematrix_ddots }
-    \__nicematrix_add_to_empty_cells:
+    \bool_gset_true:N \g__nicematrix_empty_cell_bool
   }
-\NewDocumentCommand \__nicematrix_Iddots { s }
+\NewDocumentCommand \__nicematrix_Iddots { s O { } }
   {
-    \bool_if:nF { #1 } { \__nicematrix_instruction_of_type:n { Iddots } }
+    \bool_if:nTF { #1 }
+      { \__nicematrix_error:n { starred~commands } }
+      { \__nicematrix_instruction_of_type:nn { Iddots } { #2 } }
     \bool_if:NF \l__nicematrix_nullify_dots_bool { \phantom \__nicematrix_iddots }
-    \__nicematrix_add_to_empty_cells:
+    \bool_gset_true:N \g__nicematrix_empty_cell_bool
   }
 \cs_new_protected:Npn \__nicematrix_Hspace:
   {
-   \__nicematrix_add_to_empty_cells:
+   \bool_gset_true:N \g__nicematrix_empty_cell_bool
    \hspace
   }
 \cs_set_eq:NN \__nicematrix_old_multicolumn \multicolumn
@@ -1877,28 +1955,29 @@
   }
 \bool_if:NTF \c__nicematrix_draft_bool
   {
-    \NewDocumentCommand \__nicematrix_Hdotsfor_i { O { }  m }
+    \NewDocumentCommand \__nicematrix_Hdotsfor_i { O { }  m O {  } }
       { \prg_replicate:nn { #2 - 1 } { & \multicolumn { 1 } { C } { } } }
   }
   {
-    \NewDocumentCommand \__nicematrix_Hdotsfor_i { O { }  m }
+    \NewDocumentCommand \__nicematrix_Hdotsfor_i { O { } m O { } }
       {
         \tl_gput_right:Nx \g__nicematrix_Hdotsfor_lines_tl
           {
-            \__nicematrix_Hdotsfor:nnn
+            \__nicematrix_Hdotsfor:nnnn
               { \int_use:N \c at iRow }
               { \int_use:N \c at jCol }
               { #2 }
+              { #3 }
           }
         \prg_replicate:nn { #2 - 1 } { & \multicolumn { 1 } { C } { } }
       }
   }
-\cs_new_protected:Npn \__nicematrix_Hdotsfor:nnn #1 #2 #3
+\cs_new_protected:Npn \__nicematrix_Hdotsfor:nnnn #1 #2 #3 #4
   {
     \bool_set_false:N \l__nicematrix_initial_open_bool
     \bool_set_false:N \l__nicematrix_final_open_bool
     \int_set:Nn \l__nicematrix_initial_i_int { #1 }
-    \int_set:Nn \l__nicematrix_final_i_int { #1 }
+    \int_set_eq:NN \l__nicematrix_final_i_int \l__nicematrix_initial_i_int
     \int_compare:nNnTF #2 = 1
       {
         \int_set:Nn \l__nicematrix_initial_j_int 1
@@ -1905,8 +1984,12 @@
         \bool_set_true:N \l__nicematrix_initial_open_bool
       }
       {
-        \int_set:Nn \l_tmpa_int { #2 - 1 }
-        \__nicematrix_if_not_empty_cell:nnTF \l__nicematrix_initial_i_int \l_tmpa_int
+        \cs_if_exist:cTF
+          {
+            pgf @ sh @ ns @ \__nicematrix_env:
+            - \int_use:N \l__nicematrix_initial_i_int
+            - \int_eval:n { #2 - 1 }
+          }
           { \int_set:Nn \l__nicematrix_initial_j_int { #2 - 1 } }
           {
             \int_set:Nn \l__nicematrix_initial_j_int { #2 }
@@ -1919,8 +2002,12 @@
         \bool_set_true:N \l__nicematrix_final_open_bool
       }
       {
-        \int_set:Nn \l_tmpa_int { #2 + #3 }
-        \__nicematrix_if_not_empty_cell:nnTF \l__nicematrix_final_i_int \l_tmpa_int
+        \cs_if_exist:cTF
+          {
+            pgf @ sh @ ns @ \__nicematrix_env:
+            - \int_use:N \l__nicematrix_final_i_int
+            - \int_eval:n { #2 + #3 }
+          }
           { \int_set:Nn \l__nicematrix_final_j_int { #2 + #3 } }
           {
             \int_set:Nn \l__nicematrix_final_j_int { #2 + #3 - 1 }
@@ -1927,11 +2014,16 @@
             \bool_set_true:N \l__nicematrix_final_open_bool
           }
       }
-    \bool_if:nT { \l__nicematrix_initial_open_bool || \l__nicematrix_final_open_bool }
-      \__nicematrix_create_medium_nodes:
     \group_begin:
-      \cs_set:Npn \__nicematrix_adjust_with_col_nodes: { }
-      \__nicematrix_actually_draw_Ldots:
+    \int_compare:nNnTF { #1 } = 0
+      { \color { nicematrix-first-row } }
+      {
+        \int_compare:nNnT { #1 } = \g__nicematrix_row_total_int
+          { \color { nicematrix-last-row } }
+      }
+    \keys_set:nn { NiceMatrix / xdots } { #4 }
+    \tl_if_empty:VF \l__nicematrix_xdots_color_tl { \color { \l__nicematrix_xdots_color_tl } }
+    \__nicematrix_actually_draw_Ldots:
     \group_end:
     \int_step_inline:nnn { #2 } { #2 + #3 - 1 }
       { \cs_set:cpn { __nicematrix _ dotted _ #1 - ##1 } { } }
@@ -1939,52 +2031,73 @@
 \cs_new_protected:Npn \__nicematrix_rotate: { \group_insert_after:N \__nicematrix_rotate_i: }
 \cs_new_protected:Npn \__nicematrix_rotate_i: { \group_insert_after:N \__nicematrix_rotate_ii: }
 \cs_new_protected:Npn \__nicematrix_rotate_ii: { \group_insert_after:N \__nicematrix_rotate_iii: }
-\cs_new_protected:Npn \__nicematrix_rotate_iii: { \box_rotate:Nn \l__nicematrix_cell_box { 90 } }
-\cs_new:Npn \__nicematrix_double_int_eval:n #1-#2 \q_stop
-  { \int_eval:n { #1 } - \int_eval:n { #2 } }
-\cs_new_protected:Npn \__nicematrix_line:nn #1 #2
+\cs_new_protected:Npn \__nicematrix_rotate_iii:
   {
-    \use:x
+    \box_rotate:Nn \l__nicematrix_cell_box { 90 }
+    \int_compare:nNnT \c at iRow = \l__nicematrix_last_row_int
       {
-        \__nicematrix_line_i:nn
-          { \__nicematrix_double_int_eval:n #1 \q_stop }
-          { \__nicematrix_double_int_eval:n #2 \q_stop }
+        \vbox_set_top:Nn \l__nicematrix_cell_box
+          {
+            \vbox_to_zero:n { }
+            \skip_vertical:n { - \box_ht:N \@arstrutbox + 0.8 ex }
+            \box_use:N \l__nicematrix_cell_box
+          }
       }
   }
-\cs_new_protected:Npn \__nicematrix_line_i:nn #1 #2
+\cs_new:Npn \__nicematrix_double_int_eval:n #1-#2 \q_stop
+  { \int_eval:n { #1 } - \int_eval:n { #2 } }
+\NewDocumentCommand \__nicematrix_line { O { } m m ! O { } }
   {
-    \bool_if:NF \c__nicematrix_draft_bool
+    \group_begin:
+    \keys_set:nn { NiceMatrix / xdots } { #1 , #4 }
+    \tl_if_empty:VF \l__nicematrix_xdots_color_tl { \color { \l__nicematrix_xdots_color_tl } }
+      \use:x
+        {
+          \__nicematrix_line_i:nn
+            { \__nicematrix_double_int_eval:n #2 \q_stop }
+            { \__nicematrix_double_int_eval:n #3 \q_stop }
+        }
+    \group_end:
+  }
+\bool_if:NTF \c__nicematrix_draft_bool
+  { \cs_new_protected:Npn \__nicematrix_line_i:nn #1 #2  { } }
+  {
+    \cs_new_protected:Npn \__nicematrix_line_i:nn #1 #2
       {
-        \dim_zero_new:N \g__nicematrix_x_initial_dim
-        \dim_zero_new:N \g__nicematrix_y_initial_dim
-        \dim_zero_new:N \g__nicematrix_x_final_dim
-        \dim_zero_new:N \g__nicematrix_y_final_dim
         \bool_set_false:N \l__nicematrix_initial_open_bool
         \bool_set_false:N \l__nicematrix_final_open_bool
         \bool_if:nTF
           {
-            \cs_if_exist_p:c { pgf at sh@ns at nm - \int_use:N \g__nicematrix_env_int - #1 }
-            &&
-            \cs_if_exist_p:c { pgf at sh@ns at nm - \int_use:N \g__nicematrix_env_int - #2 }
+            \cs_if_free_p:c { pgf @ sh @ ns @ \__nicematrix_env: - #1 }
+              ||
+            \cs_if_free_p:c { pgf @ sh @ ns @ \__nicematrix_env: - #2 }
           }
           {
-            \begin { tikzpicture }
-              \path~(#1)~--~(#2)~node[at~start]~(i)~{}~node[at~end]~(f)~{} ;
-              \__nicematrix_extract_coords:w ( i )
-              \dim_gset:Nn \g__nicematrix_x_initial_dim \pgf at x
-              \dim_gset:Nn \g__nicematrix_y_initial_dim \pgf at y
-              \__nicematrix_extract_coords:w ( f )
-              \dim_gset:Nn \g__nicematrix_x_final_dim \pgf at x
-              \dim_gset:Nn \g__nicematrix_y_final_dim \pgf at y
-            \end { tikzpicture }
-            \__nicematrix_draw_tikz_line:
+            \__nicematrix_error:nnn { unknown~cell~for~line~in~code-after } { #1 } { #2 }
           }
-          {
-            \__nicematrix_error:nnn { unknown~cell~for~line~in~code-after }
-              { #1 } { #2 }
-          }
+          { \__nicematrix_draw_line_ii:nn { #1 } { #2 } }
       }
   }
+\AtBeginDocument
+  {
+    \cs_new_protected:Npx \__nicematrix_draw_line_ii:nn #1 #2
+      {
+        \c__nicematrix_pgfortikzpicture_tl
+        \__nicematrix_draw_line_iii:nn { #1 } { #2 }
+        \c__nicematrix_endpgfortikzpicture_tl
+      }
+  }
+\cs_new_protected:Npn \__nicematrix_draw_line_iii:nn #1 #2
+  {
+    \pgfrememberpicturepositiononpagetrue
+    \pgfpointshapeborder { \__nicematrix_env: - #1 } { \__nicematrix_qpoint: { #2 } }
+    \dim_set_eq:NN \l__nicematrix_x_initial_dim \pgf at x
+    \dim_set_eq:NN \l__nicematrix_y_initial_dim \pgf at y
+    \pgfpointshapeborder { \__nicematrix_env: - #2 } { \__nicematrix_qpoint: { #1 } }
+    \dim_set_eq:NN \l__nicematrix_x_final_dim \pgf at x
+    \dim_set_eq:NN \l__nicematrix_y_final_dim \pgf at y
+    \__nicematrix_draw_line:
+  }
 \cs_set_eq:NN \OnlyMainNiceMatrix \use:n
 \cs_new_protected:Npn \__nicematrix_OnlyMainNiceMatrix:n #1
   {
@@ -2006,62 +2119,154 @@
   }
 \cs_new_protected:Npn \__nicematrix_vline: { \__nicematrix_OnlyMainNiceMatrix:n { \__nicematrix_vline_i: } }
 \cs_set_eq:NN \__nicematrix_vline_i: \vline
-\cs_new:Npn \__nicematrix_hdottedline:
+\cs_new_protected:Npn \__nicematrix_draw_vlines:
   {
-    \bool_if:NF \c__nicematrix_draft_bool
+    \group_begin:
+    \bool_if:NT \c__nicematrix_colortbl_loaded_bool \CT at arc@
+    \pgfpicture
+    \pgfrememberpicturepositiononpagetrue
+    \pgf at relevantforpicturesizefalse
+    \pgfsetlinewidth \arrayrulewidth
+    \__nicematrix_qpoint: {row - 1 }
+    \dim_set_eq:NN \l_tmpa_dim \pgf at y
+    \pgfusepathqfill
+    \__nicematrix_qpoint: { row - \__nicematrix_succ:N \c at iRow }
+    \dim_sub:Nn \l_tmpa_dim \pgf at y
+    \pgfusepathqfill
+    \dim_zero:N \l_tmpb_dim
+    \int_compare:nNnT \l__nicematrix_last_row_int > { -1 }
       {
-        \noalign{ \skip_vertical:n { 2 \l__nicematrix_radius_dim } }
+        \dim_set_eq:NN \l_tmpb_dim \g__nicematrix_dp_last_row_dim
+        \dim_add:Nn \l_tmpb_dim \g__nicematrix_ht_last_row_dim
+        \__nicematrix_qpoint: { row - \__nicematrix_succ:N\c at iRow }
+        \dim_add:Nn \l_tmpa_dim \pgf at y
+        \__nicematrix_qpoint: { row - \__nicematrix_succ:N \g__nicematrix_row_total_int }
+        \dim_sub:Nn \l_tmpa_dim \pgf at y
+        \dim_sub:Nn \l_tmpa_dim \l_tmpb_dim
+       }
+    \int_step_inline:nnn
+      { \bool_if:NTF \l__nicematrix_NiceArray_bool 1 2 }
+      { \bool_if:NTF \l__nicematrix_NiceArray_bool { \__nicematrix_succ:N \c at jCol } \c at jCol }
+      {
+        \pgfpathmoveto
+          {
+            \pgfpointadd
+              { \__nicematrix_qpoint: { col - ##1 } }
+              {
+                \pgfpoint
+                  {
+                    -0.5 \arrayrulewidth
+                    \int_compare:nNnT { ##1 } = 1
+                      {
+                        \int_compare:nNnT \l__nicematrix_first_col_int = 1
+                          { + \arrayrulewidth }
+                      }
+                  }
+                  { \l_tmpb_dim }
+              }
+          }
+        \pgfpathlineto
+          {
+            \pgfpointadd
+              { \__nicematrix_qpoint: { col - ##1 } }
+              {
+                \pgfpoint
+                  {
+                    -0.5 \arrayrulewidth
+                    \int_compare:nNnT { ##1 } = 1
+                      {
+                        \int_compare:nNnT \l__nicematrix_first_col_int = 1
+                          { + \arrayrulewidth }
+                      }
+                  }
+                  { \l_tmpb_dim + \l_tmpa_dim }
+              }
+          }
+      }
+    \pgfusepathqstroke
+    \endpgfpicture
+    \group_end:
+  }
+\bool_if:NTF \c__nicematrix_draft_bool
+  { \cs_new:Npn \__nicematrix_hdottedline: { } }
+  {
+    \cs_new:Npn \__nicematrix_hdottedline:
+      {
+        \noalign { \skip_vertical:N 2\l__nicematrix_radius_dim }
         \__nicematrix_hdottedline_i:
       }
   }
 \cs_new_protected:Npn \__nicematrix_hdottedline_i:
   {
-    \tl_gput_right:Nx \g__nicematrix_code_after_tl
+    \tl_gput_right:Nx \g__nicematrix_internal_code_after_tl
       { \__nicematrix_hdottedline:n { \int_use:N \c at iRow } }
   }
-\cs_new_protected:Npn \__nicematrix_hdottedline:n #1
+\AtBeginDocument
   {
-    \dim_zero_new:N \g__nicematrix_x_initial_dim
-    \dim_zero_new:N \g__nicematrix_y_initial_dim
-    \dim_zero_new:N \g__nicematrix_x_final_dim
-    \dim_zero_new:N \g__nicematrix_y_final_dim
-    \bool_set_true:N \l__nicematrix_initial_open_bool
-    \bool_set_true:N \l__nicematrix_final_open_bool
-    \begin { tikzpicture } [ remember~picture ]
-      \__nicematrix_extract_coords:w ( row - #1 )
-      \dim_gset:Nn \g__nicematrix_y_initial_dim { \pgf at y - \l__nicematrix_radius_dim }
-      \dim_gset:Nn \g__nicematrix_y_final_dim { \pgf at y - \l__nicematrix_radius_dim }
-      \__nicematrix_extract_coords:w ( col - 1 )
-      \dim_gset:Nn \g__nicematrix_x_initial_dim \pgf at x
-      \__nicematrix_extract_coords:w ( col - \int_eval:n { \c at jCol + 1 } )
-      \dim_gset:Nn \g__nicematrix_x_final_dim \pgf at x
-    \end { tikzpicture }
-    \__nicematrix_draw_tikz_line:
+    \cs_new_protected:Npx \__nicematrix_hdottedline:n #1
+      {
+        \bool_set_true:N \exp_not:N \l__nicematrix_initial_open_bool
+        \bool_set_true:N \exp_not:N \l__nicematrix_final_open_bool
+        \c__nicematrix_pgfortikzpicture_tl
+        \__nicematrix_hdottedline_i:n { #1 }
+        \c__nicematrix_endpgfortikzpicture_tl
+      }
   }
-\cs_new_protected:Npn \__nicematrix_vdottedline:n #1
+\cs_new_protected:Npn \__nicematrix_hdottedline_i:n #1
   {
-    \int_compare:nNnTF #1 = 0
-      { \__nicematrix_error:n { Use~of~:~in~first~position } }
-      { \bool_if:NF \c__nicematrix_draft_bool { \__nicematrix_vdottedline_i:n { #1 } } }
+    \pgfrememberpicturepositiononpagetrue
+    \__nicematrix_qpoint: { row - #1 }
+    \dim_set_eq:NN \l__nicematrix_y_initial_dim \pgf at y
+    \dim_sub:Nn \l__nicematrix_y_initial_dim \l__nicematrix_radius_dim
+    \dim_set_eq:NN \l__nicematrix_y_final_dim \l__nicematrix_y_initial_dim
+    \__nicematrix_qpoint: { col - 1 }
+    \dim_set:Nn \l__nicematrix_x_initial_dim
+      { \pgf at x + \arraycolsep - \l__nicematrix_left_margin_dim }
+    \__nicematrix_qpoint: { col - \__nicematrix_succ:N \c at jCol }
+    \dim_set:Nn \l__nicematrix_x_final_dim
+      { \pgf at x - \arraycolsep + \l__nicematrix_right_margin_dim }
+    \tl_set:Nn \l_tmpa_tl { ( }
+    \tl_if_eq:NNF \l__nicematrix_left_delim_tl \l_tmpa_tl
+      { \dim_gadd:Nn \l__nicematrix_x_initial_dim  { 0.5 \l__nicematrix_inter_dots_dim } }
+    \tl_set:Nn \l_tmpa_tl { ) }
+    \tl_if_eq:NNF \l__nicematrix_right_delim_tl \l_tmpa_tl
+      { \dim_gsub:Nn \l__nicematrix_x_final_dim { 0.5 \l__nicematrix_inter_dots_dim } }
+    \tl_set_eq:NN \l__nicematrix_xdots_line_style_tl \c__nicematrix_standard_tl
+    \__nicematrix_draw_line:
   }
+\bool_if:nTF \c__nicematrix_draft_bool
+  { \cs_new_protected:Npn \__nicematrix_vdottedline:n #1 { } }
+  {
+    \cs_new_protected:Npn \__nicematrix_vdottedline:n #1
+      {
+        \bool_set_true:N \l__nicematrix_initial_open_bool
+        \bool_set_true:N \l__nicematrix_final_open_bool
+        \bool_if:NTF \c__nicematrix_tikz_loaded_bool
+          {
+            \tikzpicture
+            \__nicematrix_vdottedline_i:n { #1 }
+            \endtikzpicture
+          }
+          {
+            \pgfpicture
+            \__nicematrix_vdottedline_i:n { #1 }
+            \endpgfpicture
+          }
+      }
+  }
 \cs_new_protected:Npn \__nicematrix_vdottedline_i:n #1
   {
-    \dim_zero_new:N \g__nicematrix_x_initial_dim
-    \dim_zero_new:N \g__nicematrix_y_initial_dim
-    \dim_zero_new:N \g__nicematrix_x_final_dim
-    \dim_zero_new:N \g__nicematrix_y_final_dim
-    \bool_set_true:N \l__nicematrix_initial_open_bool
-    \bool_set_true:N \l__nicematrix_final_open_bool
-    \begin { tikzpicture } [ remember~picture ]
-      \__nicematrix_extract_coords:w ( col - \int_eval:n { #1 + 1 } )
-      \dim_gset:Nn \g__nicematrix_x_initial_dim { \pgf at x - \l__nicematrix_radius_dim }
-      \dim_gset:Nn \g__nicematrix_x_final_dim { \pgf at x - \l__nicematrix_radius_dim }
-      \__nicematrix_extract_coords:w ( row - 1 )
-      \dim_gset:Nn \g__nicematrix_y_initial_dim { \pgf at y - ( \l__nicematrix_inter_dots_dim / 2 ) }
-      \__nicematrix_extract_coords:w ( row - \int_eval:n { \c at iRow + 1 } )
-      \dim_gset:Nn \g__nicematrix_y_final_dim { \pgf at y + ( \l__nicematrix_inter_dots_dim / 2 ) }
-    \end { tikzpicture }
-    \__nicematrix_draw_tikz_line:
+    \bool_if:NT \c__nicematrix_colortbl_loaded_bool \CT at arc@
+    \pgfrememberpicturepositiononpagetrue
+    \__nicematrix_qpoint: { col - \int_eval:n { #1 + 1 } }
+    \dim_set:Nn \l__nicematrix_x_initial_dim { \pgf at x - \l__nicematrix_radius_dim }
+    \dim_set:Nn \l__nicematrix_x_final_dim { \pgf at x - \l__nicematrix_radius_dim }
+    \__nicematrix_qpoint: { row - 1 }
+    \dim_set:Nn \l__nicematrix_y_initial_dim { \pgf at y - 0.5 \l__nicematrix_inter_dots_dim }
+    \__nicematrix_qpoint: { row - \__nicematrix_succ:N \c at iRow }
+    \dim_set:Nn \l__nicematrix_y_final_dim { \pgf at y + 0.5 \l__nicematrix_inter_dots_dim }
+    \tl_set_eq:NN \l__nicematrix_xdots_line_style_tl \c__nicematrix_standard_tl
+    \__nicematrix_draw_line:
   }
 \bool_new:N \l__nicematrix_block_auto_columns_width_bool
 \keys_define:nn { NiceMatrix / NiceMatrixBlock }
@@ -2082,8 +2287,8 @@
       {
         \cs_if_exist:cT { __nicematrix_max_cell_width_ \int_use:N \g__nicematrix_NiceMatrixBlock_int }
           {
-            \dim_set:Nx \l__nicematrix_columns_width_dim
-              { \use:c { __nicematrix_max_cell_width _ \int_use:N \g__nicematrix_NiceMatrixBlock_int } }
+            \exp_args:NNc \dim_set:Nn \l__nicematrix_columns_width_dim
+              { __nicematrix_max_cell_width _ \int_use:N \g__nicematrix_NiceMatrixBlock_int }
           }
       }
   }
@@ -2095,7 +2300,7 @@
           {
             \cs_gset:cpn
               { __nicematrix _ max _ cell _ width _ \int_use:N \g__nicematrix_NiceMatrixBlock_int }
-              { \dim_use:N \g__nicematrix_max_cell_width_dim }
+              { \dim_eval:n { \g__nicematrix_max_cell_width_dim + \arrayrulewidth } }
           }
         \iow_now:Nn \@mainaux \ExplSyntaxOff
       }
@@ -2124,11 +2329,11 @@
           \l__nicematrix_first_col_int \g__nicematrix_col_total_int \__nicematrix_j:
           {
             \cs_if_exist:cT
-              { pgf at sh@ns at nm - \int_use:N \g__nicematrix_env_int - \__nicematrix_i: - \__nicematrix_j: }
+              { pgf @ sh @ ns @ \__nicematrix_env: - \__nicematrix_i: - \__nicematrix_j: }
               {
-                \__nicematrix_extract_coords:w
-                  ( nm - \int_use:N \g__nicematrix_env_int
-                       - \__nicematrix_i: - \__nicematrix_j: .south~west )
+                \pgfpointanchor
+                  { \__nicematrix_env: - \__nicematrix_i: - \__nicematrix_j: }
+                  { south~west }
                 \dim_set:cn { l__nicematrix_row_\__nicematrix_i: _min_dim}
                   { \dim_min:vn { l__nicematrix_row _ \__nicematrix_i: _min_dim } \pgf at y }
                 \seq_if_in:NxF \g__nicematrix_multicolumn_cells_seq { \__nicematrix_i: - \__nicematrix_j: }
@@ -2136,8 +2341,9 @@
                     \dim_set:cn { l__nicematrix_column _ \__nicematrix_j: _min_dim}
                       { \dim_min:vn { l__nicematrix_column _ \__nicematrix_j: _min_dim } \pgf at x }
                   }
-                \__nicematrix_extract_coords:w
-                  ( nm - \int_use:N \g__nicematrix_env_int - \__nicematrix_i: - \__nicematrix_j: .north~east )
+                \pgfpointanchor
+                  { \__nicematrix_env: - \__nicematrix_i: - \__nicematrix_j: }
+                  { north~east }
                 \dim_set:cn { l__nicematrix_row _ \__nicematrix_i: _ max_dim }
                   { \dim_max:vn { l__nicematrix_row _ \__nicematrix_i: _ max_dim } \pgf at y }
                 \seq_if_in:NxF \g__nicematrix_multicolumn_cells_seq { \__nicematrix_i: - \__nicematrix_j: }
@@ -2151,40 +2357,37 @@
   }
 \cs_new_protected:Npn \__nicematrix_create_medium_nodes:
   {
-    \begin { tikzpicture } [ remember~picture , overlay ]
+    \pgfpicture
+      \pgfrememberpicturepositiononpagetrue
+      \pgf at relevantforpicturesizefalse
       \__nicematrix_computations_for_medium_nodes:
-      \tikzset { name~suffix = -medium }
+      \tl_set:Nn \l__nicematrix_suffix_tl { -medium }
       \__nicematrix_create_nodes:
-      \end { tikzpicture }
-    \cs_set_protected:Npn \__nicematrix_create_medium_nodes: { }
-    \cs_set_protected:Npn \__nicematrix_create_medium_and_large_nodes:
-      { \__nicematrix_create_large_nodes: }
+      \endpgfpicture
   }
 \cs_new_protected:Npn \__nicematrix_create_large_nodes:
   {
-    \begin { tikzpicture } [ remember~picture , overlay ]
+    \pgfpicture
+      \pgfrememberpicturepositiononpagetrue
+      \pgf at relevantforpicturesizefalse
       \__nicematrix_computations_for_medium_nodes:
       \__nicematrix_computations_for_large_nodes:
-      \tikzset { name~suffix = -large }
+      \tl_set:Nn \l__nicematrix_suffix_tl { - large }
       \__nicematrix_create_nodes:
-    \end { tikzpicture }
-    \cs_set_protected:Npn \__nicematrix_create_large_nodes: { }
-    \cs_set_protected:Npn \__nicematrix_create_medium_and_large_nodes:
-      { \__nicematrix_create_medium_nodes: }
+    \endpgfpicture
   }
 \cs_new_protected:Npn \__nicematrix_create_medium_and_large_nodes:
   {
-    \begin { tikzpicture } [ remember~picture , overlay ]
+    \pgfpicture
+      \pgfrememberpicturepositiononpagetrue
+      \pgf at relevantforpicturesizefalse
       \__nicematrix_computations_for_medium_nodes:
-      \tikzset { name~suffix = -medium }
+      \tl_set:Nn \l__nicematrix_suffix_tl { - medium }
       \__nicematrix_create_nodes:
       \__nicematrix_computations_for_large_nodes:
-      \tikzset { name~suffix = -large }
+      \tl_set:Nn \l__nicematrix_suffix_tl { - large }
       \__nicematrix_create_nodes:
-    \end { tikzpicture }
-    \cs_set_protected:Npn \__nicematrix_create_medium_and_large_nodes: { }
-    \cs_set_protected:Npn \__nicematrix_create_medium_nodes: { }
-    \cs_set_protected:Npn \__nicematrix_create_large_nodes: { }
+    \endpgfpicture
   }
 \cs_new_protected:Npn \__nicematrix_computations_for_large_nodes:
   {
@@ -2231,23 +2434,18 @@
       {
         \int_step_variable:nnNn \l__nicematrix_first_col_int \g__nicematrix_col_total_int \__nicematrix_j:
           {
-            \coordinate ( __nicematrix~south~west )
-               at ( \dim_use:c { l__nicematrix_column_ \__nicematrix_j: _min_dim } ,
-                    \dim_use:c { l__nicematrix_row_ \__nicematrix_i: _min_dim } ) ;
-            \coordinate ( __nicematrix~north~east )
-               at ( \dim_use:c { l__nicematrix_column_ \__nicematrix_j: _max_dim } ,
-                    \dim_use:c { l__nicematrix_row_ \__nicematrix_i: _max_dim } ) ;
-            \node
-              [
-                node~contents = { } ,
-                fit = ( __nicematrix~south~west ) ( __nicematrix~north~east )  ,
-                inner~sep = \c_zero_dim ,
-                name = nm - \int_use:N \g__nicematrix_env_int - \__nicematrix_i: - \__nicematrix_j: ,
-                alias =
-                  \str_if_empty:NF \l__nicematrix_name_str
-                    { \l__nicematrix_name_str - \__nicematrix_i: - \__nicematrix_j: }
-              ]
-              ;
+            \__nicematrix_pgf_rect_node:nnnnn
+              { \__nicematrix_env: - \__nicematrix_i: - \__nicematrix_j: \l__nicematrix_suffix_tl }
+              { \dim_use:c { l__nicematrix_column_ \__nicematrix_j: _min_dim } }
+              { \dim_use:c { l__nicematrix_row_ \__nicematrix_i: _min_dim } }
+              { \dim_use:c { l__nicematrix_column_ \__nicematrix_j: _max_dim } }
+              { \dim_use:c { l__nicematrix_row_ \__nicematrix_i: _max_dim } }
+            \str_if_empty:NF \l__nicematrix_name_str
+              {
+                \pgfnodealias
+                  { \l__nicematrix_name_str - \__nicematrix_i: - \__nicematrix_j: \l__nicematrix_suffix_tl }
+                  { \__nicematrix_env: - \__nicematrix_i: - \__nicematrix_j: \l__nicematrix_suffix_tl }
+              }
           }
       }
     \seq_mapthread_function:NNN
@@ -2263,27 +2461,18 @@
 \cs_new_protected:Npn \__nicematrix_node_for_multicolumn:nn #1 #2
   {
     \__nicematrix_extract_coords_values: #1 \q_stop
-    \coordinate ( __nicematrix~south~west ) at
-      (
-        \dim_use:c { l__nicematrix_column _ \__nicematrix_j: _ min _ dim } ,
-        \dim_use:c { l__nicematrix_row _ \__nicematrix_i: _ min _ dim }
-      ) ;
-    \coordinate ( __nicematrix~north~east ) at
-      (
-        \dim_use:c { l__nicematrix_column _ \int_eval:n { \__nicematrix_j: + #2 - 1 } _ max _ dim} ,
-        \dim_use:c { l__nicematrix_row _ \__nicematrix_i: _ max _ dim }
-      ) ;
-    \node
-      [
-        node~contents = { } ,
-        fit = ( __nicematrix~south~west ) ( __nicematrix~north~east ) ,
-        inner~sep = \c_zero_dim ,
-        name = nm - \int_use:N \g__nicematrix_env_int - \__nicematrix_i: - \__nicematrix_j: ,
-        alias =
-          \str_if_empty:NF \l__nicematrix_name_str
-            { \l__nicematrix_name_str - \__nicematrix_i: - \__nicematrix_j: }
-      ]
-      ;
+    \__nicematrix_pgf_rect_node:nnnnn
+      { \__nicematrix_env: - \__nicematrix_i: - \__nicematrix_j: \l__nicematrix_suffix_tl }
+      { \dim_use:c { l__nicematrix_column _ \__nicematrix_j: _ min _ dim } }
+      { \dim_use:c { l__nicematrix_row _ \__nicematrix_i: _ min _ dim } }
+      { \dim_use:c { l__nicematrix_column _ \int_eval:n { \__nicematrix_j: +#2-1 } _ max _ dim } }
+      { \dim_use:c { l__nicematrix_row _ \__nicematrix_i: _ max _ dim } }
+    \str_if_empty:NF \l__nicematrix_name_str
+      {
+        \pgfnodealias
+          { \l__nicematrix_name_str - \__nicematrix_i: - \__nicematrix_j: \l__nicematrix_suffix_tl }
+          { \int_use:N \g__nicematrix_env_int - \__nicematrix_i: - \__nicematrix_j: \l__nicematrix_suffix_tl}
+      }
   }
 \NewDocumentCommand \__nicematrix_Block: { O { } m D < > { } m }
   { \__nicematrix_Block_i #2 \q_stop { #1 } { #3 } { #4 } }
@@ -2290,7 +2479,7 @@
 \cs_new:Npn \__nicematrix_Block_i #1-#2 \q_stop { \__nicematrix_Block_ii:nnnnn { #1 } { #2 } }
 \cs_new_protected:Npn \__nicematrix_Block_ii:nnnnn #1 #2 #3 #4 #5
   {
-    \tl_gput_left:Nx \g__nicematrix_code_after_tl
+    \tl_gput_left:Nx \g__nicematrix_internal_code_after_tl
       {
         \__nicematrix_Block_iii:nnnnnn
           { \int_use:N \c at iRow }
@@ -2327,58 +2516,59 @@
       { \msg_error:nnnn { nicematrix } { Block~too~large } { #1 } { #2 } }
       {
         \hbox_set:Nn \l__nicematrix_cell_box { #6 }
-        \begin { tikzpicture }
-          \int_set:Nn \l_tmpa_int { #1 }
-          \int_decr:N \l_tmpa_int
-          \int_set:Nn \l_tmpb_int { #2 }
-          \int_decr:N \l_tmpb_int
-          \__nicematrix_extract_coords:w ( row - \int_eval:n { \l_tmpa_int + 1 } )
+        \pgfpicture
+          \pgfrememberpicturepositiononpagetrue
+          \pgf at relevantforpicturesizefalse
+          \__nicematrix_qpoint: { row - #1 }
           \dim_set_eq:NN \l_tmpa_dim \pgf at y
-          \__nicematrix_extract_coords:w ( col - \int_eval:n { \l_tmpb_int + 1 } )
+          \__nicematrix_qpoint: { col - #2 }
           \dim_set_eq:NN \l_tmpb_dim \pgf at x
-          \coordinate ( one ) at ( \l_tmpb_dim , \l_tmpa_dim ) ;
-          \__nicematrix_extract_coords:w ( row - \int_eval:n { #3 + 1 } )
-          \dim_set_eq:NN \l_tmpa_dim \pgf at y
-          \__nicematrix_extract_coords:w ( col - \int_eval:n { #4 + 1 } )
-          \dim_set_eq:NN \l_tmpb_dim \pgf at x
-          \coordinate ( two ) at ( \l_tmpb_dim , \l_tmpa_dim ) ;
+          \__nicematrix_qpoint: { row - \__nicematrix_succ:N #3 }
+          \dim_set_eq:NN \l_tmpc_dim \pgf at y
+          \__nicematrix_qpoint: { col - \__nicematrix_succ:N #4 }
+          \dim_set_eq:NN \l_tmpd_dim \pgf at x
           \bool_if:NT \l__nicematrix_white_bool
             {
-              \fill [ white , line~width = 0 pt]
-                ( [ yshift = -\arrayrulewidth ] one )
-                rectangle
-                ( [ xshift = -\arrayrulewidth ] two ) ;
+              \begin { pgfscope }
+              \pgfsetfillcolor { white }
+              \int_compare:nNnT { #2 } = 1
+                {
+                  \int_compare:nNnT \l__nicematrix_first_col_int = 1
+                    { \dim_add:Nn \l_tmpb_dim \arrayrulewidth }
+                }
+              \pgfpathrectanglecorners
+                { \pgfpoint \l_tmpb_dim { \l_tmpa_dim - \arrayrulewidth } }
+                { \pgfpoint { \l_tmpd_dim - \arrayrulewidth } \l_tmpc_dim }
+              \pgfusepathqfill
+              \end { pgfscope }
             }
-          \use:x
-            {
-              \exp_not:N \node
-                [
-                  fit = ( one ) ( two ) ,
-                  inner~sep = 0 pt ,
-                  \l__nicematrix_tikz_tl
-                ]
-            }
-            (#1-#2-block) { } ;
+          \begin { pgfscope }
+          \exp_args:Nx \pgfset { \l__nicematrix_tikz_tl }
+          \__nicematrix_pgf_rect_node:nnnnn
+            { \__nicematrix_env: - #1 - #2 - block }
+            \l_tmpb_dim \l_tmpa_dim \l_tmpd_dim \l_tmpc_dim
+          \end { pgfscope }
         \bool_if:NT \l__nicematrix_medium_nodes_bool
           {
-            \node
-              [
-                fit = ( #1 - #2 - medium . north~west )
-                      ( #3 - #4 - medium . south~east ) ,
-                inner~sep = 0 pt ,
-              ]
-              (#1-#2-block-medium) { } ;
+            \__nicematrix_pgf_rect_node:nnn
+              { \__nicematrix_env: - #1 - #2 - block - medium }
+              { \pgfpointanchor { \__nicematrix_env: - #1 - #2 - medium } { north~west } }
+              { \pgfpointanchor { \__nicematrix_env: - #3 - #4 - medium } { south~east } }
           }
         \int_compare:nNnTF { #1 } = { #3 }
           {
-              \__nicematrix_extract_coords:w (row-#1-base)
-              \dim_set_eq:NN \l_tmpa_dim \pgf at y
-              \__nicematrix_extract_coords:w (#1-#2-block)
-              \path (\pgf at x,\l_tmpa_dim) node [ anchor = base ]
-                { \box_use_drop:N \l__nicematrix_cell_box } ;
+            \pgfextracty \l_tmpa_dim { \__nicematrix_qpoint: { row - #1 - base } }
+            \__nicematrix_qpoint: { #1 - #2 - block }
+            \pgftransformshift { \pgfpoint \pgf at x \l_tmpa_dim }
+            \pgfnode { rectangle } { base }
+              { \box_use_drop:N \l__nicematrix_cell_box } { } { }
           }
-          { \node at (#1-#2-block.center) { \box_use_drop:N \l__nicematrix_cell_box } ; }
-        \end { tikzpicture }
+          {
+            \pgftransformshift { \__nicematrix_qpoint: { #1 - #2 - block } }
+            \pgfnode { rectangle } { center }
+              { \box_use_drop:N \l__nicematrix_cell_box } { } { }
+          }
+        \endpgfpicture
       }
     \group_end:
   }
@@ -2454,7 +2644,12 @@
     transparent .meta:n = { renew-dots , renew-matrix } ,
     transparent .value_forbidden:n = true,
     obsolete-environments .code:n =
-      \__nicematrix_msg_redirect_name:nn { Obsolete~environment } { none }
+      \__nicematrix_msg_redirect_name:nn { Obsolete~environment } { none } ,
+        obsolete-environments .value_forbidden:n = true,
+    starred-commands .code:n =
+      \__nicematrix_msg_redirect_name:nn { starred~commands } { none } ,
+    starred-commands .value_forbidden:n = true ,
+
   }
 \ProcessKeysOptions { NiceMatrix / Package }
 \cs_new_protected:Npn \__nicematrix_convert_to_str_seq:N #1
@@ -2486,31 +2681,57 @@
       }
       { \__nicematrix_fatal:n { too~much~cols~for~array } }
   }
+\cs_new:Npn \__nicematrix_message_hdotsfor:
+  {
+    \tl_if_empty:VF \g__nicematrix_Hdotsfor_lines_tl
+     { ~Maybe~your~use~of~\token_to_str:N \Hdotsfor\ is~incorrect.}
+  }
 \__nicematrix_msg_new:nn { too~much~cols~for~matrix~with~last~col }
   {
     You~try~to~use~more~columns~than~allowed~by~your~
-    \__nicematrix_full_name_env:.~The~maximal~number~of~columns~is~
-    \int_eval:n { \l__nicematrix_last_col_int - 1 }~(plus~the~potential~
+    \__nicematrix_full_name_env:.\__nicematrix_message_hdotsfor:\ The~maximal~number~of~
+    columns~is~\int_eval:n { \l__nicematrix_last_col_int - 1 }~(plus~the~potential~
     exterior~ones).~This~error~is~fatal.
   }
 \__nicematrix_msg_new:nn { too~much~cols~for~matrix }
   {
     You~try~to~use~more~columns~than~allowed~by~your~
-    \__nicematrix_full_name_env:.~ Recall~that~the~maximal~number~of~columns~
-    for~a~matrix~is~fixed~by~the~LaTeX~counter~'MaxMatrixCols'.~
-    Its~actual~value~is~\int_use:N \c at MaxMatrixCols.~This~error~is~fatal.
+    \__nicematrix_full_name_env:.\__nicematrix_message_hdotsfor:\ Recall~that~the~maximal~
+    number~of~columns~for~a~matrix~is~fixed~by~the~LaTeX~counter~
+    'MaxMatrixCols'.~Its~actual~value~is~\int_use:N \c at MaxMatrixCols.~
+    This~error~is~fatal.
   }
 \__nicematrix_msg_new:nn { too~much~cols~for~array }
   {
     You~try~to~use~more~columns~than~allowed~by~your~
-    \__nicematrix_full_name_env:.~The~maximal~number~of~columns~is~
-    \int_use:N \c at jCol\space (plus~the~potential~exterior~ones).~
+    \__nicematrix_full_name_env:.\__nicematrix_message_hdotsfor:\ The~maximal~number~of~columns~is~
+    \int_eval:n { \c at jCol - 1 }~(plus~the~potential~exterior~ones).~
     This~error~is~fatal.
   }
+\__nicematrix_msg_new:nn { bad~option~for~line-style }
+  {
+    Since~you~haven't~loaded~Tikz,~the~only~value~you~can~give~to~'line-style'~
+    is~'standard'.~If~you~go~on,~this~option~will~be~ignored.
+  }
+\__nicematrix_msg_new:nn { Unknown~option~for~xdots }
+  {
+    As~for~now~there~is~only~three~options~available~here:~'color',~'line-style'~
+    and~'shorten'~(and~you~try~to~use~'\l_keys_key_str').~If~you~go~on,~
+    this~option~will~be~ignored.
+  }
+\__nicematrix_msg_new:nn { starred~commands }
+  {
+    The~starred~versions~of~\token_to_str:N \Cdots,~\token_to_str:N \Ldots,~
+    \token_to_str:N \Vdots,~\token_to_str:N\Ddots\ and~\token_to_str:N\Iddots\
+    are~deprecated.~However,~you~can~go~on~for~this~time.~If~you~don't~want~to~
+    see~this~error~we~should~load~'nicematrix'~with~the~option~
+    'starred-commands'.
+  }
 \__nicematrix_msg_new:nn { bad~value~for~baseline }
   {
-    The~value~you~gave~to~'baseline'~(\int_use:N \l_tmpa_int)~is~not~
-    valid.\\
+    The~value~given~to~'baseline'~(\int_use:N \l_tmpa_int)~is~not~
+    valid.~The~value~must~be~between~\int_use:N \l__nicematrix_first_row_int\ and~
+    \int_use:N \g__nicematrix_row_total_int\ or~equal~to~'t',~'c'~or~'b'.\\
     If~you~go~on,~a~value~of~1~will~be~used.
   }
 \__nicematrix_msg_new:nn { Second~Block }
@@ -2523,7 +2744,7 @@
 \__nicematrix_msg_new:nn { unknown~cell~for~line~in~code-after }
   {
     Your~command~\token_to_str:N\line\{#1\}\{#2\}~in~the~'code-after'~
-    can't~be~executed~because~a~Tikz~node~doesn't~exist.\\
+    can't~be~executed~because~a~cell~doesn't~exist.\\
     If~you~go~on~this~command~will~be~ignored.
   }
 \__nicematrix_msg_new:nn { last-col~non~empty~for~NiceArray }
@@ -2545,12 +2766,6 @@
     too~small~for~that~block. \\
     If~you~go~on,~this~command~will~be~ignored.
   }
-\__nicematrix_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.
-  }
 \__nicematrix_msg_new:nn { Wrong~last~row }
   {
     You~have~used~'last-row=\int_use:N \l__nicematrix_last_row_int'~but~your~
@@ -2592,7 +2807,6 @@
     create-extra-nodes,~
     create-medium-nodes,~
     create-large-nodes,~
-    dotted-lines-margin,~
     end-of-row,~
     exterior-arraycolsep,~
     hlines,~
@@ -2606,8 +2820,11 @@
     renew-matrix,~
     right-margin,~
     small,~
-    transparent~
-    and~vlines.
+    transparent,~
+    vlines,~
+    xdots/color,~
+    xdots/shorten~and~
+    xdots/line-style.
   }
 \__nicematrix_msg_new:nnn { Unknown~option~for~NiceArray }
   {
@@ -2630,7 +2847,6 @@
     create-extra-nodes,~
     create-medium-nodes,~
     create-large-nodes,~
-    dotted-lines-margin,~
     end-of-row,~
     extra-left-margin,~
     extra-right-margin,~
@@ -2649,7 +2865,10 @@
     right-margin,~
     small,~
     t,~
-    and~vlines.
+    vlines,~
+    xdots/color,~
+    xdots/shorten~and~
+    xdots/line-style.
   }
 \__nicematrix_msg_new:nnn { Unknown~option~for~NiceMatrix }
   {
@@ -2669,7 +2888,6 @@
     create-extra-nodes,~
     create-medium-nodes,~
     create-large-nodes,~
-    dotted-lines-margin,~
     end-of-row,~
     extra-left-margin,~
     extra-right-margin,~
@@ -2677,6 +2895,7 @@
     first-row,~
     hlines,~
     hvlines,~
+    l~(=L),~
     last-col,~
     last-row,~
     left-margin,~
@@ -2684,10 +2903,14 @@
     name,~
     nullify-dots,~
     parallelize-diags,~
+    r~(=R),~
     renew-dots,~
     right-margin,~
     small,~
-    and~vlines.
+    vlines,~
+    xdots/color,~
+    xdots/shorten~and~
+    xdots/line-style.
   }
 \__nicematrix_msg_new:nnn { Duplicate~name }
   {
@@ -2713,12 +2936,6 @@
     and~R~in~the~preamble~of~your~environment. \\
     This~error~is~fatal.
   }
-\__nicematrix_msg_new:nn { Use~of~:~in~first~position }
-  {
-    You~can't~use~the~column~specifier~'\l__nicematrix_letter_for_dotted_lines_str'~in~the~
-    first~position~of~the~preamble~of~the~\__nicematrix_full_name_env:. \\
-    If~you~go~on,~this~dotted~line~will~be~ignored.
-  }
 \__nicematrix_msg_new:nn { Obsolete~environment }
   {
     The~environment~\{\@currenvir\}~is~obsolete.~You~should~use~#1~instead.~
@@ -2823,6 +3040,55 @@
     \NiceArrayWithDelims
   }
   { \endNiceArrayWithDelims }
+\cs_new_protected:Npn \__nicematrix_pgf_rect_node:nnnnn #1 #2 #3 #4 #5
+  {
+    \begin { pgfscope }
+    \pgfset
+      {
+        outer~sep = \c_zero_dim ,
+        inner~sep = \c_zero_dim ,
+        minimum~size = \c_zero_dim
+      }
+    \pgftransformshift { \pgfpoint { 0.5 * ( #2 + #4 ) } { 0.5 * ( #3 + #5 ) } }
+    \pgfnode
+      { rectangle }
+      { center }
+      {
+        \vbox_to_ht:nn
+          { \dim_abs:n { #5 - #3 } }
+          {
+            \vfill
+            \hbox_to_wd:nn { \dim_abs:n { #4 - #2 } } { }
+          }
+      }
+      { #1 }
+      { }
+    \end { pgfscope }
+  }
+\cs_new_protected:Npn \__nicematrix_pgf_rect_node:nnn #1 #2 #3
+  {
+    \begin { pgfscope }
+    \pgfset
+      {
+        outer~sep = \c_zero_dim ,
+        inner~sep = \c_zero_dim ,
+        minimum~size = \c_zero_dim
+      }
+    \pgftransformshift { \pgfpointscale { 0.5 } { \pgfpointadd { #2 } { #3 } } }
+    \pgfpointdiff { #3 } { #2 }
+    \pgfgetlastxy \l_tmpa_dim \l_tmpb_dim
+    \pgfnode
+      { rectangle }
+      { center }
+      {
+        \vbox_to_ht:nn
+          { \dim_abs:n { \l_tmpb_dim } }
+          { \vfill \hbox_to_wd:nn { \dim_abs:n { \l_tmpa_dim } } { } }
+      }
+      { #1 }
+      { }
+    \end { pgfscope }
+  }
 
 \endinput
 %%



More information about the tex-live-commits mailing list.