8

In plain TeX and derivative formats, the concept of stretchable/shrinkable length, AKA a glue or a skip or a rubber length exists, in general defined as

<dimen> plus <stretch-dimen> minus <shrink-dimen>

where <dimen> is the base dimension and <stretch-dimen> and <shrink-dimen> are the maximum stretch and shrink values, respectively. The skip length will adjust within these bounds to fit its container.

Since the smallest unit of TeX computation is the scaled point, 1sp, I assume that all stretch/shrink computations are quantized at this level.

Is it possible to change the "unit of quantization" for skip lengths? My thought is that it's not, because this is deep down at (inside) the primitive. But I'm far from a TeXpert, and if it were possible, I think it could be useful for grid-like typesetting tasks.

Here is a much-simplified MWE that sets up the general idea with plain TeX code:

\def\z{\hbox to 0pt{\hss\strut\vrule\hss}}
\def\zz{\z\hskip4pt}
\def\zzz{\zz\zz\zz\zz\zz}
x\z\hskip12pt plus 12pt minus 0pt %step 4pt
\z

x\z\hskip16pt plus 12pt minus 0pt %step 4pt
\z

x\hbox to 23pt{\z\hfill\hskip16pt plus 12pt minus 0pt %step 4pt
\z\hfill}

x\zzz\zzz\zzz\zzz
\bye

which produces:

enter image description here

In the first two lines, the base dimension is used, so the rules align with the "grid" (the last line). However, in the penultimate line, a stretch component is used that is not a multiple of the grid spacing, so the rule is not aligned.

Is there a way to adjust the "quantization" so that the stretch component snaps to the nearest multiple of the grid spacing (here, 4pt)?

  • Use \scalebox{20000.0}{...}? – John Kormylo Apr 20 '15 at 4:20
  • Sorry @JohnKormylo, I don't think that will do what I want. Won't that just scale the contents, or am I missing something? – Paul Gessler Apr 20 '15 at 4:26
  • Multiplying by 20000 converts 1sp to 4pt. Seriously though, you should probably use \pgfmathparse to do the calculations. – John Kormylo Apr 20 '15 at 4:29
  • 1
    I don't think that it is possible, but I also think that it wouldn't be so useful. Don't forget that the text can have different width or height -- replace one x by i or change the font size -- and you wouldn't want to use only unproportional fonts and one font size in grid typesetting. So you don't need quantized stretch spaces but a mean to go to the next grid position. – Ulrike Fischer Apr 20 '15 at 7:25
  • 1
    at scalebox{20000}. IMHO this is not a way to solution, because you need to scale down (by 1/20000) all typesetting material, so the less precision will manifest in all typesetting: positions of all letters, not only scalable glue. – wipet Apr 20 '15 at 14:32
7

The calculation of "plus and minus" results are done in TeX using computer-dependent implementation of numbers, so Knuth decided that there will be no possibility to access these results by macro programmer in order to disable of creating computer-dependent results in document by macro language.

I suggest the macro \roundto{dimen}. This macro recalculates the width of the previous box to the multiply of "dimen". The usage in our example would be:

x\hbox to 23pt{\z\hfill\hskip16pt plus 12pt minus 0pt \z\hfill}

x\hbox{\z\hskip16pt}\hbox to\dimexpr(23pt-16pt)/2{\hfil}\roundto{4pt}\z

x\zzz\zzz\zzz\zzz

Your example (first line) includes fixed \hskip16pt plus 2*\hfill in 23pt. So each \hfill takes (23pt-16pt)/2 space. The \z is after first \hfill so the second box in my example has this dimension. And the \roundto macro rounds the width of this box to multiple of 4pt. The \z is printed after rounding.

The \roundbox macro can be implemented like this:

\newcount\tmpnum
\def\roundto#1{\setbox0=\lastbox \tmpnum=\wd0 \dimen0=#1\relax
   % \advance\tmpnum by\dimexpr \dimen0/2\relax
   % uncomment this ^ ^, if you need "central" roundning
   % \advance\tmpnum by\dimen0 \advance\tmpnum by-1
   % uncomment this ^ ^, if you need "upper" roundning
   \divide\tmpnum by\dimen0 \multiply\tmpnum by\dimen0
   \wd0=\the\tmpnum sp
   \box0
}

Meaningful usage of \roundto macro:

x\hbox{\z various text\quad}\roundto{4pt}\z next text is aligned.

x\zzz\zzz\zzz\zzz

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.