PythonTeX (incrustar salida)

PythonTeX (de Geoffrey M. Poore) es un paquete que ejecuta realmente, durante la compilación, el código Python que escribes dentro del documento y vuelve a incrustar los resultados en el texto. Gráficas, tablas y valores calculados viven junto al código que los produjo; así no hay riesgo de copiar mal un número a mano, y al cambiar la fuente y recompilar los resultados se actualizan automáticamente. Además de Python, puede manejar Ruby, Julia, R, Octave y más.

Qué hace

Los paquetes normales como listings o minted solo componen el código tal como se ve; no lo ejecutan (véase “Code listings”). PythonTeX se diferencia en que ejecuta el código y lleva su salida al documento. Escribe \py{2**10} en el texto y Python evaluará 2**10, de modo que el resultado 1024 se componga justo ahí. Escribe Python que dibuje una gráfica y la figura generada aparecerá como figura.

Se carga con una sola línea, \usepackage{pythontex}. Para ejecutarlo necesitas Python; el resaltado de sintaxis usa Pygments (pip install pygments). El código se ejecuta en un proceso separado por “sesión”, y solo se relanzan las partes que cambiaron, así que recompilar sigue siendo ligero incluso con cálculos pesados.

Los comandos y entornos forman una familia: un nombre base compartido, como py, más un sufijo. Se elige según lo que necesites: ejecutar una expresión en línea, ejecutar un bloque entero, mostrar también el código o quedarte solo con el resultado.

Comandos y entornos principales

Empecemos por los comandos en línea. \py{expr} envía la expresión a Python y compone su representación como cadena (\py{2**10} → 1024). Además de llaves, también funciona un par de delimitadores iguales, de modo que \py#2**10# y \py@2**10@ significan lo mismo. Sirve para insertar un valor en el texto, por lo que no permite asignaciones (\py{a=1} no es válido). Define antes una variable y \py{a} recuperará su valor.

  • \py{expr} — ejecuta la expresión y compone su resultado (sin sufijo).
  • \pyc{code} — lo ejecuta, pero no compone nada (c de code). Cualquier print dentro se incorpora.
  • \pyv{code} — no lo ejecuta; compone el código literalmente (v de verb; equivalente a pyverbatim).
  • \pyb{code}lo ejecuta y lo compone (b de block). La salida de print no se incluye automáticamente.
  • \pys{code} — interpolación de cadenas: sustituye cada !{expr} por su resultado evaluado y luego interpreta el código como LaTeX (s de sub).

Para varias líneas usa entornos. pycode ejecuta el código pero no compone nada, ideal para cálculos o generación de figuras. pyverbatim compone sin ejecutar. pyblock ejecuta y compone. pysub es la forma de entorno de \pys (interpolación de !{expr}). La salida de print en pyblock o \pyb no aparece por sí sola; coloca \printpythontex donde quieras traerla.

Para mostrar una sesión interactiva, usa el entorno pyconsole. Trata cada línea como si se hubiera escrito en un intérprete interactivo de Python, reproduciendo el prompt >>> junto con entrada y salida. La forma en línea \pycon{code} ejecuta el código y trae solo la salida (descarta la entrada), útil para referirse al valor de una variable de consola.

Un ejemplo

Un flujo típico es calcular un valor en un entorno pycode y luego usar \py{…} en la prosa para componerlo. Observa que el código y su resultado viven dentro de un único manuscrito.

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}

Esto produce una frase como “el área de un círculo de radio 2.5 es aproximadamente 19.63”, seguida de las ecuaciones 2¹⁰ = 1024 y √(3²+4²) = 5.0. Cambia radius y reconstruye: todos los números del texto cambiarán con él.

El flujo de construcción (tres pasos)

Una construcción con PythonTeX tiene tres etapas. (1) Ejecuta el motor LaTeX, por ejemplo pdflatex, como siempre; en esta pasada el código no se ejecuta, sino que se extrae a un archivo externo. (2) El programa incluido pythontex ejecuta ese código extraído y guarda los resultados. (3) Ejecuta otra vez el motor LaTeX, y los resultados guardados se incorporan al documento para crear el 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

Este es el punto clave: el código no lo ejecuta LaTeX, sino un programa separado, pythontex, entre medias. Por eso la construcción manual en tres pasos no necesita --shell-escape; ahí se diferencia de minted, que lanza comandos externos desde LaTeX. Si quieres automatizarlo en una sola compilación con una herramienta como latexmk, una configuración común activa -shell-escape para que la pasada de LaTeX pueda invocar pythontex. Declarar la dependencia en .latexmkrc permite ejecutar pythontex y recompilar automáticamente cuando cambia el código.

También funciona con documentos japoneses. Cambia pdflatex por lualatex y se aplican los mismos tres pasos sea cual sea el motor; también vale el platex japonés. Cuando el código contiene Unicode, configura la codificación del documento: con pdfLaTeX, \usepackage[T1]{fontenc} y \usepackage[utf8]{inputenc}; con LuaLaTeX, \usepackage{fontspec}.

Las familias sympy y pylab

De forma predeterminada, junto a la familia Python py, se ofrecen dos familias orientadas al trabajo científico. Solo cambian el nombre base a sympy o pylab, con la misma lista de comandos: \sympy, sympycode, sympyblock, y \pylab, pylabcode, pylabblock.

  • La familia sympy — carga la biblioteca de cálculo simbólico SymPy mediante from sympy import *. Un resultado insertado con \sympy se formatea como LaTeX contextual usando el LatexPrinter de SymPy.
  • La familia pylab — carga el módulo pylab de matplotlib mediante from pylab import *, reuniendo gráficos y NumPy en un mismo espacio de nombres.

Las familias pueden usarse en paralelo como conjuntos independientes de comandos y entornos. Por ejemplo, puedes componer una expresión resuelta simbólicamente por SymPy como matemática limpia con \sympy, y generar una figura de matplotlib en pylabcode para incluirla con \includegraphics.

depythontex y seguridad

Como un documento PythonTeX mezcla LaTeX y Python, encaja mal en lugares de envío que rechazan paquetes especiales o en conversiones a otros formatos. Ahí ayuda depythontex. Al compilar con la opción de paquete depythontex, se crea un archivo auxiliar <jobname>.depytx; el script depythontex.py lo cruza con la fuente original para producir un documento separado en el que todos los comandos y entornos de PythonTeX se sustituyen por el código compuesto y su salida. El resultado es LaTeX plano, sin dependencia de PythonTeX, con los resultados ya incorporados, apto para compartir o enviar a una revista.

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

Por último, ten presente la seguridad. Compilar un documento que usa PythonTeX ejecuta realmente Python, y quizá otros programas, en tu máquina. Por tanto, compila solo documentos de fuentes en las que confíes. Es una propiedad inevitable de cualquier mecanismo que “ejecuta” código, igual que en otros enfoques basados en --shell-escape.