Как использовать I18N с помощью gettext

Интернационализация (i18n) относится к поддержке приложения / пакета на нескольких языках. Эта поддержка происходит из своего рода обобщения части приложения / пакета, которая помогает локализовать его на разных языках.

Локализация или (l10n) здесь относится к процессу адаптации, перевода или настройки этого приложения / пакета для конкретной локали.

Локаль - это термин, используемый для определения набора информации, соответствующей данному языку и стране. Информация о локали используется программным приложением (или операционной системой) для демонстрации локализованного поведения. Это локализованное поведение имеет форму отображения текста приложения / пакета на местном языке или других вещей, относящихся к региональному соглашению, таких как локализованная дата, формат валюты, цветовые соглашения и т.д.

В этом уроке мы рассмотрим i18n & l10n только относительно текста i18n / l10n.

Фреймворк Gettext - один из таких подходов к тексту i18n. Это относится к набору инструментов, которые используются для интернационализации и локализации приложения / пакета. Помимо интернационализации приложений / пакетов, эти инструменты помогают переводить строки в меню, окнах сообщений или значках приложений на языке, который интересует пользователя.

Для получения подробной информации об интернационализации текста вы можете обратиться к руководству Gettext.

Мы предполагаем, что вы используете emacs. Сделайте следующее:

  1. Запустите Emacs
  2. Печатайте ALT + х
  3. Введите ansi-term в нижнем окне
  4. Нажмите клавишу Return дважды один за другим

Среда разработки

Для интернационализации приложения нам нужен набор инструментов разработки. Это единовременная установка, требующая запуска этих команд из учетной записи администратора системы (root):

yum install @development-tools
yum install @<langname>-support

выше относится к названию вашего языка. Для хинди я бы написал что-то вроде:

yum install @hindi-support

Hello World

Давайте напишем нашу первую программу Hello World:

#include<stdio.h>

int main()
{
    printf("Hello World\n");
    return 0;
}

Интернациализация Hello World

Вывод, созданный последней программой, полностью на английском языке. Теперь, чтобы сделать его локализуемым на разных языках, нам нужно каким-то образом его обобщить / интернационализировать, чтобы при выборе пользователем конкретной локали приложение переключало свои строки / вывод на язык, описанный этой локалью. Например, если я выбрал локаль hi_IN.UTF-8 (hi-> Hindi; IN-> India; encoding-> UTF-8), выходные данные / строки этого приложения должны отображаться на хинди.

Это делается с использованием концепции каталога сообщений, который представляет собой базу данных строк в каком-либо файле. Gettext поддерживает каталоги сообщений в виде файлов MO (.mo). Эти файлы MO являются двоичными файлами, в которых хранятся строки для разных приложений для разных локалей. Когда приложение запускается, все строки извлекаются из файла (ов) MO приложения на основе определенной локали. Это извлечение во время выполнения выполняется с использованием функций gettext, описанных в каркасе gettext.

Теперь, если мы интернационализируем нашу программу Hello World, используя gettext, она будет выглядеть примерно так:

#include<libintl.h>
#include<locale.h>
#include<stdio.h>

#define _(String) gettext (String)

int main()
{
    setlocale(LC_ALL,"");
    bindtextdomain("helloworld","/usr/share/locale");
    textdomain("helloworld");
    printf(_("Hello World\n"));
    return 0;
}

В этой программе функция gettext (строка формата c) отвечает за извлечение (для Hello World\n на английском языке) эквивалентной переведенной строки (नमस्कार दुनिया \n на хинди) во время выполнения, в локальном сценарий языка, описываемого локалью (например, hi_IN.UTF-8 для хинди, принадлежащего стране Индия). Общая практика заключается в использовании макросов типа _(String) вместо gettext(String), чтобы уменьшить количество печатаемых букв.

Локализация Hello World

Создайте новый каталог с именем po/

mkdir po

Извлеките строки в файл POT (helloworld.pot), используя следующую команду

xgettext --from-code=utf-8 -d helloworld -o po/helloworld.pot -k_ -s helloworld.c

Новый файл helloworld.pot будет создан внутри каталога po/

helloworld.pot:

# SOME DESCRIPTIVE TITLE.
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-04-27 17:42+0530\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"

#: helloworld.c:13
#, c-format
msgid "Hello World\n"
msgstr ""

Файл POT (.pot) обозначает файл шаблона переносимого объекта и содержит пару строк в паре, начиная с ключевых слов msgid и msgstr соответственно. В приведенном выше примере только одна такая пара & msgid показана первой, за которой следует строка на исходном языке, за которой следует msgstr в следующей строке, за которой сразу следует пустая строка.

Теперь, чтобы перевести приложение, эти файлы POT копируются как файлы PO (.po) в соответствующие языковые папки, а затем переводятся. Под переводом я подразумеваю, что для каждой строки, смежной с msgid, есть переведенная строка (в локальном скрипте), смежная с msgstr. Для хинди это будет выглядеть примерно так:

msgid "Hello World"
msgstr "नमस्कार दुनिया\n"

Теперь создайте каталог с названием вашего языка. Это название языка, вероятно, должно быть двухзначным / трехзначным кодом, указанным для вашего языка в ISO 639-1. Используйте http://www.loc.gov/standards/iso639-2/php/code_list.php для справки. Каталог с таким же именем также должен быть указан в каталоге /usr/share/locale. Для хинди я бы сделал это так:

mkdir hi/
cp helloworld.pot hi/helloworld.po

Откройте редактор по вашему выбору и переведите файл следующим образом:

# Hello World Localization.
# Copyright (C) 2010 Naveen Kumar
# This file is distributed under the same license as the PACKAGE package.
# Naveen Kumar <nkumar@redhat.com>, 2010.
#
msgid ""
msgstr ""
"Project-Id-Version: helloworld 1.0\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-04-27 18:31+0530\n"
"PO-Revision-Date: 2010-04-27 18:53+0530\n"
"Last-Translator: Naveen Kumar <nkumar@redhat.com>\n"
"Language-Team: Hindi <LL@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"

#: helloworld.c:13
#, c-format
msgid "Hello World\n"
msgstr "नमस्कार दुनिया\n"

Теперь для перевода вы можете использовать метод ввода, который позволяет использовать стандартную клавиатуру для ввода собственного сценария. Наиболее распространенные используемые методы ввода - это iBus, SCIM, UIM и т. Д. Вы можете скачать любой из них, используя yum. Для iBus я бы сделал что-то вроде

yum install ibus ibus-table*

А затем выберите сценарий / язык, которым вы желаете напечатать перевод.

Компилирование и запуск локализованного Hello World

создайте файл MO (.mo), используя следующую команду:

msgfmt helloworld.po -o helloworld.mo

В режиме root скопируйте файл MO в /usr/share/locale/hi/LC_MESSAGES. Для хинди я бы сделал что-то вроде этого:

сp helloworld.mo /usr/share/locale/hi/LC_MESSAGES/

Скомпилируйте ваш файл C

cd ../../
gcc -o helloworld helloworld.c

Запустите как-то вроде

LANG=hi_IN
./helloworld

Вы должны увидеть сообщение (Hello World) на вашем родном языке:

$ LANG=hi_IN
$ ./helloworld 
नमस्कार दुनिया

Примеры:

Ресурсы