mirror of
https://github.com/typst/typst
synced 2025-05-14 17:15:28 +08:00
377 lines
10 KiB
Rust
377 lines
10 KiB
Rust
#![allow(unused)]
|
|
|
|
use std::hash::{Hash, Hasher};
|
|
use std::num::NonZeroUsize;
|
|
|
|
use comemo::{Tracked, TrackedMut};
|
|
use typst_syntax::Span;
|
|
use typst_utils::LazyHash;
|
|
|
|
use crate::diag::SourceResult;
|
|
use crate::engine::{Engine, Route, Sink, Traced};
|
|
use crate::foundations::{
|
|
Args, Cast, Closure, Content, Context, Func, Packed, Scope, StyleChain, StyleVec,
|
|
Styles, Value,
|
|
};
|
|
use crate::introspection::{Introspector, Locator, SplitLocator};
|
|
use crate::layout::{
|
|
Abs, BoxElem, ColumnsElem, Fragment, Frame, GridElem, InlineItem, MoveElem, PadElem,
|
|
PagedDocument, Region, Regions, Rel, RepeatElem, RotateElem, ScaleElem, Size,
|
|
SkewElem, StackElem,
|
|
};
|
|
use crate::math::EquationElem;
|
|
use crate::model::{DocumentInfo, EnumElem, ListElem, TableElem};
|
|
use crate::visualize::{
|
|
CircleElem, CurveElem, EllipseElem, ImageElem, LineElem, PathElem, PolygonElem,
|
|
RectElem, SquareElem,
|
|
};
|
|
use crate::World;
|
|
|
|
/// Defines the `Routines` struct.
|
|
macro_rules! routines {
|
|
($(
|
|
$(#[$attr:meta])*
|
|
fn $name:ident $(<$($time:lifetime),*>)? ($($args:tt)*) -> $ret:ty
|
|
)*) => {
|
|
/// Defines implementation of various Typst compiler routines as a table
|
|
/// of function pointers.
|
|
///
|
|
/// This is essentially dynamic linking and done to allow for crate
|
|
/// splitting.
|
|
pub struct Routines {
|
|
$(
|
|
$(#[$attr])*
|
|
pub $name: $(for<$($time),*>)? fn ($($args)*) -> $ret
|
|
),*
|
|
}
|
|
|
|
impl Hash for Routines {
|
|
fn hash<H: Hasher>(&self, _: &mut H) {}
|
|
}
|
|
};
|
|
}
|
|
|
|
routines! {
|
|
/// Evaluates a string as code and return the resulting value.
|
|
fn eval_string(
|
|
routines: &Routines,
|
|
world: Tracked<dyn World + '_>,
|
|
string: &str,
|
|
span: Span,
|
|
mode: EvalMode,
|
|
scope: Scope,
|
|
) -> SourceResult<Value>
|
|
|
|
/// Call the closure in the context with the arguments.
|
|
fn eval_closure(
|
|
func: &Func,
|
|
closure: &LazyHash<Closure>,
|
|
routines: &Routines,
|
|
world: Tracked<dyn World + '_>,
|
|
introspector: Tracked<Introspector>,
|
|
traced: Tracked<Traced>,
|
|
sink: TrackedMut<Sink>,
|
|
route: Tracked<Route>,
|
|
context: Tracked<Context>,
|
|
args: Args,
|
|
) -> SourceResult<Value>
|
|
|
|
/// Realizes content into a flat list of well-known, styled items.
|
|
fn realize<'a>(
|
|
kind: RealizationKind,
|
|
engine: &mut Engine,
|
|
locator: &mut SplitLocator,
|
|
arenas: &'a Arenas,
|
|
content: &'a Content,
|
|
styles: StyleChain<'a>,
|
|
) -> SourceResult<Vec<Pair<'a>>>
|
|
|
|
/// Lays out content into multiple regions.
|
|
fn layout_fragment(
|
|
engine: &mut Engine,
|
|
content: &Content,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
regions: Regions,
|
|
) -> SourceResult<Fragment>
|
|
|
|
/// Lays out content into a single region, producing a single frame.
|
|
fn layout_frame(
|
|
engine: &mut Engine,
|
|
content: &Content,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
region: Region,
|
|
) -> SourceResult<Frame>
|
|
|
|
/// Lays out inline content.
|
|
fn layout_inline(
|
|
engine: &mut Engine,
|
|
children: &StyleVec,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
consecutive: bool,
|
|
region: Size,
|
|
expand: bool,
|
|
) -> SourceResult<Fragment>
|
|
|
|
/// Lays out a [`BoxElem`].
|
|
fn layout_box(
|
|
elem: &Packed<BoxElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
region: Size,
|
|
) -> SourceResult<Frame>
|
|
|
|
/// Lays out a [`ListElem`].
|
|
fn layout_list(
|
|
elem: &Packed<ListElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
regions: Regions,
|
|
) -> SourceResult<Fragment>
|
|
|
|
/// Lays out an [`EnumElem`].
|
|
fn layout_enum(
|
|
elem: &Packed<EnumElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
regions: Regions,
|
|
) -> SourceResult<Fragment>
|
|
|
|
/// Lays out a [`GridElem`].
|
|
fn layout_grid(
|
|
elem: &Packed<GridElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
regions: Regions,
|
|
) -> SourceResult<Fragment>
|
|
|
|
/// Lays out a [`TableElem`].
|
|
fn layout_table(
|
|
elem: &Packed<TableElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
regions: Regions,
|
|
) -> SourceResult<Fragment>
|
|
|
|
/// Lays out a [`StackElem`].
|
|
fn layout_stack(
|
|
elem: &Packed<StackElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
regions: Regions,
|
|
) -> SourceResult<Fragment>
|
|
|
|
/// Lays out a [`ColumnsElem`].
|
|
fn layout_columns(
|
|
elem: &Packed<ColumnsElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
regions: Regions,
|
|
) -> SourceResult<Fragment>
|
|
|
|
/// Lays out a [`MoveElem`].
|
|
fn layout_move(
|
|
elem: &Packed<MoveElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
region: Region,
|
|
) -> SourceResult<Frame>
|
|
|
|
/// Lays out a [`RotateElem`].
|
|
fn layout_rotate(
|
|
elem: &Packed<RotateElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
region: Region,
|
|
) -> SourceResult<Frame>
|
|
|
|
/// Lays out a [`ScaleElem`].
|
|
fn layout_scale(
|
|
elem: &Packed<ScaleElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
region: Region,
|
|
) -> SourceResult<Frame>
|
|
|
|
/// Lays out a [`SkewElem`].
|
|
fn layout_skew(
|
|
elem: &Packed<SkewElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
region: Region,
|
|
) -> SourceResult<Frame>
|
|
|
|
/// Lays out a [`RepeatElem`].
|
|
fn layout_repeat(
|
|
elem: &Packed<RepeatElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
region: Region,
|
|
) -> SourceResult<Frame>
|
|
|
|
/// Lays out a [`PadElem`].
|
|
fn layout_pad(
|
|
elem: &Packed<PadElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
regions: Regions,
|
|
) -> SourceResult<Fragment>
|
|
|
|
/// Lays out a [`LineElem`].
|
|
fn layout_line(
|
|
elem: &Packed<LineElem>,
|
|
_: &mut Engine,
|
|
_: Locator,
|
|
styles: StyleChain,
|
|
region: Region,
|
|
) -> SourceResult<Frame>
|
|
|
|
/// Lays out a [`CurveElem`].
|
|
fn layout_curve(
|
|
elem: &Packed<CurveElem>,
|
|
_: &mut Engine,
|
|
_: Locator,
|
|
styles: StyleChain,
|
|
region: Region,
|
|
) -> SourceResult<Frame>
|
|
|
|
/// Lays out a [`PathElem`].
|
|
fn layout_path(
|
|
elem: &Packed<PathElem>,
|
|
_: &mut Engine,
|
|
_: Locator,
|
|
styles: StyleChain,
|
|
region: Region,
|
|
) -> SourceResult<Frame>
|
|
|
|
/// Lays out a [`PolygonElem`].
|
|
fn layout_polygon(
|
|
elem: &Packed<PolygonElem>,
|
|
_: &mut Engine,
|
|
_: Locator,
|
|
styles: StyleChain,
|
|
region: Region,
|
|
) -> SourceResult<Frame>
|
|
|
|
/// Lays out a [`RectElem`].
|
|
fn layout_rect(
|
|
elem: &Packed<RectElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
region: Region,
|
|
) -> SourceResult<Frame>
|
|
|
|
/// Lays out a [`SquareElem`].
|
|
fn layout_square(
|
|
elem: &Packed<SquareElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
region: Region,
|
|
) -> SourceResult<Frame>
|
|
|
|
/// Lays out a [`EllipseElem`].
|
|
fn layout_ellipse(
|
|
elem: &Packed<EllipseElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
region: Region,
|
|
) -> SourceResult<Frame>
|
|
|
|
/// Lays out a [`CircleElem`].
|
|
fn layout_circle(
|
|
elem: &Packed<CircleElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
region: Region,
|
|
) -> SourceResult<Frame>
|
|
|
|
/// Lays out an [`ImageElem`].
|
|
fn layout_image(
|
|
elem: &Packed<ImageElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
region: Region,
|
|
) -> SourceResult<Frame>
|
|
|
|
/// Lays out an [`EquationElem`] in a paragraph.
|
|
fn layout_equation_inline(
|
|
elem: &Packed<EquationElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
region: Size,
|
|
) -> SourceResult<Vec<InlineItem>>
|
|
|
|
/// Lays out an [`EquationElem`] in a flow.
|
|
fn layout_equation_block(
|
|
elem: &Packed<EquationElem>,
|
|
engine: &mut Engine,
|
|
locator: Locator,
|
|
styles: StyleChain,
|
|
regions: Regions,
|
|
) -> SourceResult<Fragment>
|
|
}
|
|
|
|
/// In which mode to evaluate a string.
|
|
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, Cast)]
|
|
pub enum EvalMode {
|
|
/// Evaluate as code, as after a hash.
|
|
Code,
|
|
/// Evaluate as markup, like in a Typst file.
|
|
Markup,
|
|
/// Evaluate as math, as in an equation.
|
|
Math,
|
|
}
|
|
|
|
/// Defines what kind of realization we are performing.
|
|
pub enum RealizationKind<'a> {
|
|
/// This the root realization for layout. Requires a mutable reference
|
|
/// to document metadata that will be filled from `set document` rules.
|
|
LayoutDocument(&'a mut DocumentInfo),
|
|
/// A nested realization in a container (e.g. a `block`).
|
|
LayoutFragment,
|
|
/// This the root realization for HTML. Requires a mutable reference
|
|
/// to document metadata that will be filled from `set document` rules.
|
|
HtmlDocument(&'a mut DocumentInfo),
|
|
/// A nested realization in a container (e.g. a `block`).
|
|
HtmlFragment,
|
|
/// A realization within math.
|
|
Math,
|
|
}
|
|
|
|
/// Temporary storage arenas for lifetime extension during realization.
|
|
///
|
|
/// Must be kept live while the content returned from realization is processed.
|
|
#[derive(Default)]
|
|
pub struct Arenas {
|
|
/// A typed arena for owned content.
|
|
pub content: typed_arena::Arena<Content>,
|
|
/// A typed arena for owned styles.
|
|
pub styles: typed_arena::Arena<Styles>,
|
|
/// An untyped arena for everything that is `Copy`.
|
|
pub bump: bumpalo::Bump,
|
|
}
|
|
|
|
/// A pair of content and a style chain that applies to it.
|
|
pub type Pair<'a> = (&'a Content, StyleChain<'a>);
|