Нужно ли добавлять к присваиваниям %, чтобы удалить конечные пробелы?

Нужно ли добавлять к присваиваниям %, чтобы удалить конечные пробелы?

Ниже показан фрагмент кода, взятый из 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}

и космический жетон будетнетбыть проигнорировано. Тот факт, что он следует за контрольным словом, не имеет значения: фаза токенизации уже прошла. С \relaxafter вместо пробела #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в конце по тем же причинам, что и раньше; а не , поскольку такой %аргумент вызвал бы расширение до того, как будет выполнено присваивание.#22pt\multido@dimtonum

решение2

Когда TeX сканирует измерение, если только хранимое количество не представлено в виде регистра, он продолжит поиск числа и единицы (расширяясь по пути) до тех пор, пока не встретит пробел или неподходящий символ. Пробел удаляется; таким образом, назначения, записанные так, как вы их показываете, функционально ведут себя так же, как управляющие слова, удаляя следующие пробелы. И, конечно, если измерениеявляетсярегистр, то имя регистра будет либо самим управляющим словом (тем самым поглощая пространство), либо числом, которое TeX будет сканировать...

Тем не менее,некоторыйиз показанных вами назначений используют аргумент (например, #2) для измерения. Кто-то хитрый или слишком умный может использовать для этого регистр, и тогда пространство не будет съедено, потому что оно будет записано в определение макроса до того, как будет прочитано управляющее слово. На практике, когда такие данные не контролируются программистом, лучше просто уничтожить пространство с помощью \relax.

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