diff options
Diffstat (limited to 'macros/luatex/latex/piton/piton.dtx')
-rw-r--r-- | macros/luatex/latex/piton/piton.dtx | 878 |
1 files changed, 663 insertions, 215 deletions
diff --git a/macros/luatex/latex/piton/piton.dtx b/macros/luatex/latex/piton/piton.dtx index c40a3c8631..ec18e80eaa 100644 --- a/macros/luatex/latex/piton/piton.dtx +++ b/macros/luatex/latex/piton/piton.dtx @@ -59,6 +59,13 @@ \NewDocumentCommand{\indexenv}{m}{\index{#1@\texttt{\{#1\}}}} +\NewDocumentCommand{\Definition}{m} + {{\setlength{\fboxsep}{1pt}\colorbox{gray!20}{\ttfamily \vphantom{gl}#1}}} + +\NewDocumentCommand{\DefinitionCommand}{m} + {{\setlength{\fboxsep}{1pt}\colorbox{gray!20}{\ttfamily + \vphantom{gl}\textbackslash #1}}} + \PitonOptions{gobble=2} @@ -72,12 +79,12 @@ % \iffalse %<*STY> % \fi -\def\PitonFileVersion{2.8} -\def\PitonFileDate{2024/04/14} +\def\PitonFileVersion{3.0b} +\def\PitonFileDate{2024/05/23} % \iffalse %</STY> %<*LUA> -piton_version = "2.8" -- 2024/04/14 +piton_version = "3.0b" -- 2024/05/23 %</LUA> %\fi % @@ -90,9 +97,8 @@ piton_version = "2.8" -- 2024/04/14 % \maketitle % % \begin{abstract} -% The package \pkg{piton} provides tools to typeset computer listings in Python, -% OCaml, C and SQL with syntactic highlighting by using the Lua library LPEG. It -% requires LuaLaTeX. +% The package \pkg{piton} provides tools to typeset computer listings, with +% syntactic highlighting, by using the Lua library LPEG. It requires LuaLaTeX. % \end{abstract} % % @@ -103,12 +109,12 @@ piton_version = "2.8" -- 2024/04/14 % The package \pkg{piton} uses the Lua library LPEG\footnote{LPEG is a % 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, C -% or SQL listings and typesets them with syntactic highlighting. Since it uses -% the Lua of LuaLaTeX, it works with |lualatex| only (and won't work with the -% other engines: |latex|, |pdflatex| and |xelatex|). It does not use external -% program and the compilation does not require |--shell-escape|. The compilation -% is very fast since all the parsing is done by the library LPEG, written in C. +% \url{http://www.inf.puc-rio.br/~roberto/lpeg/}} for parsing informatic +% listings and typesets them with syntactic highlighting. Since it uses the Lua +% of LuaLaTeX, it works with |lualatex| only (and won't work with the other +% engines: |latex|, |pdflatex| and |xelatex|). It does not use external program +% and the compilation does not require |--shell-escape|. The compilation is very +% fast since all the parsing is done by the library LPEG, written in C. % % \bigskip % Here is an example of code typeset by \pkg{piton}, with the environment |{Piton}|. @@ -134,6 +140,15 @@ piton_version = "2.8" -- 2024/04/14 % s += (-1)**k/(2*k+1)*x**(2*k+1) % return s % \end{Piton} +% +% +% \bigskip +% The main alternatives to the package \pkg{piton} are probably the packages +% \pkg{listings} and \pkg{minted}. +% +% \bigskip +% The name of this extension (\pkg{piton}) has been chosen arbitrarily by +% reference to the pitons used by the climbers in alpinism. % % % \section{Installation} @@ -158,13 +173,22 @@ piton_version = "2.8" -- 2024/04/14 % If, at the end of the preamble, the package \pkg{xcolor} has not been loaded % (by the final user or by another package), \pkg{piton} loads \pkg{xcolor} with % the instruction |\usepackage{xcolor}| (that is to say without any option). -% The package \pkg{piton} doesn't load any other package. +% The package \pkg{piton} doesn't load any other package. It does not any +% exterior program. % % \subsection{Choice of the computer language} % -% 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. p.~\pageref{minimal}. +% The package \pkg{piton} supports two kinds of languages: +% \begin{itemize} +% \item the languages natively supported by \pkg{piton}, which are Python, OCaml, +% C~(in fact \CC), SQL and a language called |minimal|\footnote{That language +% |minimal| may be used to format pseudo-codes: cf. p.~\pageref{minimal}}; +% \item the languages defined by the final user by using the built-in command +% |\NewPitonLanguage| described p.~\pageref{NewPitonLanguage} (the parsers of +% those languages can't be as precise as those of the native languages supported +% by \pkg{piton}). +% \end{itemize} +% % % \smallskip % By default, the language used is Python. @@ -172,10 +196,15 @@ piton_version = "2.8" -- 2024/04/14 % \smallskip % \index{language (key)} % It's possible to change the current language with the command |\PitonOptions| -% and its key |language|: |\PitonOptions{language = C}|. +% and its key |language|: |\PitonOptions{language = OCaml}|. +% +% \smallskip +% In fact, for \pkg{piton}, the names of the informatic languages are always +% \textbf{case-insensitive}. In this example, we might have written |Ocaml| or +% |ocaml|. % % \smallskip -% For the developpers, let's say that the name of the current language is stored +% For the developers, 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 @@ -186,7 +215,7 @@ piton_version = "2.8" -- 2024/04/14 % % \indexenv{Piton} % -% The package \pkg{piton} provides several tools to typeset Python code: the +% The package \pkg{piton} provides several tools to typeset Python codes: the % command |\piton|, the environment |{Piton}| and the command |\PitonInputFile|. % % \begin{itemize}\setlength{\fboxsep}{1pt} @@ -211,20 +240,16 @@ piton_version = "2.8" -- 2024/04/14 % 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}{\bfseries New 2.8}\par\nobreak -% -% -% The key |path| of the command |\PitonOptions| specifies a \emph{list} of -% pathes where the files included by |\PitonInputFile| will be searched. That -% list is comma separated. +% The key \Definition{path} of the command |\PitonOptions| specifies a +% \emph{list} of paths where the files included by |\PitonInputFile| will be +% searched. That list is comma separated. % % The extension \pkg{piton} also provides the commands % \colorbox{gray!20}{\ttfamily \textbackslash PitonInputFileT}, % \colorbox{gray!20}{\ttfamily \textbackslash PitonInputFileF} and % \colorbox{gray!20}{\ttfamily \textbackslash PitonInputFileTF} with % supplementary arguments corresponding to the letters~|T| and~|F|. Those -% arguments will be exectued if the file to include has been found (letter~|T|) +% arguments will be executed if the file to include has been found (letter~|T|) % or not found (letter~|F|). % \end{itemize} % @@ -290,7 +315,7 @@ piton_version = "2.8" -- 2024/04/14 % \piton{s = 'A string'}.} % % \bigskip -% \item {\color{blue} \textsf{Syntaxe} \verb!\piton|...|!}\par\nobreak +% \item {\color{blue} \textsf{Syntax} \verb!\piton|...|!}\par\nobreak % % When the argument of the command |\piton| is provided between two identical % characters, that argument is taken in a \emph{verbatim mode}. Therefore, with @@ -323,8 +348,6 @@ piton_version = "2.8" -- 2024/04/14 % \subsection{The keys of the command \textbackslash PitonOptions} % % -% \NewDocumentCommand{\Definition}{m} -% {{\setlength{\fboxsep}{1pt}\colorbox{gray!20}{\ttfamily \vphantom{gl}#1}}} % % \indexcommand{PitonOptions} % @@ -337,7 +360,7 @@ piton_version = "2.8" -- 2024/04/14 % square brackets). % % \begin{itemize} -% \item The key \Definition{language} speficies which computer language is +% \item The key \Definition{language} specifies which computer language is % considered (that key is case-insensitive). Five values are allowed : % |Python|, |OCaml|, |C|, |SQL| and |minimal|. The initial value is |Python|. % @@ -346,7 +369,7 @@ piton_version = "2.8" -- 2024/04/14 % % \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 +% the process of highlighting 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 @@ -426,7 +449,7 @@ piton_version = "2.8" -- 2024/04/14 % % % \item \index{left-margin} The key \Definition{left-margin} corresponds to a -% margin on the left. That key may be useful in conjonction with the key +% margin on the left. That key may be useful in conjunction with the key % |line-numbers| if one does not want the numbers in an overlapping position on % the left. % @@ -554,10 +577,11 @@ piton_version = "2.8" -- 2024/04/14 % % \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 -% group.\footnote{We remind that a LaTeX environment is, in particular, a TeX group.} +% The package \pkg{piton} provides the command +% \DefinitionCommand{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 group.\footnote{We remind that +% a LaTeX environment is, in particular, a TeX group.} % % \bigskip % \indexcommand{SetPitonStyle} @@ -601,8 +625,9 @@ piton_version = "2.8" -- 2024/04/14 % % \bigskip % \indexcommand{PitonStyle} -% The command |\PitonStyle| takes in as argument the name of a style and allows -% to retrieve the value (as a list of LaTeX instructions) of that style. +% The command \DefinitionCommand{PitonStyle} takes in as argument the name of a +% style and allows to retrieve the value (as a list of LaTeX instructions) of +% that style. % % \smallskip % For example, it's possible to write |{\PitonStyle{Keyword}{function}}| and we @@ -626,11 +651,12 @@ piton_version = "2.8" -- 2024/04/14 % \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.). +% informatic language they use (Python, C, OCaml, etc. or a language defined by +% the command |\NewPitonLanguage|). % % \bigskip % 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 +% language 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.} @@ -694,7 +720,7 @@ piton_version = "2.8" -- 2024/04/14 % \SetPitonStyle{Name.Function = \MyDefFunction, ~emphase#UserFunction@ = \MyUserFunction} % \end{Verbatim} % -% \bigskip +% \smallskip % % \begin{Piton} % def transpose(v,i,j): @@ -710,6 +736,10 @@ piton_version = "2.8" -- 2024/04/14 % % \endgroup % +% \medskip +% (Some \textsc{pdf} viewers display a frame around the clickable word +% |transpose| but other do not.) +% % \PitonClearUserFunctions[Python] % % \bigskip @@ -717,12 +747,12 @@ piton_version = "2.8" -- 2024/04/14 % 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 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.} +% list : it's the command \DefinitionCommand{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} @@ -736,9 +766,10 @@ piton_version = "2.8" -- 2024/04/14 % |\newenvironment| (of standard LaTeX) or |\NewDocumentEnvironment| (of % LaTeX3). % -% That's why \pkg{piton} provides a command |\NewPitonEnvironment|. That -% command takes in three mandatory arguments. - +% That's why \pkg{piton} provides a command +% \DefinitionCommand{NewPitonEnvironment}. That command takes in three mandatory +% arguments. +% % That command has the same syntax as the classical environment % |\NewDocumentEnvironment|.\footnote{However, the specifier of argument |b| % (used to catch the body of the environment as a LaTeX argument) is @@ -783,7 +814,161 @@ piton_version = "2.8" -- 2024/04/14 % return x*x % \end{Python} % +% \section{Definition of new languages with the syntax of listings} +% +% \indexcommand{NewPitonLanguage} +% \label{NewPitonLanguage} +% \index{listings@\pkg{listings} (extension)} +% \colorbox{yellow!50}{\textbf{New 3.0}} +% +% \medskip +% The package \pkg{listings} is a famous LaTeX package to format informatic +% listings. +% +% That package provides a command |\lstdefinelanguage| which allows the user to +% define new languages. That command is also used by \pkg{listings} itself to +% provide the definition of the predefined languages in \pkg{listings} (in fact, +% for this task, \pkg{listings} uses a command called |\lst@definelanguage| but +% that command has the same syntax as |\lstdefinelanguage|). +% +% \medskip +% The package \pkg{piton} provides a command +% \DefinitionCommand{NewPitonLanguage} to define new languages (available in +% |\piton|, |{Piton}|, etc.) with a syntax which is almost the same as the +% syntax of~|\lstdefinelanguage|. +% +% Let's precise that \pkg{piton} does \emph{not} use that command to define the +% languages provided natively (Python, OCaml, \CC, SQL and |minimal|), which +% allows more powerful parsers. +% +% \medskip +% For example, in the file |lstlang1.sty|, which is one of the definition files +% of \pkg{listings}, we find the following instructions (in version 1.10a). +% +%\begin{Verbatim}[formatcom=\small\color{gray}] +% \lst~@definelanguage{Java}% +% {morekeywords={abstract,boolean,break,byte,case,catch,char,class,% +% const,continue,default,do,double,else,extends,false,final,% +% finally,float,for,goto,if,implements,import,instanceof,int,% +% interface,label,long,native,new,null,package,private,protected,% +% public,return,short,static,super,switch,synchronized,this,throw,% +% throws,transient,true,try,void,volatile,while},% +% sensitive,% +% morecomment=[l]//,% +% morecomment=[s]{/*}{*/},% +% morestring=[b]",% +% morestring=[b]',% +% }[keywords,comments,strings] +% \end{Verbatim} +% +% \medskip +% In order to define a language called |Java| for \pkg{piton}, one has only to +% write the following code {\bfseries where the last argument of +% |\lst@definelanguage|, between square brackets, has been discarded} (in fact, +% the symbols \verb+%+ may be deleted without any problem). +% +% \begin{Verbatim}[formatcom=\small\color{gray}] +% ~emphase#\NewPitonLanguage@{Java}% +% {morekeywords={abstract,boolean,break,byte,case,catch,char,class,% +% const,continue,default,do,double,else,extends,false,final,% +% finally,float,for,goto,if,implements,import,instanceof,int,% +% interface,label,long,native,new,null,package,private,protected,% +% public,return,short,static,super,switch,synchronized,this,throw,% +% throws,transient,true,try,void,volatile,while},% +% sensitive,% +% morecomment=[l]//,% +% morecomment=[s]{/*}{*/},% +% morestring=[b]",% +% morestring=[b]',% +% } +% \end{Verbatim} +% +% +% \NewPitonLanguage{Java} +% {morekeywords={abstract,boolean,break,byte,case,catch,char,class, +% const,continue,default,do,double,else,extends,false,final, +% finally,float,for,goto,if,implements,import,instanceof,int, +% interface,label,long,native,new,null,package,private,protected, +% public,return,short,static,super,switch,synchronized,this,throw, +% throws,transient,true,try,void,volatile,while}, +% sensitive, +% morecomment=[l]//, +% morecomment=[s]{/*}{*/}, +% morestring=[b]", +% morestring=[b]', +% } +% +% \medskip +% It's possible to use the language Java like any other language defined by +% \pkg{piton}. +% +% Here is an example of code formatted in an environment |{Piton}| with +% the key |language=Java|.\footnote{We recall that, for \pkg{piton}, the names +% of the informatic languages are case-insensitive. Hence, it's possible to +% write, for instance, |language=java|.} +% +% +% \bigskip +% \begingroup +% \small +% \PitonOptions{split-on-empty-lines} +% \begin{Piton}[language = java] +% public class Cipher { // Caesar cipher +% public static void main(String[] args) { +% String str = "The quick brown fox Jumped over the lazy Dog"; +% System.out.println( Cipher.encode( str, 12 )); +% System.out.println( Cipher.decode( Cipher.encode( str, 12), 12 )); +% } +% +% public static String decode(String enc, int offset) { +% return encode(enc, 26-offset); +% } +% +% public static String encode(String enc, int offset) { +% offset = offset % 26 + 26; +% StringBuilder encoded = new StringBuilder(); +% for (char i : enc.toCharArray()) { +% if (Character.isLetter(i)) { +% if (Character.isUpperCase(i)) { +% encoded.append((char) ('A' + (i - 'A' + offset) % 26 )); +% } else { +% encoded.append((char) ('a' + (i - 'a' + offset) % 26 )); +% } +% } else { +% encoded.append(i); +% } +% } +% return encoded.toString(); +% } +% } +% \end{Piton} +% \endgroup +% +% \bigskip + +% The keys of the command |\lstdefinelanguage| of \pkg{listings} supported by |\NewPitonLanguage| are: +% |morekeywords|, |otherkeywords|, |sensitive|, |keywordsprefix|, |moretexcs|, +% |morestring| (with the letters |b|, +% |d|, |s| and |m|), |morecomment| (with the letters |i|, |l|, |s| and |n|), +% |moredelim| (with the letters |i|, +% |l|, |s|, |*| and |**|), |moredirectives|, |tag|, |alsodigit|, |alsoletter| +% and |alsoother|. +% +% For the description of those keys, we redirect the reader to the documentation +% of the package \pkg{listings} (type |texdoc| |listings| in a terminal). +% +% \bigskip +% For example, here is a language called ``LaTeX'' to format LaTeX chunks of codes: + +% \begin{Verbatim} +% \NewPitonLanguage{LaTeX}{keywordsprefix = \ , alsoletter = ~@_ } +% \end{Verbatim} % +% Initially, the characters |@| and |_| are considered as letters because, in +% many informatic languages, they are allowed in the keywords and the names of +% the identifiers. With \verb|alsoletter = @_|, we retrieve them from the +% category of the letters. +% % \section{Advanced features} % % \subsection{Page breaks and line breaks} @@ -800,10 +985,9 @@ piton_version = "2.8" -- 2024/04/14 % and |splittable| to allow such breaks. % % \begin{itemize} -% \item \colorbox{yellow!50}{\textbf{New 2.7}}\par\nobreak -% The key \Definition{split-on-empty-lines} allows breaks on the empty +% \item The key \Definition{split-on-empty-lines} allows breaks on the empty % lines\footnote{The ``empty lines'' are the lines which contains only spaes.} in -% the listing. In the informatic listings, the empty lines usually seperate the +% the listing. In the informatic listings, the empty lines usually separate the % definitions of the informatic functions and it's pertinent to allow breaks % between these functions. % @@ -858,7 +1042,7 @@ piton_version = "2.8" -- 2024/04/14 % \Definition{break-lines-in-Piton}, the line breaks are allowed in the % environment |{Piton}| (hence the capital letter |P| in the name) and in the % listings produced by |\PitonInputFile|. -% \item \index{break-lines} The key \Definition{break-lines} is a conjonction of +% \item \index{break-lines} The key \Definition{break-lines} is a conjunction of % the two previous keys. % \end{itemize} % @@ -919,7 +1103,7 @@ piton_version = "2.8" -- 2024/04/14 % \label{part-of-a-file} % \indexcommand{PitonInputFile} % -% The command |\PitonInputFile| inserts (with formating) the content of a file. +% The command |\PitonInputFile| inserts (with formatting) the content of a file. % In fact, it's possible to insert only \emph{a part} of that file. Two % mechanisms are provided in this aim. % \begin{itemize} @@ -1059,16 +1243,16 @@ piton_version = "2.8" -- 2024/04/14 % % \label{SetPitonIdentifier} % -% The command |\SetPitonIdentifier| allows to change the formatting of some -% identifiers. +% The command \DefinitionCommand{SetPitonIdentifier} allows to change the +% formatting of some identifiers. % % \smallskip % That command takes in three arguments: % % \begin{itemize} -% \item The optionnal argument (within square brackets) specifies the informatic -% langage. If this argument is not present, the tunings done by -% |\SetPitonIdentifier| will apply to all the informatic langages of +% \item The optional argument (within square brackets) specifies the informatic +% language. If this argument is not present, the tunings done by +% |\SetPitonIdentifier| will apply to all the informatic languages of % \pkg{piton}.\footnote{We recall, that, in the package \pkg{piton}, the % names of the informatic languages are case-insensitive.} % @@ -1172,7 +1356,7 @@ piton_version = "2.8" -- 2024/04/14 % \item It's also possible to insert LaTeX code almost everywhere in a Python listing. % \end{itemize} % -% One should aslo remark that, when the extension \pkg{piton} is used with the +% One should also remark that, when the extension \pkg{piton} is used with the % class \cls{beamer}, \pkg{piton} detects in |{Piton}| many commands and % environments of Beamer: cf. \ref{beamer} p.~\pageref{beamer}. % @@ -1186,10 +1370,10 @@ piton_version = "2.8" -- 2024/04/14 % comments. % % \begin{itemize} -% \item It's possible to change the syntatic mark (which, by default, is |#>|). -% For this purpose, there is a key |comment-latex| available only in the -% preamble of the document, allows to choice the characters which, -% preceded by |#|, will be the syntatic marker. +% \item It's possible to change the syntactic mark (which, by default, is |#>|). +% For this purpose, there is a key \Definition{comment-latex} available only in +% the preamble of the document, allows to choice the characters which, preceded +% by |#|, will be the syntactic marker. % % For example, if the preamble contains the following instruction: % @@ -1260,7 +1444,7 @@ piton_version = "2.8" -- 2024/04/14 % \index{detected-commands (key)} % \label{detected-commands} % -% The key |detected-commands| of |\PitonOptions| allow to specify a +% The key \Definition{detected-commands} of |\PitonOptions| allows to specify a % (comma-separated) list of names of LaTeX commands that will be detected % directly by \pkg{piton}. % @@ -1271,7 +1455,7 @@ piton_version = "2.8" -- 2024/04/14 % backslash (eg. |detected-commands = { emph, textbf }|). % % \item These commands must be LaTeX commands with only one (mandatory) argument -% between braces (and these braces must be explicit). +% between braces (and these braces must appear explicitly in the informatic listing). % \end{itemize} % % \medskip @@ -1319,7 +1503,7 @@ piton_version = "2.8" -- 2024/04/14 % 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''. +% possible to achieve our goal with the more general mechanism ``escape''. % % \medskip % We assume that the preamble of the document contains @@ -1375,7 +1559,7 @@ piton_version = "2.8" -- 2024/04/14 % of LaTeX, they are, in particular, composed within a TeX group and therefore, % they can't be used to change the formatting of other lexical units. % -% In the langages where the character \verb|$| does not play a important role, +% In the languages where the character \verb|$| does not play a important role, % it's possible to activate that mechanism ``|escape-math|'' with the character % \verb|$|: % \begin{Verbatim} @@ -1492,7 +1676,7 @@ piton_version = "2.8" -- 2024/04/14 % can't extend on several lines.} of Python are not considered. % % \medskip -% Regarding the fonctions |\alt| and |\temporal| there should be no carriage +% Regarding the functions |\alt| and |\temporal| there should be no carriage % returns in the mandatory arguments of these functions. % % \medskip @@ -1569,7 +1753,7 @@ piton_version = "2.8" -- 2024/04/14 % not be the best choice because \pkg{piton} will, by design, change (most of % the time) the color the different elements of text. One may prefer an environment % |{alertenv}| that will change the background color for the elements to be -% hightlighted. +% highlighted. % % \smallskip % Here is a code that will do that job and add a yellow background. That code @@ -1609,15 +1793,15 @@ piton_version = "2.8" -- 2024/04/14 % package \pkg{footnote} or the package \pkg{footnotehyper}. % % \smallskip -% If \pkg{piton} is loaded with the option |footnote| (with +% If \pkg{piton} is loaded with the option \Definition{footnote} (with % |\usepackage[footnote]{piton}| or with |\PassOptionsToPackage|), the % package \pkg{footnote} is loaded (if it is not yet loaded) and it is used to % extract the footnotes. % % \smallskip -% If \pkg{piton} is loaded with the option |footnotehyper|, the package -% \pkg{footnotehyper} is loaded (if it is not yet loaded) ant it is used to -% extract footnotes. +% If \pkg{piton} is loaded with the option \Definition{footnotehyper}, the +% package \pkg{footnotehyper} is loaded (if it is not yet loaded) ant it is used +% to extract footnotes. % % \smallskip % Caution: The packages \pkg{footnote} and \pkg{footnotehyper} are incompatible. @@ -1641,15 +1825,15 @@ piton_version = "2.8" -- 2024/04/14 % PEP~8), \pkg{piton} accepts the characters of tabulation (that is to say the % characters U+0009) at the beginning of the lines. Each character U+0009 is % replaced by $n$~spaces. The initial value of $n$ is $4$ but it's possible to -% change it with the key |tab-size| of |\PitonOptions|. +% change it with the key \Definition{tab-size} of |\PitonOptions|. % % \smallskip -% There exists also a key |tabs-auto-gobble| which computes the minimal value -% $n$ of the number of consecutive characters U+0009 beginning each (non empty) -% line of the environment |{Piton}| and applies |gobble| with that value of~$n$ -% (before replacement of the tabulations by spaces, of course). Hence, that key -% is similar to the key |auto-gobble| but acts on U+0009 instead of U+0020 -% (spaces). +% There exists also a key \Definition{tabs-auto-gobble} which computes the +% minimal value $n$ of the number of consecutive characters U+0009 beginning +% each (non empty) line of the environment |{Piton}| and applies |gobble| with +% that value of~$n$ (before replacement of the tabulations by spaces, of +% course). Hence, that key is similar to the key |auto-gobble| but acts on +% U+0009 instead of U+0020 (spaces). % % % \bigskip @@ -1682,7 +1866,7 @@ piton_version = "2.8" -- 2024/04/14 % \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. +% in a variable of Lua if it will be used several times. % \end{itemize} % % \medskip @@ -1960,7 +2144,7 @@ piton_version = "2.8" -- 2024/04/14 % \end{Verbatim} % % In that tuning, many values given to the keys are empty: that means that the -% corresponding style won't insert any formating instruction (the element will +% corresponding style won't insert any formatting instruction (the element will % be composed in the standard color, usually in black, etc.). Nevertheless, % those entries are mandatory because the initial value of those keys in % \pkg{piton} is \emph{not} empty. @@ -2291,7 +2475,7 @@ piton_version = "2.8" -- 2024/04/14 % % % \bigskip -% It's possible to automatically capitalize the keywords by modifiying locally +% It's possible to automatically capitalize the keywords by modifying locally % for the language SQL the style |Keywords|. % \begin{Verbatim} % \SetPitonStyle~emphase#[SQL]@{Keywords = \bfseries \MakeUppercase} @@ -2341,6 +2525,38 @@ piton_version = "2.8" -- 2024/04/14 % for pseudo-code. % % \newpage +% \subsection{The languages defined by \textbackslash NewPitonLanguage} +% +% \vspace{1cm} +% The command |\NewPitonLanguage|, which defines new informatic languages with the +% syntax of the extension \pkg{listings}, has been described p.~\pageref{NewPitonLanguage}. +% +% All the languages defined by the command |\NewPitonLanguage| use the same styles. +% \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 defined in |\NewPitonLanguage| by the key |morestring| \\ +% Comment & the comments defined in |\NewPitonLanguage| by the key |morecomment| \\ +% Comment.LaTeX & the comments which are composed by \pkg{piton} as LaTeX code (merely named ``LaTeX comments'' in this document) \\ +% Keyword & the keywords defined in |\NewPitonLanguage| by the keys |morekeywords| +% and |moretexcs| (and also the key |sensitive| which specifies whether +% the keywords are case-sensitive or not) \\ +% Directive & the directives defined in |\NewPitonLanguage| by the key +% |moredirectives| \\ +% Tag & the ``tags'' defines by the key |tag| (the lexical units detected within +% the tag will also be formatted with their own style) \\ +% \bottomrule +% \end{tabularx} +% \end{center} +% +% +% +% \newpage % % \section{Implementation} % @@ -2564,7 +2780,7 @@ piton_version = "2.8" -- 2024/04/14 \@@_msg_new:nnn { piton.lua~not~found } { The~file~'piton.lua'~can't~be~found.\\ - This~eror~is~fatal.\\ + This~error~is~fatal.\\ If~you~want~to~know~how~to~retrieve~the~file~'piton.lua',~type~H~<return>. } { @@ -2591,7 +2807,7 @@ piton_version = "2.8" -- 2024/04/14 % % \medskip % The boolean |\g_@@_footnote_bool| will indicate if the option |footnote| is -% used, but quicky, it will also be set to |true| if the option |footnotehyper| +% used, but quickly, it will also be set to |true| if the option |footnotehyper| % is used. % \begin{macrocode} \bool_new:N \g_@@_footnote_bool @@ -2809,7 +3025,7 @@ piton_version = "2.8" -- 2024/04/14 % \end{macrocode} % % \medskip -% The following token list will contain the (potential) informations to write +% The following token list will contain the (potential) information to write % on the |aux| (to be used in the next compilation). % \begin{macrocode} \tl_new:N \g_@@_aux_tl @@ -2968,7 +3184,7 @@ piton_version = "2.8" -- 2024/04/14 % \medskip % If the key |width| is used with the special value~|min|, we will compute the % maximal width of the lines of an environment |{Piton}| in |\g_@@_tmp_width_dim| -% because we need it for the case of the key |width| is used with the spacial +% because we need it for the case of the key |width| is used with the special % value |min|. We need a global variable because, when the key |footnote| is in % force, each line when be composed in an environment |{savenotes}| and we need % to exit our |\g_@@_tmp_width_dim| from that environment. @@ -3511,7 +3727,7 @@ piton_version = "2.8" -- 2024/04/14 \keys_define:nn { PitonOptions } { % \end{macrocode} -% First, we put keys that should be avalaible only in the preamble. +% First, we put keys that should be available only in the preamble. % \begin{macrocode} detected-commands .code:n = \lua_now:n { piton.addListCommands('#1') } , @@ -3808,8 +4024,134 @@ piton_version = "2.8" -- 2024/04/14 % % \bigskip % \begin{macrocode} -\NewDocumentCommand { \NewPitonLanguage } { m m } - { \lua_now:e { piton.new_language("#1","\lua_escape:n{#2}") } } +\NewDocumentCommand { \NewPitonLanguage } { O { } m ! o } + { + \tl_if_novalue:nTF { #3 } +% \end{macrocode} +% The last argument is provided by curryfication. +% \begin{macrocode} + { \@@_NewPitonLanguage:nnn { #1 } { #2 } } +% \end{macrocode} +% The two last arguments are provided by curryfication. +% \begin{macrocode} + { \@@_NewPitonLanguage:nnnnn { #1 } { #2 } { #3 } } + } +% \end{macrocode} +% +% \bigskip +% The following property list will contain the definitions of the informatic +% languages as provided by the final user. However, if a language is defined +% over another base language, the corresponding list will contain the \emph{whole} +% definition of the language. +% \begin{macrocode} +\prop_new:N \g_@@_languages_prop +% \end{macrocode} +% +% \bigskip +% \begin{macrocode} +\keys_define:nn { NewPitonLanguage } + { + morekeywords .code:n = , + otherkeywords .code:n = , + sensitive .code:n = , + keywordsprefix .code:n = , + moretexcs .code:n = , + morestring .code:n = , + morecomment .code:n = , + moredelim .code:n = , + moredirectives .code:n = , + tag .code:n = , + alsodigit .code:n = , + alsoletter .code:n = , + alsoother .code:n = , + unknown .code:n = \@@_error:n { Unknown~key~NewPitonLanguage } + } +% \end{macrocode} +% +% \bigskip +% The function |\@@_NewPitonLanguage:nnn| will be used when the language is +% \emph{not} defined above a base language (and a base dialect). +% \begin{macrocode} +\cs_new_protected:Npn \@@_NewPitonLanguage:nnn #1 #2 #3 + { +% \end{macrocode} +% We store in |\l_tmpa_tl| the name of the language with the potential dialect, +% that is to say, for example : |[AspectJ]{Java}|. We use |\tl_if_blank:nF| +% because the final user may have written |\NewPitonLanguage[ ]{Java}{...}|. +% \begin{macrocode} + \tl_set:Nx \l_tmpa_tl + { + \tl_if_blank:nF { #1 } { [ \str_lowercase:n { #1 } ] } + \str_lowercase:n { #2 } + } +% \end{macrocode} +% +% The following set of keys is only used to raise an error when a key in unknown! +% \begin{macrocode} + \keys_set:nn { NewPitonLanguage } { #3 } +% \end{macrocode} +% +% We store in LaTeX the definition of the language because some languages may be +% defined with that language as base language. +% \begin{macrocode} + \prop_gput:Non \g_@@_languages_prop \l_tmpa_tl { #3 } +% \end{macrocode} +% The Lua part of the package \pkg{piton} will be loaded in a +% |\AtBeginDocument|. Hence, we will put also in a |\AtBeginDocument| the +% utilisation of the Lua function |piton.new_language| (which does the main job). +% \begin{macrocode} + \exp_args:NV \@@_NewPitonLanguage:nn \l_tmpa_tl { #3 } + } +% \end{macrocode} +% +% \begin{macrocode} +\cs_new_protected:Npn \@@_NewPitonLanguage:nn #1 #2 + { + \hook_gput_code:nnn { begindocument } { . } + { \lua_now:e { piton.new_language("#1","\lua_escape:n{#2}") } } + } +% \end{macrocode} +% +% \bigskip +% Now the case when the language is defined upon a base language. +% \begin{macrocode} +\cs_new_protected:Npn \@@_NewPitonLanguage:nnnnn #1 #2 #3 #4 #5 + { +% \end{macrocode} +% We store in |\l_tmpa_tl| the name of the base language with the dialect, that +% is to say, for example : |[AspectJ]{Java}|. We use |\tl_if_blank:nF| because +% the final user may have used |\NewPitonLanguage[Handel]{C}[ ]{C}{...}| +% \begin{macrocode} + \tl_set:Nx \l_tmpa_tl + { + \tl_if_blank:nF { #3 } { [ \str_lowercase:n { #3 } ] } + \str_lowercase:n { #4 } + } +% \end{macrocode} +% We retrieve in |\l_tmpb_tl| the definition (as provided by the final user) of +% that base language. Caution: |\g_@@_languages_prop| does not contain all the +% languages provided by \pkg{piton} but only those defined by using +% |\NewPitonLanguage|. +% \begin{macrocode} + \prop_get:NoNTF \g_@@_languages_prop \l_tmpa_tl \l_tmpb_tl +% \end{macrocode} +% We can now define the new language by using the previous function. +% \begin{macrocode} + { \@@_NewPitonLanguage:nnno { #1 } { #2 } { #5 } \l_tmpb_tl } + { \@@_error:n { Language~not~defined } } + } +% \end{macrocode} +% +% \bigskip +% \begin{macrocode} +\cs_new_protected:Npn \@@_NewPitonLanguage:nnnn #1 #2 #3 #4 +% \end{macrocode} +% In the following line, we write |#4,#3| and not |#3,#4| because we want that the +% keys which correspond to base language appear before the keys which are added +% in the language we define. +% \begin{macrocode} + { \@@_NewPitonLanguage:nnn { #1 } { #2 } { #4 , #3 } } +\cs_generate_variant:Nn \@@_NewPitonLanguage:nnnn { n n n o } % \end{macrocode} % % \bigskip @@ -4507,14 +4849,15 @@ piton_version = "2.8" -- 2024/04/14 String.Doc , String.Interpol , String.Long , - String.Short , + String.Short , + Tag , TypeParameter , UserFunction , % \end{macrocode} % Now, specific styles for the languages created with |\NewPitonLanguage| with % the syntax of \pkg{listings}. % \begin{macrocode} - directive + Directive } \clist_map_inline:Nn \g_@@_styles_clist @@ -4602,7 +4945,8 @@ piton_version = "2.8" -- 2024/04/14 TypeParameter = \color[HTML]{336666} \itshape , Preproc = \color[HTML]{AA6600} \slshape , Identifier = \@@_identifier:n , - directive = \color[HTML]{AA6600} , + Directive = \color[HTML]{AA6600} , + Tag = \colorbox{gray!10}, UserFunction = , Prompt = , ParseAgain.noCR = \@@_piton_no_cr:n , @@ -4664,7 +5008,7 @@ piton_version = "2.8" -- 2024/04/14 % % % \bigskip -% In particular, we have an highlighting of the indentifiers which are the +% In particular, we have an highlighting of the identifiers which are the % names of Python functions previously defined by the user. Indeed, when a % Python function is defined, the style |Name.Function.Internal| is applied to % that name. We define now that style (you define it directly and you short-cut @@ -4679,7 +5023,7 @@ piton_version = "2.8" -- 2024/04/14 { \PitonStyle { Name.Function } { #1 } } % \end{macrocode} % Now, we specify that the name of the new Python function is a known identifier -% that will be formated with the Piton style |UserFunction|. Of course, +% that will be formatted with the Piton style |UserFunction|. Of course, % here the affectation is global because we have to exit many groups and even % the environments |{Piton}|). % \begin{macrocode} @@ -4787,6 +5131,18 @@ piton_version = "2.8" -- 2024/04/14 % \bigskip % \subsubsection{The error messages of the package} % +% +% \begin{macrocode} +\@@_msg_new:nn { Language~not~defined } + { + Language~not~defined \\ + The~language~'\l_tmpa_tl'~has~not~been~defined~previously.\\ + If~you~go~on,~your~command~\token_to_str:N \NewPitonLanguage\ + will~be~ignored. + } +% \end{macrocode} +% +% % \begin{macrocode} \@@_msg_new:nn { bad~version~of~piton.lua } { @@ -4797,6 +5153,14 @@ piton_version = "2.8" -- 2024/04/14 } % \end{macrocode} % +% \begin{macrocode} +\@@_msg_new:nn { Unknown~key~NewPitonLanguage } + { + Unknown~key~for~\token_to_str:N \NewPitonLanguage.\\ + The~key~'\l_keys_key_str'~is~unknown.\\ + This~key~will~be~ignored.\\ + } +% \end{macrocode} % % \begin{macrocode} \@@_msg_new:nn { Unknown~key~for~SetPitonStyle } @@ -4904,6 +5268,7 @@ piton_version = "2.8" -- 2024/04/14 The~available~keys~are~(in~alphabetic~order):~ auto-gobble,~ background-color,~ + begin-range,~ break-lines,~ break-lines-in-piton,~ break-lines-in-Piton,~ @@ -5014,7 +5379,12 @@ piton_version = "2.8" -- 2024/04/14 local my_lpeg = P { "E" , E = ( V "F" * ( "," * V "F" ) ^ 0 ) / add , - F = space ^ 0 * ( alpha ^ 1 ) / "\\%0" * space ^ 0 +% \end{macrocode} +% Be careful: in Lua, \verb|/| has no priority over \verb|*|. Of course, we want +% a behaviour for this comma-separated list equal to the behaviour of a |clist| +% of L3. +% \begin{macrocode} + F = space ^ 0 * ( ( alpha ^ 1 ) / "\\%0" ) * space ^ 0 } function piton.addListCommands( key_value ) piton.ListCommands = piton.ListCommands + my_lpeg : match ( key_value ) @@ -5091,7 +5461,7 @@ end % \emph{which does a capture} of the pattern. That capture will be sent to LaTeX % with standard LaTeX catcodes for all the characters: the elements captured % will be formatted as normal LaTeX codes. It's suitable for the ``LaTeX -% comments'' in the environments |{Piton}| and the elements beetween +% comments'' in the environments |{Piton}| and the elements between % |begin-escape| and |end-escape|. That function won't be much used. % \begin{macrocode} local function L ( pattern ) @@ -5247,15 +5617,26 @@ local Number = % \end{macrocode} % % \bigskip -% We recall that |piton.begin_espace| and |piton_end_escape| are Lua strings +% We recall that |piton.begin_escape| and |piton_end_escape| are Lua strings % corresponding to the keys |begin-escape| and |end-escape|. % \begin{macrocode} local Word if piton.begin_escape then - Word = Q ( ( 1 - space - piton.begin_escape - piton.end_escape - - S "'\"\r[({})]" - digit ) ^ 1 ) + if piton.begin_escape_math then + Word = Q ( ( 1 - space - piton.begin_escape - piton.end_escape + - piton.begin_escape_math - piton.end_escape_math + - S "'\"\r[({})]" - digit ) ^ 1 ) + else + Word = Q ( ( 1 - space - piton.begin_escape - piton.end_escape + - S "'\"\r[({})]" - digit ) ^ 1 ) + end else - Word = Q ( ( 1 - space - S "'\"\r[({})]" - digit ) ^ 1 ) + if piton.begin_escape_math then + Word = Q ( ( 1 - space - piton.begin_escape_math - piton.end_escape_math + - S "'\"\r[({})]" - digit ) ^ 1 ) + else + Word = Q ( ( 1 - space - S "'\"\r[({})]" - digit ) ^ 1 ) + end end % \end{macrocode} % @@ -5355,7 +5736,7 @@ end % \paragraph{Constructions for Beamer} % % \bigskip -% If the classe Beamer is used, some environemnts and commands of Beamer are +% If the class Beamer is used, some environments and commands of Beamer are % automatically detected in the listings of \pkg{piton}. % \begin{macrocode} local Beamer = P ( false ) @@ -5550,7 +5931,7 @@ local EOL = % % \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 +% document the ``LaTeX comments''. Since the elements that will be caught 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} @@ -5648,7 +6029,7 @@ local DefClass = K ( 'Keyword' , "class" ) * Space * K ( 'Name.Class' , identifier ) % \end{macrocode} % -% If the word |class| is not followed by a identifier, it will be catched as +% If the word |class| is not followed by a identifier, it will be caught as % keyword by the \textsc{lpeg} |Keyword| (useful if we want to type a % list of keywords). % @@ -5687,7 +6068,7 @@ local ImportAs = % need a special treatment because the identifier following the keyword |from| % must be formatted with the \pkg{piton} style |Name.Namespace| and the % following keyword |import| must be formatted with the \pkg{piton} style -% |Keyword| and must \emph{not} be catched by the \textsc{lpeg} |ImportAs|. +% |Keyword| and must \emph{not} be caught by the \textsc{lpeg} |ImportAs|. % % \smallskip % Example:\enskip \piton{from math import pi} @@ -5732,7 +6113,7 @@ local FromImport = % % \bigskip % The interpolations beginning by |%| (even though there is more modern -% technics now in Python). +% techniques now in Python). % \begin{macrocode} local PercentInterpol = K ( 'String.Interpol' , @@ -5752,7 +6133,7 @@ local PercentInterpol = % formatted with another \pkg{piton} style that the rest of the % string.\footnote{The interpolations are formatted with the \pkg{piton} style % |Interpol.Inside|. The initial value of that style is \texttt{\textbackslash -% @@\_piton:n} wich means that the interpolations are parsed once again by \pkg{piton}.} +% @@\_piton:n} which means that the interpolations are parsed once again by \pkg{piton}.} % \begin{macrocode} local SingleShortString = WithStyle ( 'String.Short' , @@ -5783,6 +6164,8 @@ local SingleShortString = ) ^ 0 * Q "'" ) + + local DoubleShortString = WithStyle ( 'String.Short' , Q ( P "f\"" + "F\"" ) @@ -5813,7 +6196,15 @@ local ShortString = SingleShortString + DoubleShortString % \paragraph{Beamer} % % \begin{macrocode} -local braces = Compute_braces ( ShortString ) +local braces = + Compute_braces + ( + Q ( P "\"" + "r\"" + "R\"" + "f\"" + "F\"" ) + * ( "\"" * ( P "\\\"" + 1 - S "\"" ) ^ 0 * "\"" ) + + + Q ( P '\'' + 'r\'' + 'R\'' + 'f\'' + 'F\'' ) + * ( '\'' * ( P '\\\'' + 1 - S '\'' ) ^ 0 * '\'' ) + ) if piton.beamer then Beamer = Compute_Beamer ( 'python' , braces ) end % \end{macrocode} % @@ -5999,7 +6390,7 @@ local DefFunction = * ( EOL + CommentLaTeX + Comment ) -- in all cases, that contains an EOL * Tab ^ 0 * SkipSpace - * StringDoc ^ 0 -- there may be additionnal docstrings + * StringDoc ^ 0 -- there may be additional docstrings ) ^ -1 % \end{macrocode} % Remark that, in the previous code, |CommentLaTeX| \emph{must} appear @@ -6008,7 +6399,7 @@ local DefFunction = % % \smallskip % If the word |def| is not followed by an identifier and parenthesis, it will be -% catched as keyword by the \textsc{lpeg} |Keyword| (useful if, for example, the +% caught as keyword by the \textsc{lpeg} |Keyword| (useful if, for example, the % final user wants to speak of the keyword \piton{def}). % % @@ -6091,7 +6482,7 @@ local Delim = Q ( P "[|" + "|]" + S "[()]" ) local Punct = Q ( S ",:;!" ) % \end{macrocode} % -% The identifiers catched by |cap_identifier| begin with a cap. In OCaml, it's +% The identifiers caught by |cap_identifier| begin with a cap. In OCaml, it's % used for the constructors of types and for the modules. % \begin{macrocode} local cap_identifier = R "AZ" * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0 @@ -6529,12 +6920,12 @@ local Type = K ( 'Name.Type' , P "bool" + "char" + "char16_t" + "char32_t" + "double" + "float" + "int" + "int8_t" + "int16_t" + "int32_t" + "int64_t" + "long" + "short" + "signed" - + "unsigned" + "void" + "wchar_t" ) + + "unsigned" + "void" + "wchar_t" ) * Q "*" ^ 0 local DefFunction = Type * Space - * Q "*" ^ -1 + * Q "*" ^ -1 * K ( 'Name.Function.Internal' , identifier ) * SkipSpace * # P "(" @@ -6554,7 +6945,7 @@ local DefClass = K ( 'Keyword' , "class" ) * Space * K ( 'Name.Class' , identifier ) % \end{macrocode} % -% If the word |class| is not followed by a identifier, it will be catched as +% If the word |class| is not followed by a identifier, it will be caught as % keyword by the \textsc{lpeg} |Keyword| (useful if we want to type a % list of keywords). % @@ -6708,7 +7099,7 @@ local Operator = % 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. +% caught in special LPEG because we want to detect the names of the SQL tables. % \begin{macrocode} local function Set ( list ) local set = { } @@ -6734,7 +7125,7 @@ local set_builtins = Set } % \end{macrocode} % -% The \textsc{lpeg} |Identifer| will catch the identifiers of the fields +% The \textsc{lpeg} |Identifier| 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} @@ -7144,7 +7535,7 @@ 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). +% traditional way to indent in LaTeX). % \begin{macrocode} local EnvGobbleLPEG = ( ( 1 - P "\r" ) ^ 0 * "\r" ) ^ 0 @@ -7269,7 +7660,7 @@ end % % % \bigskip -% The following public Lua function is provided to the developper. +% The following public Lua function is provided to the developer. % \begin{macrocode} function piton.get_last_code ( ) return LPEG_cleaner[piton.last_language] : match ( piton.last_code ) @@ -7373,28 +7764,62 @@ function piton.new_language ( lang , definition ) % \bigskip % \begin{macrocode} local alpha , digit = lpeg.alpha , lpeg.digit - local letter = alpha + S "@_$" -- $ + local extra_letters = { "@" , "_" , "$" } -- $ % \end{macrocode} % -% \bigskip -% In the following \textsc{lpeg} we have a problem when we try to add |{| and -% |}|. -% \begin{macrocode} - local other = S "+-*/<>!?:;.()@[]~^=#&\"\'\\$" -- $ -% \end{macrocode} % % \bigskip +% The command |add_to_letter| (triggered by the key ||) don't write right away +% in the \textsc{lpeg} pattern of the letters in an intermediate |extra_letters| +% because we may have to retrieve letters from that ``list'' if there appear in +% a key |alsoother|. % \begin{macrocode} function add_to_letter ( c ) - if c ~= " " then letter = letter + c end + if c ~= " " then table.insert ( extra_letters , c ) end end +% \end{macrocode} +% +% For the digits, it's straitforward. +% \begin{macrocode} function add_to_digit ( c ) if c ~= " " then digit = digit + c end end % \end{macrocode} +% +% \bigskip +% The main use of the key |alsoother| is, for the language LaTeX, when you have +% to retrieve some characters from the list of letters, in particular |@| and +% |_| (which, by default, are not allowed in the name of a control sequence in +% TeX). +% +% \medskip +% (In the following \textsc{lpeg} we have a problem when we try to add |{| and +% |}|). +% \begin{macrocode} + local other = S ":_@+-*/<>!?;.()[]~^=#&\"\'\\$" -- $ + local extra_others = { } +% \end{macrocode} +% +% \begin{macrocode} + function add_to_other ( c ) + if c ~= " " then +% \end{macrocode} +% We will use |extra_others| to retrieve further these characters from the list +% of the letters. +% \begin{macrocode} + extra_others[c] = true +% \end{macrocode} +% The \textsc{lpeg} pattern |other| will be used in conjunction with the key +% |tag| (mainly for the language \textsc{html}) for the character |/| in the +% closing tags |</....>|). +% \begin{macrocode} + other = other + P "c" + end + end +% \end{macrocode} % % \bigskip -% Of course, the \textsc{lpeg} |b_braces| is for balanced braces (without the +% Of course, the \textsc{lpeg} |strict_braces| is for balanced braces (without the % question of strings of an informatic language). In fact, it \emph{won't} be % used for an informatic language (as dealt by \pkg{piton}) but for LaTeX % instructions; @@ -7419,7 +7844,7 @@ function piton.new_language ( lang , definition ) local def_table = cut_definition : match ( definition ) % \end{macrocode} % The definition of the language, provided by the final user of \pkg{piton} is -% now in the Lua table |def_table|. We will use it several times. +% now in the Lua table |def_table|. We will use it \emph{several times}. % % \medskip % The following \textsc{lpeg} will be used to extract arguments in the values of @@ -7431,6 +7856,15 @@ function piton.new_language ( lang , definition ) % \end{macrocode} % % \begin{macrocode} + local args_for_tag + = tex_option_arg + * space ^ 0 + * tex_arg + * space ^ 0 + * tex_arg +% \end{macrocode} +% +% \begin{macrocode} local args_for_morekeywords = "[" * C ( ( 1 - P "]" ) ^ 0 ) * "]" * space ^ 0 @@ -7456,17 +7890,6 @@ function piton.new_language ( lang , definition ) * 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 @@ -7475,7 +7898,7 @@ function piton.new_language ( lang , definition ) % the potential keys |alsodigit|, |alsoletter| and |tag|. % \begin{macrocode} local sensitive = true - local left_tag , right_tag + local style_tag , 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 @@ -7486,8 +7909,10 @@ function piton.new_language ( lang , definition ) 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] == "alsoother" then x[2] : gsub ( "." , add_to_other ) end if x[1] == "tag" then - left_tag , right_tag = args_for_tag : match ( x[2] ) + style_tag , left_tag , right_tag = args_for_tag : match ( x[2] ) + style_tag = style_tag or [[\PitonStyle{Tag}]] end end % \end{macrocode} @@ -7503,6 +7928,19 @@ function piton.new_language ( lang , definition ) + digit ^ 1 ) % \end{macrocode} +% +% \begin{macrocode} + local string_extra_letters = "" + for _ , x in ipairs ( extra_letters ) do + if not ( extra_others[x] ) then + string_extra_letters = string_extra_letters .. x + end + end + local letter = alpha + S ( string_extra_letters ) + + P "â" + "à" + "ç" + "é" + "è" + "ê" + "ë" + "ï" + "î" + + "ô" + "û" + "ü" + "Â" + "À" + "Ç" + "É" + "È" + "Ê" + "Ë" + + "Ï" + "Î" + "Ô" + "Û" + "Ü" +% \end{macrocode} % % \begin{macrocode} local alphanum = letter + digit @@ -7539,6 +7977,7 @@ function piton.new_language ( lang , definition ) ) end local Keyword = P ( false ) + local PrefixedKeyword = P ( false ) % \end{macrocode} % Now, we actually treat all the keywords and also the key |moredirectives|. % \begin{macrocode} @@ -7551,23 +7990,23 @@ function piton.new_language ( lang , definition ) local keywords = P ( false ) % \end{macrocode} % \begin{macrocode} - local style = [[ \PitonStyle{Keyword} ]] - if x[1] == "moredirectives" then style = [[ \PitonStyle{directive} ]] end + 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 ) + local n = tonumber ( style ) if n then - if n > 1 then style = [[ \PitonStyle{Keyword ]] .. style .. "}" end + 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 + 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 +% |morekeywords|, 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} @@ -7579,9 +8018,24 @@ function piton.new_language ( lang , definition ) Keyword = Keyword + Lc ( "{" .. style .. "{" ) * keywords * Lc "}}" end +% \end{macrocode} +% Of course, the feature with the key |keywordsprefix| is designed for the +% languages TeX, LaTeX, et \emph{al}. In that case, there is two kinds of +% keywords (= control sequences). +% \begin{itemize} +% \item those beginning with |\| and a sequence of characters of catcode ``|letter|''; +% \item those beginning by |\| followed by one character of catcode ``|other|''. +% \end{itemize} +% The following code addresses both cases. Of course, the \textsc{lpeg} pattern +% |letter| must catch only characters of catcode ``|letter|''. That's why we +% have a key |alsoletter| to add new characters in that category (e.g. |:| when +% we want to format L3 code). However, the \textsc{lpeg} pattern is allowed to +% catch \emph{more} than only the characters of catcode ``other'' in TeX. +% \begin{macrocode} if x[1] == "keywordsprefix" then local prefix = ( ( C ( 1 - P " " ) ^ 1 ) * P " " ^ 0 ) : match ( x[2] ) - Keyword = Keyword + K ( 'Keyword' , P ( prefix ) * alphanum ^ 0 ) + PrefixedKeyword = PrefixedKeyword + + K ( 'Keyword' , P ( prefix ) * ( letter ^ 1 + other ) ) end end % \end{macrocode} @@ -7597,44 +8051,42 @@ function piton.new_language ( lang , definition ) 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 + arg2 = arg2 or [[\PitonStyle{String.Long}]] + if arg1 ~= "s" then + arg4 = arg3 + end + central_pattern = 1 - S ( " \r" .. arg4 ) + 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 + if arg1 : match "d" or arg1 == "m" then + central_pattern = P ( arg3 .. arg3 ) + central_pattern + end + if arg1 == "m" + then prefix = lpeg.B ( 1 - letter - ")" - "]" ) + else prefix = P ( true ) + end +% \end{macrocode} +% We can write the pattern which matches the string. +% \begin{macrocode} + local pattern = + prefix + * Q ( arg3 ) + * ( VisualSpace + Q ( central_pattern ^ 1 ) + EOL ) ^ 0 + * Q ( arg4 ) % \end{macrocode} % First, we create |long_string| because we need that \textsc{lpeg} in the % nested comments. % \begin{macrocode} - long_string = long_string + - prefix - * Q ( arg3 ) - * ( VisualSpace + Q ( central_pattern ^ 1 ) + EOL ) ^ 0 - * Q ( arg3 ) - end + long_string = long_string + pattern LongString = LongString + Ct ( Cc "Open" * Cc ( "{" .. arg2 .. "{" ) * Cc "}}" ) - * long_string + * pattern * Ct ( Cc "Close" ) end end @@ -7655,12 +8107,12 @@ function piton.new_language ( lang , definition ) 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} ]] + 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 "i" then arg2 = [[\PitonStyle{Discard}]] end if arg1 : match "l" then local arg3 = ( tex_braced_arg + C ( P ( 1 ) ^ 0 * -1 ) ) : match ( other_args ) @@ -7753,11 +8205,7 @@ function piton.new_language ( lang , definition ) local Punct = Q ( S "=,:;!\\'\"" ) % \end{macrocode} % -% -% \begin{macrocode} -% \end{macrocode} -% -% +% % \begin{macrocode} local Main = space ^ 1 * -1 @@ -7772,9 +8220,14 @@ function piton.new_language ( lang , definition ) + Beamer + DetectedCommands + CommentDelim - + Delim +% \end{macrocode} +% We must put |LongString| before |Delim| because, in PostScript, the strings +% are delimited by parenthesis and those parenthesis would be caught by |Delim|. +% \begin{macrocode} + LongString - + Keyword * ( Space + Punct + Delim + EOL + -1 ) + + Delim + + PrefixedKeyword + + Keyword * ( -1 + # ( 1 - alphanum ) ) + Punct + K ( 'Identifier' , letter * alphanum ^ 0 ) + Number @@ -7787,14 +8240,6 @@ function piton.new_language ( lang , definition ) 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} @@ -7802,21 +8247,23 @@ function piton.new_language ( lang , definition ) Ct ( ( space ^ 0 * P "\r" ) ^ -1 * BeamerBeginEnvironments - * Lc [[ \@@_begin_line: ]] + * Lc [[\@@_begin_line:]] * SpaceIndentation ^ 0 * LPEG1[lang] * -1 - * Lc [[ \@@_end_line: ]] + * Lc [[\@@_end_line:]] ) % \end{macrocode} % -% +% If the key |tag| has been used. Of course, this feature is designed for the \textsc{html}. % \begin{macrocode} if left_tag then - local Tag = Q ( left_tag * other ^ 0 ) + local Tag = Ct ( Cc "Open" * Cc ( "{" .. style_tag .. "{" ) * Cc "}}" ) + * Q ( left_tag * other ^ 0 ) -- $ * ( ( ( 1 - P ( right_tag ) ) ^ 0 ) / ( function ( x ) return LPEG0[lang] : match ( x ) end ) ) * Q ( right_tag ) + * Ct ( Cc "Close" ) MainWithoutTag = space ^ 1 * -1 + space ^ 0 * EOL @@ -7829,37 +8276,31 @@ function piton.new_language ( lang , definition ) + CommentDelim + Delim + LongString - + Keyword * ( Space + Punct + Delim + EOL + -1 ) + + PrefixedKeyword + + Keyword * ( -1 + # ( 1 - alphanum ) ) + Punct + K ( 'Identifier' , letter * alphanum ^ 0 ) + Number + Word LPEG0[lang] = MainWithoutTag ^ 0 + local LPEGaux = Tab + Escape + EscapeMath + CommentLaTeX + + Beamer + DetectedCommands + CommentDelim + Tag MainWithTag = space ^ 1 * -1 + space ^ 0 * EOL + Space - + Tab - + Escape + EscapeMath - + CommentLaTeX - + Beamer - + DetectedCommands - + CommentDelim - + Tag - + Delim - + Punct - + K ( 'Identifier' , letter * alphanum ^ 0 ) - + Word + + LPEGaux + + Q ( ( 1 - EOL - LPEGaux ) ^ 1 ) LPEG1[lang] = MainWithTag ^ 0 LPEG2[lang] = Ct ( ( space ^ 0 * P "\r" ) ^ -1 * BeamerBeginEnvironments - * Lc [[ \@@_begin_line: ]] + * Lc [[\@@_begin_line:]] * SpaceIndentation ^ 0 * LPEG1[lang] * -1 - * Lc [[ \@@_end_line: ]] + * Lc [[\@@_end_line:]] ) end end @@ -7886,9 +8327,16 @@ end % % \verb|https://github.com/fpantigny/piton| % +% \subsection*{Changes between versions 2.8 and 3.0} +% +% New command |\NewPitonLanguage|. Thanks to that command, it's now possible to +% define new informatic languages with the syntax used by \pkg{listings}. +% Therefore, it's possible to say that virtually all the informatic languages +% are now supported by \pkg{piton}. +% % \subsection*{Changes between versions 2.7 and 2.8} % -% The key |path| now accepts a \emph{list} of pathes where the files to include +% The key |path| now accepts a \emph{list} of paths where the files to include % will be searched. % % New commands |\PitonInputFileT|, |\PitonInputFileF| and |\PitonInputFileTF|. @@ -7994,7 +8442,7 @@ end % % New key |show-spaces-in-string| and modification of the key |show-spaces|. % -% When the class \cls{beamer} is used, the environements |{uncoverenv}|, +% When the class \cls{beamer} is used, the environments |{uncoverenv}|, % |{onlyenv}|, |{visibleenv}| and |{invisibleenv}| % % |