
Estou implementando operadores não padronizados, desenhando-os como imagens usando o pict2e
pacote e depois dimensionando-os para caber nos vários modos matemáticos. Eu armazeno os parâmetros da imagem em macros externas e os invoco no picture
corpo.
Aqui está um exemplo mínimo:
\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}
Compilar isso no Overleaf e na minha instalação local do TeX Live, no entanto, gera um erro:Ausente = inserido para\ifnum
. Isso é seguido por outro erro:Número ausente, tratado como 0. Observe que esse comportamento se repete quando defino a \decimal
macro com \newcommand
. Também acontece quando o número tem ponto decimal, mas não tem parte fracionária (por exemplo, 3. e 3.0).
Esse comportamento ocorre com \vector
, mas não com \qbezier
nenhum dos outros comandos de imagem.
Se eu substituir a \decimal
invocação por um número decimal literal, a compilação será bem-sucedida. Eu sei que pict2e
apoia argumentos de inclinação real, em oposição à restrição de coprimalidade de picture
. Eu também sei que \ifnum
atua apenas em números inteiros.
Por que a compilação falha neste caso e por que apenas com \line
? Como posso fornecer corretamente \line
um argumento de inclinação decimal de uma macro?
Responder1
Isso foi um bug no pict2e
. Mandei um email para os mantenedores e Rolf respondeu positivamente. Ele incorporou as alterações abaixo e o problema deve ser corrigido agora (versão 0.3c, 20/08/2019).
A macro \pIIe@checkslopeargs
usada para fazer:
\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}
Ele armazena o primeiro argumento em uma macro temporária ( \def\@tempa{#1}
), depois expande essa macro temporária e chama \pIIe@checkslopearg
com ela. Contudo a linha
\def\@tempa{#1}\expandafter\pIIe@checkslopearg\@tempa.:{#3}
faz exatamente o mesmo que o mais simples
\pIIe@checkslopearg#1.:{#3}
e quando \pIIe@checkslopearg
expande, dividindo #1
no .
, ele não encontra o ponto se estiver oculto na sua \decimal
macro, mas funciona se você passar explicitamente. Depois disso, um número decimal entra em \ifnum
teste, tornando-se essencialmente \ifnum3.2<\z@
, que falha com Missing = inserted for \ifnum
.
O fato de o argumento ser armazenado em uma macro temporária e o códigofazsuporta números decimais, me leva a acreditar que isso é um bug. Para consertar você pode substituir os dois \def
por \edef
. Também adicionei um espaço ausente em uma macro que desencadearia uma expansão desnecessária.
Coloque isso no seu preâmbulo, após carregar 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