diff options
| author | Laurenz <laurmaedje@gmail.com> | 2023-03-13 21:40:57 +0100 |
|---|---|---|
| committer | Laurenz <laurmaedje@gmail.com> | 2023-03-13 21:41:33 +0100 |
| commit | 724e9b140cc0a87208aa9c4914b1b8aeddf25c30 (patch) | |
| tree | 632984e85eb21c5a5a04c397a74725df6f7f8a28 /src/model/realize.rs | |
| parent | 880b1847bd4170ce80be5781c2163ba085cdcaff (diff) | |
Locatability and synthesis improvements
Diffstat (limited to 'src/model/realize.rs')
| -rw-r--r-- | src/model/realize.rs | 42 |
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. |
