3

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?)

3
  • 1
    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
  • 2
    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
1

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.

In your case,

\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.

0

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.

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.