Почему персонаж, следующий за этим макросом, определяющим макрос, поглощается?

Почему персонаж, следующий за этим макросом, определяющим макрос, поглощается?

У меня есть следующий простой Tex-код:

\def\xx{ABC}
\def\temp #1 {\def\tempii{#1}}
\temp\xx a b c
\tempii\tempii

Я ожидаю увидеть следующий результат: a b c ABCABC

Но на самом деле я вижу это: b c ABCaABCa

Почему «а» попало в определение \tempii?

решение1

Я все еще думаю, почему это так, но эта доработка (включающая в себя \xx) дает вам то, что вы хотите.

Я думаю, ответ в том, что при использовании \temp\xx a b cпробел после \xxс точки зрения анализатора TeX вообще не является пробелом, а просто обозначает конец имени макроса \xx. Например, если вы просто поместите \xx Aстроку отдельно, вы увидите, что она будет напечатана как ABCAбез пробела. Таким образом, анализатор всасывает завершающую "A", как связанную с \xx. Можно также использовать \temp\xx{} a b c, как способ сообщить анализатору, что пробел является разделителем, а не просто следующим символом после \xx.

\documentclass{article}
\begin{document}
\def\xx{ABC}
\def\temp #1 {\def\tempii{#1}}
\temp{\xx} a b c
\tempii\tempii
\end{document}

решение2

Для ясности я буду обозначать пробелы как , так как они очень важны в обсуждении; пробелы в следующих примерах кода следует игнорировать.

Текст параметра \temp:

#1•

в то время как текст замены

\def\tempii{#1}

Ваш звонок \temp-

\temp\xx a•b•c•\tempii\tempii

Обратите внимание, что после этого \xxидет пробел, который служит только для разграничения макроса.нетпробел: это ничто, потому что TeX всегда игнорирует пробелы, следующие за controlслова(не контрольсимволы). Пробел после этого cберется из конца строки в вашем коде.

Следующие токены \tempсканируются (без расширения) для поиска совпадения с текстом параметра, где аргумент отделен пробелом, поэтому #1заканчивается, \xx aа следующим состоянием входного потока является

\def\tempii{\xx a}b•c•\tempii\tempii

Теперь TeX выполняет определение и удаляет его из входного потока:

b•c•\tempii\tempii

и часть b•c•передается на этап набора. После расширения двух копий \tempiiэто эквивалентно набору

b•c•\xx a\xx a

или

b•c•ABCaABCa

именно это вы и получили.

Если бы вы использовали \?вместо этого \xxпоследние две строки были бы преобразованы в

\temp\?•a•b•c•\tempii\tempii

потому что \?это управляющий символ и TeX не игнорирует пробелы после них. В этом случае результат будет

a•b•c•ABCABC

Обратите внимание, что

\expandafter\temp\xx a•b•c
\tempii\tempii

приведет к тому же результату, потому что после действия \expandafterTeX будет представлено

\temp ABCa•b•c

(то же соглашение для пробелов, что и раньше, конечно). Вы получите тот же результат, что и with \?вместо \xxwith

\expandafter\temp\expandafter\xx\space a•b•c

потому что тогда TeX будет представлен

\temp\xx•a•b•c

Действительно, пробелы после контрольных слов игнорируются только в процессе токенизации.

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