Открыть сервис

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 состоит из нескольких этапов:

  1. Подготовка исходного кода: разработчик помечает строки, подлежащие переводу, с помощью макроса _() или функции gettext(). Например: printf(gettext("Hello, world!"));.
  2. Извлечение строк: запускается утилита xgettext, которая сканирует исходный код и создаёт файл шаблона messages.pot.
  3. Создание файла перевода: для каждого языка (например, русского) запускается msginit -l ru_RU -i messages.pot, который создаёт файл ru.po.
  4. Перевод: переводчик редактирует файл .po вручную или с помощью специализированных редакторов (например, Poedit, Gtranslator, Lokalize). Он заполняет поле msgstr для каждой строки.
  5. Компиляция: после завершения перевода файл .po компилируется в .mo с помощью msgfmt -o ru.mo ru.po.
  6. Установка: скомпилированный файл .mo помещается в каталог, где библиотека libintl может его найти (обычно /usr/share/locale/ru/LC_MESSAGES/).
  7. Запуск программы: при запуске программы библиотека 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 →