LaTeX 매크로의 순환 참조

LaTeX 매크로의 순환 참조

LaTeX에서 매크로를 배우려고 하다가 우연히 알게 되었습니다.이 정의:

\x@protect" "로 표시되는 인수가 하나인 매크로입니다 #1. \@typeset@protectalso는 로 정의되므로 아무 작업도 수행하지 않는 \relax첫 번째 분기가 \ifx실행됩니다. ( \ifx두 매크로의 의미를 비교합니다.) 따라서 의 유일한 결과 는 의 정의에 있는 \x@protect첫 번째 " "인 인수가 버려지는 것입니다. 이로 인해 작동하지 않는 \protect 명령과 그 자체가 남습니다. 이것은 순환적인 정의인 것 같습니다. 사실 그렇지 않습니다. LaTeX 작성자가 자신의 흔적을 가리려고 하는 것은 불쾌한 속임수입니다. 의 목록을 매우 의심스러운 두 번째로 살펴보십시오 . 마지막 " "와 마침표 사이에는 두 개의 공백이 있지만 다른 목록의 마지막 제어 시퀀스 뒤에는 하나만 있습니다! 실제로 모든 목록에는 후행 공백이 하나만 있습니다. 목록에서 마지막 하나의 공백은 공백을 포함하여 " "인 마지막 제어 시퀀스 이름의 일부입니다 !`\\\\\\\\\\\\\\

왜 순환 참조인가?

순환 참조를 만나도 문제가 발생하지 않는 이유는 무엇입니까?

답변1

으로 대화형 세션을 시작하겠습니다 pdflatex test. test.tex여기서는

\documentclass{article}

\DeclareRobustCommand{\?}{js bibra}

\makeatletter

\show\?

\show명령은 실행을 중지하므로 더 많은 명령을 실행할 수 있습니다.

This is pdfTeX, Version 3.14159265-2.6-1.40.20 (TeX Live 2019) (preloaded format=pdflatex)
 restricted \write18 enabled.
entering extended mode
(./test.tex
LaTeX2e <2019-10-01> patch level 3
(/usr/local/texlive/2019/texmf-dist/tex/latex/base/article.cls
Document Class: article 2019/10/25 v1.4k Standard LaTeX document class
(/usr/local/texlive/2019/texmf-dist/tex/latex/base/size10.clo))
> \?=macro:
->\x@protect \?\protect \?  .
l.7 \show\?

? i\show\x@protect
> \x@protect=macro:
#1->\ifx \protect \@typeset@protect \else \@x@protect #1\fi .
<insert>   \show\x@protect

l.7 \show\?

? i\show\@x@protect
> \@x@protect=macro:
#1\fi #2#3->\fi \protect #1.
<insert>   \show\@x@protect

l.7 \show\?

\?처리 되면 어떻게 되나요 ? 두 가지 경우가 있습니다. has 가 ( ) \protect와 동일한 의미가 아닌 경우 false 분기를 따릅니다. 따라서 입력 스트림은\@typeset@protect\relax

\@x@protect\?\fi\protect\?

확장하면 \@x@protect마지막 두 개의 토큰이 제거되어 떠납니다 \protect\?\fi( \fi결국 사라집니다).

예를 들어 \protected@edef또는 에서 와 다른 의미가 할당된 \protected@write경우 이런 일이 발생합니다 .\protect\@typeset@protect

그렇다면 조건은 true이므로 입력 스트림은 false 분기를 건너뛴 후 다음을 갖게 됩니다.

\protect\?

이제 \protect사라지고 우리는~인 것 같다예전과 같은 자리에 있기 위해서. 그러나 우리는 그렇지 않습니다. 왜냐하면 다음 토큰은 다음 \protect과 같습니다.다른그로부터 \?테스트 문서에 입력되었습니다.

첫 번째 명령의 출력을 자세히 살펴보십시오 \show. 우리는 얻는다

->\x@protect \?\protect \?  .

TeX 는 ->매크로의 대체 텍스트를 나타냅니다. 이 표현의 규칙은 제어 단어 뒤에 공백이 오는 반면 제어 기호는 그렇지 않다는 것입니다. 이는 뒤에 공백이 있는 \x@protect것과 \protect뒤에 공백이 없는 것을 설명합니다 \?. 그러나 후행 기간 앞에는공백! 그들은 어디에서 왔니?

그렇게 하면 \DeclareRobustCommand{\?}{js bibra}LaTeX는 여러 가지 작업을 수행하는데, 주요 작업은 다음과 같습니다.

\expandafter\def\csname ? \endcsname{js bibra}

그런 다음 의 "사용자 수준 버전"을 정의하기 위해 매우 비표준적인 이름으로 이 매크로를 사용합니다 \?. \endcsname매크로 이름으로 끝나는 앞에 공백이 있습니다 .

몇 가지 더 자세한 내용이 있지만 아이디어는 보조 파일 작성을 쉽게 하는 것입니다. 이전 버전의 LaTeX에서는 다음과 같은 내용을 보았습니다.

\def\LaTeX{\protect\pLaTeX}
\def\pLaTeX{<the real definition>}

LaTeX2e가 출시되었을 때 이전 코드는

\DeclareRobustCommand{\LaTeX}{<the real definition>}

새로운 추상화 수준을 활용합니다. 이전 버전에서는 \LaTeX{}섹션 제목에 다음과 같이 작성했습니다.

\protect\pLaTeX {}

보조 파일에서. 이제 글이 써진다

\LaTeX  {}

이름과 규칙의 뒤에 공백이 있기 때문입니다. 보조 파일을 읽을 때 이중 공백은 무시됩니다.

\\또는 와 같은 제어 기호의 경우 약간 다르지만 \?일반적인 아이디어는 동일합니다.

관련 정보