1 from django
.template
import Lexer
, Parser
, tag_re
, NodeList
, VariableNode
, TemplateSyntaxError
2 from django
.utils
.encoding
import force_unicode
3 from django
.utils
.html
import escape
4 from django
.utils
.safestring
import SafeData
, EscapeData
6 class DebugLexer(Lexer
):
7 def __init__(self
, template_string
, origin
):
8 super(DebugLexer
, self
).__init
__(template_string
, origin
)
11 "Return a list of tokens from a given template_string"
13 for match
in tag_re
.finditer(self
.template_string
):
14 start
, end
= match
.span()
16 result
.append(self
.create_token(self
.template_string
[upto
:start
], (upto
, start
), False))
18 result
.append(self
.create_token(self
.template_string
[start
:end
], (start
, end
), True))
20 last_bit
= self
.template_string
[upto
:]
22 result
.append(self
.create_token(last_bit
, (upto
, upto
+ len(last_bit
)), False))
25 def create_token(self
, token_string
, source
, in_tag
):
26 token
= super(DebugLexer
, self
).create_token(token_string
, in_tag
)
27 token
.source
= self
.origin
, source
30 class DebugParser(Parser
):
31 def __init__(self
, lexer
):
32 super(DebugParser
, self
).__init
__(lexer
)
33 self
.command_stack
= []
35 def enter_command(self
, command
, token
):
36 self
.command_stack
.append( (command
, token
.source
) )
38 def exit_command(self
):
39 self
.command_stack
.pop()
41 def error(self
, token
, msg
):
42 return self
.source_error(token
.source
, msg
)
44 def source_error(self
, source
,msg
):
45 e
= TemplateSyntaxError(msg
)
49 def create_nodelist(self
):
50 return DebugNodeList()
52 def create_variable_node(self
, contents
):
53 return DebugVariableNode(contents
)
55 def extend_nodelist(self
, nodelist
, node
, token
):
56 node
.source
= token
.source
57 super(DebugParser
, self
).extend_nodelist(nodelist
, node
, token
)
59 def unclosed_block_tag(self
, parse_until
):
60 command
, source
= self
.command_stack
.pop()
61 msg
= "Unclosed tag '%s'. Looking for one of: %s " % (command
, ', '.join(parse_until
))
62 raise self
.source_error(source
, msg
)
64 def compile_function_error(self
, token
, e
):
65 if not hasattr(e
, 'source'):
66 e
.source
= token
.source
68 class DebugNodeList(NodeList
):
69 def render_node(self
, node
, context
):
71 result
= node
.render(context
)
72 except TemplateSyntaxError
, e
:
73 if not hasattr(e
, 'source'):
74 e
.source
= node
.source
77 from sys
import exc_info
78 wrapped
= TemplateSyntaxError(u
'Caught an exception while rendering: %s' % force_unicode(e
, errors
='replace'))
79 wrapped
.source
= node
.source
80 wrapped
.exc_info
= exc_info()
84 class DebugVariableNode(VariableNode
):
85 def render(self
, context
):
87 output
= force_unicode(self
.filter_expression
.resolve(context
))
88 except TemplateSyntaxError
, e
:
89 if not hasattr(e
, 'source'):
90 e
.source
= self
.source
92 except UnicodeDecodeError:
94 if (context
.autoescape
and not isinstance(output
, SafeData
)) or isinstance(output
, EscapeData
):