Loading...
No commits yet
Not committed History
Blame
compile.py • 6.0 KB
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Timestamp: 2026-01-27
# File: src/scitex_writer/_cli/compile.py

"""Compile CLI commands."""

import argparse
import sys
from pathlib import Path


def cmd_manuscript(args: argparse.Namespace) -> int:
    """Compile manuscript to PDF."""
    from .. import compile

    project = Path(args.project).resolve()
    if not project.exists():
        print(f"Error: Project not found: {project}", file=sys.stderr)
        return 1

    result = compile.manuscript(
        str(project),
        draft=args.draft,
        no_figs=args.no_figs,
        no_tables=args.no_tables,
        no_diff=args.no_diff,
        engine=args.engine,
    )

    if result["success"]:
        print(f"PDF: {result['pdf_path']}")
        return 0
    else:
        print(f"Error: {result['error']}", file=sys.stderr)
        return 1


def cmd_supplementary(args: argparse.Namespace) -> int:
    """Compile supplementary materials to PDF."""
    from .. import compile

    project = Path(args.project).resolve()
    if not project.exists():
        print(f"Error: Project not found: {project}", file=sys.stderr)
        return 1

    result = compile.supplementary(
        str(project),
        draft=args.draft,
        engine=args.engine,
    )

    if result["success"]:
        print(f"PDF: {result['pdf_path']}")
        return 0
    else:
        print(f"Error: {result['error']}", file=sys.stderr)
        return 1


def cmd_revision(args: argparse.Namespace) -> int:
    """Compile revision letter to PDF."""
    from .. import compile

    project = Path(args.project).resolve()
    if not project.exists():
        print(f"Error: Project not found: {project}", file=sys.stderr)
        return 1

    result = compile.revision(
        str(project),
        track_changes=args.track_changes,
        engine=args.engine,
    )

    if result["success"]:
        print(f"PDF: {result['pdf_path']}")
        return 0
    else:
        print(f"Error: {result['error']}", file=sys.stderr)
        return 1


def cmd_content(args: argparse.Namespace) -> int:
    """Compile raw LaTeX content to PDF."""
    from .. import compile

    # Read content from file or stdin
    if args.file:
        content_path = Path(args.file)
        if not content_path.exists():
            print(f"Error: File not found: {content_path}", file=sys.stderr)
            return 1
        latex_content = content_path.read_text(encoding="utf-8")
    else:
        latex_content = sys.stdin.read()

    project_dir = str(Path(args.project).resolve()) if args.project else None

    result = compile.content(
        latex_content,
        project_dir=project_dir,
        color_mode=args.color_mode,
        name=args.name,
        timeout=args.timeout,
        keep_aux=args.keep_aux,
    )

    if result["success"]:
        print(f"PDF: {result['output_pdf']}")
        return 0
    else:
        print(f"Error: {result.get('error', 'Unknown error')}", file=sys.stderr)
        if result.get("log"):
            print(f"Log: {result['log'][-500:]}", file=sys.stderr)
        return 1


def register_parser(subparsers) -> argparse.ArgumentParser:
    """Register compile subcommand parser."""
    compile_help = """Compile LaTeX documents to PDF.

Quick start:
  scitex-writer compile manuscript           # Compile manuscript
  scitex-writer compile manuscript --draft   # Fast single-pass
  scitex-writer compile supplementary        # Compile supplementary
  scitex-writer compile revision             # Compile revision letter
  scitex-writer compile content -f intro.tex  # Compile content with color modes
  echo '\\section{Test}' | scitex-writer compile content --color-mode dark
"""
    parser = subparsers.add_parser(
        "compile",
        help="Compile LaTeX to PDF",
        description=compile_help,
        formatter_class=argparse.RawDescriptionHelpFormatter,
    )
    sub = parser.add_subparsers(dest="compile_command", title="Commands")

    # manuscript
    ms = sub.add_parser("manuscript", help="Compile manuscript")
    ms.add_argument("-p", "--project", default=".", help="Project path")
    ms.add_argument("--draft", action="store_true", help="Fast single-pass mode")
    ms.add_argument("--no-figs", action="store_true", help="Skip figures")
    ms.add_argument("--no-tables", action="store_true", help="Skip tables")
    ms.add_argument("--no-diff", action="store_true", help="Skip diff generation")
    ms.add_argument(
        "--engine", choices=["tectonic", "latexmk", "3pass"], help="LaTeX engine"
    )
    ms.set_defaults(func=cmd_manuscript)

    # supplementary
    sp = sub.add_parser("supplementary", help="Compile supplementary materials")
    sp.add_argument("-p", "--project", default=".", help="Project path")
    sp.add_argument("--draft", action="store_true", help="Fast single-pass mode")
    sp.add_argument(
        "--engine", choices=["tectonic", "latexmk", "3pass"], help="LaTeX engine"
    )
    sp.set_defaults(func=cmd_supplementary)

    # revision
    rv = sub.add_parser("revision", help="Compile revision letter")
    rv.add_argument("-p", "--project", default=".", help="Project path")
    rv.add_argument(
        "--track-changes", action="store_true", help="Include track changes"
    )
    rv.add_argument(
        "--engine", choices=["tectonic", "latexmk", "3pass"], help="LaTeX engine"
    )
    rv.set_defaults(func=cmd_revision)

    # content
    ct = sub.add_parser("content", help="Compile raw LaTeX content to PDF")
    ct.add_argument("-f", "--file", help="LaTeX file to compile (or use stdin)")
    ct.add_argument("-p", "--project", help="Project path for bibliography access")
    ct.add_argument("-n", "--name", default="content", help="Output name")
    ct.add_argument(
        "-c",
        "--color-mode",
        choices=["light", "dark", "sepia", "paper"],
        default="light",
        help="Color mode (default: light)",
    )
    ct.add_argument("-t", "--timeout", type=int, default=60, help="Timeout in seconds")
    ct.add_argument("--keep-aux", action="store_true", help="Keep auxiliary files")
    ct.set_defaults(func=cmd_content)

    return parser


# EOF