
У меня есть команда \yesifone
, которая должна принимать либо 1
либо 0
в качестве аргумента и ведет себя по-разному в зависимости от этих двух случаев. Я хочу передать ей вывод команды \one
. Однако \one
полагается на какую-то другую команду \blah
, которая не генерирует вывод (в моем конкретном случае она устанавливает переменную). Моя текущая попытка заставить это работать терпит неудачу, предположительно, потому что ifnum
включает \blah{}
в сравнение , а не только число 1
. Как мне заставить это работать, например, игнорируя \blah{}
вызов и проверяя только текст вывода?
Другими словами, я хотел бы вывести следующее yes
.
\documentclass{minimal}
\begin{document}
\newcommand{\blah}{}
\newcommand{\one}{
\blah{}
1
}
\newcommand{\yesifone}[1]{%
\ifnum1=#1\relax{yes}\else{no}\fi
}
\yesifone{\one} % error: Missing number, treated as zero.
\end{document}
решение1
С вашим кодом \yesifone{\one}
выдаются токены
\yesifone{1\one}2
Это расширяется до .
\ifnum112=12\one\relax{1y11e11s11}2\else{1n11o11}2\fi
На момент сбора токенов, принадлежащих \ifnumвторому TeX-⟨число⟩-количество, т.е. число позади , токен расширяется, таким образом, у вас есть что-то вроде=12\one
\ifnum112=12␣10\blah{1}2␣10112␣10\relax{1y11e11s11}2\else{1n11o11}2\fi.
Пробел-токены сразу за удаляются и расширяются и просто исчезают, поскольку его замещающий текст пуст. Таким образом, у вас есть что-то вроде:␣10=12\blah
\ifnum112=12{1}2␣10112␣10\relax{1y11e11s11}2\else{1n11o11}2\fi.
Итак, во время сбора токенов, которые принадлежат \ifnumвторому TeX-⟨число⟩-количество, т. е. число после , TeX находит пустую группу фигурных скобок, т. е. явные-символьные-токены и , что определенно не образует начало последовательности токенов, которые образуют допустимый TeX-⟨=12{1}2число⟩-количество.
Подумайте об аналогии Кнута с TeX — зверем с глазами и пищеварительным трактом.
- Расширение расширяемых токенов происходит в глотке в виде своего рода процесса регургитации, если только расширение не подавляется, как в случае, например, с токенами, которые формируют текст параметра или текст замены -назначения
\def
. (LaTeX\newcomand
и\NewDocumentCommand
т. п. являются сложными оболочками для вызова\def
.) - Задания происходят в желудке.
Поэтому отделите такие задачи, как присвоение значений «переменным», которые задействуют желудок для выполнения работы, не связанной с набором текста, от задач, где достаточно пищевода/расширения расширяемых токенов и где пищеварительные органы за пищеводом задействованы только для набора текста:
\documentclass{minimal}
% Introduce/initialize things used as variable whose value is
% to be set via assignments that take place in the stomach:
\newcommand\VariableRelatedToBlah{}
% Define macros for tasks that involve digestive organs behind the gullet for
% for non-typesetting-tasks, e.g.,_setting_ values of variables via assignments:
\newcommand\SetValueOfVariableRelatedToBlah[1]{%
\def\VariableRelatedToBlah{#1}%
}
% Define macros for tasks that involve only the gullet, e.g.,
% _retrieving_ values of variables, or additionally to the gullet
% involve digestive organs behind the gullet only for typesetting:
\newcommand\RetrieveValueOfVariableRelatedToBlah{%
\VariableRelatedToBlah
}
\newcommand\firstofone[1]{#1}%
\newcommand{\yesifone}[1]{%
\ifnum1=\expandafter\firstofone\expandafter{\number#1} yes\else no\fi
}
\begin{document}
% Now you can keep work that involves the stomach for non-typesetting
% separated from work where the gullet is sufficient/where tokens
% delivered by the gullet can directly be used for typesetting:
\SetValueOfVariableRelatedToBlah{0}%
\yesifone{\RetrieveValueOfVariableRelatedToBlah}
\SetValueOfVariableRelatedToBlah{1}%
\yesifone{\RetrieveValueOfVariableRelatedToBlah}
\end{document}