Is there a way of limiting the scope of \newlength? I'm using the same name in many TikZ picture but each with different value, and I don't want it to live on between the pictures as it's not intended to.


The following works for me and localizes the setting of lengths using grouping:

\setlength{\mylen}{30pt}% Global definition
Here is some text. \rule{40pt}{\mylen}

{% <--- \begingroup
\setlength{\mylen}{20pt}% Local redefinition
Here is some text. \rule{40pt}{\mylen}
}% <--- \endgroup

Here is some text. \rule{40pt}{\mylen}

Localized length setting


Remember that \newlength allocates a new (skip) register, which can then be used everywhere; \setlength acts locally, so its effect is limited to the group or environment in which it is given.

There's little use (in the most common situations) for local allocation. For limited scope one can use the "scratch" registers which are never allocated:

\dimen0 \dimen2 \dimen4 \dimen6 \dimen8 \dimen255 
\dimen1 \dimen3 \dimen5 \dimen7 \dimen9 

\skip0 \skip2 \skip4 \skip6 \skip8 \skip255
\skip1 \skip3 \skip5 \skip7 \skip9

\toks0 \toks2 \toks4 \toks6 \toks8 \toks255
\toks1 \toks3 \toks5 \toks7 \toks9

\box0 \box2 \box4 \box6 \box8
\box1 \box3 \box5 \box7 \box9

The registers <type>0 are also called <type>@ (\dimen@ is the same as \dimen0 and so on). The division into pair of lines is because registers in the top line should always be used locally and those in the second line "globally", that is, their setting should be preceded by \global (this is done to prevent "save stack buildup").

LaTeX allocates also \@tempdima, \@tempdimb, \@tempdimc (dimen registers); \@tempskipa, \@tempskipb (skip register); \@tempboxa (box register); \@tempcnta, \@tempcntb (count registers) and \count@ is the same as \count255.

So there's plenty of room for playing with registers for limited scope without allocating new ones. However, scratch registers may be exploited by the macro we are using in the same scope, so some care is necessary.


Each tikzpicture can contain local settings which will not effect other tikzpicture environments. The way to limit the scope within a single tikzpicture is to use \begin{scope} ... \end{scope}.

To illustrate, consider:


\setlength{\mylen}{1cm}% global definition

% y-coordinate can be ignored, only used for formatting the output.
% We use `mylen` to determine how the long the drawn line is

\setlength{\mylen}{2cm}% This is ONLY in effect within this tikzpicture
\draw [red,thick] (0,0) -- (\mylen,0) node [right] {2cm};

\draw [blue,thick] (0,-1) -- (\mylen,-1) node [right] {1cm};% not affected by above \setlength 
\setlength{\mylen}{3cm}% This is ONLY in effect within this scope
\draw [green,thick] (0,-1.2) -- (\mylen,-1.2) node [right] {3cm}; 
\draw [orange,thick] (0,-1.4) -- (\mylen,-1.4) node [right] {1cm};% not affected by above \setlength 

enter image description here

Before we we enter the tikzpicture environment, we have globally set the value of \mylen to 1cm. In the first tikzpicture, the setting to 2cm is local within that picture, as can be seen by the blue line in the subsequent picture -- it still used the initial setting of 1cm instead of 2cm.

In the second tikzpicture, we use \begin{scope} and set \mylen to 3cm and draw the green line. This setting reverts back to the prior setting at \end{scope} and hence the orange line is still 1cm long.

The following is copied directly from a related question on moving and rotating portions of a diagram as it is relevant here as well:

Inside a tikzpicture environment the scope environment applies all options local to the environment contents. Furthermore, if you include \usetikzlibrary{scopes} in the preamble, you can start a scope at "certain places" with a { provided that the single brace is followed by the options within [].

From the documentation (Section 12.3 in the v2.10 TiKZ & PGF manual):

The “certain places” where an opening brace has this special meaning are the following: First, right after the semicolon that ends a path. Second, right after the end of a scope. Third, right at the beginning of a scope, which includes the beginning of a picture. Also note that some square bracket must follow, otherwise the brace is treated as a normal TeX scope.


I don't really know what I'm doing here because I neither deal with \newlength a lot nor with lower-level commands like \let, but the following seems to work:








If you uncomment the second \rule, you'll get four error messages because \elephant is undefined – I think this is what you want?

  • The errors occur because \elephant is not a length after using \let. It is still defined in the last (commented) command, by virtue of \let. – Werner Sep 29 '11 at 19:30
  • So \let turns the length \elephant into a marco \elephant, which hence is invalid input for \rule? Would that still solve gablin's problem? – doncherry Sep 29 '11 at 19:35
  • 2
    Yes. \let\foo\bar duplicates the meaning of \bar by putting it into \foo. I don't know why one would want to have code that does not compile. Unless @gablin's question deals with isolating instances where using a length might be out-of-place. Perhaps the OP will be able to clarify by expanding the original question. – Werner Sep 29 '11 at 19:38

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.