Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

How can I declare a length via pgfmathsetlength global?

The example results in 20pt -- 5pt -- 20pt But I had expected: 20pt -- 5pt -- 5pt

\documentclass[10pt]{article}
\parindent0pt
\usepackage{tikz}
\newlength\testl
\pgfmathsetlength\testl{20pt}
\begin{document}
\the\testl

{\global\pgfmathsetlength\testl{5pt}\the\testl}

\the\testl
\end{document}

I don't want to discuss possibilities with \setlength or \deflength.

share|improve this question
    
What does your .log file say about using \global? –  Werner Dec 20 '11 at 21:43
2  
It's interesting that \global doesn't issue an error; this is because the token that actually it acts on is \futurelet; it definitely doesn't act on the setting of \testtl's value, unfortunately. –  egreg Dec 20 '11 at 21:46
add comment

2 Answers

up vote 11 down vote accepted

You can use \global like this :

 {\pgfmathsetlength{\global\testl}{5pt}}\the\testl

Some remarks : Egreg notices this code is very similar to

\setlength{\global\testl}{5pt}

It may be interesting to know what the macro pgfmathsetlength provides. In the file pgfmathcalc.code.tes we can read :

% #1 = dimension register
% #2 = expression
%
% Description:
%
% These functions work similar to \setlength and \addtolength. Only,
% they allow #2 to contain an expression, which is evaluated before
% assignment. Furthermore, the font is setup before the assignment is
% done, so that dimensions like 1em are evaluated correctly.
%
% If #2 starts with "+", then a simple assignment is done (but the
% font is still setup). This is orders of magnitude faster than a
% parsed assignment.

Another possibility to declare a length global is to redefine pgfmathsetlength but it's bad or to use a new macro :globalpgfmathsetlength based on pgfmathsetlength. We need to add \global in two lines but simplest is my first answer.

 \makeatletter
 \def\globalpgfmathsetlength#1#2{%
    \expandafter\pgfmath@onquick#2\pgfmath@%
    {%
        % Ok, quick version:
        \begingroup%
            \pgfmath@selectfont%
            \pgfmath@x#2\unskip%
            \pgfmath@returnone\pgfmath@x%
        \endgroup%
        \global#1\pgfmathresult pt\relax% here add \global before #1
    }%
    {%
        \pgfmathparse{#2}%
        \global#1\pgfmathresult pt\relax% and here
    }%
    \ignorespaces%
}  
share|improve this answer
2  
Very similar to \setlength{\global\testl}{5pt} (which works). :) –  egreg Dec 20 '11 at 23:14
add comment

Use a scratch dimension

{\dimendef\temp=0
 \pgfmathsetlength\temp{5pt}\global\testl=\temp}

Note. I wouldn't use \testl in place of \temp, in order to avoid "save stack buildup".

share|improve this answer
    
Interesting. Why does save stack buildup occur if \testl is used instead of \temp. Shouldn't the local assignment not being discarded at the end of the group? –  Martin Scharrer Dec 20 '11 at 22:16
    
@MartinScharrer It will happen if \testl has already been used in the outer level. –  egreg Dec 20 '11 at 22:25
    
Why isn't a previously local assignment in the outer level not be discarded from the save stack as soon a global assignment is made? Or is this technical not feasible? –  Martin Scharrer Dec 21 '11 at 9:44
    
@MartinScharrer It's clearly explained both in the TeXbook and in TeX by Topic. A local assignment makes TeX push the "outer value" in the save stack and there it will remain, since the global assignment made in the group will tell TeX not to go fetching that value again. Why the useless entry is not discarded must be asked to Knuth. –  egreg Dec 21 '11 at 10:02
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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