annotate piecrust/templating/jinja/extensions.py @ 855:448710d84121

refactor: Get the taxonomy support back to a functional state. There's now a taxonomy content source that wraps another normal content source like a blog posts' source. It works in tandem with a taxonomy content pipeline that will do the heavy lifting of figuring out what kind of terms exist and need to be baked.
author Ludovic Chabant <ludovic@chabant.com>
date Tue, 06 Jun 2017 00:26:21 -0700
parents 2c7e57d80bba
children 58e28ba02fb7
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
851
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
1 from jinja2.ext import Extension, Markup
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
2 from jinja2.lexer import Token, describe_token
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
3 from jinja2.nodes import CallBlock, Const
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
4 from compressinja.html import HtmlCompressor, StreamProcessContext
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
5 from piecrust.rendering import format_text
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
6
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
7
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
8 class PieCrustFormatExtension(Extension):
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
9 tags = set(['pcformat'])
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
10
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
11 def __init__(self, environment):
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
12 super(PieCrustFormatExtension, self).__init__(environment)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
13
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
14 def parse(self, parser):
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
15 lineno = next(parser.stream).lineno
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
16 args = [parser.parse_expression()]
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
17 body = parser.parse_statements(['name:endpcformat'], drop_needle=True)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
18 return CallBlock(self.call_method('_format', args),
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
19 [], [], body).set_lineno(lineno)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
20
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
21 def _format(self, format_name, caller=None):
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
22 body = caller()
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
23 text = format_text(self.environment.app,
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
24 format_name,
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
25 Markup(body.rstrip()).unescape(),
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
26 exact_format=True)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
27 return text
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
28
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
29
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
30 class PieCrustHighlightExtension(Extension):
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
31 tags = set(['highlight', 'geshi'])
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
32
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
33 def __init__(self, environment):
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
34 super(PieCrustHighlightExtension, self).__init__(environment)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
35
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
36 def parse(self, parser):
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
37 lineno = next(parser.stream).lineno
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
38
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
39 # Extract the language name.
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
40 args = [parser.parse_expression()]
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
41
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
42 # Extract optional arguments.
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
43 kwarg_names = {'line_numbers': 0, 'use_classes': 0, 'class': 1,
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
44 'id': 1}
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
45 kwargs = {}
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
46 while not parser.stream.current.test('block_end'):
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
47 name = parser.stream.expect('name')
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
48 if name.value not in kwarg_names:
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
49 raise Exception("'%s' is not a valid argument for the code "
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
50 "highlighting tag." % name.value)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
51 if kwarg_names[name.value] == 0:
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
52 kwargs[name.value] = Const(True)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
53 elif parser.stream.skip_if('assign'):
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
54 kwargs[name.value] = parser.parse_expression()
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
55
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
56 # body of the block
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
57 body = parser.parse_statements(['name:endhighlight', 'name:endgeshi'],
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
58 drop_needle=True)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
59
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
60 return CallBlock(self.call_method('_highlight', args, kwargs),
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
61 [], [], body).set_lineno(lineno)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
62
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
63 def _highlight(self, lang, line_numbers=False, use_classes=False,
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
64 css_class=None, css_id=None, caller=None):
855
448710d84121 refactor: Get the taxonomy support back to a functional state.
Ludovic Chabant <ludovic@chabant.com>
parents: 851
diff changeset
65 from pygments import highlight
448710d84121 refactor: Get the taxonomy support back to a functional state.
Ludovic Chabant <ludovic@chabant.com>
parents: 851
diff changeset
66 from pygments.formatters import HtmlFormatter
448710d84121 refactor: Get the taxonomy support back to a functional state.
Ludovic Chabant <ludovic@chabant.com>
parents: 851
diff changeset
67 from pygments.lexers import get_lexer_by_name, guess_lexer
448710d84121 refactor: Get the taxonomy support back to a functional state.
Ludovic Chabant <ludovic@chabant.com>
parents: 851
diff changeset
68
851
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
69 # Try to be mostly compatible with Jinja2-highlight's settings.
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
70 body = caller()
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
71
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
72 if lang is None:
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
73 lexer = guess_lexer(body)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
74 else:
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
75 lexer = get_lexer_by_name(lang, stripall=False)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
76
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
77 if css_class is None:
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
78 try:
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
79 css_class = self.environment.jinja2_highlight_cssclass
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
80 except AttributeError:
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
81 pass
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
82
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
83 if css_class is not None:
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
84 formatter = HtmlFormatter(cssclass=css_class,
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
85 linenos=line_numbers)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
86 else:
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
87 formatter = HtmlFormatter(linenos=line_numbers)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
88
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
89 code = highlight(Markup(body.rstrip()).unescape(), lexer, formatter)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
90 return code
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
91
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
92
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
93 def get_highlight_css(style_name='default', class_name='.highlight'):
855
448710d84121 refactor: Get the taxonomy support back to a functional state.
Ludovic Chabant <ludovic@chabant.com>
parents: 851
diff changeset
94 from pygments.formatters import HtmlFormatter
851
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
95 return HtmlFormatter(style=style_name).get_style_defs(class_name)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
96
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
97
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
98 class PieCrustCacheExtension(Extension):
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
99 tags = set(['pccache', 'cache'])
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
100
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
101 def __init__(self, environment):
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
102 super(PieCrustCacheExtension, self).__init__(environment)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
103 environment.extend(
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
104 piecrust_cache_prefix='',
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
105 piecrust_cache={}
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
106 )
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
107
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
108 def parse(self, parser):
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
109 # the first token is the token that started the tag. In our case
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
110 # we only listen to ``'pccache'`` so this will be a name token with
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
111 # `pccache` as value. We get the line number so that we can give
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
112 # that line number to the nodes we create by hand.
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
113 lineno = next(parser.stream).lineno
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
114
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
115 # now we parse a single expression that is used as cache key.
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
116 args = [parser.parse_expression()]
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
117
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
118 # now we parse the body of the cache block up to `endpccache` and
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
119 # drop the needle (which would always be `endpccache` in that case)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
120 body = parser.parse_statements(['name:endpccache', 'name:endcache'],
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
121 drop_needle=True)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
122
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
123 # now return a `CallBlock` node that calls our _cache_support
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
124 # helper method on this extension.
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
125 return CallBlock(self.call_method('_cache_support', args),
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
126 [], [], body).set_lineno(lineno)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
127
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
128 def _cache_support(self, name, caller):
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
129 key = self.environment.piecrust_cache_prefix + name
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
130
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
131 exc_stack = self.environment.app.env.exec_info_stack
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
132 render_ctx = exc_stack.current_page_info.render_ctx
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
133 rdr_pass = render_ctx.current_pass_info
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
134
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
135 # try to load the block from the cache
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
136 # if there is no fragment in the cache, render it and store
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
137 # it in the cache.
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
138 pair = self.environment.piecrust_cache.get(key)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
139 if pair is not None:
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
140 rdr_pass.used_source_names.update(pair[1])
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
141 return pair[0]
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
142
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
143 pair = self.environment.piecrust_cache.get(key)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
144 if pair is not None:
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
145 rdr_pass.used_source_names.update(pair[1])
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
146 return pair[0]
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
147
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
148 prev_used = rdr_pass.used_source_names.copy()
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
149 rv = caller()
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
150 after_used = rdr_pass.used_source_names.copy()
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
151 used_delta = after_used.difference(prev_used)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
152 self.environment.piecrust_cache[key] = (rv, used_delta)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
153 return rv
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
154
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
155
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
156 class PieCrustSpacelessExtension(HtmlCompressor):
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
157 """ A re-implementation of `SelectiveHtmlCompressor` so that we can
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
158 both use `strip` or `spaceless` in templates.
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
159 """
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
160 def filter_stream(self, stream):
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
161 ctx = StreamProcessContext(stream)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
162 strip_depth = 0
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
163 while 1:
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
164 if stream.current.type == 'block_begin':
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
165 for tk in ['strip', 'spaceless']:
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
166 change = self._processToken(ctx, stream, tk)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
167 if change != 0:
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
168 strip_depth += change
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
169 if strip_depth < 0:
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
170 ctx.fail('Unexpected tag end%s' % tk)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
171 break
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
172 if strip_depth > 0 and stream.current.type == 'data':
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
173 ctx.token = stream.current
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
174 value = self.normalize(ctx)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
175 yield Token(stream.current.lineno, 'data', value)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
176 else:
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
177 yield stream.current
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
178 next(stream)
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
179
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
180 def _processToken(self, ctx, stream, test_token):
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
181 change = 0
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
182 if (stream.look().test('name:%s' % test_token) or
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
183 stream.look().test('name:end%s' % test_token)):
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
184 stream.skip()
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
185 if stream.current.value == test_token:
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
186 change = 1
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
187 else:
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
188 change = -1
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
189 stream.skip()
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
190 if stream.current.type != 'block_end':
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
191 ctx.fail('expected end of block, got %s' %
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
192 describe_token(stream.current))
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
193 stream.skip()
2c7e57d80bba optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff changeset
194 return change