77 lines
1.8 KiB
Python
Executable File
77 lines
1.8 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
import os
|
|
import re
|
|
from pathlib import Path
|
|
|
|
VAULT_PATH = os.path.expanduser("~/gdrive/your_vault_here")
|
|
|
|
vault = Path(VAULT_PATH)
|
|
|
|
wiki_link_re = re.compile(r"\[\[([^\]|#]+)")
|
|
markdown_link_re = re.compile(r"\[[^\]]+\]\(([^)#]+)")
|
|
|
|
existing_pages = {}
|
|
|
|
for md in vault.rglob("*.md"):
|
|
existing_pages[md.stem.lower()] = md
|
|
|
|
created = []
|
|
|
|
for md in vault.rglob("*.md"):
|
|
try:
|
|
text = md.read_text(encoding="utf-8")
|
|
except Exception as e:
|
|
print(f"Could not read {md}: {e}")
|
|
continue
|
|
|
|
links = []
|
|
|
|
# [[Page]] or [[Page|alias]]
|
|
links.extend(wiki_link_re.findall(text))
|
|
|
|
# [title](Page.md)
|
|
links.extend(markdown_link_re.findall(text))
|
|
|
|
for link in links:
|
|
link = link.strip()
|
|
|
|
if not link:
|
|
continue
|
|
|
|
# Ignore web/email/anchor links
|
|
if link.startswith(("http://", "https://", "mailto:", "#")):
|
|
continue
|
|
|
|
# Strip anchor sections
|
|
link = link.split("#", 1)[0]
|
|
|
|
# Remove .md if already present
|
|
if link.lower().endswith(".md"):
|
|
link = link[:-3]
|
|
|
|
target = vault / f"{link}.md"
|
|
|
|
# Obsidian-style loose match by page name
|
|
if Path(link).name.lower() in existing_pages:
|
|
continue
|
|
|
|
if target.exists():
|
|
continue
|
|
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
title = Path(link).name
|
|
dummy_text = f"# {title}\n"
|
|
|
|
try:
|
|
target.write_text(dummy_text, encoding="utf-8")
|
|
existing_pages[target.stem.lower()] = target
|
|
created.append(target)
|
|
print(f"Created: {target}")
|
|
except Exception as e:
|
|
print(f"Failed to create {target}: {e}")
|
|
|
|
print()
|
|
print(f"Done. Created {len(created)} missing pages.")
|