summaryrefslogtreecommitdiff
path: root/src/lib.rs
blob: 6122ffedacb385b6977b85a29c11f8633a4675c7 (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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//! The compiler for the _Typst_ typesetting language.
//!
//! # Steps
//! - **Parsing:** The parsing step 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 the text,
//!   structure, layouts, etc. of the module. The nodes of the content tree are
//!   well structured and order-independent and thus much better suited for
//!   layouting than the raw markup.
//! - **Layouting:** Next, the content is [layouted] into a portable version of
//!   the typeset document. The output of this is a collection of [`Frame`]s
//!   (one per page), ready for exporting.
//! - **Exporting:** The finished layout can be exported into a supported
//!   format. Currently, the only supported output format is [PDF].
//!
//! [tokens]: parse::Tokens
//! [parsed]: parse::parse
//! [syntax tree]: syntax::SyntaxNode
//! [AST]: syntax::ast
//! [evaluate]: eval::evaluate
//! [module]: eval::Module
//! [content]: model::Content
//! [layouted]: model::layout
//! [PDF]: export::pdf

#![allow(clippy::len_without_is_empty)]
#![allow(clippy::or_fun_call)]
#![allow(clippy::try_err)]

#[macro_use]
pub mod util;
#[macro_use]
pub mod geom;
#[macro_use]
pub mod diag;
#[macro_use]
pub mod eval;
pub mod export;
pub mod font;
pub mod frame;
pub mod image;
pub mod library;
pub mod model;
pub mod parse;
pub mod source;
pub mod syntax;

use std::path::{Path, PathBuf};

use crate::diag::{FileResult, SourceResult};
use crate::eval::Scope;
use crate::font::{Font, FontBook};
use crate::frame::Frame;
use crate::model::StyleMap;
use crate::source::{Source, SourceId};
use crate::util::Buffer;

/// Typeset 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(world: &dyn World, main: SourceId) -> SourceResult<Vec<Frame>> {
    let module = eval::evaluate(world, main, vec![])?;
    model::layout(world, &module.content)
}

/// The environment in which typesetting occurs.
pub trait World {
    /// Access the global configuration.
    fn config(&self) -> &Config;

    /// 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;

    /// Metadata about all known fonts.
    fn book(&self) -> &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>;
}

/// The global configuration for typesetting.
pub struct Config {
    /// The compilation root, relative to which absolute paths are.
    ///
    /// Default: Empty path.
    pub root: PathBuf,
    /// The scope containing definitions that are available everywhere.
    ///
    /// Default: Typst's standard library.
    pub std: Scope,
    /// The default properties for page size, font selection and so on.
    ///
    /// Default: Empty style map.
    pub styles: StyleMap,
}

impl Default for Config {
    fn default() -> Self {
        Self {
            root: PathBuf::new(),
            std: library::new(),
            styles: StyleMap::new(),
        }
    }
}