1
2
3
4 from translate.convert import dtd2po
5 from translate.convert import test_convert
6 from translate.misc import wStringIO
7 from translate.storage import po
8 from translate.storage import dtd
9
11 - def dtd2po(self, dtdsource, dtdtemplate=None):
23
31
38
45
60
69
71 """apostrophe should not break a single-quoted entity definition, bug 69"""
72 dtdsource = "<!ENTITY test.me 'bananas ' for sale'>\n"
73 pofile = self.dtd2po(dtdsource)
74 pounit = self.singleelement(pofile)
75 assert pounit.source == "bananas ' for sale"
76
78 """quotes should be handled in a single-quoted entity definition"""
79 dtdsource = """<!ENTITY test.metoo '"Bananas" for sale'>\n"""
80 pofile = self.dtd2po(dtdsource)
81 pounit = self.singleelement(pofile)
82 print str(pounit)
83 assert pounit.source == '"Bananas" for sale'
84
86 """checks that empty entity definitions survive into po file, bug 15"""
87 dtdsource = '<!ENTITY credit.translation "">\n'
88 pofile = self.dtd2po(dtdsource)
89 pounit = self.singleelement(pofile)
90 assert "credit.translation" in str(pounit)
91
93 """checks that if we translate an empty entity it makes it into the PO, bug 101"""
94 dtdtemplate = '<!ENTITY credit.translation "">\n'
95 dtdsource = '<!ENTITY credit.translation "Translators Names">\n'
96 pofile = self.dtd2po(dtdsource, dtdtemplate)
97 unit = self.singleelement(pofile)
98 print unit
99 assert "credit.translation" in str(unit)
100
101 assert len(unit.getid()) != 0
102 assert unit.target == "Translators Names"
103
105 """test the simple localisation more becomes a #. comment"""
106 dtdsource = '''<!-- LOCALIZATION NOTE (alwaysCheckDefault.height):
107 There's some sort of bug which makes wrapping checkboxes not properly reflow,
108 causing the bottom border of the groupbox to be cut off; set this
109 appropriately if your localization causes this checkbox to wrap.
110 -->
111 <!ENTITY alwaysCheckDefault.height "3em">
112 '''
113 pofile = self.dtd2po(dtdsource)
114 posource = str(pofile)
115 print posource
116 assert posource.count('#.') == 5
117
119 """test that LOCALIZATION NOTES are added properly as #. comments and disambiguated with msgctxt entries"""
120 dtdtemplate = '<!--LOCALIZATION NOTE (%s): Some note -->\n' + \
121 '<!ENTITY %s "Source text">\n'
122 dtdsource = dtdtemplate % ("note1.label", "note1.label") + dtdtemplate % ("note2.label", "note2.label")
123 pofile = self.dtd2po(dtdsource)
124 posource = str(pofile.units[1]) + str(pofile.units[2])
125 print posource
126 assert posource.count('#.') == 2
127 assert posource.count('msgctxt') == 2
128
130 """check that we handle DONT_TRANSLATE messages properly"""
131 dtdsource = '''<!-- LOCALIZATION NOTE (region.Altitude): DONT_TRANSLATE -->
132 <!ENTITY region.Altitude "Very High">'''
133 pofile = self.dtd2po(dtdsource)
134 assert self.countelements(pofile) == 0
135 dtdsource = '''<!-- LOCALIZATION NOTE (exampleOpenTag.label): DONT_TRANSLATE: they are text for HTML tagnames: "<i>" and "</i>" -->
136 <!ENTITY exampleOpenTag.label "<i>">'''
137 pofile = self.dtd2po(dtdsource)
138 assert self.countelements(pofile) == 0
139 dtdsource = '''<!-- LOCALIZATION NOTE (imapAdvanced.label): Do not translate "IMAP" -->
140 <!ENTITY imapAdvanced.label "Advanced IMAP Server Settings">'''
141 pofile = self.dtd2po(dtdsource)
142 assert self.countelements(pofile) == 1
143
145 """test strangeness when label entity is marked DONT_TRANSLATE and accesskey is not, bug 30"""
146 dtdsource = '<!--LOCALIZATION NOTE (editorCheck.label): DONT_TRANSLATE -->\n' + \
147 '<!ENTITY editorCheck.label "Composer">\n<!ENTITY editorCheck.accesskey "c">\n'
148 pofile = self.dtd2po(dtdsource)
149 posource = str(pofile)
150
151
152 assert 'editorCheck.label' not in posource
153 assert 'editorCheck.accesskey' in posource
154
156 """if the entity is itself just another entity then it shouldn't appear in the output PO file"""
157 dtdsource = '''<!-- LOCALIZATION NOTE (mainWindow.title): DONT_TRANSLATE -->
158 <!ENTITY mainWindow.title "&brandFullName;">'''
159 pofile = self.dtd2po(dtdsource)
160 assert self.countelements(pofile) == 0
161
168
170 """test that pretty print spaces at the start of subsequent DTD element lines are removed from the PO file, bug 79"""
171
172 dtdsource = '<!ENTITY noupdatesfound.intro "First line then \n' + \
173 ' next lines.">\n'
174 pofile = self.dtd2po(dtdsource)
175 pounit = self.singleelement(pofile)
176
177
178 assert pounit.source == "First line then \nnext lines."
179
180 dtdsource = '<!ENTITY noupdatesfound.intro "First line then\n' + \
181 ' next lines.">\n'
182 pofile = self.dtd2po(dtdsource)
183 pounit = self.singleelement(pofile)
184 assert pounit.source == "First line then \nnext lines."
185
187 """test that we fold accesskeys into message strings"""
188 dtdsource_template = '<!ENTITY fileSaveAs.%s "Save As...">\n<!ENTITY fileSaveAs.%s "S">\n'
189 lang_template = '<!ENTITY fileSaveAs.%s "Gcina ka...">\n<!ENTITY fileSaveAs.%s "G">\n'
190 for label in ("label", "title"):
191 for accesskey in ("accesskey", "accessKey", "akey"):
192 pofile = self.dtd2po(dtdsource_template % (label, accesskey))
193 pounit = self.singleelement(pofile)
194 assert pounit.source == "&Save As..."
195
196 pofile = self.dtd2po(lang_template % (label, accesskey), dtdsource_template % (label, accesskey))
197 pounit = self.singleelement(pofile)
198 assert pounit.source == "&Save As..."
199 assert pounit.target == "&Gcina ka..."
200
202 """check that we can handle accesskeys that don't match and thus can't be folded into the .label entry"""
203 dtdsource = '<!ENTITY fileSave.label "Save">\n' + \
204 '<!ENTITY fileSave.accesskey "z">\n'
205 pofile = self.dtd2po(dtdsource)
206 assert self.countelements(pofile) == 2
207
209 """test that we create nice PO files when we find a \r\n in a multiline DTD element"""
210 dtdsource = '<!ENTITY noupdatesfound.intro "First line then \r\n' + \
211 ' next lines.">\n'
212 pofile = self.dtd2po(dtdsource)
213 unit = self.singleelement(pofile)
214 assert unit.source == "First line then \nnext lines."
215
217 """test that we can process a multiline entity that has a blank line in it, bug 331"""
218 dtdsource = '''
219 <!ENTITY multiline.text "
220 Some text
221
222 Some other text
223 ">'''
224 pofile = self.dtd2po(dtdsource)
225 unit = self.singleelement(pofile)
226 assert unit.source == "Some text \n \nSome other text"
227
229 """test that we support various styles and spaces after closing quotes on multiline entities"""
230 dtdsource = '''
231 <!ENTITY pref.plural '<span>opsies</span><span
232 class="noWin">preferences</span>' >
233 '''
234 pofile = self.dtd2po(dtdsource)
235 unit = self.singleelement(pofile)
236 assert unit.source == '<span>opsies</span><span \nclass="noWin">preferences</span>'
237
239 """test that we preserve space that appear at the start of the first line of a DTD entity"""
240
241 dtdsource = '<!ENTITY mainWindow.titlemodifiermenuseparator " - ">'
242 pofile = self.dtd2po(dtdsource)
243 unit = self.singleelement(pofile)
244 assert unit.source == " - "
245
246 dtdsource = '<!ENTITY mainWindow.titlemodifiermenuseparator " - with a newline\n and more text">'
247 pofile = self.dtd2po(dtdsource)
248 unit = self.singleelement(pofile)
249 print repr(unit.source)
250 assert unit.source == " - with a newline \nand more text"
251
253 """test that we handle all kinds of newline permutations"""
254 dtdsource = '<!ENTITY noupdatesfound.intro "A hard coded newline.\\nAnd tab\\t and a \\r carriage return.">\n'
255 converter = dtd2po.dtd2po()
256 thedtd = dtd.dtdunit()
257 thedtd.parse(dtdsource)
258 thepo = po.pounit()
259 converter.convertstrings(thedtd, thepo)
260 print thedtd
261 print thepo.source
262
263 assert thepo.source == r"A hard coded newline.\nAnd tab\t and a \r carriage return."
264
266 """test that when a language DTD has an accelerator but the template DTD does not that we abandon the accelerator"""
267 dtdtemplate = '<!ENTITY test.label "Test">\n'
268 dtdlanguage = '<!ENTITY test.label "Toets">\n<!ENTITY test.accesskey "T">\n'
269 pofile = self.dtd2po(dtdlanguage, dtdtemplate)
270 unit = self.singleelement(pofile)
271 assert unit.source == "Test"
272 assert unit.target == "Toets"
273
275 """test to see that we can handle accelerator keys that cannot be associated correctly"""
276 dtdsource = '<!ENTITY managecerts.button "Manage Certificates...">\n<!ENTITY managecerts.accesskey "M">'
277 pofile = self.dtd2po(dtdsource)
278 assert pofile.units[1].source == "Manage Certificates..."
279 assert pofile.units[2].source == "M"
280 pofile = self.dtd2po(dtdsource, dtdsource)
281 assert pofile.units[1].target == "Manage Certificates..."
282 assert pofile.units[2].target == "M"
283
285 """test to ensure that when the template changes an entity name we can still manage the accelerators"""
286 dtdtemplate = '''<!ENTITY managecerts.caption "Manage Certificates">
287 <!ENTITY managecerts.text "Use the Certificate Manager to manage your personal certificates, as well as those of other people and certificate authorities.">
288 <!ENTITY managecerts.button "Manage Certificates...">
289 <!ENTITY managecerts.accesskey "M">'''
290 dtdlanguage = '''<!ENTITY managecerts.label "ﺇﺩﺍﺭﺓ ﺎﻠﺸﻫﺍﺩﺎﺗ">
291 <!ENTITY managecerts.text "ﺎﺴﺘﺧﺪﻣ ﻡﺪﻳﺭ ﺎﻠﺸﻫﺍﺩﺎﺗ ﻹﺩﺍﺭﺓ ﺶﻫﺍﺩﺎﺘﻛ ﺎﻠﺸﺨﺼﻳﺓ، ﺏﺍﻺﺿﺎﻓﺓ ﻞﺘﻠﻛ ﺎﻠﺧﺎﺻﺓ ﺏﺍﻶﺧﺮﻴﻧ ﻭ ﺲﻠﻃﺎﺗ ﺎﻠﺸﻫﺍﺩﺎﺗ.">
292 <!ENTITY managecerts.button "ﺇﺩﺍﺭﺓ ﺎﻠﺸﻫﺍﺩﺎﺗ...">
293 <!ENTITY managecerts.accesskey "ﺩ">'''
294 pofile = self.dtd2po(dtdlanguage, dtdtemplate)
295 print pofile
296 assert pofile.units[3].source == "Manage Certificates..."
297 assert pofile.units[3].target == u"ﺇﺩﺍﺭﺓ ﺎﻠﺸﻫﺍﺩﺎﺗ..."
298 assert pofile.units[4].source == "M"
299 assert pofile.units[4].target == u"ﺩ"
300
302 """tests to ensure that we can manage accelerator keys that are not part of the transated sentence eg in Chinese"""
303 dtdtemplate = '''<!ENTITY useAutoScroll.label "Use autoscrolling">
304 <!ENTITY useAutoScroll.accesskey "a">'''
305 dtdlanguage = '''<!ENTITY useAutoScroll.label "使用自動捲動(Autoscrolling)">
306 <!ENTITY useAutoScroll.accesskey "a">'''
307 pofile = self.dtd2po(dtdlanguage, dtdtemplate)
308 print pofile
309 assert pofile.units[1].target == "使用自動捲動(&Autoscrolling)"
310
311
312 dtdlanguage = '''<!ENTITY useAutoScroll.label "使用自動捲動">
313 <!ENTITY useAutoScroll.accesskey "a">'''
314 pofile = self.dtd2po(dtdlanguage, dtdtemplate)
315 print pofile
316 assert pofile.units[1].target == "使用自動捲動 (&A)"
317
319 """test that we don't turn an include into a translatable string"""
320 dtdsource = '<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">'
321 pofile = self.dtd2po(dtdsource)
322 assert self.countelements(pofile) == 0
323
325 """check that redundant line wraps are removed from the po file"""
326 dtdsource = '''<!ENTITY generic.longDesc "
327 <p>Test me.</p>
328 ">'''
329 pofile = self.dtd2po(dtdsource)
330 pounit = self.singleelement(pofile)
331 assert pounit.source == "<p>Test me.</p>"
332
334 """test that when we merge in new untranslated strings with existing translations we manage the encodings properly"""
335
336 dtdtemplate = '''<!ENTITY unreadFolders.label "Unread">\n<!ENTITY viewPickerUnread.label "Unread">\n<!ENTITY unreadColumn.label "Unread">'''
337 dtdlanguage = '''<!ENTITY viewPickerUnread.label "Непрочетени">\n<!ENTITY unreadFolders.label "Непрочетени">'''
338 pofile = self.dtd2po(dtdlanguage, dtdtemplate)
339 print pofile
340 assert pofile.units[1].source == "Unread"
341
343 """test that we we manage the case where we merge and their is no template file"""
344
345
346
347
348 dtdtemplate = ''
349 dtdsource = '<!ENTITY no.template "Target">'
350 pofile = self.dtd2po(dtdsource, dtdtemplate)
351 print pofile
352 assert self.countelements(pofile) == 0
353
355 """Tests running actual dtd2po commands on files"""
356 convertmodule = dtd2po
357 defaultoptions = {"progress": "none"}
358
365