math-rad.mkvi /size: 10 Kb    last modification: 2021-10-28 13:50
1%D \module
2%D   [       file=math-rad,
3%D        version=2013.07.13,
4%D          title=\CONTEXT\ Math Macros,
5%D       subtitle=Radicals,
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 / Radicals}
15
16\unprotect
17
18%D \starttyping
19%D $\sqrt[3]{10}$
20%D \stoptyping
21%D
22%D This root command will be overloaded later:
23
24%D Old stuff:
25
26% \def\rootradical{\Uroot    \defaultmathfamily "221A } % can be done in char-def
27% \def\surdradical{\Uradical \defaultmathfamily "221A } % can be done in char-def
28
29\unexpanded\def\root#1\of{\rootradical{#1}} % #2
30
31\unexpanded\def\sqrt{\doifelsenextoptionalcs\rootwithdegree\rootwithoutdegree}
32
33% \ifcase \contextlmtxmode
34
35    \unexpanded\def\styledrootradical#1#2% so that \text works ok ... \rootradical behaves somewhat weird
36      {\normalexpanded{\rootradical
37         {\normalunexpanded{#1}}%
38         {\noexpand\triggermathstyle{\number\normalmathstyle}%
39          \normalunexpanded{#2}}}}
40
41% \else % experimental new keyword: (maybe keywords should come after the symbol)
42%
43%     \unexpanded\def\styledrootradical#1#2% so that \text works ok ... \rootradical behaves somewhat weird
44%       {\Uroot style \normalmathstyle "0 "221A {#1}{#2}}
45%
46% \fi
47
48\unexpanded\def\rootwithdegree[#1]{\rootradical{#1}}
49\unexpanded\def\rootwithoutdegree {\rootradical  {}}
50
51%D Even older stuff:
52
53% % is now a ordinary character
54%
55% \let\normalsurd\surd % \Uradical "0 "221A
56% \unexpanded\def\surd{\normalsurd{}}
57
58%D The real thing. If needed one can control matters with one of the many
59%D \type {\Umath...} parameters.
60%D
61%D \starttyping
62%D \def\R {\Umathradicaldegreeafter\textstyle0pt}
63%D \def\RR{\Umathradicaldegreeafter\textstyle\dimexpr
64%D    \Umathradicaldegreeafter\textstyle+.1em\relax}
65%D \def\RRR{\frozen\Umathradicaldegreeafter\textstyle\dimexpr
66%D    \Umathradicaldegreeafter\textstyle+.2em\relax}
67%D
68%D $    \sqrt[3]{5}   \RR\sqrt[3]{5}  \sqrt[3]{5} $\par
69%D $    \sqrt[3]{5} {\RRR\sqrt[3]{5}} \sqrt[3]{5} $\par
70%D $ \RR\sqrt[3]{5} {\RRR\sqrt[3]{5}} \sqrt[3]{5} $\par
71%D
72%D \def\R  {\Umathradicaldegreeafter\textstyle
73%D            0pt}
74%D \def\RR {\Umathradicaldegreeafter\textstyle
75%D            0.95\Umathradicaldegreeafter\textstyle}
76%D \def\RRR{\frozen\Umathradicaldegreeafter\textstyle
77%D            0.9\Umathradicaldegreeafter\textstyle}
78%D
79%D $    \sqrt[3]{5}   \RR\sqrt[3]{5}  \sqrt[3]{5} $\par
80%D $    \sqrt[3]{5} {\RRR\sqrt[3]{5}} \sqrt[3]{5} $\par
81%D $ \RR\sqrt[3]{5} {\RRR\sqrt[3]{5}} \sqrt[3]{5} $\par
82%D
83%D \def\RR {\mathopenupparameter\Umathradicaldegreeafter{.1}}
84%D
85%D $ \sqrt[3]{5}  \RR\sqrt[3]{5}  \sqrt[3]{5} $\par
86%D $ \sqrt[3]{5} {\RR\sqrt[3]{5}} \sqrt[3]{5} $\par
87%D \stoptyping
88
89\installcorenamespace{mathradical}
90\installcorenamespace{mathradicalalternative}
91
92\installcommandhandler \??mathradical {mathradical} \??mathradical
93
94\setupmathradical
95  [\c!alternative=\v!normal,
96   \c!mpoffset=.25\exheight]
97
98\appendtoks
99    \setuevalue{\currentmathradical}{\math_radical_handle{\currentmathradical}}
100\to \everydefinemathradical
101
102\unexpanded\def\math_radical_handle#tag%
103  {\begingroup
104   \edef\currentmathradical{#tag}%
105   \doifelsenextoptionalcs\math_radical_degree_yes\math_radical_degree_nop}
106
107\def\math_radical_alternative{\csname\??mathradicalalternative\mathradicalparameter\c!alternative\endcsname}
108
109\def\m_math_no_degree{{}}
110
111\def\math_radical_degree_yes[#degree]{\edef\currentmathradicaldegree{#degree}\math_radical_indeed}
112\def\math_radical_degree_nop         {\let\currentmathradicaldegree\m_math_no_degree\math_radical_indeed}
113
114\def\math_radical_indeed#body%
115  {\math_radical_alternative{#body}\endgroup}
116
117\setvalue{\??mathradicalalternative\v!default}%  #body%
118  {\rootradical{\currentmathradicaldegree}}   % {#body}}
119
120\setvalue{\??mathradicalalternative\v!normal}#body%
121  {\edef\p_color{\mathradicalparameter\c!color}%
122   \ifx\p_color\empty
123     \styledrootradical{\currentmathradicaldegree}{#body}% {} really needed as \rootradical expands first
124   \else\ifx\currentmathradicaldegree\empty
125     \pushcolor[\p_color]%
126     \styledrootradical{\currentmathradicaldegree}%
127     {\popcolor#body}%
128   \else
129     \pushcolor[\p_color]%
130     \styledrootradical{\popcolor\currentmathradicaldegree\pushcolor[\p_color]}%
131     {\popcolor#body}%
132   \fi\fi}
133
134% As I had a long standing whish to see a proper final root element I decided
135% to make one my own.
136%
137% \startMPcode
138%   path p ; p := unitsquare xysized(4cm,1cm) ;
139%
140%   path q ; q := boundingbox p enlarged (bbheight(p)/10) ;
141%   numeric h ; h := bbheight(q) ;
142%
143%   draw p ;
144%   draw
145%       llcorner q shifted (-h/2,h/2) --
146%       llcorner q shifted (-h/4,0) --
147%       ulcorner q --
148%       urcorner q --
149%       urcorner q shifted (0,-h/10) ;
150% \stopMPcode
151%
152% \startMPextensions
153%     vardef math_root(expr w,h,d,o) =
154%         path q ; q := boundingbox unitsquare xysized(w,h) enlarged (o);
155%         llcorner q shifted (-h/2,h/2) --
156%         llcorner q shifted (-h/4,-d) --
157%         ulcorner q --
158%         urcorner q --
159%         urcorner q shifted (0,-h/10)
160%     enddef ;
161% \stopMPextensions
162%
163% \startuniqueMPgraphic{root}{width,height,depth,offset,linewidth}
164%     pickup pencircle scaled \MPvar{linewidth} ;
165%     draw math_root(\MPvar{width},\MPvar{height},\MPvar{depth},\MPvar{offset}) ;
166% \stopuniqueMPgraphic
167%
168% \unexpanded\def\sqrt#1%
169%   {\begingroup
170%    \setbox\scratchbox\mathstylehbox{#1}%
171%    \scratchoffset\MPrawvar{root}{offset}%.25\exheight
172%    \scratchwidth \wd\scratchbox
173%    \scratchheight\ht\scratchbox
174%    \scratchdepth \dp\scratchbox
175%    \setbox2=\hbox\bgroup % todo: tag this box as sqrt
176%      \uniqueMPgraphic
177%        {root}%
178%        {width=\the\scratchwidth,%
179%         depth=\the\scratchdepth,%
180%         height=\the\scratchheight,%
181%         offset=\the\scratchoffset,
182%         linewidth=\the\linewidth}%
183%    \egroup
184%    \scratchdimen\wd2
185%    \lower\dimexpr\scratchoffset+\scratchdepth\relax\box2
186%    \hskip-\scratchdimen
187%    \hbox to \scratchdimen{\hss\box\scratchbox\hskip\scratchoffset}%
188%    \endgroup}
189
190\startMPextensions
191    vardef math_radical_simple(expr w,h,d,o) =
192        (-h/2-o,h/2-o) --
193        (-h/4-o,-d-o)  --
194        (-o,h+o)       --
195        (w+o,h+o)      --
196        (w+o,h-h/10+o)
197    enddef ;
198\stopMPextensions
199
200\startuniqueMPgraphic{minifun::math:radical:default}%{...}
201    draw
202        math_radical_simple(OverlayWidth,OverlayHeight,OverlayDepth,OverlayOffset)
203      % withpen pencircle xscaled (2OverlayLineWidth) yscaled (3OverlayLineWidth/4) rotated 30
204        withpen pencircle scaled OverlayLineWidth
205      % dashed evenly
206        withcolor OverlayLineColor ;
207\stopuniqueMPgraphic
208
209% todo: spacing .. this is just an experiment (article driven)
210
211\setvalue{\??mathradicalalternative\v!mp}#body% we could use dowithnextbox
212  {\begingroup
213   \scratchoffset\mathradicalparameter\c!mpoffset
214   \setbox\nextbox\mathstylehbox{#body}%
215   % we use the \overlay variables as these are passes anyway and
216   % it's more efficient than using parameters
217   \d_overlay_width    \wd\nextbox
218   \d_overlay_height   \ht\nextbox
219   \d_overlay_depth    \dp\nextbox
220   \d_overlay_offset   \scratchoffset
221   \d_overlay_linewidth\the\dimexpr\triggeredmathstyleparameter\Umathfractionrule
222   %
223   \edef\overlaylinecolor{\mathradicalparameter\c!color}%
224   %
225   \edef\p_mp{\mathradicalparameter\c!mp}%
226   %
227   \setbox\scratchbox\hpack\bgroup % todo: tag this box as sqrt
228     \uniqueMPgraphic
229       {\p_mp}%
230      %{...}%
231   \egroup
232   \scratchdimen       \wd\scratchbox
233   \scratchtopoffset   \dimexpr\scratchoffset+\dp\nextbox\relax
234   \scratchbottomoffset\dimexpr\scratchoffset+\ht\nextbox/2\relax
235   \hpack to \scratchdimen{\hss\box\nextbox\hskip\scratchoffset}%
236   \hskip-\scratchdimen
237   \lower\dimexpr\scratchtopoffset\box\scratchbox%
238   \ifx\currentmathradicaldegree\empty \else
239     \setbox\scratchbox\mathstylehbox{\scriptscriptstyle\currentmathradicaldegree\hss}%
240     \wd\scratchbox\scratchdimen
241     \hskip-\scratchdimen
242     \raise\dimexpr\scratchbottomoffset\box\scratchbox
243   \fi
244   \endgroup}
245
246\definemathradical[sqrt][mp=minifun::math:radical:default]
247
248% \setupmathradical[sqrt][alternative=normal,color=darkblue]
249% \setupmathradical[sqrt][alternative=mp,color=darkgreen]
250
251%D Because I wanted to illustrate some more fun stuff another mechanism
252%D is provided as well ... let's put some dangerous tools in the hand of
253%D math jugglers like Aditya.
254
255\installcorenamespace{mathornament}
256\installcorenamespace{mathornamentalternative}
257
258\installcommandhandler \??mathornament {mathornament} \??mathornament
259
260\setupmathornament
261  [\c!alternative=\v!mp, % currently mp only .. maybe some day layer too
262   \c!mpoffset=.25\exheight]
263
264\appendtoks
265    \setuevalue{\currentmathornament}{\math_ornament_handle{\currentmathornament}}
266\to \everydefinemathornament
267
268\unexpanded\def\math_ornament_handle#tag#body%
269  {\begingroup
270   \edef\currentmathornament{#tag}%
271   \csname\??mathornamentalternative\mathornamentparameter\c!alternative\endcsname{#body}%
272   \endgroup}
273
274\setvalue{\??mathornamentalternative\v!mp}#body% we could use dowithnextbox
275  {\begingroup
276   \scratchoffset\mathornamentparameter\c!mpoffset
277   \setbox\nextbox\mathstylehbox{#body}%
278   \d_overlay_width    \wd\nextbox
279   \d_overlay_height   \ht\nextbox
280   \d_overlay_depth    \dp\nextbox
281   \d_overlay_offset   \scratchoffset
282   \d_overlay_linewidth\linewidth
283   \edef\overlaylinecolor{\mathornamentparameter\c!color}%
284   \edef\p_mp{\mathornamentparameter\c!mp}%
285   % the width of the graphic determines the width of the final result
286   \setbox\scratchbox\hpack{\uniqueMPgraphic{\p_mp}}% todo: add code key + tag
287   \hpack to \wd\scratchbox{\hss\box\nextbox\hss}%
288   \hskip-\wd\scratchbox
289   \box\scratchbox
290   \endgroup}
291
292% \startMPextensions
293%     vardef math_ornament_hat(expr w,h,d,o,l) =
294%         image ( path p ; p :=
295%             (w/2,h + 10l) --
296%             (o + w,h + o) --
297%             (w/2,h + 7l) --
298%             (-o,h + o) --
299%             cycle ;
300%             fill p ;
301%             setbounds currentpicture to (-o,0) -- (w+o,0) -- (w+o,h+2o) -- (-o,h+2o) -- cycle ;
302%         )
303%     enddef ;
304% \stopMPextensions
305%
306% \startuniqueMPgraphic{math:ornament:hat}
307%     draw
308%         math_ornament_hat(
309%             OverlayWidth,
310%             OverlayHeight,
311%             OverlayDepth,
312%             OverlayOffset,
313%             OverlayLineWidth
314%         )
315%     withpen
316%         pencircle
317%             xscaled (2OverlayLineWidth)
318%             yscaled (3OverlayLineWidth/4)
319%             rotated 30
320%     withcolor
321%         OverlayLineColor ;
322%         draw boundingbox currentpicture;
323% \stopuniqueMPgraphic
324%
325% \definemathornament [mathhat] [mp=math:ornament:hat]
326%
327% \dorecurse{8}{$\mathhat{\blackrule[width=#1ex,color=gray]}$ }
328
329\protect \endinput
330