> 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/21-how-tex-macros-actually-work-part-3.md).

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

[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)

## 잠시 멈출 시간!

이 이야기의 다음 부분으로 넘어가기 전에 복습이 필요합니다. 우리가 어디로 가고 있는지 다시 떠올리고 생각을 정리해 핵심 아이디어가 모두 제자리에 있는지 확인해야 합니다. 다시 한 번 말하자면, 우리의 작업 예제는 TeX가 다음을 포함한 텍스트 한 줄을 읽었다는 가정에 기반합니다 `Hello World \jobname` 그리고 TeX가 이것을 조판하여 문단을 만들고 있다는 점입니다.

### 궁극적인 목표

우리의 목표는 TeX 매크로의 본질과 그것이 어떻게 작동하는지에 대한 더 나은(더 깊은) 이해를 발전시키는 것입니다. 그러나 그에 이르기 위해서는 먼저 TeX가 입력 파일을 어떻게 읽고 그 안의 문자를 어떻게 처리하는지 이해해야 합니다. 지금까지 다룬 주제의 요약은 다음과 같습니다.

* TeX는 입력의 각 문자를 읽어 들이(스캔)며, 각 문자마다 TeX에는 두 가지 정보가 있습니다:
* **문자 코드**: 그 문자를 식별하는 데 사용되는 정수입니다. 예를 들어 .tex 입력 파일에 저장될 때처럼요;
* **범주 코드**: TeX 내부에 있는 또 다른 정수로, 입력에서 읽어 들인 각 문자에 의미를 부여하는 데 사용합니다.
* TeX가 문자를 읽어 들이는 즉시, 각 문자의 범주 코드(category code)는 *영구적으로* 문자 토큰을 생성함으로써 해당 개별 문자와 연결됩니다:
* TeX는 문자 코드와 대응하는 범주 코드를 문자 토큰이라고 하는 정수 하나로 “묶는” 간단한 공식을 사용합니다.
* TeX가 아직 *읽어 들이지 않은* 문자에 대해 다른 범주 코드를 부여하면, 변경하고 싶은 동작을 가진 문자의 범주 코드를 바꾸어 그 문자를 TeX가 다루는 방식을 수정할 수 있습니다.
* 범주 코드의 재정의(재매핑)는 TeX의 원시 명령 `\catcode` 명령을 사용해.
* TeX가 범주 코드 0을 보면 특별한 스캐닝 모드로 전환하여 명령을 찾기 시작합니다. 즉, (잠재적으로) 여러 글자로 이루어진 *제어 단어* 또는 한 글자짜리 *제어 기호*.

지금까지 우리는 TeX의 입력 스캔 과정을 살펴보며, 입력의 개별 문자를 식별하고 각 문자의 범주 코드를 이용해 다음에 무엇을 할지 알아냈습니다. 어떤 문자들은 조판을 위한 평범한 텍스트 항목일 뿐이지만(예: 범주 코드 11), 공백 문자(범주 코드 10)와 이스케이프 문자(범주 코드 0)도 보았습니다. 간결하게 하기 위해 아직 다루지 않은 다른 범주 코드도 있습니다. 예를 들어 범주 코드 1(“그룹 시작”, 예: `{`), 범주 코드 2(“그룹 끝”, 예: `}`) 및 기타 등이 있습니다. 각 범주 코드는 TeX의 입력 스캔과 그 후 TeX 내부의 소프트웨어 프로세스/알고리즘에 의한 후속 처리에서 고유한 역할을 합니다.

### 토큰: 간단한 복습

“토큰”이라는 개념은 TeX가 작동하는 방식의 핵심입니다. TeX 관련 서적, 기사, 온라인 커뮤니티 전반에서 “토큰”이 언급되거나 참조되는 것을 보게 될 것이므로, 이 주제를 간단히 복습해 둘 가치가 있습니다. 더 자세한 내용은 이전에 출판된 글에서 찾을 수 있습니다 ["TeX 토큰"이란 무엇일까요?](/latex/ko/in-depth-articles/53-what-is-a-tex-token.md)

우리는 이미 TeX가 문자 코드와 범주 코드를 하나의 복합 정수로 결합하여 입력 문자를 토큰으로 바꾼다는 것을 보았습니다. TeX는 명령에 대해서도 비슷한 일을 합니다. 명령의 이름을 사용하여 TeX는 *명령 토큰* 이라고 하는 정수를 계산합니다(이것은 더 자세히 살펴볼 것입니다). 안내로서, 토큰은 TeX가 입력에서 읽어 들인 항목을 “포장”하여 TeX 처리의 다음 단계로 보낼 준비를 하는 방식이라고 생각하면 됩니다. 문자든 명령이든 모든 항목을 하나의 숫자 표현으로 깔끔하게 감싸 두면, 이후 단계에서 처리하기가 더 쉬워집니다. 예를 들어 TeX가 나중에 사용할 수 있도록 입력의 일부를 저장하려 할 때, 예컨대 매크로 정의처럼 TeX는 복잡하더라도 매크로 정의를 정수들의 연속으로 저장하기만 하면 됩니다. 각 정수는 매크로 정의의 일부를 이루는(그 안에 포함된) 문자나 명령을 나타내는 토큰입니다.

## 그렇다면 다음은?

2부의 마지막 절에서 우리는 범주 코드 0을 가진 이스케이프 문자가 어떻게 TeX를 명령의 이름을 찾는 특별한 처리 모드로 전환하는지 보았습니다. 우리의 예제에서 TeX는 다음 문자열을 감지했습니다 `jobname` 그리고 우리는 2부를 TeX가 그 문자 문자열(명령의 이름)에 대해 “무언가를 할” 시점에서 마쳤습니다. 이 부분에서는 TeX가 다음에 무엇을 하는지 자세히 살펴봅니다.

TeX가 입력 파일 안의 특정 문자 시퀀스가 명령의 이름을 나타낸다는 것을 식별하면(여기, `jobname`) TeX는, 무엇을 하고 있는지에 따라, 그 명령을 실행해야 할 수도 있습니다. “해야 할 수도 있다”라고 말하는 이유는 TeX가 명령을 즉시 실행하려 하지 않는 경우도 있기 때문입니다. 예를 들어 매크로를 정의하고 있을 때(TeX가 토큰 목록을 만드는 중입니다)처럼요. 이러한 주제는 나중에 논의하겠지만, 여기서는 TeX가 문단을 조판하고 있고 *는*이런 상황에서는 다음을 실행해야 한다는 예를 계속 따라가겠습니다 `\jobname`.

### 문자열에서 명령 실행까지: 어떻게?

먼저 2부의 그림 5b를 다시 살펴보겠습니다. 여기서 TeX는 입력 안의 특정 문자 문자열이 명령의 이름을 이룬다는 것을 식별했습니다: `jobname`. 그림 5b는 TeX가 “내부 테이블을 확인해야 한다...”고 나와 있습니다. 그것이 무엇을 *실제로 의미할까요*?

![명령 이름을 찾는 TeX](/files/26ba40361e1bf21f9438aa7d61a47f425af1331e)

TeX가 “내부 테이블을 확인”하여 문자 문자열(예: `jobname`)에서 정확히 어떤 명령인지, 그리고 그것이 무엇을 의미하는지를 알아내는 방법에 대한 또 다른, 더 상세한 설명은 이전 기사에서 찾을 수 있습니다 ["TeX 토큰"이란 무엇일까요?](/latex/ko/in-depth-articles/53-what-is-a-tex-token.md) 여기서는 과도한 중복을 피하려고 하면서 핵심 아이디어를 요약해 보겠습니다.

비유부터 시작해 봅시다. 책을 읽다가 낯선 단어를 만났다고 가정해 보세요. 어떻게 하시겠습니까? 오늘날에는 거의 확실히 “구글을 검색하는 것”이겠지만, 더 옛날 방식을 선호한다고 가정해 봅시다. 즉, 단어 목록과 그 의미를 제공하는 사전을 꺼내는 것입니다. TeX에도 이와 유사한 메커니즘이 있습니다. TeX가 현재 알고 있는 모든 명령과 그 명령의 “의미”를 나열한 내부 “사전”이 있습니다. 여기서 “의미”란 그것이 어떤 종류의 명령인지, 무엇을 하는지, 그리고 TeX가 그 명령을 실행하는 데 필요할 수 있는 기타 정보가 무엇인지를 말합니다. 또한 “명령”이라는 용어에는 사용자가/TeX 프로그래머가 작성한 TeX/LaTeX 매크로와 [수백 개의 내장 원시 명령](/latex/ko/more-topics/46-tex-primitives-listed-by-tex-engine.md).

이라는 점도 기억하세요. 사전 비유를 계속해 보겠습니다. 인간 독자로서 단어의 의미를 찾을 때는 사전이 제공하는 알파벳순 목록을 이용해 사전을 검색합니다. 물론 TeX는 정확히 그렇게 작동하지 않습니다. 원래의 `jobname` 예제로 돌아가서, TeX는 어떻게 자신의 “사전”에서 `jobname`의 “의미”를 찾을까요? 그리고 그 “의미”는 TeX에 실제로 무엇을 제공할까요?

TeX가 알고 있는 모든 명령을 내부의 “알파벳순 목록”으로 제공하는 대신, 조금 다른 일을 합니다. TeX는 명령 이름에 들어 있는 문자들의 전체 시퀀스를 그것을 식별(표현)하는 데 사용될 하나의 정수로 변환합니다. 내부적으로 TeX는 알려진 모든 명령의 큰 “사전”을 유지하며, 그 안에 *정수* 를 명령 이름에서 계산하여 저장합니다. 주의할 점은 그 사전이 실제 명령 이름 자체를 글자들의 시퀀스(이를 *문자열*)로 저장하지는 않는다는 것입니다. TeX는 이 사전을 모든 내장 명령(원시 명령)에 사용하며, *및* 사용자가 만든 모든 매크로(명령)의 세부 정보도 저장하는 데 사용합니다. 즉, 매크로의 이름은 정수로 바뀌고 그 정수는 TeX의 사전 안에 “등록”됩니다.

TeX가 입력에서 사용된 명령을 감지할 때마다 그 명령에 대해 무언가를 알아야 하면, 명령 이름에 있는 문자들의 시퀀스를 “동등한” 정수로 변환한 다음 그 정수를 사용해 자신의 “큰 사전”에서 해당 명령을 찾습니다. 프로그래밍에 익숙한 분들은 TeX가 이러한 변환을 위해 [해시 함수](https://en.wikipedia.org/wiki/Hash_function) 의 한 형태를 사용한다는 점을 알아두면 좋습니다.

![해시 함수 도식](/files/68558fe8682d800eeaa11312cfdbda4f5f895d7d)

### 그림 6: 문자에서 명령 의미까지

다음 그림은 TeX가 문자 문자열을 동등한 정수로 변환하는 동안 명령이 거치는 여정을 보여줍니다. 그 정수는 **curcs**라고 불리며, 그 정수를 사용해 TeX의 “큰 사전”에서 명령의 의미를 찾아냅니다. 그 조회의 결과는 두 가지 정보, 즉 두 정수 **curcmd** 및 **curchr**라고 하는 두 정수이며, TeX는 이것을 사용해 명령이 정확히 무엇을 하는지, 그리고 이후 어떻게 실행할지를 알아낼 수 있습니다.

![문자 문자열을 동등한 정수로 변환하여 명령의 의미를 찾는 TeX](/files/a3ebd29d5e383ec77ff65c08b08288d90eaa5ff1)

내부적으로 TeX는 다음과 같은 변수를 유지합니다. **curcs** (**cur**rent **c**ontrol **s**equence)는 TeX가 현재 작업 중인 명령의 정수 값을 저장하는 데 사용됩니다. 즉, **curcs** 명령 이름에서 계산된 정수를 저장합니다. 그렇다고 이야기가 끝난 것은 아닙니다. 한 가지 더 있습니다. TeX가 방금 명령이 아니라 문자를 읽어 처리했다면, **curcs** 를 0으로 설정하여 마지막으로 읽어 들인 것이 명령이 아니라 문자였음을 기억합니다.

### TeX에게 명령이 의미하는 것

TeX 엔진이 제공하는 [내장 명령 집합](/latex/ko/more-topics/46-tex-primitives-listed-by-tex-engine.md) 을 살펴보면 그중 일부 명령이 서로 밀접하게 관련되어 있음을 알 수 있습니다. 즉, 비슷한 작업을 수행합니다. 예를 들어 모든 TeX 엔진이 매크로를 정의(생성)하는 데 사용하는 원시 명령이 4개 있습니다: `\def`, `\gdef`, `\edef`, `\xdef`. 이 4개의 명령은 모두 매크로를 정의하지만, 물론 각각 약간씩 다르게 합니다. 프로그래밍 관점에서 생각해 보면, 여기에는 대체로 같은 일을 하는 4개의 매크로 정의 명령이 있지만, 각각의 동작을 고려하려면 그중에서 하나를 선택해야 합니다.

이를 처리하기 위해 TeX는 모든 명령에 두 값을 할당하며, TeX는 이 두 값을 명령의 “의미”(역할/하는 일)로 이해합니다. 이 두 값은 TeX 내부, 소프트웨어 깊숙한 곳에 있으며 사용자에게는 접근할 수 없는 “내부 기계장치”의 일부입니다. 내장 원시 명령이든 사용자가 정의한 명령이든 모든 TeX 명령에는 두 값이 할당되며, TeX에게 그것이 의미하는 것, 즉 그 동작을 정의/분류합니다. TeX가 “큰 사전”을 사용해 명령을 찾을 때, 다음의 두 가지 중요한 정보를 발견합니다:

* **명령 코드**: 일종의 “일반 분류”로, 그것이 어떤 “유형”의 명령인지 나타냅니다. 예를 들어 “매크로 정의” 명령(다음 중 하나 `\def`, `\gdef`, `\edef`, `\xdef`); “상자 만들기” 명령(다음 중 하나 `\hbox`, `\vbox` 또는 `\vcenter` ) 등, TeX 엔진이 지원하는 수백 개의 명령에 대해 마찬가지입니다. 매크로(사용자 정의 명령)에도 명령 코드가 할당됩니다.
* **명령 수정자**: 이것은 TeX에 명령에 대한 구체적인 정보를 제공하는 보조 정보입니다. 매크로(사용자 정의 명령)에도 명령 수정자가 할당되지만, 매크로에서는 명령 수정자가 원시 명령에서와는 약간 다른 역할을 합니다(매크로의 경우 명령 수정자는 매크로 정의가 메모리의 어디에 저장되어 있는지를 나타냅니다).

이 둘을 합치면 명령 코드와 명령 수정자가 각 명령을 고유하게 식별합니다. 여기에는 Knuth의 원래 TeX 소프트웨어에서 사용된 매크로 정의 명령의 명령 코드와 명령 수정자가 나와 있습니다. 다른 TeX 엔진은 다른 값을 사용할 수 있지만, 정확히 같은 원리를 따릅니다:

|         |                                                   |                                                    |
| ------- | ------------------------------------------------- | -------------------------------------------------- |
| **명령**  | <p><strong>명령</strong><br><strong>코드</strong></p> | <p><strong>명령</strong><br><strong>수정자</strong></p> |
| `\def`  | 97                                                | 0                                                  |
| `\gdef` | 97                                                | 1                                                  |
| `\edef` | 97                                                | 2                                                  |
| `\xdef` | 97                                                | 3                                                  |

### 복습: 이 모든 변수/값을 이해하기

이 시점에서는 값, 변수, 명령 값과 온갖 세부 정보에 관한 정보가 너무 많아 쉽게 혼란스러워질 수 있습니다. 그러니 우리가 알고 있는 것을 정리해 봅시다. TeX가 입력에서 무언가를 읽으면 그것은 문자이거나 명령입니다. TeX가 입력에서 무언가를 읽을 때마다 방금 읽은(스캔한) 것에 대한 정보를 저장해야 합니다:

* 수직 **문자**: 문자 코드와 범주 코드를 기록해야 합니다. 또한 TeX가 그 값들을 사용해 계산한 토큰 값도 만들어 저장해야 합니다.
* 수직 **명령**: TeX는 명령 이름에서 계산한 숫자 대응값 **curcs**를 알아야 합니다. 또한 TeX의 “사전”에서 명령을 찾아 얻은 “의미”, 즉 명령 코드와 명령 수정자도 저장해야 할 수 있습니다. 이 외에도 TeX는 이 명령을 나타내는 토큰 값을 계산해야 합니다.

맞습니다, 혼란스럽습니다. 변수와 토큰 개념이 많이 떠다니니 이를 정리해 봅시다.

내부적으로 TeX는 TeX가 방금 읽어 들인(또는 현재 “작업 중인”) 최신 항목에 대한 정보를 저장하기 위해 네 개의 전역 변수를 사용합니다. 이 변수들을 자세히 논의하지는 않겠지만, 그 존재를 아는 것은 실제로 무슨 일이 일어나는지 이해하는 데 약간의 배경을 제공합니다:

* **curcmd**: (current command) 정수 변수입니다. 이것은 저장하는 데 사용됩니다 *현재 명령* 값, 즉 처리 중인 명령의 *또는* 현재 *범주 코드* 를 저장합니다.
* **curchr**: (current character) 정수 변수이지만, 무엇을 저장하는지는 TeX가 입력에서 방금 무엇을 읽었는지에 따라 달라집니다:
* **문자**: 가장 최근에 읽어 들인 항목이 문자라면, **curchr** 현재 *문자 코드*.
* **명령을 사용합니다**: 가장 최근에 읽어 들인 항목이 명령이라면, **curchr** 를 저장합니다. *명령 수정자*: TeX가 다음/이전 **curcmd**를 지원/명확히 하기 위해 사용하는 부가 정보입니다. 왜냐하면 위에서 보았듯이 일부 명령은 같은 값을 공유하기 때문입니다. **curcmd**
* **curcs**: (current control sequence) 명령 이름의 문자 문자열에서 계산된 값을 저장하는 정수 변수입니다. **curcs** = 0: 마지막으로 읽은 항목이 개별 문자이고 제어 시퀀스(명령 이름)가 아니었던 경우;
* **curtok**: (current token) 현재 토큰의 값을 보관하는 정수 변수로, 명령 토큰이거나 문자 토큰입니다.

위 정보를 표로 나타내면 다음과 같습니다:

|                          |                                                                                                                                                                     |                                                                                                                   |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------- |
| **TeX 내부에서 사용되는 전역 변수:** | **TeX가 문자를 스캔할 때:**                                                                                                                                                 | **TeX가 명령을 스캔할 때:**                                                                                               |
| **curcmd**               | 현재 문자의 범주 코드를 저장합니다                                                                                                                                                 | 명령 코드를 저장합니다 *명령 코드*—현재 명령의 “유형”을 식별합니다                                                                           |
| **curchr**               | 현재 문자의 문자 코드를 저장합니다                                                                                                                                                 | 보조 데이터(이를 *명령 수정자*명령 수정자라고 함)를 저장하며, 이는 현재 명령에 대한 추가 정보를 제공합니다                                                    |
| **curcs**                | 0                                                                                                                                                                   | 명령 이름에 있는 문자 문자열을 사용해 (해시 함수로) 계산된 0이 아닌 양의 정수입니다. 이것은 TeX의 “사전”에 접근해 현재 명령의 의미를 찾는 데 사용되며, 명령 코드와 명령 수정자를 가져옵니다. |
| **curtok**               | 8비트 TeX 엔진의 경우, *문자 토큰* 는 다음 공식으로 계산됩니다: $$\text{curtok}=256\times \text{curcmd} + \text{curchr}$$ 여기서 $$\text{curcmd}$$ 는 문자의 범주 코드이고 $$\text{curchr}$$ 는 문자 코드입니다 | 8비트 TeX 엔진의 경우, *명령 토큰* 는 다음 공식으로 계산됩니다: $$\text{curtok}=4095 + \text{curcs}$$                                    |

### 현재 토큰에 대한 추가 메모

문자의 경우 가능한 최대 토큰 값은 가장 큰 범주 코드(15)와 가장 큰 문자 코드(8비트 TeX 엔진의 경우 255)를 사용하여 얻습니다. 이론적으로(8비트 TeX 엔진의 경우) 최대 문자 토큰 값 $$\text{curtok}\_{\text{max}}$$는 다음과 같습니다:

$$\text{curtok}\_{\text{max}}= 256\times 15 + 255 = 4095$$

여기서 “이론적으로”라고 하는 이유는 범주 코드 15가 “잘못된 문자”를 나타내는 데 사용되기 때문입니다. 이는 TeX가 오류를 생성하게 합니다. 잘못된 문자는 TeX의 입력 스캔 과정을 결코 통과하지 못하므로 문자 토큰이 되지 않습니다.

명령의 경우 현재 토큰($$\text{curtok}$$)은 $$\text{curtok}=4095 + \text{curcs}$$ 에서 계산되지만, 명령의 경우 $$\text{curcs}$$ 는 *항상* 는 0이 아니므로, TeX는 토큰이 무엇을 나타내는지 쉽게 판별할 수 있습니다:

* 만약 $$\text{curtok} > 4095$$ 그렇다면 명령 토큰이고;
* 만약 $$\text{curtok} < 4095$$ 문자 토큰입니다.

결국 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)


---

# 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/21-how-tex-macros-actually-work-part-3.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.
