texlive[72351] Master/texmf-dist: piton (22sep24)
commits+karl at tug.org
commits+karl at tug.org
Sun Sep 22 22:22:25 CEST 2024
Revision: 72351
https://tug.org/svn/texlive?view=revision&revision=72351
Author: karl
Date: 2024-09-22 22:22:25 +0200 (Sun, 22 Sep 2024)
Log Message:
-----------
piton (22sep24)
Modified Paths:
--------------
trunk/Master/texmf-dist/doc/lualatex/piton/piton-french.pdf
trunk/Master/texmf-dist/doc/lualatex/piton/piton-french.tex
trunk/Master/texmf-dist/doc/lualatex/piton/piton.pdf
trunk/Master/texmf-dist/source/lualatex/piton/piton.dtx
trunk/Master/texmf-dist/tex/lualatex/piton/piton.lua
trunk/Master/texmf-dist/tex/lualatex/piton/piton.sty
Modified: trunk/Master/texmf-dist/doc/lualatex/piton/piton-french.pdf
===================================================================
(Binary files differ)
Modified: trunk/Master/texmf-dist/doc/lualatex/piton/piton-french.tex
===================================================================
--- trunk/Master/texmf-dist/doc/lualatex/piton/piton-french.tex 2024-09-22 20:22:16 UTC (rev 72350)
+++ trunk/Master/texmf-dist/doc/lualatex/piton/piton-french.tex 2024-09-22 20:22:25 UTC (rev 72351)
@@ -33,8 +33,6 @@
\usepackage{booktabs}
\usepackage{tcolorbox}
\usepackage{luacolor,lua-ul}
-
-
\usepackage{caption}
% We use \MakeShortVerb of shortvrb and not \DefineShortVerb of fancyvrb
@@ -73,6 +71,8 @@
\usepackage{makeidx}
\makeindex
+\usepackage{underscore}
+
\NewDocumentCommand{\Definition}{m}
{{\setlength{\fboxsep}{1pt}\colorbox{gray!20}{\ttfamily \vphantom{gl}#1}}}
@@ -113,6 +113,9 @@
\end{abstract}
+\bigskip
+{\color{red} Dans la version 4.0, la syntaxe des chemins absolus et relatifs utilisés dans
+|\PitonInputFile| a été changée : cf.~partie~\ref{PitonInputFile}, p.~\pageref{PitonInputFile}.}
\section{Présentation}
@@ -127,11 +130,11 @@
la clé |write| est utilisée). La compilation est très rapide puisque tout le travail du
parseur est fait par la librairie LPEG, écrite en C.
-\bigskip
+\medskip
Voici un exemple de code Python composé avec l'environnement |{Piton}| proposé par \pkg{piton}.
-\bigskip
+\medskip
\begin{Piton}
from math import pi
@@ -152,16 +155,17 @@
return s
\end{Piton}
-\bigskip
+\medskip
Les principaux concurrents de l'extension \pkg{piton} sont certainement les extensions
bien connues \pkg{listings} et \pkg{minted}.
-\bigskip
-Le nom de cette extension (\pkg{piton}) a été choisi un peu arbitrairement en référence
-aux pitons d'alpinisme qui servent à gravir les montagnes.
+% \medskip
+% Le nom de cette extension (\pkg{piton}) a été choisi un peu arbitrairement en référence
+% aux pitons d'alpinisme qui servent à gravir les montagnes.
+
\section{Installation}
L'extension \pkg{piton} est composée de deux fichiers : |piton.sty| et |piton.lua| (le
@@ -197,7 +201,7 @@
\smallskip
\index{language (clé)}
-On peut changer de langage avec la clé |language| de |\PitonOptions| :
+On peut changer de langage avec la clé \Definition{language} de |\PitonOptions| :
\smallskip
|\PitonOptions{language = OCaml}|
@@ -211,8 +215,8 @@
dans la variable publique L3 nommée |\l_piton_language_str|.
\smallskip
-Dans la suite de ce document, on parlera de Python mais les fonctionnalités s'appliquent
-aussi aux autres langages.
+Dans la suite de ce document, on parlera préférentiellement de Python mais les
+fonctionnalités s'appliquent aussi aux autres langages.
@@ -231,7 +235,7 @@
\indexenv{Piton}
-L'extension \pkg{piton} fournit plusieurs outils pour composer du code Python: les
+L'extension \pkg{piton} fournit plusieurs outils pour composer du code informatique : les
commandes |\piton|, l'environnement |{Piton}| et la commande |\PitonInputFile|.
\begin{itemize} \setlength{\fboxsep}{1pt}
@@ -249,24 +253,11 @@
un mode verbatim, il ne peut pas être utilisé dans l'argument d'une commande LaTeX. Pour
les besoins de personnalisation, il est possible de définir de nouveaux environnements
similaires à |{Piton}| en utilisant la commande \DefinitionCommand{NewPitonEnvironment} :
-cf. partie \ref{NewPitonEnvironment} p.~\pageref{NewPitonEnvironment}.
+cf.~partie~\ref{NewPitonEnvironment} p.~\pageref{NewPitonEnvironment}.
-\item La commande \colorbox{gray!20}{\ttfamily \textbackslash PitonInputFile} doit être
-utilisée pour insérer et composer un fichier externe.
-
-Il est possible de n'insérer qu'une partie de ce fichier : cf. partie~\ref{part-of-a-file},
-p.~\pageref{part-of-a-file}.
-
-La clé \Definition{path} de la commande |\PitonOptions| permet de spécifier une
-\emph{liste} de chemins où sera recherché le fichier à inclure (dans cette liste, les
-chemins sont séparés par des virgules).
-
-L'extension \pkg{piton} propose aussi des commandes
-\colorbox{gray!20}{\ttfamily\textbackslash PitonInputFileT}, \colorbox{gray!20}{\ttfamily
- \textbackslash PitonInputFileF} et \colorbox{gray!20}{\ttfamily \textbackslash
- PitonInputFileTF} avec des arguments correspondant aux lettres |T| et |F|, arguments qui
-seront executés dans le cas où le fichier a été trouvé (lettre |T|) ou pas (lettre |F|).
-
+\item La commande \DefinitionCommand{PitonInputFile} doit être utilisée pour insérer et
+composer un fichier externe : cf.~partie~\ref{PitonInputFile},
+p.~\pageref{PitonInputFile}.
\end{itemize}
@@ -285,7 +276,7 @@
\begin{itemize}
\item {\color{blue} \textsf{Syntaxe} \verb|\piton{...}|}\par\nobreak
-Quand son argument est donné entre accolades, la commande |\piton| ne prend pas son
+Quand son argument est donné entre accolades, la commande |\piton| ne prend \emph{pas} son
argument en mode verbatim. Les points suivants doivent être remarqués :
\begin{itemize}
@@ -303,9 +294,9 @@
{\color{cyan} mais les commandes |\{| et |\}| sont aussi fournies pour insérer des
accolades individuelles} ;
-\item les commandes LaTeX\footnote{Cela s'applique aux commandes commençant par une contre-oblique |\| mais
- également aux caractères actifs, c'est-à-dire ceux de catcode~13.} sont complètement développées sans être
-exécutées
+\item les commandes LaTeX\footnote{Cela s'applique aux commandes commençant par une
+ contre-oblique |\| mais également aux caractères actifs, c'est-à-dire ceux de
+ catcode~13.} sont complètement développées sans être exécutées
{\color{cyan} et on peut donc utiliser |\\| pour insérer une contre-oblique}.
\end{itemize}
@@ -334,6 +325,10 @@
arguments des autres commandes LaTeX.\footnote{La commande |\piton| peut par exemple être
utilisée dans une note de bas de page. Exemple : \piton{s = 'Une chaîne'}.}
+En revanche, comme son argument subit un développement (au sens de TeX), il faut prendre
+soin à ne pas utiliser dans son argument de commandes fragiles (c'est-à-dire des commandes
+qui ne sont ni \emph{protected} ni \emph{fully expandable}).
+
\bigskip
\item {\color{blue} \textsf{Syntaxe} \verb!\piton|...|!}\par\nobreak
@@ -361,10 +356,6 @@
\section{Personnalisation}
-Concernant la fonte de caractères utilisée dans les listings produits par l'extension
-\pkg{piton}, il s'agit simplement de la fonte mono-chasse courante (\pkg{piton} utilise
-simplement en interne la commande LaTeX standard |\ttfamily|). Pour la changer, le mieux
-est d'utiliser |\setmonofont| de \pkg{fontspec}.
\subsection{Les clés de la commande \textbackslash PitonOptions}
@@ -386,9 +377,16 @@
La valeur initiale est |Python|.
-\item \index{path} La clé \Definition{path} indique un chemin où seront cherchés les fichiers inclus par
-|\PitonInputFile|.
+\item \index{font-command}
+\colorbox{yellow!50}{\textbf{Nouveau 4.0}}\par\nobreak
+La clé \Definition{font-command} contient des instructions de fonte qui seront
+insérées au début de chaque élément formaté par \pkg{piton}, que ce soit avec la commande
+|\piton|, l'environnement |{Piton}| ou bien la commande |\PitonInputFile|.
+
+La valeur initiale de ce paramètre |font-command| est |\ttfamily|, ce qui fait, que, par
+défaut, \pkg{piton} utilise la fonte mono-chasse courante.
+
\item \index{gobble}\label{gobble} La clé \Definition{gobble} prend comme valeur un entier
positif $n$ : les $n$ premiers caractères de chaque ligne sont alors retirés (avant
formatage du code) dans les environnements |{Piton}|. Ces $n$ caractères ne sont pas
@@ -455,10 +453,9 @@
de lignes (insérés par |line-numbers|) et les lignes du code informatique. La valeur
initiale est 0.7~em.
-\item \colorbox{yellow!50}{\bfseries Nouveau 3.1}\enskip
-La clé \Definition{line-numbers/format} est une liste de tokens qui est insérée avant le
-numéro de ligne pour le formater. Il est possible de mettre \emph{en dernière position} de
-cette liste une commande LaTeX à un argument comme |\fbox|.
+\item La clé \Definition{line-numbers/format} est une liste de tokens qui est insérée
+avant le numéro de ligne pour le formater. Il est possible de mettre \emph{en dernière
+ position} de cette liste une commande LaTeX à un argument comme |\fbox|.
La valeur initiale est |\footnotesize \color{gray}|.
\end{itemize}
@@ -502,11 +499,6 @@
\emph{Exemple} : |\PitonOptions{background-color = {gray!5,white}}|
-\smallskip
-Si la clé |split-on-empty-lines| est utilisée (voir la partie «Coupure de pages»,
-p.~\pageref{coupure-de-pages}), les lignes de séparation entre morceaux de code générés
-par cette clé n'ont pas de fond coloré (au moins avec la valeur initiale du paramètre
-|split-separation|).
\item \index{prompt-background-color} Avec la clé \Definition{prompt-background-color},
\pkg{piton} ajoute un fond coloré aux lignes débutant par le prompt «|>>>|» (et sa
@@ -575,7 +567,7 @@
if (!swapped) break;
}
}
-\end{Piton}
+~emphase&\end{Piton}@
\end{Verbatim}
\endgroup
@@ -607,6 +599,7 @@
particulier la coupure des pages et des lignes p.~\pageref{breakable}).
+
\subsection{Les styles}
\label{styles}
@@ -637,17 +630,17 @@
\begin{Verbatim}
\SetPitonStyle
- { Name.Function = \bfseries \hightLight[red!50] }
+ { Name.Function = \bfseries \hightLight[red!30] }
\end{Verbatim}
-Ici, |\highLight[red!50]| doit être considéré comme le nom d'une fonction LaTeX qui prend
+Ici, |\highLight[red!30]| doit être considéré comme le nom d'une fonction LaTeX qui prend
exactement un argument, puisque, habituellement, elle est utilisée avec
-|\highLight[red!50]{|\texttt{\slshape text}|}|.
+|\highLight[red!30]{|\texttt{\slshape text}|}|.
\medskip
\begingroup
\SetPitonStyle
- { Name.Function = \bfseries \highLight[red!50] }
+ { Name.Function = \bfseries \highLight[red!30] }
Avec ce réglage, on obtient : \piton{def cube(x) : return x * x * x }
\endgroup
@@ -800,10 +793,10 @@
environnements directement au-dessus de l'environnement |{Piton}| avec les commandes
classiques |\newenvironment| (de LaTeX standard) et |\NewDocumentEnvironment| (de LaTeX3).
-C'est pourquoi \pkg{piton} propose une commande |\NewPitonEnvironment|. Cette commande a
-la même syntaxe que la commande classique |\NewDocumentEnvironment|.\footnote{Néanmoins,
- le spécificateur d'argument~|b|, qui sert à capter le corps de l'environnement comme un
- argument LaTeX, n'est pas autorisé.}
+C'est pourquoi \pkg{piton} propose une commande \DefinitionCommand{NewPitonEnvironment}.
+Cette commande a la même syntaxe que la commande classique
+|\NewDocumentEnvironment|.\footnote{Néanmoins, le spécificateur d'argument~|b|, qui sert à
+ capter le corps de l'environnement comme un argument LaTeX, n'est pas autorisé.}
\bigskip
Par exemple, avec l'instruction suivante, un nouvel environnement |{Python}| sera défini
@@ -849,8 +842,6 @@
\label{NewPitonLanguage}
\index{listings@\pkg{listings} (extension)}
-\colorbox{yellow!50}{\textbf{Nouveau 3.0}}
-
\medskip
L'extension \pkg{listings} est une célèbre extension LaTeX pour formater des codes informatiques.
@@ -867,7 +858,7 @@
\medskip
Précisons tout de suite que l'extension \pkg{piton} n'utilise \emph{pas} cette commande
-pour définir les langages qu'elle propose nativement (Python, C, OCaml, \CC\ et
+pour définir les langages qu'elle propose nativement (Python, C, OCaml, SQL et
|minimal|), ce qui permet de proposer des parseurs plus puissants.
\medskip
@@ -941,7 +932,7 @@
\bigskip
\begingroup
\small
-\PitonOptions{split-on-empty-lines}
+\PitonOptions{splittable-on-empty-lines}
\begin{Piton}[language = Java]
public class Cipher { // cryptage par le chiffre de César
public static void main(String[] args) {
@@ -991,161 +982,67 @@
\begin{verbatim}
\NewPitonLanguage{LaTeX}{keywordsprefix = \ , alsoletter = @_ }
\end{verbatim}
-} Initialement, les caractères |@| et |_| sont des considérés comme des lettres car de
-nombreux langages de programmation les autorisent dans les mots-clés et les
-identificateurs. Avec \verb|alsoletter = @_|, on les retire de la catégorie des lettres.
+}
+Initialement, les caractères |@| et |_| sont considérés comme des lettres car de nombreux
+langages de programmation les autorisent dans les mots-clés et les identificateurs. Avec
+\verb|alsoletter = @_|, on les retire de la catégorie des lettres.
+
\section{Fonctionnalités avancées}
-\subsection{Coupure des pages et des lignes}
+\subsection{Insertion d'un fichier}
-\label{breakable}
+\label{PitonInputFile}
-\subsubsection{Coupure des pages}
+\subsubsection{La commande \textbackslash PitonInputFile}
-\label{coupure-de-pages}
+\indexcommand{PitonInputFile}
-\index{splittable}
-\index{split-on-empty-lines}
-\index{split-separation}
+La commande \DefinitionCommand{PitonInputFile} permet d'insérer tout ou partie d'un
+fichier extérieur dont le nom est passé en argument. Il existe aussi des commandes
+\DefinitionCommand{PitonInputFileT}, \DefinitionCommand{PitonInputFileF} et
+\DefinitionCommand{PitonInputFileTF} avec des arguments correspondant aux lettres |T| et
+|F|, arguments qui seront exécutés dans le cas où le fichier a été trouvé (lettre |T|) ou
+pas (lettre |F|).
-Par défaut, les listings produits par l'environnement |{Piton}| et par la commande
-|\PitonInputFile| sont insécables.
+\bigskip
+\colorbox{yellow!50}{\textbf{Modification 4.0}}\par\nobreak
-Néanmoins, la commande |\PitonOptions| propose les clés |split-on-empty-lines| et
-|splittable| pour autoriser de telles coupures.
+\smallskip
+\index{old-PitonInputFile}
+La syntaxe pour les chemins absolus et relatifs a été changée pour être conforme aux
+usages traditionnels. Il est toutefois possible d'utiliser la clé
+\Definition{old-PitonInputFile} au chargement de l'extension (c'est-à-dire avec le
+|\usepackage|) pour avoir l'ancien comportement de |\PitonInputFile| (néanmoins, cette clé
+sera supprimée dans une prochaine version de \pkg{piton} !).
+\smallskip
+La syntaxe est maintenant la suivante :
\begin{itemize}
-\item La clé \Definition{split-on-empty-lines} autorise les coupures sur les lignes
-vides\footnote{Les lignes considérées comme vides sont celles qui ne comportent que des
- espaces.} du listing. Dans les listings informatiques, les lignes vides séparent le plus
-souvent les définitions des fonctions informatiques et il est donc souvent judicieux de
-pouvoir couper au niveau de ces lignes.
+\item Les chemins commençant par |/| sont des chemins absolus.
-Quand la clé |split-on-empty-lines| est activée, le travail effectué va en fait un peu
-plus loin : les lignes vides successives sont supprimées et remplacées par le contenu du
-paramètre correspondant à la clé \Definition{split-separation}
-\begin{itemize}
-\item Ce paramètre doit contenir du matériel à insérer en \emph{mode vertical} de TeX. On
-peut, par exemple, mettre |\hrule|.
+\emph{Exemple} : |\PitonInputFile{/Users/joe/Documents/programme.py}|
-\item La valeur initiale de ce paramètre est |\vspace{\baselineskip}\vspace{-1.25pt}|, ce qui,
-au final, correspond à une ligne vide dans le PDF produit (cet espace vertical est
-supprimé s'il tombe au niveau d'un saut de page). Si la clé |background-color| est
-utilisée, aucun fond n'est affiché au niveau de cette ligne de séparation.
-\end{itemize}
+\item Les chemins ne commençant pas par |/| sont relatifs au répertoire courant.
-\medskip
-\item La clé |split-on-empty-lines| peut bien sûr être insuffisante et c'est pourquoi
-\pkg{piton} propose la clé \Definition{splittable}.
-
-Quand la clé |splittable| est utilisée avec la valeur numérique $n$ (qui doit être un
-entier naturel non nul) le listing, ou bien chaque partie de ce listing située entre des
-lignes vides (quand |split-on-empty-lines| est utilisée), pourra être coupé n'importe où
-avec cette exception qu'aucune coupure ne pourra avoir lieu entre les $n$~premières
-lignes, ni entre les $n$~dernières. Par exemple, |splittable = 4| pourrait être un réglage
-raisonnable.
-
-Employée sans argument, la clé |splittable| est équivalente à |splittable = 1|, et les
-listings sont alors sécables n'importe où (ce n'est pas recommandable).
-
-La valeur initiale de la clé |splittable| vaut 100, ce qui fait que listings ne sont pas
-sécables.
+\emph{Exemple} : |\PitonInputFile{les_listings/programme.py}|
\end{itemize}
-\medskip
-\emph{Remarque}\par\nobreak
-Même avec une couleur de fond (fixée avec |background-color|), les sauts de page sont
-possibles, à partir du moment où |split-on-empty-lines| ou |splittable| est
-utilisée.\footnote{Avec la clé |splittable|, un environnement |{Piton}| est sécable même
- dans un environnement de \pkg{tcolorbox} (à partir du moment où la clé |breakable| de
- \pkg{tcolorbox} est utilisée). On précise cela parce que, en revanche, un environnement
- de \pkg{tcolorbox} inclus dans un autre environnement de \pkg{tcolorbox} n'est pas
- sécable, même quand les deux utilisent la clé |breakable|.}
+\index{path}
+La clé \Definition{path} de la commande |\PitonOptions| permet de spécifier une
+\emph{liste} de chemins où sera recherché le fichier à inclure (dans cette liste, les
+chemins sont séparés par des virgules). Comme précédemment, les chemins absolus doivent
+débuter par une oblique~|/|.
-\subsubsection{Coupure des lignes}
+\subsubsection{Insertion d'une partie d'un fichier}
-\label{line-breaks}
-
-Par défaut, les éléments produits par \pkg{piton} ne peuvent pas être coupés par une fin
-de ligne. Il existe néanmoins des clés pour autoriser de telles coupures (les points de
-coupure possibles sont les espaces, y compris les espaces dans les chaînes Python).
-\begin{itemize}
-\item \index{break-lines!break-lines-in-piton} Avec la clé
-\Definition{break-lines-in-piton}, les coupures de ligne sont autorisées dans la commande
-|\piton{...}| (mais pas dans la commande \verb+\piton|...|+, c'est-à-dire avec la syntaxe
-verbatim).
-
-\item \index{break-lines!break-lines-in-Piton} Avec la clé
-\Definition{break-lines-in-Piton}, les coupures de ligne sont autorisées dans
-l'environnement |{Piton}| (d'où la lettre |P| capitale dans le nom) et les listings
-produits par |\PitonInputFile|.
-
-\item \index{break-lines} La clé \Definition{break-lines} est la conjonction des deux clés
-précédentes.
-\end{itemize}
-
-\medskip
-L'extension \pkg{piton} fournit aussi plusieurs clés pour contrôler l'apparence des
-coupures de ligne autorisées par |break-lines-in-Piton|.
-
-\begin{itemize}
-\item \index{indent-broken-lines} Avec la clé \Definition{indent-broken-lines},
-l'indentation de la ligne coupée est respectée à chaque retour à la ligne.
-
-\item \index{end-of-broken-line} La clé \Definition{end-of-broken-line} correspond au
-symbole placé à la fin d'une ligne coupée. Sa valeur initiale est :
-|\hspace*{0.5em}\textbackslash|.
-
-\item \index{continuation-symbol} La clé \Definition{continuation-symbol} correspond au
-symbole placé à chaque retour de ligne dans la marge gauche. Sa valeur initiale est :
-|+\;| (la commande |\;| insère un petit espace horizontal).
-
-\item \index{continuation-symbol-on-indentation} La clé
-\Definition{continuation-symbol-on-indentation} correspond au symbole placé à chaque
-retour de ligne au niveau de l'indentation (uniquement dans le cas où la clé
-|indent-broken-lines| est active). Sa valeur initiale est : |$\hookrightarrow\;$|.
-\end{itemize}
-
-\bigskip
-Le code suivant a été composé avec le réglage suivant :
-
-\begin{Verbatim}
-\PitonOptions{width=12cm,break-lines,indent-broken-lines,background-color=gray!15}
-\end{Verbatim}
-
-\begin{center}
-\PitonOptions{width=12cm,break-lines,indent-broken-lines,background-color=gray!15}
-\begin{Piton}
-def dict_of_liste(liste):
- """Convertit une liste de subrs et de descriptions de glyphes en dictionnaire"""
- dict = {}
- for liste_lettre in liste:
- if (liste_lettre[0][0:3] == 'dup'): # si c'est un subr
- nom = liste_lettre[0][4:-3]
- print("On traite le subr de numéro " + nom)
- else:
- nom = liste_lettre[0][1:-3] # si c'est un glyphe
- print("On traite le glyphe du caractère " + nom)
- dict[nom] = [traite_ligne_Postscript(k) for k in liste_lettre[1:-1]]
- return dict
-\end{Piton}
-\end{center}
-
-
-\bigskip
-\subsection{Insertion d'une partie d'un fichier}
-
\label{part-of-a-file}
-\indexcommand{PitonInputFile}
-
-La commande |\PitonInputFile| permet d'insérer (avec formatage) le contenu d'un fichier.
En fait, il existe des mécanismes permettant de n'insérer qu'une partie du fichier en
question.
\begin{itemize}
@@ -1156,18 +1053,19 @@
Dans les deux cas, si on souhaite numéroter les lignes avec les numéros des lignes du
fichier d'origine, il convient d'utiliser la clé |line-numbers/absolute|.
-\subsubsection{Avec les numéros de lignes absolus}
+\bigskip
+\textbf{Avec les numéros de lignes absolus}\par\nobreak
La commande |\PitonInputFile| propose les clés \Definition{first-line} et
-\Definition{last-line} pour n'insérer que la partie du fichier comprise entre les lignes
-correspondantes. Ne pas confondre avec la clé |line-numbers/start| qui demande un
-numérotage des lignes commençant à la valeur donnée à cette clé (en un sens
+\Definition{last-line} qui permettent de n'insérer que la partie du fichier comprise entre
+les lignes correspondantes. Ne pas confondre avec la clé |line-numbers/start| qui demande
+un numérotage des lignes commençant à la valeur donnée à cette clé (en un sens
|line-numbers/start| concerne la sortie alors que |first-line| et |last-line| concernent
l'entrée).
+\bigskip
+\textbf{Avec des marqueurs textuels}\par\nobreak
-\subsubsection{Avec des marqueurs textuels}
-
\index{marker/beginning}
\index{marker/end}
@@ -1278,6 +1176,217 @@
+\subsection{Coupure des pages et des lignes}
+
+\label{breakable}
+
+\subsubsection{Coupure des lignes}
+
+\label{line-breaks}
+
+Par défaut, les éléments produits par \pkg{piton} ne peuvent pas être coupés par une fin
+de ligne. Il existe néanmoins des clés pour autoriser de telles coupures (les points de
+coupure possibles sont les espaces, y compris les espaces dans les chaînes Python).
+\begin{itemize}
+\item \index{break-lines!break-lines-in-piton} Avec la clé
+\Definition{break-lines-in-piton}, les coupures de ligne sont autorisées dans la commande
+|\piton{...}| (mais pas dans la commande \verb+\piton|...|+, c'est-à-dire avec la syntaxe
+verbatim).
+
+\item \index{break-lines!break-lines-in-Piton} Avec la clé
+\Definition{break-lines-in-Piton}, les coupures de ligne sont autorisées dans
+l'environnement |{Piton}| (d'où la lettre |P| capitale dans le nom) et les listings
+produits par |\PitonInputFile|.
+
+\item \index{break-lines} La clé \Definition{break-lines} est la conjonction des deux clés
+précédentes.
+\end{itemize}
+
+\medskip
+L'extension \pkg{piton} fournit aussi plusieurs clés pour contrôler l'apparence des
+coupures de ligne autorisées par |break-lines-in-Piton|.
+
+\begin{itemize}
+\item \index{indent-broken-lines} Avec la clé \Definition{indent-broken-lines},
+l'indentation de la ligne coupée est respectée à chaque retour à la ligne (à condition que
+la fonte utilisée soit une fonte mono-chasse, ce qui est le cas par défaut puisque la
+valeur initiale de |font-command| est |\ttfamily|).
+
+\item \index{end-of-broken-line} La clé \Definition{end-of-broken-line} correspond au
+symbole placé à la fin d'une ligne coupée. Sa valeur initiale est :
+|\hspace*{0.5em}\textbackslash|.
+
+\item \index{continuation-symbol} La clé \Definition{continuation-symbol} correspond au
+symbole placé à chaque retour de ligne dans la marge gauche. Sa valeur initiale est :
+|+\;| (la commande |\;| insère un petit espace horizontal).
+
+\item \index{continuation-symbol-on-indentation} La clé
+\Definition{continuation-symbol-on-indentation} correspond au symbole placé à chaque
+retour de ligne au niveau de l'indentation (uniquement dans le cas où la clé
+|indent-broken-lines| est active). Sa valeur initiale est : |$\hookrightarrow\;$|.
+\end{itemize}
+
+\bigskip
+Le code suivant a été composé avec le réglage suivant :
+
+\begin{Verbatim}
+\PitonOptions{width=12cm,break-lines,indent-broken-lines,background-color=gray!15}
+\end{Verbatim}
+
+
+\begin{center}
+\PitonOptions{width=12cm,break-lines,indent-broken-lines,background-color=gray!15}
+\begin{Piton}
+def dict_of_liste(liste):
+ """Convertit une liste de subrs et de descriptions de glyphes en dictionnaire"""
+ dict = {}
+ for liste_lettre in liste:
+ if (liste_lettre[0][0:3] == 'dup'): # si c'est un subr
+ nom = liste_lettre[0][4:-3]
+ print("On traite le subr de numéro " + nom)
+ else:
+ nom = liste_lettre[0][1:-3] # si c'est un glyphe
+ print("On traite le glyphe du caractère " + nom)
+ dict[nom] = [traite_ligne_Postscript(k) for k in liste_lettre[1:-1]]
+ return dict
+\end{Piton}
+\end{center}
+
+
+
+\subsubsection{Coupure des pages}
+
+\label{coupure-de-pages}
+\index{splittable}
+\index{splittable-on-empty-lines}
+
+
+Par défaut, les listings produits par l'environnement |{Piton}| et par la commande
+|\PitonInputFile| sont insécables.
+
+
+Néanmoins, \pkg{piton} propose les clés |splittable-on-empty-lines| et |splittable| pour
+autoriser de telles coupures.
+
+\begin{itemize}
+\item La clé \Definition{splittable-on-empty-lines} autorise les coupures sur les lignes
+vides du listing. Les lignes considérées comme vides sont celles qui ne comportent que des
+espaces (et il aurait peut-être été plus habile de parler de lignes blanches).
+
+\medskip
+\item La clé |splittable-on-empty-lines| peut bien sûr être insuffisante et c'est pourquoi
+\pkg{piton} propose la clé \Definition{splittable}.
+
+Quand la clé |splittable| est utilisée avec la valeur numérique $n$ (qui doit être un
+entier naturel non nul) le listing pourra être coupé n'importe où avec cette exception
+qu'aucune coupure ne pourra avoir lieu entre les $n$~premières lignes, ni entre les
+$n$~dernières.\footnote{Remarquer que l'on parle des lignes du listing d'origine, une
+ telle ligne pouvant être composée sur plusieurs lignes dans le \textsc{pdf} final si la
+ clé |break-lines-in-Piton| est utilisée.}
+
+Par exemple, |splittable = 4| pourrait être un réglage raisonnable.
+
+Employée sans argument, la clé |splittable| est équivalente à |splittable = 1|, et les
+listings sont alors sécables n'importe où (ce n'est pas recommandable).
+
+La valeur initiale de la clé |splittable| vaut 100, ce qui fait que les listings ne sont
+pas sécables.
+\end{itemize}
+
+\medskip
+\emph{Remarque}\par\nobreak
+
+Même avec une couleur de fond (fixée avec |background-color|), les sauts de page sont
+possibles, à partir du moment où |splittable-on-empty-lines| ou |splittable| est
+utilisée.\footnote{Avec la clé |splittable|, un environnement |{Piton}| est sécable même
+ dans un environnement de \pkg{tcolorbox} (à partir du moment où la clé |breakable| de
+ \pkg{tcolorbox} est utilisée). On précise cela parce que, en revanche, un environnement
+ de \pkg{tcolorbox} inclus dans un autre environnement de \pkg{tcolorbox} n'est pas
+ sécable, même quand les deux utilisent la clé |breakable|.}
+
+\bigskip
+\subsection{Découpe d'un listing en sous-listings}
+
+\index{split-on-empty-lines}
+\label{split-on-empty-lines}
+\index{split-separation}
+\index{env-used-by-split}
+
+L'exension \pkg{piton} fournit la clé \Definition{split-on-empty-lines}, qui ne doit pas
+être confondue avec la clé |splittable-on-empty-lines| définie précédemment.
+
+\smallskip
+Pour comprendre le fonctionnement de la clé |split-on-empty-lines|, il faut imaginer que
+l'on a à composer un fichier informatique qui contient une succession de définitions de
+fonctions informatiques. Dans la plupart des langages informatiques, ces définitions
+successives sont séparées par des lignes vides (ou plutôt des lignes blanches,
+c'est-à-dire des lignes qui ne contiennent que des espaces).
+
+\smallskip
+La clé |split-on-empty-lines| coupe le listing au niveau des lignes vides. Les lignes
+vides successives sont supprimées et remplacées par le contenu du paramètre correspondant
+à la clé \Definition{split-separation}.
+\begin{itemize}
+\item Ce paramètre doit contenir du matériel à insérer en \emph{mode vertical} de TeX. On
+peut, par exemple, mettre la primmitive TeX |\hrule|.
+
+\item La valeur initiale de ce paramètre est |\vspace{\baselineskip}\vspace{-1.25pt}|, ce qui,
+au final, correspond à une ligne vide dans le \textsc{pdf} produit (cet espace vertical
+est supprimé s'il tombe au niveau d'un saut de page).
+\end{itemize}
+
+
+\colorbox{yellow!50}{\textbf{Nouveau 4.0}}\par\nobreak
+
+Chaque morceau du code informatique est formaté (de manière autonome) dans un
+environnement dont le nom est donné par la clé \Definition{env-used-by-split}. La valeur
+initiale de ce paramètre est, sans surprise, |Piton| et les différents morceaux sont donc
+composés dans des environnements |{Piton}|. Si on décide de donner une autre valeur à la
+clé |env-used-by-split|, on doit bien sûr donner le nom d'un environnement créé par
+|\NewPitonEnvironment| (cf.~partie~\ref{NewPitonEnvironment},
+p.~\pageref{NewPitonEnvironment}).
+
+\smallskip
+Chaque morceau du listing de départ étant composé dans son environnement, il dispose de sa
+propre numérotation des lignes (si la clé |line-numbers| est active) et de son propre fond
+coloré (si la clé |background-color| est utilisée), séparé des fonds des autres morceaux.
+Si elle est active, la clé |splittable| s'applique de manière autonome dans chaque
+morceau. Bien sûr, des sauts de page peuvent intervenir entre les différents morceaux du
+code, quelle que soit la valeur de la clé |splittable|.
+
+\bigskip
+\begin{Verbatim}
+\begin{Piton}[~emphase#split-on-empty-lines@,background-color=gray!15,line-numbers]
+def carré(x):
+ """Calcule le carré de x"""
+ return x*x
+
+def cube(x):
+ """Calcule le cube de x"""
+ return x*x*x
+\end{Piton}
+\end{Verbatim}
+
+
+\begin{Piton}[split-on-empty-lines,background-color=gray!15,line-numbers]
+def carré(x):
+ """Calcule le carré de x"""
+ return x*x
+
+def cube(x):
+ """Calcule le cube de x"""
+ return x*x*x
+\end{Piton}
+
+
+\bigskip
+\textbf{Attention} : Comme chaque morceau est traité de manière indépendante, les
+commandes spécifiées par |detected-commands| et les commandes et environnements de Beamer
+automatiquement détectés par \pkg{piton} ne doivent pas enjamber les lignes vides du
+listing de départ.
+
+
+\bigskip
\subsection{Mise en évidence d'identificateurs}
\indexcommand{SetPitonIdentifier}
@@ -1509,9 +1618,10 @@
\medskip
Dans l'exemple suivant, qui est une programmation récursive de la factorielle, on décide
-de surligner en jaune l'appel récursif. La commande |\highLight| de \pkg{lua-ul} (cette
-extension requiert elle-même l'extension \pkg{luacolor}) permet de le faire avec la
-syntaxe |\hightLight{...}|.
+de surligner en jaune l'appel récursif. La commande |\highLight| de
+\pkg{lua-ul}\footnote{L'extension \pkg{lua-ul} requiert elle-même l'extension
+ \pkg{luacolor}.} permet de le faire facilement avec la
+syntaxe |\highLight{...}|.
\smallskip
On suppose que l'on a mis dans le préambule du document LaTeX l'instruction suivante :
@@ -1724,9 +1834,9 @@
|#> \pause|. Ainsi, si le code Python est copié, il est interprétable par Python.} ;
\item un argument obligatoire : |\action|, |\alert|, |\invisible|, |\only|, |\uncover| et
|\visible| ; \newline
-\colorbox{yellow!50}{\bfseries Nouveau 3.1} on peut rajouter à cette liste de
-nouveaux noms de commandes avec la clé \Definition{detected-beamer-commands} (les noms de
-commandes ne doivent \emph{pas} être précédés de la contre-oblique) ;
+La clé \Definition{detected-beamer-commands} permet de rajouter à cette liste de nouveaux
+noms de commandes (les noms de commandes ne doivent \emph{pas} être précédés de la
+contre-oblique) ;
\item deux arguments obligatoires : |\alt| ;
\item trois arguments obligatoires : |\temporal|.
\end{itemize}
@@ -1779,8 +1889,8 @@
|{visibleenv}|.
\smallskip
-\index{detected-beamer-environments} \colorbox{yellow!50}{\bfseries Nouveau 3.1}\enskip On
-peut ajouter de nouveaux environnements à cette liste d'environnements reconnus avec la
+\index{detected-beamer-environments}
+On peut ajouter de nouveaux environnements à cette liste d'environnements reconnus avec la
clé \Definition{detected-beamer-environments}.
\medskip
@@ -1850,11 +1960,7 @@
|{alertenv}|).
-
\bigskip
-
-
-\bigskip
\subsection{Notes de pied de page dans les environnements de piton}
\index{footnote@\pkg{footnote} (extension)}
@@ -1900,12 +2006,12 @@
\bigskip
Par défaut, une commande |\footnote| ne peut apparaître que dans un «commentaire LaTeX».
Mais on peut aussi ajouter la commande |\footnote| à la liste des
-``\emph{detected-commands}'' (cf.~partie~\ref{detected-commands},
+\emph{detected-commands} (cf.~partie~\ref{detected-commands},
p.~\pageref{detected-commands}).
\medskip
Dans ce document, l'extension \pkg{piton} a été chargée avec l'option |footnotehyper| et
-on rajouté la commande |\footnote| aux ``\emph{detected-commands}'' avec le code suivant
+on rajouté la commande |\footnote| aux \emph{detected-commands} avec le code suivant
dans la préambule du document LaTeX :
\qquad \verb|\PitonOptions{detected-commands = footnote}|
@@ -1944,7 +2050,7 @@
Si on utilise l'environnement |{Piton}| dans un environnement |{minipage}| de LaTeX, les
notes sont, bien entendu, composées au bas de l'environnement |{minipage}|. Rappelons
-qu'une telle |{minipage}| ne peut être coupée par un saut de page.
+qu'une telle |{minipage}| ne peut \emph{pas} être coupée par un saut de page.
\begingroup
@@ -1988,7 +2094,8 @@
\index{tab-size}
\smallskip
-Même s'il est recommandé d'indenter les listings Python avec des espaces (cf. PEP~8),
+Même s'il est sans doute recommandable d'indenter les listings informatiques avec des
+espaces et non des tabulations\footnote{Voir, par exemple, pour le langage Piton, la note PEP~8},
\pkg{piton} accepte les caractères de tabulations (U+0009) en début de ligne. Chaque
caractère U+0009 est remplacé par $n$ espaces. La valeur initiale de~$n$ est~4 mais on
peut la changer avec la clé \Definition{tab-size} de |\PitonOptions|.
@@ -2010,14 +2117,13 @@
\index{piton.last@\texttt{piton.get\_last\_code} (fonction Lua)}
\label{API}
-La variable L3 |\l_piton_language_str| contient le nom du langage courant (en minuscules).
+La variable L3 \DefinitionCommand{l_piton_language_str} contient le nom du langage courant
+(en minuscules).
\bigskip
-\colorbox{yellow!50}{\textbf{Nouveau 2.6}}\par\nobreak
-
-L'extension \pkg{piton} fournit une fonction Lua |piton.get_last_code| sans argument
-permettant de récupérer le code contenu dans le dernier environnement de \pkg{piton}.
+L'extension \pkg{piton} fournit une fonction Lua \Definition{piton.get_last_code} sans
+argument permettant de récupérer le code contenu dans le dernier environnement de \pkg{piton}.
\begin{itemize}
\item Les retours à la ligne (présents dans l'environnement de départ) apparaissent comme
des caractères |\r| (c'est-à-dire des caractères U+000D).
@@ -2040,7 +2146,6 @@
Pour un exemple d'utilisation, voir la partie concernant l'utilisation (standard) de \pkg{pyluatex},
partie~\ref{pyluatex}, p.~\pageref{pyluatex}.
-
\section{Exemples}
\subsection{Numérotation des lignes}
@@ -2187,10 +2292,7 @@
Les styles graphiques ont été présentés à la partie \ref{styles}, p.~\pageref{styles}.
\smallskip
-On présente ici un réglage de ces styles adapté pour les documents en noir et blanc. On
-l'utilise avec la fonte \emph{DejaVu Sans Mono}\footnote{Voir:
- \url{https://dejavu-fonts.github.io}} spécifiée avec la commande |\setmonofont| de
-\pkg{fontspec}.
+On présente ici un réglage de ces styles adapté pour les documents en noir et blanc.
Ce réglage utilise la commande |\highLight| de \pkg{lua-ul} (cette extension nécessite
elle-même l'extension \pkg{luacolor}).
@@ -2197,8 +2299,6 @@
\begin{Verbatim}
-\setmonofont[Scale=0.85]{DejaVu Sans Mono}
-
\SetPitonStyle
{
Number = ,
@@ -2227,9 +2327,6 @@
\begingroup
-
-\setmonofont[Scale=0.85]{DejaVu Sans Mono}
-
\SetPitonStyle
{
Number = ,
Modified: trunk/Master/texmf-dist/doc/lualatex/piton/piton.pdf
===================================================================
(Binary files differ)
Modified: trunk/Master/texmf-dist/source/lualatex/piton/piton.dtx
===================================================================
--- trunk/Master/texmf-dist/source/lualatex/piton/piton.dtx 2024-09-22 20:22:16 UTC (rev 72350)
+++ trunk/Master/texmf-dist/source/lualatex/piton/piton.dtx 2024-09-22 20:22:25 UTC (rev 72351)
@@ -79,12 +79,12 @@
% \iffalse
%<*STY>
% \fi
-\def\PitonFileVersion{3.1b}
-\def\PitonFileDate{2024/08/29}
+\def\PitonFileVersion{4.0}
+\def\PitonFileDate{2024/09/22}
% \iffalse
%</STY>
%<*LUA>
-piton_version = "3.1b" -- 2024/08/29
+piton_version = "4.0" -- 2024/09/22
%</LUA>
%\fi
%
@@ -101,6 +101,10 @@
% syntactic highlighting, by using the Lua library LPEG. It requires LuaLaTeX.
% \end{abstract}
%
+% \bigskip
+% {\color{red} In the version 4.0, the syntax of the absolute and relative
+% paths used in |\PitonInputFile| has been changed:
+% cf.~part~\ref{PitonInputFile}, p.~\pageref{PitonInputFile}.}
%
%
% \section{Presentation}
@@ -143,11 +147,11 @@
% \end{Piton}
%
%
-% \bigskip
+% \medskip
% The main alternatives to the package \pkg{piton} are probably the packages
% \pkg{listings} and \pkg{minted}.
%
-% \bigskip
+% \medskip
% The name of this extension (\pkg{piton}) has been chosen arbitrarily by
% reference to the pitons used by the climbers in alpinism.
%
@@ -186,8 +190,8 @@
% |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}).
+% those languages can't be as precise as those of the languages supported
+% natively by \pkg{piton}).
% \end{itemize}
%
%
@@ -197,7 +201,7 @@
% \smallskip
% \index{language (key)}
% It's possible to change the current language with the command |\PitonOptions|
-% and its key |language|: |\PitonOptions{language = OCaml}|.
+% and its key \Definition{language}: |\PitonOptions{language = OCaml}|.
%
% \smallskip
% In fact, for \pkg{piton}, the names of the informatic languages are always
@@ -216,12 +220,12 @@
%
% \indexenv{Piton}
%
-% The package \pkg{piton} provides several tools to typeset Python codes: the
+% The package \pkg{piton} provides several tools to typeset informatic codes: the
% command |\piton|, the environment |{Piton}| and the command |\PitonInputFile|.
%
% \begin{itemize}\setlength{\fboxsep}{1pt}
-% \item The command \colorbox{gray!20}{\texttt\textbackslash piton} should be
-% used to typeset small pieces of code inside a paragraph. For example:
+% \item The command \DefinitionCommand{piton} should be used to typeset small
+% pieces of code inside a paragraph. For example:
%
% {\color{gray}\verb|\piton{def square(x): return x*x}|}\qquad
% \piton{def square(x): return x*x}
@@ -235,23 +239,11 @@
% environment |{Piton}| with the command |\NewPitonEnvironment|:
% cf.~\ref{NewPitonEnvironment} p.~\pageref{NewPitonEnvironment}.
%
-% \item The command \colorbox{gray!20}{\ttfamily\textbackslash PitonInputFile}
-% is used to insert and typeset a external file.
+% \item The command \DefinitionCommand{PitonInputFile} is used to insert and
+% typeset an external file: cf.~\ref{PitonInputFile}
+% p.~\pageref{PitonInputFile}.
%
-% It's possible to insert only a part of the file: cf.
-% part~\ref{part-of-a-file}, p.~\pageref{part-of-a-file}.
%
-% 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 executed if the file to include has been found (letter~|T|)
-% or not found (letter~|F|).
% \end{itemize}
%
% \subsection{The syntax of the command \textbackslash piton}
@@ -261,8 +253,8 @@
% In fact, the command |\piton| is provided with a double syntax. It may be used
% as a standard command of LaTeX taking its argument between curly braces
% (|\piton{...}|) but it may also be used with a syntax similar to the syntax of
-% the command
-% |\verb|, that is to say with the argument delimited by two identical characters (e.g.: \verb!\piton|...|!).
+% the command |\verb|, that is to say with the argument delimited by two identical
+% characters (e.g.: \verb!\piton|...|!).
%
% \begin{itemize}
% \item {\color{blue} \textsf{Syntax} \verb|\piton{...}|}\par\nobreak
@@ -283,8 +275,7 @@
% {\color{cyan} but the commands |\{| and |\}| are also provided for individual braces};
%
% \item the LaTeX commands\footnote{That concerns the commands beginning with a
-% backslash but also the active characters (with catcode equal to 13).} are
-% fully expanded and not executed,
+% backslash but also the active characters (with catcode equal to 13). } are fully expanded and not executed,
%
% {\color{cyan} so it's possible to use |\\| to insert a backslash}.
% \end{itemize}
@@ -315,6 +306,10 @@
% \texttt{\textbackslash piton} in a footnote. Example :
% \piton{s = 'A string'}.}
%
+% However, since the argument is expanded (in the TeX sens), one should take
+% care not using in its argument \emph{fragile} commands (that is to say
+% commands which are neither \emph{protected} nor \emph{fully expandable}).
+%
% \bigskip
% \item {\color{blue} \textsf{Syntax} \verb!\piton|...|!}\par\nobreak
%
@@ -368,10 +363,16 @@
% (cf.~part~\ref{NewPitonLanguage}, p.~\pageref{NewPitonLanguage}.
%
% The initial value is |Python|.
+%
+% \item \index{font-command}
+% \colorbox{yellow!50}{\textbf{New 4.0}}\par\nobreak
+%
+% The key \Definition{font-command} contains instructions of font which will be
+% inserted at the beginning of all the elements composed by \pkg{piton}.
+%
+% The initial value is |\ttfamily| and, thus, \pkg{piton} uses by default the
+% current monospaced font.
%
-% \item \index{path} The key \Definition{path} specifies a path where the files
-% included by |\PitonInputFile| will be searched.
-%
% \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 highlighting of the code) for each line of the environment
@@ -439,8 +440,7 @@
% \item The key \Definition{line-numbers/sep} is the horizontal distance between
% the numbers of lines (inserted by |line-numbers|) and the beginning of the
% lines of code. The initial value is 0.7~em.
-% \item \colorbox{yellow!50}{\bfseries New 3.1}\enskip The key
-% \Definition{line-numbers/format} is a list of tokens which are inserted before
+% \item The key \Definition{line-numbers/format} is a list of tokens which are inserted before
% the number of line in order to format it. It's possible to put, \emph{at the
% end} of the list, a LaTeX command with one argument, such as, for example,
% |\fbox|.
@@ -489,11 +489,6 @@
% The key |background-color| accepts a color defined «on the fly». For example,
% it's possible to write |background-color = [cmyk]{0.1,0.05,0,0}|.
%
-% \smallskip
-% When the key |split-on-empty-lines| is in force (see the part ``Page breaks'',
-% p.~\pageref{page breaks}), the empty lines generated by that key don't have
-% any background color (at least with the initial value of the parameter
-% |split-separation|).
%
% \item \index{prompt-background-color} With the key
% \Definition{prompt-background-color}, \pkg{piton} adds a
@@ -625,17 +620,17 @@
% package \pkg{luacolor}).
%
% \begin{verbatim}
-% \SetPitonStyle{ Name.Function = \bfseries \highLight[red!50] }
+% \SetPitonStyle{ Name.Function = \bfseries \highLight[red!30] }
% \end{verbatim}
%
-% In that example, |\highLight[red!50]| must be considered as the name of a
+% In that example, |\highLight[red!30]| must be considered as the name of a
% LaTeX command which takes in exactly one argument, since, usually, it is used
-% with |\highLight[red!50]{...}|.
+% with |\highLight[red!30]{...}|.
%
% \medskip
% \begingroup
% \SetPitonStyle
-% { Name.Function = \bfseries \highLight[red!50] }
+% { Name.Function = \bfseries \highLight[red!30] }
% With that setting, we will have : \piton{def cube(x) : return x * x * x }
% \endgroup
%
@@ -841,7 +836,6 @@
% \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
@@ -860,7 +854,7 @@
% 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
+% languages provided natively (Python, OCaml, C, SQL and |minimal|), which
% allows more powerful parsers.
%
% \medskip
@@ -933,7 +927,7 @@
% \bigskip
% \begingroup
% \small
-% \PitonOptions{split-on-empty-lines}
+% \PitonOptions{splittable-on-empty-lines}
% \begin{Piton}[language = java]
% public class Cipher { // Caesar cipher
% public static void main(String[] args) {
@@ -992,146 +986,55 @@
% category of the letters.
%
% \section{Advanced features}
+% \subsection{Insertion of a file}
%
-% \subsection{Page breaks and line breaks}
+% \label{PitonInputFile}
%
-% \label{breakable}
+% \subsubsection{The command \textbackslash PitonInputFile}
%
-% \subsubsection{Page breaks}
-% \label{page breaks}
-% \index{splittable}
+% \indexcommand{PitonInputFile}
%
-% By default, the listings produced by the environment |{Piton}| and the command
-% |\PitonInputFile| are not breakable.
-%
-% However, the command |\PitonOptions| provides the keys |split-on-empty-lines|
-% and |splittable| to allow such breaks.
-%
-% \begin{itemize}
-% \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 separate the
-% definitions of the informatic functions and it's pertinent to allow breaks
-% between these functions.
-%
-% In fact, when the key |split-on-empty-lines| is in force, the work goes a
-% little further than merely allowing page breaks: several successive empty lines
-% are deleted and replaced by the content of the parameter corresponding to the
-% key \Definition{split-separation}.
-% \begin{itemize}
-% \item That parameter must contain elements allowed to be inserted in
-% \emph{vertical mode} of TeX. For example, it's possible to put |\hrule|.
-%
-% \item The initial value of this parameter is
-% |\vspace{\baselineskip}\vspace{-1.25pt}| which corresponds eventually to an
-% empty line in the final PDF (this vertical space is deleted if it occurs on a
-% page break). If the key |background-color| is in force, no background color is
-% added to that empty line.
-% \end{itemize}
-%
-% \item Of course, the key |split-on-empty-lines| may not be sufficient and
-% that's why \pkg{piton} provides the key \Definition{splittable}.
-%
-% When the key |splittable| is used with the numeric value~$n$ (which must be a
-% positive integer) the listing, or each part of the listing delimited by empty
-% lines (when |split-on-empty-lines| is in force) may be broken anywhere with
-% the restriction that no break will occur within the $n$ first lines of
-% the listing or within the $n$ last lines. For example, a tuning with
-% |splittable = 4| may be a good choice.
-%
-% When used without value, the key |splittable| is equivalent to
-% |splittable = 1| and the listings may be broken anywhere (it's probably
-% not recommandable).
-%
-% The initial value of the key |splittable| is equal to 100 (by default, the
-% listings are not breakable at all).
-% \end{itemize}
+% The command \DefinitionCommand{PitonInputFile} includes the content of the
+% file specified in argument (or only a part of that file: see below). The
+% extension \pkg{piton} also provides the commands
+% \DefinitionCommand{PitonInputFileT}, \DefinitionCommand{PitonInputFileF} and
+% \DefinitionCommand{PitonInputFileTF} with supplementary arguments
+% corresponding to the letters~|T| and~|F|. Those arguments will be executed if
+% the file to include has been found (letter~|T|) or not found (letter~|F|).
%
+% \bigskip
+% \colorbox{yellow!50}{\textbf{Modification 4.0}}\par\nobreak
%
+% \index{old-PitonInputFile}
+% \smallskip
+% The syntax for the absolute and relative paths has been changed in order to
+% be conform to the traditionnal usages. However, it's possible to use the key
+% \Definition{old-PitonInputFile} at load-time (that is to say with the
+% |\usepackage|) in order to have the old behaviour (though, that key will be
+% deleted in a future version of \pkg{piton}!).
%
-% \medskip
-% Even with a background color (set by the key |background-color|), the pages
-% breaks are allowed, as soon as the key |split-on-empty-lines| or the key
-% |splittable| is in force.\footnote{With the key |splittable|, the environments
-% \texttt{\{Piton\}} are breakable, even within a (breakable) environment of
-% \pkg{tcolorbox}. Remind that an environment of \pkg{tcolorbox} included in
-% another environment of \pkg{tcolorbox} is \emph{not} breakable, even when both
-% environments use the key |breakable| of \pkg{tcolorbox}.}
-%
-%
-% \subsubsection{Line breaks}
-%
-% \label{line-breaks}
-%
-% By default, the elements produced by \pkg{piton} can't be broken by an end on
-% line. However, there are keys to allow such breaks (the possible breaking
-% points are the spaces, even the spaces in the Python strings).
+% \smallskip
+% Now, the syntax if the following one:
% \begin{itemize}
-% \item \index{break-lines!break-lines-in-piton} With the key
-% \Definition{break-lines-in-piton}, the line breaks are allowed in the command
-% |\piton{...}| (but not in the command \verb+\piton|...|+, that is to say the
-% command |\piton| in verbatim mode).
-% \item \index{break-lines!break-lines-in-Piton} With the key
-% \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 conjunction of
-% the two previous keys.
-% \end{itemize}
-%
-% \bigskip
-% The package \pkg{piton} provides also several keys to control the appearance
-% on the line breaks allowed by |break-lines-in-Piton|.
+% \item The paths beginning by |/| are absolute.
%
-% \begin{itemize}
-% \item \index{indent-broken-lines} With the key
-% \Definition{indent-broken-lines}, the indentation of a
-% broken line is respected at carriage return.
+% \emph{Example} : |\PitonInputFile{/Users/joe/Documents/program.py}|
%
-% \item The key \Definition{end-of-broken-line} corresponds to the symbol placed
-% at the end of a broken line. The initial value is:
-% |\hspace*{0.5em}\textbackslash|.
+% \item The paths which do not begin with |/| are relative to the current
+% repertory.
%
-% \item \index{continuation-symbol} The key \Definition{continuation-symbol}
-% corresponds to the symbol placed at each carriage return. The initial value
-% is: |+\;| (the command |\;| inserts a small horizontal space).
-%
-% \item \index{continuation-symbol-on-indentation}
-% The key \Definition{continuation-symbol-on-indentation} corresponds to
-% the symbol placed at each carriage return, on the position of the indentation
-% (only when the key |indent-broken-line| is in force). The initial value is:
-% |$\hookrightarrow\;$|.
+% \emph{Example} : |\PitonInputFile{my_listings/program.py}|
% \end{itemize}
%
+% \index{path}
+% 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.
%
-% \bigskip
-% The following code has been composed with the following tuning:
+% As previously, the absolute paths must begin with |/|.
%
-% \begin{Verbatim}
-% \PitonOptions{width=12cm,break-lines,indent-broken-lines,background-color=gray!15}
-% \end{Verbatim}
-%
-% \begin{center}
-% \PitonOptions{width=12cm,break-lines,indent-broken-lines,background-color=gray!15}
-% \begin{Piton}
-% def dict_of_list(l):
-% """Converts a list of subrs and descriptions of glyphs in a dictionary"""
-% our_dict = {}
-% for list_letter in l:
-% if (list_letter[0][0:3] == 'dup'): # if it's a subr
-% name = list_letter[0][4:-3]
-% print("We treat the subr of number " + name)
-% else:
-% name = list_letter[0][1:-3] # if it's a glyph
-% print("We treat the glyph of number " + name)
-% our_dict[name] = [treat_Postscript_line(k) for k in list_letter[1:-1]]
-% return dict
-% \end{Piton}
-% \end{center}
-%
-%
% \bigskip
-% \subsection{Insertion of a part of a file}
+% \subsubsection{Insertion of a part of a file}
%
% \label{part-of-a-file}
% \indexcommand{PitonInputFile}
@@ -1147,7 +1050,8 @@
% In both cases, if we want to number the lines with the numbers of the
% lines in the file, we have to use the key |line-numbers/absolute|.
%
-% \subsubsection{With line numbers}
+% \bigskip
+% \textbf{With line numbers}\par\nobreak
%
% The command |\PitonInputFile| supports the keys \Definition{first-line} and
% \Definition{last-line} in order to insert only the part of file between the
@@ -1156,7 +1060,8 @@
% |line-numbers/start| deals with the output whereas |first-line| and
% |last-line| deal with the input.
%
-% \subsubsection{With textual markers}
+% \bigskip
+% \textbf{With textual markers}\par\nobreak
%
% \index{marker/beginning}
% \index{marker/end}
@@ -1272,6 +1177,209 @@
%
%
%
+% \bigskip
+% \subsection{Page breaks and line breaks}
+%
+% \label{breakable}
+%
+% \subsubsection{Line breaks}
+%
+% \label{line-breaks}
+%
+% By default, the elements produced by \pkg{piton} can't be broken by an end on
+% line. However, there are keys to allow such breaks (the possible breaking
+% points are the spaces, even the spaces in the Python strings).
+% \begin{itemize}
+% \item \index{break-lines!break-lines-in-piton} With the key
+% \Definition{break-lines-in-piton}, the line breaks are allowed in the command
+% |\piton{...}| (but not in the command \verb+\piton|...|+, that is to say the
+% command |\piton| in verbatim mode).
+% \item \index{break-lines!break-lines-in-Piton} With the key
+% \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 conjunction of
+% the two previous keys.
+% \end{itemize}
+%
+% \bigskip
+% The package \pkg{piton} provides also several keys to control the appearance
+% on the line breaks allowed by |break-lines-in-Piton|.
+%
+% \begin{itemize}
+% \item \index{indent-broken-lines} With the key
+% \Definition{indent-broken-lines}, the indentation of a
+% broken line is respected at carriage return (on the condition that the used
+% font is a monospaced font and this is the case by default since the initial
+% value of |font-command| is |\ttfamily|).
+%
+% \item The key \Definition{end-of-broken-line} corresponds to the symbol placed
+% at the end of a broken line. The initial value is:
+% |\hspace*{0.5em}\textbackslash|.
+%
+% \item \index{continuation-symbol} The key \Definition{continuation-symbol}
+% corresponds to the symbol placed at each carriage return. The initial value
+% is: |+\;| (the command |\;| inserts a small horizontal space).
+%
+% \item \index{continuation-symbol-on-indentation}
+% The key \Definition{continuation-symbol-on-indentation} corresponds to
+% the symbol placed at each carriage return, on the position of the indentation
+% (only when the key |indent-broken-line| is in force). The initial value is:
+% |$\hookrightarrow\;$|.
+% \end{itemize}
+%
+%
+% \bigskip
+% The following code has been composed with the following tuning:
+%
+% \begin{Verbatim}
+% \PitonOptions{width=12cm,break-lines,indent-broken-lines,background-color=gray!15}
+% \end{Verbatim}
+%
+% \begin{center}
+% \PitonOptions{width=12cm,break-lines,indent-broken-lines,background-color=gray!15}
+% \begin{Piton}
+% def dict_of_list(l):
+% """Converts a list of subrs and descriptions of glyphs in a dictionary"""
+% our_dict = {}
+% for list_letter in l:
+% if (list_letter[0][0:3] == 'dup'): # if it's a subr
+% name = list_letter[0][4:-3]
+% print("We treat the subr of number " + name)
+% else:
+% name = list_letter[0][1:-3] # if it's a glyph
+% print("We treat the glyph of number " + name)
+% our_dict[name] = [treat_Postscript_line(k) for k in list_letter[1:-1]]
+% return dict
+% \end{Piton}
+% \end{center}
+%
+% \subsubsection{Page breaks}
+% \label{page breaks}
+% \index{splittable}
+% \index{splittable-on-empty-lines}
+%
+% By default, the listings produced by the environment |{Piton}| and the command
+% |\PitonInputFile| are not breakable.
+%
+% However, \pkg{piton} provides the keys |splittable-on-empty-lines| and
+% |splittable| to allow such breaks.
+%
+% \begin{itemize}
+% \item The key \Definition{splittable-on-empty-lines} allows breaks on the empty
+% lines. The ``empty lines'' are in fact the lines which contains only spaces.
+%
+% \item Of course, the key |splittable-on-empty-lines| may not be sufficient and
+% that's why \pkg{piton} provides the key \Definition{splittable}.
+%
+% When the key |splittable| is used with the numeric value~$n$ (which must be a
+% positive integer) the listing, or each part of the listing delimited by empty
+% lines (when |split-on-empty-lines| is in force) may be broken anywhere with
+% the restriction that no break will occur within the $n$ first lines of
+% the listing or within the $n$ last lines.\footnote{Remark that we speak of the
+% lines of the original informatic listing and such line may be composed on
+% several lines in the final \textsc{pdf} when the key |break-lines-in-Piton| is
+% in force.}
+%
+% For example, a tuning with |splittable = 4| may be a good choice.
+%
+% When used without value, the key |splittable| is equivalent to
+% |splittable = 1| and the listings may be broken anywhere (it's probably
+% not recommandable).
+%
+% The initial value of the key |splittable| is equal to 100 (by default, the
+% listings are not breakable at all).
+% \end{itemize}
+%
+% \medskip
+% Even with a background color (set by the key |background-color|), the pages
+% breaks are allowed, as soon as the key |split-on-empty-lines| or the key
+% |splittable| is in force.\footnote{With the key |splittable|, the environments
+% \texttt{\{Piton\}} are breakable, even within a (breakable) environment of
+% \pkg{tcolorbox}. Remind that an environment of \pkg{tcolorbox} included in
+% another environment of \pkg{tcolorbox} is \emph{not} breakable, even when both
+% environments use the key |breakable| of \pkg{tcolorbox}.}
+%
+% \subsection{Splitting of a listing in sub-listings}
+%
+% \index{split-on-empty-lines}
+% \label{split-on-empty-lines}
+% \index{split-separation}
+%
+% The extension \pkg{piton} provides the key \Definition{split-on-empty-lines},
+% which should not be confused with the key |splittable-on-empty-lines|
+% previously defined.
+%
+% \smallskip
+% In order to understand the behaviour of the key |split-on-empty-lines|, one
+% should imagine that he has to compose an informatic listing which contains
+% several definitions of informatic functions. Usually, in the informatic
+% languages, those definitions of functions are separated by empty lines.
+%
+% \smallskip
+% The key |split-on-empty-lines| splits the listings on the empty lines. Several
+% empty lines are deleted and replaced by the content of the parameter
+% corresponding to the key \Definition{split-separation}.
+% \begin{itemize}
+% \item That parameter must contain elements allowed to be inserted in
+% \emph{vertical mode} of TeX. For example, it's possible to put the TeX
+% primitive |\hrule|.
+%
+% \item The initial value of this parameter is
+% |\vspace{\baselineskip}\vspace{-1.25pt}| which corresponds eventually to an
+% empty line in the final \textsc{pdf} (this vertical space is deleted if it
+% occurs on a page break). If the key |background-color| is in force, no
+% background color is added to that empty line.
+% \end{itemize}
+%
+%
+% \colorbox{yellow!50}{\textbf{New 4.0}}\par\nobreak
+% Each chunk of the informatic listing is composed in an environment whose name
+% is given by the key \Definition{env-used-by-split}. The initial value of that
+% parameter is, not surprisingly, |Piton| and, hence, the different chunks are
+% composed in several environments |{Piton}|. If one decides to change the value
+% of |env-used-by-split|, he should use the name of an environment created by
+% |\NewPitonEnvironment| (cf.~part~\ref{NewPitonEnvironment},
+% p.~\pageref{NewPitonEnvironment}).
+%
+% Each chunk of the informatic listing is formated in its own environment.
+% Therefore, it has its own line numbering (if the key
+% |line-numbers| is in force) and its own colored background (when the key
+% |background-color| is in force), separated from the background color of the
+% other chunks. When used, the key |splittable| applies in each chunk
+% (independently of the other chunks). Of course, a page break may occur between
+% the chunks of code, regardless of the value of |splittable|.
+%
+% \bigskip
+% \begin{Verbatim}
+% \begin{Piton}[~emphase#split-on-empty-lines@,background-color=gray!15,line-numbers]
+% def square(x):
+% """Computes the square of x"""
+% return x*x
+%
+% def cube(x):
+% """Calcule the cube of x"""
+% return x*x*x
+% \end{Piton}
+% \end{Verbatim}
+%
+%
+% \begin{Piton}[split-on-empty-lines,background-color=gray!15,line-numbers]
+% def square(x):
+% """Computes the square of x"""
+% return x*x
+%
+% def cube(x):
+% """Calcule the cube of x"""
+% return x*x*x
+% \end{Piton}
+%
+% \bigskip
+% \textbf{Caution}: Since each chunk is treated independently of the others, the
+% commands specified by |detected-commands| and the commands and environments
+% of Beamer automatically detected by \pkg{piton} must not cross the enmpty
+% lines of the original listing.
+%
% \subsection{Highlighting some identifiers}
%
% \label{SetPitonIdentifier}
@@ -1293,7 +1401,7 @@
% identifiers.
%
% \item The second mandatory argument is a list of LaTeX instructions of the
-% same type as \pkg{piton} ``styles'' previously presented (cf~\ref{styles}
+% same type as \pkg{piton} ``styles'' previously presented (cf.~\ref{styles}
% p.~\pageref{styles}).
% \end{itemize}
%
@@ -1491,8 +1599,14 @@
% between braces (and these braces must appear explicitly in the informatic listing).
% \end{itemize}
%
-% \medskip
-% We assume that the preamble of the LaTeX document contains the following line.
+% \bigskip
+% In the following example, which is a recursive programmation of the factorial
+% function, we decide to highlight the recursive call. The command |\highLight|
+% of \pkg{lua-ul}\footnote{The package \pkg{lua-ul} requires itself the package
+% \pkg{luacolor}.} directly does the job with the easy syntax |\highLight{...}|.
+%
+% \medskip
+% We assume that the preamble of the LaTeX document contains the following line:
% \begin{Verbatim}
% \PitonOptions{~emphase#detected-commands@ = highLight}
% \end{Verbatim}
@@ -1700,8 +1814,7 @@
% this way, if the Python code is copied, it's still executable by Python}. ;
% \item one mandatory argument : |\action|, |\alert|, |\invisible|, |\only|,
% |\uncover| and |\visible| ; \newline
-% \colorbox{yellow!50}{\bfseries New 3.1}\newline
-% It's possible to add new commands to that list with the key
+% % It's possible to add new commands to that list with the key
% \Definition{detected-beamer-commands} (the names of the commands must
% \emph{not} be preceded by a backslash).
% \item two mandatory arguments : |\alt| ;
@@ -1756,8 +1869,6 @@
%
% \smallskip
% \index{detected-beamer-environments}
-% \colorbox{yellow!50}{\bfseries New 3.1}
-%
% It's possible to add new environments to that list with the key
% \Definition{detected-beamer-environments}.
%
@@ -1960,8 +2071,9 @@
% \index{tab-size}
%
% \smallskip
-% Even though it's recommended to indent the Python listings with spaces (see
-% PEP~8), \pkg{piton} accepts the characters of tabulation (that is to say the
+% Even though it's probably recommended to indent the informatics listings with
+% spaces and not tabulations\footnote{For the language Python, see the note %
+% 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 \Definition{tab-size} of |\PitonOptions|.
@@ -1982,15 +2094,14 @@
%
% \label{API}
%
-% The L3 variable |\l_piton_language_str| contains the name of the current
-% language of \pkg{piton} (in lower case).
+% The L3 variable \DefinitionCommand{l_piton_language_str} contains the name of
+% the current language of \pkg{piton} (in lower case).
%
% \bigskip
-% \colorbox{yellow!50}{\textbf{New 2.6}}\par\nobreak
%
-% The extension \pkg{piton} provides a Lua function |piton.get_last_code|
-% without argument which returns the code in the latest environment of
-% \pkg{piton}.
+% The extension \pkg{piton} provides a Lua function
+% \Definition{piton.get_last_code} without argument which returns the code in
+% the latest environment of \pkg{piton}.
% \begin{itemize}
% \item The carriage returns (which are present in the initial environment)
% appears as characters |\r| (i.e. U+000D).
@@ -2168,16 +2279,12 @@
%
% \smallskip
% We present now an example of tuning of these styles adapted to the documents
-% in black and white. We use the font \emph{DejaVu Sans Mono}\footnote{See:
-% \url{https://dejavu-fonts.github.io}} specified by the command |\setmonofont| of
-% \pkg{fontspec}.
+% in black and white.
%
% That tuning uses the command |\highLight| of \pkg{lua-ul} (that package
% requires itself the package \pkg{luacolor}).
%
% \begin{Verbatim}
-% \setmonofont[Scale=0.85]{DejaVu Sans Mono}
-%
% \SetPitonStyle
% {
% Number = ,
@@ -2204,9 +2311,6 @@
% \pkg{piton} is \emph{not} empty.
%
% \begingroup
-%
-% \setmonofont[Scale=0.85]{DejaVu Sans Mono}
-%
% \PitonOptions{splittable}
%
% \SetPitonStyle
@@ -2881,7 +2985,8 @@
% \end{macrocode}
%
% \medskip
-% The following boolean corresponds to the key |math-comments| (available only at load-time).
+% The following boolean corresponds to the key |math-comments| (available only
+% in the preamble of the LaTeX document).
% \begin{macrocode}
\bool_new:N \g_@@_math_comments_bool
% \end{macrocode}
@@ -2891,6 +2996,16 @@
\bool_new:N \g_@@_beamer_bool
\tl_new:N \g_@@_escape_inside_tl
% \end{macrocode}
+%
+% \medskip
+% In version 4.0 of \pkg{piton}, we changed the mechanism used by \pkg{piton}
+% to search the file to load with |\PitonInputFile|. With the key
+% |old-PitonInputFile|, it's possible to keep the old behaviour but it's only
+% for backward compatibility and it will be deleted in a future version.
+% \begin{macrocode}
+\bool_new:N \l_@@_old_PitonInputFile_bool
+% \end{macrocode}
+%
%
% \bigskip
% We define a set of keys for the options at load-time.
@@ -2899,9 +3014,22 @@
{
footnote .bool_gset:N = \g_@@_footnote_bool ,
footnotehyper .bool_gset:N = \g_@@_footnotehyper_bool ,
+ footnote .usage:n = load ,
+ footnotehyper .usage:n = load ,
beamer .bool_gset:N = \g_@@_beamer_bool ,
beamer .default:n = true ,
+ beamer .usage:n = load ,
+% \end{macrocode}
+% \medskip
+% In version 4.0 of \pkg{piton}, we changed the mechanism used by \pkg{piton}
+% to search the file to load with |\PitonInputFile|. With the key
+% |old-PitonInputFile|, it's possible to keep the old behaviour but it's only
+% for backward compatibility and it will be deleted in a future version.
+% \begin{macrocode}
+ old-PitonInputFile .bool_set:N = \l_@@_old_PitonInputFile_bool ,
+ old-PitonInputFile .default:n = true ,
+ old-PitonInputFile .usage:n = load ,
unknown .code:n = \@@_error:n { Unknown~key~for~package }
}
@@ -2914,8 +3042,8 @@
{
Unknown~key.\\
You~have~used~the~key~'\l_keys_key_str'~but~the~only~keys~available~here~
- are~'beamer',~'footnote',~'footnotehyper'.~Other~keys~are~available~in~
- \token_to_str:N \PitonOptions.\\
+ are~'beamer',~'footnote',~'footnotehyper'~and~'old-PitonInputFile'.~
+ Other~keys~are~available~in~\token_to_str:N \PitonOptions.\\
That~key~will~be~ignored.
}
% \end{macrocode}
@@ -3011,8 +3139,8 @@
% \begin{macrocode}
\lua_now:n
{
- piton.BeamerCommands = lpeg.P ( "\\uncover" )
- + "\\only" + "\\visible" + "\\invisible" + "\\alert" + "\\action"
+ piton.BeamerCommands = lpeg.P ( [[\uncover]] )
+ + [[\only]] + [[\visible]] + [[\invisible]] + [[\alert]] + [[\action]]
piton.beamer_environments = { "uncoverenv" , "onlyenv" , "visibleenv" ,
"invisibleenv" , "alertenv" , "actionenv" }
piton.DetectedCommands = lpeg.P ( false )
@@ -3062,6 +3190,12 @@
\bool_new:N \l_@@_in_PitonInputFile_bool
% \end{macrocode}
%
+% \medskip
+% The following parameter corresponds to the key |font-command|.
+% \begin{macrocode}
+\tl_new:N \l_@@_font_command_tl
+\tl_set:Nn \l_@@_font_command_tl { \ttfamily }
+% \end{macrocode}
%
% \medskip
% We will compute (with Lua) the numbers of lines of the listings (or
@@ -3075,7 +3209,9 @@
% \begin{macrocode}
\int_new:N \l_@@_nb_non_empty_lines_int
% \end{macrocode}
+%
%
+% \medskip
% The following counter will be used to count the lines during the composition.
% It will take into account all the lines, empty or not empty. It won't be used
% to print the numbers of the lines but will be used to allow or disallow line
@@ -3120,7 +3256,6 @@
% \end{macrocode}
% That parameter must contain elements to be inserted in \emph{vertical} mode by
% TeX.
-%
%
%
% \medskip
@@ -3337,8 +3472,10 @@
% \end{macrocode}
%
% \medskip
+% Be careful: when executed, the following command does \emph{not} create a
+% space (only an incrementation of the counter).
% \begin{macrocode}
-\cs_new_protected:Npn \@@_an_indentation_space:
+\cs_new_protected:Npn \@@_leading_space:
{ \int_gincr:N \g_@@_indentation_int }
% \end{macrocode}
%
@@ -3365,8 +3502,8 @@
}
}
\@esphack
- }
- { \@@_error:n { label~with~lines~numbers } }
+ }
+ { \@@_error:n { label~with~lines~numbers } }
}
% \end{macrocode}
%
@@ -3383,13 +3520,6 @@
% \end{macrocode}
%
%
-% \bigskip
-% The following commands are a easy way to insert safely braces (|{| and |}|) in
-% the TeX flow.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_open_brace: { \lua_now:n { piton.open_brace() } }
-\cs_new_protected:Npn \@@_close_brace: { \lua_now:n { piton.close_brace() } }
-% \end{macrocode}
%
% \bigskip
% The following token list will be evaluated at the beginning of
@@ -3410,7 +3540,7 @@
\tl_gset:Nn \g_@@_begin_line_hook_tl
{
\tl_if_empty:NF \l_@@_prompt_bg_color_tl
- { \clist_set:NV \l_@@_bg_color_clist \l_@@_prompt_bg_color_tl }
+ { \clist_set:No \l_@@_bg_color_clist \l_@@_prompt_bg_color_tl }
}
}
% \end{macrocode}
@@ -3434,8 +3564,8 @@
\tl_set:Nn \l_tmpa_tl { #1 }
\bool_if:NTF \l_@@_show_spaces_bool
{
- \tl_set:Nn \l_@@_space_tl { ␣ }
- \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl % U+2423
+ \tl_set:Nn \l_@@_space_tl { ␣ } % U+2423
+ \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl
}
{
% \end{macrocode}
@@ -3451,6 +3581,10 @@
{ \x20 }
{ \c { @@_breakable_space: } }
\l_tmpa_tl
+ \regex_replace_all:nnN
+ { \c { l_@@_space_tl } }
+ { \c { @@_breakable_space: } }
+ \l_tmpa_tl
}
}
\l_tmpa_tl
@@ -3459,11 +3593,22 @@
%
% \bigskip
% In the contents provided by Lua, each line of the Python code will be
-% surrounded by |\@@_begin_line:| and |\@@_end_line:|. |\@@_begin_line:| is a
-% LaTeX command that we will define now but |\@@_end_line:| is only a syntactic
-% marker that has no definition.
+% surrounded by |\@@_begin_line:| and |\@@_end_line:|.
+
+% |\@@_begin_line:| is a
+% TeX command with a delimited argument (|\@@_end_line:| is the marker for the
+% end of the argument).
%
+% However, we define also |\@@_end_line:| as no-op, because, when the last line
+% of the listing is the end of an environment of Beamer (eg |\end{uncoverenv}|),
+% we will have a token |\@@_end_line:| added at the end without any
+% corresponding |\@@_begin_line:|).
% \begin{macrocode}
+\cs_set_protected:Npn \@@_end_line: { }
+% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
\cs_set_protected:Npn \@@_begin_line: #1 \@@_end_line:
{
\group_begin:
@@ -3496,16 +3641,30 @@
\skip_horizontal:N \l_@@_left_margin_dim
\bool_if:NT \l_@@_line_numbers_bool
{
- \bool_if:nF
- {
- \str_if_eq_p:nn { #1 } { \PitonStyle { Prompt } { } }
- &&
- \l_@@_skip_empty_lines_bool
+% \end{macrocode}
+% |\l_tmpa_int| will be true equal to $1$ when the current line is not empty.
+% \begin{macrocode}
+ \int_set:Nn \l_tmpa_int
+ {
+ \lua_now:e
+ {
+ tex.sprint
+ (
+ luatexbase.catcodetables.expl ,
+ tostring
+ ( piton.empty_lines
+ [ \int_eval:n { \g_@@_line_int + 1 } ]
+ )
+ )
+ }
}
+ \bool_lazy_or:nnT
+ { \int_compare_p:nNn \l_tmpa_int = \c_one_int }
+ { ! \l_@@_skip_empty_lines_bool }
{ \int_gincr:N \g_@@_visual_line_int }
\bool_if:nT
{
- ! \str_if_eq_p:nn { #1 } { \PitonStyle { Prompt } { } }
+ \int_compare_p:nNn \l_tmpa_int = \c_one_int
||
( ! \l_@@_skip_empty_lines_bool && \l_@@_label_empty_lines_bool )
}
@@ -3521,12 +3680,17 @@
% ... but if only if the key |left-margin| is not used !
% \begin{macrocode}
\dim_compare:nNnT \l_@@_left_margin_dim = \c_zero_dim
- { \skip_horizontal:n { 0.5 em } }
+ { \skip_horizontal:n { 0.5 em } }
}
\coffin_typeset:Nnnnn \l_tmpa_coffin T l \c_zero_dim \c_zero_dim
}
\box_set_dp:Nn \l_tmpa_box { \box_dp:N \l_tmpa_box + 1.25 pt }
\box_set_ht:Nn \l_tmpa_box { \box_ht:N \l_tmpa_box + 1.25 pt }
+% \end{macrocode}
+% We have to explicitely begin a paragraph because we will insert a TeX box (and
+% we don't want that box to be inserted in the vertical list).
+% \begin{macrocode}
+ \mode_leave_vertical:
\clist_if_empty:NTF \l_@@_bg_color_clist
{ \box_use_drop:N \l_tmpa_box }
{
@@ -3539,11 +3703,10 @@
depth \box_dp:N \l_tmpa_box
width \l_@@_width_dim
}
- \skip_vertical:n { - \box_ht_plus_dp:N \l_tmpa_box }
+ \skip_vertical:n { - \box_ht_plus_dp:N \l_tmpa_box }
\box_use_drop:N \l_tmpa_box
}
}
- \vspace { - 2.5 pt }
\group_end:
\tl_gclear:N \g_@@_begin_line_hook_tl
}
@@ -3606,7 +3769,7 @@
{
\int_set:Nn \l_tmpa_int { \clist_count:N #1 }
\int_set:Nn \l_tmpb_int { \int_mod:nn \g_@@_line_int \l_tmpa_int + 1 }
- \tl_set:Nx \l_tmpa_tl { \clist_item:Nn #1 \l_tmpb_int }
+ \tl_set:Ne \l_tmpa_tl { \clist_item:Nn #1 \l_tmpb_int }
\tl_if_eq:NnTF \l_tmpa_tl { none }
% \end{macrocode}
% By setting |\l_@@_width_dim| to zero, the colored rectangle will be
@@ -3613,7 +3776,7 @@
% drawn with zero width and, thus, it will be a mere strut (and we need that strut).
% \begin{macrocode}
{ \dim_zero:N \l_@@_width_dim }
- { \exp_args:NV \@@_color_i:n \l_tmpa_tl }
+ { \exp_args:No \@@_color_i:n \l_tmpa_tl }
}
% \end{macrocode}
%
@@ -3639,57 +3802,64 @@
% \item In fact, it will be inserted between two commands
% |\@@_begin_line:|...|\@@_end_of_line:|.
% \item When the key |break-lines-in-Piton| is in force, a line of the
-% informatic code (the \emph{input}) may result in several lines in the PDF (the
-% \emph{output}).
-% \item |\@@_newline:| has a rather complex behaviour because it may close and
-% open |\vtop|s and finish and start paragraphs.
+% informatic code (the \emph{input}) may result in several lines in the
+% \textsc{pdf} (the \emph{output}).
+% \item Remind that |\@@_newline:| has a rather complex behaviour because it will
+% finish and start paragraphs.
% \end{itemize}
% \begin{macrocode}
\cs_new_protected:Npn \@@_newline:
{
+ \bool_if:NT \g_@@_footnote_bool \endsavenotes
% \end{macrocode}
% We recall that |\g_@@_line_int| is \emph{not} used for the number of line
-% printed in the PDF (when |line-numbers| is in force)...
+% printed in the \textsc{pdf} (when |line-numbers| is in force)...
% \begin{macrocode}
\int_gincr:N \g_@@_line_int
% \end{macrocode}
-% ... it will be used to allow or disallow page breaks (the final user controls
-% that behaviour with the key |splittable|).
+% ... it will be used to allow or disallow page breaks.
+%
+%
+% Each line in the listing is composed in a box of TeX (which may contain
+% several lines when the key |break-lines-in-Piton| is in force) put in a
+% paragraph.
% \begin{macrocode}
- \int_compare:nNnT \g_@@_line_int > { \l_@@_splittable_int - 1 }
- {
- \int_compare:nNnT
- { \l_@@_nb_lines_int - \g_@@_line_int + 1 } > \l_@@_splittable_int
+ \par
% \end{macrocode}
-% Now, we allow a page break after the current line of code.
+% We now add a |\kern| because each line of code is overlapping vertically by a
+% quantity of 2.5~pt in order to have a good background (when |background-color|
+% is in force). We need to use a |\kern| (in fact |\par\kern...|) and not a
+% |\vskip| because page breaks should \emph{not} be allowed on that kern.
% \begin{macrocode}
- {
- \egroup
- \bool_if:NT \g_@@_footnote_bool \endsavenotes
- \par
+ \kern -2.5 pt
% \end{macrocode}
-% Each non-splittable block of lines is composed in a |\vtop| of
-% TeX inserted in a paragraph of TeX.
-% \begin{itemize}
-% \item In the previous lines, we have closed a |\vtop| (with |\egroup|) and a
-% paragraph (with |\par|).
-% \item Now, we start a new paragraph (with |\mode_leave_vertical:|) and open a
-% |\vtop| (with |\vtop \bgroup|).
-% \end{itemize}
+% Now, we control page breaks after the paragraph. We use the Lua table
+% |piton.lines_status| which has been written by |piton.ComputeLinesStatus| for
+% this aim. Each line has a ``status`` (equal to 0, 1 or 2) and that status
+% directly says whether a break is allowed.
% \begin{macrocode}
- \mode_leave_vertical:
- \bool_if:NT \g_@@_footnote_bool \savenotes
- \vtop \bgroup
+ \int_case:nn
+ {
+ \lua_now:e
+ {
+ tex.sprint
+ (
+ luatexbase.catcodetables.expl ,
+ tostring ( piton.lines_status [ \int_use:N \g_@@_line_int ] )
+ )
+ }
+ }
+ { 1 { \penalty 100 } 2 \nobreak }
% \end{macrocode}
-% And, in that |\vtop|, of course, we will put a box for each line of the
-% informatic listing (but a line of the informatic listing may be formatted as a
-% box of several lines when |break-lines-in-Piton| is in force).
+%
+% \begin{macrocode}
+ \bool_if:NT \g_@@_footnote_bool \savenotes
+% \end{macrocode}
+%
% \begin{macrocode}
- }
- }
}
% \end{macrocode}
-% After the command |\@@_newline:|, we will have a command |\@@_begin_line:|.
+% After the command |\@@_newline:|, we will usually have a command |\@@_begin_line:|.
%
% \bigskip
% \begin{macrocode}
@@ -3724,6 +3894,8 @@
% \bigskip
% \subsubsection{PitonOptions}
%
+%
+%
% \medskip
% \begin{macrocode}
\bool_new:N \l_@@_line_numbers_bool
@@ -3737,6 +3909,7 @@
\int_new:N \l_@@_number_lines_start_int
\bool_new:N \l_@@_resume_bool
\bool_new:N \l_@@_split_on_empty_lines_bool
+\bool_new:N \l_@@_splittable_on_empty_lines_bool
% \end{macrocode}
%
%
@@ -3820,19 +3993,20 @@
% First, we put keys that should be available only in the preamble.
% \begin{macrocode}
detected-commands .code:n =
- \lua_now:n { piton.addDetectedCommands('#1') } ,
+ \lua_now:n { piton.addDetectedCommands('#1') } ,
detected-commands .value_required:n = true ,
detected-commands .usage:n = preamble ,
detected-beamer-commands .code:n =
- \lua_now:n { piton.addBeamerCommands('#1') } ,
+ \lua_now:n { piton.addBeamerCommands('#1') } ,
detected-beamer-commands .value_required:n = true ,
detected-beamer-commands .usage:n = preamble ,
detected-beamer-environments .code:n =
- \lua_now:n { piton.addBeamerEnvironments('#1') } ,
+ \lua_now:n { piton.addBeamerEnvironments('#1') } ,
detected-beamer-environments .value_required:n = true ,
detected-beamer-environments .usage:n = preamble ,
% \end{macrocode}
%
+%
% Remark that the command |\lua_escape:n| is fully expandable. That's why we use
% |\lua_now:e|.
% \begin{macrocode}
@@ -3869,7 +4043,7 @@
% Now, general keys.
% \begin{macrocode}
language .code:n =
- \str_set:Nx \l_piton_language_str { \str_lowercase:n { #1 } } ,
+ \str_set:Ne \l_piton_language_str { \str_lowercase:n { #1 } } ,
language .value_required:n = true ,
path .code:n =
\seq_clear:N \l_@@_path_seq
@@ -3886,6 +4060,8 @@
path .initial:n = . ,
path-write .str_set:N = \l_@@_path_write_str ,
path-write .value_required:n = true ,
+ font-command .tl_set:N = \l_@@_font_command_tl ,
+ font-command .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 } ,
@@ -3895,6 +4071,9 @@
tabs-auto-gobble .code:n = \int_set:Nn \l_@@_gobble_int { -3 } ,
tabs-auto-gobble .value_forbidden:n = true ,
+ splittable-on-empty-lines .bool_set:N = \l_@@_splittable_on_empty_lines_bool ,
+ splittable-on-empty-lines .default:n = true ,
+
split-on-empty-lines .bool_set:N = \l_@@_split_on_empty_lines_bool ,
split-on-empty-lines .default:n = true ,
@@ -3991,6 +4170,10 @@
} ,
range .value_required:n = true ,
+ env-used-by-split .code:n =
+ \lua_now:n { piton.env_used_by_split = '#1'} ,
+ env-used-by-split .initial:n = Piton ,
+
resume .meta:n = line-numbers/resume ,
unknown .code:n = \@@_error:n { Unknown~key~for~PitonOptions } ,
@@ -4000,10 +4183,6 @@
\bool_set_true:N \l_@@_line_numbers_bool
\bool_set_false:N \l_@@_skip_empty_lines_bool ,
all-line-numbers .value_forbidden:n = true ,
-
- % deprecated
- numbers-sep .dim_set:N = \l_@@_numbers_sep_dim ,
- numbers-sep .value_required:n = true
}
% \end{macrocode}
%
@@ -4095,7 +4274,7 @@
\tl_if_empty:NF \g_@@_aux_tl
{
\iow_now:Nn \@mainaux { \ExplSyntaxOn }
- \iow_now:Nx \@mainaux
+ \iow_now:Ne \@mainaux
{
\tl_gset:cn { c_@@_ \int_use:N \g_@@_env_int _ tl }
{ \exp_not:o \g_@@_aux_tl }
@@ -4112,7 +4291,7 @@
% \begin{macrocode}
\cs_new_protected:Npn \@@_width_to_aux:
{
- \tl_gput_right:Nx \g_@@_aux_tl
+ \tl_gput_right:Ne \g_@@_aux_tl
{
\dim_set:Nn \l_@@_line_width_dim
{ \dim_eval:n { \g_@@_tmp_width_dim } }
@@ -4180,7 +4359,7 @@
% 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_set:Ne \l_tmpa_tl
{
\tl_if_blank:nF { #1 } { [ \str_lowercase:n { #1 } ] }
\str_lowercase:n { #2 }
@@ -4201,7 +4380,7 @@
% |\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 }
+ \exp_args:No \@@_NewPitonLanguage:nn \l_tmpa_tl { #3 }
}
% \end{macrocode}
%
@@ -4223,7 +4402,7 @@
% 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_set:Ne \l_tmpa_tl
{
\tl_if_blank:nF { #3 } { [ \str_lowercase:n { #3 } ] }
\str_lowercase:n { #4 }
@@ -4234,12 +4413,12 @@
% 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
+ \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 } }
+ { \@@_NewPitonLanguage:nnno { #1 } { #2 } { #5 } \l_tmpb_tl }
+ { \@@_error:n { Language~not~defined } }
}
% \end{macrocode}
%
@@ -4272,7 +4451,7 @@
\automatichyphenmode = 1
% \end{macrocode}
% Remark that the argument of |\piton| (with the normal syntax) is expanded in
-% the TeX sens, (see the |\tl_set:Nx| below) and that's why we can provide the
+% the TeX sens, (see the |\tl_set:Ne| below) and that's why we can provide the
% following escapes to the final user:
% \begin{macrocode}
\cs_set_eq:NN \\ \c_backslash_str
@@ -4288,9 +4467,8 @@
% \end{macrocode}
%
% \begin{macrocode}
- \cs_set_protected:Npn \@@_begin_line: { }
- \cs_set_protected:Npn \@@_end_line: { }
- \tl_set:Nx \l_tmpa_tl
+ \cs_set_eq:NN \@@_begin_line: \prg_do_nothing:
+ \tl_set:Ne \l_tmpa_tl
{
\lua_now:e
{ piton.ParseBis('\l_piton_language_str',token.scan_string()) }
@@ -4312,9 +4490,9 @@
% The command |\text| is provided by the package \pkg{amstext} (loaded by \pkg{piton}).
% \begin{macrocode}
\if_mode_math:
- \text { \ttfamily \l_tmpa_tl }
+ \text { \l_@@_font_command_tl \l_tmpa_tl }
\else:
- \ttfamily \l_tmpa_tl
+ \l_@@_font_command_tl \l_tmpa_tl
\fi:
\group_end:
}
@@ -4325,11 +4503,10 @@
\NewDocumentCommand { \@@_piton_verbatim } { v }
{
\group_begin:
- \ttfamily
+ \l_@@_font_command_tl
\automatichyphenmode = 1
- \cs_set_protected:Npn \@@_begin_line: { }
- \cs_set_protected:Npn \@@_end_line: { }
- \tl_set:Nx \l_tmpa_tl
+ \cs_set_eq:NN \@@_begin_line: \prg_do_nothing:
+ \tl_set:Ne \l_tmpa_tl
{
\lua_now:e
{ piton.Parse('\l_piton_language_str',token.scan_string()) }
@@ -4353,32 +4530,21 @@
% arguments of a Python function).
% \begin{macrocode}
\cs_new_protected:Npn \@@_piton:n #1
+ { \tl_if_blank:nF { #1 } { \@@_piton_i:n { #1 } } }
+
+\cs_new_protected:Npn \@@_piton_i:n #1
{
\group_begin:
- \cs_set_protected:Npn \@@_begin_line: { }
- \cs_set_protected:Npn \@@_end_line: { }
+ \cs_set_eq:NN \@@_begin_line: \prg_do_nothing:
\cs_set:cpn { pitonStyle _ \l_piton_language_str _ Prompt } { }
\cs_set:cpn { pitonStyle _ Prompt } { }
\cs_set_eq:NN \@@_trailing_space: \space
- \bool_lazy_or:nnTF
- \l_@@_break_lines_in_piton_bool
- \l_@@_break_lines_in_Piton_bool
- {
- \tl_set:Nx \l_tmpa_tl
- {
- \lua_now:e
- { piton.ParseTer('\l_piton_language_str',token.scan_string()) }
- { #1 }
- }
+ \tl_set:Ne \l_tmpa_tl
+ {
+ \lua_now:e
+ { piton.ParseTer('\l_piton_language_str',token.scan_string()) }
+ { #1 }
}
- {
- \tl_set:Nx \l_tmpa_tl
- {
- \lua_now:e
- { piton.Parse('\l_piton_language_str',token.scan_string()) }
- { #1 }
- }
- }
\bool_if:NT \l_@@_show_spaces_bool
{ \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl } % U+2423
\exp_args:No \@@_replace_spaces:n \l_tmpa_tl
@@ -4437,7 +4603,7 @@
{ #2 }
\int_to_arabic:n
{ \g_@@_visual_line_int + \l_@@_nb_non_empty_lines_int }
- }
+ }
{
\int_to_arabic:n
{ \g_@@_visual_line_int + \l_@@_nb_lines_int }
@@ -4528,18 +4694,24 @@
####1
\c_backslash_str end \c_left_brace_str #1 \c_right_brace_str
}
- {
+ {
\group_end:
\mode_if_vertical:TF { \noindent \mode_leave_vertical: } \newline
% \end{macrocode}
+% The following line is only to compute |\l_@@_lines_int| which will be used
+% only when both |left-margin=auto| and |skip-empty-lines = false| are in force.
+% You should change that.
+% \begin{macrocode}
+ \lua_now:e { piton.CountLines ( '\lua_escape:n{##1}' ) }
+% \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 { CountNonEmptyLines } { ##1 }
\@@_compute_width:
- \ttfamily
+ \l_@@_font_command_tl
\dim_zero:N \parskip
- \noindent % added 2024/08/07
+ \noindent
% \end{macrocode}
%
% Now, the key |write|.
@@ -4553,11 +4725,11 @@
\str_if_empty:NTF \l_@@_write_str
{ \lua_now:n { piton.write = '' } }
{
- \seq_if_in:NVTF \g_@@_write_seq \l_@@_write_str
+ \seq_if_in:NoTF \g_@@_write_seq \l_@@_write_str
{ \lua_now:n { piton.write_mode = "a" } }
{
\lua_now:n { piton.write_mode = "w" }
- \seq_gput_left:NV \g_@@_write_seq \l_@@_write_str
+ \seq_gput_left:No \g_@@_write_seq \l_@@_write_str
}
}
% \end{macrocode}
@@ -4565,8 +4737,8 @@
% Now, the main job.
% \begin{macrocode}
\bool_if:NTF \l_@@_split_on_empty_lines_bool
- \@@_gobble_split_parse:n
- \@@_gobble_parse:n
+ \@@_retrieve_gobble_split_parse:n
+ \@@_retrieve_gobble_parse:n
{ ##1 }
% \end{macrocode}
%
@@ -4620,17 +4792,21 @@
%
% \bigskip
% The following function will be used when the key |split-on-empty-lines| is not
-% in force. It will gobble the spaces at the beginning of the lines and parse
-% the code. The argument is provided by curryfication.
+% in force. It will retrieve the first empty line, gobble the spaces at the
+% beginning of the lines and parse the code. The argument is provided by
+% curryfication.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_gobble_parse:n
+\cs_new_protected:Npn \@@_retrieve_gobble_parse:n
{
\lua_now:e
{
- piton.GobbleParse
+ piton.RetrieveGobbleParse
(
'\l_piton_language_str' ,
\int_use:N \l_@@_gobble_int ,
+ \bool_if:NTF \l_@@_splittable_on_empty_lines_bool
+ { \int_eval:n { - \l_@@_splittable_int } }
+ { \int_use:N \l_@@_splittable_int } ,
token.scan_argument ( )
)
}
@@ -4643,14 +4819,15 @@
% |gobble| is in force), then split the code at the empty lines and, eventually,
% parse the code. The argument is provided by curryfication.
% \begin{macrocode}
-\cs_new_protected:Npn \@@_gobble_split_parse:n
+\cs_new_protected:Npn \@@_retrieve_gobble_split_parse:n
{
\lua_now:e
{
- piton.GobbleSplitParse
+ piton.RetrieveGobbleSplitParse
(
'\l_piton_language_str' ,
\int_use:N \l_@@_gobble_int ,
+ \int_use:N \l_@@_splittable_int ,
token.scan_argument ( )
)
}
@@ -4690,21 +4867,38 @@
{
\group_begin:
% \end{macrocode}
-% The boolean |\l_tmap_bool| will be raised if the file is found somewhere in
-% the path (specified by the key |path|).
+% In version 4.0 of \pkg{piton}, we changed the mechanism used by \pkg{piton}
+% to search the file to load with |\PitonInputFile|. With the key
+% |old-PitonInputFile|, it's possible to keep the old behaviour but it's only
+% for backward compatibility and it will be deleted in a future version.
% \begin{macrocode}
- \bool_set_false:N \l_tmpa_bool
- \seq_map_inline:Nn \l_@@_path_seq
+ \bool_if:NTF \l_@@_old_PitonInputFile_bool
{
- \str_set:Nn \l_@@_file_name_str { ##1 / #3 }
- \file_if_exist:nT { \l_@@_file_name_str }
- {
- \@@_input_file:nn { #1 } { #2 }
- \bool_set_true:N \l_tmpa_bool
- \seq_map_break:
+ \bool_set_false:N \l_tmpa_bool
+ \seq_map_inline:Nn \l__piton_path_seq
+ {
+ \str_set:Nn \l__piton_file_name_str { ##1 / #3 }
+ \file_if_exist:nT { \l__piton_file_name_str }
+ {
+ \__piton_input_file:nn { #1 } { #2 }
+ \bool_set_true:N \l_tmpa_bool
+ \seq_map_break:
+ }
}
+ \bool_if:NTF \l_tmpa_bool { #4 } { #5 }
}
- \bool_if:NTF \l_tmpa_bool { #4 } { #5 }
+ {
+ \seq_concat:NNN
+ \l_file_search_path_seq
+ \l_@@_path_seq
+ \l_file_search_path_seq
+ \file_get_full_name:nNTF { #3 } \l_@@_file_name_str
+ {
+ \@@_input_file:nn { #1 } { #2 }
+ #4
+ }
+ { #5 }
+ }
\group_end:
}
% \end{macrocode}
@@ -4791,8 +4985,7 @@
\mode_if_vertical:TF \mode_leave_vertical: \newline
% \end{macrocode}
% We count with Lua the number of lines of the argument. The result will be
-% stored by Lua in |\l_@@_nb_lines_int|. That information will be used to allow
-% or disallow page breaks.
+% stored by Lua in |\l_@@_nb_lines_int|.
% \begin{macrocode}
\lua_now:e { piton.CountLinesFile ( '\l_@@_file_name_str' ) }
% \end{macrocode}
@@ -4801,7 +4994,7 @@
% \begin{macrocode}
\@@_compute_left_margin:no { CountNonEmptyLinesFile } \l_@@_file_name_str
\@@_compute_width:
- \ttfamily
+ \l_@@_font_command_tl
\lua_now:e
{
piton.ParseFile(
@@ -4809,6 +5002,9 @@
'\l_@@_file_name_str' ,
\int_use:N \l_@@_first_line_int ,
\int_use:N \l_@@_last_line_int ,
+ \bool_if:NTF \l_@@_splittable_on_empty_lines_bool
+ { \int_eval:n { - \l_@@_splittable_int } }
+ { \int_use:N \l_@@_splittable_int } ,
\bool_if:NTF \l_@@_split_on_empty_lines_bool { 1 } { 0 } )
}
\bool_if:NT \l_@@_width_min_bool \@@_width_to_aux:
@@ -4820,7 +5016,7 @@
% file (read by |\PitonInputFile|) is loaded during the compilation of the LaTeX
% document.
% \begin{macrocode}
- \exp_args:Nx \iow_log:n {(\l_@@_file_name_str)}
+ \iow_log:e {(\l_@@_file_name_str)}
% \end{macrocode}
% We recall that, if we are in Beamer, the command |\PitonInputFile| is
% ``overlay-aware'' and that's why we close now an environment |{uncoverenv}|
@@ -4843,15 +5039,15 @@
% We store the markers in L3 strings (|str|) in order to do safely the following
% replacement of |\#|.
% \begin{macrocode}
- \str_set:Nx \l_tmpa_str { \@@_marker_beginning:n \l_@@_begin_range_str }
- \str_set:Nx \l_tmpb_str { \@@_marker_end:n \l_@@_end_range_str }
+ \str_set:Ne \l_tmpa_str { \@@_marker_beginning:n \l_@@_begin_range_str }
+ \str_set:Ne \l_tmpb_str { \@@_marker_end:n \l_@@_end_range_str }
% \end{macrocode}
% We replace the sequences |\#| which may be present in the prefixes (and, more
% unlikely, suffixes) added to the markers by the functions
% |\@@_marker_beginning:n| and |\@@_marker_end:n|
% \begin{macrocode}
- \exp_args:NnV \regex_replace_all:nnN { \\\# } \c_hash_str \l_tmpa_str
- \exp_args:NnV \regex_replace_all:nnN { \\\# } \c_hash_str \l_tmpb_str
+ \exp_args:Nno \regex_replace_all:nnN { \\\# } \c_hash_str \l_tmpa_str
+ \exp_args:Nno \regex_replace_all:nnN { \\\# } \c_hash_str \l_tmpb_str
\lua_now:e
{
piton.ComputeRange
@@ -4878,7 +5074,7 @@
\NewDocumentCommand { \SetPitonStyle } { O { } m }
{
\str_clear_new:N \l_@@_SetPitonStyle_option_str
- \str_set:Nx \l_@@_SetPitonStyle_option_str { \str_lowercase:n { #1 } }
+ \str_set:Ne \l_@@_SetPitonStyle_option_str { \str_lowercase:n { #1 } }
\str_if_eq:onT \l_@@_SetPitonStyle_option_str { current-language }
{ \str_set_eq:NN \l_@@_SetPitonStyle_option_str \l_piton_language_str }
\keys_set:nn { piton / Styles } { #2 }
@@ -4982,7 +5178,7 @@
\SetPitonStyle[OCaml]
{
TypeExpression =
- \SetPitonStyle { Identifier = \PitonStyle { Name.Type } } \@@_piton:n
+ \SetPitonStyle { Identifier = \PitonStyle { Name.Type } } \@@_piton:n ,
}
% \end{macrocode}
%
@@ -5060,16 +5256,16 @@
% ``internal style'' (not available for the final user). However, maybe we will
% change that and document that style for the final user.
%
-% \medskip
-% If the key |math-comments| has been used at load-time, we change the style
-% |Comment.Math| which should be considered only at an ``internal style''.
-% However, maybe we will document in a future version the possibility to write
-% change the style \emph{locally} in a document)].
+% \medskip
+% If the key |math-comments| has been used in the preamble of the LaTeX
+% document, we change the style |Comment.Math| which should be considered only
+% at an ``internal style''. However, maybe we will document in a future version
+% the possibility to write change the style \emph{locally} in a document)].
% \begin{macrocode}
-\AtBeginDocument
+\hook_gput_code:nnn { begindocument } { . }
{
\bool_if:NT \g_@@_math_comments_bool
- { \SetPitonStyle { Comment.Math = \@@_math_scantokens:n } }
+ { \SetPitonStyle { Comment.Math = \@@_math_scantokens:n } }
}
% \end{macrocode}
%
@@ -5090,7 +5286,7 @@
{ \cs_set:cpn { PitonIdentifier _ ##1 } { #3 } }
}
{
- \str_set:Nx \l_tmpa_str { \str_lowercase:n { #1 } }
+ \str_set:Ne \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
@@ -5146,8 +5342,8 @@
% 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_piton_language_str
- { \seq_gput_left:NV \g_@@_languages_seq \l_piton_language_str }
+ \seq_if_in:NoF \g_@@_languages_seq \l_piton_language_str
+ { \seq_gput_left:No \g_@@_languages_seq \l_piton_language_str }
}
% \end{macrocode}
%
@@ -5327,7 +5523,7 @@
\@@_msg_new:nn { SyntaxError }
{
Syntax~Error.\\
- Your~code~of~the~language~"\l_piton_language_str"~is~not~
+ Your~code~of~the~language~'\l_piton_language_str'~is~not~
syntactically~correct.\\
It~won't~be~printed~in~the~PDF~file.
}
@@ -5399,6 +5595,8 @@
end-of-broken-line,~
end-range,~
env-gobble,~
+ env-used-by-split,~
+ font-command,~
gobble,~
indent-broken-lines,~
language,~
@@ -5413,6 +5611,7 @@
show-spaces,~
show-spaces-in-strings,~
splittable,~
+ splittable-on-empty-lines,~
split-on-empty-lines,~
split-separation,~
tabs-auto-gobble,~
@@ -5555,7 +5754,7 @@
% \begin{macrocode}
local P, S, V, C, Ct, Cc = lpeg.P, lpeg.S, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Cc
local Cs , Cg , Cmt , Cb = lpeg.Cs, lpeg.Cg , lpeg.Cmt , lpeg.Cb
-local R = lpeg.R
+local B , R = lpeg.B , lpeg.R
% \end{macrocode}
%
%
@@ -5769,8 +5968,10 @@
% \end{macrocode}
%
% \bigskip
+% Remember that |\@@_leading_space:| does \emph{not} create a space, only an
+% incrementation of the coutnter |\g_@@_indentation_int|.
% \begin{macrocode}
-local SpaceIndentation = Lc [[\@@_an_indentation_space:]] * Q " "
+local SpaceIndentation = Lc [[\@@_leading_space:]] * Q " "
% \end{macrocode}
%
% \bigskip
@@ -5836,11 +6037,11 @@
%
% \bigskip
% The following Lua function will compute the \text{lpeg} |DetectedCommands|
-% which is a \textsc{lpeg} with captures).
+% which is a \textsc{lpeg} with captures.
% \begin{macrocode}
local function Compute_DetectedCommands ( lang , braces ) return
Ct ( Cc "Open"
- * C ( piton.DetectedCommands * P "{" )
+ * C ( piton.DetectedCommands * space ^ 0 * P "{" )
* Cc "}"
)
* ( braces
@@ -5902,7 +6103,7 @@
BeamerEndEnvironments =
( space ^ 0 *
L ( P "\\end{" * piton.BeamerEnvironments * "}" )
- * "\r"
+ * "\r"
) ^ 0
% \end{macrocode}
%
@@ -5915,10 +6116,10 @@
local function Compute_Beamer ( lang , braces )
% \end{macrocode}
%
-% \bigskip
+% \smallskip
% We will compute in |lpeg| the \textsc{lpeg} that we will return.
% \begin{macrocode}
- local lpeg = L ( P "\\pause" * ( "[" * ( 1 - P "]" ) ^ 0 * "]" ) ^ -1 )
+ local lpeg = L ( P [[\pause]] * ( "[" * ( 1 - P "]" ) ^ 0 * "]" ) ^ -1 )
lpeg = lpeg +
Ct ( Cc "Open"
* C ( piton.BeamerCommands
@@ -5939,7 +6140,7 @@
% brackets) is mandatory.
% \begin{macrocode}
lpeg = lpeg +
- L ( P "\\alt" * "<" * ( 1 - P ">" ) ^ 0 * ">" * "{" )
+ L ( P [[\alt]] * "<" * ( 1 - P ">" ) ^ 0 * ">" * "{" )
* ( braces /
( function ( s ) if s ~= '' then return LPEG1[lang] : match ( s ) end end ) )
* L ( P "}{" )
@@ -5953,7 +6154,7 @@
% is mandatory.
% \begin{macrocode}
lpeg = lpeg +
- L ( ( P "\\temporal" ) * "<" * ( 1 - P ">" ) ^ 0 * ">" * "{" )
+ L ( ( P [[\temporal]] ) * "<" * ( 1 - P ">" ) ^ 0 * ">" * "{" )
* ( braces
/ ( function ( s )
if s ~= '' then return LPEG1[lang] : match ( s ) end end ) )
@@ -6022,7 +6223,7 @@
% |\@@_begin_line:|, it's too late to change de background).
% \begin{macrocode}
local PromptHastyDetection =
- ( # ( P ">>>" + "..." ) * Lc '\\@@_prompt:' ) ^ -1
+ ( # ( 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.
@@ -6039,11 +6240,11 @@
% \bigskip
% The following \textsc{lpeg} |EOL| is for the end of lines.
% \begin{macrocode}
-local EOL_without_space_indentation =
+local EOL =
P "\r"
*
(
- ( space ^ 0 * -1 )
+ space ^ 0 * -1
+
% \end{macrocode}
% We recall that each line of the informatic code we have to parse will be sent
@@ -6055,22 +6256,30 @@
Ct (
Cc "EOL"
*
- Ct (
- Lc [[\@@_end_line:]]
+ Ct ( Lc [[\@@_end_line:]]
* BeamerEndEnvironments
- * BeamerBeginEnvironments
- * PromptHastyDetection
- * Lc [[\@@_newline:\@@_begin_line:]]
- * Prompt
+ *
+ (
+% \end{macrocode}
+% If the last line of the listing is the end of an environment of Beamer (eg.
+% |\end{uncoverenv}|), then, we don't open a new line. A token |\@@_end_line:|
+% will be added at the end of the environment but it will be no-op since we have
+% defined the macro |\@@_end_line:| to be no-op (even though it is also used as
+% a marker for the TeX delimited macro |\@@_begin_line:|).
+% \begin{macrocode}
+ -1
+ +
+ BeamerBeginEnvironments
+ * PromptHastyDetection
+ * Lc [[\@@_newline:\@@_begin_line:]]
+ * Prompt
+ )
)
)
)
+ * ( SpaceIndentation ^ 0 * # ( 1 - S " \r" ) ) ^ -1
% \end{macrocode}
%
-% \begin{macrocode}
-local EOL = EOL_without_space_indentation
- * ( SpaceIndentation ^ 0 * # ( 1 - S " \r" ) ) ^ -1
-% \end{macrocode}
%
% \bigskip
% The following \textsc{lpeg} |CommentLaTeX| is for what is called in that
@@ -6079,10 +6288,10 @@
% 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"
+ P ( piton.comment_latex )
+ * Lc [[{\PitonStyle{Comment.LaTeX}{\ignorespaces]]
* L ( ( 1 - P "\r" ) ^ 0 )
- * Lc "}}"
+ * Lc [[}}]]
* ( EOL + -1 )
% \end{macrocode}
%
@@ -6091,77 +6300,81 @@
% \bigskip
% \subsubsection{The language Python}
%
+% We open a Lua local scope for the language Python (of course, there will be
+% also global definitions).
+% \begin{macrocode}
+do
+% \end{macrocode}
+%
% \bigskip
% 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 Operator =
- K ( 'Operator' ,
- P "!=" + "<>" + "==" + "<<" + ">>" + "<=" + ">=" + ":=" + "//" + "**"
- + S "-~+/*%=<>&.@|" )
+ local Operator =
+ K ( 'Operator' ,
+ P "!=" + "<>" + "==" + "<<" + ">>" + "<=" + ">=" + ":=" + "//" + "**"
+ + S "-~+/*%=<>&.@|" )
-local OperatorWord =
- K ( 'Operator.Word' , P "in" + "is" + "and" + "or" + "not" )
+ local OperatorWord =
+ K ( 'Operator.Word' , P "in" + "is" + "and" + "or" + "not" )
% \end{macrocode}
%
% \smallskip
% The keyword |in| in a construction such as ``|for i in range(n)|'' must be
-% formatted as a keyword and not as an |Operator.Word|.
+% formatted as a keyword and not as an |Operator.Word| and that's why we write
+% the following LPEG |For|.
% \begin{macrocode}
-local For = K ( 'Keyword' , P "for" )
- * Space
- * Identifier
- * Space
- * K ( 'Keyword' , P "in" )
+ local For = K ( 'Keyword' , P "for" )
+ * Space
+ * Identifier
+ * Space
+ * K ( 'Keyword' , P "in" )
-local Keyword =
- K ( 'Keyword' ,
- P "as" + "assert" + "break" + "case" + "class" + "continue" + "def" +
- "del" + "elif" + "else" + "except" + "exec" + "finally" + "for" + "from" +
- "global" + "if" + "import" + "lambda" + "non local" + "pass" + "return" +
- "try" + "while" + "with" + "yield" + "yield from" )
- + K ( 'Keyword.Constant' , P "True" + "False" + "None" )
+ local Keyword =
+ K ( 'Keyword' ,
+ P "as" + "assert" + "break" + "case" + "class" + "continue" + "def" +
+ "del" + "elif" + "else" + "except" + "exec" + "finally" + "for" + "from" +
+ "global" + "if" + "import" + "lambda" + "non local" + "pass" + "return" +
+ "try" + "while" + "with" + "yield" + "yield from" )
+ + K ( 'Keyword.Constant' , P "True" + "False" + "None" )
-local Builtin =
- K ( 'Name.Builtin' ,
- P "__import__" + "abs" + "all" + "any" + "bin" + "bool" + "bytearray" +
- "bytes" + "chr" + "classmethod" + "compile" + "complex" + "delattr" +
- "dict" + "dir" + "divmod" + "enumerate" + "eval" + "filter" + "float" +
- "format" + "frozenset" + "getattr" + "globals" + "hasattr" + "hash" +
- "hex" + "id" + "input" + "int" + "isinstance" + "issubclass" + "iter" +
- "len" + "list" + "locals" + "map" + "max" + "memoryview" + "min" + "next"
- + "object" + "oct" + "open" + "ord" + "pow" + "print" + "property" +
- "range" + "repr" + "reversed" + "round" + "set" + "setattr" + "slice" +
- "sorted" + "staticmethod" + "str" + "sum" + "super" + "tuple" + "type" +
- "vars" + "zip" )
+ local Builtin =
+ K ( 'Name.Builtin' ,
+ P "__import__" + "abs" + "all" + "any" + "bin" + "bool" + "bytearray" +
+ "bytes" + "chr" + "classmethod" + "compile" + "complex" + "delattr" +
+ "dict" + "dir" + "divmod" + "enumerate" + "eval" + "filter" + "float" +
+ "format" + "frozenset" + "getattr" + "globals" + "hasattr" + "hash" +
+ "hex" + "id" + "input" + "int" + "isinstance" + "issubclass" + "iter" +
+ "len" + "list" + "locals" + "map" + "max" + "memoryview" + "min" + "next"
+ + "object" + "oct" + "open" + "ord" + "pow" + "print" + "property" +
+ "range" + "repr" + "reversed" + "round" + "set" + "setattr" + "slice" +
+ "sorted" + "staticmethod" + "str" + "sum" + "super" + "tuple" + "type" +
+ "vars" + "zip" )
+ local Exception =
+ K ( 'Exception' ,
+ P "ArithmeticError" + "AssertionError" + "AttributeError" +
+ "BaseException" + "BufferError" + "BytesWarning" + "DeprecationWarning" +
+ "EOFError" + "EnvironmentError" + "Exception" + "FloatingPointError" +
+ "FutureWarning" + "GeneratorExit" + "IOError" + "ImportError" +
+ "ImportWarning" + "IndentationError" + "IndexError" + "KeyError" +
+ "KeyboardInterrupt" + "LookupError" + "MemoryError" + "NameError" +
+ "NotImplementedError" + "OSError" + "OverflowError" +
+ "PendingDeprecationWarning" + "ReferenceError" + "ResourceWarning" +
+ "RuntimeError" + "RuntimeWarning" + "StopIteration" + "SyntaxError" +
+ "SyntaxWarning" + "SystemError" + "SystemExit" + "TabError" + "TypeError"
+ + "UnboundLocalError" + "UnicodeDecodeError" + "UnicodeEncodeError" +
+ "UnicodeError" + "UnicodeTranslateError" + "UnicodeWarning" +
+ "UserWarning" + "ValueError" + "VMSError" + "Warning" + "WindowsError" +
+ "ZeroDivisionError" + "BlockingIOError" + "ChildProcessError" +
+ "ConnectionError" + "BrokenPipeError" + "ConnectionAbortedError" +
+ "ConnectionRefusedError" + "ConnectionResetError" + "FileExistsError" +
+ "FileNotFoundError" + "InterruptedError" + "IsADirectoryError" +
+ "NotADirectoryError" + "PermissionError" + "ProcessLookupError" +
+ "TimeoutError" + "StopAsyncIteration" + "ModuleNotFoundError" +
+ "RecursionError" )
-local Exception =
- K ( 'Exception' ,
- P "ArithmeticError" + "AssertionError" + "AttributeError" +
- "BaseException" + "BufferError" + "BytesWarning" + "DeprecationWarning" +
- "EOFError" + "EnvironmentError" + "Exception" + "FloatingPointError" +
- "FutureWarning" + "GeneratorExit" + "IOError" + "ImportError" +
- "ImportWarning" + "IndentationError" + "IndexError" + "KeyError" +
- "KeyboardInterrupt" + "LookupError" + "MemoryError" + "NameError" +
- "NotImplementedError" + "OSError" + "OverflowError" +
- "PendingDeprecationWarning" + "ReferenceError" + "ResourceWarning" +
- "RuntimeError" + "RuntimeWarning" + "StopIteration" + "SyntaxError" +
- "SyntaxWarning" + "SystemError" + "SystemExit" + "TabError" + "TypeError"
- + "UnboundLocalError" + "UnicodeDecodeError" + "UnicodeEncodeError" +
- "UnicodeError" + "UnicodeTranslateError" + "UnicodeWarning" +
- "UserWarning" + "ValueError" + "VMSError" + "Warning" + "WindowsError" +
- "ZeroDivisionError" + "BlockingIOError" + "ChildProcessError" +
- "ConnectionError" + "BrokenPipeError" + "ConnectionAbortedError" +
- "ConnectionRefusedError" + "ConnectionResetError" + "FileExistsError" +
- "FileNotFoundError" + "InterruptedError" + "IsADirectoryError" +
- "NotADirectoryError" + "PermissionError" + "ProcessLookupError" +
- "TimeoutError" + "StopAsyncIteration" + "ModuleNotFoundError" +
- "RecursionError" )
-
-
-local RaiseException = K ( 'Keyword' , P "raise" ) * SkipSpace * Exception * Q "("
-
+ local RaiseException = K ( 'Keyword' , P "raise" ) * SkipSpace * Exception * Q "("
% \end{macrocode}
%
% \bigskip
@@ -6168,7 +6381,7 @@
% In Python, a ``decorator'' is a statement whose begins by |@| which patches
% the function defined in the following statement.
% \begin{macrocode}
-local Decorator = K ( 'Name.Decorator' , P "@" * letter ^ 1 )
+ local Decorator = K ( 'Name.Decorator' , P "@" * letter ^ 1 )
% \end{macrocode}
%
% \bigskip
@@ -6179,8 +6392,8 @@
% \smallskip
% Example:\enskip \piton{class myclass:}
% \begin{macrocode}
-local DefClass =
- K ( 'Keyword' , "class" ) * Space * K ( 'Name.Class' , identifier )
+ 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 caught as
@@ -6187,7 +6400,6 @@
% keyword by the \textsc{lpeg} |Keyword| (useful if we want to type a
% list of keywords).
%
-%
% \bigskip
% The following \textsc{lpeg} |ImportAs| is used for the lines beginning by |import|.
% % We have to detect the potential keyword |as| because both the name of the
@@ -6203,17 +6415,17 @@
% \smallskip
% Example:\enskip \piton{import math, numpy}
% \begin{macrocode}
-local ImportAs =
- K ( 'Keyword' , "import" )
- * Space
- * K ( 'Name.Namespace' , identifier * ( "." * identifier ) ^ 0 )
- * (
- ( Space * K ( 'Keyword' , "as" ) * Space
- * K ( 'Name.Namespace' , identifier ) )
- +
- ( SkipSpace * Q "," * SkipSpace
- * K ( 'Name.Namespace' , identifier ) ) ^ 0
- )
+ local ImportAs =
+ K ( 'Keyword' , "import" )
+ * Space
+ * K ( 'Name.Namespace' , identifier * ( "." * identifier ) ^ 0 )
+ * (
+ ( Space * K ( 'Keyword' , "as" ) * Space
+ * K ( 'Name.Namespace' , identifier ) )
+ +
+ ( SkipSpace * Q "," * SkipSpace
+ * K ( 'Name.Namespace' , identifier ) ) ^ 0
+ )
% \end{macrocode}
% Be careful: there is no commutativity of |+| in the previous expression.
%
@@ -6229,10 +6441,10 @@
%
% \smallskip
% \begin{macrocode}
-local FromImport =
- K ( 'Keyword' , "from" )
- * Space * K ( 'Name.Namespace' , identifier )
- * Space * K ( 'Keyword' , "import" )
+ local FromImport =
+ K ( 'Keyword' , "from" )
+ * Space * K ( 'Name.Namespace' , identifier )
+ * Space * K ( 'Keyword' , "import" )
% \end{macrocode}
%
% \bigskip
@@ -6269,16 +6481,16 @@
% The interpolations beginning by |%| (even though there is more modern
% techniques now in Python).
% \begin{macrocode}
-local PercentInterpol =
- K ( 'String.Interpol' ,
- P "%"
- * ( "(" * alphanum ^ 1 * ")" ) ^ -1
- * ( S "-#0 +" ) ^ 0
- * ( digit ^ 1 + "*" ) ^ -1
- * ( "." * ( digit ^ 1 + "*" ) ) ^ -1
- * ( S "HlL" ) ^ -1
- * S "sdfFeExXorgiGauc%"
- )
+ local PercentInterpol =
+ K ( 'String.Interpol' ,
+ P "%"
+ * ( "(" * alphanum ^ 1 * ")" ) ^ -1
+ * ( S "-#0 +" ) ^ 0
+ * ( digit ^ 1 + "*" ) ^ -1
+ * ( "." * ( digit ^ 1 + "*" ) ) ^ -1
+ * ( S "HlL" ) ^ -1
+ * S "sdfFeExXorgiGauc%"
+ )
% \end{macrocode}
%
% \bigskip
@@ -6289,61 +6501,61 @@
% |Interpol.Inside|. The initial value of that style is \texttt{\textbackslash
% @@\_piton:n} which means that the interpolations are parsed once again by \pkg{piton}.}
% \begin{macrocode}
-local SingleShortString =
- WithStyle ( 'String.Short' ,
+ local SingleShortString =
+ WithStyle ( 'String.Short' ,
% \end{macrocode}
% First, we deal with the f-strings of Python, which are prefixed by |f| or |F|.
% \begin{macrocode}
- Q ( P "f'" + "F'" )
- * (
- K ( 'String.Interpol' , "{" )
- * K ( 'Interpol.Inside' , ( 1 - S "}':" ) ^ 0 )
- * Q ( P ":" * ( 1 - S "}:'" ) ^ 0 ) ^ -1
- * K ( 'String.Interpol' , "}" )
- +
- VisualSpace
- +
- Q ( ( P "\\'" + "{{" + "}}" + 1 - S " {}'" ) ^ 1 )
- ) ^ 0
- * Q "'"
- +
+ Q ( P "f'" + "F'" )
+ * (
+ K ( 'String.Interpol' , "{" )
+ * K ( 'Interpol.Inside' , ( 1 - S "}':" ) ^ 0 )
+ * Q ( P ":" * ( 1 - S "}:'" ) ^ 0 ) ^ -1
+ * K ( 'String.Interpol' , "}" )
+ +
+ VisualSpace
+ +
+ Q ( ( P "\\'" + "\\\\" + "{{" + "}}" + 1 - S " {}'" ) ^ 1 )
+ ) ^ 0
+ * Q "'"
+ +
% \end{macrocode}
% Now, we deal with the standard strings of Python, but also the ``raw strings''.
% \begin{macrocode}
- Q ( P "'" + "r'" + "R'" )
- * ( Q ( ( P "\\'" + 1 - S " '\r%" ) ^ 1 )
- + VisualSpace
- + PercentInterpol
- + Q "%"
- ) ^ 0
- * Q "'" )
+ Q ( P "'" + "r'" + "R'" )
+ * ( Q ( ( P "\\'" + "\\\\" + 1 - S " '\r%" ) ^ 1 )
+ + VisualSpace
+ + PercentInterpol
+ + Q "%"
+ ) ^ 0
+ * Q "'" )
+% \end{macrocode}
+%
+% \begin{macrocode}
+ local DoubleShortString =
+ WithStyle ( 'String.Short' ,
+ Q ( P "f\"" + "F\"" )
+ * (
+ K ( 'String.Interpol' , "{" )
+ * K ( 'Interpol.Inside' , ( 1 - S "}\":" ) ^ 0 )
+ * ( K ( 'String.Interpol' , ":" ) * Q ( (1 - S "}:\"") ^ 0 ) ) ^ -1
+ * K ( 'String.Interpol' , "}" )
+ +
+ VisualSpace
+ +
+ Q ( ( P "\\\"" + "\\\\" + "{{" + "}}" + 1 - S " {}\"" ) ^ 1 )
+ ) ^ 0
+ * Q "\""
+ +
+ Q ( P "\"" + "r\"" + "R\"" )
+ * ( Q ( ( P "\\\"" + "\\\\" + 1 - S " \"\r%" ) ^ 1 )
+ + VisualSpace
+ + PercentInterpol
+ + Q "%"
+ ) ^ 0
+ * Q "\"" )
-
-
-local DoubleShortString =
- WithStyle ( 'String.Short' ,
- Q ( P "f\"" + "F\"" )
- * (
- K ( 'String.Interpol' , "{" )
- * K ( 'Interpol.Inside' , ( 1 - S "}\":" ) ^ 0 )
- * ( K ( 'String.Interpol' , ":" ) * Q ( (1 - S "}:\"") ^ 0 ) ) ^ -1
- * K ( 'String.Interpol' , "}" )
- +
- VisualSpace
- +
- Q ( ( P "\\\"" + "{{" + "}}" + 1 - S " {}\"" ) ^ 1 )
- ) ^ 0
- * Q "\""
- +
- Q ( P "\"" + "r\"" + "R\"" )
- * ( Q ( ( P "\\\"" + 1 - S " \"\r%" ) ^ 1 )
- + VisualSpace
- + PercentInterpol
- + Q "%"
- ) ^ 0
- * Q "\"" )
-
-local ShortString = SingleShortString + DoubleShortString
+ local ShortString = SingleShortString + DoubleShortString
% \end{macrocode}
%
% \bigskip
@@ -6353,16 +6565,16 @@
% catching} corresponding to the strings of the language.
%
% \begin{macrocode}
-local braces =
- Compute_braces
- (
- ( P "\"" + "r\"" + "R\"" + "f\"" + "F\"" )
- * ( P "\\\"" + 1 - S "\"" ) ^ 0 * "\""
- +
- ( P '\'' + 'r\'' + 'R\'' + 'f\'' + 'F\'' )
- * ( P '\\\'' + 1 - S '\'' ) ^ 0 * '\''
- )
-if piton.beamer then Beamer = Compute_Beamer ( 'python' , braces ) end
+ local braces =
+ Compute_braces
+ (
+ ( P "\"" + "r\"" + "R\"" + "f\"" + "F\"" )
+ * ( P "\\\"" + 1 - S "\"" ) ^ 0 * "\""
+ +
+ ( P '\'' + 'r\'' + 'R\'' + 'f\'' + 'F\'' )
+ * ( P '\\\'' + 1 - S '\'' ) ^ 0 * '\''
+ )
+ if piton.beamer then Beamer = Compute_Beamer ( 'python' , braces ) end
% \end{macrocode}
%
% \bigskip
@@ -6369,7 +6581,7 @@
% \paragraph{Detected commands}
%
% \begin{macrocode}
-DetectedCommands = Compute_DetectedCommands ( 'python' , braces )
+ DetectedCommands = Compute_DetectedCommands ( 'python' , braces )
% \end{macrocode}
%
% \bigskip
@@ -6377,7 +6589,7 @@
% \paragraph{LPEG_cleaner}
%
% \begin{macrocode}
-LPEG_cleaner['python'] = Compute_LPEG_cleaner ( 'python' , braces )
+ LPEG_cleaner['python'] = Compute_LPEG_cleaner ( 'python' , braces )
% \end{macrocode}
%
% \bigskip
@@ -6385,66 +6597,67 @@
%
%
% \begin{macrocode}
-local SingleLongString =
- WithStyle ( 'String.Long' ,
- ( Q ( S "fF" * P "'''" )
- * (
- K ( 'String.Interpol' , "{" )
- * K ( 'Interpol.Inside' , ( 1 - S "}:\r" - "'''" ) ^ 0 )
- * Q ( P ":" * (1 - S "}:\r" - "'''" ) ^ 0 ) ^ -1
- * K ( 'String.Interpol' , "}" )
- +
- Q ( ( 1 - P "'''" - S "{}'\r" ) ^ 1 )
- +
- EOL
- ) ^ 0
- +
- Q ( ( S "rR" ) ^ -1 * "'''" )
- * (
- Q ( ( 1 - P "'''" - S "\r%" ) ^ 1 )
- +
- PercentInterpol
- +
- P "%"
- +
- EOL
- ) ^ 0
- )
- * Q "'''" )
-
-
-local DoubleLongString =
- WithStyle ( 'String.Long' ,
- (
- Q ( S "fF" * "\"\"\"" )
- * (
- K ( 'String.Interpol', "{" )
- * K ( 'Interpol.Inside' , ( 1 - S "}:\r" - "\"\"\"" ) ^ 0 )
- * Q ( ":" * (1 - S "}:\r" - "\"\"\"" ) ^ 0 ) ^ -1
- * K ( 'String.Interpol' , "}" )
- +
- Q ( ( 1 - S "{}\"\r" - "\"\"\"" ) ^ 1 )
- +
- EOL
- ) ^ 0
- +
- Q ( S "rR" ^ -1 * "\"\"\"" )
- * (
- Q ( ( 1 - P "\"\"\"" - S "%\r" ) ^ 1 )
- +
- PercentInterpol
- +
- P "%"
- +
- EOL
- ) ^ 0
- )
- * Q "\"\"\""
- )
+ local SingleLongString =
+ WithStyle ( 'String.Long' ,
+ ( Q ( S "fF" * P "'''" )
+ * (
+ K ( 'String.Interpol' , "{" )
+ * K ( 'Interpol.Inside' , ( 1 - S "}:\r" - "'''" ) ^ 0 )
+ * Q ( P ":" * (1 - S "}:\r" - "'''" ) ^ 0 ) ^ -1
+ * K ( 'String.Interpol' , "}" )
+ +
+ Q ( ( 1 - P "'''" - S "{}'\r" ) ^ 1 )
+ +
+ EOL
+ ) ^ 0
+ +
+ Q ( ( S "rR" ) ^ -1 * "'''" )
+ * (
+ Q ( ( 1 - P "'''" - S "\r%" ) ^ 1 )
+ +
+ PercentInterpol
+ +
+ P "%"
+ +
+ EOL
+ ) ^ 0
+ )
+ * Q "'''" )
% \end{macrocode}
+%
+% \begin{macrocode}
+ local DoubleLongString =
+ WithStyle ( 'String.Long' ,
+ (
+ Q ( S "fF" * "\"\"\"" )
+ * (
+ K ( 'String.Interpol', "{" )
+ * K ( 'Interpol.Inside' , ( 1 - S "}:\r" - "\"\"\"" ) ^ 0 )
+ * Q ( ":" * (1 - S "}:\r" - "\"\"\"" ) ^ 0 ) ^ -1
+ * K ( 'String.Interpol' , "}" )
+ +
+ Q ( ( 1 - S "{}\"\r" - "\"\"\"" ) ^ 1 )
+ +
+ EOL
+ ) ^ 0
+ +
+ Q ( S "rR" ^ -1 * "\"\"\"" )
+ * (
+ Q ( ( 1 - P "\"\"\"" - S "%\r" ) ^ 1 )
+ +
+ PercentInterpol
+ +
+ P "%"
+ +
+ EOL
+ ) ^ 0
+ )
+ * Q "\"\"\""
+ )
+% \end{macrocode}
%
% \begin{macrocode}
-local LongString = SingleLongString + DoubleLongString
+ local LongString = SingleLongString + DoubleLongString
% \end{macrocode}
%
% \bigskip
@@ -6452,12 +6665,12 @@
% be used in the \textsc{lpeg} |DefFunction| which deals with the whole preamble
% of a function definition (which begins with |def|).
% \begin{macrocode}
-local StringDoc =
- K ( 'String.Doc' , P "r" ^ -1 * "\"\"\"" )
- * ( K ( 'String.Doc' , (1 - P "\"\"\"" - "\r" ) ^ 0 ) * EOL
- * Tab ^ 0
- ) ^ 0
- * K ( 'String.Doc' , ( 1 - P "\"\"\"" - "\r" ) ^ 0 * "\"\"\"" )
+ local StringDoc =
+ K ( 'String.Doc' , P "r" ^ -1 * "\"\"\"" )
+ * ( K ( 'String.Doc' , (1 - P "\"\"\"" - "\r" ) ^ 0 ) * EOL
+ * Tab ^ 0
+ ) ^ 0
+ * K ( 'String.Doc' , ( 1 - P "\"\"\"" - "\r" ) ^ 0 * "\"\"\"" )
% \end{macrocode}
%
% \bigskip
@@ -6466,10 +6679,12 @@
% We define different \textsc{lpeg} dealing with comments in the Python
% listings.
% \begin{macrocode}
-local Comment =
- WithStyle ( 'Comment' ,
- Q "#" * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 ) -- $
- * ( EOL + -1 )
+ local Comment =
+ WithStyle
+ ( 'Comment' ,
+ Q "#" * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 -- $
+ )
+ * ( EOL + -1 )
% \end{macrocode}
%
%
@@ -6482,19 +6697,19 @@
% (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 expression =
- P { "E" ,
- E = ( "'" * ( P "\\'" + 1 - S "'\r" ) ^ 0 * "'"
- + "\"" * ( P "\\\"" + 1 - S "\"\r" ) ^ 0 * "\""
- + "{" * V "F" * "}"
- + "(" * V "F" * ")"
- + "[" * V "F" * "]"
- + ( 1 - S "{}()[]\r," ) ) ^ 0 ,
- F = ( "{" * V "F" * "}"
- + "(" * V "F" * ")"
- + "[" * V "F" * "]"
- + ( 1 - S "{}()[]\r\"'" ) ) ^ 0
- }
+ local expression =
+ P { "E" ,
+ E = ( "'" * ( P "\\'" + 1 - S "'\r" ) ^ 0 * "'"
+ + "\"" * ( P "\\\"" + 1 - S "\"\r" ) ^ 0 * "\""
+ + "{" * V "F" * "}"
+ + "(" * V "F" * ")"
+ + "[" * V "F" * "]"
+ + ( 1 - S "{}()[]\r," ) ) ^ 0 ,
+ F = ( "{" * V "F" * "}"
+ + "(" * V "F" * ")"
+ + "[" * V "F" * "]"
+ + ( 1 - S "{}()[]\r\"'" ) ) ^ 0
+ }
% \end{macrocode}
%
% \bigskip
@@ -6508,15 +6723,15 @@
%
% \medskip
% \begin{macrocode}
-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' , identifier )
- ) ^ -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' , identifier )
+ ) ^ -1
+ }
% \end{macrocode}
%
%
@@ -6527,14 +6742,14 @@
% |piton.sty|) after the definition of several other \textsc{lpeg} such as
% |Comment|, |CommentLaTeX|, |Params|, |StringDoc|...
% \begin{macrocode}
-local DefFunction =
- K ( 'Keyword' , "def" )
- * Space
- * K ( 'Name.Function.Internal' , identifier )
- * SkipSpace
- * Q "(" * Params * Q ")"
- * SkipSpace
- * ( Q "->" * SkipSpace * K ( 'Name.Type' , identifier ) ) ^ -1
+ local DefFunction =
+ K ( 'Keyword' , "def" )
+ * Space
+ * K ( 'Name.Function.Internal' , identifier )
+ * SkipSpace
+ * Q "(" * Params * Q ")"
+ * SkipSpace
+ * ( Q "->" * SkipSpace * K ( 'Name.Type' , identifier ) ) ^ -1
% \end{macrocode}
% Here, we need a \pkg{piton} style |ParseAgain.noCR| which will be linked to
% |\@@_piton_no_cr:n| (that means that the capture will be parsed once again by
@@ -6541,14 +6756,14 @@
% \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.noCR' , ( 1 - S ":\r" ) ^ 0 )
- * Q ":"
- * ( SkipSpace
- * ( EOL + CommentLaTeX + Comment ) -- in all cases, that contains an EOL
- * Tab ^ 0
- * SkipSpace
- * StringDoc ^ 0 -- there may be additional docstrings
- ) ^ -1
+ * K ( 'ParseAgain.noCR' , ( 1 - S ":\r" ) ^ 0 )
+ * Q ":"
+ * ( SkipSpace
+ * ( EOL + CommentLaTeX + Comment ) -- in all cases, that contains an EOL
+ * Tab ^ 0
+ * SkipSpace
+ * StringDoc ^ 0 -- there may be additional docstrings
+ ) ^ -1
% \end{macrocode}
% Remark that, in the previous code, |CommentLaTeX| \emph{must} appear
% before |Comment|: there is no commutativity of the addition for the
@@ -6563,7 +6778,7 @@
% \paragraph{Miscellaneous}
%
% \begin{macrocode}
-local ExceptionInConsole = Exception * Q ( ( 1 - P "\r" ) ^ 0 ) * EOL
+ local ExceptionInConsole = Exception * Q ( ( 1 - P "\r" ) ^ 0 ) * EOL
% \end{macrocode}
%
%
@@ -6571,44 +6786,44 @@
% \paragraph{The main LPEG for the language Python}
%
% \begin{macrocode}
-local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
+ local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
% \end{macrocode}
%
% First, the main loop :
% \begin{macrocode}
-local Main =
- -- space ^ 1 * -1
- -- + space ^ 0 * EOL
- Space
- + Tab
- + Escape + EscapeMath
- + CommentLaTeX
- + Beamer
- + DetectedCommands
- + LongString
- + Comment
- + ExceptionInConsole
- + Delim
- + Operator
- + OperatorWord * EndKeyword
- + ShortString
- + Punct
- + FromImport
- + RaiseException
- + DefFunction
- + DefClass
- + For
- + Keyword * EndKeyword
- + Decorator
- + Builtin * EndKeyword
- + Identifier
- + Number
- + Word
+ local Main =
+ space ^ 0 * EOL -- faut-il le mettre en commentaire ?
+ + Space
+ + Tab
+ + Escape + EscapeMath
+ + CommentLaTeX
+ + Beamer
+ + DetectedCommands
+ + LongString
+ + Comment
+ + ExceptionInConsole
+ + Delim
+ + Operator
+ + OperatorWord * EndKeyword
+ + ShortString
+ + Punct
+ + FromImport
+ + RaiseException
+ + DefFunction
+ + DefClass
+ + For
+ + Keyword * EndKeyword
+ + Decorator
+ + Builtin * EndKeyword
+ + Identifier
+ + Number
+ + Word
% \end{macrocode}
%
+% \bigskip
% Here, we must not put |local|!
% \begin{macrocode}
-LPEG1['python'] = Main ^ 0
+ LPEG1['python'] = Main ^ 0
% \end{macrocode}
%
% \bigskip
@@ -6618,547 +6833,654 @@
% will be used as marker in order to delimit the argument of the command
% \texttt{\textbackslash @@\_begin\_line:}}.
% \begin{macrocode}
-LPEG2['python'] =
- Ct (
- ( space ^ 0 * "\r" ) ^ -1
- * BeamerBeginEnvironments
- * PromptHastyDetection
- * Lc [[\@@_begin_line:]]
- * Prompt
- * SpaceIndentation ^ 0
- * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0
- * -1
- * Lc [[\@@_end_line:]]
- )
+ LPEG2['python'] =
+ Ct (
+ ( space ^ 0 * "\r" ) ^ -1
+ * BeamerBeginEnvironments
+ * PromptHastyDetection
+ * Lc [[\@@_begin_line:]]
+ * Prompt
+ * SpaceIndentation ^ 0
+ * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0
+ * -1
+ * Lc [[\@@_end_line:]]
+ )
% \end{macrocode}
%
+% \bigskip
+% End of the Lua scope for the language Python.
+% \begin{macrocode}
+end
+% \end{macrocode}
%
% \bigskip
% \subsubsection{The language Ocaml}
%
+% We open a Lua local scope for the language OCaml (of course, there will be also
+% global definitions).
+% \begin{macrocode}
+do
+% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+ local SkipSpace = ( Q " " + EOL ) ^ 0
+ local Space = ( Q " " + EOL ) ^ 1
+% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+ local braces = Compute_braces ( "\"" * ( 1 - S "\"" ) ^ 0 * "\"" )
+% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+ if piton.beamer then
+ Beamer = Compute_Beamer ( 'ocaml' , braces )
+ end
+ DetectedCommands = Compute_DetectedCommands ( 'ocaml' , braces )
+ local function Q ( pattern )
+ return Ct ( Cc ( luatexbase.catcodetables.CatcodeTableOther )
+ * C ( pattern ) )
+ + Beamer + DetectedCommands + EscapeMath + Escape
+ end
+% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+ local function K ( style , pattern )
+ return
+ Lc ( "{\\PitonStyle{" .. style .. "}{" )
+ * Q ( pattern )
+ * Lc "}}"
+ end
+% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+ local function WithStyle ( style , pattern )
+ return
+ Ct ( Cc "Open" * Cc ( "{\\PitonStyle{" .. style .. "}{" ) * Cc "}}" )
+ * ( pattern + Beamer + DetectedCommands + EscapeMath + Escape )
+ * Ct ( Cc "Close" )
+ end
+% \end{macrocode}
+%
+% \bigskip
% The following LPEG corresponds to the balanced expressions (balanced according
% to the parenthesis). Of course, we must write |(1 - S "()")| with outer parenthesis.
% \begin{macrocode}
-local balanced_parens =
- P { "E" , E = ( "(" * V "E" * ")" + ( 1 - S "()" ) ) ^ 0 }
+ local balanced_parens =
+ P { "E" , E = ( "(" * V "E" * ")" + ( 1 - S "()" ) ) ^ 0 }
% \end{macrocode}
+%
+% \paragraph{The strings of OCaml}
+% \begin{macrocode}
+ local ocaml_string =
+ Q "\""
+ * (
+ VisualSpace
+ +
+ Q ( ( 1 - S " \"\r" ) ^ 1 )
+ +
+ EOL
+ ) ^ 0
+ * Q "\""
+% \end{macrocode}
+%
+% \begin{macrocode}
+ local String = WithStyle ( 'String.Long' , ocaml_string )
+% \end{macrocode}
+%
+% \bigskip
+% Now, the ``quoted strings'' of OCaml (for example \verb+{ext|Essai|ext}+).
+%
+% For those strings, we will do two consecutive analysis. First an analysis to
+% determine the whole string and, then, an analysis for the potential visual
+% spaces and the EOL in the string.
%
+% The first analysis require a match-time capture. For explanations about that
+% programmation, see the paragraphe \emph{Lua's long strings} in
+% |www.inf.puc-rio.br/~roberto/lpeg|.
+%
% \begin{macrocode}
-local Delim = Q ( P "[|" + "|]" + S "[()]" )
+ local ext = ( R "az" + "_" ) ^ 0
+ local open = "{" * Cg ( ext , 'init' ) * "|"
+ local close = "|" * C ( ext ) * "}"
+ local closeeq =
+ Cmt ( close * Cb ( 'init' ) ,
+ function ( s , i , a , b ) return a == b end )
% \end{macrocode}
%
+% \medskip
+% The \textsc{lpeg} |QuotedStringBis| will do the second analysis.
% \begin{macrocode}
-local Punct = Q ( S ",:;!" )
+ local QuotedStringBis =
+ WithStyle ( 'String.Long' ,
+ (
+ Space
+ +
+ Q ( ( 1 - S " \r" ) ^ 1 )
+ +
+ EOL
+ ) ^ 0 )
% \end{macrocode}
%
-% The identifiers caught by |cap_identifier| begin with a cap. In OCaml, it's
-% used for the constructors of types and for the modules.
+% \medskip
+% We use a ``function capture'' (as called in the official documentation of the
+% \textsc{lpeg}) in order to do the second analysis on the result of the first one.
% \begin{macrocode}
-local cap_identifier = R "AZ" * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0
+ local QuotedString =
+ C ( open * ( 1 - closeeq ) ^ 0 * close ) /
+ ( function ( s ) return QuotedStringBis : match ( s ) end )
% \end{macrocode}
%
+% \bigskip
+% In OCaml, the delimiters for the comments are |(*| and |*)|. There are
+% unsymmetrical and OCaml allows those comments to be nested. That's why we need a
+% grammar.
+%
+% In these comments, we embed the math comments (between |$| and |$|) and we
+% embed also a treatment for the end of lines (since the comments may be multi-lines).
+%
% \begin{macrocode}
-local Constructor = K ( 'Name.Constructor' , cap_identifier )
-local ModuleType = K ( 'Name.Type' , cap_identifier )
+ local Comment =
+ WithStyle ( 'Comment' ,
+ P {
+ "A" ,
+ A = Q "(*"
+ * ( V "A"
+ + Q ( ( 1 - S "\r$\"" - "(*" - "*)" ) ^ 1 ) -- $
+ + ocaml_string
+ + "$" * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1 ) * "$" -- $
+ + EOL
+ ) ^ 0
+ * Q "*)"
+ } )
% \end{macrocode}
%
-% The identifiers which begin with a lower case letter or an underscore are used
-% elsewhere in OCaml.
+%
+% \paragraph{Some standard LPEG}
+%
% \begin{macrocode}
-local identifier = ( R "az" + "_" ) * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0
-local Identifier = K ( 'Identifier.Internal' , identifier )
+ local Delim = Q ( P "[|" + "|]" + S "[()]" )
+ local Punct = Q ( S ",:;!" )
% \end{macrocode}
%
+% \bigskip
+% The identifiers caught by |cap_identifier| begin with a capital. In OCaml,
+% it's used for the constructors of types and for the names of the modules.
%
-% Now, we deal with the records because we want to catch the names of the fields
-% of those records in all circunstancies.
% \begin{macrocode}
-local expression_for_fields =
- P { "E" ,
- E = ( "{" * V "F" * "}"
- + "(" * V "F" * ")"
- + "[" * V "F" * "]"
- + "\"" * ( P "\\\"" + 1 - S "\"\r" ) ^ 0 * "\""
- + "'" * ( P "\\'" + 1 - S "'\r" ) ^ 0 * "'"
- + ( 1 - S "{}()[]\r;" ) ) ^ 0 ,
- F = ( "{" * V "F" * "}"
- + "(" * V "F" * ")"
- + "[" * V "F" * "]"
- + ( 1 - S "{}()[]\r\"'" ) ) ^ 0
- }
+ local cap_identifier = R "AZ" * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0
% \end{macrocode}
-%
+%
+% \bigskip
% \begin{macrocode}
-local OneFieldDefinition =
- ( K ( 'Keyword' , "mutable" ) * SkipSpace ) ^ -1
- * K ( 'Name.Field' , identifier ) * SkipSpace
- * Q ":" * SkipSpace
- * K ( 'TypeExpression' , expression_for_fields )
- * SkipSpace
-
-local OneField =
- K ( 'Name.Field' , identifier ) * SkipSpace
- * Q "=" * SkipSpace
- * ( expression_for_fields
- / ( function ( s ) return LPEG1['ocaml'] : match ( s ) end )
- )
- * SkipSpace
-
-local Record =
- Q "{" * SkipSpace
- *
- (
- OneFieldDefinition * ( Q ";" * SkipSpace * OneFieldDefinition ) ^ 0
- +
- OneField * ( Q ";" * SkipSpace * OneField ) ^ 0
- )
- *
- Q "}"
+ local Constructor =
+ K ( 'Name.Constructor' ,
+ Q "`" ^ -1 * cap_identifier
% \end{macrocode}
+% We consider |::| and |[]| as constructors (of the lists) as does the Tuareg
+% mode of Emacs.
+% \begin{macrocode}
+ + Q "::"
+ + Q "[" * SkipSpace * Q "]" )
+% \end{macrocode}
%
% \bigskip
-% Now, we deal with the notations with points (eg: |List.length|). In OCaml,
-% such notation is used for the fields of the records and for the modules.
% \begin{macrocode}
-local DotNotation =
- (
- K ( 'Name.Module' , cap_identifier )
- * Q "."
- * ( Identifier + Constructor + Q "(" + Q "[" + Q "{" ) ^ ( -1 )
- +
- Identifier
- * Q "."
- * K ( 'Name.Field' , identifier )
- )
- * ( Q "." * K ( 'Name.Field' , identifier ) ) ^ 0
+ local ModuleType = K ( 'Name.Type' , cap_identifier )
% \end{macrocode}
%
+% \bigskip
% \begin{macrocode}
-local Operator =
- K ( 'Operator' ,
- P "!=" + "<>" + "==" + "<<" + ">>" + "<=" + ">=" + ":=" + "||" + "&&" +
- "//" + "**" + ";;" + "::" + "->" + "+." + "-." + "*." + "/."
- + S "-~+/*%=<>&@|" )
-
-local OperatorWord =
- K ( 'Operator.Word' ,
- P "asr" + "land" + "lor" + "lsl" + "lxor" + "mod" + "or" )
-
-
-local governing_keyword = P "and" + "begin" + "class" + "constraint" +
- "end" + "external" + "functor" + "include" + "inherit" + "initializer" +
- "in" + "let" + "method" + "module" + "object" + "open" + "rec" + "sig" +
- "struct" + "type" + "val"
-
-local Keyword =
- K ( 'Keyword' ,
- P "assert" + "as" + "done" + "downto" + "do" + "else" + "exception"
- + "for" + "function" + "fun" + "if" + "lazy" + "match" + "mutable"
- + "new" + "of" + "private" + "raise" + "then" + "to" + "try"
- + "virtual" + "when" + "while" + "with" )
- + K ( 'Keyword.Constant' , P "true" + "false" )
- + K ('Keyword.Governing', governing_keyword )
-
-local Builtin =
- K ( 'Name.Builtin' , P "not" + "incr" + "decr" + "fst" + "snd" + "ref" )
+ local OperatorWord =
+ K ( 'Operator.Word' ,
+ P "asr" + "land" + "lor" + "lsl" + "lxor" + "mod" + "or" )
% \end{macrocode}
%
% \bigskip
-% The following exceptions are exceptions in the standard library of OCaml (Stdlib).
+% In OCaml, some keywords are considered as \emph{governing keywords} with some
+% special syntactic characteristics.
% \begin{macrocode}
-local Exception =
- K ( 'Exception' ,
- P "Division_by_zero" + "End_of_File" + "Failure" + "Invalid_argument" +
- "Match_failure" + "Not_found" + "Out_of_memory" + "Stack_overflow" +
- "Sys_blocked_io" + "Sys_error" + "Undefined_recursive_module" )
+ local governing_keyword = P "and" + "begin" + "class" + "constraint" +
+ "end" + "external" + "functor" + "include" + "inherit" + "initializer" +
+ "in" + "let" + "method" + "module" + "object" + "open" + "rec" + "sig" +
+ "struct" + "type" + "val"
% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+ local Keyword =
+ K ( 'Keyword' ,
+ P "assert" + "as" + "done" + "downto" + "do" + "else" + "exception"
+ + "for" + "function" + "fun" + "if" + "lazy" + "match" + "mutable"
+ + "new" + "of" + "private" + "raise" + "then" + "to" + "try"
+ + "virtual" + "when" + "while" + "with" )
+ + K ( 'Keyword.Constant' , P "true" + "false" )
+ + K ( 'Keyword.Governing', governing_keyword )
+% \end{macrocode}
%
% \bigskip
-% \paragraph{The characters in OCaml}
+% \begin{macrocode}
+ local EndKeyword
+ = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
+% \end{macrocode}
%
+% \bigskip
+% Now, the identifier. Recall that we have also a LPEG |cap_identifier| for the
+% indentifiers beginning with a capital letter.
% \begin{macrocode}
-local Char =
- K ( 'String.Short',
- P "'" *
- (
- ( 1 - S "'\\" )
- + "\\"
- * ( S "\\'ntbr \""
- + digit * digit * digit
- + P "x" * ( digit + R "af" + R "AF" )
- * ( digit + R "af" + R "AF" )
- * ( digit + R "af" + R "AF" )
- + P "o" * R "03" * R "07" * R "07" )
- )
- * "'" )
+ local identifier = ( R "az" + "_" ) * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0
+ - ( OperatorWord + Keyword ) * EndKeyword
% \end{macrocode}
-%
%
% \bigskip
-% \paragraph{Beamer}
+% We have the internal style |Identifier.Internal| in order to be able to
+% implement the mechanism |\SetPitonIdentifier|. The final user has access to a
+% style called |Identifier|.
+% \begin{macrocode}
+ local Identifier = K ( 'Identifier.Internal' , identifier )
+% \end{macrocode}
%
% \bigskip
-% The argument of |Compute_braces| must be a pattern \emph{which does no
-% catching} corresponding to the strings of the language.
+% In OCmal, \emph{character} is a type different of the type |string|.
+% \begin{macrocode}
+ local Char =
+ K ( 'String.Short',
+ P "'" *
+ (
+ ( 1 - S "'\\" )
+ + "\\"
+ * ( S "\\'ntbr \""
+ + digit * digit * digit
+ + P "x" * ( digit + R "af" + R "AF" )
+ * ( digit + R "af" + R "AF" )
+ * ( digit + R "af" + R "AF" )
+ + P "o" * R "03" * R "07" * R "07" )
+ )
+ * "'" )
+% \end{macrocode}
%
+% \bigskip
+% For the parameter of the types (for example : |`\a| as in |`a list|).
% \begin{macrocode}
-local braces = Compute_braces ( "\"" * ( 1 - S "\"" ) ^ 0 * "\"" )
-if piton.beamer then
- Beamer = Compute_Beamer ( 'ocaml' , braces ) -- modified 2024/07/24
-end
+ local TypeParameter =
+ K ( 'TypeParameter' ,
+ "'" * Q"_" ^ -1 * alpha ^ 1 * ( # ( 1 - P "'" ) + -1 ) )
% \end{macrocode}
-%
+%
+% \paragraph{The records}
+%
% \begin{macrocode}
-DetectedCommands = Compute_DetectedCommands ( 'ocaml' , braces )
+ local expression_for_fields_type =
+ P { "E" ,
+ E = ( "{" * V "F" * "}"
+ + "(" * V "F" * ")"
+ + TypeParameter
+ + ( 1 - S "{}()[]\r;" ) ) ^ 0 ,
+ F = ( "{" * V "F" * "}"
+ + "(" * V "F" * ")"
+ + ( 1 - S "{}()[]\r\"'" ) + TypeParameter ) ^ 0
+ }
% \end{macrocode}
%
% \bigskip
% \begin{macrocode}
-LPEG_cleaner['ocaml'] = Compute_LPEG_cleaner ( 'ocaml' , braces )
+ local expression_for_fields_value =
+ P { "E" ,
+ E = ( "{" * V "F" * "}"
+ + "(" * V "F" * ")"
+ + "[" * V "F" * "]"
+ + String + QuotedString + Char
+ + ( 1 - S "{}()[]\r;" ) ) ^ 0 ,
+ F = ( "{" * V "F" * "}"
+ + "(" * V "F" * ")"
+ + "[" * V "F" * "]"
+ + ( 1 - S "{}()[]\r\"'" )) ^ 0
+ }
% \end{macrocode}
%
% \bigskip
-%
-%
-% \paragraph{The strings en OCaml}
-%
-% We need a pattern |ocaml_string| without captures because it will be used
-% within the comments of OCaml.
% \begin{macrocode}
-local ocaml_string =
- Q "\""
- * (
- VisualSpace
- +
- Q ( ( 1 - S " \"\r" ) ^ 1 )
- +
- EOL
- ) ^ 0
- * Q "\""
+ local OneFieldDefinition =
+ ( K ( 'Keyword' , "mutable" ) * SkipSpace ) ^ -1
+ * K ( 'Name.Field' , identifier ) * SkipSpace
+ * Q ":" * SkipSpace
+ * K ( 'TypeExpression' , expression_for_fields_type )
+ * SkipSpace
% \end{macrocode}
-%
+%
+% \bigskip
% \begin{macrocode}
-local String = WithStyle ( 'String.Long' , ocaml_string )
+ local OneField =
+ K ( 'Name.Field' , identifier ) * SkipSpace
+ * Q "=" * SkipSpace
+ * ( expression_for_fields_value
+ / ( function ( s ) return LPEG1['ocaml'] : match ( s ) end )
+ )
+ * SkipSpace
% \end{macrocode}
%
-%
% \bigskip
-% Now, the ``quoted strings'' of OCaml (for example \verb+{ext|Essai|ext}+).
-%
-% For those strings, we will do two consecutive analysis. First an analysis to
-% determine the whole string and, then, an analysis for the potential visual
-% spaces and the EOL in the string.
-%
-% The first analysis require a match-time capture. For explanations about that
-% programmation, see the paragraphe \emph{Lua's long % strings} in
-% |www.inf.puc-rio.br/~roberto/lpeg|.
+% The \emph{records} may occur in the definitions of type (beginning by |type|)
+% but also when used as values.
% \begin{macrocode}
-local ext = ( R "az" + "_" ) ^ 0
-local open = "{" * Cg ( ext , 'init' ) * "|"
-local close = "|" * C ( ext ) * "}"
-local closeeq =
- Cmt ( close * Cb ( 'init' ) ,
- function ( s , i , a , b ) return a == b end )
+ local Record =
+ Q "{" * SkipSpace
+ *
+ (
+ OneFieldDefinition
+ * ( Q ";" * SkipSpace * ( Comment * SkipSpace ) ^ 0 * OneFieldDefinition ) ^ 0
+ +
+ OneField * ( Q ";" * SkipSpace * ( Comment * SkipSpace ) ^ 0 * OneField ) ^ 0
+ )
+ * SkipSpace
+ * Q ";" ^ -1
+ * SkipSpace
+ * Comment ^ -1
+ * SkipSpace
+ * Q "}"
% \end{macrocode}
%
-% \medskip
-% The \textsc{lpeg} |QuotedStringBis| will do the second analysis.
+% \paragraph{DotNotation}
+%
+% Now, we deal with the notations with points (eg: |List.length|). In OCaml,
+% such notation is used for the fields of the records and for the modules.
% \begin{macrocode}
-local QuotedStringBis =
- WithStyle ( 'String.Long' ,
- (
- Space
+ local DotNotation =
+ (
+ K ( 'Name.Module' , cap_identifier )
+ * Q "."
+ * ( Identifier + Constructor + Q "(" + Q "[" + Q "{" ) ^ -1
+
- Q ( ( 1 - S " \r" ) ^ 1 )
- +
- EOL
- ) ^ 0 )
+ Identifier
+ * Q "."
+ * K ( 'Name.Field' , identifier )
+ )
+ * ( Q "." * K ( 'Name.Field' , identifier ) ) ^ 0
% \end{macrocode}
-%
-% \medskip
-% We use a ``function capture'' (as called in the official documentation of the
-% \textsc{lpeg}) in order to do the second analysis on the result of the first one.
+%
+% \bigskip
% \begin{macrocode}
-local QuotedString =
- C ( open * ( 1 - closeeq ) ^ 0 * close ) /
- ( function ( s ) return QuotedStringBis : match ( s ) end )
+ local Operator =
+ K ( 'Operator' ,
+ P "!=" + "<>" + "==" + "<<" + ">>" + "<=" + ">=" + ":=" + "||" + "&&" +
+ "//" + "**" + ";;" + "->" + "+." + "-." + "*." + "/."
+ + S "-~+/*%=<>&@|" )
% \end{macrocode}
-%
%
% \bigskip
-% \paragraph{The comments in the OCaml listings}
+% \begin{macrocode}
+ local Builtin =
+ K ( 'Name.Builtin' , P "not" + "incr" + "decr" + "fst" + "snd" + "ref" )
+% \end{macrocode}
%
-% In OCaml, the delimiters for the comments are |(*| and |*)|. There are
-% unsymmetrical and OCaml allows those comments to be nested. That's why we need a
-% grammar.
-%
-% In these comments, we embed the math comments (between |$| and |$|) and we
-% embed also a treatment for the end of lines (since the comments may be multi-lines).
-%
+% \bigskip
% \begin{macrocode}
-local Comment =
- WithStyle ( 'Comment' ,
- P {
- "A" ,
- A = Q "(*"
- * ( V "A"
- + Q ( ( 1 - S "\r$\"" - "(*" - "*)" ) ^ 1 ) -- $
- + ocaml_string
- + "$" * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1 ) * "$" -- $
- + EOL
- ) ^ 0
- * Q "*)"
- } )
+ local Exception =
+ K ( 'Exception' ,
+ P "Division_by_zero" + "End_of_File" + "Failure" + "Invalid_argument" +
+ "Match_failure" + "Not_found" + "Out_of_memory" + "Stack_overflow" +
+ "Sys_blocked_io" + "Sys_error" + "Undefined_recursive_module" )
% \end{macrocode}
-%
+%
% \bigskip
-% \paragraph{The DefFunction}
+% \begin{macrocode}
+ LPEG_cleaner['ocaml'] = Compute_LPEG_cleaner ( 'ocaml' , braces )
+% \end{macrocode}
%
+% \bigskip
% \begin{macrocode}
-local Argument =
+ local Argument =
% \end{macrocode}
% For the labels of the labeled arguments. Maybe you will, in the future, create
% a style for those elements.
% \begin{macrocode}
- ( Q "~" * Identifier * Q ":" * SkipSpace ) ^ -1
- *
- ( K ( 'Identifier.Internal' , identifier )
- + Q "(" * SkipSpace
- * K ( 'Identifier.Internal' , identifier ) * SkipSpace
- * Q ":" * SkipSpace
- * K ( 'TypeExpression' , balanced_parens ) * SkipSpace
- * Q ")"
- )
+ ( Q "~" * Identifier * Q ":" * SkipSpace ) ^ -1
+ *
+ ( K ( 'Identifier.Internal' , identifier )
+ + Q "(" * SkipSpace
+ * K ( 'Identifier.Internal' , identifier ) * SkipSpace
+ * Q ":" * SkipSpace
+ * K ( 'TypeExpression' , balanced_parens ) * SkipSpace
+ * Q ")"
+ )
% \end{macrocode}
%
+% \bigskip
% Despite its name, then \textsc{lpeg} |DefFunction| deals also with |let open|
% which opens locally a module.
% \begin{macrocode}
-local DefFunction =
- K ( 'Keyword.Governing' , "let open" )
- * Space
- * K ( 'Name.Module' , cap_identifier )
- +
- K ( 'Keyword.Governing' , P "let rec" + "let" + "and" )
+ local DefFunction =
+ K ( 'Keyword.Governing' , "let open" )
* Space
- * K ( 'Name.Function.Internal' , identifier )
- * Space
- * (
- Q "=" * SkipSpace * K ( 'Keyword' , "function" )
- +
- Argument
- * ( SkipSpace * Argument ) ^ 0
- * (
- SkipSpace
- * Q ":"
- * K ( 'TypeExpression' , ( 1 - P "=" ) ^ 0 )
- ) ^ -1
- )
+ * K ( 'Name.Module' , cap_identifier )
+ +
+ K ( 'Keyword.Governing' , P "let rec" + "let" + "and" )
+ * Space
+ * K ( 'Name.Function.Internal' , identifier )
+ * Space
+ * (
+ Q "=" * SkipSpace * K ( 'Keyword' , "function" )
+ +
+ Argument
+ * ( SkipSpace * Argument ) ^ 0
+ * (
+ SkipSpace
+ * Q ":"
+ * K ( 'TypeExpression' , ( 1 - P "=" ) ^ 0 )
+ ) ^ -1
+ )
% \end{macrocode}
%
-%
-% \bigskip
-% \paragraph{The DefModule}\par
+% \paragraph{DefModule}
%
-% The following LPEG will be used in the definitions of modules but also in the
-% definitions of \emph{types} of modules.
% \begin{macrocode}
-local DefModule =
- K ( 'Keyword.Governing' , "module" ) * Space
- *
- (
- K ( 'Keyword.Governing' , "type" ) * Space
- * K ( 'Name.Type' , cap_identifier )
- +
- K ( 'Name.Module' , cap_identifier ) * SkipSpace
- *
- (
- Q "(" * SkipSpace
- * K ( 'Name.Module' , cap_identifier ) * SkipSpace
- * Q ":" * SkipSpace
- * K ( 'Name.Type' , cap_identifier ) * SkipSpace
- *
+ local DefModule =
+ K ( 'Keyword.Governing' , "module" ) * Space
+ *
+ (
+ K ( 'Keyword.Governing' , "type" ) * Space
+ * K ( 'Name.Type' , cap_identifier )
+ +
+ K ( 'Name.Module' , cap_identifier ) * SkipSpace
+ *
+ (
+ Q "(" * SkipSpace
+ * K ( 'Name.Module' , cap_identifier ) * SkipSpace
+ * Q ":" * SkipSpace
+ * K ( 'Name.Type' , cap_identifier ) * SkipSpace
+ *
+ (
+ Q "," * SkipSpace
+ * K ( 'Name.Module' , cap_identifier ) * SkipSpace
+ * Q ":" * SkipSpace
+ * K ( 'Name.Type' , cap_identifier ) * SkipSpace
+ ) ^ 0
+ * Q ")"
+ ) ^ -1
+ *
+ (
+ Q "=" * SkipSpace
+ * K ( 'Name.Module' , cap_identifier ) * SkipSpace
+ * Q "("
+ * K ( 'Name.Module' , cap_identifier ) * SkipSpace
+ *
(
- Q "," * SkipSpace
- * K ( 'Name.Module' , cap_identifier ) * SkipSpace
- * Q ":" * SkipSpace
- * K ( 'Name.Type' , cap_identifier ) * SkipSpace
- ) ^ 0
+ Q ","
+ *
+ K ( 'Name.Module' , cap_identifier ) * SkipSpace
+ ) ^ 0
* Q ")"
- ) ^ -1
- *
- (
- Q "=" * SkipSpace
- * K ( 'Name.Module' , cap_identifier ) * SkipSpace
- * Q "("
- * K ( 'Name.Module' , cap_identifier ) * SkipSpace
- *
- (
- Q ","
- *
- K ( 'Name.Module' , cap_identifier ) * SkipSpace
- ) ^ 0
- * Q ")"
- ) ^ -1
- )
- +
- K ( 'Keyword.Governing' , P "include" + "open" )
- * Space * K ( 'Name.Module' , cap_identifier )
+ ) ^ -1
+ )
+ +
+ K ( 'Keyword.Governing' , P "include" + "open" )
+ * Space
+ * K ( 'Name.Module' , cap_identifier )
% \end{macrocode}
%
-%
-% \bigskip
-% \paragraph{The DefType}\par
+% \paragraph{DefType}
%
% \begin{macrocode}
-local TypeParameter =
- K ( 'TypeParameter' , "'" * alpha * ( # ( 1 - P "'" ) + -1 ) )
+ local DefType =
+ K ( 'Keyword.Governing' , "type" )
+ * Space
+ * K ( 'TypeExpression' , Q ( 1 - P "=" ) ^ 1 )
+ * SkipSpace
+ * ( Q "+=" + Q "=" )
+ * SkipSpace
+ * (
+ Record
+ +
+ WithStyle
+ (
+ 'TypeExpression' ,
+ (
+ ( EOL + Q ( 1 - P ";;" - governing_keyword ) ) ^ 0
+ * ( # ( governing_keyword ) + Q ";;" )
+ )
+ )
+ )
% \end{macrocode}
%
-%
% \bigskip
-% The following LPEG is for the instructions of definitions of types (which
-% begin with |type|).
-% \begin{macrocode}
-local DefType =
- K ( 'Keyword.Governing' , "type" )
- * Space
- * WithStyle
- (
- 'TypeExpression' ,
- ( Q ( 1 - P ";;" - P "\r" ) + EOL_without_space_indentation ) ^ 0
- )
- * ( # governing_keyword + Q ";;" + -1 )
-% \end{macrocode}
-%
-% \bigskip
% \paragraph{The main LPEG for the language OCaml}
%
% \begin{macrocode}
-local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
+ local Main =
+ space ^ 0 * EOL
+ + Space
+ + Tab
+ + Escape + EscapeMath
+ + Beamer
+ + DetectedCommands
+ + TypeParameter
+ + String + QuotedString + Char
+ + Comment
+ + Operator
% \end{macrocode}
-%
-% First, the main loop :
+% For the labels (maybe we will write in the future a dedicated LPEG pour those tokens).
% \begin{macrocode}
-local Main =
- Space
- + Tab
- + Escape + EscapeMath
- + Beamer
- + DetectedCommands
- + TypeParameter
- + String + QuotedString + Char
- + Comment
- + Delim
- + Operator
+ + Q ( "~" ) * Identifier * ( Q ":" ) ^ -1
+ + Q ":" * # (1 - P ":") * SkipSpace
+ * K ( 'TypeExpression' , balanced_parens ) * SkipSpace * Q ")"
+ + Exception
+ + DefType
+ + DefFunction
+ + DefModule
+ + Record
+ + Keyword * EndKeyword
+ + OperatorWord * EndKeyword
+ + Builtin * EndKeyword
+ + DotNotation
+ + Constructor
+ + Identifier
+ + Punct
+ + Delim
+ + Number
+ + Word
% \end{macrocode}
-% For the labels of the labeled arguments. Maybe you will, in the future, create
-% a style for those elements.
+%
+% \bigskip
+% % Here, we must not put |local|!
% \begin{macrocode}
- + Q ( "~" ) * Identifier * ( Q ":" ) ^ -1
- + Q ":" * # (1 - P":") * SkipSpace
- * K ( 'TypeExpression' , balanced_parens ) * SkipSpace * Q ")"
- + Punct
- + Exception
- + DefFunction
- + DefModule
- + DefType
- + Record
- + Keyword * EndKeyword
- + OperatorWord * EndKeyword
- + Builtin * EndKeyword
- + DotNotation
- + Constructor
- + Identifier
- + Number
- + Word
-
-LPEG1['ocaml'] = Main ^ 0
+ LPEG1['ocaml'] = Main ^ 0
% \end{macrocode}
%
% \bigskip
-% We recall that each line in the 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}
-LPEG2['ocaml'] =
- Ct (
+ LPEG2['ocaml'] =
+ Ct (
% \end{macrocode}
% The following lines are in order to allow, in |\piton| (and not in |{Piton}|),
-% judments of type (such as |f : my_type -> 'a list|) or single expressions of
+% judgments of type (such as |f : my_type -> 'a list|) or single expressions of
% type such as |my_type -> 'a list| (in that case, the argument of |\piton|
% \emph{must} begin by a colon).
% \begin{macrocode}
- ( P ":" + Identifier * SkipSpace * Q ":" )
- * SkipSpace
- * K ( 'TypeExpression' , ( 1 - P "\r" ) ^ 0 )
- +
+ ( P ":" + Identifier * SkipSpace * Q ":" )
+ * SkipSpace
+ * K ( 'TypeExpression' , ( 1 - P "\r" ) ^ 0 )
+ +
+ ( space ^ 0 * "\r" ) ^ -1
+ * BeamerBeginEnvironments
+ * Lc [[\@@_begin_line:]]
+ * SpaceIndentation ^ 0
+ * ( ( space * Lc [[\@@_trailing_space:]] ) ^ 1 * -1
+ + space ^ 0 * EOL
+ + Main
+ ) ^ 0
+ * -1
+ * Lc [[\@@_end_line:]]
+ )
% \end{macrocode}
-% Now, the main part.
+%
+% \bigskip
+% End of the Lua scope for the language OCaml.
% \begin{macrocode}
- ( space ^ 0 * "\r" ) ^ -1
- * BeamerBeginEnvironments
- * Lc [[\@@_begin_line:]]
- * SpaceIndentation ^ 0
- * ( ( space * Lc [[\@@_trailing_space:]] ) ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0
- * -1
- * Lc [[\@@_end_line:]]
- )
+end
% \end{macrocode}
-%
%
+%
% \bigskip
% \subsubsection{The language C}
%
+% We open a Lua local scope for the language C (of course, there will be also
+% global definitions).
% \begin{macrocode}
-local Delim = Q ( S "{[()]}" )
+do
% \end{macrocode}
%
+% \bigskip
% \begin{macrocode}
-local Punct = Q ( S ",:;!" )
+ local Delim = Q ( S "{[()]}" )
% \end{macrocode}
%
+% \begin{macrocode}
+ local Punct = Q ( S ",:;!" )
+% \end{macrocode}
+%
% \bigskip
% 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 identifier = letter * alphanum ^ 0
-local Operator =
- K ( 'Operator' ,
- P "!=" + "==" + "<<" + ">>" + "<=" + ">=" + "||" + "&&"
- + S "-~+/*%=<>&.@|!" )
+ local Operator =
+ K ( 'Operator' ,
+ P "!=" + "==" + "<<" + ">>" + "<=" + ">=" + "||" + "&&"
+ + S "-~+/*%=<>&.@|!" )
-local Keyword =
- K ( 'Keyword' ,
- P "alignas" + "asm" + "auto" + "break" + "case" + "catch" + "class" +
- "const" + "constexpr" + "continue" + "decltype" + "do" + "else" + "enum" +
- "extern" + "for" + "goto" + "if" + "nexcept" + "private" + "public" +
- "register" + "restricted" + "return" + "static" + "static_assert" +
- "struct" + "switch" + "thread_local" + "throw" + "try" + "typedef" +
- "union" + "using" + "virtual" + "volatile" + "while"
- )
- + K ( 'Keyword.Constant' , P "default" + "false" + "NULL" + "nullptr" + "true" )
+ local Keyword =
+ K ( 'Keyword' ,
+ P "alignas" + "asm" + "auto" + "break" + "case" + "catch" + "class" +
+ "const" + "constexpr" + "continue" + "decltype" + "do" + "else" + "enum" +
+ "extern" + "for" + "goto" + "if" + "nexcept" + "private" + "public" +
+ "register" + "restricted" + "return" + "static" + "static_assert" +
+ "struct" + "switch" + "thread_local" + "throw" + "try" + "typedef" +
+ "union" + "using" + "virtual" + "volatile" + "while"
+ )
+ + K ( 'Keyword.Constant' , P "default" + "false" + "NULL" + "nullptr" + "true" )
-local Builtin =
- K ( 'Name.Builtin' ,
- P "alignof" + "malloc" + "printf" + "scanf" + "sizeof" )
+ local Builtin =
+ K ( 'Name.Builtin' ,
+ P "alignof" + "malloc" + "printf" + "scanf" + "sizeof" )
-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" ) * Q "*" ^ 0
+ 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" ) * Q "*" ^ 0
-local DefFunction =
- Type
- * Space
- * Q "*" ^ -1
- * K ( 'Name.Function.Internal' , identifier )
- * SkipSpace
- * # P "("
+ local DefFunction =
+ Type
+ * Space
+ * Q "*" ^ -1
+ * K ( 'Name.Function.Internal' , identifier )
+ * SkipSpace
+ * # P "("
% \end{macrocode}
% We remind that the marker |#| of \textsc{lpeg} specifies that the pattern will be
% detected but won't consume any character.
@@ -7171,8 +7493,8 @@
% \smallskip
% Example:\enskip \piton{class myclass:}
% \begin{macrocode}
-local DefClass =
- K ( 'Keyword' , "class" ) * Space * K ( 'Name.Class' , identifier )
+ 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 caught as
@@ -7183,17 +7505,17 @@
% \paragraph{The strings of C}
%
% \begin{macrocode}
-String =
- WithStyle ( 'String.Long' ,
- Q "\""
- * ( VisualSpace
- + K ( 'String.Interpol' ,
- "%" * ( S "difcspxXou" + "ld" + "li" + "hd" + "hi" )
- )
- + Q ( ( P "\\\"" + 1 - S " \"" ) ^ 1 )
- ) ^ 0
- * Q "\""
- )
+ String =
+ WithStyle ( 'String.Long' ,
+ Q "\""
+ * ( VisualSpace
+ + K ( 'String.Interpol' ,
+ "%" * ( S "difcspxXou" + "ld" + "li" + "hd" + "hi" )
+ )
+ + Q ( ( P "\\\"" + 1 - S " \"" ) ^ 1 )
+ ) ^ 0
+ * Q "\""
+ )
% \end{macrocode}
%
% \bigskip
@@ -7203,16 +7525,16 @@
% The argument of |Compute_braces| must be a pattern \emph{which does no
% catching} corresponding to the strings of the language.
% \begin{macrocode}
-local braces = Compute_braces ( "\"" * ( 1 - S "\"" ) ^ 0 * "\"" )
-if piton.beamer then Beamer = Compute_Beamer ( 'c' , braces ) end
+ local braces = Compute_braces ( "\"" * ( 1 - S "\"" ) ^ 0 * "\"" )
+ if piton.beamer then Beamer = Compute_Beamer ( 'c' , braces ) end
% \end{macrocode}
%
% \begin{macrocode}
-DetectedCommands = Compute_DetectedCommands ( 'c' , braces )
+ DetectedCommands = Compute_DetectedCommands ( 'c' , braces )
% \end{macrocode}
%
% \begin{macrocode}
-LPEG_cleaner['c'] = Compute_LPEG_cleaner ( 'c' , braces )
+ LPEG_cleaner['c'] = Compute_LPEG_cleaner ( 'c' , braces )
% \end{macrocode}
%
% \bigskip
@@ -7219,7 +7541,7 @@
% \paragraph{The directives of the preprocessor}
%
% \begin{macrocode}
-local Preproc = K ( 'Preproc' , "#" * ( 1 - P "\r" ) ^ 0 ) * ( EOL + -1 )
+ local Preproc = K ( 'Preproc' , "#" * ( 1 - P "\r" ) ^ 0 ) * ( EOL + -1 )
% \end{macrocode}
%
%
@@ -7228,17 +7550,17 @@
%
% We define different \textsc{lpeg} dealing with comments in the C listings.
% \begin{macrocode}
-local Comment =
- WithStyle ( 'Comment' ,
- Q "//" * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 ) -- $
- * ( EOL + -1 )
+ local Comment =
+ WithStyle ( 'Comment' ,
+ Q "//" * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 ) -- $
+ * ( EOL + -1 )
-local LongComment =
- WithStyle ( 'Comment' ,
- Q "/*"
- * ( CommentMath + Q ( ( 1 - P "*/" - S "$\r" ) ^ 1 ) + EOL ) ^ 0
- * Q "*/"
- ) -- $
+ local LongComment =
+ WithStyle ( 'Comment' ,
+ Q "/*"
+ * ( CommentMath + Q ( ( 1 - P "*/" - S "$\r" ) ^ 1 ) + EOL ) ^ 0
+ * Q "*/"
+ ) -- $
% \end{macrocode}
%
%
@@ -7248,37 +7570,39 @@
% \paragraph{The main LPEG for the language C}
%
% \begin{macrocode}
-local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
+ local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
% \end{macrocode}
%
% First, the main loop :
% \begin{macrocode}
-local Main =
- Space
- + Tab
- + Escape + EscapeMath
- + CommentLaTeX
- + Beamer
- + DetectedCommands
- + Preproc
- + Comment + LongComment
- + Delim
- + Operator
- + String
- + Punct
- + DefFunction
- + DefClass
- + Type * ( Q "*" ^ -1 + EndKeyword )
- + Keyword * EndKeyword
- + Builtin * EndKeyword
- + Identifier
- + Number
- + Word
+ local Main =
+ space ^ 0 * EOL
+ + Space
+ + Tab
+ + Escape + EscapeMath
+ + CommentLaTeX
+ + Beamer
+ + DetectedCommands
+ + Preproc
+ + Comment + LongComment
+ + Delim
+ + Operator
+ + String
+ + Punct
+ + DefFunction
+ + DefClass
+ + Type * ( Q "*" ^ -1 + EndKeyword )
+ + Keyword * EndKeyword
+ + Builtin * EndKeyword
+ + Identifier
+ + Number
+ + Word
% \end{macrocode}
%
+% \bigskip
% Here, we must not put |local|!
% \begin{macrocode}
-LPEG1['c'] = Main ^ 0
+ LPEG1['c'] = Main ^ 0
% \end{macrocode}
%
% \bigskip
@@ -7288,47 +7612,60 @@
% will be used as marker in order to delimit the argument of the command
% \texttt{\textbackslash @@\_begin\_line:}}.
% \begin{macrocode}
-LPEG2['c'] =
- Ct (
- ( space ^ 0 * P "\r" ) ^ -1
- * BeamerBeginEnvironments
- * Lc [[\@@_begin_line:]]
- * SpaceIndentation ^ 0
- * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0
- * -1
- * Lc [[\@@_end_line:]]
- )
+ LPEG2['c'] =
+ Ct (
+ ( space ^ 0 * P "\r" ) ^ -1
+ * BeamerBeginEnvironments
+ * Lc [[\@@_begin_line:]]
+ * SpaceIndentation ^ 0
+ * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0
+ * -1
+ * Lc [[\@@_end_line:]]
+ )
% \end{macrocode}
%
+% \bigskip
+% End of the Lua scope for the language C.
+% \begin{macrocode}
+end
+% \end{macrocode}
%
% \bigskip
% \subsubsection{The language SQL}
%
+% We open a Lua local scope for the language SQL (of course, there will be also
+% global definitions).
% \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
+do
% \end{macrocode}
%
% \bigskip
+% \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}
+%
+% \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 + "-" ) ^ 0
- + P '"' * ( ( 1 - P '"' ) ^ 1 ) * '"'
-
-
-local Operator =
- K ( 'Operator' , P "=" + "!=" + "<>" + ">=" + ">" + "<=" + "<" + S "*+/" )
+ local identifier =
+ letter * ( alphanum + "-" ) ^ 0
+ + P '"' * ( ( 1 - P '"' ) ^ 1 ) * '"'
% \end{macrocode}
+%
+% \begin{macrocode}
+ local Operator =
+ K ( 'Operator' , 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,
@@ -7335,56 +7672,61 @@
% distinguish the keywords with a Lua function. However, some keywords will be
% caught 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"
- }
+ local function Set ( list )
+ local set = { }
+ for _, l in ipairs ( list ) do set[l] = true end
+ return set
+ end
% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+ 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"
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+ 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} |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}
-local Identifier =
- C ( identifier ) /
- (
- function (s)
- if set_keywords[string.upper(s)] -- the keywords are case-insensitive in SQL
+ 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
- )
+ 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
@@ -7391,7 +7733,7 @@
% \paragraph{The strings of SQL}
%
% \begin{macrocode}
-local String = K ( 'String.Long' , "'" * ( 1 - P "'" ) ^ 1 * "'" )
+ local String = K ( 'String.Long' , "'" * ( 1 - P "'" ) ^ 1 * "'" )
% \end{macrocode}
%
% \bigskip
@@ -7402,16 +7744,16 @@
% catching} corresponding to the strings of the language.
%
% \begin{macrocode}
-local braces = Compute_braces ( "'" * ( 1 - P "'" ) ^ 1 * "'" )
-if piton.beamer then Beamer = Compute_Beamer ( 'sql' , braces ) end
+ local braces = Compute_braces ( "'" * ( 1 - P "'" ) ^ 1 * "'" )
+ if piton.beamer then Beamer = Compute_Beamer ( 'sql' , braces ) end
% \end{macrocode}
%
% \begin{macrocode}
-DetectedCommands = Compute_DetectedCommands ( 'sql' , braces )
+ DetectedCommands = Compute_DetectedCommands ( 'sql' , braces )
% \end{macrocode}
%
% \begin{macrocode}
-LPEG_cleaner['sql'] = Compute_LPEG_cleaner ( 'sql' , braces )
+ LPEG_cleaner['sql'] = Compute_LPEG_cleaner ( 'sql' , braces )
% \end{macrocode}
%
%
@@ -7421,18 +7763,18 @@
%
% We define different \textsc{lpeg} dealing with comments in the SQL listings.
% \begin{macrocode}
-local Comment =
- WithStyle ( 'Comment' ,
- Q "--" -- syntax of SQL92
- * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 ) -- $
- * ( EOL + -1 )
+ local Comment =
+ WithStyle ( 'Comment' ,
+ Q "--" -- syntax of SQL92
+ * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 ) -- $
+ * ( EOL + -1 )
-local LongComment =
- WithStyle ( 'Comment' ,
- Q "/*"
- * ( CommentMath + Q ( ( 1 - P "*/" - S "$\r" ) ^ 1 ) + EOL ) ^ 0
- * Q "*/"
- ) -- $
+ local LongComment =
+ WithStyle ( 'Comment' ,
+ Q "/*"
+ * ( CommentMath + Q ( ( 1 - P "*/" - S "$\r" ) ^ 1 ) + EOL ) ^ 0
+ * Q "*/"
+ ) -- $
% \end{macrocode}
%
%
@@ -7441,78 +7783,80 @@
% \paragraph{The main LPEG for the language SQL}
%
% \begin{macrocode}
-local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
+ local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
% \end{macrocode}
%
% \begin{macrocode}
-local TableField =
- K ( 'Name.Table' , identifier )
- * Q "."
- * K ( 'Name.Field' , identifier )
+ local TableField =
+ K ( 'Name.Table' , identifier )
+ * Q "."
+ * K ( 'Name.Field' , identifier )
-local OneField =
- (
- Q ( "(" * ( 1 - P ")" ) ^ 0 * ")" )
- +
- K ( 'Name.Table' , identifier )
- * Q "."
- * K ( 'Name.Field' , identifier )
- +
- K ( 'Name.Field' , identifier )
- )
- * (
- Space * LuaKeyword "AS" * Space * K ( 'Name.Field' , identifier )
- ) ^ -1
- * ( Space * ( LuaKeyword "ASC" + LuaKeyword "DESC" ) ) ^ -1
+ local OneField =
+ (
+ Q ( "(" * ( 1 - P ")" ) ^ 0 * ")" )
+ +
+ K ( 'Name.Table' , identifier )
+ * Q "."
+ * 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 OneTable =
+ K ( 'Name.Table' , identifier )
+ * (
+ Space
+ * LuaKeyword "AS"
+ * Space
+ * K ( 'Name.Table' , identifier )
+ ) ^ -1
-local WeCatchTableNames =
- LuaKeyword "FROM"
- * ( Space + EOL )
- * OneTable * ( SkipSpace * Q "," * SkipSpace * OneTable ) ^ 0
- + (
- LuaKeyword "JOIN" + LuaKeyword "INTO" + LuaKeyword "UPDATE"
- + LuaKeyword "TABLE"
- )
- * ( Space + EOL ) * OneTable
+ local WeCatchTableNames =
+ LuaKeyword "FROM"
+ * ( Space + EOL )
+ * OneTable * ( SkipSpace * Q "," * SkipSpace * OneTable ) ^ 0
+ + (
+ LuaKeyword "JOIN" + LuaKeyword "INTO" + LuaKeyword "UPDATE"
+ + LuaKeyword "TABLE"
+ )
+ * ( Space + EOL ) * OneTable
% \end{macrocode}
%
% \begin{macrocode}
-local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
+ local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
% \end{macrocode}
%
%
% First, the main loop :
% \begin{macrocode}
-local Main =
- Space
- + Tab
- + Escape + EscapeMath
- + CommentLaTeX
- + Beamer
- + DetectedCommands
- + Comment + LongComment
- + Delim
- + Operator
- + String
- + Punct
- + WeCatchTableNames
- + ( TableField + Identifier ) * ( Space + Operator + Punct + Delim + EOL + -1 )
- + Number
- + Word
+ local Main =
+ space ^ 0 * EOL
+ + Space
+ + Tab
+ + Escape + EscapeMath
+ + CommentLaTeX
+ + Beamer
+ + DetectedCommands
+ + Comment + LongComment
+ + Delim
+ + Operator
+ + String
+ + Punct
+ + WeCatchTableNames
+ + ( TableField + Identifier ) * ( Space + Operator + Punct + Delim + EOL + -1 )
+ + Number
+ + Word
% \end{macrocode}
%
+% \bigskip
% Here, we must not put |local|!
% \begin{macrocode}
-LPEG1['sql'] = Main ^ 0
+ LPEG1['sql'] = Main ^ 0
% \end{macrocode}
%
% \bigskip
@@ -7522,87 +7866,112 @@
% will be used as marker in order to delimit the argument of the command
% \texttt{\textbackslash @@\_begin\_line:}}.
% \begin{macrocode}
-LPEG2['sql'] =
- Ct (
- ( space ^ 0 * "\r" ) ^ -1
- * BeamerBeginEnvironments
- * Lc [[\@@_begin_line:]]
- * SpaceIndentation ^ 0
- * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0
- * -1
- * Lc [[\@@_end_line:]]
- )
+ LPEG2['sql'] =
+ Ct (
+ ( space ^ 0 * "\r" ) ^ -1
+ * BeamerBeginEnvironments
+ * Lc [[\@@_begin_line:]]
+ * SpaceIndentation ^ 0
+ * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0
+ * -1
+ * Lc [[\@@_end_line:]]
+ )
% \end{macrocode}
%
+% \bigskip
+% End of the Lua scope for the language SQL.
+% \begin{macrocode}
+end
+% \end{macrocode}
%
% \subsubsection{The language ``Minimal''}
%
+% We open a Lua local scope for the language ``|minimal|'' (of course, there
+% will be also global definitions).
% \begin{macrocode}
-local Punct = Q ( S ",:;!\\" )
+do
+% \end{macrocode}
+%
+% \begin{macrocode}
+ local Punct = Q ( S ",:;!\\" )
-local Comment =
- WithStyle ( 'Comment' ,
- Q "#"
- * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 -- $
- )
- * ( EOL + -1 )
+ local Comment =
+ WithStyle ( 'Comment' ,
+ Q "#"
+ * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 -- $
+ )
+ * ( EOL + -1 )
-local String =
- WithStyle ( 'String.Short' ,
- Q "\""
- * ( VisualSpace
- + Q ( ( P "\\\"" + 1 - S " \"" ) ^ 1 )
- ) ^ 0
- * Q "\""
- )
-
+ local String =
+ WithStyle ( 'String.Short' ,
+ Q "\""
+ * ( VisualSpace
+ + Q ( ( P "\\\"" + 1 - S " \"" ) ^ 1 )
+ ) ^ 0
+ * Q "\""
+ )
% \end{macrocode}
+%
+% \bigskip
% The argument of |Compute_braces| must be a pattern \emph{which does no
% catching} corresponding to the strings of the language.
% \begin{macrocode}
-local braces = Compute_braces ( P "\"" * ( P "\\\"" + 1 - P "\"" ) ^ 1 * "\"" )
+ local braces = Compute_braces ( P "\"" * ( P "\\\"" + 1 - P "\"" ) ^ 1 * "\"" )
-if piton.beamer then Beamer = Compute_Beamer ( 'minimal' , braces ) end
+ if piton.beamer then Beamer = Compute_Beamer ( 'minimal' , braces ) end
-DetectedCommands = Compute_DetectedCommands ( 'minimal' , braces )
+ DetectedCommands = Compute_DetectedCommands ( 'minimal' , braces )
-LPEG_cleaner['minimal'] = Compute_LPEG_cleaner ( 'minimal' , braces )
+ LPEG_cleaner['minimal'] = Compute_LPEG_cleaner ( 'minimal' , braces )
-local identifier = letter * alphanum ^ 0
+ local identifier = letter * alphanum ^ 0
-local Identifier = K ( 'Identifier.Internal' , identifier )
+ local Identifier = K ( 'Identifier.Internal' , identifier )
-local Delim = Q ( S "{[()]}" )
+ local Delim = Q ( S "{[()]}" )
-local Main =
- Space
- + Tab
- + Escape + EscapeMath
- + CommentLaTeX
- + Beamer
- + DetectedCommands
- + Comment
- + Delim
- + String
- + Punct
- + Identifier
- + Number
- + Word
+ local Main =
+ space ^ 0 * EOL
+ + Space
+ + Tab
+ + Escape + EscapeMath
+ + CommentLaTeX
+ + Beamer
+ + DetectedCommands
+ + Comment
+ + Delim
+ + String
+ + Punct
+ + Identifier
+ + Number
+ + Word
+% \end{macrocode}
+%
+% \bigskip
+% Here, we must not put |local|!
+% \begin{macrocode}
+ LPEG1['minimal'] = Main ^ 0
-LPEG1['minimal'] = Main ^ 0
-
-LPEG2['minimal'] =
- Ct (
- ( space ^ 0 * "\r" ) ^ -1
- * BeamerBeginEnvironments
- * Lc [[\@@_begin_line:]]
- * SpaceIndentation ^ 0
- * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0
- * -1
- * Lc [[\@@_end_line:]]
- )
-
+ LPEG2['minimal'] =
+ Ct (
+ ( space ^ 0 * "\r" ) ^ -1
+ * BeamerBeginEnvironments
+ * Lc [[\@@_begin_line:]]
+ * SpaceIndentation ^ 0
+ * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0
+ * -1
+ * Lc [[\@@_end_line:]]
+ )
+% \end{macrocode}
+%
+%
% \bigskip
+% End of the Lua scope for the language ``|minimal|''.
+% \begin{macrocode}
+end
+% \end{macrocode}
+%
+% \bigskip
% \subsubsection{The function Parse}
%
% \medskip
@@ -7673,7 +8042,8 @@
% That function merely reads the file (between |first_line| and |last_line|) and
% then apply the function~|Parse| to the resulting Lua string.
% \begin{macrocode}
-function piton.ParseFile ( language , name , first_line , last_line , split )
+function piton.ParseFile
+ ( lang , name , first_line , last_line , splittable , split )
local s = ''
local i = 0
for line in io.lines ( name ) do
@@ -7696,15 +8066,21 @@
end
end
if split == 1 then
- piton.GobbleSplitParse ( language , 0 , s )
+ piton.RetrieveGobbleSplitParse ( lang , 0 , splittable , s )
else
- sprintL3 [[ \bool_if:NT \g_@@_footnote_bool \savenotes \vtop \bgroup ]]
- piton.Parse ( language , s )
- sprintL3
- [[\vspace{2.5pt}\egroup\bool_if:NT\g_@@_footnote_bool\endsavenotes\par]]
+ piton.RetrieveGobbleParse ( lang , 0 , splittable , s )
end
end
% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+function piton.RetrieveGobbleParse ( lang , n , splittable , code )
+ local s
+ s = ( ( P " " ^ 0 * "\r" ) ^ -1 * C ( P ( 1 ) ^ 0 ) * -1 ) : match ( code )
+ piton.GobbleParse ( lang , n , splittable , s )
+end
+% \end{macrocode}
%
% \bigskip
% \subsubsection{Two variants of the function Parse with integrated preprocessors}
@@ -7730,8 +8106,16 @@
% Be careful: we have to write |[[\@@_breakable_space: ]]| with a space after
% the name of the LaTeX command |\@@_breakable_space:|.
% \begin{macrocode}
- local s = ( Cs ( ( P [[\@@_breakable_space: ]] / ' ' + 1 ) ^ 0 ) )
- : match ( code )
+ local s
+ s = ( Cs ( ( P [[\@@_breakable_space: ]] / ' ' + 1 ) ^ 0 ) )
+ : match ( code )
+% \end{macrocode}
+% Remember that |\@@_leading_space:| does not create a space, only an
+% incrementation of the counter |\g_@@_indentation_int|. That's why we don't
+% replace it by a space...
+% \begin{macrocode}
+ s = ( Cs ( ( P [[\@@_leading_space: ]] / '' + 1 ) ^ 0 ) )
+ : match ( s )
return piton.Parse ( lang , s )
end
% \end{macrocode}
@@ -7820,7 +8204,8 @@
end
% \end{macrocode}
% We have a second test |if n == 0| because the, even if the key like
-% |auto-gobble| is in force, it's possible that, in fact, there is no space to gobble...
+% |auto-gobble| is in force, it's possible that, in fact, there is no space to
+% gobble...
% \begin{macrocode}
if n == 0 then
return code
@@ -7846,33 +8231,29 @@
%
% \bigskip
% In the following code, |n| is the value of |\l_@@_gobble_int|.
+%
+% |splittable| is the value of |\l_@@_splittable_int|.
% \begin{macrocode}
-function piton.GobbleParse ( lang , n , code )
+function piton.GobbleParse ( lang , n , splittable , code )
+ piton.ComputeLinesStatus ( code , splittable )
piton.last_code = gobble ( n , code )
piton.last_language = lang
% \end{macrocode}
% We count the number of lines of the informatic code. The result will be stored
-% by Lua in |\l_@@_nb_lines_int|. That information will be used to allow or
-% disallow page breaks (when |splittable| is in force).
+% by Lua in |\l_@@_nb_lines_int|.
% \begin{macrocode}
piton.CountLines ( piton.last_code )
sprintL3 [[ \bool_if:NT \g_@@_footnote_bool \savenotes ]]
-% \end{macrocode}
-% We begin a |\vtop| for an non-splittable block of lines.
-% \begin{macrocode}
- sprintL3 [[ \vtop \bgroup ]]
piton.Parse ( lang , piton.last_code )
% \end{macrocode}
-% We close the latest opened |\vtop| with the following |\egroup|. Be careful:
-% that |\vtop| is \emph{not} necessarily the |\vtop| opened two lines above
-% because the commands |\@@_newline:| inserted by Lua may open and close
-% |\vtop|s and start and finish paragraphs (when |splittable| is in force).
+%
% \begin{macrocode}
- sprintL3 [[ \vspace{2.5pt} \egroup ]]
+ sprintL3 [[ \vspace{2.5pt} ]]
sprintL3 [[ \bool_if:NT \g_@@_footnote_bool \endsavenotes ]]
% \end{macrocode}
-% We finish the paragraph (each block of non-splittable lines of code is
-% composed in a |\vtop| inserted in a paragraph).
+% We finish the paragraph (each line of the listing is composed in a TeX box
+% --- with potentially several lines when |break-lines-in-Piton| is in force ---
+% put alone in a paragraph.
% \begin{macrocode}
sprintL3 [[ \par ]]
% \end{macrocode}
@@ -7900,35 +8281,49 @@
% argument |n| corresponds to the value of the key |gobble| (number of spaces to
% gobble).
% \begin{macrocode}
-function piton.GobbleSplitParse ( lang , n , code )
- P { "E" ,
- E = ( V "F"
- * ( P " " ^ 0 * "\r"
- / ( function ( x ) sprintL3 [[ \@@_incr_visual_line: ]] end )
- ) ^ 1
- / ( function ( x )
- sprintL3 ( piton.string_between_chunks )
- end )
- ) ^ 0 * V "F" ,
+function piton.GobbleSplitParse ( lang , n , splittable , code )
+ local chunks
+ chunks =
+ (
+ Ct (
+ (
+ P " " ^ 0 * "\r"
+ +
+ C ( ( ( 1 - P "\r" ) ^ 1 * "\r" - ( P " " ^ 0 * "\r" ) ) ^ 1 )
+ ) ^ 0
+ )
+ ) : match ( gobble ( n , code ) )
+ sprintL3 ( [[ \begingroup ]] )
+ sprintL3
+ (
+ [[ \PitonOptions { split-on-empty-lines=false, gobble = 0, ]]
+ .. "language = " .. lang .. ","
+ .. "splittable = " .. splittable .. "}"
+ )
+ for k , v in pairs ( chunks ) do
+ if k > 1 then
+ sprintL3 ( [[\l_@@_split_separation_tl ]] )
+ end
+ tex.sprint
+ (
+ [[\begin{]] .. piton.env_used_by_split .. "}\r"
+ .. v
+ .. [[\end{]] .. piton.env_used_by_split .. "}"
+ )
+ end
+ sprintL3 ( [[ \endgroup ]] )
+end
% \end{macrocode}
-% The non-terminal |F| corresponds to a chunk of the informatic code.
+%
+% \bigskip
% \begin{macrocode}
- F = C ( V "G" ^ 0 )
-% \end{macrocode}
-% The second argument of |piton.GobbleSplitParse| is the argument |gobble|: we put
-% that argument to~$0$ because we will have gobbled previously the whole argument
-% |code| (see below).
-% \begin{macrocode}
- / ( function ( x ) piton.GobbleParse ( lang , 0 , x ) end ) ,
-% \end{macrocode}
-% The non-terminal |G| corresponds to a non-empty line of code.
-% \begin{macrocode}
- G = ( 1 - P "\r" ) ^ 0 * "\r" - ( P " " ^ 0 * "\r" )
- + ( ( 1 - P "\r" ) ^ 1 * -1 - ( P " " ^ 0 * -1 ) )
- } : match ( gobble ( n , code ) )
+function piton.RetrieveGobbleSplitParse ( lang , n , splittable , code )
+ local s
+ s = ( ( P " " ^ 0 * "\r" ) ^ -1 * C ( P ( 1 ) ^ 0 ) * -1 ) : match ( code )
+ piton.GobbleSplitParse ( lang , n , splittable , s )
end
% \end{macrocode}
-%
+%
% \bigskip
% The following Lua string will be inserted between the chunks of code created
% when the key |split-on-empty-lines| is in force. It's used only once: you have
@@ -7953,18 +8348,19 @@
%
%
% \bigskip
+%
% \subsubsection{To count the number of lines}
%
-% \medskip
-% The following function is only used once (in |piton.GobbleParse|). We have
-% written an autonomous function only for legibility. The number of lines of the
-% code will be stored in |\l_@@_nb_lines_int| and will be used to allow or
-% disallow line breaks (when |splittable| is in force).
% \begin{macrocode}
function piton.CountLines ( code )
- local count = 0
- for i in code : gmatch ( "\r" ) do count = count + 1 end
- sprintL3 ( string.format ( [[ \int_set:Nn \l_@@_nb_lines_int { % i } ]] , count ) )
+ local count = 0
+ count =
+ ( Ct ( ( ( 1 - P "\r" ) ^ 0 * C "\r" ) ^ 0
+ * ( ( 1 - P "\r" ) ^ 1 * Cc "\r" ) ^ -1
+ * -1
+ ) / table.getn
+ ) : match ( code )
+ sprintL3 ( string.format ( [[ \int_set:Nn \l_@@_nb_lines_int { %i } ]] , count ) )
end
% \end{macrocode}
%
@@ -7984,7 +8380,7 @@
) / table.getn
) : match ( code )
sprintL3
- ( string.format ( [[ \int_set:Nn \l_@@_nb_non_empty_lines_int { % i } ]] , count ) )
+ ( string.format ( [[ \int_set:Nn \l_@@_nb_non_empty_lines_int { %i } ]] , count ) )
end
% \end{macrocode}
%
@@ -7994,7 +8390,7 @@
local count = 0
for line in io.lines ( name ) do count = count + 1 end
sprintL3
- ( string.format ( [[ \int_set:Nn \l_@@_nb_lines_int { %i } ]], count))
+ ( string.format ( [[ \int_set:Nn \l_@@_nb_lines_int { %i } ]], count ) )
end
% \end{macrocode}
%
@@ -8050,6 +8446,143 @@
% \end{macrocode}
%
% \bigskip
+% \subsubsection{To determine the empty lines of the listings}
+%
+% Despite its name, the Lua function |ComputeLinesStatus| computes
+% |piton.lines_status| but also |piton.empty_lines|.
+%
+% \medskip
+% In |piton.empty_lines|, a line will have the number 0 if it's a empty line (in
+% fact a blank line, with only spaces) and 1 elsewhere.
+%
+% \medskip
+% In |piton.lines_status|, each line will have a status with regard the
+% breaking points allowed (for the changes of pages).
+% \begin{itemize}
+% \item 0 if the line is empty and a page break is allowed;
+% \item 1 if the line is not empty but a page break is allowed after that line;
+% \item 2 if a page break is \emph{not} allowed after that line (empty or not empty).
+% \end{itemize}
+%
+% \medskip
+% |splittable| is the value of |\l_@@_splittable_int|.
+% However, if |splittable-on-empty-lines| is in force, |splittable| is the
+% opposite of |\l_@@_splittable_int|.
+% \begin{macrocode}
+function piton.ComputeLinesStatus ( code , splittable )
+% \end{macrocode}
+% The lines in the listings which correspond to the beginning or the end of an
+% environment of Beamer (eg. |\begin{uncoverenv}|) must be retrieved (those
+% lines have \emph{no} number and therefore, \emph{no} status).
+% \begin{macrocode}
+ local lpeg_line_beamer
+ if piton.beamer then
+ lpeg_line_beamer =
+ space ^ 0
+ * P "\\begin{" * piton.BeamerEnvironments * "}"
+ * ( "<" * ( 1 - P ">" ) ^ 0 * ">" ) ^ -1
+ +
+ space ^ 0
+ * P "\\end{" * piton.BeamerEnvironments * "}"
+ else
+ lpeg_line_beamer = P ( false )
+ end
+% \end{macrocode}
+% \begin{macrocode}
+ local lpeg_empty_lines =
+ Ct (
+ ( lpeg_line_beamer * "\r"
+ +
+ P " " ^ 0 * "\r" * Cc ( 0 )
+ +
+ ( 1 - P "\r" ) ^ 0 * "\r" * Cc ( 1 )
+ ) ^ 0
+ *
+ ( lpeg_line_beamer + ( 1 - P "\r" ) ^ 1 * Cc ( 1 ) ) ^ -1
+ )
+ * -1
+% \end{macrocode}
+% \begin{macrocode}
+ local lpeg_all_lines =
+ Ct (
+ ( lpeg_line_beamer * "\r"
+ +
+ ( 1 - P "\r" ) ^ 0 * "\r" * Cc ( 1 )
+ ) ^ 0
+ *
+ ( lpeg_line_beamer + ( 1 - P "\r" ) ^ 1 * Cc ( 1 ) ) ^ -1
+ )
+ * -1
+% \end{macrocode}
+% We begin with the computation of |piton.empty_lines|. It will be used in
+% conjonction with |line-numbers|.
+% \begin{macrocode}
+ piton.empty_lines = lpeg_empty_lines : match ( code )
+% \end{macrocode}
+%
+% Now, we compute |piton.lines_status|. It will be used in conjonction with
+% |splittable| and |splittable-on-empty-lines|.
+%
+% Now, we will take into account the current value of |\l_@@_splittable_int|
+% (provided by the \emph{absolute value} of the argument |splittable|).
+% \begin{macrocode}
+ local lines_status
+ local s = splittable
+ if splittable < 0 then s = - splittable end
+% \end{macrocode}
+%
+% \begin{macrocode}
+ if splittable > 0 then
+ lines_status = lpeg_all_lines : match ( code )
+ else
+% \end{macrocode}
+% Here, we should try to copy |piton.empty_lines| but it's not easy.
+% \begin{macrocode}
+ lines_status = lpeg_empty_lines : match ( code )
+ for i , x in ipairs ( lines_status ) do
+ if x == 0 then
+ for j = 1 , s - 1 do
+ if i + j > #lines_status then break end
+ if lines_status[i+j] == 0 then break end
+ lines_status[i+j] = 2
+ end
+ for j = 1 , s - 1 do
+ if i - j - 1 == 0 then break end
+ if lines_status[i-j-1] == 0 then break end
+ lines_status[i-j-1] = 2
+ end
+ end
+ end
+ end
+% \end{macrocode}
+%
+% In all cases (whatever is the value of |splittable-on-empty-lines|) we have to
+% deal with both extremities of the listing to format.
+%
+% First from the beginning of the code.
+% \begin{macrocode}
+ for j = 1 , s - 1 do
+ if j > #lines_status then break end
+ if lines_status[j] == 0 then break end
+ lines_status[j] = 2
+ end
+% \end{macrocode}
+% Now, from the end of the code.
+% \begin{macrocode}
+ for j = 1 , s - 1 do
+ if #lines_status - j == 0 then break end
+ if lines_status[#lines_status - j] == 0 then break end
+ lines_status[#lines_status - j] = 2
+ end
+% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+ piton.lines_status = lines_status
+end
+% \end{macrocode}
+%
+% \bigskip
% \subsubsection{To create new languages with the syntax of listings}
%
% \begin{macrocode}
@@ -8353,7 +8886,7 @@
central_pattern = P ( arg3 .. arg3 ) + central_pattern
end
if arg1 == "m"
- then prefix = lpeg.B ( 1 - letter - ")" - "]" )
+ then prefix = B ( 1 - letter - ")" - "]" )
else prefix = P ( true )
end
% \end{macrocode}
@@ -8503,7 +9036,8 @@
%
% \begin{macrocode}
local Main =
- Space
+ space ^ 0 * EOL
+ + Space
+ Tab
+ Escape + EscapeMath
+ CommentLaTeX
@@ -8526,6 +9060,8 @@
%
% The \textsc{lpeg} |LPEG1[lang]| is used to reformat small elements, for
% example the arguments of the ``detected commands''.
+%
+% Of course, here, we must not put |local|!
% \begin{macrocode}
LPEG1[lang] = Main ^ 0
% \end{macrocode}
@@ -8617,6 +9153,16 @@
%
% \verb|https://github.com/fpantigny/piton|
%
+% \subsection*{Changes between versions 3.1 and 4.0}
+%
+% This version introduces an incompatibility: the syntax for the relative and
+% absolute paths in |\PitonInputFile| and the key |path| has been changed to be
+% conform to usual conventions. An temporary key |old-PitonInputFile|, available
+% at load-time, has been added for backward compatibility.
+%
+% New keys |font-command|, |splittable-on-empty-lines| and |env-used-by-split|.
+%
+%
% \subsection*{Changes between versions 3.0 and 3.1}
%
% Keys |line-numbers/format|, |detected-beamer-commands| and
Modified: trunk/Master/texmf-dist/tex/lualatex/piton/piton.lua
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/piton/piton.lua 2024-09-22 20:22:16 UTC (rev 72350)
+++ trunk/Master/texmf-dist/tex/lualatex/piton/piton.lua 2024-09-22 20:22:25 UTC (rev 72351)
@@ -20,7 +20,7 @@
-- -------------------------------------------
--
-- This file is part of the LuaLaTeX package 'piton'.
-piton_version = "3.1b" -- 2024/08/29
+piton_version = "4.0" -- 2024/09/22
@@ -32,7 +32,7 @@
end
local P, S, V, C, Ct, Cc = lpeg.P, lpeg.S, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Cc
local Cs , Cg , Cmt , Cb = lpeg.Cs, lpeg.Cg , lpeg.Cmt , lpeg.Cb
-local R = lpeg.R
+local B , R = lpeg.B , lpeg.R
local function Q ( pattern )
return Ct ( Cc ( luatexbase.catcodetables.CatcodeTableOther ) * C ( pattern ) )
end
@@ -120,7 +120,7 @@
local Punct = Q ( S ".,:;!" )
local Tab = "\t" * Lc [[\__piton_tab:]]
-local SpaceIndentation = Lc [[\__piton_an_indentation_space:]] * Q " "
+local SpaceIndentation = Lc [[\__piton_leading_space:]] * Q " "
local Delim = Q ( S "[({})]" )
local VisualSpace = space * Lc [[\l__piton_space_tl]]
local strict_braces =
@@ -146,7 +146,7 @@
end
local function Compute_DetectedCommands ( lang , braces ) return
Ct ( Cc "Open"
- * C ( piton.DetectedCommands * P "{" )
+ * C ( piton.DetectedCommands * space ^ 0 * P "{" )
* Cc "}"
)
* ( braces
@@ -186,7 +186,7 @@
* "\r"
) ^ 0
local function Compute_Beamer ( lang , braces )
- local lpeg = L ( P "\\pause" * ( "[" * ( 1 - P "]" ) ^ 0 * "]" ) ^ -1 )
+ local lpeg = L ( P [[\pause]] * ( "[" * ( 1 - P "]" ) ^ 0 * "]" ) ^ -1 )
lpeg = lpeg +
Ct ( Cc "Open"
* C ( piton.BeamerCommands
@@ -200,7 +200,7 @@
* "}"
* Ct ( Cc "Close" )
lpeg = lpeg +
- L ( P "\\alt" * "<" * ( 1 - P ">" ) ^ 0 * ">" * "{" )
+ L ( P [[\alt]] * "<" * ( 1 - P ">" ) ^ 0 * ">" * "{" )
* ( braces /
( function ( s ) if s ~= '' then return LPEG1[lang] : match ( s ) end end ) )
* L ( P "}{" )
@@ -208,7 +208,7 @@
( function ( s ) if s ~= '' then return LPEG1[lang] : match ( s ) end end ) )
* L ( P "}" )
lpeg = lpeg +
- L ( ( P "\\temporal" ) * "<" * ( 1 - P ">" ) ^ 0 * ">" * "{" )
+ L ( ( P [[\temporal]] ) * "<" * ( 1 - P ">" ) ^ 0 * ">" * "{" )
* ( braces
/ ( function ( s )
if s ~= '' then return LPEG1[lang] : match ( s ) end end ) )
@@ -246,906 +246,962 @@
local CommentMath =
P "$" * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1 ) * P "$" -- $
local PromptHastyDetection =
- ( # ( P ">>>" + "..." ) * Lc '\\__piton_prompt:' ) ^ -1
+ ( # ( P ">>>" + "..." ) * Lc [[\__piton_prompt:]] ) ^ -1
local Prompt = K ( 'Prompt' , ( ( P ">>>" + "..." ) * P " " ^ -1 ) ^ -1 )
-local EOL_without_space_indentation =
+local EOL =
P "\r"
*
(
- ( space ^ 0 * -1 )
+ space ^ 0 * -1
+
Ct (
Cc "EOL"
*
- Ct (
- Lc [[\__piton_end_line:]]
+ Ct ( Lc [[\__piton_end_line:]]
* BeamerEndEnvironments
- * BeamerBeginEnvironments
- * PromptHastyDetection
- * Lc [[\__piton_newline:\__piton_begin_line:]]
- * Prompt
+ *
+ (
+ -1
+ +
+ BeamerBeginEnvironments
+ * PromptHastyDetection
+ * Lc [[\__piton_newline:\__piton_begin_line:]]
+ * Prompt
+ )
)
)
)
-local EOL = EOL_without_space_indentation
* ( SpaceIndentation ^ 0 * # ( 1 - S " \r" ) ) ^ -1
local CommentLaTeX =
- P(piton.comment_latex)
- * Lc "{\\PitonStyle{Comment.LaTeX}{\\ignorespaces"
+ P ( piton.comment_latex )
+ * Lc [[{\PitonStyle{Comment.LaTeX}{\ignorespaces]]
* L ( ( 1 - P "\r" ) ^ 0 )
- * Lc "}}"
+ * Lc [[}}]]
* ( EOL + -1 )
-local Operator =
- K ( 'Operator' ,
- P "!=" + "<>" + "==" + "<<" + ">>" + "<=" + ">=" + ":=" + "//" + "**"
- + S "-~+/*%=<>&.@|" )
+do
+ local Operator =
+ K ( 'Operator' ,
+ P "!=" + "<>" + "==" + "<<" + ">>" + "<=" + ">=" + ":=" + "//" + "**"
+ + S "-~+/*%=<>&.@|" )
-local OperatorWord =
- K ( 'Operator.Word' , P "in" + "is" + "and" + "or" + "not" )
-local For = K ( 'Keyword' , P "for" )
- * Space
- * Identifier
- * Space
- * K ( 'Keyword' , P "in" )
+ local OperatorWord =
+ K ( 'Operator.Word' , P "in" + "is" + "and" + "or" + "not" )
+ local For = K ( 'Keyword' , P "for" )
+ * Space
+ * Identifier
+ * Space
+ * K ( 'Keyword' , P "in" )
-local Keyword =
- K ( 'Keyword' ,
- P "as" + "assert" + "break" + "case" + "class" + "continue" + "def" +
- "del" + "elif" + "else" + "except" + "exec" + "finally" + "for" + "from" +
- "global" + "if" + "import" + "lambda" + "non local" + "pass" + "return" +
- "try" + "while" + "with" + "yield" + "yield from" )
- + K ( 'Keyword.Constant' , P "True" + "False" + "None" )
+ local Keyword =
+ K ( 'Keyword' ,
+ P "as" + "assert" + "break" + "case" + "class" + "continue" + "def" +
+ "del" + "elif" + "else" + "except" + "exec" + "finally" + "for" + "from" +
+ "global" + "if" + "import" + "lambda" + "non local" + "pass" + "return" +
+ "try" + "while" + "with" + "yield" + "yield from" )
+ + K ( 'Keyword.Constant' , P "True" + "False" + "None" )
-local Builtin =
- K ( 'Name.Builtin' ,
- P "__import__" + "abs" + "all" + "any" + "bin" + "bool" + "bytearray" +
- "bytes" + "chr" + "classmethod" + "compile" + "complex" + "delattr" +
- "dict" + "dir" + "divmod" + "enumerate" + "eval" + "filter" + "float" +
- "format" + "frozenset" + "getattr" + "globals" + "hasattr" + "hash" +
- "hex" + "id" + "input" + "int" + "isinstance" + "issubclass" + "iter" +
- "len" + "list" + "locals" + "map" + "max" + "memoryview" + "min" + "next"
- + "object" + "oct" + "open" + "ord" + "pow" + "print" + "property" +
- "range" + "repr" + "reversed" + "round" + "set" + "setattr" + "slice" +
- "sorted" + "staticmethod" + "str" + "sum" + "super" + "tuple" + "type" +
- "vars" + "zip" )
+ local Builtin =
+ K ( 'Name.Builtin' ,
+ P "__import__" + "abs" + "all" + "any" + "bin" + "bool" + "bytearray" +
+ "bytes" + "chr" + "classmethod" + "compile" + "complex" + "delattr" +
+ "dict" + "dir" + "divmod" + "enumerate" + "eval" + "filter" + "float" +
+ "format" + "frozenset" + "getattr" + "globals" + "hasattr" + "hash" +
+ "hex" + "id" + "input" + "int" + "isinstance" + "issubclass" + "iter" +
+ "len" + "list" + "locals" + "map" + "max" + "memoryview" + "min" + "next"
+ + "object" + "oct" + "open" + "ord" + "pow" + "print" + "property" +
+ "range" + "repr" + "reversed" + "round" + "set" + "setattr" + "slice" +
+ "sorted" + "staticmethod" + "str" + "sum" + "super" + "tuple" + "type" +
+ "vars" + "zip" )
-local Exception =
- K ( 'Exception' ,
- P "ArithmeticError" + "AssertionError" + "AttributeError" +
- "BaseException" + "BufferError" + "BytesWarning" + "DeprecationWarning" +
- "EOFError" + "EnvironmentError" + "Exception" + "FloatingPointError" +
- "FutureWarning" + "GeneratorExit" + "IOError" + "ImportError" +
- "ImportWarning" + "IndentationError" + "IndexError" + "KeyError" +
- "KeyboardInterrupt" + "LookupError" + "MemoryError" + "NameError" +
- "NotImplementedError" + "OSError" + "OverflowError" +
- "PendingDeprecationWarning" + "ReferenceError" + "ResourceWarning" +
- "RuntimeError" + "RuntimeWarning" + "StopIteration" + "SyntaxError" +
- "SyntaxWarning" + "SystemError" + "SystemExit" + "TabError" + "TypeError"
- + "UnboundLocalError" + "UnicodeDecodeError" + "UnicodeEncodeError" +
- "UnicodeError" + "UnicodeTranslateError" + "UnicodeWarning" +
- "UserWarning" + "ValueError" + "VMSError" + "Warning" + "WindowsError" +
- "ZeroDivisionError" + "BlockingIOError" + "ChildProcessError" +
- "ConnectionError" + "BrokenPipeError" + "ConnectionAbortedError" +
- "ConnectionRefusedError" + "ConnectionResetError" + "FileExistsError" +
- "FileNotFoundError" + "InterruptedError" + "IsADirectoryError" +
- "NotADirectoryError" + "PermissionError" + "ProcessLookupError" +
- "TimeoutError" + "StopAsyncIteration" + "ModuleNotFoundError" +
- "RecursionError" )
+ local Exception =
+ K ( 'Exception' ,
+ P "ArithmeticError" + "AssertionError" + "AttributeError" +
+ "BaseException" + "BufferError" + "BytesWarning" + "DeprecationWarning" +
+ "EOFError" + "EnvironmentError" + "Exception" + "FloatingPointError" +
+ "FutureWarning" + "GeneratorExit" + "IOError" + "ImportError" +
+ "ImportWarning" + "IndentationError" + "IndexError" + "KeyError" +
+ "KeyboardInterrupt" + "LookupError" + "MemoryError" + "NameError" +
+ "NotImplementedError" + "OSError" + "OverflowError" +
+ "PendingDeprecationWarning" + "ReferenceError" + "ResourceWarning" +
+ "RuntimeError" + "RuntimeWarning" + "StopIteration" + "SyntaxError" +
+ "SyntaxWarning" + "SystemError" + "SystemExit" + "TabError" + "TypeError"
+ + "UnboundLocalError" + "UnicodeDecodeError" + "UnicodeEncodeError" +
+ "UnicodeError" + "UnicodeTranslateError" + "UnicodeWarning" +
+ "UserWarning" + "ValueError" + "VMSError" + "Warning" + "WindowsError" +
+ "ZeroDivisionError" + "BlockingIOError" + "ChildProcessError" +
+ "ConnectionError" + "BrokenPipeError" + "ConnectionAbortedError" +
+ "ConnectionRefusedError" + "ConnectionResetError" + "FileExistsError" +
+ "FileNotFoundError" + "InterruptedError" + "IsADirectoryError" +
+ "NotADirectoryError" + "PermissionError" + "ProcessLookupError" +
+ "TimeoutError" + "StopAsyncIteration" + "ModuleNotFoundError" +
+ "RecursionError" )
-local RaiseException = K ( 'Keyword' , P "raise" ) * SkipSpace * Exception * Q "("
+ local RaiseException = K ( 'Keyword' , P "raise" ) * SkipSpace * Exception * Q "("
+ local Decorator = K ( 'Name.Decorator' , P "@" * letter ^ 1 )
+ local DefClass =
+ K ( 'Keyword' , "class" ) * Space * K ( 'Name.Class' , identifier )
+ local ImportAs =
+ K ( 'Keyword' , "import" )
+ * Space
+ * K ( 'Name.Namespace' , identifier * ( "." * identifier ) ^ 0 )
+ * (
+ ( Space * K ( 'Keyword' , "as" ) * Space
+ * K ( 'Name.Namespace' , identifier ) )
+ +
+ ( SkipSpace * Q "," * SkipSpace
+ * K ( 'Name.Namespace' , identifier ) ) ^ 0
+ )
+ local FromImport =
+ K ( 'Keyword' , "from" )
+ * Space * K ( 'Name.Namespace' , identifier )
+ * Space * K ( 'Keyword' , "import" )
+ local PercentInterpol =
+ K ( 'String.Interpol' ,
+ P "%"
+ * ( "(" * alphanum ^ 1 * ")" ) ^ -1
+ * ( S "-#0 +" ) ^ 0
+ * ( digit ^ 1 + "*" ) ^ -1
+ * ( "." * ( digit ^ 1 + "*" ) ) ^ -1
+ * ( S "HlL" ) ^ -1
+ * S "sdfFeExXorgiGauc%"
+ )
+ local SingleShortString =
+ WithStyle ( 'String.Short' ,
+ Q ( P "f'" + "F'" )
+ * (
+ K ( 'String.Interpol' , "{" )
+ * K ( 'Interpol.Inside' , ( 1 - S "}':" ) ^ 0 )
+ * Q ( P ":" * ( 1 - S "}:'" ) ^ 0 ) ^ -1
+ * K ( 'String.Interpol' , "}" )
+ +
+ VisualSpace
+ +
+ Q ( ( P "\\'" + "\\\\" + "{{" + "}}" + 1 - S " {}'" ) ^ 1 )
+ ) ^ 0
+ * Q "'"
+ +
+ Q ( P "'" + "r'" + "R'" )
+ * ( Q ( ( P "\\'" + "\\\\" + 1 - S " '\r%" ) ^ 1 )
+ + VisualSpace
+ + PercentInterpol
+ + Q "%"
+ ) ^ 0
+ * Q "'" )
+ local DoubleShortString =
+ WithStyle ( 'String.Short' ,
+ Q ( P "f\"" + "F\"" )
+ * (
+ K ( 'String.Interpol' , "{" )
+ * K ( 'Interpol.Inside' , ( 1 - S "}\":" ) ^ 0 )
+ * ( K ( 'String.Interpol' , ":" ) * Q ( (1 - S "}:\"") ^ 0 ) ) ^ -1
+ * K ( 'String.Interpol' , "}" )
+ +
+ VisualSpace
+ +
+ Q ( ( P "\\\"" + "\\\\" + "{{" + "}}" + 1 - S " {}\"" ) ^ 1 )
+ ) ^ 0
+ * Q "\""
+ +
+ Q ( P "\"" + "r\"" + "R\"" )
+ * ( Q ( ( P "\\\"" + "\\\\" + 1 - S " \"\r%" ) ^ 1 )
+ + VisualSpace
+ + PercentInterpol
+ + Q "%"
+ ) ^ 0
+ * Q "\"" )
-local Decorator = K ( 'Name.Decorator' , P "@" * letter ^ 1 )
-local DefClass =
- K ( 'Keyword' , "class" ) * Space * K ( 'Name.Class' , identifier )
-local ImportAs =
- K ( 'Keyword' , "import" )
- * Space
- * K ( 'Name.Namespace' , identifier * ( "." * identifier ) ^ 0 )
- * (
- ( Space * K ( 'Keyword' , "as" ) * Space
- * K ( 'Name.Namespace' , identifier ) )
+ local ShortString = SingleShortString + DoubleShortString
+ local braces =
+ Compute_braces
+ (
+ ( P "\"" + "r\"" + "R\"" + "f\"" + "F\"" )
+ * ( P "\\\"" + 1 - S "\"" ) ^ 0 * "\""
+
- ( SkipSpace * Q "," * SkipSpace
- * K ( 'Name.Namespace' , identifier ) ) ^ 0
+ ( P '\'' + 'r\'' + 'R\'' + 'f\'' + 'F\'' )
+ * ( P '\\\'' + 1 - S '\'' ) ^ 0 * '\''
)
-local FromImport =
- K ( 'Keyword' , "from" )
- * Space * K ( 'Name.Namespace' , identifier )
- * Space * K ( 'Keyword' , "import" )
-local PercentInterpol =
- K ( 'String.Interpol' ,
- P "%"
- * ( "(" * alphanum ^ 1 * ")" ) ^ -1
- * ( S "-#0 +" ) ^ 0
- * ( digit ^ 1 + "*" ) ^ -1
- * ( "." * ( digit ^ 1 + "*" ) ) ^ -1
- * ( S "HlL" ) ^ -1
- * S "sdfFeExXorgiGauc%"
+ if piton.beamer then Beamer = Compute_Beamer ( 'python' , braces ) end
+ DetectedCommands = Compute_DetectedCommands ( 'python' , braces )
+ LPEG_cleaner['python'] = Compute_LPEG_cleaner ( 'python' , braces )
+ local SingleLongString =
+ WithStyle ( 'String.Long' ,
+ ( Q ( S "fF" * P "'''" )
+ * (
+ K ( 'String.Interpol' , "{" )
+ * K ( 'Interpol.Inside' , ( 1 - S "}:\r" - "'''" ) ^ 0 )
+ * Q ( P ":" * (1 - S "}:\r" - "'''" ) ^ 0 ) ^ -1
+ * K ( 'String.Interpol' , "}" )
+ +
+ Q ( ( 1 - P "'''" - S "{}'\r" ) ^ 1 )
+ +
+ EOL
+ ) ^ 0
+ +
+ Q ( ( S "rR" ) ^ -1 * "'''" )
+ * (
+ Q ( ( 1 - P "'''" - S "\r%" ) ^ 1 )
+ +
+ PercentInterpol
+ +
+ P "%"
+ +
+ EOL
+ ) ^ 0
+ )
+ * Q "'''" )
+ local DoubleLongString =
+ WithStyle ( 'String.Long' ,
+ (
+ Q ( S "fF" * "\"\"\"" )
+ * (
+ K ( 'String.Interpol', "{" )
+ * K ( 'Interpol.Inside' , ( 1 - S "}:\r" - "\"\"\"" ) ^ 0 )
+ * Q ( ":" * (1 - S "}:\r" - "\"\"\"" ) ^ 0 ) ^ -1
+ * K ( 'String.Interpol' , "}" )
+ +
+ Q ( ( 1 - S "{}\"\r" - "\"\"\"" ) ^ 1 )
+ +
+ EOL
+ ) ^ 0
+ +
+ Q ( S "rR" ^ -1 * "\"\"\"" )
+ * (
+ Q ( ( 1 - P "\"\"\"" - S "%\r" ) ^ 1 )
+ +
+ PercentInterpol
+ +
+ P "%"
+ +
+ EOL
+ ) ^ 0
+ )
+ * Q "\"\"\""
)
-local SingleShortString =
- WithStyle ( 'String.Short' ,
- Q ( P "f'" + "F'" )
- * (
- K ( 'String.Interpol' , "{" )
- * K ( 'Interpol.Inside' , ( 1 - S "}':" ) ^ 0 )
- * Q ( P ":" * ( 1 - S "}:'" ) ^ 0 ) ^ -1
- * K ( 'String.Interpol' , "}" )
- +
- VisualSpace
- +
- Q ( ( P "\\'" + "{{" + "}}" + 1 - S " {}'" ) ^ 1 )
- ) ^ 0
- * Q "'"
- +
- Q ( P "'" + "r'" + "R'" )
- * ( Q ( ( P "\\'" + 1 - S " '\r%" ) ^ 1 )
- + VisualSpace
- + PercentInterpol
- + Q "%"
- ) ^ 0
- * Q "'" )
-
-local DoubleShortString =
- WithStyle ( 'String.Short' ,
- Q ( P "f\"" + "F\"" )
- * (
- K ( 'String.Interpol' , "{" )
- * K ( 'Interpol.Inside' , ( 1 - S "}\":" ) ^ 0 )
- * ( K ( 'String.Interpol' , ":" ) * Q ( (1 - S "}:\"") ^ 0 ) ) ^ -1
- * K ( 'String.Interpol' , "}" )
- +
- VisualSpace
- +
- Q ( ( P "\\\"" + "{{" + "}}" + 1 - S " {}\"" ) ^ 1 )
- ) ^ 0
- * Q "\""
- +
- Q ( P "\"" + "r\"" + "R\"" )
- * ( Q ( ( P "\\\"" + 1 - S " \"\r%" ) ^ 1 )
- + VisualSpace
- + PercentInterpol
- + Q "%"
- ) ^ 0
- * Q "\"" )
-
-local ShortString = SingleShortString + DoubleShortString
-local braces =
- Compute_braces
- (
- ( P "\"" + "r\"" + "R\"" + "f\"" + "F\"" )
- * ( P "\\\"" + 1 - S "\"" ) ^ 0 * "\""
- +
- ( P '\'' + 'r\'' + 'R\'' + 'f\'' + 'F\'' )
- * ( P '\\\'' + 1 - S '\'' ) ^ 0 * '\''
- )
-if piton.beamer then Beamer = Compute_Beamer ( 'python' , braces ) end
-DetectedCommands = Compute_DetectedCommands ( 'python' , braces )
-LPEG_cleaner['python'] = Compute_LPEG_cleaner ( 'python' , braces )
-local SingleLongString =
- WithStyle ( 'String.Long' ,
- ( Q ( S "fF" * P "'''" )
- * (
- K ( 'String.Interpol' , "{" )
- * K ( 'Interpol.Inside' , ( 1 - S "}:\r" - "'''" ) ^ 0 )
- * Q ( P ":" * (1 - S "}:\r" - "'''" ) ^ 0 ) ^ -1
- * K ( 'String.Interpol' , "}" )
- +
- Q ( ( 1 - P "'''" - S "{}'\r" ) ^ 1 )
- +
- EOL
- ) ^ 0
- +
- Q ( ( S "rR" ) ^ -1 * "'''" )
- * (
- Q ( ( 1 - P "'''" - S "\r%" ) ^ 1 )
- +
- PercentInterpol
- +
- P "%"
- +
- EOL
- ) ^ 0
- )
- * Q "'''" )
-
-local DoubleLongString =
- WithStyle ( 'String.Long' ,
- (
- Q ( S "fF" * "\"\"\"" )
- * (
- K ( 'String.Interpol', "{" )
- * K ( 'Interpol.Inside' , ( 1 - S "}:\r" - "\"\"\"" ) ^ 0 )
- * Q ( ":" * (1 - S "}:\r" - "\"\"\"" ) ^ 0 ) ^ -1
- * K ( 'String.Interpol' , "}" )
- +
- Q ( ( 1 - S "{}\"\r" - "\"\"\"" ) ^ 1 )
- +
- EOL
+ local LongString = SingleLongString + DoubleLongString
+ local StringDoc =
+ K ( 'String.Doc' , P "r" ^ -1 * "\"\"\"" )
+ * ( K ( 'String.Doc' , (1 - P "\"\"\"" - "\r" ) ^ 0 ) * EOL
+ * Tab ^ 0
) ^ 0
- +
- Q ( S "rR" ^ -1 * "\"\"\"" )
- * (
- Q ( ( 1 - P "\"\"\"" - S "%\r" ) ^ 1 )
- +
- PercentInterpol
- +
- P "%"
- +
- EOL
- ) ^ 0
+ * K ( 'String.Doc' , ( 1 - P "\"\"\"" - "\r" ) ^ 0 * "\"\"\"" )
+ local Comment =
+ WithStyle
+ ( 'Comment' ,
+ Q "#" * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 -- $
)
- * Q "\"\"\""
- )
-local LongString = SingleLongString + DoubleLongString
-local StringDoc =
- K ( 'String.Doc' , P "r" ^ -1 * "\"\"\"" )
- * ( K ( 'String.Doc' , (1 - P "\"\"\"" - "\r" ) ^ 0 ) * EOL
- * Tab ^ 0
- ) ^ 0
- * K ( 'String.Doc' , ( 1 - P "\"\"\"" - "\r" ) ^ 0 * "\"\"\"" )
-local Comment =
- WithStyle ( 'Comment' ,
- Q "#" * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 ) -- $
- * ( EOL + -1 )
-local expression =
- P { "E" ,
- E = ( "'" * ( P "\\'" + 1 - S "'\r" ) ^ 0 * "'"
- + "\"" * ( P "\\\"" + 1 - S "\"\r" ) ^ 0 * "\""
- + "{" * V "F" * "}"
- + "(" * V "F" * ")"
- + "[" * V "F" * "]"
- + ( 1 - S "{}()[]\r," ) ) ^ 0 ,
- F = ( "{" * V "F" * "}"
- + "(" * V "F" * ")"
- + "[" * V "F" * "]"
- + ( 1 - S "{}()[]\r\"'" ) ) ^ 0
- }
-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' , identifier )
- ) ^ -1
- }
-local DefFunction =
- K ( 'Keyword' , "def" )
- * Space
- * K ( 'Name.Function.Internal' , identifier )
- * SkipSpace
- * Q "(" * Params * Q ")"
- * SkipSpace
- * ( Q "->" * SkipSpace * K ( 'Name.Type' , identifier ) ) ^ -1
- * K ( 'ParseAgain.noCR' , ( 1 - S ":\r" ) ^ 0 )
- * Q ":"
- * ( SkipSpace
- * ( EOL + CommentLaTeX + Comment ) -- in all cases, that contains an EOL
- * Tab ^ 0
- * SkipSpace
- * StringDoc ^ 0 -- there may be additional docstrings
- ) ^ -1
-local ExceptionInConsole = Exception * Q ( ( 1 - P "\r" ) ^ 0 ) * EOL
-local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
-local Main =
- -- space ^ 1 * -1
- -- + space ^ 0 * EOL
- Space
- + Tab
- + Escape + EscapeMath
- + CommentLaTeX
- + Beamer
- + DetectedCommands
- + LongString
- + Comment
- + ExceptionInConsole
- + Delim
- + Operator
- + OperatorWord * EndKeyword
- + ShortString
- + Punct
- + FromImport
- + RaiseException
- + DefFunction
- + DefClass
- + For
- + Keyword * EndKeyword
- + Decorator
- + Builtin * EndKeyword
- + Identifier
- + Number
- + Word
-LPEG1['python'] = Main ^ 0
-LPEG2['python'] =
- Ct (
- ( space ^ 0 * "\r" ) ^ -1
- * BeamerBeginEnvironments
- * PromptHastyDetection
- * Lc [[\__piton_begin_line:]]
- * Prompt
- * SpaceIndentation ^ 0
- * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0
- * -1
- * Lc [[\__piton_end_line:]]
- )
-local balanced_parens =
- P { "E" , E = ( "(" * V "E" * ")" + ( 1 - S "()" ) ) ^ 0 }
-local Delim = Q ( P "[|" + "|]" + S "[()]" )
-local Punct = Q ( S ",:;!" )
-local cap_identifier = R "AZ" * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0
-local Constructor = K ( 'Name.Constructor' , cap_identifier )
-local ModuleType = K ( 'Name.Type' , cap_identifier )
-local identifier = ( R "az" + "_" ) * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0
-local Identifier = K ( 'Identifier.Internal' , identifier )
-local expression_for_fields =
- P { "E" ,
- E = ( "{" * V "F" * "}"
- + "(" * V "F" * ")"
- + "[" * V "F" * "]"
- + "\"" * ( P "\\\"" + 1 - S "\"\r" ) ^ 0 * "\""
- + "'" * ( P "\\'" + 1 - S "'\r" ) ^ 0 * "'"
- + ( 1 - S "{}()[]\r;" ) ) ^ 0 ,
- F = ( "{" * V "F" * "}"
- + "(" * V "F" * ")"
- + "[" * V "F" * "]"
- + ( 1 - S "{}()[]\r\"'" ) ) ^ 0
- }
-local OneFieldDefinition =
- ( K ( 'Keyword' , "mutable" ) * SkipSpace ) ^ -1
- * K ( 'Name.Field' , identifier ) * SkipSpace
- * Q ":" * SkipSpace
- * K ( 'TypeExpression' , expression_for_fields )
- * SkipSpace
-
-local OneField =
- K ( 'Name.Field' , identifier ) * SkipSpace
- * Q "=" * SkipSpace
- * ( expression_for_fields
- / ( function ( s ) return LPEG1['ocaml'] : match ( s ) end )
- )
- * SkipSpace
-
-local Record =
- Q "{" * SkipSpace
- *
- (
- OneFieldDefinition * ( Q ";" * SkipSpace * OneFieldDefinition ) ^ 0
+ * ( EOL + -1 )
+ local expression =
+ P { "E" ,
+ E = ( "'" * ( P "\\'" + 1 - S "'\r" ) ^ 0 * "'"
+ + "\"" * ( P "\\\"" + 1 - S "\"\r" ) ^ 0 * "\""
+ + "{" * V "F" * "}"
+ + "(" * V "F" * ")"
+ + "[" * V "F" * "]"
+ + ( 1 - S "{}()[]\r," ) ) ^ 0 ,
+ F = ( "{" * V "F" * "}"
+ + "(" * V "F" * ")"
+ + "[" * V "F" * "]"
+ + ( 1 - S "{}()[]\r\"'" ) ) ^ 0
+ }
+ 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' , identifier )
+ ) ^ -1
+ }
+ local DefFunction =
+ K ( 'Keyword' , "def" )
+ * Space
+ * K ( 'Name.Function.Internal' , identifier )
+ * SkipSpace
+ * Q "(" * Params * Q ")"
+ * SkipSpace
+ * ( Q "->" * SkipSpace * K ( 'Name.Type' , identifier ) ) ^ -1
+ * K ( 'ParseAgain.noCR' , ( 1 - S ":\r" ) ^ 0 )
+ * Q ":"
+ * ( SkipSpace
+ * ( EOL + CommentLaTeX + Comment ) -- in all cases, that contains an EOL
+ * Tab ^ 0
+ * SkipSpace
+ * StringDoc ^ 0 -- there may be additional docstrings
+ ) ^ -1
+ local ExceptionInConsole = Exception * Q ( ( 1 - P "\r" ) ^ 0 ) * EOL
+ local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
+ local Main =
+ space ^ 0 * EOL -- faut-il le mettre en commentaire ?
+ + Space
+ + Tab
+ + Escape + EscapeMath
+ + CommentLaTeX
+ + Beamer
+ + DetectedCommands
+ + LongString
+ + Comment
+ + ExceptionInConsole
+ + Delim
+ + Operator
+ + OperatorWord * EndKeyword
+ + ShortString
+ + Punct
+ + FromImport
+ + RaiseException
+ + DefFunction
+ + DefClass
+ + For
+ + Keyword * EndKeyword
+ + Decorator
+ + Builtin * EndKeyword
+ + Identifier
+ + Number
+ + Word
+ LPEG1['python'] = Main ^ 0
+ LPEG2['python'] =
+ Ct (
+ ( space ^ 0 * "\r" ) ^ -1
+ * BeamerBeginEnvironments
+ * PromptHastyDetection
+ * Lc [[\__piton_begin_line:]]
+ * Prompt
+ * SpaceIndentation ^ 0
+ * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0
+ * -1
+ * Lc [[\__piton_end_line:]]
+ )
+end
+do
+ local SkipSpace = ( Q " " + EOL ) ^ 0
+ local Space = ( Q " " + EOL ) ^ 1
+ local braces = Compute_braces ( "\"" * ( 1 - S "\"" ) ^ 0 * "\"" )
+ if piton.beamer then
+ Beamer = Compute_Beamer ( 'ocaml' , braces )
+ end
+ DetectedCommands = Compute_DetectedCommands ( 'ocaml' , braces )
+ local function Q ( pattern )
+ return Ct ( Cc ( luatexbase.catcodetables.CatcodeTableOther )
+ * C ( pattern ) )
+ + Beamer + DetectedCommands + EscapeMath + Escape
+ end
+ local function K ( style , pattern )
+ return
+ Lc ( "{\\PitonStyle{" .. style .. "}{" )
+ * Q ( pattern )
+ * Lc "}}"
+ end
+ local function WithStyle ( style , pattern )
+ return
+ Ct ( Cc "Open" * Cc ( "{\\PitonStyle{" .. style .. "}{" ) * Cc "}}" )
+ * ( pattern + Beamer + DetectedCommands + EscapeMath + Escape )
+ * Ct ( Cc "Close" )
+ end
+ local balanced_parens =
+ P { "E" , E = ( "(" * V "E" * ")" + ( 1 - S "()" ) ) ^ 0 }
+ local ocaml_string =
+ Q "\""
+ * (
+ VisualSpace
+
- OneField * ( Q ";" * SkipSpace * OneField ) ^ 0
- )
- *
- Q "}"
-local DotNotation =
- (
- K ( 'Name.Module' , cap_identifier )
- * Q "."
- * ( Identifier + Constructor + Q "(" + Q "[" + Q "{" ) ^ ( -1 )
+ Q ( ( 1 - S " \"\r" ) ^ 1 )
+
- Identifier
- * Q "."
- * K ( 'Name.Field' , identifier )
- )
- * ( Q "." * K ( 'Name.Field' , identifier ) ) ^ 0
-local Operator =
- K ( 'Operator' ,
- P "!=" + "<>" + "==" + "<<" + ">>" + "<=" + ">=" + ":=" + "||" + "&&" +
- "//" + "**" + ";;" + "::" + "->" + "+." + "-." + "*." + "/."
- + S "-~+/*%=<>&@|" )
-
-local OperatorWord =
- K ( 'Operator.Word' ,
- P "asr" + "land" + "lor" + "lsl" + "lxor" + "mod" + "or" )
-
-local governing_keyword = P "and" + "begin" + "class" + "constraint" +
- "end" + "external" + "functor" + "include" + "inherit" + "initializer" +
- "in" + "let" + "method" + "module" + "object" + "open" + "rec" + "sig" +
- "struct" + "type" + "val"
-
-local Keyword =
- K ( 'Keyword' ,
- P "assert" + "as" + "done" + "downto" + "do" + "else" + "exception"
- + "for" + "function" + "fun" + "if" + "lazy" + "match" + "mutable"
- + "new" + "of" + "private" + "raise" + "then" + "to" + "try"
- + "virtual" + "when" + "while" + "with" )
- + K ( 'Keyword.Constant' , P "true" + "false" )
- + K ('Keyword.Governing', governing_keyword )
-
-local Builtin =
- K ( 'Name.Builtin' , P "not" + "incr" + "decr" + "fst" + "snd" + "ref" )
-local Exception =
- K ( 'Exception' ,
- P "Division_by_zero" + "End_of_File" + "Failure" + "Invalid_argument" +
- "Match_failure" + "Not_found" + "Out_of_memory" + "Stack_overflow" +
- "Sys_blocked_io" + "Sys_error" + "Undefined_recursive_module" )
-local Char =
- K ( 'String.Short',
- P "'" *
- (
- ( 1 - S "'\\" )
- + "\\"
- * ( S "\\'ntbr \""
- + digit * digit * digit
- + P "x" * ( digit + R "af" + R "AF" )
- * ( digit + R "af" + R "AF" )
- * ( digit + R "af" + R "AF" )
- + P "o" * R "03" * R "07" * R "07" )
- )
- * "'" )
-local braces = Compute_braces ( "\"" * ( 1 - S "\"" ) ^ 0 * "\"" )
-if piton.beamer then
- Beamer = Compute_Beamer ( 'ocaml' , braces ) -- modified 2024/07/24
-end
-DetectedCommands = Compute_DetectedCommands ( 'ocaml' , braces )
-LPEG_cleaner['ocaml'] = Compute_LPEG_cleaner ( 'ocaml' , braces )
-local ocaml_string =
- Q "\""
- * (
- VisualSpace
- +
- Q ( ( 1 - S " \"\r" ) ^ 1 )
- +
- EOL
- ) ^ 0
- * Q "\""
-local String = WithStyle ( 'String.Long' , ocaml_string )
-local ext = ( R "az" + "_" ) ^ 0
-local open = "{" * Cg ( ext , 'init' ) * "|"
-local close = "|" * C ( ext ) * "}"
-local closeeq =
- Cmt ( close * Cb ( 'init' ) ,
- function ( s , i , a , b ) return a == b end )
-local QuotedStringBis =
- WithStyle ( 'String.Long' ,
+ EOL
+ ) ^ 0
+ * Q "\""
+ local String = WithStyle ( 'String.Long' , ocaml_string )
+ local ext = ( R "az" + "_" ) ^ 0
+ local open = "{" * Cg ( ext , 'init' ) * "|"
+ local close = "|" * C ( ext ) * "}"
+ local closeeq =
+ Cmt ( close * Cb ( 'init' ) ,
+ function ( s , i , a , b ) return a == b end )
+ local QuotedStringBis =
+ WithStyle ( 'String.Long' ,
+ (
+ Space
+ +
+ Q ( ( 1 - S " \r" ) ^ 1 )
+ +
+ EOL
+ ) ^ 0 )
+ local QuotedString =
+ C ( open * ( 1 - closeeq ) ^ 0 * close ) /
+ ( function ( s ) return QuotedStringBis : match ( s ) end )
+ local Comment =
+ WithStyle ( 'Comment' ,
+ P {
+ "A" ,
+ A = Q "(*"
+ * ( V "A"
+ + Q ( ( 1 - S "\r$\"" - "(*" - "*)" ) ^ 1 ) -- $
+ + ocaml_string
+ + "$" * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1 ) * "$" -- $
+ + EOL
+ ) ^ 0
+ * Q "*)"
+ } )
+ local Delim = Q ( P "[|" + "|]" + S "[()]" )
+ local Punct = Q ( S ",:;!" )
+ local cap_identifier = R "AZ" * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0
+ local Constructor =
+ K ( 'Name.Constructor' ,
+ Q "`" ^ -1 * cap_identifier
+ + Q "::"
+ + Q "[" * SkipSpace * Q "]" )
+ local ModuleType = K ( 'Name.Type' , cap_identifier )
+ local OperatorWord =
+ K ( 'Operator.Word' ,
+ P "asr" + "land" + "lor" + "lsl" + "lxor" + "mod" + "or" )
+ local governing_keyword = P "and" + "begin" + "class" + "constraint" +
+ "end" + "external" + "functor" + "include" + "inherit" + "initializer" +
+ "in" + "let" + "method" + "module" + "object" + "open" + "rec" + "sig" +
+ "struct" + "type" + "val"
+ local Keyword =
+ K ( 'Keyword' ,
+ P "assert" + "as" + "done" + "downto" + "do" + "else" + "exception"
+ + "for" + "function" + "fun" + "if" + "lazy" + "match" + "mutable"
+ + "new" + "of" + "private" + "raise" + "then" + "to" + "try"
+ + "virtual" + "when" + "while" + "with" )
+ + K ( 'Keyword.Constant' , P "true" + "false" )
+ + K ( 'Keyword.Governing', governing_keyword )
+ local EndKeyword
+ = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
+ local identifier = ( R "az" + "_" ) * ( R "az" + R "AZ" + S "_'" + digit ) ^ 0
+ - ( OperatorWord + Keyword ) * EndKeyword
+ local Identifier = K ( 'Identifier.Internal' , identifier )
+ local Char =
+ K ( 'String.Short',
+ P "'" *
(
- Space
+ ( 1 - S "'\\" )
+ + "\\"
+ * ( S "\\'ntbr \""
+ + digit * digit * digit
+ + P "x" * ( digit + R "af" + R "AF" )
+ * ( digit + R "af" + R "AF" )
+ * ( digit + R "af" + R "AF" )
+ + P "o" * R "03" * R "07" * R "07" )
+ )
+ * "'" )
+ local TypeParameter =
+ K ( 'TypeParameter' ,
+ "'" * Q"_" ^ -1 * alpha ^ 1 * ( # ( 1 - P "'" ) + -1 ) )
+ local expression_for_fields_type =
+ P { "E" ,
+ E = ( "{" * V "F" * "}"
+ + "(" * V "F" * ")"
+ + TypeParameter
+ + ( 1 - S "{}()[]\r;" ) ) ^ 0 ,
+ F = ( "{" * V "F" * "}"
+ + "(" * V "F" * ")"
+ + ( 1 - S "{}()[]\r\"'" ) + TypeParameter ) ^ 0
+ }
+ local expression_for_fields_value =
+ P { "E" ,
+ E = ( "{" * V "F" * "}"
+ + "(" * V "F" * ")"
+ + "[" * V "F" * "]"
+ + String + QuotedString + Char
+ + ( 1 - S "{}()[]\r;" ) ) ^ 0 ,
+ F = ( "{" * V "F" * "}"
+ + "(" * V "F" * ")"
+ + "[" * V "F" * "]"
+ + ( 1 - S "{}()[]\r\"'" )) ^ 0
+ }
+ local OneFieldDefinition =
+ ( K ( 'Keyword' , "mutable" ) * SkipSpace ) ^ -1
+ * K ( 'Name.Field' , identifier ) * SkipSpace
+ * Q ":" * SkipSpace
+ * K ( 'TypeExpression' , expression_for_fields_type )
+ * SkipSpace
+ local OneField =
+ K ( 'Name.Field' , identifier ) * SkipSpace
+ * Q "=" * SkipSpace
+ * ( expression_for_fields_value
+ / ( function ( s ) return LPEG1['ocaml'] : match ( s ) end )
+ )
+ * SkipSpace
+ local Record =
+ Q "{" * SkipSpace
+ *
+ (
+ OneFieldDefinition
+ * ( Q ";" * SkipSpace * ( Comment * SkipSpace ) ^ 0 * OneFieldDefinition ) ^ 0
+
- Q ( ( 1 - S " \r" ) ^ 1 )
+ OneField * ( Q ";" * SkipSpace * ( Comment * SkipSpace ) ^ 0 * OneField ) ^ 0
+ )
+ * SkipSpace
+ * Q ";" ^ -1
+ * SkipSpace
+ * Comment ^ -1
+ * SkipSpace
+ * Q "}"
+ local DotNotation =
+ (
+ K ( 'Name.Module' , cap_identifier )
+ * Q "."
+ * ( Identifier + Constructor + Q "(" + Q "[" + Q "{" ) ^ -1
+
- EOL
- ) ^ 0 )
-local QuotedString =
- C ( open * ( 1 - closeeq ) ^ 0 * close ) /
- ( function ( s ) return QuotedStringBis : match ( s ) end )
-local Comment =
- WithStyle ( 'Comment' ,
- P {
- "A" ,
- A = Q "(*"
- * ( V "A"
- + Q ( ( 1 - S "\r$\"" - "(*" - "*)" ) ^ 1 ) -- $
- + ocaml_string
- + "$" * K ( 'Comment.Math' , ( 1 - S "$\r" ) ^ 1 ) * "$" -- $
- + EOL
- ) ^ 0
- * Q "*)"
- } )
-local Argument =
- ( Q "~" * Identifier * Q ":" * SkipSpace ) ^ -1
- *
- ( K ( 'Identifier.Internal' , identifier )
- + Q "(" * SkipSpace
- * K ( 'Identifier.Internal' , identifier ) * SkipSpace
- * Q ":" * SkipSpace
- * K ( 'TypeExpression' , balanced_parens ) * SkipSpace
- * Q ")"
- )
-local DefFunction =
- K ( 'Keyword.Governing' , "let open" )
- * Space
- * K ( 'Name.Module' , cap_identifier )
- +
- K ( 'Keyword.Governing' , P "let rec" + "let" + "and" )
+ Identifier
+ * Q "."
+ * K ( 'Name.Field' , identifier )
+ )
+ * ( Q "." * K ( 'Name.Field' , identifier ) ) ^ 0
+ local Operator =
+ K ( 'Operator' ,
+ P "!=" + "<>" + "==" + "<<" + ">>" + "<=" + ">=" + ":=" + "||" + "&&" +
+ "//" + "**" + ";;" + "->" + "+." + "-." + "*." + "/."
+ + S "-~+/*%=<>&@|" )
+ local Builtin =
+ K ( 'Name.Builtin' , P "not" + "incr" + "decr" + "fst" + "snd" + "ref" )
+ local Exception =
+ K ( 'Exception' ,
+ P "Division_by_zero" + "End_of_File" + "Failure" + "Invalid_argument" +
+ "Match_failure" + "Not_found" + "Out_of_memory" + "Stack_overflow" +
+ "Sys_blocked_io" + "Sys_error" + "Undefined_recursive_module" )
+ LPEG_cleaner['ocaml'] = Compute_LPEG_cleaner ( 'ocaml' , braces )
+ local Argument =
+ ( Q "~" * Identifier * Q ":" * SkipSpace ) ^ -1
+ *
+ ( K ( 'Identifier.Internal' , identifier )
+ + Q "(" * SkipSpace
+ * K ( 'Identifier.Internal' , identifier ) * SkipSpace
+ * Q ":" * SkipSpace
+ * K ( 'TypeExpression' , balanced_parens ) * SkipSpace
+ * Q ")"
+ )
+ local DefFunction =
+ K ( 'Keyword.Governing' , "let open" )
* Space
- * K ( 'Name.Function.Internal' , identifier )
- * Space
- * (
- Q "=" * SkipSpace * K ( 'Keyword' , "function" )
+ * K ( 'Name.Module' , cap_identifier )
+ +
+ K ( 'Keyword.Governing' , P "let rec" + "let" + "and" )
+ * Space
+ * K ( 'Name.Function.Internal' , identifier )
+ * Space
+ * (
+ Q "=" * SkipSpace * K ( 'Keyword' , "function" )
+ +
+ Argument
+ * ( SkipSpace * Argument ) ^ 0
+ * (
+ SkipSpace
+ * Q ":"
+ * K ( 'TypeExpression' , ( 1 - P "=" ) ^ 0 )
+ ) ^ -1
+ )
+ local DefModule =
+ K ( 'Keyword.Governing' , "module" ) * Space
+ *
+ (
+ K ( 'Keyword.Governing' , "type" ) * Space
+ * K ( 'Name.Type' , cap_identifier )
+
- Argument
- * ( SkipSpace * Argument ) ^ 0
- * (
- SkipSpace
- * Q ":"
- * K ( 'TypeExpression' , ( 1 - P "=" ) ^ 0 )
- ) ^ -1
- )
-local DefModule =
- K ( 'Keyword.Governing' , "module" ) * Space
- *
- (
- K ( 'Keyword.Governing' , "type" ) * Space
- * K ( 'Name.Type' , cap_identifier )
- +
- K ( 'Name.Module' , cap_identifier ) * SkipSpace
- *
- (
- Q "(" * SkipSpace
+ K ( 'Name.Module' , cap_identifier ) * SkipSpace
+ *
+ (
+ Q "(" * SkipSpace
+ * K ( 'Name.Module' , cap_identifier ) * SkipSpace
+ * Q ":" * SkipSpace
+ * K ( 'Name.Type' , cap_identifier ) * SkipSpace
+ *
+ (
+ Q "," * SkipSpace
+ * K ( 'Name.Module' , cap_identifier ) * SkipSpace
+ * Q ":" * SkipSpace
+ * K ( 'Name.Type' , cap_identifier ) * SkipSpace
+ ) ^ 0
+ * Q ")"
+ ) ^ -1
+ *
+ (
+ Q "=" * SkipSpace
+ * K ( 'Name.Module' , cap_identifier ) * SkipSpace
+ * Q "("
* K ( 'Name.Module' , cap_identifier ) * SkipSpace
- * Q ":" * SkipSpace
- * K ( 'Name.Type' , cap_identifier ) * SkipSpace
- *
+ *
(
- Q "," * SkipSpace
- * K ( 'Name.Module' , cap_identifier ) * SkipSpace
- * Q ":" * SkipSpace
- * K ( 'Name.Type' , cap_identifier ) * SkipSpace
+ Q ","
+ *
+ K ( 'Name.Module' , cap_identifier ) * SkipSpace
) ^ 0
* Q ")"
- ) ^ -1
- *
- (
- Q "=" * SkipSpace
- * K ( 'Name.Module' , cap_identifier ) * SkipSpace
- * Q "("
- * K ( 'Name.Module' , cap_identifier ) * SkipSpace
- *
- (
- Q ","
- *
- K ( 'Name.Module' , cap_identifier ) * SkipSpace
- ) ^ 0
- * Q ")"
- ) ^ -1
- )
- +
- K ( 'Keyword.Governing' , P "include" + "open" )
- * Space * K ( 'Name.Module' , cap_identifier )
-local TypeParameter =
- K ( 'TypeParameter' , "'" * alpha * ( # ( 1 - P "'" ) + -1 ) )
-local DefType =
- K ( 'Keyword.Governing' , "type" )
- * Space
- * WithStyle
- (
- 'TypeExpression' ,
- ( Q ( 1 - P ";;" - P "\r" ) + EOL_without_space_indentation ) ^ 0
+ ) ^ -1
)
- * ( # governing_keyword + Q ";;" + -1 )
-local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
-local Main =
- Space
- + Tab
- + Escape + EscapeMath
- + Beamer
- + DetectedCommands
- + TypeParameter
- + String + QuotedString + Char
- + Comment
- + Delim
- + Operator
- + Q ( "~" ) * Identifier * ( Q ":" ) ^ -1
- + Q ":" * # (1 - P":") * SkipSpace
+ +
+ K ( 'Keyword.Governing' , P "include" + "open" )
+ * Space
+ * K ( 'Name.Module' , cap_identifier )
+ local DefType =
+ K ( 'Keyword.Governing' , "type" )
+ * Space
+ * K ( 'TypeExpression' , Q ( 1 - P "=" ) ^ 1 )
+ * SkipSpace
+ * ( Q "+=" + Q "=" )
+ * SkipSpace
+ * (
+ Record
+ +
+ WithStyle
+ (
+ 'TypeExpression' ,
+ (
+ ( EOL + Q ( 1 - P ";;" - governing_keyword ) ) ^ 0
+ * ( # ( governing_keyword ) + Q ";;" )
+ )
+ )
+ )
+ local Main =
+ space ^ 0 * EOL
+ + Space
+ + Tab
+ + Escape + EscapeMath
+ + Beamer
+ + DetectedCommands
+ + TypeParameter
+ + String + QuotedString + Char
+ + Comment
+ + Operator
+ + Q ( "~" ) * Identifier * ( Q ":" ) ^ -1
+ + Q ":" * # (1 - P ":") * SkipSpace
* K ( 'TypeExpression' , balanced_parens ) * SkipSpace * Q ")"
- + Punct
- + Exception
- + DefFunction
- + DefModule
- + DefType
- + Record
- + Keyword * EndKeyword
- + OperatorWord * EndKeyword
- + Builtin * EndKeyword
- + DotNotation
- + Constructor
- + Identifier
- + Number
- + Word
+ + Exception
+ + DefType
+ + DefFunction
+ + DefModule
+ + Record
+ + Keyword * EndKeyword
+ + OperatorWord * EndKeyword
+ + Builtin * EndKeyword
+ + DotNotation
+ + Constructor
+ + Identifier
+ + Punct
+ + Delim
+ + Number
+ + Word
+ LPEG1['ocaml'] = Main ^ 0
+ LPEG2['ocaml'] =
+ Ct (
+ ( P ":" + Identifier * SkipSpace * Q ":" )
+ * SkipSpace
+ * K ( 'TypeExpression' , ( 1 - P "\r" ) ^ 0 )
+ +
+ ( space ^ 0 * "\r" ) ^ -1
+ * BeamerBeginEnvironments
+ * Lc [[\__piton_begin_line:]]
+ * SpaceIndentation ^ 0
+ * ( ( space * Lc [[\__piton_trailing_space:]] ) ^ 1 * -1
+ + space ^ 0 * EOL
+ + Main
+ ) ^ 0
+ * -1
+ * Lc [[\__piton_end_line:]]
+ )
+end
+do
+ local Delim = Q ( S "{[()]}" )
+ local Punct = Q ( S ",:;!" )
+ local identifier = letter * alphanum ^ 0
-LPEG1['ocaml'] = Main ^ 0
-LPEG2['ocaml'] =
- Ct (
- ( P ":" + Identifier * SkipSpace * Q ":" )
- * SkipSpace
- * K ( 'TypeExpression' , ( 1 - P "\r" ) ^ 0 )
- +
- ( space ^ 0 * "\r" ) ^ -1
- * BeamerBeginEnvironments
- * Lc [[\__piton_begin_line:]]
- * SpaceIndentation ^ 0
- * ( ( space * Lc [[\__piton_trailing_space:]] ) ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0
- * -1
- * Lc [[\__piton_end_line:]]
- )
-local Delim = Q ( S "{[()]}" )
-local Punct = Q ( S ",:;!" )
-local identifier = letter * alphanum ^ 0
+ local Operator =
+ K ( 'Operator' ,
+ P "!=" + "==" + "<<" + ">>" + "<=" + ">=" + "||" + "&&"
+ + S "-~+/*%=<>&.@|!" )
-local Operator =
- K ( 'Operator' ,
- P "!=" + "==" + "<<" + ">>" + "<=" + ">=" + "||" + "&&"
- + S "-~+/*%=<>&.@|!" )
+ local Keyword =
+ K ( 'Keyword' ,
+ P "alignas" + "asm" + "auto" + "break" + "case" + "catch" + "class" +
+ "const" + "constexpr" + "continue" + "decltype" + "do" + "else" + "enum" +
+ "extern" + "for" + "goto" + "if" + "nexcept" + "private" + "public" +
+ "register" + "restricted" + "return" + "static" + "static_assert" +
+ "struct" + "switch" + "thread_local" + "throw" + "try" + "typedef" +
+ "union" + "using" + "virtual" + "volatile" + "while"
+ )
+ + K ( 'Keyword.Constant' , P "default" + "false" + "NULL" + "nullptr" + "true" )
-local Keyword =
- K ( 'Keyword' ,
- P "alignas" + "asm" + "auto" + "break" + "case" + "catch" + "class" +
- "const" + "constexpr" + "continue" + "decltype" + "do" + "else" + "enum" +
- "extern" + "for" + "goto" + "if" + "nexcept" + "private" + "public" +
- "register" + "restricted" + "return" + "static" + "static_assert" +
- "struct" + "switch" + "thread_local" + "throw" + "try" + "typedef" +
- "union" + "using" + "virtual" + "volatile" + "while"
- )
- + K ( 'Keyword.Constant' , P "default" + "false" + "NULL" + "nullptr" + "true" )
+ local Builtin =
+ K ( 'Name.Builtin' ,
+ P "alignof" + "malloc" + "printf" + "scanf" + "sizeof" )
-local Builtin =
- K ( 'Name.Builtin' ,
- P "alignof" + "malloc" + "printf" + "scanf" + "sizeof" )
+ 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" ) * Q "*" ^ 0
-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" ) * Q "*" ^ 0
+ local DefFunction =
+ Type
+ * Space
+ * Q "*" ^ -1
+ * K ( 'Name.Function.Internal' , identifier )
+ * SkipSpace
+ * # P "("
+ local DefClass =
+ K ( 'Keyword' , "class" ) * Space * K ( 'Name.Class' , identifier )
+ String =
+ WithStyle ( 'String.Long' ,
+ Q "\""
+ * ( VisualSpace
+ + K ( 'String.Interpol' ,
+ "%" * ( S "difcspxXou" + "ld" + "li" + "hd" + "hi" )
+ )
+ + Q ( ( P "\\\"" + 1 - S " \"" ) ^ 1 )
+ ) ^ 0
+ * Q "\""
+ )
+ local braces = Compute_braces ( "\"" * ( 1 - S "\"" ) ^ 0 * "\"" )
+ if piton.beamer then Beamer = Compute_Beamer ( 'c' , braces ) end
+ DetectedCommands = Compute_DetectedCommands ( 'c' , braces )
+ LPEG_cleaner['c'] = Compute_LPEG_cleaner ( 'c' , braces )
+ local Preproc = K ( 'Preproc' , "#" * ( 1 - P "\r" ) ^ 0 ) * ( EOL + -1 )
+ local Comment =
+ WithStyle ( 'Comment' ,
+ Q "//" * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 ) -- $
+ * ( EOL + -1 )
-local DefFunction =
- Type
- * Space
- * Q "*" ^ -1
- * K ( 'Name.Function.Internal' , identifier )
- * SkipSpace
- * # P "("
-local DefClass =
- K ( 'Keyword' , "class" ) * Space * K ( 'Name.Class' , identifier )
-String =
- WithStyle ( 'String.Long' ,
- Q "\""
- * ( VisualSpace
- + K ( 'String.Interpol' ,
- "%" * ( S "difcspxXou" + "ld" + "li" + "hd" + "hi" )
- )
- + Q ( ( P "\\\"" + 1 - S " \"" ) ^ 1 )
- ) ^ 0
- * Q "\""
- )
-local braces = Compute_braces ( "\"" * ( 1 - S "\"" ) ^ 0 * "\"" )
-if piton.beamer then Beamer = Compute_Beamer ( 'c' , braces ) end
-DetectedCommands = Compute_DetectedCommands ( 'c' , braces )
-LPEG_cleaner['c'] = Compute_LPEG_cleaner ( 'c' , braces )
-local Preproc = K ( 'Preproc' , "#" * ( 1 - P "\r" ) ^ 0 ) * ( EOL + -1 )
-local Comment =
- WithStyle ( 'Comment' ,
- Q "//" * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 ) -- $
- * ( EOL + -1 )
-
-local LongComment =
- WithStyle ( 'Comment' ,
- Q "/*"
- * ( CommentMath + Q ( ( 1 - P "*/" - S "$\r" ) ^ 1 ) + EOL ) ^ 0
- * Q "*/"
- ) -- $
-local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
-local Main =
- Space
- + Tab
- + Escape + EscapeMath
- + CommentLaTeX
- + Beamer
- + DetectedCommands
- + Preproc
- + Comment + LongComment
- + Delim
- + Operator
- + String
- + Punct
- + DefFunction
- + DefClass
- + Type * ( Q "*" ^ -1 + EndKeyword )
- + Keyword * EndKeyword
- + Builtin * EndKeyword
- + Identifier
- + Number
- + Word
-LPEG1['c'] = Main ^ 0
-LPEG2['c'] =
- Ct (
- ( space ^ 0 * P "\r" ) ^ -1
- * BeamerBeginEnvironments
- * Lc [[\__piton_begin_line:]]
- * SpaceIndentation ^ 0
- * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0
- * -1
- * Lc [[\__piton_end_line:]]
- )
-local function LuaKeyword ( name )
-return
- Lc [[{\PitonStyle{Keyword}{]]
- * Q ( Cmt (
- C ( identifier ) ,
- function ( s , i , a ) return string.upper ( a ) == name end
- )
+ local LongComment =
+ WithStyle ( 'Comment' ,
+ Q "/*"
+ * ( CommentMath + Q ( ( 1 - P "*/" - S "$\r" ) ^ 1 ) + EOL ) ^ 0
+ * Q "*/"
+ ) -- $
+ local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
+ local Main =
+ space ^ 0 * EOL
+ + Space
+ + Tab
+ + Escape + EscapeMath
+ + CommentLaTeX
+ + Beamer
+ + DetectedCommands
+ + Preproc
+ + Comment + LongComment
+ + Delim
+ + Operator
+ + String
+ + Punct
+ + DefFunction
+ + DefClass
+ + Type * ( Q "*" ^ -1 + EndKeyword )
+ + Keyword * EndKeyword
+ + Builtin * EndKeyword
+ + Identifier
+ + Number
+ + Word
+ LPEG1['c'] = Main ^ 0
+ LPEG2['c'] =
+ Ct (
+ ( space ^ 0 * P "\r" ) ^ -1
+ * BeamerBeginEnvironments
+ * Lc [[\__piton_begin_line:]]
+ * SpaceIndentation ^ 0
+ * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0
+ * -1
+ * Lc [[\__piton_end_line:]]
)
- * Lc "}}"
end
-local identifier =
- letter * ( alphanum + "-" ) ^ 0
- + P '"' * ( ( 1 - P '"' ) ^ 1 ) * '"'
+do
+ local function LuaKeyword ( name )
+ return
+ Lc [[{\PitonStyle{Keyword}{]]
+ * Q ( Cmt (
+ C ( identifier ) ,
+ function ( s , i , a ) return string.upper ( a ) == name end
+ )
+ )
+ * Lc "}}"
+ end
+ local identifier =
+ letter * ( alphanum + "-" ) ^ 0
+ + P '"' * ( ( 1 - P '"' ) ^ 1 ) * '"'
+ local Operator =
+ K ( 'Operator' , P "=" + "!=" + "<>" + ">=" + ">" + "<=" + "<" + S "*+/" )
+ 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"
+ }
+ local Identifier =
+ C ( identifier ) /
+ (
+ function (s)
+ if set_keywords[string.upper(s)] -- the keywords are case-insensitive in SQL
+ 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
+ )
+ local String = K ( 'String.Long' , "'" * ( 1 - P "'" ) ^ 1 * "'" )
+ local braces = Compute_braces ( "'" * ( 1 - P "'" ) ^ 1 * "'" )
+ if piton.beamer then Beamer = Compute_Beamer ( 'sql' , braces ) end
+ DetectedCommands = Compute_DetectedCommands ( 'sql' , braces )
+ LPEG_cleaner['sql'] = Compute_LPEG_cleaner ( 'sql' , braces )
+ local Comment =
+ WithStyle ( 'Comment' ,
+ Q "--" -- syntax of SQL92
+ * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 ) -- $
+ * ( EOL + -1 )
-local Operator =
- K ( 'Operator' , P "=" + "!=" + "<>" + ">=" + ">" + "<=" + "<" + S "*+/" )
-local function Set ( list )
- local set = { }
- for _, l in ipairs ( list ) do set[l] = true end
- return set
-end
+ local LongComment =
+ WithStyle ( 'Comment' ,
+ Q "/*"
+ * ( CommentMath + Q ( ( 1 - P "*/" - S "$\r" ) ^ 1 ) + EOL ) ^ 0
+ * Q "*/"
+ ) -- $
+ local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
+ local TableField =
+ K ( 'Name.Table' , identifier )
+ * Q "."
+ * K ( 'Name.Field' , identifier )
-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 OneField =
+ (
+ Q ( "(" * ( 1 - P ")" ) ^ 0 * ")" )
+ +
+ K ( 'Name.Table' , identifier )
+ * Q "."
+ * K ( 'Name.Field' , identifier )
+ +
+ K ( 'Name.Field' , identifier )
+ )
+ * (
+ Space * LuaKeyword "AS" * Space * K ( 'Name.Field' , identifier )
+ ) ^ -1
+ * ( Space * ( LuaKeyword "ASC" + LuaKeyword "DESC" ) ) ^ -1
-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"
- }
-local Identifier =
- C ( identifier ) /
- (
- function (s)
- if set_keywords[string.upper(s)] -- the keywords are case-insensitive in SQL
- 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
- )
-local String = K ( 'String.Long' , "'" * ( 1 - P "'" ) ^ 1 * "'" )
-local braces = Compute_braces ( "'" * ( 1 - P "'" ) ^ 1 * "'" )
-if piton.beamer then Beamer = Compute_Beamer ( 'sql' , braces ) end
-DetectedCommands = Compute_DetectedCommands ( 'sql' , braces )
-LPEG_cleaner['sql'] = Compute_LPEG_cleaner ( 'sql' , braces )
-local Comment =
- WithStyle ( 'Comment' ,
- Q "--" -- syntax of SQL92
- * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 ) -- $
- * ( EOL + -1 )
-
-local LongComment =
- WithStyle ( 'Comment' ,
- Q "/*"
- * ( CommentMath + Q ( ( 1 - P "*/" - S "$\r" ) ^ 1 ) + EOL ) ^ 0
- * Q "*/"
- ) -- $
-local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
-local TableField =
+ local OneTable =
K ( 'Name.Table' , identifier )
- * Q "."
- * K ( 'Name.Field' , identifier )
+ * (
+ Space
+ * LuaKeyword "AS"
+ * Space
+ * K ( 'Name.Table' , identifier )
+ ) ^ -1
-local OneField =
- (
- Q ( "(" * ( 1 - P ")" ) ^ 0 * ")" )
- +
- K ( 'Name.Table' , identifier )
- * Q "."
- * K ( 'Name.Field' , identifier )
- +
- K ( 'Name.Field' , identifier )
- )
- * (
- Space * LuaKeyword "AS" * Space * K ( 'Name.Field' , identifier )
- ) ^ -1
- * ( Space * ( LuaKeyword "ASC" + LuaKeyword "DESC" ) ) ^ -1
+ local WeCatchTableNames =
+ LuaKeyword "FROM"
+ * ( Space + EOL )
+ * OneTable * ( SkipSpace * Q "," * SkipSpace * OneTable ) ^ 0
+ + (
+ LuaKeyword "JOIN" + LuaKeyword "INTO" + LuaKeyword "UPDATE"
+ + LuaKeyword "TABLE"
+ )
+ * ( Space + EOL ) * OneTable
+ local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
+ local Main =
+ space ^ 0 * EOL
+ + Space
+ + Tab
+ + Escape + EscapeMath
+ + CommentLaTeX
+ + Beamer
+ + DetectedCommands
+ + Comment + LongComment
+ + Delim
+ + Operator
+ + String
+ + Punct
+ + WeCatchTableNames
+ + ( TableField + Identifier ) * ( Space + Operator + Punct + Delim + EOL + -1 )
+ + Number
+ + Word
+ LPEG1['sql'] = Main ^ 0
+ LPEG2['sql'] =
+ Ct (
+ ( space ^ 0 * "\r" ) ^ -1
+ * BeamerBeginEnvironments
+ * Lc [[\__piton_begin_line:]]
+ * SpaceIndentation ^ 0
+ * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0
+ * -1
+ * Lc [[\__piton_end_line:]]
+ )
+end
+do
+ local Punct = Q ( S ",:;!\\" )
-local OneTable =
- K ( 'Name.Table' , identifier )
- * (
- Space
- * LuaKeyword "AS"
- * Space
- * K ( 'Name.Table' , identifier )
- ) ^ -1
+ local Comment =
+ WithStyle ( 'Comment' ,
+ Q "#"
+ * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 -- $
+ )
+ * ( EOL + -1 )
-local WeCatchTableNames =
- LuaKeyword "FROM"
- * ( Space + EOL )
- * OneTable * ( SkipSpace * Q "," * SkipSpace * OneTable ) ^ 0
- + (
- LuaKeyword "JOIN" + LuaKeyword "INTO" + LuaKeyword "UPDATE"
- + LuaKeyword "TABLE"
- )
- * ( Space + EOL ) * OneTable
-local EndKeyword = Space + Punct + Delim + EOL + Beamer + DetectedCommands + -1
-local Main =
- Space
- + Tab
- + Escape + EscapeMath
- + CommentLaTeX
- + Beamer
- + DetectedCommands
- + Comment + LongComment
- + Delim
- + Operator
- + String
- + Punct
- + WeCatchTableNames
- + ( TableField + Identifier ) * ( Space + Operator + Punct + Delim + EOL + -1 )
- + Number
- + Word
-LPEG1['sql'] = Main ^ 0
-LPEG2['sql'] =
- Ct (
- ( space ^ 0 * "\r" ) ^ -1
- * BeamerBeginEnvironments
- * Lc [[\__piton_begin_line:]]
- * SpaceIndentation ^ 0
- * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0
- * -1
- * Lc [[\__piton_end_line:]]
- )
-local Punct = Q ( S ",:;!\\" )
+ local String =
+ WithStyle ( 'String.Short' ,
+ Q "\""
+ * ( VisualSpace
+ + Q ( ( P "\\\"" + 1 - S " \"" ) ^ 1 )
+ ) ^ 0
+ * Q "\""
+ )
+ local braces = Compute_braces ( P "\"" * ( P "\\\"" + 1 - P "\"" ) ^ 1 * "\"" )
-local Comment =
- WithStyle ( 'Comment' ,
- Q "#"
- * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0 -- $
- )
- * ( EOL + -1 )
+ if piton.beamer then Beamer = Compute_Beamer ( 'minimal' , braces ) end
-local String =
- WithStyle ( 'String.Short' ,
- Q "\""
- * ( VisualSpace
- + Q ( ( P "\\\"" + 1 - S " \"" ) ^ 1 )
- ) ^ 0
- * Q "\""
- )
+ DetectedCommands = Compute_DetectedCommands ( 'minimal' , braces )
-local braces = Compute_braces ( P "\"" * ( P "\\\"" + 1 - P "\"" ) ^ 1 * "\"" )
+ LPEG_cleaner['minimal'] = Compute_LPEG_cleaner ( 'minimal' , braces )
-if piton.beamer then Beamer = Compute_Beamer ( 'minimal' , braces ) end
+ local identifier = letter * alphanum ^ 0
-DetectedCommands = Compute_DetectedCommands ( 'minimal' , braces )
+ local Identifier = K ( 'Identifier.Internal' , identifier )
-LPEG_cleaner['minimal'] = Compute_LPEG_cleaner ( 'minimal' , braces )
+ local Delim = Q ( S "{[()]}" )
-local identifier = letter * alphanum ^ 0
+ local Main =
+ space ^ 0 * EOL
+ + Space
+ + Tab
+ + Escape + EscapeMath
+ + CommentLaTeX
+ + Beamer
+ + DetectedCommands
+ + Comment
+ + Delim
+ + String
+ + Punct
+ + Identifier
+ + Number
+ + Word
+ LPEG1['minimal'] = Main ^ 0
-local Identifier = K ( 'Identifier.Internal' , identifier )
-
-local Delim = Q ( S "{[()]}" )
-
-local Main =
- Space
- + Tab
- + Escape + EscapeMath
- + CommentLaTeX
- + Beamer
- + DetectedCommands
- + Comment
- + Delim
- + String
- + Punct
- + Identifier
- + Number
- + Word
-
-LPEG1['minimal'] = Main ^ 0
-
-LPEG2['minimal'] =
- Ct (
- ( space ^ 0 * "\r" ) ^ -1
- * BeamerBeginEnvironments
- * Lc [[\__piton_begin_line:]]
- * SpaceIndentation ^ 0
- * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0
- * -1
- * Lc [[\__piton_end_line:]]
- )
-
+ LPEG2['minimal'] =
+ Ct (
+ ( space ^ 0 * "\r" ) ^ -1
+ * BeamerBeginEnvironments
+ * Lc [[\__piton_begin_line:]]
+ * SpaceIndentation ^ 0
+ * ( space ^ 1 * -1 + space ^ 0 * EOL + Main ) ^ 0
+ * -1
+ * Lc [[\__piton_end_line:]]
+ )
+end
function piton.Parse ( language , code )
local t = LPEG2[language] : match ( code )
if t == nil
@@ -1183,7 +1239,8 @@
end
end
end
-function piton.ParseFile ( language , name , first_line , last_line , split )
+function piton.ParseFile
+ ( lang , name , first_line , last_line , splittable , split )
local s = ''
local i = 0
for line in io.lines ( name ) do
@@ -1203,21 +1260,26 @@
end
end
if split == 1 then
- piton.GobbleSplitParse ( language , 0 , s )
+ piton.RetrieveGobbleSplitParse ( lang , 0 , splittable , s )
else
- sprintL3 [[ \bool_if:NT \g__piton_footnote_bool \savenotes \vtop \bgroup ]]
- piton.Parse ( language , s )
- sprintL3
- [[\vspace{2.5pt}\egroup\bool_if:NT\g__piton_footnote_bool\endsavenotes\par]]
+ piton.RetrieveGobbleParse ( lang , 0 , splittable , s )
end
end
+function piton.RetrieveGobbleParse ( lang , n , splittable , code )
+ local s
+ s = ( ( P " " ^ 0 * "\r" ) ^ -1 * C ( P ( 1 ) ^ 0 ) * -1 ) : match ( code )
+ piton.GobbleParse ( lang , n , splittable , s )
+end
function piton.ParseBis ( lang , code )
local s = ( Cs ( ( P '##' / '#' + 1 ) ^ 0 ) ) : match ( code )
return piton.Parse ( lang , s )
end
function piton.ParseTer ( lang , code )
- local s = ( Cs ( ( P [[\__piton_breakable_space: ]] / ' ' + 1 ) ^ 0 ) )
- : match ( code )
+ local s
+ s = ( Cs ( ( P [[\__piton_breakable_space: ]] / ' ' + 1 ) ^ 0 ) )
+ : match ( code )
+ s = ( Cs ( ( P [[\__piton_leading_space: ]] / '' + 1 ) ^ 0 ) )
+ : match ( s )
return piton.Parse ( lang , s )
end
local AutoGobbleLPEG =
@@ -1281,14 +1343,14 @@
end
end
end
-function piton.GobbleParse ( lang , n , code )
+function piton.GobbleParse ( lang , n , splittable , code )
+ piton.ComputeLinesStatus ( code , splittable )
piton.last_code = gobble ( n , code )
piton.last_language = lang
piton.CountLines ( piton.last_code )
sprintL3 [[ \bool_if:NT \g__piton_footnote_bool \savenotes ]]
- sprintL3 [[ \vtop \bgroup ]]
piton.Parse ( lang , piton.last_code )
- sprintL3 [[ \vspace{2.5pt} \egroup ]]
+ sprintL3 [[ \vspace{2.5pt} ]]
sprintL3 [[ \bool_if:NT \g__piton_footnote_bool \endsavenotes ]]
sprintL3 [[ \par ]]
if piton.write and piton.write ~= '' then
@@ -1301,22 +1363,43 @@
end
end
end
-function piton.GobbleSplitParse ( lang , n , code )
- P { "E" ,
- E = ( V "F"
- * ( P " " ^ 0 * "\r"
- / ( function ( x ) sprintL3 [[ \__piton_incr_visual_line: ]] end )
- ) ^ 1
- / ( function ( x )
- sprintL3 ( piton.string_between_chunks )
- end )
- ) ^ 0 * V "F" ,
- F = C ( V "G" ^ 0 )
- / ( function ( x ) piton.GobbleParse ( lang , 0 , x ) end ) ,
- G = ( 1 - P "\r" ) ^ 0 * "\r" - ( P " " ^ 0 * "\r" )
- + ( ( 1 - P "\r" ) ^ 1 * -1 - ( P " " ^ 0 * -1 ) )
- } : match ( gobble ( n , code ) )
+function piton.GobbleSplitParse ( lang , n , splittable , code )
+ local chunks
+ chunks =
+ (
+ Ct (
+ (
+ P " " ^ 0 * "\r"
+ +
+ C ( ( ( 1 - P "\r" ) ^ 1 * "\r" - ( P " " ^ 0 * "\r" ) ) ^ 1 )
+ ) ^ 0
+ )
+ ) : match ( gobble ( n , code ) )
+ sprintL3 ( [[ \begingroup ]] )
+ sprintL3
+ (
+ [[ \PitonOptions { split-on-empty-lines=false, gobble = 0, ]]
+ .. "language = " .. lang .. ","
+ .. "splittable = " .. splittable .. "}"
+ )
+ for k , v in pairs ( chunks ) do
+ if k > 1 then
+ sprintL3 ( [[\l__piton_split_separation_tl ]] )
+ end
+ tex.sprint
+ (
+ [[\begin{]] .. piton.env_used_by_split .. "}\r"
+ .. v
+ .. [[\end{]] .. piton.env_used_by_split .. "}"
+ )
+ end
+ sprintL3 ( [[ \endgroup ]] )
end
+function piton.RetrieveGobbleSplitParse ( lang , n , splittable , code )
+ local s
+ s = ( ( P " " ^ 0 * "\r" ) ^ -1 * C ( P ( 1 ) ^ 0 ) * -1 ) : match ( code )
+ piton.GobbleSplitParse ( lang , n , splittable , s )
+end
piton.string_between_chunks =
[[ \par \l__piton_split_separation_tl \mode_leave_vertical: ]]
.. [[ \int_gzero:N \g__piton_line_int ]]
@@ -1325,8 +1408,13 @@
end
function piton.CountLines ( code )
local count = 0
- for i in code : gmatch ( "\r" ) do count = count + 1 end
- sprintL3 ( string.format ( [[ \int_set:Nn \l__piton_nb_lines_int { % i } ]] , count ) )
+ count =
+ ( Ct ( ( ( 1 - P "\r" ) ^ 0 * C "\r" ) ^ 0
+ * ( ( 1 - P "\r" ) ^ 1 * Cc "\r" ) ^ -1
+ * -1
+ ) / table.getn
+ ) : match ( code )
+ sprintL3 ( string.format ( [[ \int_set:Nn \l__piton_nb_lines_int { %i } ]] , count ) )
end
function piton.CountNonEmptyLines ( code )
local count = 0
@@ -1338,13 +1426,13 @@
) / table.getn
) : match ( code )
sprintL3
- ( string.format ( [[ \int_set:Nn \l__piton_nb_non_empty_lines_int { % i } ]] , count ) )
+ ( string.format ( [[ \int_set:Nn \l__piton_nb_non_empty_lines_int { %i } ]] , count ) )
end
function piton.CountLinesFile ( name )
local count = 0
for line in io.lines ( name ) do count = count + 1 end
sprintL3
- ( string.format ( [[ \int_set:Nn \l__piton_nb_lines_int { %i } ]], count))
+ ( string.format ( [[ \int_set:Nn \l__piton_nb_lines_int { %i } ]], count ) )
end
function piton.CountNonEmptyLinesFile ( name )
local count = 0
@@ -1384,6 +1472,76 @@
[[ \int_set:Nn \l__piton_first_line_int { ]] .. first_line .. ' + 2 }'
.. [[ \int_set:Nn \l__piton_last_line_int { ]] .. count .. ' }' )
end
+function piton.ComputeLinesStatus ( code , splittable )
+ local lpeg_line_beamer
+ if piton.beamer then
+ lpeg_line_beamer =
+ space ^ 0
+ * P "\\begin{" * piton.BeamerEnvironments * "}"
+ * ( "<" * ( 1 - P ">" ) ^ 0 * ">" ) ^ -1
+ +
+ space ^ 0
+ * P "\\end{" * piton.BeamerEnvironments * "}"
+ else
+ lpeg_line_beamer = P ( false )
+ end
+ local lpeg_empty_lines =
+ Ct (
+ ( lpeg_line_beamer * "\r"
+ +
+ P " " ^ 0 * "\r" * Cc ( 0 )
+ +
+ ( 1 - P "\r" ) ^ 0 * "\r" * Cc ( 1 )
+ ) ^ 0
+ *
+ ( lpeg_line_beamer + ( 1 - P "\r" ) ^ 1 * Cc ( 1 ) ) ^ -1
+ )
+ * -1
+ local lpeg_all_lines =
+ Ct (
+ ( lpeg_line_beamer * "\r"
+ +
+ ( 1 - P "\r" ) ^ 0 * "\r" * Cc ( 1 )
+ ) ^ 0
+ *
+ ( lpeg_line_beamer + ( 1 - P "\r" ) ^ 1 * Cc ( 1 ) ) ^ -1
+ )
+ * -1
+ piton.empty_lines = lpeg_empty_lines : match ( code )
+ local lines_status
+ local s = splittable
+ if splittable < 0 then s = - splittable end
+ if splittable > 0 then
+ lines_status = lpeg_all_lines : match ( code )
+ else
+ lines_status = lpeg_empty_lines : match ( code )
+ for i , x in ipairs ( lines_status ) do
+ if x == 0 then
+ for j = 1 , s - 1 do
+ if i + j > #lines_status then break end
+ if lines_status[i+j] == 0 then break end
+ lines_status[i+j] = 2
+ end
+ for j = 1 , s - 1 do
+ if i - j - 1 == 0 then break end
+ if lines_status[i-j-1] == 0 then break end
+ lines_status[i-j-1] = 2
+ end
+ end
+ end
+ end
+ for j = 1 , s - 1 do
+ if j > #lines_status then break end
+ if lines_status[j] == 0 then break end
+ lines_status[j] = 2
+ end
+ for j = 1 , s - 1 do
+ if #lines_status - j == 0 then break end
+ if lines_status[#lines_status - j] == 0 then break end
+ lines_status[#lines_status - j] = 2
+ end
+ piton.lines_status = lines_status
+end
function piton.new_language ( lang , definition )
lang = string.lower ( lang )
local alpha , digit = lpeg.alpha , lpeg.digit
@@ -1544,7 +1702,7 @@
central_pattern = P ( arg3 .. arg3 ) + central_pattern
end
if arg1 == "m"
- then prefix = lpeg.B ( 1 - letter - ")" - "]" )
+ then prefix = B ( 1 - letter - ")" - "]" )
else prefix = P ( true )
end
long_string = long_string +
@@ -1664,7 +1822,8 @@
local Delim = Q ( S "{[()]}" )
local Punct = Q ( S "=,:;!\\'\"" )
local Main =
- Space
+ space ^ 0 * EOL
+ + Space
+ Tab
+ Escape + EscapeMath
+ CommentLaTeX
Modified: trunk/Master/texmf-dist/tex/lualatex/piton/piton.sty
===================================================================
--- trunk/Master/texmf-dist/tex/lualatex/piton/piton.sty 2024-09-22 20:22:16 UTC (rev 72350)
+++ trunk/Master/texmf-dist/tex/lualatex/piton/piton.sty 2024-09-22 20:22:25 UTC (rev 72351)
@@ -19,8 +19,8 @@
%% LaTeX version 2005/12/01 or later.
%% -------------------------------------------
%%
-\def\PitonFileVersion{3.1b}
-\def\PitonFileDate{2024/08/29}
+\def\PitonFileVersion{4.0}
+\def\PitonFileDate{2024/09/22}
@@ -90,13 +90,20 @@
\bool_new:N \g__piton_math_comments_bool
\bool_new:N \g__piton_beamer_bool
\tl_new:N \g__piton_escape_inside_tl
+\bool_new:N \l__piton_old_PitonInputFile_bool
\keys_define:nn { piton / package }
{
footnote .bool_gset:N = \g__piton_footnote_bool ,
footnotehyper .bool_gset:N = \g__piton_footnotehyper_bool ,
+ footnote .usage:n = load ,
+ footnotehyper .usage:n = load ,
beamer .bool_gset:N = \g__piton_beamer_bool ,
beamer .default:n = true ,
+ beamer .usage:n = load ,
+ old-PitonInputFile .bool_set:N = \l__piton_old_PitonInputFile_bool ,
+ old-PitonInputFile .default:n = true ,
+ old-PitonInputFile .usage:n = load ,
unknown .code:n = \__piton_error:n { Unknown~key~for~package }
}
@@ -104,8 +111,8 @@
{
Unknown~key.\\
You~have~used~the~key~'\l_keys_key_str'~but~the~only~keys~available~here~
- are~'beamer',~'footnote',~'footnotehyper'.~Other~keys~are~available~in~
- \token_to_str:N \PitonOptions.\\
+ are~'beamer',~'footnote',~'footnotehyper'~and~'old-PitonInputFile'.~
+ Other~keys~are~available~in~\token_to_str:N \PitonOptions.\\
That~key~will~be~ignored.
}
\ProcessKeysOptions { piton / package }
@@ -157,8 +164,8 @@
}
\lua_now:n
{
- piton.BeamerCommands = lpeg.P ( "\\uncover" )
- + "\\only" + "\\visible" + "\\invisible" + "\\alert" + "\\action"
+ piton.BeamerCommands = lpeg.P ( [[\uncover]] )
+ + [[\only]] + [[\visible]] + [[\invisible]] + [[\alert]] + [[\action]]
piton.beamer_environments = { "uncoverenv" , "onlyenv" , "visibleenv" ,
"invisibleenv" , "alertenv" , "actionenv" }
piton.DetectedCommands = lpeg.P ( false )
@@ -172,6 +179,8 @@
\str_new:N \l__piton_path_write_str
\bool_new:N \l__piton_in_PitonOptions_bool
\bool_new:N \l__piton_in_PitonInputFile_bool
+\tl_new:N \l__piton_font_command_tl
+\tl_set:Nn \l__piton_font_command_tl { \ttfamily }
\int_new:N \l__piton_nb_lines_int
\int_new:N \l__piton_nb_non_empty_lines_int
\int_new:N \g__piton_line_int
@@ -227,7 +236,7 @@
\tl_new:N \l__piton_space_tl
\tl_set_eq:NN \l__piton_space_tl \nobreakspace
\int_new:N \g__piton_indentation_int
-\cs_new_protected:Npn \__piton_an_indentation_space:
+\cs_new_protected:Npn \__piton_leading_space:
{ \int_gincr:N \g__piton_indentation_int }
\cs_new_protected:Npn \__piton_label:n #1
{
@@ -243,13 +252,11 @@
}
}
\@esphack
- }
- { \__piton_error:n { label~with~lines~numbers } }
+ }
+ { \__piton_error:n { label~with~lines~numbers } }
}
\cs_new_protected:Npn \__piton_marker_beginning:n #1 { }
\cs_new_protected:Npn \__piton_marker_end:n #1 { }
-\cs_new_protected:Npn \__piton_open_brace: { \lua_now:n { piton.open_brace() } }
-\cs_new_protected:Npn \__piton_close_brace: { \lua_now:n { piton.close_brace() } }
\tl_new:N \g__piton_begin_line_hook_tl
\cs_new_protected:Npn \__piton_prompt:
{
@@ -256,7 +263,7 @@
\tl_gset:Nn \g__piton_begin_line_hook_tl
{
\tl_if_empty:NF \l__piton_prompt_bg_color_tl
- { \clist_set:NV \l__piton_bg_color_clist \l__piton_prompt_bg_color_tl }
+ { \clist_set:No \l__piton_bg_color_clist \l__piton_prompt_bg_color_tl }
}
}
\cs_new_protected:Npn \__piton_trailing_space: { }
@@ -265,8 +272,8 @@
\tl_set:Nn \l_tmpa_tl { #1 }
\bool_if:NTF \l__piton_show_spaces_bool
{
- \tl_set:Nn \l__piton_space_tl { ␣ }
- \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl % U+2423
+ \tl_set:Nn \l__piton_space_tl { ␣ } % U+2423
+ \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl
}
{
\bool_if:NT \l__piton_break_lines_in_Piton_bool
@@ -275,10 +282,16 @@
{ \x20 }
{ \c { __piton_breakable_space: } }
\l_tmpa_tl
+ \regex_replace_all:nnN
+ { \c { l__piton_space_tl } }
+ { \c { __piton_breakable_space: } }
+ \l_tmpa_tl
}
}
\l_tmpa_tl
}
+
+\cs_set_protected:Npn \__piton_end_line: { }
\cs_set_protected:Npn \__piton_begin_line: #1 \__piton_end_line:
{
\group_begin:
@@ -299,16 +312,27 @@
\skip_horizontal:N \l__piton_left_margin_dim
\bool_if:NT \l__piton_line_numbers_bool
{
- \bool_if:nF
+ \int_set:Nn \l_tmpa_int
{
- \str_if_eq_p:nn { #1 } { \PitonStyle { Prompt } { } }
- &&
- \l__piton_skip_empty_lines_bool
+ \lua_now:e
+ {
+ tex.sprint
+ (
+ luatexbase.catcodetables.expl ,
+ tostring
+ ( piton.empty_lines
+ [ \int_eval:n { \g__piton_line_int + 1 } ]
+ )
+ )
+ }
}
+ \bool_lazy_or:nnT
+ { \int_compare_p:nNn \l_tmpa_int = \c_one_int }
+ { ! \l__piton_skip_empty_lines_bool }
{ \int_gincr:N \g__piton_visual_line_int }
\bool_if:nT
{
- ! \str_if_eq_p:nn { #1 } { \PitonStyle { Prompt } { } }
+ \int_compare_p:nNn \l_tmpa_int = \c_one_int
||
( ! \l__piton_skip_empty_lines_bool && \l__piton_label_empty_lines_bool )
}
@@ -317,12 +341,13 @@
\clist_if_empty:NF \l__piton_bg_color_clist
{
\dim_compare:nNnT \l__piton_left_margin_dim = \c_zero_dim
- { \skip_horizontal:n { 0.5 em } }
+ { \skip_horizontal:n { 0.5 em } }
}
\coffin_typeset:Nnnnn \l_tmpa_coffin T l \c_zero_dim \c_zero_dim
}
\box_set_dp:Nn \l_tmpa_box { \box_dp:N \l_tmpa_box + 1.25 pt }
\box_set_ht:Nn \l_tmpa_box { \box_ht:N \l_tmpa_box + 1.25 pt }
+ \mode_leave_vertical:
\clist_if_empty:NTF \l__piton_bg_color_clist
{ \box_use_drop:N \l_tmpa_box }
{
@@ -339,7 +364,6 @@
\box_use_drop:N \l_tmpa_box
}
}
- \vspace { - 2.5 pt }
\group_end:
\tl_gclear:N \g__piton_begin_line_hook_tl
}
@@ -360,10 +384,10 @@
{
\int_set:Nn \l_tmpa_int { \clist_count:N #1 }
\int_set:Nn \l_tmpb_int { \int_mod:nn \g__piton_line_int \l_tmpa_int + 1 }
- \tl_set:Nx \l_tmpa_tl { \clist_item:Nn #1 \l_tmpb_int }
+ \tl_set:Ne \l_tmpa_tl { \clist_item:Nn #1 \l_tmpb_int }
\tl_if_eq:NnTF \l_tmpa_tl { none }
{ \dim_zero:N \l__piton_width_dim }
- { \exp_args:NV \__piton_color_i:n \l_tmpa_tl }
+ { \exp_args:No \__piton_color_i:n \l_tmpa_tl }
}
\cs_set_protected:Npn \__piton_color_i:n #1
{
@@ -377,20 +401,23 @@
}
\cs_new_protected:Npn \__piton_newline:
{
+ \bool_if:NT \g__piton_footnote_bool \endsavenotes
\int_gincr:N \g__piton_line_int
- \int_compare:nNnT \g__piton_line_int > { \l__piton_splittable_int - 1 }
+ \par
+ \kern -2.5 pt
+ \int_case:nn
{
- \int_compare:nNnT
- { \l__piton_nb_lines_int - \g__piton_line_int + 1 } > \l__piton_splittable_int
+ \lua_now:e
{
- \egroup
- \bool_if:NT \g__piton_footnote_bool \endsavenotes
- \par
- \mode_leave_vertical:
- \bool_if:NT \g__piton_footnote_bool \savenotes
- \vtop \bgroup
+ tex.sprint
+ (
+ luatexbase.catcodetables.expl ,
+ tostring ( piton.lines_status [ \int_use:N \g__piton_line_int ] )
+ )
}
- }
+ }
+ { 1 { \penalty 100 } 2 \nobreak }
+ \bool_if:NT \g__piton_footnote_bool \savenotes
}
\cs_set_protected:Npn \__piton_breakable_space:
{
@@ -429,6 +456,7 @@
\int_new:N \l__piton_number_lines_start_int
\bool_new:N \l__piton_resume_bool
\bool_new:N \l__piton_split_on_empty_lines_bool
+\bool_new:N \l__piton_splittable_on_empty_lines_bool
\keys_define:nn { PitonOptions / marker }
{
beginning .code:n = \cs_set:Nn \__piton_marker_beginning:n { #1 } ,
@@ -493,15 +521,15 @@
\keys_define:nn { PitonOptions }
{
detected-commands .code:n =
- \lua_now:n { piton.addDetectedCommands('#1') } ,
+ \lua_now:n { piton.addDetectedCommands('#1') } ,
detected-commands .value_required:n = true ,
detected-commands .usage:n = preamble ,
detected-beamer-commands .code:n =
- \lua_now:n { piton.addBeamerCommands('#1') } ,
+ \lua_now:n { piton.addBeamerCommands('#1') } ,
detected-beamer-commands .value_required:n = true ,
detected-beamer-commands .usage:n = preamble ,
detected-beamer-environments .code:n =
- \lua_now:n { piton.addBeamerEnvironments('#1') } ,
+ \lua_now:n { piton.addBeamerEnvironments('#1') } ,
detected-beamer-environments .value_required:n = true ,
detected-beamer-environments .usage:n = preamble ,
begin-escape .code:n =
@@ -532,7 +560,7 @@
math-comments .default:n = true ,
math-comments .usage:n = preamble ,
language .code:n =
- \str_set:Nx \l_piton_language_str { \str_lowercase:n { #1 } } ,
+ \str_set:Ne \l_piton_language_str { \str_lowercase:n { #1 } } ,
language .value_required:n = true ,
path .code:n =
\seq_clear:N \l__piton_path_seq
@@ -545,6 +573,8 @@
path .initial:n = . ,
path-write .str_set:N = \l__piton_path_write_str ,
path-write .value_required:n = true ,
+ font-command .tl_set:N = \l__piton_font_command_tl ,
+ font-command .value_required:n = true ,
gobble .int_set:N = \l__piton_gobble_int ,
gobble .value_required:n = true ,
auto-gobble .code:n = \int_set:Nn \l__piton_gobble_int { -1 } ,
@@ -554,6 +584,9 @@
tabs-auto-gobble .code:n = \int_set:Nn \l__piton_gobble_int { -3 } ,
tabs-auto-gobble .value_forbidden:n = true ,
+ splittable-on-empty-lines .bool_set:N = \l__piton_splittable_on_empty_lines_bool ,
+ splittable-on-empty-lines .default:n = true ,
+
split-on-empty-lines .bool_set:N = \l__piton_split_on_empty_lines_bool ,
split-on-empty-lines .default:n = true ,
@@ -650,6 +683,10 @@
} ,
range .value_required:n = true ,
+ env-used-by-split .code:n =
+ \lua_now:n { piton.env_used_by_split = '#1'} ,
+ env-used-by-split .initial:n = Piton ,
+
resume .meta:n = line-numbers/resume ,
unknown .code:n = \__piton_error:n { Unknown~key~for~PitonOptions } ,
@@ -659,10 +696,6 @@
\bool_set_true:N \l__piton_line_numbers_bool
\bool_set_false:N \l__piton_skip_empty_lines_bool ,
all-line-numbers .value_forbidden:n = true ,
-
- % deprecated
- numbers-sep .dim_set:N = \l__piton_numbers_sep_dim ,
- numbers-sep .value_required:n = true
}
\cs_new_protected:Npn \__piton_in_PitonInputFile:n #1
{
@@ -700,7 +733,7 @@
\tl_if_empty:NF \g__piton_aux_tl
{
\iow_now:Nn \@mainaux { \ExplSyntaxOn }
- \iow_now:Nx \@mainaux
+ \iow_now:Ne \@mainaux
{
\tl_gset:cn { c__piton_ \int_use:N \g__piton_env_int _ tl }
{ \exp_not:o \g__piton_aux_tl }
@@ -711,7 +744,7 @@
}
\cs_new_protected:Npn \__piton_width_to_aux:
{
- \tl_gput_right:Nx \g__piton_aux_tl
+ \tl_gput_right:Ne \g__piton_aux_tl
{
\dim_set:Nn \l__piton_line_width_dim
{ \dim_eval:n { \g__piton_tmp_width_dim } }
@@ -743,7 +776,7 @@
}
\cs_new_protected:Npn \__piton_NewPitonLanguage:nnn #1 #2 #3
{
- \tl_set:Nx \l_tmpa_tl
+ \tl_set:Ne \l_tmpa_tl
{
\tl_if_blank:nF { #1 } { [ \str_lowercase:n { #1 } ] }
\str_lowercase:n { #2 }
@@ -750,7 +783,7 @@
}
\keys_set:nn { NewPitonLanguage } { #3 }
\prop_gput:Non \g__piton_languages_prop \l_tmpa_tl { #3 }
- \exp_args:NV \__piton_NewPitonLanguage:nn \l_tmpa_tl { #3 }
+ \exp_args:No \__piton_NewPitonLanguage:nn \l_tmpa_tl { #3 }
}
\cs_new_protected:Npn \__piton_NewPitonLanguage:nn #1 #2
{
@@ -759,14 +792,14 @@
}
\cs_new_protected:Npn \__piton_NewPitonLanguage:nnnnn #1 #2 #3 #4 #5
{
- \tl_set:Nx \l_tmpa_tl
+ \tl_set:Ne \l_tmpa_tl
{
\tl_if_blank:nF { #3 } { [ \str_lowercase:n { #3 } ] }
\str_lowercase:n { #4 }
}
- \prop_get:NoNTF \g__piton_languages_prop \l_tmpa_tl \l_tmpb_tl
- { \__piton_NewPitonLanguage:nnno { #1 } { #2 } { #5 } \l_tmpb_tl }
- { \__piton_error:n { Language~not~defined } }
+ \prop_get:NoNTF \g__piton_languages_prop \l_tmpa_tl \l_tmpb_tl
+ { \__piton_NewPitonLanguage:nnno { #1 } { #2 } { #5 } \l_tmpb_tl }
+ { \__piton_error:n { Language~not~defined } }
}
\cs_new_protected:Npn \__piton_NewPitonLanguage:nnnn #1 #2 #3 #4
{ \__piton_NewPitonLanguage:nnn { #1 } { #2 } { #4 , #3 } }
@@ -783,9 +816,8 @@
\cs_set_eq:NN \} \c_right_brace_str
\cs_set_eq:NN \$ \c_dollar_str
\cs_set_eq:cN { ~ } \space
- \cs_set_protected:Npn \__piton_begin_line: { }
- \cs_set_protected:Npn \__piton_end_line: { }
- \tl_set:Nx \l_tmpa_tl
+ \cs_set_eq:NN \__piton_begin_line: \prg_do_nothing:
+ \tl_set:Ne \l_tmpa_tl
{
\lua_now:e
{ piton.ParseBis('\l_piton_language_str',token.scan_string()) }
@@ -798,9 +830,9 @@
{ \regex_replace_all:nnN { \x20 } { \x20 } \l_tmpa_tl }
}
\if_mode_math:
- \text { \ttfamily \l_tmpa_tl }
+ \text { \l__piton_font_command_tl \l_tmpa_tl }
\else:
- \ttfamily \l_tmpa_tl
+ \l__piton_font_command_tl \l_tmpa_tl
\fi:
\group_end:
}
@@ -807,11 +839,10 @@
\NewDocumentCommand { \__piton_piton_verbatim } { v }
{
\group_begin:
- \ttfamily
+ \l__piton_font_command_tl
\automatichyphenmode = 1
- \cs_set_protected:Npn \__piton_begin_line: { }
- \cs_set_protected:Npn \__piton_end_line: { }
- \tl_set:Nx \l_tmpa_tl
+ \cs_set_eq:NN \__piton_begin_line: \prg_do_nothing:
+ \tl_set:Ne \l_tmpa_tl
{
\lua_now:e
{ piton.Parse('\l_piton_language_str',token.scan_string()) }
@@ -824,32 +855,21 @@
}
\cs_new_protected:Npn \__piton_piton:n #1
+ { \tl_if_blank:nF { #1 } { \__piton_piton_i:n { #1 } } }
+
+\cs_new_protected:Npn \__piton_piton_i:n #1
{
\group_begin:
- \cs_set_protected:Npn \__piton_begin_line: { }
- \cs_set_protected:Npn \__piton_end_line: { }
+ \cs_set_eq:NN \__piton_begin_line: \prg_do_nothing:
\cs_set:cpn { pitonStyle _ \l_piton_language_str _ Prompt } { }
\cs_set:cpn { pitonStyle _ Prompt } { }
\cs_set_eq:NN \__piton_trailing_space: \space
- \bool_lazy_or:nnTF
- \l__piton_break_lines_in_piton_bool
- \l__piton_break_lines_in_Piton_bool
+ \tl_set:Ne \l_tmpa_tl
{
- \tl_set:Nx \l_tmpa_tl
- {
- \lua_now:e
- { piton.ParseTer('\l_piton_language_str',token.scan_string()) }
- { #1 }
- }
+ \lua_now:e
+ { piton.ParseTer('\l_piton_language_str',token.scan_string()) }
+ { #1 }
}
- {
- \tl_set:Nx \l_tmpa_tl
- {
- \lua_now:e
- { piton.Parse('\l_piton_language_str',token.scan_string()) }
- { #1 }
- }
- }
\bool_if:NT \l__piton_show_spaces_bool
{ \regex_replace_all:nnN { \x20 } { ␣ } \l_tmpa_tl } % U+2423
\exp_args:No \__piton_replace_spaces:n \l_tmpa_tl
@@ -884,7 +904,7 @@
{ #2 }
\int_to_arabic:n
{ \g__piton_visual_line_int + \l__piton_nb_non_empty_lines_int }
- }
+ }
{
\int_to_arabic:n
{ \g__piton_visual_line_int + \l__piton_nb_lines_int }
@@ -930,14 +950,15 @@
####1
\c_backslash_str end \c_left_brace_str #1 \c_right_brace_str
}
- {
+ {
\group_end:
\mode_if_vertical:TF { \noindent \mode_leave_vertical: } \newline
+ \lua_now:e { piton.CountLines ( '\lua_escape:n{##1}' ) }
\__piton_compute_left_margin:nn { CountNonEmptyLines } { ##1 }
\__piton_compute_width:
- \ttfamily
+ \l__piton_font_command_tl
\dim_zero:N \parskip
- \noindent % added 2024/08/07
+ \noindent
\str_if_empty:NTF \l__piton_path_write_str
{ \lua_now:e { piton.write = "\l__piton_write_str" } }
{
@@ -947,16 +968,16 @@
\str_if_empty:NTF \l__piton_write_str
{ \lua_now:n { piton.write = '' } }
{
- \seq_if_in:NVTF \g__piton_write_seq \l__piton_write_str
+ \seq_if_in:NoTF \g__piton_write_seq \l__piton_write_str
{ \lua_now:n { piton.write_mode = "a" } }
{
\lua_now:n { piton.write_mode = "w" }
- \seq_gput_left:NV \g__piton_write_seq \l__piton_write_str
+ \seq_gput_left:No \g__piton_write_seq \l__piton_write_str
}
}
\bool_if:NTF \l__piton_split_on_empty_lines_bool
- \__piton_gobble_split_parse:n
- \__piton_gobble_parse:n
+ \__piton_retrieve_gobble_split_parse:n
+ \__piton_retrieve_gobble_parse:n
{ ##1 }
\bool_if:NT \l__piton_width_min_bool \__piton_width_to_aux:
\end { #1 }
@@ -978,26 +999,30 @@
{ #4 }
\AddToHook { env / #1 / begin } { \char_set_catcode_other:N \^^M }
}
-\cs_new_protected:Npn \__piton_gobble_parse:n
+\cs_new_protected:Npn \__piton_retrieve_gobble_parse:n
{
\lua_now:e
{
- piton.GobbleParse
+ piton.RetrieveGobbleParse
(
'\l_piton_language_str' ,
\int_use:N \l__piton_gobble_int ,
+ \bool_if:NTF \l__piton_splittable_on_empty_lines_bool
+ { \int_eval:n { - \l__piton_splittable_int } }
+ { \int_use:N \l__piton_splittable_int } ,
token.scan_argument ( )
)
}
}
-\cs_new_protected:Npn \__piton_gobble_split_parse:n
+\cs_new_protected:Npn \__piton_retrieve_gobble_split_parse:n
{
\lua_now:e
{
- piton.GobbleSplitParse
+ piton.RetrieveGobbleSplitParse
(
'\l_piton_language_str' ,
\int_use:N \l__piton_gobble_int ,
+ \int_use:N \l__piton_splittable_int ,
token.scan_argument ( )
)
}
@@ -1021,18 +1046,33 @@
\NewDocumentCommand { \PitonInputFileTF } { d < > O { } m m m }
{
\group_begin:
- \bool_set_false:N \l_tmpa_bool
- \seq_map_inline:Nn \l__piton_path_seq
+ \bool_if:NTF \l__piton_old_PitonInputFile_bool
{
- \str_set:Nn \l__piton_file_name_str { ##1 / #3 }
- \file_if_exist:nT { \l__piton_file_name_str }
+ \bool_set_false:N \l_tmpa_bool
+ \seq_map_inline:Nn \l__piton_path_seq
{
+ \str_set:Nn \l__piton_file_name_str { ##1 / #3 }
+ \file_if_exist:nT { \l__piton_file_name_str }
+ {
+ \__piton_input_file:nn { #1 } { #2 }
+ \bool_set_true:N \l_tmpa_bool
+ \seq_map_break:
+ }
+ }
+ \bool_if:NTF \l_tmpa_bool { #4 } { #5 }
+ }
+ {
+ \seq_concat:NNN
+ \l_file_search_path_seq
+ \l__piton_path_seq
+ \l_file_search_path_seq
+ \file_get_full_name:nNTF { #3 } \l__piton_file_name_str
+ {
\__piton_input_file:nn { #1 } { #2 }
- \bool_set_true:N \l_tmpa_bool
- \seq_map_break:
+ #4
}
+ { #5 }
}
- \bool_if:NTF \l_tmpa_bool { #4 } { #5 }
\group_end:
}
\cs_new_protected:Npn \__piton_unknown_file:n #1
@@ -1099,7 +1139,7 @@
\lua_now:e { piton.CountLinesFile ( '\l__piton_file_name_str' ) }
\__piton_compute_left_margin:no { CountNonEmptyLinesFile } \l__piton_file_name_str
\__piton_compute_width:
- \ttfamily
+ \l__piton_font_command_tl
\lua_now:e
{
piton.ParseFile(
@@ -1107,11 +1147,14 @@
'\l__piton_file_name_str' ,
\int_use:N \l__piton_first_line_int ,
\int_use:N \l__piton_last_line_int ,
+ \bool_if:NTF \l__piton_splittable_on_empty_lines_bool
+ { \int_eval:n { - \l__piton_splittable_int } }
+ { \int_use:N \l__piton_splittable_int } ,
\bool_if:NTF \l__piton_split_on_empty_lines_bool { 1 } { 0 } )
}
\bool_if:NT \l__piton_width_min_bool \__piton_width_to_aux:
\group_end:
- \exp_args:Nx \iow_log:n {(\l__piton_file_name_str)}
+ \iow_log:e {(\l__piton_file_name_str)}
\tl_if_novalue:nF { #1 }
{ \bool_if:NT \g__piton_beamer_bool { \end { uncoverenv } } }
\__piton_write_aux:
@@ -1118,10 +1161,10 @@
}
\cs_new_protected:Npn \__piton_compute_range:
{
- \str_set:Nx \l_tmpa_str { \__piton_marker_beginning:n \l__piton_begin_range_str }
- \str_set:Nx \l_tmpb_str { \__piton_marker_end:n \l__piton_end_range_str }
- \exp_args:NnV \regex_replace_all:nnN { \\\# } \c_hash_str \l_tmpa_str
- \exp_args:NnV \regex_replace_all:nnN { \\\# } \c_hash_str \l_tmpb_str
+ \str_set:Ne \l_tmpa_str { \__piton_marker_beginning:n \l__piton_begin_range_str }
+ \str_set:Ne \l_tmpb_str { \__piton_marker_end:n \l__piton_end_range_str }
+ \exp_args:Nno \regex_replace_all:nnN { \\\# } \c_hash_str \l_tmpa_str
+ \exp_args:Nno \regex_replace_all:nnN { \\\# } \c_hash_str \l_tmpb_str
\lua_now:e
{
piton.ComputeRange
@@ -1136,7 +1179,7 @@
\NewDocumentCommand { \SetPitonStyle } { O { } m }
{
\str_clear_new:N \l__piton_SetPitonStyle_option_str
- \str_set:Nx \l__piton_SetPitonStyle_option_str { \str_lowercase:n { #1 } }
+ \str_set:Ne \l__piton_SetPitonStyle_option_str { \str_lowercase:n { #1 } }
\str_if_eq:onT \l__piton_SetPitonStyle_option_str { current-language }
{ \str_set_eq:NN \l__piton_SetPitonStyle_option_str \l_piton_language_str }
\keys_set:nn { piton / Styles } { #2 }
@@ -1221,7 +1264,7 @@
\SetPitonStyle[OCaml]
{
TypeExpression =
- \SetPitonStyle { Identifier = \PitonStyle { Name.Type } } \__piton_piton:n
+ \SetPitonStyle { Identifier = \PitonStyle { Name.Type } } \__piton_piton:n ,
}
\clist_gput_left:Nn \g__piton_styles_clist { String }
\clist_gsort:Nn \g__piton_styles_clist
@@ -1267,10 +1310,10 @@
ParseAgain = \__piton_piton_no_cr:n ,
Discard = \use_none:n
}
-\AtBeginDocument
+\hook_gput_code:nnn { begindocument } { . }
{
\bool_if:NT \g__piton_math_comments_bool
- { \SetPitonStyle { Comment.Math = \__piton_math_scantokens:n } }
+ { \SetPitonStyle { Comment.Math = \__piton_math_scantokens:n } }
}
\NewDocumentCommand { \SetPitonIdentifier } { o m m }
{
@@ -1281,7 +1324,7 @@
{ \cs_set:cpn { PitonIdentifier _ ##1 } { #3 } }
}
{
- \str_set:Nx \l_tmpa_str { \str_lowercase:n { #1 } }
+ \str_set:Ne \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
@@ -1305,8 +1348,8 @@
\seq_if_exist:cF { g__piton_functions _ \l_piton_language_str _ seq }
{ \seq_new:c { g__piton_functions _ \l_piton_language_str _ seq } }
\seq_gput_right:cn { g__piton_functions _ \l_piton_language_str _ seq } { #1 }
- \seq_if_in:NVF \g__piton_languages_seq \l_piton_language_str
- { \seq_gput_left:NV \g__piton_languages_seq \l_piton_language_str }
+ \seq_if_in:NoF \g__piton_languages_seq \l_piton_language_str
+ { \seq_gput_left:No \g__piton_languages_seq \l_piton_language_str }
}
\NewDocumentCommand \PitonClearUserFunctions { ! o }
{
@@ -1413,7 +1456,7 @@
\__piton_msg_new:nn { SyntaxError }
{
Syntax~Error.\\
- Your~code~of~the~language~"\l_piton_language_str"~is~not~
+ Your~code~of~the~language~'\l_piton_language_str'~is~not~
syntactically~correct.\\
It~won't~be~printed~in~the~PDF~file.
}
@@ -1468,6 +1511,8 @@
end-of-broken-line,~
end-range,~
env-gobble,~
+ env-used-by-split,~
+ font-command,~
gobble,~
indent-broken-lines,~
language,~
@@ -1482,6 +1527,7 @@
show-spaces,~
show-spaces-in-strings,~
splittable,~
+ splittable-on-empty-lines,~
split-on-empty-lines,~
split-separation,~
tabs-auto-gobble,~
More information about the tex-live-commits
mailing list.