Viewing file: xmlgettext.py (2.6 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
from xml.dom import pulldom from cStringIO import StringIO from twisted.python import usage import nevow
class LineBasedStream(object): """ Allow pulldom to read at most one line at a time, to get accurate line number reporting. Otherwise it always reports everything is on the last line read in a single chunk.
Delay reporting newlines to next read, to avoid line numbers always being off by one.
Not the prettiest code I've written :-( """ def __init__(self, stream): self.stream = stream self.buffer = ''
def read(self, bufsize): if not self.buffer: self.buffer = self.stream.readline(bufsize)
if not self.buffer: # eof return ''
data, self.buffer = self.buffer, '' while data.endswith('\n'): self.buffer = self.buffer + data[-1] data = data[:-1] if not data: # data was nothing but newlines, undo above or it would # look like EOF and we'd never make progress data, self.buffer = self.buffer, '' return data
def getMsgID(node): out = StringIO() print >>out, 'msgid ""' for child in node.childNodes: s = child.toxml('utf-8') s = s.replace('\\', '\\\\') s = s.replace('"', '\\"') s = s.replace('\n', '\\n') print >>out, '"%s"' % s print >>out, 'msgstr ""' return out.getvalue()
def process(filename, messages): f = open(filename, 'rU') stream = LineBasedStream(f) events = pulldom.parse(stream)
for (event, node) in events: if event == pulldom.START_ELEMENT: get = getattr(node, 'getAttributeNS', None) if get is not None: value = get('http://nevow.com/ns/nevow/0.1', 'render') if value == 'i18n': events.expandNode(node)
msgid = getMsgID(node) l = messages.setdefault(msgid, []) l.append('#: %s:%d' % (filename, events.parser.getLineNumber()))
def report(messages): for msgid, locations in messages.items(): for line in locations: print line print msgid
class GettextOptions(usage.Options): def opt_version(self): print 'Nevow version:', nevow.__version__ usage.Options.opt_version(self)
def parseArgs(self, *files): self['files'] = files
def runApp(config): messages = {}
for filename in config['files']: process(filename, messages)
report(messages)
def run(): from twisted.application import app app.run(runApp, GettextOptions)
|