diff options
Diffstat (limited to 'Master/texmf-dist/source')
-rw-r--r-- | Master/texmf-dist/source/generic/memoize/Makefile | 56 | ||||
-rw-r--r-- | Master/texmf-dist/source/generic/memoize/memoize.edtx | 760 | ||||
-rw-r--r-- | Master/texmf-dist/source/generic/memoize/memoize.ins | 1 |
3 files changed, 494 insertions, 323 deletions
diff --git a/Master/texmf-dist/source/generic/memoize/Makefile b/Master/texmf-dist/source/generic/memoize/Makefile index 7edbd7ba341..2f79a3b8ce7 100644 --- a/Master/texmf-dist/source/generic/memoize/Makefile +++ b/Master/texmf-dist/source/generic/memoize/Makefile @@ -9,15 +9,16 @@ all: ctan/memoize.zip # Prepare the CTAN submission. PACKAGE = memoize -VERSION = 1.0.0 -YEAR = 2023 -MONTH = 10 -DAY = 10 +VERSION = 1.1.0 +YEAR = 2024 +MONTH = 01 +DAY = 02 FORMAT = generic COMMON = memoize nomemoize memoizable PLAIN = memoize-extract-one.tex +GENERIC = memoizable.code.tex SOURCE = memoize.edtx memoize.ins # $(makefiles) SCRIPTS := memoize-extract memoize-clean @@ -31,11 +32,9 @@ SCRIPTS := $(SCRIPTS:%=%.pl) $(SCRIPTS:%=%.py) %.py.1: %.1 echo .so man1/$*.1 > $@ # link to .1 man page -.PHONY: runtime -runtime: $(RUNTIME) - README = doc/README.memoize.md INSTALL = INSTALL.md +CHANGELOG = CHANGELOG.md MAKEFILE = Makefile LICENCE = LICENCE @@ -44,11 +43,11 @@ makefiles = Makefile.package Makefile.runtimes Makefile.advice Makefile.collargs codedoc-source = memoize-code.tex \ memoize-code.sty memoize-doc-common.sty -manual-source = memoize.tex \ +manual-source = memoize-doc.tex \ memoize-doc.sty memoize-doc-common.sty yadoc.sty \ - memoize.mst + memoize-doc.mst -PDF = memoize.pdf memoize-code.pdf +PDF = memoize-doc.pdf memoize-code.pdf codedoc-source := $(codedoc-source:%=doc/%) manual-source := $(manual-source:%=doc/%) @@ -80,11 +79,19 @@ ctan/$(PACKAGE).zip: ln -sr $(TDS-DOC-DIR)/examples.zip $(CTAN-DIR)/doc $(CTAN-END) +%.py.dtx: %.py + edtx2dtx -s -c '#' -B '^__version__' -E '^# Local Variables:' $< \ + | sed -e '/^% Local Variables:/Q' > $@ +%.pl.dtx: %.pl + edtx2dtx -s -c '#' -B '^my \$$PROG' -E '^# Local Variables:' $< \ + | sed -e '/^% Local Variables:/Q' > $@ -doc/memoize-code.pdf: $(SOURCE) $(codedoc-source) +doc/memoize-code.pdf: $(SOURCE) $(codedoc-source) \ + advice.edtx advice.ins collargs.edtx collargs.ins \ + $(SCRIPTS:%=%.dtx) -doc/memoize.pdf: $(manual-source) $(examples-src) +doc/memoize.pdf: $(manual-source) $(examples-src) memoize.edtx advice.edtx collargs.edtx %.pdf: %.tex latexmk -cd -lualatex -bibtex- $< && touch $@ @@ -119,11 +126,9 @@ version: $(call EDIT-VERSION-PYTHON,memoize-clean.py) $(call EDIT-VERSION-MAN,doc/memoize-extract.1.md) $(call EDIT-VERSION-MAN,doc/memoize-clean.1.md) -# Change the date of the latest release (identified by the version). - sed -Ei 's!^\\item\[\\githubrelease\{[0-9]{4}/[0-9]{2}/[0-9]{2}\}\{v$(VERSION)\}\] *$$!\\item\[\\githubrelease\{$(YEAR)/$(MONTH)/$(DAY)\}\{v$(VERSION)\}\]!' doc/memoize.tex - + $(call EDIT-DATE-CHANGELOG,CHANGELOG.md) define COLOR_VERSION -grep -E --color '[0-9]{4}[/-][0-9]{2}[/-][0-9]{2}|v?[0-9]\.[0-9]\.[0-9]|(January|February|March|April|May|June|July|August|September|October|November|December) [0-9]+, [0-9]{4}' +grep -E --color '[0-9]{4}[/-][0-9]{2}[/-][0-9]{2}|v?[0-9]\.[0-9]\.[0-9]([-a-z]*)|(January|February|March|April|May|June|July|August|September|October|November|December) [0-9]+, [0-9]{4}' endef versions-show: @@ -131,9 +136,26 @@ versions-show: @grep __version__ *.py | ${COLOR_VERSION} @grep VERSION *.pl | ${COLOR_VERSION} @grep -E '^(footer|date):' doc/memoize-*.md | ${COLOR_VERSION} - @grep -E 'githubrelease' doc/memoize.tex | ${COLOR_VERSION} + @${COLOR_VERSION} CHANGELOG.md doc/CHANGELOG.advice.md doc/CHANGELOG.collargs.md include Makefile.package include Makefile.runtimes VERSION-MAN = of Memoize v$(VERSION) + +.PHONY: all-runtimes link-all-runtimes unlink-all-runtimes test + +all-runtimes: runtimes + $(MAKE) -f Makefile.advice runtimes + $(MAKE) -f Makefile.collargs runtimes + +link-all-runtimes: link-runtimes + $(MAKE) -f Makefile.advice link-runtimes + $(MAKE) -f Makefile.collargs link-runtimes + +unlink-all-runtimes: unlink-runtimes + $(MAKE) -f Makefile.advice unlink-runtimes + $(MAKE) -f Makefile.collargs unlink-runtimes + +test: + cd testing && ./MakeTests.py diff --git a/Master/texmf-dist/source/generic/memoize/memoize.edtx b/Master/texmf-dist/source/generic/memoize/memoize.edtx index 10794c7a3b0..86ed2b61974 100644 --- a/Master/texmf-dist/source/generic/memoize/memoize.edtx +++ b/Master/texmf-dist/source/generic/memoize/memoize.edtx @@ -1,5 +1,3 @@ -% \iffalse -% % memoize.edtx (this is not a .dtx file; to produce a .dtx, process it with edtx2dtx) % %% This file is a part of Memoize, a TeX package for externalization of @@ -21,8 +19,6 @@ %% The files belonging to this work and covered by LPPL are listed in %% (<texmf>/doc/generic/memoize/)FILES. % -% \fi -% % \begin{macrocode} % % \relax @@ -68,7 +64,7 @@ % listing options app={basicstyle=\ttfamily\scriptsize}}} % % \begin{tcbraster}[raster columns=100] -% \tcbinputlisting{raster multicolumn=55, ins listing, top=1mm, bottom=1mm, title=memoize.ins,listing file=../memoize.ins, linerange={27-38}, leftupper=1mm} +% \tcbinputlisting{raster multicolumn=55, ins listing, top=1mm, bottom=1mm, title=memoize.ins,listing file=../memoize.ins, linerange={27-39}, leftupper=1mm} % \begin{tcboxedraster}[raster columns=1]{blankest, raster multicolumn=45} % \tcbinputlisting{ins listing, title=advice.ins, listing file=../advice.ins, linerange=28-31} % \tcbinputlisting{ins listing, title=collar\raisebox{0pt}[\height][0pt]{g}s.ins, listing file=../collargs.ins, linerange=29-31} @@ -77,8 +73,7 @@ % % Memoize also contains two scripts, |memoize-extract| and |memoize-clean|. % Both come in two functionally equivalent implementations: Perl (|.pl|) and a -% Python (|.py|). The code is listed in \S\ref{sec:code:scripts}, I believe it -% is self-explanatory enough to lack more than a occasional comment. +% Python (|.py|). Their code is listed in \S\ref{sec:code:scripts}. % % % \thispagestyle{empty} @@ -95,55 +90,55 @@ % % \paragraph{Identification} of |memoize|, |memoizable| and |nomemoize|. %<*mmz> -%<latex>\ProvidesPackage{memoize}[2023/10/10 v1.0.0 Fast and flexible externalization] +%<latex>\ProvidesPackage{memoize}[2024/1/02 v1.1.0 Fast and flexible externalization] %<context>%D \module[ %<context>%D file=t-memoize.tex, -%<context>%D version=1.0.0, +%<context>%D version=1.1.0, %<context>%D title=Memoize, %<context>%D subtitle=Fast and flexible externalization, %<context>%D author=Saso Zivanovic, -%<context>%D date=2023-10-10, +%<context>%D date=2024-01-02, %<context>%D copyright=Saso Zivanovic, %<context>%D license=LPPL, %<context>%D ] %<context>\writestatus{loading}{ConTeXt User Module / memoize} %<context>\unprotect %<context>\startmodule[memoize] -%<plain>% Package memoize 2023/10/10 v1.0.0 +%<plain>% Package memoize 2024/01/02 v1.1.0 %</mmz> %<*mmzable> -%<latex>\ProvidesPackage{memoizable}[2023/10/10 v1.0.0 A programmer's stub for Memoize] +%<latex>\ProvidesPackage{memoizable}[2024/1/02 v1.1.0 A programmer's stub for Memoize] %<context>%D \module[ %<context>%D file=t-memoizable.tex, -%<context>%D version=1.0.0, +%<context>%D version=1.1.0, %<context>%D title=Memoizable, %<context>%D subtitle=A programmer's stub for Memoize, %<context>%D author=Saso Zivanovic, -%<context>%D date=2023-10-10, +%<context>%D date=2024-01-02, %<context>%D copyright=Saso Zivanovic, %<context>%D license=LPPL, %<context>%D ] %<context>\writestatus{loading}{ConTeXt User Module / memoizable} %<context>\unprotect %<context>\startmodule[memoizable] -%<plain>% Package memoizable 2023/10/10 v1.0.0 +%<plain>% Package memoizable 2024/01/02 v1.1.0 %</mmzable> %<*nommz> -%<latex>\ProvidesPackage{nomemoize}[2023/10/10 v1.0.0 A no-op stub for Memoize] +%<latex>\ProvidesPackage{nomemoize}[2024/1/02 v1.1.0 A no-op stub for Memoize] %<context>%D \module[ %<context>%D file=t-nomemoize.tex, -%<context>%D version=1.0.0, +%<context>%D version=1.1.0, %<context>%D title=Memoize, %<context>%D subtitle=A no-op stub for Memoize, %<context>%D author=Saso Zivanovic, -%<context>%D date=2023-10-10, +%<context>%D date=2024-01-02, %<context>%D copyright=Saso Zivanovic, %<context>%D license=LPPL, %<context>%D ] %<context>\writestatus{loading}{ConTeXt User Module / nomemoize} %<context>\unprotect %<context>\startmodule[nomemoize] -%<mmz>% Package nomemoize 2023/10/10 v1.0.0 +%<mmz>% Package nomemoize 2024/01/02 v1.1.0 %</nommz> % % \paragraph{Required packages} and \hologo{LaTeX}ization of \hologo{plainTeX} @@ -163,13 +158,6 @@ \def\newtoks{\alloc@5\toks\toksdef\@cclvi} \def\newwrite{\alloc@7\write\chardef\sixt@@n} %</mmz&plain> -% |Nomemoize| has to load |pgfopts| as well, and process package options (right -% away, why not), otherwise \hologo{LaTeX} will complain. -%<*latex> -%<mmz,nommz>\RequirePackage{pgfopts} % pgfkeys-based package options -%<nommz>\pgfkeys{/memoize/package options/.unknown/.code={}} -%<nommz>\ProcessPgfPackageOptions{/memoize/package options} -%</latex> % I can't really write any code without |etoolbox| \dots %<*mmz> %<latex>\RequirePackage{etoolbox} @@ -238,6 +226,7 @@ }% }% } +%</mmz> % % In \hologo{ConTeXt}, |\unexpanded| means |\protected|, and the usual % |\unexpanded| is available as |\normalunexpanded|. Option one: use dtx @@ -249,6 +238,18 @@ % |\unexpanded| in the |.dtx|, and |sed| through the generated \hologo{ConTeXt} % files to replace all its occurrences by |\normalunexpanded|. Oh yeah! % +% Load |pgfkeys| in |nomemoize| and |memoizable|. Not necessary in |memoize|, +% as it is already loaded by CollArgs. +%<*nommz,mmzable> +%<latex>\RequirePackage{pgfkeys} +%<plain>\input pgfkeys +%<context>\input t-pgfkey +%</nommz,mmzable> +% +% Different formats of |memoizable| merely load |memoizable.code.tex|, which +% exists so that |memoizable| can be easily loaded by generic code, like a +% |tikz| library. +%<mmzable&!generic>\input memoizable.code.tex % % \paragraph.{Shipout} % We will next load our own auxiliary package, CollArgs, but before we do @@ -260,6 +261,7 @@ % section~\ref{sec:code:extern}. Below, we first check that the current % meaning of |\shipout| is primitive, and then redefine it. % +%<*mmz> %<*plain> \def\mmz@regular@shipout{% \global\advance\mmzRegularPages1\relax @@ -284,7 +286,7 @@ % \paragraph.{Loading order} |memoize| and |nomemoize| are mutually exclusive, % and |memoizable| must be loaded before either of them. |\mmz@loadstatus|: 1 % = memoize, 2 = memoizable, 3 = nomemoize. -%<*(plain,context)&(mmz,nommz,mmzable)> +%<*mmz,nommz> \def\ifmmz@loadstatus#1{% \ifnum#1=0\csname mmz@loadstatus\endcsname\relax \expandafter\@firstoftwo @@ -292,11 +294,9 @@ \expandafter\@secondoftwo \fi } -%</(plain,context)&(mmz,nommz,mmzable)> +%</mmz,nommz> %<*mmz> -%<latex>\@ifpackageloaded{nomemoize}% -%<plain,context>\ifmmz@loadstatus{3}% -{% +\ifmmz@loadstatus{3}{% \PackageError{memoize}{Cannot load the package, as "nomemoize" is already loaded. Memoization will NOT be in effect}{Packages "memoize" and "nomemoize" are mutually exclusive, please load either one or the other.}% @@ -304,9 +304,7 @@ %<latex>\ProcessPgfPackageOptions{/memoize/package options} \endinput }{}% -%<latex>\@ifpackageloaded{memoizable}% -%<plain,context>\ifmmz@loadstatus{2}% -{% +\ifmmz@loadstatus{2}{% \PackageError{memoize}{Cannot load the package, as "memoizable" is already loaded}{Package "memoizable" is loaded by packages which support memoization. Memoize must be loaded before all such packages. The @@ -324,30 +322,20 @@ %<latex>\ProcessPgfPackageOptions{/memoize/package options} \endinput }{}% -%<plain,context>\ifmmz@loadstatus{1}{\endinput}{}% -%<plain,context>\def\mmz@loadstatus{1}% +\ifmmz@loadstatus{1}{\endinput}{}% +\def\mmz@loadstatus{1}% %</mmz> -%<*mmzable> -%<latex>\@ifpackageloaded{memoize}% -%<plain,context>\ifmmz@loadstatus{1}% -{\endinput}{} -%<latex>\@ifpackageloaded{nomemoize}% -%<plain,context>\ifmmz@loadstatus{3}% -{\endinput}{}% -%<plain,context>\ifmmz@loadstatus{2}{\endinput}{}% -%<plain,context>\def\mmz@loadstatus{2}% -%</mmzable> +%<*mmzable&generic> +\ifcsname mmz@loadstatus\endcsname\endinput\fi +\def\mmz@loadstatus{2}% +%</mmzable&generic> %<*nommz> -%<latex>\@ifpackageloaded{memoize} -%<plain,context>\ifmmz@loadstatus{1}% -{% +\ifmmz@loadstatus{1}{% \PackageError{nomemoize}{Cannot load the package, as "memoize" is already loaded; memoization will remain in effect}{Packages "memoize" and "nomemoize" are mutually exclusive, please load either one or the other.}% \endinput }{}% -%<latex>\@ifpackageloaded{memoizable}% -%<plain,context>\ifmmz@loadstatus{2}% -{% +\ifmmz@loadstatus{2}{% \PackageError{nomemoize}{Cannot load the package, as "memoizable" is already loaded}{Package "memoizable" is loaded by packages which support memoization. (No)Memoize must be loaded before all such packages. The @@ -363,8 +351,8 @@ of that package.}% \endinput }{}% -%<plain,context>\ifmmz@loadstatus{3}{\endinput}{}% -%<plain,context>\def\mmz@loadstatus{3}% +\ifmmz@loadstatus{3}{\endinput}{}% +\def\mmz@loadstatus{3}% %</nommz> % %<*mmz> @@ -373,7 +361,7 @@ % Read \hologo{TeX} file |#2| into token register |#1| (under the current % category code regime); |\toksapp| is defined in CollArgs. \def\filetotoks#1#2{% - \immediate\openin0{#2}% + \immediate\mmz@openin0{#2}% #1={}% \loop \unless\ifeof0 @@ -385,6 +373,12 @@ } % \end{macro} % +% \begin{macro}{\mmz@openin,\mmz@openout} +% A workaround for |morewrites|. +\let\mmz@openin\openin +\let\mmz@openout\openout +% \end{macro} +% % \paragraph{Other} little things. \newif\ifmmz@temp \newtoks\mmz@temptoks @@ -395,22 +389,24 @@ % \label{sec:code:configuration} % % \begin{macro}{\mmzset} -% The user primarily interacts with |Memoize| through the |pgfkeys|-based +% The user primarily interacts with Memoize through the |pgfkeys|-based % configuration macro |\mmzset|, which executes keys in path |/mmz|. In % |nomemoize| and |memoizable|, is exists as a no-op. \def\mmzset#1{\pgfqkeys{/mmz}{#1}\ignorespaces} %</mmz> -%<nommz,mmzable>\def\mmzset#1{\ignorespaces} +%<*nommz,mmzable&generic> +\def\mmzset#1{\ignorespaces} +%</nommz,mmzable&generic> % \end{macro} -% -% \begin{macro}{\mmzset} +% +% \begin{macro}{\nommzkeys} % Any |/mmz| keys used outside of |\mmzset| must be declared by this macro % for |nomemoize| package to work. %<mmz>\def\nommzkeys#1{} -%<*nommz,mmzable> +%<*nommz,mmzable&generic> \def\nommzkeys{\pgfqkeys{/mmz}} \pgfqkeys{/mmz}{.unknown/.code={\pgfkeysdef{\pgfkeyscurrentkey}{}}} -%</nommz,mmzable> +%</nommz,mmzable&generic> % \end{macro} % % \begin{key}{enable, disable} @@ -427,7 +423,9 @@ % % |Nomemoize| does not need the keys themselves, but it does need the % underlying conditional --- which will be always false. -%<mmz,nommz,mmzable>\newif\ifmemoize +%<*mmz,nommz,mmzable&generic> +\newif\ifmemoize +%</mmz,nommz,mmzable&generic> %<*mmz> \mmzset{% enable/.style={begindocument/.append code=\memoizetrue}, @@ -439,10 +437,15 @@ % Memoize is enabled at the beginning of the document, unless explicitly % disabled by the user in the preamble. enable, -} % \end{macro} % \end{key} % +% \begin{key}{options} +% Execute the given value as a keylist of Memoize settings. + options/.style={#1}, +} +% \end{key} +% % \begin{key}{normal,readonly,recompile} % When Memoize is enabled, it can be in one of three modes % (\MS\ref{sec:tut:working-on-a-picture}): normal, readonly, and recompile. @@ -461,7 +464,7 @@ } % \end{key} % -% \begin{key}{path, path/relative, path/dir, path/prefix} +% \begin{key}{prefix} % Key |path| executes the given keylist in path |/mmz/path|, to determine the % full \emph{path prefix} to memo and extern files % (\MS\ref{sec:tut:memodir},\ref{sec:memos}): |relative|, true by default, @@ -471,56 +474,77 @@ % under user control, and neither is the suffix. These subkeys will be % initialized a bit later, via |no memo dir|. \mmzset{% - path/.code={\pgfqkeys{/mmz/path}{#1}}, - path/.cd, - relative/.is if=mmz@relativepath, - dir/.store in=\mmz@dir, - dir/.value required, - prefix/.store in=\mmz@prefix, - prefix/.value required, -} -\newif\ifmmz@relativepath -% Key |path| concludes by performing two post-path-setting actions: creating -% the given directory if |mkdir| is in effect, and noting the new path prefix -% in record files (by eventually executing |record/prefix|, which typically -% puts a |\mmzPrefix| line in the |.mmz| file). These actions are the reason -% for having the path setting keys grouped under |path| --- we don't want them -% to be triggered by changes of the individual components of the path. -% Similarly, we don't want them triggered by multiple invocations of |path| in -% the preamble; only the final setting matters, so |path| is only equipped with -% the action-triggering code at the beginning of the document. + prefix/.code={\mmz@parse@prefix{#1}}, +} +% \begin{macro}{\mmz@split@prefix} +% This macro stores the detokenized expansion of |#1| into |\mmz@prefix|, +% which it then splits into |\mmz@prefix@dir| and |\mmz@prefix@name| at the +% final |/|. The slash goes into |\mmz@prefix@dir|. If there is no slash, +% |\mmz@prefix@dir| is empty. +\begingroup +\catcode`\/=12 +\gdef\mmz@parse@prefix#1{% + \edef\mmz@prefix{\detokenize\expandafter{\expanded{#1}}}% + \def\mmz@prefix@dir{}% + \def\mmz@prefix@name{}% + \expandafter\mmz@parse@prefix@i\mmz@prefix/\mmz@eov +} +\gdef\mmz@parse@prefix@i#1/#2{% + \ifx\mmzeov#2% + \def\mmz@prefix@name{#1}% + \else + \appto\mmz@prefix@dir{#1/}% + \expandafter\mmz@parse@prefix@i\expandafter#2% + \fi +} +\endgroup +% \end{macro} +% +% Key |prefix| concludes by performing two actions: it creates the given +% directory if |mkdir| is in effect, and notes the new prefix in record files +% (by eventually executing |record/prefix|, which typically puts a |\mmzPrefix| +% line in the |.mmz| file). In the preamble, only the final setting of +% |prefix| matters, so this key is only equipped with the action-triggering +% code at the beginning of the document. \mmzset{% begindocument/.append style={ - path/.append code=\mmz@maybe@mkmemodir\mmz@record@prefix, + prefix/.append code=\mmz@maybe@mkmemodir\mmz@record@prefix, }, - % Consequently, the post-path-setting actions must be triggered manually at + % Consequently, the post-prefix-setting actions must be triggered manually at % the beginning of the document. Below, we trigger directory creation; % |record/prefix| will be called from |record/begin|, which is executed at % the beginning of the document, so it shouldn't be mentioned here. begindocument/.append code=\mmz@maybe@mkmemodir, } -% Define the paths to the memo directory and the prefix. -\def\mmz@dir@path{\ifmmz@relativepath.\fi/\mmz@dir} -\def\mmz@prefix@path{\mmz@dir@path/\mmz@prefix} % \end{key} % % \begin{key}{mkdir, mkdir command} % Should we create the memo/extern directory if it doesn't exist? And which -% command should we use to create it? Of course, shell escape must be -% properly configured for this to work (\MS\ref{sec:shell-escape}). -% ^^A todo: What about quoting the paths containing spaces on Windows? Will this work? +% command should we use to create it? There is no initial value for the +% latter, because |mkdir| cannot be executed out of the box, but note that +% |extract=perl| and |extract=python| will set the extraction script with +% option |--mkdir| as the value of |mkdir command|. \mmzset{ mkdir/.is if=mmz@mkdir, - mkdir command/.code={\def\mmz@mkdir@command##1{#1}}, - mkdir command={mkdir "#1"}, + mkdir command/.store in=\mmz@mkdir@command, + mkdir command={}, } % The underlying conditional \cs{ifmmz@mkdir} is only ever used in % |\mmz@maybe@mkmemodir| below, which is itself only executed at the end of -% |path| and in |begindocument|. +% |prefix| and in |begindocument|. \newif\ifmmz@mkdir +\mmz@mkdirtrue +% We only attempt to create the memo directory if |\ifmmz@mkdir| is in effect +% and if both |\mmz@mkdir@command| and |\mmz@prefix@dir| are specified (i.e.\ +% non-empty). \def\mmz@maybe@mkmemodir{% \ifmmz@mkdir - \pdf@system{\mmz@mkdir@command{\mmzOutputDirectory\mmz@dir@path}}% + \ifdefempty\mmz@mkdir@command{}{% + \ifdefempty\mmz@prefix@dir{}{% + \mmz@remove@quotes{\mmz@prefix@dir}\mmz@temp + \pdf@system{\mmz@mkdir@command\space"\mmz@temp"}% + }% + }% \fi } % \end{key} @@ -533,51 +557,49 @@ % filenames themselves have no prefix. Furthermore, |memo dir| triggers the % creation of the directory. \mmzset{% - memo dir/.style={ - mkdir, - path={ - relative, - dir={#1.memo.dir}, - prefix={}, - }, - }, - memo dir/.default=\mmzUnquote\jobname, - no memo dir/.style={ - mkdir=false, - path={ - relative, - dir={}, - prefix={#1.}, - }, - }, - no memo dir/.default=\mmzUnquote\jobname, + memo dir/.style={prefix={#1.memo.dir/}}, + memo dir/.default=\jobname, + no memo dir/.style={prefix={#1.}}, + no memo dir/.default=\jobname, no memo dir, } % \end{key} % -% \begin{macro}{\mmzUnquote} -% If the expanded argument is surrounded by double quotes, remove them. This -% relies on |#1| containing no quotes other than the potential surrounding -% quotes, which should be the case when applying the macro to |\jobname|. An -% empty |#1| is dealt with correctly, even if |\jobname| can hardly ever be -% empty (needs |openout_any=a|). +% \begin{macro}{\mmz@remove@quotes} +% This macro removes fully expands |#1|, detokenizes the expansion and then +% removes all double quotes the string. The result is stored in the control +% sequence given in |#2|. % % We use this macro when we are passing a filename constructed from % |\jobname| to external programs. -\def\mmzUnquote#1{\expanded{\noexpand\mmz@unquote#1}\mmz@unquote@end} -\def\mmz@unquote#1{% - \ifx\mmz@unquote@end#1% +\def\mmz@remove@quotes#1#2{% + \def\mmz@remove@quotes@end{\let#2\mmz@temp}% + \def\mmz@temp{}% + \expanded{% + \noexpand\mmz@remove@quotes@i + \detokenize\expandafter{\expanded{#1}}% + "\noexpand\mmz@eov + }% +} +\def\mmz@remove@quotes@i{% + \CollectArgumentsRaw + {\collargsBraceCollectedfalse + \collargsNoDelimiterstrue + \collargsAppendPostwrap{{##1}}% + }% + {u"u\mmz@eov}% + \mmz@remove@quotes@ii +} +\def\mmz@remove@quotes@ii#1#2{% + \appto\mmz@temp{#1}% + \ifx&% + \mmz@remove@quotes@end + \expandafter\@gobble \else - \ifx"#1% - \expandafter\expandafter\expandafter\mmz@unquote@quotes - \else - \expandafter\expandafter\expandafter\mmz@unquote@noquotes - \expandafter\expandafter\expandafter#1% - \fi + \expandafter\@firstofone \fi + {\mmz@remove@quotes@i#2\mmz@eov}% } -\def\mmz@unquote@quotes#1"\mmz@unquote@end{#1} -\def\mmz@unquote@noquotes#1\mmz@unquote@end{#1} % \end{macro} % % \begin{key}{ignore spaces} @@ -832,6 +854,7 @@ %<context>\let\startmemoize\startnomemoize %<context>\let\stopmemoize\stopnomemoize %</nommz> +%</mmz,nommz> % \end{environment} % % \subsection{The memoization process} @@ -843,6 +866,7 @@ % anywhere else. It is checked by |\Memoize| to prevent nested % memoizations, deployed in advice run conditions set by |run only if % memoizing|, etc. +%<*mmz,nommz,mmzable&generic> \newif\ifmemoizing % \end{macro} % @@ -859,7 +883,7 @@ % An auxiliary macro which rescans the given % code using |\scantokens| if the verbatim mode is active. We also need it % in NoMemoize, to properly grab verbatim manually memoized code. -%</mmz,nommz> +%</mmz,nommz,mmzable&generic> %<*mmz> \def\mmz@maybe@scantokens{% \ifmmz@verbatim @@ -1091,15 +1115,16 @@ \gtoksapp\mmzCMemo{\global\mmzUnmemoizabletrue}% \mmz@write@cmemo \mmz@trace@endmemoize@unmemoizable - \PackageWarning{memoize}{Marking this code as unmemoizable}% + \PackageInfo{memoize}{Marking this code as unmemoizable}% \else \ifmmz@abort % If memoization was aborted, we create an empty c-memo, to make sure that % no leftover c-memo tricks Memoize into thinking that the code was % successfully memoized. \mmz@trace@endmemoize@aborted - \PackageWarning{memoize}{Memoization was aborted}% - \mmz@write@empty@cmemo + \PackageInfo{memoize}{Memoization was aborted}% + \mmz@compute@context@mdfivesum + \mmz@write@cmemo \else % If memoization was not aborted, we compute the \meta{context md5sum}, % open and write out the memos, and shipout the externs (as pages into the @@ -1320,7 +1345,7 @@ % % \paragraph.{Tracing} We populate the hooks which send the tracing info to the % terminal. -\def\mmz@trace#1{\immediate\write16{[tracing memoize] #1}} +\def\mmz@trace#1{\advice@typeout{[tracing memoize] #1}} \def\mmz@trace@context{\mmz@trace{\space\space Context: "\expandonce{\mmz@context@key}" --> \mmz@context@mdfivesum}} \def\mmz@trace@Memoize@on{% @@ -1424,9 +1449,6 @@ % \end{macro} % \end{key} % -%</mmz> -%<nommz,mmzable>\newcommand\IfMemoizing[2][]{\@secondoftwo} -%<*mmz> % % \subsection{Context} % \label{sec:code:context} @@ -1465,24 +1487,27 @@ % context, key value to context, /handlers/.meaning to context, % /handlers/.value to context} % Utilities to put the meaning of various stuff into |context|. + % \indentmacrocode meaning to context/.code={\forcsvlist\mmz@mtoc{#1}}, - csname meaning to context/.code={\mmz@mtoc@cs{#1}}, - key meaning to context/.code={\forcsvlist\mmz@mtoc\mmz@mtoc@keycmd{#1}}, + csname meaning to context/.code={\mmz@mtoc@csname{#1}}, + key meaning to context/.code={% + \forcsvlist\mmz@mtoc\mmz@mtoc@keycmd{#1}}, key value to context/.code={\forcsvlist\mmz@mtoc@key{#1}}, - /handlers/.meaning to context/.code={% - \expanded{\noexpand\mmz@mtoc@cs{pgfk@\pgfkeyscurrentpath/.@cmd}}}, + /handlers/.meaning to context/.code={\expanded{% + \noexpand\mmz@mtoc@csname{pgfk@\pgfkeyscurrentpath/.@cmd}}}, /handlers/.value to context/.code={% - \expanded{\noexpand\mmz@mtoc@cs{pgfk@\pgfkeyscurrentpath}}}, + \expanded{\noexpand\mmz@mtoc@csname{pgfk@\pgfkeyscurrentpath}}}, } +% \noindentmacrocode \def\mmz@mtoc#1{% \collargs@cs@cases{#1}% {\mmz@mtoc@cmd{#1}}% {\mmz@mtoc@error@notcsorenv{#1}}% {% - \mmz@mtoc@cs{% + \mmz@mtoc@csname{% %<context>start% #1}% - \mmz@mtoc@cs{% + \mmz@mtoc@csname{% %<latex,plain>end% %<context>stop% #1}% @@ -1492,17 +1517,18 @@ \begingroup \escapechar=-1 \expandafter\endgroup - \expandafter\mmz@mtoc@cs\expandafter{\string#1}% + \expandafter\mmz@mtoc@csname\expandafter{\string#1}% } -\def\mmz@mtoc@cs#1{% +\def\mmz@mtoc@csname#1{% \pgfkeysvalueof{/mmz/context/.@cmd}% - \expandafter\string\csname#1\endcsname={\expandafter\meaning\csname#1\endcsname}% - \pgfeov + \detokenize{#1}={\expandafter\meaning\csname#1\endcsname}% + \pgfeov } -\def\mmz@mtoc@key#1{\mmz@mtoc@cs{pgfk@#1}} -\def\mmz@mtoc@key#1{\mmz@mtoc@cs{pgfk@#1/.@cmd}} +\def\mmz@mtoc@key#1{\mmz@mtoc@csname{pgfk@#1}} +\def\mmz@mtoc@keycmd#1{\mmz@mtoc@csname{pgfk@#1/.@cmd}} \def\mmz@mtoc@error@notcsorenv#1{% - \PackageError{memoize}{'\detokenize{#1}' passed to key 'meaning to context' is neither a command nor an environment}{}% + \PackageError{memoize}{'\detokenize{#1}' passed to key 'meaning to context' + is neither a command nor an environment}{}% } % \end{key} % @@ -1512,7 +1538,7 @@ % % \paragraph{The path} to a c-memo consists of the path prefix, the MD5 sum of % the memoized code, and suffix |.memo|. -\def\mmz@cmemo@path{\mmz@prefix@path\mmz@code@mdfivesum.memo} +\def\mmz@cmemo@path{\mmz@prefix\mmz@code@mdfivesum.memo} % \begin{macro}{\mmzCMemo} % The additional, free-form content of the c-memo is collected in this token % register. @@ -1536,7 +1562,7 @@ % |\mmzCMemo|. \def\mmz@write@cmemo{% % Open the file for writing. - \immediate\openout\mmz@out{\mmz@cmemo@path}% + \immediate\mmz@openout\mmz@out{\mmz@cmemo@path}% % The memo starts with the |\mmzMemo| marker (a signal that the memo is valid). \immediate\write\mmz@out{\noexpand\mmzMemo}% % We store the content of |\mmzContextExtra| by writing out a command that @@ -1559,17 +1585,6 @@ } % \end{macro} % -% \begin{macro}{\mmz@write@empty@cmemo} -% This macro is used to create an empty c-memo on aborted memoization, to -% make sure that no leftover c-memo tricks Memoize into thinking that the -% code was successfully memoized. -\def\mmz@write@empty@cmemo{% - \immediate\openout\mmz@out{\mmz@cmemo@path}% - \immediate\closeout\mmz@out -} -% \end{macro} -% -% % \begin{macro}{\mmzSource} % The c-memo memoized code marker. This macro is synonymous with |\endinput|, % so the source following it is ignored when inputting the c-memo. @@ -1644,7 +1659,7 @@ % hyphen-separated MD5 sums of the memoized code and the (evaluated) context, % and suffix |.memo|. \def\mmz@ccmemo@path{% - \mmz@prefix@path\mmz@code@mdfivesum-\mmz@context@mdfivesum.memo} + \mmz@prefix\mmz@code@mdfivesum-\mmz@context@mdfivesum.memo} % % \paragraph{The structure} of a cc-memo: % \begin{itemize} @@ -1699,7 +1714,7 @@ % memoized code can update the context. This is one of the two reasons why % we couldn't write the cc-memo directly into the file, but had to collect % its contents into token register |\mmzCCMemo|. - \immediate\openout\mmz@out{\mmz@ccmemo@path}% + \immediate\mmz@openout\mmz@out{\mmz@ccmemo@path}% % Token register |\mmz@ccmemo@resources| consists of calls to % |\mmz@ccmemo@append@resource|, so the following code writes down the list % of created externs into the cc-memo. Wanting to have this list at the top @@ -1751,7 +1766,7 @@ % might be produced by a failed \hologo{TeX}-based extraction, should count % as no file. The |0| behind |\ifnum| is there because |\pdffilesize| % returns an empty string when the file does not exist. - \ifnum0\pdf@filesize{\mmz@dir@path/#1}=0 + \ifnum0\pdf@filesize{\mmz@prefix@dir/#1}=0 \ifmmz@direct@ccmemo@input \let\mmzMemo\endinput \else @@ -1768,8 +1783,10 @@ % % \begin{macro}{\mmz@process@ccmemo,\mmzThisContext,\mmzEndMemo} % This macro processes the cc-memo. +% \indentmacrocode \def\mmz@process@ccmemo{% \mmz@trace@process@ccmemo + % \noindentmacrocode % The following conditional signals whether cc-memo was successfully % utilized. If the cc-memo file does not exist, |\ifmmz@abort| will remain % true. If it exists, it is headed by the list of resources. If a @@ -1865,11 +1882,11 @@ % full path. \newcount\mmz@seq \def\mmz@extern@basename{% - \mmz@prefix\mmz@code@mdfivesum-\mmz@context@mdfivesum + \mmz@prefix@name\mmz@code@mdfivesum-\mmz@context@mdfivesum \ifnum\mmz@seq>0 -\the\mmz@seq\fi } \def\mmz@extern@name{\mmz@extern@basename.pdf} -\def\mmz@extern@basepath{\mmz@dir@path/\mmz@extern@basename} +\def\mmz@extern@basepath{\mmz@prefix@dir\mmz@extern@basename} \def\mmz@extern@path{\mmz@extern@basepath.pdf} % % \begin{key}{padding left, padding right, padding top, padding bottom} @@ -2124,12 +2141,14 @@ % |\mmzExternPages| holds the number of shipped-out extern pages; and % |\mmzExtraPages| holds, or at least should hold, the number of pages % shipped out using any other means. - \edef\pagenumber{\the\numexpr\mmzRegularPages + \edef\pagenumber{% + \the\numexpr\mmzRegularPages % In \hologo{LaTeX}, the |\mmzRegularPages| holds to number of pages % already shipped out. In \hologo{ConTeXt}, the counter is already % increased while processing the page, so we need to subtract $1$. %<context> -1% - +\mmzExternPages+\mmzExtraPages}% + +\mmzExternPages+\mmzExtraPages + }% % Record the creation of the new extern. We do this after shipping out the % extern page, so that the recording mechanism can serve as an after-shipout % hook, for the unlikely situation that some package really needs to do @@ -2212,7 +2231,7 @@ enddocument/afterlastpage/.append code={% \ifnum\mmzExternPages>0 \PackageWarning{memoize}{The compilation produced \the\mmzExternPages\space - new extern\ifnum\mmzExternPages>1 s\fi.}% + new extern\ifnum\mmzExternPages>1 s\fi}% \fi }, } @@ -2304,13 +2323,13 @@ % % \begin{macro}{\mmz@include@extern@from@tbe@box} % Include the extern number |#1| residing in |\mmz@tbe@box| into the -% document. This helper macro makes it possible for a complex memoization -% driver to process the cc-memo right after memoization --- by using the -% |\mmzkeepexternstrue\xtoksapp\mmzAfterMemoizationExtra{\the\mmzCCMemo}| -% trick --- to ensure that the result of the memoizing compilation matches -% the result of inputting the cc-memo. The rest of the arguments are -% gobbled, as we don't have to do any size adjustment or checking here, and -% the box is of the correct type. +% document. It may be called as |\mmzIncludeExtern| from |after memoization| +% hook if |\ifmmzkeepexterns| was set to true during memoization. The macro +% takes the same arguments as |\mmzIncludeExtern| but disregards all but +% the first one, the extern sequential number. Using this macro, a complex +% memoization driver can process the cc-memo right after memoization, by +% issuing +% |\global\mmzkeepexternstrue\xtoksapp\mmzAfterMemoizationExtra{\the\mmzCCMemo}|. \def\mmz@include@extern@from@tbe@box#1#2#3#4#5#6#7#8#9{% \setbox0\vbox{% \@tempcnta#1\relax @@ -2344,7 +2363,7 @@ \mmzset{ extract/.estore in=\mmz@extraction@method, extract/.value required, - begindocument/.append style={extract/.code=\mmz@preamble@only@warning}, + begindocument/.append style={extract/.code=\mmz@preamble@only@error}, % \end{key} % % \begin{key}{extract/perl, extract/python} @@ -2352,10 +2371,10 @@ % Memoize ships with two extraction scripts, a Perl script and a Python % script, which are selected by |extract=perl| (the default) and % |extract=python|, respectively. We run the scripts in verbose mode - % (without |-q|), and keep the |.mmz| file as is, i.e.\ we're not commenting - % out the |\mmzNewExtern| lines, because we're about to overwrite it - % anyway. We also request the log file, which will contain - % |\mmzExtractionSuccessful| if extraction was successful. + % (without |-q|), and keep the |.mmz| file as is (without |-k|), i.e.\ + % we're not commenting out the |\mmzNewExtern| lines, because we're about + % to overwrite it anyway. We inform the script about the format of the + % document (|-F|). extract/perl/.code={% \mmz@clear@extraction@log \pdf@system{% @@ -2363,17 +2382,14 @@ \mmzvalueof{perl extraction options}% }% \mmz@check@extraction@log{perl}% - \def\mmz@mkdir@command##1{\mmzvalueof{perl extraction command}\space --mkdir "##1"}% + \def\mmz@mkdir@command{\mmzvalueof{perl extraction command} --mkdir}% }, perl extraction command/.initial=memoize-extract.pl, - perl extraction options/.initial={% -% \begin{listingregion}{perl-extraction-options.tex} - -e -l "\mmzOutputDirectory\mmzUnquote\jobname.mmz.log" -w - %<latex>"\string\PackageWarning{memoize (perl-based extraction)}{\string\warningtext}" - %<plain>"\string\warning{memoize (perl-based extraction): \string\warningtext}" - %<context>"\string\warning{memoize (perl-based extraction): \string\warningtext}" - "\mmzOutputDirectory\mmzUnquote\jobname.mmz" -% \end{listingregion} + perl extraction options/.initial={\space + %<latex>-F latex + %<plain>-F plain + %<context>-F context + \jobname\space }, extract=perl, extract/python/.code={% @@ -2383,21 +2399,20 @@ \mmzvalueof{python extraction options}% }% \mmz@check@extraction@log{python}% - \def\mmz@mkdir@command##1{\mmzvalueof{python extraction command}\space --mkdir "##1"}% + \def\mmz@mkdir@command{\mmzvalueof{python extraction command} --mkdir}% }, python extraction command/.initial=memoize-extract.py, - python extraction options/.initial={% - -e -l "\mmzOutputDirectory\mmzUnquote\jobname.mmz.log" -w - %<latex>"\string\PackageWarning{memoize (python-based extraction)}{\string\warningtext}" - %<plain>"\string\warning{memoize (python-based extraction): \string\warningtext}" - %<context>"\string\warning{memoize (python-based extraction): \string\warningtext}" - "\mmzOutputDirectory\mmzUnquote\jobname.mmz" + python extraction options/.initial={\space + %<latex>-F latex + %<plain>-F plain + %<context>-F context + \jobname\space }, } -\def\mmz@preamble@only@warning{% - \PackageWarning{memoize}{% +\def\mmz@preamble@only@error{% + \PackageError{memoize}{% Ignoring the invocation of "\pgfkeyscurrentkey". - This key may only be executed in the preamble}% + This key may only be executed in the preamble}{}% } % \end{key} % @@ -2406,15 +2421,14 @@ % communicate with the system command via the ``extraction log file,'' produced % by both \hologo{TeX}-based extraction and the Perl and Python extraction % script. This file signals whether the embedded extraction was successful --- -% if it is, the file contains |\mmzExtractionSuccessful| --- and also contains -% any size-mismatch warnings (these are currently only thrown by the -% \hologo{TeX}-based extraction). As the log is really a \hologo{TeX} file, -% the idea is to simply input it after extracting each extern (for +% if it is, the file ends if |\endinput| --- and also contains any warnings and +% errors thrown by the script. As the log is really a \hologo{TeX} file, the +% idea is to simply input it after extracting each extern (for % \hologo{TeX}-based extraction) or after the extraction of all externs (for % the external scripts). \def\mmz@clear@extraction@log{% \begingroup - \immediate\openout0{\mmzUnquote\jobname.mmz.log"}% + \immediate\mmz@openout0{\jobname.mmz.log}% \immediate\closeout0 \endgroup } @@ -2426,9 +2440,11 @@ \@input{\jobname.mmz.log}% \ifmmz@temp \else \mmz@extraction@error \fi \endgroup } \def\mmz@extraction@error{% - \PackageWarning{memoize}{Extraction of externs from document "\mmzUnquote\jobname.pdf" - using method "\extractionmethod" was unsuccessful. Have you set the - shell escape mode as suggested in chapter 1 of the manual?}{}} + \PackageError{memoize}{Extraction of externs from document + "\jobname.pdf" using method "\extractionmethod" was + unsuccessful}{The extraction script "\mmzvalueof{\extractionmethod\space + extraction command}" wasn't executed or didn't finish execution + properly.}} % % \subsection{The record files} % \label{sec:code:record} @@ -2451,7 +2467,7 @@ % surely occurs at the top of the |.mmz| file. Listing each prefix type % separately in this hook ensures that |prefix| of a certain type is % executed after that type's |begin|. - /mmz/record/#1/prefix/.try/.expanded=\mmz@prefix@path, + /mmz/record/#1/prefix/.try/.expanded=\mmz@prefix, }, record/prefix/.append style={/mmz/record/#1/prefix/.try={##1}}, record/new extern/.append style={/mmz/record/#1/new extern/.try={##1}}, @@ -2495,7 +2511,7 @@ % We define this macro because |\aftergroup|, used in |record/prefix|, only % accepts a token. \def\mmz@record@prefix{% - \mmzset{/mmz/record/prefix/.expanded=\mmz@prefix@path}% + \mmzset{/mmz/record/prefix/.expanded=\mmz@prefix}% } % \paragraph{Initialize} the hook keys, preactivate |mmz| record type, and % execute hooks |begin| and |end| at the edges of the document. @@ -2516,12 +2532,11 @@ % contains are intentionally as simple as possible (just a macro plus braced % arguments), to facilitate parsing by the external scripts. % -% These hooks simply put the calls of the corresponding macros into the file. -% All but hooks but |begin| and |end| receive the full path to the relevant -% file as the only argument (ok, |prefix| receives the full path prefix, as set -% by key |path|). -% % \begin{key}{record/mmz/...} +% These hooks simply put the calls of the corresponding macros into the file. +% All but hooks but |begin| and |end| receive the full path to the relevant +% file as the only argument (ok, |prefix| receives the full path prefix, as +% set by key |path|). \mmzset{ record/mmz/begin/.code={% \newwrite\mmz@mmzout @@ -2529,7 +2544,7 @@ % location (the current directory, i.e.\ the directory where \hologo{TeX} % is executed from; usually, this will be the directory containing the % \hologo{TeX} source). - \immediate\openout\mmz@mmzout{\jobname.mmz}% + \immediate\mmz@openout\mmz@mmzout{\jobname.mmz}% }, % The |\mmzPrefix| is used by the clean-up script, which will remove all % files with the given path prefix but (unless called with |--all|) those @@ -2592,7 +2607,7 @@ % \begin{key}{record/sh/...} Define the Linux shell script record type. record/sh/begin/.code={% \newwrite\mmz@shout - \immediate\openout\mmz@shout{\mmz@shname}% + \immediate\mmz@openout\mmz@shout{\mmz@shname}% }, record/sh/new extern/.code={% \begingroup @@ -2611,7 +2626,7 @@ % Rinse and repeat for Windows. record/bat/begin/.code={% \newwrite\mmz@batout - \immediate\openout\mmz@batout{\mmz@batname}% + \immediate\mmz@openout\mmz@batout{\mmz@batname}% }, record/bat/new extern/.code={% \begingroup @@ -2649,7 +2664,7 @@ % variables |.DEFAULT_GOAL| and |.PHONY|. \newwrite\mmz@makefileout \newtoks\mmz@makefile@externs - \immediate\openout\mmz@makefileout{\mmz@makefilename}% + \immediate\mmz@openout\mmz@makefileout{\mmz@makefilename}% \immediate\write\mmz@makefileout{.DEFAULT_GOAL = externs}% \immediate\write\mmz@makefileout{.PHONY: externs}% }, @@ -2693,11 +2708,10 @@ } % \end{key} % -% \begingroup -% \setlength\MacroIndent{2em} % \begin{macro}{\mmzUsedCMemo,\mmzUsedCCMemo,\mmzUsedExtern,\mmzNewCMemo,\mmzNewCCMemo,\mmzPrefix} % We can ignore everything but |\mmzNewExtern|s. All these macros receive a % single argument. +% \indentmacrocode \def\mmzUsedCMemo#1{} \def\mmzUsedCCMemo#1{} \def\mmzUsedExtern#1{} @@ -2705,7 +2719,6 @@ \def\mmzNewCCMemo#1{} \def\mmzPrefix#1{} % \end{macro} -% \endgroup % % \begin{macro}{\mmzNewExtern} % Command |\mmzNewExtern| takes four arguments. It instructs us to extract @@ -2744,11 +2757,11 @@ % \end{macro} \def\mmz@pageextraction@error{% \PackageError{memoize}{Extraction of extern page \pagenumber\space from - document "\mmzUnquote\jobname.pdf" using method "\extractionmethod" was unsuccessful. - Have you set the shell escape mode as suggested in chapter 1 of the - manual?}{If "\mmzvalueof{tex extraction command}" was executed, - shell escape mode is not the problem, and inspecting "\externbasepath.log" - might give you a clue what's wrong}} + document "jobname.pdf" using method "\extractionmethod" was + unsuccessful.}{Check the log file to see if the extraction script was + executed at all, and if it finished successfully. You might also want to + inspect "\externbasepath.log", the log file of the embedded TeX compilation + which ran the extraction script}} % % \begin{key}{tex extraction command, tex extraction options, tex extraction script} % Using these keys, we set the system call @@ -2786,12 +2799,11 @@ -halt-on-error -interaction=batchmode -jobname "\externbasepath" - \ifdefempty\mmzOutputDirectory{}{-output-directory "\mmzOutputDirectory"} % \end{listingregion} }, tex extraction script/.initial={% % \begin{listingregion}{tex-extraction-script.tex} ^^A todo: context - \def\noexpand\fromdocument{"\mmzOutputDirectory"\jobname.pdf}% + \def\noexpand\fromdocument{\jobname.pdf}% \def\noexpand\pagenumber{\pagenumber}% \def\noexpand\expectedwidth{\expectedwidth}% \def\noexpand\expectedheight{\expectedheight}% @@ -3008,6 +3020,7 @@ %<plain,context>noop/.style={inner handler=\mmz@auto@noop}, nomemoize/.style={noop, options=disable}, replicate/.style={run if memoizing, inner handler=\mmz@auto@replicate}, + to context/.style={run if memoizing, outer handler=\mmz@auto@tocontext}, } % % \paragraph{Abortion} @@ -3221,6 +3234,27 @@ } % \end{macro} % \end{mmzautokey} +% +% \begin{mmzautokey}{to context} +% \begin{macro}{\mmz@auto@tocontext} +% This outer handler appends the original definition of the handled command +% to the context. The |\expandafter| are there to expand |\AdviceName| +% once before fully expanding |\AdviceGetOriginalCsname|. +\def\mmz@auto@tocontext{% + \expanded{% + \noexpand\pgfkeysvalueof{/mmz/context/.@cmd}% + original "\AdviceNamespace" csname "\AdviceCsname"={% + \noexpand\expanded{% + \noexpand\noexpand\noexpand\meaning + \noexpand\AdviceCsnameGetOriginal{\AdviceNamespace}{\AdviceCsname}% + }% + }% + }% + \pgfeov + \AdviceOriginal +} +% \end{macro} +% \end{mmzautokey} % % \subsection{\hologo{LaTeX}-specific handlers} % @@ -3277,12 +3311,7 @@ % appends the reference key to the context. |\mmzNoRef| only does that if % the reference is defined, otherwise it aborts the memoization. \def\mmzForceNoRef#1{% - \ifmemoizing - \expandafter\gtoksapp\expandafter\mmzContextExtra - \else - \expandafter\toksapp\expandafter\mmzContext - \fi - {r@#1={\csname r@#1\endcsname}}% + \mmz@mtoc@csname{r@#1}% \ignorespaces } \def\mmzNoRef#1{% @@ -3360,11 +3389,17 @@ \endgroup } %</latex> -%</mmz> % % \end{macro} % % \section{Support for various classes and packages} +% +%<*latex> +\AddToHook{shipout/before}[memoize]{\global\advance\mmzExtraPages-1\relax} +\AddToHook{shipout/after}[memoize]{\global\advance\mmzExtraPages1\relax} +\mmzset{auto=\DiscardShipoutBox{ + outer handler=\global\advance\mmzExtraPages1\relax\AdviceOriginal}} +%</latex> % % \subsection{\TikZ;} % \label{sec:code:mmz:tikz} @@ -3373,7 +3408,6 @@ % Advice). All the action happens at the end of the preamble, so that we can % detect whether \TikZ; was loaded (regardless of whether Memoize was loaded % before \TikZ;, or vice versa), but still input the definitions. -%<*mmz> \mmzset{ begindocument/before/.append code={% %<latex>\@ifpackageloaded{tikz}{% @@ -3384,32 +3418,23 @@ % We define and activate the automemoization handlers for the \TikZ; command % and environment. \mmzset{% - % \begin{listingregion}{_auto-tikz-collector.tex} - auto=\tikz{memoize, collector=\AdviceCollectTikZArguments}, - % \end{listingregion} - %/utils/exec={\tracingall}, - auto={tikzpicture}{memoize}, - % A hack to prevent memoizing pictures which are accidentally marked as - % remembered --- accidentally in the sense that because the document - % changed, the |.aux| file contains a |\pgfsyspdfmark| command which - % erroneously refers to the picture being memoized. We know that - % memoizing a remembered picture can't be right, as we always abort on - % |\pdfsavepos|. This is implemented by hacking into PGF's - % |\pgfsys@getposition|, and aborting memoization if the mark does not - % equal |\relax|. (We have to duplicate |#| because of |.append code|.) - auto=\pgfsys@getposition{ - run if memoizing, outer handler=\mmz@pgfsys@getposition}, - }% - \def\mmz@pgfsys@getposition##1{% - \expandafter\ifx\csname pgf@sys@pdf@mark@pos@##1\endcsname\relax - \else - \mmzAbort - \fi - \AdviceOriginal{##1}% + auto/memoize tikz/.style={ + memoize, + at begin memoization=\edef\mmz@pgfpictureid{% + \the\pgf@picture@serial@count + }, + at end memoization=\xtoksapp\mmzCCMemo{% + \unexpanded{% + \global\expandafter\advance\csname pgf@picture@serial@count\endcsname + }% + \the\numexpr\pgf@picture@serial@count-\mmz@pgfpictureid\relax\relax + }, + }, + auto=\tikz{memoize tikz, collector=\AdviceCollectTikZArguments}, + auto={tikzpicture}{memoize tikz}, }% }, } -%</mmz> % % % \subsection{Forest} @@ -3417,7 +3442,6 @@ % % Forest will soon feature extensive memoization support, but for now, let's % just enable the basic, single extern externalization. -%<*mmz> %<*latex> \mmzset{ begindocument/before/.append code={% @@ -3478,6 +3502,98 @@ }{}} %</latex> % +% \subsection{Morewrites} +% \label{sec:code:morewrites} +% +% Use the old grammar for |\openin| and |\openout| as a temporary workaround. +% |prefix|es containing spaces must be quoted manually. +%<*latex> +\AddToHook{begindocument/before}{% + \@ifpackageloaded{morewrites}{% + \def\mmz@openin#1#2{\openin#1=#2\relax}% + \def\mmz@openout#1#2{\openout#1=#2\relax}% + }{}% +} +%</latex> +% +% \subsection{Biblatex} +% \label{sec:biblatex} +% +%<*latex> +\mmzset{ + begindocument/before/.append style={% + auto=\blx@bbl@entry{outer handler=\mmz@biblatex@entry}, + auto/cite/.style={run if memoizing, outer handler=\mmz@biblatex@cite}, + auto/cites/.style={run if memoizing, outer handler=\mmz@biblatex@cites}, + auto=\cite{cite}, + auto=\cites{cites}, + }% +} +% \begin{macro}{\mmz@biblatex@entry} +% This macro stores the MD5 sum of the |\entry| when reading the |.bbl| file. +\def\mmz@biblatex@entry#1#2\endentry{% + \csxdef{mmz@bbl@#1}{\pdf@mdfivesum{#2}}% + \AdviceOriginal{#1}#2\endentry +} +% \end{macro} +% \begin{macro}{\mmz@biblatex@cite} +% This macro puts the cites reference keys into the context, and adds the +% handled |\cite| command to the cc-memo. +\def\mmz@biblatex@cite#1#{\mmz@biblatex@cite@i{#1}} +\def\mmz@biblatex@cite@i#1#2{% + \forcsvlist\mmz@biblatex@cite@do@key{#2}% + \xtoksapp\mmzCCMemo{% + \noexpand\setbox0\noexpand\hbox{% + \expandonce\AdviceOriginal\unexpanded{#1}{#2}% + }}% + \AdviceOriginal#1{#2}% +} +\def\mmz@biblatex@cite@do@key#1{% + \mmz@mtoc@csname{mmz@bbl@#1}% + \ifcsdef{mmz@bbl@#1}{}{\mmzAbort}% +} +% \end{macro} +% \begin{macro}{\mmz@biblatex@cites} +% This macro puts the cites reference keys into the context, and adds the +% handled |\cites| command to the cc-memo. +\def\mmz@biblatex@cites{% + \mmz@temptoks{}% + \mmz@biblatex@cites@i +} +\def\mmz@biblatex@cites@i{% + \futurelet\mmz@temp\mmz@biblatex@cites@ii +} +\def\mmz@biblatex@cites@ii{% + \mmz@tempfalse + \ifx\mmz@temp\bgroup + \mmz@temptrue + \else + \ifx\mmz@temp[%] + \mmz@temptrue + \fi + \fi + \ifmmz@temp + \expandafter\mmz@biblatex@cites@iii + \else + \expandafter\mmz@biblatex@cites@z + \fi +} +\def\mmz@biblatex@cites@iii#1#{\mmz@biblatex@cites@iv{#1}} +\def\mmz@biblatex@cites@iv#1#2{% + \forcsvlist\mmz@biblatex@cite@do@key{#2}% + \toksapp\mmz@temptoks{#1{#2}}% + \mmz@biblatex@cites@i +} +\def\mmz@biblatex@cites@z{% + \xtoksapp\mmzCCMemo{% + \noexpand\setbox0\noexpand\hbox{% + \expandonce\AdviceOriginal\the\mmz@temptoks + }}% + \expandafter\AdviceOriginal\the\mmz@temptoks +} +%</latex> +% \end{macro} +% % % \section{Initialization} % \label{sec:code:initialization} @@ -3512,6 +3628,10 @@ %</plain,context> % \end{key} % +% Formats other than \hologo{plainTeX} need a way to prevent extraction during +% package-loading. +%<!plain>\mmzset{extract/no/.code={}} +% % \paragraph{\texttt{memoize.cfg}} Load the configuration file. Note that % |nomemoize| must input this file as well, because any special % memoization-related macros defined by the user should be available; for @@ -3521,63 +3641,91 @@ %<mmz,nommz>\InputIfFileExists{memoize.cfg}{}{} %<*mmz> % -% Formats other than \hologo{plainTeX} need a way to prevent extraction during -% package-loading. -\mmzset{ - %<!plain>extract/no/.code={}, -% \begin{key}{output directory} -% \begin{macro}{mmzOutputDirectory} -% Set the |-output-directory| --- manually, as there is no other way. -% \indentmacrocode - output-directory/.store in=\mmzOutputDirectory, -} -% \end{macro} -% \end{key} +% For formats other than \hologo{plainTeX}, we also save the current (initial +% or |memoize.cfg|-set) value of |extract|, so that we can restore it when +% package options include |extract=no|. Then, |extract| can be called without +% an argument in the preamble, triggering extraction using this method; this is +% useful e.g.\ if Memoize is compiled into a format. +%<!plain>\let\mmz@initial@extraction@method\mmz@extraction@method % % \paragraph{Process} the package options (except in \hologo{plainTeX}). -%<latex>\ProcessPgfPackageOptions{/mmz} +%<*latex> +\DeclareUnknownKeyHandler[mmz]{% + \expanded{\noexpand\pgfqkeys{/mmz}{#1\IfBlankF{#2}{={#2}}}}} +\ProcessKeyOptions[mmz] +%</latex> %<context>\expandafter\mmzset\expandafter{\currentmoduleparameters} -% -% Define |\mmzOutputDirectory| if |output-directory| was not given. -\ifdefined\mmzOutputDirectory -\else - \def\mmzOutputDirectory{}% -\fi -\mmzset{output directory/.code={\PackageError{memoize}{Key "output-directory" - may only be used as a package option}{}}} +% +% In \hologo{LaTeX}, |nomemoize| has to process package options as well, +% otherwise \hologo{LaTeX} will complain. +%</mmz> +%<*latex&nommz> +\DeclareUnknownKeyHandler[mmz]{} +\ProcessKeyOptions[mmz] +%</latex&nommz> +% \paragraph{Extern extraction} +% We redefine |extract| to immediately trigger extraction. This is crucial in +% \hologo{plainTeX}, where extraction must be invoked after loading the +% package, but also potentially useful in other formats when package options +% include |extract=no|. +%<*mmz> \mmzset{ - % \paragraph{Extract} the externs using the method given by |memoize.cfg| or - % the package options --- unless we're running \hologo{plainTeX}. - %<*!plain> - extract/\mmz@extraction@method, - % In non-\hologo{plainTeX} formats, also disable |extract| in the preamble. - extract/.code={\PackageError{memoize}{Key "extract" is only allowed as a - package option.}{If you really want to extract in the preamble, execute - "extract/<method>".}}, - %</!plain> - %<*plain> - % In \hologo{plainTeX}, where extraction must be invoked after - % loading the package, we now have to redefine |extract|, so that it will - % immediately trigger extraction. extract/.is choice, extract/.default=\mmz@extraction@method, % But only once: extract/.append style={ - extract/.code={\PackageError{memoize}{Key "extract" is only allowed to - be used once.}{If you really want to extract again, execute - "extract/<method>".}}, + extract/.code={\PackageError{memoize}{Key "extract" was invoked twice.}{In + principle, externs should be extracted only once. If you really want + to extract again, execute "extract/<method>".}}, }, - %</plain> -} + % In formats other than \hologo{plainTeX}, we remember the current |extract| + % code and then trigger the extraction. + %<!plain>/utils/exec={\pgfkeysgetvalue{/mmz/extract/.@cmd}\mmz@temp@extract}, + %<!plain>extract=\mmz@extraction@method, +} +% Option |extract=no| (which only exists in formats other than +% \hologo{plainTeX}) should allow for an explicit invocation of |extract| in +% the preamble. +%<*!plain> +\def\mmz@temp{no} +\ifx\mmz@extraction@method\mmz@temp + \pgfkeyslet{/mmz/extract/.@cmd}\mmz@temp@extract + \let\mmz@extraction@method\mmz@initial@extraction@method +\fi +\let\mmz@temp@extract\relax +%</!plain> % % Memoize was not really born for the draft mode, as it cannot produce new -% externs there. But we don't want to disable the package, as utilization is -% still perfectly valid in this mode, so let's just warn the user. +% externs there. But we don't want to disable the package, as utilization and +% pure memoization are still perfectly valid in this mode, so let's just warn +% the user. \ifnum\pdf@draftmode=1 - \PackageWarning{memoize}{No memoization will be performed in the draft mode}% + \PackageWarning{memoize}{No externalization will be performed in the draft mode}% \fi %</mmz> % +% Several further things which need to be defined as dummies in +% |nomemoize|\slash|memoizable|. +%<*nommz,mmzable&generic> +\pgfkeys{% + /handlers/.meaning to context/.code={}, + /handlers/.value to context/.code={}, +} +\let\mmzAbort\relax +\let\mmzUnmemoizable\relax +\newcommand\IfMemoizing[2][]{\@secondoftwo} +\let\mmzNoRef\@gobble +\let\mmzForceNoRef\@gobble +\newtoks\mmzContext +\newtoks\mmzContextExtra +\newtoks\mmzCMemo +\newtoks\mmzCCMemo +\newcount\mmzExternPages +\newcount\mmzExtraPages +\let\mmzTracingOn\relax +\let\mmzTracingOff\relax +%</nommz,mmzable&generic> +% % \paragraph{The end} of |memoize|, |nomemoize| and |memoizable|. %<*mmz,nommz,mmzable> %<plain>\resetatcatcode diff --git a/Master/texmf-dist/source/generic/memoize/memoize.ins b/Master/texmf-dist/source/generic/memoize/memoize.ins index f288e8e5554..2c24ac368b2 100644 --- a/Master/texmf-dist/source/generic/memoize/memoize.ins +++ b/Master/texmf-dist/source/generic/memoize/memoize.ins @@ -34,6 +34,7 @@ \file{memoizable.sty}{\from{memoize.dtx}{mmzable,latex}}% \file{memoizable.tex}{\from{memoize.dtx}{mmzable,plain}}% \file{t-memoizable.tex}{\from{memoize.dtx}{mmzable,context}}% + \file{memoizable.code.tex}{\from{memoize.dtx}{mmzable,generic}}% \file{memoize-extract-one.tex}{\from{memoize.dtx}{extract-one}}% } \endbatchfile |