1

I'm trying to define a macro returning a calculated length, but making the parameter optional breaks the macro (error Missing number, treated as zero.):

\documentclass{article}

\usepackage{xfp}
\usepackage{numprint}

\newcommand{\testa}[1]{\fpeval{#1*0.03}\linewidth}
\newcommand{\testb}[1][1]{\fpeval{#1*0.03}\linewidth}

\begin{document}

\lenprint[pt]{\testa{1}}% prints 10,34958 pt

\lenprint[pt]{\testa{2}}% prints 20,69915 pt

\lenprint[pt]{\testb}% gives ERROR and prints 0.030 pt

\lenprint[pt]{\testb[2]}% gives ERROR and prints 0.060 pt

\end{document}

Can you help understand why?

Is there a way to make the parameter optional without breaking the working macro?

N.B. The above MWE uses \lenprint, but I'm asking for a solution working in general or at least with \addtolength, since my real world need is to use the macro as argument of \addtolength.

3
  • A command with an optional argument is not fully expandable, a required feature if you want to use it in the argument to \lenprint.
    – egreg
    Jun 25, 2021 at 8:31
  • @egreg Is there a way to make the parameter optional without breaking the working macro?
    – mmj
    Jun 25, 2021 at 8:37
  • Very short answer: no.
    – egreg
    Jun 25, 2021 at 8:39

1 Answer 1

1

You can define \testb as expandable macro. For example:

\long\def\testb#1{\ifx[#1\afterfi{\testbA[}\else\afterfi{\testbA[1]#1}\fi}
\def\testbA[#1]{\fpeval{#1*0.03}\linewidth}
\long\def\afterfi#1#2\fi{\fi#1}

It will not work in all cases but your case works:

\lenprint[pt]{\testb}% works

\lenprint[pt]{\testb[2]}% works
2
  • Just by chance; \lenprint does \setlength{\@tempdima}{#2} and so you get \@tempdima=\testb\relax which works because there is a token after \testb that can be taken as the argument. But it's very specific and other usages of \testb will definitely break.
    – egreg
    Jun 25, 2021 at 12:29
  • And it works also for my real world need which is using the macro as argument of \addtolenght, so thanks.
    – mmj
    Jun 25, 2021 at 18:00

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .