Package translate :: Package storage :: Package placeables :: Module lisa

[hide private]
[frames] | no frames]

# Source Code for Module translate.storage.placeables.lisa

      1  #!/usr/bin/env python
      2  # -*- coding: utf-8 -*-
      3  #
      4  # Copyright 2008-2009 Zuza Software Foundation
      5  #
      6  # This file is part of the Translate Toolkit.
      7  #
      8  # This program is free software; you can redistribute it and/or modify
      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
     11  # (at your option) any later version.
     12  #
     13  # This program is distributed in the hope that it will be useful,
     14  # but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  # GNU General Public License for more details.
     17  #
     18  # You should have received a copy of the GNU General Public License
     19  # along with this program; if not, see <http://www.gnu.org/licenses/>.
     20
     21  from lxml import etree
     22
     23  from translate.misc.xml_helpers import normalize_xml_space
     24  from translate.storage.placeables import base, xliff, StringElem
     25  from translate.storage.xml_extract import misc
     26
     27  __all__ = ['xml_to_strelem', 'strelem_to_xml']
     28  # Use the above functions as entry points into this module. The rest are used by these functions.
     29
     30
     31 -def make_empty_replacement_placeable(klass, node, xml_space="preserve"):
     32      try:
     33          return klass(
     34              id=node.attrib[u'id'],
     35              rid=node.attrib.get('rid', None),
     36              xid=node.attrib.get('xid', None),
     37              xml_attrib=node.attrib,
     38          )
     39      except KeyError:
     40          pass
     41      return klass()
     42
     43
     44 -def make_g_placeable(klass, node, xml_space="default"):
     45      return klass(
     46          id=node.attrib[u'id'],
     47          sub=xml_to_strelem(node, xml_space).sub,
     48          xml_attrib=node.attrib,
     49      )
     50
     51
     52 -def not_yet_implemented(klass, node, xml_space="preserve"):
     53      raise NotImplementedError
     54
     55
     56 -def make_unknown(klass, node, xml_space="preserve"):
     57      assert klass is xliff.UnknownXML
     58
     59      sub = xml_to_strelem(node, xml_space).sub
     60      id = node.get('id', None)
     61      rid = node.get('rid', None)
     62      xid = node.get('xid', None)
     63
     64      return klass(sub=sub, id=id, rid=rid, xid=xid, xml_node=node)
     65
     66  _class_dictionary = {
     67      #u'bpt': (xliff.Bpt, not_yet_implemented),
     68      u'bx': (xliff.Bx, make_empty_replacement_placeable),
     69      #u'ept': (xliff.Ept, not_yet_implemented),
     70      u'ex': (xliff.Ex, make_empty_replacement_placeable),
     71      u'g': (xliff.G, make_g_placeable),
     72      #u'it': (xliff.It, not_yet_implemented),
     73      #u'ph': (xliff.Ph, not_yet_implemented),
     74      #u'sub': (xliff.Sub, not_yet_implemented),
     75      u'x': (xliff.X, make_empty_replacement_placeable),
     76  }
     77
     78
     79 -def make_placeable(node, xml_space):
     80      _namespace, tag = misc.parse_tag(node.tag)
     81      if tag in _class_dictionary:
     82          klass, maker = _class_dictionary[tag]
     83      else:
     84          klass, maker = xliff.UnknownXML, make_unknown
     85      return maker(klass, node, xml_space)
     86
     87
     88 -def as_unicode(string):
     89      if isinstance(string, unicode):
     90          return string
     91      elif isinstance(string, StringElem):
     92          return unicode(string)
     93      else:
     94          return unicode(string.decode('utf-8'))
     95
     96
     97 -def xml_to_strelem(dom_node, xml_space="preserve"):
     98      if dom_node is None:
     99          return StringElem()
    100      if isinstance(dom_node, basestring):
    101          dom_node = etree.fromstring(dom_node)
    102      normalize_xml_space(dom_node, xml_space, remove_start=True)
    103      result = StringElem()
    104      if dom_node.text:
    105          result.sub.append(StringElem(unicode(dom_node.text)))
    106      for child_dom_node in dom_node:
    107          result.sub.append(make_placeable(child_dom_node, xml_space))
    108          if child_dom_node.tail:
    109              result.sub.append(StringElem(unicode(child_dom_node.tail)))
    110      result.prune()
    111      return result
    112
    113  # ==========================================================
    114
    115
    116 -def placeable_as_dom_node(placeable, tagname):
    117      dom_node = etree.Element(tagname)
    118      if placeable.id is not None:
    119          dom_node.attrib['id'] = placeable.id
    120      if placeable.xid is not None:
    121          dom_node.attrib['xid'] = placeable.xid
    122      if placeable.rid is not None:
    123          dom_node.attrib['rid'] = placeable.rid
    124
    125      if hasattr(placeable, 'xml_attrib'):
    126          for attrib, value in placeable.xml_attrib.items():
    127              dom_node.set(attrib, value)
    128
    129      return dom_node
    130
    131
    132 -def unknown_placeable_as_dom_node(placeable):
    133      assert type(placeable) is xliff.UnknownXML
    134
    135      from copy import copy
    136      node = copy(placeable.xml_node)
    137      for i in range(len(node)):
    138          del node[0]
    139      node.tail = None
    140      node.text = None
    141
    142      return node
    143
    144  _placeable_dictionary = {
    145      xliff.Bpt: lambda placeable: placeable_as_dom_node(placeable, 'bpt'),
    146      xliff.Bx: lambda placeable: placeable_as_dom_node(placeable, 'bx'),
    147      xliff.Ept: lambda placeable: placeable_as_dom_node(placeable, 'ept'),
    148      xliff.Ex: lambda placeable: placeable_as_dom_node(placeable, 'ex'),
    149      xliff.G: lambda placeable: placeable_as_dom_node(placeable, 'g'),
    150      xliff.It: lambda placeable: placeable_as_dom_node(placeable, 'it'),
    151      xliff.Ph: lambda placeable: placeable_as_dom_node(placeable, 'ph'),
    152      xliff.Sub: lambda placeable: placeable_as_dom_node(placeable, 'sub'),
    153      xliff.X: lambda placeable: placeable_as_dom_node(placeable, 'x'),
    154      xliff.UnknownXML: unknown_placeable_as_dom_node,
    155      base.Bpt: lambda placeable: placeable_as_dom_node(placeable, 'bpt'),
    156      base.Bx: lambda placeable: placeable_as_dom_node(placeable, 'bx'),
    157      base.Ept: lambda placeable: placeable_as_dom_node(placeable, 'ept'),
    158      base.Ex: lambda placeable: placeable_as_dom_node(placeable, 'ex'),
    159      base.G: lambda placeable: placeable_as_dom_node(placeable, 'g'),
    160      base.It: lambda placeable: placeable_as_dom_node(placeable, 'it'),
    161      base.Ph: lambda placeable: placeable_as_dom_node(placeable, 'ph'),
    162      base.Sub: lambda placeable: placeable_as_dom_node(placeable, 'sub'),
    163      base.X: lambda placeable: placeable_as_dom_node(placeable, 'x'),
    164  }
    165
    166
    167 -def xml_append_string(node, string):
    168      if not len(node):
    169          if not node.text:
    170              node.text = unicode(string)
    171          else:
    172              node.text += unicode(string)
    173      else:
    174          lastchild = node.getchildren()[-1]
    175          if lastchild.tail is None:
    176              lastchild.tail = ''
    177          lastchild.tail += unicode(string)
    178      return node
    179
    180
    181 -def strelem_to_xml(parent_node, elem):
    182      if isinstance(elem, (str, unicode)):
    183          return xml_append_string(parent_node, elem)
    184      if not isinstance(elem, StringElem):
    185          return parent_node
    186
    187      if type(elem) is StringElem and elem.isleaf():
    188          return xml_append_string(parent_node, elem)
    189
    190      if elem.__class__ in _placeable_dictionary:
    191          node = _placeable_dictionary[elem.__class__](elem)
    192          parent_node.append(node)
    193      else:
    194          node = parent_node
    195
    196      for sub in elem.sub:
    197          strelem_to_xml(node, sub)
    198
    199      return parent_node
    200
    201
    202 -def parse_xliff(pstr):
    203      try:
    204          return xml_to_strelem(etree.fromstring('<source>%s</source>' % (pstr)))
    205      except Exception, exc:
    206          raise
    207          return None
    208  xliff.parsers = [parse_xliff]
    209