yew_lmth/
lib.rs

1//! # Yew Lmth
2//!
3//! A macro crate for writing HTML-like syntax, which will be translated into a corresponding `yew::prelude::html!()` macro.
4//!
5//! ## Syntax
6//!
7//! ### Tags
8//!
9//! | `lmth!` syntax        | meaning                         | `html!` syntax             |
10//! | --------------------- | ------------------------------- | -------------------------- |
11//! | `! { ... }`           | Yew's fragment                  | `<> ... </>`               |
12//! | `@{expr} { ... }`     | Dynamicly named tag             | `<@{expr}> ... </@>`       |
13//! | `tag (attrs) { ... }` | Tag with attributes and content | `<tag attrs>{ ... }</tag>` |
14//! | `tag (attrs)`         | Void tag with attributes        | `<tag attrs />`            |
15//! | `tag { ... }`         | Tag with content                | `<tag>{ ... }</tag>`       |
16//! | `tag`                 | Void tag with no attribute      | `<tag />`                  |
17//!
18//! ### Attributes
19//!
20//! Attributes are separated by commas: `tag (attr: val, attr: val, ...) { ... }`
21//!
22//! | `lmth!` syntax  | meaning                                | `html!` syntax |
23//! | --------------- | -------------------------------------- | -------------- |
24//! | `attr: expr`    | Attribute with expression as value     | `attr={expr}`  |
25//! | `attr: {code}`  | Attribute with code block as value     | `attr={code}`  |
26//! | `attr="litstr"` | Attribute with literal string as value | `attr="litstr"`|
27//! | `attr`          | Shorthand for `{attr}` in yew          | `{attr}`       |
28//!
29//! ### Content
30//!
31//! | `lmth!` syntax  | meaning                   | `html!` syntax    |
32//! | --------------- | ------------------------- | ----------------- |
33//! | `{code}`        | Code as content           | `{code}`          |
34//! | `"litstr"`      | Literal string as content | `"litstr"`        |
35//! | `tag ...`       | Tag                       | corresponding tag |
36//!
37//! ### Conditional rendering
38//!
39//! | `lmth!` syntax          | meaning                   | `html!` syntax          |
40//! | ----------------------- | ------------------------- | ----------------------- |
41//! | `if {code} { ... }`     | Conditional rendering     | `if {code} { ... }`     |
42//! | `if let {code} { ... }` | Conditional rendering     | `if let {code} { ... }` |
43
44use lmth::{ir::LmthNode, lmth_act};
45use proc_macro as pm;
46use quote::quote;
47use syn::parse_macro_input;
48
49//~ Sub-modules
50mod lmth;
51#[cfg(test)]
52mod tests;
53
54/// Macro for writing HTML-like syntax. It works by translating it
55/// into a corresponding `yew::prelude::html!()` macro.
56///
57/// # Example
58///
59/// ```rust
60/// use yew_lmth::lmth;
61///
62/// lmth! {
63///     div (class="container") {
64///        h1 { "Hello, world!" }
65///        button (onclick: handle_click()) { "Click me!" }
66///     }
67/// }
68///
69/// // expands to:
70/// // yew::prelude::html! {
71/// //     <div class="container">
72/// //         <h1>{ "Hello, world!" }</h1>
73/// //         <button onclick={handle_click()}>{ "Click me!" }</button>
74/// //     </div>
75/// // }
76/// ```
77#[proc_macro]
78pub fn lmth(input: pm::TokenStream) -> pm::TokenStream {
79    if input.is_empty() {
80        return quote! {
81            yew::prelude::html! {}
82        }
83        .into();
84    }
85
86    let node = parse_macro_input!(input as LmthNode);
87
88    lmth_act(node).into()
89}