def create_parser() -> argparse.ArgumentParser:
"""Create ArgumentParser with all subcommands."""
parser = argparse.ArgumentParser(
prog="academic-doc-generator",
description="Unified tool for thesis colloquiums, project grading, and peer reviews",
)
# Global arguments
parser.add_argument("--config", help="Path to JSON configuration file", metavar="CONFIG")
parser.add_argument(
"--list-templates",
action="store_true",
help="List available configuration templates",
)
# Subcommands
subparsers = parser.add_subparsers(dest="command", help="Task to execute")
# --- Colloquium Subcommand ---
colloquium_parser = subparsers.add_parser(
"colloquium", help="Generate colloquium protocol letter"
)
colloquium_parser.add_argument("pdf", help="Path to the thesis PDF")
colloquium_parser.add_argument("--date", required=True, help="Colloquium date (DD.MM.YYYY)")
colloquium_parser.add_argument("--time", required=True, help="Colloquium time (HH:MM)")
colloquium_parser.add_argument(
"--location-type",
choices=["campus", "company", "online"],
default="campus",
help="Location type (default: campus)",
)
colloquium_parser.add_argument("--room", help="Room number (for campus)")
colloquium_parser.add_argument("--company-name", help="Company name (for company)")
colloquium_parser.add_argument("--company-address", help="Company address (for company)")
colloquium_parser.add_argument("--zoom-link", help="Zoom meeting link (for online)")
colloquium_parser.add_argument(
"--zoom-code", dest="zcode", help="Zoom access code (for online)"
)
colloquium_parser.add_argument(
"--api",
choices=["openai", "groq", "gemini", "ollama"],
help="LLM API to use (auto-detected if omitted)",
)
colloquium_parser.add_argument("--model", help="LLM model to use")
colloquium_parser.add_argument("--groq-free", action="store_true", help="Use free-tier pacing")
colloquium_parser.add_argument(
"--gemini-eval",
action="store_true",
help="Enable automatic Gemini emark",
)
colloquium_parser.add_argument(
"--gemini-model",
default="gemini-2.0-flash-exp",
help="Gemini model for emark",
)
colloquium_parser.add_argument(
"--gemini-upload-pdf",
action="store_true",
help="Upload PDF instead of text (not default)",
)
colloquium_parser.add_argument("--out", help="Output folder")
colloquium_parser.add_argument(
"--no-compile", action="store_true", help="Do not compile .tex to PDF"
)
# --- Project Subcommand ---
project_parser = subparsers.add_parser("project", help="Generate project work grading letter")
project_parser.add_argument("pdf", help="Path to the project work PDF")
project_parser.add_argument("--mark", help="Grade for the project (e.g., 1.3)")
project_parser.add_argument("--work-type", help="Type of work (e.g., 'Projektteil WASP1')")
project_parser.add_argument(
"--api",
choices=["openai", "groq", "gemini", "ollama"],
help="LLM API to use (auto-detected if omitted)",
)
project_parser.add_argument("--model", help="LLM model to use")
project_parser.add_argument("--out", help="Output folder")
project_parser.add_argument(
"--no-compile", action="store_true", help="Do not compile .tex to PDF"
)
project_parser.add_argument(
"--signature", default="signature.png", help="Path to signature image"
)
project_parser.add_argument(
"--create-feedback-mail",
action="store_true",
dest="create_feedback_mail",
default=True,
help="Generate feedback summary and student email (default: True)",
)
project_parser.add_argument(
"--no-feedback-mail",
action="store_false",
dest="create_feedback_mail",
help="Do not generate feedback summary and student email",
)
# --- Review Subcommand ---
review_parser = subparsers.add_parser("review", help="Generate peer review comments")
review_parser.add_argument("pdf", help="Path to the paper PDF")
review_parser.add_argument(
"--api",
choices=["openai", "groq", "gemini", "ollama"],
help="LLM API to use (auto-detected if omitted)",
)
review_parser.add_argument("--model", help="LLM model to use")
review_parser.add_argument("--groq-free", action="store_true", help="Use free-tier pacing")
review_parser.add_argument("--out", help="Output folder")
return parser