summaryrefslogtreecommitdiff
path: root/macros/generic
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2024-03-18 03:01:30 +0000
committerNorbert Preining <norbert@preining.info>2024-03-18 03:01:30 +0000
commit9c8677e09c2c9b0d9593f26ed226411d68160a4e (patch)
tree1c5464d3dc4dbe0ad27d69bec29b581f4b0d1fdd /macros/generic
parent55140d5421e1ad0024c9acbfa72bd06402c2aa9f (diff)
CTAN sync 202403180301
Diffstat (limited to 'macros/generic')
-rw-r--r--macros/generic/advice/CHANGELOG.md4
-rw-r--r--macros/generic/advice/README.md4
-rw-r--r--macros/generic/advice/advice.edtx73
-rw-r--r--macros/generic/collargs/CHANGELOG.md10
-rw-r--r--macros/generic/collargs/README.md8
-rw-r--r--macros/generic/collargs/collargs.edtx211
-rw-r--r--macros/generic/memoize/CHANGELOG.md22
-rw-r--r--macros/generic/memoize/Makefile7
-rw-r--r--macros/generic/memoize/doc/memoize-clean.1.md4
-rw-r--r--macros/generic/memoize/doc/memoize-code.pdfbin626672 -> 637916 bytes
-rw-r--r--macros/generic/memoize/doc/memoize-code.sty3
-rw-r--r--macros/generic/memoize/doc/memoize-doc-common.sty2
-rw-r--r--macros/generic/memoize/doc/memoize-doc.pdfbin2181013 -> 2230627 bytes
-rw-r--r--macros/generic/memoize/doc/memoize-doc.sty12
-rw-r--r--macros/generic/memoize/doc/memoize-doc.tex872
-rw-r--r--macros/generic/memoize/doc/memoize-extract.1.md4
-rwxr-xr-xmacros/generic/memoize/memoize-clean.pl2
-rwxr-xr-xmacros/generic/memoize/memoize-clean.py2
-rwxr-xr-xmacros/generic/memoize/memoize-extract.pl2
-rwxr-xr-xmacros/generic/memoize/memoize-extract.py2
-rw-r--r--macros/generic/memoize/memoize.edtx471
-rw-r--r--macros/generic/memoize/memoize.ins1
22 files changed, 1215 insertions, 501 deletions
diff --git a/macros/generic/advice/CHANGELOG.md b/macros/generic/advice/CHANGELOG.md
index f112324840..ec26675b3c 100644
--- a/macros/generic/advice/CHANGELOG.md
+++ b/macros/generic/advice/CHANGELOG.md
@@ -14,6 +14,10 @@ those cases, please see [Memoize's GitHub
repository](https://github.com/sasozivanovic/memoize) for the recent
development history.
+## 2024/03/15 v1.1.1
+* Bugfix in `\AdviceGetOriginal`.
+* Simplify the definition of the initial outer handler.
+
## 2024/01/02 v1.1.0
* Implement `\AdviceCsnameGetOriginal`.
* Change `\AdviceGetOriginal` to expand to the internal control sequence
diff --git a/macros/generic/advice/README.md b/macros/generic/advice/README.md
index fa1e6294d9..5069b13bbf 100644
--- a/macros/generic/advice/README.md
+++ b/macros/generic/advice/README.md
@@ -15,5 +15,5 @@ any later version. The latest version of this license is in
https://www.latex-project.org/lppl.txt and version 1.3c or later is part of all
distributions of LaTeX version 2008 or later.
-This work has the LPPL maintenance status `maintained'. The Current Maintainer
-of this work is Sašo Živanović (saso.zivanovic@guest.arnes.si).
+This work has the LPPL maintenance status `maintained`. The Current Maintainer
+of this work is Sašo Živanović (`saso.zivanovic@guest.arnes.si`).
diff --git a/macros/generic/advice/advice.edtx b/macros/generic/advice/advice.edtx
index 415d9da79b..9fad4ef993 100644
--- a/macros/generic/advice/advice.edtx
+++ b/macros/generic/advice/advice.edtx
@@ -29,14 +29,14 @@
% \relax
%
%<*main>
-%<latex>\ProvidesPackage{advice}[2024/01/02 v1.1.0 Extend commands and environments]
+%<latex>\ProvidesPackage{advice}[2024/03/15 v1.1.1 Extend commands and environments]
%<context>%D \module[
%<context>%D file=t-advice.tex,
-%<context>%D version=1.1.0,
+%<context>%D version=1.1.1,
%<context>%D title=Advice,
%<context>%D subtitle=Extend commands and environments,
%<context>%D author=Saso Zivanovic,
-%<context>%D date=2024-01-02,
+%<context>%D date=2024-03-15,
%<context>%D copyright=Saso Zivanovic,
%<context>%D license=LPPL,
%<context>%D ]
@@ -203,7 +203,7 @@
% commands, as assigned by |\advice@setup@init@command|.
run conditions/.default=\AdviceRuntrue,
bailout handler/.default=\relax,
- outer handler/.default=\advice@default@outer@handler,
+ outer handler/.default=\AdviceCollector,
collector/.default=\advice@CollectArgumentsRaw,
collector options/.value required,
raw collector options/.value required,
@@ -324,7 +324,7 @@
\def\advice@setup@init@common{%
\def\AdviceRunConditions{\AdviceRuntrue}%
\def\AdviceBailoutHandler{\relax}%
- \def\AdviceOuterHandler{\advice@default@outer@handler}%
+ \def\AdviceOuterHandler{\AdviceCollector}%
\def\AdviceCollector{\advice@CollectArgumentsRaw}%
\def\AdviceCollectorOptions{}%
\def\AdviceInnerHandler{\advice@error@noinnerhandler}%
@@ -497,7 +497,7 @@
\ifcsname advice@o#1//\string#2\endcsname
\expandonce{\csname advice@o#1//\string#2\expandafter\endcsname\expandafter}%
\else
- \expandafter\noexpand\expandafter#2%
+ \unexpanded\expandafter{\expandafter#2\expandafter}%
\fi
}
% \end{macro}
@@ -764,14 +764,6 @@
\newif\ifAdviceRun
% \end{macro}
%
-% \begin{macro}{\advice@default@outer@handler}
-% The default outer handler merely executes the argument collector. Note
-% that it works for both commands and environments.
-\def\advice@default@outer@handler{%
- \AdviceCollector
-}
-% \end{macro}
-%
% \begin{macro}{\advice@CollectArgumentsRaw}
% This is the default collector, which will collect the argument using
% CollArgs' command |\CollectArgumentsRaw|. It will provide that command
@@ -1081,24 +1073,65 @@
\noexpand\advice@trace{\space\space\space\space
Raw options:
\detokenize\expandafter{\AdviceRawCollectorOptions}}%
+ % Collargs' |return| complicates tracing of the received argument. We put
+ % the code for remembering its value among the raw collector options. The
+ % default is 0; it is needed when we're using a collector other that
+ % |\CollectArguments|, the assumption being that external collectors will
+ % always return the collected arguments braced.
+ \unexpanded{%
+ \gdef\advice@collargs@return{0}%
+ \appto\AdviceRawCollectorOptions{\advice@remember@collargs@return}%
+ }%
\expandonce\AdviceCollector
}%
- % The tracing inner handler must grab the provided argument, if it's to show
- % what it is.
- \edef\advice@inner@handler@trace##1{%
+ \edef\advice@inner@handler@trace@do{%
\noexpand\advice@trace{\space\space
Executing inner handler:
\detokenize\expandafter{\AdviceInnerHandler}}%
+ % When this macro is executed, the received arguments are waiting for us in
+ % |\toks0|.
\noexpand\advice@trace{\space\space\space\space
- Received arguments:
- \noexpand\detokenize{##1}}%
+ Received arguments\noexpand\advice@inner@handler@trace@printcollargsreturn:
+ \noexpand\detokenize\noexpand\expandafter{\unexpanded{\the\toks0}}}%
\noexpand\advice@trace{\space\space\space\space
Options:
\detokenize\expandafter{\AdviceOptions}}%
- \expandonce{\AdviceInnerHandler}{##1}%
+ \expandonce{\AdviceInnerHandler}%
}%
\def\AdviceInnerHandler{\advice@inner@handler@trace}%
}
+\def\advice@remember@collargs@return{%
+ \global\let\advice@collargs@return\collargsReturn
+}
+% This is the entry point into the tracing inner handler. It will either get
+% the received arguments as a braced argument (when Collargs' |return=0|), or
+% from |\collargsArgs| otherwise. We don't simply always inspect
+% |\collargsArgs| because foreign argument collectors will not use this token
+% register; the assumption is that they will always return the collected
+% arguments braced.
+\def\advice@inner@handler@trace{%
+ \ifnum\advice@collargs@return=0
+ \expandafter\advice@inner@handler@trace@i
+ \else
+ \expandafter\advice@inner@handler@trace@ii
+ \fi
+}
+\def\advice@inner@handler@trace@i#1{%
+ \toks0={#1}%
+ \advice@inner@handler@trace@do{#1}%
+}
+\def\advice@inner@handler@trace@ii{%
+ \expandafter\toks\expandafter0\expandafter{\the\collargsArgs}%
+ \advice@inner@handler@trace@do
+}
+\def\advice@inner@handler@trace@printcollargsreturn{%
+ \ifnum\advice@collargs@return=0
+ \else
+ \space(collargs return=%
+ \ifcase\advice@collargs@return braced\or plain\or no\fi
+ )%
+ \fi
+}
% \end{macro}
%<plain>\resetatcatcode
%<context>\stopmodule
diff --git a/macros/generic/collargs/CHANGELOG.md b/macros/generic/collargs/CHANGELOG.md
index e3e1204b2d..d79205db9a 100644
--- a/macros/generic/collargs/CHANGELOG.md
+++ b/macros/generic/collargs/CHANGELOG.md
@@ -14,6 +14,16 @@ those cases, please see [Memoize's GitHub
repository](https://github.com/sasozivanovic/memoize) for the recent
development history.
+## 2024/03/15 v1.2.0
+* Argument processors:
+ * They now work without a formal argument, taking token register
+ `\collargsArg` as input. The processors taking a formal argument were
+ impossible (or at least too hard for me) to define.
+ * Remove `append/prepend pre/postwrap`, as they become useless with the above
+ change.
+* Implement keys `clear args` and `return`, and expose `\collargsArgs`.
+* Implement key `alias`.
+
## 2024/01/02 v1.1.0
* Implement `brace collected`.
diff --git a/macros/generic/collargs/README.md b/macros/generic/collargs/README.md
index 235225f08a..35ec0dd7be 100644
--- a/macros/generic/collargs/README.md
+++ b/macros/generic/collargs/README.md
@@ -1,6 +1,6 @@
Package CollArgs provides a command which can determine the argument scope of
-any command whose argument structure conforms to
-[xparse](https://ctan.org/pkg/xparse)'s argument specification.
+any command whose argument structure conforms to
+[LaTeX3 argument specification](https://www.latex-project.org/help/documentation/usrguide.pdf).
This package was developed as an auxiliary package of
[Memoize](https://ctan.org/pkg/memoize). This is why it is, somewhat
@@ -15,5 +15,5 @@ any later version. The latest version of this license is in
https://www.latex-project.org/lppl.txt and version 1.3c or later is part of all
distributions of LaTeX version 2008 or later.
-This work has the LPPL maintenance status `maintained'. The Current Maintainer
-of this work is Sašo Živanović (saso.zivanovic@guest.arnes.si).
+This work has the LPPL maintenance status `maintained`. The Current Maintainer
+of this work is Sašo Živanović (`saso.zivanovic@guest.arnes.si`).
diff --git a/macros/generic/collargs/collargs.edtx b/macros/generic/collargs/collargs.edtx
index 6cd39ad4ca..3df03eabfb 100644
--- a/macros/generic/collargs/collargs.edtx
+++ b/macros/generic/collargs/collargs.edtx
@@ -46,14 +46,14 @@
%
%
% \paragraph{Identification}
-%<latex>\ProvidesPackage{collargs}[2024/01/02 v1.1.0 Collect arguments of any command]
+%<latex>\ProvidesPackage{collargs}[2024/03/15 v1.2.0 Collect arguments of any command]
%<context>%D \module[
%<context>%D file=t-collargs.tex,
-%<context>%D version=1.1.0,
+%<context>%D version=1.2.0,
%<context>%D title=CollArgs,
%<context>%D subtitle=Collect arguments of any command,
%<context>%D author=Saso Zivanovic,
-%<context>%D date=2024-01-02,
+%<context>%D date=2024-03-15,
%<context>%D copyright=Saso Zivanovic,
%<context>%D license=LPPL,
%<context>%D ]
@@ -105,15 +105,14 @@
% \end{macro}
%
% \begin{macro}{\CollectArguments,\CollectArgumentsRaw}
-% These are the only public commands provided by the
-% package. |\CollectArguments| takes three arguments: the optional |#1| is
-% the option list, processed by |pgfkeys| (given the grouping structure,
-% these options will apply to all arguments); the mandatory |#2| is the
-% |xparse|-style argument specification; the mandatory |#3| is the ``next''
-% command (or a sequence of commands). The argument list is expected to
-% start immediately after the final argument; |\CollectArguments| parses it,
-% effectively figuring out its extent, and then passes the entire argument
-% list to the ``next'' command (as a single argument).
+% |\CollectArguments| takes three arguments: the optional |#1| is the option
+% list, processed by |pgfkeys| (given the grouping structure, these options
+% will apply to all arguments); the mandatory |#2| is the |xparse|-style
+% argument specification; the mandatory |#3| is the ``next'' command (or a
+% sequence of commands). The argument list is expected to start immediately
+% after the final argument; |\CollectArguments| parses it, effectively
+% figuring out its extent, and then passes the entire argument list to the
+% ``next'' command (as a single argument).
%
% |\CollectArgumentsRaw| differs only in how it takes and processes the
% options. For one, these should be given as a mandatory argument.
@@ -145,7 +144,9 @@
% Remember the code to execute after collection.
\def\collargs@next{#3}%
% Initialize the token register holding the collected arguments.
- \global\collargs@toks{}%
+ \ifcollargsClearArgs
+ \global\collargsArgs{}%
+ \fi
% Execute the central loop macro, which expects the argument specification
% |#2| to be delimited from the following argument tokens by a dot.
\collargs@#2.%
@@ -162,7 +163,6 @@
\def\collargsSet#1{\pgfqkeys{/collargs}{#1}}
% \end{macro}
%
-%
% \subsubsection{The keys}
% \label{sec:code:collargs:keys}
%
@@ -409,24 +409,10 @@
append postprocessor/.code={\collargsAppendPostprocessor{#1}},
prepend postprocessor/.code={\collargsPrependPostprocessor{#1}},
}
-\def\collargsAppendPreprocessor{%
- \collargs@addprocessor\appto\collargs@preprocess@arg}
-\def\collargsPrependPreprocessor{%
- \collargs@addprocessor\preto\collargs@preprocess@arg}
-\def\collargsAppendPostprocessor{%
- \collargs@addprocessor\appto\collargs@postprocess@arg}
-\def\collargsPrependPostprocessor{%
- \collargs@addprocessor\preto\collargs@postprocess@arg}
-% Here, |#1| will be either |\appto| or |\preto|, and |#2| will be either
-% |\collargs@preprocess@arg| or |\collargs@postprocess@arg|. |#3| is the
-% processor code.
-\def\collargs@addprocessor#1#2#3{%
- #1#2{%
- \expanded{%
- \unexpanded{#3}{\the\collargsArg}%
- }%
- }%
-}
+\def\collargsAppendPreprocessor#1{\appto\collargs@preprocess@arg{#1}}
+\def\collargsPrependPreprocessor#1{\preto\collargs@preprocess@arg{#1}}
+\def\collargsAppendPostprocessor#1{\appto\collargs@postprocess@arg{#1}}
+\def\collargsPrependPostprocessor#1{\preto\collargs@postprocess@arg{#1}}
% \end{macro}
% \end{collargskey}
% \end{macro}
@@ -451,71 +437,38 @@
% \end{collargskey}
% \end{macro}
% \end{collargskey}
-%
+%
% \begin{collargskey}[noindex]{(append/prepend) expandable (pre/post)processor}
% \begin{macro}[noindex]{\collargs(Append/Prepend)Expandable(Pre/Post)processor}
% \begin{collargskey}[noprint]{append expandable preprocessor, prepend expandable preprocessor, append expandable postprocessor, prepend expandable postprocessor}
% \begin{macro}[noprint]{\collargsAppendExpandablePreprocessor,\collargsPrependExpandablePreprocessor,\collargsAppendExpandablePostprocessor,\collargsPrependExpandablePostprocessor}
-% These keys
-% and macros simplify the definition of fully expandable processors. Note
-% that expandable processors are added to the same list as non-expandable
-% processors.
+% These keys and macros simplify the definition of expandable
+% processors. Note that expandable processors are added to the same
+% list as non-expandable processors.
\collargsSet{
- append expandable preprocessor/.code={%
- \collargsAppendExpandablePreprocessor{#1}},
- prepend expandable preprocessor/.code={%
- \collargsPrependExpandablePreprocessor{#1}},
- append expandable postprocessor/.code={%
- \collargsAppendExpandablePostprocessor{#1}},
- prepend expandable postprocessor/.code={%
- \collargsPrependExpandablePostprocessor{#1}},
-}
-\def\collargsAppendExpandablePreprocessor{%
- \collargs@addeprocessor\appto\collargs@preprocess@arg}
-\def\collargsPrependExpandablePreprocessor{%
- \collargs@addeprocessor\preto\collargs@preprocess@arg}
-\def\collargsAppendExpandablePostprocessor{%
- \collargs@addeprocessor\appto\collargs@postprocess@arg}
-\def\collargsPrependExpandablePostprocessor{%
- \collargs@addeprocessor\preto\collargs@postprocess@arg}
-\def\collargs@addeprocessor#1#2#3{%
- #1#2{%
- \expanded{%
- \edef\noexpand\collargs@temp{\unexpanded{#3}{\the\collargsArg}}%
- \unexpanded{\expandafter\collargsArg\expandafter{\collargs@temp}}%
- }%
+ append expandable preprocessor/.code={\collargsAppendExpandablePreprocessor{#1}},
+ prepend expandable preprocessor/.code={\collargsPrependExpandablePreprocessor{#1}},
+ append expandable postprocessor/.code={\collargsAppendExpandablePostprocessor{#1}},
+ prepend expandable postprocessor/.code={\collargsPrependExpandablePostprocessor{#1}},
+}
+\def\collargsAppendExpandablePreprocessor#1{%
+ \appto\collargs@preprocess@arg{%
+ \collargsArg\expandafter{\expanded{#1}}%
}%
}
-% \end{macro}
-% \end{collargskey}
-% \end{macro}
-% \end{collargskey}
-%
-% \begin{collargskey}[noindex]{(append/prepend) (pre/post)wrap}
-% \begin{macro}[noindex]{\collargs(Append/Prepend)(Pre/Post)wrap}
-% \begin{collargskey}[noprint]{append prewrap, prepend prewrap, append postwrap, prepend postwrap}
-% \begin{macro}[noprint]{\collargsAppendPrewrap,\collargsPrependPrewrap,\collargsAppendPostwrap,\collargsPrependPostwrap}
-% These keys and macros
-% simplify the definition of processors which yield the result after a
-% single expansion. Again, they are added to the same list as other
-% processors.
-\collargsSet{
- append prewrap/.code={\collargsAppendPrewrap{#1}},
- prepend prewrap/.code={\collargsPrependPrewrap{#1}},
- append postwrap/.code={\collargsAppendPostwrap{#1}},
- prepend postwrap/.code={\collargsPrependPostwrap{#1}},
-}
-\def\collargsAppendPrewrap{\collargs@addwrap\appto\collargs@preprocess@arg}
-\def\collargsPrependPrewrap{\collargs@addwrap\preto\collargs@preprocess@arg}
-\def\collargsAppendPostwrap{\collargs@addwrap\appto\collargs@postprocess@arg}
-\def\collargsPrependPostwrap{\collargs@addwrap\preto\collargs@postprocess@arg}
-\def\collargs@addwrap#1#2#3{%
- #1#2{%
- \long\def\collargs@temp##1{#3}%
- \expandafter\expandafter\expandafter\collargsArg
- \expandafter\expandafter\expandafter{%
- \expandafter\collargs@temp\expandafter{\the\collargsArg}%
- }%
+\def\collargsPrependExpandablePreprocessor#1{%
+ \preto\collargs@preprocess@arg{%
+ \collargsArg\expandafter{\expanded{#1}}%
+ }%
+}
+\def\collargsAppendExpandablePostprocessor#1{%
+ \appto\collargs@postprocess@arg{%
+ \collargsArg\expandafter{\expanded{#1}}%
+ }%
+}
+\def\collargsPrependExpandablePostprocessor#1{%
+ \preto\collargs@postprocess@arg{%
+ \collargsArg\expandafter{\expanded{#1}}%
}%
}
% \end{macro}
@@ -535,19 +488,51 @@
\newif\ifcollargsNoDelimiters
% \end{macro}
% \end{collargskey}
-
-% \begin{collargskey}{brace collected}
-% \begin{macro}{\ifcollargsBraceCollected}
-% When this conditional is set to false, the collected arguments are not
-% enclosed in braces when passed on to \meta{next-code}.
+%
+% \begin{collargskey}{clear args}
+% \begin{macro}{\ifcollargsClearArgs}
+% When this conditional is set to |false|, the global token register
+% |\collargsArgs| receiving the collected arguments is not cleared prior
+% to argument collection.
+\collargsSet{%
+ clear args/.is if=collargsClearArgs,
+}
+\newif\ifcollargsClearArgs
+\collargsClearArgstrue
+% \end{macro}
+% \end{collargskey}
+%
+% \begin{collargskey}{return}
+% \begin{macro}{\collargsReturn}
+% Exiting |\CollectArguments|, should the next-command be followed by the
+% braced collected arguments, collected arguments as they are, or nothing?
+\collargsSet{%
+ return/.is choice,
+ return/braced/.code=\collargsReturnBraced,
+ return/plain/.code=\collargsReturnPlain,
+ return/no/.code=\collargsReturnNo,
+}
+\def\collargsReturnBraced{\def\collargsReturn{0}}
+\def\collargsReturnPlain{\def\collargsReturn{1}}
+\def\collargsReturnNo{\def\collargsReturn{2}}
+\collargsReturnBraced
+% \end{macro}
+% \end{collargskey}
+%
+% \begin{collargskey}{alias}
+% \begin{macro}{\collargsAlias}
+%
\collargsSet{%
- brace collected/.is if=collargsBraceCollected,
+ alias/.code 2 args=\collargsAlias{#1}{#2}%
+}
+\def\collargsAlias#1#2{%
+ \csdef{collargs@#1}{\collargs@@@#2}%
}
-\newif\ifcollargsBraceCollected
-\collargsBraceCollectedtrue
% \end{macro}
% \end{collargskey}
%
+%
+%
% \subsubsection{The central loop}
% \label{sec:code:collargs:central-loop}
%
@@ -677,11 +662,11 @@
}
% \end{macro}
%
-% \begin{macro}{\collargs@toks}
+% \begin{macro}{\collargsArgs}
% This token register is where we store the collected argument tokens. All
% assignments to this register are global, because it needs to survive the
% groups opened for individual arguments.
-\newtoks\collargs@toks
+\newtoks\collargsArgs
% \end{macro}
%
% \begin{macro}{\collargsArg}
@@ -705,10 +690,10 @@
\endgroup
\noexpand\collargs@fix{%
\expandonce\collargs@next
- \ifcollargsBraceCollected
- {\the\collargs@toks}%
- \else
- \the\collargs@toks
+ \ifcase\collargsReturn\space
+ {\the\collargsArgs}%
+ \or
+ \the\collargsArgs
\fi
\collargs@spaces
}%
@@ -722,7 +707,7 @@
% \begin{macro}{\collargs@appendarg}
% This macro is used by the argument type
% handlers to append the collected argument to the storage
-% (|\collargs@toks|).
+% (|\collargsArgs|).
\long\def\collargs@appendarg#1{%
% Temporarily store the collected argument into a token register. The
% processors will manipulate the contents of this register.
@@ -744,7 +729,7 @@
\collargs@postprocess@arg
% Append the processed argument, preceded by any grabbed spaces (in the
% correct mode), to the storage.
- \xtoksapp\collargs@toks{\collargs@grabbed@spaces\the\collargsArg}%
+ \xtoksapp\collargsArgs{\collargs@grabbed@spaces\the\collargsArg}%
% Initialize the space-grabber.
\collargs@init@grabspaces
% Once the argument was appended to the list, we can close its group, opened
@@ -761,7 +746,15 @@
% defined by the argument type handler. Note that this macro \emph{appends}
% a wrapper, so multiple wrappers are allowed --- this is used by type |e|
% handler.
-\def\collargs@wrap{\collargs@addwrap\appto\collargs@process@arg}
+\def\collargs@wrap#1{%
+ \appto\collargs@process@arg{%
+ \long\def\collargs@temp##1{#1}%
+ \expandafter\expandafter\expandafter\collargsArg
+ \expandafter\expandafter\expandafter{%
+ \expandafter\collargs@temp\expandafter{\the\collargsArg}%
+ }%
+ }%
+}
\def\collargs@process@arg{}
% \end{macro}
%
@@ -1046,7 +1039,7 @@
% which will put everything up to the first opening brace into the first
% argument, looks funky, but that's all.
\collargs@defusecollector##1##{%
- % We append the collected argument, |##1|, to |\collargs@toks|, the token
+ % We append the collected argument, |##1|, to |\collargsArgs|, the token
% register holding the collected argument tokens.
\collargs@appendarg{##1}%
% Back to the central loop, with the rest of the argument specification
@@ -1448,7 +1441,7 @@
\collargs@readContent
}
% This macro appends the result given by the heavy machinery, waiting for us in
-% macro |\collargsArg|, to |\collargs@toks|, but not before dressing
+% macro |\collargsArg|, to |\collargsArgs|, but not before dressing
% it up (via |\collargs@wrap|) in a pair of verbatim braces.
\def\collargs@m@verb@group@i{%
\edef\collargs@temp{%
diff --git a/macros/generic/memoize/CHANGELOG.md b/macros/generic/memoize/CHANGELOG.md
index d92796b69e..3b58418359 100644
--- a/macros/generic/memoize/CHANGELOG.md
+++ b/macros/generic/memoize/CHANGELOG.md
@@ -3,6 +3,28 @@
For the development history, see [Memoize's GitHub
repository](https://github.com/sasozivanovic/memoize).
+## 2024/03/15 v1.2.0
+
+* Biblatex support:
+ * Allow for entries containing verbatim material.
+ * Support `\volcite` commands.
+ * Implement `biblatex ccmemo cite`.
+ * Submit all known citation commands to `auto`-keys `(vol)cite(s)`.
+ * The support must be explicitly loaded by `\mmzset{biblatex}`.
+* Minor changes:
+ * Separate generic PGF support out of TikZ support.
+ * Support `latexmk`.
+ * Drop the obsolete workaround for package `morewrites`.
+ * Clear Memoize's `begindocument` hooks after executing them.
+* Documentation:
+ * Introduce section "Support for specific classes and packages".
+ * Improve the documentation of argument specification accepted by CollArgs'
+ command `\CollectArguments` and Advice's key `args`, in particular with
+ reference to the fact that since 2020, the functionality of package
+ `xparse` is mostly integrated into the LaTeX kernel.
+ * Add a note about `TEXLIVE_WINDOWS_TRY_EXTERNAL_PERL`.
+ * Various minor changes.
+
## 2024/01/21 v1.1.2
* Fix a bug in Biblatex support.
diff --git a/macros/generic/memoize/Makefile b/macros/generic/memoize/Makefile
index b459a5fdfa..12737f4c7f 100644
--- a/macros/generic/memoize/Makefile
+++ b/macros/generic/memoize/Makefile
@@ -10,16 +10,17 @@ all: ctan/memoize.zip
# Prepare the CTAN submission.
PACKAGE = memoize
-VERSION = 1.1.2
+VERSION = 1.2.0
YEAR = 2024
-MONTH = 01
-DAY = 21
+MONTH = 03
+DAY = 15
FORMAT = generic
COMMON = memoize nomemoize memoizable
PLAIN = memoize-extract-one.tex
GENERIC = memoizable.code.tex
+LATEX = memoize-biblatex.code.tex
SOURCE = memoize.edtx memoize.ins
SCRIPTS := memoize-extract memoize-clean
diff --git a/macros/generic/memoize/doc/memoize-clean.1.md b/macros/generic/memoize/doc/memoize-clean.1.md
index b2713b3440..3587477305 100644
--- a/macros/generic/memoize/doc/memoize-clean.1.md
+++ b/macros/generic/memoize/doc/memoize-clean.1.md
@@ -2,8 +2,8 @@
title: memoize-clean
section: 1
header: User Manual
-footer: memoize-clean of Memoize v1.1.2
-date: January 21, 2024
+footer: memoize-clean of Memoize v1.2.0
+date: March 15, 2024
hyphenate: false
---
diff --git a/macros/generic/memoize/doc/memoize-code.pdf b/macros/generic/memoize/doc/memoize-code.pdf
index 6d37bb8eb7..66835fe05d 100644
--- a/macros/generic/memoize/doc/memoize-code.pdf
+++ b/macros/generic/memoize/doc/memoize-code.pdf
Binary files differ
diff --git a/macros/generic/memoize/doc/memoize-code.sty b/macros/generic/memoize/doc/memoize-code.sty
index c7bddde08b..ef5d1d9885 100644
--- a/macros/generic/memoize/doc/memoize-code.sty
+++ b/macros/generic/memoize/doc/memoize-code.sty
@@ -22,6 +22,9 @@
\ProvidesPackage{memoize-code}
\RequirePackage{memoize-doc-common}
+\def\TikZ;{{\upshape Ti\textit{k}Z}}
+\def\PGF;{PGF}
+
% Typesetting the code & indentation
%\MacroIndent=0pt
\AddToHook{begindocument}{\MacroIndent=0pt }
diff --git a/macros/generic/memoize/doc/memoize-doc-common.sty b/macros/generic/memoize/doc/memoize-doc-common.sty
index fe6ab0023f..3df90535ce 100644
--- a/macros/generic/memoize/doc/memoize-doc-common.sty
+++ b/macros/generic/memoize/doc/memoize-doc-common.sty
@@ -144,8 +144,6 @@
% various %
\usepackage{hologo}
-\def\TikZ;{{\rm Ti\emph{k}Z}}
-\def\PGF;{PGF}
\newcommand\PGFmanual[1]{%
\href
{http://mirrors.ctan.org/graphics/pgf/base/doc/pgfmanual.pdf}
diff --git a/macros/generic/memoize/doc/memoize-doc.pdf b/macros/generic/memoize/doc/memoize-doc.pdf
index 0b2419e7eb..14c2a43331 100644
--- a/macros/generic/memoize/doc/memoize-doc.pdf
+++ b/macros/generic/memoize/doc/memoize-doc.pdf
Binary files differ
diff --git a/macros/generic/memoize/doc/memoize-doc.sty b/macros/generic/memoize/doc/memoize-doc.sty
index 380ab94f28..29b3042af9 100644
--- a/macros/generic/memoize/doc/memoize-doc.sty
+++ b/macros/generic/memoize/doc/memoize-doc.sty
@@ -391,6 +391,7 @@
\newcommand\therefore{\ensuremath{\Rightarrow}}
\newcommand\nohyphen{\discretionary{}{}{}}
+\hyphenation{Coll-Args}
\let\gobble\@gobble
\lstset{
@@ -506,7 +507,9 @@
\newcommand\code[1]{\texttt{\spaceskip 0.5em plus 0.2em minus 0.2em #1}}
\newcommand\Arg[1]{\texttt{\##1}}
-\def\TikZ{\href{https://ctan.org/pkg/pgf}{{\rm Ti\emph{k}Z}}\xspace}
+\NewDocumentCommand{\TikZ}{s}{%
+ \IfBooleanF{#1}{\href{https://ctan.org/pkg/pgf}}{{\upshape Ti\textit{k}Z}}\xspace
+}
\def\PGF{\href{https://ctan.org/pkg/pgf}{PGF}\xspace}
\def\Emacs{\href{https://www.gnu.org/software/emacs}{Emacs}\xspace}
\def\AucTeX{\href{https://www.gnu.org/software/auctex}{AUC\hologo{TeX}}\xspace}
@@ -701,6 +704,13 @@
\newcommand\noprint[1]{\setbox0=\hbox{#1}}
\usepackage{wrapfig}
+\newcommand\footnoteagain[1]{%
+ \def\@thefnmark{\ref{#1}}%
+ \@footnotemark
+}%
+
+\usepackage{varioref}
+
% \usepackage{caption}
% \captionsetup{labelformat=empty}
diff --git a/macros/generic/memoize/doc/memoize-doc.tex b/macros/generic/memoize/doc/memoize-doc.tex
index 951d4b469f..e9047b96c8 100644
--- a/macros/generic/memoize/doc/memoize-doc.tex
+++ b/macros/generic/memoize/doc/memoize-doc.tex
@@ -32,7 +32,7 @@
\usepackage{makeidx}
\pdfsystem{makeindex -s memoize-doc.mst \jobname.idx}
\makeindex
-\usepackage[hangindent=1em,justific=raggedright,font=small]{idxlayout}
+\usepackage[hangindent=1em,justific=raggedright,font=small,totoc]{idxlayout}
\appto\indexfont{\def\pkgcolor{gray}}
\AddToHook{begindocument}{% so that the region compilation takes these in
@@ -100,6 +100,10 @@
cmd={name=tikzexternalize},
cmd={name=pgfsys@getposition},
},
+ scope={
+ pkg=beamer,
+ env={name=frame},
+ },
file={name=texmf.cnf},
env={name=tcblisting, pkg=tcolorbox},
cmd={name=vref, pkg=varioref},
@@ -384,7 +388,7 @@
Package Advice implements a generic framework for extending the functionality
of selected commands and environments, while package CollArgs provides a
command which can determine the argument scope of any command whose argument
- structure conforms to \pkg{xparse}'s argument specification.
+ structure conforms to \hologo{LaTeX3} argument specification.
\end{tcolorbox}
\begin{tcolorbox}[
@@ -478,7 +482,8 @@ section~\ref{sec:tut:test} to test if the setup was successful.
already installed on your system. On Windows, you might have to install it. I
tested Memoize with Strawberry Perl, available
at \url(https://){strawberryperl.com}; see \url(https://){www.perl.org} for
-other options.
+other options. On \hologo{TeX}Live on Windows, you should also set
+\code{TEXLIVE\_WINDOWS\_TRY\_EXTERNAL\_PERL=1}.
\begin{wrapfigure}[2]{r}{0.25\linewidth}
\raisebox{0.5mm}[\dimexpr\height-0.5mm][\depth]{%
@@ -895,18 +900,17 @@ environment is clearly marked). With commands, we must inform Memoize about
their argument structure, which we achieve using key \refmmzauto{args} in the
second argument of key \refmmz{auto}:
\EmphTT{\refmmz{auto}=\meta{command}\braces{\refmmzauto{memoize},
- \refmmzauto{args}=\marg{argument specification}}}. We can only leave out
-\refmmzauto{args} if the command was defined by \refcmd{NewDocumentCommand} or
-similar; in this case, Memoize can retrieve the argument specification on its
-own.
+ \refmmzauto{args}=\marg{argument specification}}}.
And how does the \meta{argument specification} look like? It is a sequence of
letters, each letter determining an argument type. Memoize recognizes the same
-argument types and their letters as package \pkg{xparse} (which defines
-\refcmd{NewDocumentCommand} and friends), so you should look at (section 1 of)
-the documentation of that package for details, if and when you need them.
-Here, we focus on the two most commonly used types, \docref{xparse:m} and \docref{xparse:o}, and add the
-optional star for good measure:
+argument types as \refcmd{NewDocumentCommand}, the \hologo{LaTeX3} command for
+defining new commands, available in core \hologo{LaTeX} since 2020. For
+the complete story, see the reference for \refmmzauto{args} in
+section~\ref{sec:ref:advice} and the frame on page~\pageref{tab:argspec} in
+section~\ref{sec:ref:collargs}; here, we focus on the two most commonly used
+types, \docref{xparse:m} and \docref{xparse:o}, and add the optional star for
+good measure:
\begin{center}
\begin{tabular}{lll}
\toprule
@@ -935,14 +939,18 @@ argument (in braces).
},
}
+If the command we're submitting to automemoization was defined by
+\refcmd{NewDocumentCommand} or similar, \refmmzauto{args} may be omitted, as in
+this case, Memoize can retrieve the argument specification on its own.
+
This should get you started with automemoization. We'll provide some further
basic information in sections~\ref{sec:tut:working-on-a-picture}
and~\ref{sec:tut:verbatim} of the tutorial, but only package writers will
probably ever need the gory details from
section~\ref{sec:tut:automemoization-details}. It is my sincere hope that they
-will support Memoize in their packages, where necessary, so that you don't even
-have to write the \refmmz{auto} declarations, but there is one thing you should
-know if you encounter a package supporting Memoize: you should load it
+will support Memoize in their packages, where necessary, so that you don't ever
+have to write the \refmmz{auto} declarations. However, there is one thing you
+should know if you encounter a package supporting Memoize: you should load it
\emph{after} Memoize!
@@ -4332,7 +4340,8 @@ automemoization deploying two specifically developed auxiliary packages:
package Advice, which provides a generic framework for extending the
functionality of selected commands and environments, and package CollArgs,
which provides a command for collection of the arguments conforming to the
-given (slightly extended) \pkg{xparse} argument specification.
+given (slightly extended) \hologo{LaTeX3}\slash \pkg{xparse} argument
+specification.
This section lists the considerations which went into designing the system,
followed by short tutorials on both auxiliary packages, which include several
@@ -4369,14 +4378,14 @@ arguments of a command can, and quite often do, differ wildly. The author (or t
package writer) will need to tell Memoize about the argument structure of the
command. And as there is already a nice and general argument specification on
the market --- I'm obviously referring to the argument specification of package
-\pkg{xparse}, which was recently even integrated into the core \hologo{LaTeX}
+\pkg{xparse}, which was recently integrated into the core \hologo{LaTeX}
--- why not use that? Memoize comes with an auxiliary package CollArgs, which
(given the slightly extended \pkg{xparse}-style argument specification)
collects the arguments of a command into a single entity. All the user needs
to write to enable automemoization for a command is thus
\refmmz{auto}|=|\meta{command}\braces{\refmmzauto{memoize},
\refmmzauto{args}|=|\braces{\meta{argument specification}}}. Even simpler,
-when it comes to commands defined by \pkg{xparse}'s \refcmd{NewDocumentCommand}
+when it comes to commands defined by \hologo{LaTeX3}'s \refcmd{NewDocumentCommand}
or friends, writing \refmmz{auto}|=|\meta{command}\braces{\refmmzauto{memoize}}
will suffice, as the argument specification of these commands can be retrieved
by \refcmd{GetDocumentCommandArgSpec}.
@@ -4685,8 +4694,7 @@ key \refmmzauto{collector} in addition to executing \refmmzauto{memoize}. For
example, Memoize submits \refcmd{tikz} to automemoization by loading
\reffile{advice-tikz.code.tex}, which contains Advice's definition of the
\cs{tikz} collector \refcmd{AdviceCollectTikZArguments}, and issuing the
-following declaration.\footnote{This is a simplification, see
- \refmmzauto{memoize tikz} for the full story.}
+following declaration.
\begin{tcblisting}{
example title={Declaring automemoization of command \cs{tikz}},
@@ -4781,8 +4789,8 @@ complain.
\paragraph{A simple collector}
Let us implement a collector for a command which accepts one (standard
-\hologo{LaTeX}) optional argument and one mandatory argument; in \pkg{xparse}
-terms, a command with argument specification |om|.
+\hologo{LaTeX}) optional argument and one mandatory argument; in
+\hologo{LaTeX3} terms, a command with argument specification |om|.
Using \cs{NewDocumentCommand}, such a collector is very easy to implement. We
simply define a command with signature |om| and distinguish two possibilities
@@ -4842,7 +4850,8 @@ The package provides two public commands, \refcmd{CollectArguments} and
\refcmd{CollectArgumentsRaw}; we'll focus on the former first.
\refcmd{CollectArguments} takes three arguments: optional \meta{options} in the
form of a \pkg{pgfkeys} keylist; a mandatory \meta{argument specification} in a
-(slightly extended) \pkg{xparse} format; and the \meta{next-code}:
+(slightly extended) \hologo{LaTeX3}\slash\pkg{xparse} format; and the
+\meta{next-code}:
\begin{center}
\refcmd{CollectArguments}\oarg{options}\marg{argument specification}\marg{next-code}%
\textcolor{gray}{\meta{tokens}}
@@ -4891,27 +4900,28 @@ conform to the given specification. In the example above, it is only in |#1#2|
of |\PrintAndDo| that |\makebox| is ``reunited'' with its arguments, but note
that the reunion is far from obligatory.
-CollArgs supports all the argument types (and modifiers) that \pkg{xparse}
-does, including the environment type \docref{xparse:b}, as exemplified below.
-Again, the code below might seem strange, as it features an |\end{minipage}|
-without the matching |\begin{minipage}|, but the logic is similar as for
- commands: just as \refcmd{CollectArguments} occurs in front of the command
- arguments, without the command itself, so it occurs in front of the
- environment body, without the opening of that body. However, while
- \refcmd{CollectArguments} never needs to know the command name, we need to
- inform it of the environment name, so that it can find the end of the
- environment. This can be achieved as shown below, using key
- \refcollargs{environment} in the optional argument of the command, or by our
- extension to the \pkg{xparse} argument specification, where the environment
- argument type \docref{xparse:b} may be followed by a braced environment name.
- In the example below, we could therefore also invoke argument collection by
- \refcmd{CollectArguments}\braces
- {\docref{xparse:+}\docref{xparse:b}\braces{\env{minipage}}} (we have preceded
- \docref{xparse:b} with a \docref{xparse:+} to allow for an environment body
- containing paragraph tokens).\footnote{CollArgs automatically adapts to the
- format, i.e.\ it knows that environments are tagged by \cs{}\meta{name} and
- \cs{end}\meta{name} in \hologo{plainTeX} and by \cs{start}\meta{name} and
- \cs{stop}\meta{name} in \hologo{ConTeXt}.}
+CollArgs supports all the argument types (and modifiers) that \hologo{LaTeX3}
+does, complete with the uncommon\slash historical types only available upon
+loading package \pkg{xparse}. Below, we provide an example of the environment
+type \docref{xparse:b}. Again, the code might seem strange, as it features an
+|\end{minipage}| without the matching |\begin{minipage}|, but the logic is
+similar as for commands: just as \refcmd{CollectArguments} occurs in front of
+the command arguments, without the command itself, so it occurs in front of the
+environment body, without the opening of that body. However, while
+\refcmd{CollectArguments} never needs to know the command name, we need to
+inform it of the environment name, so that it can find the end of the
+environment. This can be achieved as shown below, using key
+\refcollargs{environment} in the optional argument of the command, or by our
+extension to the \hologo{LaTeX3}\slash\pkg{xparse} argument specification,
+where the environment argument type \docref{xparse:b} may be followed by a
+braced environment name. In the example below, we could therefore also invoke
+argument collection by \refcmd{CollectArguments}\braces
+{\docref{xparse:+}\docref{xparse:b}\braces{\env{minipage}}} (we have preceded
+\docref{xparse:b} with a \docref{xparse:+} to allow for an environment body
+containing paragraph tokens).\footnote{CollArgs automatically adapts to the
+ format, i.e.\ it knows that environments are tagged by \cs{}\meta{name} and
+ \cs{end}\meta{name} in \hologo{plainTeX} and by \cs{start}\meta{name} and
+ \cs{stop}\meta{name} in \hologo{ConTeXt}.}
\ExampleName{collargs-minipage}
\makeexample{\examplename.tex.c1}
@@ -4927,7 +4937,7 @@ arguments, and grabbing everything until |\end{minipage}| is the same as first
grabbing the optional argument, maybe, then the mandatory argument, and finally
the argument body.
-\refcmd{CollectArguments} not only supports \pkg{xparse}'s verbatim argument
+\refcmd{CollectArguments} not only supports the verbatim argument
type \docref{xparse:v}, it can grab an argument of \emph{any} type in the
verbatim mode, triggered by option \refcollargs{verbatim}.\footnote{We refer to
the verbatim mode triggered by \refcollargs{verbatim} as the full verbatim
@@ -4948,12 +4958,12 @@ its limitations.
\makeexample{\examplename.tex.c1}
\tcbinputexample{listing and compile}
-Finally, CollArgs extends the \pkg{xparse} specification by modifier
-\docref{xparse:amp}, which allows the user to specify options which apply only
-to the following argument, as opposed to the options given as the optional
-argument of \refcmd{CollectArguments}, which apply to all the arguments. A
-third way to invoke the environment body collection in the above example is
-thus \refcmd{CollectArguments}%
+Finally, CollArgs extends the \hologo{LaTeX3}\slash\pkg{xparse} specification
+by modifier \docref{xparse:amp}, which allows the user to specify options which
+apply only to the following argument, as opposed to the options given as the
+optional argument of \refcmd{CollectArguments}, which apply to all the
+arguments. A third way to invoke the environment body collection in the above
+example is thus \refcmd{CollectArguments}%
\bracestt{\docref{xparse:amp}\bracestt{\refcollargs{environment}=minipage}+b}.
Both the single-argument and the common options can be given not only as
@@ -5585,12 +5595,6 @@ on how to handle this properly.
likely have no need of these macros.
\end{doc}
-\begin{doc}{easy, key={name=per overlay,desc=style}}
- This style is only defined in the Beamer class. When applied, the memoized
- code will produce a cc-memo (and extern) for each overlay of the frame. For
- implementation, see section~\ref{sec:per-overlay}.
-\end{doc}
-
\begin{doc}{
key={name=capture, par=\docAux{of=key:/mmz/capture, value={name=hbox}, text=\alt,
value={name=vbox,of=key:/mmz/capture}},
@@ -7447,7 +7451,7 @@ headers.
\begin{doc}{
key={name=outer handler,par=\meta{\hologo{TeX} code},
- desc=initially and default: see below},
+ desc=initially and default: \refcmd{AdviceCollector}},
}
This key declares the \meta{\hologo{TeX} code} as the outer handler component
@@ -7484,7 +7488,7 @@ headers.
\emph{not} collected before invoking the outer handler --- in fact, avoiding
the argument collection is the raison d'être of the outer handler! (In the case
of an advised environment, the environment body can be seen as an argument of
- \pkg{xparse} type \docref{xparse:+}\docref{xparse:b}.)
+ \hologo{LaTeX3} type \docref{xparse:+}\docref{xparse:b}.)
The outer handler (and any other component of the advice it invokes) has
access to the following auxiliary macros, defined by the framework:
@@ -7505,8 +7509,7 @@ headers.
more practical.)
\end{itemize}
- This key is initially set to an internal control sequence which merely
- invokes the collector by executing \refcmd{AdviceCollector}; in other words,
+ This key is initially set to \refcmd{AdviceCollector}; in other words,
the initial outer handler leaves all the work to the collector and the inner
handler. There is no need to specifically set up the outer handler when
using the inner handler. Executing this key without a value restores it to
@@ -7534,7 +7537,7 @@ headers.
While this manual occasionally states that the initial argument collector is
\refcmd{CollectArguments} of package CollArgs, this is, if we're precise,
incorrect on two counts. For one, the initial collector is not a CollArgs
- command, but a macro which acts as the ``bridge'' between Advice
+ command, but an internal macro which acts as the ``bridge'' between Advice
and CollArgs. Second, the initial collector does not really invoke
\refcmd{CollectArguments}, but its cousin, \refcmd{CollectArgumentsRaw},
which allows Advice (and Memoize) to fine tune its behaviour
@@ -7573,74 +7576,48 @@ headers.
This key describes the \meta{argument specification} of the advised command.
- Assuming that the initial value of \refmmzauto{collector} has not been
- modified, the given \meta{argument specification} is eventually interpreted
- by command \refcmd{CollectArguments} of package CollArgs, which expects an
- argument specification in the format specified by package \pkg{xparse}; the
- format is summarized in the frame below for convenience, for details, see the
- \pkg{xparse} manual. If the specification is not given, the initial collector
- assumes that the advised command was defined using \refcmd{NewDocumentCommand}
- (or similar) of package \pkg{xparse}, and will attempt to retrieve the argument
- specification automatically via \refcmd{GetDocumentCommandArgSpec}.
-
- \begin{tcolorbox}[float, before float=\hfill,
- title={The {\pkg[white]{xparse}} argument specification
- (as understood by \refcmd[link color=white]{CollectArguments})}]
- \begin{tabularx}{\linewidth}{>{\tt}lX}
- \multicolumn{2}{l}{\rm\textbf{Mandatory argument types}}\\
- m&standard (a single token or multiple tokens in braces)\\
- r\meta{token$_1$}\meta{token$_2$}&delimited by
- \meta{token$_1$} and \meta{token$_2$} \\
- v&verbatim, in the style of \cs{verb}\\
- b&the body of an environment\\
- [1ex]\multicolumn{2}{l}{\rm\textbf{Optional argument types}}\\
- o&in square brackets\\
- d\meta{token$_1$}\meta{token$_2$}&delimited by
- \meta{token$_1$} and \meta{token$_2$}\\
- s&an optional star\\
- t\meta{token}&an optional \meta{token}\\
- e\marg{tokens}&a set of embellishments\\
- [1ex]\multicolumn{2}{l}{\rm\textbf{Weird argument types}}\\
- l&a mandatory argument until the first begin-group token\\
- u\marg{tokens}&\hologo{TeX}'s delimited argument\\
- g&an optional argument inside braces\\
- [1ex]\multicolumn{2}{l}{\rm\textbf{Modifiers}}\\
- +&allow the next argument to be long\\
- !&disallow spaces before arguments of type \docref{xparse:d} and \docref{xparse:t}\\
- >\marg{processor}&process the next argument\\
- [1ex]\multicolumn{2}{l}{\rm\textbf{CollArgs extensions}}\\
- \docref{xparse:b}\marg{name}&set the environment name for this environment\\
- \docref{xparse:amp}\marg{options}&apply CollArgs options to the next argument\\
- \docref{xparse:amp}\docref{xparse:amp}\marg{raw options}&apply raw CollArgs options to the next argument\\
- \end{tabularx}
-
- \smallskip
-
- \refcmd{CollectArguments} can grab an argument of any type in the
- \refcollargs{verbatim} mode.
-
- As \refcmd{CollectArguments} does not use the arguments but only collects
- them, it does not care about the default values of optional arguments.
- Therefore, argument types with defaults (\docref{xparse:O},
- \docref{xparse:D} and \docref{xparse:R}) may be substituted by their
- \texttt{-NoValue-} counterparts (\docref{xparse:o}, \docref{xparse:d} and
- \docref{xparse:r}) and are therefore not included in the above table.
- \end{tcolorbox}
+ The value of this key is intended to be interpreted by the
+ \refmmzauto{collector}. Assuming this key retained its initial value, the
+ given \meta{argument specification} is eventually interpreted by command
+ \refcmd{CollectArguments} of package CollArgs, which expects an argument
+ specification in the format specified by \hologo{LaTeX3}, also allowing for
+ the uncommon\slash historical types only defined upon loading package
+ \pkg{xparse}, and several CollArgs-specific extensions. For further
+ information, see the following sources:
+ \begin{itemize}
+ \item The \hologo{LaTeX3} version
+ of \href{https://www.latex-project.org/help/documentation/usrguide.pdf}
+ {``\LaTeX\ for authors''} documents the standard argument types.
+ \item The \pkg{xparse} manual additionally documents the uncommon\slash
+ historical types only available upon loading package \pkg{xparse}.
+ \item CollArgs extensions are documented in section~\ref{sec:ref:collargs}.
+ \item For convenience, the entire \hologo{LaTeX3} argument specification
+ format, complete with \pkg{xparse} and CollArgs extensions, is summarized
+ in the frame on page~\pageref{tab:argspec} in
+ section~\ref{sec:ref:collargs}.
+ \end{itemize}
- In general, however, an argument collector may this interpret this setting it
+ If \meta{argument specification} is not provided, the initial collector
+ assumes that the advised command was defined using \hologo{LaTeX3}'s
+ \refcmd{NewDocumentCommand} (or similar), and will attempt to retrieve the
+ argument specification automatically.\footnote{The automatic retrieval
+ deploys command \refcmd{GetDocumentCommandArgSpec} of package \pkg{xparse},
+ which is the sole reason that Advice loads this package in \hologo{LaTeX}.}
+
+ In general, however, an argument collector may this interpret this setting
in any way it sees fit --- or not at all. For example, in Memoize the value
of \refmmzauto{args} is ignored for command \refcmd{tikz}, which requires a special
collector (\refcmd{mmzCollectTikZArguments}).
- When setting up advice for a \emph{command}, this key is initially
- ``unset,'' i.e.\ it holds a special value indicating that the argument
- specification is not provided. Note that this special value is not an empty
- string --- \refmmzauto{args}|={}|, or simply \refmmzauto{args}|=|, indicates
- a command which takes no arguments. During the execution of the advice, one
- may use the \hologo{LaTeX}-style conditional
- \docaux{cmd}{AdviceIfArgs}\marg{true branch}\marg{false branch} to test
- whether the argument specification was provided. Executing this key without
- a value restores it to the initial, unset value.
+ When setting up advice for a \emph{command}, this key is initially ``unset,''
+ i.e.\ it holds a special value indicating that the argument specification is
+ not provided. Note that this special value is not an empty string;
+ \refmmzauto{args}|={}|, or simply \refmmzauto{args}|=|, indicates a command
+ which takes no arguments. During the execution of the advice, one may use
+ the \hologo{LaTeX}-style conditional \docaux{cmd}{AdviceIfArgs}\marg{true
+ branch}\marg{false branch} to test whether the argument specification was
+ provided. Executing this key without a value restores it to the initial,
+ unset value.
When setting up the advice of an \emph{environment}, this key is
initialized to \docref{xparse:+}\docref{xparse:b} (a long environment body),
@@ -8008,8 +7985,8 @@ be generalized to \meta{namespace} and \meta{setup key} of
``remembered''.\\
\refcmd{ref}&\refmmzauto{ref}\\
\refcmd[short]{savepos}&\refmmzauto{abort}&Available only in \hologo{LuaTeX}.\\
- \refcmd{tikz}&\refmmzauto{memoize tikz}\\
- \refenv{tikzpicture}&\refmmzauto{memoize tikz}\\
+ \refcmd{tikz}&\refmmzauto{memoize}\\
+ \refenv{tikzpicture}&\refmmzauto{memoize}\\
\bottomrule
\end{tabularx}
\caption{Commands advised by Memoize}
@@ -8154,16 +8131,6 @@ be generalized to \meta{namespace} and \meta{setup key} of
preferred.
\end{doc}
-\begin{doc}{key={name=memoize tikz,desc=style}}
- This key is used to declare memoization of \TikZ pictures; it may also be
- used for PGF pictures. Besides executing \refmmzauto{memoize}, it uses
- \refmmz{at begin memoization} and \refmmz{at end memoization} to add the code
- which measures the increase of the PGF picture ID during memoization of a
- picture, and increases this ID for the measured amount upon the utilization
- of the extern, thereby making sure that a utilized \TikZ\slash\PGF extern
- advances the PGF picture ID as if the picture was compiled.
-\end{doc}
-
\begin{doc}{easy,
key={name=ref,desc=style},
key={name=force ref,desc=style},
@@ -8317,15 +8284,22 @@ be generalized to \meta{namespace} and \meta{setup key} of
\docaux{key path}{collargs}. The given options apply to all the arguments in
\meta{argument specification}. The recognized keys are listed in the rest of
the section.
-
- The \meta{argument specification} should be given in the \pkg{xparse} format
- (we summarize this format in the documentation for \refmmzauto{args} in
- section~\ref{sec:ref:advice}), with several extensions:\footnote{Collargs
- internally uses a dot (|.|) to delimit the argument specification from the
- following argument tokens. Therefore, the dot really counts as an extra
- argument type, in the sense that Collargs will stop working if the dot
- becomes an argument type or a modifier in some future release of
- \pkg{xparse}.}
+
+ \refcmd{CollectArguments} expects the \meta{argument specification} to
+ conform to the \hologo{LaTeX3} argument specification format, i.e.\ it
+ accepts the same kind of \meta{argument specification} as
+ \refcmd{NewDocumentCommand} and friends, complete with extensions available
+ upon loading package \pkg{xparse}.\footnote{Note that CollArgs collects the
+ arguments by its own means. It does \emph{not} require either
+ \hologo{LaTeX3} or \pkg{xparse} to do its job. Specifically, it may be
+ used in \hologo{plainTeX} and \hologo{ConTeXt} as well.} Furthermore,
+ CollArgs introduces several extensions to the
+ \hologo{LaTeX3}\slash\pkg{xparse} argument specification
+ format:\footnote{Collargs internally uses a dot (|.|) to delimit the argument
+ specification from the following argument tokens. Therefore, the dot
+ really counts as an extra argument type, in the sense that CollArgs will
+ stop working if the dot becomes an argument type or a modifier in some
+ future release of \hologo{LaTeX}.}
\begin{itemize}
\item We introduce modifier \docAux{xparse modifier={name=\&,label=amp,index
annotation/.prefix={additional\ }, index annotation/.append={\
@@ -8340,14 +8314,80 @@ be generalized to \meta{namespace} and \meta{setup key} of
\item The number of collected ``arguments'' is unlimited.
\end{itemize}
- Also note that the effect of \docref{xparse:O}\marg{default} is the same as
- the effect of \docref{xparse:o}, and similarly for other pairs of types with
- and without defaults (\docref{xparse:R} and \docref{xparse:r},
- \docref{xparse:D} and \docref{xparse:d}, and \docref{xparse:E} and
- \docref{xparse:e}). CollArgs is dedicated to collecting the argument tokens
- precisely as they are given: if an optional argument is missing, its default
- value is \emph{not} inserted among the collected arguments --- consequently,
- \refcmd{CollectArguments} is utterly uninterested in the default value.
+ For convenience, the entire \hologo{LaTeX3} argument specification format,
+ complete with \pkg{xparse} and CollArgs extensions, is summarized in the
+ frame \vpageref{tab:argspec}. For the official documentation of the format,
+ consult the following sources:
+ \begin{itemize}
+ \item The \hologo{LaTeX3} version
+ of \href{https://www.latex-project.org/help/documentation/usrguide.pdf}
+ {``\LaTeX\ for authors''} documents the standard argument types.
+ \item The \pkg{xparse} manual additionally documents the uncommon\slash
+ historical types only available upon loading package \pkg{xparse}.
+ \end{itemize}
+
+ \begin{tcolorbox}[float, before float=\hfill, label=tab:argspec,
+ title={The \hologo{LaTeX3}\slash\pkg[white]{xparse} argument specification,
+ with CollArgs extensions}]
+ \begin{tabularx}{\linewidth}{>{\tt}lX}
+ \multicolumn{2}{l}{\rm\textbf{Mandatory argument types}}\\
+ m&standard (a single token or multiple tokens in braces)\\
+ r\meta{token$_1$}\meta{token$_2$}
+ &delimited by \meta{token$_1$} and \meta{token$_2$} \\
+ R\meta{token$_1$}\meta{token$_2$}\marg{default}\footnote{\label{fn:ODRE}As
+ \refcmd{CollectArguments} does not use the arguments but only collects
+ them, it does not care about the default values of optional arguments.
+ Therefore, while CollArgs recognizes argument types with defaults
+ (\docref{xparse:O}, \docref{xparse:D}, \docref{xparse:R}, and
+ \docref{xparse:E}), they may be safely substituted by their
+ \texttt{-NoValue-} counterparts (\docref{xparse:o}, \docref{xparse:d},
+ \docref{xparse:r} and \docref{xparse:e}).}
+ &delimited by \meta{token$_1$} and \meta{token$_2$}, with a default value\\
+ v&verbatim, in the style of \cs{verb}\footnote{\refcmd{CollectArguments}
+ can grab an argument of any type in the \refcollargs{verbatim} mode.}\\
+ b&the body of an environment\\
+ [1ex]\multicolumn{2}{l}{\rm\textbf{Optional argument types}}\\
+ o&in square brackets\\
+ O\marg{default}\footnoteagain{fn:ODRE}&in square brackets, with a default value\\
+ d\meta{token$_1$}\meta{token$_2$}
+ &delimited by \meta{token$_1$} and \meta{token$_2$}\\
+ D\meta{token$_1$}\meta{token$_2$}\marg{default}\footnoteagain{fn:ODRE}
+ &delimited by \meta{token$_1$} and \meta{token$_2$}, with a default value\\
+ s&an optional star\\
+ t\meta{token}&an optional \meta{token}\\
+ e\marg{tokens}&a set of embellishments\\
+ E\marg{tokens}\marg{defaults}\footnoteagain{fn:ODRE}
+ &a set of embellishments, with default values\\
+ [1ex]\multicolumn{2}{l}{\rm\textbf{Weird argument types}}\\
+ l\footnote{\label{fn:lug}Argument types \docref{xparse:l},
+ \docref{xparse:u} and \docref{xparse:g} are not defined by the core
+ \hologo{LaTeX3}; they are only available upon loading package
+ \pkg{xparse}. As noted in the main text, CollArgs does not make any
+ difference between standard \hologo{LaTeX3} types and the \pkg{xparse}
+ extensions; it supports them all at all times, and even in
+ \hologo{plainTeX} and \hologo{ConTeXt}.}
+ &a mandatory argument until the first begin-group token\\
+ u\marg{tokens}\footnoteagain{fn:lug}&\hologo{TeX}'s delimited argument\\
+ g\footnoteagain{fn:lug}&an optional argument inside braces\\
+ [1ex]\multicolumn{2}{l}{\rm\textbf{Modifiers}}\\
+ +&allow the next argument to be long\\
+ !&disallow spaces before arguments of type \docref{xparse:d} and \docref{xparse:t}\\
+ >\marg{processor}&process the next argument\\
+ [1ex]\multicolumn{2}{l}{\rm\textbf{CollArgs extensions}}\\
+ \docref{xparse:b}\marg{name}&the body of an environment with the given \meta{name}\\
+ \docref{xparse:amp}\marg{options}&apply CollArgs options to the next argument\\
+ \docref{xparse:amp}\docref{xparse:amp}\marg{raw options}&apply raw CollArgs options to the next argument\\
+ \end{tabularx}
+ \end{tcolorbox}
+
+ Note that in CollArgs, \docref{xparse:O}\marg{default} has the same effect as
+ \docref{xparse:o}, and similarly for other pairs of types with and without
+ defaults (\docref{xparse:R} and \docref{xparse:r}, \docref{xparse:D} and
+ \docref{xparse:d}, and \docref{xparse:E} and \docref{xparse:e}). CollArgs is
+ dedicated to collecting the argument tokens precisely as they are given: if
+ an optional argument is missing, its default value is \emph{not} inserted
+ among the collected arguments --- consequently, \refcmd{CollectArguments} is
+ utterly uninterested in the default value.
Collection of environments automatically adapts to the format, i.e.\ given
environment body name |foo|, \refcmd{CollectArguments} knows to search for
@@ -8389,12 +8429,41 @@ be generalized to \meta{namespace} and \meta{setup key} of
\end{tcblisting}
Withing the option-setting code, the programmer may also deploy macro
- \docaux{cmd}{collargsSet}, which processes the \meta{options} in the keylist
+ \refcmd{collargsSet}, which processes the \meta{options} in the keylist
format. One idea could be to execute this macro at the end of the low-level
options; this would set the ``defaults'' using the fast programmer's
interface, but still allow for user customization.
\end{doc}
+\begin{doc}{
+ cmd={name=collargsSet, par=\meta{options}}
+ }
+ Locally update the CollArgs configuration.
+
+ The \meta{options} are a comma-separated list of \meta{key}|=|\meta{value}
+ pairs. They are processed using the \pkg{pgfkeys} utility of PGF/\TikZ (see
+ \PGFmanual{87}), with the default path set to \docaux{key path}{collargs}.
+
+ This key may be used either outside an invocation of
+ \refcmd{CollectArguments}\slash \refcmd{CollectArgumentsRaw}, to set defaults
+ or define additional styles, or within the \meta{option-setting code} in the
+ invocation of \refcmd{CollectArgumentsRaw}.
+\end{doc}
+
+\begin{doc}[
+ pi={\docaux{cmd}{collargsAlias}},
+ ]{
+ key={name=alias, par=\marg{symbol}\marg{definition}, desc=style},
+ }
+ Define \meta{symbol} as an abbreviation of \marg{definition} within the
+ \meta{argument specification} passed to \refcmd{CollectArguments}.
+
+ For example, Memoize's \pkg{biblatex} support sets
+ \code{\refcollargs{alias}=%
+ \braces{*}\braces{\&\&\braces{\cs{mmz@biblatex@mark@citation@key}}}}, with
+ \cs{mmz@biblatex@mark@citation@key} an internal macro which stores the
+ contents of \refcmd{collargsArg} into another internal macro.
+\end{doc}
\begin{doc}[
pi={\docaux{cmd}{collargsCaller}},
@@ -8554,6 +8623,9 @@ grab the environment body in the verbatim mode.)
}
These keys declare processors which will transform the collected argument
before appending it to the argument list.
+
+ A processor should be a macro taking no arguments, (locally) transforming the
+ contents of token register \docaux{cmd}{collargsArg} as it sees fit.
A collected argument undergoes the following transformations:
\begin{itemize}
@@ -8567,28 +8639,22 @@ grab the environment body in the verbatim mode.)
|prepend|.
\end{itemize}
- \meta{code} will typically consist of a single control sequence pointing to a
- one-argument macro, which will receive the collected argument (possibly
- modified by the processors already applied). In general, however, the value
- of this key may be any code; Collargs will execute \meta{code}\marg{collected
- argument}.
-
- The processed argument should be returned by storing it into token register
- \docaux{cmd}{collargsArg}.
-
The following example illustrates how one could go about reimplementing Bruno
- Le Floch ingenious package \pkg{cprotect}.\footnote{This example is merely a
+ Le Floch ingenious package \pkg{cprotect},\footnote{This example is merely a
proof of concept. For the bells and whistles which would make it useful in
- real life, see the documentation of \pkg{cprotect}.} We define processor
- |\writetofile| which dumps the argument into a file, replacing it with the
- |\input| statement. (Of course, to allow for verbatim content in the
- footnote, we also have to mark the argument as \refcollargs{verbatim}.
- And we use \refcollargs{no delimiters} to get rid of the braces around the
- footnote text.)
+ real life, see the documentation of \pkg{cprotect}.} which allows the
+ author to use verbatim text in arguments. Below, we will end up with with
+ \cs{footnote}\braces{\meta{footnote text}} replaced by |\footnote{\input
+ _fn.tex}|, with \meta{footnote text} waiting in file |_fn.tex|. To achieve
+ this, we define processor |\writetofile| which dumps the argument into a
+ file, replacing it with the |\input| statement. (Of course, to allow for
+ verbatim content in the footnote, we also have to mark the argument as
+ \refcollargs{verbatim}. And we use \refcollargs{no delimiters} to get rid of
+ the braces around the footnote text.)
\ExampleName{collargs-processor}
\makeexample{\examplename.tex.c1}
- \tcbinputexample{listing and text, listing file=\examplepath.tex.c1}
+ \tcbinputexample{comment=\input{\examplepath.tex.c1}}
\end{doc}
\begin{doc}[
@@ -8613,47 +8679,51 @@ grab the environment body in the verbatim mode.)
key={name=append expandable postprocessor, par=\meta{code}, desc={style, no default}},
key={name=prepend expandable postprocessor, par=\meta{code}, desc={style, no default}},
}
- These keys may be used to add fully expandable processors. A processor added
- with one of these keys will end up among the processors declared by
- \refcollargs{append preprocessor} et al.
-
- A processor declared by one of these keys will define the processed argument
- as the full expansion (|\edef|) of \meta{code}\marg{collected argument}.
- \meta{code} will typically consist of a single control sequence pointing to a
- fully expandable one-argument macro.
-
- For example, |\trim@spaces@noexp| from package \pkg{trimspaces} could be used
- as an expandable processor of environment body to remove the spaces around
- the grabbed environment body.
-\end{doc}
-
-\begin{doc}[
- pi={\docaux{cmd}{collargsAppendPrewrap},
- \docaux{cmd}{collargsPrependPrewrap},
- \docaux{cmd}{collargsAppendPostwrap},
- \docaux{cmd}{collargsPrependPostwrap}},
- ]{
- key={name=append prewrap, par=\meta{macro definition}, desc={style, no default}},
- key={name=prepend prewrap, par=\meta{macro definition}, desc={style, no default}},
- key={name=append postwrap, par=\meta{macro definition}, desc={style, no default}},
- key={name=prepend postwrap, par=\meta{macro definition}, desc={style, no default}},
+ These keys may be used to simplify the definition of processors which can
+ arrive at the result by means of full expansion. A processor declared by one
+ of these keys assigns the full expansion of \meta{code} to
+ \refcmd{collargsArg}, i.e.\ it is defined as
+ \code{\refcmd{collargsArg}\cs{expandafter}\braces{%
+ \cs{expanded}\braces{\meta{code}}}}.
+
+ A processor added with one of these keys will end up among the processors
+ declared by \refcollargs{append preprocessor} et al.
+
+ \meta{code} will typically contain \code{\cs{the}\refcmd{collargsArg}} to
+ refer to the input state of the argument. For example, to add quotes around
+ the collected argument: \code{\refcollargs{append expandable preprocessor}=%
+ \nohyphen``\cs{the}\refcmd{collargsArg}''}. Or, to trim spaces from an
+ argument using |\trim@spaces@noexp| from package \pkg{trimspaces}:
+ \code{\refcollargs{append expandable preprocessor}=%
+ \cs{expandafter}\cs{trim@spaces@noexp}\cs{expandafter}\braces{%
+ \cs{the}\refcmd{collargsArg}}}. A pre-processor is the right choice in
+ both these cases because we want to modify the argument before it is dressed
+ up in the original delimiters.
+
+ Let us consider another, more involved example. As the example for
+ \refcollargs{append preprocessor} above, it is inspired by \pkg{cprotect},
+ but instead of writing the argument into a file and then reading it back, we
+ rescan it using |\scantokens|. Remarks:
+ \begin{enumerate*}[(a)]
+ \item rescanning only happens when processing |\fbox|; \refcollargs{append
+ expandable preprocessor} merely inserts |\ScanMultilineTokens| in front
+ of the argument.
+ \item |\ScanMultilineTokens| below temporarily changes the |\newlinechar| to
+ 13 to allow for linebreaks in (the source code of) the argument;
+ \item |\endinput| is added to prevent the extra end-of-file space creeping
+ in;
+ \item we have used \refmmz{verb} instead of \refmmz{verbatim} so that the
+ argument is eventually dressed up in a pair of real, category code 1 and 2,
+ braces.
+ \end{enumerate*}
+
+ \ExampleName{collargs-expandable-processor}
+ \makeexample{\examplename.tex.c1}
+ \tcbinputexample{comment=\input{\examplepath.tex.c1},
+ %listing options app={numbers=left, numberstyle=\tiny, numbersep=0.5em},
}
- These keys add processors which transform the collected argument in a single
- expansion.
-
- The declared processor will use \meta{macro definition} to define a temporary
- one-argument \meta{macro}, and then set the \meta{processed argument} to be
- the single expansion of \meta{macro}\marg{collected argument}.
-
- For example, to add quotes around the collected argument, write
- \refcollargs{append prewrap}|={``#1''}| (doubling the hash when executing
- \refcmd{CollectArguments} from a macro, of course). Or, perhaps more
- usefully, \refcollargs{append prewrap}|={\scantokens{#1}}| can be used to
- retokenize a verbatim argument (during the execution of the
- \meta{next-code}).
\end{doc}
-
\begin{doc}[
pi=\docaux{cmd}{ifcollargsNoDelimiters}
]{
@@ -8661,24 +8731,99 @@ grab the environment body in the verbatim mode.)
}
When this key is in effect, the collected argument will not be dressed up
into delimiters that it was dressed up in \meta{argument tokens}. For
- example, an optional argument, encountered as [\meta{argument}] inside
- \meta{argument tokens}, will be spit out simply as \meta{argument}.
+ example, an optional argument, encountered as \code{[\meta{argument}]}, will
+ be spit out simply as \meta{argument}.
- Any user-specified pre- or post-processing will still be applied.
+ Any user-specified pre- or post-processing will still be applied (and usually
+ is, when this key is used).
+
\ExampleName{collargs-nodelimiters}
\makeexample{\examplename.tex.c1}
- \tcbinputexample{comment=\input{\examplepath.tex.c1}}
+ \tcbinputexample{comment=\small\input{\examplepath.tex.c1}}
+\end{doc}
+
+\begin{doc}[%
+ pi=\docaux{cmd}{collargsReturn}
+ ]{
+ key={name=return,
+ par=\docAux{
+ of=key:/collargs/return,
+ value={name=braced},
+ text=\Alt,
+ value={name=plain},
+ text=\Alt,
+ value={name=no},
+ },
+ desc={initially \code{braced}, no default}
+ }
+ }
+ This key determines the form in which the collected arguments are passed on
+ to \meta{next-code}:
+ \begin{itemize}
+ \item When set to \refcollargs{return=braced} (the default), \meta{next-code}
+ receives the collected arguments as a single, braced argument.
+ \item When set to \refcollargs{return=plain}, the collected arguments are
+ simply inserted behind \meta{next-code}. Combined with other keys, this
+ keys makes it possible to transform the collected arguments into form
+ expected by \meta{next-code}. For example, |&{...} b| below transforms the
+ body of an environment into a mandatory argument (after trimming the
+ surrounding spaces); the preceding optional argument remains unmodified.
+ Without \code{\refcollargs{return}=\refcollargs{return=plain}},
+ |\processbody| would receive a single argument, containing both the
+ optional argument and the transformed environment body; with
+ \code{\refcollargs{return}=\refcollargs{return=plain}}, which makes
+ CollArgs refrain from bracing the collected arguments, it receives an
+ optional plus a mandatory argument.\footnote{For further examples, see the
+ definition of \cs{mmz@remove@quotes} and advising of \cs{blx@bbl@entry}
+ in the Memoize source.}
+
+ \ExampleName{collargs-return-plain}
+ \makeexample{\examplename.tex.c1}
+ \tcbinputexample{comment=\small\input{\examplepath.tex.c1}}
+ \item When set to \refcollargs{return=no}, the collected arguments are not
+ inserted into the input stream; \meta{next-code} can access them through
+ \refcmd{collargsArgs}, a token register dedicated to holding the
+ collected arguments (regardless of the value of \refcollargs{return}).
+
+ In conjunction with \code{\refcollargs{clear args}=false}, this setup can
+ be useful for reiterating command \refcmd{CollectArguments}.\footnote{The
+ idea illustrated with this example is deployed in the definition of
+ \refmmzauto{cites} in the Memoize source.} Command
+ |\CollectOptionalArguments| defined below collects any number of optional
+ arguments given either in square brackets or in parentheses. To achieve
+ this, we instruct CollArgs to neither clear \refcmd{collargsArgs} at the
+ start of argument collection, nor insert it into the input stream once the
+ collection is finished; we thus have to clear this token register manually
+ at the start, and use it directly at the end. (There's a number of ways of
+ detecting whether further arguments follow. We use a pure Collargs
+ solution below: we define a postprocessor which sets an internal
+ conditional to true if any argument was found, and test for that
+ conditional in the \meta{next-code}.)
+
+ \ExampleName{collargs-return-no}
+ \makeexample{\examplename.tex.c1}
+ \tcbinputexample{comment=\small\input{\examplepath.tex.c1}}
+ \end{itemize}
+\end{doc}
+
+\begin{doc}{
+ cmd={name=collargsArgs, desc={token register, global}},
+ }
+ This token register holds the collected arguments upon the exit from
+ \refcmd{CollectArguments}; the token register is assigned to globally.
+
+ This register may be manipulated by the user, both within and outside an
+ invocation of \refcmd{CollectArguments}; all assignments should be global.
\end{doc}
\begin{doc}[
- pi=\docaux{cmd}{ifcollargsBraceCollected}
+ pi=\docaux{cmd}{ifcollargsClearArgs}
]{
- key={name=brace collected, conditional=true},
+ key={name=clear args, conditional=true},
}
- When this conditional is set to false, the collected arguments are not
- enclosed in braces when passed on to \meta{next-code}. This probably only
- makes sense when wrapping the individual arguments, e.g.\ by
- \refcollargs{append postwrap}|={{#1}}|.
+ When this conditional is set to |false|, token register \refcmd{collargsArgs}
+ is not cleared upon entering \refcmd{CollectArguments}; see
+ \code{\refcollargs{return}=\refcollargs{return=no}} for an example.
\end{doc}
\begin{doc}[
@@ -8937,10 +9082,291 @@ as follows: \docref{xparse:o}, \docref{xparse:d}, \docref{xparse:s},
\endgroup % /collargs
+\subsection{Support for specific classes and packages}
+
+\subsubsection{PGF}
+
+When package \PGF is loaded, commands \refcmd{mmzPgfAtBeginMemoization}
+and \refcmd{mmzPgfAtEndMemoization} are defined and appended to hooks
+\refmmz{at begin memoization} and \refmmz{at end memoization}, respectively.
+
+Note that environment \env{pgfpicture} is \emph{not} submitted to
+automemoization. Doing this would probably not be a good idea, as it is used
+by many other commands and environments.
+
+\makeexcerpt{_support-pgf}
+\tcbinputexample[.tex][.excerpt]{%
+ listing only, one file, no attachment,
+ title=\hypercolor{url}{white}\PGF support,
+}
+
+\begin{doc}{
+ cmd={name=mmzPgfAtBeginMemoization},
+ cmd={name=mmzPgfAtEndMemoization},
+ }
+ These commands are meant to be executed inside hooks \refmmz{at begin
+ memoization} and \refmmz{at end memoization}. Together, they make sure
+ that utilizing an extern containing PGF/\TikZ pictures advances the PGF
+ picture ID (\cs{pgf@picture@serial@count}) as if the pictures were compiled.
+
+ This avoids potential problems for various mechanisms which rely on a stable
+ PGF picture ID. For example, in absence of advancing the ID, placing a \TikZ
+ picture scaled by |ext.scalepicture| of \pkg{tikz-ext} \emph{after} some
+ memoized \TikZ picture would confuse the scaled picture, as its ID would
+ depend on whether the extern of the previous (unrelated!) picture was
+ memoized or utilized.
+
+ Command \refcmd{mmzPgfAtBeginMemoization}, executed in hook \refmmz{at begin
+ memoization}, remembers the PGF picture ID at the beginning of memoization.
+ Command \refcmd{mmzPgfAtEndMemoization}, executed in hook \refmmz{at end
+ memoization}, checks whether the ID was advanced during memoization, and if
+ so, appends to the cc-memo the code advancing the ID counter accordingly.
+
+ Note that out of the box, \refcmd{mmzPgfAtBeginMemoization} and
+ \refcmd{mmzPgfAtEndMemoization} reside in their respective hooks at all
+ times, not only when memoizing \refenv{tikzpicture} and \refcmd{tikz}. This
+ way, the PGF picture ID mechanism is applied to all pictures deploying PGF
+ pictures under the hook, e.g.\ \pkg{forest} trees.
+\end{doc}
+
+
+\subsubsection[TikZ]{\TikZ*}
+
+When package \TikZ is loaded, environment \refenv{tikzpicture} and command
+\refcmd{tikz} and are automatically submitted to automemoization; this may be
+prevented by \code{\refmmz{deactivate}=\refenv{tikzpicture}} and\slash or
+\code{\refmmz{deactivate}=\refcmd{tikz}}, or by \refmmz{manual}. Note that
+command \refcmd{tikz} requires a dedicated argument collector,
+\refcmd{AdviceCollectTikZArguments}.
+
+\makeexcerpt{_support-tikz}
+\tcbinputexample[.tex][.excerpt]{%
+ listing only, one file, no attachment,
+ title=\hypercolor{url}{white}\TikZ support,
+}
+
+
+\subsubsection{Forest}
+
+When package \pkg{forest} is loaded, environment \refenv{forest} and command
+\refcmd{Forest} are automatically submitted to automemoization; this may be
+prevented by \code{\refmmz{deactivate}=\refenv{forest}} and\slash or
+\code{\refmmz{deactivate}=\refcmd{Forest}}, or by \refmmz{manual}. Note that
+command \refcmd{Forest} is defined by \refcmd{NewDocumentCommand}, which makes
+specifying option \refmmzauto{args} unnecessary.
+
+\makeexcerpt{_support-forest}
+\tcbinputexample[.tex][.excerpt]{%
+ listing only, one file, no attachment,
+ title=\pkg[white]{Forest} support,
+}
+
+
+\subsubsection{Beamer}
+
+Memoize should be loaded by writing |\RequirePackage{memoize}| (rather than
+|\usepackage{memoize}|) before (rather than after) |\documentclass{beamer}|.
+
+\begin{doc}{easy, key={name=per overlay,desc=style}}
+ Applying this style to a piece of memoized code contained in a Beamer
+ \refenv{frame} will produce a separate cc-memo (and extern) for each overlay
+ of the frame. See section~\ref{sec:tut:beamer} for the tutorial.
+
+ Note that this style is \emph{not} intended for externalization of entire
+ frames.
+
+ The implementation, documented in section~\ref{sec:per-overlay}, is not
+ trivial, but only deploys the public interface offered by Memoize.
+\end{doc}
+
+\subsubsection{Biblatex}
+
+\begin{doc}{
+ key={name=biblatex, par=\marg{additional configuration}, desc=style},
+ }
+ This key loads the \pkg{biblatex} support, but only if package \pkg{biblatex}
+ is loaded (anywhere in the preamble); after loading the support,
+ \meta{additional configuration} is executed within \refcmd{mmzset}.
+
+ When \pkg{biblatex} support is loaded, all citation commands defined by this
+ package\footnote{In \pkg{biblatex} version 3.19: \cs{cite}, \cs{Cite},
+ \cs{parencite}, \cs{Parencite}, \cs{footcite}, \cs{footcitetext},
+ \cs{textcite}, \cs{Textcite}, \cs{smartcite}, \cs{Smartcite},
+ \cs{supercite}, \cs{cites}, \cs{Cites}, \cs{parencites}, \cs{Parencites},
+ \cs{footcites}, \cs{footcitetexts}, \cs{smartcites}, \cs{Smartcites},
+ \cs{textcites}, \cs{Textcites}, \cs{supercites}, \cs{autocite},
+ \cs{Autocite}, \cs{autocites}, \cs{Autocites}, \cs{citeauthor},
+ \cs{Citeauthor}, \cs{citetitle}, \cs{citeyear}, \cs{citedate},
+ \cs{citeurl}, \cs{nocite}, \cs{fullcite}, \cs{footfullcite}, \cs{volcite},
+ \cs{Volcite}, \cs{volcites}, \cs{Volcites}, \cs{pvolcite}, \cs{Pvolcite},
+ \cs{pvolcites}, \cs{Pvolcites}, \cs{fvolcite}, \cs{Fvolcite},
+ \cs{fvolcites}, \cs{Fvolcites}, \cs{ftvolcite}, \cs{ftvolcites},
+ \cs{Ftvolcite}, \cs{Ftvolcites}, \cs{svolcite}, \cs{Svolcite},
+ \cs{svolcites}, \cs{Svolcites}, \cs{tvolcite}, \cs{Tvolcite},
+ \cs{tvolcites}, \cs{Tvolcites}, \cs{avolcite}, \cs{Avolcite},
+ \cs{avolcites}, \cs{Avolcites}, \cs{notecite}, \cs{Notecite},
+ \cs{pnotecite}, \cs{Pnotecite}, \cs{fnotecite}, \cs{citename},
+ \cs{citelist}, \cs{citefield}.} behave like \refcmd{ref} in the sense that
+ changing a bibliography entry referred to by a citation command within a
+ piece of memoized code triggers recompilation of that code. For example, it
+ is safe to use \code{\cs{textcite}\braces{\meta{citation key}}} inside
+ memoized code, in the sense that the extern will be recompiled when the entry
+ for the \meta{citation key} is changed in the |.bib| file.
+
+ Furthermore, Memoize takes care that even once an extern which contains a
+ reference to \meta{citation key} is utilized (i.e.\ included into the
+ document as a picture), the \meta{citation key} is marked (by \cs{nocite}) as
+ used, and will appear among the items listed by \cs{printbibliography}.
+
+ In most cases, the out-of-the-box level of \refmmz{biblatex} support will
+ suffice. However:
+ \begin{itemize}
+ \item To support an additional citation command (most likely defined via
+ \cs{DeclareCiteCommand} etc.), advise it by one of \refmmzauto{cite} and
+ friends below.
+ \item To have ibid (and similar) tracking sensitive to citation commands
+ within memoized code, execute \refmmz{biblatex ccmemo cite}.
+ \end{itemize}
+
+ Under the hood, \pkg{biblatex} support does two things:
+ \begin{itemize}
+ \item It declares advice for \pkg{biblatex}'s internal macro
+ \cs{blx@bbl@entry}, executed while processing the |.bbl| file, which makes
+ it possible for Memoize to detect changes in bibliography entries.
+ \item It defines the \refmmz{auto}-keys of the \refmmzauto{cite} family,
+ documented below, and advises all \pkg{biblatex}'s citation commands with
+ these keys.
+ \end{itemize}
+\end{doc}
+
+
+\begin{doc}{
+ key={keypath=/mmz/auto, name=cite, desc=style},
+ key={keypath=/mmz/auto, name=cites, desc=style},
+ key={keypath=/mmz/auto, name=volcite, desc=style},
+ key={keypath=/mmz/auto, name=volcites, desc=style},
+ }
+ When a citation command is advised by one of these \refmmz{auto}-keys, a
+ piece of memoized code containing the citation command will be recompiled
+ upon changing the bibliography entry of a citation key used by the command;
+ in other words, the citation command will behave in a fashion analogous to
+ \refmmzauto{ref}.
+
+ Furthermore, the memo corresponding to the memoized piece of code will
+ contain a \cs{nocite} command for each citation key occurring within the
+ code; in effect, citation keys continue to be marked as used even when
+ utilizing the memo\slash extern. For further details, see \refmmz{biblatex
+ ccmemo cite}.
+
+ Out of the box, Memoize advises all \pkg{biblatex}'s (v3.19) citation
+ commands with these keys. If a new citation command is defined, it may be
+ submitted to these keys by the author. Use
+ \begin{itemize}
+ \item \code{\refmmz{auto}=\meta{citation command}\braces{\refmmzauto{cite}}}
+ for a \meta{citation command} in the \cs{cite} family,
+ \item \code{\refmmz{auto}=\meta{citation command}\braces{\refmmzauto{cites}}}
+ for a \meta{citation command} in the \cs{cites} family,
+ \item \code{\refmmz{auto}=\meta{citation command}\braces{\refmmzauto{volcite}}}
+ for a \meta{citation command} in the \cs{volcite} family, and
+ \item \code{\refmmz{auto}=\meta{citation command}\braces{\refmmzauto{volcites}}}
+ for a \meta{citation command} in the \cs{volcites} family.
+ \end{itemize}
+
+ Which key should be used with which command depends on the argument structure
+ of the citation command, as documented in section 3.9 of the \pkg{biblatex}
+ manual. Accordingly, the auto-keys of the \refmmzauto{cite} family set
+ \refmmzauto{args} as follows:
+
+ \begin{center}
+ \begin{tabular}{rl}
+ &\refmmzauto{args}\\
+ \midrule
+ \refmmzauto{cite}, \refmmzauto{cites}
+ &\code{l\,*m}\\
+ \refmmzauto{volcite}, \refmmzauto{volcites}
+ &\code{l\,m l\,*m}\\
+ \end{tabular}
+ \end{center}
+
+ Commands like |\cite| take one mandatory argument (the citation key), which
+ may be preceded by an optional star, prenote and postnote. Key
+ \refmmzauto{cite} grabs all the optional arguments by |l|, while |*m|
+ receives the braced \meta{citation key} argument; |*| is locally defined to
+ mark the following argument as the citation key. Commands like |\volcite|
+ take two mandatory arguments: the volume and the citation key, in this order;
+ each may be preceded by an optional argument. Again, the optional arguments
+ are collected by |l|s, and the mandatory arguments by |m|s, with the second
+ argument being marked as the citation key by |*|. The two \refmmzauto{cites}
+ variants use the given \refmmzauto{args} unconventionally: they iterate the
+ given pattern as long as the citation arguments continue (see
+ \refcollargs{return} for the gist of how they achieve this).
+
+ When advising new citation commands, the author may override the given
+ \refmmzauto{args} if necessary. In fact, this is what Memoize does do
+ support \cs{citename}, \cs{citelist} and \cs{citefield}. With these
+ commands, the braced \meta{citation key} is followed by optional arguments
+ followed by another braced mandatory argument, which implies |lm| following
+ \refmmzauto{cite}'s \refmmzauto{args}. For example, \cs{citename} is advised
+ by \code{\refmmz{auto}=\braces{%
+ \refmmzauto{cite},
+ \refmmzauto{args}=l\,*m l\,m%
+ }%
+ }.
+\end{doc}
+
+\begin{doc}{
+ key={
+ name=biblatex ccmemo cite,
+ par={%
+ \docAux{
+ of=key:/mmz/biblatex ccmemo cite,
+ value={name=nocite},
+ text=\Alt,
+ value={name=replicate},
+ }
+ },
+ desc={initially \code{nocite}, no default}
+ }
+ }
+ Select the citation command which Memoize puts into the cc-memo in order to
+ broadcast that the citation key was used in the compilation of the extern.
+
+ By default, this citation command is \cs{nocite}. Even if the memoized code
+ uses e.g.\ \cs{textcite}\braces{\meta{citation key}}, the cc-memo contains
+ \code{\cs{nocite}\braces{\meta{citation key}}}. This usually suffices, as we
+ normally only have to inform \pkg{biblatex} that the \meta{citation key} was
+ used in the utilized extern.
+
+ However, in the rare situations where a tracker (page, cite, ibid, opcit,
+ loccit or idem tracker) depends on the citation used in the extern, the
+ \cs{nocite} approach does not suffice. If such tracking is required, the
+ author should issue \code{\refmmz{biblatex ccmemo cite}=\refmmz{biblatex
+ ccmemo cite=replicate}} to have the cc-memo contain the original citation
+ command; note that if the cc-memo was already created, recompilation is
+ necessary.
+
+ The replication approach has the downside of yielding lots of `Missing
+ character' warnings. This happens because, in order to use the original
+ citation command but not produce an actual citation, Memoize precedes the
+ invocation of the original citation command by \cs{nullfont}.
+\end{doc}
+
\section{Varia}
\subsectionclearpagefalse
+
+\subsection{Changelog}
+
+The changelogs of Memoize, Advice and CollArgs can be found in the
+documentation directory of the respective package, i.e.\ in
+\code{\meta{texmf}/doc/generic/\meta{package}/CHANGELOG.md}. They are written
+in the MarkDown format. Here are direct links to these changelogs on
+CTAN:
+\href{https://mirrors.ctan.org/macros/generic/memoize/CHANGELOG.md}{Memoize},
+\href{https://mirrors.ctan.org/macros/generic/advice/CHANGELOG.md}{Advice},
+\href{https://mirrors.ctan.org/macros/generic/collargs/CHANGELOG.md}{CollArgs}.
+
\subsection{Known issues}
\label{sec:known-issues}
@@ -8978,10 +9404,8 @@ regular pages of the document will be of the same size as that extern page.
Due to an unfortunate design decision, CollArgs does not accept a dot |.| as
the \meta{token} argument of types, \docref{xparse:r}, \docref{xparse:R},
-\docref{xparse:d}, \docref{xparse:D}, and \docref{xparse:t}. Furthermore,
-\refcollargs{append prewrap} and friends (and their macro counterparts) do not
-accept a parameter symbol consistently. These issues will be fixed in the next
-release.
+\docref{xparse:d}, \docref{xparse:D}, and \docref{xparse:t}. The issue will be
+fixed in a subsequent release.
\subsection{Troubleshooting}
diff --git a/macros/generic/memoize/doc/memoize-extract.1.md b/macros/generic/memoize/doc/memoize-extract.1.md
index 086e6d9636..e670476441 100644
--- a/macros/generic/memoize/doc/memoize-extract.1.md
+++ b/macros/generic/memoize/doc/memoize-extract.1.md
@@ -2,8 +2,8 @@
title: memoize-extract
section: 1
header: User Manual
-footer: memoize-extract of Memoize v1.1.2
-date: January 21, 2024
+footer: memoize-extract of Memoize v1.2.0
+date: March 15, 2024
hyphenate: false
---
diff --git a/macros/generic/memoize/memoize-clean.pl b/macros/generic/memoize/memoize-clean.pl
index 9d34908a2b..4901a98aa3 100755
--- a/macros/generic/memoize/memoize-clean.pl
+++ b/macros/generic/memoize/memoize-clean.pl
@@ -19,7 +19,7 @@
# <texmf>/doc/generic/memoize/FILES.
my $PROG = 'memoize-clean.pl';
-my $VERSION = '2024/01/21 v1.1.2';
+my $VERSION = '2024/03/15 v1.2.0';
use strict;
use Getopt::Long;
diff --git a/macros/generic/memoize/memoize-clean.py b/macros/generic/memoize/memoize-clean.py
index 1833931bf0..3b70d63a31 100755
--- a/macros/generic/memoize/memoize-clean.py
+++ b/macros/generic/memoize/memoize-clean.py
@@ -18,7 +18,7 @@
# The files belonging to this work and covered by LPPL are listed in
# <texmf>/doc/generic/memoize/FILES.
-__version__ = '2024/01/21 v1.1.2'
+__version__ = '2024/03/15 v1.2.0'
import argparse, re, sys, pathlib, os
diff --git a/macros/generic/memoize/memoize-extract.pl b/macros/generic/memoize/memoize-extract.pl
index 243c02a8f5..d5cd1f9aa4 100755
--- a/macros/generic/memoize/memoize-extract.pl
+++ b/macros/generic/memoize/memoize-extract.pl
@@ -19,7 +19,7 @@
# <texmf>/doc/generic/memoize/FILES.
my $PROG = 'memoize-extract.pl';
-my $VERSION = '2024/01/21 v1.1.2';
+my $VERSION = '2024/03/15 v1.2.0';
use strict;
use File::Basename qw/basename/;
diff --git a/macros/generic/memoize/memoize-extract.py b/macros/generic/memoize/memoize-extract.py
index ac138178fe..962f6380e8 100755
--- a/macros/generic/memoize/memoize-extract.py
+++ b/macros/generic/memoize/memoize-extract.py
@@ -18,7 +18,7 @@
# The files belonging to this work and covered by LPPL are listed in
# <texmf>/doc/generic/memoize/FILES.
-__version__ = '2024/01/21 v1.1.2'
+__version__ = '2024/03/15 v1.2.0'
import argparse, re, sys, os, subprocess, itertools, traceback, platform
from pathlib import Path, PurePath
diff --git a/macros/generic/memoize/memoize.edtx b/macros/generic/memoize/memoize.edtx
index c14b59ae4e..e77be9a39f 100644
--- a/macros/generic/memoize/memoize.edtx
+++ b/macros/generic/memoize/memoize.edtx
@@ -64,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-39}, leftupper=1mm}
+% \tcbinputlisting{raster multicolumn=55, ins listing, top=1mm, bottom=1mm, title=memoize.ins,listing file=../memoize.ins, linerange={27-40}, 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}
@@ -90,55 +90,55 @@
%
% \paragraph{Identification} of |memoize|, |memoizable| and |nomemoize|.
%<*mmz>
-%<latex>\ProvidesPackage{memoize}[2024/01/21 v1.1.2 Fast and flexible externalization]
+%<latex>\ProvidesPackage{memoize}[2024/03/15 v1.2.0 Fast and flexible externalization]
%<context>%D \module[
%<context>%D file=t-memoize.tex,
-%<context>%D version=1.1.2,
+%<context>%D version=1.2.0,
%<context>%D title=Memoize,
%<context>%D subtitle=Fast and flexible externalization,
%<context>%D author=Saso Zivanovic,
-%<context>%D date=2024-01-21,
+%<context>%D date=2024-03-15,
%<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 2024/01/21 v1.1.2
+%<plain>% Package memoize 2024/03/15 v1.2.0
%</mmz>
%<*mmzable>
-%<latex>\ProvidesPackage{memoizable}[2024/01/21 v1.1.2 A programmer's stub for Memoize]
+%<latex>\ProvidesPackage{memoizable}[2024/03/15 v1.2.0 A programmer's stub for Memoize]
%<context>%D \module[
%<context>%D file=t-memoizable.tex,
-%<context>%D version=1.1.2,
+%<context>%D version=1.2.0,
%<context>%D title=Memoizable,
%<context>%D subtitle=A programmer's stub for Memoize,
%<context>%D author=Saso Zivanovic,
-%<context>%D date=2024-01-21,
+%<context>%D date=2024-03-15,
%<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 2024/01/21 v1.1.2
+%<plain>% Package memoizable 2024/03/15 v1.2.0
%</mmzable>
%<*nommz>
-%<latex>\ProvidesPackage{nomemoize}[2024/01/21 v1.1.2 A no-op stub for Memoize]
+%<latex>\ProvidesPackage{nomemoize}[2024/03/15 v1.2.0 A no-op stub for Memoize]
%<context>%D \module[
%<context>%D file=t-nomemoize.tex,
-%<context>%D version=1.1.2,
+%<context>%D version=1.2.0,
%<context>%D title=Memoize,
%<context>%D subtitle=A no-op stub for Memoize,
%<context>%D author=Saso Zivanovic,
-%<context>%D date=2024-01-21,
+%<context>%D date=2024-03-15,
%<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 2024/01/21 v1.1.2
+%<mmz>% Package nomemoize 2024/03/15 v1.2.0
%</nommz>
%
% \paragraph{Required packages} and \hologo{LaTeX}ization of \hologo{plainTeX}
@@ -361,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\mmz@openin0{#2}%
+ \immediate\openin0{#2}%
#1={}%
\loop
\unless\ifeof0
@@ -373,12 +373,6 @@
}
% \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
@@ -583,9 +577,9 @@
}
\def\mmz@remove@quotes@i{%
\CollectArgumentsRaw
- {\collargsBraceCollectedfalse
+ {\collargsReturnPlain
\collargsNoDelimiterstrue
- \collargsAppendPostwrap{{##1}}%
+ \collargsAppendExpandablePostprocessor{{\the\collargsArg}}%
}%
{u"u\mmz@eov}%
\mmz@remove@quotes@ii
@@ -783,11 +777,11 @@
}%
% Spaces at the beginning of the environment body are trimmed by setting
% the first argument to |!t<space>| and disappearing it with
- % |\collargsAppendPostwrap{}|; note that this removes any number of space
+ % |\collargsAppendExpandablePostprocessor{}|; note that this removes any number of space
% tokens. |\CollectArgumentsRaw| automatically adapts the argument type
% |b| to the format.
%
- }{&&{\collargsAppendPostwrap{}}!t{ }+b{memoize}}{\mmz@do}%
+ }{&&{\collargsAppendExpandablePostprocessor{}}!t{ }+b{memoize}}{\mmz@do}%
}%
%</mmz>
% \end{environment}
@@ -1562,7 +1556,7 @@
% |\mmzCMemo|.
\def\mmz@write@cmemo{%
% Open the file for writing.
- \immediate\mmz@openout\mmz@out{\mmz@cmemo@path}%
+ \immediate\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
@@ -1714,7 +1708,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\mmz@openout\mmz@out{\mmz@ccmemo@path}%
+ \immediate\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
@@ -2428,7 +2422,7 @@
% the external scripts).
\def\mmz@clear@extraction@log{%
\begingroup
- \immediate\mmz@openout0{\jobname.mmz.log}%
+ \immediate\openout0{\jobname.mmz.log}%
\immediate\closeout0
\endgroup
}
@@ -2544,7 +2538,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\mmz@openout\mmz@mmzout{\jobname.mmz}%
+ \immediate\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
@@ -2567,6 +2561,8 @@
\immediate\write\mmz@mmzout{%
\noexpand\mmzNewExtern{#1}{\pagenumber}{\expectedwidth}{\expectedheight}%
}%
+ % Support |latexmk|:
+ %<latex>\typeout{No file #1}%
},
record/mmz/new cmemo/.code={%
\immediate\write\mmz@mmzout{\noexpand\mmzNewCMemo{#1}}%
@@ -2607,7 +2603,7 @@
% \begin{key}{record/sh/...} Define the Linux shell script record type.
record/sh/begin/.code={%
\newwrite\mmz@shout
- \immediate\mmz@openout\mmz@shout{\mmz@shname}%
+ \immediate\openout\mmz@shout{\mmz@shname}%
},
record/sh/new extern/.code={%
\begingroup
@@ -2626,7 +2622,7 @@
% Rinse and repeat for Windows.
record/bat/begin/.code={%
\newwrite\mmz@batout
- \immediate\mmz@openout\mmz@batout{\mmz@batname}%
+ \immediate\openout\mmz@batout{\mmz@batname}%
},
record/bat/new extern/.code={%
\begingroup
@@ -2664,7 +2660,7 @@
% variables |.DEFAULT_GOAL| and |.PHONY|.
\newwrite\mmz@makefileout
\newtoks\mmz@makefile@externs
- \immediate\mmz@openout\mmz@makefileout{\mmz@makefilename}%
+ \immediate\openout\mmz@makefileout{\mmz@makefilename}%
\immediate\write\mmz@makefileout{.DEFAULT_GOAL = externs}%
\immediate\write\mmz@makefileout{.PHONY: externs}%
},
@@ -3401,6 +3397,57 @@
outer handler=\global\advance\mmzExtraPages1\relax\AdviceOriginal}}
%</latex>
%
+% Utility macro for clarity below. |#1| is the name of the package which should
+% be loaded (used with \hologo{LaTeX}) and |#2| is the name of the command
+% which should be defined (used with \hologo{plainTeX} and \hologo{ConTeXt})
+% for |#3| to be executed at the beginning of the document. We make sure that
+% we can use |#1| etc.\ inside |#3|.
+\def\mmz@if@package@loaded#1#2#3{%
+ \mmzset{%
+ begindocument/before/.append code={%
+ %<latex>\@ifpackageloaded{#1}{%
+ %<plain,context>\ifdefined#2%
+ #3%
+ %<plain,context>\fi
+ %<latex>}{}%
+ }%
+ }%
+}
+%
+% \subsection{\pkg{PGF}}
+%
+\mmz@if@package@loaded{pgf}{%
+ %<plain>\pgfpicture
+ %<context>\startpgfpicture
+}{%
+ \def\mmzPgfAtBeginMemoization{%
+ \edef\mmz@pgfpictureid{%
+ \the\pgf@picture@serial@count
+ }%
+ }%
+ \def\mmzPgfAtEndMemoization{%
+ \edef\mmz@temp{%
+ \the\numexpr\pgf@picture@serial@count-\mmz@pgfpictureid\relax
+ }%
+ \ifx\mmz@temp=0
+ \else
+ \xtoksapp\mmzCCMemo{%
+ \unexpanded{%
+ \global\expandafter\advance\csname pgf@picture@serial@count\endcsname
+ }%
+ \mmz@temp
+ }%
+ \fi
+ }%
+ % \begin{listingregion}{_support-pgf.tex}
+ \mmzset{%
+ at begin memoization=\mmzPgfAtBeginMemoization,
+ at end memoization=\mmzPgfAtEndMemoization,
+ }%
+ % \end{listingregion}
+}
+%
+%
% \subsection{\TikZ;}
% \label{sec:code:mmz:tikz}
%
@@ -3408,32 +3455,16 @@
% 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.
-\mmzset{
- begindocument/before/.append code={%
- %<latex>\@ifpackageloaded{tikz}{%
- %<plain,context>\ifdefined\tikz
- \input advice-tikz.code.tex
- %<latex>}{}%
- %<plain,context>\fi
- % We define and activate the automemoization handlers for the \TikZ; command
- % and environment.
- \mmzset{%
- 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@if@package@loaded{tikz}{\tikz}{%
+ \input advice-tikz.code.tex
+ % We define and activate the automemoization handlers for the \TikZ; command
+ % and environment.
+ % \begin{listingregion}{_support-tikz.tex}
+ \mmzset{%
+ auto={tikzpicture}{memoize},
+ auto=\tikz{memoize, collector=\AdviceCollectTikZArguments},
+ }%
+ % \end{listingregion}
}
%
%
@@ -3441,18 +3472,16 @@
% \label{sec:code:forest}
%
% Forest will soon feature extensive memoization support, but for now, let's
-% just enable the basic, single extern externalization.
+% just enable the basic, single extern externalization. Command |\Forest| is
+% defined using |xparse|, so |args| is unnecessary.
%<*latex>
-\mmzset{
- begindocument/before/.append code={%
- \@ifpackageloaded{forest}{%
- \mmzset{
- auto={forest}{memoize},
-% Yes, |\Forest| is defined using |xparse|.
- auto=\Forest{memoize},
- }%
- }{}%
- },
+\mmz@if@package@loaded{forest}{\Forest}{%
+ % \begin{listingregion}{_support-forest.tex}
+ \mmzset{
+ auto={forest}{memoize},
+ auto=\Forest{memoize},
+ }%
+ % \end{listingregion}
}
%</latex>
%
@@ -3502,69 +3531,176 @@
}{}}
%</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},
- }%
+ biblatex/.code={%
+ \mmz@if@package@loaded{biblatex}{}{%
+ \input memoize-biblatex.code.tex
+ \mmzset{#1}%
+ }%
+ },
}
+%</latex>
+%</mmz>
+%<*biblatex>
+\edef\memoizeresetatcatcode{\catcode`\noexpand\@\the\catcode`\@\relax}%
+\catcode`\@=11
+\mmzset{%
+ % Advise macro |\entry| occuring in |.bbl| files to collect the entry,
+ % verbatim. |args|: |m| = citation key, |&&{...}u| = the entry, verbatim,
+ % braced --- so |\blx@bbl@entry| will receive two mandatory arguments.
+ auto=\blx@bbl@entry{
+ inner handler=\mmz@biblatex@entry,
+ args={%
+ m%
+ &&{\collargsVerb
+ \collargsAppendExpandablePostprocessor{{\the\collargsArg}}%
+ }u{\endentry}%
+ },
+ % No braces around the collected arguments, as each is already braced on
+ % its own.
+ raw collector options=\collargsReturnPlain,
+ },
+ % \begin{mmzautokey}{cite,volcite,cites,volcites}
+ % Define handlers for citation commands.
+ auto/cite/.style={
+ run conditions=\mmz@biblatex@cite@rc,
+ outer handler=\mmz@biblatex@cite@outer,
+ args=l*m,
+ raw collector options=\mmz@biblatex@def@star\collargsReturnNo,
+ inner handler=\mmz@biblatex@cite@inner,
+ },
+ % We need a dedicated |volcite| even though |\volcite| executes |\cite|
+ % because otherwise, we would end up with |\cite{volume}{key}| in the cc-memo
+ % when |biblatex ccmemo cite=replicate|.
+ auto/volcite/.style={
+ run if memoizing,
+ outer handler=\mmz@biblatex@cite@outer,
+ args=lml*m,
+ raw collector options=\mmz@biblatex@def@star\collargsReturnNo,
+ inner handler=\mmz@biblatex@cite@inner,
+ },
+ auto/cites/.style={
+ run conditions=\mmz@biblatex@cite@rc,
+ outer handler=\mmz@biblatex@cites@outer,
+ args=l*m,
+ raw collector options=\mmz@biblatex@def@star\collargsClearArgsfalse\collargsReturnNo,
+ inner handler=\mmz@biblatex@cites@inner,
+ },
+ auto/volcites/.style={
+ run if memoizing,
+ outer handler=\mmz@biblatex@cites@outer,
+ args=lml*m,
+ raw collector options=\mmz@biblatex@def@star\collargsClearArgsfalse\collargsReturnNo,
+ inner handler=\mmz@biblatex@cites@inner,
+ },
+ % \end{mmzautokey}
+ % \begin{mmzautokey}{biblatex ccmemo cite}
+ % What to put into the cc-memo, |\nocite| or the handled citation command?
+ biblatex ccmemo cite/.is choice,
+ biblatex ccmemo cite/nocite/.code={%
+ \let\mmz@biblatex@do@ccmemo\mmz@biblatex@do@nocite
+ },
+ biblatex ccmemo cite/replicate/.code={%
+ \let\mmz@biblatex@do@ccmemo\mmz@biblatex@do@replicate
+ },
+ % \end{mmzautokey}
+}%
% \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{%
- \protected@edef\mmz@temp{\pdf@mdfivesum{#2}}%
+\def\mmz@biblatex@entry#1#2{%
+ \edef\mmz@temp{\pdf@mdfivesum{#2}}%
\global\cslet{mmz@bbl@#1}\mmz@temp
- \AdviceOriginal{#1}#2\endentry
+ \mmz@scantokens{\AdviceOriginal{#1}#2}%
}
% \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}%
+% \begin{macro}{\mmz@biblatex@cite@rc}
+% Run if memoizing but not within a |\volcite| command. Applied to |\cite(s)|.
+\def\mmz@biblatex@cite@rc{%
+ \ifmemoizing
+ % We cannot use the official |\ifvolcite|, or even the |blx@volcite| toggle
+ % it depends on, because these are defined\slash set within the
+ % next-citation hook, which is yet to be executed. So we depend on the
+ % internal detail that |\volcite| and friends redefine |\blx@citeargs| to
+ % |\blx@volciteargs|.
+ \ifx\blx@citeargs\blx@volciteargs
+ \else
+ \AdviceRuntrue
+ \fi
+ \fi
+}
+% \end{macro}
+% \begin{macro}{\mmz@biblatex@cite@outer}
+% Initialize the macro receiving the citation key(s), and execute the
+% collector.
+\def\mmz@biblatex@cite@outer{%
+ \gdef\mmz@biblatex@keys{}%
+ \AdviceCollector
+}
+% \end{macro}
+% \begin{macro}{\mmz@biblatex@mark@citation@key}
+% We \emph{append} to |\mmz@biblatex@keys| to automatically collect all
+% citation keys of a |\cites| command; note that we use this system for
+% |\cite| as well.
+\def\mmz@biblatex@def@star{%
+ \collargsAlias{*}{&&{\mmz@biblatex@mark@citation@key}}%
}
-\def\mmz@biblatex@cite@do@key#1{%
+\def\mmz@biblatex@mark@citation@key{%
+ \collargsAppendPreprocessor{\xappto\mmz@biblatex@keys{,\the\collargsArg}}%
+}
+% \end{macro}
+% \begin{macro}{\mmz@biblatex@cite@inner}
+\def\mmz@biblatex@cite@inner{%
+ % This macro puts the cites reference keys into the context, and adds
+ % |\nocite|, or the handled citation command, to the cc-memo.
+ \mmz@biblatex@do@context
+ \mmz@biblatex@do@ccmemo
+ \expandafter\AdviceOriginal\the\collargsArgs
+}
+\def\mmz@biblatex@do@context{%
+ \expandafter\forcsvlist
+ \expandafter\mmz@biblatex@do@context@one
+ \expandafter{\mmz@biblatex@keys}%
+}
+\def\mmz@biblatex@do@context@one#1{%
\mmz@mtoc@csname{mmz@bbl@#1}%
\ifcsdef{mmz@bbl@#1}{}{\mmzAbort}%
}
+\def\mmz@biblatex@do@nocite{%
+ \xtoksapp\mmzCCMemo{%
+ \noexpand\nocite{\mmz@biblatex@keys}%
+ }%
+}
+\def\mmz@biblatex@do@replicate{%
+ \xtoksapp\mmzCCMemo{%
+ {%
+ \nullfont
+ % It is ok to use |\AdviceName| here, as the cc-memo is never input
+ % during memoization.
+ \expandonce\AdviceName\the\collargsArgs
+ }%
+ }%
+}
+\let\mmz@biblatex@do@ccmemo\mmz@biblatex@do@nocite
% \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
+% \begin{macro}{\mmz@biblatex@cites@outer}
+% Same as for |cite|, but we iterate the collector as long as the arguments
+% continue.
+\def\mmz@biblatex@cites@outer{%
+ \global\collargsArgs{}%
+ \gdef\mmz@biblatex@keys{}%
+ \AdviceCollector
}
-\def\mmz@biblatex@cites@i{%
- \futurelet\mmz@temp\mmz@biblatex@cites@ii
+\def\mmz@biblatex@cites@inner{%
+ \futurelet\mmz@temp\mmz@biblatex@cites@inner@again
}
-\def\mmz@biblatex@cites@ii{%
+% If the following token is an opening brace or bracket, the
+% multicite arguments continue.
+\def\mmz@biblatex@cites@inner@again{%
\mmz@tempfalse
\ifx\mmz@temp\bgroup
\mmz@temptrue
@@ -3574,26 +3710,97 @@
\fi
\fi
\ifmmz@temp
- \expandafter\mmz@biblatex@cites@iii
+ \expandafter\AdviceCollector
\else
- \expandafter\mmz@biblatex@cites@z
+ \expandafter\mmz@biblatex@cites@inner@finish
\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
+\def\mmz@biblatex@cites@inner@finish{%
+ \mmz@biblatex@do@context
+ \mmz@biblatex@do@ccmemo
+ \expandafter\AdviceOriginal\the\collargsArgs
}
-%</latex>
% \end{macro}
+%
+% \paragraph{Advise} the citation commands.
+\mmzset{
+ auto=\cite{cite},
+ auto=\Cite{cite},
+ auto=\parencite{cite},
+ auto=\Parencite{cite},
+ auto=\footcite{cite},
+ auto=\footcitetext{cite},
+ auto=\textcite{cite},
+ auto=\Textcite{cite},
+ auto=\smartcite{cite},
+ auto=\Smartcite{cite},
+ auto=\supercite{cite},
+ auto=\cites{cites},
+ auto=\Cites{cites},
+ auto=\parencites{cites},
+ auto=\Parencites{cites},
+ auto=\footcites{cites},
+ auto=\footcitetexts{cites},
+ auto=\smartcites{cites},
+ auto=\Smartcites{cites},
+ auto=\textcites{cites},
+ auto=\Textcites{cites},
+ auto=\supercites{cites},
+ auto=\autocite{cite},
+ auto=\Autocite{cite},
+ auto=\autocites{cites},
+ auto=\Autocites{cites},
+ auto=\citeauthor{cite},
+ auto=\Citeauthor{cite},
+ auto=\citetitle{cite},
+ auto=\citeyear{cite},
+ auto=\citedate{cite},
+ auto=\citeurl{cite},
+ auto=\nocite{cite},
+ auto=\fullcite{cite},
+ auto=\footfullcite{cite},
+ auto=\volcite{volcite},
+ auto=\Volcite{volcite},
+ auto=\volcites{volcites},
+ auto=\Volcites{volcites},
+ auto=\pvolcite{volcite},
+ auto=\Pvolcite{volcite},
+ auto=\pvolcites{volcites},
+ auto=\Pvolcites{volcites},
+ auto=\fvolcite{volcite},
+ auto=\Fvolcite{volcite},
+ auto=\fvolcites{volcites},
+ auto=\Fvolcites{volcites},
+ auto=\ftvolcite{volcite},
+ auto=\ftvolcites{volcites},
+ auto=\Ftvolcite{volcite},
+ auto=\Ftvolcites{volcites},
+ auto=\svolcite{volcite},
+ auto=\Svolcite{volcite},
+ auto=\svolcites{volcites},
+ auto=\Svolcites{volcites},
+ auto=\tvolcite{volcite},
+ auto=\Tvolcite{volcite},
+ auto=\tvolcites{volcites},
+ auto=\Tvolcites{volcites},
+ auto=\avolcite{volcite},
+ auto=\Avolcite{volcite},
+ auto=\avolcites{volcites},
+ auto=\Avolcites{volcites},
+ auto=\notecite{cite},
+ auto=\Notecite{cite},
+ auto=\pnotecite{cite},
+ auto=\Pnotecite{cite},
+ auto=\fnotecite{cite},
+ % Similar to |volcite|, these commands must be handled specifically in order
+ % to function correctly with |biblatex ccmemo cite=replicate|.
+ auto=\citename{cite, args=l*mlm},
+ auto=\citelist{cite, args=l*mlm},
+ auto=\citefield{cite, args=l*mlm},
+}
+\memoizeresetatcatcode
+%</biblatex>
+%<*mmz>
%
%
% \section{Initialization}
@@ -3627,6 +3834,14 @@
end document/.style={enddocument/afterlastpage},
}
%</plain,context>
+% We clear the hooks after executing the last of them.
+\mmzset{
+ begindocument/end/.append style={
+ begindocument/before/.code={},
+ begindocument/.code={},
+ begindocument/end/.code={},
+ }
+}
% \end{key}
%
% Formats other than \hologo{plainTeX} need a way to prevent extraction during
diff --git a/macros/generic/memoize/memoize.ins b/macros/generic/memoize/memoize.ins
index 2c24ac368b..74b0bc1b3e 100644
--- a/macros/generic/memoize/memoize.ins
+++ b/macros/generic/memoize/memoize.ins
@@ -36,5 +36,6 @@
\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}}%
+ \file{memoize-biblatex.code.tex}{\from{memoize.dtx}{biblatex}}%
}
\endbatchfile