mirror of
https://github.com/typst/typst
synced 2025-05-14 04:56:26 +08:00
Separate typesetting and compilation
This commit is contained in:
parent
8d3c68a1de
commit
96f72eee6c
@ -30,12 +30,12 @@ type CodespanError = codespan_reporting::files::Error;
|
|||||||
|
|
||||||
/// What to do.
|
/// What to do.
|
||||||
enum Command {
|
enum Command {
|
||||||
Typeset(TypesetCommand),
|
Compile(CompileCommand),
|
||||||
Fonts(FontsCommand),
|
Fonts(FontsCommand),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Typeset a .typ file into a PDF file.
|
/// Compile a .typ file into a PDF file.
|
||||||
struct TypesetCommand {
|
struct CompileCommand {
|
||||||
input: PathBuf,
|
input: PathBuf,
|
||||||
output: PathBuf,
|
output: PathBuf,
|
||||||
root: Option<PathBuf>,
|
root: Option<PathBuf>,
|
||||||
@ -110,7 +110,7 @@ fn parse_args() -> StrResult<Command> {
|
|||||||
let root = args.opt_value_from_str("--root").map_err(|_| "missing root path")?;
|
let root = args.opt_value_from_str("--root").map_err(|_| "missing root path")?;
|
||||||
let watch = args.contains(["-w", "--watch"]);
|
let watch = args.contains(["-w", "--watch"]);
|
||||||
let (input, output) = parse_input_output(&mut args, "pdf")?;
|
let (input, output) = parse_input_output(&mut args, "pdf")?;
|
||||||
Command::Typeset(TypesetCommand { input, output, watch, root })
|
Command::Compile(CompileCommand { input, output, watch, root })
|
||||||
};
|
};
|
||||||
|
|
||||||
// Don't allow excess arguments.
|
// Don't allow excess arguments.
|
||||||
@ -164,13 +164,13 @@ fn print_error(msg: &str) -> io::Result<()> {
|
|||||||
/// Dispatch a command.
|
/// Dispatch a command.
|
||||||
fn dispatch(command: Command) -> StrResult<()> {
|
fn dispatch(command: Command) -> StrResult<()> {
|
||||||
match command {
|
match command {
|
||||||
Command::Typeset(command) => typeset(command),
|
Command::Compile(command) => compile(command),
|
||||||
Command::Fonts(command) => fonts(command),
|
Command::Fonts(command) => fonts(command),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute a typesetting command.
|
/// Execute a compilation command.
|
||||||
fn typeset(command: TypesetCommand) -> StrResult<()> {
|
fn compile(command: CompileCommand) -> StrResult<()> {
|
||||||
let root = if let Some(root) = &command.root {
|
let root = if let Some(root) = &command.root {
|
||||||
root.clone()
|
root.clone()
|
||||||
} else if let Some(dir) = command.input.parent() {
|
} else if let Some(dir) = command.input.parent() {
|
||||||
@ -182,8 +182,8 @@ fn typeset(command: TypesetCommand) -> StrResult<()> {
|
|||||||
// Create the world that serves sources, fonts and files.
|
// Create the world that serves sources, fonts and files.
|
||||||
let mut world = SystemWorld::new(root);
|
let mut world = SystemWorld::new(root);
|
||||||
|
|
||||||
// Typeset.
|
// Perform initial compilation.
|
||||||
typeset_once(&mut world, &command)?;
|
compile_once(&mut world, &command)?;
|
||||||
|
|
||||||
if !command.watch {
|
if !command.watch {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -221,20 +221,20 @@ fn typeset(command: TypesetCommand) -> StrResult<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if recompile {
|
if recompile {
|
||||||
typeset_once(&mut world, &command)?;
|
compile_once(&mut world, &command)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Typeset a single time.
|
/// Compile a single time.
|
||||||
fn typeset_once(world: &mut SystemWorld, command: &TypesetCommand) -> StrResult<()> {
|
fn compile_once(world: &mut SystemWorld, command: &CompileCommand) -> StrResult<()> {
|
||||||
status(command, Status::Compiling).unwrap();
|
status(command, Status::Compiling).unwrap();
|
||||||
world.reset();
|
world.reset();
|
||||||
|
|
||||||
let main = world.resolve(&command.input).map_err(|err| err.to_string())?;
|
let main = world.resolve(&command.input).map_err(|err| err.to_string())?;
|
||||||
let source = world.source(main);
|
let source = world.source(main);
|
||||||
|
|
||||||
match typst::typeset(world, source) {
|
match typst::compile(world, source) {
|
||||||
// Export the PDF.
|
// Export the PDF.
|
||||||
Ok(frames) => {
|
Ok(frames) => {
|
||||||
let buffer = typst::export::pdf(&frames);
|
let buffer = typst::export::pdf(&frames);
|
||||||
@ -254,7 +254,7 @@ fn typeset_once(world: &mut SystemWorld, command: &TypesetCommand) -> StrResult<
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Clear the terminal and render the status message.
|
/// Clear the terminal and render the status message.
|
||||||
fn status(command: &TypesetCommand, status: Status) -> io::Result<()> {
|
fn status(command: &CompileCommand, status: Status) -> io::Result<()> {
|
||||||
if !command.watch {
|
if !command.watch {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
12
src/lib.rs
12
src/lib.rs
@ -49,16 +49,16 @@ use comemo::{Prehashed, Track};
|
|||||||
use crate::diag::{FileResult, SourceResult};
|
use crate::diag::{FileResult, SourceResult};
|
||||||
use crate::font::{Font, FontBook};
|
use crate::font::{Font, FontBook};
|
||||||
use crate::frame::Frame;
|
use crate::frame::Frame;
|
||||||
use crate::model::{Library, Route, StyleChain};
|
use crate::model::{Library, Route};
|
||||||
use crate::syntax::{Source, SourceId};
|
use crate::syntax::{Source, SourceId};
|
||||||
use crate::util::Buffer;
|
use crate::util::Buffer;
|
||||||
|
|
||||||
/// Typeset a source file into a collection of layouted frames.
|
/// Compile a source file into a collection of layouted frames.
|
||||||
///
|
///
|
||||||
/// Returns either a vector of frames representing individual pages or
|
/// Returns either a vector of frames representing individual pages or
|
||||||
/// diagnostics in the form of a vector of error message with file and span
|
/// diagnostics in the form of a vector of error message with file and span
|
||||||
/// information.
|
/// information.
|
||||||
pub fn typeset(
|
pub fn compile(
|
||||||
world: &(dyn World + 'static),
|
world: &(dyn World + 'static),
|
||||||
source: &Source,
|
source: &Source,
|
||||||
) -> SourceResult<Vec<Frame>> {
|
) -> SourceResult<Vec<Frame>> {
|
||||||
@ -66,10 +66,8 @@ pub fn typeset(
|
|||||||
let route = Route::default();
|
let route = Route::default();
|
||||||
let module = model::eval(world.track(), route.track(), source)?;
|
let module = model::eval(world.track(), route.track(), source)?;
|
||||||
|
|
||||||
// Layout the module's contents.
|
// Typeset the module's contents.
|
||||||
let library = world.library();
|
model::typeset(world.track(), &module.content)
|
||||||
let styles = StyleChain::with_root(&library.styles);
|
|
||||||
(library.items.layout)(&module.content, world.track(), styles)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The environment in which typesetting occurs.
|
/// The environment in which typesetting occurs.
|
||||||
|
@ -21,6 +21,7 @@ mod func;
|
|||||||
mod methods;
|
mod methods;
|
||||||
mod ops;
|
mod ops;
|
||||||
mod scope;
|
mod scope;
|
||||||
|
mod typeset;
|
||||||
mod vm;
|
mod vm;
|
||||||
|
|
||||||
#[doc(hidden)]
|
#[doc(hidden)]
|
||||||
@ -38,5 +39,6 @@ pub use self::library::*;
|
|||||||
pub use self::scope::*;
|
pub use self::scope::*;
|
||||||
pub use self::str::*;
|
pub use self::str::*;
|
||||||
pub use self::styles::*;
|
pub use self::styles::*;
|
||||||
|
pub use self::typeset::*;
|
||||||
pub use self::value::*;
|
pub use self::value::*;
|
||||||
pub use self::vm::*;
|
pub use self::vm::*;
|
||||||
|
17
src/model/typeset.rs
Normal file
17
src/model/typeset.rs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
use comemo::Tracked;
|
||||||
|
|
||||||
|
use super::{Content, StyleChain};
|
||||||
|
use crate::diag::SourceResult;
|
||||||
|
use crate::frame::Frame;
|
||||||
|
use crate::World;
|
||||||
|
|
||||||
|
/// Typeset content into a collection of layouted frames.
|
||||||
|
///
|
||||||
|
/// Returns either a vector of frames representing individual pages or
|
||||||
|
/// diagnostics in the form of a vector of error message with file and span
|
||||||
|
/// information.
|
||||||
|
pub fn typeset(world: Tracked<dyn World>, content: &Content) -> SourceResult<Vec<Frame>> {
|
||||||
|
let library = world.library();
|
||||||
|
let styles = StyleChain::with_root(&library.styles);
|
||||||
|
(library.items.layout)(content, world, styles)
|
||||||
|
}
|
@ -21,6 +21,7 @@ main!(
|
|||||||
bench_edit,
|
bench_edit,
|
||||||
bench_eval,
|
bench_eval,
|
||||||
bench_typeset,
|
bench_typeset,
|
||||||
|
bench_compile,
|
||||||
bench_highlight,
|
bench_highlight,
|
||||||
bench_render,
|
bench_render,
|
||||||
);
|
);
|
||||||
@ -81,12 +82,19 @@ fn bench_eval(iai: &mut Iai) {
|
|||||||
|
|
||||||
fn bench_typeset(iai: &mut Iai) {
|
fn bench_typeset(iai: &mut Iai) {
|
||||||
let world = BenchWorld::new();
|
let world = BenchWorld::new();
|
||||||
iai.run(|| typst::typeset(&world, &world.source));
|
let route = typst::model::Route::default();
|
||||||
|
let module = typst::model::eval(world.track(), route.track(), &world.source).unwrap();
|
||||||
|
iai.run(|| typst::model::typeset(world.track(), &module.content));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn bench_compile(iai: &mut Iai) {
|
||||||
|
let world = BenchWorld::new();
|
||||||
|
iai.run(|| typst::compile(&world, &world.source));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bench_render(iai: &mut Iai) {
|
fn bench_render(iai: &mut Iai) {
|
||||||
let world = BenchWorld::new();
|
let world = BenchWorld::new();
|
||||||
let frames = typst::typeset(&world, &world.source).unwrap();
|
let frames = typst::compile(&world, &world.source).unwrap();
|
||||||
iai.run(|| typst::export::render(&frames[0], 1.0))
|
iai.run(|| typst::export::render(&frames[0], 1.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -424,7 +424,7 @@ fn test_part(
|
|||||||
println!("Model:\n{:#?}\n", module.content);
|
println!("Model:\n{:#?}\n", module.content);
|
||||||
}
|
}
|
||||||
|
|
||||||
let (mut frames, errors) = match typst::typeset(world, source) {
|
let (mut frames, errors) = match typst::compile(world, source) {
|
||||||
Ok(frames) => (frames, vec![]),
|
Ok(frames) => (frames, vec![]),
|
||||||
Err(errors) => (vec![], *errors),
|
Err(errors) => (vec![], *errors),
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user