summaryrefslogtreecommitdiff
path: root/library/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 /library/src
parent4c73456fc1f5df8ebb3a89d9db657c3c54624d66 (diff)
New macro setup
Diffstat (limited to 'library/src')
-rw-r--r--library/src/basics/heading.rs4
-rw-r--r--library/src/basics/list.rs5
-rw-r--r--library/src/basics/table.rs4
-rw-r--r--library/src/compute/calc.rs18
-rw-r--r--library/src/compute/create.rs27
-rw-r--r--library/src/compute/data.rs3
-rw-r--r--library/src/compute/foundations.rs10
-rw-r--r--library/src/compute/utility.rs6
-rw-r--r--library/src/layout/align.rs4
-rw-r--r--library/src/layout/columns.rs8
-rw-r--r--library/src/layout/container.rs8
-rw-r--r--library/src/layout/flow.rs9
-rw-r--r--library/src/layout/grid.rs4
-rw-r--r--library/src/layout/hide.rs4
-rw-r--r--library/src/layout/pad.rs4
-rw-r--r--library/src/layout/page.rs4
-rw-r--r--library/src/layout/par.rs6
-rw-r--r--library/src/layout/place.rs4
-rw-r--r--library/src/layout/repeat.rs4
-rw-r--r--library/src/layout/spacing.rs8
-rw-r--r--library/src/layout/stack.rs4
-rw-r--r--library/src/layout/transform.rs8
-rw-r--r--library/src/lib.rs185
-rw-r--r--library/src/math/matrix.rs8
-rw-r--r--library/src/math/mod.rs40
-rw-r--r--library/src/math/style.rs32
-rw-r--r--library/src/meta/document.rs4
-rw-r--r--library/src/meta/link.rs4
-rw-r--r--library/src/meta/outline.rs4
-rw-r--r--library/src/meta/reference.rs4
-rw-r--r--library/src/prelude.rs8
-rw-r--r--library/src/shared/ext.rs6
-rw-r--r--library/src/text/deco.rs4
-rw-r--r--library/src/text/misc.rs25
-rw-r--r--library/src/text/mod.rs2
-rw-r--r--library/src/text/quotes.rs2
-rw-r--r--library/src/text/raw.rs4
-rw-r--r--library/src/text/shift.rs4
-rw-r--r--library/src/text/symbol.rs4
-rw-r--r--library/src/visualize/image.rs4
-rw-r--r--library/src/visualize/line.rs4
-rw-r--r--library/src/visualize/shape.rs4
42 files changed, 326 insertions, 182 deletions
diff --git a/library/src/basics/heading.rs b/library/src/basics/heading.rs
index 0033f021..80f93e8d 100644
--- a/library/src/basics/heading.rs
+++ b/library/src/basics/heading.rs
@@ -6,6 +6,8 @@ use crate::prelude::*;
use crate::text::{SpaceNode, TextNode, TextSize};
/// A section heading.
+#[func]
+#[capable(Prepare, Show, Finalize)]
#[derive(Debug, Hash)]
pub struct HeadingNode {
/// The logical nesting depth of the section, starting from one. In the
@@ -15,7 +17,7 @@ pub struct HeadingNode {
pub body: Content,
}
-#[node(Prepare, Show, Finalize)]
+#[node]
impl HeadingNode {
/// How to number the heading.
#[property(referenced)]
diff --git a/library/src/basics/list.rs b/library/src/basics/list.rs
index bcd8ef1c..0fa8f125 100644
--- a/library/src/basics/list.rs
+++ b/library/src/basics/list.rs
@@ -4,6 +4,8 @@ use crate::prelude::*;
use crate::text::{SpaceNode, TextNode};
/// An unordered (bulleted) or ordered (numbered) list.
+#[func]
+#[capable(Layout)]
#[derive(Debug, Hash)]
pub struct ListNode<const L: ListKind = LIST> {
/// If true, the items are separated by leading instead of list spacing.
@@ -18,7 +20,7 @@ pub type EnumNode = ListNode<ENUM>;
/// A description list.
pub type DescNode = ListNode<DESC>;
-#[node(Layout)]
+#[node]
impl<const L: ListKind> ListNode<L> {
/// How the list is labelled.
#[property(referenced)]
@@ -143,6 +145,7 @@ impl<const L: ListKind> Layout for ListNode<L> {
}
/// An item in a list.
+#[capable]
#[derive(Debug, Clone, Hash)]
pub enum ListItem {
/// An item of an unordered list.
diff --git a/library/src/basics/table.rs b/library/src/basics/table.rs
index 448ad1bd..5a4e8e81 100644
--- a/library/src/basics/table.rs
+++ b/library/src/basics/table.rs
@@ -2,6 +2,8 @@ use crate::layout::{GridNode, TrackSizing, TrackSizings};
use crate::prelude::*;
/// A table of items.
+#[func]
+#[capable(Layout)]
#[derive(Debug, Hash)]
pub struct TableNode {
/// Defines sizing for content rows and columns.
@@ -12,7 +14,7 @@ pub struct TableNode {
pub cells: Vec<Content>,
}
-#[node(Layout)]
+#[node]
impl TableNode {
/// How to fill the cells.
#[property(referenced)]
diff --git a/library/src/compute/calc.rs b/library/src/compute/calc.rs
index 3541e08c..71e43e21 100644
--- a/library/src/compute/calc.rs
+++ b/library/src/compute/calc.rs
@@ -3,7 +3,8 @@ use std::cmp::Ordering;
use crate::prelude::*;
/// The absolute value of a numeric value.
-pub fn abs(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn abs(args: &mut Args) -> SourceResult<Value> {
let Spanned { v, span } = args.expect("numeric value")?;
Ok(match v {
Value::Int(v) => Value::Int(v.abs()),
@@ -19,12 +20,14 @@ pub fn abs(_: &Vm, args: &mut Args) -> SourceResult<Value> {
}
/// The minimum of a sequence of values.
-pub fn min(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn min(args: &mut Args) -> SourceResult<Value> {
minmax(args, Ordering::Less)
}
/// The maximum of a sequence of values.
-pub fn max(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn max(args: &mut Args) -> SourceResult<Value> {
minmax(args, Ordering::Greater)
}
@@ -50,17 +53,20 @@ fn minmax(args: &mut Args, goal: Ordering) -> SourceResult<Value> {
}
/// Whether an integer is even.
-pub fn even(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn even(args: &mut Args) -> SourceResult<Value> {
Ok(Value::Bool(args.expect::<i64>("integer")? % 2 == 0))
}
/// Whether an integer is odd.
-pub fn odd(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn odd(args: &mut Args) -> SourceResult<Value> {
Ok(Value::Bool(args.expect::<i64>("integer")? % 2 != 0))
}
/// The modulo of two numbers.
-pub fn mod_(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn mod_(args: &mut Args) -> SourceResult<Value> {
let Spanned { v: v1, span: span1 } = args.expect("integer or float")?;
let Spanned { v: v2, span: span2 } = args.expect("integer or float")?;
diff --git a/library/src/compute/create.rs b/library/src/compute/create.rs
index 4fd27499..acd2e31f 100644
--- a/library/src/compute/create.rs
+++ b/library/src/compute/create.rs
@@ -5,7 +5,8 @@ use typst::model::Regex;
use crate::prelude::*;
/// Convert a value to an integer.
-pub fn int(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn int(args: &mut Args) -> SourceResult<Value> {
let Spanned { v, span } = args.expect("value")?;
Ok(Value::Int(match v {
Value::Bool(v) => v as i64,
@@ -20,7 +21,8 @@ pub fn int(_: &Vm, args: &mut Args) -> SourceResult<Value> {
}
/// Convert a value to a float.
-pub fn float(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn float(args: &mut Args) -> SourceResult<Value> {
let Spanned { v, span } = args.expect("value")?;
Ok(Value::Float(match v {
Value::Int(v) => v as f64,
@@ -34,13 +36,15 @@ pub fn float(_: &Vm, args: &mut Args) -> SourceResult<Value> {
}
/// Create a grayscale color.
-pub fn luma(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn luma(args: &mut Args) -> SourceResult<Value> {
let Component(luma) = args.expect("gray component")?;
Ok(Value::Color(LumaColor::new(luma).into()))
}
/// Create an RGB(A) color.
-pub fn rgb(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn rgb(args: &mut Args) -> SourceResult<Value> {
Ok(Value::Color(if let Some(string) = args.find::<Spanned<EcoString>>()? {
match RgbaColor::from_str(&string.v) {
Ok(color) => color.into(),
@@ -56,7 +60,8 @@ pub fn rgb(_: &Vm, args: &mut Args) -> SourceResult<Value> {
}
/// Create a CMYK color.
-pub fn cmyk(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn cmyk(args: &mut Args) -> SourceResult<Value> {
let RatioComponent(c) = args.expect("cyan component")?;
let RatioComponent(m) = args.expect("magenta component")?;
let RatioComponent(y) = args.expect("yellow component")?;
@@ -95,7 +100,8 @@ castable! {
}
/// Convert a value to a string.
-pub fn str(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn str(args: &mut Args) -> SourceResult<Value> {
let Spanned { v, span } = args.expect("value")?;
Ok(Value::Str(match v {
Value::Int(v) => format_str!("{}", v),
@@ -107,18 +113,21 @@ pub fn str(_: &Vm, args: &mut Args) -> SourceResult<Value> {
}
/// Create a label from a string.
-pub fn label(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn label(args: &mut Args) -> SourceResult<Value> {
Ok(Value::Label(Label(args.expect("string")?)))
}
/// Create a regular expression from a string.
-pub fn regex(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn regex(args: &mut Args) -> SourceResult<Value> {
let Spanned { v, span } = args.expect::<Spanned<EcoString>>("regular expression")?;
Ok(Regex::new(&v).at(span)?.into())
}
/// Create an array consisting of a sequence of numbers.
-pub fn range(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn range(args: &mut Args) -> SourceResult<Value> {
let first = args.expect::<i64>("end")?;
let (start, end) = match args.eat::<i64>()? {
Some(second) => (first, second),
diff --git a/library/src/compute/data.rs b/library/src/compute/data.rs
index 4f6e3b67..57dce5c1 100644
--- a/library/src/compute/data.rs
+++ b/library/src/compute/data.rs
@@ -5,6 +5,7 @@ use typst::diag::{format_xml_like_error, FileError};
use crate::prelude::*;
/// Read structured data from a CSV file.
+#[func]
pub fn csv(vm: &Vm, args: &mut Args) -> SourceResult<Value> {
let Spanned { v: path, span } =
args.expect::<Spanned<EcoString>>("path to csv file")?;
@@ -45,6 +46,7 @@ fn format_csv_error(error: csv::Error) -> String {
}
/// Read structured data from a JSON file.
+#[func]
pub fn json(vm: &Vm, args: &mut Args) -> SourceResult<Value> {
let Spanned { v: path, span } =
args.expect::<Spanned<EcoString>>("path to json file")?;
@@ -85,6 +87,7 @@ fn format_json_error(error: serde_json::Error) -> String {
}
/// Read structured data from an XML file.
+#[func]
pub fn xml(vm: &Vm, args: &mut Args) -> SourceResult<Value> {
let Spanned { v: path, span } =
args.expect::<Spanned<EcoString>>("path to xml file")?;
diff --git a/library/src/compute/foundations.rs b/library/src/compute/foundations.rs
index 5134d4ac..abe797dc 100644
--- a/library/src/compute/foundations.rs
+++ b/library/src/compute/foundations.rs
@@ -5,17 +5,20 @@ use typst::model;
use typst::syntax::Source;
/// The name of a value's type.
-pub fn type_(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn type_(args: &mut Args) -> SourceResult<Value> {
Ok(args.expect::<Value>("value")?.type_name().into())
}
/// The string representation of a value.
-pub fn repr(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn repr(args: &mut Args) -> SourceResult<Value> {
Ok(args.expect::<Value>("value")?.repr().into())
}
/// Ensure that a condition is fulfilled.
-pub fn assert(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn assert(args: &mut Args) -> SourceResult<Value> {
let Spanned { v, span } = args.expect::<Spanned<bool>>("condition")?;
if !v {
bail!(span, "assertion failed");
@@ -24,6 +27,7 @@ pub fn assert(_: &Vm, args: &mut Args) -> SourceResult<Value> {
}
/// Evaluate a string as Typst markup.
+#[func]
pub fn eval(vm: &Vm, args: &mut Args) -> SourceResult<Value> {
let Spanned { v: text, span } = args.expect::<Spanned<String>>("source")?;
let source = Source::synthesized(text, span);
diff --git a/library/src/compute/utility.rs b/library/src/compute/utility.rs
index 196f8368..d48f794e 100644
--- a/library/src/compute/utility.rs
+++ b/library/src/compute/utility.rs
@@ -4,13 +4,15 @@ use crate::prelude::*;
use crate::text::Case;
/// Create a blind text string.
-pub fn lorem(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn lorem(args: &mut Args) -> SourceResult<Value> {
let words: usize = args.expect("number of words")?;
Ok(Value::Str(lipsum::lipsum(words).into()))
}
/// Apply a numbering pattern to a number.
-pub fn numbering(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn numbering(args: &mut Args) -> SourceResult<Value> {
let pattern = args.expect::<NumberingPattern>("pattern")?;
let numbers = args.all::<NonZeroUsize>()?;
Ok(Value::Str(pattern.apply(&numbers).into()))
diff --git a/library/src/layout/align.rs b/library/src/layout/align.rs
index 506ef684..4fae3c3c 100644
--- a/library/src/layout/align.rs
+++ b/library/src/layout/align.rs
@@ -1,6 +1,8 @@
use crate::prelude::*;
-/// Just an empty shell to scope styles.
+/// Align content horizontally and vertically.
+#[func]
+#[capable]
#[derive(Debug, Hash)]
pub enum AlignNode {}
diff --git a/library/src/layout/columns.rs b/library/src/layout/columns.rs
index 28576fdd..0e29bc00 100644
--- a/library/src/layout/columns.rs
+++ b/library/src/layout/columns.rs
@@ -2,6 +2,8 @@ use crate::prelude::*;
use crate::text::TextNode;
/// Separate a region into multiple equally sized columns.
+#[func]
+#[capable(Layout)]
#[derive(Debug, Hash)]
pub struct ColumnsNode {
/// How many columns there should be.
@@ -11,7 +13,7 @@ pub struct ColumnsNode {
pub body: Content,
}
-#[node(Layout)]
+#[node]
impl ColumnsNode {
/// The size of the gutter space between each column.
#[property(resolve)]
@@ -101,12 +103,14 @@ impl Layout for ColumnsNode {
}
/// A column break.
+#[func]
+#[capable(Behave)]
#[derive(Debug, Hash)]
pub struct ColbreakNode {
pub weak: bool,
}
-#[node(Behave)]
+#[node]
impl ColbreakNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
let weak = args.named("weak")?.unwrap_or(false);
diff --git a/library/src/layout/container.rs b/library/src/layout/container.rs
index 0b035273..85257715 100644
--- a/library/src/layout/container.rs
+++ b/library/src/layout/container.rs
@@ -2,6 +2,8 @@ use super::VNode;
use crate::prelude::*;
/// An inline-level container that sizes content.
+#[func]
+#[capable(Layout, Inline)]
#[derive(Debug, Hash)]
pub struct BoxNode {
/// How to size the content horizontally and vertically.
@@ -10,7 +12,7 @@ pub struct BoxNode {
pub body: Content,
}
-#[node(Layout, Inline)]
+#[node]
impl BoxNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
let width = args.named("width")?;
@@ -60,10 +62,12 @@ impl Layout for BoxNode {
impl Inline for BoxNode {}
/// A block-level container that places content into a separate flow.
+#[func]
+#[capable(Layout)]
#[derive(Debug, Hash)]
pub struct BlockNode(pub Content);
-#[node(Layout)]
+#[node]
impl BlockNode {
/// The spacing between the previous and this block.
#[property(skip)]
diff --git a/library/src/layout/flow.rs b/library/src/layout/flow.rs
index b78f3932..611e9ee1 100644
--- a/library/src/layout/flow.rs
+++ b/library/src/layout/flow.rs
@@ -7,15 +7,12 @@ use crate::prelude::*;
///
/// This node is reponsible for layouting both the top-level content flow and
/// the contents of boxes.
+#[capable(Layout)]
#[derive(Hash)]
pub struct FlowNode(pub StyleVec<Content>, pub bool);
-#[node(Layout)]
-impl FlowNode {
- fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
- Ok(BlockNode(args.expect("body")?).pack())
- }
-}
+#[node]
+impl FlowNode {}
impl Layout for FlowNode {
fn layout(
diff --git a/library/src/layout/grid.rs b/library/src/layout/grid.rs
index 9ae780f1..2a6bd4ff 100644
--- a/library/src/layout/grid.rs
+++ b/library/src/layout/grid.rs
@@ -3,6 +3,8 @@ use crate::prelude::*;
use super::Spacing;
/// Arrange content in a grid.
+#[func]
+#[capable(Layout)]
#[derive(Debug, Hash)]
pub struct GridNode {
/// Defines sizing for content rows and columns.
@@ -13,7 +15,7 @@ pub struct GridNode {
pub cells: Vec<Content>,
}
-#[node(Layout)]
+#[node]
impl GridNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
let TrackSizings(columns) = args.named("columns")?.unwrap_or_default();
diff --git a/library/src/layout/hide.rs b/library/src/layout/hide.rs
index f6ce21d5..1318b7ed 100644
--- a/library/src/layout/hide.rs
+++ b/library/src/layout/hide.rs
@@ -1,10 +1,12 @@
use crate::prelude::*;
/// Hide content without affecting layout.
+#[func]
+#[capable(Layout, Inline)]
#[derive(Debug, Hash)]
pub struct HideNode(pub Content);
-#[node(Layout, Inline)]
+#[node]
impl HideNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.expect("body")?).pack())
diff --git a/library/src/layout/pad.rs b/library/src/layout/pad.rs
index 7ae738ac..9c44919d 100644
--- a/library/src/layout/pad.rs
+++ b/library/src/layout/pad.rs
@@ -1,6 +1,8 @@
use crate::prelude::*;
/// Pad content at the sides.
+#[func]
+#[capable(Layout)]
#[derive(Debug, Hash)]
pub struct PadNode {
/// The amount of padding.
@@ -9,7 +11,7 @@ pub struct PadNode {
pub body: Content,
}
-#[node(Layout)]
+#[node]
impl PadNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
let all = args.named("rest")?.or(args.find()?);
diff --git a/library/src/layout/page.rs b/library/src/layout/page.rs
index 8ea1eed6..5a23b27b 100644
--- a/library/src/layout/page.rs
+++ b/library/src/layout/page.rs
@@ -5,6 +5,8 @@ use crate::prelude::*;
use crate::text::TextNode;
/// Layouts its child onto one or multiple pages.
+#[func]
+#[capable]
#[derive(Clone, Hash)]
pub struct PageNode(pub Content);
@@ -143,6 +145,8 @@ impl Debug for PageNode {
}
/// A page break.
+#[func]
+#[capable]
#[derive(Debug, Copy, Clone, Hash)]
pub struct PagebreakNode {
pub weak: bool,
diff --git a/library/src/layout/par.rs b/library/src/layout/par.rs
index d93bfba7..925eea54 100644
--- a/library/src/layout/par.rs
+++ b/library/src/layout/par.rs
@@ -12,6 +12,8 @@ use crate::text::{
};
/// Arrange text, spacing and inline-level nodes into a paragraph.
+#[func]
+#[capable]
#[derive(Hash)]
pub struct ParNode(pub StyleVec<Content>);
@@ -142,10 +144,12 @@ castable! {
}
/// A paragraph break.
+#[func]
+#[capable(Unlabellable)]
#[derive(Debug, Hash)]
pub struct ParbreakNode;
-#[node(Unlabellable)]
+#[node]
impl ParbreakNode {
fn construct(_: &Vm, _: &mut Args) -> SourceResult<Content> {
Ok(Self.pack())
diff --git a/library/src/layout/place.rs b/library/src/layout/place.rs
index 28d231b7..4c9c0a46 100644
--- a/library/src/layout/place.rs
+++ b/library/src/layout/place.rs
@@ -1,10 +1,12 @@
use crate::prelude::*;
/// Place content at an absolute position.
+#[func]
+#[capable(Layout, Behave)]
#[derive(Debug, Hash)]
pub struct PlaceNode(pub Content, bool);
-#[node(Layout, Behave)]
+#[node]
impl PlaceNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
let aligns = args.find()?.unwrap_or(Axes::with_x(Some(GenAlign::Start)));
diff --git a/library/src/layout/repeat.rs b/library/src/layout/repeat.rs
index 6e0ce39f..196f19de 100644
--- a/library/src/layout/repeat.rs
+++ b/library/src/layout/repeat.rs
@@ -1,10 +1,12 @@
use crate::prelude::*;
/// Repeats content to fill a line.
+#[func]
+#[capable(Layout, Inline)]
#[derive(Debug, Hash)]
pub struct RepeatNode(pub Content);
-#[node(Layout, Inline)]
+#[node]
impl RepeatNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.expect("body")?).pack())
diff --git a/library/src/layout/spacing.rs b/library/src/layout/spacing.rs
index f5c39af4..91e45b03 100644
--- a/library/src/layout/spacing.rs
+++ b/library/src/layout/spacing.rs
@@ -3,6 +3,8 @@ use std::cmp::Ordering;
use crate::prelude::*;
/// Horizontal spacing.
+#[func]
+#[capable(Behave)]
#[derive(Debug, Copy, Clone, Hash)]
pub struct HNode {
/// The amount of horizontal spacing.
@@ -11,7 +13,7 @@ pub struct HNode {
pub weak: bool,
}
-#[node(Behave)]
+#[node]
impl HNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
let amount = args.expect("spacing")?;
@@ -50,6 +52,8 @@ impl Behave for HNode {
}
/// Vertical spacing.
+#[func]
+#[capable(Behave)]
#[derive(Debug, Copy, Clone, Hash, PartialEq, PartialOrd)]
pub struct VNode {
/// The amount of vertical spacing.
@@ -58,7 +62,7 @@ pub struct VNode {
pub weakness: u8,
}
-#[node(Behave)]
+#[node]
impl VNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
let amount = args.expect("spacing")?;
diff --git a/library/src/layout/stack.rs b/library/src/layout/stack.rs
index d44dcb48..1e956669 100644
--- a/library/src/layout/stack.rs
+++ b/library/src/layout/stack.rs
@@ -4,6 +4,8 @@ use super::{AlignNode, Spacing};
use crate::prelude::*;
/// Arrange content and spacing along an axis.
+#[func]
+#[capable(Layout)]
#[derive(Debug, Hash)]
pub struct StackNode {
/// The stacking direction.
@@ -14,7 +16,7 @@ pub struct StackNode {
pub children: Vec<StackChild>,
}
-#[node(Layout)]
+#[node]
impl StackNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self {
diff --git a/library/src/layout/transform.rs b/library/src/layout/transform.rs
index 8bf465a9..35b6709a 100644
--- a/library/src/layout/transform.rs
+++ b/library/src/layout/transform.rs
@@ -3,6 +3,8 @@ use typst::geom::Transform;
use crate::prelude::*;
/// Move content without affecting layout.
+#[func]
+#[capable(Layout, Inline)]
#[derive(Debug, Hash)]
pub struct MoveNode {
/// The offset by which to move the content.
@@ -11,7 +13,7 @@ pub struct MoveNode {
pub body: Content,
}
-#[node(Layout, Inline)]
+#[node]
impl MoveNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
let dx = args.named("dx")?.unwrap_or_default();
@@ -44,6 +46,8 @@ impl Layout for MoveNode {
impl Inline for MoveNode {}
/// Transform content without affecting layout.
+#[func]
+#[capable(Layout, Inline)]
#[derive(Debug, Hash)]
pub struct TransformNode<const T: TransformKind> {
/// Transformation to apply to the content.
@@ -58,7 +62,7 @@ pub type RotateNode = TransformNode<ROTATE>;
/// Scale content without affecting layout.
pub type ScaleNode = TransformNode<SCALE>;
-#[node(Layout, Inline)]
+#[node]
impl<const T: TransformKind> TransformNode<T> {
/// The origin of the transformation.
#[property(resolve)]
diff --git a/library/src/lib.rs b/library/src/lib.rs
index 86bef0b9..2d03ef7c 100644
--- a/library/src/lib.rs
+++ b/library/src/lib.rs
@@ -25,111 +25,110 @@ fn scope() -> Scope {
let mut std = Scope::new();
// Basics.
- std.def_node::<basics::HeadingNode>("heading");
- std.def_node::<basics::ListNode>("list");
- std.def_node::<basics::EnumNode>("enum");
- std.def_node::<basics::DescNode>("desc");
- std.def_node::<basics::TableNode>("table");
+ std.def_func::<basics::HeadingNode>("heading");
+ std.def_func::<basics::ListNode>("list");
+ std.def_func::<basics::EnumNode>("enum");
+ std.def_func::<basics::DescNode>("desc");
+ std.def_func::<basics::TableNode>("table");
// Text.
- std.def_node::<text::TextNode>("text");
- std.def_node::<text::LinebreakNode>("linebreak");
- std.def_node::<text::SymbolNode>("symbol");
- std.def_node::<text::SmartQuoteNode>("smartquote");
- std.def_node::<text::StrongNode>("strong");
- std.def_node::<text::EmphNode>("emph");
- std.def_fn("lower", text::lower);
- std.def_fn("upper", text::upper);
- std.def_fn("smallcaps", text::smallcaps);
- std.def_node::<text::SubNode>("sub");
- std.def_node::<text::SuperNode>("super");
- std.def_node::<text::UnderlineNode>("underline");
- std.def_node::<text::StrikeNode>("strike");
- std.def_node::<text::OverlineNode>("overline");
- std.def_node::<text::RawNode>("raw");
+ std.def_func::<text::TextNode>("text");
+ std.def_func::<text::LinebreakNode>("linebreak");
+ std.def_func::<text::SymbolNode>("symbol");
+ std.def_func::<text::SmartQuoteNode>("smartquote");
+ std.def_func::<text::StrongNode>("strong");
+ std.def_func::<text::EmphNode>("emph");
+ std.def_func::<text::LowerFunc>("lower");
+ std.def_func::<text::UpperFunc>("upper");
+ std.def_func::<text::SmallcapsFunc>("smallcaps");
+ std.def_func::<text::SubNode>("sub");
+ std.def_func::<text::SuperNode>("super");
+ std.def_func::<text::UnderlineNode>("underline");
+ std.def_func::<text::StrikeNode>("strike");
+ std.def_func::<text::OverlineNode>("overline");
+ std.def_func::<text::RawNode>("raw");
// Math.
- std.def_node::<math::MathNode>("math");
- std.def_node::<math::AtomNode>("atom");
- std.def_node::<math::AccNode>("acc");
- std.def_node::<math::FracNode>("frac");
- std.def_node::<math::BinomNode>("binom");
- std.def_node::<math::SqrtNode>("sqrt");
- std.def_node::<math::FloorNode>("floor");
- std.def_node::<math::CeilNode>("ceil");
- std.def_node::<math::VecNode>("vec");
- std.def_node::<math::CasesNode>("cases");
- std.def_node::<math::SerifNode>("serif");
- std.def_node::<math::SansNode>("sans");
- std.def_node::<math::BoldNode>("bold");
- std.def_node::<math::ItalNode>("ital");
- std.def_node::<math::CalNode>("cal");
- std.def_node::<math::FrakNode>("frak");
- std.def_node::<math::MonoNode>("mono");
- std.def_node::<math::BbNode>("bb");
+ std.def_func::<math::MathNode>("math");
+ std.def_func::<math::AtomNode>("atom");
+ std.def_func::<math::AccNode>("acc");
+ std.def_func::<math::FracNode>("frac");
+ std.def_func::<math::BinomNode>("binom");
+ std.def_func::<math::SqrtNode>("sqrt");
+ std.def_func::<math::FloorNode>("floor");
+ std.def_func::<math::CeilNode>("ceil");
+ std.def_func::<math::VecNode>("vec");
+ std.def_func::<math::CasesNode>("cases");
+ std.def_func::<math::SerifNode>("serif");
+ std.def_func::<math::SansNode>("sans");
+ std.def_func::<math::BoldNode>("bold");
+ std.def_func::<math::ItalNode>("ital");
+ std.def_func::<math::CalNode>("cal");
+ std.def_func::<math::FrakNode>("frak");
+ std.def_func::<math::MonoNode>("mono");
+ std.def_func::<math::BbNode>("bb");
// Layout.
- std.def_node::<layout::PageNode>("page");
- std.def_node::<layout::PagebreakNode>("pagebreak");
- std.def_node::<layout::FlowNode>("flow");
- std.def_node::<layout::VNode>("v");
- std.def_node::<layout::ParNode>("par");
- std.def_node::<layout::ParbreakNode>("parbreak");
- std.def_node::<layout::HNode>("h");
- std.def_node::<layout::BoxNode>("box");
- std.def_node::<layout::BlockNode>("block");
- std.def_node::<layout::StackNode>("stack");
- std.def_node::<layout::GridNode>("grid");
- std.def_node::<layout::ColumnsNode>("columns");
- std.def_node::<layout::ColbreakNode>("colbreak");
- std.def_node::<layout::PlaceNode>("place");
- std.def_node::<layout::AlignNode>("align");
- std.def_node::<layout::PadNode>("pad");
- std.def_node::<layout::RepeatNode>("repeat");
- std.def_node::<layout::MoveNode>("move");
- std.def_node::<layout::ScaleNode>("scale");
- std.def_node::<layout::RotateNode>("rotate");
- std.def_node::<layout::HideNode>("hide");
+ std.def_func::<layout::PageNode>("page");
+ std.def_func::<layout::PagebreakNode>("pagebreak");
+ std.def_func::<layout::VNode>("v");
+ std.def_func::<layout::ParNode>("par");
+ std.def_func::<layout::ParbreakNode>("parbreak");
+ std.def_func::<layout::HNode>("h");
+ std.def_func::<layout::BoxNode>("box");
+ std.def_func::<layout::BlockNode>("block");
+ std.def_func::<layout::StackNode>("stack");
+ std.def_func::<layout::GridNode>("grid");
+ std.def_func::<layout::ColumnsNode>("columns");
+ std.def_func::<layout::ColbreakNode>("colbreak");
+ std.def_func::<layout::PlaceNode>("place");
+ std.def_func::<layout::AlignNode>("align");
+ std.def_func::<layout::PadNode>("pad");
+ std.def_func::<layout::RepeatNode>("repeat");
+ std.def_func::<layout::MoveNode>("move");
+ std.def_func::<layout::ScaleNode>("scale");
+ std.def_func::<layout::RotateNode>("rotate");
+ std.def_func::<layout::HideNode>("hide");
// Visualize.
- std.def_node::<visualize::ImageNode>("image");
- std.def_node::<visualize::LineNode>("line");
- std.def_node::<visualize::RectNode>("rect");
- std.def_node::<visualize::SquareNode>("square");
- std.def_node::<visualize::EllipseNode>("ellipse");
- std.def_node::<visualize::CircleNode>("circle");
+ std.def_func::<visualize::ImageNode>("image");
+ std.def_func::<visualize::LineNode>("line");
+ std.def_func::<visualize::RectNode>("rect");
+ std.def_func::<visualize::SquareNode>("square");
+ std.def_func::<visualize::EllipseNode>("ellipse");
+ std.def_func::<visualize::CircleNode>("circle");
// Meta.
- std.def_node::<meta::DocumentNode>("document");
- std.def_node::<meta::RefNode>("ref");
- std.def_node::<meta::LinkNode>("link");
- std.def_node::<meta::OutlineNode>("outline");
+ std.def_func::<meta::DocumentNode>("document");
+ std.def_func::<meta::RefNode>("ref");
+ std.def_func::<meta::LinkNode>("link");
+ std.def_func::<meta::OutlineNode>("outline");
// Compute.
- std.def_fn("type", compute::type_);
- std.def_fn("repr", compute::repr);
- std.def_fn("assert", compute::assert);
- std.def_fn("eval", compute::eval);
- std.def_fn("int", compute::int);
- std.def_fn("float", compute::float);
- std.def_fn("luma", compute::luma);
- std.def_fn("rgb", compute::rgb);
- std.def_fn("cmyk", compute::cmyk);
- std.def_fn("str", compute::str);
- std.def_fn("label", compute::label);
- std.def_fn("regex", compute::regex);
- std.def_fn("range", compute::range);
- std.def_fn("abs", compute::abs);
- std.def_fn("min", compute::min);
- std.def_fn("max", compute::max);
- std.def_fn("even", compute::even);
- std.def_fn("odd", compute::odd);
- std.def_fn("mod", compute::mod_);
- std.def_fn("csv", compute::csv);
- std.def_fn("json", compute::json);
- std.def_fn("xml", compute::xml);
- std.def_fn("lorem", compute::lorem);
- std.def_fn("numbering", compute::numbering);
+ std.def_func::<compute::TypeFunc>("type");
+ std.def_func::<compute::ReprFunc>("repr");
+ std.def_func::<compute::AssertFunc>("assert");
+ std.def_func::<compute::EvalFunc>("eval");
+ std.def_func::<compute::IntFunc>("int");
+ std.def_func::<compute::FloatFunc>("float");
+ std.def_func::<compute::LumaFunc>("luma");
+ std.def_func::<compute::RgbFunc>("rgb");
+ std.def_func::<compute::CmykFunc>("cmyk");
+ std.def_func::<compute::StrFunc>("str");
+ std.def_func::<compute::LabelFunc>("label");
+ std.def_func::<compute::RegexFunc>("regex");
+ std.def_func::<compute::RangeFunc>("range");
+ std.def_func::<compute::AbsFunc>("abs");
+ std.def_func::<compute::MinFunc>("min");
+ std.def_func::<compute::MaxFunc>("max");
+ std.def_func::<compute::EvenFunc>("even");
+ std.def_func::<compute::OddFunc>("odd");
+ std.def_func::<compute::ModFunc>("mod");
+ std.def_func::<compute::CsvFunc>("csv");
+ std.def_func::<compute::JsonFunc>("json");
+ std.def_func::<compute::XmlFunc>("xml");
+ std.def_func::<compute::LoremFunc>("lorem");
+ std.def_func::<compute::NumberingFunc>("numbering");
// Colors.
std.define("black", Color::BLACK);
diff --git a/library/src/math/matrix.rs b/library/src/math/matrix.rs
index bc5e542a..2d32f4b5 100644
--- a/library/src/math/matrix.rs
+++ b/library/src/math/matrix.rs
@@ -1,10 +1,12 @@
use super::*;
/// A column vector.
+#[func]
+#[capable(Texify)]
#[derive(Debug, Hash)]
pub struct VecNode(Vec<Content>);
-#[node(Texify)]
+#[node]
impl VecNode {
/// The kind of delimiter.
pub const DELIM: Delimiter = Delimiter::Paren;
@@ -61,10 +63,12 @@ castable! {
}
/// A case distinction.
+#[func]
+#[capable(Texify)]
#[derive(Debug, Hash)]
pub struct CasesNode(Vec<Content>);
-#[node(Texify)]
+#[node]
impl CasesNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.all()?).pack())
diff --git a/library/src/math/mod.rs b/library/src/math/mod.rs
index 317bc1d4..59c621e8 100644
--- a/library/src/math/mod.rs
+++ b/library/src/math/mod.rs
@@ -15,6 +15,8 @@ use crate::prelude::*;
use crate::text::{FontFamily, LinebreakNode, SpaceNode, SymbolNode, TextNode};
/// A piece of a mathematical formula.
+#[func]
+#[capable(Show, Layout, Inline, Texify)]
#[derive(Debug, Clone, Hash)]
pub struct MathNode {
/// Whether the formula is display-level.
@@ -23,7 +25,7 @@ pub struct MathNode {
pub children: Vec<Content>,
}
-#[node(Show, Layout, Inline, Texify)]
+#[node]
impl MathNode {
fn field(&self, name: &str) -> Option<Value> {
match name {
@@ -242,10 +244,12 @@ impl Texify for Content {
}
/// An atom in a math formula: `x`, `+`, `12`.
+#[func]
+#[capable(Texify)]
#[derive(Debug, Hash)]
pub struct AtomNode(pub EcoString);
-#[node(Texify)]
+#[node]
impl AtomNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.expect("text")?).pack())
@@ -279,6 +283,8 @@ impl Texify for AtomNode {
}
/// An accented node.
+#[func]
+#[capable(Texify)]
#[derive(Debug, Hash)]
pub struct AccNode {
/// The accent base.
@@ -287,7 +293,7 @@ pub struct AccNode {
pub accent: char,
}
-#[node(Texify)]
+#[node]
impl AccNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
let base = args.expect("base")?;
@@ -352,6 +358,8 @@ impl Texify for AccNode {
}
/// A fraction.
+#[func]
+#[capable(Texify)]
#[derive(Debug, Hash)]
pub struct FracNode {
/// The numerator.
@@ -360,7 +368,7 @@ pub struct FracNode {
pub denom: Content,
}
-#[node(Texify)]
+#[node]
impl FracNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
let num = args.expect("numerator")?;
@@ -381,6 +389,8 @@ impl Texify for FracNode {
}
/// A binomial.
+#[func]
+#[capable(Texify)]
#[derive(Debug, Hash)]
pub struct BinomNode {
/// The upper index.
@@ -389,7 +399,7 @@ pub struct BinomNode {
pub lower: Content,
}
-#[node(Texify)]
+#[node]
impl BinomNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
let upper = args.expect("upper index")?;
@@ -410,6 +420,8 @@ impl Texify for BinomNode {
}
/// A sub- and/or superscript.
+#[func]
+#[capable(Texify)]
#[derive(Debug, Hash)]
pub struct ScriptNode {
/// The base.
@@ -420,7 +432,7 @@ pub struct ScriptNode {
pub sup: Option<Content>,
}
-#[node(Texify)]
+#[node]
impl ScriptNode {}
impl Texify for ScriptNode {
@@ -444,10 +456,12 @@ impl Texify for ScriptNode {
}
/// A math alignment point: `&`, `&&`.
+#[func]
+#[capable(Texify)]
#[derive(Debug, Hash)]
pub struct AlignPointNode(pub usize);
-#[node(Texify)]
+#[node]
impl AlignPointNode {}
impl Texify for AlignPointNode {
@@ -457,10 +471,12 @@ impl Texify for AlignPointNode {
}
/// A square root.
+#[func]
+#[capable(Texify)]
#[derive(Debug, Hash)]
pub struct SqrtNode(pub Content);
-#[node(Texify)]
+#[node]
impl SqrtNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.expect("body")?).pack())
@@ -477,10 +493,12 @@ impl Texify for SqrtNode {
}
/// A floored expression.
+#[func]
+#[capable(Texify)]
#[derive(Debug, Hash)]
pub struct FloorNode(pub Content);
-#[node(Texify)]
+#[node]
impl FloorNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.expect("body")?).pack())
@@ -497,10 +515,12 @@ impl Texify for FloorNode {
}
/// A ceiled expression.
+#[func]
+#[capable(Texify)]
#[derive(Debug, Hash)]
pub struct CeilNode(pub Content);
-#[node(Texify)]
+#[node]
impl CeilNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.expect("body")?).pack())
diff --git a/library/src/math/style.rs b/library/src/math/style.rs
index 9e81a549..0fdff740 100644
--- a/library/src/math/style.rs
+++ b/library/src/math/style.rs
@@ -1,10 +1,12 @@
use super::*;
/// Serif (roman) font style.
+#[func]
+#[capable(Texify)]
#[derive(Debug, Hash)]
pub struct SerifNode(pub Content);
-#[node(Texify)]
+#[node]
impl SerifNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.expect("body")?).pack())
@@ -21,10 +23,12 @@ impl Texify for SerifNode {
}
/// Sans-serif font style.
+#[func]
+#[capable(Texify)]
#[derive(Debug, Hash)]
pub struct SansNode(pub Content);
-#[node(Texify)]
+#[node]
impl SansNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.expect("body")?).pack())
@@ -41,10 +45,12 @@ impl Texify for SansNode {
}
/// Bold font style.
+#[func]
+#[capable(Texify)]
#[derive(Debug, Hash)]
pub struct BoldNode(pub Content);
-#[node(Texify)]
+#[node]
impl BoldNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.expect("body")?).pack())
@@ -61,10 +67,12 @@ impl Texify for BoldNode {
}
/// Italic font style.
+#[func]
+#[capable(Texify)]
#[derive(Debug, Hash)]
pub struct ItalNode(pub Content);
-#[node(Texify)]
+#[node]
impl ItalNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.expect("body")?).pack())
@@ -81,10 +89,12 @@ impl Texify for ItalNode {
}
/// Calligraphic font style.
+#[func]
+#[capable(Texify)]
#[derive(Debug, Hash)]
pub struct CalNode(pub Content);
-#[node(Texify)]
+#[node]
impl CalNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.expect("body")?).pack())
@@ -101,10 +111,12 @@ impl Texify for CalNode {
}
/// Fraktur font style.
+#[func]
+#[capable(Texify)]
#[derive(Debug, Hash)]
pub struct FrakNode(pub Content);
-#[node(Texify)]
+#[node]
impl FrakNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.expect("body")?).pack())
@@ -121,10 +133,12 @@ impl Texify for FrakNode {
}
/// Monospace font style.
+#[func]
+#[capable(Texify)]
#[derive(Debug, Hash)]
pub struct MonoNode(pub Content);
-#[node(Texify)]
+#[node]
impl MonoNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.expect("body")?).pack())
@@ -141,10 +155,12 @@ impl Texify for MonoNode {
}
/// Blackboard bold (double-struck) font style.
+#[func]
+#[capable(Texify)]
#[derive(Debug, Hash)]
pub struct BbNode(pub Content);
-#[node(Texify)]
+#[node]
impl BbNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.expect("body")?).pack())
diff --git a/library/src/meta/document.rs b/library/src/meta/document.rs
index fbb62b6b..1dae4a2a 100644
--- a/library/src/meta/document.rs
+++ b/library/src/meta/document.rs
@@ -2,10 +2,12 @@ use crate::layout::{LayoutRoot, PageNode};
use crate::prelude::*;
/// The root node that represents a full document.
+#[func]
+#[capable(LayoutRoot)]
#[derive(Hash)]
pub struct DocumentNode(pub StyleVec<PageNode>);
-#[node(LayoutRoot)]
+#[node]
impl DocumentNode {
/// The document's title.
#[property(referenced)]
diff --git a/library/src/meta/link.rs b/library/src/meta/link.rs
index 34304ea9..94328b00 100644
--- a/library/src/meta/link.rs
+++ b/library/src/meta/link.rs
@@ -2,6 +2,8 @@ use crate::prelude::*;
use crate::text::TextNode;
/// Link text and other elements to a destination.
+#[func]
+#[capable(Show, Finalize)]
#[derive(Debug, Hash)]
pub struct LinkNode {
/// The destination the link points to.
@@ -23,7 +25,7 @@ impl LinkNode {
}
}
-#[node(Show, Finalize)]
+#[node]
impl LinkNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
let dest = args.expect::<Destination>("destination")?;
diff --git a/library/src/meta/outline.rs b/library/src/meta/outline.rs
index 53535be5..d0fbc3f7 100644
--- a/library/src/meta/outline.rs
+++ b/library/src/meta/outline.rs
@@ -4,10 +4,12 @@ use crate::prelude::*;
use crate::text::{LinebreakNode, SpaceNode, TextNode};
/// A section outline (table of contents).
+#[func]
+#[capable(Prepare, Show)]
#[derive(Debug, Hash)]
pub struct OutlineNode;
-#[node(Prepare, Show)]
+#[node]
impl OutlineNode {
/// The title of the outline.
#[property(referenced)]
diff --git a/library/src/meta/reference.rs b/library/src/meta/reference.rs
index a04fd13f..657e5ef7 100644
--- a/library/src/meta/reference.rs
+++ b/library/src/meta/reference.rs
@@ -2,10 +2,12 @@ use crate::prelude::*;
use crate::text::TextNode;
/// A reference to a label.
+#[func]
+#[capable(Show)]
#[derive(Debug, Hash)]
pub struct RefNode(pub EcoString);
-#[node(Show)]
+#[node]
impl RefNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.expect("target")?).pack())
diff --git a/library/src/prelude.rs b/library/src/prelude.rs
index 26a3c6c3..9b461389 100644
--- a/library/src/prelude.rs
+++ b/library/src/prelude.rs
@@ -15,10 +15,10 @@ pub use typst::doc::*;
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, Introspector, Label, Node, NodeId, Prepare,
- Resolve, Selector, Show, Smart, StabilityProvider, Str, StyleChain, StyleMap,
- StyleVec, Unlabellable, Value, Vm, Vt,
+ array, capability, capable, castable, dict, dynamic, format_str, func, node, Args,
+ Array, Cast, 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 23db71f9..ba3579e7 100644
--- a/library/src/shared/ext.rs
+++ b/library/src/shared/ext.rs
@@ -98,6 +98,7 @@ impl StyleMapExt for StyleMap {
}
/// Fill the frames resulting from content.
+#[capable(Layout)]
#[derive(Debug, Hash)]
struct FillNode {
/// How to fill the frames resulting from the `child`.
@@ -106,7 +107,7 @@ struct FillNode {
child: Content,
}
-#[node(Layout)]
+#[node]
impl FillNode {}
impl Layout for FillNode {
@@ -126,6 +127,7 @@ impl Layout for FillNode {
}
/// Stroke the frames resulting from content.
+#[capable(Layout)]
#[derive(Debug, Hash)]
struct StrokeNode {
/// How to stroke the frames resulting from the `child`.
@@ -134,7 +136,7 @@ struct StrokeNode {
child: Content,
}
-#[node(Layout)]
+#[node]
impl StrokeNode {}
impl Layout for StrokeNode {
diff --git a/library/src/text/deco.rs b/library/src/text/deco.rs
index a6fa490f..fceb4cfd 100644
--- a/library/src/text/deco.rs
+++ b/library/src/text/deco.rs
@@ -5,6 +5,8 @@ use super::TextNode;
use crate::prelude::*;
/// Typeset underline, stricken-through or overlined text.
+#[func]
+#[capable(Show)]
#[derive(Debug, Hash)]
pub struct DecoNode<const L: DecoLine>(pub Content);
@@ -17,7 +19,7 @@ pub type StrikeNode = DecoNode<STRIKETHROUGH>;
/// Typeset overlined text.
pub type OverlineNode = DecoNode<OVERLINE>;
-#[node(Show)]
+#[node]
impl<const L: DecoLine> DecoNode<L> {
/// How to stroke the line. The text color and thickness are read from the
/// font tables if `auto`.
diff --git a/library/src/text/misc.rs b/library/src/text/misc.rs
index 896c03ac..1c5a32b4 100644
--- a/library/src/text/misc.rs
+++ b/library/src/text/misc.rs
@@ -2,10 +2,12 @@ use super::TextNode;
use crate::prelude::*;
/// A text space.
+#[func]
+#[capable(Unlabellable, Behave)]
#[derive(Debug, Hash)]
pub struct SpaceNode;
-#[node(Unlabellable, Behave)]
+#[node]
impl SpaceNode {
fn construct(_: &Vm, _: &mut Args) -> SourceResult<Content> {
Ok(Self.pack())
@@ -21,12 +23,14 @@ impl Behave for SpaceNode {
}
/// A line break.
+#[func]
+#[capable(Behave)]
#[derive(Debug, Hash)]
pub struct LinebreakNode {
pub justify: bool,
}
-#[node(Behave)]
+#[node]
impl LinebreakNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
let justify = args.named("justify")?.unwrap_or(false);
@@ -41,10 +45,12 @@ impl Behave for LinebreakNode {
}
/// Strongly emphasizes content by increasing the font weight.
+#[func]
+#[capable(Show)]
#[derive(Debug, Hash)]
pub struct StrongNode(pub Content);
-#[node(Show)]
+#[node]
impl StrongNode {
/// The delta to apply on the font weight.
pub const DELTA: i64 = 300;
@@ -86,10 +92,12 @@ impl Fold for Delta {
}
/// Emphasizes content by flipping the italicness.
+#[func]
+#[capable(Show)]
#[derive(Debug, Hash)]
pub struct EmphNode(pub Content);
-#[node(Show)]
+#[node]
impl EmphNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.expect("body")?).pack())
@@ -122,12 +130,14 @@ impl Fold for Toggle {
}
/// Convert a string or content to lowercase.
-pub fn lower(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn lower(args: &mut Args) -> SourceResult<Value> {
case(Case::Lower, args)
}
/// Convert a string or content to uppercase.
-pub fn upper(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn upper(args: &mut Args) -> SourceResult<Value> {
case(Case::Upper, args)
}
@@ -161,7 +171,8 @@ impl Case {
}
/// Display text in small capitals.
-pub fn smallcaps(_: &Vm, args: &mut Args) -> SourceResult<Value> {
+#[func]
+pub fn smallcaps(args: &mut Args) -> SourceResult<Value> {
let body: Content = args.expect("content")?;
Ok(Value::Content(body.styled(TextNode::SMALLCAPS, true)))
}
diff --git a/library/src/text/mod.rs b/library/src/text/mod.rs
index 5466637e..d09d8f28 100644
--- a/library/src/text/mod.rs
+++ b/library/src/text/mod.rs
@@ -26,6 +26,8 @@ use crate::layout::ParNode;
use crate::prelude::*;
/// A single run of text with the same style.
+#[func]
+#[capable]
#[derive(Clone, Hash)]
pub struct TextNode(pub EcoString);
diff --git a/library/src/text/quotes.rs b/library/src/text/quotes.rs
index 95cf1ad9..0f678de3 100644
--- a/library/src/text/quotes.rs
+++ b/library/src/text/quotes.rs
@@ -3,6 +3,8 @@ use typst::syntax::is_newline;
use crate::prelude::*;
/// A smart quote.
+#[func]
+#[capable]
#[derive(Debug, Hash)]
pub struct SmartQuoteNode {
pub double: bool,
diff --git a/library/src/text/raw.rs b/library/src/text/raw.rs
index 21a0531a..4ad70654 100644
--- a/library/src/text/raw.rs
+++ b/library/src/text/raw.rs
@@ -7,6 +7,8 @@ use crate::layout::BlockNode;
use crate::prelude::*;
/// Raw text with optional syntax highlighting.
+#[func]
+#[capable(Show)]
#[derive(Debug, Hash)]
pub struct RawNode {
/// The raw text.
@@ -15,7 +17,7 @@ pub struct RawNode {
pub block: bool,
}
-#[node(Show)]
+#[node]
impl RawNode {
/// The language to syntax-highlight in.
#[property(referenced)]
diff --git a/library/src/text/shift.rs b/library/src/text/shift.rs
index 92e963e8..65adc027 100644
--- a/library/src/text/shift.rs
+++ b/library/src/text/shift.rs
@@ -10,6 +10,8 @@ use crate::prelude::*;
/// typography possible, we first try to transform the text to superscript
/// codepoints. If that fails, we fall back to rendering shrunk normal letters
/// in a raised way.
+#[func]
+#[capable(Show)]
#[derive(Debug, Hash)]
pub struct ShiftNode<const S: ShiftKind>(pub Content);
@@ -19,7 +21,7 @@ pub type SuperNode = ShiftNode<SUPERSCRIPT>;
/// Shift the text into subscript.
pub type SubNode = ShiftNode<SUBSCRIPT>;
-#[node(Show)]
+#[node]
impl<const S: ShiftKind> ShiftNode<S> {
/// Whether to prefer the dedicated sub- and superscript characters of the
/// font.
diff --git a/library/src/text/symbol.rs b/library/src/text/symbol.rs
index cc12afb9..fc746eb2 100644
--- a/library/src/text/symbol.rs
+++ b/library/src/text/symbol.rs
@@ -2,10 +2,12 @@ use crate::prelude::*;
use crate::text::TextNode;
/// A symbol identified by symmie notation.
+#[func]
+#[capable(Show)]
#[derive(Debug, Hash)]
pub struct SymbolNode(pub EcoString);
-#[node(Show)]
+#[node]
impl SymbolNode {
fn construct(_: &Vm, args: &mut Args) -> SourceResult<Content> {
Ok(Self(args.expect("notation")?).pack())
diff --git a/library/src/visualize/image.rs b/library/src/visualize/image.rs
index 205c8a7d..b8b05aec 100644
--- a/library/src/visualize/image.rs
+++ b/library/src/visualize/image.rs
@@ -5,10 +5,12 @@ use typst::image::{Image, ImageFormat, RasterFormat, VectorFormat};
use crate::prelude::*;
/// Show a raster or vector graphic.
+#[func]
+#[capable(Layout, Inline)]
#[derive(Debug, Hash)]
pub struct ImageNode(pub Image);
-#[node(Layout, Inline)]
+#[node]
impl ImageNode {
/// How the image should adjust itself to a given area.
pub const FIT: ImageFit = ImageFit::Cover;
diff --git a/library/src/visualize/line.rs b/library/src/visualize/line.rs
index ef6ce2c3..ed6a3d92 100644
--- a/library/src/visualize/line.rs
+++ b/library/src/visualize/line.rs
@@ -1,6 +1,8 @@
use crate::prelude::*;
/// Display a line without affecting the layout.
+#[func]
+#[capable(Layout, Inline)]
#[derive(Debug, Hash)]
pub struct LineNode {
/// Where the line starts.
@@ -9,7 +11,7 @@ pub struct LineNode {
pub delta: Axes<Rel<Length>>,
}
-#[node(Layout, Inline)]
+#[node]
impl LineNode {
/// How to stroke the line.
#[property(resolve, fold)]
diff --git a/library/src/visualize/shape.rs b/library/src/visualize/shape.rs
index 4517380a..702fc6f8 100644
--- a/library/src/visualize/shape.rs
+++ b/library/src/visualize/shape.rs
@@ -3,6 +3,8 @@ use std::f64::consts::SQRT_2;
use crate::prelude::*;
/// A sizable and fillable shape with optional content.
+#[func]
+#[capable(Layout, Inline)]
#[derive(Debug, Hash)]
pub struct ShapeNode<const S: ShapeKind>(pub Option<Content>);
@@ -18,7 +20,7 @@ pub type CircleNode = ShapeNode<CIRCLE>;
/// A ellipse with optional content.
pub type EllipseNode = ShapeNode<ELLIPSE>;
-#[node(Layout, Inline)]
+#[node]
impl<const S: ShapeKind> ShapeNode<S> {
/// How to fill the shape.
pub const FILL: Option<Paint> = None;