summaryrefslogtreecommitdiff
path: root/Master/texmf-dist/tex/generic
diff options
context:
space:
mode:
authorKarl Berry <karl@freefriends.org>2021-07-15 19:58:54 +0000
committerKarl Berry <karl@freefriends.org>2021-07-15 19:58:54 +0000
commit44e933e35901329b69a607da2dc65d10b1420c86 (patch)
treef65177ff7646481b790b3d178b158051ab2d9261 /Master/texmf-dist/tex/generic
parent891003f6c81de2e720cd103ba1837a370fb99153 (diff)
texdimens (15jul21)
git-svn-id: svn://tug.org/texlive/trunk@59939 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/tex/generic')
-rw-r--r--Master/texmf-dist/tex/generic/texdimens/texdimens.sty2
-rw-r--r--Master/texmf-dist/tex/generic/texdimens/texdimens.tex278
2 files changed, 218 insertions, 62 deletions
diff --git a/Master/texmf-dist/tex/generic/texdimens/texdimens.sty b/Master/texmf-dist/tex/generic/texdimens/texdimens.sty
index c29f1458e0b..dbf39c72f80 100644
--- a/Master/texmf-dist/tex/generic/texdimens/texdimens.sty
+++ b/Master/texmf-dist/tex/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/06/30 v0.9beta 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/Master/texmf-dist/tex/generic/texdimens/texdimens.tex b/Master/texmf-dist/tex/generic/texdimens/texdimens.tex
index 471a07f807d..189caca95d0 100644
--- a/Master/texmf-dist/tex/generic/texdimens/texdimens.tex
+++ b/Master/texmf-dist/tex/generic/texdimens/texdimens.tex
@@ -1,101 +1,257 @@
% 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/06/30 v0.9beta
+% 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)=floor(N phi) is strictly increasing
+% U(N,phi)=trunc(N phi) is strictly increasing
% U(N)<= T < U(N+1) iff N = ceil((T+1)psi) - 1
% U(M)< T <= U(M+1) iff M = ceil(T psi) - 1
% Either:
-% - M = N, i.e. T is not attainable, M=N < T psi < (T+1) psi <= N+1
-% - M = N - 1, i.e. T is attained, T psi <= N < (T+1) psi, T = floor(N phi)
+% case1: M = N, i.e. T is not attainable, M=N < T psi < (T+1) psi <= N+1
+% case2: M = N - 1, i.e. T is attained, T psi <= N < (T+1) psi, T = floor(N phi)
%
-% In the latter case:
-% - as psi<1, |N - (T+0.5) psi| < 0.5, hence N = R := round((T+0.5) psi).
-% Also works for T=0 but T<0 would need -0.5.
+% Let X = round(T psi). And let Y = trunc(X phi).
%
-% - if psi<1/2, then N = round(T psi) is simpler formula which works
-% also for attainable T<0.
+% case1: X can be N or N+1. It will be N+1 iff Y > T.
+% case2: X can be N or N-1. It will be N iff trunc((X+1)phi)>T.
%
-% This R=round((T+0.5) psi) can always be computed via \numexpr because 2T+1
-% will not trigger arithmetic overflow.
+% This is not convenient: if Y <= T it might still be that we are in case 2
+% and we must check then if trunc((X+1) phi) > T or not.
+%
+% If psi < 0.5
+% ------------
+%
+% The situation then simplifies:
%
-% If Tsp>0 is not attainable, this R can produce either N or N+1 (=M+1).
+% case1: X can be N or N+1. It will be N+1 iff Y = trunc(X phi) > T.
+% case2: X is necessarily N.
%
-% If we try computing ceil(x) via round(x+0.5) (\numexpr rounds up)
-% this means for N, we need round((T+1)psi + 0.5), for example with
-% psi = 100/7227 for "in", this gives round((((T+1)200)+7227)/14454)
-% feasible via \numexpr only for (circa) 100 T less than \maxdimen.
+% Thus:
+% a) compute X = round(T psi)
+% b) compute Y = trunc(X phi) and test if Y > T. If true, we
+% were in case 1, replace X by X - 1, else we were either
+% in case 1 or case 2, but we can leave X as is.
+% We have thus found N.
%
-% We could rather compute round(T psi) but we don't know if it gives
-% N or N+1. We know it is N if round(T psi)< round((T+1) psi)
-% but if the two are the same we don't know if they are both N or
-% both N+1.
+% The operation Y = trunc(X phi) can be achieved this way:
+% i) use \the\dimexpr to convert X sp into D pt,
+% ii) use \the\numexpr\dimexpr to convert "D uu" into sp.
+% These steps give Y.
%
-% It is slightly less costly to compute X = round(T psi) than R,
-% but if we then realize that X uu < T sp we do not yet know
-% if (X+1) uu = T sp or is > Tsp, except if psi<1/2, because
-% if T sp is attainable then X = round(T psi) is then necessarily N
-% so if X uu < T sp we now that T sp was not attainable.
+% This way we find the maximal dimension at most T sp exactly
+% representable in "uu" unit.
%
-% We decide with some hesitation to not split whether psi<1/2 or
-% psi>1/2. Reverted! Currently following done only for psi>1/2,
-% i.e. bp, nd, dd.
+% The computations of X and Y can be done independently of sign of T.
+% But the final test has to be changed to Y < T if T < 0 and then
+% one must replace X by X+1. So we must filter sign.
%
-% 1. compute R = round((T+0.5) psi) in \numexpr. This forces
-% to check for negative T because then we would want here (T-0.5)psi
+% If the goal is only to find a decimal D such that "D uu" is
+% exactly T sp in the case this is possible, then things are simpler
+% because from X = round(T psi) we get D such as X sp is same as D pt
+% and "D uu" will work.
+% We don't have to take sign into account for this computation.
+% But if T sp was not atteignable we don't know if this X will give
+% a D such that D uu < T sp or D uu > T sp.
%
-% 2. check for the "up" and "down" variants whether R uu is <, =, or > T sp.
-% But we have to choose here what "up" and "down" mean for T<0.
-% Also, computation of R uu
-% may trigger Dimension too large if T sp is not attainable,
-% close to \maxdimen, and \maxdimen itself is not attainable.
+% If psi > 0.5
+% ------------
%
-% For the envisioned "safe versions" we would tabulate first per unit
-% what is Rmax such that Rmax uu <= \maxdimen. Then the "safe" versions
-% would have an extra check of R. But for \texdimeninuuu it will
-% then not be compliant to its definition for inputs close to
-% non-attainable \maxdimen.
+% For example unit "bp" has phi=803/800.
+%
+% It is then not true that if T sp is atteignable, the X = round(T psi)
+% will always work.
+%
+% But it is true that R = round((T + 0.5) psi) will always work.
+% Here we must use -0.5 if T < 0, though.
+%
+% This R=round((T+0.5) psi) can always be computed via \numexpr because 2T+1
+% will not trigger arithmetic overflow.
+%
+% So this gives an approach to find a D such that "D uu" is exactly
+% T sp when this is possible.
+%
+% If Tsp (positive) is not attainable, this R however can produce
+% either N or N+1.
+%
+% But we can decide what happened by computing Z = trunc(R phi).
+% If and only if Z > T this means R was N+1.
+%
+% It is slightly less costly to compute X = round(T psi) than
+% R = round((T + 0.5) psi),
+% but if we then realize that trunc(X phi) < T we do not yet know
+% if trunc((X+1) phi) = T or is > T.
+%
+% To recapitulate: we have our algorithm for all units to find out
+% maximal dimension exactly atteignable in "uu" unit and at most equal
+% to (positive) T sp.
+%
+% Unfortunately the check that Y (in case psi < 0.5) or Z (in case psi >
+% 0.5) may trigger a Dimension too large error if T sp was near
+% non-atteignable \maxdimen.
+%
+% For additional envisioned "safe versions" we would tabulate first per unit
+% what is the integer Rmax such that trunc(Rmax phi) <= \maxdimen. Then
+% the "safe" versions would have an extra check of X or R before
+% proceeding further. But the "up macros" supposed to give the next
+% dimension above Tsp and exactly atteignable in "uu" unit, if compliant
+% to their description can not avoid "Dimension too large" for inputs
+% close to non-attainable \maxdimen.
%
% After having written the macros we will tabulate what is for each unit
% the maximal attainable dimension.
%
-% Hesitation about whether using simpler round(T psi) approach
-% for units > 2pt and the \texdimin<uu> macros.
+% About the macros such as \texdiminbp whose constraints are:
+% - give a decimal D such that "Duu" = "T sp" for TeX if possible
+% - else give nearest from below or above without knowing
+% which one,
+%
+% there was some hesitation about whether or not using the simpler
+% round(T psi) approach for units > 2pt and the \texdimin<uu> macros.
+% Testing showed that this did not change the output for \maxdimen
+% with the units "nc" and "in": still N+1 is returned...
+%
+% As it has great
+% advantage to not have to check the sign of the input, the
+% "simpler" approach was chosen for those units to which it
+% applies, i.e. the units uu > 2pt (phi>2, psi<1/2), i.e.
+% all units except bp, nd and dd.
+%
+% Implementation
+% ==============
+%
+\def\texdimenfirstofone#1{#1}%
+{\catcode`p 12\catcode`t 12
+ \csname expandafter\endcsname\gdef\csname texdimenstrippt\endcsname#1pt{#1}}%
%
-% Testing shows that this would not change output for \maxdimen
-% with "nc" and "in": still N+1 is returned... but it has great
-% advantage to not have to check the sign.
+% 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\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\texdimenstrippt\the\dimexpr#1\relax}%
%
-% OK let's do this,
-% especially as I don't know if I will ever implement "up" and "down".
-\def\texdiminpt#1{\expandafter\texdiminpt_\the\dimexpr#1\relax}%
-{\catcode`p 12\catcode`t 12\csname expandafter\endcsname\gdef\csname texdiminpt_\endcsname#1pt{#1}}%
% bp 7227/7200 = 803/800
-% complications and annoying overhead caused by sign
-% and we don't want to evaluate #1 twice in a \dimexpr; if #1 was
-% restricted to be a dimen register, we would avoid "\the and re-grab" step.
+%
\def\texdiminbp#1{\expandafter\texdiminbp_\the\numexpr\dimexpr#1;}%
-\def\texdiminbp_#1#2;{\texdiminpt{\numexpr(2*#1#2+\if-#1-\fi1)*400/803sp}}%
+\def\texdiminbp_#1#2;{%
+ \expandafter\texdimenstrippt\the\dimexpr\numexpr(2*#1#2+\if-#1-\fi1)*400/803sp\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\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}}%
+\def\texdiminnd_#1#2;{%
+ \expandafter\texdimenstrippt\the\dimexpr\numexpr(2*#1#2+\if-#1-\fi1)*321/685sp\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\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}}%
+\def\texdimindd_#1#2;{%
+ \expandafter\texdimenstrippt\the\dimexpr\numexpr(2*#1#2+\if-#1-\fi1)*1157/2476sp\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\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{\texdiminpt{(#1)*2540/7227}}%
+%
+\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\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\texdimenup_a\the\numexpr\dimexpr#1;*2540/7227;mm;}%
+%
% pc 12/1
-\def\texdiminpc#1{\texdiminpt{(#1)/12}}%
+%
+\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\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\texdimenup_a\the\numexpr\dimexpr#1;/12;pc;}%
+%
% nc 1370/107
-\def\texdiminnc#1{\texdiminpt{(#1)*107/1370}}%
+%
+\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\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\texdimenup_a\the\numexpr\dimexpr#1;*107/1370;nc;}%
+%
% cc 14856/1157
-\def\texdimincc#1{\texdiminpt{(#1)*1157/14856}}%
+%
+\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\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\texdimenup_a\the\numexpr\dimexpr#1;*1157/14856;cc;}%
+%
% cm 7227/254
-\def\texdimincm#1{\texdiminpt{(#1)*254/7227}}%
+%
+\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\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\texdimenup_a\the\numexpr\dimexpr#1;*254/7227;cm;}%
+%
% in 7227/100
-\def\texdiminin#1{\texdiminpt{(#1)*100/7227}}%
+%
+\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\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\texdimenup_a\the\numexpr\dimexpr#1;*100/7227;in;}%
+%
\texdimensendinput