summaryrefslogtreecommitdiff
path: root/library/src
diff options
context:
space:
mode:
Diffstat (limited to 'library/src')
-rw-r--r--library/src/basics/list.rs2
-rw-r--r--library/src/layout/mod.rs34
-rw-r--r--library/src/layout/page.rs4
-rw-r--r--library/src/layout/par.rs16
-rw-r--r--library/src/meta/document.rs6
-rw-r--r--library/src/meta/link.rs6
-rw-r--r--library/src/prelude.rs5
-rw-r--r--library/src/shared/ext.rs7
-rw-r--r--library/src/text/raw.rs13
-rw-r--r--library/src/text/shaping.rs8
-rw-r--r--library/src/visualize/image.rs7
-rw-r--r--library/src/visualize/shape.rs7
12 files changed, 79 insertions, 36 deletions
diff --git a/library/src/basics/list.rs b/library/src/basics/list.rs
index e35fe9fa..f5a58977 100644
--- a/library/src/basics/list.rs
+++ b/library/src/basics/list.rs
@@ -216,7 +216,7 @@ pub const ENUM: ListKind = 1;
pub const DESC: ListKind = 2;
/// How to label a list or enumeration.
-#[derive(Debug, Clone, PartialEq, Hash)]
+#[derive(Debug, Clone, Hash)]
pub enum Label {
/// The default labelling.
Default,
diff --git a/library/src/layout/mod.rs b/library/src/layout/mod.rs
index e3691732..047d78f9 100644
--- a/library/src/layout/mod.rs
+++ b/library/src/layout/mod.rs
@@ -59,9 +59,11 @@ impl LayoutRoot for Content {
fn cached(
node: &Content,
world: comemo::Tracked<dyn World>,
+ provider: TrackedMut<StabilityProvider>,
+ introspector: Tracked<Introspector>,
styles: StyleChain,
) -> SourceResult<Document> {
- let mut vt = Vt { world };
+ let mut vt = Vt { world, provider, introspector };
let scratch = Scratch::default();
let (realized, styles) = realize_root(&mut vt, &scratch, node, styles)?;
realized
@@ -70,7 +72,13 @@ impl LayoutRoot for Content {
.layout_root(&mut vt, styles)
}
- cached(self, vt.world, styles)
+ cached(
+ self,
+ vt.world,
+ TrackedMut::reborrow_mut(&mut vt.provider),
+ vt.introspector,
+ styles,
+ )
}
}
@@ -97,10 +105,12 @@ impl Layout for Content {
fn cached(
node: &Content,
world: comemo::Tracked<dyn World>,
+ provider: TrackedMut<StabilityProvider>,
+ introspector: Tracked<Introspector>,
styles: StyleChain,
regions: &Regions,
) -> SourceResult<Fragment> {
- let mut vt = Vt { world };
+ let mut vt = Vt { world, provider, introspector };
let scratch = Scratch::default();
let (realized, styles) = realize_block(&mut vt, &scratch, node, styles)?;
let barrier = Style::Barrier(realized.id());
@@ -111,7 +121,14 @@ impl Layout for Content {
.layout(&mut vt, styles, regions)
}
- cached(self, vt.world, styles, regions)
+ cached(
+ self,
+ vt.world,
+ TrackedMut::reborrow_mut(&mut vt.provider),
+ vt.introspector,
+ styles,
+ regions,
+ )
}
}
@@ -290,6 +307,15 @@ impl<'a, 'v, 't> Builder<'a, 'v, 't> {
content: &'a Content,
styles: StyleChain<'a>,
) -> SourceResult<()> {
+ // Prepare only if this is the first application for this node.
+ if let Some(node) = content.with::<dyn Prepare>() {
+ if !content.is_prepared() {
+ let prepared = node.prepare(self.vt, content.clone().prepared(), styles);
+ let stored = self.scratch.content.alloc(prepared);
+ return self.accept(stored, styles);
+ }
+ }
+
if let Some(styled) = content.to::<StyledNode>() {
return self.styled(styled, styles);
}
diff --git a/library/src/layout/page.rs b/library/src/layout/page.rs
index 08411ad1..dee77abd 100644
--- a/library/src/layout/page.rs
+++ b/library/src/layout/page.rs
@@ -5,7 +5,7 @@ use crate::prelude::*;
use crate::text::TextNode;
/// Layouts its child onto one or multiple pages.
-#[derive(PartialEq, Clone, Hash)]
+#[derive(Clone, Hash)]
pub struct PageNode(pub Content);
#[node]
@@ -157,7 +157,7 @@ impl PagebreakNode {
}
/// A header, footer, foreground or background definition.
-#[derive(Debug, Clone, PartialEq, Hash)]
+#[derive(Debug, Clone, Hash)]
pub enum Marginal {
/// Nothing,
None,
diff --git a/library/src/layout/par.rs b/library/src/layout/par.rs
index e96845dd..78e9b2a3 100644
--- a/library/src/layout/par.rs
+++ b/library/src/layout/par.rs
@@ -57,13 +57,15 @@ impl ParNode {
fn cached(
par: &ParNode,
world: Tracked<dyn World>,
+ provider: TrackedMut<StabilityProvider>,
+ introspector: Tracked<Introspector>,
styles: StyleChain,
consecutive: bool,
width: Abs,
base: Size,
expand: bool,
) -> SourceResult<Fragment> {
- let mut vt = Vt { world };
+ let mut vt = Vt { world, provider, introspector };
// Collect all text into one string for BiDi analysis.
let (text, segments) = collect(par, &styles, consecutive);
@@ -80,7 +82,17 @@ impl ParNode {
finalize(&mut vt, &p, &lines, width, base, expand)
}
- cached(self, vt.world, styles, consecutive, width, base, expand)
+ cached(
+ self,
+ vt.world,
+ TrackedMut::reborrow_mut(&mut vt.provider),
+ vt.introspector,
+ styles,
+ consecutive,
+ width,
+ base,
+ expand,
+ )
}
}
diff --git a/library/src/meta/document.rs b/library/src/meta/document.rs
index 77181671..fbb62b6b 100644
--- a/library/src/meta/document.rs
+++ b/library/src/meta/document.rs
@@ -27,11 +27,9 @@ impl LayoutRoot for DocumentNode {
}
Ok(Document {
- metadata: Metadata {
- title: styles.get(Self::TITLE).clone(),
- author: styles.get(Self::AUTHOR).clone(),
- },
pages,
+ title: styles.get(Self::TITLE).clone(),
+ author: styles.get(Self::AUTHOR).clone(),
})
}
}
diff --git a/library/src/meta/link.rs b/library/src/meta/link.rs
index e7d217e7..52163371 100644
--- a/library/src/meta/link.rs
+++ b/library/src/meta/link.rs
@@ -25,10 +25,6 @@ impl LinkNode {
#[node(Show, Finalize)]
impl LinkNode {
- /// A destination the text should be linked to.
- #[property(skip, referenced)]
- pub(crate) const DEST: Option<Destination> = None;
-
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
let dest = args.expect::<Destination>("destination")?;
Ok(match dest {
@@ -61,6 +57,6 @@ impl Show for LinkNode {
impl Finalize for LinkNode {
fn finalize(&self, realized: Content) -> Content {
- realized.styled(Self::DEST, Some(self.dest.clone()))
+ realized.styled(Meta::DATA, vec![Meta::Link(self.dest.clone())])
}
}
diff --git a/library/src/prelude.rs b/library/src/prelude.rs
index e7d824cc..26a3c6c3 100644
--- a/library/src/prelude.rs
+++ b/library/src/prelude.rs
@@ -16,8 +16,9 @@ pub use typst::geom::*;
#[doc(no_inline)]
pub use typst::model::{
array, capability, castable, dict, dynamic, format_str, node, Args, Array, Cast,
- Content, Dict, Finalize, Fold, Func, Label, Node, NodeId, Resolve, Selector, Show,
- Smart, Str, StyleChain, StyleMap, StyleVec, Unlabellable, Value, Vm, Vt,
+ Content, Dict, Finalize, Fold, Func, Introspector, Label, Node, NodeId, Prepare,
+ Resolve, Selector, Show, Smart, StabilityProvider, Str, StyleChain, StyleMap,
+ StyleVec, Unlabellable, Value, Vm, Vt,
};
#[doc(no_inline)]
pub use typst::syntax::{Span, Spanned};
diff --git a/library/src/shared/ext.rs b/library/src/shared/ext.rs
index 2d2dc751..4fd1f161 100644
--- a/library/src/shared/ext.rs
+++ b/library/src/shared/ext.rs
@@ -13,6 +13,9 @@ pub trait ContentExt {
/// Underline this content.
fn underlined(self) -> Self;
+ /// Link the content to a destination.
+ fn linked(self, dest: Destination) -> Self;
+
/// Force a size for this content.
fn boxed(self, sizing: Axes<Option<Rel<Length>>>) -> Self;
@@ -45,6 +48,10 @@ impl ContentExt for Content {
crate::text::DecoNode::<{ crate::text::UNDERLINE }>(self).pack()
}
+ fn linked(self, dest: Destination) -> Self {
+ self.styled(Meta::DATA, vec![Meta::Link(dest.clone())])
+ }
+
fn boxed(self, sizing: Axes<Option<Rel<Length>>>) -> Self {
crate::layout::BoxNode { sizing, child: self }.pack()
}
diff --git a/library/src/text/raw.rs b/library/src/text/raw.rs
index c0bf105f..9c04fedf 100644
--- a/library/src/text/raw.rs
+++ b/library/src/text/raw.rs
@@ -42,6 +42,19 @@ impl RawNode {
}
}
+impl Prepare for RawNode {
+ fn prepare(&self, _: &mut Vt, mut this: Content, styles: StyleChain) -> Content {
+ this.push_field(
+ "lang",
+ match styles.get(Self::LANG) {
+ Some(lang) => Value::Str(lang.clone().into()),
+ None => Value::None,
+ },
+ );
+ this
+ }
+}
+
impl Show for RawNode {
fn show(&self, _: &mut Vt, _: &Content, styles: StyleChain) -> Content {
let lang = styles.get(Self::LANG).as_ref().map(|s| s.to_lowercase());
diff --git a/library/src/text/shaping.rs b/library/src/text/shaping.rs
index 6dbbb535..6d4e41dc 100644
--- a/library/src/text/shaping.rs
+++ b/library/src/text/shaping.rs
@@ -6,7 +6,6 @@ use typst::font::{Font, FontVariant};
use typst::util::SliceExt;
use super::*;
-use crate::meta::LinkNode;
use crate::prelude::*;
/// The result of shaping text.
@@ -93,7 +92,6 @@ impl<'a> ShapedText<'a> {
let lang = self.styles.get(TextNode::LANG);
let decos = self.styles.get(TextNode::DECO);
let fill = self.styles.get(TextNode::FILL);
- let link = self.styles.get(LinkNode::DEST);
for ((font, y_offset), group) in
self.glyphs.as_ref().group_by_key(|g| (g.font.clone(), g.y_offset))
@@ -128,10 +126,8 @@ impl<'a> ShapedText<'a> {
offset += width;
}
- // Apply link if it exists.
- if let Some(dest) = link {
- frame.link(dest.clone());
- }
+ // Apply metadata.
+ frame.meta(self.styles);
frame
}
diff --git a/library/src/visualize/image.rs b/library/src/visualize/image.rs
index 077fe76d..48764c37 100644
--- a/library/src/visualize/image.rs
+++ b/library/src/visualize/image.rs
@@ -2,7 +2,6 @@ use std::ffi::OsStr;
use typst::image::{Image, ImageFormat, RasterFormat, VectorFormat};
-use crate::meta::LinkNode;
use crate::prelude::*;
/// Show a raster or vector graphic.
@@ -89,10 +88,8 @@ impl Layout for ImageNode {
frame.clip();
}
- // Apply link if it exists.
- if let Some(url) = styles.get(LinkNode::DEST) {
- frame.link(url.clone());
- }
+ // Apply metadata.
+ frame.meta(styles);
Ok(Fragment::frame(frame))
}
diff --git a/library/src/visualize/shape.rs b/library/src/visualize/shape.rs
index f2d15cab..acb5a9e9 100644
--- a/library/src/visualize/shape.rs
+++ b/library/src/visualize/shape.rs
@@ -1,6 +1,5 @@
use std::f64::consts::SQRT_2;
-use crate::meta::LinkNode;
use crate::prelude::*;
/// A sizable and fillable shape with optional content.
@@ -160,10 +159,8 @@ impl<const S: ShapeKind> Layout for ShapeNode<S> {
}
}
- // Apply link if it exists.
- if let Some(url) = styles.get(LinkNode::DEST) {
- frame.link(url.clone());
- }
+ // Apply metadata.
+ frame.meta(styles);
Ok(Fragment::frame(frame))
}