summaryrefslogtreecommitdiff
path: root/src/model/realize.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2023-03-13 21:40:57 +0100
committerLaurenz <laurmaedje@gmail.com>2023-03-13 21:41:33 +0100
commit724e9b140cc0a87208aa9c4914b1b8aeddf25c30 (patch)
tree632984e85eb21c5a5a04c397a74725df6f7f8a28 /src/model/realize.rs
parent880b1847bd4170ce80be5781c2163ba085cdcaff (diff)
Locatability and synthesis improvements
Diffstat (limited to 'src/model/realize.rs')
-rw-r--r--src/model/realize.rs42
1 files changed, 28 insertions, 14 deletions
diff --git a/src/model/realize.rs b/src/model/realize.rs
index 4685a605..3ead8f7d 100644
--- a/src/model/realize.rs
+++ b/src/model/realize.rs
@@ -1,9 +1,10 @@
use super::{Content, NodeId, Recipe, Selector, StyleChain, Vt};
use crate::diag::SourceResult;
+use crate::doc::{Meta, MetaNode};
/// Whether the target is affected by show rules in the given style chain.
pub fn applicable(target: &Content, styles: StyleChain) -> bool {
- if target.can::<dyn Synthesize>() && !target.is_synthesized() {
+ if target.needs_preparation() {
return true;
}
@@ -31,21 +32,31 @@ pub fn realize(
target: &Content,
styles: StyleChain,
) -> SourceResult<Option<Content>> {
- // Find out how many recipes there are.
- let mut n = styles.recipes().count();
+ // Pre-process.
+ if target.needs_preparation() {
+ let mut node = target.clone();
+ if target.can::<dyn Locatable>() || target.label().is_some() {
+ let id = vt.identify(target);
+ node.set_stable_id(id);
+ }
+
+ if let Some(node) = node.with_mut::<dyn Synthesize>() {
+ node.synthesize(vt, styles);
+ }
+
+ node.mark_prepared();
- // Synthesize if not already happened for this node.
- if target.can::<dyn Synthesize>() && !target.is_synthesized() {
- return Ok(Some(
- target
- .clone()
- .synthesized()
- .with::<dyn Synthesize>()
- .unwrap()
- .synthesize(vt, styles),
- ));
+ if let Some(id) = node.stable_id() {
+ let meta = Meta::Node(id, node.clone());
+ return Ok(Some(node.styled(MetaNode::set_data(vec![meta]))));
+ }
+
+ return Ok(Some(node));
}
+ // Find out how many recipes there are.
+ let mut n = styles.recipes().count();
+
// Find an applicable recipe.
let mut realized = None;
for recipe in styles.recipes() {
@@ -144,10 +155,13 @@ fn try_apply(
}
}
+/// Makes this node locatable through `vt.locate`.
+pub trait Locatable {}
+
/// Synthesize fields on a node. This happens before execution of any show rule.
pub trait Synthesize {
/// Prepare the node for show rule application.
- fn synthesize(&self, vt: &mut Vt, styles: StyleChain) -> Content;
+ fn synthesize(&mut self, vt: &Vt, styles: StyleChain);
}
/// The base recipe for a node.