summaryrefslogtreecommitdiff
path: root/src/model
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-11-26 23:42:40 +0100
committerLaurenz <laurmaedje@gmail.com>2022-11-26 23:52:01 +0100
commit6bafc6391061d4b589dea835705a08b25a4df9f8 (patch)
tree4add85f17fc56da341acfb58a223ea20d80c280a /src/model
parent0579fd4409375aaa9fd8e87a06fd59097b5fcd97 (diff)
Document metadata
Diffstat (limited to 'src/model')
-rw-r--r--src/model/cast.rs2
-rw-r--r--src/model/eval.rs6
-rw-r--r--src/model/library.rs4
-rw-r--r--src/model/styles.rs41
-rw-r--r--src/model/typeset.rs10
5 files changed, 34 insertions, 29 deletions
diff --git a/src/model/cast.rs b/src/model/cast.rs
index d0a4650a..a4a3fe4e 100644
--- a/src/model/cast.rs
+++ b/src/model/cast.rs
@@ -3,8 +3,8 @@ use std::str::FromStr;
use super::{Content, Regex, Selector, Transform, Value};
use crate::diag::{with_alternative, StrResult};
+use crate::doc::{Destination, Lang, Location, Region};
use crate::font::{FontStretch, FontStyle, FontWeight};
-use crate::frame::{Destination, Lang, Location, Region};
use crate::geom::{
Axes, Corners, Dir, GenAlign, Get, Length, Paint, PartialStroke, Point, Rel, Sides,
};
diff --git a/src/model/eval.rs b/src/model/eval.rs
index da7036b7..166dadde 100644
--- a/src/model/eval.rs
+++ b/src/model/eval.rs
@@ -21,10 +21,6 @@ use crate::util::{format_eco, EcoString, PathExt};
use crate::World;
/// Evaluate a source file and return the resulting module.
-///
-/// Returns either a module containing a scope with top-level bindings and
-/// layoutable contents or diagnostics in the form of a vector of error
-/// messages with file and span information.
#[comemo::memoize]
pub fn eval(
world: Tracked<dyn World>,
@@ -934,7 +930,7 @@ impl Eval for ast::SetRule {
let target = self.target();
let target = target.eval(vm)?.cast::<Func>().at(target.span())?;
let args = self.args().eval(vm)?;
- target.set(args)
+ Ok(target.set(args)?.spanned(self.span()))
}
}
diff --git a/src/model/library.rs b/src/model/library.rs
index 2ee09b27..518caca1 100644
--- a/src/model/library.rs
+++ b/src/model/library.rs
@@ -7,7 +7,7 @@ use once_cell::sync::OnceCell;
use super::{Content, NodeId, Scope, StyleChain, StyleMap};
use crate::diag::SourceResult;
-use crate::frame::Frame;
+use crate::doc::Document;
use crate::geom::{Abs, Dir};
use crate::util::{hash128, EcoString};
use crate::World;
@@ -31,7 +31,7 @@ pub struct LangItems {
world: Tracked<dyn World>,
content: &Content,
styles: StyleChain,
- ) -> SourceResult<Vec<Frame>>,
+ ) -> SourceResult<Document>,
/// Access the em size.
pub em: fn(StyleChain) -> Abs,
/// Access the text direction.
diff --git a/src/model/styles.rs b/src/model/styles.rs
index f3cfb648..80ec0d1e 100644
--- a/src/model/styles.rs
+++ b/src/model/styles.rs
@@ -79,9 +79,25 @@ impl StyleMap {
self
}
- /// Whether this map contains styles for the given `node.`
- pub fn interrupts<T: 'static>(&self) -> bool {
- self.0.iter().any(|entry| entry.is_of(NodeId::of::<T>()))
+ /// Add an origin span to all contained properties.
+ pub fn spanned(mut self, span: Span) -> Self {
+ for entry in &mut self.0 {
+ if let Style::Property(property) = entry {
+ property.origin = Some(span);
+ }
+ }
+ self
+ }
+
+ /// Returns `Some(_)` with an optional span if this map contains styles for
+ /// the given `node`.
+ pub fn interruption<T: 'static>(&self) -> Option<Option<Span>> {
+ let node = NodeId::of::<T>();
+ self.0.iter().find_map(|entry| match entry {
+ Style::Property(property) => property.is_of(node).then(|| property.origin),
+ Style::Recipe(recipe) => recipe.is_of(node).then(|| Some(recipe.span)),
+ _ => None,
+ })
}
}
@@ -127,15 +143,6 @@ impl Style {
_ => None,
}
}
-
- /// Whether this entry contains styles for the given `node.`
- pub fn is_of(&self, node: NodeId) -> bool {
- match self {
- Self::Property(property) => property.is_of(node),
- Self::Recipe(recipe) => recipe.is_of(node),
- _ => false,
- }
- }
}
impl Debug for Style {
@@ -162,6 +169,8 @@ pub struct Property {
scoped: bool,
/// The property's value.
value: Arc<Prehashed<dyn Bounds>>,
+ /// The span of the set rule the property stems from.
+ origin: Option<Span>,
/// The name of the property.
#[cfg(debug_assertions)]
name: &'static str,
@@ -175,6 +184,7 @@ impl Property {
node: K::node(),
value: Arc::new(Prehashed::new(value)),
scoped: false,
+ origin: None,
#[cfg(debug_assertions)]
name: K::NAME,
}
@@ -330,8 +340,11 @@ impl Recipe {
let args = Args::new(self.span, [Value::Content(content.clone())]);
let mut result = func.call_detached(world, args);
if let Some(span) = content.span() {
- let point = || Tracepoint::Show(content.name().into());
- result = result.trace(world, point, span);
+ // For selector-less show rules, a tracepoint makes no sense.
+ if self.selector.is_some() {
+ let point = || Tracepoint::Show(content.name().into());
+ result = result.trace(world, point, span);
+ }
}
Ok(result?.display())
}
diff --git a/src/model/typeset.rs b/src/model/typeset.rs
index ad2af3b2..451c6eb0 100644
--- a/src/model/typeset.rs
+++ b/src/model/typeset.rs
@@ -2,16 +2,12 @@ use comemo::Tracked;
use super::{Content, StyleChain};
use crate::diag::SourceResult;
-use crate::frame::Frame;
+use crate::doc::Document;
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.
+/// Typeset content into a fully layouted document.
#[comemo::memoize]
-pub fn typeset(world: Tracked<dyn World>, content: &Content) -> SourceResult<Vec<Frame>> {
+pub fn typeset(world: Tracked<dyn World>, content: &Content) -> SourceResult<Document> {
let library = world.library();
let styles = StyleChain::new(&library.styles);
(library.items.layout)(world, content, styles)