From 45c7bac9080d91b53c686e776fc6217d7f139b86 Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Wed, 12 Apr 2023 03:01:14 +0000
Subject: CTAN sync 202304120301

---
 macros/luatex/latex/piton/piton.dtx | 10335 +++++++++++++++++-----------------
 1 file changed, 5174 insertions(+), 5161 deletions(-)

(limited to 'macros/luatex/latex/piton/piton.dtx')

diff --git a/macros/luatex/latex/piton/piton.dtx b/macros/luatex/latex/piton/piton.dtx
index 8d8caee54f..4f1d4290a1 100644
--- a/macros/luatex/latex/piton/piton.dtx
+++ b/macros/luatex/latex/piton/piton.dtx
@@ -1,5161 +1,5174 @@
-% \iffalse -*- coding: utf-8 ; -*- \fi \iffalse meta-comment
-%
-% Copyright (C) 2023 by F. Pantigny
-% -----------------------------------
-%
-% This file may be distributed and/or modified under the
-% conditions of the LaTeX Project Public License, either version 1.3
-% of this license or (at your option) any later version.
-% The latest version of this license is in:
-%
-% http://www.latex-project.org/lppl.txt
-%
-% and version 1.3 or later is part of all distributions of LaTeX
-% version 2005/12/01 or later.
-%
-% \fi
-% \iffalse
-\def\myfileversion{1.5}
-\def\myfiledate{2023/04/04}
-%
-%
-%<*batchfile> 
-\begingroup
-\input l3docstrip.tex
-\keepsilent
-\usedir{tex/latex/cascade}
-\preamble
-
-Copyright (C) 2022-2023 by F. Pantigny
------------------------------------
-
-This file may be distributed and/or modified under the
-conditions of the LaTeX Project Public License, either version 1.3
-of this license or (at your option) any later version.
-The latest version of this license is in:
-
-http://www.latex-project.org/lppl.txt
-
-and version 1.3 or later is part of all distributions of LaTeX
-version 2005/12/01 or later.
-
-\endpreamble
-\askforoverwritefalse
-\endgroup
-%</batchfile>
-%
-%<@@=piton>
-%<*driver>
-\documentclass{l3doc}
-\usepackage{geometry}
-\geometry{left=2.8cm,right=2.8cm,top=2.5cm,bottom=2.5cm,papersize={21cm,29.7cm}}
-\usepackage{fontspec}
-\usepackage[dvipsnames]{xcolor}
-\usepackage{caption,tabularx,tcolorbox,luacolor,lua-ul}
-\def\emphase{\bgroup\color{RoyalPurple}\let\next=}
-\fvset{commandchars=\~\#\@,formatcom=\color{gray}}
-\captionsetup{labelfont = bf}
-\usepackage{ragged2e}
-\usepackage[footnotehyper,escape-inside=$$,math-comments]{piton} % $$
-
-\parindent 0pt
-\skip\footins = 2\bigskipamount
-
-\PitonOptions{gobble=2}
-
-\EnableCrossrefs
-
-\begin{document}
-\DocInput{piton.dtx}
-\end{document}
-%</driver>
-% \fi
-%
-% \catcode`\" = 11 
-% 
-% \title{The package \pkg{piton}\thanks{This document corresponds to the
-% version~\myfileversion\space of \pkg{piton}, at the date of~\myfiledate.}} 
-% \author{F. Pantigny \\ \texttt{fpantigny@wanadoo.fr}}
-%
-% \maketitle
-%
-% \begin{abstract}
-% The package \pkg{piton} provides tools to typeset Python listings with
-% syntactic highlighting by using the Lua library LPEG. It requires LuaLaTeX.
-% \end{abstract}
-% 
-% 
-%
-% \section{Presentation}
-% 
-%
-% The package \pkg{piton} uses the Lua library LPEG\footnote{LPEG is a
-% pattern-matching library for Lua, written in C, based on \emph{parsing
-% expression grammars}: \url{http://www.inf.puc-rio.br/~roberto/lpeg/}} for
-% parsing Python listings and typeset them with syntactic highlighting. Since it
-% uses Lua code, it works with |lualatex| only (and won't work with the other
-% engines: |latex|, |pdflatex| and |xelatex|). It does not use external program
-% and the compilation does not require |--shell-escape|. The compilation is very
-% fast since all the parsing is done by the library LPEG, written in C.
-% 
-% \bigskip
-% Here is an example of code typeset by \pkg{piton}, with the environment |{Piton}|.
-%
-% \bigskip
-%
-%    \begin{Piton}
-% from math import pi
-%
-% def arctan(x,n=10):
-%    """Compute the mathematical value of arctan(x)
-%
-%    n is the number of terms in the sum
-%    """
-%     if x < 0:
-%         return -arctan(-x) # recursive call
-%     elif x > 1: 
-%         return pi/2 - arctan(1/x) 
-%         #> (we have used that $\arctan(x)+\arctan(1/x)=\frac{\pi}{2}$ for $x>0$)\footnote{This LaTeX escape has been done by beginning the comment by \ttfamily\#>.}
-%     else: 
-%         s = 0
-%         for k in range(n):
-%             s += (-1)**k/(2*k+1)*x**(2*k+1)
-%         return s 
-%    \end{Piton}
-% 
-%
-% \bigskip
-% The package \pkg{piton} is entirely contained in the file
-% |piton.sty|. This file may be put in the current directory or in a
-% |texmf| tree. However, the best is to install \pkg{piton} with a TeX
-% distribution such as MiKTeX, TeX Live or MacTeX.
-% 
-% 
-% \section{Use of the package}
-%
-%
-% \subsection{Loading the package}
-% 
-% The package \pkg{piton} should be loaded with the classical command
-% |\usepackage|: |\usepackage{piton}|.
-%
-% \smallskip
-% Nevertheless, we have two remarks:
-% \begin{itemize}
-% \item the package \pkg{piton} uses the package \pkg{xcolor} (but \pkg{piton}
-% does \emph{not} load \pkg{xcolor}: if \pkg{xcolor} is not loaded before the
-% |\begin{document}|, a fatal error will be raised).
-% \item the package \pkg{piton} must be used with LuaLaTeX exclusively: if
-% another LaTeX engine (|latex|, |pdflatex|, |xelatex|,\dots ) is used, a
-% fatal error will be raised.
-% \end{itemize}
-% 
-% \subsection{The tools provided to the user}
-% 
-% The package \pkg{piton} provides several tools to typeset Python code: the
-% command |\piton|, the environment |{Piton}| and the command |\PitonInputFile|.
-%
-% \begin{itemize}\setlength{\fboxsep}{1pt}
-% \item The command \colorbox{gray!20}{\texttt\textbackslash piton} should be
-% used to typeset small pieces of code inside a paragraph. For example:
-% 
-% {\color{gray}\verb|\piton{def square(x): return x*x}|}\qquad 
-% \piton{def square(x): return x*x}
-%
-% The syntax and particularities of the command |\piton| are detailed below.
-%
-% \item The environment \colorbox{gray!20}{\ttfamily\{Piton\}} should be used to
-% typeset multi-lines code. Since it takes its argument in a verbatim mode, it
-% can't be used within the argument of a LaTeX command. For sake of
-% customization, it's possible to define new environments similar to the
-% environment |{Piton}| with the command |\NewPitonEnvironment|:
-% cf.~\ref{NewPitonEnvironment} p.~\pageref{NewPitonEnvironment}.
-%
-% \item The command \colorbox{gray!20}{\ttfamily\textbackslash PitonInputFile}
-% is used to insert and typeset a whole external file.
-%
-% That command takes in as optional argument (between square brackets) two keys
-% |first-line| and |last-line|: only the part between the corresponding lines
-% will be inserted.
-% \end{itemize}
-%
-% \subsection{The syntax of the command \textbackslash piton}
-% 
-% In fact, the command |\piton| is provided with a double syntax. It may be used
-% as a standard command of LaTeX taking its argument between curly braces
-% (|\piton{...}|) but it may also be used with a syntax similar to the syntax of
-% the command
-% |\verb|, that is to say with the argument delimited by two identical characters (e.g.: \verb!\piton|...|!).
-% 
-% \begin{itemize}
-% \item {\color{blue} \textsf{Syntax} \verb|\piton{...}|}\par\nobreak
-% When its argument is given between curly braces, the command |\piton| does not
-% take its argument in verbatim mode. In particular:
-% \begin{itemize}
-% \item several consecutive spaces will be replaced by only one space,
-% 
-% {\color{cyan} but the command |\|␣ is provided to force the insertion of a space};
-%
-% \item it's not possible to use |%| inside the argument,
-%
-% {\color{cyan} but the command |\%| is provided to insert a |%|};
-%
-% \item the braces must be appear by pairs correctly nested
-%
-% {\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,
-%
-% {\color{cyan} so it's possible to use |\\| to insert a backslash}.
-% \end{itemize}
-%
-%
-% The other characters (including |#|, |^|, |_|, |&|, |$| and |@|)
-% must be inserted without backslash.
-% 
-% \bigskip
-%\begin{tabular}{>{\color{gray}}w{l}{75mm}@{\hspace*{1cm}}l}
-% \omit Examples : \hfil \\
-% \noalign{\vskip1mm}
-% \verb|\piton{MyString = '\\n'}| & 
-% \piton{MyString = '\\n'} \\
-% \verb|\piton{def even(n): return n\%2==0}| & 
-% \piton{def even(n): return n\%2==0} \\
-% \verb|\piton{c="#"    # an affectation }| & 
-% \piton{c="#"     # an affectation } \\
-% \verb|\piton{c="#" \ \ \ # an affectation }| & 
-% \piton{c="#" \ \ \ # an affectation } \\
-% \verb|\piton{MyDict = {'a': 3, 'b': 4 }}| &
-% \piton{MyDict = {'a': 3, 'b': 4 }}
-% \end{tabular}
-%
-% \bigskip
-% It's possible to use the command |\piton| in the arguments of a
-% LaTeX command.\footnote{For example, it's possible to use the command
-% \texttt{\textbackslash piton} in a footnote. Example :
-% \piton{s = 'A string'}.}
-%
-% \bigskip
-% \item {\color{blue} \textsf{Syntaxe} \verb!\piton|...|!}\par\nobreak
-%
-% When the argument of the command |\piton| is provided between two identical
-% characters, that argument is taken in a \emph{verbatim mode}. Therefore, with
-% that syntax, the command |\piton| can't be used within the argument of another
-% command. 
-%
-% \medskip
-%
-% \begin{tabular}{>{\color{gray}}w{l}{75mm}@{\hspace*{1cm}}l}
-% \omit Examples : \hfil \\
-% \noalign{\vskip1mm}
-% \verb!\piton|MyString = '\n'|! & 
-% \piton|MyString = '\n'| \\
-% \verb|\piton!def even(n): return n%2==0!| & 
-% \piton!def even(n): return n%2==0! \\
-% \verb|\piton+c="#"    # an affectation +| & 
-% \piton+c="#"     # an affectation + \\
-% \verb|\piton?MyDict = {'a': 3, 'b': 4}?| &
-% \piton!MyDict = {'a': 3, 'b': 4}!
-% \end{tabular}
-%
-% \end{itemize}
-% 
-% \section{Customization}
-%
-% \subsection{The command \textbackslash PitonOptions}
-%
-%
-% \NewDocumentCommand{\Definition}{m}
-%   {{\setlength{\fboxsep}{1pt}\colorbox{gray!20}{\ttfamily \vphantom{gl}#1}}}
-% 
-% The command |\PitonOptions| takes in as argument a comma-separated list of
-% \textsl{key=value} pairs. The scope of the settings done by that command is
-% the current TeX group.\footnote{We remind that a LaTeX environment is, in
-% particular, a TeX group.}
-%
-% \begin{itemize}
-% \item The key \Definition{gobble} takes in as value a
-% positive integer~$n$: the first $n$ characters are discarded (before the
-% process of highlightning of the code) for each line of the environment
-% |{Piton}|. These characters are not necessarily spaces.
-%
-% \item When the key \Definition{auto-gobble} is in force, the
-% extension \pkg{piton} computes the minimal value $n$ of the number of
-% consecutive spaces beginning each (non empty) line of the environment
-% |{Piton}| and applies |gobble| with that value of~$n$.
-%
-% \item When the key \Definition{env-gobble} is in force, \pkg{piton} analyzes the last
-% line of the environment |{Piton}|, that is to say the line which contains
-% |\end{Piton}| and determines whether that line contains only spaces followed
-% by the |\end{Piton}|. If we are in that situation, \pkg{piton} computes the
-% number~$n$ of spaces on that line and applies |gobble| with that value of~$n$.
-% The name of that key comes from \emph{environment gobble}: the effect of
-% gobble is set by the position of the commands |\begin{Piton}| and
-% |\end{Piton}| which delimit the current environment.
-%
-% \item With the key \Definition{line-numbers}, the \emph{non empty} lines (and
-% all the lines of the \emph{docstrings}, even the empty ones) are numbered in
-% the environments |{Piton}| and in the listings resulting from the use of
-% |\PitonInputFile|.
-% 
-% \item With the key \Definition{all-line-numbers}, \emph{all} the lines are numbered,
-% including the empty ones.
-%
-% \item \colorbox{yellow!50}{\bfseries{New 1.5}}\par\nobreak
-%
-% The key \Definition{numbers-sep} is the horizontal distance between the
-% numbers of lines (inserted by |line-numbers| of |all-line-numbers|) and the
-% beginning of the lines of code. The initial value is 0.7~em.
-%
-% \item With the key \Definition{resume}, the counter of lines is not set to zero
-% at the beginning of each environment |{Piton}| or use of |\PitonInputFile| as
-% it is otherwise. That allows a numbering of the lines across several
-% environments.
-%
-% \item The key \Definition{left-margin} corresponds to a margin on the left.
-% That key may be useful in conjonction with the key |line-numbers| or the key
-% |line-all-numbers| if one does not want the numbers in an overlapping position
-% on the left.
-%
-% It's possible to use the key |left-margin| with the value |auto|. With that
-% value, if the key |line-numbers| or the key |all-line-numbers| is used, a
-% margin will be automatically inserted to fit the numbers of lines. See an
-% 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|).
-%
-% \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.
-%
-% \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}|.
-%
-% \item With the key \Definition{prompt-background-color}, \pkg{piton} adds a
-% color background to the lines beginning with the prompt ``|>>>|'' (and its
-% continuation ``|...|'') characteristic of the Python consoles with
-% \textsc{repl} (\emph{read-eval-print loop}).
-%
-% \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
-% character~U+2423 must be present in the monospaced font which is
-% used.\footnote{The package \pkg{piton} simply uses the current monospaced
-% font. The best way to change that font is to use the command
-% \texttt{\textbackslash setmonofont} of the package \pkg{fontspec}.}\par\nobreak
-% \begingroup \PitonOptions{show-spaces-in-strings} Example : 
-% \piton|my_string = 'Very good answer'| \endgroup
-%
-% With the key \Definition{show-spaces}, all the spaces are replaced by U+2423
-% (and no line break can occur on those ``visible spaces'', even when the key
-% |break-lines|\footnote{cf. \ref{line-breaks} p.~\pageref{line-breaks}} is in
-% force). 
-% \end{itemize}
-%
-% \bigskip
-%
-% \begingroup
-% \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
-% \begin{Verbatim}
-% ~emphase&\PitonOptions{line-numbers,auto-gobble,background-color = gray!15}@
-% \begin{Piton}
-%     from math import pi
-%     def arctan(x,n=10):
-%         """Compute the mathematical value of arctan(x)
-%
-%         n is the number of terms in the sum
-%         """
-%         if x < 0:
-%             return -arctan(-x) # recursive call
-%         elif x > 1: 
-%             return pi/2 - arctan(1/x) 
-%             #> (we have used that $\arctan(x)+\arctan(1/x)=\frac{\pi}{2}$ pour $x>0$)
-%         else 
-%             s = 0
-%             for k in range(n):
-%                 s += (-1)**k/(2*k+1)*x**(2*k+1)
-%             return s 
-% \end{Piton}
-% \end{Verbatim}
-% \endgroup
-%
-% \begingroup
-% \PitonOptions{line-numbers,background-color = gray!15}
-%    \begin{Piton}
-% from math import pi
-%
-% def arctan(x,n=10):
-%     """Compute the mathematical value of arctan(x)
-%                                         
-%     n is the number of terms in the sum
-%     """
-%     if x < 0:
-%         return -arctan(-x) # recursive call
-%     elif x > 1: 
-%         return pi/2 - arctan(1/x) 
-%         #> (we have used that $\arctan(x)+\arctan(1/x)=\frac{\pi}{2}$ for $x>0$)
-%     else 
-%         s = 0
-%         for k in range(n):
-%             s += (-1)**k/(2*k+1)*x**(2*k+1)
-%         return s 
-%    \end{Piton}
-% \endgroup
-% 
-% \bigskip
-% The command |\PitonOptions| provides in fact several other keys which will be
-% described further (see in particular the ``Pages breaks and line breaks''
-% p.~\pageref{breakable}). 
-%
-% \subsection{The styles}
-%
-% \label{styles}
-%
-% The package \pkg{piton} provides the command |\SetPitonStyle| to customize the
-% different styles used to format the syntactic elements of the Python listings.
-% The customizations done by that command are limited to the current TeX
-% group.\footnote{We remind that a LaTeX environment is, in particular, a TeX group.}
-%
-% \bigskip
-% The command |\SetPitonStyle| takes in as argument a comma-separated list of
-% \textsl{key=value} pairs. The keys are names of styles and the value are LaTeX
-% formatting instructions.
-%
-% \bigskip
-% These LaTeX instructions must be formatting instructions such as
-% |\color{...}|, |\bfseries|, |\slshape|, etc. (the commands of this kind are
-% sometimes called \emph{semi-global} commands). It's also possible to put,
-% \emph{at the end of the list of instructions}, a LaTeX command taking exactly
-% one argument.
-% 
-% \bigskip
-% Here an example which changes the style used to highlight, in the definition
-% of a Python function, the name of the function which is defined. That code
-% uses the command |\highLight| of \pkg{lua-ul} (that package requires also the
-% package \pkg{luacolor}).
-%
-% \begin{verbatim}
-% \SetPitonStyle{ Name.Function = \bfseries \highLight[red!50] }
-% \end{verbatim}
-%
-% In that example, |\highLight[red!50]| must be considered as the name of a
-% LaTeX command which takes in exactly one argument, since, usually, it is used
-% with |\highLight[red!50]{...}|.
-%
-% \medskip
-% \begingroup
-% \SetPitonStyle 
-%   { Name.Function = \bfseries \highLight[red!50] }
-% With that setting, we will have : \piton{def cube(x) : return x * x * x }
-% \endgroup
-% 
-% \bigskip
-% The different styles are described in the table \ref{Semantic}. The initial
-% settings done by \pkg{piton} in |piton.sty| are inspired by the style
-% \pkg{manni} de Pygments.\footnote{See:
-% \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.
-%
-% \smallskip
-% For example, it's possible to write |{\PitonStyle{Keyword}{function}}| and we
-% will have the word {\PitonStyle{Keyword}{function}} formatted as a keyword.
-%
-% \smallskip
-% The syntax |{\PitonStyle{|\textsl{\texttt{style}}|}{...}}| is mandatory in
-% order to be able to deal both with the semi-global commands and the commands
-% with arguments which may be present in the definition of the style
-% \texttt{\textsl{style}}. 
-%
-% \begin{table}[b]
-% \centering
-% \caption{Usage of the different styles}
-% \label{Semantic}
-% \begin{tabular}{@{}>{\ttfamily}l>{\RaggedRight\arraybackslash}p{9cm}@{}}
-% \toprule
-% \normalfont Style  & Usage \\
-% \midrule
-% Number & the numbers \\
-% String.Short & the short strings (between \texttt{'} or \verb|"|) \\
-% String.Long & the long strings (between \texttt{'''} or \verb|"""|) except the
-% documentation strings \\ 
-% String & that keys sets both |String.Short| and |String.Long| \\
-% String.Doc & the documentation strings (only between \texttt{"""} following
-% PEP~257) \\
-% String.Interpol & the syntactic elements of the fields of the f-strings (that
-% is to say the characters \texttt{\{} and \texttt{\}}) \\
-% Operator & the following operators : \texttt{!= == << >> - \~{} + / * \% = < > \& .} \verb+|+ \verb|@|\\
-% Operator.Word & the following operators : \texttt{in}, \texttt{is},
-% \texttt{and}, \texttt{or} and \texttt{not} \\ 
-% Name.Builtin & the predefined functions of Python \\
-% Name.Function & the name of the functions defined by the user, at the point of
-% their definition (that is to say after the keyword |def|) \\
-% Name.Decorator & the decorators (instructions beginning by \verb|@|) \\
-% Name.Namespace & the name of the modules (= external libraries) \\
-% Name.Class & the name of the classes at the point of their definition (that is
-% to say after the keyword |class|) \\
-% Exception & the names of the exceptions (eg: \texttt{SyntaxError}) \\
-% Comment & the comments beginning with \verb|#| \\
-% Comment.LaTeX & the comments beginning by \verb|#>|, which are composed in LaTeX by
-% \pkg{piton} (and simply called ``LaTeX comments'' in this document) \\
-% Keyword.Constant & |True|, |False| and |None| \\
-% Keyword & the following keywords :
-%           \ttfamily as, assert, break, case, continue, def, del,
-%           elif, else, except, exec, finally, for, from, 
-%           global, if, import, lambda, non local,
-%           pass, raise, return, try, while,
-%           with, yield, yield from.\\
-% \bottomrule 
-% \end{tabular}
-% \end{table}
-%
-%
-%
-% 
-% \subsection{Creation of new environments}
-%
-% \label{NewPitonEnvironment}
-% 
-% Since the environment |{Piton}| has to catch its body in a special way (more
-% or less as verbatim text), it's not possible to construct new environments
-% directly over the environment |{Piton}| with the classical commands
-% |\newenvironment| or |\NewDocumentEnvironment|.
-%
-% That's why \pkg{piton} provides a command |\NewPitonEnvironment|. That
-% command takes in three mandatory arguments. 
-
-% That command has the same syntax as the classical environment
-% |\NewDocumentEnvironment|.
-% 
-% \bigskip
-% With the following instruction, a new environment |{Python}| will be
-% constructed with the same behaviour as |{Piton}|:
-%
-% {\color{gray}\verb|\NewPitonEnvironment{Python}{}{}{}|}
-%
-% \bigskip
-% If one wishes an environment |{Python}| with takes in as optional argument
-% (between square brackets) the keys of the command |\PitonOptions|, it's
-% possible to program as follows:
-%
-% {\color{gray}\verb|\NewPitonEnvironment{Python}{O{}}{\PitonOptions{#1}}{}|}
-% 
-% \bigskip
-% If one wishes to format Python code in a box of \pkg{tcolorbox}, it's possible
-% to define an environment |{Python}| with the following code (of course, the
-% package \pkg{tcolorbox} must be loaded).
-%
-%\begin{verbatim}
-% \NewPitonEnvironment{Python}{}
-%   {\begin{tcolorbox}}
-%   {\end{tcolorbox}}
-% \end{verbatim}
-%
-% \bigskip
-% With this new environment |{Python}|, it's possible to write:
-%
-% \begin{Verbatim}
-% ~emphase#\begin{Python}@
-% def square(x):
-%     """Compute the square of a number"""
-%     return x*x
-% ~emphase#\end{Python}@
-% \end{Verbatim}
-%
-% \NewPitonEnvironment{Python}{}
-%   {\begin{tcolorbox}}
-%   {\end{tcolorbox}}
-%
-% \begin{Python}
-% def square(x):
-%     """Compute the square of a number"""
-%     return x*x
-% \end{Python}
-%
-%
-% \section{Advanced features}
-%
-% \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|.
-%
-% \smallskip
-% That key takes in as argument a value of the following format:
-%
-% \quad |{ names = |\textsl{\ttfamily names}|, style = |\textsl{\ttfamily
-% instructions}| }|
-%
-% \begin{itemize}
-% \item \textsl{\ttfamily names} is a (comma-separated) list of identifiers
-% names; 
-%
-% \item \textsl{\ttfamily instructions} is a list of LaTeX instructions of the
-% same type that \pkg{piton} ``styles'' previously presented (cf~\ref{styles}
-% p.~\pageref{styles}). 
-% \end{itemize}
-%
-% \emph{Caution}: Only the identifiers may be concerned by that key. The
-% keywords and the built-in functions won't be affected, even if their name is
-% in the list |\textsl{\ttfamily names}|.
-% 
-% \begin{Verbatim}
-% \PitonOptions 
-%   {
-%     ~emphase#identifiers@ = 
-%      {
-%        ~emphase#names@ = { l1 , l2 } , 
-%        ~emphase#style@ = \color{red} 
-%      }
-%   }
-%
-% \begin{Piton}
-% def tri(l):
-%     """Segmentation sort"""
-%     if len(l) <= 1:
-%         return l
-%     else:
-%         a = l[0]
-%         l1 = [ x for x in l[1:] if x < a  ]
-%         l2 = [ x for x in l[1:] if x >= a ]
-%         return tri(l1) + [a] + tri(l2)
-% \end{Piton}
-% \end{Verbatim}
-%
-%
-% \bigskip
-%
-% \begingroup
-%
-% \PitonOptions 
-%   {
-%     identifiers = 
-%      {
-%        names = { l1 , l2 } , 
-%        style = \color{red} 
-%      }
-%   }
-%
-% \begin{Piton}
-% def tri(l):
-%     """Segmentation sort"""
-%     if len(l) <= 1:
-%         return l
-%     else:
-%         a = l[0]
-%         l1 = [ x for x in l[1:] if x < a  ]
-%         l2 = [ x for x in l[1:] if x >= a ]
-%         return tri(l1) + [a] + tri(l2)
-% \end{Piton}
-%
-% \endgroup
-% 
-% \bigskip
-% By using the key |identifier|, it's possible to add other built-in functions
-% (or other new keywords, etc.) that will be detected by \pkg{piton}.
-%
-%
-% \begin{Verbatim}
-% \PitonOptions 
-%   {
-%     ~emphase#identifiers@ = 
-%      {
-%        names = { cos, sin, tan, floor, ceil, trunc, pow, exp, ln, factorial } , 
-%        style = \PitonStyle{Name.Builtin}
-%      }
-%   }
-%
-% \begin{Piton}
-% from math import *
-% cos(pi/2) 
-% factorial(5)
-% ceil(-2.3) 
-% floor(5.4) 
-% \end{Piton}
-% \end{Verbatim}
-%
-% \begingroup
-%
-% \PitonOptions 
-%   {
-%     identifiers = 
-%      {
-%        names = { cos, sin, tan, floor, ceil, trunc, pow, exp, ln, factorial } , 
-%        style = \PitonStyle{Name.Builtin}
-%      }
-%   }
-%
-% \begin{Piton}
-% from math import *
-% cos(pi/2) 
-% factorial(5)
-% ceil(-2.3) 
-% floor(5.4) 
-% \end{Piton}
-%
-%
-% \endgroup
-%
-%
-% \subsection{Mechanisms to escape to LaTeX}
-%
-% The package \pkg{piton} provides several mechanisms for escaping to LaTeX:
-% \begin{itemize}
-% \item It's possible to compose comments entirely in LaTeX.
-% \item It's possible to have the elements between \texttt{\$} in the comments
-% composed in LateX mathematical mode.
-% \item It's also possible to insert LaTeX code almost everywhere in a Python listing.
-% \end{itemize}
-%
-% One should aslo remark that, when the extension \pkg{piton} is used with the
-% class \cls{beamer}, \pkg{piton} detects in |{Piton}| many commands and
-% environments of Beamer: cf. \ref{beamer} p.~\pageref{beamer}.
-%
-% \subsubsection{The ``LaTeX comments''}
-%
-% In this document, we call ``LaTeX comments'' the comments which begins by
-% |#>|. The code following those characters, until the end of the line, will be
-% composed as standard LaTeX code. There is two tools to customize those
-% comments.
-%
-% \begin{itemize}
-% \item It's possible to change the syntatic mark (which, by default, is |#>|).
-% For this purpose, there is a key |comment-latex| available at load-time (that
-% is to say at the |\usepackage|) which allows to choice the characters which,
-% preceded by |#|, will be the syntatic marker.
-%
-% For example, with the following loading:
-% 
-% \quad \verb|\usepackage[comment-latex = LaTeX]{piton}|
-%
-% the LaTeX comments will begin by |#LaTeX|.
-%
-% If the key |comment-latex| is used with the empty value, all the Python
-% comments (which begins by |#|) will, in fact, be ``LaTeX comments''.
-%
-% \smallskip
-% \item It's possible to change the formatting of the LaTeX comment itself by
-% changing the \pkg{piton} style |Comment.LaTeX|.
-%
-% For example, with |\SetPitonStyle{Comment.LaTeX = \normalfont\color{blue}}|,
-% the LaTeX comments will be composed in blue.
-%
-% If you want to have a character |#| at the beginning of the LaTeX comment in
-% the \textsc{pdf}, you can use set |Comment.LaTeX| as follows:
-%
-% \begin{Verbatim}
-% \SetPitonStyle{Comment.LaTeX = \color{gray}\~#\normalfont\space }
-% \end{Verbatim}
-% 
-% For other examples of customization of the LaTeX comments, see the part
-% \ref{example-comments} p.~\pageref{example-comments}
-% \end{itemize}
-%
-% \bigskip
-% If the user has required line numbers in the left margin (with the
-% key |line-numbers| or the key |all-line-numbers| of |\PitonOptions|), it's
-% possible to refer to a number of line with the command |\label| used in a
-% LaTeX comment.\footnote{That feature is implemented by using a redefinition of
-% the standard command \texttt{\textbackslash label} in the environments
-% \texttt{\{Piton\}}. Therefore, incompatibilities may occur with extensions
-% which redefine (globally) that command \texttt{\textbackslash label} (for
-% example: \pkg{varioref}, \pkg{refcheck}, \pkg{showlabels}, etc.)}
-%
-% \subsubsection{The key ``math-comments''}
-%
-% It's possible to request that, in the standard Python comments (that is to say
-% those beginning by |#| and not |#>|), the elements between \texttt{\$} be
-% composed in LaTeX mathematical mode (the other elements of the comment being
-% composed verbatim).
-%
-% That feature is activated by the key |math-comments| at load-time (that is to
-% say with the |\usepackage|).
-%
-% \medskip
-% In the following example, we assume that the key |math-comments| has been used
-% when loading \pkg{piton}.
-%
-% \begin{Verbatim}
-% \begin{Piton}
-% def square(x):
-%     return x*x ~# compute $x^2$
-% \end{Piton}
-% \end{Verbatim}
-%
-% \begin{Piton}
-% def square(x):
-%     return x*x # compute $x^2$
-% \end{Piton}
-% 
-% \subsubsection{The mechanism ``escape-inside''}
-%
-% It's also possible to overwrite the Python listings to insert LaTeX code
-% almost everywhere (but between lexical units, of course). By default,
-% \pkg{piton} does not fix any character for that kind of escape.
-%
-% In order to use this mechanism, it's necessary to specify two characters which
-% will delimit the escape (one for the beginning and one for the end) by using
-% the key |escape-inside| at load-time (that is to say at the
-% |\begin{docuemnt}|). 
-%
-% \medskip
-% In the following example, we assume that the extension \pkg{piton} has been
-% loaded by the following instruction.
-%
-% \begin{Verbatim}
-% \usepackage[~emphase#escape-inside=$$@]{piton}
-% \end{Verbatim}
-%
-% \medskip
-% In the following code, which is a recursive programmation of the mathematical
-% factorial, we decide to highlight in yellow the instruction which contains the
-% recursive call. That example uses the command |\highLight| of \pkg{lua-ul}
-% (that package requires itself the package \pkg{luacolor}).
-% \begin{Verbatim}
-% \begin{Piton}
-% def fact(n):
-%     if n==0:
-%         return 1
-%     else:
-%         ~emphase#$\highLight{$@return n*fact(n-1)~emphase#$}$@
-% \end{Piton}
-% \end{Verbatim}
-%
-%    \begin{Piton}
-% def fact(n):
-%     if n==0:
-%         return 1
-%     else:
-%         $\highLight{$return n*fact(n-1)$}$
-%    \end{Piton}
-%         
-% \bigskip
-% In fact, in that case, it's probably easier to use the command |\@highLight|
-% of \pkg{lua-ul}: that command sets a yellow background until the end of the
-% current TeX group. Since the name of that command contains the character |@|,
-% it's necessary to define a synonym without |@| in order to be able to use it
-% directly in |{Piton}|.
-% \begingroup
-% \fvset{commandchars=\~\#\+,formatcom=\color{gray}}
-% \begin{Verbatim}
-% \makeatletter
-% ~emphase#\let\Yellow\@highLight+
-% \makeatother
-% \end{Verbatim}
-% \endgroup
-%
-% \begin{Verbatim}
-% \begin{Piton}
-% def fact(n):
-%     if n==0:
-%         return 1
-%     else:
-%         ~emphase#$\Yellow$@return n*fact(n-1)
-% \end{Piton}
-% \end{Verbatim}
-%
-% \makeatletter
-% \let\Yellow\@highLight
-% \makeatother
-%
-%
-% \begin{Piton}
-% def fact(n):
-%     if n==0:
-%         return 1
-%     else:
-%         $\Yellow$return n*fact(n-1)
-% \end{Piton}
-%
-%
-%
-% \bigskip
-% \emph{Caution} : The escape to LaTeX allowed by the characters of
-% |escape-inside| is not active in the strings nor in the Python comments
-% (however, it's possible to have a whole Python comment composed in LaTeX by
-% beginning it with |#>|; such comments are merely called ``LaTeX comments'' in
-% this document). 
-% 
-%
-% \subsection{Behaviour in the class Beamer}
-%
-% \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).}
-%
-%
-% \bigskip
-% When the package \pkg{piton} is used within the class
-% \cls{beamer}\footnote{The extension \pkg{piton} detects the class \cls{beamer}
-% but, if needed, it's also possible to activate that mechanism with the key
-% |beamer| provided by \pkg{piton} at load-time: |\textbackslash
-% usepackage[beamer]\{piton\}|}, the behaviour of \pkg{piton} is slightly
-% modified, as described now.
-%
-% \subsubsection{\{Piton\} et \textbackslash PitonInputFile are
-% ``overlay-aware''}
-%
-% When \pkg{piton} is used in the class \cls{beamer}, the environment |{Piton}|
-% and the command |\PitonInputFile| accept the optional argument |<...>| of
-% Beamer for the overlays which are involved.
-%
-% For example, it's possible to write:
-%
-% \begin{Verbatim}
-% \begin{Piton}~emphase#<2-5>@
-% ...
-% \end{Piton}
-% \end{Verbatim}
-%
-% and 
-%
-% \begin{Verbatim}
-% \PitonInputFile~emphase#<2-5>@{my_file.py}
-% \end{Verbatim}
-% 
-% \subsubsection{Commands of Beamer allowed in \{Piton\} and \textbackslash PitonInputFile}
-%
-% When \pkg{piton} is used in the class \cls{beamer} , the following commands of
-% \cls{beamer} (classified upon their number of arguments) are automatically
-% detected in the environments |{Piton}| (and in the listings processed by
-% |\PitonInputFile|):
-% \begin{itemize}
-% \item no mandatory argument : |\pause|\footnote{One should remark that it's
-% also  possible to use the command \texttt{\textbackslash pause} in a ``LaTeX
-% comment'', that is to say by writing \texttt{\#> \textbackslash pause}. By
-% this way, if the Python code is copied, it's still executable by Python}.  ;
-% \item one mandatory argument : |\action|, |\alert|, |\invisible|, |\only|, |\uncover| and |\visible| ;
-% \item two mandatory arguments : |\alt| ; 
-% \item three mandatory arguments  : |\temporal|.
-% \end{itemize}
-
-% \medskip
-% In the mandatory arguments of these commands, the braces must be balanced.
-% However, the braces included in short strings\footnote{The short strings of
-% Python are the strings delimited by characters \texttt{'} or the characters
-% \texttt{"} and not \texttt{'''} nor \texttt{"""}. In Python, the short strings
-% can't extend on several lines.} of Python are not considered. 
-%
-% \medskip
-% Here is a complete example of file:
-%
-% \begin{Verbatim}[formatcom = \small\color{gray}]
-% \documentclass{beamer}
-% \usepackage{piton}
-% \begin{document}
-% \begin{frame}[fragile]
-% \begin{Piton}
-% def string_of_list(l):
-%     """Convert a list of numbers in string"""
-% ~emphase#    \only<2->{s = "{" + str(l[0])}@
-% ~emphase#    \only<3->{for x in l[1:]: s = s + "," + str(x)}@
-% ~emphase#    \only<4->{s = s + "}"}@
-%     return s
-% \end{Piton}
-% \end{frame}
-% \end{document}
-% \end{Verbatim}
-%
-% In the previous example, the braces in the Python strings |"{"| and |"}"| are
-% correctly interpreted (without any escape character).
-% 
-% 
-%
-%
-% \bigskip
-% \subsubsection{Environments of Beamer allowed in \{Piton\} and \textbackslash PitonInputFile}
-%
-% When \pkg{piton} is used in the class \pkg{beamer}, the following environments
-% of Beamer are directly detected in the environments |{Piton}| (and in the
-% listings processed by |\PitonInputFile|): |{actionenv}|, |{alertenv}|,
-% |{invisibleenv}|, |{onlyenv}|, |{uncoverenv}| and |{visibleenv}|.
-%
-% However, there is a restriction: these environments must contain only \emph{whole
-% lines of Python code} in their body.
-%
-%\medskip
-% Here is an example:
-%
-% \begin{Verbatim}[formatcom = \small\color{gray}]
-% \documentclass{beamer}
-% \usepackage{piton}
-% \begin{document}
-% \begin{frame}[fragile]
-% \begin{Piton}
-% def square(x):
-%     """Compure the square of its argument"""
-%     ~emphase#\begin{uncoverenv}<2>@
-%     return x*x
-%     ~emphase#\end{uncoverenv}@
-% \end{Piton}
-% \end{frame}
-% \end{document}
-% \end{Verbatim}
-%
-%
-% \vspace{1cm}
-% \textbf{Remark concerning the command \textbackslash alert and the environment
-% \{alertenv\} of Beamer}\par\nobreak
-%
-% \smallskip
-% Beamer provides an easy way to change the color used by the environment
-% |{alertenv}| (and by the command |\alert| which relies upon it) to highlight
-% its argument. Here is an example:
-%
-% \begin{Verbatim}
-% \setbeamercolor{~emphase#alerted text@}{fg=blue} 
-% \end{Verbatim}
-%
-% However, when used inside an environment |{Piton}|, such tuning will probably
-% not be the best choice because \pkg{piton} will, by design, change (most of
-% the time) the color the different elements of text. One may prefer an environment
-% |{alertenv}| that will change the background color for the elements to be
-% hightlighted. 
-%
-% \smallskip
-% Here is a code that will do that job and add a yellow background. That code
-% uses the command |\@highLight| of \pkg{lua-ul} (that extension requires also
-% the package \pkg{luacolor}).
-%
-% \begingroup
-% \fvset{commandchars=\~\#\+,formatcom=\color{gray}}
-% \begin{Verbatim}
-% \setbeamercolor{alerted text}{bg=yellow!50}
-% \makeatletter
-% \AddToHook{env/Piton/begin}
-%   {\renewenvironment<>{alertenv}{\only~#1{~emphase#\@highLight+[alerted text.bg]}}{}}
-% \makeatother
-% \end{Verbatim}
-% \endgroup
-%
-% That code redefines locally the environment |{alertenv}| within the
-% environments |{Piton}| (we recall that the command |\alert| relies upon that
-% environment |{alertenv}|).
-%
-% \subsection{Page breaks and line breaks}
-%
-% \label{breakable}
-%
-% \subsubsection{Page breaks}
-%
-% By default, the listings produced by the environment |{Piton}| and the command
-% |\PitonInputFile| are not breakable.
-%
-% However, the command |\PitonOptions| provides the key |splittable| to allow such
-% breaks.
-%
-% \begin{itemize}
-% \item If the key |splittable| is used without any value, the listings are
-% breakable everywhere.
-% \item If the key |splittable| is used with a numeric value~$n$ (which must be
-% a non-negative integer number), the listings are breakable but no break will
-% occur within the first $n$ lines and within the last $n$ lines. Therefore,
-% |splittable=1| is equivalent to |splittable|.
-% \end{itemize}
-%
-% \medskip
-% Even with a background color (set by the key |background-color|), the pages
-% breaks are allowed, as soon as the key |splittable| is in force.\footnote{With
-% the key |splittable|, the environments \texttt{\{Piton\}} are breakable, even
-% within a (breakable) environment of \pkg{tcolorbox}. Remind that an
-% environment of \pkg{tcolorbox} included in another environment of
-% \pkg{tcolorbox} is \emph{not} breakable, even when both environments use the
-% key |breakable| of \pkg{tcolorbox}.}
-% 
-% \subsubsection{Line breaks}
-% 
-% \label{line-breaks}
-% 
-% By default, the elements produced by \pkg{piton} can't be broken by an end on
-% line. However, there are keys to allow such breaks (the possible breaking
-% points are the spaces, even the spaces in the Python strings).
-% \begin{itemize}
-% \item With the key |break-lines-in-piton|, the line breaks are allowed in the
-% command |\piton{...}| (but not in the command \verb+\piton|...|+, that is to say
-% the command |\piton| in verbatim mode). 
-% \item With the key |break-lines-in-Piton|, the line breaks are allowed in the
-% environment |{Piton}| (hence the capital letter |P| in the name) and in the
-% listings produced by |\PitonInputFile|.
-% \item The key |break-lines| is a conjonction of the two previous keys.
-% \end{itemize}
-% 
-% \bigskip 
-% The package \pkg{piton} provides also several keys to control the appearance
-% on the line breaks allowed by |break-lines-in-Piton|.
-%
-% \begin{itemize}
-% \item With the key |indent-broken-lines|, the indentation of a broken line is
-% respected at carriage return.
-%
-% \item The key |end-of-broken-line| corresponds to the symbol placed at the end
-% of a broken line. The initial value is: |\hspace*{0.5em}\textbackslash|.
-%
-% \item The key |continuation-symbol| corresponds to the symbol placed at each
-% carriage return. The initial value is: |+\;|.
-%
-% \item The key |continuation-symbol-on-indentation| coresponds to the symbol
-% placed at each carriage return, on the position of the indentation (only when
-% the key |indent-broken-line| is in force). The initial value is:
-% |$\hookrightarrow\;$|.
-% \end{itemize}
-%
-%
-% \bigskip
-% The following code has been composed in a standard LaTeX |{minipage}| of width
-% 12~cm with the following tuning:
-%
-% \begin{Verbatim}
-% \PitonOptions{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}
-% \begin{Piton}
-% def dict_of_list(l):
-%     """Converts a list of subrs and descriptions of glyphs in a dictionary"""
-%     our_dict = {}
-%     for list_letter in l:
-%         if (list_letter[0][0:3] == 'dup'): # if it's a subr
-%             name = list_letter[0][4:-3]
-%             print("We treat the subr of number " + name)
-%         else:
-%             name = list_letter[0][1:-3] # if it's a glyph
-%             print("We treat the glyph of number " + name)
-%         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}
-% 
-% \label{footnote}
-% If you want to put footnotes in an environment |{Piton}| or
-% (or, more unlikely, in a listing produced by |\PitonInputFile|), you can use a
-% pair |\footnotemark|--|\footnotetext|. 
-%
-% \smallskip
-% However, it's also possible to extract the footnotes with the help of the
-% package \pkg{footnote} or the package \pkg{footnotehyper}.
-%
-% \smallskip
-% If \pkg{piton} is loaded with the option |footnote| (with
-% |\usepackage[footnote]{piton}| or with |\PassOptionsToPackage|), the
-% package \pkg{footnote} is loaded (if it is not yet loaded) and it is used to
-% extract the footnotes.
-%
-% \smallskip
-% If \pkg{piton} is loaded with the option |footnotehyper|, the package
-% \pkg{footnotehyper} is loaded (if it is not yet loaded) ant it is used to
-% extract footnotes.
-%
-% \smallskip
-% Caution: The packages \pkg{footnote} and \pkg{footnotehyper} are incompatible.
-% The package \pkg{footnotehyper} is the successor of the package \pkg{footnote}
-% and should be used preferently. The package \pkg{footnote} has some drawbacks,
-% in particular: it must be loaded after the package \pkg{xcolor} and it is not
-% perfectly compatible with \pkg{hyperref}.
-%
-% \medskip 
-% In this document, the package \pkg{piton} has been loaded with the
-% option |footnotehyper|. For examples of notes, cf. \ref{notes-examples},
-% p.~\pageref{notes-examples}.
-%
-% \subsection{Tabulations}
-%
-% \smallskip 
-% Even though it's recommended to indent the Python listings with spaces (see
-% PEP~8), \pkg{piton} accepts the characters of tabulation (that is to say the
-% characters U+0009) at the beginning of the lines. Each character U+0009 is
-% replaced by $n$~spaces. The initial value of $n$ is $4$ but it's possible to
-% change it with the key |tab-size| of |\PitonOptions|.
-%
-% \smallskip
-% There exists also a key |tabs-auto-gobble| which computes the minimal value
-% $n$ of the number of consecutive characters U+0009 beginning each (non empty)
-% line of the environment |{Piton}| and applies |gobble| with that value of~$n$
-% (before replacement of the tabulations by spaces, of course). Hence, that key
-% is similar to the key |auto-gobble| but acts on U+0009 instead of U+0020
-% (spaces).
-%
-% \section{Examples}
-%
-% \subsection{Line numbering}
-%
-% \label{example-numbering}
-%
-% We remind that it's possible to have an automatic numbering of the lines in
-% the Python listings by using the key |line-numbers| or the key |all-line-numbers|.
-%
-% By default, the numbers of the lines are composed by \pkg{piton} in an
-% overlapping position on the left (by using internally the command |\llap| of LaTeX).
-%
-% In order to avoid that overlapping, it's possible to use the option |left-margin=auto|
-% which will insert automatically a margin adapted to the numbers of lines that
-% will be written (that margin is larger when the numbers are greater than~10).
-%
-%
-% \begingroup
-% \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
-% \begin{Verbatim}
-% ~emphase&\PitonOptions{background-color=gray!10, left-margin = auto, line-numbers}@
-% \begin{Piton}
-% def arctan(x,n=10):
-%     if x < 0:
-%         return -arctan(-x)        #> (appel récursif)
-%     elif x > 1: 
-%         return pi/2 - arctan(1/x) #> (autre appel récursif) 
-%     else: 
-%         return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
-% \end{Piton}
-% \end{Verbatim}
-% \endgroup
-%
-%
-%
-% \begingroup
-% \PitonOptions{background-color=gray!10,left-margin = auto, line-numbers}
-% \begin{Piton}
-% def arctan(x,n=10):
-%     if x < 0:
-%         return -arctan(-x)        #> (appel récursif)
-%     elif x > 1: 
-%         return pi/2 - arctan(1/x) #> (autre appel récursif) 
-%     else: 
-%         return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
-% \end{Piton}
-% \endgroup
-%
-%
-%
-% \bigskip
-% \subsection{Formatting of the LaTeX comments}
-%
-% \label{example-comments}
-%
-% It's possible to modify the style |Comment.LaTeX| (with |\SetPitonStyle|) in
-% order to display the LaTeX comments (which begin with |#>|) aligned on the
-% right margin.
-%
-%
-% \begingroup
-% \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
-% \begin{Verbatim}
-% \PitonOptions{background-color=gray!10}
-% ~emphase&\SetPitonStyle{Comment.LaTeX = \hfill \normalfont\color{gray}}@
-% \begin{Piton}
-% def arctan(x,n=10):
-%     if x < 0:
-%         return -arctan(-x)        #> appel récursif
-%     elif x > 1: 
-%         return pi/2 - arctan(1/x) #> autre appel récursif 
-%     else: 
-%         return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
-% \end{Piton}
-% \end{Verbatim}
-% \endgroup
-%
-% \begingroup
-% \PitonOptions{background-color=gray!10}
-% \SetPitonStyle{Comment.LaTeX = \hfill \normalfont\color{gray}}
-% \begin{Piton}
-% def arctan(x,n=10):
-%     if x < 0:
-%         return -arctan(-x)        #> appel récursif
-%     elif x > 1: 
-%         return pi/2 - arctan(1/x) #> autre appel récursif 
-%     else: 
-%         return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
-% \end{Piton}
-% \endgroup
-%
-%
-% \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.
-%
-%
-% \begingroup
-% \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
-% \begin{Verbatim}
-% \PitonOptions{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:
-%         return -arctan(-x)       #> appel récursif
-%     elif x > 1: 
-%         return pi/2 - arctan(1/x) #> autre appel récursif 
-%     else: 
-%         s = 0
-%         for k in range(n):
-%              s += (-1)**k/(2*k+1)*x**(2*k+1)
-%         return s 
-% \end{Piton}
-% ~emphase&\end{minipage}@
-% \end{Verbatim}
-% \endgroup
-%
-%
-%
-% \begingroup
-% \PitonOptions{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:
-%         return -arctan(-x)       #> appel récursif
-%     elif x > 1: 
-%         return pi/2 - arctan(1/x) #> autre appel récursif 
-%     else: 
-%         s = 0
-%         for k in range(n):
-%              s += (-1)**k/(2*k+1)*x**(2*k+1)
-%         return s 
-% \end{Piton}
-% \end{minipage}
-% \endgroup
-%
-%
-% \bigskip
-% \subsection{Notes in the listings}
-%
-% \label{notes-examples}
-% 
-% In order to be able to extract the notes (which are typeset with the command
-% |\footnote|), the extension \pkg{piton} must be loaded with the key |footnote|
-% or the key |footenotehyper| as explained in the section \ref{footnote}
-% p.~\pageref{footnote}. In this document, the extension \pkg{piton} has been
-% loaded with the key |footnotehyper|.
-%
-% Of course, in an environment |{Piton}|, a command |\footnote| may appear only
-% within a LaTeX comment (which begins with |#>|). It's possible to have comments
-% which contain only that command |\footnote|. That's the case in the following example.
-%
-%
-%
-% \begingroup
-% \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
-% \begin{Verbatim}
-% \PitonOptions{background-color=gray!10}
-% \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{Verbatim}
-% \endgroup
-%
-% \begingroup
-% \PitonOptions{background-color=gray!10}
-% \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}
-% \endgroup
-%
-%
-% \vspace{1cm}
-%
-% If an environment |{Piton}| is used in an environment |{minipage}| of LaTeX,
-% the notes are composed, of course, at the foot of the environment
-% |{minipage}|. Recall that such |{minipage}| can't be broken by a page break.
-%
-%
-% \begingroup
-% \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
-% \begin{Verbatim}
-% \PitonOptions{background-color=gray!10}
-% \emphase\begin{minipage}{\linewidth}
-% \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}
-% \end{Verbatim}
-% \endgroup
-%
-% \begingroup
-% \PitonOptions{background-color=gray!10}
-% \begin{minipage}{\linewidth}
-% \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}
-% \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}
-%
-% The graphical styles have been presented in the section \ref{styles},
-% p.~\pageref{styles}.
-%
-% \smallskip
-% We present now an example of tuning of these styles adapted to the documents
-% in black and white. We use the font \emph{DejaVu Sans Mono}\footnote{See:
-% \url{https://dejavu-fonts.github.io}} specified by the command |\setmonofont| of 
-% \pkg{fontspec}. 
-%
-% That tuning uses the command |\highLight| of \pkg{lua-ul} (that package
-% requires itself the package \pkg{luacolor}).
-%
-% \begin{Verbatim}
-% \setmonofont[Scale=0.85]{DejaVu Sans Mono}
-%
-% \SetPitonStyle
-%   {
-%     Number = ,
-%     String = \itshape , 
-%     String.Doc = \color{gray} \slshape ,
-%     Operator = , 
-%     Operator.Word = \bfseries ,
-%     Name.Builtin = ,
-%     Name.Function = \bfseries \highLight[gray!20] ,
-%     Comment = \color{gray} ,
-%     Comment.LaTeX = \normalfont \color{gray},
-%     Keyword = \bfseries ,
-%     Name.Namespace = ,
-%     Name.Class = , 
-%     Name.Type = ,
-%     InitialValues = \color{gray}
-%   }
-% \end{Verbatim}
-%
-%
-% \begingroup
-%
-% \setmonofont[Scale=0.85]{DejaVu Sans Mono}
-%
-%  \PitonOptions{splittable}
-%
-% \SetPitonStyle
-%   {
-%     Number = ,
-%     String = \itshape , 
-%     String.Doc = \color{gray} \slshape ,
-%     Operator.Word = \bfseries ,
-%     Operator = , 
-%     Name.Builtin = ,
-%     Name.Function = \bfseries \highLight[gray!20] ,
-%     Comment = \color{gray} ,
-%     Comment.LaTeX = \normalfont \color{gray} ,
-%     Keyword = \bfseries ,
-%     Name.Namespace = ,
-%     Name.Class = , 
-%     Name.Type = ,
-%     InitialValues = \color{gray}
-%   }
-%
-%
-% \bigskip
-%
-% \begin{Piton}
-% from math import pi
-%
-% def arctan(x,n=10):
-%     """Compute the mathematical value of arctan(x)
-%                                               
-%     n is the number of terms in the sum
-%     """
-%     if x < 0:
-%         return -arctan(-x) # appel récursif
-%     elif x > 1: 
-%         return pi/2 - arctan(1/x) 
-%         #> (we have used that $\arctan(x)+\arctan(1/x)=\pi/2$ for $x>0$)
-%     else: 
-%         s = 0
-%         for k in range(n):
-%             s += (-1)**k/(2*k+1)*x**(2*k+1)
-%         return s 
-% \end{Piton}
-%
-% \endgroup
-% 
-% \subsection{Use with pyluatex}
-%
-% The package \pkg{pyluatex} is an extension which allows the execution of some
-% Python code from |lualatex| (provided that Python is installed on the machine
-% and that the compilation is done with |lualatex| and |--shell-escape|).
-%
-% Here is, for example, an environment |{PitonExecute}| which formats a Python
-% listing (with \pkg{piton}) but display also the output of the execution of the
-% code with Python (for technical reasons, the |!| is mandatory in the signature
-% of the environment).
-%
-%
-% \begin{Verbatim}
-% \ExplSyntaxOn
-% \NewDocumentEnvironment { ~emphase#PitonExecute@ } { ! O { } } % the ! is mandatory 
-%   { 
-%     \PyLTVerbatimEnv
-%     \begin{pythonq} 
-%   }
-%   {
-%     \end{pythonq}
-%     \directlua
-%       {
-%         tex.print("\\PitonOptions{~#1}")
-%         tex.print("\\begin{Piton}")
-%         tex.print(pyluatex.get_last_code())
-%         tex.print("\\end{Piton}")
-%         tex.print("") 
-%       }
-%     \begin{center}
-%       \directlua{tex.print(pyluatex.get_last_output())}
-%     \end{center}
-%   }
-% \ExplSyntaxOff
-% \end{Verbatim}
-%
-% \ExplSyntaxOn
-% \NewDocumentEnvironment { PitonExecute } { ! O { } } 
-%   { 
-%     \PyLTVerbatimEnv
-%     \begin{pythonq} 
-%   }
-%   {
-%     \end{pythonq}
-%     \directlua
-%       {
-%         tex.print("\\PitonOptions{#1}")
-%         tex.print("\\begin{Piton}")
-%         tex.print(pyluatex.get_last_code())
-%         tex.print("\\end{Piton}")
-%         tex.print("") 
-%       }
-%     \begin{center}
-%       \directlua{tex.print(pyluatex.get_last_output())}
-%     \end{center}
-%   }
-% \ExplSyntaxOff
-%
-% This environment |{PitonExecute}| takes in as optional argument (between
-% square brackets) the options of the command |\PitonOptions|.
-%
-%
-% \bigskip
-% \clearpage
-%
-% \section{Implementation}
-%
-% \subsection{Introduction}
-% 
-% The main job of the package \pkg{piton} is to take in as input a Python
-% listing and to send back to LaTeX as output that code \emph{with interlaced LaTeX
-% instructions of formatting}.
-%
-% In fact, all that job is done by a \textsc{lpeg} called |python|. That
-% \textsc{lpeg}, when matched against the string of a Python listing,
-% returns as capture a Lua table containing data to send to LaTeX. 
-% The only thing to do after will be to apply |tex.tprint| to each element of
-% that table.\footnote{Recall that |tex.tprint| takes in as argument a Lua table whose
-% first component is a ``catcode table'' and the second element a string. The
-% string will be sent to LaTeX with the regime of catcodes specified by the
-% catcode table. If no catcode table is provided, the standard catcodes of LaTeX
-% will be used.}
-% 
-% \bigskip
-% Consider, for example, the following Python code:
-%
-% \begin{Piton}
-% def parity(x):
-%     return x%2
-% \end{Piton}
-%
-% The capture returned by the \pkg{lpeg} |python| against that code is the
-% Lua table containing the following elements :
-%
-% \bigskip
-% \begin{minipage}{\linewidth}
-% \color{gray}
-% 
-% |{ "\\__piton_begin_line:" }|\footnote{Each line of the Python listings will
-% be encapsulated in a pair: \texttt{\textbackslash_@@_begin_line:} --
-% \texttt{\textbackslash@@_end_line:}. The token
-% \texttt{\textbackslash@@_end_line:} must be explicit because it will be used as
-% marker in order to delimit the argument of the command \texttt{\textbackslash
-% @@\_begin\_line:}. Both tokens \texttt{\textbackslash_@@_begin_line:} and
-% \texttt{\textbackslash@@_end_line:} will be nullified in the command
-% \texttt{\textbackslash piton} (since there can't be lines breaks in the
-% argument of a command \texttt{\textbackslash piton}).}  
-% 
-% \texttt{\{ "\{\textbackslash PitonStyle\{Keyword\}\{" \}}\footnote{The
-% lexical elements of Python for which we have a \pkg{piton} style will be
-% formatted via the use of the command \texttt{\textbackslash PitonStyle}.
-% Such an element is typeset in LaTeX via the syntax \texttt{\{\textbackslash
-% PitonStyle\{\textsl{style}\}\{...\}\}} because the instructions inside an \texttt{\textbackslash
-% PitonStyle} may be both semi-global declarations like
-% \texttt{\textbackslash bfseries} and commands with one argument like
-% \texttt{\textbackslash fbox}.}
-%
-% \texttt{\{
-% luatexbase.catcodetables.CatcodeTableOther\footnote{\texttt{luatexbase.catcodetables.CatcodeTableOther} is a mere number which corresponds to the ``catcode table'' whose all characters have the catcode ``other'' (which means that they will be typeset by LaTeX verbatim).}, "def" \} }
-%
-% |{ "}}" }|
-%
-% |{ luatexbase.catcodetables.CatcodeTableOther, " " }|
-%
-% |{ "{\PitonStyle{Name.Function}{" }|
-%
-% |{ luatexbase.catcodetables.CatcodeTableOther, "parity" }|
-%
-% |{ "}}" }|
-% 
-% |{ luatexbase.catcodetables.CatcodeTableOther, "(" }|
-%
-% |{ luatexbase.catcodetables.CatcodeTableOther, "x" }|
-%
-% |{ luatexbase.catcodetables.CatcodeTableOther, ")" }|
-%
-% |{ luatexbase.catcodetables.CatcodeTableOther, ":" }|
-% 
-% |{ "\\__piton_end_line: \\__piton_newline: \\__piton_begin_line:" }|
-%
-% |{ luatexbase.catcodetables.CatcodeTableOther, "    " }|
-%
-% |{ "{\PitonStyle{Keyword}{" }|
-%
-% |{ luatexbase.catcodetables.CatcodeTableOther, "return" }|
-%
-% |{ "}}" }|
-%
-% |{ luatexbase.catcodetables.CatcodeTableOther, " " }|
-%
-% |{ luatexbase.catcodetables.CatcodeTableOther, "x" }|
-%
-% |{ "{\PitonStyle{Operator}{" }|
-%
-% |{ luatexbase.catcodetables.CatcodeTableOther, "&" }|
-%
-% |{ "}}" }|
-%
-% |{ "{\PitonStyle{Number}{" }|
-%
-% |{ luatexbase.catcodetables.CatcodeTableOther, "2" }|
-%
-% |{ "}}" }|
-% 
-% |{ "\\__piton_end_line:" }|
-% 
-% \end{minipage}
-%
-% \bigskip
-% We give now the LaTeX code which is sent back by Lua to TeX (we have written
-% on several lines for legibility but no character |\r| will be sent to LaTeX). The
-% characters which are greyed-out are sent to LaTeX with the catcode ``other''
-% (=12). All the others characters are sent with the regime of catcodes of L3
-% (as set by |\ExplSyntaxOn|)
-%
-% 
-% \begingroup
-% \def\gbox#1{\colorbox{gray!20}{\strut #1}}
-% \setlength{\fboxsep}{1pt}
-% 
-% \begin{Verbatim*}[formatcom = \color{black}]
-% \__piton_begin_line:{\PitonStyle{Keyword}{~gbox#def@}}
-% ~gbox# @{\PitonStyle{Name.Function}{~gbox#parity@}}~gbox#(x):@\__piton_end_line:\__piton_newline:
-% \__piton_begin_line:~gbox#    @{\PitonStyle{Keyword}{~gbox#return@}}
-% ~gbox# x@{\PitonStyle{Operator}{~gbox#%@}}{\PitonStyle{Number}{~gbox#2@}}\__piton_end_line:
-% \end{Verbatim*}
-% \endgroup
-%
-%
-% 
-%
-% \subsection{The L3 part of the implementation}
-%
-% \subsubsection{Declaration of the package}
-%    \begin{macrocode}
-\NeedsTeXFormat{LaTeX2e}
-\RequirePackage{l3keys2e}
-\ProvidesExplPackage
-  {piton}
-  {\myfiledate}
-  {\myfileversion}
-  {Highlight Python codes with LPEG on LuaLaTeX}
-%    \end{macrocode}
-%
-% \bigskip
-%    \begin{macrocode}
-\msg_new:nnn { piton } { LuaLaTeX~mandatory }
-  { 
-    LuaLaTeX~is~mandatory.\\
-    The~package~'piton'~requires~the~engine~LuaLaTeX.\\
-    \str_if_eq:VnT \c_sys_jobname_str { output }
-      { If~you~use~Overleaf,~you~can~switch~to~LuaLaTeX~in~the~"Menu". \\}
-    If~you~go~on,~the~package~'piton'~won't~be~loaded.
-  }
-\sys_if_engine_luatex:F { \msg_critical:nn { piton } { LuaLaTeX~mandatory } }
-%    \end{macrocode}
-% 
-% \bigskip
-%    \begin{macrocode}
-\RequirePackage { luatexbase } 
-%    \end{macrocode}
-%
-% \bigskip
-% The boolean |\c_@@_footnotehyper_bool| will indicate if the option
-% |footnotehyper| is used.
-%    \begin{macrocode}
-\bool_new:N \c_@@_footnotehyper_bool
-%    \end{macrocode}
-%
-% \medskip
-% The boolean |\c_@@_footnote_bool| will indicate if the option |footnote| is
-% used, but quicky, it will also be set to |true| if the option |footnotehyper|
-% is used.
-%    \begin{macrocode}
-\bool_new:N \c_@@_footnote_bool
-%    \end{macrocode}
-%
-% \medskip
-% The following boolean corresponds to the key |math-comments| (only at load-time).
-%    \begin{macrocode}
-\bool_new:N \c_@@_math_comments_bool
-%    \end{macrocode}
-%
-% \medskip
-% The following boolean corresponds to the key |beamer|. 
-%    \begin{macrocode}
-\bool_new:N \c_@@_beamer_bool
-%    \end{macrocode}
-% 
-% \bigskip
-% We define a set of keys for the options at load-time.
-%    \begin{macrocode}
-\keys_define:nn { piton / package }
-  { 
-    footnote .bool_set:N = \c_@@_footnote_bool ,
-    footnotehyper .bool_set:N = \c_@@_footnotehyper_bool ,
-    escape-inside .tl_set:N = \c_@@_escape_inside_tl ,
-    escape-inside .initial:n = , 
-    comment-latex .code:n = { \lua_now:n { comment_latex = "#1" } } ,   
-    comment-latex .value_required:n = true ,
-    math-comments .bool_set:N = \c_@@_math_comments_bool ,
-    math-comments .default:n  = true ,
-    beamer        .bool_set:N = \c_@@_beamer_bool ,
-    beamer        .default:n = true , 
-    unknown .code:n = \msg_error:nn { piton } { unknown~key~for~package }
-  }
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-\msg_new:nnn { piton } { unknown~key~for~package }
-  {
-    Unknown~key.\\
-    You~have~used~the~key~'\l_keys_key_str'~but~the~only~keys~available~here~
-    are~'beamer',~'comment-latex',~'escape-inside',~'footnote',~'footnotehyper'~and~ 
-    'math-comments'.~Other~keys~are~available~in~\token_to_str:N \PitonOptions.\\
-    That~key~will~be~ignored.
-  }
-%    \end{macrocode}
-%
-% \bigskip
-% We process the options provided by the user at load-time.
-%    \begin{macrocode}
-\ProcessKeysOptions { piton / package }
-%    \end{macrocode}
-%
-% \bigskip
-%    \begin{macrocode}
-\begingroup
-\cs_new_protected:Npn \@@_set_escape_char:nn #1 #2 
-  {
-    \lua_now:n { piton_begin_escape = "#1" }
-    \lua_now:n { piton_end_escape = "#2" }
-  }
-\cs_generate_variant:Nn \@@_set_escape_char:nn { x x }
-\@@_set_escape_char:xx 
-  { \tl_head:V \c_@@_escape_inside_tl }
-  { \tl_tail:V \c_@@_escape_inside_tl }
-\endgroup
-%    \end{macrocode}
-% 
-% \bigskip
-%    \begin{macrocode}
-\@ifclassloaded { beamer } { \bool_set_true:N \c_@@_beamer_bool } { }
-\bool_if:NT \c_@@_beamer_bool { \lua_now:n { piton_beamer = true } }
-%    \end{macrocode}
-% 
-% \bigskip
-%    \begin{macrocode}
-\hook_gput_code:nnn { begindocument } { . }
-  {
-    \@ifpackageloaded { xcolor }
-      { }
-      { \msg_fatal:nn { piton } { xcolor~not~loaded } }
-  }
-%    \end{macrocode}
-%
-%    \begin{macrocode}     
-\msg_new:nnn { piton } { xcolor~not~loaded }
-  {
-    xcolor~not~loaded \\
-    The~package~'xcolor'~is~required~by~'piton'.\\
-    This~error~is~fatal.
-  }
-%    \end{macrocode}
-% 
-%
-%    \begin{macrocode}
-\msg_new:nnn { piton } { footnote~with~footnotehyper~package }
-  { 
-    Footnote~forbidden.\\
-    You~can't~use~the~option~'footnote'~because~the~package~
-    footnotehyper~has~already~been~loaded.~
-    If~you~want,~you~can~use~the~option~'footnotehyper'~and~the~footnotes~  
-    within~the~environments~of~piton~will~be~extracted~with~the~tools~
-    of~the~package~footnotehyper.\\
-    If~you~go~on,~the~package~footnote~won't~be~loaded.
-  }
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-\msg_new:nnn { piton } { footnotehyper~with~footnote~package }
-  { 
-    You~can't~use~the~option~'footnotehyper'~because~the~package~
-    footnote~has~already~been~loaded.~
-    If~you~want,~you~can~use~the~option~'footnote'~and~the~footnotes~  
-    within~the~environments~of~piton~will~be~extracted~with~the~tools~
-    of~the~package~footnote.\\ 
-    If~you~go~on,~the~package~footnotehyper~won't~be~loaded.
-  }
-%    \end{macrocode}
-%
-% \medskip
-%    \begin{macrocode}
-\bool_if:NT \c_@@_footnote_bool 
-  { 
-%    \end{macrocode}
-% The class \cls{beamer} has its own system to extract footnotes and that's why
-% we have nothing to do if \cls{beamer} is used. 
-%    \begin{macrocode}
-    \@ifclassloaded { beamer }
-      { \bool_set_false:N \c_@@_footnote_bool }
-      { 
-        \@ifpackageloaded { footnotehyper }
-          { \@@_error:n { footnote~with~footnotehyper~package } }
-          { \usepackage { footnote } }
-      }
-  }
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-\bool_if:NT \c_@@_footnotehyper_bool 
-  { 
-%    \end{macrocode}
-% The class \cls{beamer} has its own system to extract footnotes and that's why
-% we have nothing to do if \cls{beamer} is used. 
-%    \begin{macrocode}
-    \@ifclassloaded { beamer }
-      { \bool_set_false:N \c_@@_footnote_bool }
-      { 
-        \@ifpackageloaded { footnote }
-          { \@@_error:n { footnotehyper~with~footnote~package } }
-          { \usepackage { footnotehyper } }
-        \bool_set_true:N \c_@@_footnote_bool 
-      }
-  }
-%    \end{macrocode}
-% The flag |\c_@@_footnote_bool| is raised and so, we will only have to test
-% |\c_@@_footnote_bool| in order to know if we have to insert an environment
-% |{savenotes}|.
-% 
-% \bigskip
-% \subsubsection{Parameters and technical definitions}
-%
-% The following string will contain the name of the informatic language
-% considered (the initial value is |python|).
-%
-%    \begin{macrocode}
-\str_new:N \l_@@_language_str
-\str_set:Nn \l_@@_language_str { python }
-%    \end{macrocode}
-% 
-% We will compute (with Lua) the numbers of lines of the Python code and store
-% it in the following counter.
-%    \begin{macrocode}
-\int_new:N \l_@@_nb_lines_int
-%    \end{macrocode}
-% 
-% The same for the number of non-empty lines of the Python codes.
-%    \begin{macrocode}
-\int_new:N \l_@@_nb_non_empty_lines_int
-%    \end{macrocode}
-% 
-% The following counter will be used to count the lines during the composition.
-% It will count all the lines, empty or not empty. It won't be used to print the
-% numbers of the lines.
-%    \begin{macrocode}
-\int_new:N \g_@@_line_int
-%    \end{macrocode}
-% 
-% \medskip
-% The following token list will contains the (potential) informations to write
-% on the |aux| (to be used in the next compilation).
-%    \begin{macrocode}
-\tl_new:N \g_@@_aux_tl
-%    \end{macrocode}
-% 
-% \medskip
-% The following counter corresponds to the key |splittable| of |\PitonOptions|.
-% If the value of |\l_@@_splittable_int| is equal to $n$, then no line break can
-% occur within the first $n$~lines or the last $n$~lines of the listings.
-%    \begin{macrocode}
-\int_new:N \l_@@_splittable_int
-%    \end{macrocode}
-%
-% \medskip
-% An initial value of |splittable| equal to 100 is equivalent to say that the
-% environments |{Piton}| are unbreakable.
-%    \begin{macrocode}
-\int_set:Nn \l_@@_splittable_int { 100 }
-%    \end{macrocode}
-%
-% \medskip
-% The following string corresponds to the key |background-color| of |\PitonOptions|.
-%    \begin{macrocode}
-\clist_new:N \l_@@_bg_color_clist
-%    \end{macrocode}
-%
-% \medskip
-% The package \pkg{piton} will also detect the lines of code which correspond to
-% the user input in a Python console, that is to say the lines of code beginning
-% with |>>>| and |...|. It's possible, with the key |prompt-background-color|,
-% to require a background for these lines of code (and the other lines of code
-% will have the standard background color specified by |background-color|).
-%    \begin{macrocode}
-\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
-% |\PitonInputFile|, despite the name |\g_@@_env_int|).
-%    \begin{macrocode}
-\int_new:N \g_@@_env_int 
-%    \end{macrocode}
-%
-% \medskip
-% The following boolean corresponds to the key |show-spaces|.
-%    \begin{macrocode}
-\bool_new:N \l_@@_show_spaces_bool
-%    \end{macrocode}
-%
-% \medskip
-% The following booleans correspond to the keys |break-lines| and
-% |indent-broken-lines|.
-%    \begin{macrocode}
-\bool_new:N \l_@@_break_lines_in_Piton_bool
-\bool_new:N \l_@@_indent_broken_lines_bool
-%    \end{macrocode}
-%
-% \medskip
-% The following token list corresponds to the key |continuation-symbol|.
-%    \begin{macrocode}
-\tl_new:N \l_@@_continuation_symbol_tl
-\tl_set:Nn \l_@@_continuation_symbol_tl { + }
-%    \end{macrocode}
-%
-% \medskip
-%    \begin{macrocode}
-% The following token list corresponds to the key
-% |continuation-symbol-on-indentation|. The name has been shorten to |csoi|.
-\tl_new:N \l_@@_csoi_tl 
-\tl_set:Nn \l_@@_csoi_tl { $ \hookrightarrow \; $  }
-%    \end{macrocode}
-%
-% \medskip
-% The following token list corresponds to the key |end-of-broken-line|.
-%    \begin{macrocode}
-\tl_new:N \l_@@_end_of_broken_line_tl 
-\tl_set:Nn \l_@@_end_of_broken_line_tl { \hspace*{0.5em} \textbackslash }
-%    \end{macrocode}
-%
-% \medskip
-% The following boolean corresponds to the key |break-lines-in-piton|.
-%    \begin{macrocode}
-\bool_new:N \l_@@_break_lines_in_piton_bool
-%    \end{macrocode}
-% 
-% \medskip
-% The following boolean corresponds to the key |slim| of |\PitonOptions|.
-%    \begin{macrocode}
-\bool_new:N \l_@@_slim_bool
-%    \end{macrocode}
-%
-% \medskip
-% The following dimension corresponds to the key |left-margin| of |\PitonOptions|. 
-%    \begin{macrocode}
-\dim_new:N \l_@@_left_margin_dim
-%    \end{macrocode}
-%
-% \medskip
-% The following boolean will be set when the key |left-margin=auto|
-% is used.
-%    \begin{macrocode}
-\bool_new:N \l_@@_left_margin_auto_bool
-%    \end{macrocode}
-%
-% \medskip
-% The following dimension corresponds to the key |numbers-sep| of
-% |\PitonOptions|.
-%    \begin{macrocode}
-\dim_new:N \l_@@_numbers_sep_dim 
-\dim_set:Nn \l_@@_numbers_sep_dim { 0.7 em }
-%    \end{macrocode}
-% 
-% \medskip
-% The tabulators will be replaced by the content of the following token list.
-%    \begin{macrocode}
-\tl_new:N \l_@@_tab_tl
-%    \end{macrocode}
-%
-% \medskip
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_set_tab_tl:n #1
-  { 
-    \tl_clear:N \l_@@_tab_tl
-    \prg_replicate:nn { #1 } 
-      { \tl_put_right:Nn \l_@@_tab_tl { ~ } }
-  }
-\@@_set_tab_tl:n { 4 }
-%    \end{macrocode}
-% 
-% \medskip
-% The following integer corresponds to the key |gobble|.
-%    \begin{macrocode}
-\int_new:N \l_@@_gobble_int 
-%    \end{macrocode}
-%
-% \medskip
-%    \begin{macrocode}
-\tl_new:N \l_@@_space_tl
-\tl_set:Nn \l_@@_space_tl { ~ } 
-%    \end{macrocode}
-% 
-%
-% \medskip
-% At each line, the following counter will count the spaces at the beginning.
-%    \begin{macrocode}
-\int_new:N \g_@@_indentation_int
-%    \end{macrocode}
-% 
-% \medskip
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_an_indentation_space:
-  { \int_gincr:N \g_@@_indentation_int }
-%    \end{macrocode}
-%
-% \medskip
-% The following command |\@@_beamer_command:n| executes the argument
-% corresponding to its argument but also stores it in |\l_@@_beamer_command_str|.
-% That string is used only in the error message ``|cr~not~allowed|'' raised when
-% there is a carriage return in the mandatory argument of that command.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_beamer_command:n #1 
-  { 
-    \str_set:Nn \l_@@_beamer_command_str { #1 } 
-    \use:c { #1 } 
-  }
-%    \end{macrocode}
-% 
-% \bigskip
-% In the environment |{Piton}|, the command |\label| will be linked to the
-% following command.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_label:n #1
-  {
-    \bool_if:NTF \l_@@_line_numbers_bool
-      {
-        \@bsphack 
-        \protected@write \@auxout { }
-          { 
-            \string \newlabel { #1 } 
-            { 
-%    \end{macrocode}
-% Remember that the content of a line is typeset in a box \emph{before} the
-% composition of the potential number of line.
-%    \begin{macrocode}
-              { \int_eval:n { \g_@@_visual_line_int + 1 } } 
-              { \thepage } 
-            } 
-          } 
-        \@esphack
-     }
-     { \msg_error:nn { piton } { label~with~lines~numbers } }
-  }
-%    \end{macrocode}
-%
-% 
-% \bigskip
-% The following commands are a easy way to insert safely braces (|{| and |}|) in
-% the TeX flow.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_open_brace:
-  { \directlua { piton.open_brace() } }
-\cs_new_protected:Npn \@@_close_brace:
-  { \directlua { piton.close_brace() } }
-%    \end{macrocode}
-% 
-% \bigskip
-% The following token list will be evaluated at the beginning of
-% |\@@_begin_line:|... |\@@_end_line:| and cleared at the end. It will be used
-% by LPEG acting between the lines of the Python code in order to add
-% instructions to be executed at the beginning of the line.
-%    \begin{macrocode} 
-\tl_new:N \g_@@_begin_line_hook_tl
-%    \end{macrocode}
-%
-% \smallskip
-% For example, the LPEG |Prompt| will trigger the following command which will
-% insert an instruction in the hook |\g_@@_begin_line_hook| to specify that a
-% background must be inserted to the current line of code.
-%    \begin{macrocode}
-\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 } 
-      }
-  }
-%    \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}
-% 
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_replace_spaces:n #1 
-  {
-    \tl_set:Nn \l_tmpa_tl { #1 } 
-    \bool_if:NTF \l_@@_show_spaces_bool
-      { \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl } % U+2423
-      {
-%    \end{macrocode}
-% If the key |break-lines-in-Piton| is in force, we replace all the characters
-% U+0020 (that is to say the spaces) by |\@@_breakable_space:|. Remark that,
-% except the spaces inserted in the LaTeX comments (and maybe in the math
-% comments), all these spaces are of catcode ``other'' (=12) and are
-% unbreakable.
-%    \begin{macrocode}
-        \bool_if:NT \l_@@_break_lines_in_Piton_bool
-          { 
-            \regex_replace_all:nnN 
-              { \x20 } 
-              { \c { @@_breakable_space: } }
-              \l_tmpa_tl 
-          } 
-      }
-    \l_tmpa_tl 
-  }
-\cs_generate_variant:Nn \@@_replace_spaces:n { x } 
-%    \end{macrocode}
-% 
-% \bigskip
-% In the contents provided by Lua, each line of the Python code will be
-% surrounded by |\@@_begin_line:| and |\@@_end_line:|. |\@@_begin_line:| is a
-% LaTeX command that we will define now but |\@@_end_line:| is only a syntactic
-% marker that has no definition.
-%
-%    \begin{macrocode}
-\cs_set_protected:Npn \@@_begin_line: #1 \@@_end_line:
-  { 
-    \group_begin:
-    \g_@@_begin_line_hook_tl
-    \int_gzero:N \g_@@_indentation_int
-%    \end{macrocode}
-%
-% 
-% Be careful: there is curryfication in the following lines.
-%    \begin{macrocode}
-    \bool_if:NTF \l_@@_slim_bool
-      { \hcoffin_set:Nn \l_tmpa_coffin }
-      { 
-        \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 
-        \@@_replace_spaces:n { #1 }
-        \strut \hfil 
-      } 
-    \hbox_set:Nn \l_tmpa_box 
-      { 
-        \skip_horizontal:N \l_@@_left_margin_dim
-        \bool_if:NT \l_@@_line_numbers_bool
-          {
-            \bool_if:NF \l_@@_all_line_numbers_bool
-              { \tl_if_empty:nF { #1 } }
-              \@@_print_number:
-          }
-        \clist_if_empty:NF \l_@@_bg_color_clist 
-          { 
-            \dim_compare:nNnT \l_@@_left_margin_dim = \c_zero_dim 
-               { 
-                 \bool_if:NF \l_@@_left_margin_auto_bool
-                   { \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 
-          { 
-            \hbox:n
-              { 
-                \@@_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
-              } 
-            \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
-          }
-      }   
-    \vspace { - 2.5 pt }
-    \group_end:
-    \tl_gclear:N \g_@@_begin_line_hook_tl
-  }
-%    \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).
-%    \begin{macrocode}
-\cs_set_protected:Npn \@@_color:N #1 
-  {
-    \int_set:Nn \l_tmpa_int { \clist_count:N #1 }
-    \int_set:Nn \l_tmpb_int { \int_mod:nn \g_@@_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 }
-%    \end{macrocode}
-% By setting |\l_@@_width_on_aux_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 }
-      { \exp_args:NV \@@_color_i:n \l_tmpa_tl }
-  }
-%    \end{macrocode}
-%
-% The following command |\@@_color:n| will accept both the instruction
-% |\@@_color:n { red!15 }| and the instruction |\@@_color:n { [rgb]{0.9,0.9,0} }|.
-%    \begin{macrocode}
-\cs_set_protected:Npn \@@_color_i:n #1
-  {
-    \tl_if_head_eq_meaning:nNTF { #1 } [ 
-      { 
-        \tl_set:Nn \l_tmpa_tl { #1 }
-        \tl_set_rescan:Nno \l_tmpa_tl { } \l_tmpa_tl 
-        \exp_last_unbraced:NV \color \l_tmpa_tl
-      }
-      { \color { #1 } }
-  }
-\cs_generate_variant:Nn \@@_color:n { V }
-%    \end{macrocode}
-% 
-% \bigskip
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_newline: 
-  { 
-    \int_gincr:N \g_@@_line_int
-    \int_compare:nNnT \g_@@_line_int > { \l_@@_splittable_int - 1 }
-      {
-        \int_compare:nNnT 
-          { \l_@@_nb_lines_int - \g_@@_line_int } > \l_@@_splittable_int 
-          {
-            \egroup
-            \bool_if:NT \c_@@_footnote_bool { \end { savenotes } } 
-            \newline
-            \bool_if:NT \c_@@_footnote_bool { \begin { savenotes } } 
-            \vtop \bgroup
-          }
-     }
-  } 
-%    \end{macrocode}
-%
-% \bigskip
-%    \begin{macrocode}
-\cs_set_protected:Npn \@@_breakable_space:
-  { 
-    \discretionary 
-      { \hbox:n { \color { gray } \l_@@_end_of_broken_line_tl } } 
-      { 
-        \hbox_overlap_left:n 
-          { 
-            { 
-              \normalfont \footnotesize \color { gray } 
-              \l_@@_continuation_symbol_tl 
-            } 
-            \skip_horizontal:n { 0.3 em }  
-            \clist_if_empty:NF \l_@@_bg_color_clist 
-              { \skip_horizontal:n { 0.5 em } }
-          }  
-        \bool_if:NT \l_@@_indent_broken_lines_bool
-          { 
-            \hbox:n
-              { 
-                \prg_replicate:nn { \g_@@_indentation_int } { ~ } 
-                { \color { gray } \l_@@_csoi_tl }
-              } 
-          } 
-      } 
-      { \hbox { ~ } }
-  }
-%    \end{macrocode}
-% 
-% \bigskip
-% \subsubsection{PitonOptions}
-%
-% \medskip
-% The following parameters correspond to the keys |line-numbers| and
-% |all-line-numbers|.
-%    \begin{macrocode}
-\bool_new:N \l_@@_line_numbers_bool 
-\bool_new:N \l_@@_all_line_numbers_bool 
-%    \end{macrocode}
-% 
-% \medskip
-% The following flag corresponds to the key |resume|.
-%    \begin{macrocode}
-\bool_new:N \l_@@_resume_bool 
-%    \end{macrocode}
-% 
-% \bigskip
-% Be careful! The name of the following set of keys must be considered as
-% public! Hence, it should \emph{not} be changed.
-% 
-%    \begin{macrocode}
-\keys_define:nn { PitonOptions }
-  {
-    language         .str_set:N         = \l_@@_language_str ,
-    language         .value_required:n  = true ,
-    gobble           .int_set:N         = \l_@@_gobble_int , 
-    gobble           .value_required:n  = true ,
-    auto-gobble      .code:n            = \int_set:Nn \l_@@_gobble_int { -1 } , 
-    auto-gobble      .value_forbidden:n = true ,
-    env-gobble       .code:n            = \int_set:Nn \l_@@_gobble_int { -2 } , 
-    env-gobble       .value_forbidden:n = true ,
-    tabs-auto-gobble .code:n            = \int_set:Nn \l_@@_gobble_int { -3 } , 
-    tabs-auto-gobble .value_forbidden:n = true ,
-    line-numbers     .bool_set:N        = \l_@@_line_numbers_bool ,
-    line-numbers     .default:n         = true ,
-    all-line-numbers .code:n = 
-      \bool_set_true:N \l_@@_line_numbers_bool 
-      \bool_set_true:N \l_@@_all_line_numbers_bool ,
-    all-line-numbers .value_forbidden:n = true  ,
-    resume           .bool_set:N        = \l_@@_resume_bool ,
-    resume           .value_forbidden:n = true ,
-    splittable       .int_set:N         = \l_@@_splittable_int ,
-    splittable       .default:n         = 1 , 
-    background-color .clist_set:N       = \l_@@_bg_color_clist ,
-    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 ,
-    left-margin      .code:n =
-      \str_if_eq:nnTF { #1 } { auto }
-        { 
-          \dim_zero:N \l_@@_left_margin_dim 
-          \bool_set_true:N \l_@@_left_margin_auto_bool
-        }
-        { \dim_set:Nn \l_@@_left_margin_dim { #1 } } ,
-    left-margin      .value_required:n  = true ,
-    numbers-sep      .dim_set:N         = \l_@@_numbers_sep_dim ,
-    numbers-sep      .value_required:n  = true , 
-    tab-size         .code:n            = \@@_set_tab_tl:n { #1 } ,
-    tab-size         .value_required:n  = true , 
-    show-spaces      .bool_set:N        = \l_@@_show_spaces_bool , 
-    show-spaces      .default:n         = true , 
-    show-spaces-in-strings .code:n      = \tl_set:Nn \l_@@_space_tl { ␣ } , % U+2423
-    show-spaces-in-strings .value_forbidden:n = true ,
-    break-lines-in-Piton .bool_set:N    = \l_@@_break_lines_in_Piton_bool ,
-    break-lines-in-Piton .default:n     = true ,
-    break-lines-in-piton .bool_set:N    = \l_@@_break_lines_in_piton_bool ,
-    break-lines-in-piton .default:n     = true ,
-    break-lines .meta:n = { break-lines-in-piton , break-lines-in-Piton } , 
-    break-lines .value_forbidden:n      = true ,
-    indent-broken-lines .bool_set:N     = \l_@@_indent_broken_lines_bool ,
-    indent-broken-lines .default:n      = true ,
-    end-of-broken-line  .tl_set:N       = \l_@@_end_of_broken_line_tl ,
-    end-of-broken-line  .value_required:n = true , 
-    continuation-symbol .tl_set:N       = \l_@@_continuation_symbol_tl ,
-    continuation-symbol .value_required:n = true , 
-    continuation-symbol-on-indentation .tl_set:N = \l_@@_csoi_tl ,
-    continuation-symbol-on-indentation .value_required:n = true , 
-    unknown          .code:n = 
-      \msg_error:nn { piton } { Unknown~key~for~PitonOptions }
-  }
-%    \end{macrocode}
-%
-% 
-%  \bigskip
-% 
-% \bigskip
-% The argument of |\PitonOptions| is provided by curryfication.
-%    \begin{macrocode}
-\NewDocumentCommand \PitonOptions { } { \keys_set:nn { PitonOptions } }
-%    \end{macrocode}
-%
-% \bigskip
-% \subsubsection{The numbers of the lines}
-%
-% \medskip
-% The following counter will be used to count the lines in the code when the
-% user requires the numbers of the lines to be printed (with |line-numbers| or
-% |all-line-numbers|). 
-%
-%    \begin{macrocode}
-\int_new:N \g_@@_visual_line_int 
-%    \end{macrocode}
-% 
-% 
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_print_number:
-  {
-    \int_gincr:N \g_@@_visual_line_int
-    \hbox_overlap_left:n
-      { 
-        { \color { gray } \footnotesize \int_to_arabic:n \g_@@_visual_line_int }
-        \skip_horizontal:N \l_@@_numbers_sep_dim  
-      }
-  }
-%    \end{macrocode}
-% 
-%
-% \bigskip
-% \subsubsection{The command to write on the aux file}
-%
-%   
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_write_aux:
-  {
-    \tl_if_empty:NF \g_@@_aux_tl 
-      {
-        \iow_now:Nn \@mainaux { \ExplSyntaxOn }
-        \iow_now:Nx \@mainaux 
-          {
-            \tl_gset:cn { c_@@_ \int_use:N \g_@@_env_int _ tl } 
-              { \exp_not:V \g_@@_aux_tl } 
-          }
-        \iow_now:Nn \@mainaux { \ExplSyntaxOff }
-      }
-    \tl_gclear:N \g_@@_aux_tl 
-  }
-%    \end{macrocode}
-%
-%    \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 } }
-              }
-          }
-      }
-  }
-%    \end{macrocode}
-% 
-% \bigskip
-% \subsubsection{The main commands and environments for the final user}
-%
-% \bigskip
-%    \begin{macrocode}
-\NewDocumentCommand { \piton } { }
-  { \peek_meaning:NTF \bgroup \@@_piton_standard \@@_piton_verbatim }
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-\NewDocumentCommand { \@@_piton_standard } { m }
-  {
-    \group_begin:
-    \ttfamily
-%    \end{macrocode}
-% The following tuning of LuaTeX in order to avoid all break of lines on the
-% hyphens. 
-%    \begin{macrocode}
-    \automatichyphenmode = 1
-    \cs_set_eq:NN \\ \c_backslash_str
-    \cs_set_eq:NN \% \c_percent_str  
-    \cs_set_eq:NN \{ \c_left_brace_str
-    \cs_set_eq:NN \} \c_right_brace_str
-    \cs_set_eq:NN \$ \c_dollar_str
-    \cs_set_eq:cN { ~ } \space 
-    \cs_set_protected:Npn \@@_begin_line: { }
-    \cs_set_protected:Npn \@@_end_line: { }
-    \tl_set:Nx \l_tmpa_tl 
-      { 
-        \lua_now:e 
-          { piton.ParseBis('\l_@@_language_str',token.scan_string()) }
-          { #1 } 
-      }
-    \bool_if:NTF \l_@@_show_spaces_bool
-      { \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl } % U+2423
-%    \end{macrocode}
-% The following code replaces the characters U+0020 (spaces) by characters
-% U+0020 of catcode~10: thus, they become breakable by an end of line.
-%    \begin{macrocode}
-      {
-        \bool_if:NT \l_@@_break_lines_in_piton_bool
-          { \regex_replace_all:nnN { \x20 } { \x20 } \l_tmpa_tl }
-      }
-    \l_tmpa_tl 
-    \group_end:
-  }
-%    \end{macrocode}
-%
-% 
-%    \begin{macrocode}
-\NewDocumentCommand { \@@_piton_verbatim } { v }
-  {
-    \group_begin:
-    \ttfamily
-    \automatichyphenmode = 1
-    \cs_set_protected:Npn \@@_begin_line: { }
-    \cs_set_protected:Npn \@@_end_line: { }
-    \tl_set:Nx \l_tmpa_tl 
-      { 
-        \lua_now:e 
-          { piton.Parse('\l_@@_language_str',token.scan_string()) } 
-          { #1 } 
-      }
-    \bool_if:NT \l_@@_show_spaces_bool
-      { \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl } % U+2423
-    \l_tmpa_tl 
-    \group_end:
-  }
-%    \end{macrocode}
-%
-
-%  \bigskip
-%
-%
-% \bigskip
-% The following command is not a user command. It will be used when we will
-% have to ``rescan'' some chunks of Python code. For example, it will be the
-% initial value of the Piton style |InitialValues| (the default values of the
-% arguments of a Python function).
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_piton:n #1
-  { 
-    \group_begin:
-    \cs_set_protected:Npn \@@_begin_line: { }
-    \cs_set_protected:Npn \@@_end_line: { }
-    \bool_lazy_or:nnTF 
-      \l_@@_break_lines_in_piton_bool
-      \l_@@_break_lines_in_Piton_bool
-      {
-        \tl_set:Nx \l_tmpa_tl 
-          { 
-            \lua_now:e 
-              { piton.ParseTer('\l_@@_language_str',token.scan_string()) } 
-              { #1 } 
-          }
-      }
-      {
-        \tl_set:Nx \l_tmpa_tl 
-          { 
-            \lua_now:e 
-              { piton.Parse('\l_@@_language_str',token.scan_string()) }
-              { #1 } 
-          }
-      }
-    \bool_if:NT \l_@@_show_spaces_bool
-      { \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl } % U+2423
-    \l_tmpa_tl 
-    \group_end:
-  }
-%    \end{macrocode}
-%
-% \bigskip
-% The following command is similar to the previous one but raise a fatal error if
-% its argument contains a carriage return.
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_piton_no_cr:n #1
-  { 
-    \group_begin:
-    \cs_set_protected:Npn \@@_begin_line: { }
-    \cs_set_protected:Npn \@@_end_line: { }
-    \cs_set_protected:Npn \@@_newline:
-      { \msg_fatal:nn { piton } { cr~not~allowed } }
-    \bool_lazy_or:nnTF 
-      \l_@@_break_lines_in_piton_bool
-      \l_@@_break_lines_in_Piton_bool
-      {
-        \tl_set:Nx \l_tmpa_tl 
-          { 
-            \lua_now:e 
-              { piton.ParseTer('\l_@@_language_str',token.scan_string()) } 
-              { #1 }
-          } 
-      }
-      {
-        \tl_set:Nx \l_tmpa_tl 
-          { 
-            \lua_now:e 
-              { piton.Parse('\l_@@_language_str',token.scan_string()) }
-              { #1 } 
-          }
-      }
-    \bool_if:NT \l_@@_show_spaces_bool
-      { \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl } % U+2423
-    \l_tmpa_tl 
-    \group_end:
-  }
-%    \end{macrocode}
-% 
-% \bigskip
-% Despite its name, |\@@_pre_env:| will be used both in |\PitonInputFile| and
-% in the environments such as |{Piton}|.
-%    \begin{macrocode}
-\cs_new:Npn \@@_pre_env:
-  {
-    \automatichyphenmode = 1
-    \int_gincr:N \g_@@_env_int 
-    \tl_gclear:N \g_@@_aux_tl
-    \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
-    \int_gzero:N \g_@@_line_int
-    \dim_zero:N \parindent 
-    \dim_zero:N \lineskip 
-    \dim_zero:N \parindent 
-    \cs_set_eq:NN \label \@@_label:n
-  }
-%    \end{macrocode}
-% 
-% \bigskip
-%    \begin{macrocode}
-\keys_define:nn { PitonInputFile }
-  {
-    first-line .int_set:N = \l_@@_first_line_int ,  
-    first-line .value_required:n = true ,
-    last-line .int_set:N = \l_@@_last_line_int , 
-    last-line .value_required:n = true , 
-  }
-%    \end{macrocode}
-% 
-% \bigskip
-%    \begin{macrocode}
-\NewDocumentCommand { \PitonInputFile } { d < > O { } m }
-  {
-    \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}     
-% 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|. 
-%    \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 }
-        }
-%    \end{macrocode}
-% Now, the main job.
-%    \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:
-  }
-%    \end{macrocode}
-%
-% 
-% \bigskip 
-%    \begin{macrocode}
-\NewDocumentCommand { \NewPitonEnvironment } { m m m m }
-  { 
-%    \end{macrocode}
-% We construct a TeX macro which will catch as argument all the tokens until
-% |\end{|\texttt{\textsl{name_env}}|}| with, in that
-% |\end{|\texttt{\textsl{name_env}}|}|, the catcodes of |\|, |{| and |}| equal to
-% 12 (``\texttt{other}''). The latter explains why the definition of that
-% function is a bit complicated.
-%    \begin{macrocode}
-    \use:x 
-      { 
-        \cs_set_protected:Npn 
-          \use:c { _@@_collect_ #1 :w } 
-          ####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}
-% 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.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|.
-%    \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 }
-              }
-%    \end{macrocode}
-% Now, the main job.
-%    \begin{macrocode}
-            \ttfamily
-            \bool_if:NT \c_@@_footnote_bool { \begin { savenotes } } 
-            \vtop \bgroup 
-            \lua_now:e 
-              { 
-                piton.GobbleParse
-                  ( 
-                    '\l_@@_language_str' , 
-                    \int_use:N \l_@@_gobble_int , 
-                    token.scan_argument() 
-                  ) 
-              } 
-              { ##1 }
-            \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.
-%    \begin{macrocode}
-            \end { #1 }
-            \@@_write_aux:
-          }   
-%    \end{macrocode}
-% 
-% 
-% \bigskip
-% We can now define the new environment.
-%
-% We are still in the definition of the command |\NewPitonEnvironment|...
-%    \begin{macrocode}
-    \NewDocumentEnvironment { #1 } { #2 } 
-      {
-        #3 
-        \@@_pre_env:
-        \group_begin:
-        \tl_map_function:nN 
-          { \ \\ \{ \} \$ \& \# \^ \_ \% \~ \^^I } 
-          \char_set_catcode_other:N 
-        \use:c { _@@_collect_ #1 :w }
-      }
-      { #4 }
-%    \end{macrocode}
-%
-% \medskip
-% The following code is for technical reasons. We want to change the catcode of
-% |^^M| before catching the arguments of the new environment we are defining.
-% Indeed, if not, we will have problems if there is a final optional argument in
-% our environment (if that final argument is not used by the user in an
-% instance of the environment, a spurious space is inserted, probably because
-% the |^^M| is converted to space).
-%    \begin{macrocode}
-    \AddToHook { env / #1 / begin } { \char_set_catcode_other:N \^^M }
-  }
-%    \end{macrocode}
-% This is the end of the definition of the command |\NewPitonEnvironment|.
-%
-% \bigskip
-% Now, we define the environment |{Piton}|, which is the main environment
-% provided by the package \pkg{piton}. Of course, you use
-% |\NewPitonEnvironment|. 
-%    \begin{macrocode}
-\bool_if:NTF \c_@@_beamer_bool
-  {
-    \NewPitonEnvironment { Piton } { d < > }
-      { 
-        \IfValueTF { #1 }
-          { \begin { uncoverenv } < #1 > }
-          { \begin { uncoverenv } }
-      }
-      { \end { uncoverenv } } 
-  }
-  { \NewPitonEnvironment { Piton } { } { } { } }
-%    \end{macrocode}
-%
-%
-%
-% \bigskip
-% \subsubsection{The styles}
-% 
-% \medskip
-% The following command is fundamental: it will be used by the Lua code.
-%    \begin{macrocode}
-\NewDocumentCommand { \PitonStyle } { m } { \use:c { pitonStyle #1 } }
-%    \end{macrocode}
-%
-% \medskip
-% The following command takes in its argument by curryfication.
-%    \begin{macrocode}
-\NewDocumentCommand { \SetPitonStyle } { } { \keys_set:nn { piton / Styles } } 
-%    \end{macrocode}
-% 
-% \medskip
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_math_scantokens:n #1 
-  { \normalfont \scantextokens { $#1$ } }
-%    \end{macrocode}
-% 
-% \medskip
-%    \begin{macrocode}
-\keys_define:nn { piton / Styles }
-  {
-    String.Interpol   .tl_set:c = pitonStyle String.Interpol , 
-    String.Interpol   .value_required:n = true ,
-    FormattingType    .tl_set:c = pitonStyle FormattingType ,
-    FormattingType    .value_required:n = true ,
-    Dict.Value        .tl_set:c = pitonStyle Dict.Value ,
-    Dict.Value        .value_required:n = true ,
-    Name.Decorator    .tl_set:c = pitonStyle Name.Decorator ,
-    Name.Decorator    .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 ,
-    Keyword           .tl_set:c = pitonStyle Keyword ,
-    Keyword           .value_required:n = true ,
-    Keyword.Constant  .tl_set:c = pitonStyle Keyword.Constant ,
-    Keyword.constant  .value_required:n = true ,
-    String.Doc        .tl_set:c = pitonStyle String.Doc ,
-    String.Doc        .value_required:n = true ,
-    Interpol.Inside   .tl_set:c = pitonStyle Interpol.Inside ,
-    Interpol.Inside   .value_required:n = true ,
-    String.Long       .tl_set:c = pitonStyle String.Long ,
-    String.Long       .value_required:n = true ,
-    String.Short      .tl_set:c = pitonStyle String.Short ,
-    String.Short      .value_required:n = true ,
-    String            .meta:n = { String.Long = #1 , String.Short = #1 } ,
-    Comment.Math      .tl_set:c = pitonStyle Comment.Math , 
-    Comment.Math      .default:n = \@@_math_scantokens:n ,
-    Comment.Math      .initial:n = ,
-    Comment           .tl_set:c = pitonStyle Comment , 
-    Comment           .value_required:n = true ,
-    InitialValues     .tl_set:c = pitonStyle InitialValues ,
-    InitialValues     .value_required:n = true ,
-    Number            .tl_set:c = pitonStyle Number , 
-    Number            .value_required:n = true ,
-    Name.Namespace    .tl_set:c = pitonStyle Name.Namespace , 
-    Name.Namespace    .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 , 
-    Name.Builtin      .value_required:n = true ,
-    TypeParameter     .tl_set:c = pitonStyle TypeParameter , 
-    TypeParameter     .value_required:n = true ,
-    Name.Type         .tl_set:c = pitonStyle Name.Type , 
-    Name.Type         .value_required:n = true ,
-    Operator          .tl_set:c = pitonStyle Operator , 
-    Operator          .value_required:n = true ,
-    Operator.Word     .tl_set:c = pitonStyle Operator.Word , 
-    Operator.Word     .value_required:n = true ,
-    Exception         .tl_set:c = pitonStyle Exception ,
-    Exception         .value_required:n = true ,
-    Comment.LaTeX     .tl_set:c = pitonStyle Comment.LaTeX ,
-    Comment.LaTeX     .value_required:n = true ,
-    Identifier        .tl_set:c = pitonStyle Identifier ,
-    Comment.LaTeX     .value_required:n = true ,
-    ParseAgain.noCR   .tl_set:c = pitonStyle ParseAgain.noCR ,
-    ParseAgain.noCR   .value_required:n = true ,
-    ParseAgain        .tl_set:c = pitonStyle ParseAgain , 
-    ParseAgain        .value_required:n = true ,
-    Prompt            .tl_set:c = pitonStyle Prompt , 
-    Prompt            .value_required:n = true ,
-    unknown           .code:n = 
-      \msg_error:nn { piton } { Unknown~key~for~SetPitonStyle }
-  }
-%    \end{macrocode}
-% 
-% 
-% \bigskip
-%    \begin{macrocode}
-\msg_new:nnn { piton } { Unknown~key~for~SetPitonStyle } 
-  {
-    The~style~'\l_keys_key_str'~is~unknown.\\
-    This~key~will~be~ignored.\\
-    The~available~styles~are~(in~alphabetic~order):~
-    Comment,~
-    Comment.LaTeX,~
-    Dict.Value,~
-    Exception,~
-    Identifier,~
-    InitialValues,~ 
-    Keyword,~
-    Keyword.Constant,~
-    Name.Builtin,~
-    Name.Class,~
-    Name.Decorator,~
-    Name.Function,~
-    Name.Namespace,~
-    Number,~
-    Operator,~
-    Operator.Word,~
-    Prompt,~
-    String,~
-    String.Doc,~
-    String.Long,~
-    String.Short,~and~
-    String.Interpol. 
-  }
-%    \end{macrocode}
-%
-% \bigskip
-% \subsubsection{The initial style}
-%
-% The initial style is inspired by the style ``manni'' of Pygments.
-% 
-% \medskip
-%    \begin{macrocode}
-\SetPitonStyle
-  {                                                       
-    Comment            = \color[HTML]{0099FF} \itshape , 
-    Exception          = \color[HTML]{CC0000} ,
-    Keyword            = \color[HTML]{006699} \bfseries ,               
-    Keyword.Constant   = \color[HTML]{006699} \bfseries ,               
-    Name.Builtin       = \color[HTML]{336666} ,
-    Name.Decorator     = \color[HTML]{9999FF}, 
-    Name.Class         = \color[HTML]{00AA88} \bfseries ,
-    Name.Function      = \color[HTML]{CC00FF} , 
-    Name.Namespace     = \color[HTML]{00CCFF} , 
-    Number             = \color[HTML]{FF6600} ,
-    Operator           = \color[HTML]{555555} ,
-    Operator.Word      = \bfseries ,
-    String             = \color[HTML]{CC3300} ,         
-    String.Doc         = \color[HTML]{CC3300} \itshape , 
-    String.Interpol    = \color[HTML]{AA0000} ,
-    Comment.LaTeX      = \normalfont \color[rgb]{.468,.532,.6} , 
-    Name.Type          = \color[HTML]{336666} ,
-    InitialValues      = \@@_piton:n ,
-    Dict.Value         = \@@_piton:n ,
-    Interpol.Inside    = \color{black}\@@_piton:n ,
-    TypeParameter      = \color[HTML]{008800} \itshape ,
-    Identifier         = \@@_identifier:n , 
-    Name.UserFunction  = , 
-    Prompt             = , 
-    ParseAgain.noCR    = \@@_piton_no_cr:n , 
-    ParseAgain         = \@@_piton:n ,
-  }
-%    \end{macrocode}
-% The last styles |ParseAgain.noCR| and |ParseAgain| should be considered as 
-% ``internal style'' (not available for the final user). However, maybe we will
-% change that and document these styles for the final user (why not?).
-%
-% \medskip
-% If the key |math-comments| has been used at load-time, we change the style
-% |Comment.Math| which should be considered only at an ``internal style''.
-% However, maybe we will document in a future version the possibility to write
-% change the style \emph{locally} in a document)].
-%    \begin{macrocode}
-\bool_if:NT \c_@@_math_comments_bool { \SetPitonStyle { Comment.Math } }
-%    \end{macrocode}
-% 
-% \bigskip
-%
-% \bigskip
-% \subsubsection{Highlighting some identifiers}
-% 
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_identifier:n #1
-  { \cs_if_exist_use:c { PitonIdentifier _ \l_@@_language_str _ #1 } { #1 } } 
-%    \end{macrocode}
-%
-% \bigskip
-%    \begin{macrocode}
-\keys_define:nn { PitonOptions }
-  { identifiers .code:n = \@@_set_identifiers:n { #1 } }
-%    \end{macrocode}
-%
-% \bigskip
-%    \begin{macrocode}
-\keys_define:nn { Piton / identifiers }
-  {
-    names .clist_set:N = \l_@@_identifiers_names_tl ,
-    style .tl_set:N    = \l_@@_style_tl ,
-  }
-%    \end{macrocode}
-%
-% \bigskip
-%    \begin{macrocode}
-\cs_new_protected:Npn \@@_set_identifiers:n #1
-  {
-    \clist_clear_new:N \l_@@_identifiers_names_tl 
-    \tl_clear_new:N \l_@@_style_tl 
-    \keys_set:nn { Piton / identifiers } { #1 }
-    \clist_map_inline:Nn \l_@@_identifiers_names_tl 
-      {
-        \tl_set_eq:cN 
-          { PitonIdentifier _ \l_@@_language_str _ ##1 }
-          \l_@@_style_tl
-      }
-  }
-%    \end{macrocode}
-%
-%
-% \bigskip
-% In particular, we have an hightlighting 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
-% 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.
-%    \begin{macrocode}
-    { \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,
-% 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 } }
-%    \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|.
-%    \begin{macrocode}
-    \seq_if_exist:cF { g_@@_functions _ \l_@@_language_str _ seq }
-      { \seq_new:c { g_@@_functions _ \l_@@_language_str _ seq } }
-    \seq_gput_right:cn { g_@@_functions _ \l_@@_language_str _ seq } { #1 }
-  }
-%    \end{macrocode}
-%
-% \bigskip
-%    \begin{macrocode}
-\NewDocumentCommand \PitonClearUserFunctions { ! O { \l_@@_language_str }  } 
-  {
-    \seq_if_exist:cT { g_@@_functions _ #1 _ seq }
-      {
-        \seq_map_inline:cn { g_@@_functions _ #1 _ seq }
-          { \cs_undefine:c { PitonIdentifier _ #1 _ ##1} }
-        \seq_gclear:c { g_@@_functions _ #1 _ seq }
-      }
-  }
-%    \end{macrocode}
-% 
-% \bigskip
-% \subsubsection{Security}
-%
-%     \begin{macrocode}
-\AddToHook { env / piton / begin } 
-   { \msg_fatal:nn { piton } { No~environment~piton } }
-
-\msg_new:nnn { piton } { No~environment~piton }
-  { 
-    There~is~no~environment~piton!\\
-    There~is~an~environment~{Piton}~and~a~command~
-    \token_to_str:N \piton\ but~there~is~no~environment~
-    {piton}.~This~error~is~fatal.
-  }
-%    \end{macrocode}
-% 
-% \bigskip
-% \subsubsection{The error messages of the package}
-%
-%    \begin{macrocode}
-\msg_new:nnnn { piton } { Unknown~key~for~PitonOptions }
-  { 
-    Unknown~key. \\
-    The~key~'\l_keys_key_str'~is~unknown~for~\token_to_str:N \PitonOptions.~
-    It~will~be~ignored.\\
-    For~a~list~of~the~available~keys,~type~H~<return>.
-  }
-  {
-    The~available~keys~are~(in~alphabetic~order):~
-    all-line-numbers,~
-    auto-gobble,~
-    background-color,~
-    break-lines,~
-    break-lines-in-piton,~
-    break-lines-in-Piton,~
-    continuation-symbol,~
-    continuation-symbol-on-indentation,~
-    end-of-broken-line,~
-    env-gobble,~
-    gobble,~
-    identifiers,~
-    indent-broken-lines,~
-    language,~
-    left-margin,~
-    line-numbers,~
-    prompt-background-color,~
-    resume,~
-    show-spaces,~
-    show-spaces-in-strings,~
-    slim,~
-    splittable,~
-    tabs-auto-gobble~
-    and~tab-size.
-  }
-%    \end{macrocode}
-%
-% \bigskip
-%    \begin{macrocode}
-\msg_new:nnn { piton } { label~with~lines~numbers } 
-  {
-    You~can't~use~the~command~\token_to_str:N \label\
-    because~the~key~'line-numbers'~(or~'all-line-numbers')~
-    is~not~active.\\
-    If~you~go~on,~that~command~will~ignored.
-  }
-%    \end{macrocode}
-% 
-% \bigskip
-%    \begin{macrocode}
-\msg_new:nnn { piton } { cr~not~allowed }
-  {
-    You~can't~put~any~carriage~return~in~the~argument~
-    of~a~command~\c_backslash_str
-    \l_@@_beamer_command_str\ within~an~
-    environment~of~'piton'.~You~should~consider~using~the~
-    corresponding~environment.\\
-    That~error~is~fatal.
-  }
-%    \end{macrocode}
-%
-% \bigskip
-%    \begin{macrocode}
-\msg_new:nnn { piton } { overlay~without~beamer }
-  {
-    You~can't~use~an~argument~<...>~for~your~command~
-    \token_to_str:N \PitonInputFile\ because~you~are~not~
-    in~Beamer.\\
-    If~you~go~on,~that~argument~will~be~ignored.
-  }
-%    \end{macrocode}
-%
-% \bigskip
-%    \begin{macrocode}
-\msg_new:nnn { Piton } { Python~error }
-  { A~Python~error~has~been~detected. }
-%    \end{macrocode}
-% 
-% \bigskip
-% \subsection{The Lua part of the implementation}
-%
-% \bigskip
-%    \begin{macrocode}
-\ExplSyntaxOff
-\RequirePackage{luacode}
-%    \end{macrocode}
-% 
-%
-% \bigskip
-% The Lua code will be loaded via a |{luacode*}| environment. The environment
-% is by itself a Lua block and the local declarations will be local to that
-% block. All the global functions (used by the L3 parts of the implementation)
-% will be put in a Lua table |piton|.
-%
-% \medskip
-%    \begin{macrocode}
-\begin{luacode*}
-piton = piton or { }
-%    \end{macrocode}
-% 
-%    \begin{macrocode}
-if piton.comment_latex == nil then piton.comment_latex = ">" end 
-piton.comment_latex = "#" .. piton.comment_latex 
-%    \end{macrocode}
-%
-%
-% \bigskip
-% The following functions are an easy way to safely insert braces (|{| and |}|)
-% in the TeX flow.
-%    \begin{macrocode}
-function piton.open_brace () 
-   tex.sprint("{") 
-end 
-function piton.close_brace () 
-   tex.sprint("}") 
-end 
-%    \end{macrocode}
-%
-% \bigskip
-% \subsubsection{Special functions dealing with LPEG}
-%
-% \medskip
-% We will use the Lua library \pkg{lpeg} which is built in LuaTeX. That's why we
-% define first aliases for several functions of that library.
-%    \begin{macrocode}
-local P, S, V, C, Ct, Cc = lpeg.P, lpeg.S, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Cc
-local Cf, Cs , Cg , Cmt , Cb = lpeg.Cf, lpeg.Cs, lpeg.Cg , lpeg.Cmt , lpeg.Cb
-local R = lpeg.R
-%    \end{macrocode}
-%
-% 
-%
-% \bigskip
-% The function |Q| takes in as argument a pattern and returns a \textsc{lpeg}
-% \emph{which does a capture} of the pattern. That capture will be sent to LaTeX
-% with the catcode ``other'' for all the characters: it's suitable for elements
-% of the Python listings that \pkg{piton} will typeset verbatim (thanks to the
-% catcode ``other''). 
-%    \begin{macrocode}
-local function Q(pattern)
-  return Ct ( Cc ( luatexbase.catcodetables.CatcodeTableOther ) * C ( pattern ) )
-end 
-%    \end{macrocode}
-%
-%
-% \bigskip
-% The function |L| takes in as argument a pattern and returns a \textsc{lpeg}
-% \emph{which does a capture} of the pattern. That capture will be sent to LaTeX
-% with standard LaTeX catcodes for all the characters: the elements captured
-% will be formatted as normal LaTeX codes. It's suitable for the ``LaTeX
-% comments'' in the environments |{Piton}| and the elements beetween 
-% ``|escape-inside|''. That function won't be much used.
-%    \begin{macrocode}
-local function L(pattern)
-  return Ct ( C ( pattern ) ) 
-end
-%    \end{macrocode}
-%
-% \bigskip
-% The function |Lc| (the c is for \emph{constant}) takes in as argument a string
-% and returns a \textsc{lpeg} \emph{with does a constant capture} which returns
-% that string. The elements captured will be formatted as L3 code. It will be
-% used to send to LaTeX all the formatting LaTeX instructions we have to insert
-% in order to do the syntactic highlighting (that's the main job of
-% \pkg{piton}). That function will be widely used.
-%    \begin{macrocode}
-local function Lc(string)
-  return Cc ( { luatexbase.catcodetables.expl , string } ) 
-end 
-%    \end{macrocode}
-% 
-% \bigskip
-% The function |K| creates a \textsc{lpeg} which will return as capture the
-% whole LaTeX code corresponding to a Python chunk (that is to say with the
-% LaTeX formatting instructions corresponding to the syntactic nature of that
-% Python chunk). The first argument is a Lua string corresponding to the name of
-% a \pkg{piton} style and the second element is a pattern (that is to say a
-% \textsc{lpeg} without capture)
-%    \begin{macrocode}
-local function K(style, pattern)
-  return
-     Lc ( "{\\PitonStyle{" .. style .. "}{" )
-     * Q ( pattern )
-     * Lc ( "}}" )
-end
-%    \end{macrocode}
-% The formatting commands in a given \pkg{piton} style (eg. the style |Keyword|)
-% may be semi-global declarations (such as |\bfseries| or |\slshape|) or LaTeX
-% macros with an argument (such as |\fbox| or |\colorbox{yellow}|). In order to
-% deal with both syntaxes, we have used two pairs of braces: 
-% |{\PitonStyle{Keyword}{|\texttt{\slshape text to format}|}}|.
-% 
-%
-% \bigskip
-%    \begin{macrocode}
-local function WithStyle(style,pattern)
-  return 
-       Ct ( Cc "Open" * Cc ( "{\\PitonStyle{" .. style .. "}{" ) * Cc "}}" ) 
-     * pattern 
-     * Ct ( Cc "Close" ) 
-end
-%    \end{macrocode}
-% 
-% \bigskip
-% The following \textsc{lpeg} catches the Python chunks which are in LaTeX
-% escapes (and that chunks will be considered as normal LaTeX constructions). We
-% recall that |piton.begin_espace| and |piton_end_escape| are Lua strings
-% corresponding to the key |escape-inside|\footnote{The \pkg{piton} key
-% |escape-inside| is available at load-time only.}. Since the elements that will
-% be catched must be sent to LaTeX with standard LaTeX catcodes, we put the
-% capture (done by the function |C|) in a table (by using |Ct|, which is an
-% alias for |lpeg.Ct|) without number of catcode table at the first component of
-% the table.
-%    \begin{macrocode}
-local Escape = 
-  P(piton_begin_escape)
-  * L ( ( 1 - P(piton_end_escape) ) ^ 1 ) 
-  * P(piton_end_escape)
-%    \end{macrocode}
-% 
-% \vspace{1cm}
-% The following line is mandatory.
-%    \begin{macrocode}
-lpeg.locale(lpeg)
-%    \end{macrocode}
-%
-% \bigskip
-% \paragraph{The basic syntactic LPEG}
-%
-%    \begin{macrocode}
-local alpha, digit = lpeg.alpha, lpeg.digit
-local space = P " " 
-%    \end{macrocode}
-%
-% Remember that, for \textsc{lpeg}, the Unicode characters such as |à|, |â|,
-% |ç|, etc. are in fact strings of length 2 (2 bytes) because \pkg{lpeg} is not
-% Unicode-aware. 
-%    \begin{macrocode}
-local letter = alpha + P "_" 
-  + P "â" + P "à" + P "ç" + P "é" + P "è" + P "ê" + P "ë" + P "ï" + P "î" 
-  + P "ô" + P "û" + P "ü" + P "Â" + P "À" + P "Ç" + P "É" + P "È" + P "Ê" 
-  + P "Ë" + P "Ï" + P "Î" + P "Ô" + P "Û" + P "Ü" 
-
-local alphanum = letter + digit
-%    \end{macrocode}
-% 
-% \bigskip
-% The following \textsc{lpeg} |identifier| is a mere pattern (that is to say
-% more or less a regular expression) which matches the Python identifiers (hence
-% the name).
-%    \begin{macrocode}
-local identifier = letter * alphanum ^ 0
-%    \end{macrocode}
-% 
-% \medskip
-% On the other hand, the \textsc{lpeg} |Identifier| (with a capital) also returns
-% a \emph{capture}.
-%    \begin{macrocode}
-local Identifier = K ( 'Identifier' , identifier)
-%    \end{macrocode}
-%
-% \bigskip
-% By convention, we will use names with an initial capital for \textsc{lpeg}
-% which return captures.
-%
-% 
-% \bigskip
-% Here is the first use of our function~|K|. That function will be used to
-% construct \textsc{lpeg} which capture Python chunks for which we have a
-% dedicated \pkg{piton} style. For example, for the numbers, \pkg{piton}
-% provides a style which is called |Number|. The name of the style is provided
-% as a Lua string in the second argument of the function~|K|. By convention, we
-% use single quotes for delimiting the Lua strings which are names of
-% \pkg{piton} styles (but this is only a convention).
-%    \begin{macrocode}
-local Number =
-  K ( 'Number' ,
-      ( digit^1 * P "." * digit^0 + digit^0 * P "." * digit^1 + digit^1 )
-      * ( S "eE" * S "+-" ^ -1 * digit^1 ) ^ -1
-      + digit^1 
-    ) 
-%    \end{macrocode}
-%
-% \bigskip
-% We recall that |piton.begin_espace| and |piton_end_escape| are Lua strings
-% corresponding to the key |escape-inside|\footnote{The \pkg{piton} key
-% |escape-inside| is available at load-time only.}. Of course, if the final user
-% has not used the key |escape-inside|, these strings are empty.
-%    \begin{macrocode}
-local Word
-if piton_begin_escape ~= ''
-then Word = Q ( ( ( 1 - space - P(piton_begin_escape) - P(piton_end_escape) ) 
-                   - S "'\"\r[()]" - digit ) ^ 1 )
-else Word = Q ( ( ( 1 - space ) - S "'\"\r[()]" - digit ) ^ 1 )
-end
-%    \end{macrocode}
-%
-% \bigskip
-%    \begin{macrocode}
-local Space = ( Q " " ) ^ 1
-
-local SkipSpace = ( Q " " ) ^ 0
-
-local Punct = Q ( S ".,:;!" )
-
-local Tab = P "\t" * Lc ( '\\l_@@_tab_tl' )
-%    \end{macrocode}
-% 
-% \bigskip
-%    \begin{macrocode}
-local SpaceIndentation = Lc ( '\\@@_an_indentation_space:' ) * ( Q " " )
-%    \end{macrocode}
-%
-%
-% \bigskip
-%    \begin{macrocode}
-local Delim = Q ( S "[()]" )
-%    \end{macrocode}
-% 
-% \bigskip
-% The following \textsc{lpeg} catches a space (U+0020) and replace it by
-% |\l_@@_space_tl|. It will be used in the strings. Usually,
-% |\l_@@_space_tl| will contain a space and therefore there won't be difference.
-% However, when the key |show-spaces-in-strings| is in force, |\\l_@@_space_tl| will
-% contain ␣ (U+2423) in order to visualize the spaces.
-%    \begin{macrocode}
-local VisualSpace = space * Lc "\\l_@@_space_tl" 
-%    \end{macrocode}
-% 
-%
-% \bigskip
-% \subsubsection{The LPEG python}
-% 
-% \bigskip
-% Some strings of length 2 are explicit because we want the corresponding
-% ligatures available in some fonts such as \emph{Fira Code} to be active.
-%    \begin{macrocode}
-local Operator = 
-  K ( 'Operator' ,
-      P "!=" + P "<>" + P "==" + P "<<" + P ">>" + P "<=" + P ">=" + P ":=" 
-      + P "//" + P "**" + S "-~+/*%=<>&.@|" 
-    )
-
-local OperatorWord = 
-  K ( 'Operator.Word' ,P "in" + P "is" + P "and" + P "or" + P "not" )
-
-local Keyword = 
-  K ( 'Keyword' ,
-      P "as" + P "assert" + P "break" + P "case" + P "class" + P "continue" 
-      + P "def" + P "del" + P "elif" + P "else" + P "except" + P "exec" 
-      + P "finally" + P "for" + P "from" + P "global" + P "if" + P "import" 
-      + P "lambda" + P "non local" + P "pass" + P "return" + P "try" 
-      + P "while" + P "with" + P "yield" + P "yield from" )
-  + K ( 'Keyword.Constant' ,P "True" + P "False" + P "None" ) 
-
-local Builtin = 
-  K ( 'Name.Builtin' ,
-      P "__import__" + P "abs" + P "all" + P "any" + P "bin" + P "bool" 
-    + P "bytearray" + P "bytes" + P "chr" + P "classmethod" + P "compile" 
-    + P "complex" + P "delattr" + P "dict" + P "dir" + P "divmod" 
-    + P "enumerate" + P "eval" + P "filter" + P "float" + P "format" 
-    + P "frozenset" + P "getattr" + P "globals" + P "hasattr" + P "hash" 
-    + P "hex" + P "id" + P "input" + P "int" + P "isinstance" + P "issubclass"
-    + P "iter" + P "len" + P "list" + P "locals" + P "map" + P "max" 
-    + P "memoryview" + P "min" + P "next" + P "object" + P "oct" + P "open" 
-    + P "ord" + P "pow" + P "print" + P "property" + P "range" + P "repr" 
-    + P "reversed" + P "round" + P "set" + P "setattr" + P "slice" + P "sorted" 
-    + P "staticmethod" + P "str" + P "sum" + P "super" + P "tuple" + P "type"
-    + P "vars" + P "zip" )
-
-
-local Exception =
-  K ( 'Exception' ,
-      P "ArithmeticError" + P "AssertionError" + P "AttributeError"
-   + P "BaseException" + P "BufferError" + P "BytesWarning" + P "DeprecationWarning"
-   + P "EOFError" + P "EnvironmentError" + P "Exception" + P "FloatingPointError"
-   + P "FutureWarning" + P "GeneratorExit" + P "IOError" + P "ImportError"
-   + P "ImportWarning" + P "IndentationError" + P "IndexError" + P "KeyError"
-   + P "KeyboardInterrupt" + P "LookupError" + P "MemoryError" + P "NameError"
-   + P "NotImplementedError" + P "OSError" + P "OverflowError"
-   + P "PendingDeprecationWarning" + P "ReferenceError" + P "ResourceWarning"
-   + P "RuntimeError" + P "RuntimeWarning" + P "StopIteration"
-   + P "SyntaxError" + P "SyntaxWarning" + P "SystemError" + P "SystemExit"
-   + P "TabError" + P "TypeError" + P "UnboundLocalError" + P "UnicodeDecodeError"
-   + P "UnicodeEncodeError" + P "UnicodeError" + P "UnicodeTranslateError"
-   + P "UnicodeWarning" + P "UserWarning" + P "ValueError" + P "VMSError"
-   + P "Warning" + P "WindowsError" + P "ZeroDivisionError"
-   + P "BlockingIOError" + P "ChildProcessError" + P "ConnectionError"
-   + P "BrokenPipeError" + P "ConnectionAbortedError" + P "ConnectionRefusedError"
-   + P "ConnectionResetError" + P "FileExistsError" + P "FileNotFoundError"
-   + P "InterruptedError" + P "IsADirectoryError" + P "NotADirectoryError"
-   + P "PermissionError" + P "ProcessLookupError" + P "TimeoutError"
-   + P "StopAsyncIteration" + P "ModuleNotFoundError" + P "RecursionError" )
-
-
-local RaiseException = K ( 'Keyword' , P "raise" ) * SkipSpace * Exception * Q ( P "(" ) 
-
-%    \end{macrocode}
-%
-% \bigskip
-% In Python, a ``decorator'' is a statement whose begins by |@| which patches
-% the function defined in the following statement.
-%    \begin{macrocode}
-local Decorator = K ( 'Name.Decorator' , P "@" * letter^1  ) 
-%    \end{macrocode}
-% 
-% \bigskip
-% The following \textsc{lpeg} |DefClass| will be used to detect the definition of a
-% new class (the name of that new class will be formatted with the \pkg{piton}
-% style |Name.Class|). 
-%
-% \smallskip
-% Example:\enskip \piton{class myclass:}
-%    \begin{macrocode}
-local DefClass = 
-  K ( 'Keyword' , P "class" ) * Space * K ( 'Name.Class' , identifier ) 
-%    \end{macrocode}
-% 
-% If the word |class| is not followed by a identifier, it will be catched as
-% keyword by the \textsc{lpeg} |Keyword| (useful if we want to type a
-% list of keywords).
-%
-%
-% \bigskip
-% The following \textsc{lpeg} |ImportAs| is used for the lines beginning by |import|.
-% % We have to detect the potential keyword |as| because both the name of the
-% module and its alias must be formatted with the \pkg{piton} style |Name.Namespace|.
-%
-% \smallskip
-% Example:\enskip \piton{import numpy as np}
-%
-% \smallskip
-% Moreover, after the keyword |import|, it's possible to have a comma-separated
-% list of modules (if the keyword |as| is not used).
-%
-% \smallskip
-% Example:\enskip \piton{import math, numpy}
-%    \begin{macrocode}
-local ImportAs = 
-  K ( 'Keyword' , P "import" )
-   * Space 
-   * K ( 'Name.Namespace' , 
-         identifier * ( P "." * identifier ) ^ 0 )
-   * ( 
-       ( Space * K ( 'Keyword' , P "as" ) * Space 
-          * K ( 'Name.Namespace' , identifier ) )
-       + 
-       ( SkipSpace * Q ( P "," ) * SkipSpace 
-          * K ( 'Name.Namespace' , identifier ) ) ^ 0 
-     ) 
-%    \end{macrocode}
-% Be careful: there is no commutativity of |+| in the previous expression.
-%
-% \bigskip
-% The \textsc{lpeg} |FromImport| is used for the lines beginning by |from|. We
-% need a special treatment because the identifier following the keyword |from|
-% must be formatted with the \pkg{piton} style |Name.Namespace| and the
-% following keyword |import| must be formatted with the \pkg{piton} style
-% |Keyword| and must \emph{not} be catched by the \textsc{lpeg} |ImportAs|.
-%
-% \smallskip
-% Example:\enskip \piton{from math import pi}
-%
-% \smallskip
-%    \begin{macrocode}
-local FromImport =
-  K ( 'Keyword' , P "from" ) 
-    * Space * K ( 'Name.Namespace' , identifier )
-    * Space * K ( 'Keyword' , P "import" ) 
-%    \end{macrocode}
-%
-% \bigskip
-% \paragraph{The strings of Python}
-%
-% For the strings in Python, there are four categories of delimiters (without
-% counting the prefixes for f-strings and raw strings). We will use, in the
-% names of our \textsc{lpeg}, prefixes to distinguish the \textsc{lpeg} dealing
-% with that categories of strings, as presented in the following tabular.
-% \begin{center}
-% \begin{tabular}{ccc}
-% \toprule
-%         & |Single| & |Double| \\
-% \midrule
-% |Short| & |'text'|     & |"text"| \\
-% |Long|  & |'''test'''| & |"""text"""| \\
-% \bottomrule
-% \end{tabular}
-% \end{center}
-%
-% 
-% \bigskip
-% We have also to deal with the interpolations in the f-strings. Here
-% is an example of a f-string with an interpolation and a format
-% instruction\footnote{There is no special \pkg{piton} style for the formatting
-% instruction (after the colon): the style which will be applied will be the
-% style of the encompassing string, that is to say |String.Short| or
-% |String.Long|.} in that interpolation:
-%
-% \piton{f'Total price: {total+1:.2f} €'}
-%
-%
-% \bigskip
-% The interpolations beginning by |%| (even though there is more modern
-% technics now in Python).
-%    \begin{macrocode}
-local PercentInterpol =  
-  K ( 'String.Interpol' , 
-      P "%" 
-      * ( P "(" * alphanum ^ 1 * P ")" ) ^ -1 
-      * ( S "-#0 +" ) ^ 0 
-      * ( digit ^ 1 + P "*" ) ^ -1 
-      * ( P "." * ( digit ^ 1 + P "*" ) ) ^ -1 
-      * ( S "HlL" ) ^ -1
-      * S "sdfFeExXorgiGauc%" 
-    ) 
-%    \end{macrocode}
-% 
-% \bigskip
-% We can now define the \textsc{lpeg} for the four kinds of strings. It's not
-% possible to use our function~|K| because of the interpolations which must be
-% formatted with another \pkg{piton} style that the rest of the
-% string.\footnote{The interpolations are formatted with the \pkg{piton} style
-% |Interpol.Inside|. The initial value of that style is \texttt{\textbackslash
-% @@\_piton:n} wich means that the interpolations are parsed once again by \pkg{piton}.}
-%    \begin{macrocode}
-local SingleShortString =
-  WithStyle ( 'String.Short' ,
-%    \end{macrocode}
-% First, we deal with the f-strings of Python, which are prefixed by |f| or |F|.
-%    \begin{macrocode}
-         Q ( P "f'" + P "F'" ) 
-         * ( 
-             K ( 'String.Interpol' , P "{" )
-              * K ( 'Interpol.Inside' , ( 1 - S "}':" ) ^ 0  )
-              * Q ( P ":" * (1 - S "}:'") ^ 0 ) ^ -1
-              * K ( 'String.Interpol' , P "}" )
-             + 
-             VisualSpace 
-             + 
-             Q ( ( P "\\'" + P "{{" + P "}}" + 1 - S " {}'" ) ^ 1 )
-           ) ^ 0 
-         * Q ( P "'" )
-       + 
-%    \end{macrocode}
-% Now, we deal with the standard strings of Python, but also the ``raw strings''.
-%    \begin{macrocode}
-         Q ( P "'" + P "r'" + P "R'" ) 
-         * ( Q ( ( P "\\'" + 1 - S " '\r%" ) ^ 1 ) 
-             + VisualSpace 
-             + PercentInterpol 
-             + Q ( P "%" ) 
-           ) ^ 0 
-         * Q ( P "'" ) )
-
-
-local DoubleShortString =
-  WithStyle ( 'String.Short' , 
-         Q ( P "f\"" + P "F\"" ) 
-         * ( 
-             K ( 'String.Interpol' , P "{" )
-               * Q ( ( 1 - S "}\":" ) ^ 0 , 'Interpol.Inside' )
-               * ( K ( 'String.Interpol' , P ":" ) * Q ( (1 - S "}:\"") ^ 0 ) ) ^ -1
-               * K ( 'String.Interpol' , P "}" )
-             + 
-             VisualSpace 
-             + 
-             Q ( ( P "\\\"" + P "{{" + P "}}" + 1 - S " {}\"" ) ^ 1 ) 
-            ) ^ 0
-         * Q ( P "\"" )
-       +
-         Q ( P "\"" + P "r\"" + P "R\"" ) 
-         * ( Q ( ( P "\\\"" + 1 - S " \"\r%" ) ^ 1 ) 
-             + VisualSpace 
-             + PercentInterpol 
-             + Q ( P "%" ) 
-           ) ^ 0 
-         * Q ( P "\"" ) )
-
-local ShortString = SingleShortString + DoubleShortString
-%    \end{macrocode}
-%
-% \bigskip
-% \paragraph{Beamer}
-%
-% The following \textsc{lpeg} |BalancedBraces| 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 =
-  P { "E" ,
-       E = 
-           (
-             P "{" * V "E" * P "}" 
-             + 
-             ShortString  
-             + 
-             ( 1 - S "{}" ) 
-           ) ^ 0 
-    }
-%    \end{macrocode}
-% 
-%
-% \bigskip 
-% If Beamer is used (or if the key |beamer| is used at load-time), the following
-% LPEG will be redefined.
-%    \begin{macrocode}
-local Beamer = P ( false ) 
-local BeamerBeginEnvironments = P ( true ) 
-local BeamerEndEnvironments = P ( true ) 
-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}
-% 
-%    \begin{macrocode}
-function OneBeamerEnvironment(name)
-  return 
-      Ct ( Cc "Open" 
-            * C ( 
-                  P ( "\\begin{" .. name ..   "}" )
-                  * ( P "<" * (1 - P ">") ^ 0 * P ">" ) ^ -1 
-                ) 
-           * Cc ( "\\end{" .. name ..  "}" )
-          ) 
-     * ( 
-         C ( ( 1 - P ( "\\end{" .. name .. "}" ) ) ^ 0 ) 
-         / (function (s) return MainLoopPython:match(s) end ) 
-       )
-     * P ( "\\end{" .. name ..  "}" ) * Ct ( Cc "Close" ) 
-end 
-%    \end{macrocode}
-% 
-%
-% \bigskip
-%    \begin{macrocode}
-if piton_beamer 
-then
-  Beamer =
-      L  ( P "\\pause" * ( P "[" * (1 - P "]") ^ 0 * P "]" ) ^ -1 ) 
-    + 
-      Ct ( Cc "Open" 
-            * C ( 
-                  ( 
-                    P "\\uncover" + P "\\only" + P "\\alert" + P "\\visible"
-                    + P "\\invisible" + P "\\action" 
-                  ) 
-                  * ( P "<" * (1 - P ">") ^ 0 * P ">" ) ^ -1 
-                  * P "{" 
-                ) 
-            * Cc "}" 
-         ) 
-       * ( C ( BalancedBraces ) / (function (s) return MainLoopPython:match(s) end ) )
-       * P "}" * Ct ( Cc "Close" ) 
-    + 
-      OneBeamerEnvironment "uncoverenv" 
-    + OneBeamerEnvironment "onlyenv" 
-    + OneBeamerEnvironment "visibleenv" 
-    + OneBeamerEnvironment "invisibleenv" 
-    + OneBeamerEnvironment "alertenv" 
-    + OneBeamerEnvironment "actionenv" 
-    +
-      L ( 
-%    \end{macrocode}
-% For |\\alt|, the specification of the overlays (between angular brackets) is mandatory.
-%    \begin{macrocode}
-          ( P "\\alt" )
-          * P "<" * (1 - P ">") ^ 0 * P ">" 
-          * P "{" 
-        )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
-      * L ( P "}" )
-    +  
-      L ( 
-%    \end{macrocode}
-% For |\\alt|, the specification of the overlays (between angular brackets) is mandatory.
-%    \begin{macrocode}
-          ( P "\\temporal" )
-          * P "<" * (1 - P ">") ^ 0 * P ">" 
-          * P "{" 
-        )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
-      * L ( P "}" )
-%    \end{macrocode}
-% Now for the environemnts.
-%    \begin{macrocode}
-  BeamerBeginEnvironments = 
-      ( space ^ 0 * 
-        L 
-          ( 
-            P "\\begin{" * BeamerNamesEnvironments * "}"
-            * ( P "<" * ( 1 - P ">") ^ 0 * P ">" ) ^ -1
-          )
-        * P "\r" 
-      ) ^ 0 
-  BeamerEndEnvironments = 
-      ( space ^ 0 * 
-        L ( P "\\end{" * BeamerNamesEnvironments * P "}" ) 
-        * P "\r" 
-      ) ^ 0 
-end
-%    \end{macrocode}
-%
-% \bigskip
-% \paragraph{EOL}
-%
-% \bigskip
-% The following LPEG will detect the Python prompts when the user is typesetting
-% an interactive session of Python (directly or through |{pyconsole}| of
-% \pkg{pyluatex}). We have to detect that prompt twice. The first detection
-% (called \emph{hasty detection}) will be before the |\@@_begin_line:| because
-% you want to trigger a special background color for that row (and, after the
-% |\@@_begin_line:|, it's too late to change de background).
-%    \begin{macrocode}
-local PromptHastyDetection = ( # ( P ">>>" + P "..." ) * Lc ( '\\@@_prompt:' ) ) ^ -1 
-%    \end{macrocode}
-% We remind that the marker |#| of \textsc{lpeg} specifies that the pattern will be
-% detected but won't consume any character.
-%
-% \medskip
-% With the following \textsc{lpeg}, a style will actually be applied to the
-% prompt (for instance, it's possible to decide to discard these prompts).
-%    \begin{macrocode}
-local Prompt = K ( 'Prompt' , ( ( P ">>>" + P "..." ) * P " " ^ -1 ) ^ -1  ) 
-%    \end{macrocode}
-%    
-%
-%
-% \bigskip
-% The following \textsc{lpeg} |EOL| is for the end of lines.
-%    \begin{macrocode}
-local EOL = 
-  P "\r" 
-  *
-  (
-    ( space^0 * -1 )
-    + 
-%    \end{macrocode}
-% We recall that each line in the Python code we have to parse will be sent
-% back to LaTeX between a pair |\@@_begin_line:| --
-% |\@@_end_line:|\footnote{Remember that the \texttt{\textbackslash
-% @@\_end\_line:} must be explicit because it will be used as marker in order to
-% delimit the argument of the command \texttt{\textbackslash @@\_begin\_line:}}.
-%    \begin{macrocode}
-    Ct ( 
-         Cc "EOL"
-         * 
-         Ct (
-              Lc "\\@@_end_line:"
-              * BeamerEndEnvironments 
-              * BeamerBeginEnvironments 
-              * PromptHastyDetection
-              * Lc "\\@@_newline: \\@@_begin_line:"
-              * Prompt
-            )
-       )
-  ) 
-  *
-  SpaceIndentation ^ 0
-%    \end{macrocode}
-%
-% 
-% \bigskip
-% \paragraph{The long strings}
-% 
-% 
-%    \begin{macrocode}
-local SingleLongString =
-  WithStyle ( 'String.Long' , 
-     ( Q ( S "fF" * P "'''" )
-         * (
-             K ( 'String.Interpol' , P "{"  )
-               * K ( 'Interpol.Inside' , ( 1 - S "}:\r" - P "'''" ) ^ 0  )
-               * Q ( P ":" * (1 - S "}:\r" - P "'''" ) ^ 0 ) ^ -1
-               * K ( 'String.Interpol' , P "}"  )
-             + 
-             Q ( ( 1 - P "'''" - S "{}'\r" ) ^ 1 )
-             + 
-             EOL
-           ) ^ 0 
-       +
-         Q ( ( S "rR" ) ^ -1  * P "'''" )
-         * (
-             Q ( ( 1 - P "'''" - S "\r%" ) ^ 1 )  
-             + 
-             PercentInterpol
-             +
-             P "%"
-             +
-             EOL
-           ) ^ 0 
-      )
-      * Q ( P "'''" ) ) 
-
-
-local DoubleLongString =
-  WithStyle ( 'String.Long' ,
-     (
-        Q ( S "fF" * P "\"\"\"" )
-        * (
-            K ( 'String.Interpol', P "{"  )
-              * K ( 'Interpol.Inside' , ( 1 - S "}:\r" - P "\"\"\"" ) ^ 0 )
-              * Q ( P ":" * (1 - S "}:\r" - P "\"\"\"" ) ^ 0 ) ^ -1
-              * K ( 'String.Interpol' , P "}"  )
-            + 
-            Q ( ( 1 - P "\"\"\"" - S "{}\"\r" ) ^ 1 ) 
-            + 
-            EOL
-          ) ^ 0 
-      +
-        Q ( ( S "rR" ) ^ -1  * P "\"\"\"" )
-        * (
-            Q ( ( 1 - P "\"\"\"" - S "%\r" ) ^ 1 )  
-            + 
-            PercentInterpol 
-            + 
-            P "%"
-            + 
-            EOL
-          ) ^ 0 
-     )
-     * Q ( P "\"\"\"" ) 
-  ) 
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-local LongString = SingleLongString + DoubleLongString
-%    \end{macrocode}
-%
-% \bigskip
-% We have a \textsc{lpeg} for the Python docstrings. That \textsc{lpeg} will
-% be used in the \textsc{lpeg} |DefFunction| which deals with the whole preamble
-% of a function definition (which begins with |def|).
-%    \begin{macrocode}
-local StringDoc = 
-    K ( 'String.Doc' , P "\"\"\"" )
-      * ( K ( 'String.Doc' , (1 - P "\"\"\"" - P "\r" ) ^ 0  ) * EOL
-          * Tab ^ 0 
-        ) ^ 0
-      * K ( 'String.Doc' , ( 1 - P "\"\"\"" - P "\r" ) ^ 0 * P "\"\"\"" )
-%    \end{macrocode}
-%
-% \bigskip
-% \paragraph{The comments in the Python listings}
-%
-% We define different \textsc{lpeg} dealing with comments in the Python
-% listings.
-%    \begin{macrocode}
-local CommentMath = 
-  P "$" * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1  ) * P "$"
-
-local Comment = 
-  WithStyle ( 'Comment' ,
-     Q ( P "#" ) 
-     * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 ) 
-  * ( EOL + -1 )
-%    \end{macrocode}
-% 
-%
-%
-% \bigskip
-% The following \textsc{lpeg} |CommentLaTeX| is for what is called in that
-% document the ``LaTeX comments''. Since the elements that will be catched must
-% be sent to LaTeX with standard LaTeX catcodes, we put the capture (done by
-% the function~|C|) in a table (by using~|Ct|, which is an alias for |lpeg.Ct|).
-%    \begin{macrocode}
-local CommentLaTeX =
-  P(piton.comment_latex) 
-  * Lc "{\\PitonStyle{Comment.LaTeX}{\\ignorespaces" 
-  * L ( ( 1 - P "\r" ) ^ 0 ) 
-  * Lc "}}" 
-  * ( EOL + -1 )  -- you could put EOL instead of EOL
-%    \end{macrocode}
-% 
-% \bigskip
-% \paragraph{DefFunction}
-%
-% 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 =
-  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 , 
-    }
-%    \end{macrocode}
-%
-% \bigskip 
-% We will now define a \textsc{lpeg} |Params| that will catch the list of
-% parameters (that is to say the \emph{argspec}) in the definition of a Python
-% function. For example, in the line of code
-% \begin{center}
-% \piton{def MyFunction(a,b,x=10,n:int): return n}
-% \end{center}
-% the \textsc{lpeg} |Params| will be used to catch the chunk\enskip |a,b,x=10,n:int|.
-% 
-% Or course, a |Params| is simply a comma-separated list of |Param|, and that's
-% why we define first the \textsc{lpeg} |Param|.
-%
-% \medskip
-%    \begin{macrocode}
-local Param = 
-  SkipSpace * Identifier * SkipSpace
-   * ( 
-         K ( 'InitialValues' , P "=" * Expression )
-       + Q ( P ":" ) * SkipSpace * K ( 'Name.Type' , letter^1  ) 
-     ) ^ -1
-%    \end{macrocode}
-% 
-% \medskip
-%    \begin{macrocode}
-local Params = ( Param * ( Q "," * Param ) ^ 0 ) ^ -1
-%    \end{macrocode}
-% 
-% \bigskip
-% The following \textsc{lpeg} |DefFunction| catches a keyword |def| and the
-% following name of function \emph{but also everything else until a potential
-% docstring}. That's why this definition of \textsc{lpeg} must occur (in the file
-% |piton.sty|) after the definition of several other \textsc{lpeg} such as
-% |Comment|, |CommentLaTeX|, |Params|, |StringDoc|...
-%    \begin{macrocode}
-local DefFunction =
-  K ( 'Keyword' , P "def" )
-  * Space
-  * K ( 'Name.Function.Internal' , identifier ) 
-  * SkipSpace 
-  * Q ( P "(" ) * Params * Q ( P ")" ) 
-  * SkipSpace
-  * ( Q ( P "->" ) * SkipSpace * K ( 'Name.Type' , identifier  ) ) ^ -1
-%    \end{macrocode}
-% Here, we need a \pkg{piton} style |ParseAgain| which will be linked to
-% |\@@_piton:n| (that means that the capture will be parsed once again by
-% \pkg{piton}). We could avoid that kind of trick by using a non-terminal of a
-% grammar but we have probably here a better legibility.
-%    \begin{macrocode}
-  * K ( 'ParseAgain' , ( 1 - S ":\r" )^0  ) 
-  * Q ( P ":" )
-  * ( SkipSpace
-      * ( EOL + CommentLaTeX + Comment ) -- in all cases, that contains an EOL
-      * Tab ^ 0 
-      * SkipSpace
-      * StringDoc ^ 0 -- there may be additionnal docstrings 
-    ) ^ -1
-%    \end{macrocode}
-% Remark that, in the previous code, |CommentLaTeX| \emph{must} appear
-% before |Comment|: there is no commutativity of the addition for the
-% \emph{parsing expression grammars} (\textsc{peg}).
-% 
-% \smallskip 
-% If the word |def| is not followed by an identifier and parenthesis, it will be
-% catched as keyword by the \textsc{lpeg} |Keyword| (useful if, for example, the
-% final user wants to speak of the keyword \piton{def}).
-%
-% \bigskip
-% \paragraph{The dictionaries of Python}
-%
-% We have \textsc{lpeg} dealing with dictionaries of Python because, in
-% typesettings of explicit Python dictionaries, one may prefer to have all the
-% values formatted in black (in order to see more clearly the keys which are
-% usually Python strings). That's why we have a \pkg{piton} style |Dict.Value|.
-%
-% The initial value of that \pkg{piton} style is |\@@_piton:n|, which means that
-% the value of the entry of the dictionary is parsed once again by \pkg{piton}
-% (and nothing special is done for the dictionary). In the following example, we
-% have set the \pkg{piton} style |Dict.Value| to |\color{black}|:
-%
-% \medskip
-% \begingroup
-% \SetPitonStyle{Dict.Value = \color{black}}
-% \piton{mydict = { 'name' : 'Paul', 'sex' : 'male', 'age' : 31 } }
-% \endgroup
-%
-% \medskip
-% At this time, this mechanism works only for explicit dictionaries on a single line!
-%
-%    \begin{macrocode}
-local ItemDict = 
-  ShortString * SkipSpace * Q ( P ":" ) * K ( 'Dict.Value' , Expression  ) 
-
-local ItemOfSet = SkipSpace * ( ItemDict + ShortString ) * SkipSpace 
-
-local Set = 
-  Q ( P "{" ) 
-  * ItemOfSet * ( Q ( P "," ) * ItemOfSet )  ^ 0 
-  * Q ( P "}" )
-%    \end{macrocode}
-%
-% \paragraph{Miscellaneous}
-% 
-%    \begin{macrocode}
-local ExceptionInConsole = Exception *  Q ( ( 1 - P "\r" ) ^ 0 ) * EOL 
-%    \end{macrocode}
-% 
-% 
-% \bigskip
-% \paragraph{The main LPEG}
-%
-% First, the main loop :
-%    \begin{macrocode}
-MainLoopPython = 
-  (  ( space^1 * -1 ) 
-     + EOL
-     + Space 
-     + Tab
-     + Escape 
-     + CommentLaTeX
-     + Beamer
-     + UserCommands 
-     + LongString 
-     + Comment
-     + ExceptionInConsole
-     + Set 
-     + Delim
-%    \end{macrocode}
-% |Operator| must be before |Punct|.
-%    \begin{macrocode}
-     + Operator
-     + ShortString
-     + Punct
-     + FromImport
-     + RaiseException 
-     + DefFunction
-     + DefClass 
-     + Keyword * ( Space + Punct + Delim + EOL+ -1 ) 
-     + Decorator
-     + OperatorWord * ( Space + Punct + Delim + EOL+ -1 ) 
-     + Builtin * ( Space + Punct + Delim + EOL+ -1 ) 
-     + Identifier 
-     + Number
-     + Word
-  ) ^ 0 
-%    \end{macrocode}
-%
-% \bigskip
-% We recall that each line in the Python code to parse will be sent back to
-% LaTeX between a pair |\@@_begin_line:| -- |\@@_end_line:|\footnote{Remember
-% that the \texttt{\textbackslash @@\_end\_line:} must be explicit because it
-% will be used as marker in order to delimit the argument of the command
-% \texttt{\textbackslash @@\_begin\_line:}}.
-%    \begin{macrocode}
-local python = P ( true ) 
-
-python =
-  Ct (
-       ( ( space - P "\r" ) ^0 * P "\r" ) ^ -1 
-       * BeamerBeginEnvironments 
-       * PromptHastyDetection
-       * Lc '\\@@_begin_line:'
-       * Prompt 
-       * SpaceIndentation ^ 0 
-       * MainLoopPython
-       * -1 
-       * Lc '\\@@_end_line:' 
-     )
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-local languages = { }
-languages['python'] = python
-%    \end{macrocode}
-%
-% % \bigskip
-% \subsubsection{The LPEG ocaml}
-% 
-%    \begin{macrocode}
-local Delim = Q ( P "[|" + P "|]" + S "[()]" )
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-local Punct = Q ( S ",:;!" )
-%    \end{macrocode}
-% 
-%    \begin{macrocode}
-local identifier = 
-  ( R "az" + R "AZ" + P "_") * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0 
-
-local Identifier = K ( 'Identifier' , identifier )
-
-local Operator = 
-  K ( 'Operator' ,
-      P "!=" + P "<>" + P "==" + P "<<" + P ">>" + P "<=" + P ">=" + P ":=" 
-      + P "||" + P "&&" + P "//" + P "**" + P ";;" + P "::" + P "->" 
-      + P "+." + P "-." + P "*." + P "/." 
-      + S "-~+/*%=<>&@|" 
-    )
-
-local OperatorWord = 
-  K ( 'Operator.Word' ,
-      P "and" + P "asr" + P "land" + P "lor" + P "lsl" + P "lxor" 
-      + P "mod" + P "or" )
-
-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 "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" 
-  + P "value" + P "val" + P "virtual" + P "when" + P "while" + P "with" )
-  + 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" )
-%    \end{macrocode}
-% 
-% \bigskip
-% The following exceptions are exceptions in the standard library of OCaml (Stdlib).
-%    \begin{macrocode}
-local Exception =
-  K (   'Exception' ,
-       P "Division_by_zero" + P "End_of_File" + P "Failure" 
-     + P "Invalid_argument" + P "Match_failure" + P "Not_found" 
-     + P "Out_of_memory" + P "Stack_overflow" + P "Sys_blocked_io" 
-     + P "Sys_error" + P "Undefined_recursive_module" )
-%    \end{macrocode}
-%
-% \bigskip
-% \paragraph{The characters in OCaml}
-%
-%    \begin{macrocode}
-local Char = 
-  K ( 'String.Short' , P "'" * ( ( 1 - P "'" ) ^ 0 + P "\\'" ) * P "'" ) 
-%    \end{macrocode}
-% 
-%
-% \bigskip
-% \paragraph{Beamer}
-%
-%    \begin{macrocode}
-local BalancedBraces =
-  P { "E" ,
-       E = 
-           (
-             P "{" * V "E" * P "}" 
-             + 
-             P "\"" * ( 1 - S "\"" ) ^ 0 * P "\""  -- OCaml strings
-             + 
-             ( 1 - S "{}" ) 
-           ) ^ 0 
-    }
-%    \end{macrocode}
-%
-% 
-%    \begin{macrocode}
-if piton_beamer 
-then
-  Beamer =
-      L  ( P "\\pause" * ( P "[" * (1 - P "]") ^ 0 * P "]" ) ^ -1 ) 
-    + 
-      (   P "\\uncover"   * Lc ( '\\@@_beamer_command:n{uncover}' ) 
-        + P "\\only"      * Lc ( '\\@@_beamer_command:n{only}' ) 
-        + P "\\alert"     * Lc ( '\\@@_beamer_command:n{alert}' ) 
-        + P "\\visible"   * Lc ( '\\@@_beamer_command:n{visible}' ) 
-        + P "\\invisible" * Lc ( '\\@@_beamer_command:n{invisible}' ) 
-        + P "\\action"    * Lc ( '\\@@_beamer_command:n{action}' ) 
-      ) 
-      *
-      L ( ( P "<" * (1 - P ">") ^ 0 * P ">" ) ^ -1 * P "{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
-      * L ( P "}" )
-    +  
-      L ( 
-          ( P "\\alt" )
-          * P "<" * (1 - P ">") ^ 0 * P ">" 
-          * P "{" 
-        )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
-      * L ( P "}" )
-    +  
-      L ( 
-          ( P "\\temporal" )
-          * P "<" * (1 - P ">") ^ 0 * P ">" 
-          * P "{" 
-        )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
-      * L ( P "}" )
-  BeamerBeginEnvironments = 
-      ( space ^ 0 * 
-        L 
-          ( 
-            P "\\begin{" * BeamerNamesEnvironments * "}"
-            * ( P "<" * ( 1 - P ">") ^ 0 * P ">" ) ^ -1
-          )
-        * P "\r" 
-      ) ^ 0 
-  BeamerEndEnvironments = 
-      ( space ^ 0 * 
-        L ( P "\\end{" * BeamerNamesEnvironments * P "}" ) 
-        * P "\r" 
-      ) ^ 0 
-end
-%    \end{macrocode}
-%
-% \bigskip
-% \paragraph{EOL}
-%    \begin{macrocode}
-local EOL = 
-  P "\r" 
-  *
-  (
-    ( space^0 * -1 )
-    + 
-    Ct ( 
-         Cc "EOL"
-         * 
-         Ct (
-              Lc "\\@@_end_line:"
-              * BeamerEndEnvironments 
-              * BeamerBeginEnvironments 
-              * PromptHastyDetection
-              * Lc "\\@@_newline: \\@@_begin_line:"
-              * Prompt
-            )
-       )
-  ) 
-  *
-  SpaceIndentation ^ 0
-%    \end{macrocode}
-%
-%
-%    \begin{macrocode}
-% 
-% \paragraph{The strings}
-% 
-% We need a pattern |string| without captures because it will be used within the
-% comments of OCaml.
-%    \begin{macrocode}
-local string =
-       Q ( P "\"" )
-     * ( 
-         VisualSpace
-         + 
-         Q ( ( 1 - S " \"\r" ) ^ 1 ) 
-         +  
-         EOL
-       ) ^ 0 
-     * Q ( P "\"" ) 
-%    \end{macrocode}
-% 
-%    \begin{macrocode}
-local String = WithStyle ( 'String.Long' , string ) 
-%    \end{macrocode}
-%
-% 
-% \bigskip
-% Now, the ``quoted strings'' of OCaml (for example \verb+{ext|Essai|ext}+). 
-%
-% For those strings, we will do two consecutive analysis. First an analysis to
-% determine the whole string and, then, an analysis for the potential visual
-% spaces and the EOL in the string.
-% 
-% The first analysis require a match-time capture. For explanations about that
-% programmation, see the paragraphe \emph{Lua's long % strings} in
-% |www.inf.puc-rio.br/~roberto/lpeg|. 
-%    \begin{macrocode}
-local ext = ( R "az" + P "_" ) ^ 0
-local open = "{" * Cg(ext, 'init') * "|" 
-local close = "|" * C(ext) * "}"
-local closeeq = 
-  Cmt ( close * Cb('init'), 
-        function (s, i, a, b) return a==b end ) 
-%    \end{macrocode}
-%
-% \medskip
-% The \textsc{lpeg} |QuotedStringBis| will do the second analysis. 
-%    \begin{macrocode}
-local QuotedStringBis = 
-  WithStyle ( 'String.Long' ,
-      (  
-        VisualSpace
-        +
-        Q ( ( 1 - S " \r" ) ^ 1 ) 
-        +  
-        EOL
-      ) ^ 0  ) 
-
-%    \end{macrocode}
-% 
-% \medskip
-% We use a ``function capture'' (as called in the official documentation of the
-% \textsc{lpeg}) in order to do the second analysis on the result of the first one.
-%    \begin{macrocode}
-local QuotedString = 
-   C ( open * ( 1 - closeeq ) ^ 0  * close ) /
-  ( function (s) return QuotedStringBis : match(s) end ) 
-%    \end{macrocode}
-% 
-%
-% \bigskip
-% \paragraph{The comments in the OCaml listings}
-%
-% In OCaml, the delimiters for the comments are |(*| and |*)|. There are
-% unsymmetrical and, therefore, the comments may be nested. That's why we need a
-% grammar.
-% 
-% In these comments, we embed the math comments (between |$| and |$|) and we
-% embed also a treatment for the end of lines (since the comments may be multi-lines).
-% 
-%    \begin{macrocode}
-local Comment =
-  WithStyle ( 'Comment' ,
-     P {
-         "A" ,
-         A = Q "(*"
-             * ( V "A" 
-                 + Q ( ( 1 - P "(*" - P "*)" - S "\r$\"" ) ^ 1 ) -- $
-                 + string 
-                 + P "$" * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1 ) * P "$" -- $
-                 + EOL
-               ) ^ 0 
-             * Q "*)" 
-       }   )
-%    \end{macrocode}
-% 
-% \bigskip
-% \paragraph{The DefFunction}
-%
-%    \begin{macrocode}
-local DefFunction = 
-  K ( 'Keyword' , P "let rec" + P "let" + P "and" ) 
-  * Space
-  * K ( 'Name.Function.Internal' , identifier ) 
-  * Space 
-  * # ( P "=" * space * P "function" + ( 1 - P "=" ) )
-%    \end{macrocode}
-% 
-% \bigskip
-% \paragraph{The parameters of the types}
-% 
-%    \begin{macrocode}
-local TypeParameter = K ( 'TypeParameter' , P "'" * alpha * # ( 1 - P "'" ) ) 
-%    \end{macrocode}
-% 
-% \bigskip
-% \paragraph{The main LPEG}
-%
-% First, the main loop :
-%    \begin{macrocode}
-MainLoopOCaml = 
-  (  ( space^1 * -1 ) 
-     + EOL
-     + Space 
-     + Tab
-     + Escape 
-     + Beamer 
-     + TypeParameter
-     + String + QuotedString + Char
-     + Comment
-     + Delim
-     + Operator
-     + Punct
-     + FromImport
-     + ImportAs
-     + Exception 
-     + DefFunction
-     + Keyword * ( Space + Punct + Delim + EOL + -1 ) 
-     + OperatorWord * ( Space + Punct + Delim + EOL + -1 ) 
-     + Builtin * ( Space + Punct + Delim + EOL + -1 ) 
-     + Identifier 
-     + Number
-     + Word
-  ) ^ 0 
-%    \end{macrocode}
-%
-% \bigskip
-% We recall that each line in the Python code to parse will be sent back to
-% LaTeX between a pair |\@@_begin_line:| -- |\@@_end_line:|\footnote{Remember
-% that the \texttt{\textbackslash @@\_end\_line:} must be explicit because it
-% will be used as marker in order to delimit the argument of the command
-% \texttt{\textbackslash @@\_begin\_line:}}.
-%    \begin{macrocode}
-local ocaml = P ( true ) 
-
-ocaml =
-  Ct (
-       ( ( space - P "\r" ) ^0 * P "\r" ) ^ -1 
-       * BeamerBeginEnvironments 
-       * Lc ( '\\@@_begin_line:' ) 
-       * SpaceIndentation ^ 0 
-       * MainLoopOCaml
-       * -1 
-       * Lc ( '\\@@_end_line:' )
-     )
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-languages['ocaml'] = ocaml
-%    \end{macrocode}
-% 
-% \bigskip
-% \subsubsection{The function Parse}
-%
-%
-% The function |Parse| is the main function of the package \pkg{piton}.
-% It parses its argument and sends back to LaTeX the code with interlaced
-% formatting LaTeX instructions. In fact, everything is done by the
-% \textsc{lpeg} |python| which returns as capture a Lua table containing
-% data to send to LaTeX.
-% 
-% \bigskip
-%    \begin{macrocode}
-function piton.Parse(language,code)
-  local t = languages[language] : match ( code ) 
-  local left_stack = {}
-  local right_stack = {}
-  for _ , one_item in ipairs(t) 
-  do 
-     if one_item[1] == "EOL"
-     then 
-          for _ , s in ipairs(right_stack) 
-            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 ) 
-            end
-     else 
-          if one_item[1] == "Open"
-          then
-               tex.sprint( one_item[2] ) 
-               table.insert(left_stack,one_item[2])
-               table.insert(right_stack,one_item[3])
-          else 
-               if one_item[1] == "Close"
-               then
-                    tex.sprint( right_stack[#right_stack] ) 
-                    left_stack[#left_stack] = nil
-                    right_stack[#right_stack] = nil
-               else 
-                    tex.tprint(one_item)  
-               end 
-          end 
-     end 
-  end 
-end
-%    \end{macrocode}
-%
-%    
-%
-% \bigskip
-% The function |ParseFile| will be used by the LaTeX command |\PitonInputFile|.
-% That function merely reads the whole file (that is to say all its lines) and
-% then apply the function~|Parse| to the resulting Lua string.
-%    \begin{macrocode}
-function piton.ParseFile(language,name,first_line,last_line)
-  s = ''
-  local i = 0 
-  for line in io.lines(name) 
-  do i = i + 1 
-     if i >= first_line
-     then s = s .. '\r' .. line 
-     end
-     if i >= last_line then break end 
-  end
-  piton.Parse(language,s) 
-end
-%    \end{macrocode}
-% 
-% \bigskip
-% \subsubsection{Two variants of  the function Parse with integrated preprocessors}
-%
-% The following command will be used by the user command |\piton|.
-% For that command, we have to undo the duplication of the symbols |#|.
-%    \begin{macrocode}
-function piton.ParseBis(language,code)
-  local s = ( Cs ( ( P '##' / '#' + 1 ) ^ 0 ) ) : match ( code )
-  return piton.Parse(language,s) 
-end
-%    \end{macrocode}
-%
-% \bigskip
-% The following command will be used when we have to parse some small chunks of
-% code that have yet been parsed. They are re-scanned by LaTeX because it has
-% been required by |\@@_piton:n| in the \pkg{piton} style of the syntaxic
-% element. In that case, you have to remove the potential |\@@_breakable_space:|
-% that have been inserted when the key |break-lines| is in force.
-%    \begin{macrocode}
-function piton.ParseTer(language,code)
-  local s = ( Cs ( ( P '\\@@_breakable_space:' / ' ' + 1 ) ^ 0 ) ) 
-            : match ( code )
-  return piton.Parse(language,s)
-end
-%    \end{macrocode}
-% 
-%
-% \bigskip
-% \subsubsection{Preprocessors of the function Parse for gobble}
-%
-% We deal now with preprocessors of the function |Parse| which are needed when
-% the ``gobble mechanism'' is used.
-% 
-%
-% \bigskip
-% The function |gobble| gobbles $n$ characters on the left of the code. It uses
-% a \textsc{lpeg} that we have to compute dynamically because if depends on the
-% value of~$n$.
-%    \begin{macrocode}
-local function gobble(n,code)
-  function concat(acc,new_value)
-    return acc .. new_value
-  end 
-  if n==0 
-  then return code
-  else 
-       return Cf ( 
-                   Cc ( "" ) * 
-                   ( 1 - P "\r" ) ^ (-n)  * C ( ( 1 - P "\r" ) ^ 0 ) 
-                     * ( C ( P "\r" )
-                     * ( 1 - P "\r" ) ^ (-n)
-                     * C ( ( 1 - P "\r" ) ^ 0 )
-                    ) ^ 0 ,
-                    concat 
-                 ) : match ( code ) 
-  end
-end
-%    \end{macrocode}
-%
-% 
-% 
-% \bigskip
-% The following function |add| will be used in the following \textsc{lpeg}
-% |AutoGobbleLPEG|, |TabsAutoGobbleLPEG| and |EnvGobbleLPEG|.
-%    \begin{macrocode}
-local function add(acc,new_value)
-  return acc + new_value
-end 
-%    \end{macrocode}
-% 
-% \bigskip
-% The following \textsc{lpeg} returns as capture the minimal number of spaces at
-% the beginning of the lines of code. The main work is done by two \emph{fold
-% captures} (|lpeg.Cf|), one using |add| and the other (encompassing the
-% previous one) using |math.min| as folding operator.
-%    \begin{macrocode}
-local AutoGobbleLPEG = 
-    ( space ^ 0 * P "\r" ) ^ -1 
-    * Cf (
-           (
-%    \end{macrocode}
-% We don't take into account the empty lines (with only spaces).
-%    \begin{macrocode}
-             ( P " " ) ^ 0 * P "\r"
-             + 
-             Cf ( Cc(0) * ( P " " * Cc(1) ) ^ 0 , add )
-             * ( 1 - P " " ) * ( 1 - P "\r" ) ^ 0 * P "\r"
-           ) ^ 0
-%    \end{macrocode}
-% Now for the last line of the Python code...
-%    \begin{macrocode}
-           *
-           ( Cf ( Cc(0) * ( P " " * Cc(1) ) ^ 0 , add )
-           * ( 1 - P " " ) * ( 1 - P "\r" ) ^ 0 ) ^ -1 ,
-           math.min
-         )
-%    \end{macrocode}
-%
-% \bigskip
-% The following \textsc{lpeg} is similar but works with the indentations.
-%    \begin{macrocode}
-local TabsAutoGobbleLPEG = 
-    ( space ^ 0 * P "\r" ) ^ -1 
-    * Cf (
-           (
-             ( P "\t" ) ^ 0 * P "\r"
-             + 
-             Cf ( Cc(0) * ( P "\t" * Cc(1) ) ^ 0 , add )
-             * ( 1 - P "\t" ) * ( 1 - P "\r" ) ^ 0 * P "\r"
-           ) ^ 0
-           *
-           ( Cf ( Cc(0) * ( P "\t" * Cc(1) ) ^ 0 , add )
-           * ( 1 - P "\t" ) * ( 1 - P "\r" ) ^ 0 ) ^ -1 ,
-           math.min
-         )
-%    \end{macrocode}
-% 
-%
-%
-% \bigskip
-% The following \textsc{lpeg} returns as capture the number of spaces at the
-% last line, that is to say before the |\end{Piton}| (and usually it's also the
-% number of spaces before the corresponding |\begin{Piton}| because that's the
-% traditionnal way to indent in LaTeX). The main work is done by a \emph{fold
-% capture} (|lpeg.Cf|) using the function |add| as folding operator.
-%    \begin{macrocode}
-local EnvGobbleLPEG =
-  ( ( 1 - P "\r" ) ^ 0 * P "\r" ) ^ 0 
-    * Cf ( Cc(0) * ( P " " * Cc(1) ) ^ 0 , add ) * -1
-%    \end{macrocode}
-% 
-% \bigskip
-%    \begin{macrocode}
-function piton.GobbleParse(language,n,code)
-  if n==-1 
-  then n = AutoGobbleLPEG : match(code)
-  else if n==-2 
-       then n = EnvGobbleLPEG : match(code)
-       else if n==-3
-            then n = TabsAutoGobbleLPEG : match(code)
-            end
-       end
-  end
-  piton.Parse(language,gobble(n,code))
-end 
-%    \end{macrocode}
-%
-% \bigskip
-% \subsubsection{To count the number of lines}
-%
-% \medskip
-%    \begin{macrocode}
-function piton.CountLines(code)
-  local count = 0 
-  for i in code : gmatch ( "\r" ) do count = count + 1 end 
-  tex.sprint( 
-      luatexbase.catcodetables.expl , 
-      '\\int_set:Nn \\l_@@_nb_lines_int {' .. count .. '}' )
-end 
-%    \end{macrocode}
-%
-%    \begin{macrocode}
-function piton.CountNonEmptyLines(code)
-  local count = 0 
-  count = 
-  ( Cf (  Cc(0) * 
-          ( 
-            ( P " " ) ^ 0 * P "\r"  
-            + ( 1 - P "\r" ) ^ 0 * P "\r" * Cc(1) 
-          ) ^ 0 
-          * (1 - P "\r" ) ^ 0 ,
-         add
-       ) * -1 ) : match (code) 
-  tex.sprint( 
-      luatexbase.catcodetables.expl , 
-      '\\int_set:Nn \\l_@@_nb_non_empty_lines_int {' .. count .. '}' )
-end 
-%    \end{macrocode}
-%
-% \bigskip
-%    \begin{macrocode}
-function piton.CountLinesFile(name)
-  local count = 0 
-  for line in io.lines(name) do count = count + 1 end
-  tex.sprint( 
-      luatexbase.catcodetables.expl , 
-      '\\int_set:Nn \\l_@@_nb_lines_int {' .. count .. '}' )
-end 
-%    \end{macrocode}
-%
-%
-% \bigskip
-%    \begin{macrocode}
-function piton.CountNonEmptyLinesFile(name)
-  local count = 0 
-  for line in io.lines(name) 
-  do if not ( ( ( P " " ) ^ 0 * -1 ) : match ( line ) ) 
-     then count = count + 1 
-     end
-  end
-  tex.sprint( 
-      luatexbase.catcodetables.expl , 
-      '\\int_set:Nn \\l_@@_nb_non_empty_lines_int {' .. count .. '}' )
-end 
-%    \end{macrocode}
-% 
-%    \begin{macrocode}
-\end{luacode*}
-%    \end{macrocode}
-%
-% 
-% \vspace{1cm}
-% \section{History}
-%
-% % \subsection*{Changes between versions 1.4 and 1.5}
-%
-% New key |numbers-sep|.
-%
-%
-% \subsection*{Changes between versions 1.3 and 1.4}
-%
-% New key |identifiers| in |\PitonOptions|.
-%
-% New command |\PitonStyle|.
-%
-% |background-color| now accepts as value a \emph{list} of colors.
-%
-% \subsection*{Changes between versions 1.2 and 1.3}
-%
-% When the class Beamer is used, the environment |{Piton}| and the command 
-% |\PitonInputFile| are ``overlay-aware'' (that is to say, they accept a
-% specification of overlays between angular brackets).
-%
-% New key |prompt-background-color|
-%
-% It's now possible to use the command |\label| to reference a line of code in
-% an environment |{Piton}|.
-%
-% A new command |\|␣ is available in the argument of the command |\piton{...}| to
-% insert a space (otherwise, several spaces are replaced by a single space).
-% 
-% \subsection*{Changes between versions 1.1 and 1.2}
-%
-% New keys |break-lines-in-piton| and |break-lines-in-Piton|.
-% 
-% New key |show-spaces-in-string| and modification of the key |show-spaces|.
-%
-% When the class \cls{beamer} is used, the environements |{uncoverenv}|,
-% |{onlyenv}|, |{visibleenv}| and |{invisibleenv}|
-%
-%
-% \subsection*{Changes between versions 1.0 and 1.1}
-%
-% The extension \pkg{piton} detects the class \cls{beamer} and activates the
-% commands |\action|, |\alert|, |\invisible|, |\only|, |\uncover| and |\visible|
-% in the environments |{Piton}| when the class \cls{beamer} is used.
-%
-% \subsection*{Changes between versions 0.99 and 1.0}
-%
-% New key |tabs-auto-gobble|.
-% 
-% \subsection*{Changes between versions 0.95 and 0.99}
-%
-% New key |break-lines| to allow breaks of the lines of code (and other keys to
-% customize the appearance).
-%
-% \subsection*{Changes between versions 0.9 and 0.95}
-%
-% New key |show-spaces|.
-%
-% The key |left-margin| now accepts the special value |auto|.
-%
-% New key |latex-comment| at load-time and replacement of |##| by |#>|
-%
-% New key |math-comments| at load-time.
-%
-% New keys |first-line| and |last-line| for the command |\InputPitonFile|.
-%
-% \subsection*{Changes between versions 0.8 and 0.9}
-%
-% New key |tab-size|.
-%
-% Integer value for the key |splittable|.
-%
-% \subsection*{Changes between versions 0.7 and 0.8}
-% 
-% New keys |footnote| and |footnotehyper| at load-time.
-%
-% New key |left-margin|.
-% 
-% \subsection*{Changes between versions 0.6 and 0.7}
-% 
-% New keys |resume|, |splittable| and |background-color| in |\PitonOptions|.
-%
-% The file |piton.lua| has been embedded in the file |piton.sty|. That means
-% that the extension \pkg{piton} is now entirely contained in the file |piton.sty|.
-% 
-%
-%
-% \tableofcontents
-%
-% \end{document}
-% 
-%
-% Local Variables:
-% TeX-fold-mode: t
-% TeX-fold-preserve-comments: nil
-% flyspell-mode: nil
-% fill-column: 80
-% End:
-
-
-
-
-
-
+% \iffalse -*- coding: utf-8 ; -*- \fi \iffalse meta-comment
+%
+% Copyright (C) 2023 by F. Pantigny
+% -----------------------------------
+%
+% This file may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3
+% of this license or (at your option) any later version.
+% The latest version of this license is in:
+%
+% http://www.latex-project.org/lppl.txt
+%
+% and version 1.3 or later is part of all distributions of LaTeX
+% version 2005/12/01 or later.
+%
+% \fi
+% \iffalse
+\def\myfileversion{1.5a}
+\def\myfiledate{2023/04/11}
+%
+%
+%<*batchfile> 
+\begingroup
+\input l3docstrip.tex
+\keepsilent
+\usedir{tex/latex/cascade}
+\preamble
+
+Copyright (C) 2022-2023 by F. Pantigny
+-----------------------------------
+
+This file may be distributed and/or modified under the
+conditions of the LaTeX Project Public License, either version 1.3
+of this license or (at your option) any later version.
+The latest version of this license is in:
+
+http://www.latex-project.org/lppl.txt
+
+and version 1.3 or later is part of all distributions of LaTeX
+version 2005/12/01 or later.
+
+\endpreamble
+\askforoverwritefalse
+\endgroup
+%</batchfile>
+%
+%<@@=piton>
+%<*driver>
+\documentclass{l3doc}
+\usepackage{geometry}
+\geometry{left=2.8cm,right=2.8cm,top=2.5cm,bottom=2.5cm,papersize={21cm,29.7cm}}
+\usepackage{fontspec}
+\usepackage[dvipsnames]{xcolor}
+\usepackage{caption,tabularx,tcolorbox,luacolor,lua-ul}
+\def\emphase{\bgroup\color{RoyalPurple}\let\next=}
+\fvset{commandchars=\~\#\@,formatcom=\color{gray}}
+\captionsetup{labelfont = bf}
+\usepackage{ragged2e}
+\usepackage[footnotehyper,escape-inside=$$,math-comments]{piton} % $$
+
+\parindent 0pt
+\skip\footins = 2\bigskipamount
+
+\PitonOptions{gobble=2}
+
+\EnableCrossrefs
+
+\begin{document}
+\DocInput{piton.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \catcode`\" = 11 
+% 
+% \title{The package \pkg{piton}\thanks{This document corresponds to the
+% version~\myfileversion\space of \pkg{piton}, at the date of~\myfiledate.}} 
+% \author{F. Pantigny \\ \texttt{fpantigny@wanadoo.fr}}
+%
+% \maketitle
+%
+% \begin{abstract}
+% The package \pkg{piton} provides tools to typeset Python listings with
+% syntactic highlighting by using the Lua library LPEG. It requires LuaLaTeX.
+% \end{abstract}
+% 
+% 
+%
+% \section{Presentation}
+% 
+%
+% The package \pkg{piton} uses the Lua library LPEG\footnote{LPEG is a
+% pattern-matching library for Lua, written in C, based on \emph{parsing
+% expression grammars}: \url{http://www.inf.puc-rio.br/~roberto/lpeg/}} for
+% parsing Python listings and typeset them with syntactic highlighting. Since it
+% uses Lua code, it works with |lualatex| only (and won't work with the other
+% engines: |latex|, |pdflatex| and |xelatex|). It does not use external program
+% and the compilation does not require |--shell-escape|. The compilation is very
+% fast since all the parsing is done by the library LPEG, written in C.
+% 
+% \bigskip
+% Here is an example of code typeset by \pkg{piton}, with the environment |{Piton}|.
+%
+% \bigskip
+%
+%    \begin{Piton}
+% from math import pi
+%
+% def arctan(x,n=10):
+%    """Compute the mathematical value of arctan(x)
+%
+%    n is the number of terms in the sum
+%    """
+%     if x < 0:
+%         return -arctan(-x) # recursive call
+%     elif x > 1: 
+%         return pi/2 - arctan(1/x) 
+%         #> (we have used that $\arctan(x)+\arctan(1/x)=\frac{\pi}{2}$ for $x>0$)\footnote{This LaTeX escape has been done by beginning the comment by \ttfamily\#>.}
+%     else: 
+%         s = 0
+%         for k in range(n):
+%             s += (-1)**k/(2*k+1)*x**(2*k+1)
+%         return s 
+%    \end{Piton}
+% 
+%
+% \bigskip
+% The package \pkg{piton} is entirely contained in the file
+% |piton.sty|. This file may be put in the current directory or in a
+% |texmf| tree. However, the best is to install \pkg{piton} with a TeX
+% distribution such as MiKTeX, TeX Live or MacTeX.
+% 
+% 
+% \section{Use of the package}
+%
+%
+% \subsection{Loading the package}
+% 
+% The package \pkg{piton} should be loaded with the classical command
+% |\usepackage|: |\usepackage{piton}|.
+%
+% \smallskip
+% Nevertheless, we have two remarks:
+% \begin{itemize}
+% \item the package \pkg{piton} uses the package \pkg{xcolor} (but \pkg{piton}
+% does \emph{not} load \pkg{xcolor}: if \pkg{xcolor} is not loaded before the
+% |\begin{document}|, a fatal error will be raised).
+% \item the package \pkg{piton} must be used with LuaLaTeX exclusively: if
+% another LaTeX engine (|latex|, |pdflatex|, |xelatex|,\dots ) is used, a
+% fatal error will be raised.
+% \end{itemize}
+% 
+% \subsection{The tools provided to the user}
+% 
+% The package \pkg{piton} provides several tools to typeset Python code: the
+% command |\piton|, the environment |{Piton}| and the command |\PitonInputFile|.
+%
+% \begin{itemize}\setlength{\fboxsep}{1pt}
+% \item The command \colorbox{gray!20}{\texttt\textbackslash piton} should be
+% used to typeset small pieces of code inside a paragraph. For example:
+% 
+% {\color{gray}\verb|\piton{def square(x): return x*x}|}\qquad 
+% \piton{def square(x): return x*x}
+%
+% The syntax and particularities of the command |\piton| are detailed below.
+%
+% \item The environment \colorbox{gray!20}{\ttfamily\{Piton\}} should be used to
+% typeset multi-lines code. Since it takes its argument in a verbatim mode, it
+% can't be used within the argument of a LaTeX command. For sake of
+% customization, it's possible to define new environments similar to the
+% environment |{Piton}| with the command |\NewPitonEnvironment|:
+% cf.~\ref{NewPitonEnvironment} p.~\pageref{NewPitonEnvironment}.
+%
+% \item The command \colorbox{gray!20}{\ttfamily\textbackslash PitonInputFile}
+% is used to insert and typeset a whole external file.
+%
+% That command takes in as optional argument (between square brackets) two keys
+% |first-line| and |last-line|: only the part between the corresponding lines
+% will be inserted.
+% \end{itemize}
+%
+% \subsection{The syntax of the command \textbackslash piton}
+% 
+% In fact, the command |\piton| is provided with a double syntax. It may be used
+% as a standard command of LaTeX taking its argument between curly braces
+% (|\piton{...}|) but it may also be used with a syntax similar to the syntax of
+% the command
+% |\verb|, that is to say with the argument delimited by two identical characters (e.g.: \verb!\piton|...|!).
+% 
+% \begin{itemize}
+% \item {\color{blue} \textsf{Syntax} \verb|\piton{...}|}\par\nobreak
+% When its argument is given between curly braces, the command |\piton| does not
+% take its argument in verbatim mode. In particular:
+% \begin{itemize}
+% \item several consecutive spaces will be replaced by only one space,
+% 
+% {\color{cyan} but the command |\|␣ is provided to force the insertion of a space};
+%
+% \item it's not possible to use |%| inside the argument,
+%
+% {\color{cyan} but the command |\%| is provided to insert a |%|};
+%
+% \item the braces must be appear by pairs correctly nested
+%
+% {\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,
+%
+% {\color{cyan} so it's possible to use |\\| to insert a backslash}.
+% \end{itemize}
+%
+%
+% The other characters (including |#|, |^|, |_|, |&|, |$| and |@|)
+% must be inserted without backslash.
+% 
+% \bigskip
+%\begin{tabular}{>{\color{gray}}w{l}{75mm}@{\hspace*{1cm}}l}
+% \omit Examples : \hfil \\
+% \noalign{\vskip1mm}
+% \verb|\piton{MyString = '\\n'}| & 
+% \piton{MyString = '\\n'} \\
+% \verb|\piton{def even(n): return n\%2==0}| & 
+% \piton{def even(n): return n\%2==0} \\
+% \verb|\piton{c="#"    # an affectation }| & 
+% \piton{c="#"     # an affectation } \\
+% \verb|\piton{c="#" \ \ \ # an affectation }| & 
+% \piton{c="#" \ \ \ # an affectation } \\
+% \verb|\piton{MyDict = {'a': 3, 'b': 4 }}| &
+% \piton{MyDict = {'a': 3, 'b': 4 }}
+% \end{tabular}
+%
+% \bigskip
+% It's possible to use the command |\piton| in the arguments of a
+% LaTeX command.\footnote{For example, it's possible to use the command
+% \texttt{\textbackslash piton} in a footnote. Example :
+% \piton{s = 'A string'}.}
+%
+% \bigskip
+% \item {\color{blue} \textsf{Syntaxe} \verb!\piton|...|!}\par\nobreak
+%
+% When the argument of the command |\piton| is provided between two identical
+% characters, that argument is taken in a \emph{verbatim mode}. Therefore, with
+% that syntax, the command |\piton| can't be used within the argument of another
+% command. 
+%
+% \medskip
+%
+% \begin{tabular}{>{\color{gray}}w{l}{75mm}@{\hspace*{1cm}}l}
+% \omit Examples : \hfil \\
+% \noalign{\vskip1mm}
+% \verb!\piton|MyString = '\n'|! & 
+% \piton|MyString = '\n'| \\
+% \verb|\piton!def even(n): return n%2==0!| & 
+% \piton!def even(n): return n%2==0! \\
+% \verb|\piton+c="#"    # an affectation +| & 
+% \piton+c="#"     # an affectation + \\
+% \verb|\piton?MyDict = {'a': 3, 'b': 4}?| &
+% \piton!MyDict = {'a': 3, 'b': 4}!
+% \end{tabular}
+%
+% \end{itemize}
+% 
+% \section{Customization}
+%
+% \subsection{The command \textbackslash PitonOptions}
+%
+%
+% \NewDocumentCommand{\Definition}{m}
+%   {{\setlength{\fboxsep}{1pt}\colorbox{gray!20}{\ttfamily \vphantom{gl}#1}}}
+% 
+% The command |\PitonOptions| takes in as argument a comma-separated list of
+% \textsl{key=value} pairs. The scope of the settings done by that command is
+% the current TeX group.\footnote{We remind that a LaTeX environment is, in
+% particular, a TeX group.}
+%
+% \begin{itemize}
+% \item The key \Definition{gobble} takes in as value a
+% positive integer~$n$: the first $n$ characters are discarded (before the
+% process of highlightning of the code) for each line of the environment
+% |{Piton}|. These characters are not necessarily spaces.
+%
+% \item When the key \Definition{auto-gobble} is in force, the
+% extension \pkg{piton} computes the minimal value $n$ of the number of
+% consecutive spaces beginning each (non empty) line of the environment
+% |{Piton}| and applies |gobble| with that value of~$n$.
+%
+% \item When the key \Definition{env-gobble} is in force, \pkg{piton} analyzes the last
+% line of the environment |{Piton}|, that is to say the line which contains
+% |\end{Piton}| and determines whether that line contains only spaces followed
+% by the |\end{Piton}|. If we are in that situation, \pkg{piton} computes the
+% number~$n$ of spaces on that line and applies |gobble| with that value of~$n$.
+% The name of that key comes from \emph{environment gobble}: the effect of
+% gobble is set by the position of the commands |\begin{Piton}| and
+% |\end{Piton}| which delimit the current environment.
+%
+% \item With the key \Definition{line-numbers}, the \emph{non empty} lines (and
+% all the lines of the \emph{docstrings}, even the empty ones) are numbered in
+% the environments |{Piton}| and in the listings resulting from the use of
+% |\PitonInputFile|.
+% 
+% \item With the key \Definition{all-line-numbers}, \emph{all} the lines are numbered,
+% including the empty ones.
+%
+% \item \colorbox{yellow!50}{\bfseries{New 1.5}}\par\nobreak
+%
+% The key \Definition{numbers-sep} is the horizontal distance between the
+% numbers of lines (inserted by |line-numbers| of |all-line-numbers|) and the
+% beginning of the lines of code. The initial value is 0.7~em.
+%
+% \item With the key \Definition{resume}, the counter of lines is not set to zero
+% at the beginning of each environment |{Piton}| or use of |\PitonInputFile| as
+% it is otherwise. That allows a numbering of the lines across several
+% environments.
+%
+% \item The key \Definition{left-margin} corresponds to a margin on the left.
+% That key may be useful in conjonction with the key |line-numbers| or the key
+% |line-all-numbers| if one does not want the numbers in an overlapping position
+% on the left.
+%
+% It's possible to use the key |left-margin| with the value |auto|. With that
+% value, if the key |line-numbers| or the key |all-line-numbers| is used, a
+% margin will be automatically inserted to fit the numbers of lines. See an
+% 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|).
+%
+% \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.
+%
+% \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}|.
+%
+% \item With the key \Definition{prompt-background-color}, \pkg{piton} adds a
+% color background to the lines beginning with the prompt ``|>>>|'' (and its
+% continuation ``|...|'') characteristic of the Python consoles with
+% \textsc{repl} (\emph{read-eval-print loop}).
+%
+% \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
+% character~U+2423 must be present in the monospaced font which is
+% used.\footnote{The package \pkg{piton} simply uses the current monospaced
+% font. The best way to change that font is to use the command
+% \texttt{\textbackslash setmonofont} of the package \pkg{fontspec}.}\par\nobreak
+% \begingroup \PitonOptions{show-spaces-in-strings} Example : 
+% \piton|my_string = 'Very good answer'| \endgroup
+%
+% With the key \Definition{show-spaces}, all the spaces are replaced by U+2423
+% (and no line break can occur on those ``visible spaces'', even when the key
+% |break-lines|\footnote{cf. \ref{line-breaks} p.~\pageref{line-breaks}} is in
+% force). 
+% \end{itemize}
+%
+% \bigskip
+%
+% \begingroup
+% \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
+% \begin{Verbatim}
+% ~emphase&\PitonOptions{line-numbers,auto-gobble,background-color = gray!15}@
+% \begin{Piton}
+%     from math import pi
+%     def arctan(x,n=10):
+%         """Compute the mathematical value of arctan(x)
+%
+%         n is the number of terms in the sum
+%         """
+%         if x < 0:
+%             return -arctan(-x) # recursive call
+%         elif x > 1: 
+%             return pi/2 - arctan(1/x) 
+%             #> (we have used that $\arctan(x)+\arctan(1/x)=\frac{\pi}{2}$ pour $x>0$)
+%         else 
+%             s = 0
+%             for k in range(n):
+%                 s += (-1)**k/(2*k+1)*x**(2*k+1)
+%             return s 
+% \end{Piton}
+% \end{Verbatim}
+% \endgroup
+%
+% \begingroup
+% \PitonOptions{line-numbers,background-color = gray!15}
+%    \begin{Piton}
+% from math import pi
+%
+% def arctan(x,n=10):
+%     """Compute the mathematical value of arctan(x)
+%                                         
+%     n is the number of terms in the sum
+%     """
+%     if x < 0:
+%         return -arctan(-x) # recursive call
+%     elif x > 1: 
+%         return pi/2 - arctan(1/x) 
+%         #> (we have used that $\arctan(x)+\arctan(1/x)=\frac{\pi}{2}$ for $x>0$)
+%     else 
+%         s = 0
+%         for k in range(n):
+%             s += (-1)**k/(2*k+1)*x**(2*k+1)
+%         return s 
+%    \end{Piton}
+% \endgroup
+% 
+% \bigskip
+% The command |\PitonOptions| provides in fact several other keys which will be
+% described further (see in particular the ``Pages breaks and line breaks''
+% p.~\pageref{breakable}). 
+%
+% \subsection{The styles}
+%
+% \label{styles}
+%
+% The package \pkg{piton} provides the command |\SetPitonStyle| to customize the
+% different styles used to format the syntactic elements of the Python listings.
+% The customizations done by that command are limited to the current TeX
+% group.\footnote{We remind that a LaTeX environment is, in particular, a TeX group.}
+%
+% \bigskip
+% The command |\SetPitonStyle| takes in as argument a comma-separated list of
+% \textsl{key=value} pairs. The keys are names of styles and the value are LaTeX
+% formatting instructions.
+%
+% \bigskip
+% These LaTeX instructions must be formatting instructions such as
+% |\color{...}|, |\bfseries|, |\slshape|, etc. (the commands of this kind are
+% sometimes called \emph{semi-global} commands). It's also possible to put,
+% \emph{at the end of the list of instructions}, a LaTeX command taking exactly
+% one argument.
+% 
+% \bigskip
+% Here an example which changes the style used to highlight, in the definition
+% of a Python function, the name of the function which is defined. That code
+% uses the command |\highLight| of \pkg{lua-ul} (that package requires also the
+% package \pkg{luacolor}).
+%
+% \begin{verbatim}
+% \SetPitonStyle{ Name.Function = \bfseries \highLight[red!50] }
+% \end{verbatim}
+%
+% In that example, |\highLight[red!50]| must be considered as the name of a
+% LaTeX command which takes in exactly one argument, since, usually, it is used
+% with |\highLight[red!50]{...}|.
+%
+% \medskip
+% \begingroup
+% \SetPitonStyle 
+%   { Name.Function = \bfseries \highLight[red!50] }
+% With that setting, we will have : \piton{def cube(x) : return x * x * x }
+% \endgroup
+% 
+% \bigskip
+% The different styles are described in the table \ref{Semantic}. The initial
+% settings done by \pkg{piton} in |piton.sty| are inspired by the style
+% \pkg{manni} de Pygments.\footnote{See:
+% \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.
+%
+% \smallskip
+% For example, it's possible to write |{\PitonStyle{Keyword}{function}}| and we
+% will have the word {\PitonStyle{Keyword}{function}} formatted as a keyword.
+%
+% \smallskip
+% The syntax |{\PitonStyle{|\textsl{\texttt{style}}|}{...}}| is mandatory in
+% order to be able to deal both with the semi-global commands and the commands
+% with arguments which may be present in the definition of the style
+% \texttt{\textsl{style}}. 
+%
+% \begin{table}[b]
+% \centering
+% \caption{Usage of the different styles}
+% \label{Semantic}
+% \begin{tabular}{@{}>{\ttfamily}l>{\RaggedRight\arraybackslash}p{9cm}@{}}
+% \toprule
+% \normalfont Style  & Usage \\
+% \midrule
+% Number & the numbers \\
+% String.Short & the short strings (between \texttt{'} or \verb|"|) \\
+% String.Long & the long strings (between \texttt{'''} or \verb|"""|) except the
+% documentation strings \\ 
+% String & that keys sets both |String.Short| and |String.Long| \\
+% String.Doc & the documentation strings (only between \texttt{"""} following
+% PEP~257) \\
+% String.Interpol & the syntactic elements of the fields of the f-strings (that
+% is to say the characters \texttt{\{} and \texttt{\}}) \\
+% Operator & the following operators : \texttt{!= == << >> - \~{} + / * \% = < > \& .} \verb+|+ \verb|@|\\
+% Operator.Word & the following operators : \texttt{in}, \texttt{is},
+% \texttt{and}, \texttt{or} and \texttt{not} \\ 
+% Name.Builtin & the predefined functions of Python \\
+% Name.Function & the name of the functions defined by the user, at the point of
+% their definition (that is to say after the keyword |def|) \\
+% Name.Decorator & the decorators (instructions beginning by \verb|@|) \\
+% Name.Namespace & the name of the modules (= external libraries) \\
+% Name.Class & the name of the classes at the point of their definition (that is
+% to say after the keyword |class|) \\
+% Exception & the names of the exceptions (eg: \texttt{SyntaxError}) \\
+% Comment & the comments beginning with \verb|#| \\
+% Comment.LaTeX & the comments beginning by \verb|#>|, which are composed in LaTeX by
+% \pkg{piton} (and simply called ``LaTeX comments'' in this document) \\
+% Keyword.Constant & |True|, |False| and |None| \\
+% Keyword & the following keywords :
+%           \ttfamily as, assert, break, case, continue, def, del,
+%           elif, else, except, exec, finally, for, from, 
+%           global, if, import, lambda, non local,
+%           pass, raise, return, try, while,
+%           with, yield, yield from.\\
+% \bottomrule 
+% \end{tabular}
+% \end{table}
+%
+%
+%
+% 
+% \subsection{Creation of new environments}
+%
+% \label{NewPitonEnvironment}
+% 
+% Since the environment |{Piton}| has to catch its body in a special way (more
+% or less as verbatim text), it's not possible to construct new environments
+% directly over the environment |{Piton}| with the classical commands
+% |\newenvironment| or |\NewDocumentEnvironment|.
+%
+% That's why \pkg{piton} provides a command |\NewPitonEnvironment|. That
+% command takes in three mandatory arguments. 
+
+% That command has the same syntax as the classical environment
+% |\NewDocumentEnvironment|.
+% 
+% \bigskip
+% With the following instruction, a new environment |{Python}| will be
+% constructed with the same behaviour as |{Piton}|:
+%
+% {\color{gray}\verb|\NewPitonEnvironment{Python}{}{}{}|}
+%
+% \bigskip
+% If one wishes an environment |{Python}| with takes in as optional argument
+% (between square brackets) the keys of the command |\PitonOptions|, it's
+% possible to program as follows:
+%
+% {\color{gray}\verb|\NewPitonEnvironment{Python}{O{}}{\PitonOptions{#1}}{}|}
+% 
+% \bigskip
+% If one wishes to format Python code in a box of \pkg{tcolorbox}, it's possible
+% to define an environment |{Python}| with the following code (of course, the
+% package \pkg{tcolorbox} must be loaded).
+%
+%\begin{verbatim}
+% \NewPitonEnvironment{Python}{}
+%   {\begin{tcolorbox}}
+%   {\end{tcolorbox}}
+% \end{verbatim}
+%
+% \bigskip
+% With this new environment |{Python}|, it's possible to write:
+%
+% \begin{Verbatim}
+% ~emphase#\begin{Python}@
+% def square(x):
+%     """Compute the square of a number"""
+%     return x*x
+% ~emphase#\end{Python}@
+% \end{Verbatim}
+%
+% \NewPitonEnvironment{Python}{}
+%   {\begin{tcolorbox}}
+%   {\end{tcolorbox}}
+%
+% \begin{Python}
+% def square(x):
+%     """Compute the square of a number"""
+%     return x*x
+% \end{Python}
+%
+%
+% \section{Advanced features}
+%
+% \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|.
+%
+% \smallskip
+% That key takes in as argument a value of the following format:
+%
+% \quad |{ names = |\textsl{\ttfamily names}|, style = |\textsl{\ttfamily
+% instructions}| }|
+%
+% \begin{itemize}
+% \item \textsl{\ttfamily names} is a (comma-separated) list of identifiers
+% names; 
+%
+% \item \textsl{\ttfamily instructions} is a list of LaTeX instructions of the
+% same type that \pkg{piton} ``styles'' previously presented (cf~\ref{styles}
+% p.~\pageref{styles}). 
+% \end{itemize}
+%
+% \emph{Caution}: Only the identifiers may be concerned by that key. The
+% keywords and the built-in functions won't be affected, even if their name is
+% in the list |\textsl{\ttfamily names}|.
+% 
+% \begin{Verbatim}
+% \PitonOptions 
+%   {
+%     ~emphase#identifiers@ = 
+%      {
+%        ~emphase#names@ = { l1 , l2 } , 
+%        ~emphase#style@ = \color{red} 
+%      }
+%   }
+%
+% \begin{Piton}
+% def tri(l):
+%     """Segmentation sort"""
+%     if len(l) <= 1:
+%         return l
+%     else:
+%         a = l[0]
+%         l1 = [ x for x in l[1:] if x < a  ]
+%         l2 = [ x for x in l[1:] if x >= a ]
+%         return tri(l1) + [a] + tri(l2)
+% \end{Piton}
+% \end{Verbatim}
+%
+%
+% \bigskip
+%
+% \begingroup
+%
+% \PitonOptions 
+%   {
+%     identifiers = 
+%      {
+%        names = { l1 , l2 } , 
+%        style = \color{red} 
+%      }
+%   }
+%
+% \begin{Piton}
+% def tri(l):
+%     """Segmentation sort"""
+%     if len(l) <= 1:
+%         return l
+%     else:
+%         a = l[0]
+%         l1 = [ x for x in l[1:] if x < a  ]
+%         l2 = [ x for x in l[1:] if x >= a ]
+%         return tri(l1) + [a] + tri(l2)
+% \end{Piton}
+%
+% \endgroup
+% 
+% \bigskip
+% By using the key |identifier|, it's possible to add other built-in functions
+% (or other new keywords, etc.) that will be detected by \pkg{piton}.
+%
+%
+% \begin{Verbatim}
+% \PitonOptions 
+%   {
+%     ~emphase#identifiers@ = 
+%      {
+%        names = { cos, sin, tan, floor, ceil, trunc, pow, exp, ln, factorial } , 
+%        style = \PitonStyle{Name.Builtin}
+%      }
+%   }
+%
+% \begin{Piton}
+% from math import *
+% cos(pi/2) 
+% factorial(5)
+% ceil(-2.3) 
+% floor(5.4) 
+% \end{Piton}
+% \end{Verbatim}
+%
+% \begingroup
+%
+% \PitonOptions 
+%   {
+%     identifiers = 
+%      {
+%        names = { cos, sin, tan, floor, ceil, trunc, pow, exp, ln, factorial } , 
+%        style = \PitonStyle{Name.Builtin}
+%      }
+%   }
+%
+% \begin{Piton}
+% from math import *
+% cos(pi/2) 
+% factorial(5)
+% ceil(-2.3) 
+% floor(5.4) 
+% \end{Piton}
+%
+%
+% \endgroup
+%
+%
+% \subsection{Mechanisms to escape to LaTeX}
+%
+% The package \pkg{piton} provides several mechanisms for escaping to LaTeX:
+% \begin{itemize}
+% \item It's possible to compose comments entirely in LaTeX.
+% \item It's possible to have the elements between \texttt{\$} in the comments
+% composed in LateX mathematical mode.
+% \item It's also possible to insert LaTeX code almost everywhere in a Python listing.
+% \end{itemize}
+%
+% One should aslo remark that, when the extension \pkg{piton} is used with the
+% class \cls{beamer}, \pkg{piton} detects in |{Piton}| many commands and
+% environments of Beamer: cf. \ref{beamer} p.~\pageref{beamer}.
+%
+% \subsubsection{The ``LaTeX comments''}
+%
+% In this document, we call ``LaTeX comments'' the comments which begins by
+% |#>|. The code following those characters, until the end of the line, will be
+% composed as standard LaTeX code. There is two tools to customize those
+% comments.
+%
+% \begin{itemize}
+% \item It's possible to change the syntatic mark (which, by default, is |#>|).
+% For this purpose, there is a key |comment-latex| available at load-time (that
+% is to say at the |\usepackage|) which allows to choice the characters which,
+% preceded by |#|, will be the syntatic marker.
+%
+% For example, with the following loading:
+% 
+% \quad \verb|\usepackage[comment-latex = LaTeX]{piton}|
+%
+% the LaTeX comments will begin by |#LaTeX|.
+%
+% If the key |comment-latex| is used with the empty value, all the Python
+% comments (which begins by |#|) will, in fact, be ``LaTeX comments''.
+%
+% \smallskip
+% \item It's possible to change the formatting of the LaTeX comment itself by
+% changing the \pkg{piton} style |Comment.LaTeX|.
+%
+% For example, with |\SetPitonStyle{Comment.LaTeX = \normalfont\color{blue}}|,
+% the LaTeX comments will be composed in blue.
+%
+% If you want to have a character |#| at the beginning of the LaTeX comment in
+% the \textsc{pdf}, you can use set |Comment.LaTeX| as follows:
+%
+% \begin{Verbatim}
+% \SetPitonStyle{Comment.LaTeX = \color{gray}\~#\normalfont\space }
+% \end{Verbatim}
+% 
+% For other examples of customization of the LaTeX comments, see the part
+% \ref{example-comments} p.~\pageref{example-comments}
+% \end{itemize}
+%
+% \bigskip
+% If the user has required line numbers in the left margin (with the
+% key |line-numbers| or the key |all-line-numbers| of |\PitonOptions|), it's
+% possible to refer to a number of line with the command |\label| used in a
+% LaTeX comment.\footnote{That feature is implemented by using a redefinition of
+% the standard command \texttt{\textbackslash label} in the environments
+% \texttt{\{Piton\}}. Therefore, incompatibilities may occur with extensions
+% which redefine (globally) that command \texttt{\textbackslash label} (for
+% example: \pkg{varioref}, \pkg{refcheck}, \pkg{showlabels}, etc.)}
+%
+% \subsubsection{The key ``math-comments''}
+%
+% It's possible to request that, in the standard Python comments (that is to say
+% those beginning by |#| and not |#>|), the elements between \texttt{\$} be
+% composed in LaTeX mathematical mode (the other elements of the comment being
+% composed verbatim).
+%
+% That feature is activated by the key |math-comments| at load-time (that is to
+% say with the |\usepackage|).
+%
+% \medskip
+% In the following example, we assume that the key |math-comments| has been used
+% when loading \pkg{piton}.
+%
+% \begin{Verbatim}
+% \begin{Piton}
+% def square(x):
+%     return x*x ~# compute $x^2$
+% \end{Piton}
+% \end{Verbatim}
+%
+% \begin{Piton}
+% def square(x):
+%     return x*x # compute $x^2$
+% \end{Piton}
+% 
+% \subsubsection{The mechanism ``escape-inside''}
+%
+% It's also possible to overwrite the Python listings to insert LaTeX code
+% almost everywhere (but between lexical units, of course). By default,
+% \pkg{piton} does not fix any character for that kind of escape.
+%
+% In order to use this mechanism, it's necessary to specify two characters which
+% will delimit the escape (one for the beginning and one for the end) by using
+% the key |escape-inside| at load-time (that is to say at the
+% |\begin{docuemnt}|). 
+%
+% \medskip
+% In the following example, we assume that the extension \pkg{piton} has been
+% loaded by the following instruction.
+%
+% \begin{Verbatim}
+% \usepackage[~emphase#escape-inside=$$@]{piton}
+% \end{Verbatim}
+%
+% \medskip
+% In the following code, which is a recursive programmation of the mathematical
+% factorial, we decide to highlight in yellow the instruction which contains the
+% recursive call. That example uses the command |\highLight| of \pkg{lua-ul}
+% (that package requires itself the package \pkg{luacolor}).
+% \begin{Verbatim}
+% \begin{Piton}
+% def fact(n):
+%     if n==0:
+%         return 1
+%     else:
+%         ~emphase#$\highLight{$@return n*fact(n-1)~emphase#$}$@
+% \end{Piton}
+% \end{Verbatim}
+%
+%    \begin{Piton}
+% def fact(n):
+%     if n==0:
+%         return 1
+%     else:
+%         $\highLight{$return n*fact(n-1)$}$
+%    \end{Piton}
+%         
+% \bigskip
+% In fact, in that case, it's probably easier to use the command |\@highLight|
+% of \pkg{lua-ul}: that command sets a yellow background until the end of the
+% current TeX group. Since the name of that command contains the character |@|,
+% it's necessary to define a synonym without |@| in order to be able to use it
+% directly in |{Piton}|.
+% \begingroup
+% \fvset{commandchars=\~\#\+,formatcom=\color{gray}}
+% \begin{Verbatim}
+% \makeatletter
+% ~emphase#\let\Yellow\@highLight+
+% \makeatother
+% \end{Verbatim}
+% \endgroup
+%
+% \begin{Verbatim}
+% \begin{Piton}
+% def fact(n):
+%     if n==0:
+%         return 1
+%     else:
+%         ~emphase#$\Yellow$@return n*fact(n-1)
+% \end{Piton}
+% \end{Verbatim}
+%
+% \makeatletter
+% \let\Yellow\@highLight
+% \makeatother
+%
+%
+% \begin{Piton}
+% def fact(n):
+%     if n==0:
+%         return 1
+%     else:
+%         $\Yellow$return n*fact(n-1)
+% \end{Piton}
+%
+%
+%
+% \bigskip
+% \emph{Caution} : The escape to LaTeX allowed by the characters of
+% |escape-inside| is not active in the strings nor in the Python comments
+% (however, it's possible to have a whole Python comment composed in LaTeX by
+% beginning it with |#>|; such comments are merely called ``LaTeX comments'' in
+% this document). 
+% 
+%
+% \subsection{Behaviour in the class Beamer}
+%
+% \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).}
+%
+%
+% \bigskip
+% When the package \pkg{piton} is used within the class
+% \cls{beamer}\footnote{The extension \pkg{piton} detects the class \cls{beamer}
+% but, if needed, it's also possible to activate that mechanism with the key
+% |beamer| provided by \pkg{piton} at load-time: |\textbackslash
+% usepackage[beamer]\{piton\}|}, the behaviour of \pkg{piton} is slightly
+% modified, as described now.
+%
+% \subsubsection{\{Piton\} et \textbackslash PitonInputFile are
+% ``overlay-aware''}
+%
+% When \pkg{piton} is used in the class \cls{beamer}, the environment |{Piton}|
+% and the command |\PitonInputFile| accept the optional argument |<...>| of
+% Beamer for the overlays which are involved.
+%
+% For example, it's possible to write:
+%
+% \begin{Verbatim}
+% \begin{Piton}~emphase#<2-5>@
+% ...
+% \end{Piton}
+% \end{Verbatim}
+%
+% and 
+%
+% \begin{Verbatim}
+% \PitonInputFile~emphase#<2-5>@{my_file.py}
+% \end{Verbatim}
+% 
+% \subsubsection{Commands of Beamer allowed in \{Piton\} and \textbackslash PitonInputFile}
+%
+% When \pkg{piton} is used in the class \cls{beamer} , the following commands of
+% \cls{beamer} (classified upon their number of arguments) are automatically
+% detected in the environments |{Piton}| (and in the listings processed by
+% |\PitonInputFile|):
+% \begin{itemize}
+% \item no mandatory argument : |\pause|\footnote{One should remark that it's
+% also  possible to use the command \texttt{\textbackslash pause} in a ``LaTeX
+% comment'', that is to say by writing \texttt{\#> \textbackslash pause}. By
+% this way, if the Python code is copied, it's still executable by Python}.  ;
+% \item one mandatory argument : |\action|, |\alert|, |\invisible|, |\only|, |\uncover| and |\visible| ;
+% \item two mandatory arguments : |\alt| ; 
+% \item three mandatory arguments  : |\temporal|.
+% \end{itemize}
+
+% \medskip
+% In the mandatory arguments of these commands, the braces must be balanced.
+% However, the braces included in short strings\footnote{The short strings of
+% Python are the strings delimited by characters \texttt{'} or the characters
+% \texttt{"} and not \texttt{'''} nor \texttt{"""}. In Python, the short strings
+% can't extend on several lines.} of Python are not considered. 
+%
+% \medskip
+% Regarding the fonctions |\alt| and |\temporal| there should be no carriage
+% returns in the mandatory arguments of these functions.
+%
+% \medskip
+% Here is a complete example of file:
+%
+% \begin{Verbatim}[formatcom = \small\color{gray}]
+% \documentclass{beamer}
+% \usepackage{piton}
+% \begin{document}
+% \begin{frame}[fragile]
+% \begin{Piton}
+% def string_of_list(l):
+%     """Convert a list of numbers in string"""
+% ~emphase#    \only<2->{s = "{" + str(l[0])}@
+% ~emphase#    \only<3->{for x in l[1:]: s = s + "," + str(x)}@
+% ~emphase#    \only<4->{s = s + "}"}@
+%     return s
+% \end{Piton}
+% \end{frame}
+% \end{document}
+% \end{Verbatim}
+%
+% In the previous example, the braces in the Python strings |"{"| and |"}"| are
+% correctly interpreted (without any escape character).
+% 
+% 
+%
+%
+% \bigskip
+% \subsubsection{Environments of Beamer allowed in \{Piton\} and \textbackslash PitonInputFile}
+%
+% When \pkg{piton} is used in the class \pkg{beamer}, the following environments
+% of Beamer are directly detected in the environments |{Piton}| (and in the
+% listings processed by |\PitonInputFile|): |{actionenv}|, |{alertenv}|,
+% |{invisibleenv}|, |{onlyenv}|, |{uncoverenv}| and |{visibleenv}|.
+%
+% However, there is a restriction: these environments must contain only \emph{whole
+% lines of Python code} in their body.
+%
+%\medskip
+% Here is an example:
+%
+% \begin{Verbatim}[formatcom = \small\color{gray}]
+% \documentclass{beamer}
+% \usepackage{piton}
+% \begin{document}
+% \begin{frame}[fragile]
+% \begin{Piton}
+% def square(x):
+%     """Compure the square of its argument"""
+%     ~emphase#\begin{uncoverenv}<2>@
+%     return x*x
+%     ~emphase#\end{uncoverenv}@
+% \end{Piton}
+% \end{frame}
+% \end{document}
+% \end{Verbatim}
+%
+%
+% \vspace{1cm}
+% \textbf{Remark concerning the command \textbackslash alert and the environment
+% \{alertenv\} of Beamer}\par\nobreak
+%
+% \smallskip
+% Beamer provides an easy way to change the color used by the environment
+% |{alertenv}| (and by the command |\alert| which relies upon it) to highlight
+% its argument. Here is an example:
+%
+% \begin{Verbatim}
+% \setbeamercolor{~emphase#alerted text@}{fg=blue} 
+% \end{Verbatim}
+%
+% However, when used inside an environment |{Piton}|, such tuning will probably
+% not be the best choice because \pkg{piton} will, by design, change (most of
+% the time) the color the different elements of text. One may prefer an environment
+% |{alertenv}| that will change the background color for the elements to be
+% hightlighted. 
+%
+% \smallskip
+% Here is a code that will do that job and add a yellow background. That code
+% uses the command |\@highLight| of \pkg{lua-ul} (that extension requires also
+% the package \pkg{luacolor}).
+%
+% \begingroup
+% \fvset{commandchars=\~\#\+,formatcom=\color{gray}}
+% \begin{Verbatim}
+% \setbeamercolor{alerted text}{bg=yellow!50}
+% \makeatletter
+% \AddToHook{env/Piton/begin}
+%   {\renewenvironment<>{alertenv}{\only~#1{~emphase#\@highLight+[alerted text.bg]}}{}}
+% \makeatother
+% \end{Verbatim}
+% \endgroup
+%
+% That code redefines locally the environment |{alertenv}| within the
+% environments |{Piton}| (we recall that the command |\alert| relies upon that
+% environment |{alertenv}|).
+%
+% \subsection{Page breaks and line breaks}
+%
+% \label{breakable}
+%
+% \subsubsection{Page breaks}
+%
+% By default, the listings produced by the environment |{Piton}| and the command
+% |\PitonInputFile| are not breakable.
+%
+% However, the command |\PitonOptions| provides the key |splittable| to allow such
+% breaks.
+%
+% \begin{itemize}
+% \item If the key |splittable| is used without any value, the listings are
+% breakable everywhere.
+% \item If the key |splittable| is used with a numeric value~$n$ (which must be
+% a non-negative integer number), the listings are breakable but no break will
+% occur within the first $n$ lines and within the last $n$ lines. Therefore,
+% |splittable=1| is equivalent to |splittable|.
+% \end{itemize}
+%
+% \medskip
+% Even with a background color (set by the key |background-color|), the pages
+% breaks are allowed, as soon as the key |splittable| is in force.\footnote{With
+% the key |splittable|, the environments \texttt{\{Piton\}} are breakable, even
+% within a (breakable) environment of \pkg{tcolorbox}. Remind that an
+% environment of \pkg{tcolorbox} included in another environment of
+% \pkg{tcolorbox} is \emph{not} breakable, even when both environments use the
+% key |breakable| of \pkg{tcolorbox}.}
+% 
+% \subsubsection{Line breaks}
+% 
+% \label{line-breaks}
+% 
+% By default, the elements produced by \pkg{piton} can't be broken by an end on
+% line. However, there are keys to allow such breaks (the possible breaking
+% points are the spaces, even the spaces in the Python strings).
+% \begin{itemize}
+% \item With the key |break-lines-in-piton|, the line breaks are allowed in the
+% command |\piton{...}| (but not in the command \verb+\piton|...|+, that is to say
+% the command |\piton| in verbatim mode). 
+% \item With the key |break-lines-in-Piton|, the line breaks are allowed in the
+% environment |{Piton}| (hence the capital letter |P| in the name) and in the
+% listings produced by |\PitonInputFile|.
+% \item The key |break-lines| is a conjonction of the two previous keys.
+% \end{itemize}
+% 
+% \bigskip 
+% The package \pkg{piton} provides also several keys to control the appearance
+% on the line breaks allowed by |break-lines-in-Piton|.
+%
+% \begin{itemize}
+% \item With the key |indent-broken-lines|, the indentation of a broken line is
+% respected at carriage return.
+%
+% \item The key |end-of-broken-line| corresponds to the symbol placed at the end
+% of a broken line. The initial value is: |\hspace*{0.5em}\textbackslash|.
+%
+% \item The key |continuation-symbol| corresponds to the symbol placed at each
+% carriage return. The initial value is: |+\;|.
+%
+% \item The key |continuation-symbol-on-indentation| coresponds to the symbol
+% placed at each carriage return, on the position of the indentation (only when
+% the key |indent-broken-line| is in force). The initial value is:
+% |$\hookrightarrow\;$|.
+% \end{itemize}
+%
+%
+% \bigskip
+% The following code has been composed in a standard LaTeX |{minipage}| of width
+% 12~cm with the following tuning:
+%
+% \begin{Verbatim}
+% \PitonOptions{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}
+% \begin{Piton}
+% def dict_of_list(l):
+%     """Converts a list of subrs and descriptions of glyphs in a dictionary"""
+%     our_dict = {}
+%     for list_letter in l:
+%         if (list_letter[0][0:3] == 'dup'): # if it's a subr
+%             name = list_letter[0][4:-3]
+%             print("We treat the subr of number " + name)
+%         else:
+%             name = list_letter[0][1:-3] # if it's a glyph
+%             print("We treat the glyph of number " + name)
+%         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}
+% 
+% \label{footnote}
+% If you want to put footnotes in an environment |{Piton}| or
+% (or, more unlikely, in a listing produced by |\PitonInputFile|), you can use a
+% pair |\footnotemark|--|\footnotetext|. 
+%
+% \smallskip
+% However, it's also possible to extract the footnotes with the help of the
+% package \pkg{footnote} or the package \pkg{footnotehyper}.
+%
+% \smallskip
+% If \pkg{piton} is loaded with the option |footnote| (with
+% |\usepackage[footnote]{piton}| or with |\PassOptionsToPackage|), the
+% package \pkg{footnote} is loaded (if it is not yet loaded) and it is used to
+% extract the footnotes.
+%
+% \smallskip
+% If \pkg{piton} is loaded with the option |footnotehyper|, the package
+% \pkg{footnotehyper} is loaded (if it is not yet loaded) ant it is used to
+% extract footnotes.
+%
+% \smallskip
+% Caution: The packages \pkg{footnote} and \pkg{footnotehyper} are incompatible.
+% The package \pkg{footnotehyper} is the successor of the package \pkg{footnote}
+% and should be used preferently. The package \pkg{footnote} has some drawbacks,
+% in particular: it must be loaded after the package \pkg{xcolor} and it is not
+% perfectly compatible with \pkg{hyperref}.
+%
+% \medskip 
+% In this document, the package \pkg{piton} has been loaded with the
+% option |footnotehyper|. For examples of notes, cf. \ref{notes-examples},
+% p.~\pageref{notes-examples}.
+%
+% \subsection{Tabulations}
+%
+% \smallskip 
+% Even though it's recommended to indent the Python listings with spaces (see
+% PEP~8), \pkg{piton} accepts the characters of tabulation (that is to say the
+% characters U+0009) at the beginning of the lines. Each character U+0009 is
+% replaced by $n$~spaces. The initial value of $n$ is $4$ but it's possible to
+% change it with the key |tab-size| of |\PitonOptions|.
+%
+% \smallskip
+% There exists also a key |tabs-auto-gobble| which computes the minimal value
+% $n$ of the number of consecutive characters U+0009 beginning each (non empty)
+% line of the environment |{Piton}| and applies |gobble| with that value of~$n$
+% (before replacement of the tabulations by spaces, of course). Hence, that key
+% is similar to the key |auto-gobble| but acts on U+0009 instead of U+0020
+% (spaces).
+%
+% \section{Examples}
+%
+% \subsection{Line numbering}
+%
+% \label{example-numbering}
+%
+% We remind that it's possible to have an automatic numbering of the lines in
+% the Python listings by using the key |line-numbers| or the key |all-line-numbers|.
+%
+% By default, the numbers of the lines are composed by \pkg{piton} in an
+% overlapping position on the left (by using internally the command |\llap| of LaTeX).
+%
+% In order to avoid that overlapping, it's possible to use the option |left-margin=auto|
+% which will insert automatically a margin adapted to the numbers of lines that
+% will be written (that margin is larger when the numbers are greater than~10).
+%
+%
+% \begingroup
+% \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
+% \begin{Verbatim}
+% ~emphase&\PitonOptions{background-color=gray!10, left-margin = auto, line-numbers}@
+% \begin{Piton}
+% def arctan(x,n=10):
+%     if x < 0:
+%         return -arctan(-x)        #> (appel récursif)
+%     elif x > 1: 
+%         return pi/2 - arctan(1/x) #> (autre appel récursif) 
+%     else: 
+%         return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
+% \end{Piton}
+% \end{Verbatim}
+% \endgroup
+%
+%
+%
+% \begingroup
+% \PitonOptions{background-color=gray!10,left-margin = auto, line-numbers}
+% \begin{Piton}
+% def arctan(x,n=10):
+%     if x < 0:
+%         return -arctan(-x)        #> (appel récursif)
+%     elif x > 1: 
+%         return pi/2 - arctan(1/x) #> (autre appel récursif) 
+%     else: 
+%         return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
+% \end{Piton}
+% \endgroup
+%
+%
+%
+% \bigskip
+% \subsection{Formatting of the LaTeX comments}
+%
+% \label{example-comments}
+%
+% It's possible to modify the style |Comment.LaTeX| (with |\SetPitonStyle|) in
+% order to display the LaTeX comments (which begin with |#>|) aligned on the
+% right margin.
+%
+%
+% \begingroup
+% \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
+% \begin{Verbatim}
+% \PitonOptions{background-color=gray!10}
+% ~emphase&\SetPitonStyle{Comment.LaTeX = \hfill \normalfont\color{gray}}@
+% \begin{Piton}
+% def arctan(x,n=10):
+%     if x < 0:
+%         return -arctan(-x)        #> appel récursif
+%     elif x > 1: 
+%         return pi/2 - arctan(1/x) #> autre appel récursif 
+%     else: 
+%         return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
+% \end{Piton}
+% \end{Verbatim}
+% \endgroup
+%
+% \begingroup
+% \PitonOptions{background-color=gray!10}
+% \SetPitonStyle{Comment.LaTeX = \hfill \normalfont\color{gray}}
+% \begin{Piton}
+% def arctan(x,n=10):
+%     if x < 0:
+%         return -arctan(-x)        #> appel récursif
+%     elif x > 1: 
+%         return pi/2 - arctan(1/x) #> autre appel récursif 
+%     else: 
+%         return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
+% \end{Piton}
+% \endgroup
+%
+%
+% \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.
+%
+%
+% \begingroup
+% \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
+% \begin{Verbatim}
+% \PitonOptions{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:
+%         return -arctan(-x)       #> appel récursif
+%     elif x > 1: 
+%         return pi/2 - arctan(1/x) #> autre appel récursif 
+%     else: 
+%         s = 0
+%         for k in range(n):
+%              s += (-1)**k/(2*k+1)*x**(2*k+1)
+%         return s 
+% \end{Piton}
+% ~emphase&\end{minipage}@
+% \end{Verbatim}
+% \endgroup
+%
+%
+%
+% \begingroup
+% \PitonOptions{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:
+%         return -arctan(-x)       #> appel récursif
+%     elif x > 1: 
+%         return pi/2 - arctan(1/x) #> autre appel récursif 
+%     else: 
+%         s = 0
+%         for k in range(n):
+%              s += (-1)**k/(2*k+1)*x**(2*k+1)
+%         return s 
+% \end{Piton}
+% \end{minipage}
+% \endgroup
+%
+%
+% \bigskip
+% \subsection{Notes in the listings}
+%
+% \label{notes-examples}
+% 
+% In order to be able to extract the notes (which are typeset with the command
+% |\footnote|), the extension \pkg{piton} must be loaded with the key |footnote|
+% or the key |footenotehyper| as explained in the section \ref{footnote}
+% p.~\pageref{footnote}. In this document, the extension \pkg{piton} has been
+% loaded with the key |footnotehyper|.
+%
+% Of course, in an environment |{Piton}|, a command |\footnote| may appear only
+% within a LaTeX comment (which begins with |#>|). It's possible to have comments
+% which contain only that command |\footnote|. That's the case in the following example.
+%
+%
+%
+% \begingroup
+% \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
+% \begin{Verbatim}
+% \PitonOptions{background-color=gray!10}
+% \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{Verbatim}
+% \endgroup
+%
+% \begingroup
+% \PitonOptions{background-color=gray!10}
+% \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}
+% \endgroup
+%
+%
+% \vspace{1cm}
+%
+% If an environment |{Piton}| is used in an environment |{minipage}| of LaTeX,
+% the notes are composed, of course, at the foot of the environment
+% |{minipage}|. Recall that such |{minipage}| can't be broken by a page break.
+%
+%
+% \begingroup
+% \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
+% \begin{Verbatim}
+% \PitonOptions{background-color=gray!10}
+% \emphase\begin{minipage}{\linewidth}
+% \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}
+% \end{Verbatim}
+% \endgroup
+%
+% \begingroup
+% \PitonOptions{background-color=gray!10}
+% \begin{minipage}{\linewidth}
+% \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}
+% \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}
+%
+% The graphical styles have been presented in the section \ref{styles},
+% p.~\pageref{styles}.
+%
+% \smallskip
+% We present now an example of tuning of these styles adapted to the documents
+% in black and white. We use the font \emph{DejaVu Sans Mono}\footnote{See:
+% \url{https://dejavu-fonts.github.io}} specified by the command |\setmonofont| of 
+% \pkg{fontspec}. 
+%
+% That tuning uses the command |\highLight| of \pkg{lua-ul} (that package
+% requires itself the package \pkg{luacolor}).
+%
+% \begin{Verbatim}
+% \setmonofont[Scale=0.85]{DejaVu Sans Mono}
+%
+% \SetPitonStyle
+%   {
+%     Number = ,
+%     String = \itshape , 
+%     String.Doc = \color{gray} \slshape ,
+%     Operator = , 
+%     Operator.Word = \bfseries ,
+%     Name.Builtin = ,
+%     Name.Function = \bfseries \highLight[gray!20] ,
+%     Comment = \color{gray} ,
+%     Comment.LaTeX = \normalfont \color{gray},
+%     Keyword = \bfseries ,
+%     Name.Namespace = ,
+%     Name.Class = , 
+%     Name.Type = ,
+%     InitialValues = \color{gray}
+%   }
+% \end{Verbatim}
+%
+%
+% \begingroup
+%
+% \setmonofont[Scale=0.85]{DejaVu Sans Mono}
+%
+%  \PitonOptions{splittable}
+%
+% \SetPitonStyle
+%   {
+%     Number = ,
+%     String = \itshape , 
+%     String.Doc = \color{gray} \slshape ,
+%     Operator.Word = \bfseries ,
+%     Operator = , 
+%     Name.Builtin = ,
+%     Name.Function = \bfseries \highLight[gray!20] ,
+%     Comment = \color{gray} ,
+%     Comment.LaTeX = \normalfont \color{gray} ,
+%     Keyword = \bfseries ,
+%     Name.Namespace = ,
+%     Name.Class = , 
+%     Name.Type = ,
+%     InitialValues = \color{gray}
+%   }
+%
+%
+% \bigskip
+%
+% \begin{Piton}
+% from math import pi
+%
+% def arctan(x,n=10):
+%     """Compute the mathematical value of arctan(x)
+%                                               
+%     n is the number of terms in the sum
+%     """
+%     if x < 0:
+%         return -arctan(-x) # appel récursif
+%     elif x > 1: 
+%         return pi/2 - arctan(1/x) 
+%         #> (we have used that $\arctan(x)+\arctan(1/x)=\pi/2$ for $x>0$)
+%     else: 
+%         s = 0
+%         for k in range(n):
+%             s += (-1)**k/(2*k+1)*x**(2*k+1)
+%         return s 
+% \end{Piton}
+%
+% \endgroup
+% 
+% \subsection{Use with pyluatex}
+%
+% The package \pkg{pyluatex} is an extension which allows the execution of some
+% Python code from |lualatex| (provided that Python is installed on the machine
+% and that the compilation is done with |lualatex| and |--shell-escape|).
+%
+% Here is, for example, an environment |{PitonExecute}| which formats a Python
+% listing (with \pkg{piton}) but display also the output of the execution of the
+% code with Python (for technical reasons, the |!| is mandatory in the signature
+% of the environment).
+%
+%
+% \begin{Verbatim}
+% \ExplSyntaxOn
+% \NewDocumentEnvironment { ~emphase#PitonExecute@ } { ! O { } } % the ! is mandatory 
+%   { 
+%     \PyLTVerbatimEnv
+%     \begin{pythonq} 
+%   }
+%   {
+%     \end{pythonq}
+%     \directlua
+%       {
+%         tex.print("\\PitonOptions{~#1}")
+%         tex.print("\\begin{Piton}")
+%         tex.print(pyluatex.get_last_code())
+%         tex.print("\\end{Piton}")
+%         tex.print("") 
+%       }
+%     \begin{center}
+%       \directlua{tex.print(pyluatex.get_last_output())}
+%     \end{center}
+%   }
+% \ExplSyntaxOff
+% \end{Verbatim}
+%
+% \ExplSyntaxOn
+% \NewDocumentEnvironment { PitonExecute } { ! O { } } 
+%   { 
+%     \PyLTVerbatimEnv
+%     \begin{pythonq} 
+%   }
+%   {
+%     \end{pythonq}
+%     \directlua
+%       {
+%         tex.print("\\PitonOptions{#1}")
+%         tex.print("\\begin{Piton}")
+%         tex.print(pyluatex.get_last_code())
+%         tex.print("\\end{Piton}")
+%         tex.print("") 
+%       }
+%     \begin{center}
+%       \directlua{tex.print(pyluatex.get_last_output())}
+%     \end{center}
+%   }
+% \ExplSyntaxOff
+%
+% This environment |{PitonExecute}| takes in as optional argument (between
+% square brackets) the options of the command |\PitonOptions|.
+%
+%
+% \bigskip
+% \clearpage
+%
+% \section{Implementation}
+%
+% \subsection{Introduction}
+% 
+% The main job of the package \pkg{piton} is to take in as input a Python
+% listing and to send back to LaTeX as output that code \emph{with interlaced LaTeX
+% instructions of formatting}.
+%
+% In fact, all that job is done by a \textsc{lpeg} called |python|. That
+% \textsc{lpeg}, when matched against the string of a Python listing,
+% returns as capture a Lua table containing data to send to LaTeX. 
+% The only thing to do after will be to apply |tex.tprint| to each element of
+% that table.\footnote{Recall that |tex.tprint| takes in as argument a Lua table whose
+% first component is a ``catcode table'' and the second element a string. The
+% string will be sent to LaTeX with the regime of catcodes specified by the
+% catcode table. If no catcode table is provided, the standard catcodes of LaTeX
+% will be used.}
+% 
+% \bigskip
+% Consider, for example, the following Python code:
+%
+% \begin{Piton}
+% def parity(x):
+%     return x%2
+% \end{Piton}
+%
+% The capture returned by the \pkg{lpeg} |python| against that code is the
+% Lua table containing the following elements :
+%
+% \bigskip
+% \begin{minipage}{\linewidth}
+% \color{gray}
+% 
+% |{ "\\__piton_begin_line:" }|\footnote{Each line of the Python listings will
+% be encapsulated in a pair: \texttt{\textbackslash_@@_begin_line:} --
+% \texttt{\textbackslash@@_end_line:}. The token
+% \texttt{\textbackslash@@_end_line:} must be explicit because it will be used as
+% marker in order to delimit the argument of the command \texttt{\textbackslash
+% @@\_begin\_line:}. Both tokens \texttt{\textbackslash_@@_begin_line:} and
+% \texttt{\textbackslash@@_end_line:} will be nullified in the command
+% \texttt{\textbackslash piton} (since there can't be lines breaks in the
+% argument of a command \texttt{\textbackslash piton}).}  
+% 
+% \texttt{\{ "\{\textbackslash PitonStyle\{Keyword\}\{" \}}\footnote{The
+% lexical elements of Python for which we have a \pkg{piton} style will be
+% formatted via the use of the command \texttt{\textbackslash PitonStyle}.
+% Such an element is typeset in LaTeX via the syntax \texttt{\{\textbackslash
+% PitonStyle\{\textsl{style}\}\{...\}\}} because the instructions inside an \texttt{\textbackslash
+% PitonStyle} may be both semi-global declarations like
+% \texttt{\textbackslash bfseries} and commands with one argument like
+% \texttt{\textbackslash fbox}.}
+%
+% \texttt{\{
+% luatexbase.catcodetables.CatcodeTableOther\footnote{\texttt{luatexbase.catcodetables.CatcodeTableOther} is a mere number which corresponds to the ``catcode table'' whose all characters have the catcode ``other'' (which means that they will be typeset by LaTeX verbatim).}, "def" \} }
+%
+% |{ "}}" }|
+%
+% |{ luatexbase.catcodetables.CatcodeTableOther, " " }|
+%
+% |{ "{\PitonStyle{Name.Function}{" }|
+%
+% |{ luatexbase.catcodetables.CatcodeTableOther, "parity" }|
+%
+% |{ "}}" }|
+% 
+% |{ luatexbase.catcodetables.CatcodeTableOther, "(" }|
+%
+% |{ luatexbase.catcodetables.CatcodeTableOther, "x" }|
+%
+% |{ luatexbase.catcodetables.CatcodeTableOther, ")" }|
+%
+% |{ luatexbase.catcodetables.CatcodeTableOther, ":" }|
+% 
+% |{ "\\__piton_end_line: \\__piton_newline: \\__piton_begin_line:" }|
+%
+% |{ luatexbase.catcodetables.CatcodeTableOther, "    " }|
+%
+% |{ "{\PitonStyle{Keyword}{" }|
+%
+% |{ luatexbase.catcodetables.CatcodeTableOther, "return" }|
+%
+% |{ "}}" }|
+%
+% |{ luatexbase.catcodetables.CatcodeTableOther, " " }|
+%
+% |{ luatexbase.catcodetables.CatcodeTableOther, "x" }|
+%
+% |{ "{\PitonStyle{Operator}{" }|
+%
+% |{ luatexbase.catcodetables.CatcodeTableOther, "&" }|
+%
+% |{ "}}" }|
+%
+% |{ "{\PitonStyle{Number}{" }|
+%
+% |{ luatexbase.catcodetables.CatcodeTableOther, "2" }|
+%
+% |{ "}}" }|
+% 
+% |{ "\\__piton_end_line:" }|
+% 
+% \end{minipage}
+%
+% \bigskip
+% We give now the LaTeX code which is sent back by Lua to TeX (we have written
+% on several lines for legibility but no character |\r| will be sent to LaTeX). The
+% characters which are greyed-out are sent to LaTeX with the catcode ``other''
+% (=12). All the others characters are sent with the regime of catcodes of L3
+% (as set by |\ExplSyntaxOn|)
+%
+% 
+% \begingroup
+% \def\gbox#1{\colorbox{gray!20}{\strut #1}}
+% \setlength{\fboxsep}{1pt}
+% 
+% \begin{Verbatim*}[formatcom = \color{black}]
+% \__piton_begin_line:{\PitonStyle{Keyword}{~gbox#def@}}
+% ~gbox# @{\PitonStyle{Name.Function}{~gbox#parity@}}~gbox#(x):@\__piton_end_line:\__piton_newline:
+% \__piton_begin_line:~gbox#    @{\PitonStyle{Keyword}{~gbox#return@}}
+% ~gbox# x@{\PitonStyle{Operator}{~gbox#%@}}{\PitonStyle{Number}{~gbox#2@}}\__piton_end_line:
+% \end{Verbatim*}
+% \endgroup
+%
+%
+% 
+%
+% \subsection{The L3 part of the implementation}
+%
+% \subsubsection{Declaration of the package}
+%    \begin{macrocode}
+\NeedsTeXFormat{LaTeX2e}
+\RequirePackage{l3keys2e}
+\ProvidesExplPackage
+  {piton}
+  {\myfiledate}
+  {\myfileversion}
+  {Highlight Python codes with LPEG on LuaLaTeX}
+%    \end{macrocode}
+%
+% \bigskip
+%    \begin{macrocode}
+\msg_new:nnn { piton } { LuaLaTeX~mandatory }
+  { 
+    LuaLaTeX~is~mandatory.\\
+    The~package~'piton'~requires~the~engine~LuaLaTeX.\\
+    \str_if_eq:VnT \c_sys_jobname_str { output }
+      { If~you~use~Overleaf,~you~can~switch~to~LuaLaTeX~in~the~"Menu". \\}
+    If~you~go~on,~the~package~'piton'~won't~be~loaded.
+  }
+\sys_if_engine_luatex:F { \msg_critical:nn { piton } { LuaLaTeX~mandatory } }
+%    \end{macrocode}
+% 
+% \bigskip
+%    \begin{macrocode}
+\RequirePackage { luatexbase } 
+%    \end{macrocode}
+%
+% \bigskip
+% The boolean |\c_@@_footnotehyper_bool| will indicate if the option
+% |footnotehyper| is used.
+%    \begin{macrocode}
+\bool_new:N \c_@@_footnotehyper_bool
+%    \end{macrocode}
+%
+% \medskip
+% The boolean |\c_@@_footnote_bool| will indicate if the option |footnote| is
+% used, but quicky, it will also be set to |true| if the option |footnotehyper|
+% is used.
+%    \begin{macrocode}
+\bool_new:N \c_@@_footnote_bool
+%    \end{macrocode}
+%
+% \medskip
+% The following boolean corresponds to the key |math-comments| (only at load-time).
+%    \begin{macrocode}
+\bool_new:N \c_@@_math_comments_bool
+%    \end{macrocode}
+%
+% \medskip
+% The following boolean corresponds to the key |beamer|. 
+%    \begin{macrocode}
+\bool_new:N \c_@@_beamer_bool
+%    \end{macrocode}
+% 
+% \bigskip
+% We define a set of keys for the options at load-time.
+%    \begin{macrocode}
+\keys_define:nn { piton / package }
+  { 
+    footnote .bool_set:N = \c_@@_footnote_bool ,
+    footnotehyper .bool_set:N = \c_@@_footnotehyper_bool ,
+    escape-inside .tl_set:N = \c_@@_escape_inside_tl ,
+    escape-inside .initial:n = , 
+    comment-latex .code:n = { \lua_now:n { comment_latex = "#1" } } ,   
+    comment-latex .value_required:n = true ,
+    math-comments .bool_set:N = \c_@@_math_comments_bool ,
+    math-comments .default:n  = true ,
+    beamer        .bool_set:N = \c_@@_beamer_bool ,
+    beamer        .default:n = true , 
+    unknown .code:n = \msg_error:nn { piton } { unknown~key~for~package }
+  }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\msg_new:nnn { piton } { unknown~key~for~package }
+  {
+    Unknown~key.\\
+    You~have~used~the~key~'\l_keys_key_str'~but~the~only~keys~available~here~
+    are~'beamer',~'comment-latex',~'escape-inside',~'footnote',~'footnotehyper'~and~ 
+    'math-comments'.~Other~keys~are~available~in~\token_to_str:N \PitonOptions.\\
+    That~key~will~be~ignored.
+  }
+%    \end{macrocode}
+%
+% \bigskip
+% We process the options provided by the user at load-time.
+%    \begin{macrocode}
+\ProcessKeysOptions { piton / package }
+%    \end{macrocode}
+%
+% \bigskip
+%    \begin{macrocode}
+\begingroup
+\cs_new_protected:Npn \@@_set_escape_char:nn #1 #2 
+  {
+    \lua_now:n { piton_begin_escape = "#1" }
+    \lua_now:n { piton_end_escape = "#2" }
+  }
+\cs_generate_variant:Nn \@@_set_escape_char:nn { x x }
+\@@_set_escape_char:xx 
+  { \tl_head:V \c_@@_escape_inside_tl }
+  { \tl_tail:V \c_@@_escape_inside_tl }
+\endgroup
+%    \end{macrocode}
+% 
+% \bigskip
+%    \begin{macrocode}
+\@ifclassloaded { beamer } { \bool_set_true:N \c_@@_beamer_bool } { }
+\bool_if:NT \c_@@_beamer_bool { \lua_now:n { piton_beamer = true } }
+%    \end{macrocode}
+% 
+% \bigskip
+%    \begin{macrocode}
+\hook_gput_code:nnn { begindocument } { . }
+  {
+    \@ifpackageloaded { xcolor }
+      { }
+      { \msg_fatal:nn { piton } { xcolor~not~loaded } }
+  }
+%    \end{macrocode}
+%
+%    \begin{macrocode}     
+\msg_new:nnn { piton } { xcolor~not~loaded }
+  {
+    xcolor~not~loaded \\
+    The~package~'xcolor'~is~required~by~'piton'.\\
+    This~error~is~fatal.
+  }
+%    \end{macrocode}
+% 
+%
+%    \begin{macrocode}
+\msg_new:nnn { piton } { footnote~with~footnotehyper~package }
+  { 
+    Footnote~forbidden.\\
+    You~can't~use~the~option~'footnote'~because~the~package~
+    footnotehyper~has~already~been~loaded.~
+    If~you~want,~you~can~use~the~option~'footnotehyper'~and~the~footnotes~  
+    within~the~environments~of~piton~will~be~extracted~with~the~tools~
+    of~the~package~footnotehyper.\\
+    If~you~go~on,~the~package~footnote~won't~be~loaded.
+  }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\msg_new:nnn { piton } { footnotehyper~with~footnote~package }
+  { 
+    You~can't~use~the~option~'footnotehyper'~because~the~package~
+    footnote~has~already~been~loaded.~
+    If~you~want,~you~can~use~the~option~'footnote'~and~the~footnotes~  
+    within~the~environments~of~piton~will~be~extracted~with~the~tools~
+    of~the~package~footnote.\\ 
+    If~you~go~on,~the~package~footnotehyper~won't~be~loaded.
+  }
+%    \end{macrocode}
+%
+% \medskip
+%    \begin{macrocode}
+\bool_if:NT \c_@@_footnote_bool 
+  { 
+%    \end{macrocode}
+% The class \cls{beamer} has its own system to extract footnotes and that's why
+% we have nothing to do if \cls{beamer} is used. 
+%    \begin{macrocode}
+    \@ifclassloaded { beamer }
+      { \bool_set_false:N \c_@@_footnote_bool }
+      { 
+        \@ifpackageloaded { footnotehyper }
+          { \@@_error:n { footnote~with~footnotehyper~package } }
+          { \usepackage { footnote } }
+      }
+  }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\bool_if:NT \c_@@_footnotehyper_bool 
+  { 
+%    \end{macrocode}
+% The class \cls{beamer} has its own system to extract footnotes and that's why
+% we have nothing to do if \cls{beamer} is used. 
+%    \begin{macrocode}
+    \@ifclassloaded { beamer }
+      { \bool_set_false:N \c_@@_footnote_bool }
+      { 
+        \@ifpackageloaded { footnote }
+          { \@@_error:n { footnotehyper~with~footnote~package } }
+          { \usepackage { footnotehyper } }
+        \bool_set_true:N \c_@@_footnote_bool 
+      }
+  }
+%    \end{macrocode}
+% The flag |\c_@@_footnote_bool| is raised and so, we will only have to test
+% |\c_@@_footnote_bool| in order to know if we have to insert an environment
+% |{savenotes}|.
+% 
+% \bigskip
+% \subsubsection{Parameters and technical definitions}
+%
+% The following string will contain the name of the informatic language
+% considered (the initial value is |python|).
+%
+%    \begin{macrocode}
+\str_new:N \l_@@_language_str
+\str_set:Nn \l_@@_language_str { python }
+%    \end{macrocode}
+% 
+% We will compute (with Lua) the numbers of lines of the Python code and store
+% it in the following counter.
+%    \begin{macrocode}
+\int_new:N \l_@@_nb_lines_int
+%    \end{macrocode}
+% 
+% The same for the number of non-empty lines of the Python codes.
+%    \begin{macrocode}
+\int_new:N \l_@@_nb_non_empty_lines_int
+%    \end{macrocode}
+% 
+% The following counter will be used to count the lines during the composition.
+% It will count all the lines, empty or not empty. It won't be used to print the
+% numbers of the lines.
+%    \begin{macrocode}
+\int_new:N \g_@@_line_int
+%    \end{macrocode}
+% 
+% \medskip
+% The following token list will contains the (potential) informations to write
+% on the |aux| (to be used in the next compilation).
+%    \begin{macrocode}
+\tl_new:N \g_@@_aux_tl
+%    \end{macrocode}
+% 
+% \medskip
+% The following counter corresponds to the key |splittable| of |\PitonOptions|.
+% If the value of |\l_@@_splittable_int| is equal to $n$, then no line break can
+% occur within the first $n$~lines or the last $n$~lines of the listings.
+%    \begin{macrocode}
+\int_new:N \l_@@_splittable_int
+%    \end{macrocode}
+%
+% \medskip
+% An initial value of |splittable| equal to 100 is equivalent to say that the
+% environments |{Piton}| are unbreakable.
+%    \begin{macrocode}
+\int_set:Nn \l_@@_splittable_int { 100 }
+%    \end{macrocode}
+%
+% \medskip
+% The following string corresponds to the key |background-color| of |\PitonOptions|.
+%    \begin{macrocode}
+\clist_new:N \l_@@_bg_color_clist
+%    \end{macrocode}
+%
+% \medskip
+% The package \pkg{piton} will also detect the lines of code which correspond to
+% the user input in a Python console, that is to say the lines of code beginning
+% with |>>>| and |...|. It's possible, with the key |prompt-background-color|,
+% to require a background for these lines of code (and the other lines of code
+% will have the standard background color specified by |background-color|).
+%    \begin{macrocode}
+\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
+% |\PitonInputFile|, despite the name |\g_@@_env_int|).
+%    \begin{macrocode}
+\int_new:N \g_@@_env_int 
+%    \end{macrocode}
+%
+% \medskip
+% The following boolean corresponds to the key |show-spaces|.
+%    \begin{macrocode}
+\bool_new:N \l_@@_show_spaces_bool
+%    \end{macrocode}
+%
+% \medskip
+% The following booleans correspond to the keys |break-lines| and
+% |indent-broken-lines|.
+%    \begin{macrocode}
+\bool_new:N \l_@@_break_lines_in_Piton_bool
+\bool_new:N \l_@@_indent_broken_lines_bool
+%    \end{macrocode}
+%
+% \medskip
+% The following token list corresponds to the key |continuation-symbol|.
+%    \begin{macrocode}
+\tl_new:N \l_@@_continuation_symbol_tl
+\tl_set:Nn \l_@@_continuation_symbol_tl { + }
+%    \end{macrocode}
+%
+% \medskip
+%    \begin{macrocode}
+% The following token list corresponds to the key
+% |continuation-symbol-on-indentation|. The name has been shorten to |csoi|.
+\tl_new:N \l_@@_csoi_tl 
+\tl_set:Nn \l_@@_csoi_tl { $ \hookrightarrow \; $  }
+%    \end{macrocode}
+%
+% \medskip
+% The following token list corresponds to the key |end-of-broken-line|.
+%    \begin{macrocode}
+\tl_new:N \l_@@_end_of_broken_line_tl 
+\tl_set:Nn \l_@@_end_of_broken_line_tl { \hspace*{0.5em} \textbackslash }
+%    \end{macrocode}
+%
+% \medskip
+% The following boolean corresponds to the key |break-lines-in-piton|.
+%    \begin{macrocode}
+\bool_new:N \l_@@_break_lines_in_piton_bool
+%    \end{macrocode}
+% 
+% \medskip
+% The following boolean corresponds to the key |slim| of |\PitonOptions|.
+%    \begin{macrocode}
+\bool_new:N \l_@@_slim_bool
+%    \end{macrocode}
+%
+% \medskip
+% The following dimension corresponds to the key |left-margin| of |\PitonOptions|. 
+%    \begin{macrocode}
+\dim_new:N \l_@@_left_margin_dim
+%    \end{macrocode}
+%
+% \medskip
+% The following boolean will be set when the key |left-margin=auto|
+% is used.
+%    \begin{macrocode}
+\bool_new:N \l_@@_left_margin_auto_bool
+%    \end{macrocode}
+%
+% \medskip
+% The following dimension corresponds to the key |numbers-sep| of
+% |\PitonOptions|.
+%    \begin{macrocode}
+\dim_new:N \l_@@_numbers_sep_dim 
+\dim_set:Nn \l_@@_numbers_sep_dim { 0.7 em }
+%    \end{macrocode}
+% 
+% \medskip
+% The tabulators will be replaced by the content of the following token list.
+%    \begin{macrocode}
+\tl_new:N \l_@@_tab_tl
+%    \end{macrocode}
+%
+% \medskip
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_set_tab_tl:n #1
+  { 
+    \tl_clear:N \l_@@_tab_tl
+    \prg_replicate:nn { #1 } 
+      { \tl_put_right:Nn \l_@@_tab_tl { ~ } }
+  }
+\@@_set_tab_tl:n { 4 }
+%    \end{macrocode}
+% 
+% \medskip
+% The following integer corresponds to the key |gobble|.
+%    \begin{macrocode}
+\int_new:N \l_@@_gobble_int 
+%    \end{macrocode}
+%
+% \medskip
+%    \begin{macrocode}
+\tl_new:N \l_@@_space_tl
+\tl_set:Nn \l_@@_space_tl { ~ } 
+%    \end{macrocode}
+% 
+%
+% \medskip
+% At each line, the following counter will count the spaces at the beginning.
+%    \begin{macrocode}
+\int_new:N \g_@@_indentation_int
+%    \end{macrocode}
+% 
+% \medskip
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_an_indentation_space:
+  { \int_gincr:N \g_@@_indentation_int }
+%    \end{macrocode}
+%
+% \medskip
+% The following command |\@@_beamer_command:n| executes the argument
+% corresponding to its argument but also stores it in |\l_@@_beamer_command_str|.
+% That string is used only in the error message ``|cr~not~allowed|'' raised when
+% there is a carriage return in the mandatory argument of that command.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_beamer_command:n #1 
+  { 
+    \str_set:Nn \l_@@_beamer_command_str { #1 } 
+    \use:c { #1 } 
+  }
+%    \end{macrocode}
+% 
+% \bigskip
+% In the environment |{Piton}|, the command |\label| will be linked to the
+% following command.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_label:n #1
+  {
+    \bool_if:NTF \l_@@_line_numbers_bool
+      {
+        \@bsphack 
+        \protected@write \@auxout { }
+          { 
+            \string \newlabel { #1 } 
+            { 
+%    \end{macrocode}
+% Remember that the content of a line is typeset in a box \emph{before} the
+% composition of the potential number of line.
+%    \begin{macrocode}
+              { \int_eval:n { \g_@@_visual_line_int + 1 } } 
+              { \thepage } 
+            } 
+          } 
+        \@esphack
+     }
+     { \msg_error:nn { piton } { label~with~lines~numbers } }
+  }
+%    \end{macrocode}
+%
+% 
+% \bigskip
+% The following commands are a easy way to insert safely braces (|{| and |}|) in
+% the TeX flow.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_open_brace:
+  { \directlua { piton.open_brace() } }
+\cs_new_protected:Npn \@@_close_brace:
+  { \directlua { piton.close_brace() } }
+%    \end{macrocode}
+% 
+% \bigskip
+% The following token list will be evaluated at the beginning of
+% |\@@_begin_line:|... |\@@_end_line:| and cleared at the end. It will be used
+% by LPEG acting between the lines of the Python code in order to add
+% instructions to be executed at the beginning of the line.
+%    \begin{macrocode} 
+\tl_new:N \g_@@_begin_line_hook_tl
+%    \end{macrocode}
+%
+% \smallskip
+% For example, the LPEG |Prompt| will trigger the following command which will
+% insert an instruction in the hook |\g_@@_begin_line_hook| to specify that a
+% background must be inserted to the current line of code.
+%    \begin{macrocode}
+\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 } 
+      }
+  }
+%    \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}
+% 
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_replace_spaces:n #1 
+  {
+    \tl_set:Nn \l_tmpa_tl { #1 } 
+    \bool_if:NTF \l_@@_show_spaces_bool
+      { \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl } % U+2423
+      {
+%    \end{macrocode}
+% If the key |break-lines-in-Piton| is in force, we replace all the characters
+% U+0020 (that is to say the spaces) by |\@@_breakable_space:|. Remark that,
+% except the spaces inserted in the LaTeX comments (and maybe in the math
+% comments), all these spaces are of catcode ``other'' (=12) and are
+% unbreakable.
+%    \begin{macrocode}
+        \bool_if:NT \l_@@_break_lines_in_Piton_bool
+          { 
+            \regex_replace_all:nnN 
+              { \x20 } 
+              { \c { @@_breakable_space: } }
+              \l_tmpa_tl 
+          } 
+      }
+    \l_tmpa_tl 
+  }
+\cs_generate_variant:Nn \@@_replace_spaces:n { x } 
+%    \end{macrocode}
+% 
+% \bigskip
+% In the contents provided by Lua, each line of the Python code will be
+% surrounded by |\@@_begin_line:| and |\@@_end_line:|. |\@@_begin_line:| is a
+% LaTeX command that we will define now but |\@@_end_line:| is only a syntactic
+% marker that has no definition.
+%
+%    \begin{macrocode}
+\cs_set_protected:Npn \@@_begin_line: #1 \@@_end_line:
+  { 
+    \group_begin:
+    \g_@@_begin_line_hook_tl
+    \int_gzero:N \g_@@_indentation_int
+%    \end{macrocode}
+%
+% 
+% Be careful: there is curryfication in the following lines.
+%    \begin{macrocode}
+    \bool_if:NTF \l_@@_slim_bool
+      { \hcoffin_set:Nn \l_tmpa_coffin }
+      { 
+        \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 
+        \@@_replace_spaces:n { #1 }
+        \strut \hfil 
+      } 
+    \hbox_set:Nn \l_tmpa_box 
+      { 
+        \skip_horizontal:N \l_@@_left_margin_dim
+        \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
+              \@@_print_number:
+          }
+        \clist_if_empty:NF \l_@@_bg_color_clist 
+          { 
+            \dim_compare:nNnT \l_@@_left_margin_dim = \c_zero_dim 
+               { 
+                 \bool_if:NF \l_@@_left_margin_auto_bool
+                   { \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 
+          { 
+            \hbox:n
+              { 
+                \@@_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
+              } 
+            \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
+          }
+      }   
+    \vspace { - 2.5 pt }
+    \group_end:
+    \tl_gclear:N \g_@@_begin_line_hook_tl
+  }
+%    \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).
+%    \begin{macrocode}
+\cs_set_protected:Npn \@@_color:N #1 
+  {
+    \int_set:Nn \l_tmpa_int { \clist_count:N #1 }
+    \int_set:Nn \l_tmpb_int { \int_mod:nn \g_@@_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 }
+%    \end{macrocode}
+% By setting |\l_@@_width_on_aux_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 }
+      { \exp_args:NV \@@_color_i:n \l_tmpa_tl }
+  }
+%    \end{macrocode}
+%
+% The following command |\@@_color:n| will accept both the instruction
+% |\@@_color:n { red!15 }| and the instruction |\@@_color:n { [rgb]{0.9,0.9,0} }|.
+%    \begin{macrocode}
+\cs_set_protected:Npn \@@_color_i:n #1
+  {
+    \tl_if_head_eq_meaning:nNTF { #1 } [ 
+      { 
+        \tl_set:Nn \l_tmpa_tl { #1 }
+        \tl_set_rescan:Nno \l_tmpa_tl { } \l_tmpa_tl 
+        \exp_last_unbraced:NV \color \l_tmpa_tl
+      }
+      { \color { #1 } }
+  }
+\cs_generate_variant:Nn \@@_color:n { V }
+%    \end{macrocode}
+% 
+% \bigskip
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_newline: 
+  { 
+    \int_gincr:N \g_@@_line_int
+    \int_compare:nNnT \g_@@_line_int > { \l_@@_splittable_int - 1 }
+      {
+        \int_compare:nNnT 
+          { \l_@@_nb_lines_int - \g_@@_line_int } > \l_@@_splittable_int 
+          {
+            \egroup
+            \bool_if:NT \c_@@_footnote_bool { \end { savenotes } } 
+            \newline
+            \bool_if:NT \c_@@_footnote_bool { \begin { savenotes } } 
+            \vtop \bgroup
+          }
+     }
+  } 
+%    \end{macrocode}
+%
+% \bigskip
+%    \begin{macrocode}
+\cs_set_protected:Npn \@@_breakable_space:
+  { 
+    \discretionary 
+      { \hbox:n { \color { gray } \l_@@_end_of_broken_line_tl } } 
+      { 
+        \hbox_overlap_left:n 
+          { 
+            { 
+              \normalfont \footnotesize \color { gray } 
+              \l_@@_continuation_symbol_tl 
+            } 
+            \skip_horizontal:n { 0.3 em }  
+            \clist_if_empty:NF \l_@@_bg_color_clist 
+              { \skip_horizontal:n { 0.5 em } }
+          }  
+        \bool_if:NT \l_@@_indent_broken_lines_bool
+          { 
+            \hbox:n
+              { 
+                \prg_replicate:nn { \g_@@_indentation_int } { ~ } 
+                { \color { gray } \l_@@_csoi_tl }
+              } 
+          } 
+      } 
+      { \hbox { ~ } }
+  }
+%    \end{macrocode}
+% 
+% \bigskip
+% \subsubsection{PitonOptions}
+%
+% \medskip
+% The following parameters correspond to the keys |line-numbers| and
+% |all-line-numbers|.
+%    \begin{macrocode}
+\bool_new:N \l_@@_line_numbers_bool 
+\bool_new:N \l_@@_all_line_numbers_bool 
+%    \end{macrocode}
+% 
+% \medskip
+% The following flag corresponds to the key |resume|.
+%    \begin{macrocode}
+\bool_new:N \l_@@_resume_bool 
+%    \end{macrocode}
+% 
+% \bigskip
+% Be careful! The name of the following set of keys must be considered as
+% public! Hence, it should \emph{not} be changed.
+% 
+%    \begin{macrocode}
+\keys_define:nn { PitonOptions }
+  {
+    language         .str_set:N         = \l_@@_language_str ,
+    language         .value_required:n  = true ,
+    gobble           .int_set:N         = \l_@@_gobble_int , 
+    gobble           .value_required:n  = true ,
+    auto-gobble      .code:n            = \int_set:Nn \l_@@_gobble_int { -1 } , 
+    auto-gobble      .value_forbidden:n = true ,
+    env-gobble       .code:n            = \int_set:Nn \l_@@_gobble_int { -2 } , 
+    env-gobble       .value_forbidden:n = true ,
+    tabs-auto-gobble .code:n            = \int_set:Nn \l_@@_gobble_int { -3 } , 
+    tabs-auto-gobble .value_forbidden:n = true ,
+    line-numbers     .bool_set:N        = \l_@@_line_numbers_bool ,
+    line-numbers     .default:n         = true ,
+    all-line-numbers .code:n = 
+      \bool_set_true:N \l_@@_line_numbers_bool 
+      \bool_set_true:N \l_@@_all_line_numbers_bool ,
+    all-line-numbers .value_forbidden:n = true  ,
+    resume           .bool_set:N        = \l_@@_resume_bool ,
+    resume           .value_forbidden:n = true ,
+    splittable       .int_set:N         = \l_@@_splittable_int ,
+    splittable       .default:n         = 1 , 
+    background-color .clist_set:N       = \l_@@_bg_color_clist ,
+    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 ,
+    left-margin      .code:n =
+      \str_if_eq:nnTF { #1 } { auto }
+        { 
+          \dim_zero:N \l_@@_left_margin_dim 
+          \bool_set_true:N \l_@@_left_margin_auto_bool
+        }
+        { \dim_set:Nn \l_@@_left_margin_dim { #1 } } ,
+    left-margin      .value_required:n  = true ,
+    numbers-sep      .dim_set:N         = \l_@@_numbers_sep_dim ,
+    numbers-sep      .value_required:n  = true , 
+    tab-size         .code:n            = \@@_set_tab_tl:n { #1 } ,
+    tab-size         .value_required:n  = true , 
+    show-spaces      .bool_set:N        = \l_@@_show_spaces_bool , 
+    show-spaces      .default:n         = true , 
+    show-spaces-in-strings .code:n      = \tl_set:Nn \l_@@_space_tl { ␣ } , % U+2423
+    show-spaces-in-strings .value_forbidden:n = true ,
+    break-lines-in-Piton .bool_set:N    = \l_@@_break_lines_in_Piton_bool ,
+    break-lines-in-Piton .default:n     = true ,
+    break-lines-in-piton .bool_set:N    = \l_@@_break_lines_in_piton_bool ,
+    break-lines-in-piton .default:n     = true ,
+    break-lines .meta:n = { break-lines-in-piton , break-lines-in-Piton } , 
+    break-lines .value_forbidden:n      = true ,
+    indent-broken-lines .bool_set:N     = \l_@@_indent_broken_lines_bool ,
+    indent-broken-lines .default:n      = true ,
+    end-of-broken-line  .tl_set:N       = \l_@@_end_of_broken_line_tl ,
+    end-of-broken-line  .value_required:n = true , 
+    continuation-symbol .tl_set:N       = \l_@@_continuation_symbol_tl ,
+    continuation-symbol .value_required:n = true , 
+    continuation-symbol-on-indentation .tl_set:N = \l_@@_csoi_tl ,
+    continuation-symbol-on-indentation .value_required:n = true , 
+    unknown          .code:n = 
+      \msg_error:nn { piton } { Unknown~key~for~PitonOptions }
+  }
+%    \end{macrocode}
+%
+% 
+%  \bigskip
+% 
+% \bigskip
+% The argument of |\PitonOptions| is provided by curryfication.
+%    \begin{macrocode}
+\NewDocumentCommand \PitonOptions { } { \keys_set:nn { PitonOptions } }
+%    \end{macrocode}
+%
+% \bigskip
+% \subsubsection{The numbers of the lines}
+%
+% \medskip
+% The following counter will be used to count the lines in the code when the
+% user requires the numbers of the lines to be printed (with |line-numbers| or
+% |all-line-numbers|). 
+%
+%    \begin{macrocode}
+\int_new:N \g_@@_visual_line_int 
+%    \end{macrocode}
+% 
+% 
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_print_number:
+  {
+    \int_gincr:N \g_@@_visual_line_int
+    \hbox_overlap_left:n
+      { 
+        { \color { gray } \footnotesize \int_to_arabic:n \g_@@_visual_line_int }
+        \skip_horizontal:N \l_@@_numbers_sep_dim  
+      }
+  }
+%    \end{macrocode}
+% 
+%
+% \bigskip
+% \subsubsection{The command to write on the aux file}
+%
+%   
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_write_aux:
+  {
+    \tl_if_empty:NF \g_@@_aux_tl 
+      {
+        \iow_now:Nn \@mainaux { \ExplSyntaxOn }
+        \iow_now:Nx \@mainaux 
+          {
+            \tl_gset:cn { c_@@_ \int_use:N \g_@@_env_int _ tl } 
+              { \exp_not:V \g_@@_aux_tl } 
+          }
+        \iow_now:Nn \@mainaux { \ExplSyntaxOff }
+      }
+    \tl_gclear:N \g_@@_aux_tl 
+  }
+%    \end{macrocode}
+%
+%    \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 } }
+              }
+          }
+      }
+  }
+%    \end{macrocode}
+% 
+% \bigskip
+% \subsubsection{The main commands and environments for the final user}
+%
+% \bigskip
+%    \begin{macrocode}
+\NewDocumentCommand { \piton } { }
+  { \peek_meaning:NTF \bgroup \@@_piton_standard \@@_piton_verbatim }
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+\NewDocumentCommand { \@@_piton_standard } { m }
+  {
+    \group_begin:
+    \ttfamily
+%    \end{macrocode}
+% The following tuning of LuaTeX in order to avoid all break of lines on the
+% hyphens. 
+%    \begin{macrocode}
+    \automatichyphenmode = 1
+    \cs_set_eq:NN \\ \c_backslash_str
+    \cs_set_eq:NN \% \c_percent_str  
+    \cs_set_eq:NN \{ \c_left_brace_str
+    \cs_set_eq:NN \} \c_right_brace_str
+    \cs_set_eq:NN \$ \c_dollar_str
+    \cs_set_eq:cN { ~ } \space 
+    \cs_set_protected:Npn \@@_begin_line: { }
+    \cs_set_protected:Npn \@@_end_line: { }
+    \tl_set:Nx \l_tmpa_tl 
+      { 
+        \lua_now:e 
+          { piton.ParseBis('\l_@@_language_str',token.scan_string()) }
+          { #1 } 
+      }
+    \bool_if:NTF \l_@@_show_spaces_bool
+      { \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl } % U+2423
+%    \end{macrocode}
+% The following code replaces the characters U+0020 (spaces) by characters
+% U+0020 of catcode~10: thus, they become breakable by an end of line.
+%    \begin{macrocode}
+      {
+        \bool_if:NT \l_@@_break_lines_in_piton_bool
+          { \regex_replace_all:nnN { \x20 } { \x20 } \l_tmpa_tl }
+      }
+    \l_tmpa_tl 
+    \group_end:
+  }
+%    \end{macrocode}
+%
+% 
+%    \begin{macrocode}
+\NewDocumentCommand { \@@_piton_verbatim } { v }
+  {
+    \group_begin:
+    \ttfamily
+    \automatichyphenmode = 1
+    \cs_set_protected:Npn \@@_begin_line: { }
+    \cs_set_protected:Npn \@@_end_line: { }
+    \tl_set:Nx \l_tmpa_tl 
+      { 
+        \lua_now:e 
+          { piton.Parse('\l_@@_language_str',token.scan_string()) } 
+          { #1 } 
+      }
+    \bool_if:NT \l_@@_show_spaces_bool
+      { \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl } % U+2423
+    \l_tmpa_tl 
+    \group_end:
+  }
+%    \end{macrocode}
+%
+
+%  \bigskip
+%
+%
+% \bigskip
+% The following command is not a user command. It will be used when we will
+% have to ``rescan'' some chunks of Python code. For example, it will be the
+% initial value of the Piton style |InitialValues| (the default values of the
+% arguments of a Python function).
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_piton:n #1
+  { 
+    \group_begin:
+    \cs_set_protected:Npn \@@_begin_line: { }
+    \cs_set_protected:Npn \@@_end_line: { }
+    \bool_lazy_or:nnTF 
+      \l_@@_break_lines_in_piton_bool
+      \l_@@_break_lines_in_Piton_bool
+      {
+        \tl_set:Nx \l_tmpa_tl 
+          { 
+            \lua_now:e 
+              { piton.ParseTer('\l_@@_language_str',token.scan_string()) } 
+              { #1 } 
+          }
+      }
+      {
+        \tl_set:Nx \l_tmpa_tl 
+          { 
+            \lua_now:e 
+              { piton.Parse('\l_@@_language_str',token.scan_string()) }
+              { #1 } 
+          }
+      }
+    \bool_if:NT \l_@@_show_spaces_bool
+      { \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl } % U+2423
+    \l_tmpa_tl 
+    \group_end:
+  }
+%    \end{macrocode}
+%
+% \bigskip
+% The following command is similar to the previous one but raise a fatal error if
+% its argument contains a carriage return.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_piton_no_cr:n #1
+  { 
+    \group_begin:
+    \cs_set_protected:Npn \@@_begin_line: { }
+    \cs_set_protected:Npn \@@_end_line: { }
+    \cs_set_protected:Npn \@@_newline:
+      { \msg_fatal:nn { piton } { cr~not~allowed } }
+    \bool_lazy_or:nnTF 
+      \l_@@_break_lines_in_piton_bool
+      \l_@@_break_lines_in_Piton_bool
+      {
+        \tl_set:Nx \l_tmpa_tl 
+          { 
+            \lua_now:e 
+              { piton.ParseTer('\l_@@_language_str',token.scan_string()) } 
+              { #1 }
+          } 
+      }
+      {
+        \tl_set:Nx \l_tmpa_tl 
+          { 
+            \lua_now:e 
+              { piton.Parse('\l_@@_language_str',token.scan_string()) }
+              { #1 } 
+          }
+      }
+    \bool_if:NT \l_@@_show_spaces_bool
+      { \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl } % U+2423
+    \l_tmpa_tl 
+    \group_end:
+  }
+%    \end{macrocode}
+% 
+% \bigskip
+% Despite its name, |\@@_pre_env:| will be used both in |\PitonInputFile| and
+% in the environments such as |{Piton}|.
+%    \begin{macrocode}
+\cs_new:Npn \@@_pre_env:
+  {
+    \automatichyphenmode = 1
+    \int_gincr:N \g_@@_env_int 
+    \tl_gclear:N \g_@@_aux_tl
+    \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
+    \int_gzero:N \g_@@_line_int
+    \dim_zero:N \parindent 
+    \dim_zero:N \lineskip 
+    \dim_zero:N \parindent 
+    \cs_set_eq:NN \label \@@_label:n
+  }
+%    \end{macrocode}
+% 
+% \bigskip
+%    \begin{macrocode}
+\keys_define:nn { PitonInputFile }
+  {
+    first-line .int_set:N = \l_@@_first_line_int ,  
+    first-line .value_required:n = true ,
+    last-line .int_set:N = \l_@@_last_line_int , 
+    last-line .value_required:n = true , 
+  }
+%    \end{macrocode}
+% 
+% \bigskip
+%    \begin{macrocode}
+\NewDocumentCommand { \PitonInputFile } { d < > O { } m }
+  {
+    \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}     
+% 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|. 
+%    \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 }
+        }
+%    \end{macrocode}
+% Now, the main job.
+%    \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:
+  }
+%    \end{macrocode}
+%
+% 
+% \bigskip 
+%    \begin{macrocode}
+\NewDocumentCommand { \NewPitonEnvironment } { m m m m }
+  { 
+%    \end{macrocode}
+% We construct a TeX macro which will catch as argument all the tokens until
+% |\end{|\texttt{\textsl{name_env}}|}| with, in that
+% |\end{|\texttt{\textsl{name_env}}|}|, the catcodes of |\|, |{| and |}| equal to
+% 12 (``\texttt{other}''). The latter explains why the definition of that
+% function is a bit complicated.
+%    \begin{macrocode}
+    \use:x 
+      { 
+        \cs_set_protected:Npn 
+          \use:c { _@@_collect_ #1 :w } 
+          ####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}
+% 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.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|.
+%    \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 }
+              }
+%    \end{macrocode}
+% Now, the main job.
+%    \begin{macrocode}
+            \ttfamily
+            \bool_if:NT \c_@@_footnote_bool { \begin { savenotes } } 
+            \vtop \bgroup 
+            \lua_now:e 
+              { 
+                piton.GobbleParse
+                  ( 
+                    '\l_@@_language_str' , 
+                    \int_use:N \l_@@_gobble_int , 
+                    token.scan_argument() 
+                  ) 
+              } 
+              { ##1 }
+            \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.
+%    \begin{macrocode}
+            \end { #1 }
+            \@@_write_aux:
+          }   
+%    \end{macrocode}
+% 
+% 
+% \bigskip
+% We can now define the new environment.
+%
+% We are still in the definition of the command |\NewPitonEnvironment|...
+%    \begin{macrocode}
+    \NewDocumentEnvironment { #1 } { #2 } 
+      {
+        #3 
+        \@@_pre_env:
+        \group_begin:
+        \tl_map_function:nN 
+          { \ \\ \{ \} \$ \& \# \^ \_ \% \~ \^^I } 
+          \char_set_catcode_other:N 
+        \use:c { _@@_collect_ #1 :w }
+      }
+      { #4 }
+%    \end{macrocode}
+%
+% \medskip
+% The following code is for technical reasons. We want to change the catcode of
+% |^^M| before catching the arguments of the new environment we are defining.
+% Indeed, if not, we will have problems if there is a final optional argument in
+% our environment (if that final argument is not used by the user in an
+% instance of the environment, a spurious space is inserted, probably because
+% the |^^M| is converted to space).
+%    \begin{macrocode}
+    \AddToHook { env / #1 / begin } { \char_set_catcode_other:N \^^M }
+  }
+%    \end{macrocode}
+% This is the end of the definition of the command |\NewPitonEnvironment|.
+%
+% \bigskip
+% Now, we define the environment |{Piton}|, which is the main environment
+% provided by the package \pkg{piton}. Of course, you use
+% |\NewPitonEnvironment|. 
+%    \begin{macrocode}
+\bool_if:NTF \c_@@_beamer_bool
+  {
+    \NewPitonEnvironment { Piton } { d < > }
+      { 
+        \IfValueTF { #1 }
+          { \begin { uncoverenv } < #1 > }
+          { \begin { uncoverenv } }
+      }
+      { \end { uncoverenv } } 
+  }
+  { \NewPitonEnvironment { Piton } { } { } { } }
+%    \end{macrocode}
+%
+%
+%
+% \bigskip
+% \subsubsection{The styles}
+% 
+% \medskip
+% The following command is fundamental: it will be used by the Lua code.
+%    \begin{macrocode}
+\NewDocumentCommand { \PitonStyle } { m } { \use:c { pitonStyle #1 } }
+%    \end{macrocode}
+%
+% \medskip
+% The following command takes in its argument by curryfication.
+%    \begin{macrocode}
+\NewDocumentCommand { \SetPitonStyle } { } { \keys_set:nn { piton / Styles } } 
+%    \end{macrocode}
+% 
+% \medskip
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_math_scantokens:n #1 
+  { \normalfont \scantextokens { $#1$ } }
+%    \end{macrocode}
+% 
+% \medskip
+%    \begin{macrocode}
+\keys_define:nn { piton / Styles }
+  {
+    String.Interpol   .tl_set:c = pitonStyle String.Interpol , 
+    String.Interpol   .value_required:n = true ,
+    FormattingType    .tl_set:c = pitonStyle FormattingType ,
+    FormattingType    .value_required:n = true ,
+    Dict.Value        .tl_set:c = pitonStyle Dict.Value ,
+    Dict.Value        .value_required:n = true ,
+    Name.Decorator    .tl_set:c = pitonStyle Name.Decorator ,
+    Name.Decorator    .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 ,
+    Keyword           .tl_set:c = pitonStyle Keyword ,
+    Keyword           .value_required:n = true ,
+    Keyword.Constant  .tl_set:c = pitonStyle Keyword.Constant ,
+    Keyword.constant  .value_required:n = true ,
+    String.Doc        .tl_set:c = pitonStyle String.Doc ,
+    String.Doc        .value_required:n = true ,
+    Interpol.Inside   .tl_set:c = pitonStyle Interpol.Inside ,
+    Interpol.Inside   .value_required:n = true ,
+    String.Long       .tl_set:c = pitonStyle String.Long ,
+    String.Long       .value_required:n = true ,
+    String.Short      .tl_set:c = pitonStyle String.Short ,
+    String.Short      .value_required:n = true ,
+    String            .meta:n = { String.Long = #1 , String.Short = #1 } ,
+    Comment.Math      .tl_set:c = pitonStyle Comment.Math , 
+    Comment.Math      .default:n = \@@_math_scantokens:n ,
+    Comment.Math      .initial:n = ,
+    Comment           .tl_set:c = pitonStyle Comment , 
+    Comment           .value_required:n = true ,
+    InitialValues     .tl_set:c = pitonStyle InitialValues ,
+    InitialValues     .value_required:n = true ,
+    Number            .tl_set:c = pitonStyle Number , 
+    Number            .value_required:n = true ,
+    Name.Namespace    .tl_set:c = pitonStyle Name.Namespace , 
+    Name.Namespace    .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 , 
+    Name.Builtin      .value_required:n = true ,
+    TypeParameter     .tl_set:c = pitonStyle TypeParameter , 
+    TypeParameter     .value_required:n = true ,
+    Name.Type         .tl_set:c = pitonStyle Name.Type , 
+    Name.Type         .value_required:n = true ,
+    Operator          .tl_set:c = pitonStyle Operator , 
+    Operator          .value_required:n = true ,
+    Operator.Word     .tl_set:c = pitonStyle Operator.Word , 
+    Operator.Word     .value_required:n = true ,
+    Exception         .tl_set:c = pitonStyle Exception ,
+    Exception         .value_required:n = true ,
+    Comment.LaTeX     .tl_set:c = pitonStyle Comment.LaTeX ,
+    Comment.LaTeX     .value_required:n = true ,
+    Identifier        .tl_set:c = pitonStyle Identifier ,
+    Comment.LaTeX     .value_required:n = true ,
+    ParseAgain.noCR   .tl_set:c = pitonStyle ParseAgain.noCR ,
+    ParseAgain.noCR   .value_required:n = true ,
+    ParseAgain        .tl_set:c = pitonStyle ParseAgain , 
+    ParseAgain        .value_required:n = true ,
+    Prompt            .tl_set:c = pitonStyle Prompt , 
+    Prompt            .value_required:n = true ,
+    unknown           .code:n = 
+      \msg_error:nn { piton } { Unknown~key~for~SetPitonStyle }
+  }
+%    \end{macrocode}
+% 
+% 
+% \bigskip
+%    \begin{macrocode}
+\msg_new:nnn { piton } { Unknown~key~for~SetPitonStyle } 
+  {
+    The~style~'\l_keys_key_str'~is~unknown.\\
+    This~key~will~be~ignored.\\
+    The~available~styles~are~(in~alphabetic~order):~
+    Comment,~
+    Comment.LaTeX,~
+    Dict.Value,~
+    Exception,~
+    Identifier,~
+    InitialValues,~ 
+    Keyword,~
+    Keyword.Constant,~
+    Name.Builtin,~
+    Name.Class,~
+    Name.Decorator,~
+    Name.Function,~
+    Name.Namespace,~
+    Number,~
+    Operator,~
+    Operator.Word,~
+    Prompt,~
+    String,~
+    String.Doc,~
+    String.Long,~
+    String.Short,~and~
+    String.Interpol. 
+  }
+%    \end{macrocode}
+%
+% \bigskip
+% \subsubsection{The initial style}
+%
+% The initial style is inspired by the style ``manni'' of Pygments.
+% 
+% \medskip
+%    \begin{macrocode}
+\SetPitonStyle
+  {                                                       
+    Comment            = \color[HTML]{0099FF} \itshape , 
+    Exception          = \color[HTML]{CC0000} ,
+    Keyword            = \color[HTML]{006699} \bfseries ,               
+    Keyword.Constant   = \color[HTML]{006699} \bfseries ,               
+    Name.Builtin       = \color[HTML]{336666} ,
+    Name.Decorator     = \color[HTML]{9999FF}, 
+    Name.Class         = \color[HTML]{00AA88} \bfseries ,
+    Name.Function      = \color[HTML]{CC00FF} , 
+    Name.Namespace     = \color[HTML]{00CCFF} , 
+    Number             = \color[HTML]{FF6600} ,
+    Operator           = \color[HTML]{555555} ,
+    Operator.Word      = \bfseries ,
+    String             = \color[HTML]{CC3300} ,         
+    String.Doc         = \color[HTML]{CC3300} \itshape , 
+    String.Interpol    = \color[HTML]{AA0000} ,
+    Comment.LaTeX      = \normalfont \color[rgb]{.468,.532,.6} , 
+    Name.Type          = \color[HTML]{336666} ,
+    InitialValues      = \@@_piton:n ,
+    Dict.Value         = \@@_piton:n ,
+    Interpol.Inside    = \color{black}\@@_piton:n ,
+    TypeParameter      = \color[HTML]{008800} \itshape ,
+    Identifier         = \@@_identifier:n , 
+    Name.UserFunction  = , 
+    Prompt             = , 
+    ParseAgain.noCR    = \@@_piton_no_cr:n , 
+    ParseAgain         = \@@_piton:n ,
+  }
+%    \end{macrocode}
+% The last styles |ParseAgain.noCR| and |ParseAgain| should be considered as 
+% ``internal style'' (not available for the final user). However, maybe we will
+% change that and document these styles for the final user (why not?).
+%
+% \medskip
+% If the key |math-comments| has been used at load-time, we change the style
+% |Comment.Math| which should be considered only at an ``internal style''.
+% However, maybe we will document in a future version the possibility to write
+% change the style \emph{locally} in a document)].
+%    \begin{macrocode}
+\bool_if:NT \c_@@_math_comments_bool { \SetPitonStyle { Comment.Math } }
+%    \end{macrocode}
+% 
+% \bigskip
+%
+% \bigskip
+% \subsubsection{Highlighting some identifiers}
+% 
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_identifier:n #1
+  { \cs_if_exist_use:c { PitonIdentifier _ \l_@@_language_str _ #1 } { #1 } } 
+%    \end{macrocode}
+%
+% \bigskip
+%    \begin{macrocode}
+\keys_define:nn { PitonOptions }
+  { identifiers .code:n = \@@_set_identifiers:n { #1 } }
+%    \end{macrocode}
+%
+% \bigskip
+%    \begin{macrocode}
+\keys_define:nn { Piton / identifiers }
+  {
+    names .clist_set:N = \l_@@_identifiers_names_tl ,
+    style .tl_set:N    = \l_@@_style_tl ,
+  }
+%    \end{macrocode}
+%
+% \bigskip
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_set_identifiers:n #1
+  {
+    \clist_clear_new:N \l_@@_identifiers_names_tl 
+    \tl_clear_new:N \l_@@_style_tl 
+    \keys_set:nn { Piton / identifiers } { #1 }
+    \clist_map_inline:Nn \l_@@_identifiers_names_tl 
+      {
+        \tl_set_eq:cN 
+          { PitonIdentifier _ \l_@@_language_str _ ##1 }
+          \l_@@_style_tl
+      }
+  }
+%    \end{macrocode}
+%
+%
+% \bigskip
+% In particular, we have an hightlighting 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
+% 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.
+%    \begin{macrocode}
+    { \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,
+% 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 } }
+%    \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|.
+%    \begin{macrocode}
+    \seq_if_exist:cF { g_@@_functions _ \l_@@_language_str _ seq }
+      { \seq_new:c { g_@@_functions _ \l_@@_language_str _ seq } }
+    \seq_gput_right:cn { g_@@_functions _ \l_@@_language_str _ seq } { #1 }
+  }
+%    \end{macrocode}
+%
+% \bigskip
+%    \begin{macrocode}
+\NewDocumentCommand \PitonClearUserFunctions { ! O { \l_@@_language_str }  } 
+  {
+    \seq_if_exist:cT { g_@@_functions _ #1 _ seq }
+      {
+        \seq_map_inline:cn { g_@@_functions _ #1 _ seq }
+          { \cs_undefine:c { PitonIdentifier _ #1 _ ##1} }
+        \seq_gclear:c { g_@@_functions _ #1 _ seq }
+      }
+  }
+%    \end{macrocode}
+% 
+% \bigskip
+% \subsubsection{Security}
+%
+%     \begin{macrocode}
+\AddToHook { env / piton / begin } 
+   { \msg_fatal:nn { piton } { No~environment~piton } }
+
+\msg_new:nnn { piton } { No~environment~piton }
+  { 
+    There~is~no~environment~piton!\\
+    There~is~an~environment~{Piton}~and~a~command~
+    \token_to_str:N \piton\ but~there~is~no~environment~
+    {piton}.~This~error~is~fatal.
+  }
+%    \end{macrocode}
+% 
+% \bigskip
+% \subsubsection{The error messages of the package}
+%
+%    \begin{macrocode}
+\msg_new:nnnn { piton } { Unknown~key~for~PitonOptions }
+  { 
+    Unknown~key. \\
+    The~key~'\l_keys_key_str'~is~unknown~for~\token_to_str:N \PitonOptions.~
+    It~will~be~ignored.\\
+    For~a~list~of~the~available~keys,~type~H~<return>.
+  }
+  {
+    The~available~keys~are~(in~alphabetic~order):~
+    all-line-numbers,~
+    auto-gobble,~
+    background-color,~
+    break-lines,~
+    break-lines-in-piton,~
+    break-lines-in-Piton,~
+    continuation-symbol,~
+    continuation-symbol-on-indentation,~
+    end-of-broken-line,~
+    env-gobble,~
+    gobble,~
+    identifiers,~
+    indent-broken-lines,~
+    language,~
+    left-margin,~
+    line-numbers,~
+    prompt-background-color,~
+    resume,~
+    show-spaces,~
+    show-spaces-in-strings,~
+    slim,~
+    splittable,~
+    tabs-auto-gobble~
+    and~tab-size.
+  }
+%    \end{macrocode}
+%
+% \bigskip
+%    \begin{macrocode}
+\msg_new:nnn { piton } { label~with~lines~numbers } 
+  {
+    You~can't~use~the~command~\token_to_str:N \label\
+    because~the~key~'line-numbers'~(or~'all-line-numbers')~
+    is~not~active.\\
+    If~you~go~on,~that~command~will~ignored.
+  }
+%    \end{macrocode}
+% 
+% \bigskip
+%    \begin{macrocode}
+\msg_new:nnn { piton } { cr~not~allowed }
+  {
+    You~can't~put~any~carriage~return~in~the~argument~
+    of~a~command~\c_backslash_str
+    \l_@@_beamer_command_str\ within~an~
+    environment~of~'piton'.~You~should~consider~using~the~
+    corresponding~environment.\\
+    That~error~is~fatal.
+  }
+%    \end{macrocode}
+%
+% \bigskip
+%    \begin{macrocode}
+\msg_new:nnn { piton } { overlay~without~beamer }
+  {
+    You~can't~use~an~argument~<...>~for~your~command~
+    \token_to_str:N \PitonInputFile\ because~you~are~not~
+    in~Beamer.\\
+    If~you~go~on,~that~argument~will~be~ignored.
+  }
+%    \end{macrocode}
+%
+% \bigskip
+%    \begin{macrocode}
+\msg_new:nnn { Piton } { Python~error }
+  { A~Python~error~has~been~detected. }
+%    \end{macrocode}
+% 
+% \bigskip
+% \subsection{The Lua part of the implementation}
+%
+% \bigskip
+%    \begin{macrocode}
+\ExplSyntaxOff
+\RequirePackage{luacode}
+%    \end{macrocode}
+% 
+%
+% \bigskip
+% The Lua code will be loaded via a |{luacode*}| environment. The environment
+% is by itself a Lua block and the local declarations will be local to that
+% block. All the global functions (used by the L3 parts of the implementation)
+% will be put in a Lua table |piton|.
+%
+% \medskip
+%    \begin{macrocode}
+\begin{luacode*}
+piton = piton or { }
+%    \end{macrocode}
+% 
+%    \begin{macrocode}
+if piton.comment_latex == nil then piton.comment_latex = ">" end 
+piton.comment_latex = "#" .. piton.comment_latex 
+%    \end{macrocode}
+%
+%
+% \bigskip
+% The following functions are an easy way to safely insert braces (|{| and |}|)
+% in the TeX flow.
+%    \begin{macrocode}
+function piton.open_brace () 
+   tex.sprint("{") 
+end 
+function piton.close_brace () 
+   tex.sprint("}") 
+end 
+%    \end{macrocode}
+%
+% \bigskip
+% \subsubsection{Special functions dealing with LPEG}
+%
+% \medskip
+% We will use the Lua library \pkg{lpeg} which is built in LuaTeX. That's why we
+% define first aliases for several functions of that library.
+%    \begin{macrocode}
+local P, S, V, C, Ct, Cc = lpeg.P, lpeg.S, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Cc
+local Cf, Cs , Cg , Cmt , Cb = lpeg.Cf, lpeg.Cs, lpeg.Cg , lpeg.Cmt , lpeg.Cb
+local R = lpeg.R
+%    \end{macrocode}
+%
+% 
+%
+% \bigskip
+% The function |Q| takes in as argument a pattern and returns a \textsc{lpeg}
+% \emph{which does a capture} of the pattern. That capture will be sent to LaTeX
+% with the catcode ``other'' for all the characters: it's suitable for elements
+% of the Python listings that \pkg{piton} will typeset verbatim (thanks to the
+% catcode ``other''). 
+%    \begin{macrocode}
+local function Q(pattern)
+  return Ct ( Cc ( luatexbase.catcodetables.CatcodeTableOther ) * C ( pattern ) )
+end 
+%    \end{macrocode}
+%
+%
+% \bigskip
+% The function |L| takes in as argument a pattern and returns a \textsc{lpeg}
+% \emph{which does a capture} of the pattern. That capture will be sent to LaTeX
+% with standard LaTeX catcodes for all the characters: the elements captured
+% will be formatted as normal LaTeX codes. It's suitable for the ``LaTeX
+% comments'' in the environments |{Piton}| and the elements beetween 
+% ``|escape-inside|''. That function won't be much used.
+%    \begin{macrocode}
+local function L(pattern)
+  return Ct ( C ( pattern ) ) 
+end
+%    \end{macrocode}
+%
+% \bigskip
+% The function |Lc| (the c is for \emph{constant}) takes in as argument a string
+% and returns a \textsc{lpeg} \emph{with does a constant capture} which returns
+% that string. The elements captured will be formatted as L3 code. It will be
+% used to send to LaTeX all the formatting LaTeX instructions we have to insert
+% in order to do the syntactic highlighting (that's the main job of
+% \pkg{piton}). That function will be widely used.
+%    \begin{macrocode}
+local function Lc(string)
+  return Cc ( { luatexbase.catcodetables.expl , string } ) 
+end 
+%    \end{macrocode}
+% 
+% \bigskip
+% The function |K| creates a \textsc{lpeg} which will return as capture the
+% whole LaTeX code corresponding to a Python chunk (that is to say with the
+% LaTeX formatting instructions corresponding to the syntactic nature of that
+% Python chunk). The first argument is a Lua string corresponding to the name of
+% a \pkg{piton} style and the second element is a pattern (that is to say a
+% \textsc{lpeg} without capture)
+%    \begin{macrocode}
+local function K(style, pattern)
+  return
+     Lc ( "{\\PitonStyle{" .. style .. "}{" )
+     * Q ( pattern )
+     * Lc ( "}}" )
+end
+%    \end{macrocode}
+% The formatting commands in a given \pkg{piton} style (eg. the style |Keyword|)
+% may be semi-global declarations (such as |\bfseries| or |\slshape|) or LaTeX
+% macros with an argument (such as |\fbox| or |\colorbox{yellow}|). In order to
+% deal with both syntaxes, we have used two pairs of braces: 
+% |{\PitonStyle{Keyword}{|\texttt{\slshape text to format}|}}|.
+% 
+%
+% \bigskip
+%    \begin{macrocode}
+local function WithStyle(style,pattern)
+  return 
+       Ct ( Cc "Open" * Cc ( "{\\PitonStyle{" .. style .. "}{" ) * Cc "}}" ) 
+     * pattern 
+     * Ct ( Cc "Close" ) 
+end
+%    \end{macrocode}
+% 
+% \bigskip
+% The following \textsc{lpeg} catches the Python chunks which are in LaTeX
+% escapes (and that chunks will be considered as normal LaTeX constructions). We
+% recall that |piton.begin_espace| and |piton_end_escape| are Lua strings
+% corresponding to the key |escape-inside|\footnote{The \pkg{piton} key
+% |escape-inside| is available at load-time only.}. Since the elements that will
+% be catched must be sent to LaTeX with standard LaTeX catcodes, we put the
+% capture (done by the function |C|) in a table (by using |Ct|, which is an
+% alias for |lpeg.Ct|) without number of catcode table at the first component of
+% the table.
+%    \begin{macrocode}
+local Escape = 
+  P(piton_begin_escape)
+  * L ( ( 1 - P(piton_end_escape) ) ^ 1 ) 
+  * P(piton_end_escape)
+%    \end{macrocode}
+% 
+% \vspace{1cm}
+% The following line is mandatory.
+%    \begin{macrocode}
+lpeg.locale(lpeg)
+%    \end{macrocode}
+%
+% \bigskip
+% \paragraph{The basic syntactic LPEG}
+%
+%    \begin{macrocode}
+local alpha, digit = lpeg.alpha, lpeg.digit
+local space = P " " 
+%    \end{macrocode}
+%
+% Remember that, for \textsc{lpeg}, the Unicode characters such as |à|, |â|,
+% |ç|, etc. are in fact strings of length 2 (2 bytes) because \pkg{lpeg} is not
+% Unicode-aware. 
+%    \begin{macrocode}
+local letter = alpha + P "_" 
+  + P "â" + P "à" + P "ç" + P "é" + P "è" + P "ê" + P "ë" + P "ï" + P "î" 
+  + P "ô" + P "û" + P "ü" + P "Â" + P "À" + P "Ç" + P "É" + P "È" + P "Ê" 
+  + P "Ë" + P "Ï" + P "Î" + P "Ô" + P "Û" + P "Ü" 
+
+local alphanum = letter + digit
+%    \end{macrocode}
+% 
+% \bigskip
+% The following \textsc{lpeg} |identifier| is a mere pattern (that is to say
+% more or less a regular expression) which matches the Python identifiers (hence
+% the name).
+%    \begin{macrocode}
+local identifier = letter * alphanum ^ 0
+%    \end{macrocode}
+% 
+% \medskip
+% On the other hand, the \textsc{lpeg} |Identifier| (with a capital) also returns
+% a \emph{capture}.
+%    \begin{macrocode}
+local Identifier = K ( 'Identifier' , identifier)
+%    \end{macrocode}
+%
+% \bigskip
+% By convention, we will use names with an initial capital for \textsc{lpeg}
+% which return captures.
+%
+% 
+% \bigskip
+% Here is the first use of our function~|K|. That function will be used to
+% construct \textsc{lpeg} which capture Python chunks for which we have a
+% dedicated \pkg{piton} style. For example, for the numbers, \pkg{piton}
+% provides a style which is called |Number|. The name of the style is provided
+% as a Lua string in the second argument of the function~|K|. By convention, we
+% use single quotes for delimiting the Lua strings which are names of
+% \pkg{piton} styles (but this is only a convention).
+%    \begin{macrocode}
+local Number =
+  K ( 'Number' ,
+      ( digit^1 * P "." * digit^0 + digit^0 * P "." * digit^1 + digit^1 )
+      * ( S "eE" * S "+-" ^ -1 * digit^1 ) ^ -1
+      + digit^1 
+    ) 
+%    \end{macrocode}
+%
+% \bigskip
+% We recall that |piton.begin_espace| and |piton_end_escape| are Lua strings
+% corresponding to the key |escape-inside|\footnote{The \pkg{piton} key
+% |escape-inside| is available at load-time only.}. Of course, if the final user
+% has not used the key |escape-inside|, these strings are empty.
+%    \begin{macrocode}
+local Word
+if piton_begin_escape ~= ''
+then Word = Q ( ( ( 1 - space - P(piton_begin_escape) - P(piton_end_escape) ) 
+                   - S "'\"\r[()]" - digit ) ^ 1 )
+else Word = Q ( ( ( 1 - space ) - S "'\"\r[()]" - digit ) ^ 1 )
+end
+%    \end{macrocode}
+%
+% \bigskip
+%    \begin{macrocode}
+local Space = ( Q " " ) ^ 1
+
+local SkipSpace = ( Q " " ) ^ 0
+
+local Punct = Q ( S ".,:;!" )
+
+local Tab = P "\t" * Lc ( '\\l_@@_tab_tl' )
+%    \end{macrocode}
+% 
+% \bigskip
+%    \begin{macrocode}
+local SpaceIndentation = Lc ( '\\@@_an_indentation_space:' ) * ( Q " " )
+%    \end{macrocode}
+%
+%
+% \bigskip
+%    \begin{macrocode}
+local Delim = Q ( S "[()]" )
+%    \end{macrocode}
+% 
+% \bigskip
+% The following \textsc{lpeg} catches a space (U+0020) and replace it by
+% |\l_@@_space_tl|. It will be used in the strings. Usually,
+% |\l_@@_space_tl| will contain a space and therefore there won't be difference.
+% However, when the key |show-spaces-in-strings| is in force, |\\l_@@_space_tl| will
+% contain ␣ (U+2423) in order to visualize the spaces.
+%    \begin{macrocode}
+local VisualSpace = space * Lc "\\l_@@_space_tl" 
+%    \end{macrocode}
+% 
+%
+% \bigskip
+% \subsubsection{The LPEG python}
+% 
+% \bigskip
+% Some strings of length 2 are explicit because we want the corresponding
+% ligatures available in some fonts such as \emph{Fira Code} to be active.
+%    \begin{macrocode}
+local Operator = 
+  K ( 'Operator' ,
+      P "!=" + P "<>" + P "==" + P "<<" + P ">>" + P "<=" + P ">=" + P ":=" 
+      + P "//" + P "**" + S "-~+/*%=<>&.@|" 
+    )
+
+local OperatorWord = 
+  K ( 'Operator.Word' ,P "in" + P "is" + P "and" + P "or" + P "not" )
+
+local Keyword = 
+  K ( 'Keyword' ,
+      P "as" + P "assert" + P "break" + P "case" + P "class" + P "continue" 
+      + P "def" + P "del" + P "elif" + P "else" + P "except" + P "exec" 
+      + P "finally" + P "for" + P "from" + P "global" + P "if" + P "import" 
+      + P "lambda" + P "non local" + P "pass" + P "return" + P "try" 
+      + P "while" + P "with" + P "yield" + P "yield from" )
+  + K ( 'Keyword.Constant' ,P "True" + P "False" + P "None" ) 
+
+local Builtin = 
+  K ( 'Name.Builtin' ,
+      P "__import__" + P "abs" + P "all" + P "any" + P "bin" + P "bool" 
+    + P "bytearray" + P "bytes" + P "chr" + P "classmethod" + P "compile" 
+    + P "complex" + P "delattr" + P "dict" + P "dir" + P "divmod" 
+    + P "enumerate" + P "eval" + P "filter" + P "float" + P "format" 
+    + P "frozenset" + P "getattr" + P "globals" + P "hasattr" + P "hash" 
+    + P "hex" + P "id" + P "input" + P "int" + P "isinstance" + P "issubclass"
+    + P "iter" + P "len" + P "list" + P "locals" + P "map" + P "max" 
+    + P "memoryview" + P "min" + P "next" + P "object" + P "oct" + P "open" 
+    + P "ord" + P "pow" + P "print" + P "property" + P "range" + P "repr" 
+    + P "reversed" + P "round" + P "set" + P "setattr" + P "slice" + P "sorted" 
+    + P "staticmethod" + P "str" + P "sum" + P "super" + P "tuple" + P "type"
+    + P "vars" + P "zip" )
+
+
+local Exception =
+  K ( 'Exception' ,
+      P "ArithmeticError" + P "AssertionError" + P "AttributeError"
+   + P "BaseException" + P "BufferError" + P "BytesWarning" + P "DeprecationWarning"
+   + P "EOFError" + P "EnvironmentError" + P "Exception" + P "FloatingPointError"
+   + P "FutureWarning" + P "GeneratorExit" + P "IOError" + P "ImportError"
+   + P "ImportWarning" + P "IndentationError" + P "IndexError" + P "KeyError"
+   + P "KeyboardInterrupt" + P "LookupError" + P "MemoryError" + P "NameError"
+   + P "NotImplementedError" + P "OSError" + P "OverflowError"
+   + P "PendingDeprecationWarning" + P "ReferenceError" + P "ResourceWarning"
+   + P "RuntimeError" + P "RuntimeWarning" + P "StopIteration"
+   + P "SyntaxError" + P "SyntaxWarning" + P "SystemError" + P "SystemExit"
+   + P "TabError" + P "TypeError" + P "UnboundLocalError" + P "UnicodeDecodeError"
+   + P "UnicodeEncodeError" + P "UnicodeError" + P "UnicodeTranslateError"
+   + P "UnicodeWarning" + P "UserWarning" + P "ValueError" + P "VMSError"
+   + P "Warning" + P "WindowsError" + P "ZeroDivisionError"
+   + P "BlockingIOError" + P "ChildProcessError" + P "ConnectionError"
+   + P "BrokenPipeError" + P "ConnectionAbortedError" + P "ConnectionRefusedError"
+   + P "ConnectionResetError" + P "FileExistsError" + P "FileNotFoundError"
+   + P "InterruptedError" + P "IsADirectoryError" + P "NotADirectoryError"
+   + P "PermissionError" + P "ProcessLookupError" + P "TimeoutError"
+   + P "StopAsyncIteration" + P "ModuleNotFoundError" + P "RecursionError" )
+
+
+local RaiseException = K ( 'Keyword' , P "raise" ) * SkipSpace * Exception * Q ( P "(" ) 
+
+%    \end{macrocode}
+%
+% \bigskip
+% In Python, a ``decorator'' is a statement whose begins by |@| which patches
+% the function defined in the following statement.
+%    \begin{macrocode}
+local Decorator = K ( 'Name.Decorator' , P "@" * letter^1  ) 
+%    \end{macrocode}
+% 
+% \bigskip
+% The following \textsc{lpeg} |DefClass| will be used to detect the definition of a
+% new class (the name of that new class will be formatted with the \pkg{piton}
+% style |Name.Class|). 
+%
+% \smallskip
+% Example:\enskip \piton{class myclass:}
+%    \begin{macrocode}
+local DefClass = 
+  K ( 'Keyword' , P "class" ) * Space * K ( 'Name.Class' , identifier ) 
+%    \end{macrocode}
+% 
+% If the word |class| is not followed by a identifier, it will be catched as
+% keyword by the \textsc{lpeg} |Keyword| (useful if we want to type a
+% list of keywords).
+%
+%
+% \bigskip
+% The following \textsc{lpeg} |ImportAs| is used for the lines beginning by |import|.
+% % We have to detect the potential keyword |as| because both the name of the
+% module and its alias must be formatted with the \pkg{piton} style |Name.Namespace|.
+%
+% \smallskip
+% Example:\enskip \piton{import numpy as np}
+%
+% \smallskip
+% Moreover, after the keyword |import|, it's possible to have a comma-separated
+% list of modules (if the keyword |as| is not used).
+%
+% \smallskip
+% Example:\enskip \piton{import math, numpy}
+%    \begin{macrocode}
+local ImportAs = 
+  K ( 'Keyword' , P "import" )
+   * Space 
+   * K ( 'Name.Namespace' , 
+         identifier * ( P "." * identifier ) ^ 0 )
+   * ( 
+       ( Space * K ( 'Keyword' , P "as" ) * Space 
+          * K ( 'Name.Namespace' , identifier ) )
+       + 
+       ( SkipSpace * Q ( P "," ) * SkipSpace 
+          * K ( 'Name.Namespace' , identifier ) ) ^ 0 
+     ) 
+%    \end{macrocode}
+% Be careful: there is no commutativity of |+| in the previous expression.
+%
+% \bigskip
+% The \textsc{lpeg} |FromImport| is used for the lines beginning by |from|. We
+% need a special treatment because the identifier following the keyword |from|
+% must be formatted with the \pkg{piton} style |Name.Namespace| and the
+% following keyword |import| must be formatted with the \pkg{piton} style
+% |Keyword| and must \emph{not} be catched by the \textsc{lpeg} |ImportAs|.
+%
+% \smallskip
+% Example:\enskip \piton{from math import pi}
+%
+% \smallskip
+%    \begin{macrocode}
+local FromImport =
+  K ( 'Keyword' , P "from" ) 
+    * Space * K ( 'Name.Namespace' , identifier )
+    * Space * K ( 'Keyword' , P "import" ) 
+%    \end{macrocode}
+%
+% \bigskip
+% \paragraph{The strings of Python}
+%
+% For the strings in Python, there are four categories of delimiters (without
+% counting the prefixes for f-strings and raw strings). We will use, in the
+% names of our \textsc{lpeg}, prefixes to distinguish the \textsc{lpeg} dealing
+% with that categories of strings, as presented in the following tabular.
+% \begin{center}
+% \begin{tabular}{ccc}
+% \toprule
+%         & |Single| & |Double| \\
+% \midrule
+% |Short| & |'text'|     & |"text"| \\
+% |Long|  & |'''test'''| & |"""text"""| \\
+% \bottomrule
+% \end{tabular}
+% \end{center}
+%
+% 
+% \bigskip
+% We have also to deal with the interpolations in the f-strings. Here
+% is an example of a f-string with an interpolation and a format
+% instruction\footnote{There is no special \pkg{piton} style for the formatting
+% instruction (after the colon): the style which will be applied will be the
+% style of the encompassing string, that is to say |String.Short| or
+% |String.Long|.} in that interpolation:
+%
+% \piton{f'Total price: {total+1:.2f} €'}
+%
+%
+% \bigskip
+% The interpolations beginning by |%| (even though there is more modern
+% technics now in Python).
+%    \begin{macrocode}
+local PercentInterpol =  
+  K ( 'String.Interpol' , 
+      P "%" 
+      * ( P "(" * alphanum ^ 1 * P ")" ) ^ -1 
+      * ( S "-#0 +" ) ^ 0 
+      * ( digit ^ 1 + P "*" ) ^ -1 
+      * ( P "." * ( digit ^ 1 + P "*" ) ) ^ -1 
+      * ( S "HlL" ) ^ -1
+      * S "sdfFeExXorgiGauc%" 
+    ) 
+%    \end{macrocode}
+% 
+% \bigskip
+% We can now define the \textsc{lpeg} for the four kinds of strings. It's not
+% possible to use our function~|K| because of the interpolations which must be
+% formatted with another \pkg{piton} style that the rest of the
+% string.\footnote{The interpolations are formatted with the \pkg{piton} style
+% |Interpol.Inside|. The initial value of that style is \texttt{\textbackslash
+% @@\_piton:n} wich means that the interpolations are parsed once again by \pkg{piton}.}
+%    \begin{macrocode}
+local SingleShortString =
+  WithStyle ( 'String.Short' ,
+%    \end{macrocode}
+% First, we deal with the f-strings of Python, which are prefixed by |f| or |F|.
+%    \begin{macrocode}
+         Q ( P "f'" + P "F'" ) 
+         * ( 
+             K ( 'String.Interpol' , P "{" )
+              * K ( 'Interpol.Inside' , ( 1 - S "}':" ) ^ 0  )
+              * Q ( P ":" * (1 - S "}:'") ^ 0 ) ^ -1
+              * K ( 'String.Interpol' , P "}" )
+             + 
+             VisualSpace 
+             + 
+             Q ( ( P "\\'" + P "{{" + P "}}" + 1 - S " {}'" ) ^ 1 )
+           ) ^ 0 
+         * Q ( P "'" )
+       + 
+%    \end{macrocode}
+% Now, we deal with the standard strings of Python, but also the ``raw strings''.
+%    \begin{macrocode}
+         Q ( P "'" + P "r'" + P "R'" ) 
+         * ( Q ( ( P "\\'" + 1 - S " '\r%" ) ^ 1 ) 
+             + VisualSpace 
+             + PercentInterpol 
+             + Q ( P "%" ) 
+           ) ^ 0 
+         * Q ( P "'" ) )
+
+
+local DoubleShortString =
+  WithStyle ( 'String.Short' , 
+         Q ( P "f\"" + P "F\"" ) 
+         * ( 
+             K ( 'String.Interpol' , P "{" )
+               * Q ( ( 1 - S "}\":" ) ^ 0 , 'Interpol.Inside' )
+               * ( K ( 'String.Interpol' , P ":" ) * Q ( (1 - S "}:\"") ^ 0 ) ) ^ -1
+               * K ( 'String.Interpol' , P "}" )
+             + 
+             VisualSpace 
+             + 
+             Q ( ( P "\\\"" + P "{{" + P "}}" + 1 - S " {}\"" ) ^ 1 ) 
+            ) ^ 0
+         * Q ( P "\"" )
+       +
+         Q ( P "\"" + P "r\"" + P "R\"" ) 
+         * ( Q ( ( P "\\\"" + 1 - S " \"\r%" ) ^ 1 ) 
+             + VisualSpace 
+             + PercentInterpol 
+             + Q ( P "%" ) 
+           ) ^ 0 
+         * Q ( P "\"" ) )
+
+local ShortString = SingleShortString + DoubleShortString
+%    \end{macrocode}
+%
+% \bigskip
+% \paragraph{Beamer}
+%
+% The following \textsc{lpeg} |BalancedBraces| 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 =
+  P { "E" ,
+       E = 
+           (
+             P "{" * V "E" * P "}" 
+             + 
+             ShortString  
+             + 
+             ( 1 - S "{}" ) 
+           ) ^ 0 
+    }
+%    \end{macrocode}
+% 
+%
+% \bigskip 
+% If Beamer is used (or if the key |beamer| is used at load-time), the following
+% LPEG will be redefined.
+%    \begin{macrocode}
+local Beamer = P ( false ) 
+local BeamerBeginEnvironments = P ( true ) 
+local BeamerEndEnvironments = P ( true ) 
+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}
+% 
+%    \begin{macrocode}
+function OneBeamerEnvironment(name)
+  return 
+      Ct ( Cc "Open" 
+            * C ( 
+                  P ( "\\begin{" .. name ..   "}" )
+                  * ( P "<" * (1 - P ">") ^ 0 * P ">" ) ^ -1 
+                ) 
+           * Cc ( "\\end{" .. name ..  "}" )
+          ) 
+     * ( 
+         C ( ( 1 - P ( "\\end{" .. name .. "}" ) ) ^ 0 ) 
+         / (function (s) return MainLoopPython:match(s) end ) 
+       )
+     * P ( "\\end{" .. name ..  "}" ) * Ct ( Cc "Close" ) 
+end 
+%    \end{macrocode}
+% 
+%
+% \bigskip
+%    \begin{macrocode}
+if piton_beamer 
+then
+  Beamer =
+      L  ( P "\\pause" * ( P "[" * (1 - P "]") ^ 0 * P "]" ) ^ -1 ) 
+    + 
+      Ct ( Cc "Open" 
+            * C ( 
+                  ( 
+                    P "\\uncover" + P "\\only" + P "\\alert" + P "\\visible"
+                    + P "\\invisible" + P "\\action" 
+                  ) 
+                  * ( P "<" * (1 - P ">") ^ 0 * P ">" ) ^ -1 
+                  * P "{" 
+                ) 
+            * Cc "}" 
+         ) 
+       * ( C ( BalancedBraces ) / (function (s) return MainLoopPython:match(s) end ) )
+       * P "}" * Ct ( Cc "Close" ) 
+    + 
+      OneBeamerEnvironment "uncoverenv" 
+    + OneBeamerEnvironment "onlyenv" 
+    + OneBeamerEnvironment "visibleenv" 
+    + OneBeamerEnvironment "invisibleenv" 
+    + OneBeamerEnvironment "alertenv" 
+    + OneBeamerEnvironment "actionenv" 
+    +
+      L ( 
+%    \end{macrocode}
+% For |\\alt|, the specification of the overlays (between angular brackets) is mandatory.
+%    \begin{macrocode}
+          ( P "\\alt" )
+          * P "<" * (1 - P ">") ^ 0 * P ">" 
+          * P "{" 
+        )
+      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * L ( P "}{" )
+      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * L ( P "}" )
+    +  
+      L ( 
+%    \end{macrocode}
+% For |\\alt|, the specification of the overlays (between angular brackets) is mandatory.
+%    \begin{macrocode}
+          ( P "\\temporal" )
+          * P "<" * (1 - P ">") ^ 0 * P ">" 
+          * P "{" 
+        )
+      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * L ( P "}{" )
+      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * L ( P "}{" )
+      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * L ( P "}" )
+%    \end{macrocode}
+% Now for the environemnts.
+%    \begin{macrocode}
+  BeamerBeginEnvironments = 
+      ( space ^ 0 * 
+        L 
+          ( 
+            P "\\begin{" * BeamerNamesEnvironments * "}"
+            * ( P "<" * ( 1 - P ">") ^ 0 * P ">" ) ^ -1
+          )
+        * P "\r" 
+      ) ^ 0 
+  BeamerEndEnvironments = 
+      ( space ^ 0 * 
+        L ( P "\\end{" * BeamerNamesEnvironments * P "}" ) 
+        * P "\r" 
+      ) ^ 0 
+end
+%    \end{macrocode}
+%
+% \bigskip
+% \paragraph{EOL}
+%
+% \bigskip
+% The following LPEG will detect the Python prompts when the user is typesetting
+% an interactive session of Python (directly or through |{pyconsole}| of
+% \pkg{pyluatex}). We have to detect that prompt twice. The first detection
+% (called \emph{hasty detection}) will be before the |\@@_begin_line:| because
+% you want to trigger a special background color for that row (and, after the
+% |\@@_begin_line:|, it's too late to change de background).
+%    \begin{macrocode}
+local PromptHastyDetection = ( # ( P ">>>" + P "..." ) * Lc ( '\\@@_prompt:' ) ) ^ -1 
+%    \end{macrocode}
+% We remind that the marker |#| of \textsc{lpeg} specifies that the pattern will be
+% detected but won't consume any character.
+%
+% \medskip
+% With the following \textsc{lpeg}, a style will actually be applied to the
+% prompt (for instance, it's possible to decide to discard these prompts).
+%    \begin{macrocode}
+local Prompt = K ( 'Prompt' , ( ( P ">>>" + P "..." ) * P " " ^ -1 ) ^ -1  ) 
+%    \end{macrocode}
+%    
+%
+%
+% \bigskip
+% The following \textsc{lpeg} |EOL| is for the end of lines.
+%    \begin{macrocode}
+local EOL = 
+  P "\r" 
+  *
+  (
+    ( space^0 * -1 )
+    + 
+%    \end{macrocode}
+% We recall that each line in the Python code we have to parse will be sent
+% back to LaTeX between a pair |\@@_begin_line:| --
+% |\@@_end_line:|\footnote{Remember that the \texttt{\textbackslash
+% @@\_end\_line:} must be explicit because it will be used as marker in order to
+% delimit the argument of the command \texttt{\textbackslash @@\_begin\_line:}}.
+%    \begin{macrocode}
+    Ct ( 
+         Cc "EOL"
+         * 
+         Ct (
+              Lc "\\@@_end_line:"
+              * BeamerEndEnvironments 
+              * BeamerBeginEnvironments 
+              * PromptHastyDetection
+              * Lc "\\@@_newline: \\@@_begin_line:"
+              * Prompt
+            )
+       )
+  ) 
+  *
+  SpaceIndentation ^ 0
+%    \end{macrocode}
+%
+% 
+% \bigskip
+% \paragraph{The long strings}
+% 
+% 
+%    \begin{macrocode}
+local SingleLongString =
+  WithStyle ( 'String.Long' , 
+     ( Q ( S "fF" * P "'''" )
+         * (
+             K ( 'String.Interpol' , P "{"  )
+               * K ( 'Interpol.Inside' , ( 1 - S "}:\r" - P "'''" ) ^ 0  )
+               * Q ( P ":" * (1 - S "}:\r" - P "'''" ) ^ 0 ) ^ -1
+               * K ( 'String.Interpol' , P "}"  )
+             + 
+             Q ( ( 1 - P "'''" - S "{}'\r" ) ^ 1 )
+             + 
+             EOL
+           ) ^ 0 
+       +
+         Q ( ( S "rR" ) ^ -1  * P "'''" )
+         * (
+             Q ( ( 1 - P "'''" - S "\r%" ) ^ 1 )  
+             + 
+             PercentInterpol
+             +
+             P "%"
+             +
+             EOL
+           ) ^ 0 
+      )
+      * Q ( P "'''" ) ) 
+
+
+local DoubleLongString =
+  WithStyle ( 'String.Long' ,
+     (
+        Q ( S "fF" * P "\"\"\"" )
+        * (
+            K ( 'String.Interpol', P "{"  )
+              * K ( 'Interpol.Inside' , ( 1 - S "}:\r" - P "\"\"\"" ) ^ 0 )
+              * Q ( P ":" * (1 - S "}:\r" - P "\"\"\"" ) ^ 0 ) ^ -1
+              * K ( 'String.Interpol' , P "}"  )
+            + 
+            Q ( ( 1 - P "\"\"\"" - S "{}\"\r" ) ^ 1 ) 
+            + 
+            EOL
+          ) ^ 0 
+      +
+        Q ( ( S "rR" ) ^ -1  * P "\"\"\"" )
+        * (
+            Q ( ( 1 - P "\"\"\"" - S "%\r" ) ^ 1 )  
+            + 
+            PercentInterpol 
+            + 
+            P "%"
+            + 
+            EOL
+          ) ^ 0 
+     )
+     * Q ( P "\"\"\"" ) 
+  ) 
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+local LongString = SingleLongString + DoubleLongString
+%    \end{macrocode}
+%
+% \bigskip
+% We have a \textsc{lpeg} for the Python docstrings. That \textsc{lpeg} will
+% be used in the \textsc{lpeg} |DefFunction| which deals with the whole preamble
+% of a function definition (which begins with |def|).
+%    \begin{macrocode}
+local StringDoc = 
+    K ( 'String.Doc' , P "\"\"\"" )
+      * ( K ( 'String.Doc' , (1 - P "\"\"\"" - P "\r" ) ^ 0  ) * EOL
+          * Tab ^ 0 
+        ) ^ 0
+      * K ( 'String.Doc' , ( 1 - P "\"\"\"" - P "\r" ) ^ 0 * P "\"\"\"" )
+%    \end{macrocode}
+%
+% \bigskip
+% \paragraph{The comments in the Python listings}
+%
+% We define different \textsc{lpeg} dealing with comments in the Python
+% listings.
+%    \begin{macrocode}
+local CommentMath = 
+  P "$" * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1  ) * P "$"
+
+local Comment = 
+  WithStyle ( 'Comment' ,
+     Q ( P "#" ) 
+     * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 ) 
+  * ( EOL + -1 )
+%    \end{macrocode}
+% 
+%
+%
+% \bigskip
+% The following \textsc{lpeg} |CommentLaTeX| is for what is called in that
+% document the ``LaTeX comments''. Since the elements that will be catched must
+% be sent to LaTeX with standard LaTeX catcodes, we put the capture (done by
+% the function~|C|) in a table (by using~|Ct|, which is an alias for |lpeg.Ct|).
+%    \begin{macrocode}
+local CommentLaTeX =
+  P(piton.comment_latex) 
+  * Lc "{\\PitonStyle{Comment.LaTeX}{\\ignorespaces" 
+  * L ( ( 1 - P "\r" ) ^ 0 ) 
+  * Lc "}}" 
+  * ( EOL + -1 )  -- you could put EOL instead of EOL
+%    \end{macrocode}
+% 
+% \bigskip
+% \paragraph{DefFunction}
+%
+% 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 =
+  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 , 
+    }
+%    \end{macrocode}
+%
+% \bigskip 
+% We will now define a \textsc{lpeg} |Params| that will catch the list of
+% parameters (that is to say the \emph{argspec}) in the definition of a Python
+% function. For example, in the line of code
+% \begin{center}
+% \piton{def MyFunction(a,b,x=10,n:int): return n}
+% \end{center}
+% the \textsc{lpeg} |Params| will be used to catch the chunk\enskip |a,b,x=10,n:int|.
+% 
+% Or course, a |Params| is simply a comma-separated list of |Param|, and that's
+% why we define first the \textsc{lpeg} |Param|.
+%
+% \medskip
+%    \begin{macrocode}
+local Param = 
+  SkipSpace * Identifier * SkipSpace
+   * ( 
+         K ( 'InitialValues' , P "=" * Expression )
+       + Q ( P ":" ) * SkipSpace * K ( 'Name.Type' , letter^1  ) 
+     ) ^ -1
+%    \end{macrocode}
+% 
+% \medskip
+%    \begin{macrocode}
+local Params = ( Param * ( Q "," * Param ) ^ 0 ) ^ -1
+%    \end{macrocode}
+% 
+% \bigskip
+% The following \textsc{lpeg} |DefFunction| catches a keyword |def| and the
+% following name of function \emph{but also everything else until a potential
+% docstring}. That's why this definition of \textsc{lpeg} must occur (in the file
+% |piton.sty|) after the definition of several other \textsc{lpeg} such as
+% |Comment|, |CommentLaTeX|, |Params|, |StringDoc|...
+%    \begin{macrocode}
+local DefFunction =
+  K ( 'Keyword' , P "def" )
+  * Space
+  * K ( 'Name.Function.Internal' , identifier ) 
+  * SkipSpace 
+  * Q ( P "(" ) * Params * Q ( P ")" ) 
+  * SkipSpace
+  * ( Q ( P "->" ) * SkipSpace * K ( 'Name.Type' , identifier  ) ) ^ -1
+%    \end{macrocode}
+% Here, we need a \pkg{piton} style |ParseAgain| which will be linked to
+% |\@@_piton:n| (that means that the capture will be parsed once again by
+% \pkg{piton}). We could avoid that kind of trick by using a non-terminal of a
+% grammar but we have probably here a better legibility.
+%    \begin{macrocode}
+  * K ( 'ParseAgain' , ( 1 - S ":\r" )^0  ) 
+  * Q ( P ":" )
+  * ( SkipSpace
+      * ( EOL + CommentLaTeX + Comment ) -- in all cases, that contains an EOL
+      * Tab ^ 0 
+      * SkipSpace
+      * StringDoc ^ 0 -- there may be additionnal docstrings 
+    ) ^ -1
+%    \end{macrocode}
+% Remark that, in the previous code, |CommentLaTeX| \emph{must} appear
+% before |Comment|: there is no commutativity of the addition for the
+% \emph{parsing expression grammars} (\textsc{peg}).
+% 
+% \smallskip 
+% If the word |def| is not followed by an identifier and parenthesis, it will be
+% catched as keyword by the \textsc{lpeg} |Keyword| (useful if, for example, the
+% final user wants to speak of the keyword \piton{def}).
+%
+% \bigskip
+% \paragraph{The dictionaries of Python}
+%
+% We have \textsc{lpeg} dealing with dictionaries of Python because, in
+% typesettings of explicit Python dictionaries, one may prefer to have all the
+% values formatted in black (in order to see more clearly the keys which are
+% usually Python strings). That's why we have a \pkg{piton} style |Dict.Value|.
+%
+% The initial value of that \pkg{piton} style is |\@@_piton:n|, which means that
+% the value of the entry of the dictionary is parsed once again by \pkg{piton}
+% (and nothing special is done for the dictionary). In the following example, we
+% have set the \pkg{piton} style |Dict.Value| to |\color{black}|:
+%
+% \medskip
+% \begingroup
+% \SetPitonStyle{Dict.Value = \color{black}}
+% \piton{mydict = { 'name' : 'Paul', 'sex' : 'male', 'age' : 31 } }
+% \endgroup
+%
+% \medskip
+% At this time, this mechanism works only for explicit dictionaries on a single line!
+%
+%    \begin{macrocode}
+local ItemDict = 
+  ShortString * SkipSpace * Q ( P ":" ) * K ( 'Dict.Value' , Expression  ) 
+
+local ItemOfSet = SkipSpace * ( ItemDict + ShortString ) * SkipSpace 
+
+local Set = 
+  Q ( P "{" ) 
+  * ItemOfSet * ( Q ( P "," ) * ItemOfSet )  ^ 0 
+  * Q ( P "}" )
+%    \end{macrocode}
+%
+% \paragraph{Miscellaneous}
+% 
+%    \begin{macrocode}
+local ExceptionInConsole = Exception *  Q ( ( 1 - P "\r" ) ^ 0 ) * EOL 
+%    \end{macrocode}
+% 
+% 
+% \bigskip
+% \paragraph{The main LPEG}
+%
+% First, the main loop :
+%    \begin{macrocode}
+MainLoopPython = 
+  (  ( space^1 * -1 ) 
+     + EOL
+     + Space 
+     + Tab
+     + Escape 
+     + CommentLaTeX
+     + Beamer
+     + UserCommands 
+     + LongString 
+     + Comment
+     + ExceptionInConsole
+     + Set 
+     + Delim
+%    \end{macrocode}
+% |Operator| must be before |Punct|.
+%    \begin{macrocode}
+     + Operator
+     + ShortString
+     + Punct
+     + FromImport
+     + RaiseException 
+     + DefFunction
+     + DefClass 
+     + Keyword * ( Space + Punct + Delim + EOL+ -1 ) 
+     + Decorator
+     + OperatorWord * ( Space + Punct + Delim + EOL+ -1 ) 
+     + Builtin * ( Space + Punct + Delim + EOL+ -1 ) 
+     + Identifier 
+     + Number
+     + Word
+  ) ^ 0 
+%    \end{macrocode}
+%
+% \bigskip
+% We recall that each line in the Python code to parse will be sent back to
+% LaTeX between a pair |\@@_begin_line:| -- |\@@_end_line:|\footnote{Remember
+% that the \texttt{\textbackslash @@\_end\_line:} must be explicit because it
+% will be used as marker in order to delimit the argument of the command
+% \texttt{\textbackslash @@\_begin\_line:}}.
+%    \begin{macrocode}
+local python = P ( true ) 
+
+python =
+  Ct (
+       ( ( space - P "\r" ) ^0 * P "\r" ) ^ -1 
+       * BeamerBeginEnvironments 
+       * PromptHastyDetection
+       * Lc '\\@@_begin_line:'
+       * Prompt 
+       * SpaceIndentation ^ 0 
+       * MainLoopPython
+       * -1 
+       * Lc '\\@@_end_line:' 
+     )
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+local languages = { }
+languages['python'] = python
+%    \end{macrocode}
+%
+% % \bigskip
+% \subsubsection{The LPEG ocaml}
+% 
+%    \begin{macrocode}
+local Delim = Q ( P "[|" + P "|]" + S "[()]" )
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+local Punct = Q ( S ",:;!" )
+%    \end{macrocode}
+% 
+%    \begin{macrocode}
+local identifier = 
+  ( R "az" + R "AZ" + P "_") * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0 
+
+local Identifier = K ( 'Identifier' , identifier )
+
+local Operator = 
+  K ( 'Operator' ,
+      P "!=" + P "<>" + P "==" + P "<<" + P ">>" + P "<=" + P ">=" + P ":=" 
+      + P "||" + P "&&" + P "//" + P "**" + P ";;" + P "::" + P "->" 
+      + P "+." + P "-." + P "*." + P "/." 
+      + S "-~+/*%=<>&@|" 
+    )
+
+local OperatorWord = 
+  K ( 'Operator.Word' ,
+      P "and" + P "asr" + P "land" + P "lor" + P "lsl" + P "lxor" 
+      + P "mod" + P "or" )
+
+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 "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" 
+  + P "value" + P "val" + P "virtual" + P "when" + P "while" + P "with" )
+  + 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" )
+%    \end{macrocode}
+% 
+% \bigskip
+% The following exceptions are exceptions in the standard library of OCaml (Stdlib).
+%    \begin{macrocode}
+local Exception =
+  K (   'Exception' ,
+       P "Division_by_zero" + P "End_of_File" + P "Failure" 
+     + P "Invalid_argument" + P "Match_failure" + P "Not_found" 
+     + P "Out_of_memory" + P "Stack_overflow" + P "Sys_blocked_io" 
+     + P "Sys_error" + P "Undefined_recursive_module" )
+%    \end{macrocode}
+%
+% \bigskip
+% \paragraph{The characters in OCaml}
+%
+%    \begin{macrocode}
+local Char = 
+  K ( 'String.Short' , P "'" * ( ( 1 - P "'" ) ^ 0 + P "\\'" ) * P "'" ) 
+%    \end{macrocode}
+% 
+%
+% \bigskip
+% \paragraph{Beamer}
+%
+%    \begin{macrocode}
+local BalancedBraces =
+  P { "E" ,
+       E = 
+           (
+             P "{" * V "E" * P "}" 
+             + 
+             P "\"" * ( 1 - S "\"" ) ^ 0 * P "\""  -- OCaml strings
+             + 
+             ( 1 - S "{}" ) 
+           ) ^ 0 
+    }
+%    \end{macrocode}
+%
+% 
+%    \begin{macrocode}
+if piton_beamer 
+then
+  Beamer =
+      L  ( P "\\pause" * ( P "[" * (1 - P "]") ^ 0 * P "]" ) ^ -1 ) 
+    + 
+      (   P "\\uncover"   * Lc ( '\\@@_beamer_command:n{uncover}' ) 
+        + P "\\only"      * Lc ( '\\@@_beamer_command:n{only}' ) 
+        + P "\\alert"     * Lc ( '\\@@_beamer_command:n{alert}' ) 
+        + P "\\visible"   * Lc ( '\\@@_beamer_command:n{visible}' ) 
+        + P "\\invisible" * Lc ( '\\@@_beamer_command:n{invisible}' ) 
+        + P "\\action"    * Lc ( '\\@@_beamer_command:n{action}' ) 
+      ) 
+      *
+      L ( ( P "<" * (1 - P ">") ^ 0 * P ">" ) ^ -1 * P "{" )
+      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * L ( P "}" )
+    +  
+      L ( 
+          ( P "\\alt" )
+          * P "<" * (1 - P ">") ^ 0 * P ">" 
+          * P "{" 
+        )
+      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * L ( P "}{" )
+      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * L ( P "}" )
+    +  
+      L ( 
+          ( P "\\temporal" )
+          * P "<" * (1 - P ">") ^ 0 * P ">" 
+          * P "{" 
+        )
+      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * L ( P "}{" )
+      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * L ( P "}{" )
+      * K ( 'ParseAgain.noCR' , BalancedBraces ) 
+      * L ( P "}" )
+  BeamerBeginEnvironments = 
+      ( space ^ 0 * 
+        L 
+          ( 
+            P "\\begin{" * BeamerNamesEnvironments * "}"
+            * ( P "<" * ( 1 - P ">") ^ 0 * P ">" ) ^ -1
+          )
+        * P "\r" 
+      ) ^ 0 
+  BeamerEndEnvironments = 
+      ( space ^ 0 * 
+        L ( P "\\end{" * BeamerNamesEnvironments * P "}" ) 
+        * P "\r" 
+      ) ^ 0 
+end
+%    \end{macrocode}
+%
+% \bigskip
+% \paragraph{EOL}
+%    \begin{macrocode}
+local EOL = 
+  P "\r" 
+  *
+  (
+    ( space^0 * -1 )
+    + 
+    Ct ( 
+         Cc "EOL"
+         * 
+         Ct (
+              Lc "\\@@_end_line:"
+              * BeamerEndEnvironments 
+              * BeamerBeginEnvironments 
+              * PromptHastyDetection
+              * Lc "\\@@_newline: \\@@_begin_line:"
+              * Prompt
+            )
+       )
+  ) 
+  *
+  SpaceIndentation ^ 0
+%    \end{macrocode}
+%
+%
+%    \begin{macrocode}
+% 
+% \paragraph{The strings}
+% 
+% We need a pattern |string| without captures because it will be used within the
+% comments of OCaml.
+%    \begin{macrocode}
+local string =
+       Q ( P "\"" )
+     * ( 
+         VisualSpace
+         + 
+         Q ( ( 1 - S " \"\r" ) ^ 1 ) 
+         +  
+         EOL
+       ) ^ 0 
+     * Q ( P "\"" ) 
+%    \end{macrocode}
+% 
+%    \begin{macrocode}
+local String = WithStyle ( 'String.Long' , string ) 
+%    \end{macrocode}
+%
+% 
+% \bigskip
+% Now, the ``quoted strings'' of OCaml (for example \verb+{ext|Essai|ext}+). 
+%
+% For those strings, we will do two consecutive analysis. First an analysis to
+% determine the whole string and, then, an analysis for the potential visual
+% spaces and the EOL in the string.
+% 
+% The first analysis require a match-time capture. For explanations about that
+% programmation, see the paragraphe \emph{Lua's long % strings} in
+% |www.inf.puc-rio.br/~roberto/lpeg|. 
+%    \begin{macrocode}
+local ext = ( R "az" + P "_" ) ^ 0
+local open = "{" * Cg(ext, 'init') * "|" 
+local close = "|" * C(ext) * "}"
+local closeeq = 
+  Cmt ( close * Cb('init'), 
+        function (s, i, a, b) return a==b end ) 
+%    \end{macrocode}
+%
+% \medskip
+% The \textsc{lpeg} |QuotedStringBis| will do the second analysis. 
+%    \begin{macrocode}
+local QuotedStringBis = 
+  WithStyle ( 'String.Long' ,
+      (  
+        VisualSpace
+        +
+        Q ( ( 1 - S " \r" ) ^ 1 ) 
+        +  
+        EOL
+      ) ^ 0  ) 
+
+%    \end{macrocode}
+% 
+% \medskip
+% We use a ``function capture'' (as called in the official documentation of the
+% \textsc{lpeg}) in order to do the second analysis on the result of the first one.
+%    \begin{macrocode}
+local QuotedString = 
+   C ( open * ( 1 - closeeq ) ^ 0  * close ) /
+  ( function (s) return QuotedStringBis : match(s) end ) 
+%    \end{macrocode}
+% 
+%
+% \bigskip
+% \paragraph{The comments in the OCaml listings}
+%
+% In OCaml, the delimiters for the comments are |(*| and |*)|. There are
+% unsymmetrical and, therefore, the comments may be nested. That's why we need a
+% grammar.
+% 
+% In these comments, we embed the math comments (between |$| and |$|) and we
+% embed also a treatment for the end of lines (since the comments may be multi-lines).
+% 
+%    \begin{macrocode}
+local Comment =
+  WithStyle ( 'Comment' ,
+     P {
+         "A" ,
+         A = Q "(*"
+             * ( V "A" 
+                 + Q ( ( 1 - P "(*" - P "*)" - S "\r$\"" ) ^ 1 ) -- $
+                 + string 
+                 + P "$" * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1 ) * P "$" -- $
+                 + EOL
+               ) ^ 0 
+             * Q "*)" 
+       }   )
+%    \end{macrocode}
+% 
+% \bigskip
+% \paragraph{The DefFunction}
+%
+%    \begin{macrocode}
+local DefFunction = 
+  K ( 'Keyword' , P "let rec" + P "let" + P "and" ) 
+  * Space
+  * K ( 'Name.Function.Internal' , identifier ) 
+  * Space 
+  * # ( P "=" * space * P "function" + ( 1 - P "=" ) )
+%    \end{macrocode}
+% 
+% \bigskip
+% \paragraph{The parameters of the types}
+% 
+%    \begin{macrocode}
+local TypeParameter = K ( 'TypeParameter' , P "'" * alpha * # ( 1 - P "'" ) ) 
+%    \end{macrocode}
+% 
+% \bigskip
+% \paragraph{The main LPEG}
+%
+% First, the main loop :
+%    \begin{macrocode}
+MainLoopOCaml = 
+  (  ( space^1 * -1 ) 
+     + EOL
+     + Space 
+     + Tab
+     + Escape 
+     + Beamer 
+     + TypeParameter
+     + String + QuotedString + Char
+     + Comment
+     + Delim
+     + Operator
+     + Punct
+     + FromImport
+     + ImportAs
+     + Exception 
+     + DefFunction
+     + Keyword * ( Space + Punct + Delim + EOL + -1 ) 
+     + OperatorWord * ( Space + Punct + Delim + EOL + -1 ) 
+     + Builtin * ( Space + Punct + Delim + EOL + -1 ) 
+     + Identifier 
+     + Number
+     + Word
+  ) ^ 0 
+%    \end{macrocode}
+%
+% \bigskip
+% We recall that each line in the Python code to parse will be sent back to
+% LaTeX between a pair |\@@_begin_line:| -- |\@@_end_line:|\footnote{Remember
+% that the \texttt{\textbackslash @@\_end\_line:} must be explicit because it
+% will be used as marker in order to delimit the argument of the command
+% \texttt{\textbackslash @@\_begin\_line:}}.
+%    \begin{macrocode}
+local ocaml = P ( true ) 
+
+ocaml =
+  Ct (
+       ( ( space - P "\r" ) ^0 * P "\r" ) ^ -1 
+       * BeamerBeginEnvironments 
+       * Lc ( '\\@@_begin_line:' ) 
+       * SpaceIndentation ^ 0 
+       * MainLoopOCaml
+       * -1 
+       * Lc ( '\\@@_end_line:' )
+     )
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+languages['ocaml'] = ocaml
+%    \end{macrocode}
+% 
+% \bigskip
+% \subsubsection{The function Parse}
+%
+%
+% The function |Parse| is the main function of the package \pkg{piton}.
+% It parses its argument and sends back to LaTeX the code with interlaced
+% formatting LaTeX instructions. In fact, everything is done by the
+% \textsc{lpeg} |python| which returns as capture a Lua table containing
+% data to send to LaTeX.
+% 
+% \bigskip
+%    \begin{macrocode}
+function piton.Parse(language,code)
+  local t = languages[language] : match ( code ) 
+  local left_stack = {}
+  local right_stack = {}
+  for _ , one_item in ipairs(t) 
+  do 
+     if one_item[1] == "EOL"
+     then 
+          for _ , s in ipairs(right_stack) 
+            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 ) 
+            end
+     else 
+          if one_item[1] == "Open"
+          then
+               tex.sprint( one_item[2] ) 
+               table.insert(left_stack,one_item[2])
+               table.insert(right_stack,one_item[3])
+          else 
+               if one_item[1] == "Close"
+               then
+                    tex.sprint( right_stack[#right_stack] ) 
+                    left_stack[#left_stack] = nil
+                    right_stack[#right_stack] = nil
+               else 
+                    tex.tprint(one_item)  
+               end 
+          end 
+     end 
+  end 
+end
+%    \end{macrocode}
+%
+%    
+%
+% \bigskip
+% The function |ParseFile| will be used by the LaTeX command |\PitonInputFile|.
+% That function merely reads the whole file (that is to say all its lines) and
+% then apply the function~|Parse| to the resulting Lua string.
+%    \begin{macrocode}
+function piton.ParseFile(language,name,first_line,last_line)
+  s = ''
+  local i = 0 
+  for line in io.lines(name) 
+  do i = i + 1 
+     if i >= first_line
+     then s = s .. '\r' .. line 
+     end
+     if i >= last_line then break end 
+  end
+  piton.Parse(language,s) 
+end
+%    \end{macrocode}
+% 
+% \bigskip
+% \subsubsection{Two variants of  the function Parse with integrated preprocessors}
+%
+% The following command will be used by the user command |\piton|.
+% For that command, we have to undo the duplication of the symbols |#|.
+%    \begin{macrocode}
+function piton.ParseBis(language,code)
+  local s = ( Cs ( ( P '##' / '#' + 1 ) ^ 0 ) ) : match ( code )
+  return piton.Parse(language,s) 
+end
+%    \end{macrocode}
+%
+% \bigskip
+% The following command will be used when we have to parse some small chunks of
+% code that have yet been parsed. They are re-scanned by LaTeX because it has
+% been required by |\@@_piton:n| in the \pkg{piton} style of the syntaxic
+% element. In that case, you have to remove the potential |\@@_breakable_space:|
+% that have been inserted when the key |break-lines| is in force.
+%    \begin{macrocode}
+function piton.ParseTer(language,code)
+  local s = ( Cs ( ( P '\\@@_breakable_space:' / ' ' + 1 ) ^ 0 ) ) 
+            : match ( code )
+  return piton.Parse(language,s)
+end
+%    \end{macrocode}
+% 
+%
+% \bigskip
+% \subsubsection{Preprocessors of the function Parse for gobble}
+%
+% We deal now with preprocessors of the function |Parse| which are needed when
+% the ``gobble mechanism'' is used.
+% 
+%
+% \bigskip
+% The function |gobble| gobbles $n$ characters on the left of the code. It uses
+% a \textsc{lpeg} that we have to compute dynamically because if depends on the
+% value of~$n$.
+%    \begin{macrocode}
+local function gobble(n,code)
+  function concat(acc,new_value)
+    return acc .. new_value
+  end 
+  if n==0 
+  then return code
+  else 
+       return Cf ( 
+                   Cc ( "" ) * 
+                   ( 1 - P "\r" ) ^ (-n)  * C ( ( 1 - P "\r" ) ^ 0 ) 
+                     * ( C ( P "\r" )
+                     * ( 1 - P "\r" ) ^ (-n)
+                     * C ( ( 1 - P "\r" ) ^ 0 )
+                    ) ^ 0 ,
+                    concat 
+                 ) : match ( code ) 
+  end
+end
+%    \end{macrocode}
+%
+% 
+% 
+% \bigskip
+% The following function |add| will be used in the following \textsc{lpeg}
+% |AutoGobbleLPEG|, |TabsAutoGobbleLPEG| and |EnvGobbleLPEG|.
+%    \begin{macrocode}
+local function add(acc,new_value)
+  return acc + new_value
+end 
+%    \end{macrocode}
+% 
+% \bigskip
+% The following \textsc{lpeg} returns as capture the minimal number of spaces at
+% the beginning of the lines of code. The main work is done by two \emph{fold
+% captures} (|lpeg.Cf|), one using |add| and the other (encompassing the
+% previous one) using |math.min| as folding operator.
+%    \begin{macrocode}
+local AutoGobbleLPEG = 
+    ( space ^ 0 * P "\r" ) ^ -1 
+    * Cf (
+           (
+%    \end{macrocode}
+% We don't take into account the empty lines (with only spaces).
+%    \begin{macrocode}
+             ( P " " ) ^ 0 * P "\r"
+             + 
+             Cf ( Cc(0) * ( P " " * Cc(1) ) ^ 0 , add )
+             * ( 1 - P " " ) * ( 1 - P "\r" ) ^ 0 * P "\r"
+           ) ^ 0
+%    \end{macrocode}
+% Now for the last line of the Python code...
+%    \begin{macrocode}
+           *
+           ( Cf ( Cc(0) * ( P " " * Cc(1) ) ^ 0 , add )
+           * ( 1 - P " " ) * ( 1 - P "\r" ) ^ 0 ) ^ -1 ,
+           math.min
+         )
+%    \end{macrocode}
+%
+% \bigskip
+% The following \textsc{lpeg} is similar but works with the indentations.
+%    \begin{macrocode}
+local TabsAutoGobbleLPEG = 
+    ( space ^ 0 * P "\r" ) ^ -1 
+    * Cf (
+           (
+             ( P "\t" ) ^ 0 * P "\r"
+             + 
+             Cf ( Cc(0) * ( P "\t" * Cc(1) ) ^ 0 , add )
+             * ( 1 - P "\t" ) * ( 1 - P "\r" ) ^ 0 * P "\r"
+           ) ^ 0
+           *
+           ( Cf ( Cc(0) * ( P "\t" * Cc(1) ) ^ 0 , add )
+           * ( 1 - P "\t" ) * ( 1 - P "\r" ) ^ 0 ) ^ -1 ,
+           math.min
+         )
+%    \end{macrocode}
+% 
+%
+%
+% \bigskip
+% The following \textsc{lpeg} returns as capture the number of spaces at the
+% last line, that is to say before the |\end{Piton}| (and usually it's also the
+% number of spaces before the corresponding |\begin{Piton}| because that's the
+% traditionnal way to indent in LaTeX). The main work is done by a \emph{fold
+% capture} (|lpeg.Cf|) using the function |add| as folding operator.
+%    \begin{macrocode}
+local EnvGobbleLPEG =
+  ( ( 1 - P "\r" ) ^ 0 * P "\r" ) ^ 0 
+    * Cf ( Cc(0) * ( P " " * Cc(1) ) ^ 0 , add ) * -1
+%    \end{macrocode}
+% 
+% \bigskip
+%    \begin{macrocode}
+function piton.GobbleParse(language,n,code)
+  if n==-1 
+  then n = AutoGobbleLPEG : match(code)
+  else if n==-2 
+       then n = EnvGobbleLPEG : match(code)
+       else if n==-3
+            then n = TabsAutoGobbleLPEG : match(code)
+            end
+       end
+  end
+  piton.Parse(language,gobble(n,code))
+end 
+%    \end{macrocode}
+%
+% \bigskip
+% \subsubsection{To count the number of lines}
+%
+% \medskip
+%    \begin{macrocode}
+function piton.CountLines(code)
+  local count = 0 
+  for i in code : gmatch ( "\r" ) do count = count + 1 end 
+  tex.sprint( 
+      luatexbase.catcodetables.expl , 
+      '\\int_set:Nn \\l_@@_nb_lines_int {' .. count .. '}' )
+end 
+%    \end{macrocode}
+%
+%    \begin{macrocode}
+function piton.CountNonEmptyLines(code)
+  local count = 0 
+  count = 
+  ( Cf (  Cc(0) * 
+          ( 
+            ( P " " ) ^ 0 * P "\r"  
+            + ( 1 - P "\r" ) ^ 0 * P "\r" * Cc(1) 
+          ) ^ 0 
+          * (1 - P "\r" ) ^ 0 ,
+         add
+       ) * -1 ) : match (code) 
+  tex.sprint( 
+      luatexbase.catcodetables.expl , 
+      '\\int_set:Nn \\l_@@_nb_non_empty_lines_int {' .. count .. '}' )
+end 
+%    \end{macrocode}
+%
+% \bigskip
+%    \begin{macrocode}
+function piton.CountLinesFile(name)
+  local count = 0 
+  for line in io.lines(name) do count = count + 1 end
+  tex.sprint( 
+      luatexbase.catcodetables.expl , 
+      '\\int_set:Nn \\l_@@_nb_lines_int {' .. count .. '}' )
+end 
+%    \end{macrocode}
+%
+%
+% \bigskip
+%    \begin{macrocode}
+function piton.CountNonEmptyLinesFile(name)
+  local count = 0 
+  for line in io.lines(name) 
+  do if not ( ( ( P " " ) ^ 0 * -1 ) : match ( line ) ) 
+     then count = count + 1 
+     end
+  end
+  tex.sprint( 
+      luatexbase.catcodetables.expl , 
+      '\\int_set:Nn \\l_@@_nb_non_empty_lines_int {' .. count .. '}' )
+end 
+%    \end{macrocode}
+% 
+%    \begin{macrocode}
+\end{luacode*}
+%    \end{macrocode}
+%
+% 
+% \vspace{1cm}
+% \section{History}
+%
+% The successive versions of the file |piton.sty| provided by TeXLive are available on the
+% \textsc{svn} server of TeXLive:\par\nobreak
+%
+% \smallskip
+% {
+% \small
+% \nolinkurl{https://tug.org/svn/texlive/trunk/Master/texmf-dist/tex/lualatex/piton/piton.sty}
+% }
+%
+% % \subsection*{Changes between versions 1.4 and 1.5}
+%
+% New key |numbers-sep|.
+%
+%
+% \subsection*{Changes between versions 1.3 and 1.4}
+%
+% New key |identifiers| in |\PitonOptions|.
+%
+% New command |\PitonStyle|.
+%
+% |background-color| now accepts as value a \emph{list} of colors.
+%
+% \subsection*{Changes between versions 1.2 and 1.3}
+%
+% When the class Beamer is used, the environment |{Piton}| and the command 
+% |\PitonInputFile| are ``overlay-aware'' (that is to say, they accept a
+% specification of overlays between angular brackets).
+%
+% New key |prompt-background-color|
+%
+% It's now possible to use the command |\label| to reference a line of code in
+% an environment |{Piton}|.
+%
+% A new command |\|␣ is available in the argument of the command |\piton{...}| to
+% insert a space (otherwise, several spaces are replaced by a single space).
+% 
+% \subsection*{Changes between versions 1.1 and 1.2}
+%
+% New keys |break-lines-in-piton| and |break-lines-in-Piton|.
+% 
+% New key |show-spaces-in-string| and modification of the key |show-spaces|.
+%
+% When the class \cls{beamer} is used, the environements |{uncoverenv}|,
+% |{onlyenv}|, |{visibleenv}| and |{invisibleenv}|
+%
+%
+% \subsection*{Changes between versions 1.0 and 1.1}
+%
+% The extension \pkg{piton} detects the class \cls{beamer} and activates the
+% commands |\action|, |\alert|, |\invisible|, |\only|, |\uncover| and |\visible|
+% in the environments |{Piton}| when the class \cls{beamer} is used.
+%
+% \subsection*{Changes between versions 0.99 and 1.0}
+%
+% New key |tabs-auto-gobble|.
+% 
+% \subsection*{Changes between versions 0.95 and 0.99}
+%
+% New key |break-lines| to allow breaks of the lines of code (and other keys to
+% customize the appearance).
+%
+% \subsection*{Changes between versions 0.9 and 0.95}
+%
+% New key |show-spaces|.
+%
+% The key |left-margin| now accepts the special value |auto|.
+%
+% New key |latex-comment| at load-time and replacement of |##| by |#>|
+%
+% New key |math-comments| at load-time.
+%
+% New keys |first-line| and |last-line| for the command |\InputPitonFile|.
+%
+% \subsection*{Changes between versions 0.8 and 0.9}
+%
+% New key |tab-size|.
+%
+% Integer value for the key |splittable|.
+%
+% \subsection*{Changes between versions 0.7 and 0.8}
+% 
+% New keys |footnote| and |footnotehyper| at load-time.
+%
+% New key |left-margin|.
+% 
+% \subsection*{Changes between versions 0.6 and 0.7}
+% 
+% New keys |resume|, |splittable| and |background-color| in |\PitonOptions|.
+%
+% The file |piton.lua| has been embedded in the file |piton.sty|. That means
+% that the extension \pkg{piton} is now entirely contained in the file |piton.sty|.
+% 
+%
+%
+% \tableofcontents
+%
+% \end{document}
+% 
+%
+% Local Variables:
+% TeX-fold-mode: t
+% TeX-fold-preserve-comments: nil
+% flyspell-mode: nil
+% fill-column: 80
+% End:
+
+
+
+
+
+
-- 
cgit v1.2.3

