Skip to content

Instantly share code, notes, and snippets.

@eholk
Created August 10, 2012 18:49
Show Gist options
  • Select an option

  • Save eholk/3316694 to your computer and use it in GitHub Desktop.

Select an option

Save eholk/3316694 to your computer and use it in GitHub Desktop.
macro_rules! html {
{ $($body:tt)* } => (
parse_node!( []; []; $($body)* )
)
}
macro_rules! parse_node {
{
[:$head:ident ($(:$head_nodes:expr),*)
$(:$tags:ident ($(:$tag_nodes:expr),*))*];
[$(:$nodes:expr),*];
</$tag:ident> $($rest:tt)*
} => (
parse_node!(
[$(: $tags ($(:$tag_nodes),*))*];
[$(:$head_nodes,)* :tag(stringify!($head), ~[$($nodes),*])];
$($rest)*
)
);
{
[$(:$tags:ident ($(:$tag_nodes:expr),*) )*];
[$(:$nodes:expr),*];
<$tag:ident> $($rest:tt)*
} => (
parse_node!(
[:$tag ($(:$nodes)*) $(: $tags ($(:$tag_nodes),*) )*];
[];
$($rest)*
)
);
{
[$(:$tags:ident ($(:$tag_nodes:expr),*) )*];
[$(:$nodes:expr),*];
. $($rest:tt)*
} => (
parse_node!(
[$(: $tags ($(:$tag_nodes),*))*];
[$(:$nodes,)* :text(~".")];
$($rest)*
)
);
{
[$(:$tags:ident ($(:$tag_nodes:expr),*) )*];
[$(:$nodes:expr),*];
$word:ident $($rest:tt)*
} => (
parse_node!(
[$(: $tags ($(:$tag_nodes),*))*];
[$(:$nodes,)* :text(stringify!($word))];
$($rest)*
)
);
{ []; [:$e:expr]; } => ( $e );
}
fn main() {
let page = html! {
<html>
<head><title>This is the title.</title></head>
<body>
<p>This is some text</p>
</body>
</html>
};
}
enum HTMLFragment {
tag(~str, ~[HTMLFragment]),
text(~str),
}
@eholk

eholk commented Aug 10, 2012

Copy link
Copy Markdown
Author

Main expands to...

fn main() {
    let page =
        tag(~"html",
            ~[tag(~"head",
                  ~[tag(~"title",
                        ~[text(~"This"), text(~"is"), text(~"the"),
                          text(~"title"), text(~".")])]),
              tag(~"body",
                  ~[tag(~"p",
                        ~[text(~"This"), text(~"is"), text(~"some"),
                          text(~"text")])])]);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment