GNU gettext
GNU gettext — это набор инструментов и библиотек для интернационализации и локализации программного обеспечения, разработанный в рамках проекта GNU. Он предоставляет разработчикам единый механизм для извлечения текстовых строк из исходного кода, их перевода и последующей подстановки переведённых версий в работающую программу без необходимости изменения самого кода. gettext является де-факто стандартом интернационализации в Unix-подобных операционных системах и широко используется в свободном и открытом программном обеспечении, а также в коммерческих проектах.
История
Проект gettext был начат в 1990 году немецким программистом Ульрихом Дреппером (Ulrich Drepper) как часть пакета GNU C Library (glibc). Целью было создание системы, которая бы упростила и стандартизировала процесс локализации программ, избавив разработчиков от ручного управления переводами. Первая стабильная версия, GNU gettext 1.0, была выпущена в 1995 году. Впоследствии проект развивался, в него были добавлены поддержка различных языков программирования (C, C++, Python, Java, Perl, Ruby, PHP и другие), а также инструменты для работы с переводами. В 2000-х годах gettext стал основным инструментом интернационализации для многих проектов, включая GNOME, KDE, WordPress и Drupal. В 2010-х годах была добавлена поддержка формата PO (Portable Object) и его бинарного варианта MO (Machine Object), а также улучшена работа с контекстами и множественными числами.
Архитектура и принцип работы
Система gettext основана на трёх ключевых компонентах: библиотеке libintl, инструментах командной строки и файлах переводов.
Библиотека libintl
Библиотека libintl предоставляет функции для замены текстовых строк в работающей программе. Основная функция — gettext(), которая принимает на вход строку на языке оригинала (обычно английском) и возвращает её перевод на язык, установленный в системе пользователя. Для поддержки множественных чисел используется функция ngettext(), а для учёта контекста — pgettext(). Библиотека автоматически определяет язык пользователя через переменные окружения, такие как LANG, LC_ALL или LC_MESSAGES.
Инструменты командной строки
Набор инструментов включает несколько утилит, которые автоматизируют процесс локализации:
- xgettext — извлекает все строки, помеченные для перевода, из исходного кода на различных языках программирования и создаёт файл шаблона перевода (
.pot). - msginit — создаёт начальный файл перевода (
.po) для конкретного языка на основе шаблона. - msgmerge — обновляет существующий файл перевода при изменении исходного кода, добавляя новые строки и удаляя устаревшие.
- msgfmt — компилирует файл
.poв бинарный файл.mo, который используется библиотекой libintl для быстрого поиска переводов. - msgfmt --check — проверяет файл перевода на наличие синтаксических ошибок и несоответствий.
Файлы переводов
Файлы переводов имеют два основных формата:
- PO (Portable Object) — текстовый файл, содержащий пары «оригинал — перевод» с метаданными (например, комментарии переводчика, контекст, дата последнего изменения). Каждая запись может включать несколько вариантов для множественных чисел.
- MO (Machine Object) — бинарный файл, скомпилированный из PO. Он оптимизирован для быстрого поиска и используется в работающей программе.
Процесс локализации
Типичный процесс локализации с использованием gettext состоит из нескольких этапов:
- Подготовка исходного кода: разработчик помечает строки, подлежащие переводу, с помощью макроса
_()или функцииgettext(). Например:printf(gettext("Hello, world!"));. - Извлечение строк: запускается утилита
xgettext, которая сканирует исходный код и создаёт файл шаблонаmessages.pot. - Создание файла перевода: для каждого языка (например, русского) запускается
msginit -l ru_RU -i messages.pot, который создаёт файлru.po. - Перевод: переводчик редактирует файл
.poвручную или с помощью специализированных редакторов (например, Poedit, Gtranslator, Lokalize). Он заполняет полеmsgstrдля каждой строки. - Компиляция: после завершения перевода файл
.poкомпилируется в.moс помощьюmsgfmt -o ru.mo ru.po. - Установка: скомпилированный файл
.moпомещается в каталог, где библиотека libintl может его найти (обычно/usr/share/locale/ru/LC_MESSAGES/). - Запуск программы: при запуске программы библиотека libintl определяет язык пользователя и загружает соответствующий файл
.mo, заменяя все строки на переведённые.
Поддержка множественных чисел
Одной из ключевых особенностей gettext является поддержка множественных чисел, что особенно важно для языков с различными формами числа (например, в русском языке: «1 файл», «2 файла», «10 файлов»). Функция ngettext() принимает три аргумента: строку для единственного числа, строку для множественного числа и само число. На основе числа и правил языка, заданных в файле перевода, выбирается правильная форма. Правила множественных чисел для каждого языка описываются в заголовке файла .po с помощью директивы Plural-Forms.
Критика и ограничения
Несмотря на широкое распространение, gettext имеет ряд недостатков:
- Сложность настройки: для использования gettext требуется интеграция в процесс сборки проекта, что может быть нетривиально для новичков.
- Зависимость от файловой системы: gettext требует наличия установленных файлов
.moв определённых каталогах, что может быть проблемой для встраиваемых систем или веб-приложений. - Отсутствие поддержки контекста по умолчанию: до появления функции
pgettext()переводчики не могли различать одинаковые строки в разных контекстах (например, «File» как имя файла и как глагол). - Проблемы с кодировками: в ранних версиях gettext возникали проблемы с поддержкой Unicode, которые были решены только в более поздних версиях.
- Неэффективность для больших проектов: при наличии тысяч строк переводов файлы
.poмогут становиться большими и медленно обрабатываться.
Применение
GNU gettext используется в тысячах проектов, включая:
- Операционные системы: GNU/Linux, BSD, macOS (частично).
- Среды рабочего стола: GNOME, KDE, Xfce.
- Веб-приложения: WordPress, Drupal, Joomla, MediaWiki.
- Инструменты разработки: Git, GCC, Python, PHP.
- Игры и мультимедиа: GIMP, Inkscape, Blender.
Интересные факты
- Название «gettext» происходит от одноимённой функции, которая, в свою очередь, была названа в честь более ранней системы
catgetsиз AT&T Unix. - Формат PO был разработан как замена более сложному формату
catgetsи стал популярным благодаря своей простоте и читаемости. - В 2012 году была выпущена версия 0.18.2, которая добавила поддержку формата JSON для веб-приложений.
- Существуют альтернативные реализации gettext, такие как
libintl-perlдля Perl иgettext.jsдля JavaScript.
Источники
- Drepper, U. (1995). GNU gettext: The GNU Translation Project. Free Software Foundation.
- Free Software Foundation. (2023). GNU gettext Manual. Version 0.21.1.
- Stallman, R. (2002). GNU Coding Standards. Free Software Foundation.
- Официальная документация проекта GNU gettext (gnu.org/software/gettext).
BFOmetr — база данных и аналитика по компаниям России.
На главную BFOmetr →