summaryrefslogtreecommitdiff
path: root/src/model/content.rs
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2023-03-17 11:32:15 +0100
committerLaurenz <laurmaedje@gmail.com>2023-03-17 11:45:57 +0100
commit312197b276748e1a17258ad21837850f582a467c (patch)
tree3fd0c078a2673a98b74bc12b4d654a4c143b4e1f /src/model/content.rs
parente8435df5ec718e8ecc8a2ad48e4eb3ddd1f92a72 (diff)
Counters
Diffstat (limited to 'src/model/content.rs')
-rw-r--r--src/model/content.rs48
1 files changed, 42 insertions, 6 deletions
diff --git a/src/model/content.rs b/src/model/content.rs
index 58b80487..11ad635f 100644
--- a/src/model/content.rs
+++ b/src/model/content.rs
@@ -8,8 +8,12 @@ use comemo::Tracked;
use ecow::{eco_format, EcoString, EcoVec};
use once_cell::sync::Lazy;
-use super::{node, Guard, Locatable, Recipe, StableId, Style, StyleMap, Synthesize};
+use super::{
+ node, Behave, Behaviour, Fold, Guard, Locatable, Recipe, StableId, Style, StyleMap,
+ Synthesize,
+};
use crate::diag::{SourceResult, StrResult};
+use crate::doc::Meta;
use crate::eval::{
cast_from_value, cast_to_value, Args, Cast, Func, FuncInfo, Str, Value, Vm,
};
@@ -35,9 +39,15 @@ enum Modifier {
}
impl Content {
+ /// Create a content of the given node kind.
pub fn new<T: Node>() -> Self {
+ Self::new_of(T::id())
+ }
+
+ /// Create a content of the given node kind.
+ pub fn new_of(id: NodeId) -> Self {
Self {
- id: T::id(),
+ id,
span: Span::detached(),
fields: EcoVec::new(),
modifiers: EcoVec::new(),
@@ -133,11 +143,10 @@ impl Content {
.map(|(_, value)| value)
}
- /// Access a field on the content as a specified type.
- #[track_caller]
+ /// Try to access a field on the content as a specified type.
pub fn cast_field<T: Cast>(&self, name: &str) -> Option<T> {
match self.field(name) {
- Some(value) => Some(value.clone().cast().unwrap()),
+ Some(value) => value.clone().cast().ok(),
None => None,
}
}
@@ -145,7 +154,7 @@ impl Content {
/// Expect a field on the content to exist as a specified type.
#[track_caller]
pub fn expect_field<T: Cast>(&self, name: &str) -> T {
- self.cast_field(name).unwrap()
+ self.field(name).unwrap().clone().cast().unwrap()
}
/// List all fields on the content.
@@ -500,6 +509,33 @@ cast_from_value! {
StyleMap: "style map",
}
+/// Host for metadata.
+///
+/// Display: Meta
+/// Category: special
+#[node(Behave)]
+pub struct MetaNode {
+ /// Metadata that should be attached to all elements affected by this style
+ /// property.
+ #[fold]
+ pub data: Vec<Meta>,
+}
+
+impl Behave for MetaNode {
+ fn behaviour(&self) -> Behaviour {
+ Behaviour::Ignorant
+ }
+}
+
+impl Fold for Vec<Meta> {
+ type Output = Self;
+
+ fn fold(mut self, outer: Self::Output) -> Self::Output {
+ self.extend(outer);
+ self
+ }
+}
+
/// The missing key access error message.
#[cold]
#[track_caller]