A reusable newlength (no stop/break if length already defined)
Your answer appears to work. A simpler method might consist of first \let
-ting the length variable in question to \relax
and then applying \newlength
to it. Put differently, if you can't remember if a certain macro name has been used before to denote a length parameter (or anything else, really!) and if you're comfortable with (re)using it anyway, you can first \let
it to \relax
and then issue a \newlength
directive.
\documentclass{article}
\begin{document}
\newlength\mytmplen
\setlength\mytmplen{10pt}
\the\mytmplen
\let\mytmplen\relax % let \mytmplen to \relax
\newlength\mytmplen % now it's safe to "re-issue" it as a length
\setlength\mytmplen{20pt}
\the\mytmplen
\end{document}
Here is a \providelength
command that will define a new length if not already defined, but also checks whether the command passed as argument has been defined with \newlength
, in order to issue an error message if you try to use, say, \providelength{\textit}
.
\documentclass{article}
\makeatletter
\newcommand{\providelength}[1]{%
\@ifundefined{\expandafter\@gobble\string#1}
{% if #1 is undefined, do \newlength
\typeout{\string\providelength: making new length \string#1}%
\newlength{#1}%
}
{% else check whether #1 is actually a length
\sdaau@checkforlength{#1}%
}%
}
\newcommand{\sdaau@checkforlength}[1]{%
% get the first five characters from \meaning#1
\edef\sdaau@temp{\expandafter\sdaau@getfive\meaning#1TTTTT$}%
% compare with the string "\skip"
\ifx\sdaau@temp\sdaau@skipstring
\typeout{\string\providelength: \string#1 already a length}%
\else
\@latex@error
{\string#1 illegal in \string\providelength}
{\string#1 is defined, but not with \string\newlength}%
\fi
}
\def\sdaau@getfive#1#2#3#4#5#6${#1#2#3#4#5}
\edef\sdaau@skipstring{\string\skip}
\makeatother
\begin{document}
\providelength{\foo}
\providelength{\foo}
\providelength{\textit}
\stop
Here is the terminal output:
\providelength: making new length \foo
\providelength: \foo already a length
! LaTeX Error: \textit illegal in \providelength.
See the LaTeX manual or LaTeX Companion for explanation.
Type H <return> for immediate help.
...
l.31 \providelength{\textit}
? h
\textit is defined, but not with \newlength
?
A version with expl3
, that avoids the trick for finding if the command is already a length.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\providelength}{m}
{
\cs_if_exist:NTF #1
{
\sdaau_providelength_check:N #1
}
{
\msg_info:nnx { providelength } { making } { \token_to_str:N #1 }
\newlength{#1}
}
}
\cs_new_protected:Nn \sdaau_providelength_check:N
{
\token_if_skip_register:NTF #1
{
\msg_info:nnx { providelength } { not-making } { \token_to_str:N #1 }
}
{
\msg_error:nnx { providelength } { defined } { \token_to_str:N #1 }
}
}
\msg_new:nnn { providelength } { making }
{
\token_to_str:N \providelength :~making~new~length~#1
}
\msg_new:nnn { providelength } { not-making }
{
\token_to_str:N \providelength :~#1~is~already~a~length
}
\msg_new:nnnn { providelength } { defined }
{
#1~illegal~in~\token_to_str:N\providelength
}
{
#1~is~defined,~but~not~with~\token_to_str:N\newlength
}
\ExplSyntaxOff
\begin{document}
\providelength{\foo}
\providelength{\foo}
\providelength{\textit}
\stop
This is the excerpt from the log file
.................................................
. providelength info: "making"
.
. \providelength: making new length \foo
.................................................
\foo=\skip49
.................................................
. providelength info: "not-making"
.
. \providelength: \foo is already a length
.................................................
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! providelength error: "defined"
!
! \textit illegal in \providelength
!
! See the providelength documentation for further information.
!
! For immediate help type H <return>.
!...............................................
l.47 \providelength{\textit}
? h
|'''''''''''''''''''''''''''''''''''''''''''''''
| \textit is defined, but not with \newlength
|...............................................