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 sub = result.sub # just an optimisation 105 for child_dom_node in dom_node: 106 sub.append(make_placeable(child_dom_node, xml_space)) 107 if child_dom_node.tail: 108 sub.append(StringElem(unicode(child_dom_node.tail))) 109 110 # This is just a strange way of inserting the first text and avoiding a 111 # call to .prune() which is very expensive. We assume the tree is optimal. 112 node_text = dom_node.text 113 if sub and node_text: 114 sub.insert(0, StringElem(unicode(node_text))) 115 elif node_text: 116 sub.append(unicode(node_text)) 117 return result
118 119 # ========================================================== 120 121
122 -def placeable_as_dom_node(placeable, tagname):
123 dom_node = etree.Element(tagname) 124 if placeable.id is not None: 125 dom_node.attrib['id'] = placeable.id 126 if placeable.xid is not None: 127 dom_node.attrib['xid'] = placeable.xid 128 if placeable.rid is not None: 129 dom_node.attrib['rid'] = placeable.rid 130 131 if hasattr(placeable, 'xml_attrib'): 132 for attrib, value in placeable.xml_attrib.items(): 133 dom_node.set(attrib, value) 134 135 return dom_node
136 137
138 -def unknown_placeable_as_dom_node(placeable):
139 assert type(placeable) is xliff.UnknownXML 140 141 from copy import copy 142 node = copy(placeable.xml_node) 143 for i in range(len(node)): 144 del node[0] 145 node.tail = None 146 node.text = None 147 148 return node
149 150 _placeable_dictionary = { 151 xliff.Bpt: lambda placeable: placeable_as_dom_node(placeable, 'bpt'), 152 xliff.Bx: lambda placeable: placeable_as_dom_node(placeable, 'bx'), 153 xliff.Ept: lambda placeable: placeable_as_dom_node(placeable, 'ept'), 154 xliff.Ex: lambda placeable: placeable_as_dom_node(placeable, 'ex'), 155 xliff.G: lambda placeable: placeable_as_dom_node(placeable, 'g'), 156 xliff.It: lambda placeable: placeable_as_dom_node(placeable, 'it'), 157 xliff.Ph: lambda placeable: placeable_as_dom_node(placeable, 'ph'), 158 xliff.Sub: lambda placeable: placeable_as_dom_node(placeable, 'sub'), 159 xliff.X: lambda placeable: placeable_as_dom_node(placeable, 'x'), 160 xliff.UnknownXML: unknown_placeable_as_dom_node, 161 base.Bpt: lambda placeable: placeable_as_dom_node(placeable, 'bpt'), 162 base.Bx: lambda placeable: placeable_as_dom_node(placeable, 'bx'), 163 base.Ept: lambda placeable: placeable_as_dom_node(placeable, 'ept'), 164 base.Ex: lambda placeable: placeable_as_dom_node(placeable, 'ex'), 165 base.G: lambda placeable: placeable_as_dom_node(placeable, 'g'), 166 base.It: lambda placeable: placeable_as_dom_node(placeable, 'it'), 167 base.Ph: lambda placeable: placeable_as_dom_node(placeable, 'ph'), 168 base.Sub: lambda placeable: placeable_as_dom_node(placeable, 'sub'), 169 base.X: lambda placeable: placeable_as_dom_node(placeable, 'x'), 170 } 171 172
173 -def xml_append_string(node, string):
174 if not len(node): 175 if not node.text: 176 node.text = unicode(string) 177 else: 178 node.text += unicode(string) 179 else: 180 lastchild = node.getchildren()[-1] 181 if lastchild.tail is None: 182 lastchild.tail = '' 183 lastchild.tail += unicode(string) 184 return node
185 186
187 -def strelem_to_xml(parent_node, elem):
188 if isinstance(elem, unicode): 189 return xml_append_string(parent_node, elem) 190 if not isinstance(elem, StringElem): 191 return parent_node 192 193 if type(elem) is StringElem and elem.isleaf(): 194 return xml_append_string(parent_node, elem) 195 196 if elem.__class__ in _placeable_dictionary: 197 node = _placeable_dictionary[elem.__class__](elem) 198 parent_node.append(node) 199 else: 200 node = parent_node 201 202 for sub in elem.sub: 203 strelem_to_xml(node, sub) 204 205 return parent_node
206 207
208 -def parse_xliff(pstr):
209 try: 210 return xml_to_strelem(etree.fromstring('<source>%s</source>' % (pstr))) 211 except Exception, exc: 212 raise 213 return None
214 xliff.parsers = [parse_xliff] 215