From 30e902c79d7838a9ec84133dec2415eb48968762 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Wed, 6 Sep 2023 03:01:07 +0000 Subject: CTAN sync 202309060301 --- macros/luatex/latex/piton/piton.dtx | 728 ++++++++++++++++++++++++++++++++---- 1 file changed, 647 insertions(+), 81 deletions(-) (limited to 'macros/luatex/latex/piton/piton.dtx') diff --git a/macros/luatex/latex/piton/piton.dtx b/macros/luatex/latex/piton/piton.dtx index e6a78c709a..d6596263ef 100644 --- a/macros/luatex/latex/piton/piton.dtx +++ b/macros/luatex/latex/piton/piton.dtx @@ -43,12 +43,12 @@ version 2005/12/01 or later. % %<@@=piton> %<*STY> -\def\myfileversion{2.1} -\def\myfiledate{2023/08/26} +\def\myfileversion{2.2} +\def\myfiledate{2023/09/05} % %<*driver> -\def\myfileversion{2.1} -\def\myfiledate{2023/08/26} +\def\myfileversion{2.2} +\def\myfiledate{2023/09/05} \documentclass{l3doc} \usepackage{geometry} \geometry{left=2.8cm,right=2.8cm,top=2.5cm,bottom=2.5cm,papersize={21cm,29.7cm}} @@ -96,7 +96,7 @@ version 2005/12/01 or later. % % \begin{abstract} % The package \pkg{piton} provides tools to typeset computer listings in Python, -% OCaml and C with syntactic highlighting by using the Lua library LPEG. It +% OCaml, C and SQL with syntactic highlighting by using the Lua library LPEG. It % requires LuaLaTeX. % \end{abstract} % @@ -109,7 +109,7 @@ version 2005/12/01 or later. % pattern-matching library for Lua, written in C, based on \emph{parsing % expression grammars}: % \url{http://www.inf.puc-rio.br/~roberto/lpeg/}} -% for parsing Python OCaml or C listings and typesets them with syntactic +% for parsing Python, OCaml, C or SQL listings and typesets them with syntactic % highlighting. Since it uses Lua code, 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|. @@ -170,8 +170,8 @@ version 2005/12/01 or later. % % \subsection{Choice of the computer language} % -% In current version, the package \pkg{piton} supports three computer languages: -% Python, OCaml and C (in fact \CC). +% In current version, the package \pkg{piton} supports four computer languages: +% Python, OCaml, SQL and C (in fact \CC). % % \smallskip % By default, the language used is Python. @@ -210,6 +210,11 @@ version 2005/12/01 or later. % % It's possible to insert only a part of the file: cf. % part~\ref{part-of-a-file}, p.~\pageref{part-of-a-file}. +% +% \colorbox{yellow!50}{\textbf{New 2.2}}\enskip The key |path| of the command +% |\PitonOptions| specifies a path where the files included by |\PitonInputFile| +% will be searched. In fact, it's possible to specify a comma-separated list of +% paths. % \end{itemize} % % \subsection{The syntax of the command \textbackslash piton} @@ -317,8 +322,12 @@ version 2005/12/01 or later. % % \begin{itemize} % \item The key \Definition{language} speficies which computer language is -% considered (that key is case-insensitive). Three values are allowed : -% |Python|, |OCaml| and |C|. the initial value is |Python|. +% considered (that key is case-insensitive). Four values are allowed : +% |Python|, |OCaml|, |C| and |SQL|. The initial value is |Python|. +% +% \item The key |path| specifies a path where the files included by +% |\PitonInputFile| will be searched. In fact, it's possible to specify a +% comma-separated list of paths. % % \item The key \Definition{gobble} takes in as value a % positive integer~$n$: the first $n$ characters are discarded (before the @@ -508,6 +517,8 @@ version 2005/12/01 or later. % % \label{styles} % +% \subsubsection{Notion of style} +% % The package \pkg{piton} provides the command |\SetPitonStyle| to customize the % different styles used to format the syntactic elements of the Python listings. % The customizations done by that command are limited to the current TeX @@ -547,10 +558,10 @@ version 2005/12/01 or later. % \endgroup % % \bigskip -% The different styles are described in the table \ref{Semantic}. The initial -% settings done by \pkg{piton} in |piton.sty| are inspired by the style -% \pkg{manni} de Pygments.\footnote{See: -% \url{https://pygments.org/styles/}. Remark that, by default, Pygments provides for its style \pkg{manni} a colored background whose color is the HTML color \texttt{\#F0F3F3}. It's possible to have the same color in \texttt{\{Pion\}} with the instruction \texttt{\textbackslash PitonOptions\{background-color = [HTML]\{F0F3F3\}\}}.} +% The different styles, and their use by \pkg{piton} in the different languages +% which it supports (Python, OCaml, C and SQL), are described in the part +% \ref{Semantic}, starting at the page \pageref{Semantic}. +% % % \bigskip % The command |\PitonStyle| takes in as argument the name of a style and allows @@ -567,17 +578,59 @@ version 2005/12/01 or later. % \texttt{\textsl{style}}. % % \bigskip +% \subsubsection{Global styles and local styles} +% +% A style may be defined globally with the command |\SetPitonStyle|. That means +% that it will apply to all the informatic languages that use that style. +% +% \bigskip +% For example, with the command +% \begin{Verbatim} +% \SetPitonStyle{Comment = \color{gray}} +% \end{Verbatim} +% all the comments will be composed in gray in all the listings, whatever +% informatic language they use (Python, C, OCaml, etc.). +% +% \bigskip +% \colorbox{yellow!50}{\textbf{New 2.2}}\enskip But it's also possible to define +% a style locally for a given informatic langage by providing the name of that +% language as optional argument (between square brackets) to the command +% |\SetPitonStyle|.\footnote{We recall, that, in the package \pkg{piton}, the +% names of the informatic languages are case-insensitive.} % +% \bigskip +% For example, with the command +% \begin{Verbatim} +% \SetPitonStyle~emphase#[SQL]@{Keywords = \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 +% keywords are case-insensitive). +% +% \bigskip +% As expected, if an informatic language uses a given style and if that style has +% no local definition for that language, the global version is used. That notion +% of ``global style'' has no link with the notion of global definition in TeX +% (the notion of \emph{group} in TeX). +% +% \bigskip +% The package \pkg{piton} itself (that is to say the file |piton.sty|) defines +% all the styles globally. +% +% \bigskip +% +% \subsubsection{The style UserFunction} % The extension \pkg{piton} provides a special style called~|UserFunction|. That -% style applies to the names of the functions previously defined by the user via -% an instruction Python \piton{def} in one of the previous listings. The initial -% value of that style is empty, and, therefore, the names of the functions are -% formatted as standard text (in black). However, it's possible to change the -% value of that style, as any other style, with the command |\SetPitonStyle|. +% style applies to the names of the functions previously defined by the user +% (for example, in Python, these names are those following the keyword +% \piton{def} in a previous Python listing). The initial value of that style is +% empty, and, therefore, the names of the functions are formatted as standard +% text (in black). However, it's possible to change the value of that style, as +% any other style, with the command |\SetPitonStyle|. % % \medskip % In the following example, we fix as value for that style |UserFunction| the -% initial value of the the style |Name.Function| (which applies to the name of +% initial value of the style |Name.Function| (which applies to the name of % the functions, \emph{at the moment of their definition}). % % \begingroup @@ -602,17 +655,24 @@ version 2005/12/01 or later. % % \endgroup % -% As one see, the name |transpse| has been highlighted because it's the name of +% As one see, the name |transpose| has been highlighted because it's the name of % a Python function previously defined by the user (hence the name % |UserFunction| for that style). % -% \PitonClearUserFunctions +% \PitonClearUserFunctions[Python] % % \bigskip +% \begin{small} % Of course, the list of the names of Python functions previously défined is -% kept in the memory of LuaLaTeX (in a global way, that is to say independtly of -% the TeX groups). The extension \pkg{piton} provides a command to clear that -% list : it's the command |\PitonClearUserFunctions|. +% kept in the memory of LuaLaTeX (in a global way, that is to say independently +% of the TeX groups). The extension \pkg{piton} provides a command to clear that +% list : it's the command |\PitonClearUserFunctions|. When it is used without +% argument, that command is applied to all the informatic languages used by the +% user but it's also possible to use it with an optional argument (between +% square brackets) which is a list of informatic languages to which the command +% will be applied.\footnote{We remind that, in \pkg{piton}, the name of the +% informatic languages are case-insensitive.} +% \end{small} % % \subsection{Creation of new environments} % @@ -621,7 +681,8 @@ version 2005/12/01 or later. % Since the environment |{Piton}| has to catch its body in a special way (more % or less as verbatim text), it's not possible to construct new environments % directly over the environment |{Piton}| with the classical commands -% |\newenvironment| or |\NewDocumentEnvironment|. +% |\newenvironment| (of standard LaTeX) or |\NewDocumentEnvironment| (of +% LaTeX3). % % That's why \pkg{piton} provides a command |\NewPitonEnvironment|. That % command takes in three mandatory arguments. @@ -907,7 +968,9 @@ version 2005/12/01 or later. % \subsection{Highlighting some identifiers} % % It's possible to require a changement of formating for some identifiers with -% the key |identifiers| of |\PitonOptions|. +% the key |identifiers| of |\PitonOptions|.\footnote{This feature is not +% available for the language SQL because, in SQL, there is no identifiers : +% there are only names of fields and names of tables.} % % \smallskip % That key takes in as argument a value of the following format: @@ -1597,7 +1660,7 @@ version 2005/12/01 or later. % if x < 0: % return -arctan(-x) #> recursive call % elif x > 1: -% return pi/2 - arctan(1/x) #> anoother recursive call +% return pi/2 - arctan(1/x) #> another recursive call % else: % s = 0 % for k in range(n): @@ -1879,6 +1942,16 @@ version 2005/12/01 or later. % In \pkg{piton}, the default language is Python. If necessary, it's possible to % come back to the language Python with |\PitonOptions{language=Python}|. % +% \bigskip +% +% The initial settings +% done by \pkg{piton} in |piton.sty| are inspired by the style \pkg{manni} de +% Pygments, as applied by Pygments to the language Python.\footnote{See: +% \url{https://pygments.org/styles/}. Remark that, by default, Pygments provides +% for its style \pkg{manni} a colored background whose color is the HTML color +% \texttt{\#F0F3F3}. It's possible to have the same color in \texttt{\{Piton\}} +% with the instruction \texttt{\textbackslash PitonOptions\{background-color = +% [HTML]\{F0F3F3\}\}}.} % % \vspace{1cm} % @@ -1947,6 +2020,8 @@ version 2005/12/01 or later. % \end{Piton} % \end{Verbatim} % +% \bigskip +% The option exists also for |\PitonInputFile| : |\PitonInputFile[language=OCaml]{...}| % % \vspace{1cm} % @@ -1969,11 +2044,11 @@ version 2005/12/01 or later. % Name.Module & the name of the modules \\ % Name.Function & the name of the Python functions defined by the user \emph{at their % point of definition} (with the keyword |let|) \\ -% UserFunction & the name of the Python functions previously defined by the user +% UserFunction & the name of the OCaml functions previously defined by the user % (the initial value of that parameter is empty and these % elements are drawn in the current color, usually black) \\ % Exception & the predefined exceptions (eg : |End_of_File|) \\ -% TypeParameter & the parameters of the type \\ +% 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: @@ -2005,6 +2080,8 @@ version 2005/12/01 or later. % \end{Piton} % \end{Verbatim} % +% \bigskip +% The option exists also for |\PitonInputFile| : |\PitonInputFile[language=C]{...}| % % \vspace{1cm} % @@ -2045,6 +2122,57 @@ version 2005/12/01 or later. % \end{tabularx} % \end{center} % +% \newpage +% +% \subsection{The language SQL} +% +% +% It's possible to switch to the language |SQL| with |\PitonOptions{language = SQL}|. +% +% \bigskip +% It's also possible to set the language SQL for an individual environment |{Piton}|. +% % +% \begin{Verbatim} +% \begin{Piton}~emphase#[language=SQL]@ +% ... +% \end{Piton} +% \end{Verbatim} +% +% \bigskip +% The option exists also for |\PitonInputFile| : |\PitonInputFile[language=SQL]{...}| +% +% +% \vspace{1cm} +% +% \begin{center} +% \begin{tabularx}{0.9\textwidth}{@{}>{\ttfamily}l>{\raggedright\arraybackslash}X@{}} +% \toprule +% \normalfont Style & Use \\ +% \midrule +% Number & the numbers \\ +% String.Long & the strings (between \texttt{'} and not \texttt{"} because the +% elements between \texttt{"} are names of fields and formatted with |Name.Field|) \\ +% Operator & the following operators : \texttt{= != <> >= > < <= * + / } \\ +% Name.Table & the names of the tables \\ +% Name.Field & the names of the fields of the tables \\ +% Name.Builtin & the following built-in functions (their names are \emph{not} case-sensitive): +% |avg|, |count|, |char_lenght|, |concat|, |curdate|, |current_date|, +% |date_format|, |day|, |lower|, |ltrim|, |max|, |min|, |month|, |now|, +% |rank|, |round|, |rtrim|, |substring|, |sum|, |upper| and |year|. \\ +% Comment & the comments (beginning by \texttt{--} or between |/*| and |*/|) \\ +% Comment.LaTeX & the comments beginning by \texttt{-->} which are composed by +% \pkg{piton} as LaTeX code (merely named ``LaTeX comments'' in this document) \\ +% Keyword & the following keywords (their names are \emph{not} case-sensitive): +% |add|, |after|, |all|, |alter|, |and|, |as|, |asc|, |between|, |by|, +% |change|, |column|, |create|, |cross join|, |delete|, |desc|, |distinct|, +% |drop|, |from|, |group|, |having|, |in|, |inner|, |insert|, |into|, |is|, +% |join|, |left|, |like|, |limit|, |merge|, |not|, |null|, |on|, |or|, +% |order|, |over|, |right|, |select|, |set|, |table|, |then|, |truncate|, +% |union|, |update|, |values|, |when|, |where| and |with|. \\ +% \bottomrule +% \end{tabularx} +% \end{center} +% % % \newpage % @@ -2434,6 +2562,12 @@ version 2005/12/01 or later. % \end{macrocode} % % \medskip +% \begin{macrocode} +\tl_new:N \l_@@_path_seq +% \end{macrocode} +% +% +% \medskip % In order to have a better control over the keys. % \begin{macrocode} \bool_new:N \l_@@_in_PitonOptions_bool @@ -2514,7 +2648,7 @@ version 2005/12/01 or later. % \medskip % The argument of |\PitonInputFile|. % \begin{macrocode} -\str_new:N \l_@@_file_name_str +\tl_new:N \l_@@_file_name_tl % \end{macrocode} % % \medskip @@ -2642,6 +2776,18 @@ version 2005/12/01 or later. % \end{macrocode} % % \medskip +% Be careful. The following sequence |\g_@@_languages_seq| is not the list of +% the languages supported by \pkg{piton}. It's the list of the languages for +% which at least a user function has been defined. We need that sequence only +% for the command |\PitonClearUserFunctions| when it is used without its +% optional argument: it must clear all the list of languages for which at least +% a user function has been defined. +% \begin{macrocode} +\seq_new:N \g_@@_languages_seq +% \end{macrocode} +% +% +% \medskip % \begin{macrocode} \cs_new_protected:Npn \@@_set_tab_tl:n #1 { @@ -3156,6 +3302,9 @@ version 2005/12/01 or later. language .code:n = \str_set:Nx \l_@@_language_str { \str_lowercase:n { #1 } } , language .value_required:n = true , + path .code:n = + \seq_set_from_clist:Nn \l_@@_path_seq { #1 } , + path .value_required:n = true , gobble .int_set:N = \l_@@_gobble_int , gobble .value_required:n = true , auto-gobble .code:n = \int_set:Nn \l_@@_gobble_int { -1 } , @@ -3569,6 +3718,7 @@ version 2005/12/01 or later. { \box_wd:N \l_tmpa_box + \l_@@_numbers_sep_dim + 0.1 em } } } +\cs_generate_variant:Nn \@@_compute_left_margin:nn { n V } % \end{macrocode} % % @@ -3764,16 +3914,18 @@ version 2005/12/01 or later. % \begin{macrocode} \NewDocumentCommand { \PitonInputFile } { d < > O { } m } { - \file_if_exist:nTF { #3 } - { \@@_input_file:nnn { #1 } { #2 } { #3 } } + \group_begin: + \seq_set_eq:NN \l_file_search_path_seq \l_@@_path_seq + \file_get_full_name:nNTF { #3 } \l_@@_file_name_tl + { \@@_input_file:nn { #1 } { #2 } } { \msg_error:nnn { piton } { Unknown~file } { #3 } } + \group_end: } % \end{macrocode} % % \begin{macrocode} -\cs_new_protected:Npn \@@_input_file:nnn #1 #2 #3 +\cs_new_protected:Npn \@@_input_file:nn #1 #2 { - \str_set:Nn \l_@@_file_name_str { #3 } % \end{macrocode} % We recall that, if we are in Beamer, the command |\PitonInputFile| is % ``overlay-aware'' and that's why there is an optional argument between angular @@ -3839,12 +3991,12 @@ version 2005/12/01 or later. % stored by Lua in |\l_@@_nb_lines_int|. That information will be used to allow % or disallow page breaks. % \begin{macrocode} - \lua_now:e { piton.CountLinesFile('\l_@@_file_name_str') } + \lua_now:e { piton.CountLinesFile('\l_@@_file_name_tl') } % \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. % \begin{macrocode} - \@@_compute_left_margin:nn { CountNonEmptyLinesFile } { #3 } + \@@_compute_left_margin:nV { CountNonEmptyLinesFile } \l_@@_file_name_tl \@@_compute_width: \ttfamily \bool_if:NT \g_@@_footnote_bool { \begin { savenotes } } @@ -3853,7 +4005,7 @@ version 2005/12/01 or later. { piton.ParseFile( '\l_@@_language_str' , - '\l_@@_file_name_str' , + '\l_@@_file_name_tl' , \int_use:N \l_@@_first_line_int , \int_use:N \l_@@_last_line_int ) } @@ -3895,7 +4047,7 @@ version 2005/12/01 or later. \lua_now:e { piton.ComputeRange - ( '\l_tmpa_str' , '\l_tmpb_str' , '\l_@@_file_name_str' ) + ( '\l_tmpa_str' , '\l_tmpb_str' , '\l_@@_file_name_tl' ) } } % \end{macrocode} @@ -3906,13 +4058,23 @@ version 2005/12/01 or later. % \medskip % The following command is fundamental: it will be used by the Lua code. % \begin{macrocode} -\NewDocumentCommand { \PitonStyle } { m } { \use:c { pitonStyle #1 } } +\NewDocumentCommand { \PitonStyle } { m } + { + \cs_if_exist_use:cF { pitonStyle _ \l_@@_language_str _ #1 } + { \use:c { pitonStyle _ #1 } } + } % \end{macrocode} % % \medskip -% The following command takes in its argument by curryfication. % \begin{macrocode} -\NewDocumentCommand { \SetPitonStyle } { } { \keys_set:nn { piton / Styles } } +\NewDocumentCommand { \SetPitonStyle } { O { } m } + { + \str_set:Nx \l_@@_SetPitonStyle_option_str { \str_lowercase:n { #1 } } + \str_if_eq:VnT \l_@@_SetPitonStyle_option_str { current-language } + { \str_set_eq:NN \l_@@_SetPitonStyle_option_str \l_@@_language_str } + \keys_set:nn { piton / Styles } { #2 } + \str_clear:N \l_@@_SetPitonStyle_option_str + } % \end{macrocode} % % \medskip @@ -3943,6 +4105,7 @@ version 2005/12/01 or later. Name.Function , Name.Module , Name.Namespace , + Name.Table , Name.Type , Number , Operator , @@ -3957,12 +4120,20 @@ version 2005/12/01 or later. UserFunction } -\clist_map_inline:Nn \g_@@_styles_clist +\clist_map_inline:Nn \g_@@_styles_clist { \keys_define:nn { piton / Styles } { - #1 .tl_set:c = pitonStyle #1 , - #1 .value_required:n = true + #1 .value_required:n = true , + #1 .code:n = + \tl_set:cn + { + pitonStyle _ + \str_if_empty:NF \l_@@_SetPitonStyle_option_str + { \l_@@_SetPitonStyle_option_str _ } + #1 + } + { ##1 } } } @@ -4022,6 +4193,7 @@ version 2005/12/01 or later. 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 , @@ -4035,7 +4207,7 @@ version 2005/12/01 or later. TypeParameter = \color[HTML]{336666} \itshape , Preproc = \color[HTML]{AA6600} \slshape , Identifier = \@@_identifier:n , - UserFunction = , + UserFunction = , Prompt = , ParseAgain.noCR = \@@_piton_no_cr:n , ParseAgain = \@@_piton:n , @@ -4103,7 +4275,7 @@ version 2005/12/01 or later. % that name. We define now that style (you define it directly and you short-cut % the function |\SetPitonStyle|). % \begin{macrocode} -\cs_new_protected:cpn { pitonStyle Name.Function.Internal } #1 +\cs_new_protected:cpn { pitonStyle _ Name.Function.Internal } #1 { % \end{macrocode} % First, the element is composed in the TeX flow with the style |Name.Function| @@ -4126,12 +4298,50 @@ version 2005/12/01 or later. \seq_if_exist:cF { g_@@_functions _ \l_@@_language_str _ seq } { \seq_new:c { g_@@_functions _ \l_@@_language_str _ seq } } \seq_gput_right:cn { g_@@_functions _ \l_@@_language_str _ seq } { #1 } +% \end{macrocode} +% We update |\g_@@_languages_seq| which is used only by the command +% |\PitonClearUserFunctions| when it's used without its optional argument. +% \begin{macrocode} + \seq_if_in:NVF \g_@@_languages_seq \l_@@_language_str + { \seq_gput_left:NV \g_@@_languages_seq \l_@@_language_str } } % \end{macrocode} % % \bigskip % \begin{macrocode} -\NewDocumentCommand \PitonClearUserFunctions { ! O { \l_@@_language_str } } +\NewDocumentCommand \PitonClearUserFunctions { ! o } + { + \tl_if_novalue:nTF { #1 } +% \end{macrocode} +% If the command is used without its optional argument, we will deleted the +% user language for all the informatic languages. +% \begin{macrocode} + { \@@_clear_all_functions: } + { \@@_clear_list_functions:n { #1 } } + } +% \end{macrocode} +% +% \bigskip +% \begin{macrocode} +\cs_new_protected:Npn \@@_clear_list_functions:n #1 + { + \clist_set:Nn \l_tmpa_clist { #1 } + \clist_map_function:NN \l_tmpa_clist \@@_clear_functions_i:n + \clist_map_inline:nn { #1 } + { \seq_gremove_all:Nn \g_@@_languages_seq { ##1 } } + } +% \end{macrocode} +% +% \bigskip +% \begin{macrocode} +\cs_new_protected:Npn \@@_clear_functions_i:n #1 + { \exp_args:Nx \@@_clear_functions_ii:n { \str_lowercase:n { #1 } } } +% \end{macrocode} +% +% The following command clears the list of the user-defined functions for the +% language provided in argument (mandatory in lower case). +% \begin{macrocode} +\cs_new_protected:Npn \@@_clear_functions_ii:n #1 { \seq_if_exist:cT { g_@@_functions _ #1 _ seq } { @@ -4141,13 +4351,33 @@ version 2005/12/01 or later. } } % \end{macrocode} +% +% \bigskip +% \begin{macrocode} +\cs_new_protected:Npn \@@_clear_functions:n #1 + { + \@@_clear_functions_i:n { #1 } + \seq_gremove_all:Nn \g_@@_languages_seq { #1 } + } +% \end{macrocode} +% +% \bigskip +% The following command clears all the user-defined functions for all the +% informatic languages. +% \begin{macrocode} +\cs_new_protected:Npn \@@_clear_all_functions: + { + \seq_map_function:NN \g_@@_languages_seq \@@_clear_functions_i:n + \seq_gclear:N \g_@@_languages_seq + } +% \end{macrocode} % % \bigskip % \subsubsection{Security} % % \begin{macrocode} \AddToHook { env / piton / begin } - { \msg_fatal:nn { piton } { No~environment~piton } } + { \msg_fatal:nn { piton } { No~environment~piton } } \msg_new:nnn { piton } { No~environment~piton } { @@ -4205,15 +4435,13 @@ version 2005/12/01 or later. } % \end{macrocode} % -% -% % \begin{macrocode} \@@_msg_new:nn { bad~range~specification } { Incompatible~keys.\\ You~can't~specify~the~range~of~lines~to~include~by~using~both~ markers~and~explicit~number~of~lines.\\ - Your~whole~file~'\l_@@_file_name_str'~will~be~included. + Your~whole~file~'\l_@@_file_name_tl'~will~be~included. } % \end{macrocode} % @@ -4237,7 +4465,7 @@ version 2005/12/01 or later. Marker~not~found.\\ The~range~'\l_@@_begin_range_str'~provided~to~the~ command~\token_to_str:N \PitonInputFile\ has~not~been~found.~ - The~whole~file~'\l_@@_file_name_str'~will~be~inserted. + The~whole~file~'\l_@@_file_name_tl'~will~be~inserted. } % \end{macrocode} % @@ -4248,7 +4476,7 @@ version 2005/12/01 or later. Marker~not~found.\\ The~marker~of~end~of~the~range~'\l_@@_end_range_str'~ provided~to~the~command~\token_to_str:N \PitonInputFile\ - has~not~been~found.~The~file~'\l_@@_file_name_str'~will~ + has~not~been~found.~The~file~'\l_@@_file_name_tl'~will~ be~inserted~till~the~end. } % \end{macrocode} @@ -4297,6 +4525,7 @@ version 2005/12/01 or later. left-margin,~ line-numbers/,~ marker/,~ + path,~ prompt-background-color,~ resume,~ show-spaces,~ @@ -4465,6 +4694,8 @@ end % % % \bigskip +% The following function |WithStyle| is similar to the function |K| but should +% be used for multi-lines elements. % \begin{macrocode} local function WithStyle(style,pattern) return @@ -4543,7 +4774,7 @@ local identifier = letter * alphanum ^ 0 % On the other hand, the \textsc{lpeg} |Identifier| (with a capital) also returns % a \emph{capture}. % \begin{macrocode} -local Identifier = K ( 'Identifier' , identifier) +local Identifier = K ( 'Identifier' , identifier ) % \end{macrocode} % % \bigskip @@ -5308,7 +5539,7 @@ local MainPython = + Word % \end{macrocode} % -% Ici, il ne faut pas mettre |local| ! +% Here, we must not put |local|! % \begin{macrocode} MainLoopPython = ( ( space^1 * -1 ) @@ -5860,6 +6091,8 @@ languages['ocaml'] = ocaml % Some strings of length 2 are explicit because we want the corresponding % ligatures available in some fonts such as \emph{Fira Code} to be active. % \begin{macrocode} +local identifier = letter * alphanum ^ 0 + local Operator = K ( 'Operator' , P "!=" + P "==" + P "<<" + P ">>" + P "<=" + P ">=" @@ -6020,29 +6253,7 @@ end % \bigskip % \paragraph{EOL} % -% \bigskip -% The following LPEG will detect the Python prompts when the user is typesetting -% an interactive session of Python (directly or through |{pyconsole}| of -% \pkg{pyluatex}). We have to detect that prompt twice. The first detection -% (called \emph{hasty detection}) will be before the |\@@_begin_line:| because -% you want to trigger a special background color for that row (and, after the -% |\@@_begin_line:|, it's too late to change de background). -% \begin{macrocode} -local PromptHastyDetection = ( # ( P ">>>" + P "..." ) * Lc ( '\\@@_prompt:' ) ) ^ -1 -% \end{macrocode} -% We remind that the marker |#| of \textsc{lpeg} specifies that the pattern will be -% detected but won't consume any character. -% -% \medskip -% With the following \textsc{lpeg}, a style will actually be applied to the -% prompt (for instance, it's possible to decide to discard these prompts). -% \begin{macrocode} -local Prompt = K ( 'Prompt' , ( ( P ">>>" + P "..." ) * P " " ^ -1 ) ^ -1 ) -% \end{macrocode} -% % -% -% \bigskip % The following \textsc{lpeg} |EOL| is for the end of lines. % \begin{macrocode} local EOL = @@ -6152,7 +6363,7 @@ local MainC = + Word % \end{macrocode} % -% Ici, il ne faut pas mettre |local| ! +% Here, we must not put |local|! % \begin{macrocode} MainLoopC = ( ( space^1 * -1 ) @@ -6171,9 +6382,7 @@ languageC = Ct ( ( ( space - P "\r" ) ^0 * P "\r" ) ^ -1 * BeamerBeginEnvironments - * PromptHastyDetection * Lc '\\@@_begin_line:' - * Prompt * SpaceIndentation ^ 0 * MainLoopC * -1 @@ -6185,6 +6394,354 @@ languageC = languages['c'] = languageC % \end{macrocode} % +% +% \bigskip +% \subsubsection{The LPEG language SQL} +% +% \bigskip +% In the identifiers, we will be able to catch those contening spaces, that is +% to say like |"last name"|. +% \begin{macrocode} +local identifier = + letter * ( alphanum + P "-" ) ^ 0 + + P '"' * ( ( alphanum + space - P '"' ) ^ 1 ) * P '"' + + +local Operator = + K ( 'Operator' , + P "=" + P "!=" + P "<>" + P ">=" + P ">" + P "<=" + P "<" + S "*+/" + ) +% \end{macrocode} +% In SQL, the keywords are case-insensitive. That's why we have a little +% complication. We will catch the keywords with the identifiers and, then, +% distinguish the keywords with a Lua function. However, some keywords will be +% catched in special LPEG because we want to detect the names of the SQL tables. +% \begin{macrocode} +local function Set (list) + local set = {} + for _, l in ipairs(list) do set[l] = true end + return set +end + +local set_keywords = Set + { + "ADD" , "AFTER" , "ALL" , "ALTER" , "AND" , "AS" , "ASC" , "BETWEEN" , "BY" , + "CHANGE" , "COLUMN" , "CREATE" , "CROSS JOIN" , "DELETE" , "DESC" , "DISTINCT" , + "DROP" , "FROM" , "GROUP" , "HAVING" , "IN" , "INNER" , "INSERT" , "INTO" , "IS" , + "JOIN" , "LEFT" , "LIKE" , "LIMIT" , "MERGE" , "NOT" , "NULL" , "ON" , "OR" , + "ORDER" , "OVER" , "RIGHT" , "SELECT" , "SET" , "TABLE" , "THEN" , "TRUNCATE" , + "UNION" , "UPDATE" , "VALUES" , "WHEN" , "WHERE" , "WITH" + } + +local set_builtins = Set + { + "AVG" , "COUNT" , "CHAR_LENGHT" , "CONCAT" , "CURDATE" , "CURRENT_DATE" , + "DATE_FORMAT" , "DAY" , "LOWER" , "LTRIM" , "MAX" , "MIN" , "MONTH" , "NOW" , + "RANK" , "ROUND" , "RTRIM" , "SUBSTRING" , "SUM" , "UPPER" , "YEAR" + } +% \end{macrocode} +% +% The \textsc{lpeg} |Identifer| will catch the identifiers of the fields +% but also the keywords and the built-in functions of SQL. If will \emph{not} +% catch the names of the SQL tables. +% \begin{macrocode} +local Identifier = + C ( identifier ) / + ( + function (s) + if set_keywords[string.upper(s)] -- the keywords are case-insensitive in SQL +% \end{macrocode} +% Remind that, in Lua, it's possible to return \emph{several} values. +% \begin{macrocode} + then return { "{\\PitonStyle{Keyword}{" } , + { luatexbase.catcodetables.other , s } , + { "}}" } + else if set_builtins[string.upper(s)] + then return { "{\\PitonStyle{Name.Builtin}{" } , + { luatexbase.catcodetables.other , s } , + { "}}" } + else return { "{\\PitonStyle{Name.Field}{" } , + { luatexbase.catcodetables.other , s } , + { "}}" } + end + end + end + ) +% \end{macrocode} +% +% \bigskip +% \paragraph{The strings of SQL} +% +% \begin{macrocode} +local String = + K ( 'String.Long' , P "'" * ( 1 - P "'" ) ^ 1 * P "'" ) +% \end{macrocode} +% +% \bigskip +% \paragraph{Beamer} +% +% The following \textsc{lpeg} |balanced_braces| will be used for the (mandatory) +% argument of the commands |\only| and \emph{al.} of Beamer. It's necessary to +% use a \emph{grammar} because that pattern mainly checks the correct nesting of +% the delimiters (and it's known in the theory of formal languages that this +% can't be done with regular expressions \emph{stricto sensu} only). +% \begin{macrocode} +local balanced_braces = + P { "E" , + E = + ( + P "{" * V "E" * P "}" + + + String + + + ( 1 - S "{}" ) + ) ^ 0 + } +% \end{macrocode} +% +% +% \bigskip +% \begin{macrocode} +if piton_beamer +then + Beamer = + L ( P "\\pause" * ( P "[" * ( 1 - P "]" ) ^ 0 * P "]" ) ^ -1 ) + + + Ct ( Cc "Open" + * C ( + ( + P "\\uncover" + P "\\only" + P "\\alert" + P "\\visible" + + P "\\invisible" + P "\\action" + ) + * ( P "<" * (1 - P ">") ^ 0 * P ">" ) ^ -1 + * P "{" + ) + * Cc "}" + ) + * ( C ( balanced_braces ) / (function (s) return MainLoopSQL:match(s) end ) ) + * P "}" * Ct ( Cc "Close" ) + + OneBeamerEnvironment ( "uncoverenv" , MainLoopSQL ) + + OneBeamerEnvironment ( "onlyenv" , MainLoopSQL ) + + OneBeamerEnvironment ( "visibleenv" , MainLoopSQL ) + + OneBeamerEnvironment ( "invisibleenv" , MainLoopSQL ) + + OneBeamerEnvironment ( "alertenv" , MainLoopSQL ) + + OneBeamerEnvironment ( "actionenv" , MainLoopSQL ) + + + L ( +% \end{macrocode} +% For |\\alt|, the specification of the overlays (between angular brackets) is mandatory. +% \begin{macrocode} + ( P "\\alt" ) + * P "<" * (1 - P ">") ^ 0 * P ">" + * P "{" + ) + * K ( 'ParseAgain.noCR' , balanced_braces ) + * L ( P "}{" ) + * K ( 'ParseAgain.noCR' , balanced_braces ) + * L ( P "}" ) + + + L ( +% \end{macrocode} +% For |\\temporal|, the specification of the overlays (between angular brackets) is mandatory. +% \begin{macrocode} + ( P "\\temporal" ) + * P "<" * (1 - P ">") ^ 0 * P ">" + * P "{" + ) + * K ( 'ParseAgain.noCR' , balanced_braces ) + * L ( P "}{" ) + * K ( 'ParseAgain.noCR' , balanced_braces ) + * L ( P "}{" ) + * K ( 'ParseAgain.noCR' , balanced_braces ) + * L ( P "}" ) +end +% \end{macrocode} +% +% \bigskip +% \paragraph{EOL} +% +% \bigskip +% The following \textsc{lpeg} |EOL| is for the end of lines. +% \begin{macrocode} +local EOL = + P "\r" + * + ( + ( space^0 * -1 ) + + +% \end{macrocode} +% We recall that each line in the SQL code we have to parse will be sent +% back to LaTeX between a pair |\@@_begin_line:| -- +% |\@@_end_line:|\footnote{Remember that the \texttt{\textbackslash +% @@\_end\_line:} must be explicit because it will be used as marker in order to +% delimit the argument of the command \texttt{\textbackslash @@\_begin\_line:}}. +% \begin{macrocode} + Ct ( + Cc "EOL" + * + Ct ( + Lc "\\@@_end_line:" + * BeamerEndEnvironments + * BeamerBeginEnvironments + * Lc "\\@@_newline: \\@@_begin_line:" + ) + ) + ) + * + SpaceIndentation ^ 0 +% \end{macrocode} +% +% +% +% \bigskip +% \paragraph{The comments in the SQL listings} +% +% We define different \textsc{lpeg} dealing with comments in the SQL listings. +% \begin{macrocode} +local CommentMath = + P "$" * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1 ) * P "$" + +local Comment = + WithStyle ( 'Comment' , + Q ( P "--" ) -- syntax of SQL92 + * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 ) + * ( EOL + -1 ) + +local LongComment = + WithStyle ( 'Comment' , + Q ( P "/*" ) + * ( CommentMath + Q ( ( 1 - P "*/" - S "$\r" ) ^ 1 ) + EOL ) ^ 0 + * Q ( P "*/" ) + ) -- $ +% \end{macrocode} +% +% +% \bigskip +% The following \textsc{lpeg} |CommentLaTeX| is for what is called in that +% document the ``LaTeX comments''. Since the elements that will be catched must +% be sent to LaTeX with standard LaTeX catcodes, we put the capture (done by +% the function~|C|) in a table (by using~|Ct|, which is an alias for |lpeg.Ct|). +% \begin{macrocode} +local CommentLaTeX = + P(piton.comment_latex) + * Lc "{\\PitonStyle{Comment.LaTeX}{\\ignorespaces" + * L ( ( 1 - P "\r" ) ^ 0 ) + * Lc "}}" + * ( EOL + -1 ) +% \end{macrocode} +% +% +% +% +% \bigskip +% \paragraph{The main LPEG for the language SQL} +% +% +% \begin{macrocode} +local function LuaKeyword ( name ) +return + Lc ( "{\\PitonStyle{Keyword}{" ) + * Q ( Cmt ( + C ( identifier ) , + function(s,i,a) return string.upper(a) == name end + ) + ) + * Lc ( "}}" ) +end +% \end{macrocode} +% +% \begin{macrocode} +local TableField = + K ( 'Name.Table' , identifier ) + * Q ( P "." ) + * K ( 'Name.Field' , identifier ) + +local OneField = + ( + Q ( P "(" * ( 1 - P ")" ) ^ 0 * P ")" ) + + + K ( 'Name.Table' , identifier ) + * Q ( P "." ) + * K ( 'Name.Field' , identifier ) + + + K ( 'Name.Field' , identifier ) + ) + * ( + Space * LuaKeyword ( "AS" ) * Space * K ( 'Name.Field' , identifier ) + ) ^ -1 + * ( Space * ( LuaKeyword ( "ASC" ) + LuaKeyword ( "DESC" ) ) ) ^ -1 + +local OneTable = + K ( 'Name.Table' , identifier ) + * ( + Space + * LuaKeyword ( "AS" ) + * Space + * K ( 'Name.Table' , identifier ) + ) ^ -1 + +local WeCatchTableNames = + LuaKeyword ( "FROM" ) + * ( Space + EOL ) + * OneTable * ( SkipSpace * Q ( P "," ) * SkipSpace * OneTable ) ^ 0 + + ( + LuaKeyword ( "JOIN" ) + LuaKeyword ( "INTO" ) + LuaKeyword ( "UPDATE" ) + + LuaKeyword ( "TABLE" ) + ) + * ( Space + EOL ) * OneTable +% \end{macrocode} +% +% +% First, the main loop : +% \begin{macrocode} +local MainSQL = + EOL + + Space + + Tab + + Escape + EscapeMath + + CommentLaTeX + + Beamer + + Comment + LongComment + + Delim + + Operator + + String + + Punct + + WeCatchTableNames + + ( TableField + Identifier ) * ( Space + Operator + Punct + Delim + EOL + -1 ) + + Number + + Word +% \end{macrocode} +% +% Here, we must not put |local|! +% \begin{macrocode} +MainLoopSQL = + ( ( space^1 * -1 ) + + MainSQL + ) ^ 0 +% \end{macrocode} +% +% \bigskip +% We recall that each line in the C code to parse will be sent back to +% LaTeX between a pair |\@@_begin_line:| -- |\@@_end_line:|\footnote{Remember +% that the \texttt{\textbackslash @@\_end\_line:} must be explicit because it +% will be used as marker in order to delimit the argument of the command +% \texttt{\textbackslash @@\_begin\_line:}}. +% \begin{macrocode} +languageSQL = + Ct ( + ( ( space - P "\r" ) ^ 0 * P "\r" ) ^ -1 + * BeamerBeginEnvironments + * Lc '\\@@_begin_line:' + * SpaceIndentation ^ 0 + * MainLoopSQL + * -1 + * Lc '\\@@_end_line:' + ) +% \end{macrocode} +% +% \begin{macrocode} +languages['sql'] = languageSQL +% \end{macrocode} % % \bigskip % \subsubsection{The function Parse} @@ -6551,6 +7108,15 @@ end % % \verb|https://github.com/fpantigny/piton| % +% \subsection*{Changes between versions 2.1 and 2.2} +% +% New key |path| for |\PitonOptions|. +% +% New language SQL. +% +% It's now possible to define styles locally to a given language (with the +% optional argument of |\SetPitonStyle|). +% % \subsection*{Changes between versions 2.0 and 2.1} % % The key |line-numbers| has now subkeys |line-numbers/skip-empty-lines|, -- cgit v1.2.3