diff options
Diffstat (limited to 'Master/texmf-dist/doc/generic/texdimens/texdimens.md')
-rw-r--r-- | Master/texmf-dist/doc/generic/texdimens/texdimens.md | 297 |
1 files changed, 189 insertions, 108 deletions
diff --git a/Master/texmf-dist/doc/generic/texdimens/texdimens.md b/Master/texmf-dist/doc/generic/texdimens/texdimens.md index 98ae9f5b3b9..ec6ac406e07 100644 --- a/Master/texmf-dist/doc/generic/texdimens/texdimens.md +++ b/Master/texmf-dist/doc/generic/texdimens/texdimens.md @@ -10,7 +10,7 @@ LPPL 1.3c. See file LICENSE.md. Repository: https://github.com/jfbu/texdimens -Release: `0.99d 2021/11/04` +Release: `1.0 2021/11/10` ## Usage @@ -30,21 +30,33 @@ available TeX units, to the extent possible. This package provides expandable macros: -- `\texdimenpt`, -- `\texdimenUU`, `\texdimenUUup` and - `\texdimenUUdown` with `UU` standing for one of `bp`, `cm`, `mm`, `in`, - `pc`, `cc`, `nc`, `dd` and `nd`, -- `\texdimenbothincm` (and relatives not listed here, see below), +- `\texdimenUU` with `UU` standing for one of `pt`, `bp`, `cm`, `mm`, + `in`, `pc`, `cc`, `nc`, `dd` and `nd`, +- `\texdimenUUup` and `\texdimenUUdown` with `UU` as above except `pt`, +- `\texdimenbothincm` and relatives, +- `\texdimenbothbpmm` and relatives, - `\texdimenwithunit`. -For example `\texdimenbp` takes on input some dimension or dimension -expression and produces on output a decimal `D` such that `D bp` is -guaranteed to be the same dimension as the input, if that one admits any -representation as `E bp`; else it will be either the closest match from -above or from below (for this unit the error is at most `1sp`). +`\texdimenbp` takes on input some dimension or dimension expression and +produces on output a decimal `D` such that `D bp` is guaranteed to be +the same dimension as the input, *if* it admits any representation as `E +bp`; else it will be either the closest match from above or from +below. For this unit, as well as for `nd` and `dd` the difference is at +most `1sp`. For other units (not `pt` of course) the distance will +usually be larger than `1sp` and one does not know if the approximant +from the other direction would have been better or worst. -The variants `\texdimenbpup` and `\texdimenbpdown` allow to choose the -direction of approximation. +The variants `\texdimenbpup` and `\texdimenbpdown` expand slightly less +fast than `\texdimenbp` but they allow to choose the direction of +approximation (in absolute value). + +The macros associated to the other units have +the same descriptions. + +`\texdimenbothincm`, respectively `\texdimenbothbpmm`, find the largest +(in absolute value) dimension not exceeding the input and exactly +representable both with the `in` and `cm` units, respectively exactly +representable both with the `bp` and `mm` units. `\texdimenwithunit{<dimen1>}{<dimen2>}` produces a decimal `D` such that `D \dimexpr dimen2\relax` is parsed by TeX into the same dimension as @@ -54,9 +66,8 @@ attainable. If not attainable, the decimal `D` will ensure a closest match from below or from above but one does not know if the approximation from the other direction is better or worst. -In a sense, this macro divides `<dimen1>` by `<dimen2>` but please continue -reading this documentation for relevant -information on how TeX handles dimensions. +In a sense, this macro divides `<dimen1>` by `<dimen2>`, see additional +details in the complete macro description. ## Quick review of basics: TeX points and scaled points @@ -118,7 +129,7 @@ For core units however, the hard-coded ratio `n/d` never has a denominator `d` which is a power of `2`, except for the `pc` whose associated ratio factor is `12/1` (and arguably for the `sp` for which morally `phi` is `1/65536` but we keep it separate from the general -discussion). +discussion; as well as `pt` with its unit conversion factor). Here is a table with the hard-coded conversion factors: @@ -138,7 +149,15 @@ Here is a table with the hard-coded conversion factors: The values of `1uu` in the `sp` and `pt` units are irrelevant and even misleading regarding the TeX parsing of `D uu` input. Notice for example that `\the\dimexpr1bp\relax` gives `1.00374pt` but the actual -conversion factor is `1.00375`. +conversion factor is `1.00375` (and +`1.00375pt=65782sp>1bp`...). Similarly `\the\dimexpr1in\relax` outputs +`72.26999pt` and is represented internally as `4736286sp` but the actual +conversion factor is `72.27=7227/100`, and +`72.27pt=4736287sp>1in`... And for the other units except the `pc`, the +conversion factors are not decimal numbers, so even less likely to match +`\the<1uu>` as listed in the last column. Their denominators are not +powers of `2` so they don't match exactly either `(1uu in sp)/65536` but +are only close. When TeX parses an assignment `U uu` with a decimal `U` and a unit `uu`, be it a core unit, or a unit corresponding to an internal dimension, @@ -229,26 +248,31 @@ at last step the sign (if result is not zero) is applied (so "down" means Remarks about "Dimension too large" issues: -1. For input `X` equal to (or sufficiently close to) `\maxdimen` and +1. For input `X` equal to `\maxdimen` (or differing by a few `sp`'s) and those units `uu` for which `\maxdimen` is not exactly representable - (i.e. all core units except `pt`, `bp` and `nd`), the output `D` of the - "up" macros `\texdimen<uu>up{X}`, if used as `Duu` in a dimension - assignment or expression, will (naturally) trigger a "Dimension too - large" error. -2. The same potentially happens with `\texdimenwithunit{dimen1}{dimen2}` - if `\maxdimen` - is not representable exactly by `dimen2` used as a base dimension, - (which may happen only if `dimen2>1pt`): it is possible that the - output `D`, if consequently used as `D\dimexpr dimen2\relax` will - trigger "Dimension too large". -3. For `dd`, `nc` and `in`, and input `X` equal to (or sufficiently - close to) `\maxdimen` it turns out that `\texdimen<uu>{X}` produces - an output `D` such that `Duu` is the first "virtually attainable" TeX - dimension *beyond* `\maxdimen`. Hence here also `Duu` will trigger on use - "Dimension too large error". -4. 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`. + (i.e. all core units except `pt`, `bp` and `nd`), the output `D` of + the "up" macros `\texdimen<uu>up{X}`, if used as `Duu` in a dimension + assignment or expression, will (as is logical) trigger a "Dimension + too large" error. +2. For `dd`, `nc` and `in`, it turns out that `\texdimen<uu>{X}` chooses + the "up" approximant for `X` equal to or very near `\maxdimen` (check + the respective macro documentations), + i.e. the output `D` is such that `Duu` is the first virtually + attainable dimension beyond `\maxdimen`. Hence `Duu` will trigger on + use a "Dimension too large error". With the other units for which + `\maxdimen` is not attainable exactly, `\texdimen<uu>{\maxdimen}` + output is by luck the "down" approximant. +3. Similarly the macro `\texdimenwithunit{D1pt}{D2pt}` covers the entire + dimension range, but its output `F` for `D1pt` equal to or very close + to `\maxdimen` may be such that `F<D2pt>` represents a dimension + beyond `\maxdimen`, if the latter is not exactly representable. + Hence `F<D2pt>` would trigger "Dimension too large" on use. This can + only happen if `D2pt>1pt` and (roughly) `D1pt>\maxdimen-D2sp`. As + `D2sp` is less than `0.25pt`, this is not likely to occur in real + life practice except if deliberately targeting `\maxdimen`. For + `D2pt<1pt`, all dimensions `D1pt` are exactly representable, in + particular `\maxdimen`, and the output `F` will always be such that + TeX parses `F<D2pt>` into exactly the same dimension as `D1pt`. `\texdimenpt{<dim. expr.>}` @@ -306,8 +330,9 @@ Remarks about "Dimension too large" issues: > 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 attainable via `15312.02584dd`. +> will trigger on use "Dimension too large" error. +> `\maxdimen-1sp` is the maximal input for which the output remains +> less than `\maxdimen` (max attainable dimension: `\maxdimen-1sp`). `\texdimendddown{<dim. expr.>}` @@ -320,6 +345,9 @@ Remarks about "Dimension too large" issues: > Produces a decimal (with up to five decimal places) `D` such that `Ddd` > represents the dimension exactly if possible. If not possible it > will be larger by `1sp` from the original dimension. +> +> If input is `\maxdimen`, then `Ddd` virtually represents +> `\maxdimen+1sp` and will trigger on use "Dimension too large". `\texdimenmm{<dim. expr.>}` @@ -330,7 +358,7 @@ Remarks about "Dimension too large" issues: > would have been closer). > `\maxdimen` as input produces on output `5758.31741` and indeed the -> maximal attainable dimension is `5758.31741mm` (`1073741822sp`). +> maximal attainable dimension is `5758.31741mm` (`\maxdimen-1sp`). `\texdimenmmdown{<dim. expr.>}` @@ -343,6 +371,9 @@ Remarks about "Dimension too large" issues: > Produces a decimal (with up to five decimal places) `D` such that `Dmm` > represents the dimension exactly if possible. If not possible it > will be smallest representable dimension larger than the original one. +> +> If input is `\maxdimen`, then `Dmm` virtually represents +> `\maxdimen+2sp` and will trigger on use "Dimension too large". `\texdimenpc{<dim. expr.>}` @@ -352,7 +383,7 @@ Remarks about "Dimension too large" issues: > from above is chosen). > `\maxdimen` as input produces on output `1365.33333` and indeed the -> maximal attainable dimension is `1365.33333pc` (`1073741820sp`). +> maximal attainable dimension is `1365.33333pc` (`\maxdimen-3sp`). `\texdimenpcdown{<dim. expr.>}` @@ -365,6 +396,9 @@ Remarks about "Dimension too large" issues: > Produces a decimal (with up to five decimal places) `D` such that `Dpc` > represents the dimension exactly if possible. If not possible it > will be smallest representable dimension larger than the original one. +> +> If input is `>\maxdimen-3sp`, then `Dpc` virtually represents +> `\maxdimen+9sp` and will trigger on use "Dimension too large". `\texdimennc{<dim. expr.>}` @@ -374,9 +408,10 @@ Remarks about "Dimension too large" issues: > known in advance which one (and it is not known if the other choice > would have been closer). -> Warning: the output for `\maxdimen` is `1279.62628` but `1279.62628nc` -> will trigger "Dimension too large" error. -> `\maxdimen-9sp` is attainable via `1279.62627nc`. +> Warning: the output for `\maxdimen-1sp` is `1279.62628` but `1279.62628nc` +> will trigger on use "Dimension too large" error. +> `\maxdimen-2sp` is the maximal input for which the output remains +> less than `\maxdimen` (max attainable dimension: `\maxdimen-9sp`). `\texdimenncdown{<dim. expr.>}` @@ -389,6 +424,9 @@ Remarks about "Dimension too large" issues: > Produces a decimal (with up to five decimal places) `D` such that `Dnc` > represents the dimension exactly if possible. If not possible it > will be smallest representable dimension larger than the original one. +> +> If input is `>\maxdimen-9sp`, then `Dnc` virtually represents +> `\maxdimen+4sp` and will trigger on use "Dimension too large". `\texdimencc{<dim. expr.>}` @@ -399,7 +437,7 @@ Remarks about "Dimension too large" issues: > would have been closer). > `\maxdimen` as input produces on output `1276.00215` and indeed the -> maximal attainable dimension is `1276.00215cc` (`1073741821sp`). +> maximal attainable dimension is `1276.00215cc` (`\maxdimen-2sp`). `\texdimenccdown{<dim. expr.>}` @@ -412,6 +450,9 @@ Remarks about "Dimension too large" issues: > Produces a decimal (with up to five decimal places) `D` such that `Dcc` > represents the dimension exactly if possible. If not possible it > will be smallest representable dimension larger than the original one. +> +> If input is `>\maxdimen-2sp`, then `Dcc` virtually represents +> `\maxdimen+11sp` and will trigger on use "Dimension too large". `\texdimencm{<dim. expr.>}` @@ -422,7 +463,7 @@ Remarks about "Dimension too large" issues: > would have been closer). > `\maxdimen` as input produces on output `575.83174` and indeed the -> maximal attainable dimension is `575.83174cm` (`1073741822sp`). +> maximal attainable dimension is `575.83174cm` (`\maxdimen-1sp`). `\texdimencmdown{<dim. expr.>}` @@ -435,6 +476,9 @@ Remarks about "Dimension too large" issues: > Produces a decimal (with up to five decimal places) `D` such that `Dcm` > represents the dimension exactly if possible. If not possible it > will be smallest representable dimension larger than the original one. +> +> If input is `\maxdimen`, then `Dcm` virtually represents +> `\maxdimen+28sp` and will trigger on use "Dimension too large". `\texdimenin{<dim. expr.>}` @@ -444,9 +488,10 @@ Remarks about "Dimension too large" issues: > known in advance which one (and it is not known if the other choice > would have been closer). -> Warning: the output for `\maxdimen` is `226.70541` but `226.70541in` -> will trigger "Dimension too large" error. -> `\maxdimen-55sp` is maximal attainable dimension (via `226.7054in`). +> Warning: the output for `\maxdimen-18sp` is `226.70541` but `226.70541in` +> will trigger on use "Dimension too large" error. +> `\maxdimen-19sp` is the maximal input for which the output remains +> less than `\maxdimen` (max attainable dimension: `\maxdimen-55sp`). `\texdimenindown{<dim. expr.>}` @@ -459,102 +504,138 @@ Remarks about "Dimension too large" issues: > Produces a decimal (with up to five decimal places) `D` such that `Din` > represents the dimension exactly if possible. If not possible it > will be smallest representable dimension larger than the original one. +> +> If input is `>\maxdimen-55sp`, then `Din` virtually represents +> `\maxdimen+17sp` and will trigger on use "Dimension too large". `\texdimenbothcmin{<dim. expr.>}` -> Produces a decimal (with up to five decimal places) `D` such that `Din` -> is the largest dimension smaller than the original one and -> exactly representable both in the `in` and `cm` units. +> Produces a decimal (with up to five decimal places) `D` such that +> `Din` is the largest dimension not exceeding the original one (in +> absolute value) and exactly representable both in the `in` and `cm` +> units. `\texdimenbothincm{<dim. expr.>}` -> Produces a decimal (with up to five decimal places) `D` such that `Dcm` -> is the largest dimension smaller than the original one and -> exactly representable both in the `in` and `cm` units. It thus represents -> the same dimension as `\texdimenbothcmin{<dim. expr.>}in`. +> Produces a decimal (with up to five decimal places) `D` such that +> `Dcm` is the largest dimension not exceeding the original one (in +> absolute value) and exactly representable both in the `in` and `cm` +> units. Thus both expressions `\texdimenbothcmin{<dim. expr.>}in` and +> `\texdimenbothincm{<dim. expr.>}cm` represent the same dimension. `\texdimenbothcminpt{<dim. expr.>}` -> Produces a decimal (with up to five decimal places) `D` such that `Dpt` -> is the largest dimension smaller than the original one and -> exactly representable both in the `in` and `cm` units. It thus represents -> the same dimension as the one provided by `\texdimenbothcmin` and -> `\texdimenbothincm`. +> Produces a decimal (with up to five decimal places) `D` such that +> `Dpt` is the largest dimension not exceeding the original one (in +> absolute value) and exactly representable both in the `in` and `cm` +> units. It thus represents the same dimension as the one determined by +> `\texdimenbothcmin` and `\texdimenbothincm`. `\texdimenbothincmpt{<dim. expr.>}` -> Same as `\texdimenbothcminpt`. +> Alias for `\texdimenbothcminpt`. `\texdimenbothcminsp{<dim. expr.>}` -> Produces an integer (explicit digit tokens) `N` such that `Nsp` -> is the largest dimension smaller than the original one and +> Produces an integer (explicit digit tokens) `N` such that `Nsp` is the +> largest dimension not exceeding the original one in absolute value and > exactly representable both in the `in` and `cm` units. `\texdimenbothincmsp{<dim. expr.>}` -> Same as `\texdimenbothcminsp`. +> Alias for `\texdimenbothcminsp`. + +`\texdimenbothbpmm{<dim. expr.>}` + +> Produces a decimal (with up to five decimal places) `D` such that +> `Dmm` is the largest dimension smaller (in absolute value) than the +> original one and exactly representable both in the `bp` and `mm` +> units. + +`\texdimenbothmmbp{<dim. expr.>}` + +> Produces a decimal (with up to five decimal places) `D` such that +> `Dbp` is the largest dimension smaller (in absolute value) than the +> original one and exactly representable both in the `bp` and `mm` +> units. Thus `\texdimenbothmmbp{<dim. expr.>}bp` is the same +> dimension as `\texdimenbothbpmm{<dim. expr.>}mm`. + +`\texdimenbothbpmmpt{<dim. expr.>}` + +> Produces a decimal (with up to five decimal places) `D` such that +> `Dpt` is the largest dimension not exceeding the original one and +> exactly representable both in the `bp` and `mm` units. + +`\texdimenbothmmbppt{<dim. expr.>}` + +> Alias for `\texdimenbothbpmmpt`. + +`\texdimenbothbpmmsp{<dim. expr.>}` + +> Produces an integer (explicit digit tokens) `N` such that `Nsp` +> is the largest dimension not exceeding the original one and +> exactly representable both in the `bp` and `mm` units. + +`\texdimenbothmmbpsp{<dim. expr.>}` + +> Alias for `\texdimenbothbpmmsp`. `\texdimenwithunit{<dim. expr. 1>}{<dim expr. 2>}` > Produces a decimal `D` such that `D\dimexpr <dim expr. 2>\relax` is > considered by TeX the same as `<dim. expr. 1>` if at all possible. If -> not possible it will be a closest match either from above or below -> (but one does not know if the other direction is a better or worst -> match). +> the (assumed non zero) second argument `<dim2>` is at most `1pt` (in +> absolute value), then this is always possible. If the second argument +> `<dim2>` is `>1pt` then this is not always possible and the output `D` +> will ensure for `D<dim2>` to be a closest match to the first argument +> `dim1` either from above or below, but one does not know if the other +> direction would have given a better or worst match. > -> `\texdimenwithunit{dim}{1bp}` and `\texdimenbp{dim}` are not +> `\texdimenwithunit{<dim>}{1bp}` and `\texdimenbp{<dim>}` are not > the same: The former produces a decimal `D` such that `D\dimexpr -> 1bp\relax` is represented internally as is `dim` if at all possible, +> 1bp\relax` is represented internally as is `<dim>` if at all possible, > whereas the latter produces a decimal `D` such that `D bp` is the one -> aiming at being the same as `dim`. Using `D\dimexpr 1bp\relax` implies +> aiming at being the same as `<dim>`. Using `D\dimexpr 1bp\relax` implies > a conversion factor equal to `65781/65536`, whereas `D bp` involves > the `803/800` conversion factor. +> +> `\texdimenwithunit{D1pt}{D2pt}` output is close to the mathematical +> ratio `D1/D2`. But notwithstanding the various unavoidable "errors" +> arising from conversion of decimal inputs to binary internals, and +> from the latter to the former, the output `R` will tend to be +> on average slightly larger (in its last decimal) than mathematical +> `D1/D2`. The root cause being that the specification for `R` is that +> `R<D2pt>` must be exactly `<D1pt>` after TeX parsing, if at all +> possible; and it turns out this is always possible for `D2pt<1pt`. The +> final step in the TeX parsing of a multiplication of a dimension by a +> scalar is a *truncation* to an integer multiple of the `sp=1/65536pt` +> unit, not a rounding. So `R` is basically (i.e. before conversion to a +> decimal) `ceil(D1/D2,16)`, or to be more precise it is obtained as +> `ceil(N1/N2,16)` with `D1pt->N1sp`, `D2pt->N2sp` and the second +> argument of `ceil` means that `16` binary places are used. This +> formula is the one used for `D2pt<1pt`, for `D2pt>1pt` the mathematics +> is different, but the implication that `R` has a (less significant) +> bias to be "shifted upwards" (in its last decimal place) compared to +> the (rounded) value `D1/D2` or rather `N1/N2` still stands. -## 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. - -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 attainable, i.e. for all units except `bp`, and `nd` -(and `pt` but there is no "up" macro for it). - -The -dimensions representable with both `in` and `cm` units have the shape -`trunc(3613.5*k)sp` for some integer `k`. The largest one smaller -than a given dimension will thus differ from it by at most about `0.055pt`, -which is also about `0.02mm`. - -For example `\texdimenbothincm{1cm}` expands to `0.99994cm` which maps -internally to `1864566sp` which differs from TeX's `1cm` by only -`-113sp`. It can be obtained from `0.39368in` or `28.45102pt`. - -And `\texdimenbothcmin{1in}` expands to `0.99945in`, maps internally to -`4733685sp` which differs from TeX's `1in` by `-2601sp`. It can be obtained -as `2.5386cm` or `72.2303pt`. - -Currently the package does not provide analogous approximations from above. -For the `1in` for example it would be `4737298sp`, i.e. `1.00021in` which -differs from TeX's `1in` by `+1012sp` and is obtained also as `2.54054cm` -and `72.28543pt`. - ## Acknowledgements Thanks to Denis Bitouzé for raising an [issue](https://github.com/latex3/latex3/issues/953) on the LaTeX3 tracker which became the initial stimulus for this package. -Thanks to Ruixi Zhang for reviving the above linked-to thread -and opening up here [issue #2](https://github.com/jfbu/texdimens/issues/2) -asking to add handling of the `ex`,`em`, and `px` cases. This was done -at release `0.99` via the addition of `\texdimenwithunit`. +Thanks to Ruixi Zhang for reviving the above linked-to thread and +opening up on the package issue tracker the +[issue #2](https://github.com/jfbu/texdimens/issues/2) asking to add +handling of the `ex` and `em` cases. This was done at release `0.99` via +the addition of `\texdimenwithunit`. + +Renewed thanks to Ruixi Zhang for analyzing at +[issue #10](https://github.com/jfbu/texdimens/issues/10) what is at +stake into finding dimensions exactly representable both in the `bp` and +`mm` units. Macros `\texdimenbothbpmm` and `\texdimenbothmmbp` now +address this (release `1.0`). <!-- --> |