You can define multiple templates in a `define!` block.

```rust
markup::define! {
    First {
      "First!"
    }
    Second {
      "Second!"
    }
}
```

```rust
println!("{}", First);
println!("{}", Second.to_string());
```

```html
First!
Second!
```

A template can have bare literal strings and arbitrary expressions in braces.

+ Hello {
    "Hello,"
    " "
    "world!\n"
    {1 + 2}
    {'π'}
    {format!("{}{}", 3, 4)}
    {if true { Some(5) } else { None }}
    {if false { Some(6) } else { None }}
}
- Hello {}

Elements can either have children inside `{}` or be a void tag, ending with `;`.

+ Hello {
    div {}
    br;
}
- Hello {}

An id and multiple classes can be applied to an element using CSS like selectors.
The value after `#` and `.` can be either an identifier, a literal string, or an expression inside braces.

+ Hello {
    .foo {
        .bar {}
    }
    button#go.button."button-blue" {}
    button#"go-back".{1 + 2}.{2 + 3} {}
}
- Hello {}

Attributes can either be normal or boolean (ends with ?).
The name can be an identifier, a literal string, or an expression inside braces.
Boolean attributes are printed without value if true and omitted if false.
The value can be an Option, where None values are omitted and Some are unwrapped.

+ Hello {
    div[
        a = 1,
        b = "2",
        c? = true,
        d? = false,
        "e-f" = 3,
        {"g".to_string() + "-h"} = 4,
        i = None::<i32>,
        j = Some(5)
    ] {}
    "\n"
    br[k = 6];
    "\n"
    input[type = "text"];
}
- Hello {}

An element can have zero or more children inside braces.

+ Hello {
    .foo[a = 1] {
        "One"
        {0 + 1}
    }
    div {
        "Two"
        {1 + 1}
    }
}
- Hello {}

Automatic HTML escaping can be disabled using the `markup::raw` function.
This function accepts any type implementing std::fmt::Display.

+ Hello {
    "<&\">"
    {markup::raw("<span></span>")}
}
- Hello {}

A template can accept simple arguments as well as generic arguments with where clauses.

+ Hello(foo: u32, bar: u32, string: String) {
    div {
        {foo + bar}
        {string}
    }
}
- Hello { foo: 1, bar: 2, string: String::from("hello") }

+ Hello<'a, T: std::fmt::Debug, U>(arg: T, arg2: U, str: &'a str) where U: std::fmt::Display {
    div {
        {format!("{:?}", arg)}
        {format!("{}", arg2)}
        {str}
    }
}
- Hello { arg: (1, 2), arg2: "arg2", str: "str" }

Other templates can be embedded by simply putting them in braces.

+ Add(a: u32, b: u32) {
    span { {a + b} }
}
Hello {
    {Add { a: 1, b: 2 }}
    {Add { a: 3, b: 4 }}
}
- Hello {}

@if

+ Classify(value: i32) {
    {value}
    " is "
    @if *value < 0 {
        "negative"
    } else if *value == 0 {
        "zero"
    } else {
        "positive"
    }
    ".\n"
}
Main {
    {Classify { value: -42 }}
    " "
    {Classify { value: 0 }}
    " "
    {Classify { value: 42 }}
}
- Main {}

@if let

+ Classify(value: Option<i32>) {
    @if let Some(0) = *(value) {
        "Some(ZERO)"
    } else if let Some(value) = *(value) {
        "Some(" {value} ")"
    } else {
        "None"
    }
    "\n"
}
Main {
    {Classify { value: None }}
    {Classify { value: Some(0) }}
    {Classify { value: Some(1) }}
}
- Main {}

@for

+ Main {
    @for i in 1..5 {
        {i} " * 2 = " {i * 2} ";\n"
    }
}
- Main {}

Curly braces also accept single statements and items and outputs it as-is in the generated code.

+ Main {
    {let x = 1;}
    {fn add1(x: i32) -> i32 {
        x + 1
    }}
    {add1(x)}
}
- Main {}
