В вычислительной технике gettext — это система интернационализации и локализации (i18n и l10n), обычно используемая для написания многоязычных программ в операционных системах Unix-подобных компьютеров . Одним из главных преимуществ gettext является то, что она разделяет программирование и перевод. [4] Наиболее часто используемая реализация gettext — GNU gettext , [5] выпущенная проектом GNU в 1995 году. Библиотека времени выполнения — libintl . gettext предоставляет возможность использовать разные строки для любого количества форм множественного числа существительных, но эта функция не поддерживает грамматический род . Основные расширения имен файлов, используемые этой системой, — .POT (Portable Object Template), .PO (Portable Object) и .MO (Machine Object). [6]
Первоначально POSIX не предоставлял никаких средств локализации сообщений. В конце 1980-х годов было выдвинуто два предложения: Uniforum gettext 1988 года и X/Open catgets (XPG-3 § 5) 1989 года. Sun Microsystems реализовала первый gettext в 1993 году. [1] Разработчики Unix и POSIX так и не пришли к согласию относительно того, какой интерфейс использовать (другой вариант — X/Open catgets), поэтому многие библиотеки C , включая glibc , реализовали оба. [7] По состоянию на август 2019 года [обновлять]вопрос о том, должен ли gettext быть частью POSIX, все еще оставался предметом споров в Austin Group , несмотря на то, что его старый враг уже вышел из употребления. В число упомянутых проблем входила его зависимость от системной локали ( глобальная переменная, подверженная проблемам многопоточности) и поддержка новых расширений языка C, включающих широкие строки. [8]
Проект GNU решил, что подход gettext «сообщение как ключ» проще и дружелюбнее. (Большинство других систем, включая catgets, требуют, чтобы разработчик придумывал имена «ключей» для каждой строки.) [9] Они выпустили GNU gettext, свободное программное обеспечение , реализующее систему в 1995 году. [2] Gettext, GNU или нет, с тех пор был портирован на многие языки программирования. [10] Простота po и широкая поддержка редакторов даже привели к его принятию в непрограммных контекстах для текстовых документов или в качестве промежуточного звена между другими форматами локализации, с появлением конвертеров, таких как po4a (po для чего угодно) и Translate Toolkit, которые стали таким мостом. [11] [12]
Базовый интерфейс gettext — это gettext(const char*)
функция, которая принимает строку , которую пользователь увидит на исходном языке, обычно английском. Чтобы сэкономить время набора текста и уменьшить беспорядок в коде, эта функция обычно имеет псевдоним_
: [13]
printf ( gettext ( "Меня зовут %s. \n " ), my_name ); printf ( _ ( "Меня зовут %s. \n " ), my_name ); // то же самое, но короче
gettext()
затем использует предоставленные строки как ключи для поиска переводов и возвращает исходную строку, если перевод недоступен. Это контрастирует с POSIX catgets()
, [14] AmigaOS GetString()
, [15] или Microsoft Windows LoadString()
, где используется программный идентификатор (часто целое число). Для обработки случая, когда один и тот же текст на исходном языке может иметь разные значения, gettext имеет такие функции, cgettext()
которые принимают дополнительную строку «контекста».
xgettext
запускается на источниках для создания .pot
файла (Portable Object Template), который содержит список всех переводимых строк, извлеченных из источников. Комментарии, начинающиеся с , ///
используются для предоставления подсказок переводчикам, хотя другие префиксы также можно настроить для дальнейшего ограничения области действия. Одним из таких распространенных префиксов является TRANSLATORS:
.
Например, входной файл с комментарием может выглядеть так:
/// ПЕРЕВОДЧИКИ: %s содержит имя пользователя, указанное в настройках printf ( _ ( "Меня зовут %s. \n " ), my_name );
xgettext
запускается с помощью команды:
xgettext -c /
Результирующий файл .pot выглядит следующим образом с комментарием (обратите внимание, что xgettext распознает строку как строку формата printf на языке C ):
#. ПЕРЕВОДЧИКИ: %s содержит имя пользователя, как указано в настройках #, c-формат #: src/name.c:36 msgid "Меня зовут %s.\n" msgstr ""
В сценарии оболочки POSIX gettext предоставляет gettext.sh
библиотеку, которую можно включить, которая предоставляет множество тех же функций, которые gettext предоставляет в похожих языках. [16] GNU bash также имеет упрощенную конструкцию $"msgid"
для простой функции gettext, хотя она зависит от библиотеки C для предоставления gettext()
функции. [17]
Переводчик извлекает .po
файл (Portable Object) из шаблона с помощью msginit
программы, затем заполняет переводы. [18] msginit
инициализирует переводы, так, например, для перевода на французский язык команда для запуска будет следующей: [6]
msginit --locale=fr --input=name.pot
Это создаст fr.po
. Затем переводчик редактирует полученный файл вручную или с помощью инструмента перевода, например Poedit , или Emacs с его режимом редактирования .po
файлов. Отредактированная запись будет выглядеть так:
#: src/name.c:36 msgid "Меня зовут %s.\n" msgstr "Меня зовут %s.\n"
Наконец, файлы .po компилируются в msgfmt
двоичные .mo
файлы (Machine Object). GNU gettext может использовать собственное расширение имени файла .gmo
в системах с другой реализацией gettext. [19] Теперь они готовы к распространению с программным пакетом.
GNU msgfmt
также может выполнять некоторые проверки, относящиеся к строке формата, используемой языком программирования. Он также позволяет выводить данные в форматы, специфичные для языка, отличные от MO; [20] эквивалент X/Open — gencat
.
На более поздних этапах рабочего процесса разработки msgmerge
может использоваться для «обновления» старого перевода на новый шаблон. Также есть msgunfmt
для обратной компиляции .mo
файлов и многих других утилит для пакетной обработки.
Пользователь в системах типа Unix устанавливает переменную окружения LC_MESSAGES
, и программа будет отображать строки на выбранном языке, если .mo
для этого существует файл.
Пользователи вариантов GNU также могут использовать переменную окружения LANGUAGE
вместо этого. Ее главное отличие от переменной Unix заключается в том, что она поддерживает несколько языков, разделенных двоеточием, для отката. [21]
Интерфейс ngettext()
учитывает количество существительных в строке. Как и в случае с соглашением gettext()
, на практике его часто называют псевдонимом N_
. Рассмотрим пример кода:
// параметры: английское единственное число, английское множественное число, целочисленное количество printf ( ngettext ( "%d переведенное сообщение" , "%d переведенные сообщения" , n ), n );
Заголовок в ""
записи (пустая строка) файла PO хранит некоторые метаданные, одним из которых является форма множественного числа, используемая в языке, обычно указываемая с помощью тернарного оператора в стиле C. Предположим, мы хотим сделать перевод для словенского языка :
msgid "" msgstr "" "..." " Язык: sl\n" " Формы множественного числа: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n%100==4 ? 3 : 0);\n"
Поскольку теперь существует четыре формы множественного числа, окончательное po будет выглядеть так:
#: src/msgfmt.c:876 #, c-format msgid "%d переведенное сообщение" msgid_plural " % d переведенное сообщение" msgstr[ 0 ] "%d преведено спорочил" msgstr [ 1 ] "%d преведено спорочило" msgstr[ 2 ] "%d преведена спорочила" msgstr[ 3 ] " %d преведена спорочила"
Справочные правила множественного числа для языков предоставлены консорциумом Unicode . [22] msginit также предварительно заполняет соответствующее правило при создании файла для одного конкретного языка. [18]
Помимо C , gettext имеет следующие реализации: C# для ASP.NET [23] [24] и для WPF , [25] Perl , [26] PHP , [27] Python , [ 28] R , [29] Scala , [30] и Node.js. [31]
GNU gettext имеет встроенную поддержку Objective-C, но пока нет поддержки языка программирования Swift . Обычно используемая реализация gettext на этих платформах Cocoa — POLocalizedString. [32] Команда Microsoft Outlook для iOS также предоставляет библиотеку LocalizedStringsKit с API, похожим на gettext. [33]
{{cite web}}
: CS1 maint: неподходящий URL ( ссылка )