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.

I need a macro similar to \providecommand. \providelength{\lengthName}{0.5cm} should give me a new length if it is not existing yet. I would like to use the macro to set standard values for a TikzPicture if no desired values are given. I found the following code on the web but it is not working:

\documentclass[a4paper,10pt]{article}
\usepackage[utf8]{inputenc}

\makeatletter
\newcommand*\providelength[1]{%
  \begingroup
    \escapechar\m@ne
    \xdef\@gtempa{\string#1}%
  \endgroup
  \@ifundefined{\@gtempa}%
    {\newskip#1}%
    {}%
}
\makeatother

\begin{document}
  \providelength{\ltest}{0.1pt}
  \the\ltest

\end{document}

The output of this document is

0.1pt
0.0pt

Hence, the command seems to have no effect at all. Instead, the argument is printed out. Does anyone have an idea how to solve this?

share|improve this question
    
Doesn't tikz parse those values, so you could just store them in a macro, no need for a length. Does't etoolbox provide something similar? –  daleif Mar 13 at 11:52
    
@daleif: I thought etoolbox would provide it, but it doesn't not, as far as I know. –  Christian Hupfer Mar 13 at 12:07
    
If the length is already defined, setting it to a value might break the package that defined it. –  egreg Mar 13 at 12:41
    
@egreg: That is a fair statement -- if lengths are needed one should define such ones with very 'peculiar' names. –  Christian Hupfer Mar 13 at 14:07

1 Answer 1

up vote 11 down vote accepted

My solution assumes, that there is a \ character at the beginning of the length register name, it is not tested for tikz etc.

\documentclass[a4paper,10pt]{article}
\usepackage[utf8]{inputenc}
\usepackage{etoolbox}%
\usepackage{ifmtarg}%


\makeatletter
\newcommand*{\otherprovidelength}[2]{%
  \begingroup
    \escapechar\m@ne
    \xdef\@gtempa{\string#1}%
  \endgroup
  \@ifundefined{\@gtempa}%
    {\newskip#1%
     #1=#2}%  Assign the 2nd argument.
    {}%
}
\makeatother



\providecommand{\providelength}[2]{%
\ifdeflength{#1}{% It is already defined!
}{% Not defined, so define it!
\newlength{#1}%
}%
\setlength{#1}{#2}%
}%

\makeatletter
\providecommand{\ProvideLength}[2][]{%
% Check, if the command is already defined, if not, then define it!
\ifdeflength{#2}{% It is already defined!
\GenericWarning{}{Warning: Length #2 already defined!!!!!!!!} % Optional
}{% Not defined, so define it!
\newlength{#2}%
}%
\@ifmtarg{#1}{%  is 1st argument empty -> do not set the length at all!
}{% Set the length to the value of the 1st argument.
\setlength{#2}{#1}%  
}% End of \@ifmtarg
}% End of \providecommand
\makeatother



\begin{document}
  \providelength{\ltest}{0.01pt}
  \the\ltest \par
% Some testing
  \addtolength{\ltest}{0.05pt}
  \the\ltest \par 

  \ProvideLength[0.17pt]{\ltesttwo}
  \ProvideLength{\lyetanotherlength} % initialized to 0.0pt if undefined before
 \the\ltesttwo \par
 \the\lyetanotherlength
\end{document}

EDIT:

I added another command \ProvideLength which takes the length value as optional first argument and the length register names as 2nd argument. It will also generate a warning if the length register already exists.

I changed Simon's command to \otherprovidelength and added the missing 2nd argument as well as the assignment to the skip register.

share|improve this answer
    
that was what I was referring to –  daleif Mar 13 at 12:18
    
@daleif: I meant I my previous comment: I once thought that etoolbox would have such a command, but I had to write it myself some months ago. I did not want to contradict you. –  Christian Hupfer Mar 13 at 12:24
    
not at all, just wanted to emphasize that etoolbox has tool to build it. I did not formulate that comment very well. –  daleif Mar 13 at 12:30
    
Perhaps a typo? At the end of yur answer you say "My (optional) test results in 0.01pt 0.06pt", but your code will actually produce "10.0pt 10.05pt". Am I perhaps misunderstanding that final remark of your answer? –  Gonzalo Medina Mar 13 at 13:29
1  
@Simon: Your original command contains two logical errors: 1st: You use two arguments to \providecommand, but it is defined to have only one. 2nd: \newskip only defines a skip register, but does not set any value other than 0pt. I added another version of \providelength with a modified version of your command to my solution. See also tex.stackexchange.com/questions/22863/… –  Christian Hupfer Mar 14 at 3:23

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.