Added clipping function.

This commit is contained in:
sarah committed 2026-09-21 23:40:04 +02:00
1 parent e9390dfa7e
commit b06231ea5e
1 file changed
+63 -5
+63 -5
View File
@@ -13,9 +13,12 @@ LoopSources = ("children", "siblings", "parents")
MarkerPattern = re.compile(
r"\{(?:(?P<CrossPath>[^\s{}']+)\s+)?\*\*\*(?P<CrossName>[^\s*{}]+)"
r"(?:\s+(?P<CrossPipe>head|tail)\s+(?P<CrossPipeCount>\d+))?\}"
r"|\{(?P<PipePath>[^\s{}']+)\s+(?P<PipeMode>head|tail)\s+(?P<PipeCount>\d+)\}"
r"|\{(?P<LinePath>[^\s{}']+)\s+'(?P<LineNumber>\d+)'\}"
r"(?:\s+(?P<CrossPipe>head|tail)\s+(?P<CrossPipeCount>\d+))?"
r"(?:\s*\\\s*(?P<CrossClip>[^{}]*))?\}"
r"|\{(?P<PipePath>[^\s{}']+)\s+(?P<PipeMode>head|tail)\s+(?P<PipeCount>\d+)"
r"(?:\s*\\\s*(?P<PipeClip>[^{}]*))?\}"
r"|\{(?P<LinePath>[^\s{}']+)\s+'(?P<LineNumber>\d+)'"
r"(?:\s*\\\s*(?P<LineClip>[^{}]*))?\}"
r"|\{\*\*(?P<LineName>[^\s*{}]+)\}"
r"|\{\*(?P<BlockName>[^\s*{}]+)\}"
)
@@ -30,6 +33,39 @@ LoopMarkerPattern = re.compile(
)
def _CompileClipPattern(Pattern: str) -> re.Pattern:
RegexParts = []
LastIndex = len(Pattern) - 1
for Index, Char in enumerate(Pattern):
IsLast = Index == LastIndex
if Char == "!":
RegexParts.append("(.*)" if IsLast else "(.*?)")
elif Char == "?":
RegexParts.append(".*" if IsLast else ".*?")
else:
RegexParts.append(re.escape(Char))
if not Pattern or Pattern[-1] not in "!?":
RegexParts.append(".*")
return re.compile("".join(RegexParts), re.DOTALL)
def _ApplyClip(Value: str, Pattern: str) -> str:
Pattern = Pattern.strip()
if not Pattern:
return Value
Match = _CompileClipPattern(Pattern).match(Value)
if Match is None:
return Value
return "".join(Match.groups())
def _LineBounds(Content: str, Position: int) -> tuple[int, int]:
LineStart = Content.rfind("\n", 0, Position) + 1
LineEnd = Content.find("\n", Position)
@@ -206,9 +242,25 @@ def _ResolveLoops(
CloseMatch = _FindLoopClose(Matches, Index + 1, IsFixed, Key)
BodyEnd = CloseMatch.start() if CloseMatch is not None else len(Content)
BodyTemplate = Content[Match.end() : BodyEnd]
VariablePattern = re.compile(rf"%{re.escape(LoopVar)}\b")
EscapedVar = re.escape(LoopVar)
VariablePattern = re.compile(
r"\{%" + EscapedVar + r"\s*\\\s*(?P<Clip>[^{}]*)\}"
r"|%" + EscapedVar + r"\b"
)
Rendered = "\n".join(VariablePattern.sub(Item, BodyTemplate) for Item in Items)
RenderedItems = []
for Item in Items:
ItemRendered = VariablePattern.sub(
lambda VariableMatch, CurrentItem=Item: (
_ApplyClip(CurrentItem, VariableMatch.group("Clip"))
if VariableMatch.group("Clip") is not None
else CurrentItem
),
BodyTemplate,
)
RenderedItems.append(ItemRendered)
Rendered = "\n".join(RenderedItems)
Output.append(Content[Cursor : Match.start()])
Output.append(Rendered)
@@ -383,6 +435,8 @@ def ResolvePortals(
Replacement = _ApplyPipe(
Replacement, Match.group("CrossPipe"), int(Match.group("CrossPipeCount"))
)
if Replacement is not None and Match.group("CrossClip"):
Replacement = _ApplyClip(Replacement, Match.group("CrossClip"))
elif Match.group("PipeMode"):
Replacement = _ResolveWholeFilePipe(
RootName,
@@ -393,6 +447,8 @@ def ResolvePortals(
Username,
UserGroups,
)
if Replacement is not None and Match.group("PipeClip"):
Replacement = _ApplyClip(Replacement, Match.group("PipeClip"))
elif Match.group("LineNumber"):
Replacement = _ResolveLineNumberReference(
RootName,
@@ -402,6 +458,8 @@ def ResolvePortals(
Username,
UserGroups,
)
if Replacement is not None and Match.group("LineClip"):
Replacement = _ApplyClip(Replacement, Match.group("LineClip"))
if Replacement is not None:
Output.append(LocallyResolved[Cursor : Match.start()])