> 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/05-an-introduction-to-endlinechar-how-tex-reads-lines-from-text-files.md).

# Введение в \\\endlinechar: как TeX читает строки из текстовых файлов

Как люди, мы предпочитаем просматривать и редактировать текстовые файлы построчно. Когда нам кажется, что строка текста достаточно длинная, мы нажимаем «Enter» (в текстовом редакторе), чтобы обозначить конец этой строки. Внутри ваш текстовый редактор интерпретирует это как указание добавить [символ новой строки](https://en.wikipedia.org/wiki/Newline) в том месте, где вы решаете разорвать строку.

Однако, если бы всё было так просто: проблема в том, что разные операционные системы по-разному понимают, что считается символом новой строки. Более того, Windows будет обрабатывать символы новой строки по-разному в зависимости от того, открыт ли файл в так называемом [*двоичном режиме* или *текстовом режиме*](https://docs.microsoft.com/en-us/cpp/c-runtime-library/text-and-binary-mode-file-i-o?view=vs-2017). В результате, в зависимости от операционной системы-хоста, строки в текстовом файле могут завершаться разными комбинациями символов, называемыми *возврат каретки* (символ ASCII/Юникода 13) и *перевод строки* (символ ASCII/Юникода 10): обозначаемые соответственно как `\r` и `\n` соответственно.

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

### Входной буфер TeX

Возможно, вас удивит или нет, узнать, что движки TeX (включая LuaTeX и XeTeX) читают входные файлы построчно: они не загружают весь текстовый файл целиком в память. Хотя большинство текстовых файлов, обрабатываемых движками TeX, ничтожно малы по сравнению с доступной памятью на современных устройствах, каждая строка в файле считывается и хранится отдельно в небольшом внутреннем буфере. Но, разумеется, процесс чтения и сохранения строки в TeX имеет несколько дополнительных особенностей.

## «Я сделаю это по-своему» — команда \endlinechar в TeX

Когда TeX читает очередную строку текста из входного файла, он выполняет две «служебные операции»:

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

Эти два процесса происходят до того, как TeX фактически начинает разбирать символы, содержащиеся в самой строке: думайте о них как о форме «служебной обработки» в подготовке к следующему этапу обработки (разбору). Итак, на этой начальной стадии процесса чтения строк TeX уже удалил все зависящие от платформы окончания строк (и любые завершающие пробелы): так как же TeX узнает (определит), где заканчивается эта строка? У TeX есть ещё один «трюк» в запасе: `\endlinechar` команды.

Чтобы избежать проблемы символов новой строки, зависящих от платформы, TeX вводит понятие `\endlinechar`, параметра, задаваемого пользователем, который TeX использует, чтобы вставить собственный символ конца строки в самый конец строки текста, только что прочитанной из файла. Заметьте ещё раз, что это происходит до того, как TeX фактически начинает разбирать символы — это заключительный шаг служебной обработки TeX перед тем, как он будет готов начать читать (разбирать) реальные символы, содержащиеся в строке.

TeX будет использовать значение, хранящееся в `\endlinechar` для добавления собственного завершающего символа конца строки, если и только если `\endlinechar` определён надлежащим образом — в TeX Кнута это означает, что он должен иметь значение >-1 и < 256. Обычно `\endlinechar` присваивается значение 13: символ возврата каретки — обычно обозначаемый как `\r` в программной литературе.

Но если вы напишете `\endlinechar=-1` где-либо в вашем вводе, то *при следующем* раз TeX прочитает строку текста из файла, он не будет *не* добавлять какой-либо дополнительный завершающий символ в конец строки. Следовательно, ваш ввод будет обрабатываться как одна длинная непрерывная строка текста, пока вы не сбросите `\endlinechar` до подходящего значения — обычно 13 (`\r`):

```latex
\endlinechar=13
```

Один из 16 кодов категорий TeX (значение 5) зарезервирован для обозначения символа «конца строки», который обычно является символом, который `\endlinechar` вставляет TeX, — который вставляется, если (и только если) значение `\endlinechar` установлено в подходящее значение.

## Сводка обработки конца строки

Хотя эти детали довольно низкоуровневые, они будут интересны любому, кто хочет изучить написание макросов, работающих с чтением строк текста.

1. Когда TeX читает строку из вашего файла, он сначала удаляет все символы конца строки (`\r` и `\n`) добавленные вашим текстовым редактором при сохранении файла. Кроме того:

* TeX также удаляет любые пробельные символы в конце строки;
* TeX *не* удаляет завершающие символы табуляции (ASCII-код символа 9).

**Примечание**: Один из файлов исходного кода LuaTeX, тот, в котором есть код для выполнения этого удаления пробелов, содержит следующую заметку:

> (Цитируется в файле `luatex.c`) «Дэвид Фукс упоминает, что это \[удаление] пробелов было сделано, чтобы обеспечить переносимость документов TeX с учётом заполнения пробелами фиксированных “строк” на некоторых системах того времени, например IBM VM/CMS и OS/360.»

3. После шага (1) TeX добавляет (вставляет) дополнительный символ, значение которого хранится в \endlinechar (при условии, что он задан надлежащим образом: >-1 и < 256)
4. \endlinechar обычно устанавливается в значение 13 (`\r`), что означает, что символ, добавленный на шаге (2), обычно является символом 13 (`\r`) — но, разумеется, вы можете установить \endlinechar в другое значение, чтобы добиться особых эффектов посредством программирования макросов.
5. Когда его процедуры сканирования ввода обнаруживают символ `\r` (код символа 13) в конце внутреннего буфера, TeX, как обычно, проверяет его код категории, чтобы решить, что с ним делать.
6. Символ 13 *обычно* имеет значение кода категории 5 («конец строки»), если, конечно, его код категории не был изменён — некоторые макросы делают символ конца строки активным, чтобы выполнять сложную обработку.
7. В зависимости от внутреннего состояния TeX (по сути, от того, что он делает) TeX может преобразовать символ конца строки (обычно `\r`, код категории 5) в символ пробела — именно так символы конца строки становятся пробелами.
8. Заметьте также, что TeX использует символы с кодом категории 5, чтобы определить, когда он прочитал пустую строку и ему нужно сгенерировать `\par` токен.

Следующая иллюстрация даёт наглядную сводку шагов (1) и (2): удаление символов новой строки и завершающих пробелов и вставка `\endlinechar` готово к задаче разбора входных данных.

![Как TeX использует \endlinechar](/files/63281bc94235680a5de95555fbebfff070fc4ed2)


---

# 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/05-an-introduction-to-endlinechar-how-tex-reads-lines-from-text-files.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.
