diff options
| author | Laurenz <laurmaedje@gmail.com> | 2024-02-27 11:05:16 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-02-27 10:05:16 +0000 |
| commit | 145723b1ef4fa23f1f6665b8907dfe79d0bf83cf (patch) | |
| tree | 02a7de661ddd5dafa75dfce3e3c8b45a7333b9dc /crates/typst-macros/src | |
| parent | e9ee00a7c0df083663ff5ccca162238b88525e14 (diff) | |
New context system (#3497)
Diffstat (limited to 'crates/typst-macros/src')
| -rw-r--r-- | crates/typst-macros/src/elem.rs | 23 | ||||
| -rw-r--r-- | crates/typst-macros/src/func.rs | 15 | ||||
| -rw-r--r-- | crates/typst-macros/src/lib.rs | 2 | ||||
| -rw-r--r-- | crates/typst-macros/src/util.rs | 1 |
4 files changed, 38 insertions, 3 deletions
diff --git a/crates/typst-macros/src/elem.rs b/crates/typst-macros/src/elem.rs index 81548dd7..f14d3350 100644 --- a/crates/typst-macros/src/elem.rs +++ b/crates/typst-macros/src/elem.rs @@ -617,6 +617,7 @@ fn create_native_elem_impl(element: &Elem) -> TokenStream { vtable: <#ident as #foundations::Capable>::vtable, field_id: |name| name.parse().ok().map(|id: Fields| id as u8), field_name: |id| id.try_into().ok().map(Fields::to_str), + field_from_styles: <#ident as #foundations::Fields>::field_from_styles, local_name: #local_name, scope: #foundations::Lazy::new(|| #scope), params: #foundations::Lazy::new(|| ::std::vec![#(#params),*]) @@ -866,6 +867,20 @@ fn create_fields_impl(element: &Elem) -> TokenStream { quote! { Fields::#enum_ident => #expr } }); + // Fields that can be accessed using the `field_from_styles` method. + let field_from_styles_arms = element.visible_fields().map(|field| { + let Field { enum_ident, .. } = field; + + let expr = if field.required || field.synthesized { + quote! { None } + } else { + let value = create_style_chain_access(field, false, quote!(None)); + quote! { Some(#into_value(#value)) } + }; + + quote! { Fields::#enum_ident => #expr } + }); + // Sets fields from the style chain. let materializes = visible_non_ghost() .filter(|field| !field.required && !field.synthesized) @@ -939,6 +954,14 @@ fn create_fields_impl(element: &Elem) -> TokenStream { } } + fn field_from_styles(id: u8, styles: #foundations::StyleChain) -> Option<#foundations::Value> { + let id = Fields::try_from(id).ok()?; + match id { + #(#field_from_styles_arms,)* + _ => None, + } + } + fn materialize(&mut self, styles: #foundations::StyleChain) { #(#materializes)* } diff --git a/crates/typst-macros/src/func.rs b/crates/typst-macros/src/func.rs index 953df428..728ab05b 100644 --- a/crates/typst-macros/src/func.rs +++ b/crates/typst-macros/src/func.rs @@ -24,6 +24,7 @@ struct Func { constructor: bool, keywords: Vec<String>, parent: Option<syn::Type>, + contextual: bool, docs: String, vis: syn::Visibility, ident: Ident, @@ -37,6 +38,7 @@ struct Func { struct SpecialParams { self_: Option<Param>, engine: bool, + context: bool, args: bool, span: bool, } @@ -67,6 +69,7 @@ enum Binding { /// The `..` in `#[func(..)]`. pub struct Meta { pub scope: bool, + pub contextual: bool, pub name: Option<String>, pub title: Option<String>, pub constructor: bool, @@ -78,6 +81,7 @@ impl Parse for Meta { fn parse(input: ParseStream) -> Result<Self> { Ok(Self { scope: parse_flag::<kw::scope>(input)?, + contextual: parse_flag::<kw::contextual>(input)?, name: parse_string::<kw::name>(input)?, title: parse_string::<kw::title>(input)?, constructor: parse_flag::<kw::constructor>(input)?, @@ -117,6 +121,7 @@ fn parse(stream: TokenStream, item: &syn::ItemFn) -> Result<Func> { constructor: meta.constructor, keywords: meta.keywords, parent: meta.parent, + contextual: meta.contextual, docs, vis: item.vis.clone(), ident: item.sig.ident.clone(), @@ -171,6 +176,7 @@ fn parse_param( match ident.to_string().as_str() { "engine" => special.engine = true, + "context" => special.context = true, "args" => special.args = true, "span" => special.span = true, _ => { @@ -247,6 +253,7 @@ fn create_func_data(func: &Func) -> TokenStream { scope, parent, constructor, + contextual, .. } = func; @@ -272,6 +279,7 @@ fn create_func_data(func: &Func) -> TokenStream { title: #title, docs: #docs, keywords: &[#(#keywords),*], + contextual: #contextual, scope: #foundations::Lazy::new(|| #scope), params: #foundations::Lazy::new(|| ::std::vec![#(#params),*]), returns: #foundations::Lazy::new(|| <#returns as #foundations::Reflect>::output()), @@ -320,12 +328,13 @@ fn create_wrapper_closure(func: &Func) -> TokenStream { .as_ref() .map(bind) .map(|tokens| quote! { #tokens, }); - let vt_ = func.special.engine.then(|| quote! { engine, }); + let engine_ = func.special.engine.then(|| quote! { engine, }); + let context_ = func.special.context.then(|| quote! { context, }); let args_ = func.special.args.then(|| quote! { args, }); let span_ = func.special.span.then(|| quote! { args.span, }); let forwarded = func.params.iter().filter(|param| !param.external).map(bind); quote! { - __typst_func(#self_ #vt_ #args_ #span_ #(#forwarded,)*) + __typst_func(#self_ #engine_ #context_ #args_ #span_ #(#forwarded,)*) } }; @@ -333,7 +342,7 @@ fn create_wrapper_closure(func: &Func) -> TokenStream { let ident = &func.ident; let parent = func.parent.as_ref().map(|ty| quote! { #ty:: }); quote! { - |engine, args| { + |engine, context, args| { let __typst_func = #parent #ident; #handlers #finish diff --git a/crates/typst-macros/src/lib.rs b/crates/typst-macros/src/lib.rs index 5d340473..f92230ef 100644 --- a/crates/typst-macros/src/lib.rs +++ b/crates/typst-macros/src/lib.rs @@ -40,6 +40,8 @@ use syn::DeriveInput; /// You can customize some properties of the resulting function: /// - `scope`: Indicates that the function has an associated scope defined by /// the `#[scope]` macro. +/// - `contextual`: Indicates that the function makes use of context. This has +/// no effect on the behaviour itself, but is used for the docs. /// - `name`: The functions's normal name (e.g. `min`). Defaults to the Rust /// name in kebab-case. /// - `title`: The functions's title case name (e.g. `Minimum`). Defaults to the diff --git a/crates/typst-macros/src/util.rs b/crates/typst-macros/src/util.rs index 89880db1..bfe22285 100644 --- a/crates/typst-macros/src/util.rs +++ b/crates/typst-macros/src/util.rs @@ -255,6 +255,7 @@ pub mod kw { syn::custom_keyword!(span); syn::custom_keyword!(title); syn::custom_keyword!(scope); + syn::custom_keyword!(contextual); syn::custom_keyword!(cast); syn::custom_keyword!(constructor); syn::custom_keyword!(keywords); |
