84 lines
2.7 KiB
Python
84 lines
2.7 KiB
Python
#!/usr/bin/env python3
|
|
"""Apply the two link-fix passes across /vault:
|
|
1. fix_map: [[OldTarget]] -> [[NewNote|OldTarget]] (preserves display text)
|
|
Also handles piped/heading variants: [[OldTarget|Display]] -> [[NewNote|Display]]
|
|
[[OldTarget#Heading]] -> [[NewNote#Heading]]
|
|
2. unlink_targets: [[Target]] -> Target (plain text, drop brackets)
|
|
Also handles piped: [[Target|Display]] -> Display
|
|
"""
|
|
import os, re, json, sys
|
|
|
|
VAULT = "/vault"
|
|
|
|
with open("/tmp/link_fix_map.json") as f:
|
|
FIX_MAP = json.load(f)
|
|
with open("/tmp/unlink_targets.json") as f:
|
|
UNLINK = set(json.load(f))
|
|
|
|
# Full link regex capturing target, optional #heading, optional |display
|
|
LINK_RE = re.compile(r'\[\[([^\]|#]+)(#[^\]|]*)?(\|[^\]]*)?\]\]')
|
|
|
|
def process_text(text):
|
|
changed = False
|
|
def repl(m):
|
|
nonlocal changed
|
|
target = m.group(1)
|
|
heading = m.group(2) or ""
|
|
pipe_display = m.group(3) # includes leading |
|
|
target_stripped = target.strip()
|
|
|
|
if target_stripped in FIX_MAP:
|
|
new_target = FIX_MAP[target_stripped]
|
|
changed = True
|
|
if pipe_display:
|
|
# keep existing custom display text
|
|
return f"[[{new_target}{heading}{pipe_display}]]"
|
|
else:
|
|
# preserve original text as display so prose doesn't change visually
|
|
return f"[[{new_target}{heading}|{target_stripped}]]"
|
|
|
|
if target_stripped in UNLINK:
|
|
changed = True
|
|
if pipe_display:
|
|
display = pipe_display[1:] # strip leading |
|
|
return display
|
|
else:
|
|
return target_stripped
|
|
|
|
return m.group(0) # unchanged
|
|
|
|
new_text = LINK_RE.sub(repl, text)
|
|
return new_text, changed
|
|
|
|
def main():
|
|
execute = "--execute" in sys.argv
|
|
files_changed = 0
|
|
total_fix_applied = 0
|
|
total_unlink_applied = 0
|
|
|
|
for dp, _, fns in os.walk(VAULT):
|
|
if ".git" in dp.split(os.sep):
|
|
continue
|
|
for fn in fns:
|
|
if not fn.lower().endswith(".md"):
|
|
continue
|
|
p = os.path.join(dp, fn)
|
|
try:
|
|
with open(p, "r", encoding="utf-8", errors="ignore") as f:
|
|
text = f.read()
|
|
except Exception:
|
|
continue
|
|
new_text, changed = process_text(text)
|
|
if changed:
|
|
files_changed += 1
|
|
if execute:
|
|
with open(p, "w", encoding="utf-8") as f:
|
|
f.write(new_text)
|
|
|
|
print(f"Files changed: {files_changed}")
|
|
if not execute:
|
|
print("(dry run -- pass --execute to write)")
|
|
|
|
if __name__ == "__main__":
|
|
main()
|