> 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/51-unicode-utf-8-and-multilingual-text-an-introduction.md).

# 유니코드, UTF-8 및 다국어 텍스트: 소개

## 유니코드와 오픈타입: 문자와 글리프

현대 TeX 엔진, 즉 XeTeX와 LuaTeX는 Knuth의 원래 TeX 엔진에서 발전해 왔는데, 이는 주로 기술 환경의 발전, 특히 텍스트용 유니코드와 글꼴용 오픈타입을 따라가야 할 필요성 때문입니다. 오늘날에는 다음과 같은 패키지를 사용함으로써 [fontspec](https://ctan.org/pkg/fontspec?lang=en) 및 [unicode-math](https://ctan.org/pkg/unicode-math?lang=en), LaTeX 사용자는 오픈타입 글꼴이 제공하는 매우 정교한 조판 기능을 이용할 수 있습니다. 여기에는 고급 다국어 조판과 오픈타입 기반 수학 조판([마이크로소프트가 선구적으로 도입한](https://blogs.msdn.microsoft.com/murrays)).

그러나 XeTeX/LuaTeX와 함께 오픈타입 글꼴을 최대한 활용하려면 여러 배경 주제/개념에 익숙해지는 것이 도움이 될 수 있습니다. 특히 문제를 해결할 때나 더 고급/복잡한 작업의 기반을 닦을 때 그렇습니다. 예를 들어, XeTeX와 LuaTeX 엔진이 “UTF-8 입력”을 사용한다거나 “유니코드 인식”을 한다는 설명을 접할 수 있고, 오픈타입 글꼴에 대한 추가 읽기에서는 “유니코드 인코딩”, 오픈타입 “글꼴 기능”, “글리프”, “글리프 ID”, “글리프 이름” 등의 주제가 언급될 수 있습니다. 우리의 목표는 이러한 용어/주제에 대한 소개를 제공하고, 그것들이 어떻게 서로 관련되어 있는지 보여 주는 기본 틀을 함께 구성하여, 앞으로의 작업이나 문제 해결에 도움이 되도록 하는 것입니다.

우리가 다루려는 주제는 크게 두 가지 주요 영역으로 깔끔하게 나뉩니다: *유니코드* 즉, 사실상 텍스트/문자와 텍스트 인코딩의 세계에 속하며 *OpenType* 또 하나는 글꼴과 글리프의 세계입니다. 물론 이 두 세계는 서로 연결되어 있고, 이번 첫 번째 글에서도 어느 정도는 겹치는 부분이 있습니다.

### 우리는 어떤 주제들을 다루게 될까요?

이 글의 주요 초점은 유니코드와 관련된 몇몇 주제입니다. 즉, “문자”가 무엇을 의미하는지에 대한 논의로 시작하여, 문자 체계/언어, 유니코드 인코딩과 UTF-8을 소개하고, 다국어 텍스트 파일을 다루는 예시까지 살펴볼 것입니다. 후속 글에서는 이 글을 바탕으로 오픈타입 글꼴 기술과 관련된 배경 주제들을 다룰 예정입니다. 분명히 블로그 게시물의 한계 안에서 우리가 논의하고자 하는 모든 영역을 “깊이 파고들기”는 불가능합니다. 우리의 목표는 몇 가지 핵심 개념이 어떻게 서로 연관되어 있고 함께 작동하는지를 보여 주는 전체적인 틀을 제공하는 것입니다. 가장 기본적인 개념인 *문자*.

## 문자: 기본 구성 요소

우리 논의의 핵심이자 유니코드의 핵심에 있는 기본적인 생각/개념은 “문자”의 의미입니다. 이 단어는 일상적인 작업과 대화에서 사용될 때 그 의미가 종종 “가정”되는 말 가운데 하나입니다. 그러나 유니코드, 조판, 글꼴 기술의 관점에서는 “문자”가 무엇을 뜻하는지 조금 더 정확하게 정의할 필요가 있습니다. 예를 들어, 우리는 다음을 자연스럽게 **하나의** 및 *하나의* 서로 다른 “문자”로 생각할 수 있습니다: ‘굵은 a’와 ‘기울임꼴 a’. 하지만 그렇지 않습니다. 그것들은 유니코드가 공식 명칭으로 부여하는 동일한 기본 문자의 서로 다른 시각적 표현일 뿐입니다. [라틴 소문자 a](http://unicode.org/charts/PDF/U0000.pdf).

유니코드 [문자를 다음과 같이 정의합니다](http://www.unicode.org/glossary/#character) 다음과 같이

> “의미적 가치를 지닌 문어의 가장 작은 구성 요소; 특정한 형태가 아니라 추상적인 의미 및/또는 형태를 가리킨다...”

이는 문자에 특유한 *시각적 모습* 와 그 *의미를*.

문자를 언어의 기본 단위, 즉 구성 요소로 생각할 수 있으며, 더 정확히는 하나의 *문자*—아래에서 다루는 주제입니다. 특정 글꼴로 표시될 때 문자가 실제로 어떻게 보이는지는 유니코드의 문자 정의와는 관련이 없습니다. 여기서 실제로 중요한 것은 *의미를* 여기서 진짜로 중요한 것은: *역할과 목적* 입니다. 각 문자는 궁극적으로 문자 체계/언어가 구성되는 하나의 구성 블록 집합 가운데 하나로서의 역할을 합니다.

### 문자 체계와 언어

두 가지 중요한 개념을 간단히 언급할 가치가 있습니다: *문자 체계* 및 *언어*. 유니코드 웹사이트는 유용한 [문자 체계의 정의](https://www.unicode.org/standard/supported.html):

> “유니코드 표준은 언어가 아니라 문자 체계를 인코딩한다. 둘 이상의 언어를 위한 문자 체계들이 역사적으로 관련된 파생 관계를 가진 그래픽 기호 집합을 공유할 때, 그 모든 그래픽 기호의 합집합은 인코딩을 위한 하나의 문자 집합으로 간주되며 하나의 문자 체계로 식별된다.”

다음의 [위키백과 예시를 사용하면](https://en.wikipedia.org/wiki/Script_\(Unicode\)), 라틴 문자 체계는 특정한 [문자 집합](http://unicode.org/charts/) 으로 구성되며, 이는 영어, 프랑스어, 독일어, 이탈리아어 등 여러 언어 전반에서 사용됩니다. 물론 라틴 문자 체계를 기반으로 하는 모든 언어가 라틴 문자 체계에 정의된 모든 문자를 사용하는 것은 아닙니다. 예를 들어 영어 알파벳에는 프랑스어나 독일어 같은 다른 유럽 언어에 있는 악센트가 붙은 문자가 포함되어 있지 않습니다.

### 오픈타입 글꼴: 문자 체계와 언어

이 시점에서 우리는 유니코드에서 오픈타입 글꼴로 넘어가게 됩니다. 왜냐하면 문자 체계와 언어의 개념이 오픈타입 글꼴 기술에서도 매우 중요한 역할을 하기 때문입니다.

같은 [문자](http://www.unicode.org/glossary/#script) 를 사용하는 언어 집합은 각 언어로 작성된 텍스트를 표시(조판)할 때 서로 다른 타이포그래피 전통을 가질 수 있습니다. 좋은 예는 터키어와 [점이 없는 i의 동작](https://en.wikipedia.org/wiki/Dotted_and_dotless_I) (그 페이지의 합자에 대한 주석을 보십시오). 문자 체계/언어와 관련된 타이포그래피 “규칙”은 이른바 문자 체계 및 언어 *태그* 를 사용하여 오픈타입 글꼴의 기능 안에 내장되며, 이를 통해 특정 문자 체계/언어 조합에 적용되어야 할 규칙을 식별합니다. 당연히 각 오픈타입 글꼴이 지원하는 문자 체계/언어 집합은 글꼴 제작자가 내린 선택과 제작 목적에 따라 달라집니다. XeTeX나 LuaTeX 같은 정교한 조판 소프트웨어는 LaTeX [fontspec 패키지](https://ctan.org/pkg/fontspec?lang=en).

#### 오픈타입 글꼴 안 들여다보기: 문자 체계/언어

좀 더 분명히 하기 위해, 다음은 무료 [Scheherazade 오픈타입 글꼴](http://software.sil.org/scheherazade/download/) 을 (역시 무료인) [Microsoft VOLT](https://www.microsoft.com/en-us/Typography/volt.aspx) 글꼴 편집 소프트웨어 안에서 연 스크린샷입니다. 이 이미지에서는 Scheherazade에 내장된 문자 체계, 언어, 타이포그래피 기능을 볼 수 있습니다. VOLT를 사용하면 Scheherazade에 추가 기능과 기능성을 더할 수 있지만, 그것은 이 글의 범위를 훨씬 벗어납니다!

![Microsoft VOLT에서 연 Scheherazade 오픈타입(TrueType 변형) 글꼴](/files/25064c1781611ed90eec51d183e60b66aa6c3e34)

이 스크린샷에서 Scheherazade가 아랍어와 라틴 문자 체계를 지원하고, 아랍 문자 체계를 사용하는 여러 언어에 대해 추가적인 전문 지원을 제공한다는 것을 알 수 있습니다. 이는 위의 초록색 테두리 상자에 나열된 이른바 오픈타입 기능을 통해 이루어집니다. 이 기능들의 세부 사항까지는 다루지 않겠지만, 여기서 전달하고자 하는 메시지는 고품질 오픈타입 글꼴에는 글꼴에 내장된 타이포그래피 규칙을 활용할 수 있도록 많은 지능이 담겨 있다는 것입니다.

관심 있는 독자는 오픈타입 태그 레지스트리를 둘러보며 [문자 체계 태그](https://www.microsoft.com/typography/otspec/scripttags.htm) 및 [언어 태그](https://www.microsoft.com/typography/developers/opentype/languagetags.aspx) 를 현재 오픈타입 명세에서 어떻게 사용하고 있는지 볼 수 있습니다.

### 문자로 돌아가기: 서로 다른 문자 역할

어떤 문자 체계(또는 언어)의 기본 요소를 이루는 문자 집합이 모두 같은 역할을 수행하는 것은 아닙니다. 예를 들어 대부분의 언어에는 다음을 위한 문자가 있습니다. *문장 부호*, 숫자 *자릿수* 를 위한 문자와 함께, 우리가 *문자* 라고 생각하는 알파벳의 문자들도 있습니다. 일부 문자 체계에서는 대문자와 소문자 형태도 존재합니다. 문자의 개념은 매우 넓어서 유니코드 표준에는 *표시되도록 설계되지 않은* 특수 문자도 포함되어 있지만, 그 역할은 “텍스트의 해석이나 표시를 제어하는 것”입니다. 예를 들어 어떤 아랍어 텍스트를 조판할 때 특정 문자들의 결합 동작을 강제로 만들거나, 반대로 막고 싶을 수 있습니다. 유니코드 표준은 이를 위해 특별한 제어 문자를 제공합니다. 이른바 [ZERO WIDTH JOINER](https://en.wikipedia.org/wiki/Zero-width_joiner) 와 [ZERO WIDTH NON-JOINER](https://en.wikipedia.org/wiki/Zero-width_non-joiner)입니다. 이러한 문자들은 표시를 위한 것이 아니며, 의도된 시각 효과를 만들어 내기 위해 텍스트를 처리하는 동안 소프트웨어에 의해 “흡수”됩니다.

유니코드 표준에서 지정된 모든 문자에는 일련의 속성이 부여되며, 이는 사실상 유니코드 인코딩에서 각 문자의 역할과 목적을 설명합니다. LATIN SMALL LETTER A와 같은 문자 이름은 문자 속성 목록의 한 요소일 뿐입니다. 이러한 속성은 [Unicode Character Database (UCD)](http://www.unicode.org/reports/tr44/) 에 완전히 기술되어 있으며, 검색, 정렬, 맞춤법 검사 등과 같은 컴퓨터화된 텍스트 처리 작업에서 널리 사용됩니다. 유니코드 문자 속성을 나열한 데이터 파일도 [다운로드할 수 있습니다](http://www.unicode.org/Public/UCD/latest/).

각 문자에 부여된 속성들 가운데, 우리의 논의에서 가장 중요한 것은 *숫자 식별자* 입니다. 이는 해당 문자의 유니코드 인코딩에 의해 할당됩니다. 이제 그 주제로 넘어가겠습니다.

### 문자: 숫자와 인코딩

당연한 말이지만 컴퓨터와 기타 디지털 장치는 숫자 데이터를 저장하고 처리하는 일을 합니다. 그렇다면 이것이 텍스트와는 어떻게 관련될까요? 컴퓨터 키보드로 글을 입력하거나 모바일 기기의 화면을 탭해서 텍스트를 입력할 때, 여러분의 키 입력은 입력 중인 문자열을 나타내는 숫자로 바뀝니다.

어느 시점에는 그 텍스트(숫자의 연속)를 이메일, 문자 메시지, 또는 트윗이나 어떤 형태의 소셜 미디어 게시물 같은 온라인 통신 수단을 통해 전달하고 싶을 수 있습니다. 분명히 텍스트를 작성한 기기와 수신자가 사용하는 기기(들)는 어떤 숫자가 어떤 문자를 나타내는지에 대해 somehow 합의해야 합니다. 그렇지 않으면 수신자의 기기에서 텍스트가 올바르게 표시되지 않을 수 있습니다.

오늘날의 전 세계적 통신이 작동하려면 송신 및 수신 장치가 특정 숫자 집합이 특정 문자 집합을 나타내는 “상호 합의된 관례”를 필요로 합니다. 이 관례를 *인코딩*이라고 하며, 특정 문자 집합을 나타내는 데 사용되는 숫자들의 집합입니다. 그리고 유니코드 인코딩은 이제 *사실상의* 글로벌 표준이 되었습니다.

## 유니코드: 텍스트 저장을 위한 비트와 바이트

유니코드는 텍스트 인코딩보다 훨씬, 훨씬 더 많은 것을 다루는 거대한 표준이지만, 여기서는 그것이 제공하는 인코딩에만 초점을 맞춥니다.

#### 비트, 바이트, 그리고 몇 개의 문자?

장치가 텍스트를 숫자로 저장하고 표현한다고 언급했습니다. 구체적으로 문자는 정수, 즉 전체수로 저장됩니다. 이것이 유니코드 인코딩에 어떤 의미를 갖는지 이해하려면 컴퓨터가 정수를 어떻게 저장하는지에 대한 *아주* 짧은, *아주* 기본적인 검토가 필요합니다(우리는 컴퓨터과학에 깊이 들어가려는 것은 아닙니다).

아주 긴 이야기를 줄여 말하자면, 오늘날의 데스크톱 또는 휴대형 장치들은 1, 2, 4 또는 8바이트 길이의 분리된 “덩어리”로 정수를 저장합니다. 이러한 저장 단위 각각은 포함된 전체 비트 수에 따라 최대 양의 정수를 저장할 수 있습니다.

* 1바이트(8비트): 최대 양의 정수는 255입니다;
* 2바이트(16비트): 최대 양의 정수는 65535입니다;
* 4바이트(32비트): 최대 양의 정수는 4,294,967,295입니다;
* 8바이트(64비트): 최대 양의 정수는 18,446,744,073,709,551,615입니다.

실제로 유니코드 표준은 전 세계의 모든 문자를 인코딩하기 위해 0부터 1,114,111까지의 숫자를 사용하며, 그 결과 전체 범위를 인코딩하려면 21비트만 있으면 됩니다. 이는 n비트를 포함한 저장 단위가 0에서 최대값 $$2^n -1$$까지의 임의의 양의 정수를 나타낼 수 있다는 점을 통해 알 수 있습니다. 따라서:

* 20비트에 저장할 수 있는 최대값은 $$2^{20} -1 = 1,048,575$$ (너무 작음);
* 21비트에 저장할 수 있는 최대값은 $$2^{21} -1 = 2,097,151$$ (충분히 큼).

컴퓨터가 데이터를(숫자를) 1, 2, 4(또는 8)바이트 단위로 저장한다는 점을 언급했습니다. 그렇다면 최대 유니코드 값인 1,114,111까지 저장해야 한다면 저장 단위는 얼마나 커야 할까요? 분명히 1바이트 저장 단위는 최대 255를 담을 수 있고 2바이트는 65535를 저장할 수 있습니다. 둘 다 유니코드로 인코딩된 전체 문자 범위를 저장하기에는 충분하지 않습니다. 다음으로 가능한 옵션은 4바이트 크기의 저장 단위이며, 이는 최대 4,294,967,295까지의 정수를 저장할 수 있어 실제로 필요한 것보다 훨씬 더 큽니다. 따라서 저장 단위로 4바이트를 선택하면 분명히 모든 유니코드 값을 저장할 충분한 공간이 있으며, 각 문자는 4바이트(32비트)가 필요한 정수로 저장됩니다. 그러나 모든 것을 저장하는 데 4바이트를 사용하는 것은 공간을 매우 낭비하는 일입니다. 왜냐하면 가장 큰 유니코드 값조차 최대 21비트만 필요하기 때문입니다. 이를 32비트로 저장하면 32비트 중 11비트는 절대 사용되지 않는다는 뜻이 됩니다.

**참고**: 유니코드 범위는 0부터 1,114,111까지이지만, 그 범위의 모든 값이 실제로 사용되는 것은 아닙니다. 기술적인 이유로 일부 값은 실제 유니코드 문자로 사용하기에 유효하지 않은 것으로 간주됩니다.

### 그렇다면 UTF-8은 무엇일까요?

XeTeX나 LuaTeX에 대해 읽다 보면, 이 TeX 엔진들이 텍스트와 LaTeX 입력 파일을 “UTF-8 형식”으로 읽는다고 설명하는 내용을 거의 확실히 접하게 됩니다. 그렇다면 “UTF-8 형식”은 무엇이며 유니코드와는 어떻게 관련될까요? 유니코드 용어로 말하면, 전 세계의 문자를 인코딩하는 데 사용되는 0부터 1,114,111까지의 1,114,112개 값 각각은 하나의 [코드 포인트](http://www.unicode.org/glossary/#code_point).

우리는 보았습니다, *이론상*, 유니코드로 인코딩된 텍스트 전체를 표현하려면 문자당 4바이트로 저장해야 한다는 것을요. 그러나 실제로는 꽤 영리한 사람들이 단일 유니코드 숫자(코드 포인트)를 *연속* 의 더 작은 숫자들의 연속으로 나타내는 간단한 방법을 고안했으며, 그 더 작은 숫자들 각각은 1바이트에 저장됩니다. 이는 *변환하는* 과정으로, 하나의(더 큰) 정수를 더 작은(바이트 크기의) 정수들의 연속으로 바꿉니다. 이 변환 때문에 텍스트 파일의 각 문자는 더 이상 하나의 숫자 값으로 표현되지 않습니다. 각 문자는 *다중 바이트 시퀀스*가 되며, 텍스트 파일에서 1부터 4개의(연속된) 바이트가 단일한 유니코드 문자를(i.e., 그 코드 포인트 값)을 나타낼 수 있습니다.

UTF는 *유니코드 변환 형식* 의 약자이며, 여기서 핵심 단어는 *변환*입니다. 본질적으로 UTF-8은 단일 유니코드 코드 포인트 값을 1에서 4개의 바이트 크기 조각으로 변환(변형)하는 “레시피” 또는 알고리즘이라고 생각할 수 있습니다. 유니코드 코드 포인트 값이 커질수록 UTF-8 형식으로 표현하는 데 필요한 단일 바이트의 수도 늘어납니다.

UTF-8을 만든 데에는 기술적, 역사적 이유가 있으며, UTF-8 발명 뒤에 있는 이야기는 [2003년의 흥미로운 이메일에 기록되어 있습니다](https://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt), 그 이메일의 초반부에는 다음 문장이 있습니다:

> “그건 사실이 아닙니다. UTF-8은 1992년 9월 어느 날 밤쯤, 뉴저지 식당의 식탁 깔개 위에서 제 눈앞에서 설계되었습니다.”

#### 예시: 아랍어 문자 ل

아랍어 문자 ل(유니코드 이름 ARABIC LETTER LAM)의 예를 들어 봅시다. 이 문자는 유니코드 코드 포인트 값 1604(10진수) 또는 0644(16진수)가 할당되어 있으며, UTF-8에서의 표현은 *2바이트* 시퀀스 D9 84(16진수) 또는 10진수로는 217 132입니다. 텍스트를 저장하는 형식으로 UTF-8을 사용할 때, ل을 나타내기 위해 단일 숫자 1604를 담은 텍스트 파일 대신 이것은 두 개의 바이트 크기 값인 217과 132로 변환됩니다. 문자 ل은 *2바이트 시퀀스*로 저장됩니다. UTF-8 알고리즘을 더 자세히 살펴보고 싶은 독자는 제 [개인 블로그 사이트](http://www.readytext.co.uk/?p=1284).

에서 자세한 설명과 C 코드를 찾을 수 있습니다. 어떤 소프트웨어(예: XeTeX나 LuaTeX)가 UTF-8 형식의 텍스트를 읽을 때, 그 소프트웨어는 해당 파일에 있는 각 문자의 유니코드 값을 알아내야 하므로, 알고리즘을 사용하여 *역으로* UTF-8 변환 과정을 되돌립니다. 그 “역변환 알고리즘”을 통해 두 바이트(217과 132)가 다시 결합되어 정수 1604가 생성되며, 이는 이후 아랍어 문자 ل의 유니코드 코드 포인트 값으로 인식될 수 있습니다.

따라서 결론적으로, UTF-8은 유니코드로 인코딩된 텍스트를 저장하고 전송하기 위해 사용되는 중간 데이터 형식일 뿐입니다.

**참고**: 일부 시스템은 문자당 32비트를 사용하여 텍스트를 저장/사용하기도 하는데, 이를 [UTF-32](https://en.wikipedia.org/wiki/UTF-32)라고 합니다. 또한 [UTF-16](https://en.wikipedia.org/wiki/UTF-16) 도 있지만, UTF-8이 유니코드로 인코딩된 텍스트를 저장하는 가장 일반적인 방식입니다.

## 다국어 TeX 파일: XeTeX와 LuaTeX

XeTeX와 LuaTeX 둘 다 매우 정교한 다국어 조판이 가능하지만, 이를 구현하는 메커니즘은 꽤 다르며 각 엔진의 설계/개발 철학을 반영합니다. 이를 깊이 파고들지는 않겠지만, XeTeX 엔진에는 LuaTeX에는 없는 소프트웨어 구성 요소가 포함되어 있다는 점만 짚어 두겠습니다. 특히 다음과 같은 과정에 대한 소프트웨어가 그렇습니다. *오픈타입 셰이핑* (예를 들어, 다음과 같은 라이브러리를 통해 [HarfBuzz](https://www.freedesktop.org/wiki/Software/HarfBuzz/)).

반면 LuaTeX은 다른 접근 방식을 취합니다. 실제 TeX 엔진 자체에 기능을 직접 내장하는 대신, LuaTeX은 매우 풍부한 명령어 모음(TeX 원시 명령)과 매우 강력한 [Lua 기반 API](/latex/ko/in-depth-articles/07-an-introduction-to-luatex-part-1-what-is-it-and-what-makes-it-so-different.md) 를 제공하며, 이를 통해 개발자는 다국어 조판을 위한 동등하게 고급의 해결책을 구성할 수 있습니다. LuaTeX의 철학은 LaTeX 패키지 개발자에게 추가 작업을 의미할 수 있지만, 해결책이 실제 LuaTeX 엔진 자체에 “하드코딩”되는 것이 아니라 TeX와 Lua 코드, 또는 C/C++로 작성된 플러그인으로 구성되기 때문에 훨씬 더 큰 유연성을 제공합니다.

**덧붙임**: OpenType 셰이핑의 매력적이지만 복잡한 세계를 더 탐구하고 싶은 독자라면 [HarfBuzz](https://www.freedesktop.org/wiki/Software/HarfBuzz/)라고 불리는 뛰어난 오픈소스 라이브러리에 대해 읽어 볼 수 있습니다. 이 라이브러리는 Firefox, Chrome, LibreOffice를 포함한 많은 애플리케이션에서 사용되며, 물론 XeTeX에서도 사용됩니다. 이 글의 저자는 HarfBuzz를 사용해 [아랍어 조판용 LuaTeX 플러그인](http://www.readytext.co.uk/?p=3186).

를 만든 적이 있습니다. 오늘날에는(예를 들어 소셜 미디어에서) 여러 언어의 문자가 포함된 텍스트를 전송하는 것이 일상적이며, 다국어 텍스트를 저장한 UTF-8 텍스트 파일에는 UTF-8 표현이 1, 2, 3 또는 4바이트 길이인 문자가 쉽게 포함될 수 있습니다. 따라서 사실상 UTF-8 텍스트 파일은 단지 바이트들의 연속이지만, 그 파일의 실제 각 문자는 1에서 4바이트 길이일 수 있습니다. 개별 문자는 *다중 바이트 시퀀스*.

가 된 것입니다. 다국어 텍스트를 (조판 관점에서) 다루는 몇 가지 핵심 측면을 더 살펴보기 위해, 우리는 아랍어 문자 체계를 포함한 예시를 사용할 것입니다. 아랍어는 여러 개념을 다룰 수 있는 여지를 제공하기 때문입니다.

#### 덧붙임: 아랍어 문자 체계

다음 [아랍어 문자 체계](https://en.wikipedia.org/wiki/Arabic_script) 는 오른쪽에서 왼쪽으로 읽고 쓰는 필기체 스타일로 작성됩니다. 각 아랍어 문자는 다음에 따라 잠재적으로 4가지 서로 다른 형태 중 하나를 취할 수 있습니다:

* 그것이 단독의, 독립적인(고립된) 문자로 표시되는지 여부(다른 어떤 것에도 연결되지 않음);
* 단어 안에서 나타나는지 여부—단어의 시작, 중간 또는 끝에 위치하는지: 이를 각각 *초기*, *중간* 및 *최종* 형태라고 합니다.

아랍 문자 체계의 각 문자는 고유한 결합 규칙 집합을 가지며, 왼쪽, 오른쪽 또는 양쪽에 다른 문자가 있을 때 모양/표현이 바뀔 수도 있고 바뀌지 않을 수도 있습니다. 이를 더 탐구하고 싶은 독자는 [위키백과의 전체 목록](https://en.wikipedia.org/wiki/Template:Arabic_alphabet_shapes/joining).

#### 예시: UTF-8의 아랍어와 영어 텍스트

영어와 아랍어 텍스트 한 줄을 포함하는 UTF-8 텍스트 파일을 만든다고 가정해 봅시다: This is العَرَبِيَّة text!

이 텍스트 줄에는 공백 문자 3개, 영어(라틴 문자 체계) 문자 11개, 아랍어 문자 12개가 포함되어 있습니다(비록 그것이 즉시 분명하지 않을 수는 있습니다). 이것을 UTF-8 텍스트 파일로 저장하면 다음 이유로 38바이트의 저장 공간을 차지합니다:

* **라틴 문자 체계**: 공백과 영어 텍스트: 14 ✕ 1바이트 문자 = 14바이트;
* **아랍어 문자 체계**: 아랍어 문자 12개 ✕ 문자당 2바이트 = 24바이트.

합계는 14 + 24 = 38바이트입니다.

#### 더 깊이 들어가기

예시 텍스트를 `arabic.txt` 라는 UTF-8 파일로 저장하고 16진수 편집기에서 열면, 실제로 포함된 바이트를 살펴볼 수 있습니다. 다음의 주석이 달린 스크린샷을 보면 아랍어 텍스트가 문자당 2바이트로 저장되어 있음을 알 수 있습니다:

![영어와 아랍어 텍스트가 포함된 UTF-8 텍스트 파일을 16진수 편집기에서 연 모습.](/files/a3e9d5576926318a524e866bcce6a4a9e54a3d65)

영어와 아랍어 텍스트가 포함된 UTF-8 텍스트 파일을 16진수 편집기에서 연 모습. 라틴 문자 체계 문자는 단일 바이트가 필요하지만 아랍 문자 체계 문자는 문자당 2바이트로 저장된다는 것을 분명히 볼 수 있습니다.

이 스크린샷에서 두 가지를 관찰할 수 있습니다:

* 아랍어 텍스트는 왼쪽에서 오른쪽 순서로 저장되어 있으며, 문자는 아랍어 글자와 모음의 원시적이고 형태가 다듬어지지 않은(고립된) 버전입니다;
* 라틴 문자 체계의 “This is ” 뒤에는 이 파일을 읽는 어떤 소프트웨어에도 다음 문자가 아랍 문자 체계임을 알려 주는 추가 정보가 없습니다.

영어와 아랍어를 포함하는 다국어 문서를 조판하는 경우, 입력 텍스트 파일을(바이트 스트림으로) 읽고 처리하는 동안 XeTeX나 LuaTeX은 각 문자의 시작과 끝을 감지하고, UTF-8 변환을 역으로 되돌려 대응하는 유니코드 코드 포인트를 생성하는 데 필요한 정확한 바이트 수를 읽을 수 있어야 합니다. 소프트웨어가 이를 가능하게 하는 것은 바로 UTF-8 알고리즘 자체입니다. 즉, 각 개별 문자의 첫 번째 바이트를 감지하고 대응하는 유니코드 코드 포인트를 계산하기 위해 몇 바이트를 읽어야 하는지 알 수 있게 해 줍니다. UTF-8은 사용하기 간단하지만, 사실 매우 기발합니다.

#### 논리적 순서, 표시 순서, 그리고 오픈타입 셰이핑

위의 아랍어(العَرَبِيَّة)를 자세히 보면, 우리의 텍스트 파일이 실제로 12개의 개별 아랍어 문자를 포함하고 있다는 점을 알아차리기 어려울 수 있습니다. 특히 아랍 문자 체계에 익숙하지 않다면 더욱 그렇습니다! 하지만 위 스크린샷의 오른쪽에 표시된 아랍어 문자를 주의 깊게 세어 보면 총 12개라는 것을 알 수 있습니다.

아랍어와 같은 복잡한 문자 체계 언어의 경우, 우리의 텍스트 파일이 *저장하는 것과* 당신이 *화면에서 보는 것은* 확실히 눈에 띄게 *아주* 다릅니다! 예를 들어 브라우저에서 그 텍스트를 볼 때 보이는 것은(사용된 글꼴에 따라):

![조판된 아랍어 텍스트의 이미지](/files/bdfd62320516f8320595e39626362f096e9b2570)

하지만 위 스크린샷이 보여 주듯, UTF-8 텍스트 파일이 실제로 담고 있는 것은 다음과 같습니다:

![조판되지 않은 아랍어 텍스트(고립된 문자)의 이미지](/files/9dd9905c663543ffc67678ef2da561d298983c18)

아랍 문자 체계의 필기체적 성격에 익숙하지 않더라도, 텍스트 파일에 들어 있던 아랍어 문자를 조판 및/또는 화면 표시로 옮기는 과정에서 “무언가”가 일어났다는 것을 분명히 알 수 있습니다(글리프로서). TeX/LaTeX를 라틴계 언어 같은 단순 문자 체계 언어와 함께 사용해 온 사람이라면, 이것은 정말 매우 혼란스러울 수 있습니다!

여기에는 몇 가지 중요한 개념이 작동하고 있습니다. 유니코드 텍스트 파일은 텍스트(유니코드)를 저장하는 일을 하고, 조판 및 표시 시스템은 글꼴과 글리프(오픈타입)를 사용하는 일을 하기 때문입니다:

* 텍스트 파일은 아랍어 문자를 왼쪽에서 오른쪽 순서로 저장했지만, 아랍어는 오른쪽에서 왼쪽으로 읽고 표시됩니다. 텍스트 파일은 이른바 *논리적 순서*;
* 를 사용해 저장되었으며, 화면에 나타난 실제 표시와는 매우 다르게 보이는 개별 문자들을 포함합니다. 텍스트 파일에는 고립되어 서로 연결되지 않은 형태의 아랍어 문자들이 들어 있습니다.

#### 무슨 일이 일어나고 있는 걸까요?

텍스트 파일 안에서 아랍어는 왼쪽에서 오른쪽으로 이어지는 고립형 문자들의 순서로 저장됩니다. 생각해 보면, 텍스트 파일은 아랍어 텍스트를 입력된 순서/연속으로 저장합니다 *입력된 순서대로* (즉, *논리적 순서*). 그 텍스트가 표시를 위해 처리되거나 조판될 때에만 올바른 읽기 순서로 표시되며, 이는 흔히 다음과 같이 불립니다: *시각적 순서* 또는 *표시 순서*; 또한 아랍어 문자의 고립형은 *형태가 변환됩니다* 타이포그래피적으로 올바른 표시 형태로 변환됩니다. 이를 이해하는 한 가지 방법은, 일반 텍스트 파일이 텍스트(유니코드 문자)를 가능한 한 가장 기본적인 형태, 즉 가공되지 않은 개별 문자 그대로 저장해야 한다는 것입니다. 이러한 문자들을 디스플레이 장치에서 사용할 수 있는 운영체제, 글꼴, 조판/렌더링 소프트웨어에 따라 화면에 표시하는 것은 시스템 소프트웨어의 역할입니다.

그 파일 안의 아랍어 텍스트가 조판/표시될 때, 다음과 같은 과정을 거칩니다 *셰이핑*. 개별 아랍어 문자는 아랍 문자 및 표기 체계의 연결 규칙에 따라 각 문자의 변형을 올바르게 반영하는 형태 변환된 글리프로 바뀝니다. 또한 고품질 조판 소프트웨어(좋은 OpenType 글꼴 사용)는 다음과 같은 과정을 통해 추가적인 타이포그래피 처리를 적용하여 더 정교한 처리를 더합니다: *오픈타입 셰이핑*—이 과정은 다음을 포함할 수 있는 다양한 타이포그래피 연산을 포괄합니다:

* 여러 개의 개별 글리프를 하나의 복합 합자 글리프로 대체하는 것(아랍어에서 매우 흔함), 또는
* 예를 들어 아랍어 모음이 어느 글리프 위 또는 아래에 놓이는지에 따라 그 위치를 조정하는 배치 연산입니다.

![조판될 때 아랍어 텍스트가 거치는 변형을 보여주는 이미지](/files/7903d0ea205a6daa482c86d7a921eaa4335eaac1)

논리 순서와 시각적(표시) 순서의 차이. 이 그림에서는 텍스트 파일에 저장된 아랍어 문자가 표시되거나 조판될 때 재정렬과 형태 변환을 거친다는 것을 볼 수 있습니다.

고급 OpenType 글꼴의 설계자와 제작자는 글꼴에 내장된 정교한 타이포그래피 기능을 제공하기 위해 매우 많은 시간과 전문 지식을 투자합니다.

아랍어 텍스트에 적용되는 형태 변환을 끄려면, 훌륭한 무료, [BabelPad](http://www.babelstone.co.uk/Software/BabelPad.html) 유니코드 텍스트 편집기(Windows 전용)로, 형태 변환을 비활성화하여 텍스트 파일에 실제로 들어 있는 가공되지 않은 개별 비결합(비형태화) 문자를 볼 수 있습니다—이 합성 스크린샷의 아래쪽 절반을 보세요:

![BabelPad 텍스트 편집기가 OpenType 형태 변환을 끌 수 있는 기능을 보여주는 이미지](/files/a4134af782d84d9f545bc4639ff4909bf400e98f)

BabelPad 유니코드 텍스트 편집기를 사용하여 OpenType 형태 변환을 켜기(위 그림) 또는 끄기(아래 그림). OpenType 형태 변환을 끄면 아랍어 텍스트를 편집하기가 훨씬 쉬워집니다.

논리 순서와 표시 순서의 개념은, 형태 변환 과정과 결합될 때, 아랍어처럼 복잡한 스크립트가 포함된 다국어 텍스트 파일을 편집하거나 조판할 때 처음 접하면 꽤 혼란스러울 수 있습니다. 바라건대, 위 내용이 초기의 혼란을 어느 정도 줄이는 데 도움이 되었기를 바랍니다.


---

# 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/51-unicode-utf-8-and-multilingual-text-an-introduction.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.
