> For the complete documentation index, see [llms.txt](https://overleaf-pro.ayaka.space/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://overleaf-pro.ayaka.space/latex/ko/in-depth-articles/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md).

# \expandafter는 어떻게 작동하나요: 기본 원리부터 TeX 소스 코드 탐색까지

[1부](/latex/ko/in-depth-articles/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md) [2부](/latex/ko/in-depth-articles/22-how-does-expandafter-work-the-meaning-of-expansion.md) [3부](/latex/ko/in-depth-articles/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md) [4부](/latex/ko/in-depth-articles/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md) [5부](/latex/ko/in-depth-articles/17-how-does-expandafter-work-a-detailed-macro-case-study.md) [6부](/latex/ko/in-depth-articles/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.md)

## 소개

이제 우리는 다음의 완전한 탐구에 필요한 배경 주제들을 다루었다: `\expandafter`:

* TeX 토큰의 기본과 그것이 어떻게 계산되는지;
* TeX의 확장 과정 뒤에 있는 원리;
* 문서 처리 중 TeX이 임시 토큰 목록을 사용/생성하는 방식;
* TeX이 여러 입력 स्रोत(임시 토큰 목록 포함)을 어떻게 사용하고 “다루는지.”

이 글에서는 이러한 주제/개념을 함께 모아 TeX의 `\expandafter` 명령어가 어떻게 작동하는지, 즉 그 메커니즘을 설명할 것이다.

## 그래서, \expandafter에 대해

뒤에 있는 아이디어는 `\expandafter` TeX이 일반적으로 그렇게 하기 전에 명령어(토큰)의 확장을 강제로 일으키는 것이다. 두 토큰이 주어지면, $$\mathrm{T\_1}$$ 및 $$\mathrm{T\_2}$$ 의 동작은 `\expandafter` $$\mathrm{T\_1T\_2}$$ TeX이 처리하게 $$\mathrm{T\_1}\text{<}$$의 확장을 $$\mathrm{T\_2}\text{>}$$, 여기서 $$\text{<}\dots\text{>}$$ 는 토큰 목록을 나타낸다. TeX은 $$\mathrm{T\_2}$$ 미리 확장하여 토큰 $$\mathrm{T\_1}$$ (예: 프리미티브 또는 매크로)가 확장으로부터 나온 토큰들을 보거나 그에 대해 작동할 수 있게 한다. $$\mathrm{T\_2}$$. 만약 토큰 $$\mathrm{T\_2}$$ 이 비활성 문자나(대부분의) 프리미티브 같은 확장 불가능한 항목을 나타낸다면, `\expandafter` 의 동작은 아무것도 바꾸지 않는다: TeX은 토큰들을 $$\mathrm{T\_1T\_2}$$ 일반적인 방식으로 계속 처리할 것이다.

### \expandafter 사용하기 소개

만약 아직 `\expandafter`를 사용해 본 적이 없다면, 여기 그 사용 예가 있다. 프리미티브 `\uppercase{...}`와 함께 사용하는 예이다. `.tex` 주 입력 파일의 이름을 대문자로 조판하고 싶다고 가정해 보자. 우리는 다음 TeX 프리미티브 명령들을 알고 있을 수 있다:

* `\uppercase`: 이름이 말해 주듯이 문자 토큰을 그에 대응하는 대문자 형태로 변환한다(그런 대응이 존재하는 경우);
* `\jobname`: 앞서 보았듯이, 주 입력 파일의 이름을 주도록 확장된다. `.tex` 파일.

우리의 TeX 파일 이름이 `mycode.tex` 라고 가정하면, 우리는 `\uppercase{\jobname}` 가 `MYCODE`로 조판될 것으로 합리적으로 예상할 수 있다. 하지만 아니다, 실제로는 `mycode` 를 소문자로 조판한다. 무엇이 “잘못”된 걸까?

일반적인 `\uppercase` 의 사용을

```
\uppercase{<token list>}
```

로 쓰면 우리는 `\uppercase` 가 `<token list>` 을 훑어보며, 그 안에서 발견한 *문자 토큰* 에 대해서만 작동(대소문자 변경)한다고 말할 수 있다. `<token list>`에서 감지한 것들에 대해서만 작동한다: 모든 비문자 토큰은 *무시된다* 왜냐하면 `\uppercase` 비문자 토큰이 무엇을 담고 있거나 무엇을 나타내는지 보기 위해 그것들을 “들여다보거나”(확장하거나) 하지 않기 때문이다. 토큰은 단순히 정수값이므로, `\uppercase` 가 해야 할 일은 `<token list>` 각 토큰의 숫자값이 문자 토큰을 나타내는 값의 범위 안에 있는지 확인하기 위해 토큰 목록을 훑어보는 것뿐이다. 덧붙여, `\uppercase` 또한 *활성 문자의 대소문자도 변경할 수 있다* 대문자 활성 문자를 만들게 되며, 그것이 여전히 활성 상태이므로 역시 정의되어 있어야 하고, 그렇지 않으면 TeX은 오류를 발생시킨다: `정의되지 않은 제어 시퀀스`, 하지만 이야기가 옆으로 샜다...

예를 들어, 텍스트만 있는 매크로를 정의하더라도

```
\def\foo{some lower-case text}
```

그렇다면 `\uppercase{\foo}` 는 여전히 `some lower-case text` 를 조판할 뿐이며 `SOME LOWER-CASE TEXT` 가 되지 않는다. 우리가 기대한 것처럼 되지 않는 이유는 단지 `\uppercase` 의 동작이 `\foo` 가 무엇을 나타내는지 알아내려 하지 않기 때문이다: 그것을 명령 토큰으로 보고 `\foo` \jobname `\jobname`.

### 이 문제를 어떻게 고칠 수 있을까? \expandafter가 구세주다

파일 이름의 대문자 버전을 조판하려면, 우리는 `\uppercase{\jobname}` 을 수정해야 한다 `\jobname` TeX이 그것을 확장 결과(문자 토큰들의 연속)로 바꾸도록 강제함으로써 *이전에* `\uppercase` 가 작동하게 된다. 다시 말해, 확장은 `\jobname` 토큰(명령어)을 제거하고 그것의 확장 결과(문자 토큰을 포함한 토큰 목록)로 대체하는 데 사용되고 있다. 따라서 우리가

```
\uppercase\expandafter{\jobname}
```

라고 쓰면 그것은 작동한다: `MYCODE` 가 조판될 것이다. 실제로 일어나는 일은 TeX이 `\uppercase` 의 처리를 시작하자마자 필수적인 여는 중괄호 문자(`{`를 확인하는데; 그러나 TeX은 `\expandafter` 명령어를 감지하고, 그 때문에 일시적으로 주의를 `\expandafter{\jobname}`.

의 처리로 돌린다.

`\expandafter` $$\mathrm{T\_1T\_2}$$

를 우리의 예와 비교해 보면

`\expandafter{\jobname}`

우리는 알 수 있다

* $$\mathrm{T\_1} =\space$$`{`<sub>토큰</sub>
* $$\mathrm{T\_2} =\space$$`\jobname`<sub>토큰</sub>

여기서 `{`<sub>토큰</sub> 및 `\jobname`<sub>토큰</sub> 는 TeX이 계산한 토큰 값을 가리킨다—아래첨자 표기법 <sub>토큰</sub> 는 TeX이 정수 토큰의 세계에서 작동한다는 점을 상기시키기 위해 사용된다.

작성하는 것은 `\uppercase\expandafter{\jobname}` 가 개략적으로 보면(세부 사항은 뒤에서 설명) 작동하기 때문에 가능하다. `\expandafter` 는 TeX이 다음 작업들을 수행하게 한다:

1. 여는 `{`<sub>토큰</sub>;
2. 다음 토큰을 읽는다: `\jobname`<sub>토큰</sub>. TeX은 `\jobname`<sub>토큰</sub> 가 확장 가능한 명령어임을 인식하고 이를 확장한다. `\jobname`<sub>토큰</sub> 는 그것의 확장 결과—일련의 문자 토큰—로 대체된다;
3. 을 확장한 뒤 `\jobname` 명령어를, TeX은 `{`$$\_\mathrm{token}$$ 를 “입력으로 되돌려 넣고” `\jobname` 의 확장에서 나온 토큰 목록을 사용한다 `\uppercase{`<sub>토큰</sub>`<\jobname의 확장 결과>`<sub>토큰 목록(문자들)</sub>`}`, 그렇게 해서 우리가 원하는 결과가 만들어진다.

다음 도표는 TeX이 `\uppercase\expandafter{\jobname}`을 어떻게 처리하는지 보여 준다—과정 흐름을 따라가려면 그래픽을 아래에서 위로 읽어라.

![\expandafter의 작동 방식](/files/83b14030b546f5881caf3331796b7461492ab7e3)

다음 메모들은 처리의 여러 단계를 설명한다.

1. TeX이 `\uppercase` 의 처리를 시작하고 필수적인 여는 중괄호 문자(`{`)를 확인하지만 `\expandafter` 명령을 어떻게 해석해야 하는지 알게 되므로 오류 메시지가 사라집니다.
2. 의 처리로 돌린다. `\expandafter` $$\mathrm{T\_1T\_2}$$ 우리의 입력인 `\expandafter{\jobname}` 우리는 알 수 있다 $$\mathrm{T\_1} =$$`{`<sub>토큰</sub> 및 $$\mathrm{T\_2} =$$`\jobname`<sub>토큰</sub>. 여기서는 아래첨자 <sub>토큰</sub> 를 사용해 TeX이 정수 토큰 값을 처리하고 있음을 나타낸다.
3. `\expandafter` 를 읽고, 잠시 저장한 뒤, `{`<sub>토큰</sub> 그 정수 토큰 값을 내부 변수에 저장함으로써 `\jobname` 명령을 어떻게 해석해야 하는지 알게 되므로 오류 메시지가 사라집니다.
4. `\expandafter` 은 다음 토큰 `\jobname`<sub>토큰</sub>을 읽고 `\jobname` 명령을 어떻게 해석해야 하는지 알게 되므로 오류 메시지가 사라집니다.
5. 의 확장 결과 `\jobname` 은 `.tex` 파일 이름을 나타내는 문자 토큰들의 연속을 포함하는 임시 토큰 목록을 생성한다. 다음 점에 유의하라. `\jobname` 가 생성하는 모든 문자 토큰은 카테고리 코드 12를 사용해 계산된다.
6. 일단 `\jobname` 이 확장되면, TeX은 3단계에서 저장한 토큰(`{`<sub>토큰</sub>)을 다시 삽입하고 그것을 입력으로 되돌린다. TeX은 또 다른 토큰 목록을 만들어 그 안에 *하나의* `{`<sub>토큰</sub>
7. TeX은 이제 `\expandafter`의 처리를 끝냈고, 결과적으로 TeX 입력의 원천으로 사용할 준비가 된 두 개의 토큰 목록을 얻게 된다. 이제 TeX은 다시 `\uppercase` 의 처리로 돌아가지만, 두 토큰 목록이 `\expandafter` 에 대한 토큰의 원천이 되도록 입력을 구성해 두었다 `\uppercase`—이제 `\uppercase{`<sub>토큰</sub>`<\jobname의 확장 결과>`<sub>토큰 목록(문자들)</sub>`}`. `\uppercase` 는 문자 토큰들의 연속을 보고 우리가 원하는 결과를 만들어 낼 수 있다.
8. 가 생성한 모든 문자 토큰을 읽은 뒤 `\jobname`, TeX은 이전 입력 원천(우리의 `.tex` 파일)에서 토큰을 얻는 것으로 되돌아가며, 거기서 다음 토큰인 닫는 `}` 을 읽게 된다. 이 토큰은 `\uppercase`.

### \expandafter와 내부 토큰 목록

임시 토큰 목록은 *매우 중요한* 요소이다 `\expandafter`의 처리 동작에 대한: 그러한 토큰 목록의 사용과 존재를 이해하면 `\expandafter` 의 결과를 더 분명하게 이해하는 데 도움이 될 수 있다. 특히 여러 개의 연속된 `\expandafter` 명령어를 사용해 더 복잡한 형태의 토큰 처리를 달성하는 매크로를 작성하거나 이해하려 할 때 그렇다: `\expandafter\expandafter\expandafter...`

의 또 다른 핵심 요소는 `\expandafter`의 동작, 특히 여러 개의 연속된 `\expandafter` 명령어와 관련해서는 *재귀* 의 사용이다—이 주제는 이 글의 뒤에서 살펴볼 것이다.

임시 토큰 목록에 대한 이해를 더 돕기 위해 `\expandafter`의 예를 하나 더 살펴보자. 이번에는 `\the` 명령을 어떻게 해석해야 하는지 알게 되므로 오류 메시지가 사라집니다.

#### \expandafter와 내부 토큰 목록: 예제 2

이 예제에서는 `\expandafter` 이 토큰 레지스터에 저장된 토큰에 영향을 주는 데 어떻게 사용될 수 있는지 볼 것이다 `\toks` 명령어를 통해서. 우리가 사용할 TeX 프리미티브는 다음과 같다:

* `**\count** *register*=*number*`: TeX의 위치 `*number*` 에 값 `*register*`;
* `**\toks** *register*={*token list*}`: 토큰 레지스터 위치에 `*token list*` 를 저장하는 데 사용되는 TeX 프리미티브 `*register*`—토큰의 연속을 나중에 사용하기 위해 저장한다;
* `**\the** *token*`: `*token*`을 처리하는 확장 가능한 TeX 프리미티브 명령어로, 정확한 결과는 처리되는 `*token*` 의 성격에 따라 달라진다. `\the` 는 여러 용도가 있다: 그중 하나는 TeX 매개변수나 변수(예: 레지스터)에 저장된 값을 조판하는 것이다. `\the` \the의 다른 용도에는 토큰 레지스터에 저장된 토큰의 복사본을 삽입하는 것도 포함된다. 여기서는 `\the` 를 사용하여 `\count` 레지스터에 저장된 값을 조판할 것이다.

먼저 다음 TeX 코드를 사용해 값 `12345` 을 TeX의 `\count` 레지스터에 저장해 보자 `99`:

```
\count99=12345
```

만약 `\count99` 에 저장된 값을 조판하고 싶다면 `\the\count99` (또는 `\number\count99`).

를 사용할 수 있다. `\toks` 다음으로 우리는 `99`:

```
명령어를 사용해 토큰 레지스터
```

에 몇몇 토큰을 저장할 것이다. `99` 토큰 레지스터

|                               |                                                                               |
| ----------------------------- | ----------------------------------------------------------------------------- |
| **에 저장된 토큰 목록은 다음을 포함할 것이다:** | **표현되는 항목**                                                                   |
| 5382                          | `\the`                                                                        |
| 7885                          | `\count`                                                                      |
| 3129                          | `9` (카테고리 코드 12를 가진 문자 코드 57), 그 결과 토큰 값은 $$256 \times 12 + 57 = 3129$$       |
| 3129                          | `9` (카테고리 코드 12를 가진 문자 코드 57), 그 결과 토큰 값은 $$256 \times 12 + 57 = 3129$$       |
| 2592                          | `<space>` (카테고리 코드 10을 가진 문자 코드 32), 그 결과 토큰 값은 $$256 \times 10 + 32 = 2592$$ |

가 생성한 토큰 목록에 주목하라. `\toks99` 는 *실제 데이터 값을 포함하지* 않는다 `\count99` 왜냐하면 `\toks` 명령어는 확장을 수행하지 않기 때문이다: 그것은 단지 토큰을 만들고 저장할 뿐이다. 우리의 예에서 `\the` 는 확장되지 않으므로 `\count99`를 처리하지 않는다; `\the` 여기서

만 단지 토큰(값 5382)으로 바뀌어 토큰 목록에 저장될 뿐이다. `\toks99` 토큰 목록이 토큰을 포함해 `\count99` 에 저장된 데이터를 나타내게 하려면 `\toks` 명령어가 그것들에 접근할 수 있도록 그 토큰들을 만들어(이용 가능하게 해) 줄 어떤 방법이 필요하다. 물론 `\expandafter` 가 우리를 위해 이것을 할 수 있다. 만약 우리가 다음과 같이 쓴다면:

```
        \toks99=\expandafter{\the\count99 }
```

의 동작/처리는 `\toks` 명령어가 처리되는 동안 “보류”되고 `\expandafter` 가 `\the` 의 확장을 일으켜 `\count` 에 저장된 데이터를 나타내는 문자 토큰을 포함하는 임시 토큰 목록을 생성하도록 한다. `\count99`. 작지만 중요한 점은 `<space>` 숫자 뒤의 `99`문자이다: 그 `<space>` 문자는 TeX이 숫자량을 찾고 있을 때의 스캔 과정을 종료시키는 역할을 한다.

여기서 `\expandafter` 의 동작은 `\jobname` 예제와 매우 비슷하다.

1. 여는 `{`<sub>토큰</sub>.
2. 다음 토큰을 읽는다, `\the`<sub>토큰</sub>는 확장 가능한 명령어를 나타내므로 TeX은 그것을 확장한다. `\expandafter` 는 `\the` 의 확장을 강제하고 `\count99` 그 뒤 `\count` 레지스터에 저장해 보자 `99` 에 저장된 데이터(숫자 12345)를 임시 토큰 목록으로 변환한다. 그 목록에는 숫자 `1`, `2`, `3`, `4` 및 `5`을 나타내는 문자 토큰들—카테고리 코드 12를 가진 문자 토큰들—이 포함될 것이다.
3. 를 확장하고 처리한 뒤 `\the`, TeX은 `{`<sub>토큰</sub> 를 “입력으로 되돌려 넣고” `\the\count99` 의 확장에서 나온 토큰 목록을 사용한다 `\toks99={`<sub>토큰</sub>`<\the\count99의 확장 결과>`<sub>토큰 목록(문자들)</sub>`}` 를 통해 나온 토큰 목록을 사용하며, 이것이 우리가 원하는 결과를 만든다.

이 일련의 사건은 다음 도표에 요약되어 있다—과정 흐름을 따라가려면 그래픽을 아래에서 위로 읽어라.

![\expandafter의 작동 방식](/files/02904d643e238241631a3f2d1f9b9aaa4a39d5fb)

1. TeX이 `\toks`; 그러면 선택적인 `=` 기호를 보고, 그다음 필수적인 여는 중괄호 문자(`{`, 또는 카테고리 코드 1의 모든 문자)를 확인한다. 이는 토큰 목록의 시작을 나타내는 데 사용된다. 그러나 TeX은 `\expandafter` 명령어를 감지하고 대신 그것을 실행한다.
2. 의 처리로 돌린다. `\expandafter` $$\mathrm{T\_1T\_2}$$ 우리의 입력인 `\expandafter{\the\count99 }` 우리는 알 수 있다 $$\mathrm{T\_1} =$$ `{`<sub>토큰</sub> 및 $$\mathrm{T\_2} =$$ `\the<sub>token</sub>`.
3. `\expandafter` 를 읽고, 잠시 저장한 뒤, `{`<sub>토큰</sub> (TeX은 그 정수 토큰 값을 일시적으로 내부 변수에 저장한다). 나중에 TeX은 그것을 처리한 뒤 그 토큰을 다시 입력에 삽입할 것이다 `\the`
4. `\expandafter` 은 다음 토큰 `\the`<sub>토큰</sub> 를 처리하고 확장한다.
5. 의 확장 결과 `\the` 는 처리로부터 임시 토큰 목록을 생성한다 `\count99`—그 토큰 목록에는 `\count` 레지스터에 저장해 보자 `99`.
6. 일단 `\the` 이 확장되면, TeX은 3단계에서 저장한 토큰(`{`<sub>토큰</sub>에 저장된 데이터 값을 나타내는 문자 토큰들의 연속이 포함된다. *하나의* 토큰 `{`<sub>토큰</sub>.
7. TeX은 이제 `\expandafter` )을 넣어 그 토큰을 입력으로 되돌린다. TeX은 또 다른 토큰 목록을 만들어 그 안에 `\toks99=` 를 포함시켰고, 이제 TeX은 입력을 다음 원천으로 사용하도록 두 개의 토큰 목록이 생기게 구성해 두었다 `\expandafter` 에 대한 토큰의 원천이 되도록 입력을 구성해 두었다 `\toks`—이제 `{`<sub>토큰</sub>`<\the\count99의 확장 결과>`<sub>토큰 목록(문자들)</sub>`}`. `\toks` 는 이제 접근할 수 있고, 또 저장할 수 있다. 그리고 5개의 문자 토큰들의 연속을, 즉 데이터 값(`12345`)을 나타내는 토큰들을 `\count99`에 저장할 수 있다: 우리가 원하는 결과.
8. 가 생성한 모든 문자 토큰을 읽은 뒤 `\the\count99`, TeX은 이전 입력 원천(우리의 `.tex` 파일)에서 토큰을 얻는 것으로 되돌아가며, 거기서 다음 토큰인 닫는 `}` 가 저장할 토큰 목록을 종료하는 데 필요한 `\toks99={...}`.

## \expandafter가 실제로 작동하는 방식

이 섹션에서는 TeX 자체 내부를 “저수준”에서 살펴볼 것이다: 그 동작을 구현하는 TeX 내부의 소스 코드/함수들을 탐구한다 `\expandafter`. 세부 사항은 의사 C 코드로 표현되어 있지만 다른 프로그래밍 언어에 익숙한 사람이라면 이해할 수 있을 것이다.

다음의 주석이 달린 도표는 TeX이 `\expandafter` 를 더 큰 함수인 `expand()`의 일부로 어떻게 구현하는지 설명한다—TeX의 확장 처리를 주도하는 핵심 함수이다. 구현을 담당하는 부분 안에서 `\expandafter` 우리는 알 수 있다 [*재귀적* 동작을](https://en.wikipedia.org/wiki/Recursion) 의 또 다른 호출이 `expand()` 함수를 사용해 두 번째로 읽어 들인 토큰을 처리하는데 사용되며, $$\mathrm{T\_2}$$가 확장 가능할 때의 경우이다. $$\mathrm{T\_2}$$ 가 확장 가능하다.

이 코드는 Knuth의 TeX 엔진에 나타나지만, 이 도표가 개괄하는 기본 원리는 모든 TeX 엔진에 적용된다.

![TeX 내부에서 \expandafter가 작동하는 방식](/files/2ae730d894a9d07e870890a18b29f44da0cb2986)

의 첫 번째 작업은 `expand()` 확장될 명령어가 매크로인지 프리미티브인지 판별하는 것이다. 매크로는 `macrocall()`.

만약 확장될 명령어가 프리미티브라면, `expand()` 함수는 현재 명령 코드 값(전역 변수 `에 저장된)`을 사용해 어떤 특정 프리미티브를 처리해야 하는지 식별한다. 우리는 더 완전한 목록에서 이 세부 사항을 볼 수 있다 `expand()`:

```
    void expand(void)
    {
    //curcmd는 전역 변수이다
    if(curcmd != macro) // curcmd < 111
    {
      switch(curcmd)
      {
        case \expandafter: // \expandafter T1T2 명령을 처리
        {
            gettoken(); // 토큰 T1을 읽기
            t = curtok; // 토큰 T1을 지역 변수 t에 저장
            gettoken(); // 토큰 T2를 읽기
            if(curcmd > 100) // 토큰 T2가 확장 가능한가?
                expand();    // 네! T2는 확장 가능합니다:
                             // T2의 확장을 수행하기 위해
                             // expand()를 재귀적으로 호출하여
            else
                backinput(); // T2는 확장 불가: 해당 토큰을
                             // 입력으로 되돌려 나중에 다시 읽히게 함

            curtok = t ;  // 전역 변수 curtok를 저장해 둔 T1의 값으로 복원
            backinput() ; // 토큰 T1을 입력으로 되돌림
                          // T2의 확장에서 나온 토큰들보다 앞에
        }
        break;

        // 다른 확장 가능한 명령을 처리하는 코드
        case “텍스트로 변환” 명령: // \number, \string, \romannumeral, 중 하나
                                        // \meaning, \fontname, \jobname
                                        // 이들은 curcmd의 같은 값을 공유한다
        break;

        case \noexpand: // 다음 토큰의 확장을 억제
        ...
        break;

        case \csname:  //제어 시퀀스 이름을 생성한다.
        ...
        break;

        case \the: // 일부 토큰을 삽입
        ....
        break;

        case “\if... 테스트 명령” : // TeX의 조건문 중 하나를 처리:
                                      // \if, \ifcat, \ifnum, \ifdim,\ifodd, \ifvmode,
                                      // \ifhmode, \ifmmode, \ifinner, \ifvoid,
                                      // \ifhbox, \ifvbox, \ifx, \ifeof, \iftrue, \iffalse,
                                      // \ifcase, \ifdefined, \ifcsname, \iffontchar
        ...
        break;

        case “\fi 또는 \else”: // 현재 조건문을 종료
        ...
        break;

        // TeX 엔진이 지원하는 다른 확장 가능한 primitive 명령들에 대해서도
        // TeX 엔진

        }

    }else // 확장 가능한 primitive가 아님: 매크로임
        {
             macrocall()
        }
        //... 코드 더 제거됨
    }
```

### 전역 변수를 사랑하는 TeX

아마도 TeX의 연식과 그것이 설계된 시대를 반영하듯, TeX의 소스 코드는 이른바 [전역 변수](https://en.wikipedia.org/wiki/Global_variable)—실제로는 수백 개나 있다. 전역 변수는 그 특성상 TeX 소스 코드 어디에서나 변경/수정될 수 있는데, Knuth의 TeX의 경우 이는 25,000줄이 넘는 코드와 수백 개의 함수를 담은 단일 거대한 파일이다. TeX가 어떻게 동작하는지 이해하는 일은 항상 쉬운 과제는 아니다...

처리하려면 `\expandafter`, TeX는 다음이라는 함수를 사용해 현재 입력에서 토큰들을 읽는다 `gettoken()` 이 함수의 동작은 토큰을 생성하고 TeX 소스 코드 전반에서 사용되는 몇몇 핵심 전역 변수의 값을 설정하는 것이다. 그 동작에 의해 업데이트되는 두 변수는 `gettoken()`, 은/는 다음의 구현에 사용된다 `\expandafter`:

* `curtok`: (현재 토큰) 방금 읽은 토큰의 정수값;
* `에 저장된)`: (현재 명령 코드) 그 토큰이 나타내는 명령(또는 문자)의 명령 코드 `curtok`.

처리할 때 `\expandafter`$$\mathrm{T\_1T\_2}$$ TeX는 토큰 $$\mathrm{T\_1}$$ 를 읽고 그 값(정수)을 다음이라는 지역 변수에 임시로 저장한다 `t`. 그런 다음 TeX는 $$\mathrm{T\_2}$$ 를 읽고, 그 토큰이 확장 가능한 명령을 나타내는지 확인한다—즉, 그 명령 코드(`에 저장된)`)가 100보다 큰지 확인한다. 그렇다면 TeX는 다음이 나타내는 명령을 확장해야 한다 $$\mathrm{T\_2}$$ 그리고 다음 함수에 또 한 번 호출을 가한다 `expand()`: 이는 다음의 예이다 *재귀* 왜냐하면 `expand()` 함수가 자기 자신을 호출하는 것. 확장의 재귀적 특성을 인식하는 일은, 특히 다음을 사용할 때 `\expandafter`, 을/를 사용하면 여러 개가 연속된 `\expandafter` 명령들—즉, `\expandafter\expandafter\expandafter...` 이 어떻게 효과를 내는지 이해하는 데 도움이 될 수 있다.

만약 토큰 $$\mathrm{T\_2}$$ 가 확장 가능하면, 확장이 일어나며 재귀 호출이 다음으로 `expand()` 돌아오면, 다음의 구현 내 코드가 `\expandafter` 토큰을 다시 삽입한다 $$\mathrm{T\_1}$$ 입력에 되돌려 넣는다. 전역 변수 `curtok` 는 저장된 토큰의 값으로 다시 할당되는데—그 값은 지역 변수 `t`, 즉 토큰의 값인 $$\mathrm{T\_1}$$—이며, 다음 함수가 호출된다 `backinput().`

#### 함수 backinput()

이름에서 알 수 있듯이, 이 함수는 토큰을 “입력으로 되돌린다”. 이를 위해 TeX는 전역 변수의 현재 값을 사용해 `curtok` 단 하나의 토큰을 포함하는 토큰 리스트를 만든다(그 토큰의 정수값은 다음에 의해 제공된다 `curtok`). TeX는 또한 입력 처리를 조정하여, 적절한 시점에 그 단일 토큰 리스트가 이후 입력 처리의 일부로 TeX에 의해 다시 읽히도록 한다. 특히 다음 토큰에 유의하라 $$\mathrm{T\_1}$$ 가 다시 삽입되는 것은 *확장이 끝난 뒤에*, 이는 TeX가 그 다시 삽입된 토큰을 읽게 한다 *이전에* 그것이 다음의 확장에서 생겨난 토큰들을 읽을 때 $$\mathrm{T\_2}$$.

### 매크로 처리: macrocall() 함수

앞서 논의했듯이, 모든 매크로와 일부 primitive 명령은 확장 가능하며 모든 확장 처리는 다음을 거친다 `expand()` 함수. 하지만 `expand()` 는 다음을 신중하게 사용한다 `에 저장된)` (현재 명령) 값을 사용해 확장 가능한 primitive와 매크로를 구별하는데, 이는 매크로 확장 과정이 다음이라는 전용 함수에 의해 처리되기 때문이다 `macrocall()`. 매크로는 특수한 확장 과정이 필요한데, 매크로 인자와 구분자 토큰을 매우 특정하고 엄격한 방식으로 찾아내어 스캔해야 하기 때문이다. 따라서 그 과정은 이를 수행하도록 설계된 함수에 맡겨진다: `macrocall()`.

#### 매크로 확장 vs. 매크로 실행

매크로 *확장* 은/는 매크로 *실행*: 매크로의 확장은 TeX가 매크로를 *실행할 준비가 되도록 하기 위해 수행하는 사전 실행 과정이다*. 매크로의 “실행”은 TeX가 그 매크로의 정의(치환 텍스트)와 그 인자(매개변수)에 들어 있는 토큰들을 적극적으로 읽고 처리할 때 일어난다.

#### 매크로 확장

매크로를 확장하려면 TeX는 먼저 그 매크로가 인자를 받는지 확인한다; 그렇다면, `macrocall()` 매우 주의 깊게 입력을 훑어 매크로의 인자가 될 토큰을 찾는다. 그 과정에는 매크로의 원래 정의에서 사용된 구분자 토큰이 있는지 사용자의 입력을 확인하는 일도 포함된다—매크로 호출에서 사용된 토큰의 패턴은 저장된 정의에 들어 있는 토큰의 패턴과 정확히 일치해야 한다. 그러나 구분자로 사용된 토큰은 TeX에 의해 단순히 버려진다. 사실상 그것들은 TeX가 매크로의 인자가 될 실제 토큰들, 즉 사용자가 매크로로 처리하길 의도한 토큰들을 판별하는 데 사용하는 일종의 “구두점”일 뿐이다. 구분자 토큰에 대한 자세한 내용은 다음을 보라 [TeX 매크로는 실제로 어떻게 동작하는가](/latex/ko/more-topics/22-how-tex-macros-actually-work-part-4.md).

각 매개변수(`#1, #2...#9`)가 매크로의 원래 정의에 있는 경우, TeX는 실제 매크로 호출을 스캔하여 사용자가 제공한 어떤 토큰이 각 매개변수에 들어갈 것인지(즉, 매크로의 인자를 형성하는지) 식별한다. 그 과정은 하나 이상의 작은 토큰 리스트를 만들어 내는데, 매크로 인자마다 하나씩이다.

매크로 인자가 감지되고 그 토큰 리스트가 준비되면, TeX는 메모리에 저장된 매크로의 정의(치환 텍스트)를 가져오고, TeX가 더 많은 토큰을 읽고/처리할 준비가 될 때마다 그것들을 매크로의 치환 텍스트에서 읽도록 입력 처리를 조정하여 매크로를 실행한다. 적절한 시점에, 매크로 실행 중에, 매크로 인자를 나타내는 토큰 리스트가 매크로 치환 텍스트 안의 올바른 위치에 삽입된다.

다시 말해, 매크로 명령의 확장은 다음을 의미한다 *제거하는 것* 그 매크로 명령(토큰)을 입력에서 *대체하는 것* 그것을 매크로의 치환 텍스트로 저장된 토큰 리스트로

TeX의 매크로 처리에 대한 심층적인 내용은 6부작 글 시리즈를 보라 [TeX 매크로는 실제로 어떻게 동작하는가?](/latex/ko/more-topics/01-a-six-part-series-how-do-tex-macros-actually-work.md)

[1부](/latex/ko/in-depth-articles/19-how-does-expandafter-work-an-introduction-to-tex-tokens.md) [2부](/latex/ko/in-depth-articles/22-how-does-expandafter-work-the-meaning-of-expansion.md) [3부](/latex/ko/in-depth-articles/21-how-does-expandafter-work-tex-uses-temporary-token-lists.md) [4부](/latex/ko/in-depth-articles/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md) [5부](/latex/ko/in-depth-articles/17-how-does-expandafter-work-a-detailed-macro-case-study.md) [6부](/latex/ko/in-depth-articles/18-how-does-expandafter-work-a-detailed-study-of-consecutive-expandafter-commands.md)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://overleaf-pro.ayaka.space/latex/ko/in-depth-articles/20-how-does-expandafter-work-from-basic-principles-to-exploring-tex-s-source-code.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
