Repository navigation
Expand file tree
/
Copy pathruncode.tex
More file actions
520 lines (438 loc) · 20.6 KB
/
Copy pathruncode.tex
File metadata and controls
520 lines (438 loc) · 20.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
% LaTeX Package: runcode v2.6.2
%
% Copyright (C) 2020-2026 by Haim Bar and HaiYing Wang
%
% This file may be distributed and/or modified under the
% conditions of the LaTeX Project Public License, either
% version 1.3c of this license or (at your option) any later
% version. The latest version of this license is in:
%
% http://www.latex-project.org/lppl.txt
%
% and version 1.3c or later is part of all distributions of
% LaTeX version 2005/12/01 or later.
\PassOptionsToPackage{colorlinks=true,linkcolor=blue,urlcolor=blue}{hyperref}
\documentclass{ltxdoc}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
% hyperref is loaded by ltxdoc via hypdoc; options are set above.
\usepackage{listings}
\usepackage{xcolor}
\lstset{
basicstyle=\ttfamily\small,
frame=single,
breaklines=true,
columns=flexible,
}
\newcommand{\pkg}[1]{\textsf{#1}}
\newcommand{\opt}[1]{\texttt{#1}}
\newcommand{\file}[1]{\texttt{#1}}
\title{The \pkg{runcode} package}
\author{Haim Bar and HaiYing Wang \\
\href{mailto:haim.bar@uconn.edu}{haim.bar@uconn.edu},
\href{mailto:haiying.wang@uconn.edu}{haiying.wang@uconn.edu}}
\date{v2.6.2, 2026}
\begin{document}
\maketitle
\begin{abstract}
\pkg{runcode} is a \LaTeX{} package that executes programming source
codes (including all command-line tools) from \LaTeX{} and embeds the
results in the resulting PDF file. Many programming languages can be
used and any command-line executable can be invoked when preparing the
PDF from a \texttt{.tex} file. \pkg{runcode} is also available on
\href{https://ctan.org/pkg/runcode}{CTAN}.
It is recommended to use this package in server mode together with the
Python \href{https://pypi.org/project/talk2stat/}{talk2stat} package.
Currently, the server mode supports
\href{https://julialang.org/}{Julia},
\href{https://www.mathworks.com/products/matlab.html}{MatLab},
\href{https://www.python.org/}{Python}, and
\href{https://www.r-project.org/}{R}.
More languages will be added.
For more details, usage examples, and troubleshooting, refer to the
package's GitHub repository at
\url{https://github.com/Ossifragus/runcode}.
\end{abstract}
\tableofcontents
%%--------------------------------------------------------------------
\section{Installation}
\label{sec:installation}
You can simply put the \file{runcode.sty} file in your \LaTeX{} project
folder.
The server mode requires the
\href{https://pypi.org/project/talk2stat/}{talk2stat} package.
Some chunk commands (e.g., \cs{showChunk}) also require the
\href{https://pypi.org/project/advance-touch/}{advance-touch} package.
Install them from the command line with:
\begin{lstlisting}[language=bash]
pip3 install talk2stat advance-touch
\end{lstlisting}
\textbf{Note:} \pkg{runcode} requires the \texttt{shell-escape} option
when compiling a \LaTeX{} document:
\begin{lstlisting}[language=bash]
pdflatex --shell-escape yourfile.tex
\end{lstlisting}
When using AUCTeX or a similar IDE, you can avoid setting
\texttt{shell-escape} manually by adding the following magic comment at
the top of your \texttt{.tex} file:
\begin{lstlisting}[language=tex]
% !TEX program = pdflatex --shell-escape
\end{lstlisting}
Replace \texttt{pdflatex} with \texttt{xelatex} or \texttt{lualatex} as
appropriate.
%%--------------------------------------------------------------------
\section{Usage}
\label{sec:usage}
\subsection{Loading the package}
\begin{lstlisting}[language=tex]
\usepackage[options]{runcode}
\end{lstlisting}
Available options:
\begin{description}
\item[\opt{cache}] Use cached results (do not re-run code).
\item[\opt{fvextra}] Use the \href{https://ctan.org/pkg/fvextra}{fvextra}
package to display code.
\item[\opt{julia}] Start a server for
\href{https://julialang.org/}{Julia} (requires \pkg{talk2stat}).
\item[\opt{listings}] Use the
\href{https://ctan.org/pkg/listings}{listings} package to display code.
\item[\opt{matlab}] Start a server for
\href{https://www.mathworks.com/products/matlab.html}{MatLab}
(requires \pkg{talk2stat}).
\item[\opt{minted}] Use the
\href{https://ctan.org/pkg/minted}{minted} package to display code
(requires \href{https://pygments.org/}{Pygments}).
This is the default.
\item[\opt{nominted}] Use \href{https://ctan.org/pkg/fvextra}{fvextra}
instead of \pkg{minted} (no syntax highlighting; no Pygments required).
\item[\opt{nohup}] Use \texttt{nohup} when starting a server.
Some editors (e.g.\ Emacs with AUCTeX) terminate child processes after
compilation; this option keeps the server alive.
\textbf{Must be declared before any language option}, e.g.\
\opt{[nohup,R]} works but \opt{[R,nohup]} does not.
See Section~\ref{sec:tools} for tools that smooth the \opt{nohup}
workflow.
\item[\opt{python}] Start a server for
\href{https://www.python.org/}{Python} (requires \pkg{talk2stat}).
\item[\opt{R}] Start a server for \href{https://www.r-project.org/}{R}
(requires \pkg{talk2stat}).
\item[\opt{reducedspace}] Reduce the vertical space around output boxes.
\item[\opt{run}] Force source code to run (override cache).
\item[\opt{stopserver}] Stop the server(s) when PDF compilation finishes.
\end{description}
\subsection{Output box style}
Output boxes are displayed using
\href{https://ctan.org/pkg/tcolorbox}{tcolorbox} and can be customised
with \cs{tcbset}, e.g.:
\begin{lstlisting}[language=tex]
\tcbset{breakable, colback=red!5!white, colframe=red!75!black}
\end{lstlisting}
\subsection{Code display style}
The style of \emph{source code} blocks (shown by \cs{showCode},
\cs{showChunk}, and the \texttt{\cs{run}LANG\texttt{Chunk}} commands)
depends on the package option used to display code:
\begin{itemize}
\item \textbf{\pkg{minted}} (default): use \cs{setminted} to control
language-specific highlighting, e.g.:
\begin{lstlisting}[language=tex]
\setminted[r]{linenos, frame=single, bgcolor=bg, breaklines=true}
\end{lstlisting}
\item \textbf{\pkg{fvextra}} or \opt{nominted}: use \cs{fvset} to set
options globally, e.g.:
\begin{lstlisting}[language=tex]
\fvset{frame=single, numbers=left, breaklines=true}
\end{lstlisting}
\item \textbf{\pkg{listings}}: use \cs{lstset} to configure the style,
e.g.:
\begin{lstlisting}[language=tex]
\lstset{basicstyle=\ttfamily\small, frame=single, numbers=left}
\end{lstlisting}
\end{itemize}
\subsection{Basic commands}
\DescribeMacro{\runExtCode}
\cs{runExtCode}\marg{prog}\marg{src}\marg{label}\oarg{flag}
runs an external code file.
\begin{itemize}
\item \meta{prog}: the executable program.
\item \meta{src}: the source file name.
\item \meta{label}: the output file name (empty $\Rightarrow$ uses
counter \texttt{codeOutput}).
\item \oarg{flag}: optional run control --- omit or empty to use the
global \texttt{runcode} Boolean; \texttt{run} to force execution;
\texttt{cache} (or any other value) to use cached results.
\end{itemize}
\textbf{Checksum-based cache invalidation (v2.5):} when neither
\opt{cache} nor \opt{run} is active, \pkg{runcode} computes an MD5
checksum of \meta{src} and compares it with the checksum stored from the
previous run. The script is re-executed only if the source has changed
or if the output file is missing; otherwise the cached output is reused.
This avoids unnecessary reruns without requiring the user to manage
cache flags manually.
\DescribeMacro{\showCode}
\cs{showCode}\marg{lang}\marg{src}\oarg{first}\oarg{last}
displays source code using \pkg{minted}, \pkg{fvextra}, or \pkg{listings}.
\begin{itemize}
\item \meta{lang}: programming language.
\item \meta{src}: source file name.
\item \oarg{first}/\oarg{last}: first and last line to display
(optional; defaults to the whole file).
\end{itemize}
\DescribeMacro{\includeOutput}
\cs{includeOutput}\marg{label}\oarg{type}
embeds the output of executed code.
\begin{itemize}
\item \meta{label}: output file name (must match \meta{label} in
\cs{runExtCode}; empty $\Rightarrow$ uses counter).
\item \oarg{type}: \texttt{vbox} (default) = verbatim in a box;
\texttt{tex} = raw \LaTeX{}; \texttt{inline} = inline text.
\end{itemize}
\DescribeMacro{\inln}
\cs{inln}\marg{prog}\marg{code}\oarg{label}\oarg{type}
runs a short piece of code and displays the result inline.
\begin{itemize}
\item \meta{prog}: executable or language server.
\item \meta{code}: source code.
\item \oarg{label}: output file name (optional).
\item \oarg{type}: controls display format and caching. Values:
\texttt{inline} (default), \texttt{vbox}, \texttt{tex};
append \texttt{.cache} to any of these
(e.g.\ \texttt{vbox.cache}) to reuse a cached result,
re-running only if the output file is absent.
\end{itemize}
\DescribeMacro{\showChunk}
\cs{showChunk}\marg{lang}\marg{src}\marg{id}\oarg{begin}\oarg{end}
displays a labelled chunk of a source file. Chunks are delimited by
comment lines containing \texttt{label===}\meta{id} (start) and
\texttt{===end} (end) by default. These delimiters can be overridden
with \oarg{begin} and \oarg{end}.
\DescribeMacro{\writeChunk}
\cs{writeChunk}\marg{lang}\marg{src}\marg{id}\oarg{begin}\oarg{end}
extracts the chunk identified by \meta{id} from \meta{src} and writes it
to \file{generated/}\meta{src}\texttt{-}\meta{id} on disk. This is
called internally by \cs{showChunk} and \cs{runLANGChunk}, but can also
be used standalone when only the extraction step is needed.
In normal (non-cache) mode, extraction is skipped and the cached file
reused whenever \meta{src}'s MD5 checksum matches the one recorded the
last time it was extracted, so repeated \cs{showChunk} calls against an
unchanged source are effectively free; editing \meta{src} automatically
invalidates every chunk cached from it, so no manual cache-clearing step
is needed. In \opt{cache} mode, the checksum check itself is skipped: an
existing cached file is trusted outright with no subprocess call at all,
matching \cs{runExtCode}'s and \cs{inln}'s behaviour in that mode (see
Section~\ref{sec:usage}).
\subsection{Extended commands}
\DescribeMacro{\runCodeIncOut}
\cs{runCodeIncOut}\marg{prog}\marg{src}\oarg{flag}\oarg{label}\oarg{type}
combines \cs{runExtCode} and \cs{includeOutput} in one call.
\subsection{Language-specific shortcuts}
Replace \texttt{LANG} with \texttt{Julia}, \texttt{MatLab},
\texttt{Python}, or \texttt{R} in the following commands.
\DescribeMacro{\runLANG}
\cs{runLANG}\oarg{prog}\marg{src}\marg{label}\oarg{flag}
runs an external \texttt{LANG} code file. \oarg{prog} is optional and
defaults to the \pkg{talk2stat} \texttt{LANG} server.
\DescribeMacro{\runLANGIncOut}
\cs{runLANGIncOut}\oarg{prog}\marg{src}\oarg{flag}\oarg{label}\oarg{type}
runs a \texttt{LANG} code file and embeds the output.
\DescribeMacro{\inlnLANG}
\cs{inlnLANG}\oarg{prog}\marg{code}\oarg{label}\oarg{type}
runs \texttt{LANG} source code and displays the result inline.
If \meta{code} is wrapped in triple backticks (\texttt{```code```}),
it is sent directly to the server; otherwise it is written to a file
first.
\DescribeMacro{\runLANGChunk}
\cs{runLANGChunk}\oarg{prog}\marg{src}\marg{id}\oarg{flag}\oarg{label}\oarg{type}
extracts the chunk \meta{id} from \meta{src}, runs it, and embeds the
output.
\begin{itemize}
\item \oarg{label}: output file name. When omitted, the label is
derived automatically as \meta{src}\texttt{-}\meta{id}
(e.g.\ \texttt{code/analysis.R-section2}).
\item \oarg{type}: output display type (\texttt{vbox}, \texttt{tex},
\texttt{inline}, or their \texttt{.cache} variants).
\end{itemize}
For example:
\begin{lstlisting}[language=tex]
\runR{code/analysis.R}{result1}
\runRIncOut{code/analysis.R}[][result1]
\runRChunk{code/analysis.R}{section2}
\inlnR{```mean(c(1,2,3,4,5))```}
\end{lstlisting}
\subsubsection{Python batch mode}
\DescribeMacro{\runPythonBatch}
\cs{runPythonBatch}\oarg{src}\oarg{label}
runs a Python file in batch mode (no server). Requires the
\href{https://pypi.org/project/dill/}{dill} module
(\texttt{pip3 install dill}), which provides session save/restore
so that variables persist across calls.
%%--------------------------------------------------------------------
\section{Auxiliary tools}
\label{sec:tools}
The following scripts are distributed with the package and address
common workflow needs. Copy them into your project directory alongside
your \texttt{.tex} file.
\subsection{\file{wait\_for\_server.py}}
Polls a \pkg{talk2stat} server until it is ready to accept connections.
This eliminates the server-startup race condition that can occur in
\opt{nohup} mode, where the first \cs{runR} call may arrive before the
server socket is open.
\begin{lstlisting}[language=bash]
python3 wait_for_server.py [LANG [DIR [TIMEOUT]]]
\end{lstlisting}
\begin{itemize}
\item \texttt{LANG}: language server to wait for --- \texttt{R},
\texttt{python}, \texttt{julia}, or \texttt{matlab} (default: \texttt{R}).
\item \texttt{DIR}: working directory of the server (default: \texttt{./}).
\item \texttt{TIMEOUT}: seconds before giving up (default: 120).
\end{itemize}
\subsection{\file{runcode-Makefile.sample}}
A sample \file{Makefile} for documents compiled in \opt{nohup} server
mode. Copy it to your project as \file{Makefile} and set the
\texttt{MAIN} and \texttt{LANGS} variables. The \texttt{make all}
target encodes three best practices:
\begin{enumerate}
\item Quit any existing server before starting a fresh one, so the
new server picks up the current \file{.config} settings
(including any updated \texttt{PIPETIMEOUT}).
\item Call \file{wait\_for\_rserver.py} to block until the server is
ready before the first \LaTeX{} pass.
\item After the draft pass (\texttt{-{}-no-pdf} / \texttt{-draftmode}),
send a language-appropriate no-op command as a sync barrier
(\texttt{invisible(NULL)} for R, \texttt{pass} for Python, etc.)
to ensure all queued scripts have finished writing their output
files before the final passes begin.
\end{enumerate}
\textbf{PIPETIMEOUT note:} the default timeout in the generated
\file{.config} is 60 seconds. For long-running scripts, raise it by
editing the \file{.config} file (e.g.\ \texttt{PIPETIMEOUT = 3600})
and restarting the server (\texttt{make stopserver}).
\subsection{\file{consolidate.py}}
Produces a self-contained copy of a \pkg{runcode} project in which all
cached outputs are inlined into the \texttt{.tex} source, so the result
compiles without \pkg{talk2stat} or any language runtime. This is
useful for submission to Overleaf, a journal, or any recipient who does
not have \pkg{runcode} installed.
\begin{lstlisting}[language=bash]
python3 consolidate.py [--out DIR] [--engine CMD] [--no-compile]
[--exclude GLOB] MAIN.tex
\end{lstlisting}
The script copies the project to \file{standalone/} (configurable via
\texttt{-{}-out}), transforms all \texttt{.tex} files by replacing
\cs{includeOutput}, \cs{inlnR}/\cs{inlnPython}/\ldots,
\cs{runRIncOut}, \cs{runRChunk}, etc.\ with the cached content from
\file{generated/}, and substitutes \cs{usepackage}\texttt{\{runcode\}}
with a minimal \pkg{tcolorbox} + \pkg{listings} shim. Run-only
commands (\cs{runR}, \cs{runPython}, \ldots) are silently removed.
A \texttt{make consolidate} target is provided in
\file{runcode-Makefile.sample}.
%%--------------------------------------------------------------------
\section{Revisions}
\label{sec:revisions}
\begin{itemize}
\item \textbf{v2.6.2, August 2026:}
The v2.6.1 MD5 checksum check fixed \cs{writeChunk}'s missing cache,
but the checksum subprocess itself ran unconditionally --- including
under the \opt{cache} package option, where it defeats the point: on
Overleaf (which \file{make\_overleaf.py}-style workflows put into
\opt{cache} mode) this meant one \texttt{python3} spawn per
\cs{showChunk} call, on every compile, even with a warm cache.
\cs{writeChunk} now checks \cs{ifruncode} first, matching
\cs{runExtCode} and \cs{inln}: in \opt{cache} mode it trusts an
existing cached file outright with zero subprocess calls; the
checksum check only runs in normal mode. Verified against the full
factorial design (\cs{ifruncode} true/false $\times$
missing/fresh/stale cached file) in the new
\file{examples/WriteChunkCacheTest/} regression test.
\item \textbf{v2.6.1, August 2026:}
\cs{writeChunk} re-scanned its whole source file, line by line, via a
slow \TeX-native loop on every call, with no caching --- unlike every
other command in the package. On documents with many \cs{showChunk}
calls against large source files, across the multiple \LaTeX{} passes
a typical build requires, this dominated compile time (in one
real-world document, a single pass went from 3m33s to 11s once
\cs{showChunk} calls were disabled). \cs{writeChunk} now applies the
same MD5 checksum-based staleness check used elsewhere in the package
(see the v2.6 entry below): the scan is skipped and the cached
\file{generated/}\meta{src}\texttt{-}\meta{id} file reused whenever
\meta{src} is unchanged since it was last extracted.
\item \textbf{v2.6, June 2026:}
\begin{enumerate}
\item Checksum-based cache invalidation: source files are
fingerprinted with MD5; a script is re-executed only when its
source has changed or when the output file is missing, avoiding
unnecessary reruns.
\item New \file{wait\_for\_rserver.py}: eliminates the server-startup
race condition in \opt{nohup} mode (see Section~\ref{sec:tools}).
\item New \file{runcode-Makefile.sample}: sample \file{Makefile}
with server lifecycle management, startup synchronisation, and
sync barrier (see Section~\ref{sec:tools}).
\item New \file{consolidate.py}: produces standalone \LaTeX{}
projects with all cached outputs inlined
(see Section~\ref{sec:tools}).
\end{enumerate}
\item \textbf{v2.4.1, June 10, 2026:}
Bug fixes in \cs{writeChunk}: (1) replaced \texttt{mkdir -p} with
Python \texttt{os.makedirs} for cross-platform subdirectory creation;
(2) fixed stream exhaustion when more than 16 \cs{showChunk} calls
appear in one document (streams are now pre-allocated at package load
time); (3) removed erroneous \verb|\write18{ad ...}| call in
\cs{showChunk}.
Added AUCTeX magic comment to example files.
\item \textbf{v2.4, January 17, 2025:}
(1) Put file names within \texttt{\$\$} for more robust warnings;
(2) use the Python \pkg{advance-touch} package to create sub-folders
for chunk-related commands.
\item \textbf{v2.3, January 12, 2024:}
Two bug fixes: (1) removed extra space after \cs{inlnX};
(2) fixed compilation error when an underscore appeared inside R code.
\item \textbf{v2.2, September 8, 2023:}
Added \cs{showChunk} basic command and \cs{runLANGChunk} commands for
multiple languages.
\item \textbf{v2.1, June 30, 2023:}
Detokenize code passed to \cs{inln}. This prevents special
\LaTeX{} characters (e.g.\ backslash) from being escaped before
reaching the interpreter. Thanks to
\href{https://github.com/kiryph}{kiryph} for the report.
\item \textbf{v2.0, June 23, 2023:}
Added \cs{runCodeIncOut}; updated \cs{runExtCode} to override cache
when output is missing; updated \cs{inln} to accept \texttt{cache}
in \texttt{Arg4}. Thanks to
\href{https://github.com/kiryph}{kiryph} for the suggestions.
\item \textbf{v1.9, June 13, 2023:}
Updated \cs{inln}: optional \texttt{Arg3} is the output file name,
optional \texttt{Arg4} is the output type.
\item \textbf{v1.8, January 18, 2023:}
Added support for the \pkg{listings} package.
\item \textbf{v1.7, August 20, 2022:}
Renamed the \texttt{tmp/} folder to \texttt{generated/} (CTAN
requirement); renamed the troubleshooting file.
\item \textbf{v1.6, August 10, 2022:}
Stop only configured/running servers; new \opt{reducedspace} option;
default server timeout changed to 60 s; expanded troubleshooting
document.
\item \textbf{v1.5, July 23, 2022:}
Removed \texttt{utf8x} option from \pkg{inputenc} (conflict with
\pkg{hyperref}).
\item \textbf{v1.4, July 18, 2022:} Fixed a bug in cache mode.
\item \textbf{v1.3, May 14, 2022:} Removed hard-coded \pkg{minted}
options.
\item \textbf{v1.2, May 3, 2022:} Added Python server and batch-mode
options.
\item \textbf{v1.1, April 17, 2021:} Added \opt{nohup} option;
improved error handling for missing code files and zero-byte outputs.
\end{itemize}
%%--------------------------------------------------------------------
\section{Contributing}
\label{sec:contributing}
We welcome contributions by opening issues or pull requests on
\href{https://github.com/Ossifragus/runcode}{GitHub}. Additional
example documents written using \pkg{runcode} are especially
appreciated.
\bigskip\noindent
\textbf{Citing \pkg{runcode}:}
Haim Bar and HaiYing Wang (2021).
\href{https://jds-online.org/journal/JDS/article/103/info}{Reproducible
Science with \LaTeX{}}.
\textit{Journal of Data Science} 19(1), 111--125.
DOI:~10.6339/21-JDS998.
\end{document}