termcinema-cli 0.1.0

🎬 Animated terminal-to-SVG renderer CLI for the termcinema project
Documentation
//! Command-line argument definitions for the `termcinema` binary.
//!
//! This module defines the [`CliArgs`] struct, which covers all
//! rendering configuration options exposed via CLI:
//!
//! - Input source: `--input`, `--script`, or stdin
//! - Style and theme overrides
//! - Layout and spacing options
//! - Animation controls
//! - Output destination
//!
//! Argument parsing is powered by [`clap`].

use clap::Parser;
use std::path::PathBuf;

/// Defines all command-line options for the `termcinema` binary.
#[derive(Parser, Debug)]
#[command(
    name = "termcinema",
    author,
    version,
    about = "🎬 Turn terminal into cinematic SVG",
    help_template = "\
{name} {version}
{about}

📥 Input:
    -i, --input <INPUT>                 Input raw text directly
    -s, --script <FILE>                 Load from a script file
        (stdin)                         echo \"The quick brown fox\" | termcinema


💾 Output:
    -o, --output <FILE>                 Write SVG to file (default: stdout)


🎨 Style:
    --theme <THEME>                     Theme name (e.g. \"dos_classic\", see --list-themes for all)

    --font-family <FONT>                Font family name (e.g. \"Monospace\", see --list-fonts for all)
    --font-size <PX>                    Font size in pixels

    --text-color <HEX>                  Text color (e.g. \"#00FF00\")
    --background-color <HEX>            Background color (e.g. \"#000000\")

    --cursor-char <CHAR>                Custom cursor character (e.g. \"_\")


📐 Layout:
    --width <PX>                        SVG width in pixels
    --height <PX>                       SVG height in pixels

    --padding <PX>                      Margin (default 10px)
    --line-spacing <PX>                 Line spacing in pixels

    --align <left|center|right>         Horizontal alignment
    --v-align <top|middle|bottom>       Vertical alignment


🎞️ Animation:
    --speed <slow|normal|fast|extreme>  Typing speed preset (e.g. \"normal\")
    --frame-delay <MS>                  Frame delay per character (ms, lower = faster)

    --fade-duration <MS>                Fade-in duration per char (e.g. 100)


⚙️ Advanced:
    --no-escape                         Disable escape sequences

    --list-fonts                        List all built-in fonts
    --list-themes                       List all built-in themes


❓ Help:
    -h, --help                          Print help
    -V, --version                       Print version
"
)]
pub struct CliArgs {
    // 📥 Input
    /// Input text (conflicts with --script)
    #[arg(short = 'i', long, value_name = "TEXT", conflicts_with = "script")]
    pub input: Option<String>,

    /// Script file path (conflicts with --input)
    #[arg(short = 's', long, value_name = "FILE", conflicts_with = "input")]
    pub script: Option<PathBuf>,

    // stdin is supported implicitly (no field needed)

    // 💾 Output
    /// Output file path (default: stdout)
    #[arg(short = 'o', long, value_name = "FILE")]
    pub output: Option<String>,

    // 🎨 Style
    /// Theme name (see --list-themes)
    #[arg(long, value_name = "NAME")]
    pub theme: Option<String>,

    /// Font family name
    #[arg(long, value_name = "FONT")]
    pub font_family: Option<String>,

    /// Font size in pixels
    #[arg(long, value_name = "PX")]
    pub font_size: Option<u32>,

    /// Text color (e.g. "#00FF00")
    #[arg(long, value_name = "HEX")]
    pub text_color: Option<String>,

    /// Background color (e.g. "#000000")
    #[arg(long, value_name = "HEX")]
    pub background_color: Option<String>,

    /// Cursor character (e.g. "_")
    #[arg(long, value_name = "CHAR")]
    pub cursor_char: Option<String>,

    // 📐 Layout
    /// Padding around content (default: 10)
    #[arg(long, value_name = "PX")]
    pub width: Option<u32>,

    /// Line spacing in pixels
    #[arg(long, value_name = "PX")]
    pub height: Option<u32>,

    /// SVG height in pixels
    #[arg(long, value_name = "PX")]
    pub padding: Option<u32>,

    /// SVG width in pixels
    #[arg(long, value_name = "PX")]
    pub line_spacing: Option<u32>,

    /// Horizontal alignment: left, center, or right
    #[arg(long, value_name = "ENUM")]
    pub align: Option<String>,

    /// Vertical alignment: top, middle, or bottom
    #[arg(long, value_name = "ENUM")]
    pub v_align: Option<String>,

    // 🎞️ Animation
    /// Typing speed preset (e.g. "normal")
    #[arg(long, value_name = "ENUM", conflicts_with = "frame_delay")]
    pub speed: Option<String>,

    /// Frame delay per character (ms)
    #[arg(long, value_name = "MS", conflicts_with = "speed")]
    pub frame_delay: Option<u32>,

    /// Fade-in duration per character (ms)
    #[arg(long, value_name = "MS")]
    pub fade_duration: Option<u32>,

    // ⚙️ Advanced
    /// Disable escape sequences like \n or \t
    #[arg(long, default_value_t = false)]
    pub no_escape: bool,

    /// List all built-in fonts
    #[arg(long, default_value_t = false)]
    pub list_fonts: bool,

    /// List all built-in themes
    #[arg(long, default_value_t = false)]
    pub list_themes: bool,
}

/// Parse command-line arguments using `clap`.
///
/// Called once by `main()` as the entrypoint to argument collection.
#[allow(dead_code)]
pub(crate) fn parse_args() -> CliArgs {
    CliArgs::parse()
}

/// Return default arguments for internal use or SDK initialization.
///
/// Equivalent to `CliArgs::default()`.
#[allow(dead_code)]
pub fn default_args() -> CliArgs {
    CliArgs::default()
}

/// Provide default arguments for SDKs, playgrounds, or programmatic usage.
///
/// These defaults are suitable for embedding scenarios where no CLI is involved.
/// They represent a typical middle-ground layout and animation config.
///
/// This implementation is used by [`default_args()`] and [`render_svg_direct()`].
impl Default for CliArgs {
    fn default() -> Self {
        Self {
            input: None,
            script: None,
            output: None,

            theme: None,
            font_family: None,
            font_size: Some(16),
            text_color: None,
            background_color: None,
            cursor_char: None,

            width: Some(800),
            height: Some(600),
            padding: Some(10),
            line_spacing: Some(6),
            align: Some("left".into()),
            v_align: Some("middle".into()),

            speed: Some("normal".into()),
            frame_delay: None,
            fade_duration: Some(100),

            no_escape: false,
            list_fonts: false,
            list_themes: false,
        }
    }
}