summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurenz <laurmaedje@gmail.com>2022-12-14 10:09:44 +0100
committerLaurenz <laurmaedje@gmail.com>2022-12-14 10:09:44 +0100
commit9ba4d2c134479aad876a0e2ac4cd1622a353109e (patch)
treea94e0e6ae53a1ba440e869fca26cc2ea0b179057 /src
parent4c73456fc1f5df8ebb3a89d9db657c3c54624d66 (diff)
New macro setup
Diffstat (limited to 'src')
-rw-r--r--src/doc.rs5
-rw-r--r--src/model/content.rs6
-rw-r--r--src/model/eval.rs2
-rw-r--r--src/model/func.rs37
-rw-r--r--src/model/mod.rs2
-rw-r--r--src/model/scope.rs21
-rw-r--r--src/model/value.rs4
7 files changed, 48 insertions, 29 deletions
diff --git a/src/doc.rs b/src/doc.rs
index d412a371..90cca969 100644
--- a/src/doc.rs
+++ b/src/doc.rs
@@ -10,7 +10,9 @@ use crate::geom::{
Abs, Align, Axes, Dir, Em, Numeric, Paint, Point, Shape, Size, Transform,
};
use crate::image::Image;
-use crate::model::{dict, node, Content, Dict, Fold, StableId, StyleChain, Value};
+use crate::model::{
+ capable, dict, node, Content, Dict, Fold, StableId, StyleChain, Value,
+};
use crate::util::EcoString;
/// A finished document with metadata and page frames.
@@ -539,6 +541,7 @@ impl FromStr for Region {
}
/// Meta information that isn't visible or renderable.
+#[capable]
#[derive(Debug, Clone, Hash)]
pub enum Meta {
/// An internal or external link.
diff --git a/src/model/content.rs b/src/model/content.rs
index f261f9b1..e73fa4a8 100644
--- a/src/model/content.rs
+++ b/src/model/content.rs
@@ -10,7 +10,9 @@ use siphasher::sip128::{Hasher128, SipHasher};
use thin_vec::ThinVec;
use typst_macros::node;
-use super::{capability, Args, Guard, Key, Property, Recipe, Style, StyleMap, Value, Vm};
+use super::{
+ capability, capable, Args, Guard, Key, Property, Recipe, Style, StyleMap, Value, Vm,
+};
use crate::diag::{SourceResult, StrResult};
use crate::syntax::Span;
use crate::util::{EcoString, ReadableTypeId};
@@ -342,6 +344,7 @@ impl Hash for dyn Bounds {
}
/// A node with applied styles.
+#[capable]
#[derive(Clone, Hash)]
pub struct StyledNode {
/// The styled content.
@@ -364,6 +367,7 @@ impl Debug for StyledNode {
///
/// Combines other arbitrary content. So, when you write `[Hi] + [you]` in
/// Typst, the two text nodes are combined into a single sequence node.
+#[capable]
#[derive(Clone, Hash)]
pub struct SequenceNode(pub Vec<Content>);
diff --git a/src/model/eval.rs b/src/model/eval.rs
index ef9ba0a8..d54acf0a 100644
--- a/src/model/eval.rs
+++ b/src/model/eval.rs
@@ -1147,7 +1147,7 @@ impl Eval for ast::ModuleImport {
match self.imports() {
ast::Imports::Wildcard => {
for (var, value) in module.scope.iter() {
- vm.scopes.top.define(var, value.clone());
+ vm.scopes.top.define(var.clone(), value.clone());
}
}
ast::Imports::Items(idents) => {
diff --git a/src/model/func.rs b/src/model/func.rs
index 60f36bd4..0261b5e2 100644
--- a/src/model/func.rs
+++ b/src/model/func.rs
@@ -30,16 +30,22 @@ enum Repr {
}
impl Func {
+ /// Create a new function from a type that can be turned into a function.
+ pub fn from_type<T: FuncType>(name: &'static str) -> Self {
+ T::create_func(name)
+ }
+
/// Create a new function from a native rust function.
pub fn from_fn(
name: &'static str,
func: fn(&Vm, &mut Args) -> SourceResult<Value>,
+ doc: &'static str,
) -> Self {
- Self(Arc::new(Repr::Native(Native { name, func, set: None, node: None })))
+ Self(Arc::new(Repr::Native(Native { name, func, set: None, node: None, doc })))
}
/// Create a new function from a native rust node.
- pub fn from_node<T: Node>(name: &'static str) -> Self {
+ pub fn from_node<T: Node>(name: &'static str, doc: &'static str) -> Self {
Self(Arc::new(Repr::Native(Native {
name,
func: |ctx, args| {
@@ -49,6 +55,7 @@ impl Func {
},
set: Some(|args| T::set(args, false)),
node: Some(NodeId::of::<T>()),
+ doc,
})))
}
@@ -66,6 +73,15 @@ impl Func {
}
}
+ /// Documentation for the function.
+ pub fn doc(&self) -> Option<&str> {
+ match self.0.as_ref() {
+ Repr::Native(native) => Some(native.doc),
+ Repr::With(func, _) => func.doc(),
+ _ => None,
+ }
+ }
+
/// The number of positional arguments this function takes, if known.
pub fn argc(&self) -> Option<usize> {
match self.0.as_ref() {
@@ -159,16 +175,24 @@ impl PartialEq for Func {
}
}
+/// Types that can be turned into functions.
+pub trait FuncType {
+ /// Create a function with the given name from this type.
+ fn create_func(name: &'static str) -> Func;
+}
+
/// A function defined by a native rust function or node.
struct Native {
/// The name of the function.
- pub name: &'static str,
+ name: &'static str,
/// The function pointer.
- pub func: fn(&Vm, &mut Args) -> SourceResult<Value>,
+ func: fn(&Vm, &mut Args) -> SourceResult<Value>,
/// The set rule.
- pub set: Option<fn(&mut Args) -> SourceResult<StyleMap>>,
+ set: Option<fn(&mut Args) -> SourceResult<StyleMap>>,
/// The id of the node to customize with this function's show rule.
- pub node: Option<NodeId>,
+ node: Option<NodeId>,
+ /// Documentation of the function.
+ doc: &'static str,
}
impl Hash for Native {
@@ -177,6 +201,7 @@ impl Hash for Native {
(self.func as usize).hash(state);
self.set.map(|set| set as usize).hash(state);
self.node.hash(state);
+ self.doc.hash(state);
}
}
diff --git a/src/model/mod.rs b/src/model/mod.rs
index fa047746..015df9b3 100644
--- a/src/model/mod.rs
+++ b/src/model/mod.rs
@@ -26,7 +26,7 @@ mod typeset;
#[doc(hidden)]
pub use once_cell;
-pub use typst_macros::{capability, node};
+pub use typst_macros::{capability, capable, func, node};
pub use self::args::*;
pub use self::array::*;
diff --git a/src/model/scope.rs b/src/model/scope.rs
index d21d0587..c54cf1b3 100644
--- a/src/model/scope.rs
+++ b/src/model/scope.rs
@@ -2,8 +2,8 @@ use std::collections::BTreeMap;
use std::fmt::{self, Debug, Formatter};
use std::hash::Hash;
-use super::{Args, Func, Node, Value, Vm};
-use crate::diag::{SourceResult, StrResult};
+use super::{Func, FuncType, Value};
+use crate::diag::StrResult;
use crate::util::EcoString;
/// A stack of scopes.
@@ -75,17 +75,8 @@ impl Scope {
}
/// Define a function through a native rust function.
- pub fn def_fn(
- &mut self,
- name: &'static str,
- func: fn(&Vm, &mut Args) -> SourceResult<Value>,
- ) {
- self.define(name, Func::from_fn(name, func));
- }
-
- /// Define a function through a native rust node.
- pub fn def_node<T: Node>(&mut self, name: &'static str) {
- self.define(name, Func::from_node::<T>(name));
+ pub fn def_func<T: FuncType>(&mut self, name: &'static str) {
+ self.define(name, Func::from_type::<T>(name));
}
/// Define a captured, immutable binding.
@@ -108,8 +99,8 @@ impl Scope {
}
/// Iterate over all definitions.
- pub fn iter(&self) -> impl Iterator<Item = (&str, &Value)> {
- self.0.iter().map(|(k, v)| (k.as_str(), v.read()))
+ pub fn iter(&self) -> impl Iterator<Item = (&EcoString, &Value)> {
+ self.0.iter().map(|(k, v)| (k, v.read()))
}
}
diff --git a/src/model/value.rs b/src/model/value.rs
index 59dac720..98d11e15 100644
--- a/src/model/value.rs
+++ b/src/model/value.rs
@@ -424,9 +424,5 @@ mod tests {
test(dict![], "(:)");
test(dict!["one" => 1], "(one: 1)");
test(dict!["two" => false, "one" => 1], "(one: 1, two: false)");
-
- // Functions, content and dynamics.
- test(Func::from_fn("nil", |_, _| Ok(Value::None)), "<function nil>");
- test(Dynamic::new(1), "1");
}
}