81
81
self.comments[t] = comment
83
83
def outputHeader(self, out):
84
85
out.write("""msgid ""
86
87
"Project-Id-Version: PACKAGE VERSION\\n"
87
"PO-Revision-Date: YEAR-MO-DA HO:MI +ZONE\\n"
88
"Language-Team: LANGUAGE\\n"
89
"Last-Translator: TRANSLATOR\\n"
88
"POT-Creation-Date: %s\\n"
89
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\\n"
90
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\\n"
91
"Language-Team: LANGUAGE <LL@li.org>\\n"
90
92
"MIME-Version: 1.0\\n"
91
93
"Content-Type: text/plain; charset=UTF-8\\n"
92
94
"Content-Transfer-Encoding: 8bit\\n"
96
""" % (time.strftime("%Y-%m-%d %H:%M%z")))
96
98
def outputAll(self, out):
97
99
self.outputHeader(out)
141
142
# Lets add document DTD so entities are resolved
142
143
dtd = doc.intSubset()
144
if expand_entities: # FIXME: we get a "Segmentation fault" in libxml2.parseMemory() when we include DTD otherwise
145
tmp = dtd.serialize()
144
tmp = dtd.serialize('utf-8')
146
145
tmp = tmp + '<norm>%s</norm>' % text
148
147
tmp = '<norm>%s</norm>' % text
151
#libxml2.replaceEntities(0)
152
tree = libxml2.parseMemory(tmp,len(tmp))
150
ctxt = libxml2.createDocParserCtxt(tmp)
152
ctxt.replaceEntities(1)
153
155
newnode = tree.getRootElement()
155
157
print >> sys.stderr, """Error while normalizing string as XML:\n"%s"\n""" % (text)
171
173
def stringForEntity(node):
172
174
"""Replaces entities in the node."""
173
text = node.serialize()
175
text = node.serialize('utf-8')
175
177
# Lets add document DTD so entities are resolved
176
178
dtd = node.doc.intSubset()
177
tmp = dtd.serialize() + '<norm>%s</norm>' % text
179
tmp = dtd.serialize('utf-8') + '<norm>%s</norm>' % text
180
182
tmp = '<norm>%s</norm>' % text
300
306
def replaceNodeContentsWithText(node,text):
301
307
"""Replaces all subnodes of a node with contents of text treated as XML."""
302
#print >> sys.stderr, text
303
308
if node.children:
304
starttag = startTagForNode(node)
309
starttag = node.name #startTagForNode(node)
310
endtag = endTagForNode(node)
307
312
# Lets add document DTD so entities are resolved
308
313
dtd = doc.intSubset()
310
315
if expand_entities: # FIXME: we get a "Segmentation fault" in libxml2.parseMemory() when we include DTD otherwise
311
tmp = dtd.serialize()
316
tmp = dtd.serialize('utf-8')
312
317
tmp = tmp + '<%s>%s</%s>' % (starttag, text, endtag)
314
319
tmp = '<%s>%s</%s>' % (starttag, text, endtag)
317
ctxt = libxml2.createDocParserCtxt(tmp)
322
ctxt = libxml2.createDocParserCtxt(tmp.encode('utf-8'))
318
323
ctxt.replaceEntities(0)
319
324
ctxt.parseDocument()
320
325
newnode = ctxt.doc()
322
print >> sys.stderr, """Error while parsing translation as XML:\n"%s"\n""" % (text)
327
print >> sys.stderr, """Error while parsing translation as XML:\n"%s"\n""" % (text.encode('utf-8'))
325
330
newelem = newnode.getRootElement()
372
379
return autoNodeIsFinal(node)
374
def processElementTag(node):
381
def processElementTag(node, replacements, restart = 0):
375
382
"""Process node with node.type == 'element'."""
376
383
if node.type == 'element':
379
if not worthOutputting(node):
380
child = node.children
382
outtxt += doSerialize(child)
388
child = node.children
390
if isFinalNode(child):
392
(starttag, submsg, endtag) = processElementTag(child)
393
outtxt += '<placeholder-%d/>' % (PlaceHolder)
395
submsgs[PlaceHolder] = (starttag, getTranslation(submsg, isSpacePreserveNode(node)), endtag)
388
myrepl = replacements
392
child = node.children
394
if (isFinalNode(child)) or (child.type == 'element' and worthOutputting(child)):
395
myrepl.append(processElementTag(child, myrepl, 1))
396
outtxt += '<placeholder-%d/>' % (len(myrepl))
398
if child.type == 'element':
399
(starttag, content, endtag, translation) = processElementTag(child, myrepl, 0)
400
outtxt += '<%s>%s</%s>' % (starttag, content, endtag)
397
402
outtxt += doSerialize(child)
402
outtxt = getTranslation(outtxt, isSpacePreserveNode(node))
403
for i in submsgs.keys():
404
outtxt = outtxt.replace('<placeholder-%d/>' % (i), ''.join(submsgs[i]))
405
if worthOutputting(node):
406
replaceNodeContentsWithText(node, outtxt)
407
elif worthOutputting(node):
408
msg.outputMessage(outtxt, node.lineNo(), getCommentForNode(node), isSpacePreserveNode(node), tag = node.name)
410
starttag = '<' + startTagForNode(node) + '>'
411
endtag = '</' + node.name + '>'
412
return (starttag, outtxt, endtag)
407
translation = getTranslation(outtxt, isSpacePreserveNode(node))
410
starttag = startTagForNode(node)
411
endtag = endTagForNode(node)
413
if restart or worthOutputting(node):
415
while i < len(myrepl):
416
replacement = '<%s>%s</%s>' % (myrepl[i][0], myrepl[i][3], myrepl[i][2])
418
translation = translation.replace('<placeholder-%d/>' % (i), replacement)
420
if worthOutputting(node):
422
replaceNodeContentsWithText(node, translation)
424
msg.outputMessage(outtxt, node.lineNo(), getCommentForNode(node), isSpacePreserveNode(node), tag = node.name)
426
return (starttag, outtxt, endtag, translation)
414
428
raise Exception("You must pass node with node.type=='element'.")
458
472
elif node.type == 'text':
459
473
return node.serialize('utf-8')
460
474
elif node.type == 'element':
461
return ''.join(processElementTag(node))
476
(starttag, content, endtag, translation) = processElementTag(node, repl, 1)
477
return '<%s>%s</%s>' % (starttag, content, endtag)
463
479
child = node.children
610
631
if len(sys.argv) < 2: usage()
612
633
args = sys.argv[1:]
613
try: opts, args = getopt.getopt(args, 'avhkem:t:o:p:u:r:',
634
try: opts, args = getopt.getopt(args, 'avhkem:t:o:p:u:r:l:',
614
635
['automatic-tags','version', 'help', 'keep-entities', 'expand-all-entities', 'mode=', 'translation=',
615
'output=', 'po-file=', 'update-translation=', 'reuse=' ])
636
'output=', 'po-file=', 'update-translation=', 'reuse=', 'language=' ])
616
637
except getopt.GetoptError: usage(True)
618
639
for opt, arg in opts:
624
645
expand_entities = 0
625
646
elif opt in ('-e', '--expand-all-entities'):
626
647
expand_all_entities = 1
648
elif opt in ('-l', '--language'):
649
translationlanguage = arg
627
650
elif opt in ('-t', '--translation'):
630
translationlanguage = os.path.splitext(mofile)[0]
653
if translationlanguage == '': translationlanguage = os.path.split(os.path.splitext(mofile)[0])[1]
631
654
elif opt in ('-r', '--reuse'):
633
656
elif opt in ('-u', '--update-translation'):
635
658
elif opt in ('-p', '--po-file'):
636
659
mofile = ".xml2po.mo"
638
translationlanguage = os.path.splitext(pofile)[0]
639
os.system("msgfmt -o %s %s >/dev/null" % (mofile, pofile)) and sys.exit(7)
661
if translationlanguage == '': translationlanguage = os.path.split(os.path.splitext(pofile)[0])[1]
662
os.system("msgfmt -o %s %s >%s" % (mofile, pofile, NULL_STRING)) and sys.exit(7)
641
664
elif opt in ('-o', '--output'):