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.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
45 """A single term in the qph file."""
46
47 rootNode = "phrase"
48 languageNode = "source"
49 textNode = ""
50 namespace = ''
51
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
61
64
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
82
83 notenode = self.xmlelement.find(self.namespaced("definition"))
84 comment = ''
85 if not notenode is None:
86 comment = notenode.text
87 return comment
88
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
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()
116
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
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
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
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
157
158
159
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