ИМЕ
Locale::Po4a::TransTractor -
генерички
транс(латор
екс)трактор.
ОПИС
Циљ po4a (PO for anything – PO
за било шта)
пројекта
је да
поједностави
превођење
(и што је још
интересантније,
одржавање
превода)
употребом
gettext алата на
деловима
на којима
се не
очекује
њихова
употреба,
као што је
документација.
Ова класа
је предак
сваког po4a
парсера
који се
користи за
парсирање
документа,
за
претрагу
стрингова
који могу
да се
преведу, за
њихово
издвајање
у PO фајл и
њихову
замену са
својим
преводима
у излазном
документу.
Формалније
речено, она
узима као
улаз
следеће
аргументе:
- документ
који се
преводи;
- PO фајл са
преводима
који треба
се
употребе.
Као излаз,
она
креира:
- други PO
фајл, који
настаје
као
резултат
издвајања
преводивих
стрингова
из улазног
документа;
- преведени
документ,
са истом
структуром
као и онај
са улаза,
али у коме
су сви
стрингови
замењени
са
преводима
пронађеним
у PO фајлу
који је
наведен у
улазу.
Ево
графичке
представе
овога:
Улазни документ --\ /---> Излазни документ
\ / (преведен)
+-> parse() функција -----+
/ \
Улазни PO --------/ \---> Излазни PO
(издвојен)
ФУНКЦИЈЕ
КОЈЕ БИ ВАШ
ПАРСЕР
ТРЕБАЛО ДА
ПРЕИНАЧИ
- parse()
- Ово је
место на
којем се
обавља сав
посао:
парсирање
улазних
докумената,
генерисање
излаза и
издвајање
преводивих
стрингова.
Ово је
прилично
једноставно
употребом
приложених
функција
приказаних
у одељку
ИНТЕРНЕ
ФУНКЦИЈЕ
испод.
Погледајте
такође
СИНОПСИС,
који
представља
пример.
Ову
функцију
позива
функција
process() испод,
али ако
изаберете
да
користите
функцију
new(), и да
ручно
додате
садржај у
свој
документ,
ову
функцију
ћете
морати
сами да
позовете.
- Ова
функција
враћа
заглавље
које би
требало да
се дода у
креирани
документ,
прописно
цитирано
тако да
буде
коментар у
циљном
језику.
Погледајте
одељак
Едуковање
девелопера
у вези
превода,
из po4a(7), у вези
онога за
шта је
добра ова
функција.
СИНОПСИС
Следећи
пример
парсира
листу
пасуса
који
почињу са
„<p>”. Ради
једноставности,
претпостављамо
да је
документ
добро
форматиран,
тј. да су
’<p>’ ознаке
једине
присутне
ознаке, и да
се ова
ознака
налази на
самом
почетку
сваког
пасуса.
sub parse {
my $self = shift;
PARAGRAPH: while (1) {
my ($paragraph,$pararef)=("","");
my $first=1;
my ($line,$lref)=$self->shiftline();
while (defined($line)) {
if ($line =~ m/<p>/ && !$first--; ) {
# Није први пут да видимо <p>.
# Поново постави текућу линију у улаз,
# и стави изграђени пасус у излаз
$self->unshiftline($line,$lref);
# Сада када је документ формиран, преведи га:
# - Уклони водећу ознаку
$paragraph =~ s/^<p>//s;
# - гурни у излаз водећу ознаку (непреведену) као и
# остатак пасуса (преведен)
$self->pushline( "<p>"
. $self->translate($paragraph,$pararef)
);
next PARAGRAPH;
} else {
# Додај на крај пасуса
$paragraph .= $line;
$pararef = $lref unless(length($pararef));
}
# Поново иницијализуј петљу
($line,$lref)=$self->shiftline();
}
# Није добијена дефинисана линија? Крај улазног фајла.
return;
}
}
Једном
када сте
имплементирали
функцију
за
парсирање,
можете да
употребите
своју
класу
документа,
користећи
јавни
интерфејс
који је
представљен
у следећем
одељку.
ЈАВНИ
ИНТЕРФЕЈС
за скрипте
које
користе
ваш парсер
Конструктор
- process(%)
- Ова
функција
може да
уради све
што је
потребно
да се уради
са po4a
документом
у једном
позиву.
Њени
аргументи
морају да
се упакују
као хеш.
АКЦИЈЕ:
- а.
- Чита све PO
фајлове
наведене у
po_in_name
- б.
- Чита све
оригиналне
документе
наведене у
file_in_name
- г.
- Парсира
документ
- д.
- Чита и
примењује
све
наведене
додатке
- ђ.
- Уписује
преведени
документ у
file_out_name (ако је
задато)
- е.
- Уписује
издвојени
PO фајл у po_out_name
(ако је
задато)
АРГУМЕНТИ,
уз оне које
прихвата
new() (са
очекиваним
типом):
- file_in_name
(@)
- Листа
имена
фајлова из
којих би
требало да
прочитамо
улазни
документ.
- file_in_charset
($)
- Скуп
карактера
који се
користи у
улазном
документу
(ако није
наведен,
покушаће
се са
детекцијом
из улазног
документа).
- file_out_name
($)
- Име фајла у
који би
требало да
упишемо
излазни
документ.
- file_out_charset
($)
- Скуп
карактера
који се
користи у
излазном
документу
(ако није
наведен,
користиће
се скуп
карактера
PO фајла).
- po_in_name
(@)
- Листа
имена
фајлова из
којих би
требало да
се читају PO
фајлови,
они који
садрже
преведене
стрингове
који ће се
користити
за превод
документа.
- po_out_name
($)
- Име фајла у
који би
требало да
упишемо
излазни PO
фајл, који
садржи
стрингове
издвојене
из улазног
документа.
- addendum (@)
- Листа
имена
фајлова из
којих
треба да се
читају
додаци.
- addendum_charset
($)
- Скуп
карактера
за
додатке.
- new(%)
- Креира
нови po4a
документ.
Прихватају
се опције
(у хешу
који се
прослеђује
као
параметар):
Манипулација
фајловима
докумената
- read($$)
- Додаје
податке
другог
улазног
документа
на крај
постојећег
низа
"@{$self->{TT}{doc_in}}".
Аргумент
је име
фајла који
треба да се
прочита.
Ако се зада
и други
аргумент,
он
представља
име фајла
који треба
да се
користи у
референцама.
Низ
"@{$self->{TT}{doc_in}}"
чува
податке
из овог
улазни
документа
као низ
стрингова
са
наизменичним
значењима.
* Стринг
$textline који
држи
сваку
линију
улазног
текста.
* Стринг
"$filename:$linenum"
који држи
његову
локацију
и који се
зове "reference"
("linenum"
почиње од
1).
Имајте
на уму,
молим вас,
да ово још
ништа не
парсира.
Када
завршите
са
паковањем
улазних
фајлова у
документ,
требало
би да
употребите
функцију
parse().
- write($)
- Уписује
преведени
документ у
фајл са
датим
именом.
Ови
подаци
преведеног
документа
се
добијају
из:
* "$self->docheader()"
који чува
текст
заглавља
за модул
додатка, и
* "@{$self->{TT}{doc_out}}"
који у
низу чува
сваку
линију
главног
преведеног
текста.
Манипулација
PO
фајловима
- readpo($)
- Додаје
садржај
фајла (чије
име је
прослеђено
као
аргумент)
постојећем
улазном PO.
Стари
садржај се
не
одбацује.
- writepo($)
- Уписује
издвојени
PO фајл у
дато име
фајла.
- stats()
- Враћа неке
статистичке
податке у
вези до
сада
одрађеног
превода.
Имајте не
уму, молим
вас, да ово
није иста
статистика
коју
исписује msgfmt
--statistic. Овде је
то
статистика
у вези
скорашње
употребе PO
фајла, док msgfmt
пријављује
статус
фајла. То
је
функција
која
обавија
функцију
Locale::Po4a::Po::stats_get function
примењену
на улазни PO
фајл.
Пример
употребе:
[нормална употреба po4a документа...]
($percent,$hit,$queries) = $document->stats();
print "Пронашли смо преводе за $percent\% ($hit од $queries) стрингова.\n";
Манипулација
додацима
- addendum($)
- Молимо
погледајте
po4a(7) за више
информација
о томе шта
су додаци,
и како би
преводиоци
требало да
их пишу. Да
бисте
применили
додатак на
преведени
документ,
једноставно
проследите
име
његовог
фајла овој
функцији и
то је то ;)
У
случају
грешке,
ова
функција
враћа цео
број
различит
од нуле.
ИНТЕРНЕ
ФУНКЦИЈЕ
које се
користе за
писање
изведених
парсера
Добављање
улаза,
обезбеђивање
излаза
За
преузимање
улаза и
враћање
излаза се
користе
четири
функције.
Оне су врло
сличне са
shift/unshift и push/pop у
језику Perl.
* Perl shift враћа прву ставку низа и уклања је из њега.
* Perl unshift ставља ставку на почетак низа као прву.
* Perl pop враћа последњу ставку низа и уклања је из њега.
* Perl push додаје ставку у низ као последњу.
Први пар
се тиче
улаза, док
је други у
вези
излаза. Да
се лакше
упамти: за
улаз вам је
од
интереса
прва
линија, а то
је управо
оно што
враћа shift, док
за излаз
желите да
свој
резултат
додате на
крај, као
што то ради
push.
- shiftline()
- Ова
функција
враћа прву
линију
која треба
да се
парсира у
њену
одговарајућу
референцу
(упаковано
као низ) из
низа
"@{$self->{TT}{doc_in}}" и
уклања ове
прве 2
ставке
низа.
Референцу
овде
обезбеђује
стринг
"$filename:$linenum".
- unshiftline($$)
- Unshift-ује
последњу
shift-овану
линију
улазног
документа
и њену
одговарајућу
референцу
назад на
почетак
"{$self->{TT}{doc_in}}".
- pushline($)
- Ради push нове
линије на
крај
"{$self->{TT}{doc_out}}".
- popline()
- Ради pop
последње
push-оване
линије са
краја
"{$self->{TT}{doc_out}}".
Обележавање
стрингова
као
преводивих
Достављена
је једна
функција
која
обрађује
текст
предвиђен
за
превођење.
- translate($$$)
- Обавезни
аргументи:
- Стринг за
превођење
- Референца
овог
стринга
(тј.
позиција у
улазном
фајлу)
- Тип овог
стринга
(тј.
текстуални
опис
његове
структурне
улоге;
користи се
у Locale::Po4a::Po::gettextization();
погледајте
такође po4a(7),
одељак На
који начин
програм
функционише?)
И ова
функција
може да
узме
неколико
додатних
аргумената.
Они морају
да се
организују
у хеш. На
пример:
$self->translate("string","ref","type",
'wrap' => 1);
- wrap
- логичка
вредност
која
назначава
можемо ли
претпоставити
да празни
карактери
у стрингу
нису битни.
Ако је
истинита,
функција
канонизује
стринг пре
тражења
превода
или
његовог
издвајања,
и обавија
превод.
- wrapcol
- колона око
које се
врши
обавијање
(подразумевано:
76).
- допунски
коментар
који се
додаје
ставци.
Акције:
- Ради push
стринга,
референце
и типа у po_out.
- Враћа
стринг
превода
(као што је
пронађен у
po_in) и
омогућава
да парсер
изгради doc_out.
- Обрађује
скупове
карактера
како би се
стрингови
рекодирали
пре него
што се
пошаљу у po_out и
пре
враћања
превода.
Разне
функције
- verbose()
- Враћа
информацију
да ли је
током
креирања
објекта TransTractor
прослеђена
опција
детаљног
извештавања.
- debug()
- Враћа
информацију
да ли је
приликом
креирања
објекта TransTractor
била
прослеђена
опција
детаљнијег
извештавања.
- detected_charset($)
- Ово говори
TransTractor -у да је
откривен
нови скуп
карактера
(први
аргумент) у
улазном
документу.
Обично
може да се
прочита из
заглавља
документа.
Преостаће
само први
скуп
карактера,
који
долази или
из
аргумената
функције
process(), или се
детектује
из
документа.
- get_out_charset()
- Ова
функција
ће да врати
скуп
карактера
који би
требало да
се користи
у излазном
документу
(обично је
корисно за
замену
скупа
карактера
детектованог
у улазном
документу
у коме је
пронађен).
Користиће
излазни
скуп
карактера
наведен у
командној
линији.
Ако није
био задат,
користиће
се скуп
карактера
улазног PO, а
ако
улазни PO
има
подразумевану
вредност
„CHARSET”,
вратиће
скуп
карактера
улазног
документа,
тако да се
не обавља
кодирање..
- recode_skipped_text($)
- Ова
функција
враћа
рекодирани
текст који
јој је
прослеђен
као
аргумент,
из скупа
карактера
улазног
документа
у скуп
карактера
излазног
документа.
Ово није
неопходно
када се се
стринг
преводи
(функција
translate() сама
све
рекодира),
али је
неопходно
када
прескочите
стринг из
улазног
документа
и желите да
излазни
документ
буде у
сагласности
са
глобалним
кодирањем.
СМЕРНИЦЕ
ЗА
БУДУЋНОСТ
Једна од
лоших
страна
текуће TransTractor
класе је да
не може
обрађивати
преведене
документе
који
садрже све
језике, као
што су debconf
шаблони,
или .desktop
фајлови.
Како би се
решио
проблем,
неопходне
су само
следеће
измене
интерфејса:
Видећемо
да ли је ово
довољно ;)
АУТОРИ
Дени Барбије <barbier@linuxfr.org>
Мартин Квинсон (mquinson#debian.org)
Жорди Вилалта <jvprat@gmail.com>