summaryrefslogtreecommitdiff
path: root/Master
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2024-03-15 21:24:25 +0000
committerKarl Berry <karl@freefriends.org>2024-03-15 21:24:25 +0000
commit9b538c17bb17945ed3521bdc36baeca6972b0875 (patch)
treea58c1f624f91db54b13e9c00de140d0f0a845116 /Master
parent3131cacfc8d58c8e3f5f4992a9129b56b2e78cae (diff)
robust-externalize (15mar24)
git-svn-id: svn://tug.org/texlive/trunk@70653 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master')
-rw-r--r--Master/texmf-dist/doc/latex/robust-externalize/robust-externalize.pdfbin1634655 -> 1634999 bytes
-rw-r--r--Master/texmf-dist/doc/latex/robust-externalize/robust-externalize.tex6
-rw-r--r--Master/texmf-dist/tex/latex/robust-externalize/robust-externalize.sty172
3 files changed, 175 insertions, 3 deletions
diff --git a/Master/texmf-dist/doc/latex/robust-externalize/robust-externalize.pdf b/Master/texmf-dist/doc/latex/robust-externalize/robust-externalize.pdf
index 92914f28333..afb803aa2c4 100644
--- a/Master/texmf-dist/doc/latex/robust-externalize/robust-externalize.pdf
+++ b/Master/texmf-dist/doc/latex/robust-externalize/robust-externalize.pdf
Binary files differ
diff --git a/Master/texmf-dist/doc/latex/robust-externalize/robust-externalize.tex b/Master/texmf-dist/doc/latex/robust-externalize/robust-externalize.tex
index 049cfb54432..ca511919896 100644
--- a/Master/texmf-dist/doc/latex/robust-externalize/robust-externalize.tex
+++ b/Master/texmf-dist/doc/latex/robust-externalize/robust-externalize.tex
@@ -105,7 +105,7 @@
{\Large\bfseries Cache anything (\tikzname, tikz-cd, python…),\\in a robust, efficient and pure way.}
\vspace{1em}
- {Léo Colisson \quad Version 2.8}\\[3mm]
+ {Léo Colisson \quad Version 2.9}\\[3mm]
{\href{https://github.com/leo-colisson/robust-externalize}{\texttt{github.com/leo-colisson/robust-externalize}}}
\end{center}
@@ -4932,6 +4932,10 @@ Options > Configure TeXstudio > Editor > Replace tabs in text with spaces
\section{Changelog}
\begin{itemize}
+\item v2.9 (2024/03/15)
+ \begin{itemize}
+ \item Bug that may forbid the package to load has been fixed (you might encounter |ERROR: Missing = inserted for \ifnum|)
+ \end{itemize}
\item v2.8 (current master, not yet released):
\begin{itemize}
\item Fix a regression bug introduced in 2.7: |python print code and result| was adding a new line above the code printed. This is fixed now.
diff --git a/Master/texmf-dist/tex/latex/robust-externalize/robust-externalize.sty b/Master/texmf-dist/tex/latex/robust-externalize/robust-externalize.sty
index 5deeec6c84b..a84155e474b 100644
--- a/Master/texmf-dist/tex/latex/robust-externalize/robust-externalize.sty
+++ b/Master/texmf-dist/tex/latex/robust-externalize/robust-externalize.sty
@@ -1,4 +1,4 @@
-\ProvidesPackage{robust-externalize}[2.8 Cache anything (tikz, latex, python) in a robust, efficient and pure way.]
+\ProvidesPackage{robust-externalize}[2024/03/15 v2.9 Cache anything (tikz, latex, python) in a robust, efficient and pure way.]
% todo:
% change order argument replace from list, it is hard to read this way
@@ -251,6 +251,7 @@
\msg_new:nnn {robExt}{enabled parallel no shell escape}{Warning:~you~enabled~parallel~compilation~but~shell-escape~is~disabled.}
\msg_new:nnn {robExt}{rerun because parallel}{Warning:~Compiling~all~missing~figures~in~parallel~with~"#1".~You~need~to~rerun~LaTeX~to~include~them.}
\msg_new:nnn {robExt}{gpgetvar recompilation needed}{Warning:~you~need~to~recompile~as~the~gpgetvar~variable~"#1"~does~not~exist~yet.}
+\msg_new:nnn {robExt}{warning res not defined}{Warning:~the~result~\\res{#1}~is~not~defined,~maybe~try~to~recompile..}
% dummy placeholders added if image is not present
\def\robExtImagePlaceholderIfManualMode{
@@ -857,7 +858,7 @@ if __name__ == '__main__':
\NewDocumentCommand{\robExtPlaceholderFromString}{smm}{
- \str_set_eq:cN { l__robExt_placeholder_#2_str } {#3}
+ \str_set_eq:cN { l__robExt_placeholder_#2_str } #3
\checkIfPlaceholderNameIsLegal{#2}
\IfBooleanTF {#1} {} {\robExtAddPlaceholderToList{#2}}
}
@@ -2808,6 +2809,9 @@ if __name__ == '__main__':
recompile/.code={\def\robExtForceRecompilation{}},
do not recompile/.code={\let\robExtForceRecompilation\undefined},
set compilation command/.code={\robExtSetCompilationCommand{#1}},
+ change source extension/.style={
+ add before placeholder/.expanded={__ROBEXT_COMPILATION_COMMAND__}{\robExtCp\space "__ROBEXT_SOURCE_FILE__" "__ROBEXT_OUTPUT_PREFIX__.#1" &&},
+ },
% like "set compilation command" but moves the "__ROBEXT_OUTPUT_PDF__-tmp" to "__ROBEXT_OUTPUT_PDF__" if
% there is no error.
set compilation command move if no error/.style={
@@ -3264,6 +3268,38 @@ if __name__ == '__main__':
}
\let\cacheMe\robExtCacheMe
+\ExplSyntaxOn
+%% #1: Arguments, #2: content to externalize
+\str_new:N \__robExt_tmp_contain_code_str
+\tl_new:N \__robExt_tmp_contain_code_tl
+\NewDocumentCommand{\robExtCacheMeCode}{O{}+v}{%
+ {% Group
+ %% We store the input in a non-string element for efficiently implementing "auto forward"
+ \edef\robExtUserInputCacheMe{\unexpanded{#2}}%
+ \tl_set:Nn \__robExt_tmp_contain_code_tl {#2}
+ \tl_replace_all:Nen \__robExt_tmp_contain_code_tl {\char_generate:nn{13}{12}} {^^J}
+ \str_set:Ne \__robExt_tmp_contain_code_str {\tl_to_str:e {\__robExt_tmp_contain_code_tl}}
+ %\str_show:N \__robExt_tmp_contain_code_str
+ %\tl_replace_all:Nnn \__robExt_tmp_contain_code_str {^^M} {b}
+ %\str_show:N \__robExt_tmp_contain_code_str
+ \pgfkeys{%
+ /robExt/.cd,%
+ %% This is needed notably if the cached elements are nested, like the include command uses itself a tikz
+ %% picture etc cached via \cacheTikz... It it hard to reset everything efficiently (like we might not
+ %% want to reset all compilation commands etc), so you can add here stuff that might need to be restored
+ %% later.
+ reset,
+ /utils/exec={\robExtPlaceholderFromString{__ROBEXT_MAIN_CONTENT_ORIG__}{\__robExt_tmp_contain_code_str}},
+ default~style,%
+ defaultPlaceholderFromCodeStyle,
+ #1,
+ }%
+ \robExtEvaluateCompileAndInclude%
+ }%
+}
+\let\cacheMeCode\robExtCacheMeCode
+\ExplSyntaxOff
+
%% #1: Arguments, #2: content to externalize
\NewDocumentEnvironment{RobExtCacheMe}{m+b}{%
\robExtCacheMe[#1]{#2}%
@@ -3748,6 +3784,138 @@ print_file.close()
\robExtCopyGroupPlaceholders{python print code result}{main}
\robExtRegisterGroupPlaceholders{python print code result}
+%%%%%%
+%%%%%% Group "python exec"
+%%%%%%
+
+\robExtClearGroupPlaceholders{main}
+
+% if we set res = XXX or res[""] = XXX it will print it by default, if we do instead res[42] = XXX
+% it will not load it. To make this easy to program, we create an element for the empty string,
+% this way we can always \res{} in the include command.
+
+\begin{RobExtPlaceholderFromCode}[remove spaces until=>]{__ROBEXT_PYTHON_EXEC_TEMPLATE__}
+ > def toMacro(x):
+ > if hasattr(x, '__toMacro'):
+ > return x.__toMacro()
+ > else:
+ > return str(x)
+ >
+ > __ROBEXT_PYTHON_EXEC_LIBRARY_CHANGES__
+ > __ROBEXT_PYTHON_EXEC_CUSTOM_TO_MACRO_DEF__
+ > # We create a special class extending dict to check if the user just did res[42] = xxx
+ > # or res = foo, as in that case we will just print the result directly.
+ > class DictToExportToMacros(dict):
+ > pass
+ > res = DictToExportToMacros()
+ > res[""] = ""
+ > __ROBEXT_PYTHON_EXEC_RES_EQUALITY____ROBEXT_MAIN_CONTENT_ORIG__
+ > if not isinstance(res, DictToExportToMacros):
+ > write_to_out(r"\gdef\robExtResMacro{" + toMacro(res) + r"}")
+ > else:
+ > for k in res:
+ > # We create a macro with csname to allow numbers in the name etc and parallel compilation
+ > write_to_out(r"\expandafter\gdef\csname robExtResMacro" + str(k) + r"\endcsname{" + toMacro(res[k]) + r"}")
+\end{RobExtPlaceholderFromCode}
+
+\robExtSetPlaceholder{__ROBEXT_PYTHON_EXEC_RES_EQUALITY__}{}
+\robExtSetPlaceholder{__ROBEXT_PYTHON_EXEC_LIBRARY_CHANGES__}{}
+\begin{RobExtPlaceholderFromCode}{__ROBEXT_PYTHON_EXEC_CUSTOM_TO_MACRO_DEF__}
+\end{RobExtPlaceholderFromCode}
+
+% Some macro always expect a number to work, and must be expandable
+\NewDocumentCommand{\robExtResForceNumber}{m}{%
+ \ifcsname robExtResMacro#1\endcsname%
+ \csname robExtResMacro#1\endcsname%
+ \else%
+ 404%
+ \fi%
+}
+
+\def\robExtNoResult#1{%
+ \textbf{??}%
+}
+\NewDocumentCommand{\robExtRes}{m}{%
+ \ifcsname robExtResMacro#1\endcsname%
+ \csname robExtResMacro#1\endcsname%
+ \else%
+ \msg_warning:nnx{robExt}{warning res not defined}{#1}%%
+ \robExtNoRes{#1}%
+ \fi%
+}
+\let\res\robExtRes
+
+\robExtConfigure{
+ new preset={python exec res}{
+ python,
+ % we do that so that custom include command does not pick the result from previous runs locally
+ /utils/exec={\let\robExtResMacro\undefined},
+ import placeholders={__ROBEXT_PYTHON_EXEC_CUSTOM_TO_MACRO_DEF__,__ROBEXT_PYTHON_EXEC_RES_EQUALITY__,__ROBEXT_PYTHON_EXEC_TEMPLATE__,__ROBEXT_PYTHON_EXEC_LIBRARY_CHANGES__},
+ custom include command={\robExtRes{}},
+ set placeholder={__ROBEXT_MAIN_CONTENT__}{__ROBEXT_PYTHON_EXEC_TEMPLATE__},
+ },
+ new preset={python exec}{
+ python exec res,
+ set placeholder={__ROBEXT_PYTHON_EXEC_RES_EQUALITY__}{res =},
+ },
+}
+
+\robExtCopyGroupPlaceholders{python exec}{main}
+\robExtRegisterGroupPlaceholders{python exec}
+
+%%%%%%
+%%%%%% Group "sage" and "sage res"
+%%%%%%
+
+\robExtClearGroupPlaceholders{main}
+
+\robExtSetPlaceholder{__ROBEXT_SAGE_EXEC__}{sage}
+
+% We need to overwrite some definitions as it adds a .sage in front automatically by default
+\begin{RobExtPlaceholderFromCode}[]{__ROBEXT_SAGE_EXEC_LIBRARY_CHANGES__}
+def get_filename_from_extension(extension):
+ '''
+ If you want to create a file with extension 'extension' (with the appropriate base name), this command
+ is for you. For instance get_filename_from_extension(".mp4") would return something like
+ robExt-somehash.mp4
+ the extension can also be like get_filename_from_extension("-out.tex") etc.
+ '''
+ return os.path.join(get_cache_folder(), "__ROBEXT_OUTPUT_PREFIX__" + extension)
+
+ROBEXT_PLOT_SAVE_FORMAT = "png"
+ROBEXT_PLOT_SAVE_OPTIONS = {}
+ROBEXT_PLOT_ID = 0
+
+def __plot_graphics_to_macro(self):
+ global ROBEXT_PLOT_SAVE_FORMAT
+ global ROBEXT_PLOT_ID
+ global ROBEXT_PLOT_SAVE_OPTIONS
+ filename = get_file_base() + f"plot-{ROBEXT_PLOT_ID}.{ROBEXT_PLOT_SAVE_FORMAT}"
+ self.save(filename, **ROBEXT_PLOT_SAVE_OPTIONS)
+ ROBEXT_PLOT_ID += 1
+ return filename
+
+sage.plot.graphics.Graphics.__toMacro = __plot_graphics_to_macro
+
+\end{RobExtPlaceholderFromCode}
+
+\robExtConfigure{
+ new preset={sage res}{
+ python exec res,
+ import placeholders={__ROBEXT_SAGE_EXEC__,__ROBEXT_SAGE_EXEC_LIBRARY_CHANGES__},
+ set placeholder={__ROBEXT_PYTHON_EXEC_LIBRARY_CHANGES__}{__ROBEXT_SAGE_EXEC_LIBRARY_CHANGES__},
+ % Sage expects the extension .sage
+ set compilation command={__ROBEXT_SAGE_EXEC__ "__ROBEXT_OUTPUT_PREFIX__.sage"},
+ change source extension=sage,
+ },
+ new preset={sage}{
+ sage res,
+ set placeholder={__ROBEXT_PYTHON_EXEC_RES_EQUALITY__}{res =},
+ },
+}
+
+\robExtCopyGroupPlaceholders{python exec}{main}
+\robExtRegisterGroupPlaceholders{python exec}
%%%%%%
%%%%%% Group "verbatim"