mirror of
https://github.com/Zenithsiz/dynatos.git
synced 2026-02-03 18:13:04 +00:00
dynatos_html::{html, html_file} now allow expressions inside of text using %{expr}%.
This commit is contained in:
parent
f3d792f544
commit
9939564b37
1
Cargo.lock
generated
1
Cargo.lock
generated
@ -95,6 +95,7 @@ name = "dynatos-html-macros"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"dynatos-html-parser",
|
||||
"itertools",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.50",
|
||||
|
||||
@ -10,6 +10,7 @@ proc-macro = true
|
||||
|
||||
dynatos-html-parser = { workspace = true }
|
||||
|
||||
itertools = { workspace = true }
|
||||
proc-macro2 = { workspace = true }
|
||||
quote = { workspace = true }
|
||||
syn = { workspace = true }
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
// Imports
|
||||
use {
|
||||
dynatos_html_parser::{XHtml, XHtmlNode},
|
||||
itertools::Itertools,
|
||||
proc_macro::TokenStream,
|
||||
std::{
|
||||
fs,
|
||||
@ -197,11 +198,37 @@ impl Node {
|
||||
return None;
|
||||
}
|
||||
|
||||
let args = self::split_text_args(text);
|
||||
|
||||
// If we have just a single constant argument, return a simple version
|
||||
if let [TextArg::Cons(text)] = &*args {
|
||||
return Some(Self {
|
||||
ty: NodeTy::Text,
|
||||
expr: syn::parse_quote!(
|
||||
dynatos_html::text(#text)
|
||||
),
|
||||
});
|
||||
};
|
||||
|
||||
let (cons, args) = args
|
||||
.into_iter()
|
||||
.partition_map::<Vec<_>, Vec<_>, _, _, _>(|arg| match arg {
|
||||
TextArg::Cons(text) => itertools::Either::Left(text),
|
||||
TextArg::Argument(arg) => itertools::Either::Right(arg),
|
||||
});
|
||||
|
||||
let fmt = cons.into_iter().join("{}");
|
||||
let args = args
|
||||
.into_iter()
|
||||
.map(|arg| syn::parse_str::<syn::Expr>(arg).expect("Unable to parse argument expression"))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Self {
|
||||
ty: NodeTy::Text,
|
||||
expr: syn::parse_quote!(
|
||||
dynatos_html::text(#text)
|
||||
),
|
||||
expr: syn::parse_quote!(dynatos::NodeWithDynText::with_dyn_text(
|
||||
dynatos_html::text(""),
|
||||
move || format!(#fmt, #(#args),*)
|
||||
)),
|
||||
}
|
||||
},
|
||||
XHtmlNode::Comment(comment) => Self {
|
||||
@ -221,3 +248,35 @@ impl quote::ToTokens for Node {
|
||||
self.expr.to_tokens(tokens);
|
||||
}
|
||||
}
|
||||
|
||||
enum TextArg<'a> {
|
||||
/// Constant
|
||||
Cons(&'a str),
|
||||
|
||||
/// Argument
|
||||
Argument(&'a str),
|
||||
}
|
||||
|
||||
/// Splits a string into constants and arguments
|
||||
fn split_text_args(mut text: &str) -> Vec<TextArg> {
|
||||
let mut args = vec![];
|
||||
while !text.is_empty() {
|
||||
// Find the first escape
|
||||
#[expect(clippy::mixed_read_write_in_expression, reason = "False positive")]
|
||||
let Some(start) = text.find("%{") else {
|
||||
args.push(TextArg::Cons(text));
|
||||
text = &text[text.len()..];
|
||||
continue;
|
||||
};
|
||||
|
||||
let Some(end) = text[start..].find("}%") else {
|
||||
panic!("Expected `}}%`, found {:?}", &text[start..]);
|
||||
};
|
||||
|
||||
args.push(TextArg::Cons(&text[..start]));
|
||||
args.push(TextArg::Argument(&text[start..][2..end]));
|
||||
text = &text[start..][end + 2..];
|
||||
}
|
||||
|
||||
args
|
||||
}
|
||||
|
||||
1
examples/Cargo.lock
generated
1
examples/Cargo.lock
generated
@ -98,6 +98,7 @@ name = "dynatos-html-macros"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"dynatos-html-parser",
|
||||
"itertools",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.53",
|
||||
|
||||
@ -5,7 +5,6 @@
|
||||
|
||||
// Imports
|
||||
use {
|
||||
dynatos::NodeWithDynText,
|
||||
dynatos_html::{html, NodeWithChildren, NodeWithText},
|
||||
dynatos_reactive::{Signal, SignalBorrowMut, SignalGet, SignalSet},
|
||||
dynatos_util::{cloned, ev, EventTargetWithListener, JsResultContext},
|
||||
@ -57,7 +56,6 @@ fn counter() -> Element {
|
||||
html::button()
|
||||
.with_text("-")
|
||||
.with_event_listener::<ev::Click>(move |_ev| *value.borrow_mut() -= 1),
|
||||
#[cloned(value)]
|
||||
html::span().with_dyn_text(move || format!("Value: {}.", value.get())),
|
||||
html!("<span>Value: %{value.get()}%.</span>"),
|
||||
])
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user