summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/latex/non-decimal-units
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2023-09-26 20:08:36 +0000
committerKarl Berry <karl@freefriends.org>2023-09-26 20:08:36 +0000
commit574f55abeb7ecec548e1acd1e7619d7559a7afa1 (patch)
treef289264a6e0a12ce7a9afd8fd9323e91dff7a8d8 /Master/texmf-dist/tex/latex/non-decimal-units
parentc1b2f7cc37f5bf1c8704ba4b37df8e0d61a97750 (diff)
non-decimal-units (26sep23)
git-svn-id: svn://tug.org/texlive/trunk@68377 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/latex/non-decimal-units')
-rw-r--r--Master/texmf-dist/tex/latex/non-decimal-units/non-decimal-units.british.tex27
-rw-r--r--Master/texmf-dist/tex/latex/non-decimal-units/non-decimal-units.danish.tex122
-rw-r--r--Master/texmf-dist/tex/latex/non-decimal-units/non-decimal-units.german.tex21
-rw-r--r--Master/texmf-dist/tex/latex/non-decimal-units/non-decimal-units.sty598
4 files changed, 768 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/latex/non-decimal-units/non-decimal-units.british.tex b/Master/texmf-dist/tex/latex/non-decimal-units/non-decimal-units.british.tex
new file mode 100644
index 00000000000..28c849f641d
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/non-decimal-units/non-decimal-units.british.tex
@@ -0,0 +1,27 @@
+%%% CURRENCY %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+% https://en.wikipedia.org/wiki/£sd
+
+\nduBaseUnits{%
+ pound sterling={%
+ symbol=£,
+ display={\nduSym}{},
+ },
+ shilling={%
+ symbol=s,
+ factor=20 per pound sterling,
+ display={}{\nduSym},
+ },
+ penny={%
+ symbol=d,
+ factor=12 per shilling,
+ display={}{\nduSym},
+ },
+}
+
+\nduAliases{%
+ british pound sterling lsd={%
+ units=pound sterling.shilling.penny,
+ segment separator={. },
+ },
+}
diff --git a/Master/texmf-dist/tex/latex/non-decimal-units/non-decimal-units.danish.tex b/Master/texmf-dist/tex/latex/non-decimal-units/non-decimal-units.danish.tex
new file mode 100644
index 00000000000..0ac75c3587c
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/non-decimal-units/non-decimal-units.danish.tex
@@ -0,0 +1,122 @@
+%%% CURRENCY %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\nduBaseUnits{%
+ rigsbankdaler={%
+ symbol=Rbd.,
+ },
+ rigsdaler={%
+ symbol=Rdl.,
+ },
+ sletdaler={%
+ symbol=Sldl.,
+ },
+ speciedaler={%
+ symbol=Spdl.,
+ },
+ ort={symbol=Ort,factor=4 per rigsdaler},
+ mark={%
+ symbol=Mk.,
+ factor=6 per rigsdaler,
+ factor=4 per sletdaler,
+ },
+ skilling={%
+ symbol=Sk.,
+ factor=16 per mark,
+ factor=24 per ort,
+ factor=84 per speciedaler,
+ factor=96 per rigsbankdaler,
+ },
+ hvid={%
+ symbol=Hvid,
+ factor=3 per skilling,
+ },
+ penning={%
+ symbol=Pg.,
+ factor=4 per hvid,
+ factor=12 per skilling,
+ },
+}
+
+\nduAliases{%
+ danish rigsbankdaler={%
+ units=rigsbankdaler.skilling,
+ macro={rbd}{%
+ normalize,
+ treat zero as nil
+ },
+ },
+ danish rigsdaler={%
+ units=rigsdaler.mark.skilling.penning,
+ macro={rdl}{%
+ normalize,
+ treat zero as nil
+ },
+ },
+ danish sletdaler={%
+ units=sletdaler.mark.skilling.penning,
+ macro={sldl}{%
+ normalize,
+ treat zero as nil
+ },
+ },
+}
+
+
+%%%% AREA %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\nduBaseUnits{%
+ tønde={%
+ symbol=Td.,
+ },
+ skæppe={%
+ symbol=Skp.,
+ factor=8 per tønde,
+ },
+ fjerdingkar={%
+ symbol=Fjk.,
+ factor=4 per skæppe,
+ },
+ album={%
+ symbol=Alb.,
+ factor=3 per fjerdingkar,
+ },
+ penning/factor=4 per album, % penning symbols defined under currency
+}
+
+\nduAliases{%
+ danish hartkorn={%
+ units=tønde.skæppe.fjerdingkar.album.penning,
+ macro={hartkorn}{%
+ normalize,
+ treat zero as nil
+ },
+ },
+}
+
+
+%%%% WEIGHT %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\nduBaseUnits{%
+ skippund={%
+ symbol=Spd.,
+ },
+ lispund={%
+ symbol=Lpd.,
+ factor=20 per skippund,
+ },
+ skaalpund={%
+ symbol=Pd.,
+ factor=16 per lispund,
+ },
+}
+
+\nduAliases{%
+ danish pund={%
+ units=skippund.lispund.skaalpund,
+ macro={pund}{%
+ normalize,
+ treat zero as nil
+ },
+ },
+}
+
diff --git a/Master/texmf-dist/tex/latex/non-decimal-units/non-decimal-units.german.tex b/Master/texmf-dist/tex/latex/non-decimal-units/non-decimal-units.german.tex
new file mode 100644
index 00000000000..912ee0d4280
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/non-decimal-units/non-decimal-units.german.tex
@@ -0,0 +1,21 @@
+%%% CURRENCY %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\nduBaseUnits{%
+ reichsthaler={%
+ symbol=Rthl., % \mufi{reichtalold}
+ },
+ groschen={%
+ symbol=Gr., % \mufi{grosch}
+ factor=30 per reichsthaler,
+ },
+ pfennig={%
+ symbol=Pf., % \mufi{20B0}
+ factor=12 per groschen,
+ },
+}
+
+\nduAliases{%
+ german reichsthaler={%
+ units=reichsthaler.groschen.pfennig,
+ },
+}
diff --git a/Master/texmf-dist/tex/latex/non-decimal-units/non-decimal-units.sty b/Master/texmf-dist/tex/latex/non-decimal-units/non-decimal-units.sty
new file mode 100644
index 00000000000..92459759cc0
--- /dev/null
+++ b/Master/texmf-dist/tex/latex/non-decimal-units/non-decimal-units.sty
@@ -0,0 +1,598 @@
+\ProvidesPackage{non-decimal-units}[2023/09/26 Macros for displaying and manipulating historical non-decimal units]
+
+% License: CC-BY-SA 4.0
+% Author: Mikkel Eide Eriksen <mikkel.eriksen@gmail.com>
+
+\RequirePackage{pgfkeys}
+\RequirePackage{pgfopts}
+\RequirePackage{bigintcalc}
+
+\RequirePackage{etoolbox}
+\RequirePackage{ifthen}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\pgfkeys{/handlers/.store in cs/.code=\pgfkeysalso{%
+ \pgfkeyscurrentpath/.code=\csdef{#1}{##1}}%
+}
+
+\def\nduset{\pgfqkeys{/ndu}}
+
+\newif\ifndushowvalues
+\newif\ifndushowaffixes
+\newif\ifndutreatzeroasnil
+\newif\ifndualigned
+\ndushowvaluestrue
+\ndushowaffixestrue
+\newif\ifndunormalize
+
+\newcounter{autorepr}
+
+\gdef\ndu@nextdelim{}%
+\gdef\ndu@delim{}%
+
+\nduset{%
+ base units/.is family,
+ base units/.unknown/.code={%
+ \expandafter\nduBuildBaseUnitKeys\expandafter{\pgfkeyscurrentname}{#1}%
+ },
+ unit groups/.is family,
+ unit groups/.unknown/.code={%
+ \expandafter\nduBuildUnitGroupKeys\expandafter{\pgfkeyscurrentname}%
+ },
+ aliases/.is family,
+ aliases/.unknown/.code={%
+ \expandafter\nduBuildAliasKeys\expandafter{\pgfkeyscurrentname}{#1}%
+ },
+ show/.is choice,
+ show/values/.code={\ndushowvaluestrue\ndushowaffixesfalse},
+ show/values and symbols/.code={\ndushowvaluestrue\ndushowaffixestrue},
+ show/symbols/.code={\ndushowvaluesfalse\ndushowaffixestrue},
+ show=values and symbols,
+ cell width/.initial=5em,
+ add to variable/.code={%
+ \csdef{ndu@current@variable}{#1}%
+ \csdef{ndu@current@operator}{+}%
+ },
+ subtract from variable/.code={%
+ \csdef{ndu@current@variable}{#1}%
+ \csdef{ndu@current@operator}{-}%
+ },
+ replace nil with/.store in cs=ndu@nil@replacement,
+ treat zero as nil/.is if=ndutreatzeroasnil,
+ treat zero as nil=false,
+ normalize/.is if=ndunormalize,
+ normalize=false,
+ segment separator/.initial={~},
+ aligned/.is if=ndualigned,
+ aligned=false,
+ set aligned for environment/.code={%
+ \AtBeginEnvironment{#1}{\nduset{aligned}}%
+ },
+}
+
+\newcommand\nduBuildBaseUnitKeys[2]{%
+ \nduset{%
+ base units/#1/.is family,base units/#1,
+ symbol/.initial={#1},
+ factor/.style args={##1 per ##2}{%
+ /ndu/base units/##2/factors/#1/.initial=##1,
+ },
+ prefix/.initial={},
+ suffix/.initial={~\nduSym},
+ display/.style 2 args={%
+ prefix={##1},
+ suffix={##2},
+ },
+ #2,
+ }%
+}
+
+\newcommand\nduBaseUnits[1]{%
+ \nduset{%
+ base units,#1,
+ }%
+}
+
+\newcommand\nduBuildUnitGroupKeys[1]{% called by .unknown handler
+ \nduset{%
+ unit groups/#1/.search also={/ndu},
+ unit groups/#1/.is family,unit groups/#1,
+ segment separator/.link=/ndu/segment separator,
+ segment depth/.initial=-1,
+ update segment depth/.code={%
+ \ifnum##1>\pgfkeysvalueof{/ndu/unit groups/#1/segment depth}%
+ \nduset{%
+ unit groups/#1/segment depth=##1,
+ }%
+ \fi%
+ },
+ restrict segment depth/.link=/ndu/unit groups/#1/segment depth,
+ }%
+ \nduBuildSegments{#1}{#1}%
+}
+
+\newcommand\nduUnitGroups[1]{%
+ \nduset{%
+ unit groups,#1,
+ }%
+}
+
+\newcommand\nduBuildAliasKeys[2]{% called by .unknown handler
+ \nduset{%
+ aliases/#1/.is family,aliases/#1,
+ units/.code={%
+ % create unit group and set search path
+ \pgfkeys{%
+ /ndu/unit groups/##1,
+ /ndu/aliases/#1/.search also={/ndu/unit groups/##1},
+ /ndu/aliases/#1/unit group/.initial=##1,
+ }%
+ },
+ macro/.code 2 args={%
+ \nduNewMacro{#1}[##2]{##1}%
+ },
+ #2,
+ }%
+}
+
+\newcommand\nduAliases[1]{%
+ \nduset{%
+ aliases,#1,
+ }%
+}
+
+\NewDocumentCommand\nduBuildSegments{ m > { \SplitArgument { 6 } { . } } m }{%
+ \nduBuildSegments@internal{#1}#2%
+}
+
+\newcommand\nduBuildSegments@internal[8]{%
+ \nduNewUnit@segment{#1}{0}{#2}{#1}%
+ \nduNewUnit@segment{#1}{1}{#3}{#2}%
+ \nduNewUnit@segment{#1}{2}{#4}{#3}%
+ \nduNewUnit@segment{#1}{3}{#5}{#4}%
+ \nduNewUnit@segment{#1}{4}{#6}{#5}%
+ \nduNewUnit@segment{#1}{5}{#7}{#6}%
+ \nduNewUnit@segment{#1}{6}{#8}{#7}%
+}
+
+\newcommand\nduNewUnit@segment[4]{%
+ \IfValueT{#3}{%
+ \nduset{
+ unit groups/#1/segment #2/.is family,unit groups/#1/segment #2,
+ name/.initial=#3,
+ symbol/.link=/ndu/base units/#3/symbol,
+ prefix/.link=/ndu/base units/#3/prefix,
+ suffix/.link=/ndu/base units/#3/suffix,
+ display/.style 2 args={%
+ segment #2/prefix={##1}, % why is the segment needed here ???
+ segment #2/suffix={##2},
+ },
+ factor/.link=/ndu/base units/#4/factors/#3,
+ }%
+ \nduset{%
+ unit groups/#1/update segment depth=#2,
+ }%
+ }%
+}
+
+\NewDocumentCommand\nduNewMacro{ m O{} m }{%
+ \expandafter\NewDocumentCommand\csname#3\endcsname { O{} m } {%
+ \begingroup%
+ \nduset{unit groups/#1,#2}%
+ \nduValue{#1}[##1]{##2}%
+ \endgroup%
+ }%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newcommand\nduName[2]{%
+ \pgfkeysifdefined{/ndu/unit groups/\nduAliasOrGroup{#1}/segment #2/name}{%
+ \pgfkeysvalueof{/ndu/unit groups/\nduAliasOrGroup{#1}/segment #2/name}%
+ }{%
+ \PackageError{non-decimal-units}{No name defined for "\nduAliasOrGroup{#1}" segment #2}{}%
+ \nduNameMissing%
+ }%
+}
+
+\newcommand\nduSymbol[2]{%
+ \pgfkeysifdefined{/ndu/unit groups/\nduAliasOrGroup{#1}/segment #2/symbol}{%
+ \pgfkeysvalueof{/ndu/unit groups/\nduAliasOrGroup{#1}/segment #2/symbol}%
+ }{%
+ \PackageError{non-decimal-units}{No symbol defined for "\nduAliasOrGroup{#1}" segment #2 (\nduName{#1}{#2})}{}%
+ \nduSymbolMissing%
+ }%
+}
+
+\newcommand\nduPrefix[2]{%
+ \pgfkeysifdefined{/ndu/unit groups/\nduAliasOrGroup{#1}/segment #2/prefix}{%
+ \gdef\nduSym{\nduSymbol{\nduAliasOrGroup{#1}}{#2}}%
+ \pgfkeysvalueof{/ndu/unit groups/\nduAliasOrGroup{#1}/segment #2/prefix}%
+ }{%
+ \PackageError{non-decimal-units}{No prefix defined for "\nduAliasOrGroup{#1}" segment #2 (\nduName{#1}{#2})}{}%
+ \nduPrefixMissing%
+ }%
+}
+
+\newcommand\nduSuffix[2]{%
+ \pgfkeysifdefined{/ndu/unit groups/\nduAliasOrGroup{#1}/segment #2/suffix}{%
+ \gdef\nduSym{\nduSymbol{\nduAliasOrGroup{#1}}{#2}}%
+ \pgfkeysvalueof{/ndu/unit groups/\nduAliasOrGroup{#1}/segment #2/suffix}%
+ }{%
+ \PackageError{non-decimal-units}{No suffix defined for "\nduAliasOrGroup{#1}" segment #2 (\nduName{#1}{#2})}{}%
+ \nduSuffixMissing%
+ }%
+}
+
+\newcommand\nduFactor[2]{%
+ \pgfkeysifdefined{/ndu/unit groups/\nduAliasOrGroup{#1}/segment #2/factor}{%
+ \pgfkeysvalueof{/ndu/unit groups/\nduAliasOrGroup{#1}/segment #2/factor}%
+ }{%
+ % Having a PackageError here breaks bigintcalc.
+ \nduFactorMissing@#1@#2%
+ }%
+}
+
+\newcommand\ifnduFactorDefined[4]{%
+ \pgfkeysifdefined{/ndu/base units/\nduName{#1}{\the\numexpr#2-1\relax}/factors/\nduName{#1}{#2}}{%
+ #3%
+ }{%
+ #4%
+ }%
+}
+
+\newcommand\nduNamedFactor[2]{%
+ \pgfkeysifdefined{/ndu/base units/\nduAliasOrGroup{#1}/factors/#2}{%
+ \pgfkeysvalueof{/ndu/base units/\nduAliasOrGroup{#1}/factors/#2}%
+ }{%
+ % Having a PackageError here breaks bigintcalc.
+ \nduFactorMissing@#1@#2%
+ }%
+}
+
+\newcommand\nduSegmentDepth[1]{%
+ \pgfkeysifdefined{/ndu/unit groups/\nduAliasOrGroup{#1}/restrict segment depth}{%
+ \pgfkeysvalueof{/ndu/unit groups/\nduAliasOrGroup{#1}/restrict segment depth}%
+ }{%
+ \pgfkeysvalueof{/ndu/unit groups/\nduAliasOrGroup{#1}/segment depth}%
+ }%
+}
+
+\newcommand\nduAliasOrGroup[1]{%
+ \pgfkeysifdefined{/ndu/aliases/#1/unit group}{%
+ \pgfkeysvalueof{/ndu/aliases/#1/unit group}%
+ }{%
+ #1%
+ }%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newcommand\ndu@if@depth@at@least[3]{%
+ \ifnum#2>\nduSegmentDepth{#1}%
+ \relax%
+ \else%
+ #3%
+ \fi%
+}
+
+\newcommand\ndu@nil@helper[4]{%
+ \IfValueTF{#1}{%
+ \ifblank{#1}{%
+ \ifcsvoid{ndu@nil@replacement}{}{#2\ndu@nil@replacement{}#4}%
+ }{%
+ \ifndutreatzeroasnil%
+ \expandafter\ifnum#1=0
+ \ifcsvoid{ndu@nil@replacement}{}{#2\csuse{ndu@nil@replacement}#4}%
+ \else%
+ #2#3#4%
+ \fi%
+ \else%
+ #2#3#4%
+ \fi%
+ }%
+ }{%
+ \ifcsvoid{ndu@nil@replacement}{}{#2\csuse{ndu@nil@replacement}#4}%
+ }%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\NewDocumentCommand\nduValue{ m O{} m }{%
+ \nduValue@unitgroup{\nduAliasOrGroup{#1}}[#2]{#3}%
+}
+
+\NewDocumentCommand\nduValue@unitgroup{ m O{} m }{%
+ % #1 = unit group
+ % #2 = options
+ % #3 = values joined by .
+ \nduset{unit groups/#1}%
+ \begingroup%
+ \nduset{unit groups/#1,#2}%
+ \ifndualigned%
+ \nduAlignedValue@entry{#1}{#3}%
+ \else%
+ \nduFormatValue@entry{#1}{#3}%
+ \fi%
+ \endgroup%
+ \ifcsvoid{ndu@current@variable}{}{%
+ \nduMath{#1}{\ndu@current@variable}{\ndu@current@operator}{#3}%
+ }%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newcommand\nduFormatSegment[3]{%
+ % #1 = unit group
+ % #2 = segment
+ % #3 = value
+ %\csshow{nduSym}%
+ \ndu@nil@helper{#3}{%
+ \ndu@delim%
+ \ifndushowaffixes\nduPrefix{#1}{#2}\fi%
+ \edef\ndu@delim{\ndu@nextdelim}%
+ }{%
+ \ifndushowvalues#3\fi%
+ }{%
+ \ifndushowaffixes\nduSuffix{#1}{#2}\fi%
+ }%
+}
+
+\newcommand\nduFormatValue@helper[3]{%
+ \ndu@if@depth@at@least{#1}{#2}{%
+ \nduFormatSegment{#1}{#2}{#3}%
+ }%
+}
+
+\newcommand\nduFormatValue@internal[8]{%
+ % #1 = unit group
+ % #2-8 = values
+ \edef\ndu@nextdelim{\pgfkeysvalueof{/ndu/unit groups/#1/segment separator}}%
+ \edef\ndu@delim{}%
+ \nduFormatValue@helper{#1}{0}{#2}%
+ \nduFormatValue@helper{#1}{1}{#3}%
+ \nduFormatValue@helper{#1}{2}{#4}%
+ \nduFormatValue@helper{#1}{3}{#5}%
+ \nduFormatValue@helper{#1}{4}{#6}%
+ \nduFormatValue@helper{#1}{5}{#7}%
+ \nduFormatValue@helper{#1}{6}{#8}%
+}
+
+\NewDocumentCommand\nduFormatValue@entry{ m > { \SplitArgument { 6 } { . } } m }{%
+ % #1 = unit group
+ % #2 = values joined by .
+ \ifndunormalize%
+ \stepcounter{autorepr}%
+ \nduConvertToRepr@internal{#1}{autorepr\arabic{autorepr}}#2%
+ \nduResult{#1}{autorepr\arabic{autorepr}}%
+ \else%
+ \nduFormatValue@internal{#1}#2%
+ \fi%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newcommand*{\ndu@minwidthbox}[2]{%
+ \makebox[{\ifdim#1<\width\width\else#1\fi}][r]{%
+ #2%
+ }%
+}
+
+\newcommand\nduAlignedHeader@helper[2]{%
+ \ndu@if@depth@at@least{#1}{#2}{\ndu@minwidthbox{\pgfkeysvalueof{/ndu/cell width}}{%
+ \nduSymbol{#1}{#2}%
+ }}%
+}
+
+\newcommand\nduAlignedValue@helper[3]{%
+ \ndu@if@depth@at@least{#1}{#2}{\ndu@minwidthbox{\pgfkeysvalueof{/ndu/cell width}}{\nduFormatSegment{#1}{#2}{#3}}}%
+}
+
+\newcommand\nduAlignedValue@internal[8]{%
+ % #1 = unit group
+ % #2-8 = values
+ \nduAlignedValue@helper{#1}{0}{#2}%
+ \nduAlignedValue@helper{#1}{1}{#3}%
+ \nduAlignedValue@helper{#1}{2}{#4}%
+ \nduAlignedValue@helper{#1}{3}{#5}%
+ \nduAlignedValue@helper{#1}{4}{#6}%
+ \nduAlignedValue@helper{#1}{5}{#7}%
+ \nduAlignedValue@helper{#1}{6}{#8}%
+}
+
+\NewDocumentCommand\nduHeader{ m O{} }{%
+ \nduHeader@unitgroup{\nduAliasOrGroup{#1}}[#2]%
+}
+
+\NewDocumentCommand\nduHeader@unitgroup{ m O{} }{%
+ \nduset{unit groups/#1}%
+ \begingroup%
+ \nduset{unit groups/#1,#2}%
+ \nduAlignedHeader@helper{#1}{0}%
+ \nduAlignedHeader@helper{#1}{1}%
+ \nduAlignedHeader@helper{#1}{2}%
+ \nduAlignedHeader@helper{#1}{3}%
+ \nduAlignedHeader@helper{#1}{4}%
+ \nduAlignedHeader@helper{#1}{5}%
+ \nduAlignedHeader@helper{#1}{6}%
+ \endgroup%
+}
+
+\NewDocumentCommand\nduAlignedValue@entry{ m > { \SplitArgument { 6 } { . } } m }{%
+ % #1 = unit group
+ % #2 = values joined by .
+ \begingroup%
+ \nduset{show=values}%
+ \ifndunormalize%
+ \stepcounter{autorepr}%
+ \nduConvertToRepr@internal{#1}{autorepr\arabic{autorepr}}#2%
+ \nduResult{#1}[aligned]{autorepr\arabic{autorepr}}%
+ \else%
+ \nduAlignedValue@internal{#1}#2%
+ \fi%
+ \endgroup%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\newcommand\ndu@val@or@zero[1]{%
+ \IfValueTF{#1}{%
+ \ifblank{#1}{%
+ 0%
+ }{%
+ #1%
+ }%
+ }{%
+ 0%
+ }%
+}
+
+\newcommand\nduConvertToRepr@helper[4]{%
+ % convert from overlying unit and add value
+ % #1 = unit group
+ % #2 = repr name
+ % #3 = segment
+ % #4 = value
+ \ndu@if@depth@at@least{#1}{#3}{%
+ \ifnum#3=0%
+ % no conversion at top level
+ \else%
+ \ifnduFactorDefined{#1}{#3}{%
+ %\show#3%
+ \csxdef{ndu@repr@#2}{\bigintcalcMul{\csuse{ndu@repr@#2}}{\nduFactor{#1}{#3}}}%
+ }{%
+ % there is no factor to the overlying unit
+ % instead attempt to skip ahead to the underlying unit?
+ \PackageError{non-decimal-units}{Cannot convert to representation because there is no conversion factor from \nduName{#1}{\the\numexpr#3-1\relax} to \nduName{#1}{#3}}{}%
+ }%
+ \fi%
+ \csxdef{ndu@repr@#2}{\bigintcalcAdd{\csuse{ndu@repr@#2}}{\ndu@val@or@zero{#4}}}%
+ \csxdef{ndu@repr@#2@unit}{\nduName{#1}{#3}}%
+ }%
+}
+
+\newcommand\nduConvertToRepr@internal[9]{%
+ % #1 = unit group
+ % #2 = repr name
+ % #3-9 = values
+ \csdef{ndu@repr@#2}{0}%
+ \nduConvertToRepr@helper{#1}{#2}{0}{#3}%
+ \nduConvertToRepr@helper{#1}{#2}{1}{#4}%
+ \nduConvertToRepr@helper{#1}{#2}{2}{#5}%
+ \nduConvertToRepr@helper{#1}{#2}{3}{#6}%
+ \nduConvertToRepr@helper{#1}{#2}{4}{#7}%
+ \nduConvertToRepr@helper{#1}{#2}{5}{#8}%
+ \nduConvertToRepr@helper{#1}{#2}{6}{#9}%
+}
+
+\NewDocumentCommand\nduConvertToRepr{ m O{} m > { \SplitArgument { 6 } { . } } m }{%
+ \nduset{unit groups/#1,#2}%
+ \nduConvertToRepr@internal{#1}{#3}#4%
+}
+
+\newcommand\nduFormatRepr@helper[3]{%
+ % V = mod(R, F)
+ % R = div(R - V, F)
+ % #1 = unit group
+ % #2 = repr name
+ % #3 = segment (F)
+ \ndu@if@depth@at@least{#1}{#3}{%
+ \ifnum#3=0%
+ \csxdef{ndu@repr@#2@result@#3}{\csuse{ndu@repr@#2}}%
+ \else%
+ \ifnduFactorDefined{#1}{#3}{%
+ \csxdef{ndu@repr@#2@result@#3}{\bigintcalcMod{\csuse{ndu@repr@#2}}{\nduFactor{#1}{#3}}}%
+ \csxdef{ndu@repr@#2}{\bigintcalcDiv{\bigintcalcSub{\csuse{ndu@repr@#2}}{\csuse{ndu@repr@#2@result@#3}}}{\nduFactor{#1}{#3}}}%
+ }{%
+ % there is no factor to the underlying unit
+ % instead attempt to skip ahead to the overlying unit?
+ \PackageError{non-decimal-units}{Cannot convert from representation because there is no conversion factor from \nduName{#1}{\the\numexpr#3-1\relax} to \nduName{#1}{#3}}{}%
+ }%
+ \fi%
+ }%
+}
+
+\NewDocumentCommand\nduResult{ m O{} m }{%
+ \nduResult@unitgroup{\nduAliasOrGroup{#1}}[#2]{#3}%
+}
+
+\NewDocumentCommand\nduResult@unitgroup{ m O{} m }{%
+ % #1 = unit group
+ % #2 = options
+ % #3 = repr name
+ \nduset{unit groups/#1}%
+ \csdef{ndu@repr@tmp #3}{\csuse{ndu@repr@#3}}%
+ \nduFormatRepr@helper{#1}{tmp #3}{6}%
+ \nduFormatRepr@helper{#1}{tmp #3}{5}%
+ \nduFormatRepr@helper{#1}{tmp #3}{4}%
+ \nduFormatRepr@helper{#1}{tmp #3}{3}%
+ \nduFormatRepr@helper{#1}{tmp #3}{2}%
+ \nduFormatRepr@helper{#1}{tmp #3}{1}%
+ \nduFormatRepr@helper{#1}{tmp #3}{0}%
+ \edef\ndu@nextdelim{\pgfkeysvalueof{/ndu/unit groups/#1/segment separator}}%
+ \edef\ndu@delim{}%
+ \begingroup%
+ \nduset{unit groups/#1,#2}%
+ \ifndualigned%
+ \nduset{show=values}%
+ \nduAlignedValue@helper{#1}{0}{\csuse{ndu@repr@tmp #3@result@0}}%
+ \nduAlignedValue@helper{#1}{1}{\csuse{ndu@repr@tmp #3@result@1}}%
+ \nduAlignedValue@helper{#1}{2}{\csuse{ndu@repr@tmp #3@result@2}}%
+ \nduAlignedValue@helper{#1}{3}{\csuse{ndu@repr@tmp #3@result@3}}%
+ \nduAlignedValue@helper{#1}{4}{\csuse{ndu@repr@tmp #3@result@4}}%
+ \nduAlignedValue@helper{#1}{5}{\csuse{ndu@repr@tmp #3@result@4}}%
+ \nduAlignedValue@helper{#1}{6}{\csuse{ndu@repr@tmp #3@result@4}}%
+ \else%
+ \nduFormatValue@helper{#1}{0}{\csuse{ndu@repr@tmp #3@result@0}}%
+ \nduFormatValue@helper{#1}{1}{\csuse{ndu@repr@tmp #3@result@1}}%
+ \nduFormatValue@helper{#1}{2}{\csuse{ndu@repr@tmp #3@result@2}}%
+ \nduFormatValue@helper{#1}{3}{\csuse{ndu@repr@tmp #3@result@3}}%
+ \nduFormatValue@helper{#1}{4}{\csuse{ndu@repr@tmp #3@result@4}}%
+ \nduFormatValue@helper{#1}{5}{\csuse{ndu@repr@tmp #3@result@4}}%
+ \nduFormatValue@helper{#1}{6}{\csuse{ndu@repr@tmp #3@result@4}}%
+ \fi%
+ \endgroup%
+}
+
+\newcommand\nduMath[4]{%
+ \nduMath@unitgroup{\nduAliasOrGroup{#1}}{#2}{#3}{#4}%
+}
+
+\newcommand\nduMath@unitgroup[4]{%
+ % #1 = unit group
+ % #2 = repr name
+ % #3 = operator
+ % #4 = value
+ \nduset{unit groups/#1}%
+ \ifcsvoid{ndu@repr@#2}{\csxdef{ndu@repr@#2}{0}}{}%
+ \ifthenelse{\equal{#3}{+}}{%
+ \nduConvertToRepr{#1}{tmp #2}{#4}%
+ \csxdef{ndu@repr@#2}{\bigintcalcAdd{\csuse{ndu@repr@#2}}{\csuse{ndu@repr@tmp #2}}}%
+ }{%
+ \ifthenelse{\equal{#3}{-}}{%
+ \nduConvertToRepr{#1}{tmp #2}{#4}%
+ \csxdef{ndu@repr@#2}{\bigintcalcSub{\csuse{ndu@repr@#2}}{\csuse{ndu@repr@tmp #2}}}%
+ }{%
+ \ifthenelse{\equal{#3}{*}}{%
+ \csxdef{ndu@repr@#2}{\bigintcalcMul{\csuse{ndu@repr@#2}}{#4}}%
+ }{%
+ \ifthenelse{\equal{#3}{/}}{%
+ \csxdef{ndu@repr@#2}{\bigintcalcDiv{\csuse{ndu@repr@#2}}{#4}}%
+ }{%
+ \PackageError{non-decimal-units}{Unrecognized math operator: #3}{Only + - * / are allowed.}%
+ }%
+ }%
+ }%
+ }%
+}
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\nduset{
+ options/.cd,
+ british/.code={\input{non-decimal-units.british}},
+ danish/.code={\input{non-decimal-units.danish}},
+}
+
+\ProcessPgfPackageOptions{/ndu/options}