summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/source/latex-dev
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2023-09-13 20:40:56 +0000
committerKarl Berry <karl@freefriends.org>2023-09-13 20:40:56 +0000
commit99bdd2e42bf8c8ec861eb8b6a7708f63396c5d8e (patch)
tree31f555c33bcc0153b169a88c625085b6c39389ee /Master/texmf-dist/source/latex-dev
parent8f22ac5379816e4b6bdd9e5c9dc981b4223187b4 (diff)
latex-dev (13sep23)
git-svn-id: svn://tug.org/texlive/trunk@68270 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/source/latex-dev')
-rw-r--r--Master/texmf-dist/source/latex-dev/base/format.ins2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/latexrelease.ins2
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltcmd.dtx153
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltcmdhooks.dtx8
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltfilehook.dtx3
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltfiles.dtx26
-rw-r--r--Master/texmf-dist/source/latex-dev/base/lthooks.dtx38
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltluatex.dtx12
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltmiscen.dtx245
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltproperties.dtx943
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltsockets.dtx1069
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltspace.dtx19
-rw-r--r--Master/texmf-dist/source/latex-dev/base/ltvers.dtx2
-rw-r--r--Master/texmf-dist/source/latex-dev/firstaid/firstaid.ins7
-rw-r--r--Master/texmf-dist/source/latex-dev/firstaid/latex2e-first-aid-for-external-files.dtx121
15 files changed, 2300 insertions, 350 deletions
diff --git a/Master/texmf-dist/source/latex-dev/base/format.ins b/Master/texmf-dist/source/latex-dev/base/format.ins
index 74cd78ff4a8..ba0965004d1 100644
--- a/Master/texmf-dist/source/latex-dev/base/format.ins
+++ b/Master/texmf-dist/source/latex-dev/base/format.ins
@@ -169,6 +169,7 @@ the system are in the document `cfgguide.tex'.
\from{ltcmd.dtx}{2ekernel} % L3 layer module (used to be xparse)
\from{lthooks.dtx}{2ekernel} % L3 layer module
\from{ltcmdhooks.dtx}{2ekernel} % L3 layer module
+ \from{ltsockets.dtx}{2ekernel} % L3 layer module
\from{ltalloc.dtx}{2ekernel}
\from{ltcntrl.dtx}{2ekernel}
\from{lterror.dtx}{2ekernel}
@@ -191,6 +192,7 @@ the system are in the document `cfgguide.tex'.
\from{lttextcomp.dtx}{2ekernel}
\from{ltpageno.dtx}{2ekernel}
\from{ltxref.dtx}{2ekernel}
+ \from{ltproperties.dtx}{2ekernel}
\from{ltmiscen.dtx}{2ekernel}
\from{ltmath.dtx}{2ekernel}
\from{ltlists.dtx}{2ekernel}
diff --git a/Master/texmf-dist/source/latex-dev/base/latexrelease.ins b/Master/texmf-dist/source/latex-dev/base/latexrelease.ins
index 61315f8e078..93739630e3e 100644
--- a/Master/texmf-dist/source/latex-dev/base/latexrelease.ins
+++ b/Master/texmf-dist/source/latex-dev/base/latexrelease.ins
@@ -96,6 +96,7 @@ extension .ins) which are part of the distribution.
\from{ltcmd.dtx} {latexrelease}% L3 layer module
\from{lthooks.dtx} {latexrelease}% L3 layer module
\from{ltcmdhooks.dtx} {latexrelease}% L3 layer module
+ \from{ltsockets.dtx} {latexrelease}% L3 layer module
\from{ltalloc.dtx} {latexrelease}% empty
\from{ltcntrl.dtx} {latexrelease}% empty
\from{lterror.dtx} {latexrelease}% empty
@@ -118,6 +119,7 @@ extension .ins) which are part of the distribution.
\from{lttextcomp.dtx} {latexrelease}%
\from{ltpageno.dtx} {latexrelease}% empty
\from{ltxref.dtx} {latexrelease}% empty
+ \from{ltproperties.dtx}{latexrelease}%
\from{ltmiscen.dtx} {latexrelease}%
\from{ltmath.dtx} {latexrelease}%
\from{ltlists.dtx} {latexrelease}% empty
diff --git a/Master/texmf-dist/source/latex-dev/base/ltcmd.dtx b/Master/texmf-dist/source/latex-dev/base/ltcmd.dtx
index d6322ff3ee8..dcb85a1ae8d 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltcmd.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltcmd.dtx
@@ -34,8 +34,8 @@
%%% From File: ltcmd.dtx
%
% \begin{macrocode}
-\def\ltcmdversion{v1.1e}
-\def\ltcmddate{2023-05-26}
+\def\ltcmdversion{v1.2a}
+\def\ltcmddate{2023-08-19}
% \end{macrocode}
%
%<*driver>
@@ -59,6 +59,8 @@
% \section{Creating document commands}
%
% \changes{v1.0a}{2020/11/20}{Initial version derived from \texttt{xparse.dtx}}
+% \changes{v1.2a}{2023/08/19}{Removed commands that should have remained
+% only in \texttt{xparse.dtx}}
%
% Document commands should be created using the tools provided by this module:
% \cs{NewDocumentCommand}, etc.\@, in almost all cases. This allows clean
@@ -4263,116 +4265,6 @@
% \end{macro}
% \end{macro}
%
-% \subsection{Access to the argument specification}
-%
-% \begin{macro}{\@@_get_arg_spec_error:N, \@@_get_arg_spec_error:n}
-% \begin{macro}{\@@_get_arg_spec_error_aux:n}
-% Provide an informative error when trying to get the argument
-% specification of a non-\pkg{xparse} command or environment.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_get_arg_spec_error:N #1
- {
- \bool_set_false:N \l_@@_environment_bool
- \tl_set:Nn \l_@@_fn_tl {#1}
- \@@_get_arg_spec_error_aux:n { \cs_if_exist:NTF #1 }
- }
-\cs_new_protected:Npn \@@_get_arg_spec_error:n #1
- {
- \bool_set_true:N \l_@@_environment_bool
- \str_set:Nx \l_@@_environment_str {#1}
- \@@_get_arg_spec_error_aux:n
- { \cs_if_exist:cTF { \l_@@_environment_str } }
- }
-\cs_new_protected:Npn \@@_get_arg_spec_error_aux:n #1
- {
- #1
- {
- \msg_error:nnx { cmd } { non-xparse }
- { \@@_environment_or_command: }
- }
- {
- \msg_error:nnx { cmd } { unknown }
- { \@@_environment_or_command: }
- }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_get_arg_spec:NTF}
-% If the command is not an \pkg{xparse} command, complain. If it is,
-% its second \enquote{item} is the argument specification.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_get_arg_spec:NTF #1#2#3
- {
- \__kernel_cmd_if_xparse:NTF #1
- {
- \tl_set:Nx \ArgumentSpecification { \tl_item:Nn #1 { 2 } }
- #2
- }
- {#3}
- }
-% \end{macrocode}
-% \end{macro}
-%
-% Rolling forward from 2020-10-01 is tricky because the entire |ltcmd|
-% module is new, but the user-level commands have the same name, so only
-% these will clash. To work around that, in |latexrelease| mode we will
-% (temporarily) disable \cs{__kernel_chk_if_free_cs:N} for this final
-% part of the code, then restore at the end.
-% \begin{macrocode}
-%<latexrelease>\cs_new_eq:NN \@@_chk_if_free_cs:N \__kernel_chk_if_free_cs:N
-%<latexrelease>\cs_gset_eq:NN \__kernel_chk_if_free_cs:N \use_none:n
-% \end{macrocode}
-%
-% \begin{variable}{\ArgumentSpecification}
-% \begin{macrocode}
-\tl_new:N \ArgumentSpecification
-% \end{macrocode}
-% \end{variable}
-%
-% \begin{macro}{\@@_get_arg_spec:N}
-% \begin{macro}{\@@_get_arg_spec:n}
-% Recovering the argument specification is now trivial.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_get_arg_spec:N #1
- {
- \@@_get_arg_spec:NTF #1 { }
- { \@@_get_arg_spec_error:N #1 }
- }
-\cs_new_protected:Npn \@@_get_arg_spec:n #1
- {
- \exp_args:Nc \@@_get_arg_spec:NTF
- { environment~ \tl_to_str:n {#1} }
- { }
- { \@@_get_arg_spec_error:n {#1} }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
-% \begin{macro}{\@@_show_arg_spec:N}
-% \begin{macro}{\@@_show_arg_spec:n}
-% Showing the argument specification simply means finding it and then
-% calling the \cs{tl_show:N} function.
-% \begin{macrocode}
-\cs_new_protected:Npn \@@_show_arg_spec:N #1
- {
- \@@_get_arg_spec:NTF #1
- { \tl_show:N \ArgumentSpecification }
- { \@@_get_arg_spec_error:N #1 }
- }
-\cs_new_protected:Npn \@@_show_arg_spec:n #1
- {
- \exp_args:Nc \@@_get_arg_spec:NTF
- { environment~ \tl_to_str:n {#1} }
- { \tl_show:N \ArgumentSpecification }
- { \@@_get_arg_spec_error:n {#1} }
- }
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-%
% \subsection{Utilities}
%
% \begin{macro}{\@@_check_definable:nNT, \@@_check_definable_aux:nN}
@@ -4817,12 +4709,6 @@
LaTeX~did~not~find~this~argument~and~will~insert~a~default~value~
for~further~processing.
}
-\msg_new:nnnn { cmd } { non-xparse }
- { \str_uppercase:n #1~not~defined~using~xparse. }
- {
- You~have~asked~for~the~argument~specification~for~the~#1,~
- but~this~was~not~defined~using~xparse.
- }
\msg_new:nnnn { cmd } { arg-split }
{ Too~many~'#1'~separators~in~argument. }
{
@@ -4830,12 +4716,6 @@
at~each~occurrence~of~the~separator~'#1'~into~#2~parts.~
Too~many~separators~were~found.
}
-\msg_new:nnnn { cmd } { unknown }
- { Unknown~document~#1. }
- {
- You~have~asked~for~the~argument~specification~for~the~#1,~
- but~it~is~not~defined.
- }
\msg_new:nnnn { cmd } { verbatim-nl }
{ Verbatim-like~#1~ended~by~end~of~line. }
{
@@ -5153,31 +5033,6 @@
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}{\GetDocumentCommandArgSpec}
-% \begin{macro}{\GetDocumentEnvironmentArgSpec}
-% \begin{macro}{\ShowDocumentCommandArgSpec}
-% \begin{macro}{\ShowDocumentEnvironmentArgSpec}
-% More simple mappings, with a check that the argument is a single
-% control sequence or active character.
-% \begin{macrocode}
-\cs_new_protected:Npn \GetDocumentCommandArgSpec #1
- {
- \@@_check_definable:nNT {#1} \GetDocumentCommandArgSpec
- { \@@_get_arg_spec:N #1 }
- }
-\cs_new_eq:NN \GetDocumentEnvironmentArgSpec \@@_get_arg_spec:n
-\cs_new_protected:Npn \ShowDocumentCommandArgSpec #1
- {
- \@@_check_definable:nNT {#1} \ShowDocumentCommandArgSpec
- { \@@_show_arg_spec:N #1 }
- }
-\cs_new_eq:NN \ShowDocumentEnvironmentArgSpec \@@_show_arg_spec:n
-% \end{macrocode}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-% \end{macro}
-%
% Finally as promised, restore \cs{__kernel_chk_if_free_cs:N}:
% \begin{macrocode}
%<latexrelease>\cs_gset_eq:NN \__kernel_chk_if_free_cs:N \@@_chk_if_free_cs:N
diff --git a/Master/texmf-dist/source/latex-dev/base/ltcmdhooks.dtx b/Master/texmf-dist/source/latex-dev/base/ltcmdhooks.dtx
index 27907af6798..6f885a2c6ce 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltcmdhooks.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltcmdhooks.dtx
@@ -14,8 +14,8 @@
%
%%% From File: ltcmdhooks.dtx
%
-\def\ltcmdhooksversion{v1.0h}
-\def\ltcmdhooksdate{2023/05/21}
+\def\ltcmdhooksversion{v1.0i}
+\def\ltcmdhooksdate{2023/06/16}
%
%
%
@@ -1641,10 +1641,10 @@
% \subsection{Messages}
%
% \begin{macrocode}
-%<latexrelease>\IncludeInRelease{2021/11/15}{wrong-cmd-hook}%
+%<latexrelease>\IncludeInRelease{2023/06/01}{wrong-cmd-hook}%
%<latexrelease> {Standardise~generic~hook~names}
%<latexrelease>\EndIncludeInRelease
-%<latexrelease>\IncludeInRelease{2021/11/15}{wrong-cmd-hook}%
+%<latexrelease>\IncludeInRelease{2021/06/01}{wrong-cmd-hook}%
%<latexrelease> {Standardise~generic~hook~names}
%<latexrelease>\msg_new:nnnn { hooks } { wrong-cmd-hook }
%<latexrelease> {
diff --git a/Master/texmf-dist/source/latex-dev/base/ltfilehook.dtx b/Master/texmf-dist/source/latex-dev/base/ltfilehook.dtx
index e10a5416e58..ae183bfeb47 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltfilehook.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltfilehook.dtx
@@ -32,7 +32,7 @@
%
% \begin{macrocode}
\providecommand\ltfilehookversion{v1.0o}
-\providecommand\ltfilehookdate{2023/04/02}
+\providecommand\ltfilehookdate{2023/07/10}
% \end{macrocode}
%
%<*driver>
@@ -1043,7 +1043,6 @@
%
% \begin{macrocode}
%<@@=>
-\ExplSyntaxOff
% \end{macrocode}
%
% \subsection{Selecting a file (\cs{set@curr@file})}
diff --git a/Master/texmf-dist/source/latex-dev/base/ltfiles.dtx b/Master/texmf-dist/source/latex-dev/base/ltfiles.dtx
index 3bac7ea0b22..f079c2cf5b1 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltfiles.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltfiles.dtx
@@ -32,7 +32,7 @@
%<*driver>
% \fi
\ProvidesFile{ltfiles.dtx}
- [2023/05/17 v1.2t LaTeX Kernel (File Handling)]
+ [2023/06/17 v1.2u LaTeX Kernel (File Handling)]
% \iffalse
\documentclass{ltxdoc}
\GetFileInfo{ltfiles.dtx}
@@ -1203,8 +1203,9 @@
% \changes{v1.2d}{2019/10/26}{quote on openin}
% \changes{v1.2k}{2021/03/12}{Allow unbalanced conditionals (gh/530)}
% \changes{v1.2t}{2023/05/15}{Use \pkg{expl3} file existence test}
-% \begin{macro}{\IfFileExists@}
+% \begin{macro}{\IfFileExists@@}
% \changes{v1.2t}{2023/05/15}{Macro added}
+% \changes{v1.2u}{2023/06/16}{Support piped input}
% Argument |#1| is |\@curr@file| so catcode 12 string with no quotes.
%
% The original definition picked up arguments |#2| and |#3| in a
@@ -1212,7 +1213,7 @@
% implementation would have been not to pick up the arguments at
% all but instead use the usual \cs{@firstoftwo} and
% \cs{secondoftwo}. However, that changes how |#| is interpreted
-% and so we can't do that nowaways without invalidating a lot of
+% and so we can't do that nowadays without invalidating a lot of
% code. Therefore the somewhat curious construction near the end.
%
% Earlier versions used |\openin| here, but this led to two
@@ -1224,7 +1225,7 @@
% \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2023/05/01}%
+%<latexrelease>\IncludeInRelease{2023/06/01}%
%<latexrelease> {\IfFileExists@}{IfFileExists}
\long\def \IfFileExists@#1#2#3{%
\edef\@filef@und{\IfFileExists@@{#1}}%
@@ -1251,8 +1252,23 @@
\expandafter\def\expandafter\reserved@a
\expandafter{\reserved@a{#2}{#3}}%
\reserved@a}
+% \end{macrocode}
+% Pipes are not really files, but at the document level they are supported.
+% To quickly trim of any leading spaces, we use a blank test and \cs{use:n}
+% rather than \cs{tl_trim_spaces:n} for speed as we don't care about the end
+% of the input.
+% \begin{macrocode}
\ExplSyntaxOn
-\cs_new_eq:NN \IfFileExists@@ \file_full_name:n
+\cs_new:Npn \IfFileExists@@ #1
+ {
+ \tl_if_blank:nF {#1}
+ {
+ \tl_if_head_eq_charcode:oNTF { \use:n #1 } |
+ {#1}
+ { \file_full_name:n {#1} }
+ }
+ }
+\cs_generate_variant:Nn \tl_if_head_eq_charcode:nNTF { o }
\ExplSyntaxOff
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
diff --git a/Master/texmf-dist/source/latex-dev/base/lthooks.dtx b/Master/texmf-dist/source/latex-dev/base/lthooks.dtx
index 3807d25c44b..e43fa4ef351 100644
--- a/Master/texmf-dist/source/latex-dev/base/lthooks.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/lthooks.dtx
@@ -31,8 +31,8 @@
%%% From File: lthooks.dtx
%
% \begin{macrocode}
-\def\lthooksversion{v1.1e}
-\def\lthooksdate{2023/06/06}
+\def\lthooksversion{v1.1f}
+\def\lthooksdate{2023/08/11}
% \end{macrocode}
%
%<*driver>
@@ -298,10 +298,6 @@
% consumed and any further attempt to add to it will result in
% executing the code to be added immediately.
%
-% The \meta{hook} \emph{cannot} be specified using the dot-syntax.
-% A leading |.| is treated literally. See
-% section~\ref{sec:default-label} for details.
-%
% Using \cs{UseOneTimeHook} several times with the same
% \Arg{hook} means that it only executes the first time it is used.
% For example, if it is used in a command that can be called several times
@@ -311,6 +307,11 @@
% Mixing \cs{UseHook} and \cs{UseOneTimeHook} for the same
% \Arg{hook} should be avoided, but if this is done then neither will execute
% after the first \cs{UseOneTimeHook}.
+%
+% The \meta{hook} \emph{cannot} be specified using the dot-syntax.
+% A leading |.| is treated literally. See
+% section~\ref{sec:default-label} for details.
+%
% \end{function}
%
% \begin{function}{\UseOneTimeHookWithArguments}
@@ -327,6 +328,11 @@
% longer possible to use \cs{AddToHookWithArguments} or similar with
% that hook. \cs{AddToHook} continues to work as normal.
% Section~\ref{sec:hook-args} explains hooks with arguments.
+%
+% The \meta{hook} \emph{cannot} be specified using the dot-syntax.
+% A leading |.| is treated literally. See
+% section~\ref{sec:default-label} for details.
+%
% \end{function}
%
%
@@ -607,7 +613,10 @@
% \meta{hook} arguments, both in the \LaTeXe{} interface, and the \LaTeX3
% interface described in section~\ref{sec:l3hook-interface}.
%
-% Note, however, that the replacement of |.| by the \meta{default label}
+% Note,\marginpar{\raggedleft\rightskip5pt\itshape \textbf{Important:}\break The dot-syntax
+% is \textbf{not} available with
+% \cs{UseHook} and some other commands that are typically used within code!}
+% however, that the replacement of |.| by the \meta{default label}
% takes place when the hook command is executed, so actions that are
% somehow executed after the package ends will have the wrong
% \meta{default label} if the dot-syntax is used. For that reason,
@@ -1997,8 +2006,9 @@
%
% \item[\hook{begindocument}]
%
-% This hook is added to when using \cs{AtBeginDocument} and it is
-% executed after the \texttt{.aux} file as be read in and most
+% This hook is added to by using \cs{AddToHook}\texttt{\{begindocument\}}
+% or by using \cs{AtBeginDocument} and it is
+% executed after the \texttt{.aux} file has been read and most
% initialization are done, so they can be altered and inspected by
% the hook code. It is followed by a small number of further
% initializations that shouldn't be altered and are therefore
@@ -3534,7 +3544,7 @@
% \changes{v1.1a}{2023/04/06}
% {Add \cs{hook_gput_code_with_args:nnn} (hook-args).}
% \begin{macrocode}
-%<latexrelease>\IncludeInRelease{2023/06/01}{\hook_gput_code_with_args:nnn}
+%<latexrelease>\IncludeInRelease{2023/06/01}{\hook_gput_code:nnn}
%<latexrelease> {Hooks~with~args}
\cs_new_protected:Npn \hook_gput_code:nnn #1 #2 #3
{
@@ -4386,7 +4396,7 @@
% \end{macrocode}
%
% \begin{macrocode}
-%<latexrelease>\IncludeInRelease{2023/06/01}{\hook_gremove_code:nn}
+%<latexrelease>\IncludeInRelease{2020/10/01}{\hook_gremove_code:nn}
%<latexrelease> {Hooks~with~args}
%<latexrelease>\cs_new_protected:Npn \@@_gremove_code:nn #1 #2
%<latexrelease> {
@@ -5287,6 +5297,10 @@
%<latexrelease> \cs_gset_eq:NN \hook_use:n \@@_use_initialized:n
%<latexrelease> \cs_gset_eq:NN \@@_preamble_hook:n \use_none:n
%<latexrelease> }
+%<@@=>
+%<latexrelease>\cs_gset_eq:NN \@expl@@@initialize@all@@
+%<latexrelease> \__hook_initialize_all:
+%<@@=hook>
%<latexrelease>\EndIncludeInRelease
% \end{macrocode}
% \end{macro}
@@ -7365,7 +7379,7 @@
\NewDocumentCommand \NewMirroredHookPairWithArguments { mmm }
{ \hook_new_pair_with_args:nnn {#1} {#2} {#3} }
%<latexrelease>\EndIncludeInRelease
-%<latexrelease>\IncludeInRelease{2023/06/01}{\NewHookWithArguments}
+%<latexrelease>\IncludeInRelease{2020/10/01}{\NewHookWithArguments}
%<latexrelease> {Hooks~with~args}
%<latexrelease>\cs_new_protected:Npn \NewHookWithArguments #1 #2 { }
%<latexrelease>\cs_new_protected:Npn \NewReversedHookWithArguments #1 #2 { }
diff --git a/Master/texmf-dist/source/latex-dev/base/ltluatex.dtx b/Master/texmf-dist/source/latex-dev/base/ltluatex.dtx
index 135cb630096..6d274ed5c33 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltluatex.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltluatex.dtx
@@ -28,7 +28,7 @@
\ProvidesFile{ltluatex.dtx}
%</driver>
%<*tex>
-[2023/01/19 v1.2b
+[2023/08/03 v1.2c
%</tex>
%<plain> LuaTeX support for plain TeX (core)
%<*tex>
@@ -1284,6 +1284,7 @@ luatexbase.new_chunkname = new_chunkname
%
% \begin{macro}{new_luafunction}
% \changes{v1.1i}{2018/10/21}{Function added}
+% \changes{v1.2c}{2023/07/02}{Ensure existing table entries not overwritten gh/1100}
% Much the same as for attribute allocation in Lua.
% The optional \meta{name} argument is used in the log if given.
% \begin{macrocode}
@@ -1291,7 +1292,11 @@ local luafunction_count_name =
luafunction_count_name or "e@alloc@luafunction@count"
local function new_luafunction(name)
tex_setcount("global", luafunction_count_name,
- tex_count[luafunction_count_name] + 1)
+ math.max(
+ #(lua.get_functions_table()),
+ tex_count[luafunction_count_name])
+ + 1)
+ lua.get_functions_table()[tex_count[luafunction_count_name]] = false
if tex_count[luafunction_count_name] > 65534 then
luatexbase_error("No room for a new luafunction register")
end
@@ -2147,12 +2152,13 @@ luatexbase.uninstall = uninstall
% \begin{macro}{mlist_to_hlist}
% \changes{v1.1l}{2020/02/02}{|pre/post_mlist_to_hlist| added}
% \changes{v1.1y}{2022/08/13}{Use shared\_callback system for pre/post/mlist_to_hlist}
+% \changes{v1.2c}{2023/08/03}{Fix callback type of post_mlist_to_hlist_callback}
% To emulate these callbacks, the ``real'' |mlist_to_hlist| is replaced by a
% wrapper calling the wrappers before and after.
% \begin{macrocode}
create_callback('pre_mlist_to_hlist_filter', 'list')
create_callback('mlist_to_hlist', 'exclusive', node.mlist_to_hlist)
-create_callback('post_mlist_to_hlist_filter', 'list')
+create_callback('post_mlist_to_hlist_filter', 'reverselist')
function shared_callbacks.mlist_to_hlist.handler(head, display_type, need_penalties)
local current = call_callback("pre_mlist_to_hlist_filter", head, display_type, need_penalties)
if current == false then
diff --git a/Master/texmf-dist/source/latex-dev/base/ltmiscen.dtx b/Master/texmf-dist/source/latex-dev/base/ltmiscen.dtx
index 801d1e68627..74a9685f1fb 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltmiscen.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltmiscen.dtx
@@ -32,7 +32,7 @@
%<*driver>
% \fi
\ProvidesFile{ltmiscen.dtx}
- [2022/11/06 v1.2a LaTeX Kernel (Misc. Environments)]
+ [2023/09/13 v1.2c LaTeX Kernel (Misc. Environments)]
% \iffalse
\documentclass{ltxdoc}
\GetFileInfo{ltmiscen.dtx}
@@ -194,8 +194,8 @@
% \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2020/10/01}%
-%<latexrelease> {\enddocument}{Use Hooks}%
+%<latexrelease>\IncludeInRelease{2023/11/01}%
+%<latexrelease> {\enddocument}{check property labels}%
\def\enddocument{%
% \end{macrocode}
% The |\end{document}| hook is executed first. If necessary it can
@@ -230,6 +230,10 @@
\let\@setckpt\@gobbletwo
\let\@newl@bel\@testdef
% \end{macrocode}
+% \changes{v1.2b}{2023/09/06}{Test changes of values in \cs{new@label@record}}
+% \begin{macrocode}
+ \let\new@label@record\@kernel@new@label@record@testdef
+% \end{macrocode}
% \changes{v1.0z}{1995/07/13}{Shorten redefinition of \cs{bibcite} and
% \cs{newlabel}}
% The previous line is equiv to setting
@@ -357,6 +361,67 @@
% \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{2020/10/01}%
+%<latexrelease> {\enddocument}{Use Hooks}%
+%<latexrelease>\def\enddocument{%
+%<latexrelease> \@kernel@before@enddocument
+%<latexrelease> \UseOneTimeHook{enddocument}%
+%<latexrelease> \@kernel@after@enddocument
+%<latexrelease> \@checkend{document}%
+%<latexrelease> \clearpage
+%<latexrelease> \UseOneTimeHook{enddocument/afterlastpage}%
+%<latexrelease> \@kernel@after@enddocument@afterlastpage
+%<latexrelease> \begingroup
+%<latexrelease> \if@filesw
+%<latexrelease> \immediate\closeout\@mainaux
+%<latexrelease> \let\@setckpt\@gobbletwo
+%<latexrelease> \let\@newl@bel\@testdef
+%<latexrelease> \@tempswafalse
+%<latexrelease> \makeatletter \@@input\jobname.aux
+%<latexrelease> \fi
+%<latexrelease> \UseOneTimeHook{enddocument/afteraux}%
+%<latexrelease> \UseOneTimeHook{enddocument/info}%
+%<latexrelease> \endgroup
+%<latexrelease> \UseOneTimeHook{enddocument/end}%
+%<latexrelease> \deadcycles\z@\@@end}
+%<latexrelease>\NewHook{enddocument}
+%<latexrelease>\NewHook{enddocument/afterlastpage}
+%<latexrelease>\NewHook{enddocument/afteraux}
+%<latexrelease>\NewHook{enddocument/info}
+%<latexrelease>\NewHook{enddocument/end}
+%<latexrelease>\AddToHook{enddocument/info}[kernel/filelist]{\@dofilelist}
+%<latexrelease>\AddToHook{enddocument/info}[kernel/warnings]{\@enddocument@kernel@warnings}
+%<latexrelease>\AddToHook{enddocument/info}[kernel/release]{%
+%<latexrelease> \let\show@release@info\wlog
+%<latexrelease> \show@release@info{ ***********}%
+%<latexrelease> \the\LaTeXReleaseInfo
+%<latexrelease> \show@release@info{ ***********}}
+%<latexrelease>
+%<latexrelease>\DeclareHookRule{enddocument/info}{kernel/release}{before}{kernel/filelist}
+%<latexrelease>\DeclareHookRule{enddocument/info}{kernel/filelist}{before}{kernel/warnings}
+%<latexrelease>\def\@enddocument@kernel@warnings{%
+%<latexrelease> \ifdim \font@submax >\fontsubfuzz\relax
+%<latexrelease> \@font@warning{Size substitutions with differences\MessageBreak
+%<latexrelease> up to \font@submax\space have occurred.\@gobbletwo}%
+%<latexrelease> \fi
+%<latexrelease> \@defaultsubs
+%<latexrelease> \@refundefined
+%<latexrelease> \if@filesw
+%<latexrelease> \ifx \@multiplelabels \relax
+%<latexrelease> \if@tempswa
+%<latexrelease> \@latex@warning@no@line{Label(s) may have changed.
+%<latexrelease> Rerun to get cross-references right}%
+%<latexrelease> \fi
+%<latexrelease> \else
+%<latexrelease> \@multiplelabels
+%<latexrelease> \fi
+%<latexrelease> \ifx \@extra@page@added \relax
+%<latexrelease> \@latex@warning@no@line{Temporary extra page added at the end.
+%<latexrelease> Rerun to get it removed}%
+%<latexrelease> \fi
+%<latexrelease> \fi
+%<latexrelease>}
+%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{0000/00/00}%
%<latexrelease> {\enddocument}{Use Hooks}%
%<latexrelease>
@@ -496,8 +561,7 @@
\protected\def\protected@file@percent{}
% \end{macrocode}
% \end{macro}
-
-
+%
% \begin{macro}{\add@percent@to@temptokena}
% Helper function which is used to inspect a sequence of tokens
% (the second argument of \cs{@writefile} and it the last token is
@@ -1189,11 +1253,33 @@
% print as the \TeX{}book's space character instead of as blank spaces.
%
% \begin{macro}{\@vobeyspaces}
+% \changes{v1.2b}{2023/06/15}{Support tabs}
+% \begin{macro}{\@vobeytabs}
+% \changes{v1.2b}{2023/06/14}{Macro added}
+% \changes{v1.2c}{2023/09/01}{Provide global definition for active tab}
% \begin{macrocode}
+%</2ekernel>
+%<latexrelease>\IncludeInRelease{2023/11/01}%
+%<latexrelease> {\@vobeytabs}{Obeyed tabs}%
+%<*2ekernel|latexrelease>
{\catcode`\ =\active%
-\gdef\@vobeyspaces{\catcode`\ \active\let \@xobeysp}}
+\gdef\@vobeyspaces{\catcode`\ \active\let \@xobeysp\@vobeytabs}}
+{\catcode`\^^I=\active
+\gdef\@vobeytabs{\catcode`\^^I\active\let^^I\@xobeytab}%
+\global\let^^I=\space
+}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease> {\@vobeytabs}{Obeyed tabs}%
+%<latexrelease>{\catcode`\ =\active%
+%<latexrelease>\gdef\@vobeyspaces{\catcode`\ \active\let \@xobeysp}}
+%<latexrelease>\let\@vobeytabs\@undefined
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
% \end{macrocode}
% \end{macro}
+% \end{macro}
%
% \begin{macro}{\@xobeysp}
% \changes{v1.0z}{1995/07/13}{Use \cs{nobreak}}
@@ -1368,44 +1454,8 @@
% \end{macro}
%
%
-
-% \begin{macro}{\@setupverbvisiblespace}
-%
-% In pdf\TeX{} a catcode 12 space will produce the character in
-% slot 32 which is assumed to be a visible space character (in a
-% typewriter font in OT1 or T1 encoding). In Xe\TeX{} or Lua\TeX{} a
-% font in TU encoding is normally used and that has a real space in
-% this slot. So what we do in this case is this: we check the
-% definition of
-% |\verbvisiblespace| and if it is |\asciispace| we assume that the
-% char32 can be used (e.g., in pdf\TeX{}). We then redefine
-% |\@xobeysp| so that after running |\@vobeyspaces| we get
-% characters from slot 32 for each active space.
-%
-% \changes{v1.1o}{2018/10/11}
-% {Provide visible space in \cs{verb*} also for XeTeX and LuaTeX (github/69)}
-% \begin{macrocode}
-\def\@setupverbvisiblespace{%
- \ifx\verbvisiblespace\asciispace
- \let\@xobeysp\asciispace
- \else
-% \end{macrocode} Otherwise we measure the width of a character in
-% the mon-spaced current font and place a
-% |\verbvisiblespace| into a box of the right width which we are then
-% using as the character for a space. By default this will be the space
-% character from OT1 cmtt but by changing
-% |\verbvisiblespace| one could use, for example, the |\textvisiblespace|
-% of the current typewriter font.
-% \begin{macrocode}
- \setbox\z@\hbox{x}%
- \setbox\@verbvisiblespacebox\hbox to\wd\z@{\hss\verbvisiblespace\hss}%
- \def\@xobeysp{\leavevmode\copy\@verbvisiblespacebox}%
- \fi
-}
-% \end{macrocode}
-% \end{macro}
+% ^^A \@setupverbvisiblespace was here
%
-
% \begin{macro}{\@verbvisiblespacebox}
% The box to hold the visible space character if it isn't in slot
% 32 in the current typewriter font.
@@ -1426,6 +1476,8 @@
% check if space is already active---it shouldn't be.
% \changes{v1.1o}{2018/10/11}
% {Provide visible space in \cs{verb*} also for XeTeX and LuaTeX (github/69)}
+% \changes{v1.2b}{2023/06/14}
+% {Support visible tabs in \cs{verb*}}
% \begin{macrocode}
\@namedef{verbatim*}{\@verbatim
\@setupverbvisiblespace
@@ -1434,8 +1486,6 @@
% \end{macrocode}
% \end{environment}
%
-%
-%
% \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
@@ -1452,7 +1502,88 @@
%<*2ekernel>
% \end{macrocode}
%
+% \begin{macro}{\@setupverbvisiblespace}
%
+% In pdf\TeX{} a catcode 12 space will produce the character in
+% slot 32 which is assumed to be a visible space character (in a
+% typewriter font in OT1 or T1 encoding). In Xe\TeX{} or Lua\TeX{} a
+% font in TU encoding is normally used and that has a real space in
+% this slot. So what we do in this case is this: we check the
+% definition of
+% |\verbvisiblespace| and if it is |\asciispace| we assume that the
+% char32 can be used (e.g., in pdf\TeX{}). We then redefine
+% |\@xobeysp| so that after running |\@vobeyspaces| we get
+% characters from slot 32 for each active space.
+%
+% \changes{v1.1o}{2018/10/11}
+% {Provide visible space in \cs{verb*} also for XeTeX and LuaTeX (github/69)}
+% \changes{v1.2b}{2023/06/15}
+% {Support visible tabs}
+% \begin{macrocode}
+%</2ekernel>
+%<*2ekernel|latexrelease>
+%<latexrelease>\IncludeInRelease{2023/11/01}%
+%<latexrelease> {\@setupverbvisiblespace}{Setup visible tab for \verb}%
+\def\@setupverbvisiblespace{%
+ \ifx\verbvisiblespace\asciispace
+ \let\@xobeysp\asciispace
+ \else
+% \end{macrocode}
+% Otherwise we measure the width of a character in
+% the mono-spaced current font and place a
+% |\verbvisiblespace| into a box of the right width which we are then
+% using as the character for a space. By default this will be the space
+% character from OT1 cmtt but by changing
+% |\verbvisiblespace| one could use, for example, the |\textvisiblespace|
+% of the current typewriter font.
+% \begin{macrocode}
+ \setbox\z@\hbox{x}%
+ \setbox\@verbvisiblespacebox\hbox to\wd\z@{\hss\verbvisiblespace\hss}%
+ \def\@xobeysp{\leavevmode\copy\@verbvisiblespacebox}%
+ \fi
+ \@setupverbvisibletab
+}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{2018/12/01}%
+%<latexrelease> {\@setupverbvisiblespace}{Setup visible space for \verb}%
+%<latexrelease>\def\@setupverbvisiblespace{%
+%<latexrelease> \ifx\verbvisiblespace\asciispace
+%<latexrelease> \let\@xobeysp\asciispace
+%<latexrelease> \else
+%<latexrelease> \setbox\z@\hbox{x}%
+%<latexrelease> \setbox\@verbvisiblespacebox\hbox to\wd\z@{\hss\verbvisiblespace\hss}%
+%<latexrelease> \def\@xobeysp{\leavevmode\copy\@verbvisiblespacebox}%
+%<latexrelease> \fi
+%<latexrelease>}
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease> {\@setupverbvisiblespace}{Setup visible space for \verb}%
+%<latexrelease>\let\@setupverbvisiblespace\@undefined
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\@setupverbvisibletab}
+% \changes{v1.2q}{2023/06/15}
+% {Provide visible tab in \cs{verb*}}
+% A redirection: just a simple wrapper.
+% \begin{macrocode}
+%</2ekernel>
+%<latexrelease>\IncludeInRelease{2023/11/01}%
+%<latexrelease> {\@setupverbvisibletab}{Setup visible tab for \verb}%
+%<*2ekernel|latexrelease>
+\def\@setupverbvisibletab{\let\@xobeytab\@xobeysp}
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease> {\@setupverbvisibletab}{Setup visible tab for \verb}%
+%<latexrelease>\let\@setupverbvisibletab\@undefined
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
+% \end{macrocode}
+% \end{macro}
%
% \begin{macro}{\@sverb}
% \begin{macro}{\@@sverb}
@@ -1464,8 +1595,8 @@
% \begin{macrocode}
%</2ekernel>
%<*2ekernel|latexrelease>
-%<latexrelease>\IncludeInRelease{2020/10/01}%
-%<latexrelease> {\@sverb}{Drop spaces before \verb delimiter}%
+%<latexrelease>\IncludeInRelease{2023/11/01}%
+%<latexrelease> {\@sverb}{Support visible tabs}%
% \end{macrocode}
%
% If the users types \verb=\verb !~! foo= then surprisingly we would
@@ -1496,8 +1627,13 @@
% it the definition for the active space character.
% \changes{v1.1o}{2018/10/11}
% {Provide visible space in \cs{verb*} also for XeTeX and LuaTeX (github/69)}
+% \changes{v1.2b}{2023/06/15}
+% {Support visible tabs}
% \begin{macrocode}
- \ifnum\catcode`\ =\active
+ \ifnum0%
+ \ifnum\catcode`\ =\active\else 1\fi
+ \ifnum\catcode`\^^I=\active\else 1\fi
+ =0 %
\else \@setupverbvisiblespace \@vobeyspaces \fi
}
% \end{macrocode}
@@ -1505,6 +1641,19 @@
% \begin{macrocode}
%</2ekernel|latexrelease>
%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{2020/10/01}%
+%<latexrelease> {\@sverb}{Drop spaces before \verb delimiter}%
+%<latexrelease>\def\@@sverb#1{%
+%<latexrelease> \catcode`#1\active
+%<latexrelease> \lccode`\~`#1%
+%<latexrelease> \gdef\verb@balance@group{\verb@egroup
+%<latexrelease> \@latex@error{\noexpand\verb illegal in argument}\@ehc}%
+%<latexrelease> \aftergroup\verb@balance@group
+%<latexrelease> \lowercase{\let~\verb@egroup}%
+%<latexrelease> \ifnum\catcode`\ =\active
+%<latexrelease> \else \@setupverbvisiblespace \@vobeyspaces \fi
+%<latexrelease>}
+%<latexrelease>\EndIncludeInRelease
%<latexrelease>\IncludeInRelease{2018/12/01}%
%<latexrelease> {\@sverb}{Setup visible space for \verb}%
%<latexrelease>
diff --git a/Master/texmf-dist/source/latex-dev/base/ltproperties.dtx b/Master/texmf-dist/source/latex-dev/base/ltproperties.dtx
new file mode 100644
index 00000000000..71b6e2a14fe
--- /dev/null
+++ b/Master/texmf-dist/source/latex-dev/base/ltproperties.dtx
@@ -0,0 +1,943 @@
+% \iffalse meta-comment
+%
+%% File: ltproperties.dtx
+%
+% Copyright (C) 2021-2023 The LaTeX Project
+%
+% It may be distributed and/or modified under the conditions of the
+% LaTeX Project Public License (LPPL), either version 1.3c of this
+% license or (at your option) any later version. The latest version
+% of this license is in the file
+%
+% http://www.latex-project.org/lppl.txt
+%
+% This file is part of the LaTeX base system. (The Work in LPPL)
+% and all files in that bundle must be distributed together.
+%
+% -----------------------------------------------------------------------
+%
+% The development version of the bundle can be found at
+%
+% https://github.com/latex3/latex2e
+%
+% for those people who are interested.
+% \begin{macrocode}
+\def\ltpropertiesversion{1.0b}
+\def\ltpropertiesdate{2023-09-13}
+% \end{macrocode}
+
+%<*driver>
+\documentclass[full]{l3doc}
+\EnableCrossrefs
+\CodelineIndex
+\begin{document}
+ \DocInput{ltproperties.dtx}
+\end{document}
+%</driver>
+% \fi
+%
+% \title{^^A
+% Recording and cross-referencing document properties^^A
+% \thanks{This module has version
+% \ltpropertiesversion\ dated \ltpropertiesdate, \copyright\ The \LaTeX\
+% Project.}
+% }
+%
+% \author{^^A
+% The \LaTeX\ Project\thanks
+% {^^A
+% E-mail:
+% \href{mailto:latex-team@latex-project.org}
+% {latex-team@latex-project.org}^^A
+% }^^A
+% }
+%
+% \maketitle
+%
+% \begin{documentation}
+% \begin{abstract}
+% This code implements command to record and (expandably) reference
+% document properties. It extends the standard \cs{label}/\cs{ref}/\cs{pageref}
+% commands.
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Introduction}
+%
+% The module allows to record the \enquote{current state} of various
+% document properties (typically the content of macros and values of counters)
+% and to access them in other places through a label.
+% The list of properties that can be recorded and retrieved
+% are not fix and can be extended by the user. The values of the properties
+% are recorded in the \texttt{.aux} file and can be retrieved at the second compilation.
+%
+%
+% The module uses the ideas of properties and labels. A label is
+% a document reference point: a name for the user. An property is something
+% that \LaTeX{} can track, such as a page number, section number or name.
+% The names of labels and properties may be arbitrary. Note that there is
+% a single namespace for each.
+%
+% \section{Design discussion}
+%
+% The design here largely follows ideas from \pkg{zref}. In particular, there
+% are two independent concepts: properties that can be recorded between runs,
+% and labels which consist of lists of these properties. The reason for the
+% split is that individual labels will want to record some but not all
+% properties. For examples, a label concerned with position would track
+% the $x$ and $y$ co-ordinates of the current point, but not for example
+% the page number.
+%
+% In the current implementation, properties share a single namespace. This
+% allows multiple lists to re-use the same properties, for example page number,
+% absolute page number, etc. This does mean that \emph{changing} a standard
+% property is an issue. However, some properties have complex definitions
+% (again, see \pkg{zref} at present): having them in a single shared space
+% avoids the need to copy code.
+%
+% Labels could be implemented as |prop| data. That is not done at present as
+% there is no obvious need to map to or copy the data. As such, faster
+% performance is available using a hash table approach as in a \enquote{classical}
+% set up. Data written to the |.aux| file uses simple paired \emph{balanced
+% text} not keyvals: this avoids any restrictions on names and again offers
+% increased performance.
+%
+% The \pkg{expl3} versions of the label command do not
+% use \cs{@bsphack}/\cs{@esphack} to avoid double spaces,
+% but the \LaTeXe{} command does as it lives at the document command level.
+%
+% The reference commands are expandable.
+%
+% Currently the code has nearly no impact on the main \cs{label} and \cs{ref} commands as
+% too many external packages rely on the concrete implementation.
+% There is one exception:
+% the label names share the same namespace. That means that if both |\label{ABC}| and
+% |\RecordProperties{ABC}{page}| are used there is a warning
+% \texttt{Label `ABC' multiply defined}.
+%
+% \section{Handling unknown labels and properties}
+% With the standard \cs{label}/\cs{ref} commands the requested label is
+% either in the |.aux|-file (and so known) or not.
+% In the first case the stored value can be used,
+% in the second case the reference commands print two question marks.
+%
+% With flexible property lists a reference commands asks for the
+% value of a specific property stored under a label name
+% and we have to consider more variants:
+% \begin{itemize}
+% \item If the requested property is unknown (not declared) the system
+% is not correctly set up and an error is issued.
+% \item If the label is unknown, the default of the property is used.
+% \item If the label is known, but doesn't provide a value for the
+% property then again the default of the property is used.
+% \item The command |\property_ref:nnn| allows to give a local default
+% which is used instead of the property default in the two cases before.
+% \end{itemize}
+%
+% \section{Rerun messages}
+%
+% As the reference commands are expandable they can neither issue a message that
+% the label or the label-property combination is unknown, nor can they trigger the
+% rerun message at the end of the \LaTeX{} run.
+%
+% Where needed such messages must therefore be triggered manually. For this two commands
+% are provided: \cs{property_ref_undefined_warn:} and \cs{property_ref_undefined_warn:nn}.
+% See below for a description.
+%
+% \section{Open points}
+%
+% \begin{itemize}
+% \item The \texttt{xpos} and \texttt{ypos} properties require that the position is
+% stored first but there is no (public) engine independent interface yet. Code must
+% use \cs{tex_savepos:D}.
+% \end{itemize}
+%
+% \section{Code interfaces}
+%
+% \begin{function}{\property_new:nnnn,\property_gset:nnnn}
+% \begin{syntax}
+% \cs{property_new:nnnn} \Arg{property} \Arg{setpoint} \Arg{default} \Arg{code}
+% \cs{property_gset:nnnn} \Arg{property}\Arg{setpoint} \Arg{default} \Arg{code}
+% \end{syntax}
+% \LaTeXe-interface: see \cs{NewProperty}, \cs{SetProperty}.\\
+% Sets the \meta{property} to have the \meta{default} specified, and at the
+% \meta{setpoint} (either |now| or |shipout|) to write the result of the
+% \meta{code} as part of a label. The \meta{code} should be expandable. The expansion
+% of \meta{code} (the value of the property) is written to the |.aux| file and read
+% back from there at the next compilation. Values should assume that the
+% standard \LaTeX{} catcode régime with |@| a letter is active then.
+%
+% If the property is declared within a package it is suggested
+% that its name is build from letters, hyphens and slashes,
+% and is always structured as follows:\\
+% \meta{package-name}\texttt{/}\meta{property-name}.
+% \end{function}
+%
+% \begin{function}
+% {
+% \property_record:nN,
+% \property_record:nn, \property_record:nV, \property_record:xx
+% }
+% \begin{syntax}
+% \cs{property_record:nN} \Arg{label} \Arg{clist var}
+% \cs{property_record:nn} \Arg{label} \Arg{clist}
+% \end{syntax}
+% \LaTeXe{}-interface: see \cs{RecordProperties}.\\
+% Writes the list of properties given by the \meta{clist} to the |.aux|
+% file with the \meta{label} specified.
+% \end{function}
+%
+% \begin{function}[EXP]{\property_ref:nn,\property_ref:ee}
+% \begin{syntax}
+% \cs{property_ref:nn} \Arg{label} \Arg{property}
+% \end{syntax}
+% \LaTeXe{}-interface: see \cs{RefProperty}.\\
+% Expands to the value of the \meta{property} for the \meta{label}, if
+% available, and the default value of the property otherwise.
+% If \meta{property} has not been declared with |\property_new:nnnn|
+% an error is issued. The command raises an internal, expandable, local flag
+% if the reference can not be resolved.
+% \end{function}
+%
+% \begin{function}[EXP]{\property_ref:nnn,\property_ref:een}
+% \begin{syntax}
+% \cs{property_ref:nnn} \Arg{label} \Arg{property} \Arg{local default}
+% \end{syntax}
+% \LaTeXe{}-interface: see \cs{RefProperty}.\\
+% Expands to the value of the \meta{property} for the \meta{label}, if
+% available, and to \meta{local default} otherwise.
+% If \meta{property} has not been declared with |\property_new:nnnn|
+% an error is issued. The command raises an internal, expandable local flag
+% if the reference can not be resolved.
+% \end{function}
+%
+% \begin{function}{\property_ref_undefined_warn:}
+% \begin{syntax}
+% \cs{property_ref_undefined_warn:}
+% \end{syntax}
+% \LaTeXe{}-interface: not provided.\\
+% The commands triggers the standard warning
+% \\
+% \hspace*{1em}\texttt{LaTeX Warning: There were undefined references.}
+% \\
+% at the end of the document if there was a recent
+% \cs{property_ref:nn} or \cs{property_ref:nnn} which couldn't be resolved
+% and so raised the flag. \enquote{Recent} means in the same group
+% or in some outer group!
+% \end{function}
+%
+% \begin{function}{\property_ref_undefined_warn:n,\property_ref_undefined_warn:x}
+% \begin{syntax}
+% \cs{property_ref_undefined_warn:n} \Arg{label}
+% \end{syntax}
+% \LaTeXe{}-interface: not provided.\\
+% The commands triggers the standard warning\\
+% \hspace*{1em}\texttt{LaTeX Warning: There were undefined references.}
+% \\
+% at the end of the document if \meta{label} is not known.
+% At the point where it is called it also issues the warning\\
+% \hspace*{1em}%
+% \texttt{Reference~`\meta{label}'~on~page~\meta{page}\space undefined}.
+% \end{function}
+%
+% \begin{function}{\property_ref_undefined_warn:nn,\property_ref_undefined_warn:xx}
+% \begin{syntax}
+% \cs{property_ref_undefined_warn:nn} \Arg{label} \Arg{property}
+% \end{syntax}
+% \LaTeXe{}-interface: see \cs{RefUndefinedWarn}.\\
+% The commands triggers the standard warning\\
+% \hspace*{1em}%
+% \texttt{LaTeX Warning: There were undefined references.}\\
+% at the end of the document if the reference can not be resolved.
+% At the point where it is called it also issues the warning\\
+% \hspace*{1em}%
+% \texttt{Reference~`\meta{label}'~on~page~\meta{page}\space undefined}\\
+% if the label
+% is unknown, or the more specific\\
+% \hspace*{1em}%
+% \texttt{Property `\meta{property}' undefined for reference
+% `\meta{label}' on page \meta{page}}\\
+% if the label is known but doesn't provide a value for the requested property.
+% \end{function}
+%
+% \begin{function}[pTF]{\property_if_exist:n,\property_if_exist:e}
+% \begin{syntax}
+% \cs{property_if_exist_p:n} \Arg{property}
+% \cs{property_if_exist:nTF} \Arg{property} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% \LaTeXe{}-interface: \cs{IfPropertyExistTF}.\\
+% Tests if the \meta{property} has been declared.
+% \end{function}
+%
+% \begin{function}[pTF]{\property_if_recorded:n,\property_if_recorded:e}
+% \begin{syntax}
+% \cs{property_if_recorded_p:n} \Arg{label}
+% \cs{property_if_recorded:nTF} \Arg{label} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% \LaTeXe{}-interface: \cs{IfLabelExistTF}\\
+% Tests if the \meta{label} is known. This is also true if the label has been
+% set with the standard \cs{label} command.
+% \end{function}
+%
+% \begin{function}[pTF]{\property_if_recorded:nn,\property_if_recorded:ee}
+% \begin{syntax}
+% \cs{property_if_recorded_p:nn} \Arg{label} \Arg{property}
+% \cs{property_if_recorded:nnTF} \Arg{label} \Arg{property} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% \LaTeXe{}-interface: \cs{IfPropertyRecordedTF}.\\
+% Tests if the label \meta{label} is known and if it provides a value of the \meta{property}.
+% \end{function}
+%
+% \section{Auxiliary file interfaces}
+%
+% \begin{function}{\new@label@record}
+% \begin{syntax}
+% \cs{new@label@record} \Arg{label} \Arg{data}
+% \end{syntax}
+% This is a command only for use in the |.aux| file. It loads the key--value
+% list of \meta{data} to be available for the \meta{label}.
+% \end{function}
+%
+% \section{\LaTeXe{} interface}
+%
+% The LaTeXe{} interfaces always expand label and property arguments.
+%
+% \begin{function}{\NewProperty,\SetProperty}
+% \begin{syntax}
+% \cs{NewProperty} \Arg{property} \Arg{setpoint} \Arg{default} \Arg{code}
+% \cs{SetProperty} \Arg{property} \Arg{setpoint} \Arg{default} \Arg{code}
+% \end{syntax}
+% Sets the \meta{property} to have the \meta{default} specified, and at the
+% \meta{setpoint} (either |now| or |shipout|) to write the result of the
+% \meta{code} as part of a label. The \meta{code} should be expandable. The expansion
+% of \meta{code} (the value of the property) is written to the |.aux| file and read
+% back from there at the next compilation (at which point normally
+% the standard \LaTeX{} catcode régime with |@| a letter is active).
+%
+% \end{function}
+%
+% \begin{function}{\RecordProperties}
+% \begin{syntax}
+% \cs{RecordProperties} \Arg{label} \Arg{clist}
+% \end{syntax}
+% Writes the list of properties given by the \meta{clist} to the |.aux|
+% file with the \meta{label} specified. Similar to the standard \cs{label} command
+% the arguments are expanded. So \meta{clist} can be a macro containing a list
+% of properties. Also similar to the standard \cs{label} command, the command is surrounded
+% by an \cs{@bsphack}/\cs{@esphack} pair to preserve spacing.
+% \end{function}
+
+% \begin{function}[EXP]{\RefProperty}
+% \begin{syntax}
+% \cs{RefProperty} \oarg{local default} \Arg{label} \Arg{property}
+% \end{syntax}
+% Expands to the value of the \meta{property} for the \meta{label}, if
+% available, and the default value of the property or -- if given --
+% to \meta{local default} otherwise.
+% If \Arg{property} has not been declared an error is issued.
+% \end{function}
+%
+% \begin{function}{\IfPropertyExistTF}
+% \begin{syntax}
+% \cs{IfPropertyExistTF} \Arg{property} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{property} has been declared.
+% \end{function}
+%
+% \begin{function}{\IfLabelExistTF}
+% \begin{syntax}
+% \cs{IfLabelExistTF} \Arg{label} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the \meta{label} has been recorded. This is also true if a label
+% has been set with the standard \cs{label} command.
+% \end{function}
+%
+% \begin{function}{\IfPropertyRecordedTF}
+% \begin{syntax}
+% \cs{IfPropertyRecordedTF} \Arg{label} \Arg{property} \Arg{true code} \Arg{false code}
+% \end{syntax}
+% Tests if the label and a value of the \meta{property} for the \meta{label} are both known.
+% \end{function}
+
+% \begin{function}{\RefUndefinedWarn}
+% \begin{syntax}
+% \cs{RefUndefinedWarn} \Arg{label} \Arg{property}
+% \end{syntax}
+% This commands triggers the standard warning\\
+% \hspace*{1em}%
+% \texttt{LaTeX Warning: There were undefined references.}\\
+% at the end of the document if the reference for \meta{label} and \meta{property}
+% can not be resolved.
+% At the point where it is called it also issues the warning\\
+% \hspace*{1em}%
+% \texttt{Reference `\meta{label}' on page \meta{page} undefined}\\
+% if the label is unknown, or the more specific\\
+% \hspace*{1em}%
+% \texttt{Property `\meta{property}' undefined for reference
+% `\meta{label}' on page \meta{page}}
+% if the label is known but doesn't provide a value for the requested property.
+% \end{function}
+%
+% \section{Pre-declared properties}
+%
+% \begin{variable}{abspage}
+% (shipout) The absolute value of the current page: starts at $1$ and increases
+% monotonically at each shipout.
+% \end{variable}
+%
+% \begin{variable}{page}
+% (shipout) The current page as given by \cs{thepage}: this may or may not
+% be a numerical value, depending on the current style. Contrast with
+% \cs{abspage}. You get this value also with the standard \cs{label}/\cs{pageref}.
+% \end{variable}
+%
+% \begin{variable}{pagenum}
+% (shipout) The current page as arabic number. This is suitable for integer operations and
+% comparisions.
+% \end{variable}
+%
+% \begin{variable}{currentlabel}
+% (now) The content of \cs{@currentlabel}. This is the value that
+% you get also with the standard \cs{label}/\cs{ref}.
+% \end{variable}
+%
+% \begin{variable}{title}
+% (now) The content of \cs{@currentlabelname}.
+% This command is filled beside others by the \pkg{nameref} package and some
+% classes (e.g.~\pkg{memoir}).
+% \end{variable}
+%
+% \begin{variable}{target}
+% (now) The content of \cs{@currentHref}.
+% This command is normally filled by for example by
+% \pkg{hyperref} and gives the name of the last destination it created.
+% \end{variable}
+%
+% \begin{variable}{counter}
+% (now) The content of \cs{@currentcounter}.
+% This command contains after a \cs{refstepcounter} the name of the counter.
+% \end{variable}
+%
+% \begin{variable}{xpos,ypos}
+% (shipout) This stores the $x$~and $y$ coordinates of a point previously
+% stored with \cs{pdfsavepos}/\cs{savepos}.
+% E.g.~(if bidi is used it can be necessary to save the position
+% before and after the label):
+% \begin{verbatim}
+% \tex_savepos:D
+% \property_record:nn{myposition}{xpos,ypos}
+% \tex_savepos:D
+% \end{verbatim}
+% \end{variable}
+% \end{documentation}
+%
+% \begin{implementation}
+%
+% \section{The Implementation}
+%
+% \begin{macrocode}
+%<*2ekernel|latexrelease>
+% \end{macrocode}
+% \begin{macrocode}
+\ExplSyntaxOn
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=property>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<latexrelease>\NewModuleRelease{2023/11/01}{ltproperties}
+%<latexrelease> {Cross-referencing~properties}
+% \end{macrocode}
+%
+% The approach here is based closely on that from \pkg{zref}; separate out
+% lists of properties and the properties themselves, so the latter can be
+% used multiple times and in varying combinations.
+% However, not everything is a straight copy. Firstly,
+% we treat lists of properties as simple comma lists: that allows us to have
+% either saved or dynamic lists and to avoid another data structure. The cost
+% is that errors are detected at point-of-use, but in any real case that should
+% be true anyway (and is true for \tn{zref@labelbyprop} already). Secondly,
+% we allow properties to have
+% arbitrary names, as the code does not require them to tokenize as control
+% sequences.
+%
+% \begin{macro}{\property_new:nnnn, \property_gset:nnnn, \@@_gset:nnnn}
+% As properties can be reset, they are not constants. But they also have
+% various pieces of required data. So we use the same approach as color and
+% make them declarations. Data-wise, we need the detail of the implementation,
+% the default and a flag to show if the code works now or at shipout. This
+% last entry is done using text so needs a check. We could use a set of
+% |prop| here, but as we never need to map or copy the lists, we can gain
+% performance using the hash table approach.
+% \begin{macrocode}
+\cs_new_protected:Npn \property_new:nnnn #1#2#3#4
+ {
+ \cs_if_free:cTF { @@_code_ #1 : }
+ {
+ \exp_args:Nx \@@_gset:nnnn { \tl_to_str:n {#1} }
+ {#2} {#3} {#4}
+ }
+ {
+ \msg_error:nn { property }{ exists }{#1}
+ }
+ }
+\cs_new_protected:Npn \property_gset:nnnn #1#2#3#4
+ {
+ \@@_gset:xnnn { \tl_to_str:n {#1} }
+ {#2} {#3} {#4}
+ }
+\cs_new_protected:Npn \@@_gset:nnnn #1#2#3#4
+ {
+ \cs_gset:cpn { @@_code_ #1 : } {#4}
+ \tl_gclear_new:c { g_@@_default_ #1 _tl }
+ \tl_gset:cn { g_@@_default_ #1 _tl } {#3}
+ \bool_if_exist:cF { g_@@_shipout_ #1 _tl }
+ { \bool_new:c { g_@@_shipout_ #1 _tl } }
+ \str_case:nnF {#2}
+ {
+ { now } { { \bool_gset_false:c { g_@@_shipout_ #1 _tl } } }
+ { shipout }
+ { \bool_gset_true:c { g_@@_shipout_ #1 _tl } }
+ }
+ { \msg_error:nnnn { property } { unknown-setpoint } {#1} {#2} }
+ }
+\cs_generate_variant:Nn \@@_gset:nnnn {xnnn}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\NewProperty,\SetProperty}
+% For consistency we expand the property name, but this doesn't warant a
+% variant of the L3-commands.
+% \begin{macrocode}
+\cs_new_protected:Npn \NewProperty #1#2#3#4
+ {
+ \exp_args:Nx \property_new:nnnn {#1}{#2}{#3}{#4}
+ }
+\cs_new_protected:Npn \SetProperty #1#2#3#4
+ {
+ \exp_args:Nx \property_gset:nnnn {#1}{#2}{#3}{#4}
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\property_record:nN}
+% \begin{macro}
+% {
+% \property_record:nn,
+% \property_record:nV,
+% \property_record:xx,
+% \@@_record:nn,
+% \@@_record:xn
+% }
+% \begin{macro}[EXP]
+% {\@@_record_value:n, \@@_record_value_aux:n, \@@_record_value_aux:e}
+% Writing data when it is labelled means expanding at this stage and possibly
+% later too. That is all pretty easy using \pkg{expl3}: we accept a stray
+% comma at the end of the list as that is easier to deal with than trying
+% to tidy up, and there is no real downside.
+% \begin{macrocode}
+\cs_new_protected:Npn \property_record:nN #1#2
+ { \property_record:nV {#1} #2 }
+\cs_new_protected:Npn \property_record:nn #1#2
+ { \@@_record:xn { \tl_to_str:n {#1} } {#2} }
+\cs_generate_variant:Nn \property_record:nn { nV , xx }
+\cs_new_protected:Npn \@@_record:nn #1#2
+ {
+ \legacy_if:nT { @filesw }
+ {
+ \iow_shipout_x:Nx \@auxout
+ {
+ \token_to_str:N \new@label@record
+ {#1}
+ { \clist_map_function:nN {#2} \@@_record_value:n }
+ }
+ }
+ }
+\cs_generate_variant:Nn \@@_record:nn { x }
+\cs_new:Npn \@@_record_value:n #1
+ { \@@_record_value_aux:e { \tl_to_str:n {#1} } }
+\cs_new:Npn \@@_record_value_aux:n #1
+ {
+ \cs_if_exist:cTF { @@_code_ #1 : }
+ {
+ {#1}
+ {
+ \bool_if:cTF { g_@@_shipout_ #1 _tl }
+ { \exp_not:c }
+ { \use:c }
+ { @@_code_ #1 : }
+ }
+ }
+ { \msg_expandable_error:nnn { property } { not-declared } {#1} }
+ }
+\cs_generate_variant:Nn \@@_record_value_aux:n { e }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\RecordProperties}
+% \begin{macrocode}
+\NewDocumentCommand\RecordProperties { m m }
+ {
+ \@bsphack
+ \property_record:xx {#1}{#2}
+ \@esphack
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Reference commands}
+%
+% \begin{variable}{ l_@@_ref_flag }
+% A flag that is set if a reference couldn't be resolved.
+% \begin{macrocode}
+\flag_new:n { l_@@_ref_flag }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{macro}[EXP]{\property_ref:nn,\property_ref:ee}
+% Search for the label/property combination, and if not found fall back
+% to the default of the property.
+% \begin{macrocode}
+\cs_new:Npn \property_ref:nn #1#2
+ {
+ \@@_ref:een
+ { \tl_to_str:n {#1} }
+ { \tl_to_str:n {#2} }
+ { \tl_use:c { g_@@_default_ #2 _tl } }
+ }
+\cs_generate_variant:Nn \property_ref:nn {ee}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\property_ref:nnn,\property_ref:een, \@@_ref:nnn, \@@_ref:een}
+% This allows to set a local default value which overrides the default value
+% of the property.
+% \begin{macrocode}
+\cs_new:Npn \property_ref:nnn #1#2#3
+ {
+ \@@_ref:een
+ { \tl_to_str:n {#1} }
+ { \tl_to_str:n {#2} }
+ {#3}
+ }
+\cs_new:Npn \@@_ref:nnn #1#2#3
+ {
+ \tl_if_exist:cTF { g_@@_label_ #1 _ #2 _tl }
+ { \tl_use:c { g_@@_label_ #1 _ #2 _tl } }
+ {
+ \flag_if_raised:nF
+ { l_@@_ref_flag } { \flag_raise:n { l_@@_ref_flag } }
+% \end{macrocode}
+% We test for the default of the property only to check if the property has
+% been declared.
+% \begin{macrocode}
+ \tl_if_exist:cTF { g_@@_default_ #2 _tl }
+ { #3 }
+ { \msg_expandable_error:nnn { property } { not-declared } {#2} }
+ }
+ }
+\cs_generate_variant:Nn \@@_ref:nnn { ee }
+\cs_generate_variant:Nn \property_ref:nnn {een}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[EXP]{\RefProperty}
+% Search for the label/property combination, and if not found fall back
+% to the default of the property or the given default.
+% \begin{macrocode}
+\NewExpandableDocumentCommand \RefProperty { o m m }
+ {
+ \IfNoValueTF {#1}
+ {
+ \property_ref:ee {#2}{#3}
+ }
+ {
+ \property_ref:een {#2}{#3}{#1}
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\new@label@record}
+% \begin{macro}{\@@_data:nnn}
+% A standard recursion loop.
+% \begin{macrocode}
+\cs_new_protected:Npn \new@label@record #1#2
+ {
+ \tl_if_exist:cTF { r@#1 }
+ {
+ \gdef \@multiplelabels
+ { \@latex@warning@no@line { There~were~multiply-defined~labels } }
+ \@latex@warning@no@line { Label~`#1'~multiply~defined }
+ }
+ {
+ \tl_new:c { r@#1 }
+ \tl_gset:cn { r@#1 }{#2}
+ }
+ \@@_data:nnn {#1} #2 { \q_recursion_tail } { ? } \q_recursion_stop
+ }
+\cs_new_protected:Npn \@@_data:nnn #1#2#3
+ {
+ \quark_if_recursion_tail_stop:n {#2}
+ \tl_gclear_new:c { g_@@_label_ \tl_to_str:n {#1} _ \tl_to_str:n {#2} _tl }
+ \tl_gset:cn { g_@@_label_ \tl_to_str:n {#1} _ \tl_to_str:n {#2} _tl } {#3}
+ \@@_data:nnn {#1}
+ }
+% \end{macrocode}
+%
+% This command is used in \cs{enddocument} to test if some label values have changed.
+% \begin{macrocode}
+\cs_new_protected:Npn \@kernel@new@label@record@testdef #1 #2
+ {
+ \tl_if_eq:cnF { r@#1 } {#2}
+ { \@tempswatrue }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \subsection{Tests and warnings}
+%
+% \begin{macro}[pTF]{\property_if_exist:n}
+% Tests if property has been declared.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \property_if_exist:n #1 { p , T , F, TF }
+ % #1 property
+ {
+ \cs_if_exist:cTF { @@_code_ #1 : }
+ {
+ \prg_return_true:
+ }
+ {
+ \prg_return_false:
+ }
+ }
+\prg_generate_conditional_variant:Nnn \property_if_exist:n {e} {TF}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{IfPropertyExistTF}
+% \begin{macrocode}
+\cs_new_eq:NN \IfPropertyExistTF \property_if_exist:eTF
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\property_if_recorded:n}
+% Tests if the label has been set.
+% This can then be used to setup e.g.~rerun messages.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \property_if_recorded:n #1 { p , T , F, TF }
+ % #1 label
+ {
+ \tl_if_exist:cTF { r@#1 }
+ {
+ \prg_return_true:
+ }
+ {
+ \prg_return_false:
+ }
+ }
+\prg_generate_conditional_variant:Nnn \property_if_recorded:n {e} {TF}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\IfLabelExistTF}
+% \begin{macrocode}
+\cs_new_eq:NN \IfLabelExistTF \property_if_recorded:eTF
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}[pTF]{\property_if_recorded:nn}
+% tests if the label/property combination has been set
+% This can then be used to setup e.g.~rerun messages.
+% \begin{macrocode}
+\prg_new_conditional:Npnn \property_if_recorded:nn #1#2 { p , T , F, TF }
+ % #1 label #2 property
+ {
+ \tl_if_exist:cTF { g_@@_label_ \tl_to_str:n {#1} _ \tl_to_str:n {#2} _tl }
+ {
+ \prg_return_true:
+ }
+ {
+ \prg_return_false:
+ }
+ }
+\prg_generate_conditional_variant:Nnn \property_if_recorded:nn {ee} {TF}
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\IfPropertyRecordedTF}
+% \begin{macrocode}
+\cs_new_eq:NN \IfPropertyRecordedTF \property_if_recorded:eeTF
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\property_ref_undefined_warn:}
+% \cs{G@refundefinedtrue} is defined in \texttt{ltxref} and redefines a warning message.
+% \begin{macrocode}
+\cs_new_protected:Npn \property_ref_undefined_warn:
+ {
+ \flag_if_raised:nT { l_@@_ref_flag }
+ {
+ \G@refundefinedtrue
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\property_ref_undefined_warn:n}
+% \begin{macrocode}
+\cs_new_protected:Npn \property_ref_undefined_warn:n #1 %#1 label
+ {
+ \property_if_recorded:nF {#1}
+ {
+ \G@refundefinedtrue
+ \@latex@warning{Reference~`#1'~on~page~\thepage\space undefined}%
+ }
+ }
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\property_ref_undefined_warn:nn,
+% \property_ref_undefined_warn:xx,
+% \RefUndefinedWarn}
+% \begin{macrocode}
+\cs_new_protected:Npn \property_ref_undefined_warn:nn #1#2 %#1 label, #2 property
+ {
+ \property_if_recorded:nTF {#1}
+ {
+ \property_if_recorded:nnF {#1}{#2}
+ {
+ \G@refundefinedtrue
+ \@latex@warning
+ { Property~`#2'~undefined~for~reference~`#1'~on~page~\thepage }
+ }
+ }
+ {
+ \G@refundefinedtrue
+ \@latex@warning { Reference~`#1'~on~page~\thepage\space undefined }%
+ }
+ }
+\cs_generate_variant:Nn \property_ref_undefined_warn:nn {xx}
+\cs_set_eq:NN \RefUndefinedWarn \property_ref_undefined_warn:xx
+% \end{macrocode}
+% \end{macro}
+%
+% \subsection{Predeclared properties}
+%
+% \begin{variable}{abspage}
+% \begin{macrocode}
+\property_new:nnnn { abspage } { shipout }
+ { 0 } { \int_use:N \g_shipout_readonly_int }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{page}
+% \begin{macrocode}
+\property_new:nnnn { page } { shipout } { 0 } { \thepage }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{pagenum}
+% \begin{macrocode}
+\property_new:nnnn { pagenum } { shipout } { 0 } { \the \value { page } }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{currentlabel}
+% \begin{macrocode}
+\property_new:nnnn { currentlabel } { now } { ?? } { \@currentlabel }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{title}
+% \begin{macrocode}
+\property_new:nnnn { title } { now }
+ { \exp_not:n { \textbf { ?? } } } { \@currentlabelname }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{target}
+% \begin{macrocode}
+\property_new:nnnn { target } { now } { } { \@currentHref }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{counter}
+% \begin{macrocode}
+\property_new:nnnn { counter } { now } { } { \@currentcounter }
+% \end{macrocode}
+% \end{variable}
+%
+% \begin{variable}{xpos,ypos}
+% \begin{macrocode}
+\property_new:nnnn { xpos } { shipout } { 0} { \int_use:N \tex_lastxpos:D }
+\property_new:nnnn { ypos } { shipout } { 0} { \int_use:N \tex_lastypos:D }
+% \end{macrocode}
+% \end{variable}
+%
+% \subsection{Messages}
+% \begin{macrocode}
+\msg_new:nnnn { property } { exists }
+ { Property~'#1'~ has~ already~ been~ declared. }
+ { There~ already~ exists~ a~ property~ declaration~ with~ this~
+ name.\\
+ Please~ use~ a~ different~ name~ for~ your~ property.}
+
+\msg_new:nnnn { property } { not-declared }
+ { Property~'#1'~not~declared. }
+ {
+ LaTeX~has~been~asked~to~use~property~'#1',~but~this~
+ name~has~not~been~declared.
+ }
+\msg_new:nnnn { property } { unknown-setpoint }
+ { Unknown~keyword~'#2'~for~setting~property~'#1'. }
+ {
+ LaTeX~has~been~asked~to~set~the~property~'#1',~but~the~keyword~
+ '#2'~is~not~one~of~the~two~known~values:~'now'~or~'shipout'.
+ }
+% \end{macrocode}
+%
+% \begin{macrocode}
+%
+%<latexrelease>\IncludeInRelease{0000/00/00}{ltproperties}
+%<latexrelease> {cross-referencing~properties~(undo)}%
+%<latexrelease>
+%<latexrelease>\let \NewProperty \@undefined
+%<latexrelease>\let \SetProperty \@undefined
+%<latexrelease>
+%<latexrelease>\let \RecordProperties \@undefined
+%<latexrelease>\let \RefProperty \@undefined
+%<latexrelease>\let \RefUndefinedWarn \@undefined
+%<latexrelease>
+%<latexrelease>\let \IfPropertyExistTF \@undefined
+%<latexrelease>\let \IfLabelExistTF \@undefined
+%<latexrelease>\let \IfPropertyRecordedTF \@undefined
+%<latexrelease>
+%<latexrelease>\let\new@label@record \@undefined
+%<latexrelease>\let\@kernel@new@label@record@testdef\@undefined
+%<latexrelease>\EndModuleRelease
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ExplSyntaxOff
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</2ekernel|latexrelease>
+% \end{macrocode}
+%
+% Reset module prefix:
+% \begin{macrocode}
+%<@@=>
+% \end{macrocode}
+%
+%
+% \end{implementation}
+%
+% \Finale
diff --git a/Master/texmf-dist/source/latex-dev/base/ltsockets.dtx b/Master/texmf-dist/source/latex-dev/base/ltsockets.dtx
new file mode 100644
index 00000000000..7d2940f454b
--- /dev/null
+++ b/Master/texmf-dist/source/latex-dev/base/ltsockets.dtx
@@ -0,0 +1,1069 @@
+% \iffalse meta-comment
+%
+% Copyright (C) 2023
+% Frank Mittelbach, The LaTeX Project
+%
+% This file is part of the LaTeX base system.
+% -------------------------------------------
+%
+% It may be distributed and/or modified under the
+% conditions of the LaTeX Project Public License, either version 1.3c
+% of this license or (at your option) 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 file has the LPPL maintenance status "maintained".
+%
+% The list of all files belonging to the LaTeX base distribution is
+% given in the file `manifest.txt'. See also `legal.txt' for additional
+% information.
+%
+% The list of derived (unpacked) files belonging to the distribution
+% and covered by LPPL is defined by the unpacking scripts (with
+% extension .ins) which are part of the distribution.
+%
+% \fi
+%
+% \iffalse
+%
+%%% From File: ltsockets.dtx
+%
+% \begin{macrocode}
+\def\ltsocketsversion{0.9a}
+\def\ltsocketsdate{2023-08-21}
+% \end{macrocode}
+%
+%<*driver>
+\documentclass{l3doc}
+
+
+\providecommand\InternalDetectionOff{}
+\providecommand\InternalDetectionOn{}
+
+\EnableCrossrefs
+\CodelineIndex
+\begin{document}
+ \DocInput{ltsockets.dtx}
+\end{document}
+%</driver>
+%
+% \fi
+%
+%
+%
+%
+% \title{\LaTeX{}'s socket management\thanks{This module has version
+% \ltsocketsversion\ dated \ltsocketsdate, \copyright\ \LaTeX\
+% Project.}}
+%
+% \author{Frank Mittelbach}
+%
+% \maketitle
+%
+% ^^A this needs some cleanup:
+% \long\def\fmi#1{\begin{quote} TODO: \itshape #1\end{quote}}
+%
+% \providecommand\pkg[1]{\texttt{#1}}
+% \providecommand\hook[1]{\texttt{#1}}
+% \providecommand\env[1]{\texttt{#1}}
+% \providecommand\plug[1]{\texttt{#1}}
+% \providecommand\socket[1]{\texttt{#1}}
+%
+%
+% \begin{abstract}
+% This code implements sockets which are places in the code into
+% which predeclared chunks of code (plugs) can be placed. Both the sockets
+% and the plugs are \enquote{named} and each socket is
+% assigned exactly one plug at any given time.
+% \end{abstract}
+%
+% \tableofcontents
+%
+% \section{Introduction}
+%
+% A \LaTeX{} source file is transformed into a typeset document by
+% executing code for each command or environment in the document
+% source. Through various steps this code transforms the input and
+% eventually generates typeset output appearing in a \enquote{galley}
+% from which individual pages are cut off in an asyncronous way. This
+% page generating process is normally not directly associated with
+% commands in the input\footnote{Excepts for directives such as
+% \cs{newpage}.} but is triggered whenever the galley has received
+% enough material to form another page (giving current settings).
+%
+% As part of this transformation input data may get stored in some form
+% and later reused, for example, as part of the output routine
+% processing.
+%
+% \section{Configuration of the transformation process}
+%
+% There are three different major methods offered by \LaTeX{} to
+% configure the transformation process:
+% \begin{itemize}
+% \item through the template mechanism,
+% \item through the hook mechanism, or
+% \item through sockets and plugs.
+% \end{itemize}
+% They offer different possibilities (with different features and
+% limitations) and are intended for specific use cases, though it is
+% possible to combine them.
+%
+% \subsection{The template mechanism}
+%
+% The template mechanism is intended for more complex document-level
+% elements (e.g., headings such as \verb=\section= or environments like
+% \env{itemize}). The template code implements the overall processing
+% logic for such an element and offers a set of parameters to influence
+% the final result.
+%
+% The document element is then implemented by (a) selecting a suitable
+% template (there may be more than one available for the kind of
+% document element) and (b) by setting its parameters to desired
+% values. This then forms a so-called instance which is executed when
+% the document element is found in the source.
+%
+% By altering the parameter values (in a document class or in the
+% document preamble) or, if more drastic layout changes are desired, by
+% selecting a different template and then adjusting its parameters, a
+% wide variety of layouts can be realized through simple configuration
+% setups without the need to develop new code.
+%
+% The target audience of this method are therefore document class
+% developers or users who wish to alter an existing layout (implemented
+% by a document class) in certain (minor) ways.
+%
+% The template mechanism is currently documented as part of the
+% \pkg{xtemplate} package and one more elaborate implementation can be
+% found as part of the \texttt{latex-lab} code for lists (to be
+% documented further).
+%
+% \subsection{The hook mechanism}
+%
+% Hooks are places in the kernel code (or in packages) that offer
+% packages the possibility to inject additional code at specific
+% points in the processing in a controlled way without the need to
+% replace the existing code block (and thereby overwriting
+% modifications/extensions made by other packages). The target
+% audience is therefore mainly package developers, even though some
+% hooks can be useful for document authors.
+%
+% Obviously, what can reasonably be added into a hook depends on the
+% individual hook (hopefully documented as part of the hook
+% documentation), but in general the idea behind hooks is that more
+% than one package could add code into the hook at the same
+% time. Perhaps the most famous hook (that \LaTeX{} had for a very
+% long time) is \hook{begindocument} into which many packages add code
+% to through \cs{AtBeginDocument}\marg{code} (which is nowadays
+% implemented as a shorthand for
+% \cs{AddToHook}\texttt{\{\hook{begindocument}\}}\marg{code}). To
+% resolve possible conflicts between injections by different packages
+% there is a rule mechanism by which code chunks in a hook can be
+% ordered in a certain way and by which incompatible packages can be
+% detected if a resolution is impossible.
+%
+% In contrast to template code, there is no standard configuration
+% method through parameters for hooks, i.e., the code added to a hook
+% \enquote{is} the configuration. If it wants to provide for
+% configuration through parameters it has to also provide its own
+% method to set such parameters in some way. However, in that case it
+% is likely that using a hook is not the right approach and the
+% developer better calls a template instance instead which then offers
+% configuration through a key/value interface.
+%
+% In most cases, hooks do not take any arguments as input. Instead, the data
+% that they can (and are allowed to) access depends on the surrounding
+% context.
+%
+% For example, the various hooks available during the page shipout
+% process in \LaTeX's output routine can (and have to) access the
+% accumulated page material stored in a box named
+% \verb=\ShipoutBox=. This way, code added to, say, the
+% \hook{shipout/before} hook could access the page content, alter it,
+% and then write it back into \verb=\ShipoutBox= and any other code
+% added to this hook could then operate on the modified content. Of
+% course, for such a scheme to work the code prior to executing the hook
+% would need to setup up data in appropriate places and the hook
+% documentation would need to document what kind of storage can be
+% accessed (and possibly altered) by the hook.
+%
+% There are also hooks that take arguments (typically portions of
+% document data) and in that case the hook code can access these
+% arguments through \verb=#1=, \verb=#2=, etc.
+%
+% The hook mechanism is documented in \texttt{lthooks-doc.pdf}.
+%
+%
+%
+% \subsection{The socket mechanism}
+%
+% In some cases there is code that implements a certain programming
+% logic (for example, combining footnotes, floats, and the text for the
+% current page to be shipped out) and if this logic should change (e.g.,
+% footnotes to be placed above bottom floats instead of below) then this
+% whole code block needs to be replaced with different code.
+%
+% In theory, this could be implemented with templates, i.e., the code
+% simply calls some instance that implements the logic and that instance
+% is altered by selecting a different templates and/or adjusting their
+% parameters. However, in many cases customization through parameters is
+% overkill in such a case (or otherwise awkward, because paramerization
+% is better done on a higher level instead of individually for small
+% blocks of code) and using the template mechanism just to replace one
+% block of code with a different one results in a fairly high
+% performance hit. It is therefore usually not a good choice.
+%
+% In theory, it would also be possible to use a hook, but again that is
+% basically a misuse of the concept, because in this use case there should
+% never be more than one block of code inside the hook; thus, to alter
+% the processing logic one would need to set up rules that replace code
+% rather than (as intended) execute all code added to the hook.
+%
+%
+%
+% For this reason \LaTeX{} now offers a third mechanism:
+% \enquote{sockets} into which one can place exactly one code block
+% --- a \enquote{plug}.
+%
+% In a nutshell: instead of having a fixed code block somewhere as part
+% of the code, implementing a certain programming logic there is a
+% reference to a named socket at this point.
+% This is done by first declaring the named socket with:
+% \begin{quote}
+% \cs{NewSocket}\marg{socket-name}\marg{number-of-inputs}
+% \end{quote}
+% This is then referenced at the point where the replaceable code block
+% should be executed with:
+% \begin{quote}
+% \cs{UseSocket}\marg{socket-name}
+% \end{quote}
+% or, if the socket should take a number of inputs (additional
+% arguments beside the name) with
+% \begin{quote}
+% \cs{UseSocket}\marg{socket-name}\marg{arg\textsubscript{1}}\ldots
+% \marg{arg\textsubscript{\meta{number-of-inputs}}}
+% \end{quote}
+%
+% In addition, several code blocks (a.k.a.\ plugs) implementing different logic for this
+% socket are set up, each with a declaration of the form:
+% \begin{quote}
+% \cs{NewSocketPlug}\marg{socket-name}\marg{socket-plug-name}\marg{code}
+% \end{quote}
+% Finally,
+% one of them is assigned to the socket:
+% \begin{quote}
+% \cs{AssignSocketPlug}\marg{socket-name}\marg{socket-plug-name}
+% \end{quote}
+% If the programming logic should change, then all that is necessary is
+% to make a new assignment with \cs{AssignSocketPlug} to a different
+% \marg{socket-plug-name}. This assignment obeys scope so that an
+% environment can alter a socket without the need to restore the
+% previous setting manually.
+%
+% If the socket takes inputs, then those need to be provided to
+% \cs{UseSocket} and in that case they can be referenced in the \meta{code}
+% argument of \cs{NewSocketPlug} with \verb=#1=, \verb=#2=, etc.
+%
+% In most cases a named socket is used only in a single place, but there
+% is, of course, nothing wrong with using it in several places, as long
+% as the code in all places is supposed to change in the same way.
+%
+%
+%
+%
+%
+% \subsubsection{Examples}
+%
+%
+% We start by declaring a new socket named \socket{foo} that expects
+% two inputs:
+%\begin{verbatim}
+% \NewSocket{foo}{2}
+%\end{verbatim}
+% \NewSocket{foo}{2}
+%
+% Such a declaration has do be unique across the whole \LaTeX{}
+% run. Thus, if another package attempts to use the same name
+% (regardless of the number of inputs) it will generate an error:
+%\begin{verbatim}
+% \NewSocket{foo}{2}
+% \NewSocket{foo}{1}
+% \end{verbatim}
+% Both declarations would therefore produce:
+% \begin{verbatim}
+% ! LaTeX socket Error: Socket 'foo' already declared!
+%\end{verbatim}
+%
+% You also get an error if you attempt to declare some socket plug and
+% the socket name is not yet declared, e.g.,
+%\begin{verbatim}
+% \NewSocketPlug{baz}{undeclared}{some code}
+%\end{verbatim}
+% generates
+%\begin{verbatim}
+% ! LaTeX socket Error: Socket 'baz' undeclared!
+%\end{verbatim}
+%
+%
+% Setting up plugs for the socket is done like this:
+%\begin{verbatim}
+% \NewSocketPlug{foo}{plug-A}
+% {\begin{quote}\itshape foo-A: #1!#2\end{quote}}
+% \NewSocketPlug{foo}{plug-B}
+% {\begin{quote}\sffamily foo-B: #2\textsuperscript{2}\end{quote}}
+%\end{verbatim}
+% This will set up the plugs \texttt{plug-A} and \texttt{plug-B} for
+% this socket.
+%
+%\NewSocketPlug{foo}{plug-A}{\begin{quote}\itshape foo-A: #1!#2\end{quote}}
+%\NewSocketPlug{foo}{plug-B}{\begin{quote}\sffamily foo-B: #2\textsuperscript{2}\end{quote}}
+%
+% We still have to assign one or the other to the socket, thus without
+% doing that the line
+% \begin{verbatim}
+% \UseSocket{foo}{hello}{world}
+% \end{verbatim}
+% produces nothing because the default plug for sockets with 2 inputs
+% is \plug{noop} (which grabs the additional arguments and throws them
+% away).\footnote{If socket \socket{foo} would have been a socket with one
+% input, then the default plug would be \plug{identity}, in which case
+% the socket input would remain without braces and gets typeset!}
+%
+% \UseSocket{foo}{hello}{world} ^^A nothing happens
+%
+% So let's do the assignment
+% \begin{verbatim}
+% \AssignSocketPlug{foo}{plug-A}
+% \end{verbatim}
+% and then
+% \begin{verbatim}
+% \UseSocket{foo}{hello}{world}
+% \end{verbatim}
+% will properly typeset
+% \AssignSocketPlug{foo}{plug-A}\UseSocket{foo}{hello}{world}
+% and after
+% \begin{verbatim}
+% \AssignSocketPlug{foo}{plug-B}
+% \end{verbatim}
+% and another call to
+% \begin{verbatim}
+% \UseSocket{foo}{hello}{world}
+% \end{verbatim}
+% we get
+% \AssignSocketPlug{foo}{plug-B}\UseSocket{foo}{hello}{world}
+%
+% If we attempt to assign a plug that was not defined, e.g.,
+% \begin{verbatim}
+% \AssignSocketPlug{foo}{plug-C}
+% \end{verbatim}
+% then we get an error during the assignment
+% \begin{verbatim}
+% ! LaTeX socket Error: Plug 'plug-C' for socket 'foo' undeclared!
+% \end{verbatim}
+% and the previous assignment remains in place.
+%
+% To see what is known about a socket and its plugs you can use
+% \cs{ShowSocket} or \cs{LogSocket} which displays information similar
+% to this on the terminal or in the transcript file:
+% \begin{verbatim}
+% Socket foo:
+% number of inputs = 2
+% available plugs = noop, plug-A, plug-B
+% current plug = plug-B
+% definition = \protected\long macro:#1#2->\begin {quote}\sffamily
+% foo-B: #2\textsuperscript {2}\end {quote}
+% \end{verbatim}
+% \LogSocket{foo}
+%
+%
+% \subsubsection{Details and semantics}
+%
+% In this section we collect some normative statements.
+%
+% \begin{itemize}
+%
+% \item
+% From a functional point of view sockets are like simple \TeX{} macros,
+% i.e., they expect 0 to 9 mandatory arguments (the socket inputs) and get replaced by
+% their \enquote{expansion}
+%
+% \item
+% A socket is \enquote{named} and the name consists of ASCII letters
+% \texttt{[a-z]},
+% \texttt{[A-Z]}, \texttt{[0-9]}, \texttt{[-/@]} only
+%
+% \item
+% Socket names have to be unique, i.e., there can be only one socket
+% named \meta{name}. This is ensured by declaring each socket with
+% \cs{NewSocket}.
+%
+% However, there is no requirement that sockets and
+% hook names have to be different. In fact, if a certain action that
+% could overwise be specified as hook code has to be executed always
+% last (or first) one could ensure this by placing a socket (single
+% action) after a hook (or vice versa) and using the same name to
+% indicate the relationship, e.g.,
+%\begin{verbatim}
+% \UseHook{foo} % different package can add code here
+% \UseSocket{foo} % only one package can assign a plug
+%\end{verbatim}
+% This avoids the need to order the hook code to ensure that
+% something is always last.
+%
+% \item
+% Best practice naming conventions are \ldots\ \emph{to be documented}
+%
+% \item
+% A socket has documented inputs which are
+%
+% \begin{itemize}
+% \item
+% the positional arguments (if any) with a description of what
+% they contain when used
+%
+% \item
+% implicit data (registers and other 2e/expl3 data stores) that
+% the socket is allowed to make use of, with a documented description
+% of what they contain (if relevant for the task at hand---no need to
+% describe the whole \LaTeX{} universe)
+%
+% \item
+% information about the state of the \TeX{} engine (again when
+% relevant), e.g. is called in mmode or vmode or in the output routine or \ldots
+%
+% \item
+% \ldots\ \empty{anything missing?}
+% \end{itemize}
+%
+%
+% \item
+% A socket has documented results/outputs which can be
+%
+% \begin{itemize}
+% \item
+% what kind of data it should write to the current list (if that
+% is part of its task)
+%
+% \item
+% what kind of registers and other 2e/expl3 data stores it should
+% modify and in what way
+%
+% \item
+% what kind of state changes it should do (if any)
+%
+% \item
+% \emph{\ldots\ anything else?}
+% \end{itemize}
+%
+% \item
+%
+% At any time a socket has one block of code (a plug \iffalse(\fi:-)\,)
+% associated with it. Such code is itself named and the association
+% is done by linking the socket name to the code name (putting a
+% plug into the socket).
+%
+% \item
+%
+% The name of a plug consists of ASCII letters \texttt{[a-z]},
+% \texttt{[A-Z]}, \texttt{[0-9]}, \texttt{[-/@]} only.
+%
+% \item
+% Socket plug names have to be unique within on a per socket basis,
+% but it is perfectly allowed (and sensible in some cases) to use
+% the same plug name with different sockets (where based on the
+% sockets' purposes, different actions may be associated with the plug
+% name). For example \plug{noop} is a plug name declared for every
+% socket, yet it action \enquote{grab the socket inputs and throw
+% them away} obviously differs depending on how many inputs the
+% socket has.
+%
+% \item
+%
+% When declaring a plug it is stated for which socket it is meant
+% (i.e., its code can only be used with that socket). This means
+% that the same plug name can be used with different sockets
+% referring to different code in each case.
+%
+% \item
+% Configuration of a socket can only be done by
+% linking different code to it. Nevertheless the code linked to it can
+% provide its own means of configuration (but this is outside of the
+% spec).
+%
+% \item
+% Technically execution of a socket (\cs{UseSocket}) involves
+%
+% \begin{itemize}
+% \item
+% doing any house keeping (like writing debugging info, \ldots);
+%
+% \item
+% looking up the current code association (what plug is in the socket);
+%
+% \item
+% executing this code which will pick up the mandatory arguments
+% (happens at this point, not
+% before), i.e., it is like calling a csname defined with
+% \begin{verbatim}
+% \def\foo#1#2...{...#1...#2...}
+% \end{verbatim}
+%
+% \item
+% do some further house keeping (if needed).
+% \end{itemize}
+%
+% \item
+% A socket is typically only used in one place in code, but this is not
+% a requirement, i.e., if the same operation with the same inputs need
+% to be carried out in several places the same named socket can be used.
+%
+% \end{itemize}
+%
+%
+%
+%
+%
+% \subsubsection{Command syntax}
+%
+% We give both the \LaTeXe{} and the L3 programming layer command names.
+%
+% \begin{function}{\NewSocket,\socket_new:nn}
+% \begin{syntax}
+% \cs{NewSocket} \Arg{socket-name}\Arg{number-of-inputs}
+% \cs{socket_new:nn}\Arg{socket-name}\Arg{number-of-inputs}
+% \end{syntax}
+% Declares a new socket with name \meta{socket-name} having
+% \meta{number-of-inputs} inputs. There is automatically a
+% plug \plug{noop} declared for it, which does nothing, i.e., it gobbles
+% the socket inputs (if any). This is made the default plug except for
+% sockets with one input which additionally define the plug
+% \plug{identity} and assign that as their default.
+%
+% This \plug{identity} plug simply returns the socket input without
+% its outer braces.
+% The use case for this plug are situations like this:
+% \begin{quote}
+% \cs{UseSocket}\verb={tagsupport/footnote}=\Arg{code}
+% \end{quote}
+% If tagging is not active and the socket contains the plug \plug{identity}
+% then this returns \meta{code} without the outer braces and to
+% activate tagging all that is necessary is to change the plug to
+% say \plug{tagpdf} so
+% that it surrounds \meta{code} by some tagging magic.
+% This is the most common use case for sockets with one input, which
+% is why they have this special default.
+%
+% The socket documentation should describe its purpose, its inputs and the
+% expected results as discussed above.
+%
+% The declaration is only allowed at top-level, i.e., not inside a group.
+% \end{function}
+%
+%
+% \begin{function}{\NewSocketPlug,\socket_new_plug:nnn,\socket_set_plug:nnn}
+% \begin{syntax}
+% \cs{NewSocketPlug} \Arg{socket-name}\Arg{socket-plug-name}\Arg{code}
+% \cs{socket_new_plug:nnn}\Arg{socket-name}\Arg{socket-plug-name}\Arg{code}
+% \cs{socket_set_plug:nnn}\Arg{socket-name}\Arg{socket-plug-name}\Arg{code}
+% \end{syntax}
+% Declares a new plug for socket \meta{socket-name} that runs
+% \meta{code} when executing. It complains if the plug was already
+% declared previously.
+%
+% The form \cs{socket_set_plug:nnn} changes an existing plug. As
+% this should normally not be necessary, we currently have only an L3
+% layer name for the few cases it might be useful.
+%
+% The declarations can be made inside a group and obey scope, i.e.,
+% they vanish if the group ends.
+% \end{function}
+%
+%
+% \begin{function}{\AssignSocketPlug,\socket_assign_plug:nn}
+% \begin{syntax}
+% \cs{AssignSocketPlug} \Arg{socket-name}\Arg{socket-plug-name}
+% \cs{socket_assign_plug:nn}\Arg{socket-name}\Arg{socket-plug-name}
+% \end{syntax}
+% Assigns the plug \meta{socket-plug-name} to the socket
+% \meta{socket-name}. It errors if either socket or plug is not
+% defined.
+%
+% The assignment is local, i.e., it obeys scope.
+% \end{function}
+%
+%
+% \begin{function}{\UseSocket,\socket_use:nw,\socket_use:n,\socket_use:nn,\socket_use:nnn,\socket_use:nnnn}
+% \begin{syntax}
+% \cs{UseSocket} \Arg{socket-name}
+% \cs{socket_use:nnn}\Arg{socket-name} \Arg{socket-arg\textsubscript{1}} \Arg{socket-arg\textsubscript{2}}
+% \end{syntax}
+% Executes the socket \meta{socket-name} by retrieving the
+% \meta{code} of the current plug assigned to the socket. This is
+% the only command that would appear inside macro code in packages.
+%
+% For performance reasons there is no explicit check that the socket
+% was declared!
+%
+% The different L3 programming layer commands are really doing the
+% same thing: they grab as many arguments as defined as inputs for the socket
+% and then pass them to the plug. The different names are only there
+% to make the code more readable, i.e., to indicate how many
+% arguments are grabbed in total (note that no runtime check is made to
+% verify that this is actually true). We only provide them for
+% sockets with up to 3 inputs (most likely those with zero or one input would
+% have been sufficient). If you happen to have a socket with more
+% inputs, use \cs{socket_use:nw}.
+% \end{function}
+%
+%
+% \begin{function}{\ShowSocket,\LogSocket,\socket_show:n,\socket_log:n}
+% \begin{syntax}
+% \cs{ShowSocket} \Arg{socket-name}
+% \cs{socket_show:n}\Arg{socket-name}
+% \end{syntax}
+% Displays information about the socket \meta{socket-name} and its
+% state then stops and waits for further instructions --- at the
+% moment some what rudimentary.
+%
+% \cs{LogSocket} and \cs{socket_log:n} only differ in that they don't stop.
+% \end{function}
+%
+%
+% \begin{function}{\DebugSocketsOn,\DebugSocketsOff,
+% \socket_debug_on:,\socket_debug_off:}
+% \begin{syntax}
+% \cs{DebugSocketsOn} \ldots\ \cs{DebugSocketsOff}
+% \end{syntax}
+% Turns debugging of sockets on or off.
+% \end{function}
+%
+% \subsubsection{Rationale for error handling}
+%
+% The errors during the declarations are produced to help with
+% typos---after all, such declarations might be part of a document
+% preamble (not that likely, but possible). However, \cs{UseSocket} is
+% not doing much checking, e.g.,
+% \begin{verbatim}
+% \UseSocket{mispelled-socket}{hello}{world}
+% \end{verbatim}
+% will generate a rather low-level error and then typesets
+% ``{hello}{world}'' because there is no dedicated runtime check if
+% \texttt{mispelled-socket} is a known socket.
+%
+% The reason is that if the misspelling is in the code, then this is a
+% programming error in the package and for speed reasons \LaTeX{} does
+% not repeately make runtime checks for coding errors unless they can or
+% are likely to be user introduced.
+%
+%
+% \MaybeStop{\setlength\IndexMin{200pt} \PrintIndex }
+%
+%
+% \section{The Implementation}
+%
+% The implementation of the socket mechanism should be (partially)
+% redone and we should probably store the different code chunks in
+% a property list so that we can have a decent \cs{ShowSocket}
+% command that shows the available alternatives.\fmi{implement?}
+%
+% \begin{macrocode}
+%<*2ekernel|latexrelease>
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ExplSyntaxOn
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<@@=socket>
+% \end{macrocode}
+%
+% \begin{macrocode}
+%<latexrelease>\NewModuleRelease{2023/11/01}{ltsockets}
+%<latexrelease> {The~socket~management~system}
+% \end{macrocode}
+%
+%
+%
+% \subsection{Debugging the socket structures}
+%
+% Code and commands in this section are not final, it needs more
+% experimentation to see what kind of tracing information is going to
+% be useful in practice. For now the tracing is mainly meant to be used
+% for code testing and not so much for application testing.
+%
+% It is quite likely that the
+% commands and the behavior of the tracing might change in the
+% future once we gained some experience with it.
+%
+% \begin{macro}{\g_@@_debug_bool}
+% Holds the current debugging state.
+% \begin{macrocode}
+\bool_new:N \g_@@_debug_bool
+% \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\socket_debug_on:,\socket_debug_off:}
+% \begin{macro}{\@@_debug:n, \@@_debug_term:n}
+% \begin{macro}{\@@_debug_gset:}
+% Turns debugging on and off by redefining \cs{@@_debug:n} and
+% \cs{@@_debug_term:n}. By default they do nothing.
+% \begin{macrocode}
+\cs_new_eq:NN \@@_debug:n \use_none:n
+\cs_new_eq:NN \@@_debug_term:n \use_none:n
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \socket_debug_on:
+ {
+ \bool_gset_true:N \g_@@_debug_bool
+ \@@_debug_gset:
+ }
+\cs_new_protected:Npn \socket_debug_off:
+ {
+ \bool_gset_false:N \g_@@_debug_bool
+ \@@_debug_gset:
+ }
+\cs_new_protected:Npn \@@_debug_gset:
+ {
+ \cs_gset_protected:Npx \@@_debug:n ##1
+ { \bool_if:NT \g_@@_debug_bool {##1} }
+ \cs_gset_protected:Npx \@@_debug_term:n ##1
+ { \bool_if:NT \g_@@_debug_bool
+ { \iow_term:x { ^^J [Sockets]~ ==>~ ##1} } }
+ }
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+%
+% \subsection{The L3 layer commands}
+%
+% \begin{macro}{\socket_new:nn}
+%
+% Declaring a socket creates a str to hold the name (a pointer) to the
+% code that should be used when the socket is executed, and an integer to
+% hold the number of inputs of that socket. Initially, an
+% ``empty'' code chunk is created and assigned so the socket
+% does nothing by default other than swallowing its inputs (if any).
+% \begin{macrocode}
+\cs_new_protected:Npn \socket_new:nn #1 #2 {
+ \str_if_exist:cTF { l_@@_#1_plug_str }
+ {
+ \msg_error:nnn { socket } { already-declared } {#1}
+ }
+ {
+% \end{macrocode}
+% We only support declarations on top-level.
+% \begin{macrocode}
+ \int_if_zero:nTF \tex_currentgrouplevel:D
+ {
+ \str_new:c { l_@@_#1_plug_str }
+ \seq_new:c { l_@@_#1_plugs_seq }
+ \int_const:cn { c_@@_#1_args_int } {#2}
+ \socket_new_plug:nnn {#1} { noop } {}
+ \int_compare:nNnTF {#2} = 1
+ {
+ \socket_new_plug:nnn {#1} { identity } {##1}
+ \socket_assign_plug:nn {#1} { identity }
+ }
+ { \socket_assign_plug:nn {#1} { noop } }
+ \@@_debug_term:n
+ { Socket~ '#1'~ declared~ with~ #2~ input(s) }
+ }
+ {
+ \msg_error:nn { socket } { not-top-level }
+ }
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\socket_log:n,\socket_show:n}
+% Show the current state of the socket --- for now this is just a
+% quick draft and should be redone and extended.
+% \begin{macrocode}
+\cs_new_protected:Npn \socket_log:n #1 {
+ \typeout{ Socket~ #1:}
+ \str_if_exist:cTF { l_@@_#1_plug_str }
+ {
+ \typeout{ \@spaces number~ of~ inputs~ =~
+ \int_use:c { c_@@_#1_args_int } }
+ \typeout{ \@spaces available~plugs~ =~
+ \seq_use:cnnn { l_@@_#1_plugs_seq }{,~}{,~}{,~} }
+ \typeout{ \@spaces current~ plug~ =~
+ \str_use:c { l_@@_#1_plug_str } }
+ \typeout{ \@spaces definition~ =~
+ \cs_meaning:c
+ { @@_#1_plug_ \str_use:c { l_@@_#1_plug_str } :w } }
+ \typeout{}
+ }
+ {
+% \end{macrocode}
+% If we are showing a socket it is not an error if it doesn't exist.
+% \begin{macrocode}
+ \typeout { Socket~ is~ not~ declared! }
+ }
+}
+% \end{macrocode}
+% And here the version that stops:
+% \begin{macrocode}
+\cs_new_protected:Npn \socket_show:n #1 {\socket_log:n {#1} \errmessage{}}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+%
+%
+% \begin{macro}{\socket_new_plug:nnn,\socket_set_plug:nnn}
+%
+% Declaring a code for a socket is just making a definition, taking
+% the number of arguments from the saved int.
+% \begin{macrocode}
+\cs_new_protected:Npn \socket_new_plug:nnn #1#2#3 {
+ \str_if_exist:cTF { l_@@_#1_plug_str }
+ {
+ \cs_if_exist:cTF { @@_#1_plug_#2:w }
+ {
+ \msg_error:nnnn { socket } { plug-already-declared } {#1} {#2}
+ }
+ {
+ \cs_generate_from_arg_count:cNnn
+ { @@_#1_plug_#2:w }
+ \cs_new_protected:Npn
+ { \int_use:c { c_@@_#1_args_int } }
+ {#3}
+% \end{macrocode}
+% This is a new declaration so we add the name to a seq for the
+% debugging info.
+% \begin{macrocode}
+ \seq_put_right:cn { l_@@_#1_plugs_seq } {#2}
+ \@@_debug_term:n
+ { Plug~ '#2'~ for~ socket~ '#1'~ declared. }
+ }
+ }
+ {
+ \msg_error:nnn { socket } { undeclared } {#1}
+ }
+}
+% \end{macrocode}
+% Changing the plug of an existing socket is rather similar, except
+% that we don't have to deal with adding it to the debugging
+% sequence.
+% \begin{macrocode}
+\cs_new_protected:Npn \socket_set_plug:nnn #1#2#3 {
+ \str_if_exist:cTF { l_@@_#1_plug_str }
+ {
+ \cs_if_exist:cTF { @@_#1_plug_#2:w }
+ {
+ \cs_generate_from_arg_count:cNnn
+ { @@_#1_plug_#2:w }
+ \cs_set_protected:Npn
+ { \int_use:c { c_@@_#1_args_int } }
+ {#3}
+ \@@_debug_term:n
+ { Plug~ '#2'~ for~ socket~ '#1'~ changed. }
+ }
+ {
+ \msg_error:nnnn { socket } { plug-undeclared } {#1} {#2}
+ }
+ }
+ {
+ \msg_error:nnn { socket } { undeclared } {#1}
+ }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macro}{\socket_assign_plug:nn}
+%
+% Assigning a plug to a socket just changes the name in
+% the socket string. The assignment is local to the current group.
+% \begin{macrocode}
+\cs_new_protected:Npn \socket_assign_plug:nn #1 #2 {
+ \str_if_exist:cTF { l_@@_#1_plug_str }
+ {
+ \cs_if_exist:cTF { @@_#1_plug_#2:w }
+ {
+ \@@_debug_term:n
+ { Replacing~ plug~ '\str_use:c { l_@@_#1_plug_str }'~
+ with~ '#2'~ in~ socket~ '#1'. }
+ \str_set:cn { l_@@_#1_plug_str } {#2}
+ }
+ {
+ \msg_error:nnnn { socket } { plug-undeclared } {#1} {#2}
+ }
+ }
+ { \msg_error:nnn { socket } { undeclared } {#1} }
+}
+% \end{macrocode}
+% \end{macro}
+%
+%
+% \begin{macro}{\socket_use:nw,\socket_use:n,\socket_use:nn,\socket_use:nnn,\socket_use:nnnn}
+%
+% And using it is more or less a \cs{use:c} so very lightweight. We do not
+% add a runtime check for speed reasons!
+%
+% This command is named
+% \cs{socket_use:nw} because we don't know how many inputs the
+% socket has until we have looked at the socket name (in argument \verb=#1=).
+% But, of course, the developer knows so we also offer a few aliases
+% \cs{socket_use:nn}, etc.\ so that one can indicate the correct number of
+% arguments (socket inputs plus one) in the L3 layer code.
+%
+% \begin{macrocode}
+\cs_new_protected:Npn \socket_use:nw #1 {
+ \@@_debug_term:n
+ { Socket~ '#1'~ containing~ plug~
+ '\str_use:c { l_@@_#1_plug_str }'~ used. }
+ \use:c { @@_#1_plug_ \str_use:c { l_@@_#1_plug_str } :w }
+}
+% \end{macrocode}
+% To make code a bit more readable we also define functions that
+% indicate how many arguments are picked up. However, this is just for
+% code documentation: internally they all do the same and the number
+% of arguments isn't checked by default.
+% \begin{macrocode}
+\cs_new_eq:NN \socket_use:n \socket_use:nw % socket with no inputs
+\cs_new_eq:NN \socket_use:nn \socket_use:nw % socket with one input
+\cs_new_eq:NN \socket_use:nnn \socket_use:nw % socket with two inputs
+\cs_new_eq:NN \socket_use:nnnn \socket_use:nw % socket with three inputs
+% \end{macrocode}
+% The above commands could be changed to check how many inputs
+% the socket is declared with (for example, when checking is in
+% force).
+% \fmi{Implement?}
+% \end{macro}
+%
+%
+%
+%
+%
+%
+%
+% \subsection{Error messages}
+%
+
+%
+% \begin{macrocode}
+\msg_new:nnnn { socket } { already-declared }
+ { Socket~ '#1'~ already~ declared! }
+ { A~ socket~ can~ only~ be~ declared~ once.~ The~ name~ '#1'~ is~
+ already~ taken.~ Use~ \ShowSocket{#1}~ to~ see~ its~ definition. }
+
+\msg_new:nnnn { socket } { undeclared }
+ { Socket~ '#1'~ undeclared! }
+ { You~ tried~ to~ use~ a~ socket~ that~ was~ not~ declared~ before. }
+
+\msg_new:nnnn { socket } { not-top-level }
+ { Sockets~ can~ only~ be~ declared~ at~ top-level! }
+ { It~ is~ not~ allowed~ to~ declare~ sockets~ inside~ a~
+ group.~ Move~ the~ declaration~ to~ the~ top-level. }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\msg_new:nnnn { socket } { plug-already-declared }
+ { Plug~ '#2'~ for~ socket~ '#1'~ already~ declared! }
+ { You~ can't~ change~ an~ existing~ plug~ with~ \NewSocketPlug~ and~ it~
+ is~ normally~ not~ sensible~ to~ do~ so.~ Use~ the~ L3~ programming~
+ layer~ function~ \socket_set_plug:nnn~ if~ you~ really~ have~ to. }
+
+\msg_new:nnnn { socket } { plug-undeclared }
+ { Plug~ '#2'~ for~ socket~ '#1'~ undeclared! }
+ { The~ plug~ name~ is~ unknown.~ Is~ the~ name~ misspelled~ or~ did~ you~
+ intend~ to~ assign~ it~ to~ a~ different~ socket? }
+% \end{macrocode}
+%
+% \begin{macrocode}
+\prop_gput:Nnn \g_msg_module_type_prop { socket } { LaTeX }
+% \end{macrocode}
+%
+%
+%
+%
+% \subsection{The \LaTeXe{} interface commands}
+%
+% \begin{macro}{\NewSocket,\NewSocketPlug,
+% \ShowSocket,\LogSocket,
+% \AssignSocketPlug,\UseSocket,
+% \DebugSocketsOn,\DebugSocketsOff}
+% As we expect that there are existing \LaTeXe{} packages that may
+% want to make use of the socket mechanism, we provide 2e names for
+% most of the commands.
+% \begin{macrocode}
+\cs_new_eq:NN \NewSocket \socket_new:nn
+\cs_new_eq:NN \ShowSocket \socket_show:n
+\cs_new_eq:NN \LogSocket \socket_log:n
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_eq:NN \NewSocketPlug \socket_new_plug:nnn
+\cs_new_eq:NN \AssignSocketPlug \socket_assign_plug:nn
+\cs_new_eq:NN \UseSocket \socket_use:nw
+% \end{macrocode}
+%
+% \begin{macrocode}
+\cs_new_eq:NN \DebugSocketsOn \socket_debug_on:
+\cs_new_eq:NN \DebugSocketsOff \socket_debug_off:
+% \end{macrocode}
+% \end{macro}
+%
+%
+%
+% \begin{macrocode}
+%
+%<latexrelease>\IncludeInRelease{0000/00/00}{ltsockets}
+%<latexrelease> {The~socket~management~(undo)}%
+%<latexrelease>
+%<latexrelease>\let \NewSocket \@undefined
+%<latexrelease>\let \ShowSocket \@undefined
+%<latexrelease>\let \LogSocket \@undefined
+%<latexrelease>
+%<latexrelease>\let \NewSocketPlug \@undefined
+%<latexrelease>\let \AssignSocketPlug \@undefined
+%<latexrelease>\let \UseSocket \@undefined
+%<latexrelease>
+%<latexrelease>\let \DebugSocketsOn \@undefined
+%<latexrelease>\let \DebugSocketsOff \@undefined
+%<latexrelease>
+%<latexrelease>\EndModuleRelease
+% \end{macrocode}
+%
+% \begin{macrocode}
+\ExplSyntaxOff
+% \end{macrocode}
+%
+% \begin{macrocode}
+%</2ekernel|latexrelease>
+% \end{macrocode}
+%
+% Reset module prefix:
+% \begin{macrocode}
+%<@@=>
+% \end{macrocode}
+%
+%
+% \Finale
+%
+%
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\endinput
+
+
+
+^^A Needed for emacs
+^^A
+^^A Local Variables:
+^^A mode: latex
+^^A coding: utf-8-unix
+^^A End:
+
+
+
diff --git a/Master/texmf-dist/source/latex-dev/base/ltspace.dtx b/Master/texmf-dist/source/latex-dev/base/ltspace.dtx
index a77314b1bd1..66841cae384 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltspace.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltspace.dtx
@@ -32,7 +32,7 @@
%<*driver>
% \fi
\ProvidesFile{ltspace.dtx}
- [2023/05/26 v1.3p LaTeX Kernel (spacing)]
+ [2023/06/14 v1.3q LaTeX Kernel (spacing)]
% \iffalse
\documentclass{ltxdoc}
\GetFileInfo{ltspace.dtx}
@@ -1223,9 +1223,24 @@
% \end{macro}
% \end{macro}
%
+% \begin{macro}{\@xobeytab}
+% \changes{v1.3q}{2023/06/14}{Macro added}
+% Equivalent to the space case with the default settings.
% \begin{macrocode}
+%</2ekernel>
+%<latexrelease>\IncludeInRelease{2023/11/01}%
+%<latexrelease> {\@xobeytab}{Obeyed tabs}%
+%<*2ekernel|latexrelease>
+\let\@xobeytab\@xobeysp
+%</2ekernel|latexrelease>
+%<latexrelease>\EndIncludeInRelease
+%<latexrelease>\IncludeInRelease{0000/00/00}%
+%<latexrelease> {\@xobeytab}{Obeyed tabs}%
+%<latexrelease>\let\@xobeytab\@undefined
+%<latexrelease>\EndIncludeInRelease
+%<*2ekernel>
% \end{macrocode}
-%
+% \end{macro}
%
%
% \begin{macro}{\@}
diff --git a/Master/texmf-dist/source/latex-dev/base/ltvers.dtx b/Master/texmf-dist/source/latex-dev/base/ltvers.dtx
index 5b124febd9e..5b78c3bc5ed 100644
--- a/Master/texmf-dist/source/latex-dev/base/ltvers.dtx
+++ b/Master/texmf-dist/source/latex-dev/base/ltvers.dtx
@@ -115,7 +115,7 @@
{2023-11-01}
%</2ekernel|latexrelease>
%<*2ekernel>
-\def\patch@level{-0}
+\def\patch@level{-1}
% \end{macrocode}
%
% \begin{macro}{\development@branch@name}
diff --git a/Master/texmf-dist/source/latex-dev/firstaid/firstaid.ins b/Master/texmf-dist/source/latex-dev/firstaid/firstaid.ins
index cd5ea2006db..b3f30c30daa 100644
--- a/Master/texmf-dist/source/latex-dev/firstaid/firstaid.ins
+++ b/Master/texmf-dist/source/latex-dev/firstaid/firstaid.ins
@@ -3,7 +3,7 @@
%% driver files from the doc files in this package when run through
%% LaTeX or TeX.
%%
-%% Copyright (C) 2020-2021
+%% Copyright (C) 2020-2023
%% The LaTeX Project and any individual authors listed elsewhere
%% in this file.
%%
@@ -44,7 +44,7 @@ reports for it can be opened at https://latex-project.org/bugs/
(but please observe conditions on bug reports sent to that address!)
-Copyright (C) 2020-2021
+Copyright (C) 2020-2023
The LaTeX Project and any individual authors listed elsewhere
in this file.
@@ -72,7 +72,4 @@ without such generated files.
\generate{\file{filehook-ltx.sty}
{\from{latex2e-first-aid-for-external-files.dtx}{filehook-ltx}}}
-\generate{\file{everysel-ltx.sty}
- {\from{latex2e-first-aid-for-external-files.dtx}{everysel-ltx}}}
-
\endbatchfile
diff --git a/Master/texmf-dist/source/latex-dev/firstaid/latex2e-first-aid-for-external-files.dtx b/Master/texmf-dist/source/latex-dev/firstaid/latex2e-first-aid-for-external-files.dtx
index 90958ed7776..d1eeaf5ce2a 100644
--- a/Master/texmf-dist/source/latex-dev/firstaid/latex2e-first-aid-for-external-files.dtx
+++ b/Master/texmf-dist/source/latex-dev/firstaid/latex2e-first-aid-for-external-files.dtx
@@ -111,8 +111,8 @@
% \end{macrocode}
%
% \begin{macrocode}
-\def\LaTeXFirstAidDate{2023/05/20}
-\def\LaTeXFirstAidVersion{v1.0z}
+\def\LaTeXFirstAidDate{2023/07/18}
+\def\LaTeXFirstAidVersion{v1.1a}
% \end{macrocode}
%
% \begin{macrocode}
@@ -285,62 +285,10 @@
%</filehook-ltx>
% \end{macrocode}
%
-%
-%
-%
-% \subsection{The \pkg{bidi} package first aid}
-%
-% The \pkg{bidi} package adds a lot of hooks in various places and
-% those added to \cs{document} and \cs{enddocument} are now no
-% longer necessary as the kernel already provides the right hooks
-% there.
-%
-% However, we aren't trying to change that but instead only make
-% sure that the existing patches still work by adding some first
-% aid after \pkg{biditools} has been loaded.
-%
-% If the package gets updated one can easily take that out simply
-% through
-%\begin{verbatim}
-% \RemoveFromHook{file/biditools.sty/after}[firstaid]
-%\end{verbatim}
-% This makes it easy to test new bidi code while the first aid code
-% is still in the kernel.
-%
% \begin{macrocode}
%<*kernel>
% \end{macrocode}
%
-% Bidi is now ar a new version: patches are no longer needed.
-% \begin{macrocode}
-%\AddToHook{file/biditools.sty/after}[firstaid]{%
-% \FirstAidNeededT{biditools}{sty}%
-% {2020/05/13 v2 Programming tools for bidi package}%
-% {%
-% \end{macrocode}
-% \pkg{bidi} adds some code to the beginning of \cs{document} which
-% contains \cs{endgroup} and \cs{begingroup} which is no longer
-% correct.
-%
-% Patching \cs{document} using \cs{bidi@patchcmd} doesn't work so
-% we take the extra groups out by hand:
-% \begin{macrocode}
-% \def\firstaid@bidi@document@patch
-% \endgroup#1\begingroup#2\firstaid@bidi@document@patch
-% {\unexpanded{#1#2}}%
-% \edef\document{\expandafter\firstaid@bidi@document@patch\document
-% \firstaid@bidi@document@patch}%
-% \end{macrocode}
-% There are also some patches into \cs{enddocument}, some continue
-% to go in but one fails, so we add that now into the right place.
-% \begin{macrocode}
-% \AddToHook{enddocument/info}%
-% {\let\bidi@AfterEndDocumentCheckLabelsRerun\@firstofone
-% \bidi@afterenddocumentchecklabelsrerunhook}%
-% }%
-%}
-% \end{macrocode}
-%
% \subsection{The \pkg{dinbrief} class first aid}
%
% Again a case of a no longer correct \cs{endgroup} in document.
@@ -482,46 +430,6 @@
%</kernel>
% \end{macrocode}
%
-% \subsection{The \pkg{everysel} package first aid}
-%
-%
-% The \cs{selectfont} command got a hook (with the 2021/05 release) which
-% was originally provided by the \pkg{everysel}
-% package. Now that it is in the kernel this package is no longer
-% needed (or only in a simplified manner).
-%
-% If it is requested we replace it with a simplified package
-% (until) it gets updated at which point this line can be removed.
-% \changes{v2.2k}{2020/12/04}{Emulate everysel package}
-% \begin{macrocode}
-%<*kernel>
-% this has been updated
-%\declare@file@substitution{everysel.sty}{everysel-ltx.sty}
-%</kernel>
-% \end{macrocode}
-%
-%
-%
-% \begin{macrocode}
-%<*everysel-ltx>
-\ProvidesPackage{everysel-ltx}
- [2020/12/04 v1.0a
- Emulation of the original everysel^^Jpackage with kernel methods]
-% \end{macrocode}
-%
-% \begin{macrocode}
-\newcommand*{\EverySelectfont}[1]
- {\AddToHook{selectfont}{#1}}
-\newcommand*{\AtNextSelectfont}[1]
- {\AddToHookNext{selectfont}{#1}}
-% \end{macrocode}
-%
-%
-% \begin{macrocode}
-%</everysel-ltx>
-% \end{macrocode}
-%
-%
%
% \begin{macrocode}
%<*kernel>
@@ -652,31 +560,6 @@
}
% \end{macrocode}
%
-%
-% \subsection{First aid for \pkg{memoir}}
-%
-% The introduction of \cs{stockheight} and \cs{stockwidth} into the
-% kernel requires some first aid. This has to go in \emph{before}
-% loading the class, so we cannot check the version string here.
-% \begin{macrocode}
-\AddToHook{file/memoir.cls/before}[firstaid]{%
- \expandafter\def\expandafter\@tempa\string\dimen{}%
- \edef\kernel@stockheight{\expandafter\@tempa\meaning\stockheight}%
- \edef\kernel@stockwidth{\expandafter\@tempa\meaning\stockwidth}%
- \let\stockheight\@undefined
- \let\stockwidth\@undefined
-}
-\AddToHook{file/memoir.cls/after}[firstaid]{%
- \dimen\kernel@stockheight=\stockheight
- \dimen\kernel@stockwidth=\stockwidth
- \dimendef\stockheight=\kernel@stockheight
- \dimendef\stockwidth=\kernel@stockwidth
-}
-% \end{macrocode}
-%
-%
-%
-%
% \begin{macrocode}
%</kernel>
% \end{macrocode}