summaryrefslogtreecommitdiff
path: root/macros/latex/contrib/runcode
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2023-09-10 03:01:10 +0000
committerNorbert Preining <norbert@preining.info>2023-09-10 03:01:10 +0000
commit5aeceaafdf41d8bd02ef1521380f21cbb163bd69 (patch)
tree6fc5a25e0ff30a802239a964357bb419c42f526a /macros/latex/contrib/runcode
parent802cff464fb0c30783078dd27c9615c8b3500af3 (diff)
CTAN sync 202309100301
Diffstat (limited to 'macros/latex/contrib/runcode')
-rw-r--r--macros/latex/contrib/runcode/README4
-rw-r--r--macros/latex/contrib/runcode/runcode.pdfbin251041 -> 251374 bytes
-rw-r--r--macros/latex/contrib/runcode/runcode.sty322
-rw-r--r--macros/latex/contrib/runcode/runcode.tex154
4 files changed, 240 insertions, 240 deletions
diff --git a/macros/latex/contrib/runcode/README b/macros/latex/contrib/runcode/README
index 7a1480a3b1..6075685680 100644
--- a/macros/latex/contrib/runcode/README
+++ b/macros/latex/contrib/runcode/README
@@ -1,11 +1,11 @@
-LaTeX Package: runcode 2023/06/23 v2.0
+LaTeX Package: runcode 2023/09/08 v2.2
----------------------------------------
The runcode package enables the execution of source code (e.g., R,
Julia, Matlab, shell, Python, etc.) and embed the results in the pdf file
when compiling the LaTeX file. To use this package the shell-escape
option must be enabled.
-Copyright (C) 2020-2022
+Copyright (C) 2020-2023
Haim Bar and HaiYing Wang https://github.com/Ossifragus/runcode
Files:
diff --git a/macros/latex/contrib/runcode/runcode.pdf b/macros/latex/contrib/runcode/runcode.pdf
index 95afe13532..0a2d35f5e0 100644
--- a/macros/latex/contrib/runcode/runcode.pdf
+++ b/macros/latex/contrib/runcode/runcode.pdf
Binary files differ
diff --git a/macros/latex/contrib/runcode/runcode.sty b/macros/latex/contrib/runcode/runcode.sty
index 1fe5b07956..06c3d346e0 100644
--- a/macros/latex/contrib/runcode/runcode.sty
+++ b/macros/latex/contrib/runcode/runcode.sty
@@ -4,7 +4,9 @@
%
% This package is based on an ongoing work by Haim Bar and HaiYing Wang, and comments and questions are welcome!
-\ProvidesPackage{runcode}[2023/06/23 runcode v2.0]
+\ProvidesPackage{runcode}[2023/09/08 runcode v2.2]
+
+\def \langs {}
\newif\ifruncode
% Change to \runcodefalse if you want to suspend code execution
@@ -48,105 +50,73 @@
\notnohuptrue
\DeclareOption{nohup}{\notnohupfalse}
+\newcounter{portNo}
+\setcounter{portNo}{65430}
+
+\NewDocumentCommand{\InitLang}{m}{
+ % Create a configuration file for the server for the language provided
+ % in the argument, if it does not exist, and add to the serverslist.txt file.
+ \IfFileExists{#1.config}{}{
+ \newwrite\tempfile
+ \immediate\openout\tempfile=#1.config
+ \immediate\write\tempfile{[SERVERCONFIG]}
+ \immediate\write\tempfile{PORT = \theportNo}
+ \immediate\write\tempfile{DEBUGFILE = #1debug.txt}
+ \immediate\write\tempfile{PIPETIMEOUT = 60}
+ \immediate\closeout\tempfile
+ \edef\langs{\langs#1_}
+ \stepcounter{portNo}
+ }
+ % Start the server. Need to run just once. Can comment out after the first
+ % compilation, but remember to terminate the server
+ \ifnotnohup
+ {\immediate\write18{python3 -c 'from talk2stat.talk2stat import server,client; server("./","#1") if not client("./","#1","``` ```") else print("server is already running")'}}
+ \else
+ {\immediate\write18{nohup python3 -c 'from talk2stat.talk2stat import server,client; server("./","#1") if not client("./","#1","``` ```") else print("server is already running")' &}}
+ \fi
+}
+
\DeclareOption{R}{
- % create a configuration file for R server if it does not exist.
- \IfFileExists{R.config}{}{
- \newwrite\tempfile
- \immediate\openout\tempfile=R.config
- \immediate\write\tempfile{[SERVERCONFIG]}
- \immediate\write\tempfile{PORT = 65432}
- \immediate\write\tempfile{DEBUGFILE = Rdebug.txt}
- \immediate\write\tempfile{PIPETIMEOUT = 60}
- \immediate\closeout\tempfile
- }
- % Start the server. Need to run just once. Can comment out after the first
- % compilation, but remember to terminate the server
- \ifnotnohup
- {\immediate\write18{python3 -c 'from talk2stat.talk2stat import server,client; server("./","R") if not client("./","R","``` ```") else print("server is already running")'}}
- \else
- {\immediate\write18{nohup python3 -c 'from talk2stat.talk2stat import server,client; server("./","R") if not client("./","R","``` ```") else print("server is already running")' &}}
- \fi
+ \InitLang{R}
}
\DeclareOption{julia}{
- % create a configuration file for R server if it does not exist.
- \IfFileExists{julia.config}{}{
- \newwrite\tempfile
- \immediate\openout\tempfile=julia.config
- \immediate\write\tempfile{[SERVERCONFIG]}
- \immediate\write\tempfile{PORT = 65431}
- \immediate\write\tempfile{DEBUGFILE = juliadebug.txt}
- \immediate\write\tempfile{PIPETIMEOUT = 60}
- \immediate\closeout\tempfile
- }
- % Start the server. Need to run just once. Can comment out after the first
- % compilation, but remember to terminate the server
- \ifnotnohup
- {\immediate\write18{python3 -c 'from talk2stat.talk2stat import server,client; server("./","julia") if not client("./","julia","``` ```") else print("server is already running")'}}
- \else
- {\immediate\write18{nohup python3 -c 'from talk2stat.talk2stat import server,client; server("./","julia") if not client("./","julia","``` ```") else print("server is already running")' &}}
- \fi
+ \InitLang{julia}
}
\DeclareOption{matlab}{
- % create a configuration file for R server if it does not exist.
- \IfFileExists{matlab.config}{}{
- \newwrite\tempfile
- \immediate\openout\tempfile=matlab.config
- \immediate\write\tempfile{[SERVERCONFIG]}
- \immediate\write\tempfile{PORT = 65430}
- \immediate\write\tempfile{DEBUGFILE = matlabdebug.txt}
- \immediate\write\tempfile{PIPETIMEOUT = 60}
- \immediate\closeout\tempfile
- }
- % Start the server. Need to run just once. Can comment out after the first
- % compilation, but remember to terminate the server
- \ifnotnohup
- {\immediate\write18{python3 -c 'from talk2stat.talk2stat import server,client; server("./","matlab") if not client("./","matlab","``` ```") else print("server is already running")'}}
- \else
- {\immediate\write18{nohup python3 -c 'from talk2stat.talk2stat import server,client; server("./","matlab") if not client("./","matlab","``` ```") else print("server is already running")' &}}
- \fi
+ \InitLang{matlab}
}
\DeclareOption{python}{
- % create a configuration file for Python server if it does not exist.
- \IfFileExists{python.config}{}{
- \newwrite\tempfile
- \immediate\openout\tempfile=python.config
- \immediate\write\tempfile{[SERVERCONFIG]}
- \immediate\write\tempfile{PORT = 65433}
- \immediate\write\tempfile{DEBUGFILE = pythondebug.txt}
- \immediate\write\tempfile{PIPETIMEOUT = 60}
- \immediate\closeout\tempfile
- }
- % Start the server. Need to run just once. Can comment out after the first
- % compilation, but remember to terminate the server
- \ifnotnohup
- {\immediate\write18{python3 -c 'from talk2stat.talk2stat import server,client; server("./","python") if not client("./","python","``` ```") else print("server is already running")'}}
- \else
- {\immediate\write18{nohup python3 -c 'from talk2stat.talk2stat import server,client; server("./","python") if not client("./","python","``` ```") else print("server is already running")' &}}
- \fi
+ \InitLang{python}
}
+
\DeclareOption{stopserver}{
\AtEndDocument{
- %% stop the server when the pdf compilation is done.
- \IfFileExists{R.config}{
- \immediate\write18{python3 -c 'from talk2stat.talk2stat import client; client("./","R","QUIT")'}
- }{}
- \IfFileExists{julia.config}{
- \immediate\write18{python3 -c 'from talk2stat.talk2stat import client; client("./","julia","QUIT")'}
- }{}
- \IfFileExists{matlab.config}{
- \immediate\write18{python3 -c 'from talk2stat.talk2stat import client; client("./","matlab","QUIT")'}
- }{}
- \IfFileExists{python.config}{
- \immediate\write18{python3 -c 'from talk2stat.talk2stat import client; client("./","python","QUIT")'}
+ \IfFileExists{serverslist.txt}{
+ \newread\file
+ \openin\file=serverslist.txt
+ \immediate\readline\file to\lang
+ \closein\file
+ \StrCount{\lang}{\detokenize{_}}[\langNo]
+ \newcounter{x}
+ \forloop{x}{0}{\value{x} < \langNo}{
+ \StrBefore{\lang}{\detokenize{_}}[\curlang]
+ \StrBehind{\lang}{\detokenize{_}}[\lang]
+ %% stop the server when the pdf compilation is done.
+ \IfFileExists{\curlang.config}{
+ \immediate\write18{python3 -c 'from talk2stat.talk2stat import client; client("./","\curlang","QUIT")'}
+ }{}
+ }
}{}
-}}
+ }
+}
\ProcessOptions*
+\usepackage{etoolbox}
\usepackage{morewrites} % allow more than 16 \write
\usepackage[many]{tcolorbox} % to put boxes around text
\tcbset{colframe=blue!25,colback=blue!10} % default colors for box output
@@ -157,6 +127,15 @@
\usepackage{xifthen}
\usepackage{xparse}
\usepackage{xstring}
+\usepackage{forloop}
+
+%%%% check if \langs is empty !!
+\ifdefempty{\langs}{}{
+ \newwrite\outfile
+ \immediate\openout\outfile=serverslist.txt
+ \immediate\write\outfile{\langs}
+ \immediate\closeout\outfile}
+{}
% Use minted by default; but the user can change to listings or fvextra.
\ifminted
@@ -205,7 +184,6 @@
\setvalue{\tmpname}{} % initialize with a blank
-
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \showCode prints the source code, using minted or listings for a pretty layout
% Arg #1 is the programming language,
@@ -320,8 +298,63 @@
}
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \writeChunk writes a selected chunk from source code as a .txt file.
+% Arg #1 is the source file name,
+% Arg #2 is the chunk identifier
+% Args #3 and #4 are the beginning and end markings of a chunk (optional).
+
+\NewDocumentCommand{\writeChunk}{m m O{label===} O{===end}} {
+ \IfFileExists{#1}{
+ \endlinechar=-1
+ \def\printcode{0} % don't print until we see the begin-block string
+ \newread\file
+ \openin\file=#1
+ \newwrite\outfile
+ \immediate\openout\outfile=\generated/#1-#2.txt
+ \loop\unless\ifeof\file
+ \immediate\readline\file to\fileline
+ \ifnum\printcode=1
+ \IfSubStr{\fileline}{\detokenize{#4}}{
+ \renewcommand{\printcode}{-1}}{\immediate\write\outfile{\fileline}}
+ \fi
+ \IfSubStr{\fileline}{\detokenize{#3}}{
+ \StrBehind{\fileline}{\detokenize{#3}}[\chunkname]
+ \IfStrEq*{\detokenize{#2}}{\chunkname}{\renewcommand{\printcode}{1}}{}
+ }
+ {}
+ \repeat
+ \closein\file
+ \immediate\closeout\outfile
+ \endlinechar=13
+ \ifnum\printcode=0
+ \textcolor{red}{\textbf{Label #2 not found in #1}}
+ \fi
+ }{\textcolor{red}{\textbf{Source file #1 not found}}}
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% \showChunk prints a selected chunk from source code, using minted or listings for a pretty layout.
+% The chunk is identified in the source code by two strings that define the beginning and end of the chunk.
+% The default beginning is label===<name> where <name> should be a unique user-defined chunk ID.
+% The default end marker is ===end
+% In the code, these markers should appear after a comment character, so that the code will run.
+% Arg #1 is the programming language,
+% Arg #2 is the source file name,
+% Args #3 is the chunk identifier
+% Args #4 and #5 are the beginning and end markings of a chunk (optional).
+
+\NewDocumentCommand{\showChunk}{m m m O{label===} O{===end}}{
+ \IfFileExists{#2}{
+ \writeChunk{#2}{#3}[#4][#5]
+ \IfFileExists{\generated/#2-#3.txt}{\showCode{#1}{\generated/#2-#3.txt}}
+ {\textcolor{red}{\textbf{Label #3 not found in #2}}}
+ }{\textcolor{red}{\textbf{Source file #2 not found}}}
+}
+
+
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% \inln{Arg #1}{Arg #2}[Arg #3] is used to execute short source code
+% \inln{Arg #1}{Arg #2}[Arg #3][Arg #4] is used to execute short source code
% and embed resulting output.
% Arg #1 is the executable program;
% Arg #2 is the source code;
@@ -342,7 +375,7 @@
\IfBeginWith{#2}{```}{\ifruncode\immediate\write18{#1 > \tmpname.tex}\unskip\fi}
{\newwrite\tempfile
\immediate\openout\tempfile=\tmpname.txt
- \immediate\write\tempfile{#2}
+ \immediate\write\tempfile{\detokenize{#2}}
\immediate\closeout\tempfile
\ifruncode
\immediate\write18{#1 \tmpname.txt > \tmpname.tex}\unskip
@@ -367,7 +400,7 @@
{\textcolor{red}{\textbf{Output file \tmpname~ not found}}}}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-% Extended and language-specific comments:
+% Extended and language-specific commands:
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% \runCodeIncOut: runs an external code and embeds the output.
@@ -388,77 +421,84 @@
\includeOutput{#4}[#5]
}
+\newcommand{\runcmd}[2]
+{python3 -c 'from talk2stat.talk2stat import client; client("./","#1",#2)'}
+
% R
-\NewDocumentCommand{\runR}{O{python3 -c 'from talk2stat.talk2stat import client; client("./","R","#2")'} m m O{}}
-{
- \def\runcmd{python3 -c 'from talk2stat.talk2stat import client; client("./","R","#2")'}
- \ifstrequal{#1}{\runcmd}
- {\runExtCode{#1}{}{#3}[#4]}
+% It will be used as a template for other languages
+\newcommand{\LANG}{R}
+\newcommand{\LANGcmd}{R}
+
+\expandafter\NewDocumentCommand\csname run\LANG\endcsname
+{O{} m m O{}}
+{\ifthenelse{\isempty{#1}}
+ {\runExtCode{\runcmd{\LANGcmd}{"#2"}}{#2}{#3}[#4]}
{\runExtCode{#1}{#2}{#3}[#4]}
}
-\NewDocumentCommand{\runRIncOut}
-{O{python3 -c 'from talk2stat.talk2stat import client; client("./","R","#2")'} m O{} O{} O{vbox}}
-{\def\runcmd{python3 -c 'from talk2stat.talk2stat import client; client("./","R","#2")'}
- \ifstrequal{#1}{\runcmd}
- {\runCodeIncOut{#1}{}[#3][#4][#5]}
- {\runCodeIncOut{#1}{#2}[#3][#4][#5]}}
+\expandafter\NewDocumentCommand\csname run\LANG IncOut\endcsname
+{O{} m O{} O{} O{vbox}}
+{\ifthenelse{\isempty{#1}}
+ {\runCodeIncOut{\runcmd{\LANGcmd}{"#2"}}{#2}[#3][#4][#5]}
+ {\runCodeIncOut{#1}{#2}[#3][#4][#5]}
+}
-\NewDocumentCommand{\inlnR}{O{python3 -c 'from talk2stat.talk2stat import client; client("./","R","\tmpname.txt")'} m O{} O{inline}}{\IfBeginWith{#2}{```}{\inln{python3 -c 'from talk2stat.talk2stat import client;rc0="""#2""";rc0=rc0.lstrip("```").rstrip("```");client("./","R",f"```{rc0}```")'}{#2}[#3][#4]}{\inln{#1}{#2}[#3][#4]}}
+\expandafter\NewDocumentCommand\csname inln\LANG\endcsname
+{O{} m O{} O{inline}}
+{\ifthenelse{\isempty{#1}}
+ {\IfBeginWith{#2}{```}
+ {\inln{\runcmd{\LANGcmd}{r"""\detokenize{#2}"""}}{#2}[#3][#4]}
+ {\inln{\runcmd{\LANGcmd}{"\tmpname.txt"}}{#2}[#3][#4]}
+ }
+ {\inln{#1}{#2}[#3][#4]}
+}
-% Julia
-\NewDocumentCommand{\runJulia}{O{python3 -c 'from talk2stat.talk2stat import client; client("./","julia","#2")'} m m O{}}
-{
- \def\runcmd{python3 -c 'from talk2stat.talk2stat import client; client("./","julia","#2")'}
- \ifstrequal{#1}{\runcmd}
- {\runExtCode{#1}{}{#3}[#4]}
- {\runExtCode{#1}{#2}{#3}[#4]}
+\expandafter\NewDocumentCommand\csname run\LANG Chunk\endcsname
+{O{} m m O{} O{} O{vbox}}
+{\IfFileExists{\generated/#2-#3.txt}{}{\writeChunk{#2}{#3}}
+ {\csname run\LANG IncOut\endcsname[#1]{\generated/#2-#3.txt}[#4][#2-#3][#6]}
}
-\NewDocumentCommand{\runJuliaIncOut}
-{O{python3 -c 'from talk2stat.talk2stat import client; client("./","julia","#2")'} m O{} O{} O{vbox}}
-{\def\runcmd{python3 -c 'from talk2stat.talk2stat import client; client("./","julia","#2")'}
- \ifstrequal{#1}{\runcmd}
- {\runCodeIncOut{#1}{}[#3][#4][#5]}
- {\runCodeIncOut{#1}{#2}[#3][#4][#5]}}
+% Julia
+\NewDocumentCommand{\runJulia}{O{} m m O{}}
+{\renewcommand{\LANGcmd}{julia} \runR[#1]{#2}{#3}[#4]}
+
+\NewDocumentCommand{\runJuliaIncOut}{O{} m O{} O{} O{vbox}}
+{\renewcommand{\LANGcmd}{julia} \runRIncOut[#1]{#2}[#3][#4][#5]}
+
+\NewDocumentCommand{\inlnJulia}{O{} m O{} O{inline}}
+{\renewcommand{\LANGcmd}{julia} \inlnR[#1]{#2}[#3][#4]}
+
+\NewDocumentCommand{\runJuliaChunk}{O{} m m O{} O{} O{vbox}}
+{\renewcommand{\LANGcmd}{julia} \runRChunk[#1]{#2}{#3}[#4][#5][#6]}
-\NewDocumentCommand{\inlnJulia}{O{python3 -c 'from talk2stat.talk2stat import client; client("./","julia","\tmpname.txt")'} m O{} O{inline}}{\IfBeginWith{#2}{```}{\inln{python3 -c 'from talk2stat.talk2stat import client;rc0="""#2""";rc0=rc0.lstrip("```").rstrip("```");client("./","julia",f"```{rc0}```")'}{#2}[#3][#4]}{\inln{#1}{#2}[#3][#4]}}
% Matlab
-\NewDocumentCommand{\runMatlab}{O{python3 -c 'from talk2stat.talk2stat import client; client("./","matlab","#2")'} m m O{}}
-{
- \def\runcmd{python3 -c 'from talk2stat.talk2stat import client; client("./","matlab","#2")'}
- \ifstrequal{#1}{\runcmd}
- {\runExtCode{#1}{}{#3}[#4]}
- {\runExtCode{#1}{#2}{#3}[#4]}
-}
+\NewDocumentCommand{\runMatLab}{O{} m m O{}}
+{\renewcommand{\LANGcmd}{matlab} \runR[#1]{#2}{#3}[#4]}
+
+\NewDocumentCommand{\runMatLabIncOut}{O{} m O{} O{} O{vbox}}
+{\renewcommand{\LANGcmd}{matlab} \runRIncOut[#1]{#2}[#3][#4][#5]}
+
+\NewDocumentCommand{\inlnMatLab}{O{} m O{} O{inline}}
+{\renewcommand{\LANGcmd}{matlab} \inlnR[#1]{#2}[#3][#4]}
-\NewDocumentCommand{\runMatlabIncOut}
-{O{python3 -c 'from talk2stat.talk2stat import client; client("./","matlab","#2")'} m O{} O{} O{vbox}}
-{\def\runcmd{python3 -c 'from talk2stat.talk2stat import client; client("./","matlab","#2")'}
- \ifstrequal{#1}{\runcmd}
- {\runCodeIncOut{#1}{}[#3][#4][#5]}
- {\runCodeIncOut{#1}{#2}[#3][#4][#5]}}
+\NewDocumentCommand{\runMatLabChunk}{O{} m m O{} O{} O{vbox}}
+{\renewcommand{\LANGcmd}{matlab} \runRChunk[#1]{#2}{#3}[#4][#5][#6]}
-\NewDocumentCommand{\inlnMatlab}{O{python3 -c 'from talk2stat.talk2stat import client; client("./","matlab","\tmpname.txt")'} m O{} O{inline}}{\IfBeginWith{#2}{```}{\inln{python3 -c 'from talk2stat.talk2stat import client;rc0="""#2""";rc0=rc0.lstrip("```").rstrip("```");client("./","matlab",f"```{rc0}```")'}{#2}[#3][#4]}{\inln{#1}{#2}[#3][#4]}}
% Python
-\NewDocumentCommand{\runPython}{O{python3 -c 'from talk2stat.talk2stat import client; client("./","python","#2")'} m m O{}}
-{
- \def\runcmd{python3 -c 'from talk2stat.talk2stat import client; client("./","python","#2")'}
- \ifstrequal{#1}{\runcmd}
- {\runExtCode{#1}{}{#3}[#4]}
- {\runExtCode{#1}{#2}{#3}[#4]}
-}
+\NewDocumentCommand{\runPython}{O{} m m O{}}
+{\renewcommand{\LANGcmd}{python} \runR[#1]{#2}{#3}[#4]}
+
+\NewDocumentCommand{\runPythonIncOut}{O{} m O{} O{} O{vbox}}
+{\renewcommand{\LANGcmd}{python} \runRIncOut[#1]{#2}[#3][#4][#5]}
-\NewDocumentCommand{\runPythonIncOut}
-{O{python3 -c 'from talk2stat.talk2stat import client; client("./","python","#2")'} m O{} O{} O{vbox}}
-{\def\runcmd{python3 -c 'from talk2stat.talk2stat import client; client("./","python","#2")'}
- \ifstrequal{#1}{\runcmd}
- {\runCodeIncOut{#1}{}[#3][#4][#5]}
- {\runCodeIncOut{#1}{#2}[#3][#4][#5]}}
+\NewDocumentCommand{\inlnPython}{O{} m O{} O{inline}}
+{\renewcommand{\LANGcmd}{python} \inlnR[#1]{#2}[#3][#4]}
-\NewDocumentCommand{\inlnPython}{O{python3 -c 'from talk2stat.talk2stat import client; client("./","python","\tmpname.txt")'} m O{} O{inline}}{\IfBeginWith{#2}{```}{\inln{python3 -c 'from talk2stat.talk2stat import client;rc0="""#2""";rc0=rc0.lstrip("```").rstrip("```");client("./","python",f"```{rc0}```")'}{#2}[#3][#4]}{\inln{#1}{#2}[#3][#4]}}
+\NewDocumentCommand{\runPythonChunk}{O{} m m O{} O{} O{vbox}}
+{\renewcommand{\LANGcmd}{python} \runRChunk[#1]{#2}{#3}[#4][#5][#6]}
%%%%%%%%
@@ -503,4 +543,4 @@
}
-\endinput \ No newline at end of file
+\endinput
diff --git a/macros/latex/contrib/runcode/runcode.tex b/macros/latex/contrib/runcode/runcode.tex
index 89c7acd6aa..23f833bdf5 100644
--- a/macros/latex/contrib/runcode/runcode.tex
+++ b/macros/latex/contrib/runcode/runcode.tex
@@ -1,4 +1,4 @@
-% LaTeX Package: runcode 2023/06/23 v2.0
+% LaTeX Package: runcode 2023/09/08 v2.2
%
% Copyright (C) 2020-2023 by Haim Bar and HaiYing Wang
%
@@ -49,7 +49,7 @@ package’s github repository, at \url{https://github.com/Ossifragus/runcode}.
\end{abstract}
\section{Installation}
-\label{sec:org594ce40}
+\label{sec:org6031edc}
You can simply put the runcode.sty file in the \LaTeX{} project folder.
The server mode requires the
@@ -65,9 +65,9 @@ compiling a \LaTeX{} document.
\section{Usage}
-\label{sec:org826d1b1}
+\label{sec:org46d9194}
\subsection{Load the package:}
-\label{sec:orgfba21b6}
+\label{sec:orgdf4d2a5}
\begin{minted}[]{latex}
\usepackage[options]{runcode}
\end{minted}
@@ -139,7 +139,7 @@ be customized with \texttt{\textbackslash{}tcbset},
\end{minted}
\subsection{Basic commands:}
-\label{sec:org9a60003}
+\label{sec:org1eb4192}
\begin{itemize}
\item \texttt{\textbackslash{}runExtCode\{Arg1\}\{Arg2\}\{Arg3\}[Arg4]} runs an external code.
@@ -203,11 +203,27 @@ output file in \texttt{Arg3} exists: the cached result will be used and the code
will not run.
\end{itemize}
\end{itemize}
+
+\item \texttt{\textbackslash{}showChunk\{Arg1\}\{Arg2\}[Arg3][Arg4]} prints a selected chunk from source
+code. The chunk is identified in the source code by two strings that define
+the beginning and end of the chunk. The default beginning is \texttt{label===<name>}
+where \texttt{<name>} should be a unique user-defined chunk ID. The default end marker is
+\texttt{===end}. In the code, these markers should appear after a comment character, so
+that the code will run.
+
+\begin{itemize}
+\item \texttt{Arg1} is the programming language.
+\item \texttt{Arg2} is the source file name.
+\item \texttt{Arg3} is is the chunk identifier.
+\item \texttt{Arg4} and \texttt{Arg5} are the beginning and end markings of a chunk (optional with
+default \texttt{label==} and \texttt{===end}.
+\end{itemize}
\end{itemize}
+
\subsection{Extended commands:}
-\label{sec:org57656ef}
+\label{sec:org2e715a7}
\begin{itemize}
\item \texttt{\textbackslash{}runCodeIncOut\{Arg1\}\{Arg2\}[Arg3][Arg4][Arg5]} runs an external code and
embeds the output. This is a combination of \texttt{\textbackslash{}runExtCode} and \texttt{\textbackslash{}includeOutput}.
@@ -224,89 +240,56 @@ functionality is the same as that of \texttt{Arg3} of \texttt{\textbackslash{}in
\end{itemize}
\subsection{Language specific shortcuts:}
-\label{sec:org9f79956}
-\href{https://julialang.org/}{Julia}
+\label{sec:org04ff6f1}
+Replace \texttt{LANG} with \texttt{Julia}, \texttt{MatLab}, \texttt{Python}, or \texttt{R}, for the \href{https://julialang.org/}{Julia}, \href{https://www.mathworks.com/products/matlab.html}{MatLab}, \href{https://www.python.org/}{Python}, \href{https://www.r-project.org/}{R}
+language, respectively, for the following commands.
\begin{itemize}
-\item \texttt{\textbackslash{}runJulia[Arg1]\{Arg2\}\{Arg3\}[Arg4]} runs an external \href{https://julialang.org/}{Julia} code file.
+\item \texttt{\textbackslash{}runLANG[Arg1]\{Arg2\}\{Arg3\}[Arg4]} runs an external \texttt{LANG} code file.
\begin{itemize}
-\item \texttt{Arg1} is optional and uses \href{https://pypi.org/project/talk2stat/}{talk2stat}'s \href{https://julialang.org/}{Julia} server by default.
+\item \texttt{Arg1} is optional and uses \href{https://pypi.org/project/talk2stat/}{talk2stat}'s \texttt{LANG} server by default.
\item \texttt{Arg2}, \texttt{Arg3}, and \texttt{Arg4} have the same effects as those of the basic command
\texttt{\textbackslash{}runExtCode}.
\end{itemize}
-\item \texttt{\textbackslash{}runJuliaIncOut[Arg1]\{Arg2\}[Arg3][Arg4][Arg5]} runs an external \href{https://julialang.org/}{Julia} code
+\item \texttt{\textbackslash{}runLANGIncOut[Arg1]\{Arg2\}[Arg3][Arg4][Arg5]} runs an external \texttt{LANG} code
file and embeds the output.
\begin{itemize}
-\item \texttt{Arg1} is optional and uses \href{https://pypi.org/project/talk2stat/}{talk2stat}'s \href{https://julialang.org/}{Julia} server by default.
+\item \texttt{Arg1} is optional and uses \href{https://pypi.org/project/talk2stat/}{talk2stat}'s \texttt{LANG} server by default.
\item \texttt{Arg2}, \texttt{Arg3}, \texttt{Arg4}, and \texttt{Arg5} have the same effects as those of the command
\texttt{\textbackslash{}runCodeIncOut}.
\end{itemize}
-\item \texttt{\textbackslash{}inlnJulia[Arg1]\{Arg2\}[Arg3][Arg4]} runs \href{https://julialang.org/}{Julia} source code (\texttt{Arg2}) and displays
+\item \texttt{\textbackslash{}inlnLANG[Arg1]\{Arg2\}[Arg3][Arg4]} runs \texttt{LANG} source code (\texttt{Arg2}) and displays
the output in line.
\begin{itemize}
-\item \texttt{Arg1} is optional and uses the \href{https://julialang.org/}{Julia} server by default.
-\item \texttt{Arg2} is the \href{https://julialang.org/}{Julia} source code to run. If the \href{https://julialang.org/}{Julia} source code is wrapped
+\item \texttt{Arg1} is optional and uses the \texttt{LANG} server by default.
+\item \texttt{Arg2} is the \texttt{LANG} source code to run. If the \texttt{LANG} source code is wrapped
between "\texttt{```}" on both sides (as in the markdown grammar), then it will be
implemented directly; otherwise the code will be written to a file on the
disk and then be called.
\item \texttt{Arg3} and \texttt{Arg4} have the same effects as those of the basic command \texttt{\textbackslash{}inln}.
\end{itemize}
-\end{itemize}
-\href{https://www.mathworks.com/products/matlab.html}{MatLab}
-
-\begin{itemize}
-\item \texttt{\textbackslash{}runMatLab[Arg1]\{Arg2\}\{Arg3\}[Arg4]} runs an external \href{https://www.mathworks.com/products/matlab.html}{MatLab} code file.
-\begin{itemize}
-\item \texttt{Arg1} is optional and uses \href{https://pypi.org/project/talk2stat/}{talk2stat}'s \href{https://www.mathworks.com/products/matlab.html}{MatLab} server by default.
-\item \texttt{Arg2}, \texttt{Arg3}, and \texttt{Arg4} have the same effects as those of the basic command
-\texttt{\textbackslash{}runExtCode}.
-\end{itemize}
-\item \texttt{\textbackslash{}runMatLabIncOut[Arg1]\{Arg2\}[Arg3][Arg4][Arg5]} runs an external \href{https://www.mathworks.com/products/matlab.html}{MatLab} code
-file and embeds the output.
+\item \texttt{\textbackslash{}runLANGChunk[Arg1]\{Arg2\}\{Arg3\}[Arg4][Arg5][Arg6]} runs a selected chunk from
+an external \texttt{LANG} code file and embeds the output.
\begin{itemize}
-\item \texttt{Arg1} is optional and uses \href{https://pypi.org/project/talk2stat/}{talk2stat}'s \href{https://www.mathworks.com/products/matlab.html}{MatLab} server by default.
-\item \texttt{Arg2}, \texttt{Arg3}, \texttt{Arg4}, and \texttt{Arg5} have the same effects as those of the command
-\texttt{\textbackslash{}runCodeIncOut}.
-\end{itemize}
-\item \texttt{\textbackslash{}inlnMatLab[Arg1]\{Arg2\}[Arg3][Arg4]} runs \href{https://www.mathworks.com/products/matlab.html}{MatLab} source code (\texttt{Arg2}) and
-displays the output in line.
-\begin{itemize}
-\item \texttt{Arg1} is optional and uses the \href{https://www.mathworks.com/products/matlab.html}{MatLab} server by default.
-\item \texttt{Arg2} is the \href{https://www.mathworks.com/products/matlab.html}{MatLab} source code to run. If the \href{https://www.mathworks.com/products/matlab.html}{MatLab} source code is wrapped
-between "```" on both sides (as in the markdown grammar), then it will be
-implemented directly; otherwise the code will be written to a file on the
-disk and then be called.
-\item \texttt{Arg3} and \texttt{Arg4} have the same effects as those of the basic command \texttt{\textbackslash{}inln}.
+\item \texttt{Arg1} (optional ) uses \href{https://pypi.org/project/talk2stat/}{talk2stat}'s \texttt{LANG} server by default.
+\item \texttt{Arg2} is the source file name.
+\item \texttt{Arg3} is is the chunk identifier.
+\item \texttt{Arg4} (optional) controls whether to run the code.
+\item \texttt{Arg5} (optional) is the output file name.
+\item \texttt{Arg6} (optional) controls the type of output with a default value \texttt{vbox}.
\end{itemize}
\end{itemize}
-\href{https://www.python.org/}{Python}
+For example,
+\begin{minted}[]{latex}
+\runR{code/MontyHall_1.R}{montyhall-R1}
+\runRIncOut{code/MontyHall_1.R}[][montyhall-R1]
+\end{minted}
+
+Specifically for \href{https://www.python.org/}{Python},
\begin{itemize}
-\item \texttt{\textbackslash{}runPython[Arg1]\{Arg2\}\{Arg3\}[Arg4]} runs an external \href{https://www.python.org/}{Python} code file.
-\begin{itemize}
-\item \texttt{Arg1} is optional and uses \href{https://pypi.org/project/talk2stat/}{talk2stat}'s \href{https://www.python.org/}{Python} server by default.
-\item \texttt{Arg2}, \texttt{Arg3}, and \texttt{Arg4} have the same effects as those of the basic command
-\texttt{\textbackslash{}runExtCode}.
-\end{itemize}
-\item \texttt{\textbackslash{}runPythonIncOut[Arg1]\{Arg2\}[Arg3][Arg4][Arg5]} runs an external \href{https://www.python.org/}{Python} code
-file and embeds the output.
-\begin{itemize}
-\item \texttt{Arg1} is optional and uses \href{https://pypi.org/project/talk2stat/}{talk2stat}'s \href{https://www.python.org/}{Python} server by default.
-\item \texttt{Arg2}, \texttt{Arg3}, \texttt{Arg4}, and \texttt{Arg5} have the same effects as those of the command
-\texttt{\textbackslash{}runCodeIncOut}.
-\end{itemize}
-\item \texttt{\textbackslash{}inlnPython[Arg1]\{Arg2\}[Arg3][Arg4]} runs \href{https://www.python.org/}{Python} source code (\texttt{Arg2}) and
-displays the output in line.
-\begin{itemize}
-\item \texttt{Arg1} is optional and uses the \href{https://www.python.org/}{Python} server by default.
-\item \texttt{Arg2} is the \href{https://julialang.org/}{Julia} source code to run. If the \href{https://www.python.org/}{Python} source code is wrapped
-between "```" on both sides (as in the markdown grammar), then it will be
-implemented directly; otherwise the code will be written to a file on the
-disk and then be called.
-\item \texttt{Arg3} and \texttt{Arg4} have the same effects as those of the basic command \texttt{\textbackslash{}inln}.
-\end{itemize}
\item \texttt{\textbackslash{}runPythonBatch[Arg1][Arg2]} runs an external \href{https://www.python.org/}{Python} code file in batch mode
(without a server running). Python (at least currently), unlike the other
languages we use, does not have an option to save and restore a session, which
@@ -320,47 +303,24 @@ installed via \texttt{pip3 install dill}.
\end{itemize}
\end{itemize}
-\href{https://www.r-project.org/}{R}
-
-\begin{itemize}
-\item \texttt{\textbackslash{}runR[Arg1]\{Arg2\}\{Arg3\}[Arg4]} runs an external \href{https://www.r-project.org/}{R} code file.
-\begin{itemize}
-\item \texttt{Arg1} is optional and uses \href{https://pypi.org/project/talk2stat/}{talk2stat}'s \href{https://www.r-project.org/}{R} server by default.
-\item \texttt{Arg2}, \texttt{Arg3}, and \texttt{Arg4} have the same effects as those of the basic command
-\texttt{\textbackslash{}runExtCode}.
-\end{itemize}
-
-\item \texttt{\textbackslash{}runRIncOut[Arg1]\{Arg2\}[Arg3][Arg4][Arg5]} runs an external \href{https://www.r-project.org/}{R} code file and
-embeds the output.
-\begin{itemize}
-\item \texttt{Arg1} is optional and uses \href{https://pypi.org/project/talk2stat/}{talk2stat}'s \href{https://www.r-project.org/}{R} server by default.
-\item \texttt{Arg2}, \texttt{Arg3}, \texttt{Arg4}, and \texttt{Arg5} have the same effects as those of the command
-\texttt{\textbackslash{}runCodeIncOut}.
-\end{itemize}
-
-\item \texttt{\textbackslash{}inlnR[Arg1]\{Arg2\}[Arg3][Arg4]} runs \href{https://www.r-project.org/}{R}
-source code (\texttt{Arg2}) and displays the output in line.
-\begin{itemize}
-\item \texttt{Arg1} is optional and uses the \href{https://www.r-project.org/}{R} server by default.
-\item \texttt{Arg2} is the \href{https://www.r-project.org/}{R} source code to run. If the \href{https://www.r-project.org/}{R} source code is wrapped between
-"```" on both sides (as in the markdown grammar), then it will be
-implemented directly; otherwise the code will be written to a file on the
-disk and then be called.
-\item \texttt{Arg3} and \texttt{Arg4} have the same effects as those of the basic command \texttt{\textbackslash{}inln}.
-\end{itemize}
-\end{itemize}
-
\section{Revisions}
-\label{sec:orga78221a}
+\label{sec:orgae938b1}
\begin{itemize}
+\item v2.2, September 8, 2023: add \texttt{\textbackslash{}showChunk} basic command and \texttt{\textbackslash{}runLANGChunk}
+commands for multiple languages.
+\item v2.1, June 30, 2023: detokenize code which is passed to \texttt{\textbackslash{}inln}. This is
+necessary when the code contains special latex characters like backslash.
+These characters are escaped by latex when they are passed to macros as arguments,
+which, in the case of \texttt{\textbackslash{}inln}, alters the correct syntax and causes execution errors.
+Detokenizing ensures that the code is passed as-is to R/Julia/MatLab/Python.
+We thank \href{https://github.com/kiryph}{kiryph} for reporting the issue.
\item v2.0, June 23, 2023: add \texttt{\textbackslash{}runCodeIncOut} command that runs an external code and
embeds the output and andd some language specific shortcuts; update
\texttt{\textbackslash{}runExtCode} so that if the output file does not exist, the \texttt{cache} option will
be overridden and the code will run; update \texttt{\textbackslash{}inln} so that its \texttt{Arg4} accept
\texttt{cache} or appending \texttt{.cache} to use the cached result. We thank \href{https://github.com/kiryph}{kiryph} for
suggesting these features.
-
\item v1.9, June 13, 2023: update \texttt{\textbackslash{}inln} command; the optional \texttt{Arg3} is the output
file name and the optional \texttt{Arg4} is the output type.
\item v1.8, January 18, 2023, add support to \href{https://ctan.org/pkg/listings?lang=en}{listings.}
@@ -381,7 +341,7 @@ code files, zero bytes in output files.)
\end{itemize}
\section{Contributing}
-\label{sec:org097e6a5}
+\label{sec:org9eb0902}
We welcome your contributions to this package by opening issues on
GitHub and/or making a pull request. We also appreciate more example
documents written using \texttt{runcode}.