python-liquid 2.3.6__py3-none-any.whl → 3.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- liquid/__about__.py +1 -0
- liquid/__init__.py +161 -187
- liquid/_base_tag.py +66 -0
- liquid/{utils/chain_map.py → _chain_map.py} +18 -19
- liquid/_context.py +465 -0
- liquid/_drop.py +108 -0
- liquid/_filter.py +174 -0
- liquid/_io.py +18 -0
- liquid/_lax_parser_mixin.py +100 -0
- liquid/_lexer.py +93 -0
- liquid/_lexer_extended.py +623 -0
- liquid/_lexer_legacy.py +536 -0
- liquid/_loader.py +84 -0
- liquid/{utils/lru_cache.py → _lru_cache.py} +28 -36
- liquid/_markup.py +253 -0
- liquid/_messages.py +292 -0
- liquid/_missing.py +3 -0
- liquid/_nothing.py +28 -0
- liquid/_parser.py +460 -0
- liquid/_parser_extended.py +293 -0
- liquid/_parser_legacy.py +819 -0
- liquid/_resource_limits.py +50 -0
- liquid/_slice.py +41 -0
- liquid/_static_analysis.py +503 -0
- liquid/_strftime.py +186 -0
- liquid/_template.py +536 -0
- liquid/drops/__init__.py +20 -0
- liquid/drops/forloop.py +78 -0
- liquid/drops/iterable.py +25 -0
- liquid/drops/range.py +76 -0
- liquid/drops/self_.py +45 -0
- liquid/drops/tablerowloop.py +142 -0
- liquid/drops/undefined.py +228 -0
- liquid/environment.py +717 -551
- liquid/exceptions.py +67 -214
- liquid/expressions.py +1184 -0
- liquid/filters/__init__.py +134 -0
- liquid/filters/abs.py +7 -0
- liquid/filters/append.py +5 -0
- liquid/filters/at_least.py +9 -0
- liquid/filters/at_most.py +9 -0
- liquid/filters/babel.py +560 -0
- liquid/filters/base64.py +26 -0
- liquid/filters/capitalize.py +5 -0
- liquid/filters/ceil.py +8 -0
- liquid/filters/compact.py +25 -0
- liquid/filters/concat.py +11 -0
- liquid/filters/date.py +27 -0
- liquid/filters/default.py +25 -0
- liquid/filters/divided_by.py +21 -0
- liquid/filters/downcase.py +5 -0
- liquid/filters/escape.py +56 -0
- liquid/filters/find.py +56 -0
- liquid/filters/first.py +19 -0
- liquid/filters/floor.py +8 -0
- liquid/filters/html.py +23 -0
- liquid/filters/index.py +12 -0
- liquid/filters/join.py +13 -0
- liquid/filters/json_.py +30 -0
- liquid/filters/last.py +17 -0
- liquid/filters/map.py +5 -0
- liquid/filters/minus.py +13 -0
- liquid/filters/modulo.py +18 -0
- liquid/filters/newline_to_br.py +16 -0
- liquid/filters/plus.py +13 -0
- liquid/filters/prepend.py +5 -0
- liquid/filters/reject.py +19 -0
- liquid/filters/remove.py +36 -0
- liquid/filters/replace.py +32 -0
- liquid/filters/reverse.py +5 -0
- liquid/filters/round.py +35 -0
- liquid/filters/size.py +25 -0
- liquid/filters/slice.py +39 -0
- liquid/filters/sort.py +148 -0
- liquid/filters/split.py +34 -0
- liquid/filters/squish.py +9 -0
- liquid/filters/strip.py +13 -0
- liquid/filters/strip_html.py +19 -0
- liquid/filters/strip_newlines.py +17 -0
- liquid/filters/sum.py +21 -0
- liquid/filters/times.py +13 -0
- liquid/filters/translate.py +380 -0
- liquid/filters/truncate.py +39 -0
- liquid/filters/uniq.py +11 -0
- liquid/filters/upcase.py +5 -0
- liquid/filters/url.py +18 -0
- liquid/filters/where.py +18 -0
- liquid/loaders/__init__.py +17 -0
- liquid/loaders/caching_file_system_loader.py +64 -0
- liquid/loaders/choice_loader.py +93 -0
- liquid/loaders/dict_loader.py +56 -0
- liquid/{builtin/loaders → loaders}/file_system_loader.py +51 -55
- liquid/{builtin/loaders → loaders}/mixins.py +39 -51
- liquid/loaders/package_loader.py +110 -0
- liquid/tags/__init__.py +61 -0
- liquid/tags/assign.py +68 -0
- liquid/tags/capture.py +83 -0
- liquid/tags/case.py +199 -0
- liquid/tags/comment.py +56 -0
- liquid/tags/cycle.py +131 -0
- liquid/tags/decrement.py +55 -0
- liquid/tags/doc.py +56 -0
- liquid/tags/echo.py +65 -0
- liquid/tags/else_.py +53 -0
- liquid/tags/error.py +51 -0
- liquid/tags/extends.py +448 -0
- liquid/tags/for_.py +421 -0
- liquid/tags/if_.py +156 -0
- liquid/tags/ifchanged.py +69 -0
- liquid/tags/include.py +223 -0
- liquid/tags/increment.py +55 -0
- liquid/tags/inline_comment.py +70 -0
- liquid/tags/liquid.py +56 -0
- liquid/tags/macro.py +281 -0
- liquid/tags/output.py +58 -0
- liquid/tags/raw.py +60 -0
- liquid/tags/render.py +245 -0
- liquid/tags/tablerow.py +254 -0
- liquid/tags/template_comment.py +56 -0
- liquid/tags/translate.py +316 -0
- liquid/tags/unless.py +121 -0
- liquid/tags/with_.py +83 -0
- liquid/tokens.py +370 -0
- {python_liquid-2.3.6.dist-info → python_liquid-3.0.0.dist-info}/METADATA +32 -39
- python_liquid-3.0.0.dist-info/RECORD +128 -0
- {python_liquid-2.3.6.dist-info → python_liquid-3.0.0.dist-info}/WHEEL +1 -1
- {python_liquid-2.3.6.dist-info → python_liquid-3.0.0.dist-info}/licenses/LICENSE +1 -1
- liquid/analyze_tags.py +0 -214
- liquid/ast.py +0 -252
- liquid/builtin/__init__.py +0 -203
- liquid/builtin/content.py +0 -41
- liquid/builtin/drops/__init__.py +0 -3
- liquid/builtin/drops/drops.py +0 -13
- liquid/builtin/expressions/__init__.py +0 -47
- liquid/builtin/expressions/_tokenize.py +0 -186
- liquid/builtin/expressions/arguments.py +0 -207
- liquid/builtin/expressions/filtered.py +0 -387
- liquid/builtin/expressions/logical.py +0 -672
- liquid/builtin/expressions/loop.py +0 -275
- liquid/builtin/expressions/path.py +0 -163
- liquid/builtin/expressions/primitive.py +0 -417
- liquid/builtin/filters/__init__.py +0 -0
- liquid/builtin/filters/array.py +0 -329
- liquid/builtin/filters/extra.py +0 -83
- liquid/builtin/filters/math.py +0 -129
- liquid/builtin/filters/misc.py +0 -137
- liquid/builtin/filters/string.py +0 -416
- liquid/builtin/illegal.py +0 -28
- liquid/builtin/loaders/__init__.py +0 -0
- liquid/builtin/loaders/caching_file_system_loader.py +0 -61
- liquid/builtin/loaders/choice_loader.py +0 -94
- liquid/builtin/loaders/dict_loader.py +0 -64
- liquid/builtin/loaders/package_loader.py +0 -132
- liquid/builtin/output.py +0 -74
- liquid/builtin/tags/__init__.py +0 -0
- liquid/builtin/tags/assign_tag.py +0 -75
- liquid/builtin/tags/capture_tag.py +0 -98
- liquid/builtin/tags/case_tag.py +0 -287
- liquid/builtin/tags/comment_tag.py +0 -77
- liquid/builtin/tags/cycle_tag.py +0 -132
- liquid/builtin/tags/decrement_tag.py +0 -59
- liquid/builtin/tags/doc_tag.py +0 -68
- liquid/builtin/tags/echo_tag.py +0 -45
- liquid/builtin/tags/for_tag.py +0 -337
- liquid/builtin/tags/if_tag.py +0 -209
- liquid/builtin/tags/ifchanged_tag.py +0 -94
- liquid/builtin/tags/include_tag.py +0 -251
- liquid/builtin/tags/increment_tag.py +0 -60
- liquid/builtin/tags/inline_comment_tag.py +0 -47
- liquid/builtin/tags/liquid_tag.py +0 -183
- liquid/builtin/tags/render_tag.py +0 -371
- liquid/builtin/tags/tablerow_tag.py +0 -320
- liquid/builtin/tags/unless_tag.py +0 -218
- liquid/context.py +0 -615
- liquid/expression.py +0 -41
- liquid/extra/__init__.py +0 -98
- liquid/extra/filters/__init__.py +0 -33
- liquid/extra/filters/_json.py +0 -33
- liquid/extra/filters/array.py +0 -60
- liquid/extra/filters/babel.py +0 -552
- liquid/extra/filters/html.py +0 -32
- liquid/extra/filters/translate.py +0 -448
- liquid/extra/tags/__init__.py +0 -17
- liquid/extra/tags/_with.py +0 -80
- liquid/extra/tags/extends_tag.py +0 -576
- liquid/extra/tags/macro_tag.py +0 -270
- liquid/extra/tags/snippet_tag.py +0 -107
- liquid/extra/tags/translate_tag.py +0 -388
- liquid/filter.py +0 -230
- liquid/future/__init__.py +0 -3
- liquid/future/environment.py +0 -30
- liquid/future/filters/__init__.py +0 -1
- liquid/future/tags/__init__.py +0 -1
- liquid/lex.py +0 -260
- liquid/limits.py +0 -66
- liquid/loader.py +0 -141
- liquid/messages.py +0 -357
- liquid/mode.py +0 -12
- liquid/output.py +0 -35
- liquid/parser.py +0 -119
- liquid/span.py +0 -35
- liquid/static_analysis.py +0 -443
- liquid/stream.py +0 -148
- liquid/stringify.py +0 -31
- liquid/tag.py +0 -47
- liquid/template.py +0 -658
- liquid/token.py +0 -145
- liquid/undefined.py +0 -218
- liquid/utils/__init__.py +0 -15
- liquid/utils/html.py +0 -57
- liquid/utils/text.py +0 -28
- python_liquid-2.3.6.dist-info/RECORD +0 -96
|
@@ -1,448 +0,0 @@
|
|
|
1
|
-
"""Translation filters."""
|
|
2
|
-
|
|
3
|
-
import re
|
|
4
|
-
from gettext import NullTranslations
|
|
5
|
-
from typing import Any
|
|
6
|
-
from typing import Optional
|
|
7
|
-
from typing import cast
|
|
8
|
-
|
|
9
|
-
from markupsafe import Markup
|
|
10
|
-
|
|
11
|
-
from liquid import Expression
|
|
12
|
-
from liquid import RenderContext
|
|
13
|
-
from liquid.builtin.expressions import Filter
|
|
14
|
-
from liquid.builtin.expressions import KeywordArgument
|
|
15
|
-
from liquid.builtin.expressions import PositionalArgument
|
|
16
|
-
from liquid.builtin.expressions import StringLiteral
|
|
17
|
-
from liquid.filter import int_arg
|
|
18
|
-
from liquid.messages import MESSAGES
|
|
19
|
-
from liquid.messages import MessageText
|
|
20
|
-
from liquid.messages import TranslatableFilter
|
|
21
|
-
from liquid.messages import Translations
|
|
22
|
-
from liquid.stringify import to_liquid_string
|
|
23
|
-
|
|
24
|
-
__all__ = [
|
|
25
|
-
"Translate",
|
|
26
|
-
"GetText",
|
|
27
|
-
"NGetText",
|
|
28
|
-
"PGetText",
|
|
29
|
-
"NPGetText",
|
|
30
|
-
]
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
class BaseTranslateFilter:
|
|
34
|
-
"""Base class for the default translation filters.
|
|
35
|
-
|
|
36
|
-
Args:
|
|
37
|
-
translations_var: The name of a render context variable that resolves to a
|
|
38
|
-
gettext `Translations` class. Defaults to `"translations"`.
|
|
39
|
-
default_translations: A fallback translations class to use if
|
|
40
|
-
`translations_var` can not be resolves. Defaults to `NullTranslations`.
|
|
41
|
-
message_interpolation: If `True` (default), perform printf-style string
|
|
42
|
-
interpolation on the translated message, using keyword arguments passed to
|
|
43
|
-
the filter function.
|
|
44
|
-
autoescape_message: If `True` and the current environment has `autoescape`
|
|
45
|
-
set to `True`, the filter's left value will be escaped before translation.
|
|
46
|
-
Defaults to `False`.
|
|
47
|
-
"""
|
|
48
|
-
|
|
49
|
-
name = "base"
|
|
50
|
-
re_vars = re.compile(r"(?<!%)%\((\w+)\)s")
|
|
51
|
-
with_context = True
|
|
52
|
-
|
|
53
|
-
def __init__(
|
|
54
|
-
self,
|
|
55
|
-
*,
|
|
56
|
-
translations_var: str = "translations",
|
|
57
|
-
default_translations: Optional[Translations] = None,
|
|
58
|
-
message_interpolation: bool = True,
|
|
59
|
-
autoescape_message: bool = False,
|
|
60
|
-
) -> None:
|
|
61
|
-
self.translations_var = translations_var
|
|
62
|
-
self.default_translations = default_translations or NullTranslations()
|
|
63
|
-
self.message_interpolation = message_interpolation
|
|
64
|
-
self.autoescape_message = autoescape_message
|
|
65
|
-
|
|
66
|
-
def format_message(
|
|
67
|
-
self, context: RenderContext, message_text: str, message_vars: dict[str, Any]
|
|
68
|
-
) -> str:
|
|
69
|
-
"""Return the message string formatted with the given message variables."""
|
|
70
|
-
with context.extend(namespace=message_vars):
|
|
71
|
-
_vars = {
|
|
72
|
-
k: to_liquid_string(
|
|
73
|
-
context.resolve(k), autoescape=context.env.autoescape
|
|
74
|
-
)
|
|
75
|
-
for k in self.re_vars.findall(message_text)
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
# Missing variables get replaced by the current `Undefined` type and we're
|
|
79
|
-
# converting all values to a string, so a KeyError or a ValueError should
|
|
80
|
-
# be impossible.
|
|
81
|
-
return message_text % _vars
|
|
82
|
-
|
|
83
|
-
def _resolve_translations(self, context: RenderContext) -> Translations:
|
|
84
|
-
return cast(
|
|
85
|
-
Translations,
|
|
86
|
-
context.resolve(self.translations_var, default=self.default_translations),
|
|
87
|
-
)
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
class Translate(BaseTranslateFilter, TranslatableFilter):
|
|
91
|
-
"""A Liquid filter for translating strings to other languages.
|
|
92
|
-
|
|
93
|
-
Depending on the keyword arguments provided when the resulting filter
|
|
94
|
-
is called, it could behave like gettext, ngettext, pgettext or npgettext.
|
|
95
|
-
"""
|
|
96
|
-
|
|
97
|
-
name = "t"
|
|
98
|
-
|
|
99
|
-
def __call__(
|
|
100
|
-
self,
|
|
101
|
-
__left: object,
|
|
102
|
-
__message_context: object = None,
|
|
103
|
-
*,
|
|
104
|
-
context: RenderContext,
|
|
105
|
-
**kwargs: Any,
|
|
106
|
-
) -> str:
|
|
107
|
-
"""Apply the filter and return the result."""
|
|
108
|
-
autoescape = context.env.autoescape
|
|
109
|
-
__left = to_liquid_string(
|
|
110
|
-
__left,
|
|
111
|
-
autoescape=autoescape and self.autoescape_message,
|
|
112
|
-
)
|
|
113
|
-
|
|
114
|
-
translations = self._resolve_translations(context)
|
|
115
|
-
|
|
116
|
-
plural = kwargs.pop("plural", None)
|
|
117
|
-
n = _count(kwargs.get("count"))
|
|
118
|
-
|
|
119
|
-
if plural is not None and n is not None:
|
|
120
|
-
plural = to_liquid_string(
|
|
121
|
-
plural,
|
|
122
|
-
autoescape=autoescape and self.autoescape_message,
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
if __message_context is not None:
|
|
126
|
-
text = translations.npgettext(
|
|
127
|
-
to_liquid_string(
|
|
128
|
-
__message_context,
|
|
129
|
-
autoescape=autoescape and self.autoescape_message,
|
|
130
|
-
),
|
|
131
|
-
__left,
|
|
132
|
-
plural,
|
|
133
|
-
n,
|
|
134
|
-
)
|
|
135
|
-
else:
|
|
136
|
-
text = translations.ngettext(__left, plural, n)
|
|
137
|
-
elif __message_context is not None:
|
|
138
|
-
text = translations.pgettext(
|
|
139
|
-
to_liquid_string(
|
|
140
|
-
__message_context,
|
|
141
|
-
autoescape=autoescape and self.autoescape_message,
|
|
142
|
-
),
|
|
143
|
-
__left,
|
|
144
|
-
)
|
|
145
|
-
else:
|
|
146
|
-
text = translations.gettext(__left)
|
|
147
|
-
|
|
148
|
-
if autoescape:
|
|
149
|
-
text = Markup(text)
|
|
150
|
-
|
|
151
|
-
if self.message_interpolation:
|
|
152
|
-
text = self.format_message(context, text, kwargs)
|
|
153
|
-
|
|
154
|
-
return text
|
|
155
|
-
|
|
156
|
-
def message( # noqa: D102
|
|
157
|
-
self,
|
|
158
|
-
left: Expression,
|
|
159
|
-
_filter: Filter,
|
|
160
|
-
lineno: int,
|
|
161
|
-
) -> Optional[MessageText]:
|
|
162
|
-
if not isinstance(left, StringLiteral):
|
|
163
|
-
return None
|
|
164
|
-
|
|
165
|
-
if not _filter.args:
|
|
166
|
-
return MessageText(
|
|
167
|
-
lineno=lineno,
|
|
168
|
-
funcname="gettext",
|
|
169
|
-
message=(left.value,),
|
|
170
|
-
)
|
|
171
|
-
|
|
172
|
-
if isinstance(_filter.args[0], PositionalArgument):
|
|
173
|
-
_context: Optional[Expression] = _filter.args[0].value
|
|
174
|
-
else:
|
|
175
|
-
_context = None
|
|
176
|
-
|
|
177
|
-
plural: Optional[Expression] = None
|
|
178
|
-
for arg in _filter.args:
|
|
179
|
-
if isinstance(arg, KeywordArgument) and arg.name == "plural":
|
|
180
|
-
plural = arg.value
|
|
181
|
-
|
|
182
|
-
# Translate our filters into standard *gettext argument specs.
|
|
183
|
-
|
|
184
|
-
if isinstance(plural, StringLiteral):
|
|
185
|
-
if isinstance(_context, StringLiteral):
|
|
186
|
-
funcname = "npgettext"
|
|
187
|
-
message: MESSAGES = ((_context.value, "c"), left.value, plural.value)
|
|
188
|
-
else:
|
|
189
|
-
funcname = "ngettext"
|
|
190
|
-
message = (left.value, plural.value)
|
|
191
|
-
elif plural is not None:
|
|
192
|
-
# Don't attempt to extract any messages if plural is given
|
|
193
|
-
# but not a string literal
|
|
194
|
-
return None
|
|
195
|
-
elif isinstance(_context, StringLiteral):
|
|
196
|
-
funcname = "pgettext"
|
|
197
|
-
message = ((_context.value, "c"), left.value)
|
|
198
|
-
else:
|
|
199
|
-
funcname = "gettext"
|
|
200
|
-
message = (left.value,)
|
|
201
|
-
|
|
202
|
-
return MessageText(
|
|
203
|
-
lineno=lineno,
|
|
204
|
-
funcname=funcname,
|
|
205
|
-
message=message,
|
|
206
|
-
)
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
class GetText(BaseTranslateFilter, TranslatableFilter):
|
|
210
|
-
"""A Liquid filter equivalent of `gettext.gettext`."""
|
|
211
|
-
|
|
212
|
-
name = "gettext"
|
|
213
|
-
|
|
214
|
-
def __call__( # noqa: D102
|
|
215
|
-
self,
|
|
216
|
-
__left: object,
|
|
217
|
-
*,
|
|
218
|
-
context: RenderContext,
|
|
219
|
-
**kwargs: Any,
|
|
220
|
-
) -> str:
|
|
221
|
-
autoescape = context.env.autoescape
|
|
222
|
-
__left = to_liquid_string(
|
|
223
|
-
__left,
|
|
224
|
-
autoescape=autoescape and self.autoescape_message,
|
|
225
|
-
)
|
|
226
|
-
|
|
227
|
-
translations = self._resolve_translations(context)
|
|
228
|
-
text = translations.gettext(__left)
|
|
229
|
-
|
|
230
|
-
if autoescape:
|
|
231
|
-
text = Markup(text)
|
|
232
|
-
|
|
233
|
-
if self.message_interpolation:
|
|
234
|
-
text = self.format_message(context, text, kwargs)
|
|
235
|
-
|
|
236
|
-
return text
|
|
237
|
-
|
|
238
|
-
def message( # noqa: D102
|
|
239
|
-
self,
|
|
240
|
-
left: Expression,
|
|
241
|
-
_filter: Filter,
|
|
242
|
-
lineno: int,
|
|
243
|
-
) -> Optional[MessageText]:
|
|
244
|
-
if not isinstance(left, StringLiteral):
|
|
245
|
-
return None
|
|
246
|
-
|
|
247
|
-
return MessageText(
|
|
248
|
-
lineno=lineno,
|
|
249
|
-
funcname=self.name,
|
|
250
|
-
message=(left.value,),
|
|
251
|
-
)
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
class NGetText(BaseTranslateFilter, TranslatableFilter):
|
|
255
|
-
"""A Liquid filter equivalent of `gettext.ngettext`."""
|
|
256
|
-
|
|
257
|
-
name = "ngettext"
|
|
258
|
-
|
|
259
|
-
def __call__(
|
|
260
|
-
self,
|
|
261
|
-
__left: object,
|
|
262
|
-
__plural: str,
|
|
263
|
-
__count: object,
|
|
264
|
-
*,
|
|
265
|
-
context: RenderContext,
|
|
266
|
-
**kwargs: Any,
|
|
267
|
-
) -> str:
|
|
268
|
-
"""Apply the filter and return the result."""
|
|
269
|
-
autoescape = context.env.autoescape
|
|
270
|
-
__left = to_liquid_string(
|
|
271
|
-
__left,
|
|
272
|
-
autoescape=autoescape and self.autoescape_message,
|
|
273
|
-
)
|
|
274
|
-
|
|
275
|
-
__plural = to_liquid_string(
|
|
276
|
-
__plural,
|
|
277
|
-
autoescape=autoescape and self.autoescape_message,
|
|
278
|
-
)
|
|
279
|
-
|
|
280
|
-
__count = int_arg(__count, default=1)
|
|
281
|
-
|
|
282
|
-
translations = self._resolve_translations(context)
|
|
283
|
-
text = translations.ngettext(__left, __plural, __count)
|
|
284
|
-
|
|
285
|
-
if autoescape:
|
|
286
|
-
text = Markup(text)
|
|
287
|
-
|
|
288
|
-
if self.message_interpolation:
|
|
289
|
-
text = self.format_message(context, text, kwargs)
|
|
290
|
-
|
|
291
|
-
return text
|
|
292
|
-
|
|
293
|
-
def message( # noqa: D102
|
|
294
|
-
self,
|
|
295
|
-
left: Expression,
|
|
296
|
-
_filter: Filter,
|
|
297
|
-
lineno: int,
|
|
298
|
-
) -> Optional[MessageText]:
|
|
299
|
-
if len(_filter.args) < 1:
|
|
300
|
-
return None
|
|
301
|
-
|
|
302
|
-
plural = _filter.args[0].value
|
|
303
|
-
|
|
304
|
-
if not isinstance(left, StringLiteral) or not isinstance(plural, StringLiteral):
|
|
305
|
-
return None
|
|
306
|
-
|
|
307
|
-
return MessageText(
|
|
308
|
-
lineno=lineno,
|
|
309
|
-
funcname=self.name,
|
|
310
|
-
message=(left.value, plural.value),
|
|
311
|
-
)
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
class PGetText(BaseTranslateFilter, TranslatableFilter):
|
|
315
|
-
"""A Liquid filter equivalent of `gettext.pgettext`."""
|
|
316
|
-
|
|
317
|
-
name = "pgettext"
|
|
318
|
-
|
|
319
|
-
def __call__( # noqa: D102
|
|
320
|
-
self,
|
|
321
|
-
__left: object,
|
|
322
|
-
__message_context: str,
|
|
323
|
-
*,
|
|
324
|
-
context: RenderContext,
|
|
325
|
-
**kwargs: Any,
|
|
326
|
-
) -> str:
|
|
327
|
-
autoescape = context.env.autoescape
|
|
328
|
-
__left = to_liquid_string(
|
|
329
|
-
__left,
|
|
330
|
-
autoescape=autoescape and self.autoescape_message,
|
|
331
|
-
)
|
|
332
|
-
|
|
333
|
-
__message_context = to_liquid_string(
|
|
334
|
-
__message_context,
|
|
335
|
-
autoescape=autoescape and self.autoescape_message,
|
|
336
|
-
)
|
|
337
|
-
|
|
338
|
-
translations = self._resolve_translations(context)
|
|
339
|
-
text = translations.pgettext(__message_context, __left)
|
|
340
|
-
|
|
341
|
-
if autoescape:
|
|
342
|
-
text = Markup(text)
|
|
343
|
-
|
|
344
|
-
if self.message_interpolation:
|
|
345
|
-
text = self.format_message(context, text, kwargs)
|
|
346
|
-
|
|
347
|
-
return text
|
|
348
|
-
|
|
349
|
-
def message( # noqa: D102
|
|
350
|
-
self, left: Expression, _filter: Filter, lineno: int
|
|
351
|
-
) -> Optional[MessageText]:
|
|
352
|
-
if len(_filter.args) < 1:
|
|
353
|
-
return None
|
|
354
|
-
|
|
355
|
-
ctx = _filter.args[0].value
|
|
356
|
-
|
|
357
|
-
if not isinstance(left, StringLiteral) or not isinstance(ctx, StringLiteral):
|
|
358
|
-
return None
|
|
359
|
-
|
|
360
|
-
return MessageText(
|
|
361
|
-
lineno=lineno,
|
|
362
|
-
funcname=self.name,
|
|
363
|
-
message=((ctx.value, "c"), left.value),
|
|
364
|
-
)
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
class NPGetText(BaseTranslateFilter, TranslatableFilter):
|
|
368
|
-
"""A Liquid filter equivalent of `gettext.npgettext`."""
|
|
369
|
-
|
|
370
|
-
name = "npgettext"
|
|
371
|
-
|
|
372
|
-
def __call__( # noqa: D102
|
|
373
|
-
self,
|
|
374
|
-
__left: object,
|
|
375
|
-
__message_context: str,
|
|
376
|
-
__plural: str,
|
|
377
|
-
__count: object,
|
|
378
|
-
*,
|
|
379
|
-
context: RenderContext,
|
|
380
|
-
**kwargs: Any,
|
|
381
|
-
) -> str:
|
|
382
|
-
autoescape = context.env.autoescape
|
|
383
|
-
__left = to_liquid_string(
|
|
384
|
-
__left,
|
|
385
|
-
autoescape=autoescape and self.autoescape_message,
|
|
386
|
-
)
|
|
387
|
-
|
|
388
|
-
__message_context = to_liquid_string(
|
|
389
|
-
__message_context,
|
|
390
|
-
autoescape=autoescape and self.autoescape_message,
|
|
391
|
-
)
|
|
392
|
-
|
|
393
|
-
__plural = to_liquid_string(
|
|
394
|
-
__plural,
|
|
395
|
-
autoescape=autoescape and self.autoescape_message,
|
|
396
|
-
)
|
|
397
|
-
|
|
398
|
-
__count = int_arg(__count, default=1)
|
|
399
|
-
|
|
400
|
-
translations = self._resolve_translations(context)
|
|
401
|
-
text = translations.npgettext(
|
|
402
|
-
__message_context,
|
|
403
|
-
__left,
|
|
404
|
-
__plural,
|
|
405
|
-
__count,
|
|
406
|
-
)
|
|
407
|
-
|
|
408
|
-
if autoescape:
|
|
409
|
-
text = Markup(text)
|
|
410
|
-
|
|
411
|
-
if self.message_interpolation:
|
|
412
|
-
text = self.format_message(context, text, kwargs)
|
|
413
|
-
|
|
414
|
-
return text
|
|
415
|
-
|
|
416
|
-
def message( # noqa: D102
|
|
417
|
-
self,
|
|
418
|
-
left: Expression,
|
|
419
|
-
_filter: Filter,
|
|
420
|
-
lineno: int,
|
|
421
|
-
) -> Optional[MessageText]:
|
|
422
|
-
if len(_filter.args) < 2: # noqa: PLR2004
|
|
423
|
-
return None
|
|
424
|
-
|
|
425
|
-
ctx = _filter.args[0].value
|
|
426
|
-
plural = _filter.args[1].value
|
|
427
|
-
|
|
428
|
-
if (
|
|
429
|
-
not isinstance(left, StringLiteral)
|
|
430
|
-
or not isinstance(plural, StringLiteral)
|
|
431
|
-
or not isinstance(ctx, StringLiteral)
|
|
432
|
-
):
|
|
433
|
-
return None
|
|
434
|
-
|
|
435
|
-
return MessageText(
|
|
436
|
-
lineno=lineno,
|
|
437
|
-
funcname=self.name,
|
|
438
|
-
message=((ctx.value, "c"), left.value, plural.value),
|
|
439
|
-
)
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
def _count(val: Any) -> Optional[int]:
|
|
443
|
-
if val in (None, False, True):
|
|
444
|
-
return None
|
|
445
|
-
try:
|
|
446
|
-
return int(val)
|
|
447
|
-
except ValueError:
|
|
448
|
-
return None
|
liquid/extra/tags/__init__.py
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
from ._with import WithTag # noqa: D104
|
|
2
|
-
from .extends_tag import BlockTag
|
|
3
|
-
from .extends_tag import ExtendsTag
|
|
4
|
-
from .macro_tag import CallTag
|
|
5
|
-
from .macro_tag import MacroTag
|
|
6
|
-
from .snippet_tag import SnippetTag
|
|
7
|
-
from .translate_tag import TranslateTag
|
|
8
|
-
|
|
9
|
-
__all__ = (
|
|
10
|
-
"WithTag",
|
|
11
|
-
"BlockTag",
|
|
12
|
-
"ExtendsTag",
|
|
13
|
-
"CallTag",
|
|
14
|
-
"MacroTag",
|
|
15
|
-
"SnippetTag",
|
|
16
|
-
"TranslateTag",
|
|
17
|
-
)
|
liquid/extra/tags/_with.py
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
"""The extra _with_ tag."""
|
|
2
|
-
|
|
3
|
-
from __future__ import annotations
|
|
4
|
-
|
|
5
|
-
import sys
|
|
6
|
-
from typing import TYPE_CHECKING
|
|
7
|
-
from typing import Iterable
|
|
8
|
-
from typing import TextIO
|
|
9
|
-
|
|
10
|
-
from liquid.ast import BlockNode
|
|
11
|
-
from liquid.ast import Node
|
|
12
|
-
from liquid.builtin.expressions import Identifier
|
|
13
|
-
from liquid.builtin.expressions import KeywordArgument
|
|
14
|
-
from liquid.parser import get_parser
|
|
15
|
-
from liquid.tag import Tag
|
|
16
|
-
from liquid.token import TOKEN_EOF
|
|
17
|
-
from liquid.token import TOKEN_TAG
|
|
18
|
-
from liquid.token import Token
|
|
19
|
-
|
|
20
|
-
if TYPE_CHECKING:
|
|
21
|
-
from liquid.context import RenderContext
|
|
22
|
-
from liquid.expression import Expression
|
|
23
|
-
from liquid.stream import TokenStream
|
|
24
|
-
|
|
25
|
-
TAG_WITH = sys.intern("with")
|
|
26
|
-
TAG_ENDWITH = sys.intern("endwith")
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
class WithNode(Node):
|
|
30
|
-
__slots__ = ("args", "block")
|
|
31
|
-
|
|
32
|
-
def __init__(self, token: Token, args: list[KeywordArgument], block: BlockNode):
|
|
33
|
-
super().__init__(token)
|
|
34
|
-
self.args = args
|
|
35
|
-
self.block = block
|
|
36
|
-
self.blank = self.block.blank
|
|
37
|
-
|
|
38
|
-
def render_to_output(
|
|
39
|
-
self,
|
|
40
|
-
context: RenderContext,
|
|
41
|
-
buffer: TextIO,
|
|
42
|
-
) -> int:
|
|
43
|
-
with context.extend({a.name: a.value.evaluate(context) for a in self.args}):
|
|
44
|
-
return self.block.render(context, buffer)
|
|
45
|
-
|
|
46
|
-
async def render_to_output_async(
|
|
47
|
-
self,
|
|
48
|
-
context: RenderContext,
|
|
49
|
-
buffer: TextIO,
|
|
50
|
-
) -> int:
|
|
51
|
-
namespace = {a.name: await a.value.evaluate_async(context) for a in self.args}
|
|
52
|
-
with context.extend(namespace):
|
|
53
|
-
return await self.block.render_async(context, buffer)
|
|
54
|
-
|
|
55
|
-
def children(
|
|
56
|
-
self,
|
|
57
|
-
static_context: RenderContext, # noqa: ARG002
|
|
58
|
-
*,
|
|
59
|
-
include_partials: bool = True, # noqa: ARG002
|
|
60
|
-
) -> Iterable[Node]:
|
|
61
|
-
yield self.block
|
|
62
|
-
|
|
63
|
-
def expressions(self) -> Iterable[Expression]:
|
|
64
|
-
yield from (arg.value for arg in self.args)
|
|
65
|
-
|
|
66
|
-
def block_scope(self) -> Iterable[Identifier]:
|
|
67
|
-
yield from (Identifier(p.name, token=p.token) for p in self.args)
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
class WithTag(Tag):
|
|
71
|
-
name = TAG_WITH
|
|
72
|
-
end = TAG_ENDWITH
|
|
73
|
-
node_class = WithNode
|
|
74
|
-
|
|
75
|
-
def parse(self, stream: TokenStream) -> Node:
|
|
76
|
-
token = stream.eat(TOKEN_TAG)
|
|
77
|
-
args = KeywordArgument.parse(self.env, stream.into_inner(tag=token))
|
|
78
|
-
block = get_parser(self.env).parse_block(stream, (TAG_ENDWITH, TOKEN_EOF))
|
|
79
|
-
stream.expect(TOKEN_TAG, value=TAG_ENDWITH)
|
|
80
|
-
return self.node_class(token, args=args, block=block)
|