texlive[68398] Master/texmf-dist: nicematrix (29sep23)

commits+karl at tug.org commits+karl at tug.org
Fri Sep 29 23:05:29 CEST 2023


Revision: 68398
          https://tug.org/svn/texlive?view=revision&revision=68398
Author:   karl
Date:     2023-09-29 23:05:29 +0200 (Fri, 29 Sep 2023)
Log Message:
-----------
nicematrix (29sep23)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/nicematrix/nicematrix-code.pdf
    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/doc/latex/nicematrix/nicematrix.tex
    trunk/Master/texmf-dist/source/latex/nicematrix/nicematrix-code.dtx
    trunk/Master/texmf-dist/tex/latex/nicematrix/nicematrix.sty

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

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	2023-09-29 21:04:41 UTC (rev 68397)
+++ trunk/Master/texmf-dist/doc/latex/nicematrix/nicematrix-french.tex	2023-09-29 21:05:29 UTC (rev 68398)
@@ -1,6 +1,6 @@
 % -*- coding: utf-8 ; -*-
 % Ce fichier doit être compilé avec xelatex uniquement.
-\documentclass[dvipsnames]{article}% dvipsnames is for xcolor (loaded by Tikz, loaded by nicematrix)
+\documentclass[dvipsnames]{article}% dvipsnames is for xcolor (loaded by TikZ, loaded by nicematrix)
 \usepackage{xltxtra}
 \usepackage[french]{babel}
 \frenchsetup{og = « , fg = »}
@@ -533,13 +533,16 @@
 
 \interitem
 La commande |\Block| accepte en premier argument optionnel (entre crochets) une
-liste de couples \textsl{clé=valeur}. Les clés sont les suivantes :
+liste de couples \textsl{clé=valeur}. 
+
+\smallskip
+Les premières clés sont des outils rapides pour contrôler l'apparence du bloc :
+
 \begin{itemize}
 \item \index{fill (clé de \texttt{\textbackslash Block})}
 la clé \Definition{fill} prend en argument une couleur et remplit le bloc
 avec cette couleur ;
 \item \index{opacity! (clé de la commande \texttt{\textbackslash Block})}
-\colorbox{yellow!50}{\bfseries Nouveau 6.22}\enskip
 la clé \Definition{opacity} fixe l'opacité de la couleur de remplissage donnée
 par |fill| ;
 \item \index{draw (clé de \texttt{\textbackslash Block})}
@@ -566,15 +569,46 @@
 cadre dessiné par |draw| et le fond dessiné par |fill|)
 avec un rayon égal à la valeur de cette clé (la valeur par défaut est
 4~pt\footnote{Cette valeur par défaut est la valeur initiale des \emph{rounded
-    corners} de TikZ.}) ;
+    corners} de TikZ.}). 
+\end{itemize}
+
+\medskip
+Ces outils ne sont parfois pas suffisants pour contrôler l'apparence du bloc.
+Les clés suivantes sont plus puissantes, mais plus difficiles d'utilisation.
+Elles nécessitent également que TikZ soit chargé (par |\usepackage{tikz}|). Par
+défaut, \pkg{nicematrix} ne charge pas TikZ mais uniquement \textsc{pgf}, qui
+est une sous-couche de TikZ.
+\begin{itemize}
+\item \index{borders (clé de \texttt{\textbackslash Block})} \index{tikzz at tikz!clé de «borders» de \texttt{\textbackslash Block}}
+La clé \Definition{borders} permet de ne tracer que certaines des bordures
+du bloc : cette clé prend comme valeur une liste d'éléments parmi les suivants :
+|left|, |right|, |top| et |bottom| ; on peut en fait, dans la liste qui est la
+valeur de la clé |borders| mettre une entrée de la forme
+|tikz={|\textsl{liste}|}| où \textsl{liste} est une liste de couples
+\textsl{clé=valeur} de TikZ spécifiant les caractéristiques graphiques des
+traits qui seront dessinés (pour un exemple, voir p.~\pageref{tiretes}).
+
 \item \index{tikzz at tikz!clé de \texttt{\textbackslash Block}}
-quand la clé \Definition{tikz} est utilisée, le chemin TikZ correspondant
+Quand la clé \Definition{tikz} est utilisée, le chemin TikZ correspondant
 au rectangle délimitant le bloc est exécuté avec TikZ\footnote{TikZ doit être
   chargé préalablement (par défaut, \pkg{nicematrix} ne charge que
   \textsc{pgf}), faute de quoi, une erreur sera levée.} en utilisant comme
 options la valeur de cette clé |tikz| (qui doit donc être une liste de clés TikZ
 applicables à un chemin de TikZ). Pour des exemples d'utilisation de cette clé
-|tikz|, voir p.~\pageref{tikz-key-examples} ;
+|tikz|, voir p.~\pageref{tikz-key-examples}.
+
+\colorbox{yellow!50}{\textbf{Nouveau 6.24}}\enskip En fait, dans la liste des
+clés fournies à |tikz|, on peut mettre une clé |offset|. Cette clé n'est pas
+fournie par TikZ mais par \pkg{nicematrix}. Elle réduit le rectangle
+correspondant au bloc par une marge (horizontalement et verticalement) égale à
+la valeur (passée à |offset|). C'est ce rectangle réduit qui sera le chemin
+exécuté par TikZ avec comme options les autres clés passées à la clé |tikz|.
+\end{itemize}
+
+
+\medskip
+Enfin, il existe quelque clés techniques :
+\begin{itemize}
 \item \index{name!clé de \texttt{\textbackslash Block}}
 la clé \Definition{name} donne un nom au nœud TikZ rectangulaire
 correspondant au bloc ; on peut utiliser ce nom avec TikZ dans le |\CodeAfter|
@@ -582,22 +616,18 @@
 \item \index{respect-arraystretch (clé de \texttt{\textbackslash Block})}
 la clé \Definition{respect-arraystretch} évite la remise à $1$ de
 |\arraystretch| en début de bloc (qui a lieu par défaut) ;
-\item \index{borders (clé de \texttt{\textbackslash Block})} \index{tikzz at tikz!clé de «borders» de \texttt{\textbackslash Block}}
-la clé \Definition{borders} permet de ne tracer que certaines des bordures
-du bloc : cette clé prend comme valeur une liste d'éléments parmi les suivants :
-|left|, |right|, |top| et |bottom| ; on peut en fait, dans la liste qui est la
-valeur de la clé |borders| mettre une entrée de la forme
-|tikz={|\textsl{liste}|}| où \textsl{liste} est une liste de couples
-\textsl{clé=valeur} de TikZ spécifiant les caractéristiques graphiques des
-traits qui seront dessinés (pour un exemple, voir p.~\pageref{tiretes}).
 \item \index{transparent (clé de \texttt{\textbackslash Block})}
 Par défaut, les filets ne sont pas tracés dans les blocs (voir à ce sujet
 la partie sur les filets, section~\ref{rules} p.~\pageref{rules}). Néanmoins, si
-la clé \Definition{transparent} est utilisée, les filets seront tracés. Pour un
-example, voir la section~\ref{tikz-key-examples},
-page~\pageref{tikz-key-examples}. Attention : cette clé n'implique pas du tout
-que le contenu du bloc sera transparent.
+la clé \Definition{transparent} est utilisée, les filets seront tracés.\footnote{Par
+ailleurs, la commande |\TikzEveryCell| disponible dans le |\CodeAfter|, ne
+s'applique aux blocs avec la clé |transparent|).}
 
+Pour un exemple, voir la section~\ref{tikz-key-examples},
+page~\pageref{tikz-key-examples}. 
+
+Attention : cette clé n'implique pas du tout que le contenu du bloc sera
+transparent.
 \end{itemize}
 
 Il existe aussi des clés de positionnement horizontal et vertical du bloc qui
@@ -885,9 +915,9 @@
 
 \item Avec la clé \Definition{T}, le contenu du bloc est calé vers le haut.
 
-\colorbox{yellow!50}{Modification 6.18}\enskip Il n'y a plus de marge verticale.
-Néanmoins, le contenu du bloc est (toujours) composé en interne dans une |{minipage}|, un
-|{tabular}| ou un |{array}|, ce qui fait qu'il y souvent déjà une marge.
+Il n'y a pas de marge verticale. Néanmoins, le contenu du bloc est (toujours)
+composé en interne dans une |{minipage}|, un |{tabular}| ou un |{array}|, ce qui
+fait qu'il y souvent déjà une marge.
 
 \item Avec la clé \Definition{B}, le contenu du bloc est calé vers le bas.
 \end{itemize}
@@ -1146,7 +1176,7 @@
 Les environnements de \pkg{nicematrix} proposent une clé |rules/width| pour
 fixer la largeur (on devrait plutôt dire l'épaisseur) des filets dans
 l'environnement. En fait,  cette clé ne fait que fixer la valeur du paramètre
-dimensionnel |\arrayrulewidth|.
+dimensionnel de LaTeX |\arrayrulewidth|.
 
 \smallskip
 On sait que \pkg{colortbl} propose la commande |\arrayrulecolor| pour spécifier
@@ -1153,13 +1183,14 @@
 la couleur de ces filets.
 
 \smallskip
-\indexcommand{arrayrulecolor}
+\indexcommand{arrayrulecolor} 
 Avec \pkg{nicematrix}, il est possible de spécifier une couleur même si
 \pkg{colortbl} n'est pas chargé. Par souci de compatibilité, la commande est
-nommée également |\arrayrulecolor|. Les environnements de \pkg{nicematrix}
-proposent également une clé |rules/color| qui permet de fixer cette couleur pour
-l'environnement en question. Cette clé fixe localement la couleur des filets
-(alors que la commande |\arrayrulecolor| agit globalement !).
+nommée également |\arrayrulecolor|. Néanmoins, \pkg{nicematrix} propose aussi
+une clé |rules/color|, disponible dans |\NiceMatrixOptions| ou dans un
+environnement individuel, pour fixer la couleur des filets. Cette clé fixe
+localement la couleur des filets (alors que la commande |\arrayrulecolor| agit
+globalement !). Elle est à privilégier.
 
 \medskip
 \begin{scope}
@@ -1182,8 +1213,13 @@
 \end{NiceTabular}
 \end{scope}
 
+\medskip
+En fait, dans cet exemple, au lieu de |\hline|, il aurait mieux valu utiliser la
+commande |\Hline|, fournie par \pkg{nicematrix} et décrite ci-dessous, car elle
+garantit un meilleur résultat dans les lecteurs de PDF aux bas niveaux de zoom.
 
 
+
 \medskip
 \subsection{Les outils de nicematrix pour tracer des filets}
 
@@ -1218,21 +1254,19 @@
 \item Pour les rangées et colonnes extérieures, cf. p.~\pageref{exterior}.
 \end{itemize}
 
-En particulier, cette remarque explique la différence entre la commande standard
-|\hline| et la commande |\Hline| proposée par \pkg{nicematrix}.
+En particulier, cette remarque montre déjà une différence entre la commande
+standard |\hline| et la commande |\Hline| proposée par \pkg{nicematrix}.
 
-La commande |\Hline| admet entre crochets un argument optionnel qui est une
-liste de couples \textsl{clé=valeur} qui décrivent un filet. Pour la description
-de ces clés, voir |custom-line| p.~\pageref{custom-line}.\footnote{Remarque
-  technique. Si l'utilisateur définit une commande par-dessus la commande
-  |\Hline|, il doit veiller à ce qu'elle soit \emph{développable} au sens de
-  TeX (en utilisant |\NewExpandableDocumentCommand| de LaTeX3, |\newcommand| de
-  LaTeX ou même |\def| de TeX). Exemple :
-  |\newcommand{\RedLine}{\Hline{color=red}}|}
+Par ailleurs, la commande |\Hline| admet entre crochets un argument optionnel
+qui est une liste de couples \textsl{clé=valeur} qui décrivent un filet. Pour la
+description de ces clés, voir |custom-line|
+p.~\pageref{custom-line}.\footnote{Remarque technique. Si l'utilisateur définit
+  une commande par-dessus la commande |\Hline|, il doit veiller à ce qu'elle
+  soit \emph{développable} au sens de TeX (en utilisant
+  |\NewExpandableDocumentCommand| de LaTeX3, |\newcommand| de LaTeX ou même
+  |\def| de TeX). Exemple : |\newcommand{\RedLine}{\Hline[color=red]}|}
 
 \bigskip
-\colorbox{yellow!50}{\textbf{Nouveau 6.23}}\enskip 
-
 De même que la commande |\Hline|, le specificateur «\verb+|+» admet entre crochets
 des options qui caractérisent le filet à tracer. 
 
@@ -1516,9 +1550,11 @@
 
 \bigskip
 On traite maintenant de la description du filet elle-même. Les options qui
-suivent peuvent aussi s'utiliser dans l'argument optionnel d'une |\Hline|
-individuelle. 
+suivent peuvent aussi s'utiliser dans l'argument optionnel d'une commande
+|\Hline| individuelle ou dans l'argument optionnel d'un spécificateur «\verb+|+»
+dans un préambule d'environnement.
 
+\bigskip
 Il y a trois possibilités.
 
 
@@ -1731,7 +1767,7 @@
 
 Rappelons que l'extension \pkg{colortbl} peut être chargée directement par
 |\usepackage{colortbl}| ou en chargeant l'extension \pkg{xcolor} avec l'option
-|table| : |\usepackage[table]{xcolor}|.
+\texttt{table} : |\usepackage[table]{xcolor}|.
 
 \medskip
 Comme l'extension \pkg{nicematrix} est fondée sur \pkg{array}, il est possible
@@ -1828,7 +1864,9 @@
 \index{arraycolor@\texttt{\textbackslash arraycolor} (commande du \texttt{\textbackslash
   CodeBefore)}}
 
+Les noms de ces commandes sont inspirés des noms des commandes de \pkg{colortbl}.
 
+
 \medskip
 Ces commandes ne colorient pas les cases qui se trouvent dans les «coins» si la
 clé |corners| a été utilisée. La description de cette clé a été faite
@@ -2327,13 +2365,13 @@
 commande |\columncolor| de \pkg{colortbl}, celle de \pkg{nicematrix} peut
 apparaître à l'intérieur d'une autre commande, elle-même utilisée dans le
 préambule) ; 
-\item \colorbox{yellow!50}{\textbf{Nouveau 6.21}}\enskip |\rowcolors| qui prend pour arguments deux couleurs et colorie la suite du
+\item |\rowcolors| qui prend pour arguments deux couleurs et colorie la suite du
 tableau avec ces deux couleurs ; 
-\item \colorbox{yellow!50}{\textbf{Nouveau 6.21}}\enskip |\rowlistcolors| qui prend pour argument une liste de couleurs et colorie
+\item |\rowlistcolors| qui prend pour argument une liste de couleurs et colorie
 la suite du tableau avec ces couleurs.\footnote{Quand la commande
   |\rowlistcolors| (ou la commande |\rowcolors|) est utilisée dans une case de
-  la colonne~$j$, le coloriage ne s'applique que les colonnes au-delà de~$j$
-  (à dessein).}
+  la colonne~$j$, le coloriage ne s'applique que les colonnes au-delà de~$j$ (à
+  dessein).}
 \end{itemize}
 
 \medskip
@@ -2399,7 +2437,7 @@
 fixe la couleur du texte.\footnote{La clé |color| utilise la commande |\color| mais
   insère aussi une instruction |\leavevmode| devant. Cela évite un espace
   vertical parasite dans les cases qui correspondent à des colonnes de type
-  |p|, |b|, |m|, |X| et |V| (qui débutent en mode vertical de LateX).}
+  |p|, |b|, |m|, |X| et |V| (qui débutent en mode vertical de LaTeX).}
 
 \item \index{bold (clé de \texttt{\textbackslash RowStyle})}
 La clé \Definition{bold} impose des caractères gras aux éléments de la rangée, qu'ils
@@ -2590,10 +2628,7 @@
 Pour se rapprocher davantage de l'environnement |{tabularx}|, \pkg{nicematrix}
 propose aussi un environnement |{NiceTabularX}| avec une syntaxe similaire à
 celle de |{tabularx}|, c'est-à-dire que la largeur voulue pour le tableau est
-spécifiée en premier argument (obligatoire).\footnote{Si \pkg{tabularx} est
-  chargé, on doit obligatoirement utiliser |{NiceTabularX}| pour utiliser les
-  colonnes |X| (cela est dû à un problème de conflit de définition des
-  spécificateurs de colonne |X|).}
+spécifiée en premier argument (obligatoire).
 
 
 Comme avec les extensions \pkg{tabu}\footnote{L'extension \pkg{tabu} est
@@ -3270,10 +3305,10 @@
 mathématique avec |\scriptstyle|.
 
 \smallskip
-\colorbox{yellow!50}{\textbf{Nouveau 6.22}}\enskip La version 6.22 introduit un
-nouveau label spécifié par le caractère~«|:|» pour un label situé \emph{sur} la ligne
-elle-même. Ce label est en fait composé sur un fond blanc qui est superposé sur
-la ligne en pointillés (voir un exemple p.~\pageref{ex:colon}).
+La version 6.22 de \pkg{nicematrix} a introduit un nouveau label spécifié par le
+caractère~«|:|» pour un label situé \emph{sur} la ligne elle-même. Ce label est
+en fait composé sur un fond blanc qui est superposé sur la ligne en pointillés
+(voir un exemple p.~\pageref{ex:colon}).
 
 \bigskip
 \begin{BVerbatim}[baseline=c,boxwidth=10cm]
@@ -3355,7 +3390,7 @@
 
 \bigskip
 La clé \Definition{xdots/horizontal-labels} demande que les labels (introduits
-par |_| et |^|) restent horizontaux.
+par |_|, |^| et |:|) restent horizontaux.
 
 \medskip
 L'option \Definition{xdots/color} indique bien entendu la couleur de la ligne
@@ -3477,10 +3512,9 @@
 
 \index{blkarray@\pkg{blkarray} (extension)}
 
-\colorbox{yellow!50}{\textbf{Modifié 6.16}}\enskip Pour les environnements à
-préambule (|{NiceArray}|, |{pNiceArray}|, etc.), il est possible de placer des
-délimiteurs verticaux directement dans le préambule.\footnote{Cette syntaxe est
-  inspirée de l'extension \pkg{blkarray}.}
+Pour les environnements à préambule (|{NiceArray}|, |{pNiceArray}|, etc.), il
+est possible de placer des délimiteurs verticaux directement dans le
+préambule.\footnote{Cette syntaxe est inspirée de l'extension \pkg{blkarray}.}
 \label{delimiters-in-preamble}%
 
 \smallskip
@@ -3581,9 +3615,9 @@
 à partir de la page \pageref{PGF-nodes}.
 
 \medskip
-Par ailleurs, plusieurs commandes spéciales sont disponibles dans le |\CodeAfter| :
-|\line|, |\SubMatrix|, |\OverBrace| et |\UnderBrace|. On va maintenant détailler
-ces commandes. 
+Par ailleurs, plusieurs commandes spéciales sont disponibles dans le
+|\CodeAfter| : |\line|, |\SubMatrix|, |\OverBrace|, |\UnderBrace| et
+|\TikzEveryCell|. On va maintenant détailler ces commandes.
 
 
 \subsection{La commande \textbackslash line dans le \textbackslash CodeAfter}
@@ -4007,7 +4041,7 @@
 
 \bigskip
 Attention : Aucun espace vertical n'est réservé par \pkg{nicematrix} pour ces
-accolades.\footnote{Voir à ce sujet: \url{https://tex.stackexchange.com/questions/685755}}
+accolades, ni pour leurs labels.\footnote{Voir à ce sujet: \url{https://tex.stackexchange.com/questions/685755}}
 
 \bigskip
 \index{color!clé de \texttt{\textbackslash OverBrace} et \texttt{\textbackslash
@@ -4053,6 +4087,77 @@
   \OverBrace[shorten,yshift=3pt]{1-4}{2-6}{B}
 \end{pNiceMatrix}$
 
+
+\subsection{La commande \textbackslash TikzEveryCell dans le \textbackslash CodeAfter}
+
+\index{SubMatrix@\texttt{\textbackslash TikzEveryCell} (commande du 
+\texttt{\textbackslash CodeAfter}\newline et du
+\texttt{\textbackslash CodeBefore})|textbf}
+
+
+\colorbox{yellow!50}{\textbf{Nouveau 6.24}}\enskip La commande |\TikzEveryCell|
+exécute avec TikZ le chemin rectangulaire qui correspond à chaque case du tableau,
+avec comme paramètres TikZ l'argument de |\TikzEveryCell|. Cet argument doit
+être une liste de couples \textsl{clé=valeur} applicables à un chemin
+TikZ. En fait, cette commande s'applique à chaque cellule du tableau, exceptées
+celles situées dans les rangées et colonnes extérieures (cf.~p.~\pageref{exterior})o et celles situées dans
+les coins vides (quand la clé |corners| est utilisée: cf.~p.~\pageref{corners}). Elle s'applique en fait à
+chaque bloc (sauf ceux qui ont la clé |transparent|) et ne s'applique pas aux
+cellules situées dans ces blocs.
+
+\medskip
+En fait, dans la liste des clés passée en argument on peut mettre une clé
+|offset|. Cette clé n'est pas fournie par TikZ mais par \pkg{nicematrix}. Elle
+réduit le rectangle correspondant au bloc par une marge (horizontalement et
+verticalement) égale à la valeur (passée à |offset|). C'est ce rectangle réduit
+qui sera le chemin exécuté par TikZ avec comme options les autres clés de
+l'argument de |\TikzEveryCell|.
+
+
+\medskip
+\begingroup
+\bigskip
+\begin{BVerbatim}[baseline=c,boxwidth=9cm]
+
+\renewcommand{\arraystretch}{1.3}
+\begin{NiceTabular}{ccc}[corners]
+  & \Block{1-2}{columns} \\
+  \Block{2-1}{rows}
+  & cell 1 1 & cell 1 2 \\
+  & cell 2 1 & cell 2 2
+\CodeAfter
+  ~emphase#\TikzEveryCell{offset=1pt,draw}@
+\end{NiceTabular}
+\end{BVerbatim}
+\renewcommand{\arraystretch}{1.3}
+\begin{NiceTabular}{ccc}[corners]
+  & \Block{1-2}{columns} \\
+  \Block{2-1}{rows}
+  & cell 1 1 & cell 1 2 \\
+  & cell 2 1 & cell 2 2
+\CodeAfter
+  \TikzEveryCell{offset=1pt,draw}
+\end{NiceTabular}
+\endgroup
+
+
+\medskip
+La commande |\TikzEveryCell| possède deux clés :
+\begin{itemize}
+\item avec la clé \Definition{empty}, la commande ne s'applique qu'aux cellules
+vides ;
+\item avec la clé \Definition{non-empty}, la commande ne s'applique qu'aux
+cellules non vides.
+\end{itemize}
+
+
+\medskip
+La commande |\TikzEveryCell| est en fait aussi disponible dans le |\CodeBefore|.
+
+
+
+
+
 \index{CodeAfter@\texttt{\textbackslash CodeAfter}|)}
 
 \section{Les légendes et les notes dans les tableaux}
@@ -4204,7 +4309,7 @@
 \item Si une commande |\tabularnote{...}| se trouve exactement à la fin d'une case
 (sans aucun espace après), l'appel de note est composé en débordement vers la
 droite (cela peut permettre de mieux conserver l'alignement des contenus d'une
-colonne). Depuis la version 6.20a, ce comportement n'a lieu que le mode
+colonne). Depuis la version 6.20a, ce comportement n'a lieu que si le mode
 l'alignement de la case est |c| ou |r| (alignement horizontal centré ou en
 butée à droite). 
 
@@ -4524,9 +4629,9 @@
 \end{itemize}
 
 \bigskip
-\colorbox{yellow!50}{\textbf{Nouveau 6.21}} Cette clé est disponible dans tous
-les environnements et commandes de \pkg{nicematrix} (comme
-|\pAutoNiceMatrix|) et également dans |\NiceMatrixOptions|. 
+Cette clé est disponible dans tous les environnements et commandes de
+\pkg{nicematrix} (comme par exemple |\pAutoNiceMatrix|) et également dans
+|\NiceMatrixOptions|.
 
 \bigskip
 \begin{BVerbatim}[baseline=c,boxwidth=9.5cm]
@@ -4715,11 +4820,10 @@
 \end{varwidth}
 
 \bigskip
-\colorbox{yellow!50}{\textbf{Nouveau 6.21}}\enskip La commande |\rotate| accepte
-une option |c| entre crochets : |\rotate[c]| (les espaces sont supprimés après
-|\rotate[c]|). Quand cette clé est utilisée, le contenu, après rotation, est
-composé dans une |\vcenter|, ce qui fait que, le plus souvent, on obtiendra un
-centrage vertical.
+La commande |\rotate| accepte une option |c| entre crochets : |\rotate[c]| (les
+espaces sont supprimés après |\rotate[c]|). Quand cette clé est utilisée, le
+contenu, après rotation, est composé dans une |\vcenter|, ce qui fait que, le
+plus souvent, on obtiendra un centrage vertical.
 
 
 \medskip

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

Modified: trunk/Master/texmf-dist/doc/latex/nicematrix/nicematrix.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/nicematrix/nicematrix.tex	2023-09-29 21:04:41 UTC (rev 68397)
+++ trunk/Master/texmf-dist/doc/latex/nicematrix/nicematrix.tex	2023-09-29 21:05:29 UTC (rev 68398)
@@ -511,16 +511,17 @@
 
 \interitem
 In fact, the command |\Block| accepts as first optional argument (between
-square brackets) a list of couples \textsl{key=value}. The available keys are as
-follows:
+square brackets) a list of couples \textsl{key=value}. 
+
+First, there are keys which are quick tools to control the apperance of the block.
+
 \begin{itemize}
 \item \index{fill (key of \texttt{\textbackslash Block})}
 the key \Definition{fill} takes in as value a color and fills the block
 with that color;
 \item \index{opacity  (key of \texttt{\textbackslash Block})} 
-\colorbox{yellow!50}{\bfseries New 6.22}\enskip the key
-\Definition{opacity} sets the opacity of
-the filling color specified by |fill|;
+the key \Definition{opacity} sets the opacity of the filling color specified by
+|fill|; 
 \item \index{draw (key of \texttt{\textbackslash Block})}
 the key \Definition{draw} takes in as value a color and strokes the
 frame of the block with that color (the default value of that key is the
@@ -546,14 +547,50 @@
 the key \Definition{rounded-corners} requires rounded corners (for the
 frame drawn by |draw| and the shape drawn by |fill|) with a radius equal to
 the value of that key (the default value is 4~pt\footnote{This value is the
-initial value of the \emph{rounded corners} of Tikz.});
+initial value of the \emph{rounded corners} of Tikz.}).
+\end{itemize}
+
+\medskip
+Sometimes, these tools are not sufficient to control the appearance of the
+block. The following keys are more powerful but also more difficult to use.
+Moreover, the require the loading of TikZ by the user (with
+|\usepackage{tikz}|). By default, \pkg{nicematrix} does not load TikZ but only
+\textsc{pgf}, which is a sublayer of TikZ.
+
+\begin{itemize}
+\item \index{borders (key of \texttt{\textbackslash Block})}
+\index{tikzz at tikz!key of ``borders'' de \texttt{\textbackslash Block}}
+The key \Definition{borders} provides the ability to draw only some
+borders of the blocks; the value of that key is a (comma-separated) list of
+elements covered by |left|, |right|, |top| and |bottom|; it's possible, in
+fact, in the list which is the value of the key |borders|, to add an entry of
+the form |tikz={|\textsl{list}|}| where \textsl{list} is a list of couples
+\textsl{key=value} of Tikz specifying the graphical characteristics of the
+lines that will be drawn (for an example, see p.~\pageref{dashed}).
+
 \item \index{tikzz at tikz!key of \texttt{\textbackslash Block}}
-when the key \Definition{tikz} is used, the Tikz path corresponding of
+When the key \Definition{tikz} is used, the Tikz path corresponding of
 the rectangle which delimits the block is executed with Tikz\footnote{Tikz
 should be loaded (by default, \pkg{nicematrix} only loads \textsc{pgf}) and,
 if it's not, an error will be raised.} by using as options the value of that
-key |tikz| (which must be a list of keys allowed for a Tikz path). For
-examples, cf. p.~\pageref{tikz-key-examples};
+key |tikz| (which must be a list of keys allowed for a Tikz path). 
+
+\colorbox{yellow!50}{\textbf{New 6.24}}\enskip In fact, in the list of the keys
+provided  by the user as value of |tikz|, it's possible to put a key |offset|.
+That key is not provided by TikZ but by \pkg{nicematrix}. It will narrow the
+rectangular frame corresponding to the block by a margin (horizontally and
+vertically) equal to the value (of that key |offset|). That new frame, a bit
+narrower, will be executed by TikZ with options which are the other keys in the
+list of keys provided as value to the key |tikz| of |\Block|.
+
+For examples, cf. p.~\pageref{tikz-key-examples}.
+\end{itemize}
+
+
+\medskip
+There is also some technical keys:
+
+\begin{itemize}
 \item \index{name!key of \texttt{\textbackslash Block}}
 the key \Definition{name} provides a name to the rectangular Tikz node
 corresponding to the block; it's possible to use that name with Tikz in the
@@ -562,15 +599,6 @@
 the key \Definition{respect-arraystretch} prevents the setting of
 |\arraystretch| to $1$ at the beginning of the block (which is the behaviour
 by default) ;
-\item \index{borders (key of \texttt{\textbackslash Block})}
-\index{tikzz at tikz!key of ``borders'' de \texttt{\textbackslash Block}}
-the key \Definition{borders} provides the ability to draw only some
-borders of the blocks; the value of that key is a (comma-separated) list of
-elements covered by |left|, |right|, |top| and |bottom|; it's possible, in
-fact, in the list which is the value of the key |borders|, to add an entry of
-the form |tikz={|\textsl{list}|}| where \textsl{list} is a list of couples
-\textsl{key=value} of Tikz specifying the graphical characteristics of the
-lines that will be drawn (for an example, see p.~\pageref{dashed}).
 \item \index{transparent (key of \texttt{\textbackslash Block})}
 By default, the rules are not drawn in the blocks (see the section about
 the rules: section~\ref{rules} p.~\pageref{rules}). However, if the key
@@ -1112,7 +1140,8 @@
 
 The environments of \pkg{nicematrix} provide a key |rules/width| to set the
 width (in fact the thickness) of the rules in the current environment. In
-fact, this key merely sets the value of the length |\arrayrulewidth|.
+fact, this key merely sets the value of the standard LaTeX length
+|\arrayrulewidth|. 
 
 \smallskip
 It's well known that \pkg{colortbl} provides the command |\arrayrulecolor| in
@@ -1120,12 +1149,12 @@
 
 \smallskip
 \indexcommand{arrayrulecolor}
-With \pkg{nicematrix}, it's possible to specify the color of the rules even
-when \pkg{colortbl} is not loaded. For sake of compatibility, the command is
-also named |\arrayrulecolor|. The environments of \pkg{nicematrix} also
-provide a key |rules/color| to fix the color of the rules in the current
-environment. This key sets the value locally (whereas |\arrayrulecolor| acts
-globally!). 
+With \pkg{nicematrix}, it's possible to specify the color of the rules even when
+\pkg{colortbl} is not loaded. For sake of compatibility, the command is also
+named |\arrayrulecolor|. However, \pkg{nicematrix} also provides a key
+|rules/color|, available in |\NiceMatrixOptions| or in an individual
+environment, to fix the color of the rules. This key sets the value locally
+(whereas |\arrayrulecolor| acts globally!) and should be prefered.
 
 \medskip
 \begin{scope}
@@ -1148,8 +1177,11 @@
 \end{NiceTabular}
 \end{scope}
 
+\medskip
+In fact, in that example, instead of |\hline|, it would have a better choice to
+use |\Hline|, provided by \pkg{nicematrix} and described just below, because it
+ensures a better output in the PDF viewers at the low levels of zoom.
 
-
 \subsection{The tools of nicematrix for the rules}
 
 Here are the tools provided by \pkg{nicematrix} for the rules.
@@ -1180,22 +1212,21 @@
 \item For the exterior rows and columns, see~p.~\pageref{exterior}.
 \end{itemize}
 
-In particular, this remark explains the difference between the standard
+In particular, this remark exhibits a first difference between the standard
 command |\hline| and the command |\Hline| provided by \pkg{nicematrix}.
 
-The key |\Hline| takes in an optional argument (between square brackets) which
-is a list of \textsl{key=value} pairs. For the description of those keys, see
-|custom-line| on p.~\pageref{custom-line}.\footnote{Technical remark: If the
-  user wants to write a command over the command |\Hline|, it shall be ensured
-  that this new command is expandable in the TeX sens (by using, for instance,
-  |\NewExpandableDocumentCommand| of LaTeX3, |\newcommand| of LaTeX or |\def| of
-  TeX). Example: |\newcommand{\RedLine}{\Hline[color=red]}|}
+Moreover, the key |\Hline| takes in an optional argument (between square
+brackets) which is a list of \textsl{key=value} pairs. For the description of
+those keys, see |custom-line| on p.~\pageref{custom-line}.\footnote{Technical
+  remark: If the user wants to write a command over the command |\Hline|, it
+  shall be ensured that this new command is expandable in the TeX sens (by
+  using, for instance, |\NewExpandableDocumentCommand| of LaTeX3, |\newcommand|
+  of LaTeX or |\def| of TeX). Example:
+  |\newcommand{\RedLine}{\Hline[color=red]}|}
 
 
 \bigskip
-\colorbox{yellow!50}{\textbf{New 6.23}}\enskip 
-
-As well as the command |\Hline|, the specifier ``\verb+|+'' supports a optional
+As well as the command |\Hline|, the specifier ``\verb+|+'' supports an optional
 argument between square brackets for the characteristics of the rule.
 
 \medskip
@@ -1472,8 +1503,11 @@
 
 \bigskip
 We will now speak of the keys which describe the rule itself. Those keys may
-also be used in the (optional) argument of an individual command |\Hline|.
+also be used in the (optional) argument of an individual command |\Hline| or in
+the (optional) argument of a specifier ``\verb+|+'' in the preamble of an
+environment. 
 
+\bigskip
 There is three possibilities.
 
 \begin{itemize}
@@ -1775,6 +1809,10 @@
 \index{arraycolor@\texttt{\textbackslash arraycolor} (command of \texttt{\textbackslash
   CodeBefore)}}
 
+The names of these commands are inspired by the names of the commands provided
+by \pkg{colortbl}.
+
+
 \medskip
 These commands don't color the cells which are in the ``corners'' if the key
 |corners| is used. That key has been described p.~\pageref{corners}.
@@ -2263,9 +2301,9 @@
 \pkg{colortbl} (however, unlike the command |\columncolor| of \pkg{colortbl},
 this command |\columncolor| can appear within another command, itself used in the
 preamble of the array);
-\item \colorbox{yellow!50}{\textbf{New 6.21}}\enskip |\rowcolors| which takes in as arguments two colors and color the rest of
+\item |\rowcolors| which takes in as arguments two colors and color the rest of
 the tabular with those colors;
-\item \colorbox{yellow!50}{\textbf{New 6.21}}\enskip |\rowlistcolors| which takes in as argument a color and color the rest of
+\item |\rowlistcolors| which takes in as argument a color and color the rest of
 the tabular with the colors of that list of colors.\footnote{When the command
   |\rowlistcolors| (or the command |\rowcolors| is used in a cell of the
   column~$j$ of the array, the command applies only on the columns above~$j$ (by
@@ -2519,10 +2557,7 @@
 For sake of similarity with the environment |{tabularx}|, \pkg{nicematrix}
 also provides an environment |{NiceTabularX}| with a syntax similar to the
 syntax of |{tabularx}|, that is to say with a first mandatory argument
-which is the width of the tabular.\footnote{If \pkg{tabularx} is loaded, one
-must use |{NiceTabularX}| (and not |{NiceTabular}|) in order to use the
-columns |X| (this point comes from a conflict in the definitions of the
-specifier |X|).}
+which is the width of the tabular.
 
 As with the packages \pkg{tabu}\footnote{The extension \pkg{tabu} is now
 considered as deprecated.} and \pkg{tabularray}, the specifier |X| takes
@@ -3189,10 +3224,10 @@
 tokens |_| and |^| for labels positionned below and above the line. The
 arguments are composed in math mode with |\scriptstyle|.
 
-\colorbox{yellow!50}{\textbf{New 6.22}}\enskip The version 6.22 introduces a new
-label, specified by the token ``|:|'' for a label placed on the line. The label
-is composed on a white background which is put on the line previously drawn (see
-example on p.~\pageref{ex:colon}).
+The version 6.22 of \pkg{nicematrix} has introduced a new label, specified by
+the token ``|:|'' for a label placed on the line. The label is composed on a
+white background which is put on the line previously drawn (see example on
+p.~\pageref{ex:colon}).
 
 \bigskip
 \begin{BVerbatim}[baseline=c,boxwidth=10cm]
@@ -3269,8 +3304,8 @@
 
 
 \bigskip
-With the key \Definition{xdots/horizontal-labels}, the labels (introduced by |_|
-and |^|) stay horizontal.
+With the key \Definition{xdots/horizontal-labels}, the labels (introduced by~|_|,
+|^| and~|:|) stay horizontal.
 
 \bigskip
 The option \Definition{xdots/color} fixes the color or the dotted line. However,
@@ -3498,7 +3533,8 @@
 
 \medskip
 Moreover, several special commands are available in the |\CodeAfter|: |line|, 
-|\SubMatrix|, |\OverBrace| and |\UnderBrace|. We will now present these commands.
+|\SubMatrix|, |\OverBrace|, |\UnderBrace| and |\TikzEveryCell|. We will now
+present these commands. 
 
 \subsection{The command \textbackslash line in the \textbackslash CodeAfter}
 
@@ -3914,7 +3950,7 @@
 \end{pNiceMatrix}$
 
 \bigskip
-Caution : There is no vertical space reserved for those braces.\footnote{See:
+Caution : There is no vertical space reserved for those braces and their labels.\footnote{See:
   \url{https://tex.stackexchange.com/questions/685755}} 
 
 
@@ -3964,6 +4000,72 @@
   \OverBrace[shorten,yshift=3pt]{1-4}{2-6}{B}
 \end{pNiceMatrix}$
 
+
+\subsection{The command \textbackslash TikzEveryCell in the \textbackslash
+  CodeAfter}
+
+
+\index{SubMatrix@\texttt{\textbackslash TikzEveryCell} (command of 
+\texttt{\textbackslash CodeAfter}\newline and 
+\texttt{\textbackslash CodeBefore})|textbf}
+
+
+
+\colorbox{yellow!50}{\textbf{New 6.24}}\enskip The command |\TikzEveryCell|
+execute with TikZ the rectangular path corresponding to each cell of the tabular
+with parameters of TikZ the argument of |\TikzEveryCell|. That argument must be
+a list of \textsl{key=value} pairs which may be applied to a Tikz path. In fact,
+the command applies to each of the tabular, except those in the exterior rows
+and columns (cf.~p.~\pageref{exterior}) and those in the empty corners (when the
+key |corners| is used: cf.~p.~\pageref{corners}). It applies in fact to each
+block (excepted those with the key |transparent|) and does not apply to the
+cells located within these blocks. 
+
+\medskip
+In fact, in the list of keys provided as argument of |\TikzEveryCell|, it's
+possible to put a key |offset|. That key is not provided by TikZ but by
+\pkg{nicematrix}. It will narrow the rectangular frame corresponding to the
+block by a margin (horizontally and vertically) equal to the value (of that key
+|offset|). That new frame, a bit narrower, will be executed by TikZ with options
+which are the other keys in the argument of |\TikzEveryCell|.
+
+\medskip
+\begingroup
+\bigskip
+\begin{BVerbatim}[baseline=c,boxwidth=9cm]
+\renewcommand{\arraystretch}{1.3}
+\begin{NiceTabular}{ccc}[corners]
+  & \Block{1-2}{columns} \\
+  \Block{2-1}{rows}
+  & cell 1 1 & cell 1 2 \\
+  & cell 2 1 & cell 2 2
+\CodeAfter
+  ~emphase#\TikzEveryCell{offset=1pt,draw}@
+\end{NiceTabular}
+\end{BVerbatim}
+\renewcommand{\arraystretch}{1.3}
+\begin{NiceTabular}{ccc}[corners]
+  & \Block{1-2}{columns} \\
+  \Block{2-1}{rows}
+  & cell 1 1 & cell 1 2 \\
+  & cell 2 1 & cell 2 2
+\CodeAfter
+  \TikzEveryCell{offset=1pt,draw}
+\end{NiceTabular}
+\endgroup
+
+\bigskip
+The command |\TikzEveryCell| has two keys:
+\begin{itemize}
+\item with the key \Definition{empty}, the command only acts on the empty cells;
+
+\item with key \Definition{non-empty}, the command only acts on the non-empty cells.
+\end{itemize}
+
+\medskip
+The commmand |\TikzEveryCell| is, in fact, also available in the |\CodeBefore|.
+
+
 \index{CodeAfter@\texttt{\textbackslash CodeAfter}|)}
 
 \section{Captions and notes in the tabulars}
@@ -4421,9 +4523,9 @@
 \end{itemize}
 
 
-\colorbox{yellow!50}{New 6.21}\enskip That key is available in all
-the environments and commands (e.g. |\pAutoNiceMatrix|) of \pkg{nicematrix} and also
-in the command |\NiceMatrixOptions|.
+That key is available in all the environments and commands (e.g.
+|\pAutoNiceMatrix|) of \pkg{nicematrix} and also in the command
+|\NiceMatrixOptions|.
 
 \bigskip
 \begin{BVerbatim}[baseline=c,boxwidth=9cm]
@@ -4616,10 +4718,9 @@
 \end{varwidth}
 
 \bigskip
-\colorbox{yellow!50}{\textbf{New 6.21}}\enskip The command |\rotate| has a key
-|c|: |\rotate[c]| (spaces are deleted after |\rotate[c]|). When that key is
-used, the content is composed in a |\vcenter| and, therefore, in most cases, we
-will have a vertical alignment.
+The command |\rotate| has a key |c|: |\rotate[c]| (spaces are deleted after
+|\rotate[c]|). When that key is used, the content is composed in a |\vcenter|
+and, therefore, in most cases, we will have a vertical alignment.
 
 \bigskip
 Caution: the command |\rotate| is designed to be used in a |\Block| or in
@@ -6961,6 +7062,15 @@
 \nolinkurl{https:www.tug.org/svn/texlive/trunk/Master/texmf-dist/tex/latex/nicematrix/nicematrix.sty}
 }
 
+
+\subsection*{Changes between version 6.23 and 6.24}
+
+New command |\TikzEveryCell| available in the |\CodeAfter| and the |\CodeBefore|
+to apply the same TikZ instruction to all the cells and blocks of the array.
+
+New key |offset| in the key |tikz| of a command |\Block|.
+
+
 \subsection*{Changes between version 6.22 and 6.23}
 
 The specifier ``\verb+|+'' in the preambles of the environments has now an
@@ -6982,7 +7092,7 @@
 
 New commands |\rowcolors| and |\rowlistcolors| available in the array itself
 (previously, there were only two commands |\rowcolors| and |\rowlistcolors|
-avaailable in the |\CodeBefore|.
+available in the |\CodeBefore|.
 
 
 \subsection*{Changes between version 6.20 and 6.20a}

Modified: trunk/Master/texmf-dist/source/latex/nicematrix/nicematrix-code.dtx
===================================================================
--- trunk/Master/texmf-dist/source/latex/nicematrix/nicematrix-code.dtx	2023-09-29 21:04:41 UTC (rev 68397)
+++ trunk/Master/texmf-dist/source/latex/nicematrix/nicematrix-code.dtx	2023-09-29 21:05:29 UTC (rev 68398)
@@ -17,11 +17,11 @@
 %
 % \fi
 % \iffalse
-\def\myfileversion{6.23}
-\def\myfiledate{2023/09/02}
+\def\myfileversion{6.24}
+\def\myfiledate{2023/09/28}
 %
 %
-%<*batchfile>
+%<*batchfile>  
 \begingroup
 \input l3docstrip.tex
 \keepsilent
@@ -708,41 +708,7 @@
 %    \end{macrocode}
 % 
 % \bigskip
-% \textbf{The column S of siunitx}\par\nobreak
-%
-% The command |\@@_renew_NC at rewrite@S:| will be used in each environment of
-% \pkg{nicematrix} in order to ``rewrite'' the |S| column in each environment.
 %    \begin{macrocode}
-\hook_gput_code:nnn { begindocument } { . }
-  {
-    \IfPackageLoadedTF { siunitx }
-      {
-        \cs_new_protected:Npn \@@_renew_NC at rewrite@S:
-          {
-            \renewcommand*{\NC at rewrite@S}[1][]
-              {
-%    \end{macrocode}
-% |\@temptokena| is a toks (not supported by the L3 programming layer).
-%    \begin{macrocode}
-                \tl_if_empty:nTF { ##1 }
-                  {
-                    \@temptokena \exp_after:wN 
-                      { \tex_the:D \@temptokena \@@_S: } 
-                  }
-                  {
-                    \@temptokena \exp_after:wN 
-                      { \tex_the:D \@temptokena \@@_S: [ ##1 ] } 
-                  }
-                \NC at find
-              }
-          }
-      }
-      { \cs_set_eq:NN \@@_renew_NC at rewrite@S: \prg_do_nothing: }
-  }
-%    \end{macrocode}
-%
-% \bigskip
-%    \begin{macrocode}
 \cs_new_protected:Npn \@@_rescan_for_spanish:N #1
   { 
     \tl_set_rescan:Nno 
@@ -965,6 +931,13 @@
 %    \begin{macrocode}
 \dim_new:N \l_@@_rule_width_dim 
 %    \end{macrocode}
+%
+% \bigskip
+% The key |color| in a command of rule such as |\Hline| (or the specifier
+% ``\verb+|+'' in the preamble of an environment).
+%    \begin{macrocode}
+\tl_new:N \l_@@_rule_color_tl
+%    \end{macrocode}
 % 
 % \bigskip
 % The following boolean will be raised when the command |\rotate| is used.
@@ -1017,6 +990,22 @@
 %    \begin{macrocode}
 \tl_new:N \g_@@_left_delim_tl 
 \tl_new:N \g_@@_right_delim_tl
+%    \end{macrocode}
+%
+% \bigskip
+% The token list |\g_@@_user_preamble_tl| will contain the preamble provided by
+% the the final user of \pkg{nicematrix} (eg the preamble of an environment
+% |{NiceTabular}|). 
+%    \begin{macrocode}
+\tl_new:N \g_@@_user_preamble_tl
+%    \end{macrocode}
+% The token list |\g_@@_array_preamble_tl| will contain the preamble constructed
+% by \pkg{nicematrix} for the environment |{array}| (of \pkg{array}).
+%    \begin{macrocode}
+\tl_new:N \g_@@_array_preamble_tl
+%    \end{macrocode}
+% For |\multicolumn|.
+%    \begin{macrocode}
 \tl_new:N \g_@@_preamble_tl
 %    \end{macrocode}
 % 
@@ -1023,15 +1012,10 @@
 % \bigskip
 % The following parameter corresponds to the key |columns-type| of the
 % environments |{NiceMatrix}|, |{pNiceMatrix}|, etc. and also the key 
-% |matrix / columns-type| of |\NiceMatrixOptions|. However, it does \emph{not}
-% contain the value provided by the final user. Indeed, a transformation is done
-% in order to have a preamble (for the package \pkg{array}) which is
-% nicematrix-aware. That transformation is done with the command
-% |\@@_set_preamble:Nn|. 
+% |matrix / columns-type| of |\NiceMatrixOptions|. 
 %    \begin{macrocode}
 \tl_new:N \l_@@_columns_type_tl
-\hook_gput_code:nnn { begindocument } { . }
-  { \@@_set_preamble:Nn \l_@@_columns_type_tl { c } }
+\tl_set:Nn \l_@@_columns_type_tl { c } 
 %    \end{macrocode}
 %
 % \bigskip
@@ -1432,6 +1416,15 @@
 %    \begin{macrocode}
 \tl_new:N \l_@@_color_tl
 %    \end{macrocode}
+%
+% \medskip
+% In the key |tikz| of a command |\Block| or in the argument of a command
+% |\TikzEveryCell|, the final user puts a list of tikz keys. But, you have added
+% another key, named |offset| (which means that an offset will be used for the
+% frame of the block or the cell). The following parameter corresponds to that key.
+%    \begin{macrocode}
+\dim_new:N \l_@@_offset_dim 
+%    \end{macrocode}
 % 
 % \medskip
 % Here is the dimension for the width of the rule when a block (created by
@@ -2363,10 +2356,9 @@
 \bool_new:N \l_@@_delimiters_max_width_bool
 %    \end{macrocode}
 % 
+%
 % \bigskip
 %    \begin{macrocode}
-% \bigskip
-%    \begin{macrocode}
 \keys_define:nn { NiceMatrix / xdots }
   {
     shorten-start .code:n = 
@@ -2663,6 +2655,7 @@
     SubMatrix / rules .inherit:n = NiceMatrix / rules ,  
     CodeAfter / xdots .inherit:n = NiceMatrix / xdots ,
     CodeBefore / sub-matrix .inherit:n = NiceMatrix / sub-matrix ,
+    CodeAfter / sub-matrix .inherit:n = NiceMatrix / sub-matrix ,
     NiceMatrix .inherit:n = 
       { 
         NiceMatrix / Global ,
@@ -2759,8 +2752,7 @@
     notes .value_required:n = true ,
     sub-matrix .code:n = \keys_set:nn { NiceMatrix / sub-matrix } { #1 } , 
     sub-matrix .value_required:n = true ,
-    matrix / columns-type .code:n = 
-      \@@_set_preamble:Nn \l_@@_columns_type_tl { #1 },
+    matrix / columns-type .tl_set:N = \l_@@_columns_type_tl ,
     matrix / columns-type .value_required:n = true ,
     caption-above .bool_set:N = \l_@@_caption_above_bool ,
     caption-above .default:n = true , 
@@ -2794,7 +2786,7 @@
                            \int_set:Nn \l_@@_last_col_int { -1 }
                          }
                          { \int_set:Nn \l_@@_last_col_int { #1 } } ,
-    columns-type .code:n = \@@_set_preamble:Nn \l_@@_columns_type_tl { #1 } , 
+    columns-type .tl_set:N = \l_@@_columns_type_tl , 
     columns-type .value_required:n = true , 
     l .meta:n = { columns-type = l } ,
     r .meta:n = { columns-type = r } ,
@@ -2892,7 +2884,32 @@
   }
 %    \end{macrocode}
 %
+%
+% \bigskip
+% The |\CodeAfter| (inserted with the key |code-after| or after the keyword
+% |\CodeAfter|) may always begin with a list of pairs \textsl{key=value} between
+% square brackets. Here is the corresponding set of keys.
+%
+% We \emph{must} put the following instructions \emph{after} the :
+%
+% \begin{verbatim}
+% CodeAfter / sub-matrix .inherit:n = NiceMatrix / sub-matrix
+% \end{verbatim}
 % 
+%    \begin{macrocode}
+\keys_define:nn { NiceMatrix / CodeAfter }
+  {
+    delimiters / color .tl_set:N = \l_@@_delimiters_color_tl ,
+    delimiters / color .value_required:n = true ,
+    rules .code:n = \keys_set:nn { NiceMatrix / rules } { #1 } ,
+    rules .value_required:n = true ,
+    xdots .code:n = \keys_set:nn { NiceMatrix / xdots } { #1 } , 
+    sub-matrix .code:n = \keys_set:nn { NiceMatrix / sub-matrix } { #1 } , 
+    sub-matrix .value_required:n = true ,
+    unknown .code:n = \@@_error:n { Unknown~key~for~CodeAfter }
+  }
+%    \end{macrocode}
+% 
 % \bigskip
 % \section{Important code used by \{NiceArrayWithDelims\} }
 %
@@ -3459,19 +3476,6 @@
   }
 %    \end{macrocode}
 %
-% \bigskip
-% The command |\@@_newcolumntype| is the command |\newcolumntype| of
-% \pkg{array} without the warnings for redefinitions of columns types (we will
-% use it to redefine the columns types |w| and |W|).
-%    \begin{macrocode}
-\cs_set_protected:Npn \@@_newcolumntype #1
-  {
-    \cs_set:cpn { NC @ find @ #1 } ##1 #1 { \NC@ { ##1 } }
-    \peek_meaning:NTF [ 
-      { \newcol@ #1 }
-      { \newcol@ #1 [ 0 ] }
-  }   
-%    \end{macrocode}
 % 
 %
 % \bigskip
@@ -3712,10 +3716,6 @@
 %    \begin{macrocode}
     \cs_set_eq:NN \@ifnextchar \new at ifnextchar
 %    \end{macrocode}
-%
-%    \begin{macrocode}
-    \@@_renew_NC at rewrite@S:
-%    \end{macrocode}
 % 
 %    \begin{macrocode}
     \bool_gset_false:N \g_@@_last_col_found_bool 
@@ -3998,6 +3998,7 @@
     \cs_set_eq:NN \chessboardcolors \@@_chessboardcolors
     \cs_set_eq:NN \SubMatrix \@@_SubMatrix_in_code_before
     \cs_set_eq:NN \ShowCellNames \@@_ShowCellNames
+    \cs_set_eq:NN \TikzEveryCell \@@_TikzEveryCell
   }
 %    \end{macrocode}
 % 
@@ -4231,7 +4232,7 @@
 %    \begin{macrocode}
     \tl_gset:Nn \g_@@_left_delim_tl { #1 }
     \tl_gset:Nn \g_@@_right_delim_tl { #2 }
-    \tl_gset:Nn \g_@@_preamble_tl { #4 }
+    \tl_gset:Nn \g_@@_user_preamble_tl { #4 }
 %    \end{macrocode}
 %   
 %
@@ -4611,20 +4612,17 @@
 % \vspace{1cm}
 % \section{We construct the preamble of the array}
 %
-% \bigskip
-% The transformation of the preamble is an operation in several
-% steps.\footnote{Be careful: the transformation of the preamble may also have
-% by-side effects, for example, the boolean |\g_@@_delims_bool| will be set
-% to |true| if we detect in the preamble a delimiter at the beginning or at the
-% end.}
+% \bigskip 
+% The final user provides a preamble, but we must convert that preamble into a
+% preamble that will be given to |{array}| (of the package \pkg{array}).
 %
 % \bigskip
-% The preamble given by the final user is in |\g_@@_preamble_tl| and the modified
-% version will be stored in |\g_@@_preamble_tl| also.
+% The preamble given by the final user is stored in |\g_@@_user_preamble_tl|.
+% The modified version will be stored in |\g_@@_array_preamble_tl| also.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_transform_preamble:
   {
-    \bool_if:NT \l_@@_preamble_bool \@@_transform_preamble_i:
+    \@@_transform_preamble_i:
     \@@_transform_preamble_ii:
   }
 %    \end{macrocode}
@@ -4632,97 +4630,50 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_transform_preamble_i:
   {
-%    \end{macrocode}
-% First, we will do an ``expansion'' of the preamble with the tools of the
-% package \pkg{array} itself. This ``expansion'' will expand all the constructions
-% with |*| and all column types (defined by the user or by various packages
-% using |\newcolumntype|).
-%
-% Since we use the tools of \pkg{array} to do this expansion, we will have a
-% programmation which is not in the style of the L3 programming layer.
-% 
-%
-% \bigskip
-% We redefine the column types |w| and |W|. We use |\@@_newcolumntype| instead
-% of |\newcolumtype| because we don't want warnings for column types already
-% defined. These redefinitions are in fact \emph{protections} of the letters |w|
-% and |W|. We don't want these columns type expanded because we will do the
-% patch ourselves after. We want to be able to use the standard column types |w|
-% and |W| in potential |{tabular}| of \pkg{array} in some cells of our array.
-% That's why we do those redefinitions in a TeX group.
-%   \begin{macrocode}
+    \int_gzero:N \c at jCol
     \group_begin:
-    \@@_newcolumntype w [ 2 ] { \@@_w: { ##1 } { ##2 } }
-    \@@_newcolumntype W [ 2 ] { \@@_W: { ##1 } { ##2 } }
 %    \end{macrocode}
-%
-% \bigskip
-% If the package \pkg{varwidth} has defined the column type |V|, we protect from
-% expansion by redefining it to |\@@_V:| (which will be catched by our system).
+% The sequence |\g_@@_cols_vlsim_seq| will contain the numbers of the columns
+% where you will to have to draw vertical lines in the potential sub-matrices
+% (hence the name |vlism|). 
 %    \begin{macrocode}
-     \cs_if_exist:NT \NC at find@V { \@@_newcolumntype V { \@@_V: } }
+    \seq_gclear:N \g_@@_cols_vlism_seq 
 %    \end{macrocode}
-%
-% First, we have to store our preamble in the token register |\@temptokena|
-% (those ``token registers'' are \emph{not} supported by the L3 programming layer).
+% |\g_tmpb_bool| will be raised if you have a \verb+|+ at the end of the
+% preamble provided by the final user.
 %    \begin{macrocode}
-    \exp_args:NV \@temptokena \g_@@_preamble_tl 
+    \bool_gset_false:N \g_tmpb_bool
 %    \end{macrocode}
-% Initialisation of a flag used by \pkg{array} to detect the end of the expansion.
+%
+% The following sequence will store the arguments of the successive |>| in the
+% preamble. 
 %    \begin{macrocode}
-    \@tempswatrue
+    \tl_gclear_new:N \g_@@_pre_cell_tl
 %    \end{macrocode}
-% The following line actually does the expansion (it's has been copied from
-% |array.sty|). The expanded version is still in |\@temptokena|.
+% The counter |\l_tmpa_int| will count the number of consecutive occurrences
+% of the symbol \verb+|+.
 %    \begin{macrocode}
-    \@whilesw \if at tempswa \fi { \@tempswafalse \the \NC at list }
-    \int_gzero:N \c at jCol
-    \tl_gclear:N \g_@@_preamble_tl 
-%    \end{macrocode}
-% |\g_tmpb_bool| will be raised if you have a \verb+|+ at the end of the preamble.
-%    \begin{macrocode}
-    \bool_gset_false:N \g_tmpb_bool
+    \int_zero:N \l_tmpa_int
+    \tl_gclear:N \g_@@_array_preamble_tl 
     \tl_if_eq:NnTF \l_@@_vlines_clist { all } 
       { 
-        \tl_gset:Nn \g_@@_preamble_tl 
+        \tl_gset:Nn \g_@@_array_preamble_tl 
           { ! { \skip_horizontal:N \arrayrulewidth } }
       }
       {
         \clist_if_in:NnT \l_@@_vlines_clist 1 
           { 
-            \tl_gset:Nn \g_@@_preamble_tl 
+            \tl_gset:Nn \g_@@_array_preamble_tl 
               { ! { \skip_horizontal:N \arrayrulewidth } }
           }
       }
 %    \end{macrocode}
-% The sequence |\g_@@_cols_vlsim_seq| will contain the numbers of the columns
-% where you will to have to draw vertical lines in the potential sub-matrices
-% (hence the name |vlism|). 
+% Now, we actually make the preamble (which will be given to |{array}|). It will
+% be stored in |\g_@@_array_preamble_tl|.
 %    \begin{macrocode}
-    \seq_clear:N \g_@@_cols_vlism_seq 
-%    \end{macrocode}
-%
-% \bigskip
-% The following sequence will store the arguments of the successive |>| in the
-% preamble. 
-%    \begin{macrocode}
-    \tl_gclear_new:N \g_@@_pre_cell_tl
-%    \end{macrocode}
-%
-% The counter |\l_tmpa_int| will count the number of consecutive occurrences
-% of the symbol \verb+|+.
-%    \begin{macrocode}
-    \int_zero:N \l_tmpa_int
-%    \end{macrocode}
-% Now, we actually patch the preamble (and it is constructed in
-% |\g_@@_preamble_tl|). 
-%    \begin{macrocode}
-    \exp_after:wN \@@_patch_preamble:n \the \@temptokena \q_stop
+    \exp_last_unbraced:NV \@@_make_preamble:n \g_@@_user_preamble_tl \q_stop
     \int_gset_eq:NN \g_@@_static_num_of_col_int \c at jCol
 %    \end{macrocode}
-% Remark that |\g_@@_static_num_of_col_int| will stay equel to zero in the
-% environments without preamble since we are in a code that is executed only
-% in the environments \emph{with} preamble.
 %
 % \medskip
 % Now, we replace |\columncolor| by |\@@_columncolor_preamble|.
@@ -4732,28 +4683,18 @@
         \regex_replace_all:NnN 
           \c_@@_columncolor_regex
           { \c { @@_columncolor_preamble } }  
-          \g_@@_preamble_tl
+          \g_@@_array_preamble_tl
       }
 %    \end{macrocode}
 %
 % \medskip
-% Now, we can close the TeX group which was opened for the redefinition of
-% the columns of type |w| and~|W|. 
+% We are not sure that the following TeX group is still necessary.
 %    \begin{macrocode}
     \group_end:
   }
 %    \end{macrocode}
 % 
-%
-% 
 % \bigskip
-% Now, we have to ``patch'' that preamble by transforming some columns. 
-% We will insert in the TeX flow the preamble in its actual form (that is to say
-% after the ``expansion'') following by a marker |\q_stop| and we will consume
-% these tokens constructing the (new form of the) preamble in
-% |\g_@@_preamble_tl|. This is done recursively with the command
-% |\@@_patch_preamble:n|. In the same time, we will count the columns with the
-% counter |\c at jCol|.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_transform_preamble_ii:
   {
@@ -4779,7 +4720,7 @@
 % We complete the preamble with the potential ``exterior columns'' (on both sides).
 %    \begin{macrocode}
     \int_compare:nNnTF \l_@@_first_col_int = 0
-      { \tl_gput_left:NV \g_@@_preamble_tl \c_@@_preamble_first_col_tl }
+      { \tl_gput_left:NV \g_@@_array_preamble_tl \c_@@_preamble_first_col_tl }
       {
         \bool_lazy_all:nT 
           { 
@@ -4788,10 +4729,10 @@
             { \tl_if_empty_p:N \l_@@_vlines_clist } 
             { \bool_not_p:n \l_@@_exterior_arraycolsep_bool }
           }
-          { \tl_gput_left:Nn \g_@@_preamble_tl { @ { } } }
+          { \tl_gput_left:Nn \g_@@_array_preamble_tl { @ { } } }
       }
     \int_compare:nNnTF \l_@@_last_col_int > { -1 }
-      { \tl_gput_right:NV \g_@@_preamble_tl \c_@@_preamble_last_col_tl }
+      { \tl_gput_right:NV \g_@@_array_preamble_tl \c_@@_preamble_last_col_tl }
       { 
         \bool_lazy_all:nT
           { 
@@ -4800,7 +4741,7 @@
             { \tl_if_empty_p:N \l_@@_vlines_clist } 
             { \bool_not_p:n \l_@@_exterior_arraycolsep_bool }
           }
-          { \tl_gput_right:Nn \g_@@_preamble_tl { @ { } } }
+          { \tl_gput_right:Nn \g_@@_array_preamble_tl { @ { } } }
       }
 %    \end{macrocode}
 % We add a last column to raise a good error message when the user puts more
@@ -4810,7 +4751,7 @@
 %    \begin{macrocode}
     \dim_compare:nNnT \l_@@_tabular_width_dim = \c_zero_dim 
       { 
-        \tl_gput_right:Nn \g_@@_preamble_tl 
+        \tl_gput_right:Nn \g_@@_array_preamble_tl 
           { > { \@@_error_too_much_cols: } l }
       } 
   }
@@ -4817,54 +4758,24 @@
 %    \end{macrocode}
 %
 % \bigskip
-% The command |\@@_patch_preamble:n| is the main function for the transformation
+% The command |\@@_make_preamble:n| is the main function for the creation
 % of the preamble. It is recursive.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble:n #1
+\cs_new_protected:Npn \@@_make_preamble:n #1
   {
-    \str_case:nnF { #1 }
+    \str_if_eq:nnF { #1 } { \q_stop }
       {
-        c       { \@@_patch_preamble_i:n #1 }
-        l       { \@@_patch_preamble_i:n #1 }
-        r       { \@@_patch_preamble_i:n #1 }
-        >       { \@@_patch_preamble_xiv:n }
-        !       { \@@_patch_preamble_ii:nn #1 }
-        @       { \@@_patch_preamble_ii:nn #1 }
-        |       { \@@_patch_preamble_iii:n #1 }
-        p       { \@@_patch_preamble_iv:n #1 }
-        b       { \@@_patch_preamble_iv:n #1 }
-        m       { \@@_patch_preamble_iv:n #1 }
-        \@@_V:  { \@@_patch_preamble_v:n }
-        V       { \@@_patch_preamble_v:n } 
-        \@@_w:  { \@@_patch_preamble_vi:nnnn { } #1 } 
-        \@@_W:  { \@@_patch_preamble_vi:nnnn { \@@_special_W: } #1 } 
-        \@@_S:  { \@@_patch_preamble_vii:n }
-        (       { \@@_patch_preamble_viii:nn #1 }
-        [       { \@@_patch_preamble_viii:nn #1 }
-        \{      { \@@_patch_preamble_viii:nn #1 }
-        \left   { \@@_patch_preamble_viii:nn }
-        )       { \@@_patch_preamble_ix:nn #1 }       
-        ]       { \@@_patch_preamble_ix:nn #1 }       
-        \}      { \@@_patch_preamble_ix:nn #1 }       
-        \right  { \@@_patch_preamble_ix:nn }
-        X       { \@@_patch_preamble_x:n }
-%    \end{macrocode}
-% When \pkg{tabularx} is loaded, a local redefinition of the specifier |X| is
-% done to replace |X| by |\@@_X|. Thus, our column type |X| will be used in the
-% |{NiceTabularX}|. 
-%    \begin{macrocode}
-        \@@_X   { \@@_patch_preamble_x:n }
-        \q_stop { }
-      }
-      { 
-        \str_if_eq:nVTF { #1 } \l_@@_letter_vlism_tl 
+        \cs_if_exist:cTF { @@ \token_to_str:N #1 }
+          { \use:c { @@ \token_to_str:N #1 } { #1 } }
           { 
-            \seq_gput_right:Nx \g_@@_cols_vlism_seq 
-              { \int_eval:n { \c at jCol + 1 } }
-            \tl_gput_right:Nx \g_@@_preamble_tl
-              { \exp_not:N ! { \skip_horizontal:N \arrayrulewidth } }
-            \@@_patch_preamble:n
-          }
+            \str_if_eq:nVTF { #1 } \l_@@_letter_vlism_tl 
+              { 
+                \seq_gput_right:Nx \g_@@_cols_vlism_seq 
+                  { \int_eval:n { \c at jCol + 1 } }
+                \tl_gput_right:Nx \g_@@_array_preamble_tl
+                  { \exp_not:N ! { \skip_horizontal:N \arrayrulewidth } }
+                \@@_make_preamble:n
+              }
 %    \end{macrocode}
 % Now the case of a letter set by the final user for a customized rule. Such
 % customized rule is defined by using the key |custom-line| in
@@ -4876,16 +4787,24 @@
 % keys of that set of keys won't never be used as keys by the final user (he
 % will use, instead, letters in the preamble of its array).
 %    \begin{macrocode}
-          { 
-            \keys_if_exist:nnTF { NiceMatrix / ColumnTypes } { #1 } 
-              {
-                \keys_set:nn { NiceMatrix / ColumnTypes } { #1 } 
-                \@@_patch_preamble:n 
-              }
               { 
-                \tl_if_eq:nnT { #1 } { S }
-                  { \@@_fatal:n { unknown~column~type~S } }
-                  { \@@_fatal:nn { unknown~column~type } { #1 } }
+                \keys_if_exist:nnTF { NiceMatrix / ColumnTypes } { #1 } 
+                  {
+                    \keys_set:nn { NiceMatrix / ColumnTypes } { #1 } 
+                    \@@_make_preamble:n 
+                  }
+                  { 
+                    \cs_if_exist:cTF { NC @ find @ #1 }
+                      {
+                        \tl_set_eq:Nc \l_tmpb_tl { NC @ rewrite @ #1 }
+                        \exp_last_unbraced:NV \@@_make_preamble:n \l_tmpb_tl
+                      }
+                      { 
+                        \tl_if_eq:nnT { #1 } { S }
+                          { \@@_fatal:n { unknown~column~type~S } }
+                          { \@@_fatal:nn { unknown~column~type } { #1 } }
+                      }
+                  }
               }
           }
       }
@@ -4892,19 +4811,48 @@
   }
 %    \end{macrocode}
 %
-% 
 % \bigskip
 % Now, we will list all the auxiliary functions for the different types of
 % entries in the preamble of the array.
+%    \begin{macrocode}
+\cs_new:cpn { @@ \string c }        { \@@_make_preamble_i:n }
+\cs_new:cpn { @@ \string l }        { \@@_make_preamble_i:n }
+\cs_new:cpn { @@ \string r }        { \@@_make_preamble_i:n }
+\cs_new:cpn { @@ \string > }        { \@@_make_preamble_xiv:nn }
+\cs_new:cpn { @@ \string ! }        { \@@_make_preamble_ii:nn }
+\cs_new:cpn { @@ \string @ }        { \@@_make_preamble_ii:nn }
+\cs_new:cpn { @@ \string | }        { \@@_make_preamble_iii:n }
+\cs_new:cpn { @@ \string p }        { \@@_make_preamble_iv:n }
+\cs_new:cpn { @@ \string b }        { \@@_make_preamble_iv:n }
+\cs_new:cpn { @@ \string m }        { \@@_make_preamble_iv:n }
+\cs_new:cpn { @@ \string V }        { \@@_make_preamble_v:nn } 
+\cs_new:cpn { @@ \string w }        { \@@_make_preamble_vi:nnnn { } } 
+\cs_new:cpn { @@ \string W }        { \@@_make_preamble_vi:nnnn { \@@_special_W: } } 
+\cs_new:cpn { @@ \string S }        { \@@_make_preamble_vii:nn }
+\cs_new:cpn { @@ \string ( }        { \@@_make_preamble_viii:nn }
+\cs_new:cpn { @@ \string [ }        { \@@_make_preamble_viii:nn }
+\cs_new:cpn { @@ \string \{ }       { \@@_make_preamble_viii:nn }
+\cs_new:cpn { @@ \string \left }    { \@@_make_preamble_viii_ii:n }
+\cs_new:cpn { @@ \string ) }        { \@@_make_preamble_ix:nn }       
+\cs_new:cpn { @@ \string ] }        { \@@_make_preamble_ix:nn }       
+\cs_new:cpn { @@ \string \} }       { \@@_make_preamble_ix:nn }       
+\cs_new:cpn { @@ \string \right }   { \@@_make_preamble_ix_ii:n }
+\cs_new:cpn { @@ \string X }        { \@@_make_preamble_x:nn }
+\cs_new:cpn { @@ \string * }        { \@@_make_preamble_xvi:nnn }
+\cs_new:cpn { @@ \string \NC at find } { \@@_make_preamble_xx:n }
+%    \end{macrocode}
+% The token |\NC at find| is at the head of the definition of the columns type done
+% by |\newcolumntype|. We wan't that token to be no-op here.
+%
 % 
-% \medskip
+% \bigskip
 % For |c|, |l| and |r|
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_i:n #1
+\cs_new_protected:Npn \@@_make_preamble_i:n #1
   { 
-    \tl_gput_right:NV \g_@@_preamble_tl \g_@@_pre_cell_tl 
+    \tl_gput_right:NV \g_@@_array_preamble_tl \g_@@_pre_cell_tl 
     \tl_gclear:N \g_@@_pre_cell_tl
-    \tl_gput_right:Nn \g_@@_preamble_tl 
+    \tl_gput_right:Nn \g_@@_array_preamble_tl 
       { 
         > { \@@_cell_begin:w \str_set:Nn \l_@@_hpos_cell_str { #1 } } 
         #1 
@@ -4915,7 +4863,7 @@
 % We increment the counter of columns and then we test for the presence of a |<|.
 %    \begin{macrocode}
     \int_gincr:N \c at jCol
-    \@@_patch_preamble_xi:n
+    \@@_make_preamble_xi:n
   }
 %    \end{macrocode}
 % 
@@ -4922,10 +4870,10 @@
 % \medskip
 % For |>|, |!| and |@|
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_ii:nn #1 #2
+\cs_new_protected:Npn \@@_make_preamble_ii:nn #1 #2
   {  
-    \tl_gput_right:Nn \g_@@_preamble_tl { #1 { #2 } }
-    \@@_patch_preamble:n
+    \tl_gput_right:Nn \g_@@_array_preamble_tl { #1 { #2 } }
+    \@@_make_preamble:n
   }
 %    \end{macrocode}
 %
@@ -4933,34 +4881,41 @@
 % \medskip
 % For \verb+|+
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_iii:n #1
+\cs_new_protected:Npn \@@_make_preamble_iii:n #1
   { 
 %    \end{macrocode}
 % |\l_tmpa_int| is the number of successive occurrences of \verb+|+
 %    \begin{macrocode}
     \int_incr:N \l_tmpa_int 
-    \@@_patch_preamble_iii_i:n
+    \@@_make_preamble_iii_i:n
   }
 %    \end{macrocode}
 % 
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_iii_i:n #1
+\cs_new_protected:Npn \@@_make_preamble_iii_i:n #1
   {
     \str_if_eq:nnTF { #1 } | 
-      { \@@_patch_preamble_iii:n | }
-      {
-        \str_if_eq:nnTF { #1 } [
-          { \@@_patch_preamble_iii_ii:nw { } [ }
-          { \@@_patch_preamble_iii_ii:nw { #1 } [ ] }
-      }
+      { \@@_make_preamble_iii:n | }
+      { \@@_make_preamble_iii_ii:nn { } #1 }
   }
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_iii_ii:nw #1 [ #2 ]
+\cs_new_protected:Npn \@@_make_preamble_iii_ii:nn #1 #2
   {
+    \str_if_eq:nnTF { #2 } [
+      { \@@_make_preamble_iii_ii:nw { #1 } [ }
+      { \@@_make_preamble_iii_iii:nn { #2 } { #1 } }
+  }
+\cs_new_protected:Npn \@@_make_preamble_iii_ii:nw #1 [ #2 ]  
+  { \@@_make_preamble_iii_ii:nn { #1 , #2 } }
+%    \end{macrocode}
+% 
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_make_preamble_iii_iii:nn #1 #2
+  {
     \@@_compute_rule_width:n { multiplicity = \l_tmpa_int , #2 }
-    \tl_gput_right:Nx \g_@@_preamble_tl
+    \tl_gput_right:Nx \g_@@_array_preamble_tl
       { 
 %    \end{macrocode}
 % Here, the command |\dim_eval:n| is mandatory.
@@ -4984,15 +4939,15 @@
       }
     \int_zero:N \l_tmpa_int
     \str_if_eq:nnT { #1 } { \q_stop } { \bool_gset_true:N \g_tmpb_bool } 
-    \@@_patch_preamble:n #1 
+    \@@_make_preamble:n #1 
   }
 %    \end{macrocode}
 % 
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_xiv:n #1 
+\cs_new_protected:Npn \@@_make_preamble_xiv:nn #1 #2
   { 
-    \tl_gput_right:Nn \g_@@_pre_cell_tl { > { #1 } } 
-    \@@_patch_preamble:n 
+    \tl_gput_right:Nn \g_@@_pre_cell_tl { > { #2 } } 
+    \@@_make_preamble:n 
   }
 %    \end{macrocode}
 % 
@@ -5053,7 +5008,7 @@
 % \medskip
 % For |p|, |b| and |m|. The argument |#1| is that value : |p|, |b| or |m|.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_iv:n #1
+\cs_new_protected:Npn \@@_make_preamble_iv:n #1
   { 
     \str_set:Nn \l_@@_vpos_col_str { #1 }
 %    \end{macrocode}
@@ -5060,22 +5015,22 @@
 % Now, you look for a potential character |[| after the letter of the specifier
 % (for the options).
 %    \begin{macrocode}
-    \@@_patch_preamble_iv_i:n 
+    \@@_make_preamble_iv_i:n 
   }
 %    \end{macrocode}
 % 
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_iv_i:n #1
+\cs_new_protected:Npn \@@_make_preamble_iv_i:n #1
   {
     \str_if_eq:nnTF { #1 } { [ }
-      { \@@_patch_preamble_iv_ii:w [ }
-      { \@@_patch_preamble_iv_ii:w [ ] { #1 } }
+      { \@@_make_preamble_iv_ii:w [ }
+      { \@@_make_preamble_iv_ii:w [ ] { #1 } }
   }
 %    \end{macrocode}
 % 
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_iv_ii:w [ #1 ]
-  { \@@_patch_preamble_iv_iii:nn { #1 } }
+\cs_new_protected:Npn \@@_make_preamble_iv_ii:w [ #1 ]
+  { \@@_make_preamble_iv_iii:nn { #1 } }
 %    \end{macrocode}
 % 
 % \medskip
@@ -5084,7 +5039,7 @@
 %
 % |#2| is the mandatory argument of the specifier: the width of the column.
 %    \begin{macrocode}  
-\cs_new_protected:Npn \@@_patch_preamble_iv_iii:nn #1 #2 
+\cs_new_protected:Npn \@@_make_preamble_iv_iii:nn #1 #2 
   {  
 %    \end{macrocode}
 % The possible values of |\l_@@_hpos_col_str| are |j| (for \emph{justified} which is
@@ -5093,9 +5048,8 @@
 %    \begin{macrocode}
     \str_set:Nn \l_@@_hpos_col_str { j }
     \tl_set:Nn \l_tmpa_tl { #1 }
-    \tl_replace_all:Nnn \l_tmpa_tl { \@@_S: } { S }
     \@@_keys_p_column:V \l_tmpa_tl 
-    \@@_patch_preamble_iv_iv:nn { #2 } { minipage }
+    \@@_make_preamble_iv_iv:nn { #2 } { minipage }
   }
 %    \end{macrocode}
 %
@@ -5109,11 +5063,11 @@
 % The first argument is the width of the column. The second is the type of
 % environment: |minipage| or |varwidth|. 
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_iv_iv:nn #1 #2
+\cs_new_protected:Npn \@@_make_preamble_iv_iv:nn #1 #2
   {
     \use:x 
       { 
-        \@@_patch_preamble_iv_v:nnnnnnnn
+        \@@_make_preamble_iv_v:nnnnnnnn
           { \str_if_eq:VnTF \l_@@_vpos_col_str { p } { t } { b } }
           { \dim_eval:n { #1 } }
           {
@@ -5160,7 +5114,7 @@
 % We increment the counter of columns, and then we test for the presence of a |<|.
 %    \begin{macrocode}
     \int_gincr:N \c at jCol
-    \@@_patch_preamble_xi:n
+    \@@_make_preamble_xi:n
   }
 %    \end{macrocode}
 % 
@@ -5189,14 +5143,14 @@
 % |#8| is the letter |c| or |r| or |l| which is the basic specificier of column
 % which is used \emph{in fine}.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_iv_v:nnnnnnnn #1 #2 #3 #4 #5 #6 #7 #8
+\cs_new_protected:Npn \@@_make_preamble_iv_v:nnnnnnnn #1 #2 #3 #4 #5 #6 #7 #8
   {
     \str_if_eq:VnTF \l_@@_hpos_col_str { si }
-      { \tl_gput_right:Nn \g_@@_preamble_tl { > { \@@_test_if_empty_for_S: } } }
-      { \tl_gput_right:Nn \g_@@_preamble_tl { > { \@@_test_if_empty: } } }
-    \tl_gput_right:NV \g_@@_preamble_tl \g_@@_pre_cell_tl 
+      { \tl_gput_right:Nn \g_@@_array_preamble_tl { > { \@@_test_if_empty_for_S: } } }
+      { \tl_gput_right:Nn \g_@@_array_preamble_tl { > { \@@_test_if_empty: } } }
+    \tl_gput_right:NV \g_@@_array_preamble_tl \g_@@_pre_cell_tl 
     \tl_gclear:N \g_@@_pre_cell_tl
-    \tl_gput_right:Nn \g_@@_preamble_tl
+    \tl_gput_right:Nn \g_@@_array_preamble_tl
       {
         > { 
 %    \end{macrocode}
@@ -5324,26 +5278,25 @@
 % \medskip
 % For |V| (similar to the |V| of \pkg{varwidth}).
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_v:n #1
+\cs_new_protected:Npn \@@_make_preamble_v:nn #1 #2
   {
-    \str_if_eq:nnTF { #1 } { [ }
-      { \@@_patch_preamble_v_i:w [ }
-      { \@@_patch_preamble_v_i:w [ ] { #1 } }
+    \str_if_eq:nnTF { #2 } { [ }
+      { \@@_make_preamble_v_i:w [ }
+      { \@@_make_preamble_v_i:w [ ] { #2 } }
   }
-\cs_new_protected:Npn \@@_patch_preamble_v_i:w [ #1 ]
-  { \@@_patch_preamble_v_ii:nn { #1 } }
-\cs_new_protected:Npn \@@_patch_preamble_v_ii:nn #1 #2
+\cs_new_protected:Npn \@@_make_preamble_v_i:w [ #1 ]
+  { \@@_make_preamble_v_ii:nn { #1 } }
+\cs_new_protected:Npn \@@_make_preamble_v_ii:nn #1 #2
   {
     \str_set:Nn \l_@@_vpos_col_str { p }
     \str_set:Nn \l_@@_hpos_col_str { j }
     \tl_set:Nn \l_tmpa_tl { #1 }
-    \tl_replace_all:Nnn \l_tmpa_tl { \@@_S: } { S }
     \@@_keys_p_column:V \l_tmpa_tl 
     \IfPackageLoadedTF { varwidth }
-      { \@@_patch_preamble_iv_iv:nn { #2 } { varwidth } }
+      { \@@_make_preamble_iv_iv:nn { #2 } { varwidth } }
       { 
         \@@_error_or_warning:n { varwidth~not~loaded }
-        \@@_patch_preamble_iv_iv:nn { #2 } { minipage } 
+        \@@_make_preamble_iv_iv:nn { #2 } { minipage } 
       }
   }
 %    \end{macrocode}
@@ -5360,11 +5313,11 @@
 % |#4| is the width of the column.
 %
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_vi:nnnn #1 #2 #3 #4
+\cs_new_protected:Npn \@@_make_preamble_vi:nnnn #1 #2 #3 #4
   {  
     \str_if_eq:nnTF { #3 } { s }
-      { \@@_patch_preamble_vi_i:nnnn { #1 } { #4 } }
-      { \@@_patch_preamble_vi_ii:nnnn { #1 } { #2 } { #3 } { #4 } }
+      { \@@_make_preamble_vi_i:nnnn { #1 } { #4 } }
+      { \@@_make_preamble_vi_ii:nnnn { #1 } { #2 } { #3 } { #4 } }
   }
 %    \end{macrocode}
 % 
@@ -5376,11 +5329,11 @@
 %
 % |#2| is the width of the column.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_vi_i:nnnn #1 #2 
+\cs_new_protected:Npn \@@_make_preamble_vi_i:nnnn #1 #2 
   {  
-    \tl_gput_right:NV \g_@@_preamble_tl \g_@@_pre_cell_tl 
+    \tl_gput_right:NV \g_@@_array_preamble_tl \g_@@_pre_cell_tl 
     \tl_gclear:N \g_@@_pre_cell_tl
-    \tl_gput_right:Nn \g_@@_preamble_tl
+    \tl_gput_right:Nn \g_@@_array_preamble_tl
       {
         > {
             \dim_set:Nn \l_@@_col_width_dim { #2 }
@@ -5396,7 +5349,7 @@
           }
       }
     \int_gincr:N \c at jCol
-    \@@_patch_preamble_xi:n
+    \@@_make_preamble_xi:n
   }
 %    \end{macrocode}
 % 
@@ -5404,11 +5357,11 @@
 % Then, the most important version, for the horizontal alignments types of |c|,
 % |l| and |r| (and not |s|).
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_vi_ii:nnnn #1 #2 #3 #4
+\cs_new_protected:Npn \@@_make_preamble_vi_ii:nnnn #1 #2 #3 #4
   {  
-    \tl_gput_right:NV \g_@@_preamble_tl \g_@@_pre_cell_tl 
+    \tl_gput_right:NV \g_@@_array_preamble_tl \g_@@_pre_cell_tl 
     \tl_gclear:N \g_@@_pre_cell_tl
-    \tl_gput_right:Nn \g_@@_preamble_tl
+    \tl_gput_right:Nn \g_@@_array_preamble_tl
       {
         > {
 %    \end{macrocode}
@@ -5434,7 +5387,7 @@
 % We increment the counter of columns and then we test for the presence of a |<|.
 %    \begin{macrocode}
     \int_gincr:N \c at jCol
-    \@@_patch_preamble_xi:n
+    \@@_make_preamble_xi:n
   }
 %    \end{macrocode}
 % 
@@ -5448,31 +5401,29 @@
 %    \end{macrocode}
 % 
 % \medskip
-% For |\@@_S:|. If the user has used |S[...]|, |S| has been replaced by |\@@_S:|
-% during the first expansion of the preamble (done with the tools of standard
-% LaTeX and \pkg{array}).
+% For |S| (of \pkg{siunitx}). 
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_vii:n #1
+\cs_new_protected:Npn \@@_make_preamble_vii:nn #1 #2
   {
-    \str_if_eq:nnTF { #1 } { [ }
-      { \@@_patch_preamble_vii_i:w [ }
-      { \@@_patch_preamble_vii_i:w [ ] { #1 } }
+    \str_if_eq:nnTF { #2 } { [ }
+      { \@@_make_preamble_vii_i:w [ }
+      { \@@_make_preamble_vii_i:w [ ] { #2 } }
   }
 %    \end{macrocode}
 % 
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_vii_i:w [ #1 ]
-  { \@@_patch_preamble_vii_ii:n { #1 } }
+\cs_new_protected:Npn \@@_make_preamble_vii_i:w [ #1 ]
+  { \@@_make_preamble_vii_ii:n { #1 } }
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_vii_ii:n #1
+\cs_new_protected:Npn \@@_make_preamble_vii_ii:n #1
   { 
     \IfPackageAtLeastTF { siunitx } { 2022/01/01 }
       {
-        \tl_gput_right:NV \g_@@_preamble_tl \g_@@_pre_cell_tl 
+        \tl_gput_right:NV \g_@@_array_preamble_tl \g_@@_pre_cell_tl 
         \tl_gclear:N \g_@@_pre_cell_tl
-        \tl_gput_right:Nn \g_@@_preamble_tl 
+        \tl_gput_right:Nn \g_@@_array_preamble_tl 
           {
             > { 
                 \@@_cell_begin:w 
@@ -5486,7 +5437,7 @@
 % We increment the counter of columns and then we test for the presence of a |<|.
 %    \begin{macrocode}
         \int_gincr:N \c at jCol
-        \@@_patch_preamble_xi:n
+        \@@_make_preamble_xi:n
       } 
       { \@@_fatal:n { Version~of~siunitx~too~old } }
   }
@@ -5496,7 +5447,7 @@
 % \medskip
 % For |(|, |[| and |\{|.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_viii:nn #1 #2
+\cs_new_protected:Npn \@@_make_preamble_viii:nn #1 #2
   {
     \bool_if:NT \l_@@_small_bool { \@@_fatal:n { Delimiter~with~small } }
 %    \end{macrocode}
@@ -5513,19 +5464,19 @@
 %    \begin{macrocode}
             \tl_gset:Nn \g_@@_left_delim_tl { #1 } 
             \tl_gset:Nn \g_@@_right_delim_tl { . }
-            \@@_patch_preamble:n #2 
+            \@@_make_preamble:n #2 
           }
           {  
-            \tl_gput_right:Nn \g_@@_preamble_tl { ! { \enskip } } 
-            \@@_patch_preamble_viii_i:nn { #1 } { #2 }
+            \tl_gput_right:Nn \g_@@_array_preamble_tl { ! { \enskip } } 
+            \@@_make_preamble_viii_i:nn { #1 } { #2 }
           }
       }
-      { \@@_patch_preamble_viii_i:nn { #1 } { #2 } } 
+      { \@@_make_preamble_viii_i:nn { #1 } { #2 } } 
   }
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_viii_i:nn #1 #2
+\cs_new_protected:Npn \@@_make_preamble_viii_i:nn #1 #2
   {
     \tl_gput_right:Nx \g_@@_pre_code_after_tl
       { \@@_delimiter:nnn #1 { \int_eval:n { \c at jCol + 1 } } \c_true_bool }  
@@ -5532,11 +5483,16 @@
     \tl_if_in:nnTF { ( [ \{ ) ] \} \left \right } { #2 }
       {
         \@@_error:nn { delimiter~after~opening } { #2 } 
-        \@@_patch_preamble:n
+        \@@_make_preamble:n
       }
-      { \@@_patch_preamble:n #2 }
+      { \@@_make_preamble:n #2 }
   }
 %    \end{macrocode}
+%
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_make_preamble_viii_ii:n #1 
+  { \@@_make_preamble_viii:nn }
+%    \end{macrocode}
 % 
 % \bigskip
 % For the closing delimiters. We have two arguments for the following command because
@@ -5546,11 +5502,11 @@
 % considered as the right delimiter of the environment if the environment is
 % |{NiceArray}|). 
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_ix:nn #1 #2
+\cs_new_protected:Npn \@@_make_preamble_ix:nn #1 #2 
   {
     \bool_if:NT \l_@@_small_bool { \@@_fatal:n { Delimiter~with~small } }
     \tl_if_in:nnTF { ) ] \} } { #2 }
-      { \@@_patch_preamble_ix_i:nnn #1 #2 }
+      { \@@_make_preamble_ix_i:nnn #1 #2 }
       { 
         \tl_if_eq:nnTF { \q_stop } { #2 }
           {
@@ -5557,18 +5513,18 @@
             \str_if_eq:VnTF \g_@@_right_delim_tl { . }
               { \tl_gset:Nn \g_@@_right_delim_tl { #1 } }
               {
-                \tl_gput_right:Nn \g_@@_preamble_tl { ! { \enskip } } 
+                \tl_gput_right:Nn \g_@@_array_preamble_tl { ! { \enskip } } 
                 \tl_gput_right:Nx \g_@@_pre_code_after_tl
                   { \@@_delimiter:nnn #1 { \int_use:N \c at jCol } \c_false_bool }
-                \@@_patch_preamble:n #2
+                \@@_make_preamble:n #2
               }
           }
           {
             \tl_if_in:nnT { ( [ \{ \left } { #2 }
-              { \tl_gput_right:Nn \g_@@_preamble_tl { ! { \enskip } } }
+              { \tl_gput_right:Nn \g_@@_array_preamble_tl { ! { \enskip } } }
             \tl_gput_right:Nx \g_@@_pre_code_after_tl
               { \@@_delimiter:nnn #1 { \int_use:N \c at jCol } \c_false_bool }
-            \@@_patch_preamble:n #2
+            \@@_make_preamble:n #2
           }
       }
   }
@@ -5575,19 +5531,19 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_ix_i:nnn #1 #2 #3
+\cs_new_protected:Npn \@@_make_preamble_ix_i:nnn #1 #2 #3
   {
     \tl_if_eq:nnTF { \q_stop } { #3 }
       {
         \str_if_eq:VnTF \g_@@_right_delim_tl { . }
           {
-            \tl_gput_right:Nn \g_@@_preamble_tl { ! { \enskip } } 
+            \tl_gput_right:Nn \g_@@_array_preamble_tl { ! { \enskip } } 
             \tl_gput_right:Nx \g_@@_pre_code_after_tl
               { \@@_delimiter:nnn #1 { \int_use:N \c at jCol } \c_false_bool }
             \tl_gset:Nn \g_@@_right_delim_tl { #2 }
           }
           {
-            \tl_gput_right:Nn \g_@@_preamble_tl { ! { \enskip } } 
+            \tl_gput_right:Nn \g_@@_array_preamble_tl { ! { \enskip } } 
             \tl_gput_right:Nx \g_@@_pre_code_after_tl
               { \@@_delimiter:nnn #1 { \int_use:N \c at jCol } \c_false_bool }
             \@@_error:nn { double~closing~delimiter } { #2 } 
@@ -5597,10 +5553,15 @@
         \tl_gput_right:Nx \g_@@_pre_code_after_tl
           { \@@_delimiter:nnn #1 { \int_use:N \c at jCol } \c_false_bool }
         \@@_error:nn { double~closing~delimiter } { #2 } 
-        \@@_patch_preamble:n #3 
+        \@@_make_preamble:n #3 
       }
   }
 %    \end{macrocode}
+%
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_make_preamble_ix_ii:n #1 
+  { \@@_make_preamble_ix:nn }
+%    \end{macrocode}
 % 
 % \bigskip
 % For the case of a letter |X|. This specifier may take in an optional argument
@@ -5607,17 +5568,17 @@
 % (between square brackets). That's why we test whether there is a |[| after the
 % letter |X|.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_x:n #1
+\cs_new_protected:Npn \@@_make_preamble_x:nn #1 #2
   {
-    \str_if_eq:nnTF { #1 } { [ }
-      { \@@_patch_preamble_x_i:w [ }
-      { \@@_patch_preamble_x_i:w [ ] #1 }
+    \str_if_eq:nnTF { #2 } { [ }
+      { \@@_make_preamble_x_i:w [ }
+      { \@@_make_preamble_x_i:w [ ] #2 }
   }
 %    \end{macrocode}
 % 
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_x_i:w [ #1 ]
-  { \@@_patch_preamble_x_ii:n { #1 } }
+\cs_new_protected:Npn \@@_make_preamble_x_i:w [ #1 ]
+  { \@@_make_preamble_x_ii:n { #1 } }
 %    \end{macrocode}
 % |#1| is the optional argument of the |X| specifier (a list of
 % \emph{key}-\emph{value} pairs).
@@ -5636,7 +5597,7 @@
 % \medskip
 % In the following command, |#1| is the list of the options of the specifier |X|.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_x_ii:n #1
+\cs_new_protected:Npn \@@_make_preamble_x_ii:n #1
   {
 %    \end{macrocode}
 % The possible values of |\l_@@_hpos_col_str| are |j| (for \emph{justified} which is
@@ -5661,7 +5622,6 @@
     \int_zero_new:N \l_@@_weight_int 
     \int_set:Nn \l_@@_weight_int { 1 }
     \tl_set:Nn \l_tmpa_tl { #1 }
-    \tl_replace_all:Nnn \l_tmpa_tl { \@@_S: } { S }
     \@@_keys_p_column:V \l_tmpa_tl
     \keys_set:nV { WithArrows / X-column } \l_tmpa_tl
     \int_compare:nNnT \l_@@_weight_int < 0 
@@ -5679,12 +5639,12 @@
     \bool_if:NTF \l_@@_X_columns_aux_bool
       { 
         \exp_args:Nnx
-        \@@_patch_preamble_iv_iv:nn 
+        \@@_make_preamble_iv_iv:nn 
           { \l_@@_weight_int \l_@@_X_columns_dim } 
           { minipage }
       }
       {
-        \tl_gput_right:Nn \g_@@_preamble_tl 
+        \tl_gput_right:Nn \g_@@_array_preamble_tl 
           { 
             > { 
                 \@@_cell_begin:w 
@@ -5715,7 +5675,7 @@
               }
           }  
         \int_gincr:N \c at jCol
-        \@@_patch_preamble_xi:n
+        \@@_make_preamble_xi:n
       }
   }
 %    \end{macrocode}
@@ -5727,17 +5687,17 @@
 % |!{\skip_horizontal:N ...}| when the key |vlines| is used. In fact, we have
 % also to test whether there is, after the |<{...}|, a |@{...}|.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_xi:n #1
+\cs_new_protected:Npn \@@_make_preamble_xi:n #1
   {
     \str_if_eq:nnTF { #1 } { < }
-      \@@_patch_preamble_xiii:n 
+      \@@_make_preamble_xiii:n 
       { 
         \str_if_eq:nnTF { #1 } { @ }
-          \@@_patch_preamble_xv:n 
+          \@@_make_preamble_xv:n 
           {
             \tl_if_eq:NnTF \l_@@_vlines_clist { all }
               { 
-                \tl_gput_right:Nn \g_@@_preamble_tl 
+                \tl_gput_right:Nn \g_@@_array_preamble_tl 
                   { ! { \skip_horizontal:N \arrayrulewidth } }
               } 
               { 
@@ -5744,11 +5704,11 @@
                 \exp_args:NNx 
                 \clist_if_in:NnT \l_@@_vlines_clist { \int_eval:n { \c at jCol + 1 } }  
                   { 
-                    \tl_gput_right:Nn \g_@@_preamble_tl 
+                    \tl_gput_right:Nn \g_@@_array_preamble_tl 
                       { ! { \skip_horizontal:N \arrayrulewidth } }
                   } 
               }
-            \@@_patch_preamble:n { #1 }
+            \@@_make_preamble:n { #1 }
           }
       }
   }
@@ -5755,10 +5715,10 @@
 %    \end{macrocode}
 % 
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_xiii:n #1
+\cs_new_protected:Npn \@@_make_preamble_xiii:n #1
   {
-    \tl_gput_right:Nn \g_@@_preamble_tl { < { #1 } }
-    \@@_patch_preamble_xi:n
+    \tl_gput_right:Nn \g_@@_array_preamble_tl { < { #1 } }
+    \@@_make_preamble_xi:n
   }
 %    \end{macrocode}
 %
@@ -5766,11 +5726,11 @@
 % draw a vertical rule, we have to add in that |@{...}| a |\hskip| corresponding
 % to the width of the vertical rule.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_preamble_xv:n #1
+\cs_new_protected:Npn \@@_make_preamble_xv:n #1
   {
     \tl_if_eq:NnTF \l_@@_vlines_clist { all }
       { 
-        \tl_gput_right:Nn \g_@@_preamble_tl 
+        \tl_gput_right:Nn \g_@@_array_preamble_tl 
           { @ { #1 \skip_horizontal:N \arrayrulewidth } }
       } 
       { 
@@ -5777,32 +5737,30 @@
         \exp_args:NNx 
         \clist_if_in:NnTF \l_@@_vlines_clist { \int_eval:n { \c at jCol + 1 } }  
           { 
-            \tl_gput_right:Nn \g_@@_preamble_tl 
+            \tl_gput_right:Nn \g_@@_array_preamble_tl 
               { @ { #1 \skip_horizontal:N \arrayrulewidth } }
           } 
-          { \tl_gput_right:Nn \g_@@_preamble_tl { @ { #1 } } }
+          { \tl_gput_right:Nn \g_@@_array_preamble_tl { @ { #1 } } }
       }
-    \@@_patch_preamble:n 
+    \@@_make_preamble:n 
   }
 %    \end{macrocode}
 %
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_make_preamble_xx:n #1 { \@@_make_preamble:n }
+%    \end{macrocode}
+% 
 % \bigskip
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_set_preamble:Nn #1 #2
-  {
-    \group_begin:
-    \@@_newcolumntype w [ 2 ] { \@@_w: { ##1 } { ##2 } }
-    \@@_newcolumntype W [ 2 ] { \@@_W: { ##1 } { ##2 } }
-    \@temptokena { #2 }
-    \@tempswatrue
-    \@whilesw \if at tempswa \fi { \@tempswafalse \the \NC at list }
-    \tl_gclear:N \g_@@_preamble_tl 
-    \exp_after:wN \@@_patch_m_preamble:n \the \@temptokena \q_stop
-    \group_end:
-    \tl_set_eq:NN #1 \g_@@_preamble_tl 
+\cs_new_protected:Npn \@@_make_preamble_xvi:nnn #1 #2 #3
+  { 
+    \tl_clear:N \l_tmpa_tl
+    \int_step_inline:nn { #2 } { \tl_put_right:Nn \l_tmpa_tl { #3 } } 
+    \exp_last_unbraced:NV \@@_make_preamble:n \l_tmpa_tl
   }
 %    \end{macrocode}
 % 
+% 
 % \bigskip
 % \section{The redefinition of \textbackslash multicolumn}
 %
@@ -5823,25 +5781,12 @@
     \cs_set:Npn \@addamp { \if at firstamp \@firstampfalse \else \@preamerr 5 \fi } 
 %    \end{macrocode}
 %
-%    \begin{macrocode}
-    \@@_newcolumntype w [ 2 ] { \@@_w: { ##1 } { ##2 } }
-    \@@_newcolumntype W [ 2 ] { \@@_W: { ##1 } { ##2 } }
-%    \end{macrocode}
-%
 % \medskip
-% You do the expansion of the (small) preamble with the tools of \pkg{array}.
-%    \begin{macrocode}
-    \@temptokena = { #2 }
-    \@tempswatrue
-    \@whilesw \if at tempswa \fi { \@tempswafalse \the \NC at list }
-%    \end{macrocode}
-% 
-% \medskip
 % Now, we patch the (small) preamble as we have done with the main preamble of
 % the array.
 %    \begin{macrocode}
     \tl_gclear:N \g_@@_preamble_tl
-    \exp_after:wN \@@_patch_m_preamble:n \the \@temptokena \q_stop
+    \@@_make_m_preamble:n #2 \q_stop
 %    \end{macrocode}
 %
 % \medskip
@@ -5905,28 +5850,40 @@
 % All those commands have a |m| in their name to recall that they deal with the
 % redefinition of |\multicolumn|.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_m_preamble:n #1
+\cs_new_protected:Npn \@@_make_m_preamble:n #1
   {
     \str_case:nnF { #1 }
       {
-        c { \@@_patch_m_preamble_i:n #1 }
-        l { \@@_patch_m_preamble_i:n #1 }
-        r { \@@_patch_m_preamble_i:n #1 }
-        > { \@@_patch_m_preamble_ii:nn #1 }
-        ! { \@@_patch_m_preamble_ii:nn #1 }
-        @ { \@@_patch_m_preamble_ii:nn #1 }
-        | { \@@_patch_m_preamble_iii:n #1 }
-        p { \@@_patch_m_preamble_iv:nnn t #1 }
-        m { \@@_patch_m_preamble_iv:nnn c #1 }
-        b { \@@_patch_m_preamble_iv:nnn b #1 }
-        \@@_w: { \@@_patch_m_preamble_v:nnnn { } #1 } 
-        \@@_W: { \@@_patch_m_preamble_v:nnnn { \@@_special_W: } #1 } 
+        c { \@@_make_m_preamble_i:n #1 }
+        l { \@@_make_m_preamble_i:n #1 }
+        r { \@@_make_m_preamble_i:n #1 }
+        > { \@@_make_m_preamble_ii:nn #1 }
+        ! { \@@_make_m_preamble_ii:nn #1 }
+        @ { \@@_make_m_preamble_ii:nn #1 }
+        | { \@@_make_m_preamble_iii:n #1 }
+        p { \@@_make_m_preamble_iv:nnn t #1 }
+        m { \@@_make_m_preamble_iv:nnn c #1 }
+        b { \@@_make_m_preamble_iv:nnn b #1 }
+        w { \@@_make_m_preamble_v:nnnn { } #1 } 
+        W { \@@_make_m_preamble_v:nnnn { \@@_special_W: } #1 } 
         \q_stop { }
+%    \end{macrocode}
+% The token |\NC at find| is at the head of the definition of the columns type done
+% by |\newcolumntype|. We wan't that token to no-op here.
+%    \begin{macrocode}
+        \NC at find { \@@_make_preamble:n }
       }
       { 
-        \tl_if_eq:nnT { #1 } { S }
-          { \@@_fatal:n { unknown~column~type~S } }
-          { \@@_fatal:nn { unknown~column~type } { #1 } }
+        \cs_if_exist:cTF { NC @ find @ #1 }
+          {
+            \tl_set_eq:Nc \l_tmpa_tl { NC @ rewrite @ #1 }
+            \exp_last_unbraced:NV \@@_make_m_preamble:n \l_tmpa_tl
+          }
+          { 
+            \tl_if_eq:nnT { #1 } { S }
+              { \@@_fatal:n { unknown~column~type~S } }
+              { \@@_fatal:nn { unknown~column~type } { #1 } }
+          }
       }
   }
 %    \end{macrocode}
@@ -5934,7 +5891,7 @@
 % \medskip
 % For |c|, |l| and |r|
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_m_preamble_i:n #1
+\cs_new_protected:Npn \@@_make_m_preamble_i:n #1
   { 
     \tl_gput_right:Nn \g_@@_preamble_tl 
       { 
@@ -5946,7 +5903,7 @@
 %
 % We test for the presence of a |<|.
 %    \begin{macrocode}
-    \@@_patch_m_preamble_x:n
+    \@@_make_m_preamble_x:n
   }
 %    \end{macrocode}
 % 
@@ -5953,10 +5910,10 @@
 % \medskip
 % For |>|, |!| and |@|
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_m_preamble_ii:nn #1 #2
+\cs_new_protected:Npn \@@_make_m_preamble_ii:nn #1 #2
   {  
     \tl_gput_right:Nn \g_@@_preamble_tl { #1 { #2 } }
-    \@@_patch_m_preamble:n
+    \@@_make_m_preamble:n
   }
 %    \end{macrocode}
 %
@@ -5964,10 +5921,10 @@
 % \medskip
 % For \verb+|+
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_m_preamble_iii:n #1
+\cs_new_protected:Npn \@@_make_m_preamble_iii:n #1
   { 
     \tl_gput_right:Nn \g_@@_preamble_tl { #1 }
-    \@@_patch_m_preamble:n
+    \@@_make_m_preamble:n
   }
 %    \end{macrocode}
 %
@@ -5974,7 +5931,7 @@
 % \medskip
 % For |p|, |m| and |b|
 %    \begin{macrocode}  
-\cs_new_protected:Npn \@@_patch_m_preamble_iv:nnn #1 #2 #3
+\cs_new_protected:Npn \@@_make_m_preamble_iv:nnn #1 #2 #3
   {  
     \tl_gput_right:Nn \g_@@_preamble_tl
       {
@@ -5995,7 +5952,7 @@
 %    \end{macrocode}
 % We test for the presence of a |<|.
 %    \begin{macrocode}
-    \@@_patch_m_preamble_x:n
+    \@@_make_m_preamble_x:n
   }
 %    \end{macrocode}
 % 
@@ -6002,7 +5959,7 @@
 % \medskip
 % For |w| and |W|
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_m_preamble_v:nnnn #1 #2 #3 #4
+\cs_new_protected:Npn \@@_make_m_preamble_v:nnnn #1 #2 #3 #4
   {  
     \tl_gput_right:Nn \g_@@_preamble_tl
       {
@@ -6025,7 +5982,7 @@
 %    \end{macrocode}
 % We test for the presence of a |<|.
 %    \begin{macrocode}
-    \@@_patch_m_preamble_x:n
+    \@@_make_m_preamble_x:n
   }
 %    \end{macrocode}
 %
@@ -6033,19 +5990,19 @@
 % After a specifier of column, we have to test whether there is one or several
 % |<{..}|.
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_m_preamble_x:n #1
+\cs_new_protected:Npn \@@_make_m_preamble_x:n #1
   {
     \str_if_eq:nnTF { #1 } { < }
-      \@@_patch_m_preamble_ix:n 
-      { \@@_patch_m_preamble:n { #1 } }
+      \@@_make_m_preamble_ix:n 
+      { \@@_make_m_preamble:n { #1 } }
   }
 %    \end{macrocode}
 % 
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_patch_m_preamble_ix:n #1
+\cs_new_protected:Npn \@@_make_m_preamble_ix:n #1
   {
     \tl_gput_right:Nn \g_@@_preamble_tl { < { #1 } }
-    \@@_patch_m_preamble_x:n
+    \@@_make_m_preamble_x:n
   }
 %    \end{macrocode}
 %
@@ -6521,7 +6478,7 @@
 % Here is the call to |\array| (we have a dedicated macro |\@@_array:n| because
 % of compatibility with the classes \cls{revtex4-1} and \cls{revtex4-2}).
 %    \begin{macrocode}
-            \@@_array:V \g_@@_preamble_tl 
+            \@@_array:V \g_@@_array_preamble_tl 
           }
       }
   }
@@ -6656,7 +6613,7 @@
 % |\@@_array:n| because of compatibility with the classes \cls{revtex4-1} and
 % \cls{revtex4-2}). 
 %    \begin{macrocode}
-    \@@_array:V \g_@@_preamble_tl \l_@@_new_body_tl
+    \@@_array:V \g_@@_array_preamble_tl \l_@@_new_body_tl
   }
 %    \end{macrocode}
 %
@@ -7273,31 +7230,11 @@
   { \endNiceArray }
 %    \end{macrocode}
 %
-% \bigskip
-%    \begin{macrocode}
-\cs_set_protected:Npn \@@_newcolumntype #1
-  {
-    \cs_if_free:cT { NC @ find @ #1 }
-      { \NC at list \expandafter { \the \NC at list \NC at do #1 } }
-    \cs_set:cpn {NC @ find @ #1 } ##1 #1 { \NC@ { ##1 } }
-    \peek_meaning:NTF [ 
-      { \newcol@ #1 }
-      { \newcol@ #1 [ 0 ] }
-  }
-%    \end{macrocode}
 %
 % \bigskip
 %    \begin{macrocode}
 \NewDocumentEnvironment { NiceTabularX } { m O { } m ! O { } }
   { 
-%    \end{macrocode}
-% The following code prevents the expansion of the `X` columns with the
-% definition of that columns in \pkg{tabularx} (this would result in an error in
-% |{NiceTabularX}|). 
-%    \begin{macrocode}
-    \IfPackageLoadedTF { tabularx }
-      { \newcolumntype { X } { \@@_X } } 
-      { }
     \str_gset:Nn \g_@@_name_env_str { NiceTabularX }
     \dim_zero_new:N \l_@@_width_dim 
     \dim_set:Nn \l_@@_width_dim { #1 }
@@ -7305,7 +7242,11 @@
     \bool_set_true:N \l_@@_tabular_bool 
     \NiceArray { #3 }
   }
-  { \endNiceArray }
+  { 
+    \endNiceArray 
+    \int_compare:nNnT \g_@@_total_X_weight_int = \c_zero_int
+      { \@@_error:n { NiceTabularX~without~X } }
+  }
 %    \end{macrocode}
 %
 % \bigskip 
@@ -7578,6 +7519,7 @@
     \cs_set_eq:NN \UnderBrace \@@_UnderBrace
     \cs_set_eq:NN \OverBrace \@@_OverBrace
     \cs_set_eq:NN \ShowCellNames \@@_ShowCellNames
+    \cs_set_eq:NN \TikzEveryCell \@@_TikzEveryCell
     \cs_set_eq:NN \line \@@_line
     \g_@@_pre_code_after_tl
     \tl_gclear:N \g_@@_pre_code_after_tl
@@ -10608,7 +10550,7 @@
   {
     \peek_remove_spaces:n 
       {
-        \tl_gput_right:Nx \g__nicematrix_pre_code_before_tl 
+        \tl_gput_right:Nx \g_@@_pre_code_before_tl 
           { 
             \@@_rowlistcolors 
                [ #1 ] { \int_use:N \c at iRow } { #2 } 
@@ -10754,7 +10696,17 @@
     dotted .bool_set:N = \l_@@_dotted_bool ,
     dotted .initial:n = false , 
     dotted .default:n = true ,
-    color .code:n = \@@_set_CT at arc@:n { #1 } , 
+%    \end{macrocode}
+% We want that, even when the rule has been defined with TikZ by the key |tikz|,
+% the user has still the possibility to change the color of the rule with the key
+% |color| (in the command |\Hline|, not in the key |tikz| of the command
+% |\Hline|). The main use is, when the user has defined its own command
+% |\MyDashedLine| by |\newcommand{\MyDashedRule}{\Hline[tikz=dashed]}|, to give
+% the ability to write |\MyDashedRule[color=red]|.
+%    \begin{macrocode}
+    color .code:n = 
+      \@@_set_CT at arc@:n { #1 } 
+      \tl_set:Nn \l_@@_rule_color_tl { #1 } , 
     color .value_required:n = true ,
     sep-color .code:n = \@@_set_CT at drsc@:n { #1 } ,
     sep-color .value_required:n = true ,
@@ -10763,9 +10715,11 @@
 % sub-rules since a rule may be broken by blocks or others) will be drawn with
 % Tikz. 
 %    \begin{macrocode}
-    tikz .tl_set:N = \l_@@_tikz_rule_tl , 
+    tikz .code:n = 
+      \IfPackageLoadedTF { tikz }
+        { \clist_put_right:Nn \l_@@_tikz_rule_tl { #1 } }
+        { \@@_error:n { tikz~without~tikz } } ,
     tikz .value_required:n = true ,
-    tikz .initial:n = ,
     total-width .dim_set:N = \l_@@_rule_width_dim ,
     total-width .value_required:n = true ,
     width .meta:n = { total-width = #1 } ,
@@ -10887,6 +10841,7 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_vline_ii:
   {
+    \tl_clear:N \l_@@_tikz_rule_tl 
     \keys_set:nV { NiceMatrix / RulesBis } \l_@@_other_keys_tl 
     \bool_if:NTF \l_@@_dotted_bool
       \@@_vline_iv: 
@@ -10983,12 +10938,21 @@
 %    \end{macrocode}
 %
 % \bigskip
-% The following code is for the case when the user uses the key |tikz| (in the
-% definition of a customized rule by using the key |custom-line|).
+% The following code is for the case when the user uses the key |tikz|.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_vline_v:
   {
     \begin {tikzpicture }
+    % added 2023/09/25
+%    \end{macrocode}
+% By default, the color defined by |\arrayrulecolor| or by |rules/color| will be
+% used, but it's still possible to change the color by using the key |color| or,
+% of course, the key |color| inside the key |tikz| (that is to say the key
+% |color| provided by \textsc{pgf}.
+%    \begin{macrocode}
+    \CT at arc@
+    \tl_if_empty:NF \l_@@_rule_color_tl
+      { \tl_put_right:Nx \l_@@_tikz_rule_tl { , color = \l_@@_rule_color_tl } }  
     \pgfrememberpicturepositiononpagetrue
     \pgf at relevantforpicturesizefalse
     \@@_qpoint:n { row - \int_use:N \l_@@_local_start_int }
@@ -11142,6 +11106,7 @@
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_hline_ii:
   {
+    \tl_clear:N \l_@@_tikz_rule_tl 
     \keys_set:nV { NiceMatrix / RulesBis } \l_@@_other_keys_tl 
     \bool_if:NTF \l_@@_dotted_bool
       \@@_hline_iv: 
@@ -11304,6 +11269,16 @@
 \cs_new_protected:Npn \@@_hline_v:
   {
     \begin { tikzpicture }
+    % added 2023/09/25
+%    \end{macrocode}
+% By default, the color defined by |\arrayrulecolor| or by |rules/color| will be
+% used, but it's still possible to change the color by using the key |color| or,
+% of course, the key |color| inside the key |tikz| (that is to say the key
+% |color| provided by \textsc{pgf}.
+%    \begin{macrocode}
+    \CT at arc@
+    \tl_if_empty:NF \l_@@_rule_color_tl
+      { \tl_put_right:Nx \l_@@_tikz_rule_tl { , color = \l_@@_rule_color_tl } }  
     \pgfrememberpicturepositiononpagetrue
     \pgf at relevantforpicturesizefalse
     \@@_qpoint:n { col - \int_use:N \l_@@_local_start_int }
@@ -11481,7 +11456,7 @@
       {
         \IfPackageLoadedTF { tikz }
           { }
-          { \@@_error:n { tikz~in~custom-line~without~tikz }} 
+          { \@@_error:n { tikz~in~custom-line~without~tikz } } 
         \bool_if:NT \l_@@_color_bool
           { \@@_error:n { color~in~custom-line~with~tikz } }
       }
@@ -11589,25 +11564,10 @@
   {
 %    \end{macrocode}
 % We use |\cs_set:cpn| and not |\cs_new:cpn| because we want a local definition.
-% Moreover, the command must \emph{not} be protected since it begins with |\noalign|.
+% Moreover, the command must \emph{not} be protected since it begins with
+% |\noalign| (which is in |\Hline|). 
 %    \begin{macrocode}
-    \cs_set:cpn { nicematrix - \l_@@_command_str }
-      { 
-        \noalign
-          {
-            \@@_compute_rule_width:n { #1 }
-            \skip_vertical:n { \l_@@_rule_width_dim }
-            \tl_gput_right:Nx \g_@@_pre_code_after_tl
-              { 
-                \@@_hline:n 
-                  { 
-                    #1 , 
-                    position = \int_eval:n { \c at iRow + 1 } ,
-                    total-width = \dim_use:N \l_@@_rule_width_dim
-                  } 
-              }
-          }
-      }
+    \cs_set:cpn { nicematrix - \l_@@_command_str } { \Hline [ #1 ] }
     \seq_put_left:NV \l_@@_custom_line_commands_seq \l_@@_command_str
   }
 %    \end{macrocode}
@@ -11697,7 +11657,7 @@
 %    \end{macrocode}
 % In the following line, the |\dim_use:N| is mandatory since we do an expansion.
 %    \begin{macrocode}
-    \tl_gput_right:Nx \g_@@_preamble_tl
+    \tl_gput_right:Nx \g_@@_array_preamble_tl
       { \exp_not:N ! { \skip_horizontal:n { \dim_use:N \l_@@_rule_width_dim } } }
     \tl_gput_right:Nx \g_@@_pre_code_after_tl
       { 
@@ -12365,9 +12325,7 @@
 % |\multicolumn{|$n$|}{...}{...}| with $n$>1 was issued and in
 % |\g_@@_multicolumn_sizes_seq| the correspondant values of $n$. 
 %    \begin{macrocode}
-    \cs_if_exist_use:NF 
       \seq_map_pairwise_function:NNN 
-      \seq_mapthread_function:NNN 
       \g_@@_multicolumn_cells_seq 
       \g_@@_multicolumn_sizes_seq
       \@@_node_for_multicolumn:nn
@@ -13839,7 +13797,7 @@
     borders .clist_set:N = \l_@@_borders_clist ,
     rounded-corners .dim_set:N = \l_@@_rounded_corners_dim ,
     rounded-corners .default:n = 4 pt ,
-    line-width .dim_set:N = \l_@@_line_width_dim ,
+    line-width .dim_set:N = \l_@@_line_width_dim 
   }
 %    \end{macrocode}
 %
@@ -13847,22 +13805,45 @@
 % The following command will be used if the key |tikz| has been used for the
 % command |\Block|. The arguments |#1| and |#2| are the coordinates of the first
 % cell and |#3| and |#4| the coordinates of the last cell of the block. |#5| is
-% a comma-separated list of the Tikz keys used with the path.
+% a comma-separated list of the Tikz keys used with the path. However, among
+% those keys, you have added in \pkg{nicematrix} a special key |offset| (an
+% offset for the rectangle of the block). That's why we have to extract that key 
+% first. 
 %    \begin{macrocode}
-\cs_new_protected:Npn \@@_block_tikz:nnnnn #1 #2 #3 #4 #5
+\cs_new_protected:Npn \@@_block_tikz:nnnnn #1 #2 #3 #4 #5 
   {
     \begin { tikzpicture }
     \@@_clip_with_rounded_corners:
     \clist_map_inline:nn { #5 }
       {
-        \path [ ##1 ] 
-              ( #1 -| #2 ) 
+        \keys_set_known:nnN { NiceMatrix / SpecialOffset } { ##1 } \l_tmpa_tl
+        \use:x { \exp_not:N \path [ \l_tmpa_tl ] }
+              ( 
+                [ 
+                  xshift = \dim_use:N \l_@@_offset_dim , 
+                  yshift = - \dim_use:N \l_@@_offset_dim 
+                ] 
+                #1 -| #2 
+              ) 
               rectangle 
-              ( \int_eval:n { #3 + 1 } -| \int_eval:n { #4 + 1 } ) ; 
+              ( 
+                [ 
+                  xshift = - \dim_use:N \l_@@_offset_dim , 
+                  yshift = \dim_use:N \l_@@_offset_dim 
+                ] 
+                \int_eval:n { #3 + 1 } -| \int_eval:n { #4 + 1 } 
+              ) ; 
       }
     \end { tikzpicture }
   }
+\cs_generate_variant:Nn \@@_block_tikz:nnnnn { n n n n V }
 %    \end{macrocode}
+%
+% \medskip
+%    \begin{macrocode}
+\keys_define:nn { NiceMatrix / SpecialOffset }
+  { offset .dim_set:N = \l_@@_offset_dim }
+%    \end{macrocode}
 % 
 % 
 % \section{How to draw the dotted lines transparently}
@@ -13898,7 +13879,7 @@
 %    \begin{macrocode} 
 \keys_define:nn { NiceMatrix / Auto }
   {
-    columns-type .code:n = \@@_set_preamble:Nn \l_@@_columns_type_tl { #1 } ,
+    columns-type .tl_set:N = \l_@@_columns_type_tl ,
     columns-type .value_required:n = true ,
     l .meta:n = { columns-type = l } ,
     r .meta:n = { columns-type = r } , 
@@ -13934,7 +13915,7 @@
 % preamble which is yet transformed (by using |\l_@@_columns_type_tl| which is
 % yet nicematrix-ready).
 %    \begin{macrocode}
-    \bool_set_false:N \l_@@_preamble_bool 
+    % \bool_set_false:N \l_@@_preamble_bool 
     \use:x 
       {
         \exp_not:N \begin { NiceArrayWithDelims } { #1 } { #2 } 
@@ -14133,27 +14114,6 @@
 % \section{The keyword \textbackslash CodeAfter}
 %
 % 
-% The |\CodeAfter| (inserted with the key |code-after| or after the keyword
-% |\CodeAfter|) may always begin with a list of pairs \textsl{key=value} between
-% square brackets. Here is the corresponding set of keys.
-%    \begin{macrocode}
-\keys_define:nn { NiceMatrix }
-  { 
-    CodeAfter / rules .inherit:n = NiceMatrix / rules ,
-    CodeAfter / sub-matrix .inherit:n = NiceMatrix / sub-matrix  
-  }
-\keys_define:nn { NiceMatrix / CodeAfter }
-  {
-    sub-matrix .code:n = \keys_set:nn { NiceMatrix / sub-matrix } { #1 } , 
-    sub-matrix .value_required:n = true ,
-    delimiters / color .tl_set:N = \l_@@_delimiters_color_tl ,
-    delimiters / color .value_required:n = true ,
-    rules .code:n = \keys_set:nn { NiceMatrix / rules } { #1 } ,
-    rules .value_required:n = true ,
-    xdots .code:n = \keys_set:nn { NiceMatrix / xdots } { #1 } , 
-    unknown .code:n = \@@_error:n { Unknown~key~for~CodeAfter }
-  }
-%    \end{macrocode}
 % 
 % \medskip
 % In fact, in this subsection, we define the user command |\CodeAfter| for the
@@ -14334,13 +14294,11 @@
     vlines .clist_set:N = \l_@@_submatrix_vlines_clist ,
     vlines .default:n = all ,
     hvlines .meta:n = { hlines, vlines } ,
-    hvlines .value_forbidden:n = true ,
+    hvlines .value_forbidden:n = true 
   }
 \keys_define:nn { NiceMatrix }
   { 
     SubMatrix .inherit:n = NiceMatrix / sub-matrix ,
-    CodeAfter / sub-matrix .inherit:n = NiceMatrix / sub-matrix ,
-    NiceMatrix / sub-matrix .inherit:n = NiceMatrix / sub-matrix ,
     NiceArray / sub-matrix .inherit:n = NiceMatrix / sub-matrix ,
     pNiceArray / sub-matrix .inherit:n = NiceMatrix / sub-matrix ,
     NiceMatrixOptions / sub-matrix .inherit:n = NiceMatrix / sub-matrix , 
@@ -14385,6 +14343,8 @@
   }
 %    \end{macrocode}
 %
+% 
+% 
 % \bigskip
 %    \begin{macrocode}
 \NewDocumentCommand \@@_SubMatrix_in_code_before { m m m m ! O { } }
@@ -15133,7 +15093,110 @@
       { }
   }
 %    \end{macrocode}
+%
+% \bigskip
+% \section{The command TikzEveryCell}
+%
+%    \begin{macrocode}
+
+
+\bool_new:N \l_@@_not_empty_bool 
+\bool_new:N \l_@@_empty_bool 
+
+\keys_define:nn { NiceMatrix / TikzEveryCell }
+  { 
+    not-empty .code:n = 
+      \bool_lazy_or:nnTF 
+        \l_@@_in_code_after_bool 
+        \g_@@_recreate_cell_nodes_bool 
+        { \bool_set_true:N \l_@@_not_empty_bool }
+        { \@@_error:n { detection~of~empty~cells } } ,
+    not-empty .value_forbidden:n = true ,
+    empty .code:n = 
+      \bool_lazy_or:nnTF 
+        \l_@@_in_code_after_bool 
+        \g_@@_recreate_cell_nodes_bool 
+        { \bool_set_true:N \l_@@_empty_bool }
+        { \@@_error:n { detection~of~empty~cells } } ,
+    empty .value_forbidden:n = true ,
+    unknown .code:n = \@@_error:n { Unknown~key~for~TikzEveryCell }
+  }
+
+
+\NewDocumentCommand { \@@_TikzEveryCell } { O { } m }
+  {
+    \IfPackageLoadedTF { tikz } 
+      {
+        \group_begin:
+        \keys_set:nn { NiceMatrix / TikzEveryCell } { #1 }
+        \tl_set:Nn \l_tmpa_tl { #2 }
+        \seq_map_inline:Nn \g_@@_pos_of_blocks_seq 
+          { \@@_for_a_block:nnnnn ##1 }  
+        \@@_all_the_cells:
+        \group_end:
+      }
+      { \@@_error:n { TikzEveryCell~without~tikz } }
+  }
+
+\tl_new:N \@@_i_tl
+\tl_new:N \@@_j_tl
+
+\cs_new_protected:Nn \@@_all_the_cells:
+  {
+    \int_step_variable:nNn { \int_use:c { c at iRow } } \@@_i_tl
+      {
+        \int_step_variable:nNn { \int_use:c { c at jCol } } \@@_j_tl
+          { 
+            \cs_if_exist:cF { cell - \@@_i_tl - \@@_j_tl } 
+              {
+                \exp_args:NNx \seq_if_in:NnF \l_@@_corners_cells_seq 
+                  { \@@_i_tl - \@@_j_tl }
+                  {
+                    \bool_set_false:N \l_tmpa_bool
+                    \cs_if_exist:cTF
+                      { pgf @ sh @ ns @ \@@_env: - \@@_i_tl - \@@_j_tl }
+                      { 
+                        \bool_if:NF \l_@@_empty_bool 
+                          { \bool_set_true:N \l_tmpa_bool }
+                      }
+                      { 
+                        \bool_if:NF \l_@@_not_empty_bool 
+                          { \bool_set_true:N \l_tmpa_bool }
+                      }                   
+                    \bool_if:NT \l_tmpa_bool
+                      {
+                        \@@_block_tikz:nnnnV
+                        \@@_i_tl \@@_j_tl \@@_i_tl \@@_j_tl \l_tmpa_tl 
+                      }
+                  }
+              }
+          }
+      }
+  }
+
+\cs_new_protected:Nn \@@_for_a_block:nnnnn
+  { 
+    \bool_if:NF \l_@@_empty_bool
+      {
+        \@@_block_tikz:nnnnV
+          { #1 } { #2 } { #3 } { #4 } \l_tmpa_tl 
+      }
+    \@@_mark_cells_of_block:nnnn { #1 } { #2 } { #3 } { #4 }
+  }
+
+\cs_new_protected:Nn \@@_mark_cells_of_block:nnnn 
+  {
+    \int_step_inline:nnn { #1 } { #3 }
+      {
+        \int_step_inline:nnn { #2 } { #4 }
+          { \cs_set:cpn { cell - ##1 - ####1 } { } }
+      }
+  }
+
+
+%    \end{macrocode}
 % 
+% 
 % \bigskip
 % \section{The command \textbackslash ShowCellNames}
 %
@@ -15494,27 +15557,7 @@
               }
           }
       }
-      { 
-        \IfPackageLoadedTF { tabularx }
-          { 
-            \str_if_eq:VnTF \g_@@_name_env_str { NiceTabularX } 
-              { 
-                \int_compare:nNnTF \c at iRow = \c_zero_int 
-                  { \@@_fatal:n { X~columns~with~tabularx } }
-                  { 
-                    \@@_fatal:nn { too~much~cols~for~array } 
-                      { 
-                        However,~this~message~may~be~erroneous:~
-                        maybe~you~have~used~X~columns~while~'tabularx'~is~loaded,~
-                        ~which~is~forbidden~(however,~it's~still~possible~to~use~ 
-                        X~columns~in~{NiceTabularX}).
-                      }
-                  }
-              }
-              { \@@_fatal:nn { too~much~cols~for~array } { } }
-          }
-          { \@@_fatal:nn { too~much~cols~for~array } { } }
-      }
+      { \@@_fatal:nn { too~much~cols~for~array } }
   }
 %    \end{macrocode}
 %
@@ -15593,22 +15636,11 @@
     ~you~try~to~use~more~columns~than~allowed~by~your~
     \@@_full_name_env:.\@@_message_hdotsfor:\ The~maximal~number~of~columns~is~ 
     \int_use:N \g_@@_static_num_of_col_int\ 
-    ~(plus~the~potential~exterior~ones).~#1 
+    ~(plus~the~potential~exterior~ones).
     This~error~is~fatal.
   }
 %    \end{macrocode}
 %
-% \medskip
-%    \begin{macrocode}
-\@@_msg_new:nn { X~columns~with~tabularx }
-  {
-    There~is~a~problem.\\
-    You~have~probably~used~X~columns~in~your~environment~{\g_@@_name_env_str}.~
-    That's~not~allowed~because~'tabularx'~is~loaded~(however,~you~can~use~X~columns~
-    in~an~environment~{NiceTabularX}).\\
-    This~error~is~fatal.
-  }
-%    \end{macrocode}
 % 
 %    \begin{macrocode}
 \@@_msg_new:nn { columns~not~used }
@@ -15735,6 +15767,16 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
+\@@_msg_new:nn { Unknown~key~for~TikzEveryCell }
+  {
+    Unknown~key.\\
+    There~is~only~two~keys~available~here:~
+    'empty'~and~'not-empty'.\\
+    Your~key~'\l_keys_key_str'~will~be~ignored.
+  }
+%    \end{macrocode}
+% 
+%    \begin{macrocode}
 \@@_msg_new:nn { Unknown~key~for~rotate }
   {
     Unknown~key.\\
@@ -15876,6 +15918,17 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
+\@@_msg_new:nn { detection~of~empty~cells }
+  {
+    Problem~with~'not-empty'\\
+    For~technical~reasons,~you~must~activate~
+    'recreate-cell-nodes'~in~\token_to_str:N \CodeBefore\ 
+    in~order~to~use~the~key~'\l_keys_key_str'.\\
+    That~key~will~be~ignored.
+  }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 \@@_msg_new:nn { ragged2e~not~loaded }
   {
     You~have~to~load~'ragged2e'~in~order~to~use~the~key~'\l_keys_key_str'~in~
@@ -16066,9 +16119,19 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
+\@@_msg_new:nn { TikzEveryCell~without~tikz }
+  {
+    TikZ~not~loaded.\\
+    You~can't~use~\token_to_str:N \TikzEveryCell\
+    because~you~have~not~loaded~tikz.~
+    This~command~will~be~ignored.
+  }
+%    \end{macrocode}
+% 
+%    \begin{macrocode}
 \@@_msg_new:nn { tikz~key~without~tikz }
   {
-    Tikz~not~loaded.\\
+    TikZ~not~loaded.\\
     You~can't~use~the~key~'tikz'~for~the~command~'\token_to_str:N
     \Block'~because~you~have~not~loaded~tikz.~
     This~key~will~be~ignored.
@@ -16190,6 +16253,15 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
+\@@_msg_new:nn { tikz~without~tikz } 
+  {
+    Tikz~not~loaded.\\
+    You~can't~use~the~key~'tikz'~here~because~Tikz~is~not~
+    loaded.~If~you~go~on,~that~key~will~be~ignored.
+  }
+%    \end{macrocode}
+% 
+%    \begin{macrocode}
 \@@_msg_new:nn { tikz~in~custom-line~without~tikz } 
   {
     Tikz~not~loaded.\\
@@ -16714,6 +16786,15 @@
   }
 %    \end{macrocode}
 %
+%    \begin{macrocode}
+\@@_msg_new:nn { NiceTabularX~without~X }
+  {
+    NiceTabularX~without~X.\\
+    You~should~not~use~{NiceTabularX}~without~X~columns.\\
+    However,~you~can~go~on.
+  }
+%    \end{macrocode}
+% 
 % \newpage
 % \tableofcontents
 %

Modified: trunk/Master/texmf-dist/tex/latex/nicematrix/nicematrix.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/nicematrix/nicematrix.sty	2023-09-29 21:04:41 UTC (rev 68397)
+++ trunk/Master/texmf-dist/tex/latex/nicematrix/nicematrix.sty	2023-09-29 21:05:29 UTC (rev 68398)
@@ -18,8 +18,8 @@
 %% and version 1.3 or later is part of all distributions of
 %% LaTeX version 2005/12/01 or later.
 %% 
-\def\myfileversion{6.23}
-\def\myfiledate{2023/09/02}
+\def\myfileversion{6.24}
+\def\myfiledate{2023/09/28}
 \RequirePackage{pgfcore}
 \usepgfmodule{shapes}
 \RequirePackage{l3keys2e}
@@ -303,29 +303,6 @@
   { \tl_if_blank:nF { #1 } { \__nicematrix_exp_color_arg:Nn \color { #1 } } }
 \cs_generate_variant:Nn \__nicematrix_color:n { V }
 \cs_set_eq:NN \__nicematrix_old_pgfpointanchor \pgfpointanchor
-\hook_gput_code:nnn { begindocument } { . }
-  {
-    \IfPackageLoadedTF { siunitx }
-      {
-        \cs_new_protected:Npn \__nicematrix_renew_NC at rewrite@S:
-          {
-            \renewcommand*{\NC at rewrite@S}[1][]
-              {
-                \tl_if_empty:nTF { ##1 }
-                  {
-                    \@temptokena \exp_after:wN
-                      { \tex_the:D \@temptokena \__nicematrix_S: }
-                  }
-                  {
-                    \@temptokena \exp_after:wN
-                      { \tex_the:D \@temptokena \__nicematrix_S: [ ##1 ] }
-                  }
-                \NC at find
-              }
-          }
-      }
-      { \cs_set_eq:NN \__nicematrix_renew_NC at rewrite@S: \prg_do_nothing: }
-  }
 \cs_new_protected:Npn \__nicematrix_rescan_for_spanish:N #1
   {
     \tl_set_rescan:Nno
@@ -370,6 +347,7 @@
 \bool_set_true:N \l__nicematrix_notes_detect_duplicates_bool
 \dim_new:N \l__nicematrix_tabular_width_dim
 \dim_new:N \l__nicematrix_rule_width_dim
+\tl_new:N \l__nicematrix_rule_color_tl
 \bool_new:N \g__nicematrix_rotate_bool
 \bool_new:N \g__nicematrix_rotate_c_bool
 \bool_new:N \l__nicematrix_X_column_bool
@@ -379,10 +357,11 @@
 \seq_new:N \g__nicematrix_size_seq
 \tl_new:N \g__nicematrix_left_delim_tl
 \tl_new:N \g__nicematrix_right_delim_tl
+\tl_new:N \g__nicematrix_user_preamble_tl
+\tl_new:N \g__nicematrix_array_preamble_tl
 \tl_new:N \g__nicematrix_preamble_tl
 \tl_new:N \l__nicematrix_columns_type_tl
-\hook_gput_code:nnn { begindocument } { . }
-  { \__nicematrix_set_preamble:Nn \l__nicematrix_columns_type_tl { c } }
+\tl_set:Nn \l__nicematrix_columns_type_tl { c }
 \tl_new:N \l__nicematrix_xdots_down_tl
 \tl_new:N \l__nicematrix_xdots_up_tl
 \tl_new:N \l__nicematrix_xdots_middle_tl
@@ -458,6 +437,7 @@
 \dim_new:N \l__nicematrix_rounded_corners_dim
 \dim_new:N \l__nicematrix_tab_rounded_corners_dim
 \tl_new:N \l__nicematrix_color_tl
+\dim_new:N \l__nicematrix_offset_dim
 \dim_new:N \l__nicematrix_line_width_dim
 \str_new:N \l__nicematrix_hpos_block_str
 \str_set:Nn \l__nicematrix_hpos_block_str { c }
@@ -1014,6 +994,7 @@
     SubMatrix / rules .inherit:n = NiceMatrix / rules ,
     CodeAfter / xdots .inherit:n = NiceMatrix / xdots ,
     CodeBefore / sub-matrix .inherit:n = NiceMatrix / sub-matrix ,
+    CodeAfter / sub-matrix .inherit:n = NiceMatrix / sub-matrix ,
     NiceMatrix .inherit:n =
       {
         NiceMatrix / Global ,
@@ -1074,8 +1055,7 @@
     notes .value_required:n = true ,
     sub-matrix .code:n = \keys_set:nn { NiceMatrix / sub-matrix } { #1 } ,
     sub-matrix .value_required:n = true ,
-    matrix / columns-type .code:n =
-      \__nicematrix_set_preamble:Nn \l__nicematrix_columns_type_tl { #1 },
+    matrix / columns-type .tl_set:N = \l__nicematrix_columns_type_tl ,
     matrix / columns-type .value_required:n = true ,
     caption-above .bool_set:N = \l__nicematrix_caption_above_bool ,
     caption-above .default:n = true ,
@@ -1091,7 +1071,7 @@
                            \int_set:Nn \l__nicematrix_last_col_int { -1 }
                          }
                          { \int_set:Nn \l__nicematrix_last_col_int { #1 } } ,
-    columns-type .code:n = \__nicematrix_set_preamble:Nn \l__nicematrix_columns_type_tl { #1 } ,
+    columns-type .tl_set:N = \l__nicematrix_columns_type_tl ,
     columns-type .value_required:n = true ,
     l .meta:n = { columns-type = l } ,
     r .meta:n = { columns-type = r } ,
@@ -1156,6 +1136,17 @@
     l .code:n = \__nicematrix_error:n { r~or~l~with~preamble } ,
     unknown .code:n = \__nicematrix_error:n { Unknown~key~for~NiceTabular }
   }
+\keys_define:nn { NiceMatrix / CodeAfter }
+  {
+    delimiters / color .tl_set:N = \l__nicematrix_delimiters_color_tl ,
+    delimiters / color .value_required:n = true ,
+    rules .code:n = \keys_set:nn { NiceMatrix / rules } { #1 } ,
+    rules .value_required:n = true ,
+    xdots .code:n = \keys_set:nn { NiceMatrix / xdots } { #1 } ,
+    sub-matrix .code:n = \keys_set:nn { NiceMatrix / sub-matrix } { #1 } ,
+    sub-matrix .value_required:n = true ,
+    unknown .code:n = \__nicematrix_error:n { Unknown~key~for~CodeAfter }
+  }
 \cs_new_protected:Npn \__nicematrix_cell_begin:w
   {
     \tl_gclear:N \g__nicematrix_cell_after_hook_tl
@@ -1461,13 +1452,6 @@
           }
       }
   }
-\cs_set_protected:Npn \__nicematrix_newcolumntype #1
-  {
-    \cs_set:cpn { NC @ find @ #1 } ##1 #1 { \NC@ { ##1 } }
-    \peek_meaning:NTF [
-      { \newcol@ #1 }
-      { \newcol@ #1 [ 0 ] }
-  }
 \cs_set_protected:Npn \__nicematrix_renew_dots:
   {
     \cs_set_eq:NN \ldots \__nicematrix_Ldots
@@ -1581,7 +1565,6 @@
     \int_gzero_new:N \g__nicematrix_row_total_int
     \int_gzero_new:N \g__nicematrix_col_total_int
     \cs_set_eq:NN \@ifnextchar \new at ifnextchar
-    \__nicematrix_renew_NC at rewrite@S:
     \bool_gset_false:N \g__nicematrix_last_col_found_bool
     \tl_gclear_new:N \g__nicematrix_Cdots_lines_tl
     \tl_gclear_new:N \g__nicematrix_Ldots_lines_tl
@@ -1703,6 +1686,7 @@
     \cs_set_eq:NN \chessboardcolors \__nicematrix_chessboardcolors
     \cs_set_eq:NN \SubMatrix \__nicematrix_SubMatrix_in_code_before
     \cs_set_eq:NN \ShowCellNames \__nicematrix_ShowCellNames
+    \cs_set_eq:NN \TikzEveryCell \__nicematrix_TikzEveryCell
   }
 \cs_new_protected:Npn \__nicematrix_exec_code_before:
   {
@@ -1841,7 +1825,7 @@
     \bgroup
     \tl_gset:Nn \g__nicematrix_left_delim_tl { #1 }
     \tl_gset:Nn \g__nicematrix_right_delim_tl { #2 }
-    \tl_gset:Nn \g__nicematrix_preamble_tl { #4 }
+    \tl_gset:Nn \g__nicematrix_user_preamble_tl { #4 }
     \int_gzero:N \g__nicematrix_block_box_int
     \dim_zero:N \g__nicematrix_width_last_col_dim
     \dim_zero:N \g__nicematrix_width_first_col_dim
@@ -2031,37 +2015,31 @@
   }
 \cs_new_protected:Npn \__nicematrix_transform_preamble:
   {
-    \bool_if:NT \l__nicematrix_preamble_bool \__nicematrix_transform_preamble_i:
+    \__nicematrix_transform_preamble_i:
     \__nicematrix_transform_preamble_ii:
   }
 \cs_new_protected:Npn \__nicematrix_transform_preamble_i:
   {
+    \int_gzero:N \c at jCol
     \group_begin:
-    \__nicematrix_newcolumntype w [ 2 ] { \__nicematrix_w: { ##1 } { ##2 } }
-    \__nicematrix_newcolumntype W [ 2 ] { \__nicematrix_W: { ##1 } { ##2 } }
-     \cs_if_exist:NT \NC at find@V { \__nicematrix_newcolumntype V { \__nicematrix_V: } }
-    \exp_args:NV \@temptokena \g__nicematrix_preamble_tl
-    \@tempswatrue
-    \@whilesw \if at tempswa \fi { \@tempswafalse \the \NC at list }
-    \int_gzero:N \c at jCol
-    \tl_gclear:N \g__nicematrix_preamble_tl
+    \seq_gclear:N \g__nicematrix_cols_vlism_seq
     \bool_gset_false:N \g_tmpb_bool
+    \tl_gclear_new:N \g__nicematrix_pre_cell_tl
+    \int_zero:N \l_tmpa_int
+    \tl_gclear:N \g__nicematrix_array_preamble_tl
     \tl_if_eq:NnTF \l__nicematrix_vlines_clist { all }
       {
-        \tl_gset:Nn \g__nicematrix_preamble_tl
+        \tl_gset:Nn \g__nicematrix_array_preamble_tl
           { ! { \skip_horizontal:N \arrayrulewidth } }
       }
       {
         \clist_if_in:NnT \l__nicematrix_vlines_clist 1
           {
-            \tl_gset:Nn \g__nicematrix_preamble_tl
+            \tl_gset:Nn \g__nicematrix_array_preamble_tl
               { ! { \skip_horizontal:N \arrayrulewidth } }
           }
       }
-    \seq_clear:N \g__nicematrix_cols_vlism_seq
-    \tl_gclear_new:N \g__nicematrix_pre_cell_tl
-    \int_zero:N \l_tmpa_int
-    \exp_after:wN \__nicematrix_patch_preamble:n \the \@temptokena \q_stop
+    \exp_last_unbraced:NV \__nicematrix_make_preamble:n \g__nicematrix_user_preamble_tl \q_stop
     \int_gset_eq:NN \g__nicematrix_static_num_of_col_int \c at jCol
     \bool_if:NT \l__nicematrix_color_inside_bool
       {
@@ -2068,7 +2046,7 @@
         \regex_replace_all:NnN
           \c__nicematrix_columncolor_regex
           { \c { __nicematrix_columncolor_preamble } }
-          \g__nicematrix_preamble_tl
+          \g__nicematrix_array_preamble_tl
       }
     \group_end:
   }
@@ -2080,7 +2058,7 @@
        { \bool_gset_true:N \g__nicematrix_delims_bool }
     \bool_if:NT \g_tmpb_bool { \bool_set_true:N \l__nicematrix_bar_at_end_of_pream_bool }
     \int_compare:nNnTF \l__nicematrix_first_col_int = 0
-      { \tl_gput_left:NV \g__nicematrix_preamble_tl \c__nicematrix_preamble_first_col_tl }
+      { \tl_gput_left:NV \g__nicematrix_array_preamble_tl \c__nicematrix_preamble_first_col_tl }
       {
         \bool_lazy_all:nT
           {
@@ -2089,10 +2067,10 @@
             { \tl_if_empty_p:N \l__nicematrix_vlines_clist }
             { \bool_not_p:n \l__nicematrix_exterior_arraycolsep_bool }
           }
-          { \tl_gput_left:Nn \g__nicematrix_preamble_tl { @ { } } }
+          { \tl_gput_left:Nn \g__nicematrix_array_preamble_tl { @ { } } }
       }
     \int_compare:nNnTF \l__nicematrix_last_col_int > { -1 }
-      { \tl_gput_right:NV \g__nicematrix_preamble_tl \c__nicematrix_preamble_last_col_tl }
+      { \tl_gput_right:NV \g__nicematrix_array_preamble_tl \c__nicematrix_preamble_last_col_tl }
       {
         \bool_lazy_all:nT
           {
@@ -2101,73 +2079,81 @@
             { \tl_if_empty_p:N \l__nicematrix_vlines_clist }
             { \bool_not_p:n \l__nicematrix_exterior_arraycolsep_bool }
           }
-          { \tl_gput_right:Nn \g__nicematrix_preamble_tl { @ { } } }
+          { \tl_gput_right:Nn \g__nicematrix_array_preamble_tl { @ { } } }
       }
     \dim_compare:nNnT \l__nicematrix_tabular_width_dim = \c_zero_dim
       {
-        \tl_gput_right:Nn \g__nicematrix_preamble_tl
+        \tl_gput_right:Nn \g__nicematrix_array_preamble_tl
           { > { \__nicematrix_error_too_much_cols: } l }
       }
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble:n #1
+\cs_new_protected:Npn \__nicematrix_make_preamble:n #1
   {
-    \str_case:nnF { #1 }
+    \str_if_eq:nnF { #1 } { \q_stop }
       {
-        c       { \__nicematrix_patch_preamble_i:n #1 }
-        l       { \__nicematrix_patch_preamble_i:n #1 }
-        r       { \__nicematrix_patch_preamble_i:n #1 }
-        >       { \__nicematrix_patch_preamble_xiv:n }
-        !       { \__nicematrix_patch_preamble_ii:nn #1 }
-        @       { \__nicematrix_patch_preamble_ii:nn #1 }
-        |       { \__nicematrix_patch_preamble_iii:n #1 }
-        p       { \__nicematrix_patch_preamble_iv:n #1 }
-        b       { \__nicematrix_patch_preamble_iv:n #1 }
-        m       { \__nicematrix_patch_preamble_iv:n #1 }
-        \__nicematrix_V:  { \__nicematrix_patch_preamble_v:n }
-        V       { \__nicematrix_patch_preamble_v:n }
-        \__nicematrix_w:  { \__nicematrix_patch_preamble_vi:nnnn { } #1 }
-        \__nicematrix_W:  { \__nicematrix_patch_preamble_vi:nnnn { \__nicematrix_special_W: } #1 }
-        \__nicematrix_S:  { \__nicematrix_patch_preamble_vii:n }
-        (       { \__nicematrix_patch_preamble_viii:nn #1 }
-        [       { \__nicematrix_patch_preamble_viii:nn #1 }
-        \{      { \__nicematrix_patch_preamble_viii:nn #1 }
-        \left   { \__nicematrix_patch_preamble_viii:nn }
-        )       { \__nicematrix_patch_preamble_ix:nn #1 }
-        ]       { \__nicematrix_patch_preamble_ix:nn #1 }
-        \}      { \__nicematrix_patch_preamble_ix:nn #1 }
-        \right  { \__nicematrix_patch_preamble_ix:nn }
-        X       { \__nicematrix_patch_preamble_x:n }
-        \__nicematrix_X   { \__nicematrix_patch_preamble_x:n }
-        \q_stop { }
-      }
-      {
-        \str_if_eq:nVTF { #1 } \l__nicematrix_letter_vlism_tl
+        \cs_if_exist:cTF { __nicematrix \token_to_str:N #1 }
+          { \use:c { __nicematrix \token_to_str:N #1 } { #1 } }
           {
-            \seq_gput_right:Nx \g__nicematrix_cols_vlism_seq
-              { \int_eval:n { \c at jCol + 1 } }
-            \tl_gput_right:Nx \g__nicematrix_preamble_tl
-              { \exp_not:N ! { \skip_horizontal:N \arrayrulewidth } }
-            \__nicematrix_patch_preamble:n
-          }
-          {
-            \keys_if_exist:nnTF { NiceMatrix / ColumnTypes } { #1 }
+            \str_if_eq:nVTF { #1 } \l__nicematrix_letter_vlism_tl
               {
-                \keys_set:nn { NiceMatrix / ColumnTypes } { #1 }
-                \__nicematrix_patch_preamble:n
+                \seq_gput_right:Nx \g__nicematrix_cols_vlism_seq
+                  { \int_eval:n { \c at jCol + 1 } }
+                \tl_gput_right:Nx \g__nicematrix_array_preamble_tl
+                  { \exp_not:N ! { \skip_horizontal:N \arrayrulewidth } }
+                \__nicematrix_make_preamble:n
               }
               {
-                \tl_if_eq:nnT { #1 } { S }
-                  { \__nicematrix_fatal:n { unknown~column~type~S } }
-                  { \__nicematrix_fatal:nn { unknown~column~type } { #1 } }
+                \keys_if_exist:nnTF { NiceMatrix / ColumnTypes } { #1 }
+                  {
+                    \keys_set:nn { NiceMatrix / ColumnTypes } { #1 }
+                    \__nicematrix_make_preamble:n
+                  }
+                  {
+                    \cs_if_exist:cTF { NC @ find @ #1 }
+                      {
+                        \tl_set_eq:Nc \l_tmpb_tl { NC @ rewrite @ #1 }
+                        \exp_last_unbraced:NV \__nicematrix_make_preamble:n \l_tmpb_tl
+                      }
+                      {
+                        \tl_if_eq:nnT { #1 } { S }
+                          { \__nicematrix_fatal:n { unknown~column~type~S } }
+                          { \__nicematrix_fatal:nn { unknown~column~type } { #1 } }
+                      }
+                  }
               }
           }
       }
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_i:n #1
+\cs_new:cpn { __nicematrix \string c }        { \__nicematrix_make_preamble_i:n }
+\cs_new:cpn { __nicematrix \string l }        { \__nicematrix_make_preamble_i:n }
+\cs_new:cpn { __nicematrix \string r }        { \__nicematrix_make_preamble_i:n }
+\cs_new:cpn { __nicematrix \string > }        { \__nicematrix_make_preamble_xiv:nn }
+\cs_new:cpn { __nicematrix \string ! }        { \__nicematrix_make_preamble_ii:nn }
+\cs_new:cpn { __nicematrix \string @ }        { \__nicematrix_make_preamble_ii:nn }
+\cs_new:cpn { __nicematrix \string | }        { \__nicematrix_make_preamble_iii:n }
+\cs_new:cpn { __nicematrix \string p }        { \__nicematrix_make_preamble_iv:n }
+\cs_new:cpn { __nicematrix \string b }        { \__nicematrix_make_preamble_iv:n }
+\cs_new:cpn { __nicematrix \string m }        { \__nicematrix_make_preamble_iv:n }
+\cs_new:cpn { __nicematrix \string V }        { \__nicematrix_make_preamble_v:nn }
+\cs_new:cpn { __nicematrix \string w }        { \__nicematrix_make_preamble_vi:nnnn { } }
+\cs_new:cpn { __nicematrix \string W }        { \__nicematrix_make_preamble_vi:nnnn { \__nicematrix_special_W: } }
+\cs_new:cpn { __nicematrix \string S }        { \__nicematrix_make_preamble_vii:nn }
+\cs_new:cpn { __nicematrix \string ( }        { \__nicematrix_make_preamble_viii:nn }
+\cs_new:cpn { __nicematrix \string [ }        { \__nicematrix_make_preamble_viii:nn }
+\cs_new:cpn { __nicematrix \string \{ }       { \__nicematrix_make_preamble_viii:nn }
+\cs_new:cpn { __nicematrix \string \left }    { \__nicematrix_make_preamble_viii_ii:n }
+\cs_new:cpn { __nicematrix \string ) }        { \__nicematrix_make_preamble_ix:nn }
+\cs_new:cpn { __nicematrix \string ] }        { \__nicematrix_make_preamble_ix:nn }
+\cs_new:cpn { __nicematrix \string \} }       { \__nicematrix_make_preamble_ix:nn }
+\cs_new:cpn { __nicematrix \string \right }   { \__nicematrix_make_preamble_ix_ii:n }
+\cs_new:cpn { __nicematrix \string X }        { \__nicematrix_make_preamble_x:nn }
+\cs_new:cpn { __nicematrix \string * }        { \__nicematrix_make_preamble_xvi:nnn }
+\cs_new:cpn { __nicematrix \string \NC at find } { \__nicematrix_make_preamble_xx:n }
+\cs_new_protected:Npn \__nicematrix_make_preamble_i:n #1
   {
-    \tl_gput_right:NV \g__nicematrix_preamble_tl \g__nicematrix_pre_cell_tl
+    \tl_gput_right:NV \g__nicematrix_array_preamble_tl \g__nicematrix_pre_cell_tl
     \tl_gclear:N \g__nicematrix_pre_cell_tl
-    \tl_gput_right:Nn \g__nicematrix_preamble_tl
+    \tl_gput_right:Nn \g__nicematrix_array_preamble_tl
       {
         > { \__nicematrix_cell_begin:w \str_set:Nn \l__nicematrix_hpos_cell_str { #1 } }
         #1
@@ -2174,32 +2160,36 @@
         < \__nicematrix_cell_end:
       }
     \int_gincr:N \c at jCol
-    \__nicematrix_patch_preamble_xi:n
+    \__nicematrix_make_preamble_xi:n
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_ii:nn #1 #2
+\cs_new_protected:Npn \__nicematrix_make_preamble_ii:nn #1 #2
   {
-    \tl_gput_right:Nn \g__nicematrix_preamble_tl { #1 { #2 } }
-    \__nicematrix_patch_preamble:n
+    \tl_gput_right:Nn \g__nicematrix_array_preamble_tl { #1 { #2 } }
+    \__nicematrix_make_preamble:n
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_iii:n #1
+\cs_new_protected:Npn \__nicematrix_make_preamble_iii:n #1
   {
     \int_incr:N \l_tmpa_int
-    \__nicematrix_patch_preamble_iii_i:n
+    \__nicematrix_make_preamble_iii_i:n
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_iii_i:n #1
+\cs_new_protected:Npn \__nicematrix_make_preamble_iii_i:n #1
   {
     \str_if_eq:nnTF { #1 } |
-      { \__nicematrix_patch_preamble_iii:n | }
-      {
-        \str_if_eq:nnTF { #1 } [
-          { \__nicematrix_patch_preamble_iii_ii:nw { } [ }
-          { \__nicematrix_patch_preamble_iii_ii:nw { #1 } [ ] }
-      }
+      { \__nicematrix_make_preamble_iii:n | }
+      { \__nicematrix_make_preamble_iii_ii:nn { } #1 }
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_iii_ii:nw #1 [ #2 ]
+\cs_new_protected:Npn \__nicematrix_make_preamble_iii_ii:nn #1 #2
   {
+    \str_if_eq:nnTF { #2 } [
+      { \__nicematrix_make_preamble_iii_ii:nw { #1 } [ }
+      { \__nicematrix_make_preamble_iii_iii:nn { #2 } { #1 } }
+  }
+\cs_new_protected:Npn \__nicematrix_make_preamble_iii_ii:nw #1 [ #2 ]
+  { \__nicematrix_make_preamble_iii_ii:nn { #1 , #2 } }
+\cs_new_protected:Npn \__nicematrix_make_preamble_iii_iii:nn #1 #2
+  {
     \__nicematrix_compute_rule_width:n { multiplicity = \l_tmpa_int , #2 }
-    \tl_gput_right:Nx \g__nicematrix_preamble_tl
+    \tl_gput_right:Nx \g__nicematrix_array_preamble_tl
       {
         \exp_not:N ! { \skip_horizontal:n { \dim_eval:n { \l__nicematrix_rule_width_dim } } }
       }
@@ -2215,12 +2205,12 @@
       }
     \int_zero:N \l_tmpa_int
     \str_if_eq:nnT { #1 } { \q_stop } { \bool_gset_true:N \g_tmpb_bool }
-    \__nicematrix_patch_preamble:n #1
+    \__nicematrix_make_preamble:n #1
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_xiv:n #1
+\cs_new_protected:Npn \__nicematrix_make_preamble_xiv:nn #1 #2
   {
-    \tl_gput_right:Nn \g__nicematrix_pre_cell_tl { > { #1 } }
-    \__nicematrix_patch_preamble:n
+    \tl_gput_right:Nn \g__nicematrix_pre_cell_tl { > { #2 } }
+    \__nicematrix_make_preamble:n
   }
 \bool_new:N \l__nicematrix_bar_at_end_of_pream_bool
 \keys_define:nn { WithArrows / p-column }
@@ -2265,35 +2255,34 @@
     b .code:n = \str_set:Nn \l__nicematrix_vpos_col_str { b } ,
     b .value_forbidden:n = true ,
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_iv:n #1
+\cs_new_protected:Npn \__nicematrix_make_preamble_iv:n #1
   {
     \str_set:Nn \l__nicematrix_vpos_col_str { #1 }
-    \__nicematrix_patch_preamble_iv_i:n
+    \__nicematrix_make_preamble_iv_i:n
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_iv_i:n #1
+\cs_new_protected:Npn \__nicematrix_make_preamble_iv_i:n #1
   {
     \str_if_eq:nnTF { #1 } { [ }
-      { \__nicematrix_patch_preamble_iv_ii:w [ }
-      { \__nicematrix_patch_preamble_iv_ii:w [ ] { #1 } }
+      { \__nicematrix_make_preamble_iv_ii:w [ }
+      { \__nicematrix_make_preamble_iv_ii:w [ ] { #1 } }
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_iv_ii:w [ #1 ]
-  { \__nicematrix_patch_preamble_iv_iii:nn { #1 } }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_iv_iii:nn #1 #2
+\cs_new_protected:Npn \__nicematrix_make_preamble_iv_ii:w [ #1 ]
+  { \__nicematrix_make_preamble_iv_iii:nn { #1 } }
+\cs_new_protected:Npn \__nicematrix_make_preamble_iv_iii:nn #1 #2
   {
     \str_set:Nn \l__nicematrix_hpos_col_str { j }
     \tl_set:Nn \l_tmpa_tl { #1 }
-    \tl_replace_all:Nnn \l_tmpa_tl { \__nicematrix_S: } { S }
     \__nicematrix_keys_p_column:V \l_tmpa_tl
-    \__nicematrix_patch_preamble_iv_iv:nn { #2 } { minipage }
+    \__nicematrix_make_preamble_iv_iv:nn { #2 } { minipage }
   }
 \cs_new_protected:Npn \__nicematrix_keys_p_column:n #1
   { \keys_set_known:nnN { WithArrows / p-column } { #1 } \l_tmpa_tl }
 \cs_generate_variant:Nn \__nicematrix_keys_p_column:n { V }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_iv_iv:nn #1 #2
+\cs_new_protected:Npn \__nicematrix_make_preamble_iv_iv:nn #1 #2
   {
     \use:x
       {
-        \__nicematrix_patch_preamble_iv_v:nnnnnnnn
+        \__nicematrix_make_preamble_iv_v:nnnnnnnn
           { \str_if_eq:VnTF \l__nicematrix_vpos_col_str { p } { t } { b } }
           { \dim_eval:n { #1 } }
           {
@@ -2327,16 +2316,16 @@
           }
       }
     \int_gincr:N \c at jCol
-    \__nicematrix_patch_preamble_xi:n
+    \__nicematrix_make_preamble_xi:n
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_iv_v:nnnnnnnn #1 #2 #3 #4 #5 #6 #7 #8
+\cs_new_protected:Npn \__nicematrix_make_preamble_iv_v:nnnnnnnn #1 #2 #3 #4 #5 #6 #7 #8
   {
     \str_if_eq:VnTF \l__nicematrix_hpos_col_str { si }
-      { \tl_gput_right:Nn \g__nicematrix_preamble_tl { > { \__nicematrix_test_if_empty_for_S: } } }
-      { \tl_gput_right:Nn \g__nicematrix_preamble_tl { > { \__nicematrix_test_if_empty: } } }
-    \tl_gput_right:NV \g__nicematrix_preamble_tl \g__nicematrix_pre_cell_tl
+      { \tl_gput_right:Nn \g__nicematrix_array_preamble_tl { > { \__nicematrix_test_if_empty_for_S: } } }
+      { \tl_gput_right:Nn \g__nicematrix_array_preamble_tl { > { \__nicematrix_test_if_empty: } } }
+    \tl_gput_right:NV \g__nicematrix_array_preamble_tl \g__nicematrix_pre_cell_tl
     \tl_gclear:N \g__nicematrix_pre_cell_tl
-    \tl_gput_right:Nn \g__nicematrix_preamble_tl
+    \tl_gput_right:Nn \g__nicematrix_array_preamble_tl
       {
         > {
             \dim_set:Nn \l__nicematrix_col_width_dim { #2 }
@@ -2405,39 +2394,38 @@
           }
       }
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_v:n #1
+\cs_new_protected:Npn \__nicematrix_make_preamble_v:nn #1 #2
   {
-    \str_if_eq:nnTF { #1 } { [ }
-      { \__nicematrix_patch_preamble_v_i:w [ }
-      { \__nicematrix_patch_preamble_v_i:w [ ] { #1 } }
+    \str_if_eq:nnTF { #2 } { [ }
+      { \__nicematrix_make_preamble_v_i:w [ }
+      { \__nicematrix_make_preamble_v_i:w [ ] { #2 } }
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_v_i:w [ #1 ]
-  { \__nicematrix_patch_preamble_v_ii:nn { #1 } }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_v_ii:nn #1 #2
+\cs_new_protected:Npn \__nicematrix_make_preamble_v_i:w [ #1 ]
+  { \__nicematrix_make_preamble_v_ii:nn { #1 } }
+\cs_new_protected:Npn \__nicematrix_make_preamble_v_ii:nn #1 #2
   {
     \str_set:Nn \l__nicematrix_vpos_col_str { p }
     \str_set:Nn \l__nicematrix_hpos_col_str { j }
     \tl_set:Nn \l_tmpa_tl { #1 }
-    \tl_replace_all:Nnn \l_tmpa_tl { \__nicematrix_S: } { S }
     \__nicematrix_keys_p_column:V \l_tmpa_tl
     \IfPackageLoadedTF { varwidth }
-      { \__nicematrix_patch_preamble_iv_iv:nn { #2 } { varwidth } }
+      { \__nicematrix_make_preamble_iv_iv:nn { #2 } { varwidth } }
       {
         \__nicematrix_error_or_warning:n { varwidth~not~loaded }
-        \__nicematrix_patch_preamble_iv_iv:nn { #2 } { minipage }
+        \__nicematrix_make_preamble_iv_iv:nn { #2 } { minipage }
       }
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_vi:nnnn #1 #2 #3 #4
+\cs_new_protected:Npn \__nicematrix_make_preamble_vi:nnnn #1 #2 #3 #4
   {
     \str_if_eq:nnTF { #3 } { s }
-      { \__nicematrix_patch_preamble_vi_i:nnnn { #1 } { #4 } }
-      { \__nicematrix_patch_preamble_vi_ii:nnnn { #1 } { #2 } { #3 } { #4 } }
+      { \__nicematrix_make_preamble_vi_i:nnnn { #1 } { #4 } }
+      { \__nicematrix_make_preamble_vi_ii:nnnn { #1 } { #2 } { #3 } { #4 } }
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_vi_i:nnnn #1 #2
+\cs_new_protected:Npn \__nicematrix_make_preamble_vi_i:nnnn #1 #2
   {
-    \tl_gput_right:NV \g__nicematrix_preamble_tl \g__nicematrix_pre_cell_tl
+    \tl_gput_right:NV \g__nicematrix_array_preamble_tl \g__nicematrix_pre_cell_tl
     \tl_gclear:N \g__nicematrix_pre_cell_tl
-    \tl_gput_right:Nn \g__nicematrix_preamble_tl
+    \tl_gput_right:Nn \g__nicematrix_array_preamble_tl
       {
         > {
             \dim_set:Nn \l__nicematrix_col_width_dim { #2 }
@@ -2453,13 +2441,13 @@
           }
       }
     \int_gincr:N \c at jCol
-    \__nicematrix_patch_preamble_xi:n
+    \__nicematrix_make_preamble_xi:n
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_vi_ii:nnnn #1 #2 #3 #4
+\cs_new_protected:Npn \__nicematrix_make_preamble_vi_ii:nnnn #1 #2 #3 #4
   {
-    \tl_gput_right:NV \g__nicematrix_preamble_tl \g__nicematrix_pre_cell_tl
+    \tl_gput_right:NV \g__nicematrix_array_preamble_tl \g__nicematrix_pre_cell_tl
     \tl_gclear:N \g__nicematrix_pre_cell_tl
-    \tl_gput_right:Nn \g__nicematrix_preamble_tl
+    \tl_gput_right:Nn \g__nicematrix_array_preamble_tl
       {
         > {
             \dim_set:Nn \l__nicematrix_col_width_dim { #4 }
@@ -2477,7 +2465,7 @@
           }
       }
     \int_gincr:N \c at jCol
-    \__nicematrix_patch_preamble_xi:n
+    \__nicematrix_make_preamble_xi:n
   }
 \cs_new_protected:Npn \__nicematrix_special_W:
   {
@@ -2484,21 +2472,21 @@
     \dim_compare:nNnT { \box_wd:N \l__nicematrix_cell_box } > \l__nicematrix_col_width_dim
       { \__nicematrix_warning:n { W~warning } }
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_vii:n #1
+\cs_new_protected:Npn \__nicematrix_make_preamble_vii:nn #1 #2
   {
-    \str_if_eq:nnTF { #1 } { [ }
-      { \__nicematrix_patch_preamble_vii_i:w [ }
-      { \__nicematrix_patch_preamble_vii_i:w [ ] { #1 } }
+    \str_if_eq:nnTF { #2 } { [ }
+      { \__nicematrix_make_preamble_vii_i:w [ }
+      { \__nicematrix_make_preamble_vii_i:w [ ] { #2 } }
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_vii_i:w [ #1 ]
-  { \__nicematrix_patch_preamble_vii_ii:n { #1 } }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_vii_ii:n #1
+\cs_new_protected:Npn \__nicematrix_make_preamble_vii_i:w [ #1 ]
+  { \__nicematrix_make_preamble_vii_ii:n { #1 } }
+\cs_new_protected:Npn \__nicematrix_make_preamble_vii_ii:n #1
   {
     \IfPackageAtLeastTF { siunitx } { 2022/01/01 }
       {
-        \tl_gput_right:NV \g__nicematrix_preamble_tl \g__nicematrix_pre_cell_tl
+        \tl_gput_right:NV \g__nicematrix_array_preamble_tl \g__nicematrix_pre_cell_tl
         \tl_gclear:N \g__nicematrix_pre_cell_tl
-        \tl_gput_right:Nn \g__nicematrix_preamble_tl
+        \tl_gput_right:Nn \g__nicematrix_array_preamble_tl
           {
             > {
                 \__nicematrix_cell_begin:w
@@ -2509,11 +2497,11 @@
             < { \siunitx_cell_end: \__nicematrix_cell_end: }
           }
         \int_gincr:N \c at jCol
-        \__nicematrix_patch_preamble_xi:n
+        \__nicematrix_make_preamble_xi:n
       }
       { \__nicematrix_fatal:n { Version~of~siunitx~too~old } }
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_viii:nn #1 #2
+\cs_new_protected:Npn \__nicematrix_make_preamble_viii:nn #1 #2
   {
     \bool_if:NT \l__nicematrix_small_bool { \__nicematrix_fatal:n { Delimiter~with~small } }
     \int_compare:nNnTF \c at jCol = \c_zero_int
@@ -2522,16 +2510,16 @@
           {
             \tl_gset:Nn \g__nicematrix_left_delim_tl { #1 }
             \tl_gset:Nn \g__nicematrix_right_delim_tl { . }
-            \__nicematrix_patch_preamble:n #2
+            \__nicematrix_make_preamble:n #2
           }
           {
-            \tl_gput_right:Nn \g__nicematrix_preamble_tl { ! { \enskip } }
-            \__nicematrix_patch_preamble_viii_i:nn { #1 } { #2 }
+            \tl_gput_right:Nn \g__nicematrix_array_preamble_tl { ! { \enskip } }
+            \__nicematrix_make_preamble_viii_i:nn { #1 } { #2 }
           }
       }
-      { \__nicematrix_patch_preamble_viii_i:nn { #1 } { #2 } }
+      { \__nicematrix_make_preamble_viii_i:nn { #1 } { #2 } }
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_viii_i:nn #1 #2
+\cs_new_protected:Npn \__nicematrix_make_preamble_viii_i:nn #1 #2
   {
     \tl_gput_right:Nx \g__nicematrix_pre_code_after_tl
       { \__nicematrix_delimiter:nnn #1 { \int_eval:n { \c at jCol + 1 } } \c_true_bool }
@@ -2538,15 +2526,17 @@
     \tl_if_in:nnTF { ( [ \{ ) ] \} \left \right } { #2 }
       {
         \__nicematrix_error:nn { delimiter~after~opening } { #2 }
-        \__nicematrix_patch_preamble:n
+        \__nicematrix_make_preamble:n
       }
-      { \__nicematrix_patch_preamble:n #2 }
+      { \__nicematrix_make_preamble:n #2 }
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_ix:nn #1 #2
+\cs_new_protected:Npn \__nicematrix_make_preamble_viii_ii:n #1
+  { \__nicematrix_make_preamble_viii:nn }
+\cs_new_protected:Npn \__nicematrix_make_preamble_ix:nn #1 #2
   {
     \bool_if:NT \l__nicematrix_small_bool { \__nicematrix_fatal:n { Delimiter~with~small } }
     \tl_if_in:nnTF { ) ] \} } { #2 }
-      { \__nicematrix_patch_preamble_ix_i:nnn #1 #2 }
+      { \__nicematrix_make_preamble_ix_i:nnn #1 #2 }
       {
         \tl_if_eq:nnTF { \q_stop } { #2 }
           {
@@ -2553,34 +2543,34 @@
             \str_if_eq:VnTF \g__nicematrix_right_delim_tl { . }
               { \tl_gset:Nn \g__nicematrix_right_delim_tl { #1 } }
               {
-                \tl_gput_right:Nn \g__nicematrix_preamble_tl { ! { \enskip } }
+                \tl_gput_right:Nn \g__nicematrix_array_preamble_tl { ! { \enskip } }
                 \tl_gput_right:Nx \g__nicematrix_pre_code_after_tl
                   { \__nicematrix_delimiter:nnn #1 { \int_use:N \c at jCol } \c_false_bool }
-                \__nicematrix_patch_preamble:n #2
+                \__nicematrix_make_preamble:n #2
               }
           }
           {
             \tl_if_in:nnT { ( [ \{ \left } { #2 }
-              { \tl_gput_right:Nn \g__nicematrix_preamble_tl { ! { \enskip } } }
+              { \tl_gput_right:Nn \g__nicematrix_array_preamble_tl { ! { \enskip } } }
             \tl_gput_right:Nx \g__nicematrix_pre_code_after_tl
               { \__nicematrix_delimiter:nnn #1 { \int_use:N \c at jCol } \c_false_bool }
-            \__nicematrix_patch_preamble:n #2
+            \__nicematrix_make_preamble:n #2
           }
       }
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_ix_i:nnn #1 #2 #3
+\cs_new_protected:Npn \__nicematrix_make_preamble_ix_i:nnn #1 #2 #3
   {
     \tl_if_eq:nnTF { \q_stop } { #3 }
       {
         \str_if_eq:VnTF \g__nicematrix_right_delim_tl { . }
           {
-            \tl_gput_right:Nn \g__nicematrix_preamble_tl { ! { \enskip } }
+            \tl_gput_right:Nn \g__nicematrix_array_preamble_tl { ! { \enskip } }
             \tl_gput_right:Nx \g__nicematrix_pre_code_after_tl
               { \__nicematrix_delimiter:nnn #1 { \int_use:N \c at jCol } \c_false_bool }
             \tl_gset:Nn \g__nicematrix_right_delim_tl { #2 }
           }
           {
-            \tl_gput_right:Nn \g__nicematrix_preamble_tl { ! { \enskip } }
+            \tl_gput_right:Nn \g__nicematrix_array_preamble_tl { ! { \enskip } }
             \tl_gput_right:Nx \g__nicematrix_pre_code_after_tl
               { \__nicematrix_delimiter:nnn #1 { \int_use:N \c at jCol } \c_false_bool }
             \__nicematrix_error:nn { double~closing~delimiter } { #2 }
@@ -2590,20 +2580,22 @@
         \tl_gput_right:Nx \g__nicematrix_pre_code_after_tl
           { \__nicematrix_delimiter:nnn #1 { \int_use:N \c at jCol } \c_false_bool }
         \__nicematrix_error:nn { double~closing~delimiter } { #2 }
-        \__nicematrix_patch_preamble:n #3
+        \__nicematrix_make_preamble:n #3
       }
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_x:n #1
+\cs_new_protected:Npn \__nicematrix_make_preamble_ix_ii:n #1
+  { \__nicematrix_make_preamble_ix:nn }
+\cs_new_protected:Npn \__nicematrix_make_preamble_x:nn #1 #2
   {
-    \str_if_eq:nnTF { #1 } { [ }
-      { \__nicematrix_patch_preamble_x_i:w [ }
-      { \__nicematrix_patch_preamble_x_i:w [ ] #1 }
+    \str_if_eq:nnTF { #2 } { [ }
+      { \__nicematrix_make_preamble_x_i:w [ }
+      { \__nicematrix_make_preamble_x_i:w [ ] #2 }
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_x_i:w [ #1 ]
-  { \__nicematrix_patch_preamble_x_ii:n { #1 } }
+\cs_new_protected:Npn \__nicematrix_make_preamble_x_i:w [ #1 ]
+  { \__nicematrix_make_preamble_x_ii:n { #1 } }
 \keys_define:nn { WithArrows / X-column }
   { unknown .code:n = \int_set:Nn \l__nicematrix_weight_int { \l_keys_key_str } }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_x_ii:n #1
+\cs_new_protected:Npn \__nicematrix_make_preamble_x_ii:n #1
   {
     \str_set:Nn \l__nicematrix_hpos_col_str { j }
     \tl_set:Nn \l__nicematrix_vpos_col_str { p }
@@ -2610,7 +2602,6 @@
     \int_zero_new:N \l__nicematrix_weight_int
     \int_set:Nn \l__nicematrix_weight_int { 1 }
     \tl_set:Nn \l_tmpa_tl { #1 }
-    \tl_replace_all:Nnn \l_tmpa_tl { \__nicematrix_S: } { S }
     \__nicematrix_keys_p_column:V \l_tmpa_tl
     \keys_set:nV { WithArrows / X-column } \l_tmpa_tl
     \int_compare:nNnT \l__nicematrix_weight_int < 0
@@ -2622,12 +2613,12 @@
     \bool_if:NTF \l__nicematrix_X_columns_aux_bool
       {
         \exp_args:Nnx
-        \__nicematrix_patch_preamble_iv_iv:nn
+        \__nicematrix_make_preamble_iv_iv:nn
           { \l__nicematrix_weight_int \l__nicematrix_X_columns_dim }
           { minipage }
       }
       {
-        \tl_gput_right:Nn \g__nicematrix_preamble_tl
+        \tl_gput_right:Nn \g__nicematrix_array_preamble_tl
           {
             > {
                 \__nicematrix_cell_begin:w
@@ -2644,20 +2635,20 @@
               }
           }
         \int_gincr:N \c at jCol
-        \__nicematrix_patch_preamble_xi:n
+        \__nicematrix_make_preamble_xi:n
       }
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_xi:n #1
+\cs_new_protected:Npn \__nicematrix_make_preamble_xi:n #1
   {
     \str_if_eq:nnTF { #1 } { < }
-      \__nicematrix_patch_preamble_xiii:n
+      \__nicematrix_make_preamble_xiii:n
       {
         \str_if_eq:nnTF { #1 } { @ }
-          \__nicematrix_patch_preamble_xv:n
+          \__nicematrix_make_preamble_xv:n
           {
             \tl_if_eq:NnTF \l__nicematrix_vlines_clist { all }
               {
-                \tl_gput_right:Nn \g__nicematrix_preamble_tl
+                \tl_gput_right:Nn \g__nicematrix_array_preamble_tl
                   { ! { \skip_horizontal:N \arrayrulewidth } }
               }
               {
@@ -2664,24 +2655,24 @@
                 \exp_args:NNx
                 \clist_if_in:NnT \l__nicematrix_vlines_clist { \int_eval:n { \c at jCol + 1 } }
                   {
-                    \tl_gput_right:Nn \g__nicematrix_preamble_tl
+                    \tl_gput_right:Nn \g__nicematrix_array_preamble_tl
                       { ! { \skip_horizontal:N \arrayrulewidth } }
                   }
               }
-            \__nicematrix_patch_preamble:n { #1 }
+            \__nicematrix_make_preamble:n { #1 }
           }
       }
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_xiii:n #1
+\cs_new_protected:Npn \__nicematrix_make_preamble_xiii:n #1
   {
-    \tl_gput_right:Nn \g__nicematrix_preamble_tl { < { #1 } }
-    \__nicematrix_patch_preamble_xi:n
+    \tl_gput_right:Nn \g__nicematrix_array_preamble_tl { < { #1 } }
+    \__nicematrix_make_preamble_xi:n
   }
-\cs_new_protected:Npn \__nicematrix_patch_preamble_xv:n #1
+\cs_new_protected:Npn \__nicematrix_make_preamble_xv:n #1
   {
     \tl_if_eq:NnTF \l__nicematrix_vlines_clist { all }
       {
-        \tl_gput_right:Nn \g__nicematrix_preamble_tl
+        \tl_gput_right:Nn \g__nicematrix_array_preamble_tl
           { @ { #1 \skip_horizontal:N \arrayrulewidth } }
       }
       {
@@ -2688,25 +2679,19 @@
         \exp_args:NNx
         \clist_if_in:NnTF \l__nicematrix_vlines_clist { \int_eval:n { \c at jCol + 1 } }
           {
-            \tl_gput_right:Nn \g__nicematrix_preamble_tl
+            \tl_gput_right:Nn \g__nicematrix_array_preamble_tl
               { @ { #1 \skip_horizontal:N \arrayrulewidth } }
           }
-          { \tl_gput_right:Nn \g__nicematrix_preamble_tl { @ { #1 } } }
+          { \tl_gput_right:Nn \g__nicematrix_array_preamble_tl { @ { #1 } } }
       }
-    \__nicematrix_patch_preamble:n
+    \__nicematrix_make_preamble:n
   }
-\cs_new_protected:Npn \__nicematrix_set_preamble:Nn #1 #2
+\cs_new_protected:Npn \__nicematrix_make_preamble_xx:n #1 { \__nicematrix_make_preamble:n }
+\cs_new_protected:Npn \__nicematrix_make_preamble_xvi:nnn #1 #2 #3
   {
-    \group_begin:
-    \__nicematrix_newcolumntype w [ 2 ] { \__nicematrix_w: { ##1 } { ##2 } }
-    \__nicematrix_newcolumntype W [ 2 ] { \__nicematrix_W: { ##1 } { ##2 } }
-    \@temptokena { #2 }
-    \@tempswatrue
-    \@whilesw \if at tempswa \fi { \@tempswafalse \the \NC at list }
-    \tl_gclear:N \g__nicematrix_preamble_tl
-    \exp_after:wN \__nicematrix_patch_m_preamble:n \the \@temptokena \q_stop
-    \group_end:
-    \tl_set_eq:NN #1 \g__nicematrix_preamble_tl
+    \tl_clear:N \l_tmpa_tl
+    \int_step_inline:nn { #2 } { \tl_put_right:Nn \l_tmpa_tl { #3 } }
+    \exp_last_unbraced:NV \__nicematrix_make_preamble:n \l_tmpa_tl
   }
 \cs_new:Npn \__nicematrix_multicolumn:nnn #1 #2 #3
   {
@@ -2713,13 +2698,8 @@
     \multispan { #1 }
     \begingroup
     \cs_set:Npn \@addamp { \if at firstamp \@firstampfalse \else \@preamerr 5 \fi }
-    \__nicematrix_newcolumntype w [ 2 ] { \__nicematrix_w: { ##1 } { ##2 } }
-    \__nicematrix_newcolumntype W [ 2 ] { \__nicematrix_W: { ##1 } { ##2 } }
-    \@temptokena = { #2 }
-    \@tempswatrue
-    \@whilesw \if at tempswa \fi { \@tempswafalse \the \NC at list }
     \tl_gclear:N \g__nicematrix_preamble_tl
-    \exp_after:wN \__nicematrix_patch_m_preamble:n \the \@temptokena \q_stop
+    \__nicematrix_make_m_preamble:n #2 \q_stop
     \exp_args:NV \@mkpream \g__nicematrix_preamble_tl
     \@addtopreamble \@empty
     \endgroup
@@ -2754,31 +2734,39 @@
       { \int_gset_eq:NN \g__nicematrix_col_total_int \c at jCol }
     \ignorespaces
   }
-\cs_new_protected:Npn \__nicematrix_patch_m_preamble:n #1
+\cs_new_protected:Npn \__nicematrix_make_m_preamble:n #1
   {
     \str_case:nnF { #1 }
       {
-        c { \__nicematrix_patch_m_preamble_i:n #1 }
-        l { \__nicematrix_patch_m_preamble_i:n #1 }
-        r { \__nicematrix_patch_m_preamble_i:n #1 }
-        > { \__nicematrix_patch_m_preamble_ii:nn #1 }
-        ! { \__nicematrix_patch_m_preamble_ii:nn #1 }
-        @ { \__nicematrix_patch_m_preamble_ii:nn #1 }
-        | { \__nicematrix_patch_m_preamble_iii:n #1 }
-        p { \__nicematrix_patch_m_preamble_iv:nnn t #1 }
-        m { \__nicematrix_patch_m_preamble_iv:nnn c #1 }
-        b { \__nicematrix_patch_m_preamble_iv:nnn b #1 }
-        \__nicematrix_w: { \__nicematrix_patch_m_preamble_v:nnnn { } #1 }
-        \__nicematrix_W: { \__nicematrix_patch_m_preamble_v:nnnn { \__nicematrix_special_W: } #1 }
+        c { \__nicematrix_make_m_preamble_i:n #1 }
+        l { \__nicematrix_make_m_preamble_i:n #1 }
+        r { \__nicematrix_make_m_preamble_i:n #1 }
+        > { \__nicematrix_make_m_preamble_ii:nn #1 }
+        ! { \__nicematrix_make_m_preamble_ii:nn #1 }
+        @ { \__nicematrix_make_m_preamble_ii:nn #1 }
+        | { \__nicematrix_make_m_preamble_iii:n #1 }
+        p { \__nicematrix_make_m_preamble_iv:nnn t #1 }
+        m { \__nicematrix_make_m_preamble_iv:nnn c #1 }
+        b { \__nicematrix_make_m_preamble_iv:nnn b #1 }
+        w { \__nicematrix_make_m_preamble_v:nnnn { } #1 }
+        W { \__nicematrix_make_m_preamble_v:nnnn { \__nicematrix_special_W: } #1 }
         \q_stop { }
+        \NC at find { \__nicematrix_make_preamble:n }
       }
       {
-        \tl_if_eq:nnT { #1 } { S }
-          { \__nicematrix_fatal:n { unknown~column~type~S } }
-          { \__nicematrix_fatal:nn { unknown~column~type } { #1 } }
+        \cs_if_exist:cTF { NC @ find @ #1 }
+          {
+            \tl_set_eq:Nc \l_tmpa_tl { NC @ rewrite @ #1 }
+            \exp_last_unbraced:NV \__nicematrix_make_m_preamble:n \l_tmpa_tl
+          }
+          {
+            \tl_if_eq:nnT { #1 } { S }
+              { \__nicematrix_fatal:n { unknown~column~type~S } }
+              { \__nicematrix_fatal:nn { unknown~column~type } { #1 } }
+          }
       }
   }
-\cs_new_protected:Npn \__nicematrix_patch_m_preamble_i:n #1
+\cs_new_protected:Npn \__nicematrix_make_m_preamble_i:n #1
   {
     \tl_gput_right:Nn \g__nicematrix_preamble_tl
       {
@@ -2786,19 +2774,19 @@
         #1
         < \__nicematrix_cell_end:
       }
-    \__nicematrix_patch_m_preamble_x:n
+    \__nicematrix_make_m_preamble_x:n
   }
-\cs_new_protected:Npn \__nicematrix_patch_m_preamble_ii:nn #1 #2
+\cs_new_protected:Npn \__nicematrix_make_m_preamble_ii:nn #1 #2
   {
     \tl_gput_right:Nn \g__nicematrix_preamble_tl { #1 { #2 } }
-    \__nicematrix_patch_m_preamble:n
+    \__nicematrix_make_m_preamble:n
   }
-\cs_new_protected:Npn \__nicematrix_patch_m_preamble_iii:n #1
+\cs_new_protected:Npn \__nicematrix_make_m_preamble_iii:n #1
   {
     \tl_gput_right:Nn \g__nicematrix_preamble_tl { #1 }
-    \__nicematrix_patch_m_preamble:n
+    \__nicematrix_make_m_preamble:n
   }
-\cs_new_protected:Npn \__nicematrix_patch_m_preamble_iv:nnn #1 #2 #3
+\cs_new_protected:Npn \__nicematrix_make_m_preamble_iv:nnn #1 #2 #3
   {
     \tl_gput_right:Nn \g__nicematrix_preamble_tl
       {
@@ -2816,9 +2804,9 @@
             \__nicematrix_cell_end:
           }
       }
-    \__nicematrix_patch_m_preamble_x:n
+    \__nicematrix_make_m_preamble_x:n
   }
-\cs_new_protected:Npn \__nicematrix_patch_m_preamble_v:nnnn #1 #2 #3 #4
+\cs_new_protected:Npn \__nicematrix_make_m_preamble_v:nnnn #1 #2 #3 #4
   {
     \tl_gput_right:Nn \g__nicematrix_preamble_tl
       {
@@ -2838,18 +2826,18 @@
             \makebox [ #4 ] [ #3 ] { \box_use_drop:N \l__nicematrix_cell_box }
           }
       }
-    \__nicematrix_patch_m_preamble_x:n
+    \__nicematrix_make_m_preamble_x:n
   }
-\cs_new_protected:Npn \__nicematrix_patch_m_preamble_x:n #1
+\cs_new_protected:Npn \__nicematrix_make_m_preamble_x:n #1
   {
     \str_if_eq:nnTF { #1 } { < }
-      \__nicematrix_patch_m_preamble_ix:n
-      { \__nicematrix_patch_m_preamble:n { #1 } }
+      \__nicematrix_make_m_preamble_ix:n
+      { \__nicematrix_make_m_preamble:n { #1 } }
   }
-\cs_new_protected:Npn \__nicematrix_patch_m_preamble_ix:n #1
+\cs_new_protected:Npn \__nicematrix_make_m_preamble_ix:n #1
   {
     \tl_gput_right:Nn \g__nicematrix_preamble_tl { < { #1 } }
-    \__nicematrix_patch_m_preamble_x:n
+    \__nicematrix_make_m_preamble_x:n
   }
 \cs_new_protected:Npn \__nicematrix_put_box_in_flow:
   {
@@ -3133,7 +3121,7 @@
           \__nicematrix_analyze_end:Nn
           {
             \__nicematrix_transform_preamble:
-            \__nicematrix_array:V \g__nicematrix_preamble_tl
+            \__nicematrix_array:V \g__nicematrix_array_preamble_tl
           }
       }
   }
@@ -3183,7 +3171,7 @@
           { \l__nicematrix_nb_cols_int - 1 + \l__nicematrix_first_col_int }
       }
     \__nicematrix_transform_preamble:
-    \__nicematrix_array:V \g__nicematrix_preamble_tl \l__nicematrix_new_body_tl
+    \__nicematrix_array:V \g__nicematrix_array_preamble_tl \l__nicematrix_new_body_tl
   }
 \cs_new_protected:Npn \__nicematrix_line_with_light_syntax:n #1
   {
@@ -3604,20 +3592,8 @@
     \NiceArray { #2 }
   }
   { \endNiceArray }
-\cs_set_protected:Npn \__nicematrix_newcolumntype #1
-  {
-    \cs_if_free:cT { NC @ find @ #1 }
-      { \NC at list \expandafter { \the \NC at list \NC at do #1 } }
-    \cs_set:cpn {NC @ find @ #1 } ##1 #1 { \NC@ { ##1 } }
-    \peek_meaning:NTF [
-      { \newcol@ #1 }
-      { \newcol@ #1 [ 0 ] }
-  }
 \NewDocumentEnvironment { NiceTabularX } { m O { } m ! O { } }
   {
-    \IfPackageLoadedTF { tabularx }
-      { \newcolumntype { X } { \__nicematrix_X } }
-      { }
     \str_gset:Nn \g__nicematrix_name_env_str { NiceTabularX }
     \dim_zero_new:N \l__nicematrix_width_dim
     \dim_set:Nn \l__nicematrix_width_dim { #1 }
@@ -3625,7 +3601,11 @@
     \bool_set_true:N \l__nicematrix_tabular_bool
     \NiceArray { #3 }
   }
-  { \endNiceArray }
+  {
+    \endNiceArray
+    \int_compare:nNnT \g__nicematrix_total_X_weight_int = \c_zero_int
+      { \__nicematrix_error:n { NiceTabularX~without~X } }
+  }
 \NewDocumentEnvironment { NiceTabular* } { m O { } m ! O { } }
   {
     \str_gset:Nn \g__nicematrix_name_env_str { NiceTabular* }
@@ -3777,6 +3757,7 @@
     \cs_set_eq:NN \UnderBrace \__nicematrix_UnderBrace
     \cs_set_eq:NN \OverBrace \__nicematrix_OverBrace
     \cs_set_eq:NN \ShowCellNames \__nicematrix_ShowCellNames
+    \cs_set_eq:NN \TikzEveryCell \__nicematrix_TikzEveryCell
     \cs_set_eq:NN \line \__nicematrix_line
     \g__nicematrix_pre_code_after_tl
     \tl_gclear:N \g__nicematrix_pre_code_after_tl
@@ -5731,13 +5712,17 @@
     dotted .bool_set:N = \l__nicematrix_dotted_bool ,
     dotted .initial:n = false ,
     dotted .default:n = true ,
-    color .code:n = \__nicematrix_set_CT at arc@:n { #1 } ,
+    color .code:n =
+      \__nicematrix_set_CT at arc@:n { #1 }
+      \tl_set:Nn \l__nicematrix_rule_color_tl { #1 } ,
     color .value_required:n = true ,
     sep-color .code:n = \__nicematrix_set_CT at drsc@:n { #1 } ,
     sep-color .value_required:n = true ,
-    tikz .tl_set:N = \l__nicematrix_tikz_rule_tl ,
+    tikz .code:n =
+      \IfPackageLoadedTF { tikz }
+        { \clist_put_right:Nn \l__nicematrix_tikz_rule_tl { #1 } }
+        { \__nicematrix_error:n { tikz~without~tikz } } ,
     tikz .value_required:n = true ,
-    tikz .initial:n = ,
     total-width .dim_set:N = \l__nicematrix_rule_width_dim ,
     total-width .value_required:n = true ,
     width .meta:n = { total-width = #1 } ,
@@ -5816,6 +5801,7 @@
    }
 \cs_new_protected:Npn \__nicematrix_vline_ii:
   {
+    \tl_clear:N \l__nicematrix_tikz_rule_tl
     \keys_set:nV { NiceMatrix / RulesBis } \l__nicematrix_other_keys_tl
     \bool_if:NTF \l__nicematrix_dotted_bool
       \__nicematrix_vline_iv:
@@ -5899,6 +5885,10 @@
 \cs_new_protected:Npn \__nicematrix_vline_v:
   {
     \begin {tikzpicture }
+    % added 2023/09/25
+    \CT at arc@
+    \tl_if_empty:NF \l__nicematrix_rule_color_tl
+      { \tl_put_right:Nx \l__nicematrix_tikz_rule_tl { , color = \l__nicematrix_rule_color_tl } }
     \pgfrememberpicturepositiononpagetrue
     \pgf at relevantforpicturesizefalse
     \__nicematrix_qpoint:n { row - \int_use:N \l__nicematrix_local_start_int }
@@ -6003,6 +5993,7 @@
    }
 \cs_new_protected:Npn \__nicematrix_hline_ii:
   {
+    \tl_clear:N \l__nicematrix_tikz_rule_tl
     \keys_set:nV { NiceMatrix / RulesBis } \l__nicematrix_other_keys_tl
     \bool_if:NTF \l__nicematrix_dotted_bool
       \__nicematrix_hline_iv:
@@ -6100,6 +6091,10 @@
 \cs_new_protected:Npn \__nicematrix_hline_v:
   {
     \begin { tikzpicture }
+    % added 2023/09/25
+    \CT at arc@
+    \tl_if_empty:NF \l__nicematrix_rule_color_tl
+      { \tl_put_right:Nx \l__nicematrix_tikz_rule_tl { , color = \l__nicematrix_rule_color_tl } }
     \pgfrememberpicturepositiononpagetrue
     \pgf at relevantforpicturesizefalse
     \__nicematrix_qpoint:n { col - \int_use:N \l__nicematrix_local_start_int }
@@ -6197,7 +6192,7 @@
       {
         \IfPackageLoadedTF { tikz }
           { }
-          { \__nicematrix_error:n { tikz~in~custom-line~without~tikz }}
+          { \__nicematrix_error:n { tikz~in~custom-line~without~tikz } }
         \bool_if:NT \l__nicematrix_color_bool
           { \__nicematrix_error:n { color~in~custom-line~with~tikz } }
       }
@@ -6264,23 +6259,7 @@
   }
 \cs_new_protected:Npn \__nicematrix_h_custom_line:n #1
   {
-    \cs_set:cpn { nicematrix - \l__nicematrix_command_str }
-      {
-        \noalign
-          {
-            \__nicematrix_compute_rule_width:n { #1 }
-            \skip_vertical:n { \l__nicematrix_rule_width_dim }
-            \tl_gput_right:Nx \g__nicematrix_pre_code_after_tl
-              {
-                \__nicematrix_hline:n
-                  {
-                    #1 ,
-                    position = \int_eval:n { \c at iRow + 1 } ,
-                    total-width = \dim_use:N \l__nicematrix_rule_width_dim
-                  }
-              }
-          }
-      }
+    \cs_set:cpn { nicematrix - \l__nicematrix_command_str } { \Hline [ #1 ] }
     \seq_put_left:NV \l__nicematrix_custom_line_commands_seq \l__nicematrix_command_str
   }
 \cs_new_protected:Npn \__nicematrix_c_custom_line:n #1
@@ -6342,7 +6321,7 @@
 \cs_new_protected:Npn \__nicematrix_v_custom_line:n #1
   {
     \__nicematrix_compute_rule_width:n { #1 }
-    \tl_gput_right:Nx \g__nicematrix_preamble_tl
+    \tl_gput_right:Nx \g__nicematrix_array_preamble_tl
       { \exp_not:N ! { \skip_horizontal:n { \dim_use:N \l__nicematrix_rule_width_dim } } }
     \tl_gput_right:Nx \g__nicematrix_pre_code_after_tl
       {
@@ -6730,9 +6709,7 @@
               }
           }
       }
-    \cs_if_exist_use:NF
       \seq_map_pairwise_function:NNN
-      \seq_mapthread_function:NNN
       \g__nicematrix_multicolumn_cells_seq
       \g__nicematrix_multicolumn_sizes_seq
       \__nicematrix_node_for_multicolumn:nn
@@ -7691,7 +7668,7 @@
     borders .clist_set:N = \l__nicematrix_borders_clist ,
     rounded-corners .dim_set:N = \l__nicematrix_rounded_corners_dim ,
     rounded-corners .default:n = 4 pt ,
-    line-width .dim_set:N = \l__nicematrix_line_width_dim ,
+    line-width .dim_set:N = \l__nicematrix_line_width_dim
   }
 \cs_new_protected:Npn \__nicematrix_block_tikz:nnnnn #1 #2 #3 #4 #5
   {
@@ -7699,13 +7676,29 @@
     \__nicematrix_clip_with_rounded_corners:
     \clist_map_inline:nn { #5 }
       {
-        \path [ ##1 ]
-              ( #1 -| #2 )
+        \keys_set_known:nnN { NiceMatrix / SpecialOffset } { ##1 } \l_tmpa_tl
+        \use:x { \exp_not:N \path [ \l_tmpa_tl ] }
+              (
+                [
+                  xshift = \dim_use:N \l__nicematrix_offset_dim ,
+                  yshift = - \dim_use:N \l__nicematrix_offset_dim
+                ]
+                #1 -| #2
+              )
               rectangle
-              ( \int_eval:n { #3 + 1 } -| \int_eval:n { #4 + 1 } ) ;
+              (
+                [
+                  xshift = - \dim_use:N \l__nicematrix_offset_dim ,
+                  yshift = \dim_use:N \l__nicematrix_offset_dim
+                ]
+                \int_eval:n { #3 + 1 } -| \int_eval:n { #4 + 1 }
+              ) ;
       }
     \end { tikzpicture }
   }
+\cs_generate_variant:Nn \__nicematrix_block_tikz:nnnnn { n n n n V }
+\keys_define:nn { NiceMatrix / SpecialOffset }
+  { offset .dim_set:N = \l__nicematrix_offset_dim }
 \cs_set_protected:Npn \__nicematrix_renew_matrix:
   {
     \RenewDocumentEnvironment { pmatrix } { }
@@ -7726,7 +7719,7 @@
   }
 \keys_define:nn { NiceMatrix / Auto }
   {
-    columns-type .code:n = \__nicematrix_set_preamble:Nn \l__nicematrix_columns_type_tl { #1 } ,
+    columns-type .tl_set:N = \l__nicematrix_columns_type_tl ,
     columns-type .value_required:n = true ,
     l .meta:n = { columns-type = l } ,
     r .meta:n = { columns-type = r } ,
@@ -7747,7 +7740,7 @@
   {
     \group_begin:
     \keys_set_known:nnN { NiceMatrix / Auto } { #6 } \l_tmpa_tl
-    \bool_set_false:N \l__nicematrix_preamble_bool
+    % \bool_set_false:N \l__nicematrix_preamble_bool
     \use:x
       {
         \exp_not:N \begin { NiceArrayWithDelims } { #1 } { #2 }
@@ -7869,22 +7862,6 @@
       { }
     \endpgfpicture
   }
-\keys_define:nn { NiceMatrix }
-  {
-    CodeAfter / rules .inherit:n = NiceMatrix / rules ,
-    CodeAfter / sub-matrix .inherit:n = NiceMatrix / sub-matrix
-  }
-\keys_define:nn { NiceMatrix / CodeAfter }
-  {
-    sub-matrix .code:n = \keys_set:nn { NiceMatrix / sub-matrix } { #1 } ,
-    sub-matrix .value_required:n = true ,
-    delimiters / color .tl_set:N = \l__nicematrix_delimiters_color_tl ,
-    delimiters / color .value_required:n = true ,
-    rules .code:n = \keys_set:nn { NiceMatrix / rules } { #1 } ,
-    rules .value_required:n = true ,
-    xdots .code:n = \keys_set:nn { NiceMatrix / xdots } { #1 } ,
-    unknown .code:n = \__nicematrix_error:n { Unknown~key~for~CodeAfter }
-  }
 \cs_new:Npn \__nicematrix_CodeAfter: { \omit \__nicematrix_CodeAfter_ii:n }
 \cs_new_protected:Npn \__nicematrix_CodeAfter_i: { \\ \omit \__nicematrix_CodeAfter_ii:n }
 \cs_new_protected:Npn \__nicematrix_CodeAfter_ii:n #1 \end
@@ -7975,13 +7952,11 @@
     vlines .clist_set:N = \l__nicematrix_submatrix_vlines_clist ,
     vlines .default:n = all ,
     hvlines .meta:n = { hlines, vlines } ,
-    hvlines .value_forbidden:n = true ,
+    hvlines .value_forbidden:n = true
   }
 \keys_define:nn { NiceMatrix }
   {
     SubMatrix .inherit:n = NiceMatrix / sub-matrix ,
-    CodeAfter / sub-matrix .inherit:n = NiceMatrix / sub-matrix ,
-    NiceMatrix / sub-matrix .inherit:n = NiceMatrix / sub-matrix ,
     NiceArray / sub-matrix .inherit:n = NiceMatrix / sub-matrix ,
     pNiceArray / sub-matrix .inherit:n = NiceMatrix / sub-matrix ,
     NiceMatrixOptions / sub-matrix .inherit:n = NiceMatrix / sub-matrix ,
@@ -8534,6 +8509,99 @@
       { }
       { }
   }
+
+\bool_new:N \l__nicematrix_not_empty_bool
+\bool_new:N \l__nicematrix_empty_bool
+
+\keys_define:nn { NiceMatrix / TikzEveryCell }
+  {
+    not-empty .code:n =
+      \bool_lazy_or:nnTF
+        \l__nicematrix_in_code_after_bool
+        \g__nicematrix_recreate_cell_nodes_bool
+        { \bool_set_true:N \l__nicematrix_not_empty_bool }
+        { \__nicematrix_error:n { detection~of~empty~cells } } ,
+    not-empty .value_forbidden:n = true ,
+    empty .code:n =
+      \bool_lazy_or:nnTF
+        \l__nicematrix_in_code_after_bool
+        \g__nicematrix_recreate_cell_nodes_bool
+        { \bool_set_true:N \l__nicematrix_empty_bool }
+        { \__nicematrix_error:n { detection~of~empty~cells } } ,
+    empty .value_forbidden:n = true ,
+    unknown .code:n = \__nicematrix_error:n { Unknown~key~for~TikzEveryCell }
+  }
+
+\NewDocumentCommand { \__nicematrix_TikzEveryCell } { O { } m }
+  {
+    \IfPackageLoadedTF { tikz }
+      {
+        \group_begin:
+        \keys_set:nn { NiceMatrix / TikzEveryCell } { #1 }
+        \tl_set:Nn \l_tmpa_tl { #2 }
+        \seq_map_inline:Nn \g__nicematrix_pos_of_blocks_seq
+          { \__nicematrix_for_a_block:nnnnn ##1 }
+        \__nicematrix_all_the_cells:
+        \group_end:
+      }
+      { \__nicematrix_error:n { TikzEveryCell~without~tikz } }
+  }
+
+\tl_new:N \__nicematrix_i_tl
+\tl_new:N \__nicematrix_j_tl
+
+\cs_new_protected:Nn \__nicematrix_all_the_cells:
+  {
+    \int_step_variable:nNn { \int_use:c { c at iRow } } \__nicematrix_i_tl
+      {
+        \int_step_variable:nNn { \int_use:c { c at jCol } } \__nicematrix_j_tl
+          {
+            \cs_if_exist:cF { cell - \__nicematrix_i_tl - \__nicematrix_j_tl }
+              {
+                \exp_args:NNx \seq_if_in:NnF \l__nicematrix_corners_cells_seq
+                  { \__nicematrix_i_tl - \__nicematrix_j_tl }
+                  {
+                    \bool_set_false:N \l_tmpa_bool
+                    \cs_if_exist:cTF
+                      { pgf @ sh @ ns @ \__nicematrix_env: - \__nicematrix_i_tl - \__nicematrix_j_tl }
+                      {
+                        \bool_if:NF \l__nicematrix_empty_bool
+                          { \bool_set_true:N \l_tmpa_bool }
+                      }
+                      {
+                        \bool_if:NF \l__nicematrix_not_empty_bool
+                          { \bool_set_true:N \l_tmpa_bool }
+                      }
+                    \bool_if:NT \l_tmpa_bool
+                      {
+                        \__nicematrix_block_tikz:nnnnV
+                        \__nicematrix_i_tl \__nicematrix_j_tl \__nicematrix_i_tl \__nicematrix_j_tl \l_tmpa_tl
+                      }
+                  }
+              }
+          }
+      }
+  }
+
+\cs_new_protected:Nn \__nicematrix_for_a_block:nnnnn
+  {
+    \bool_if:NF \l__nicematrix_empty_bool
+      {
+        \__nicematrix_block_tikz:nnnnV
+          { #1 } { #2 } { #3 } { #4 } \l_tmpa_tl
+      }
+    \__nicematrix_mark_cells_of_block:nnnn { #1 } { #2 } { #3 } { #4 }
+  }
+
+\cs_new_protected:Nn \__nicematrix_mark_cells_of_block:nnnn
+  {
+    \int_step_inline:nnn { #1 } { #3 }
+      {
+        \int_step_inline:nnn { #2 } { #4 }
+          { \cs_set:cpn { cell - ##1 - ####1 } { } }
+      }
+  }
+
 \NewDocumentCommand \__nicematrix_ShowCellNames_CodeBefore { }
  {
    \dim_zero_new:N \g__nicematrix_tmpc_dim
@@ -8796,27 +8864,7 @@
               }
           }
       }
-      {
-        \IfPackageLoadedTF { tabularx }
-          {
-            \str_if_eq:VnTF \g__nicematrix_name_env_str { NiceTabularX }
-              {
-                \int_compare:nNnTF \c at iRow = \c_zero_int
-                  { \__nicematrix_fatal:n { X~columns~with~tabularx } }
-                  {
-                    \__nicematrix_fatal:nn { too~much~cols~for~array }
-                      {
-                        However,~this~message~may~be~erroneous:~
-                        maybe~you~have~used~X~columns~while~'tabularx'~is~loaded,~
-                        ~which~is~forbidden~(however,~it's~still~possible~to~use~
-                        X~columns~in~{NiceTabularX}).
-                      }
-                  }
-              }
-              { \__nicematrix_fatal:nn { too~much~cols~for~array } { } }
-          }
-          { \__nicematrix_fatal:nn { too~much~cols~for~array } { } }
-      }
+      { \__nicematrix_fatal:nn { too~much~cols~for~array } }
   }
 \cs_new:Npn \__nicematrix_message_hdotsfor:
   {
@@ -8870,17 +8918,9 @@
     ~you~try~to~use~more~columns~than~allowed~by~your~
     \__nicematrix_full_name_env:.\__nicematrix_message_hdotsfor:\ The~maximal~number~of~columns~is~
     \int_use:N \g__nicematrix_static_num_of_col_int\
-    ~(plus~the~potential~exterior~ones).~#1
+    ~(plus~the~potential~exterior~ones).
     This~error~is~fatal.
   }
-\__nicematrix_msg_new:nn { X~columns~with~tabularx }
-  {
-    There~is~a~problem.\\
-    You~have~probably~used~X~columns~in~your~environment~{\g__nicematrix_name_env_str}.~
-    That's~not~allowed~because~'tabularx'~is~loaded~(however,~you~can~use~X~columns~
-    in~an~environment~{NiceTabularX}).\\
-    This~error~is~fatal.
-  }
 \__nicematrix_msg_new:nn { columns~not~used }
   {
     Columns~not~used.\\
@@ -8964,6 +9004,13 @@
     There~is~only~two~keys~available~here:~width~and~color.\\
     Your~key~'\l_keys_key_str'~will~be~ignored.
   }
+\__nicematrix_msg_new:nn { Unknown~key~for~TikzEveryCell }
+  {
+    Unknown~key.\\
+    There~is~only~two~keys~available~here:~
+    'empty'~and~'not-empty'.\\
+    Your~key~'\l_keys_key_str'~will~be~ignored.
+  }
 \__nicematrix_msg_new:nn { Unknown~key~for~rotate }
   {
     Unknown~key.\\
@@ -9066,6 +9113,14 @@
     the~form~'line-i'.\\
     A~value~of~1~will~be~used.
   }
+\__nicematrix_msg_new:nn { detection~of~empty~cells }
+  {
+    Problem~with~'not-empty'\\
+    For~technical~reasons,~you~must~activate~
+    'recreate-cell-nodes'~in~\token_to_str:N \CodeBefore\
+    in~order~to~use~the~key~'\l_keys_key_str'.\\
+    That~key~will~be~ignored.
+  }
 \__nicematrix_msg_new:nn { ragged2e~not~loaded }
   {
     You~have~to~load~'ragged2e'~in~order~to~use~the~key~'\l_keys_key_str'~in~
@@ -9203,9 +9258,16 @@
       {~if~you~load~the~LaTeX~package~'tikz'}).\\
     This~specification~of~border~will~be~ignored.
   }
+\__nicematrix_msg_new:nn { TikzEveryCell~without~tikz }
+  {
+    TikZ~not~loaded.\\
+    You~can't~use~\token_to_str:N \TikzEveryCell\
+    because~you~have~not~loaded~tikz.~
+    This~command~will~be~ignored.
+  }
 \__nicematrix_msg_new:nn { tikz~key~without~tikz }
   {
-    Tikz~not~loaded.\\
+    TikZ~not~loaded.\\
     You~can't~use~the~key~'tikz'~for~the~command~'\token_to_str:N
     \Block'~because~you~have~not~loaded~tikz.~
     This~key~will~be~ignored.
@@ -9291,6 +9353,12 @@
     All~the~commands~\token_to_str:N\tabularnote\ will~be~
     ignored~in~the~document.
   }
+\__nicematrix_msg_new:nn { tikz~without~tikz }
+  {
+    Tikz~not~loaded.\\
+    You~can't~use~the~key~'tikz'~here~because~Tikz~is~not~
+    loaded.~If~you~go~on,~that~key~will~be~ignored.
+  }
 \__nicematrix_msg_new:nn { tikz~in~custom-line~without~tikz }
   {
     Tikz~not~loaded.\\
@@ -9735,6 +9803,12 @@
     You~can't~give~the~value~'auto'~to~the~key~'columns-width'~here.~
     That~key~will~be~ignored.
   }
+\__nicematrix_msg_new:nn { NiceTabularX~without~X }
+  {
+    NiceTabularX~without~X.\\
+    You~should~not~use~{NiceTabularX}~without~X~columns.\\
+    However,~you~can~go~on.
+  }
 
 \endinput
 %%



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