# pict2e: Cannot use decimal line slope argument inserted from macro

I am implementing nonstandard operators by drawing them as pictures using the pict2e package and then scaling them to fit in the various math modes. I store the picture's parameters in external macros and invoke them in the picture body.

Here is a minimal example:

\documentclass{article}
\usepackage{pict2e}

\def\num{3}
\def\decimal{3.2}
\newcommand*\testfigure{%
\begin{picture}(3,3)(0,0)
\put(0, 0){\line(0, \decimal){\num}}
\end{picture}
}

\begin{document}
\testfigure
\end{document}


Compiling this on Overleaf and my local TeX Live installation, however, raises an error: Missing = inserted for \ifnum. This is followed by another error: Missing number, treated as 0. Note that this behavior repeats when I define the \decimal macro with \newcommand. It also happens when the number has a decimal point but no fractional part (e.g. 3. and 3.0).

This behavior recurs with \vector, but not with \qbezier or any of the other picture commands.

If I replace the \decimal invocation with a literal decimal number, compilation succeeds. I know pict2e supports real slope arguments, as opposed to the coprimality restriction of picture. I also know that \ifnum acts on integers only.

Why does compilation fail in this case, and why only with \line? How can I properly give \line a decimal slope argument from a macro?

This was a bug in pict2e. I mailed the maintainers and Rolf replied positively. He incorporated the changes below and the problem should be fixed now (version 0.3c, 20-08-2019).

The macro \pIIe@checkslopeargs used to do:

\renewcommand*\pIIe@checkslopeargs[3]{%
\def\@tempa{#1}\expandafter\pIIe@checkslopearg\@tempa.:{#3}%
\def\@tempa{#2}\expandafter\pIIe@checkslopearg\@tempa.:{#3}%
\ifdim #1\p@=\z@ \ifdim #2\p@=\z@ \@badlinearg \fi\fi}


It stores the first argument in a temporary macro (\def\@tempa{#1}), then expands that temporary macro and calls \pIIe@checkslopearg with that. However the line

\def\@tempa{#1}\expandafter\pIIe@checkslopearg\@tempa.:{#3}


does exactly the same as the simpler

\pIIe@checkslopearg#1.:{#3}


and when \pIIe@checkslopearg expands, splitting #1 in the ., it doesn't find the dot if it is hidden in your \decimal macro, but it does work if you pass it explicitly. After that a decimal number goes into an \ifnum test, essentially becoming \ifnum3.2<\z@, which fails with Missing = inserted for \ifnum.

The fact that the argument is stored in a temporary macro and the code does support decimal numbers, leads me to believe this is a bug. To fix it you can replace the two \def by \edef. I also added a missing space in a macro which would trigger unnecessary expansion.

Put this in your preamble, after loading pict2e:

\makeatletter
\renewcommand*\pIIe@checkslopeargs[3]{%
%  V \edef instead of \def
\edef\@tempa{#1}\expandafter\pIIe@checkslopearg\@tempa.:{#3}%
\edef\@tempa{#2}\expandafter\pIIe@checkslopearg\@tempa.:{#3}%
\ifdim #1\p@=\z@ \ifdim #2\p@=\z@ \@badlinearg \fi\fi}
\def\pIIe@checkslopearg #1.#2:#3{%
\def\@tempa{#1}%
\ifx\@tempa\empty\def\@tempa{0}\fi