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 *
     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 -def make_g_placeable(klass, node, xml_space="default"):
     44      return klass(
     45          id=node.attrib[u'id'],
     46          sub=xml_to_strelem(node, xml_space).sub,
     47          xml_attrib=node.attrib
     48      )
     49
     50 -def not_yet_implemented(klass, node, xml_space="preserve"):
     51      raise NotImplementedError
     52
     53 -def make_unknown(klass, node, xml_space="preserve"):
     54      assert klass is xliff.UnknownXML
     55
     56      sub = xml_to_strelem(node, xml_space).sub
     57      id =  node.get('id',  None)
     58      rid = node.get('rid', None)
     59      xid = node.get('xid', None)
     60
     61      return klass(sub=sub, id=id, rid=rid, xid=xid, xml_node=node)
     62
     63  _class_dictionary = {
     64      #u'bpt': (xliff.Bpt, not_yet_implemented),
     65      u'bx' : (xliff.Bx,  make_empty_replacement_placeable),
     66      #u'ept': (xliff.Ept, not_yet_implemented),
     67      u'ex' : (xliff.Ex,  make_empty_replacement_placeable),
     68      u'g'  : (xliff.G,   make_g_placeable),
     69      #u'it' : (xliff.It,  not_yet_implemented),
     70      #u'ph' : (xliff.Ph,  not_yet_implemented),
     71      #u'sub': (xliff.Sub, not_yet_implemented),
     72      u'x'  : (xliff.X,   make_empty_replacement_placeable)
     73  }
     74
     75 -def make_placeable(node, xml_space):
     76      _namespace, tag = misc.parse_tag(node.tag)
     77      if tag in _class_dictionary:
     78          klass, maker = _class_dictionary[tag]
     79      else:
     80          klass, maker = xliff.UnknownXML, make_unknown
     81      return maker(klass, node, xml_space)
     82
     83 -def as_unicode(string):
     84      if isinstance(string, unicode):
     85          return string
     86      elif isinstance(string, StringElem):
     87          return unicode(string)
     88      else:
     89          return unicode(string.decode('utf-8'))
     90
     91 -def xml_to_strelem(dom_node, xml_space="preserve"):
     92      if dom_node is None:
     93          return StringElem()
     94      if isinstance(dom_node, basestring):
     95          dom_node = etree.fromstring(dom_node)
     96      normalize_xml_space(dom_node, xml_space, remove_start=True)
     97      result = StringElem()
     98      if dom_node.text:
     99          result.sub.append(StringElem(unicode(dom_node.text)))
    100      for child_dom_node in dom_node:
    101          result.sub.append(make_placeable(child_dom_node, xml_space))
    102          if child_dom_node.tail:
    103              result.sub.append(StringElem(unicode(child_dom_node.tail)))
    104      result.prune()
    105      return result
    106
    107  # ==========================================================
    108
    109 -def placeable_as_dom_node(placeable, tagname):
    110      dom_node = etree.Element(tagname)
    111      if placeable.id is not None:
    112          dom_node.attrib['id'] = placeable.id
    113      if placeable.xid is not None:
    114          dom_node.attrib['xid'] = placeable.xid
    115      if placeable.rid is not None:
    116          dom_node.attrib['rid'] = placeable.rid
    117
    118      if hasattr(placeable, 'xml_attrib'):
    119          for attrib, value in placeable.xml_attrib.items():
    120              dom_node.set(attrib, value)
    121
    122      return dom_node
    123
    124 -def unknown_placeable_as_dom_node(placeable):
    125      assert type(placeable) is xliff.UnknownXML
    126
    127      from copy import copy
    128      node = copy(placeable.xml_node)
    129      for i in range(len(node)):
    130          del node[0]
    131      node.tail = None
    132      node.text = None
    133
    134      return node
    135
    136  _placeable_dictionary = {
    137      xliff.Bpt: lambda placeable: placeable_as_dom_node(placeable, 'bpt'),
    138      xliff.Bx : lambda placeable: placeable_as_dom_node(placeable, 'bx'),
    139      xliff.Ept: lambda placeable: placeable_as_dom_node(placeable, 'ept'),
    140      xliff.Ex : lambda placeable: placeable_as_dom_node(placeable, 'ex'),
    141      xliff.G  : lambda placeable: placeable_as_dom_node(placeable, 'g'),
    142      xliff.It : lambda placeable: placeable_as_dom_node(placeable, 'it'),
    143      xliff.Ph : lambda placeable: placeable_as_dom_node(placeable, 'ph'),
    144      xliff.Sub: lambda placeable: placeable_as_dom_node(placeable, 'sub'),
    145      xliff.X  : lambda placeable: placeable_as_dom_node(placeable, 'x'),
    146      xliff.UnknownXML: unknown_placeable_as_dom_node,
    147      base.Bpt:  lambda placeable: placeable_as_dom_node(placeable, 'bpt'),
    148      base.Bx :  lambda placeable: placeable_as_dom_node(placeable, 'bx'),
    149      base.Ept:  lambda placeable: placeable_as_dom_node(placeable, 'ept'),
    150      base.Ex :  lambda placeable: placeable_as_dom_node(placeable, 'ex'),
    151      base.G  :  lambda placeable: placeable_as_dom_node(placeable, 'g'),
    152      base.It :  lambda placeable: placeable_as_dom_node(placeable, 'it'),
    153      base.Ph :  lambda placeable: placeable_as_dom_node(placeable, 'ph'),
    154      base.Sub:  lambda placeable: placeable_as_dom_node(placeable, 'sub'),
    155      base.X  :  lambda placeable: placeable_as_dom_node(placeable, 'x')
    156  }
    157
    158 -def xml_append_string(node, string):
    159      if not len(node):
    160          if not node.text:
    161              node.text = unicode(string)
    162          else:
    163              node.text += unicode(string)
    164      else:
    165          lastchild = node.getchildren()[-1]
    166          if lastchild.tail is None:
    167              lastchild.tail = ''
    168          lastchild.tail += unicode(string)
    169      return node
    170
    171 -def strelem_to_xml(parent_node, elem):
    172      if isinstance(elem, (str, unicode)):
    173          return xml_append_string(parent_node, elem)
    174      if not isinstance(elem, StringElem):
    175          return parent_node
    176
    177      if type(elem) is StringElem and elem.isleaf():
    178          return xml_append_string(parent_node, elem)
    179
    180      if elem.__class__ in _placeable_dictionary:
    181          node = _placeable_dictionary[elem.__class__](elem)
    182          parent_node.append(node)
    183      else:
    184          node = parent_node
    185
    186      for sub in elem.sub:
    187          strelem_to_xml(node, sub)
    188
    189      return parent_node
    190
    191
    192 -def parse_xliff(pstr):
    193      try:
    194          return xml_to_strelem(etree.fromstring('<source>%s</source>' % (pstr)))
    195      except Exception, exc:
    196          raise
    197          return None
    198  xliff.parsers = [parse_xliff]
    199