// Copyright 2012 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // // Licensed under the Apache License, Version 2.0 or the MIT license // , at your // option. This file may not be copied, modified, or distributed // except according to those terms. // A test of the macro system. Can we do HTML literals? // ignore-test FIXME #20673 /* This is an HTML parser written as a macro. It's all CPS, and we have to carry around a bunch of state. The arguments to macros all look like this: { tag_stack* # expr* # tokens } The stack keeps track of where we are in the tree. The expr is a list of children of the current node. The tokens are everything that's left. */ use HTMLFragment::{tag, text}; macro_rules! html { ( $($body:tt)* ) => ( parse_node!( []; []; $($body)* ) ) } macro_rules! parse_node { ( [:$head:ident ($(:$head_nodes:expr),*) $(:$tags:ident ($(:$tag_nodes:expr),*))*]; [$(:$nodes:expr),*]; $($rest:tt)* ) => ( parse_node!( [$(: $tags ($(:$tag_nodes),*))*]; [$(:$head_nodes,)* :tag(stringify!($head).to_string(), vec!($($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(".".to_string())]; $($rest)* ) ); ( [$(:$tags:ident ($(:$tag_nodes:expr),*) )*]; [$(:$nodes:expr),*]; $word:ident $($rest:tt)* ) => ( parse_node!( [$(: $tags ($(:$tag_nodes),*))*]; [$(:$nodes,)* :text(stringify!($word).to_string())]; $($rest)* ) ); ( []; [:$e:expr]; ) => ( $e ); } pub fn main() { let _page = html! ( This is the title.

This is some text

); } enum HTMLFragment { tag(String, Vec ), text(String), }