Impedindo que o LaTeX substitua uma variável

Impedindo que o LaTeX substitua uma variável

Atualmente estou brincando com macros (bastante novas) e parece que estou faltando algo bastante básico sobre macros LaTeX/TeX:

\def\car{Yes}
    \def\iszero#1{
    \ifnum#1=0{
        \let \car = Yes
    }
    \else{
        \let \car = No
    }
    \car
}
\iszero{1}

Retorna Sim.

Eu queria saber por que isso acontece e como posso evitar que o LaTeX seja substituído prematuramente \carpelo seu valor atual.

Responder1

Você quer

\def\car{Yes}
\def\iszero#1{%
  \ifnum#1=0 % Terminate number with a space
    \def\car{Yes}%
  \else
    \def\car{No}%
  \fi
}
\iszero{1}

Você está usando uma condicional primitiva do TeX, então as duas ramificações sãonãolugares entre colchetes: em vez disso, os são delimitados pelo final da condicional, o \elsee o \fi. A \letprimitiva só pode ser usada para atribuir um token ao valor de um segundo: você não pode usá-la para definir uma macro, que precisa de \def.

Responder2

A sintaxe para condicionais TeX não usa colchetes para os ramos verdadeiro e falso.

Também \letse comporta de maneira diferente do que você parece pensar: \let\foo=<token>torna \foo(quase) equivalente a <token>. No caso de

\let\car = Yes

o token Yseria atribuído \care esimpresso (se estivesse no branch não ignorado); o mesmo para \let\car = No.

Você deveria usar \def, em vez disso. Mas existem maneiras melhores que não exigem \car.

Assumindo TeX simples,

\long\def\firstoftwo#1#2{#1}
\long\def\secondoftwo#1#2{#2}

\def\iszero#1{%
  \ifnum#1=0
    \expandafter\firstoftwo
  \else
    \expandafter\secondoftwo
  \fi
  {Yes}{No}%
}

funcionaria: o \expandaftertruque varre os restos do texto condicional, deixando \firstoftwo{Yes}{No}ou \secondoftwo{Yes}{No}no fluxo de entrada.

Isso pode ser generalizado

\def\IfIsZeroTF#1{%
  \ifnum#1=0
    \expandafter\firstoftwo
  \else
    \expandafter\secondoftwo
  \fi
}

ser chamado como

\IfIsZeroTF{1}{Yes}{No}

Responder3

Alternativamente, coloque a comparação dentro da definição de \car.

%\def\car{Yes}%% Not needed for this example
\def\iszero#1{%
  \edef\car{%
    \ifnum#1=0
      Yes%
    \else
      No%
    \fi
  }}

False: \iszero{1}\car

True: \iszero{0}\car

Eu uso \edefpara obter apenas Yesou Noentrar \car. Se \deffor usado, existe o risco de a entrada ser alterada antes da avaliação, por exemplo, se a entrada for um contador.

informação relacionada