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