ntg-context - mailing list for ConTeXt users
 help / color / mirror / Atom feed
From: Gavin via ntg-context <ntg-context@ntg.nl>
To: mailing list for ConTeXt users <ntg-context@ntg.nl>
Cc: Gavin <gavinpublic@comcast.net>
Subject: Re: Spacing in \unit - SOLVED
Date: Fri, 21 Oct 2022 12:20:42 -0600	[thread overview]
Message-ID: <565BAFA6-6E9C-4B71-9349-C0F2D91317F7@comcast.net> (raw)
In-Reply-To: <cb7d526f-f0b7-fe59-2856-5f1f712333fa@freedom.nl>

[-- Attachment #1: Type: text/plain, Size: 4369 bytes --]

Hi Hans,

> I'll look into it (with Mikael as some relates to math) once you're done playing and provide suggestions and tests.

I’m done playing. Below are tests and suggestions. Sorry it has taken so long for me to put this together.


Tests
I attached two test files. The first, units-spacing.tex, is for testing spacing for \unit used in text, inline math, and display math. The second, units-linebreaks.tex, tests line breaks when \unit. is used in text or in inline math. Line breaks were not my primary interest, but Max and Alan were quite interested. My proposed fixes for spacing also fix their concerns about line breaks.I tried to make these tests match the style of the Test Suite. They could be included there if they are useful.


Suggestions
I attached my my modified phys-dim.mkxl. All of my changes are commented and signed with -GP to make them easy to find. Below are comments on the five issues I addressed (not including line breaks). The first four of these are fixes.I don’t think any of these fixes are controversial or require new options. The fifth, regarding the space around the \times in scientific notation, might be an appropriate option, rather than a universal fix.


1. The \cdot in units should not have space around it.
These lines produce the \cdot between units, one is for the default \cdot, the other when the separator=cdot option is used. I’m not entirely sure why they are separate. Now, in math mode, the \cdot is changed to an ord. (ll. 392-393)

\protected\def\phys_units_separator
 {\ifcsname\??unitseparator\unitparameter\c!separator\endcsname\lastnamedcs\else\ifmmode\mathord\cdot\else\cdot\fi\fi} % Made \cdot an "ord" in math mode -GP

\installunitsseparator\v!normal{\ifmmode\mathord\cdot\else\cdot\fi}  % Made \cdot an "ord" in math mode -GP


2. Space is needed between number and units
To get the thin space between the number and the units (ll.412-418)

\protected\def\phys_units_space
 {\ifmmode
    \thinspace % let the atoms do the work. Right now atoms aren't doing the work, so I put in a \thinspace -GP
  \else
    \unskip % weird, why is unskip needed
    \ifcsname\??unitspace\unitparameter\c!space\endcsname\lastnamedcs\else\unitsmediumspace\fi
  \fi}


3. Space is needed after the units, before the next relation, binary operator, etc. Right now there seems to be no space added between the new dimension class and the relation and binary operator class. Until the space around the dimension class is fixed, The units should not be assigned to the dimension class, which means removing the code that sets units to this class. (ll. 618-623)

\def\phys_units_start
 {\ifmmode
    \dostarttagged\t!maction\t!unit
%     \mathatom % I removed this because the correct spaces after dim haven't been set (e.g. dimbin, dimrel) -GP
%        \s!leftclass  \mathdimensioncode
%        \s!rightclass \mathdimensioncode
    \bgroup
  \else
    \dostarttagged\t!unit\empty
  \fi
  \let\phys_units_finish\phys_units_stop
  \let\phys_units_start\relax}


4. Remove hardcoded backspace before the solidus in units. (If this space should be tighter, it probably should be dealt with for every solidus, not just the solidus in \unit the unit command.) (ll.412-418)

\permanent\protected\def\unitsSOLIDUS
 {%\ifnum\c_phys_units_state=\plusone % suffix  % Removed three lines to eliminate backspace before / -GP
  %  \unitsbackspace
  %\fi
  {/}%
  }%\unitsbackspace}


5. I think the \times in scientific notation should not have extra space. Everyone who commented on the mailing list agreed. However, I’m not sure that this is a universal desire, so it might be good to add an options, like scispace=normal for the usual binop space around the \times and scispace=tight for no extra space around \times. The changed line in phys-dime.mkxl used to add space around the \times in text. Now, instead, it removes the space around the \times in math by making the \times an ord. (ll. 170-172)

\permanent\protected\def\digitstextbinop#1% assumes preceding
 {\ifmmode\mathord#1\else\nobreak#1\fi} % Removed space around binop (\times or \cdot) in \units -GP
 %{\ifmmode#1\else\fourperemspace\nobreak#1\fourperemspace\fi} % This is the old line with spaces -GP


Those are my five suggestions. Thanks for looking at spacing in \units!

Gavin



[-- Attachment #2: units-spacing.tex --]
[-- Type: application/octet-stream, Size: 279 bytes --]

\starttext

The \type{\unit} command in text produces \unit{1.23e5 kg m^2/s^2}.

Inline math \type{$\unit$} produces $\unit{1.23e5 kg m^2/s^2}$.

Display math produces
\startformula
 \unit{1.23e5 kg m^2/s^2} + \unit{8.64e5 newton m} = \unit{987,000 joule}
\stopformula

\stoptext

[-- Attachment #3: units-linebreaks.tex --]
[-- Type: application/octet-stream, Size: 166 bytes --]

\starttext

Line breaks in math:

{\hsize=0pt $G = \unit{6.6743e-11 m3 kg-1 s-2}$}
\blank

Line breaks in text:

{\hsize=0pt \unit{6.6743e-11 m3 kg-1 s-2}}

\stoptext

[-- Attachment #4: phys-dim.mkxl --]
[-- Type: application/octet-stream, Size: 31108 bytes --]

%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}{}

% TAGGING NEEDS CHECKING ... WILL DO WHEN PARSER IS OK

\unprotect

%D \macros
%D   {digits, setdigitmode, setdigitsign}
%D
%D This is an update of the \MKII\ digits mechanism. Beware, space delimited mode is
%D now resticted!
%D
%D Depending on the digit mode the command \type {\digits} normalizes number
%D 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 purposes.
%D 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 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 well as different
%D formats. We strongly suggest you to use 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 period    \NC \NR
%D \NC \type{;}  \NC               \NC invisible comma     \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{//} \NC               \NC invisible high sign \NC \NR
%D \NC \type{--} \NC $\negative$   \NC high minus sign     \NC \NR
%D \NC \type{++} \NC $\positive$   \NC high plus 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 \starttabulate[|l|r|]
%D \NC \type{1}                      \NC \ruledhbox{\strut\digits{1}}                      \NC \NR
%D \NC \type{12}                     \NC \ruledhbox{\strut\digits{12}}                     \NC \NR
%D \NC \type{12.34}                  \NC \ruledhbox{\strut\digits{12.34}}                  \NC \NR
%D \NC \type{123,456}                \NC \ruledhbox{\strut\digits{123,456}}                \NC \NR
%D \NC \type{123,456.78}             \NC \ruledhbox{\strut\digits{123,456.78}}             \NC \NR
%D \NC \type{12,34}                  \NC \ruledhbox{\strut\digits{12,34}}                  \NC \NR
%D \NC \type{.1234}                  \NC \ruledhbox{\strut\digits{.1234}}                  \NC \NR
%D \NC \type{1234}                   \NC \ruledhbox{\strut\digits{1234}}                   \NC \NR
%D \NC \type{123,456.78^9}           \NC \ruledhbox{\strut\digits{123,456.78^9}}           \NC \NR
%D \NC \type{123,456.78e9}           \NC \ruledhbox{\strut\digits{123,456.78e9}}           \NC \NR
%D \NC \type{/123,456.78e-9}         \NC \ruledhbox{\strut\digits{/123,456.78e-9}}         \NC \NR
%D \NC \type{-123,456.78e-9}         \NC \ruledhbox{\strut\digits{-123,456.78e-9}}         \NC \NR
%D \NC \type{+123,456.78e-9}         \NC \ruledhbox{\strut\digits{+123,456.78e-9}}         \NC \NR
%D \NC \type{//123,456.78e-9}        \NC \ruledhbox{\strut\digits{//123,456.78e-9}}        \NC \NR
%D \NC \type{--123,456.78e-9}        \NC \ruledhbox{\strut\digits{--123,456.78e-9}}        \NC \NR
%D \NC \type{++123,456.78e-9}        \NC \ruledhbox{\strut\digits{++123,456.78e-9}}        \NC \NR
%D \NC \type{___,___,123,456,789.00} \NC \ruledhbox{\strut\digits{___,___,123,456,789.00}} \NC \NR
%D \NC \type{___,___,_12,345,678.==} \NC \ruledhbox{\strut\digits{___,___,_12,345,678.==}} \NC \NR
%D \stoptabulate

\newconstant\c_phys_digits_order
\newconstant\c_phys_digits_method
\newconstant\c_phys_digits_sign  % we has sized (text script scriptscript)

\permanent\protected\def\setdigitmethod#1{\c_phys_digits_method #1\relax}
\permanent\protected\def\setdigitsign  #1{\c_phys_digits_sign   #1\relax}
\permanent\protected\def\setdigitorder #1{\c_phys_digits_order  #1\relax}

\aliased\let\setdigitmode\setdigitmethod % compatibility

\def\phys_digits_normalized % we could calculate once and remember
  {\ifcase\c_phys_digits_sign
     \expandafter\secondoftwoarguments
   \orelse\ifmmode
     \expandafter\phys_digits_normalized_math
   \else
     \expandafter\phys_digits_normalized_text
   \fi}

\def\phys_digits_normalized_math#1#2%
  {\setbox\scratchbox\hbox{\normalstartimath\Ustack{#1}\normalstopimath}%
   \hbox to \wd\scratchbox{\hss{\normalstartimath\Ustack{#2}\normalstopimath}\hss}}

\def\phys_digits_normalized_text#1#2%
  {\setbox\scratchbox\hbox{#1}%
   \hbox to \wd\scratchbox{\hss#2\hss}}

\def\phys_digits_raised
  {\ifmmode
     \expandafter\normalsuperscript
   \else
     \expandafter\unitshigh
   \fi}

% we could use a symbolset but how many symbols are there ?

% \definesymbol[units][times][\times]
% \definesymbol[units][times][\cdots]

% \def\digitstimessymbol{\symbol[units][times]}

% \definesymbol[units][times][\times]
% \definesymbol[units][times][\cdots]
% \definesymbol[units][times][\invisibletimes]
% \definesymbol[units][times][\ifmmode\cdot\else\kern.2\emwidth\cdot\kern.2\emwidth\fi]

\permanent\protected\def\digitstextbinop#1% assumes preceding
  {\ifmmode\mathord#1\else\nobreak#1\fi} % Removed space around binop (\times or \cdot) in \units -GP
  %{\ifmmode#1\else\fourperemspace\nobreak#1\fourperemspace\fi} % This is the old line with spaces -GP

\frozen\def\digitstimessymbol{\digitstextbinop\times}

\frozen\protected\def\digitszeropadding   {\hphantom{0}}
\frozen\protected\def\digitsnegative      {\phys_digits_normalized{0}{\mathematics{\negative}}}
\frozen\protected\def\digitspositive      {\phys_digits_normalized{0}{\mathematics{\positive}}}
\frozen\protected\def\digitsminus         {\phys_digits_normalized{0}{\mathminus}}
\frozen\protected\def\digitsplus          {\phys_digits_normalized{0}{\mathplus}}
\frozen\protected\def\digitsplusminus     {\phys_digits_normalized{0}{\mathplusminus}}
\frozen\protected\def\digitsspace         {\hphantom{0}}
       \protected\def\digitsseparatorspace{\hphantom{.}}
\frozen\protected\def\digitssignspace     {\hphantom{\digitsminus}}
\frozen\protected\def\digitshighspace     {\hphantom{\digitspositive}}
\frozen\protected\def\digitspower       #1{\digitstimessymbol10\phys_digits_raised{#1}}
\frozen\protected\def\digitspowerplus   #1{\digitstimessymbol10\phys_digits_raised{\digitsplus#1}}
\frozen\protected\def\digitspowerminus  #1{\digitstimessymbol10\phys_digits_raised{\digitsminus#1}}
\frozen\protected\def\digitsdigit       #1{#1}

\frozen\protected\def\normaldigitscommasymbol {,}
\frozen\protected\def\normaldigitsperiodsymbol{.}

\frozen\let\normaldigitsseparatorspace\digitsseparatorspace

\installcorenamespace{digitscomma}
\installcorenamespace{digitsperiod}
\installcorenamespace{digitsspace}

\letcsname\??digitscomma 0\endcsname\normaldigitscommasymbol
\letcsname\??digitsperiod0\endcsname\normaldigitsperiodsymbol
\letcsname\??digitsspace 0\endcsname\normaldigitsseparatorspace

\letcsname\??digitscomma 1\endcsname\normaldigitsperiodsymbol
\letcsname\??digitsperiod1\endcsname\normaldigitscommasymbol
\letcsname\??digitsspace 1\endcsname\normaldigitsseparatorspace

\letcsname\??digitscomma 2\endcsname\normaldigitscommasymbol
\letcsname\??digitsperiod2\endcsname\normaldigitsperiodsymbol
\letcsname\??digitsspace 2\endcsname\normaldigitsseparatorspace

\letcsname\??digitscomma 3\endcsname\thinspace
\letcsname\??digitsperiod3\endcsname\normaldigitscommasymbol
\letcsname\??digitsspace 3\endcsname\thinspace

\letcsname\??digitscomma 4\endcsname\thinspace
\letcsname\??digitsperiod4\endcsname\normaldigitsperiodsymbol
\letcsname\??digitsspace 4\endcsname\thinspace

\letcsname\??digitscomma 5\endcsname\thickspace
\letcsname\??digitsperiod5\endcsname\normaldigitscommasymbol
\letcsname\??digitsspace 5\endcsname\thickspace

\letcsname\??digitscomma 6\endcsname\thickspace
\letcsname\??digitsperiod6\endcsname\normaldigitsperiodsymbol
\letcsname\??digitsspace 6\endcsname\thickspace

\frozen\protected\def\digitscommasymbol       {\csname\??digitscomma \number\c_phys_digits_method\endcsname}
\frozen\protected\def\digitsperiodsymbol      {\csname\??digitsperiod\number\c_phys_digits_method\endcsname}
\frozen\protected\def\digitsseparatorspace    {\csname\??digitsspace \number\c_phys_digits_method\endcsname}

\frozen\protected\def\digitsfinalcomma        {\digitsperiodsymbol} % more for tracing
\frozen\protected\def\digitsfinalperiod       {\digitsperiodsymbol} % more for tracing
\frozen\protected\def\digitsintermediatecomma {\digitscommasymbol } % more for tracing
\frozen\protected\def\digitsintermediateperiod{\digitscommasymbol } % more for tracing

%D The user macro:

\protected\def\phys_digits_indeed#1%
  {\dontleavehmode
   \begingroup
   \ifcase\c_phys_digits_order\expandafter\clf_digits_normal\else\expandafter\clf_digits_reverse\fi{\detokenize{#1}}%
   \endgroup
   \settrue\c_phys_units_dospace}

\permanent\protected\def\digits
  {\doifelsenextbgroup\phys_digits_argument\phys_digits_spaced}

\def\phys_digits_argument#1%
  {\phys_digits_indeed{#1}}

\def\phys_digits_spaced#1 % space delimited
  {\phys_digits_indeed{#1}}

%D \macros
%D   {unit}
%D
%D We have been using the units module (and its predecessor) for over a decade now
%D but when we moved on to \LUATEX\ a variant was prototyped that permits a less
%D texie coding. I finally picked up that thread and cleaned up the code a bit so
%D users can now play with it. (The main reason was that I wanted to test
%D 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 extent we need
%D 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

\installcorenamespace {unit}
\installcorenamespace {unitseparator}
\installcorenamespace {unitspace}

\installcommandhandler \??unit {unit} \??unit

\setupunit
  [\c!alternative=,              % done: text
   \c!separator=\v!normal,       % done: cdot|big|medium|space
   \s!language=\currentlanguage, % 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
  ]

\definehigh[unitshigh][\c!style=\txx]
\definelow [unitslow] [\c!style=\txx]

\aliased\let\setupunits\setupunit

\newconstant   \c_phys_units_mode   % 0=text 1=math 2=textinmath 3=mathintext
\newconstant   \c_phys_units_state  % 0=start 1=suffix 2=operator 3=unit 4=prefix 5=number
\newconditional\c_phys_units_quantity
\newconditional\c_phys_units_number
\newconditional\c_phys_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

\frozen\protected\def\unitssmallspace {\thinspace}
\frozen\protected\def\unitsmediumspace{\medspace}
\frozen\protected\def\unitsbigspace   {\thickspace}
\frozen\protected\def\unitsbackspace  {\negthinspace}
\frozen\protected\def\unitsmathspace  {\ifmmode\mathatomskip\mathdimensioncode\mathdimensioncode\mathstyle\fi}

\permanent\protected\def\installunitsseparator#1#2%
  {\defcsname\??unitseparator#1\endcsname{#2}}

\protected\def\phys_units_separator
  {\ifcsname\??unitseparator\unitparameter\c!separator\endcsname\lastnamedcs\else\ifmmode\mathord\cdot\else\cdot\fi\fi} % Made \cdot an "ord" in math mode -GP

\installunitsseparator\v!normal{\ifmmode\mathord\cdot\else\cdot\fi}  % Made \cdot an "ord" in math mode -GP
\installunitsseparator\v!big   {\unitsbigspace}
\installunitsseparator\v!medium{\unitsmediumspace}
\installunitsseparator\v!small {\unitssmallspace}
\installunitsseparator\v!none  {}
\installunitsseparator\v!math  {\unitsmathspace}

\permanent\protected\def\installunitsspace#1#2%
  {\defcsname\??unitspace#1\endcsname{#2}}

% \protected\def\phys_units_space
%   {\unskip % weird, why is unskip needed
%    \ifcsname\??unitspace\unitparameter\c!space\endcsname\lastnamedcs\else\unitsmediumspace\fi}

% \im{1 \unit{hour} 20 \unit{minute} 56 \unit{second}}
% \im{\unit{1 hour} \unit{20 minute} 56 \unit{second}}

\protected\def\phys_units_space
  {\ifmmode
     \thinspace % let the atoms do the work. Right now atoms aren't doing the work, so I put in a \thinspace -GP
   \else
     \unskip % weird, why is unskip needed
     \ifcsname\??unitspace\unitparameter\c!space\endcsname\lastnamedcs\else\unitsmediumspace\fi
   \fi}

\installunitsspace\v!normal{\unitsmediumspace}
\installunitsspace\v!big   {\unitsbigspace}
\installunitsspace\v!medium{\unitsmediumspace}
\installunitsspace\v!small {\unitssmallspace}
\installunitsspace\v!none  {}
\installunitsspace\v!math  {\unitsmathspace}

\newtoks \everyunits % we keep the old \units command so we need a longer one

\appendtoks
    \disablemathpunctuation
    \nocharacteralign
\to \everyunits

\appendtoks
    \frozen\instance\setuevalue\currentunit{\phys_units_direct{\currentunit}}
\to \everydefineunit

\protected\def\phys_units_direct#1%
  {\begingroup
   \the\everyunits
   \ifdim\lastskip>\zeropoint
     \settrue\c_phys_units_dospace
     \removelastskip
   \fi
   \c_phys_digits_method\unitparameter\c!method\relax
   \ifmmode\else\dontleavehmode\fi
   \edef\currentunit{#1}%
   \enforced\edef\unitlanguage{\unitparameter\s!language}%
   \enforced\let\prefixlanguage\unitlanguage
   \enforced\let\operatorlanguage\unitlanguage
%    \the\everyunits
  %\removeunwantedspaces % not ok yet
   \useunitstyleandcolor\c!style\c!color
   \ifmmode
     \ifcstok{\unitparameter\c!alternative}\v!text
       \expandafter\expandafter\expandafter\phys_units_direct_text_in_math
     \else
       \expandafter\expandafter\expandafter\phys_units_direct_math
     \fi
   \else
     \ifcstok{\unitparameter\c!alternative}\v!mathematics
       \expandafter\expandafter\expandafter\phys_units_direct_math_in_text
     \else
       \expandafter\expandafter\expandafter\phys_units_direct_text
     \fi
   \fi}

\protected\def\phys_units_direct_text_in_math#1%
  {\mathtext{
     \c_phys_units_mode\plustwo
     \phys_units_indeed{#1}%
     \phys_units_finish
   }%
   \endgroup}

\protected\def\phys_units_direct_math#1%
  {\c_phys_units_mode\plusone
   \rm\tf % slow
   \mathtf
   \phys_units_indeed{#1}%
   \phys_units_finish
   \endgroup}

\protected\def\phys_units_direct_text#1%
  {\phys_units_indeed{#1}
   \phys_units_finish
   \endgroup}

\protected\def\phys_units_direct_math_in_text#1%
  {\removeunwantedspaces % brr
   \startimath
   \c_phys_units_mode\plusthree
   \rm\tf
   \mathtf
   \phys_units_indeed{#1}%
   \phys_units_finish
   \stopimath
   \endgroup}

\protected\def\phys_units_direct_nested#1#2%
  {\phys_units_indeed{#2}}

\appendtoks
    \let\phys_units_direct\phys_units_direct_nested
\to \everyunits

\protected\def\phys_units_indeed#1%
  {\edef\p_order{\unitparameter\c!order}%
   \ifx\p_order\v!reverse\expandafter\clf_unit_reverse\else\expandafter\clf_unit_normal\fi{\detokenize{#1}}}

\permanent\protected\def\digitstextbinnop#1%
  {\ifmmode#1\else#1\fourperemspace\fi}

\permanent\protected\def\unitsPUS#1#2#3{\phys_units_next\prefixtext{#1}\unittext{#2}\unitsraise{\suffixtext{#3}}\c_phys_units_state\plusone} % suffix
\permanent\protected\def\unitsPU   #1#2{\phys_units_next\prefixtext{#1}\unittext{#2}\c_phys_units_state\plusthree}                           % unit
\permanent\protected\def\unitsPS   #1#2{\phys_units_next\prefixtext{#1}\unitsraise{\suffixtext{#2}}\c_phys_units_state\plusone}              % suffix
\permanent\protected\def\unitsUS   #1#2{\phys_units_next\unittext{#1}\unitsraise{\suffixtext{#2}}\c_phys_units_state\plusone}                % suffix
\permanent\protected\def\unitsP      #1{\phys_units_next\prefixtext{#1}1\c_phys_units_state\plusfour}                                        % prefix
\permanent\protected\def\unitsU      #1{\phys_units_next\unittext{#1}\c_phys_units_state\plusthree}                                          % unit
\permanent\protected\def\unitsS      #1{\phys_units_start{}\unitsraise{\suffixtext{#1}}\c_phys_units_state\plusone}                          % suffix
\permanent\protected\def\unitsO      #1{\phys_units_start\operatortext{#1}\c_phys_units_state\plustwo}                                       % operator
%permanent\protected\def\unitsN      #1{\phys_units_start#1\c_phys_units_state\plusfive}                                                     % number
\permanent\protected\def\unitsC      #1{\removeunwantedspaces\unittext{#1}\c_phys_units_state\plussix}                                       % connected
\permanent\protected\def\unitsQ      #1{\removeunwantedspaces\unitslower{#1}\c_phys_units_state\zerocount}
\permanent\protected\def\unitsR    #1#2{% todo: tagging
                                        \ifmmode
                                          #2%
                                        \orelse\ifnum#1=\plusone
                                          \digitstextbinop{#2}% before and after
                                        \else
                                          \digitstextbinnop{#2}% after
                                        \fi
                                        \c_phys_units_state\zerocount
                                        \setfalse\c_phys_units_dospace
                                        \setfalse\c_phys_units_number
                                        \setfalse\c_phys_units_quantity}
\permanent\protected\def\unitsRPM      {\unitsR\plusone  {±}} % todo: symbols
\permanent\protected\def\unitsRTO      {\unitsR\plusone  {–}} % todo: symbols
\permanent\protected\def\unitsRabout   {\unitsR\zerocount{±}} % todo: symbols
\permanent\protected\def\unitsPopen    {(}
\permanent\protected\def\unitsPclose   {)}
\permanent\protected\def\unitrange   #1{}

% Fonts can have a celsius and lack a fahrenheit symbol and as we want to be
% consistent so we check for the counterparts as well. It's slow but ok. Of course
% we could go virtual instead.

\permanent\protected\def\phys_units_text_prime      {\textacute}
\permanent\protected\def\phys_units_text_doubleprime{\textacute\kern-.25em\textacute}
\permanent\protected\def\phys_units_text_celsius    {°C}
\permanent\protected\def\phys_units_text_fahrenheit {°F}

\permanent\protected\def\checkedtextprime
  {\iffontchar\font"2032\relax\iffontchar\font"2033\relax
     ′\else\phys_units_text_prime\fi\else\phys_units_text_prime
   \fi}

\permanent\protected\def\checkedtextdoubleprime
  {\iffontchar\font"2033\relax\iffontchar\font"2032\relax
     ″\else\phys_units_text_doubleprime\fi\else\phys_units_text_doubleprime
   \fi}

% \permanent\protected\def\checkedtextcelsius
%   {\ifmmode
%      \phys_units_text_celsius
%    \orelse\iffontchar\font"2103\relax
%      ℃\else\phys_units_text_celsius
%    \fi}
%
% \permanent\protected\def\checkedtextfahrenheit
%   {\ifmmode
%      \phys_units_text_fahrenheit
%    \orelse\iffontchar\font"2109\relax
%      ℉\else\phys_units_text_fahrenheit
%    \fi}
%
% % but, as users don't like this ...

\aliased\let\checkedtextcelsius   \phys_units_text_celsius
\aliased\let\checkedtextfahrenheit\phys_units_text_fahrenheit

\setelementnature[unit]    [mixed]
\setelementnature[quantity][mixed]

\let\phys_units_finish\relax

\permanent\protected\def\unitsNstartindeed
  {\ifmmode \else
     \settrue\c_phys_units_quantity
     \dostarttagged\t!quantity\empty
     \settrue\c_phys_units_number
     \dostarttagged\t!number\empty
   \fi}

\permanent\protected\def\unitsNstop
  {\ifconditional\c_phys_units_number
     \setfalse\c_phys_units_number
     \dostoptagged
   \fi
   \c_phys_units_state\plusfive}

% This is a hack: for some reason \unit {micro meter} like patterns give
% \unitsNstart \unitsNstop so there is a buglet in the parser

% \aliased\let\unitsNstartindeed\unitsNstart

\permanent\protected\def\unitsNstart
  {\doifelsenextchar\unitsNstop\gobbleoneargument\unitsNstartindeed}

% End of hack.

\permanent\protected\def\unitsNspace
  {\space}

\permanent\protected\def\unitsN#1%
  {\unitsNstart#1\unitsNstop}

\def\phys_units_start
  {\ifmmode
     \dostarttagged\t!maction\t!unit
%     \mathatom % I removed this because the correct spaces after dim haven't been set (e.g. dimbin, dimrel) -GP
%        \s!leftclass  \mathdimensioncode
%        \s!rightclass \mathdimensioncode
     \bgroup
   \else
     \dostarttagged\t!unit\empty
   \fi
   \let\phys_units_finish\phys_units_stop
   \let\phys_units_start\relax}

\def\phys_units_stop
  {\ifconditional\c_phys_units_number
     \setfalse\c_phys_units_number
     \dostoptagged
   \fi
   \ifconditional\c_phys_units_quantity
     \setfalse\c_phys_units_quantity
     \dostoptagged
   \fi
   \dostoptagged
   \ifmmode
     \egroup
   \fi}

\permanent\def\unitsraise
  {\ifcase\c_phys_units_mode
     \expandafter\unitshigh
   \or
     \expandafter\normalsuperscript
   \or
     \expandafter\unitshigh
   \or
     \expandafter\normalsuperscript
   \fi}

\permanent\def\unitslower
  {\ifcase\c_phys_units_mode
     \expandafter\unitslow
   \or
     \expandafter\normalsubscript
   \or
     \expandafter\unitslow
   \or
     \expandafter\normalsubscript
   \fi}

\protected\def\phys_units_next
  {\ifcase\c_phys_units_state % start
     \ifconditional\c_phys_units_dospace
      % \ifdim\lastskip=\zeropoint
         \phys_units_space
      % \else
      %   % too tricky ... we could remove and add
      % \fi
     \fi
   \or % 1: suffix
     {\phys_units_separator}%
   \or % 2: operator
   \or % 3: unit
     {\phys_units_separator}%
   \or % 4: prefix
   \or % 5: number
     \phys_units_space
   \or % 6: symbol (connected)
   \fi
   \setfalse\c_phys_units_dospace
   \phys_units_start}

\permanent\protected\def\unitsTIMES % Does this do anything? -GP
  {\ifnum\c_phys_units_state=\plusone % suffix
   \else
     \unitssmallspace
   \fi
   \cdot} % or \times

\permanent\protected\def\unitsOUTOF
  {\ifnum\c_phys_units_state=\plusone % suffix
   \else
     \unitssmallspace
   \fi
   :}

\permanent\protected\def\unitsSOLIDUS
  {%\ifnum\c_phys_units_state=\plusone % suffix  % Removed three lines to eliminate backspace before / -GP
   %  \unitsbackspace
   %\fi
   {/}%
   }%\unitsbackspace}

\definelabelclass [unit]     [2]
\definelabelclass [operator] [2]
\definelabelclass [prefix]   [2]
\definelabelclass [suffix]   [2] % This is only a label because we want to show them in a table.

\clf_definelabels{prefix}{prefixes}\s!false\relax
\clf_definelabels{unit}{units}\s!false\relax
\clf_definelabels{operator}{operators}\s!false\relax
\clf_definelabels{suffix}{suffixes}\s!false\relax

%D You can define additional units:
%D
%D \starttyping
%D \registerunit
%D   [unit]
%D   [point=point,
%D    basepoint=basepoint,
%D    scaledpoint=scaledpoint,
%D    didot=didot,
%D    cicero=cicero]
%D \stoptyping
%D
%D Possible categories are: \type {prefix}, \type {unit}, \type {operator}, \type
%D {suffix}, \type {symbol},\type {packaged}. You also need to define labels:
%D
%D \starttyping
%D \setupunittext
%D   [point=pt,
%D    basepoint=bp,
%D    scaledpoint=sp,
%D    didot=dd,
%D    cicero=cc]
%D \stoptyping

\permanent\tolerant\protected\def\registerunit[#1]#*[#2]% todo: public implementer
  {\clf_registerunit{#1}{#2}}

%D You can generate a list as follows:
%D
%D \starttyping
%D \usemodule[phy-01]
%D
%D \ShowUnitsTable % [prefixes]
%D \stoptyping

%D Now we define the standard units command:

\defineunit
  [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
%D
%D Another example:
%D
%D \starttyping
%D \startluacode
%D     languages.data.labels.units.foo = {
%D         Liter = "l"
%D     }
%D     languages.data.labels.units.bar = {
%D         Liter = "L"
%D     }
%D \stopluacode
%D
%D \defineunits[lunit]            \lunit{10 l/s}\par
%D \defineunits[funit][label=foo] \funit{10 l/s}\par
%D \defineunits[bunit][label=bar] \bunit{10 l/s}\par
%D \stoptyping

%D Bonus:
%D
%D \starttyping
%D    \pi\ = \hyphenateddigits[\unknown]{3.141592653589793238462643383279502884197169399375105}  \blank
%D    \pi\ = \hyphenateddigits{3.141592653589793238462643383279502884197169399375105}            \blank
%D x $\pi  = \hyphenateddigits[\unknown]{3.141592653589793238462643383279502884197169399375105}$ \blank
%D x $\pi  = \hyphenateddigits{3.141592653589793238462643383279502884197169399375105}$           \blank
%D \stoptyping

\mutable\protected\def\digitsbreak{\hskip\zeropoint\s!plus\onepoint\relax\ifmmode\allowbreak\fi}

\protect \endinput

[-- Attachment #5: Type: text/plain, Size: 2 bytes --]




[-- Attachment #6: Type: text/plain, Size: 496 bytes --]

___________________________________________________________________________________
If your question is of interest to others as well, please add an entry to the Wiki!

maillist : ntg-context@ntg.nl / https://www.ntg.nl/mailman/listinfo/ntg-context
webpage  : https://www.pragma-ade.nl / http://context.aanhet.net
archive  : https://bitbucket.org/phg/context-mirror/commits/
wiki     : https://contextgarden.net
___________________________________________________________________________________

  reply	other threads:[~2022-10-21 18:20 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-10-08 17:59 Spacing in \unit Gavin via ntg-context
2022-10-10  1:32 ` Alan Braslau via ntg-context
2022-10-10  6:15   ` Max Chernoff via ntg-context
2022-10-12 21:54     ` Spacing in \unit - SOLVED Gavin via ntg-context
2022-10-12 22:11       ` Rik Kabel via ntg-context
2022-10-12 22:49       ` Max Chernoff via ntg-context
2022-10-12 23:55         ` Spacing in \unit - degrees Alan Braslau via ntg-context
2022-10-13  3:14           ` Gavin via ntg-context
2022-10-13 13:26             ` Alan Braslau via ntg-context
2022-10-13  0:11         ` Spacing in \unit - SOLVED Gavin via ntg-context
2022-10-13  7:03       ` Oliver Sieber via ntg-context
2022-10-13 11:52         ` Gavin via ntg-context
2022-10-14  8:12           ` Hans Hagen via ntg-context
2022-10-21 18:20             ` Gavin via ntg-context [this message]
2022-10-21 19:07               ` Gavin via ntg-context
2022-10-12 16:50 ` Dimension atom in math? (was: Spacing in \unit) Gavin via ntg-context

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=565BAFA6-6E9C-4B71-9349-C0F2D91317F7@comcast.net \
    --to=ntg-context@ntg.nl \
    --cc=gavinpublic@comcast.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).