1from django.conf import settings
2from django.utils.encoding import force_text as to_text
3from django.utils.translation import template
4
5from pypugjs import Compiler as _Compiler, register_filter
6from pypugjs.exceptions import CurrentlyNotSupported
7from pypugjs.utils import process
8
9
10class Compiler(_Compiler):
11    auto_close_code = [
12        'autoescape',
13        'cache',
14        'comment',
15        'compress',
16        'block',
17        'blocktrans',
18        'filter',
19        'for',
20        'if',
21        'ifchanged',
22        'ifequal',
23        'ifnotequal',
24        'localize',
25        'spaceless',
26        'trans',
27        'with',
28        'verbatim',
29    ]
30    useRuntime = True
31
32    def __init__(self, node, **options):
33        if settings.configured:
34            options.update(getattr(settings, 'PYPUGJS', {}))
35        super(Compiler, self).__init__(node, **options)
36
37    def visitCodeBlock(self, block):
38        self.buffer('{%% block %s %%}' % block.name)
39        if block.mode == 'append':
40            self.buffer('{{block.super}}')
41        self.visitBlock(block)
42        if block.mode == 'prepend':
43            self.buffer('{{block.super}}')
44        self.buffer('{% endblock %}')
45
46    def visitAssignment(self, assignment):
47        self.buffer('{%% __pypugjs_set %s = %s %%}' % (assignment.name, assignment.val))
48
49    def visitMixin(self, mixin):
50        self.mixing += 1
51        if not mixin.call:
52            self.buffer('{%% __pypugjs_kwacro %s %s %%}' % (mixin.name, mixin.args))
53            self.visitBlock(mixin.block)
54            self.buffer('{% end__pypugjs_kwacro %}')
55        elif mixin.block:
56            raise CurrentlyNotSupported("The mixin blocks are not supported yet.")
57        else:
58            self.buffer('{%% __pypugjs_usekwacro %s %s %%}' % (mixin.name, mixin.args))
59        self.mixing -= 1
60
61    def visitCode(self, code):
62        if code.buffer:
63            val = code.val.lstrip()
64            val = self.var_processor(val)
65            self.buf.append('{{%s%s}}' % (val, '|force_escape' if code.escape else ''))
66        else:
67            self.buf.append('{%% %s %%}' % code.val)
68
69        if code.block:
70            self.visit(code.block)
71
72            if not code.buffer:
73                code_tag = code.val.strip().split(' ', 1)[0]
74                if code_tag in self.auto_close_code:
75                    self.buf.append('{%% end%s %%}' % code_tag)
76
77    def attributes(self, attrs):
78        return "{%% __pypugjs_attrs %s %%}" % attrs
79
80
81def decorate_templatize(func):
82    def templatize(src, origin=None, charset=None):
83        src = to_text(src, charset or settings.FILE_CHARSET)
84        if origin.endswith(".pug"):
85            html = process(src, compiler=Compiler)
86        else:
87            html = src
88        return func(html, origin)
89
90    return templatize
91
92
93# fix translation for pug templates
94def enable_pug_translations():
95    template.templatize = decorate_templatize(template.templatize)
96
97
98try:
99    from django.contrib.markup.templatetags.markup import markdown
100
101    @register_filter('markdown')
102    def markdown_filter(x, y):
103        return markdown(x)
104
105
106except ImportError:
107    pass
108