3

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?

4

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
  \ifx\@tempa\space\def\@tempa{0}\fi%  V added space
  \ifnum\ifnum\@tempa<\z@-\fi\@tempa>#3 \@badlinearg \fi}
\makeatother
1
  • Thank you for the analysis. Your solution works well. – npjg Aug 4 '19 at 1:47

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.