Mercurial > piecrust2
annotate piecrust/templating/jinja/extensions.py @ 1188:a7c43131d871
bake: Fix file write flushing problem with Python 3.8+
Writing the cache files fails in Python 3.8 because it looks like flushing
behaviour has changed. We need to explicitly flush. And even then, in very
rare occurrences, it looks like it can still run into racing conditions,
so we do a very hacky and ugly "retry" loop when fetching cached data :(
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Tue, 15 Jun 2021 22:36:23 -0700 |
parents | 1857dbd4580f |
children |
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) |
908
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
18 return CallBlock(self.call_method('_formatTimed', args), |
851
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 |
908
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
21 def _formatTimed(self, format_name, caller=None): |
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
22 with self.environment.app.env.stats.timerScope( |
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
23 'JinjaTemplateEngine_extensions'): |
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
24 return self._format(format_name, caller) |
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
25 |
851
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
26 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
|
27 body = caller() |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
28 text = format_text(self.environment.app, |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
29 format_name, |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
30 Markup(body.rstrip()).unescape(), |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
31 exact_format=True) |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
32 return text |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
33 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
34 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
35 class PieCrustHighlightExtension(Extension): |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
36 tags = set(['highlight', 'geshi']) |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
37 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
38 def __init__(self, environment): |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
39 super(PieCrustHighlightExtension, self).__init__(environment) |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
40 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
41 def parse(self, parser): |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
42 lineno = next(parser.stream).lineno |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
43 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
44 # Extract the language name. |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
45 args = [parser.parse_expression()] |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
46 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
47 # Extract optional arguments. |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
48 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
|
49 'id': 1} |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
50 kwargs = {} |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
51 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
|
52 name = parser.stream.expect('name') |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
53 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
|
54 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
|
55 "highlighting tag." % name.value) |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
56 if kwarg_names[name.value] == 0: |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
57 kwargs[name.value] = Const(True) |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
58 elif parser.stream.skip_if('assign'): |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
59 kwargs[name.value] = parser.parse_expression() |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
60 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
61 # body of the block |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
62 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
|
63 drop_needle=True) |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
64 |
908
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
65 return CallBlock(self.call_method('_highlightTimed', args, kwargs), |
851
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
66 [], [], body).set_lineno(lineno) |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
67 |
908
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
68 def _highlightTimed(self, lang, line_numbers=False, use_classes=False, |
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
69 css_class=None, css_id=None, caller=None): |
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
70 with self.environment.app.env.stats.timerScope( |
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
71 'JinjaTemplateEngine_extensions'): |
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
72 return self._highlight(lang, line_numbers, use_classes, |
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
73 css_class, css_id, caller) |
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
74 |
851
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
75 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
|
76 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
|
77 from pygments import highlight |
448710d84121
refactor: Get the taxonomy support back to a functional state.
Ludovic Chabant <ludovic@chabant.com>
parents:
851
diff
changeset
|
78 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
|
79 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
|
80 |
851
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
81 # 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
|
82 body = caller() |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
83 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
84 if lang is None: |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
85 lexer = guess_lexer(body) |
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 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
|
88 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
89 if css_class is None: |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
90 try: |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
91 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
|
92 except AttributeError: |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
93 pass |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
94 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
95 if css_class is not None: |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
96 formatter = HtmlFormatter(cssclass=css_class, |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
97 linenos=line_numbers) |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
98 else: |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
99 formatter = HtmlFormatter(linenos=line_numbers) |
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 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
|
102 return code |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
103 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
104 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
105 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
|
106 from pygments.formatters import HtmlFormatter |
851
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
107 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
|
108 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
109 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
110 class PieCrustCacheExtension(Extension): |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
111 tags = set(['pccache', 'cache']) |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
112 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
113 def __init__(self, environment): |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
114 super(PieCrustCacheExtension, self).__init__(environment) |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
115 environment.extend( |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
116 piecrust_cache_prefix='', |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
117 piecrust_cache={} |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
118 ) |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
119 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
120 def parse(self, parser): |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
121 # 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
|
122 # 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
|
123 # `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
|
124 # 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
|
125 lineno = next(parser.stream).lineno |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
126 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
127 # 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
|
128 args = [parser.parse_expression()] |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
129 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
130 # 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
|
131 # 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
|
132 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
|
133 drop_needle=True) |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
134 |
908
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
135 # now return a `CallBlock` node that calls our _renderCache |
851
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
136 # helper method on this extension. |
908
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
137 return CallBlock(self.call_method('_renderCacheTimed', args), |
851
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
138 [], [], body).set_lineno(lineno) |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
139 |
908
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
140 def _renderCacheTimed(self, name, caller): |
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
141 with self.environment.app.env.stats.timerScope( |
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
142 'JinjaTemplateEngine_extensions'): |
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
143 return self._renderCache(name, caller) |
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
144 |
cedefb806bfd
jinja: Use the extensions performance timer.
Ludovic Chabant <ludovic@chabant.com>
parents:
858
diff
changeset
|
145 def _renderCache(self, name, caller): |
851
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
146 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
|
147 |
858
58e28ba02fb7
refactor: Fix a few more pieces of code using the old APIs.
Ludovic Chabant <ludovic@chabant.com>
parents:
855
diff
changeset
|
148 rcs = self.environment.app.env.render_ctx_stack |
991
1857dbd4580f
bake: Fix bugs introduced by bake optimizations, of course.
Ludovic Chabant <ludovic@chabant.com>
parents:
989
diff
changeset
|
149 ctx = rcs.current_ctx |
851
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
150 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
151 # 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
|
152 # 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
|
153 # it in the cache. |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
154 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
|
155 if pair is not None: |
991
1857dbd4580f
bake: Fix bugs introduced by bake optimizations, of course.
Ludovic Chabant <ludovic@chabant.com>
parents:
989
diff
changeset
|
156 for usn in pair[1]: |
1857dbd4580f
bake: Fix bugs introduced by bake optimizations, of course.
Ludovic Chabant <ludovic@chabant.com>
parents:
989
diff
changeset
|
157 ctx.addUsedSource(usn) |
851
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
158 return pair[0] |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
159 |
991
1857dbd4580f
bake: Fix bugs introduced by bake optimizations, of course.
Ludovic Chabant <ludovic@chabant.com>
parents:
989
diff
changeset
|
160 prev_used = set(ctx.current_used_source_names) |
851
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
161 rv = caller() |
991
1857dbd4580f
bake: Fix bugs introduced by bake optimizations, of course.
Ludovic Chabant <ludovic@chabant.com>
parents:
989
diff
changeset
|
162 after_used = set(ctx.current_used_source_names) |
851
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
163 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
|
164 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
|
165 return rv |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
166 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
167 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
168 class PieCrustSpacelessExtension(HtmlCompressor): |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
169 """ 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
|
170 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
|
171 """ |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
172 def filter_stream(self, stream): |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
173 ctx = StreamProcessContext(stream) |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
174 strip_depth = 0 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
175 while 1: |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
176 if stream.current.type == 'block_begin': |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
177 for tk in ['strip', 'spaceless']: |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
178 change = self._processToken(ctx, stream, tk) |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
179 if change != 0: |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
180 strip_depth += change |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
181 if strip_depth < 0: |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
182 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
|
183 break |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
184 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
|
185 ctx.token = stream.current |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
186 value = self.normalize(ctx) |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
187 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
|
188 else: |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
189 yield stream.current |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
190 next(stream) |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
191 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
192 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
|
193 change = 0 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
194 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
|
195 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
|
196 stream.skip() |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
197 if stream.current.value == test_token: |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
198 change = 1 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
199 else: |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
200 change = -1 |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
201 stream.skip() |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
202 if stream.current.type != 'block_end': |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
203 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
|
204 describe_token(stream.current)) |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
205 stream.skip() |
2c7e57d80bba
optimize: Don't load Jinja unless we need to.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
206 return change |