PythonTeX(Geoffrey M. Poore 제작)는 문서 안에 쓴 Python 코드를 컴파일할 때 실제로 실행하고, 그 결과를 다시 본문에 삽입하는 패키지입니다. 그래프, 표, 계산 결과가 그것을 만든 코드와 한 원고 안에 있으므로 값을 손으로 옮기다 틀릴 걱정이 줄고, 소스를 고쳐 다시 빌드하면 결과도 자동으로 갱신됩니다. Python뿐 아니라 Ruby, Julia, R, Octave 등도 다룰 수 있습니다.
무엇을 하는가
일반적인 listings나 minted는 코드를 보이는 모양대로 조판 할 뿐 실행하지 않습니다(“코드 목록” 참조). PythonTeX가 다른 점은 코드를 실행하고 그 출력을 문서에 가져온다 는 것입니다. 예를 들어 본문에 \py{2**10}을 쓰면 Python이 2**10을 평가하고, 결과 1024가 그 자리에 조판됩니다. 그래프를 그리는 Python 코드를 쓰면 생성된 그림이 그대로 그림으로 나타납니다.
불러오는 것은 \usepackage{pythontex} 한 줄이면 됩니다. 실행하려면 Python 자체 가 필요하고, 코드 색상 표시(문법 강조)에는 Pygments(pip install pygments)를 사용합니다. 코드는 “세션”별로 별도 프로세스에서 실행되며, 변경된 부분만 다시 실행되므로 무거운 계산이 있어도 재컴파일은 가볍게 끝납니다.
명령과 환경은 공통의 기본 이름(py 등)에 접미사를 붙인 한 가족으로 제공됩니다. “인라인에서 표현식 하나를 실행할지”, “코드 블록 전체를 실행할지”, “코드도 함께 보여 줄지”, “결과만 필요한지”에 따라 골라 씁니다.
주요 명령과 환경
먼저 인라인 명령 입니다. \py{expr}은 표현식을 Python에 넘기고 그 문자열 표현을 조판합니다(\py{2**10} → 1024). 중괄호 말고도 같은 기호 한 쌍을 구분자로 쓸 수 있어 \py#2**10#와 \py@2**10@도 같은 뜻입니다. 값을 문서에 끼워 넣기 위한 것이므로 대입은 할 수 없습니다(\py{a=1}은 불가). 앞에서 변수를 만들어 두면 \py{a}로 그 값을 불러올 수 있습니다.
\py{expr}— 표현식을 실행하고 결과를 조판합니다(접미사 없음).\pyc{code}— 실행하지만 아무것도 조판하지 않습니다(c는 code). 내부에서print하면 그 출력은 가져옵니다.\pyv{code}— 실행하지 않고 코드를 그대로 조판 합니다(v는 verb,pyverbatim에 해당).\pyb{code}— 실행도 하고 조판도 합니다(b는 block).print출력은 자동으로 들어가지 않습니다.\pys{code}— 문자열 보간.!{expr}을 평가 결과로 바꾼 뒤 코드를 LaTeX로 해석합니다(s는 sub).
여러 줄에는 환경 을 사용합니다. pycode는 안의 코드를 실행하지만 조판하지 않습니다(계산이나 그림 생성에 적합). pyverbatim은 조판만 하고 실행하지 않습니다. pyblock은 실행도 조판도 합니다. pysub는 \pys의 환경판(!{expr} 보간)입니다. pyblock이나 \pyb의 print 출력은 저절로 나타나지 않으므로, 출력하고 싶은 위치에 \printpythontex를 두어 가져옵니다.
대화형 세션을 보여 주고 싶을 때는 pyconsole 환경 을 씁니다. 안의 각 줄을 대화형 Python 인터프리터에 입력한 것처럼 다루고, >>> 프롬프트와 입력·출력을 함께 재현합니다. 인라인판 \pycon{code}는 코드를 실행하고 출력만 가져오며(입력은 버림), 콘솔 변수 값을 참조할 때 유용합니다.
사용 예
전형적인 흐름은 pycode 환경에서 값을 계산해 두고, 본문에서 \py{…}를 사용해 그 값을 조판하는 것입니다. 코드와 결과가 한 원고 안에서 완결된다는 점에 주목하세요.
\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}이는 “반지름 2.5인 원의 넓이는 약 19.63입니다”라는 문장으로 이어지고, 수식으로 2¹⁰ = 1024 및 √(3²+4²) = 5.0이 조판됩니다. radius를 바꾸고 다시 빌드하면 본문의 모든 숫자도 함께 바뀝니다.
빌드 흐름(세 단계)
PythonTeX 빌드는 세 단계 입니다. (1) 먼저 보통처럼 LaTeX 엔진(pdflatex 등)을 실행합니다. 이때 본문 속 코드는 실행되지 않고 외부 파일로 추출 됩니다. (2) 함께 제공되는 pythontex 프로그램 이 추출된 코드를 실행하고 결과를 저장합니다. (3) LaTeX 엔진을 한 번 더 실행하면 저장된 결과가 본문에 가져와져 PDF가 만들어집니다.
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핵심은 이것입니다. 코드를 실행하는 것은 LaTeX 본체가 아니라 중간에 끼는 독립 프로그램 pythontex 입니다. 그래서 수동 3단계 빌드에는 --shell-escape가 필요 없습니다. 외부 명령을 LaTeX 안에서 직접 호출하는 minted와 다른 지점입니다. 반면 latexmk 등으로 한 번의 컴파일 흐름에 자동화 하고 싶다면 LaTeX 경로에서 pythontex를 호출하기 위해 -shell-escape를 켜는 구성이 자주 쓰입니다. .latexmkrc에 의존 관계를 적어 두면 코드가 바뀔 때 pythontex 실행과 재컴파일을 자동으로 처리할 수 있습니다.
일본어 문서에서도 사용할 수 있습니다. pdflatex를 lualatex로 바꾸어도 엔진과 관계없이 같은 세 단계로 동작합니다(일본어 LaTeX의 platex도 가능). Unicode가 들어간 코드를 다룰 때는 문서 쪽 문자 인코딩을 맞춰 둡니다. pdfLaTeX라면 \usepackage[T1]{fontenc}와 \usepackage[utf8]{inputenc}, LuaLaTeX라면 \usepackage{fontspec} 같은 설정을 둡니다.
sympy와 pylab 가족
기본적으로 Python의 py 가족에 더해 과학 계산용 가족 두 개가 제공됩니다. 둘 다 기본 이름만 sympy 또는 pylab로 바꾼 것으로, \sympy, sympycode, sympyblock, \pylab, pylabcode, pylabblock처럼 같은 명령 구성을 갖습니다.
- sympy 계열 — 기호 계산 라이브러리 SymPy를
from sympy import *로 불러옵니다.\sympy로 삽입한 수식은 SymPy의LatexPrinter를 사용해 문맥에 맞는 LaTeX 표기로 정리됩니다. - pylab 계열 — matplotlib의
pylab모듈을from pylab import *로 불러와 그래프 작성과 NumPy를 한 이름공간에서 함께 씁니다.
각 가족은 독립적인 명령·환경 묶음으로 나란히 사용할 수 있습니다. 예를 들어 SymPy로 기호적으로 푼 식을 \sympy로 깔끔한 수식으로 조판하고, matplotlib로 그린 그림은 pylabcode에서 생성해 \includegraphics로 넣을 수 있습니다.
depythontex와 안전성
PythonTeX 문서는 LaTeX와 Python이 섞이므로, 특수 패키지를 받지 않는 투고처나 다른 형식으로의 변환에는 맞지 않습니다. 이때 depythontex 가 유용합니다. 패키지 옵션 depythontex를 켜고 빌드하면 보조 파일 <jobname>.depytx가 만들어지고, depythontex.py 스크립트가 이것과 원본 원고를 맞추어 모든 PythonTeX 명령과 환경을 조판된 코드와 출력으로 바꾼 별도 문서를 생성합니다. 결과가 고정되어 PythonTeX에 의존하지 않는 평범한 LaTeX가 되므로 공유나 논문 투고에 사용할 수 있습니다.
# 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마지막으로 보안 에 주의하세요. PythonTeX를 포함한 문서를 컴파일하면 당신의 컴퓨터에서 Python(경우에 따라 다른 프로그램도)을 실제로 실행 합니다. 따라서 신뢰할 수 있는 출처의 문서만 컴파일해야 합니다. “실행”하는 구조인 이상, 이는 --shell-escape를 쓰는 다른 방식과 마찬가지로 피할 수 없는 성질입니다.