| LEFT | RIGHT |
| 1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
| 2 # -*- coding: utf-8 -*- | 2 # -*- coding: utf-8 -*- |
| 3 # | 3 # |
| 4 # Copyright 2006-2007 Zuza Software Foundation | 4 # Copyright 2006-2007 Zuza Software Foundation |
| 5 # | 5 # |
| 6 # This file is part of translate. | 6 # This file is part of translate. |
| 7 # | 7 # |
| 8 # translate is free software; you can redistribute it and/or modify | 8 # translate is free software; you can redistribute it and/or modify |
| 9 # it under the terms of the GNU General Public License as published by | 9 # it under the terms of the GNU General Public License as published by |
| 10 # the Free Software Foundation; either version 2 of the License, or | 10 # the Free Software Foundation; either version 2 of the License, or |
| 11 # (at your option) any later version. | 11 # (at your option) any later version. |
| 12 # | 12 # |
| 13 # translate is distributed in the hope that it will be useful, | 13 # translate is distributed in the hope that it will be useful, |
| 14 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 14 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 16 # GNU General Public License for more details. | 16 # GNU General Public License for more details. |
| 17 # | 17 # |
| 18 # You should have received a copy of the GNU General Public License | 18 # You should have received a copy of the GNU General Public License |
| 19 # along with translate; if not, write to the Free Software | 19 # along with translate; if not, write to the Free Software |
| 20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 20 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 21 # | 21 # |
| 22 | 22 |
| 23 """An xliff file specifically suited for handling the po representation of | 23 """An xliff file specifically suited for handling the po representation of |
| 24 xliff. """ | 24 xliff. """ |
| 25 | 25 |
| 26 from translate.storage import xliff | 26 from translate.storage import xliff |
| 27 from translate.storage import lisa | 27 from translate.storage import lisa |
| 28 from translate.storage import poheader | 28 from translate.storage import poheader |
| 29 from translate.misc.multistring import multistring | 29 from translate.misc.multistring import multistring |
| 30 from lxml import etree | 30 from lxml import etree |
| 31 import re | 31 import re |
| 32 | 32 |
| 33 def hasplurals(thing): | 33 def hasplurals(thing): |
| 34 if not isinstance(thing, multistring): | 34 if not isinstance(thing, multistring): |
| 35 return False | 35 return False |
| 36 return len(thing.strings) > 1 | 36 return len(thing.strings) > 1 |
| 37 | 37 |
| 38 class PoXliffUnit(xliff.xliffunit): | 38 class PoXliffUnit(xliff.xliffunit): |
| 39 """A class to specifically handle the plural units created from a po file.""
" | 39 """A class to specifically handle the plural units created from a po file.""
" |
| 40 def __init__(self, source, empty=False): | 40 def __init__(self, source, empty=False): |
| 41 self.units = [] | 41 self.units = [] |
| 42 | 42 |
| 43 if empty: | 43 if empty: |
| 44 return | 44 return |
| 45 | 45 |
| 46 if not hasplurals(source): | 46 if not hasplurals(source): |
| 47 super(PoXliffUnit, self).__init__(source) | 47 super(PoXliffUnit, self).__init__(source) |
| 48 return | 48 return |
| 49 | 49 |
| 50 self.xmlelement = etree.Element(self.namespaced("group")) | 50 self.xmlelement = etree.Element(self.namespaced("group")) |
| (...skipping 288 matching lines...) Show 10 above Show 10 below |
| 339 """Populates this object from the given xml string""" | 339 """Populates this object from the given xml string""" |
| 340 #TODO: Make more robust | 340 #TODO: Make more robust |
| 341 def ispluralgroup(node): | 341 def ispluralgroup(node): |
| 342 """determines whether the xml node refers to a getttext plural""" | 342 """determines whether the xml node refers to a getttext plural""" |
| 343 return node.get("restype") == "x-gettext-plurals" | 343 return node.get("restype") == "x-gettext-plurals" |
| 344 | 344 |
| 345 def isnonpluralunit(node): | 345 def isnonpluralunit(node): |
| 346 """determindes whether the xml node contains a plural like id. | 346 """determindes whether the xml node contains a plural like id. |
| 347 | 347 |
| 348 We want to filter out all the plural nodes, except the very first | 348 We want to filter out all the plural nodes, except the very first |
| 349 one in each group. | 349 one in each group. |
| 350 """ | 350 """ |
| 351 return re.match(r"\d+\[[123456]\]$", node.get("id") or "") is None | 351 return re.match(r"\d+\[[123456]\]$", node.get("id") or "") is None |
| 352 | 352 |
| 353 def pluralunits(pluralgroups): | 353 def pluralunits(pluralgroups): |
| 354 for pluralgroup in pluralgroups: | 354 for pluralgroup in pluralgroups: |
| 355 yield self.UnitClass.createfromxmlElement(pluralgroup, namespace
=self.namespace) | 355 yield self.UnitClass.createfromxmlElement(pluralgroup, namespace
=self.namespace) |
| 356 | 356 |
| 357 self.filename = getattr(xml, 'name', '') | 357 self.filename = getattr(xml, 'name', '') |
| 358 if hasattr(xml, "read"): | 358 if hasattr(xml, "read"): |
| 359 xml.seek(0) | 359 xml.seek(0) |
| 360 xmlsrc = xml.read() | 360 xmlsrc = xml.read() |
| 361 xml = xmlsrc | 361 xml = xmlsrc |
| 362 self.document = etree.fromstring(xml).getroottree() | 362 self.document = etree.fromstring(xml).getroottree() |
| 363 self.initbody() | 363 self.initbody() |
| 364 assert self.document.getroot().tag == self.namespaced(self.rootNode) | 364 assert self.document.getroot().tag == self.namespaced(self.rootNode) |
| 365 groups = self.document.findall(".//%s" % self.namespaced("group")) | 365 groups = self.document.findall(".//%s" % self.namespaced("group")) |
| 366 pluralgroups = filter(ispluralgroup, groups) | 366 pluralgroups = filter(ispluralgroup, groups) |
| 367 termEntries = self.body.findall('.//%s' % self.namespaced(self.UnitClass
.rootNode)) | 367 termEntries = self.body.findall('.//%s' % self.namespaced(self.UnitClass
.rootNode)) |
| 368 if termEntries is None: | 368 if termEntries is None: |
| 369 return | 369 return |
| 370 | 370 |
| 371 singularunits = filter(isnonpluralunit, termEntries) | 371 singularunits = filter(isnonpluralunit, termEntries) |
| 372 pluralunit_iter = pluralunits(pluralgroups) | 372 pluralunit_iter = pluralunits(pluralgroups) |
| 373 try: | 373 try: |
| 374 nextplural = pluralunit_iter.next() | 374 nextplural = pluralunit_iter.next() |
| 375 except StopIteration: | 375 except StopIteration: |
| 376 nextplural = None | 376 nextplural = None |
| 377 | 377 |
| 378 for entry in singularunits: | 378 for entry in singularunits: |
| 379 term = self.UnitClass.createfromxmlElement(entry, namespace=self.nam
espace) | 379 term = self.UnitClass.createfromxmlElement(entry, namespace=self.nam
espace) |
| 380 if nextplural and unicode(term.source) in nextplural.source.strings: | 380 if nextplural and unicode(term.source) in nextplural.source.strings: |
| 381 self.units.append(nextplural) | 381 self.units.append(nextplural) |
| 382 try: | 382 try: |
| 383 nextplural = pluralunit_iter.next() | 383 nextplural = pluralunit_iter.next() |
| 384 except StopIteration, i: | 384 except StopIteration, i: |
| 385 nextplural = None | 385 nextplural = None |
| 386 else: | 386 else: |
| 387 self.units.append(term) | 387 self.units.append(term) |
| 388 | 388 |
| LEFT | RIGHT |