Вопрос по упражнению 21.10 в The TeXbook

Вопрос по упражнению 21.10 в The TeXbook

В этом упражнении спрашивается, как сохранить расширение \chapnoв момент, когда \writeобрабатывается, но \the\count0должно быть развернуто в момент \shipout. Вот полный пример:

\def\chapno{5}
\newwrite\cont \openout\cont=out.txt
\edef\next{\write\cont{\chapno,\noexpand\the\count0}}\next
\def\chapno{6}
\count0=100
\bye

В ответе использован любопытный прием:

{\let\the=0\edef\next{\write\cont{<token list>}}\next}

\noexpandЭквивалентно ли использование \let-трюку? И почему \noexpandне используется в ответе - просто чтобы показать возможности?

решение1

По сути, латекс \protected@writeдействует следующим образом:

\long\def \protected@write#1#2#3{%
      \begingroup
       \let\thepage\relax
       #2%
       \let\protect\@unexpandable@protect
       \edef\reserved@a{\write#1{#3}}%
       \reserved@a
      \endgroup
      \if@nobreak\ifvmode\nobreak\fi\fi
}

Обычно в такой конструкции вы можете использовать \noexpandперед токенами, которыми вы управляете при написании макроса, но <token list>в вашем примере обычно будет поступать как #1из некоторого аргумента заголовка раздела в документе, но вы хотите подавить расширения всех регистров до тех пор, пока \shipoutтекст не может ссылаться на любой из них. поэтому делая \theнерасширяемым (не имеет значения, к чему вы \let его относите, 0или \relaxили любой другой нерасширяемый токен, то он останется самим собой в , \edefно будет иметь свое обычное расширяемое определение в \write.

Обратите внимание, что упражнение имеет простой случай, когда номер главы является расширяемым макросом. В большинстве форматов главы будут автоматически пронумерованы, поэтому использование регистра счетчика, а также, возможно, в конечном итоге доступ к нему, \theв этом случае подавление всех \theрасширений может оказаться слишком большим. (Примечание: LaTeX просто подавляет \thepageвозможность расширения других счетчиков в точке использования, а не при окончательной отправке).

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