From 44e933e35901329b69a607da2dc65d10b1420c86 Mon Sep 17 00:00:00 2001 From: Karl Berry Date: Thu, 15 Jul 2021 19:58:54 +0000 Subject: texdimens (15jul21) git-svn-id: svn://tug.org/texlive/trunk@59939 c570f23f-e606-0410-a88d-b1316a301751 --- Master/texmf-dist/doc/generic/texdimens/README.md | 317 +++++++++++++--------- 1 file changed, 185 insertions(+), 132 deletions(-) (limited to 'Master/texmf-dist/doc') diff --git a/Master/texmf-dist/doc/generic/texdimens/README.md b/Master/texmf-dist/doc/generic/texdimens/README.md index 54f5a530dc9..4f028fe6895 100644 --- a/Master/texmf-dist/doc/generic/texdimens/README.md +++ b/Master/texmf-dist/doc/generic/texdimens/README.md @@ -10,10 +10,12 @@ 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 -both with Plain (\input texdimens) and with LaTeX (\usepackage{texdimens}). +both with Plain (`\input texdimens`) and with LaTeX (`\usepackage{texdimens}`). The aim of this package is to address the issue of expressing dimensions (or dimension expressions evaluated by `\dimexpr`) in the various TeX @@ -25,9 +27,15 @@ in a faithful manner the exact outcome of those internal procedures. The reader is supposed to be familiar with TeX basics. This project requires the e-TeX extensions `\dimexpr` and `\numexpr`. +The notation `` in the macro descriptions refers to a +*dimensional expression* as accepted by `\dimexpr`. The syntax has some +peculiarities: among them the fact that `-(...)` (for example `-(3pt)`) +is illegal, one must use alternatives such as `0pt-(...)` or a +sub-expression `-\dimexpr...\relax` for example. Notice that this is WIP and inaccuracies may exist even relative to -descriptions of TeX handlings due to limited time available for the project. +descriptions of TeX handlings due to limited time available for the +project. ## TeX points and scaled points @@ -57,17 +65,16 @@ When `\foo` has been assigned as `D pt`, `\the\foo` will produce some `E pt` where `E` is not necessarily the same as `D`. But it is guaranteed that `E pt` defines the same dimension as `D pt̀`. - ## Further units known to TeX on input TeX understands on input further units: `bp`, `cm`, `mm`, `in`, `pc`, -`cc`, `dd` and `nd`. It also understands font-dependent units `ex` and +`cc`, `nc`, `dd` and `nd`. It also understands font-dependent units `ex` and `em`, and PDFTeX adds the `px` dimension unit. Japanese engines also add specific units. `ex`, `em`, `px` and other engine-dependent units, are all currently excluded from consideration in this project and the rest of this -documentation is only for the `bp`, `cm`, `mm`, `in`, `pc`, `cc`, `dd` +documentation is only for the `bp`, `cm`, `mm`, `in`, `pc`, `cc`, `nc`, `dd` and `nd` units. When we say "unit" we mean one of those or the `pt` (the `sp` is a special case and will be included or not tacitly in the "unit" denomination depending on the case). @@ -76,7 +83,7 @@ TeX associates to each such unit `uu` a fraction `phi` which is a conversion factor. It is always `>1`: uu phi reduced real approximation 1uu in sp= x=[65536phi]/65536 \the<1uu> - [65536phi] (real approximation) + (Python output) [65536phi] (real approximation) -- ---------- ------- ------------------ --------- -------------------- ---------- bp 7227/7200 803/800 1.00375 65781 1.0037384033203125 1.00374pt nd 685/642 same 1.0669781931464175 69925 1.0669708251953125 1.06697pt @@ -116,11 +123,18 @@ to an integer ratio `12`: only dimensions which in scaled points are multiple of `12` are exactly representable in the `pc` unit. This also means that some dimensions expressible in one unit may not be -available with another unit. For example, it turns out that `0.6in` can -not be expressed as `D cm`, whatever the `D`. More surprisingly perhaps -is that `1in==2.54cm` is **false** in TeX! But it is true that -`100in==254cm`! It is also false that `10in==25.4cm` but it is true that -`10in==254mm`! It is false though that `1in==25.4mm`! +available with another unit. For example, and perhaps surprisingly, +there is no decimal `D` which would achieve `1in==Dcm`: the "step" +between attainable dimensions is `72--73sp` for the `in` and `28--29sp` +for the `cm`, and as `1in` differs internally from `2.54cm` by only +`12sp` (see below the `xintsession` verbatim) it is impossible to adjust +either the `in` side or the `cm` side to obtain equality. See in the +[TODO] section the closest dimension attainable both via `in` and via +`cm`. + +In particular `1in==2.54cm` is **false** in TeX, but it is true that +`100in==254cm`... It is also false that `10in==25.4cm` but it is true that +`10in==254mm`... It is false though that `1in==25.4mm`! >>> (\dimexpr1in, \dimexpr2.54cm); @_1 4736286, 4736274 @@ -135,17 +149,22 @@ is that `1in==2.54cm` is **false** in TeX! But it is true that @_5 47362867, 47362867 `\maxdimen` can be expressed only with `pt`, `bp`, and `nd`. For the -other units the maximal attainable dimensions are given in this table: - - 16322.78954 bp (\maxdimen = 1073741823 sp) - 15355.51532 nd (\maxdimen = 1073741823 sp) - 15312.02583 dd (1073741822 sp) - 5758.31741 mm (1073741822 sp) - 1365.33333 pc (1073741820 sp) - 1279.62627 nc (1073741814 sp) - 1276.00215 cc (1073741821 sp) - 575.83174 cm (1073741822 sp) - 226.7054 in (1073741768 sp) +other units the maximal attainable dimensions in `sp` unit are given in +the middle column of the next table. + + maximal allowed the corresponding minimal TeX dimen denotation + (with 5 places) maximal attainable dim. causing "Dimension too large" + --------------- -------------------------- -------------------------- + 16383.99999 pt 1073741823 sp (=\maxdimen) 16383.99999237060546875 pt + 16322.78954 bp 1073741823 sp (=\maxdimen) 16322.78954315185546875 bp + 15355.51532 nd 1073741823 sp (=\maxdimen) 15355.51532745361328125 nd + 15312.02584 dd 1073741822 sp 15312.02584075927734375 dd + 5758.31742 mm 1073741822 sp 5758.31742095947265625 mm + 1365.33333 pc 1073741820 sp 1365.33333587646484375 pc + 1279.62627 nc 1073741814 sp 1279.62627410888671875 nc + 1276.00215 cc 1073741821 sp 1276.00215911865234375 cc + 575.83174 cm 1073741822 sp 575.83174896240234375 cm + 226.70540 in 1073741768 sp 226.70540618896484375 in Perhaps for these various peculiarities with dimensional units, TeX does not provide an output facility for them similar to what `\the` achieves for @@ -153,34 +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. - -All macros handle negative dimensions via their absolute value then -taking the opposite. - -1. At time of writing only the `\texdimin` macros are implemented, -The envisioned "down" and "up" variants are not done yet. - -2. For `dd`, `nc` and `in`, input equal to (or sufficiently close to) -`\maxdimen` will produce also with `\texdimin` an output `D` -representing the next "attainable" dimension above `\maxdimen` hence -using `Duu` will trigger "Dimension too large error". - -3. (not yet) For input 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" variants -`\texdiminu` if used as `Duu` in a dimension assignment or -expression will (naturally) trigger "Dimension too large" error. - -4. (not yet) 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 2. and 3. regarding the -usability of the output anyhow. +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). + +Apart for the `\texdiminup` 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 `\texdiminup{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{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{}` @@ -188,73 +205,73 @@ usability of the output anyhow. `\texdiminbp{}` -> 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. > `\maxdimen` on input produces `16322.78954` and indeed is realized as `16322.78954bp`. -`\texdiminbpd{}` NOT YET +`\texdiminbpdown{}` -> 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. -`\texdiminbpu{}` NOT YET +`\texdiminbpup{}` -> 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. `\texdiminnd{}` -> 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. > `\maxdimen` on input produces `15355.51532` and indeed is realized as `15355.51532nd`. -`\texdiminndd{}` NOT YET +`\texdiminnddown{}` -> 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. -`\texdiminndu{}` NOT YET +`\texdiminndup{}` -> 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. `\texdimindd{}` -> 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. > Warning: the output for `\maxdimen` is `15312.02585` but `15312.02585dd` > will trigger "Dimension too large" error. -> `\maxdimen-1sp` is atteignable via `15312.02583dd`. +> `\maxdimen-1sp` is attainable via `15312.02584dd`. -`\texdiminddd{}` NOT YET +`\texdimindddown{}` -> 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. -`\texdiminddu{}` NOT YET +`\texdiminddup{}` -> 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{}` -> 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). @@ -262,44 +279,44 @@ usability of the output anyhow. > `\maxdimen` as input produces on output `5758.31741` and indeed the > maximal attainable dimension is `5758.31741mm` (`1073741822sp`). -`\texdiminmmd{}` NOT YET +`\texdiminmmdown{}` -> 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. -`\texdiminmmu{}` NOT YET +`\texdiminmmup{}` -> 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{}` -> 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). > `\maxdimen` as input produces on output `1365.33333` and indeed the > maximal attainable dimension is `1365.33333pc` (`1073741820sp`). -`\texdiminpcd{}` NOT YET +`\texdiminpcdown{}` -> 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. -`\texdiminpcu{}` NOT YET +`\texdiminpcup{}` -> 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{}` -> 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). @@ -308,45 +325,45 @@ usability of the output anyhow. > will trigger "Dimension too large" error. > `\maxdimen-9sp` is attainable via `1279.62627nc`. -`\texdiminncd{}` NOT YET +`\texdiminncdown{}` -> 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. -`\texdiminncu{}` NOT YET +`\texdiminncup{}` -> 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{}` -> 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 advacce which one (and it is not known if the other choice +> known in advance which one (and it is not known if the other choice > would have been closer). > `\maxdimen` as input produces on output `1276.00215` and indeed the > maximal attainable dimension is `1276.00215cc` (`1073741821sp`). -`\texdiminccd{}` NOT YET +`\texdiminccdown{}` -> 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. -`\texdiminccu{}` NOT YET +`\texdiminccup{}` -> 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{}` -> 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). @@ -354,22 +371,22 @@ usability of the output anyhow. > `\maxdimen` as input produces on output `575.83174` and indeed the > maximal attainable dimension is `575.83174cm` (`1073741822sp`). -`\texdimincmd{}` NOT YET +`\texdimincmdown{}` -> 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. -`\texdimincmu{}` NOT YET +`\texdimincmup{}` -> 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{}` -> 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). @@ -378,31 +395,67 @@ usability of the output anyhow. > will trigger "Dimension too large" error. > `\maxdimen-55sp` is maximal attainable dimension (via `226.7054in`). -`\texdiminind{}` NOT YET +`\texdiminindown{}` -> 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. -`\texdimininu{}` NOT YET +`\texdimininup{}` -> 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. +## 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. -## TODO +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). -Implement the "up" and "down" variants. +Provide a macro `\texdimforbothincm{}` which would output +the nearest dimension simultaneously representable both in `in` and in +`cm`? -Provide a macro `\texdimnearest{in,cm}{}` which provides the -nearest dimension simultaneously representable both in `in` and in `cm`? According to a reference on the web by an anonymous contributor the -available positive dimensions in scaled points have the shape -`floor(3613.5*k) sp` for some integer `k`. So we basically may have a +dimensions representable with both `in` and `cm` units have the shape +`trunc(3613.5*k) sp` for some integer `k`. So we basically may have a delta up to about `1800sp` which is about `0.0275pt` and is still small -(less than one hundredth of a millimeter), so perhaps such a utility for -"safe dimensions" may be useful. Simpler however and more efficient +(less than one hundredth of a millimeter, i.e. less than ten micron), +so perhaps such a utility for +"safe dimensions" may be useful. Here are for example the dimensions +nearest to `1in` and realizable both in `in` and `cm` units: + + >>> \input texdimens.tex\relax + (executing \input texdimens.tex\relax in background) + (./texdimens.tex) + >>> &exact + exact mode (floating point evaluations use 16 digits) + >>> (\texdiminin{4737298sp}); + @_10 1.00021 + >>> (\texdimincm{4737298sp}); + @_11 2.54054 + >>> (\dimexpr1.00021in, \dimexpr2.54054cm); + @_12 4737298, 4737298 + >>> (\texdiminin{4733685sp}); + @_13 0.99945 + >>> (\texdimincm{4733685sp}); + @_14 2.5386 + >>> (\dimexpr0.99945in, \dimexpr2.5386cm); + @_15 4733685, 4733685 + +As promised, one of them, the upper approximation, is at less than +one hundredth of millimeter from the two nearby targets. + +Simpler however and more efficient would be for people to finally adopt the French revolution Système Métrique (rather than setting up giant financial paradises). -- cgit v1.2.3