commit 044dacbb2f40c3fbb9a23f9cf667ca9a4b53b454
parent 6bc791b8656d6059e7574c36e8dfbbc3baf4ae51
Author: robert <robertrussell.72001@gmail.com>
Date: Sat, 15 Jan 2022 20:42:01 -0800
Simplify events and hooks
Diffstat:
| M | font.tex | | | 71 | +++++++++++++++++++++-------------------------------------------------- |
1 file changed, 21 insertions(+), 50 deletions(-)
diff --git a/font.tex b/font.tex
@@ -13,56 +13,27 @@ easily confusable with \textfont.)
\protected\def\rm{\rminit \rmtext \rmmath}
-% \eventdef defines an "event", which is a special type of macro. Events may
-% be treated like regular macros, except that
-% - events are always \global,
-% - the expansion of an event is not simply its body,
-% - expanding an event in an expansion-only context (like \edef) is unsafe,
-% - the body of an event may not access tokens after its arguments from the
-% main token stream (e.g., \eventdef\myevent{\macrowithargs} is broken).
-% The benefit of using events over regular macros comes from the ability to
-% attach "hooks" to events using \addhook. In order to make use of hooks,
-% an event must use the \dohooks macro at least once within its body. Hooks
-% have access to the associated event's arguments. For example,
-% \eventdef\myevent#1#2{Hello from my event! (\#1 = #1) \dohooks}
-% \addhook\myevent{Hello from my hook! (\#2 = #2)}
-% \myevent{abc}{xyz}
+% \defevent defines an "event". Hooks can be attached to events with \addhook,
+% and all hooks are run in order when the event is triggered with \event.
+% Events can have parameters like macros, and hooks have access to these
+% parameters. For example,
+% \defevent#1#2[myevent]
+% \addhook[myevent]{Hello from my 1st hook! (\#1 = #1)}
+% \addhook[myevent]{Hello from my 2nd hook! (\#2 = #2)}
+% \event[myevent]{abc}{xyz}
% produces
-% Hello from my event! (#1 = abc) Hello from my hook! (#2 = xyz)
-\newq\@eventstack
-\newtoks\@eventhooks
-\protected\def\eventdef#1#2#{\@eventdef{#1}{#2}}
-\def\@eventdef#1#2#3{%
- % We can't refer to the hooks tokens register using a \toksdef'ed control
- % sequence based on \string#1, because then event aliases created using
- % \let wouldn't work in \addhook. Instead we "hard-code" the tokens
- % register number inside the event macro.
- \newtoks\csA
- \scantokens{\toksA={#2}}% Double hashes
- \xdef#1{%
- % No op. Used by \addhook to get hooks tokens register number.
- \noexpand\selectx{\number\allocnum}%
- \pushtok\@eventstack\noexpand\dohooks
- % Put start of \csB def in \csA, so we can \expandafter over it to
- % expand the hooks token list.
- \def\noexpand\csA{\def\noexpand\csB\the\toksA}%
- \nea\noexpand\csA\nea{%
- % Expand the hooks tokens register in a tokens register instead of
- % directly in the \dohooks macro so that doubled hashes in a hook
- % body produce the more appropriate error of "you can't use `macro
- % parameter character #' in horizontal mode" instead of "illegal
- % parameter number in definition of \dohooks". We use an allocated
- % register for this purpose, so that temporary registers may be
- % used to pass information to the event body. The assignments to
- % \@eventhooks and \dohooks are global to reduce save stack usage.
- \nea\global\nea\@eventhooks\nea{\noexpand\the\toks\number\allocnum}%
- \xdef\noexpand\dohooks{\noexpand\the\@eventhooks}%
- \unexpanded{#3\relax}%
- \poptok\@eventstack \glet\noexpand\dohooks\noexpand\qtok
- }%
- \noexpand\csB
- }%
+% Hello from my 1st hook! (#1 = abc)Hello from my 2nd hook! (#2 = xyz)
+\protected\def\defevent#1[#2]{%
+ \ea\newtoks\begcs param:#2\endcs \cs{param:#2}={#1}%
+ \ea\newtoks\begcs hooks:#2\endcs \cs{hooks:#2}={}%
}
-\protected\def\addhook#1#2{\toksapp\ea\@hooknum#1{#2\relax}}
-\def\@hooknum#1#2#3\csB{#2}
+\protected\def\event[#1]{%
+ % Put start of \@hooks definition in \csA, so we can \expandafter over it
+ % to expand the hooks token list.
+ \edef\csA{\def\noexpand\@hooks\the\cs{param:#1}}%
+ \ea\csA\ea{\the\cs{hooks:#1}}%
+ \@hooks
+}
+
+\protected\def\addhook[#1]#2{\cs{hooks:#1}\ea{\the\cs{hooks:#1}#2}}