commit 0e363cd6ef86e796c5e973efdeae15de4645633f
parent 05f09546037bc5746b1524414cd5597c122a7650
Author: robert <robertrussell.72001@gmail.com>
Date: Fri, 10 Sep 2021 11:59:04 -0700
Add event/hook mechanism, particularly for font system
Diffstat:
| A | font.tex | | | 64 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
1 file changed, 64 insertions(+), 0 deletions(-)
diff --git a/font.tex b/font.tex
@@ -0,0 +1,64 @@
+\Fhsize \Ftsize \Fssize \Fzsize
+
+\newtoks\icomit \icomit={\\{.}\\{,}}
+
+An "H font set" is a list of optical sizes of the same font; each font in the
+list has an associated scale factor (times 1000) and arbitrary token list for
+initializing the font (e.g., skewchar, hyphenchar, fontdimens, etc.).
+We provide macros for deriving new font sets by scaling or adding code to the
+token list of existing font sets.
+An "M font set" is a tuple of three H font sets.
+(H = horizontal, M = math; we could call H fonts "text fonts", but that is too
+easily confusable with \textfont.)
+
+\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 \long and \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}
+% produces
+% Hello from my event! (#1 = abc) Hello from my hook! (#2 = xyz)
+\newstack\@eventstack
+\protected\long\def\eventdef#1#2#{\@eventdef{#1}{#2}}
+\long\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
+ \long\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{\long\def\noexpand\csB\the\toksA}%
+ \nea\noexpand\csA\nea{%
+ % Expand the hooks tokens register in a temporary 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".
+ \nea\toksA\nea{\noexpand\the\toks\number\allocnum}%
+ \edef\noexpand\dohooks{\noexpand\the\toksA}%
+ \unexpanded{#3\relax}%
+ \poptok\@eventstack \let\noexpand\dohooks\noexpand\ptok
+ }%
+ \noexpand\csB
+ }%
+}
+
+\protected\long\def\addhook#1#2{\toksapp\ea\@hooknum#1{#2\relax}}
+\long\def\@hooknum#1#2#3\csB{#2}