LOCALE::PO4A::XML.3PM(1)

НАЗВАНИЕ
Locale::Po4a::Xml: преобразование документов XML и производных форматов в/из PO-файлы

ОПИСАНИЕ
Целью проекта po4a (PO for anything, PO везде и для всего) является облегчение процесса перевода (и что более важно — поддержки перевода), используя инструменты gettext в тех случаях, когда их применение может выглядеть неожиданным, например для документации.

Locale::Po4a::Xml — это модуль, предназначенный для помощи в переводе документации в формате XML на другие [человеческие] языки. Его также можно использовать в качестве базы для создания других модулей для документов других форматов, основанных на XML.

ПЕРЕВОД С ПОМОЩЬЮ PO4A::XML
Этот модуль может непосредственно обрабатывать документы XML общего вида. Он будет извлекать содержимое всех тегов, но не атрибутов т.к. именно в них содержится текст в большинстве документов основанных на XML.

Есть нескоько параметров (описанных в следующей секции), которые могут изменить поведение. Если для вашего формата документации этого недостаточно, то мы рекомендуем вам написать свой собственный модуль производный от данного, дабы лучше описать детали своего формата. Как это сделать, см. в секции НАПИСАНИЕ ПРОИЗВОДНЫХ МОДУЛЕЙ ниже.

ПАРАМЕТРЫ ПРИНИМАЕМЫЕ ЭТИМ МОДУЛЕМ
Глобальный параметр `debug` делает так, что данный модуль будет показывать отброшенные строки, чтобы дать возможность пользователю посмотреть, не пропустил ли он что-то важное.

Ниже приведены специфические для данного модуля параметры:

nostrip
    Не обрезать начальные и конечные пробелы в извлекаемых строках.

wrap
    Приводить переводимые строки к каноническому виду (учитывая, что пробелы не важны) и расставляет переносы строк в документе. Действие этого параметра можно отменить специфическими параметрами для тегов. Смотрите описание параметра translated ниже.

unwrap_attributes
    По умолчанию в атрибуты могут добавляться переносы строк. Этот параметр отключает оное поведение.

caseinsensitive
    Этот параметр делает поиск тегов и атрибутов нечувствительным к регистру. Если он задан, то и «<BooK>laNG», и «<BOOK>Lang» будут сопоставлены «<book>lang».

escapequotes
    Экранировать кавычки в выходных строках. Необходимо, например, для создания строковых ресурсов, используемых инструментами сборки для Android.

    Смотрите также: https://developer.android.com/guide/topics/resources/string-resource.html

includeexternal
    Когда этот параметр задан, из внешних сущностей (entities) будут извлечены строки для перевода, и они, сущности, будут включены в сгенерированный (переведённый) документ. В противном случае, вам придётся переводить внешние сущности отдельно как независимые документы.

ontagerror
    Данный параметр определяет поведение модуля, когда он встречается с недопустимым XML синтаксисом (Например, закрывающий тег, не соответствующий последнему открывающему тегу). Он может принимать следующие значения:

    fail
        Это значение по умолчанию. Модуль будет завершать работу с ошибкой.

    warn
        Модуль выдаст предупреждение и продолжит работу.

    silent
        Модуль продолжит работу без каких-либо предупреждений.

    Используйте данный параметр с осторожностью. Вообще говоря, рекомендуется исправить исходный файл.

tagsonly
    Замечание: Использование этого параметра нежелательно (deprecated).

    Извлекать только теги указанные в параметре tags. Иначе, будут извлекаться все теги кроме заданных.

doctype
    Строка, которая будет сопоставляться с первой строкой doctype документа (если задан). Если они не совпадают, то будет выведено предупреждение, что документ может быть неправильного типа.

addlang
    Строка, задающая путь (например, <bbb><aaa>) к тегу, в который следует добавить атрибут lang="<язык>", где <язык> — это имя PO-файла без расширения «.po».

optionalclosingtag
    Логическое значение, указывающее, являются ли закрывающие теги опциональными (как в HTML). По умолчанию пропущенный закрывающий тег вызывает ошибку, обрабатываемую в соответствии с ontagerror.

tags
    Замечание: Использование этого параметра нежелательно (deprecated). Вместо него вам следует использовать параметры translated и untranslated.

    Список тегов, разделённых пробелами, которые вы хотите переводить или, наоборот, исключить из перевода. По умолчанию указанные теги будут исключены, но если вы укажите также параметр «tagsonly», то будут включены только указанные теги. Теги должны быть заданы в формате <aaa>. Вы также можете объединить несколько тегов подряд (<bbb><aaa>), чтобы указать, что содержимое тега <aaa> будет переводимым только если он находится внутри тега <bbb>.

    Вы также можете указать некоторые специфические параметры тегов, добавив некоторые символы перед иерархией тегов. Например, можно добавить w (переносить строки, wrap) или W (не переносить строки), чтобы переопределить поведение по умолчанию, заданное глобальным параметром «wrap».

    Пример: W<chapter><title>

attributes
    Список атрибутов тегов, разделённых пробелами, которые вы хотите переводить. Вы можете задавать атрибуты просто по их имени (например, «lang»), но вы также можете предварять их иерархией тегов, чтобы указать, что они должны быть переводимыми только когда они относятся к конкретным тегам. Например: <bbb><aaa>lang указывает, что «lang» будет переводиться только если он находится внутри тега <aaa>, который в свою очередь находится внутри тега <bbb>.

foldattributes
    Не переводить атрибуты во встроенных (inline) тегах. Вместо этого заменять все атрибуты тегов на po4a-id=<id>.

    Это полезно, когда атрибуты не должны переводиться, так как это упрощает строки, что проще для переводчиков, и позволяет избегать опечаток.

customtag
    Список тегов, разделённых пробелами, которые не должны обрабатываться как теги. Эти теги обрабатываются как встроенные (inline), и не требуют того, чтобы они обязательно были закрытыми.

break
    Список тегов, разделённых пробелами, которые должны обрывать переводимые строку. По умолчанию все теги являются таковыми.

    Теги должны быть заданы в виде <aaa>, но их также можно объединять (<bbb><aaa>) в случае, если тег <aaa> должен учитываться только если он находится внутри тега <bbb>.

    Учтите, что любой конкретный тег может быть задан только в одном из списков: break, inline, placeholder или customtag.

inline
    Список тегов, разделённых пробелами, которые должны обрабатываться как встроенные (inline). По умолчанию все теги обрывают переводимую строку (не являются встроенными).

    Теги должны быть заданы в виде <aaa>, но их также можно объединять (<bbb><aaa>) в случае, если тег <aaa> должен учитываться только если он находится внутри тега <bbb>.

placeholder
    Список тегов, разделённых пробелами, которые должны обрабатываться как местозаполнители (placeholder). Метки-заполнители не обрывают переводимую строку, но их содержимое переводится отдельно.

    Местоположение местозаполнителей в их блоке будет помечены строкой на подобии следующей:

      <placeholder type=\"footnote\" id=\"0\"/>

    Теги должны быть заданы в виде <aaa>, но их также можно объединять (<bbb><aaa>) в случае, если тег <aaa> должен учитываться только если он находится внутри тега <bbb>.

break-pi
    По умолчанию, инструкция обработки (processing instruction, PI, т.е теги вида "<? ... ?>") рассматриваются как встроенные теги. Добавьте данный параметр, если вы хотите обрабатывать их как разделяющие. Заметьте, что необработанные теги PHP также рассматриваются парсером, как инструкции обработки.

nodefault
    Список тегов, разделённых пробелами, которые по умолчанию не будут отнесены к какой-либо категории данным модулем.

    Если в вашем документе есть теги, у которых есть какие-либо настройки по умолчанию, установленные модулями созданными на основе данного, то это поведение можно изменить, указав их в nodefault.

cpp Поддержка директив препроцессора Си. Когда этот параметр установлен, po4a будет считать директивы препроцессора разделителями абзацев. Это важно, когда XML-файл должен быть обработан препроцессором, ибо в противном случае директивы могут быть вставлены в середину переводимых строк, если po4a решит, что они принадлежат текущему параграфу, так что они могут быть не распознаны при последующей обработке. Замечание: директивы должны располагаться между тегами (они не могут разбивать тег).

translated
    Список тегов, разделённых пробелами, которые должны быть переведены.

    Теги должны быть заданы в виде <aaa>, но их также можно объединять (<bbb><aaa>) в случае, если тег <aaa> должен учитываться только если он находится внутри тега <bbb>.

    Вы также можете задавать некоторые специальные опции для тегов, добавив символ перед данным иерархическим списком. Это переопределяет поведение, заданное глобальными параметрами wrap и defaulttranslateoption.

    w   Теги будут переводиться и переносы строк будут расставляться автоматически.

    W   Теги будут переводиться и переносы строк не будут изменяться.

    i   Теги будут переводиться как встроенные (inline).

    p   Теги будут переводиться как местозаполнители (placeholders).

    Внутри себя парсер XML использует только эти четыре опции: w W i p.

    * Тегам, перечисленные в break, задаётся опция w или W, в зависимости от параметра wrap.

    * Тегам, перечисленные в inline, задаётся опция i.

    * Тегам, перечисленные в placeholder, задаётся опция p.

    * Тегам, перечисленные в untranslated, не задаётся ни одна из этих опций.

    Вы можете просмотреть, какие именно используются внутренние параметры поведения, запустив po4a с параметром --debug.

    Пример: W<chapter><title>

    Учтите, что тег может присутствовать только в одном из списков: или в translated, или в untranslated.

untranslated
    Список тегов, разделённых пробелами, которые не должны быть переведены.

    Теги должны быть заданы в виде <aaa>, но их также можно объединять (<bbb><aaa>) в случае, если тег <aaa> должен учитываться только если он находится внутри тега <bbb>.

    Учтите, что переводимый встроенный (inline) тег, расположенный внутри непереводимого тега интерпретируется, как переводимый и разделяющий (breaking) тег. Опция i убирается и будет установлена w или W в зависимости от параметра wrap.

defaulttranslateoption
    Категория по умолчанию для тегов, которые не относятся ни к одной другой категории: переводимых, непереводимых, разделяющих, встроенных или местозаполнителей.

    Это набор символов, определённых в translated, и эти настройки действительны только для переводимых тегов.

СОЗДАНИЕ ПРОИЗВОДНЫХ МОДУЛЕЙ

  ОПРЕДЕЛЕНИЕ, КАКИЕ ТЕГИ И АТТРИБУТЫ НУЖНО ПЕРЕВОДИТЬ
Самое простое, что вы можете изменить — это задать парсеру, какие теги и атрибуты вы хотите переводить. Это должно быть сделано в функции инициализации. Во-первых, вы должны вызвать основную функцию инициализации, чтобы получить параметры командной строки, а затем добавить свои специализированные определения в хеш параметров. Если вы хотите обрабатывать свои параметры командной строки, то необходимо определить их до вызова основной функции инициализации:

  $self->{options}{'new_option'}='';
  $self->SUPER::initialize(%options);
  $self->{options}{'_default_translated'}.=' <p> <head><title>';
  $self->{options}{'attributes'}.=' <p>lang id';
  $self->{options}{'_default_inline'}.=' <br>';
  $self->treat_options;

В производных модулях вам стоит использовать параметры _default_inline, _default_break, _default_placeholder, _default_translated, _default_untranslated, и _default_attributes. Это позволит пользователю переопределить поведение по умолчанию, заданное вашем модулем из командной строки.

  ПЕРЕОПРЕДЕЛЕНИЕ ПОВЕДЕНИЯ ПО УМОЛЧАНИЮ ПАРАМЕТРАМИ КОМАНДНОЙ СТРОКИ
Если вас не устраивает поведение xml-модуля или его производных по умолчанию, то вы можете задать параметры командной строки, которые его изменят.

См. Locale::Po4a::Docbook(3pm),

  ПЕРЕОПРЕДЕЛЕНИЕ ФУНКЦИИ found_string
Другой простой шаг, который вы можете предпринять — это переопределить функцию «found_string», которая получает от парсера извлечённые строки, которые нужно перевести. Здесь вы можете контролировать, какие строки вы хотите переводить и преобразовать их произвольным образом до или после перевода.

Она принимает извлечённый текст, местоположение, откуда он был извлечён и хеш с дополнительной информацией, которая позволит контролировать, какие строки следует переводить, как их переводить и какой комментарий следует добавить для переводчика.

Содержимое этих параметров зависит от того, что именно это за строка (указано в вышеупомянутом хеше):

type="tag"
    Найденная строка является содержимым переводимого тега. По ключу «tag_options» в хеше будет указан символ опции, заданный перед иерархией тегов в параметре «tags».

type="attribute"
    Найденная строка является значением переводимого атрибута. Имя атрибута будет доступно в хеше по ключу «attribute».

Она должна возвращать текст перевода, который заменит исходную строку (значение функции «translate()» из Locale::Po4a::TransTractor, прим. переводчика). Базовый пример подобной функции:

  sub found_string {
    my ($self,$text,$ref,$options)=@_;
    $text = $self->translate($text,$ref,"type ".$options->{'type'},
      'wrap'=>$self->{options}{'wrap'});
    return $text;
  }

Другой простой пример можно посмотреть в модуле перевода диаграмм Dia, который только фильтрует некоторые строки.

  ИЗМЕНЕНИЕ ТИПОВ ТЕГОВ (TODO)
Хотя этот подход и сложнее, зато он позволяет обрабатывать документ (практически) как угодно. В основе оного лежит список хешей каждый из которых определяет поведение «типа тега». Список должен быть отсортирован так, чтобы самые общие теги следовали после самых конкретных (сначала отсортированы по началу ключей (begining), а затем по завершению (end)). Для того чтобы определить тип тега, нужно создать хеш со следующими ключами:

beginning
    Задаёт начало тега, то что следует после символа «<».

end Задаёт окончание тега, то что следует перед символом «>».

breaking
    Задаёт, является ли данный класс тегов прерывающим. Не прерывающие (встроенные, inline) теги — это теги, которые могут являться частью или содержимым других тегов. Значениями данного ключа могут быть false (0), true (1) или он может быть не определён (undefined). В последнем случае вы должны будете определить функцию f_breaking, которая будет выдавать, является ли конкретный тег прерывающим или нет.

f_breaking
    Это функция, которая должна возвращать, является ли следующие тег прерывающим или нет. Она должна быть определена, когда breaking не определено..

f_extract
    Если вы не определите этот ключ, то для экстракции самого тега будет использована базовая функция. Это полезно для тегов, которые могут иметь внутри себя другие теги или специальные структуры так, чтобы основной парсер на это не ругался. Эта функция принимает логическое значение, которое говорит, должен ли тег быть удалён из входного потока или нет.

f_translate
    Эта функция принимает текущий тег (в формате get_string_until()) и возвращает переведённый тег (включая переведённые атрибуты и все необходимые преобразования исходного тега) в виде одной строки.

ВНУТРЕННИЕ ФУНКЦИИ, используемые при создании производных парсеров

  РАБОТА С ТЕГАМИ

get_path()
    Эта функция возвращает путь от корня документа до текущего тега в формате <html><body><p>.

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

tag_type()
    Эта функция возвращает порядковый номер типа тега в списке tag_types, который соответствует следующему тегу во входном потоке или -1 при достижении конца входного файла.

    В данном случае структура тега начинается с < и заканчивается > и может содержать несколько строк.

    Это делается через обработку массива "@{$self->{TT}{doc_in}}", содержащего исходные данные документа, посредством получения неявных ссылок на него через "$self->shiftline()" и "$self->unshiftline($$)".

extract_tag($$)
    Эта функция возвращает следующий тег из потока ввода без начальной и конечной строки (beginning и end) в виде массива, дабы сохранить их местоположение в исходном файле. Она принимает два параметра: тип тега (как в tag_type) и булево значение, которое указывает, удалять ли этот тег из потока ввода.

    Это делается через обработку массива "@{$self->{TT}{doc_in}}", содержащего исходные данные документа, посредством получения неявных ссылок на него через "$self->shiftline()" и "$self->unshiftline($$)".

get_tag_name(@)
    Эта функция возвращает имя тега переданного в качестве аргумента в виде такого же массива, как и в extract_tag.

breaking_tag()
    Эта функция возвращает булево значение, которое указывает, является ли следующий тег в потоке ввода разделяющим (breaking) или нет (встроенным, inline). Она не изменяет поток ввода.

treat_tag()
    Эта функция переводит следующий тег из потока ввода. Она использует специфические для каждого типа тега функции перевода (см. f_translate).

    Это делается через обработку массива "@{$self->{TT}{doc_in}}", содержащего исходные данные документа, посредством получения неявных ссылок на него через "$self->shiftline()" и "$self->unshiftline($$)".

tag_in_list($@)
    Эта функция возвращает строковое значение, которое указывает, сопоставляется ли её первый аргумент (иерархия тегов) какому-либо тегу из её второго аргумента (список тегов или иерархий тегов). Если не сопоставляются, то она возвращает 0. Иначе она возвращает опции сопоставленного тега (символ указанный перед этим тегом или иерархией, см. параметр «tags» ) или 1 (если у тега нет опции).

  РАБОТА С АТТРИБУТАМИ

treat_attributes(@)
    Эта функция обеспечивает перевод атрибутов тегов. Она принимает тег без меток начала/конца (beginning/end), а затем она находит атрибуты, переводит те из них, что помечены как переводимые (указанные в параметре модуля attributes). Она возвращает простую строку с переведённым тегом.

  РАБОТА С СОДЕРЖИМЫМ ТЕГОВ

treat_content()
    Эта функция возвращает текст до следующего разделяющего тега (не встроенного) из потока ввода. Переводите его с помощью специфической функции перевода для конкретного типа тега.

    Это делается через обработку массива "@{$self->{TT}{doc_in}}", содержащего исходные данные документа, посредством получения неявных ссылок на него через "$self->shiftline()" и "$self->unshiftline($$)".

  РАБОТА С ПАРАМЕТРАМИ МОДУЛЯ

treat_options()
    Эта функция заполняет внутренние структуры с информацией о тегах, атрибутах и встроенных данных на основе параметров модуля (переданных в командной строке или в функцию инициализации).

  ПОЛУЧЕНИЕ ТЕКСТА ИЗ ИСХОДНОГО ДОКУМЕНТА

get_string_until($%)
    Эта функция возвращает строки исходного документа (и их расположение), расположенные до первого вхождения, строки или регулярного выражения, переданного в первом аргументе. Второй аргумент является хешем дополнительных параметров для функции, для которых значение 0 означает, что она отключена, а значение 1 — включена.

    Допустимы следующие дополнительные параметры:

    include
        Искомый текст будет включён в возвращаемый массив

    remove
        Найденный текст будет удалён из потока ввода

    unquoted
        Дополнительно удостоверится, что искомый текст не включён в какие-либо кавычки

    regex
        Обозначает, что первый аргумент является регулярным выражением, а не простой строкой

skip_spaces(\@)
    Эта функция принимает ссылку на абзац (в формате возвращённом get_string_until), пропускает начальные пробелы и возвращает их (пробелы) в виде строки.

join_lines(@)
    Эта функция возвращает простую строку с текстом, составленным из массива строк и местоположений оных в исходном файле, отбрасывая последние.

СОСТОЯНИЕ ЭТОГО МОДУЛЯ
Этот модуль может переводить теги и атрибуты.

Список TODO
DOCTYPE (СУЩНОСТИ)

Перевод сущностей (entities) на данный момент поддерживается на минимальном уровне. Они переводятся как единое целое, а теги не принимаются во внимание. Многострочные сущности не поддерживаются и во время перевода все переносы строк расставляются заново.

ИЗМЕНЯЙТЕ ТИПЫ ТЕГОВ В ПРОИЗВОДНЫХ МОДУЛЯХ (переместите структуру tag_types непосредственно в хеш $self?)

СМОТРИТЕ ТАКЖЕ
Locale::Po4a::TransTractor(3pm), po4a(7)

АВТОРЫ
 Жорди Вилальта (Jordi Vilalta) <jvprat@gmail.com>
 Николя Франсуа (Nicolas François) <nicolas.francois@centraliens.net>

АВТОРСКИЕ ПРАВА И ЛИЦЕНЗИИ
 Copyright © 2004 Жорди Вилальта (Jordi Vilalta)  <jvprat@gmail.com>
 Copyright © 2008-2009 Николя Франсуа (Nicolas François) <nicolas.francois@centraliens.net>

Данная программа является свободным программным обеспечением; вы можете распространять и/или изменять её на условиях Универсальной общественной лицензии (GPL) GNU v2.0 или новее (см. файл COPYING).