From c0e972b91a7bf8d22cd24a38fc92a9c6214c8a0c Mon Sep 17 00:00:00 2001 From: Laurenz Date: Tue, 18 Oct 2022 00:02:38 +0200 Subject: Reduce dependencies from compiler on library --- src/model/collapse.rs | 61 -------------------- src/model/content.rs | 32 +++-------- src/model/eval.rs | 154 ++++++++++++++++++++++---------------------------- src/model/layout.rs | 41 +------------- src/model/recipe.rs | 2 +- src/model/styles.rs | 12 ---- src/model/value.rs | 8 +-- src/model/vm.rs | 7 ++- 8 files changed, 90 insertions(+), 227 deletions(-) (limited to 'src/model') diff --git a/src/model/collapse.rs b/src/model/collapse.rs index 258f577e..5a0d6531 100644 --- a/src/model/collapse.rs +++ b/src/model/collapse.rs @@ -114,64 +114,3 @@ impl<'a, T> Default for CollapsingBuilder<'a, T> { Self::new() } } - -#[cfg(test)] -mod tests { - use super::*; - use crate::library::layout::FlowChild; - use crate::library::prelude::*; - - #[track_caller] - fn test(builder: CollapsingBuilder, expected: &[T]) - where - T: Debug + PartialEq, - { - let result = builder.finish().0; - let items: Vec<_> = result.items().collect(); - let expected: Vec<_> = expected.iter().collect(); - assert_eq!(items, expected); - } - - fn node() -> FlowChild { - FlowChild::Node(Content::Text("Hi".into()).pack()) - } - - fn abs(pt: f64) -> FlowChild { - FlowChild::Spacing(Length::pt(pt).into()) - } - - #[test] - fn test_collapsing_weak() { - let mut builder = CollapsingBuilder::new(); - let styles = StyleChain::default(); - builder.weak(FlowChild::Colbreak, styles, 0); - builder.supportive(node(), styles); - builder.weak(abs(10.0), styles, 0); - builder.ignorant(FlowChild::Colbreak, styles); - builder.weak(abs(20.0), styles, 0); - builder.supportive(node(), styles); - builder.weak(abs(10.0), styles, 0); - builder.weak(abs(20.0), styles, 1); - builder.supportive(node(), styles); - test(builder, &[ - node(), - FlowChild::Colbreak, - abs(20.0), - node(), - abs(10.0), - node(), - ]); - } - - #[test] - fn test_collapsing_destructive() { - let mut builder = CollapsingBuilder::new(); - let styles = StyleChain::default(); - builder.supportive(node(), styles); - builder.weak(abs(10.0), styles, 0); - builder.destructive(FlowChild::Colbreak, styles); - builder.weak(abs(20.0), styles, 0); - builder.supportive(node(), styles); - test(builder, &[node(), FlowChild::Colbreak, node()]); - } -} diff --git a/src/model/content.rs b/src/model/content.rs index 5f0536c3..428865f3 100644 --- a/src/model/content.rs +++ b/src/model/content.rs @@ -1,23 +1,24 @@ -use std::fmt::Debug; +use std::fmt::{self, Debug, Formatter}; use std::hash::Hash; use std::iter::Sum; use std::mem; use std::ops::{Add, AddAssign}; +use std::sync::Arc; use comemo::Tracked; use typed_arena::Arena; use super::{ - Barrier, CollapsingBuilder, Interruption, Key, Layout, LayoutNode, Property, Show, - ShowNode, StyleEntry, StyleMap, StyleVecBuilder, Target, + Barrier, CollapsingBuilder, Dict, Interruption, Key, Layout, LayoutNode, Property, + Regions, Selector, Show, ShowNode, StyleChain, StyleEntry, StyleMap, StyleVecBuilder, + Target, }; -use crate::diag::StrResult; +use crate::diag::{SourceResult, StrResult}; +use crate::frame::{Frame, Role}; +use crate::geom::{Length, Numeric}; use crate::library::layout::{FlowChild, FlowNode, PageNode, PlaceNode, Spacing}; -use crate::library::prelude::*; use crate::library::structure::{DocNode, ListItem, ListNode, DESC, ENUM, LIST}; -use crate::library::text::{ - DecoNode, EmphNode, ParChild, ParNode, StrongNode, UNDERLINE, -}; +use crate::library::text::{ParChild, ParNode}; use crate::util::EcoString; use crate::World; @@ -173,21 +174,6 @@ impl Content { self.clone().styled_with_entry(StyleEntry::Unguard(sel)) } - /// Make this content strong. - pub fn strong(self) -> Self { - Self::show(StrongNode(self)) - } - - /// Make this content emphasized. - pub fn emph(self) -> Self { - Self::show(EmphNode(self)) - } - - /// Underline this content. - pub fn underlined(self) -> Self { - Self::show(DecoNode::(self)) - } - /// Add weak vertical spacing above and below the node. pub fn spaced(self, above: Option, below: Option) -> Self { if above.is_none() && below.is_none() { diff --git a/src/model/eval.rs b/src/model/eval.rs index aa5f0378..6658e244 100644 --- a/src/model/eval.rs +++ b/src/model/eval.rs @@ -141,7 +141,7 @@ fn eval_markup( ast::MarkupNode::Expr(ast::Expr::Wrap(wrap)) => { let tail = eval_markup(vm, nodes)?; vm.scopes.top.define(wrap.binding().take(), tail); - wrap.body().eval(vm)?.display() + wrap.body().eval(vm)?.display(vm.world) } _ => node.eval(vm)?, @@ -181,7 +181,7 @@ impl Eval for ast::MarkupNode { Self::Desc(v) => v.eval(vm), Self::Label(v) => v.eval(vm), Self::Ref(v) => v.eval(vm), - Self::Expr(v) => v.eval(vm).map(Value::display), + Self::Expr(v) => v.eval(vm).map(|value| value.display(vm.world)), } } } @@ -242,9 +242,7 @@ impl Eval for ast::Strong { type Output = Content; fn eval(&self, vm: &mut Vm) -> SourceResult { - Ok(Content::show(library::text::StrongNode( - self.body().eval(vm)?, - ))) + Ok((vm.roles().strong)(self.body().eval(vm)?)) } } @@ -252,34 +250,80 @@ impl Eval for ast::Emph { type Output = Content; fn eval(&self, vm: &mut Vm) -> SourceResult { - Ok(Content::show(library::text::EmphNode( - self.body().eval(vm)?, - ))) + Ok((vm.roles().emph)(self.body().eval(vm)?)) + } +} + +impl Eval for ast::Raw { + type Output = Content; + + fn eval(&self, vm: &mut Vm) -> SourceResult { + let text = self.text().clone(); + let lang = self.lang().cloned(); + let block = self.block(); + Ok((vm.roles().raw)(text, lang, block)) } } impl Eval for ast::Link { type Output = Content; - fn eval(&self, _: &mut Vm) -> SourceResult { - Ok(Content::show(library::text::LinkNode::from_url( - self.url().clone(), - ))) + fn eval(&self, vm: &mut Vm) -> SourceResult { + Ok((vm.roles().link)(self.url().clone())) } } -impl Eval for ast::Raw { +impl Eval for ast::Label { type Output = Content; fn eval(&self, _: &mut Vm) -> SourceResult { - let content = Content::show(library::text::RawNode { - text: self.text().clone(), - block: self.block(), - }); - Ok(match self.lang() { - Some(_) => content.styled(library::text::RawNode::LANG, self.lang().cloned()), - None => content, - }) + Ok(Content::Empty) + } +} + +impl Eval for ast::Ref { + type Output = Content; + + fn eval(&self, vm: &mut Vm) -> SourceResult { + Ok((vm.roles().ref_)(self.get().clone())) + } +} + +impl Eval for ast::Heading { + type Output = Content; + + fn eval(&self, vm: &mut Vm) -> SourceResult { + let level = self.level(); + let body = self.body().eval(vm)?; + Ok((vm.roles().heading)(level, body)) + } +} + +impl Eval for ast::ListItem { + type Output = Content; + + fn eval(&self, vm: &mut Vm) -> SourceResult { + Ok((vm.roles().list_item)(self.body().eval(vm)?)) + } +} + +impl Eval for ast::EnumItem { + type Output = Content; + + fn eval(&self, vm: &mut Vm) -> SourceResult { + let number = self.number(); + let body = self.body().eval(vm)?; + Ok((vm.roles().enum_item)(number, body)) + } +} + +impl Eval for ast::DescItem { + type Output = Content; + + fn eval(&self, vm: &mut Vm) -> SourceResult { + let term = self.term().eval(vm)?; + let body = self.body().eval(vm)?; + Ok((vm.roles().desc_item)(term, body)) } } @@ -318,7 +362,7 @@ impl Eval for ast::MathNode { ), node.span(), ), - Self::Expr(expr) => match expr.eval(vm)?.display() { + Self::Expr(expr) => match expr.eval(vm)?.display(vm.world) { Content::Text(text) => library::math::MathNode::Atom(text), _ => bail!(expr.span(), "expected text"), }, @@ -369,68 +413,6 @@ impl Eval for ast::Align { } } -impl Eval for ast::Heading { - type Output = Content; - - fn eval(&self, vm: &mut Vm) -> SourceResult { - Ok(Content::show(library::structure::HeadingNode { - body: self.body().eval(vm)?, - level: self.level(), - })) - } -} - -impl Eval for ast::ListItem { - type Output = Content; - - fn eval(&self, vm: &mut Vm) -> SourceResult { - let body = Box::new(self.body().eval(vm)?); - Ok(Content::Item(library::structure::ListItem::List(body))) - } -} - -impl Eval for ast::EnumItem { - type Output = Content; - - fn eval(&self, vm: &mut Vm) -> SourceResult { - let number = self.number(); - let body = Box::new(self.body().eval(vm)?); - Ok(Content::Item(library::structure::ListItem::Enum( - number, body, - ))) - } -} - -impl Eval for ast::DescItem { - type Output = Content; - - fn eval(&self, vm: &mut Vm) -> SourceResult { - let term = self.term().eval(vm)?; - let body = self.body().eval(vm)?; - Ok(Content::Item(library::structure::ListItem::Desc(Box::new( - library::structure::DescItem { term, body }, - )))) - } -} - -impl Eval for ast::Label { - type Output = Content; - - fn eval(&self, _: &mut Vm) -> SourceResult { - Ok(Content::Empty) - } -} - -impl Eval for ast::Ref { - type Output = Content; - - fn eval(&self, _: &mut Vm) -> SourceResult { - Ok(Content::show(library::structure::RefNode( - self.get().clone(), - ))) - } -} - impl Eval for ast::Expr { type Output = Value; @@ -530,7 +512,7 @@ fn eval_code( break; } - let tail = eval_code(vm, exprs)?.display(); + let tail = eval_code(vm, exprs)?.display(vm.world); Value::Content(tail.styled_with_map(styles)) } ast::Expr::Show(show) => { @@ -540,7 +522,7 @@ fn eval_code( break; } - let tail = eval_code(vm, exprs)?.display(); + let tail = eval_code(vm, exprs)?.display(vm.world); Value::Content(tail.styled_with_entry(entry)) } ast::Expr::Wrap(wrap) => { diff --git a/src/model/layout.rs b/src/model/layout.rs index 09888ba5..5248157b 100644 --- a/src/model/layout.rs +++ b/src/model/layout.rs @@ -8,19 +8,13 @@ use std::sync::Arc; use comemo::{Prehashed, Tracked}; use super::{Barrier, NodeId, Resolve, StyleChain, StyleEntry}; -use super::{Builder, Content, RawAlign, RawLength, Scratch}; +use super::{Builder, Content, RawLength, Scratch}; use crate::diag::SourceResult; use crate::frame::{Element, Frame}; -use crate::geom::{ - Align, Geometry, Length, Paint, Point, Relative, Sides, Size, Spec, Stroke, -}; -use crate::library::graphics::MoveNode; -use crate::library::layout::{AlignNode, PadNode}; +use crate::geom::{Align, Geometry, Length, Paint, Point, Relative, Size, Spec, Stroke}; use crate::World; /// Layout content into a collection of pages. -/// -/// Relayouts until all pinned locations are converged. #[comemo::memoize] pub fn layout(world: Tracked, content: &Content) -> SourceResult> { let styles = StyleChain::with_root(&world.config().styles); @@ -196,37 +190,6 @@ impl LayoutNode { pub fn stroked(self, stroke: Stroke) -> Self { StrokeNode { stroke, child: self }.pack() } - - /// Set alignments for this node. - pub fn aligned(self, aligns: Spec>) -> Self { - if aligns.any(Option::is_some) { - AlignNode { aligns, child: self }.pack() - } else { - self - } - } - - /// Pad this node at the sides. - pub fn padded(self, padding: Sides>) -> Self { - if !padding.left.is_zero() - || !padding.top.is_zero() - || !padding.right.is_zero() - || !padding.bottom.is_zero() - { - PadNode { padding, child: self }.pack() - } else { - self - } - } - - /// Transform this node's contents without affecting layout. - pub fn moved(self, delta: Spec>) -> Self { - if delta.any(|r| !r.is_zero()) { - MoveNode { delta, child: self }.pack() - } else { - self - } - } } impl Layout for LayoutNode { diff --git a/src/model/recipe.rs b/src/model/recipe.rs index 05ef07a6..46dad6d1 100644 --- a/src/model/recipe.rs +++ b/src/model/recipe.rs @@ -89,7 +89,7 @@ impl Recipe { Args::new(self.func.span, [arg()]) }; - Ok(self.func.v.call_detached(world, args)?.display()) + Ok(self.func.v.call_detached(world, args)?.display(world)) } /// What kind of structure the property interrupts. diff --git a/src/model/styles.rs b/src/model/styles.rs index 76199ca1..d21f3a9f 100644 --- a/src/model/styles.rs +++ b/src/model/styles.rs @@ -8,7 +8,6 @@ use comemo::Tracked; use super::{Barrier, Content, Key, Property, Recipe, Selector, Show, Target}; use crate::diag::SourceResult; use crate::frame::Role; -use crate::library::text::{FontFamily, TextNode}; use crate::util::ReadableTypeId; use crate::World; @@ -55,17 +54,6 @@ impl StyleMap { } } - /// Set a font family composed of a preferred family and existing families - /// from a style chain. - pub fn set_family(&mut self, preferred: FontFamily, existing: StyleChain) { - self.set( - TextNode::FAMILY, - iter::once(preferred) - .chain(existing.get(TextNode::FAMILY).iter().cloned()) - .collect(), - ); - } - /// Whether the map contains a style property for the given key. pub fn contains<'a, K: Key<'a>>(&self, _: K) -> bool { self.0 diff --git a/src/model/value.rs b/src/model/value.rs index 4075ce9c..e0d5edf3 100644 --- a/src/model/value.rs +++ b/src/model/value.rs @@ -4,13 +4,14 @@ use std::fmt::{self, Debug, Formatter}; use std::hash::{Hash, Hasher}; use std::sync::Arc; +use comemo::Tracked; use siphasher::sip128::{Hasher128, SipHasher}; use super::{ops, Args, Array, Cast, Content, Dict, Func, Layout, RawLength, Str}; use crate::diag::StrResult; use crate::geom::{Angle, Color, Em, Fraction, Length, Ratio, Relative, RgbaColor}; -use crate::library::text::RawNode; use crate::util::EcoString; +use crate::World; /// A computational value. #[derive(Clone)] @@ -113,7 +114,7 @@ impl Value { } /// Return the display representation of the value. - pub fn display(self) -> Content { + pub fn display(self, world: Tracked) -> Content { match self { Value::None => Content::new(), Value::Int(v) => Content::Text(format_eco!("{}", v)), @@ -123,8 +124,7 @@ impl Value { // For values which can't be shown "naturally", we return the raw // representation with typst code syntax highlighting. - v => Content::show(RawNode { text: v.repr().into(), block: false }) - .styled(RawNode::LANG, Some("typc".into())), + v => (world.config().roles.raw)(v.repr().into(), Some("typc".into()), false), } } } diff --git a/src/model/vm.rs b/src/model/vm.rs index a1b1ba81..829693bc 100644 --- a/src/model/vm.rs +++ b/src/model/vm.rs @@ -6,7 +6,7 @@ use super::{Route, Scopes, Value}; use crate::diag::{SourceError, StrResult}; use crate::syntax::{SourceId, Span}; use crate::util::PathExt; -use crate::World; +use crate::{RoleMap, World}; /// A virtual machine. pub struct Vm<'a> { @@ -54,6 +54,11 @@ impl<'a> Vm<'a> { return Err("cannot access file system from here".into()); } + + /// The role map. + pub fn roles(&self) -> &RoleMap { + &self.world.config().roles + } } /// A control flow event that occurred during evaluation. -- cgit v1.2.3