diff options
author | Karl Berry <karl@freefriends.org> | 2024-02-27 20:48:03 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2024-02-27 20:48:03 +0000 |
commit | d17bed7049c85db6da51c9e2e72ff6e468e4cbc6 (patch) | |
tree | 9b723d3c7e32b05a3e2d3c2c65a9f493556433c9 /Master/texmf-dist/source | |
parent | 6797aad4f67e4add52f59847446bb8eb8e1266c6 (diff) |
piton (27feb24)
git-svn-id: svn://tug.org/texlive/trunk@70204 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source')
-rw-r--r-- | Master/texmf-dist/source/lualatex/piton/piton.dtx | 520 |
1 files changed, 301 insertions, 219 deletions
diff --git a/Master/texmf-dist/source/lualatex/piton/piton.dtx b/Master/texmf-dist/source/lualatex/piton/piton.dtx index 17333c50dcd..b7326c2d604 100644 --- a/Master/texmf-dist/source/lualatex/piton/piton.dtx +++ b/Master/texmf-dist/source/lualatex/piton/piton.dtx @@ -72,12 +72,12 @@ % \iffalse %<*STY> % \fi -\def\PitonFileVersion{2.5} -\def\PitonFileDate{2024/02/20} +\def\PitonFileVersion{2.6} +\def\PitonFileDate{2024/02/27} % \iffalse %</STY> %<*LUA> --- Version 2.5 of 2024/02/20 +-- Version 2.6 of 2024/02/27 %</LUA> %\fi % @@ -166,7 +166,7 @@ % % In current version, the package \pkg{piton} supports four computer languages: % Python, OCaml, SQL and C (in fact \CC). It supports also a special language -% called ``|minimal|'': cf. \pageref{minimal}. +% called ``|minimal|'': cf. p.~\pageref{minimal}. % % \smallskip % By default, the language used is Python. @@ -177,8 +177,8 @@ % and its key |language|: |\PitonOptions{language = C}|. % % \smallskip -% \colorbox{yellow!50}{\textbf{New 2.4}}\enskip The name of the L3 variable -% corresponding to that key is |\l_piton_language_str|. +% For the developpers, let's say that the name of the current language is stored +% (in lower case) in the L3 public variable |\l_piton_language_str|. % % \smallskip % In what follows, we will speak of Python, but the features described also @@ -333,9 +333,9 @@ % \item \index{path} The key \Definition{path} specifies a path where the files % included by |\PitonInputFile| will be searched. % -% \item \index{gobble} The key \Definition{gobble} takes in as value a -% positive integer~$n$: the first $n$ characters are discarded (before the -% process of highlightning of the code) for each line of the environment +% \item \index{gobble}\label{gobble} The key \Definition{gobble} takes in as +% value a positive integer~$n$: the first $n$ characters are discarded (before +% the process of highlightning of the code) for each line of the environment % |{Piton}|. These characters are not necessarily spaces. % % \item \index{auto-gobble}\index{gobble!auto-gobble} When the key @@ -354,10 +354,12 @@ % gobble is set by the position of the commands |\begin{Piton}| and % |\end{Piton}| which delimit the current environment. % -% \item \index{write} \colorbox{yellow!50}{\bfseries New 2.3}\enskip The key -% \Definition{write} takes in as argument a name of file (with its extension) -% and write the content of the current environment in that file. At the first -% use of a file by \pkg{piton}, it is erased. +% \item \index{write} The key \Definition{write} takes in as argument a name of +% file (with its extension) and write the content\footnote{In fact, it's not +% exactly the body of the environment but the value of |piton.get_last_code()| +% which is the body without the overwritten LaTeX formatting instructions (cf. +% 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. % % \item \index{path-write}\colorbox{yellow!50}{\bfseries New 2.5}\enskip The key % \Definition{path-write} specifies a path where the files written by the key @@ -384,7 +386,8 @@ % \emph{absolute} (that is to say: they are the numbers of the lines in the % file). That key may be useful when |\PitonInputFile| is used to insert only a % part of the file (cf. part~\ref{part-of-a-file}, p.~\pageref{part-of-a-file}). -% The key |/absolute| is no-op in the environments |{Piton}|. +% The key |/absolute| is no-op in the environments |{Piton}| and those created +% by |\NewPitonEnvironment|. % \item The key \Definition{line-numbers/start} requires that the line numbering % begins to the value of the key. % \item With the key \Definition{line-numbers/resume}, the counter of lines is @@ -714,7 +717,10 @@ % command takes in three mandatory arguments. % That command has the same syntax as the classical environment -% |\NewDocumentEnvironment|. +% |\NewDocumentEnvironment|.\footnote{However, the specifier of argument |b| +% (used to catch the body of the environment as a LaTeX argument) is +% not allowed.} +% % % \bigskip % With the following instruction, a new environment |{Python}| will be @@ -1207,10 +1213,8 @@ % \subsubsection{The key ``detected-commands''} % % \index{detected-commands (key)} +% \label{detected-commands} % -% \colorbox{yellow!50}{\bfseries New 2.4}\par\nobreak -% -% \smallskip % The key |detected-commands| of |\PitonOptions| allow to specify a % (comma-separated) list of names of LaTeX commands that will be detected % directly by \pkg{piton}. @@ -1253,9 +1257,7 @@ % % \subsubsection{The mechanism ``escape''} % -% \index{escape-math} -% \index{begin-escape-math} -% \index{end-escape-math} +% \label{escape} % % It's also possible to overwrite the Python listings to insert LaTeX code % almost everywhere (but between lexical units, of course). By default, @@ -1269,7 +1271,7 @@ % \medskip % We consider once again the previous example of a recursive programmation of % the factorial. We want to highlight in pink the instruction containing the -% recursive call. With the package \pkg{lua-el}, we can use the syntax +% recursive call. With the package \pkg{lua-ul}, we can use the syntax % |\highLight[LightPink]{...}|. Because of the optional argument between square % brackets, it's not possible to use the key |detected-commands| but it's % possible to acheive our goal with the more general mechanism ``escape''. @@ -1604,6 +1606,45 @@ % is similar to the key |auto-gobble| but acts on U+0009 instead of U+0020 % (spaces). % +% +% \bigskip +% \section{API for the developpers} +% +% \label{API} +% +% The L3 variable |\l_piton_language_str| contains the name of the current +% language of \pkg{piton} (in lower case). +% +% \bigskip +% \colorbox{yellow!50}{\textbf{New 2.6}}\par\nobreak +% +% The extension \pkg{piton} provides a Lua function |piton.get_last_code| +% without argument which returns the code in the latest environment of +% \pkg{piton}. +% \begin{itemize} +% \item The carriage returns (which are present in the initial environment) +% appears as characters |\r| (i.e. U+000D). +% +% \item The code returned by |piton.get_last_code()| takes into account the +% potential application of a key |gobble|, |auto-gobble| or |env-gobble| +% (cf.~p.~\pageref{gobble}). +% +% \item The extra formatting elements added in the code are deleted in the code +% returned by |piton.get_last_code()|. That concerns the LaTeX commands declared +% by the key |detected-commands| (cf. part~\ref{detected-commands}) and the +% elements inserted by the mechanism ``|escape|'' (cf. part~\ref{escape}). +% +% \item |piton.get_last_code| is a Lua function and not a Lua string: the +% treatments outlined above are executed when the function is called. Therefore, +% it might be judicious to store the value returned by |piton.get_last_code()| +% in a variable of Lua if it will be used serveral times. +% \end{itemize} +% +% \medskip +% For an example of use, see the part concerning |pyluatex|, part~\ref{pyluatex}, +% p.~\pageref{pyluatex}. +% +% % \section{Examples} % % \subsection{Line numbering} @@ -1931,68 +1972,36 @@ % \subsection{Use with pyluatex} % % \index{pyluatex@{\pkg{pyluatex}} (extension)} +% \label{pyluatex} % % The package \pkg{pyluatex} is an extension which allows the execution of some % Python code from |lualatex| (provided that Python is installed on the machine % and that the compilation is done with |lualatex| and |--shell-escape|). % % Here is, for example, an environment |{PitonExecute}| which formats a Python -% listing (with \pkg{piton}) but display also the output of the execution of the -% code with Python (for technical reasons, the |!| is mandatory in the signature -% of the environment). -% -% +% listing (with \pkg{piton}) but also displays the output of the execution of the +% code with Python. +% +% \medskip % \begin{Verbatim} -% \ExplSyntaxOn -% \NewDocumentEnvironment { ~emphase#PitonExecute@ } { ! O { } } % the ! is mandatory -% { -% \PyLTVerbatimEnv -% \begin{pythonq} -% } -% { -% \end{pythonq} -% \directlua -% { -% tex.print("\\PitonOptions{~#1}") -% tex.print("\\begin{Piton}") -% tex.print(pyluatex.get_last_code()) -% tex.print("\\end{Piton}") -% tex.print("") -% } -% \begin{center} -% \directlua{tex.print(pyluatex.get_last_output())} -% \end{center} -% } -% \ExplSyntaxOff +% \NewPitonEnvironment{~emphase#PitonExecute@}{!O{}} +% {\PitonOptions{~#1}} +% {\begin{center} +% \directlua{pyluatex.execute(piton.get_last_code(), false, true, false, true)}% +% \end{center} +% \ignorespacesafterend} % \end{Verbatim} % -% \ExplSyntaxOn -% \NewDocumentEnvironment { PitonExecute } { ! O { } } -% { -% \PyLTVerbatimEnv -% \begin{pythonq} -% } -% { -% \end{pythonq} -% \directlua -% { -% tex.print("\\PitonOptions{#1}") -% tex.print("\\begin{Piton}") -% tex.print(pyluatex.get_last_code()) -% tex.print("\\end{Piton}") -% tex.print("") -% } -% \begin{center} -% \directlua{tex.print(pyluatex.get_last_output())} -% \end{center} -% } -% \ExplSyntaxOff +% \medskip +% We have used the Lua function |piton.get_last_code| provided in the API of +% \pkg{piton} : cf.~part~\ref{API}, p.~\pageref{API}. % +% \medskip % This environment |{PitonExecute}| takes in as optional argument (between % square brackets) the options of the command |\PitonOptions|. % % -% \bigskip +% % \clearpage % \section{The styles for the different computer languages} % @@ -2247,9 +2256,6 @@ % % \subsection{The language ``minimal''} % -% \colorbox{yellow!50}{\bfseries New 2.4}\par\nobreak -% -% \bigskip % It's possible to switch to the language ``|minimal|'' with |\PitonOptions{language = minimal}|. % % \bigskip @@ -2434,7 +2440,7 @@ {piton} {\PitonFileDate} {\PitonFileVersion} - {Highlight Python codes with LPEG on LuaLaTeX} + {Highlight informatic listings with LPEG on LuaLaTeX} % \end{macrocode} % % \bigskip @@ -2472,6 +2478,7 @@ % \bigskip % \begin{macrocode} \RequirePackage { luatexbase } +\RequirePackage { luacode } % \end{macrocode} % % \bigskip @@ -2669,6 +2676,8 @@ { piton = piton~or { } piton.ListCommands = lpeg.P ( false ) + piton.last_code = '' + piton.last_language = '' } % \end{macrocode} % @@ -2684,6 +2693,13 @@ % \end{macrocode} % % \medskip +% Each time the command |\PitonInputFile| or an environment of \pkg{piton} is +% used, the code of that environment will be stored in the following global string. +% \begin{macrocode} +\tl_new:N \g_piton_last_code_tl +% \end{macrocode} +% +% \medskip % The following parameter corresponds to the key |path| (which is the path used % to include files by |\PitonInputFile|). % \begin{macrocode} @@ -3015,8 +3031,8 @@ % 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() } } +\cs_new_protected:Npn \@@_open_brace: { \lua_now:n { piton.open_brace() } } +\cs_new_protected:Npn \@@_close_brace: { \lua_now:n { piton.close_brace() } } % \end{macrocode} % % \bigskip @@ -3037,7 +3053,7 @@ { \tl_gset:Nn \g_@@_begin_line_hook_tl { - \tl_if_empty:NF \l_@@_prompt_bg_color_tl % added 2023-04-24 + \tl_if_empty:NF \l_@@_prompt_bg_color_tl { \clist_set:NV \l_@@_bg_color_clist \l_@@_prompt_bg_color_tl } } } @@ -3400,11 +3416,15 @@ % \begin{macrocode} \keys_define:nn { PitonOptions } { - detected-commands .code:n = \@@_detected_commands:n { #1 } , + detected-commands .code:n = + \lua_now:n { piton.addListCommands('#1') } , detected-commands .value_required:n = true , detected-commands .usage:n = preamble , % \end{macrocode} % First, we put keys that should be avalaible only in the preamble. +% +% Remark that the command |\lua_escape:n| is fully expandable. That's why we use +% |\lua_now:e|. % \begin{macrocode} begin-escape .code:n = \lua_now:e { piton.begin_escape = "\lua_escape:n{#1}" } , @@ -3977,7 +3997,7 @@ { \lua_now:e { piton.write = "\l_@@_write_str" } } { \lua_now:e - { piton.write = "\l_@@_path_write_str / \l_@@_write_str" } + { piton.write = "\l_@@_path_write_str / \l_@@_write_str" } } \str_if_empty:NF \l_@@_write_str { @@ -4243,11 +4263,11 @@ % \begin{macrocode} \NewDocumentCommand { \SetPitonStyle } { O { } m } { + \str_clear_new:N \l_@@_SetPitonStyle_option_str \str_set:Nx \l_@@_SetPitonStyle_option_str { \str_lowercase:n { #1 } } \str_if_eq:onT \l_@@_SetPitonStyle_option_str { current-language } { \str_set_eq:NN \l_@@_SetPitonStyle_option_str \l_piton_language_str } \keys_set:nn { piton / Styles } { #2 } - \str_clear:N \l_@@_SetPitonStyle_option_str } % \end{macrocode} % @@ -4259,8 +4279,8 @@ % % \medskip % \begin{macrocode} -\clist_new:N \g_@@_style_clist -\clist_set:Nn \g_@@_styles_clist +\clist_new:N \g_@@_styles_clist +\clist_gset:Nn \g_@@_styles_clist { Comment , Comment.LaTeX , @@ -4798,30 +4818,27 @@ % \bigskip % \subsubsection{Detected commands} % -% \begin{macrocode} -\cs_new_protected:Npn \@@_detected_commands:n #1 - { \lua_now:n { piton.addListCommands('#1') } } -% \end{macrocode} % % \begin{macrocode} \ExplSyntaxOff -\directlua - { +\begin{luacode*} lpeg.locale(lpeg) - local P , alpha , C , Cf, space - = lpeg.P , lpeg.alpha , lpeg.C , lpeg.Cf , lpeg.space - local S = lpeg.S - local One_P - = space ^ 0 - * C ( alpha ^ 1 ) / ( function (s) return P ( string.char(92) .. s ) end ) - * space ^ 0 + local P , alpha , C , space , S , V + = lpeg.P , lpeg.alpha , lpeg.C , lpeg.space , lpeg.S , lpeg.V + local function add(...) + local s = P ( false ) + for _ , x in ipairs({...}) do s = s + x end + return s + end + local my_lpeg = + P { "E" , + E = ( V "F" * ( P "," * V "F" ) ^ 0 ) / add , + F = space ^ 0 * ( alpha ^ 1 ) / "\\%0" * space ^ 0 + } function piton.addListCommands( key_value ) - piton.ListCommands = - piton.ListCommands + - Cf ( One_P * ( P "," * One_P ) ^ 0 , - ( function (s,t) return s + t end ) ) : match ( key_value ) + piton.ListCommands = piton.ListCommands + my_lpeg : match ( key_value ) end - } +\end{luacode*} %</STY> % \end{macrocode} % @@ -4863,7 +4880,7 @@ end % define first aliases for several functions of that library. % \begin{macrocode} local P, S, V, C, Ct, Cc = lpeg.P, lpeg.S, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Cc -local Cf, Cs , Cg , Cmt , Cb = lpeg.Cf, lpeg.Cs, lpeg.Cg , lpeg.Cmt , lpeg.Cb +local Cs , Cg , Cmt , Cb = lpeg.Cs, lpeg.Cg , lpeg.Cmt , lpeg.Cb local R = lpeg.R % \end{macrocode} % @@ -4945,18 +4962,23 @@ end % \bigskip % The following \textsc{lpeg} catches the Python chunks which are in LaTeX % escapes (and that chunks will be considered as normal LaTeX constructions). -% Since the elements that will be catched must be sent to LaTeX with standard -% LaTeX catcodes, we put the capture (done by the function |C|) in a table (by -% using |Ct|, which is an alias for |lpeg.Ct|) without number of catcode table -% at the first component of the table. % \begin{macrocode} Escape = P ( false ) +EscapeClean = P ( false ) if piton.begin_escape ~= nil then Escape = P(piton.begin_escape) * L ( ( 1 - P(piton.end_escape) ) ^ 1 ) * P(piton.end_escape) +% \end{macrocode} +% The LPEG |EscapeClean| will be used in the LPEG Clean (and that LPEG is used +% to ``clean'' the code by removing the formatting elements). +% \begin{macrocode} + EscapeClean = + P(piton.begin_escape) + * ( 1 - P(piton.end_escape) ) ^ 1 + * P(piton.end_escape) end % \end{macrocode} % @@ -5125,13 +5147,13 @@ then Ct ( Cc "Open" * C ( P ( "\\begin{" .. name .. "}" ) - * ( P "<" * (1 - P ">") ^ 0 * P ">" ) ^ -1 + * ( P "<" * ( 1 - P ">") ^ 0 * P ">" ) ^ -1 ) * Cc ( "\\end{" .. name .. "}" ) ) * ( - C ( ( 1 - P ( "\\end{" .. name .. "}" ) ) ^ 0 ) - / ( function (s) return lpeg : match(s) end ) + ( ( 1 - P ( "\\end{" .. name .. "}" ) ) ^ 0 ) + / ( function (s) return lpeg : match(s) end ) ) * P ( "\\end{" .. name .. "}" ) * Ct ( Cc "Close" ) end @@ -5143,6 +5165,7 @@ end % \bigskip % \begin{macrocode} local languages = { } +local CleanLPEGs = { } % \end{macrocode} % % \bigskip @@ -5375,7 +5398,7 @@ local DoubleShortString = Q ( P "f\"" + P "F\"" ) * ( K ( 'String.Interpol' , P "{" ) - * Q ( ( 1 - S "}\":" ) ^ 0 , 'Interpol.Inside' ) + * K ( 'Interpol.Inside' , ( 1 - S "}\":" ) ^ 0 ) * ( K ( 'String.Interpol' , P ":" ) * Q ( (1 - S "}:\"") ^ 0 ) ) ^ -1 * K ( 'String.Interpol' , P "}" ) + @@ -5436,7 +5459,7 @@ then ) * Cc "}" ) - * ( C ( balanced_braces ) / (function (s) return MainLoopPython:match(s) end ) ) + * ( balanced_braces / (function (s) return MainLoopPython:match(s) end ) ) * P "}" * Ct ( Cc "Close" ) + OneBeamerEnvironment ( "uncoverenv" , MainLoopPython ) + OneBeamerEnvironment ( "onlyenv" , MainLoopPython ) @@ -5481,16 +5504,28 @@ end % \begin{macrocode} DetectedCommands = Ct ( Cc "Open" - * C ( - piton.ListCommands - * ( P "<" * (1 - P ">") ^ 0 * P ">" ) ^ -1 - * P "{" - ) + * C ( piton.ListCommands * P "{" ) * Cc "}" ) - * ( C ( balanced_braces ) / (function (s) return MainLoopPython:match(s) end ) ) + * ( balanced_braces / (function (s) return MainLoopPython:match(s) end ) ) * P "}" * Ct ( Cc "Close" ) % \end{macrocode} +% +% \bigskip +% +% \paragraph{The LPEG Clean} +% +% \begin{macrocode} +CleanLPEGs['python'] + = Ct ( ( piton.ListCommands * P "{" + * ( balanced_braces + / ( function (s) return CleanLPEGs['python']:match(s) end ) ) + * P "}" + + EscapeClean + + C ( P ( 1 ) ) + ) ^ 0 ) / table.concat +% \end{macrocode} +% % % \bigskip % \paragraph{EOL} @@ -5624,7 +5659,7 @@ local LongString = SingleLongString + DoubleLongString % of a function definition (which begins with |def|). % \begin{macrocode} local StringDoc = - K ( 'String.Doc' , P "\"\"\"" ) + K ( 'String.Doc' , P "r" ^ -1 * P "\"\"\"" ) * ( K ( 'String.Doc' , (1 - P "\"\"\"" - P "\r" ) ^ 0 ) * EOL * Tab ^ 0 ) ^ 0 @@ -5702,7 +5737,7 @@ local expression = % \medskip % \begin{macrocode} local Param = - SkipSpace * Identifier * SkipSpace + SkipSpace * ( Identifier + Q "*args" + Q "**kwargs" ) * SkipSpace * ( K ( 'InitialValues' , P "=" * expression ) + Q ( P ":" ) * SkipSpace * K ( 'Name.Type' , letter ^ 1 ) @@ -5868,8 +5903,8 @@ local expression_for_fields = E = ( P "{" * V "F" * P "}" + P "(" * V "F" * P ")" + P "[" * V "F" * P "]" - + P "\"" * (P "\\\"" + 1 - S "\"\r" )^0 * P "\"" - + P "'" * ( P "\\'" + 1 - S "'\r" )^0 * P "'" + + P "\"" * (P "\\\"" + 1 - S "\"\r" ) ^ 0 * P "\"" + + P "'" * ( P "\\'" + 1 - S "'\r" ) ^ 0 * P "'" + ( 1 - S "{}()[]\r;" ) ) ^ 0 , F = ( P "{" * V "F" * P "}" + P "(" * V "F" * P ")" @@ -5889,7 +5924,7 @@ local OneFieldDefinition = local OneField = K ( 'Name.Field' , identifier ) * SkipSpace * Q "=" * SkipSpace - * ( C ( expression_for_fields ) / ( function (s) return LoopOCaml:match(s) end ) ) + * ( expression_for_fields / ( function (s) return LoopOCaml:match(s) end ) ) * SkipSpace local Record = @@ -5940,7 +5975,7 @@ local Keyword = K ( 'Keyword' , P "assert" + P "and" + P "as" + P "begin" + P "class" + P "constraint" + P "done" + P "downto" + P "do" + P "else" + P "end" + P "exception" + P "external" - + P "for" + P "function" + P "functor" + P "fun" + P "if" + + P "for" + P "function" + P "functor" + P "fun" + P "if" + P "include" + P "inherit" + P "initializer" + P "in" + P "lazy" + P "let" + P "match" + P "method" + P "module" + P "mutable" + P "new" + P "object" + P "of" + P "open" + P "private" + P "raise" + P "rec" + P "sig" @@ -6009,7 +6044,7 @@ then ) * Cc "}" ) - * ( C ( balanced_braces ) / (function (s) return MainLoopOCaml:match(s) end ) ) + * ( balanced_braces / (function (s) return MainLoopOCaml:match(s) end ) ) * P "}" * Ct ( Cc "Close" ) + OneBeamerEnvironment ( "uncoverenv" , MainLoopOCaml ) + OneBeamerEnvironment ( "onlyenv" , MainLoopOCaml ) @@ -6051,16 +6086,25 @@ end % \begin{macrocode} DetectedCommands = Ct ( Cc "Open" - * C ( - piton.ListCommands - * ( P "<" * (1 - P ">") ^ 0 * P ">" ) ^ -1 - * P "{" - ) - * Cc "}" + * C ( piton.ListCommands * P "{" ) * Cc "}" ) - * ( C ( balanced_braces ) / (function (s) return MainLoopOCaml:match(s) end ) ) + * ( balanced_braces / (function (s) return MainLoopOCaml:match(s) end ) ) * P "}" * Ct ( Cc "Close" ) % \end{macrocode} +% +% \bigskip +% \begin{macrocode} +CleanLPEGs['ocaml'] + = Ct ( ( piton.ListCommands * P "{" + * ( balanced_braces + / ( function (s) return CleanLPEGs['ocaml']:match(s) end ) ) + * P "}" + + EscapeClean + + C ( P ( 1 ) ) + ) ^ 0 ) / table.concat +% \end{macrocode} +% + % % % \bigskip @@ -6128,7 +6172,7 @@ local open = "{" * Cg(ext, 'init') * "|" local close = "|" * C(ext) * "}" local closeeq = Cmt ( close * Cb('init'), - function (s, i, a, b) return a==b end ) + function (s, i, a, b) return a == b end ) % \end{macrocode} % % \medskip @@ -6490,7 +6534,7 @@ then ) * Cc "}" ) - * ( C ( balanced_braces ) / (function (s) return MainLoopC:match(s) end ) ) + * ( balanced_braces / (function (s) return MainLoopC:match(s) end ) ) * P "}" * Ct ( Cc "Close" ) + OneBeamerEnvironment ( "uncoverenv" , MainLoopC ) + OneBeamerEnvironment ( "onlyenv" , MainLoopC ) @@ -6532,16 +6576,23 @@ end % \begin{macrocode} DetectedCommands = Ct ( Cc "Open" - * C ( - piton.ListCommands - * ( P "<" * (1 - P ">") ^ 0 * P ">" ) ^ -1 - * P "{" - ) - * Cc "}" + * C ( piton.ListCommands * P "{" ) * Cc "}" ) - * ( C ( balanced_braces ) / (function (s) return MainLoopC:match(s) end ) ) + * ( balanced_braces / (function (s) return MainLoopC:match(s) end ) ) * P "}" * Ct ( Cc "Close" ) % \end{macrocode} +% +% \bigskip +% \begin{macrocode} +CleanLPEGs['c'] + = Ct ( ( piton.ListCommands * P "{" + * ( balanced_braces + / ( function (s) return CleanLPEGs['c']:match(s) end ) ) + * P "}" + + EscapeClean + + C ( P ( 1 ) ) + ) ^ 0 ) / table.concat +% \end{macrocode} % % \bigskip % \paragraph{EOL} @@ -6813,7 +6864,7 @@ then ) * Cc "}" ) - * ( C ( balanced_braces ) / (function (s) return MainLoopSQL:match(s) end ) ) + * ( balanced_braces / (function (s) return MainLoopSQL:match(s) end ) ) * P "}" * Ct ( Cc "Close" ) + OneBeamerEnvironment ( "uncoverenv" , MainLoopSQL ) + OneBeamerEnvironment ( "onlyenv" , MainLoopSQL ) @@ -6855,18 +6906,25 @@ end % \begin{macrocode} DetectedCommands = Ct ( Cc "Open" - * C ( - piton.ListCommands - * ( P "<" * (1 - P ">") ^ 0 * P ">" ) ^ -1 - * P "{" - ) - * Cc "}" + * C ( piton.ListCommands * P "{" ) * Cc "}" ) - * ( C ( balanced_braces ) / (function (s) return MainLoopSQL:match(s) end ) ) + * ( balanced_braces / (function (s) return MainLoopSQL:match(s) end ) ) * P "}" * Ct ( Cc "Close" ) % \end{macrocode} % % \bigskip +% \begin{macrocode} +CleanLPEGs['sql'] + = Ct ( ( piton.ListCommands * P "{" + * ( balanced_braces + / ( function (s) return CleanLPEGs['sql']:match(s) end ) ) + * P "}" + + EscapeClean + + C ( P ( 1 ) ) + ) ^ 0 ) / table.concat +% \end{macrocode} +% +% \bigskip % \paragraph{EOL} % % \bigskip @@ -7106,7 +7164,7 @@ then ) * Cc "}" ) - * ( C ( balanced_braces ) / (function (s) return MainLoopMinimal:match(s) end ) ) + * ( balanced_braces / (function (s) return MainLoopMinimal:match(s) end ) ) * P "}" * Ct ( Cc "Close" ) + OneBeamerEnvironment ( "uncoverenv" , MainLoopMinimal ) + OneBeamerEnvironment ( "onlyenv" , MainLoopMinimal ) @@ -7140,16 +7198,23 @@ end DetectedCommands = Ct ( Cc "Open" - * C ( - piton.ListCommands - * ( P "<" * (1 - P ">") ^ 0 * P ">" ) ^ -1 - * P "{" - ) - * Cc "}" + * C ( piton.ListCommands * P "{" ) * Cc "}" ) - * ( C ( balanced_braces ) / (function (s) return MainLoopMinimal:match(s) end ) ) + * ( balanced_braces / (function (s) return MainLoopMinimal:match(s) end ) ) * P "}" * Ct ( Cc "Close" ) + +CleanLPEGs['minimal'] + = Ct ( ( piton.ListCommands * P "{" + * ( balanced_braces + / ( function (s) return CleanLPEGs['minimal']:match(s) end ) ) + * P "}" + + EscapeClean + + C ( P ( 1 ) ) + ) ^ 0 ) / table.concat + + + local EOL = P "\r" * @@ -7222,7 +7287,7 @@ languages['minimal'] = languageMinimal % \bigskip % \subsubsection{The function Parse} % -% +% \medskip % The function |Parse| is the main function of the package \pkg{piton}. It % parses its argument and sends back to LaTeX the code with interlaced % formatting LaTeX instructions. In fact, everything is done by the @@ -7360,21 +7425,16 @@ end % value of~$n$. % \begin{macrocode} local function gobble(n,code) - function concat(acc,new_value) - return acc .. new_value - end if n==0 then return code else - return Cf ( - Cc ( "" ) * - ( 1 - P "\r" ) ^ (-n) * C ( ( 1 - P "\r" ) ^ 0 ) - * ( C ( P "\r" ) - * ( 1 - P "\r" ) ^ (-n) - * C ( ( 1 - P "\r" ) ^ 0 ) - ) ^ 0 , - concat - ) : match ( code ) + return ( Ct ( + ( 1 - P "\r" ) ^ (-n) * C ( ( 1 - P "\r" ) ^ 0 ) + * ( C ( P "\r" ) + * ( 1 - P "\r" ) ^ (-n) + * C ( ( 1 - P "\r" ) ^ 0 ) + ) ^ 0 + ) / table.concat ) : match ( code ) end end % \end{macrocode} @@ -7382,59 +7442,55 @@ end % % % \bigskip -% The following function |add| will be used in the following \textsc{lpeg} -% |AutoGobbleLPEG|, |TabsAutoGobbleLPEG| and |EnvGobbleLPEG|. +% The following function |sum| will be used in the following \textsc{lpeg} +% |AutoGobbleLPEG|, |TabsAutoGobbleLPEG| and |EnvGobbleLPEG|. It computes the +% sum of all its arguments. % \begin{macrocode} -local function add(acc,new_value) - return acc + new_value -end +local function count_captures(...) + local acc = 0 + for _ in ipairs({...}) do + acc = acc + 1 + end + return acc +end % \end{macrocode} % % \bigskip % The following \textsc{lpeg} returns as capture the minimal number of spaces at -% the beginning of the lines of code. The main work is done by two \emph{fold -% captures} (|lpeg.Cf|), one using |add| and the other (encompassing the -% previous one) using |math.min| as folding operator. +% the beginning of the lines of code. +% begin{macrocode} % \begin{macrocode} local AutoGobbleLPEG = - ( space ^ 0 * P "\r" ) ^ -1 - * Cf ( - ( + ( + ( % \end{macrocode} -% We don't take into account the empty lines (with only spaces). +% We don't take into account the empty lines (those containing only spaces). % \begin{macrocode} - ( P " " ) ^ 0 * P "\r" - + - Cf ( Cc(0) * ( P " " * Cc(1) ) ^ 0 , add ) - * ( 1 - P " " ) * ( 1 - P "\r" ) ^ 0 * P "\r" - ) ^ 0 + P " " ^ 0 * P "\r" + + + C ( P " " ) ^ 0 / count_captures * ( 1 - P " " ) * ( 1 - P "\r" ) ^ 0 * P "\r" + ) ^ 0 % \end{macrocode} % Now for the last line of the Python code... % \begin{macrocode} - * - ( Cf ( Cc(0) * ( P " " * Cc(1) ) ^ 0 , add ) - * ( 1 - P " " ) * ( 1 - P "\r" ) ^ 0 ) ^ -1 , - math.min - ) + * + ( C ( P " " ) ^ 0 / count_captures * ( 1 - P " " ) * ( 1 - P "\r" ) ^ 0 ) ^ -1 + ) / math.min % \end{macrocode} % % \bigskip % The following \textsc{lpeg} is similar but works with the indentations. % \begin{macrocode} local TabsAutoGobbleLPEG = - ( space ^ 0 * P "\r" ) ^ -1 - * Cf ( - ( - ( P "\t" ) ^ 0 * P "\r" - + - Cf ( Cc(0) * ( P "\t" * Cc(1) ) ^ 0 , add ) - * ( 1 - P "\t" ) * ( 1 - P "\r" ) ^ 0 * P "\r" - ) ^ 0 - * - ( Cf ( Cc(0) * ( P "\t" * Cc(1) ) ^ 0 , add ) - * ( 1 - P "\t" ) * ( 1 - P "\r" ) ^ 0 ) ^ -1 , - math.min - ) + ( + ( + P "\t" ^ 0 * P "\r" + + + C ( P " " ) ^ 0 / count_captures * ( 1 - P "\t" ) * ( 1 - P "\r" ) ^ 0 * P "\r" + ) ^ 0 + * + ( C ( P " " ) ^ 0 / count_captures * ( 1 - P "\t" ) * ( 1 - P "\r" ) ^ 0 ) ^ -1 + ) / math.min % \end{macrocode} % % @@ -7443,17 +7499,28 @@ local TabsAutoGobbleLPEG = % The following \textsc{lpeg} returns as capture the number of spaces at the % last line, that is to say before the |\end{Piton}| (and usually it's also the % number of spaces before the corresponding |\begin{Piton}| because that's the -% traditionnal way to indent in LaTeX). The main work is done by a \emph{fold -% capture} (|lpeg.Cf|) using the function |add| as folding operator. +% traditionnal way to indent in LaTeX). % \begin{macrocode} local EnvGobbleLPEG = - ( ( 1 - P "\r" ) ^ 0 * P "\r" ) ^ 0 - * Cf ( Cc(0) * ( P " " * Cc(1) ) ^ 0 , add ) * -1 + ( ( 1 - P "\r" ) ^ 0 * P "\r" ) ^ 0 * ( C ( P " " ) ^ 0 / count_captures ) * -1 % \end{macrocode} % % \bigskip % \begin{macrocode} +local function remove_before_cr(input_string) + local match_result = P("\r") : match(input_string) + if match_result then + return string.sub(input_string, match_result ) + else + return input_string + end +end +% \end{macrocode} +% +% \bigskip +% \begin{macrocode} function piton.GobbleParse(language,n,code) + code = remove_before_cr(code) if n==-1 then n = AutoGobbleLPEG : match(code) else if n==-2 @@ -7463,16 +7530,31 @@ function piton.GobbleParse(language,n,code) end end end - piton.Parse(language,gobble(n,code)) + piton.last_code = gobble(n,code) + piton.Parse(language,piton.last_code) + piton.last_language = language +% \end{macrocode} +% Now, if the final user has used the key |write| to write the code of the +% environment on an external file. +% \begin{macrocode} if piton.write ~= '' then local file = assert(io.open(piton.write,piton.write_mode)) - file:write(code) + file:write(piton.get_last_code()) file:close() end end % \end{macrocode} % % \bigskip +% The following Lua function is provided to the developper. +% \begin{macrocode} +function piton.get_last_code ( ) + return CleanLPEGs[piton.last_language] : match(piton.last_code) +end +% \end{macrocode} +% +% +% \bigskip % \subsubsection{To count the number of lines} % % \medskip @@ -7490,14 +7572,12 @@ end function piton.CountNonEmptyLines(code) local count = 0 count = - ( Cf ( Cc(0) * - ( + ( ( ( ( ( P " " ) ^ 0 * P "\r" - + ( 1 - P "\r" ) ^ 0 * P "\r" * Cc(1) - ) ^ 0 - * (1 - P "\r" ) ^ 0 , - add - ) * -1 ) : match (code) + + ( 1 - P "\r" ) ^ 0 * C ( P "\r" ) + ) ^ 0 + * (1 - P "\r" ) ^ 0 + ) / count_captures ) * -1 ) : match (code) tex.sprint( luatexbase.catcodetables.expl , '\\int_set:Nn \\l_@@_nb_non_empty_lines_int {' .. count .. '}' ) @@ -7508,7 +7588,7 @@ end % \begin{macrocode} function piton.CountLinesFile(name) local count = 0 - io.open(name) -- added + io.open(name) for line in io.lines(name) do count = count + 1 end tex.sprint( luatexbase.catcodetables.expl , @@ -7590,6 +7670,10 @@ end % % \verb|https://github.com/fpantigny/piton| % +% \subsection*{Changes between versions 2.5 and 2.6} +% +% API: |piton.last_code| and |\g_piton_last_code_tl| are provided. +% % \subsection*{Changes between versions 2.4 and 2.5} % % New key |path-write| @@ -7610,8 +7694,6 @@ end % The variable |\l_piton_language_str| is now public. % % -% \subsection*{Changes between versions 2.2 and 2.3} -% % New key |write|. % % \subsection*{Changes between versions 2.1 and 2.2} |