Ниже показан фрагмент кода, взятый из multido.tex
. Я заметил, что назначения не заканчиваются на %
.
Смотреть
\dimen@=#1\advance\dimen@#2
в\def\multido@step@d#1#2{% \dimen@=#1\advance\dimen@#2 \edef#1{\number\dimen@ sp}}%
Увидимся снова
\count@=#1\advance\count@ by #2
в\def\multido@step@i#1#2{% \count@=#1\advance\count@ by #2 \edef#1{\the\count@}}
Смотрите еще раз
\dimen@=#1pt
,\dimen@=#2pt
и\dimen@=#1pt\advance\dimen@#2
в\def\multido@init@r#1#2#3{% \dimen@=#1pt \multido@dimtonum\dimen@#3% \dimen@=#2pt \ifnum\multido@count<\z@\dimen@=-\dimen@\fi \multido@addtostep{\do\multido@step@r{\do#3}{\number\dimen@ sp}}} \def\multido@step@r#1#2{% \dimen@=#1pt\advance\dimen@#2 \multido@dimtonum\dimen@#1}
Возникают ли при присваивании конечные пробелы, которые необходимо заканчивать знаком %
?
решение1
Пример 1
\def\multido@step@d#1#2{%
\dimen@=#1\advance\dimen@#2
\edef#1{\number\dimen@ sp}}%
После #2
должно быть \relax
. Действительно, если #2
это регистр или параметр, такой как \z@
или \lineskip
, то пространство, предоставленное в конце строки, будетнетбыть проигнорировано. В этом случае также %
может быть использовано, поскольку следующий токен нерасширяемый ( \edef
). Список токенов, полученный из, \multido@step@d{\x}{2pt}
будет (я обозначаю пробел токеном с помощью •)
\dimen@=\x\advance\dimen@2pt•\edef\x{\number\dimen@ sp}
и пробел перед ним \edef
будет проигнорирован. Но с `\multido@step@d{\x}{\parindent} можно было бы иметь
\dimen@=\x\advance\dimen@\parindent•\edef\x{\number\dimen@ sp}
и космический жетон будетнетбыть проигнорировано. Тот факт, что он следует за контрольным словом, не имеет значения: фаза токенизации уже прошла. С \relax
after вместо пробела #2
будет токен.\relax
Пример 2
Это то же самое. Должно быть \relax
после#2
Пример 3
Для ясности я пронумерую строки.
1 \def\multido@init@r#1#2#3{%
2 \dimen@=#1pt
3 \multido@dimtonum\dimen@#3%
4 \dimen@=#2pt
5 \ifnum\multido@count<\z@\dimen@=-\dimen@\fi
6 \multido@addtostep{\do\multido@step@r{\do#3}{\number\dimen@ sp}}}
7 \def\multido@step@r#1#2{%
8 \dimen@=#1pt\advance\dimen@#2
9 \multido@dimtonum\dimen@#1}
Нет необходимости завершать строки 2 и 4 символом %
; на самом деле, a %
в конце строки 4 было бы неправильно, поскольку TeX начнет расширяться \ifnum
до того, как выполнит присваивание \dimen@
(вероятно, безвредное в данном конкретном случае).
Та же проблема, что и раньше, в строке 3: %
здесь это хорошо, потому что следующий токен \dimen@
that нерасширяем; \relax
был бы лучше.
Строка 8 должна иметь \relax
в конце по тем же причинам, что и раньше; а не , поскольку такой %
аргумент вызвал бы расширение до того, как будет выполнено присваивание.#2
2pt
\multido@dimtonum
решение2
Когда TeX сканирует измерение, если только хранимое количество не представлено в виде регистра, он продолжит поиск числа и единицы (расширяясь по пути) до тех пор, пока не встретит пробел или неподходящий символ. Пробел удаляется; таким образом, назначения, записанные так, как вы их показываете, функционально ведут себя так же, как управляющие слова, удаляя следующие пробелы. И, конечно, если измерениеявляетсярегистр, то имя регистра будет либо самим управляющим словом (тем самым поглощая пространство), либо числом, которое TeX будет сканировать...
Тем не менее,некоторыйиз показанных вами назначений используют аргумент (например, #2
) для измерения. Кто-то хитрый или слишком умный может использовать для этого регистр, и тогда пространство не будет съедено, потому что оно будет записано в определение макроса до того, как будет прочитано управляющее слово. На практике, когда такие данные не контролируются программистом, лучше просто уничтожить пространство с помощью \relax
.