PythonTeX (intégrer la sortie)

PythonTeX (par Geoffrey M. Poore) est un package qui exécute réellement, au moment de la compilation, le code Python écrit dans le document, puis réinsère les résultats dans le texte. Graphiques, tableaux et valeurs calculées restent à côté du code qui les produit : plus de risque de recopier une valeur à la main, et une modification de la source suivie d’une recompilation met les résultats à jour automatiquement. Outre Python, il peut aussi piloter Ruby, Julia, R, Octave, etc.

Ce qu’il fait

Les packages ordinaires comme listings ou minted ne font que composer le code tel qu’il apparaît ; ils ne l’exécutent jamais (voir « Code listings »). PythonTeX se distingue parce qu’il exécute le code et ramène sa sortie dans le document. Écrivez \py{2**10} dans le texte : Python évalue 2**10, et le résultat 1024 est composé à cet endroit. Écrivez du Python qui trace un graphique, et la figure générée apparaît comme figure.

Le chargement tient en une ligne, \usepackage{pythontex}. Pour l’exécution, il faut Python lui-même ; la coloration syntaxique utilise Pygments (pip install pygments). Le code s’exécute dans un processus séparé par « session », et seules les parties modifiées sont relancées ; même avec de gros calculs, la recompilation reste légère.

Les commandes et environnements forment une famille : un nom de base commun, comme py, plus un suffixe. On choisit selon le besoin : exécuter une expression inline, exécuter un bloc entier, montrer aussi le code, ou ne vouloir que le résultat.

Commandes et environnements principaux

Commençons par les commandes inline. \py{expr} envoie l’expression à Python et compose sa représentation sous forme de chaîne (\py{2**10} → 1024). Outre les accolades, une paire du même délimiteur fonctionne aussi : \py#2**10# et \py@2**10@ ont le même sens. Cette commande sert à insérer une valeur dans le texte ; les affectations sont interdites (\py{a=1} est invalide). Si une variable a été définie plus tôt, \py{a} récupère sa valeur.

  • \py{expr} — exécute l’expression et compose son résultat (sans suffixe).
  • \pyc{code} — exécute le code, mais ne compose rien (c pour code). Ce qui est produit par print est récupéré.
  • \pyv{code} — n’exécute pas ; compose le code tel quel (v pour verb, équivalent à pyverbatim).
  • \pyb{code}exécute et compose (b pour block). Les sorties de print ne sont pas incluses automatiquement.
  • \pys{code} — interpolation de chaîne : remplace chaque !{expr} par son résultat, puis interprète le code comme du LaTeX (s pour sub).

Pour plusieurs lignes, utilisez les environnements. pycode exécute le code mais ne compose rien, idéal pour les calculs ou la génération de figures. pyverbatim compose sans exécuter. pyblock exécute et compose. pysub est la forme environnement de \pys (interpolation de !{expr}). Les sorties de print dans pyblock ou \pyb n’apparaissent pas seules ; placez \printpythontex là où vous voulez les insérer.

Pour montrer une session interactive, utilisez l’environnement pyconsole. Chaque ligne y est traitée comme si elle était saisie dans un interpréteur Python interactif, avec le prompt >>>, les entrées et les sorties. La forme inline \pycon{code} exécute le code et ne récupère que la sortie (l’entrée est ignorée), pratique pour citer la valeur d’une variable de console.

Un exemple

Le flux typique consiste à calculer une valeur dans un environnement pycode, puis à utiliser \py{…} dans le texte pour la composer. Le code et son résultat vivent ainsi dans un seul manuscrit.

document.tex
\documentclass{article}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{pythontex}

\begin{document}
% 実行されるが、何も組版されない
\begin{pycode}
from math import sqrt
radius = 2.5
area = 3.14159 * radius**2
hyp = sqrt(3**2 + 4**2)
\end{pycode}

半径 \py{radius} の円の面積はおよそ \py{round(area, 2)} です。

\(2^{10} = \py{2**10}\)、また \(\sqrt{3^2+4^2} = \py{hyp}\)\end{document}

On obtient une phrase du type « l’aire d’un cercle de rayon 2.5 est environ 19.63 », suivie des équations 2¹⁰ = 1024 et √(3²+4²) = 5.0. Changez radius et reconstruisez : toutes les valeurs du texte suivent.

Le flux de compilation (trois étapes)

Une compilation PythonTeX comporte trois étapes. (1) Lancez le moteur LaTeX, par exemple pdflatex, comme d’habitude ; à cette passe, le code n’est pas exécuté mais extrait vers un fichier externe. (2) Le programme fourni pythontex exécute ce code extrait et enregistre les résultats. (3) Lancez de nouveau le moteur LaTeX : les résultats enregistrés sont réintégrés dans le document pour produire le PDF.

terminal
pdflatex document.tex    # 1) コードを抽出 / extract the code
pythontex document.tex   # 2) Python で実行 / run it with Python
pdflatex document.tex    # 3) 結果を取り込む / pull the output back in

Le point clé est le suivant : le code n’est pas exécuté par LaTeX lui-même, mais par un programme séparé, pythontex, intercalé entre deux passes. Ainsi, la compilation manuelle en trois étapes n’a pas besoin de --shell-escape ; c’est précisément ce qui la distingue de minted, qui lance des commandes externes depuis LaTeX. Si vous voulez l’automatiser en une seule compilation avec un outil comme latexmk, une configuration courante active -shell-escape pour permettre à la passe LaTeX d’appeler pythontex. Une dépendance dans .latexmkrc permet alors de relancer pythontex et de recompiler quand le code change.

Cela fonctionne aussi pour les documents japonais. Remplacez pdflatex par lualatex et les trois mêmes étapes s’appliquent, quel que soit le moteur ; le platex japonais est également possible. Lorsque le code contient de l’Unicode, configurez l’encodage du document : avec pdfLaTeX, \usepackage[T1]{fontenc} et \usepackage[utf8]{inputenc} ; avec LuaLaTeX, \usepackage{fontspec}.

Les familles sympy et pylab

Par défaut, à côté de la famille Python py, deux familles destinées au calcul scientifique sont fournies. Elles ne font que remplacer le nom de base par sympy ou pylab, avec la même série de commandes : \sympy, sympycode, sympyblock, ainsi que \pylab, pylabcode, pylabblock.

  • La famille sympy — charge la bibliothèque de calcul symbolique SymPy avec from sympy import *. Un résultat inséré par \sympy est formaté en LaTeX contextuel avec le LatexPrinter de SymPy.
  • La famille pylab — charge le module pylab de matplotlib avec from pylab import *, regroupant tracés et NumPy dans le même espace de noms.

Les familles peuvent être utilisées côte à côte comme ensembles indépendants de commandes et d’environnements. On peut, par exemple, composer une expression résolue symboliquement par SymPy avec \sympy, puis générer une figure matplotlib dans pylabcode et l’inclure avec \includegraphics.

depythontex et sécurité

Un document PythonTeX mélange LaTeX et Python ; il convient donc mal aux lieux de soumission qui refusent les packages spéciaux, ou aux conversions vers d’autres formats. depythontex sert à cela. En compilant avec l’option de package depythontex, un fichier auxiliaire <jobname>.depytx est créé ; le script depythontex.py le rapproche de la source originale pour produire un document séparé où toutes les commandes et tous les environnements PythonTeX sont remplacés par le code composé et sa sortie. Le résultat est un LaTeX ordinaire, sans dépendance à PythonTeX, avec les résultats intégrés : pratique pour le partage ou la soumission.

terminal
# 1) depythontex オプション付きで通常の 3 ステップを実行
#    Run the usual three steps with the depythontex option on
pdflatex document.tex
pythontex document.tex
pdflatex document.tex

# 2) 静的な版を書き出す(-o で出力名を指定)
#    Write the static version (-o gives the output name)
depythontex -o document-plain.tex document.tex

Enfin, gardez en tête la sécurité. Compiler un document utilisant PythonTeX exécute réellement Python, et parfois d’autres programmes, sur votre machine. Il faut donc compiler uniquement des documents provenant de sources fiables. Dès qu’un mécanisme « exécute » du code, cette propriété est inévitable, comme avec les autres approches reposant sur --shell-escape.