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

# Unicode, UTF-8 и многоязычный текст: введение

## Юникод и OpenType: символы и глифы

Современные движки TeX, то есть XeTeX и LuaTeX, развились из оригинального движка TeX Кнута во многом из-за необходимости идти в ногу с развитием технологического ландшафта, в частности Unicode (для текста) и OpenType (для шрифтов). Сегодня, с помощью пакетов, таких как [fontspec](https://ctan.org/pkg/fontspec?lang=en) и [unicode-math](https://ctan.org/pkg/unicode-math?lang=en), пользователи LaTeX могут получить доступ к чрезвычайно сложным возможностям набора, предоставляемым шрифтами OpenType, включая продвинутый многоязычный набор и математический набор на основе OpenType ([впервые предложенный Microsoft](https://blogs.msdn.microsoft.com/murrays)).

Однако, чтобы извлечь максимум из использования шрифтов OpenType с XeTeX/LuaTeX, полезно ознакомиться с рядом фоновых тем/понятий — особенно для отладки проблем или чтобы подготовить почву для более продвинутой/сложной работы. Например, вы можете прочитать о движках XeTeX и LuaTeX, использующих «входные данные UTF-8» или о том, что они «понимают Unicode», а дальнейшее чтение о шрифтах OpenType может обсуждать или упоминать такие темы, как «кодировка Unicode», «свойства шрифтов OpenType», «глифы», «идентификаторы глифов», «имена глифов» и так далее. Наша цель — дать введение в эти термины/темы и собрать воедино базовую схему, показывающую, как они связаны друг с другом и, будем надеяться, помочь в дальнейшей работе или решении проблем.

Темы, которые мы собираемся рассмотреть, довольно четко делятся на две основные области: *Unicode* которая, по сути, обитает в мире текста/символов и кодировки текста, и *OpenType* мир которой — это мир шрифтов и глифов; но, разумеется, эти два мира взаимосвязаны, и между ними есть пересечение, даже в этой первой статье.

### Какие темы мы собираемся обсудить?

Основное внимание этой статьи уделено нескольким темам, связанным с Unicode: начиная с обсуждения того, что подразумевается под «символом», и далее — к введению в письменности/языки, кодировку Unicode и UTF-8 — вместе с примером работы с многоязычными текстовыми файлами. Последующая статья продолжит эту тему, чтобы рассмотреть фоновые вопросы, связанные с технологией шрифтов OpenType. Очевидно, в рамках поста в блоге невозможно попытаться сделать «глубокое погружение» во все области, которые мы надеемся обсудить: наша заявленная цель — предоставить общую схему, показывающую, как связаны и взаимодействуют несколько ключевых понятий. Начнем с самого базового понятия: *символ*.

## Символ: базовый строительный блок

Фундаментальная идея/понятие, лежащее в основе наших обсуждений (и Unicode), — это значение «символа»: это одно из тех слов, значение которых часто «предполагается» в повседневной работе и разговорах. Однако с точки зрения Unicode, верстки и шрифтовых технологий нам нужно быть чуть точнее и определить, что имеется в виду под «символом». Например, нам может казаться вполне естественным думать о **один** и *один* как о разных «символах»: «a жирным» и «a курсивом». Но это не так: это лишь разные визуальные представления одного и того же фундаментального символа, которому Unicode дает официальное имя [LATIN SMALL LETTER A](http://unicode.org/charts/PDF/U0000.pdf).

Unicode [определяет символ](http://www.unicode.org/glossary/#character) как:

> «Наименьший компонент письменного языка, обладающий семантической ценностью; относится к абстрактному значению и/или форме, а не к конкретной форме...»

что ясно различает конкретную *внешнем виде* и его *значение*.

Можно рассматривать символ как фундаментальную единицу или строительный блок языка или, точнее, *письменности*—тему, которую мы обсуждаем ниже. То, как символ на самом деле выглядит при отображении с использованием конкретного шрифта, не имеет отношения к определению символа в Unicode: важна только *значение* представляет реальный интерес здесь: *роль и назначение* каждого символа как одного из набора строительных блоков, из которых в конечном счете строятся письменности/языки.

### Письменность и язык

Стоит кратко упомянуть две важные концепции: *письменности* и *языков*. На веб-сайте Unicode есть полезное [определение письменности](https://www.unicode.org/standard/supported.html):

> «Стандарт Unicode кодирует письменности, а не языки. Когда системы письма для более чем одного языка разделяют наборы графических символов, имеющих исторически родственные происхождения, объединение всех этих графических символов рассматривается как единый набор символов для кодирования и определяется как одна письменность.»

Используя [пример из Википедии](https://en.wikipedia.org/wiki/Script_\(Unicode\)), латинская письменность состоит из определенного [набора символов](http://unicode.org/charts/) который используется во многих языках: английском, французском, немецком, итальянском и так далее. Разумеется, не все символы, определенные в латинской письменности, используются всеми языками, основанными на латинской письменности, — например, английский алфавит не содержит букв с диакритическими знаками, присутствующих в других европейских языках, таких как французский или немецкий.

### Шрифты OpenType: письменности и языки

На этом этапе мы перейдем от Unicode к шрифтам OpenType, поскольку понятия письменности и языка также играют чрезвычайно важную роль в технологии шрифтов OpenType.

Набор языков, использующих одну и ту же [письменности](http://www.unicode.org/glossary/#script) может иметь разные типографические традиции, когда речь идет о отображении (верстке) текста, написанного на конкретном языке. Хороший пример можно найти в турецком языке и [поведении буквы i без точки](https://en.wikipedia.org/wiki/Dotted_and_dotless_I) (см. примечания на той странице о лигатурах). Типографические «правила», связанные с письменностями/языками, встроены в функциональность шрифтов OpenType с помощью так называемых script и language *тегов* которые используются для идентификации правил, которые должны применяться к определенным комбинациям письменность/язык. Разумеется, набор письменностей/языков, поддерживаемых каждым шрифтом OpenType, будет различаться в зависимости от решений, принятых создателями шрифта, и причины его создания. Продвинутое программное обеспечение для верстки, такое как XeTeX или LuaTeX, может использовать эти правила (встроенные в шрифты OpenType), позволяя пользователям выборочно применять их к входному тексту при наборе текста на определенном языке — например, с помощью пакета LaTeX [fontspec](https://ctan.org/pkg/fontspec?lang=en).

#### Заглядывая внутрь шрифта OpenType: письменности/языки

Чтобы прояснить это, вот снимок экрана, показывающий бесплатный [шрифт OpenType Scheherazade](http://software.sil.org/scheherazade/download/) открытый в (тоже бесплатном) [Microsoft VOLT](https://www.microsoft.com/en-us/Typography/volt.aspx) программе для редактирования шрифтов. На этом изображении вы можете увидеть письменности, языки и типографические возможности, встроенные в Scheherazade — с помощью VOLT можно добавить дополнительные функции и возможности в Scheherazade, но это далеко выходит за рамки этой статьи!

![Шрифт OpenType Scheherazade (в варианте TrueType), открытый в Microsoft VOLT](/files/dbba50e514ab9ed0ce804c605d11b2df622051ff)

Из этого снимка экрана видно, что Scheherazade поддерживает арабскую и латинскую письменности и предоставляет дополнительную специализированную поддержку для нескольких языков, использующих арабскую письменность, — с помощью так называемых функций OpenType, которые перечислены в рамке с зеленой рамкой выше. Мы не будем вдаваться в особенности этих функций, но смысл здесь в том, что высококачественные шрифты OpenType содержат много «интеллекта», готового к использованию программами верстки, способными воспользоваться типографическими правилами, встроенными в шрифты.

Заинтересованный читатель может просмотреть реестр тегов OpenType, чтобы увидеть [теги письменностей](https://www.microsoft.com/typography/otspec/scripttags.htm) и [теги языков](https://www.microsoft.com/typography/developers/opentype/languagetags.aspx) в настоящее время используемые в спецификации OpenType.

### Вернемся к символам: разные роли символов

Набор символов, составляющих фундаментальные элементы письменности (или языка), не все выполняют одну и ту же роль. Например, в большинстве языков есть символы для *пунктуации*, символы для числовых *цифр* а также символы, которые мы воспринимаем как *буквы* алфавита, которые для некоторых письменностей также существуют в прописной и строчной формах. Понятие символа довольно широкое, и Стандарт Unicode включает специальные символы, которые *не предназначены для отображения* но чья задача — «управлять интерпретацией или отображением текста». Например, при наборе некоторого арабского текста вы можете захотеть принудительно включить или запретить соединительное поведение определенных символов; стандарт Unicode предоставляет для этого специальные управляющие символы: так называемые [ZERO WIDTH JOINER](https://en.wikipedia.org/wiki/Zero-width_joiner) и [ZERO WIDTH NON-JOINER](https://en.wikipedia.org/wiki/Zero-width_non-joiner). Эти символы не предназначены для отображения и «поглощаются» программным обеспечением при обработке текста, чтобы создать нужные визуальные эффекты.

Все символы, определенные в стандарте Unicode, наделяются набором свойств, который, по сути, описывает роль и назначение каждого символа в кодировке Unicode — имена символов, такие как LATIN SMALL LETTER A, лишь один элемент списка свойств символа. Эти свойства полностью описаны в [Базе данных символов Unicode (UCD)](http://www.unicode.org/reports/tr44/) и широко используются в компьютерной обработке текста, такой как поиск, сортировка, проверка орфографии и так далее. Файлы данных, перечисляющие свойства символов Unicode, также [доступны для загрузки](http://www.unicode.org/Public/UCD/latest/).

Среди свойств, присваиваемых каждому символу, самым важным для нашего обсуждения является *числовой идентификатор* присваиваемый его кодировкой Unicode; к этой теме мы сейчас и перейдем.

### Символы: числа и кодировки

Это очевидно, но компьютеры и другие цифровые устройства занимаются хранением и обработкой числовых данных: так как же это связано с текстом? Когда вы вводите текст с помощью компьютерной клавиатуры или касаясь экрана мобильного устройства, ваши нажатия клавиш преобразуются в числа, которые представляют строку символов, которую вы вводите.

В какой-то момент вы можете захотеть передать этот текст (последовательность чисел) по электронной почте, в текстовом сообщении или через онлайн-коммуникацию, такую как твит или публикация в какой-либо социальной сети. Очевидно, устройство, на котором вы составили текст, и устройство(а), используемое(ые) его получателем(ями), должны каким-то образом соглашаться, какие числа представляют какие символы. В противном случае ваш текст может отображаться на устройстве получателя некорректно.

Чтобы сегодняшняя глобальная связь работала, отправляющим и принимающим устройствам нужна некая «взаимно согласованная конвенция», посредством которой определенный набор чисел представляет конкретный набор символов. Это соглашение называется *кодировка*: набор чисел, используемый для представления определенного набора символов, и кодировка Unicode теперь является *де-факто* глобальным стандартом.

## Unicode: биты и байты для хранения текста

Unicode — это огромный стандарт, который охватывает гораздо, гораздо больше, чем просто кодирование текста, но здесь мы сосредотачиваемся только на предоставляемой им кодировке.

#### Биты, байты и сколько символов?

Мы упоминали, что устройства хранят и представляют текст как числа — точнее, символы будут храниться как целые числа: целые значения. Чтобы понять последствия этого для кодировки Unicode, нам нужен *очень* краткий, *очень* базовый обзор того, как компьютеры хранят целые числа (мы не собираемся углубляться в информатику).

Если коротко, современные настольные или портативные устройства хранят целые числа в дискретных «кусках», которые могут иметь длину 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.

На практике стандарт Unicode использует числа в диапазоне от 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) байт, так какого размера должна быть единица хранения, если нам нужно хранить значения вплоть до максимального значения Unicode 1,114,111? Очевидно, единица хранения размером в байт может содержать максимум 255, а 2 байта — 65535: ни того ни другого недостаточно для хранения полного диапазона символов, закодированных Unicode. Следующий доступный вариант — единицы хранения размером 4 байта, которые могут хранить целые числа до максимума 4,294,967,295, что намного больше, чем нам действительно нужно. Итак, если бы мы выбрали 4 байта в качестве единицы хранения, у нас, безусловно, было бы более чем достаточно места для хранения всех значений Unicode, при этом каждый символ хранился бы как целое число, требующее 4 байта (32 бита). Однако использовать 4 байта для хранения всего — крайне расточительно по объему, потому что даже самым большим значениям Unicode нужно максимум 21 бит — а это, если хранить их в 32 битах, означало бы, что 11 из этих 32 бит никогда не будут использованы.

**Примечание**: Хотя диапазон Unicode простирается от 0 до 1,114,111, не каждое значение в этом диапазоне фактически используется: по техническим причинам некоторые значения считаются недопустимыми для реального использования в качестве символов Unicode.

### Итак, что такое UTF-8?

Если вы читаете о XeTeX или LuaTeX, вы почти наверняка столкнетесь с объяснениями, которые утверждают, что эти движки TeX читают текст и входные файлы LaTeX в «формате UTF-8». Так что же такое «формат UTF-8» и как он связан с Unicode? На языке Unicode каждое из его 1,114,112 значений (от 0 до 1,114,111), используемых для кодирования символов мира, называется [кодовой точкой](http://www.unicode.org/glossary/#code_point).

Мы увидели, что, *в теории*, нам пришлось бы хранить весь наш текст, закодированный Unicode, используя 4 байта на символ, чтобы представить полный диапазон кодовых точек Unicode. Однако на практике некоторые весьма умные люди придумали простой способ представить одно число Unicode (кодовую точку) как *последовательность* последовательность меньших чисел, каждое из которых хранится в одном байте: процесс, который *преобразует* одно (большее) целое число в последовательность меньших (размером с байт) чисел. Из-за этого преобразования символы нашего текстового файла больше не представлены по отдельности одним числовым значением: каждый символ становится *многобайтовой последовательностью*—любые от 1 до 4 (последовательных) байт в текстовом файле могут представлять один отдельный символ Unicode (то есть значение его кодовой точки).

UTF означает *Unicode Transformation Format* и ключевое слово здесь — *Transformation*. По сути, UTF-8 можно рассматривать как «рецепт» или алгоритм преобразования одного значения кодовой точки Unicode в последовательность из 1–4 частей размером с байт. По мере увеличения значения кодовой точки Unicode увеличивается и число отдельных байтов, необходимых для представления его в формате UTF-8.

Для создания UTF-8 существуют технические и исторические причины, и история изобретения UTF-8 [записана в увлекательном электронном письме 2003 года](https://www.cl.cam.ac.uk/~mgk25/ucs/utf-8-history.txt), в котором в начале письма содержится строка:

> «Это неправда. UTF-8 был спроектирован у меня на глазах на салфетке в закусочной в Нью-Джерси одной ночью в сентябре 1992 года или около того».

#### Пример: арабская буква ل

Возьмем пример арабской буквы ل (имя Unicode: ARABIC LETTER LAM), которой присвоено значение кодовой точки Unicode 1604 (десятичное) или 0644 (шестнадцатеричное): ее представление в UTF-8 — это *двухбайтовая* последовательность D9 84 (hex) или, в десятичном виде, 217 132. При использовании UTF-8 в качестве формата хранения текста, вместо текстового файла, содержащего одно число 1604 для представления ل, оно преобразуется в два байтовых значения: 217 и 132 — символ ل хранится как *двухбайтовая последовательность*. Читатели, желающие подробнее изучить алгоритм UTF-8, могут найти подробное объяснение и код C на моем [личном блоге](http://www.readytext.co.uk/?p=1284).

Когда программное обеспечение (например, XeTeX или LuaTeX) читает текст в формате UTF-8, ему нужно определить значение Unicode для каждого символа, присутствующего в этом файле, поэтому оно использует алгоритм, чтобы *обратить* обратить процесс преобразования UTF-8. С помощью этого «обратного алгоритма» два байта (217 и 132) объединяются, чтобы получить целое число 1604, которое затем распознается как значение кодовой точки Unicode для арабской буквы ل.

Итак, в заключение, UTF-8 — это всего лишь промежуточный формат данных, используемый для хранения и передачи текста, закодированного Unicode.

**Примечание**: Некоторые системы предпочитают использовать/хранить текст, используя 32 бита на символ; это называется [UTF-32](https://en.wikipedia.org/wiki/UTF-32)— есть также [UTF-16](https://en.wikipedia.org/wiki/UTF-16) но UTF-8 — наиболее распространенный способ хранения текста, закодированного Unicode.

## Многоязычные TeX-файлы: XeTeX и LuaTeX

И XeTeX, и LuaTeX способны выполнять очень сложную многоязычную верстку, хотя их механизмы достижения этого довольно различны и отражают философию проектирования/разработки каждого движка. Мы не будем углубляться в это, а лишь отметим, что движок XeTeX содержит программные компоненты (встроенные в его исполняемый файл), которых нет в LuaTeX — в частности, программное обеспечение для процесса, называемого *шейпинг OpenType* (например, через библиотеку под названием [HarfBuzz](https://www.freedesktop.org/wiki/Software/HarfBuzz/)).

LuaTeX, напротив, придерживается иного подхода: вместо того чтобы встраивать средства непосредственно в сам движок TeX, LuaTeX предоставляет чрезвычайно богатый набор команд (примитивов TeX) и очень мощный [API на основе Lua](/latex/ru/podrobnye-stati/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 байт.

#### Углубляясь дальше

Если мы сохраним наш пример текста в файле UTF-8 под названием `arabic.txt` и откроем его в шестнадцатеричном редакторе, мы сможем изучить его и увидеть фактические байты, которые он содержит. Из анализа следующего аннотированного снимка экрана видно, что арабский текст хранится по 2 байта на символ:

![Текстовый файл UTF-8, содержащий английский и арабский текст, открыт в шестнадцатеричном редакторе.](/files/e1cf5fa0910d000439a4308423ca9462bbe6db27)

Текстовый файл UTF-8, содержащий английский и арабский текст, открыт в шестнадцатеричном редакторе. Ясно видно, что символы латинской письменности требуют одного байта, а символы арабской письменности хранятся по два байта на символ.

Из этого снимка экрана можно сделать пару наблюдений:

* арабский текст хранится в последовательности слева направо, а символы представляют собой необработанные, неоформленные (изолированные) версии арабских букв и огласовок;
* после текста латинской письменности «This is » нет дополнительной информации, которая сообщала бы любому программному обеспечению, читающему этот файл, что следующий символ относится к арабской письменности.

Если вы верстаете многоязычный документ (например, содержащий английский и арабский), то при чтении/обработке входного текстового файла (как потока байтов) XeTeX или LuaTeX должны уметь определять начало и конец каждого символа и читать правильное количество байтов, необходимых для обратного преобразования UTF-8 и получения соответствующей кодовой точки Unicode. Именно сам алгоритм UTF-8 позволяет программному обеспечению делать это: он позволяет обнаруживать первый байт каждого отдельного символа и определять, сколько байтов нужно прочитать, чтобы вычислить соответствующую кодовую точку Unicode. UTF-8 прост в использовании, но на самом деле весьма изобретателен.

#### Логический порядок, порядок отображения и шейпинг OpenType

Если вы внимательно посмотрите на арабский текст выше (العَرَبِيَّة), может быть трудно увидеть, что наш текстовый файл действительно содержит 12 отдельных арабских символов — особенно если вы не знакомы с арабской письменностью! Однако, если вы тщательно посчитаете арабские символы, отображаемые в правой части снимка экрана выше, вы увидите, что их всего 12.

Для языков с сложной письменностью, таких как арабский, то, что наш текстовый файл *сохраняет* и то, что вы *видите на экране* заметно *очень* различаются! То, что вы видите при просмотре этого текста, например, в браузере, — это (в зависимости от используемого шрифта):

![Изображение набранного арабского текста](/files/dc0307ac76d178229e9e6ad9dcdc122a7fa7ec2c)

Но, как показывает снимок экрана выше, то, что на самом деле содержит текстовый файл UTF-8, выглядит так:

![Изображение ненабранного арабского текста (изолированные символы)](/files/dd515486ec396bb37809ae5b215edddab0e95751)

Даже если вы не знакомы с курсивной природой арабской письменности, вы можете ясно видеть, что при переносе арабских символов, содержащихся в текстовом файле, в процесс верстки и/или отображения на экране (в виде глифов) произошло «что-то». Если вы привыкли использовать TeX/LaTeX с языками простой письменности, например с языками на латинской основе, это действительно может сильно сбивать с толку!

Здесь задействованы некоторые важные концепции, потому что текстовые файлы Unicode занимаются хранением… ну, текста (Unicode), а системы верстки и отображения — использованием шрифтов и глифов (OpenType):

* текстовый файл сохранил арабские символы в порядке слева направо, но арабский читается/отображается справа налево: текстовые файлы хранят текст в так называемом *логическом порядке*;
* текстовый файл содержит отдельные символы, которые выглядят совсем иначе, чем фактическое отображение на экране: текстовый файл содержит арабские символы в их изолированной, несоединенной форме.

#### Что происходит?

Внутри текстового файла арабский хранится как последовательность слева направо из символов в изолированной форме: если подумать, текстовый файл хранит арабский текст в порядке/последовательности *в которой он был набран* (буква *логическом порядке*). Лишь когда этот текст обрабатывается для отображения или верстки, он отображается в правильном порядке чтения, который часто называют *визуальным порядком* или *порядком отображения*; кроме того, изолированные формы арабских символов *формируются* в их типографически корректные отображаемые формы. Один из способов понять это — считать, что простой текстовый файл должен хранить текст (символы Unicode) в самой базовой форме: в виде необработанных, неоформленных отдельных текстовых символов; задача системного программного обеспечения — отображать эти символы на экране в зависимости от операционной системы, шрифтов и программного обеспечения для набора/рендеринга, доступных на устройстве отображения.

Когда арабский текст в этом файле набирается/отображается, он проходит процесс, называемый *формирование*. Отдельные арабские символы преобразуются в оформленные глифы, которые правильно представляют вариант каждого символа, требуемый согласно правилам соединения арабской письменности и системы письма. Кроме того, высококачественное программное обеспечение для набора текста (с использованием хороших шрифтов OpenType) добавляет дальнейшую обработку, применяя дополнительные типографические усовершенствования через процесс, называемый *шейпинг OpenType*— процесс, охватывающий широкий спектр типографических операций, которые могут включать:

* замену нескольких отдельных глифов одним сложным глифом лигатуры (очень часто в арабском письме), или
* операции позиционирования, которые, например, корректируют положения арабских гласных в зависимости от того, над каким или под каким глифом они находятся.

![Изображение, показывающее преобразование, которому подвергается арабский текст при его наборе](/files/947385a0983cf881a0ee07e23f1b30f285208169)

Разница между логическим порядком и визуальным (отображаемым) порядком. На этой схеме видно, что арабские символы, хранящиеся в текстовом файле, при отображении или наборе подвергаются переупорядочиванию и формированию глифов.

Дизайнеры и создатели продвинутых шрифтов OpenType вкладывают очень значительное время и опыт, чтобы предоставить сложные типографические возможности, встроенные в их шрифты.

Чтобы отключить формирование, применяемое к арабскому тексту, можно использовать отличный бесплатный [BabelPad](http://www.babelstone.co.uk/Software/BabelPad.html) Unicode-редактор текста (только для Windows), который позволяет отключить формирование, чтобы увидеть необработанные, отдельные, несоединённые (неоформленные) символы, фактически присутствующие в текстовом файле — см. нижнюю половину этого объединённого снимка экрана:

![Изображение, показывающее возможность текстового редактора BabelPad отключать формирование OpenType](/files/f81183ea2baac29cac014dadeb9bc82eac8becd9)

Использование Unicode-редактора текста 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/ru/podrobnye-stati/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.
