Giter VIP home page Giter VIP logo

android2po's Introduction

android2po

image

Convert Android string resources to gettext .po files, and import them right back.

The goal is to remove as many syntax elements required by the Android string resource files when exporting, to present the text to translators in as easy a format as possible; and correctly writing everything back to Android on import while keeping the generated XML files easily readable as well (i.e. no unnecessary escaping).

Requirements

The following Python modules are required, and will mostly be auto-installed. See Installation below.

babel

http://babel.pocoo.org/

lxml

http://codespeak.net/lxml/

argparse

http://argparse.googlecode.com/

Since the .po files this script generates use contexts (msgctx), that's what you're gettext software will have to support as well.

Installation

To install the current release, you can simply do:

$ easy_install android2po

That's it!

If you want to install the current development version of android2po instead, get the source code, then run:

$ python setup.py install

setup.py should automatically install all the dependencies. Alternatively, you can also use pip if you prefer:

$ pip install -r requirements.pip

Usage

The basic idea is that:

  • values/strings.xml holds the reference strings in their original language (the gettext msgid fields).
  • The gettext .po files generated and updated by this script contain the reference version of the translations.
  • The values-XX/strings.xml files are fully generated based on your .po files, and should not be modified manually.

In addition to your authoritative strings.xml file, you will usually also want to keep your .po files in source control; The generated language-specific strings.xml files then contain no additional information, and do not need to be source controlled, though you are free to if you like.

The environment

To be able to run, the script necessarily needs to know about two filesystem locations: The directory where your Android resources are located, and the directory where the gettext .po files should be stored:

$ a2po COMMAND --android myproject/res --gettext myproject/locale

However, to simplify usage, the program will automatically try to detect the location of these folders, as follows:

  • It will search the directory hierarchy, starting with the your working directory, for a AndroidManifest.xml or .android2po file.
  • As soon as it finds either of those files, it will stop, and consider the it's location the project directory.
  • Unless explicitly overriden by you, it will place the .po files in a subdirectory ./locale of that project directory.
  • Only if a AndroidManifest.xml file is in the project directory will it assume that the Android resources are located in a subfolder named ./res.
  • If a .android2po file is in the project directory, it automatically will be loaded as a configuration file. See the section below on the format of the configuration file, and possible values.
  • The script automatically processes all the languages it can find. It will normally look at the existing .po files to determine the list of languages, with the exception of the init command, in which case the list of languages inside the Android resource directory will be used.

Initial setup

When switching to android2po, you will first want to create an initial export of your current translations.

$ a2po init

This will ignore any languages for which a .po file already exists.

For testing purposes, you may want to immediately import the generated files back in, to compare with what you originally had, and make sure the script was able to process your files correctly. At this point, make sure you have a backup, since your language-specific strings.xml files are going to be replaced (you are using source control, right?!):

$ a2po import
$ git diff --ignore-all-space res/values-XX/strings.xml

In the example above, git is used for source control. git provides a nice option to show a diff while ignoring whitespace changes, which will make it much easier to spot problems with the import. If you use a different tool, see if there is a comparable feature.

Hopefully, your translated XML files at this point hold the same information as before. The whitespace will probably have changed, comments will have been removed, and some strings may have changed visually (i.e. use different escaping). However, their meaning should not have changed. If it has, please report a bug.

Updating

After hacking on your code for a while, you have changed some strings (in your authoritative values/strings.xml file), and now you need to pass those on to your translators through your .po files.

Simply do:

$ a2po export

This will update your .po files with your changes.

Importing

Your translators have come back to you with their changes, and you want to include them in the next build. Simply do:

$ a2po import

This will fully regenerate your language-specific strings.xml based on the gettext .po files.

You can do this step manually, or add it to your build process.

Adding a new language

As noted above, android2po will automatically process all the languages it can find, based on the .po files that exist. To add a new language, simply run

$ a2po init {LANGUAGE CODES}

For example:

$ a2po init de fr

This will create both new .po and strings.xml files for German and French.

You are also free to simply create the appropriate strings.xml files yourself, and let

$ a2po init

initialize their proper .po counterparts (in case of the init command, the languages found in the Android resource directory will be processed).

Configuration file

A configuration file can be used to avoid manually specifying all the required options. The format of the file is simply a list of command line option, each specified on a line of it's own. For example:

--no-template
# Paths - don't specify --android, default location is used.
--gettext ../locale

As you can see, comments are supported by using #, and the mechanism to automatically try to detect the directories for .po files and Android strings.xml files is still in place if you don't specify locations explicitly.

The configuration file may be specified by using the --config option. Alternatively, if a .android2po file is found in the project directory, it will be used.

See --help for a list of possible configuration options. There's also an example configuration file in example.config that you can have a look at, or use as a template for your own.

Plurals support

<plurals> are supported, but merit some additional explanation.

Android's plural support is based on CLDR keywords like "one" and "many". The rules specifying which quantity n maps to which keyword are built into Android itself, by way of the CLDR database. It is important to understand that a keyword like "one" may be used for quantities other then 1.

In the gettext system, on the other hand, each catalog has the ability to define the plural rules it wants to use itself, via an expression like nplurals=2; plural=((n == 1) ? 0 : 1). The expression returns the index of the string to use for the quantity n.

android2po converts between those two system in the following way:

  • When writing .po files, it will generate a plural rule expression like above based on the CLDR data, custom-fit for the language in question. The result is a .po file that defines as many plural forms as required for the language, and your translation tool will ask for a different string for each plural form.
  • During import, it will generate a <plurals> tag with the correct quantity keywords based on it's knowledge (CLDR) about which such keywords the language supports.
  • The init command, having to convert existing <plurals> tags to gettext, will pick those quantity keywords the language supports, and ignore others (and display a warning in those cases).
  • The export command will ensure that the catalog uses the correct plural definition, but it otherwise does not have to deal with individual plural forms / quantities.

If this is confusing, consider the issue: Android lets you define a number of different quantity keywords for each <plurals> element, but ignores all keywords that are not supported by the language (see this erroneous bug report). gettext only allows you to define a fixed number of plural rules, as many as the language purports to require via the catalog's plural rule expression.

To cleanly convert between the two systems, we are forced to ignore keywords in an Android XML resource that are really not supported - but only if Android itself would also ignore them. So view this as essentially a validation feature.

A final note: plurals can be complex (and there are many languages) and the CLDR database is regularly updated. In French, whether 0 is treated as plural or singular possibly even depends on the dialect. As such, you may find that different plural rules for the same languages are in use in the wild. android2po uses the CLDR rules, but not necessarily the same version as Android does, and Android presumably will upgrade their CLDR version over time as well. I think the goal here would be to always make android2po use a reasonably recent version of the CLDR data, and accept that old Android versions with outdated plural information might not be able to correctly internationalize some plural strings into into those languages where the data is incorrect.

Further reading:

The CLDR plural system and rules

http://unicode.org/repos/cldr-tmp/trunk/diff/supplemental/language_plural_rules.html http://cldr.unicode.org/index/cldr-spec/plural-rules

Plural information about various languages:

http://translate.sourceforge.net/wiki/l10n/pluralforms https://translations.launchpad.net/+languages https://developer.mozilla.org/en/Localization_and_Plurals

Understanding / Debugging the android2po

If something doesn't work as expected, it may be helpful to understand which files are processed how and when:

On init, android2po will take your language-neutral (English) values/strings.xml file and convert it to a .pot template.

Further on init, if there are existing values-{lang}/strings.xml files, it will take the strings from there, match them with the strings in the language-neutral values/strings.xml file, and generate .po files for these languages which already contain translations, in addition to the template. This is the only time that the values-{lang}/strings.xml files will be looked at and considered.

On export, android2po will take the language-neutral values/strings.xml file, generate a new .pot template, and then merge the new template into any existing .po catalogs, i.e. update the .po catalogs for each language with the changes. This is how gettext normally works (msgmerge). The values-{lang}/strings.xml files do not play a role here.

On 'import', android2po will only look at the .po catalogs for each language and generate values-{lang}/strings.xml files, without looking at anything else.

Notes

Initially based on:

http://code.google.com/p/openintents/source/browse/tools/Androidxml2po/androidxml2po.bash

http://www.gnu.org/software/hello/manual/gettext/PO-Files.html

GNU PO file format docs.

http://docs.oasis-open.org/xliff/v1.2/xliff-profile-po/xliff-profile-po-1.2.html

Explains the gettext format according to how xliff interprets it.

http://www.artfulbits.com/Android/aiLocalizer.aspx

App to localize Android xml string files directly. They seems to be involved with the Ukrainian translation of Android itself.

http://groups.google.com/group/android-platform/browse_thread/thread/a2626195205e8543

Notes that Google internally manages Android translations in their own system.

There is a converter from and to XLIFF in frameworks/base/tools/localize, which might be what they are using. It looks pretty decent too. Why isn't this promoted more?

https://launchpad.net/intltool

Converts to and from .po und "can be extended to support other types of XML" - sounds like something we could've used? It's Perl though, ugh.

android2po's People

Contributors

amvasilyev avatar bkeller-vuzix avatar brot avatar bugsbegone avatar gforcada avatar hansfn avatar imankulov avatar kruton avatar mauriciogior avatar miracle2k avatar rv0 avatar tosky avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

android2po's Issues

a2po export

There doesn't seem to be a way to prevent a2po export from exporting all initialized languages. Since exporting is pretty CPU intensive / slow, would it be possible to add a --no-languages option to only export the .pot file?

n/a

Missclick, can be deleted

Translate plurals files into po files ?

Hi,

don't really know if this is possible or you explained it somewhere. But i am looking for a solution to also transform my separated plural files into po files and back?

Or in genaral what is your work arround for something like this.

<plurals name="delete_entries">
        <item quantity="one">entry deleted!</item>
    <item quantity="other">entries deleted!</item>
</plural>

This can be even more example as i am also using a different format:

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">

Cheers
tobias

P.S.: Thanks for the great work already, its really cool that its possible to integrate android translation into pootle :)

Doesn't unescape XML.

If my strings.xml has a string such as this:

<string name="about_text2">This android app was developed by &lt;a href="http://murrayc.com/&quot;&gt;Murray Cumming&lt;a&gt;</string>

Then the strings.pot file (and the strings-*.po files) contains this:

msgctxt "about_text2"
msgid ""
"This android app was developed by &lt;a "
"href=http://murrayc.com/&gt;Murray Cumming&lt;a&gt;"
msgstr ""

These lt, gt and quot entities are entirely specific to XML so I wouldn't expect to see them in the .po file for translators to see.

I think there are at least some cases (full HTML to show in an HTML view?) where people really need to correctly escape their markup in strings.xml.

This could get awkward because Android also accepts unescaped markup in strings.xml, in which case it seems to parse the resulting child nodes and pretend that nothing odd happened. And that's actually the only way to have an a link in your TextView's text when specifying the text via the layout XML, so I have to set these in code via Html.fromHtml(getString(R.string.something)).

I actually started using the correct XML escaping in my strings.xml because a2po adds quotes around the strings when importing them back into strings.xml. Android seemes to ignore them, but it seemed odd and I considered it a bug in my strings.xml ratherr than a problem with a2po.

Add support for using single files

I got strings.xml dialog.xml in EN and PL languages for one Android application. Checked your tool as a way to get it done using gettext based tools but I fail to get it working:

14:57 hrw@puchatek:ussdchecker$ ls -R
.:
res

./res:
values values-pl

./res/values:
dialog.xml strings.xml

./res/values-pl:
dialog.xml strings.xml
14:57 hrw@puchatek:ussdchecker$ a2po --android $PWD/res --gettext . init
usage: a2po [-h] [--version] {import,init,export} ...
a2po: error: argument command: invalid choice: '/home/hrw/HDD/devel/devices/android/t\xc5\x82umaczenia/ussdchecker/res' (choose from 'import', 'init', 'export')

babel 0.9.6, other deps are installed too.
Ubuntu 11.10 'oneiric'

Single % sign in strings.xml

Hi

If a string in strings.xml contains a single "%" which should be shown in the UI, android2po doesn't seem to convert this into "%%" upon export, and back into "%" upon import. Shouldn't it do this? If I use "%%" in strings.xml, both are shown in the UI.

If I'm not mistaken, a string like:
"VAT in Denmark is 25%" should be converted into "VAT in Denmark is 25%%"
while:
"My name is %1$s." should remain with one %.

I have a translator mentioning that this causes problems in the translation process.
Please see: pryds/ve#15

'00A9' what is it?

$ a2po init zh_CN
'00A9'
'00A9'
[created] locale/zh_CN.po
[mkdir] res/values-zh-rCN
[created] res/values-zh-rCN/strings.xml

I thought it was supposed to create:
[created] locale/strings-zh_CN.po

No?

Merge arrays-*.po (and arrays.pot) and strings-*.po (and strings.pot)

Translators expect to deal with only one .po file, so it's awkward that we a2po generates a separate set of po/pot files for each XML file that has translatable strings. It would be great if they could be merged into one file, though I guess there would need to be some marker to identify the source so they could be imported back into the correct XML again.

Python 3?

Is support for python 3 planned?

Our project https://github.com/Softcatala/translation-memory-tools relies on android2po, and as we are thinking on supporting python 3 our dependencies also need to support it too.

If there's no plans but a pull request would be welcome we will evaluate it and try to contribute it.

Don't mark formated strings as c-format

If we have a string like

<plurals name="received_files_title">
    <item quantity="one">Received file from %2$s</item>
    <item quantity="other">Received %1$d files from %2$s</item>
</plurals>

a2po will create

#, c-format
msgctxt "received_files_title"
msgid "Received file from %2$s"
msgid_plural "Received %1$d files from %2$s"
msgstr[0] ""
msgstr[1] ""

But the problem is that adding c-format enforces that the translation strings contain both %1 and %2 since printf c-format can't skip strings while android can.

So I think it's better not to include c-format, does that make sense to you?

fy-NL is not a valid locale

One of ours apps is getting localized to Frisian (Netherlands), locale: fy-NL. However importing/exporting fails with:

[failed] fy-NL is not a valid locale

a2po command-line format ambiguity

The following command-line
a2po export --groups strings -
is intended to only export the group strings and only the template (no languages), but --groups is greedy and interprets the - as a group, not a language.

Perhaps an explicit (but optional) --languages option should be used...

KeyError: 'plural_form'

As a test I took the source for the stock android alarm clock (deskclock) available at Google source and ran a2po init.
It crashes due to the plurals. I removed all plurals from the default values/strings.xml (but not the translations) and got the same error.

....
'0021'
   [created] locale\hi.po
'0021'
   [created] locale\hr.po
'0021'
   [created] locale\hu.po
'0021'
    [failed] locale\hy_AM.po
Traceback (most recent call last):
  File "C:\Users\Ben\DEV\WinPython-64bit-2.7.9.3\python-2.7.9.amd64\Scripts\a2po-script.py", line 9, in <module>
    load_entry_point('android2po==1.2.0', 'console_scripts', 'a2po')()
  File "C:\Users\Ben\DEV\WinPython-64bit-2.7.9.3\python-2.7.9.amd64\lib\site-packages\android2po-1.2.0-py2.7.egg\android2po\program.py", line 226, in run
    sys.exit(main(sys.argv) or 0)
  File "C:\Users\Ben\DEV\WinPython-64bit-2.7.9.3\python-2.7.9.amd64\lib\site-packages\android2po-1.2.0-py2.7.egg\android2po\program.py", line 214, in main
    command_result = cmd.execute()
  File "C:\Users\Ben\DEV\WinPython-64bit-2.7.9.3\python-2.7.9.amd64\lib\site-packages\android2po-1.2.0-py2.7.egg\android2po\commands.py", line 423, in execute
    ignore_exists=show_exists):
  File "C:\Users\Ben\DEV\WinPython-64bit-2.7.9.3\python-2.7.9.amd64\lib\site-packages\android2po-1.2.0-py2.7.egg\android2po\commands.py", line 342, in generate_po
    ignore_exists=ignore_exists)
  File "C:\Users\Ben\DEV\WinPython-64bit-2.7.9.3\python-2.7.9.amd64\lib\site-packages\android2po-1.2.0-py2.7.egg\android2po\commands.py", line 182, in write_file
    content = content()
  File "C:\Users\Ben\DEV\WinPython-64bit-2.7.9.3\python-2.7.9.amd64\lib\site-packages\android2po-1.2.0-py2.7.egg\android2po\commands.py", line 323, in make_catalog
    language_data)
  File "C:\Users\Ben\DEV\WinPython-64bit-2.7.9.3\python-2.7.9.amd64\lib\site-packages\android2po-1.2.0-py2.7.egg\android2po\commands.py", line 80, in xml2po
    return convert.xml2po(*a, **kw)
  File "C:\Users\Ben\DEV\WinPython-64bit-2.7.9.3\python-2.7.9.amd64\lib\site-packages\android2po-1.2.0-py2.7.egg\android2po\convert.py", line 490, in xml2po
    set_catalog_plural_forms(catalog, translations.language)
  File "C:\Users\Ben\DEV\WinPython-64bit-2.7.9.3\python-2.7.9.amd64\lib\site-packages\android2po-1.2.0-py2.7.egg\android2po\convert.py", line 460, in set_catalog_plural_forms
    language.locale.plural_form)
  File "C:\Users\Ben\DEV\WinPython-64bit-2.7.9.3\python-2.7.9.amd64\lib\site-packages\babel-1.0.dev0-py2.7.egg\babel\core.py", line 610, in plural_form
    return self._data['plural_form']
  File "C:\Users\Ben\DEV\WinPython-64bit-2.7.9.3\python-2.7.9.amd64\lib\site-packages\babel-1.0.dev0-py2.7.egg\babel\localedata.py", line 195, in __getitem__
    orig = val = dict.__getitem__(self, key)
KeyError: 'plural_form'

[improvement] Add option to ignore strings that have the translatable="false"

When exporting resources file that contains definitions of strings with attribute translatable=false they make it into the .po file.
This seems like an undesirable behavior as the attribute clearly states that given string should not be translated thus it should not be written to the *.po file.
It would be really nice to see this added.

And in the meantime there is a simple workaround, it is enough to place your non-translatable strings in the donottranslate.xml file(see http://tools.android.com/recent/non-translatablestrings).

Babel-1.0dev isn't installable because "elsdoerfer.name" is down

Hi,

It seems python setup.py install fails with the following message:

Downloading http://elsdoerfer.name/download/android2po/files/Babel-1.0dev.tar.gz
error: http://elsdoerfer.name/download/android2po/files/Babel-1.0dev.tar.gz returned a bad status line. The server might be down, 

I think it's possible to modify setup.py to install the latest Babel, but I think elsdoerfer.name is your own domain. Can you fix it? Or should I locally modify setup.py to download the latest version of Babel?

Thanks,

Error on unicode character \u00A0

When using Unicode character \u00A0 (non-breaking whitespace) in a strings.xml, I get the crash below. Anything wrong with my configuration (if there is any) or any quick fix for that?


u'00A0'
u'00A0'
u'00A0'
[failed] locale/strings.pot
Traceback (most recent call last):
File "/usr/local/bin/a2po", line 3, in
android2po.run()
File "/usr/local/lib/python2.7/dist-packages/android2po/program.py", line 227, in run
sys.exit(main(sys.argv) or 0)
File "/usr/local/lib/python2.7/dist-packages/android2po/program.py", line 215, in main
command_result = cmd.execute()
File "/usr/local/lib/python2.7/dist-packages/android2po/commands.py", line 464, in execute
self.generate_templates()
File "/usr/local/lib/python2.7/dist-packages/android2po/commands.py", line 293, in generate_templates
kind, do_write=True, update=update)
File "/usr/local/lib/python2.7/dist-packages/android2po/commands.py", line 264, in make_or_get_template
xmldata = read_xml(action, self.env.default.xml(kind))
File "/usr/local/lib/python2.7/dist-packages/android2po/commands.py", line 63, in read_xml
return convert.read_xml(filename, warnfunc=action.message, **kw)
File "/usr/local/lib/python2.7/dist-packages/android2po/convert.py", line 370, in read_xml
text, formatted = get_element_text(tag, name, warnfunc)
File "/usr/local/lib/python2.7/dist-packages/android2po/convert.py", line 310, in get_element_text
converted_value, elem_formatted = convert_text(t)
File "/usr/local/lib/python2.7/dist-packages/android2po/convert.py", line 242, in convert_text
return "".join(text[:-1]), formatted
UnicodeDecodeError: 'ascii' codec can't decode byte 0xa0 in position 0: ordinal not in range(128)

line wrapping width system dependent

I am using a2po for the same project on two different systems (Ubuntu 14.04 and 16.04).
Apparently a2po is using different paragraph widths for line wrapping on both systems, which results in a lot of diffs like this:

-"The image file is missing. Unfortunately, you cannot edit the image without.\n"
+"The image file is missing. Unfortunately, you cannot edit the image "
+"without.\n"

when switching between systems. It would be great to fix the paragraph width with a command line parameter to prevent this problem.

String arrays with missing translations

a2po exports an Android string array such as to keys like my_strings:1, etc.

If some of the strings in the string-array are not translated in some languages (for example, a new string is added to the array in the default language, but some of the translators haven't had a chance to translate it yet), when the array is imported back in to the Android xml, it will be missing some items for the affected languages, and if that array is used in a Preference, the Preference will be missing some items.

It would be better to either force the default values for the missing array items, or to fully remove the array from the Android xml if any item is missing.

Word-wrapped XML gets corrupted

In 1.1.0, this worked fine, but with 1.2-dev, when processing XML like

<string name="name">Part of the string
but continues here
and here</string>

a2po export chokes and corrupts the .pot output.

Python 2.5 is not supported (Error running a2po)

Hi
I've installed all the prerequisits that I think I need to and Pootle is running fine, but when I run the a2po command I always get the same error regardless of the parameters passed to it.

a2po
Traceback (most recent call last):
File "/usr/bin/a2po", line 8, in
load_entry_point('android2po==1.1.0', 'console_scripts', 'a2po')()
File "/usr/lib/python2.5/site-packages/pkg_resources.py", line 318, in load_entry_point

File "/usr/lib/python2.5/site-packages/pkg_resources.py", line 2221, in load_entry_point

File "/usr/lib/python2.5/site-packages/pkg_resources.py", line 1954, in load
"EntryPoint must be in 'name=module:attrs [extras]' format",
File "/usr/lib/python2.5/site-packages/android2po-1.1.0-py2.5.egg/android2po/init.py", line 5, in
from program import *
File "/usr/lib/python2.5/site-packages/android2po-1.1.0-py2.5.egg/android2po/program.py", line 15, in
from .commands import InitCommand, ExportCommand, ImportCommand, CommandError
File "/usr/lib/python2.5/site-packages/android2po-1.1.0-py2.5.egg/android2po/commands.py", line 14, in
from .env import Language
File "/usr/lib/python2.5/site-packages/android2po-1.1.0-py2.5.egg/android2po/env.py", line 257
return Path(*pargs, base=self.project_dir)
^
SyntaxError: invalid syntax

I'm not sure what I might be missing. Any suggestions?

Changing the output folder

Right now everything is saved on "locale".
As far as I know launchpad needs to have this folder called exactly the same as the project. In my case "smspopup".

It would be nice to have a cfg file where I can write down the path of the output folder.

Long Arrays get corrupted

I'm not really sure what the problem here is, but it's really simple to reproduce. My guess is that android2po is not handling two-digit array indices in the message context very well.

.po file:

msgctxt "EPr_quiet_hours_start:0"
msgid "disabled"
msgstr "desactivado"

msgctxt "EPr_quiet_hours_start:1"
msgid "8 PM"
msgstr ""

msgctxt "EPr_quiet_hours_start:2"
msgid "9 PM"
msgstr ""

msgctxt "EPr_quiet_hours_start:3"
msgid "10 PM"
msgstr ""

msgctxt "EPr_quiet_hours_start:4"
msgid "11 PM"
msgstr ""

msgctxt "EPr_quiet_hours_start:5"
msgid "12 AM"
msgstr ""

msgctxt "EPr_quiet_hours_start:6"
msgid "1 AM"
msgstr ""

msgctxt "EPr_quiet_hours_start:7"
msgid "2 AM"
msgstr ""

msgctxt "EPr_quiet_hours_start:8"
msgid "3 AM"
msgstr ""

msgctxt "EPr_quiet_hours_start:9"
msgid "4 AM"
msgstr ""

msgctxt "EPr_quiet_hours_start:10"
msgid "5 AM"
msgstr ""

msgctxt "EPr_quiet_hours_start:11"
msgid "6 AM"
msgstr ""

msgctxt "EPr_quiet_hours_start:12"
msgid "7 AM"
msgstr ""

msgctxt "EPr_quiet_hours_start:13"
msgid "8 AM"
msgstr ""

msgctxt "EPr_quiet_hours_start:14"
msgid "9 AM"
msgstr ""

msgctxt "EPr_quiet_hours_start:15"
msgid "10 AM"
msgstr ""

msgctxt "EPr_quiet_hours_start:16"
msgid "11 AM"
msgstr ""

msgctxt "EPr_quiet_hours_start:17"
msgid "12 PM"
msgstr ""

msgctxt "EPr_quiet_hours_start:18"
msgid "1 PM"
msgstr ""

msgctxt "EPr_quiet_hours_start:19"
msgid "2 PM"
msgstr ""

msgctxt "EPr_quiet_hours_start:20"
msgid "3 PM"
msgstr ""

msgctxt "EPr_quiet_hours_start:21"
msgid "4 PM"
msgstr ""

msgctxt "EPr_quiet_hours_start:22"
msgid "5 PM"
msgstr ""

msgctxt "EPr_quiet_hours_start:23"
msgid "6 PM"
msgstr ""

msgctxt "EPr_quiet_hours_start:24"
msgid "7 PM"
msgstr ""

I would expect all of the times to be ordered as they are above, but the following XML is produced:

<?xml version='1.0' encoding='utf-8'?>
<resources>
  <string-array name="EPr_quiet_hours_start">
    <item>desactivado</item>
    <item>8 PM</item>
    <item>5 AM</item>
    <item>6 AM</item>
    <item>7 AM</item>
    <item>8 AM</item>
    <item>9 AM</item>
    <item>10 AM</item>
    <item>11 AM</item>
    <item>12 PM</item>
    <item>1 PM</item>
    <item>2 PM</item>
    <item>9 PM</item>
    <item>3 PM</item>
    <item>4 PM</item>
    <item>5 PM</item>
    <item>6 PM</item>
    <item>7 PM</item>
    <item>10 PM</item>
    <item>11 PM</item>
    <item>12 AM</item>
    <item>1 AM</item>
    <item>2 AM</item>
    <item>3 AM</item>
    <item>4 AM</item>
  </string-array>
</resources>

Notice that it's all out of order. Sad times.

Avoiding strings with regex on their names

I had to move all my .__pref and .__default to a separate place to avoid android2po to parse them and add them to the template.

For example:
true
wouldn't be shown since I add ".*_default$" regex as a filter.

Adds surrounding " quotes to strings with markup.

Unescaped markup is apparently normal in Android strings.xml files, according to:
http://developer.android.com/guide/topics/resources/string-resource.html

For instance, my values/strings.xml can have this:

<string name="about_text2">This android app was developed by <a href="http://murrayc.com/">Murray Cumming</a></string>

And my values-de/strings.xml can have this translation:

<string name="about_text2">Diese Android App wurde von <a href="http://murrayc.com/">Murray Cumming</a> entwickelt.</string>

However, when I export and import with a2po, that translation changes to:

<string name="about_text2">"Diese Android App wurde von "<a href="http://murrayc.com/">Murray Cumming</a>" entwickelt."</string>

Notice the extra quotes around the whole string and around the markup. Android seems to ignore them, and they don't appear in the .po file when I export again, but it's pretty strange. I'd feel better if I knew that it's really legal and correct.

Unable to init my project

Hello,

I downloaded android2po, installed and tried to init my project with 'a2po init' command. It detects all languages correctly, but fails without writing any file (only an empty 'locale' folder appears).

Here is the output:
XXXX@YYYY:~/Programmieren/MailBoxer/android/workspace/SayMyName Donut$ a2po export
Found 4 language(s): de, es, fr, it
Generating template.pot
Traceback (most recent call last):
File "/usr/local/bin/a2po", line 3, in
android2po.run()
File "/usr/local/lib/python2.6/dist-packages/android2po/program.py", line 264, in run
sys.exit(main(sys.argv) or 0)
File "/usr/local/lib/python2.6/dist-packages/android2po/program.py", line 255, in main
return cmd.execute()
File "/usr/local/lib/python2.6/dist-packages/android2po/commands.py", line 183, in execute
default_po = xml2po(file)
File "/usr/local/lib/python2.6/dist-packages/android2po/convert.py", line 263, in xml2po
catalog.add(org_value, trans_value or u'', context=name)
TypeError: add() got an unexpected keyword argument 'context'

Thanks
Tom

Not emitting empty items in string-array

It is valid for an item in a string-array to be empty. The parser will accept a self-closing tag, but it is more common to find:
<item></item>

This is commonly used. You can see an example from AOSP source that uses this technique multiple times.

However, a2po will omit those with a warning. Then the string-array is missing an item. If run on the case in the provided example, this causes the remaining values to correlate with the wrong array index, and thus the wrong status is displayed.

It is critical that empty items be emitted in the original location within a string-array.

crash on UTF-8 characters

I get crashes when generating the .pot files during "init" and when converting back to "XML" with "import" on each input file containing any non-ASCII UTF-8 characters.

For example:
File "/usr/local/lib/python2.7/dist-packages/android2po-1.3.dev-py2.7.egg/android2po/commands.py", line 184, in write_file
f.write(content)
UnicodeEncodeError: 'ascii' codec can't encode character u'\u2026' in position 19558: ordinal not in range(128)

UTF-8 is specified in the XML file:

Anything I am missing or is UTF-8 support missing (which would make a translation tool pretty unusable)?

losing string attribute: formatted="false"

Using 1.3 dev

When I add the formatted="false" attribute to my strings they get lost on the roundtrip and never show up in my specific language string files.

It would be nice if android2po could preserve this attribute.

Locales: id, he, yi -> in, iw, ji

Our gettext based tools are using language codes id, he, yi. However Java/Android are expecting in, iw, ji respectively.

We fixed this by adding those mappings to ANDROID_LOCALE_MAPPING in env.py.

Cannot process <item>\?</item>

Trying to process the string-array entry
<item>\?</item>
fails after an init followed by export. The escape character is removed, creating invalid XML:
<item>?</item>

A sample source tree is available here name="ram_states" becomes corrupted.

dump source strings

android2po works nicely.

One thing that I could use though is the ability for a2po to dump the raw source strings in res/values/strings.xml to stdout.

Maybe an option like "dumpsource"?

Setting .pot filename

Launchpad needs to have the pot file called exactly as the project. In my case: smspopup.pot. Right now I am using android2po and then renaming the file.

It would be nice to be able to set the .pot filename instead of getting a template.pot. For example: A cfg file where I can write down which name the .pot should have.

android resource files with hyphens in filename

I have a couple of Android resource files named like this: "strings-dialogs.xml".
When processing them with "a2po export", I get crashes saying:
...
File "/home/farindk/.local/ File "/home/farindk/.local/lib/python2.7/site-packages/babel/core.py", line 902, in parse_locale
raise ValueError('expected only letters, got %r' % lang)
ValueError: expected only letters, got u'dialogs-de'

I did not look deeper into this, but my guess what goes wrong is this: in order to get the language code, the script searches for the first hyphen and considers the rest of the name the language code. This fails in this case, because of the two hyphens in the name.

Probably the simple fix would be to search for the last hypen in the name instead of the first one.

Default values for pot header fields

By default, pot files are created with the following default information:

# Translations template for PROJECT.
# Copyright (C) 2014 ORGANIZATION
# This file is distributed under the same license as the PROJECT project.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2014.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2014-01-18 15:01+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <[email protected]>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Generated-By: Babel 1.0dev\n"

It would be very nice to be able to specify values for PROJECT, ORGANIZATION, VERSION, EMAIL@ADDRESS (in Report-Msgid-Bugs), i.e. info that translators aren't supposed to enter or change.

'pip install android2po' is missing termcolor module

$ a2po--help                                                                                                                          Traceback (most recent call last):
  File "/usr/local/bin/a2po", line 9, in <module>
    load_entry_point('android2po==1.5.0', 'console_scripts', 'a2po')()
  File "/home/dax/.local/lib/python2.7/site-packages/pkg_resources/__init__.py", line 558, in load_entry_point
    return get_distribution(dist).load_entry_point(group, name)
  File "/home/dax/.local/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2682, in load_entry_point
    return ep.load()
  File "/home/dax/.local/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2355, in load
    return self.resolve()
  File "/home/dax/.local/lib/python2.7/site-packages/pkg_resources/__init__.py", line 2361, in resolve
    module = __import__(self.module_name, fromlist=['__name__'], level=0)
  File "/usr/local/lib/python2.7/dist-packages/android2po/__init__.py", line 5, in <module>
    from .program import *
  File "/usr/local/lib/python2.7/dist-packages/android2po/program.py", line 16, in <module>
    from .commands import InitCommand, ExportCommand, ImportCommand, CommandError
  File "/usr/local/lib/python2.7/dist-packages/android2po/commands.py", line 11, in <module>
    from termcolor import colored
ImportError: No module named termcolor

Installing the module with pip fixed the problem.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.