notes/conv_obsidian.py
2026-05-07 16:55:00 +01:00

72 lines
1.8 KiB
Python

#!/usr/bin/env python3
import re
from pathlib import Path
from urllib.parse import quote
root = Path(".").resolve()
def find_note(target):
"""Find target.md anywhere in the tree."""
target = target.strip()
target = target.split("#")[0].split("|")[0].strip()
if not target.endswith(".md"):
target += ".md"
matches = list(root.rglob(target))
if matches:
return matches[0]
return None
def convert_link(match, current_file):
raw = match.group(1).strip()
# Ignore embeds for now: ![[image.png]]
if raw.lower().endswith((".png", ".jpg", ".jpeg", ".gif", ".pdf")):
return match.group(0)
# Obsidian alias: [[PID|my PID note]]
if "|" in raw:
target, label = raw.split("|", 1)
label = label.strip()
else:
target = raw
label = raw.split("#")[0].strip()
# Obsidian heading link: [[PID#Some heading]]
if "#" in target:
filename, heading = target.split("#", 1)
anchor = "#" + quote(heading.strip().lower().replace(" ", "-"))
else:
filename = target
anchor = ""
found = find_note(filename)
if found:
rel = found.relative_to(current_file.parent.resolve())
link = quote(str(rel).replace("\\", "/"))
return f"[{label}]({link}{anchor})"
# Fallback: assume same directory
fallback = filename.strip()
if not fallback.endswith(".md"):
fallback += ".md"
fallback = quote(fallback)
return f"[{label}]({fallback}{anchor})"
for md in root.rglob("*.md"):
text = md.read_text(encoding="utf-8", errors="ignore")
# Convert [[...]] but not ![[...]]
new_text = re.sub(
r"(?<!!)\[\[([^\]]+)\]\]",
lambda m: convert_link(m, md),
text
)
if new_text != text:
md.write_text(new_text, encoding="utf-8")
print(f"fixed {md}")
print("Done.")