[latex3-commits] [latex3/latex2e] latexlab/rcb: adjustments to socket code (WIP) (cdaea16b)

github at latex-project.org github at latex-project.org
Thu Jul 20 19:58:52 CEST 2023


Repository : https://github.com/latex3/latex2e
On branch  : latexlab/rcb
Link       : https://github.com/latex3/latex2e/commit/cdaea16ba089806bf0dd1353ac07c76d13a3602b

>---------------------------------------------------------------

commit cdaea16ba089806bf0dd1353ac07c76d13a3602b
Author: Frank Mittelbach <frank.mittelbach at latex-project.org>
Date:   Thu Jul 20 19:58:52 2023 +0200

    adjustments to socket code (WIP)


>---------------------------------------------------------------

cdaea16ba089806bf0dd1353ac07c76d13a3602b
 required/latex-lab/latex-lab-footnotes.dtx  |  23 +-
 required/latex-lab/latex-lab-new-or-2.dtx   |  90 +++---
 required/latex-lab/latex-lab-socket.dtx     | 480 ++++++++++++++++++++++++++--
 required/latex-lab/testfiles/new-or-001.lvt |   8 +-
 required/latex-lab/testfiles/new-or-001.tlg |  22 +-
 5 files changed, 537 insertions(+), 86 deletions(-)

diff --git a/required/latex-lab/latex-lab-footnotes.dtx b/required/latex-lab/latex-lab-footnotes.dtx
index 414e90f3..10091971 100644
--- a/required/latex-lab/latex-lab-footnotes.dtx
+++ b/required/latex-lab/latex-lab-footnotes.dtx
@@ -39,6 +39,7 @@
 % \providecommand\class[1]{\texttt{#1.cls}}
 % \providecommand\pkg[1]{\texttt{#1}}
 % \providecommand\hook[1]{\texttt{#1}}
+% \providecommand\socket[1]{\texttt{#1}}
 %
 % \begin{abstract}
 %   \emph{to be written}
@@ -103,11 +104,9 @@
 %
 %
 %
-% \section{Hooks and configuration points}
+% \section{Hooks and sockets}
 %
-%    Note: the configuration points do not have an interface mechanism
-%    yet and all their names are temporary right now.
-%    Also note that configuration points are of interest only to very
+%    Note that sockets are of interest only to very
 %    few specialized packages, mainly \pkg{footmisc}, and packages
 %    providing similar functionality---the current documentation is
 %    therefore fairly sketchy.
@@ -2008,10 +2007,10 @@
 %    \texttt{dblfnote} package if we integrate that).
 %    \begin{macrocode}
 \ifFN at para
-  \DeclareSocketCode{@makecol/footnotes}{para}{%
+  \NewSocketPlug{@makecol/footnotes}{para}{%
      \global\setbox\footins\vbox{\FN at makefootnoteparagraph}%
     }
-  \AssignSocketCode{@makecol/footnotes}{para}
+  \AssignSocketPlug{@makecol/footnotes}{para}
 \fi
 %    \end{macrocode}
 %
@@ -2044,21 +2043,21 @@
   \ERROR
 \or %1
   \ifFN at abovefloats
-    \AssignSocketCode {@makecol/outputbox}{space-footnotes-floats}
+    \AssignSocketPlug {@makecol/outputbox}{space-footnotes-floats}
   \else
-    \AssignSocketCode {@makecol/outputbox}{floats-footnotes-space}
+    \AssignSocketPlug {@makecol/outputbox}{floats-footnotes-space}
   \fi
 \or %2
   \ifFN at abovefloats
-    \AssignSocketCode {@makecol/outputbox}{footnotes-space-floats}
+    \AssignSocketPlug {@makecol/outputbox}{footnotes-space-floats}
   \else
-    \AssignSocketCode {@makecol/outputbox}{space-floats-footnotes}
+    \AssignSocketPlug {@makecol/outputbox}{space-floats-footnotes}
   \fi
 \or %3
   \ifFN at abovefloats
-    \AssignSocketCode {@makecol/outputbox}{footnotes-floats}
+    \AssignSocketPlug {@makecol/outputbox}{footnotes-floats}
   \else
-    \AssignSocketCode {@makecol/outputbox}{floats-footnotes}
+    \AssignSocketPlug {@makecol/outputbox}{floats-footnotes}
   \fi
 \else
   \ERROR
diff --git a/required/latex-lab/latex-lab-new-or-2.dtx b/required/latex-lab/latex-lab-new-or-2.dtx
index bef372cc..1134c6a3 100644
--- a/required/latex-lab/latex-lab-new-or-2.dtx
+++ b/required/latex-lab/latex-lab-new-or-2.dtx
@@ -37,6 +37,8 @@
 % \newcommand\fmi[1]{\begin{quote} TODO: \itshape #1\end{quote}}
 % \newcommand\NEW[1]{\marginpar{\mbox{}\hfill\fbox{New: #1}}}
 % \providecommand\pkg[1]{\texttt{#1}}
+% \providecommand\hook[1]{\texttt{#1}}
+% \providecommand\socket[1]{\texttt{#1}}
 %
 % \begin{abstract}
 % \end{abstract}
@@ -51,28 +53,28 @@
 % \section{Hooks and replaceable code blocks}
 %
 %
-% \subsubsection{Replaceable code blocks}
+% \subsubsection{Replaceable code blocks (sockets)}
 %
 %    To cater for different layouts with respect to text, footnotes,
-%    and bottom-floats placements there are two replaceable code blocks for
+%    and bottom-floats placements there are two sockets for
 %    now.
 %    \begin{description}
-%    \item[\texttt{@makecol/outputbox} (0 arguments)]
+%    \item[\socket{@makecol/outputbox} (0 arguments)]
 %
-%      In this code block the \cs{@outputbox} (holding the
+%      In code for this socket the \cs{@outputbox} (holding the
 %      galley text for the current column or page) is augmented by
 %      attaching floats and footnote areas together with appropriate
 %      spacing.
 %
-%      Prior to calling the replaceable block the output routine has already
+%      Prior to calling the socket the output routine has already
 %      decided which floats go into which area and which get deferred.
-%      Therefore, the assumtion is that the replaceable block attaches all
-%      areas that contain floats. If this is not done then the order
+%      Therefore, the assumtion is that the code in the socket attaches all
+%      areas that contain floats. If this is not done, then the order
 %      of floats is likely to be screwed up unless unused floats
 %      are moved to the defer list in an appropriate way (for now we
 %      don't offer any interface for that scenario). 
 %
-%      Before the code is run any existing glue at the bottom
+%      Before the code in the soocket is run, any existing glue at the bottom
 %      of the \cs{@outputbox} is removed and stored in a safe
 %      place. If needed, it can be reinserted with one of the helper
 %      commands.
@@ -111,12 +113,14 @@
 %        (names are likely to change).
 %   
 %      \end{description}
-%      This configuration point needs an appropriate definition; a
+%      This socket cannot be empty but needs appropriate code; a
 %      default is already given in the kernel.
 %
-%    \item[\cs{@makecol at cfgpointii} (0 arguments)]
+%-----------------------
 %
-%       This configuration point is used to manipulate the footnote
+%    \item[\socket{@makecol/footnotes} (0 arguments)]
+%
+%       This socket is used to manipulate the footnote
 %        material inside \cs{box}\cs{footins}. It if contains code, it
 %        is supposed to do some processing of that box and then write
 %        the result back into it (and nothing else!). By default it
@@ -149,10 +153,16 @@
 %
 %  \begin{macro}{\@makecol}
 %    \cs{@makecol} is shortened a lot, basically all the hardwired
-%    code in the middle has moved into a configuration point.
+%    code in the middle has moved into a socket.
 %    \begin{macrocode}
 \def \@makecol {%
+%    \end{macrocode}
+%    We start with a kernel hook for tagging.
+%    \begin{macrocode}
   \@kernel at before@cclv
+%    \end{macrocode}
+%    Save away box 255 as \cs{@outputbox} to make it available for further adjustments.
+%    \begin{macrocode}
   \setbox\@outputbox \box\@cclv
 %    \end{macrocode}
 %    The only real addition is the next command which either does
@@ -161,25 +171,25 @@
 %    \begin{macrocode}
   \@outputbox at removebskip
 %    \end{macrocode}
-%    Any ``here'' floats in the \cs{@outputbox} are now handled so we
+%    When this code is run any ``here'' floats in the \cs{@outputbox} are already handled, so we
 %    recycle their registers and put them back to the \cs{@freelist}.
 %    \begin{macrocode}
   \let\@elt\relax
   \xdef\@freelist{\@freelist\@midlist}%
   \global \let \@midlist \@empty
 %    \end{macrocode}
-%    Here we have the configurable part. It appends floats and
+%    Here we have the configurable part. This socket is supposed to add floats and
 %    footnotes as appropriate to the \cs{@outputbox}.
 %    \begin{macrocode}
   \UseSocket{@makecol/outputbox}%
 %    \end{macrocode}
-%    The we deal with any \cs{enlargethispage} or run the normal code
+%    Then we deal with any \cs{enlargethispage} or run the normal code
 %    to build a column.
 %    \begin{macrocode}
   \ifvbox\@kludgeins
-     \@makespecialcolbox
+     \@make at specialcolbox
   \else
-     \@makenormalcolbox
+     \@make at normalcolbox
   \fi
   \global \maxdepth \@maxdepth
 }
@@ -196,10 +206,10 @@
 %    \end{macrocode}
 %  \end{macro}
 %
-%  \begin{macro}{\@makenormalcolbox}
+%  \begin{macro}{\@make at normalcolbox}
 %    Taken out of \cs{@makecol} for readability.
 %    \begin{macrocode}
-\def \@makenormalcolbox {%
+\def \@make at normalcolbox {%
    \setbox\@outputbox \vbox to\@colht {%
        \@texttop
        \@outputbox at depth \dp\@outputbox
@@ -212,10 +222,10 @@
 %  \end{macro}
 %
 %
-%  \begin{macro}{\@makespecialcolbox}
+%  \begin{macro}{\@make at specialcolbox}
 %    Make the colbox when \cs{enlargethispage} was used.
 %    \begin{macrocode}
-\def \@makespecialcolbox {%
+\def \@make at specialcolbox {%
    \@outputbox at append {\vskip-\@outputbox at depth}%
    \@tempdima \@colht
    \ifdim \wd\@kludgeins>\z@
@@ -278,6 +288,7 @@
       \ifnum \gluestretchorder\@tempskipa>\z@
         \vskip-\@tempskipa
 %    \end{macrocode}
+%        
 %  \begin{macro}{\@outputbox at reinsertbskip}
 %    We also record the value so that it can be reinserted
 %    elsewhere. As we have to do this globally, we also need to
@@ -306,7 +317,8 @@
 %  \begin{macro}{\@kernel at before@cclv}
 %  \begin{macro}{\@kernel at before@footins}
 %    These two commands are internal kernel hooks intended for tagging
-%    support in case that is active. By default they do nothing (and
+%    support in case that is active. They should not be altered by package code!
+%    By default they do nothing (and
 %    may have been defined already by \cs{DocumentMetadata}).
 %    \begin{macrocode}
 \providecommand\@kernel at before@cclv{}
@@ -320,8 +332,8 @@
 %
 % \subsection{The output routine configuration components}
 %
-%    Here we provide the components that are used to define
-%    \cs{@makecol at cfgpoint}.
+%    Here we provide the components that are used to define code for the
+%    \socket{@makecol/outputbox} socket.
 %
 %
 %  \begin{macro}{\@outputbox at append}
@@ -354,7 +366,7 @@
 %  \begin{macro}{\@outputbox at appendfootnotes}
 %
 %    This command appends the footnotes to the \cs{@outputbox} (if
-%    there are any). If not then it does nothing.
+%    there are any). If not, then it does nothing.
 %    \begin{macrocode}
 \def\@outputbox at appendfootnotes {%
    \ifvoid\footins \else
@@ -362,9 +374,12 @@
 %    First come two configuration points: what to do if we are in a split
 %    footnote situation and a second one that does some manipulation
 %    of the \cs{footins} box before it gets appended.
-% \fmi{this code will get revised as part of RCB handling  in the future}
+% \fmi{this code will get revised as part of socket handling  in the future}
 %    \begin{macrocode}
      \@makecol at handlesplitfootnotes
+%    \end{macrocode}
+%
+%    \begin{macrocode}
      \UseSocket{@makecol/footnotes}%
 %    \end{macrocode}
 %    Then the footnotes are appended:
@@ -445,7 +460,7 @@
 %
 %  \begin{macro}{@makecol/footnote}
 %
-%    Replaceable code block to support manipulation of \cs{footins} box
+%    The socket allowing the manipulation of \cs{footins} box
 %    (result needs to be moved back in there). Used when footnotes are
 %    reformatted into a single paragraph by the
 %    \texttt{para} option of \pkg{footmisc}. By default it does nothing.
@@ -506,18 +521,19 @@
 %
 %
 %  \begin{macro}{@makecol/outputbox}
-%    We have one replaceable code block that is supposed to augment the \cs{@outputbox}
-%    by attching floats and footnotes with appropriate spacing
+%    We have one socket that is supposed to augment the \cs{@outputbox}
+%    by attching floats and footnotes with appropriate spacing.
 %
 %    \begin{macrocode}
 \NewSocket{@makecol/outputbox}{0}
 %    \end{macrocode}
 %  \end{macro}
 %
-%    The following replaceable code alternatives are available:
+%    The following replaceable code alternatives are available for
+%    this socket:
 %
 %    \begin{macrocode}
-\DeclareSocketCode{@makecol/outputbox}{space-footnotes-floats} {%
+\NewSocketPlug{@makecol/outputbox}{space-footnotes-floats} {%
   \@if at footnotes@TF
       {\@outputbox at append{\vfill}}%
       {\@if at bfloats@TF
@@ -530,7 +546,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\DeclareSocketCode{@makecol/outputbox}{floats-footnotes-space} {%
+\NewSocketPlug{@makecol/outputbox}{floats-footnotes-space} {%
   \@outputbox at attachfloats
   \@if at footnotes@TF
       {\@outputbox at append{\vfill}}%
@@ -540,7 +556,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\DeclareSocketCode {@makecol/outputbox}{footnotes-space-floats} {%
+\NewSocketPlug {@makecol/outputbox}{footnotes-space-floats} {%
   \@outputbox at appendfootnotes
   \@if at bfloats@TF
       {\@outputbox at append{\vfill}}%
@@ -550,7 +566,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\DeclareSocketCode {@makecol/outputbox}{space-floats-footnotes} {%
+\NewSocketPlug {@makecol/outputbox}{space-floats-footnotes} {%
   \@if at footnotes@TF
       {\@outputbox at append{\vfill}}%
       {\@if at bfloats@TF
@@ -562,7 +578,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\DeclareSocketCode {@makecol/outputbox}{floats-footnotes} {%
+\NewSocketPlug {@makecol/outputbox}{floats-footnotes} {%
   \@outputbox at attachfloats
   \@outputbox at appendfootnotes
   \@outputbox at reinsertbskip
@@ -570,7 +586,7 @@
 %    \end{macrocode}
 %
 %    \begin{macrocode}
-\DeclareSocketCode {@makecol/outputbox}{footnotes-floats} {%
+\NewSocketPlug {@makecol/outputbox}{footnotes-floats} {%
   \@outputbox at appendfootnotes
   \@outputbox at attachfloats
 %    \end{macrocode}
@@ -588,7 +604,7 @@
 %    \LaTeX{}, it can be overwritten either through \pkg{footmisc} or
 %    by assigning any of the other replaceable block code chunks.
 %    \begin{macrocode}
-\AssignSocketCode {@makecol/outputbox}{footnotes-floats}
+\AssignSocketPlug {@makecol/outputbox}{footnotes-floats}
 %    \end{macrocode}
 %
 %
diff --git a/required/latex-lab/latex-lab-socket.dtx b/required/latex-lab/latex-lab-socket.dtx
index fa5e3474..7c1d1365 100644
--- a/required/latex-lab/latex-lab-socket.dtx
+++ b/required/latex-lab/latex-lab-socket.dtx
@@ -29,7 +29,7 @@
 % \fi
 %
 %
-% \title{The \texttt{latex-lab-testphase-socket} code\thanks{}}
+% \title{The \texttt{latex-lab-testphase-socket} code}
 % \author{Frank Mittelbach, \LaTeX{} Project}
 %
 % \maketitle
@@ -37,16 +37,404 @@
 % \newcommand\fmi[1]{\begin{quote} TODO: \itshape #1\end{quote}}
 % \newcommand\NEW[1]{\marginpar{\mbox{}\hfill\fbox{New: #1}}}
 % \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}
 %
-%    This code implements sockets which are places in the code into
-%    which predeclared chunks of code can be placed. Both the sockets
-%    and the code chunks are \enquote{named} and each socket is
-%    assigned exactly one code chunk.
+% 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.
+% \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 that 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-arguments}
+% \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 arguments with
+% \begin{quote}
+%   \cs{UseSocket}\marg{socket-name}\marg{arg\textsubscript{1}}\ldots
+%   \marg{arg\textsubscript{number-of-arguments}}
+% \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}.
+% 
+% If the socket takes arguments, 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 wth using it in several places, as long
+% as the code in all places is supposed to change in the same way.
+% 
+% 
+%
+% \subsubsection{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-arguments}
+% \cs{socket_new:nn}\Arg{socket-name}\Arg{number-of-arguments}
+% \end{syntax}
+%   Declares a new socket with name \meta{socket-name} having
+%   \meta{number-of-arguments} arguments. By default it does nothing
+%   other than gobbling the arguments,
+%   i.e., executes the plug \plug{do-nothing}, which is automatically
+%   defined for the new socket as part of the declaration.
+%
+%   Its documentation should describe its purpose, its inputs and the
+%   expected results as discussed above.
+% \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 that.
+% \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.
+% \end{function}
+%
+% 
+% \begin{function}{\UseSocket,\socket_use:n}
+% \begin{syntax}
+% \cs{UseSocket}   \Arg{socket-name}
+% \cs{socket_use:n}\Arg{socket-name}
+% \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.
+% \end{function}
+%
+% 
+% \begin{function}{\ShowSocket,\socket_show: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.
+% \end{function}
+%
+% 
+% \begin{function}{\DebugSocketsOn,\DebugSocketsOff}
+% \begin{syntax}
+% \cs{DebugSocketsOn} \ldots\ \cs{DebugSocketsOff}
+% \end{syntax}
+%   Turns debugging of sockets on or off.\fmi{implement}
+% \end{function}
+%
+% 
+% 
+%
+% \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 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
+%  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
+%       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 :-)\,)
+%   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
+%
+%   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}
+% 
+% 
 %
 %
 %
@@ -66,10 +454,9 @@
 %<@@=socket>
 %    \end{macrocode}
 %
-% \subsection{File declaration}
 %
 %    \begin{macrocode}
-\ProvidesExplPackage {latex-lab-testphase-socket} {2023-06-15} {0.1a}
+\ProvidesExplPackage {latex-lab-testphase-socket} {2023-07-20} {0.8a}
   {sockets (or replaceable code blocks)}
 %    \end{macrocode}
 %
@@ -91,8 +478,32 @@
       {
         \str_new:c { g_@@_#1_code_str }
         \int_const:cn { c_@@_#1_args_int } {#2}
-        \socket_new_code:nnn {#1} { do_nothing } { }
-        \socket_assign_code:nn {#1} { do_nothing }
+        \socket_new_plug:nnn {#1} { do-nothing } { }
+        \socket_assign_plug:nn {#1} { do-nothing }
+      }
+}
+%    \end{macrocode}
+%  \end{macro}
+%  
+%  
+%  \begin{macro}{\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_show:n #1 {
+  \str_if_exist:cTF { g_@@_#1_code_str }
+      {
+        \typeout{ Socket~ #1:}
+        \typeout{ \@spaces number~ of~ arguments~ =~ \int_use:c { c_@@_#1_args_int } }
+        \typeout{ \@spaces available~plugs~ =~ "not~ tracked~ yet" }
+        \typeout{ \@spaces current~ plug~ =~ \str_use:c { g_@@_#1_code_str } }
+        \typeout{ \@spaces definition~ =~
+          \exp_args:Nc \cs_meaning:N 
+                       { _@@_#1_code_ \str_use:c { g_@@_#1_code_str } :w } }
+        \typeout{}
+      }
+      {
+        \errmessage { Socket~ '#1'~ not~ declared! }
       }
 }
 %    \end{macrocode}
@@ -100,22 +511,31 @@
 %  
 %  
 %  
-%  \begin{macro}{\socket_new_code:nnn}
+%  
+%  
+%  \begin{macro}{\socket_new_plug:nnn}
 %    
 %    Declaring a code for a socket is just making a definition, taking
-%    the number of arguments from the saved int.
+% the number of arguments from the saved int.
 %    \begin{macrocode}
-\cs_new_protected:Npn \socket_new_code:nnn #1 #2 #3 {
-  \str_if_exist:cTF { g_@@_#1_code_str }
+\cs_new_protected:Npn \socket_new_plug:nnn {
+  \@@_define_code:Nnnn \cs_new_protected:Npn
+}
+\cs_new_protected:Npn \socket_set_code:nnn {
+  \@@_define_code:Nnnn \cs_set_protected:Npn
+}
+
+\cs_new_protected:Npn \@@_define_code:Nnnn #1 #2 #3 #4 {
+  \str_if_exist:cTF { g_@@_#2_code_str }
       {
         \cs_generate_from_arg_count:cNnn
-           { _@@_#1_code_#2:w }
-           \cs_new_protected:Npn
-           { \int_use:c { c_@@_#1_args_int } }
-           {#3}
+           { @@_#2_code_#3:w }
+           #1
+           { \int_use:c { c_@@_#2_args_int } }
+           {#4}
       }
       {
-        \errmessage { Socket~ '#1'~ not~ declared! }
+        \errmessage { Socket~ '#2'~ not~ declared! }
       }
 }
 %    \end{macrocode}
@@ -123,15 +543,15 @@
 %  
 %  
 %  
-%  \begin{macro}{\socket_assign_code:nn}
+%  \begin{macro}{\socket_assign_plug:nn}
 %    
 %    Assigning stored code to a socket just changes the name in
 %    the socket string.
 %    \begin{macrocode}
-\cs_new_protected:Npn \socket_assign_code:nn #1 #2 {
+\cs_new_protected:Npn \socket_assign_plug:nn #1 #2 {
   \str_if_exist:cTF { g_@@_#1_code_str }
       {
-        \cs_if_exist:cTF { _@@_#1_code_#2:w }
+        \cs_if_exist:cTF { @@_#1_code_#2:w }
           {
             \str_gset:cn { g_@@_#1_code_str } {#2}
           }
@@ -160,15 +580,23 @@
 %  
 % \subsection{The \LaTeXe{} interface commands}
 %
-%  \begin{macro}{\NewSocket,\DeclareSocketCode,
-%                \AssignSocketCode,\UseSocket}
-%    
+%  \begin{macro}{\NewSocket,\NewSocketPlug,
+%                \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 \DeclareSocketCode \socket_new_code:nnn
-\cs_new_eq:NN \AssignSocketCode  \socket_assign_code:nn
+\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:n
 %    \end{macrocode}
+%    Not yet implemented:
+%    \begin{macrocode}
+\cs_new_eq:NN \DebugSocketsOn    \prg_do_nothing:
+\cs_new_eq:NN \DebugSocketsOff   \prg_do_nothing:
+%    \end{macrocode}
 %  \end{macro}
 %  
 %
diff --git a/required/latex-lab/testfiles/new-or-001.lvt b/required/latex-lab/testfiles/new-or-001.lvt
index 676c4626..65d63531 100644
--- a/required/latex-lab/testfiles/new-or-001.lvt
+++ b/required/latex-lab/testfiles/new-or-001.lvt
@@ -13,8 +13,12 @@
 
 \makeatletter
 \ShowCommand\@makecol
-\ShowCommand\@makecol at cfgpoint
-\ShowCommand\@makecol at cfgpointii
+\typeout{-------------------}
+
+\ShowSocket {@makecol/outputbox}
+\ShowSocket {@makecol/footnotes}
+
+\typeout{-------------------}
 \ShowCommand\@outputbox at removebskip
 
 \END
diff --git a/required/latex-lab/testfiles/new-or-001.tlg b/required/latex-lab/testfiles/new-or-001.tlg
index 5bc8459e..d3aa400d 100644
--- a/required/latex-lab/testfiles/new-or-001.tlg
+++ b/required/latex-lab/testfiles/new-or-001.tlg
@@ -1,17 +1,21 @@
 This is a generated file for the l3build validation system.
 Don't change this file in any respect.
 > \@makecol=macro:
-->\@kernel at before@cclv \setbox \@outputbox \box \@cclv \@outputbox at removebskip \let \@elt \relax \xdef \@freelist {\@freelist \@midlist }\global \let \@midlist \@empty \@makecol at cfgpoint \ifvbox \@kludgeins \@makespecialcolbox \else \@makenormalcolbox \fi \global \maxdepth \@maxdepth .
+->\@kernel at before@cclv \setbox \@outputbox \box \@cclv \@outputbox at removebskip \let \@elt \relax \xdef \@freelist {\@freelist \@midlist }\global \let \@midlist \@empty \UseSocket {@makecol/outputbox}\ifvbox \@kludgeins \@makespecialcolbox \else \@makenormalcolbox \fi \global \maxdepth \@maxdepth .
 <argument> \@makecol 
 l. ...\ShowCommand\@makecol
-> \@makecol at cfgpoint=macro:
-->\@outputbox at appendfootnotes \@outputbox at attachfloats \@outputbox at reinsertbskip .
-<argument> \@makecol at cfgpoint 
-l. ...\ShowCommand\@makecol at cfgpoint
-> \@makecol at cfgpointii=macro:
-->.
-<argument> \@makecol at cfgpointii 
-l. ...\ShowCommand\@makecol at cfgpointii
+-------------------
+Socket '@makecol/outputbox':
+    number of arguments = 0
+    available plugs = "not tracked yet"
+    current plug = footnotes-floats
+    definition = \protected\long macro:->\@outputbox at appendfootnotes \@outputbox at attachfloats \@outputbox at reinsertbskip 
+Socket '@makecol/footnotes':
+    number of arguments = 0
+    available plugs = "not tracked yet"
+    current plug = do_nothing
+    definition = \protected\long macro:->
+-------------------
 > \@outputbox at removebskip=macro:
 ->\ifx \@textbottom \relax \else \@outputbox at append {\@tempskipa \lastskip \ifnum \gluestretchorder \@tempskipa >\z@ \vskip -\@tempskipa \xdef \@outputbox at reinsertbskip {\noexpand \@outputbox at append {\vskip \the \@tempskipa }}\else \global \let \@outputbox at reinsertbskip \relax \fi }\fi .
 <argument> \@outputbox at removebskip 





More information about the latex3-commits mailing list.