From 966517bb9505e847c789e2b64ea934121fb997cd Mon Sep 17 00:00:00 2001
From: Mike Bayer <mike_mp@zzzcomputing.com>
Date: Sun, 26 Nov 2006 04:19:10 +0000
Subject: [PATCH] text tag, adding "inheritable" flag to namespace

---
 examples/bench/basic.py |  2 +-
 lib/mako/codegen.py     |  2 ++
 lib/mako/lexer.py       | 13 +++++++------
 lib/mako/parsetree.py   |  9 +++++++--
 lib/mako/runtime.py     |  2 +-
 test/lexer.py           | 28 +++++++++++++++++++++++++++-
 6 files changed, 45 insertions(+), 11 deletions(-)

diff --git a/examples/bench/basic.py b/examples/bench/basic.py
index bf531ef..e9131e1 100644
--- a/examples/bench/basic.py
+++ b/examples/bench/basic.py
@@ -70,7 +70,7 @@ def mako(dirname, verbose=False):
     def render():
         return template.render(title="Just a test", user="joe", list_items=[u'Number %d' % num for num in range(1,15)])
     if verbose:
-        print render()
+        print template.code, render()
     return render
 mako_inheritance = mako
 
diff --git a/lib/mako/codegen.py b/lib/mako/codegen.py
index 78aa21d..6ce1d9a 100644
--- a/lib/mako/codegen.py
+++ b/lib/mako/codegen.py
@@ -265,6 +265,8 @@ class _GenerateRenderMethod(object):
         self.printer.writeline("return [%s]" % (','.join(export)))
         self.printer.writeline(None)
         self.printer.writeline("%s = runtime.Namespace(%s, context.clean_inheritance_tokens(), templateuri=%s, callables=make_namespace())" % (node.name, repr(node.name), node.parsed_attributes.get('file', 'None')))
+        if eval(node.attributes.get('inheritable', "False")):
+            self.printer.writeline("self.%s = %s" % (node.name, node.name))
         
     def visitDefTag(self, node):
         pass
diff --git a/lib/mako/lexer.py b/lib/mako/lexer.py
index 0b1d2b7..4b59c26 100644
--- a/lib/mako/lexer.py
+++ b/lib/mako/lexer.py
@@ -103,9 +103,7 @@ class Lexer(object):
             
             (\w+)   # keyword
             
-            \s+     # some space
-            
-            ((?:\w+|=|".*?"|'.*?')*)  # attrname, = sign, string expression
+            ((?:\s+\w+|=|".*?"|'.*?')*)  # attrname, = sign, string expression
             
             \s*     # more whitespace
             
@@ -126,14 +124,17 @@ class Lexer(object):
             self.append_node(parsetree.Tag, keyword, attributes)
             if isend:
                 self.tag.pop()
+            else:
+                if keyword == 'text':
+                    match = self.match(r'.*?(?=\</%text>)',  re.S)
+                    if not match:
+                        raise exceptions.SyntaxException("Unclosed tag: <%%%s>" % self.tag[-1].keyword, self.matched_lineno, self.matched_charpos)
+                    return self.match_tag_end()
             return True
         else: 
             return False
         
     def match_tag_end(self):
-#        if not len(self.tag):
-#            return False
-#        match = self.match(r'\</%\s*(.+?)' + self.tag[-1].keyword + '\s*>')
         match = self.match(r'\</%\s*(.+?)\s*>')
         if match:
             if not len(self.tag):
diff --git a/lib/mako/parsetree.py b/lib/mako/parsetree.py
index 4ee3cba..45e696d 100644
--- a/lib/mako/parsetree.py
+++ b/lib/mako/parsetree.py
@@ -222,11 +222,16 @@ class IncludeTag(Tag):
 class NamespaceTag(Tag):
     __keyword__ = 'namespace'
     def __init__(self, keyword, attributes, **kwargs):
-        super(NamespaceTag, self).__init__(keyword, attributes, ('file',), ('name',), ('name',), **kwargs)
+        super(NamespaceTag, self).__init__(keyword, attributes, ('file',), ('name','inheritable'), ('name',), **kwargs)
         self.name = attributes['name']
     def declared_identifiers(self):
         return [self.name]
-        
+
+class TextTag(Tag):
+    __keyword__ = 'text'
+    def __init__(self, keyword, attributes, **kwargs):
+        super(TextTag, self).__init__(keyword, attributes, (), (), (), **kwargs)
+            
 class DefTag(Tag):
     __keyword__ = 'def'
     def __init__(self, keyword, attributes, **kwargs):
diff --git a/lib/mako/runtime.py b/lib/mako/runtime.py
index 1a81c09..1941ba6 100644
--- a/lib/mako/runtime.py
+++ b/lib/mako/runtime.py
@@ -93,7 +93,7 @@ class Namespace(object):
         if callables is not None:
             self.callables = dict([(c.func_name, c) for c in callables])
         else:
-            self.callables = {}
+            self.callables = None
         if populate_self and self.template is not None:
             (lclcallable, self.context) = _populate_self_namespace(context, self.template, self_ns=self)
         
diff --git a/test/lexer.py b/test/lexer.py
index 8ca478b..c673332 100644
--- a/test/lexer.py
+++ b/test/lexer.py
@@ -71,6 +71,32 @@ class LexerTest(unittest.TestCase):
         except exceptions.CompileException, e:
             assert str(e) == "No such tag: 'lala' at line: 2 char: 13"
     
+    def test_text_tag(self):
+        template = """
+        # comment
+        % if foo:
+            hi
+        % endif
+        <%text>
+            # more code
+            
+            % more code
+            <%illegal compionent>/></>
+            <%def name="laal">def</%def>
+            
+            
+        </%text>
+
+        <%def name="foo">this is foo</%def>
+        
+        % if bar:
+            code
+        % endif
+        """
+        node = Lexer(template).parse()
+        print repr(node)
+        assert repr(node) == """TemplateNode({}, [Comment('comment', (1, 1)), ControlLine('if', 'if foo:', False, (3, 1)), Text('            hi\n', (4, 1)), ControlLine('if', 'endif', True, (5, 1)), Text('        ', (6, 1)), TextTag('text', {}, (6, 9), []), Text('\n\n        ', (14, 17)), DefTag('def', {'name': 'foo'}, (16, 9), ["Text('this is foo', (16, 26))"]), Text('\n', (16, 44)), ControlLine('if', 'if bar:', False, (17, 1)), Text('            code\n', (19, 1)), ControlLine('if', 'endif', True, (20, 1)), Text('        ', (21, 1))])"""
+        
     def test_def_syntax(self):
         template = """
         <%def lala>
@@ -162,7 +188,7 @@ class LexerTest(unittest.TestCase):
         ${hi()}
 """
         nodes = Lexer(template).parse()
-        assert repr(nodes) == r"""TemplateNode({}, [Text('\n        this is some ', (1, 1)), Expression('text', [], (2, 22)), Text(' and this is ', (2, 29)), Expression('textwith ', ['escapes', 'moreescapes'], (2, 42)), Text('\n        ', (2, 76)), DefTag('def', {'name': 'hi'}, (3, 9), ["Text('\\n            give me ', (3, 31))", "Expression('foo()', [], (4, 21))", "Text(' and ', (4, 29))", "Expression('bar()', [], (4, 34))", "Text('\\n        ', (4, 42))"]), Text('\n        ', (5, 22)), Expression('hi()', [], (6, 9)), Text('\n', (6, 16))])"""
+        assert repr(nodes) == r"""TemplateNode({}, [Text('\n        this is some ', (1, 1)), Expression('text', [], (2, 22)), Text(' and this is ', (2, 29)), Expression('textwith ', ['escapes', 'moreescapes'], (2, 42)), Text('\n        ', (2, 76)), DefTag('def', {'name': 'hi'}, (3, 9), ["Text('\\n            give me ', (3, 25))", "Expression('foo()', [], (4, 21))", "Text(' and ', (4, 29))", "Expression('bar()', [], (4, 34))", "Text('\\n        ', (4, 42))"]), Text('\n        ', (5, 16)), Expression('hi()', [], (6, 9)), Text('\n', (6, 16))])"""
 
     def test_control_lines(self):
         template = """
-- 
GitLab