initial version

This commit is contained in:
Ignacio Ballesteros
2026-02-14 09:09:54 +01:00
commit 3738d1d7d8
16 changed files with 1037 additions and 0 deletions

141
src/org_to_quartz/main.py Normal file
View File

@@ -0,0 +1,141 @@
"""CLI entry point for org-to-quartz converter."""
import argparse
import sys
from pathlib import Path
from .org_parser import parse_org_file
from .markdown_writer import convert_document, write_markdown
from .image_handler import copy_images, update_image_paths
from .citations import CitationResolver
def find_org_files(input_dir: Path) -> list[Path]:
"""Find all .org files in directory (non-recursive)."""
return list(input_dir.glob("*.org"))
def convert_file(
org_path: Path,
output_dir: Path,
citation_resolver: CitationResolver | None,
verbose: bool = False,
) -> Path | None:
"""Convert a single org file to Quartz markdown.
Returns:
Path to created note directory, or None on error
"""
try:
# Parse org file
doc = parse_org_file(org_path)
if verbose:
print(f" Parsed: {doc.title or org_path.stem}")
# Create output directory for this note
note_dir = output_dir / doc.slug
note_dir.mkdir(parents=True, exist_ok=True)
# Copy images first (before conversion, to get path mapping)
image_mapping = copy_images(doc, output_dir)
if verbose and image_mapping:
print(f" Copied {len(image_mapping)} images")
# Convert document
md_content = convert_document(doc, citation_resolver)
# Update image paths in converted content
md_content = update_image_paths(md_content, image_mapping)
# Write output
output_path = note_dir / "index.md"
output_path.write_text(md_content, encoding="utf-8")
return note_dir
except Exception as e:
print(f" Error converting {org_path.name}: {e}", file=sys.stderr)
return None
def main() -> int:
"""Main CLI entry point."""
parser = argparse.ArgumentParser(
prog="org-to-quartz",
description="Convert org-mode notes to Quartz-compatible markdown",
)
parser.add_argument(
"input_dir",
type=Path,
help="Directory containing .org files",
)
parser.add_argument(
"output_dir",
type=Path,
help="Output directory (e.g., quartz/content)",
)
parser.add_argument(
"--bib",
type=Path,
metavar="FILE",
help="Path to .bib file for citation resolution",
)
parser.add_argument(
"-v", "--verbose",
action="store_true",
help="Verbose output",
)
args = parser.parse_args()
# Validate input directory
if not args.input_dir.is_dir():
print(f"Error: Input directory does not exist: {args.input_dir}", file=sys.stderr)
return 1
# Create output directory
args.output_dir.mkdir(parents=True, exist_ok=True)
# Find org files
org_files = find_org_files(args.input_dir)
if not org_files:
print(f"No .org files found in {args.input_dir}", file=sys.stderr)
return 1
print(f"Found {len(org_files)} org files")
# Initialize citation resolver
citation_resolver = CitationResolver(args.bib)
if args.verbose:
if citation_resolver.zotero.is_available():
print("Zotero Better BibTeX: available")
else:
print("Zotero Better BibTeX: not available")
if args.bib:
print(f"BibTeX file: {args.bib}")
# Convert each file
success_count = 0
error_count = 0
for org_path in org_files:
print(f"Converting: {org_path.name}")
result = convert_file(org_path, args.output_dir, citation_resolver, args.verbose)
if result:
success_count += 1
if args.verbose:
print(f" -> {result}")
else:
error_count += 1
# Summary
print(f"\nDone: {success_count} converted, {error_count} errors")
return 0 if error_count == 0 else 1
if __name__ == "__main__":
sys.exit(main())