Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(245)

Unified Diff: grit/format/android_xml.py

Issue 1258833004: Compile plural strings to android <plurals> elem (Closed) Base URL: https://chromium.googlesource.com/external/grit-i18n.git@master
Patch Set: Handled comments Created 5 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: grit/format/android_xml.py
diff --git a/grit/format/android_xml.py b/grit/format/android_xml.py
index d960bf49ddb8f009575b36f3a146cd25edbef8f8..5b2c080f8c482cc4619e5de61eb4ee36afc56dfb 100644
--- a/grit/format/android_xml.py
+++ b/grit/format/android_xml.py
@@ -58,6 +58,7 @@ would generate
"""
import os
+import re
import types
import xml.sax.saxutils
@@ -96,6 +97,13 @@ _SIMPLE_TEMPLATE = u'<string name="%s">%s</string>\n'
_PRODUCT_TEMPLATE = u'<string name="%s" product="%s">%s</string>\n'
+# Some strings have a plural equivalent
+_PLURALS_TEMPLATE = '<plurals name="%s">\n%s</plurals>\n'
+_PLURALS_ITEM_TEMPLATE = ' <item quantity="%s">%s</item>\n'
+_PLURALS_PATTERN = lazy_re.compile(r'\{[A-Z_]+,\s*plural,(?P<items>.*)\}$', flags=re.S)
+_PLURALS_ITEM_PATTERN = lazy_re.compile(r'(?P<quantity>\S+)\s*\{(?P<value>.*?)\}')
+
+
def Format(root, lang='en', output_dir='.'):
yield ('<?xml version="1.0" encoding="utf-8"?>\n'
'<resources '
@@ -131,6 +139,51 @@ def ShouldOutputNode(node, tagged_only):
(not tagged_only or _EMIT_TAG in node.formatter_data))
+def _FormatPluralMessage(message):
+ """Compile ICU plural syntax to the body of an Android <plurals> element.
newt (away) 2015/08/04 03:14:26 nit: "Compiles"
conleyo 2015/08/04 16:53:02 Done.
+
+ 1. In a .grd file, we can write a plural string like this:
+
+ <message name="IDS_THINGS">
+ {NUM_THINGS, plural,
+ =1 {1 thing}
+ other {# things}}
+ </message>
+
+ 2. The Android equivalent looks like this:
+
+ <plurals name="things">
+ <item quantity="one">1 thing</item>
+ <item quantity="other">%d things</item>
+ </plurals>
+
+ This method takes the body of (1) and converts it to the body of (2).
+
+ If the message is *not* a plural string, this function returns `None`.
+ If the message includes quantities without an equivalent format in Android,
+ it raises an exception.
+ """
+ ret = {}
+ plural_match = _PLURALS_PATTERN.match(message)
+ if not plural_match:
+ return None
+ body_in = plural_match.group('items').strip()
+ body_out = u''
newt (away) 2015/08/04 03:14:26 A better idiom for concatenating strings in python
conleyo 2015/08/04 16:53:02 Done.
+ for item_match in _PLURALS_ITEM_PATTERN.finditer(body_in):
+ quantity = item_match.group('quantity')
+ value = item_match.group('value').replace('#', '%d')
+ if quantity == '=0':
+ body_out += _PLURALS_ITEM_TEMPLATE % ('zero', value)
+ elif quantity == '=1':
+ body_out += _PLURALS_ITEM_TEMPLATE % ('one', value)
+ elif quantity == 'other':
+ body_out += _PLURALS_ITEM_TEMPLATE % ('other', value)
+ else:
newt (away) 2015/08/04 03:14:26 Why not handle "=2", "few" and "many"?
conleyo 2015/08/04 16:53:02 Done.
+ raise Exception('Unsupported plural quantity for android '
+ 'strings.xml: %s' % quantity)
+ return body_out
+
+
def _FormatMessage(item, lang):
"""Writes out a single string as a <resource/> element."""
@@ -138,6 +191,7 @@ def _FormatMessage(item, lang):
# Replace < > & with &lt; &gt; &amp; to ensure we generate valid XML and
# replace ' " with \' \" to conform to Android's string formatting rules.
value = xml.sax.saxutils.escape(value, {"'": "\\'", '"': '\\"'})
+ plurals = _FormatPluralMessage(value)
# Wrap the string in double quotes to preserve whitespace.
value = '"' + value + '"'
@@ -152,7 +206,9 @@ def _FormatMessage(item, lang):
product = item.formatter_data.get(_PRODUCT_TAG, product)
name = item.formatter_data.get(_NAME_TAG, name)
- if product:
+ if plurals:
+ return _PLURALS_TEMPLATE % (name, plurals)
+ elif product:
return _PRODUCT_TEMPLATE % (name, product, value)
else:
return _SIMPLE_TEMPLATE % (name, value)
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698