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 sometimes encounter a problem when I attempt to use \widthof from the calc package, and don't know why. In the past I have just worked around it using a two step process of defining a \newdimen{} and using \settowidth (or \setlength and \widthof) to determine the value before attempting to use this length.

The MWE below shows how this fails when I attempt to use the \widthof as the length of a \kern (i.e., the \KernA macro), but the two step process works just fine:

enter image description here

Questions:

  1. Why does \KernA not work?
  2. When can I use \widthof directly?

References:

Code:

\documentclass{article}
\usepackage{calc}

\newcommand*{\KernA}{\kern\widthof{$text$}}%

\newdimen{\KernAmount}%
\newcommand*{\KernB}{%
    \setlength{\KernAmount}{\widthof{$text$}}%
    \kern\KernAmount%
}%

\newcommand*{\KernC}{%
    \settowidth{\KernAmount}{$text$}%
    \kern\KernAmount%
}%


\begin{document}
x~$text$~y 

%x~\KernA~y  \verb|\kernA: \widthof| ??

x~\KernB~y  \verb|\KernB: \setlength and \widthof|

x~\KernC~y  \verb|\KernC: \settowidth|
\end{document}
share|improve this question
1  
You could just use \hphantom{$text$} instead. –  Martin Scharrer May 1 '12 at 20:47
    
@MartinScharrer: Yes that would be a simpler solution for this situation in the MWE, but this was meant to be a more general question. –  Peter Grill May 1 '12 at 20:55
add comment

2 Answers

up vote 12 down vote accepted

\kern is a TeX primitive which awaits a dimension expression, while \widthof is a calc package function which only works in \setlength and friends. It requires internal box assignments, which are not allowed in a normal dimension expression. You can't therefore use \widthof and other things like this at positions where TeX dimension expressions are awaited. You need to use \setlength first to assign the value to a length register and then use this register, as you did.

share|improve this answer
add comment

The problem here is that \widthof is actually only a "macro" that works inside one of calc's redefined length macros. Using \show\widthof you'll note that it is actually defined as \ignorespaces... a placeholder and action to remove any preceding spaces in the argument. As such, your two-step procedure (using an interim length) is required to obtain the desired result.

The alternative \settowidth macro does box assignment and length extraction using (from latex.ltx):

\def\@settodim#1#2#3{\setbox\@tempboxa\hbox{{#3}}#2#1\@tempboxa
       \setbox\@tempboxa\box\voidb@x}
\def\settoheight{\@settodim\ht}
\def\settodepth {\@settodim\dp}
\def\settowidth {\@settodim\wd}
share|improve this answer
3  
The calc package redefines \setcounter, \addtocounter, \setlength and \addtolength to benefit from the extended syntax. Only in their arguments \widthof and the similar commands receive the meaning for doing computations; outside of them they are equivalent, as you say, to \ignorespaces. –  egreg May 1 '12 at 21:14
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.