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, 2014 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, 2014 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, 2014 at 7:46

2 Answers 2

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.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .