Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Extract CLI crate and add shell completion and man page #42

Merged
merged 12 commits into from
Nov 13, 2023
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
38 changes: 38 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

46 changes: 7 additions & 39 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,47 +1,15 @@
[workspace]
members = ["tests"]
members = ["crates/*", "tests"]
default-members = ["crates/svg2pdf"]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would change this to default-members = ["crates/typst-cli"], since the cli is what you want to execute by default when running cargo run in the root directory.

resolver = "2"

[workspace.package]
version = "0.9.0"
authors = ["Martin Haug <[email protected]>", "Laurenz Stampfl <[email protected]>"]
authors = [
"Martin Haug <[email protected]>",
"Laurenz Stampfl <[email protected]>",
]
edition = "2021"
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" }
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
38 changes: 38 additions & 0 deletions crates/svg2pdf-cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[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" }
laurmaedje marked this conversation as resolved.
Show resolved Hide resolved
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",
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess that's personal preference, but maybe better to keep everything in a single line? Not sure about this one, though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had a TOML formatter turned on for VSCode which did this, but I can revert it if you prefer, no problem.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I prefer single lines, too.

] }
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"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add newlines at the end of files where they are missing.

30 changes: 30 additions & 0 deletions crates/svg2pdf-cli/build.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
use std::{env, path::Path};

use clap::{CommandFactory, ValueEnum};
use clap_complete::{generate_to, Shell};

mod args {
include!("src/cli.rs");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the name args.rs (like in Typst) is clearer.

}

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 same level as the binary (e.g. /target/debug folder)
let outdir_path = &Path::new(&outdir_str).ancestors().nth(3).unwrap();

let mut cmd = args::Args::command();

let man = clap_mangen::Man::new(cmd.clone());
let mut manpage_file = std::fs::File::create(outdir_path.join("svg2pdf.1"))?;
man.render(&mut manpage_file)?;

for shell in Shell::value_variants() {
generate_to(*shell, &mut cmd, "svg2pdf", outdir_path).unwrap();
}

Ok(())
}
15 changes: 15 additions & 0 deletions crates/svg2pdf-cli/src/cli.rs
Original file line number Diff line number Diff line change
@@ -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<PathBuf>,
/// The number of SVG pixels per PDF points.
#[clap(long, default_value = "72.0")]
pub dpi: f32,
}
16 changes: 3 additions & 13 deletions src/main.rs → crates/svg2pdf-cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use std::io::{self, Write};
use std::path::{Path, PathBuf};
use std::path::Path;
use std::process;

use clap::Parser;
Expand All @@ -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<PathBuf>,
/// The number of SVG pixels per PDF points.
#[clap(long, default_value = "72.0")]
dpi: f32,
}
mod cli;

fn main() {
if let Err(msg) = run() {
Expand All @@ -28,7 +18,7 @@ fn main() {
}

fn run() -> Result<(), String> {
let args = Args::parse();
let args = cli::Args::parse();

let name =
Path::new(args.input.file_name().ok_or("Input path does not point to a file")?);
Expand Down
31 changes: 31 additions & 0 deletions crates/svg2pdf/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
[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" }
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
2 changes: 1 addition & 1 deletion tests/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down