%D \module %D [ file=phys-dim, %D version=2011-06-13, % was digits and units 1997.03.19, %D title=\CONTEXT\ Physics, %D subtitle=Digits and Units, %D author={Hans Hagen}, %D date=\currentdate, %D copyright={PRAGMA ADE \& \CONTEXT\ Development Team}] %C %C This module is part of the \CONTEXT\ macro||package and is %C therefore copyrighted by \PRAGMA. See mreadme.pdf for %C details. \registerctxluafile{phys-dim}{} \unprotect %D \macros %D {digits, setdigitmode, setdigitsign} %D %D This is an update of the \MKII\ digits mechanism. Beware, %D space delimited mode is now resticted! %D %D Depending on the digit mode the command \type {\digits} %D normalizes number patterns depending on the language set. %D %D \starttyping %D This will never be a \digits{1.000.000} seller. %D \stoptyping %D %D We still support the space delimited case but this is only for special %D purposes. When used in the text, you'd better use the argument variant. %D %D \startbuffer %D 1 \setdigitmode {1} \setdigitorder{0} \digits {12.345,90} %D 2 \setdigitmode {2} \setdigitorder{0} \digits {12.345,90} %D 3 \setdigitmode {3} \setdigitorder{0} \digits {12.345,90} %D 4 \setdigitmode {4} \setdigitorder{0} \digits {12.345,90} %D 5 \setdigitmode {5} \setdigitorder{0} \digits {12.345,90} %D 6 \setdigitmode {6} \setdigitorder{0} \digits {12.345,90} %D 1 \setdigitmode {1} \setdigitorder{1} \digits {12.345,90} %D 2 \setdigitmode {2} \setdigitorder{1} \digits {12.345,90} %D 3 \setdigitmode {3} \setdigitorder{1} \digits {12.345,90} %D 4 \setdigitmode {4} \setdigitorder{1} \digits {12.345,90} %D 5 \setdigitmode {5} \setdigitorder{1} \digits {12.345,90} %D 6 \setdigitmode {6} \setdigitorder{1} \digits {12.345,90} %D \stopbuffer %D %D \typebuffer %D %D This is typeset as: %D %D \startlines \getbuffer \stoplines %D %D The sign can be typeset as is or within the space of a %D digit. %D %D \startbuffer %D \setdigitsign 0 \digits {+12.345,90} %D \setdigitsign 1 \digits {+12.345,90} %D \stopbuffer %D %D \typebuffer %D %D This is typset as: %D %D \startlines %D \getbuffer %D \stoplines %D %D The digit modes are: %D %D \startitemize[n,packed] %D \item periods/comma %D \item commas/period %D \item thinmuskips/comma %D \item thinmuskips/period %D \item thickmuskips/comma %D \item thickmuskips/period %D \stopitemize %D %D The digit parser handles a bunch of special characters as %D well as different formats. We strongly suggest you to use %D the grouped call. %D %D \starttabulate[|l|l|l|] %D \NC \type{.} \NC , . \NC comma or period \NC \NR %D \NC \type{,} \NC , . \NC comma or period \NC \NR %D \NC \type{@} \NC \NC invisible space \NC \NR %D \NC \type{_} \NC \NC invisible space \NC \NR %D \NC \type{/} \NC \NC invisible sign \NC \NR %D \NC \type{-} \NC $-$ \NC minus sign \NC \NR %D \NC \type{+} \NC $+$ \NC plus sign \NC \NR %D \NC \type{s} \NC \NC invisible high sign \NC \NR %D \NC \type{p} \NC $\positive$ \NC high plus sign \NC \NR %D \NC \type{m} \NC $\negative$ \NC high minus sign \NC \NR %D \NC \type{n} \NC $\negative$ \NC high minus (negative) sign \NC \NR %D \NC \type{=} \NC $\zeroamount$ \NC zero padding \NC \NR %D \stoptabulate %D %D These triggers are used in the following examples. %D %D \startbuffer %D \digits{12} %D \digits{~~~.~~~.~~~.68.712,34} %D \digits{___.___.111.68.712,34} %D \digits{111.111.111.68.712,34} %D \digits{12.345,90} %D \digits{12.345.000} %D \digits{12,34} %D \digits{392.857.230.68.712,34} %D \digits{1234} %D \digits{123.222,00} %D \digits{123.222,==} %D \digits{123.222,00^10} %D \digits{123.222,00e10} %D \digits{/123.222,00e-12} %D \digits{-123.222,00e-12} %D \digits{+123.222,00e-12} %D \digits{n123.222,00e-12} %D \digits{s123.222,00e-12} %D \digits{p123.222,00e-12} %D \stopbuffer %D %D \typebuffer %D %D \startlines %D \getbuffer %D \stoplines \newconstant\c_digits_order \newconstant\c_digits_method \newconstant\c_digits_sign % we has sized (text script scriptscript) \def\setdigitmethod#1{\c_digits_method #1\relax} \def\setdigitsign #1{\c_digits_sign #1\relax} \def\setdigitorder #1{\c_digits_order #1\relax} \let\setdigitmode\setdigitmethod % compatibility \def\digits_normalized % we could calculate once and remember {\ifcase\c_digits_sign \expandafter\secondoftwoarguments \else\ifmmode \expandafter\expandafter\expandafter\digits_normalized_math \else \expandafter\expandafter\expandafter\digits_normalized_text \fi\fi} \def\digits_normalized_math#1#2% {\setbox\scratchbox\hbox{$\Ustack{#1}$}% \hbox to \wd\scratchbox{\hss{$\Ustack{#2}$}\hss}} \def\digits_normalized_text#1#2% {\setbox\scratchbox\hbox{#1}% \hbox to \wd\scratchbox{\hss#2\hss}} \def\digits_raised {\ifmmode \expandafter\normalsuperscript \else \expandafter\high \fi} \def\digitszeropadding {\zeroamount} \def\digitsnegative {\digits_normalized{0}{\digits_raised{\textminus}}} \def\digitspositive {\digits_normalized{0}{\digits_raised{\textplus}}} \def\digitsnegative {\digits_normalized{0}{\mathematics{\negative}}} \def\digitspositive {\digits_normalized{0}{\mathematics{\positive}}} \def\digitsminus {\digits_normalized{0}{\mathematics{-}}} \def\digitsplus {\digits_normalized{0}{\mathematics{+}}} \def\digitsspace {\hphantom{0}} \def\digitsseparatorspace{\hphantom{.}} \def\digitssignspace {\hphantom{\digitsminus}} \def\digitshighspace {\hphantom{\digitspositive}} \def\digitspower {\digits_raised} \def\digitspowerplus #1{\digits_raised{\digitsplus#1}} \def\digitspowerminus #1{\digits_raised{\digitsminus#1}} \def\digitsdigit #1{#1} \def\normaldigitscommasymbol {,} \def\normaldigitsperiodsymbol {.} \let\normaldigitsseparatorspace\digitsseparatorspace \letvalue{digit_c_0}\normaldigitscommasymbol \letvalue{digit_p_0}\normaldigitsperiodsymbol \letvalue{digit_s_0}\normaldigitsseparatorspace \letvalue{digit_c_1}\normaldigitsperiodsymbol \letvalue{digit_p_1}\normaldigitscommasymbol \letvalue{digit_s_1}\normaldigitsseparatorspace \letvalue{digit_c_2}\normaldigitscommasymbol \letvalue{digit_p_2}\normaldigitsperiodsymbol \letvalue{digit_s_2}\normaldigitsseparatorspace \letvalue{digit_c_3}\thinspace \letvalue{digit_p_3}\normaldigitscommasymbol \letvalue{digit_s_3}\thinspace \letvalue{digit_c_4}\thinspace \letvalue{digit_p_4}\normaldigitsperiodsymbol \letvalue{digit_s_4}\thinspace \letvalue{digit_c_5}\thickspace \letvalue{digit_p_5}\normaldigitscommasymbol \letvalue{digit_s_5}\thickspace \letvalue{digit_c_6}\thickspace \letvalue{digit_p_6}\normaldigitsperiodsymbol \letvalue{digit_s_6}\thickspace \def\digitscommasymbol {\csname digit_c_\number\c_digits_method\endcsname} \def\digitsperiodsymbol {\csname digit_p_\number\c_digits_method\endcsname} \def\digitsseparatorspace {\csname digit_s_\number\c_digits_method\endcsname} \def\digitsfinalcomma {\digitscommasymbol } % more for tracing \def\digitsfinalperiod {\digitsperiodsymbol} % more for tracing \def\digitsintermediatecomma {\digitscommasymbol } % more for tracing \def\digitsintermediateperiod {\digitsperiodsymbol} % more for tracing %D The user macro: \unexpanded\def\digits_indeed#1% {\dontleavehmode \begingroup \ctxcommand{digits(\!!bs\detokenize{#1}\!!es,"\ifcase\c_digits_order \v!normal\else\v!reverse\fi")}% \endgroup \settrue\c_units_dospace} \unexpanded\def\digits {\doifnextbgroupelse\digits_argument\digits_spaced} \def\digits_argument#1% {\digits_indeed{#1}} \def\digits_spaced#1 % space delimited {\digits_indeed{#1}} %D \macros %D {unit} %D %D We have been using the units module (and its predecessor) for over a decade %D now but when we moved on to \LUATEX\ a variant was prototyped that permits a %D less texie coding. I finally picked up that thread and cleaned up the code a %D bit so users can now play with it. (The main reason was that I wanted to %D test exporting.) %D %D \startbuffer %D 01: $10\unit{km/h}$ %D 02: $\unit{10 km/h}$ %D 03: \unit{km/h} %D 04: \unit{10 km/h} %D 05: \unit{10 km/h} %D 06: \unit{~1 km/h} %D 07: 10\unit{km/h} %D 08: 10 \unit{km/h} %D 09: $10 \unit{km/h}$ %D 10: 10 \unit{KiloMeter/Hour} %D 11: 10 \unit{kilometer/hour} %D 12: 10 \unit{km/h} %D 13: 10 \unit{kilometer per hour} %D 14: 10 \unit{km / h} %D 15: 10 \unit{ km / h } %D 16: 10 \unit{km/ms2} %D 17: 10 \unit{meter per second} %D 18: 10 \unit{cubic meter} %D 19: 10 \unit{cubic meter per second} %D 21: 10 \unit{cubic meter / second} %D 22: $10 \unit{cubic meter / second}$ %D 23: 30 \unit{kilo pascal } %D 24: 30 \unit{kilo pascal square meter / second} %D 25: 30 \unit{kilo pascal square meter / kelvin second} %D 26: \unit{30 kilo pascal square meter / kelvin second} %D 27: $30 \unit{kilo pascal square meter / kelvin second }$ %D 28: 30 \unit{crap} %D 29: 30 \unit{AC} %D 30: $\frac{10 \unit{m/s}}{20 \unit{m/s}} $ %D 31: {\ss 30 \unit{kilo pascal square meter / second kelvin}} %D 32: \unit{123.22^-3 km/s} %D 33: \unit{123.22e-3 km/s} %D \stopbuffer %D %D \typebuffer %D %D Result: \startlines \getbuffer \stoplines %D %D Depending on needs we can add more tweaks (also depends on to what %D extent we need to be compatible with \MKII. %D %D Formatting is supported too: %D %D \startbuffer %D \starttabulate[|l|l|l|] %D \HL %D \NC \unit{10 kilo gram} \NC \digits{10} \NC \unit{10} \NC \NR %D \NC \unit{1 kilogram} \NC \digits{1} \NC \unit{1} \NC \NR %D \NC \unit{0.1 kilogram} \NC \digits{0.1} \NC \unit{0.1} \NC \NR %D \NC \unit{1.1 kilogram} \NC \digits{1.1} \NC \unit{1.1} \NC \NR %D \NC \unit{11 kilogram} \NC \digits{11} \NC \unit{11} \NC \NR %D \HL %D \NC \unit{00,000.10 kilogram} \NC \digits{00,000.10} \NC \unit{00,000.10} \NC \NR %D \NC \unit{@@,@@0.10 kilogram} \NC \digits{@@,@@0.10} \NC \unit{@@,@@0.10} \NC \NR %D \NC \unit{__,___.10 kilogram} \NC \digits{__,___.10} \NC \unit{__,___.10} \NC \NR %D \NC \unit{__,__0:10 kilogram} \NC \digits{__,__0:10} \NC \unit{__,__0:10} \NC \NR %D \NC \unit{__,___:10 kilogram} \NC \digits{__,___:10} \NC \unit{__,___:10} \NC \NR %D \HL %D \stoptabulate %D \stopbuffer %D %D \typebuffer \getbuffer %D %D Punctuation can be configures usiing \type {method}: %D %D \startbuffer %D \starttabulate[|l|l|l|] %D \HL %D \NC \NC \setupunits[method=0]\unit{00,000.10 kilogram} \NC \setupunits[method=0]\unit{@@,@@0.10 kilogram} \NC \NR %D \NC 1 \NC \setupunits[method=1]\unit{00,000.10 kilogram} \NC \setupunits[method=1]\unit{@@,@@0.10 kilogram} \NC \NR %D \NC 2 \NC \setupunits[method=2]\unit{00,000.10 kilogram} \NC \setupunits[method=2]\unit{@@,@@0.10 kilogram} \NC \NR %D \NC 3 \NC \setupunits[method=3]\unit{00,000.10 kilogram} \NC \setupunits[method=3]\unit{@@,@@0.10 kilogram} \NC \NR %D \NC 4 \NC \setupunits[method=4]\unit{00,000.10 kilogram} \NC \setupunits[method=4]\unit{@@,@@0.10 kilogram} \NC \NR %D \NC 5 \NC \setupunits[method=5]\unit{00,000.10 kilogram} \NC \setupunits[method=5]\unit{@@,@@0.10 kilogram} \NC \NR %D \NC 6 \NC \setupunits[method=6]\unit{00,000.10 kilogram} \NC \setupunits[method=6]\unit{@@,@@0.10 kilogram} \NC \NR %D \HL %D \stoptabulate %D \stopbuffer %D %D \typebuffer \getbuffer % only a space when a number is part of the unit \installcommandhandler \??un {units} \??un \setupunits [\c!alternative=, % done: text \c!separator=\v!normal, % done: cdot|big|medium|space \c!label=, % done: (no interface yet) \c!order=\v!normal, % ,. (reverse: .,) \c!method=0, %\c!grid=\v!yes, % (maybe) %\c!style=..., % done %\c!color=..., % done %\c!space=..., % (maybe) small medium big ] \newconstant \c_units_mode % 0=text 1=math 2=textinmath 3=mathintext \newconstant \c_units_state % 0=start 1=suffix 2=operator 3=unit 4=prefix 5=number \newconditional\c_units_quantity \newconditional\c_units_number \newconditional\c_units_dospace % [\unit {micro ohm}]\par % no space before unit % [10\unit {micro ohm}]\par % no space before unit % [10 \unit{micro ohm}]\par % space before unit % [ \unit {micro ohm}]\par % space before unit % [\unit{10 micro ohm}]\par % space before unit \def\unitssmallspace {\thinspace} \def\unitsmediumspace{\medspace} \def\unitsbigspace {\thickspace} \def\unitsbackspace {\negthinspace} \def\installunitsseparator#1#2% {\setvalue{\??un::#1}{#2}} \unexpanded\def\dounitsseparator {\edef\currentunitsseparator{\unitsparameter\c!separator}% \csname\??un::% \ifcsname\??un::\currentunitsseparator\endcsname\currentunitsseparator\else\v!normal\fi \endcsname} \installunitsseparator\v!normal {\cdot} \installunitsseparator\v!big {\unitsbigspace} \installunitsseparator\v!medium {\unitsmediumspace} \installunitsseparator\v!small {\unitssmallspace} \installunitsseparator\v!none {} \newtoks \everyunits % we keep the old \units command so we need a longer one \appendtoks \setuevalue\currentunits{\units_direct{\currentunits}} \to \everydefineunits \unexpanded\def\units_direct#1% {\begingroup \ifdim\lastskip>\zeropoint \settrue\c_units_dospace \removelastskip \fi \c_digits_method\unitsparameter\c!method\relax \ifmmode\else\dontleavehmode\fi \edef\currentunits{#1}% \the\everyunits %\removeunwantedspaces % now ok yet \dosetunitsattributes\c!style\c!color \edef\currentunitsalternative{\unitsparameter\c!alternative}% \ifmmode \ifx\currentunitsalternative\v!text \expandafter\expandafter\expandafter\units_direct_text_in_math \else \expandafter\expandafter\expandafter\units_direct_math \fi \else \ifx\currentunitsalternative\v!mathematics \expandafter\expandafter\expandafter\units_direct_math_in_text \else \expandafter\expandafter\expandafter\units_direct_text \fi \fi} \unexpanded\def\units_direct_text_in_math#1% {\mathtext{% \c_units_mode\plustwo \units_indeed{#1}% \units_finish }% \endgroup} \unexpanded\def\units_direct_math#1% {\c_units_mode\plusone \rm\tf \mathtf \units_indeed{#1}% \units_finish \endgroup} \unexpanded\def\units_direct_text#1% {\units_indeed{#1}% \units_finish \endgroup} \unexpanded\def\units_direct_math_in_text#1% {\removeunwantedspaces % brr \startimath \c_units_mode\plusthree \rm\tf \mathtf \units_indeed{#1}% \units_finish \stopimath \endgroup} \unexpanded\def\units_direct_nested#1#2% {\units_indeed{#2}} \appendtoks \let\units_direct\units_direct_nested \to \everyunits \unexpanded\def\units_indeed#1{\ctxcommand{unit(\!!bs\detokenize{#1}\!!es,"\unitsparameter\c!label","\unitsparameter\c!order")}} \unexpanded\def\unitsPUS#1#2#3{\units_next#1#2\unitsraise{#3}\c_units_state\plusone} % suffix \unexpanded\def\unitsPU #1#2{\units_next#1#2\c_units_state \plusthree} % unit \unexpanded\def\unitsPS #1#2{\units_next#1\unitsraise{#2}\c_units_state \plusone} % suffix \unexpanded\def\unitsUS #1#2{\units_next#1\unitsraise{#2}\c_units_state \plusone} % suffix \unexpanded\def\unitsP #1{\units_next#1\c_units_state \plusfour} % prefix \unexpanded\def\unitsU #1{\units_next#1\c_units_state \plusthree} % unit \unexpanded\def\unitsS #1{\units_start{}\unitsraise{#1}\c_units_state \plusone} % suffix \unexpanded\def\unitsO #1{\units_start#1\c_units_state \plustwo} % operator \unexpanded\def\unitsN #1{\units_start#1\c_units_state \plusfive} % number \setelementnature[unit] [mixed] \setelementnature[quantity][mixed] \let\units_finish\relax \unexpanded\def\unitsNstart {\ifmmode \else \settrue\c_units_quantity \dostarttagged\t!quantity\empty \settrue\c_units_number \dostarttagged\t!number\empty \fi} \unexpanded\def\unitsNstop {\ifconditional\c_units_number \setfalse\c_units_number \dostoptagged \fi \c_units_state\plusfive} \unexpanded\def\unitsN#1% {\unitsNstart#1\unitsNstop} \def\units_start {\ifmmode \dostarttagged\t!mathaction\t!unit \bgroup % make an mrow \else \dostarttagged\t!unit\empty \fi \let\units_finish\units_stop \let\units_start\relax} \def\units_stop {\ifconditional\c_units_number \setfalse\c_units_number \dostoptagged \fi \ifconditional\c_units_quantity \setfalse\c_units_quantity \dostoptagged \fi \dostoptagged \ifmmode \egroup \fi} \def\unitsraise {\ifcase\c_units_mode \expandafter\high \or \expandafter\normalsuperscript \or \expandafter\high \or \expandafter\normalsuperscript \fi} \def\unitslower {\ifcase\c_units_mode \expandafter\low \or \expandafter\normalsubscript \or \expandafter\low \or \expandafter\normalsubscript \fi} \unexpanded\def\units_next {\ifcase\c_units_state % start \ifconditional\c_units_dospace % \ifdim\lastskip=\zeropoint \unitsbigspace % \else % % too tricky ... we could remove and add % \fi \fi \or % suffix {\dounitsseparator}% \or % operator \or % unit {\dounitsseparator}% \or % prefix \or % number \unitsbigspace \fi \setfalse\c_units_dospace \units_start} \unexpanded\def\unitsTIMES {\ifnum\c_units_state=\plusone % suffix \else \unitssmallspace \fi \cdot} % or \times \unexpanded\def\unitsOUTOF {\ifnum\c_units_state=\plusone % suffix \else \unitssmallspace \fi :} \unexpanded\def\unitsSOLIDUS {\ifnum\c_units_state=\plusone % suffix \unitsbackspace \fi {/}% }%\unitsbackspace} %D Now we define the standard units command: \defineunits [unit] %D Example: %D %D \startbuffer[definitions] %D \startluacode %D languages.data.labels.prefixes.whatever = { %D Kilo = "olik" %D } %D %D languages.data.labels.units.whatever = { %D Meter = "retem", %D Second = "dnoces", %D } %D %D languages.data.labels.operators.whatever = { %D Solidus = " rep " %D } %D \stopluacode %D \stopbuffer %D %D \startbuffer[sample] %D \startlines %D \lunit{10 km/s} %D \lunit{10 Kilo Meter/s} %D \lunit{10 kilo Meter/s} %D \lunit{10 Kilo m/s} %D \lunit{10 k Meter/s} %D \stoplines %D \stopbuffer %D %D \typebuffer[definitions] \getbuffer[definitions] %D %D \startbuffer %D \typebuffer[sample] %D %D \defineunits[lunit] \getbuffer[sample] %D \defineunits[lunit][label=test] \getbuffer[sample] %D \defineunits[lunit][label=whatever] \getbuffer[sample] %D \stopbuffer %D %D \typebuffer \getbuffer \protect \endinput