diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5c09ac57..4f1d219b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,6 +49,6 @@ jobs: - uses: actions/checkout@v3 - uses: dtolnay/rust-toolchain@stable - uses: Swatinem/rust-cache@v2 - - run: cargo clippy --all-targets --features cli + - run: cargo clippy --all-targets - run: cargo fmt --check --all - run: cargo doc --workspace --no-deps diff --git a/Cargo.lock b/Cargo.lock index 99bcc0dc..cac231ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -253,6 +253,15 @@ dependencies = [ "strsim", ] +[[package]] +name = "clap_complete" +version = "4.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3ae8ba90b9d8b007efe66e55e48fb936272f5ca00349b5b0e89877520d35ea7" +dependencies = [ + "clap", +] + [[package]] name = "clap_derive" version = "4.4.2" @@ -271,6 +280,16 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +[[package]] +name = "clap_mangen" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b44f35c514163027542f7147797ff930523eea288e03642727348ef1a9666f6b" +dependencies = [ + "clap", + "roff", +] + [[package]] name = "color_quant" version = "1.1.0" @@ -1123,6 +1142,12 @@ dependencies = [ "bytemuck", ] +[[package]] +name = "roff" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316" + [[package]] name = "roxmltree" version = "0.18.0" @@ -1259,12 +1284,25 @@ checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" [[package]] name = "svg2pdf" version = "0.9.0" +dependencies = [ + "image", + "miniz_oxide", + "pdf-writer", + "usvg", +] + +[[package]] +name = "svg2pdf-cli" +version = "0.9.0" dependencies = [ "clap", + "clap_complete", + "clap_mangen", "fontdb", "image", "miniz_oxide", "pdf-writer", + "svg2pdf", "termcolor", "usvg", ] diff --git a/Cargo.toml b/Cargo.toml index 119444ea..cbb64007 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,7 @@ [workspace] -members = ["tests"] +members = ["crates/*", "tests"] +default-members = ["crates/svg2pdf-cli"] +resolver = "2" [workspace.package] version = "0.9.0" @@ -9,39 +11,3 @@ repository = "https://github.com/typst/svg2pdf" readme = "README.md" license = "MIT OR Apache-2.0" -[package] -name = "svg2pdf" -description = "Convert SVG files to PDFs." -categories = ["encoding", "graphics", "multimedia"] -keywords = ["svg", "pdf", "vector-graphics", "conversion"] -version.workspace = true -authors.workspace = true -edition.workspace = true -repository.workspace = true -license.workspace = true - -[features] -default = ["image"] -image = ["dep:image"] -cli = ["dep:clap", "dep:termcolor", "usvg/text", "dep:fontdb"] - -[lib] -test = false -doctest = false - -[[bin]] -name = "svg2pdf" -path = "src/main.rs" -required-features = ["cli"] - -[dependencies] -miniz_oxide = "0.7" -pdf-writer = "0.9" -usvg = { version = "0.36", default-features = false } -image = { version = "0.24", default-features = false, features = ["jpeg", "png", "gif"], optional = true } -termcolor = { version = "1", optional = true } -clap = { version = "4.4.2", features = ["derive"], optional = true } -fontdb = { version = "0.15", optional= true } - -[dev-dependencies] -usvg = { version = "0.36.0" } diff --git a/README.md b/README.md index 883e919a..9290b832 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ std::fs::write("target/time_series.pdf", pdf)?; This crate also contains a command line interface. Install it by running the command below: ```bash -cargo install svg2pdf --features cli +cargo install svg2pdf-cli ``` You can then convert SVGs to PDFs by running commands like these: diff --git a/crates/svg2pdf-cli/Cargo.toml b/crates/svg2pdf-cli/Cargo.toml new file mode 100644 index 00000000..1b87ad2f --- /dev/null +++ b/crates/svg2pdf-cli/Cargo.toml @@ -0,0 +1,35 @@ +[package] +name = "svg2pdf-cli" +description = "The command line interface for svg2pdf." +categories = ["encoding", "graphics", "multimedia", "command-line-utilities"] +keywords = ["svg2pdf", "cli"] +version.workspace = true +authors.workspace = true +edition.workspace = true +repository.workspace = true +license.workspace = true +build = "build.rs" + +[[bin]] +name = "svg2pdf" +path = "src/main.rs" +test = false +doctest = false +bench = false +doc = false + +[dependencies] +svg2pdf = { path = "../svg2pdf" } +miniz_oxide = "0.7" +pdf-writer = "0.9" +usvg = { version = "0.36", default-features = false, features = ["text"] } +image = { version = "0.24", default-features = false, features = ["jpeg", "png", "gif"] } +termcolor = { version = "1" } +clap = { version = "4.4.2", features = ["derive"] } +fontdb = { version = "0.15" } + +[build-dependencies] +clap = { version = "4.4.2", features = ["derive", "string"] } +clap_complete = "4.4.3" +clap_mangen = "0.2.14" + diff --git a/crates/svg2pdf-cli/build.rs b/crates/svg2pdf-cli/build.rs new file mode 100644 index 00000000..7ba59d35 --- /dev/null +++ b/crates/svg2pdf-cli/build.rs @@ -0,0 +1,32 @@ +use std::{env, path::Path}; + +use clap::{CommandFactory, ValueEnum}; +use clap_complete::{generate_to, Shell}; + +mod args { + include!("src/args.rs"); +} + +fn main() -> Result<(), std::io::Error> { + let outdir_str = match env::var_os("OUT_DIR") { + None => return Ok(()), + Some(outdir) => outdir, + }; + + // Put the files in the artifacts folder (/target/artifacts) + let outdir_path = &Path::new(&outdir_str).ancestors().nth(3).unwrap(); + let artifacts_path = outdir_path.join("artifacts"); + std::fs::create_dir_all(&artifacts_path)?; + + let mut cmd = args::Args::command(); + + let man = clap_mangen::Man::new(cmd.clone()); + let mut manpage_file = std::fs::File::create(artifacts_path.join("svg2pdf.1"))?; + man.render(&mut manpage_file)?; + + for shell in Shell::value_variants() { + generate_to(*shell, &mut cmd, "svg2pdf", &artifacts_path).unwrap(); + } + + Ok(()) +} diff --git a/crates/svg2pdf-cli/src/args.rs b/crates/svg2pdf-cli/src/args.rs new file mode 100644 index 00000000..905997c8 --- /dev/null +++ b/crates/svg2pdf-cli/src/args.rs @@ -0,0 +1,15 @@ +use std::path::PathBuf; + +use clap::Parser; + +#[derive(Debug, Parser)] +#[clap(about, version)] +pub struct Args { + /// Path to read SVG file from. + pub input: PathBuf, + /// Path to write PDF file to. + pub output: Option, + /// The number of SVG pixels per PDF points. + #[clap(long, default_value = "72.0")] + pub dpi: f32, +} diff --git a/src/main.rs b/crates/svg2pdf-cli/src/main.rs similarity index 79% rename from src/main.rs rename to crates/svg2pdf-cli/src/main.rs index c87c7925..77ff1f02 100644 --- a/src/main.rs +++ b/crates/svg2pdf-cli/src/main.rs @@ -1,5 +1,5 @@ use std::io::{self, Write}; -use std::path::{Path, PathBuf}; +use std::path::Path; use std::process; use clap::Parser; @@ -8,17 +8,7 @@ use usvg::{TreeParsing, TreeTextToPath}; use svg2pdf::Options; -#[derive(Debug, Parser)] -#[clap(about, version)] -struct Args { - /// Path to read SVG file from. - input: PathBuf, - /// Path to write PDF file to. - output: Option, - /// The number of SVG pixels per PDF points. - #[clap(long, default_value = "72.0")] - dpi: f32, -} +mod args; fn main() { if let Err(msg) = run() { @@ -28,7 +18,7 @@ fn main() { } fn run() -> Result<(), String> { - let args = Args::parse(); + let args = args::Args::parse(); let name = Path::new(args.input.file_name().ok_or("Input path does not point to a file")?); diff --git a/crates/svg2pdf/Cargo.toml b/crates/svg2pdf/Cargo.toml new file mode 100644 index 00000000..42607228 --- /dev/null +++ b/crates/svg2pdf/Cargo.toml @@ -0,0 +1,28 @@ +[package] +name = "svg2pdf" +description = "Convert SVG files to PDFs." +categories = ["encoding", "graphics", "multimedia"] +keywords = ["svg", "pdf", "vector-graphics", "conversion"] +version.workspace = true +authors.workspace = true +edition.workspace = true +repository.workspace = true +license.workspace = true + +[lib] +doctest = false +bench = false + +[features] +default = ["image"] +image = ["dep:image"] + +[dependencies] +miniz_oxide = "0.7" +pdf-writer = "0.9" +usvg = { version = "0.36", default-features = false } +image = { version = "0.24", default-features = false, features = ["jpeg", "png", "gif"], optional = true } + +[dev-dependencies] +usvg = { version = "0.36.0" } + diff --git a/src/lib.rs b/crates/svg2pdf/src/lib.rs similarity index 100% rename from src/lib.rs rename to crates/svg2pdf/src/lib.rs diff --git a/src/render/clip_path.rs b/crates/svg2pdf/src/render/clip_path.rs similarity index 100% rename from src/render/clip_path.rs rename to crates/svg2pdf/src/render/clip_path.rs diff --git a/src/render/gradient.rs b/crates/svg2pdf/src/render/gradient.rs similarity index 100% rename from src/render/gradient.rs rename to crates/svg2pdf/src/render/gradient.rs diff --git a/src/render/group.rs b/crates/svg2pdf/src/render/group.rs similarity index 100% rename from src/render/group.rs rename to crates/svg2pdf/src/render/group.rs diff --git a/src/render/image.rs b/crates/svg2pdf/src/render/image.rs similarity index 100% rename from src/render/image.rs rename to crates/svg2pdf/src/render/image.rs diff --git a/src/render/mask.rs b/crates/svg2pdf/src/render/mask.rs similarity index 100% rename from src/render/mask.rs rename to crates/svg2pdf/src/render/mask.rs diff --git a/src/render/mod.rs b/crates/svg2pdf/src/render/mod.rs similarity index 100% rename from src/render/mod.rs rename to crates/svg2pdf/src/render/mod.rs diff --git a/src/render/path.rs b/crates/svg2pdf/src/render/path.rs similarity index 100% rename from src/render/path.rs rename to crates/svg2pdf/src/render/path.rs diff --git a/src/render/pattern.rs b/crates/svg2pdf/src/render/pattern.rs similarity index 100% rename from src/render/pattern.rs rename to crates/svg2pdf/src/render/pattern.rs diff --git a/src/util/allocate.rs b/crates/svg2pdf/src/util/allocate.rs similarity index 100% rename from src/util/allocate.rs rename to crates/svg2pdf/src/util/allocate.rs diff --git a/src/util/context.rs b/crates/svg2pdf/src/util/context.rs similarity index 100% rename from src/util/context.rs rename to crates/svg2pdf/src/util/context.rs diff --git a/src/util/defer.rs b/crates/svg2pdf/src/util/defer.rs similarity index 100% rename from src/util/defer.rs rename to crates/svg2pdf/src/util/defer.rs diff --git a/src/util/helper.rs b/crates/svg2pdf/src/util/helper.rs similarity index 100% rename from src/util/helper.rs rename to crates/svg2pdf/src/util/helper.rs diff --git a/src/util/mod.rs b/crates/svg2pdf/src/util/mod.rs similarity index 100% rename from src/util/mod.rs rename to crates/svg2pdf/src/util/mod.rs diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 6903a466..3536ce11 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -29,7 +29,7 @@ test = false [dependencies] fontdb = "0.15" -svg2pdf = { path = ".." } +svg2pdf = { path = "../crates/svg2pdf" } usvg = "0.36.0" pdfium-render = "0.8.6" walkdir = "2.3.3"