Русский язык в листингах кода (minted/listings) без ошибок компиляции
Почему возникает ошибка кириллицы в listings LaTeX
Каждый студент или разработчик при подготовке дипломного проекта
сталкивается с неприятным сбоем: при попытке скомпилировать исходный код с русскими
комментариями или строковыми литералами компилятор выдает сообщение вида ! Package
inputenc Error: Unicode character... или превращает слова в нечитаемые кракозябры. Это
классическая ошибка кириллицы в listings latex.
Причина кроется в архитектуре классического движка
pdfLaTeX: пакет listings обрабатывает текст побайтово как 8-битный
поток ASCII, тогда как русские символы в кодировке UTF-8 состоят из двух байтов. В результате
парсер кода разрывает двухбайтовую последовательность, что приводит к фатальной ошибке
компиляции. Если в вашей работе код описывает сложные структуры, рекомендуем также ознакомиться
с версткой псевдокода алгоритмов в
algorithm2e.
Русский язык в листингах кода LaTeX: правильная настройка listings
Параметры inputencoding и extendedchars
часто ставят первыми, но в pdfLaTeX их недостаточно для кириллицы внутри
lstlisting. Рабочий способ — таблица literate ниже. Для полноты
преамбула может выглядеть так:
\usepackage{listings}
\usepackage{xcolor}
\lstset{
inputencoding=utf8,
extendedchars=true,
basicstyle=\ttfamily\small,
breaklines=true,
numbers=left,
numberstyle=\tiny\color{gray},
frame=single,
captionpos=b,
keepspaces=true,
showstringspaces=false
}
Если вы хотите экранировать русские фрагменты или формулы прямо
внутри кода, добавьте директиву escapeinside:
\lstset{escapeinside={(*@}{@*)}}
\begin{lstlisting}[language=Python]
def calculate_sum(a, b):
# (*@\textbf{Вычисление суммы двух чисел}@*)
return a + b
\end{lstlisting}
Символьная таблица literate для полного охвата русского алфавита
Наиболее надежный способ заставить listings в
pdfLaTeX понимать русский текст без экранирования — передать маппинг кириллических
букв через свойство literate:
\lstset{
literate=
{а}{{\cyra}}1 {б}{{\cyrb}}1 {в}{{\cyrv}}1 {г}{{\cyrg}}1
{д}{{\cyrd}}1 {е}{{\cyre}}1 {ж}{{\cyrzh}}1 {з}{{\cyrz}}1
{и}{{\cyri}}1 {й}{{\cyrishrt}}1 {к}{{\cyrk}}1 {л}{{\cyrl}}1
{м}{{\cyrm}}1 {н}{{\cyrn}}1 {о}{{\cyro}}1 {п}{{\cyrp}}1
{р}{{\cyrr}}1 {с}{{\cyrs}}1 {т}{{\cyrt}}1 {у}{{\cyru}}1
{ф}{{\cyrf}}1 {х}{{\cyrh}}1 {ц}{{\cyrc}}1 {ч}{{\cyrch}}1
{ш}{{\cyrsh}}1 {щ}{{\cyrshch}}1 {ъ}{{\cyrhrdsn}}1 {ы}{{\cyrery}}1
{ь}{{\cyrsftsn}}1 {э}{{\cyrerev}}1 {ю}{{\cyryu}}1 {я}{{\cyrya}}1 {ё}{{\cyryo}}1
{А}{{\CYRA}}1 {Б}{{\CYRB}}1 {В}{{\CYRV}}1 {Г}{{\CYRG}}1
{Д}{{\CYRD}}1 {Е}{{\CYRE}}1 {Ж}{{\CYRZH}}1 {З}{{\CYRZ}}1
{И}{{\CYRI}}1 {Й}{{\CYRISHRT}}1 {К}{{\CYRK}}1 {Л}{{\CYRL}}1
{М}{{\CYRM}}1 {Н}{{\CYRN}}1 {О}{{\CYRO}}1 {П}{{\CYRP}}1
{Р}{{\CYRR}}1 {С}{{\CYRS}}1 {Т}{{\CYRT}}1 {У}{{\CYRU}}1
{Ф}{{\CYRF}}1 {Х}{{\CYRH}}1 {Ц}{{\CYRC}}1 {Ч}{{\CYRCH}}1
{Ш}{{\CYRSH}}1 {Щ}{{\CYRSHCH}}1 {Ъ}{{\CYRHRDSN}}1 {Ы}{{\CYRERY}}1
{Ь}{{\CYRSFTSN}}1 {Э}{{\CYREREV}}1 {Ю}{{\CYRYU}}1 {Я}{{\CYRYA}}1 {Ё}{{\CYRYO}}1
}
После включения этой таблицы можно писать русские комментарии, включая букву «ё»: без неё в таблице literate эта буква по-прежнему ломает сборку.
Пакет minted с поддержкой UTF-8: только локальная сборка
Более современная альтернатива listings — пакет
minted. Он использует мощный лексер Pygments, нативно поддерживает
Unicode и оформляет код так же красиво, как современные IDE:
\usepackage{minted}
\usemintedstyle{friendly}
\begin{minted}[
frame=lines,
framesep=2mm,
linenos,
fontsize=\small
]{python}
# Функция расчета факториала на русском языке
def factorial(n: int) -> int:
if n <= 1:
return 1
return n * factorial(n - 1)
print("Результат вычисления:", factorial(5))
\end{minted}
Обратите внимание: minted запускает внешнюю
программу — Python с библиотекой Pygments, поэтому для локальной сборки нужен флаг компиляции
-shell-escape. В Labkeeper minted не работает: серверная сборка запрещает запуск
внешних программ, и пакет останавливается с ошибкой minted executable is unavailable or
disabled. Используйте listings с таблицей literate из раздела
выше.
Движки XeLaTeX и LuaLaTeX при локальной сборке
Если у вас есть возможность переключить компилятор с
pdfLaTeX на XeLaTeX или LuaLaTeX, проблема с кодировками
исчезает полностью. Благодаря пакету fontspec движок нативно работает с кодировкой
UTF-8 и системными шрифтами OpenType/TrueType. Этот способ подходит только для локальной сборки:
в Labkeeper работает pdfLaTeX, и блок с fontspec остановит компиляцию с ошибкой
fontspec requires XeTeX or LuaTeX.
\usepackage{fontspec}
\setmainfont{Times New Roman}
\setmonofont{Courier New} % или Fira Code
\usepackage{listings}
\lstset{
basicstyle=\ttfamily\small,
breaklines=true
}
Для интерактивного перехода к нужным листингам из текста работы не забудьте ознакомиться с настройкой кликабельных ссылок hyperref.
Частые вопросы и рекомендации по ГОСТ
Требования к листингам задают методические указания вуза; для программной документации ориентиром служит ГОСТ 19.401-78 «Текст программы». Обычно листинги кода в дипломе оформляют так:
- Шрифт моноширинный: используйте Courier New или PT Mono кеглем 10–12 pt;
- Подпись к листингу: размещается снизу или сверху с единообразным выравниванием («Листинг 3.1 — Метод авторизации пользователя»);
- Перенос строк: обязательно включите
breaklines=true, чтобы длинные строки кода не вылезали за границы правого поля.
Практические советы
Компактные листинги в приложении
Длинные портянки кода объемом более 1 страницы по требованиям большинства методичек выносят в «Приложения», оставляя в основном тексте только фрагменты ключевых алгоритмов на 15–30 строк.
Листинги в автоматической преамбуле Labkeeper
Если в проекте нет своей преамбулы, Labkeeper подставляет автоматическую, в которой уже есть
listings и кодировка T2A. Достаточно добавить в LaTeX-сегмент команду
\lstset с таблицей literate: строка \usepackage в обычном
сегменте отключила бы автоматическую преамбулу целиком.