summaryrefslogtreecommitdiff
path: root/src/lib.rs
blob: 4d4cbb8b342f44a9ff6a20e79013bde0ba89c336 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//! The compiler for the _Typst_ markup language.
//!
//! # Steps
//! - **Parsing:** The compiler first transforms a plain string into an
//!   [iterator of tokens][tokens]. This token stream is [parsed] into a [syntax
//!   tree]. The tree itself is untyped, but the [AST] module provides a typed
//!   layer over it.
//! - **Evaluation:** The next step is to [evaluate] the markup. This produces a
//!   [module], consisting of a scope of values that were exported by the code
//!   and [content], a hierarchical, styled representation of what was written
//!   in the source file. The nodes of the content tree are well structured and
//!   order-independent and thus much better suited for further processing than
//!   the raw markup.
//! - **Typesetting:** Next, the content is [typeset] into a [document]
//!   containing one [frame] per page with elements and fixed positions.
//! - **Exporting:** These frames can finally be exported into an output format
//!   (currently supported are [PDF] and [raster images]).
//!
//! [tokens]: syntax::Tokens
//! [parsed]: syntax::parse
//! [syntax tree]: syntax::SyntaxNode
//! [AST]: syntax::ast
//! [evaluate]: model::eval
//! [module]: model::Module
//! [content]: model::Content
//! [typeset]: model::typeset
//! [document]: doc::Document
//! [frame]: doc::Frame
//! [PDF]: export::pdf
//! [raster images]: export::render

#![recursion_limit = "1000"]

extern crate self as typst;

#[macro_use]
pub mod util;
#[macro_use]
pub mod geom;
#[macro_use]
pub mod diag;
#[macro_use]
pub mod model;
pub mod doc;
pub mod export;
pub mod font;
pub mod ide;
pub mod image;
pub mod syntax;

use std::path::Path;

use comemo::{Prehashed, Track};
use model::Tracer;

use crate::diag::{FileResult, SourceResult};
use crate::doc::Document;
use crate::font::{Font, FontBook};
use crate::model::{Library, Route};
use crate::syntax::{Source, SourceId};
use crate::util::Buffer;

/// Compile a source file into a fully layouted document.
pub fn compile(world: &(dyn World + 'static), source: &Source) -> SourceResult<Document> {
    // Evaluate the source file into a module.
    let route = Route::default();
    let mut tracer = Tracer::default();
    let module = model::eval(world.track(), route.track(), tracer.track_mut(), source)?;

    // Typeset the module's contents.
    model::typeset(world.track(), &module.content())
}

/// The environment in which typesetting occurs.
#[comemo::track]
pub trait World {
    /// The path relative to which absolute paths are.
    fn root(&self) -> &Path;

    /// The standard library.
    fn library(&self) -> &Prehashed<Library>;

    /// Metadata about all known fonts.
    fn book(&self) -> &Prehashed<FontBook>;

    /// Try to access the font with the given id.
    fn font(&self, id: usize) -> Option<Font>;

    /// Try to access a file at a path.
    fn file(&self, path: &Path) -> FileResult<Buffer>;

    /// Try to resolve the unique id of a source file.
    fn resolve(&self, path: &Path) -> FileResult<SourceId>;

    /// Access a source file by id.
    fn source(&self, id: SourceId) -> &Source;
}