summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock77
-rw-r--r--Cargo.toml66
-rw-r--r--src/layout/incremental.rs2
-rw-r--r--src/main.rs106
-rw-r--r--tests/typeset.rs9
5 files changed, 129 insertions, 131 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ec9f290c..cb6a1c93 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -15,12 +15,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234"
[[package]]
-name = "anyhow"
-version = "1.0.52"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "84450d0b4a8bd1ba4144ce8ce718fbc5d071358b1e5384bace6536b3d1f2d5b3"
-
-[[package]]
name = "arrayref"
version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -92,9 +86,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
[[package]]
name = "crc32fast"
-version = "1.3.0"
+version = "1.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "738c290dfaea84fc1ca15ad9c168d083b05a714e1efddd8edaab678dc28d2836"
+checksum = "a2209c310e29876f7f0b2721e7e26b84aff178aa3da5d091f9bfbf47669e60e3"
dependencies = [
"cfg-if",
]
@@ -219,9 +213,9 @@ checksum = "a246d82be1c9d791c5dfde9a2bd045fc3cbba3fa2b11ad558f27d01712f00569"
[[package]]
name = "filedescriptor"
-version = "0.8.1"
+version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ed3d8a5e20435ff00469e51a0d82049bae66504b5c429920dadf9bb54d47b3f"
+checksum = "7199d965852c3bac31f779ef99cbb4537f80e952e2d6aa0ffeb30cce00f4f46e"
dependencies = [
"libc",
"thiserror",
@@ -247,16 +241,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "98de4bbd547a563b716d8dfa9aad1cb19bfab00f4fa09a6a4ed21dbcf44ce9c4"
[[package]]
-name = "fontdb"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01b07f5c05414a0d8caba4c17eef8dc8b5c8955fc7c68d324191c7a56d3f3449"
-dependencies = [
- "log",
- "ttf-parser",
-]
-
-[[package]]
name = "fxhash"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -279,7 +263,7 @@ dependencies = [
[[package]]
name = "iai"
version = "0.1.1"
-source = "git+https://github.com/reknih/iai#f57a4452e7ac3b118e695e1feddb6ea02c4015be"
+source = "git+https://github.com/reknih/iai#3f0f92736408ebce6545808b98e0cb2aea89b7dd"
dependencies = [
"cfg-if",
]
@@ -332,9 +316,9 @@ dependencies = [
[[package]]
name = "libc"
-version = "0.2.112"
+version = "0.2.113"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b03d17f364a3a042d5e5d46b053bbbf82c92c9430c592dd4c064dc6ee997125"
+checksum = "eef78b64d87775463c549fbd80e19249ef436ea3bf1de2a1eb7e717ec7fab1e9"
[[package]]
name = "log"
@@ -485,9 +469,9 @@ dependencies = [
[[package]]
name = "quote"
-version = "1.0.14"
+version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "47aa80447ce4daf1717500037052af176af5d38cc3e571d9ec1c7353fc10c87d"
+checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
dependencies = [
"proc-macro2",
]
@@ -559,15 +543,16 @@ dependencies = [
[[package]]
name = "resvg"
-version = "0.19.0"
+version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "256cc9203115db152290219f35f3362e729301b59e2a391fb2721fe3fa155352"
+checksum = "d94a32ca845cdda27237a40beba9bd3d3858ac8fc5356eb9442bdeecfe34d9e0"
dependencies = [
"jpeg-decoder",
"log",
"pico-args",
"png 0.17.2",
"rgb",
+ "svgtypes",
"tiny-skia",
"usvg",
]
@@ -632,18 +617,18 @@ dependencies = [
[[package]]
name = "serde"
-version = "1.0.133"
+version = "1.0.135"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "97565067517b60e2d1ea8b268e59ce036de907ac523ad83a0475da04e818989a"
+checksum = "2cf9235533494ea2ddcdb794665461814781c53f19d87b76e571a1c35acbad2b"
dependencies = [
"serde_derive",
]
[[package]]
name = "serde_derive"
-version = "1.0.133"
+version = "1.0.135"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ed201699328568d8d08208fdd080e3ff594e6c422e438b6705905da01005d537"
+checksum = "8dcde03d87d4c973c04be249e7d8f0b35db1c848c487bd43032808e59dd8328d"
dependencies = [
"proc-macro2",
"quote",
@@ -661,9 +646,9 @@ dependencies = [
[[package]]
name = "siphasher"
-version = "0.3.8"
+version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ba1eead9e94aa5a2e02de9e7839f96a007f686ae7a1d57c7797774810d24908a"
+checksum = "a86232ab60fa71287d7f2ddae4a7073f6b7aac33631c3015abb556f08c6d0a3e"
[[package]]
name = "smallvec"
@@ -673,9 +658,9 @@ checksum = "f2dd574626839106c320a323308629dcb1acfc96e32a8cba364ddc61ac23ee83"
[[package]]
name = "svg2pdf"
-version = "0.1.0"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df8af8eebab963c97dc4ae380c0adb6063fdaaf586dd961b55205c6a9d646430"
+checksum = "b7feae49dae1a460ecd13b50e4389204672daac9c7133fd830132f44486ab84d"
dependencies = [
"image",
"miniz_oxide 0.4.4",
@@ -694,9 +679,9 @@ dependencies = [
[[package]]
name = "syn"
-version = "1.0.85"
+version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a684ac3dcd8913827e18cd09a68384ee66c1de24157e3c556c9ab16d85695fb7"
+checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
dependencies = [
"proc-macro2",
"quote",
@@ -756,7 +741,7 @@ checksum = "7ae2f58a822f08abdaf668897e96a5656fe72f5a9ce66422423e8849384872e6"
name = "typst"
version = "0.1.0"
dependencies = [
- "anyhow",
+ "bytemuck",
"codespan-reporting",
"dirs",
"filedescriptor",
@@ -832,12 +817,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
[[package]]
-name = "unicode-vo"
-version = "0.1.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b1d386ff53b415b7fe27b50bb44679e2cc4660272694b7b6f3326d8480823a94"
-
-[[package]]
name = "unicode-width"
version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -851,28 +830,22 @@ checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "usvg"
-version = "0.19.0"
+version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f472f6f5d41d3eaef059bc893dcd2382eefcdda3e04ebe0b2860c56b538e491e"
+checksum = "00f064d38f79ff69e3160e2fba884e4ede897061c15178041a3976371c68cab1"
dependencies = [
"base64",
"data-url",
"flate2",
"float-cmp",
- "fontdb",
"kurbo",
"log",
"pico-args",
"rctree",
"roxmltree",
- "rustybuzz",
"simplecss",
"siphasher",
"svgtypes",
- "ttf-parser",
- "unicode-bidi",
- "unicode-script",
- "unicode-vo",
]
[[package]]
diff --git a/Cargo.toml b/Cargo.toml
index 0bf68d74..3d2d7706 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -5,55 +5,71 @@ authors = ["The Typst Project Developers"]
edition = "2021"
[features]
-default = ["cli", "fs", "layout-cache"]
-cli = ["anyhow", "codespan-reporting", "fs", "pico-args", "same-file"]
+default = ["fs", "layout-cache"]
+cli = ["fs", "pico-args", "codespan-reporting", "same-file"]
fs = ["dirs", "memmap2", "same-file", "walkdir"]
-layout-cache = ["rand"]
+layout-cache = []
-[profile.dev]
-# Faster compilation
-debug = 0
-
-[profile.dev.package."*"]
-# Faster test execution
-opt-level = 2
+# Dependency updates:
+# - Bump ttf-parser when rustybuzz is updated
+# - Bump usvg and resvg in conjunction with svg2pdf
[dependencies]
+# Workspace
+typst-macros = { path = "./macros" }
+
+# Utilities
+bytemuck = "1"
fxhash = "0.2"
-image = { version = "0.23", default-features = false, features = ["png", "jpeg"] }
itertools = "0.10"
-miniz_oxide = "0.4"
once_cell = "1"
-pdf-writer = "0.4"
-rustybuzz = "0.4"
serde = { version = "1", features = ["derive", "rc"] }
-svg2pdf = { version = "0.1", default-features = false, features = ["text", "png", "jpeg"] }
+
+# Text and font handling
ttf-parser = "0.12"
-typst-macros = { path = "./macros" }
+rustybuzz = "0.4"
unicode-bidi = "0.3.5"
unicode-segmentation = "1"
unicode-xid = "0.2"
-usvg = { version = "0.19", default-features = false, features = ["text"] }
xi-unicode = "0.3"
-anyhow = { version = "1", optional = true }
+
+# Raster and vector graphics handling
+image = { version = "0.23", default-features = false, features = ["png", "jpeg"] }
+resvg = { version = "0.20", default-features = false }
+usvg = { version = "0.20", default-features = false }
+
+# PDF export
+miniz_oxide = "0.4"
+pdf-writer = "0.4"
+svg2pdf = "0.2"
+
+# Command line interface
+pico-args = { version = "0.4", optional = true }
codespan-reporting = { version = "0.11", optional = true }
+same-file = { version = "1", optional = true }
+
+# File system loading
dirs = { version = "4", optional = true }
memmap2 = { version = "0.5", optional = true }
-pico-args = { version = "0.4", optional = true }
-rand = { version = "0.8", optional = true }
-same-file = { version = "1", optional = true }
walkdir = { version = "2", optional = true }
+# Still here for layout cache evaluation, but must be activated manually.
+rand = { version = "0.8", optional = true }
+
[dev-dependencies]
filedescriptor = "0.8"
iai = { git = "https://github.com/reknih/iai" }
-resvg = { version = "0.19", default-features = false, features = ["text"] }
+resvg = { version = "0.20", default-features = false }
tiny-skia = "0.6.2"
walkdir = "2"
-# Dependencies updates:
-# - Bump ttf-parser when rustybuzz is updated
-# - Bump usvg and resvg in conjunction with svg2pdf
+[profile.dev]
+# Faster compilation
+debug = 0
+
+[profile.dev.package."*"]
+# Faster test execution
+opt-level = 2
[[bin]]
name = "typst"
diff --git a/src/layout/incremental.rs b/src/layout/incremental.rs
index 4c046051..f737a3ef 100644
--- a/src/layout/incremental.rs
+++ b/src/layout/incremental.rs
@@ -150,6 +150,7 @@ impl LayoutCache {
entries.retain(|f| f.hits() as f64 / f.age() as f64 > threshold);
}
}
+ #[cfg(feature = "rand")]
EvictionPolicy::Random => {
// Fraction of items that should be kept.
let threshold = self.max_size as f64 / len as f64;
@@ -340,6 +341,7 @@ pub enum EvictionPolicy {
/// Evict the least frequently used item.
LeastFrequentlyUsed,
/// Evict randomly.
+ #[cfg(feature = "rand")]
Random,
/// Use the pattern verdicts.
Patterns,
diff --git a/src/main.rs b/src/main.rs
index fa8b6103..daeff033 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,7 +3,6 @@ use std::io::{self, Write};
use std::path::{Path, PathBuf};
use std::process;
-use anyhow::Context as _;
use codespan_reporting::diagnostic::{Diagnostic, Label};
use codespan_reporting::term::{self, termcolor, Config, Styles};
use same_file::is_same_file;
@@ -15,20 +14,34 @@ use typst::loading::FsLoader;
use typst::source::SourceStore;
use typst::Context;
+const HELP: &'static str = "\
+typst creates PDF files from .typ files
+
+USAGE:
+ typst [OPTIONS] <input.typ> [output.pdf]
+
+OPTIONS:
+ -h, --help Print this help
+
+ARGS:
+ <input.typ> Path input Typst file
+ [output.pdf] Path to output PDF
+";
+
fn main() {
- if let Err(error) = try_main() {
- print_error(error).unwrap();
+ let args = parse_args();
+ let ok = args.is_ok();
+ if let Err(msg) = args.and_then(try_main) {
+ print_error(&msg).unwrap();
+ if !ok {
+ println!("\nfor more information, try --help");
+ }
process::exit(1);
}
}
/// The main compiler logic.
-fn try_main() -> anyhow::Result<()> {
- let args = Args::from_env().unwrap_or_else(|_| {
- print_usage().unwrap();
- process::exit(2);
- });
-
+fn try_main(args: Args) -> Result<(), String> {
// Create a loader for fonts and files.
let mut loader = FsLoader::new();
@@ -51,24 +64,27 @@ fn try_main() -> anyhow::Result<()> {
// Ensure that the source file is not overwritten.
if is_same_file(&args.input, &args.output).unwrap_or(false) {
- anyhow::bail!("source and destination files are the same");
+ Err("source and destination files are the same")?;
}
// Load the source file.
- let id = ctx.sources.load(&args.input).context("source file not found")?;
+ let id = ctx
+ .sources
+ .load(&args.input)
+ .map_err(|_| "failed to load source file")?;
// Typeset.
match ctx.typeset(id) {
// Export the PDF.
Ok(frames) => {
let buffer = export::pdf(&ctx, &frames);
- fs::write(&args.output, buffer).context("failed to write PDF file")?;
+ fs::write(&args.output, buffer).map_err(|_| "failed to write PDF file")?;
}
// Print diagnostics.
Err(errors) => {
print_diagnostics(&ctx.sources, *errors)
- .context("failed to print diagnostics")?;
+ .map_err(|_| "failed to print diagnostics")?;
}
}
@@ -80,55 +96,41 @@ struct Args {
output: PathBuf,
}
-impl Args {
- fn from_env() -> Result<Self, anyhow::Error> {
- let mut parser = pico_args::Arguments::from_env();
-
- // Parse free-standing arguments.
- let input = parser.free_from_str::<PathBuf>()?;
- let output = match parser.opt_free_from_str()? {
- Some(output) => output,
- None => {
- let name = input.file_name().context("source path is not a file")?;
- Path::new(name).with_extension("pdf")
- }
- };
-
- // Don't allow excess arguments.
- if !parser.finish().is_empty() {
- anyhow::bail!("too many arguments");
- }
-
- Ok(Self { input, output })
+/// Parse command line arguments.
+fn parse_args() -> Result<Args, String> {
+ let mut args = pico_args::Arguments::from_env();
+ if args.contains(["-h", "--help"]) {
+ print!("{}", HELP);
+ std::process::exit(0);
}
-}
-/// Print a usage message.
-fn print_usage() -> io::Result<()> {
- let mut w = StandardStream::stderr(ColorChoice::Always);
- let styles = Styles::default();
+ let input = args.free_from_str::<PathBuf>().map_err(|_| "missing input file")?;
+ let output = match args.opt_free_from_str().ok().flatten() {
+ Some(output) => output,
+ None => {
+ let name = input.file_name().ok_or("source path does not point to a file")?;
+ Path::new(name).with_extension("pdf")
+ }
+ };
- w.set_color(&styles.header_help)?;
- write!(w, "usage")?;
+ // Don't allow excess arguments.
+ if !args.finish().is_empty() {
+ Err("too many arguments")?;
+ }
- w.set_color(&styles.header_message)?;
- writeln!(w, ": typst <input.typ> [output.pdf]")
+ Ok(Args { input, output })
}
-/// Print an error outside of a source file.
-fn print_error(error: anyhow::Error) -> io::Result<()> {
+/// Print an application-level error (independent from a source file).
+fn print_error(msg: &str) -> io::Result<()> {
let mut w = StandardStream::stderr(ColorChoice::Always);
let styles = Styles::default();
- for (i, cause) in error.chain().enumerate() {
- w.set_color(&styles.header_error)?;
- write!(w, "{}", if i == 0 { "error" } else { "cause" })?;
-
- w.set_color(&styles.header_message)?;
- writeln!(w, ": {}", cause)?;
- }
+ w.set_color(&styles.header_error)?;
+ write!(w, "error")?;
- w.reset()
+ w.reset()?;
+ writeln!(w, ": {msg}.")
}
/// Print diagnostics messages to the terminal.
diff --git a/tests/typeset.rs b/tests/typeset.rs
index 60214b9f..a4e20774 100644
--- a/tests/typeset.rs
+++ b/tests/typeset.rs
@@ -760,7 +760,12 @@ fn draw_image(
let w = (scale * view_width.max(aspect * view_height)).ceil() as u32;
let h = ((w as f32) / aspect).ceil() as u32;
let mut pixmap = sk::Pixmap::new(w, h).unwrap();
- resvg::render(&tree, FitTo::Size(w, h), pixmap.as_mut());
+ resvg::render(
+ &tree,
+ FitTo::Size(w, h),
+ sk::Transform::identity(),
+ pixmap.as_mut(),
+ );
pixmap
}
};
@@ -838,7 +843,7 @@ fn convert_usvg_fill(fill: &usvg::Fill) -> (sk::Paint<'static>, sk::FillRule) {
let mut paint = sk::Paint::default();
paint.anti_alias = true;
- if let usvg::Paint::Color(usvg::Color { red, green, blue, alpha: _ }) = fill.paint {
+ if let usvg::Paint::Color(usvg::Color { red, green, blue }) = fill.paint {
paint.set_color_rgba8(red, green, blue, fill.opacity.to_u8())
}