summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2024-01-24 15:47:54 +0100
committerLaurenz <laurmaedje@gmail.com>2024-01-24 15:47:54 +0100
commita3684352ea3a09f5dd2587305f202d530d0b892f (patch)
tree24e775cadd13559705463dea6f6ea210f019ec63
parent1612913f8f195248059156a7ae1a08a31c7f5016 (diff)
Handle `Finalize` alongside `Synthesize`
-rw-r--r--crates/typst/src/foundations/content.rs13
-rw-r--r--crates/typst/src/realize/mod.rs49
2 files changed, 29 insertions, 33 deletions
diff --git a/crates/typst/src/foundations/content.rs b/crates/typst/src/foundations/content.rs
index f7667b2d..582fd9c5 100644
--- a/crates/typst/src/foundations/content.rs
+++ b/crates/typst/src/foundations/content.rs
@@ -14,8 +14,8 @@ use smallvec::smallvec;
use crate::diag::{SourceResult, StrResult};
use crate::engine::Engine;
use crate::foundations::{
- elem, func, scope, ty, Dict, Element, Fields, Guard, IntoValue, Label, NativeElement,
- Recipe, Repr, Selector, Str, Style, Styles, Synthesize, Value,
+ elem, func, scope, ty, Dict, Element, Fields, Finalize, Guard, IntoValue, Label,
+ NativeElement, Recipe, Repr, Selector, Str, Style, Styles, Synthesize, Value,
};
use crate::introspection::{Locatable, Location, Meta, MetaElem};
use crate::layout::{AlignElem, Alignment, Axes, Length, MoveElem, PadElem, Rel, Sides};
@@ -147,10 +147,11 @@ impl Content {
/// Whether the content needs to be realized specially.
pub fn needs_preparation(&self) -> bool {
- (self.can::<dyn Locatable>()
- || self.can::<dyn Synthesize>()
- || self.label().is_some())
- && !self.inner.prepared
+ !self.inner.prepared
+ && (self.can::<dyn Locatable>()
+ || self.can::<dyn Synthesize>()
+ || self.can::<dyn Finalize>()
+ || self.label().is_some())
}
/// Check whether a show rule recipe is disabled.
diff --git a/crates/typst/src/realize/mod.rs b/crates/typst/src/realize/mod.rs
index 000b5c83..ff191d80 100644
--- a/crates/typst/src/realize/mod.rs
+++ b/crates/typst/src/realize/mod.rs
@@ -107,58 +107,53 @@ pub fn realize(
elem.set_location(location);
}
- if let Some(elem) = elem.with_mut::<dyn Synthesize>() {
- elem.synthesize(engine, styles)?;
+ if let Some(synthesizable) = elem.with_mut::<dyn Synthesize>() {
+ synthesizable.synthesize(engine, styles)?;
}
elem.mark_prepared();
- if elem.location().is_some() {
- let span = elem.span();
- let meta = Meta::Elem(elem.clone());
+ let span = elem.span();
+ let meta = elem.location().is_some().then(|| Meta::Elem(elem.clone()));
+
+ let mut content = elem;
+ if let Some(finalizable) = target.with::<dyn Finalize>() {
+ content = finalizable.finalize(content, styles);
+ }
+
+ if let Some(meta) = meta {
return Ok(Some(
- (elem + MetaElem::new().pack().spanned(span))
+ (content + MetaElem::new().pack().spanned(span))
.styled(MetaElem::set_data(smallvec![meta])),
));
+ } else {
+ return Ok(Some(content));
}
-
- return Ok(Some(elem));
}
// Find out how many recipes there are.
let mut n = styles.recipes().count();
- // Find an applicable recipe.
- let mut realized = None;
+ // Find an applicable show rule recipe.
for recipe in styles.recipes() {
let guard = Guard::Nth(n);
if recipe.applicable(target) && !target.is_guarded(guard) {
if let Some(content) = try_apply(engine, target, recipe, guard)? {
- realized = Some(content);
- break;
+ return Ok(Some(content));
}
}
n -= 1;
}
- // Realize if there was no matching recipe.
- if let Some(showable) = target.with::<dyn Show>() {
- let guard = Guard::Base(target.func());
- if realized.is_none() && !target.is_guarded(guard) {
- realized = Some(showable.show(engine, styles)?);
- }
- }
-
- // Finalize only if this is the first application for this element.
- if let Some(elem) = target.with::<dyn Finalize>() {
- if target.is_pristine() {
- if let Some(already) = realized {
- realized = Some(elem.finalize(already, styles));
- }
+ // Apply the built-in show rule if there was no matching recipe.
+ let guard = Guard::Base(target.func());
+ if !target.is_guarded(guard) {
+ if let Some(showable) = target.with::<dyn Show>() {
+ return Ok(Some(showable.show(engine, styles)?));
}
}
- Ok(realized)
+ Ok(None)
}
/// Try to apply a recipe to the target.