mapres 2.4a10__tar.gz → 2.4a12__tar.gz
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.
- {mapres-2.4a10/src/mapres.egg-info → mapres-2.4a12}/PKG-INFO +1 -1
- {mapres-2.4a10 → mapres-2.4a12}/pyproject.toml +1 -1
- {mapres-2.4a10 → mapres-2.4a12}/src/mapres/datamap.py +9 -10
- {mapres-2.4a10 → mapres-2.4a12}/src/mapres/resolver.py +42 -4
- {mapres-2.4a10 → mapres-2.4a12/src/mapres.egg-info}/PKG-INFO +1 -1
- {mapres-2.4a10 → mapres-2.4a12}/LICENSE +0 -0
- {mapres-2.4a10 → mapres-2.4a12}/README.md +0 -0
- {mapres-2.4a10 → mapres-2.4a12}/setup.cfg +0 -0
- {mapres-2.4a10 → mapres-2.4a12}/src/mapres/__init__.py +0 -0
- {mapres-2.4a10 → mapres-2.4a12}/src/mapres/cache.py +0 -0
- {mapres-2.4a10 → mapres-2.4a12}/src/mapres/exceptions.py +0 -0
- {mapres-2.4a10 → mapres-2.4a12}/src/mapres/layers.py +0 -0
- {mapres-2.4a10 → mapres-2.4a12}/src/mapres/maps/__init__.py +0 -0
- {mapres-2.4a10 → mapres-2.4a12}/src/mapres/maps/color.py +0 -0
- {mapres-2.4a10 → mapres-2.4a12}/src/mapres/maps/time.py +0 -0
- {mapres-2.4a10 → mapres-2.4a12}/src/mapres.egg-info/SOURCES.txt +0 -0
- {mapres-2.4a10 → mapres-2.4a12}/src/mapres.egg-info/dependency_links.txt +0 -0
- {mapres-2.4a10 → mapres-2.4a12}/src/mapres.egg-info/requires.txt +0 -0
- {mapres-2.4a10 → mapres-2.4a12}/src/mapres.egg-info/top_level.txt +0 -0
|
@@ -2,16 +2,15 @@ import re
|
|
|
2
2
|
from dataclasses import dataclass, fields, is_dataclass
|
|
3
3
|
|
|
4
4
|
class syntax:
|
|
5
|
-
double_braces = r'\{\{([
|
|
6
|
-
dollars = r'\$\{([
|
|
7
|
-
angles = r'<([
|
|
8
|
-
percents = r'%([
|
|
9
|
-
at_tags = r'@([
|
|
10
|
-
hash_tags = r'#([
|
|
11
|
-
pipe_tags = r'\|([
|
|
12
|
-
paren_dollar = r'\$\(([
|
|
13
|
-
colons = r':([
|
|
14
|
-
|
|
5
|
+
double_braces = r'\{\{([A-Za-z][A-Za-z0-9_]*)\}\}' # {{value}}
|
|
6
|
+
dollars = r'\$\{([A-Za-z][A-Za-z0-9_]*)\}' # ${value}
|
|
7
|
+
angles = r'<([A-Za-z][A-Za-z0-9_]*)>' # <value>
|
|
8
|
+
percents = r'%([A-Za-z][A-Za-z0-9_]*)%' # %value%
|
|
9
|
+
at_tags = r'@([A-Za-z][A-Za-z0-9_]*)@' # @value@
|
|
10
|
+
hash_tags = r'#([A-Za-z][A-Za-z0-9_]*)#' # #value#
|
|
11
|
+
pipe_tags = r'\|([A-Za-z][A-Za-z0-9_]*)\|' # |value|
|
|
12
|
+
paren_dollar = r'\$\(([A-Za-z][A-Za-z0-9_]*)\)' # $(value)
|
|
13
|
+
colons = r':([A-Za-z][A-Za-z0-9_]*):' # :value:
|
|
15
14
|
|
|
16
15
|
@dataclass
|
|
17
16
|
class DataMap:
|
|
@@ -5,6 +5,38 @@ from .layers import Layer, LayerStack
|
|
|
5
5
|
from .exceptions import MapResError, MissingKeyError, MapSyntaxError
|
|
6
6
|
|
|
7
7
|
|
|
8
|
+
# escape pipeline
|
|
9
|
+
ESCAPES = {
|
|
10
|
+
r'\:': '__ESC_COLON__',
|
|
11
|
+
r'\<': '__ESC_LT__',
|
|
12
|
+
r'\%': '__ESC_PERCENT__',
|
|
13
|
+
r'\$': '__ESC_DOLLAR__',
|
|
14
|
+
r'\{': '__ESC_LBRACE__',
|
|
15
|
+
r'\|': '__ESC_PIPE__',
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
# Reverse mapping: placeholder -> literal char (without backslash)
|
|
19
|
+
UNESCAPES = {
|
|
20
|
+
placeholder: esc[1:] # remove leading backslash
|
|
21
|
+
for esc, placeholder in ESCAPES.items()
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def escape_stage(text: str, ctx: dict, resolver) -> str:
|
|
26
|
+
"""Replace escaped opening delimiters with placeholders."""
|
|
27
|
+
for esc, placeholder in ESCAPES.items():
|
|
28
|
+
text = text.replace(esc, placeholder)
|
|
29
|
+
return text
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def unescape_stage(text: str, ctx: dict, resolver) -> str:
|
|
33
|
+
"""Restore escaped delimiters after resolution."""
|
|
34
|
+
for placeholder, literal in UNESCAPES.items():
|
|
35
|
+
text = text.replace(placeholder, literal)
|
|
36
|
+
return text
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
# core resolver
|
|
8
40
|
class MapResolver:
|
|
9
41
|
'''
|
|
10
42
|
Core resolution engine for mapres.
|
|
@@ -35,6 +67,12 @@ class MapResolver:
|
|
|
35
67
|
# unified recursion control
|
|
36
68
|
self.passes_default = passes_default
|
|
37
69
|
|
|
70
|
+
# Insert escape stage FIRST
|
|
71
|
+
self.pipeline.insert(0, escape_stage)
|
|
72
|
+
|
|
73
|
+
# Append unescape stage LAST
|
|
74
|
+
self.pipeline.append(unescape_stage)
|
|
75
|
+
|
|
38
76
|
# pipeline
|
|
39
77
|
def _apply_pipeline(self, text: str, ctx: dict) -> str:
|
|
40
78
|
try:
|
|
@@ -152,7 +190,6 @@ class MapResolver:
|
|
|
152
190
|
Resolve a string using maps, syntax providers, pipeline, and context.
|
|
153
191
|
'''
|
|
154
192
|
try:
|
|
155
|
-
# determine number of passes
|
|
156
193
|
depth = passes if passes is not None else self.passes_default
|
|
157
194
|
|
|
158
195
|
if depth <= 0:
|
|
@@ -200,16 +237,17 @@ class MapResolver:
|
|
|
200
237
|
# ----------------------------------
|
|
201
238
|
# ---------- SIMPLE USAGE ----------
|
|
202
239
|
# ----------------------------------
|
|
203
|
-
|
|
240
|
+
|
|
241
|
+
_DEFAULT_RESOLVER = MapResolver()
|
|
204
242
|
|
|
205
243
|
def setGlobalMaps(maps, *, name=None, priority=0):
|
|
206
|
-
|
|
244
|
+
'''
|
|
207
245
|
Register a global map or datamap class into the default resolver.
|
|
208
246
|
|
|
209
247
|
maps: datamap class OR dict
|
|
210
248
|
name: optional layer name (default = class name or 'global')
|
|
211
249
|
priority: layer priority (lower = earlier)
|
|
212
|
-
|
|
250
|
+
'''
|
|
213
251
|
layer_name = name or getattr(maps, "__name__", "global")
|
|
214
252
|
layer = Layer(layer_name, maps=[maps], priority=priority)
|
|
215
253
|
_DEFAULT_RESOLVER.layers.add_layer(layer)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|