From 186d4646c7e3708019cccdcf98a635fb29d668f3 Mon Sep 17 00:00:00 2001 From: Frank Mittelbach Date: Wed, 23 Oct 2024 08:41:36 +0200 Subject: [PATCH 1/2] Gh1501 gh1091 and gh1430 (#1506) * doc for #1501 * grumble * also add docu for #1091 and #1430 --- base/changes.txt | 9 ++++-- base/ltcmdhooks.dtx | 78 +++++++++++++++++++++++++++++++++++++++------ 2 files changed, 75 insertions(+), 12 deletions(-) diff --git a/base/changes.txt b/base/changes.txt index 09851d532..18593c367 100644 --- a/base/changes.txt +++ b/base/changes.txt @@ -5,6 +5,12 @@ hotfixes). It is provided for convenience only. It therefore makes no claims to completeness or accuracy and it contains some references to files that are not part of the distribution. ================================================================================ + +2024-10-22 Frank Mittelbach + * ltcmdhooks.dtx: + Some clarification why not all + commands allow generic cmd hooks (gh/1091, gh/1430 and gh/1501) + 2024-10-22 Ulrike Fischer * ltshipout.dtx: correct documentation (gh/1470). @@ -21,7 +27,7 @@ not part of the distribution. Correct passing of token list content using \KeyValue 2024-10-02 Ulrike Fischer - * lttagging.dtx: restore also paratagging in the para/restore socket, + * lttagging.dtx: restore also paratagging in the para/restore socket, see https://github.com/latex3/tagging-project/issues/723 2024-09-25 Matthew Bertucci @@ -40,7 +46,6 @@ not part of the distribution. Use sockets in \refstepcounter for target and tagging support. * ltmeta.dtx: move patches and change of \MakeLinkTarget from latex-lab. * lttagging.dtx: add tagging socket for targets. - 2024-09-15 Joseph Wright * lttemplates-doc.tex, lttemplates-code.tex: diff --git a/base/ltcmdhooks.dtx b/base/ltcmdhooks.dtx index e8793817d..0d14ebfe6 100644 --- a/base/ltcmdhooks.dtx +++ b/base/ltcmdhooks.dtx @@ -20,7 +20,7 @@ %<*driver> % \fi \ProvidesFile{ltcmdhooks.dtx} - [2024/07/08 v1.0j LaTeX Kernel (Command hooks)] + [2024/10/22 v1.0j LaTeX Kernel (Command hooks)] % \iffalse % \documentclass{l3doc} @@ -68,7 +68,15 @@ % supported % for all types of commands, see section~\ref{sec:look-ahead} for % the restrictions that apply and what happens if one tries to use -% this with commands for which this is not supported.} These are: +% this with commands for which this is not supported.} +% +% However, this is only true \enquote{in theory}. In practice there +% are a number of restrictions that makes it impossible to use such +% generic command hooks in a number of cases, so please read all +% of section~\ref{sec:restrictions} to understand what may prevent +% you from using them successfully. +% +% The generic command hooks are: % \begin{description} % \item[\hook{cmd/\meta{name}/before}] % @@ -152,7 +160,55 @@ % and \TeX{} doesn't have a reliable way to see that, so some guesswork % has to be employed. % -% \subsection{Patching} +% We can do this in most cases when commands are defined using +% \cs{NewDocumentCommand} or \cs{newcommand} (with a few exceptions). +% For commands defined with \tn{def} the situation is less good. +% Common cases where the command hooks will not work are: +% \begin{itemize} +% \item +% +% Commands that use special catcode settings within their +% definition. In that case it is usually not possible to augment the +% definition (see~\ref{sec:patching}). +% +% \item +% +% If a command is defined while \cs{ExplSyntaxOn} is in force +% \textbf{and} the command contains \verb=~= characters to represent +% spaces, then it can't be patched to include the command hooks. In +% fact in some very special circumstances you might even get a +% low-level error rather than the information that the command can't +% be patched (see, for example, +% \url{https://github.com/latex3/latex2e/issues/1430}. +% +% \item +% +% Commands that have arguments as far as the user is concerned +% (e.g., \cs{section} or \cs{caption}), but are defined in a way that these +% arguments are not read by the user level command but only later +% during the processing. In that case the \texttt{after} hook +% doesn't work at all. The \text{before} hook only works with +% \cs{AddToHook} but not with \cs{AddToHookWithArguments} because the +% arguments haven't been read at that point where the hook is +% patched in. See +% section~\ref{sec:look-ahead}. +% +% +% \item +% Adding a specific generic command hook is only attempted once per +% command, thus after redefining a command such hooks will no longer +% be there and will also not being re-added, see section~\ref{sec:timing}. +% +% \end{itemize} +% All this means that you have to have a good understanding of how +% commands are defined when you attempt to make use of such hooks and +% something goes wrong. +% What can help in that case is to turn on \cs{DebugHooksOn} in which +% case you get much more (low-level) details on why something fails and +% what was tried to enable the hooks. +% +% +% \subsection{Patching}\label{sec:patching} % % The code here tries to find out if a command was defined with % \tn{newcommand} or \tn{DeclareRobustCommand} or @@ -172,7 +228,7 @@ % catcode settings are not the same as the ones at the time of command's % definition, so not always adding a hook to a command will work. % -% \subsubsection{Timing} +% \subsubsection{Timing}\label{sec:timing} % % When \cs{AddToHook} (or its \pkg{expl3} equivalent) is called with % a generic |cmd| hook, say, \hook{cmd/foo/before}, for the first time @@ -211,12 +267,14 @@ % hooks attached to them. % % One good example is the \tn{section} command. You can add something -% to the \hook{cmd/section/before} hook, but if you try to add something -% to the \hook{cmd/section/after} hook, \tn{section} will no longer -% work. That happens because the \tn{section} macro takes no argument, -% but instead calls a few internal \LaTeX{} macros to look for the -% optional and mandatory arguments. By adding code to the -% \hook{cmd/section/after} hook, you get in the way of that scanning. +% to the \hook{cmd/section/before} hook (but only with \cs{AddToHook} +% not \cs{AddToHookWithArguments}), +% but if you try to add anything to the \hook{cmd/section/after} +% hook, \tn{section} will no longer work at all. That happens because the +% \tn{section} macro takes no argument, but instead calls a few +% internal \LaTeX{} macros to look for the optional and mandatory +% arguments. By adding code to the \hook{cmd/section/after} hook, you +% get in the way of that scanning. % % In such a case, where it is known that a specific generic command % hook does not work if code is added to it, the package author can From 1f649d3160415fa1e8f06573e0222dfdca05fa14 Mon Sep 17 00:00:00 2001 From: mbertucci47 <61854785+mbertucci47@users.noreply.github.com> Date: Wed, 23 Oct 2024 02:23:51 -0600 Subject: [PATCH 2/2] Add a few T, F conditionals (#1504) * add T,F conditionals * fixes * update tests --------- Co-authored-by: Joseph Wright --- base/changes.txt | 8 ++++++++ base/lthooks.dtx | 9 ++++++--- base/ltmarks.dtx | 15 +++++++++++---- base/ltproperties.dtx | 11 +++++++---- base/testfiles-lthooks/lthooks-025.lvt | 12 ++++++++++++ base/testfiles-lthooks/lthooks-025.tlg | 6 ++++++ base/testfiles-ltmarks/xmarks-004.lvt | 2 ++ base/testfiles-ltmarks/xmarks-004.tlg | 1 + base/testfiles/properties-008-expansion.lvt | 6 ++++-- 9 files changed, 57 insertions(+), 13 deletions(-) diff --git a/base/changes.txt b/base/changes.txt index 18593c367..513048477 100644 --- a/base/changes.txt +++ b/base/changes.txt @@ -13,6 +13,14 @@ not part of the distribution. 2024-10-22 Ulrike Fischer * ltshipout.dtx: correct documentation (gh/1470). + + 2024-10-21 Matthew Bertucci + * lthooks.dtx + Define \IfHookEmptyT, \IfHookEmptyF + * ltmarks.dtx + Define \IfMarksEqualT, \IfMarksEqualF + * ltproperties.dtx + Define \IfPropertyRecordedT, \IfPropertyRecordedF 2024-10-18 Clea Rees * lttextcomp.dtx diff --git a/base/lthooks.dtx b/base/lthooks.dtx index 9e4450d62..c37e01e6a 100644 --- a/base/lthooks.dtx +++ b/base/lthooks.dtx @@ -32,7 +32,7 @@ %<*driver> % \fi \ProvidesFile{lthooks.dtx} - [2024/08/09 v1.1i LaTeX Kernel (hooks)] + [2024/10/21 v1.1j LaTeX Kernel (hooks)] % \iffalse % \documentclass{l3doc} @@ -894,7 +894,7 @@ % some variant thereof. Generic hooks such as \hook{file} and \hook{env} hooks are % automatically declared when code is added to them. % -% \begin{function}[EXP]{\IfHookEmptyTF} +% \begin{function}[EXP]{\IfHookEmptyTF,\IfHookEmptyT,\IfHookEmptyF} % \begin{syntax} % \cs{IfHookEmptyTF} \Arg{hook} \Arg{true code} \Arg{false code} % \end{syntax} @@ -7764,13 +7764,16 @@ % \end{macro} % % -% \begin{macro}[EXP]{\IfHookEmptyTF} +% \begin{macro}[EXP]{\IfHookEmptyTF,\IfHookEmptyT,\IfHookEmptyF} +% \changes{v1.1j}{2024/10/21}{Define \cs{IfHookEmptyT}, \cs{IfHookEmptyF}} % Here we avoid the overhead of \pkg{xparse}, since \cs{IfHookEmptyTF} % is used in \cs{end} (that is, every \LaTeX{} environment). As a % further optimization, use \cs{let} rather than \cs{def} to avoid one % expansion step. % \begin{macrocode} \cs_new_eq:NN \IfHookEmptyTF \hook_if_empty:nTF +\cs_new_eq:NN \IfHookEmptyT \hook_if_empty:nT +\cs_new_eq:NN \IfHookEmptyF \hook_if_empty:nF % \end{macrocode} % \end{macro} % diff --git a/base/ltmarks.dtx b/base/ltmarks.dtx index 6b8e1fa52..f769a0932 100644 --- a/base/ltmarks.dtx +++ b/base/ltmarks.dtx @@ -17,7 +17,7 @@ %<*driver> % \fi \ProvidesFile{ltmarks.dtx} - [2024/10/22 v1.0g LaTeX Kernel (Marks)] + [2024/10/22 v1.0h LaTeX Kernel (Marks)] % \iffalse % \documentclass{l3doc} @@ -257,7 +257,7 @@ % running headers and footers and shipout out both in one % go.\footnote{As of now that scenario is not yet officially supported.} % -% \begin{function}[EXP]{\IfMarksEqualTF,\mark_if_eq:nnnnTF,\mark_if_eq:nnnnnnTF} +% \begin{function}[EXP]{\IfMarksEqualTF,\IfMarksEqualT,\IfMarksEqualF,\mark_if_eq:nnnnTF,\mark_if_eq:nnnnnnTF} % \begin{syntax} % \cs{IfMarksEqualTF} \oarg{region} \Arg{class} \Arg{pos_1} \Arg{pos_2} \Arg{true} \Arg{false} % \cs{mark_if_eq:nnnnTF} \Arg{region} \Arg{class} \Arg{pos_1} \Arg{pos_2} \Arg{true} \Arg{false} @@ -1800,8 +1800,9 @@ % % % -% \begin{macro}[EXP]{\IfMarksEqualTF} -% We only provide a CamelCase command for the case with one region +% \begin{macro}[EXP]{\IfMarksEqualTF,\IfMarksEqualT,\IfMarksEqualF} +% \changes{v1.0h}{2024/10/21}{Define \cs{IfMarksEqualT}, \cs{IfMarksEqualF}} +% We only provide CamelCase commands for the case with one region % (optional) and one class. One could think of also providing a % version for the general case with several optional arguments, but % use cases for this are most likely rare, so not done yet. @@ -1809,6 +1810,12 @@ \NewExpandableDocumentCommand \IfMarksEqualTF {O{page}mmm} { \mark_if_eq:nnnnTF {#1}{#2}{#3}{#4} } +\NewExpandableDocumentCommand \IfMarksEqualT {O{page}mmm} { + \mark_if_eq:nnnnT {#1}{#2}{#3}{#4} +} +\NewExpandableDocumentCommand \IfMarksEqualF {O{page}mmm} { + \mark_if_eq:nnnnF {#1}{#2}{#3}{#4} +} % \end{macrocode} % \end{macro} % diff --git a/base/ltproperties.dtx b/base/ltproperties.dtx index 23a38c43a..77d36a43a 100644 --- a/base/ltproperties.dtx +++ b/base/ltproperties.dtx @@ -30,7 +30,7 @@ %<*driver> % \fi \ProvidesFile{ltproperties.dtx} - [2024/09/25 v1.0g LaTeX Kernel (Properties)] + [2024/10/21 v1.0h LaTeX Kernel (Properties)] % \iffalse % \documentclass[full]{l3doc} @@ -363,7 +363,7 @@ % has been set with the standard \cs{label} command. % \end{function} % -% \begin{function}{\IfPropertyRecordedTF} +% \begin{function}{\IfPropertyRecordedTF,\IfPropertyRecordedT,\IfPropertyRecordedF} % \begin{syntax} % \cs{IfPropertyRecordedTF} \Arg{label} \Arg{property} \Arg{true code} \Arg{false code} % \end{syntax} @@ -805,9 +805,12 @@ % \end{macrocode} % \end{macro} % -% \begin{macro}{\IfPropertyRecordedTF} +% \begin{macro}{\IfPropertyRecordedTF,\IfPropertyRecordedT,\IfPropertyRecordedF} +% \changes{v1.0h}{2024-10-21}{Define \cs{IfPropertyRecordedT}, \cs{IfPropertyRecordedF}} % \begin{macrocode} -\cs_new_eq:NN \IfPropertyRecordedTF \property_if_recorded:eeTF +\cs_new_eq:NN \IfPropertyRecordedTF \property_if_recorded:eeTF +\cs_new:Npn \IfPropertyRecordedT #1#2#3 { \property_if_recorded:eeTF {#1}{#2}{#3}{} } +\cs_new:Npn \IfPropertyRecordedF #1#2#3 { \property_if_recorded:eeTF {#1}{#2}{}{#3} } % \end{macrocode} % \end{macro} % diff --git a/base/testfiles-lthooks/lthooks-025.lvt b/base/testfiles-lthooks/lthooks-025.lvt index 2bbb95708..69fe72227 100644 --- a/base/testfiles-lthooks/lthooks-025.lvt +++ b/base/testfiles-lthooks/lthooks-025.lvt @@ -10,22 +10,30 @@ \IfHookExistsTF{foo}{\typeout{foo exists}}{\typeout{foo does not exists}} \IfHookEmptyTF {foo}{\typeout{foo empty}}{\typeout{foo not empty}} +\IfHookEmptyT {foo}{\typeout{foo empty}} +\IfHookEmptyF {foo}{\typeout{foo not empty}} \NewHook{foo} \IfHookExistsTF{foo}{\typeout{foo exists}}{\typeout{foo does not exists}} \IfHookEmptyTF {foo}{\typeout{foo empty}}{\typeout{foo not empty}} +\IfHookEmptyT {foo}{\typeout{foo empty}} +\IfHookEmptyF {foo}{\typeout{foo not empty}} \AddToHook{foo}{...} \IfHookExistsTF{foo}{\typeout{foo exists}}{\typeout{foo does not exists}} \IfHookEmptyTF {foo}{\typeout{foo empty}}{\typeout{foo not empty}} +\IfHookEmptyT {foo}{\typeout{foo empty}} +\IfHookEmptyF {foo}{\typeout{foo not empty}} \IfHookExistsTF{env/quote/before}{\typeout{env/quote/before exists}} {\typeout{env/quote/before does not exists}} \IfHookEmptyTF {env/quote/before}{\typeout{env/quote/before empty}} {\typeout{env/quote/before not empty}} +\IfHookEmptyT {env/quote/before}{\typeout{env/quote/before empty}} +\IfHookEmptyF {env/quote/before}{\typeout{env/quote/before not empty}} \AddToHook{env/quote/before}{...} @@ -33,6 +41,8 @@ {\typeout{env/quote/before does not exists}} \IfHookEmptyTF {env/quote/before}{\typeout{env/quote/before empty}} {\typeout{env/quote/before not empty}} +\IfHookEmptyT {env/quote/before}{\typeout{env/quote/before empty}} +\IfHookEmptyF {env/quote/before}{\typeout{env/quote/before not empty}} \RemoveFromHook{env/quote/before}[*] @@ -40,5 +50,7 @@ {\typeout{env/quote/before does not exists}} \IfHookEmptyTF {env/quote/before}{\typeout{env/quote/before empty}} {\typeout{env/quote/before not empty}} +\IfHookEmptyT {env/quote/before}{\typeout{env/quote/before empty}} +\IfHookEmptyF {env/quote/before}{\typeout{env/quote/before not empty}} \END diff --git a/base/testfiles-lthooks/lthooks-025.tlg b/base/testfiles-lthooks/lthooks-025.tlg index 2c826a4a2..8ca1e22c5 100644 --- a/base/testfiles-lthooks/lthooks-025.tlg +++ b/base/testfiles-lthooks/lthooks-025.tlg @@ -2,13 +2,19 @@ This is a generated file for the l3build validation system. Don't change this file in any respect. foo does not exists foo empty +foo empty foo exists foo empty +foo empty foo exists foo not empty +foo not empty env/quote/before does not exists env/quote/before empty +env/quote/before empty env/quote/before exists env/quote/before not empty +env/quote/before not empty env/quote/before exists env/quote/before empty +env/quote/before empty diff --git a/base/testfiles-ltmarks/xmarks-004.lvt b/base/testfiles-ltmarks/xmarks-004.lvt index 1c0c168e0..b43841b1d 100644 --- a/base/testfiles-ltmarks/xmarks-004.lvt +++ b/base/testfiles-ltmarks/xmarks-004.lvt @@ -60,6 +60,8 @@ Some text % testing a non-existent mark returns true (which is not unreasonable) \IfMarksEqualTF{foobar}{top}{first}{\typeout{equal}}{\typeout{not equal}} +\IfMarksEqualT{foobar}{top}{first}{\typeout{equal}} +\IfMarksEqualF{foobar}{top}{first}{\typeout{not equal}} % testing a an existing and a non-existing mark returns false (which is not unreasonable) diff --git a/base/testfiles-ltmarks/xmarks-004.tlg b/base/testfiles-ltmarks/xmarks-004.tlg index 35b525df9..3a5508646 100644 --- a/base/testfiles-ltmarks/xmarks-004.tlg +++ b/base/testfiles-ltmarks/xmarks-004.tlg @@ -204,6 +204,7 @@ control sequence to too much text. How can we recover? My plan is to forget the whole thing and hope for the best. equal equal +equal not equal Marks: 2e-left in OR (twoside-even second column): page (current):|\__mark_id:n {2}\MakeUppercase []{1\hskip 1em\relax A test}|\__mark_id:n {2}\MakeUppercase []{1\hskip 1em\relax A test}|\__mark_id:n {2}\MakeUppercase []{1\hskip 1em\relax A test}| diff --git a/base/testfiles/properties-008-expansion.lvt b/base/testfiles/properties-008-expansion.lvt index 565164c2c..7e5dc0819 100644 --- a/base/testfiles/properties-008-expansion.lvt +++ b/base/testfiles/properties-008-expansion.lvt @@ -63,9 +63,11 @@ xxxxx \TEST{Test~label/property~by~command} { - \ASSERT{true} + \ASSERT{true true false} { - \IfPropertyRecordedTF {label\labelsuffix}{name\propsuffix} {true}{false} + \IfPropertyRecordedTF {label\labelsuffix}{name\propsuffix}{true}{false} + \IfPropertyRecordedT {label\labelsuffix}{name\propsuffix}{true} + \IfPropertyRecordedF {label\labelsuffix XXX}{name\propsuffix}{false} } }