mirror of
https://git.srhtnin.garden/sarah/SaraView.git
synced 2026-10-13 18:28:14 +02:00
Added children, siblings, and parents as variables. Also % as for.
This commit is contained in:
1 parent
104198036a
commit
0cd98873e0
2 files changed
+109
-4
No files matched your search
+99
-2
@@ -3,12 +3,13 @@ from __future__ import annotations
|
||||
import re
|
||||
|
||||
from Core import NormalizeRelativePath, ResolvePath
|
||||
from Explorer import ClassifyFile, ListDirectory
|
||||
from Explorer import ClassifyFile, ListDirectory, NoteFilePrefix
|
||||
from Locks import IsPathAccessible
|
||||
from Preview import ReadTextFile
|
||||
|
||||
|
||||
PortalFileTypes = {"markdown", "text"}
|
||||
LoopSources = ("children", "siblings", "parents")
|
||||
|
||||
MarkerPattern = re.compile(
|
||||
r"\{(?:(?P<CrossPath>[^\s{}']+)\s+)?\*\*\*(?P<CrossName>[^\s*{}]+)"
|
||||
@@ -19,6 +20,11 @@ MarkerPattern = re.compile(
|
||||
r"|\{\*(?P<BlockName>[^\s*{}]+)\}"
|
||||
)
|
||||
|
||||
LoopMarkerPattern = re.compile(
|
||||
r"\{(?P<LoopSource>children|siblings|parents)\s+%\s+(?P<LoopVar>[A-Za-z_][A-Za-z0-9_]*)\}"
|
||||
r"|\{(?P<CloseSource>children|siblings|parents)\s+%\}"
|
||||
)
|
||||
|
||||
|
||||
def _LineBounds(Content: str, Position: int) -> tuple[int, int]:
|
||||
LineStart = Content.rfind("\n", 0, Position) + 1
|
||||
@@ -94,6 +100,95 @@ def _ResolveLocalPortals(Content: str) -> str:
|
||||
return "".join(Output)
|
||||
|
||||
|
||||
def _ListAccessibleEntryNames(
|
||||
RootName: str, DirectoryRelativePath: str, Username: str, UserGroups: list[str], Exclude: str | None
|
||||
) -> list[str]:
|
||||
if not IsPathAccessible(RootName, DirectoryRelativePath, Username, UserGroups):
|
||||
return []
|
||||
|
||||
try:
|
||||
Entries = ListDirectory(RootName, DirectoryRelativePath, False, False)
|
||||
except (ValueError, NotADirectoryError, FileNotFoundError):
|
||||
return []
|
||||
|
||||
Names: list[str] = []
|
||||
|
||||
for Entry in Entries:
|
||||
if Entry["Name"] == Exclude:
|
||||
continue
|
||||
|
||||
EntryPath = (
|
||||
f"{DirectoryRelativePath}/{Entry['Name']}" if DirectoryRelativePath else Entry["Name"]
|
||||
)
|
||||
|
||||
if IsPathAccessible(RootName, EntryPath, Username, UserGroups):
|
||||
Names.append(Entry["Name"])
|
||||
|
||||
return Names
|
||||
|
||||
|
||||
def _ComputeLoopLists(
|
||||
RootName: str, RelativePath: str, Username: str, UserGroups: list[str]
|
||||
) -> dict[str, list[str]]:
|
||||
FileName = RelativePath.rsplit("/", 1)[-1] if RelativePath else ""
|
||||
ParentDirectory = RelativePath.rsplit("/", 1)[0] if "/" in RelativePath else ""
|
||||
ParentBaseName = ParentDirectory.rsplit("/", 1)[-1] if ParentDirectory else ""
|
||||
|
||||
IsDirectoryNote = FileName.startswith(f"{NoteFilePrefix}{ParentBaseName}.")
|
||||
|
||||
Children = (
|
||||
_ListAccessibleEntryNames(RootName, ParentDirectory, Username, UserGroups, FileName)
|
||||
if IsDirectoryNote
|
||||
else []
|
||||
)
|
||||
Siblings = _ListAccessibleEntryNames(RootName, ParentDirectory, Username, UserGroups, FileName)
|
||||
Parents = [Segment for Segment in ParentDirectory.split("/") if Segment]
|
||||
|
||||
return {"children": Children, "siblings": Siblings, "parents": Parents}
|
||||
|
||||
|
||||
def _ResolveLoops(Content: str, Lists: dict[str, list[str]]) -> str:
|
||||
Matches = list(LoopMarkerPattern.finditer(Content))
|
||||
Output: list[str] = []
|
||||
Cursor = 0
|
||||
Index = 0
|
||||
|
||||
while Index < len(Matches):
|
||||
Match = Matches[Index]
|
||||
|
||||
if not Match.group("LoopSource"):
|
||||
Index += 1
|
||||
continue
|
||||
|
||||
Source = Match.group("LoopSource")
|
||||
LoopVar = Match.group("LoopVar")
|
||||
|
||||
CloseMatch = None
|
||||
for Candidate in Matches[Index + 1 :]:
|
||||
if Candidate.group("CloseSource") == Source:
|
||||
CloseMatch = Candidate
|
||||
break
|
||||
|
||||
BodyEnd = CloseMatch.start() if CloseMatch is not None else len(Content)
|
||||
BodyTemplate = Content[Match.end() : BodyEnd]
|
||||
Items = Lists.get(Source, [])
|
||||
VariablePattern = re.compile(rf"%{re.escape(LoopVar)}\b")
|
||||
|
||||
Rendered = "\n".join(VariablePattern.sub(Item, BodyTemplate) for Item in Items)
|
||||
|
||||
Output.append(Content[Cursor : Match.start()])
|
||||
Output.append(Rendered)
|
||||
Cursor = CloseMatch.end() if CloseMatch is not None else len(Content)
|
||||
|
||||
if CloseMatch is not None:
|
||||
Index = Matches.index(CloseMatch) + 1
|
||||
else:
|
||||
break
|
||||
|
||||
Output.append(Content[Cursor:])
|
||||
return "".join(Output)
|
||||
|
||||
|
||||
def _ReadAccessiblePortalSource(
|
||||
RootName: str, RelativePath: str, Username: str, UserGroups: list[str]
|
||||
) -> str | None:
|
||||
@@ -224,7 +319,9 @@ def _ResolveLineNumberReference(
|
||||
def ResolvePortals(
|
||||
RootName: str, RelativePath: str, Content: str, Username: str, UserGroups: list[str]
|
||||
) -> str:
|
||||
LocallyResolved = _ResolveLocalPortals(Content)
|
||||
LoopLists = _ComputeLoopLists(RootName, RelativePath, Username, UserGroups)
|
||||
WithLoopsResolved = _ResolveLoops(Content, LoopLists)
|
||||
LocallyResolved = _ResolveLocalPortals(WithLoopsResolved)
|
||||
RefererDirectory = RelativePath.rsplit("/", 1)[0] if "/" in RelativePath else ""
|
||||
|
||||
Matches = list(MarkerPattern.finditer(LocallyResolved))
|
||||
|
||||
+10
-2
@@ -239,7 +239,15 @@ export default function App() {
|
||||
const Created = await EnsureDirectoryNote(ActiveRoot, DirectoryPath);
|
||||
HandleSelectDirectoryNote(DirectoryPath, Created.Name, Created.FileType);
|
||||
} catch (Error) {
|
||||
SetErrorMessage(Error.message);
|
||||
HandleNavigateDirectory(DirectoryPath);
|
||||
}
|
||||
}
|
||||
|
||||
function HandleBreadcrumbNavigate(Path) {
|
||||
if (!Path) {
|
||||
HandleNavigateDirectory("");
|
||||
} else {
|
||||
OpenDirectoryNote(Path, null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -333,7 +341,7 @@ export default function App() {
|
||||
RootName={ActiveRoot}
|
||||
FilePath={ViewPath}
|
||||
IsDirectory={ViewIsDirectory || Boolean(ViewNoteFilePath)}
|
||||
OnNavigate={HandleNavigateDirectory}
|
||||
OnNavigate={HandleBreadcrumbNavigate}
|
||||
/>
|
||||
) : (
|
||||
<span />
|
||||
|
||||
Reference in new issue
Block a user