From 778579c04f7d5820b50b95d7c1ee161c0dca272d Mon Sep 17 00:00:00 2001 From: SRHTNIN Date: Mon, 21 Sep 2026 18:52:35 +0200 Subject: [PATCH] Added head and tail functions. They work with portals: {./Example.md ***portalname head 2} --- Backend/Portals.py | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/Backend/Portals.py b/Backend/Portals.py index 9872912..c6c81ad 100644 --- a/Backend/Portals.py +++ b/Backend/Portals.py @@ -11,7 +11,9 @@ from Preview import ReadTextFile PortalFileTypes = {"markdown", "text"} MarkerPattern = re.compile( - r"\{(?:(?P[^\s{}']+)\s+)?\*\*\*(?P[^\s*{}]+)\}" + r"\{(?:(?P[^\s{}']+)\s+)?\*\*\*(?P[^\s*{}]+)" + r"(?:\s+(?Phead|tail)\s+(?P\d+))?\}" + r"|\{(?P[^\s{}']+)\s+(?Phead|tail)\s+(?P\d+)\}" r"|\{(?P[^\s{}']+)\s+'(?P\d+)'\}" r"|\{\*\*(?P[^\s*{}]+)\}" r"|\{\*(?P[^\s*{}]+)\}" @@ -188,6 +190,30 @@ def _ResolveCrossFileReference( return _FindLocalDefinitions(Content).get(Name) +def _ApplyPipe(Text: str, Mode: str, Count: int) -> str: + Lines = Text.splitlines() + Selected = Lines[:Count] if Mode == "head" else Lines[-Count:] if Count > 0 else [] + return "\n".join(Selected) + + +def _ResolveWholeFilePipe( + RootName: str, + RefererDirectory: str, + PathText: str, + Mode: str, + Count: int, + Username: str, + UserGroups: list[str], +) -> str | None: + TargetRelativePath = _NormalizeRelativePath(RefererDirectory, PathText) + Content = _ReadAccessiblePortalSource(RootName, TargetRelativePath, Username, UserGroups) + + if Content is None: + return None + + return _ApplyPipe(_ResolveLocalPortals(Content), Mode, Count) + + def _ResolveLineNumberReference( RootName: str, RefererDirectory: str, @@ -233,6 +259,20 @@ def ResolvePortals( Username, UserGroups, ) + if Replacement is not None and Match.group("CrossPipe"): + Replacement = _ApplyPipe( + Replacement, Match.group("CrossPipe"), int(Match.group("CrossPipeCount")) + ) + elif Match.group("PipeMode"): + Replacement = _ResolveWholeFilePipe( + RootName, + RefererDirectory, + Match.group("PipePath"), + Match.group("PipeMode"), + int(Match.group("PipeCount")), + Username, + UserGroups, + ) elif Match.group("LineNumber"): Replacement = _ResolveLineNumberReference( RootName,