Предотвращение замены переменной в LaTeX

Предотвращение замены переменной в LaTeX

В настоящее время я работаю с макросами (довольно новичок) и, похоже, мне не хватает чего-то довольно элементарного в макросах LaTeX/TeX:

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

Возврат Да.

Мне было интересно, почему это происходит и как предотвратить преждевременную замену LaTeX \carтекущим значением.

решение1

Вы хотите

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

Вы используете примитивное условное выражение TeX, поэтому две ветвинетместа в фигурных скобках: вместо этого разделяются концом условного оператора, \elseи \fi. \letПримитив может использоваться только для назначения одного токена значению второго: вы не можете использовать его для определения макроса, для которого требуется \def.

решение2

Синтаксис условных операторов TeX не использует фигурные скобки для ветвей true и false.

Также \letведет себя не так, как вы, кажется, думаете: \let\foo=<token>делает \foo(почти) эквивалентным <token>. В случае

\let\car = Yes

токен Yбудет назначен \carи esвыведен на печать (если находится в непропущенной ветви); то же самое для \let\car = No.

Вместо этого следует использовать \def,. Но есть и лучшие способы, не требующие наличия \car.

Предположим, что это обычный TeX,

\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}%
}

сработает: \expandafterтрюк стирает остатки условного текста, оставляя либо , \firstoftwo{Yes}{No}либо \secondoftwo{Yes}{No}во входном потоке.

Это можно обобщить

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

называться как

\IfIsZeroTF{1}{Yes}{No}

решение3

В качестве альтернативы можно поместить сравнение внутрь определения \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

Я использую \edefдля получения только Yesили Noв \car. Если \defиспользуется, существует риск того, что входные данные будут изменены до оценки, например, если входные данные являются счетчиком.

Связанный контент