fix(export_docs): sidebar folder tree follows parent/child paths
Render _Sidebar entries in DFS order instead of sorting by depth globally. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -2,6 +2,12 @@
|
|||||||
|
|
||||||
All notable changes to **export_1c_help** are documented in this file.
|
All notable changes to **export_1c_help** are documented in this file.
|
||||||
|
|
||||||
|
## [0.3.12] - 2026-07-29
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- `_Sidebar` folder tree: list subfolders under their real parent (DFS), not as a flat sort by depth (which made e.g. `transfer/mapping` appear under `ws`).
|
||||||
|
|
||||||
## [0.3.11] - 2026-07-29
|
## [0.3.11] - 2026-07-29
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
|||||||
@@ -344,32 +344,28 @@ def _docs_index_rel(folder: str, managed_files: set[str]) -> str | None:
|
|||||||
|
|
||||||
def _sidebar_folder_links(folder: str, managed_files: set[str]) -> list[tuple[int, str, str]]:
|
def _sidebar_folder_links(folder: str, managed_files: set[str]) -> list[tuple[int, str, str]]:
|
||||||
"""
|
"""
|
||||||
Return (depth, label, target) for folder index pages in wiki.
|
Return (depth, label, target) for folder index pages in wiki, in tree order.
|
||||||
|
|
||||||
Supports both:
|
Supports both:
|
||||||
- nested mode: docs/sub/INDEX.md
|
- nested mode: docs/sub/INDEX.md
|
||||||
- flat mode: docs__sub__INDEX.md
|
- flat mode: docs__sub__INDEX.md
|
||||||
"""
|
"""
|
||||||
folder_clean = folder.strip().strip("/").strip("\\")
|
folder_clean = folder.strip().strip("/").strip("\\")
|
||||||
rows: list[tuple[int, str, str]] = []
|
|
||||||
|
|
||||||
if not folder_clean:
|
if not folder_clean:
|
||||||
return rows
|
return []
|
||||||
|
|
||||||
|
target_by_folder: dict[str, str] = {}
|
||||||
|
|
||||||
# nested mode
|
|
||||||
for rel in managed_files:
|
for rel in managed_files:
|
||||||
if not rel.endswith("/INDEX.md"):
|
if not rel.endswith("/INDEX.md"):
|
||||||
continue
|
continue
|
||||||
if not rel.startswith(folder_clean + "/"):
|
if rel.startswith(folder_clean + "/"):
|
||||||
continue
|
folder_rel = rel[: -len("/INDEX.md")]
|
||||||
folder_rel = rel[: -len("/INDEX.md")]
|
target_by_folder[folder_rel] = rel
|
||||||
depth = max(folder_rel.count("/") - folder_clean.count("/"), 0)
|
|
||||||
rows.append((depth, folder_rel, rel))
|
|
||||||
|
|
||||||
# flat mode
|
|
||||||
root_flat = f"{folder_clean}__INDEX.md"
|
root_flat = f"{folder_clean}__INDEX.md"
|
||||||
if root_flat in managed_files:
|
if root_flat in managed_files:
|
||||||
rows.append((0, folder_clean, root_flat))
|
target_by_folder[folder_clean] = root_flat
|
||||||
prefix = f"{folder_clean}__"
|
prefix = f"{folder_clean}__"
|
||||||
suffix = "__INDEX.md"
|
suffix = "__INDEX.md"
|
||||||
for rel in managed_files:
|
for rel in managed_files:
|
||||||
@@ -379,14 +375,34 @@ def _sidebar_folder_links(folder: str, managed_files: set[str]) -> list[tuple[in
|
|||||||
if not mid:
|
if not mid:
|
||||||
continue
|
continue
|
||||||
folder_rel = folder_clean + "/" + mid.replace("__", "/")
|
folder_rel = folder_clean + "/" + mid.replace("__", "/")
|
||||||
depth = max(folder_rel.count("/") - folder_clean.count("/"), 0)
|
target_by_folder[folder_rel] = rel
|
||||||
rows.append((depth, folder_rel, rel))
|
|
||||||
|
|
||||||
# dedupe by target
|
if not target_by_folder:
|
||||||
uniq: dict[str, tuple[int, str, str]] = {}
|
return []
|
||||||
for row in rows:
|
|
||||||
uniq[row[2]] = row
|
children: dict[str, list[str]] = {}
|
||||||
return sorted(uniq.values(), key=lambda x: (x[0], x[1].casefold()))
|
for folder_rel in target_by_folder:
|
||||||
|
if folder_rel == folder_clean:
|
||||||
|
continue
|
||||||
|
parent = Path(folder_rel).parent.as_posix()
|
||||||
|
if parent != folder_clean and not parent.startswith(folder_clean + "/"):
|
||||||
|
parent = folder_clean
|
||||||
|
children.setdefault(parent, []).append(folder_rel)
|
||||||
|
|
||||||
|
ordered: list[tuple[int, str, str]] = []
|
||||||
|
|
||||||
|
def walk(parent: str, depth: int) -> None:
|
||||||
|
for child in sorted(children.get(parent, []), key=lambda x: x.casefold()):
|
||||||
|
ordered.append((depth, child, target_by_folder[child]))
|
||||||
|
walk(child, depth + 1)
|
||||||
|
|
||||||
|
if folder_clean in target_by_folder:
|
||||||
|
ordered.append((0, folder_clean, target_by_folder[folder_clean]))
|
||||||
|
walk(folder_clean, 1)
|
||||||
|
else:
|
||||||
|
walk(folder_clean, 0)
|
||||||
|
|
||||||
|
return ordered
|
||||||
|
|
||||||
|
|
||||||
def ensure_root_navigation(
|
def ensure_root_navigation(
|
||||||
|
|||||||
Reference in New Issue
Block a user