% -*- coding: utf-8 ; -*-
\documentclass[dvipsnames]{article}

\usepackage{fontspec}

\usepackage[french]{babel}
\frenchsetup{og = « , fg = »}

\usepackage[footnotehyper,escape-inside=$$,math-comments]{piton}

\usepackage[executable=python.exe]{pyluatex}

\usepackage{xcolor}

\usepackage{geometry}
\geometry{left=2.8cm,right=2.8cm,top=2.5cm,bottom=2.5cm,papersize={21cm,29.7cm}}

\usepackage{enumitem}
\usepackage{verbatim}
\usepackage{amsmath}
\usepackage{tabularx}
\usepackage{booktabs}

\usepackage{caption}

% We use \MakeShortVerb of shortvrb and not \DefineShortVerb of fancyvrb
% because we don't want the contents of short verbatim colored in gray
\usepackage{shortvrb}
\MakeShortVerb{\|}

\usepackage{varwidth}

\skip\footins = 2\bigskipamount

\usepackage{fancyvrb}
\fvset{commandchars=\~\#\@,formatcom=\color{gray}}
\def\emphase{\bgroup\color{RoyalPurple}\let\next=}


\usepackage{titlesec}
\titlespacing*{\section}{0pt}{6.5ex plus 1ex minus .2ex}{4.3ex plus .2ex}
\titlespacing*{\subsection}{0pt}{4.5ex plus 1ex minus .2ex}{2ex plus .2ex}

\def\interitem{\vspace{7mm plus 2 mm minus 3mm}}          


\usepackage[hyperfootnotes = false]{hyperref}

\hypersetup
  {
    pdfinfo = 
      {
        Title = L’extension piton ,
        Subject = Une extension LaTeX ,
        Author = F. Pantigny 
      }
  } 


\NewDocumentEnvironment {scope} {} {} {}

\NewDocumentCommand {\pkg} {m} {\textsf{#1}}
\NewDocumentCommand {\cls} {m} {\textsf{#1}}

\setlength{\parindent}{0pt}


\begin{document}

\PitonOptions{splittable = 4}

\VerbatimFootnotes


\title{L'extension LaTeX \pkg{piton}\thanks{Ce document correspond à la 
version~\myfileversion\space de \pkg{piton}, à la date du~\myfiledate.}} 
\author{F. Pantigny \\ \texttt{fpantigny@wanadoo.fr}}

\maketitle

\begin{abstract}
L'extension \pkg{piton} propose des outils pour composer du code Python avec une coloration syntaxique
en utilisant la bibliothèque Lua LPEG. L'extension \pkg{piton} nécessite l'emploi de LuaLaTeX.
\end{abstract}

\section{Présentation}

L'extension \pkg{piton} utilise la librairie Lua nommée LPEG\footnote{LPEG est une librairie de capture de motifs
  (\emph{pattern-matching} en anglais) pour Lua, écrite en C, fondée sur les PEG (\emph{parsing expression
    grammars}): \url{http://www.inf.puc-rio.br/~roberto/lpeg/}} pour «parser» le code Python et le composer avec un
coloriage syntaxique. Comme elle utilise du code Lua, elle fonctionne uniquement avec |lualatex| (et ne va pas
fonctionner avec les autres moteurs de compilation LaTeX, que ce soit |latex|, |pdflatex| ou |xelatex|). Elle
n'utilise aucun programme extérieur et la compilation ne requiert donc pas |--shell-escape|. La compilation est
très rapide puisque tout le travail du parseur est fait par la librairie LPEG, écrite en C.

\bigskip
Voici un exemple de code Python composé avec l'environnement |{Piton}| proposé par \pkg{piton}.

\bigskip
\begin{Piton}
from math import pi

def arctan(x,n=10):
    """Compute the mathematical value of arctan(x)

    n is the number of terms in the sum
    """
    if x < 0:
        return -arctan(-x) # appel récursif
    elif x > 1: 
        return pi/2 - arctan(1/x) 
        #> (on a utilisé le fait que $\arctan(x)+\arctan(1/x)=\pi/2$ pour $x>0$)\footnote{Cet échappement vers LaTeX a été obtenu en débutant par \ttfamily\#>.} 
    else: 
        s = 0
        for k in range(n):
            s += (-1)**k/(2*k+1)*x**(2*k+1)
        return s 
\end{Piton}

\bigskip

L'extension LaTeX \pkg{piton} est entièrement contenue dans le fichier |piton.sty|. Ce
fichier peut être placé dans le répertoire courant ou dans une arborescence |texmf|. Le mieux reste néanmoins
d'installer \pkg{piton} avec une distribution TeX comme MiKTeX, TeX~Live ou MacTeX.


\section{Utilisation de l'extension}

L'extension \pkg{piton} se charge simplement avec la commande |\usepackage| : |\usepackage{piton}|.

On a néanmoins deux remarques à formuler :
\begin{itemize}
\item l'extension \pkg{piton} utilise l'extension \pkg{xcolor} (néanmoins \pkg{piton} charge pas \pkg{xcolor} : si
\pkg{xcolor} n'est pas chargée avant le |\begin{document}|, une erreur fatale sera levée) ;

\item l'extension \pkg{piton} n'est utilisable qu'avec LuaLaTeX : si un autre moteur de compilation (comme |latex|,
|pdflatex| ou |xelatex|) est utilisé, une erreur fatale sera levée.
\end{itemize}


\medskip
L'extension \pkg{piton} fournit trois outils pour composer du code Python: la commande |\piton|, l'environnement
|{Piton}| et la commande |\PitonInputFile|.

\begin{itemize}
\item La commande |\piton| doit être utilisée pour composer de petits éléments de code à l'intérieur d'un
paragraphe. \emph{Attention} : Cette fonction prend son argument en mode \emph{verbatim} (comme la commande
\verb|\verb|) et, de ce fait, cette fonction ne peut pas être utilisée à l'intérieur d'un argument d'une autre
fonction (on peut néanmoins l'utiliser à l'intérieur d'un environnement).

\item L'environnement |{Piton}| doit être utilisé pour composer des codes de plusieurs lignes. Pour les besoins de
personnalisation, il est possible de définir de nouveaux environnements similaires à |{Piton}| en utilisant la
commande |\NewPitonEnvironment| : cf. partie \ref{NewPitonEnvironment} p.~\pageref{NewPitonEnvironment}. 

\item La commande |\PitonInputFile| doit être utilisée pour insérer et composer un fichier extérieur.

\colorbox{yellow!50}{\textbf{Nouveau 0.95}}\enskip La commande |\PitonInputFile| prend en argument optionnel entre
crochets deux clés |first-line| et |last-line| qui permettent de n'insérer que la partie du fichier comprise entre
les lignes correspondantes.
\end{itemize}


\section{Personnalisation}

\subsection{La commande \textbackslash PitonOptions}

La commande |\PitonOptions| prend en argument une liste de couples \textsl{clé=valeur}. La portée des réglages
effectués par cette commande est le groupe TeX courant.\footnote{On rappelle que tout environnement LaTeX est, en particulier, un groupe.}

\begin{itemize}
\item La clé |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
nécessairement des espaces.

\item Quand la clé |auto-gobble| est activée, l'extension \pkg{piton} détermine la valeur minimale $n$ du nombre
d'espaces successifs débutant chaque ligne (non vide) de l'environnement |{Piton}| et applique |gobble| avec cette
valeur de~$n$.

\item Quand la clé |env-gobble| est activée, \pkg{piton} analyse la dernière ligne de l'environnement, c'est-à-dire
celle qui contient le |\end{Piton}| et détermine si cette ligne ne comporte que des espaces suivis par
|\end{Piton}|. Si c'est le cas, \pkg{piton} calcule le nombre $n$ de ces espaces et applique |gobble| avec cette
valeur de~$n$. Le nom de cette clé vient de \emph{environment gobble}: le nombre d'espaces à retirer ne dépend que
de la position des délimiteurs |\begin{Piton}| et |\end{Piton}| de l'environnement.

\item Avec la clé |line-numbers|, les lignes \emph{non vides} (et toutes les lignes des \emph{docstrings}, y
compris celles qui sont vides) sont numérotées dans les environnements \verb|{Piton}| et dans les listings produits
par la commande |\PitonInputFile|.

\item Avec la clé |all-line-numbers|, \emph{toutes} les lignes sont numérotées, y compris les lignes vides.

\item La clé |left-margin| fixe une marge sur la gauche. Cette clé peut être utile, en particulier, en conjonction
avec l'une des clés |line-numbers| et |all-line-numbers| si on ne souhaite pas que les numéros de ligne soient dans
une position en débordement sur la gauche. 

\colorbox{yellow!50}{\textbf{Nouveau 0.95}}\enskip Il est possible de donner à la clé |left-margin| la valeur
spéciale~|auto|. Avec cette valeur, une marge est insérée automatiquement pour les numéros de ligne quand l'une des
clés |line-numbers| ou |all-line-numbers| est utilisée. Voir un exemple à la partie \ref{example-numbering}
p.~\pageref{example-numbering}.

\item Avec la clé |resume|, le compteur de lignes n'est pas remis à zéro comme il l'est normalement au début d'un
environnement |{Piton}| ou bien au début d'un listing produit par |\PitonInputFile|. Cela permet de poursuivre la
numérotation d'un environnement à l'autre.

\item La clé |splittable| autorise un saut de page dans les environnements |{Piton}| et les listings produits par
|\PitonInputFile|.

\smallskip
On peut donner comme valeur à la clé |splittable| un entier naturel~$n$. Avec une telle valeur, les environnements
|{Piton}| et les listings produits par |\PitonInputFile| sont sécables mais aucune coupure ne pourra avoir lieu
entre les $n$~premières lignes, ni entre les $n$~dernières. La valeur par défaut de la clé |splittable| vaut en
fait $1$, qui autorise les sauts de page partout.

\item La clé |background-color| fixe la couleur de fond des environnements |{Piton}| et des listings produits par
|\PitonInputFile| (ce fond a une largeur égale à la valeur courante de |\linewidth|). Même avec une couleur de
fond, les sauts de page sont possibles, à partir du moment où la clé |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|.}
\item \colorbox{yellow!50}{\textbf{Nouveau 0.95}}\enskip En activant la clé |show-spaces|, les espaces dans
les chaînes courtes (c'est-à-dire celles délimitées par |'| ou |"|) sont matérialisés par le caractère ␣ (U+2423 :
\textsc{open box}). Bien sûr, le caractère U+2423 doit être présent dans la fonte mono-chasse
utilisée.\footnote{L'extension \pkg{piton} utilise simplement la fonte mono-chasse courante. Pour la changer, le
  mieux est d'utiliser |\setmonofont| de \pkg{fontspec}.}


\begingroup
\PitonOptions{show-spaces}
Exemple : \piton|my_string = 'Très bonne réponse'|
\endgroup
\end{itemize}

\bigskip

\begingroup
\fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
\begin{Verbatim}
~emphase&\PitonOptions{line-numbers,auto-gobble,background-color = gray!15}@
\begin{Piton}
    from math import pi

    def arctan(x,n=10):
        """Compute the mathematical value of arctan(x)

        n is the number of terms in the sum
        """
        if x < 0:
            return -arctan(-x) # appel récursif
        elif x > 1: 
            return pi/2 - arctan(1/x) 
            #> (on a utilisé le fait que $\arctan(x)+\arctan(1/x)=\pi/2$ pour $x>0$)
        else: 
            s = 0
            for k in range(n):
                s += (-1)**k/(2*k+1)*x**(2*k+1)
            return s 
\end{Piton}
\end{Verbatim}
\endgroup

\begingroup
\PitonOptions{line-numbers,auto-gobble,background-color = gray!15}
\begin{Piton}
    from math import pi

    def arctan(x,n=10):
        """Compute the value of arctan(x)

        n is the number of terms in the sum
        """
        if x < 0:
            return -arctan(-x) # appel récursif
        elif x > 1: 
            return pi/2 - arctan(1/x) 
            #> (on a utilisé le fait que $\arctan(x)+\arctan(1/x)=\pi/2$ pour $x>0$)
        else: 
            s = 0
            for k in range(n):
                s += (-1)**k/(2*k+1)*x**(2*k+1)
            return s 
\end{Piton}
\endgroup


\subsection{Les styles}

\label{styles}

L'extension \pkg{piton} fournit la commande |\SetPitonStyle| pour personnaliser les différents styles utilisés pour
formater les éléments syntaxiques des listings Python. Ces personnalisations ont une portée qui correspond au
groupe TeX courant.\footnote{On rappelle que tout environnement LaTeX est, en particulier, un groupe.}

\bigskip
La commande |\SetPitonStyle| prend en argument une liste de couples \textsl{clé=valeur}. Les clés sont les noms des
styles et les valeurs sont les instructions LaTeX de formatage correspondantes.

\bigskip
Ces instructions LaTeX doivent être des instructions de formatage du type de |\bfseries|, |\slshape|,
|\color{...}|, etc. (les commandes de ce type sont parfois qualifiées de \emph{semi-globales}). Il est aussi
possible de mettre, \emph{à la fin de la liste d'instructions}, une commande LaTeX prenant exactement un argument.

\bigskip
Voici un exemple qui change le style utilisé pour le nom d'une fonction Python, au moment de sa définition
(c'est-à-dire après le mot-clé |def|).

\begin{Verbatim}
\SetPitonStyle
  { Name.Function = \bfseries \setlength{\fboxsep}{1pt}\colorbox{yellow!50} }
\end{Verbatim}

Dans cet exemple, |\colorbox{yellow!50}| doit être considéré comme le nom d'une fonction LaTeX qui prend exactement
un argument, puisque, habituellement, elle est utilisée avec la syntaxe 
|\colorbox{yellow!50}{|\texttt{\slshape text}|}|. 

\medskip
\begingroup
\SetPitonStyle 
  { Name.Function = \bfseries \setlength{\fboxsep}{1pt}\colorbox{yellow!50} }
Avec ce réglage, on obtient : \piton{def cube(x) : return x * x * x }
\endgroup


\bigskip
Les différents styles sont décrits dans la table \ref{Semantic}. Les réglages initiaux effectués par \pkg{piton}
dans |piton.sty| sont inspirés par le style \pkg{manni} de Pygments.\footnote{Voir
  \url{https://pygments.org/styles/}. À remarquer que, par défaut, Pygments propose pour le style \pkg{manni} un
  fond coloré dont la couleur est la couleur HTML |#F0F3F3|.}

\begin{table}[htb]
\centering
\caption{Les styles proposés par \pkg{piton}}
\label{Semantic}
\begin{tabularx}{0.9\textwidth}{@{}>{\ttfamily}l>{\raggedright\arraybackslash}X@{}}
\toprule
\normalfont Style  & Usage \\
\midrule
Number & les nombres \\
String.Short & les chaînes de caractères courtes (entre \texttt{'} ou \texttt{"}) \\
String.Long & les chaînes de caractères longues (entre \texttt{'''} ou \texttt{"""}) sauf les chaînes de
              documentation \\
String & cette clé fixe à la fois |String.Short| et |String.Long| \\
String.Doc & les chaînes de documentation (seulement entre |"""| suivant PEP~257) \\
String.Interpol & les éléments syntaxiques des champs des f-strings (c'est-à-dire les caractères \texttt{\{}et \texttt{\}}) \\
Operator & les opérateurs suivants : \texttt{!= == << >> - \~{} + / * \% = < > \& .} \verb+|+ \verb|@| \\
Operator.Word & les opérateurs suivants : |in|, |is|, |and|, |or| et |not| \\
Name.Builtin & la plupart des fonctions prédéfinies par Python \\
Name.Function & le nom des fonctions définies par l'utilisateur \emph{au moment de leur définition}, c'est-à-dire 
                après le mot-clé \verb|def| \\ 
Name.Decorator & les décorateurs (instructions débutant par \verb|@|) \\
Name.Namespace & le nom des modules (= bibliothèques extérieures) \\
Name.Class & le nom des classes au moment de leur définition, c'est-à-dire après le mot-clé \verb|class| \\
Exception & le nom des exceptions prédéfinies (eg: SyntaxError) \\
Comment & les commentaires commençant par \texttt{\#} \\
Comment.LaTeX & les commentaires commençant par \texttt{\#>} qui sont composés en LaTeX par \pkg{piton} (et
                appelés simplement «commentaires LaTeX» dans ce document) \\
Keyword.Constant & |True|, |False| et |None| \\
Keyword & les mots-clés suivants :
          \ttfamily assert, break, case, continue, del,
          elif, else, except, exec, finally, for, from, 
          global, if, import, lambda, non local,
          pass, raise, return, try, while,
          with, yield, yield from.\\
  \bottomrule
\end{tabularx}
\end{table}






\subsection{Définition de nouveaux environnements}

\label{NewPitonEnvironment}

Comme l'environnement |{Piton}| a besoin d'absorber son contenu d'une manière spéciale (à peu près comme du texte
verbatim), il n'est pas possible de définir de nouveaux environnements directement au-dessus de l'environnement
|{Piton}| avec les commandes classiques |\newenvironment| et |\NewDocumentEnvironment|.

C'est pourquoi \pkg{piton} propose une commande |\NewPitonEnvironment|. Cette commande a la même syntaxe que la
commande classique |\NewDocumentEnvironment|.

\bigskip
Par exemple, avec l'instruction suivante, un nouvel environnement |{Python}| sera défini avec le même comportement
que l'environnement |{Piton}|:

{\color{gray}\verb|\NewPitonEnvironment{Python}{}{}{}|}


\bigskip
Si on souhaite un environnement |{Python}| qui prenne en argument optionnel entre crochets les clés de
|\PitonOptions|, on peut écrire :

{\color{gray}\verb|\NewPitonEnvironment{Python}{O{}}{\PitonOptions{#1}}{}|}

\bigskip
Si on souhaite un environnement |{Python}| qui compose le code inclus dans une boîte de \pkg{tcolorbox}, on peut
écrire:

\begin{verbatim}
\NewPitonEnvironment{Python}{}
  {\begin{tcolorbox}}
  {\end{tcolorbox}}
\end{verbatim}


\section{Fonctionnalités avancées}

\subsection{Les échappements vers LaTeX}

L'extension \pkg{piton} propose plusieurs mécanismes d'échappement vers LaTeX :
\begin{itemize}
\item Il est possible d'avoir des commentaires entièrement composés en LaTeX.
\item Il est possible d'avoir, dans les commentaires Python, les éléments entre \texttt{\$} composés en mode
mathématique de LaTeX.
\item Il est possible d'insérer du code LaTeX à n'importe quel endroit d'un listing Python.
\end{itemize}


\subsubsection{Les «commentaires LaTeX»}

Dans ce document, on appelle «commentaire LaTeX» des commentaires qui débutent par |#>|. Tout ce qui suit ces deux 
caractères, et jusqu'à la fin de la ligne, sera composé comme du code LaTeX standard.

Il y a deux outils pour personnaliser ces commentaires.

\begin{itemize}
\item \colorbox{yellow!50}{\bfseries Nouveau 0.95}\enskip Il est possible de changer le marquage syntaxique utilisé
(qui vaut initialement~|#>|). Pour ce faire, il existe une clé |comment-latex|, disponible seulement au chargement
de \pkg{piton} (c'est-à-dire au moment du |\usepackage|), qui permet de choisir les caractères qui (précédés
par~|#|) serviront de marqueur syntaxique. 

Par exemple, avec le chargement suivant :

\quad \verb|\usepackage[comment-latex = LaTeX]{piton}|

les commentaires LaTeX commenceront par~|#LaTeX|.

Si on donne la valeur nulle à la clé |comment-latex|, tous les commentaires Python (débutant par~|#|) seront en
fait des «commentaires LaTeX».

\smallskip
\item Il est possible de changer le formatage du commentaire LaTeX lui-même en changeant le style \pkg{piton}
|Comment.LaTeX|.

Par exemple, avec |\SetPitonStyle{Comment.LaTeX = \normalfont\color{blue}}|, les commentaires LaTeX seront composés
en bleu.

Pour d'autres exemples de personnalisation des commentaires LaTeX, voir la partie \ref{example-comments}
p.~\pageref{example-comments}. 
\end{itemize}


\subsubsection{La clé «math-comments»}

\colorbox{yellow!50}{\textbf{Nouveau 0.95}}\enskip Il est possible de demander que, dans les commentaires Python
normaux, c'est-à-dire débutant par |#| (et non par |#>|), les élements placés entre symboles \texttt{\$} soient
composés en mode mathématique de LaTeX (le reste du commentaire restant composé en verbatim).

La clé |math-comments|, qui n'est disponible qu'au chargement de \pkg{piton} (c'est-à-dire au moment du
|\usepackage|), active ce comportement.

\bigskip
Dans l'exemple suivant, on suppose que la clé |math-comments| a été utilisée au chargement de \pkg{piton}.

\begin{Verbatim}
\begin{Piton}
def carré(x):
    return x*x ~# renvoie $x^2$
\end{Piton}
\end{Verbatim}

\begin{Piton}
def carré(x):
    return x*x # renvoie $x^2$
\end{Piton}


\subsubsection{Le mécanisme «espace-inside»}

Il est aussi possible de surcharger les listings Python pour y insérer du code LaTeX à peu près n'importe où. Cette
fonctionnalité n'est pas activée par défaut par \pkg{piton}. Pour l'utiliser, il faut spécifier les deux caractères
marquant l'échappement (le premier le commençant et le deuxième le terminant) en utilisant la clé |escape-inside|
au chargement de \pkg{piton} (c'est-à-dire au moment du |\usepackage|). Les deux caractères peuvent être
identiques.


\bigskip
Dans l'exemple suivant, on suppose que l'extension \pkg{piton} a été chargée de la manière suivante :

\begin{Verbatim}
\usepackage[~emphase#escape-inside=$$@]{piton}
\end{Verbatim}

\medskip
Dans le code suivant, qui est une programmation récursive de la factorielle, on décide de surligner en jaune
l'instruction qui contient l'appel récursif.
\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{Attention} : L'échappement vers LaTeX permis par les caractères de |escape-inside| n'est pas actif dans les
chaînes de caractères ni dans les commentaires (pour avoir un commentaire entièrement en échappement vers LaTeX,
c'est-à-dire ce qui est 
appelé dans ce document «commentaire LateX», il suffit de le faire débuter par |#>|).



\bigskip
\subsection{Notes de pied de page dans les environnements de piton}

\label{footnote}

Si vous voulez mettre des notes de pied de page dans un environnement de \pkg{piton} (ou bien dans un listing
produit par |\PitonInputFile|, bien que cela paraisse moins pertinent dans ce cas-là) vous pouvez utiliser une
paire |\footnotemark|--|\footnotetext|. 

\smallskip
Néanmoins, il est également possible d'extraire les notes de pieds de page avec l'extension \pkg{footnote} ou bien
l'extension \pkg{footnotehyper}.

\smallskip
Si \pkg{piton} est chargée avec l'option |footnote| (avec |\usepackage[footnote]{piton}|) l'extension
\pkg{footnote} est chargée (si elle ne l'est pas déjà) et elle est utilisée pour extraire les notes de pied de
page.

\smallskip
Si \pkg{piton} est chargée avec l'option |footnotehyper|, l'extension \pkg{footnotehyper} est chargée (si
elle ne l'est pas déjà) et elle est utilisée pour extraire les notes de pied de page.

\smallskip
Attention : Les extensions \pkg{footnote} et \pkg{footnotehyper} sont incompatibles.
L'extension \pkg{footnotehyper} est le successeur de l'extension \pkg{footnote}
et devrait être utilisée préférentiellement. L'extension \pkg{footnote} a quelques défauts ;
en particulier, elle doit être chargée après l'extension \pkg{xcolor} et elle n'est pas parfaitement
compatible avec \pkg{hyperref}.

\medskip
Dans ce document, l'extension \pkg{piton} a été chargée avec l'option |footnotehyper| et c'est pourquoi des notes
peuvent être mises dans les environnements |{Piton}| : voir un exemple sur la première page de ce document. 

\subsection{Tabulations}

\smallskip
Même s'il est recommandé d'indenter les listings Python avec des espaces (cf. 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é |tab-size| de |\PitonOptions|.

\emph{Remarque} : Contrairement à ce qui se passe avec l'extension \pkg{listings}, la clé |gobble| (et ses
variantes |auto-gobble| et |env-gobble|) agit \emph{avant} la transformation des tabulations en espaces.

\section{Exemples}


\subsection{Numérotation des lignes}

\label{example-numbering}

On rappelle que l'on peut demander la numérotation des lignes des listings avec la clé |line-numbers| ou la clé |all-line-numbers|.

Par défaut, les numéros de ligne sont composés par \pkg{piton} en débordement à gauche (en utilisant en interne la commande |\llap| de LaTeX).

Si on ne veut pas de débordement, on peut utiliser l'option |left-margin=auto| qui va insérer une marge adaptée aux
numéros qui seront insérés (elle est plus large quand les numéros dépassent 10).


\begingroup
\fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
\begin{Verbatim}
~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)
    elif x > 1: 
        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}
\end{Verbatim}
\endgroup



\begingroup
\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)
    elif x > 1: 
        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}
\endgroup


\bigskip

\subsection{Formatage des commentaires LaTeX}

\label{example-comments}

On peut modifier le style |Comment.LaTeX| (avec |\SetPitonStyle|) pour faire afficher les commentaires 
LaTeX (qui débutent par |#>|) en butée à droite.

\begingroup
\fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
\begin{Verbatim}
\PitonOptions{background-color=gray!10}
~emphase&\SetPitonStyle{Comment.LaTeX = \hfill \normalfont\color{gray}}@
\begin{Piton}
def arctan(x,n=10):
    if x < 0:
        return -arctan(-x)        #> appel récursif
    elif x > 1: 
        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}
\end{Verbatim}
\endgroup

\begingroup
\PitonOptions{background-color=gray!10}
\SetPitonStyle{Comment.LaTeX = \hfill \normalfont\color{gray}}
\begin{Piton}
def arctan(x,n=10):
    if x < 0:
        return -arctan(-x)        #> appel récursif
    elif x > 1: 
        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}
\endgroup


\vspace{1cm}
On peut aussi faire afficher les commentaires dans une deuxième colonne à droite si on limite la largeur du code
proprement dit avec un environnement |{minipage}| de LaTeX.


\begingroup
\fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
\begin{Verbatim}
\PitonOptions{background-color=gray!10}
~emphase&\NewDocumentCommand{\MyLaTeXCommand}{m}{\hfill \normalfont\itshape\rlap{\quad #1}}@
~emphase&\SetPitonStyle{Comment.LaTeX = \MyLaTeXCommand}@
~emphase&\begin{minipage}{12cm}@
\begin{Piton}
def arctan(x,n=10):
    if x < 0:
        return -arctan(-x)       #> appel récursif
    elif x > 1: 
        return pi/2 - arctan(1/x) #> autre appel récursif 
    else: 
        s = 0
        for k in range(n):
             s += (-1)**k/(2*k+1)*x**(2*k+1)
        return s 
\end{Piton}
~emphase&\end{minipage}@
\end{Verbatim}
\endgroup



\begingroup
\PitonOptions{background-color=gray!10}
\NewDocumentCommand{\MyLaTeXCommand}{m}{\hfill \normalfont\itshape\rlap{\quad #1}}
\SetPitonStyle{Comment.LaTeX = \MyLaTeXCommand}
\begin{minipage}{12cm}
\begin{Piton}
def arctan(x,n=10):
    if x < 0:
        return -arctan(-x)       #> appel récursif
    elif x > 1: 
        return pi/2 - arctan(1/x) #> autre appel récursif 
    else: 
        s = 0
        for k in range(n):
             s += (-1)**k/(2*k+1)*x**(2*k+1)
        return s 
\end{Piton}
\end{minipage}
\endgroup

\bigskip

\subsection{Notes dans les listings}

Pour pouvoir extraire les notes (introduites par |\footnote|), l'extension |piton| doit être chargée, soit avec la
clé |footnote|, soit avec la clé |footnotehyper|, comme expliqué à la section \ref{footnote} p.~\pageref{footnote}.
Dans le présent document, l'extension \pkg{piton} a été chargée par la clé |footnotehyper|.

Bien entendu, une commande |\footnote| ne peut apparaître que dans un commentaire LaTeX (qui débute par |#>|). Un
tel commentaire peut se limiter à cette unique commande |\footnote|, comme dans l'exemple suivant.

\begingroup
\fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
\begin{Verbatim}
\PitonOptions{background-color=gray!10}
\begin{Piton}
def arctan(x,n=10):
    if x < 0:
        return -arctan(-x)~emphase&#>\footnote{Un premier appel récursif.}]@
    elif x > 1: 
        return pi/2 - arctan(1/x)~emphase&#>\footnote{Un deuxième appel récursif.}@
    else: 
        return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
\end{Piton}
\end{Verbatim}
\endgroup

\begingroup
\PitonOptions{background-color=gray!10}
\begin{Piton}
def arctan(x,n=10):
    if x < 0:
        return -arctan(-x)#>\footnote{Un premier appel récursif.}
    elif x > 1: 
        return pi/2 - arctan(1/x)#>\footnote{Un deuxième appel récursif.}
    else: 
        return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
\end{Piton}
\endgroup


\vspace{1cm}

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. 


\begingroup
\fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
\begin{Verbatim}
\PitonOptions{background-color=gray!10}
\emphase\begin{minipage}{\linewidth}
\begin{Piton}
def arctan(x,n=10):
    if x < 0:
        return -arctan(-x)~emphase&#>\footnote{Un premier appel récursif.}@
    elif x > 1: 
        return pi/2 - arctan(1/x)~emphase&#>\footnote{Un deuxième appel récursif.}@
    else: 
        return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
\end{Piton}
\end{minipage}
\end{Verbatim}
\endgroup

\begingroup
\PitonOptions{background-color=gray!10}
\begin{minipage}{\linewidth}
\begin{Piton}
def arctan(x,n=10):
    if x < 0:
        return -arctan(-x)#>\footnote{Un premier appel récursif.}
    elif x > 1: 
        return pi/2 - arctan(1/x)#>\footnote{Un deuxième appel récursif.}
    else: 
        return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
\end{Piton}
\end{minipage}
\endgroup


\vspace{1cm}
Si on encapsule l'environnement |{Piton}| dans un environnement |{minipage}| pour, typiquement, limiter la largeur
d'un fond coloré, il faut encadrer l'ensemble dans un environnement |{savenotes}| (de \pkg{footnote} ou
\pkg{footnotehyper}) si on veut avoir les notes reportées en pied de page.

\begingroup
\fvset{commandchars=\~\&\@,formatcom=\small\color{gray}}
\begin{Verbatim}
\PitonOptions{background-color=gray!10}
~emphase&\begin{savenotes}@
\begin{minipage}{13cm}
\begin{Piton}
def arctan(x,n=10):
    if x < 0:
        return -arctan(-x)~emphase&#>\footnote{Un premier appel récursif.}@
    elif x > 1: 
        return pi/2 - arctan(1/x)~emphase&#>\footnote{Un deuxième appel récursif.}@
    else: 
        return sum( (-1)**k/(2*k+1)*x**(2*k+1) for k in range(n) ) 
\end{Piton}
\end{minipage}
~emphase&\end{savenotes}@
\end{Verbatim}
\endgroup



\begin{savenotes}
\PitonOptions{background-color=gray!10}
\begin{minipage}{13cm}
\begin{Piton}
def arctan(x,n=10):
    if x < 0:
        return -arctan(-x)#>\footnote{Un premier appel récursif.}
    elif x > 1: 
        return pi/2 - arctan(1/x)#>\footnote{Un deuxième appel récursif.}
    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{Un exemple de réglage des styles}

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}.


\begin{Verbatim}
\setmonofont[Scale=0.85]{DejaVu Sans Mono}

\SetPitonStyle
  {
    Number = ,
    String = \itshape , 
    String.Doc = \color{gray} \itshape ,
    Operator = , 
    Operator.Word = \bfseries ,
    Name.Builtin = ,
    Name.Function = \bfseries \colorbox{gray!20} ,
    Comment = \color{gray} ,
    Comment.LaTeX = \normalfont \color{gray},
    Keyword = \bfseries ,
    Name.Namespace = ,
    Name.Class = , 
    Name.Type = ,
    InitialValues = \color{gray}
  }
\end{Verbatim}


\begingroup


\setmonofont[Scale=0.85]{DejaVu Sans Mono}

\SetPitonStyle
  {
    Number = ,
    String = \itshape , 
    String.Doc = \color{gray} \itshape ,
    Operator = , 
    Operator.Word = \bfseries ,
    Name.Builtin = ,
    Name.Function = \bfseries \colorbox{gray!20} ,
    Comment = \color{gray} ,
    Comment.LaTeX = \normalfont \color{gray},
    Keyword = \bfseries ,
    Name.Namespace = ,
    Name.Class = , 
    Name.Type = ,
    InitialValues = \color{gray}
  }


\bigskip 

\begin{Piton}
from math import pi

def arctan(x,n=10):
    """Compute the mathematical value of arctan(x)

    n is the number of terms in the sum
    """
    if x < 0:
        return -arctan(-x) # appel récursif
    elif x > 1: 
        return pi/2 - arctan(1/x) 
        #> (on a utilisé le fait que $\arctan(x)+\arctan(1/x)=\pi/2$ pour $x>0$)
    else: 
        s = 0
        for k in range(n):
            s += (-1)**k/(2*k+1)*x**(2*k+1)
        return s 
\end{Piton}


\endgroup

\section{Utilisation avec pyluatex}

L'extension \pkg{pyluatex} est une extension iqui permet l'exécution de code Python à partir |lualatex| (pourvu
que Python soit installé sur la machine et que la compilation soit effectuée avec |lualatex| et |--shell-escape|).

Voici, à titre d'exemple, un environnement |{PitonExecute}| qui formate un listing Python (avec \pkg{piton}) et qui
affiche également dessous le résultat de l'exécution de ce code avec 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

Cet environnement |{PitonExcecute}| prend en argument optionnel (entre crochets) les options proposées par la
commande |\PitonOptions|.

\bigskip
Voici un exemple d'utilisation de cet environnement |{PitonExecute}| :

\begin{Verbatim}
\begin{~emphase#PitonExecute@}[background-color=gray!15]
def square(x):
    return x*x
print(f'The square of 12 is {square(12)}.')
\end{~emphase#PitonExecute@}
\end{Verbatim}


\medskip
\begin{PitonExecute}[background-color=gray!15]
def square(x):
    return x*x
print(f'The square of 12 is {square(12)}.')
\end{PitonExecute}



\section*{Autre documentation}

Le document |piton.pdf| (fourni avec l'extension \pkg{piton}) contient une traduction anglaise de la
documentation ici présente, ainsi que le code source commenté et un historique des versions. 


\end{document}