texlive[67019] Master/texmf-dist: piton (4may23)

commits+karl at tug.org commits+karl at tug.org
Thu May 4 22:30:12 CEST 2023


Revision: 67019
          http://tug.org/svn/texlive?view=revision&revision=67019
Author:   karl
Date:     2023-05-04 22:30:12 +0200 (Thu, 04 May 2023)
Log Message:
-----------
piton (4may23)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/lualatex/piton/README.md
    trunk/Master/texmf-dist/doc/lualatex/piton/piton-french.pdf
    trunk/Master/texmf-dist/doc/lualatex/piton/piton-french.tex
    trunk/Master/texmf-dist/doc/lualatex/piton/piton.pdf
    trunk/Master/texmf-dist/source/lualatex/piton/piton.dtx
    trunk/Master/texmf-dist/tex/lualatex/piton/piton.sty

Modified: trunk/Master/texmf-dist/doc/lualatex/piton/README.md
===================================================================
--- trunk/Master/texmf-dist/doc/lualatex/piton/README.md	2023-05-04 20:29:43 UTC (rev 67018)
+++ trunk/Master/texmf-dist/doc/lualatex/piton/README.md	2023-05-04 20:30:12 UTC (rev 67019)
@@ -4,6 +4,8 @@
 
 CTAN page: `https://ctan.org/pkg/piton`
 
+GitHub page: `github.com/fpantigny/piton`
+
 ## License
 The LaTeX extension `piton` is distributed under the LPPL 1.3 license.
 

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

Modified: trunk/Master/texmf-dist/doc/lualatex/piton/piton-french.tex
===================================================================
--- trunk/Master/texmf-dist/doc/lualatex/piton/piton-french.tex	2023-05-04 20:29:43 UTC (rev 67018)
+++ trunk/Master/texmf-dist/doc/lualatex/piton/piton-french.tex	2023-05-04 20:30:12 UTC (rev 67019)
@@ -185,7 +185,7 @@
 \begin{itemize}
 \item {\color{blue} \textsf{Syntaxe} \verb|\piton{...}|}\par\nobreak
 
-Quant son argument est donné entre accolades, la commande |\piton| ne prend pas son argument en mode verbatim. Les
+Quand son argument est donné entre accolades, la commande |\piton| ne prend pas son argument en mode verbatim. Les
 points suivants doivent être remarqués :
 
 \begin{itemize}
@@ -201,8 +201,9 @@
 
 {\color{cyan} mais les commandes |\{| et |\}| sont aussi fournies pour insérer des accolades individuelles} ;
 
-\item les commandes LaTeX\footnote{Cela s'applique aux commandes commençant par une contre-oblique |\| mais également aux caractères actifs.} sont
-complètement développées sans être exécutées 
+\item les commandes LaTeX\footnote{Cela s'applique aux commandes commençant par une contre-oblique |\| mais
+  également aux caractères actifs, c'est-à-dire ceux de catcode~13.} sont complètement développées sans être
+exécutées
 
 {\color{cyan} et on peut donc utiliser |\\| pour insérer une contre-oblique}.
 \end{itemize}
@@ -306,21 +307,34 @@
 poursuivre la numérotation d'un environnement à l'autre.
 
 \item La clé \Definition{background-color} fixe la couleur de fond des environnements |{Piton}| et des listings
-produits par |\PitonInputFile| (ce fond a une largeur égale à la valeur courante de |\linewidth|). La clé
-|background-color| accepte une couleur définie «à la volée», c'est-à-dire que l'on peut écrire par exemple
+produits par |\PitonInputFile| (ce fond a une largeur que l'on peut fixer avec la clé |width| décrite ci-dessous).
+La clé |background-color| accepte une couleur définie «à la volée», c'est-à-dire que l'on peut écrire par exemple
 |background-color = [cmyk]{0.1,0.05,0,0}|
 
 \smallskip
-\colorbox{yellow!50}{\textbf{Nouveau 1.4}}\enskip La clé |background-color| accepte aussi en argument une
-\emph{liste} de couleurs. Les lignes sont alors coloriées de manière cyclique avec ces couleurs.
+La clé |background-color| accepte aussi en argument une \emph{liste} de couleurs. Les lignes sont alors coloriées
+de manière cyclique avec ces couleurs.
 
 \emph{Exemple} : |\PitonOptions{background-color = {gray!5,white}}|
 
 \item Avec la clé \Definition{prompt-background-color}, \pkg{piton} ajoute un fond coloré aux lignes débutant par
 le prompt «|>>>|» (et sa continuation «|...|») caractéristique des consoles Python avec boucle \textsc{repl}
-(\emph{read-only-eval loop}). Pour un exemple d'utilisation de cette clé, voir la partie \ref{pythonrepl}
+(\emph{read-eval-print loop}). Pour un exemple d'utilisation de cette clé, voir la partie \ref{pythonrepl}
 p.~\pageref{pythonrepl}.
 
+\item \colorbox{yellow!50}{\textbf{Nouveau 1.6}}\enskip La clé \Definition{width} fixe la largeur du listing
+produit. Cette largeur s'applique aux fonds colorés spécifiés par les clés |background-color| et
+|prompt-background-color| et également quand une coupure automatique des lignes est demandée par |break-lines|
+(cf.~\ref{line-breaks}, p.~\pageref{line-breaks}). 
+
+Cette clé peut prendre comme valeur une longueur explicite mais aussi la valeur spéciale~|min|. Avec cette valeur,
+la largeur sera calculée à partir de la largeur maximale des lignes de code. Attention : l'usage de cette valeur
+spéciale~|min| requiert deux compilations LuaLaTeX\footnote{La largeur maximale est calculée lors de la première
+compilation, écrite sur le fichier~|aux|, puis réutilisée lors de la compilation suivante. Certains outils comme
+|latexmk| (utilisé par Overleaf) effectuent automatiquement un nombre suffisant de compilations.}.
+
+Pour un exemple d'utilisation de |width=min|, voir la partie~\ref{example-comments} sur les exemples, p.~\pageref{example-comments}.
+
 \item En activant la clé \Definition{show-spaces-in-strings}, les espaces dans les chaînes courtes (c'est-à-dire
 celles délimitées par |'| ou |"|) sont matérialisés par le caractère ␣ (U+2423 : \textsc{open box}). Bien sûr, le
 caractère U+2423 doit être présent dans la fonte mono-chasse utilisée.\footnote{L'extension \pkg{piton} utilise
@@ -480,8 +494,8 @@
 \end{table}
 
 \bigskip
-\colorbox{yellow!50}{\textbf{Nouveau 1.4}}\enskip La commande |\PitonStyle| prend en argument le nom d'un style
-et permet de récupérer la valeur (en tant que liste d'instructions LaTeX) de ce style.
+La commande |\PitonStyle| prend en argument le nom d'un style et permet de récupérer la valeur (en tant que liste
+d'instructions LaTeX) de ce style.
 
 \smallskip
 Par exemple, on peut écrire, dans le texte courant, |{\PitonStyle{Keyword}{function}}| et on aura 
@@ -492,6 +506,53 @@
 semi-globales et des commandes à argument présentes dans la valeur courante du style \texttt{\textsl{style}}.
 
 
+\vspace{1cm} \colorbox{yellow!50}{\textbf{Nouveau 1.6}}\par\nobreak
+
+Il existe un style spécial nommé |UserFunction|. Ce style s'applique aux noms des fonctions précédemment définies
+par l'utilisateur via une instruction Python \piton{def} dans l'un des listings précédents. La valeur initiale de
+ce style est nulle (=vide), ce qui fait que ces noms de fonctions sont formatés comme du texte courant (en noir).
+Néanmoins, il est possible de ce changer la valeur de ce style, comme tous les autres styles, avec la commande
+|\PitonSetStyle|.
+
+
+\medskip
+Dans l'exemple suivant, on prend comme valeur de ce style |UserFunction| la valeur initiale du style
+|Name.Function| (qui s'applique au nom des fonctions \emph{au moment de leur définition}).
+
+\begingroup
+
+\begin{Verbatim}
+\PitonSetStyle{~emphase#UserFunction@ = \color[HTML]{CC00FF}}
+\end{Verbatim}
+
+\SetPitonStyle{UserFunction = \color[HTML]{CC00FF}}
+
+\begin{Piton}
+def transpose(v,i,j):
+    x = v[i]
+    v[i] = v[j]
+    v[j] = x 
+
+def passe(v):
+    for in in range(0,len(v)-1):
+        if v[i] > v[i+1]:
+            transpose(v,i,i+1)
+\end{Piton}
+
+\endgroup
+
+\medskip
+Comme on le voit, le nom |transpose| a été mis en évidence comme étant le nom d'une fonction définie précédemment
+par l'utilisateur (d'où le nom |UserFunction| pour ce style).
+
+\PitonClearUserFunctions
+
+\bigskip
+Bien sûr, la liste des noms de fonctions Python précédemment définies est gardée en mémoire de LuaLaTeX (de manière
+globale, c'est-à-dire indépendamment des groupes TeX). L'extension \pkg{piton} fournit une commande pour permet de
+vider cette liste : c'est la commande |\PitonClearUserFunctions|.
+
+
 \subsection{Définition de nouveaux environnements}
 
 \label{NewPitonEnvironment}
@@ -553,8 +614,6 @@
 
 \subsection{Mise en évidence d'identificateurs}
 
-\colorbox{yellow!50}{\textbf{Nouveau 1.4}}
-
 On peut demander le changement de formatage de certains identificateurs avec la clé |identifiers| de
 |\PitonOptions|.  
 
@@ -727,7 +786,7 @@
 
 
 \bigskip 
-Si l'utilisateur a demandé l'affichage des numéros de ligne (avec |line-numbers| ou |all-line-numbers|), il est
+Si l'utilisateur a demandé l'affichage des numéros de ligne avec |line-numbers| ou |all-line-numbers|, il est
 possible de faire référence à ce numéro de ligne avec la commande |\label| placée dans un commentaire
 LaTeX.\footnote{Cette fonctionnalité est implémentée en redéfinissant, dans les environnements |{Piton}|, la
   commande |\label|. Il peut donc y avoir des incompatibilités avec les extensions qui redéfinissent (globalement)
@@ -854,9 +913,10 @@
 
 \emph{Première remarque}\par\nobreak
 Remarquons que, comme l'environnement |{Piton}| prend son argument selon un mode verbatim, il convient, ce qui
-n'est pas surprenant, de l'utiliser dans des environnements |{frame}| de Beamer protégés par la clé |fragile|.\footnote{On
-  rappelle que pour un environnement |{frame}| de Beamer qui utilise la clé |fragile|, l'instruction |\end{frame}|
-  doit être seule sur une ligne (à l'exception d'éventuels espaces en début de ligne).}
+n'est pas surprenant, de l'utiliser dans des environnements |{frame}| de Beamer protégés par la clé |fragile|,
+c'est-à-dire avec |\begin{frame}[fragile]|.\footnote{On rappelle que pour un environnement |{frame}| de Beamer qui
+  utilise la clé |fragile|, l'instruction |\end{frame}| doit être seule sur une ligne (à l'exception d'éventuels
+  espaces en début de ligne).}
 
 
 \medskip
@@ -1046,7 +1106,7 @@
 (mais pas dans la commande \verb+\piton|...|+, c'est-à-dire avec la syntaxe verbatim). 
 
 \item Avec la clé |break-lines-in-Piton|, les coupures de ligne sont autorisées dans l'environnement |{Piton}|
-(d'où la lettre |P| capitale dans le nom) et dans les listings produits par |\PitonInputFile|.
+(d'où la lettre |P| capitale dans le nom) et les listings produits par |\PitonInputFile|.
 
 \item La clé |break-lines| est la conjonction des deux clés précédentes.
 \end{itemize}
@@ -1069,15 +1129,14 @@
 \end{itemize}
 
 \bigskip
-Le code suivant a été composé dans une |{minipage}| standard de LaTeX de largeur 12~cm avec le réglage suivant :  
+Le code suivant a été composé avec le réglage suivant :  
 
 \begin{Verbatim}
-\PitonOptions{break-lines,indent-broken-lines,background-color=gray!15}
+\PitonOptions{width=12cm,break-lines,indent-broken-lines,background-color=gray!15}
 \end{Verbatim}
 
 \begin{center}
-\PitonOptions{break-lines,indent-broken-lines,background-color=gray!15}
-\begin{minipage}{12cm}
+\PitonOptions{width=12cm,break-lines,indent-broken-lines,background-color=gray!15}
 \begin{Piton}
 def dict_of_liste(liste):
     """Convertit une liste de subrs et de descriptions de glyphes en dictionnaire"""
@@ -1092,7 +1151,6 @@
         dict[nom] = [traite_ligne_Postscript(k) for k in liste_lettre[1:-1]]
     return dict
 \end{Piton}
-\end{minipage}
 \end{center}
 
 
@@ -1233,16 +1291,16 @@
 
 \vspace{1cm}
 On peut aussi faire afficher les commentaires dans une deuxième colonne à droite si on limite la largeur du code
-proprement dit avec un environnement |{minipage}| de LaTeX.
+proprement dit avec la clé |width|. Dans l'exemple qui suit, on utilise la clé |width| avec la valeur
+spéciale~|min|. 
 
 
 \begingroup
 \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
 \begin{Verbatim}
-\PitonOptions{background-color=gray!10}
+\PitonOptions{width=min, background-color=gray!10}
 ~emphase&\NewDocumentCommand{\MyLaTeXCommand}{m}{\hfill \normalfont\itshape\rlap{\quad #1}}@
 ~emphase&\SetPitonStyle{Comment.LaTeX = \MyLaTeXCommand}@
-~emphase&\begin{minipage}{12cm}@
 \begin{Piton}
 def arctan(x,n=10):
     if x < 0:
@@ -1255,7 +1313,6 @@
              s += (-1)**k/(2*k+1)*x**(2*k+1)
         return s 
 \end{Piton}
-~emphase&\end{minipage}@
 \end{Verbatim}
 \endgroup
 
@@ -1262,10 +1319,9 @@
 
 
 \begingroup
-\PitonOptions{background-color=gray!10}
+\PitonOptions{width = min, background-color=gray!10}
 \NewDocumentCommand{\MyLaTeXCommand}{m}{\hfill \normalfont\itshape\rlap{\quad #1}}
 \SetPitonStyle{Comment.LaTeX = \MyLaTeXCommand}
-\begin{minipage}{12cm}
 \begin{Piton}
 def arctan(x,n=10):
     if x < 0:
@@ -1278,7 +1334,6 @@
              s += (-1)**k/(2*k+1)*x**(2*k+1)
         return s 
 \end{Piton}
-\end{minipage}
 \endgroup
 
 \bigskip
@@ -1363,48 +1418,6 @@
 \endgroup
 
 
-\vspace{1cm}
-Si on encapsule l'environnement |{Piton}| dans un environnement |{minipage}| pour, typiquement, limiter la largeur
-d'un fond coloré, il faut encadrer l'ensemble dans un environnement |{savenotes}| (de \pkg{footnote} ou
-\pkg{footnotehyper}) si on veut avoir les notes reportées en pied de page.
-
-\begingroup
-\fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
-\begin{Verbatim}
-\PitonOptions{background-color=gray!10}
-~emphase&\begin{savenotes}@
-\begin{minipage}{13cm}
-\begin{Piton}
-def arctan(x,n=10):
-    if x < 0:
-        return -arctan(-x)~emphase&#>\footnote{Un premier appel récursif.}@
-    elif x > 1: 
-        return pi/2 - arctan(1/x)~emphase&#>\footnote{Un deuxième appel récursif.}@
-    else: 
-        return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
-\end{Piton}
-\end{minipage}
-~emphase&\end{savenotes}@
-\end{Verbatim}
-\endgroup
-
-
-
-\begin{savenotes}
-\PitonOptions{background-color=gray!10}
-\begin{minipage}{13cm}
-\begin{Piton}
-def arctan(x,n=10):
-    if x < 0:
-        return -arctan(-x)#>\footnote{Un premier appel récursif.}
-    elif x > 1: 
-        return pi/2 - arctan(1/x)#>\footnote{Un deuxième appel récursif.}
-    else: 
-        return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
-\end{Piton}
-\end{minipage}
-\end{savenotes}
-
 \bigskip
 
 \subsection{Un exemple de réglage des styles}
@@ -1595,7 +1608,8 @@
 \NewDocumentEnvironment { PitonREPL } { ! O { } } % le ! est obligatoire
  { 
    \PitonOptions
-     { background-color=white,
+     { 
+       background-color=white,
        ~emphase#prompt-background-color = gray!10@,
        ~#1
      }
@@ -1743,7 +1757,11 @@
 \nolinkurl{https://tug.org/svn/texlive/trunk/Master/texmf-dist/tex/lualatex/piton/piton.sty}
 }
 
+\medskip
+Le développement de l'extension \pkg{piton} se fait sur le dépôt GitHub suivant :
 
+\smallskip
+\verb|https://github.com/fpantigny/piton|
 
 \tableofcontents
 

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

Modified: trunk/Master/texmf-dist/source/lualatex/piton/piton.dtx
===================================================================
--- trunk/Master/texmf-dist/source/lualatex/piton/piton.dtx	2023-05-04 20:29:43 UTC (rev 67018)
+++ trunk/Master/texmf-dist/source/lualatex/piton/piton.dtx	2023-05-04 20:30:12 UTC (rev 67019)
@@ -15,8 +15,8 @@
 %
 % \fi
 % \iffalse
-\def\myfileversion{1.5a}
-\def\myfiledate{2023/04/11}
+\def\myfileversion{1.6}
+\def\myfiledate{2023/05/03}
 %
 %
 %<*batchfile> 
@@ -205,8 +205,8 @@
 % {\color{cyan} but the commands |\{| and |\}| are also provided for individual braces};
 %
 % \item the LaTeX commands\footnote{That concerns the commands beginning with a
-% backslash but also the active characters.} are fully expanded and not
-% executed,
+% backslash but also the active characters (with catcode equal to 13).} are
+% fully expanded and not executed,
 %
 % {\color{cyan} so it's possible to use |\\| to insert a backslash}.
 % \end{itemize}
@@ -325,17 +325,17 @@
 % example part \ref{example-numbering} on page~\pageref{example-numbering}.
 %
 % \item The key \Definition{background-color} sets the background color of the
-% environments |{Piton}| and the listings produced by |\PitonInputFile| (that
-% background has a width of |\linewidth|).
+% environments |{Piton}| and the listings produced by |\PitonInputFile| (it's
+% possible to fix the width of that background with the key |width| described
+% below). 
 %
 % \smallskip
-% \colorbox{yellow!50}{\textbf{New 1.4}}\enskip The key |background-color|
-% supports also as value a \emph{list} of colors. In this case, the successive
-% rows are colored by using the colors of the list in a cyclic way.
+% The key |background-color| supports also as value a \emph{list} of colors. In
+% this case, the successive rows are colored by using the colors of the list in
+% a cyclic way.
 %
 % \emph{Example} : |\PitonOptions{background-color = {gray!5,white}}|
 %
-%
 % The key |background-color| accepts a color defined «on the fly». For example,
 % it's possible to write |background-color = [cmyk]{0.1,0.05,0,0}|.
 %
@@ -344,6 +344,24 @@
 % continuation ``|...|'') characteristic of the Python consoles with
 % \textsc{repl} (\emph{read-eval-print loop}).
 %
+% \item \colorbox{yellow!50}{\textbf{New 1.6}}\enskip The key |width| will fix
+% the width of the listing. That width applies to the colored backgrounds 
+% specified by |background-color| and |prompt-background-color| but also for the
+% automatic breaking of the lines (when required by |break-lines|:
+% cf.~\ref{line-breaks}, p.~\pageref{line-breaks}).
+%
+% That key may take in as value a numeric value but also the special
+% value~|min|. With that value, the width will be computed from the maximal
+% width of the lines of code. Caution: the special value~|min| requires two
+% compilations with LuaLaTeX\footnote{The maximal width is computed during the
+% first compilation, written on the |aux| file and re-used during the second
+% compilation. Several tools such as |latexmk| (used by Overleaf) do
+% automatically a sufficient number of compilations.}.
+%
+% For an example of use of |width=min|, see the section~\ref{example-comments},
+% p.~\pageref{example-comments}. 
+%
+%
 % \item When the key \Definition{show-spaces-in-strings} is activated, the
 % spaces in the short strings (that is to say those delimited by |'| or |"|) are
 % replaced by the character~␣ (U+2423 : \textsc{open box}). Of course, that
@@ -464,9 +482,8 @@
 % \url{https://pygments.org/styles/}. Remark that, by default, Pygments provides for its style \pkg{manni} a colored background whose color is the HTML color \texttt{\#F0F3F3}. It's possible to have the same color in \texttt{\{Pion\}} with the instruction \texttt{\textbackslash PitonOptions\{background-color = [HTML]\{F0F3F3\}\}}.}
 %
 % \bigskip
-% \colorbox{yellow!50}{\textbf{New 1.4}}\enskip The command |\PitonStyle| takes
-% in as argument the name of a style and allows to retrieve the value (as a list
-% of LaTeX instructions) of that style.
+% The command |\PitonStyle| takes in as argument the name of a style and allows
+% to retrieve the value (as a list of LaTeX instructions) of that style.
 %
 % \smallskip
 % For example, it's possible to write |{\PitonStyle{Keyword}{function}}| and we
@@ -521,7 +538,53 @@
 % \end{table}
 %
 %
+% \vspace{1cm} \colorbox{yellow!50}{\textbf{New 1.6}}\par\nobreak
 %
+% The extension \pkg{piton} provides a special style called~|UserFunction|. That
+% style applies to the names of the functions previously defined by the user via
+% an instruction Python \piton{def} in one of the previous listings. The initial
+% value of that style is empty, and, therefore, the names of the functions are
+% formatted as standard text (in black). However, it's possible to change the
+% value of that style, as any other style, with the command |\PitonSetStyle|.
+%
+% \medskip
+% In the following example, we fix as value for that style |UserFunction| the
+% initial value of the the style |Name.Function| (which applies to the name of
+% the functions, \emph{at the moment of their definition}).
+%
+% \begingroup
+%
+% \begin{Verbatim}
+% \PitonSetStyle{~emphase#UserFunction@ = \color[HTML]{CC00FF}}
+% \end{Verbatim}
+%
+% \SetPitonStyle{UserFunction = \color[HTML]{CC00FF}}
+%
+% \begin{Piton}
+% def transpose(v,i,j):
+%     x = v[i]
+%     v[i] = v[j]
+%     v[j] = x 
+%
+% def passe(v):
+%     for in in range(0,len(v)-1):
+%         if v[i] > v[i+1]:
+%             transpose(v,i,i+1)
+% \end{Piton}
+%
+% \endgroup
+%
+% As one see, the name |transpse| has been highlighted because it's the name of
+% a Python function previously defined by the user (hence the name
+% |UserFunction| for that style).
+%
+% \PitonClearUserFunctions
+%
+% \bigskip
+% Of course, the list of the names of Python functions previously défined is
+% kept in the memory of LuaLaTeX (in a global way, that is to say independtly of
+% the TeX groups). The extension \pkg{piton} provides a command to clear that
+% list : it's the command |\PitonClearUserFunctions|.
 % 
 % \subsection{Creation of new environments}
 %
@@ -588,9 +651,8 @@
 %
 % \subsection{Highlighting some identifiers}
 %
-% \colorbox{yellow!50}{\textbf{New 1.4}} It's possible to require a changement
-% of formating for some identifiers with the key |identifiers| of
-% |\PitonOptions|.
+% It's possible to require a changement of formating for some identifiers with
+% the key |identifiers| of |\PitonOptions|.
 %
 % \smallskip
 % That key takes in as argument a value of the following format:
@@ -894,12 +956,13 @@
 % \label{beamer}
 %
 % \emph{First remark}\par\nobreak
-% Since the environment |{Piton}| catches its body with a verbatim mode,
-% it's necessary to use the environments |{Piton}| within environments |{frame}|
-% of Beamer protected by the key |fragile|.\footnote{Remind that for an
-% environment \texttt{\{frame\}} of Beamer using the key |fragile|, the
-% instruction \texttt{\textbackslash end\{frame\}} must be alone on a single
-% line (except for any leading whitespace).}
+% Since the environment |{Piton}| catches its body with a verbatim mode, it's
+% necessary to use the environments |{Piton}| within environments |{frame}| of
+% Beamer protected by the key |fragile|, i.e. with
+% |\begin{frame}[fragile]|.\footnote{Remind that for an environment
+% \texttt{\{frame\}} of Beamer using the key |fragile|, the instruction
+% \texttt{\textbackslash end\{frame\}} must be alone on a single line (except
+% for any leading whitespace).}
 %
 %
 % \bigskip
@@ -1123,16 +1186,14 @@
 %
 %
 % \bigskip
-% The following code has been composed in a standard LaTeX |{minipage}| of width
-% 12~cm with the following tuning:
+% The following code has been composed with the following tuning:
 %
 % \begin{Verbatim}
-% \PitonOptions{break-lines,indent-broken-lines,background-color=gray!15}
+% \PitonOptions{width=12cm,break-lines,indent-broken-lines,background-color=gray!15}
 % \end{Verbatim}
 %
 % \begin{center}
-% \PitonOptions{break-lines,indent-broken-lines,background-color=gray!15}
-% \begin{minipage}{12cm}
+% \PitonOptions{width=12cm,break-lines,indent-broken-lines,background-color=gray!15}
 % \begin{Piton}
 % def dict_of_list(l):
 %     """Converts a list of subrs and descriptions of glyphs in a dictionary"""
@@ -1147,7 +1208,6 @@
 %         our_dict[name] = [treat_Postscript_line(k) for k in list_letter[1:-1]]
 %     return dict
 % \end{Piton}
-% \end{minipage}
 % \end{center}
 % 
 % \subsection{Footnotes in the environments of piton}
@@ -1225,9 +1285,9 @@
 % \begin{Piton}
 % def arctan(x,n=10):
 %     if x < 0:
-%         return -arctan(-x)        #> (appel récursif)
+%         return -arctan(-x)        #> (recursive call)
 %     elif x > 1: 
-%         return pi/2 - arctan(1/x) #> (autre appel récursif) 
+%         return pi/2 - arctan(1/x) #> (other recursive call) 
 %     else: 
 %         return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
 % \end{Piton}
@@ -1241,9 +1301,9 @@
 % \begin{Piton}
 % def arctan(x,n=10):
 %     if x < 0:
-%         return -arctan(-x)        #> (appel récursif)
+%         return -arctan(-x)        #> (recursive call)
 %     elif x > 1: 
-%         return pi/2 - arctan(1/x) #> (autre appel récursif) 
+%         return pi/2 - arctan(1/x) #> (other recursive call) 
 %     else: 
 %         return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
 % \end{Piton}
@@ -1269,9 +1329,9 @@
 % \begin{Piton}
 % def arctan(x,n=10):
 %     if x < 0:
-%         return -arctan(-x)        #> appel récursif
+%         return -arctan(-x)        #> recursive call
 %     elif x > 1: 
-%         return pi/2 - arctan(1/x) #> autre appel récursif 
+%         return pi/2 - arctan(1/x) #> other recursive call 
 %     else: 
 %         return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
 % \end{Piton}
@@ -1284,9 +1344,9 @@
 % \begin{Piton}
 % def arctan(x,n=10):
 %     if x < 0:
-%         return -arctan(-x)        #> appel récursif
+%         return -arctan(-x)        #> recursive call
 %     elif x > 1: 
-%         return pi/2 - arctan(1/x) #> autre appel récursif 
+%         return pi/2 - arctan(1/x) #> another recursive call 
 %     else: 
 %         return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
 % \end{Piton}
@@ -1295,22 +1355,22 @@
 %
 % \vspace{1cm}
 % It's also possible to display these LaTeX comments in a kind of second column
-% by limiting the width of the Python code by an environment |{minipage}| of LaTeX.
+% by limiting the width of the Python code with the key |width|. In the
+% following example, we use the key |width| with the special value~|min|.
 %
 %
 % \begingroup
 % \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
 % \begin{Verbatim}
-% \PitonOptions{background-color=gray!10}
+% \PitonOptions{background-color=gray!10, width=min}
 % ~emphase&\NewDocumentCommand{\MyLaTeXCommand}{m}{\hfill \normalfont\itshape\rlap{\quad #1}}@
 % ~emphase&\SetPitonStyle{Comment.LaTeX = \MyLaTeXCommand}@
-% ~emphase&\begin{minipage}{12cm}@
 % \begin{Piton}
 % def arctan(x,n=10):
 %     if x < 0:
-%         return -arctan(-x)       #> appel récursif
+%         return -arctan(-x) #> recursive call
 %     elif x > 1: 
-%         return pi/2 - arctan(1/x) #> autre appel récursif 
+%         return pi/2 - arctan(1/x) #> anoother recursive call 
 %     else: 
 %         s = 0
 %         for k in range(n):
@@ -1317,7 +1377,6 @@
 %              s += (-1)**k/(2*k+1)*x**(2*k+1)
 %         return s 
 % \end{Piton}
-% ~emphase&\end{minipage}@
 % \end{Verbatim}
 % \endgroup
 %
@@ -1324,16 +1383,15 @@
 %
 %
 % \begingroup
-% \PitonOptions{background-color=gray!10}
+% \PitonOptions{background-color=gray!10, width=min}
 % \NewDocumentCommand{\MyLaTeXCommand}{m}{\hfill \normalfont\itshape\rlap{\quad #1}}
 % \SetPitonStyle{Comment.LaTeX = \MyLaTeXCommand}
-% \begin{minipage}{12cm}
 % \begin{Piton}
 % def arctan(x,n=10):
 %     if x < 0:
-%         return -arctan(-x)       #> appel récursif
+%         return -arctan(-x) #> recursive call
 %     elif x > 1: 
-%         return pi/2 - arctan(1/x) #> autre appel récursif 
+%         return pi/2 - arctan(1/x) #> another recursive call 
 %     else: 
 %         s = 0
 %         for k in range(n):
@@ -1340,7 +1398,6 @@
 %              s += (-1)**k/(2*k+1)*x**(2*k+1)
 %         return s 
 % \end{Piton}
-% \end{minipage}
 % \endgroup
 %
 %
@@ -1432,50 +1489,7 @@
 % \endgroup
 %
 %
-% \vspace{1cm}
-% If we embed an environment |{Piton}| in an environment |{minipage}|
-% (typically in order to limit the width of a colored background), it's
-% necessary to embed the whole environment |{minipage}| in an environment
-% |{savenotes}| (of \pkg{footnote} or \pkg{footnotehyper}) in order to have the
-% footnotes composed at the bottom of the page. 
 %
-% \begingroup
-% \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
-% \begin{Verbatim}
-% \PitonOptions{background-color=gray!10}
-% ~emphase&\begin{savenotes}@
-% \begin{minipage}{13cm}
-% \begin{Piton}
-% def arctan(x,n=10):
-%     if x < 0:
-%         return -arctan(-x)~emphase&#>\footnote{First recursive call.}@
-%     elif x > 1: 
-%         return pi/2 - arctan(1/x)~emphase&#>\footnote{Second recursive call.}@
-%     else: 
-%         return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
-% \end{Piton}
-% \end{minipage}
-% ~emphase&\end{savenotes}@
-% \end{Verbatim}
-% \endgroup
-%
-%
-%
-% \begin{savenotes}
-% \PitonOptions{background-color=gray!10}
-% \begin{minipage}{13cm}
-% \begin{Piton}
-% def arctan(x,n=10):
-%     if x < 0:
-%         return -arctan(-x)#>\footnote{First recursive call.}
-%     elif x > 1: 
-%         return pi/2 - arctan(1/x)#>\footnote{Second recursive call.}
-%     else: 
-%         return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
-% \end{Piton}
-% \end{minipage}
-% \end{savenotes}
-%
 % \bigskip
 %
 % \subsection{An example of tuning of the styles}
@@ -1551,7 +1565,7 @@
 %     n is the number of terms in the sum
 %     """
 %     if x < 0:
-%         return -arctan(-x) # appel récursif
+%         return -arctan(-x) # recursive call
 %     elif x > 1: 
 %         return pi/2 - arctan(1/x) 
 %         #> (we have used that $\arctan(x)+\arctan(1/x)=\pi/2$ for $x>0$)
@@ -1631,6 +1645,12 @@
 %
 % \section{Implementation}
 %
+% % \medskip
+% The development of the extension \pkg{piton} is done on the following GitHub
+% depot:
+%
+% \verb|https://github.com/fpantigny/piton|
+%
 % \subsection{Introduction}
 % 
 % The main job of the package \pkg{piton} is to take in as input a Python
@@ -2021,20 +2041,6 @@
 \tl_new:N \l_@@_prompt_bg_color_tl
 %    \end{macrocode}
 % 
-% \medskip
-% We will compute the maximal width of the lines of an environment |{Piton}| in
-% |\g_@@_width_dim|. We need a global variable because, when the key |footnote|
-% is in force, each line when be composed in an environment |{savenotes}| and
-% (when |slim| is in force) we need to exit |\g_@@_width_dim| from that
-% environment.
-%    \begin{macrocode}
-\dim_new:N \g_@@_width_dim 
-%    \end{macrocode}
-% The value of that dimension as written on the |aux| file will be stored in 
-% |\l_@@_width_on_aux_dim|.
-%    \begin{macrocode}
-\dim_new:N \l_@@_width_on_aux_dim 
-%    \end{macrocode}
 %
 % \medskip
 % We will count the environments |{Piton}| (and, in fact, also the commands
@@ -2085,13 +2091,55 @@
 \bool_new:N \l_@@_break_lines_in_piton_bool
 %    \end{macrocode}
 % 
+% \bigskip
+% The following dimension will be the width of the listing constructed by
+% |{Piton}| or |\PitonInputFile|.
+% \begin{itemize}
+% \item If the user uses the key |width| of |\PitonOptions| with a numerical
+% value, that value will be stored in |\l_@@_width_dim|.
+% \item If the user uses the key |width| with the special value~|min|, the
+% dimension |\l_@@_width_dim| will, \emph{in the second run}, be computed from
+% the value of |\l_@@_line_width_dim| stored in the |aux| file
+% (computed during the first run the maximal width of the lines of the listing).
+% During the first run, |\l_@@_width_line_dim| will be set equal to |\linewidth|.
+% \item Elsewhere, |\l_@@_width_dim| will be set at the beginning of the listing
+% (in |\@@_pre_env:|) equal to the current value of |\linewidth|.
+% \end{itemize}
+% 
+%    \begin{macrocode} 
+\dim_new:N \l_@@_width_dim 
+%    \end{macrocode}
+% 
 % \medskip
-% The following boolean corresponds to the key |slim| of |\PitonOptions|.
+% We will also use another dimension called |\l_@@_line_width_dim|. That
+% will the width of the actual lines of code. That dimension may be lower than
+% the whole |\l_@@_width_dim| because we have to take into account the value of
+% |\l_@@_left_margin_dim| (for the numbers of lines when |line-numbers| is in
+% force) and another small margin when a background color is used (with the key
+% |background-color|). 
 %    \begin{macrocode}
-\bool_new:N \l_@@_slim_bool
+\dim_new:N \l_@@_line_width_dim
 %    \end{macrocode}
+% 
+% \medskip
+% The following flag will be raised with the key |width| is used with the
+% special value |min|.
+%    \begin{macrocode}
+\bool_new:N \l_@@_width_min_bool
+%    \end{macrocode}
 %
 % \medskip
+% If the key |width| is used with the special value~|min|, we will compute the
+% maximal width of the lines of an environment |{Piton}| in |\g_@@_tmp_width_dim|
+% because we need it for the case of the key |width| is used with the spacial
+% value |min|. We need a global variable because, when the key |footnote| is in
+% force, each line when be composed in an environment |{savenotes}| and we need
+% to exit our |\g_@@_tmp_width_dim| from that environment.
+%    \begin{macrocode}
+\dim_new:N \g_@@_tmp_width_dim 
+%    \end{macrocode}
+%
+% \medskip
 % The following dimension corresponds to the key |left-margin| of |\PitonOptions|. 
 %    \begin{macrocode}
 \dim_new:N \l_@@_left_margin_dim
@@ -2222,85 +2270,14 @@
 \cs_new_protected:Npn \@@_prompt: 
   { 
     \tl_gset:Nn \g_@@_begin_line_hook_tl
-      { \clist_set:NV \l_@@_bg_color_clist \l_@@_prompt_bg_color_tl } 
-  }
-%    \end{macrocode}
-%
-% 
-% \bigskip
-% You will keep track of the current style for the treatment of EOL (for the
-% multi-line syntactic elements).
-%    \begin{macrocode}
-\clist_new:N \g_@@_current_style_clist
-\clist_set:Nn \g_@@_current_style_clist { __end }
-%    \end{macrocode}
-% The element |__end| is an arbitrary syntactic marker.
-% 
-% \medskip
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_close_current_styles:
-  { 
-    \int_set:Nn \l_tmpa_int { \clist_count:N \g_@@_current_style_clist - 1  } 
-    \exp_args:NV \@@_close_n_styles:n \l_tmpa_int
-  }
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_close_n_styles:n #1
-  { 
-    \int_compare:nNnT { #1 } > 0 
       { 
-        \@@_close_brace:
-        \@@_close_brace:
-        \@@_close_n_styles:n { #1 - 1 } 
-      }
+        \tl_if_empty:NF \l_@@_prompt_bg_color_tl % added 2023-04-24
+          { \clist_set:NV \l_@@_bg_color_clist \l_@@_prompt_bg_color_tl }
+      } 
   }
 %    \end{macrocode}
 %
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_open_current_styles:
-  { \exp_last_unbraced:NV \@@_open_styles:w \g_@@_current_style_clist , }
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_open_styles:w #1 , 
-  {
-    \tl_if_eq:nnF { #1 } { __end }
-      { \@@_open_brace: #1 \@@_open_brace: \@@_open_styles:w }
-  }
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_pop_style:
-  {
-    \clist_greverse:N \g_@@_current_style_clist
-    \clist_gpop:NN \g_@@_current_style_clist \l_tmpa_tl
-    \clist_gpop:NN \g_@@_current_style_clist \l_tmpa_tl
-    \clist_gpush:Nn \g_@@_current_style_clist { __end }
-    \clist_greverse:N \g_@@_current_style_clist
-  }
-%    \end{macrocode}
 % 
-% \medskip
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_push_style:n #1
-  {
-    \clist_greverse:N \g_@@_current_style_clist
-    \clist_gpop:NN \g_@@_current_style_clist \l_tmpa_tl
-    \clist_gpush:Nn \g_@@_current_style_clist { #1 }
-    \clist_gpush:Nn \g_@@_current_style_clist { __end }
-    \clist_greverse:N \g_@@_current_style_clist
-  }
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_push_and_exec:n #1
-  {
-    \@@_push_style:n { #1 }
-    \@@_open_brace: #1 \@@_open_brace:
-  }
-%    \end{macrocode}
-% 
 % \bigskip
 % \subsubsection{Treatment of a line of code}
 % 
@@ -2345,23 +2322,16 @@
     \int_gzero:N \g_@@_indentation_int
 %    \end{macrocode}
 %
-% 
-% Be careful: there is curryfication in the following lines.
+% \medskip
+% First, we will put in the coffin |\l_tmpa_coffin| the actual content of a line
+% of the code (without the potential number of line).
+%
+% Be careful: There is curryfication in the following code.
 %    \begin{macrocode}
-    \bool_if:NTF \l_@@_slim_bool
-      { \hcoffin_set:Nn \l_tmpa_coffin }
+    \bool_if:NTF \l_@@_width_min_bool
+      \@@_put_in_coffin_ii:n 
+      \@@_put_in_coffin_i:n 
       { 
-        \clist_if_empty:NTF \l_@@_bg_color_clist
-          { 
-            \vcoffin_set:Nnn \l_tmpa_coffin 
-              { \dim_eval:n { \linewidth - \l_@@_left_margin_dim } } 
-          }
-          { 
-            \vcoffin_set:Nnn \l_tmpa_coffin
-              { \dim_eval:n { \linewidth - \l_@@_left_margin_dim - 0.5 em } } 
-          }
-      }
-      { 
         \language = -1
         \raggedright 
         \strut 
@@ -2368,6 +2338,10 @@
         \@@_replace_spaces:n { #1 }
         \strut \hfil 
       } 
+%    \end{macrocode}
+% Now, we add the potential number of line, the potential left margin and the
+% potential background.
+%    \begin{macrocode}
     \hbox_set:Nn \l_tmpa_box 
       { 
         \skip_horizontal:N \l_@@_left_margin_dim
@@ -2374,31 +2348,32 @@
         \bool_if:NT \l_@@_line_numbers_bool
           {
             \bool_if:NF \l_@@_all_line_numbers_bool
-              { \tl_if_eq:nnF  { #1 } { \PitonStyle {Prompt}{} } } % corrected 2023/04/10
+              { \tl_if_eq:nnF  { #1 } { \PitonStyle {Prompt}{} } } 
+%    \end{macrocode}
+% Remember that |\@@_print_number:| always uses |\hbox_overlap_left:n|.
+%    \begin{macrocode}
               \@@_print_number:
           }
+%    \end{macrocode}
+% If there is a background, we must remind that there is a left margin of 0.5~em
+% for the background...
+%    \begin{macrocode}
         \clist_if_empty:NF \l_@@_bg_color_clist 
           { 
+%    \end{macrocode}
+% ... but if only if the key |left-margin| is not used !
+%    \begin{macrocode}
             \dim_compare:nNnT \l_@@_left_margin_dim = \c_zero_dim 
-               { 
-                 \bool_if:NF \l_@@_left_margin_auto_bool
-                   { \skip_horizontal:n { 0.5 em } }
-               }
+               { \skip_horizontal:n { 0.5 em } }
           }
         \coffin_typeset:Nnnnn \l_tmpa_coffin T l \c_zero_dim \c_zero_dim 
       }  
-%    \end{macrocode}
-% We compute in |\g_@@_width_dim| the maximal width of the lines of the
-% environment. 
-%    \begin{macrocode}
-    \dim_compare:nNnT { \box_wd:N \l_tmpa_box } > \g_@@_width_dim 
-      { \dim_gset:Nn \g_@@_width_dim { \box_wd:N \l_tmpa_box } }
     \box_set_dp:Nn \l_tmpa_box { \box_dp:N \l_tmpa_box + 1.25 pt } 
     \box_set_ht:Nn \l_tmpa_box { \box_ht:N \l_tmpa_box + 1.25 pt } 
     \clist_if_empty:NTF \l_@@_bg_color_clist
       { \box_use_drop:N \l_tmpa_box }
       {
-        \vbox_top:n 
+        \vtop 
           { 
             \hbox:n
               { 
@@ -2405,10 +2380,9 @@
                 \@@_color:N \l_@@_bg_color_clist
                 \vrule height \box_ht:N \l_tmpa_box 
                        depth \box_dp:N \l_tmpa_box 
-                       width \l_@@_width_on_aux_dim
+                       width \l_@@_width_dim
               } 
             \skip_vertical:n { - \box_ht_plus_dp:N \l_tmpa_box }
-            \box_set_wd:Nn \l_tmpa_box \l_@@_width_on_aux_dim 
             \box_use_drop:N \l_tmpa_box
           }
       }   
@@ -2419,6 +2393,54 @@
 %    \end{macrocode}
 %
 % \bigskip
+% In the general case (which is also the simpler), the key |width| is not used,
+% or (if used) it is not used with the special value~|min|.
+% In that case, the content of a line of code is composed in a vertical coffin
+% with a width equal to |\l_@@_line_width_dim|. That coffin may,
+% eventually, contains several lines when the key |broken-lines-in-Piton| (or
+% |broken-lines|) is used.
+% 
+% That commands takes in its argument by curryfication.
+%    \begin{macrocode}
+\cs_set_protected:Npn \@@_put_in_coffin_i:n 
+  { \vcoffin_set:Nnn \l_tmpa_coffin \l_@@_line_width_dim }
+%    \end{macrocode}
+%
+% \bigskip
+% The second case is the case when the key |width| is used with the special
+% value~|min|. 
+%    \begin{macrocode}
+\cs_set_protected:Npn \@@_put_in_coffin_ii:n #1
+  {
+%    \end{macrocode}
+% First, we compute the natural width of the line of code because we have to
+% compute the natural width of the whole listing (and it will be written on the
+% |aux| file in the variable |\l_@@_width_dim|).
+%    \begin{macrocode}
+    \hbox_set:Nn \l_tmpa_box { #1 }
+%    \end{macrocode}
+% Now, you can actualize the value of |\g_@@_tmp_width_dim| (it will be used to 
+% write on the |aux| file the natural width of the environment).
+%    \begin{macrocode}
+    \dim_compare:nNnT { \box_wd:N \l_tmpa_box } > \g_@@_tmp_width_dim
+      { \dim_gset:Nn \g_@@_tmp_width_dim { \box_wd:N \l_tmpa_box } }
+%    \end{macrocode}
+% 
+%    \begin{macrocode}
+    \hcoffin_set:Nn \l_tmpa_coffin 
+      { 
+        \hbox_to_wd:nn \l_@@_line_width_dim 
+%    \end{macrocode}
+% We unpack the bock in order to free the potential |\hfill| springs present in
+% the LaTeX comments (cf. section~\ref{example-comments}, p.~\pageref{example-comments}).
+%    \begin{macrocode}
+          { \hbox_unpack:N \l_tmpa_box \hfil } 
+      } 
+  }
+%    \end{macrocode}
+%
+% 
+% \bigskip
 % The command |\@@_color:N| will take in as argument a reference to a
 % comma-separated list of colors. A color will be picked by using the value of
 % |\g_@@_line_int| (modulo the number of colors in the list).
@@ -2430,10 +2452,10 @@
     \tl_set:Nx \l_tmpa_tl { \clist_item:Nn #1 \l_tmpb_int }
     \tl_if_eq:NnTF \l_tmpa_tl { none }
 %    \end{macrocode}
-% By setting |\l_@@_width_on_aux_dim| to zero, the colored rectangle will be
+% By setting |\l_@@_width_dim| to zero, the colored rectangle will be
 % drawn with zero width and, thus, it will be a mere strut (and we need that strut).
 %    \begin{macrocode}
-      { \dim_zero:N \l_@@_width_on_aux_dim }
+      { \dim_zero:N \l_@@_width_dim }
       { \exp_args:NV \@@_color_i:n \l_tmpa_tl }
   }
 %    \end{macrocode}
@@ -2466,7 +2488,7 @@
           {
             \egroup
             \bool_if:NT \c_@@_footnote_bool { \end { savenotes } } 
-            \newline
+            \par \mode_leave_vertical: % \newline
             \bool_if:NT \c_@@_footnote_bool { \begin { savenotes } } 
             \vtop \bgroup
           }
@@ -2552,8 +2574,17 @@
     background-color .value_required:n  = true ,
     prompt-background-color .tl_set:N         = \l_@@_prompt_bg_color_tl ,
     prompt-background-color .value_required:n = true ,
-    slim             .bool_set:N        = \l_@@_slim_bool ,
-    slim             .default:n         = true ,
+    width            .code:n = 
+      \str_if_eq:nnTF  { #1 } { min } 
+        { 
+          \bool_set_true:N \l_@@_width_min_bool 
+          \dim_zero:N \l_@@_width_dim 
+        }
+        { 
+          \bool_set_false:N \l_@@_width_min_bool
+          \dim_set:Nn \l_@@_width_dim { #1 } 
+        } , 
+    width            .value_required:n  = true ,
     left-margin      .code:n =
       \str_if_eq:nnTF { #1 } { auto }
         { 
@@ -2560,7 +2591,10 @@
           \dim_zero:N \l_@@_left_margin_dim 
           \bool_set_true:N \l_@@_left_margin_auto_bool
         }
-        { \dim_set:Nn \l_@@_left_margin_dim { #1 } } ,
+        { 
+          \dim_set:Nn \l_@@_left_margin_dim { #1 } 
+          \bool_set_false:N \l_@@_left_margin_auto_bool
+        } ,
     left-margin      .value_required:n  = true ,
     numbers-sep      .dim_set:N         = \l_@@_numbers_sep_dim ,
     numbers-sep      .value_required:n  = true , 
@@ -2645,20 +2679,17 @@
   }
 %    \end{macrocode}
 %
+% \bigskip
+% The following macro with be used only when the key |width| is used with the
+% special value~|min|.
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_width_to_aux:
   {
-    \bool_if:NT \l_@@_slim_bool
-      {
-        \clist_if_empty:NF \l_@@_bg_color_clist
-          {
-            \tl_gput_right:Nx \g_@@_aux_tl
-              {
-                \dim_set:Nn \l_@@_width_on_aux_dim 
-                  { \dim_eval:n { \g_@@_width_dim + 0.5 em } }
-              }
-          }
-      }
+    \tl_gput_right:Nx \g_@@_aux_tl
+      { 
+        \dim_set:Nn \l_@@_line_width_dim 
+          { \dim_eval:n { \g_@@_tmp_width_dim } }
+      } 
   }
 %    \end{macrocode}
 % 
@@ -2819,11 +2850,18 @@
     \automatichyphenmode = 1
     \int_gincr:N \g_@@_env_int 
     \tl_gclear:N \g_@@_aux_tl
+    \dim_compare:nNnT \l_@@_width_dim = \c_zero_dim 
+      { \dim_set_eq:NN \l_@@_width_dim \linewidth }
+%    \end{macrocode}
+% We read the information written on the |aux| file by previous run (when the
+% key |width| is used with the special value~|min|). At this time, the only
+% potential information written on the |aux| file is the value of
+% |\l_@@_line_width_dim| when the key |width| has been used with the special
+% value~|min|). 
+%    \begin{macrocode}
     \cs_if_exist_use:c { c_@@ _ \int_use:N \g_@@_env_int _ tl }
-    \dim_compare:nNnT \l_@@_width_on_aux_dim = \c_zero_dim
-      { \dim_set_eq:NN \l_@@_width_on_aux_dim \linewidth }
     \bool_if:NF \l_@@_resume_bool { \int_gzero:N \g_@@_visual_line_int }
-    \dim_gzero:N \g_@@_width_dim
+    \dim_gzero:N \g_@@_tmp_width_dim
     \int_gzero:N \g_@@_line_int
     \dim_zero:N \parindent 
     \dim_zero:N \lineskip 
@@ -2842,79 +2880,99 @@
     last-line .value_required:n = true , 
   }
 %    \end{macrocode}
+%
+%
+% \bigskip
+% If the final user has used both |left-margin=auto| and |line-numbers|, we have
+% to compute the width of the maximal number of lines at the end of the
+% environment to fix the correct value to |left-margin|. The first argument of
+% the following function is the name of the Lua function that will be applied to
+% the second argument in order to count the number of lines.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_compute_left_margin:nn #1 #2
+  {
+    \bool_lazy_and:nnT \l_@@_left_margin_auto_bool \l_@@_line_numbers_bool
+       {
+        \hbox_set:Nn \l_tmpa_box
+          {
+            \footnotesize
+            \bool_if:NTF \l_@@_all_line_numbers_bool
+              {
+                \int_to_arabic:n 
+                  { \g_@@_visual_line_int + \l_@@_nb_lines_int }  
+              }
+              {
+                \lua_now:n 
+                  { piton.#1(token.scan_argument()) }
+                  { #2 }
+                \int_to_arabic:n 
+                  { \g_@@_visual_line_int + \l_@@_nb_non_empty_lines_int }   
+               }
+           }
+         \dim_set:Nn \l_@@_left_margin_dim 
+           { \box_wd:N \l_tmpa_box + \l_@@_numbers_sep_dim + 0.1 em }
+       }
+  }
+%    \end{macrocode}
 % 
+%
+%
 % \bigskip
+% Whereas |\l_@@_with_dim| is the width of the environment,
+% |\l_@@_line_width_dim| is the width of the lines of code without the
+% potential margins for the numbers of lines and the background. Depending on
+% the case, you have to compute |\l_@@_line_width_dim| from |\l_@@_width_dim| or
+% we have to do the opposite.
 %    \begin{macrocode}
-\NewDocumentCommand { \PitonInputFile } { d < > O { } m }
+\cs_new_protected:Npn \@@_compute_width:
   {
-    \tl_if_novalue:nF { #1 }
+    \dim_compare:nNnTF \l_@@_line_width_dim = \c_zero_dim
       {
-        \bool_if:NTF \c_@@_beamer_bool
-          { \begin { uncoverenv } < #1 > }     
-          { \msg_error:nn { piton } { overlay~without~beamer } }
-      }
-    \group_begin:
-      \int_zero_new:N \l_@@_first_line_int
-      \int_zero_new:N \l_@@_last_line_int 
-      \int_set_eq:NN \l_@@_last_line_int \c_max_int
-      \keys_set:nn { PitonInputFile } { #2 }
-      \@@_pre_env:
-      \mode_if_vertical:TF \mode_leave_vertical: \newline 
+        \dim_set_eq:NN \l_@@_line_width_dim \l_@@_width_dim
+        \clist_if_empty:NTF \l_@@_bg_color_clist
 %    \end{macrocode}
-% We count with Lua the number of lines of the argument. The result will be
-% stored by Lua in |\l_@@_nb_lines_int|. That information will be used to allow
-% or disallow page breaks.
+% If there is no background, we only subtract the left margin. 
 %    \begin{macrocode}
-      \lua_now:n { piton.CountLinesFile(token.scan_argument()) } { #3 }  
-%    \end{macrocode}     
-% If the final user has used both |left-margin=auto| and |line-numbers| or
-% |all-line-numbers|, we have to compute the width of the maximal number of
-% lines at the end of the composition of the listing to fix the correct value to
-% |left-margin|. 
+          { \dim_sub:Nn \l_@@_line_width_dim \l_@@_left_margin_dim }
+%    \end{macrocode}
+% If there is a background, we subtract 0.5~em for the margin on the right.
 %    \begin{macrocode}
-      \bool_lazy_and:nnT \l_@@_left_margin_auto_bool \l_@@_line_numbers_bool
-        {
-         \hbox_set:Nn \l_tmpa_box
-           {
-             \footnotesize
-             \bool_if:NTF \l_@@_all_line_numbers_bool
-               {
-                 \int_to_arabic:n 
-                   { \g_@@_visual_line_int + \l_@@_nb_lines_int }  
-               }
-               {
-                 \lua_now:n 
-                   { piton.CountNonEmptyLinesFile(token.scan_argument()) } 
-                   { #3 }
-                 \int_to_arabic:n 
-                   { \g_@@_visual_line_int + \l_@@_nb_non_empty_lines_int }   
-                }
-            }
-          \dim_set:Nn \l_@@_left_margin_dim 
-            { \box_wd:N \l_tmpa_box + \l_@@_numbers_sep_dim + 0.1 em }
-        }
+          { 
+            \dim_sub:Nn \l_@@_line_width_dim { 0.5 em }
 %    \end{macrocode}
-% Now, the main job.
+% And we subtract also for the left margin. If the key |left-margin| has been
+% used (with a numerical value or with the special value~|min|),
+% |\l_@@_left_margin_dim| has a non-zero value\footnote{If the key
+% \texttt{left-margin} has been used with the special value \texttt{min}, the
+% actual value of \texttt{\textbackslash l_\@\@_left_margin_dim} has yet been
+% computed when we use the current command.} and we use that value. Elsewhere,
+% we use a value of 0.5~em.
 %    \begin{macrocode}
-      \ttfamily
-      \bool_if:NT \c_@@_footnote_bool { \begin { savenotes } } 
-      \vtop \bgroup 
-      \lua_now:e
-        { 
-          piton.ParseFile('\l_@@_language_str',token.scan_argument() ,
-           \int_use:N \l_@@_first_line_int , 
-           \int_use:N \l_@@_last_line_int ) 
-        } 
-        { #3 }
-      \egroup 
-      \bool_if:NT \c_@@_footnote_bool { \end { savenotes } } 
-      \@@_width_to_aux:
-    \group_end:
-    \tl_if_novalue:nF { #1 }
-      { \bool_if:NT \c_@@_beamer_bool { \end { uncoverenv } } }
-    \@@_write_aux:
+            \dim_compare:nNnTF \l_@@_left_margin_dim = \c_zero_dim 
+              { \dim_sub:Nn \l_@@_line_width_dim { 0.5 em } }
+              { \dim_sub:Nn \l_@@_line_width_dim \l_@@_left_margin_dim }
+          }
+      }
+%    \end{macrocode}
+% If |\l_@@_line_width_dim| has yet a non-empty value, that means that it has
+% been read on the |aux| file: it has been written on a previous run because the
+% key |width| is used with the special value~|min|). We compute now the width of
+% the environment by computations opposite to the preceding ones.
+%    \begin{macrocode}
+      {
+        \dim_set_eq:NN \l_@@_width_dim \l_@@_line_width_dim
+        \clist_if_empty:NTF \l_@@_bg_color_clist
+          { \dim_add:Nn \l_@@_width_dim \l_@@_left_margin_dim }
+          { 
+            \dim_add:Nn \l_@@_width_dim { 0.5 em }
+            \dim_compare:nNnTF \l_@@_left_margin_dim = \c_zero_dim 
+              { \dim_add:Nn \l_@@_width_dim { 0.5 em } }
+              { \dim_add:Nn \l_@@_width_dim \l_@@_left_margin_dim }
+          }
+      }
   }
 %    \end{macrocode}
+% 
 %
 % 
 % \bigskip 
@@ -2935,7 +2993,7 @@
           ####1 
           \c_backslash_str end \c_left_brace_str #1 \c_right_brace_str
       }
-          {
+         { 
             \group_end:
             \mode_if_vertical:TF \mode_leave_vertical: \newline 
 %    \end{macrocode}
@@ -2945,39 +3003,16 @@
 %    \begin{macrocode}
             \lua_now:n { piton.CountLines(token.scan_argument()) } { ##1 }  
 %    \end{macrocode}
-% If the final user has used both |left-margin=auto| and |line-numbers|, we have
-% to compute the width of the maximal number of lines at the end of the
-% environment to fix the correct value to |left-margin|.
+% The first argument of the following function is the name of the Lua function
+% that will be applied to the second argument in order to count the number of lines.
 %    \begin{macrocode}
-            \bool_lazy_and:nnT \l_@@_left_margin_auto_bool \l_@@_line_numbers_bool
-              {
-                \bool_if:NTF \l_@@_all_line_numbers_bool
-                  {
-                    \hbox_set:Nn \l_tmpa_box
-                      { 
-                        \footnotesize
-                        \int_to_arabic:n 
-                          { \g_@@_visual_line_int + \l_@@_nb_lines_int }  
-                      }
-                  }
-                  {
-                    \lua_now:n 
-                      { piton.CountNonEmptyLines(token.scan_argument()) } 
-                      { ##1 }  
-                    \hbox_set:Nn \l_tmpa_box
-                      { 
-                        \footnotesize
-                        \int_to_arabic:n 
-                          { \g_@@_visual_line_int + \l_@@_nb_non_empty_lines_int }   
-                      }
-                  }
-                \dim_set:Nn \l_@@_left_margin_dim
-                  { \box_wd:N \l_tmpa_box + \l_@@_numbers_sep_dim + 0.1 em }
-              }
+            \@@_compute_left_margin:nn { CountNonEmptyLines } { ##1 }
+            \@@_compute_width:
+            \ttfamily
 %    \end{macrocode}
-% Now, the main job.
+% |\c_@@_footnote_bool| is raised when the package \pkg{piton} has been load
+% with the key |footnote| \emph{or} the key |footnotehyper|.
 %    \begin{macrocode}
-            \ttfamily
             \bool_if:NT \c_@@_footnote_bool { \begin { savenotes } } 
             \vtop \bgroup 
             \lua_now:e 
@@ -2993,11 +3028,15 @@
             \vspace { 2.5 pt } 
             \egroup 
             \bool_if:NT \c_@@_footnote_bool { \end { savenotes } } 
-            \@@_width_to_aux:
 %    \end{macrocode}
-% The following |\end{#1}| is only for the groups and the stack of environments
-% of LaTeX.
+% If the user has used the key |width| with the special value~|min|, we write on
+% the |aux| file the value of |\l_@@_line_width_dim| (largest width of the lines
+% of code of the environment).
 %    \begin{macrocode}
+            \bool_if:NT \l_@@_width_min_bool \@@_width_to_aux:
+%    \end{macrocode}
+% The following |\end{#1}| is only for the stack of environments of LaTeX.
+%    \begin{macrocode}
             \end { #1 }
             \@@_write_aux:
           }   
@@ -3054,7 +3093,79 @@
 %    \end{macrocode}
 %
 %
+% \bigskip
+% The code of the command |\PitonInputFile| is somewhat similar to the code of
+% the environment |{Piton}|. In fact, it's simpler because there isn't the
+% problem of catching the content of the environment in a verbatim mode.
+%    \begin{macrocode}
+\NewDocumentCommand { \PitonInputFile } { d < > O { } m }
+  {
+    \file_if_exist:nTF { #3 }
+      { \@@_input_file:nnn { #1 } { #2 } { #3 } }
+      { \msg_error:nnn { piton } { unknown~file } { #3 } } 
+  }
+%    \end{macrocode}
 %
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_input_file:nnn #1 #2 #3
+  {
+%    \end{macrocode}
+% We recall that, if we are in Beamer, the command |\PitonInputFile| is
+% ``overlay-aware'' and that's why there is an optional argument between angular
+% brackets (|<| and |>|).
+%    \begin{macrocode}
+    \tl_if_novalue:nF { #1 }
+      {
+        \bool_if:NTF \c_@@_beamer_bool
+          { \begin { uncoverenv } < #1 > }     
+          { \msg_error:nn { piton } { overlay~without~beamer } }
+      }
+    \group_begin:
+      \int_zero_new:N \l_@@_first_line_int
+      \int_zero_new:N \l_@@_last_line_int 
+      \int_set_eq:NN \l_@@_last_line_int \c_max_int
+      \keys_set:nn { PitonInputFile } { #2 }
+      \@@_pre_env:
+      \mode_if_vertical:TF \mode_leave_vertical: \newline 
+%    \end{macrocode}
+% We count with Lua the number of lines of the argument. The result will be
+% stored by Lua in |\l_@@_nb_lines_int|. That information will be used to allow
+% or disallow page breaks.
+%    \begin{macrocode}
+      \lua_now:n { piton.CountLinesFile(token.scan_argument()) } { #3 }  
+%    \end{macrocode}
+% The first argument of the following function is the name of the Lua function
+% that will be applied to the second argument in order to count the number of lines.
+%    \begin{macrocode}
+      \@@_compute_left_margin:nn { CountNonEmptyLinesFile } { #3 }
+      \@@_compute_width:
+      \ttfamily
+      \bool_if:NT \c_@@_footnote_bool { \begin { savenotes } } 
+      \vtop \bgroup 
+      \lua_now:e
+        { 
+          piton.ParseFile(
+           '\l_@@_language_str',
+           token.scan_argument() ,
+           \int_use:N \l_@@_first_line_int , 
+           \int_use:N \l_@@_last_line_int ) 
+        } 
+        { #3 }
+      \egroup 
+      \bool_if:NT \c_@@_footnote_bool { \end { savenotes } } 
+      \bool_if:NT \l_@@_width_min_bool \@@_width_to_aux:
+    \group_end:
+%    \end{macrocode}
+% We recall that, if we are in Beamer, the command |\PitonInputFile| is
+% ``overlay-aware'' and that's why we close now an environment |{uncoverenv}|
+% that we have opened at the beginning of the command.
+%    \begin{macrocode}
+    \tl_if_novalue:nF { #1 }
+      { \bool_if:NT \c_@@_beamer_bool { \end { uncoverenv } } }
+    \@@_write_aux:
+  }
+%    \end{macrocode}
+%
 % \bigskip
 % \subsubsection{The styles}
 % 
@@ -3088,10 +3199,12 @@
     Dict.Value        .value_required:n = true ,
     Name.Decorator    .tl_set:c = pitonStyle Name.Decorator ,
     Name.Decorator    .value_required:n = true ,
+    Name.Field        .tl_set:c = pitonStyle Name.Field , 
+    Name.Field        .value_required:n = true ,
     Name.Function     .tl_set:c = pitonStyle Name.Function ,
     Name.Function     .value_required:n = true ,
-    Name.UserFunction .tl_set:c = pitonStyle Name.UserFunction ,
-    Name.UserFunction .value_required:n = true ,
+    UserFunction      .tl_set:c = pitonStyle UserFunction ,
+    UserFunction      .value_required:n = true ,
     Keyword           .tl_set:c = pitonStyle Keyword ,
     Keyword           .value_required:n = true ,
     Keyword.Constant  .tl_set:c = pitonStyle Keyword.Constant ,
@@ -3110,6 +3223,8 @@
     Comment.Math      .initial:n = ,
     Comment           .tl_set:c = pitonStyle Comment , 
     Comment           .value_required:n = true ,
+    Name.Constructor  .tl_set:c = pitonStyle Name.Constructor , 
+    Name.Constructor  .value_required:n = true ,
     InitialValues     .tl_set:c = pitonStyle InitialValues ,
     InitialValues     .value_required:n = true ,
     Number            .tl_set:c = pitonStyle Number , 
@@ -3116,6 +3231,8 @@
     Number            .value_required:n = true ,
     Name.Namespace    .tl_set:c = pitonStyle Name.Namespace , 
     Name.Namespace    .value_required:n = true ,
+    Name.Module       .tl_set:c = pitonStyle Name.Module , 
+    Name.Module       .value_required:n = true ,
     Name.Class        .tl_set:c = pitonStyle Name.Class , 
     Name.Class        .value_required:n = true ,
     Name.Builtin      .tl_set:c = pitonStyle Name.Builtin , 
@@ -3163,9 +3280,13 @@
     Keyword.Constant,~
     Name.Builtin,~
     Name.Class,~
+    Name.Constructor,~
     Name.Decorator,~
+    Name.Field,~
     Name.Function,~
+    Name.Module,~
     Name.Namespace,~
+    UserFunction,~
     Number,~
     Operator,~
     Operator.Word,~
@@ -3179,9 +3300,9 @@
 %    \end{macrocode}
 %
 % \bigskip
-% \subsubsection{The initial style}
+% \subsubsection{The initial styles}
 %
-% The initial style is inspired by the style ``manni'' of Pygments.
+% The initial styles are inspired by the style ``manni'' of Pygments.
 % 
 % \medskip
 %    \begin{macrocode}
@@ -3196,6 +3317,9 @@
     Name.Class         = \color[HTML]{00AA88} \bfseries ,
     Name.Function      = \color[HTML]{CC00FF} , 
     Name.Namespace     = \color[HTML]{00CCFF} , 
+    Name.Constructor   = \color[HTML]{006000} \bfseries , 
+    Name.Field         = \color[HTML]{AA6600} , 
+    Name.Module        = \color[HTML]{0060A0} \bfseries ,
     Number             = \color[HTML]{FF6600} ,
     Operator           = \color[HTML]{555555} ,
     Operator.Word      = \bfseries ,
@@ -3207,9 +3331,9 @@
     InitialValues      = \@@_piton:n ,
     Dict.Value         = \@@_piton:n ,
     Interpol.Inside    = \color{black}\@@_piton:n ,
-    TypeParameter      = \color[HTML]{008800} \itshape ,
+    TypeParameter      = \color[HTML]{336666} \itshape ,
     Identifier         = \@@_identifier:n , 
-    Name.UserFunction  = , 
+    UserFunction  = , 
     Prompt             = , 
     ParseAgain.noCR    = \@@_piton_no_cr:n , 
     ParseAgain         = \@@_piton:n ,
@@ -3271,7 +3395,7 @@
 %
 %
 % \bigskip
-% In particular, we have an hightlighting of the indentifiers which are the
+% In particular, we have an highlighting of the indentifiers which are the
 % names of Python functions previously defined by the user. Indeed, when a
 % Python function is defined, the style |Name.Function.Internal| is applied to
 % that name. We define now that style (you define it directly and you short-cut
@@ -3278,7 +3402,7 @@
 % the function |\SetPitonStyle|). 
 %    \begin{macrocode}
 \cs_new_protected:cpn { pitonStyle Name.Function.Internal } #1
-  {
+  { 
 %    \end{macrocode}
 % First, the element is composed in the TeX flow with the style |Name.Function|
 % which is provided to the final user.
@@ -3286,16 +3410,16 @@
     { \PitonStyle { Name.Function } { #1 } }
 %    \end{macrocode}
 % Now, we specify that the name of the new Python function is a known identifier
-% that will be formated with the Piton style |Name.UserFunction|. Of course,
+% that will be formated with the Piton style |UserFunction|. Of course,
 % here the affectation is global because we have to exit many groups and even
 % the environments |{Piton}|).
 %    \begin{macrocode}
     \cs_gset_protected:cpn { PitonIdentifier _ \l_@@_language_str _ #1 } 
-      { \PitonStyle{ Name.UserFunction } }
+      { \PitonStyle { UserFunction } }
 %    \end{macrocode}
 % Now, we put the name of that new user function in the dedicated sequence
-% (specific of the current language). That sequence will be used only by 
-% |\PitonClearUserFunctions|.
+% (specific of the current language). {\bfseries That sequence will be used only
+% by |\PitonClearUserFunctions|}.
 %    \begin{macrocode}
     \seq_if_exist:cF { g_@@_functions _ \l_@@_language_str _ seq }
       { \seq_new:c { g_@@_functions _ \l_@@_language_str _ seq } }
@@ -3336,6 +3460,15 @@
 % \subsubsection{The error messages of the package}
 %
 %    \begin{macrocode}
+\msg_new:nnn { piton } { unknown~file }
+  {
+    Unknown~file. \\
+    The~file~'#1'~is~unknown.\\
+    Your~command~\token_to_str:N \PitonInputFile\ will~be~discarded.
+  }
+%    \end{macrocode}
+% 
+%    \begin{macrocode}
 \msg_new:nnnn { piton } { Unknown~key~for~PitonOptions }
   { 
     Unknown~key. \\
@@ -3365,10 +3498,9 @@
     resume,~
     show-spaces,~
     show-spaces-in-strings,~
-    slim,~
     splittable,~
-    tabs-auto-gobble~
-    and~tab-size.
+    tabs-auto-gobble,~
+    tab-size~and~width.
   }
 %    \end{macrocode}
 %
@@ -3636,7 +3768,7 @@
 %    \begin{macrocode}
 local Space = ( Q " " ) ^ 1
 
-local SkipSpace = ( Q " " ) ^ 0
+local SkipSpace = ( Q " " ) ^ 0 
 
 local Punct = Q ( S ".,:;!" )
 
@@ -3679,7 +3811,7 @@
     )
 
 local OperatorWord = 
-  K ( 'Operator.Word' ,P "in" + P "is" + P "and" + P "or" + P "not" )
+  K ( 'Operator.Word' , P "in" + P "is" + P "and" + P "or" + P "not" )
 
 local Keyword = 
   K ( 'Keyword' ,
@@ -3919,13 +4051,13 @@
 % \bigskip
 % \paragraph{Beamer}
 %
-% The following \textsc{lpeg} |BalancedBraces| will be used for the (mandatory)
+% The following \textsc{lpeg} |balanced_braces| will be used for the (mandatory)
 % argument of the commands |\only| and \emph{al.} of Beamer. It's necessary to
 % use a \emph{grammar} because that pattern mainly checks the correct nesting of
 % the delimiters (and it's known in the theory of formal languages that this
 % can't be done with regular expressions \emph{stricto sensu} only).
 %    \begin{macrocode}
-local BalancedBraces =
+local balanced_braces =
   P { "E" ,
        E = 
            (
@@ -3949,16 +4081,13 @@
 local BeamerNamesEnvironments =  
   P "uncoverenv" + P "onlyenv" + P "visibleenv" + P "invisibleenv" 
   + P "alertenv" + P "actionenv"
-
 %    \end{macrocode}
 %
-%    \begin{macrocode}
-UserCommands = 
-       Ct ( Cc "Open" * C ( "\\emph{" ) * Cc "}" ) 
-     * ( C ( BalancedBraces ) / (function (s) return MainLoopPython:match(s) end ) )
-     * P "}" * Ct ( Cc "Close" ) 
-%    \end{macrocode}
 % 
+% \bigskip
+% The following function will return a \textsc{lpeg} which will catch an
+% environment of Beamer (supported by \pkg{piton}), that is to say |{uncover}|,
+% |{only}|, etc.
 %    \begin{macrocode}
 function OneBeamerEnvironment(name)
   return 
@@ -3971,7 +4100,7 @@
           ) 
      * ( 
          C ( ( 1 - P ( "\\end{" .. name .. "}" ) ) ^ 0 ) 
-         / (function (s) return MainLoopPython:match(s) end ) 
+         / ( function (s) return MainLoopPython:match(s) end ) 
        )
      * P ( "\\end{" .. name ..  "}" ) * Ct ( Cc "Close" ) 
 end 
@@ -3983,7 +4112,7 @@
 if piton_beamer 
 then
   Beamer =
-      L  ( P "\\pause" * ( P "[" * (1 - P "]") ^ 0 * P "]" ) ^ -1 ) 
+      L ( P "\\pause" * ( P "[" * ( 1 - P "]" ) ^ 0 * P "]" ) ^ -1 ) 
     + 
       Ct ( Cc "Open" 
             * C ( 
@@ -3996,10 +4125,9 @@
                 ) 
             * Cc "}" 
          ) 
-       * ( C ( BalancedBraces ) / (function (s) return MainLoopPython:match(s) end ) )
+       * ( C ( balanced_braces ) / (function (s) return MainLoopPython:match(s) end ) )
        * P "}" * Ct ( Cc "Close" ) 
-    + 
-      OneBeamerEnvironment "uncoverenv" 
+    + OneBeamerEnvironment "uncoverenv" 
     + OneBeamerEnvironment "onlyenv" 
     + OneBeamerEnvironment "visibleenv" 
     + OneBeamerEnvironment "invisibleenv" 
@@ -4014,9 +4142,9 @@
           * P "<" * (1 - P ">") ^ 0 * P ">" 
           * P "{" 
         )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * K ( 'ParseAgain.noCR' , balanced_braces ) 
       * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * K ( 'ParseAgain.noCR' , balanced_braces ) 
       * L ( P "}" )
     +  
       L ( 
@@ -4027,11 +4155,11 @@
           * P "<" * (1 - P ">") ^ 0 * P ">" 
           * P "{" 
         )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * K ( 'ParseAgain.noCR' , balanced_braces ) 
       * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * K ( 'ParseAgain.noCR' , balanced_braces ) 
       * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * K ( 'ParseAgain.noCR' , balanced_braces ) 
       * L ( P "}" )
 %    \end{macrocode}
 % Now for the environemnts.
@@ -4221,34 +4349,30 @@
   * Lc "{\\PitonStyle{Comment.LaTeX}{\\ignorespaces" 
   * L ( ( 1 - P "\r" ) ^ 0 ) 
   * Lc "}}" 
-  * ( EOL + -1 )  -- you could put EOL instead of EOL
+  * ( EOL + -1 )  
 %    \end{macrocode}
 % 
 % \bigskip
 % \paragraph{DefFunction}
 %
-% The following \textsc{lpeg} |Expression| will be used for the parameters in
+% The following \textsc{lpeg} |expression| will be used for the parameters in
 % the \emph{argspec} of a Python function. It's necessary to use a \emph{grammar}
 % because that pattern mainly checks the correct nesting of the delimiters
 % (and it's known in the theory of formal languages that this can't be done with
 % regular expressions \emph{stricto sensu} only). 
 %    \begin{macrocode}
-local Expression =
+local expression =
   P { "E" ,
-       E = ( 1 - S "{}()[]\r," ) ^ 0
-           *  (
-                (   P "{" * V "F" * P "}"
-                  + P "(" * V "F" * P ")"
-                  + P "[" * V "F" * P "]" ) * ( 1 - S "{}()[]\r," ) ^ 0
-              ) ^ 0 ,
-       F = ( 1 - S "{}()[]\r\"'" ) ^ 0
-           * ( (
-                   P "'" * (P "\\'" + 1 - S"'\r" )^0 * P "'"
-                 + P "\"" * (P "\\\"" + 1 - S"\"\r" )^0 * P "\""
-                 + P "{"  * V "F" * P "}"
-                 + P "(" * V "F" * P ")"
-                 + P "[" * V "F" * P "]"
-               ) * ( 1 - S "{}()[]\r\"'" ) ^ 0 ) ^ 0 , 
+       E = ( P "'" * ( P "\\'" + 1 - S "'\r" ) ^ 0 * P "'"
+             + P "\"" * (P "\\\"" + 1 - S "\"\r" ) ^ 0 * P "\""
+             + P "{" * V "F" * P "}"
+             + P "(" * V "F" * P ")"
+             + P "[" * V "F" * P "]" 
+             + ( 1 - S "{}()[]\r," ) ) ^ 0 ,
+       F = ( P "{" * V "F" * P "}"
+             + P "(" * V "F" * P ")"
+             + P "[" * V "F" * P "]"
+             + ( 1 - S "{}()[]\r\"'" ) ) ^ 0
     }
 %    \end{macrocode}
 %
@@ -4269,8 +4393,8 @@
 local Param = 
   SkipSpace * Identifier * SkipSpace
    * ( 
-         K ( 'InitialValues' , P "=" * Expression )
-       + Q ( P ":" ) * SkipSpace * K ( 'Name.Type' , letter^1  ) 
+         K ( 'InitialValues' , P "=" * expression )
+       + Q ( P ":" ) * SkipSpace * K ( 'Name.Type' , letter ^ 1  ) 
      ) ^ -1
 %    \end{macrocode}
 % 
@@ -4342,7 +4466,7 @@
 %
 %    \begin{macrocode}
 local ItemDict = 
-  ShortString * SkipSpace * Q ( P ":" ) * K ( 'Dict.Value' , Expression  ) 
+  ShortString * SkipSpace * Q ( P ":" ) * K ( 'Dict.Value' , expression  ) 
 
 local ItemOfSet = SkipSpace * ( ItemDict + ShortString ) * SkipSpace 
 
@@ -4364,24 +4488,20 @@
 %
 % First, the main loop :
 %    \begin{macrocode}
-MainLoopPython = 
-  (  ( space^1 * -1 ) 
-     + EOL
+local MainPython = 
+       EOL
      + Space 
      + Tab
      + Escape 
      + CommentLaTeX
      + Beamer
-     + UserCommands 
      + LongString 
      + Comment
      + ExceptionInConsole
      + Set 
      + Delim
-%    \end{macrocode}
-% |Operator| must be before |Punct|.
-%    \begin{macrocode}
      + Operator
+     + OperatorWord * ( Space + Punct + Delim + EOL + -1 ) 
      + ShortString
      + Punct
      + FromImport
@@ -4388,13 +4508,19 @@
      + RaiseException 
      + DefFunction
      + DefClass 
-     + Keyword * ( Space + Punct + Delim + EOL+ -1 ) 
+     + Keyword * ( Space + Punct + Delim + EOL + -1 ) 
      + Decorator
-     + OperatorWord * ( Space + Punct + Delim + EOL+ -1 ) 
-     + Builtin * ( Space + Punct + Delim + EOL+ -1 ) 
+     + Builtin * ( Space + Punct + Delim + EOL + -1 ) 
      + Identifier 
      + Number
      + Word
+%    \end{macrocode}
+%
+% Ici, il ne faut pas mettre |local| !
+%    \begin{macrocode}
+MainLoopPython = 
+  (  ( space^1 * -1 ) 
+     + MainPython
   ) ^ 0 
 %    \end{macrocode}
 %
@@ -4437,12 +4563,89 @@
 local Punct = Q ( S ",:;!" )
 %    \end{macrocode}
 % 
+% The identifiers catched by |cap_identifier| begin with a cap. In OCaml, it's
+% used for the constructors of types and for the modules.
 %    \begin{macrocode}
+local cap_identifier = R "AZ" * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0 
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+local Constructor = K ( 'Name.Constructor' , cap_identifier )
+local ModuleType = K ( 'Name.Type' , cap_identifier ) 
+%    \end{macrocode}
+%
+% The identifiers which begin with a lower case letter of an underscore are used 
+% elsewhere in OCaml.
+%    \begin{macrocode}
 local identifier = 
-  ( R "az" + R "AZ" + P "_") * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0 
-
+  ( R "az" + P "_") * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0 
 local Identifier = K ( 'Identifier' , identifier )
+%    \end{macrocode}
+%
+%
+% Now, we deal with the records because we want to catch the names of the fields
+% of those records in all circunstancies.
+%    \begin{macrocode}
+local expression_for_fields =
+  P { "E" ,
+       E = ( P "{" * V "F" * P "}"
+             + P "(" * V "F" * P ")"
+             + P "[" * V "F" * P "]" 
+             + P "\"" * (P "\\\"" + 1 - S "\"\r" )^0 * P "\""
+             + P "'" * ( P "\\'" + 1 - S "'\r" )^0 * P "'"
+             + ( 1 - S "{}()[]\r;" ) ) ^ 0 ,
+       F = ( P "{" * V "F" * P "}"
+             + P "(" * V "F" * P ")"
+             + P "[" * V "F" * P "]"
+             + ( 1 - S "{}()[]\r\"'" ) ) ^ 0
+    }
+%    \end{macrocode}
+% 
+%    \begin{macrocode}
+local OneFieldDefinition = 
+    ( K ( 'KeyWord' , P "mutable" ) * SkipSpace ) ^ -1
+  * K ( 'Name.Field' , identifier ) * SkipSpace
+  * Q ":" * SkipSpace
+  * K ( 'Name.Type' , expression_for_fields ) 
+  * SkipSpace
 
+local OneField = 
+    K ( 'Name.Field' , identifier ) * SkipSpace
+  * Q "=" * SkipSpace
+  * ( C ( expression_for_fields ) / ( function (s) return LoopOCaml:match(s) end ) )
+  * SkipSpace
+
+local Record = 
+  Q "{" * SkipSpace
+  * 
+    (
+      OneFieldDefinition * ( Q ";" * SkipSpace * OneFieldDefinition ) ^ 0 
+      + 
+      OneField * ( Q ";" * SkipSpace * OneField ) ^ 0 
+    )
+  *
+  Q "}"
+%    \end{macrocode}
+%
+% \bigskip
+% Now, we deal with the notations with points (eg: |List.length|). In OCaml,
+% such notation is used for the fields of the records and for the modules.
+%    \begin{macrocode}
+local DotNotation = 
+  (
+      K ( 'Name.Module' , cap_identifier ) 
+        * Q "." 
+        * ( Identifier + Constructor + Q "(" + Q "[" + Q "{" ) 
+
+      + 
+      Identifier 
+        * Q "."
+        * K ( 'Name.Field' , identifier ) 
+  )
+  * ( Q "." * K ( 'Name.Field' , identifier ) ) ^ 0 
+%    \end{macrocode}
+%
+%    \begin{macrocode}
 local Operator = 
   K ( 'Operator' ,
       P "!=" + P "<>" + P "==" + P "<<" + P ">>" + P "<=" + P ">=" + P ":=" 
@@ -4458,10 +4661,10 @@
 
 local Keyword = 
   K ( 'Keyword' ,
-      P "as" + P "assert" + P "begin" + P "class" + P "constraint" + P "done" 
-  + P "do" + P "downto" + P "else" + P "end" + P "exception" + P "external" 
-  + P "false" + P "for" + P "function" + P "fun" + P "functor" + P "if" 
-  + P "in" + P "include" + P "inherit" + P "initializer" + P "lazy" + P "let" 
+      P "assert" + P "as" + P "begin" + P "class" + P "constraint" + P "done" 
+  + P "downto" + P "do" + P "else" + P "end" + P "exception" + P "external" 
+  + P "false" + P "for" + P "function" + P "functor" + P "fun"  + P "if" 
+  + P "include" + P "inherit" + P "initializer" + P "in"  + P "lazy" + P "let" 
   + P "match" + P "method" + P "module" + P "mutable" + P "new" + P "object" 
   + P "of" + P "open" + P "private" + P "raise" + P "rec" + P "sig" 
   + P "struct" + P "then" + P "to" + P "true" + P "try" + P "type" 
@@ -4470,20 +4673,7 @@
 
 
 local Builtin = 
-  K ( 'Name.Builtin' ,
-        P "not" + P "incr" + P "decr" + P "fst" + P "snd" 
-      + P "String.length" 
-      + P "List.tl" + P "List.hd" + P "List.mem" + P "List.exists" 
-      + P "List.for_all" + P "List.filter" + P "List.length" + P "List.map" 
-      + P "List.iter" 
-      + P "Array.length" + P "Array.make" + P "Array.make_matrix" 
-      + P "Array.init" + P "Array.copy" + P "Array.copy" + P "Array.mem" 
-      + P "Array.exists" + P "Array.for_all" + P "Array.map" + P "Array.iter" 
-      + P "Queue.create" + P "Queue.is_empty" + P "Queue.push" + P "Queue.pop" 
-      + P "Stack.create" + P "Stack.is_empty" + P "Stack.push" + P "Stack.pop" 
-      + P "Hashtbl.create" + P "Hashtbl.add" + P "Hashtbl.remove" 
-      + P "Hashtbl.mem" + P "Hashtbl.find" + P "Hashtbl.find_opt" 
-      + P "Hashtbl.iter" )
+  K ( 'Name.Builtin' , P "not" + P "incr" + P "decr" + P "fst" + P "snd" )
 %    \end{macrocode}
 % 
 % \bigskip
@@ -4510,7 +4700,7 @@
 % \paragraph{Beamer}
 %
 %    \begin{macrocode}
-local BalancedBraces =
+local balanced_braces =
   P { "E" ,
        E = 
            (
@@ -4539,7 +4729,7 @@
       ) 
       *
       L ( ( P "<" * (1 - P ">") ^ 0 * P ">" ) ^ -1 * P "{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * K ( 'ParseAgain.noCR' , balanced_braces ) 
       * L ( P "}" )
     +  
       L ( 
@@ -4547,9 +4737,9 @@
           * P "<" * (1 - P ">") ^ 0 * P ">" 
           * P "{" 
         )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * K ( 'ParseAgain.noCR' , balanced_braces ) 
       * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * K ( 'ParseAgain.noCR' , balanced_braces ) 
       * L ( P "}" )
     +  
       L ( 
@@ -4557,11 +4747,11 @@
           * P "<" * (1 - P ">") ^ 0 * P ">" 
           * P "{" 
         )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * K ( 'ParseAgain.noCR' , balanced_braces ) 
       * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * K ( 'ParseAgain.noCR' , balanced_braces ) 
       * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * K ( 'ParseAgain.noCR' , balanced_braces ) 
       * L ( P "}" )
   BeamerBeginEnvironments = 
       ( space ^ 0 * 
@@ -4614,7 +4804,7 @@
 % We need a pattern |string| without captures because it will be used within the
 % comments of OCaml.
 %    \begin{macrocode}
-local string =
+local ocaml_string =
        Q ( P "\"" )
      * ( 
          VisualSpace
@@ -4627,7 +4817,7 @@
 %    \end{macrocode}
 % 
 %    \begin{macrocode}
-local String = WithStyle ( 'String.Long' , string ) 
+local String = WithStyle ( 'String.Long' , ocaml_string ) 
 %    \end{macrocode}
 %
 % 
@@ -4693,7 +4883,7 @@
          A = Q "(*"
              * ( V "A" 
                  + Q ( ( 1 - P "(*" - P "*)" - S "\r$\"" ) ^ 1 ) -- $
-                 + string 
+                 + ocaml_string 
                  + P "$" * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1 ) * P "$" -- $
                  + EOL
                ) ^ 0 
@@ -4705,15 +4895,103 @@
 % \paragraph{The DefFunction}
 %
 %    \begin{macrocode}
+local balanced_parens =
+  P { "E" ,
+       E = 
+           (
+             P "(" * V "E" * P ")" 
+             + 
+             ( 1 - S "()" ) 
+           ) ^ 0 
+    }
+%    \end{macrocode}
+% 
+%    \begin{macrocode}
+local Argument = 
+  K ( 'Identifier' , identifier ) 
+  + Q "(" * SkipSpace 
+    * K ( 'Identifier' , identifier ) * SkipSpace 
+    * Q ":" * SkipSpace  
+    * K ( 'Name.Type' , balanced_parens ) * SkipSpace
+    * Q ")"
+%    \end{macrocode}
+%
+% Despite its name, then \textsc{lpeg} |DefFunction| deals also with |let open|
+% which opens locally a module.
+%    \begin{macrocode}
 local DefFunction = 
+  K ( 'Keyword' , P "let open" ) 
+   * Space
+   * K ( 'Name.Module' , cap_identifier ) 
+  + 
   K ( 'Keyword' , P "let rec" + P "let" + P "and" ) 
-  * Space
-  * K ( 'Name.Function.Internal' , identifier ) 
-  * Space 
-  * # ( P "=" * space * P "function" + ( 1 - P "=" ) )
+    * Space
+    * K ( 'Name.Function.Internal' , identifier ) 
+    * Space 
+    * (
+        Q "=" * SkipSpace * K ( 'Keyword' , P "function" ) 
+        + 
+        Argument 
+         * ( SkipSpace * Argument ) ^ 0 
+         * ( 
+             SkipSpace 
+             * Q ":" 
+             * K ( 'Name.Type' , ( 1 - P "=" ) ^ 0 ) 
+           ) ^ -1 
+      ) 
 %    \end{macrocode}
+%
 % 
 % \bigskip
+% \paragraph{The DefModule}
+%
+% The following LPEG will be used in the definitions of modules but also in the
+% definitions of \emph{types} of modules.
+%    \begin{macrocode}
+local DefModule = 
+  K ( 'Keyword' , P "module" ) * Space
+  *
+    (
+          K ( 'Keyword' , P "type" ) * Space
+        * K ( 'Name.Type' , cap_identifier ) 
+      + 
+        K ( 'Name.Module' , cap_identifier ) * SkipSpace 
+        * 
+          (
+            Q "(" * SkipSpace 
+              * K ( 'Name.Module' , cap_identifier ) * SkipSpace 
+              * Q ":" * SkipSpace 
+              * K ( 'Name.Type' , cap_identifier ) * SkipSpace 
+              *
+                (
+                  Q "," * SkipSpace 
+                    * K ( 'Name.Module' , cap_identifier ) * SkipSpace 
+                    * Q ":" * SkipSpace 
+                    * K ( 'Name.Type' , cap_identifier ) * SkipSpace 
+                ) ^ 0 
+              * Q ")"
+          ) ^ -1
+        *
+          (
+            Q "=" * SkipSpace
+            * K ( 'Name.Module' , cap_identifier )  * SkipSpace 
+            * Q "("
+            * K ( 'Name.Module' , cap_identifier ) * SkipSpace 
+              * 
+              (
+                Q ","
+                * 
+                K ( 'Name.Module' , cap_identifier ) * SkipSpace 
+              ) ^ 0 
+            * Q ")"
+          ) ^ -1
+    )
+  + 
+  K ( 'Keyword' , P "include" + P "open" )
+  * Space * K ( 'Name.Module' , cap_identifier ) 
+%    \end{macrocode}
+% 
+% \bigskip
 % \paragraph{The parameters of the types}
 % 
 %    \begin{macrocode}
@@ -4725,9 +5003,8 @@
 %
 % First, the main loop :
 %    \begin{macrocode}
-MainLoopOCaml = 
-  (  ( space^1 * -1 ) 
-     + EOL
+MainOCaml = 
+       EOL
      + Space 
      + Tab
      + Escape 
@@ -4739,15 +5016,24 @@
      + Operator
      + Punct
      + FromImport
-     + ImportAs
      + Exception 
      + DefFunction
+     + DefModule
+     + Record 
      + Keyword * ( Space + Punct + Delim + EOL + -1 ) 
      + OperatorWord * ( Space + Punct + Delim + EOL + -1 ) 
      + Builtin * ( Space + Punct + Delim + EOL + -1 ) 
+     + DotNotation
+     + Constructor
      + Identifier 
      + Number
      + Word
+
+LoopOCaml = MainOCaml ^ 0 
+
+MainLoopOCaml = 
+  (  ( space^1 * -1 ) 
+     + MainOCaml
   ) ^ 0 
 %    \end{macrocode}
 %
@@ -4797,15 +5083,28 @@
      if one_item[1] == "EOL"
      then 
           for _ , s in ipairs(right_stack) 
-            do tex.sprint( s ) 
+            do tex.sprint(s) 
             end
           for _ , s in ipairs(one_item[2]) 
             do tex.tprint(s)
             end
           for _ , s in ipairs(left_stack) 
-            do tex.sprint( s ) 
+            do tex.sprint(s) 
             end
      else 
+%    \end{macrocode}
+%
+% Here is an example of an item beginning with |"Open"|.
+%
+% |{ "Open" , "\begin{uncover}<2>" , "\end{cover}" }|
+%
+% In order to deal with the ends of lines, we have to close the environment
+% (|{cover}| in this example) at the end of each line and reopen it at the
+% beginning of the new line. That's why we use two Lua stacks, called
+% |left_stack| and |right_stack|. |left_stack| will be for the elements like
+% |\begin{uncover}<2>| and |right_stack| will be for the elements like
+% |\end{cover}|. 
+%    \begin{macrocode}
           if one_item[1] == "Open"
           then
                tex.sprint( one_item[2] ) 
@@ -4834,7 +5133,7 @@
 % then apply the function~|Parse| to the resulting Lua string.
 %    \begin{macrocode}
 function piton.ParseFile(language,name,first_line,last_line)
-  s = ''
+  local s = ''
   local i = 0 
   for line in io.lines(name) 
   do i = i + 1 
@@ -4843,7 +5142,19 @@
      end
      if i >= last_line then break end 
   end
-  piton.Parse(language,s) 
+%    \end{macrocode}
+% We extract the BOM of utf-8, if present.
+%    \begin{macrocode}
+  if string.byte(s,1) == 13
+  then if string.byte(s,2) == 239
+       then if string.byte(s,3) == 187
+            then if string.byte(s,4) == 191
+                 then s = string.sub(s,5,-1)
+                 end 
+            end
+       end
+  end
+  piton.Parse(language,s)
 end
 %    \end{macrocode}
 % 
@@ -5070,8 +5381,22 @@
 % \nolinkurl{https://tug.org/svn/texlive/trunk/Master/texmf-dist/tex/lualatex/piton/piton.sty}
 % }
 %
-% % \subsection*{Changes between versions 1.4 and 1.5}
+% \medskip
+% The development of the extension \pkg{piton} is done on the following GitHub
+% repository:
 %
+% \verb|https://github.com/fpantigny/piton|
+%
+% \subsection*{Changes between versions 1.5 and 1.6}
+%
+% New key |width| (for the total width of the listing).
+%
+% New style |UserFunction| to format the names of the Python functions
+% previously defined by the user. Command |\PitonClearUserFunctions| to clear
+% the list of such functions names.
+%
+% \subsection*{Changes between versions 1.4 and 1.5}
+%
 % New key |numbers-sep|.
 %
 %

Modified: trunk/Master/texmf-dist/tex/lualatex/piton/piton.sty
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/piton/piton.sty	2023-05-04 20:29:43 UTC (rev 67018)
+++ trunk/Master/texmf-dist/tex/lualatex/piton/piton.sty	2023-05-04 20:30:12 UTC (rev 67019)
@@ -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{1.5a}
-\def\myfiledate{2023/04/11}
+\def\myfileversion{1.6}
+\def\myfiledate{2023/05/03}
 
 
 \NeedsTeXFormat{LaTeX2e}
@@ -141,8 +141,6 @@
 \int_set:Nn \l__piton_splittable_int { 100 }
 \clist_new:N \l__piton_bg_color_clist
 \tl_new:N \l__piton_prompt_bg_color_tl
-\dim_new:N \g__piton_width_dim
-\dim_new:N \l__piton_width_on_aux_dim
 \int_new:N \g__piton_env_int
 \bool_new:N \l__piton_show_spaces_bool
 \bool_new:N \l__piton_break_lines_in_Piton_bool
@@ -154,7 +152,10 @@
 \tl_new:N \l__piton_end_of_broken_line_tl
 \tl_set:Nn \l__piton_end_of_broken_line_tl { \hspace*{0.5em} \textbackslash }
 \bool_new:N \l__piton_break_lines_in_piton_bool
-\bool_new:N \l__piton_slim_bool
+\dim_new:N \l__piton_width_dim
+\dim_new:N \l__piton_line_width_dim
+\bool_new:N \l__piton_width_min_bool
+\dim_new:N \g__piton_tmp_width_dim
 \dim_new:N \l__piton_left_margin_dim
 \bool_new:N \l__piton_left_margin_auto_bool
 \dim_new:N \l__piton_numbers_sep_dim
@@ -203,52 +204,11 @@
 \cs_new_protected:Npn \__piton_prompt:
   {
     \tl_gset:Nn \g__piton_begin_line_hook_tl
-      { \clist_set:NV \l__piton_bg_color_clist \l__piton_prompt_bg_color_tl }
-  }
-\clist_new:N \g__piton_current_style_clist
-\clist_set:Nn \g__piton_current_style_clist { __end }
-\cs_new_protected:Npn \__piton_close_current_styles:
-  {
-    \int_set:Nn \l_tmpa_int { \clist_count:N \g__piton_current_style_clist - 1  }
-    \exp_args:NV \__piton_close_n_styles:n \l_tmpa_int
-  }
-\cs_new_protected:Npn \__piton_close_n_styles:n #1
-  {
-    \int_compare:nNnT { #1 } > 0
       {
-        \__piton_close_brace:
-        \__piton_close_brace:
-        \__piton_close_n_styles:n { #1 - 1 }
+        \tl_if_empty:NF \l__piton_prompt_bg_color_tl % added 2023-04-24
+          { \clist_set:NV \l__piton_bg_color_clist \l__piton_prompt_bg_color_tl }
       }
   }
-\cs_new_protected:Npn \__piton_open_current_styles:
-  { \exp_last_unbraced:NV \__piton_open_styles:w \g__piton_current_style_clist , }
-\cs_new_protected:Npn \__piton_open_styles:w #1 ,
-  {
-    \tl_if_eq:nnF { #1 } { __end }
-      { \__piton_open_brace: #1 \__piton_open_brace: \__piton_open_styles:w }
-  }
-\cs_new_protected:Npn \__piton_pop_style:
-  {
-    \clist_greverse:N \g__piton_current_style_clist
-    \clist_gpop:NN \g__piton_current_style_clist \l_tmpa_tl
-    \clist_gpop:NN \g__piton_current_style_clist \l_tmpa_tl
-    \clist_gpush:Nn \g__piton_current_style_clist { __end }
-    \clist_greverse:N \g__piton_current_style_clist
-  }
-\cs_new_protected:Npn \__piton_push_style:n #1
-  {
-    \clist_greverse:N \g__piton_current_style_clist
-    \clist_gpop:NN \g__piton_current_style_clist \l_tmpa_tl
-    \clist_gpush:Nn \g__piton_current_style_clist { #1 }
-    \clist_gpush:Nn \g__piton_current_style_clist { __end }
-    \clist_greverse:N \g__piton_current_style_clist
-  }
-\cs_new_protected:Npn \__piton_push_and_exec:n #1
-  {
-    \__piton_push_style:n { #1 }
-    \__piton_open_brace: #1 \__piton_open_brace:
-  }
 \cs_new_protected:Npn \__piton_replace_spaces:n #1
   {
     \tl_set:Nn \l_tmpa_tl { #1 }
@@ -271,20 +231,10 @@
     \group_begin:
     \g__piton_begin_line_hook_tl
     \int_gzero:N \g__piton_indentation_int
-    \bool_if:NTF \l__piton_slim_bool
-      { \hcoffin_set:Nn \l_tmpa_coffin }
+    \bool_if:NTF \l__piton_width_min_bool
+      \__piton_put_in_coffin_ii:n
+      \__piton_put_in_coffin_i:n
       {
-        \clist_if_empty:NTF \l__piton_bg_color_clist
-          {
-            \vcoffin_set:Nnn \l_tmpa_coffin
-              { \dim_eval:n { \linewidth - \l__piton_left_margin_dim } }
-          }
-          {
-            \vcoffin_set:Nnn \l_tmpa_coffin
-              { \dim_eval:n { \linewidth - \l__piton_left_margin_dim - 0.5 em } }
-          }
-      }
-      {
         \language = -1
         \raggedright
         \strut
@@ -297,27 +247,22 @@
         \bool_if:NT \l__piton_line_numbers_bool
           {
             \bool_if:NF \l__piton_all_line_numbers_bool
-              { \tl_if_eq:nnF  { #1 } { \PitonStyle {Prompt}{} } } % corrected 2023/04/10
+              { \tl_if_eq:nnF  { #1 } { \PitonStyle {Prompt}{} } }
               \__piton_print_number:
           }
         \clist_if_empty:NF \l__piton_bg_color_clist
           {
             \dim_compare:nNnT \l__piton_left_margin_dim = \c_zero_dim
-               {
-                 \bool_if:NF \l__piton_left_margin_auto_bool
-                   { \skip_horizontal:n { 0.5 em } }
-               }
+               { \skip_horizontal:n { 0.5 em } }
           }
         \coffin_typeset:Nnnnn \l_tmpa_coffin T l \c_zero_dim \c_zero_dim
       }
-    \dim_compare:nNnT { \box_wd:N \l_tmpa_box } > \g__piton_width_dim
-      { \dim_gset:Nn \g__piton_width_dim { \box_wd:N \l_tmpa_box } }
     \box_set_dp:Nn \l_tmpa_box { \box_dp:N \l_tmpa_box + 1.25 pt }
     \box_set_ht:Nn \l_tmpa_box { \box_ht:N \l_tmpa_box + 1.25 pt }
     \clist_if_empty:NTF \l__piton_bg_color_clist
       { \box_use_drop:N \l_tmpa_box }
       {
-        \vbox_top:n
+        \vtop
           {
             \hbox:n
               {
@@ -324,10 +269,9 @@
                 \__piton_color:N \l__piton_bg_color_clist
                 \vrule height \box_ht:N \l_tmpa_box
                        depth \box_dp:N \l_tmpa_box
-                       width \l__piton_width_on_aux_dim
+                       width \l__piton_width_dim
               }
             \skip_vertical:n { - \box_ht_plus_dp:N \l_tmpa_box }
-            \box_set_wd:Nn \l_tmpa_box \l__piton_width_on_aux_dim
             \box_use_drop:N \l_tmpa_box
           }
       }
@@ -335,6 +279,19 @@
     \group_end:
     \tl_gclear:N \g__piton_begin_line_hook_tl
   }
+\cs_set_protected:Npn \__piton_put_in_coffin_i:n
+  { \vcoffin_set:Nnn \l_tmpa_coffin \l__piton_line_width_dim }
+\cs_set_protected:Npn \__piton_put_in_coffin_ii:n #1
+  {
+    \hbox_set:Nn \l_tmpa_box { #1 }
+    \dim_compare:nNnT { \box_wd:N \l_tmpa_box } > \g__piton_tmp_width_dim
+      { \dim_gset:Nn \g__piton_tmp_width_dim { \box_wd:N \l_tmpa_box } }
+    \hcoffin_set:Nn \l_tmpa_coffin
+      {
+        \hbox_to_wd:nn \l__piton_line_width_dim
+          { \hbox_unpack:N \l_tmpa_box \hfil }
+      }
+  }
 \cs_set_protected:Npn \__piton_color:N #1
   {
     \int_set:Nn \l_tmpa_int { \clist_count:N #1 }
@@ -341,7 +298,7 @@
     \int_set:Nn \l_tmpb_int { \int_mod:nn \g__piton_line_int \l_tmpa_int + 1 }
     \tl_set:Nx \l_tmpa_tl { \clist_item:Nn #1 \l_tmpb_int }
     \tl_if_eq:NnTF \l_tmpa_tl { none }
-      { \dim_zero:N \l__piton_width_on_aux_dim }
+      { \dim_zero:N \l__piton_width_dim }
       { \exp_args:NV \__piton_color_i:n \l_tmpa_tl }
   }
 \cs_set_protected:Npn \__piton_color_i:n #1
@@ -365,7 +322,7 @@
           {
             \egroup
             \bool_if:NT \c__piton_footnote_bool { \end { savenotes } }
-            \newline
+            \par \mode_leave_vertical: % \newline
             \bool_if:NT \c__piton_footnote_bool { \begin { savenotes } }
             \vtop \bgroup
           }
@@ -426,8 +383,17 @@
     background-color .value_required:n  = true ,
     prompt-background-color .tl_set:N         = \l__piton_prompt_bg_color_tl ,
     prompt-background-color .value_required:n = true ,
-    slim             .bool_set:N        = \l__piton_slim_bool ,
-    slim             .default:n         = true ,
+    width            .code:n =
+      \str_if_eq:nnTF  { #1 } { min }
+        {
+          \bool_set_true:N \l__piton_width_min_bool
+          \dim_zero:N \l__piton_width_dim
+        }
+        {
+          \bool_set_false:N \l__piton_width_min_bool
+          \dim_set:Nn \l__piton_width_dim { #1 }
+        } ,
+    width            .value_required:n  = true ,
     left-margin      .code:n =
       \str_if_eq:nnTF { #1 } { auto }
         {
@@ -434,7 +400,10 @@
           \dim_zero:N \l__piton_left_margin_dim
           \bool_set_true:N \l__piton_left_margin_auto_bool
         }
-        { \dim_set:Nn \l__piton_left_margin_dim { #1 } } ,
+        {
+          \dim_set:Nn \l__piton_left_margin_dim { #1 }
+          \bool_set_false:N \l__piton_left_margin_auto_bool
+        } ,
     left-margin      .value_required:n  = true ,
     numbers-sep      .dim_set:N         = \l__piton_numbers_sep_dim ,
     numbers-sep      .value_required:n  = true ,
@@ -488,16 +457,10 @@
   }
 \cs_new_protected:Npn \__piton_width_to_aux:
   {
-    \bool_if:NT \l__piton_slim_bool
+    \tl_gput_right:Nx \g__piton_aux_tl
       {
-        \clist_if_empty:NF \l__piton_bg_color_clist
-          {
-            \tl_gput_right:Nx \g__piton_aux_tl
-              {
-                \dim_set:Nn \l__piton_width_on_aux_dim
-                  { \dim_eval:n { \g__piton_width_dim + 0.5 em } }
-              }
-          }
+        \dim_set:Nn \l__piton_line_width_dim
+          { \dim_eval:n { \g__piton_tmp_width_dim } }
       }
   }
 \NewDocumentCommand { \piton } { }
@@ -614,11 +577,11 @@
     \automatichyphenmode = 1
     \int_gincr:N \g__piton_env_int
     \tl_gclear:N \g__piton_aux_tl
+    \dim_compare:nNnT \l__piton_width_dim = \c_zero_dim
+      { \dim_set_eq:NN \l__piton_width_dim \linewidth }
     \cs_if_exist_use:c { c__piton _ \int_use:N \g__piton_env_int _ tl }
-    \dim_compare:nNnT \l__piton_width_on_aux_dim = \c_zero_dim
-      { \dim_set_eq:NN \l__piton_width_on_aux_dim \linewidth }
     \bool_if:NF \l__piton_resume_bool { \int_gzero:N \g__piton_visual_line_int }
-    \dim_gzero:N \g__piton_width_dim
+    \dim_gzero:N \g__piton_tmp_width_dim
     \int_gzero:N \g__piton_line_int
     \dim_zero:N \parindent
     \dim_zero:N \lineskip
@@ -632,60 +595,55 @@
     last-line .int_set:N = \l__piton_last_line_int ,
     last-line .value_required:n = true ,
   }
-\NewDocumentCommand { \PitonInputFile } { d < > O { } m }
+\cs_new_protected:Npn \__piton_compute_left_margin:nn #1 #2
   {
-    \tl_if_novalue:nF { #1 }
+    \bool_lazy_and:nnT \l__piton_left_margin_auto_bool \l__piton_line_numbers_bool
+       {
+        \hbox_set:Nn \l_tmpa_box
+          {
+            \footnotesize
+            \bool_if:NTF \l__piton_all_line_numbers_bool
+              {
+                \int_to_arabic:n
+                  { \g__piton_visual_line_int + \l__piton_nb_lines_int }
+              }
+              {
+                \lua_now:n
+                  { piton.#1(token.scan_argument()) }
+                  { #2 }
+                \int_to_arabic:n
+                  { \g__piton_visual_line_int + \l__piton_nb_non_empty_lines_int }
+               }
+           }
+         \dim_set:Nn \l__piton_left_margin_dim
+           { \box_wd:N \l_tmpa_box + \l__piton_numbers_sep_dim + 0.1 em }
+       }
+  }
+\cs_new_protected:Npn \__piton_compute_width:
+  {
+    \dim_compare:nNnTF \l__piton_line_width_dim = \c_zero_dim
       {
-        \bool_if:NTF \c__piton_beamer_bool
-          { \begin { uncoverenv } < #1 > }
-          { \msg_error:nn { piton } { overlay~without~beamer } }
+        \dim_set_eq:NN \l__piton_line_width_dim \l__piton_width_dim
+        \clist_if_empty:NTF \l__piton_bg_color_clist
+          { \dim_sub:Nn \l__piton_line_width_dim \l__piton_left_margin_dim }
+          {
+            \dim_sub:Nn \l__piton_line_width_dim { 0.5 em }
+            \dim_compare:nNnTF \l__piton_left_margin_dim = \c_zero_dim
+              { \dim_sub:Nn \l__piton_line_width_dim { 0.5 em } }
+              { \dim_sub:Nn \l__piton_line_width_dim \l__piton_left_margin_dim }
+          }
       }
-    \group_begin:
-      \int_zero_new:N \l__piton_first_line_int
-      \int_zero_new:N \l__piton_last_line_int
-      \int_set_eq:NN \l__piton_last_line_int \c_max_int
-      \keys_set:nn { PitonInputFile } { #2 }
-      \__piton_pre_env:
-      \mode_if_vertical:TF \mode_leave_vertical: \newline
-      \lua_now:n { piton.CountLinesFile(token.scan_argument()) } { #3 }
-      \bool_lazy_and:nnT \l__piton_left_margin_auto_bool \l__piton_line_numbers_bool
-        {
-         \hbox_set:Nn \l_tmpa_box
-           {
-             \footnotesize
-             \bool_if:NTF \l__piton_all_line_numbers_bool
-               {
-                 \int_to_arabic:n
-                   { \g__piton_visual_line_int + \l__piton_nb_lines_int }
-               }
-               {
-                 \lua_now:n
-                   { piton.CountNonEmptyLinesFile(token.scan_argument()) }
-                   { #3 }
-                 \int_to_arabic:n
-                   { \g__piton_visual_line_int + \l__piton_nb_non_empty_lines_int }
-                }
-            }
-          \dim_set:Nn \l__piton_left_margin_dim
-            { \box_wd:N \l_tmpa_box + \l__piton_numbers_sep_dim + 0.1 em }
-        }
-      \ttfamily
-      \bool_if:NT \c__piton_footnote_bool { \begin { savenotes } }
-      \vtop \bgroup
-      \lua_now:e
-        {
-          piton.ParseFile('\l__piton_language_str',token.scan_argument() ,
-           \int_use:N \l__piton_first_line_int ,
-           \int_use:N \l__piton_last_line_int )
-        }
-        { #3 }
-      \egroup
-      \bool_if:NT \c__piton_footnote_bool { \end { savenotes } }
-      \__piton_width_to_aux:
-    \group_end:
-    \tl_if_novalue:nF { #1 }
-      { \bool_if:NT \c__piton_beamer_bool { \end { uncoverenv } } }
-    \__piton_write_aux:
+      {
+        \dim_set_eq:NN \l__piton_width_dim \l__piton_line_width_dim
+        \clist_if_empty:NTF \l__piton_bg_color_clist
+          { \dim_add:Nn \l__piton_width_dim \l__piton_left_margin_dim }
+          {
+            \dim_add:Nn \l__piton_width_dim { 0.5 em }
+            \dim_compare:nNnTF \l__piton_left_margin_dim = \c_zero_dim
+              { \dim_add:Nn \l__piton_width_dim { 0.5 em } }
+              { \dim_add:Nn \l__piton_width_dim \l__piton_left_margin_dim }
+          }
+      }
   }
 \NewDocumentCommand { \NewPitonEnvironment } { m m m m }
   {
@@ -696,35 +654,12 @@
           ####1
           \c_backslash_str end \c_left_brace_str #1 \c_right_brace_str
       }
-          {
+         {
             \group_end:
             \mode_if_vertical:TF \mode_leave_vertical: \newline
             \lua_now:n { piton.CountLines(token.scan_argument()) } { ##1 }
-            \bool_lazy_and:nnT \l__piton_left_margin_auto_bool \l__piton_line_numbers_bool
-              {
-                \bool_if:NTF \l__piton_all_line_numbers_bool
-                  {
-                    \hbox_set:Nn \l_tmpa_box
-                      {
-                        \footnotesize
-                        \int_to_arabic:n
-                          { \g__piton_visual_line_int + \l__piton_nb_lines_int }
-                      }
-                  }
-                  {
-                    \lua_now:n
-                      { piton.CountNonEmptyLines(token.scan_argument()) }
-                      { ##1 }
-                    \hbox_set:Nn \l_tmpa_box
-                      {
-                        \footnotesize
-                        \int_to_arabic:n
-                          { \g__piton_visual_line_int + \l__piton_nb_non_empty_lines_int }
-                      }
-                  }
-                \dim_set:Nn \l__piton_left_margin_dim
-                  { \box_wd:N \l_tmpa_box + \l__piton_numbers_sep_dim + 0.1 em }
-              }
+            \__piton_compute_left_margin:nn { CountNonEmptyLines } { ##1 }
+            \__piton_compute_width:
             \ttfamily
             \bool_if:NT \c__piton_footnote_bool { \begin { savenotes } }
             \vtop \bgroup
@@ -741,7 +676,7 @@
             \vspace { 2.5 pt }
             \egroup
             \bool_if:NT \c__piton_footnote_bool { \end { savenotes } }
-            \__piton_width_to_aux:
+            \bool_if:NT \l__piton_width_min_bool \__piton_width_to_aux:
             \end { #1 }
             \__piton_write_aux:
           }
@@ -769,6 +704,50 @@
       { \end { uncoverenv } }
   }
   { \NewPitonEnvironment { Piton } { } { } { } }
+\NewDocumentCommand { \PitonInputFile } { d < > O { } m }
+  {
+    \file_if_exist:nTF { #3 }
+      { \__piton_input_file:nnn { #1 } { #2 } { #3 } }
+      { \msg_error:nnn { piton } { unknown~file } { #3 } }
+  }
+\cs_new_protected:Npn \__piton_input_file:nnn #1 #2 #3
+  {
+    \tl_if_novalue:nF { #1 }
+      {
+        \bool_if:NTF \c__piton_beamer_bool
+          { \begin { uncoverenv } < #1 > }
+          { \msg_error:nn { piton } { overlay~without~beamer } }
+      }
+    \group_begin:
+      \int_zero_new:N \l__piton_first_line_int
+      \int_zero_new:N \l__piton_last_line_int
+      \int_set_eq:NN \l__piton_last_line_int \c_max_int
+      \keys_set:nn { PitonInputFile } { #2 }
+      \__piton_pre_env:
+      \mode_if_vertical:TF \mode_leave_vertical: \newline
+      \lua_now:n { piton.CountLinesFile(token.scan_argument()) } { #3 }
+      \__piton_compute_left_margin:nn { CountNonEmptyLinesFile } { #3 }
+      \__piton_compute_width:
+      \ttfamily
+      \bool_if:NT \c__piton_footnote_bool { \begin { savenotes } }
+      \vtop \bgroup
+      \lua_now:e
+        {
+          piton.ParseFile(
+           '\l__piton_language_str',
+           token.scan_argument() ,
+           \int_use:N \l__piton_first_line_int ,
+           \int_use:N \l__piton_last_line_int )
+        }
+        { #3 }
+      \egroup
+      \bool_if:NT \c__piton_footnote_bool { \end { savenotes } }
+      \bool_if:NT \l__piton_width_min_bool \__piton_width_to_aux:
+    \group_end:
+    \tl_if_novalue:nF { #1 }
+      { \bool_if:NT \c__piton_beamer_bool { \end { uncoverenv } } }
+    \__piton_write_aux:
+  }
 \NewDocumentCommand { \PitonStyle } { m } { \use:c { pitonStyle #1 } }
 \NewDocumentCommand { \SetPitonStyle } { } { \keys_set:nn { piton / Styles } }
 \cs_new_protected:Npn \__piton_math_scantokens:n #1
@@ -783,10 +762,12 @@
     Dict.Value        .value_required:n = true ,
     Name.Decorator    .tl_set:c = pitonStyle Name.Decorator ,
     Name.Decorator    .value_required:n = true ,
+    Name.Field        .tl_set:c = pitonStyle Name.Field ,
+    Name.Field        .value_required:n = true ,
     Name.Function     .tl_set:c = pitonStyle Name.Function ,
     Name.Function     .value_required:n = true ,
-    Name.UserFunction .tl_set:c = pitonStyle Name.UserFunction ,
-    Name.UserFunction .value_required:n = true ,
+    UserFunction      .tl_set:c = pitonStyle UserFunction ,
+    UserFunction      .value_required:n = true ,
     Keyword           .tl_set:c = pitonStyle Keyword ,
     Keyword           .value_required:n = true ,
     Keyword.Constant  .tl_set:c = pitonStyle Keyword.Constant ,
@@ -805,6 +786,8 @@
     Comment.Math      .initial:n = ,
     Comment           .tl_set:c = pitonStyle Comment ,
     Comment           .value_required:n = true ,
+    Name.Constructor  .tl_set:c = pitonStyle Name.Constructor ,
+    Name.Constructor  .value_required:n = true ,
     InitialValues     .tl_set:c = pitonStyle InitialValues ,
     InitialValues     .value_required:n = true ,
     Number            .tl_set:c = pitonStyle Number ,
@@ -811,6 +794,8 @@
     Number            .value_required:n = true ,
     Name.Namespace    .tl_set:c = pitonStyle Name.Namespace ,
     Name.Namespace    .value_required:n = true ,
+    Name.Module       .tl_set:c = pitonStyle Name.Module ,
+    Name.Module       .value_required:n = true ,
     Name.Class        .tl_set:c = pitonStyle Name.Class ,
     Name.Class        .value_required:n = true ,
     Name.Builtin      .tl_set:c = pitonStyle Name.Builtin ,
@@ -853,9 +838,13 @@
     Keyword.Constant,~
     Name.Builtin,~
     Name.Class,~
+    Name.Constructor,~
     Name.Decorator,~
+    Name.Field,~
     Name.Function,~
+    Name.Module,~
     Name.Namespace,~
+    UserFunction,~
     Number,~
     Operator,~
     Operator.Word,~
@@ -877,6 +866,9 @@
     Name.Class         = \color[HTML]{00AA88} \bfseries ,
     Name.Function      = \color[HTML]{CC00FF} ,
     Name.Namespace     = \color[HTML]{00CCFF} ,
+    Name.Constructor   = \color[HTML]{006000} \bfseries ,
+    Name.Field         = \color[HTML]{AA6600} ,
+    Name.Module        = \color[HTML]{0060A0} \bfseries ,
     Number             = \color[HTML]{FF6600} ,
     Operator           = \color[HTML]{555555} ,
     Operator.Word      = \bfseries ,
@@ -888,9 +880,9 @@
     InitialValues      = \__piton_piton:n ,
     Dict.Value         = \__piton_piton:n ,
     Interpol.Inside    = \color{black}\__piton_piton:n ,
-    TypeParameter      = \color[HTML]{008800} \itshape ,
+    TypeParameter      = \color[HTML]{336666} \itshape ,
     Identifier         = \__piton_identifier:n ,
-    Name.UserFunction  = ,
+    UserFunction  = ,
     Prompt             = ,
     ParseAgain.noCR    = \__piton_piton_no_cr:n ,
     ParseAgain         = \__piton_piton:n ,
@@ -921,7 +913,7 @@
   {
     { \PitonStyle { Name.Function } { #1 } }
     \cs_gset_protected:cpn { PitonIdentifier _ \l__piton_language_str _ #1 }
-      { \PitonStyle{ Name.UserFunction } }
+      { \PitonStyle { UserFunction } }
     \seq_if_exist:cF { g__piton_functions _ \l__piton_language_str _ seq }
       { \seq_new:c { g__piton_functions _ \l__piton_language_str _ seq } }
     \seq_gput_right:cn { g__piton_functions _ \l__piton_language_str _ seq } { #1 }
@@ -945,6 +937,12 @@
     \token_to_str:N \piton\ but~there~is~no~environment~
     {piton}.~This~error~is~fatal.
   }
+\msg_new:nnn { piton } { unknown~file }
+  {
+    Unknown~file. \\
+    The~file~'#1'~is~unknown.\\
+    Your~command~\token_to_str:N \PitonInputFile\ will~be~discarded.
+  }
 \msg_new:nnnn { piton } { Unknown~key~for~PitonOptions }
   {
     Unknown~key. \\
@@ -974,10 +972,9 @@
     resume,~
     show-spaces,~
     show-spaces-in-strings,~
-    slim,~
     splittable,~
-    tabs-auto-gobble~
-    and~tab-size.
+    tabs-auto-gobble,~
+    tab-size~and~width.
   }
 \msg_new:nnn { piton } { label~with~lines~numbers }
   {
@@ -1084,7 +1081,7 @@
     )
 
 local OperatorWord =
-  K ( 'Operator.Word' ,P "in" + P "is" + P "and" + P "or" + P "not" )
+  K ( 'Operator.Word' , P "in" + P "is" + P "and" + P "or" + P "not" )
 
 local Keyword =
   K ( 'Keyword' ,
@@ -1211,7 +1208,7 @@
          * Q ( P "\"" ) )
 
 local ShortString = SingleShortString + DoubleShortString
-local BalancedBraces =
+local balanced_braces =
   P { "E" ,
        E =
            (
@@ -1228,11 +1225,6 @@
 local BeamerNamesEnvironments =
   P "uncoverenv" + P "onlyenv" + P "visibleenv" + P "invisibleenv"
   + P "alertenv" + P "actionenv"
-
-UserCommands =
-       Ct ( Cc "Open" * C ( "\\emph{" ) * Cc "}" )
-     * ( C ( BalancedBraces ) / (function (s) return MainLoopPython:match(s) end ) )
-     * P "}" * Ct ( Cc "Close" )
 function OneBeamerEnvironment(name)
   return
       Ct ( Cc "Open"
@@ -1244,7 +1236,7 @@
           )
      * (
          C ( ( 1 - P ( "\\end{" .. name .. "}" ) ) ^ 0 )
-         / (function (s) return MainLoopPython:match(s) end )
+         / ( function (s) return MainLoopPython:match(s) end )
        )
      * P ( "\\end{" .. name ..  "}" ) * Ct ( Cc "Close" )
 end
@@ -1251,7 +1243,7 @@
 if piton_beamer
 then
   Beamer =
-      L  ( P "\\pause" * ( P "[" * (1 - P "]") ^ 0 * P "]" ) ^ -1 )
+      L ( P "\\pause" * ( P "[" * ( 1 - P "]" ) ^ 0 * P "]" ) ^ -1 )
     +
       Ct ( Cc "Open"
             * C (
@@ -1264,10 +1256,9 @@
                 )
             * Cc "}"
          )
-       * ( C ( BalancedBraces ) / (function (s) return MainLoopPython:match(s) end ) )
+       * ( C ( balanced_braces ) / (function (s) return MainLoopPython:match(s) end ) )
        * P "}" * Ct ( Cc "Close" )
-    +
-      OneBeamerEnvironment "uncoverenv"
+    + OneBeamerEnvironment "uncoverenv"
     + OneBeamerEnvironment "onlyenv"
     + OneBeamerEnvironment "visibleenv"
     + OneBeamerEnvironment "invisibleenv"
@@ -1279,9 +1270,9 @@
           * P "<" * (1 - P ">") ^ 0 * P ">"
           * P "{"
         )
-      * K ( 'ParseAgain.noCR' , BalancedBraces )
+      * K ( 'ParseAgain.noCR' , balanced_braces )
       * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces )
+      * K ( 'ParseAgain.noCR' , balanced_braces )
       * L ( P "}" )
     +
       L (
@@ -1289,11 +1280,11 @@
           * P "<" * (1 - P ">") ^ 0 * P ">"
           * P "{"
         )
-      * K ( 'ParseAgain.noCR' , BalancedBraces )
+      * K ( 'ParseAgain.noCR' , balanced_braces )
       * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces )
+      * K ( 'ParseAgain.noCR' , balanced_braces )
       * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces )
+      * K ( 'ParseAgain.noCR' , balanced_braces )
       * L ( P "}" )
   BeamerBeginEnvironments =
       ( space ^ 0 *
@@ -1408,29 +1399,25 @@
   * Lc "{\\PitonStyle{Comment.LaTeX}{\\ignorespaces"
   * L ( ( 1 - P "\r" ) ^ 0 )
   * Lc "}}"
-  * ( EOL + -1 )  -- you could put EOL instead of EOL
-local Expression =
+  * ( EOL + -1 )
+local expression =
   P { "E" ,
-       E = ( 1 - S "{}()[]\r," ) ^ 0
-           *  (
-                (   P "{" * V "F" * P "}"
-                  + P "(" * V "F" * P ")"
-                  + P "[" * V "F" * P "]" ) * ( 1 - S "{}()[]\r," ) ^ 0
-              ) ^ 0 ,
-       F = ( 1 - S "{}()[]\r\"'" ) ^ 0
-           * ( (
-                   P "'" * (P "\\'" + 1 - S"'\r" )^0 * P "'"
-                 + P "\"" * (P "\\\"" + 1 - S"\"\r" )^0 * P "\""
-                 + P "{"  * V "F" * P "}"
-                 + P "(" * V "F" * P ")"
-                 + P "[" * V "F" * P "]"
-               ) * ( 1 - S "{}()[]\r\"'" ) ^ 0 ) ^ 0 ,
+       E = ( P "'" * ( P "\\'" + 1 - S "'\r" ) ^ 0 * P "'"
+             + P "\"" * (P "\\\"" + 1 - S "\"\r" ) ^ 0 * P "\""
+             + P "{" * V "F" * P "}"
+             + P "(" * V "F" * P ")"
+             + P "[" * V "F" * P "]"
+             + ( 1 - S "{}()[]\r," ) ) ^ 0 ,
+       F = ( P "{" * V "F" * P "}"
+             + P "(" * V "F" * P ")"
+             + P "[" * V "F" * P "]"
+             + ( 1 - S "{}()[]\r\"'" ) ) ^ 0
     }
 local Param =
   SkipSpace * Identifier * SkipSpace
    * (
-         K ( 'InitialValues' , P "=" * Expression )
-       + Q ( P ":" ) * SkipSpace * K ( 'Name.Type' , letter^1  )
+         K ( 'InitialValues' , P "=" * expression )
+       + Q ( P ":" ) * SkipSpace * K ( 'Name.Type' , letter ^ 1  )
      ) ^ -1
 local Params = ( Param * ( Q "," * Param ) ^ 0 ) ^ -1
 local DefFunction =
@@ -1450,7 +1437,7 @@
       * StringDoc ^ 0 -- there may be additionnal docstrings
     ) ^ -1
 local ItemDict =
-  ShortString * SkipSpace * Q ( P ":" ) * K ( 'Dict.Value' , Expression  )
+  ShortString * SkipSpace * Q ( P ":" ) * K ( 'Dict.Value' , expression  )
 
 local ItemOfSet = SkipSpace * ( ItemDict + ShortString ) * SkipSpace
 
@@ -1459,15 +1446,13 @@
   * ItemOfSet * ( Q ( P "," ) * ItemOfSet )  ^ 0
   * Q ( P "}" )
 local ExceptionInConsole = Exception *  Q ( ( 1 - P "\r" ) ^ 0 ) * EOL
-MainLoopPython =
-  (  ( space^1 * -1 )
-     + EOL
+local MainPython =
+       EOL
      + Space
      + Tab
      + Escape
      + CommentLaTeX
      + Beamer
-     + UserCommands
      + LongString
      + Comment
      + ExceptionInConsole
@@ -1474,6 +1459,7 @@
      + Set
      + Delim
      + Operator
+     + OperatorWord * ( Space + Punct + Delim + EOL + -1 )
      + ShortString
      + Punct
      + FromImport
@@ -1480,13 +1466,15 @@
      + RaiseException
      + DefFunction
      + DefClass
-     + Keyword * ( Space + Punct + Delim + EOL+ -1 )
+     + Keyword * ( Space + Punct + Delim + EOL + -1 )
      + Decorator
-     + OperatorWord * ( Space + Punct + Delim + EOL+ -1 )
-     + Builtin * ( Space + Punct + Delim + EOL+ -1 )
+     + Builtin * ( Space + Punct + Delim + EOL + -1 )
      + Identifier
      + Number
      + Word
+MainLoopPython =
+  (  ( space^1 * -1 )
+     + MainPython
   ) ^ 0
 local python = P ( true )
 
@@ -1506,11 +1494,60 @@
 languages['python'] = python
 local Delim = Q ( P "[|" + P "|]" + S "[()]" )
 local Punct = Q ( S ",:;!" )
+local cap_identifier = R "AZ" * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0
+local Constructor = K ( 'Name.Constructor' , cap_identifier )
+local ModuleType = K ( 'Name.Type' , cap_identifier )
 local identifier =
-  ( R "az" + R "AZ" + P "_") * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0
-
+  ( R "az" + P "_") * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0
 local Identifier = K ( 'Identifier' , identifier )
+local expression_for_fields =
+  P { "E" ,
+       E = ( P "{" * V "F" * P "}"
+             + P "(" * V "F" * P ")"
+             + P "[" * V "F" * P "]"
+             + P "\"" * (P "\\\"" + 1 - S "\"\r" )^0 * P "\""
+             + P "'" * ( P "\\'" + 1 - S "'\r" )^0 * P "'"
+             + ( 1 - S "{}()[]\r;" ) ) ^ 0 ,
+       F = ( P "{" * V "F" * P "}"
+             + P "(" * V "F" * P ")"
+             + P "[" * V "F" * P "]"
+             + ( 1 - S "{}()[]\r\"'" ) ) ^ 0
+    }
+local OneFieldDefinition =
+    ( K ( 'KeyWord' , P "mutable" ) * SkipSpace ) ^ -1
+  * K ( 'Name.Field' , identifier ) * SkipSpace
+  * Q ":" * SkipSpace
+  * K ( 'Name.Type' , expression_for_fields )
+  * SkipSpace
 
+local OneField =
+    K ( 'Name.Field' , identifier ) * SkipSpace
+  * Q "=" * SkipSpace
+  * ( C ( expression_for_fields ) / ( function (s) return LoopOCaml:match(s) end ) )
+  * SkipSpace
+
+local Record =
+  Q "{" * SkipSpace
+  *
+    (
+      OneFieldDefinition * ( Q ";" * SkipSpace * OneFieldDefinition ) ^ 0
+      +
+      OneField * ( Q ";" * SkipSpace * OneField ) ^ 0
+    )
+  *
+  Q "}"
+local DotNotation =
+  (
+      K ( 'Name.Module' , cap_identifier )
+        * Q "."
+        * ( Identifier + Constructor + Q "(" + Q "[" + Q "{" )
+
+      +
+      Identifier
+        * Q "."
+        * K ( 'Name.Field' , identifier )
+  )
+  * ( Q "." * K ( 'Name.Field' , identifier ) ) ^ 0
 local Operator =
   K ( 'Operator' ,
       P "!=" + P "<>" + P "==" + P "<<" + P ">>" + P "<=" + P ">=" + P ":="
@@ -1526,10 +1563,10 @@
 
 local Keyword =
   K ( 'Keyword' ,
-      P "as" + P "assert" + P "begin" + P "class" + P "constraint" + P "done"
-  + P "do" + P "downto" + P "else" + P "end" + P "exception" + P "external"
-  + P "false" + P "for" + P "function" + P "fun" + P "functor" + P "if"
-  + P "in" + P "include" + P "inherit" + P "initializer" + P "lazy" + P "let"
+      P "assert" + P "as" + P "begin" + P "class" + P "constraint" + P "done"
+  + P "downto" + P "do" + P "else" + P "end" + P "exception" + P "external"
+  + P "false" + P "for" + P "function" + P "functor" + P "fun"  + P "if"
+  + P "include" + P "inherit" + P "initializer" + P "in"  + P "lazy" + P "let"
   + P "match" + P "method" + P "module" + P "mutable" + P "new" + P "object"
   + P "of" + P "open" + P "private" + P "raise" + P "rec" + P "sig"
   + P "struct" + P "then" + P "to" + P "true" + P "try" + P "type"
@@ -1537,20 +1574,7 @@
   + K ( 'Keyword.Constant' , P "true" + P "false" )
 
 local Builtin =
-  K ( 'Name.Builtin' ,
-        P "not" + P "incr" + P "decr" + P "fst" + P "snd"
-      + P "String.length"
-      + P "List.tl" + P "List.hd" + P "List.mem" + P "List.exists"
-      + P "List.for_all" + P "List.filter" + P "List.length" + P "List.map"
-      + P "List.iter"
-      + P "Array.length" + P "Array.make" + P "Array.make_matrix"
-      + P "Array.init" + P "Array.copy" + P "Array.copy" + P "Array.mem"
-      + P "Array.exists" + P "Array.for_all" + P "Array.map" + P "Array.iter"
-      + P "Queue.create" + P "Queue.is_empty" + P "Queue.push" + P "Queue.pop"
-      + P "Stack.create" + P "Stack.is_empty" + P "Stack.push" + P "Stack.pop"
-      + P "Hashtbl.create" + P "Hashtbl.add" + P "Hashtbl.remove"
-      + P "Hashtbl.mem" + P "Hashtbl.find" + P "Hashtbl.find_opt"
-      + P "Hashtbl.iter" )
+  K ( 'Name.Builtin' , P "not" + P "incr" + P "decr" + P "fst" + P "snd" )
 local Exception =
   K (   'Exception' ,
        P "Division_by_zero" + P "End_of_File" + P "Failure"
@@ -1559,7 +1583,7 @@
      + P "Sys_error" + P "Undefined_recursive_module" )
 local Char =
   K ( 'String.Short' , P "'" * ( ( 1 - P "'" ) ^ 0 + P "\\'" ) * P "'" )
-local BalancedBraces =
+local balanced_braces =
   P { "E" ,
        E =
            (
@@ -1584,7 +1608,7 @@
       )
       *
       L ( ( P "<" * (1 - P ">") ^ 0 * P ">" ) ^ -1 * P "{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces )
+      * K ( 'ParseAgain.noCR' , balanced_braces )
       * L ( P "}" )
     +
       L (
@@ -1592,9 +1616,9 @@
           * P "<" * (1 - P ">") ^ 0 * P ">"
           * P "{"
         )
-      * K ( 'ParseAgain.noCR' , BalancedBraces )
+      * K ( 'ParseAgain.noCR' , balanced_braces )
       * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces )
+      * K ( 'ParseAgain.noCR' , balanced_braces )
       * L ( P "}" )
     +
       L (
@@ -1602,11 +1626,11 @@
           * P "<" * (1 - P ">") ^ 0 * P ">"
           * P "{"
         )
-      * K ( 'ParseAgain.noCR' , BalancedBraces )
+      * K ( 'ParseAgain.noCR' , balanced_braces )
       * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces )
+      * K ( 'ParseAgain.noCR' , balanced_braces )
       * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces )
+      * K ( 'ParseAgain.noCR' , balanced_braces )
       * L ( P "}" )
   BeamerBeginEnvironments =
       ( space ^ 0 *
@@ -1644,7 +1668,7 @@
   )
   *
   SpaceIndentation ^ 0
-local string =
+local ocaml_string =
        Q ( P "\"" )
      * (
          VisualSpace
@@ -1654,7 +1678,7 @@
          EOL
        ) ^ 0
      * Q ( P "\"" )
-local String = WithStyle ( 'String.Long' , string )
+local String = WithStyle ( 'String.Long' , ocaml_string )
 local ext = ( R "az" + P "_" ) ^ 0
 local open = "{" * Cg(ext, 'init') * "|"
 local close = "|" * C(ext) * "}"
@@ -1681,22 +1705,92 @@
          A = Q "(*"
              * ( V "A"
                  + Q ( ( 1 - P "(*" - P "*)" - S "\r$\"" ) ^ 1 ) -- $
-                 + string
+                 + ocaml_string
                  + P "$" * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1 ) * P "$" -- $
                  + EOL
                ) ^ 0
              * Q "*)"
        }   )
+local balanced_parens =
+  P { "E" ,
+       E =
+           (
+             P "(" * V "E" * P ")"
+             +
+             ( 1 - S "()" )
+           ) ^ 0
+    }
+local Argument =
+  K ( 'Identifier' , identifier )
+  + Q "(" * SkipSpace
+    * K ( 'Identifier' , identifier ) * SkipSpace
+    * Q ":" * SkipSpace
+    * K ( 'Name.Type' , balanced_parens ) * SkipSpace
+    * Q ")"
 local DefFunction =
+  K ( 'Keyword' , P "let open" )
+   * Space
+   * K ( 'Name.Module' , cap_identifier )
+  +
   K ( 'Keyword' , P "let rec" + P "let" + P "and" )
-  * Space
-  * K ( 'Name.Function.Internal' , identifier )
-  * Space
-  * # ( P "=" * space * P "function" + ( 1 - P "=" ) )
+    * Space
+    * K ( 'Name.Function.Internal' , identifier )
+    * Space
+    * (
+        Q "=" * SkipSpace * K ( 'Keyword' , P "function" )
+        +
+        Argument
+         * ( SkipSpace * Argument ) ^ 0
+         * (
+             SkipSpace
+             * Q ":"
+             * K ( 'Name.Type' , ( 1 - P "=" ) ^ 0 )
+           ) ^ -1
+      )
+local DefModule =
+  K ( 'Keyword' , P "module" ) * Space
+  *
+    (
+          K ( 'Keyword' , P "type" ) * Space
+        * K ( 'Name.Type' , cap_identifier )
+      +
+        K ( 'Name.Module' , cap_identifier ) * SkipSpace
+        *
+          (
+            Q "(" * SkipSpace
+              * K ( 'Name.Module' , cap_identifier ) * SkipSpace
+              * Q ":" * SkipSpace
+              * K ( 'Name.Type' , cap_identifier ) * SkipSpace
+              *
+                (
+                  Q "," * SkipSpace
+                    * K ( 'Name.Module' , cap_identifier ) * SkipSpace
+                    * Q ":" * SkipSpace
+                    * K ( 'Name.Type' , cap_identifier ) * SkipSpace
+                ) ^ 0
+              * Q ")"
+          ) ^ -1
+        *
+          (
+            Q "=" * SkipSpace
+            * K ( 'Name.Module' , cap_identifier )  * SkipSpace
+            * Q "("
+            * K ( 'Name.Module' , cap_identifier ) * SkipSpace
+              *
+              (
+                Q ","
+                *
+                K ( 'Name.Module' , cap_identifier ) * SkipSpace
+              ) ^ 0
+            * Q ")"
+          ) ^ -1
+    )
+  +
+  K ( 'Keyword' , P "include" + P "open" )
+  * Space * K ( 'Name.Module' , cap_identifier )
 local TypeParameter = K ( 'TypeParameter' , P "'" * alpha * # ( 1 - P "'" ) )
-MainLoopOCaml =
-  (  ( space^1 * -1 )
-     + EOL
+MainOCaml =
+       EOL
      + Space
      + Tab
      + Escape
@@ -1708,15 +1802,24 @@
      + Operator
      + Punct
      + FromImport
-     + ImportAs
      + Exception
      + DefFunction
+     + DefModule
+     + Record
      + Keyword * ( Space + Punct + Delim + EOL + -1 )
      + OperatorWord * ( Space + Punct + Delim + EOL + -1 )
      + Builtin * ( Space + Punct + Delim + EOL + -1 )
+     + DotNotation
+     + Constructor
      + Identifier
      + Number
      + Word
+
+LoopOCaml = MainOCaml ^ 0
+
+MainLoopOCaml =
+  (  ( space^1 * -1 )
+     + MainOCaml
   ) ^ 0
 local ocaml = P ( true )
 
@@ -1740,13 +1843,13 @@
      if one_item[1] == "EOL"
      then
           for _ , s in ipairs(right_stack)
-            do tex.sprint( s )
+            do tex.sprint(s)
             end
           for _ , s in ipairs(one_item[2])
             do tex.tprint(s)
             end
           for _ , s in ipairs(left_stack)
-            do tex.sprint( s )
+            do tex.sprint(s)
             end
      else
           if one_item[1] == "Open"
@@ -1768,7 +1871,7 @@
   end
 end
 function piton.ParseFile(language,name,first_line,last_line)
-  s = ''
+  local s = ''
   local i = 0
   for line in io.lines(name)
   do i = i + 1
@@ -1777,6 +1880,15 @@
      end
      if i >= last_line then break end
   end
+  if string.byte(s,1) == 13
+  then if string.byte(s,2) == 239
+       then if string.byte(s,3) == 187
+            then if string.byte(s,4) == 191
+                 then s = string.sub(s,5,-1)
+                 end
+            end
+       end
+  end
   piton.Parse(language,s)
 end
 function piton.ParseBis(language,code)



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