summaryrefslogtreecommitdiff
path: root/macros/generic/advice
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2024-01-03 03:03:02 +0000
committerNorbert Preining <norbert@preining.info>2024-01-03 03:03:02 +0000
commit92effab22b73c432933e7eb8e12c1cefda221df9 (patch)
treecdf3576ee645074d1df994e376d9ca2483c81ec5 /macros/generic/advice
parent6b10e9901a24325e837f0fdc2cbce8f43f18ccff (diff)
CTAN sync 202401030303
Diffstat (limited to 'macros/generic/advice')
-rw-r--r--macros/generic/advice/CHANGELOG.md9
-rw-r--r--macros/generic/advice/advice.edtx129
2 files changed, 94 insertions, 44 deletions
diff --git a/macros/generic/advice/CHANGELOG.md b/macros/generic/advice/CHANGELOG.md
index 63de5163a9..f112324840 100644
--- a/macros/generic/advice/CHANGELOG.md
+++ b/macros/generic/advice/CHANGELOG.md
@@ -14,6 +14,15 @@ those cases, please see [Memoize's GitHub
repository](https://github.com/sasozivanovic/memoize) for the recent
development history.
+## 2024/01/02 v1.1.0
+* Implement `\AdviceCsnameGetOriginal`.
+* Change `\AdviceGetOriginal` to expand to the internal control sequence
+ holding the original definition of the advised command under full expansion.
+* Add the missing info messages for environment (de)activation.
+* Add the original command meaning to trace.
+
+Manual: Memoize 2024/01/02 v1.1.0
+
## 2023/10/25 v1.0.1
* Require package `xparse`, as `\GetDocumentCommandArgSpec` is being dropped
from the LaTeX kernel.
diff --git a/macros/generic/advice/advice.edtx b/macros/generic/advice/advice.edtx
index dcbdfb297e..415d9da79b 100644
--- a/macros/generic/advice/advice.edtx
+++ b/macros/generic/advice/advice.edtx
@@ -29,14 +29,14 @@
% \relax
%
%<*main>
-%<latex>\ProvidesPackage{advice}[2023/10/25 v1.0.1 Extend commands and environments]
+%<latex>\ProvidesPackage{advice}[2024/01/02 v1.1.0 Extend commands and environments]
%<context>%D \module[
%<context>%D file=t-advice.tex,
-%<context>%D version=1.0.1,
+%<context>%D version=1.1.0,
%<context>%D title=Advice,
%<context>%D subtitle=Extend commands and environments,
%<context>%D author=Saso Zivanovic,
-%<context>%D date=2023-10-25,
+%<context>%D date=2024-01-02,
%<context>%D copyright=Saso Zivanovic,
%<context>%D license=LPPL,
%<context>%D ]
@@ -96,7 +96,9 @@
% namespace is hard-coded into these keys via |#1|; their arguments are
% the command/environment (cs)name, and setup keys belonging to path
% \meta{installation keypath}|/\meta{setup key name}|.
+ % \indentmacrocode
#2/.code 2 args={%
+ % \noindentmacrocode
% Call the internal setup macro, wrapping the received keylist into a
% |pgfkeys| invocation.
\AdviceSetup{#1}{#2}{##1}{\pgfqkeys{#1/#2}{##2}}%
@@ -151,7 +153,7 @@
% defined right away, as they don't change with the type of activation
% (immediate vs.\ deferred).
activate csname/.style={activate/.expand once={\csname##1\endcsname}},
- deactivate csname/.style={activate/.expand once={\csname##1\endcsname}},
+ deactivate csname/.style={deactivate/.expand once={\csname##1\endcsname}},
% \end{key}
%
% \begin{key}{activate key, deactivate key}
@@ -178,7 +180,8 @@
% These keys are used to setup the handling of the command or
% environment. The storage macros (|\AdviceRunConditions| etc.) have
% public names as they also play a crucial role in the handler
- % definitions, see section~\ref{sec:code:advice:handle}. \indentmacrocode
+ % definitions, see section~\ref{sec:code:advice:handle}.
+ % \indentmacrocode[-0.5em]
run conditions/.store in=\AdviceRunConditions,
bailout handler/.store in=\AdviceBailoutHandler,
outer handler/.store in=\AdviceOuterHandler,
@@ -215,7 +218,7 @@
reset/.code={\csname\advice@setup@init@\AdviceType\endcsname},
% \end{mmzautokey}
%
- % \begin{mmzautokey}
+ % \begin{mmzautokey}{after setup}
% The code given here will be executed once we exit the setup group.
% |integrated driver| of Memoize uses it to declare a conditional.
after setup/.code={\appto\AdviceAfterSetup{##1}},
@@ -257,6 +260,7 @@
% Open a group, so that we allow for embedded |auto| invocations.
\begingroup
\def\AdviceName{#3}%
+ \advice@def@AdviceCsname
% Command, complain, or environment?
\collargs@cs@cases{#3}{%
\def\AdviceType{command}%
@@ -399,7 +403,8 @@
\noexpand\csdef{advice@I#1//\string#2}{%
\def\noexpand\AdviceOuterHandler{\expandonce\AdviceOuterHandler}%
\def\noexpand\AdviceCollector{\expandonce\AdviceCollector}%
- \def\noexpand\AdviceRawCollectorOptions{\expandonce\AdviceRawCollectorOptions}%
+ \def\noexpand\AdviceRawCollectorOptions{%
+ \expandonce\AdviceRawCollectorOptions}%
\def\noexpand\AdviceCollectorOptions{\expandonce\AdviceCollectorOptions}%
\def\noexpand\AdviceArgs{\expandonce\AdviceArgs}%
\def\noexpand\AdviceInnerHandler{\expandonce\AdviceInnerHandler}%
@@ -412,9 +417,9 @@
% \label{sec:code:advice:activation}
%
% \begin{advicekey}{activation/immediate, activation/deferred}
-% The two subkeys of |/advice/activation| install the immediate and the
+% These two subkeys of |/advice/activation| install the immediate and the
% deferred activation code into the installation keypath. They are invoked
-% by \meta{installation keypath}|/activation=|\meta{type}.
+% by key \meta{installation keypath}|/activation=|\meta{type}.
%
% Under the deferred activation regime, the commands are not (de)activated
% right away. Rather, the (de)activation calls are collected in style
@@ -490,9 +495,27 @@
\def\advice@original@cs#1#2{\csname advice@o#1//\string#2\endcsname}
\def\AdviceGetOriginal#1#2{%
\ifcsname advice@o#1//\string#2\endcsname
- \csname advice@o#1//\string#2\expandafter\endcsname
+ \expandonce{\csname advice@o#1//\string#2\expandafter\endcsname\expandafter}%
\else
- \expandafter#2%
+ \expandafter\noexpand\expandafter#2%
+ \fi
+}
+% \end{macro}
+%
+% \begin{macro}{\AdviceCsnameGetOriginal}
+% A version of |\AdviceGetOriginal| which accepts a control sequence name as
+% the second argument.
+\begingroup
+\catcode`\/=0
+\catcode`\\=12
+/gdef/advice@backslash@other{\}%
+/endgroup
+\def\AdviceCsnameGetOriginal#1#2{%
+ \ifcsname advice@o#1//\advice@backslash@other#2\endcsname
+ \expandonce{\csname advice@o#1//\advice@backslash@other#2\expandafter\endcsname
+ \expandafter}%
+ \else
+ \expandonce{\csname#2\expandafter\endcsname\expandafter}%
\fi
}
% \end{macro}
@@ -696,6 +719,7 @@
\def\advice@handle@outer#1#2{%
\def\AdviceNamespace{#1}%
\def\AdviceName{#2}%
+ \advice@def@AdviceCsname
\let\AdviceReplaced\AdviceName
\def\AdviceOriginal{\AdviceGetOriginal{#1}{#2}}%
% We then load the stage-two settings. This defines the following macros:
@@ -724,6 +748,14 @@
% All prepared, we execute the outer handler.
\AdviceOuterHandler
}
+\def\advice@def@AdviceCsname{%
+ \begingroup
+ \escapechar=-1
+ \expandafter\expandafter\expandafter\endgroup
+ \expandafter\expandafter\expandafter\def
+ \expandafter\expandafter\expandafter\AdviceCsname
+ \expandafter\expandafter\expandafter{\expandafter\string\AdviceName}%
+}
% \end{macro}
%
% \begin{macro}{\ifAdviceRun}
@@ -745,18 +777,22 @@
% CollArgs' command |\CollectArgumentsRaw|. It will provide that command
% with:
% \begin{itemize}
-% \item the collector options, given in the raw format: the caller
-% (|\collargsCaller|), the raw options (|\AdviceRawCollectorOptions|) and the
-% user options (|\AdviceRawCollectorOptions|, wrapped in |\collargsSet|;
+% \item the collector options, given in the raw format:
+% \begin{itemize}
+% \item the caller (|\collargsCaller|),
+% \item the raw options (|\AdviceRawCollectorOptions|), and
+% \item the user options (|\AdviceRawCollectorOptions|, wrapped in
+% |\collargsSet|;
+% \end{itemize}
% \item the argument specification |\AdviceArgs| of the handled command; and
% \item the inner handler |\AdviceInnerHandler| to execute after collecting the
% arguments; the inner handler receives the collected arguments as a single
% braced argument.
% \end{itemize}
-% If the argument specification is not defined (either the user did not set
-% it, or has reset it by writing |args| without a value), it is assumed that
-% the handled command was defined by |xparse| and |\AdviceArgs| will be
-% retrieved by |\GetDocumentCommandArgSpec|.
+% \hangindent=0pt If the argument specification is not defined (either the user
+% did not set it, or has reset it by writing |args| without a value), it is
+% assumed that the handled command was defined by |xparse| and |\AdviceArgs|
+% will be retrieved by |\GetDocumentCommandArgSpec|.
% \begin{listingregion}{_advice-CollectArgumentsRaw.tex}
\def\advice@CollectArgumentsRaw{%
\AdviceIfArgs{}{%
@@ -845,6 +881,7 @@
\advice@activate@error@activated{#1}{#2}{Environment}{already}%
}{%
\csdef{\advice@original@csname{#1}{#2}}{}%
+ \PackageInfo{advice (#1)}{Activated environment "#2"}%
}%
}
\def\advice@deactivate@env#1#2{%
@@ -852,6 +889,7 @@
\csundef{\advice@original@csname{#1}{#2}}{}%
}{%
\advice@activate@error@activated{#1}{#2}{Environment}{not yet}%
+ \PackageInfo{advice (#1)}{Dectivated environment "#2"}%
}%
}
% \end{macro}
@@ -911,6 +949,7 @@
\def\advice@begin@env@outer#1#2#3{%
\def\AdviceNamespace{#1}%
\def\AdviceName{#3}%
+ \let\AdviceCsname\advice@undefined
\def\AdviceReplaced{#2{#3}}%
\def\AdviceOriginal{\AdviceGetOriginal{#1}{#2}{#3}}%
\advice@init@I{#1}{#3}%
@@ -1000,6 +1039,8 @@
% Install the tracing code.
\def\advice@trace@init@i#1#2{%
\advice@trace{Advising \detokenize\expandafter{\string#2} (\detokenize{#1})}%
+ \advice@trace{\space\space Original command meaning:
+ \expandafter\expandafter\expandafter\meaning\advice@original@cs{#1}{#2}}%
\advice@setup@init@i{#1}{#2}%
\edef\AdviceRunConditions{%
% We first execute the original run conditions, so that we can show the
@@ -1032,13 +1073,13 @@
Executing collector:
\detokenize\expandafter{\AdviceCollector}}%
\noexpand\advice@trace{\space\space\space\space
- argument specification:
+ Argument specification:
\detokenize\expandafter{\AdviceArgs}}%
\noexpand\advice@trace{\space\space\space\space
- options:
+ Options:
\detokenize\expandafter{\AdviceCollectorOptions}}%
\noexpand\advice@trace{\space\space\space\space
- raw options:
+ Raw options:
\detokenize\expandafter{\AdviceRawCollectorOptions}}%
\expandonce\AdviceCollector
}%
@@ -1052,7 +1093,7 @@
Received arguments:
\noexpand\detokenize{##1}}%
\noexpand\advice@trace{\space\space\space\space
- options:
+ Options:
\detokenize\expandafter{\AdviceOptions}}%
\expandonce{\AdviceInnerHandler}{##1}%
}%
@@ -1079,38 +1120,38 @@
% The \TikZ; code resides in a special file. It is meant to be |\input| at any
% time, so we need to temporarily assign |@| category code 11.
%<*tikz>
-\edef\mmzresetatcatcode{\catcode`\noexpand\@\the\catcode`\@\relax}%
+\edef\adviceresetatcatcode{\catcode`\noexpand\@\the\catcode`\@\relax}%
\catcode`\@=11
\def\AdviceCollectTikZArguments{%
-% We initialize the token register which will hold the collected arguments, and
-% start the collection. Nothing of note happens until \dots
- \mmz@temptoks={}%
- \mmz@tikz@anim
+ % We initialize the token register which will hold the collected arguments,
+ % and start the collection. Nothing of note happens until \dots
+ \toks0={}%
+ \advice@tikz@anim
}
-\def\mmz@tikz@anim{%
- \pgfutil@ifnextchar[{\mmz@tikz@opt}{%
- \pgfutil@ifnextchar:{\mmz@tikz@anim@a}{%
- \mmz@tikz@code}}%]
+\def\advice@tikz@anim{%
+ \pgfutil@ifnextchar[{\advice@tikz@opt}{%
+ \pgfutil@ifnextchar:{\advice@tikz@anim@a}{%
+ \advice@tikz@code}}%]
}
-\def\mmz@tikz@anim@a#1=#2{%
- \toksapp\mmz@temptoks{#1={#2}}%
- \mmz@tikz@anim
+\def\advice@tikz@anim@a#1=#2{%
+ \toksapp0{#1={#2}}%
+ \advice@tikz@anim
}
-\def\mmz@tikz@opt[#1]{%
- \toksapp\mmz@temptoks{[#1]}%
- \mmz@tikz@code
+\def\advice@tikz@opt[#1]{%
+ \toksapp0{[#1]}%
+ \advice@tikz@code
}
-\def\mmz@tikz@code{%
- \pgfutil@ifnextchar\bgroup\mmz@tikz@braced\mmz@tikz@single
+\def\advice@tikz@code{%
+ \pgfutil@ifnextchar\bgroup\advice@tikz@braced\advice@tikz@single
}
-\long\def\mmz@tikz@braced#1{\toksapp\mmz@temptoks{{#1}}\mmz@tikz@done}
-\def\mmz@tikz@single#1;{\toksapp\mmz@temptoks{#1;}\mmz@tikz@done}
+\long\def\advice@tikz@braced#1{\toksapp0{{#1}}\advice@tikz@done}
+\def\advice@tikz@single#1;{\toksapp0{#1;}\advice@tikz@done}
% \dots\ we finish collecting the arguments, when we execute the inner handler,
% with the (braced) collected arguments is its sole argument.
-\def\mmz@tikz@done{%
- \expandafter\AdviceInnerHandler\expandafter{\the\mmz@temptoks}%
+\def\advice@tikz@done{%
+ \expandafter\AdviceInnerHandler\expandafter{\the\toks0}%
}
-\mmzresetatcatcode
+\adviceresetatcatcode
%</tikz>
% \end{macrocode}
%