Package translate :: Package storage :: Module qph

[hide private]
[frames] | no frames]

# Source Code for Module translate.storage.qph

      1  #!/usr/bin/env python
      2  # -*- coding: utf-8 -*-
      3  #
      4  # Copyright 2008, 2010 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  """Module for handling Qt Linguist Phrase Book (.qph) files.
     24
     25  Extract from the U{Qt Linguist Manual:
     26  Translators<http://doc.trolltech.com/4.3/linguist-translators.html>}:
     27  .qph Qt Phrase Book Files are human-readable XML files containing standard
     28  phrases and their translations. These files are created and updated by Qt
     29  Linguist and may be used by any number of projects and applications.
     30
     31  A DTD to define the format does not seem to exist, but the following U{code
     32  U{code<http://qt.gitorious.org/qt/qt/blobs/4.7/tools/linguist/shared/qph.cpp}>
     33  provides the reference implementation for the Qt Linguist product.
     34  """
     35
     36  from lxml import etree
     37
     38  from translate.lang import data
     39  from translate.misc.typecheck import accepts, Self, IsOneOf
     40  from translate.misc.typecheck.typeclasses import String
     41  from translate.storage import lisa
     42
     43
     44 -class QphUnit(lisa.LISAunit):
     45      """A single term in the qph file."""
     46
     47      rootNode = "phrase"
     48      languageNode = "source"
     49      textNode = ""
     50      namespace = ''
     51
     52 -    def createlanguageNode(self, lang, text, purpose):
     53          """Returns an xml Element setup with given parameters."""
     54          assert purpose
     55          langset = etree.Element(self.namespaced(purpose))
     56          langset.text = text
     57          return langset
     58
     59 -    def _getsourcenode(self):
     60          return self.xmlelement.find(self.namespaced(self.languageNode))
     61
     62 -    def _gettargetnode(self):
     63          return self.xmlelement.find(self.namespaced("target"))
     64
     65 -    def getlanguageNodes(self):
     66          """We override this to get source and target nodes."""
     67
     68          def not_none(node):
     69              return not node is None
     70
     71          return filter(not_none, [self._getsourcenode(), self._gettargetnode()])
     72
     73      @accepts(Self(), unicode, IsOneOf(String, type(None)), String)
     74 -    def addnote(self, text, origin=None, position="append"):
     75          """Add a note specifically in a "definition" tag"""
     76          current_notes = self.getnotes(origin)
     77          self.removenotes()
     78          note = etree.SubElement(self.xmlelement, self.namespaced("definition"))
     79          note.text = "\n".join(filter(None, [current_notes, text.strip()]))
     80
     81 -    def getnotes(self, origin=None):
     82          #TODO: consider only responding when origin has certain values
     83          notenode = self.xmlelement.find(self.namespaced("definition"))
     84          comment = ''
     85          if not notenode is None:
     86              comment = notenode.text
     87          return comment
     88
     89 -    def removenotes(self):
     90          """Remove all the translator notes."""
     91          note = self.xmlelement.find(self.namespaced("definition"))
     92          if not note is None:
     93              self.xmlelement.remove(note)
     94
     95
     96 -class QphFile(lisa.LISAfile):
     97      """Class representing a QPH file store."""
     98      UnitClass = QphUnit
     99      Name = _("Qt Phrase Book")
    100      Mimetypes = ["application/x-qph"]
    101      Extensions = ["qph"]
    102      rootNode = "QPH"
    103      bodyNode = "QPH"
    104      XMLskeleton = '''<!DOCTYPE QPH>
    105  <QPH>
    106  </QPH>
    107  '''
    108      namespace = ''
    109
    110 -    def initbody(self):
    111          """Initialises self.body so it never needs to be retrieved from the
    112          XML again."""
    113          self.namespace = self.document.getroot().nsmap.get(None, None)
    114          self.header = self.document.getroot()
    115          self.body = self.document.getroot() # The root node contains the units
    116
    117 -    def getsourcelanguage(self):
    118          """Get the source language for this .qph file.
    119
    120          We don't implement setsourcelanguage as users really shouldn't be
    121          altering the source language in .qph files, it should be set correctly
    122          by the extraction tools.
    123
    124          @return: ISO code e.g. af, fr, pt_BR
    125          @rtype: String
    126          """
    127          lang = data.normalize_code(self.header.get('sourcelanguage', "en"))
    128          if lang == 'en-us':
    129              return 'en'
    130          return lang
    131
    132 -    def gettargetlanguage(self):
    133          """Get the target language for this .qph file.
    134
    135          @return: ISO code e.g. af, fr, pt_BR
    136          @rtype: String
    137          """
    138          return data.normalize_code(self.header.get('language'))
    139
    140 -    def settargetlanguage(self, targetlanguage):
    141          """Set the target language for this .qph file to L{targetlanguage}.
    142
    143          @param targetlanguage: ISO code e.g. af, fr, pt_BR
    144          @type targetlanguage: String
    145          """
    146          if targetlanguage:
    147              self.header.set('language', targetlanguage)
    148
    149 -    def __str__(self):
    150          """Converts to a string containing the file's XML.
    151
    152          We have to override this to ensure mimic the Qt convention:
    153              - no XML decleration
    154              - plain DOCTYPE that lxml seems to ignore
    155          """
    156          # A bug in lxml means we have to output the doctype ourselves. For
    157          # more information, see:
    158          # http://codespeak.net/pipermail/lxml-dev/2008-October/004112.html
    159          # The problem was fixed in lxml 2.1.3
    160          output = etree.tostring(self.document, pretty_print=True,
    161                                  xml_declaration=False, encoding='utf-8')
    162          if not "<!DOCTYPE QPH>" in output[:30]:
    163              output = "<!DOCTYPE QPH>" + output
    164          return output
    165