Permalink
Browse files

Bug#662846 Adding extract command via tower. Added translate-toolkit,…

… shoehorn_l10n.
  • Loading branch information...
ozten committed Jun 8, 2011
1 parent 9c993d4 commit b28132883d2bab43ca8f2033de9e0a1a94506e13
View
No changes.
No changes.
@@ -0,0 +1,19 @@
"""Monkeypatch to normalize blocktrans msgids to work with tower."""
from tower import strip_whitespace
from django.templatetags import i18n
OldBlockTranslateNode = i18n.BlockTranslateNode
class ShoehornedBlockTranslateNode(OldBlockTranslateNode):
def render_token_list(self, tokens):
"""Strip whitespace from msgid before letting gettext touch it."""
rendered = super(ShoehornedBlockTranslateNode, self).render_token_list(
tokens)
return strip_whitespace(rendered[0]), rendered[1]
def monkeypatch():
i18n.BlockTranslateNode = ShoehornedBlockTranslateNode
@@ -0,0 +1,101 @@
"""Modified Django templatize utility to translate Django L10n into something almost usable by Jinja2."""
from cStringIO import StringIO
import re
dot_re = re.compile(r'\S')
def blankout(src, char):
"""
Changes every non-whitespace character to the given char.
Used in the templatize function.
"""
return dot_re.sub(char, src)
inline_re = re.compile(r"""^\s*trans\s+((?:".*?")|(?:'.*?'))\s*""")
block_re = re.compile(r"""^\s*blocktrans(?:\s+|$)""")
endblock_re = re.compile(r"""^\s*endblocktrans$""")
plural_re = re.compile(r"""^\s*plural$""")
constant_re = re.compile(r"""_\(((?:".*?")|(?:'.*?'))\)""")
def templatize(src):
"""
Turns a Django template into something that is understood by xgettext. It
does so by translating the Django translation tags into standard gettext
function invocations.
"""
from django.template import Lexer, TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK
out = StringIO()
intrans = False
inplural = False
singular = []
plural = []
for t in Lexer(src, None).tokenize():
if intrans:
if t.token_type == TOKEN_BLOCK:
endbmatch = endblock_re.match(t.contents)
pluralmatch = plural_re.match(t.contents)
if endbmatch:
if inplural:
out.write(' {{ ngettext(%r,%r,count) }} ' % (''.join(singular), ''.join(plural)))
for part in singular:
out.write(blankout(part, 'S'))
for part in plural:
out.write(blankout(part, 'P'))
else:
out.write(' {{ gettext(%r) }} ' % ''.join(singular))
for part in singular:
out.write(blankout(part, 'S'))
intrans = False
inplural = False
singular = []
plural = []
elif pluralmatch:
inplural = True
else:
raise SyntaxError("Translation blocks must not include other block tags: %s" % t.contents)
elif t.token_type == TOKEN_VAR:
if inplural:
plural.append('%%(%s)s' % t.contents)
else:
singular.append('%%(%s)s' % t.contents)
elif t.token_type == TOKEN_TEXT:
if inplural:
plural.append(t.contents)
else:
singular.append(t.contents)
else:
if t.token_type == TOKEN_BLOCK:
imatch = inline_re.match(t.contents)
bmatch = block_re.match(t.contents)
cmatches = constant_re.findall(t.contents)
if imatch:
g = imatch.group(1)
if g[0] == '"': g = g.strip('"')
elif g[0] == "'": g = g.strip("'")
out.write(' {{ gettext(%r) }} ' % g)
elif bmatch:
for fmatch in constant_re.findall(t.contents):
out.write(' {{ _(%s) }} ' % fmatch)
intrans = True
inplural = False
singular = []
plural = []
elif cmatches:
for cmatch in cmatches:
out.write(' {{ _(%s) }} ' % cmatch)
else:
out.write(blankout(t.contents, 'B'))
elif t.token_type == TOKEN_VAR:
parts = t.contents.split('|')
cmatch = constant_re.match(parts[0])
if cmatch:
out.write(' {{ _(%s) }} ' % cmatch.group(1))
for p in parts[1:]:
if p.find(':_(') >= 0:
out.write(' %s ' % p.split(':',1)[1])
else:
out.write(blankout(p, 'F'))
else:
out.write(blankout(t.contents, 'X'))
return out.getvalue()
@@ -0,0 +1,12 @@
"""Teach tower L10n library to hopefully extract from django templates."""
from StringIO import StringIO
from tower.management.commands.extract import (extract_tower_template,
tweak_message)
from lib.shoehorn_l10n.templatize import templatize
def extract_django_template(fileobj, keywords, comment_tags, options):
src = fileobj.read()
templatized = StringIO(templatize(src))
return extract_tower_template(templatized, keywords, comment_tags, options)
View
@@ -1 +1,4 @@
-r prod.txt
-r prod.txt
# L10n
translate-toolkit==1.6.0
View
@@ -2,6 +2,8 @@
# Django settings for ff4 project.
ROOT = os.path.dirname(os.path.abspath(__file__))
PROJECT_PATH = os.path.realpath(os.path.dirname(__file__))
PROJECT_DIR = os.path.realpath(os.path.dirname(__file__))
@@ -44,6 +46,35 @@
DBGETTEXT_PATH = PROJECT_PATH + '/locale'
# Tells the extract script what files to look for l10n in and what function
# handles the extraction. The Tower library expects this.
DOMAIN_METHODS = {
# We usually use "messages" as text domain. "django" is required by Django L10n.
'django': [
# Normally, apps would be in apps/ and templates in templates/.
# Not so here.
('webifyme/**.py',
'tower.management.commands.extract.extract_tower_python'),
('templates/**.html',
'lib.shoehorn_l10n.tower_blocktrans.extract_django_template'),
('templates_orig/**.html',
'lib.shoehorn_l10n.tower_blocktrans.extract_django_template'),
],
}
TOWER_KEYWORDS = {
#'_lazy': None,
}
# The POT headers take care of the encoding.
TOWER_ADD_HEADERS = True
# Fake Jinja2 config for tower. Don't ask. (If you must, bug 647352).
def JINJA_CONFIG():
return {'extensions': []}
# tower-ize django's blocktrans
import lib.shoehorn_l10n.templatetag
lib.shoehorn_l10n.templatetag.monkeypatch()
# Absolute path to the directory that holds media.
# Example: "/home/media/media.lawrence.com/"
MEDIA_ROOT = PROJECT_PATH + '/../static/'
@@ -91,8 +122,8 @@
def JINJA_CONFIG():
import jinja2
config = {'extensions': ['jinja2.ext.loopcontrols',
'jinja2.ext.with_', 'caching.ext.cache'],
config = {'extensions': ['tower.template.i18n', 'jinja2.ext.loopcontrols',
'jinja2.ext.with_'],
'finalize': lambda x: x if x is not None else ''}
return config
@@ -120,6 +151,7 @@ def JINJA_CONFIG():
'django.contrib.admindocs',
'ff4.things',
'south',
'tower',
)
FIXTURE_DIRS = (

0 comments on commit b281328

Please sign in to comment.