> 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/54-what-is-a-tex-token-list.md).

# TeX 토큰 리스트란 무엇인가

## 그렇다면, "TeX 토큰 목록"이란 정확히 무엇일까요?

이 [이전 글에서](/latex/ko/in-depth-articles/53-what-is-a-tex-token.md)—이것도 이 [저수준 TeX 관련 사항 시리즈의 일부입니다—](/latex/ko/in-depth-articles/01-a-new-series-of-articles-tex-tokens-and-related-concepts-but-why-and-how.md)—에서 TeX가 당신의 `.tex` 파일을 스캔해 새 토큰을 생성하는 과정을 살펴보았습니다. 즉, TeX 토큰의 근본적인 성질과 TeX가 그것들을 만드는 방법을 검토했습니다(참조 ["TeX 토큰"이란 무엇일까요?](/latex/ko/in-depth-articles/53-what-is-a-tex-token.md)).

이 후속 글에서는 *토큰 목록*들을 살펴봅니다: 그것들은 무엇이며, TeX 엔진은 어떻게 그것들을 생성/사용하는가. 토큰 목록을 이해하는 것은 까다로울 수 있는데, 왜냐하면 그것들은 TeX 내부 깊숙한 곳에 저장되기 때문입니다. 그런 세부 사항은 사용자에게 숨겨져 있습니다—물론, LuaTeX로 더 고급 프로그래밍을 하면 오늘날에는 항상 그런 것은 아닙니다. 하지만 지금은, 토큰 목록을 TeX가 일련의 정수값을 저장하는 방식이라고 생각해도 됩니다. 여기서 각 정수는 TeX가 입력 파일에서 읽은 문자나 명령에서 파생된 토큰입니다.

토큰 목록은 TeX의 내부 동작에서 중추적인 역할을 하며, 종종 다음과 같은 다소 놀라운 방식으로 쓰입니다. `\uppercase` 및 `\lowercase`. 토큰 목록의 특히 중요한 용도 중 하나는 매크로를 저장하고 실행하는 것인데, 이 주제는 이 시리즈의 향후 글에서 자세히 살펴보겠습니다.

### TeX는 파일과 토큰 목록에서 입력을 받습니다

TeX 엔진에는 세 가지 입력 स्रोत가 있습니다—그중 두 가지는 아마 아실 겁니다:

* 디스크에 저장된 물리적 텍스트 파일;
* 사용자가 터미널(명령행)에 입력하는 텍스트;

하지만 세 번째로 입력을 읽거나 얻는 방법도 있습니다: 토큰 목록!

토큰 목록은 사실상 TeX가 동작의 일부로 사용하는 내부 데이터 저장 장치입니다. TeX의 토큰 목록은 이전에 생성된 토큰을 위한 “저장소” 역할을 하므로, 그것들을 또 다른 입력 स्रोत으로 재사용할 수 있어야 논리적입니다. 다음 입력을 특정 토큰 목록에서 받아야 할 때(또는 TeX가 그렇게 하도록 지시받을 때), TeX는 일시적으로 물리적 파일에서 입력을 읽는 것(즉, *새 토큰을 생성하는 것*)을 멈추고 *기존 토큰*을 입력으로 받는 것으로 전환합니다: 토큰 목록이 저장된 메모리 내부 위치에서 말입니다. 분명히 토큰 목록에서는 토큰의 스캔 + 생성 과정이 이미 일어났으므로, TeX는 목록의 각 토큰을 보고 각각에 대해 무엇을 할지 결정하기만 하면 됩니다.

간단한 예로, 저수준(TeX 원시 명령) `\toks` 명령은 TeX가 나중에 재사용할 수 있도록 메모리에 저장하는 토큰 목록을 만들 수 있게 해줍니다:

```latex
\toks100={Hello}
```

그 토큰들을 다시 가져오려면(즉, TeX가 그것들을 다음 입력 स्रोत으로 취급하도록 하려면) 다음과 같은 명령을 내리면 됩니다.

```latex
\the\toks100
```

그러면 TeX는 입력 파일에서 새 토큰을 만드는 것에서, 해당 토큰들(에 의해 생성된 `\toks` )이 저장된 곳—소위 *토큰 레지스터* —로부터 다음 입력을 가져오는 것으로 전환합니다. 이것은 TeX가 아는 내부 메모리 위치일 뿐입니다(여기서는 100번 레지스터입니다).

또한 여러 TeX 명령은 토큰 목록을 내부적으로 즉석에서 생성할 수 있습니다. 한 예가 `\jobname` 명령인데, 이것은 TeX가 처리 중인 메인 파일 이름의 각 문자마다 하나씩, 일련의 문자 토큰을 생성합니다. 또 다른 예는 `\string` 명령입니다. 예를 들어

```latex
\string\mymacro
```

는 이름 `\mymacro`의 각 글자에 대해 문자 토큰들을 생성합니다—초기의 `\` 문자도 포함해서요. 이 글의 끝부분에서 몇 가지 “토큰 생성 명령”을 더 자세히 살펴보겠습니다.

## 토큰 목록: 비유로 설명하기

프로그래밍 배경이나 컴퓨터 과학 지식이 없다면, “토큰 목록”은 다소 अस्पष्ट하고 어쩌면 조금 혼란스러운 개념일 수 있습니다. 하지만 TeX/LaTeX 매크로를 능숙하게 작성하고 싶다면, TeX 토큰, 토큰 목록, 카테고리 코드(`\catcode`) 같은 주제들을 잘 이해하는 것이 매우 유용할 것입니다.

이 섹션에서는 TeX 토큰 목록의 핵심 아이디어/원리를 설명하고 보여주기 위해 비유를 사용하겠습니다: TeX가 메모리에 토큰을 어떻게 저장하는지 말입니다. 토큰 목록은 *근본적인* TeX의 측면이므로, 조금 더 자세히 이해할 가치가 있습니다.

### 토큰 목록: 비유(사고 실험)

TeX 토큰 목록을 이해하기 위한 기반을 마련하려고 “사고 실험”을 해보겠습니다. 수백 개의 통처럼 큰 수의 저장 용기에 접근할 수 있다고 상상해 보세요—이 사고 실험의 용기를 설명할 때는 “상자”라는 용어를 사용할 수 없습니다. 왜냐하면 TeX에서 “box”는 물론 아주 특정한 의미를 가지며, 여기서의 논의와는 전혀 관련이 없기 때문입니다. 그래서 우리는 우리의 용기를 “Tins”라고 부르겠습니다. 각 Tin은:

* 외부에 고유한 식별 번호가 인쇄되어 있고;
* (내부적으로) 두 개의 칸으로 나뉘어 있습니다.

그 두 칸은 다음과 같이 설계되어 있습니다:

* 왼쪽 칸에는 Tin에 넣고 싶은 항목이 들어갑니다;
* 오른쪽 칸에는 종이 한 장을 넣도록 되어 있으며, 그 종이에는 다른 Tin의 번호 하나를 적을 수 있습니다.

![테스트](/files/2d7452cce0a21474ecbc9ad2a37eebfa8143f68b)

예를 들어 5개의 항목이 있는 컬렉션이 있고, 그 컬렉션을 이 Tin들 안에 저장하고 싶다고 해봅시다. 그런데 안타깝게도 각 Tin은 저장하려는 종류의 항목을 1개만 담을 수 있습니다.

간단히 하기 위해, 우리가 5개의 색색의 원을 저장하려 한다고 가정해 봅시다:

![{{{alt}}}](/files/6be112a6097671e93beca8fa0dfd48a34d7be292)

더욱이, 저장 시스템(Tin)에서 그 항목들을 다시 꺼내려 할 때, 그 항목들은 *반드시* 특정한 순서—저장된 순서—대로 찾아내야 합니다: 그 순서는 보존되어야 합니다. 어떻게 이를 달성할 수 있을까요?

다음과 같은 점을 활용할 수 있습니다. 각 Tin은:

* 외부에 고유한 식별 번호가 붙어 있고;
* 칸이 2개 있으며—그중 1개만 항목을 담는 데 사용할 것이고, 다른 칸에는 다른 Tin의 번호가 적힌 종이 한 장이 들어갑니다.

모든 Tin이 비어 있다고 가정하겠습니다—하지만 특정 Tin을 열어 비어 있는지 확인하는 것을 막을 수는 없습니다. 비어 있지 않다면, 빈 Tin을 찾을 때까지 다음 Tin을 계속 확인하면 됩니다.

우리가 할 수 있는 일은 다음과 같습니다. 첫 번째 항목(짙은 초록색 원)을 Tin 중 하나(예: Tin 124)에 넣고, 그 첫 Tin의 번호를 적어 둡니다—첫 Tin의 번호가 무엇인지는 중요하지 않습니다. 중요한 것은 그 번호를 어딘가에 적어 두고 나중에 다시 사용할 수 있도록 저장하는 것입니다.

![{{{alt}}}](/files/e13d012bc30ee0d7150c0a7cb21d7eaccfecf21f)

두 번째 Tin을 찾습니다—어떤 Tin 번호든 됩니다(예: Tin 432)—그리고 그 번호를 적습니다. 그 두 번째 Tin(432)의 번호를 종이에 적고 그 메모를 *첫 번째 Tin 안에* (Tin 124) 넣습니다. 두 번째 항목(연한 초록색 원)을 두 번째 Tin에 넣습니다. 그러면 현재 상황은 다음과 같습니다:

* 종이에 적힌 메모—Tin 안에 저장되어 있지 않음—에는 첫 번째 Tin이 124번이라고 적혀 있습니다(거기에 우리의 첫 항목이 들어 있습니다);
* Tin 124 안에는 다음 항목이 Tin 432에 있다는 또 다른 메모를 넣었습니다.

본질적으로 우리는 *연결했습니다* 우리의 첫 두 Tin을: 어디서 시작해야 하는지(Tin 124), 그리고 Tin 124 안의 메모가 다음 항목이 들어 있는 Tin(Tin 432)을 알려준다는 것을 알게 된 것입니다.

![{{{alt}}}](/files/726126454e7582983a872fc992d114c673f7b6f3)

그다음 세 번째 Tin을 찾아 번호(예: Tin 543)를 종이에 적고, 그것을 *두 번째* Tin(번호 432)에 넣습니다. 그런 다음 세 번째 항목(빨간 원)을 세 번째 Tin에 넣습니다.

이제 우리는 다음 순서로 세 Tin을 연결했습니다: 시작점인 Tin 124(짙은 초록색 원) → Tin 432(연한 초록색 원)→ Tin 543(빨간 원) →…

![{{{alt}}}](/files/f1727af6baa6553e8f3853b4982c84ffaf278534)

마지막 두 항목(연한 파란색과 짙은 파란색 원)에 대해서도 Tin 213(연한 파란색 원)과 Tin 102(짙은 파란색 원)를 사용해 이 과정을 반복합니다.

![{{{alt}}}](/files/aa415c1a65de9e47f9ac72da7df4b7e13116cf70)

이제 5개의 Tin이 모두(각 Tin의 숫자 식별자를 사용하여) 서로 연결되었고, 각 Tin을 차례로 방문하여 우리의 항목을 꺼내고, 다음 항목이 들어 있는 Tin을 알려주는 메모를 보면, 저장된 모든 항목을—올바른 순서로—다시 꺼낼 수 있습니다.

### 우리 목록의 마지막 항목(Tin 102)은 어떻게 해야 할까요?

왜 이것을 특히 걱정해야 할까요? 지금까지 우리는 각 항목을 하나의 Tin에 저장하고, 다음 항목이 들어 있는 Tin을 알려주는 메모를 함께 넣었습니다. 그렇다면 우리 목록의 마지막 항목에 대해서는 그 메모에 무엇이라고 적어야 할까요—다음 Tin이 없으니까요.

마지막 항목(Tin)에 도달하면, 이 Tin(마지막 항목을 담고 있는)이 우리 목록의 최종 항목임이 분명해야 합니다—더 찾을 Tin은 없으므로 다른 Tin을 찾을 필요가 없습니다. 이를 위한 한 가지 방법은 마지막 Tin(102) 안에 “특수한” Tin 번호를 넣는 것입니다. 실제 Tin 번호가 아닌 고유한 번호만 선택한다면 원하는 어떤 번호든 사용할 수 있습니다. 예를 들어 “Tin -1”, “Tin 0”처럼요. 중요한 것은 “Tin -1”이나 “Tin 0” 등이 즉시 검색을 멈추라는 신호가 되기만 하면 된다는 점입니다. 이것이 마지막이므로 더 이상 꺼낼 항목이 없기 때문입니다.

### “항목”과 “Tin”에서 토큰과 TeX로

이제 우리의 비유에서 TeX의 현실에 더 가까운 설명으로 넘어가야 합니다. 우선, 가상의 Tin 안에 서로 다른 색의 원을 저장하는 대신, 그 Tin들이 TeX 토큰—즉, 단순한 정수—를 저장한다고 생각하면 됩니다. 이것은 비유를 소프트웨어(TeX)의 영역으로 옮길 때 더 쉬운 부분입니다. 하지만 “칸”이 있는 물리적인 번호표 Tin에 대응하는 소프트웨어 요소는 무엇일까요?

프로그래밍 개념으로 너무 멀리 들어가고 싶지는 않지만, 우리의 “Tin”은 편리한 저장 단위로 “포장된” 몇 바이트의 컴퓨터 메모리를 나타낸다고 생각할 수 있습니다. 비유에서 각 Tin의 숫자 식별자는 컴퓨터 메모리 안에서 각 작은 저장 묶음이 위치한 자리라고 볼 수 있습니다. TeX 자체에서는 이런 작은 저장 묶음을 “memory words”라고 부르는데, 이 용어는 TeX가 만들어진 시기/시대(1970년대)를 반영합니다. 이 “memory words”는 TeX 내부에서 사용되는 기본 구성 요소이지만, 여기서 더 자세히 탐구할 필요는 없습니다—더 자세한 내용을 원하는 분은 다음에 대한 글을 참고하면 됩니다. [저자의 개인 블로그](http://www.readytext.co.uk/?p=3537).

컴퓨터 프로그래밍 용어로 말하면, 우리가 지금 논의한 것은 [*연결 리스트*](https://en.wikipedia.org/wiki/Linked_list)라고 합니다: TeX 토큰 목록은 다음과 같은 TeX의 저장 컨테이너로 구성된 연결 리스트입니다. *memory words* 각 memory word는 다음을 저장하는 데 사용할 수 있습니다:

* 하나의 *값*: 토큰의 값(정수);
* 하나의 *링크*: 목록의 다음 토큰을 담고 있는 다음 memory word의 메모리 위치.

## TeX는 어디에서 토큰 목록을 사용할까요?

모든 곳에서요! TeX/LaTeX 매크로 정의(예: LaTeX 명령)는 (약간 특수화된) 형태의 토큰 목록으로 저장되기 때문입니다—특수화되었다는 뜻은 표준적인 토큰 목록에서는 보이지 않는 토큰들(매크로 매개변수 일치와 관련된 것들 등)을 포함한다는 것입니다. 이 부분은 걱정하지 마세요. 자세한 것은 다음 글에서 다루겠습니다.

### 매크로 예시

매크로는 세 부분으로 이루어진다고 생각할 수 있습니다:

```
\def\<매크로 이름><매개변수 텍스트>{<대체 텍스트>}
```

다음 대신 `\def` 을 사용할 수도 있고 `\edef`, `\gdef` 또는 `\xdef`.

**LaTeX 사용자에게 드리는 참고**: 여기서는 원시적인 저수준 TeX 명령(이른바 *원시 명령*)을 사용하여 매크로를 정의하고 있습니다. LaTeX 사용자라면 LaTeX의 `\newcommand` 를 통해 매크로를 만드는 방식(그 자체도 매크로입니다)에 더 익숙할 것입니다.

TeX에게 매크로를 생성(정의)하라고 하면, `<매크로 이름>` 그리고 하나의 *토큰 목록* 을 나타내는 토큰을 만들고, 그것이 결합된 `<매개변수 텍스트>` 및 `<대체 텍스트>`를 나타내는 토큰 목록과 연결되도록 아주 신중하게 모든 것을 저장합니다. `<매크로 이름>` 을 나타내는 토큰은 그 정의를 나타내는 토큰 목록과 연결됩니다(`<매개변수 텍스트>` 및 `<대체 텍스트>`).

예를 들어, 다음과 같이 정의하면 `\mymacro` 처럼:

```latex
\def\mymacro abc #1 defz{I typed "#1"!}
```

그 구성 요소는 다음과 같습니다:

* `<매크로 이름>` = `mymacro`
* `<매개변수 텍스트>` = `abc #1 defz`
* `<대체 텍스트>` = `I typed "#1"!`

예를 들어, 다음과 같이 호출할 수 있습니다. `\mymacro` 처럼:

```latex
\mymacro abc THIS TEXT defz
```

그 결과 `I typed "THIS TEXT"!` 가 조판됩니다— `abc` 및 `defz` 는 *작동하지* 조판되지 않습니다. `abc` 및 `defz` 는 다음을 위해 사용되는 문자 토큰들의 연속입니다. *구분* 매크로 매개변수를 `#1` 그리고 TeX가 매크로 호출을 성공적으로 처리하면 흡수되어 버려집니다.

매크로를 정의할 때 `\mymacro`에 포함된 토큰 패턴은 TeX가 다음을 알아내는 데 사용할 수 있는 “템플릿” 역할을 합니다:

* 입력 중 어느 토큰이 구분자 토큰인지;
* 입력 중 어느 토큰이 실제로 매크로의 매개변수를 구성하는지(여기서는, `#1` 로 사용하는 것); `\mymacro`).

호출할 때는 `\mymacro` 를 다음과 함께 `<매개변수 텍스트>` 정의에 사용된 것과 동일한 구분자를 포함해야 합니다—문자 구분자를 사용할 때는 카테고리 코드도 동일해야 합니다. 호출에 사용된 구분자가 `<매개변수 텍스트>` 에 사용된 구분자 `\mymacro` 와 정의에 사용된 것(메모리에 저장된 “템플릿”)이 다르면, TeX는 상당히 혼란스러워질 수 있습니다— `\mymacro` 를 처리하려 할 때 메모리에 저장해 둔 “템플릿”을 맞출 수 없게 됩니다.

TeX가 당신이 매크로를 호출하고 있다는 것을 보면 입력 텍스트를 스캔하여 새 토큰을 만들고, 토큰 단위로 그것들을 매크로 정의의 일부로 저장된 토큰 목록의 `<매개변수 텍스트>` 템플릿과 맞추려 합니다. 입력 텍스트에서 사용한 구분자가 “템플릿”에 저장된 토큰들과 일치하지 않는 토큰들의 연속을 만들면, TeX는 보통 오류를 발생시킵니다.

TeX는 매우 까다롭습니다—문자 토큰은 문자 코드와 카테고리 코드의 조합이라는 점을 기억하세요: 어떤 문자의 카테고리 코드를 바꾸면, 그 문자에서 파생되는 토큰 값도 달라집니다.

우리가 `z` 의 카테고리 코드를 예를 들어 12로 바꾸었다고 해봅시다—보통은 11입니다—그리고 이렇게 매크로를 호출해 봅니다:

```latex
\catcode`z=12
\mymacro abc THIS TEXT defz more text here...
```

이번에는 작동하지 않을 것입니다. 왜냐하면 `z` 의 카테고리 코드가 바뀌었기 때문입니다. 다음과 같은 오류가 나타날 것입니다:

```latex
Runaway argument?
THIS TEXT defz
! Paragraph ended before \mymacro was complete.
<to be read again>
\par
l.22
```

TeX가 `z` 에서 `defz` 를 읽고 스캔할 때, 그것이 `\mymacro`의 `<매개변수 텍스트>` 에 사용된 `z` 의 끝을 형성한다고 인식할 수 없습니다. 그 잘못된 `def` 를 보기 전까지는, `z` (카테고리 코드 12의) 것이 TeX의 스캔을 방해합니다. 우리가 `z` 를 *정의* `\mymacro`할 때 카테고리 코드가 11이었다고 가정하면: 그 결과 `\mymacro`의 정의의 일부로(즉, “템플릿”의 일부로) 256×11 + 122 = 2938이라는 토큰 값이 저장됩니다. 하지만 카테고리 코드 12에서는 `z` 는 이제 256×12 + 122 = 3194라는 토큰 값을 만들게 됩니다. 입력에서 읽힌 `z`의 토큰 값(3194)이 저장된 `z`-토큰과 일치하지 않으므로 `<매개변수 텍스트>` 토큰 목록 템플릿의 값 2938), TeX는 입력 스캔을 계속합니다. TeX는 매크로 뒤에 이어지는 텍스트(*more text here* ...)를 계속 스캔하여 추가 토큰을 찾고—저장된 템플릿을 입력에서 찾은 토큰들과 맞추려 합니다. 아마도 올바른 토큰 패턴을 찾지 못할 것이고, TeX가 입력을 “과도하게 읽어” 추가 토큰을 생성하면서 오류가 발생할 것입니다. 그 추가 토큰들은 이 시점에서 읽혔어서는 안 되었으며, 거의 확실하게 오류를 일으킬 것입니다.

이 부분은 나중 글에서 더 자세히 다루겠습니다.

## 토큰 목록의 다른 용도

토큰 목록을 생성/저장하는 데 쓰이는 다른 명령에는 다음이 있습니다:

```latex
\toks<n>={...}
\everypar={...}
\everymath={...}
\everydisplay={...}
\everyhbox={...}
\everyvbox={...}
\output={...}
\everyjob={...}
\everycr={...}
\errhelp={...}
```

이 각 명령은 중괄호 ‘{...}’ 안에 있는 문자와 명령들로부터 토큰 목록을 만들며, 그 토큰 목록은 특정한 상황에서 재사용되도록 의도되어 있습니다. 예를 들어, `\everypar={...}` 는 새 단락을 시작하기 바로 전에 TeX가 입력에 삽입하는 토큰 집합(토큰 목록)을 생성하고 저장합니다.

## 토큰 목록의 숨겨진 용도: 예시

이 마지막 섹션에서는 예상치 못한 방식으로 사용되는 토큰 목록의 실용적 예시들을 살펴보겠습니다.

### 예시 1: \uppercase{...} 및 \lowercase{....}—임시 토큰 목록

토큰 목록을 생성하는 명시적 명령 외에도, TeX가 어떤 특별한 처리를 수행하기 위해 숨겨진 임시 내부 토큰 목록을 생성하는 경우가 있습니다. TeX가 입력 문자/명령을 읽고 처리할 때 그것들은 토큰으로 바뀐다는 점을 기억하세요: 이것이 TeX 엔진이 다루는 기본 구성 요소입니다.

좋은 예가 다음 명령들입니다. `\uppercase{...}` 또는 `\lowercase{...}` 처음 접하면 그 동작이 다소 혼란스러울 수 있기 때문입니다. 그들이 무엇을 하고 있는지—TeX 내부 깊숙한 곳에서, 사용자에게는 보이지 않게—이해하면 그 동작을 훨씬 더 쉽게 파악할 수 있습니다.

간단한 문자 시퀀스를 대문자로 바꾸고 싶다고 해봅시다—예를 들어 abcde를 ABCDE로 바꾸는 것입니다. TeX의 `\uppercase` 명령:

```latex
\uppercase{abcde}
```

는 TeX가 `ABCDE`를 출력하게 만듭니다. 이제 이 간단한 문자 시퀀스를 나중에 사용하기 위해 저장하고 싶다고 가정해 봅시다—즉, 바로 출력하고 싶지 않으므로 데이터를 저장하는 TeX의 유일한 *내부* 메커니즘—외부(파일) 메커니즘이 아닌—을 사용해야 합니다: 토큰 목록을 사용하세요. 우리는 매크로를 만들거나 명시적인 토큰 목록 명령을 사용하여 이를 할 수 있습니다:

```latex
\toks100={abcde}
\def\mychars{abcde}
```

그런 다음 어느 시점에서 이 문자 시퀀스를 다시 사용하고 싶은데, 이번에는 대문자로 사용하고 싶다고 결정할 수 있습니다. 그래서 다음을 시도합니다.

```latex
\uppercase{\the\toks100}
```

및

```latex
\uppercase{\mychars}
```

하지만 안타깝게도 둘 다 작동하지 않습니다. 왜 그럴까요?

### 비밀 토큰 목록!

명령들이 `\uppercase{...}` `\lowercase{...}` 실제로 어떻게 작동하는지 이해하려면 TeX의 내부 구조를 들여다봐야 했고, 따라서 다음 설명은 그 작업에서 나온 것입니다.

TeX가 `\uppercase{<material>}` 또는 `\lowercase{<material>}` 를 감지하면, TeX가 가장 먼저 하는 일은 `<material>` 에서 (임시) 내부 토큰 목록을 만드는 것입니다. 이 `\uppercase{...}` 또는 `\lowercase{...}` 명령 뒤에 오는 ‘{’와 ‘}’ 사이에 들어 있는 내용이 그 대상입니다—그 임시 토큰 목록은 TeX 내부에만 존재합니다.

중요한 점이자 `\uppercase{<material>}` 및 `\lowercase{<material>}` 의 작동 방식을 이해하는 핵심은, `<material>` 에 포함된 어떤 명령이나 매크로도 *확장되고*아니라는 것입니다: TeX가 하는 일은 단지 `{...}`사이에 놓인 문자와 명령으로부터 토큰을 생성하는 것뿐입니다.  `\uppercase{<material>}` 또는 `\lowercase{<material>}` 동작 중에는

중괄호 안의 내용은 아무것도 실행되지 않고, 단지 토큰으로 바뀔 뿐입니다. `<material>` 이후 `{...}` 가운데 *문자* 가 (임시) 토큰 목록으로 변환되면, TeX는 그 목록의 모든 토큰을 다시 살펴보며 그것이 *토큰인지, 아니면* 명령 `\uppercase` 또는 `\lowercase` 토큰인지(토큰의 숫자 값을 사용하여) 검사합니다. TeX가 문자 토큰을 감지하면, 그 토큰을 수정하여 문자의 대소문자를 조정합니다(어느 쪽이

예를 들어, 다음과 같은 TeX 명령을 내리면 `\uppercase{abcde}` TeX는 `abcde` 로부터 문자 토큰만으로 이루어진 토큰 목록을 만들 것입니다: 모든 토큰이 조정되어 A, B, C, D, E를 나타내는 수정된 토큰들의 연속이 됩니다. 그 수정된 토큰들은 TeX의 입력 처리기로 다시 들어가고, 그 결과 `ABCDE` 가 조판됩니다. 하지만 우리가 문자 *를 매크로 안에*—예를 들어 `\def\mychars{abcde}`—저장해 두고 이를 이렇게 대문자로 바꾸려 하면:

```latex
\uppercase{\mychars}
```

그러면 실패하고, 예상과 달리 ABCDE가 아니라 abcde가 조판됩니다. 이후 문자들을 다음과 같은 토큰 목록에 저장하려고 하면 `\toks0={abcde}` 그리고 `을 하면` 다시 한 번, `\uppercase` 가 실패할 것입니다. 왜냐하면 토큰 목록이 `\uppercase`.

우리의 매크로 예로 돌아가서 보면, `\mychars`를 입력에서 감지한 뒤, TeX는 `\uppercase` 의 의미를 찾아 그것을 실행하고, `\uppercase` 을 `{\mychars}`로부터 임시 토큰 목록을 만듭니다. 분명히 그 임시 토큰 목록에는 문자 토큰이 아니라 우리의 매크로 명령 `\mychars`를 나타내는 토큰 하나만 들어 있습니다: 따라서 `\uppercase`을 실행하는 관점에서는 그 토큰은 무시됩니다—`\mychars` 는 문자 토큰을 나타내지 않기 때문입니다. 그러나 위에서 언급했듯이, `\uppercase` 가 작업을 마치면, ( `\uppercase`의 작용으로 만들어진) 임시 토큰 목록이 TeX의 전체 입력 처리(스캔) 메커니즘으로 다시 들어갑니다. TeX가 그 토큰 목록을 다시 읽으면, 우리의 `\mychars` 매크로를 나타내는 토큰을 감지하고, TeX는 그것을 실행(확장)하여 abcde를 조판하는 문자 시퀀스를 생성합니다—여전히 소문자인 이유는 그것들이 매크로 안에 “포장”되어 있어 `\uppercase`.

의 작용에서는 보이지 않았기 때문입니다. `\uppercase{...}` 또는 `\lowercase{...}`TeX가

### 이것을 어떻게 고칠 수 있을까요?

왜냐하면 `\uppercase{...}` 또는 `\lowercase{...}` 는 문자 토큰에 대해서만 작동하므로, 매크로 `\mychars` 안에 들어 있는 문자들을 (또는 `\toks` 레지스터 안에 들어 있는 문자들을) `\uppercase{...}` 또는 `\lowercase{...}` 가 작동하기 전에 “포장을 풀” 방법이 필요합니다. 여기서 “포장을 푼다”는 것은 실제로 TeX의 *확장*:

* 즉, TeX/LaTeX 명령을 그 *연속* 의 토큰으로 바꾸는 과정 *에서 그 명령이* (*예를 들어 매크로*) *로 이루어져 있는지를 알아내기 위한 과정입니다.* 또는
* 명령이 설계된 대로 *생성하는 토큰들의 연속을 만들어 내는 것. 토큰을 생성하는 명령의 한 예는*인데, 이는 처리 중인 메인 TeX 파일의 이름을 나타내는 문자 토큰들의 연속을 만들어 냅니다. `\jobname`, which produces a sequence of character tokens representing the name of the main TeX file being processed.

#### 더 낮은 수준의 마법: scantoks(..., ...)

여기서는 TeX 내부의 조금 더 어두운 구석을 파고드는 것이므로, 세부사항을 즐기지 않는다면 이 섹션은 무시해도 됩니다…

TeX가 입력 스트림에서 `\uppercase` 또는 `\lowercase` 를 감지하면, 내부 함수인 `scantoks(..., ...)` 을 실행합니다. 이 함수의 임무는 열린 ‘{’와 닫힌 ‘}’ 사이의 항목들을 사용하여 토큰 목록을 생성하는 것입니다—앞서 설명했듯이, 그 토큰 목록은 나중에 검토되어 필요한 경우 문자 대소문자를 바꾸기 위해 문자 토큰을 감지(그다음 조정)합니다. 주의해서 보면, 여기서 말하는 `scantoks(..., ...)` 는 TeX 엔진의 소스 코드에 내장된 내부 함수로서의 이름이지, 제어 시퀀스의 이름으로 말하는 것이 아닙니다.

그 작업의 일부로 `scantoks(..., ...)` 토큰 목록을 구성할 때 그것을 확장할지, 확장하지 않을지를 지시받을 수 있으며, 그리고 `\uppercase` 그리고 (`\lowercase`) 그것은 토큰을 확장하지 않는다: 그저 토큰을 만들고 토큰 목록에 넣을 뿐이다.

가장 먼저 해야 하는 일 중 하나는 `scantoks(..., ...)` 열린 ‘{’(또는 카테고리 코드 `\catcode` 1)의 문자를 확인하는 것이다. 이는 사용자가 문법 오류를 내고 여는 ‘{’(또는 카테고리 코드 1의 어떤 문자든)를 잊어버린 것은 아닌지 확인해야 하기 때문이다. 카테고리 코드 1을 가진 문자는 토큰화할 항목 목록의 시작을 구분하는 데 필요하다.

그리고 여기서 핵심은, 여는 ‘{’를 찾는 작업이 `scantoks(..., ...)` TeX의 확장 과정을 실행하게 만든다는 점이다. 즉, 다음 예제들이 작동한다:

```latex
\\let\\ob={
\\uppercase\\ob abcde}
\\def\\obb{\\ob}
\\uppercase\\obb xyz}
```

예를 들어 `\\obb`, 매크로인데, 이는 *확장 가능한 명령* 로 인식되며 TeX에 의해 적절히 확장된다( `scantoks(..., ...)` 함수를 통해) 여는 중괄호(카테고리 코드 1을 가진 어떤 문자든)를 찾는 과정에서이다. 이것이 의미하는 바는 “`\\expandafter` 트릭”을 사용해 매크로의 제약 속에 갇힌 문자들을 “풀어내는” 목표, 즉 확장하는 것을 달성할 수 있다는 것이다. 참고로 `\\expandafter` 또한 *확장 가능한 명령*, 따라서 TeX는 여기서 이를 동작시켜 여는 ‘{’(또는 카테고리 코드 1의 어떤 문자든)를 찾는 과정의 일부로서 그 작업을 수행하게 한다.

그러므로 다음과 같이 정의하면:

```latex
\toks0={abcde}
\def\mychars{abcde}
```

그리고 이렇게 하면:

```latex
\\uppercase\\expandafter{\\mychars}
\\uppercase\\expandafter{\\the\\toks0}
```

두 경우 모두 이제 ABCDE가 조판되는 것을 볼 수 있는데, 이는 `\\expandafter` 가 `\mychars` 및 `\\the\\toks0`의 “포장 해제”(확장)를 일으키기 때문이다. 둘 다 `\uppercase` 문자 토큰들의 흐름을 보게 되며, 이를 처리해 대소문자를 바꿀 수 있다.

### 예제 2: \\\string—더 많은 임시 토큰 목록

내부적으로 TeX는 `\string` 을 소위 “변환(convert)” 명령 중 하나로 분류한다: “텍스트로 변환” 작업을 수행하는 것이다.  `\string` 이 명령은 토큰을 사람이 읽을 수 있는 텍스트 버전으로 변환하도록 설계되어 있다—즉, 그 토큰이 원래 만들어진 사람이 읽을 수 있는 문자 문자열을 조판한다.

예를 들면 `\\string\\hello` 는 문자 \\\\, h, e, l, l, o를 포함하는 임시 토큰 목록을 만든다—그렇다, 맨 앞의 ‘\\\’까지 포함해서 말이다. 그 토큰 목록이 만들어지면 TeX가 그것을 다시 읽고 명령 “`\\hello`”가 조판된다—맞다, 올바른 글꼴을 선택하면 ‘\\\’까지 포함해서…

TeX가 보통은 스캐너를 자극해 명령 토큰을 만들게 하는 데 쓰이는 이스케이프 문자를 어떻게/왜 조판할 수 있는지 궁금할 수 있다: 왜 여기서는 그렇게 하지 않는가? 답은 카테고리 코드에 있다: 보통 ‘\\\’ 문자는 catcode 0(이스케이프 문자)이지만 `\string` 가 내부 토큰 목록을 생성할 때는 조금 다르게 동작한다. 문자 토큰 목록을 만들 때는 공백 문자에만 catcode 10을 할당하고 나머지 모든 문자에는 카테고리 코드 12를 할당한다—문자 토큰은 256 x catcode + ASCII 값으로 계산된다는 점을 떠올리자. 따라서 TeX가 `\string` 에서 생성된 `\\hello`, TeX *이스케이프 문자를 보지 못한다* 왜냐하면 ‘\\\’에 대한 토큰은 catcode 0이 아니라 12로 계산되었기 때문이다: TeX는 ‘\\\’를 그냥 일반 문자로 취급해 조판한다.

엄밀히 말하면, TeX는 입력에서 이스케이프 문자를 감지할 때 실제로 그 문자에 대한 토큰을 생성하지 않는다고 짚어 두는 편이 맞다. 카테고리 코드 0의 문자를 인식하면, 그 문자는 단지 제어 시퀀스 토큰을 생성하도록 “트리거”하는 데만 사용된다. 그렇게 TeX를 작동시킨 뒤에는 이스케이프 문자의 역할은 끝나며 더 이상 고려되지 않는다.

### 기술적 참고

다음과 같은 명령이 있다 `\\showtokens{...}` (e-TeX 엔진에서 도입됨)은 토큰 목록을 보여줄 수 있다(로그 파일에). e-TeX 매뉴얼에서:

> 명령은 `\\showtokens{<token list>}` 토큰 목록을 표시하며, 다음에 의해 표시할 수 없는 항목들도 표시할 수 있게 해준다 `\\show` 또는 `\\showthe`, 예를 들면:
>
> ```latex
> \\showtokens\\expandafter{\\jobname}
> ```

## 결론적으로

TeX 소스 코드의 291절에서( [TeX: The Program](https://www.amazon.co.uk/Computers-Typesetting-TeX-Program-TEX/dp/0201134373)) Knuth는 토큰 목록을 다음과 같이 설명한다:

> “토큰 목록은 mem의 한 단어 노드들로 이루어진 단일 연결 리스트이며, 각 단어는 토큰과 링크를 포함한다. 매크로 정의, 출력 루틴 정의, 마크, `\\write` 텍스트와 몇몇 다른 것들은 TeX가 토큰 목록의 형태로 기억하며, 보통은 그 “token\_ref\_count” 필드에 참조 횟수가 들어 있는 노드가 앞에 붙는다.”

처음 읽을 때는 이해하기 쉽지 않았을 수 있지만, 바라건대 이제는 조금 더 이해가 갈 것이다.


---

# 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/54-what-is-a-tex-token-list.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.
