chore: initialize homebrew-magic-rpg monorepo
Consolidates the HbM: RPG project (formerly the loose hbm-books working folder) into a single repo. ObsidianNotes, foundry-lore, and foundry-system are wired in as submodules pointing at their existing Gitea repos. Loose tooling scripts are organized under tools/, obsolete/one-off scripts (fix_vault.py, generate_mocs.py, debug-*.ts, write_file_helper.py) and _books/ (superseded by ObsidianNotes) are excluded via .gitignore rather than deleted. foundryvtt-admin is excluded pending its own separate repo.
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
import os
|
||||
import re
|
||||
import json
|
||||
|
||||
VAULT_DIR = "ObsidianNotes"
|
||||
|
||||
def main():
|
||||
if not os.path.exists(VAULT_DIR):
|
||||
print(json.dumps({"error": f"Directory {VAULT_DIR} not found."}))
|
||||
return
|
||||
|
||||
md_files = {} # filename (without .md) -> relative path
|
||||
for root, dirs, files in os.walk(VAULT_DIR):
|
||||
for file in files:
|
||||
if file.endswith(".md"):
|
||||
name = file[:-3]
|
||||
rel_path = os.path.relpath(os.path.join(root, file), VAULT_DIR)
|
||||
md_files[name] = rel_path
|
||||
|
||||
links = {} # source file rel_path -> list of target link names
|
||||
broken_links = [] # list of (source file rel_path, broken link name)
|
||||
incoming_links = {name: [] for name in md_files.keys()} # target name -> list of source file rel_paths
|
||||
|
||||
link_pattern = re.compile(r'\[\[(.*?)\]\]')
|
||||
|
||||
for name, rel_path in md_files.items():
|
||||
full_path = os.path.join(VAULT_DIR, rel_path)
|
||||
try:
|
||||
with open(full_path, 'r', encoding='utf-8') as f:
|
||||
content = f.read()
|
||||
except Exception as e:
|
||||
print(f"Error reading {rel_path}: {e}")
|
||||
continue
|
||||
|
||||
file_links = link_pattern.findall(content)
|
||||
parsed_links = []
|
||||
for raw_link in file_links:
|
||||
# Handle aliases [[Link|Alias]] and headings [[Link#Heading]]
|
||||
base_link = raw_link.split('|')[0].split('#')[0].strip()
|
||||
if not base_link:
|
||||
continue
|
||||
parsed_links.append(base_link)
|
||||
|
||||
# Check if it exists
|
||||
link_basename = os.path.basename(base_link)
|
||||
if link_basename.endswith('.md'):
|
||||
link_basename = link_basename[:-3]
|
||||
|
||||
if link_basename in md_files:
|
||||
incoming_links[link_basename].append(rel_path)
|
||||
else:
|
||||
broken_links.append((rel_path, base_link))
|
||||
|
||||
links[rel_path] = parsed_links
|
||||
|
||||
orphans = [rel_path for name, rel_path in md_files.items() if len(incoming_links[name]) == 0]
|
||||
|
||||
report = {
|
||||
"total_files": len(md_files),
|
||||
"total_links": sum(len(l) for l in links.values()),
|
||||
"broken_links_count": len(broken_links),
|
||||
"orphans_count": len(orphans),
|
||||
"broken_links": broken_links,
|
||||
"orphans": orphans
|
||||
}
|
||||
|
||||
with open("vault_analysis_report.json", "w", encoding="utf-8") as f:
|
||||
json.dump(report, f, indent=2)
|
||||
|
||||
print("Analysis complete. Check vault_analysis_report.json")
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user