Доброго дня!
Відсьогодні український переклад KDE (стабільної та нестабільної гілок) переведено на нову формулу роботи з формами множини (тотожну тій, яка використовується у сербській мові):
"Plural-Forms: nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n%"
"10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
1.
Навіщо?Розгляньмо приклад. Нехай треба перекласти українською таку комбінацію (digiKam):
msgid "You have edited the image caption. "
msgid_plural "You have edited the captions of %1 images. "
Попередня формула запису форм множини надавала можливість використати для перекладу три форми:
0: для 1, 21, 31, 41... підпису
1: для 2, 3, 4, 22, 23... підписів
2: для 5, 6, 7... підписів.
Типовою похибкою є такий переклад:
msgstr[0] "Ви змінили підпис до зображення. "
msgstr[1] "Ви змінили підписи до %1 зображень. "
msgstr[2] "Ви змінили підписи до %1 зображень. "
Проста перевірка msgfmt -v -c digikam.po показує, що такий переклад є некоректним з точки зору gettext. Чому?
Ви певно вже здогадалися: нульова форма описує не один, а нескінченно багато варіантів. Для виправлення цього недоліку доводилося робити так:
msgstr[0] "Ви змінили підпис до %1 зображення. "
msgstr[1] "Ви змінили підписи до %1 зображень. "
msgstr[2] "Ви змінили підписи до %1 зображень. "
Виглядає незграбно (користувачеві буде показано надмірну інформацію у випадку 1 підпису), але працює.
Трохи видозмінимо приклад:
msgid "You have edited the image caption. "
msgid_plural "You have edited the captions of images. "
Тепер будь-який переклад за попередньою формулою буде мати помилкові варіанти:
msgstr[0] "Ви змінили підпис до зображення. "
msgstr[1] "Ви змінили підписи до зображень. "
msgstr[2] "Ви змінили підписи до зображень. "
Помилка: підписів може бути 21, а це аж ніяк не «підпис».msgstr[0] "Ви змінили підписи до зображення. "
msgstr[1] "Ви змінили підписи до зображень. "
msgstr[2] "Ви змінили підписи до зображень. "
Помилка: підписів може бути 1, а це аж ніяк не «підписи».msgstr[0] "Ви змінили підпис до %1 зображення. "
msgstr[1] "Ви змінили підписи до %1 зображень. "
msgstr[2] "Ви змінили підписи до %1 зображень. "
Помилка: формально працює, але не проходить перевірку msgfmt.Нова формула позбавлена недоліків попередньої. В ній чітко розмежовано однину від всіх інших випадків:
msgstr[0] "Ви змінили підпис до %1 зображення. "
msgstr[1] "Ви змінили підписи до %1 зображень. "
msgstr[2] "Ви змінили підписи до %1 зображень. "
msgstr[3] "Ви змінили підпис до зображення. "
msgstr[0] "Ви змінили підписи до зображень. "
msgstr[1] "Ви змінили підписи до зображень. "
msgstr[2] "Ви змінили підписи до зображень. "
msgstr[3] "Ви змінили підпис до зображення. "
2.
Як перейти на нову формулу?Часлав Іліч (координатор сербської команди KDE) надав скрипт, який працює на основі оболонки обробки перекладів KDE Pology (перший рядок побито з метою пройти перевірку на місцеві трояни
):
# ! / usr / bin/ env python
# -*- coding: UTF-8 -*-
import fallback_import_paths
import os
import sys
from pology.file.catalog import Catalog
from pology.misc.fsops import collect_catalogs
from pology.misc.report import report, error
cmd = os.path.basename(sys.argv[0])
args = sys.argv[1:]
if len(args) != 3:
error("Usage: %(cmd)s PATH PLURALFORMS COPYMAP" % dict(cmd=cmd))
path = args.pop(0)
newplhead = args.pop(0)
copyspec = args.pop(0)
# Process form mapping.
srcforms = set()
dstforms = set()
copymap = {}
for spec1 in copyspec.split(","):
try:
sform, dform = map(int, spec1.split(">"))
except:
error("Malformed copy map '%(map)s'." % dict(map=copyspec))
copymap[sform] = dform
srcforms.add(sform)
dstforms.add(dform)
if max(srcforms) + 1 != len(srcforms):
error("Gaps in source forms.")
if max(dstforms) + 1 != len(dstforms):
error("Gaps in destination forms.")
copyord = [0] * len(dstforms)
for sform, dform in copymap.items():
copyord[dform] = sform
# Convert catalogs.
for popath in collect_catalogs(path):
cat = Catalog(popath)
cat.header.replace_field_value(u"Plural-Forms", unicode(newplhead))
for msg in cat:
if msg.msgid_plural is not None:
msg.msgstr[:] = [msg.msgstr[x] for x in copyord]
if cat.sync():
report(cat.filename)
Щоб перевести ваші переклади на нову формулу, звантажте Pology, збережіть скрипт до підкаталогу scripts і віддайте команду:
./modplforms.py /шлях/до/каталогу/перекладів 'nplurals=4; plural=n==1 ? 3 : n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;0>0,1>1,2>2,0>3'
У результаті до четвертої форми потрапить копія того, що було у першій. Змінені переклади не буде позначено як неточні, отже ніяких незручностей виникнути не повинно.
3.
Що далі?Я поступово переводитиму всі переклади, які контролюю, на нову формулу. Координатор перекладів GNOME у приватному повідомленні погодився з тим, що якщо введення четвертої форми покращує якість перекладів, її варто вживати.
Експерименти показують, що додаткова четверта форма обрізається без повідомлень про помилку Virtaal і Rosetta. Тому користувачі *Ubuntu бачитимуть три форми попередньої формули. Різкий перехід неможливий через те, що у Rosetta немає внутрішніх механізмів, які б забезпечували безпроблемну зміну кількості форм множини.
Всі інші дистрибутиви, які використовують коди, пропоновані для збирання командою KDE, зможуть скористатися перевагами нового формату.
Transifex і Lokalize розуміють все без проблем.
Радий буду почути коментарі.