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