2

I am trying to get the width of a macro parameter using

\def\getwidthof#1{%
    \newdimen\myl%
    \settowidth\myl{#1}%
    \the\myl%
}

where \settowidth is defined as

\catcode`\@=11
\newbox\@tempboxa
\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}
\catcode`\@=12

using egreg's answer here. I would like the code \getwidthof{some text} to print out the width of some text, which in this case would be 42.55563pt. The code

\newdimen\myl
\settowidth\myl{some text}
\the\myl

works, but breaks when a parameter is used. Is it because #1 is not expanded when put in \settowidth\myl{#1}?

btshepard
  • 680

2 Answers2

3

Error or not, your code is wrong anyway. You're allocating a new \dimen register each time you're calling \getwidthof and wasting resources.

Let's see with an error-free definition:

\def\getwidthof#1{%
    \csname newdimen\endcsname\myl%
    \settowidth\myl{#1}%
    \the\myl%
}
\catcode`\@=11
\newbox\@tempboxa
\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}
\catcode`\@=12

\getwidthof{abc} \getwidthof{def} \getwidthof{ghij}

\bye

The log file will have

\@tempboxa=\box16
\myl=\dimen16
\myl=\dimen17
\myl=\dimen18

Fixed code.

\catcode`\@=11
\newbox\@tempboxa
\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}
\catcode`\@=12

\newdimen\myl \def\printwidthof#1{% \settowidth{\myl}{#1}% \the\myl }

\printwidthof{abc}

\printwidthof{def}

\printwidthof{ghil}

\bye

enter image description here

egreg
  • 1,121,712
1

This also will helps:

\newbox\mywidthbox%
\newdimen\mywidthdimen%

\def\getwidthof#1{% \setbox\mywidthbox=\hbox{#1}% \mywidthdimen=\wd\mywidthbox% }

\getwidthof{test}

\showthe\mywidthdimen

\getwidthof{long test}

\showthe\mywidthdimen

\bye

16.16669pt.

37.8334pt.

MadyYuvi
  • 13,693