> 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/17-how-does-expandafter-work-a-detailed-macro-case-study.md).

# \expandafter는 어떻게 작동하나요: 상세한 매크로 사례 연구

&#x20;[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)&#x20;

## 사례 연구: \expandafter 예시, The $$\varepsilon\mathrm{\text{-}{\TeX}}$$ 매뉴얼

다음 $$\varepsilon\mathrm{\text{-}{\TeX}}$$ 조판 엔진은 Knuth의 TeX 소프트웨어에서 파생되었으며, 원래는 “임시” 단계로서 다음의 개발을 향한 것으로 의도되었다 [새 조판 시스템](https://en.wikipedia.org/wiki/New_Typesetting_System) (NTS)는 Java 프로그래밍 언어로 작성되었다. $$\varepsilon\mathrm{\text{-}{\TeX}}$$ 는 1990년대 후반에 Knuth의 원래 프로그램에는 없는 추가 기능을 제공하는 새로운 원시 명령어 모음을 추가하기 위해 처음 개발되었다. 비록 $$\varepsilon\mathrm{\text{-}{\TeX}}$$ 초기 출시 이후 정기적인 업데이트를 받아왔지만, 오늘날에는 독립형 조판 엔진으로 널리 사용되지는 않으며, 그 혁신은 이후 세대의 TeX인 pdfTeX, XeTeX, LuaTeX에 흡수되었다.

다음 [$$\varepsilon\mathrm{\text{-}{\TeX}}$$ manual](http://mirror.ox.ac.uk/sites/ctan.org/systems/doc/etex/etex_man.pdf) 는 ...를 영리하게 활용하는 매크로의 유익한 예를 담고 있다 `\\expandafter`:

```
    \def\foo#1#2{\number#1
    \ifnum#1<#2,
    \expandafter\foo
    \expandafter{\number\numexpr#1+1\expandafter}%
    \expandafter{\number#2\expandafter}%
    \fi}
```

`\foo` 반복 메커니즘을 구현하여, 그 결과 `\foo{7}{13}` 를 생성한다 `7, 8, 9, 10, 11, 12, 13`; 그러나, `\foo` 어떠한 것도 사용하지 않는다 *변수에 대한 할당* 반복 과정을 제어하기 위해서인데—이 때문에 이 매크로는 좀 더 자세히 살펴볼 가치가 있는 흥미로운 매크로가 된다.

### 배경 설명: 표현식과 할당

의 중요한 요소는 `\foo`의 코드에서 명령어를 사용하는 것이다 `\numexpr`, 처음 소개된 관련 원시 명령어 4개로 이루어진 집합의 명령어이다 $$\varepsilon\mathrm{\text{-}{\TeX}}$$: `\numexpr`, `\dimexpr`, `\glueexpr` 및 `\muexpr`. 그 목적은 이른바 *표현식* 을 구성하는 것이다. 이는 TeX 값의 number, dimen, glue 또는 muglue 유형을 각각 계산/조작할 수 있게 한다. The $$\varepsilon\mathrm{\text{-}{\TeX}}$$ 매뉴얼에서 논의하듯, 중요한 특징은 *표현식* 그들의 평가(계산)는 TeX이 어떤 *할당*.

프로그래밍 용어로, 할당은 변수에 특정 값을 설정(배정)하는 과정이다; 예를 들어, `\count` 레지스터 `99` 값이 들어가도록 `12345` 통해 `\count99=12345`. TeX 처리 중에는 토큰 레지스터에 일련의 토큰을 담도록 할당하거나, 박스 레지스터에 박스 내용을 담도록 할당하는 등 다른 많은 유형의 할당이 이루어진다.

예를 들어 다음과 같은 할당을 수행하려면 `\count99=12345`, TeX은 ...의 동작을 구현하는 내부 코드를 실행(작동)해야 한다 `\count` 또는 어떤 종류의 할당을 수행하는 다른 원시 명령어도 마찬가지이다. 그러나 TeX이 순수한 *확장* 를 수행할 때가 있는데, 그때는 그러한 할당이 실행되지 않는다—*TeX 처리의 그 시점에서는*. 이러한 상황의 예로 다음 명령들이 있다:

* `\edef\command {*token list*}` 토큰을 확장하는 “확장 정의” 매크로 정의 명령으로, *토큰 리스트* 를 확장하고 결과를 `\command`.
* `\write *number* {*token list*}` ...의 토큰을 확장하고 `*token list*` 그리고 이를 ...로 표시되는 파일에 기록한다 `*숫자*`.
* `\directlua {*token list*}` 이 LuaTeX 원시 명령은 Lua 코드를 내장 Lua 인터프리터에 전달하는 데 사용된다. ...의 모든 토큰은 `*token list*` 실행을 위해 Lua 인터프리터에 전달되기 전에 완전히 확장된다.

#### \edef의 간단한 예

다음과 같은 기본 매크로를 작성하면:

```
     \def\mycount{\count99=12345}
     \edef\mymacro{\mycount}
```

`\edef` 는 확장되지만 `\mycount` 를 구성 토큰들로 분해할 뿐 더 나아가지는 않는다: `\mymacro` 실행되지 않는다: 즉, `12345` 을 `\count99` *이 시점에서는 일어나지 않는다*; 우리가 `\mymacro` 를 호출할 때에만 그 할당이 이루어진다. TeX이 그 `\count` 원시 명령을 처리하는 코드를 실행하면서 *확장 전용 작업* 어떠한 할당도 확장 과정 자체가 아니라 TeX 처리의 나중 단계에서 실행된다.

#### 왜 여기서 할당이 중요한가?

반복을 수행하는 코드를 작성할 때—어떤 프로그래밍 언어든—“루프 카운터” 역할을 하도록 지정된 변수를 두는 것이 일반적이다: 이는 루프가 실행되는 횟수를 제어하는 데 사용된다. 반복은 보통 그 지정된 루프 카운터 변수가 특정 값에 도달했는지 검사함으로써 제어되며, 그 변수는 루프의 각 반복마다 증가(또는 감소)한다. 그러나 루프 카운터 변수를 수정한다는 것은 새 값을 할당하는 것을 의미하고, TeX에서는 대개 원시 명령어 `\advance` 에 저장된 값을 증가(또는 감소)시키기 위해 `\count` 레지스터. 보았듯이, TeX의 순수 확장 과정에서는 그러한 할당(변수 증가 포함)이 일어날 수 없다: 매크로 `\foo` 는 이 제약을 영리하게 우회한다.

### \foo 설명으로 돌아가서

이 매크로는 `\foo` 반복 과정을 제어할 수 있다 *없이* 어떤 변수에도 값을 할당할 필요 없이: 확장에서 생겨나는 데이터, 즉 임시 토큰 리스트에 저장된 데이터 값을 사용하여 루프가 얼마나 자주 일어날지를 제어한다. TeX이 임시 토큰 리스트를 사용하는 방식(생성)에 대한 지식을 활용하면, 정확히 어떻게 `\foo` 그 결과를 달성하는지 자세히 살펴볼 수 있다.

**기억하세요**: 우리는 어떤 매크로의 실행을, 그 정의의 원래 텍스트가 물리적인 `.tex` 파일에 담겨 있었고—TeX에 의해 스캔(읽어 들여짐)되어 매크로 정의를 나타내는 토큰 리스트로 변환된 뒤의 시점에서 따라가고 있다. 본질적으로, 우리는 저장된 그 *토큰* 를 TeX의 메모리 어딘가에 있는 매크로 정의의 토큰들을 읽고 처리하는 동안 추적하는 셈이다. 매크로 정의의 TeX 코드에 원래 존재하던 공백 문자들(다음 안의 텍스트)은 `.tex` 파일)은 TeX이 그 텍스트를 명령어를 찾기 위해 스캔하는 동안(공백은 종결자 역할), 흡수되었거나, 또는 쉼표 뒤의 공백 문자(`,`)와 같은 토큰으로 변환되었을 것이다.  `\ifnum#1<#2,` 는 줄 끝 문자(`\r`)가 공백으로 변환되면서 생겨난 것이다.

왜냐하면 ...의 TeX 코드에서는 `\foo` 여러 개의 `\\expandafter` 명령을 사용하므로, 각 `\\expandafter`에 아래첨자를 붙여 설명을 돕겠다 `\\expandafter` 을 $$\mathrm{T^i\_1}$$ 및 $$\mathrm{T^i\_2}$$에 의해 처리되는 토큰에 대한 표기법을 확장하여 $$\mathrm{T\_1}$$ 및 $$\mathrm{T\_2}$$ 에는 `\expandafter<sub>i</sub>`: `\expandafter<sub>i</sub>` $$\mathrm{T^i\_1T^i\_2}$$

주석을 단 매크로 코드는 다음과 같다:

```
    \def\foo#1#2{\number#1
    \ifnum#1<#2,
    \expandafter1\foo
    \expandafter2{\number\numexpr#1+1\expandafter3}%
    \expandafter4{\number#2\expandafter5}%
    \fi}
```

`\foo` 로 시작한다 `\number#1` 확장 가능한 명령어인 `\number` 를 사용하여 첫 번째 인수 값을 조판된 표현으로 변환한다. 이 `\number` 명령은 숫자 값에 포함된 개별 숫자를 나타내는 문자 토큰을 포함한 임시 토큰 리스트를 생성함으로써 작동한다. `\number` 가 다루고 있는 그 토큰 리스트는 TeX의 다음 입력 원천이 된다. 여기서 그 토큰 리스트가 읽히고, 토큰들은 `#1`.

다음으로, 매크로는 다음 테스트를 수행한다 `\ifnum#1<#2` ...에 대한 인수가 `#1` ...에 전달된 인수보다 작은지 확인한다 `#2`. 그렇다면 쉼표(`,`) 토큰이 출력(조판)되고, 그 뒤에 쉼표 뒤의 줄바꿈 문자(`,`)에서 생성된 토큰에서 비롯된 공백이 이어진다. 그 공백 문자는 TeX이 이 줄을 `.tex` 파일에 있습니다.

매크로는 다음 코드 부분을 처리하면서 계속 진행하는데, 이것이 작동의 핵심이다:

```
    \expandafter1\foo
    \expandafter2{\number\numexpr#1+1\expandafter3}%
    \expandafter4{\number#2\expandafter5}%
    \fi}
```

본질적으로, 이 코드는 일련의 임시 토큰 리스트를 생성하며, 그 결과 `\foo` 매크로는 if-테스트가 `\ifnum#1<#2` 더 이상 참이 아니게 되면 종료된다. 그러나 *어떻게* 반복이 어떻게 제어되는가? 왜냐하면 할당이 일어나지 않기 때문이다: “루프 카운터”는 어디에 있는가?

코드를 살펴보는 것부터 시작하자 `\expandafter<sub>1</sub>\foo\expandafter<sub>2</sub>`. 아래첨자 표기를 사용하겠다는 점에 유의하자 `<sub>token</sub>` (또는 `<sub>(token)</sub>`)는 여기서 TeX이 숫자(정수) 토큰 값을 읽고/처리하고 있음을 상기시키기 위한 것이다.

여기서는 다음 토큰들이 `\expandafter<sub>1</sub>`:

* $$\mathrm{T^1\_1} =$$`\foo<sub>token</sub>` 읽혀서 나중을 위해 저장되고 *다시 삽입하기 위해 저장된다* 입력으로
* $$\mathrm{T^1\_2} =$$`\expandafter<sub>2 (token)</sub>` 확장된다

수직 `\expandafter<sub>2</sub>` 그러면 다음과 같다:

* $$\mathrm{T^2\_1} =$$`{<sub>token</sub>` 를 보게 되며, 이는 나중에 *다시 삽입하기 위해 저장된다* 입력으로
* $$\mathrm{T^2\_2} =$$ `\number<sub>token</sub>` 확장된다

**참고:**`\number` 는 “토큰으로 변환”하는 것이 목적의 확장 가능한 명령어이다. 즉, 수치를 그 수치를 나타내는 일련의 문자 토큰으로 변환한다. `\number` 가 확장되면, TeX이 가장 먼저 하는 일은 정수를 찾기 위해 입력을 스캔하는 것이다: 이 과정에서 추가 확장이 촉발된다.

**핵심은 다음과 같다:** 여기서, `\number` 는 ...에 작용하고 있다 *표현식* `\numexpr#1+1` 의 값을 계산하는 `#1+1`. 그 계산 결과는 `\number` 에 의해 처리되어 ...의 값을 나타내는 문자 토큰을 포함한 임시 토큰 리스트로 변환한다 `#1 + 1`. ...에 의해 생성된 그 임시 토큰 리스트는 `\number`\expandafter를 통해 `\foo`의 또 다른 호출에 대한 첫 번째 인수로 읽히게 된다 `\advance` 루프 카운터를 증가시키는 대신(즉, `\numexpr` 와 할당을 통해),`\foo`의 사용은 새로운 값을 만들지만 할당은 필요하지 않다. 이 메커니즘을 통해 루프를 제어하는 변수( `#1`의 매개변수

다음으로, `\expandafter<sub>3</sub>` 가 처리되어 다음을 산출한다:

* $$\mathrm{T^3\_1} =$$`}<sub>token</sub>` 를 보게 되며, 이는 나중에 *다시 삽입하기 위해 저장된다* 입력으로
* $$\mathrm{T^3\_2} =$$`\expandafter<sub>4 (token)</sub>`, 이는 확장된다:

수직 `\expandafter<sub>4</sub>` 그러면 다음과 같다:

* $$\mathrm{T^4\_1} =$$`{<sub>token</sub>` 를 보게 되며, 이는 나중에 *다시 삽입하기 위해 저장된다* 입력으로
* $$\mathrm{T^4\_2} =$$`\number<sub>token</sub>` 이는 확장되어 `#2` 또 다른 임시 토큰 리스트로 변환한다.

마지막으로,`\expandafter<sub>5</sub>` 가 확장된다:

* $$\mathrm{T^5\_1} =$$`}<sub>token</sub>` 를 보게 되며, 이는 나중에 *다시 삽입하기 위해 저장된다* 입력으로
* $$\mathrm{T^5\_2} =$$`\fi<sub>token</sub>`, 이는 확장 가능한 명령어이다.

  ...의 확장은 `\fi` 사실상 ...를 종료한다 `\ifnum` 이며, 결과적으로 이 매크로의 이번 반복을 닫는다. 이제 TeX은 여러 `\\expandafter` 명령에 의해 임시로 저장된 모든 토큰의 재삽입을 완료한다: 이는 각 `\\expandafter`가 저장한 토큰에서 비롯된 단일 토큰 토큰 리스트들의 연속을 생성한다. 그에 더해 TeX은 또한 `\number`.

### 토큰 리스트 조립

본질적으로, `\foo` 매크로는 일련의 토큰 리스트를 생성한다: 이를 `\foo` 를 토큰 리스트 “생산 시설”로 생각할 수 있다. 그 토큰 리스트들은 TeX에 의해 읽혀 다음 입력 원천이 된다. 영리한 부분은 `\foo`:

```
    \expandafter1\foo\expandafter2
```

이를 통해 `\foo` 자신을 다시 호출하도록 하지만, `\number`에 의해 구성된 토큰 리스트에 저장된 다른 인수들을 사용하게 한다. 이러한 토큰 리스트들이 함께 매크로 호출처럼 동작하게 하려면, 중괄호 `{` 및 `}` 는 모두 저장되었고 ...의 작용에 의해 (단일 토큰 리스트로) 입력에 다시 삽입되었다 `\\expandafter` 명령들.

![\foo 매크로에 의해 생성된 토큰 리스트](/files/dfc93ba048ed7205cff74b51d1d6830e18b80038)

&#x20;[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/17-how-does-expandafter-work-a-detailed-macro-case-study.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.
