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
     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