diff options
Diffstat (limited to 'Master/texmf-dist/source/lualatex/piton/piton.dtx')
-rw-r--r-- | Master/texmf-dist/source/lualatex/piton/piton.dtx | 1385 |
1 files changed, 813 insertions, 572 deletions
diff --git a/Master/texmf-dist/source/lualatex/piton/piton.dtx b/Master/texmf-dist/source/lualatex/piton/piton.dtx index ec18e80eaa6..0174f405615 100644 --- a/Master/texmf-dist/source/lualatex/piton/piton.dtx +++ b/Master/texmf-dist/source/lualatex/piton/piton.dtx @@ -44,7 +44,7 @@ end-escape = ! , begin-escape-math = \( , end-escape-math = \) , - detected-commands = highLight + detected-commands = { highLight, footnote } } \parindent 0pt @@ -79,12 +79,12 @@ % \iffalse %<*STY> % \fi -\def\PitonFileVersion{3.0b} -\def\PitonFileDate{2024/05/23} +\def\PitonFileVersion{3.1b} +\def\PitonFileDate{2024/08/29} % \iffalse %</STY> %<*LUA> -piton_version = "3.0b" -- 2024/05/23 +piton_version = "3.1b" -- 2024/08/29 %</LUA> %\fi % @@ -113,8 +113,9 @@ piton_version = "3.0b" -- 2024/05/23 % listings and typesets them with syntactic highlighting. Since it uses the Lua % of LuaLaTeX, it works with |lualatex| only (and won't work with the other % engines: |latex|, |pdflatex| and |xelatex|). It does not use external program -% and the compilation does not require |--shell-escape|. The compilation is very -% fast since all the parsing is done by the library LPEG, written in C. +% and the compilation does not require |--shell-escape| (except when the key +% |write| is used). The compilation is very fast since all the parsing is done +% by the library LPEG, written in C. % % \bigskip % Here is an example of code typeset by \pkg{piton}, with the environment |{Piton}|. @@ -361,8 +362,12 @@ piton_version = "3.0b" -- 2024/05/23 % % \begin{itemize} % \item The key \Definition{language} specifies which computer language is -% considered (that key is case-insensitive). Five values are allowed : -% |Python|, |OCaml|, |C|, |SQL| and |minimal|. The initial value is |Python|. +% considered (that key is case-insensitive). It's possible to use the name of +% the five built-in languages (|Python|, |OCaml|, |C|, |SQL| and |minimal|) or +% the name of the language defined by the user with |\NewPitonLanguage| +% (cf.~part~\ref{NewPitonLanguage}, p.~\pageref{NewPitonLanguage}. +% +% The initial value is |Python|. % % \item \index{path} The key \Definition{path} specifies a path where the files % included by |\PitonInputFile| will be searched. @@ -395,6 +400,9 @@ piton_version = "3.0b" -- 2024/05/23 % the part~\ref{API}, p.~\pageref{API}).} of the current environment in % that file. At the first use of a file by \pkg{piton}, it is erased. % +% {\bfseries This key requires a compilation with {\ttfamily lualatex +% -shell-escape}}. +% % \item \index{path-write} The key \Definition{path-write} specifies a path % where the files written by the key |write| will be written. % @@ -431,6 +439,13 @@ piton_version = "3.0b" -- 2024/05/23 % \item The key \Definition{line-numbers/sep} is the horizontal distance between % the numbers of lines (inserted by |line-numbers|) and the beginning of the % lines of code. The initial value is 0.7~em. +% \item \colorbox{yellow!50}{\bfseries New 3.1}\enskip The key +% \Definition{line-numbers/format} is a list of tokens which are inserted before +% the number of line in order to format it. It's possible to put, \emph{at the +% end} of the list, a LaTeX command with one argument, such as, for example, +% |\fbox|. +% +% The initial value is |\footnotesize\color{gray}|. % \end{itemize} % % For convenience, a mechanism of factorisation of the prefix |line-numbers| is @@ -442,7 +457,8 @@ piton_version = "3.0b" -- 2024/05/23 % { % skip-empty-lines = false , % label-empty-lines = false , -% sep = 1 em +% sep = 1 em , +% line-format = \footnotesize \color{blue} % } % } % \end{Verbatim} @@ -473,6 +489,12 @@ piton_version = "3.0b" -- 2024/05/23 % The key |background-color| accepts a color defined «on the fly». For example, % it's possible to write |background-color = [cmyk]{0.1,0.05,0,0}|. % +% \smallskip +% When the key |split-on-empty-lines| is in force (see the part ``Page breaks'', +% p.~\pageref{page breaks}), the empty lines generated by that key don't have +% any background color (at least with the initial value of the parameter +% |split-separation|). +% % \item \index{prompt-background-color} With the key % \Definition{prompt-background-color}, \pkg{piton} adds a % color background to the lines beginning with the prompt ``|>>>|'' (and its @@ -664,7 +686,7 @@ piton_version = "3.0b" -- 2024/05/23 % \bigskip % For example, with the command % \begin{Verbatim} -% \SetPitonStyle~emphase#[SQL]@{Keywords = \color[HTML]{006699} \bfseries \MakeUppercase} +% \SetPitonStyle~emphase#[SQL]@{Keyword = \color[HTML]{006699} \bfseries \MakeUppercase} % \end{Verbatim} % the keywords in the SQL listings will be composed in capital letters, even if % they appear in lower case in the LaTeX source (we recall that, in SQL, the @@ -976,6 +998,7 @@ piton_version = "3.0b" -- 2024/05/23 % \label{breakable} % % \subsubsection{Page breaks} +% \label{page breaks} % \index{splittable} % % By default, the listings produced by the environment |{Piton}| and the command @@ -994,10 +1017,17 @@ piton_version = "3.0b" -- 2024/05/23 % In fact, when the key |split-on-empty-lines| is in force, the work goes a % little further than merely allowing page breaks: several successive empty lines % are deleted and replaced by the content of the parameter corresponding to the -% key \Definition{split-separation}. The initial value of this parameter is -% |\vspace{\baselineskip}\vspace{-1.25pt}| which corresponds eventually to an +% key \Definition{split-separation}. +% \begin{itemize} +% \item That parameter must contain elements allowed to be inserted in +% \emph{vertical mode} of TeX. For example, it's possible to put |\hrule|. +% +% \item The initial value of this parameter is +% |\vspace{\baselineskip}\vspace{-1.25pt}| which corresponds eventually to an % empty line in the final PDF (this vertical space is deleted if it occurs on a -% page break). +% page break). If the key |background-color| is in force, no background color is +% added to that empty line. +% \end{itemize} % % \item Of course, the key |split-on-empty-lines| may not be sufficient and % that's why \pkg{piton} provides the key \Definition{splittable}. @@ -1012,6 +1042,9 @@ piton_version = "3.0b" -- 2024/05/23 % When used without value, the key |splittable| is equivalent to % |splittable = 1| and the listings may be broken anywhere (it's probably % not recommandable). +% +% The initial value of the key |splittable| is equal to 100 (by default, the +% listings are not breakable at all). % \end{itemize} % % @@ -1654,6 +1687,8 @@ piton_version = "3.0b" -- 2024/05/23 % % \subsubsection{Commands of Beamer allowed in \{Piton\} and \textbackslash PitonInputFile} % +% \index{detected-beamer-commands} +% % When \pkg{piton} is used in the class \cls{beamer} , the following commands of % \cls{beamer} (classified upon their number of arguments) are automatically % detected in the environments |{Piton}| (and in the listings processed by @@ -1663,17 +1698,23 @@ piton_version = "3.0b" -- 2024/05/23 % also possible to use the command \texttt{\textbackslash pause} in a ``LaTeX % comment'', that is to say by writing \texttt{\#> \textbackslash pause}. By % this way, if the Python code is copied, it's still executable by Python}. ; -% \item one mandatory argument : |\action|, |\alert|, |\invisible|, |\only|, |\uncover| and |\visible| ; +% \item one mandatory argument : |\action|, |\alert|, |\invisible|, |\only|, +% |\uncover| and |\visible| ; \newline +% \colorbox{yellow!50}{\bfseries New 3.1}\newline +% It's possible to add new commands to that list with the key +% \Definition{detected-beamer-commands} (the names of the commands must +% \emph{not} be preceded by a backslash). % \item two mandatory arguments : |\alt| ; % \item three mandatory arguments : |\temporal|. % \end{itemize} -% \medskip -% In the mandatory arguments of these commands, the braces must be balanced. -% However, the braces included in short strings\footnote{The short strings of -% Python are the strings delimited by characters \texttt{'} or the characters -% \texttt{"} and not \texttt{'''} nor \texttt{"""}. In Python, the short strings -% can't extend on several lines.} of Python are not considered. +% \medskip +% These commands must be used preceded and following by a space. In the +% mandatory arguments of these commands, the braces must be balanced. However, +% the braces included in short strings\footnote{The short strings of Python are +% the strings delimited by characters \texttt{'} or the characters \texttt{"} +% and not \texttt{'''} nor \texttt{"""}. In Python, the short strings can't +% extend on several lines.} of Python are not considered. % % \medskip % Regarding the functions |\alt| and |\temporal| there should be no carriage @@ -1713,8 +1754,18 @@ piton_version = "3.0b" -- 2024/05/23 % listings processed by |\PitonInputFile|): |{actionenv}|, |{alertenv}|, % |{invisibleenv}|, |{onlyenv}|, |{uncoverenv}| and |{visibleenv}|. % +% \smallskip +% \index{detected-beamer-environments} +% \colorbox{yellow!50}{\bfseries New 3.1} +% +% It's possible to add new environments to that list with the key +% \Definition{detected-beamer-environments}. +% +% \smallskip +% % However, there is a restriction: these environments must contain only \emph{whole -% lines of Python code} in their body. +% lines of Python code} in their body. The instructions |\begin{...}| and +% |\end{...}| must be alone on their lines. % %\medskip % Here is an example: @@ -1810,10 +1861,98 @@ piton_version = "3.0b" -- 2024/05/23 % in particular: it must be loaded after the package \pkg{xcolor} and it is not % perfectly compatible with \pkg{hyperref}. % +% +% \medskip +% \textbf{Important remark} : If you use Beamer, you should know taht Beamer has +% its own system to extract the footnotes. Therefore, \pkg{piton} must be loaded +% in that class without the option |footnote| nor the option |footnotehyper|. +% +% +% \bigskip +% By default, in an environment |{Piton}|, a command |\footnote| may appear only +% within a ``LaTeX comment''. But it's also possible to add the command +% |\footnote| to the list of the ``\emph{detected-commands}'' +% (cf.~part~\ref{detected-commands}, p.~\pageref{detected-commands}). + % \medskip % In this document, the package \pkg{piton} has been loaded with the -% option |footnotehyper|. For examples of notes, cf. \ref{notes-examples}, -% p.~\pageref{notes-examples}. +% option |footnotehyper| dans we added the command |\footnote| to the list of +% the ``\emph{detected-commands}'' with the following instruction in the +% preamble of the LaTeX document. +% +% \qquad \verb|\PitonOptions{detected-commands = footnote}| +% +% +% \begingroup +% \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}} +% \begin{Verbatim} +% \PitonOptions{background-color=gray!10} +% \begin{Piton} +% def arctan(x,n=10): +% if x < 0: +% return -arctan(-x)~emphase&\footnote{First recursive call.}]@ +% elif x > 1: +% return pi/2 - arctan(1/x)~emphase&\footnote{Second recursive call.}@ +% else: +% return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) +% \end{Piton} +% \end{Verbatim} +% \endgroup +% +% \begingroup +% \PitonOptions{background-color=gray!10} +% \begin{Piton} +% def arctan(x,n=10): +% if x < 0: +% return -arctan(-x)\footnote{First recursive call.} +% elif x > 1: +% return pi/2 - arctan(1/x)\footnote{Second recursive call.} +% else: +% return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) +% \end{Piton} +% \endgroup +% +% +% \vspace{1cm} +% +% If an environment |{Piton}| is used in an environment |{minipage}| of LaTeX, +% the notes are composed, of course, at the foot of the environment +% |{minipage}|. Recall that such |{minipage}| can't be broken by a page break. +% +% +% \begingroup +% \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}} +% \begin{Verbatim} +% \PitonOptions{background-color=gray!10} +% \emphase\begin{minipage}{\linewidth} +% \begin{Piton} +% def arctan(x,n=10): +% if x < 0: +% return -arctan(-x)~emphase&\footnote{First recursive call.}@ +% elif x > 1: +% return pi/2 - arctan(1/x)~emphase&\footnote{Second recursive call.}@ +% else: +% return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) +% \end{Piton} +% \end{minipage} +% \end{Verbatim} +% \endgroup +% +% \begingroup +% \PitonOptions{background-color=gray!10} +% \begin{minipage}{\linewidth} +% \begin{Piton} +% def arctan(x,n=10): +% if x < 0: +% return -arctan(-x)\footnote{First recursive call.} +% elif x > 1: +% return pi/2 - arctan(1/x)\footnote{Second recursive call.} +% else: +% return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) +% \end{Piton} +% \end{minipage} +% \endgroup +% % % \subsection{Tabulations} % @@ -1835,6 +1974,8 @@ piton_version = "3.0b" -- 2024/05/23 % course). Hence, that key is similar to the key |auto-gobble| but acts on % U+0009 instead of U+0020 (spaces). % +% The key |env-gobble| is not compatible with the tabulations. +% % % \bigskip % \section{API for the developpers} @@ -1882,7 +2023,7 @@ piton_version = "3.0b" -- 2024/05/23 % \index{numbers of the lines de code|emph} % % We remind that it's possible to have an automatic numbering of the lines in -% the Python listings by using the key |line-numbers|. +% the Python listings by using the key |line-numbers| (used without value). % % By default, the numbers of the lines are composed by \pkg{piton} in an % overlapping position on the left (by using internally the command |\llap| of LaTeX). @@ -2015,94 +2156,7 @@ piton_version = "3.0b" -- 2024/05/23 % \endgroup % % -% \bigskip -% \subsection{Notes in the listings} -% -% \label{notes-examples} -% \index{notes in the listings} % -% In order to be able to extract the notes (which are typeset with the command -% |\footnote|), the extension \pkg{piton} must be loaded with the key |footnote| -% or the key |footenotehyper| as explained in the section \ref{footnote} -% p.~\pageref{footnote}. In this document, the extension \pkg{piton} has been -% loaded with the key |footnotehyper|. -% -% Of course, in an environment |{Piton}|, a command |\footnote| may appear only -% within a LaTeX comment (which begins with |#>|). It's possible to have comments -% which contain only that command |\footnote|. That's the case in the following example. -% -% -% -% \begingroup -% \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}} -% \begin{Verbatim} -% \PitonOptions{background-color=gray!10} -% \begin{Piton} -% def arctan(x,n=10): -% if x < 0: -% return -arctan(-x)~emphase&#>\footnote{First recursive call.}]@ -% elif x > 1: -% return pi/2 - arctan(1/x)~emphase&#>\footnote{Second recursive call.}@ -% else: -% return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) -% \end{Piton} -% \end{Verbatim} -% \endgroup -% -% \begingroup -% \PitonOptions{background-color=gray!10} -% \begin{Piton} -% def arctan(x,n=10): -% if x < 0: -% return -arctan(-x)#>\footnote{First recursive call.} -% elif x > 1: -% return pi/2 - arctan(1/x)#>\footnote{Second recursive call.} -% else: -% return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) -% \end{Piton} -% \endgroup -% -% -% \vspace{1cm} -% -% If an environment |{Piton}| is used in an environment |{minipage}| of LaTeX, -% the notes are composed, of course, at the foot of the environment -% |{minipage}|. Recall that such |{minipage}| can't be broken by a page break. -% -% -% \begingroup -% \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}} -% \begin{Verbatim} -% \PitonOptions{background-color=gray!10} -% \emphase\begin{minipage}{\linewidth} -% \begin{Piton} -% def arctan(x,n=10): -% if x < 0: -% return -arctan(-x)~emphase&#>\footnote{First recursive call.}@ -% elif x > 1: -% return pi/2 - arctan(1/x)~emphase&#>\footnote{Second recursive call.}@ -% else: -% return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) -% \end{Piton} -% \end{minipage} -% \end{Verbatim} -% \endgroup -% -% \begingroup -% \PitonOptions{background-color=gray!10} -% \begin{minipage}{\linewidth} -% \begin{Piton} -% def arctan(x,n=10): -% if x < 0: -% return -arctan(-x)#>\footnote{First recursive call.} -% elif x > 1: -% return pi/2 - arctan(1/x)#>\footnote{Second recursive call.} -% else: -% return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) -% \end{Piton} -% \end{minipage} -% \endgroup -% % % % \bigskip @@ -2256,7 +2310,7 @@ piton_version = "3.0b" -- 2024/05/23 % \vspace{1cm} % % \begin{center} -% \begin{tabularx}{0.9\textwidth}{@{}>{\ttfamily}l>{\raggedright\arraybackslash}X@{}} +% \begin{tabularx}{\textwidth}{@{}>{\ttfamily}l>{\raggedright\arraybackslash}X@{}} % \toprule % \normalfont Style & Use \\ % \midrule @@ -2297,9 +2351,10 @@ piton_version = "3.0b" -- 2024/05/23 % Keyword & the following keywords: % \ttfamily assert, break, case, continue, del, % elif, else, except, exec, finally, for, from, -% global, if, import, lambda, non local, +% global, if, import, in, lambda, non local, % pass, raise, return, try, while, % with, yield et yield from.\\ +% Identifier & the identifiers. \\ % \bottomrule % \end{tabularx} % \end{center} @@ -2336,7 +2391,7 @@ piton_version = "3.0b" -- 2024/05/23 % String.Long & the strings, between |"| but also the \emph{quoted-strings} \\ % String & that key fixes both |String.Short| and |String.Long| \\ % Operator & les opérateurs, en particulier |+|, |-|, |/|, |*|, |@|, |!=|, |==|, |&&| \\ -% Operator.Word & les opérateurs suivants : |and|, |asr|, |land|, |lor|, |lsl|, |lxor|, |mod| et |or| \\ +% Operator.Word & les opérateurs suivants : |asr|, |land|, |lor|, |lsl|, |lxor|, |mod| et |or| \\ % Name.Builtin & les fonctions |not|, |incr|, |decr|, |fst| et |snd| \\ % Name.Type & the name of a type of OCaml \\ % Name.Field & the name of a field of a module \\ @@ -2351,15 +2406,15 @@ piton_version = "3.0b" -- 2024/05/23 % TypeParameter & the parameters of the types \\ % Comment & the comments, between |(*| et |*)|; these comments may be nested \\ % Keyword.Constant & |true| et |false| \\ -% Keyword & the following keywords: -% |assert|, |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| and |with| \\ +% Keyword & the following keywords: |assert|, |as|, |done|, |downto|, |do|, +% |else|, |exception|, |for|, |function| , |fun|, |if|, |lazy|, |match|, +% |mutable|, |new|, |of|, |private|, |raise|, |then|, |to|, |try| , |virtual|, +% |when|, |while| and |with| \\ +% Keyword.Governing & the following keywords: |and|, |begin|, |class|, |constraint|, +% |end|, |external|, |functor|, |include|, |inherit|, |initializer|, +% |in|, |let|, |method|, |module|, |object|, |open|, |rec|, |sig|, +% |struct|, |type| and |val|. \\ +% Identifier & the identifiers. \\ % \bottomrule % \end{tabularx} % \end{center} @@ -2418,6 +2473,7 @@ piton_version = "3.0b" -- 2024/05/23 % |return|, |static|, |static_assert|, |struct|, |switch|, |thread_local|, |throw|, % |typedef|, |union|, |using|, |virtual|, |volatile| and |while| % \\ +% Identifier & the identifiers. \\ % \bottomrule % \end{tabularx} % \end{center} @@ -2513,7 +2569,9 @@ piton_version = "3.0b" -- 2024/05/23 % String & the strings (between \texttt{"}) \\ % 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) \\ +% \pkg{piton} as LaTeX code (merely named ``LaTeX comments'' in this document) +% \\ +% Identifier & the identifiers. \\ % \bottomrule % \end{tabularx} % \end{center} @@ -2550,6 +2608,7 @@ piton_version = "3.0b" -- 2024/05/23 % |moredirectives| \\ % Tag & the ``tags'' defines by the key |tag| (the lexical units detected within % the tag will also be formatted with their own style) \\ +% Identifier & the identifiers. \\ % \bottomrule % \end{tabularx} % \end{center} @@ -2705,6 +2764,14 @@ piton_version = "3.0b" -- 2024/05/23 % \end{macrocode} % % \bigskip +% The command |\text| provided by the package \pkg{amstext} will be used to +% allow the use of the command |\pion{...}| (with the standard syntax) in +% mathematical mode. +% \begin{macrocode} +\RequirePackage { amstext } +% \end{macrocode} +% +% \bigskip % \begin{macrocode} \cs_new_protected:Npn \@@_error:n { \msg_error:nn { piton } } \cs_new_protected:Npn \@@_warning:n { \msg_warning:nn { piton } } @@ -2835,25 +2902,12 @@ piton_version = "3.0b" -- 2024/05/23 beamer .bool_gset:N = \g_@@_beamer_bool , beamer .default:n = true , - - math-comments .code:n = \@@_error:n { moved~to~preamble } , - comment-latex .code:n = \@@_error:n { moved~to~preamble } , unknown .code:n = \@@_error:n { Unknown~key~for~package } } % \end{macrocode} % % -% \bigskip -% \begin{macrocode} -\@@_msg_new:nn { moved~to~preamble } - { - The~key~'\l_keys_key_str'~*must*~now~be~used~with~ - \token_to_str:N \PitonOptions`in~the~preamble~of~your~ - document.\\ - That~key~will~be~ignored. - } -% \end{macrocode} % % \begin{macrocode} \@@_msg_new:nn { Unknown~key~for~package } @@ -2957,7 +3011,11 @@ piton_version = "3.0b" -- 2024/05/23 % \begin{macrocode} \lua_now:n { - piton.ListCommands = lpeg.P ( false ) + piton.BeamerCommands = lpeg.P ( "\\uncover" ) + + "\\only" + "\\visible" + "\\invisible" + "\\alert" + "\\action" + piton.beamer_environments = { "uncoverenv" , "onlyenv" , "visibleenv" , + "invisibleenv" , "alertenv" , "actionenv" } + piton.DetectedCommands = lpeg.P ( false ) piton.last_code = '' piton.last_language = '' } @@ -2975,8 +3033,8 @@ piton_version = "3.0b" -- 2024/05/23 % \end{macrocode} % % \medskip -% Each time the command |\PitonInputFile| of \pkg{piton} is -% used, the code of that environment will be stored in the following global string. +% Each time an environment of \pkg{piton} is used, the informatic code in the +% body of that environment will be stored in the following global string. % \begin{macrocode} \tl_new:N \g_piton_last_code_tl % \end{macrocode} @@ -3006,27 +3064,31 @@ piton_version = "3.0b" -- 2024/05/23 % % % \medskip -% We will compute (with Lua) the numbers of lines of the Python code and store +% We will compute (with Lua) the numbers of lines of the listings (or +% \emph{chunks} of listings when |split-on-empty-lines| is in force) and store % it in the following counter. % \begin{macrocode} \int_new:N \l_@@_nb_lines_int % \end{macrocode} % -% The same for the number of non-empty lines of the Python codes. +% The same for the number of non-empty lines of the listings. % \begin{macrocode} \int_new:N \l_@@_nb_non_empty_lines_int % \end{macrocode} % % The following counter will be used to count the lines during the composition. -% It will count all the lines, empty or not empty. It won't be used to print the -% numbers of the lines. +% It will take into account all the lines, empty or not empty. It won't be used +% to print the numbers of the lines but will be used to allow or disallow line +% breaks (when |splittable| is in force) and for the color of the background +% (when |background-color| is used with a \emph{list} of colors). % \begin{macrocode} \int_new:N \g_@@_line_int % \end{macrocode} % % \medskip % The following token list will contain the (potential) information to write -% on the |aux| (to be used in the next compilation). +% on the |aux| (to be used in the next compilation). The technic of the +% auxiliary file will be used when the key |width| is used with the value~|min|. % \begin{macrocode} \tl_new:N \g_@@_aux_tl % \end{macrocode} @@ -3034,26 +3096,31 @@ piton_version = "3.0b" -- 2024/05/23 % \medskip % The following counter corresponds to the key |splittable| of |\PitonOptions|. % If the value of |\l_@@_splittable_int| is equal to $n$, then no line break can -% occur within the first $n$~lines or the last $n$~lines of the listings. +% occur within the first $n$~lines or the last $n$~lines of a listing (or a +% \emph{chunk} of listings when the key |split-on-empty-lines| is in force). % \begin{macrocode} \int_new:N \l_@@_splittable_int % \end{macrocode} % % \medskip +% An initial value of |splittable| equal to 100 is equivalent to say that the +% environments |{Piton}| are unbreakable. +% \begin{macrocode} +\int_set:Nn \l_@@_splittable_int { 100 } +% \end{macrocode} +% +% \medskip % When the key |split-on-empty-lines| will be in force, then the following token % list will be inserted between the chunks of code (the informatic code provided -% by the final user is split in chunks on the empty lines in the code). +% by the final user is split in chunks on the empty lines in the code). % \begin{macrocode} \tl_new:N \l_@@_split_separation_tl -\tl_set:Nn \l_@@_split_separation_tl { \vspace{\baselineskip} \vspace{-1.25pt} } +\tl_set:Nn \l_@@_split_separation_tl + { \vspace { \baselineskip } \vspace { -1.25pt } } % \end{macrocode} +% That parameter must contain elements to be inserted in \emph{vertical} mode by +% TeX. % -% \medskip -% An initial value of |splittable| equal to 100 is equivalent to say that the -% environments |{Piton}| are unbreakable. -% \begin{macrocode} -\int_set:Nn \l_@@_splittable_int { 100 } -% \end{macrocode} % % % \medskip @@ -3213,11 +3280,6 @@ piton_version = "3.0b" -- 2024/05/23 \dim_set:Nn \l_@@_numbers_sep_dim { 0.7 em } % \end{macrocode} % -% \medskip -% The tabulators will be replaced by the content of the following token list. -% \begin{macrocode} -\tl_new:N \l_@@_tab_tl -% \end{macrocode} % % \medskip % Be careful. The following sequence |\g_@@_languages_seq| is not the list of @@ -3233,30 +3295,26 @@ piton_version = "3.0b" -- 2024/05/23 % % \medskip % \begin{macrocode} -\cs_new_protected:Npn \@@_set_tab_tl:n #1 - { - \tl_clear:N \l_@@_tab_tl - \prg_replicate:nn { #1 } - { \tl_put_right:Nn \l_@@_tab_tl { ~ } } - } -\@@_set_tab_tl:n { 4 } +\int_new:N \l_@@_tab_size_int +\int_set:Nn \l_@@_tab_size_int { 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 +\cs_new_protected:Npn \@@_tab: + { + \bool_if:NTF \l_@@_show_spaces_bool { + \hbox_set:Nn \l_tmpa_box + { \prg_replicate:nn \l_@@_tab_size_int { ~ } } + \dim_set:Nn \l_tmpa_dim { \box_wd:N \l_tmpa_box } \( \mathcolor { gray } - { \hbox_to_wd:nn \l_tmpa_dim { \rightarrowfill } \) } + { \hbox_to_wd:nn \l_tmpa_dim { \rightarrowfill } } \) } + { \hbox:n { \prg_replicate:nn \l_@@_tab_size_int { ~ } } } + \int_gadd:Nn \g_@@_indentation_int \l_@@_tab_size_int } % \end{macrocode} +% % % \medskip % The following integer corresponds to the key |gobble|. @@ -3284,18 +3342,6 @@ piton_version = "3.0b" -- 2024/05/23 { \int_gincr:N \g_@@_indentation_int } % \end{macrocode} % -% \medskip -% The following command |\@@_beamer_command:n| executes the argument -% corresponding to its argument but also stores it in |\l_@@_beamer_command_str|. -% That string is used only in the error message ``|cr~not~allowed|'' raised when -% there is a carriage return in the mandatory argument of that command. -% \begin{macrocode} -\cs_new_protected:Npn \@@_beamer_command:n #1 - { - \str_set:Nn \l_@@_beamer_command_str { #1 } - \use:c { #1 } - } -% \end{macrocode} % % \bigskip % In the environment |{Piton}|, the command |\label| will be linked to the @@ -3369,11 +3415,19 @@ piton_version = "3.0b" -- 2024/05/23 } % \end{macrocode} % +% +% \bigskip +% The spaces at the end of a line of code are deleted by \pkg{piton}. +% However, it's not actually true: they are replace by |\@@_trailing_space:|. +% \begin{macrocode} +\cs_new_protected:Npn \@@_trailing_space: { } +% \end{macrocode} +% When we have to rescan some pieces of code with |\@@_piton:n|, we will set +% |\@@_trailing_space:| equal to |\space|. % % \bigskip % \subsubsection{Treatment of a line of code} % -% The following command is only used once. % \begin{macrocode} \cs_new_protected:Npn \@@_replace_spaces:n #1 { @@ -3444,14 +3498,14 @@ piton_version = "3.0b" -- 2024/05/23 { \bool_if:nF { - \str_if_eq_p:nn { #1 } { \PitonStyle {Prompt}{} } + \str_if_eq_p:nn { #1 } { \PitonStyle { Prompt } { } } && \l_@@_skip_empty_lines_bool } { \int_gincr:N \g_@@_visual_line_int } \bool_if:nT { - ! \str_if_eq_p:nn { #1 } { \PitonStyle {Prompt}{} } + ! \str_if_eq_p:nn { #1 } { \PitonStyle { Prompt } { } } || ( ! \l_@@_skip_empty_lines_bool && \l_@@_label_empty_lines_bool ) } @@ -3579,24 +3633,63 @@ piton_version = "3.0b" -- 2024/05/23 % \end{macrocode} % % \bigskip +% The command |\@@_newline:| will be inserted by Lua between two lines of the +% informatic listing. +% \begin{itemize} +% \item In fact, it will be inserted between two commands +% |\@@_begin_line:|...|\@@_end_of_line:|. +% \item When the key |break-lines-in-Piton| is in force, a line of the +% informatic code (the \emph{input}) may result in several lines in the PDF (the +% \emph{output}). +% \item |\@@_newline:| has a rather complex behaviour because it may close and +% open |\vtop|s and finish and start paragraphs. +% \end{itemize} % \begin{macrocode} \cs_new_protected:Npn \@@_newline: { +% \end{macrocode} +% We recall that |\g_@@_line_int| is \emph{not} used for the number of line +% printed in the PDF (when |line-numbers| is in force)... +% \begin{macrocode} \int_gincr:N \g_@@_line_int +% \end{macrocode} +% ... it will be used to allow or disallow page breaks (the final user controls +% that behaviour with the key |splittable|). +% \begin{macrocode} \int_compare:nNnT \g_@@_line_int > { \l_@@_splittable_int - 1 } { \int_compare:nNnT - { \l_@@_nb_lines_int - \g_@@_line_int } > \l_@@_splittable_int + { \l_@@_nb_lines_int - \g_@@_line_int + 1 } > \l_@@_splittable_int +% \end{macrocode} +% Now, we allow a page break after the current line of code. +% \begin{macrocode} { \egroup \bool_if:NT \g_@@_footnote_bool \endsavenotes - \par \mode_leave_vertical: + \par +% \end{macrocode} +% Each non-splittable block of lines is composed in a |\vtop| of +% TeX inserted in a paragraph of TeX. +% \begin{itemize} +% \item In the previous lines, we have closed a |\vtop| (with |\egroup|) and a +% paragraph (with |\par|). +% \item Now, we start a new paragraph (with |\mode_leave_vertical:|) and open a +% |\vtop| (with |\vtop \bgroup|). +% \end{itemize} +% \begin{macrocode} + \mode_leave_vertical: \bool_if:NT \g_@@_footnote_bool \savenotes \vtop \bgroup +% \end{macrocode} +% And, in that |\vtop|, of course, we will put a box for each line of the +% informatic listing (but a line of the informatic listing may be formatted as a +% box of several lines when |break-lines-in-Piton| is in force). +% \begin{macrocode} } } } % \end{macrocode} +% After the command |\@@_newline:|, we will have a command |\@@_begin_line:|. % % \bigskip % \begin{macrocode} @@ -3637,6 +3730,8 @@ piton_version = "3.0b" -- 2024/05/23 \bool_new:N \l_@@_skip_empty_lines_bool \bool_set_true:N \l_@@_skip_empty_lines_bool \bool_new:N \l_@@_line_numbers_absolute_bool +\tl_new:N \l_@@_line_numbers_format_bool +\tl_set:Nn \l_@@_line_numbers_format_tl { \footnotesize \color { gray } } \bool_new:N \l_@@_label_empty_lines_bool \bool_set_true:N \l_@@_label_empty_lines_bool \int_new:N \l_@@_number_lines_start_int @@ -3667,12 +3762,8 @@ piton_version = "3.0b" -- 2024/05/23 false .code:n = \bool_set_false:N \l_@@_line_numbers_bool , start .code:n = - \bool_if:NTF \l_@@_in_PitonOptions_bool - { Invalid~key } - { - \bool_set_true:N \l_@@_line_numbers_bool - \int_set:Nn \l_@@_number_lines_start_int { #1 } - } , + \bool_set_true:N \l_@@_line_numbers_bool + \int_set:Nn \l_@@_number_lines_start_int { #1 } , start .value_required:n = true , skip-empty-lines .code:n = @@ -3699,11 +3790,7 @@ piton_version = "3.0b" -- 2024/05/23 { \bool_set_true:N \l_@@_line_numbers_absolute_bool \bool_set_false:N \l_@@_skip_empty_lines_bool - } - \bool_lazy_or:nnF - \l_@@_in_PitonInputFile_bool - \l_@@_in_PitonOptions_bool - { \@@_error:n { Invalid~key } } , + } , absolute .value_forbidden:n = true , resume .code:n = @@ -3715,6 +3802,9 @@ piton_version = "3.0b" -- 2024/05/23 sep .dim_set:N = \l_@@_numbers_sep_dim , sep .value_required:n = true , + format .tl_set:N = \l_@@_line_numbers_format_tl , + format .value_required:n = true , + unknown .code:n = \@@_error:n { Unknown~key~for~line-numbers } } % \end{macrocode} @@ -3730,9 +3820,17 @@ piton_version = "3.0b" -- 2024/05/23 % First, we put keys that should be available only in the preamble. % \begin{macrocode} detected-commands .code:n = - \lua_now:n { piton.addListCommands('#1') } , + \lua_now:n { piton.addDetectedCommands('#1') } , detected-commands .value_required:n = true , detected-commands .usage:n = preamble , + detected-beamer-commands .code:n = + \lua_now:n { piton.addBeamerCommands('#1') } , + detected-beamer-commands .value_required:n = true , + detected-beamer-commands .usage:n = preamble , + detected-beamer-environments .code:n = + \lua_now:n { piton.addBeamerEnvironments('#1') } , + detected-beamer-environments .value_required:n = true , + detected-beamer-environments .usage:n = preamble , % \end{macrocode} % % Remark that the command |\lua_escape:n| is fully expandable. That's why we use @@ -3849,11 +3947,9 @@ piton_version = "3.0b" -- 2024/05/23 } , left-margin .value_required:n = true , - tab-size .code:n = \@@_set_tab_tl:n { #1 } , + tab-size .int_set:N = \l_@@_tab_size_int , tab-size .value_required:n = true , - show-spaces .code:n = - \bool_set_true:N \l_@@_show_spaces_bool - \@@_convert_tab_tl: , + show-spaces .bool_set:N = \l_@@_show_spaces_bool , 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 , @@ -3939,7 +4035,7 @@ piton_version = "3.0b" -- 2024/05/23 % When using |\NewPitonEnvironment| a user may use |\PitonOptions| inside. % However, the set of keys available should be different that in standard % |\PitonOptions|. That's why we define a version of |\PitonOptions| with no -% restrection on the set of available keys and we will link that version to +% restriction on the set of available keys and we will link that version to % |\PitonOptions| in such environment. % \begin{macrocode} \NewDocumentCommand \@@_fake_PitonOptions { } @@ -3954,7 +4050,9 @@ piton_version = "3.0b" -- 2024/05/23 % % \medskip % The following counter will be used to count the lines in the code when the -% user requires the numbers of the lines to be printed (with |line-numbers|). +% user requires the numbers of the lines to be printed (with |line-numbers|) +% whereas the counter |\g_@@_line_int| previously defined is \emph{not} used for +% that functionality. % % \begin{macrocode} \int_new:N \g_@@_visual_line_int @@ -3974,9 +4072,12 @@ piton_version = "3.0b" -- 2024/05/23 \hbox_overlap_left:n { { - \color { gray } - \footnotesize - \int_to_arabic:n \g_@@_visual_line_int + \l_@@_line_numbers_format_tl +% \end{macrocode} +% We put braces. Thus, the user may use the key |line-numbers/format| with a +% value such as |\fbox|. +% \begin{macrocode} + { \int_to_arabic:n \g_@@_visual_line_int } } \skip_horizontal:N \l_@@_numbers_sep_dim } @@ -4164,18 +4265,29 @@ piton_version = "3.0b" -- 2024/05/23 \NewDocumentCommand { \@@_piton_standard } { m } { \group_begin: - \ttfamily % \end{macrocode} % The following tuning of LuaTeX in order to avoid all break of lines on the % hyphens. % \begin{macrocode} \automatichyphenmode = 1 +% \end{macrocode} +% Remark that the argument of |\piton| (with the normal syntax) is expanded in +% the TeX sens, (see the |\tl_set:Nx| below) and that's why we can provide the +% following escapes to the final user: +% \begin{macrocode} \cs_set_eq:NN \\ \c_backslash_str \cs_set_eq:NN \% \c_percent_str \cs_set_eq:NN \{ \c_left_brace_str \cs_set_eq:NN \} \c_right_brace_str \cs_set_eq:NN \$ \c_dollar_str +% \end{macrocode} +% The standard command |\␣| is \emph{not} expandable and we need here expandable +% commands. With the following code, we define an expandable command. +% \begin{macrocode} \cs_set_eq:cN { ~ } \space +% \end{macrocode} +% +% \begin{macrocode} \cs_set_protected:Npn \@@_begin_line: { } \cs_set_protected:Npn \@@_end_line: { } \tl_set:Nx \l_tmpa_tl @@ -4196,7 +4308,14 @@ piton_version = "3.0b" -- 2024/05/23 \bool_if:NT \l_@@_break_lines_in_piton_bool { \regex_replace_all:nnN { \x20 } { \x20 } \l_tmpa_tl } } - \l_tmpa_tl +% \end{macrocode} +% The command |\text| is provided by the package \pkg{amstext} (loaded by \pkg{piton}). +% \begin{macrocode} + \if_mode_math: + \text { \ttfamily \l_tmpa_tl } + \else: + \ttfamily \l_tmpa_tl + \fi: \group_end: } % \end{macrocode} @@ -4229,7 +4348,7 @@ piton_version = "3.0b" -- 2024/05/23 % % \bigskip % The following command is not a user command. It will be used when we will -% have to ``rescan'' some chunks of Python code. For example, it will be the +% have to ``rescan'' some chunks of informatic code. For example, it will be the % initial value of the Piton style |InitialValues| (the default values of the % arguments of a Python function). % \begin{macrocode} @@ -4240,6 +4359,7 @@ piton_version = "3.0b" -- 2024/05/23 \cs_set_protected:Npn \@@_end_line: { } \cs_set:cpn { pitonStyle _ \l_piton_language_str _ Prompt } { } \cs_set:cpn { pitonStyle _ Prompt } { } + \cs_set_eq:NN \@@_trailing_space: \space \bool_lazy_or:nnTF \l_@@_break_lines_in_piton_bool \l_@@_break_lines_in_Piton_bool @@ -4261,50 +4381,12 @@ piton_version = "3.0b" -- 2024/05/23 } \bool_if:NT \l_@@_show_spaces_bool { \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl } % U+2423 - \l_tmpa_tl + \exp_args:No \@@_replace_spaces:n \l_tmpa_tl \group_end: } % \end{macrocode} % -% \bigskip -% The following command is similar to the previous one but raise a fatal error if -% its argument contains a carriage return. -% \begin{macrocode} -\cs_new_protected:Npn \@@_piton_no_cr:n #1 - { - \group_begin: - \cs_set_protected:Npn \@@_begin_line: { } - \cs_set_protected:Npn \@@_end_line: { } - \cs_set:cpn { pitonStyle _ \l_piton_language_str _ Prompt } { } - \cs_set:cpn { pitonStyle _ Prompt } { } - \cs_set_protected:Npn \@@_newline: - { \msg_fatal:nn { piton } { cr~not~allowed } } - \bool_lazy_or:nnTF - \l_@@_break_lines_in_piton_bool - \l_@@_break_lines_in_Piton_bool - { - \tl_set:Nx \l_tmpa_tl - { - \lua_now:e - { piton.ParseTer('\l_piton_language_str',token.scan_string()) } - { #1 } - } - } - { - \tl_set:Nx \l_tmpa_tl - { - \lua_now:e - { piton.Parse('\l_piton_language_str',token.scan_string()) } - { #1 } - } - } - \bool_if:NT \l_@@_show_spaces_bool - { \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl } % U+2423 - \l_tmpa_tl - \group_end: - } -% \end{macrocode} -% +% % \bigskip % Despite its name, |\@@_pre_env:| will be used both in |\PitonInputFile| and % in the environments such as |{Piton}|. @@ -4347,7 +4429,7 @@ piton_version = "3.0b" -- 2024/05/23 { \hbox_set:Nn \l_tmpa_box { - \footnotesize + \l_@@_line_numbers_format_tl \bool_if:NTF \l_@@_skip_empty_lines_bool { \lua_now:n @@ -4448,14 +4530,7 @@ piton_version = "3.0b" -- 2024/05/23 } { \group_end: - \mode_if_vertical:TF \mode_leave_vertical: \newline -% \end{macrocode} -% We count with Lua the number of lines of the argument. The result will be -% stored by Lua in |\l_@@_nb_lines_int|. That information will be used to allow -% or disallow page breaks. The use of |token.scan_argument| avoids problems with -% the delimiters of the Lua string. -% \begin{macrocode} - \lua_now:n { piton.CountLines(token.scan_argument()) } { ##1 } + \mode_if_vertical:TF { \noindent \mode_leave_vertical: } \newline % \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. @@ -4463,7 +4538,8 @@ piton_version = "3.0b" -- 2024/05/23 \@@_compute_left_margin:nn { CountNonEmptyLines } { ##1 } \@@_compute_width: \ttfamily - \dim_zero:N \parskip + \dim_zero:N \parskip + \noindent % added 2024/08/07 % \end{macrocode} % % Now, the key |write|. @@ -4545,7 +4621,7 @@ piton_version = "3.0b" -- 2024/05/23 % \bigskip % The following function will be used when the key |split-on-empty-lines| is not % in force. It will gobble the spaces at the beginning of the lines and parse -% the code. The argument is provided by curryfication. +% the code. The argument is provided by curryfication. % \begin{macrocode} \cs_new_protected:Npn \@@_gobble_parse:n { @@ -4726,7 +4802,6 @@ piton_version = "3.0b" -- 2024/05/23 \@@_compute_left_margin:no { CountNonEmptyLinesFile } \l_@@_file_name_str \@@_compute_width: \ttfamily - % \leavevmode \lua_now:e { piton.ParseFile( @@ -4739,6 +4814,14 @@ piton_version = "3.0b" -- 2024/05/23 \bool_if:NT \l_@@_width_min_bool \@@_width_to_aux: \group_end: % \end{macrocode} +% +% +% The following line is to allow programs such as |latexmk| to be aware that the +% file (read by |\PitonInputFile|) is loaded during the compilation of the LaTeX +% document. +% \begin{macrocode} + \exp_args:Nx \iow_log:n {(\l_@@_file_name_str)} +% \end{macrocode} % We recall that, if we are in Beamer, the command |\PitonInputFile| is % ``overlay-aware'' and that's why we close now an environment |{uncoverenv}| % that we have opened at the beginning of the command. @@ -4818,10 +4901,12 @@ piton_version = "3.0b" -- 2024/05/23 Discard , Exception , FormattingType , + Identifier.Internal , Identifier , InitialValues , Interpol.Inside , Keyword , + Keyword.Governing , Keyword.Constant , Keyword2 , Keyword3 , @@ -4854,10 +4939,14 @@ piton_version = "3.0b" -- 2024/05/23 TypeParameter , UserFunction , % \end{macrocode} +% |TypeExpression| is an internal style for expressions which defines types in OCaml. +% \begin{macrocode} + TypeExpression , +% \end{macrocode} % Now, specific styles for the languages created with |\NewPitonLanguage| with % the syntax of \pkg{listings}. % \begin{macrocode} - Directive + Directive } \clist_map_inline:Nn \g_@@_styles_clist @@ -4879,18 +4968,25 @@ piton_version = "3.0b" -- 2024/05/23 \keys_define:nn { piton / Styles } { - String .meta:n = { String.Long = #1 , String.Short = #1 } , - Comment.Math .tl_set:c = pitonStyle _ Comment.Math , - ParseAgain .tl_set:c = pitonStyle _ ParseAgain , - ParseAgain .value_required:n = true , - ParseAgain.noCR .tl_set:c = pitonStyle _ ParseAgain.noCR , - ParseAgain.noCR .value_required:n = true , + String .meta:n = { String.Long = #1 , String.Short = #1 } , + Comment.Math .tl_set:c = pitonStyle _ Comment.Math , + ParseAgain .tl_set:c = pitonStyle _ ParseAgain , + ParseAgain .value_required:n = true , unknown .code:n = \@@_error:n { Unknown~key~for~SetPitonStyle } } % \end{macrocode} % % \bigskip +% \begin{macrocode} +\SetPitonStyle[OCaml] + { + TypeExpression = + \SetPitonStyle { Identifier = \PitonStyle { Name.Type } } \@@_piton:n + } +% \end{macrocode} +% +% \bigskip % We add the word |String| to the list of the styles because we will use that % list in the error message for an unknown key in |\SetPitonStyle|. % @@ -4919,44 +5015,50 @@ piton_version = "3.0b" -- 2024/05/23 % \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} , - Name.Constructor = \color[HTML]{006000} \bfseries , - Name.Field = \color[HTML]{AA6600} , - Name.Module = \color[HTML]{0060A0} \bfseries , - Name.Table = \color[HTML]{309030} , - 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 , - Interpol.Inside = \color{black}\@@_piton:n , - TypeParameter = \color[HTML]{336666} \itshape , - Preproc = \color[HTML]{AA6600} \slshape , - Identifier = \@@_identifier:n , - Directive = \color[HTML]{AA6600} , - Tag = \colorbox{gray!10}, - UserFunction = , - Prompt = , - ParseAgain.noCR = \@@_piton_no_cr:n , - ParseAgain = \@@_piton:n , - Discard = \use_none:n + Comment = \color[HTML]{0099FF} \itshape , + Exception = \color[HTML]{CC0000} , + Keyword = \color[HTML]{006699} \bfseries , + Keyword.Governing = \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} , + Name.Constructor = \color[HTML]{006000} \bfseries , + Name.Field = \color[HTML]{AA6600} , + Name.Module = \color[HTML]{0060A0} \bfseries , + Name.Table = \color[HTML]{309030} , + 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 , + Interpol.Inside = \color{black}\@@_piton:n , + TypeParameter = \color[HTML]{336666} \itshape , + Preproc = \color[HTML]{AA6600} \slshape , +% \end{macrocode} +% We need the command |\@@_identifier:n| because of the command +% |\SetPitonIdentifier|. The command |\@@_identifier:n| will potentially call +% the style |Identifier| (which is a user-style, not an internal style). +% \begin{macrocode} + Identifier.Internal = \@@_identifier:n , + Identifier = , + Directive = \color[HTML]{AA6600} , + Tag = \colorbox{gray!10}, + UserFunction = , + Prompt = , + ParseAgain = \@@_piton_no_cr:n , + Discard = \use_none:n } % \end{macrocode} -% The last styles |ParseAgain.noCR| and |ParseAgain| should be considered as +% The styles |ParseAgain.noCR| should be considered as % ``internal style'' (not available for the final user). However, maybe we will -% change that and document these styles for the final user (why not?). +% change that and document that style for the final user. % % \medskip % If the key |math-comments| has been used at load-time, we change the style @@ -5001,7 +5103,10 @@ piton_version = "3.0b" -- 2024/05/23 \cs_new_protected:Npn \@@_identifier:n #1 { \cs_if_exist_use:cF { PitonIdentifier _ \l_piton_language_str _ #1 } - { \cs_if_exist_use:c { PitonIdentifier _ #1 } } + { + \cs_if_exist_use:cF { PitonIdentifier _ #1 } + { \PitonStyle { Identifier } } + } { #1 } } % \end{macrocode} @@ -5215,9 +5320,13 @@ piton_version = "3.0b" -- 2024/05/23 } % \end{macrocode} % +% We don't give the name |syntax error| for the following error because you +% should not give a name with a space because such space could be replaced by +% U+2423 when the key |show-spaces| is in force in the command |\piton|. % \begin{macrocode} -\@@_msg_new:nn { syntax~error } +\@@_msg_new:nn { SyntaxError } { + Syntax~Error.\\ Your~code~of~the~language~"\l_piton_language_str"~is~not~ syntactically~correct.\\ It~won't~be~printed~in~the~PDF~file. @@ -5225,6 +5334,16 @@ piton_version = "3.0b" -- 2024/05/23 % \end{macrocode} % % \begin{macrocode} +\@@_msg_new:nn { FileError } + { + File~Error.\\ + It's~not~possible~to~write~on~the~file~'\l_@@_write_str'.\\ + \sys_if_shell_unrestricted:F { Be~sure~to~compile~with~'-shell-escape'.\\ } + If~you~go~on,~nothing~will~be~written~on~the~file. + } +% \end{macrocode} +% +% \begin{macrocode} \@@_msg_new:nn { begin~marker~not~found } { Marker~not~found.\\ @@ -5274,6 +5393,8 @@ piton_version = "3.0b" -- 2024/05/23 break-lines-in-Piton,~ continuation-symbol,~ continuation-symbol-on-indentation,~ + detected-beamer-commands,~ + detected-beamer-environments,~ detected-commands,~ end-of-broken-line,~ end-range,~ @@ -5310,18 +5431,6 @@ piton_version = "3.0b" -- 2024/05/23 } % \end{macrocode} % -% \bigskip -% \begin{macrocode} -\@@_msg_new:nn { cr~not~allowed } - { - You~can't~put~any~carriage~return~in~the~argument~ - of~a~command~\c_backslash_str - \l_@@_beamer_command_str\ within~an~ - environment~of~'piton'.~You~should~consider~using~the~ - corresponding~environment.\\ - That~error~is~fatal. - } -% \end{macrocode} % % \bigskip % \begin{macrocode} @@ -5386,8 +5495,28 @@ piton_version = "3.0b" -- 2024/05/23 % \begin{macrocode} F = space ^ 0 * ( ( alpha ^ 1 ) / "\\%0" ) * space ^ 0 } - function piton.addListCommands( key_value ) - piton.ListCommands = piton.ListCommands + my_lpeg : match ( key_value ) + function piton.addDetectedCommands( key_value ) + piton.DetectedCommands = piton.DetectedCommands + my_lpeg : match ( key_value ) + end + function piton.addBeamerCommands( key_value ) + piton.BeamerCommands + = piton.BeamerCommands + my_lpeg : match ( key_value ) + end +% \end{macrocode} +% +% \begin{macrocode} + local function insert(...) + local s = piton.beamer_environments + for _ , x in ipairs({...}) do table.insert(s,x) end + return s + end + local my_lpeg_bis = + P { "E" , + E = ( V "F" * ( "," * V "F" ) ^ 0 ) / insert , + F = space ^ 0 * ( alpha ^ 1 ) * space ^ 0 + } + function piton.addBeamerEnvironments( key_value ) + piton.beamer_environments = my_lpeg_bis : match ( key_value ) end \end{luacode*} %</STY> @@ -5411,23 +5540,11 @@ 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} -% % \begin{macrocode} local function sprintL3 ( s ) tex.sprint ( luatexbase.catcodetables.expl , s ) end -% \end{uncoverenv} +% \end{macrocode} % % \bigskip % \subsubsection{Special functions dealing with LPEG} @@ -5589,7 +5706,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.Internal' , identifier ) % \end{macrocode} % % \bigskip @@ -5648,12 +5765,12 @@ local SkipSpace = Q " " ^ 0 local Punct = Q ( S ".,:;!" ) -local Tab = "\t" * Lc "\\l_@@_tab_tl" +local Tab = "\t" * Lc [[\@@_tab:]] % \end{macrocode} % % \bigskip % \begin{macrocode} -local SpaceIndentation = Lc "\\@@_an_indentation_space:" * Q " " +local SpaceIndentation = Lc [[\@@_an_indentation_space:]] * Q " " % \end{macrocode} % % \bigskip @@ -5668,7 +5785,18 @@ local Delim = Q ( S "[({})]" ) % However, when the key |show-spaces-in-strings| is in force, |\\l_@@_space_tl| will % contain ␣ (U+2423) in order to visualize the spaces. % \begin{macrocode} -local VisualSpace = space * Lc "\\l_@@_space_tl" +local VisualSpace = space * Lc [[\l_@@_space_tl]] +% \end{macrocode} +% +% \bigskip +% Of course, the \textsc{lpeg} |strict_braces| is for balanced braces (without the +% question of strings of an informatic language). +% \begin{macrocode} + local strict_braces = + P { "E" , + E = ( "{" * V "F" * "}" + ( 1 - S ",{}" ) ) ^ 0 , + F = ( "{" * V "F" * "}" + ( 1 - S "{}" ) ) ^ 0 + } % \end{macrocode} % % \bigskip @@ -5687,7 +5815,8 @@ local LPEG_cleaner = { } % 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). +% the language (at least the shorts strings). The argument of |Compute_braces| +% must be a pattern \emph{which does no catching}. % \begin{macrocode} local function Compute_braces ( lpeg_string ) return P { "E" , @@ -5703,16 +5832,19 @@ local function Compute_braces ( lpeg_string ) return 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 "{" ) + * C ( piton.DetectedCommands * P "{" ) * Cc "}" ) - * ( braces / (function ( s ) return LPEG1[lang] : match ( s ) end ) ) + * ( braces + / ( function ( s ) if s ~= '' then return LPEG1[lang] : match ( s ) end end ) ) * P "}" * Ct ( Cc "Close" ) end @@ -5721,9 +5853,10 @@ end % \bigskip % \begin{macrocode} local function Compute_LPEG_cleaner ( lang , braces ) return - Ct ( ( piton.ListCommands * "{" - * ( braces - / ( function ( s ) return LPEG_cleaner[lang] : match ( s ) end ) ) + Ct ( ( piton.DetectedCommands * "{" + * ( braces + / ( function ( s ) + if s ~= '' then return LPEG_cleaner[lang] : match ( s ) end end ) ) * "}" + EscapeClean + C ( P ( 1 ) ) @@ -5744,28 +5877,20 @@ local BeamerBeginEnvironments = P ( true ) local BeamerEndEnvironments = P ( true ) % \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 +piton.BeamerEnvironments = P ( false ) +for _ , x in ipairs ( piton.beamer_environments ) do + piton.BeamerEnvironments = piton.BeamerEnvironments + x end % \end{macrocode} -% +% % \bigskip % \begin{macrocode} BeamerBeginEnvironments = ( space ^ 0 * L ( - P "\\begin{" * BeamerNamesEnvironments * "}" + P "\\begin{" * piton.BeamerEnvironments * "}" * ( "<" * ( 1 - P ">" ) ^ 0 * ">" ) ^ -1 ) * "\r" @@ -5776,11 +5901,12 @@ BeamerBeginEnvironments = % \begin{macrocode} BeamerEndEnvironments = ( space ^ 0 * - L ( P "\\end{" * BeamerNamesEnvironments * "}" ) + L ( P "\\end{" * piton.BeamerEnvironments * "}" ) * "\r" ) ^ 0 % \end{macrocode} % +% % % \bigskip % The following Lua function will be used to compute the \textsc{lpeg} |Beamer| @@ -5795,14 +5921,14 @@ local function Compute_Beamer ( lang , braces ) local lpeg = L ( P "\\pause" * ( "[" * ( 1 - P "]" ) ^ 0 * "]" ) ^ -1 ) lpeg = lpeg + Ct ( Cc "Open" - * C ( ( P "\\uncover" + "\\only" + "\\alert" + "\\visible" - + "\\invisible" + "\\action" ) + * C ( piton.BeamerCommands * ( "<" * ( 1 - P ">" ) ^ 0 * ">" ) ^ -1 * P "{" ) * Cc "}" ) - * ( braces / ( function ( s ) return LPEG1[lang] : match ( s ) end ) ) + * ( braces / + ( function ( s ) if s ~= '' then return LPEG1[lang] : match ( s ) end end ) ) * "}" * Ct ( Cc "Close" ) % \end{macrocode} @@ -5814,29 +5940,38 @@ local function Compute_Beamer ( lang , braces ) % \begin{macrocode} lpeg = lpeg + L ( P "\\alt" * "<" * ( 1 - P ">" ) ^ 0 * ">" * "{" ) - * K ( 'ParseAgain.noCR' , braces ) + * ( braces / + ( function ( s ) if s ~= '' then return LPEG1[lang] : match ( s ) end end ) ) * L ( P "}{" ) - * K ( 'ParseAgain.noCR' , braces ) + * ( braces / + ( function ( s ) if s ~= '' then return LPEG1[lang] : match ( s ) end end ) ) * L ( P "}" ) % \end{macrocode} % % \bigskip -% For |\\temporal|, the specification of the overlays (between angular brackets) is mandatory. +% For |\\temporal|, the specification of the overlays (between angular brackets) +% is mandatory. % \begin{macrocode} lpeg = lpeg + L ( ( P "\\temporal" ) * "<" * ( 1 - P ">" ) ^ 0 * ">" * "{" ) - * K ( 'ParseAgain.noCR' , braces ) + * ( braces + / ( function ( s ) + if s ~= '' then return LPEG1[lang] : match ( s ) end end ) ) * L ( P "}{" ) - * K ( 'ParseAgain.noCR' , braces ) + * ( braces + / ( function ( s ) + if s ~= '' then return LPEG1[lang] : match ( s ) end end ) ) * L ( P "}{" ) - * K ( 'ParseAgain.noCR' , braces ) + * ( braces + / ( function ( s ) + if s ~= '' then return LPEG1[lang] : match ( s ) end end ) ) * L ( P "}" ) % \end{macrocode} % % \bigskip % Now, the environments of Beamer. % \begin{macrocode} - for _ , x in ipairs ( list_beamer_env ) do + for _ , x in ipairs ( piton.beamer_environments ) do lpeg = lpeg + Ct ( Cc "Open" * C ( @@ -5847,7 +5982,11 @@ local function Compute_Beamer ( lang , braces ) ) * ( ( ( 1 - P ( "\\end{" .. x .. "}" ) ) ^ 0 ) - / ( function ( s ) return LPEG1[lang] : match ( s ) end ) + / ( function ( s ) + if s ~= '' + then return LPEG1[lang] : match ( s ) + end + end ) ) * P ( "\\end{" .. x .. "}" ) * Ct ( Cc "Close" ) @@ -5900,14 +6039,14 @@ local Prompt = K ( 'Prompt' , ( ( P ">>>" + "..." ) * P " " ^ -1 ) ^ -1 ) % \bigskip % The following \textsc{lpeg} |EOL| is for the end of lines. % \begin{macrocode} -local EOL = +local EOL_without_space_indentation = P "\r" * ( ( space ^ 0 * -1 ) + % \end{macrocode} -% We recall that each line in the Python code we have to parse will be sent +% We recall that each line of the informatic 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 @@ -5917,18 +6056,22 @@ local EOL = Cc "EOL" * Ct ( - Lc "\\@@_end_line:" + Lc [[\@@_end_line:]] * BeamerEndEnvironments * BeamerBeginEnvironments * PromptHastyDetection - * Lc "\\@@_newline: \\@@_begin_line:" + * Lc [[\@@_newline:\@@_begin_line:]] * Prompt ) ) ) - * ( SpaceIndentation ^ 0 * # ( 1 - S " \r" ) ) ^ -1 % \end{macrocode} % +% \begin{macrocode} +local EOL = EOL_without_space_indentation + * ( 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 caught must @@ -5959,6 +6102,17 @@ local Operator = local OperatorWord = K ( 'Operator.Word' , P "in" + "is" + "and" + "or" + "not" ) +% \end{macrocode} +% +% \smallskip +% The keyword |in| in a construction such as ``|for i in range(n)|'' must be +% formatted as a keyword and not as an |Operator.Word|. +% \begin{macrocode} +local For = K ( 'Keyword' , P "for" ) + * Space + * Identifier + * Space + * K ( 'Keyword' , P "in" ) local Keyword = K ( 'Keyword' , @@ -6195,15 +6349,18 @@ local ShortString = SingleShortString + DoubleShortString % \bigskip % \paragraph{Beamer} % +% The argument of |Compute_braces| must be a pattern \emph{which does no +% catching} corresponding to the strings of the language. +% % \begin{macrocode} local braces = Compute_braces ( - Q ( P "\"" + "r\"" + "R\"" + "f\"" + "F\"" ) - * ( "\"" * ( P "\\\"" + 1 - S "\"" ) ^ 0 * "\"" ) + ( P "\"" + "r\"" + "R\"" + "f\"" + "F\"" ) + * ( P "\\\"" + 1 - S "\"" ) ^ 0 * "\"" + - Q ( P '\'' + 'r\'' + 'R\'' + 'f\'' + 'F\'' ) - * ( '\'' * ( P '\\\'' + 1 - S '\'' ) ^ 0 * '\'' ) + ( P '\'' + 'r\'' + 'R\'' + 'f\'' + 'F\'' ) + * ( P '\\\'' + 1 - S '\'' ) ^ 0 * '\'' ) if piton.beamer then Beamer = Compute_Beamer ( 'python' , braces ) end % \end{macrocode} @@ -6379,8 +6536,8 @@ local DefFunction = * SkipSpace * ( 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 +% Here, we need a \pkg{piton} style |ParseAgain.noCR| which will be linked to +% |\@@_piton_no_cr: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} @@ -6413,12 +6570,16 @@ local ExceptionInConsole = Exception * Q ( ( 1 - P "\r" ) ^ 0 ) * EOL % \bigskip % \paragraph{The main LPEG for the language Python} % +% \begin{macrocode} +local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1 +% \end{macrocode} +% % First, the main loop : % \begin{macrocode} local Main = - space ^ 1 * -1 - + space ^ 0 * EOL - + Space + -- space ^ 1 * -1 + -- + space ^ 0 * EOL + Space + Tab + Escape + EscapeMath + CommentLaTeX @@ -6429,16 +6590,17 @@ local Main = + ExceptionInConsole + Delim + Operator - + OperatorWord * ( Space + Punct + Delim + EOL + -1 ) + + OperatorWord * EndKeyword + ShortString + Punct + FromImport + RaiseException + DefFunction + DefClass - + Keyword * ( Space + Punct + Delim + EOL + -1 ) + + For + + Keyword * EndKeyword + Decorator - + Builtin * ( Space + Punct + Delim + EOL + -1 ) + + Builtin * EndKeyword + Identifier + Number + Word @@ -6461,18 +6623,25 @@ LPEG2['python'] = ( space ^ 0 * "\r" ) ^ -1 * BeamerBeginEnvironments * PromptHastyDetection - * Lc '\\@@_begin_line:' + * Lc [[\@@_begin_line:]] * Prompt * SpaceIndentation ^ 0 - * LPEG1['python'] + * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0 * -1 - * Lc '\\@@_end_line:' + * Lc [[\@@_end_line:]] ) % \end{macrocode} % % % \bigskip % \subsubsection{The language Ocaml} +% +% The following LPEG corresponds to the balanced expressions (balanced according +% to the parenthesis). Of course, we must write |(1 - S "()")| with outer parenthesis. +% \begin{macrocode} +local balanced_parens = + P { "E" , E = ( "(" * V "E" * ")" + ( 1 - S "()" ) ) ^ 0 } +% \end{macrocode} % % \begin{macrocode} local Delim = Q ( P "[|" + "|]" + S "[()]" ) @@ -6497,7 +6666,7 @@ local ModuleType = K ( 'Name.Type' , cap_identifier ) % elsewhere in OCaml. % \begin{macrocode} local identifier = ( R "az" + "_" ) * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0 -local Identifier = K ( 'Identifier' , identifier ) +local Identifier = K ( 'Identifier.Internal' , identifier ) % \end{macrocode} % % @@ -6524,7 +6693,7 @@ local OneFieldDefinition = ( K ( 'Keyword' , "mutable" ) * SkipSpace ) ^ -1 * K ( 'Name.Field' , identifier ) * SkipSpace * Q ":" * SkipSpace - * K ( 'Name.Type' , expression_for_fields ) + * K ( 'TypeExpression' , expression_for_fields ) * SkipSpace local OneField = @@ -6555,7 +6724,7 @@ local DotNotation = ( K ( 'Name.Module' , cap_identifier ) * Q "." - * ( Identifier + Constructor + Q "(" + Q "[" + Q "{" ) + * ( Identifier + Constructor + Q "(" + Q "[" + Q "{" ) ^ ( -1 ) + Identifier * Q "." @@ -6573,21 +6742,25 @@ local Operator = local OperatorWord = K ( 'Operator.Word' , - P "and" + "asr" + "land" + "lor" + "lsl" + "lxor" + "mod" + "or" ) + P "asr" + "land" + "lor" + "lsl" + "lxor" + "mod" + "or" ) -local Keyword = + +local governing_keyword = P "and" + "begin" + "class" + "constraint" + + "end" + "external" + "functor" + "include" + "inherit" + "initializer" + + "in" + "let" + "method" + "module" + "object" + "open" + "rec" + "sig" + + "struct" + "type" + "val" + +local Keyword = K ( 'Keyword' , - 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" ) + P "assert" + "as" + "done" + "downto" + "do" + "else" + "exception" + + "for" + "function" + "fun" + "if" + "lazy" + "match" + "mutable" + + "new" + "of" + "private" + "raise" + "then" + "to" + "try" + + "virtual" + "when" + "while" + "with" ) + + K ( 'Keyword.Constant' , P "true" + "false" ) + + K ('Keyword.Governing', governing_keyword ) local Builtin = - K ( 'Name.Builtin' , P "not" + "incr" + "decr" + "fst" + "snd" ) + K ( 'Name.Builtin' , P "not" + "incr" + "decr" + "fst" + "snd" + "ref" ) % \end{macrocode} % % \bigskip @@ -6604,8 +6777,20 @@ local Exception = % \paragraph{The characters in OCaml} % % \begin{macrocode} -local Char = - K ( 'String.Short' , "'" * ( ( 1 - P "'" ) ^ 0 + "\\'" ) * "'" ) +local Char = + K ( 'String.Short', + P "'" * + ( + ( 1 - S "'\\" ) + + "\\" + * ( S "\\'ntbr \"" + + digit * digit * digit + + P "x" * ( digit + R "af" + R "AF" ) + * ( digit + R "af" + R "AF" ) + * ( digit + R "af" + R "AF" ) + + P "o" * R "03" * R "07" * R "07" ) + ) + * "'" ) % \end{macrocode} % % @@ -6613,10 +6798,13 @@ local Char = % \paragraph{Beamer} % % \bigskip +% The argument of |Compute_braces| must be a pattern \emph{which does no +% catching} corresponding to the strings of the language. +% % \begin{macrocode} -braces = Compute_braces ( "\"" * ( 1 - S "\"" ) ^ 0 * "\"" ) +local braces = Compute_braces ( "\"" * ( 1 - S "\"" ) ^ 0 * "\"" ) if piton.beamer then - Beamer = Compute_Beamer ( 'ocaml' , "\"" * ( 1 - S "\"" ) ^ 0 * "\"" ) + Beamer = Compute_Beamer ( 'ocaml' , braces ) -- modified 2024/07/24 end % \end{macrocode} % @@ -6727,29 +6915,31 @@ local Comment = % \paragraph{The DefFunction} % % \begin{macrocode} -local balanced_parens = - P { "E" , E = ( "(" * V "E" * ")" + 1 - S "()" ) ^ 0 } -% \end{macrocode} -% -% \begin{macrocode} local Argument = - K ( 'Identifier' , identifier ) - + Q "(" * SkipSpace - * K ( 'Identifier' , identifier ) * SkipSpace - * Q ":" * SkipSpace - * K ( 'Name.Type' , balanced_parens ) * SkipSpace - * Q ")" +% \end{macrocode} +% For the labels of the labeled arguments. Maybe you will, in the future, create +% a style for those elements. +% \begin{macrocode} + ( Q "~" * Identifier * Q ":" * SkipSpace ) ^ -1 + * + ( K ( 'Identifier.Internal' , identifier ) + + Q "(" * SkipSpace + * K ( 'Identifier.Internal' , identifier ) * SkipSpace + * Q ":" * SkipSpace + * K ( 'TypeExpression' , balanced_parens ) * SkipSpace + * Q ")" + ) % \end{macrocode} % % Despite its name, then \textsc{lpeg} |DefFunction| deals also with |let open| % which opens locally a module. % \begin{macrocode} local DefFunction = - K ( 'Keyword' , "let open" ) + K ( 'Keyword.Governing' , "let open" ) * Space * K ( 'Name.Module' , cap_identifier ) + - K ( 'Keyword' , P "let rec" + "let" + "and" ) + K ( 'Keyword.Governing' , P "let rec" + "let" + "and" ) * Space * K ( 'Name.Function.Internal' , identifier ) * Space @@ -6761,7 +6951,7 @@ local DefFunction = * ( SkipSpace * Q ":" - * K ( 'Name.Type' , ( 1 - P "=" ) ^ 0 ) + * K ( 'TypeExpression' , ( 1 - P "=" ) ^ 0 ) ) ^ -1 ) % \end{macrocode} @@ -6774,10 +6964,10 @@ local DefFunction = % definitions of \emph{types} of modules. % \begin{macrocode} local DefModule = - K ( 'Keyword' , "module" ) * Space + K ( 'Keyword.Governing' , "module" ) * Space * ( - K ( 'Keyword' , "type" ) * Space + K ( 'Keyword.Governing' , "type" ) * Space * K ( 'Name.Type' , cap_identifier ) + K ( 'Name.Module' , cap_identifier ) * SkipSpace @@ -6812,26 +7002,46 @@ local DefModule = ) ^ -1 ) + - K ( 'Keyword' , P "include" + "open" ) + K ( 'Keyword.Governing' , P "include" + "open" ) * Space * K ( 'Name.Module' , cap_identifier ) % \end{macrocode} +% % % \bigskip -% \paragraph{The parameters of the types} -% +% \paragraph{The DefType}\par +% % \begin{macrocode} -local TypeParameter = K ( 'TypeParameter' , "'" * alpha * # ( 1 - P "'" ) ) +local TypeParameter = + K ( 'TypeParameter' , "'" * alpha * ( # ( 1 - P "'" ) + -1 ) ) +% \end{macrocode} +% +% +% \bigskip +% The following LPEG is for the instructions of definitions of types (which +% begin with |type|). +% \begin{macrocode} +local DefType = + K ( 'Keyword.Governing' , "type" ) + * Space + * WithStyle + ( + 'TypeExpression' , + ( Q ( 1 - P ";;" - P "\r" ) + EOL_without_space_indentation ) ^ 0 + ) + * ( # governing_keyword + Q ";;" + -1 ) % \end{macrocode} % % \bigskip % \paragraph{The main LPEG for the language OCaml} % +% \begin{macrocode} +local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1 +% \end{macrocode} +% % First, the main loop : % \begin{macrocode} local Main = - space ^ 1 * -1 - + space ^ 0 * EOL - + Space + Space + Tab + Escape + EscapeMath + Beamer @@ -6841,15 +7051,22 @@ local Main = + Comment + Delim + Operator +% \end{macrocode} +% For the labels of the labeled arguments. Maybe you will, in the future, create +% a style for those elements. +% \begin{macrocode} + + Q ( "~" ) * Identifier * ( Q ":" ) ^ -1 + + Q ":" * # (1 - P":") * SkipSpace + * K ( 'TypeExpression' , balanced_parens ) * SkipSpace * Q ")" + Punct - + FromImport + Exception + DefFunction + DefModule + + DefType + Record - + Keyword * ( Space + Punct + Delim + EOL + -1 ) - + OperatorWord * ( Space + Punct + Delim + EOL + -1 ) - + Builtin * ( Space + Punct + Delim + EOL + -1 ) + + Keyword * EndKeyword + + OperatorWord * EndKeyword + + Builtin * EndKeyword + DotNotation + Constructor + Identifier @@ -6867,18 +7084,31 @@ LPEG1['ocaml'] = Main ^ 0 % \texttt{\textbackslash @@\_begin\_line:}}. % \begin{macrocode} LPEG2['ocaml'] = - Ct ( + Ct ( +% \end{macrocode} +% The following lines are in order to allow, in |\piton| (and not in |{Piton}|), +% judments of type (such as |f : my_type -> 'a list|) or single expressions of +% type such as |my_type -> 'a list| (in that case, the argument of |\piton| +% \emph{must} begin by a colon). +% \begin{macrocode} + ( P ":" + Identifier * SkipSpace * Q ":" ) + * SkipSpace + * K ( 'TypeExpression' , ( 1 - P "\r" ) ^ 0 ) + + +% \end{macrocode} +% Now, the main part. +% \begin{macrocode} ( space ^ 0 * "\r" ) ^ -1 * BeamerBeginEnvironments - * Lc '\\@@_begin_line:' + * Lc [[\@@_begin_line:]] * SpaceIndentation ^ 0 - * LPEG1['ocaml'] + * ( ( space * Lc [[\@@_trailing_space:]] ) ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0 * -1 - * Lc '\\@@_end_line:' + * Lc [[\@@_end_line:]] ) % \end{macrocode} % -% +% % \bigskip % \subsubsection{The language C} % @@ -6970,8 +7200,10 @@ String = % \paragraph{Beamer} % % \bigskip +% The argument of |Compute_braces| must be a pattern \emph{which does no +% catching} corresponding to the strings of the language. % \begin{macrocode} -braces = Compute_braces ( "\"" * ( 1 - S "\"" ) ^ 0 * "\"" ) +local braces = Compute_braces ( "\"" * ( 1 - S "\"" ) ^ 0 * "\"" ) if piton.beamer then Beamer = Compute_Beamer ( 'c' , braces ) end % \end{macrocode} % @@ -7015,12 +7247,14 @@ local LongComment = % \bigskip % \paragraph{The main LPEG for the language C} % +% \begin{macrocode} +local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1 +% \end{macrocode} +% % First, the main loop : % \begin{macrocode} local Main = - space ^ 1 * -1 - + space ^ 0 * EOL - + Space + Space + Tab + Escape + EscapeMath + CommentLaTeX @@ -7034,9 +7268,9 @@ local Main = + Punct + DefFunction + DefClass - + Type * ( Q "*" ^ -1 + Space + Punct + Delim + EOL + -1 ) - + Keyword * ( Space + Punct + Delim + EOL + -1 ) - + Builtin * ( Space + Punct + Delim + EOL + -1 ) + + Type * ( Q "*" ^ -1 + EndKeyword ) + + Keyword * EndKeyword + + Builtin * EndKeyword + Identifier + Number + Word @@ -7058,11 +7292,11 @@ LPEG2['c'] = Ct ( ( space ^ 0 * P "\r" ) ^ -1 * BeamerBeginEnvironments - * Lc '\\@@_begin_line:' + * Lc [[\@@_begin_line:]] * SpaceIndentation ^ 0 - * LPEG1['c'] + * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0 * -1 - * Lc '\\@@_end_line:' + * Lc [[\@@_end_line:]] ) % \end{macrocode} % @@ -7089,7 +7323,7 @@ end % \begin{macrocode} local identifier = letter * ( alphanum + "-" ) ^ 0 - + '"' * ( ( alphanum + space - '"' ) ^ 1 ) * '"' + + P '"' * ( ( 1 - P '"' ) ^ 1 ) * '"' local Operator = @@ -7164,8 +7398,11 @@ local String = K ( 'String.Long' , "'" * ( 1 - P "'" ) ^ 1 * "'" ) % \paragraph{Beamer} % % \bigskip +% The argument of |Compute_braces| must be a pattern \emph{which does no +% catching} corresponding to the strings of the language. +% % \begin{macrocode} -braces = Compute_braces ( String ) +local braces = Compute_braces ( "'" * ( 1 - P "'" ) ^ 1 * "'" ) if piton.beamer then Beamer = Compute_Beamer ( 'sql' , braces ) end % \end{macrocode} % @@ -7203,6 +7440,9 @@ local LongComment = % \bigskip % \paragraph{The main LPEG for the language SQL} % +% \begin{macrocode} +local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1 +% \end{macrocode} % % \begin{macrocode} local TableField = @@ -7245,13 +7485,15 @@ local WeCatchTableNames = * ( Space + EOL ) * OneTable % \end{macrocode} % +% \begin{macrocode} +local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1 +% \end{macrocode} +% % % First, the main loop : % \begin{macrocode} local Main = - space ^ 1 * -1 - + space ^ 0 * EOL - + Space + Space + Tab + Escape + EscapeMath + CommentLaTeX @@ -7284,11 +7526,11 @@ LPEG2['sql'] = Ct ( ( space ^ 0 * "\r" ) ^ -1 * BeamerBeginEnvironments - * Lc [[ \@@_begin_line: ]] + * Lc [[\@@_begin_line:]] * SpaceIndentation ^ 0 - * LPEG1['sql'] + * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0 * -1 - * Lc [[ \@@_end_line: ]] + * Lc [[\@@_end_line:]] ) % \end{macrocode} % @@ -7314,7 +7556,12 @@ local String = * Q "\"" ) -braces = Compute_braces ( String ) +% \end{macrocode} +% The argument of |Compute_braces| must be a pattern \emph{which does no +% catching} corresponding to the strings of the language. +% \begin{macrocode} +local braces = Compute_braces ( P "\"" * ( P "\\\"" + 1 - P "\"" ) ^ 1 * "\"" ) + if piton.beamer then Beamer = Compute_Beamer ( 'minimal' , braces ) end DetectedCommands = Compute_DetectedCommands ( 'minimal' , braces ) @@ -7323,14 +7570,12 @@ LPEG_cleaner['minimal'] = Compute_LPEG_cleaner ( 'minimal' , braces ) local identifier = letter * alphanum ^ 0 -local Identifier = K ( 'Identifier' , identifier ) +local Identifier = K ( 'Identifier.Internal' , identifier ) local Delim = Q ( S "{[()]}" ) local Main = - space ^ 1 * -1 - + space ^ 0 * EOL - + Space + Space + Tab + Escape + EscapeMath + CommentLaTeX @@ -7350,11 +7595,11 @@ LPEG2['minimal'] = Ct ( ( space ^ 0 * "\r" ) ^ -1 * BeamerBeginEnvironments - * Lc [[ \@@_begin_line: ]] + * Lc [[\@@_begin_line:]] * SpaceIndentation ^ 0 - * LPEG1['minimal'] + * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0 * -1 - * Lc [[ \@@_end_line: ]] + * Lc [[\@@_end_line:]] ) % \bigskip @@ -7373,7 +7618,7 @@ function piton.Parse ( language , code ) local t = LPEG2[language] : match ( code ) if t == nil then - sprintL3 [[ \@@_error_or_warning:n { syntax~error } ]] + sprintL3 [[ \@@_error_or_warning:n { SyntaxError } ]] return -- to exit in force the function end local left_stack = {} @@ -7394,14 +7639,14 @@ function piton.Parse ( language , code ) % % Here is an example of an item beginning with |"Open"|. % -% |{ "Open" , "\begin{uncover}<2>" , "\end{cover}" }| +% |{ "Open" , "\begin{uncover}<2>" , "\end{uncover}" }| % % In order to deal with the ends of lines, we have to close the environment -% (|{cover}| in this example) at the end of each line and reopen it at the +% (|{uncover}| in this example) at the end of each line and reopen it at the % beginning of the new line. That's why we use two Lua stacks, called % |left_stack| and |right_stack|. |left_stack| will be for the elements like % |\begin{uncover}<2>| and |right_stack| will be for the elements like -% |\end{cover}|. +% |\end{uncover}|. % \begin{macrocode} if one_item[1] == "Open" then tex.sprint( one_item[2] ) @@ -7606,20 +7851,43 @@ function piton.GobbleParse ( lang , n , code ) piton.last_code = gobble ( n , code ) piton.last_language = lang % \end{macrocode} +% We count the number of lines of the informatic code. The result will be stored +% by Lua in |\l_@@_nb_lines_int|. That information will be used to allow or +% disallow page breaks (when |splittable| is in force). +% \begin{macrocode} + piton.CountLines ( piton.last_code ) + sprintL3 [[ \bool_if:NT \g_@@_footnote_bool \savenotes ]] +% \end{macrocode} +% We begin a |\vtop| for an non-splittable block of lines. % \begin{macrocode} - sprintL3 [[ \bool_if:NT \g_@@_footnote_bool \savenotes \vtop \bgroup ]] + sprintL3 [[ \vtop \bgroup ]] piton.Parse ( lang , piton.last_code ) - sprintL3 - [[\vspace{2.5pt}\egroup\bool_if:NT\g_@@_footnote_bool\endsavenotes\par]] +% \end{macrocode} +% We close the latest opened |\vtop| with the following |\egroup|. Be careful: +% that |\vtop| is \emph{not} necessarily the |\vtop| opened two lines above +% because the commands |\@@_newline:| inserted by Lua may open and close +% |\vtop|s and start and finish paragraphs (when |splittable| is in force). +% \begin{macrocode} + sprintL3 [[ \vspace{2.5pt} \egroup ]] + sprintL3 [[ \bool_if:NT \g_@@_footnote_bool \endsavenotes ]] +% \end{macrocode} +% We finish the paragraph (each block of non-splittable lines of code is +% composed in a |\vtop| inserted in a paragraph). +% \begin{macrocode} + sprintL3 [[ \par ]] % \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 and piton.write ~= '' then - local file = assert ( io.open ( piton.write , piton.write_mode ) ) - file:write ( piton.get_last_code ( ) ) - file:close ( ) + local file = io.open ( piton.write , piton.write_mode ) + if file then + file:write ( piton.get_last_code ( ) ) + file:close ( ) + else + sprintL3 [[ \@@_error_or_warning:n { FileError } ]] + end end end % \end{macrocode} @@ -7628,7 +7896,9 @@ end % The following function will be used when the key |split-on-empty-lines| is in % force. With that key, the informatic code is split in chunks at the empty % lines (usually between the informatic functions defined in the informatic -% code). LaTeX will be able to change the page between the chunks. +% code). LaTeX will be able to change the page between the chunks. The second +% argument |n| corresponds to the value of the key |gobble| (number of spaces to +% gobble). % \begin{macrocode} function piton.GobbleSplitParse ( lang , n , code ) P { "E" , @@ -7637,7 +7907,7 @@ function piton.GobbleSplitParse ( lang , n , code ) / ( function ( x ) sprintL3 [[ \@@_incr_visual_line: ]] end ) ) ^ 1 / ( function ( x ) - sprintL3 [[ \l_@@_split_separation_tl \int_gzero:N \g_@@_line_int ]] + sprintL3 ( piton.string_between_chunks ) end ) ) ^ 0 * V "F" , % \end{macrocode} @@ -7645,7 +7915,7 @@ function piton.GobbleSplitParse ( lang , n , code ) % \begin{macrocode} F = C ( V "G" ^ 0 ) % \end{macrocode} -% The second argument of |.pitonGobbleParse| is the argument |gobble|: we put +% The second argument of |piton.GobbleSplitParse| is the argument |gobble|: we put % that argument to~$0$ because we will have gobbled previously the whole argument % |code| (see below). % \begin{macrocode} @@ -7654,10 +7924,24 @@ function piton.GobbleSplitParse ( lang , n , code ) % The non-terminal |G| corresponds to a non-empty line of code. % \begin{macrocode} G = ( 1 - P "\r" ) ^ 0 * "\r" - ( P " " ^ 0 * "\r" ) + + ( ( 1 - P "\r" ) ^ 1 * -1 - ( P " " ^ 0 * -1 ) ) } : match ( gobble ( n , code ) ) end % \end{macrocode} % +% \bigskip +% The following Lua string will be inserted between the chunks of code created +% when the key |split-on-empty-lines| is in force. It's used only once: you have +% given a name to that Lua string only for legibily. The token list +% |\l_@@_split_separation_tl| corresponds to the key |split-separation|. That +% token list must contain elements inserted in \emph{vertical mode} of TeX. +% \begin{macrocode} +piton.string_between_chunks = + [[ \par \l_@@_split_separation_tl \mode_leave_vertical: ]] + .. [[ \int_gzero:N \g_@@_line_int ]] +% \end{macrocode} +% The counter |\g_@@_line_int| will be used to control the points where the code +% may be broken by a change of page (see the key |splittable|). % % \bigskip % The following public Lua function is provided to the developer. @@ -7672,14 +7956,23 @@ end % \subsubsection{To count the number of lines} % % \medskip +% The following function is only used once (in |piton.GobbleParse|). We have +% written an autonomous function only for legibility. The number of lines of the +% code will be stored in |\l_@@_nb_lines_int| and will be used to allow or +% disallow line breaks (when |splittable| is in force). % \begin{macrocode} function piton.CountLines ( code ) local count = 0 for i in code : gmatch ( "\r" ) do count = count + 1 end - sprintL3 ( [[ \int_set:Nn \l_@@_nb_lines_int { ]] .. count .. '}' ) + sprintL3 ( string.format ( [[ \int_set:Nn \l_@@_nb_lines_int { % i } ]] , count ) ) end % \end{macrocode} % +% \bigskip +% The following function is only used once (in |piton.GobbleParse|). We have +% written an autonomous function only for legibility. The number of lines of the +% code will be stored in |\l_@@_nb_non_empty_lines_int|. It will be used to +% compute the largest number of lines to write (when |line-numbers| is in force). % \begin{macrocode} function piton.CountNonEmptyLines ( code ) local count = 0 @@ -7690,7 +7983,8 @@ function piton.CountNonEmptyLines ( code ) * -1 ) / table.getn ) : match ( code ) - sprintL3 ( [[ \int_set:Nn \l_@@_nb_non_empty_lines_int { ]] .. count .. '}' ) + sprintL3 + ( string.format ( [[ \int_set:Nn \l_@@_nb_non_empty_lines_int { % i } ]] , count ) ) end % \end{macrocode} % @@ -7699,7 +7993,8 @@ end function piton.CountLinesFile ( name ) local count = 0 for line in io.lines ( name ) do count = count + 1 end - sprintL3 ( [[ \int_set:Nn \l_@@_nb_lines_int { ]] .. count .. '}' ) + sprintL3 + ( string.format ( [[ \int_set:Nn \l_@@_nb_lines_int { %i } ]], count)) end % \end{macrocode} % @@ -7713,7 +8008,8 @@ function piton.CountNonEmptyLinesFile ( name ) count = count + 1 end end - sprintL3 ( [[ \int_set:Nn \l_@@_nb_non_empty_lines_int { ]] .. count .. '}' ) + sprintL3 + ( string.format ( [[ \int_set:Nn \l_@@_nb_non_empty_lines_int { % i } ]] , count ) ) end % \end{macrocode} % @@ -7813,23 +8109,11 @@ function piton.new_language ( lang , definition ) % |tag| (mainly for the language \textsc{html}) for the character |/| in the % closing tags |</....>|). % \begin{macrocode} - other = other + P "c" + other = other + P ( c ) end end % \end{macrocode} % -% \bigskip -% Of course, the \textsc{lpeg} |strict_braces| is for balanced braces (without the -% question of strings of an informatic language). In fact, it \emph{won't} be -% used for an informatic 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 @@ -7945,7 +8229,7 @@ function piton.new_language ( lang , definition ) % \begin{macrocode} local alphanum = letter + digit local identifier = letter * alphanum ^ 0 - local Identifier = K ( 'Identifier' , identifier ) + local Identifier = K ( 'Identifier.Internal' , identifier ) % \end{macrocode} % % @@ -8046,6 +8330,7 @@ function piton.new_language ( lang , definition ) % the strings. % \begin{macrocode} local long_string = P ( false ) + local Long_string = P ( false ) local LongString = P (false ) local central_pattern = P ( false ) for _ , x in ipairs ( def_table ) do @@ -8072,7 +8357,15 @@ function piton.new_language ( lang , definition ) else prefix = P ( true ) end % \end{macrocode} -% We can write the pattern which matches the string. +% First, a pattern \emph{without captures} (needed to compute |braces|). +% \begin{macrocode} + long_string = long_string + + prefix + * arg3 + * ( space + central_pattern ) ^ 0 + * arg4 +% \end{macrocode} +% Now a pattern \emph{with captures}. % \begin{macrocode} local pattern = prefix @@ -8080,18 +8373,20 @@ function piton.new_language ( lang , definition ) * ( VisualSpace + Q ( central_pattern ^ 1 ) + EOL ) ^ 0 * Q ( arg4 ) % \end{macrocode} -% First, we create |long_string| because we need that \textsc{lpeg} in the -% nested comments. +% We will need |Long_string| in the nested comments. % \begin{macrocode} - long_string = long_string + pattern + Long_string = Long_string + pattern LongString = LongString + Ct ( Cc "Open" * Cc ( "{" .. arg2 .. "{" ) * Cc "}}" ) * pattern * Ct ( Cc "Close" ) end end - - local braces = Compute_braces ( String ) +% \end{macrocode} +% The argument of |Compute_braces| must be a pattern \emph{which does no +% catching} corresponding to the strings of the language. +% \begin{macrocode} + local braces = Compute_braces ( long_string ) if piton.beamer then Beamer = Compute_Beamer ( lang , braces ) end DetectedCommands = Compute_DetectedCommands ( lang , braces ) @@ -8208,12 +8503,7 @@ function piton.new_language ( lang , definition ) % % \begin{macrocode} local Main = - space ^ 1 * -1 -% \end{macrocode} -% The spaces at the end of the lines are discarded. -% \begin{macrocode} - + space ^ 0 * EOL - + Space + Space + Tab + Escape + EscapeMath + CommentLaTeX @@ -8229,7 +8519,7 @@ function piton.new_language ( lang , definition ) + PrefixedKeyword + Keyword * ( -1 + # ( 1 - alphanum ) ) + Punct - + K ( 'Identifier' , letter * alphanum ^ 0 ) + + K ( 'Identifier.Internal' , letter * alphanum ^ 0 ) + Number + Word % \end{macrocode} @@ -8249,7 +8539,7 @@ function piton.new_language ( lang , definition ) * BeamerBeginEnvironments * Lc [[\@@_begin_line:]] * SpaceIndentation ^ 0 - * LPEG1[lang] + * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0 * -1 * Lc [[\@@_end_line:]] ) @@ -8279,7 +8569,7 @@ function piton.new_language ( lang , definition ) + PrefixedKeyword + Keyword * ( -1 + # ( 1 - alphanum ) ) + Punct - + K ( 'Identifier' , letter * alphanum ^ 0 ) + + K ( 'Identifier.Internal' , letter * alphanum ^ 0 ) + Number + Word LPEG0[lang] = MainWithoutTag ^ 0 @@ -8296,7 +8586,7 @@ function piton.new_language ( lang , definition ) Ct ( ( space ^ 0 * P "\r" ) ^ -1 * BeamerBeginEnvironments - * Lc [[\@@_begin_line:]] + * Lc [[ \@@_begin_line: ]] * SpaceIndentation ^ 0 * LPEG1[lang] * -1 @@ -8327,6 +8617,12 @@ end % % \verb|https://github.com/fpantigny/piton| % +% \subsection*{Changes between versions 3.0 and 3.1} +% +% Keys |line-numbers/format|, |detected-beamer-commands| and +% |detected-beamer-environments|. +% +% % \subsection*{Changes between versions 2.8 and 3.0} % % New command |\NewPitonLanguage|. Thanks to that command, it's now possible to @@ -8396,61 +8692,6 @@ end % The key |escape-inside| is deprecated: use |begin-escape| and |end-escape|. % % -% \subsection*{Changes between versions 1.6 and 2.0} -% -% 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} -% -% New key |width| (for the total width of the listing). -% -% New style |UserFunction| to format the names of the Python functions -% previously defined by the user. Command |\PitonClearUserFunctions| to clear -% the list of such functions names. -% -% \subsection*{Changes between versions 1.4 and 1.5} -% -% New key |numbers-sep|. -% -% -% \subsection*{Changes between versions 1.3 and 1.4} -% -% New key |identifiers| in |\PitonOptions|. -% -% New command |\PitonStyle|. -% -% |background-color| now accepts as value a \emph{list} of colors. -% -% \subsection*{Changes between versions 1.2 and 1.3} -% -% When the class Beamer is used, the environment |{Piton}| and the command -% |\PitonInputFile| are ``overlay-aware'' (that is to say, they accept a -% specification of overlays between angular brackets). -% -% New key |prompt-background-color| -% -% It's now possible to use the command |\label| to reference a line of code in -% an environment |{Piton}|. -% -% A new command |\|␣ is available in the argument of the command |\piton{...}| to -% insert a space (otherwise, several spaces are replaced by a single space). -% -% \subsection*{Changes between versions 1.1 and 1.2} -% -% New keys |break-lines-in-piton| and |break-lines-in-Piton|. -% -% New key |show-spaces-in-string| and modification of the key |show-spaces|. -% -% When the class \cls{beamer} is used, the environments |{uncoverenv}|, -% |{onlyenv}|, |{visibleenv}| and |{invisibleenv}| -% -% -% \subsection*{Changes between versions 1.0 and 1.1} -% -% The extension \pkg{piton} detects the class \cls{beamer} and activates the -% commands |\action|, |\alert|, |\invisible|, |\only|, |\uncover| and |\visible| -% in the environments |{Piton}| when the class \cls{beamer} is used. % % \tableofcontents % |