diff --git a/src/wip/cache/cache.pysty3 b/src/wip/cache/cache.pysty3 new file mode 100644 index 0000000..6337939 --- /dev/null +++ b/src/wip/cache/cache.pysty3 @@ -0,0 +1,121 @@ +__HEADER__(Cache definitions of previous LaTeX runs to avoid computations) + + + +%%%% This is just a proof of concept package, +%%%% there is possibly more room for clean-up +%%%% and / or speed-up etc. + +%%% Also, the provided +%%% \DeclareCachedDocumentCommand +%%% is of course not really +%%% useful and just for demonstration +%%% purposes + +\bool_new:N \g__cache_cache_bool +\int_new:N \g__cache_cache_version_document_int +\int_new:N \g__cache_cache_version_aux_int +\int_gset:Nn \g__cache_cache_version_aux_int { -1 } + +\tl_new:N \g__cache_dump_auxfile_tl +\tl_new:N \g__cache_lazy_document_tl +\tl_new:N \g__cache_lazy_auxfile_tl + +\keys_define:nn { cache } + { + cache .bool_set:N = \g__cache_cache_bool, + cache .default:n = { true }, + __cache version__ .int_set:N = \g__cache_cache_version_document_int, + cache version .meta:nn = { cache } { cache = true, __cache version__ = #1 }, + cache version .default:n = { 0 }, + } +\RequirePackage{l3keys2e} +\ProcessKeysOptions{cache} + + +% Setting up lazy execution and +% selecting of executing after reading of aux file +% if cache option has been used +\bool_if:NTF \g__cache_cache_bool + { + %% Writing things (at one go) to aux file at end of document: + \cs_new:Npn \__cache_put_aux:n #1 + { + \tl_gput_right:Nn \g__cache_dump_auxfile_tl { #1 } + } + \cs_generate_variant:Nn \__cache_put_aux:n { x, V } + + \cs_generate_variant:Nn \iow_now:Nn { c V } + + %%% Handles dumping data to aux file at end of document + \hook_gput_code:nnn { enddocument } { cache } + { + \iow_now:cV { @auxout } \g__cache_dump_auxfile_tl + } + + %%% Writes the current cache version into aux file + \__cache_put_aux:x + { + \ExplSyntaxOn + \int_gset:Nn \exp_not:N \g__cache_cache_version_aux_int + { + \int_use:N \g__cache_cache_version_document_int + } + \ExplSyntaxOff + } + + %%% Executing something lazily at beginning of document + %%% Lazy code only gets executed if auxfile version is older than document + \cs_new:Npn \__cache_lazy:n + { + \tl_gput_right:Nn \g__cache_lazy_document_tl + } + + %%% Caching things. Handles writing and reading to aux file + %%% and makes code available in the next run of LaTeX + \cs_new:Npn \__cache_cache:n #1 + { + \tl_set:Nn \l_tmpa_tl + { + \csname tl_gput_right:cn \endcsname { g__cache_lazy_auxfile_tl } { #1 } + } + \regex_replace_all:nnN { \cP\# } { \cO\# } \l_tmpa_tl + \__cache_put_aux:V \l_tmpa_tl + } + + %%% This handles loading either the cached definitions + %%% from last run or executing the lazy definitions from the current run + %%% after loading the aux file + \hook_gput_code:nnn { begindocument } { cache } + { + \int_compare:nNnTF + \g__cache_cache_version_aux_int < \g__cache_cache_version_document_int + { + \tl_use:N \g__cache_lazy_document_tl + } + { + \tl_use:N \g__cache_lazy_auxfile_tl + } + } + } + { + \cs_set_eq:NN \__cache_lazy:n \use:n + \cs_set_eq:NN \__cache_cache:n \use_none:n + } + +\cs_new:Npn \__cached_new_document_command:nnn #1 #2 #3 + { + \NewDocumentCommand{#1}{#2}{#3} + \__cache_cache:n + { + \csname __cached_new_document_command:nnn \endcsname { #1 } { #2 } { #3 } + } + } + +\NewDocumentCommand{\DeclareCachedDocumentCommand}{mmm} + { + \__cache_lazy:n + { + \__cached_new_document_command:nnn{#1}{#2}{#3} + } + } diff --git a/tests/wip/cache/test.tex b/tests/wip/cache/test.tex new file mode 100644 index 0000000..eb85da9 --- /dev/null +++ b/tests/wip/cache/test.tex @@ -0,0 +1,43 @@ +\documentclass{article} + + + +%%% Setting a higher cache version will cause a re-evaluation of the +% \DeclareCachedDocumentCommand macros present in the preamble +% Otherwise, the definitions can be altered or even removed without breaking +% the document, as long as the aux file is present. + + + +%% \DeclareCachedDocumentCommand is now just a plain wrapper around \DeclareDocumentCommand +%% that implements this caching, so it is not useful on itself +%% +%% If \DeclareCachedDocumentCommand is, however, some macro that does lengthy computations +%% and then issues one ore more of underlying \DeclareDocumentCommands +%% we can save this computation on the second run, since we do not evaluate +%% \DeclareCachedDocumentCommand further (we just copied its definition) +%% and load the plain definitions that the invocation produced in the last run +%% and that we saved to the aux file for restoration. + +\usepackage[cache version = 0]{mkessler-cache} + +\DeclareCachedDocumentCommand\foo{m}{foo: Called with argument '#1'. hi} +\DeclareCachedDocumentCommand\baz{m}{baz: Called with argument '#1'.} + +\DeclareCachedDocumentCommand\parser{!s !t+} + { + \IfBooleanT {#1} {*} + \IfBooleanT {#2} {$\dagger$} + } + +\begin{document} + +\foo { one } + +\baz{ arg } + +\parser*+ + +Some text. + +\end{document}