wiki: sanitize Windows-reserved characters in filenames (#594)

On Windows, to_wiki crashes with OSError [Errno 22] when a node label
contains any of < > : " / \ | ? * (Windows reserved chars in
filenames). Repro: an Obsidian note titled "Czy Wii jeszcze ok?.md"
becomes a community label, then write_text fails because Windows
rejects the question mark in the path.

The previous _safe_filename only handled three characters (/ space :)
which is enough on Linux/macOS but not on Windows. Extended the
substitution to cover all Windows-reserved chars plus trailing dots
and spaces (also reserved on Windows), and added a 200-char length
cap to stay well under MAX_PATH-segment limits.

Falls back to 'unnamed' if sanitization produces an empty string,
so we never try to create a file named "" or ".".

Tested on a 1773-file vault with mixed Polish/English content where
~12 community labels and several god node labels contained reserved
characters. Generates 763 wiki articles cleanly.
This commit is contained in:
cod3warrior
2026-05-02 15:15:09 +02:00
committed by GitHub
parent b9871d7019
commit fd0ebb5957
+12 -1
View File
@@ -7,7 +7,18 @@ import networkx as nx
def _safe_filename(name: str) -> str:
return name.replace("/", "-").replace(" ", "_").replace(":", "-")
"""Make a label safe for use as a filename across platforms.
Substitutes characters that Windows reserves in filenames
(< > : " / \\ | ? *) and strips trailing dots/spaces, also reserved.
Falls back to 'unnamed' for empty results and caps length at 200
chars to stay well under common filesystem limits.
"""
import re
s = name.replace("/", "-").replace(" ", "_").replace(":", "-")
s = re.sub(r'[<>:"/\\|?*]', '_', s)
s = s.strip('. ')
return s[:200] if s else 'unnamed'
def _cross_community_links(G: nx.Graph, nodes: list[str], own_cid: int, labels: dict[int, str]) -> list[tuple[str, int]]: