]> git.lizzy.rs Git - rust.git/blob - src/test/run-pass/html-literals.rs
Rollup merge of #45171 - rust-lang:petrochenkov-patch-2, r=steveklabnik
[rust.git] / src / test / run-pass / html-literals.rs
1 // Copyright 2012 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 // A test of the macro system. Can we do HTML literals?
12
13 /*
14
15 This is an HTML parser written as a macro. It's all CPS, and we have
16 to carry around a bunch of state. The arguments to macros all look like this:
17
18 { tag_stack* # expr* # tokens }
19
20 The stack keeps track of where we are in the tree. The expr is a list
21 of children of the current node. The tokens are everything that's
22 left.
23
24 */
25 use HTMLFragment::{tag, text};
26
27 macro_rules! html {
28     ( $($body:tt)* ) => (
29         parse_node!( []; []; $($body)* )
30     )
31 }
32
33 macro_rules! parse_node {
34     (
35         [:$head:ident ($(:$head_nodes:expr),*)
36          $(:$tags:ident ($(:$tag_nodes:expr),*))*];
37         [$(:$nodes:expr),*];
38         </$tag:ident> $($rest:tt)*
39     ) => (
40         parse_node!(
41             [$(: $tags ($(:$tag_nodes),*))*];
42             [$(:$head_nodes,)* :tag(stringify!($head).to_string(),
43                                     vec![$($nodes),*])];
44             $($rest)*
45         )
46     );
47
48     (
49         [$(:$tags:ident ($(:$tag_nodes:expr),*) )*];
50         [$(:$nodes:expr),*];
51         <$tag:ident> $($rest:tt)*
52     ) => (
53         parse_node!(
54             [:$tag ($(:$nodes)*) $(: $tags ($(:$tag_nodes),*) )*];
55             [];
56             $($rest)*
57         )
58     );
59
60     (
61         [$(:$tags:ident ($(:$tag_nodes:expr),*) )*];
62         [$(:$nodes:expr),*];
63         . $($rest:tt)*
64     ) => (
65         parse_node!(
66             [$(: $tags ($(:$tag_nodes),*))*];
67             [$(:$nodes,)* :text(".".to_string())];
68             $($rest)*
69         )
70     );
71
72     (
73         [$(:$tags:ident ($(:$tag_nodes:expr),*) )*];
74         [$(:$nodes:expr),*];
75         $word:ident $($rest:tt)*
76     ) => (
77         parse_node!(
78             [$(: $tags ($(:$tag_nodes),*))*];
79             [$(:$nodes,)* :text(stringify!($word).to_string())];
80             $($rest)*
81         )
82     );
83
84     ( []; [:$e:expr]; ) => ( $e );
85 }
86
87 pub fn main() {
88     let _page = html! (
89         <html>
90             <head><title>This is the title.</title></head>
91             <body>
92             <p>This is some text</p>
93             </body>
94         </html>
95     );
96 }
97
98 enum HTMLFragment {
99     tag(String, Vec<HTMLFragment> ),
100     text(String),
101 }