texlive[68223] Master/texmf-dist: runcode (9sep23)

commits+karl at tug.org commits+karl at tug.org
Sat Sep 9 22:09:19 CEST 2023


Revision: 68223
          http://tug.org/svn/texlive?view=revision&revision=68223
Author:   karl
Date:     2023-09-09 22:09:19 +0200 (Sat, 09 Sep 2023)
Log Message:
-----------
runcode (9sep23)

Modified Paths:
--------------
    trunk/Master/texmf-dist/doc/latex/runcode/README
    trunk/Master/texmf-dist/doc/latex/runcode/runcode.pdf
    trunk/Master/texmf-dist/doc/latex/runcode/runcode.tex
    trunk/Master/texmf-dist/tex/latex/runcode/runcode.sty

Modified: trunk/Master/texmf-dist/doc/latex/runcode/README
===================================================================
--- trunk/Master/texmf-dist/doc/latex/runcode/README	2023-09-09 20:09:08 UTC (rev 68222)
+++ trunk/Master/texmf-dist/doc/latex/runcode/README	2023-09-09 20:09:19 UTC (rev 68223)
@@ -1,4 +1,4 @@
-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
@@ -5,7 +5,7 @@
 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:

Modified: trunk/Master/texmf-dist/doc/latex/runcode/runcode.pdf
===================================================================
(Binary files differ)

Modified: trunk/Master/texmf-dist/doc/latex/runcode/runcode.tex
===================================================================
--- trunk/Master/texmf-dist/doc/latex/runcode/runcode.tex	2023-09-09 20:09:08 UTC (rev 68222)
+++ trunk/Master/texmf-dist/doc/latex/runcode/runcode.tex	2023-09-09 20:09:19 UTC (rev 68223)
@@ -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 @@
 \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 @@
 
 
 \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 @@
 \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 @@
 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 @@
 \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}
-
+\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{\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}.
+\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}
-\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.
-\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}.
-\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,40 +303,18 @@
 \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
@@ -360,7 +321,6 @@
 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 @@
 \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}.

Modified: trunk/Master/texmf-dist/tex/latex/runcode/runcode.sty
===================================================================
--- trunk/Master/texmf-dist/tex/latex/runcode/runcode.sty	2023-09-09 20:09:08 UTC (rev 68222)
+++ trunk/Master/texmf-dist/tex/latex/runcode/runcode.sty	2023-09-09 20:09:19 UTC (rev 68223)
@@ -4,8 +4,10 @@
 %
 %  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
 \runcodetrue
@@ -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{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")'}
+        }{}
+      }
     }{}
-    \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")'}
-    }{}
-}}
+  }
+}
 
 \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,7 +127,16 @@
 \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
 \usepackage[cache=false]{minted}
@@ -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,79 +421,86 @@
   \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{\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]}}
+\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]}
+
+
 % 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{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{\runMatLabIncOut}{O{} m O{} O{} O{vbox}}
+{\renewcommand{\LANGcmd}{matlab} \runRIncOut[#1]{#2}[#3][#4][#5]}
 
-\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]}}
+\NewDocumentCommand{\inlnMatLab}{O{} m O{} O{inline}}
+{\renewcommand{\LANGcmd}{matlab} \inlnR[#1]{#2}[#3][#4]}
 
+\NewDocumentCommand{\runMatLabChunk}{O{} m m O{} O{} O{vbox}}
+{\renewcommand{\LANGcmd}{matlab} \runRChunk[#1]{#2}{#3}[#4][#5][#6]}
+
+
 % 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{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{\runPythonIncOut}{O{} m O{} O{} O{vbox}}
+{\renewcommand{\LANGcmd}{python} \runRIncOut[#1]{#2}[#3][#4][#5]}
 
-\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{\inlnPython}{O{} m O{} O{inline}}
+{\renewcommand{\LANGcmd}{python} \inlnR[#1]{#2}[#3][#4]}
 
+\NewDocumentCommand{\runPythonChunk}{O{} m m O{} O{} O{vbox}}
+{\renewcommand{\LANGcmd}{python} \runRChunk[#1]{#2}{#3}[#4][#5][#6]}
 
+
 %%%%%%%%
 % For Python batch mode, implement saving and restoring session
 % Arg #1 is the source file name,
@@ -503,4 +543,4 @@
 }
 
 
-\endinput
\ No newline at end of file
+\endinput



More information about the tex-live-commits mailing list.