From 35a5221c920ee73c4013d1addbc3c6bf7fb20d0a Mon Sep 17 00:00:00 2001 From: Manuel Cillero Date: Thu, 11 Jun 2026 06:46:16 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20(macros):=20Permite=20(expr)=20como?= =?UTF-8?q?=20atributo=20en=20html!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Introduce `Attribute::Splice` en el AST de Maud, de modo que `(expr)` en posición de atributo renderiza la expresión directamente sobre el buffer de salida del elemento. --- helpers/pagetop-macros/src/maud/ast.rs | 16 ++++++++++++++++ helpers/pagetop-macros/src/maud/generate.rs | 10 ++++++++-- 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/helpers/pagetop-macros/src/maud/ast.rs b/helpers/pagetop-macros/src/maud/ast.rs index cdda2331..c8309ef5 100644 --- a/helpers/pagetop-macros/src/maud/ast.rs +++ b/helpers/pagetop-macros/src/maud/ast.rs @@ -212,6 +212,7 @@ impl DiagnosticParse for Element { || input.peek(Lit) || input.peek(Dot) || input.peek(Pound) + || input.peek(Paren) { let attr = input.diagnostic_parse(diagnostics)?; @@ -346,6 +347,10 @@ pub enum Attribute { name: HtmlName, attr_type: AttributeType, }, + Splice { + paren_token: Paren, + expr: Expr, + }, } impl DiagnosticParse for Attribute { @@ -374,6 +379,12 @@ impl DiagnosticParse for Attribute { pound_token: input.parse()?, name: input.diagnostic_parse(diagnostics)?, }) + } else if lookahead.peek(Paren) { + let content; + Ok(Self::Splice { + paren_token: parenthesized!(content in input), + expr: content.parse()?, + }) } else { let name = input.diagnostic_parse::(diagnostics)?; @@ -424,6 +435,11 @@ impl ToTokens for Attribute { name.to_tokens(tokens); attr_type.to_tokens(tokens); } + Self::Splice { paren_token, expr } => { + paren_token.surround(tokens, |tokens| { + expr.to_tokens(tokens); + }); + } } } } diff --git a/helpers/pagetop-macros/src/maud/generate.rs b/helpers/pagetop-macros/src/maud/generate.rs index a3dfb36e..ed2fa214 100644 --- a/helpers/pagetop-macros/src/maud/generate.rs +++ b/helpers/pagetop-macros/src/maud/generate.rs @@ -139,7 +139,7 @@ impl Generator { } fn attrs(&self, attrs: Vec, build: &mut Builder) { - let (classes, id, named_attrs) = split_attrs(attrs); + let (classes, id, named_attrs, spliced) = split_attrs(attrs); if !classes.is_empty() { let mut toggle_class_exprs = vec![]; @@ -184,6 +184,9 @@ impl Generator { for (name, attr_type) in named_attrs { self.attr(name, attr_type, build); } + for expr in spliced { + self.splice(expr, build); + } } fn control_flow>(&self, control_flow: ControlFlow, build: &mut Builder) { @@ -316,10 +319,12 @@ fn split_attrs( Vec<(HtmlNameOrMarkup, Option)>, Option, Vec<(HtmlName, AttributeType)>, + Vec, ) { let mut classes = vec![]; let mut id = None; let mut named_attrs = vec![]; + let mut spliced = vec![]; for attr in attrs { match attr { @@ -328,10 +333,11 @@ fn split_attrs( } Attribute::Id { name, .. } => id = Some(name), Attribute::Named { name, attr_type } => named_attrs.push((name, attr_type)), + Attribute::Splice { expr, .. } => spliced.push(expr), } } - (classes, id, named_attrs) + (classes, id, named_attrs, spliced) } ////////////////////////////////////////////////////////