> 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/more-topics/22-how-tex-macros-actually-work-part-4.md).

# TeX 매크로는 실제로 어떻게 작동하는가: 4부

[1부](/latex/ko/more-topics/19-how-tex-macros-actually-work-part-1.md) [2부](/latex/ko/more-topics/20-how-tex-macros-actually-work-part-2.md) [3부](/latex/ko/more-topics/21-how-tex-macros-actually-work-part-3.md) [4부](/latex/ko/more-topics/22-how-tex-macros-actually-work-part-4.md) [5부](/latex/ko/more-topics/23-how-tex-macros-actually-work-part-5.md) [6부](/latex/ko/more-topics/24-how-tex-macros-actually-work-part-6.md)

## 소개 및 개요

1–3부에서는 TeX 매크로가 어떻게 작동하는지 이해하기 위한 준비로, 몇 가지 저수준 배경 세부사항을 깊이 있게 살펴보았습니다. 이 글에서는 5부와 6부에서 다시 한 번 깊이 있게 살펴보기 위한 준비로 TeX 매크로의 몇 가지 기본적인 실용 원리를 검토하기 위해 잠시 “숨을 고르려” 합니다. 이 글 전반에서 우리는 TeX 원시 명령으로 정의된 예제 매크로를 보여줄 것입니다 `\def`: 아마 더 익숙할 LaTeX 명령은 사용하지 않을 것입니다 `\newcommand`. 그 이유는 아주 분명합니다. 우리의 목표는 TeX의 매크로 동작의 근본 원리를 이해하는 것이지만, 그러려면 핵심 명령을 사용해야 하기 때문입니다 *내장된* TeX 소프트웨어의. 다음과 같은 LaTeX 명령은 `\newcommand`, 그 자체가 매크로입니다. 즉, 특정한 프로그램된 동작을 가진 명령이며, 궁극적으로는 더 낮은 수준의 TeX 원시 명령 층들로 구성됩니다. TeX의 근본적인 동작을 더 잘 이해하려면 LaTeX 매크로가 아니라 TeX 원시 명령을 사용해야 합니다.

### 우리는 어디로 가고 있나요?

본질적으로, 우리는 매크로를 토큰 목록의 특수한 형태로 설명하려고 합니다. TeX에 매크로를 정의하라고 지시하면 TeX는 하나의 토큰 시퀀스(토큰 목록)를 만들고, 여러분이 정의한 이름과 연결된 자신의 메모리에 저장합니다. 5부와 6부에서는 매크로 토큰 목록을 꽤 자세히 살펴보겠지만, 이 글에서 벗어나 배경 정보를 읽고 싶다면 [TeX 토큰 리스트란 무엇인가?](/latex/ko/in-depth-articles/54-what-is-a-tex-token-list.md)

매크로의 토큰 목록과 그 매개변수에는 우리가 자세히 살펴볼 몇 가지 추가적인 요소가 포함되며, 예제를 충분히 사용하게 됩니다. TeX의 매크로 처리 동작을 더 잘 이해하려면 기억해야 할 핵심은 딱 하나입니다. TeX는 입력 처리의 가장 초기 단계에서만 문자에 대해 생각한다는 점입니다. 그 시점부터는 끝까지 토큰뿐입니다! 이 글과 이 시리즈의 나머지 글들에서 우리는 TeX 매크로에서 토큰이 맡는 역할을 살펴볼 것입니다.

## 매크로의 네 부분

### 알림: 매크로 매개변수와 매크로 인수

시작하기 전에 매크로의 *매개변수* 와 매크로의 *인자*의 차이를 다시 떠올려 두는 것이 좋습니다. 이 글 전반에서 두 용어를 모두 사용할 것이기 때문입니다. 예를 들어 매크로 \foo를 정의한다고 합시다

```
\def\foo#1#2{이것은 #1, 이것은 #2}
```

구성 요소(토큰) `#1`, `#2` (최대 `#9`)을 매크로의 *매개변수*이라고 합니다. 매크로를 호출할 때 실제로 사용할 데이터를 위한 “자리 표시자”라고 생각하면 됩니다:

```
\foo{alpha}{beta}
```

여기서, `alpha` 및 `beta` 는 *인자* 입니다. 매크로의 인수는 매크로를 정의할 때 사용한 매개변수 자리표시자(`#1`, `#2`... `#9`)에 채워 넣는 실제 값입니다.

### 매크로 정의: 4개의 요소가 있습니다

아마 다소 형식적으로 보이는 매크로 정의부터 시작하겠지만, 이후 논의를 위한 유용한 틀을 제공합니다.

모든 매크로 정의는 4개의 부분으로 이루어집니다:

```
<TeX macro primitive><macro name><parameter text>{<replacement text>}
```

여기서:

* `<TeX macro primitive>`: 다음 중 하나 `\def`, `\edef`, `\gdef` 또는 `\xdef`;
* `<매크로 이름>`: 매크로 명령에 부여된 이름, 예를 들면 `\foo`;
* `<매개변수 텍스트>`: 이것은 없을 수도 있지만, 있다면 *토큰* 앞에 나타나는 `<대체 텍스트>` 들의 연속입니다. 그 `<매개변수 텍스트>` 에는 매크로 매개변수(`#1`, `#2`... `#9`)와 다른 토큰 유형이 포함될 수 있습니다. 본질적으로, 그리고 자세히 살펴보겠지만, 그 `<매개변수 텍스트>` 는 일종의 *토큰 템플릿* 을 제공하며, TeX는 이를 사용해 사용자가 매크로의 인수로 어떤 토큰을 사용하려는지 알아냅니다. 매크로를 호출하면 TeX는 *인자의 일부를 이루는지* 토큰들을 여러분의 매크로의 `<대체 텍스트>` (이것 역시 토큰 목록입니다)으로 보냅니다.
* `{<대체 텍스트>}`: 이것이 여러분 매크로의 실제 본문입니다. 매크로가 처리(확장)될 때 *인자* 가 “주입”되는 토큰들의 연속입니다. 인수는 원래 정의에서 사용된 매크로 매개변수가 가리키는 위치에 채워집니다.

**주의**: 논의 전반에서 우리는 `<매크로 이름>` 뒤에는 구분 기호 역할을 하여 `<매크로 이름>`를 끝내는 데 쓰이는 범주 코드 10의 공백 문자가 따라온다고 가정합니다. 우리는 *그 공백 문자를* 텍스트/논의에서 명시적으로 보여주지 않았지만, 그것이 있다고 가정합니다. 엄밀히 말하면, 우리는 그것을 대략 이렇게 나타내야 합니다:

```
<TeX 매크로 원시 명령><매크로 이름><공백><매개변수 텍스트>{<대체 텍스트>}
```

그러나 우리는 `<공백>` 문자의 명시적 포함은 생략하고, 그 존재를 암묵적으로 가정할 것입니다.

#### 중괄호 {}에 대한 메모

우리는 두 개의 중괄호 사용을 보여주었습니다: `{` 및 `}` 이는 여러분 매크로의 실제 본문을 둘러싸고(구분하고) 있습니다 `<대체 텍스트>`. 그러나 `{` 및 `}` 의 사용은 단지 받아들인 관례일 뿐입니다. TeX가 실제로 기대하는 것은 여러분의 매크로 `<대체 텍스트>` 텍스트가 범주 코드 1("그룹 시작")의 문자로 열리고 범주 코드 2("그룹 끝")의 문자로 닫히는 것입니다. 관례적으로, 이것들은 각각 `{` 및 `}` 중괄호 문자입니다. 하지만 원한다면 임의의 문자 쌍을 그 역할로 지정할 수 있습니다. 예를 들어

```
\catcode`\(=1
\catcode`\)=2
```

이제 다음과 같이 매크로를 정의하고 사용할 수 있습니다:

```
\def\foo #1(Hello, #1)
\foo(World!)
```

그리고 여전히 `{` 및 `}` 를 사용할 수 있습니다. 왜냐하면 우리는 그들의 범주 코드를 바꾸지 않았기 때문입니다. 여러 문자는 같은 범주 코드를 가질 수 있고 실제로 그렇게 하므로, 기존 방식대로 매크로를 계속 정의할 수 있습니다:

```
\def\foo #1{Hello, #1}
\foo{World!}
```

### 그리고 {}

우리 논의와 가장 관련이 있는 매크로 정의의 구성 요소는 `<매개변수 텍스트>` 및 `{<대체 텍스트>}`입니다. 매크로를 정의할 때 `<매개변수 텍스트>` 는 사실상 매크로를 어떻게 사용해야 하는지를 정의하는 엄격한 토큰 템플릿입니다. 앞서 언급했듯이, `<매개변수 텍스트>` 는 예를 들어 비워 둘 수도 있습니다 `\def\foo{Some text}` 여기서는 명령 이름(`\foo`)과 여는 중괄호 `{` 사이에 아무것도 없으며, 이 중괄호는 여기서 매크로의 `<대체 텍스트>`.

**참고**의 시작을 알립니다. 어떤 독자들은 TeX의 “해시쿼트(hashquote)” 메커니즘(`#{`)에 대해 알고 있을 수 있지만, 여기서는 다루지 않겠습니다.

### 와 매크로 구분 기호

이 글은 매크로 작성에 대한 아주 포괄적인 총정리를 하려는 것은 아니지만, 간단한 복습을 하고 몇 가지 예를 통해 `<매개변수 텍스트>` 가 왜 복잡해질 수 있는지 보여주는 것은 가치가 있습니다. TeX는 `<매개변수 텍스트>` 에 다음을 포함할 수 있도록 허용하기

* **매크로 매개변수**: (`#1`, `#2`,... `#9`) — 사용자가 매크로를 실행할 때 제공할 값의 “자리 표시자” 역할을 합니다. 즉 매크로의 *인자*;
* **구분자 토큰**: 매개변수 토큰들 사이/주변에 끼워 넣을 수 있는 임의의 토큰들로, 매크로 매개변수 사이의 경계를 지정하는 데 사용됩니다. 그런 구분자들은 `<매개변수 텍스트>` 를 여러분이 매크로를 사용할 때 따라야 할 “토큰 템플릿”으로 만드는 일종의 “구두점”이라고 생각할 수 있습니다. 구분자 토큰은 조판되지 않습니다.

그렇다면 이게 실제로 무슨 뜻일까요—몇 가지 예를 살펴보겠습니다. `<매개변수 텍스트>` 는 매크로 이름과 왼쪽 중괄호 `{` 사이에 놓입니다

#### 구분자: 예 1

다음과 같은 기본 매크로를 정의한다고 합시다: `\foo` 은 다음과 같습니다:

```
\def\foo ABC{hello, there}
```

* `<매개변수 텍스트>` = `ABC`
* 매개변수 토큰(`#1`, `#2`,... `#9`)
* 구분자는 *세 문자 토큰* `ABC` 입니다. 하지만 이 예에서는 다소 군더더기 같고, 단지 예시로만 쓰인 것입니다.

세 문자 토큰 `ABC` 은 구분자로 취급됩니다. 즉 조판될 대상이 아니라, 매크로를 호출할 때 존재해야 할 것으로 기대되는 “구두점”입니다. 매크로 `\foo` 을 사용할 때는 정의될 때 있었던 것과 같은 구분자를 제공해야 합니다.

입력해 보면 `\foo ABC` 를 텍스트에 넣으면 `hello, there`가 조판됩니다. 문자 토큰 `ABC` 은 조판되지 않지만, TeX는 매우 주의 깊게 그것들이 여러분의 `\foo`호출에 실제로 존재하는지 확인했습니다. TeX는 다음 Overleaf 화면 이미지에서 볼 수 있듯이 그 구분자(“구두점”)를 찾아 제거(흡수)합니다: `ABC` 는 조판되지 않습니다:

![TeX 매크로를 실행하는 Overleaf](/files/87c29368f26383d2acaa5ace8b38f72b2a5dc896)

다음을 사용하려고 하면 `\foo` 구분자 없이 `ABC` TeX는 오류를 내게 됩니다 `Use of \foo doesn’t match its definition.`:

![Overleaf에서 TeX 오류 표시](/files/8f908d8f03037418290608008d5ad9f5ce1f6412)

위 예에서는 `\foo` 를 감지한 뒤 TeX는 세 문자 토큰 `ABC` 를 보려고 기대하지만, 그렇게 하지 못합니다. 대신 `w` 에 대한 문자 토큰을 보고, 즉시 무언가 잘못되었음을 감지합니다.

#### 구분자: 예 2

흥미롭고 아마도 놀라운 사실은, 구분자는 정의되지 않은 명령까지 포함하여 임의의 명령 토큰일 수 있다는 점입니다 *조차*. 예를 들어, 우리는 다음과 같이 정의할 수 있습니다 `\foo` 다음과 같이

```
\def\foo A\bob B\anne{Hello \TeX{}}
```

* `<매개변수 텍스트>` = `A\bob B\anne`
* 매개변수 토큰(`#1`, `#2`,... `#9`)
* 구분자는 토큰들 `A\bob B\anne` 입니다. 하지만 역시 이 예에서는 군더더기이며, 논의 목적에만 사용됩니다. 참고로 `\bob` 및 `\anne` 는 가상의 명령으로, *정의되지 않았고*—정의될 필요도 없습니다.

매크로를 호출하면 TeX는 그 `<매개변수 텍스트>` 이 있는지 *여러분의 매크로 호출에서* 를 스캔하고, 메모리에 저장된 “토큰 템플릿” 버전 *과 토큰 단위로 비교합니다*—즉 매크로가 정의될 때 만들어진 버전입니다. TeX는 여러분의 매크로 호출에서 사용된 *을 스캔하고, 그곳에서 발견한 명령을 숫자 토큰 값으로 바꾸기만 합니다. 그것들을 실행하려는 것이 아니므로,* 가 전혀 정의되지 않았다는 사실은 중요하지 않습니다. TeX는 단지 메모리에 저장된 토큰 템플릿을 지침으로 사용하여, 여러분 매크로 호출의 `\bob` 및 `\anne` 중 어떤 토큰이 실제로 `<매개변수 텍스트>` 에 넣을 인수인지 알아냅니다 `<대체 텍스트>`.

다음 Overleaf 화면 일부에서 볼 수 있듯이, 문자 토큰(`하나의` 및 `B`)도 `A\bob B\anne` 에서 조판되지 않았고, 정의되지 않은 명령들 `\bob` 및 `\anne` 도 아무 문제를 일으키지 않았습니다. 이 모든 토큰은 *흡수되었습니다* TeX가 여러분의 `\foo` 사용을 `\foo` (토큰 목록)으로 메모리에 저장된

![TeX 매크로를 실행하는 Overleaf](/files/65419e30d8eb0540bf92489b541e1e2d18603dbf)

#### 구분자: 예 3

다음 예처럼 매크로 매개변수와 다양한 구분자(문자 토큰, 명령 토큰)를 섞어 넣을 수 있습니다:

```
\def\foo A\bob#1B\anne#2\jane#3bye!{Hello from \TeX{} to \#1=#1, \#2=#2 and \#3=#3}
```

* `<매개변수 텍스트>` = `A\bob#1B\anne#2\jane#3bye!`
* 매크로 매개변수 토큰은 3개입니다: `#1`, `#2`, `#3`
* 이번에는 매개변수(`#1`, `#2`, `#3`)가 다음과 같은 토큰 조합으로 구분됩니다:

  `A\bob#1B\anne#2\jane#3bye!`

여기서는 사실상 TeX에 템플릿을 제공한 것이며, TeX는 매크로를 호출할 때 이를 매우 주의 깊게 맞추려 하고, 또한 맞추기를 기대합니다 `\foo`: 여러분의 매크로 호출을 *토큰 단위로* 훑어보면서 다음을 일치시키고(찾아내고)자 할 것입니다:

* 두 토큰 `하나의` 및 `\bob` 이전의 `#1`
* 두 토큰 `B` 및 `\anne` 이전의 `#2`
* 토큰 `\jane` 매개변수 `#3` 와 *네 개의 문자 토큰* `b`, `및`,`e` 및 `!` 뒤에 `#3`.

**기억하세요**: TeX는 토큰으로 생각하므로 `bye!` 는 *네 개의 문자 토큰*.

이 매크로를 사용할 수 있는 방법은 두 가지입니다. 그룹을 제공하기 위해 여러 토큰 인수를 중괄호로 감쌀 수도 있습니다:

```
\foo A\bob{This}B\anne{That}\jane{Other}bye!
```

하지만 *그럴 필요는 없습니다* 왜냐하면 우리의 매크로 정의에는 토큰 템플릿을 제공하는 구분자가 있기 때문입니다. TeX는 그 템플릿을 사용해 구분자 토큰들만으로 이루어진 토큰들 사이에서 각 인수의 토큰을 골라낼 수 있습니다. 매크로를 다음과 같이 사용할 수 있습니다:

```
\foo A\bob ThisB\anne That\jane Otherbye!
```

그리고 TeX는 그룹을 사용했을 때와 동일한 결과를 내기 위해 인수들을 골라낼 수 있습니다 `{...}`:

![구분자를 사용하는 TeX 매크로를 실행하는 Overleaf](/files/614bba0c071e7d9bf84ef1b97eb73b73918d9589)

TeX가 어떤 토큰이 매개변수와 정확히 일치하는지 알아낸 방식을 보십시오 `#1` 및 `#3`:

![구분자를 사용하는 TeX 매크로를 실행하는 Overleaf](/files/2da4803be9cb1662482ad33d675df6b13e4ba168)

#### 구분자: 예 4(핵심은 문자들이 아니라 토큰들입니다!)

매크로를 다룰 때 우리가 정말로 토큰의 세계에 있다는 점을 기억하는 것이 중요함을 보여 주는 짧은 예입니다 *토큰* 및 **작동하지** *문자*…

A와 B가 구분자 역할을 하는 문자이고 둘 다 범주 코드 11을 갖는 다음의 짧은 매크로를 정의해 봅시다. 이것은 문제 없이 작동합니다:

```
\documentclass{article}
\begin{document}
\def\foo A#1B{Hello, #1}
\foo AGrahamB
\end{document}
```

를 조판합니다 `Hello, Graham`.

하지만 A 또는 B의 범주 코드를 11이 아닌 다른 값으로 바꾸면 매크로 호출은 실패합니다. B의 범주 코드를 12로 바꾼다고 합시다. 다음을 사용하여 ``\catcode`B=12`` 를 먼저 바꾸고, 이전과 같이 매크로를 다시 호출해 봅시다:

```
\documentclass{article}
\begin{document}
\def\foo A#1B{Hello, #1}
\foo AGrahamB % This works
\catcode`\B=12\relax
\foo AGrahamB
\end{document}
```

다소 당혹스러운 오류가 발생합니다:

```
Runaway argument?
GrahamB \end {document}
! File ended while scanning use of \foo.
<inserted text>
                \par
<*> main.tex

당신이 `}'를 잊은 것 같습니다. 그 때문에 제가
멈추고 싶었던 지점을 넘어 계속 읽게 되었습니다.
복구를 시도하겠습니다. 하지만 오류가 심각하다면,
지금 `E' 또는 `X'를 입력하고 파일을 고치는 것이 좋겠습니다.

! 비상 정지.
<*> main.tex

*** (작업이 중단됨, 올바른 \end를 찾지 못함)
```

![TeX 매크로 오류를 보여주는 Overleaf](/files/dafaa6c97f4dfbf7e9ec7852e99a0ea863718f4b)

불행히도 TeX의 기본 제안인 ``당신이 `}'를 잊은 것 같습니다`` 는 **는 틀렸습니다**, 이는 누락된 중괄호(`}`).

#### 무슨 일이 일어난 걸까요?

TeX는 다음과 일치시키려 하고 있습니다 `\foo` 매크로 *호출* 을 `\foo` 매크로 *definition* 메모리에 저장된 것과. 하나 이상의 인수가 필요한 매크로를 호출하면 TeX는 매크로 사용을 검사(스캔)하여 *인자* 여러분이 그 매크로에 제공하는 인수를 알아내야 합니다. 여기서 TeX는 인수가 A(범주 코드 11)와 B(범주 코드 11) 사이에 끼워져 있기를 기대합니다. 기억하세요: TeX는 *토큰*, **작동하지** *문자*.

A와 B의 토큰 값은 $$\mathrm{T\_A}$$ 및 $$\mathrm{T\_B}$$ 각각

$$\mathrm{T\_A = 256 \times 11 + 65 = 2881}$$ $$\mathrm{T\_B = 256 \times 11 + 66 =2882}$$

입니다. 그러나 TeX가 계속 탐색하면 B *하지만* 를 보게 되는데, 이제 그 범주 코드는 12이고 그 결과 다른 토큰 값이 됩니다:

$$\mathrm{T'\_B= 256 \times 12 + 66 =3138}$$

다음에서 `\foo` 매크로 정의에서, B의 토큰 값(구분자로 사용된 값)은 2882였지만 TeX는 이제 3138의 토큰 값을 봅니다. TeX는 이것을 단지 *인자의 일부를 이루는지* 에 사용될 또 하나의 토큰이라고 생각합니다 `\foo`에 제공된. TeX 입장에서는 인수의 마지막 토큰을 아직 찾지 못했으므로, 범주 코드 11을 가진 B를 찾기 위한 탐색에서 또 다른 토큰을 가져오게 됩니다. 바로 그때, 그리고 그 이유 때문에 매크로가 실패합니다. 인수를 찾으려는 시도에서 TeX는 “과도하게 지나쳐” 여러분이 `\foo` 매크로 호출의 인수 일부가 되도록 의도하지 않은 토큰들을 읽기 시작합니다. 그다음에 일어나는 일은 B 뒤에서 TeX가 어떤 토큰을 발견하느냐에 달려 있습니다. 그것들은 다양한 `Runaway argument?` 오류를 일으킬 것입니다.

우리의 예에서 TeX는 과도하게 지나가며 토큰 스트림 `\end {document}` 을 흡수하고, 곧바로 파일 끝에 도달하므로 다음과 같은 오류 메시지가 나타납니다:

```
! \foo를 스캔하는 도중 파일이 끝났습니다
```

## 5부

위에서 보았듯이, `<매개변수 텍스트>` 부분은 매우 단순한 형태에서부터 문자 토큰과 명령 토큰이 구분자로 끼어드는 복잡한 혼합까지 다양할 수 있습니다. TeX는 `<매개변수 텍스트>` 에 존재하는 다양한 토큰 조합을 처리하여 매크로에 제공된 인수를 추출하고, 또한 우리가 매크로를 잘못 사용하려 할 때 이를 감지할 수 있습니다. 어떻게 그렇게 하는지는 이 시리즈의 다음 글의 주제입니다.

[1부](/latex/ko/more-topics/19-how-tex-macros-actually-work-part-1.md) [2부](/latex/ko/more-topics/20-how-tex-macros-actually-work-part-2.md) [3부](/latex/ko/more-topics/21-how-tex-macros-actually-work-part-3.md) [4부](/latex/ko/more-topics/22-how-tex-macros-actually-work-part-4.md) [5부](/latex/ko/more-topics/23-how-tex-macros-actually-work-part-5.md) [6부](/latex/ko/more-topics/24-how-tex-macros-actually-work-part-6.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/more-topics/22-how-tex-macros-actually-work-part-4.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.
