about summary refs log tree commit diff
diff options
context:
space:
mode:
authorKeegan McAllister <kmcallister@mozilla.com>2015-02-20 12:12:25 -0800
committerKeegan McAllister <kmcallister@mozilla.com>2015-02-24 16:28:54 -0800
commit65e1e6bb942701a061f6772507141ea9f8e920e2 (patch)
treefe11d360a14916372f49721f78a58e20f85707fe
parent0bd15657d93c932611f3aee351b6521cdfa77731 (diff)
downloadrust-65e1e6bb942701a061f6772507141ea9f8e920e2.tar.gz
rust-65e1e6bb942701a061f6772507141ea9f8e920e2.zip
Add a section on recursive macros
-rw-r--r--src/doc/trpl/macros.md39
1 files changed, 39 insertions, 0 deletions
diff --git a/src/doc/trpl/macros.md b/src/doc/trpl/macros.md
index ce6fa3ce949..d0fa735b1df 100644
--- a/src/doc/trpl/macros.md
+++ b/src/doc/trpl/macros.md
@@ -357,6 +357,45 @@ fn main() {
 
 [items]: ../reference.html#items
 
+# Recursive macros
+
+A macro's expansion can include more macro invocations, including invocations
+of the very same macro being expanded.  These recursive macros are useful for
+processing tree-structured input, as illustrated by this (simplistic) HTML
+shorthand:
+
+```rust
+# #![allow(unused_must_use)]
+macro_rules! write_html {
+    ($w:expr, ) => (());
+
+    ($w:expr, $e:tt) => (write!($w, "{}", $e));
+
+    ($w:expr, $tag:ident [ $($inner:tt)* ] $($rest:tt)*) => {{
+        write!($w, "<{}>", stringify!($tag));
+        write_html!($w, $($inner)*);
+        write!($w, "</{}>", stringify!($tag));
+        write_html!($w, $($rest)*);
+    }};
+}
+
+fn main() {
+#   // FIXME(#21826)
+    use std::fmt::Write;
+    let mut out = String::new();
+
+    write_html!(&mut out,
+        html[
+            head[title["Macros guide"]]
+            body[h1["Macros are the best!"]]
+        ]);
+
+    assert_eq!(out,
+        "<html><head><title>Macros guide</title></head>\
+         <body><h1>Macros are the best!</h1></body></html>");
+}
+```
+
 # Further reading
 
 The [advanced macros chapter][] goes into more detail about macro syntax. It