summaryrefslogtreecommitdiff
path: root/macros/luatex/latex/piton/piton.dtx
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2022-11-10 03:01:41 +0000
committerNorbert Preining <norbert@preining.info>2022-11-10 03:01:41 +0000
commit7ffc72f568b89a4914168cd6921510d226a48620 (patch)
treea5a1bfc5ecf8332877d82472c767a9db0b29fc15 /macros/luatex/latex/piton/piton.dtx
parent5de83ec843cdc88e6adc42b1fe3f0ec48c52b7f3 (diff)
CTAN sync 202211100301
Diffstat (limited to 'macros/luatex/latex/piton/piton.dtx')
-rw-r--r--macros/luatex/latex/piton/piton.dtx909
1 files changed, 659 insertions, 250 deletions
diff --git a/macros/luatex/latex/piton/piton.dtx b/macros/luatex/latex/piton/piton.dtx
index c381b9eb27..6bce058842 100644
--- a/macros/luatex/latex/piton/piton.dtx
+++ b/macros/luatex/latex/piton/piton.dtx
@@ -15,8 +15,8 @@
%
% \fi
% \iffalse
-\def\myfileversion{0.9}
-\def\myfiledate{2022/10/31}
+\def\myfileversion{0.95}
+\def\myfiledate{2022/11/09}
%
%
%<*batchfile>
@@ -56,10 +56,8 @@ version 2005/12/01 or later.
\fvset{commandchars=\~\#\@,formatcom=\color{gray}}
\captionsetup{labelfont = bf}
\usepackage{ragged2e}
-\usepackage[footnotehyper,escape-inside=$$]{piton} % $$
+\usepackage[footnotehyper,escape-inside=$$,math-comments]{piton} % $$
-
-\def\interitem{\vskip 7mm plus 2 mm minus 3mm}
\parindent 0pt
\skip\footins = 2\bigskipamount
@@ -118,7 +116,7 @@ version 2005/12/01 or later.
% return -arctan(-x) # recursive call
% elif x > 1:
% return pi/2 - arctan(1/x)
-% ## (we have used that $\arctan(x)+\arctan(1/x)=\frac{\pi}{2}$ for $x>0$)\footnote{This LaTeX escape has been done by beginning the comment by \ttfamily\#\#.}
+% #> (we have used that $\arctan(x)+\arctan(1/x)=\frac{\pi}{2}$ for $x>0$)\footnote{This LaTeX escape has been done by beginning the comment by \ttfamily\#>.}
% else:
% s = 0
% for k in range(n):
@@ -166,13 +164,12 @@ version 2005/12/01 or later.
% cf.~\ref{NewPitonEnvironment} p.~\pageref{NewPitonEnvironment}.
% \item The command |\PitonInputFile| is used to insert and typeset a whole
% external file.
+%
+% \colorbox{yellow!50}{\textbf{New 0.95}}\enskip The command |\PitonInputFile|
+% takes in as optional argument (between square brackets) two keys |first-line|
+% and |last-line|: only the part between the corresponding lines will be inserted.
% \end{itemize}
%
-% \bigskip
-% It's possible to compose comments in LaTeX by beginning them with |##| (it's a
-% ``LaTeX escape''). The characters |##| themselves won't be printed and the
-% spaces after |##| are removed. These comments will be called ``LaTeX
-% comments'' in this document.
%
% \section{Customization}
%
@@ -203,35 +200,40 @@ version 2005/12/01 or later.
% gobble is set by the position of the commands |\begin{Piton}| and
% |\end{Piton}| which delimit the current environment.
%
-% \item With the key |line-numbers|, the \emph{non empty} lines are numbered (on
-% the left) in the environments |{Piton}| and in the listings resulting from the
-% use of |\PitonInputFile|.
+% \item With the key |line-numbers|, the \emph{non empty} lines (and all the
+% lines of the \emph{docstrings}, even the empty ones) are numbered in the
+% environments |{Piton}| and in the listings resulting from the use of
+% |\PitonInputFile|.
%
% \item With the key |all-line-numbers|, \emph{all} the lines are numbered,
% including the empty ones.
%
% \item With the key |resume| the counter of lines is not set to zero at the
-% beginning of each environment |{Piton}| or use |\PitonInputFile| as it is
-% otherwise. That's allows a numbering of the lines accross several
-% environments. See an example part \ref{example-numbering} on
-% page~\pageref{example-numbering}.
+% beginning of each environment |{Piton}| or use of |\PitonInputFile| as it is
+% otherwise. That allows a numbering of the lines across several
+% environments.
%
% \item The key |left-margin| corresponds to a margin on the left. That key may
% be useful in conjonction with the key |line-numbers| or the key
% |line-all-numbers| if one does not want the numbers in an overlapping position
-% on the left.
+% on the left.
+%
+% \colorbox{yellow!50}{\textbf{New 0.95}}\enskip It's possible to use the key
+% |left-margin| with the value |auto|. With that value, if the key
+% |line-numbers| or the key |all-line-numbers| is used, a margin will be
+% automatically inserted to fit the numbers of lines. See an example part
+% \ref{example-numbering} on page~\pageref{example-numbering}.
%
-% \item The key |splittable| allows pages breaks within the environments
+% \item The key |splittable| allows page breaks within the environments
% |{Piton}| and the listings produced by
% |\PitonInputFile|.
%
% \smallskip
-% \colorbox{yellow!50}{\textbf{New 0.9}}\enskip It's possible to give as value to
-% the key |splittable| a positive integer~$n$. With that value, the environments
-% |{Piton}| and the listings produced by |\PitonInputFile| are splittable but no
-% page break can occur within the first $n$ lines and within the last $n$ lines.
-% The default value of the key |splittable| is, in fact, $1$, which allows pages
-% breaks everywhere.
+% It's possible to give as value to the key |splittable| a positive integer~$n$.
+% With that value, the environments |{Piton}| and the listings produced by
+% |\PitonInputFile| are splittable but no page break can occur within the first
+% $n$ lines and within the last $n$ lines. The default value of the key
+% |splittable| is, in fact, $1$, which allows pages breaks everywhere.
%
% \item The key |background-color| sets the background color of the environments
% |{Piton}| and the listings produced by |\PitonInputFile| (that background has
@@ -242,6 +244,19 @@ version 2005/12/01 or later.
% \pkg{tcolorbox} included in another environment of \pkg{tcolorbox} is
% \emph{not} breakable, even when both environments use the key |breakable| of
% \pkg{tcolorbox}.}
+%
+% \item \colorbox{yellow!50}{\textbf{New 0.95}}\enskip When the key
+% |show-spaces| is activated, the spaces in the short strings (that is to say
+% those delimited by |'| or |"|) are replaced by the character~␣ (U+2423 :
+% \textsc{open box}). Of course, that character~U+2423 must be present in the
+% monospaced font which is used.\footnote{The package \pkg{piton} simply uses
+% the current monospaced font. The best way to change that font is to use the
+% command \texttt{\textbackslash setmonofont} of \pkg{fontspec}.}
+%
+% \begingroup
+% \PitonOptions{show-spaces}
+% Example : \piton|my_string = 'Very good answer'|
+% \endgroup
% \end{itemize}
%
% \bigskip
@@ -261,7 +276,7 @@ version 2005/12/01 or later.
% return -arctan(-x) # recursive call
% elif x > 1:
% return pi/2 - arctan(1/x)
-% ## (we have used that $\arctan(x)+\arctan(1/x)=\frac{\pi}{2}$ pour $x>0$)
+% #> (we have used that $\arctan(x)+\arctan(1/x)=\frac{\pi}{2}$ pour $x>0$)
% else
% s = 0
% for k in range(n):
@@ -285,7 +300,7 @@ version 2005/12/01 or later.
% return -arctan(-x) # recursive call
% elif x > 1:
% return pi/2 - arctan(1/x)
-% ## (we have used that $\arctan(x)+\arctan(1/x)=\frac{\pi}{2}$ for $x>0$)
+% #> (we have used that $\arctan(x)+\arctan(1/x)=\frac{\pi}{2}$ for $x>0$)
% else
% s = 0
% for k in range(n):
@@ -294,51 +309,6 @@ version 2005/12/01 or later.
% \end{Piton}
% \endgroup
%
-% \subsection{The key escape-inside}
-%
-% The key |escape-inside| must be used when loading the package \pkg{piton}
-% (that is to say in the instruction |\usepackage|). For technical reasons, it
-% can't be used in the command |\PitonOptions|. That option takes in as value
-% two characters which will be used to delimit pieces of code which will
-% thrown directly to LaTeX (and composed by LaTeX).
-%
-% \medskip
-% In the following example, we assume that the extension \pkg{piton} has been
-% loaded by the following instruction.
-%
-% \begin{Verbatim}
-% \usepackage[~emphase#escape-inside=$$@]{piton}
-% \end{Verbatim}
-%
-% \medskip
-% In the following code, which is a recursive programmation of the mathematical
-% factorial, we decide to highlight in yellow the instruction which contains the
-% recursive call.
-% \begin{Verbatim}
-% \begin{Piton}
-% def fact(n):
-% if n==0:
-% return 1
-% else:
-% ~emphase#$\colorbox{yellow!50}{$@return n*fact(n-1)~emphase#$}$@
-% \end{Piton}
-% \end{Verbatim}
-%
-% \begin{Piton}
-% def fact(n):
-% if n==0:
-% return 1
-% else:
-% $\colorbox{yellow!50}{$return n*fact(n-1)$}$
-% \end{Piton}
-%
-% \bigskip
-%
-% \emph{Caution} : The escape to LaTeX allowed by the characters of
-% |escape-inside| is not active in the strings nor in the Python comments
-% (however, it's possible to have a whole Python comment composed in LaTeX by
-% beginning it with |##|; such comments are merely called ``LaTeX comments'' in
-% this document).
%
%
% \subsection{The styles}
@@ -420,7 +390,7 @@ version 2005/12/01 or later.
% to say after the keyword |class|) \\
% Exception & the names of the exceptions (eg: \texttt{SyntaxError}) \\
% Comment & the comments beginning with \verb|#| \\
-% Comment.LaTeX & the comments beginning by \verb|##|, which are composed in LaTeX by
+% Comment.LaTeX & the comments beginning by \verb|#>|, which are composed in LaTeX by
% \pkg{piton} (and simply called ``LaTeX comments'' in this document) \\
% Keyword.Constant & |True|, |False| and |None| \\
% Keyword & the following keywords :
@@ -477,6 +447,125 @@ version 2005/12/01 or later.
%
% \section{Advanced features}
%
+% \subsection{Mechanisms to escape to LaTeX}
+%
+% The package \pkg{piton} provides several mechanisms for escaping to LaTeX:
+% \begin{itemize}
+% \item It's possible to compose comments entirely in LaTeX.
+% \item It's possible to have the elements between \texttt{\$} in the comments
+% composed in LateX mathematical mode.
+% \item It's also possible to insert LaTeX code almost everywhere in a Python listing.
+% \end{itemize}
+%
+% \subsubsection{The ``LaTeX comments''}
+%
+% In this document, we call ``LaTeX comments'' the comments which begins by
+% |#>|. The code following those characters, until the end of the line, will be
+% composed as standard LaTeX code. There is two tools to customize those
+% comments.
+%
+% \begin{itemize}
+% \item It's possible to change the syntatic mark (which, by default, is |#>|).
+% For this purpose, there is a key |comment-latex| available at load-time (that
+% is to say at the |\usepackage|) which allows to choice the characters which,
+% preceded by |#|, will be the syntatic marker.
+%
+% For example, with the following loading:
+%
+% \quad \verb|\usepackage[comment-latex = LaTeX]{piton}|
+%
+% the LaTeX comments will begin by |#LaTeX|.
+%
+% If the key |comment-latex| is used with the empty value, all the Python
+% comments (which begins by |#|) will, in fact, be ``LaTeX comments''.
+%
+% \smallskip
+% \item \colorbox{yellow!50}{\bfseries New 0.95}\enskip It's possible to change
+% the formatting of the LaTeX comment itself by changing the \pkg{piton} style
+% |Comment.LaTeX|.
+%
+% For example, with |\SetPitonStyle{Comment.LaTeX = \normalfont\color{blue}}|,
+% the LaTeX comments will be composed in blue.
+%
+% For other examples of customization of the LaTeX comments, see the part
+% \ref{example-comments} p.~\pageref{example-comments}
+% \end{itemize}
+%
+% \subsubsection{The key ``math-comments''}
+%
+% \colorbox{yellow!50}{\textbf{New 0.95}}\enskip It's possible to request that,
+% in the standard Python comments (that is to say those beginning by |#| and not
+% |#>|), the elements between \texttt{\$} be composed in LaTeX mathematical mode
+% (the other elements of the comment being composed verbatim).
+%
+% That feature is activated by the key |math-comments| at load-time (that is to
+% say with the |\usepackage|).
+%
+% \medskip
+% In the following example, we assume that the key |math-comments| has been used
+% when loading \pkg{piton}.
+%
+% \begin{Verbatim}
+% \begin{Piton}
+% def square(x):
+% return x*x ~# compute $x^2$
+% \end{Piton}
+% \end{Verbatim}
+%
+% \begin{Piton}
+% def square(x):
+% return x*x # compute $x^2$
+% \end{Piton}
+%
+% \subsubsection{The mechanism ``escape-inside''}
+%
+% It's also possible to overwrite the Python listings to insert LaTeX code
+% almost everywhere. By default, \pkg{piton} does not fix any character for that
+% kind of escape.
+%
+% In order to use this mechanism, it's necessary to specify two characters which
+% will delimit the escape (one for the beginning and one for the end) by using
+% the key |escape-inside| at load-time (that is to say a the
+% |\begin{docuemnt}|).
+%
+% \medskip
+% In the following example, we assume that the extension \pkg{piton} has been
+% loaded by the following instruction.
+%
+% \begin{Verbatim}
+% \usepackage[~emphase#escape-inside=$$@]{piton}
+% \end{Verbatim}
+%
+% \medskip
+% In the following code, which is a recursive programmation of the mathematical
+% factorial, we decide to highlight in yellow the instruction which contains the
+% recursive call.
+% \begin{Verbatim}
+% \begin{Piton}
+% def fact(n):
+% if n==0:
+% return 1
+% else:
+% ~emphase#$\colorbox{yellow!50}{$@return n*fact(n-1)~emphase#$}$@
+% \end{Piton}
+% \end{Verbatim}
+%
+% \begin{Piton}
+% def fact(n):
+% if n==0:
+% return 1
+% else:
+% $\colorbox{yellow!50}{$return n*fact(n-1)$}$
+% \end{Piton}
+%
+% \bigskip
+%
+% \emph{Caution} : The escape to LaTeX allowed by the characters of
+% |escape-inside| is not active in the strings nor in the Python comments
+% (however, it's possible to have a whole Python comment composed in LaTeX by
+% beginning it with |#>|; such comments are merely called ``LaTeX comments'' in
+% this document).
+%
% \subsection{Footnotes in the environments of piton}
%
% \label{footnote}
@@ -514,12 +603,16 @@ version 2005/12/01 or later.
% \subsection{Tabulations}
%
% \smallskip
-% \colorbox{yellow!50}{\textbf{New 0.9}}\enskip 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 characters U+0009) at the
-% beginning of the lines. Each character U+0009 is replaced by $n$~spaces. The
-% initial value of $n$ is $4$ but it's possible to change it with the key
-% |tab-size| of |\PitonOptions|.
+% 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
+% characters U+0009) at the beginning of the lines. Each character U+0009 is
+% replaced by $n$~spaces. The initial value of $n$ is $4$ but it's possible to
+% change it with the key |tab-size| of |\PitonOptions|.
+%
+% \smallskip
+% \emph{Remark}: Unlike with the package \pkg{listings}, the key |gobble| and
+% its variants (|auto-gobble| and |env-gobble|) are applied \emph{before} the
+% transformation of the characters of tabulation in spaces.
%
% \section{Examples}
%
@@ -533,21 +626,21 @@ version 2005/12/01 or later.
% By default, the numbers of the lines are composed by \pkg{piton} in an
% overlapping position on the left (by using internally the command |\llap| of LaTeX).
%
-% In order to avoid that overlapping, it's necessary to reserve a place for the
-% number of the lines with the key |left-margin|.
-%
+% In order to avoid that overlapping, it's possible to use the option |left-margin=auto|
+% which will insert automatically a margin adapted to the numbers of lines that
+% will be written (that margin is larger when the numbers are greater than~10).
%
%
% \begingroup
% \fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
% \begin{Verbatim}
-% ~emphase&\PitonOptions{background-color=gray!10, left-margin = 5mm, line-numbers}@
+% ~emphase&\PitonOptions{background-color=gray!10, left-margin = auto, line-numbers}@
% \begin{Piton}
% def arctan(x,n=10):
% if x < 0:
-% return -arctan(-x) ## (appel récursif)
+% return -arctan(-x) #> (appel récursif)
% elif x > 1:
-% return pi/2 - arctan(1/x) ## (autre appel récursif)
+% return pi/2 - arctan(1/x) #> (autre appel récursif)
% else:
% return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) )
% \end{Piton}
@@ -557,13 +650,13 @@ version 2005/12/01 or later.
%
%
% \begingroup
-% \PitonOptions{background-color=gray!10,left-margin = 5mm, line-numbers}
+% \PitonOptions{background-color=gray!10,left-margin = auto, line-numbers}
% \begin{Piton}
% def arctan(x,n=10):
% if x < 0:
-% return -arctan(-x) ## (appel récursif)
+% return -arctan(-x) #> (appel récursif)
% elif x > 1:
-% return pi/2 - arctan(1/x) ## (autre appel récursif)
+% return pi/2 - arctan(1/x) #> (autre appel récursif)
% else:
% return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) )
% \end{Piton}
@@ -571,11 +664,13 @@ version 2005/12/01 or later.
%
%
%
-%
+% \bigskip
% \subsection{Formatting of the LaTeX comments}
%
+% \label{example-comments}
+%
% It's possible to modify the style |Comment.LaTeX| (with |\SetPitonStyle|) in
-% order to display the LaTeX comments (which begin with |##|) aligned on the
+% order to display the LaTeX comments (which begin with |#>|) aligned on the
% right margin.
%
%
@@ -587,9 +682,9 @@ version 2005/12/01 or later.
% \begin{Piton}
% def arctan(x,n=10):
% if x < 0:
-% return -arctan(-x) ## appel récursif
+% return -arctan(-x) #> appel récursif
% elif x > 1:
-% return pi/2 - arctan(1/x) ## autre appel récursif
+% return pi/2 - arctan(1/x) #> autre appel récursif
% else:
% return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) )
% \end{Piton}
@@ -602,9 +697,9 @@ version 2005/12/01 or later.
% \begin{Piton}
% def arctan(x,n=10):
% if x < 0:
-% return -arctan(-x) ## appel récursif
+% return -arctan(-x) #> appel récursif
% elif x > 1:
-% return pi/2 - arctan(1/x) ## autre appel récursif
+% return pi/2 - arctan(1/x) #> autre appel récursif
% else:
% return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) )
% \end{Piton}
@@ -626,9 +721,9 @@ version 2005/12/01 or later.
% \begin{Piton}
% def arctan(x,n=10):
% if x < 0:
-% return -arctan(-x) ## appel récursif
+% return -arctan(-x) #> appel récursif
% elif x > 1:
-% return pi/2 - arctan(1/x) ## autre appel récursif
+% return pi/2 - arctan(1/x) #> autre appel récursif
% else:
% s = 0
% for k in range(n):
@@ -649,9 +744,9 @@ version 2005/12/01 or later.
% \begin{Piton}
% def arctan(x,n=10):
% if x < 0:
-% return -arctan(-x) ## appel récursif
+% return -arctan(-x) #> appel récursif
% elif x > 1:
-% return pi/2 - arctan(1/x) ## autre appel récursif
+% return pi/2 - arctan(1/x) #> autre appel récursif
% else:
% s = 0
% for k in range(n):
@@ -662,7 +757,7 @@ version 2005/12/01 or later.
% \endgroup
%
%
-%
+% \bigskip
% \subsection{Notes in the listings}
%
% \label{notes-examples}
@@ -674,7 +769,7 @@ version 2005/12/01 or later.
% loaded with the key |footnotehyper|.
%
% Of course, in an environment |{Piton}|, a command |\footnote| may appear only
-% within a LaTeX comment (which begins with |##|). It's possible to have comments
+% within a LaTeX comment (which begins with |#>|). It's possible to have comments
% which contain only that command |\footnote|. That's the case in the following example.
%
%
@@ -686,9 +781,9 @@ version 2005/12/01 or later.
% \begin{Piton}
% def arctan(x,n=10):
% if x < 0:
-% return -arctan(-x)~emphase&##\footnote{First recursive call.}]@
+% return -arctan(-x)~emphase&#>\footnote{First recursive call.}]@
% elif x > 1:
-% return pi/2 - arctan(1/x)~emphase&##\footnote{Second recursive call.}@
+% return pi/2 - arctan(1/x)~emphase&#>\footnote{Second recursive call.}@
% else:
% return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) )
% \end{Piton}
@@ -700,9 +795,9 @@ version 2005/12/01 or later.
% \begin{Piton}
% def arctan(x,n=10):
% if x < 0:
-% return -arctan(-x)##\footnote{First recursive call.}
+% return -arctan(-x)#>\footnote{First recursive call.}
% elif x > 1:
-% return pi/2 - arctan(1/x)##\footnote{Second recursive call.}
+% return pi/2 - arctan(1/x)#>\footnote{Second recursive call.}
% else:
% return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) )
% \end{Piton}
@@ -724,9 +819,9 @@ version 2005/12/01 or later.
% \begin{Piton}
% def arctan(x,n=10):
% if x < 0:
-% return -arctan(-x)~emphase&##\footnote{First recursive call.}@
+% return -arctan(-x)~emphase&#>\footnote{First recursive call.}@
% elif x > 1:
-% return pi/2 - arctan(1/x)~emphase&##\footnote{Second recursive call.}@
+% return pi/2 - arctan(1/x)~emphase&#>\footnote{Second recursive call.}@
% else:
% return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) )
% \end{Piton}
@@ -740,9 +835,9 @@ version 2005/12/01 or later.
% \begin{Piton}
% def arctan(x,n=10):
% if x < 0:
-% return -arctan(-x)##\footnote{First recursive call.}
+% return -arctan(-x)#>\footnote{First recursive call.}
% elif x > 1:
-% return pi/2 - arctan(1/x)##\footnote{Second recursive call.}
+% return pi/2 - arctan(1/x)#>\footnote{Second recursive call.}
% else:
% return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) )
% \end{Piton}
@@ -766,9 +861,9 @@ version 2005/12/01 or later.
% \begin{Piton}
% def arctan(x,n=10):
% if x < 0:
-% return -arctan(-x)~emphase&##\footnote{First recursive call.}@
+% return -arctan(-x)~emphase&#>\footnote{First recursive call.}@
% elif x > 1:
-% return pi/2 - arctan(1/x)~emphase&##\footnote{Second recursive call.}@
+% return pi/2 - arctan(1/x)~emphase&#>\footnote{Second recursive call.}@
% else:
% return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) )
% \end{Piton}
@@ -785,15 +880,16 @@ version 2005/12/01 or later.
% \begin{Piton}
% def arctan(x,n=10):
% if x < 0:
-% return -arctan(-x)##\footnote{First recursive call.}
+% return -arctan(-x)#>\footnote{First recursive call.}
% elif x > 1:
-% return pi/2 - arctan(1/x)##\footnote{Second recursive call.}
+% return pi/2 - arctan(1/x)#>\footnote{Second recursive call.}
% else:
% return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) )
% \end{Piton}
% \end{minipage}
% \end{savenotes}
%
+% \bigskip
%
% \subsection{An example of tuning of the styles}
%
@@ -869,7 +965,7 @@ version 2005/12/01 or later.
% return -arctan(-x) # appel récursif
% elif x > 1:
% return pi/2 - arctan(1/x)
-% ## (we have used that $\arctan(x)+\arctan(1/x)=\pi/2$ for $x>0$)
+% #> (we have used that $\arctan(x)+\arctan(1/x)=\pi/2$ for $x>0$)
% else:
% s = 0
% for k in range(n):
@@ -879,6 +975,66 @@ version 2005/12/01 or later.
%
% \endgroup
%
+% \subsection{Use with pyluatex}
+%
+% The package \pkg{pyluatex} is an extension which allows the execution of some
+% Python code from |lualatex| (provided that Python is installed on the machine
+% and that the compilation is done with |lualatex| and |--shell-escape|).
+%
+% Here is, for example, an environment |{PitonExecute}| which formats a Python
+% listing (with \pkg{piton}) but display also the output of the execution of the
+% code with Python.
+%
+%
+% \begin{Verbatim}
+% \ExplSyntaxOn
+% \NewDocumentEnvironment { ~emphase#PitonExecute@ } { ! O { } }
+% {
+% \PyLTVerbatimEnv
+% \begin{pythonq}
+% }
+% {
+% \end{pythonq}
+% \directlua
+% {
+% tex.print("\\PitonOptions{~#1}")
+% tex.print("\\begin{Piton}")
+% tex.print(pyluatex.get_last_code())
+% tex.print("\\end{Piton}")
+% tex.print("")
+% }
+% \begin{center}
+% \directlua{tex.print(pyluatex.get_last_output())}
+% \end{center}
+% }
+% \ExplSyntaxOff
+% \end{Verbatim}
+%
+% \ExplSyntaxOn
+% \NewDocumentEnvironment { PitonExecute } { ! O { } }
+% {
+% \PyLTVerbatimEnv
+% \begin{pythonq}
+% }
+% {
+% \end{pythonq}
+% \directlua
+% {
+% tex.print("\\PitonOptions{~#1}")
+% tex.print("\\begin{Piton}")
+% tex.print(pyluatex.get_last_code())
+% tex.print("\\end{Piton}")
+% tex.print("")
+% }
+% \begin{center}
+% \directlua{tex.print(pyluatex.get_last_output())}
+% \end{center}
+% }
+% \ExplSyntaxOff
+%
+% This environment |{PitonExecute}| takes in as optional argument (between
+% square brackets) the options of the command |\PitonOptions|.
+%
%
% \bigskip
% \clearpage
@@ -1048,6 +1204,12 @@ version 2005/12/01 or later.
% \begin{macrocode}
\bool_new:N \c_@@_footnote_bool
% \end{macrocode}
+%
+% \medskip
+% The following boolean corresponds to the key |math-comments| (only at load-time).
+% \begin{macrocode}
+\bool_new:N \c_@@_math_comments_bool
+% \end{macrocode}
%
% \bigskip
% We define a set of keys for the options at load-time.
@@ -1058,6 +1220,10 @@ version 2005/12/01 or later.
footnotehyper .bool_set:N = \c_@@_footnotehyper_bool ,
escape-inside .tl_set:N = \c_@@_escape_inside_tl ,
escape-inside .initial:n = ,
+ comment-latex .code:n = { \lua_now:n { comment_latex = "#1" } } ,
+ comment-latex .value_required:n = true ,
+ math-comments .bool_set:N = \c_@@_math_comments_bool ,
+ math-comments .default:n = true ,
unknown .code:n = \msg_error:nn { piton } { unknown~key~for~package }
}
% \end{macrocode}
@@ -1067,12 +1233,12 @@ version 2005/12/01 or later.
{
Unknown~key.\\
You~have~used~the~key~'\l_keys_key_str'~but~the~only~keys~available~here~
- are~'escape-inside',~'footnote'~and~'footnotehyper'.~Other~keys~are~
- available~in~\token_to_str:N \PitonOptions.\\
+ are~'comment-latex',~'escape-inside',~'footnote',~'footnotehyper'~and~
+ 'math-comments'.~Other~keys~are~available~in~\token_to_str:N \PitonOptions.\\
That~key~will~be~ignored.
}
% \end{macrocode}
-%
+%
% \bigskip
% We process the options provided by the user at load-time.
% \begin{macrocode}
@@ -1084,8 +1250,8 @@ version 2005/12/01 or later.
\begingroup
\cs_new_protected:Npn \@@_set_escape_char:nn #1 #2
{
- \lua_now:n { begin_escape = "#1" }
- \lua_now:n { end_escape = "#2" }
+ \lua_now:n { piton_begin_escape = "#1" }
+ \lua_now:n { piton_end_escape = "#2" }
}
\cs_generate_variant:Nn \@@_set_escape_char:nn { x x }
\@@_set_escape_char:xx
@@ -1188,6 +1354,11 @@ version 2005/12/01 or later.
\int_new:N \l_@@_nb_lines_int
% \end{macrocode}
%
+% The same for the number of non-empty lines of the Python codes.
+% \begin{macrocode}
+\int_new:N \l_@@_nb_non_empty_lines_int
+% \end{macrocode}
+%
% The following counter will be used to count the lines during the composition.
% It will count all the lines, empty or not empty. It won't be used to print the
% numbers of the lines.
@@ -1252,7 +1423,9 @@ version 2005/12/01 or later.
% \end{macrocode}
%
% \medskip
-% The following dimension corresponds to the key |left-margin| of |\PitonOptions|.
+% The following dimension corresponds to the key |left-margin| of
+% |\PitonOptions|. By convention, when the final user will uses
+% |left-margin=auto|, |\l_@@_left_margin_dim| will be equal to -1~cm.
% \begin{macrocode}
\dim_new:N \l_@@_left_margin_dim
% \end{macrocode}
@@ -1274,32 +1447,18 @@ version 2005/12/01 or later.
\@@_set_tab_tl:n { 4 }
% \end{macrocode}
%
-% \medskip
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_newline:
- {
- \int_gincr:N \g_@@_line_int
- \int_compare:nNnT \g_@@_line_int > { \l_@@_splittable_int - 1 }
- {
- \int_compare:nNnT
- { \l_@@_nb_lines_int - \g_@@_line_int } > \l_@@_splittable_int
- {
- \egroup
- \bool_if:NT \c_@@_footnote_bool { \end { savenotes } }
- \newline
- \bool_if:NT \c_@@_footnote_bool { \begin { savenotes } }
- \vtop \bgroup
- }
- }
- }
-% \end{macrocode}
-%
% \medskip
% The following integer corresponds to the key |gobble|.
% \begin{macrocode}
\int_new:N \l_@@_gobble_int
% \end{macrocode}
%
+% \medskip
+% \begin{macrocode}
+\tl_new:N \l_@@_space_tl
+\tl_set:Nn \l_@@_space_tl { ~ }
+% \end{macrocode}
+%
% \bigskip
% \subsubsection{Treatment of a line of code}
%
@@ -1364,6 +1523,25 @@ version 2005/12/01 or later.
}
% \end{macrocode}
%
+% \bigskip
+% \begin{macrocode}
+\cs_new_protected:Npn \@@_newline:
+ {
+ \int_gincr:N \g_@@_line_int
+ \int_compare:nNnT \g_@@_line_int > { \l_@@_splittable_int - 1 }
+ {
+ \int_compare:nNnT
+ { \l_@@_nb_lines_int - \g_@@_line_int } > \l_@@_splittable_int
+ {
+ \egroup
+ \bool_if:NT \c_@@_footnote_bool { \end { savenotes } }
+ \newline
+ \bool_if:NT \c_@@_footnote_bool { \begin { savenotes } }
+ \vtop \bgroup
+ }
+ }
+ }
+% \end{macrocode}
%
% \bigskip
% \subsubsection{PitonOptions}
@@ -1409,10 +1587,15 @@ version 2005/12/01 or later.
background-color .value_required:n = true ,
slim .bool_set:N = \l_@@_slim_bool ,
slim .default:n = true ,
- left-margin .dim_set:N = \l_@@_left_margin_dim ,
+ left-margin .code:n =
+ \str_if_eq:nnTF { #1 } { auto }
+ { \dim_set:Nn \l_@@_left_margin_dim { -1cm } }
+ { \dim_set:Nn \l_@@_left_margin_dim { #1 } } ,
left-margin .value_required:n = true ,
tab-size .code:n = \@@_set_tab_tl:n { #1 } ,
tab-size .value_required:n = true ,
+ show-spaces .code:n = \tl_set:Nn \l_@@_space_tl { ␣ } , % U+2423
+ show-spaces .value_forbidden:n = true ,
unknown .code:n =
\msg_error:nn { piton } { Unknown~key~for~PitonOptions }
}
@@ -1426,7 +1609,7 @@ version 2005/12/01 or later.
Unknown~key. \\
The~key~'\l_keys_key_str'~is~unknown~for~\token_to_str:N \PitonOptions.~The~
available~keys~are:~all-line-numbers,~auto-gobble,~env-gobble,~gobble,~
- left-margin,~line-numbers,~resume,~slim~splittable~and~tab-size.\\
+ left-margin,~line-numbers,~resume,~show-spaces,~slim,~splittable~and~tab-size.\\
If~you~go~on,~that~key~will~be~ignored.
}
% \end{macrocode}
@@ -1510,7 +1693,7 @@ version 2005/12/01 or later.
\ttfamily
\cs_set_protected:Npn \@@_begin_line: { }
\cs_set_protected:Npn \@@_end_line: { }
- \lua_now:n { Parse(token.scan_argument()) } { #1 }
+ \lua_now:n { piton.Parse(token.scan_argument()) } { #1 }
\group_end:
}
% \end{macrocode}
@@ -1523,7 +1706,7 @@ version 2005/12/01 or later.
\group_begin:
\cs_set_protected:Npn \@@_begin_line: { }
\cs_set_protected:Npn \@@_end_line: { }
- \lua_now:e { Parse(token.scan_argument()) } { #1 }
+ \lua_now:n { piton.Parse(token.scan_argument()) } { #1 }
\group_end:
}
% \end{macrocode}
@@ -1536,8 +1719,7 @@ version 2005/12/01 or later.
{
\int_gincr:N \g_@@_env_int
\tl_gclear:N \g_@@_aux_tl
- \tl_if_exist:cT { c_@@ _ \int_use:N \g_@@_env_int _ tl }
- { \use:c { c_@@ _ \int_use:N \g_@@_env_int _ tl } }
+ \cs_if_exist_use:c { c_@@ _ \int_use:N \g_@@_env_int _ tl }
\dim_compare:nNnT \l_@@_width_on_aux_dim = \c_zero_dim
{ \dim_set_eq:NN \l_@@_width_on_aux_dim \linewidth }
\bool_if:NF \l_@@_resume_bool { \int_gzero:N \g_@@_visual_line_int }
@@ -1550,9 +1732,24 @@ version 2005/12/01 or later.
%
% \bigskip
% \begin{macrocode}
-\NewDocumentCommand { \PitonInputFile } { m }
+\keys_define:nn { PitonInputFile }
+ {
+ first-line .int_set:N = \l_@@_first_line_int ,
+ first-line .value_required:n = true ,
+ last-line .int_set:N = \l_@@_last_line_int ,
+ last-line .value_required:n = true ,
+ }
+% \end{macrocode}
+%
+% \bigskip
+% \begin{macrocode}
+\NewDocumentCommand { \PitonInputFile } { O { } m }
{
\group_begin:
+ \int_zero_new:N \l_@@_first_line_int
+ \int_zero_new:N \l_@@_last_line_int
+ \int_set_eq:NN \l_@@_last_line_int \c_max_int
+ \keys_set:nn { PitonInputFile } { #1 }
\@@_pre_env:
\mode_if_vertical:TF \mode_leave_vertical: \newline
% \end{macrocode}
@@ -1560,11 +1757,51 @@ version 2005/12/01 or later.
% stored by Lua in |\l_@@_nb_lines_int|. That information will be used to allow
% or disallow page breaks.
% \begin{macrocode}
- \lua_now:n { CountLinesFile(token.scan_argument()) } { #1 }
+ \lua_now:n { piton.CountLinesFile(token.scan_argument()) } { #2 }
+% If the final user has used both |left-margin=auto| and |line-numbers| or
+% |all-line-numbers|, we have to compute the width of the maximal number of
+% lines at the end of the composition of the listing to fix the correct value to
+% |left-margin|. Par convention, when |left-margin=auto|, the dimension
+% |\l_@@_left_margin_dim| is set to -1~cm.
+% \begin{macrocode}
+ \dim_compare:nNnT \l_@@_left_margin_dim < \c_zero_dim
+ {
+ \bool_if:NT \l_@@_line_numbers_bool
+ {
+ \hbox_set:Nn \l_tmpa_box
+ {
+ \footnotesize
+ \bool_if:NTF \l_@@_all_line_numbers_bool
+ {
+ \int_to_arabic:n
+ { \g_@@_visual_line_int + \l_@@_nb_lines_int }
+ }
+ {
+ \lua_now:n
+ { piton.CountNonEmptyLinesFile(token.scan_argument()) }
+ { #2 }
+ \int_to_arabic:n
+ {
+ \g_@@_visual_line_int +
+ \l_@@_nb_non_empty_lines_int
+ }
+ }
+ }
+ \dim_set:Nn \l_@@_left_margin_dim { \box_wd:N \l_tmpa_box + 0.5em }
+ }
+ }
+% \end{macrocode}
+% Now, the main job.
+% \begin{macrocode}
\ttfamily
\bool_if:NT \c_@@_footnote_bool { \begin { savenotes } }
\vtop \bgroup
- \lua_now:n { ParseFile(token.scan_argument()) } { #1 }
+ \lua_now:e
+ { piton.ParseFile(token.scan_argument(),
+ \int_use:N \l_@@_first_line_int ,
+ \int_use:N \l_@@_last_line_int )
+ }
+ { #2 }
\egroup
\bool_if:NT \c_@@_footnote_bool { \end { savenotes } }
\@@_width_to_aux:
@@ -1601,13 +1838,52 @@ version 2005/12/01 or later.
% stored by Lua in |\l_@@_nb_lines_int|. That information will be used to allow
% or disallow page breaks.
% \begin{macrocode}
- \lua_now:n { CountLines(token.scan_argument()) } { ##1 }
+ \lua_now:n { piton.CountLines(token.scan_argument()) } { ##1 }
+% \end{macrocode}
+% If the final user has used both |left-margin=auto| and |line-numbers|, we have
+% to compute the width of the maximal number of lines at the end of the
+% environment to fix the correct value to |left-margin|.
+% \begin{macrocode}
+ \dim_compare:nNnT \l_@@_left_margin_dim < \c_zero_dim
+ {
+ \bool_if:NT \l_@@_line_numbers_bool
+ {
+ \bool_if:NTF \l_@@_all_line_numbers_bool
+ {
+ \hbox_set:Nn \l_tmpa_box
+ {
+ \footnotesize
+ \int_to_arabic:n
+ { \g_@@_visual_line_int + \l_@@_nb_lines_int }
+ }
+ }
+ {
+ \lua_now:n
+ { piton.CountNonEmptyLines(token.scan_argument()) }
+ { ##1 }
+ \hbox_set:Nn \l_tmpa_box
+ {
+ \footnotesize
+ \int_to_arabic:n
+ {
+ \g_@@_visual_line_int +
+ \l_@@_nb_non_empty_lines_int
+ }
+ }
+ }
+ \dim_set:Nn \l_@@_left_margin_dim
+ { \box_wd:N \l_tmpa_box + 0.5 em }
+ }
+ }
+% \end{macrocode}
+% Now, the main job.
+% \begin{macrocode}
\ttfamily
\bool_if:NT \c_@@_footnote_bool { \begin { savenotes } }
\vtop \bgroup
\lua_now:e
{
- GobbleParse
+ piton.GobbleParse
( \int_use:N \l_@@_gobble_int , token.scan_argument() )
}
{ ##1 }
@@ -1807,6 +2083,16 @@ version 2005/12/01 or later.
% The last style |Post.Function| should be considered as an ``internal style''
% (not available 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).
+% \begin{macrocode}
+\bool_if:NT \c_@@_math_comments_bool
+ { \SetPitonStyle { Comment.Math } }
+% \end{macrocode}
+%
% \bigskip
% \subsubsection{Security}
%
@@ -1832,20 +2118,36 @@ version 2005/12/01 or later.
\ExplSyntaxOff
\RequirePackage{luacode}
% \end{macrocode}
-%
+%
+%
+% \bigskip
+% The Lua code will be loaded via a |{luacode*}| environment. Thei environment
+% is by itself a Lua block and the local declarations will be local to that
+% block. All the global functions (used by the L3 parts of the implementation)
+% will be put in a Lua table |piton|.
+%
% \medskip
% \begin{macrocode}
\begin{luacode*}
+piton = piton or { }
% \end{macrocode}
-%
+%
+% \begin{macrocode}
+if piton.comment_latex == nil then piton.comment_latex = ">" end
+piton.comment_latex = "#" .. piton.comment_latex
+% \end{macrocode}
+%
+%
% \bigskip
% \subsubsection{Special functions dealing with LPEG}
%
+%
% \medskip
% We will use the Lua library \pkg{lpeg} which is built in LuaTeX. That's why we
% define first aliases for several functions of that library.
% \begin{macrocode}
-local P, S, V, C, Ct, Cc, Cf = lpeg.P, lpeg.S, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Cc, lpeg.Cf
+local P, S, V, C, Ct, Cc = lpeg.P, lpeg.S, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Cc
+local Cf, Cs = lpeg.Cf, lpeg.Cs
% \end{macrocode}
%
%
@@ -1854,13 +2156,14 @@ local P, S, V, C, Ct, Cc, Cf = lpeg.P, lpeg.S, lpeg.V, lpeg.C, lpeg.Ct, lpeg.Cc,
% \emph{which does a capture} of the pattern. That capture will be sent to LaTeX
% with the catcode ``other'' for all the characters: it's suitable for elements
% of the Python listings that \pkg{piton} will typeset verbatim (thanks to the
-% catcode ``other''). That function will be widely used.
+% catcode ``other'').
% \begin{macrocode}
local function Q(pattern)
return Ct ( Cc ( luatexbase.catcodetables.CatcodeTableOther ) * C ( pattern ) )
end
% \end{macrocode}
%
+%
% \bigskip
% The function |L| takes in as argument a pattern and returns a \textsc{lpeg}
% \emph{which does a capture} of the pattern. That capture will be sent to LaTeX
@@ -1888,18 +2191,24 @@ end
% \end{macrocode}
%
% \bigskip
-% The function |K| function creates a \textsc{lpeg} which will return as capture
+% The function |K| creates a \textsc{lpeg} which will return as capture
% the whole LaTeX code corresponding to a Python chunk (that is to say with the
% LaTeX formatting instructions corresponding to the syntactic nature of that
% Python chunk). The first argument is a pattern (that is to say a \textsc{lpeg}
% without capture) and the second element is a Lua string corresponding to the
-% name of a \pkg{piton} style.
+% name of a \pkg{piton} style. If the seconde argument is not present, the
+% function |K| behaves as the function |Q| does.
% \begin{macrocode}
local function K(pattern, style)
+ if style
+ then
return
Lc ( "{\\PitonStyle{" .. style .. "}{" )
* Q ( pattern )
* Lc ( "}}" )
+ else
+ return Q ( pattern )
+ end
end
% \end{macrocode}
% The formatting commands in a given \pkg{piton} style (eg. the style |Keyword|)
@@ -1911,17 +2220,18 @@ end
% \bigskip
% The following \textsc{lpeg} catches the Python chunks which are in LaTeX
% escapes (and that chunks will be considered as normal LaTeX constructions). We
-% recall that |begin_espace| and |end_escape| are Lua strings corresponding to
-% the key |escape-inside|\footnote{The \pkg{piton} key |escape-inside| is
-% available at load-time only.}. Since the elements that will be catched must be
-% sent to LaTeX with standard LaTeX catcodes, we put the capture (done by the
-% function |C|) in a table (by using |Ct|, which is an alias for |lpeg.Ct|)
-% without number of catcode table at the first component of the table.
+% recall that |piton.begin_espace| and |piton_end_escape| are Lua strings
+% corresponding to the key |escape-inside|\footnote{The \pkg{piton} key
+% |escape-inside| is available at load-time only.}. Since the elements that will
+% be catched must be sent to LaTeX with standard LaTeX catcodes, we put the
+% capture (done by the function |C|) in a table (by using |Ct|, which is an
+% alias for |lpeg.Ct|) without number of catcode table at the first component of
+% the table.
% \begin{macrocode}
local Escape =
- P(begin_escape)
- * L ( ( 1 - P(end_escape) ) ^ 1 )
- * P(end_escape)
+ P(piton_begin_escape)
+ * L ( ( 1 - P(piton_end_escape) ) ^ 1 )
+ * P(piton_end_escape)
% \end{macrocode}
%
% \vspace{1cm}
@@ -1959,13 +2269,9 @@ local identifier = letter * alphanum ^ 0
%
% \medskip
% On the other hand, the \textsc{lpeg} |Identifier| (with a capital) also return
-% a \emph{capture}. Since no special LaTeX formatting will be applied to the
-% Python identifiers, we use the function~|Q| and not the function~|K|. For
-% elements which require formatting, we will usually use our function~|K|
-% instead of the function~|C|. See just below for an example of use of the
-% function~|K|.
+% a \emph{capture}.
% \begin{macrocode}
-local Identifier = Q ( identifier )
+local Identifier = K ( identifier )
% \end{macrocode}
%
% \bigskip
@@ -1992,25 +2298,26 @@ local Number =
% \end{macrocode}
%
% \bigskip
-% We recall that |begin_espace| and |end_escape| are Lua strings
+% We recall that |piton.begin_espace| and |piton_end_escape| are Lua strings
% corresponding to the key |escape-inside|\footnote{The \pkg{piton} key
% |escape-inside| is available at load-time only.}. Of course, if the final user
% has not used the key |escape-inside|, these strings are empty.
% \begin{macrocode}
-if begin_escape ~= ''
-then Word = Q ( ( ( 1 - space - P(begin_escape) - P(end_escape) )
+local Word
+if piton_begin_escape ~= ''
+then Word = K ( ( ( 1 - space - P(piton_begin_escape) - P(piton_end_escape) )
- S "'\"\r[()]" - digit ) ^ 1 )
-else Word = Q ( ( ( 1 - space ) - S "'\"\r[()]" - digit ) ^ 1 )
+else Word = K ( ( ( 1 - space ) - S "'\"\r[()]" - digit ) ^ 1 )
end
% \end{macrocode}
%
% \bigskip
% \begin{macrocode}
-local Space = Q ( ( space - P "\r" ) ^ 1 )
+local Space = K ( ( space - P "\r" ) ^ 1 )
-local SkipSpace = Q ( ( space - P "\r" ) ^ 0 )
+local SkipSpace = K ( ( space - P "\r" ) ^ 0 )
-local Punct = Q ( S ".,:;!" )
+local Punct = K ( S ".,:;!" )
% \end{macrocode}
%
% \bigskip
@@ -2040,10 +2347,19 @@ local EOL =
%
% \bigskip
% \begin{macrocode}
-local Delim = Q ( S "[()]" )
-
+local Delim = K ( S "[()]" )
+% \end{macrocode}
+%
+% \bigskip
+% Some strings of length 2 are explicit because we want the corresponding
+% ligatures in the font \emph{Fira Code} to be active.
+% \begin{macrocode}
local Operator =
- K ( P "!=" + P "==" + P "<<" + P ">>" + S "-~+/*%=<>&.@|" , 'Operator')
+ K ( P "!=" + P "<>" + P "==" + P "<<" + P ">>" + P "<=" + P ">=" + P ":="
+ + P "//" + P "**" + S "-~+/*%=<>&.@|"
+ ,
+ 'Operator'
+ )
local OperatorWord =
K ( P "in" + P "is" + P "and" + P "or" + P "not" , 'Operator.Word')
@@ -2095,9 +2411,9 @@ local Exception =
+ P "StopAsyncIteration" + P "ModuleNotFoundError" + P "RecursionError" ,
'Exception' )
-local RaiseException = K ( P "raise" , 'Keyword' ) * SkipSpace * Exception * Q ( P "(" )
+local RaiseException = K ( P "raise" , 'Keyword' ) * SkipSpace * Exception * K ( P "(" )
-local ExceptionInConsole = Exception * Q ( ( 1 - P "\r" ) ^ 0 ) * EOL
+local ExceptionInConsole = Exception * K ( ( 1 - P "\r" ) ^ 0 ) * EOL
% \end{macrocode}
%
% \bigskip
@@ -2148,7 +2464,7 @@ local ImportAs =
* (
( Space * K ( P "as" , 'Keyword' ) * Space * K ( identifier , 'Name.Namespace' ) )
+
- ( SkipSpace * Q ( P "," ) * SkipSpace * K ( identifier , 'Name.Namespace' ) ) ^ 0
+ ( SkipSpace * K ( P "," ) * SkipSpace * K ( identifier , 'Name.Namespace' ) ) ^ 0
)
% \end{macrocode}
% Be careful: there is no commutativity of |+| in the previous expression.
@@ -2210,43 +2526,71 @@ local FromImport =
local SingleShortInterpol =
K ( P "{" , 'String.Interpol')
* K ( ( 1 - S "}':" ) ^ 0 , 'Interpol.Inside' )
- * Q ( P ":" * (1 - S "}:'") ^ 0 ) ^ -1
+ * K ( P ":" * (1 - S "}:'") ^ 0 ) ^ -1
* K ( P "}" , 'String.Interpol' )
local DoubleShortInterpol =
K ( P "{" , 'String.Interpol' )
* K ( ( 1 - S "}\":" ) ^ 0 , 'Interpol.Inside' )
- * ( K ( P ":" , 'String.Interpol' ) * Q ( (1 - S "}:\"") ^ 0 ) ) ^ -1
+ * ( K ( P ":" , 'String.Interpol' ) * K ( (1 - S "}:\"") ^ 0 ) ) ^ -1
* K ( P "}" , 'String.Interpol' )
local SingleLongInterpol =
K ( P "{" , 'String.Interpol' )
* K ( ( 1 - S "}:\r" - P "'''" ) ^ 0 , 'Interpol.Inside' )
- * Q ( P ":" * (1 - S "}:\r" - P "'''" ) ^ 0 ) ^ -1
+ * K ( P ":" * (1 - S "}:\r" - P "'''" ) ^ 0 ) ^ -1
* K ( P "}" , 'String.Interpol' )
local DoubleLongInterpol =
K ( P "{" , 'String.Interpol' )
* K ( ( 1 - S "}:\r" - P "\"\"\"" ) ^ 0 , 'Interpol.Inside' )
- * Q ( P ":" * (1 - S "}:\r" - P "\"\"\"" ) ^ 0 ) ^ -1
+ * K ( P ":" * (1 - S "}:\r" - P "\"\"\"" ) ^ 0 ) ^ -1
* K ( P "}" , 'String.Interpol' )
% \end{macrocode}
%
+%
+% \bigskip
+% The following \textsc{lpeg} catches a space (U+0032) and replace it by
+% |\l_@@_space_tl|. It will be used in the short strings. Usually,
+% |\l_@@_space_tl| will contain a space and therefore there won't be difference.
+% However, when the key |show-spaces| is in force, |\\l_@@_space_tl| will
+% contain ␣ (U+2423) in order to visualize the spaces.
+% \begin{macrocode}
+local VisualSpace = P " " * Lc "\\l_@@_space_tl"
+% \end{macrocode}
+%
% \bigskip
% Now, we define \textsc{lpeg} for the parts of the strings which are \emph{not}
% in the interpolations.
+%
% \begin{macrocode}
local SingleShortPureString =
- Q ( ( P "\\'" + P "{{" + P "}}" + 1 - S "{}'" ) ^ 1 )
+ ( K ( ( P "\\'" + P "{{" + P "}}" + 1 - S " {}'" ) ^ 1 ) + VisualSpace ) ^ 1
local DoubleShortPureString =
- Q ( ( P "\\\"" + P "{{" + P "}}" + 1 - S "{}\"" ) ^ 1 )
+ ( K ( ( P "\\\"" + P "{{" + P "}}" + 1 - S " {}\"" ) ^ 1 ) + VisualSpace ) ^ 1
local SingleLongPureString =
- Q ( ( 1 - P "'''" - S "{}'\r" ) ^ 1 )
+ K ( ( 1 - P "'''" - S "{}'\r" ) ^ 1 )
local DoubleLongPureString =
- Q ( ( 1 - P "\"\"\"" - S "{}\"\r" ) ^ 1 )
+ K ( ( 1 - P "\"\"\"" - S " {}\"\r" ) ^ 1 )
+% \end{macrocode}
+%
+% \bigskip
+% The interpolations beginning by |%| (even though there is more modern
+% technics now in Python).
+% \begin{macrocode}
+local PercentInterpol =
+ K ( P "%"
+ * ( P "(" * alphanum ^ 1 * P ")" ) ^ -1
+ * ( S "-#0 +" ) ^ 0
+ * ( digit ^ 1 + P "*" ) ^ -1
+ * ( P "." * ( digit ^ 1 + P "*" ) ) ^ -1
+ * ( S "HlL" ) ^ -1
+ * S "sdfFeExXorgiGauc%" ,
+ 'String.Interpol'
+ )
% \end{macrocode}
%
% \bigskip
@@ -2263,27 +2607,37 @@ local SingleShortString =
% \end{macrocode}
% First, we deal with the f-strings of Python, which are prefixed by |f| or |F|.
% \begin{macrocode}
- Q ( P "f'" + P "F'" )
+ K ( P "f'" + P "F'" )
* ( SingleShortInterpol + SingleShortPureString ) ^ 0
- * Q ( P "'" )
+ * K ( P "'" )
+
% \end{macrocode}
% Now, we deal with the standard strings of Python, but also the ``raw strings''.
% \begin{macrocode}
- Q ( ( P "'" + P "r'" + P "R'" )
- * ( P "\\'" + 1 - S "'\r" ) ^ 0 * P "'" )
+ K ( P "'" + P "r'" + P "R'" )
+ * ( K ( ( P "\\'" + 1 - S " '\r%" ) ^ 1 )
+ + VisualSpace
+ + PercentInterpol
+ + K ( P "%" )
+ ) ^ 0
+ * K ( P "'" )
)
* Lc ( "}}" )
local DoubleShortString =
Lc ( "{\\PitonStyle{String.Short}{" )
* (
- Q ( P "f\"" + P "F\"" )
+ K ( P "f\"" + P "F\"" )
* ( DoubleShortInterpol + DoubleShortPureString ) ^ 0
- * Q ( P "\"" )
+ * K ( P "\"" )
+
- Q ( ( P "\"" + P "r\"" + P "R\"" )
- * ( P "\\\"" + 1 - S "\"\r" ) ^ 0 * P "\"" )
+ K ( P "\"" + P "r\"" + P "R\"" )
+ * ( K ( ( P "\\\"" + 1 - S " \"\r%" ) ^ 1 )
+ + VisualSpace
+ + PercentInterpol
+ + K ( P "%" )
+ ) ^ 0
+ * K ( P "\"" )
)
* Lc ( "}}" )
@@ -2299,7 +2653,7 @@ local ShortString = SingleShortString + DoubleShortString
local SingleLongString =
Lc "{\\PitonStyle{String.Long}{"
* (
- Q ( S "fF" * P "'''" )
+ K ( S "fF" * P "'''" )
* ( SingleLongInterpol + SingleLongPureString ) ^ 0
* Lc "}}"
* (
@@ -2313,26 +2667,26 @@ local SingleLongString =
* Lc "{\\PitonStyle{String.Long}{"
* ( SingleLongInterpol + SingleLongPureString ) ^ 0
+
- Q ( ( S "rR" ) ^ -1 * P "'''"
+ K ( ( S "rR" ) ^ -1 * P "'''"
* ( 1 - P "'''" - P "\r" ) ^ 0 )
* Lc "}}"
* (
Lc "{\\PitonStyle{String.Long}{"
- * Q ( ( 1 - P "'''" - P "\r" ) ^ 0 )
+ * K ( ( 1 - P "'''" - P "\r" ) ^ 0 )
* Lc "}}"
* EOL
) ^ 0
* Lc "{\\PitonStyle{String.Long}{"
- * Q ( ( 1 - P "'''" - P "\r" ) ^ 0 )
+ * K ( ( 1 - P "'''" - P "\r" ) ^ 0 )
)
- * Q ( P "'''" )
+ * K ( P "'''" )
* Lc "}}"
local DoubleLongString =
Lc "{\\PitonStyle{String.Long}{"
* (
- Q ( S "fF" * P "\"\"\"" )
+ K ( S "fF" * P "\"\"\"" )
* ( DoubleLongInterpol + DoubleLongPureString ) ^ 0
* Lc "}}"
* (
@@ -2346,19 +2700,19 @@ local DoubleLongString =
* Lc "{\\PitonStyle{String.Long}{"
* ( DoubleLongInterpol + DoubleLongPureString ) ^ 0
+
- Q ( ( S "rR" ) ^ -1 * P "\"\"\""
+ K ( ( S "rR" ) ^ -1 * P "\"\"\""
* ( 1 - P "\"\"\"" - P "\r" ) ^ 0 )
* Lc "}}"
* (
Lc "{\\PitonStyle{String.Long}{"
- * Q ( ( 1 - P "\"\"\"" - P "\r" ) ^ 0 )
+ * K ( ( 1 - P "\"\"\"" - P "\r" ) ^ 0 )
* Lc "}}"
* EOL
) ^ 0
* Lc "{\\PitonStyle{String.Long}{"
- * Q ( ( 1 - P "\"\"\"" - P "\r" ) ^ 0 )
+ * K ( ( 1 - P "\"\"\"" - P "\r" ) ^ 0 )
)
- * Q ( P "\"\"\"" )
+ * K ( P "\"\"\"" )
* Lc "}}"
% \end{macrocode}
%
@@ -2388,14 +2742,14 @@ local CommentMath =
local Comment =
Lc ( "{\\PitonStyle{Comment}{" )
- * Q ( P "#" )
- * ( CommentMath + Q ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0
+ * K ( P "#" )
+ * ( CommentMath + K ( ( 1 - S "$\r" ) ^ 1 ) ) ^ 0
* Lc ( "}}" )
* ( EOL + -1 )
% \end{macrocode}
%
-
-
+%
+%
% \bigskip
% The following \textsc{lpeg} |CommentLaTeX| is for what is called in that
% document the ``LaTeX comments''. Since the elements that will be catched must
@@ -2403,7 +2757,7 @@ local Comment =
% the function~|C|) in a table (by using~|Ct|, which is an alias for |lpeg.Ct|).
% \begin{macrocode}
local CommentLaTeX =
- P "##"
+ P(piton.comment_latex)
* Lc "{\\PitonStyle{Comment.LaTeX}{\\ignorespaces"
* L ( ( 1 - P "\r" ) ^ 0 )
* Lc "}}"
@@ -2456,13 +2810,13 @@ local Param =
SkipSpace * Identifier * SkipSpace
* (
K ( P "=" * Expression , 'InitialValues' )
- + Q ( P ":" ) * SkipSpace * K ( letter^1 , 'Name.Type' )
+ + K ( P ":" ) * SkipSpace * K ( letter^1 , 'Name.Type' )
) ^ -1
% \end{macrocode}
%
% \medskip
% \begin{macrocode}
-local Params = ( Param * ( Q "," * Param ) ^ 0 ) ^ -1
+local Params = ( Param * ( K "," * Param ) ^ 0 ) ^ -1
% \end{macrocode}
%
% \bigskip
@@ -2477,8 +2831,9 @@ local DefFunction =
* Space
* K ( identifier , 'Name.Function' )
* SkipSpace
- * Q ( P "(" ) * Params * Q ( P ")" )
+ * K ( P "(" ) * Params * K ( P ")" )
* SkipSpace
+ * ( K ( P "->" ) * SkipSpace * K ( identifier , 'Name.Type' ) ) ^ -1
% \end{macrocode}
% Here, we need a \pkg{piton} style |Post.Function| which will be linked to
% |\@@_piton:n| (that means that the capture will be parsed once again by
@@ -2486,7 +2841,7 @@ local DefFunction =
% grammar but we have probably here a better legibility.
% \begin{macrocode}
* K ( ( 1 - S ":\r" )^0 , 'Post.Function' )
- * Q ( P ":" )
+ * K ( P ":" )
* ( SkipSpace
* ( EOL + CommentLaTeX + Comment ) -- in all cases, that contains an EOL
* Tab ^ 0
@@ -2527,15 +2882,14 @@ local DefFunction =
%
% \begin{macrocode}
local ItemDict =
- ShortString * SkipSpace * Q ( P ":" ) * K ( Expression , 'Dict.Value' )
+ ShortString * SkipSpace * K ( P ":" ) * K ( Expression , 'Dict.Value' )
local ItemOfSet = SkipSpace * ( ItemDict + ShortString ) * SkipSpace
local Set =
- Q ( P "{" )
- * ItemOfSet * ( Q ( P "," ) * ItemOfSet ) ^ 0
- * Q ( P "}" )
-
+ K ( P "{" )
+ * ItemOfSet * ( K ( P "," ) * ItemOfSet ) ^ 0
+ * K ( P "}" )
% \end{macrocode}
%
%
@@ -2587,7 +2941,7 @@ local SyntaxPythonAux =
) ^0 * -1 * Lc ( '\\@@_end_line:' )
% \end{macrocode}
%
-% We have written a auxiliary \textsc{lpeg} |SyntaxPythonAux| for legibility only.
+% We have written an auxiliary \textsc{lpeg} |SyntaxPythonAux| for legibility only.
% \begin{macrocode}
local SyntaxPython = Ct ( SyntaxPythonAux )
% \end{macrocode}
@@ -2603,8 +2957,8 @@ local SyntaxPython = Ct ( SyntaxPythonAux )
%
% \bigskip
% \begin{macrocode}
-function Parse(code)
- local t = SyntaxPython : match ( code )
+function piton.Parse(code)
+ local t = SyntaxPython : match ( code ) -- match is a method of the LPEG
for _ , s in ipairs(t) do tex.tprint(s) end
end
% \end{macrocode}
@@ -2614,10 +2968,17 @@ end
% That function merely reads the whole file (that is to say all its lines) and
% then apply the function~|Parse| to the resulting Lua string.
% \begin{macrocode}
-function ParseFile(name)
+function piton.ParseFile(name,first_line,last_line)
s = ''
- for line in io.lines(name) do s = s .. '\r' .. line end
- Parse(s)
+ local i = 0
+ for line in io.lines(name)
+ do i = i + 1
+ if i >= first_line
+ then s = s .. '\r' .. line
+ end
+ if i >= last_line then break end
+ end
+ piton.Parse(s)
end
% \end{macrocode}
%
@@ -2633,7 +2994,7 @@ end
% a \textsc{lpeg} that we have to compute dynamically because if depends on the
% value of~$n$.
% \begin{macrocode}
-function gobble(n,code)
+local function gobble(n,code)
function concat(acc,new_value)
return acc .. new_value
end
@@ -2653,25 +3014,13 @@ function gobble(n,code)
end
% \end{macrocode}
%
-% \bigskip
-% \begin{macrocode}
-function GobbleParse(n,code)
- if n==-1
- then n = AutoGobbleLPEG : match(code)
- else if n==-2
- then n = EnvGobbleLPEG : match(code)
- end
- end
- Parse(gobble(n,code))
-end
-% \end{macrocode}
%
%
% \bigskip
% The following function |add| will be used in the following \textsc{lpeg}
% |AutoGobbleLPEG| and |EnvGobbleLPEG|.
% \begin{macrocode}
-function add(acc,new_value)
+local function add(acc,new_value)
return acc + new_value
end
% \end{macrocode}
@@ -2682,7 +3031,7 @@ end
% captures} (|lpeg.Cf|), one using |add| and the other (encompassing the
% previous one) using |math.min| as folding operator.
% \begin{macrocode}
-AutoGobbleLPEG =
+local AutoGobbleLPEG =
( space ^ 0 * P "\r" ) ^ -1
* Cf (
(
@@ -2711,28 +3060,59 @@ AutoGobbleLPEG =
% traditionnal way to indent in LaTeX). The main work is done by a \emph{fold
% capture} (|lpeg.Cf|) using the function |add| as folding operator.
% \begin{macrocode}
-EnvGobbleLPEG =
+local EnvGobbleLPEG =
( ( 1 - P "\r" ) ^ 0 * P "\r" ) ^ 0
* Cf ( Cc(0) * ( P " " * Cc(1) ) ^ 0 , add ) * -1
% \end{macrocode}
%
% \bigskip
+% \begin{macrocode}
+function piton.GobbleParse(n,code)
+ if n==-1
+ then n = AutoGobbleLPEG : match(code)
+ else if n==-2
+ then n = EnvGobbleLPEG : match(code)
+ end
+ end
+ piton.Parse(gobble(n,code))
+end
+% \end{macrocode}
+%
+% \bigskip
% \subsubsection{To count the number of lines}
%
% \medskip
% \begin{macrocode}
-function CountLines(code)
+function piton.CountLines(code)
local count = 0
- for i in code:gmatch("\r") do count = count + 1 end
+ for i in code : gmatch ( "\r" ) do count = count + 1 end
tex.sprint(
luatexbase.catcodetables.expl ,
'\\int_set:Nn \\l_@@_nb_lines_int {' .. count .. '}' )
end
% \end{macrocode}
%
+% \begin{macrocode}
+function piton.CountNonEmptyLines(code)
+ local count = 0
+ count =
+ ( Cf ( Cc(0) *
+ (
+ ( P " " ) ^ 0 * P "\r"
+ + ( 1 - P "\r" ) ^ 0 * P "\r" * Cc(1)
+ ) ^ 0
+ * (1 - P "\r" ) ^ 0 ,
+ add
+ ) * -1 ) : match (code)
+ tex.sprint(
+ luatexbase.catcodetables.expl ,
+ '\\int_set:Nn \\l_@@_nb_non_empty_lines_int {' .. count .. '}' )
+end
+% \end{macrocode}
+%
% \bigskip
% \begin{macrocode}
-function CountLinesFile(name)
+function piton.CountLinesFile(name)
local count = 0
for line in io.lines(name) do count = count + 1 end
tex.sprint(
@@ -2740,6 +3120,23 @@ function CountLinesFile(name)
'\\int_set:Nn \\l_@@_nb_lines_int {' .. count .. '}' )
end
% \end{macrocode}
+%
+%
+% \bigskip
+% \begin{macrocode}
+function piton.CountNonEmptyLinesFile(name)
+ local count = 0
+ for line in io.lines(name)
+ do if not ( ( ( P " " ) ^ 0 * -1 ) : match ( line ) )
+ then count = count + 1
+ end
+ end
+ tex.sprint(
+ luatexbase.catcodetables.expl ,
+ '\\int_set:Nn \\l_@@_nb_non_empty_lines_int {' .. count .. '}' )
+end
+% \end{macrocode}
+%
%
% \bigskip
% \begin{macrocode}
@@ -2769,6 +3166,18 @@ end
%
% Integer value for the key |splittable|.
%
+% \subsection*{Changes between versions 0.9 and 0.95}
+%
+% New key |show-spaces|.
+%
+% The key |left-margin| now accepts the special value |auto|.
+%
+% New key |latex-comment| at load-time and replacement of |##| by |#>|
+%
+% New key |math-comments| at load-time.
+%
+% New keys |first-line| and |last-line| for the command |\InputPitonFile|.
+%
% \end{document}
%
%