Package translate :: Package convert :: Module xliff2odf
[hide private]
[frames] | no frames]

Source Code for Module translate.convert.xliff2odf

  1  #!/usr/bin/env python 
  2  # -*- coding: utf-8 -*- 
  3  # 
  4  # Copyright 2004-2006 Zuza Software Foundation 
  5  #  
  6  # This file is part of translate. 
  7  # 
  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 
 10  # the Free Software Foundation; either version 2 of the License, or 
 11  # (at your option) any later version. 
 12  #  
 13  # translate 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 translate; if not, write to the Free Software 
 20  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
 21  # 
 22   
 23  """convert OpenDocument (ODF) files to Gettext PO localization files""" 
 24   
 25  import cStringIO 
 26  import zipfile 
 27   
 28  import lxml.etree as etree 
 29   
 30  from translate.storage import factory 
 31  from translate.storage.xml_extract import unit_tree 
 32  from translate.storage.xml_extract import extract 
 33  from translate.storage.xml_extract import generate 
 34  from translate.storage import odf_shared, odf_io 
 35   
36 -def first_child(unit_node):
37 return unit_node.children.values()[0]
38
39 -def translate_odf(template, input_file):
40 def load_dom_trees(template): 41 odf_data = odf_io.open_odf(template) 42 return dict((filename, etree.parse(cStringIO.StringIO(data))) for filename, data in odf_data.iteritems())
43 44 def load_unit_tree(input_file, dom_trees): 45 store = factory.getobject(input_file) 46 tree = unit_tree.build_unit_tree(store) 47 48 def extract_unit_tree(filename, root_dom_element_name): 49 """Find the subtree in 'tree' which corresponds to the data in XML file 'filename'""" 50 def get_tree(): 51 try: 52 return tree.children['office:%s' % root_dom_element_name, 0] 53 except KeyError: 54 return unit_tree.XPathTree() 55 return (filename, get_tree()) 56 57 return dict([extract_unit_tree('content.xml', 'document-content'), 58 extract_unit_tree('meta.xml', 'document-meta'), 59 extract_unit_tree('styles.xml', 'document-styles')]) 60 61 def translate_dom_trees(unit_trees, dom_trees): 62 make_parse_state = lambda: extract.ParseState(odf_shared.no_translate_content_elements, odf_shared.inline_elements) 63 for filename, dom_tree in dom_trees.iteritems(): 64 file_unit_tree = unit_trees[filename] 65 generate.apply_translations(dom_tree.getroot(), file_unit_tree, generate.replace_dom_text(make_parse_state)) 66 return dom_trees 67 68 # Since the convertoptionsparser will give us an open file, we risk that 69 # it could have been opened in non-binary mode on Windows, and then we'll 70 # have problems, so let's make sure we have what we want. 71 template.close() 72 template = file(template.name, mode='rb') 73 dom_trees = load_dom_trees(template) 74 unit_trees = load_unit_tree(input_file, dom_trees) 75 return translate_dom_trees(unit_trees, dom_trees) 76
77 -def write_odf(xlf_data, template, output_file, dom_trees):
78 def write_content_to_odf(output_zip, dom_trees): 79 for filename, dom_tree in dom_trees.iteritems(): 80 output_zip.writestr(filename, etree.tostring(dom_tree, encoding='UTF-8', xml_declaration=True))
81 82 # Since the convertoptionsparser will give us an open file, we risk that 83 # it could have been opened in non-binary mode on Windows, and then we'll 84 # have problems, so let's make sure we have what we want. 85 template.close() 86 template = file(template.name, mode='rb') 87 template_zip = zipfile.ZipFile(template, 'r') 88 output_file.close() 89 output_file = file(output_file.name, mode='wb') 90 output_zip = zipfile.ZipFile(output_file, 'w', compression=zipfile.ZIP_DEFLATED) 91 # Let's keep the XLIFF file out of the generated ODF for now. Note the 92 # weird handling of the manifest since it can only be written to the ZIP 93 # file once. 94 # output_zip = odf_io.copy_odf(template_zip, output_zip, dom_trees.keys() + ['META-INF/manifest.xml']) 95 # output_zip = odf_io.add_file(output_zip, template_zip.read('META-INF/manifest.xml'), 'translation.xlf', xlf_data) 96 output_zip = odf_io.copy_odf(template_zip, output_zip, dom_trees.keys()) 97 write_content_to_odf(output_zip, dom_trees) 98
99 -def convertxliff(input_file, output_file, template):
100 """reads in stdin using fromfileclass, converts using convertorclass, writes to stdout""" 101 xlf_data = input_file.read() 102 dom_trees = translate_odf(template, cStringIO.StringIO(xlf_data)) 103 write_odf(xlf_data, template, output_file, dom_trees) 104 output_file.close() 105 return True
106 107 formats = { 108 ('xlf', 'odt'): ("odt", convertxliff), # Text 109 ('xlf', 'ods'): ("ods", convertxliff), # Spreadsheet 110 ('xlf', 'odp'): ("odp", convertxliff), # Presentation 111 ('xlf', 'odg'): ("odg", convertxliff), # Drawing 112 ('xlf', 'odc'): ("odc", convertxliff), # Chart 113 ('xlf', 'odf'): ("odf", convertxliff), # Formula 114 ('xlf', 'odi'): ("odi", convertxliff), # Image 115 ('xlf', 'odm'): ("odm", convertxliff), # Master Document 116 ('xlf', 'ott'): ("ott", convertxliff), # Text template 117 ('xlf', 'ots'): ("ots", convertxliff), # Spreadsheet template 118 ('xlf', 'otp'): ("otp", convertxliff), # Presentation template 119 ('xlf', 'otg'): ("otg", convertxliff), # Drawing template 120 ('xlf', 'otc'): ("otc", convertxliff), # Chart template 121 ('xlf', 'otf'): ("otf", convertxliff), # Formula template 122 ('xlf', 'oti'): ("oti", convertxliff), # Image template 123 ('xlf', 'oth'): ("oth", convertxliff), # Web page template 124 } 125
126 -def main(argv=None):
127 from translate.convert import convert 128 129 parser = convert.ConvertOptionParser(formats, usetemplates=True, description=__doc__) 130 parser.run(argv)
131 132 if __name__ == '__main__': 133 main() 134