commit 762fd1acd1c752d31bdfb7ba6c258108e07495b8
Author: Claude Paroz <claude@2xlibre.net>
Date:   Sun Nov 14 00:02:28 2010 +0100

    Allow translator comments to be extracted from templates

diff --git a/django/template/__init__.py b/django/template/__init__.py
index 7440358..e1fdb7e 100644
--- a/django/template/__init__.py
+++ b/django/template/__init__.py
@@ -82,6 +82,7 @@ VARIABLE_TAG_START = '{{'
 VARIABLE_TAG_END = '}}'
 COMMENT_TAG_START = '{#'
 COMMENT_TAG_END = '#}'
+TRANSLATOR_COMMENT_MARK = 'L10n'
 SINGLE_BRACE_START = '{'
 SINGLE_BRACE_END = '}'
 
@@ -237,7 +238,10 @@ class Lexer(object):
             elif token_string.startswith(BLOCK_TAG_START):
                 token = Token(TOKEN_BLOCK, token_string[len(BLOCK_TAG_START):-len(BLOCK_TAG_END)].strip())
             elif token_string.startswith(COMMENT_TAG_START):
-                token = Token(TOKEN_COMMENT, '')
+                content = ''
+                if token_string.find(TRANSLATOR_COMMENT_MARK):
+                    content = token_string[len(COMMENT_TAG_START):-len(COMMENT_TAG_END)].strip()
+                token = Token(TOKEN_COMMENT, content)
         else:
             token = Token(TOKEN_TEXT, token_string)
         return token
diff --git a/django/utils/translation/trans_real.py b/django/utils/translation/trans_real.py
index 827337c..832acc7 100644
--- a/django/utils/translation/trans_real.py
+++ b/django/utils/translation/trans_real.py
@@ -427,14 +427,23 @@ def templatize(src):
     does so by translating the Django translation tags into standard gettext
     function invocations.
     """
-    from django.template import Lexer, TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK
+    from django.template import Lexer, TOKEN_TEXT, TOKEN_VAR, TOKEN_BLOCK, TOKEN_COMMENT
     out = StringIO()
     intrans = False
     inplural = False
     singular = []
     plural = []
+    incomment = False
+    comment = []
     for t in Lexer(src, None).tokenize():
-        if intrans:
+        if incomment:
+            if t.token_type == TOKEN_BLOCK and t.contents == 'endcomment':
+                out.write(' # %s' % ''.join(comment))
+                incomment = False
+                comment = []
+            else:
+                comment.append(t.contents)
+        elif intrans:
             if t.token_type == TOKEN_BLOCK:
                 endbmatch = endblock_re.match(t.contents)
                 pluralmatch = plural_re.match(t.contents)
@@ -488,6 +497,8 @@ def templatize(src):
                 elif cmatches:
                     for cmatch in cmatches:
                         out.write(' _(%s) ' % cmatch)
+                elif t.contents == 'comment':
+                    incomment = True
                 else:
                     out.write(blankout(t.contents, 'B'))
             elif t.token_type == TOKEN_VAR:
@@ -500,6 +511,8 @@ def templatize(src):
                         out.write(' %s ' % p.split(':',1)[1])
                     else:
                         out.write(blankout(p, 'F'))
+            elif t.token_type == TOKEN_COMMENT:
+                out.write(' # %s' % t.contents)
             else:
                 out.write(blankout(t.contents, 'X'))
     return out.getvalue()
diff --git a/tests/regressiontests/i18n/commands/extraction.py b/tests/regressiontests/i18n/commands/extraction.py
index 6695e9b..dfdd7c2 100644
--- a/tests/regressiontests/i18n/commands/extraction.py
+++ b/tests/regressiontests/i18n/commands/extraction.py
@@ -47,6 +47,9 @@ class BasicExtractorTests(ExtractorTests):
         po_contents = open(self.PO_FILE, 'r').read()
         self.assert_('#. L10n: This comment should be extracted' in po_contents)
         self.assert_('This comment should not be extracted' not in po_contents)
+        # Comments in templates
+        self.assert_('#. L10n: Django template comment for translators' in po_contents)
+        self.assert_('#. L10n: Django comment block for translators' in po_contents)
 
     def test_templatize(self):
         os.chdir(self.test_dir)
diff --git a/tests/regressiontests/i18n/commands/templates/test.html b/tests/regressiontests/i18n/commands/templates/test.html
index e1c3eee..ca2f952 100644
--- a/tests/regressiontests/i18n/commands/templates/test.html
+++ b/tests/regressiontests/i18n/commands/templates/test.html
@@ -1,5 +1,8 @@
 {% load i18n %}
+{% comment %} L10n: Django comment block for translators {% endcomment %}
 {% trans "This literal should be included." %}
 {% trans "This literal should also be included wrapped or not wrapped depending on the use of the --no-wrap option." %}
-{% blocktrans %}I think that 100% is more that 50% of anything.{% endblocktrans %}
-{% blocktrans with 'txt' as obj %}I think that 100% is more that 50% of {{ obj }}.{% endblocktrans %}
\ No newline at end of file
+
+{# L10n: Django template comment for translators #}
+<p>{% blocktrans %}I think that 100% is more that 50% of anything.{% endblocktrans %}</p>
+{% blocktrans with 'txt' as obj %}I think that 100% is more that 50% of {{ obj }}.{% endblocktrans %}
