"""
A Template subclass that html-escapes all strings passed from the context,
except when they are of class HTMLEscapedString
"""



# FIXME: Missing: A template loader for this ...

from django.core.template import Template, Lexer, DebugLexer, Parser, DebugParser, VariableNode, DebugVariableNode, StringOrigin
from django.utils.html import escape, linebreaks
from django.conf.settings import DEFAULT_CHARSET, TEMPLATE_DEBUG
from django.core.template.loader import find_template_source


class HTMLTemplate (Template):
    def __init__(self, template_string, origin=None):
        "Compilation stage"
        if TEMPLATE_DEBUG and origin == None:
            origin = StringOrigin(template_string)
            # Could do some crazy stack-frame stuff to record where this string
            # came from...
        self.nodelist = html_compile_string(template_string, origin)

class HTMLParser(Parser):
    def create_variable_node(self, filter_expression):
	return HTMLVariableNode(filter_expression)

class DebugHTMLParser(DebugParser):
    def create_variable_node(self, contents):
        return DebugHTMLVariableNode(contents)

class HTMLVariableNode(VariableNode):
    def encode_output(self, output):
	if isinstance(output, HTMLEscapedString):
	    return output.encode(DEFAULT_CHARSET)
	else:
	    return linebreaks(escape(super(HTMLVariableNode).encode_output(self, output)))

class DebugHTMLVariableNode(DebugVariableNode):
    def encode_output(self, output):
	if isinstance(output, HTMLEscapedString):
	    return output.encode(DEFAULT_CHARSET)
	else:
	    return linebreaks(escape(DebugVariableNode.encode_output(self, output)))

class HTMLEscapedString (unicode):
    """Same as unicode, but HTMLVariableNode does not html-escape instants of
    HTMLEscapedString
    """
    pass

if TEMPLATE_DEBUG:
    lexer_factory = DebugLexer
    parser_factory = DebugHTMLParser
else:
    lexer_factory = Lexer
    parser_factory = HTMLParser

def html_compile_string(template_string, origin):
    "Compiles template_string into NodeList ready for rendering"
    lexer = lexer_factory(template_string, origin)
    parser = parser_factory(lexer.tokenize())
    return parser.parse()

def get_template_from_string(source, origin=None):
    return HTMLTemplate(source, origin)

def get_template(template_name):
    return get_template_from_string(*find_template_source(template_name))


if __name__=='__main__':
    from django.core.template import Context
    TEMPLATE_DEBUG=True
    t = HTMLTemplate(""""
    Dies ist ein Test. 
    {{ s1 }}
    {{ s2 }}
    """)

    c = Context({'s1': u'<b>blabla</b>\n\nboblo&auch',
		 's2': HTMLEscapedString(u'<b>nochwas</b>\n\nblo&amp; test')})
    try:
	print t.render(c)
    except:
	import pdb, sys
	pdb.post_mortem(sys.exc_info()[2])

