4

I started to use the excellent PythonTex package to write reproducible reports but can't seem to get it to evaluate Python code inside a LaTeX command.

R has Sweave & knitr which provide the \Sexpr{} command that lets you access variables declared in R chunks inside a LaTeX command. This works in R with Sweave/knitr:

\documentclass{article}
\usepackage{siunitx}
\begin{document}
<<read, engine='R'>>=
y = 4
@
The value of y is $\SI{\Sexpr{y}}{\metre}$.
\end{document}

However, the following does not seem to work in PythonTex:

\documentclass{article}
\usepackage{siunitx}
\usepackage{pythontex}
\begin{document}
\pyc{y = 4}

The value of y is $\SI{\py{y}}{\metre}$.

\end{document}

Am I missing something? Is there a way to achieve \Sexpr{} functionality in PythonTex?

Thanks for your help!

majahn
  • 43
  • 1
    Welcome to TeX.SX! Your post was migrated here from another Stack Exchange site. Please register on this site, too, and make sure that both accounts are associated with each other (by using the same OpenID), otherwise you won't be able to comment on or accept answers or edit your question. – Joseph Wright Jul 01 '13 at 20:34

1 Answers1

7

You can do what you want, but the approach is a bit different from Sweave and knitr.

With Sweave and knitr, the file you create is a .Rnw, and the output is .tex. In the .tex, each \Sexpr{...} is replaced by its output. So in the final .tex file that is compiled, there are no \Sexpr{...}.

With PythonTeX, you create the .tex directly, so everything you do has to be valid .tex. Based on how \SI works, having \py inside it causes problems--\SI expects numbers, not commands.

There are a number of ways you could work around this. I've given two examples below. In the first approach, I've created a Python function SI() that takes a variable and a unit, and returns an \SI command. In the second approach, I've created a new LaTeX command \pySI that does the same thing, just using a more LaTeX-style interface. This last approach will have problems if you need to use the # and % characters in the arguments, but that shouldn't be an issue for this application.

\documentclass{article}
\usepackage{siunitx}
\usepackage{pythontex}

\begin{pycode}
def SI(var, unit):
    return '\\SI{' + str(var) + '}{' + unit + '}'
\end{pycode}

\newcommand{\pySI}[2]{\py{'\\SI{' + str(#1) + '}{#2}'}}

\begin{document}
\pyc{y = 4}

The value of y is \py{SI(y, r'\metre')}.

The value of y is \pySI{y}{\metre}.

\end{document}
G. Poore
  • 12,417
  • Thanks for the quick answer! That was exactly what I was looking for... ;-)) – majahn Jul 06 '13 at 10:05
  • Changing the last substring from '}{#2}'}} to r'}{#2}'}} ensures that the unit commands don't get messed up. If the string is not a raw string, \nano\second compiles as "anos". – Aakash Jog Sep 21 '20 at 22:23