# Using skip (glue) with pgfmath (truncating plus/minus parts from a glue length)?

Consider the following MWE:

\documentclass{article}

\usepackage{tikz}
\newlength{\tlen}
\newlength{\tlenB}

\begin{document}

\setlength{\tlen}{2cm}
\typeout{check 1, tlen is: \the\tlen}
\pgfmathsetlength{\tlenB}{2cm}
\typeout{check 1, tlenB is: \the\tlenB}

\setlength{\tlen}{2cm plus 2pt minus 1pt}
\typeout{check 2, tlen is: \the\tlen}
\pgfmathsetlength{\tlenB}{2cm plus 2pt minus 1pt}
\typeout{check 2, tlenB is: \the\tlenB}

\end{document}


It results with this output:

This is pdfTeX, Version 3.1415926-2.3-1.40.12 (TeX Live 2011)
...
check 1, tlen is: 56.9055pt
check 1, tlenB is: 56.9055pt
check 2, tlen is: 56.9055pt plus 2.0pt minus 1.0pt

! Package PGF Math Error: Unknown operator p' or pl' (in '2cm plus 2pt minus
1pt').

See the PGF Math package documentation for explanation.
Type  H <return>  for immediate help.
...

l.15 ...hsetlength{\tlenB}{2cm plus 2pt minus 1pt}


So, apparently \pgfmathsetlength (or pgfmath in general?) cannot handle glue-type lengths, in particular the plus and minus parts.

What option do I have in using glue-type length skip with pgfmath? If nothing better is possible, then I'd settle for the fixed part only (i.e. I could live with the plus/minus stretchable/shrinkable parts being truncated)...

(Note to self: good intro on glues here: What is glue stretching?)

• The buzzword is a skip (as opposed to glue-type length) and pgfmath obtains a single number as a result of a math operation. Hence you can't set a skip with stretch/shrink values. It is not meant to be a generic length setter. – percusse Sep 1 '14 at 20:02
• LaTeX lengths defined with \newlength are rubber lengths (skips, in TeXbook terminology), while \pgfmathsetlength is only able to cope with rigid lengths (\dimen registers). Unfortunate clash of terms. – egreg Sep 1 '14 at 21:12
• Thank you both @percusse and @ egreg for the comments, great as reference; I tried to edit the post a bit as well. Cheers! – sdaau Sep 2 '14 at 7:46

Look at how \pgfmathsetlength works (from pgfmathcalc.code.tex):

\def\pgfmathsetlength#1#2{%
\expandafter\pgfmath@onquick#2\pgfmath@%
{%
% Ok, quick version:
\begingroup%
\pgfmath@selectfont%
#1#2\unskip%
\expandafter\endgroup%
\expandafter#1\the#1\relax%
}%
{%
\pgfmathparse{#2}%
\ifpgfmathmathunitsdeclared%
#1\pgfmathresult mu\relax%
\else%
#1\pgfmathresult pt\relax%
\fi%
}%
\ignorespaces%
}


The “quick version” is chosen when the second argument starts with + (see section 88.3 in the manual), which is not the case here. In the “normal case”, the expression is evaluated as usual and turned into a decimal number (meaning unit points); if the original expression had mu units, also the final setting will be with mu units.

\pgfmathparse{2cm plus 2pt minus 1pt}


is tried, which is illegal and throws

! Package PGF Math Error: Unknown operator p' or pl' (in '2cm plus 2pt minus 1pt').


This doesn't happen with

\pgfmathparse{\tlen}


which would be executed by \pgfmathsetlength{\tlenB}{\tlen} because rubber lengths (\skip) are coerced to rigid lengths (\dimen) when found in the latter context.

In plain TeX terms, if you do

\newskip\tlen
\newdimen\temp

\tlen=1pt plus 2pt minus 3pt % a silly value just for example
\temp=\tlen


the \dimen register \tlen is set to 1pt; the stretch and shrink components are discarded.

In conclusion, \pgfmathsetlength works with rigid lengths. To the contrary, LaTeX's \newlength allocates a rubber length register.

A case of unfortunate terminology conflict. A rule of thumb is remembering that rubber lengths have no use in TikZ pictures (unless text is being typeset in them, but it's a different matter), whereas in text mode rubber lengths are as much used as rigid ones.

I just discovered this by accident while writing the question, so I better note it down: by replacing the below snippet in the code above:

...
\setlength{\tlen}{2cm plus 2pt minus 1pt}
\typeout{check 2, tlen is: \the\tlen}
\pgfmathsetlength{\tlenB}{\tlen}
\typeout{check 2, tlenB is: \the\tlenB}
...


... the code will compile without errors, with the following output:

check 1, tlen is: 56.9055pt
check 1, tlenB is: 56.9055pt
check 2, tlen is: 56.9055pt plus 2.0pt minus 1.0pt
check 2, tlenB is: 56.9055pt


... which means that as long as a glue length is set via \setlength, such a length can (apparently) be used as an argument to \pgfmathsetlength, and it will pass - with the plus and minus truncated from the \pgfmathsetlength variable.