Какие токены TeX не использует в качестве неразделенных аргументов (кроме как между { и } )?

Какие токены TeX не использует в качестве неразделенных аргументов (кроме как между { и } )?

Какие токены TeX не использует в качестве неразделенных аргументов (если только они не вложены между явным символьным токеном с кодом категории 1 и явным символьным токеном с кодом категории 2)?

В предпоследнем абзаце об опасном повороте перед упражнением 20.4 учебника TeXbook вы найдете предложение:

После того, как вы сказали ' \def\row#1#2{...}', вы можете ставить пробелы между аргументами (например, ' \row x n'), поскольку TeX не используетодиночные пробелыкак неразделенные аргументы.

В параграфе «Двойной опасный изгиб» перед упражнением 20.5 учебника TeXbook вы найдете предложение:

Как TeX определяет, где заканчивается аргумент, спросите вы. Ответ:[...]Неотделенный параметр следует сразу в⟨текст параметра⟩параметром-токеном, или он находится в самом конце текста параметра; в этом случае соответствующий аргумент является следующимнепустой токен, если только этот токен не является ' {', тогда аргументом будет вся {...}следующая группа.

В TeXbook я не нашел точных определений ни для термина «одиночный пробел», ни для термина «непустой токен».

Перечислите все токены, которые TeX не использует в качестве неразделенных аргументов (если только они не вложены между явным символьным токеном с кодом категории 1 и явным символьным токеном с кодом категории 2).

К настоящему моменту я обнаружил, что TeX не использует явные токены символов с кодом категории 10 и кодом символа 32 в качестве неразделенных аргументов — вам нужно сосредоточиться на том, что TeX принимает в качестве \macroвторого аргумента:

\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\macro A B 
\show\macrob
\bye

Неявные токены символов с кодом категории 10 и кодом символа 32 используются в качестве неразделенных аргументов макроса:

\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\catcode`\X=13
\uppercase{\let\space= } %
\uppercase{\letX= } %
\macro A\space B 
\show\macrob
\macro AXB
\show\macrob
\bye

Явные забавные пробелы используются в качестве неразделенных аргументов макроса:

\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\uccode`\ =`\a
\uppercase{\macro A B}%
\show\macrob
\bye

Неявные забавные пробелы используются как неразделенные аргументы макроса:

\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\def\letcs#1#2{\let#1= #2}%
\catcode`\X=13
\uccode`\ =`\a
\uppercase{\letcs\space{ }}%
\uppercase{\letcsX{ }}%
\macro A\space B 
\show\macrob
\macro AXB
\show\macrob
\bye

Неявные/явные токены символов с кодом категории 12 и кодом символа 32 используются в качестве неразделенных аргументов макроса:

\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\catcode`\ =12\relax%
\let\space= %
\macro{A} {B}%
\show\macrob
\macro{A}\space{B}%
\show\macrob
\bye

Control-space используется как неразделенный аргумент макроса:

\def\macro#1#2{\def\macrob{Arg 1:(#1) Arg 2:(#2)}}
\macro A\ B
\show\macrob
\bye

Итак, я протестировал несколько случаев, но тестирование пограничных случаев не приводит ни к точному определению термина «одиночный пробел», ни к точному определению термина «непустой токен». ;-)

Другими словами: я не знаю точно, какие токены TeX не использует в качестве неразделенных аргументов (если только они не вложены между токеном символа с кодом категории 1 и токеном символа с кодом категории 2).

Кажется, количество⟨пробел⟩не равно "одиночный пробел"/"непустой токен":

В главе 24 TeXbook: Краткое изложение вертикального режима:

Количество⟨пробел⟩, который использовался в синтаксисе⟨необязательные пробелы⟩выше, обозначает явный или неявный пробел. Другими словами, он обозначает либо токен символа категории 10, либо управляющую последовательность или активный символ, текущее значение которого было сделано равным такому токену с помощью \letили \futurelet.

Упомянутая «управляющая последовательность или активный символ», подпадающая под⟨пробел⟩, будет использоваться как неразделенный аргумент макроса — примеры выше показывают это — в то время как «одиночный пробел»/«непустой токен» не используется как неразделенный аргумент макроса.

Вероятно, «одиночный пробел»/«непустой токен» является строгим подмножеством⟨пробел⟩?

Если да, то какое именно подмножество?

решение1

Стиль TeXbook часто заключается в том, чтобы сказать что-то правильное, но не полную правду.

Формального определения «единого пространства» не существует, поскольку оно не нужно.

Действительно, если вы попробуете

\begingroup\def\\{\global\let\spacetoken= }\\ \endgroup

\def\foo#1#2{(First is #1)(Second is #2)}

\foo AB

\foo A B

\edef\two{\space\space}
\expandafter\foo\expandafter A\two B

\foo A\spacetoken B

\bye

вы получите три экземпляра

(Первый — А)(Второй — Б)

и последняя строка вместо этого выдаст

(Первый — А)(Второй — )Б

Этот \expandafterтрюк используется для вставки нескольких пробелов между Aи B. Итак, вы видите, что следующее упражнение «более правильное»: TeX пропускает любыеявныйпробел при поиске неразделенного аргумента.

Последний пример показывает, чтоскрытыйПробелы не пропускаются. Первая строка в коде заимствована из упражнения 24.6, чтобы сделать \spacetokenнеявный пробел, потому что нельзя просто сделать как в \let\bgroup={. Если вы добавите, \show\spacetokenто получите

> \spacetoken=blank space  .

но этонетигнорируется при поиске неразделенного аргумента.

Явный пробельный токен — это символьный токен категории кода 10 (пробел или табуляция при обычных настройках; но если вас это интересует, см. подробности ниже). При обычных настройках он может быть сгенерирован пробелом или табуляцией во входных данных или любым символом, которому назначен код категории 10 во время токенизации входных данных.


Но есть одна загвоздка. Она всегда есть!

Нужно учитывать, что TeX будет поглощать символы с кодом категории 10, присваивая им код символа 32 независимо от их исходного кода символа. Таким образом, табуляция не отличается от пробелов, потому что ониявляютсято же самое после выполнения токенизации.

Так в чем же проблема?

\uccode` =`x \uppercase{\foo A B}

который не игнорирует смешное пространство? Это на самом деле отличается от

\catcode`*=10 \foo A*B

который игнорирует звездочку, поскольку имеет код категории 10.

Дело в том, что символы с кодом категории 10 являютсянормализованныйиметь код символа 32во время токенизации. Однако при \uppercaseприменении токенизация уже выполнена, и пробел имеет код символа 32. Но после \uppercaseэтого символ становится x10 , что больше не может быть проигнорировано, поскольку у него нет кода символа 32.

Следовательно, ответ о том, что игнорируются только символы с кодом символа 32 и кодом категории 10, является правильным, но вводит в заблуждение, если не учитывать нормализацию.

решение2

tex.web имеет

begin if cur_tok=space_token then

чтобы пропустить игнорируемые токены, где space_tokenнаходится

@d space_token=@'5040 {$2^8\cdot|spacer|+|" "|$}

решение3

Последовательности явных символьных токенов с кодом символа 32 и категорией 10 (пробел) — единственное, что TeX пропускает при «поиске» начала неразделенного аргумента.


Количество⟨пробел⟩действительно не равно «одиночный пробел»/«непустой токен» в смысле цитируемых вами параграфов TeXbook:

Количество⟨один необязательный пробел⟩определяется как:

⟨один необязательный пробел⟩⟨пробел⟩|⟨пустой⟩

Где бы⟨один необязательный пробел⟩разрешено, это может быть также неявным символом пробела.

См., например,

\lowercase{\let\sptoken = } %
\edef\result{\number1234 }
\show\result
\edef\result{\number1234\sptoken}
\show\result
\let\result\sptoken\sptoken=\sptoken\TeX
\bye

(Здесь \lowercase ничего не происходит, кроме удаления скобок. Таким образом, вы получаете два явных пробельных токена с кодом символа 32 после "=". Первый будет отброшен, поскольку при \let-assignments один пробел после "=" необязателен. Второй не будет отброшен, но станет токеном, значение которого присвоено \sptoken.)

\sptokenявляется неявным пробельным токеном.
Он отбрасывается во время -оценки TeX, \numberкак явный пробельный токен.
Он также отбрасывается, как и любой другой⟨необязательное пространство⟩при выполнении второго \let-присваивания.
Но TeX не пропускал бы \sptokenпри «поиске» начала неразделенного аргумента.

Итак, этот пример доказывает, что величина⟨пробел⟩не равнозначно «одинарному пробелу»/«непустому токену» в смысле цитируемых вами параграфов TeXbook.


Кстати:

Ваш вопрос касается того, как TeX обрабатывает токены при поиске начала неразделенного аргумента.

Ваш вопрос относится к этапу обработки, на котором токенизация уже выполнена.

Тем не менее, стоит упомянуть факт, связанный с процессом токенизации .tex-input:

Если в процессе токенизации .tex-input TeX встречает символ, код категории которого равен 10 (пробел), в то время как считывающее устройство находится в состоянии M (середина строки), то TeX добавит к потоку токенов явный токен символа категории 10 (пробел) и код символа 32. То есть, полученный токен будет иметь код символа 32 независимо от номера, который имеет кодовая точка символа рассматриваемого ввода.

Например, горизонтальная табуляция (горизонтальная табуляция имеет кодовую точку 9 в ASCII) обычно также имеет назначенный код категории 10. Поэтому токенизация горизонтальной табуляции обычно дает явный токен символа категории 10 (пробел) и код символа 32. То есть тот самый токен, который TeX пропускает при «поиске» начала неразделенного аргумента.

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