# Configuration template_dir := ".typst-template" config_dir := ".config" out_dir := "" # Default target default: @just --list # Create new work from template new subject shortcode number="": #!/usr/bin/env nu # Convert to lowercase for config lookup let subject_lower = ("{{subject}}" | str downcase) let shortcode_lower = ("{{shortcode}}" | str downcase) # Use number if provided, otherwise empty string let number = "{{number}}" just _validate-input "{{shortcode}}" $number "{{subject}}" # Create temporary directory first let temp_dir = (mktemp -d) let final_dir = if "{{out_dir}}" != "" { $"{{out_dir}}/($subject_lower)/($shortcode_lower)($number)" } else { $"($subject_lower)/($shortcode_lower)" } let subject_dir = if "{{out_dir}}" != "" { $"{{out_dir}}/($subject_lower)" } else { $"($subject_lower)" } # Copy template to temp just _copy-template $temp_dir # Generate customized files in temp just _generate-doc-toml $shortcode_lower $subject_lower $temp_dir $number # Move to final location # NOTE: mkdir then cp: that way it copies to final_dir and not final_dir/temp_dir if "{{out_dir}}" != "" and not ("{{out_dir}}" | path exists) { mkdir {{out_dir}} } mkdir $subject_dir cp -r $temp_dir $final_dir print $"=> Created new work: ($final_dir)" # rm -rf $temp_dir # Validation helper _validate-input shortcode number subject: #!/usr/bin/env nu if not ("{{config_dir}}" | path exists) { error make -u {msg: "Config directory not found"} } let defaults_toml = "{{config_dir}}/defaults.toml" let subjects_toml = "{{config_dir}}/subjects.toml" if not ($defaults_toml | path exists) { error make -u {msg: $"defaults.toml not found in config directory"} } if not ($subjects_toml | path exists) { error make -u {msg: "subjects.toml not found in config directory"} } if "{{number}}" != "" { if ("{{number}}" | into int) <= 0 { error make -u {msg: "Number must be positive integer"} } } # Check subject exists (case insensitive) let subject_lower = ("{{subject}}" | str downcase) let subjects = (open $subjects_toml | get subjects | columns) if $subject_lower not-in $subjects { error make -u { msg: $"Subject '{{subject}}' not found in configuration" help: $"Available subjects: ($subjects | str join ', ')" } } # Directory creation _create-dir target_dir: #!/usr/bin/env nu if ("{{target_dir}}" | path exists) { error make -u {msg: $"Directory {{target_dir}} already exists"} } mkdir "{{target_dir}}" # Copy template files _copy-template target_dir: #!/usr/bin/env nu if not ("{{template_dir}}" | path exists) { error make -u {msg: $"Template directory {{template_dir}} not found"} } cd {{template_dir}}; cp -r * {{target_dir}}/ # Generate customized doc.toml _generate-doc-toml shortcode subject target_dir number="": #!/usr/bin/env nu let defaults_toml = $"{{config_dir}}/defaults.toml" let subjects_toml = $"{{config_dir}}/subjects.toml" # Extract data using Nushell's builtin TOML parsing let defaults = (open $defaults_toml) let subjects = (open $subjects_toml) let university = ($defaults | get university) let subject_data = ($subjects | get subjects | get {{subject}}) let subject_name = ($subject_data | get name) # Get work type, with fallback for unknown shortcodes let work_type = ($defaults | get work_types | try { get "{{shortcode}}" } catch { "{{shortcode}}" }) let author = ($defaults | get default_author) # Get mentors directly from the subject let mentors_data = ($subject_data | get mentors) # Build the complete TOML structure as a record let base_config = { university: $university subject: $subject_name type: $work_type mentors: $mentors_data authors: [$author] } let doc_config = if "{{number}}" != "" { $base_config | merge {number: ("{{number}}" | into int)} } else { $base_config } # Output directly to TOML format $doc_config | to toml | save $"{{target_dir}}/src/doc.toml" --force