Skip to main content

Replace some commands and environments within a TeX document by evaluating code inside a jupyter kernel

Project description

TexSurgery

Replaces some commands and environments within a TeX document by evaluating code inside a jupyter kernel.

Much like sagetex, but with the following differences:

  1. sagetex collects all the code using LaTeX and only then runs sage to get the LaTeX output, which definitely works, but this conflicts with some interesting LaTeX packages and is slower than a direct conversion.
  2. TexSurgery works in any language with a jupyter kernel

Installation

python3 -m pip install texsurgery

Testing

The following command will perform some common tests, and specific tests for some of the kernels that are installed:

python3 -m unittest tests

Selectors

texsurgery can also gather information using a limited choice of css-style selectors:

>>> from texsurgery.texsurgery import TexSurgery
>>> tex = open('tests/test_find.tex').read()
>>> TexSurgery(tex).findall('question,questionmultx runsilent')
[('questionmultx', [('runsilent', 'a = randint(1,10)\n')]),
 ('question',
   [('runsilent', 'a = randint(2,10)\nf = sin(a*x)\nfd = f.derivative(x)\n')])]
>>> TexSurgery(tex).findall('question,questionmultx choices \correctchoice')
[('question', [('choices', [('\correctchoice', '$\sage{fd}$')])])]
>>> TexSurgery(tex).findall('questionmultx \AMCnumericChoices[_nargs=2]')
[('questionmultx', [('\\AMCnumericChoices',
  ['\\eval{8+a}', 'digits=2,sign=false,scoreexact=3'])]
)]
>>> TexSurgery(tex).find(r'questionmultx{questionid}[questionid=basic-multiplication]')
('questionmultx', {'questionid':'basic-multiplication'},
 r'''\begin{runsilent}
a = randint(2,10)
\end{runsilent}
What is $8*\eval{a}$?
\AMCnumericChoices{\eval{8*a}}{digits=2,sign=false,scoreexact=3}
''')

Kernels

TexSurgery can use several jupyter kernels in the same document. In order to do so, you have to declare them with a line like

\usepackage[sagemath,python3]{texsurgery}

The first one is the default. To use another one, pass the option to the corresponding environment. For example

\begin{run}
1^1
\end{run}

will be transformed into

1

but, because of the different way that sagemath and python handle the ^ operator, this

\begin{run}[python3]
1^1
\end{run}

will be transformed into

0

instead.

This can be useful for example to include graphics generated by different systems in the same document.

Example

Start with this LaTeX code:

% Any jupyter kernel is available
\usepackage[sagemath]{texsurgery}

% Compatible with any other LaTeX package
\usepackage[bloc,completemulti]{automultiplechoice}

% Example of user macros
\providecommand{\abs}[1]{\lvert#1\rvert}
\newcommand{\R}{\mathbb{R}}

% TexSurgery can replace some \commands before pdflatex runs
\begin{minipage}{.85\linewidth}
Student: {\bf \name \;  \surname},  \quad ID:  {\bf \id}
\end{minipage}

\begin{question}{derivative-sin}
\qvariant{1} \qtags{derivative}
% TexSurgery will run code in a jupyter kernel
\begin{runsilent}
set_random_seed(\seed)
a = randint(2,10)
f = sin(a*x)
fd = f.derivative(x)
\end{runsilent}
% TexSurgery will eval code in a jupyter kernel
% and replace \eval{expr} with the output from the kernel
% \sage{expr} is just an alias for \eval{latex(expr)}
What is the first derivative of $\sage{f}$?
\begin{choices}
  \correctchoice{$\sage{fd}$}
  \wrongchoice{$\sage{fd*a}$}
  \wrongchoice{$\sage{fd + a}$}
\end{choices}
\begin{explain}
\begin{run}
# TexSurgery will run code in the jupyter kernel
# and replace this environment with the full output
\end{run}
\end{explain}
\end{question}

and run this python code:

from texsurgery.texsurgery import TexSurgery
student_vars = dict(name='Fulano', surname='de Tal', seed='1', id='314159')
ts = TexSurgery(tex_source).data_surgery(student_vars).code_surgery()

in order to transform it into this:

% Compatible with any other LaTeX package
\usepackage[bloc,completemulti]{automultiplechoice}

% Example of user macros
\providecommand{\abs}[1]{\lvert#1\rvert}
\newcommand{\R}{\mathbb{R}}

\begin{minipage}{.85\linewidth}
Student: {\bf Fulano \;  de Tal},  \quad ID:  {\bf 314159}
\end{minipage}

\begin{question}{derivative-sin}
\qvariant{1} \qtags{derivative}
What is the first derivative of $\sin\left(7 \, x\right)$?
\begin{choices}
  \correctchoice{$7 \, \cos\left(7 \, x\right)$}
  \wrongchoice{$49 \, \cos\left(7 \, x\right)$}
  \wrongchoice{$7 \, \cos\left(7 \, x\right) + 7$}
\end{choices}
\begin{explain}
\begin{run}
# TexSurgery will run code in the jupyter kernel
# and replace this environment with the full output
\end{run}
\end{explain}
\end{question}

Thanks

To all our colleagues that gave feedback to the early versions, specially Fabricio from ETSIN.UPM and carlos from ETSIAAB.UPM

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

texsurgery-0.3.8.tar.gz (16.2 kB view details)

Uploaded Source

Built Distribution

texsurgery-0.3.8-py3-none-any.whl (20.4 kB view details)

Uploaded Python 3

File details

Details for the file texsurgery-0.3.8.tar.gz.

File metadata

  • Download URL: texsurgery-0.3.8.tar.gz
  • Upload date:
  • Size: 16.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.22.0 setuptools/51.1.0 requests-toolbelt/0.9.1 tqdm/4.53.0 CPython/3.8.5

File hashes

Hashes for texsurgery-0.3.8.tar.gz
Algorithm Hash digest
SHA256 ce222f92c2958c8d903affeacdce4a264222144cadffc4687963a17d32e213ee
MD5 3279dbe19388b887bc7c4072a85f540b
BLAKE2b-256 dd96f933acdf3e2bc631407adec7d13e39d74eddcb596a5d24491a78008d379a

See more details on using hashes here.

File details

Details for the file texsurgery-0.3.8-py3-none-any.whl.

File metadata

  • Download URL: texsurgery-0.3.8-py3-none-any.whl
  • Upload date:
  • Size: 20.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.2.0 pkginfo/1.6.1 requests/2.22.0 setuptools/51.1.0 requests-toolbelt/0.9.1 tqdm/4.53.0 CPython/3.8.5

File hashes

Hashes for texsurgery-0.3.8-py3-none-any.whl
Algorithm Hash digest
SHA256 f864e80a547a56e3a28dfa844637421ef1a958a72624d925fa857a7b04e77415
MD5 24517dd85e78a6cb7ae85b0a59378a8d
BLAKE2b-256 ae82531522f70bcd557de0a46a574b58a0a812cbb9569044e548027ce642cdba

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page