nginx-configurator/ncc/templating.py
2024-11-04 12:47:46 +01:00

52 lines
1.6 KiB
Python

import bisect
import re
from collections import defaultdict
from typing import Optional, Tuple
IDENTIFIER_RE = re.compile(r"(?<!%)(?:%(\w+)\b|%{(\w+)})")
def fill_template(template_str: str) -> Tuple[Optional[str], str]:
lines = template_str.splitlines()
identifier_contexts = defaultdict(list)
for i, line in enumerate(lines):
for match in re.finditer(IDENTIFIER_RE, line):
name = match[1] or match[2]
for j in range(max(0, i - 2), min(len(lines) - 1, i + 2)):
ctx = identifier_contexts[name]
idx = bisect.bisect_left(ctx, j)
if idx >= len(ctx) or ctx[idx] != j:
ctx.insert(idx, j)
replacements = {}
for identifier, ctx in identifier_contexts.items():
def colorize(match):
name = match[1] or match[2]
if name == identifier:
return f"\x1b[31m%{match[1] or match[2]}\x1b[0m"
else:
return match[0]
prev = 0
printed = 0
for line_idx in ctx:
print(re.sub(IDENTIFIER_RE, colorize, lines[line_idx]))
printed += 1
if prev and line_idx - prev > 1:
print("\x1b[1m---\x1b[0m")
printed += 1
prev = line_idx
replacements[identifier] = input("\x1b[1m => " + identifier + ":\x1b[0m ")
printed += 1
print(f"\r\x1b[{printed}F\x1b[0J", end="")
def replace(match):
return replacements[match[1] or match[2]]
return replacements.get("name"), re.sub(IDENTIFIER_RE, replace, template_str).replace("%%","%")