diff --git a/Cargo.lock b/Cargo.lock index a475aa0af..74ad3742e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -339,6 +339,7 @@ dependencies = [ "anstyle", "clap_lex", "strsim", + "terminal_size", ] [[package]] @@ -394,6 +395,27 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "color-print" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1ee543c60ff3888934877a5671f45494dd27ed4ba25c6670b9a7576b7ed7a8c0" +dependencies = [ + "color-print-proc-macro", +] + +[[package]] +name = "color-print-proc-macro" +version = "0.3.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ff1a80c5f3cb1ca7c06ffdd71b6a6dd6d8f896c42141fbd43f50ed28dcdb93" +dependencies = [ + "nom", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "color_quant" version = "1.1.0" @@ -1374,6 +1396,12 @@ dependencies = [ "libc", ] +[[package]] +name = "minimal-lexical" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a" + [[package]] name = "miniz_oxide" version = "0.8.0" @@ -1425,6 +1453,16 @@ dependencies = [ "tempfile", ] +[[package]] +name = "nom" +version = "7.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" +dependencies = [ + "memchr", + "minimal-lexical", +] + [[package]] name = "notify" version = "6.1.1" @@ -2447,6 +2485,16 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "terminal_size" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f599bd7ca042cfdf8f4512b277c02ba102247820f9d9d4a9f521f496751a6ef" +dependencies = [ + "rustix", + "windows-sys 0.59.0", +] + [[package]] name = "thin-vec" version = "0.2.13" @@ -2698,6 +2746,7 @@ dependencies = [ "clap_complete", "clap_mangen", "codespan-reporting", + "color-print", "comemo", "dirs", "ecow", diff --git a/Cargo.toml b/Cargo.toml index 62eed382d..d3b1ba64b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,13 +38,14 @@ bytemuck = "1" chinese-number = { version = "0.7.2", default-features = false, features = ["number-to-chinese"] } chrono = { version = "0.4.24", default-features = false, features = ["clock", "std"] } ciborium = "0.2.1" -clap = { version = "4.4", features = ["derive", "env"] } +clap = { version = "4.4", features = ["derive", "env", "wrap_help"] } clap_complete = "4.2.1" clap_mangen = "0.2.10" -ctrlc = "3.4.1" codespan-reporting = "0.11" +color-print = "0.3.6" comemo = "0.4" csv = "1" +ctrlc = "3.4.1" dirs = "5" ecow = { version = "0.2", features = ["serde"] } env_proxy = "0.4" @@ -84,8 +85,8 @@ png = "0.17" portable-atomic = "1.6" proc-macro2 = "1" pulldown-cmark = "0.9" -quote = "1" qcms = "0.3.0" +quote = "1" rayon = "1.7.0" regex = "1" resvg = { version = "0.43", default-features = false, features = ["raster-images"] } diff --git a/crates/typst-cli/Cargo.toml b/crates/typst-cli/Cargo.toml index fd707ebe1..1c622d1e2 100644 --- a/crates/typst-cli/Cargo.toml +++ b/crates/typst-cli/Cargo.toml @@ -28,6 +28,7 @@ typst-svg = { workspace = true } typst-timing = { workspace = true } chrono = { workspace = true } clap = { workspace = true } +color-print = { workspace = true } codespan-reporting = { workspace = true } comemo = { workspace = true } dirs = { workspace = true } @@ -59,6 +60,7 @@ chrono = { workspace = true } clap = { workspace = true, features = ["string"] } clap_complete = { workspace = true } clap_mangen = { workspace = true } +color-print = { workspace = true } semver = { workspace = true } [features] diff --git a/crates/typst-cli/src/args.rs b/crates/typst-cli/src/args.rs index 65259ab7a..7436d25c3 100644 --- a/crates/typst-cli/src/args.rs +++ b/crates/typst-cli/src/args.rs @@ -13,9 +13,36 @@ use semver::Version; /// in environment variables. const ENV_PATH_SEP: char = if cfg!(windows) { ';' } else { ':' }; -/// The Typst compiler. +/// The overall structure of the help. +#[rustfmt::skip] +const HELP_TEMPLATE: &str = "\ +Typst {version} + +{usage-heading} {usage} + +{all-args}{after-help}\ +"; + +/// Adds a list of useful links after the normal help. +#[rustfmt::skip] +const AFTER_HELP: &str = color_print::cstr!("\ +Resources: + Tutorial: https://typst.app/docs/tutorial/ + Reference documentation: https://typst.app/docs/reference/ + Templates & Packages: https://typst.app/universe/ + Forum for questions: https://forum.typst.app/ +"); + +/// The Typst compiler #[derive(Debug, Clone, Parser)] -#[clap(name = "typst", version = crate::typst_version(), author)] +#[clap( + name = "typst", + version = crate::typst_version(), + author, + help_template = HELP_TEMPLATE, + after_help = AFTER_HELP, + max_term_width = 80, +)] pub struct CliArguments { /// The command to run #[command(subcommand)] diff --git a/crates/typst-cli/src/greet.rs b/crates/typst-cli/src/greet.rs new file mode 100644 index 000000000..01f273fcf --- /dev/null +++ b/crates/typst-cli/src/greet.rs @@ -0,0 +1,66 @@ +use std::io::{self, Read}; + +/// This is shown to users who just type `typst` the first time. +#[rustfmt::skip] +const GREETING: &str = color_print::cstr!("\ +Welcome to Typst, we are glad to have you here! ❤️ + +If you are new to Typst, start with the tutorial at \ +https://typst.app/docs/tutorial/. To get a quick start with your first \ +project, choose a template on https://typst.app/universe/. + +Here are the most important commands you will be using: + +- Compile a file once: typst compile file.typ +- Compile a file on every change: typst watch file.typ +- Set up a project from a template: typst init @preview/<