i18n_po_tools 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/.gitignore +34 -0
- data/Design.md +0 -0
- data/Design.ru.md +188 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/Rakefile +1 -0
- data/Readme.md +77 -0
- data/Readme.ru.md +191 -0
- data/bin/i18n-po +9 -0
- data/i18n_yml_tools.gemspec +47 -0
- data/lib/i18n_po_tools/cli.rb +171 -0
- data/lib/i18n_po_tools/core_ext/dotted_hash.rb +34 -0
- data/lib/i18n_po_tools/data/languages.yml +26 -0
- data/lib/i18n_po_tools/data/plurals.rb +116 -0
- data/lib/i18n_po_tools/formats/android_format.rb +28 -0
- data/lib/i18n_po_tools/formats/base_format.rb +57 -0
- data/lib/i18n_po_tools/formats/basic_flat_yaml_format.rb +18 -0
- data/lib/i18n_po_tools/formats/csv_format.rb +31 -0
- data/lib/i18n_po_tools/formats/ios_format.rb +17 -0
- data/lib/i18n_po_tools/formats/po_format.rb +115 -0
- data/lib/i18n_po_tools/formats/rails_yaml_format.rb +32 -0
- data/lib/i18n_po_tools/formats.rb +32 -0
- data/lib/i18n_po_tools/plural_message.rb +18 -0
- data/lib/i18n_po_tools/utils/data.rb +25 -0
- data/lib/i18n_po_tools/utils/ios_strings.rb +83 -0
- data/lib/i18n_po_tools/utils/locfile.rb +164 -0
- data/lib/i18n_po_tools/utils/po.rb +87 -0
- data/lib/i18n_po_tools/version.rb +3 -0
- data/lib/i18n_po_tools.rb +24 -0
- metadata +185 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
OTJkYTk0MTc2YjRkOWQ3OWNlZDVhNjI2ZGY4ZDNkZjk5NDc2M2IzMw==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
OTNmMWRkY2FkZjJmZTM5YzFlNWU4OGE3ZGMwMTEwZGM3MGJjNjVjYg==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
Y2JiYWRkMWVlMmEzNTA3Y2E0ZjNhZWFhYTdlNDg2NjNlNTY0ODA0ZWFjMzdl
|
10
|
+
ZDY1NjdiYzE5MTM5MTc3MTE0ZWEwYTFlODFiNzA2MjM1YTBjZDU5MmEwOGFj
|
11
|
+
M2RhMzA1M2NlOTRjMjJlYzMzNTlkODFjMTEzMDliMGJkYzBiZTU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
MmIzMTNhN2RkY2Y3ZWI2NjdjZjJiNzdmOGJhN2I2Yjg0YzIyM2MzNTAzNDM2
|
14
|
+
OTQ4ZTRmODNiNDA5MzZlNmNhN2I3ZDg2NGY0ZTRlY2QzYjc5OGFhYzcwZTEy
|
15
|
+
ZTYwMjA3NDI0Zjc1MWNkZWFjMGQ5YTI2ZWY1ZGYyZWU1ZDQ5Y2M=
|
data/.gitignore
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/test/tmp/
|
9
|
+
/test/version_tmp/
|
10
|
+
/tmp/
|
11
|
+
|
12
|
+
## Specific to RubyMotion:
|
13
|
+
.dat*
|
14
|
+
.repl_history
|
15
|
+
build/
|
16
|
+
|
17
|
+
## Documentation cache and generated files:
|
18
|
+
/.yardoc/
|
19
|
+
/_yardoc/
|
20
|
+
/doc/
|
21
|
+
/rdoc/
|
22
|
+
|
23
|
+
## Environment normalisation:
|
24
|
+
/.bundle/
|
25
|
+
/lib/bundler/man/
|
26
|
+
|
27
|
+
# for a library or gem, you might want to ignore these files since the code is
|
28
|
+
# intended to run in multiple environments; otherwise, check them in:
|
29
|
+
Gemfile.lock
|
30
|
+
.ruby-version
|
31
|
+
.ruby-gemset
|
32
|
+
|
33
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
34
|
+
.rvmrc
|
data/Design.md
ADDED
File without changes
|
data/Design.ru.md
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
Почему получилось то, что получилось
|
2
|
+
------------------------------------
|
3
|
+
|
4
|
+
Проблема
|
5
|
+
========
|
6
|
+
Есть несколько проектов:
|
7
|
+
- мобильное приложение на Android
|
8
|
+
- мобильное приложение на iOS
|
9
|
+
- настольное приложение для Mac OS X
|
10
|
+
- настольное приложение для Windows
|
11
|
+
- веб-приложение на Ruby on Rails
|
12
|
+
- маркетинговые сайты на Middleman
|
13
|
+
|
14
|
+
Они используют следующие механизмы перевода:
|
15
|
+
- Android (Java properties XML) (наследие Java)
|
16
|
+
- файлы Localizable.strings для iOS и Mac OS X, так же сделали локализацию Windows через них (собственное довольно старое изобретение)
|
17
|
+
- файлы .yml (зачем еще и эти изобрели свой формат понятно, но всё равно печально) для Ruby on Rails и Middleman
|
18
|
+
|
19
|
+
Все они поддерживают несколько языков:
|
20
|
+
- русский
|
21
|
+
- английский
|
22
|
+
- польский
|
23
|
+
- французский
|
24
|
+
|
25
|
+
Команда, в основном, знает русский и английский. Причем, русский лучше.
|
26
|
+
Остальное отдается на перевод переводчикам. Они переводят с русского или английского варианта.
|
27
|
+
|
28
|
+
Переводчики обычно технически не особенно подкованны. Им нужны простые программы, чтобы сделать свою работу.
|
29
|
+
|
30
|
+
Каждая же из систем предлагает свой вариант формата файлов для перевода.
|
31
|
+
|
32
|
+
Напрямую с ними переводчикам крайне сложно и неудобно работать. Более того,
|
33
|
+
полученный перевод, скорее всего, содержит ошибки форматирования. Так же разработка идет достаточно интенсивно, нужно достаточно часто (скажем, раз в неделю) допереводить новые строки.
|
34
|
+
|
35
|
+
Так же не хотелось бы вводить дополнительных людей, которые бы стояли между переводчиками и программистами.
|
36
|
+
|
37
|
+
1. Используем одну программу для переводчиков
|
38
|
+
=============================================
|
39
|
+
Желательно, чтобы переводчики работали в программе, а не с файлами напрямую.
|
40
|
+
Так не будет синтаксических ошибок в файлах.
|
41
|
+
|
42
|
+
Желательно, чтобы программа была одна, а не несколько, чтобы иметь общую базу
|
43
|
+
переводов. Да и обучать было бы проще.
|
44
|
+
|
45
|
+
Желательно, чтобы программа была как под Windows, так и под другие ОС. Мало ли чем будут пользоваться переводчики.
|
46
|
+
|
47
|
+
2. Используем один формат
|
48
|
+
=========================
|
49
|
+
Из желания использовать одну программу приходим к решению использовать один формат для переводов. Т.к. программ, поддерживающих все и разные не найдено.
|
50
|
+
|
51
|
+
Соответственно, нужно будет обеспечить конвертацию форматов в обе стороны.
|
52
|
+
|
53
|
+
3. PO (Gettext) спасает день
|
54
|
+
============================
|
55
|
+
Формат .po довольно популярен и достаточно прост. Все найденные редакторы его поддерживают. Его так же поддерживают различные online-редакторы (при необходимости).
|
56
|
+
|
57
|
+
Как альтернатива можно было использовать .xlf .xliff Localisation Interchange File Format, но никаких преимуществ относительно .po не увидел.
|
58
|
+
|
59
|
+
Теоритических преград для портирования из необходимых исходных форматов в обе стороны нет.
|
60
|
+
|
61
|
+
Стоит отметить, что большинство форматов основаны на первичных ключах вида "main_window.options_group.first_name.hint". PO-файлы переводят фразы с одного языка на другой. При этом изначально разработчики делают перевод хотя бы на русский язык. Но этот перевод так же хотелось бы исправлять нетехническими людьми. К счастью, есть механизм в .po файле и для задачи ключей (msgctxt). Это поможет правильно сделать обратный экспорт в любом случае.
|
62
|
+
|
63
|
+
Но при изменении русского и английского текста старый перевод будет отображаться как неиспользуемый, а новая фраза как непереведенная. Такие правки лучше исправлять людьми, т.к. улучшенный исходный текст часто будет приводить и к более точному переведенному тексту.
|
64
|
+
|
65
|
+
4. Так какие же именно программы для редактирования переводов?
|
66
|
+
=================================
|
67
|
+
Проще всего в установке и использовании, бесплатный, достаточный по функционалу http://poedit.net .
|
68
|
+
Более навороченный Lokalize из проекта KDE.
|
69
|
+
Можно использовать и другие варианты при необходимости.
|
70
|
+
|
71
|
+
5. Как хранить переводы?
|
72
|
+
========================
|
73
|
+
Переводчики народ не очень технически грамотный. Научить их обращаться с Git проблематично. Поэтому можно сделать общую папку в сервисе Dropbox (или аналогичном, их тысячи).
|
74
|
+
|
75
|
+
6. Как структурировать папку переводов?
|
76
|
+
=======================================
|
77
|
+
На первом уровне шаблоны (.pot-файлы, .po-файлы без перевода) или переводы. На втором код языка, чтобы один язык можно было отдельно распространять. Затем название приложения, а уже внутри сами файлы переводов. Шаблоны на 2-х языках (рус. и англ.) в разные папки шаблонов, т.к. с них переводят. Пример:
|
78
|
+
Templates/
|
79
|
+
ru/
|
80
|
+
editor-windows/
|
81
|
+
main.pot
|
82
|
+
en/
|
83
|
+
editor-windows/
|
84
|
+
main.pot
|
85
|
+
Translations/
|
86
|
+
ru
|
87
|
+
editor-windows/
|
88
|
+
main.po //перевод с русского на русский, для исправлений текстов нетехническими людьми
|
89
|
+
en
|
90
|
+
editor-windows/
|
91
|
+
main.po //перевод с русского на английский, для исправлений текстов нетехническими людьми
|
92
|
+
fr
|
93
|
+
editor-windows/
|
94
|
+
main.po //перевод с английского на французский
|
95
|
+
sp
|
96
|
+
editor-windows/
|
97
|
+
main.po //перевод с русского на испанский
|
98
|
+
|
99
|
+
Такой вариант позволяет без конфликтов разным людям обновлять разные папки. По сути, над отдельной папкой (точнее файлом) не работает на запись более одного человека.
|
100
|
+
|
101
|
+
Это достигается односторонним потоком данных:
|
102
|
+
src --(developer)--> pot --(translator)--> po --(developer)--> src
|
103
|
+
Как исключение, если редактор, установленный у переводчика не поддерживает удобное добавление новых строк из обновленного pot-файла, то при обновлении pot-файла могут обновляться и соотв. po-файлы.
|
104
|
+
|
105
|
+
Естественно, если было бы несколько переводчиков на один язык, то пришлось бы использовать Git или другим способом координировать их работу.
|
106
|
+
|
107
|
+
7. Не ограничиваем программистов
|
108
|
+
================================
|
109
|
+
Программисты могут использовать любой удобный для их проекта формат файлов перевода. Хранить файлы у себя в проекте в любом месте и под любым именем. Иметь столько файлов переводов сколько им удобно. Одному файлу исходному будет соответствовать 1 файл pot и по кол-ву языков файлы po.
|
110
|
+
|
111
|
+
8. Как создавать файлы переводов?
|
112
|
+
=================================
|
113
|
+
Под каждый формат нужна утила конвертирования (она может быть и одна, и несколько). Нужно их или найти, или написать свои.
|
114
|
+
|
115
|
+
Разработчик у себя в проекте создает shell-скрипт или другим образом 2 задачи:
|
116
|
+
- на импорт переводов (копирование из папки Dropbox соотв. .po-файлов и конвертирование в нативный формат)
|
117
|
+
- на экспорт переводов (экспорт в .pot-формат и копирвание в папку шаблонов)
|
118
|
+
|
119
|
+
Gem 18n-po содержит библиотеку для простого написания собственных скриптов, т.к. при большом количестве исходных файлов и языков перевода появляется много однотипных задач.
|
120
|
+
|
121
|
+
Получается схема работы (пример):
|
122
|
+
- разработчик экспортирует перевод из нативного формата в файлы example.pot и example_dialogs.pot, они помещаются в папку Templates/ru/example/ в Dropbox
|
123
|
+
- переводчик на английский в редакторе открывает эти файлы, переводит и кладет файлы example.po и example_dialogs.po в папку Translations/en/example/
|
124
|
+
- разработчик example (или переводчик у которого настроен запуск) запускает конвертацию из переводов в шаблоны Templates/en/example. Аналогично и с русским языком, если его исправляли. В этот же момент для удобства можно сделать merge из pot в po файлы (если такое делается, то организационно нужно согласовать так, чтобы в это время файлы переводов этого приложения ни одним из переводчиков не обновлялись). Это шел-скрипт без параметров (для простоты запуска).
|
125
|
+
- переводчики на другие языки открывают шаблоны на русском или английском и переводят. Файлы .po кладут в папку своего языка и приложения. Если перевод уже был, то при обновлении .pot-файла редакторы сами заметят, что появились новые строки. Если редактор менее навороченный, то в п.1 при экспорте переводов нужно так же запустить утилиту из пакета gettext по слиянию переводов. При этом в .po файлах появятся непереведенне строки.
|
126
|
+
- разработчик запускает импорт переводов. Файлы из Dropbox переводятся в нативный формат и помещаются в нужные места в проекте.
|
127
|
+
|
128
|
+
9. Что делать с уже существующими переводами в нативном формате?
|
129
|
+
================================================================
|
130
|
+
Основная утила i18n-po поддерживает импорт/экспорт во все стороны. Разово пишем команды для фомирования исходных po-файлов.
|
131
|
+
|
132
|
+
10. Так как помещать новые непереведенные строки из .pot файлов в .po файлы?
|
133
|
+
============================================================================
|
134
|
+
В идеале это делает редактор. Иначе стандартный пакет для работы с файлами .po -- gettext -- содержит утилиту для этого. Через PO-редактор Catalog > Update from POT-file. Утила из gettext:
|
135
|
+
msgmerge --update example.po example.pot
|
136
|
+
|
137
|
+
11. Как конвертировать перевод в Android .xml формат из .po?
|
138
|
+
===========================================================
|
139
|
+
Пришлось свою утилу писать. Опубликована как i18n-po gem.
|
140
|
+
|
141
|
+
12. Как конвертировать перевод в .strings формат из .po?
|
142
|
+
========================================================
|
143
|
+
Пришлось свою утилу писать. Опубликована как i18n-po gem.
|
144
|
+
|
145
|
+
13. Как конвертировать перевод в .yml формат из .po?
|
146
|
+
====================================================
|
147
|
+
Пришлось свою утилу писать. Опубликована как i18n-po gem.
|
148
|
+
|
149
|
+
14. Как конвертировать перевод в .po формат из Android .xml?
|
150
|
+
===========================================================
|
151
|
+
Пришлось свою утилу писать. Опубликована как i18n-po gem.
|
152
|
+
|
153
|
+
15. Как конвертировать перевод в .po формат из .strings?
|
154
|
+
===========================================================
|
155
|
+
Пришлось свою утилу писать. Опубликована как i18n-po gem.
|
156
|
+
|
157
|
+
16. Как конвертировать перевод в .po формат из .yml?
|
158
|
+
===========================================================
|
159
|
+
Пришлось свою утилу писать. Опубликована как i18n-po gem.
|
160
|
+
|
161
|
+
17. Что из всего этого бекапить?
|
162
|
+
================================
|
163
|
+
Скрипты импорта/экспорта бекапятся как часть исходников. pot-файлы на ключах восстанавливаются из исходников. Нативные переводы восстанавливаются из .po-файлов, но не наоборот (такие утилы вне проекта, хотя и возможны). Поэтому нужно бекапить всю папку Dropbox, остальное не обязательно. Папку для бекапов можно добавлять в отдельный git-репозитарий, тогда будет бекапиться по процессу бекапа исходных текстов.
|
164
|
+
|
165
|
+
18. Нужен конвертор yml <--> po?
|
166
|
+
================================
|
167
|
+
Да. Причем нужна поддержка нескольких .yml-файлов (может генерироваться и несколько соотв. .po-файлов). И поддержка множественных форм. Конвертация в обе стороны. Проектов, которые бы удовлетворяли всем требованиям не было найдено.
|
168
|
+
|
169
|
+
19. Как добавлять новый язык?
|
170
|
+
=============================
|
171
|
+
Переводчики могут независимо из pot-файлов сделать po-файлы с переводом на новый язык. Программисты добавляют всю инфраструктуру вокруг нового языка самостоятельно: возможность его выбора, создание папок для файлов (для Apple и Android), сконвертированных из po, добавление нового языка в Locfile.
|
172
|
+
|
173
|
+
Как итог: какие сторонние программы использовались?
|
174
|
+
==================================================
|
175
|
+
1) poeditor.net
|
176
|
+
2) Dropbox
|
177
|
+
3) Gettext
|
178
|
+
4) Скрипты для автоматизации консольных команд
|
179
|
+
5) Собственный gem i18n-po для конвертаций из формата в формат и общая часть скриптов автоматизации
|
180
|
+
|
181
|
+
Что делать, если захочется статистику и прочее?
|
182
|
+
===============================================
|
183
|
+
Искать утилы для .po-файлов. Наверняка такое уже есть. Например, конвертация .po-файла в .pot:
|
184
|
+
msgfilter -i main.po -o main.pot --keep-header sed -e 's/.*//g;/^$/d'
|
185
|
+
|
186
|
+
Особенности реализации конвертации из Rails (.yml)
|
187
|
+
==================================================
|
188
|
+
Редакторы не поддерживают конструкции вида %{count}. Для plural сообщений используется автоматическая конвертация в C-format: %d <--> %{count}. В остальных случаях ничего не делается.
|
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2014 Igor Stepin <igor_for_os@stepin.name>
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
22
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/Readme.md
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
# i18n-po-tools
|
2
|
+
|
3
|
+
Utils to convert translations from source formats to PO/POT Gettex and vise versa. It allows to separate translations from development of apps.
|
4
|
+
|
5
|
+
Supported input/output formats:
|
6
|
+
* [iOS and OS X String Resources][http://developer.apple.com/documentation/Cocoa/Conceptual/LoadingResources/Strings/Strings.html] (format: ios)
|
7
|
+
* [Android String XML][http://developer.android.com/guide/topics/resources/string-resource.html] (format: android)
|
8
|
+
* [Gettext PO/POT][http://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/PO-Files.html] (format:po and pot)
|
9
|
+
* [Rails YAML][http://guides.rubyonrails.org/i18n.html] (format: rails-yaml)
|
10
|
+
* Basic flat YAML (format: flat-yaml)
|
11
|
+
* CVS for easy exchange with other apps (format: csv-yaml)
|
12
|
+
|
13
|
+
Direct converation between any formats supported.
|
14
|
+
|
15
|
+
About design decision you can read in the Design.txt.
|
16
|
+
|
17
|
+
Rails YAML and PO supports plural forms of messages. Example: 1 message, 2 messages.
|
18
|
+
|
19
|
+
Sorry, more info only in Russian in the Readme.re.md file.
|
20
|
+
|
21
|
+
|
22
|
+
## Installation
|
23
|
+
|
24
|
+
Add this line to your application's Gemfile:
|
25
|
+
|
26
|
+
gem 'i18n_po_tools'
|
27
|
+
|
28
|
+
And then execute:
|
29
|
+
|
30
|
+
$ bundle
|
31
|
+
|
32
|
+
Or install it yourself as:
|
33
|
+
|
34
|
+
$ gem install i18n_po_tools
|
35
|
+
|
36
|
+
|
37
|
+
## Usage
|
38
|
+
|
39
|
+
Command: i18n-po [OPTIONS]
|
40
|
+
|
41
|
+
Options
|
42
|
+
-i, --input FILENAME input filename (default STDIN)
|
43
|
+
-b, --base FILENAME base language input filename (only for po output mode)
|
44
|
+
-o, --output FILENAME output filename (default STDOUT)
|
45
|
+
-f, --from FORMAT input file format (default is autodetect by ext)
|
46
|
+
(rails_yaml, flat_yaml, po, pot, ios, android, csv)
|
47
|
+
-t, --to FORMAT output file format (default is autodetect by ext)
|
48
|
+
(rails_yaml, flat_yaml, po, pot, ios, android, csv)
|
49
|
+
-l, --language LANGUAGE input file language (only for po or rails_yaml output mode)
|
50
|
+
-h, --help help
|
51
|
+
|
52
|
+
Examples:
|
53
|
+
1) First import (generation of PO file) from Rails YAML file:
|
54
|
+
i18n-po --input ~/projects/rails_app/config/locales/devise.en.yml --language en \
|
55
|
+
--base ~/projects/rails_app/config/locales/devise.ru.yml \
|
56
|
+
--output ~/projects/translations/rails_app/devise.en.po
|
57
|
+
|
58
|
+
2) Generation of translation template (POT file) from Rails YAML file:
|
59
|
+
i18n-po --input ~/projects/rails_app/config/locales/devise.ru.yml \
|
60
|
+
--output ~/projects/translations/rails_app/devise.en.pot
|
61
|
+
|
62
|
+
3) Generation of Rails YAML file from PO file:
|
63
|
+
i18n-po --input ~/projects/translations/rails_app/devise.en.po --language en \
|
64
|
+
--output ~/projects/rails_app/config/locales/devise.en.yml
|
65
|
+
|
66
|
+
4) Translation convertation from iOS to Android format:
|
67
|
+
i18n-po --input ~/projects/ios_app/Localizable.strings \
|
68
|
+
--output ~/projects/android_app/en/strings.xml
|
69
|
+
|
70
|
+
|
71
|
+
## Contributing
|
72
|
+
|
73
|
+
1. Fork it
|
74
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
75
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
76
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
77
|
+
5. Create new Pull Request
|
data/Readme.ru.md
ADDED
@@ -0,0 +1,191 @@
|
|
1
|
+
# i18n-po-tools
|
2
|
+
|
3
|
+
Утилы для конвертирования переводов из исходных форматов в PO/POT Gettex и обратно. Позволяет разделить перевод и разработку программ.
|
4
|
+
|
5
|
+
Поддерживаемые форматы (в обе стороны):
|
6
|
+
* [iOS и OS X String Resources][http://developer.apple.com/documentation/Cocoa/Conceptual/LoadingResources/Strings/Strings.html] (формат: ios)
|
7
|
+
* [Android String XML][http://developer.android.com/guide/topics/resources/string-resource.html] (формат: android)
|
8
|
+
* [Gettext PO/POT][http://www.gnu.org/savannah-checkouts/gnu/gettext/manual/html_node/PO-Files.html] (формат: po или pot)
|
9
|
+
* [Rails YAML][http://guides.rubyonrails.org/i18n.html] (формат: rails-yaml)
|
10
|
+
* Простой плоский формат YAML (формат: flat-yaml)
|
11
|
+
* CVS для упрощенного обмена с другими программами (формат: csv-yaml)
|
12
|
+
|
13
|
+
Возможна прямая конвертация между любыми поддерживаемыми форматами.
|
14
|
+
|
15
|
+
Почему проект получился таким каким получился можно прочитать в Design.ru.txt.
|
16
|
+
|
17
|
+
Rails YAML и PO поддерживают специальный вид строк для переводов, зависящих от чисел (plurals). Пример: 1 сообщение, 6 сообщений.
|
18
|
+
|
19
|
+
|
20
|
+
## Установка
|
21
|
+
|
22
|
+
Добавьте строчку в Gemfile:
|
23
|
+
|
24
|
+
gem 'i18n_po_tools'
|
25
|
+
|
26
|
+
и запустите:
|
27
|
+
|
28
|
+
$ bundle
|
29
|
+
|
30
|
+
Или установка без Gemfile:
|
31
|
+
|
32
|
+
$ gem install i18n_po_tools
|
33
|
+
|
34
|
+
|
35
|
+
## Использование
|
36
|
+
|
37
|
+
Утила: i18n-po [Опции]
|
38
|
+
|
39
|
+
Опции
|
40
|
+
-i, --input FILENAME input filename (default STDIN)
|
41
|
+
-b, --base FILENAME base language input filename (only for po output mode)
|
42
|
+
-o, --output FILENAME output filename (default STDOUT)
|
43
|
+
-f, --from FORMAT input file format (default is autodetect by ext)
|
44
|
+
(rails_yaml, flat_yaml, po, pot, ios, android, csv)
|
45
|
+
-t, --to FORMAT output file format (default is autodetect by ext)
|
46
|
+
(rails_yaml, flat_yaml, po, pot, ios, android, csv)
|
47
|
+
-l, --language LANGUAGE input file language (only for po or rails_yaml output mode)
|
48
|
+
-h, --help help
|
49
|
+
|
50
|
+
Примеры:
|
51
|
+
1) Первоначальный импорт перевода (генерация po-файла) из Rails yml-файла:
|
52
|
+
i18n-po --input ~/projects/rails_app/config/locales/devise.en.yml --language en \
|
53
|
+
--base ~/projects/rails_app/config/locales/devise.ru.yml \
|
54
|
+
--output ~/projects/translations/rails_app/devise.en.po
|
55
|
+
|
56
|
+
2) Генерация шаблона для перевода (pot-файла) из Rails yml-файла:
|
57
|
+
i18n-po --input ~/projects/rails_app/config/locales/devise.ru.yml \
|
58
|
+
--output ~/projects/translations/rails_app/devise.en.pot
|
59
|
+
|
60
|
+
3) Генерация Rails yml-файла из переведенного po-файла:
|
61
|
+
i18n-po --input ~/projects/translations/rails_app/devise.en.po --language en \
|
62
|
+
--output ~/projects/rails_app/config/locales/devise.en.yml
|
63
|
+
|
64
|
+
4) Конвертация файла перевода из iOS-формата в Android:
|
65
|
+
i18n-po --input ~/projects/ios_app/Localizable.strings \
|
66
|
+
--output ~/projects/android_app/en/strings.xml
|
67
|
+
|
68
|
+
|
69
|
+
## Как работает механизм переводов на базе i18n-po?
|
70
|
+
Системой пользуются 2 роли пользователей: переводчики и разработчики прикладных программ.
|
71
|
+
|
72
|
+
Источником данных являются .po-файлы. Файлы в приложениях -- автосгенерированы из .po-файлов.
|
73
|
+
|
74
|
+
|
75
|
+
## Со стороны переводчиков
|
76
|
+
У переводчиков есть папка в Dropbox (или аналогичном сервисе). Они открывают папку своего языка в [PO Editor](http://poedit.net) (доступен под Windows,
|
77
|
+
Mac OS X и Linux), выбирают язык для перевода и переводят.
|
78
|
+
|
79
|
+
Структура папки:
|
80
|
+
Templates/
|
81
|
+
ru/
|
82
|
+
example-app/
|
83
|
+
main.pot
|
84
|
+
en/
|
85
|
+
example-app/
|
86
|
+
main.pot
|
87
|
+
Translations/
|
88
|
+
ru/
|
89
|
+
example-app/
|
90
|
+
main.po //перевод с русского на русский, для исправлений текстов нетехническими людьми
|
91
|
+
en/
|
92
|
+
example-app/
|
93
|
+
main.po //перевод с русского на английский, для исправлений текстов нетехническими людьми
|
94
|
+
fr
|
95
|
+
example-app/
|
96
|
+
main.po //перевод с английского на французский
|
97
|
+
sp
|
98
|
+
example-app/
|
99
|
+
main.po //перевод с русского на испанский
|
100
|
+
|
101
|
+
pot-файлы -- это те же файлы .po, но без переводов.
|
102
|
+
|
103
|
+
Когда обновляется перевод в программе, то обновляются только
|
104
|
+
.pot-файлы. Уже сам редактор замечает, что они обновились и предлагает
|
105
|
+
доперевести их в .po-файле. Если редакторы без этой функции, то можно автоматически обновлять и переводы, но нужно договориться в этот момент не править переводы переводчикам.
|
106
|
+
|
107
|
+
Первоначальный импорт уже созданных переводов так же можно сделать, что уже было переведено не пропадет.
|
108
|
+
|
109
|
+
Зачем пользоваться специальным программами, если можно открыть .po-файл в текстовом редакторе?
|
110
|
+
1) Всегда корректный синтаксис файла, случайно "не сломаешь" его.
|
111
|
+
2) В редакторах, как правило, есть база перевода. Позволит аналогично переводить похожие сообщения.
|
112
|
+
3) Через некоторое время осознаешь и другие преимущества использования специализированной программы (удобный интерфейс именно для переводов, статистика и т.п.)
|
113
|
+
|
114
|
+
|
115
|
+
## Со стороны разработчиков
|
116
|
+
Готовите переводы в стандартных для своей платформы форматах.
|
117
|
+
Затем с помощью i18n-po переводите в po-файлы. Кол-во po-файлов
|
118
|
+
соответствует количеству исходных файлов.
|
119
|
+
|
120
|
+
В папке Dropbox должны присутствовать только файлы форматов .po и .pot,
|
121
|
+
чтобы не путать переводчиков.
|
122
|
+
|
123
|
+
Добавляете скрипты (или другим образом оформляете задачи) извлечения переводов
|
124
|
+
из исходников (в po-файлы) и выгрузки в исходники (в Rails yml,
|
125
|
+
iOS/MacOSX .strings, Android .xml). Используется консольная
|
126
|
+
утилитиа i18n-po. Так же они копируют новые шаблоны для переводов в Dropbox.
|
127
|
+
|
128
|
+
Рекомендуется, чтобы разработчики имели доступ к этому репозитарию и папке
|
129
|
+
Dropbox. Тогда они сами смогут обновлять шаблоны для переводов и импортировать
|
130
|
+
новые переводы.
|
131
|
+
|
132
|
+
При подготовке строк для перевода рекомендуется следовать https://techbase.kde.org/Development/Tutorials/Localization/i18n_Mistakes .
|
133
|
+
|
134
|
+
Источником переводов может быть несколько любых языков.
|
135
|
+
|
136
|
+
Первоначальное добавление языков в код своего проекта -- на стороне разработчиков, т.к. сильно зависит от программной платформы проекта и самого проекта. Для iOS, Mac OS X и Android -- это создание соотв. папок.
|
137
|
+
|
138
|
+
|
139
|
+
Замечания по сторонним программным продуктам
|
140
|
+
============================================
|
141
|
+
1) Вместо Dropbox можно использовать другие аналогичные решения. Переводчикам проще обращаться с таким решением, чем с полноценными репозитариями (например Git).
|
142
|
+
|
143
|
+
2) Вместо poedit.net можно использовать Localize из KDE http://l10n.kde.org/docs/translation-howto/gui-specialized-apps.html#lokalize . Его ставить сложнее, но по функционалу лучше.
|
144
|
+
|
145
|
+
3) Формат po-файлов позволяет использовать множество утил и программ, он известен практически всем, кто занимается переводами программ. Более того утила i18n-po поддеживает конвертацию во множество форматов, включая CSV.
|
146
|
+
|
147
|
+
|
148
|
+
Особенности реализации конвертации из Rails
|
149
|
+
===========================================
|
150
|
+
Редакторы не поддерживают конструкции вида %{count}. Для plural сообщений используется автоматическая конвертация в C-format: %d <--> %{count}. В остальных случаях ничего не делается.
|
151
|
+
|
152
|
+
|
153
|
+
## Интересные проекты
|
154
|
+
1) https://github.com/mrmans0n/localio
|
155
|
+
Сделан для перевода через гуглотаблицы. Содержит некоторые другие форматы (JSON). Из минусов: не поддерживает plurals, некоторые форматы (po). Возможны проблемы с escaping'ом.
|
156
|
+
|
157
|
+
2) https://github.com/netbe/Babelish
|
158
|
+
Основой является текстовый файл в csv формате. Соотв., нет поддержки PO и plurals.
|
159
|
+
|
160
|
+
3) https://github.com/mobiata/twine
|
161
|
+
Основой является текстовый файл в ini-подобном формате.
|
162
|
+
Поддерживает экспорт во множество форматов.
|
163
|
+
|
164
|
+
4) http://olshansk.github.io/ios_localizer/
|
165
|
+
Осуществляет автоматический перевод ios-файлов с помощью Google Translate.
|
166
|
+
Если вдруг нужно сделать плохой (зато дешевый -- $20 per 1M characters) автоматический перевод. Далее с помощью i18n-po преобразовать в любой нужный формат.
|
167
|
+
|
168
|
+
5) https://localise.biz/free/converter/yml
|
169
|
+
Online-конвертор файла в разные форматы. Пока что бесплатно. Плюсы -- множество форматов. Минус -- в любой момент может стать платным или перестать работать. Так же нет генерации po-файла из 2х исходных файлов (перевод человеческого текста, не ключей).
|
170
|
+
|
171
|
+
6) http://pology.nedohodnik.net/
|
172
|
+
Библиотека на Python для автоматизации манипуляций с po-файлами. Интересно, если писать дополнительные утилы манипуляций с переводами.
|
173
|
+
|
174
|
+
7) https://github.com/grosser/get_pomo
|
175
|
+
Если для автоматизации больше нравится Ruby, то эта библиотека поможет.
|
176
|
+
|
177
|
+
8) https://github.com/pejuko/i18n-translators-tools
|
178
|
+
Интересный, но заброшенный проект. К сожалению, вмешивается в то как Rails читает файлы переводов и в каком формате они должны быть.
|
179
|
+
|
180
|
+
9) https://github.com/airbnb/polyglot.js
|
181
|
+
Интересный проект для переводов web-части приложений. Пока что не поддерживается i18n-po, но есть все шансы.
|
182
|
+
|
183
|
+
|
184
|
+
## Contributing
|
185
|
+
|
186
|
+
1. Fork it
|
187
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
188
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
189
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
190
|
+
5. Create new Pull Request
|
191
|
+
|
data/bin/i18n-po
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'i18n_po_tools/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "i18n_po_tools"
|
8
|
+
spec.version = I18nPoTools::VERSION
|
9
|
+
spec.authors = ["Igor Stepin"]
|
10
|
+
spec.email = ["igor_for_os@stepin.name"]
|
11
|
+
spec.homepage = "http://github.com/stepin/#{spec.name}"
|
12
|
+
spec.license = "MIT"
|
13
|
+
spec.summary = "Utils to convert translations from source formats to PO/POT Gettex and vise versa."
|
14
|
+
spec.description = <<EOF
|
15
|
+
Utils to convert translations from source formats to PO/POT Gettex and vise versa.
|
16
|
+
It allows to separate translations from development of apps.
|
17
|
+
|
18
|
+
Supported input/output formats:
|
19
|
+
* iOS and OS X String Resources
|
20
|
+
* Android String XML
|
21
|
+
* Gettext PO/POT
|
22
|
+
* Rails YAML
|
23
|
+
* Basic flat YAML
|
24
|
+
* CVS for easy exchange with other apps
|
25
|
+
|
26
|
+
Direct converation between any formats supported.
|
27
|
+
|
28
|
+
Rails YAML and PO supports plural forms of messages.
|
29
|
+
EOF
|
30
|
+
|
31
|
+
spec.files = `git ls-files`.split($/)
|
32
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
33
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
34
|
+
spec.require_paths = ["lib"]
|
35
|
+
|
36
|
+
#for Android files support
|
37
|
+
spec.add_runtime_dependency "nokogiri"
|
38
|
+
#for PO files support
|
39
|
+
spec.add_runtime_dependency "get_pomo", "= 0.9.0"
|
40
|
+
#for blank?/present?
|
41
|
+
spec.add_runtime_dependency "activesupport", "~> 4.1.6"
|
42
|
+
|
43
|
+
|
44
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
45
|
+
spec.add_development_dependency "rake"
|
46
|
+
spec.add_development_dependency "gem-release"
|
47
|
+
end
|