
저는 이 답변을 살펴보고 코드를 이해하려고 노력했습니다. 저는 LaTeX의 슈퍼 초보자(두 번째 날)이고 테이블이 아닌 환경에서 작동하도록 할 수 없는 코드의 다음 부분에 갇혔습니다. 내가 이해하지 못하는 가장 간단한 형태는 다음과 같습니다.
\documentclass{article}
\begin{document}
\newcommand*\f[3]{#1-#2-#3}
\newcommand*\ex[1]{\f#1 - \expandafter\f\@firstofone}
Try \ex{111}{221}
\end{document}
나에게 명확하지 않은 어떤 이유로 연결된 코드에서 마지막 인수는 소비되지 않지만 구문에 의해 소비되도록 남아 있습니다 expandafter\f\...
. 내가 이해하는 바에 따르면 \expandafter
먼저 "실행" 하여 인수를 \@firstofone
얻고 {221}
대괄호를 제거하고 에 공급 해야 합니다 \f
. 이런 일이 발생하지 않으며 이유를 알 수 없습니다.
답변1
이것이 작동하려면 사용해야 \makeatletter
하지만 최소한입니다.
호출이 \ex{111}{221}
먼저 다음으로 확장됩니다.
\f 111 - \expandafter\f\@firstofone{221}
Now 는 확장되어 3개의 인수인 find , and 를 \f
찾습니다. 왜냐하면 TeX는 중괄호가 누락된 경우 단일 토큰을 사용하기 때문입니다.1
1
1
정의에 따라 \f
확장되고 대체 텍스트가 입력 스트림에 다시 삽입됩니다.
1-1-1 - \expandafter\f\@firstofone{221}
토큰은 1-1-1 -
확장이 불가능하므로 다음 단계로 전송됩니다. 이제 남아있어요
\expandafter\f\@firstofone{221}
이것은 (중괄호가 없는 인수)를 반환하는 \f
따로 설정되고 확장 되므로 우리는 다음을 얻습니다.\@firstofone
\f221
그것은 가 됩니다 2-2-1
. 따라서 코드의 최종 효과는 인쇄하는 것입니다.
1-1-1 - 2-2-1
정말 유용하지 않은 것 같습니다. 어디서 찾았든 믿지 마세요.
답변2
egreg가 그의 답변에서 지적했듯이 사용은 \@firstofone
그다지 유용하지 않으며 이 특별한 경우에는 차이를 만들지 않습니다. 그러나 다음과 같은 경우가 있습니다.~이다유용한. 완전성을 위해 두 가지 예를 들어보고 싶습니다.
확장 가능한 매크로
~ 안에왜 \expandafter\@firstoftwo
관용구입니까?완전히 확장 가능한 매크로에 대한 일반적인 사용 사례가 제공 \@firstoftwo
됩니다 . LaTeX의 "identity function"의 일종인 는 단일 매개변수만 처리해야 하는 유사한 상황에서 유용합니다.\@secondoftwo
\@firstofone
\def\gobbleIfZero#1{%
\ifnum#1=0
\expandafter\@gobble
\else
\expandafter\@firstofone
\fi
}
foo\gobbleIfZero{0}{bar}
foo\gobbleIfZero{123}{bar}
줄게
푸
푸바
\@gobble
(예: \@firstofone
)은 단일 매개변수를 취하지만 이를 버리고 "없음"으로 확장합니다.
Catcode 수정
좀 더 까다롭지만 더 흥미로운 것은 catcode 변경이 관련된 경우입니다. TeX가 매크로에 대한 인수를 구문 분석할 때 인수 텍스트를 읽을 때마다 catcode를 수정합니다. 여기에는 catcode 변경 사항이 없으므로 귀하의 경우에는 중요하지 않습니다. 그러나 다음과 같이 다소 인위적인 예가 제공된다고 가정해 보겠습니다.
\begingroup
\catcode`4=\active
\gdef 4{four}
\endgroup
\newcommand*\f{\catcode`4=\active}
\newcommand*\exA{\f}
\newcommand*\exB{\expandafter\f\@firstofone}
{\exA{345}--{345}}
{\exB{345}--{345}}
이로 인해
345-345
345-3포5
처음 네 줄은 4
로 확장되는 전역 매크로를 정의합니다 four
. 일반적으로 4
catcode는 12(기타)이므로 매크로를 만들 수 있도록 13(활성)으로 변경합니다. \f
여기서는 실행될 때 이 매크로를 다시 범위로 가져옵니다.
실행 되면 \exA
의 catcode가 4
13으로 변경되고 이후에는 다음 두 그룹 모두 4
로 확장 됩니다. four
여기에는 매개변수가 전혀 없으므로 간단합니다.
반면에 매크로에서는 동일한 텍스트를 반환하는 \exB
첫 번째 {345}
부분이 처리됩니다 .\@firstofone
하지만 캣코드는 고쳐졌어~ 4
12. 일단 수정되면 더 이상 변경할 수 없습니다! catcode 변경이 \f
처리되었음에도 불구하고~ 전에첫 번째는 345
아무런 영향을 미치지 않습니다. 두 번째의 catcode는 {345}
아직 수정되지 않았으므로 변경 사항은 이 그룹에 계속 적용됩니다.
이 동작은 catcode 변경을 처리하는 기존 매크로에 추가 코드를 삽입하려는 경우 매우 유용합니다. 예를 들어 \verb
(에서 영감을 얻었습니다.이 TeX 진주):
\begingroup
\catcode`\/\active
\catcode`\_\active
\@firstofone{%
\verb|%
\catcode`\/\active \def/{\par}%
\catcode`\_\active \def_#1_{\textcolor{blue}{#1}}%
}_\documentclass_{article}/_\begin_{document}/ We all love _\LaTeX_!/_\end_{document}|
\endgroup
출력
\@firstofone
처음에 어디서 읽으셨는지 모르겠지만 , 아마도 이러한 맥락 중 하나였을 것입니다.