summaryrefslogtreecommitdiff
path: root/macros/generic
diff options
context:
space:
mode:
authorNorbert Preining <norbert@preining.info>2021-07-16 03:01:07 +0000
committerNorbert Preining <norbert@preining.info>2021-07-16 03:01:07 +0000
commit01b14a20f8942ab0c52aeb8abffa85b811c7a95a (patch)
tree2db57d63324f0141577f40d9e8a8a035b131e176 /macros/generic
parent55ae461252a599d6bc951065a37c16a8971fc560 (diff)
CTAN sync 202107160301
Diffstat (limited to 'macros/generic')
-rw-r--r--macros/generic/expkv/README.md2
-rw-r--r--macros/generic/expkv/expkv.dtx169
-rw-r--r--macros/generic/expkv/expkv.pdfbin480586 -> 487605 bytes
-rw-r--r--macros/generic/texdimens/README.md177
-rw-r--r--macros/generic/texdimens/texdimens.sty2
-rw-r--r--macros/generic/texdimens/texdimens.tex238
6 files changed, 307 insertions, 281 deletions
diff --git a/macros/generic/expkv/README.md b/macros/generic/expkv/README.md
index a402daa774..8c241c4217 100644
--- a/macros/generic/expkv/README.md
+++ b/macros/generic/expkv/README.md
@@ -1,7 +1,7 @@
-------------------------------------------------------------------------------
# expkv -- an expandable key=val implementation
-Version 2021-06-03 v1.8a
+Version 2021-07-15 v1.9
Released under the LaTeX Project Public License v1.3c or later
See http://www.latex-project.org/lppl.txt
diff --git a/macros/generic/expkv/expkv.dtx b/macros/generic/expkv/expkv.dtx
index 283cd0353d..da6fcf2542 100644
--- a/macros/generic/expkv/expkv.dtx
+++ b/macros/generic/expkv/expkv.dtx
@@ -421,7 +421,7 @@ and the derived files expkv.pdf
% \end{function}
% \example Define |text| in |foo| to store the value inside |\foo@text|:
% \begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
-% \protected\long\ekvdef{foo}{text}{\def\foo@width{#1}}
+% \protected\long\ekvdef{foo}{text}{\def\foo@text{#1}}
% \end{lstlisting}
%
% \begin{function}{\ekvdefNoVal}
@@ -440,7 +440,8 @@ and the derived files expkv.pdf
% \cs{ekvlet}\marg{set}\marg{key}\meta{cs}
% \end{syntax}
% Let the value taking \key\ in \set\ to \meta{cs}, there are no checks on
-% \meta{cs} enforced.
+% \meta{cs} enforced, but the code should expect the value as a single braced
+% argument directly following it.
% \end{function}
% \example Let |cmd| in |foo| do the same as |\foo@cmd|:
% \begin{lstlisting}[aboveskip=0pt,belowskip=0pt]
@@ -811,7 +812,8 @@ and the derived files expkv.pdf
% argument will be wrapped in braces, the mandatory argument will be
% untouched). If there was no optional argument the result will be
% \meta{next}\marg{default}\marg{mandatory} (so the default will be used and
-% the mandatory argument will be wrapped in braces).
+% the mandatory argument will be wrapped in braces after being read once -- if
+% it was already wrapped it is effectively unchanged).
% \end{function}
% |\ekvoptarg| expands in exactly two steps, grabs all the arguments only at the
% second expansion step, and is alignment safe. It has its limitations however.
@@ -845,6 +847,43 @@ and the derived files expkv.pdf
% \newcommand\foo@b[1]{Mandatory: #1\par No optional.}
% \end{lstlisting}
%
+% \begin{function}{\ekvcsvloop}
+% \begin{syntax}
+% \cs{ekvcsvloop}\marg{code}\marg{csv-list}
+% \end{syntax}
+% This loops over the comma separated items in \meta{csv-list} and, after
+% stripping spaces from either end of \meta{item} and removing at most one set
+% of outer braces, leaves
+% \texttt
+% {^^A
+% \cs[no-index]{unexpanded}\hskip0pt
+% \{\hskip0pt
+% \meta{code}\hskip0pt
+% \marg{item}\hskip0pt
+% \}^^A
+% }
+% for each list item in the input stream. Blank elements are ignored (if you
+% need a blank element it should be given as |{}|). It supports both active
+% commas and commas of category other. You could consider it as a watered down
+% version of |\ekvparse|. However it is not alignment safe, which you could
+% achieve by nesting it in |\expanded| (since the braces around the argument
+% of |\expanded| will hide |&|s from \TeX's alignment parsing).
+% \end{function}
+% \example The following splits a comma separated list and prints it in a
+% typewriter font with parentheses around each element.\\
+% \begin{minipage}{.75\linewidth}
+% \begin{lstlisting}
+% \newcommand*\myprocessor[1]{\texttt{(#1)}}
+% \ekvcsvloop\myprocessor{abc,def,ghi}\par
+% \ekvcsvloop\myprocessor{1,,2,,3,,4}\par
+% \end{lstlisting}
+% \end{minipage}^^A
+% \begin{exresult}[nobeforeafter,box align=center]{.25\linewidth}
+% \newcommand*\myprocessor[1]{\texttt{(#1)}}
+% \ekvcsvloop\myprocessor{abc,def,ghi}\par
+% \ekvcsvloop\myprocessor{1,,2,,3,,4}\par
+% \end{exresult}
+%
% \begin{function}{\ekverr}
% \begin{syntax}
% \cs{ekverr}\marg{package}\marg{message}
@@ -1554,8 +1593,8 @@ and the derived files expkv.pdf
% \begin{macro}{\ekvVersion,\ekvDate}
% We're on our first input, so lets store the version and date in a macro.
% \begin{macrocode}
-\def\ekvVersion{1.8a}
-\def\ekvDate{2021-06-03}
+\def\ekvVersion{1.9}
+\def\ekvDate{2021-07-15}
% \end{macrocode}
% \end{macro}
%
@@ -1762,35 +1801,73 @@ and the derived files expkv.pdf
% \end{macrocode}
% \end{macro}
%
-% \begin{macro}[internal]{\ekv@csv@loop,\ekv@csv@loop@do,\ekv@csv@loop@end}
-% This is just a very simple loop over a list of comma separated values,
-% leaving each element as the argument to a specified function inside of
-% |\unravel|. It should be used as
-% \texttt
-% {^^A
-% \cs[no-index]{ekv@csv@loop}\hskip0pt^^A
-% \marg{function}\hskip0pt^^A
-% \cs[no-index]{ekv@mark}\hskip0pt^^A
-% \meta{csv-list}\hskip0pt^^A
-% ,\cs[no-index]{ekv@stop},^^A
-% }.
-% We use some |\expandafter| chain to preexpand |\ekv@strip| here.
-% \begin{macrocode}
-\ekv@exparg{\long\def\ekv@csv@loop#1#2,}%
+% \begin{macro}{\ekvcsvloop}
+% \begin{macro}[internal]{\ekv@csv@loop@active,\ekv@csv@loop@active@end}
+% An |\ekvcsvloop| will just loop over a csv list in a simple manner. First we
+% split at active commas (gives better performance this way), next we have to
+% check whether we're at the end of the list (checking for |\ekv@stop|). If
+% not we go on splitting at commas of category other.
+% \begin{macrocode}
+\begingroup
+\def\ekvcsvloop#1{%
+\endgroup
+\long\def\ekvcsvloop##1##2%
+ {\ekv@csv@loop@active{##1}\ekv@mark##2#1\ekv@stop#1}
+% \end{macrocode}
+% This does the same as |\ekv@csv@loop| but for active commas.
+% \begin{macrocode}
+\long\def\ekv@csv@loop@active##1##2#1%
{%
- \expandafter
- \ekv@gobble@from@mark@to@stop
- \expandafter#\expandafter2\expandafter\ekv@csv@loop@end\expandafter
+ \ekv@gobble@from@mark@to@stop##2\ekv@csv@loop@active@end\ekv@stop
+ \ekv@csv@loop{##1}##2,\ekv@stop,%
+ }%
+\long\def\ekv@csv@loop@active@end
\ekv@stop
- \ekv@strip{#2}{\ekv@csv@loop@do{#1}}%
- \ekv@csv@loop{#1}\ekv@mark
+ \ekv@csv@loop##1\ekv@mark\ekv@stop,\ekv@stop,%
+ {}%
+}
+% \end{macrocode}
+% Do the definitions with the weird catcode.
+% \begin{macrocode}
+\catcode`\,=13
+\ekvcsvloop,
+% \end{macrocode}
+% \end{macro}
+% \end{macro}
+%
+% \begin{macro}[internal]{\ekv@csv@loop,\ekv@csv@loop@do,\ekv@csv@loop@end}
+% We use temporary macros and an |\expandafter| chain to preexpand
+% |\ekv@strip| here. After splitting at other commas we check again for end
+% the end of the sublist, check for blank elements which should be ignored,
+% and else strip spaces and execute the user code (protecting it from further
+% expanding with |\unexpanded|).
+% \begin{macrocode}
+\def\ekv@csv@loop#1%
+ {%
+ \long\def\ekv@csv@loop##1##2,%
+ {%
+ \ekv@gobble@from@mark@to@stop##2\ekv@csv@loop@end\ekv@stop
+ \ekv@ifblank@##2\ekv@nil\ekv@ifempty@B\ekv@csv@loop@blank
+ \ekv@ifempty@A\ekv@ifempty@B
+ #1\ekv@csv@loop@do{##1}%
+ }%
}
-\long\def\ekv@csv@loop@do#1#2{\unexpanded{#1{#2}}}
-\long\expandafter\def\expandafter\ekv@csv@loop@end
- \expandafter\ekv@stop
- \ekv@strip{#1}#2%
- \ekv@csv@loop#3\ekv@mark
- {}
+\expandafter\ekv@csv@loop\expandafter{\ekv@strip{#2}}
+\long\def\ekv@csv@loop@do#1#2{\unexpanded{#2{#1}}\ekv@csv@loop{#2}\ekv@mark}
+\def\ekv@csv@loop@end#1%
+ {%
+ \long\def\ekv@csv@loop@end
+ \ekv@stop
+ \ekv@ifblank@\ekv@mark\ekv@stop\ekv@nil\ekv@ifempty@B\ekv@csv@loop@blank
+ \ekv@ifempty@A\ekv@ifempty@B
+ #1\ekv@csv@loop@do##1%
+ {\ekv@csv@loop@active{##1}\ekv@mark}%
+ }
+\expandafter\ekv@csv@loop@end\expandafter{\ekv@strip{\ekv@mark\ekv@stop}}
+\long\expandafter\def\expandafter\ekv@csv@loop@blank
+ \expandafter\ekv@ifempty@A\expandafter\ekv@ifempty@B
+ \ekv@strip{\ekv@mark#1}\ekv@csv@loop@do#2%
+ {\ekv@csv@loop{#2}\ekv@mark}
% \end{macrocode}
% \end{macro}
%
@@ -1969,9 +2046,9 @@ and the derived files expkv.pdf
\begingroup
\edef\ekv@tmp
{%
- \ekv@csv@loop#1\ekv@mark#6,\ekv@stop,%
+ \ekvcsvloop#1{#6}%
\unexpanded{#2}%
- {\ekv@csv@loop{}\ekv@mark#5,#6,\ekv@stop,}%
+ {\ekvcsvloop{}{#5,#6}}%
}%
\ekv@expargtwice
{\endgroup#3{#5}}%
@@ -2690,7 +2767,10 @@ and the derived files expkv.pdf
% possibilities (they don't care for nested bracket levels).
%
% We start with a temporary definition to pre-expand |\ekv@alignsafe| (will be
-% |#1|) and |\ekv@endalignsafe| (will be |#2|).
+% |#1|) and |\ekv@endalignsafe| (will be |#2|). As |\ekv@alignsafe| starts with
+% a |\romannumeral| we use that to also control the number of steps needed
+% instead of adding another |\romannumeral|. For this we have to remove the
+% space token from the end of |\ekv@alignsafe|'s definition.
% \begin{macrocode}
\begingroup
\def\ekvoptarg#1#2{%
@@ -2702,24 +2782,24 @@ and the derived files expkv.pdf
% bracket, if it is found grab the optional argument, else leave |#1{#2}| in the
% input stream after ending the expansion context.
% \begin{macrocode}
-\def\ekvoptarg{\romannumeral#1\ekv@optarg@a}
+\def\ekvoptarg{#1\ekv@optarg@a}
\long\def\ekv@optarg@a##1##2##3%
{%
\ekv@optarg@if\ekv@mark##3\ekv@mark\ekv@optarg@b\ekv@mark[\ekv@mark
#2%
- \@firstofone{\ekv@zero##1}{##2}{##3}%
+ \@firstofone{ ##1}{##2}{##3}%
}%
% \end{macrocode}
% The other variant of this will do roughly the same. Here, |#1| will be the
% next step if an optional argument is found, |#2| the next step else, and |#3|
% might be the opening bracket or mandatory argument.
% \begin{macrocode}
-\def\ekvoptargTF{\romannumeral#1\ekv@optargTF@a}
+\def\ekvoptargTF{#1\ekv@optargTF@a}
\long\def\ekv@optargTF@a##1##2##3%
{%
\ekv@optarg@if\ekv@mark##3\ekv@mark\ekv@optargTF@b{##1}\ekv@mark[\ekv@mark
#2%
- \@firstofone{\ekv@zero##2}{##3}%
+ \@firstofone{ ##2}{##3}%
}
% \end{macrocode}
% The two macros to grab the optional argument have to remove the remainder of
@@ -2729,12 +2809,19 @@ and the derived files expkv.pdf
{#2##2{##5}}
\long\def\ekv@optargTF@b
##1\ekv@mark[\ekv@mark\ifnum`##2\fi\@firstofone##3##4##5]%
- {#2\ekv@zero##1{##5}}
+ {#2 ##1{##5}}
}
% \end{macrocode}
-% Do the definitions and add the test macro.
+% Do the definitions and add the test macro. We use |\ekv@strip| to remove the
+% trailing space from the definition of |\ekv@alignsafe|.
% \begin{macrocode}
-\ekv@exparg{\expandafter\ekvoptarg\expandafter{\ekv@alignsafe}}\ekv@endalignsafe
+\ekv@exparg
+ {%
+ \expandafter\ekv@strip\expandafter
+ {\expandafter\ekv@mark\ekv@alignsafe}%
+ \ekvoptarg
+ }%
+ \ekv@endalignsafe
\long\def\ekv@optarg@if#1\ekv@mark[\ekv@mark{}
% \end{macrocode}
% \end{macro}
diff --git a/macros/generic/expkv/expkv.pdf b/macros/generic/expkv/expkv.pdf
index c72c22153a..59012eccd1 100644
--- a/macros/generic/expkv/expkv.pdf
+++ b/macros/generic/expkv/expkv.pdf
Binary files differ
diff --git a/macros/generic/texdimens/README.md b/macros/generic/texdimens/README.md
index 401dea828f..4f028fe689 100644
--- a/macros/generic/texdimens/README.md
+++ b/macros/generic/texdimens/README.md
@@ -10,6 +10,8 @@ LPPL 1.3c. See file LICENSE.md.
Development: https://github.com/jfbu/texdimens
+Release: `0.9delta 2021/07/15`
+
## Aim of this package
Utilities and documentation related to TeX dimensional units, usable
@@ -170,33 +172,32 @@ the `pt`.
## Macros of this package
-All macros are expandable. At time of writing they may not be
-f-expandable, but (perhaps) in future final versions will expand fully
-in two steps. This refinement is anyhow not really important as TeX
-engines now support the `\expanded` primitive.
-
-Negative dimensions behave as if replaced by their absolute value, then
-at last step the sign (if result is not zero) is applied.
+The macros defined by the package are expandable, and will expand
+completely in an `\edef`, or in a `\dimexpr...\relax` construc.
+As they parse their inputs via `\dimexpr` they can be nested (with
+suitable postfix dimension unit added to inner macro).
-1. For input `X` equal to (or sufficiently close to)
-`\maxdimen` and those units `uu` for which `\maxdimen` is not exactly
-representable (i.e. all units except `pt`, `bp` and `nd`), the output `D`
-of the "up" macros `\texdimin<uu>up{X}`, if used as `Duu` in a dimension
-assignment or expression, will (naturally) trigger a "Dimension too large"
-error.
+Apart for the `\texdimin<uu>up` in case of a negative input, they will
+even expand completely under f-expansion.
+Negative dimensions behave as if replaced by their absolute value, then
+at last step the sign (if result is not zero) is applied (so "down" means
+"towards zero", and "up" means "away from zero").
+
+1. For input `X` equal to (or sufficiently close to) `\maxdimen` and
+ those units `uu` for which `\maxdimen` is not exactly representable
+ (i.e. all units except `pt`, `bp` and `nd`), the output `D` of the
+ "up" macros `\texdimin<uu>up{X}`, if used as `Duu` in a dimension
+ assignment or expression, will (naturally) trigger a "Dimension too
+ large" error.
2. For `dd`, `nc` and `in`, and input `X` equal to (or sufficiently
-close to) `\maxdimen` it turns out that `\texdimin<uu>{X}` produces an
-output `D` such that `Duu` is the first "virtually attainable" TeX
-dimension *beyond* `\maxdimen`. Hence `Duu` will trigger on use
-"Dimension too large error".
-
-3. For some units the "down" and "up" macros may trigger
-"Dimension too large" during their execution if used with an input too
-close to `\maxdimen`. "Safe" variants which are guaranteed never to
-trigger this error but have some extra overhead to filter out inputs too
-close to `\maxdimen` will *perhaps* be provided. But
-see 1. and 2. regarding the usability of the output anyhow.
+ close to) `\maxdimen` it turns out that `\texdimin<uu>{X}` produces
+ an output `D` such that `Duu` is the first "virtually attainable" TeX
+ dimension *beyond* `\maxdimen`. Hence `Duu` will trigger on use
+ "Dimension too large error".
+3. Again for the `dd`, `nc` and `in` units, both the "down" and "up" macros
+ will trigger "Dimension too large" during their execution if used
+ with an input equal to (or sufficiently close to `\maxdimen`.
`\texdiminpt{<dim. expr.>}`
@@ -204,8 +205,8 @@ see 1. and 2. regarding the usability of the output anyhow.
`\texdiminbp{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> bp` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D bp`
+> represents the dimension exactly if possible. If not possible it
> will differ by `1sp` from the original dimension, but it is not
> known in advance if it will be above or below.
@@ -213,20 +214,20 @@ see 1. and 2. regarding the usability of the output anyhow.
`\texdiminbpdown{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> bp` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D bp`
+> represents the dimension exactly if possible. If not possible it
> will be smaller by `1sp` from the original dimension.
`\texdiminbpup{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> bp` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D bp`
+> represents the dimension exactly if possible. If not possible it
> will be larger by `1sp` from the original dimension.
-`\texdiminndown{<dim. expr.>}`
+`\texdiminnd{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> nd` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D nd`
+> represents the dimension exactly if possible. If not possible it
> will differ by `1sp` from the original dimension, but it is not
> known in advance if it will be above or below.
@@ -234,20 +235,20 @@ see 1. and 2. regarding the usability of the output anyhow.
`\texdiminnddown{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> nd` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D nd`
+> represents the dimension exactly if possible. If not possible it
> will be smaller by `1sp` from the original dimension.
`\texdiminndup{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> nd` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D nd`
+> represents the dimension exactly if possible. If not possible it
> will be larger by `1sp` from the original dimension.
-`\texdiminddown{<dim. expr.>}`
+`\texdimindd{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> dd` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D dd`
+> represents the dimension exactly if possible. If not possible it
> will differ by `1sp` from the original dimension, but it is not
> known in advance if it will be above or below.
@@ -257,20 +258,20 @@ see 1. and 2. regarding the usability of the output anyhow.
`\texdimindddown{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> dd` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D dd`
+> represents the dimension exactly if possible. If not possible it
> will be smaller by `1sp` from the original dimension.
`\texdiminddup{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> dd` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D dd`
+> represents the dimension exactly if possible. If not possible it
> will be larger by `1sp` from the original dimension.
`\texdiminmm{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> mm` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D mm`
+> represents the dimension exactly if possible. If not possible it
> will either be the closest from below or from above, but it is not
> known in advance which one (and it is not known if the other choice
> would have been closer).
@@ -280,20 +281,20 @@ see 1. and 2. regarding the usability of the output anyhow.
`\texdiminmmdown{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> mm` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D mm`
+> represents the dimension exactly if possible. If not possible it
> will be largest representable dimension smaller than the original one.
`\texdiminmmup{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> mm` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D mm`
+> represents the dimension exactly if possible. If not possible it
> will be smallest representable dimension larger than the original one.
`\texdiminpc{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> pc` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D pc`
+> represents the dimension exactly if possible. If not possible it
> will be the closest representable one (in case of tie, the approximant
> from above is chosen).
@@ -302,20 +303,20 @@ see 1. and 2. regarding the usability of the output anyhow.
`\texdiminpcdown{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> pc` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D pc`
+> represents the dimension exactly if possible. If not possible it
> will be largest representable dimension smaller than the original one.
`\texdiminpcup{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> pc` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D pc`
+> represents the dimension exactly if possible. If not possible it
> will be smallest representable dimension larger than the original one.
`\texdiminnc{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> nc` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D nc`
+> represents the dimension exactly if possible. If not possible it
> will either be the closest from below or from above, but it is not
> known in advance which one (and it is not known if the other choice
> would have been closer).
@@ -326,20 +327,20 @@ see 1. and 2. regarding the usability of the output anyhow.
`\texdiminncdown{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> nc` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D nc`
+> represents the dimension exactly if possible. If not possible it
> will be largest representable dimension smaller than the original one.
`\texdiminncup{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> nc` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D nc`
+> represents the dimension exactly if possible. If not possible it
> will be smallest representable dimension larger than the original one.
`\texdimincc{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> cc` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D cc`
+> represents the dimension exactly if possible. If not possible it
> will either be the closest from below or from above, but it is not
> known in advance which one (and it is not known if the other choice
> would have been closer).
@@ -349,20 +350,20 @@ see 1. and 2. regarding the usability of the output anyhow.
`\texdiminccdown{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> cc` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D cc`
+> represents the dimension exactly if possible. If not possible it
> will be largest representable dimension smaller than the original one.
`\texdiminccup{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> cc` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D cc`
+> represents the dimension exactly if possible. If not possible it
> will be smallest representable dimension larger than the original one.
`\texdimincm{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> cm` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D cm`
+> represents the dimension exactly if possible. If not possible it
> will either be the closest from below or from above, but it is not
> known in advance which one (and it is not known if the other choice
> would have been closer).
@@ -372,20 +373,20 @@ see 1. and 2. regarding the usability of the output anyhow.
`\texdimincmdown{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> cm` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D cm`
+> represents the dimension exactly if possible. If not possible it
> will be largest representable dimension smaller than the original one.
`\texdimincmup{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> cm` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D cm`
+> represents the dimension exactly if possible. If not possible it
> will be smallest representable dimension larger than the original one.
`\texdiminin{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> in` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D in`
+> represents the dimension exactly if possible. If not possible it
> will either be the closest from below or from above, but it is not
> known in advance which one (and it is not known if the other choice
> would have been closer).
@@ -396,21 +397,31 @@ see 1. and 2. regarding the usability of the output anyhow.
`\texdiminindown{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> in` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D in`
+> represents the dimension exactly if possible. If not possible it
> will be largest representable dimension smaller than the original one.
`\texdimininup{<dim. expr.>}`
-> Produces a decimal (with up to five decimal places) `D` such that `D
-> in` represents the dimension exactly if possible. If not possible it
+> Produces a decimal (with up to five decimal places) `D` such that `D in`
+> represents the dimension exactly if possible. If not possible it
> will be smallest representable dimension larger than the original one.
-## TODO
+## Extras?
+
+As already stated the "up" and also the "down" macros for the `dd`, `nc`
+and `in` units will trigger "Dimension too large" if used with inputs
+equal to or very near `\maxdimen`. "Safe" variants which are guaranteed
+never to trigger this error but have some extra overhead to filter out
+inputs very close to `\maxdimen` will *perhaps* be provided if there is
+some demand for it.
-Currently (most) macros require exhaustive expansion.
+But of course anyhow the output from the "up" macros if used
+as input with the corresponding unit will be beyond `\maxdimen` if the
+latter is not atteignable, i.e. for all units except `bp`, and `nd`
+(and `pt` but there is no "up" macro for it).
-Provide a macro `\texdimnearest{in,cm}{<dim.expr.>}` which would output
+Provide a macro `\texdimforbothincm{<dim.expr.>}` which would output
the nearest dimension simultaneously representable both in `in` and in
`cm`?
diff --git a/macros/generic/texdimens/texdimens.sty b/macros/generic/texdimens/texdimens.sty
index 9aa422cb55..dbf39c72f8 100644
--- a/macros/generic/texdimens/texdimens.sty
+++ b/macros/generic/texdimens/texdimens.sty
@@ -1,5 +1,5 @@
% This is file texdimens.tex, part of texdimens package, which
% is distributed under the LPPL 1.3c. Copyright (c) 2021 Jean-François Burnol
-\ProvidesPackage{texdimens}[2021/07/14 v0.9gamma conversion of TeX dimensions to decimals (JFB)]
+\ProvidesPackage{texdimens}[2021/07/15 v0.9delta conversion of TeX dimensions to decimals (JFB)]
\@@input texdimens.tex\relax
\endinput \ No newline at end of file
diff --git a/macros/generic/texdimens/texdimens.tex b/macros/generic/texdimens/texdimens.tex
index 7068d57db9..189caca95d 100644
--- a/macros/generic/texdimens/texdimens.tex
+++ b/macros/generic/texdimens/texdimens.tex
@@ -1,9 +1,13 @@
% This is file texdimens.tex, part of texdimens package, which
% is distributed under the LPPL 1.3c. Copyright (c) 2021 Jean-François Burnol
-% 2021/07/14 v0.9gamma
+% 2021/07/15 v0.9delta
\edef\texdimensendinput{\endlinechar\the\endlinechar\catcode`\noexpand _=\the\catcode`\_\relax\noexpand\endinput}%
\endlinechar13\relax%
\catcode`\_=11
+%
+% Mathematics
+% ===========
+%
% Is T sp attainable from unit "uu"?. Here we suppose T>0.
% phi>1, psi=1/phi, psi<1
% U(N,phi)=trunc(N phi) is strictly increasing
@@ -119,211 +123,135 @@
% applies, i.e. the units uu > 2pt (phi>2, psi<1/2), i.e.
% all units except bp, nd and dd.
%
-\def\texdimfirstofone#1{#1}%
+% Implementation
+% ==============
+%
+\def\texdimenfirstofone#1{#1}%
+{\catcode`p 12\catcode`t 12
+ \csname expandafter\endcsname\gdef\csname texdimenstrippt\endcsname#1pt{#1}}%
+%
+% down macros:
+% for units with phi < 2:
+\def\texdimendown_A#1{\if-#1\texdimendown_neg\fi\texdimendown_B#1}%
+\def\texdimendown_B#1;#2;{\expandafter\texdimendown_c\the\numexpr(2*#1+1)#2;#1;}%
+% for units with phi > 2:
+\def\texdimendown_a#1{\if-#1\texdimendown_neg\fi\texdimendown_b#1}%
+\def\texdimendown_b#1;#2;{\expandafter\texdimendown_c\the\numexpr#1#2;#1;}%
+% shared macros:
+\def\texdimendown_c#1;{\expandafter\texdimendown_d\the\dimexpr#1sp;#1;}%
+{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdimendown_d#1PT};#2;#3;#4;%
+ {\ifdim#1#4>#3sp \texdimendown_e{#2}\fi\texdimenfirstofone{#1}}%
+}%
% this #2 will be \fi
-\def\texdiminuudown_e#1#2#3#4{#2\expandafter\texdiminpt_\the\dimexpr\numexpr(#1-1)sp\relax}%
-\def\texdiminuuup_e#1#2#3#4{#2\expandafter\texdiminpt_\the\dimexpr\numexpr(#1+1)sp\relax}%
-% this #1 will be \fi
-\def\texdiminuuup_neg#1#2-{#1-#2}%
+\def\texdimendown_e#1#2#3#4{#2\expandafter\texdimenstrippt\the\dimexpr\numexpr#1-1sp\relax}%
+% negative branch:
+% The problem here is that if input very small, output can be 0.0, and we
+% do not want -0.0 as output.
+% So let's do this somewhat brutally and non-efficiently.
+% Anyhow, negative inputs are not our priority.
+% #1 is \fi here and #2 is \texdimendown_b or _B:
+\def\texdimendown_neg#1#2-#3;#4;#5;{#1\expandafter\texdimenstrippt\the\dimexpr-#2#3;#4;#5;pt\relax}%
+%
+% up macros:
+\def\texdimenup_A#1{\if-#1\texdimenup_neg\fi\texdimenup_B#1}%
+\def\texdimenup_B#1;#2;{\expandafter\texdimenup_c\the\numexpr(2*#1+1)#2;#1;}%
+\def\texdimenup_a#1{\if-#1\texdimenup_neg\fi\texdimenup_b#1}%
+\def\texdimenup_b#1;#2;{\expandafter\texdimenup_c\the\numexpr#1#2;#1;}%
+\def\texdimenup_c#1;{\expandafter\texdimenup_d\the\dimexpr#1sp;#1;}%
+{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdimenup_d#1PT};#2;#3;#4;%
+ {\ifdim#1#4<#3sp \texdimenup_e{#2}\fi\texdimenfirstofone{#1}}%
+}%
+% this #2 will be \fi
+\def\texdimenup_e#1#2#3#4{#2\expandafter\texdimenstrippt\the\dimexpr\numexpr#1+1sp\relax}%
+% negative branch:
+% Here we can me more expeditive than for the "down" macros.
+% But this breaks f-expandability.
+% #1 will be \fi and #2 is \texdimenup_b or _B:
+\def\texdimenup_neg#1#2-{#1-#2}%
%
% pt
%
-\def\texdiminpt#1{\expandafter\texdiminpt_\the\dimexpr#1\relax}%
-{\catcode`p 12\catcode`t 12\csname expandafter\endcsname\gdef\csname texdiminpt_\endcsname#1pt{#1}}%
+\def\texdiminpt#1{\expandafter\texdimenstrippt\the\dimexpr#1\relax}%
%
% bp 7227/7200 = 803/800
%
\def\texdiminbp#1{\expandafter\texdiminbp_\the\numexpr\dimexpr#1;}%
-\def\texdiminbp_#1#2;{\texdiminpt{\numexpr(2*#1#2+\if-#1-\fi1)*400/803sp}}%
-% \texdiminbpdown: maximal dim exactly expressible in bp and at most equal to input
-\def\texdiminbpdown#1{\expandafter\texdiminbpdown_a\the\numexpr\dimexpr#1;}%
-\def\texdiminbpdown_a#1{\if-#1\texdiminbpdown_neg\fi\texdiminbpdown_b#1}%
-\def\texdiminbpdown_b#1;{\expandafter\texdiminbpdown_c\the\numexpr(2*#1+1)*400/803;#1;}%
-\def\texdiminbpdown_c#1;{\expandafter\texdiminbpdown_d\the\dimexpr#1sp;#1;}%
-{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdiminbpdown_d#1PT};#2;#3;%
- {\ifdim#1bp>#3sp \texdiminuudown_e{#2}\fi\texdimfirstofone{#1}}%
+\def\texdiminbp_#1#2;{%
+ \expandafter\texdimenstrippt\the\dimexpr\numexpr(2*#1#2+\if-#1-\fi1)*400/803sp\relax
}%
-% The problem here is that if close to 0sp, output can be 0.0, and we do not want
-% -0.0 as output. So let's do this somewhat brutally. Anyhow, negative inputs are
-% not our priority. #1 is \fi here:
-\def\texdiminbpdown_neg#1#2-#3;{#1\expandafter\texdiminpt_\the\dimexpr-\texdiminbpdown_b#3;pt\relax}%
+% \texdiminbpdown: maximal dim exactly expressible in bp and at most equal to input
+\def\texdiminbpdown#1{\expandafter\texdimendown_A\the\numexpr\dimexpr#1;*400/803;bp;}%
% \texdiminbpup: minimal dim exactly expressible in bp and at least equal to input
-\def\texdiminbpup#1{\expandafter\texdiminbpup_a\the\numexpr\dimexpr#1;}%
-\def\texdiminbpup_a#1{\if-#1\texdiminuuup_neg\fi\texdiminbpup_b#1}%
-\def\texdiminbpup_b#1;{\expandafter\texdiminbpup_c\the\numexpr(2*#1+1)*400/803;#1;}%
-\def\texdiminbpup_c#1;{\expandafter\texdiminbpup_d\the\dimexpr#1sp;#1;}%
-{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdiminbpup_d#1PT};#2;#3;%
- {\ifdim#1bp<#3sp \texdiminuuup_e{#2}\fi\texdimfirstofone{#1}}%
-}%
+\def\texdiminbpup#1{\expandafter\texdimenup_A\the\numexpr\dimexpr#1;*400/803;bp;}%
%
% nd 685/642
%
\def\texdiminnd#1{\expandafter\texdiminnd_\the\numexpr\dimexpr#1;}%
-\def\texdiminnd_#1#2;{\texdiminpt{\numexpr(2*#1#2+\if-#1-\fi1)*321/685sp}}%
-% \texdiminnddown: maximal dim exactly expressible in nd and at most equal to input
-\def\texdiminnddown#1{\expandafter\texdiminnddown_a\the\numexpr\dimexpr#1;}%
-\def\texdiminnddown_a#1{\if-#1\texdiminnddown_neg\fi\texdiminnddown_b#1}%
-\def\texdiminnddown_b#1;{\expandafter\texdiminnddown_c\the\numexpr(2*#1+1)*321/685;#1;}%
-\def\texdiminnddown_c#1;{\expandafter\texdiminnddown_d\the\dimexpr#1sp;#1;}%
-{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdiminnddown_d#1PT};#2;#3;%
- {\ifdim#1nd>#3sp \texdiminuudown_e{#2}\fi\texdimfirstofone{#1}}%
+\def\texdiminnd_#1#2;{%
+ \expandafter\texdimenstrippt\the\dimexpr\numexpr(2*#1#2+\if-#1-\fi1)*321/685sp\relax
}%
-\def\texdiminnddown_neg#1#2-#3;{#1\expandafter\texdiminpt_\the\dimexpr-\texdiminnddown_b#3;pt\relax}%
+% \texdiminnddown: maximal dim exactly expressible in nd and at most equal to input
+\def\texdiminnddown#1{\expandafter\texdimendown_A\the\numexpr\dimexpr#1;*321/685;nd;}%
% \texdiminndup: minimal dim exactly expressible in nd and at least equal to input
-\def\texdiminndup#1{\expandafter\texdiminndup_a\the\numexpr\dimexpr#1;}%
-\def\texdiminndup_a#1{\if-#1\texdiminuuup_neg\fi\texdiminndup_b#1}%
-\def\texdiminndup_b#1;{\expandafter\texdiminndup_c\the\numexpr(2*#1+1)*321/685;#1;}%
-\def\texdiminndup_c#1;{\expandafter\texdiminndup_d\the\dimexpr#1sp;#1;}%
-{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdiminndup_d#1PT};#2;#3;%
- {\ifdim#1nd<#3sp \texdiminuuup_e{#2}\fi\texdimfirstofone{#1}}%
-}%
+\def\texdiminndup#1{\expandafter\texdimenup_A\the\numexpr\dimexpr#1;*321/685;nd;}%
%
% dd 1238/1157
%
\def\texdimindd#1{\expandafter\texdimindd_\the\numexpr\dimexpr#1;}%
-\def\texdimindd_#1#2;{\texdiminpt{\numexpr(2*#1#2+\if-#1-\fi1)*1157/2476sp}}%
-% \texdimindddown: maximal dim exactly expressible in dd and at most equal to input
-\def\texdimindddown#1{\expandafter\texdimindddown_a\the\numexpr\dimexpr#1;}%
-\def\texdimindddown_a#1{\if-#1\texdimindddown_neg\fi\texdimindddown_b#1}%
-\def\texdimindddown_b#1;{\expandafter\texdimindddown_c\the\numexpr(2*#1+1)*1157/2476;#1;}%
-\def\texdimindddown_c#1;{\expandafter\texdimindddown_d\the\dimexpr#1sp;#1;}%
-{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdimindddown_d#1PT};#2;#3;%
- {\ifdim#1dd>#3sp \texdiminuudown_e{#2}\fi\texdimfirstofone{#1}}%
+\def\texdimindd_#1#2;{%
+ \expandafter\texdimenstrippt\the\dimexpr\numexpr(2*#1#2+\if-#1-\fi1)*1157/2476sp\relax
}%
-\def\texdimindddown_neg#1#2-#3;{#1\expandafter\texdiminpt_\the\dimexpr-\texdimindddown_b#3;pt\relax}%
+% \texdimindddown: maximal dim exactly expressible in dd and at most equal to input
+\def\texdimindddown#1{\expandafter\texdimendown_A\the\numexpr\dimexpr#1;*1157/2476;dd;}%
% \texdiminddup: minimal dim exactly expressible in dd and at least equal to input
-\def\texdiminddup#1{\expandafter\texdiminddup_a\the\numexpr\dimexpr#1;}%
-\def\texdiminddup_a#1{\if-#1\texdiminuuup_neg\fi\texdiminddup_b#1}%
-\def\texdiminddup_b#1;{\expandafter\texdiminddup_c\the\numexpr(2*#1+1)*1157/2476;#1;}%
-\def\texdiminddup_c#1;{\expandafter\texdiminddup_d\the\dimexpr#1sp;#1;}%
-{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdiminddup_d#1PT};#2;#3;%
- {\ifdim#1dd<#3sp \texdiminuuup_e{#2}\fi\texdimfirstofone{#1}}%
-}%
+\def\texdiminddup#1{\expandafter\texdimenup_A\the\numexpr\dimexpr#1;*1157/2476;dd;}%
%
% mm 7227/2540 phi now >2, use from here on the simpler approach
%
-\def\texdiminmm#1{\expandafter\texdiminpt_\the\dimexpr(#1)*2540/7227\relax}%
+\def\texdiminmm#1{\expandafter\texdimenstrippt\the\dimexpr(#1)*2540/7227\relax}%
% \texdiminmmdown: maximal dim exactly expressible in mm and at most equal to input
-\def\texdiminmmdown#1{\expandafter\texdiminmmdown_a\the\numexpr\dimexpr#1;}%
-\def\texdiminmmdown_a#1{\if-#1\texdiminmmdown_neg\fi\texdiminmmdown_b#1}%
-\def\texdiminmmdown_b#1;{\expandafter\texdiminmmdown_c\the\numexpr#1*2540/7227;#1;}%
-\def\texdiminmmdown_c#1;{\expandafter\texdiminmmdown_d\the\dimexpr#1sp;#1;}%
-{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdiminmmdown_d#1PT};#2;#3;%
- {\ifdim#1mm>#3sp \texdiminuudown_e{#2}\fi\texdimfirstofone{#1}}%
-}%
-\def\texdiminmmdown_neg#1#2-#3;{#1\expandafter\texdiminpt_\the\dimexpr-\texdiminmmdown_b#3;pt\relax}%
+\def\texdiminmmdown#1{\expandafter\texdimendown_a\the\numexpr\dimexpr#1;*2540/7227;mm;}%
% \texdiminmmup: minimal dim exactly expressible in mm and at least equal to input
-\def\texdiminmmup#1{\expandafter\texdiminmmup_a\the\numexpr\dimexpr#1;}%
-\def\texdiminmmup_a#1{\if-#1\texdiminuuup_neg\fi\texdiminmmup_b#1}%
-\def\texdiminmmup_b#1;{\expandafter\texdiminmmup_c\the\numexpr#1*2540/7227;#1;}%
-\def\texdiminmmup_c#1;{\expandafter\texdiminmmup_d\the\dimexpr#1sp;#1;}%
-{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdiminmmup_d#1PT};#2;#3;%
- {\ifdim#1mm<#3sp \texdiminuuup_e{#2}\fi\texdimfirstofone{#1}}%
-}%
+\def\texdiminmmup#1{\expandafter\texdimenup_a\the\numexpr\dimexpr#1;*2540/7227;mm;}%
%
% pc 12/1
%
-\def\texdiminpc#1{\expandafter\texdiminpt_\the\dimexpr(#1)/12\relax}%
+\def\texdiminpc#1{\expandafter\texdimenstrippt\the\dimexpr(#1)/12\relax}%
% \texdiminpcdown: maximal dim exactly expressible in pc and at most equal to input
-\def\texdiminpcdown#1{\expandafter\texdiminpcdown_a\the\numexpr\dimexpr#1;}%
-\def\texdiminpcdown_a#1{\if-#1\texdiminpcdown_neg\fi\texdiminpcdown_b#1}%
-\def\texdiminpcdown_b#1;{\expandafter\texdiminpcdown_c\the\numexpr#1/12;#1;}%
-\def\texdiminpcdown_c#1;{\expandafter\texdiminpcdown_d\the\dimexpr#1sp;#1;}%
-{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdiminpcdown_d#1PT};#2;#3;%
- {\ifdim#1pc>#3sp \texdiminuudown_e{#2}\fi\texdimfirstofone{#1}}%
-}%
-\def\texdiminpcdown_neg#1#2-#3;{#1\expandafter\texdiminpt_\the\dimexpr-\texdiminpcdown_b#3;pt\relax}%
+\def\texdiminpcdown#1{\expandafter\texdimendown_a\the\numexpr\dimexpr#1;/12;pc;}%
% \texdiminpcup: minimal dim exactly expressible in pc and at least equal to input
-\def\texdiminpcup#1{\expandafter\texdiminpcup_a\the\numexpr\dimexpr#1;}%
-\def\texdiminpcup_a#1{\if-#1\texdiminuuup_neg\fi\texdiminpcup_b#1}%
-\def\texdiminpcup_b#1;{\expandafter\texdiminpcup_c\the\numexpr#1/12;#1;}%
-\def\texdiminpcup_c#1;{\expandafter\texdiminpcup_d\the\dimexpr#1sp;#1;}%
-{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdiminpcup_d#1PT};#2;#3;%
- {\ifdim#1pc<#3sp \texdiminuuup_e{#2}\fi\texdimfirstofone{#1}}%
-}%
+\def\texdiminpcup#1{\expandafter\texdimenup_a\the\numexpr\dimexpr#1;/12;pc;}%
%
% nc 1370/107
%
-\def\texdiminnc#1{\expandafter\texdiminpt_\the\dimexpr(#1)*107/1370\relax}%
+\def\texdiminnc#1{\expandafter\texdimenstrippt\the\dimexpr(#1)*107/1370\relax}%
% \texdiminncdown: maximal dim exactly expressible in nc and at most equal to input
-\def\texdiminncdown#1{\expandafter\texdiminncdown_a\the\numexpr\dimexpr#1;}%
-\def\texdiminncdown_a#1{\if-#1\texdiminncdown_neg\fi\texdiminncdown_b#1}%
-\def\texdiminncdown_b#1;{\expandafter\texdiminncdown_c\the\numexpr#1*107/1370;#1;}%
-\def\texdiminncdown_c#1;{\expandafter\texdiminncdown_d\the\dimexpr#1sp;#1;}%
-{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdiminncdown_d#1PT};#2;#3;%
- {\ifdim#1nc>#3sp \texdiminuudown_e{#2}\fi\texdimfirstofone{#1}}%
-}%
-\def\texdiminncdown_neg#1#2-#3;{#1\expandafter\texdiminpt_\the\dimexpr-\texdiminncdown_b#3;pt\relax}%
+\def\texdiminncdown#1{\expandafter\texdimendown_a\the\numexpr\dimexpr#1;*107/1370;nc;}%
% \texdiminncup: minimal dim exactly expressible in nc and at least equal to input
-\def\texdiminncup#1{\expandafter\texdiminncup_a\the\numexpr\dimexpr#1;}%
-\def\texdiminncup_a#1{\if-#1\texdiminuuup_neg\fi\texdiminncup_b#1}%
-\def\texdiminncup_b#1;{\expandafter\texdiminncup_c\the\numexpr#1*107/1370;#1;}%
-\def\texdiminncup_c#1;{\expandafter\texdiminncup_d\the\dimexpr#1sp;#1;}%
-{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdiminncup_d#1PT};#2;#3;%
- {\ifdim#1nc<#3sp \texdiminuuup_e{#2}\fi\texdimfirstofone{#1}}%
-}%
+\def\texdiminncup#1{\expandafter\texdimenup_a\the\numexpr\dimexpr#1;*107/1370;nc;}%
%
% cc 14856/1157
%
-\def\texdimincc#1{\expandafter\texdiminpt_\the\dimexpr(#1)*1157/14856\relax}%
+\def\texdimincc#1{\expandafter\texdimenstrippt\the\dimexpr(#1)*1157/14856\relax}%
% \texdiminccdown: maximal dim exactly expressible in cc and at most equal to input
-\def\texdiminccdown#1{\expandafter\texdiminccdown_a\the\numexpr\dimexpr#1;}%
-\def\texdiminccdown_a#1{\if-#1\texdiminccdown_neg\fi\texdiminccdown_b#1}%
-\def\texdiminccdown_b#1;{\expandafter\texdiminccdown_c\the\numexpr#1*1157/14856;#1;}%
-\def\texdiminccdown_c#1;{\expandafter\texdiminccdown_d\the\dimexpr#1sp;#1;}%
-{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdiminccdown_d#1PT};#2;#3;%
- {\ifdim#1cc>#3sp \texdiminuudown_e{#2}\fi\texdimfirstofone{#1}}%
-}%
-\def\texdiminccdown_neg#1#2-#3;{#1\expandafter\texdiminpt_\the\dimexpr-\texdiminccdown_b#3;pt\relax}%
+\def\texdiminccdown#1{\expandafter\texdimendown_a\the\numexpr\dimexpr#1;*1157/14856;cc;}%
% \texdiminccup: minimal dim exactly expressible in cc and at least equal to input
-\def\texdiminccup#1{\expandafter\texdiminccup_a\the\numexpr\dimexpr#1;}%
-\def\texdiminccup_a#1{\if-#1\texdiminuuup_neg\fi\texdiminccup_b#1}%
-\def\texdiminccup_b#1;{\expandafter\texdiminccup_c\the\numexpr#1*1157/14856;#1;}%
-\def\texdiminccup_c#1;{\expandafter\texdiminccup_d\the\dimexpr#1sp;#1;}%
-{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdiminccup_d#1PT};#2;#3;%
- {\ifdim#1cc<#3sp \texdiminuuup_e{#2}\fi\texdimfirstofone{#1}}%
-}%
+\def\texdiminccup#1{\expandafter\texdimenup_a\the\numexpr\dimexpr#1;*1157/14856;cc;}%
%
% cm 7227/254
%
-\def\texdimincm#1{\expandafter\texdiminpt_\the\dimexpr(#1)*254/7227\relax}%
+\def\texdimincm#1{\expandafter\texdimenstrippt\the\dimexpr(#1)*254/7227\relax}%
% \texdimincmdown: maximal dim exactly expressible in cm and at most equal to input
-\def\texdimincmdown#1{\expandafter\texdimincmdown_a\the\numexpr\dimexpr#1;}%
-\def\texdimincmdown_a#1{\if-#1\texdimincmdown_neg\fi\texdimincmdown_b#1}%
-\def\texdimincmdown_b#1;{\expandafter\texdimincmdown_c\the\numexpr#1*254/7227;#1;}%
-\def\texdimincmdown_c#1;{\expandafter\texdimincmdown_d\the\dimexpr#1sp;#1;}%
-{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdimincmdown_d#1PT};#2;#3;%
- {\ifdim#1cm>#3sp \texdiminuudown_e{#2}\fi\texdimfirstofone{#1}}%
-}%
-\def\texdimincmdown_neg#1#2-#3;{#1\expandafter\texdiminpt_\the\dimexpr-\texdimincmdown_b#3;pt\relax}%
+\def\texdimincmdown#1{\expandafter\texdimendown_a\the\numexpr\dimexpr#1;*254/7227;cm;}%
% \texdimincmup: minimal dim exactly expressible in cm and at least equal to input
-\def\texdimincmup#1{\expandafter\texdimincmup_a\the\numexpr\dimexpr#1;}%
-\def\texdimincmup_a#1{\if-#1\texdiminuuup_neg\fi\texdimincmup_b#1}%
-\def\texdimincmup_b#1;{\expandafter\texdimincmup_c\the\numexpr#1*254/7227;#1;}%
-\def\texdimincmup_c#1;{\expandafter\texdimincmup_d\the\dimexpr#1sp;#1;}%
-{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdimincmup_d#1PT};#2;#3;%
- {\ifdim#1cm<#3sp \texdiminuuup_e{#2}\fi\texdimfirstofone{#1}}%
-}%
+\def\texdimincmup#1{\expandafter\texdimenup_a\the\numexpr\dimexpr#1;*254/7227;cm;}%
%
% in 7227/100
%
-\def\texdiminin#1{\expandafter\texdiminpt_\the\dimexpr(#1)*100/7227\relax}%
+\def\texdiminin#1{\expandafter\texdimenstrippt\the\dimexpr(#1)*100/7227\relax}%
% \texdiminindown: maximal dim exactly expressible in in and at most equal to input
-\def\texdiminindown#1{\expandafter\texdiminindown_a\the\numexpr\dimexpr#1;}%
-\def\texdiminindown_a#1{\if-#1\texdiminindown_neg\fi\texdiminindown_b#1}%
-\def\texdiminindown_b#1;{\expandafter\texdiminindown_c\the\numexpr#1*100/7227;#1;}%
-\def\texdiminindown_c#1;{\expandafter\texdiminindown_d\the\dimexpr#1sp;#1;}%
-{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdiminindown_d#1PT};#2;#3;%
- {\ifdim#1in>#3sp \texdiminuudown_e{#2}\fi\texdimfirstofone{#1}}%
-}%
-\def\texdiminindown_neg#1#2-#3;{#1\expandafter\texdiminpt_\the\dimexpr-\texdiminindown_b#3;pt\relax}%
+\def\texdiminindown#1{\expandafter\texdimendown_a\the\numexpr\dimexpr#1;*100/7227;in;}%
% \texdimininup: minimal dim exactly expressible in in and at least equal to input
-\def\texdimininup#1{\expandafter\texdimininup_a\the\numexpr\dimexpr#1;}%
-\def\texdimininup_a#1{\if-#1\texdiminuuup_neg\fi\texdimininup_b#1}%
-\def\texdimininup_b#1;{\expandafter\texdimininup_c\the\numexpr#1*100/7227;#1;}%
-\def\texdimininup_c#1;{\expandafter\texdimininup_d\the\dimexpr#1sp;#1;}%
-{\catcode`P 12\catcode`T 12\lowercase{\gdef\texdimininup_d#1PT};#2;#3;%
- {\ifdim#1in<#3sp \texdiminuuup_e{#2}\fi\texdimfirstofone{#1}}%
-}%
+\def\texdimininup#1{\expandafter\texdimenup_a\the\numexpr\dimexpr#1;*100/7227;in;}%
%
\texdimensendinput