From 1b771c1e303b8274d871ee6bd4bdd5ba03bdd152 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Tue, 19 Mar 2024 03:02:55 +0000 Subject: CTAN sync 202403190302 --- macros/luatex/latex/piton/piton.dtx | 607 +++++++++++++++++++++++++----------- 1 file changed, 425 insertions(+), 182 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 fb06977b46..aa149d78e9 100644 --- a/macros/luatex/latex/piton/piton.dtx +++ b/macros/luatex/latex/piton/piton.dtx @@ -72,12 +72,12 @@ % \iffalse %<*STY> % \fi -\def\PitonFileVersion{2.6a} -\def\PitonFileDate{2024/03/06} +\def\PitonFileVersion{2.6b} +\def\PitonFileDate{2024/03/18} % \iffalse % %<*LUA> --- Version 2.6a of 2024/03/06 +piton_version = "2.6b" -- 2024/03/18 % %\fi % @@ -659,17 +659,31 @@ % 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 style |Name.Function| (which applies to the name of -% the functions, \emph{at the moment of their definition}). +% In the following example, we tune the styles |Name.Function| and |UserFunction| +% so as to have clickable names of functions linked to the (informatic) +% definition of the function. % % \begingroup % +% \NewDocumentCommand{\MyDefFunction}{m}{\hypertarget{piton:#1}{\color[HTML]{CC00FF}{#1}}} +% \NewDocumentCommand{\MyUserFunction}{m}{\hyperlink{piton:#1}{#1}} +% +% \SetPitonStyle +% { +% Name.Function = \MyDefFunction , +% UserFunction = \MyUserFunction +% } +% +% \medskip % \begin{Verbatim} -% \SetPitonStyle{~emphase#UserFunction@ = \color[HTML]{CC00FF}} +% \NewDocumentCommand{\MyDefFunction}{m} +% {\hypertarget{piton:~#1}{\color[HTML]{CC00FF}{~#1}}} +% \NewDocumentCommand{\MyUserFunction}{m}{\hyperlink{piton:~#1}{~#1}} +% +% \SetPitonStyle{Name.Function = \MyDefFunction, ~emphase#UserFunction@ = \MyUserFunction} % \end{Verbatim} % -% \SetPitonStyle{UserFunction = \color[HTML]{CC00FF}} +% \bigskip % % \begin{Piton} % def transpose(v,i,j): @@ -685,10 +699,6 @@ % % \endgroup % -% 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[Python] % % \bigskip @@ -3145,7 +3155,6 @@ % Now, we add the potential number of line, the potential left margin and the % potential background. % \begin{macrocode} - \tl_log:n { Contenu : #1.} \hbox_set:Nn \l_tmpa_box { \skip_horizontal:N \l_@@_left_margin_dim @@ -3793,6 +3802,8 @@ \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 } { } \bool_lazy_or:nnTF \l_@@_break_lines_in_piton_bool \l_@@_break_lines_in_Piton_bool @@ -3828,6 +3839,8 @@ \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 @@ -4318,6 +4331,7 @@ { Comment , Comment.LaTeX , + Discard , Exception , FormattingType , Identifier , @@ -4325,6 +4339,14 @@ Interpol.Inside , Keyword , Keyword.Constant , + Keyword2 , + Keyword3 , + Keyword4 , + Keyword5 , + Keyword6 , + Keyword7 , + Keyword8 , + Keyword9 , Name.Builtin , Name.Class , Name.Constructor , @@ -4345,7 +4367,12 @@ String.Long , String.Short , TypeParameter , - UserFunction + UserFunction , +% \end{macrocode} +% Now, specific styles for the languages created with |\NewPitonLanguage| with +% the syntax of \pkg{listings}. +% \begin{macrocode} + directive } \clist_map_inline:Nn \g_@@_styles_clist @@ -4433,10 +4460,12 @@ TypeParameter = \color[HTML]{336666} \itshape , Preproc = \color[HTML]{AA6600} \slshape , Identifier = \@@_identifier:n , + directive = \color[HTML]{AA6600} , UserFunction = , Prompt = , ParseAgain.noCR = \@@_piton_no_cr:n , ParseAgain = \@@_piton:n , + Discard = \use_none:n } % \end{macrocode} % The last styles |ParseAgain.noCR| and |ParseAgain| should be considered as @@ -4470,14 +4499,14 @@ \tl_if_novalue:nTF { #1 } { \clist_map_inline:Nn \l_tmpa_clist - { \cs_set:cpn { pitonIdentifier _ ##1 } { #3 } } + { \cs_set:cpn { PitonIdentifier _ ##1 } { #3 } } } { \str_set:Nx \l_tmpa_str { \str_lowercase:n { #1 } } \str_if_eq:onT \l_tmpa_str { current-language } { \str_set_eq:NN \l_tmpa_str \l_piton_language_str } \clist_map_inline:Nn \l_tmpa_clist - { \cs_set:cpn { pitonIdentifier _ \l_tmpa_str _ ##1 } { #3 } } + { \cs_set:cpn { PitonIdentifier _ \l_tmpa_str _ ##1 } { #3 } } } } % \end{macrocode} @@ -4485,8 +4514,8 @@ % \begin{macrocode} \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 _ \l_piton_language_str _ #1 } + { \cs_if_exist_use:c { PitonIdentifier _ #1 } } { #1 } } % \end{macrocode} @@ -4644,11 +4673,22 @@ {piton}.~This~error~is~fatal. } % \end{macrocode} +% % % \bigskip % \subsubsection{The error messages of the package} % % \begin{macrocode} +\@@_msg_new:nn { bad~version~of~piton.lua } + { + Bad~number~version~of~'piton.lua'\\ + The~file~'piton.lua'~loaded~has~not~the~same~number~of~ + version~as~the~file~'piton.sty'.~You~can~go~on~but~you~should~ + address~that~issue. + } +% \end{macrocode} +% +% \begin{macrocode} \@@_msg_new:nn { key~identifiers~deprecated } { The~key~'identifiers'~in~the~command~\token_to_str:N PitonOptions\ @@ -4831,10 +4871,27 @@ % \bigskip % \subsubsection{We load piton.lua} % +% +% \bigskip +% \begin{macrocode} +\cs_new_protected:Npn \@@_test_version:n #1 + { + \str_if_eq:VnF \PitonFileVersion { #1 } + { \@@_error:n { bad~version~of~piton.lua } } + } +% \end{macrocode} +% % \bigskip % \begin{macrocode} \hook_gput_code:nnn { begindocument } { . } - { \lua_now:e { require("piton.lua") } } + { + \lua_now:n + { + require ( "piton" ) + tex.sprint ( luatexbase.catcodetables.CatcodeTableExpl , + "\\@@_test_version:n {" .. piton_version .. "}" ) + } + } % \end{macrocode} % % \bigskip @@ -5086,10 +5143,11 @@ local Number = % corresponding to the keys |begin-escape| and |end-escape|. % \begin{macrocode} local Word -if piton.begin_escape ~= nil -then Word = Q ( ( ( 1 - space - P ( piton.begin_escape ) - P ( piton.end_escape ) ) +if piton.begin_escape then + Word = Q ( ( 1 - space - piton.begin_escape - piton.end_escape - S "'\"\r[({})]" - digit ) ^ 1 ) -else Word = Q ( ( ( 1 - space ) - S "'\"\r[({})]" - digit ) ^ 1 ) +else + Word = Q ( ( 1 - space - S "'\"\r[({})]" - digit ) ^ 1 ) end % \end{macrocode} % @@ -5128,6 +5186,7 @@ local VisualSpace = space * Lc "\\l_@@_space_tl" % \paragraph{Several tools for the construction of the main LPEG} % % \begin{macrocode} +local LPEG0 = { } local LPEG1 = { } local LPEG2 = { } local LPEG_cleaner = { } @@ -5145,7 +5204,7 @@ local function Compute_braces ( lpeg_string ) return P { "E" , E = ( - P "{" * V "E" * P "}" + "{" * V "E" * "}" + lpeg_string + @@ -5173,10 +5232,10 @@ end % \bigskip % \begin{macrocode} local function Compute_LPEG_cleaner ( lang , braces ) return - Ct ( ( piton.ListCommands * P "{" + Ct ( ( piton.ListCommands * "{" * ( braces / ( function ( s ) return LPEG_cleaner[lang] : match ( s ) end ) ) - * P "}" + * "}" + EscapeClean + C ( P ( 1 ) ) ) ^ 0 ) / table.concat @@ -5217,9 +5276,9 @@ BeamerBeginEnvironments = L ( P "\\begin{" * BeamerNamesEnvironments * "}" - * ( P "<" * ( 1 - P ">" ) ^ 0 * P ">" ) ^ -1 + * ( "<" * ( 1 - P ">" ) ^ 0 * ">" ) ^ -1 ) - * P "\r" + * "\r" ) ^ 0 % \end{macrocode} % @@ -5227,8 +5286,8 @@ BeamerBeginEnvironments = % \begin{macrocode} BeamerEndEnvironments = ( space ^ 0 * - L ( P "\\end{" * BeamerNamesEnvironments * P "}" ) - * P "\r" + L ( P "\\end{" * BeamerNamesEnvironments * "}" ) + * "\r" ) ^ 0 % \end{macrocode} % @@ -5243,18 +5302,18 @@ local function Compute_Beamer ( lang , braces ) % \bigskip % We will compute in |lpeg| the \textsc{lpeg} that we will return. % \begin{macrocode} - local lpeg = L ( P "\\pause" * ( P "[" * ( 1 - P "]" ) ^ 0 * P "]" ) ^ -1 ) + local lpeg = L ( P "\\pause" * ( "[" * ( 1 - P "]" ) ^ 0 * "]" ) ^ -1 ) lpeg = lpeg + Ct ( Cc "Open" * C ( ( P "\\uncover" + "\\only" + "\\alert" + "\\visible" + "\\invisible" + "\\action" ) - * ( P "<" * ( 1 - P ">" ) ^ 0 * P ">" ) ^ -1 + * ( "<" * ( 1 - P ">" ) ^ 0 * ">" ) ^ -1 * P "{" ) * Cc "}" ) * ( braces / ( function ( s ) return LPEG1[lang] : match ( s ) end ) ) - * P "}" + * "}" * Ct ( Cc "Close" ) % \end{macrocode} % @@ -5264,7 +5323,7 @@ local function Compute_Beamer ( lang , braces ) % brackets) is mandatory. % \begin{macrocode} lpeg = lpeg + - L ( P "\\alt" * P "<" * ( 1 - P ">" ) ^ 0 * P ">" * P "{" ) + L ( P "\\alt" * "<" * ( 1 - P ">" ) ^ 0 * ">" * "{" ) * K ( 'ParseAgain.noCR' , braces ) * L ( P "}{" ) * K ( 'ParseAgain.noCR' , braces ) @@ -5275,7 +5334,7 @@ local function Compute_Beamer ( lang , braces ) % For |\\temporal|, the specification of the overlays (between angular brackets) is mandatory. % \begin{macrocode} lpeg = lpeg + - L ( ( P "\\temporal" ) * P "<" * ( 1 - P ">" ) ^ 0 * P ">" * P "{" ) + L ( ( P "\\temporal" ) * "<" * ( 1 - P ">" ) ^ 0 * ">" * "{" ) * K ( 'ParseAgain.noCR' , braces ) * L ( P "}{" ) * K ( 'ParseAgain.noCR' , braces ) @@ -5292,7 +5351,7 @@ local function Compute_Beamer ( lang , braces ) Ct ( Cc "Open" * C ( P ( "\\begin{" .. x .. "}" ) - * ( P "<" * ( 1 - P ">") ^ 0 * P ">" ) ^ -1 + * ( "<" * ( 1 - P ">") ^ 0 * ">" ) ^ -1 ) * Cc ( "\\end{" .. x .. "}" ) ) @@ -5569,9 +5628,9 @@ local FromImport = local PercentInterpol = K ( 'String.Interpol' , P "%" - * ( P "(" * alphanum ^ 1 * P ")" ) ^ -1 + * ( "(" * alphanum ^ 1 * ")" ) ^ -1 * ( S "-#0 +" ) ^ 0 - * ( digit ^ 1 + P "*" ) ^ -1 + * ( digit ^ 1 + "*" ) ^ -1 * ( "." * ( digit ^ 1 + "*" ) ) ^ -1 * ( S "HlL" ) ^ -1 * S "sdfFeExXorgiGauc%" @@ -5789,24 +5848,20 @@ local expression = % \piton{def MyFunction(a,b,x=10,n:int): return n} % \end{center} % the \textsc{lpeg} |Params| will be used to catch the chunk\enskip |a,b,x=10,n:int|. -% -% Or course, a |Params| is simply a comma-separated list of |Param|, and that's -% why we define first the \textsc{lpeg} |Param|. % % \medskip % \begin{macrocode} -local Param = - SkipSpace * ( Identifier + Q "*args" + Q "**kwargs" ) * SkipSpace - * ( - K ( 'InitialValues' , "=" * expression ) - + Q ":" * SkipSpace * K ( 'Name.Type' , letter ^ 1 ) - ) ^ -1 +local Params = + P { "E" , + E = ( V "F" * ( Q "," * V "F" ) ^ 0 ) ^ -1 , + F = SkipSpace * ( Identifier + Q "*args" + Q "**kwargs" ) * SkipSpace + * ( + K ( 'InitialValues' , "=" * expression ) + + Q ":" * SkipSpace * K ( 'Name.Type' , letter ^ 1 ) + ) ^ -1 + } % \end{macrocode} % -% \medskip -% \begin{macrocode} -local Params = ( Param * ( Q "," * Param ) ^ 0 ) ^ -1 -% \end{macrocode} % % \bigskip % The following \textsc{lpeg} |DefFunction| catches a keyword |def| and the @@ -5829,7 +5884,7 @@ local DefFunction = % \pkg{piton}). We could avoid that kind of trick by using a non-terminal of a % grammar but we have probably here a better legibility. % \begin{macrocode} - * K ( 'ParseAgain' , ( 1 - S ":\r" ) ^ 0 ) + * K ( 'ParseAgain.noCR' , ( 1 - S ":\r" ) ^ 0 ) * Q ":" * ( SkipSpace * ( EOL + CommentLaTeX + Comment ) -- in all cases, that contains an EOL @@ -6942,16 +6997,15 @@ end % value of~$n$. % \begin{macrocode} local function gobble ( n , code ) - if n==0 + if n == 0 then return code - else - return ( Ct ( - ( 1 - P "\r" ) ^ (-n) * C ( ( 1 - P "\r" ) ^ 0 ) - * ( C "\r" - * ( 1 - P "\r" ) ^ (-n) - * C ( ( 1 - P "\r" ) ^ 0 ) - ) ^ 0 - ) / table.concat ) : match ( code ) + else return + ( Ct ( + ( 1 - P "\r" ) ^ (-n) * C ( ( 1 - P "\r" ) ^ 0 ) + * ( C "\r" * ( 1 - P "\r" ) ^ (-n) * C ( ( 1 - P "\r" ) ^ 0 ) + ) ^ 0 ) + / table.concat + ) : match ( code ) end end % \end{macrocode} @@ -7208,22 +7262,73 @@ function piton.new_language ( lang , definition ) % now in the Lua table |def_table|. We will use it several times. % % \medskip +% The following \textsc{lpeg} will be used to extract arguments in the values of +% the keys (|morekeywords|, |morecomment|, |morestring|, etc.). +% \begin{macrocode} + local tex_braced_arg = "{" * C ( ( 1 - P "}" ) ^ 0 ) * "}" + local tex_arg = tex_braced_arg + C ( 1 ) + local tex_option_arg = "[" * C ( ( 1 - P "]" ) ^ 0 ) * "]" + Cc ( nil ) +% \end{macrocode} +% +% \begin{macrocode} + local args_for_morekeywords + = "[" * C ( ( 1 - P "]" ) ^ 0 ) * "]" + * space ^ 0 + * tex_option_arg + * space ^ 0 + * tex_arg + * space ^ 0 + * ( tex_braced_arg + Cc ( nil ) ) +% \end{macrocode} +% +% \begin{macrocode} + local args_for_moredelims + = ( C ( P "*" ^ -2 ) + Cc ( nil ) ) * space ^ 0 + * args_for_morekeywords +% \end{macrocode} +% +% \begin{macrocode} + local args_for_morecomment + = "[" * C ( ( 1 - P "]" ) ^ 0 ) * "]" + * space ^ 0 + * tex_option_arg + * space ^ 0 + * C ( P ( 1 ) ^ 0 * -1 ) +% \end{macrocode} +% +% \begin{macrocode} + local args_for_tag + = ( P "*" ^ -2 ) + * space ^ 0 + * ( "[" * ( 1 - P "]" ) ^ 0 * "]" ) ^ 0 + * space ^ 0 + * tex_arg + * space ^ 0 + * tex_arg +% \end{macrocode} +% +% % \bigskip % We scan the definition of the language (i.e. the table |def_table|) in order % to detect the potential key |sensitive|. Indeed, we have to catch that key % before the treatment of the keywords of the language. We will also look for -% the potential keys |alsodigit| and |alsoletter|. +% the potential keys |alsodigit|, |alsoletter| and |tag|. % \begin{macrocode} local sensitive = true - for _ , x in ipairs ( def_table ) - do if x[1] == "sensitive" - then if x[2] == nil or ( P "true" ) : match ( x[2] ) - then sensitive = true - else if ( P "false" ) : match ( x[2] ) then sensitive = false end - end - end - if x[1] == "alsodigit" then x[2] : gsub ( "." , add_to_digit ) end - if x[1] == "alsoletter" then x[2] : gsub ( "." , add_to_letter ) end + local left_tag , right_tag + for _ , x in ipairs ( def_table ) do + if x[1] == "sensitive" then + if x[2] == nil or ( P "true" ) : match ( x[2] ) then + sensitive = true + else + if ( P "false" + P "f" ) : match ( x[2] ) then sensitive = false end + end + end + if x[1] == "alsodigit" then x[2] : gsub ( "." , add_to_digit ) end + if x[1] == "alsoletter" then x[2] : gsub ( "." , add_to_letter ) end + if x[1] == "tag" then + left_tag , right_tag = args_for_tag : match ( x[2] ) + end end % \end{macrocode} % Now, the \textsc{lpeg} for the numbers. Of course, it uses |digit| previously @@ -7250,11 +7355,6 @@ function piton.new_language ( lang , definition ) % Now, we scan the definition of the language (i.e. the table |def_table|) for % the keywords. % -% The following LPEG catches the optional argument (between square brackets) in -% first position. -% \begin{macrocode} - local option = "[" * C ( ( 1 - P "]" ) ^ 0 ) * "]" -% \end{macrocode} % % The following LPEG does \emph{not} catch the optional argument between square % brackets in first position. @@ -7280,28 +7380,44 @@ function piton.new_language ( lang , definition ) end local Keyword = P ( false ) % \end{macrocode} -% Now, we actually treat all the keywords. +% Now, we actually treat all the keywords and also the key |moredirectives|. % \begin{macrocode} for _ , x in ipairs ( def_table ) - do if x[1] == "morekeywords" or x[1] == "otherkeywords" then - local keywords = P ( false ) - for _ , word in ipairs ( split_clist : match ( x[2] ) ) - do if sensitive + do if x[1] == "morekeywords" + or x[1] == "otherkeywords" + or x[1] == "moredirectives" + or x[1] == "moretexcs" + then + local keywords = P ( false ) +% \end{macrocode} +% \begin{macrocode} + local style = "\\PitonStyle{Keyword}" + if x[1] == "moredirectives" then style = "\\PitonStyle{directive}" end + style = tex_option_arg : match ( x[2] ) or style + local n = tonumber (style ) + if n then + if n > 1 then style = "\\PitonStyle{Keyword" .. style .. "}" end + end +% \end{macrocode} +% \begin{macrocode} + for _ , word in ipairs ( split_clist : match ( x[2] ) ) do + if x[1] == "moretexcs" then + keywords = Q ( "\\" .. word ) + keywords + else + if sensitive % \end{macrocode} % The documentation of \pkg{lstlistings} specifies that, for the key % |otherkeywords|, if a keyword is a prefix of another keyword, then the prefix % must appear first. However, for the \text{lpeg}, it's rather the contrary. % That's why, here, we add the new element \emph{on the left}. % \begin{macrocode} - then keywords = Q ( word ) + keywords - else keywords = keyword_to_lpeg ( word ) + keywords - end + then keywords = Q ( word ) + keywords + else keywords = keyword_to_lpeg ( word ) + keywords + end + end end Keyword = Keyword + - Lc ( "{" - .. ( option : match ( x[2] ) or "\\PitonStyle{Keyword}" ) - .. "{" ) - * keywords * Lc "}}" + Lc ( "{" .. style .. "{" ) * keywords * Lc "}}" end if x[1] == "keywordsprefix" then local prefix = ( ( C ( 1 - P " " ) ^ 1 ) * P " " ^ 0 ) : match ( x[2] ) @@ -7310,50 +7426,57 @@ function piton.new_language ( lang , definition ) end % \end{macrocode} % +% % \bigskip % Now, we scan the definition of the language (i.e. the table |def_table|) for % the strings. % \begin{macrocode} local long_string = P ( false ) local LongString = P (false ) - local args = "[" * C ( ( 1 - P "]" ) ^ 0 ) * "]" - * space ^ 0 - * ( "[" * C ( ( 1 - P "]" ) ^ 0 ) * "]" + Cc ( nil ) ) - * space ^ 0 - * ( "{" * C ( ( 1 - P "}" ) ^ 0 ) * "}" + C ( 1 ) ) local central_pattern = P ( false ) - for _ , x in ipairs ( def_table ) - do if x[1] == "morestring" then - arg1 , arg2 , arg3 = args : match ( x[2] ) - arg2 = arg2 or "\\PitonStyle{String.Long}" - if arg1 == "b" then - central_pattern = Q ( ( P ( "\\" .. arg3 ) + 1 - S ( " \r" .. arg3 ) ) ^ 1 ) - end - if arg1 == "d" then - central_pattern = Q ( ( P ( arg3 .. arg3 ) + 1 - S ( " \r" .. arg3 ) ) ^ 1 ) - end - if arg1 == "bd" then - central_pattern = - Q ( ( P ( arg3 .. arg3 ) + P ( "\\" .. arg3 ) + 1 - S ( " \r" .. arg3 ) ) ^ 1 ) - end - if arg1 == "m" then - central_pattern = Q ( ( P ( arg3 .. arg3 ) + 1 - S ( " \r" .. arg3 ) ) ^ 1 ) - end - if arg1 == "m" - then prefix = P ( false ) - else prefix = lpeg.B ( 1 - letter - ")" - "]" ) - end + for _ , x in ipairs ( def_table ) do + if x[1] == "morestring" then + arg1 , arg2 , arg3 , arg4 = args_for_morekeywords : match ( x[2] ) + arg2 = arg2 or "\\PitonStyle{String.Long}" + if arg1 == "s" then + long_string = + Q ( arg3 ) + * ( Q ( ( 1 - P ( arg4 ) - S "$\r" ) ^ 1 ) -- $ + + EOL + ) ^ 0 + * Q ( arg4 ) + else + central_pattern = 1 - S ( " \r" .. arg3 ) + if arg1 : match "b" then + central_pattern = P ( "\\" .. arg3 ) + central_pattern + end +% \end{macrocode} +% In fact, the specifier |d| is point-less: when it is not in force, it's still +% possible to double the delimiter with a correct behaviour of \pkg{piton} +% since, in that case, \pkg{piton} will compose \emph{two} contiguous strings... +% \begin{macrocode} + if arg1 : match "d" or arg1 == "m" then + central_pattern = P ( arg3 .. arg3 ) + central_pattern + end + if arg1 == "m" + then prefix = P ( false ) + else prefix = lpeg.B ( 1 - letter - ")" - "]" ) + end % \end{macrocode} % First, we create |long_string| because we need that \textsc{lpeg} in the % nested comments. % \begin{macrocode} - long_string = long_string + - prefix * ( Q ( arg3 ) * ( VisualSpace + central_pattern + EOL ) ^ 0 * Q ( arg3 ) ) - LongString = LongString + - Ct ( Cc "Open" * Cc ( "{" .. arg2 .. "{" ) * Cc "}}" ) - * long_string - * Ct ( Cc "Close" ) - end + long_string = long_string + + prefix + * Q ( arg3 ) + * ( VisualSpace + Q ( central_pattern ^ 1 ) + EOL ) ^ 0 + * Q ( arg3 ) + end + LongString = LongString + + Ct ( Cc "Open" * Cc ( "{" .. arg2 .. "{" ) * Cc "}}" ) + * long_string + * Ct ( Cc "Close" ) + end end local braces = Compute_braces ( String ) @@ -7365,70 +7488,122 @@ function piton.new_language ( lang , definition ) % \end{macrocode} % % \bigskip -% Now, we deal with the comments. +% Now, we deal with the comments and the delims. % \begin{macrocode} - local Comment = P ( false ) + local CommentDelim = P ( false ) - local args = "[" * C ( ( 1 - P "]" ) ^ 0 ) * "]" - * space ^ 0 - * ( "[" * C ( ( 1 - P "]" ) ^ 0 ) * "]" + Cc ( nil ) ) - * space ^ 0 - * ( "{" * C ( ( 1 - P "}" ) ^ 0 ) * "}" + C ( 1 ) ) - * space ^ 0 - * ( "{" * C ( ( 1 - P "}" ) ^ 0 ) * "}" + Cc ( nil ) ) - - for _ , x in ipairs ( def_table ) - do if x[1] == "morecomment" - then local arg1 , arg2 , arg3 , arg4 = args : match ( x[2] ) - arg2 = arg2 or "\\PitonStyle{Comment}" - if arg1 == "l" then - if arg3 == [[\#]] then arg3 = "#" end -- mandatory - Comment = Comment + - Ct ( Cc "Open" - * Cc ( "{" .. arg2 .. "{" ) * Cc "}}" ) - * Q ( arg3 ) - * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 -- $ - * Ct ( Cc "Close" ) - * ( EOL + -1 ) - end - if arg1 == "s" then - Comment = Comment + - Ct ( Cc "Open" * Cc ( "{" .. arg2 .. "{" ) * Cc "}}" ) - * Q ( arg3 ) - * ( - CommentMath - + Q ( ( 1 - P ( arg4 ) - S "$\r" ) ^ 1 ) -- $ - + EOL - ) ^ 0 - * Q ( arg4 ) - * Ct ( Cc "Close" ) - end - if arg1 == "n" then - Comment = Comment + - Ct ( Cc "Open" * Cc ( "{" .. arg2 .. "{" ) * Cc "}}" ) - * P { "A" , - A = Q ( arg3 ) - * ( V "A" - + Q ( ( 1 - P ( arg3 ) - P ( arg4 ) - - S "\r$\"" ) ^ 1 ) -- $ - + long_string - + "$" -- $ - * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1 ) --$ - * "$" -- $ - + EOL - ) ^ 0 - * Q ( arg4 ) - } - * Ct ( Cc "Close" ) - end + for _ , x in ipairs ( def_table ) do + if x[1] == "morecomment" then + local arg1 , arg2 , other_args = args_for_morecomment : match ( x[2] ) + arg2 = arg2 or "\\PitonStyle{Comment}" +% \end{macrocode} +% If the letter |i| is present in the first argument (eg: +% |morecomment = [si]{(*}{*)}|, then the corresponding comments are discarded. +% \begin{macrocode} + if arg1 : match "i" then arg2 = "\\PitonStyle{Discard}" end + if arg1 : match "l" then + local arg3 = ( tex_braced_arg + C ( P ( 1 ) ^ 0 * -1 ) ) + : match ( other_args ) + if arg3 == [[\#]] then arg3 = "#" end -- mandatory + CommentDelim = CommentDelim + + Ct ( Cc "Open" + * Cc ( "{" .. arg2 .. "{" ) * Cc "}}" ) + * Q ( arg3 ) + * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 -- $ + * Ct ( Cc "Close" ) + * ( EOL + -1 ) + else + local arg3 , arg4 = + ( tex_arg * space ^ 0 * tex_arg ) : match ( other_args ) + if arg1 : match "s" then + CommentDelim = CommentDelim + + Ct ( Cc "Open" * Cc ( "{" .. arg2 .. "{" ) * Cc "}}" ) + * Q ( arg3 ) + * ( + CommentMath + + Q ( ( 1 - P ( arg4 ) - S "$\r" ) ^ 1 ) -- $ + + EOL + ) ^ 0 + * Q ( arg4 ) + * Ct ( Cc "Close" ) + end + if arg1 : match "n" then + CommentDelim = CommentDelim + + Ct ( Cc "Open" * Cc ( "{" .. arg2 .. "{" ) * Cc "}}" ) + * P { "A" , + A = Q ( arg3 ) + * ( V "A" + + Q ( ( 1 - P ( arg3 ) - P ( arg4 ) + - S "\r$\"" ) ^ 1 ) -- $ + + long_string + + "$" -- $ + * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1 ) --$ + * "$" -- $ + + EOL + ) ^ 0 + * Q ( arg4 ) + } + * Ct ( Cc "Close" ) + end + end + end +% \end{macrocode} +% For the keys |moredelim|, we have to add another argument in first position, +% equal to |*| or |**|. +% \begin{macrocode} + if x[1] == "moredelim" then + local arg1 , arg2 , arg3 , arg4 , arg5 + = args_for_moredelims : match ( x[2] ) + local MyFun = Q + if arg1 == "*" or arg1 == "**" then + MyFun = function ( x ) return K ( 'ParseAgain.noCR' , x ) end + end + local left_delim + if arg2 : match "i" then + left_delim = P ( arg4 ) + else + left_delim = Q ( arg4 ) end + if arg2 : match "l" then + CommentDelim = CommentDelim + + Ct ( Cc "Open" * Cc ( "{" .. arg3 .. "{" ) * Cc "}}" ) + * left_delim + * ( MyFun ( ( 1 - P "\r" ) ^ 1 ) ) ^ 0 + * Ct ( Cc "Close" ) + * ( EOL + -1 ) + end + if arg2 : match "s" then + local right_delim + if arg2 : match "i" then + right_delim = P ( arg5 ) + else + right_delim = Q ( arg5 ) + end + CommentDelim = CommentDelim + + Ct ( Cc "Open" * Cc ( "{" .. arg3 .. "{" ) * Cc "}}" ) + * left_delim + * ( MyFun ( ( 1 - P ( arg5 ) - "\r" ) ^ 1 ) + EOL ) ^ 0 + * right_delim + * Ct ( Cc "Close" ) + end + end end local Delim = Q ( S "{[()]}" ) - local Punct = Q ( S ",:;!\\'\"" ) - + local Punct = Q ( S "=,:;!\\'\"" ) +% \end{macrocode} +% +% +% \begin{macrocode} +% \end{macrocode} +% +% +% \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 + Tab @@ -7436,18 +7611,33 @@ function piton.new_language ( lang , definition ) + CommentLaTeX + Beamer + DetectedCommands - + Comment + + CommentDelim + Delim + LongString - -- should maybe be after the following line! + Keyword * ( Space + Punct + Delim + EOL + -1 ) + Punct + K ( 'Identifier' , letter * alphanum ^ 0 ) + Number + Word - +% \end{macrocode} +% +% The \textsc{lpeg} |LPEG1[lang]| is used to reformat small elements, for +% example the arguments of the ``detected commands''. +% \begin{macrocode} LPEG1[lang] = Main ^ 0 - +% \end{macrocode} +% +% +% \bigskip +% If the key |tag| has been used, then |left_tag| (and also |right_tag|) is non nil. +% \begin{macrocode} + if left_tag then + end +% \end{macrocode} +% +% +% The \textsc{lpeg} |LPEG2[lang]| is used to format general chunks of code. +% \begin{macrocode} LPEG2[lang] = Ct ( ( space ^ 0 * P "\r" ) ^ -1 @@ -7458,11 +7648,64 @@ function piton.new_language ( lang , definition ) * -1 * Lc '\\@@_end_line:' ) - +% \end{macrocode} +% +% +% \begin{macrocode} + if left_tag then + local Tag = Q ( left_tag * other ^ 0 ) + * ( ( ( 1 - P ( right_tag ) ) ^ 0 ) + / ( function ( x ) return LPEG0[lang] : match ( x ) end ) ) + * Q ( right_tag ) + MainWithoutTag + = space ^ 1 * -1 + + space ^ 0 * EOL + + Space + + Tab + + Escape + EscapeMath + + CommentLaTeX + + Beamer + + DetectedCommands + + CommentDelim + + Delim + + LongString + + Keyword * ( Space + Punct + Delim + EOL + -1 ) + + Punct + + K ( 'Identifier' , letter * alphanum ^ 0 ) + + Number + + Word + LPEG0[lang] = MainWithoutTag ^ 0 + MainWithTag + = space ^ 1 * -1 + + space ^ 0 * EOL + + Space + + Tab + + Escape + EscapeMath + + CommentLaTeX + + Beamer + + DetectedCommands + + CommentDelim + + Tag + + Delim + + Punct + + K ( 'Identifier' , letter * alphanum ^ 0 ) + + Word + LPEG1[lang] = MainWithTag ^ 0 + LPEG2[lang] = + Ct ( + ( space ^ 0 * P "\r" ) ^ -1 + * BeamerBeginEnvironments + * Lc '\\@@_begin_line:' + * SpaceIndentation ^ 0 + * LPEG1[lang] + * -1 + * Lc '\\@@_end_line:' + ) + end end % % \end{macrocode} -% +% % % % \vspace{1cm} -- cgit v1.2.3