m-oldnum.mkiv /size: 10 Kb    last modification: 2021-10-28 13:51
1%D \module
2%D   [       file=m-oldnum, % was: supp-num
3%D        version=1998.05.15,
4%D          title=\CONTEXT\ Support Macros,
5%D       subtitle=Numbers,
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\ifcase\contextlmtxmode\else\endinput\fi
15
16% See end for transition to mkiv.
17
18\writestatus{loading}{ConTeXt Support Macros / Numbers}
19
20\unprotect
21
22%D \macros
23%D   {digits, setdigitmode, setdigitsign}
24%D
25%D Depending on the digit mode the command \type {\digits}
26%D normalizes number patterns depending on the language set.
27%D
28%D \starttyping
29%D This will never be a \digits{1.000.000} seller.
30%D \stoptyping
31%D
32%D or
33%D
34%D \starttyping
35%D I will never grow longer than \digits 1.86 \Meter.
36%D \stoptyping
37%D
38%D The different modes are shown in:
39%D
40%D \startbuffer
41%D \setdigitmode 1 \digits 12.345,90 \digits 12.345.000 \digits 1,23
42%D \setdigitmode 2 \digits 12.345,90 \digits 12.345.000 \digits 1,23
43%D \setdigitmode 3 \digits 12.345,90 \digits 12.345.000 \digits 1,23
44%D \setdigitmode 4 \digits 12.345,90 \digits 12.345.000 \digits 1,23
45%D \setdigitmode 5 \digits 12.345,90 \digits 12.345.000 \digits 1,23
46%D \setdigitmode 6 \digits 12.345,90 \digits 12.345.000 \digits 1,23
47%D \stopbuffer
48%D
49%D \typebuffer
50%
51%  This is typset as:
52%
53%  \startlines
54%  \getbuffer
55%  \stoplines
56%D
57%D The sign can be typeset as is or within the space of a
58%D digit.
59%D
60%D \startbuffer
61%D \setdigitsign 0 \digits +12.345,90
62%D \setdigitsign 1 \digits +12.345,90
63%D \setdigitsign 2 \digits +12.345,90
64%D \setdigitsign 3 \digits +12.345,90
65%D \stopbuffer
66%D
67%D \typebuffer
68%D
69%  This is typset as:
70%
71%  \startlines
72%  \getbuffer
73%  \stoplines
74
75\chardef\digitoutputmode=1 % 0..6
76\chardef\digitsignmode  =0 % 0..3
77
78\unexpanded\def\setdigitmode{\chardef\digitoutputmode}
79\unexpanded\def\setdigitsign{\chardef\digitsignmode}
80
81%D The digit modes are:
82%D
83%D \startitemize[packed]
84%D \item periods      \& comma
85%D \item commas       \& period
86%D \item thinmuskips  \& comma
87%D \item thinmuskips  \& period
88%D \item thickmuskips \& comma
89%D \item thickmuskips \& period
90%D \stopitemize
91
92\let\collecteddigits \empty \chardef\digitinputmode =1
93\let\saveddigits     \empty \chardef\skipdigit      =0
94\let\savedpowerdigits\empty \chardef\powerdigits    =0
95
96%D The first stage of the \type {\digit} macro takes care of
97%D the grouped call, the other branch handles the fuzzy
98%D delimited calls.
99
100\ifdefined\mbox \else \let\mbox\hbox \fi
101
102\unexpanded\def\digits
103  {\bgroup
104   \let~@%
105   \doifelsenextbgroup\dodigits{\doifelsenextchar\normalmathshift\domathdigits\grabdigit}}
106
107\def\dodigits#1%
108  {\grabdigit#1\relax}
109
110\def\domathdigits$#1$%
111  {\mbox{\grabdigit#1\relax}} % adding $ $ goes wrong in tabulate
112
113\def\grabdigit
114  {\futurelet\nexttoken\scandigit}
115
116%D Watch the test for \type {\nextobeyedline}, because the
117%D endofline token can be \type {\def'd}, not \type {\let}'d,
118%D we need to do an indirect test (see \type {verb-ini.tex})
119%D for details. (This probably needs an update.)
120
121\ifx\normalmathshift\undefined \let\normalmathshift=$ \fi
122
123\unexpanded\def\scandigit
124  {\ifx\nexttoken\blankspace
125     \let\next\handledigits
126   \else\ifx\nexttoken\nextobeyedline % the indirect one
127     \let\next\handledigits
128   \else\ifx\nexttoken\bgroup
129     \let\next\handledigits
130   \else\ifx\nexttoken\egroup
131     \let\next\handledigits
132   \else\ifx\nexttoken\normalmathshift
133     \let\next\handledigits
134   \else
135     \let\next\collectdigit
136   \fi\fi\fi\fi\fi
137   \next}
138
139%D We store the power||of||ten (to be signaled by \type {^},
140%D \type {e} or~\type {E}) in a seperate macro so that we can
141%D typeset it in superscript. The space placeholders are
142%D replaced by a \type {@}.
143
144\unexpanded\def\savedigit#1#2%
145  {\edef#1{#1\saveddigits#2}\let\saveddigits\empty}
146
147\unexpanded\def\collectdigit#1%
148  {\ifx#1~%
149     \savedigit\collecteddigits @%
150   \else\if#1_% tricky as can be several catcodes ... will become lua code anyway
151     \savedigit\collecteddigits @%
152   \else\if\noexpand#1\relax
153     \let\grabdigit\handledigits
154   \else\ifcase\powerdigits
155     \if#1E%
156       \chardef\powerdigits\plusone
157     \else\if#1e%
158       \chardef\powerdigits\plusone
159     \else\if#1^%
160       \chardef\powerdigits\plusone
161     \else
162       \savedigit\collecteddigits#1%
163       %\doifelsenumber{#1}
164       %  {\savedigit\collecteddigits#1}
165       %  {\def\saveddigits{#1}}%
166     \fi\fi\fi
167   \else
168     \savedigit\savedpowerdigits#1%
169     %\doifelsenumber{#1}
170     %  {\savedigit\savedpowerdigits#1}
171     %  {\def\saveddigits{#1}}%
172   \fi\fi\fi\fi
173   \grabdigit}
174
175\let\handlemathdigits\firstofoneargument
176\let\handletextdigits\mathematics
177
178\unexpanded\def\handledigits
179  {%\ifcase\powerdigits
180   %  \edef\collecteddigits{\collecteddigits\saveddigits}%
181   %\else
182   %  \edef\savedpowerdigits{\savedpowerdigits\saveddigits}%
183   %\fi
184   \ifmmode
185     \handlemathdigits{\dohandledigits}%
186   \else
187     \dontleavehmode\hbox{\handletextdigits{\dohandledigits}}%
188   \fi
189   \egroup}
190
191%D Although we could do with one pass, a second pass for
192%D handling the stored sequence is more readable.
193
194\def\dohandledigits
195  {\mathcode`\,="002C \mathcode`\.="002E % pretty hard coded
196   \expandafter\handletokens\collecteddigits\with\scandigits
197   \ifcase\powerdigits\else\digitpowerseparator^{\savedpowerdigits}\fi}
198
199\chardef\mathaxisfontid\zerocount
200
201\def\doscandigit#1%
202  {\ifcase\skipdigit\expandafter\hbox\else\expandafter\hphantom\fi\bgroup
203     \mathematics % brr, needed because of stored punctuation
204       {\ifnum\digitinputmode=#1\relax
205        \ifcase\digitoutputmode
206        \or .%
207        \or ,%
208        \or \mskip\thinmuskip
209        \or \mskip\thinmuskip
210        \or \mskip\thickmuskip
211        \or \mskip\thickmuskip
212        \fi
213      \else
214        \ifodd\digitoutputmode,\else.\fi
215      \fi}%
216   \egroup}
217
218%D The signs can be made smaller and sqeezed into the width
219%D of a digit. Watch the \type {\mathaxisheight} trickery (this
220%D font related register stored the math axis).
221
222% 0,=
223% 0,==  second = results in delta(00,=)
224% 0,-   is invalid, should be =
225% 0,--  is invalid, should be ==
226
227\unexpanded\def\digitzeroamount
228  {\digitsgn\zeroamount
229   \def\digitzeroamount
230     {\hphantom
231        {00\setbox\scratchbox\hbox{$\zeroamount$}%
232         \hskip-\wd\scratchbox}%
233      \let\digitzeroamount\empty}}
234
235\unexpanded\def\scandigits#1%
236  {\if#1.\digitsep1\else
237   \if#1,\digitsep2\else
238   \if#1@\digitnop \else
239   \if#1_\digitnop \else
240   \if#1/\digitsgn{\hphantom{+}}\chardef\skipdigit0\else
241   \if#1-\ifcase\skipdigit\digitsgn-\else
242           \box\digitsepbox\digitzeroamount \fi\chardef\skipdigit0\else
243   \if#1+\digitsgn+\chardef\skipdigit0\else
244   \if#1=\box\digitsepbox\digitzeroamount \chardef\skipdigit0\else
245   \if#1s\digitsgn{\hphantom{\positive}}\chardef\skipdigit0\else
246   \if#1p\digitsgn\positive\chardef\skipdigit0\else
247   \if#1m\digitsgn\negative\chardef\skipdigit0\else
248   \if#1n\digitsgn\negative\chardef\skipdigit0\else
249         \box\digitsepbox #1\chardef\skipdigit0\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi\fi}
250
251\newbox\digitsepbox \chardef\autodigitmode=1
252
253\unexpanded\def\digitsep#1%
254  {\ifcase\autodigitmode
255     \doscandigit#1%
256   \else
257     \setbox\digitsepbox\hbox{\doscandigit#1}%
258   \fi
259   \chardef\skipdigit0\relax}
260
261% strange, does not work
262%
263% \def\digitnop
264%   {\hphantom{\box\digitsepbox}%
265%    \hphantom{0}\chardef\skipdigit1\relax}
266%
267% while this works
268
269\unexpanded\def\digitnop
270  {\hbox{\hphantom{\box\digitsepbox}}%
271   \hphantom{0}\chardef\skipdigit1\relax}
272
273% but this doesn't
274%
275% \def\digitnop
276%   {\hphantom{\box\digitsepbox0}%
277%    \chardef\skipdigit1\relax}
278
279\unexpanded\def\digitsgn#1%
280  {\ifcase\digitsignmode#1\else
281     \hbox
282       {\setbox\scratchbox\hbox{0}%
283        \scratchdimen\mathaxisheight\textfont\mathaxisfontid
284        \def\digitsgn##1##2%
285          {\advance\scratchdimen-\mathaxisheight##1\mathaxisfontid
286           \raise\scratchdimen
287           \hbox to \wd\scratchbox{\hss$##2#1$\hss}}%
288        \ifcase\digitsignmode\or
289          \digitsgn\textfont        \textstyle        \or
290          \digitsgn\scriptfont      \scriptstyle      \or
291          \digitsgn\scriptscriptfont\scriptscriptstyle\fi}%
292   \fi}
293
294\ifx\undefined\zeroamount \def\zeroamount{-} \fi
295\ifx\undefined\positive   \def\positive  {+} \fi
296\ifx\undefined\negative   \def\negative  {-} \fi
297
298%D The digit parser handles a bunch of special characters as
299%D well as different formats. We strongly suggest you to use
300%D the grouped call.
301%D
302%D \starttabulate[|l|l|l|]
303%D \NC \type{.} \NC , . \NC comma or period \NC \NR
304%D \NC \type{,} \NC , . \NC comma or period \NC \NR
305%D \NC \type{@} \NC \NC invisible space \NC \NR
306%D \NC \type{_} \NC \NC invisible space \NC \NR
307%D \NC \type{/} \NC \NC invisible sign \NC \NR
308%D \NC \type{-} \NC $-$ \NC minus sign \NC \NR
309%D \NC \type{+} \NC $+$ \NC plus sign \NC \NR
310%D \NC \type{s} \NC \NC invisible high sign \NC \NR
311%D \NC \type{p} \NC $\positive$ \NC high plus sign \NC \NR
312%D \NC \type{m} \NC $\negative$ \NC high minus sign \NC \NR
313%D \NC \type{n} \NC $\negative$ \NC high minus (negative) sign \NC \NR
314%D \NC \type{=} \NC $\zeroamount$ \NC zero padding \NC \NR
315%D \stoptabulate
316%D
317%D These triggers are used in the following examples.
318%D
319%D \startbuffer
320%D \digits 12
321%D \digits{~~~.~~~.~~~.68.712,34}
322%D \digits ~~~.~~~.~~~.68.712,34
323%D \digits ___.___.111.68.712,34
324%D \digits 111.111.111.68.712,34
325%D \digits 12.345,90
326%D \digits 12.345.000
327%D \digits 12,34
328%D \digits{392.857.230.68.712,34}
329%D {\digits1234}
330%D \digits{1234}
331%D \digits 1234\relax
332%D $\digits 123.222,00$
333%D \digits 123.222,00
334%D \digits 123.222,==
335%D \digits 123.222,00^10
336%D \digits 123.222,00e10
337%D \digits /123.222,00e-12
338%D \digits -123.222,00e-12
339%D \digits +123.222,00e-12
340%D \digits n123.222,00e-12
341%D \digits s123.222,00e-12
342%D \digits p123.222,00e-12
343%D \stopbuffer
344%D
345%D \typebuffer
346%
347%  \startlines
348%  \getbuffer
349%  \stoplines
350
351%D \macros
352%D   {Digits}
353%D
354%D We also permit:
355
356\let\Digits\digits
357
358%D These macros are complicated by the fact that we also
359%D have to support cases like:
360%D
361%D \starttyping
362%D {\digits1234}
363%D \digits{1234}
364%D \digits 1234\whatever
365%D $\digits 123.222,00$
366%D \digits 123.222,00.
367%D \stoptyping
368%D
369%D The latter case shows us that trailing non digits are to
370%D be passed untreated.
371%D
372%D Another interesting case is:
373%D
374%D \starttyping
375%D \digits 123.222,00^10
376%D \stoptyping
377%D
378%D The separator is defined as:
379
380% \def\digitpowerseparator%
381%   {\cdot10} % {\times10}
382
383\def\digitpowerseparator
384  {\ifx\collecteddigits\empty\else\cdot\fi10}
385
386%D \macros
387%D   {digittemplate}
388%D
389%D Users can specify the way they enter those digits by saying
390%D something like:
391%D
392%D \starttyping
393%D \digittemplate 12.000.000,00 % \digittemplate .,
394%D \stoptyping
395
396\unexpanded\def\digittemplate #1 %
397  {\chardef\digitinputmode\zerocount
398   \handletokens#1\with\scandigittemplate}
399
400\unexpanded\def\scandigittemplate#1%
401  {\if     #1.\ifcase\digitinputmode\chardef\digitinputmode\plusone \fi% period
402   \else\if#1,\ifcase\digitinputmode\chardef\digitinputmode\plustwo \fi% comma
403   \fi\fi}
404
405\protect \endinput
406