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.
|
||||
enum Command {
|
||||
Typeset(TypesetCommand),
|
||||
Compile(CompileCommand),
|
||||
Fonts(FontsCommand),
|
||||
}
|
||||
|
||||
/// Typeset a .typ file into a PDF file.
|
||||
struct TypesetCommand {
|
||||
/// Compile a .typ file into a PDF file.
|
||||
struct CompileCommand {
|
||||
input: PathBuf,
|
||||
output: 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 watch = args.contains(["-w", "--watch"]);
|
||||
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.
|
||||
@ -164,13 +164,13 @@ fn print_error(msg: &str) -> io::Result<()> {
|
||||
/// Dispatch a command.
|
||||
fn dispatch(command: Command) -> StrResult<()> {
|
||||
match command {
|
||||
Command::Typeset(command) => typeset(command),
|
||||
Command::Compile(command) => compile(command),
|
||||
Command::Fonts(command) => fonts(command),
|
||||
}
|
||||
}
|
||||
|
||||
/// Execute a typesetting command.
|
||||
fn typeset(command: TypesetCommand) -> StrResult<()> {
|
||||
/// Execute a compilation command.
|
||||
fn compile(command: CompileCommand) -> StrResult<()> {
|
||||
let root = if let Some(root) = &command.root {
|
||||
root.clone()
|
||||
} 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.
|
||||
let mut world = SystemWorld::new(root);
|
||||
|
||||
// Typeset.
|
||||
typeset_once(&mut world, &command)?;
|
||||
// Perform initial compilation.
|
||||
compile_once(&mut world, &command)?;
|
||||
|
||||
if !command.watch {
|
||||
return Ok(());
|
||||
@ -221,20 +221,20 @@ fn typeset(command: TypesetCommand) -> StrResult<()> {
|
||||
}
|
||||
|
||||
if recompile {
|
||||
typeset_once(&mut world, &command)?;
|
||||
compile_once(&mut world, &command)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Typeset a single time.
|
||||
fn typeset_once(world: &mut SystemWorld, command: &TypesetCommand) -> StrResult<()> {
|
||||
/// Compile a single time.
|
||||
fn compile_once(world: &mut SystemWorld, command: &CompileCommand) -> StrResult<()> {
|
||||
status(command, Status::Compiling).unwrap();
|
||||
world.reset();
|
||||
|
||||
let main = world.resolve(&command.input).map_err(|err| err.to_string())?;
|
||||
let source = world.source(main);
|
||||
|
||||
match typst::typeset(world, source) {
|
||||
match typst::compile(world, source) {
|
||||
// Export the PDF.
|
||||
Ok(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.
|
||||
fn status(command: &TypesetCommand, status: Status) -> io::Result<()> {
|
||||
fn status(command: &CompileCommand, status: Status) -> io::Result<()> {
|
||||
if !command.watch {
|
||||
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::font::{Font, FontBook};
|
||||
use crate::frame::Frame;
|
||||
use crate::model::{Library, Route, StyleChain};
|
||||
use crate::model::{Library, Route};
|
||||
use crate::syntax::{Source, SourceId};
|
||||
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
|
||||
/// diagnostics in the form of a vector of error message with file and span
|
||||
/// information.
|
||||
pub fn typeset(
|
||||
pub fn compile(
|
||||
world: &(dyn World + 'static),
|
||||
source: &Source,
|
||||
) -> SourceResult<Vec<Frame>> {
|
||||
@ -66,10 +66,8 @@ pub fn typeset(
|
||||
let route = Route::default();
|
||||
let module = model::eval(world.track(), route.track(), source)?;
|
||||
|
||||
// Layout the module's contents.
|
||||
let library = world.library();
|
||||
let styles = StyleChain::with_root(&library.styles);
|
||||
(library.items.layout)(&module.content, world.track(), styles)
|
||||
// Typeset the module's contents.
|
||||
model::typeset(world.track(), &module.content)
|
||||
}
|
||||
|
||||
/// The environment in which typesetting occurs.
|
||||
|
@ -21,6 +21,7 @@ mod func;
|
||||
mod methods;
|
||||
mod ops;
|
||||
mod scope;
|
||||
mod typeset;
|
||||
mod vm;
|
||||
|
||||
#[doc(hidden)]
|
||||
@ -38,5 +39,6 @@ pub use self::library::*;
|
||||
pub use self::scope::*;
|
||||
pub use self::str::*;
|
||||
pub use self::styles::*;
|
||||
pub use self::typeset::*;
|
||||
pub use self::value::*;
|
||||
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_eval,
|
||||
bench_typeset,
|
||||
bench_compile,
|
||||
bench_highlight,
|
||||
bench_render,
|
||||
);
|
||||
@ -81,12 +82,19 @@ fn bench_eval(iai: &mut Iai) {
|
||||
|
||||
fn bench_typeset(iai: &mut Iai) {
|
||||
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) {
|
||||
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))
|
||||
}
|
||||
|
||||
|
@ -424,7 +424,7 @@ fn test_part(
|
||||
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![]),
|
||||
Err(errors) => (vec![], *errors),
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user