# HG changeset patch # User cmlenz # Date 1212763059 0 # Node ID 3b8a38fcc1ab423424893731fb9a573bfbdaddb5 # Parent ca72e3dc443de591f481369cdcdb9cf71f9ea131 Minor cleanup in the i18n module. diff --git a/genshi/filters/i18n.py b/genshi/filters/i18n.py --- a/genshi/filters/i18n.py +++ b/genshi/filters/i18n.py @@ -332,26 +332,37 @@ class MessageBuffer(object): - """Helper class for managing localizable mixed content. + """Helper class for managing internationalized mixed content. :since: version 0.5 """ def __init__(self, lineno=-1): + """Initialize the message buffer. + + :param lineno: the line number on which the first stream event + belonging to the message was found + """ self.lineno = lineno - self.strings = [] + self.string = [] self.events = {} self.depth = 1 self.order = 1 self.stack = [0] def append(self, kind, data, pos): + """Append a stream event to the buffer. + + :param kind: the stream event kind + :param data: the event data + :param pos: the position of the event in the source + """ if kind is TEXT: - self.strings.append(data) + self.string.append(data) self.events.setdefault(self.stack[-1], []).append(None) else: if kind is START: - self.strings.append(u'[%d:' % self.order) + self.string.append(u'[%d:' % self.order) self.events.setdefault(self.order, []).append((kind, data, pos)) self.stack.append(self.order) self.depth += 1 @@ -360,13 +371,21 @@ self.depth -= 1 if self.depth: self.events[self.stack[-1]].append((kind, data, pos)) - self.strings.append(u']') + self.string.append(u']') self.stack.pop() def format(self): - return u''.join(self.strings).strip() + """Return a message identifier representing the content in the + buffer. + """ + return u''.join(self.string).strip() def translate(self, string): + """Interpolate the given message translation with the events in the + buffer and return the translated stream. + + :param string: the translated message string + """ parts = parse_msg(string) for order, string in parts: events = self.events[order] @@ -382,6 +401,50 @@ yield event +def parse_msg(string, regex=re.compile(r'(?:\[(\d+)\:)|\]')): + """Parse a translated message using Genshi mixed content message + formatting. + + >>> parse_msg("See [1:Help].") + [(0, 'See '), (1, 'Help'), (0, '.')] + + >>> parse_msg("See [1:our [2:Help] page] for details.") + [(0, 'See '), (1, 'our '), (2, 'Help'), (1, ' page'), (0, ' for details.')] + + >>> parse_msg("[2:Details] finden Sie in [1:Hilfe].") + [(2, 'Details'), (0, ' finden Sie in '), (1, 'Hilfe'), (0, '.')] + + >>> parse_msg("[1:] Bilder pro Seite anzeigen.") + [(1, ''), (0, ' Bilder pro Seite anzeigen.')] + + :param string: the translated message string + :return: a list of ``(order, string)`` tuples + :rtype: `list` + """ + parts = [] + stack = [0] + while True: + mo = regex.search(string) + if not mo: + break + + if mo.start() or stack[-1]: + parts.append((stack[-1], string[:mo.start()])) + string = string[mo.end():] + + orderno = mo.group(1) + if orderno is not None: + stack.append(int(orderno)) + else: + stack.pop() + if not stack: + break + + if string: + parts.append((stack[-1], string)) + + return parts + def extract_from_code(code, gettext_functions): """Extract strings from Python bytecode. @@ -425,47 +488,6 @@ yield funcname, strings return _walk(code.ast) -def parse_msg(string, regex=re.compile(r'(?:\[(\d+)\:)|\]')): - """Parse a message using Genshi compound message formatting. - - >>> parse_msg("See [1:Help].") - [(0, 'See '), (1, 'Help'), (0, '.')] - - >>> parse_msg("See [1:our [2:Help] page] for details.") - [(0, 'See '), (1, 'our '), (2, 'Help'), (1, ' page'), (0, ' for details.')] - - >>> parse_msg("[2:Details] finden Sie in [1:Hilfe].") - [(2, 'Details'), (0, ' finden Sie in '), (1, 'Hilfe'), (0, '.')] - - >>> parse_msg("[1:] Bilder pro Seite anzeigen.") - [(1, ''), (0, ' Bilder pro Seite anzeigen.')] - - :since: version 0.5 - """ - parts = [] - stack = [0] - while True: - mo = regex.search(string) - if not mo: - break - - if mo.start() or stack[-1]: - parts.append((stack[-1], string[:mo.start()])) - string = string[mo.end():] - - orderno = mo.group(1) - if orderno is not None: - stack.append(int(orderno)) - else: - stack.pop() - if not stack: - break - - if string: - parts.append((stack[-1], string)) - - return parts - def extract(fileobj, keywords, comment_tags, options): """Babel extraction method for Genshi templates.