summaryrefslogtreecommitdiff
path: root/macros/luatex/latex/piton/piton.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2023-04-05 03:02:06 +0000
committerNorbert Preining <norbert@preining.info>2023-04-05 03:02:06 +0000
commit085271aaf9917d7116be9774c6cd0a117aa4111e (patch)
treef222fa9f21aed2a069c8d380429558a802964b66 /macros/luatex/latex/piton/piton.dtx
parente9f267fd4c8414d6146c5fee0dbe459613dd0f3b (diff)
CTAN sync 202304050302
Diffstat (limited to 'macros/luatex/latex/piton/piton.dtx')
-rw-r--r--macros/luatex/latex/piton/piton.dtx1161
1 files changed, 690 insertions, 471 deletions
diff --git a/macros/luatex/latex/piton/piton.dtx b/macros/luatex/latex/piton/piton.dtx
index 126c19dc10..8d8caee54f 100644
--- a/macros/luatex/latex/piton/piton.dtx
+++ b/macros/luatex/latex/piton/piton.dtx
@@ -15,8 +15,8 @@
%
% \fi
% \iffalse
-\def\myfileversion{1.4}
-\def\myfiledate{2023/02/14}
+\def\myfileversion{1.5}
+\def\myfiledate{2023/04/04}
%
%
%<*batchfile>
@@ -125,7 +125,6 @@ version 2005/12/01 or later.
%
%
% \bigskip
-%
% The package \pkg{piton} is entirely contained in the file
% |piton.sty|. This file may be put in the current directory or in a
% |texmf| tree. However, the best is to install \pkg{piton} with a TeX
@@ -193,29 +192,33 @@ version 2005/12/01 or later.
% When its argument is given between curly braces, the command |\piton| does not
% take its argument in verbatim mode. In particular:
% \begin{itemize}
-% \item several consecutive spaces will be replaced by only one space;
-% \item it's not possible to use |%| inside the argument;
-% \item the braces must be appear by pairs correctly nested;
-% \item the LaTeX commands (those beginning with a backslash |\| but also the
-% active characters) are fully expanded (but not executed).
-% \end{itemize}
+% \item several consecutive spaces will be replaced by only one space,
+%
+% {\color{cyan} but the command |\|␣ is provided to force the insertion of a space};
%
-% An escaping mechanism is provided: the commands |\\|, |\%|, |\{| and |\}|
-% insert the corresponding characters |\|, |%|, |{| and |}|. The last two
-% commands are necessary only if one need to insert braces which are not
-% balanced.
+% \item it's not possible to use |%| inside the argument,
+%
+% {\color{cyan} but the command |\%| is provided to insert a |%|};
+%
+% \item the braces must be appear by pairs correctly nested
+%
+% {\color{cyan} but the commands |\{| and |\}| are also provided for individual braces};
+%
+% \item the LaTeX commands\footnote{That concerns the commands beginning with a
+% backslash but also the active characters.} are fully expanded and not
+% executed,
+%
+% {\color{cyan} so it's possible to use |\\| to insert a backslash}.
+% \end{itemize}
%
-% \smallskip
-% The command |\|␣ inserts a space. It may be used in order to insert several
-% consecutive spaces.
%
-% \smallskip
% The other characters (including |#|, |^|, |_|, |&|, |$| and |@|)
% must be inserted without backslash.
%
-% Examples:
-%
-%\begin{tabular}{>{\color{gray}}l@{\hspace*{1cm}}l}
+% \bigskip
+%\begin{tabular}{>{\color{gray}}w{l}{75mm}@{\hspace*{1cm}}l}
+% \omit Examples : \hfil \\
+% \noalign{\vskip1mm}
% \verb|\piton{MyString = '\\n'}| &
% \piton{MyString = '\\n'} \\
% \verb|\piton{def even(n): return n\%2==0}| &
@@ -228,7 +231,7 @@ version 2005/12/01 or later.
% \piton{MyDict = {'a': 3, 'b': 4 }}
% \end{tabular}
%
-%
+% \bigskip
% It's possible to use the command |\piton| in the arguments of a
% LaTeX command.\footnote{For example, it's possible to use the command
% \texttt{\textbackslash piton} in a footnote. Example :
@@ -243,9 +246,10 @@ version 2005/12/01 or later.
% command.
%
% \medskip
-% Examples:
%
-% \begin{tabular}{>{\color{gray}}l@{\hspace*{1cm}}l}
+% \begin{tabular}{>{\color{gray}}w{l}{75mm}@{\hspace*{1cm}}l}
+% \omit Examples : \hfil \\
+% \noalign{\vskip1mm}
% \verb!\piton|MyString = '\n'|! &
% \piton|MyString = '\n'| \\
% \verb|\piton!def even(n): return n%2==0!| &
@@ -299,7 +303,13 @@ version 2005/12/01 or later.
% \item With the key \Definition{all-line-numbers}, \emph{all} the lines are numbered,
% including the empty ones.
%
-% \item With the key \Definition{resume} the counter of lines is not set to zero
+% \item \colorbox{yellow!50}{\bfseries{New 1.5}}\par\nobreak
+%
+% The key \Definition{numbers-sep} is the horizontal distance between the
+% numbers of lines (inserted by |line-numbers| of |all-line-numbers|) and the
+% beginning of the lines of code. The initial value is 0.7~em.
+%
+% \item With the key \Definition{resume}, the counter of lines is not set to zero
% at the beginning of each environment |{Piton}| or use of |\PitonInputFile| as
% it is otherwise. That allows a numbering of the lines across several
% environments.
@@ -340,13 +350,14 @@ version 2005/12/01 or later.
% character~U+2423 must be present in the monospaced font which is
% used.\footnote{The package \pkg{piton} simply uses the current monospaced
% font. The best way to change that font is to use the command
-% \texttt{\textbackslash setmonofont} of \pkg{fontspec}.}\par\nobreak
+% \texttt{\textbackslash setmonofont} of the package \pkg{fontspec}.}\par\nobreak
% \begingroup \PitonOptions{show-spaces-in-strings} Example :
% \piton|my_string = 'Very good answer'| \endgroup
%
% With the key \Definition{show-spaces}, all the spaces are replaced by U+2423
% (and no line break can occur on those ``visible spaces'', even when the key
-% |break-lines| is in force).
+% |break-lines|\footnote{cf. \ref{line-breaks} p.~\pageref{line-breaks}} is in
+% force).
% \end{itemize}
%
% \bigskip
@@ -551,7 +562,7 @@ version 2005/12/01 or later.
% {\end{tcolorbox}}
% \end{verbatim}
%
-\bigskip
+% \bigskip
% With this new environment |{Python}|, it's possible to write:
%
% \begin{Verbatim}
@@ -597,7 +608,7 @@ version 2005/12/01 or later.
% \end{itemize}
%
% \emph{Caution}: Only the identifiers may be concerned by that key. The
-% keywords and the built-in functions won't be affected, even if their names is
+% keywords and the built-in functions won't be affected, even if their name is
% in the list |\textsl{\ttfamily names}|.
%
% \begin{Verbatim}
@@ -882,6 +893,16 @@ version 2005/12/01 or later.
%
% \label{beamer}
%
+% \emph{First remark}\par\nobreak
+% Since the environment |{Piton}| catches its body with a verbatim mode,
+% it's necessary to use the environments |{Piton}| within environments |{frame}|
+% of Beamer protected by the key |fragile|.\footnote{Remind that for an
+% environment \texttt{\{frame\}} of Beamer using the key |fragile|, the
+% instruction \texttt{\textbackslash end\{frame\}} must be alone on a single
+% line (except for any leading whitespace).}
+%
+%
+% \bigskip
% When the package \pkg{piton} is used within the class
% \cls{beamer}\footnote{The extension \pkg{piton} detects the class \cls{beamer}
% but, if needed, it's also possible to activate that mechanism with the key
@@ -927,26 +948,11 @@ version 2005/12/01 or later.
% \end{itemize}
% \medskip
-% However, there is two restrictions for the content of the mandatory arguments
-% of these commands.
-% \begin{itemize}
-% \item In the mandatory arguments of these commands, the braces must be
-% balanced. However, the braces includes in short strings\footnote{The
-% short strings of Python are the strings delimited by characters \texttt{'} or
-% the characters \texttt{"} and not \texttt{'''} nor \texttt{"""}. In Python,
-% the short strings can't extend on several lines.} of Python are not considered.
-% \item The must be \textbf{no carriage return} in the mandatory arguments of the
-% command (if there is, a fatal error will be raised). For multi-lines elements,
-% one should consider the corresponding environments (see below).
-% \end{itemize}
-%
-% \medskip
-% Remark that, since the environment |{Piton}| catches its body with a verbatim
-% mode, it's necessary to use the environments |{Piton}| within environments
-% |{frame}| of Beamer protected by the key |fragile|.\footnote{Remind that for
-% an environment \texttt{\{frame\}} of Beamer using the key |fragile|, the
-% instruction \texttt{\textbackslash end\{frame\}} must be alone on a single
-% line (except for any leading whitespace).}
+% In the mandatory arguments of these commands, the braces must be balanced.
+% However, the braces included in short strings\footnote{The short strings of
+% Python are the strings delimited by characters \texttt{'} or the characters
+% \texttt{"} and not \texttt{'''} nor \texttt{"""}. In Python, the short strings
+% can't extend on several lines.} of Python are not considered.
%
% \medskip
% Here is a complete example of file:
@@ -984,7 +990,7 @@ version 2005/12/01 or later.
%
% However, there is a restriction: these environments must contain only \emph{whole
% lines of Python code} in their body.
-%%
+%
%\medskip
% Here is an example:
%
@@ -1076,6 +1082,8 @@ version 2005/12/01 or later.
%
% \subsubsection{Line breaks}
%
+% \label{line-breaks}
+%
% By default, the elements produced by \pkg{piton} can't be broken by an end on
% line. However, there are keys to allow such breaks (the possible breaking
% points are the spaces, even the spaces in the Python strings).
@@ -1089,7 +1097,6 @@ version 2005/12/01 or later.
% \item The key |break-lines| is a conjonction of the two previous keys.
% \end{itemize}
%
-
% \bigskip
% The package \pkg{piton} provides also several keys to control the appearance
% on the line breaks allowed by |break-lines-in-Piton|.
@@ -1385,7 +1392,7 @@ version 2005/12/01 or later.
% If an environment |{Piton}| is used in an environment |{minipage}| of LaTeX,
% the notes are composed, of course, at the foot of the environment
% |{minipage}|. Recall that such |{minipage}| can't be broken by a page break.
-
+%
%
% \begingroup
% \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
@@ -1747,7 +1754,7 @@ version 2005/12/01 or later.
% \subsection{The L3 part of the implementation}
%
% \subsubsection{Declaration of the package}
-% \begin{macrocode}
+% \begin{macrocode}
\NeedsTeXFormat{LaTeX2e}
\RequirePackage{l3keys2e}
\ProvidesExplPackage
@@ -1760,7 +1767,13 @@ version 2005/12/01 or later.
% \bigskip
% \begin{macrocode}
\msg_new:nnn { piton } { LuaLaTeX~mandatory }
- { The~package~'piton'~must~be~used~with~LuaLaTeX.\\ It~won't~be~loaded. }
+ {
+ LuaLaTeX~is~mandatory.\\
+ The~package~'piton'~requires~the~engine~LuaLaTeX.\\
+ \str_if_eq:VnT \c_sys_jobname_str { output }
+ { If~you~use~Overleaf,~you~can~switch~to~LuaLaTeX~in~the~"Menu". \\}
+ If~you~go~on,~the~package~'piton'~won't~be~loaded.
+ }
\sys_if_engine_luatex:F { \msg_critical:nn { piton } { LuaLaTeX~mandatory } }
% \end{macrocode}
%
@@ -2075,18 +2088,25 @@ version 2005/12/01 or later.
% \end{macrocode}
%
% \medskip
-% The following dimension corresponds to the key |left-margin| of
-% |\PitonOptions|.
+% The following dimension corresponds to the key |left-margin| of |\PitonOptions|.
% \begin{macrocode}
\dim_new:N \l_@@_left_margin_dim
% \end{macrocode}
%
% \medskip
-% The following boolean correspond will be set when the key |left-margin=auto|
+% The following boolean will be set when the key |left-margin=auto|
% is used.
% \begin{macrocode}
\bool_new:N \l_@@_left_margin_auto_bool
% \end{macrocode}
+%
+% \medskip
+% The following dimension corresponds to the key |numbers-sep| of
+% |\PitonOptions|.
+% \begin{macrocode}
+\dim_new:N \l_@@_numbers_sep_dim
+\dim_set:Nn \l_@@_numbers_sep_dim { 0.7 em }
+% \end{macrocode}
%
% \medskip
% The tabulators will be replaced by the content of the following token list.
@@ -2170,7 +2190,17 @@ version 2005/12/01 or later.
}
% \end{macrocode}
%
-%
+%
+% \bigskip
+% The following commands are a easy way to insert safely braces (|{| and |}|) in
+% the TeX flow.
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_open_brace:
+ { \directlua { piton.open_brace() } }
+\cs_new_protected:Npn \@@_close_brace:
+ { \directlua { piton.close_brace() } }
+% \end{macrocode}
+%
% \bigskip
% The following token list will be evaluated at the beginning of
% |\@@_begin_line:|... |\@@_end_line:| and cleared at the end. It will be used
@@ -2191,8 +2221,82 @@ version 2005/12/01 or later.
{ \clist_set:NV \l_@@_bg_color_clist \l_@@_prompt_bg_color_tl }
}
% \end{macrocode}
+%
%
+% \bigskip
+% You will keep track of the current style for the treatment of EOL (for the
+% multi-line syntactic elements).
+% \begin{macrocode}
+\clist_new:N \g_@@_current_style_clist
+\clist_set:Nn \g_@@_current_style_clist { __end }
+% \end{macrocode}
+% The element |__end| is an arbitrary syntactic marker.
+%
+% \medskip
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_close_current_styles:
+ {
+ \int_set:Nn \l_tmpa_int { \clist_count:N \g_@@_current_style_clist - 1 }
+ \exp_args:NV \@@_close_n_styles:n \l_tmpa_int
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_close_n_styles:n #1
+ {
+ \int_compare:nNnT { #1 } > 0
+ {
+ \@@_close_brace:
+ \@@_close_brace:
+ \@@_close_n_styles:n { #1 - 1 }
+ }
+ }
+% \end{macrocode}
%
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_open_current_styles:
+ { \exp_last_unbraced:NV \@@_open_styles:w \g_@@_current_style_clist , }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_open_styles:w #1 ,
+ {
+ \tl_if_eq:nnF { #1 } { __end }
+ { \@@_open_brace: #1 \@@_open_brace: \@@_open_styles:w }
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_pop_style:
+ {
+ \clist_greverse:N \g_@@_current_style_clist
+ \clist_gpop:NN \g_@@_current_style_clist \l_tmpa_tl
+ \clist_gpop:NN \g_@@_current_style_clist \l_tmpa_tl
+ \clist_gpush:Nn \g_@@_current_style_clist { __end }
+ \clist_greverse:N \g_@@_current_style_clist
+ }
+% \end{macrocode}
+%
+% \medskip
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_push_style:n #1
+ {
+ \clist_greverse:N \g_@@_current_style_clist
+ \clist_gpop:NN \g_@@_current_style_clist \l_tmpa_tl
+ \clist_gpush:Nn \g_@@_current_style_clist { #1 }
+ \clist_gpush:Nn \g_@@_current_style_clist { __end }
+ \clist_greverse:N \g_@@_current_style_clist
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_push_and_exec:n #1
+ {
+ \@@_push_style:n { #1 }
+ \@@_open_brace: #1 \@@_open_brace:
+ }
+% \end{macrocode}
+%
% \bigskip
% \subsubsection{Treatment of a line of code}
%
@@ -2226,8 +2330,8 @@ version 2005/12/01 or later.
% \bigskip
% In the contents provided by Lua, each line of the Python code will be
% surrounded by |\@@_begin_line:| and |\@@_end_line:|. |\@@_begin_line:| is a
-% LaTeX that we will define now but |\@@_end_line:| is only a syntactic marker
-% that has no definition.
+% LaTeX command that we will define now but |\@@_end_line:| is only a syntactic
+% marker that has no definition.
%
% \begin{macrocode}
\cs_set_protected:Npn \@@_begin_line: #1 \@@_end_line:
@@ -2270,7 +2374,13 @@ version 2005/12/01 or later.
\@@_print_number:
}
\clist_if_empty:NF \l_@@_bg_color_clist
- { \skip_horizontal:n { 0.5 em } }
+ {
+ \dim_compare:nNnT \l_@@_left_margin_dim = \c_zero_dim
+ {
+ \bool_if:NF \l_@@_left_margin_auto_bool
+ { \skip_horizontal:n { 0.5 em } }
+ }
+ }
\coffin_typeset:Nnnnn \l_tmpa_coffin T l \c_zero_dim \c_zero_dim
}
% \end{macrocode}
@@ -2448,6 +2558,8 @@ version 2005/12/01 or later.
}
{ \dim_set:Nn \l_@@_left_margin_dim { #1 } } ,
left-margin .value_required:n = true ,
+ numbers-sep .dim_set:N = \l_@@_numbers_sep_dim ,
+ numbers-sep .value_required:n = true ,
tab-size .code:n = \@@_set_tab_tl:n { #1 } ,
tab-size .value_required:n = true ,
show-spaces .bool_set:N = \l_@@_show_spaces_bool ,
@@ -2502,7 +2614,7 @@ version 2005/12/01 or later.
\hbox_overlap_left:n
{
{ \color { gray } \footnotesize \int_to_arabic:n \g_@@_visual_line_int }
- \skip_horizontal:n { 0.4 em }
+ \skip_horizontal:N \l_@@_numbers_sep_dim
}
}
% \end{macrocode}
@@ -2774,7 +2886,8 @@ version 2005/12/01 or later.
{ \g_@@_visual_line_int + \l_@@_nb_non_empty_lines_int }
}
}
- \dim_set:Nn \l_@@_left_margin_dim { \box_wd:N \l_tmpa_box + 0.5em }
+ \dim_set:Nn \l_@@_left_margin_dim
+ { \box_wd:N \l_tmpa_box + \l_@@_numbers_sep_dim + 0.1 em }
}
% \end{macrocode}
% Now, the main job.
@@ -2855,7 +2968,7 @@ version 2005/12/01 or later.
}
}
\dim_set:Nn \l_@@_left_margin_dim
- { \box_wd:N \l_tmpa_box + 0.5 em }
+ { \box_wd:N \l_tmpa_box + \l_@@_numbers_sep_dim + 0.1 em }
}
% \end{macrocode}
% Now, the main job.
@@ -2963,65 +3076,67 @@ version 2005/12/01 or later.
% \begin{macrocode}
\keys_define:nn { piton / Styles }
{
- String.Interpol .tl_set:c = pitonStyle String.Interpol ,
- String.Interpol .value_required:n = true ,
- FormattingType .tl_set:c = pitonStyle FormattingType ,
- FormattingType .value_required:n = true ,
- Dict.Value .tl_set:c = pitonStyle Dict.Value ,
- Dict.Value .value_required:n = true ,
- Name.Decorator .tl_set:c = pitonStyle Name.Decorator ,
- Name.Decorator .value_required:n = true ,
- Name.Function .tl_set:c = pitonStyle Name.Function ,
- Name.Function .value_required:n = true ,
- Keyword .tl_set:c = pitonStyle Keyword ,
- Keyword .value_required:n = true ,
- Keyword.Constant .tl_set:c = pitonStyle Keyword.Constant ,
- Keyword.constant .value_required:n = true ,
- String.Doc .tl_set:c = pitonStyle String.Doc ,
- String.Doc .value_required:n = true ,
- Interpol.Inside .tl_set:c = pitonStyle Interpol.Inside ,
- Interpol.Inside .value_required:n = true ,
- String.Long .tl_set:c = pitonStyle String.Long ,
- String.Long .value_required:n = true ,
- String.Short .tl_set:c = pitonStyle String.Short ,
- String.Short .value_required:n = true ,
- String .meta:n = { String.Long = #1 , String.Short = #1 } ,
- Comment.Math .tl_set:c = pitonStyle Comment.Math ,
- Comment.Math .default:n = \@@_math_scantokens:n ,
- Comment.Math .initial:n = ,
- Comment .tl_set:c = pitonStyle Comment ,
- Comment .value_required:n = true ,
- InitialValues .tl_set:c = pitonStyle InitialValues ,
- InitialValues .value_required:n = true ,
- Number .tl_set:c = pitonStyle Number ,
- Number .value_required:n = true ,
- Name.Namespace .tl_set:c = pitonStyle Name.Namespace ,
- Name.Namespace .value_required:n = true ,
- Name.Class .tl_set:c = pitonStyle Name.Class ,
- Name.Class .value_required:n = true ,
- Name.Builtin .tl_set:c = pitonStyle Name.Builtin ,
- Name.Builtin .value_required:n = true ,
- TypeParameter .tl_set:c = pitonStyle TypeParameter ,
- TypeParameter .value_required:n = true ,
- Name.Type .tl_set:c = pitonStyle Name.Type ,
- Name.Type .value_required:n = true ,
- Operator .tl_set:c = pitonStyle Operator ,
- Operator .value_required:n = true ,
- Operator.Word .tl_set:c = pitonStyle Operator.Word ,
- Operator.Word .value_required:n = true ,
- Exception .tl_set:c = pitonStyle Exception ,
- Exception .value_required:n = true ,
- Comment.LaTeX .tl_set:c = pitonStyle Comment.LaTeX ,
- Comment.LaTeX .value_required:n = true ,
- Identifier .tl_set:c = pitonStyle Identifier ,
- Comment.LaTeX .value_required:n = true ,
- ParseAgain.noCR .tl_set:c = pitonStyle ParseAgain.noCR ,
- ParseAgain.noCR .value_required:n = true ,
- ParseAgain .tl_set:c = pitonStyle ParseAgain ,
- ParseAgain .value_required:n = true ,
- Prompt .tl_set:c = pitonStyle Prompt ,
- Prompt .value_required:n = true ,
- unknown .code:n =
+ String.Interpol .tl_set:c = pitonStyle String.Interpol ,
+ String.Interpol .value_required:n = true ,
+ FormattingType .tl_set:c = pitonStyle FormattingType ,
+ FormattingType .value_required:n = true ,
+ Dict.Value .tl_set:c = pitonStyle Dict.Value ,
+ Dict.Value .value_required:n = true ,
+ Name.Decorator .tl_set:c = pitonStyle Name.Decorator ,
+ Name.Decorator .value_required:n = true ,
+ Name.Function .tl_set:c = pitonStyle Name.Function ,
+ Name.Function .value_required:n = true ,
+ Name.UserFunction .tl_set:c = pitonStyle Name.UserFunction ,
+ Name.UserFunction .value_required:n = true ,
+ Keyword .tl_set:c = pitonStyle Keyword ,
+ Keyword .value_required:n = true ,
+ Keyword.Constant .tl_set:c = pitonStyle Keyword.Constant ,
+ Keyword.constant .value_required:n = true ,
+ String.Doc .tl_set:c = pitonStyle String.Doc ,
+ String.Doc .value_required:n = true ,
+ Interpol.Inside .tl_set:c = pitonStyle Interpol.Inside ,
+ Interpol.Inside .value_required:n = true ,
+ String.Long .tl_set:c = pitonStyle String.Long ,
+ String.Long .value_required:n = true ,
+ String.Short .tl_set:c = pitonStyle String.Short ,
+ String.Short .value_required:n = true ,
+ String .meta:n = { String.Long = #1 , String.Short = #1 } ,
+ Comment.Math .tl_set:c = pitonStyle Comment.Math ,
+ Comment.Math .default:n = \@@_math_scantokens:n ,
+ Comment.Math .initial:n = ,
+ Comment .tl_set:c = pitonStyle Comment ,
+ Comment .value_required:n = true ,
+ InitialValues .tl_set:c = pitonStyle InitialValues ,
+ InitialValues .value_required:n = true ,
+ Number .tl_set:c = pitonStyle Number ,
+ Number .value_required:n = true ,
+ Name.Namespace .tl_set:c = pitonStyle Name.Namespace ,
+ Name.Namespace .value_required:n = true ,
+ Name.Class .tl_set:c = pitonStyle Name.Class ,
+ Name.Class .value_required:n = true ,
+ Name.Builtin .tl_set:c = pitonStyle Name.Builtin ,
+ Name.Builtin .value_required:n = true ,
+ TypeParameter .tl_set:c = pitonStyle TypeParameter ,
+ TypeParameter .value_required:n = true ,
+ Name.Type .tl_set:c = pitonStyle Name.Type ,
+ Name.Type .value_required:n = true ,
+ Operator .tl_set:c = pitonStyle Operator ,
+ Operator .value_required:n = true ,
+ Operator.Word .tl_set:c = pitonStyle Operator.Word ,
+ Operator.Word .value_required:n = true ,
+ Exception .tl_set:c = pitonStyle Exception ,
+ Exception .value_required:n = true ,
+ Comment.LaTeX .tl_set:c = pitonStyle Comment.LaTeX ,
+ Comment.LaTeX .value_required:n = true ,
+ Identifier .tl_set:c = pitonStyle Identifier ,
+ Comment.LaTeX .value_required:n = true ,
+ ParseAgain.noCR .tl_set:c = pitonStyle ParseAgain.noCR ,
+ ParseAgain.noCR .value_required:n = true ,
+ ParseAgain .tl_set:c = pitonStyle ParseAgain ,
+ ParseAgain .value_required:n = true ,
+ Prompt .tl_set:c = pitonStyle Prompt ,
+ Prompt .value_required:n = true ,
+ unknown .code:n =
\msg_error:nn { piton } { Unknown~key~for~SetPitonStyle }
}
% \end{macrocode}
@@ -3068,31 +3183,32 @@ version 2005/12/01 or later.
% \begin{macrocode}
\SetPitonStyle
{
- Comment = \color[HTML]{0099FF} \itshape ,
- Exception = \color[HTML]{CC0000} ,
- Keyword = \color[HTML]{006699} \bfseries ,
- Keyword.Constant = \color[HTML]{006699} \bfseries ,
- Name.Builtin = \color[HTML]{336666} ,
- Name.Decorator = \color[HTML]{9999FF},
- Name.Class = \color[HTML]{00AA88} \bfseries ,
- Name.Function = \color[HTML]{CC00FF} ,
- Name.Namespace = \color[HTML]{00CCFF} ,
- Number = \color[HTML]{FF6600} ,
- Operator = \color[HTML]{555555} ,
- Operator.Word = \bfseries ,
- String = \color[HTML]{CC3300} ,
- String.Doc = \color[HTML]{CC3300} \itshape ,
- String.Interpol = \color[HTML]{AA0000} ,
- Comment.LaTeX = \normalfont \color[rgb]{.468,.532,.6} ,
- Name.Type = \color[HTML]{336666} ,
- InitialValues = \@@_piton:n ,
- Dict.Value = \@@_piton:n ,
- Interpol.Inside = \color{black}\@@_piton:n ,
- TypeParameter = \color[HTML]{008800} \itshape ,
- Identifier = \@@_identifier:n ,
- Prompt = ,
- ParseAgain.noCR = \@@_piton_no_cr:n ,
- ParseAgain = \@@_piton:n ,
+ Comment = \color[HTML]{0099FF} \itshape ,
+ Exception = \color[HTML]{CC0000} ,
+ Keyword = \color[HTML]{006699} \bfseries ,
+ Keyword.Constant = \color[HTML]{006699} \bfseries ,
+ Name.Builtin = \color[HTML]{336666} ,
+ Name.Decorator = \color[HTML]{9999FF},
+ Name.Class = \color[HTML]{00AA88} \bfseries ,
+ Name.Function = \color[HTML]{CC00FF} ,
+ Name.Namespace = \color[HTML]{00CCFF} ,
+ Number = \color[HTML]{FF6600} ,
+ Operator = \color[HTML]{555555} ,
+ Operator.Word = \bfseries ,
+ String = \color[HTML]{CC3300} ,
+ String.Doc = \color[HTML]{CC3300} \itshape ,
+ String.Interpol = \color[HTML]{AA0000} ,
+ Comment.LaTeX = \normalfont \color[rgb]{.468,.532,.6} ,
+ Name.Type = \color[HTML]{336666} ,
+ InitialValues = \@@_piton:n ,
+ Dict.Value = \@@_piton:n ,
+ Interpol.Inside = \color{black}\@@_piton:n ,
+ TypeParameter = \color[HTML]{008800} \itshape ,
+ Identifier = \@@_identifier:n ,
+ Name.UserFunction = ,
+ Prompt = ,
+ ParseAgain.noCR = \@@_piton_no_cr:n ,
+ ParseAgain = \@@_piton:n ,
}
% \end{macrocode}
% The last styles |ParseAgain.noCR| and |ParseAgain| should be considered as
@@ -3109,11 +3225,13 @@ version 2005/12/01 or later.
% \end{macrocode}
%
% \bigskip
+%
+% \bigskip
% \subsubsection{Highlighting some identifiers}
%
% \begin{macrocode}
\cs_new_protected:Npn \@@_identifier:n #1
- { \cs_if_exist_use:c { PitonIdentifier #1 } { #1 } }
+ { \cs_if_exist_use:c { PitonIdentifier _ \l_@@_language_str _ #1 } { #1 } }
% \end{macrocode}
%
% \bigskip
@@ -3141,11 +3259,58 @@ version 2005/12/01 or later.
\clist_map_inline:Nn \l_@@_identifiers_names_tl
{
\tl_set_eq:cN
- { PitonIdentifier ##1 }
+ { PitonIdentifier _ \l_@@_language_str _ ##1 }
\l_@@_style_tl
}
}
% \end{macrocode}
+%
+%
+% \bigskip
+% In particular, we have an hightlighting of the indentifiers which are the
+% names of Python functions previously defined by the user. Indeed, when a
+% Python function is defined, the style |Name.Function.Internal| is applied to
+% that name. We define now that style (you define it directly and you short-cut
+% the function |\SetPitonStyle|).
+% \begin{macrocode}
+\cs_new_protected:cpn { pitonStyle Name.Function.Internal } #1
+ {
+% \end{macrocode}
+% First, the element is composed in the TeX flow with the style |Name.Function|
+% which is provided to the final user.
+% \begin{macrocode}
+ { \PitonStyle { Name.Function } { #1 } }
+% \end{macrocode}
+% Now, we specify that the name of the new Python function is a known identifier
+% that will be formated with the Piton style |Name.UserFunction|. Of course,
+% here the affectation is global because we have to exit many groups and even
+% the environments |{Piton}|).
+% \begin{macrocode}
+ \cs_gset_protected:cpn { PitonIdentifier _ \l_@@_language_str _ #1 }
+ { \PitonStyle{ Name.UserFunction } }
+% \end{macrocode}
+% Now, we put the name of that new user function in the dedicated sequence
+% (specific of the current language). That sequence will be used only by
+% |\PitonClearUserFunctions|.
+% \begin{macrocode}
+ \seq_if_exist:cF { g_@@_functions _ \l_@@_language_str _ seq }
+ { \seq_new:c { g_@@_functions _ \l_@@_language_str _ seq } }
+ \seq_gput_right:cn { g_@@_functions _ \l_@@_language_str _ seq } { #1 }
+ }
+% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+\NewDocumentCommand \PitonClearUserFunctions { ! O { \l_@@_language_str } }
+ {
+ \seq_if_exist:cT { g_@@_functions _ #1 _ seq }
+ {
+ \seq_map_inline:cn { g_@@_functions _ #1 _ seq }
+ { \cs_undefine:c { PitonIdentifier _ #1 _ ##1} }
+ \seq_gclear:c { g_@@_functions _ #1 _ seq }
+ }
+ }
+% \end{macrocode}
%
% \bigskip
% \subsubsection{Security}
@@ -3164,7 +3329,7 @@ version 2005/12/01 or later.
% \end{macrocode}
%
% \bigskip
-% \subsubsection{The errors messages of the package}
+% \subsubsection{The error messages of the package}
%
% \begin{macrocode}
\msg_new:nnnn { piton } { Unknown~key~for~PitonOptions }
@@ -3237,6 +3402,12 @@ version 2005/12/01 or later.
If~you~go~on,~that~argument~will~be~ignored.
}
% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+\msg_new:nnn { Piton } { Python~error }
+ { A~Python~error~has~been~detected. }
+% \end{macrocode}
%
% \bigskip
% \subsection{The Lua part of the implementation}
@@ -3265,6 +3436,19 @@ if piton.comment_latex == nil then piton.comment_latex = ">" end
piton.comment_latex = "#" .. piton.comment_latex
% \end{macrocode}
%
+%
+% \bigskip
+% The following functions are an easy way to safely insert braces (|{| and |}|)
+% in the TeX flow.
+% \begin{macrocode}
+function piton.open_brace ()
+ tex.sprint("{")
+end
+function piton.close_brace ()
+ tex.sprint("}")
+end
+% \end{macrocode}
+%
% \bigskip
% \subsubsection{Special functions dealing with LPEG}
%
@@ -3276,6 +3460,7 @@ local P, S, V, C, Ct, Cc = lpeg.P, lpeg.S, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Cc
local Cf, Cs , Cg , Cmt , Cb = lpeg.Cf, lpeg.Cs, lpeg.Cg , lpeg.Cmt , lpeg.Cb
local R = lpeg.R
% \end{macrocode}
+%
%
%
% \bigskip
@@ -3318,24 +3503,18 @@ end
% \end{macrocode}
%
% \bigskip
-% The function |K| creates a \textsc{lpeg} which will return as capture
-% the whole LaTeX code corresponding to a Python chunk (that is to say with the
+% The function |K| creates a \textsc{lpeg} which will return as capture the
+% whole LaTeX code corresponding to a Python chunk (that is to say with the
% LaTeX formatting instructions corresponding to the syntactic nature of that
-% Python chunk). The first argument is a pattern (that is to say a \textsc{lpeg}
-% without capture) and the second element is a Lua string corresponding to the
-% name of a \pkg{piton} style. If the second argument is not present, the
-% function |K| behaves as the function |Q| does.
-% \begin{macrocode}
-local function K(pattern, style)
- if style
- then
- return
+% Python chunk). The first argument is a Lua string corresponding to the name of
+% a \pkg{piton} style and the second element is a pattern (that is to say a
+% \textsc{lpeg} without capture)
+% \begin{macrocode}
+local function K(style, pattern)
+ return
Lc ( "{\\PitonStyle{" .. style .. "}{" )
* Q ( pattern )
* Lc ( "}}" )
- else
- return Q ( pattern )
- end
end
% \end{macrocode}
% The formatting commands in a given \pkg{piton} style (eg. the style |Keyword|)
@@ -3344,6 +3523,17 @@ end
% deal with both syntaxes, we have used two pairs of braces:
% |{\PitonStyle{Keyword}{|\texttt{\slshape text to format}|}}|.
%
+%
+% \bigskip
+% \begin{macrocode}
+local function WithStyle(style,pattern)
+ return
+ Ct ( Cc "Open" * Cc ( "{\\PitonStyle{" .. style .. "}{" ) * Cc "}}" )
+ * pattern
+ * Ct ( Cc "Close" )
+end
+% \end{macrocode}
+%
% \bigskip
% The following \textsc{lpeg} catches the Python chunks which are in LaTeX
% escapes (and that chunks will be considered as normal LaTeX constructions). We
@@ -3399,7 +3589,7 @@ local identifier = letter * alphanum ^ 0
% On the other hand, the \textsc{lpeg} |Identifier| (with a capital) also returns
% a \emph{capture}.
% \begin{macrocode}
-local Identifier = K ( identifier , 'Identifier' )
+local Identifier = K ( 'Identifier' , identifier)
% \end{macrocode}
%
% \bigskip
@@ -3417,11 +3607,10 @@ local Identifier = K ( identifier , 'Identifier' )
% \pkg{piton} styles (but this is only a convention).
% \begin{macrocode}
local Number =
- K (
+ K ( 'Number' ,
( digit^1 * P "." * digit^0 + digit^0 * P "." * digit^1 + digit^1 )
* ( S "eE" * S "+-" ^ -1 * digit^1 ) ^ -1
- + digit^1 ,
- 'Number'
+ + digit^1
)
% \end{macrocode}
%
@@ -3433,32 +3622,32 @@ local Number =
% \begin{macrocode}
local Word
if piton_begin_escape ~= ''
-then Word = K ( ( ( 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 = K ( ( ( 1 - space ) - S "'\"\r[()]" - digit ) ^ 1 )
+else Word = Q ( ( ( 1 - space ) - S "'\"\r[()]" - digit ) ^ 1 )
end
% \end{macrocode}
%
% \bigskip
% \begin{macrocode}
-local Space = ( K " " ) ^ 1
+local Space = ( Q " " ) ^ 1
-local SkipSpace = ( K " " ) ^ 0
+local SkipSpace = ( Q " " ) ^ 0
-local Punct = K ( S ".,:;!" )
+local Punct = Q ( S ".,:;!" )
local Tab = P "\t" * Lc ( '\\l_@@_tab_tl' )
% \end{macrocode}
%
% \bigskip
% \begin{macrocode}
-local SpaceIndentation = Lc ( '\\@@_an_indentation_space:' ) * ( K " " )
+local SpaceIndentation = Lc ( '\\@@_an_indentation_space:' ) * ( Q " " )
% \end{macrocode}
%
%
% \bigskip
% \begin{macrocode}
-local Delim = K ( S "[()]" )
+local Delim = Q ( S "[()]" )
% \end{macrocode}
%
% \bigskip
@@ -3480,26 +3669,26 @@ local VisualSpace = space * Lc "\\l_@@_space_tl"
% ligatures available in some fonts such as \emph{Fira Code} to be active.
% \begin{macrocode}
local Operator =
- K ( P "!=" + P "<>" + P "==" + P "<<" + P ">>" + P "<=" + P ">=" + P ":="
+ K ( 'Operator' ,
+ P "!=" + P "<>" + P "==" + P "<<" + P ">>" + P "<=" + P ">=" + P ":="
+ P "//" + P "**" + S "-~+/*%=<>&.@|"
- ,
- 'Operator'
)
local OperatorWord =
- K ( P "in" + P "is" + P "and" + P "or" + P "not" , 'Operator.Word')
+ K ( 'Operator.Word' ,P "in" + P "is" + P "and" + P "or" + P "not" )
local Keyword =
- K ( P "as" + P "assert" + P "break" + P "case" + P "class" + P "continue"
+ 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" ,
- 'Keyword' )
- + K ( P "True" + P "False" + P "None" , 'Keyword.Constant' )
+ + P "while" + P "with" + P "yield" + P "yield from" )
+ + K ( 'Keyword.Constant' ,P "True" + P "False" + P "None" )
local Builtin =
- K ( P "__import__" + P "abs" + P "all" + P "any" + P "bin" + P "bool"
+ 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"
@@ -3510,11 +3699,12 @@ local Builtin =
+ 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" ,
- 'Name.Builtin' )
+ + P "vars" + P "zip" )
+
local Exception =
- K ( P "ArithmeticError" + P "AssertionError" + P "AttributeError"
+ 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"
@@ -3533,10 +3723,10 @@ local Exception =
+ P "ConnectionResetError" + P "FileExistsError" + P "FileNotFoundError"
+ P "InterruptedError" + P "IsADirectoryError" + P "NotADirectoryError"
+ P "PermissionError" + P "ProcessLookupError" + P "TimeoutError"
- + P "StopAsyncIteration" + P "ModuleNotFoundError" + P "RecursionError" ,
- 'Exception' )
+ + P "StopAsyncIteration" + P "ModuleNotFoundError" + P "RecursionError" )
+
-local RaiseException = K ( P "raise" , 'Keyword' ) * SkipSpace * Exception * K ( P "(" )
+local RaiseException = K ( 'Keyword' , P "raise" ) * SkipSpace * Exception * Q ( P "(" )
% \end{macrocode}
%
@@ -3544,7 +3734,7 @@ local RaiseException = K ( P "raise" , 'Keyword' ) * SkipSpace * Exception * K (
% In Python, a ``decorator'' is a statement whose begins by |@| which patches
% the function defined in the following statement.
% \begin{macrocode}
-local Decorator = K ( P "@" * letter^1 , 'Name.Decorator' )
+local Decorator = K ( 'Name.Decorator' , P "@" * letter^1 )
% \end{macrocode}
%
% \bigskip
@@ -3556,7 +3746,7 @@ local Decorator = K ( P "@" * letter^1 , 'Name.Decorator' )
% Example:\enskip \piton{class myclass:}
% \begin{macrocode}
local DefClass =
- K ( P "class" , 'Keyword' ) * Space * K ( identifier , 'Name.Class' )
+ K ( 'Keyword' , P "class" ) * Space * K ( 'Name.Class' , identifier )
% \end{macrocode}
%
% If the word |class| is not followed by a identifier, it will be catched as
@@ -3580,17 +3770,16 @@ local DefClass =
% Example:\enskip \piton{import math, numpy}
% \begin{macrocode}
local ImportAs =
- K ( P "import" , 'Keyword' )
+ K ( 'Keyword' , P "import" )
* Space
- * K ( identifier * ( P "." * identifier ) ^ 0 ,
- 'Name.Namespace'
- )
+ * K ( 'Name.Namespace' ,
+ identifier * ( P "." * identifier ) ^ 0 )
* (
- ( Space * K ( P "as" , 'Keyword' ) * Space
- * K ( identifier , 'Name.Namespace' ) )
+ ( Space * K ( 'Keyword' , P "as" ) * Space
+ * K ( 'Name.Namespace' , identifier ) )
+
- ( SkipSpace * K ( P "," ) * SkipSpace
- * K ( identifier , 'Name.Namespace' ) ) ^ 0
+ ( SkipSpace * Q ( P "," ) * SkipSpace
+ * K ( 'Name.Namespace' , identifier ) ) ^ 0
)
% \end{macrocode}
% Be careful: there is no commutativity of |+| in the previous expression.
@@ -3608,9 +3797,9 @@ local ImportAs =
% \smallskip
% \begin{macrocode}
local FromImport =
- K ( P "from" , 'Keyword' )
- * Space * K ( identifier , 'Name.Namespace' )
- * Space * K ( P "import" , 'Keyword' )
+ K ( 'Keyword' , P "from" )
+ * Space * K ( 'Name.Namespace' , identifier )
+ * Space * K ( 'Keyword' , P "import" )
% \end{macrocode}
%
% \bigskip
@@ -3648,14 +3837,14 @@ local FromImport =
% technics now in Python).
% \begin{macrocode}
local PercentInterpol =
- K ( P "%"
+ K ( 'String.Interpol' ,
+ P "%"
* ( P "(" * alphanum ^ 1 * P ")" ) ^ -1
* ( S "-#0 +" ) ^ 0
* ( digit ^ 1 + P "*" ) ^ -1
* ( P "." * ( digit ^ 1 + P "*" ) ) ^ -1
* ( S "HlL" ) ^ -1
- * S "sdfFeExXorgiGauc%" ,
- 'String.Interpol'
+ * S "sdfFeExXorgiGauc%"
)
% \end{macrocode}
%
@@ -3668,62 +3857,57 @@ local PercentInterpol =
% @@\_piton:n} wich means that the interpolations are parsed once again by \pkg{piton}.}
% \begin{macrocode}
local SingleShortString =
- Lc ( "{\\PitonStyle{String.Short}{" )
- * (
+ WithStyle ( 'String.Short' ,
% \end{macrocode}
% First, we deal with the f-strings of Python, which are prefixed by |f| or |F|.
% \begin{macrocode}
- K ( P "f'" + P "F'" )
+ Q ( P "f'" + P "F'" )
* (
- K ( P "{" , 'String.Interpol')
- * K ( ( 1 - S "}':" ) ^ 0 , 'Interpol.Inside' )
- * K ( P ":" * (1 - S "}:'") ^ 0 ) ^ -1
- * K ( P "}" , 'String.Interpol' )
+ K ( 'String.Interpol' , P "{" )
+ * K ( 'Interpol.Inside' , ( 1 - S "}':" ) ^ 0 )
+ * Q ( P ":" * (1 - S "}:'") ^ 0 ) ^ -1
+ * K ( 'String.Interpol' , P "}" )
+
VisualSpace
+
- K ( ( P "\\'" + P "{{" + P "}}" + 1 - S " {}'" ) ^ 1 )
+ Q ( ( P "\\'" + P "{{" + P "}}" + 1 - S " {}'" ) ^ 1 )
) ^ 0
- * K ( P "'" )
+ * Q ( P "'" )
+
% \end{macrocode}
% Now, we deal with the standard strings of Python, but also the ``raw strings''.
% \begin{macrocode}
- K ( P "'" + P "r'" + P "R'" )
- * ( K ( ( P "\\'" + 1 - S " '\r%" ) ^ 1 )
+ Q ( P "'" + P "r'" + P "R'" )
+ * ( Q ( ( P "\\'" + 1 - S " '\r%" ) ^ 1 )
+ VisualSpace
+ PercentInterpol
- + K ( P "%" )
+ + Q ( P "%" )
) ^ 0
- * K ( P "'" )
- )
- * Lc ( "}}" )
+ * Q ( P "'" ) )
+
local DoubleShortString =
- Lc ( "{\\PitonStyle{String.Short}{" )
- * (
- K ( P "f\"" + P "F\"" )
+ WithStyle ( 'String.Short' ,
+ Q ( P "f\"" + P "F\"" )
* (
- K ( P "{" , 'String.Interpol' )
- * K ( ( 1 - S "}\":" ) ^ 0 , 'Interpol.Inside' )
- * ( K ( P ":" , 'String.Interpol' ) * K ( (1 - S "}:\"") ^ 0 ) ) ^ -1
- * K ( P "}" , 'String.Interpol' )
+ K ( 'String.Interpol' , P "{" )
+ * Q ( ( 1 - S "}\":" ) ^ 0 , 'Interpol.Inside' )
+ * ( K ( 'String.Interpol' , P ":" ) * Q ( (1 - S "}:\"") ^ 0 ) ) ^ -1
+ * K ( 'String.Interpol' , P "}" )
+
VisualSpace
+
- K ( ( P "\\\"" + P "{{" + P "}}" + 1 - S " {}\"" ) ^ 1 )
+ Q ( ( P "\\\"" + P "{{" + P "}}" + 1 - S " {}\"" ) ^ 1 )
) ^ 0
- * K ( P "\"" )
+ * Q ( P "\"" )
+
- K ( P "\"" + P "r\"" + P "R\"" )
- * ( K ( ( P "\\\"" + 1 - S " \"\r%" ) ^ 1 )
+ Q ( P "\"" + P "r\"" + P "R\"" )
+ * ( Q ( ( P "\\\"" + 1 - S " \"\r%" ) ^ 1 )
+ VisualSpace
+ PercentInterpol
- + K ( P "%" )
+ + Q ( P "%" )
) ^ 0
- * K ( P "\"" )
- )
- * Lc ( "}}" )
+ * Q ( P "\"" ) )
local ShortString = SingleShortString + DoubleShortString
% \end{macrocode}
@@ -3749,6 +3933,7 @@ local BalancedBraces =
) ^ 0
}
% \end{macrocode}
+%
%
% \bigskip
% If Beamer is used (or if the key |beamer| is used at load-time), the following
@@ -3757,12 +3942,38 @@ local BalancedBraces =
local Beamer = P ( false )
local BeamerBeginEnvironments = P ( true )
local BeamerEndEnvironments = P ( true )
-local BeamerNamesEnvironments =
+local BeamerNamesEnvironments =
P "uncoverenv" + P "onlyenv" + P "visibleenv" + P "invisibleenv"
+ P "alertenv" + P "actionenv"
% \end{macrocode}
+%
+% \begin{macrocode}
+UserCommands =
+ Ct ( Cc "Open" * C ( "\\emph{" ) * Cc "}" )
+ * ( C ( BalancedBraces ) / (function (s) return MainLoopPython:match(s) end ) )
+ * P "}" * Ct ( Cc "Close" )
+% \end{macrocode}
+%
+% \begin{macrocode}
+function OneBeamerEnvironment(name)
+ return
+ Ct ( Cc "Open"
+ * C (
+ P ( "\\begin{" .. name .. "}" )
+ * ( P "<" * (1 - P ">") ^ 0 * P ">" ) ^ -1
+ )
+ * Cc ( "\\end{" .. name .. "}" )
+ )
+ * (
+ C ( ( 1 - P ( "\\end{" .. name .. "}" ) ) ^ 0 )
+ / (function (s) return MainLoopPython:match(s) end )
+ )
+ * P ( "\\end{" .. name .. "}" ) * Ct ( Cc "Close" )
+end
+% \end{macrocode}
%
+%
% \bigskip
% \begin{macrocode}
if piton_beamer
@@ -3770,24 +3981,27 @@ then
Beamer =
L ( P "\\pause" * ( P "[" * (1 - P "]") ^ 0 * P "]" ) ^ -1 )
+
-% \end{macrocode}
-% We recall that the command |\@@_beamer_command:n| executes the argument
-% corresponding to its argument but also stores it in |\l_@@_beamer_command_str|.
-% That string is used only in the error message ``|cr~not~allowed|'' raised when
-% there is a carriage return in the mandatory argument of that command.
-% \begin{macrocode}
- ( P "\\uncover" * Lc ( '\\@@_beamer_command:n{uncover}' )
- + P "\\only" * Lc ( '\\@@_beamer_command:n{only}' )
- + P "\\alert" * Lc ( '\\@@_beamer_command:n{alert}' )
- + P "\\visible" * Lc ( '\\@@_beamer_command:n{visible}' )
- + P "\\invisible" * Lc ( '\\@@_beamer_command:n{invisible}' )
- + P "\\action" * Lc ( '\\@@_beamer_command:n{action}' )
- )
- *
- L ( ( P "<" * (1 - P ">") ^ 0 * P ">" ) ^ -1 * P "{" )
- * K ( BalancedBraces , 'ParseAgain.noCR' )
- * L ( P "}" )
- +
+ Ct ( Cc "Open"
+ * C (
+ (
+ P "\\uncover" + P "\\only" + P "\\alert" + P "\\visible"
+ + P "\\invisible" + P "\\action"
+ )
+ * ( P "<" * (1 - P ">") ^ 0 * P ">" ) ^ -1
+ * P "{"
+ )
+ * Cc "}"
+ )
+ * ( C ( BalancedBraces ) / (function (s) return MainLoopPython:match(s) end ) )
+ * P "}" * Ct ( Cc "Close" )
+ +
+ OneBeamerEnvironment "uncoverenv"
+ + OneBeamerEnvironment "onlyenv"
+ + OneBeamerEnvironment "visibleenv"
+ + OneBeamerEnvironment "invisibleenv"
+ + OneBeamerEnvironment "alertenv"
+ + OneBeamerEnvironment "actionenv"
+ +
L (
% \end{macrocode}
% For |\\alt|, the specification of the overlays (between angular brackets) is mandatory.
@@ -3796,9 +4010,9 @@ then
* P "<" * (1 - P ">") ^ 0 * P ">"
* P "{"
)
- * K ( BalancedBraces , 'ParseAgain.noCR' )
+ * K ( 'ParseAgain.noCR' , BalancedBraces )
* L ( P "}{" )
- * K ( BalancedBraces , 'ParseAgain.noCR' )
+ * K ( 'ParseAgain.noCR' , BalancedBraces )
* L ( P "}" )
+
L (
@@ -3809,11 +4023,11 @@ then
* P "<" * (1 - P ">") ^ 0 * P ">"
* P "{"
)
- * K ( BalancedBraces , 'ParseAgain.noCR' )
+ * K ( 'ParseAgain.noCR' , BalancedBraces )
* L ( P "}{" )
- * K ( BalancedBraces , 'ParseAgain.noCR' )
+ * K ( 'ParseAgain.noCR' , BalancedBraces )
* L ( P "}{" )
- * K ( BalancedBraces , 'ParseAgain.noCR' )
+ * K ( 'ParseAgain.noCR' , BalancedBraces )
* L ( P "}" )
% \end{macrocode}
% Now for the environemnts.
@@ -3841,24 +4055,29 @@ end
% \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}).
+% \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 LPEG specifies that the pattern will be
+% 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 ( ( ( P ">>>" + P "..." ) * P " " ^ -1 ) ^ -1 , 'Prompt' )
+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
-if piton_beamer
-then
-EOL =
+local EOL =
P "\r"
*
(
@@ -3871,45 +4090,23 @@ EOL =
% @@\_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}
- Lc ( '\\@@_end_line:' )
- * BeamerEndEnvironments
- * BeamerBeginEnvironments
- * PromptHastyDetection
- * Lc ( '\\@@_newline: \\@@_begin_line:' )
- * Prompt
- )
- *
- SpaceIndentation ^ 0
-else
-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}
- Lc ( '\\@@_end_line:' )
- * PromptHastyDetection
- * Lc ( '\\@@_newline: \\@@_begin_line:' )
- * Prompt
+ Ct (
+ Cc "EOL"
+ *
+ Ct (
+ Lc "\\@@_end_line:"
+ * BeamerEndEnvironments
+ * BeamerBeginEnvironments
+ * PromptHastyDetection
+ * Lc "\\@@_newline: \\@@_begin_line:"
+ * Prompt
+ )
+ )
)
*
SpaceIndentation ^ 0
-end
% \end{macrocode}
%
-% \bigskip
-% \begin{macrocode}
-function EOL_for_style ( s )
- return Lc "}}" * EOL * Lc ( "{\\PitonStyle{" .. s .. "}{" )
-end
-% \end{macrocode}
%
% \bigskip
% \paragraph{The long strings}
@@ -3917,63 +4114,61 @@ end
%
% \begin{macrocode}
local SingleLongString =
- Lc "{\\PitonStyle{String.Long}{"
- * (
- K ( S "fF" * P "'''" )
+ WithStyle ( 'String.Long' ,
+ ( Q ( S "fF" * P "'''" )
* (
- K ( P "{" , 'String.Interpol' )
- * K ( ( 1 - S "}:\r" - P "'''" ) ^ 0 , 'Interpol.Inside' )
- * K ( P ":" * (1 - S "}:\r" - P "'''" ) ^ 0 ) ^ -1
- * K ( P "}" , 'String.Interpol' )
+ 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 ( ( 1 - P "'''" - S "{}'\r" ) ^ 1 )
+ Q ( ( 1 - P "'''" - S "{}'\r" ) ^ 1 )
+
- EOL_for_style 'String.Long'
+ EOL
) ^ 0
+
- K ( ( S "rR" ) ^ -1 * P "'''" )
+ Q ( ( S "rR" ) ^ -1 * P "'''" )
* (
- K ( ( 1 - P "'''" - S "\r%" ) ^ 1 )
+ Q ( ( 1 - P "'''" - S "\r%" ) ^ 1 )
+
PercentInterpol
+
P "%"
+
- EOL_for_style 'String.Long'
+ EOL
) ^ 0
)
- * K ( P "'''" )
- * Lc "}}"
+ * Q ( P "'''" ) )
local DoubleLongString =
- Lc "{\\PitonStyle{String.Long}{"
- * (
- K ( S "fF" * P "\"\"\"" )
- * (
- K ( P "{" , 'String.Interpol' )
- * K ( ( 1 - S "}:\r" - P "\"\"\"" ) ^ 0 , 'Interpol.Inside' )
- * K ( P ":" * (1 - S "}:\r" - P "\"\"\"" ) ^ 0 ) ^ -1
- * K ( P "}" , 'String.Interpol' )
- +
- K ( ( 1 - P "\"\"\"" - S "{}\"\r" ) ^ 1 )
- +
- EOL_for_style 'String.Long'
- ) ^ 0
- +
- K ( ( S "rR" ) ^ -1 * P "\"\"\"" )
- * (
- K ( ( 1 - P "\"\"\"" - S "%\r" ) ^ 1 )
- +
- PercentInterpol
- +
- P "%"
- +
- EOL_for_style 'String.Long'
- ) ^ 0
- )
- * K ( P "\"\"\"" )
- * Lc "}}"
+ WithStyle ( 'String.Long' ,
+ (
+ Q ( S "fF" * P "\"\"\"" )
+ * (
+ K ( 'String.Interpol', P "{" )
+ * K ( 'Interpol.Inside' , ( 1 - S "}:\r" - P "\"\"\"" ) ^ 0 )
+ * Q ( P ":" * (1 - S "}:\r" - P "\"\"\"" ) ^ 0 ) ^ -1
+ * K ( 'String.Interpol' , P "}" )
+ +
+ Q ( ( 1 - P "\"\"\"" - S "{}\"\r" ) ^ 1 )
+ +
+ EOL
+ ) ^ 0
+ +
+ Q ( ( S "rR" ) ^ -1 * P "\"\"\"" )
+ * (
+ Q ( ( 1 - P "\"\"\"" - S "%\r" ) ^ 1 )
+ +
+ PercentInterpol
+ +
+ P "%"
+ +
+ EOL
+ ) ^ 0
+ )
+ * Q ( P "\"\"\"" )
+ )
% \end{macrocode}
%
% \begin{macrocode}
@@ -3986,11 +4181,11 @@ local LongString = SingleLongString + DoubleLongString
% of a function definition (which begins with |def|).
% \begin{macrocode}
local StringDoc =
- K ( P "\"\"\"" , 'String.Doc' )
- * ( K ( (1 - P "\"\"\"" - P "\r" ) ^ 0 , 'String.Doc' ) * EOL
+ K ( 'String.Doc' , P "\"\"\"" )
+ * ( K ( 'String.Doc' , (1 - P "\"\"\"" - P "\r" ) ^ 0 ) * EOL
* Tab ^ 0
) ^ 0
- * K ( ( 1 - P "\"\"\"" - P "\r" ) ^ 0 * P "\"\"\"" , 'String.Doc' )
+ * K ( 'String.Doc' , ( 1 - P "\"\"\"" - P "\r" ) ^ 0 * P "\"\"\"" )
% \end{macrocode}
%
% \bigskip
@@ -4000,13 +4195,12 @@ local StringDoc =
% listings.
% \begin{macrocode}
local CommentMath =
- P "$" * K ( ( 1 - S "$\r" ) ^ 1 , 'Comment.Math' ) * P "$"
+ P "$" * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1 ) * P "$"
local Comment =
- Lc ( "{\\PitonStyle{Comment}{" )
- * K ( P "#" )
- * ( CommentMath + K ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0
- * Lc ( "}}" )
+ WithStyle ( 'Comment' ,
+ Q ( P "#" )
+ * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 )
* ( EOL + -1 )
% \end{macrocode}
%
@@ -4023,7 +4217,7 @@ local CommentLaTeX =
* Lc "{\\PitonStyle{Comment.LaTeX}{\\ignorespaces"
* L ( ( 1 - P "\r" ) ^ 0 )
* Lc "}}"
- * ( EOL + -1 )
+ * ( EOL + -1 ) -- you could put EOL instead of EOL
% \end{macrocode}
%
% \bigskip
@@ -4071,14 +4265,14 @@ local Expression =
local Param =
SkipSpace * Identifier * SkipSpace
* (
- K ( P "=" * Expression , 'InitialValues' )
- + K ( P ":" ) * SkipSpace * K ( letter^1 , 'Name.Type' )
+ K ( 'InitialValues' , P "=" * Expression )
+ + Q ( P ":" ) * SkipSpace * K ( 'Name.Type' , letter^1 )
) ^ -1
% \end{macrocode}
%
% \medskip
% \begin{macrocode}
-local Params = ( Param * ( K "," * Param ) ^ 0 ) ^ -1
+local Params = ( Param * ( Q "," * Param ) ^ 0 ) ^ -1
% \end{macrocode}
%
% \bigskip
@@ -4089,21 +4283,21 @@ local Params = ( Param * ( K "," * Param ) ^ 0 ) ^ -1
% |Comment|, |CommentLaTeX|, |Params|, |StringDoc|...
% \begin{macrocode}
local DefFunction =
- K ( P "def" , 'Keyword' )
+ K ( 'Keyword' , P "def" )
* Space
- * K ( identifier , 'Name.Function' )
+ * K ( 'Name.Function.Internal' , identifier )
* SkipSpace
- * K ( P "(" ) * Params * K ( P ")" )
+ * Q ( P "(" ) * Params * Q ( P ")" )
* SkipSpace
- * ( K ( P "->" ) * SkipSpace * K ( identifier , 'Name.Type' ) ) ^ -1
+ * ( Q ( P "->" ) * SkipSpace * K ( 'Name.Type' , identifier ) ) ^ -1
% \end{macrocode}
% Here, we need a \pkg{piton} style |ParseAgain| which will be linked to
% |\@@_piton:n| (that means that the capture will be parsed once again by
% \pkg{piton}). We could avoid that kind of trick by using a non-terminal of a
% grammar but we have probably here a better legibility.
% \begin{macrocode}
- * K ( ( 1 - S ":\r" )^0 , 'ParseAgain' )
- * K ( P ":" )
+ * K ( 'ParseAgain' , ( 1 - S ":\r" )^0 )
+ * Q ( P ":" )
* ( SkipSpace
* ( EOL + CommentLaTeX + Comment ) -- in all cases, that contains an EOL
* Tab ^ 0
@@ -4144,20 +4338,20 @@ local DefFunction =
%
% \begin{macrocode}
local ItemDict =
- ShortString * SkipSpace * K ( P ":" ) * K ( Expression , 'Dict.Value' )
+ ShortString * SkipSpace * Q ( P ":" ) * K ( 'Dict.Value' , Expression )
local ItemOfSet = SkipSpace * ( ItemDict + ShortString ) * SkipSpace
local Set =
- K ( P "{" )
- * ItemOfSet * ( K ( P "," ) * ItemOfSet ) ^ 0
- * K ( P "}" )
+ Q ( P "{" )
+ * ItemOfSet * ( Q ( P "," ) * ItemOfSet ) ^ 0
+ * Q ( P "}" )
% \end{macrocode}
%
% \paragraph{Miscellaneous}
%
% \begin{macrocode}
-local ExceptionInConsole = Exception * K ( ( 1 - P "\r" ) ^ 0 ) * EOL
+local ExceptionInConsole = Exception * Q ( ( 1 - P "\r" ) ^ 0 ) * EOL
% \end{macrocode}
%
%
@@ -4166,14 +4360,15 @@ local ExceptionInConsole = Exception * K ( ( 1 - P "\r" ) ^ 0 ) * EOL
%
% First, the main loop :
% \begin{macrocode}
-MainLoop =
+MainLoopPython =
( ( space^1 * -1 )
+ EOL
+ Space
+ Tab
+ Escape
+ CommentLaTeX
- + Beamer
+ + Beamer
+ + UserCommands
+ LongString
+ Comment
+ ExceptionInConsole
@@ -4189,10 +4384,10 @@ MainLoop =
+ RaiseException
+ DefFunction
+ DefClass
- + Keyword * ( Space + Punct + Delim + EOL + -1 )
+ + Keyword * ( Space + Punct + Delim + EOL+ -1 )
+ Decorator
- + OperatorWord * ( Space + Punct + Delim + EOL + -1 )
- + Builtin * ( Space + Punct + Delim + EOL + -1 )
+ + OperatorWord * ( Space + Punct + Delim + EOL+ -1 )
+ + Builtin * ( Space + Punct + Delim + EOL+ -1 )
+ Identifier
+ Number
+ Word
@@ -4213,12 +4408,12 @@ python =
( ( space - P "\r" ) ^0 * P "\r" ) ^ -1
* BeamerBeginEnvironments
* PromptHastyDetection
- * Lc ( '\\@@_begin_line:' )
+ * Lc '\\@@_begin_line:'
* Prompt
* SpaceIndentation ^ 0
- * MainLoop
+ * MainLoopPython
* -1
- * Lc ( '\\@@_end_line:' )
+ * Lc '\\@@_end_line:'
)
% \end{macrocode}
%
@@ -4231,44 +4426,48 @@ languages['python'] = python
% \subsubsection{The LPEG ocaml}
%
% \begin{macrocode}
-local Punct = K ( S ",:;!" )
+local Delim = Q ( P "[|" + P "|]" + S "[()]" )
+% \end{macrocode}
+%
+% \begin{macrocode}
+local Punct = Q ( S ",:;!" )
% \end{macrocode}
%
% \begin{macrocode}
local identifier =
( R "az" + R "AZ" + P "_") * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0
-local Identifier = K ( identifier )
+local Identifier = K ( 'Identifier' , identifier )
local Operator =
- K ( P "!=" + P "<>" + P "==" + P "<<" + P ">>" + P "<=" + P ">=" + P ":="
+ K ( 'Operator' ,
+ P "!=" + P "<>" + P "==" + P "<<" + P ">>" + P "<=" + P ">=" + P ":="
+ P "||" + P "&&" + P "//" + P "**" + P ";;" + P "::" + P "->"
+ P "+." + P "-." + P "*." + P "/."
+ S "-~+/*%=<>&@|"
- ,
- 'Operator'
)
local OperatorWord =
- K ( P "and" + P "asr" + P "land" + P "lor" + P "lsl" + P "lxor"
- + P "mod" + P "or" ,
- 'Operator.Word')
+ K ( 'Operator.Word' ,
+ P "and" + P "asr" + P "land" + P "lor" + P "lsl" + P "lxor"
+ + P "mod" + P "or" )
local Keyword =
- K ( P "as" + P "assert" + P "begin" + P "class" + P "constraint" + P "done"
+ K ( 'Keyword' ,
+ P "as" + P "assert" + P "begin" + P "class" + P "constraint" + P "done"
+ P "do" + P "downto" + P "else" + P "end" + P "exception" + P "external"
+ P "false" + P "for" + P "function" + P "fun" + P "functor" + P "if"
+ P "in" + P "include" + P "inherit" + P "initializer" + P "lazy" + P "let"
+ P "match" + P "method" + P "module" + P "mutable" + P "new" + P "object"
+ P "of" + P "open" + P "private" + P "raise" + P "rec" + P "sig"
+ P "struct" + P "then" + P "to" + P "true" + P "try" + P "type"
- + P "value" + P "val" + P "virtual" + P "when" + P "while" + P "with" ,
- 'Keyword' )
- + K ( P "true" + P "false" , 'Keyword.Constant' )
+ + P "value" + P "val" + P "virtual" + P "when" + P "while" + P "with" )
+ + K ( 'Keyword.Constant' , P "true" + P "false" )
local Builtin =
- K ( P "not" + P "incr" + P "decr" + P "fst" + P "snd"
+ K ( 'Name.Builtin' ,
+ P "not" + P "incr" + P "decr" + P "fst" + P "snd"
+ P "String.length"
+ P "List.tl" + P "List.hd" + P "List.mem" + P "List.exists"
+ P "List.for_all" + P "List.filter" + P "List.length" + P "List.map"
@@ -4280,27 +4479,26 @@ local Builtin =
+ P "Stack.create" + P "Stack.is_empty" + P "Stack.push" + P "Stack.pop"
+ P "Hashtbl.create" + P "Hashtbl.add" + P "Hashtbl.remove"
+ P "Hashtbl.mem" + P "Hashtbl.find" + P "Hashtbl.find_opt"
- + P "Hashtbl.iter"
- , 'Name.Builtin' )
+ + P "Hashtbl.iter" )
% \end{macrocode}
%
% \bigskip
% The following exceptions are exceptions in the standard library of OCaml (Stdlib).
% \begin{macrocode}
local Exception =
- K ( P "Division_by_zero" + P "End_of_File" + P "Failure"
+ 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" ,
- 'Exception' )
+ + P "Sys_error" + P "Undefined_recursive_module" )
% \end{macrocode}
%
-%
+% \bigskip
% \paragraph{The characters in OCaml}
%
% \begin{macrocode}
local Char =
- K ( P "'" * ( ( 1 - P "'" ) ^ 0 + P "\\'" ) * P "'" , 'String.Short' )
+ K ( 'String.Short' , P "'" * ( ( 1 - P "'" ) ^ 0 + P "\\'" ) * P "'" )
% \end{macrocode}
%
%
@@ -4337,7 +4535,7 @@ then
)
*
L ( ( P "<" * (1 - P ">") ^ 0 * P ">" ) ^ -1 * P "{" )
- * K ( BalancedBraces , 'ParseAgain.noCR' )
+ * K ( 'ParseAgain.noCR' , BalancedBraces )
* L ( P "}" )
+
L (
@@ -4345,9 +4543,9 @@ then
* P "<" * (1 - P ">") ^ 0 * P ">"
* P "{"
)
- * K ( BalancedBraces , 'ParseAgain.noCR' )
+ * K ( 'ParseAgain.noCR' , BalancedBraces )
* L ( P "}{" )
- * K ( BalancedBraces , 'ParseAgain.noCR' )
+ * K ( 'ParseAgain.noCR' , BalancedBraces )
* L ( P "}" )
+
L (
@@ -4355,11 +4553,11 @@ then
* P "<" * (1 - P ">") ^ 0 * P ">"
* P "{"
)
- * K ( BalancedBraces , 'ParseAgain.noCR' )
+ * K ( 'ParseAgain.noCR' , BalancedBraces )
* L ( P "}{" )
- * K ( BalancedBraces , 'ParseAgain.noCR' )
+ * K ( 'ParseAgain.noCR' , BalancedBraces )
* L ( P "}{" )
- * K ( BalancedBraces , 'ParseAgain.noCR' )
+ * K ( 'ParseAgain.noCR' , BalancedBraces )
* L ( P "}" )
BeamerBeginEnvironments =
( space ^ 0 *
@@ -4380,61 +4578,52 @@ end
%
% \bigskip
% \paragraph{EOL}
-%
% \begin{macrocode}
-local EOL
-if piton_beamer
-then
-EOL =
+local EOL =
P "\r"
*
(
( space^0 * -1 )
+
- Lc ( '\\@@_end_line:' )
- * BeamerEndEnvironments
- * BeamerBeginEnvironments
- * Lc ( '\\@@_newline: \\@@_begin_line:' )
- )
- *
- SpaceIndentation ^ 0
-else
-EOL =
- P "\r"
- *
- (
- ( space ^ 0 * -1 )
- +
- Lc ( '\\@@_end_line:' )
- * Lc ( '\\@@_newline: \\@@_begin_line:' )
+ Ct (
+ Cc "EOL"
+ *
+ Ct (
+ Lc "\\@@_end_line:"
+ * BeamerEndEnvironments
+ * BeamerBeginEnvironments
+ * PromptHastyDetection
+ * Lc "\\@@_newline: \\@@_begin_line:"
+ * Prompt
+ )
+ )
)
*
SpaceIndentation ^ 0
-end
% \end{macrocode}
%
+%
% \begin{macrocode}
-function EOL_for_style ( s )
- return Lc "}}" * EOL * Lc ( "{\\PitonStyle{" .. s .. "}{" )
-end
-% \end{macrocode}
-%
%
% \paragraph{The strings}
%
+% We need a pattern |string| without captures because it will be used within the
+% comments of OCaml.
% \begin{macrocode}
-local String =
- Lc "{\\PitonStyle{String.Long}{"
- * K ( P "\"" )
- * (
- VisualSpace
- +
- K ( ( 1 - S " \"\r" ) ^ 1 )
- +
- EOL_for_style 'String.Long'
- ) ^ 0
- * K ( P "\"" )
- * Lc "}}"
+local string =
+ Q ( P "\"" )
+ * (
+ VisualSpace
+ +
+ Q ( ( 1 - S " \"\r" ) ^ 1 )
+ +
+ EOL
+ ) ^ 0
+ * Q ( P "\"" )
+% \end{macrocode}
+%
+% \begin{macrocode}
+local String = WithStyle ( 'String.Long' , string )
% \end{macrocode}
%
%
@@ -4461,16 +4650,15 @@ local closeeq =
% The \textsc{lpeg} |QuotedStringBis| will do the second analysis.
% \begin{macrocode}
local QuotedStringBis =
- Lc "{\\PitonStyle{String.Long}{"
- *
- (
+ WithStyle ( 'String.Long' ,
+ (
VisualSpace
+
- K ( ( 1 - S " \r" ) ^ 1 )
+ Q ( ( 1 - S " \r" ) ^ 1 )
+
- EOL_for_style 'String.Long'
- ) ^ 0
- * Lc "}}"
+ EOL
+ ) ^ 0 )
+
% \end{macrocode}
%
% \medskip
@@ -4486,7 +4674,7 @@ local QuotedString =
% \bigskip
% \paragraph{The comments in the OCaml listings}
%
-% In OCaml, the delimiters for the comments are |(*| and |*)|. There
+% In OCaml, the delimiters for the comments are |(*| and |*)|. There are
% unsymmetrical and, therefore, the comments may be nested. That's why we need a
% grammar.
%
@@ -4495,20 +4683,18 @@ local QuotedString =
%
% \begin{macrocode}
local Comment =
- Lc "{\\PitonStyle{Comment}{"
- *
- P {
- "A" ,
- A = K "(*"
- * ( V "A"
- + K ( ( 1 - P "(*" - P "*)" - S "\r$" ) ^ 1 ) -- $
- + P "$" * K ( ( 1 - S "$\r" ) ^ 1 , 'Comment.Math' ) * P "$" -- $
- + EOL_for_style 'Comment'
- ) ^ 0
- * K "*)"
- }
- *
- Lc "}}"
+ WithStyle ( 'Comment' ,
+ P {
+ "A" ,
+ A = Q "(*"
+ * ( V "A"
+ + Q ( ( 1 - P "(*" - P "*)" - S "\r$\"" ) ^ 1 ) -- $
+ + string
+ + P "$" * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1 ) * P "$" -- $
+ + EOL
+ ) ^ 0
+ * Q "*)"
+ } )
% \end{macrocode}
%
% \bigskip
@@ -4516,18 +4702,18 @@ local Comment =
%
% \begin{macrocode}
local DefFunction =
- ( K ( P "let rec" + P "let" + P "and" , 'Keyword' ) )
+ K ( 'Keyword' , P "let rec" + P "let" + P "and" )
* Space
- * K ( identifier , 'Name.Function' )
+ * K ( 'Name.Function.Internal' , identifier )
* Space
- * # ( 1 - P "=" )
+ * # ( P "=" * space * P "function" + ( 1 - P "=" ) )
% \end{macrocode}
%
% \bigskip
% \paragraph{The parameters of the types}
%
% \begin{macrocode}
-local TypeParameter = K ( P "'" * alpha * # ( 1 - P "'") , 'TypeParameter' )
+local TypeParameter = K ( 'TypeParameter' , P "'" * alpha * # ( 1 - P "'" ) )
% \end{macrocode}
%
% \bigskip
@@ -4535,7 +4721,7 @@ local TypeParameter = K ( P "'" * alpha * # ( 1 - P "'") , 'TypeParameter' )
%
% First, the main loop :
% \begin{macrocode}
-MainLoop =
+MainLoopOCaml =
( ( space^1 * -1 )
+ EOL
+ Space
@@ -4576,7 +4762,7 @@ ocaml =
* BeamerBeginEnvironments
* Lc ( '\\@@_begin_line:' )
* SpaceIndentation ^ 0
- * MainLoop
+ * MainLoopOCaml
* -1
* Lc ( '\\@@_end_line:' )
)
@@ -4589,9 +4775,6 @@ languages['ocaml'] = ocaml
% \bigskip
% \subsubsection{The function Parse}
%
-% \begin{macrocode}
-local MinimalSyntax = Ct ( ( (1 - P "\r" ) ^ 1 + EOL ) ^ 0 )
-% \end{macrocode}
%
% 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
@@ -4603,8 +4786,39 @@ local MinimalSyntax = Ct ( ( (1 - P "\r" ) ^ 1 + EOL ) ^ 0 )
% \begin{macrocode}
function piton.Parse(language,code)
local t = languages[language] : match ( code )
- if t == nil then t = MinimalSyntax : match ( code ) end
- for _ , s in ipairs(t) do tex.tprint(s) end
+ local left_stack = {}
+ local right_stack = {}
+ for _ , one_item in ipairs(t)
+ do
+ if one_item[1] == "EOL"
+ then
+ for _ , s in ipairs(right_stack)
+ do tex.sprint( s )
+ end
+ for _ , s in ipairs(one_item[2])
+ do tex.tprint(s)
+ end
+ for _ , s in ipairs(left_stack)
+ do tex.sprint( s )
+ end
+ else
+ if one_item[1] == "Open"
+ then
+ tex.sprint( one_item[2] )
+ table.insert(left_stack,one_item[2])
+ table.insert(right_stack,one_item[3])
+ else
+ if one_item[1] == "Close"
+ then
+ tex.sprint( right_stack[#right_stack] )
+ left_stack[#left_stack] = nil
+ right_stack[#right_stack] = nil
+ else
+ tex.tprint(one_item)
+ end
+ end
+ end
+ end
end
% \end{macrocode}
%
@@ -4843,6 +5057,11 @@ end
% \vspace{1cm}
% \section{History}
%
+% % \subsection*{Changes between versions 1.4 and 1.5}
+%
+% New key |numbers-sep|.
+%
+%
% \subsection*{Changes between versions 1.3 and 1.4}
%
% New key |identifiers| in |\PitonOptions|.