#!/usr/bin/env nu # Content Processor Wrapper Script # Provides convenient access to the Rust content_processor with enhanced features # Show help information def show_help [] { print $" (ansi blue)Content Processor Wrapper(ansi reset) Convenient interface to the Rust content_processor binary (ansi green)USAGE:(ansi reset) ./content-processor.nu [OPTIONS] (ansi green)OPTIONS:(ansi reset) -h, --help Show this help message -t, --content-type TYPE Process specific content type only (e.g., blog, recipes) -l, --language LANG Process specific language only (e.g., en, es) -c, --category CATEGORY Process specific category only (subdirectory name) -f, --file FILE Process specific file(s) - supports glob patterns -w, --watch Watch for changes and auto-regenerate --list-types List available content types --list-languages List available languages --list-categories LANG List categories for a specific language --dry-run Show what would be processed without actually processing (ansi green)EXAMPLES:(ansi reset) # Show help ./content-processor.nu --help # Process all content ./content-processor.nu # Process only blog content ./content-processor.nu --content-type blog # Process English blog content ./content-processor.nu --content-type blog --language en # Process rust category in English blog ./content-processor.nu --content-type blog --language en --category rust # Process specific file ./content-processor.nu --file \"blog/en/rust/rust-web-development-2024.md\" # Process files matching pattern ./content-processor.nu --file \"blog/en/*/rust-*.md\" # Watch mode for development ./content-processor.nu --watch # List available content types ./content-processor.nu --list-types # List available languages ./content-processor.nu --list-languages # List categories for English content ./content-processor.nu --list-categories en # Dry run to see what would be processed ./content-processor.nu --content-type blog --dry-run (ansi green)ENVIRONMENT VARIABLES:(ansi reset) SITE_CONTENT_PATH Source content directory (default: site/content) SITE_PUBLIC_PATH Output directory (default: site/public) (ansi yellow)NOTES:(ansi reset) - This script wraps the Rust content_processor binary - All options are passed through to the underlying processor - Use --dry-run to preview what would be processed - Watch mode requires the notify feature to be enabled " } # Load environment variables from .env file def load_env_from_file [] { let env_file = ".env" if ($env_file | path exists) { let env_content = (open $env_file | lines) for line in $env_content { if not ($line | str trim | str starts-with "#") and not ($line | str trim | is-empty) { if ($line | str contains "=") { let parts = ($line | split column "=" key value) if ($parts | length) >= 2 { let key = ($parts | first | get key | str trim) let value = ($parts | first | get value | str trim) let clean_value = ($value | str replace -a '"' '' | str replace -a "'" '') load-env {($key): $clean_value} } } } } } } # Get environment variable with default def get_env_var [name: string, default: string] { try { $env | get $name } catch { $default } } # List available content types def list_content_types [] { load_env_from_file let content_dir = (get_env_var "SITE_CONTENT_PATH" "site/content") let content_kinds_file = ($content_dir | path join "content-kinds.toml") print $"(ansi blue)Available Content Types:(ansi reset)" if ($content_kinds_file | path exists) { let toml_content = (open $content_kinds_file) if "content_kinds" in $toml_content { $toml_content.content_kinds | each { |kind| if $kind.enabled { print $" ✅ ($kind.name) - ($kind.description? | default 'No description')" } else { print $" ❌ ($kind.name) - ($kind.description? | default 'No description') (disabled)" } } | ignore } } else { print $" 📁 blog - Blog posts \(default)" print $" 📁 recipes - Recipe content \(default)" print $"(ansi yellow) Note: No content-kinds.toml found, showing defaults(ansi reset)" } } # List available languages def list_languages [] { load_env_from_file let content_dir = (get_env_var "SITE_CONTENT_PATH" "site/content") print $"(ansi blue)Available Languages:(ansi reset)" # Get directories from first content type let content_types = (ls $content_dir | where type == "dir" | get name | path basename) if ($content_types | length) > 0 { let first_type = ($content_types | first) let type_dir = ($content_dir | path join $first_type) if ($type_dir | path exists) { ls $type_dir | where type == "dir" | each { |item| let lang = ($item.name | path basename) let posts_count = (glob ($item.name | path join "**/*.md") | length) print $" 🌍 ($lang) - ($posts_count) posts" } | ignore } } } # List categories for a specific language def list_categories [language: string] { load_env_from_file let content_dir = (get_env_var "SITE_CONTENT_PATH" "site/content") print $"(ansi blue)Categories for ($language):(ansi reset)" let content_types = (ls $content_dir | where type == "dir" | get name | path basename) for content_type in $content_types { let lang_dir = ($content_dir | path join $content_type $language) if ($lang_dir | path exists) { print $" 📁 ($content_type):" ls $lang_dir | where type == "dir" | each { |item| let category = ($item.name | path basename) let posts_count = (glob ($item.name | path join "**/*.md") | length) print $" 📂 ($category) - ($posts_count) posts" } | ignore } } } # Show what would be processed (dry run) def show_dry_run [args: record] { load_env_from_file let content_dir = (get_env_var "SITE_CONTENT_PATH" "site/content") print $"(ansi blue)Dry Run - What would be processed:(ansi reset)" print $" Source: ($content_dir)" mut file_pattern = "**/*.md" if $args.content_type != null { $file_pattern = ($args.content_type | str replace -a "{content_type}" $file_pattern) } if $args.language != null { $file_pattern = ($file_pattern | str replace -a "**" ($args.language + "/**")) } if $args.category != null { $file_pattern = ($file_pattern | str replace -a "**" ($args.category + "/**")) } if $args.file != null { $file_pattern = $args.file } let full_pattern = ($content_dir | path join $file_pattern) let matching_files = (glob $full_pattern | where ($it | str ends-with ".md")) print $" Pattern: ($file_pattern)" print $" Files that would be processed: ($matching_files | length)" $matching_files | each { |file| print $" 📄 ($file)" } | ignore } # Build and execute cargo command def run_content_processor [args: record] { mut cmd = ["cargo", "run", "--features=content-static", "--bin", "content_processor", "--"] if $args.content_type != null { $cmd = ($cmd | append ["--content-type", $args.content_type]) } if $args.language != null { $cmd = ($cmd | append ["--language", $args.language]) } if $args.category != null { $cmd = ($cmd | append ["--category", $args.category]) } if $args.file != null { $cmd = ($cmd | append ["--file", $args.file]) } if $args.watch { $cmd = ($cmd | append ["--watch"]) } print $"(ansi blue)🔧 Executing: ($cmd | str join ' ')(ansi reset)" run-external $cmd.0 ...$cmd.1 } # Main function def main [ --help(-h) # Show help message --content-type(-t): string # Process specific content type only --language(-l): string # Process specific language only --category(-c): string # Process specific category only --file(-f): string # Process specific file(s) - supports glob patterns --watch(-w) # Watch for changes and auto-regenerate --list-types # List available content types --list-languages # List available languages --list-categories: string # List categories for specific language --dry-run # Show what would be processed without processing ] { # Show help if requested if $help { show_help return } # Handle list operations if $list_types { list_content_types return } if $list_languages { list_languages return } if $list_categories != null { list_categories $list_categories return } # Build arguments let args = { content_type: $content_type, language: $language, category: $category, file: $file, watch: $watch } # Handle dry run if $dry_run { show_dry_run $args return } # Load environment and run processor load_env_from_file run_content_processor $args }