[latex3-commits] [git/LaTeX3-latex3-latex3] master: First steps in hooks (7f8f2dd)

Joseph Wright joseph.wright at morningstar2.co.uk
Mon Jun 3 14:46:21 CEST 2019


Repository : https://github.com/latex3/latex3
On branch  : master
Link       : https://github.com/latex3/latex3/commit/7f8f2dd5765fa6c99565208e894504d8e27ce635

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

commit 7f8f2dd5765fa6c99565208e894504d8e27ce635
Author: Joseph Wright <joseph.wright at morningstar2.co.uk>
Date:   Mon Jun 3 13:46:21 2019 +0100

    First steps in hooks


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

7f8f2dd5765fa6c99565208e894504d8e27ce635
 l3trial/l3hooks/l3hooks.dtx |  164 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 164 insertions(+)

diff --git a/l3trial/l3hooks/l3hooks.dtx b/l3trial/l3hooks/l3hooks.dtx
index bd3eecc..5291d4c 100644
--- a/l3trial/l3hooks/l3hooks.dtx
+++ b/l3trial/l3hooks/l3hooks.dtx
@@ -54,6 +54,34 @@
 %
 % \section{\pkg{l3hooks} documentation}
 %
+% \begin{function}[added = 2019-06-03]
+%   {\hook_single_new:nn, \hook_repeated_new:nn}
+%   \begin{syntax}
+%     \cs{hook_single_new:nn} \Arg{module} \Arg{hook}
+%   \end{syntax}
+%   Creates a new \meta{hook} for the \meta{module} specified. The
+%   |single| version creates a hook for a single use, and thus for
+%   document-wide concepts. The |repeated| version creates a hook which
+%   is persistent, and can be used multiple times.
+% \end{function}
+%
+% \begin{function}[added = 2019-06-03]
+%   {
+%     \hook_gpush_all:nnnn,  \hook_gpush_next:nnnn,
+%     \hook_gpush_all:nnnnn, \hook_gpush_next:nnnnn,
+%   }
+%   \begin{syntax}
+%     \cs{hook_gpush_all:nnnn} \Arg{module-a} \Arg{hook} \Arg{module-b} \Arg{code}
+%     \cs{hook_gpush_all:nnnnn} \Arg{module-a} \Arg{hook} \Arg{module-b} \Arg{desc} \Arg{code}
+%   \end{syntax}
+% \end{function}
+%
+% \begin{function}[added = 2019-06-03]{\hook_use:nn}
+%   \begin{syntax}
+%     \cs{hook_use:nn} \Arg{module} \Arg{hook}
+%   \end{syntax}
+% \end{function}
+%
 % \end{documentation}
 %
 % \begin{implementation}
@@ -75,6 +103,142 @@
 %</package>
 %    \end{macrocode}
 %
+% \begin{macro}{\hook_repeated_new:nn, \hook_single_new:nn}
+%   Hooks can be set up for a single use (for example at the start of a
+%   document) or to be used repeatedly (\emph{e.g.}~at the start of every
+%   use of an environment). We use the \enquote{one-off} hook structure as
+%   a marker: this will always be created.
+%    \begin{macrocode}
+\cs_new_protected:Npn \hook_repeated_new:nn #1#2
+  {
+    \cs_if_free:cTF { g_@@_next_ #1 _ #2 _seq }
+      {
+        \prop_new:c { g_@@_all_ #1 _ #2 _prop }
+        \prop_new:c { g_@@_next_ #1 _ #2 _prop }
+        \seq_new:c { g_@@_all_ #1 _ #2 _seq }
+        \seq_new:c { g_@@_next_ #1 _ #2 _seq }
+      }
+      {
+        \__kernel_msg_error:nnn { hooks }
+          {  hook-already-defined } {#1} {#2}
+      }
+  }
+\cs_new_protected:Npn \hook_single_new:nn #1#2
+  {
+    \cs_if_free:cTF { g_@@_next_ #1 _ #2 _seq }
+      {
+        \prop_new:c { g_@@_next_ #1 _ #2 _seq }
+        \seq_new:c { g_@@_next_ #1 _ #2 _seq }
+      }
+      {
+        \__kernel_msg_error:nnn { hooks }
+          {  hook-already-defined } {#1} {#2}
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+%
+% \begin{macro}{\hook_gpush_all:nnnn, \hook_gpush_next:nnnn}
+% \begin{macro}{\hook_gpush_all:nnnnn, \hook_gpush_next:nnnnn}
+% \begin{macro}{\@@_gpush:nnnnn}
+%   Pushing code to a hook requires that we store the order (a sequence) and
+%   the code (as a prop). Where a module uses a description for hook content,
+%   we simply join that onto the module name.
+%    \begin{macrocode}
+\cs_new_protected:Npn \hook_gpush_all:nnnn #1#2#3#4
+  { \@@_gpush:nnnnn { all } {#1} {#2} {#3} {#4} }
+\cs_new_protected:Npn \hook_gpush_next:nnnn #1#2#3#4
+  { \@@_gpush:nnnnn { next } {#1} {#2} {#3} {#4} }
+\cs_new_protected:Npn \hook_gpush_all:nnnnn #1#2#3#4#5
+  { \@@_gpush:nnnnn { all } {#1} {#2} { #3 - #4 } {#5} }
+\cs_new_protected:Npn \hook_gpush_next:nnnnn #1#2#3#4#5
+  { \@@_gpush:nnnnn { next } {#1} {#2} { #3 - #4 } {#5} }
+\cs_new_protected:Npn \@@_gpush:nnnnn #1#2#3#4#5
+  {
+    \seq_if_exist:cTF { g_@@_next_ #2 _ #3 _seq }
+      {
+        \seq_if_exist:cTF { g_@@_ #1 _ #2 _ #3 _seq }
+          {
+            \seq_gpush:cn { g_@@_ #1 _ #2 _ #3 _seq } {#4}
+            \prop_gput:cnn { g_@@_ #1 _ #2 _ #3 _prop } {#4} {#5}
+          }
+          {
+            \__kernel_msg_error:nnn { hooks }
+              {  single-use-hook } {#2} {#3}
+          }
+      }
+      {
+        \__kernel_msg_error:nnn { hooks }
+          {  unknown-hook } {#2} {#3}
+      }
+  }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}{\hook_use:nn}
+% \begin{macro}{\@@_use:n}
+%   To insert a hook, first we deal with the |all| hook data and then the
+%   |next|. The latter is set up such that the insertions will be ready-to-go
+%   with a cleared hook, to cover the case where repeated use of the |next|
+%   hook is needed.
+%    \begin{macrocode}
+\cs_new_protected:Npn \hook_use:nn #1#2
+  {
+    \cs_if_free:cTF { g_@@_next_ #1 _ #2 _seq }
+      {
+        \__kernel_msg_error:nnn { hooks }
+          {  unknown-hook } {#1} {#2}
+      }
+      {
+        \cs_set:Npn \@@_use:n ##1
+          { \prop_item:cn { g_@@_all_ #1 _ #2 _prop } {##1} }
+        \cs_if_free:cF { g_@@_all_ #1 _ #2 _seq }
+          { \seq_map_function:cN { g_@@_all_ #1 _ #2 _seq } \@@_use:n }
+        \cs_set:Npn \@@_use:n ##1
+          {
+            \exp_not:f
+              {
+                \prop_item:cn { g_@@_next_ #1 _ #2 _prop }
+                  {##1}
+              }
+          }
+        \use:x
+          {
+            \seq_gclear:c { g_@@_next_ #1 _ #2 _seq }
+            \seq_map_function:cN { g_@@_next_ #1 _ #2 _seq }
+              \@@_use:n
+          }
+      }
+  }
+\cs_new:Npn \@@_use:n #1 { }
+%    \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% Messages.
+%    \begin{macrocode}
+\__kernel_msg_new:nnnn { hooks } { hook-already-defined }
+  { Hook~'#1/#2'~already~defined. }
+  {
+    LaTeX~has~been~asked~to~create~a~new~hook~'#2'~for~module~'#1'~
+    but~this~name~has~already~been~used~elsewhere.
+  }
+\__kernel_msg_new:nnnn { hooks } { single-use-hook }
+  { Hook~'#1/#2'~is~single~use~only. }
+  {
+    LaTeX~has~been~asked~add~content~to~all~uses~of~hook~'#2'~for module~'#1'~
+    but~this~hook~is~only~every~used~once.
+  }
+\__kernel_msg_new:nnnn { hooks } { unknown-hook }
+  { Unknown~hook~'#1/#2'. }
+  {
+    LaTeX~has~been~asked~insert~a~hook~'#2'~for module~'#1'~
+    but~this~name~has~not~been~defined.
+  }
+%    \end{macrocode}
+%
 %    \begin{macrocode}
 %</initex|package>
 %    \end{macrocode}





More information about the latex3-commits mailing list