summaryrefslogtreecommitdiff
path: root/macros/luatex/latex/piton/piton.dtx
diff options
context:
space:
mode:
Diffstat (limited to 'macros/luatex/latex/piton/piton.dtx')
-rw-r--r--macros/luatex/latex/piton/piton.dtx2331
1 files changed, 1051 insertions, 1280 deletions
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 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.
+% 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
+% 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 languages = { }
-local CleanLPEGs = { }
+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 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,170 +5644,26 @@ 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}
%
@@ -5595,17 +5673,17 @@ 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}