Edgewall Software

Ticket #426: t426.2.diff

File t426.2.diff, 6.7 KB (added by cboos, 12 years ago)

i18n:choose case corrected

  • genshi/filters/i18n.py

    # HG changeset patch
    # Parent 924949fd71673266ccb00169f99ae7cd47496d16
    i18n: `MessageBuffer.translate()` now uses the untranslated message as a fallback in case the translated message doesn't parse correctly.
    
    Fixes #426.
    
    diff -r 924949fd7167 genshi/filters/i18n.py
    a b class MsgDirective(ExtractableI18NDirect 
    175175            if previous[0] is not END:
    176176                msgbuf.append(*previous)
    177177                previous = None
    178             for event in msgbuf.translate(gettext(msgbuf.format())):
     178            msg = msgbuf.format()
     179            for event in msgbuf.translate(gettext(msg), original=msg):
    179180                yield event
    180181            if previous:
    181182                yield previous
    class ChooseDirective(ExtractableI18NDir 
    411412            if kind is MSGBUF:
    412413                for event in choice:
    413414                    if event[0] is MSGBUF:
    414                         translation = ngettext(singular_msgbuf.format(),
    415                                                plural_msgbuf.format(),
    416                                                numeral)
    417                         for subevent in msgbuf.translate(translation):
     415                        smsg = singular_msgbuf.format()
     416                        pmsg = plural_msgbuf.format()
     417                        orig = (pmsg, smsg)[numeral == 1]
     418                        translation = ngettext(smsg, pmsg, numeral)
     419                        for subevent in msgbuf.translate(translation,
     420                                                         original=orig):
    418421                            yield subevent
    419422                    else:
    420423                        yield event
    class MessageBuffer(object): 
    10151018        """
    10161019        return ''.join(self.string).strip()
    10171020
    1018     def translate(self, string, regex=re.compile(r'%\((\w+)\)s')):
     1021    def translate(self, string, regex=re.compile(r'%\((\w+)\)s'),
     1022                  original=None):
    10191023        """Interpolate the given message translation with the events in the
    10201024        buffer and return the translated stream.
    10211025       
    10221026        :param string: the translated message string
     1027        :param original: the untranslated message string, used as a fallback
     1028                         in case the translated message is unparsable
    10231029        """
    10241030        substream = None
    10251031
    class MessageBuffer(object): 
    10341040                    )
    10351041
    10361042        parts = parse_msg(string)
     1043        if parts is None:
     1044            if original is None:
     1045                raise ValueError("Malformed translated message '%s'" % string)
     1046            parts = parse_msg(original)
     1047            if parts is None:
     1048                raise ValueError("Malformed original message '%s'" % original)
    10371049        parts_counter = {}
    10381050        for order, string in parts:
    10391051            parts_counter.setdefault(order, []).append(None)
    def parse_msg(string, regex=re.compile(r 
    11231135    >>> parse_msg("[1:] Bilder pro Seite anzeigen.")
    11241136    [(1, ''), (0, ' Bilder pro Seite anzeigen.')]
    11251137   
     1138    >>> parse_msg("[1:t][2]t")
     1139
     1140   
    11261141    :param string: the translated message string
    1127     :return: a list of ``(order, string)`` tuples
     1142    :return: a list of ``(order, string)`` tuples or `None` if parsing failed.
    11281143    :rtype: `list`
    11291144    """
    11301145    parts = []
    def parse_msg(string, regex=re.compile(r 
    11461161        if not stack:
    11471162            break
    11481163
     1164    if stack != [0]:
     1165        return None
     1166
    11491167    if string:
    11501168        parts.append((stack[-1], string))
    11511169
  • genshi/filters/tests/i18n.py

    diff -r 924949fd7167 genshi/filters/tests/i18n.py
    a b class MsgDirectiveTestCase(unittest.Test 
    502502          <p>Für <em>Details</em> siehe bitte <a href="help.html">Hilfe</a>.</p>
    503503        </html>""", tmpl.generate().render())
    504504
     505    def test_translate_i18n_msg_multiple_parse_msg_fallback(self):
     506        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"
     507            xmlns:i18n="http://genshi.edgewall.org/i18n">
     508          <p i18n:msg="">
     509            Please see <a href="help.html">Help</a> for <em>details</em>.
     510          </p>
     511        </html>""")
     512        gettext = lambda s: u"Für [2:Details] siehe bitte [1 Hilfe]."
     513        translator = Translator(gettext)
     514        translator.setup(tmpl)
     515        self.assertEquals("""<html>
     516          <p>Please see <a href="help.html">Help</a> for <em>details</em>.</p>
     517        </html>""", tmpl.generate().render())
     518
    505519    def test_extract_i18n_msg_multiple_empty(self):
    506520        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"
    507521            xmlns:i18n="http://genshi.edgewall.org/i18n">
    class ChooseDirectiveTestCase(unittest.T 
    13811395            <p title="Sachen">Da sind <a href="/things" title="Sachen betrachten">3 Sachen</a>.</p>
    13821396        </html>""", tmpl.generate(link="/things", num=3).render(encoding=None))
    13831397
     1398    def test_translate_i18n_choose_as_element_with_attributes_parse_msg_fallback(self):
     1399        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"
     1400            xmlns:i18n="http://genshi.edgewall.org/i18n">
     1401          <i18n:choose numeral="num" params="num">
     1402            <p i18n:singular="" title="Things">
     1403              There is <a href="$link" title="View thing">${num} thing</a>.
     1404            </p>
     1405            <p i18n:plural="" title="Things">
     1406              There are <a href="$link" title="View things">${num} things</a>.
     1407            </p>
     1408          </i18n:choose>
     1409        </html>""")
     1410        translations = DummyTranslations({
     1411            'Things': 'Sachen',
     1412            'View thing': 'Sache betrachten',
     1413            'View things': 'Sachen betrachten',
     1414            ('There is [1:%(num)s thing].', 0): 'Da ist [1 %(num)s Sache].',
     1415            ('There is [1:%(num)s thing].', 1): 'Da sind [1 %(num)s Sachen].'
     1416        })
     1417        translator = Translator(translations)
     1418        translator.setup(tmpl)
     1419        self.assertEqual(u"""<html>
     1420            <p title="Sachen">There is <a href="/things" title="Sache betrachten">1 thing</a>.</p>
     1421        </html>""", tmpl.generate(link="/things", num=1).render(encoding=None))
     1422        self.assertEqual(u"""<html>
     1423            <p title="Sachen">There are <a href="/things" title="Sachen betrachten">3 things</a>.</p>
     1424        </html>""", tmpl.generate(link="/things", num=3).render(encoding=None))
     1425
    13841426    def test_translate_i18n_choose_and_py_strip(self):
    13851427        tmpl = MarkupTemplate("""<html xmlns:py="http://genshi.edgewall.org/"
    13861428            xmlns:i18n="http://genshi.edgewall.org/i18n">