translate.convert.xliff2odf

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