
다음에서 수정된 이 MWE를 고려하십시오.ifthenelse가 동일한 문자열 비교에 실패하면:
\documentclass{article}
\edef\test{german\relax}
\edef\curentry{\string german\relax}
\typeout{test: \meaning\test, curentry: \meaning\curentry}
\ifx\curentry\test
\typeout{ equal}
\else
\typeout{ unequal}
\fi
\begin{document}
\end{document}
이것을 로 컴파일하면 pdflatex test.tex
터미널에 다음 출력이 표시됩니다.
test: macro:->german\relax , curentry: macro:->german\relax
unequal
이제 링크된 게시물에서 그 이유를 설명합니다.
무슨 일이 일어나는지는 \string이 처음 보는 토큰(이 경우에는 g)에 적용된다는 것입니다. 두 결과를 비교해 보면 결과는 동일하지 않습니다. 하나는 글자가 아닌 글자가 하나 있고, 글자는 다섯 개이고, 두 번째는 글자가 여섯 개입니다.
그러나 매크로가 어떻게 정의되었는지 실제로 알지 못하는 패키지에서 일부 상황을 검사하려고 한다고 가정해 보겠습니다. 그래서 저는 매크로 중 하나를 \typeout
선택 하기 로 결정했습니다 .\meaning
똑같다내용이 인쇄되었지만 조건문은 여전히 실패합니다. 이런 상황을 디버깅하려면 어떻게 해야 합니까?
즉, 제가 사용할 수 있는 일종의 기능이 있습니까?Latex에서 catcode 테이블을 생성합니까(터미널에 \typeout 사용)?)은 위의 매크로에 대해 다음과 같이 출력됩니다.
% \typeoutComponents{\test}
g (catcode 11)
e (catcode 11)
r (catcode 11)
m (catcode 11)
a (catcode 11)
n (catcode 11)
\relax (catcode ?)
% \typeoutComponents{\curentry}
g (catcode 12)
e (catcode 11)
r (catcode 11)
m (catcode 11)
a (catcode 11)
n (catcode 11)
\relax (catcode ?)
... "문자열"(매크로) 동일성이 실패하는 이유를 스스로 추론할 기회를 갖기 위해?
(그런데 하위 질문: 매크로/명령/토큰/제어 시퀀스(예: 로 시작하는 것 \
)에 캣코드가 있을 수 있나요?)
답변1
이 명령은 \tl_analysis_show:N
요청한 작업을 수행합니다.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\checktokenbytoken}{sm}
{
\IfBooleanTF{#1}
{
\tl_show_analysis:n { #2 }
}
{
\tl_show_analysis:N #2
}
}
\ExplSyntaxOff
\edef\xgerman{\string german\relax}
\checktokenbytoken{\xgerman}
\checktokenbytoken*{german\relax}
터미널에서
The token list \xgerman contains the tokens:
> g (the character g)
> e (the letter e)
> r (the letter r)
> m (the letter m)
> a (the letter a)
> n (the letter n)
> \relax (control sequence=\relax).
<recently read> }
l.19 \checktokenbytoken{\xgerman}
?
The token list contains the tokens:
> g (the letter g)
> e (the letter e)
> r (the letter r)
> m (the letter m)
> a (the letter a)
> n (the letter n)
> \relax (control sequence=\relax).
<recently read> }
l.20 \checktokenbytoken*{german\relax}
(TeX Live 2017 이전 릴리스의 경우 이 기능이 작동하려면 \usepackage{l3tl-analysis}
추가가 필요하며 현재는 더 이상 사용되지 않습니다)\usepackage{xparse}
\tl_show_analysis:N
답변2
내 솔루션에는 외부 패키지가 필요하지 않습니다. 이 \showcat\macro
구현됩니다. 후에
\def\test{ger{$##m}a~n \relax \foo}
\edef\curentry{\string german \relax}
\showcat\test
\showcat\curentry
우리는 결과를 얻습니다:
\test ->
the letter g (catcode 11)
the letter e (catcode 11)
the letter r (catcode 11)
begin-group character { (catcode 1)
math shift character $ (catcode 3)
macro parameter character # (catcode 6)
the letter m (catcode 11)
end-group character } (catcode 2)
the letter a (catcode 11)
the token ~ (catcode 13)
the letter n (catcode 11)
blank space (catcode 10)
the token \relax (catcode 16)
the token \foo (catcode 16)
\curentry ->
the character g (catcode 12)
the letter e (catcode 11)
the letter r (catcode 11)
the letter m (catcode 11)
the letter a (catcode 11)
the letter n (catcode 11)
blank space (catcode 10)
the token \relax (catcode 16)
구현은 다음과 같습니다.
\def\showcat#1{\immediate\write16{\string#1 -> }\expandafter\showcatA#1\showcatA}
\def\showcatA{\futurelet\tmp\showcatB}
\def\showcatB{\let\next=\showcatE
\ifx\tmp\bgroup \let\next=\showcatC \fi
\ifx\tmp\egroup \let\next=\showcatC \fi
\expandafter\ifx\space\tmp \let\next=\showcatC \fi
\ifx\tmp\showcatA \let\next=\showcatF \fi
\next
}
\def\showcatC{\afterassignment\showcatD \let\tmp= }
\def\showcatD{\showcatE\tmp}
\def\showcatE#1{\edef\next{\string#1}%
\immediate\write16{\space\space
\ifnum\showcatG<13 \meaningtmp \else the token \next
\fi \space (catcode \showcatG)}%
\showcatA
}
\def\meaningtmp{\meaning\tmp}
\def\showcatF#1{}
\def\showcatG{\showcatH\bgroup1\showcatH\egroup2\showcatH$3\showcatH&4%
\showcatH##6\showcatH^7\showcatH_8\showcatH{ }{10}%
\showcatH A{11}\showcatH/{12}\showcatH~{13}16}
\def\showcatH#1#2{\ifcat\noexpand\tmp\noexpand#1#2\expandafter\showcatI\fi}
\def\showcatI#116{}
물론 카테고리 0, 5, 9, 14, 15의 토큰은 매크로 본문에 절대 나타나지 않습니다. 그리고 제어 시퀀스(카테고리가 없는 토큰)는 테스트 \showcatG
에서 의 간단한 사용을 위해 카테고리 16으로 표현됩니다 \ifnum
.