1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
46 """A single term in the qph file."""
47
48 rootNode = "phrase"
49 languageNode = "source"
50 textNode = ""
51 namespace = ''
52
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
62
65
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
83
84 notenode = self.xmlelement.find(self.namespaced("definition"))
85 comment = ''
86 if not notenode is None:
87 comment = notenode.text
88 return comment
89
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
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()
117
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
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
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
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
158
159
160
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