[PATCH 1 of 1 STABLE] i18n: add the tool to check Mercurial specific translation problems in *.po
Martin Geisler
martin at geisler.net
Fri Nov 29 02:35:56 CST 2013
FUJIWARA Katsunori <foozy at lares.dti.ne.jp> writes:
> # HG changeset patch
> # User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
> # Date 1385560052 -32400
> # Wed Nov 27 22:47:32 2013 +0900
> # Branch stable
> # Node ID e55c09427e9ada3e218ee8cba0b598e35f293183
> # Parent 2ca325ea57fa13909e28cc2caeae3c73e60693f8
> i18n: add the tool to check Mercurial specific translation problems in *.po
>
> Existing tool like "msgfmt --check" can check typical translation
> problems (missing "%s" in msgstr, for example), but can't check
> Mercurial specific ones.
>
> For example, "msgfmt --check" can't check whether the translated
> string given to "ui.promptchoice()" is correct or not, even though
> problems like below cause run-time error or unexpected behavior:
>
> - less or more choices than msgid,
> - choices without '&', or
> - choices with '&' followed by none
>
> This patch adds the tool to check Mercurial specific translation
> problems in *.po files.
>
> diff --git a/i18n/check-translation.py b/i18n/check-translation.py
> new file mode 100644
> --- /dev/null
> +++ b/i18n/check-translation.py
> @@ -0,0 +1,148 @@
> +#!/usr/bin/env python
> +#
> +# check-translation.py - check Mercurial specific translation problems
> +
> +import polib
> +import re
> +
> +checkers = []
> +
> +def checker(level, msgidpat):
> + def decorator(func):
> + if msgidpat:
> + match = re.compile(msgidpat).search
> + else:
> + match = lambda msgid: True
> + checkers.append((func, level))
> + func.match = match
> + return func
> + return decorator
> +
> +def match(checker, pe):
> + """Examine whether POEntry "pe" is target of specified checker or not
> + """
> + if not checker.match(pe.msgid):
> + return
> + # examine suppression by translator comment
> + nochecker = 'no-%s-check' % checker.__name__
> + for tc in pe.tcomment.split():
> + if nochecker == tc:
> + return
> + return True
> +
> +####################
> +
> +def fatalchecker(msgidpat=None):
> + return checker('fatal', msgidpat)
> +
> + at fatalchecker(r'\$\$')
> +def promptchoice(pe):
> + """Check translation of the string given to "ui.promptchoice()"
> +
> + >>> pe = polib.POEntry(
> + ... msgid ='prompt$$missing &sep$$missing &$$followed by &none',
> + ... msgstr='prompt missing &sep$$missing amp$$followed by none&')
> + >>> match(promptchoice, pe)
> + True
> + >>> for e in promptchoice(pe): print e
> + number of choices differs between msgid and msgstr
> + msgstr has invalid choice missing '&'
> + msgstr has invalid '&' followed by none
> + """
> + idchoices = [c.rstrip(' ') for c in pe.msgid.split('$$')[1:]]
> + strchoices = [c.rstrip(' ') for c in pe.msgstr.split('$$')[1:]]
Super idea with such a tool!
My only comment is that you might want to reuse the code in ui.py that
does the splitting, stripping, and slicing. However, after looking it
up, I see that this code is burried inside promptchoice. I don't know if
refactoring this is worth the effort.
--
Martin Geisler
More information about the Mercurial-devel
mailing list