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   
37 -def first_child(unit_node):
38 return unit_node.children.values()[0]
39 40
41 -def translate_odf(template, input_file):
42 43 def load_dom_trees(template): 44 odf_data = odf_io.open_odf(template) 45 return dict((filename, etree.parse(cStringIO.StringIO(data))) for filename, data in odf_data.iteritems())
46 47 def load_unit_tree(input_file, dom_trees): 48 store = factory.getobject(input_file) 49 tree = unit_tree.build_unit_tree(store) 50 51 def extract_unit_tree(filename, root_dom_element_name): 52 """Find the subtree in 'tree' which corresponds to the data in XML file 'filename'""" 53 54 def get_tree(): 55 try: 56 return tree.children['office:%s' % root_dom_element_name, 0] 57 except KeyError: 58 return unit_tree.XPathTree() 59 return (filename, get_tree()) 60 61 return dict([extract_unit_tree('content.xml', 'document-content'), 62 extract_unit_tree('meta.xml', 'document-meta'), 63 extract_unit_tree('styles.xml', 'document-styles')]) 64 65 def translate_dom_trees(unit_trees, dom_trees): 66 make_parse_state = lambda: extract.ParseState(odf_shared.no_translate_content_elements, odf_shared.inline_elements) 67 for filename, dom_tree in dom_trees.iteritems(): 68 file_unit_tree = unit_trees[filename] 69 generate.apply_translations(dom_tree.getroot(), file_unit_tree, generate.replace_dom_text(make_parse_state)) 70 return dom_trees 71 72 # Since the convertoptionsparser will give us an open file, we risk that 73 # it could have been opened in non-binary mode on Windows, and then we'll 74 # have problems, so let's make sure we have what we want. 75 template.close() 76 template = file(template.name, mode='rb') 77 dom_trees = load_dom_trees(template) 78 unit_trees = load_unit_tree(input_file, dom_trees) 79 return translate_dom_trees(unit_trees, dom_trees) 80 81
82 -def write_odf(xlf_data, template, output_file, dom_trees):
83 84 def write_content_to_odf(output_zip, dom_trees): 85 for filename, dom_tree in dom_trees.iteritems(): 86 output_zip.writestr(filename, etree.tostring(dom_tree, encoding='UTF-8', xml_declaration=True))
87 88 # Since the convertoptionsparser will give us an open file, we risk that 89 # it could have been opened in non-binary mode on Windows, and then we'll 90 # have problems, so let's make sure we have what we want. 91 template.close() 92 template = file(template.name, mode='rb') 93 template_zip = zipfile.ZipFile(template, 'r') 94 output_file.close() 95 output_file = file(output_file.name, mode='wb') 96 output_zip = zipfile.ZipFile(output_file, 'w', compression=zipfile.ZIP_DEFLATED) 97 # Let's keep the XLIFF file out of the generated ODF for now. Note the 98 # weird handling of the manifest since it can only be written to the ZIP 99 # file once. 100 # output_zip = odf_io.copy_odf(template_zip, output_zip, dom_trees.keys() + ['META-INF/manifest.xml']) 101 # output_zip = odf_io.add_file(output_zip, template_zip.read('META-INF/manifest.xml'), 'translation.xlf', xlf_data) 102 output_zip = odf_io.copy_odf(template_zip, output_zip, dom_trees.keys()) 103 write_content_to_odf(output_zip, dom_trees) 104 105
106 -def convertxliff(input_file, output_file, template):
107 """reads in stdin using fromfileclass, converts using convertorclass, writes to stdout""" 108 xlf_data = input_file.read() 109 dom_trees = translate_odf(template, cStringIO.StringIO(xlf_data)) 110 write_odf(xlf_data, template, output_file, dom_trees) 111 output_file.close() 112 return True
113 114 formats = { 115 ('xlf', 'odt'): ("odt", convertxliff), # Text 116 ('xlf', 'ods'): ("ods", convertxliff), # Spreadsheet 117 ('xlf', 'odp'): ("odp", convertxliff), # Presentation 118 ('xlf', 'odg'): ("odg", convertxliff), # Drawing 119 ('xlf', 'odc'): ("odc", convertxliff), # Chart 120 ('xlf', 'odf'): ("odf", convertxliff), # Formula 121 ('xlf', 'odi'): ("odi", convertxliff), # Image 122 ('xlf', 'odm'): ("odm", convertxliff), # Master Document 123 ('xlf', 'ott'): ("ott", convertxliff), # Text template 124 ('xlf', 'ots'): ("ots", convertxliff), # Spreadsheet template 125 ('xlf', 'otp'): ("otp", convertxliff), # Presentation template 126 ('xlf', 'otg'): ("otg", convertxliff), # Drawing template 127 ('xlf', 'otc'): ("otc", convertxliff), # Chart template 128 ('xlf', 'otf'): ("otf", convertxliff), # Formula template 129 ('xlf', 'oti'): ("oti", convertxliff), # Image template 130 ('xlf', 'oth'): ("oth", convertxliff), # Web page template 131 } 132 133
134 -def main(argv=None):
135 from translate.convert import convert 136 137 parser = convert.ConvertOptionParser(formats, usetemplates=True, description=__doc__) 138 parser.run(argv)
139 140 141 if __name__ == '__main__': 142 main() 143