math-acc.mklx /size: 12 Kb    last modification: 2024-01-16 09:02
1%D \module
2%D   [       file=math-acc,
3%D        version=2013.07.31,
4%D          title=\CONTEXT\ Math Macros,
5%D       subtitle=Accents,
6%D         author=Hans Hagen,
7%D           date=\currentdate,
8%D      copyright={PRAGMA ADE \& \CONTEXT\ Development Team}]
9%C
10%C This module is part of the \CONTEXT\ macro||package and is
11%C therefore copyrighted by \PRAGMA. See mreadme.pdf for
12%C details.
13
14\writestatus{loading}{ConTeXt Math Macros / Accents}
15
16% There are probably errors ... too distracted by amazing (piano) music videos running
17% on top of scite ... so: experimental code.
18
19\unprotect
20
21%D This module permits overloading of accents so that we can do fancy things. The
22%D implementation is similar to stackers. By default accenst are defined in a simple
23%D way. Contrary to extensibles accents cannot grow indefinitely. Alas the
24%D implementation of accents is different too, in the sense that they are
25%D prepositioned i.e. are already raised. (In my opinion for no real reason as they
26%D need to adapt anyway).
27%D
28%D In \MKIV\ we used virtual characters in the "FE* range but in \LMTX\ we do it a bit
29%D different as we have a more powerful virtual subsystem. For details on the older
30%D but neat approach see the lua and mkiv files.
31%D
32%D Older implementations are kept in the \MKII\ and \MKIV\ modules for educational
33%D purposes.
34
35%D Only very few fonts provide flat accents but we emulate them for those that don't
36%D have them. We also need to fix the related font parameter for a few fonts like
37%D Lucida and Garamond.
38
39% \startbuffer
40% \im{
41%     \dostepwiserecurse{`A}{`Z}{1}{
42%         \blackrule[height=\the\Umathflattenedaccentbaseheight\textstyle,depth=0pt,width=0.05ts]
43%         \hat{\char#1}
44%     }
45% }
46% \stopbuffer
47%
48% \start % TEXpage[offset=1ts]
49%     \showglyphs
50%     \switchtobodyfont[modern]     \getbuffer\par
51%     \switchtobodyfont[erewhon]    \getbuffer\par
52%     \switchtobodyfont[concrete]   \getbuffer\par
53%     \switchtobodyfont[libertinus] \getbuffer\par
54%     \switchtobodyfont[stixtwo]    \getbuffer\par
55%     \switchtobodyfont[kpfonts]    \getbuffer\par
56%     \switchtobodyfont[minion]     \getbuffer\par
57%     \switchtobodyfont[schola]     \getbuffer\par
58%     \switchtobodyfont[lucida]     \getbuffer\par
59%     \switchtobodyfont[xcharter]   \getbuffer\par
60%     \switchtobodyfont[libertinus] \getbuffer\par
61%     \switchtobodyfont[termes]     \getbuffer\par
62% \stop %TEXpage
63
64% scale:
65%
66%   no   : only use base
67%   yes  : use base, variants and extensible, stretch and shrink when set
68%   keep : use base, variants and extensible, stretch and shrink when set, but keep base
69%
70% alignsymbol:
71%
72%   center when accent is wider than base
73%
74% stretch|shrink:
75%
76%   scale accent to fit (base and variants depending on 'scale' value)
77
78\installcorenamespace{mathaccents}
79
80\installcommandhandler \??mathaccents {mathaccent} \??mathaccents
81
82\aliased\let\setupmathaccents\setupmathaccent
83
84\setupmathaccents
85  [\c!top=,
86   \c!bottom=,
87   \c!mathstyle=,
88   \c!color=,
89   \c!scale=\v!no,
90   \c!alignsymbol=\v!yes,
91  %\c!stretch=\v!no,
92  %\c!shrink=\v!no,
93   \c!define=\v!yes, % not used
94   \c!snap=\mathematicsparameter\c!snap]
95
96\definemathaccent
97  [\v!both]
98
99\definemathaccent
100  [\v!top]
101  [\v!both]
102
103\definemathaccent
104  [\v!bottom]
105  [\v!both]
106
107\setupmathaccents
108  [\v!top]
109  [i=\v!auto]
110
111\setupmathaccents
112  [\v!both]
113  [i=\v!auto]
114
115\setupmathaccents
116  [\v!bottom]
117  [i=]
118
119\permanent\tolerant\protected\def\definemathtopaccent[#1]#*[#2]#*[#3]% class name top
120  {\ifparameter#3\or
121     \frozen\protected\instance\edefcsname#2\endcsname{\math_accent_make_double                       {#1}\plusone{\number#3}\zerocount}%
122   \else
123     \frozen\protected\instance\edefcsname#1\endcsname{\math_accent_make_double\noexpand\currentmathaccent\plusone{\number#2}\zerocount}%
124   \fi}
125
126\permanent\tolerant\protected\def\definemathbottomaccent[#1]#*[#2]#*[#3]% class name bottom
127  {\ifparameter#3\or
128     \frozen\protected\instance\edefcsname#2\endcsname{\math_accent_make_double                       {#1}\plustwo\zerocount{\number#3}}%
129   \else
130     \frozen\protected\instance\edefcsname#1\endcsname{\math_accent_make_double\noexpand\currentmathaccent\plustwo\zerocount{\number#2}}%
131   \fi}
132
133\permanent\tolerant\protected\def\definemathdoubleaccent[#1]#*[#2]#*[#3]#*[#4]% class name top bottom
134  {\ifparameter#4\or
135     \frozen\protected\instance\edefcsname#2\endcsname{\math_accent_make_double                       {#1}\plusthree{\number#3}{\number#4}}%
136   \else
137     \frozen\protected\instance\edefcsname#1\endcsname{\math_accent_make_double\noexpand\currentmathaccent\plusthree{\number#2}{\number#3}}%
138   \fi}
139
140\installlocalcurrenthandler \??mathaccents {mathaccent}
141
142%D \starttyping
143%D \im { \showboxes \showglyphs
144%D     \hat{\tilde{\dot{x}}}
145%D }
146%D \im { \showboxes \showglyphs
147%D     \hat[align=middle]{\tilde[align=middle]{\dot{x}}}
148%D }
149%D \stoptyping
150
151\tolerant\protected\def\math_accent_make_double#class#kind#top#bottom#*[#settings]#:#content%
152  {\beginmathgroup
153   \setlocalmathaccentcurrent{#class}% \edef\currentmathaccent{#class}%
154   \startusemathstyleparameter\mathaccentparameter\c!mathstyle
155   \setupcurrentmathaccent[#settings]%
156   \edef\p_scale{\mathaccentparameter\c!scale}%
157   \ifx\p_scale\v!keep
158     \lettonothing\m_fixed
159   \orelse\ifx\p_scale\v!yes
160     \lettonothing\m_fixed
161   \else
162     \let\m_fixed\s!fixed
163   \fi
164   \Umathaccent
165     \usedcolorparameterattributes{\mathaccentparameter\c!color}%
166 % nooverflow % there is never na overflow anyway but we do accept the key
167   \ifcstok{\mathaccentparameter\c!align  }\v!middle\s!center \space\fi
168   \ifcstok{\mathaccentparameter\c!stretch}\v!yes   \s!stretch\space\fi
169   \ifcstok{\mathaccentparameter\c!shrink }\v!yes   \s!shrink \space\fi
170   \ifcstok{\mathaccentparameter\c!snap   }\v!yes   \s!single \space\fi
171   \ifx\p_scale\v!keep
172     \s!keepbase\space
173   \fi
174   \ifcstok{\mathaccentparameter\c!alignsymbol}\v!yes
175     \s!nooverflow\space
176   \fi
177   \ifcstok{\mathaccentparameter\c!offset}\v!auto
178     \s!base\space
179   \fi
180   \ifcase#kind\or
181     \s!top\space
182     \m_fixed
183     \fam\zerocount#top
184   \or
185     \s!bottom\space
186     \m_fixed
187     \fam\zerocount#bottom
188   \or
189     \s!both\space
190     \m_fixed
191     \fam\zerocount#bottom
192     \fam\zerocount#top
193   \fi
194   {\ifcstok{\mathaccentparameter{i}}\v!auto\mathdotless\fi#content}%
195   \stopusemathstyleparameter
196   \endmathgroup}
197
198%D Relative new:
199
200% \newconditional\c_math_accent_auto_dotless \c_math_accent_auto_dotless\conditionaltrue % cf opentype math
201
202% \aliased\let\normalgrave\grave
203% \aliased\let\normalddot \ddot
204% \aliased\let\normalbar  \bar
205% \aliased\let\normalacute\acute
206% \aliased\let\normalhat  \hat     \aliased\let\normalwidehat  \widehat
207% \aliased\let\normalcheck\check
208% \aliased\let\normalbreve\breve
209% \aliased\let\normaldot  \dot
210% \aliased\let\normalring \ring
211% \aliased\let\normaltilde\tilde
212% \aliased\let\normaldddot\dddot
213
214\pushoverloadmode
215
216% These retain the given unicode values ... but can stretch when configured
217% to do so: \setupmathaccent[\v!top][\c!scale=\v!yes]
218
219% Extended/modified below
220%
221% \definemathtopaccent[\v!top][grave]["0060] % these are old school
222% \definemathtopaccent[\v!top][ddot] ["00A8]
223% \definemathtopaccent[\v!top][bar]  ["00AF]
224% \definemathtopaccent[\v!top][acute]["00B4]
225% \definemathtopaccent[\v!top][hat]  ["02C6]
226% \definemathtopaccent[\v!top][check]["02C7]
227% \definemathtopaccent[\v!top][breve]["02D8]
228% \definemathtopaccent[\v!top][dot]  ["02D9]
229% \definemathtopaccent[\v!top][ring] ["02DA]
230% \definemathtopaccent[\v!top][tilde]["02DC]
231% \definemathtopaccent[\v!top][dddot]["20DB]
232
233\definemathtopaccent[\v!top][grave]   ["0300]
234\definemathtopaccent[\v!top][acute]   ["0301]
235\definemathtopaccent[\v!top][hat]     ["0302]
236\definemathtopaccent[\v!top][tilde]   ["0303]
237\definemathtopaccent[\v!top][bar]     ["0305]
238%definemathtopaccent[\v!top][overbar] ["0305]% We expect overbar to stretch, so later
239\definemathtopaccent[\v!top][breve]   ["0306]
240\definemathtopaccent[\v!top][dot]     ["0307]
241\definemathtopaccent[\v!top][ddot]    ["0308]
242\definemathtopaccent[\v!top][overhook]["0309]
243\definemathtopaccent[\v!top][ring]    ["030A]
244\definemathtopaccent[\v!top][check]   ["030C]
245
246% Here starts the weird unicode ones
247
248%definemathtopaccent[\v!top][candra]               ["0310]
249%definemathtopaccent[\v!top][overturnedcomma]      ["0312]
250%definemathtopaccent[\v!top][overcommatopright]    ["0315]
251%definemathtopaccent[\v!top][leftangleabove]       ["031A]
252\definemathtopaccent[\v!top][overleftharpoon]      ["20D0]
253\definemathtopaccent[\v!top][overrightharpoon]     ["20D1]
254%definemathtopaccent[\v!top][verticaloverlayaccent]["20D2]
255%definemathtopaccent[\v!top][vec]                  ["20D7]% We expect vec to stretch, so later
256\definemathtopaccent[\v!top][dddot]                ["20DB]
257\definemathtopaccent[\v!top][ddddot]               ["20DC]
258%definemathtopaccent[\v!top][annuityaccent]        ["20E7]
259%definemathtopaccent[\v!top][overbracketaccent]    ["20E9]
260%definemathtopaccent[\v!top][asterixaccent]        ["20F0]
261
262% Weird ones (why no single and double underdots in unicode?)
263
264%definemathbottomaccent[\v!bottom][underdot]  ["0323]%Conflicting
265%definemathbottomaccent[\v!bottom][underddot] ["0324]
266%definemathbottomaccent[\v!bottom][underdddot]["20E8]
267
268\definemathaccent
269  [\v!top:\v!stretch]
270  [\v!top]
271  [\c!scale=\v!keep,\c!stretch=\v!yes,\c!shrink=\v!yes]
272
273\definemathaccent
274  [\v!bottom:\v!stretch]
275  [\v!bottom]
276  [\c!scale=\v!keep,\c!stretch=\v!yes,\c!shrink=\v!yes]
277
278\definemathaccent
279  [\v!both:\v!stretch]
280  [\v!both]
281  [\c!scale=\v!keep,\c!stretch=\v!yes,\c!shrink=\v!yes]
282
283\definemathaccent
284  [\v!top:\v!dot]
285  [\v!top:\v!stretch]
286  [i=]
287
288%D We have a problem. We can use stackers but then we need to adapt the dimensions
289%D which is font dependent. So, for now we keep them as accents.
290
291\definemathtopaccent[\v!top:\v!stretch][widegrave]["0300] % these are generic modern
292\definemathtopaccent[\v!top:\v!stretch][wideacute]["0301]
293\definemathtopaccent[\v!top:\v!stretch][widehat]  ["0302]
294\definemathtopaccent[\v!top:\v!stretch][widetilde]["0303]
295\definemathtopaccent[\v!top:\v!stretch][widebar]  ["0305]% (not 304, the caret)
296\definemathtopaccent[\v!top:\v!stretch][widebreve]["0306]
297\definemathtopaccent[\v!top:\v!stretch][widedot]  ["0307]
298\definemathtopaccent[\v!top:\v!stretch][wideddot] ["0308]
299\definemathtopaccent[\v!top:\v!stretch][widering] ["030A]
300\definemathtopaccent[\v!top:\v!stretch][widecheck]["030C]
301\definemathtopaccent[\v!top:\v!stretch][widedddot]["20DB]
302
303\definemathtopaccent[\v!top:\v!stretch][vec]["20D7] % clumsy notation for vectors
304
305\definemathtopaccent[\v!top:\v!stretch][wideoverleftharpoon]   ["20D0]
306\definemathtopaccent[\v!top:\v!stretch][wideoverrightharpoon]  ["20D1]
307\definemathtopaccent[\v!top:\v!stretch][wideoverleftarrow]     ["20D6]
308\definemathtopaccent[\v!top:\v!stretch][wideoverrightarrow]    ["20D7]
309\definemathtopaccent[\v!top:\v!stretch][wideoverleftrightarrow]["20E1]
310
311\definemathbottomaccent[\v!bottom:\v!stretch][wideundertilde]         ["0330]
312\definemathbottomaccent[\v!bottom:\v!stretch][wideunderbar]           ["0332]
313\definemathbottomaccent[\v!bottom:\v!stretch][wideunderleftrightarrow]["034D] % weird code
314\definemathbottomaccent[\v!bottom:\v!stretch][wideunderrightharpoon]  ["20EC]
315\definemathbottomaccent[\v!bottom:\v!stretch][wideunderleftharpoon]   ["20ED]
316\definemathbottomaccent[\v!bottom:\v!stretch][wideunderleftarrow]     ["20EE]
317\definemathbottomaccent[\v!bottom:\v!stretch][wideunderrightarrow]    ["20EF]
318
319% For complex conjugate: i below keeps the dot
320%
321% \im { \widebar  {\cos\theta + \ii \sin\theta} = \cos\theta - \ii\sin\theta }\par
322% \im { \conjugate{\cos\theta + \ii \sin\theta} = \cos\theta - \ii\sin\theta }
323
324\definemathtopaccent[\v!top:\v!dot][conjugate]["0305]
325
326\aliased\let\mathring\ring % for a while
327
328% \permanent\protected\def\not#1{\Umathaccent class \mathordinarycode exact overlay 0 0 "338 {#1}}
329% \permanent\protected\def\not#1{\Umathaccent class \mathrelationcode exact overlay 0 0 "338 {#1}}
330% \permanent\protected\def\not#1{\Umathaccent class \mathbinarycode   exact overlay 0 0 "338 {#1}}
331%
332% \definemathcommand[slashD][ordinary]{\Umathaccent class \mathordinarycode exact  overlay 0 0 "338 {D}}
333% \definemathcommand[slashD][ordinary]{\Umathaccent class \mathordinarycode center overlay 0 0 "338 {D}}
334
335\permanent\tolerant\protected\def\slashed[#1]#:#2%
336  {\Umathaccent
337     \s!class  \mathcodechecked{#1}%
338     \s!center \space
339     \s!overlay\space
340     \zerocount \zerocount \forwardslashasciicode
341   {#2}} % exact when =
342
343% \definemathcommand[slashD]{\slashed[ordinary]{D}}
344% \definemathcommand[slashD]{\slashed{D}}
345
346\popoverloadmode
347
348\protect \endinput
349