From dc177b2cd4ed993d65860adc66d256969c1bb6ad Mon Sep 17 00:00:00 2001
From: Norbert Preining <norbert@preining.info>
Date: Thu, 7 Mar 2024 03:01:25 +0000
Subject: CTAN sync 202403070301

---
 macros/luatex/latex/piton/piton.dtx | 2337 ++++++++++++++++-------------------
 1 file changed, 1054 insertions(+), 1283 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 b7326c2d60..fb06977b46 100644
--- a/macros/luatex/latex/piton/piton.dtx
+++ b/macros/luatex/latex/piton/piton.dtx
@@ -72,12 +72,12 @@
 % \iffalse
 %<*STY>
 % \fi
-\def\PitonFileVersion{2.6}
-\def\PitonFileDate{2024/02/27}
+\def\PitonFileVersion{2.6a}
+\def\PitonFileDate{2024/03/06}
 % \iffalse
 %</STY>
 %<*LUA>
--- Version 2.6 of 2024/02/27
+-- Version 2.6a of 2024/03/06
 %</LUA>
 %\fi
 %
@@ -372,11 +372,11 @@
 % In fact, the key |line-numbers| has several subkeys.
 % \begin{itemize}
 % \item With the key \Definition{line-numbers/skip-empty-lines}, the empty lines
-% are considered as non existent for the line numbering (if the key |/absolute|
-% is in force, the key |/skip-empty-lines| is no-op in |\PitonInputFile|). The
-% initial value of that key is |true| (and not |false|).\footnote{For the
-% language Python, the empty lines in the docstrings are taken into account (by
-% design).}
+% (which contains only spaces) are considered as non existent for the line
+% numbering (if the key |/absolute| is in force, the key |/skip-empty-lines| is
+% no-op in |\PitonInputFile|). The initial value of that key is |true| (and not
+% |false|).\footnote{For the language Python, the empty lines in the docstrings
+% are taken into account (by design).}
 % \item With the key \Definition{line-numbers/label-empty-lines}, the labels
 % (that is to say the numbers) of the empty lines are displayed. If the key
 % |/skip-empty-line| is in force, the clé |/label-empty-lines| is no-op. The
@@ -479,7 +479,9 @@
 % With the key \index{show-spaces} \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).
+% p.~\pageref{line-breaks}} is in force). By the way, one should remark that all
+% the trailing spaces (at the end of a line) are deleted by \pkg{piton}. The
+% tabulations at the beginning of the lines are represented by arrows.
 % \end{itemize}
 %
 % \bigskip
@@ -1742,7 +1744,7 @@
 % It's also possible to display these LaTeX comments in a kind of second column
 % by limiting the width of the Python code with the key |width|. In the
 % following example, we use the key |width| with the special value~|min|.
-%
+% Several compilations are required.
 %
 % \begingroup
 % \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
@@ -2282,7 +2284,7 @@
 % \midrule
 % Number & the numbers \\
 % String & the strings (between \texttt{"}) \\
-% Comment & les comments (which begins with |#|) \\
+% Comment & the comments (which begin with |#|) \\
 % Comment.LaTeX &  the comments beginning with \texttt{\#>}, which are composed by
 %   \pkg{piton} as LaTeX code (merely named ``LaTeX comments'' in this document) \\
 % \bottomrule
@@ -2583,7 +2585,8 @@
 %    \begin{macrocode}
 \@ifclassloaded { beamer } { \bool_gset_true:N \g_@@_beamer_bool } { }
 \@ifpackageloaded { beamerarticle } { \bool_gset_true:N \g_@@_beamer_bool } { }
-\bool_if:NT \g_@@_beamer_bool { \lua_now:n { piton_beamer = true } } 
+\lua_now:n { piton = piton~or~{ } }
+\bool_if:NT \g_@@_beamer_bool { \lua_now:n { piton.beamer = true } } 
 %    \end{macrocode}
 % 
 % \bigskip
@@ -2674,7 +2677,6 @@
 %    \begin{macrocode}
 \lua_now:n 
   { 
-    piton = piton~or { } 
     piton.ListCommands = lpeg.P ( false ) 
     piton.last_code = ''
     piton.last_language = ''
@@ -2948,6 +2950,22 @@
   }
 \@@_set_tab_tl:n { 4 }
 %    \end{macrocode}
+%
+% \medskip
+% When the key |show-spaces| is in force, |\l_@@_tab_tl| will be replaced by an
+% arrow by using the following command.
+%    \begin{macrocode}
+\cs_new_protected:Npn \@@_convert_tab_tl:
+  {
+    \hbox_set:Nn \l_tmpa_box { \l_@@_tab_tl }
+    \dim_set:Nn \l_tmpa_dim { \box_wd:N \l_tmpa_box }
+    \tl_set:Nn \l_@@_tab_tl 
+      { 
+        \( \mathcolor { gray } 
+             { \hbox_to_wd:nn \l_tmpa_dim { \rightarrowfill } \) } 
+      }
+  }
+%    \end{macrocode}
 % 
 % \medskip
 % The following integer corresponds to the key |gobble|.
@@ -2956,9 +2974,10 @@
 %    \end{macrocode}
 %
 % \medskip
+% The following token list will be used only for the spaces in the strings.
 %    \begin{macrocode}
 \tl_new:N \l_@@_space_tl
-\tl_set:Nn \l_@@_space_tl { ~ } 
+\tl_set_eq:NN \l_@@_space_tl \nobreakspace 
 %    \end{macrocode}
 % 
 %
@@ -3126,6 +3145,7 @@
 % Now, we add the potential number of line, the potential left margin and the
 % potential background.
 %    \begin{macrocode}
+    \tl_log:n { Contenu : #1.}
     \hbox_set:Nn \l_tmpa_box 
       { 
         \skip_horizontal:N \l_@@_left_margin_dim
@@ -3137,7 +3157,7 @@
                 && 
                 \l_@@_skip_empty_lines_bool 
               }
-              { \int_gincr:N \g_@@_visual_line_int}
+              { \int_gincr:N \g_@@_visual_line_int }
 
             \bool_if:nT
               { 
@@ -3280,9 +3300,9 @@
           { \l_@@_nb_lines_int - \g_@@_line_int } > \l_@@_splittable_int 
           {
             \egroup
-            \bool_if:NT \g_@@_footnote_bool { \end { savenotes } } 
+            \bool_if:NT \g_@@_footnote_bool { \endsavenotes } 
             \par \mode_leave_vertical: 
-            \bool_if:NT \g_@@_footnote_bool { \begin { savenotes } } 
+            \bool_if:NT \g_@@_footnote_bool { \savenotes } 
             \vtop \bgroup
           }
      }
@@ -3522,8 +3542,10 @@
 
     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      .code:n            = 
+         \bool_set_true:N \l_@@_show_spaces_bool 
+         \@@_convert_tab_tl: ,
+    show-spaces      .value_forbidden: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 ,
@@ -3683,6 +3705,12 @@
 %
 % \bigskip
 %    \begin{macrocode}
+\NewDocumentCommand { \NewPitonLanguage } { m m }
+  { \lua_now:e { piton.new_language("#1","\lua_escape:n{#2}") } }
+%    \end{macrocode}
+% 
+% \bigskip
+%    \begin{macrocode}
 \NewDocumentCommand { \piton } { }
   { \peek_meaning:NTF \bgroup \@@_piton_standard \@@_piton_verbatim }
 %    \end{macrocode}
@@ -3715,7 +3743,9 @@
       { \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.
+% U+0020 of catcode~10: thus, they become breakable by an end of line. Maybe,
+% this programmation is not very efficient but the key |break-lines-in-piton|
+% will be rarely used.
 %    \begin{macrocode}
       {
         \bool_if:NT \l_@@_break_lines_in_piton_bool
@@ -3973,7 +4003,7 @@
 %    \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.
+% or disallow page breaks. We use the technic of |token.scan_argument| for optimisation.
 %    \begin{macrocode}
             \lua_now:n { piton.CountLines(token.scan_argument()) } { ##1 }  
 %    \end{macrocode}
@@ -3988,7 +4018,7 @@
 % |\g_@@_footnote_bool| is raised when the package \pkg{piton} has been loaded
 % with the key |footnote| \emph{or} the key |footnotehyper|.
 %    \begin{macrocode}
-            \bool_if:NT \g_@@_footnote_bool { \begin { savenotes } } 
+            \bool_if:NT \g_@@_footnote_bool { \savenotes } 
 %    \end{macrocode}
 % 
 % Now, the key |write|.
@@ -4008,20 +4038,23 @@
                     \seq_gput_left:NV \g_@@_write_seq \l_@@_write_str
                   }
               }  
-            \vbox \bgroup 
+            \vtop \bgroup % modified 2024/03/02
+%    \end{macrocode}
+% Now, the main job. We use |token.scan_argument()| for optimisation.
+%    \begin{macrocode}
             \lua_now:e 
               { 
                 piton.GobbleParse
                   ( 
                     '\l_piton_language_str' , 
-                    \int_use:N \l_@@_gobble_int , 
-                    token.scan_argument() 
+                    \int_use:N \l_@@_gobble_int ,
+                    token.scan_argument ( )
                   ) 
               } 
               { ##1 }
             \vspace { 2.5 pt } 
             \egroup
-            \bool_if:NT \g_@@_footnote_bool { \end { savenotes } } 
+            \bool_if:NT \g_@@_footnote_bool { \endsavenotes } 
 %    \end{macrocode}
 % If the user has used the key |width| with the special value~|min|, we write on
 % the |aux| file the value of |\l_@@_line_width_dim| (largest width of the lines
@@ -4075,15 +4108,15 @@
 % Now, we define the environment |{Piton}|, which is the main environment
 % provided by the package \pkg{piton}. Of course, you use
 % |\NewPitonEnvironment|. 
-%    \begin{macrocode}
+%    \begin{macrocode} 
 \bool_if:NTF \g_@@_beamer_bool
   {
     \NewPitonEnvironment { Piton } { d < > O { } }
       { 
         \keys_set:nn { PitonOptions } { #2 } 
-        \IfValueTF { #1 }
-          { \begin { uncoverenv } < #1 > }
+        \tl_if_novalue:nTF { #1 }
           { \begin { uncoverenv } }
+          { \begin { uncoverenv } < #1 > }
       }
       { \end { uncoverenv } } 
   }
@@ -4116,7 +4149,8 @@
   }
 %    \end{macrocode}
 %
-% The following command uses as implicit argument the name of the file in |\l_@@_file_name_str|.
+% The following command uses as implicit argument the name of the file in
+% |\l_@@_file_name_str|. 
 %    \begin{macrocode}
 \cs_new_protected:Npn \@@_input_file:nn #1 #2 
   {
@@ -4185,7 +4219,7 @@
 % stored by Lua in |\l_@@_nb_lines_int|. That information will be used to allow
 % or disallow page breaks.
 %    \begin{macrocode}
-      \lua_now:e { piton.CountLinesFile('\l_@@_file_name_str') } 
+      \lua_now:e { piton.CountLinesFile ( '\l_@@_file_name_str' ) } 
 %    \end{macrocode}
 % The first argument of the following function is the name of the Lua function
 % that will be applied to the second argument in order to count the number of lines.
@@ -4193,7 +4227,7 @@
       \@@_compute_left_margin:no { CountNonEmptyLinesFile } \l_@@_file_name_str
       \@@_compute_width:
       \ttfamily
-      \bool_if:NT \g_@@_footnote_bool { \begin { savenotes } } 
+      \bool_if:NT \g_@@_footnote_bool { \savenotes } 
       \vtop \bgroup 
       \lua_now:e
         { 
@@ -4204,7 +4238,7 @@
            \int_use:N \l_@@_last_line_int ) 
         } 
       \egroup 
-      \bool_if:NT \g_@@_footnote_bool { \end { savenotes } } 
+      \bool_if:NT \g_@@_footnote_bool { \endsavenotes } 
       \bool_if:NT \l_@@_width_min_bool \@@_width_to_aux:
     \group_end:
 %    \end{macrocode}
@@ -4433,7 +4467,7 @@
 \NewDocumentCommand { \SetPitonIdentifier } { o m m } 
   { 
     \clist_set:Nn \l_tmpa_clist { #2 }
-    \IfNoValueTF { #1 }
+    \tl_if_novalue:nTF { #1 }
       { 
         \clist_map_inline:Nn \l_tmpa_clist 
           { \cs_set:cpn { pitonIdentifier _ ##1 } { #3 } }
@@ -4680,18 +4714,13 @@
 %   \begin{macrocode}
 \@@_msg_new:nn { syntax~error }
   {
-    Your~code~of~the~language~"\l_piton_language_str"~is~not~syntactically~correct.\\ 
+    Your~code~of~the~language~"\l_piton_language_str"~is~not~
+    syntactically~correct.\\  
     It~won't~be~printed~in~the~PDF~file.
   }
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\NewDocumentCommand \PitonSyntaxError { }
-  { \@@_error:n { syntax~error } }
-%    \end{macrocode}
-%
-%
-%    \begin{macrocode}
 \@@_msg_new:nn { begin~marker~not~found }
   {
     Marker~not~found.\\
@@ -4713,13 +4742,6 @@
   }
 %    \end{macrocode}
 % 
-%
-%    \begin{macrocode}
-\NewDocumentCommand \PitonBeginMarkerNotFound { } 
-  { \@@_error:n { begin~marker~not~found } }
-\NewDocumentCommand \PitonEndMarkerNotFound { } 
-  { \@@_error:n { end~marker~not~found } }
-%    \end{macrocode}
 % 
 %    \begin{macrocode}
 \@@_msg_new:nn { Unknown~file }
@@ -4832,7 +4854,7 @@
           end
     local my_lpeg = 
       P {  "E" ,
-           E = ( V "F" * ( P "," * V "F" ) ^ 0 ) / add ,
+           E = ( V "F" * ( "," * V "F" ) ^ 0 ) / add ,
            F = space ^ 0 * ( alpha ^ 1 ) / "\\%0" * space ^ 0 
         }
     function piton.addListCommands( key_value )
@@ -4880,7 +4902,7 @@ end
 % 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 Cs , Cg , Cmt , Cb = lpeg.Cs, lpeg.Cg , lpeg.Cmt , lpeg.Cb
+local Cs , Cg , Cmt , Cb = lpeg.Cs, lpeg.Cg , lpeg.Cmt , lpeg.Cb 
 local R = lpeg.R
 %    \end{macrocode}
 %
@@ -4893,7 +4915,7 @@ local R = lpeg.R
 % of the Python listings that \pkg{piton} will typeset verbatim (thanks to the
 % catcode ``other''). 
 %    \begin{macrocode}
-local function Q(pattern)
+local function Q ( pattern )
   return Ct ( Cc ( luatexbase.catcodetables.CatcodeTableOther ) * C ( pattern ) )
 end 
 %    \end{macrocode}
@@ -4907,7 +4929,7 @@ end
 % comments'' in the environments |{Piton}| and the elements beetween 
 % |begin-escape| and |end-escape|. That function won't be much used.
 %    \begin{macrocode}
-local function L(pattern)
+local function L ( pattern )
   return Ct ( C ( pattern ) ) 
 end
 %    \end{macrocode}
@@ -4920,7 +4942,7 @@ end
 % 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)
+local function Lc ( string )
   return Cc ( { luatexbase.catcodetables.expl , string } ) 
 end 
 %    \end{macrocode}
@@ -4932,12 +4954,12 @@ end
 % 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)
+%    \begin{macrocode}e
+local function K ( style , pattern )
   return
      Lc ( "{\\PitonStyle{" .. style .. "}{" )
      * Q ( pattern )
-     * Lc ( "}}" )
+     * Lc "}}"
 end
 %    \end{macrocode}
 % The formatting commands in a given \pkg{piton} style (eg. the style |Keyword|)
@@ -4951,7 +4973,7 @@ end
 % The following function |WithStyle| is similar to the function |K| but should
 % be used for multi-lines elements. 
 %    \begin{macrocode}
-local function WithStyle(style,pattern)
+local function WithStyle ( style , pattern )
   return 
        Ct ( Cc "Open" * Cc ( "{\\PitonStyle{" .. style .. "}{" ) * Cc "}}" ) 
      * pattern 
@@ -4968,17 +4990,17 @@ EscapeClean = P ( false )
 if piton.begin_escape ~= nil
 then 
   Escape = 
-    P(piton.begin_escape)
-    * L ( ( 1 - P(piton.end_escape) ) ^ 1 ) 
-    * P(piton.end_escape)
+    P ( piton.begin_escape )
+    * L ( ( 1 - P ( piton.end_escape ) ) ^ 1 ) 
+    * P ( piton.end_escape )
 %    \end{macrocode}
 % The LPEG |EscapeClean| will be used in the LPEG Clean (and that LPEG is used
 % to ``clean'' the code by removing the formatting elements).
 %    \begin{macrocode}
   EscapeClean = 
-    P(piton.begin_escape)
-    * ( 1 - P(piton.end_escape) ) ^ 1 
-    * P(piton.end_escape)
+    P ( piton.begin_escape )
+    * ( 1 - P ( piton.end_escape ) ) ^ 1 
+    * P ( piton.end_escape )
 end
 %    \end{macrocode}
 % 
@@ -4987,11 +5009,11 @@ EscapeMath = P ( false )
 if piton.begin_escape_math ~= nil
 then 
   EscapeMath = 
-    P(piton.begin_escape_math)
-    * Lc ( "\\ensuremath{" ) 
+    P ( piton.begin_escape_math )
+    * Lc "\\ensuremath{" 
     * L ( ( 1 - P(piton.end_escape_math) ) ^ 1 )
     * Lc ( "}" ) 
-    * P(piton.end_escape_math)
+    * P ( piton.end_escape_math )
 end
 %    \end{macrocode}
 % 
@@ -5005,7 +5027,7 @@ lpeg.locale(lpeg)
 % \paragraph{The basic syntactic LPEG}
 %
 %    \begin{macrocode}
-local alpha, digit = lpeg.alpha, lpeg.digit
+local alpha , digit = lpeg.alpha , lpeg.digit
 local space = P " " 
 %    \end{macrocode}
 %
@@ -5013,10 +5035,9 @@ local space = P " "
 % |ç|, 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 letter = alpha + "_" + "â" + "à" + "ç" + "é" + "è" + "ê" + "ë" + "ï" + "î"
+                    + "ô" + "û" + "ü" + "Â" + "À" + "Ç" + "É" + "È" + "Ê" + "Ë"
+                    + "Ï" + "Î" + "Ô" + "Û" + "Ü"
 
 local alphanum = letter + digit
 %    \end{macrocode}
@@ -5052,9 +5073,11 @@ local Identifier = K ( 'Identifier' , identifier )
 %    \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 
+      ( digit ^ 1 * P "." * # ( 1 - P "." ) * digit ^ 0 
+        + digit ^ 0 * P "." * digit ^ 1 
+        + digit ^ 1 )
+      * ( S "eE" * S "+-" ^ -1 * digit ^ 1 ) ^ -1
+      + digit ^ 1 
     ) 
 %    \end{macrocode}
 %
@@ -5064,7 +5087,7 @@ local Number =
 %    \begin{macrocode}
 local Word
 if piton.begin_escape ~= nil 
-then Word = Q ( ( ( 1 - space - P(piton.begin_escape) - P(piton.end_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
@@ -5072,21 +5095,20 @@ end
 %
 % \bigskip
 %    \begin{macrocode}
-local Space = ( Q " " ) ^ 1
+local Space = Q " " ^ 1
 
-local SkipSpace = ( Q " " ) ^ 0 
+local SkipSpace = Q " " ^ 0 
 
 local Punct = Q ( S ".,:;!" )
 
-local Tab = P "\t" * Lc ( '\\l_@@_tab_tl' )
+local Tab = "\t" * Lc "\\l_@@_tab_tl"
 %    \end{macrocode}
 % 
 % \bigskip
 %    \begin{macrocode}
-local SpaceIndentation = Lc ( '\\@@_an_indentation_space:' ) * ( Q " " )
+local SpaceIndentation = Lc "\\@@_an_indentation_space:" * Q " "
 %    \end{macrocode}
 %
-%
 % \bigskip
 %    \begin{macrocode}
 local Delim = Q ( S "[({})]" )
@@ -5101,7 +5123,70 @@ local Delim = Q ( S "[({})]" )
 %    \begin{macrocode}
 local VisualSpace = space * Lc "\\l_@@_space_tl" 
 %    \end{macrocode}
+%
+% \bigskip
+% \paragraph{Several tools for the construction of the main LPEG}
+%
+%    \begin{macrocode}
+local LPEG1 = { }
+local LPEG2 = { }
+local LPEG_cleaner = { }
+%    \end{macrocode}
+%
+% \bigskip
+% For each language, we will need a pattern to match expressions with balanced
+% braces. Those balanced braces must \emph{not} take into account the braces
+% present in strings of the language. However, the syntax for the strings is
+% language-dependent. That's why we write a Lua function |Compute_braces| which
+% will compute the pattern by taking in as argument a pattern for the strings of
+% the language (at least the shorts strings).
+%    \begin{macrocode}
+local function Compute_braces ( lpeg_string ) return 
+    P { "E" ,
+         E = 
+             (
+               P "{" * V "E" * P "}" 
+               + 
+               lpeg_string
+               + 
+               ( 1 - S "{}" ) 
+             ) ^ 0 
+      }
+end 
+%    \end{macrocode}
+%
+% \bigskip
+% The following Lua function will compute the \text{lpeg} |DetectedCommands|
+% which is a \textsc{lpeg} with captures).
+%    \begin{macrocode}
+local function Compute_DetectedCommands ( lang , braces ) return 
+  Ct ( Cc "Open" 
+        * C ( piton.ListCommands * P "{" ) 
+        * Cc "}" 
+     ) 
+   * ( braces / (function ( s ) return LPEG1[lang] : match ( s ) end ) )
+   * P "}" 
+   * Ct ( Cc "Close" ) 
+end
+%    \end{macrocode}
+%
+% \bigskip
+%    \begin{macrocode}
+local function Compute_LPEG_cleaner ( lang , braces ) return 
+  Ct ( ( piton.ListCommands * P "{" 
+          * (  braces 
+              / ( function ( s ) return LPEG_cleaner[lang] : match ( s ) end ) )
+          * P "}" 
+         + EscapeClean
+         +  C ( P ( 1 ) )
+        ) ^ 0 ) / table.concat 
+end
+%    \end{macrocode}
 % 
+%
+% \bigskip
+% \paragraph{Constructions for Beamer}
+%
 % \bigskip
 % If the classe Beamer is used, some environemnts and commands of Beamer are
 % automatically detected in the listings of \pkg{piton}.
@@ -5109,67 +5194,210 @@ local VisualSpace = space * Lc "\\l_@@_space_tl"
 local Beamer = P ( false ) 
 local BeamerBeginEnvironments = P ( true ) 
 local BeamerEndEnvironments = P ( true ) 
-if piton_beamer 
-then
-% \bigskip
-% The following function will return a \textsc{lpeg} which will catch an
-% environment of Beamer (supported by \pkg{piton}), that is to say |{uncover}|,
-% |{only}|, etc.
-%    \begin{macrocode}
-  local BeamerNamesEnvironments =  
-    P "uncoverenv" + P "onlyenv" + P "visibleenv" + P "invisibleenv" 
-    + P "alertenv" + P "actionenv"
-  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{macrocode}
 %
+% \bigskip
+%    \begin{macrocode}
+local list_beamer_env =
+  { "uncoverenv" , "onlyenv" , "visibleenv" , "invisibleenv" , "alertenv" , "actionenv" }
+%    \end{macrocode}
+%
+% \bigskip
+%    \begin{macrocode}
+local BeamerNamesEnvironments = P ( false ) 
+for _ , x in ipairs ( list_beamer_env ) do
+  BeamerNamesEnvironments = BeamerNamesEnvironments + x 
+end 
+%    \end{macrocode}
+%
+% \bigskip
+%    \begin{macrocode}
+BeamerBeginEnvironments = 
+    ( space ^ 0 * 
+      L 
+        ( 
+          P "\\begin{" * BeamerNamesEnvironments * "}"
+          * ( P "<" * ( 1 - P ">" ) ^ 0 * P ">" ) ^ -1
+        )
+      * P "\r" 
+    ) ^ 0 
+%    \end{macrocode}
+%
+% \bigskip
+%    \begin{macrocode}
+BeamerEndEnvironments = 
+    ( space ^ 0 * 
+      L ( P "\\end{" * BeamerNamesEnvironments * P "}" ) 
+      * P "\r" 
+    ) ^ 0 
+%    \end{macrocode}
+%
+% 
+% \bigskip
+% The following Lua function will be used to compute the \textsc{lpeg} |Beamer|
+% for each informatic language.
+%    \begin{macrocode}
+local function Compute_Beamer ( lang , braces ) 
+%    \end{macrocode}
+%
+% \bigskip
+% We will compute in |lpeg| the \textsc{lpeg} that we will return.
+%    \begin{macrocode}
+  local lpeg = L ( P "\\pause" * ( P "[" * ( 1 - P "]" ) ^ 0 * P "]" ) ^ -1 ) 
+  lpeg = lpeg + 
+      Ct ( Cc "Open" 
+            * C ( ( P "\\uncover" + "\\only" + "\\alert" + "\\visible"
+                    + "\\invisible" + "\\action" ) 
+                  * ( P "<" * ( 1 - P ">" ) ^ 0 * P ">" ) ^ -1 
+                  * P "{" 
+                ) 
+            * Cc "}" 
+         ) 
+       * ( braces / ( function ( s ) return LPEG1[lang] : match ( s ) end ) )
+       * P "}" 
+       * Ct ( Cc "Close" ) 
+%    \end{macrocode}
 % 
+%
+% \bigskip
+% For the command |\\alt|, the specification of the overlays (between angular
+% brackets) is mandatory. 
+%    \begin{macrocode}
+  lpeg = lpeg +
+    L ( P "\\alt" * P "<" * ( 1 - P ">" ) ^ 0 * P ">" * P "{" )
+     * K ( 'ParseAgain.noCR' , braces ) 
+     * L ( P "}{" )
+     * K ( 'ParseAgain.noCR' , braces ) 
+     * L ( P "}" )
+%    \end{macrocode}
+%
+% \bigskip
+% For |\\temporal|, the specification of the overlays (between angular brackets) is mandatory.
+%    \begin{macrocode}
+  lpeg = lpeg +
+      L ( ( P "\\temporal" ) * P "<" * ( 1 - P ">" ) ^ 0 * P ">" * P "{" )
+      * K ( 'ParseAgain.noCR' , braces ) 
+      * L ( P "}{" )
+      * K ( 'ParseAgain.noCR' , braces ) 
+      * L ( P "}{" )
+      * K ( 'ParseAgain.noCR' , braces ) 
+      * L ( P "}" )
+%    \end{macrocode}
+%
 % \bigskip
-% The following function will return a \textsc{lpeg} which will catch an
-% environment of Beamer (supported by \pkg{piton}), that is to say
-% |{uncoverenv}|, etc. The argument |lpeg| should be |MainLoopPython|,
-% |MainLoopC|, etc. 
+% Now, the environments of Beamer.
 %    \begin{macrocode}
-  function OneBeamerEnvironment(name,lpeg)
-    return 
+  for _ , x in ipairs ( list_beamer_env ) do
+  lpeg = lpeg + 
         Ct ( Cc "Open" 
-              * C ( 
-                    P ( "\\begin{" .. name ..   "}" )
+             * C ( 
+                    P ( "\\begin{" .. x .. "}" )
                     * ( P "<" * ( 1 - P ">") ^ 0 * P ">" ) ^ -1 
                   ) 
-             * Cc ( "\\end{" .. name ..  "}" )
+             * Cc ( "\\end{" .. x ..  "}" )
             ) 
-       * ( 
-           ( ( 1 - P ( "\\end{" .. name .. "}" ) ) ^ 0 ) 
-              / ( function (s) return lpeg : match(s) end ) 
-         )
-       * P ( "\\end{" .. name ..  "}" ) * Ct ( Cc "Close" ) 
+        * ( 
+            ( ( 1 - P ( "\\end{" .. x .. "}" ) ) ^ 0 ) 
+                / ( function ( s ) return LPEG1[lang] : match ( s ) end ) 
+          )
+        * P ( "\\end{" .. x .. "}" ) 
+        * Ct ( Cc "Close" ) 
   end 
+%    \end{macrocode}
+%
+% \bigskip
+% Now, you can return the value we have computed.
+%    \begin{macrocode}
+  return lpeg 
 end
 %    \end{macrocode}
+%
 % 
+% \bigskip
+% The following LPEG is in relation with the key |math-comments|. It will be
+% used in all the languages.
+%    \begin{macrocode}
+local CommentMath = 
+  P "$" * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1  ) * P "$" -- $
+%    \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 ">>>" + "..." ) * 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 " " ^ -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 * # ( 1 - S " \r" ) ) ^ -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 languages = { }
-local CleanLPEGs = { }
+local CommentLaTeX =
+  P(piton.comment_latex) 
+  * Lc "{\\PitonStyle{Comment.LaTeX}{\\ignorespaces" 
+  * L ( ( 1 - P "\r" ) ^ 0 ) 
+  * Lc "}}" 
+  * ( EOL + -1 )  
 %    \end{macrocode}
 % 
+%
+% 
 % \bigskip
-% \subsubsection{The LPEG python}
+% \subsubsection{The language Python}
 % 
 % \bigskip
 % Some strings of length 2 are explicit because we want the corresponding
@@ -5177,63 +5405,59 @@ local CleanLPEGs = { }
 %    \begin{macrocode}
 local Operator = 
   K ( 'Operator' ,
-      P "!=" + P "<>" + P "==" + P "<<" + P ">>" + P "<=" + P ">=" + P ":=" 
-      + P "//" + P "**" + S "-~+/*%=<>&.@|" 
-    )
+      P "!=" + "<>" + "==" + "<<" + ">>" + "<=" + ">=" + ":=" + "//" + "**" 
+      + S "-~+/*%=<>&.@|" )
 
 local OperatorWord = 
-  K ( 'Operator.Word' , P "in" + P "is" + P "and" + P "or" + P "not" )
+  K ( 'Operator.Word' , P "in" + "is" + "and" + "or" + "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" ) 
+      P "as" + "assert" + "break" + "case" + "class" + "continue" + "def" +
+      "del" + "elif" + "else" + "except" + "exec" + "finally" + "for" + "from" +
+      "global" + "if" + "import" + "lambda" + "non local" + "pass" + "return" +
+      "try" + "while" + "with" + "yield" + "yield from" )
+  + K ( 'Keyword.Constant' , P "True" + "False" + "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" )
+      P "__import__" + "abs" + "all" + "any" + "bin" + "bool" + "bytearray" +
+      "bytes" + "chr" + "classmethod" + "compile" + "complex" + "delattr" +
+      "dict" + "dir" + "divmod" + "enumerate" + "eval" + "filter" + "float" +
+      "format" + "frozenset" + "getattr" + "globals" + "hasattr" + "hash" +
+      "hex" + "id" + "input" + "int" + "isinstance" + "issubclass" + "iter" +
+      "len" + "list" + "locals" + "map" + "max" + "memoryview" + "min" + "next"
+      + "object" + "oct" + "open" + "ord" + "pow" + "print" + "property" +
+      "range" + "repr" + "reversed" + "round" + "set" + "setattr" + "slice" +
+      "sorted" + "staticmethod" + "str" + "sum" + "super" + "tuple" + "type" +
+      "vars" + "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" )
+      P "ArithmeticError" + "AssertionError" + "AttributeError" +
+      "BaseException" + "BufferError" + "BytesWarning" + "DeprecationWarning" +
+      "EOFError" + "EnvironmentError" + "Exception" + "FloatingPointError" +
+      "FutureWarning" + "GeneratorExit" + "IOError" + "ImportError" +
+      "ImportWarning" + "IndentationError" + "IndexError" + "KeyError" +
+      "KeyboardInterrupt" + "LookupError" + "MemoryError" + "NameError" +
+      "NotImplementedError" + "OSError" + "OverflowError" +
+      "PendingDeprecationWarning" + "ReferenceError" + "ResourceWarning" +
+      "RuntimeError" + "RuntimeWarning" + "StopIteration" + "SyntaxError" +
+      "SyntaxWarning" + "SystemError" + "SystemExit" + "TabError" + "TypeError"
+      + "UnboundLocalError" + "UnicodeDecodeError" + "UnicodeEncodeError" +
+      "UnicodeError" + "UnicodeTranslateError" + "UnicodeWarning" +
+      "UserWarning" + "ValueError" + "VMSError" + "Warning" + "WindowsError" +
+      "ZeroDivisionError" + "BlockingIOError" + "ChildProcessError" +
+      "ConnectionError" + "BrokenPipeError" + "ConnectionAbortedError" +
+      "ConnectionRefusedError" + "ConnectionResetError" + "FileExistsError" +
+      "FileNotFoundError" + "InterruptedError" + "IsADirectoryError" +
+      "NotADirectoryError" + "PermissionError" + "ProcessLookupError" +
+      "TimeoutError" + "StopAsyncIteration" + "ModuleNotFoundError" +
+      "RecursionError" ) 
 
 
-local RaiseException = K ( 'Keyword' , P "raise" ) * SkipSpace * Exception * Q ( P "(" ) 
+local RaiseException = K ( 'Keyword' , P "raise" ) * SkipSpace * Exception * Q "("  
 
 %    \end{macrocode}
 %
@@ -5241,7 +5465,7 @@ local RaiseException = K ( 'Keyword' , P "raise" ) * SkipSpace * Exception * Q (
 % 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  ) 
+local Decorator = K ( 'Name.Decorator' , P "@" * letter ^ 1  ) 
 %    \end{macrocode}
 % 
 % \bigskip
@@ -5253,7 +5477,7 @@ local Decorator = K ( 'Name.Decorator' , P "@" * letter^1  )
 % Example:\enskip \piton{class myclass:}
 %    \begin{macrocode}
 local DefClass = 
-  K ( 'Keyword' , P "class" ) * Space * K ( 'Name.Class' , identifier ) 
+  K ( 'Keyword' , "class" ) * Space * K ( 'Name.Class' , identifier ) 
 %    \end{macrocode}
 % 
 % If the word |class| is not followed by a identifier, it will be catched as
@@ -5277,15 +5501,14 @@ local DefClass =
 % Example:\enskip \piton{import math, numpy}
 %    \begin{macrocode}
 local ImportAs = 
-  K ( 'Keyword' , P "import" )
+  K ( 'Keyword' , "import" )
    * Space 
-   * K ( 'Name.Namespace' , 
-         identifier * ( P "." * identifier ) ^ 0 )
+   * K ( 'Name.Namespace' , identifier * ( "." * identifier ) ^ 0 )
    * ( 
-       ( Space * K ( 'Keyword' , P "as" ) * Space 
+       ( Space * K ( 'Keyword' , "as" ) * Space 
           * K ( 'Name.Namespace' , identifier ) )
        + 
-       ( SkipSpace * Q ( P "," ) * SkipSpace 
+       ( SkipSpace * Q "," * SkipSpace 
           * K ( 'Name.Namespace' , identifier ) ) ^ 0 
      ) 
 %    \end{macrocode}
@@ -5304,9 +5527,9 @@ local ImportAs =
 % \smallskip
 %    \begin{macrocode}
 local FromImport =
-  K ( 'Keyword' , P "from" ) 
+  K ( 'Keyword' , "from" ) 
     * Space * K ( 'Name.Namespace' , identifier )
-    * Space * K ( 'Keyword' , P "import" ) 
+    * Space * K ( 'Keyword' , "import" ) 
 %    \end{macrocode}
 %
 % \bigskip
@@ -5349,7 +5572,7 @@ local PercentInterpol =
       * ( P "(" * alphanum ^ 1 * P ")" ) ^ -1 
       * ( S "-#0 +" ) ^ 0 
       * ( digit ^ 1 + P "*" ) ^ -1 
-      * ( P "." * ( digit ^ 1 + P "*" ) ) ^ -1 
+      * ( "." * ( digit ^ 1 + "*" ) ) ^ -1 
       * ( S "HlL" ) ^ -1
       * S "sdfFeExXorgiGauc%" 
     ) 
@@ -5368,53 +5591,52 @@ local SingleShortString =
 %    \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'" ) 
+         Q ( P "f'" + "F'" ) 
          * ( 
-             K ( 'String.Interpol' , P "{" )
+             K ( 'String.Interpol' , "{" )
               * K ( 'Interpol.Inside' , ( 1 - S "}':" ) ^ 0  )
-              * Q ( P ":" * (1 - S "}:'") ^ 0 ) ^ -1
-              * K ( 'String.Interpol' , P "}" )
+              * Q ( P ":" * ( 1 - S "}:'" ) ^ 0 ) ^ -1
+              * K ( 'String.Interpol' , "}" )
              + 
              VisualSpace 
              + 
-             Q ( ( P "\\'" + P "{{" + P "}}" + 1 - S " {}'" ) ^ 1 )
+             Q ( ( P "\\'" + "{{" + "}}" + 1 - S " {}'" ) ^ 1 )
            ) ^ 0 
-         * Q ( P "'" )
+         * Q "'" 
        + 
 %    \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 "'" + "r'" + "R'" ) 
          * ( Q ( ( P "\\'" + 1 - S " '\r%" ) ^ 1 ) 
              + VisualSpace 
              + PercentInterpol 
-             + Q ( P "%" ) 
+             + Q "%" 
            ) ^ 0 
-         * Q ( P "'" ) )
-
+         * Q "'" )
 
 local DoubleShortString =
   WithStyle ( 'String.Short' , 
-         Q ( P "f\"" + P "F\"" ) 
+         Q ( P "f\"" + "F\"" ) 
          * ( 
-             K ( 'String.Interpol' , P "{" )
+             K ( 'String.Interpol' , "{" )
                * K ( 'Interpol.Inside' , ( 1 - S "}\":" ) ^ 0 )
-               * ( K ( 'String.Interpol' , P ":" ) * Q ( (1 - S "}:\"") ^ 0 ) ) ^ -1
-               * K ( 'String.Interpol' , P "}" )
+               * ( K ( 'String.Interpol' , ":" ) * Q ( (1 - S "}:\"") ^ 0 ) ) ^ -1
+               * K ( 'String.Interpol' , "}" )
              + 
              VisualSpace 
              + 
-             Q ( ( P "\\\"" + P "{{" + P "}}" + 1 - S " {}\"" ) ^ 1 ) 
+             Q ( ( P "\\\"" + "{{" + "}}" + 1 - S " {}\"" ) ^ 1 ) 
             ) ^ 0
-         * Q ( P "\"" )
+         * Q "\"" 
        +
-         Q ( P "\"" + P "r\"" + P "R\"" ) 
+         Q ( P "\"" + "r\"" + "R\"" ) 
          * ( Q ( ( P "\\\"" + 1 - S " \"\r%" ) ^ 1 ) 
              + VisualSpace 
              + PercentInterpol 
-             + Q ( P "%" ) 
+             + Q "%"
            ) ^ 0 
-         * Q ( P "\"" ) )
+         * Q "\""  )
 
 local ShortString = SingleShortString + DoubleShortString
 %    \end{macrocode}
@@ -5422,190 +5644,46 @@ local ShortString = SingleShortString + DoubleShortString
 % \bigskip
 % \paragraph{Beamer}
 %
-% The following pattern |balanced_braces| will be used for the (mandatory)
-% argument of the commands |\only| and \emph{al.} of Beamer. It's necessary to
-% use a \emph{grammar} because that pattern mainly checks the correct nesting of
-% the delimiters (and it's known in the theory of formal languages that this
-% can't be done with regular expressions \emph{stricto sensu} only).
-%    \begin{macrocode}
-local balanced_braces =
-  P { "E" ,
-       E = 
-           (
-             P "{" * V "E" * P "}" 
-             + 
-             ShortString  
-             + 
-             ( 1 - S "{}" ) 
-           ) ^ 0 
-    }
-%    \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 "}" 
-         ) 
-       * ( balanced_braces / (function (s) return MainLoopPython:match(s) end ) )
-       * P "}" * Ct ( Cc "Close" ) 
-    + OneBeamerEnvironment ( "uncoverenv" , MainLoopPython ) 
-    + OneBeamerEnvironment ( "onlyenv" , MainLoopPython ) 
-    + OneBeamerEnvironment ( "visibleenv" , MainLoopPython )
-    + OneBeamerEnvironment ( "invisibleenv" , MainLoopPython ) 
-    + OneBeamerEnvironment ( "alertenv" , MainLoopPython ) 
-    + OneBeamerEnvironment ( "actionenv" , MainLoopPython ) 
-    +
-      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' , balanced_braces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}" )
-    +  
-      L ( 
-%    \end{macrocode}
-% For |\\temporal|, the specification of the overlays (between angular brackets) is mandatory.
 %    \begin{macrocode}
-          ( P "\\temporal" )
-          * P "<" * (1 - P ">") ^ 0 * P ">" 
-          * P "{" 
-        )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}" )
-end
+local braces = Compute_braces ( ShortString ) 
+if piton.beamer then Beamer = Compute_Beamer ( 'python' , braces ) end
 %    \end{macrocode}
 %
 % \bigskip
 % \paragraph{Detected commands}
 %
 %    \begin{macrocode}
-DetectedCommands = 
-      Ct ( Cc "Open" 
-            * C ( piton.ListCommands * P "{" ) 
-            * Cc "}" 
-         ) 
-       * ( balanced_braces / (function (s) return MainLoopPython:match(s) end ) )
-       * P "}" * Ct ( Cc "Close" ) 
+DetectedCommands = Compute_DetectedCommands ( 'python' , braces ) 
 %    \end{macrocode}
 %
 % \bigskip
 %
-% \paragraph{The LPEG Clean}
+% \paragraph{LPEG_cleaner}
 %
 %    \begin{macrocode}
-CleanLPEGs['python']
-      = Ct ( ( piton.ListCommands * P "{" 
-                * (  balanced_braces 
-                    / ( function (s) return CleanLPEGs['python']:match(s) end ) )
-                * P "}" 
-               + EscapeClean
-               +  C ( P ( 1 ) )
-              ) ^ 0 ) / table.concat 
+LPEG_cleaner['python'] = Compute_LPEG_cleaner ( 'python' , braces ) 
 %    \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}
-% 
-% 
+% \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 "}"  )
+             K ( 'String.Interpol' , "{" )
+               * K ( 'Interpol.Inside' , ( 1 - S "}:\r" - "'''" ) ^ 0  )
+               * Q ( P ":" * (1 - S "}:\r" - "'''" ) ^ 0 ) ^ -1
+               * K ( 'String.Interpol' , "}"  )
              + 
              Q ( ( 1 - P "'''" - S "{}'\r" ) ^ 1 )
              + 
              EOL
            ) ^ 0 
        +
-         Q ( ( S "rR" ) ^ -1  * P "'''" )
+         Q ( ( S "rR" ) ^ -1  * "'''" )
          * (
              Q ( ( 1 - P "'''" - S "\r%" ) ^ 1 )  
              + 
@@ -5616,25 +5694,25 @@ local SingleLongString =
              EOL
            ) ^ 0 
       )
-      * Q ( P "'''" ) ) 
+      * Q "'''"  ) 
 
 
 local DoubleLongString =
   WithStyle ( 'String.Long' ,
      (
-        Q ( S "fF" * P "\"\"\"" )
+        Q ( S "fF" * "\"\"\"" )
         * (
-            K ( 'String.Interpol', P "{"  )
-              * K ( 'Interpol.Inside' , ( 1 - S "}:\r" - P "\"\"\"" ) ^ 0 )
-              * Q ( P ":" * (1 - S "}:\r" - P "\"\"\"" ) ^ 0 ) ^ -1
-              * K ( 'String.Interpol' , P "}"  )
+            K ( 'String.Interpol', "{"  )
+              * K ( 'Interpol.Inside' , ( 1 - S "}:\r" - "\"\"\"" ) ^ 0 )
+              * Q ( ":" * (1 - S "}:\r" - "\"\"\"" ) ^ 0 ) ^ -1
+              * K ( 'String.Interpol' , "}"  )
             + 
-            Q ( ( 1 - P "\"\"\"" - S "{}\"\r" ) ^ 1 ) 
+            Q ( ( 1 - S "{}\"\r" - "\"\"\"" ) ^ 1 ) 
             + 
             EOL
           ) ^ 0 
       +
-        Q ( ( S "rR" ) ^ -1  * P "\"\"\"" )
+        Q ( S "rR" ^ -1  * "\"\"\"" )
         * (
             Q ( ( 1 - P "\"\"\"" - S "%\r" ) ^ 1 )  
             + 
@@ -5645,7 +5723,7 @@ local DoubleLongString =
             EOL
           ) ^ 0 
      )
-     * Q ( P "\"\"\"" ) 
+     * Q "\"\"\"" 
   ) 
 %    \end{macrocode}
 %
@@ -5659,11 +5737,11 @@ local LongString = SingleLongString + DoubleLongString
 % of a function definition (which begins with |def|).
 %    \begin{macrocode}
 local StringDoc = 
-    K ( 'String.Doc' , P "r" ^ -1 * P "\"\"\"" )
-      * ( K ( 'String.Doc' , (1 - P "\"\"\"" - P "\r" ) ^ 0  ) * EOL
+    K ( 'String.Doc' , P "r" ^ -1 * "\"\"\"" )
+      * ( K ( 'String.Doc' , (1 - P "\"\"\"" - "\r" ) ^ 0  ) * EOL
           * Tab ^ 0 
         ) ^ 0
-      * K ( 'String.Doc' , ( 1 - P "\"\"\"" - P "\r" ) ^ 0 * P "\"\"\"" )
+      * K ( 'String.Doc' , ( 1 - P "\"\"\"" - "\r" ) ^ 0 * "\"\"\"" )
 %    \end{macrocode}
 %
 % \bigskip
@@ -5672,31 +5750,12 @@ local StringDoc =
 % 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 )
+     Q "#" * ( 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 )  
-%    \end{macrocode}
 % 
 % \bigskip
 % \paragraph{DefFunction}
@@ -5709,15 +5768,15 @@ local CommentLaTeX =
 %    \begin{macrocode}
 local expression =
   P { "E" ,
-       E = ( P "'" * ( P "\\'" + 1 - S "'\r" ) ^ 0 * P "'"
-             + P "\"" * (P "\\\"" + 1 - S "\"\r" ) ^ 0 * P "\""
-             + P "{" * V "F" * P "}"
-             + P "(" * V "F" * P ")"
-             + P "[" * V "F" * P "]" 
+       E = ( "'" * ( P "\\'" + 1 - S "'\r" ) ^ 0 * "'" 
+             + "\"" * ( P "\\\"" + 1 - S "\"\r" ) ^ 0 * "\""
+             + "{" * V "F" * "}"
+             + "(" * V "F" * ")"
+             + "[" * V "F" * "]" 
              + ( 1 - S "{}()[]\r," ) ) ^ 0 ,
-       F = ( P "{" * V "F" * P "}"
-             + P "(" * V "F" * P ")"
-             + P "[" * V "F" * P "]"
+       F = (   "{" * V "F" * "}"
+             + "(" * V "F" * ")"
+             + "[" * V "F" * "]"
              + ( 1 - S "{}()[]\r\"'" ) ) ^ 0
     }
 %    \end{macrocode}
@@ -5739,8 +5798,8 @@ local expression =
 local Param = 
   SkipSpace * ( Identifier + Q "*args" + Q "**kwargs" ) * SkipSpace
    * ( 
-         K ( 'InitialValues' , P "=" * expression )
-       + Q ( P ":" ) * SkipSpace * K ( 'Name.Type' , letter ^ 1  ) 
+         K ( 'InitialValues' , "=" * expression )
+       + Q ":" * SkipSpace * K ( 'Name.Type' , letter ^ 1  ) 
      ) ^ -1
 %    \end{macrocode}
 % 
@@ -5757,21 +5816,21 @@ local Params = ( Param * ( Q "," * Param ) ^ 0 ) ^ -1
 % |Comment|, |CommentLaTeX|, |Params|, |StringDoc|...
 %    \begin{macrocode}
 local DefFunction =
-  K ( 'Keyword' , P "def" )
+  K ( 'Keyword' , "def" )
   * Space
   * K ( 'Name.Function.Internal' , identifier ) 
   * SkipSpace 
-  * Q ( P "(" ) * Params * Q ( P ")" ) 
+  * Q "("  * Params * Q ")" 
   * SkipSpace
-  * ( Q ( P "->" ) * SkipSpace * K ( 'Name.Type' , identifier  ) ) ^ -1
+  * ( Q "->" * 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 ":" )
+  * K ( 'ParseAgain' , ( 1 - S ":\r" ) ^ 0 ) 
+  * Q ":" 
   * ( SkipSpace
       * ( EOL + CommentLaTeX + Comment ) -- in all cases, that contains an EOL
       * Tab ^ 0 
@@ -5801,8 +5860,9 @@ local ExceptionInConsole = Exception *  Q ( ( 1 - P "\r" ) ^ 0 ) * EOL
 %
 % First, the main loop :
 %    \begin{macrocode}
-local MainPython = 
-       EOL
+local Main = 
+       space ^ 1 * -1
+     + space ^ 0 * EOL 
      + Space 
      + Tab
      + Escape + EscapeMath
@@ -5831,10 +5891,7 @@ local MainPython =
 %
 % Here, we must not put |local|!
 %    \begin{macrocode}
-MainLoopPython = 
-  (  ( space^1 * -1 ) 
-     + MainPython
-  ) ^ 0 
+LPEG1['python'] = Main ^ 0 
 %    \end{macrocode}
 %
 % \bigskip
@@ -5844,31 +5901,26 @@ MainLoopPython =
 % 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 =
+LPEG2['python'] = 
   Ct (
-       ( ( space - P "\r" ) ^0 * P "\r" ) ^ -1 
+       ( space ^ 0 * "\r" ) ^ -1 
        * BeamerBeginEnvironments 
        * PromptHastyDetection
        * Lc '\\@@_begin_line:'
        * Prompt 
        * SpaceIndentation ^ 0 
-       * MainLoopPython
+       * LPEG1['python']
        * -1 
        * Lc '\\@@_end_line:' 
      )
 %    \end{macrocode}
 %
-%    \begin{macrocode}
-languages['python'] = python
-%    \end{macrocode}
 %
 % \bigskip
-% \subsubsection{The LPEG ocaml}
+% \subsubsection{The language Ocaml}
 % 
 %    \begin{macrocode}
-local Delim = Q ( P "[|" + P "|]" + S "[()]" )
+local Delim = Q ( P "[|" + "|]" + S "[()]" )
 %    \end{macrocode}
 %
 %    \begin{macrocode}
@@ -5889,8 +5941,7 @@ local ModuleType = K ( 'Name.Type' , cap_identifier )
 % The identifiers which begin with a lower case letter or an underscore are used 
 % elsewhere in OCaml.
 %    \begin{macrocode}
-local identifier = 
-  ( R "az" + P "_") * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0 
+local identifier = ( R "az" + "_" ) * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0 
 local Identifier = K ( 'Identifier' , identifier )
 %    \end{macrocode}
 %
@@ -5900,22 +5951,22 @@ local Identifier = K ( 'Identifier' , identifier )
 %    \begin{macrocode}
 local expression_for_fields =
   P { "E" ,
-       E = ( P "{" * V "F" * P "}"
-             + P "(" * V "F" * P ")"
-             + P "[" * V "F" * P "]" 
-             + P "\"" * (P "\\\"" + 1 - S "\"\r" ) ^ 0 * P "\""
-             + P "'" * ( P "\\'" + 1 - S "'\r" ) ^ 0 * P "'"
+       E = (   "{" * V "F" * "}"
+             + "(" * V "F" * ")"
+             + "[" * V "F" * "]" 
+             + "\"" * ( P "\\\"" + 1 - S "\"\r" ) ^ 0 * "\""
+             + "'" * ( P "\\'" + 1 - S "'\r" ) ^ 0 * "'"
              + ( 1 - S "{}()[]\r;" ) ) ^ 0 ,
-       F = ( P "{" * V "F" * P "}"
-             + P "(" * V "F" * P ")"
-             + P "[" * V "F" * P "]"
+       F = (   "{" * V "F" * "}"
+             + "(" * V "F" * ")"
+             + "[" * V "F" * "]"
              + ( 1 - S "{}()[]\r\"'" ) ) ^ 0
     }
 %    \end{macrocode}
 % 
 %    \begin{macrocode}
 local OneFieldDefinition = 
-    ( K ( 'KeyWord' , P "mutable" ) * SkipSpace ) ^ -1
+    ( K ( 'Keyword' , "mutable" ) * SkipSpace ) ^ -1
   * K ( 'Name.Field' , identifier ) * SkipSpace
   * Q ":" * SkipSpace
   * K ( 'Name.Type' , expression_for_fields ) 
@@ -5924,7 +5975,7 @@ local OneFieldDefinition =
 local OneField = 
     K ( 'Name.Field' , identifier ) * SkipSpace
   * Q "=" * SkipSpace
-  * ( expression_for_fields / ( function (s) return LoopOCaml:match(s) end ) )
+  * ( expression_for_fields / ( function ( s ) return LPEG1['ocaml'] : match ( s ) end ) )
   * SkipSpace
 
 local Record = 
@@ -5948,7 +5999,6 @@ local DotNotation =
       K ( 'Name.Module' , cap_identifier ) 
         * Q "." 
         * ( Identifier + Constructor + Q "(" + Q "[" + Q "{" ) 
-
       + 
       Identifier 
         * Q "."
@@ -5960,32 +6010,27 @@ local DotNotation =
 %    \begin{macrocode}
 local Operator = 
   K ( 'Operator' ,
-      P "!=" + P "<>" + P "==" + P "<<" + P ">>" + P "<=" + P ">=" + P ":=" 
-      + P "||" + P "&&" + P "//" + P "**" + P ";;" + P "::" + P "->" 
-      + P "+." + P "-." + P "*." + P "/." 
-      + S "-~+/*%=<>&@|" 
-    )
+      P "!=" + "<>" + "==" + "<<" + ">>" + "<=" + ">=" + ":=" + "||" + "&&" +
+      "//" + "**" + ";;" + "::" + "->" + "+." + "-." + "*." + "/." 
+      + S "-~+/*%=<>&@|" )
 
 local OperatorWord = 
   K ( 'Operator.Word' ,
-      P "and" + P "asr" + P "land" + P "lor" + P "lsl" + P "lxor" 
-      + P "mod" + P "or" )
+      P "and" + "asr" + "land" + "lor" + "lsl" + "lxor" + "mod" + "or" )
 
 local Keyword = 
   K ( 'Keyword' ,
-      P "assert" + P "and" + P "as" + P "begin" + P "class" + P "constraint" + P "done" 
-  + P "downto" + P "do" + P "else" + P "end" + P "exception" + P "external" 
-  + P "for" + P "function" + P "functor" + P "fun" + P "if" 
-  + P "include" + P "inherit" + P "initializer" + P "in"  + P "lazy" + P "let" 
-  + P "match" + P "method" + P "module" + P "mutable" + P "new" + P "object" 
-  + P "of" + P "open" + P "private" + P "raise" + P "rec" + P "sig" 
-  + P "struct" + P "then" + P "to" + P "try" + P "type" 
-  + P "value" + P "val" + P "virtual" + P "when" + P "while" + P "with" )
-  + K ( 'Keyword.Constant' , P "true" + P "false" )  
-
+      P "assert" + "and" + "as" + "begin" + "class" + "constraint" + "done" 
+  + "downto" + "do" + "else" + "end" + "exception" + "external" + "for" +
+  "function" + "functor" + "fun" + "if" + "include" + "inherit" + "initializer"
+  + "in"  + "lazy" + "let" + "match" + "method" + "module" + "mutable" + "new" +
+  "object" + "of" + "open" + "private" + "raise" + "rec" + "sig" + "struct" +
+  "then" + "to" + "try" + "type" + "value" + "val" + "virtual" + "when" +
+  "while" + "with" ) 
+  + K ( 'Keyword.Constant' , P "true" + "false" )  
 
 local Builtin = 
-  K ( 'Name.Builtin' , P "not" + P "incr" + P "decr" + P "fst" + P "snd" )
+  K ( 'Name.Builtin' , P "not" + "incr" + "decr" + "fst" + "snd" )
 %    \end{macrocode}
 % 
 % \bigskip
@@ -5993,10 +6038,9 @@ local Builtin =
 %    \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" )
+       P "Division_by_zero" + "End_of_File" + "Failure" + "Invalid_argument" +
+       "Match_failure" + "Not_found" + "Out_of_memory" + "Stack_overflow" +
+       "Sys_blocked_io" + "Sys_error" + "Undefined_recursive_module" )
 %    \end{macrocode}
 %
 % \bigskip
@@ -6004,134 +6048,31 @@ local Exception =
 %
 %    \begin{macrocode}
 local Char = 
-  K ( 'String.Short' , P "'" * ( ( 1 - P "'" ) ^ 0 + P "\\'" ) * P "'" ) 
+  K ( 'String.Short' , "'" * ( ( 1 - P "'" ) ^ 0 + "\\'" ) * "'" ) 
 %    \end{macrocode}
 % 
 %
 % \bigskip
 % \paragraph{Beamer}
 %
-%    \begin{macrocode}
-local balanced_braces =
-  P { "E" ,
-       E = 
-           (
-             P "{" * V "E" * P "}" 
-             + 
-             P "\"" * ( 1 - S "\"" ) ^ 0 * P "\""  -- OCaml strings
-             + 
-             ( 1 - S "{}" ) 
-           ) ^ 0 
-    }
-%    \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 "}" 
-         ) 
-       * ( balanced_braces / (function (s) return MainLoopOCaml:match(s) end ) )
-       * P "}" * Ct ( Cc "Close" ) 
-    + OneBeamerEnvironment ( "uncoverenv" , MainLoopOCaml ) 
-    + OneBeamerEnvironment ( "onlyenv" , MainLoopOCaml ) 
-    + OneBeamerEnvironment ( "visibleenv" , MainLoopOCaml )
-    + OneBeamerEnvironment ( "invisibleenv" , MainLoopOCaml ) 
-    + OneBeamerEnvironment ( "alertenv" , MainLoopOCaml ) 
-    + OneBeamerEnvironment ( "actionenv" , MainLoopOCaml ) 
-    +
-      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' , balanced_braces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}" )
-    +  
-      L ( 
-%    \end{macrocode}
-% For |\\temporal|, the specification of the overlays (between angular brackets) is mandatory.
-%    \begin{macrocode}
-          ( P "\\temporal" )
-          * P "<" * (1 - P ">") ^ 0 * P ">" 
-          * P "{" 
-        )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}" )
+braces = Compute_braces ( "\"" * ( 1 - S "\"" ) ^ 0 * "\"" ) 
+if piton.beamer then 
+  Beamer = Compute_Beamer ( 'ocaml' , "\"" * ( 1 - S "\"" ) ^ 0 * "\"" ) 
 end
 %    \end{macrocode}
-%
+% 
 %    \begin{macrocode}
-DetectedCommands = 
-      Ct ( Cc "Open" 
-            * C ( piton.ListCommands * P "{" ) * Cc "}" 
-         ) 
-       * ( balanced_braces / (function (s) return MainLoopOCaml:match(s) end ) )
-       * P "}" * Ct ( Cc "Close" ) 
+DetectedCommands = Compute_DetectedCommands ( 'ocaml' , braces ) 
 %    \end{macrocode}
 %
 % \bigskip
 %    \begin{macrocode}
-CleanLPEGs['ocaml']
-      = Ct ( ( piton.ListCommands * P "{" 
-                * ( balanced_braces 
-                    / ( function (s) return CleanLPEGs['ocaml']:match(s) end ) )
-                * P "}" 
-               + EscapeClean
-               +  C ( P ( 1 ) )
-              ) ^ 0 ) / table.concat 
+LPEG_cleaner['ocaml'] = Compute_LPEG_cleaner ( 'ocaml' , braces ) 
 %    \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}
 %
 % 
 % \paragraph{The strings en OCaml}
@@ -6140,7 +6081,7 @@ local EOL =
 % within the comments of OCaml.
 %    \begin{macrocode}
 local ocaml_string =
-       Q ( P "\"" )
+       Q "\"" 
      * ( 
          VisualSpace
          + 
@@ -6148,7 +6089,7 @@ local ocaml_string =
          +  
          EOL
        ) ^ 0 
-     * Q ( P "\"" ) 
+     * Q "\"" 
 %    \end{macrocode}
 % 
 %    \begin{macrocode}
@@ -6167,12 +6108,12 @@ local String = WithStyle ( 'String.Long' , ocaml_string )
 % 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 ext = ( R "az" + "_" ) ^ 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 ) 
+  Cmt ( close * Cb ( 'init' ) , 
+        function ( s , i , a , b ) return a == b end ) 
 %    \end{macrocode}
 %
 % \medskip
@@ -6187,7 +6128,6 @@ local QuotedStringBis =
         +  
         EOL
       ) ^ 0  ) 
-
 %    \end{macrocode}
 % 
 % \medskip
@@ -6196,7 +6136,7 @@ local QuotedStringBis =
 %    \begin{macrocode}
 local QuotedString = 
    C ( open * ( 1 - closeeq ) ^ 0  * close ) /
-  ( function (s) return QuotedStringBis : match(s) end ) 
+  ( function ( s ) return QuotedStringBis : match ( s ) end ) 
 %    \end{macrocode}
 % 
 %
@@ -6204,7 +6144,7 @@ local QuotedString =
 % \paragraph{The comments in the OCaml listings}
 %
 % In OCaml, the delimiters for the comments are |(*| and |*)|. There are
-% unsymmetrical and OCaml allow those comments to be nested. That's why we need a
+% unsymmetrical and OCaml allows those comments to be nested. That's why we need a
 % grammar.
 % 
 % In these comments, we embed the math comments (between |$| and |$|) and we
@@ -6217,9 +6157,9 @@ local Comment =
          "A" ,
          A = Q "(*"
              * ( V "A" 
-                 + Q ( ( 1 - P "(*" - P "*)" - S "\r$\"" ) ^ 1 ) -- $
+                 + Q ( ( 1 - S "\r$\"" - "(*" - "*)" ) ^ 1 ) -- $
                  + ocaml_string 
-                 + P "$" * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1 ) * P "$" -- $
+                 + "$" * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1 ) * "$" -- $
                  + EOL
                ) ^ 0 
              * Q "*)" 
@@ -6231,14 +6171,7 @@ local Comment =
 %
 %    \begin{macrocode}
 local balanced_parens =
-  P { "E" ,
-       E = 
-           (
-             P "(" * V "E" * P ")" 
-             + 
-             ( 1 - S "()" ) 
-           ) ^ 0 
-    }
+  P { "E" , E = ( "(" * V "E" * ")" + 1 - S "()" ) ^ 0 }
 %    \end{macrocode}
 % 
 %    \begin{macrocode}
@@ -6255,16 +6188,16 @@ local Argument =
 % which opens locally a module.
 %    \begin{macrocode}
 local DefFunction = 
-  K ( 'Keyword' , P "let open" ) 
+  K ( 'Keyword' , "let open" ) 
    * Space
    * K ( 'Name.Module' , cap_identifier ) 
   + 
-  K ( 'Keyword' , P "let rec" + P "let" + P "and" ) 
+  K ( 'Keyword' , P "let rec" + "let" + "and" ) 
     * Space
     * K ( 'Name.Function.Internal' , identifier ) 
     * Space 
     * (
-        Q "=" * SkipSpace * K ( 'Keyword' , P "function" ) 
+        Q "=" * SkipSpace * K ( 'Keyword' , "function" ) 
         + 
         Argument 
          * ( SkipSpace * Argument ) ^ 0 
@@ -6284,10 +6217,10 @@ local DefFunction =
 % definitions of \emph{types} of modules.
 %    \begin{macrocode}
 local DefModule = 
-  K ( 'Keyword' , P "module" ) * Space
+  K ( 'Keyword' , "module" ) * Space
   *
     (
-          K ( 'Keyword' , P "type" ) * Space
+          K ( 'Keyword' , "type" ) * Space
         * K ( 'Name.Type' , cap_identifier ) 
       + 
         K ( 'Name.Module' , cap_identifier ) * SkipSpace 
@@ -6322,7 +6255,7 @@ local DefModule =
           ) ^ -1
     )
   + 
-  K ( 'Keyword' , P "include" + P "open" )
+  K ( 'Keyword' , P "include" + "open" )
   * Space * K ( 'Name.Module' , cap_identifier ) 
 %    \end{macrocode}
 % 
@@ -6330,7 +6263,7 @@ local DefModule =
 % \paragraph{The parameters of the types}
 % 
 %    \begin{macrocode}
-local TypeParameter = K ( 'TypeParameter' , P "'" * alpha * # ( 1 - P "'" ) ) 
+local TypeParameter = K ( 'TypeParameter' , "'" * alpha * # ( 1 - P "'" ) ) 
 %    \end{macrocode}
 % 
 % \bigskip
@@ -6338,8 +6271,9 @@ local TypeParameter = K ( 'TypeParameter' , P "'" * alpha * # ( 1 - P "'" ) )
 %
 % First, the main loop :
 %    \begin{macrocode}
-MainOCaml = 
-       EOL
+local Main = 
+       space ^ 1 * -1
+     + space ^ 0 * EOL 
      + Space 
      + Tab
      + Escape + EscapeMath
@@ -6365,41 +6299,31 @@ MainOCaml =
      + Number
      + Word
 
-LoopOCaml = MainOCaml ^ 0 
-
-MainLoopOCaml = 
-  (  ( space^1 * -1 ) 
-     + MainOCaml
-  ) ^ 0 
+LPEG1['ocaml'] = Main ^ 0 
 %    \end{macrocode}
 %
 % \bigskip
-% We recall that each line in the Python code to parse will be sent back to
+% We recall that each line in the 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 =
+LPEG2['ocaml'] = 
   Ct (
-       ( ( space - P "\r" ) ^0 * P "\r" ) ^ -1 
+       ( space ^ 0 * "\r" ) ^ -1 
        * BeamerBeginEnvironments 
-       * Lc ( '\\@@_begin_line:' ) 
+       * Lc '\\@@_begin_line:' 
        * SpaceIndentation ^ 0 
-       * MainLoopOCaml
+       * LPEG1['ocaml']
        * -1 
-       * Lc ( '\\@@_end_line:' )
+       * Lc '\\@@_end_line:' 
      )
 %    \end{macrocode}
 %
-%    \begin{macrocode}
-languages['ocaml'] = ocaml
-%    \end{macrocode}
 %
 % \bigskip
-% \subsubsection{The LPEG for the language C}
+% \subsubsection{The language C}
 % 
 %    \begin{macrocode}
 local Delim = Q ( S "{[()]}" )
@@ -6417,42 +6341,34 @@ local identifier = letter * alphanum ^ 0
 
 local Operator = 
   K ( 'Operator' ,
-      P "!=" + P "==" + P "<<" + P ">>" + P "<=" + P ">=" 
-      + P "||" + P "&&" + S "-~+/*%=<>&.@|!" 
-    )
+      P "!=" + "==" + "<<" + ">>" + "<=" + ">=" + "||" + "&&" 
+        + S "-~+/*%=<>&.@|!" )
 
 local Keyword = 
   K ( 'Keyword' ,
-      P "alignas" + P "asm" + P "auto" + P "break" + P "case" + P "catch"
-      + P "class" + P "const" + P "constexpr" + P "continue" 
-      + P "decltype" + P "do" + P "else" + P "enum" + P "extern" 
-      + P "for" + P "goto" + P "if" + P "nexcept" + P "private" + P "public" 
-      + P "register" + P "restricted" + P "return" + P "static" + P "static_assert" 
-      + P "struct" + P "switch" + P "thread_local" + P "throw" + P "try" 
-      + P "typedef" + P "union" + P "using" + P "virtual" + P "volatile" 
-      + P "while" 
+      P "alignas" + "asm" + "auto" + "break" + "case" + "catch" + "class" +
+      "const" + "constexpr" + "continue" + "decltype" + "do" + "else" + "enum" +
+      "extern" + "for" + "goto" + "if" + "nexcept" + "private" + "public" +
+      "register" + "restricted" + "return" + "static" + "static_assert" +
+      "struct" + "switch" + "thread_local" + "throw" + "try" + "typedef" +
+      "union" + "using" + "virtual" + "volatile" + "while" 
     )
-  + K ( 'Keyword.Constant' , 
-        P "default" + P "false" + P "NULL" + P "nullptr" + P "true" 
-      ) 
+  + K ( 'Keyword.Constant' , P "default" + "false" + "NULL" + "nullptr" + "true" ) 
 
 local Builtin = 
   K ( 'Name.Builtin' ,
-      P "alignof" + P "malloc" + P "printf" + P "scanf" + P "sizeof" 
-    )
+      P "alignof" + "malloc" + "printf" + "scanf" + "sizeof" )
 
 local Type = 
   K ( 'Name.Type' ,
-      P "bool" + P "char" + P "char16_t" + P "char32_t" + P "double" 
-      + P "float" + P "int" + P "int8_t" + P "int16_t" + P "int32_t" 
-      + P "int64_t" + P "long" + P "short" + P "signed" + P "unsigned" 
-      + P "void" + P "wchar_t" 
-    )
+      P "bool" + "char" + "char16_t" + "char32_t" + "double" + "float" + "int" +
+      "int8_t" + "int16_t" + "int32_t" + "int64_t" + "long" + "short" + "signed"
+      + "unsigned" + "void" + "wchar_t" )
 
 local DefFunction = 
   Type 
   * Space 
-  * Q ( "*" ) ^ -1 
+  * Q "*" ^ -1 
   * K ( 'Name.Function.Internal' , identifier ) 
   * SkipSpace 
   * # P "("
@@ -6469,7 +6385,7 @@ local DefFunction =
 % Example:\enskip \piton{class myclass:}
 %    \begin{macrocode}
 local DefClass = 
-  K ( 'Keyword' , P "class" ) * Space * K ( 'Name.Class' , identifier ) 
+  K ( 'Keyword' , "class" ) * Space * K ( 'Name.Class' , identifier ) 
 %    \end{macrocode}
 % 
 % If the word |class| is not followed by a identifier, it will be catched as
@@ -6480,12 +6396,12 @@ local DefClass =
 % \paragraph{The strings of C}
 %
 %    \begin{macrocode}
-local String = 
+String = 
   WithStyle ( 'String.Long' ,
       Q "\"" 
       * ( VisualSpace 
           + K ( 'String.Interpol' , 
-                P "%" * ( S "difcspxXou" + P "ld" + P "li" + P "hd" + P "hi" )
+                "%" * ( S "difcspxXou" + "ld" + "li" + "hd" + "hi" )
               ) 
           + Q ( ( P "\\\"" + 1 - S " \"" ) ^ 1 ) 
         ) ^ 0 
@@ -6496,146 +6412,25 @@ local String =
 % \bigskip
 % \paragraph{Beamer}
 %
-% The following \textsc{lpeg} |balanced_braces| will be used for the (mandatory)
-% argument of the commands |\only| and \emph{al.} of Beamer. It's necessary to
-% use a \emph{grammar} because that pattern mainly checks the correct nesting of
-% the delimiters (and it's known in the theory of formal languages that this
-% can't be done with regular expressions \emph{stricto sensu} only).
-%    \begin{macrocode}
-local balanced_braces =
-  P { "E" ,
-       E = 
-           (
-             P "{" * V "E" * P "}" 
-             + 
-             String  
-             + 
-             ( 1 - S "{}" ) 
-           ) ^ 0 
-    }
-%    \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 "}" 
-         ) 
-       * ( balanced_braces / (function (s) return MainLoopC:match(s) end ) )
-       * P "}" * Ct ( Cc "Close" ) 
-    + OneBeamerEnvironment ( "uncoverenv" , MainLoopC ) 
-    + OneBeamerEnvironment ( "onlyenv" , MainLoopC ) 
-    + OneBeamerEnvironment ( "visibleenv" , MainLoopC )
-    + OneBeamerEnvironment ( "invisibleenv" , MainLoopC ) 
-    + OneBeamerEnvironment ( "alertenv" , MainLoopC ) 
-    + OneBeamerEnvironment ( "actionenv" , MainLoopC ) 
-    +
-      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' , balanced_braces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}" )
-    +  
-      L ( 
-%    \end{macrocode}
-% For |\\temporal|, the specification of the overlays (between angular brackets) is mandatory.
-%    \begin{macrocode}
-          ( P "\\temporal" )
-          * P "<" * (1 - P ">") ^ 0 * P ">" 
-          * P "{" 
-        )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}" )
-end
+braces = Compute_braces ( "\"" * ( 1 - S "\"" ) ^ 0 * "\"" ) 
+if piton.beamer then Beamer = Compute_Beamer ( 'c' , braces ) end
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-DetectedCommands = 
-      Ct ( Cc "Open" 
-            * C ( piton.ListCommands * P "{" ) * Cc "}" 
-         ) 
-       * ( balanced_braces / (function (s) return MainLoopC:match(s) end ) )
-       * P "}" * Ct ( Cc "Close" ) 
+DetectedCommands = Compute_DetectedCommands ( 'c' , braces ) 
 %    \end{macrocode}
 %
-% \bigskip
 %    \begin{macrocode}
-CleanLPEGs['c']
-      = Ct ( ( piton.ListCommands * P "{" 
-                * ( balanced_braces 
-                    / ( function (s) return CleanLPEGs['c']:match(s) end ) )
-                * P "}" 
-               + EscapeClean
-               +  C ( P ( 1 ) )
-              ) ^ 0 ) / table.concat 
+LPEG_cleaner['c'] = Compute_LPEG_cleaner ( 'c' , braces ) 
 %    \end{macrocode}
 % 
 % \bigskip
-% \paragraph{EOL}
-%
-%
-% 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 directives of the preprocessor}
 %
 %    \begin{macrocode}
-local Preproc = 
-  K ( 'Preproc' , P "#" * (1 - P "\r" ) ^ 0  ) * ( EOL + -1 )
+local Preproc = K ( 'Preproc' , "#" * ( 1 - P "\r" ) ^ 0  ) * ( EOL + -1 )
 %    \end{macrocode}
 % 
 %
@@ -6644,39 +6439,20 @@ local Preproc =
 %
 % We define different \textsc{lpeg} dealing with comments in the C 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 )
+     Q "//" * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 ) -- $
+            * ( EOL + -1 )
 
 local LongComment = 
   WithStyle ( 'Comment' , 
-               Q ( P "/*" ) 
+               Q "/*" 
                * ( CommentMath + Q ( ( 1 - P "*/" - S "$\r" ) ^ 1 ) + EOL ) ^ 0 
-               * Q ( P "*/" ) 
+               * Q "*/" 
             ) -- $
 %    \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 )  
-%    \end{macrocode}
-% 
-%
 %
 % 
 % \bigskip
@@ -6684,8 +6460,9 @@ local CommentLaTeX =
 %
 % First, the main loop :
 %    \begin{macrocode}
-local MainC = 
-       EOL
+local Main = 
+       space ^ 1 * -1
+     + space ^ 0 * EOL 
      + Space 
      + Tab
      + Escape + EscapeMath 
@@ -6700,7 +6477,7 @@ local MainC =
      + Punct
      + DefFunction
      + DefClass 
-     + Type * ( Q ( "*" ) ^ -1 + Space + Punct + Delim + EOL + -1 ) 
+     + Type * ( Q "*" ^ -1 + Space + Punct + Delim + EOL + -1 ) 
      + Keyword * ( Space + Punct + Delim + EOL + -1 ) 
      + Builtin * ( Space + Punct + Delim + EOL + -1 ) 
      + Identifier 
@@ -6710,10 +6487,7 @@ local MainC =
 %
 % Here, we must not put |local|!
 %    \begin{macrocode}
-MainLoopC = 
-  (  ( space^1 * -1 ) 
-     + MainC
-  ) ^ 0 
+LPEG1['c'] = Main ^ 0 
 %    \end{macrocode}
 %
 % \bigskip
@@ -6723,39 +6497,46 @@ MainLoopC =
 % will be used as marker in order to delimit the argument of the command
 % \texttt{\textbackslash @@\_begin\_line:}}.
 %    \begin{macrocode}
-languageC =
+LPEG2['c'] = 
   Ct (
-       ( ( space - P "\r" ) ^0 * P "\r" ) ^ -1 
+       ( space ^ 0 * P "\r" ) ^ -1 
        * BeamerBeginEnvironments 
        * Lc '\\@@_begin_line:'
        * SpaceIndentation ^ 0 
-       * MainLoopC
+       * LPEG1['c']
        * -1 
        * Lc '\\@@_end_line:' 
      )
 %    \end{macrocode}
 %
-%    \begin{macrocode}
-languages['c'] = languageC
-%    \end{macrocode}
-%
 %
 % \bigskip
-% \subsubsection{The LPEG language SQL}
+% \subsubsection{The language SQL}
 % 
+%    \begin{macrocode}
+local function LuaKeyword ( name ) 
+return 
+   Lc "{\\PitonStyle{Keyword}{" 
+   * Q ( Cmt ( 
+               C ( identifier ) , 
+               function ( s , i , a ) return string.upper ( a ) == name end 
+             ) 
+       ) 
+   * Lc "}}" 
+end 
+%    \end{macrocode}
+%
 % \bigskip
 % In the identifiers, we will be able to catch those contening spaces, that is
 % to say like |"last name"|. 
 %    \begin{macrocode}
 local identifier = 
-  letter * ( alphanum + P "-" ) ^ 0 
-  + P '"' * ( ( alphanum + space - P '"' ) ^ 1 ) * P '"' 
+  letter * ( alphanum + "-" ) ^ 0 
+  + '"' * ( ( alphanum + space - '"' ) ^ 1 ) * '"' 
 
 
 local Operator = 
-  K ( 'Operator' ,
-      P "=" + P "!=" + P "<>" + P ">=" + P ">" + P "<=" + P "<"  + S "*+/"
-    )
+  K ( 'Operator' , P "=" + "!=" + "<>" + ">=" + ">" + "<=" + "<"  + S "*+/" )
 %    \end{macrocode}
 %
 % In SQL, the keywords are case-insensitive. That's why we have a little
@@ -6763,9 +6544,9 @@ local Operator =
 % distinguish the keywords with a Lua function. However, some keywords will be
 % catched in special LPEG because we want to detect the names of the SQL tables.
 %    \begin{macrocode}
-local function Set (list)
-  local set = {}
-  for _, l in ipairs(list) do set[l] = true end
+local function Set ( list )
+  local set = { }
+  for _, l in ipairs ( list ) do set[l] = true end
   return set
 end
 
@@ -6819,143 +6600,24 @@ local Identifier =
 % \paragraph{The strings of SQL}
 %
 %    \begin{macrocode}
-local String = 
-  K ( 'String.Long' , P "'" * ( 1 - P "'" ) ^ 1 * P "'" ) 
+local String = K ( 'String.Long' , "'" * ( 1 - P "'" ) ^ 1 * "'" ) 
 %    \end{macrocode}
 % 
 % \bigskip
 % \paragraph{Beamer}
 %
-% The following \textsc{lpeg} |balanced_braces| will be used for the (mandatory)
-% argument of the commands |\only| and \emph{al.} of Beamer. It's necessary to
-% use a \emph{grammar} because that pattern mainly checks the correct nesting of
-% the delimiters (and it's known in the theory of formal languages that this
-% can't be done with regular expressions \emph{stricto sensu} only).
-%    \begin{macrocode}
-local balanced_braces =
-  P { "E" ,
-       E = 
-           (
-             P "{" * V "E" * P "}" 
-             + 
-             String  
-             + 
-             ( 1 - S "{}" ) 
-           ) ^ 0 
-    }
-%    \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 "}" 
-         ) 
-       * ( balanced_braces / (function (s) return MainLoopSQL:match(s) end ) )
-       * P "}" * Ct ( Cc "Close" ) 
-    + OneBeamerEnvironment ( "uncoverenv" , MainLoopSQL ) 
-    + OneBeamerEnvironment ( "onlyenv" , MainLoopSQL ) 
-    + OneBeamerEnvironment ( "visibleenv" , MainLoopSQL )
-    + OneBeamerEnvironment ( "invisibleenv" , MainLoopSQL ) 
-    + OneBeamerEnvironment ( "alertenv" , MainLoopSQL ) 
-    + OneBeamerEnvironment ( "actionenv" , MainLoopSQL ) 
-    +
-      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' , balanced_braces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}" )
-    +  
-      L ( 
-%    \end{macrocode}
-% For |\\temporal|, the specification of the overlays (between angular brackets) is mandatory.
-%    \begin{macrocode}
-          ( P "\\temporal" )
-          * P "<" * (1 - P ">") ^ 0 * P ">" 
-          * P "{" 
-        )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}" )
-end
+braces = Compute_braces ( String ) 
+if piton.beamer then Beamer = Compute_Beamer ( 'sql' , braces ) end
 %    \end{macrocode}
-%
+% 
 %    \begin{macrocode}
-DetectedCommands = 
-      Ct ( Cc "Open" 
-            * C ( piton.ListCommands * P "{" ) * Cc "}" 
-         ) 
-       * ( balanced_braces / (function (s) return MainLoopSQL:match(s) end ) )
-       * P "}" * Ct ( Cc "Close" ) 
+DetectedCommands = Compute_DetectedCommands ( 'sql' , braces ) 
 %    \end{macrocode}
 %
-% \bigskip
 %    \begin{macrocode}
-CleanLPEGs['sql']
-      = Ct ( ( piton.ListCommands * P "{" 
-                * ( balanced_braces 
-                    / ( function (s) return CleanLPEGs['sql']:match(s) end ) )
-                * P "}" 
-               + EscapeClean
-               +  C ( P ( 1 ) )
-              ) ^ 0 ) / table.concat 
-%    \end{macrocode}
-%
-% \bigskip
-% \paragraph{EOL}
-%
-% \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 SQL 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 
-              * Lc "\\@@_newline: \\@@_begin_line:"
-            )
-       )
-  ) 
-  *
-  SpaceIndentation ^ 0
+LPEG_cleaner['sql'] = Compute_LPEG_cleaner ( 'sql' , braces ) 
 %    \end{macrocode}
 %
 % 
@@ -6965,95 +6627,63 @@ local EOL =
 %
 % We define different \textsc{lpeg} dealing with comments in the SQL listings.
 %    \begin{macrocode}
-local CommentMath = 
-  P "$" * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1  ) * P "$"
-
 local Comment = 
   WithStyle ( 'Comment' ,
-     Q ( P "--" )  -- syntax of SQL92
-     * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 ) 
+     Q "--"   -- syntax of SQL92
+     * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 ) -- $
   * ( EOL + -1 )
 
 local LongComment = 
   WithStyle ( 'Comment' , 
-               Q ( P "/*" ) 
+               Q "/*" 
                * ( CommentMath + Q ( ( 1 - P "*/" - S "$\r" ) ^ 1 ) + EOL ) ^ 0 
-               * Q ( P "*/" ) 
+               * Q "*/" 
             ) -- $
 %    \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 )  
-%    \end{macrocode}
-% 
-%
-%
 % 
 % \bigskip
 % \paragraph{The main LPEG for the language SQL}
 %
 %
 %    \begin{macrocode}
-local function LuaKeyword ( name ) 
-return 
-   Lc ( "{\\PitonStyle{Keyword}{" )
-   * Q ( Cmt ( 
-               C ( identifier ) , 
-               function(s,i,a) return string.upper(a) == name end 
-             ) 
-       ) 
-   * Lc ( "}}" )
-end 
-%    \end{macrocode}
-% 
-%    \begin{macrocode}
 local TableField = 
-     K ( 'Name.Table' , identifier ) 
-     * Q ( P "." ) 
+       K ( 'Name.Table' , identifier ) 
+     * Q "." 
      * K ( 'Name.Field' , identifier ) 
 
 local OneField = 
   ( 
-    Q ( P "(" * ( 1 - P ")" ) ^ 0 * P ")" )
+    Q ( "(" * ( 1 - P ")" ) ^ 0 * ")" )
     + 
-    K ( 'Name.Table' , identifier ) 
-      * Q ( P "." ) 
+        K ( 'Name.Table' , identifier ) 
+      * Q "." 
       * K ( 'Name.Field' , identifier ) 
     + 
     K ( 'Name.Field' , identifier ) 
   )
   * ( 
-      Space * LuaKeyword ( "AS" ) * Space * K ( 'Name.Field' , identifier ) 
+      Space * LuaKeyword "AS" * Space * K ( 'Name.Field' , identifier ) 
     ) ^ -1
-  * ( Space * ( LuaKeyword ( "ASC" ) + LuaKeyword ( "DESC" ) ) ) ^ -1
+  * ( Space * ( LuaKeyword "ASC" + LuaKeyword "DESC" ) ) ^ -1
 
 local OneTable = 
      K ( 'Name.Table' , identifier ) 
    * ( 
        Space 
-       * LuaKeyword ( "AS" ) 
+       * LuaKeyword "AS"  
        * Space 
        * K ( 'Name.Table' , identifier ) 
      ) ^ -1 
 
 local WeCatchTableNames = 
-     LuaKeyword ( "FROM" ) 
+     LuaKeyword "FROM" 
    * ( Space + EOL ) 
-   * OneTable * ( SkipSpace * Q ( P "," ) * SkipSpace * OneTable ) ^ 0 
+   * OneTable * ( SkipSpace * Q "," * SkipSpace * OneTable ) ^ 0 
   + ( 
-      LuaKeyword ( "JOIN" ) + LuaKeyword ( "INTO" ) + LuaKeyword ( "UPDATE" ) 
-      + LuaKeyword ( "TABLE" ) 
+      LuaKeyword "JOIN" + LuaKeyword "INTO" + LuaKeyword "UPDATE" 
+      + LuaKeyword "TABLE" 
     ) 
     * ( Space + EOL ) * OneTable 
 %    \end{macrocode}
@@ -7061,8 +6691,9 @@ local WeCatchTableNames =
 %
 % First, the main loop :
 %    \begin{macrocode}
-local MainSQL = 
-       EOL
+local Main = 
+       space ^ 1 * -1
+     + space ^ 0 * EOL 
      + Space 
      + Tab
      + Escape + EscapeMath 
@@ -7082,168 +6713,56 @@ local MainSQL =
 %
 % Here, we must not put |local|!
 %    \begin{macrocode}
-MainLoopSQL = 
-  (  ( space^1 * -1 ) 
-     + MainSQL
-  ) ^ 0 
+LPEG1['sql'] = Main ^ 0 
 %    \end{macrocode}
 %
 % \bigskip
-% We recall that each line in the C code to parse will be sent back to
+% We recall that each line in the 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}
-languageSQL =
+LPEG2['sql'] =
   Ct (
-       ( ( space - P "\r" ) ^ 0 * P "\r" ) ^ -1 
+       ( space ^ 0 * "\r" ) ^ -1 
        * BeamerBeginEnvironments 
        * Lc '\\@@_begin_line:'
        * SpaceIndentation ^ 0 
-       * MainLoopSQL
+       * LPEG1['sql']
        * -1 
        * Lc '\\@@_end_line:' 
      )
 %    \end{macrocode}
 %
-%    \begin{macrocode}
-languages['sql'] = languageSQL
-%    \end{macrocode}
 % 
-% \subsubsection{The LPEG language Minimal}
+% \subsubsection{The language ``Minimal''}
 % 
 %    \begin{macrocode}
 local Punct = Q ( S ",:;!\\" )
 
-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 )
-
+              Q "#" 
+              * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 -- $
+            )
+     * ( EOL + -1 )
 
 local String = 
   WithStyle ( 'String.Short' ,
-      Q "\"" 
-      * ( VisualSpace 
-          + Q ( ( P "\\\"" + 1 - S " \"" ) ^ 1 ) 
-        ) ^ 0 
-      * Q "\""
-    )
-
-
-local balanced_braces =
-  P { "E" ,
-       E = 
-           (
-             P "{" * V "E" * P "}" 
-             + 
-             String  
-             + 
-             ( 1 - S "{}" ) 
-           ) ^ 0 
-    }
-
-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 "}" 
-         ) 
-       * ( balanced_braces / (function (s) return MainLoopMinimal:match(s) end ) )
-       * P "}" * Ct ( Cc "Close" ) 
-    + OneBeamerEnvironment ( "uncoverenv" , MainLoopMinimal ) 
-    + OneBeamerEnvironment ( "onlyenv" , MainLoopMinimal ) 
-    + OneBeamerEnvironment ( "visibleenv" , MainLoopMinimal )
-    + OneBeamerEnvironment ( "invisibleenv" , MainLoopMinimal ) 
-    + OneBeamerEnvironment ( "alertenv" , MainLoopMinimal ) 
-    + OneBeamerEnvironment ( "actionenv" , MainLoopMinimal ) 
-    +
-      L ( 
-          ( P "\\alt" )
-          * P "<" * (1 - P ">") ^ 0 * P ">" 
-          * P "{" 
-        )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}" )
-    +  
-      L ( 
-          ( P "\\temporal" )
-          * P "<" * (1 - P ">") ^ 0 * P ">" 
-          * P "{" 
-        )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}{" )
-      * K ( 'ParseAgain.noCR' , balanced_braces ) 
-      * L ( P "}" )
-end
-
-DetectedCommands = 
-      Ct ( Cc "Open" 
-            * C ( piton.ListCommands * P "{" ) * Cc "}" 
-         ) 
-       * ( balanced_braces / (function (s) return MainLoopMinimal:match(s) end ) )
-       * P "}" * Ct ( Cc "Close" ) 
-
-
-CleanLPEGs['minimal']
-      = Ct ( ( piton.ListCommands * P "{" 
-                * ( balanced_braces 
-                    / ( function (s) return CleanLPEGs['minimal']:match(s) end ) )
-                * P "}" 
-               + EscapeClean
-               +  C ( P ( 1 ) )
-              ) ^ 0 ) / table.concat 
-
-
-
-local EOL = 
-  P "\r" 
-  *
-  (
-    ( space^0 * -1 )
-    + 
-    Ct ( 
-         Cc "EOL"
-         * 
-         Ct (
-              Lc "\\@@_end_line:"
-              * BeamerEndEnvironments 
-              * BeamerBeginEnvironments 
-              * Lc "\\@@_newline: \\@@_begin_line:"
+              Q "\"" 
+              * ( VisualSpace 
+                  + Q ( ( P "\\\"" + 1 - S " \"" ) ^ 1 ) 
+                ) ^ 0 
+              * Q "\""
             )
-       )
-  ) 
-  *
-  SpaceIndentation ^ 0
 
-local CommentMath = 
-  P "$" * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1  ) * P "$" -- $
+braces = Compute_braces ( String ) 
+if piton.beamer then Beamer = Compute_Beamer ( 'minimal' , braces ) end
 
-local CommentLaTeX =
-  P(piton.comment_latex) 
-  * Lc "{\\PitonStyle{Comment.LaTeX}{\\ignorespaces" 
-  * L ( ( 1 - P "\r" ) ^ 0 ) 
-  * Lc "}}" 
-  * ( EOL + -1 )  
+DetectedCommands = Compute_DetectedCommands ( 'minimal' , braces ) 
+
+LPEG_cleaner['minimal'] = Compute_LPEG_cleaner ( 'minimal' , braces ) 
 
 local identifier = letter * alphanum ^ 0
 
@@ -7251,8 +6770,9 @@ local Identifier = K ( 'Identifier' , identifier )
 
 local Delim = Q ( S "{[()]}" )
 
-local MainMinimal = 
-       EOL
+local Main = 
+       space ^ 1 * -1
+     + space ^ 0 * EOL 
      + Space 
      + Tab
      + Escape + EscapeMath 
@@ -7267,22 +6787,18 @@ local MainMinimal =
      + Number
      + Word
 
-MainLoopMinimal = 
-  (  ( space^1 * -1 ) 
-     + MainMinimal
-  ) ^ 0 
+LPEG1['minimal'] = Main ^ 0
 
-languageMinimal =
+LPEG2['minimal'] = 
   Ct (
-       ( ( space - P "\r" ) ^ 0 * P "\r" ) ^ -1 
+       ( space ^ 0 * "\r" ) ^ -1 
        * BeamerBeginEnvironments 
        * Lc '\\@@_begin_line:'
        * SpaceIndentation ^ 0 
-       * MainLoopMinimal
+       * LPEG1['minimal']
        * -1 
        * Lc '\\@@_end_line:' 
      )
-languages['minimal'] = languageMinimal
 
 % \bigskip
 % \subsubsection{The function Parse}
@@ -7291,32 +6807,33 @@ languages['minimal'] = languageMinimal
 % 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} corresponding to the considered language (|languages[language]|)
+% \textsc{lpeg} corresponding to the considered language (|LPEG2[language]|)
 % 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 ) 
+function piton.Parse ( language , code )
+  local t = LPEG2[language] : match ( code ) 
   if t == nil 
   then 
-    tex.sprint("\\PitonSyntaxError")
+    tex.sprint(luatexbase.catcodetables.CatcodeTableExpl,
+               "\\@@_error:n { syntax~error }")
     return -- to exit in force the function
   end 
   local left_stack = {}
   local right_stack = {}
-  for _ , one_item in ipairs(t) 
+  for _ , one_item in ipairs ( t ) 
   do 
      if one_item[1] == "EOL"
      then 
-          for _ , s in ipairs(right_stack) 
-            do tex.sprint(s) 
+          for _ , s in ipairs ( right_stack ) 
+            do tex.sprint ( s ) 
             end
-          for _ , s in ipairs(one_item[2]) 
-            do tex.tprint(s)
+          for _ , s in ipairs ( one_item[2] ) 
+            do tex.tprint ( s )
             end
-          for _ , s in ipairs(left_stack) 
-            do tex.sprint(s) 
+          for _ , s in ipairs ( left_stack ) 
+            do tex.sprint ( s ) 
             end
      else 
 %    \end{macrocode}
@@ -7335,16 +6852,16 @@ function piton.Parse(language,code)
           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])
+               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] ) 
+                    tex.sprint ( right_stack[#right_stack] ) 
                     left_stack[#left_stack] = nil
                     right_stack[#right_stack] = nil
                else 
-                    tex.tprint(one_item)  
+                    tex.tprint ( one_item )  
                end 
           end 
      end 
@@ -7359,10 +6876,10 @@ end
 % 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)
+function piton.ParseFile ( language , name , first_line , last_line )
   local s = ''
   local i = 0 
-  for line in io.lines(name) 
+  for line in io.lines ( name ) 
   do i = i + 1 
      if i >= first_line
      then s = s .. '\r' .. line 
@@ -7372,16 +6889,16 @@ function piton.ParseFile(language,name,first_line,last_line)
 %    \end{macrocode}
 % We extract the BOM of utf-8, if present.
 %    \begin{macrocode}
-  if string.byte(s,1) == 13
-  then if string.byte(s,2) == 239
-       then if string.byte(s,3) == 187
-            then if string.byte(s,4) == 191
-                 then s = string.sub(s,5,-1)
+  if string.byte ( s , 1 ) == 13
+  then if string.byte ( s , 2 ) == 239
+       then if string.byte ( s , 3 ) == 187
+            then if string.byte ( s , 4 ) == 191
+                 then s = string.sub ( s , 5 , -1 )
                  end 
             end
        end
   end
-  piton.Parse(language,s)
+  piton.Parse ( language , s )
 end
 %    \end{macrocode}
 % 
@@ -7391,9 +6908,9 @@ end
 % 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)
+function piton.ParseBis ( language , code )
   local s = ( Cs ( ( P '##' / '#' + 1 ) ^ 0 ) ) : match ( code )
-  return piton.Parse(language,s) 
+  return piton.Parse ( language , s ) 
 end
 %    \end{macrocode}
 %
@@ -7404,10 +6921,10 @@ end
 % 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)
+function piton.ParseTer ( language , code )
   local s = ( Cs ( ( P '\\@@_breakable_space:' / ' ' + 1 ) ^ 0 ) ) 
             : match ( code )
-  return piton.Parse(language,s)
+  return piton.Parse ( language , s )
 end
 %    \end{macrocode}
 % 
@@ -7424,13 +6941,13 @@ end
 % a \textsc{lpeg} that we have to compute dynamically because if depends on the
 % value of~$n$.
 %    \begin{macrocode}
-local function gobble(n,code)
+local function gobble ( n , code )
   if n==0 
   then return code
   else 
        return ( Ct ( 
-                     ( 1 - P "\r" ) ^ (-n)  * C ( ( 1 - P "\r" ) ^ 0 ) 
-                       * ( C ( P "\r" )
+                     ( 1 - P "\r" ) ^ (-n) * C ( ( 1 - P "\r" ) ^ 0 ) 
+                       * ( C "\r" 
                        * ( 1 - P "\r" ) ^ (-n)
                        * C ( ( 1 - P "\r" ) ^ 0 )
                       ) ^ 0 
@@ -7440,60 +6957,37 @@ end
 %    \end{macrocode}
 %
 % 
-% 
-% \bigskip
-% The following function |sum| will be used in the following \textsc{lpeg}
-% |AutoGobbleLPEG|, |TabsAutoGobbleLPEG| and |EnvGobbleLPEG|. It computes the
-% sum of all its arguments.
-%    \begin{macrocode}
-local function count_captures(...)
-    local acc = 0
-    for _ in ipairs({...}) do
-        acc = acc + 1
-    end
-    return acc
-end
-%    \end{macrocode}
-% 
 % \bigskip
 % The following \textsc{lpeg} returns as capture the minimal number of spaces at
 % the beginning of the lines of code. 
-%    begin{macrocode}
-%    \begin{macrocode}
-local AutoGobbleLPEG = 
-  (
-    (
-%    \end{macrocode}
-% We don't take into account the empty lines (those containing only spaces).
-%    \begin{macrocode}
-      P " " ^ 0 * P "\r"
-      + 
-      C ( P " " ) ^ 0 / count_captures * ( 1 - P " " ) * ( 1 - P "\r" ) ^ 0 * P "\r"
-    ) ^ 0
-%    \end{macrocode}
-% Now for the last line of the Python code...
 %    \begin{macrocode}
-    *
-    ( C ( P " " ) ^ 0 / count_captures * ( 1 - P " " ) * ( 1 - P "\r" ) ^ 0 ) ^ -1 
-  ) / math.min
+local AutoGobbleLPEG =
+      (  (
+           P " " ^ 0 * "\r"
+           +
+           Ct ( C " " ^ 0 ) / table.getn
+           * ( 1 - P " " ) * ( 1 - P "\r" ) ^ 0 * "\r"
+         ) ^ 0
+         * ( Ct ( C " " ^ 0 ) / table.getn
+              * ( 1 - P " " ) * ( 1 - P "\r" ) ^ 0 ) ^ -1 
+       ) / math.min
 %    \end{macrocode}
 %
 % \bigskip
-% The following \textsc{lpeg} is similar but works with the indentations.
+% The following \textsc{lpeg} is similar but works with the tabulations.
 %    \begin{macrocode}
-local TabsAutoGobbleLPEG = 
-  (
-    (
-      P "\t" ^ 0 * P "\r"
-      + 
-      C ( P " " ) ^ 0 / count_captures * ( 1 - P "\t" ) * ( 1 - P "\r" ) ^ 0 * P "\r"
-    ) ^ 0
-    *
-    ( C ( P " " ) ^ 0 / count_captures * ( 1 - P "\t" ) * ( 1 - P "\r" ) ^ 0 ) ^ -1 
-  ) / math.min
+local TabsAutoGobbleLPEG =
+       (
+         (
+           P "\t" ^ 0 * "\r"
+           +
+           Ct ( C "\t" ^ 0 ) / table.getn
+           * ( 1 - P "\t" ) * ( 1 - P "\r" ) ^ 0 * "\r"
+         ) ^ 0
+         * ( Ct ( C "\t" ^ 0 ) / table.getn
+             * ( 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
@@ -7502,15 +6996,17 @@ local TabsAutoGobbleLPEG =
 % traditionnal way to indent in LaTeX). 
 %    \begin{macrocode}
 local EnvGobbleLPEG =
-  ( ( 1 - P "\r" ) ^ 0 * P "\r" ) ^ 0 * ( C ( P " " )  ^ 0 / count_captures ) * -1
+      ( ( 1 - P "\r" ) ^ 0 * "\r" ) ^ 0
+    * Ct ( C " " ^ 0 * -1 ) / table.getn 
 %    \end{macrocode}
 % 
 % \bigskip
 %    \begin{macrocode}
-local function remove_before_cr(input_string)
-    local match_result = P("\r") : match(input_string)
-    if match_result then
-        return string.sub(input_string, match_result ) 
+local function remove_before_cr ( input_string )
+    local match_result = ( P "\r" ) : match ( input_string )
+    if match_result 
+    then
+        return string.sub ( input_string , match_result ) 
     else
         return input_string 
     end
@@ -7518,38 +7014,39 @@ end
 %    \end{macrocode}
 %
 % \bigskip
+% In the following code, |n| is the value of |\l_@@_gobble_int|.
 %    \begin{macrocode}
-function piton.GobbleParse(language,n,code)
-  code = remove_before_cr(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)
+function piton.GobbleParse ( language , n , code )
+  code = remove_before_cr ( 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.last_code = gobble(n,code)
-  piton.Parse(language,piton.last_code)
+  piton.last_code = gobble ( n , code )
+  piton.Parse ( language , piton.last_code )
   piton.last_language = language
 %    \end{macrocode}
 % Now, if the final user has used the key |write| to write the code of the
 % environment on an external file.
 %    \begin{macrocode}
   if piton.write ~= ''
-  then local file = assert(io.open(piton.write,piton.write_mode))
-       file:write(piton.get_last_code()) 
-       file:close()
+  then local file = assert ( io.open ( piton.write , piton.write_mode ) )
+       file:write ( piton.get_last_code ( ) ) 
+       file:close ( )
   end
 end 
 %    \end{macrocode}
 %
 % \bigskip
-% The following Lua function is provided to the developper. 
+% The following public Lua function is provided to the developper. 
 %    \begin{macrocode}
 function piton.get_last_code ( ) 
-  return CleanLPEGs[piton.last_language] : match(piton.last_code) 
+  return LPEG_cleaner[piton.last_language] : match ( piton.last_code ) 
 end
 %    \end{macrocode}
 % 
@@ -7559,25 +7056,25 @@ end
 %
 % \medskip
 %    \begin{macrocode}
-function piton.CountLines(code)
+function piton.CountLines ( code )
   local count = 0 
   for i in code : gmatch ( "\r" ) do count = count + 1 end 
-  tex.sprint( 
+  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 = 
-  (  (  (  ( 
-            ( P " " ) ^ 0 * P "\r"  
-              + ( 1 - P "\r" ) ^ 0 * C ( P "\r" ) 
-            ) ^ 0 
-          * (1 - P "\r" ) ^ 0 
-       ) / count_captures ) * -1 ) : match (code) 
+function piton.CountNonEmptyLines ( code )
+  local count = 0
+  count =
+     ( Ct ( ( P " " ^ 0 * "\r"
+              + ( 1 - P "\r" ) ^ 0 * C "\r" ) ^ 0
+            * ( 1 - P "\r" ) ^ 0 
+            * -1
+          ) / table.getn
+     ) : match ( code )
   tex.sprint( 
       luatexbase.catcodetables.expl , 
       '\\int_set:Nn \\l_@@_nb_non_empty_lines_int {' .. count .. '}' )
@@ -7586,11 +7083,11 @@ end
 %
 % \bigskip
 %    \begin{macrocode}
-function piton.CountLinesFile(name)
+function piton.CountLinesFile ( name )
   local count = 0 
-  io.open(name) 
-  for line in io.lines(name) do count = count + 1 end
-  tex.sprint( 
+  io.open ( name ) 
+  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 
@@ -7599,14 +7096,14 @@ end
 %
 % \bigskip
 %    \begin{macrocode}
-function piton.CountNonEmptyLinesFile(name)
+function piton.CountNonEmptyLinesFile ( name )
   local count = 0 
-  for line in io.lines(name) 
-  do if not ( ( ( P " " ) ^ 0 * -1 ) : match ( line ) ) 
+  for line in io.lines ( name ) 
+  do if not ( ( P " " ^ 0 * -1 ) : match ( line ) ) 
      then count = count + 1 
      end
   end
-  tex.sprint( 
+  tex.sprint ( 
       luatexbase.catcodetables.expl , 
       '\\int_set:Nn \\l_@@_nb_non_empty_lines_int {' .. count .. '}' )
 end 
@@ -7624,12 +7121,12 @@ function piton.ComputeRange(marker_beginning,marker_end,file_name)
   local first_line = -1
   local count = 0
   local last_found = false
-  for line in io.lines(file_name)
+  for line in io.lines ( file_name )
   do if first_line == -1
-     then if string.sub(line,1,#s) == s 
+     then if string.sub ( line , 1 , #s ) == s 
           then first_line = count 
           end 
-     else if string.sub(line,1,#t) == t
+     else if string.sub ( line , 1 , #t ) == t
           then last_found = true 
                break 
           end 
@@ -7637,16 +7134,332 @@ function piton.ComputeRange(marker_beginning,marker_end,file_name)
      count = count + 1 
   end
   if first_line == -1 
-  then tex.sprint("\\PitonBeginMarkerNotFound")
+  then tex.sprint ( luatexbase.catcodetables.expl ,
+                    "\\@@_error:n { begin~marker~not~found }" )
   else if last_found == false
-       then tex.sprint("\\PitonEndMarkerNotFound")
+       then tex.sprint ( luatexbase.catcodetables.expl ,
+                         "\\@@_error:n { end~marker~not~found }" )
        end
   end
-  tex.sprint( 
+  tex.sprint ( 
       luatexbase.catcodetables.expl , 
       '\\int_set:Nn \\l_@@_first_line_int {' .. first_line .. ' + 2 }' 
       .. '\\int_set:Nn \\l_@@_last_line_int {' .. count .. ' }' )
 end
+%    \end{macrocode}
+%
+% \bigskip
+% \subsubsection{To create new languages with the syntax of listings}
+%
+%    \begin{macrocode}
+function piton.new_language ( lang , definition )
+  lang = string.lower ( lang )
+%    \end{macrocode}
+%
+% \bigskip
+%    \begin{macrocode}
+  local alpha , digit = lpeg.alpha , lpeg.digit 
+  local letter = alpha + S "@_$" -- $
+%    \end{macrocode}
+%
+% \bigskip 
+% In the following \textsc{lpeg} we have a problem when we try to add |{| and
+% |}|. 
+%    \begin{macrocode}
+  local other = S "+-*/<>!?:;.()@[]~^=#&\"\'\\$" -- $
+%    \end{macrocode}
+% 
+% \bigskip
+%    \begin{macrocode}
+  function add_to_letter ( c )
+     if c ~= " " then letter = letter + c end 
+  end 
+  function add_to_digit ( c )
+     if c ~= " " then digit = digit + c end 
+  end 
+%    \end{macrocode}
+% 
+% \bigskip
+% Of course, the \textsc{lpeg} |b_braces| is for balanced braces (without the
+% question of strings of an informatic language). In fact, it \emph{won't} be
+% used for an informic language (as dealt by \pkg{piton}) but for LaTeX
+% instructions; 
+%    \begin{macrocode}
+  local strict_braces  =
+    P { "E" , 
+        E = ( "{" * V "F" * "}" + ( 1 - S ",{}" ) ) ^ 0  ,
+        F = ( "{" * V "F" * "}" + ( 1 - S "{}" ) ) ^ 0 
+      }
+%    \end{macrocode}
+%
+% \bigskip
+% Now, the first transformation of the definition of the language, as provided
+% by the final user in the argument |definition| of |piton.new_language|.
+%    \begin{macrocode}
+  local cut_definition =
+    P { "E" ,
+        E = Ct ( V "F" * ( "," * V "F" ) ^ 0 ) ,
+        F = Ct ( space ^ 0 * C ( alpha ^ 1 ) * space ^ 0 
+                * ( "=" * space ^ 0 * C ( strict_braces ) ) ^ -1 )
+      }
+  local def_table = cut_definition : match ( definition )
+%    \end{macrocode}
+% The definition of the language, provided by the final user of \pkg{piton} is
+% now in the Lua table |def_table|. We will use it several times.
+%
+% \medskip
+% \bigskip
+% We scan the definition of the language (i.e. the table |def_table|) in order
+% to detect the potential key |sensitive|. Indeed, we have to catch that key
+% before the treatment of the keywords of the language. We will also look for
+% the potential keys |alsodigit| and |alsoletter|. 
+%    \begin{macrocode}
+  local sensitive = true 
+  for _ , x in ipairs ( def_table )
+  do if x[1] == "sensitive"
+     then if x[2] == nil or ( P "true" ) : match ( x[2] ) 
+          then sensitive = true 
+          else if ( P "false" ) : match ( x[2] ) then sensitive = false end
+          end
+     end
+     if x[1] == "alsodigit" then x[2] : gsub ( "." , add_to_digit ) end 
+     if x[1] == "alsoletter" then x[2] : gsub ( "." , add_to_letter ) end 
+  end
+%    \end{macrocode}
+% Now, the \textsc{lpeg} for the numbers. Of course, it uses |digit| previously
+% computed. 
+%    \begin{macrocode}
+  local Number =
+    K ( 'Number' ,
+        ( digit ^ 1 * "." * # ( 1 - P "." ) * digit ^ 0 
+          + digit ^ 0 * "." * digit ^ 1 
+          + digit ^ 1 )
+        * ( S "eE" * S "+-" ^ -1 * digit ^ 1 ) ^ -1
+        + digit ^ 1 
+      ) 
+%    \end{macrocode}
+% 
+%    \begin{macrocode}
+  local alphanum = letter + digit
+  local identifier = letter * alphanum ^ 0
+  local Identifier = K ( 'Identifier' , identifier )
+%    \end{macrocode}
+%
+% 
+% \bigskip
+% Now, we scan the definition of the language (i.e. the table |def_table|) for
+% the keywords.
+%
+% The following LPEG catches the optional argument (between square brackets) in
+% first position.
+%    \begin{macrocode}
+  local option = "[" * C ( ( 1 - P "]" ) ^ 0 ) * "]" 
+%    \end{macrocode}
+%
+% The following LPEG does \emph{not} catch the optional argument between square
+% brackets in first position.
+%    \begin{macrocode}
+  local split_clist = 
+    P { "E" ,
+         E = ( "[" * ( 1 - P "]" ) ^ 0 * "]" ) ^ -1  
+             * ( P "{" ) ^ 1
+             * Ct ( V "F" * ( "," * V "F" ) ^ 0 ) 
+             * ( P "}" ) ^ 1 * space ^ 0 ,
+         F = space ^ 0 * C ( letter * alphanum ^ 0 + other ^ 1 ) * space ^ 0 
+      }
+%    \end{macrocode}
+% The following function will be used if the keywords are not case-sensitive.
+%    \begin{macrocode}
+  local function keyword_to_lpeg ( name ) 
+  return 
+    Q ( Cmt ( 
+              C ( identifier ) , 
+              function(s,i,a) return string.upper(a) == string.upper(name) end 
+            ) 
+      ) 
+  end 
+  local Keyword = P ( false )  
+%    \end{macrocode}
+% Now, we actually treat all the keywords.
+%    \begin{macrocode}
+  for _ , x in ipairs ( def_table )
+  do if x[1] == "morekeywords" or x[1] == "otherkeywords" then
+        local keywords = P ( false ) 
+        for _ , word in ipairs ( split_clist : match ( x[2] ) )
+        do if sensitive 
+%    \end{macrocode}
+% The documentation of \pkg{lstlistings} specifies that, for the key
+% |otherkeywords|, if a keyword is a prefix of another keyword, then the prefix
+% must appear first. However, for the \text{lpeg}, it's rather the contrary.
+% That's why, here, we add the new element \emph{on the left}.
+%    \begin{macrocode}
+           then keywords = Q ( word  ) + keywords
+           else keywords = keyword_to_lpeg ( word ) + keywords
+           end 
+        end
+        Keyword = Keyword + 
+           Lc ( "{" 
+                 ..  ( option : match ( x[2] ) or "\\PitonStyle{Keyword}" ) 
+                 .. "{" )
+           * keywords * Lc "}}" 
+     end 
+     if x[1] == "keywordsprefix" then
+       local prefix = ( ( C ( 1 - P " " ) ^ 1 ) * P " " ^ 0 ) : match ( x[2] ) 
+       Keyword = Keyword + K ( 'Keyword' , P ( prefix ) * alphanum ^ 0 ) 
+     end 
+  end    
+%    \end{macrocode}
+%
+% \bigskip
+% Now, we scan the definition of the language (i.e. the table |def_table|) for
+% the strings.
+%    \begin{macrocode}
+  local long_string  = P ( false )
+  local LongString = P (false ) 
+  local args = "[" * C ( ( 1 - P "]" ) ^ 0 ) * "]" 
+               * space ^ 0 
+               * ( "[" * C ( ( 1 - P "]" ) ^ 0 ) * "]" + Cc ( nil ) ) 
+               * space ^ 0 
+               * ( "{" * C ( ( 1 - P "}" ) ^ 0 ) * "}" + C ( 1 ) ) 
+  local central_pattern = P ( false ) 
+  for _ , x in ipairs ( def_table )
+  do if x[1] == "morestring" then
+       arg1 , arg2 , arg3 = args : match ( x[2] ) 
+       arg2 = arg2 or "\\PitonStyle{String.Long}" 
+       if arg1 == "b" then 
+         central_pattern = Q ( ( P ( "\\" .. arg3 )  + 1 - S ( " \r" .. arg3 ) ) ^ 1 ) 
+       end
+       if arg1 == "d" then 
+         central_pattern = Q ( ( P ( arg3 .. arg3 )  + 1 - S ( " \r" .. arg3 ) ) ^ 1 ) 
+       end
+       if arg1 == "bd" then 
+         central_pattern = 
+           Q ( ( P ( arg3 .. arg3 ) + P ( "\\" .. arg3 ) + 1 - S ( " \r" .. arg3 ) ) ^ 1 ) 
+       end
+       if arg1 == "m" then 
+         central_pattern =  Q ( ( P ( arg3 .. arg3 ) + 1 - S ( " \r" .. arg3 ) ) ^ 1 ) 
+       end
+       if arg1 == "m" 
+       then prefix = P ( false ) 
+       else prefix = lpeg.B ( 1 - letter - ")" - "]" ) 
+       end
+%    \end{macrocode}
+% First, we create |long_string| because we need that \textsc{lpeg} in the
+% nested comments.
+%    \begin{macrocode}
+       long_string = long_string +
+         prefix * ( Q ( arg3 ) * ( VisualSpace + central_pattern + EOL ) ^ 0 * Q ( arg3 ) )
+       LongString = LongString +
+          Ct ( Cc "Open" * Cc ( "{" ..  arg2 .. "{" ) * Cc "}}" )
+          * long_string 
+          * Ct ( Cc "Close" ) 
+     end 
+  end
+
+  local braces = Compute_braces ( String ) 
+  if piton.beamer then Beamer = Compute_Beamer ( lang , braces ) end
+
+  DetectedCommands = Compute_DetectedCommands ( lang , braces ) 
+
+  LPEG_cleaner[lang] = Compute_LPEG_cleaner ( lang , braces ) 
+%    \end{macrocode}
+%
+% \bigskip
+% Now, we deal with the comments.
+%    \begin{macrocode}
+  local Comment = P ( false ) 
+
+  local args = "[" * C ( ( 1 - P "]" ) ^ 0 ) * "]" 
+               * space ^ 0 
+               * ( "[" * C ( ( 1 - P "]" ) ^ 0 ) * "]" + Cc ( nil ) ) 
+               * space ^ 0
+               * ( "{" * C ( ( 1 - P "}" ) ^ 0 ) * "}" + C ( 1 ) ) 
+               * space ^ 0
+               * ( "{" * C ( ( 1 - P "}" ) ^ 0 ) * "}" + Cc ( nil ) ) 
+
+  for _ , x in ipairs ( def_table )
+  do if x[1] == "morecomment"
+     then local arg1 , arg2 , arg3 , arg4 = args : match ( x[2] ) 
+          arg2 = arg2 or "\\PitonStyle{Comment}"
+          if arg1 == "l" then 
+            if arg3 == [[\#]] then arg3 = "#" end -- mandatory
+            Comment = Comment + 
+                Ct ( Cc "Open" 
+                     * Cc ( "{" .. arg2 .. "{" ) * Cc "}}" ) 
+                     *  Q ( arg3 ) 
+                     * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 -- $
+                * Ct ( Cc "Close" ) 
+                * ( EOL + -1 )
+           end 
+           if arg1 == "s" then 
+             Comment = Comment +
+                 Ct ( Cc "Open" * Cc ( "{" .. arg2 .. "{" ) * Cc "}}" ) 
+                 * Q ( arg3 ) 
+                 * ( 
+                     CommentMath 
+                     + Q ( ( 1 - P ( arg4 ) - S "$\r" ) ^ 1 ) -- $
+                     + EOL 
+                   ) ^ 0  
+                 * Q ( arg4 ) 
+                 * Ct ( Cc "Close" ) 
+           end
+           if arg1 == "n" then 
+             Comment = Comment +
+               Ct ( Cc "Open" * Cc ( "{" .. arg2 .. "{" ) * Cc "}}" ) 
+                * P { "A" ,
+                     A = Q ( arg3 ) 
+                         * ( V "A" 
+                             + Q ( ( 1 - P ( arg3 ) - P ( arg4 ) 
+                                     - S "\r$\"" ) ^ 1 ) -- $
+                             + long_string
+                             +   "$" -- $
+                                 * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1 ) --$
+                                 * "$" -- $
+                             + EOL
+                           ) ^ 0 
+                         * Q ( arg4 )
+                    }  
+               * Ct ( Cc "Close" ) 
+           end
+      end 
+  end 
+
+  local Delim = Q ( S "{[()]}" )
+  local Punct = Q ( S ",:;!\\'\"" )
+
+  local Main = 
+         space ^ 1 * -1
+       + space ^ 0 * EOL 
+       + Space 
+       + Tab
+       + Escape + EscapeMath 
+       + CommentLaTeX
+       + Beamer
+       + DetectedCommands
+       + Comment 
+       + Delim
+       + LongString
+        -- should maybe be after the following line!
+       + Keyword * ( Space + Punct + Delim + EOL + -1 ) 
+       + Punct 
+       + K ( 'Identifier' , letter * alphanum ^ 0 )
+       + Number
+       + Word
+
+  LPEG1[lang] = Main ^ 0 
+
+  LPEG2[lang] = 
+    Ct (
+         ( space ^ 0 * P "\r" ) ^ -1 
+         * BeamerBeginEnvironments 
+         * Lc '\\@@_begin_line:'
+         * SpaceIndentation ^ 0 
+         * LPEG1[lang]
+         * -1 
+         * Lc '\\@@_end_line:' 
+       )
+
+end
 %</LUA>
 %    \end{macrocode}
 % 
@@ -7723,7 +7536,7 @@ end
 %
 % \subsection*{Changes between versions 1.6 and 2.0}
 %
-% The extension \pkg{piton} nows supports the computer languages OCaml and C
+% The extension \pkg{piton} now supports the computer languages OCaml and C
 % (and, of course, Python).
 %
 % \subsection*{Changes between versions 1.5 and 1.6}
@@ -7777,48 +7590,6 @@ end
 % 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}
-- 
cgit v1.2.3

