2
\documentclass[10pt]{article}
\usepackage{calc}
\usepackage{fp}
\newcommand{\test}[1]{
\makeatletter
\setlength{\tempdimen}{\widthof{#1}}
\FPeval\‌​resultaP(70-\strip@pt\tempdimen)/2}
\makeatother}
\begin{document}
\test{5}
\end{document}

The command does not work when called in the document. However, if its contents are typed manually, it seems to work. Could someone please help?

user111
  • 411

1 Answers1

3

As explained in the question Manuel linked, the first problem is that you cannot use \makeatletter ... \makeatother in the definition of a macro.

\makeatletter
\newcommand{\test}[1]{
\setlength{\tempdimen}{\widthof{#1}}
\FPeval\‌​resultaP(70-\strip@pt\tempdimen)/2}
}
\makeatother

In addition, you cannot \setlength a length without creating it first.

\makeatletter
\newlength\tempdimen
\newcommand{\test}[1]{
  \setlength{\tempdimen}{\widthof{#1}}
  \FPeval\‌​resultaP(70-\strip@pt\tempdimen)/2}
}
\makeatother

If we are working from your code, we also need to eliminate the strange invisible characters.

\makeatletter
\newlength\tempdimen
\newcommand{\test}[1]{
  \setlength{\tempdimen}{\widthof{#1}}
  \FPeval\resultaP{(70-\strip@pt\tempdimen)/2}
  \FPprint‌\resultaP
}
\makeatother

Then it works without issue. (\FPprint\resultaP added for demonstration purposes.)

However, this code will not necessarily give you the results you want. For example,

Here is an example: \test{5}.

Here is another: \test{5}--\test{7809}.

produces

spurious spaces

because the definition of the macro tells TeX to insert spaces at various points - quite a lot of them, in fact.

To avoid this, we need

\newcommand{\test}[1]{%
  \setlength{\tempdimen}{\widthof{#1}}%
  \FPeval\resultaP{(70-\strip@pt\tempdimen)/2}%
  \FPprint‌\resultaP
}

which gives the expected result

expected result

\documentclass[10pt]{article}
\usepackage{calc}
\usepackage{fp}
\makeatletter
\newlength\tempdimen
\newcommand{\test}[1]{%
  \setlength{\tempdimen}{\widthof{#1}}%
  \FPeval\resultaP{(70-\strip@pt\tempdimen)/2}%
  \FPprint‌\resultaP
}
\makeatother
\begin{document}
Here is an example: \test{5}.

Here is another: \test{5}--\test{7809}.
\end{document}

As Heiko Oberdiek points out, for the minimal example, at least, \widthof is not required and calc need not be used. (In fact, I'd never heard of \widthof and have always used \settowidth so tested with that originally.)

\documentclass[10pt]{article}
\usepackage{fp}
\makeatletter
\newlength\tempdimen
\newcommand{\test}[1]{%
  \settowidth\tempdimen{#1}%
  \FPeval\resultaP{(70-\strip@pt\tempdimen)/2}%
  \FPprint‌\resultaP
}
\makeatother
\begin{document}
Here is an example: \test{5}.

Here is another: \test{5}--\test{7809}.
\end{document}

There are easier packages to use than fp by now, I think. Or, at least, better documented ones.

cfr
  • 198,882
  • 1
    Very comprehensive +1. A last step, package calc with \widthof is not really needed here, the setting of \tempdimen can be simplified by \settowidth. – Heiko Oberdiek May 22 '16 at 07:00
  • @HeikoOberdiek I thought maybe that was needed for other 'big picture' reasons. I noticed that you answered a question explicitly about using \widthof with fp. But if you think it is worth adding that, I can do so. I actually tested with \settowidth because I'd never come across \widthof before and always find fp confusing enough to begin with. (I think just the TODO status of the documentation ...) – cfr May 22 '16 at 13:26
  • @HeikoOberdiek I've added your suggested version. Is there an advantage to \widthof? I've never come across it before, but perhaps I've just led a sheltered life ;). – cfr May 22 '16 at 14:58
  • The advantage of \widthof (and \heightof, \depthof, \totalheightof) is that these commands can be used inside calc expressions of \addtolength and \setlength. – Heiko Oberdiek May 22 '16 at 15:02
  • @HeikoOberdiek Oh, OK. I see that. I just wondered if there was anything else. Thanks a lot! – cfr May 22 '16 at 15:03