\unit with converted measures
I made tables of unit conversions to explain ConTeXt’s units. Conversion works like this: \define[2]\Conv{\scratchdimen #1 \the\nodimen #2 \scratchdimen} \Conv{1dk}{mm} That gives me "2.263348mm", while I’d like "2,263348 mm". I tried to use \unit within the definition above or like \unit{\Conv{1dk}{mm}}, but the result is empty – probably an expansion problem? Complete not-working example: """ \mainlanguage[de] \setupunit[method=3,space=small,] \define[2]\Conv{\unit{\dimexpr\scratchdimen #1 \the\nodimen #2 \scratchdimen\relax}} \starttext \bTABLE \bTR\bTH Einheit \eTH\bTH mm \eTH\bTH pt \eTH\eTR \bTR\bTD 1 dk \eTD\bTD \Conv{1dk}{mm} \eTD\bTD \Conv{1dk}{pt} \eTD\eTR \bTR\bTD 1 es \eTD\bTD \Conv{1es}{mm} \eTD\bTD \Conv{1es}{pt} \eTD\eTR \bTR\bTD 1 ts \eTD\bTD \Conv{1ts}{mm} \eTD\bTD \Conv{1ts}{pt} \eTD\eTR \eTABLE \stoptext """ (Yes, I should have used a loop…) Hraban
Hi Hraban, On Tue, 2025-11-25 at 18:09 +0100, Henning Hraban Ramm wrote:
\define[2]\Conv{\scratchdimen #1 \the\nodimen #2 \scratchdimen}
I tried to use \unit within the definition above or like \unit{\Conv{1dk}{mm}}, but the result is empty – probably an expansion problem?
\define[2]\Conv{\unit{\dimexpr\scratchdimen #1 \the\nodimen #2 \scratchdimen\relax}}
1. Setting a dimension isn't expandable, so you need to do that before using \unit. 2. You need to make sure that the argument to \unit is expanded before \unit itself is. The following should work as expected: \mainlanguage[de] \setupunit[method=3,space=small,] \define[2]\Conv{% \scratchdimen=#1 \normalexpanded{\noexpand\unit{\the\nodimen #2 \scratchdimen}} } \starttext \bTABLE \bTR\bTH Einheit \eTH\bTH mm \eTH\bTH pt \eTH\eTR \bTR\bTD 1 dk \eTD\bTD \Conv{1dk}{mm} \eTD\bTD \Conv{1dk}{pt} \eTD\eTR \bTR\bTD 1 es \eTD\bTD \Conv{1es}{mm} \eTD\bTD \Conv{1es}{pt} \eTD\eTR \bTR\bTD 1 ts \eTD\bTD \Conv{1ts}{mm} \eTD\bTD \Conv{1ts}{pt} \eTD\eTR \eTABLE \stoptext Thanks, -- Max
Am 25.11.25 um 22:54 schrieb Max Chernoff via ntg-context:
\define[2]\Conv{\unit{\dimexpr\scratchdimen #1 \the\nodimen #2 \scratchdimen\relax}}
1. Setting a dimension isn't expandable, so you need to do that before using \unit.
2. You need to make sure that the argument to \unit is expanded before \unit itself is.
I’m not sure I’ll ever catch the intricacies of expansion… :/
The following should work as expected:
\mainlanguage[de] \setupunit[method=3,space=small,] \define[2]\Conv{% \scratchdimen=#1 \normalexpanded{\noexpand\unit{\the\nodimen #2 \scratchdimen}} }
This works as intended, thank you very Max! Hraban
On 11/25/2025 10:54 PM, Max Chernoff via ntg-context wrote:
Hi Hraban,
On Tue, 2025-11-25 at 18:09 +0100, Henning Hraban Ramm wrote:
\define[2]\Conv{\scratchdimen #1 \the\nodimen #2 \scratchdimen}
I tried to use \unit within the definition above or like \unit{\Conv{1dk}{mm}}, but the result is empty – probably an expansion problem?
\define[2]\Conv{\unit{\dimexpr\scratchdimen #1 \the\nodimen #2 \scratchdimen\relax}}
1. Setting a dimension isn't expandable, so you need to do that before using \unit.
2. You need to make sure that the argument to \unit is expanded before \unit itself is.
The following should work as expected:
\mainlanguage[de] \setupunit[method=3,space=small,] \define[2]\Conv{% \scratchdimen=#1 \normalexpanded{\noexpand\unit{\the\nodimen #2 \scratchdimen}} }
\starttext
\bTABLE \bTR\bTH Einheit \eTH\bTH mm \eTH\bTH pt \eTH\eTR \bTR\bTD 1 dk \eTD\bTD \Conv{1dk}{mm} \eTD\bTD \Conv{1dk}{pt} \eTD\eTR \bTR\bTD 1 es \eTD\bTD \Conv{1es}{mm} \eTD\bTD \Conv{1es}{pt} \eTD\eTR \bTR\bTD 1 ts \eTD\bTD \Conv{1ts}{mm} \eTD\bTD \Conv{1ts}{pt} \eTD\eTR \eTABLE
\stoptext
-- Max
Hi Max, So here's some low level treat for you. \unit doesn't expand in an \edef comparable situation so no need for \noexpand. Actually, you can expand by prefixing with \expand if needed. The \scratchimen can also be avoided which has some benefits. \define[2]\Conv{% \normalexpanded{\unit{\the\nodimen #2 {#1}}}% } I'd do: \starttexdefinition Conv #1#2 \normalexpanded { \unit { \the\nodimen #2 {#1} } } \stoptexdefinition Now Hraban can also go wild with two Sundqvist units in one go: \bTR \bTD 1ts+2es \eTD \bTD \Conv{1ts+2es}{mm} \eTD \bTD \Conv{1ts+2es}{pt} \eTD \eTR And of course, he can guess how \nodimen is defined. I admit that I had to look it up .. so long ago .. interesting that you found it (and remembered). Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
Am 26.11.25 um 09:51 schrieb Hans Hagen via ntg-context:
\starttexdefinition Conv #1#2 \normalexpanded { \unit { \the\nodimen #2 {#1} } } \stoptexdefinition
Thank you!
Now Hraban can also go wild with two Sundqvist units in one go:
\bTR \bTD 1ts+2es \eTD \bTD \Conv{1ts+2es}{mm} \eTD \bTD \Conv{1ts+2es}{pt} \eTD \eTR
And of course, he can guess how \nodimen is defined. I admit that I had to look it up .. so long ago .. interesting that you found it (and remembered).
Actually, I can’t. I got my code snippet from you and used it since. I only tried to add \unit because the editor of my book asked why the numbers are oddly formatted (i.e. not at all) in these tables. (I tried it then, failed, and let it be.) Hraban
On 11/25/2025 10:54 PM, Max Chernoff via ntg-context wrote:
\normalexpanded{\noexpand\unit{\the\nodimen #2 \scratchdimen}}
in lmtx you can just use \expanded ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
Am 26.11.25 um 09:53 schrieb Hans Hagen via ntg-context:
On 11/25/2025 10:54 PM, Max Chernoff via ntg-context wrote:
\normalexpanded{\noexpand\unit{\the\nodimen #2 \scratchdimen}}
in lmtx you can just use \expanded
Great, another puzzle piece. But it doesn’t stop here: Can I apply a format code, e.g. for rounding, to use such a dimension with \unit? """ \newdimen\Indent \Indent=12pt Indent is \the\Indent\ wide. That’s \the\nodimen mm\Indent in metric. Nicely formatted: \expanded{\unit{\the\nodimen mm \Indent}}. % I’d like to round/cut this to 2 digits, like \unit{__,__1.23 mm} """ BTW, why does the following work without \the? Is this not a dimension? """ \setwidthof{ABCDE}\to\Width {ABCDE} is \Width\ wide. """ Hraban
On 11/29/2025 4:26 PM, Henning Hraban Ramm wrote:
BTW, why does the following work without \the? Is this not a dimension?
""" \setwidthof{ABCDE}\to\Width {ABCDE} is \Width\ wide. """
because it is defined as \permanent\protected\def\setwidthof#1\to#2{\edef#2{\widthofstring{#1}}} actually a mkii-ish macro so one can as wel l use \scratchdimen\widthofstring{abc} if you doubt if something is a dimen, use \todimension \dimensiondef\WhatIsThis\widthofstring{abc} \todimension\scratchdimen \todimension10pt \todimension{10pt + ex + \WhatIsThis} \toscaled{10pt + ex + \WhatIsThis} etc etc Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
Am 29.11.25 um 16:37 schrieb Hans Hagen via ntg-context:
On 11/29/2025 4:26 PM, Henning Hraban Ramm wrote:
BTW, why does the following work without \the? Is this not a dimension?
""" \setwidthof{ABCDE}\to\Width {ABCDE} is \Width\ wide. """
because it is defined as
\permanent\protected\def\setwidthof#1\to#2{\edef#2{\widthofstring{#1}}}
actually a mkii-ish macro so one can as wel l use
\scratchdimen\widthofstring{abc}
Ah, thank you!
if you doubt if something is a dimen, use \todimension
\dimensiondef\WhatIsThis\widthofstring{abc}
\todimension\scratchdimen
\todimension10pt
\todimension{10pt + ex + \WhatIsThis}
\toscaled{10pt + ex + \WhatIsThis}
etc etc
The influx of new commands never ends … Hraban
On 11/29/2025 6:35 PM, Henning Hraban Ramm wrote:
The influx of new commands never ends …
depends ... \toscaled is just the primitive for \withoutpt that we already had and \todimension like \the but with some check (much is about making the repertoire consistent; not all are useful for users) (last week we added some to metapost so be glad that you don't have to keep track of that; there much is about performance and easy of programming hefty solutions) Hans ----------------------------------------------------------------- Hans Hagen | PRAGMA ADE Ridderstraat 27 | 8061 GH Hasselt | The Netherlands tel: 038 477 53 69 | www.pragma-ade.nl | www.pragma-pod.nl -----------------------------------------------------------------
Hi Hraban, On Sat, 2025-11-29 at 16:26 +0100, Henning Hraban Ramm wrote:
Can I apply a format code, e.g. for rounding, to use such a dimension with \unit?
I'm sure that this is possible from TeX, but as soon as you're doing something complicated like this, it's easiest to use Lua: \startluacode interfaces.implement { name = "FormatUnit", arguments = { "dimension", "string", }, actions = { function(from, to) return number.todimen(from, to, [[%M\thinspace %s]]) end, context }, } \stopluacode \unprotect \protected\def\FormatUnit[#S#1]#*#2{\clf_FormatUnit{#1}{#2}} \protect \startTEXpage[offset=1ex] \cdef\Units{pt,mm,cm,in} \bTABLE[ leftframe=off, rightframe=off, loffset=0.5em, roffset=0.5em, align=flushright, ] % We can't nest \startprocesscommalist or \dowith, so we need to use one % of each. \dowith{\Units}{ \bTR \startprocesscommacommand[\Units] \bTD \FormatUnit[1#1]{##1} \eTD \stopprocesscommacommand \eTR } \eTABLE \FormatUnit[10pt]{in} \FormatUnit[\textwidth]{pc} \FormatUnit[\dimexpr 1cm + 1in]{mm} \stopTEXpage Thanks, -- Max
participants (3)
-
Hans Hagen -
Henning Hraban Ramm -
Max Chernoff