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