From 0a9129f0150f1a0888d7293d35f2e15c6d07e712 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Tue, 7 May 2013 18:08:15 +0200 Subject: [PATCH 1/5] Attempt to improve storing of markup in Android resources This seems to be quite tricky as we need to guess what was intended at this point. --- translate/storage/aresource.py | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/translate/storage/aresource.py b/translate/storage/aresource.py index 5e0cb9e2ef..a7d4c10e04 100755 --- a/translate/storage/aresource.py +++ b/translate/storage/aresource.py @@ -31,7 +31,6 @@ EOF = None WHITESPACE = ' \n\t' # Whitespace that we collapse MULTIWHITESPACE = re.compile('[ \n\t]{2}') -OPEN_TAG_TO_ESCAPE = re.compile('<(?!/?\S*>)') class AndroidResourceUnit(base.TranslationUnit): """A single term in the Android resource file.""" @@ -229,13 +228,17 @@ def getsource(self, lang=None): def settarget(self, target): if '<' in target: - # Handle text with markup - target = self.escape(target).replace('&', '&') - target = OPEN_TAG_TO_ESCAPE.sub('<', target) - # Parse new XML - newstring = etree.fromstring('%s' % target) + # Handle text with possible markup + target = target.replace('&', '&') + try: + # Try as XML + newstring = etree.fromstring('%s' % target) + except: + # Fallback to string with XML escaping + target = target.replace('<', '<') + newstring = etree.fromstring('%s' % target) # Update text - self.xmlelement.text = newstring.text + self.xmlelement.text = self.escape(newstring.text) # Remove old elements for x in self.xmlelement.iterchildren(): self.xmlelement.remove(x) From 7324b529b8d7d031ecae65d28f24773aa5201c02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Thu, 9 May 2013 11:08:11 +0200 Subject: [PATCH 2/5] Add test for properly encoding < --- translate/storage/test_aresource.py | 1 + 1 file changed, 1 insertion(+) diff --git a/translate/storage/test_aresource.py b/translate/storage/test_aresource.py index 5bc34ab0a3..3d5f427a0a 100755 --- a/translate/storage/test_aresource.py +++ b/translate/storage/test_aresource.py @@ -19,6 +19,7 @@ class TestPropUnit(test_monolingual.TestMonolingualUnit): (' leading space', '" leading space"\n\n'), ('>xml&entities', '>xml&entities\n\n'), ('some html code here', 'some html code here\n\n'), + ('<<< arrow', '<<< arrow\n\n'), ] parse_test_data = escape_data + [ From 0ca4d706b7ba1c3e0d858dec742cf9888256d09e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Thu, 9 May 2013 11:16:25 +0200 Subject: [PATCH 3/5] Fixed quoting of mixed XML and text content --- translate/storage/aresource.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/translate/storage/aresource.py b/translate/storage/aresource.py index a7d4c10e04..b51c6a4ca8 100755 --- a/translate/storage/aresource.py +++ b/translate/storage/aresource.py @@ -238,7 +238,10 @@ def settarget(self, target): target = target.replace('<', '<') newstring = etree.fromstring('%s' % target) # Update text - self.xmlelement.text = self.escape(newstring.text) + if newstring.text is None: + self.xmlelement.text = '' + else: + self.xmlelement.text = newstring.text # Remove old elements for x in self.xmlelement.iterchildren(): self.xmlelement.remove(x) @@ -252,10 +255,10 @@ def settarget(self, target): def gettarget(self, lang=None): # Grab inner text - target = (self.xmlelement.text or u'') + target = self.unescape(self.xmlelement.text or u'') # Include markup as well target += u''.join([data.forceunicode(etree.tostring(child, encoding='utf-8')) for child in self.xmlelement.iterchildren()]) - return self.unescape(target) + return target target = property(gettarget, settarget) From 217fc543d15270cfaa996f6654e44a09ea02d56d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Thu, 9 May 2013 11:16:40 +0200 Subject: [PATCH 4/5] Add tests for mixed XML and text content in aresource --- translate/storage/test_aresource.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/translate/storage/test_aresource.py b/translate/storage/test_aresource.py index 3d5f427a0a..37d4892908 100755 --- a/translate/storage/test_aresource.py +++ b/translate/storage/test_aresource.py @@ -20,6 +20,8 @@ class TestPropUnit(test_monolingual.TestMonolingualUnit): ('>xml&entities', '>xml&entities\n\n'), ('some html code here', 'some html code here\n\n'), ('<<< arrow', '<<< arrow\n\n'), + ('link', 'link\n\n'), + ('link and text', 'link and text\n\n'), ] parse_test_data = escape_data + [ From a8c2ee19d7a7a2d2c23a5af97bb759e92a7da4d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C4=8Ciha=C5=99?= Date: Thu, 9 May 2013 11:21:36 +0200 Subject: [PATCH 5/5] This format supports only string resources, name it like that --- translate/storage/aresource.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translate/storage/aresource.py b/translate/storage/aresource.py index b51c6a4ca8..bae6cdceed 100755 --- a/translate/storage/aresource.py +++ b/translate/storage/aresource.py @@ -311,7 +311,7 @@ def __eq__(self, other): class AndroidResourceFile(lisa.LISAfile): """Class representing a Android resource file store.""" UnitClass = AndroidResourceUnit - Name = _("Android Resource") + Name = _("Android String Resource") Mimetypes = ["application/xml"] Extensions = ["xml"] rootNode = "resources"