Węzły konceptów w grafie linkują do kart HTML w pages/

Panel szczegółów renderuje pole `resource` jako klikalny odnośnik
(viz.js:171-183), więc ustawienie tam ścieżki pages/<id>.html daje
przejście z grafu do pełnej treści dokumentu — zero zmian w viewerze.
Ścieżka jest względna wobec viz.html, więc działa lokalnie i po deployu.

Węzły external zachowują swoje URL-e (podmiana leci przed dołożeniem
węzłów zewnętrznych). Jeśli koncept miałby własny `resource` we
frontmatterze, trafia do danych węzła jako `resource_frontmatter`.

Zmiana wyłącznie w window.BUNDLE — pliki .md nietknięte, check_okf.py
nadal zielony.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
oskar 2026-07-31 18:47:00 +02:00
parent c4f6cf3f1d
commit e8163d3800
2 changed files with 45 additions and 2 deletions

View file

@ -27,6 +27,12 @@ panel szczegółów renderuje `resource` jako klikalny odnośnik z
`target="_blank"` (viz.js:171-183) to daje "klik otwiera URL w nowej `target="_blank"` (viz.js:171-183) to daje "klik otwiera URL w nowej
karcie" bez żadnej zmiany w viewerze. karcie" bez żadnej zmiany w viewerze.
Węzły konceptów mają w `resource` ścieżkę do karty HTML w `pages/`
(generowanej przez gen_pages.py) ten sam mechanizm panelu szczegółów daje
przejście z grafu do pełnej treści dokumentu. Jeśli koncept ma własne pole
`resource` we frontmatterze, ląduje ono w danych węzła jako
`resource_frontmatter`.
Skąd brane adresy cztery niezależne źródła, każde da się wyłączyć Skąd brane adresy cztery niezależne źródła, każde da się wyłączyć
osobno stałą `SOURCES`: osobno stałą `SOURCES`:
@ -81,6 +87,9 @@ except ModuleNotFoundError as exc: # pragma: no cover
RESERVED = {"index.md", "log.md"} RESERVED = {"index.md", "log.md"}
# Karty HTML konceptów generowane przez gen_pages.py.
PAGES_DIRNAME = "pages"
# --- konfiguracja linków zewnętrznych --------------------------------- # --- konfiguracja linków zewnętrznych ---------------------------------
SOURCES = ("md-link", "bare-url", "bare-domain", "frontmatter") SOURCES = ("md-link", "bare-url", "bare-domain", "frontmatter")
@ -272,6 +281,33 @@ def _add_external(graph: dict, concepts: list) -> None:
graph["palette"] = {**graph.get("palette", {}), EXTERNAL_TYPE: EXTERNAL_COLOR} graph["palette"] = {**graph.get("palette", {}), EXTERNAL_TYPE: EXTERNAL_COLOR}
MISSING_PAGES: list[str] = []
def _point_concepts_to_pages(graph: dict) -> None:
"""Węzeł koncept → karta HTML w pages/.
Panel szczegółów renderuje `resource` jako klikalny odnośnik
(viz.js:171-183), więc ustawienie tam ścieżki karty daje przejście
z grafu do pełnej treści bez żadnej zmiany w viewerze. Ścieżka jest
względna wobec viz.html, czyli działa i lokalnie, i po deployu.
Wywoływane przed _add_external na tym etapie w grafie wyłącznie
węzły konceptów, więc URL-e węzłów external nie nadpisywane.
"""
for node in graph["nodes"]:
data = node["data"]
original = data.get("resource") or ""
if original:
# Koncept miał własny `resource` we frontmatterze — nie gubimy go,
# tylko przenosimy obok; `resource` węzła wskazuje kartę.
data["resource_frontmatter"] = original
page = f"{PAGES_DIRNAME}/{data['id']}.html"
data["resource"] = page
if not (BUNDLE_ROOT / page).is_file():
MISSING_PAGES.append(page)
# --- jedyna ingerencja w viewer --------------------------------------- # --- jedyna ingerencja w viewer ---------------------------------------
# #
# Kolor węzła jest sterowany danymi ("background-color": "data(color)"), # Kolor węzła jest sterowany danymi ("background-color": "data(color)"),
@ -358,8 +394,9 @@ def _walk_concepts(bundle_root: Path):
def _build_graph(concepts: list) -> dict: def _build_graph(concepts: list) -> dict:
"""Upstream + węzły/krawędzie linków zewnętrznych.""" """Upstream + karty HTML konceptów + węzły/krawędzie linków zewnętrznych."""
graph = _upstream_build_graph(concepts) graph = _upstream_build_graph(concepts)
_point_concepts_to_pages(graph)
_add_external(graph, concepts) _add_external(graph, concepts)
return graph return graph
@ -380,6 +417,12 @@ def main() -> int:
f" węzły: {stats['concepts']} konceptów + {external} external, " f" węzły: {stats['concepts']} konceptów + {external} external, "
f"krawędzie: {stats['edges']}, rozmiar: {stats['bytes'] / 1024:.1f} KiB" f"krawędzie: {stats['edges']}, rozmiar: {stats['bytes'] / 1024:.1f} KiB"
) )
print(f" koncepty linkują do kart w {PAGES_DIRNAME}/ (pole resource)")
if MISSING_PAGES:
print(
f" UWAGA: brakuje {len(MISSING_PAGES)} kart — uruchom "
f"gen_pages.py: {', '.join(MISSING_PAGES)}"
)
print() print()
print(f"Linki zewnętrzne, które weszły do grafu ({external}):") print(f"Linki zewnętrzne, które weszły do grafu ({external}):")
for url, origins, sources in REPORT["kept"]: for url, origins, sources in REPORT["kept"]:

File diff suppressed because one or more lines are too long