114 lines
3.3 KiB
Python
114 lines
3.3 KiB
Python
import json
|
|
import re
|
|
from pathlib import Path
|
|
|
|
def get_org_id_and_title(file_path):
|
|
"""Extract ID and TITLE from an Org file."""
|
|
id_pattern = re.compile(r"^:ID:\s*(.+)", re.MULTILINE)
|
|
title_pattern = re.compile(r"^#\+title:\s*(.+)", re.IGNORECASE | re.MULTILINE)
|
|
|
|
content = file_path.read_text(encoding="utf-8", errors="ignore")
|
|
|
|
id_match = id_pattern.search(content)
|
|
title_match = title_pattern.search(content)
|
|
|
|
org_id = id_match.group(1).strip() if id_match else None
|
|
title = title_match.group(1).strip() if title_match else "Untitled"
|
|
|
|
return org_id, title
|
|
|
|
|
|
def generate_search_index(org_dir, out_file):
|
|
"""Generate search-index.json with title, url, and id."""
|
|
print("🔍 Generating search-index.json...")
|
|
|
|
org_dir = Path(org_dir).expanduser()
|
|
out_file = Path(out_file).expanduser()
|
|
|
|
org_files = [
|
|
f for f in org_dir.rglob("*.org")
|
|
if not re.search(r"/\.#[^/]+\.org$", str(f))
|
|
]
|
|
|
|
index = []
|
|
for file_path in org_files:
|
|
org_id, title = get_org_id_and_title(file_path)
|
|
filepath_relative = file_path.relative_to(org_dir).with_suffix('')
|
|
|
|
if org_id:
|
|
index.append({
|
|
"title": title,
|
|
"url": f"/{filepath_relative}.html",
|
|
"id": org_id
|
|
})
|
|
|
|
# De-duplicate by ID
|
|
seen_ids = set()
|
|
unique_index = []
|
|
for entry in index:
|
|
if entry["id"] not in seen_ids:
|
|
unique_index.append(entry)
|
|
seen_ids.add(entry["id"])
|
|
|
|
# Ensure output directory exists
|
|
out_file.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
# Write JSON
|
|
with open(out_file, "w", encoding="utf-8") as f:
|
|
json.dump(unique_index, f, ensure_ascii=False, indent=2)
|
|
|
|
print(f"✅ search-index.json generated ({len(unique_index)} entries).")
|
|
|
|
|
|
def generate_all_files_json(search_index_file, out_file):
|
|
"""Generate all-files.json from search-index.json."""
|
|
search_index_file = Path(search_index_file).expanduser()
|
|
out_file = Path(out_file).expanduser()
|
|
|
|
# Load data
|
|
with open(search_index_file, "r", encoding="utf-8") as f:
|
|
data = json.load(f)
|
|
|
|
print(f"🔎 Loaded {len(data)} entries from {search_index_file}")
|
|
|
|
# Sort alphabetically
|
|
data.sort(key=lambda x: x.get("title", "").lower())
|
|
|
|
# Group by first letter
|
|
grouped = {}
|
|
for entry in data:
|
|
title = entry.get("title", "")
|
|
if not title:
|
|
continue
|
|
letter = title[0].upper()
|
|
grouped.setdefault(letter, []).append({
|
|
"id": entry["id"],
|
|
"title": title,
|
|
"url": entry["url"]
|
|
})
|
|
|
|
# Output structure
|
|
output = {
|
|
"title": "All Files",
|
|
"description": "A complete alphabetical index of all published pages.",
|
|
"groups": grouped,
|
|
}
|
|
|
|
with open(out_file, "w", encoding="utf-8") as f:
|
|
json.dump(output, f, ensure_ascii=False, indent=2)
|
|
|
|
print(f"✅ all-files.json generated → {out_file}")
|
|
|
|
|
|
def main():
|
|
base_dir = Path.home() / "master-folder" / "org_files" / "org_roam"
|
|
search_index = base_dir / "output" / "search-index.json"
|
|
all_files_json = base_dir / "all-files.json"
|
|
|
|
generate_search_index(base_dir, search_index)
|
|
generate_all_files_json(search_index, all_files_json)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|