mirror of
https://git.srhtnin.garden/sarah/SaraView.git
synced 2026-10-15 02:43:17 +02:00
Added clipping function.
This commit is contained in:
1 parent
e9390dfa7e
commit
b06231ea5e
1 file changed
+63
-5
+63
-5
@@ -13,9 +13,12 @@ LoopSources = ("children", "siblings", "parents")
|
|||||||
|
|
||||||
MarkerPattern = re.compile(
|
MarkerPattern = re.compile(
|
||||||
r"\{(?:(?P<CrossPath>[^\s{}']+)\s+)?\*\*\*(?P<CrossName>[^\s*{}]+)"
|
r"\{(?:(?P<CrossPath>[^\s{}']+)\s+)?\*\*\*(?P<CrossName>[^\s*{}]+)"
|
||||||
r"(?:\s+(?P<CrossPipe>head|tail)\s+(?P<CrossPipeCount>\d+))?\}"
|
r"(?:\s+(?P<CrossPipe>head|tail)\s+(?P<CrossPipeCount>\d+))?"
|
||||||
r"|\{(?P<PipePath>[^\s{}']+)\s+(?P<PipeMode>head|tail)\s+(?P<PipeCount>\d+)\}"
|
r"(?:\s*\\\s*(?P<CrossClip>[^{}]*))?\}"
|
||||||
r"|\{(?P<LinePath>[^\s{}']+)\s+'(?P<LineNumber>\d+)'\}"
|
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<LineName>[^\s*{}]+)\}"
|
||||||
r"|\{\*(?P<BlockName>[^\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]:
|
def _LineBounds(Content: str, Position: int) -> tuple[int, int]:
|
||||||
LineStart = Content.rfind("\n", 0, Position) + 1
|
LineStart = Content.rfind("\n", 0, Position) + 1
|
||||||
LineEnd = Content.find("\n", Position)
|
LineEnd = Content.find("\n", Position)
|
||||||
@@ -206,9 +242,25 @@ def _ResolveLoops(
|
|||||||
CloseMatch = _FindLoopClose(Matches, Index + 1, IsFixed, Key)
|
CloseMatch = _FindLoopClose(Matches, Index + 1, IsFixed, Key)
|
||||||
BodyEnd = CloseMatch.start() if CloseMatch is not None else len(Content)
|
BodyEnd = CloseMatch.start() if CloseMatch is not None else len(Content)
|
||||||
BodyTemplate = Content[Match.end() : BodyEnd]
|
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(Content[Cursor : Match.start()])
|
||||||
Output.append(Rendered)
|
Output.append(Rendered)
|
||||||
@@ -383,6 +435,8 @@ def ResolvePortals(
|
|||||||
Replacement = _ApplyPipe(
|
Replacement = _ApplyPipe(
|
||||||
Replacement, Match.group("CrossPipe"), int(Match.group("CrossPipeCount"))
|
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"):
|
elif Match.group("PipeMode"):
|
||||||
Replacement = _ResolveWholeFilePipe(
|
Replacement = _ResolveWholeFilePipe(
|
||||||
RootName,
|
RootName,
|
||||||
@@ -393,6 +447,8 @@ def ResolvePortals(
|
|||||||
Username,
|
Username,
|
||||||
UserGroups,
|
UserGroups,
|
||||||
)
|
)
|
||||||
|
if Replacement is not None and Match.group("PipeClip"):
|
||||||
|
Replacement = _ApplyClip(Replacement, Match.group("PipeClip"))
|
||||||
elif Match.group("LineNumber"):
|
elif Match.group("LineNumber"):
|
||||||
Replacement = _ResolveLineNumberReference(
|
Replacement = _ResolveLineNumberReference(
|
||||||
RootName,
|
RootName,
|
||||||
@@ -402,6 +458,8 @@ def ResolvePortals(
|
|||||||
Username,
|
Username,
|
||||||
UserGroups,
|
UserGroups,
|
||||||
)
|
)
|
||||||
|
if Replacement is not None and Match.group("LineClip"):
|
||||||
|
Replacement = _ApplyClip(Replacement, Match.group("LineClip"))
|
||||||
|
|
||||||
if Replacement is not None:
|
if Replacement is not None:
|
||||||
Output.append(LocallyResolved[Cursor : Match.start()])
|
Output.append(LocallyResolved[Cursor : Match.start()])
|
||||||
|
|||||||
Reference in new issue
Block a user