Rename Renderer to Builder
This commit is contained in:
parent
a902c97091
commit
5cd51481c9
3 changed files with 84 additions and 84 deletions
|
@ -3,16 +3,16 @@ use proc_macro::quote;
|
||||||
|
|
||||||
use maud_htmlescape::Escaper;
|
use maud_htmlescape::Escaper;
|
||||||
|
|
||||||
pub struct Renderer {
|
pub struct Builder {
|
||||||
output_ident: TokenTree,
|
output_ident: TokenTree,
|
||||||
stmts: Vec<TokenStream>,
|
stmts: Vec<TokenStream>,
|
||||||
tail: String,
|
tail: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Renderer {
|
impl Builder {
|
||||||
/// Creates a new `Renderer`.
|
/// Creates a new `Builder`.
|
||||||
pub fn new(output_ident: TokenTree) -> Renderer {
|
pub fn new(output_ident: TokenTree) -> Builder {
|
||||||
Renderer {
|
Builder {
|
||||||
output_ident,
|
output_ident,
|
||||||
stmts: Vec::new(),
|
stmts: Vec::new(),
|
||||||
tail: String::new(),
|
tail: String::new(),
|
||||||
|
@ -32,9 +32,9 @@ impl Renderer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reifies the `Renderer` into a raw list of statements.
|
/// Reifies the `Builder` into a raw list of statements.
|
||||||
pub fn build(mut self) -> TokenStream {
|
pub fn build(mut self) -> TokenStream {
|
||||||
let Renderer { stmts, .. } = { self.flush(); self };
|
let Builder { stmts, .. } = { self.flush(); self };
|
||||||
stmts.into_iter().collect()
|
stmts.into_iter().collect()
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ extern crate maud_htmlescape;
|
||||||
extern crate proc_macro;
|
extern crate proc_macro;
|
||||||
|
|
||||||
mod parse;
|
mod parse;
|
||||||
mod render;
|
mod build;
|
||||||
|
|
||||||
use proc_macro::{Literal, Span, Term, TokenNode, TokenStream, TokenTree};
|
use proc_macro::{Literal, Span, Term, TokenNode, TokenStream, TokenTree};
|
||||||
use proc_macro::quote;
|
use proc_macro::quote;
|
||||||
|
|
|
@ -13,14 +13,14 @@ use std::mem;
|
||||||
|
|
||||||
use literalext::LiteralExt;
|
use literalext::LiteralExt;
|
||||||
|
|
||||||
use super::render::Renderer;
|
use super::build::Builder;
|
||||||
use super::ParseResult;
|
use super::ParseResult;
|
||||||
|
|
||||||
pub fn parse(input: TokenStream, output_ident: TokenTree) -> ParseResult<TokenStream> {
|
pub fn parse(input: TokenStream, output_ident: TokenTree) -> ParseResult<TokenStream> {
|
||||||
let mut parse = Parser::new(input, output_ident);
|
let mut parser = Parser::new(input, output_ident);
|
||||||
let mut render = parse.builder();
|
let mut builder = parser.builder();
|
||||||
parse.markups(&mut render)?;
|
parser.markups(&mut builder)?;
|
||||||
Ok(render.build())
|
Ok(builder.build())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -56,8 +56,8 @@ impl Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn builder(&self) -> Renderer {
|
fn builder(&self) -> Builder {
|
||||||
Renderer::new(self.output_ident.clone())
|
Builder::new(self.output_ident.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the next token in the stream without consuming it.
|
/// Returns the next token in the stream without consuming it.
|
||||||
|
@ -93,18 +93,18 @@ impl Parser {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses and renders multiple blocks of markup.
|
/// Parses and renders multiple blocks of markup.
|
||||||
fn markups(&mut self, render: &mut Renderer) -> ParseResult<()> {
|
fn markups(&mut self, builder: &mut Builder) -> ParseResult<()> {
|
||||||
loop {
|
loop {
|
||||||
match self.peek() {
|
match self.peek() {
|
||||||
None => return Ok(()),
|
None => return Ok(()),
|
||||||
Some(TokenTree { kind: TokenNode::Op(';', _), .. }) => self.advance(),
|
Some(TokenTree { kind: TokenNode::Op(';', _), .. }) => self.advance(),
|
||||||
_ => self.markup(render)?,
|
_ => self.markup(builder)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses and renders a single block of markup.
|
/// Parses and renders a single block of markup.
|
||||||
fn markup(&mut self, render: &mut Renderer) -> ParseResult<()> {
|
fn markup(&mut self, builder: &mut Builder) -> ParseResult<()> {
|
||||||
let token = match self.peek() {
|
let token = match self.peek() {
|
||||||
Some(token) => token,
|
Some(token) => token,
|
||||||
None => return self.error("unexpected end of input"),
|
None => return self.error("unexpected end of input"),
|
||||||
|
@ -113,7 +113,7 @@ impl Parser {
|
||||||
// Literal
|
// Literal
|
||||||
TokenTree { kind: TokenNode::Literal(lit), .. } => {
|
TokenTree { kind: TokenNode::Literal(lit), .. } => {
|
||||||
self.advance();
|
self.advance();
|
||||||
self.literal(lit, render)?;
|
self.literal(lit, builder)?;
|
||||||
},
|
},
|
||||||
// Special form
|
// Special form
|
||||||
TokenTree { kind: TokenNode::Op('@', _), .. } => {
|
TokenTree { kind: TokenNode::Op('@', _), .. } => {
|
||||||
|
@ -121,13 +121,13 @@ impl Parser {
|
||||||
match self.next() {
|
match self.next() {
|
||||||
Some(TokenTree { kind: TokenNode::Term(term), span }) => {
|
Some(TokenTree { kind: TokenNode::Term(term), span }) => {
|
||||||
let keyword = TokenTree { kind: TokenNode::Term(term), span };
|
let keyword = TokenTree { kind: TokenNode::Term(term), span };
|
||||||
render.push(keyword);
|
builder.push(keyword);
|
||||||
match term.as_str() {
|
match term.as_str() {
|
||||||
"if" => self.if_expr(render)?,
|
"if" => self.if_expr(builder)?,
|
||||||
"while" => self.while_expr(render)?,
|
"while" => self.while_expr(builder)?,
|
||||||
"for" => self.for_expr(render)?,
|
"for" => self.for_expr(builder)?,
|
||||||
"match" => self.match_expr(render)?,
|
"match" => self.match_expr(builder)?,
|
||||||
"let" => self.let_expr(render)?,
|
"let" => self.let_expr(builder)?,
|
||||||
other => return self.error(format!("unknown keyword `@{}`", other)),
|
other => return self.error(format!("unknown keyword `@{}`", other)),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -137,18 +137,18 @@ impl Parser {
|
||||||
// Element
|
// Element
|
||||||
TokenTree { kind: TokenNode::Term(_), .. } => {
|
TokenTree { kind: TokenNode::Term(_), .. } => {
|
||||||
let name = self.namespaced_name()?;
|
let name = self.namespaced_name()?;
|
||||||
self.element(&name, render)?;
|
self.element(&name, builder)?;
|
||||||
},
|
},
|
||||||
// Splice
|
// Splice
|
||||||
TokenTree { kind: TokenNode::Group(Delimiter::Parenthesis, expr), .. } => {
|
TokenTree { kind: TokenNode::Group(Delimiter::Parenthesis, expr), .. } => {
|
||||||
self.advance();
|
self.advance();
|
||||||
render.splice(expr);
|
builder.splice(expr);
|
||||||
}
|
}
|
||||||
// Block
|
// Block
|
||||||
TokenTree { kind: TokenNode::Group(Delimiter::Brace, block), span } => {
|
TokenTree { kind: TokenNode::Group(Delimiter::Brace, block), span } => {
|
||||||
self.advance();
|
self.advance();
|
||||||
let block = self.block(block, span)?;
|
let block = self.block(block, span)?;
|
||||||
render.push(block);
|
builder.push(block);
|
||||||
},
|
},
|
||||||
// ???
|
// ???
|
||||||
_ => return self.error("invalid syntax"),
|
_ => return self.error("invalid syntax"),
|
||||||
|
@ -157,9 +157,9 @@ impl Parser {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses and renders a literal string.
|
/// Parses and renders a literal string.
|
||||||
fn literal(&mut self, lit: Literal, render: &mut Renderer) -> ParseResult<()> {
|
fn literal(&mut self, lit: Literal, builder: &mut Builder) -> ParseResult<()> {
|
||||||
if let Some(s) = lit.parse_string() {
|
if let Some(s) = lit.parse_string() {
|
||||||
render.string(&s);
|
builder.string(&s);
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
self.error("expected string")
|
self.error("expected string")
|
||||||
|
@ -169,25 +169,25 @@ impl Parser {
|
||||||
/// Parses and renders an `@if` expression.
|
/// Parses and renders an `@if` expression.
|
||||||
///
|
///
|
||||||
/// The leading `@if` should already be consumed.
|
/// The leading `@if` should already be consumed.
|
||||||
fn if_expr(&mut self, render: &mut Renderer) -> ParseResult<()> {
|
fn if_expr(&mut self, builder: &mut Builder) -> ParseResult<()> {
|
||||||
loop {
|
loop {
|
||||||
match self.next() {
|
match self.next() {
|
||||||
Some(TokenTree { kind: TokenNode::Group(Delimiter::Brace, block), span }) => {
|
Some(TokenTree { kind: TokenNode::Group(Delimiter::Brace, block), span }) => {
|
||||||
let block = self.block(block, span)?;
|
let block = self.block(block, span)?;
|
||||||
render.push(block);
|
builder.push(block);
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
Some(token) => render.push(token),
|
Some(token) => builder.push(token),
|
||||||
None => return self.error("unexpected end of @if expression"),
|
None => return self.error("unexpected end of @if expression"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.else_if_expr(render)
|
self.else_if_expr(builder)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses and renders an optional `@else if` or `@else`.
|
/// Parses and renders an optional `@else if` or `@else`.
|
||||||
///
|
///
|
||||||
/// The leading `@else if` or `@else` should *not* already be consumed.
|
/// The leading `@else if` or `@else` should *not* already be consumed.
|
||||||
fn else_if_expr(&mut self, render: &mut Renderer) -> ParseResult<()> {
|
fn else_if_expr(&mut self, builder: &mut Builder) -> ParseResult<()> {
|
||||||
match self.peek2() {
|
match self.peek2() {
|
||||||
// Try to match an `@else` after this
|
// Try to match an `@else` after this
|
||||||
Some((
|
Some((
|
||||||
|
@ -196,27 +196,27 @@ impl Parser {
|
||||||
)) if else_keyword.as_str() == "else" => {
|
)) if else_keyword.as_str() == "else" => {
|
||||||
self.advance2();
|
self.advance2();
|
||||||
let else_keyword = TokenTree { kind: TokenNode::Term(else_keyword), span };
|
let else_keyword = TokenTree { kind: TokenNode::Term(else_keyword), span };
|
||||||
render.push(else_keyword);
|
builder.push(else_keyword);
|
||||||
match self.peek() {
|
match self.peek() {
|
||||||
// `@else if`
|
// `@else if`
|
||||||
Some(TokenTree { kind: TokenNode::Term(if_keyword), span })
|
Some(TokenTree { kind: TokenNode::Term(if_keyword), span })
|
||||||
if if_keyword.as_str() == "if" => {
|
if if_keyword.as_str() == "if" => {
|
||||||
self.advance();
|
self.advance();
|
||||||
let if_keyword = TokenTree { kind: TokenNode::Term(if_keyword), span };
|
let if_keyword = TokenTree { kind: TokenNode::Term(if_keyword), span };
|
||||||
render.push(if_keyword);
|
builder.push(if_keyword);
|
||||||
self.if_expr(render)?;
|
self.if_expr(builder)?;
|
||||||
},
|
},
|
||||||
// Just an `@else`
|
// Just an `@else`
|
||||||
_ => {
|
_ => {
|
||||||
if let Some(TokenTree { kind: TokenNode::Group(Delimiter::Brace, block), span }) = self.next() {
|
if let Some(TokenTree { kind: TokenNode::Group(Delimiter::Brace, block), span }) = self.next() {
|
||||||
let block = self.block(block, span)?;
|
let block = self.block(block, span)?;
|
||||||
render.push(block);
|
builder.push(block);
|
||||||
} else {
|
} else {
|
||||||
return self.error("expected body for @else");
|
return self.error("expected body for @else");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
self.else_if_expr(render)
|
self.else_if_expr(builder)
|
||||||
},
|
},
|
||||||
// We didn't find an `@else`; stop
|
// We didn't find an `@else`; stop
|
||||||
_ => Ok(()),
|
_ => Ok(()),
|
||||||
|
@ -226,15 +226,15 @@ impl Parser {
|
||||||
/// Parses and renders an `@while` expression.
|
/// Parses and renders an `@while` expression.
|
||||||
///
|
///
|
||||||
/// The leading `@while` should already be consumed.
|
/// The leading `@while` should already be consumed.
|
||||||
fn while_expr(&mut self, render: &mut Renderer) -> ParseResult<()> {
|
fn while_expr(&mut self, builder: &mut Builder) -> ParseResult<()> {
|
||||||
loop {
|
loop {
|
||||||
match self.next() {
|
match self.next() {
|
||||||
Some(TokenTree { kind: TokenNode::Group(Delimiter::Brace, block), span }) => {
|
Some(TokenTree { kind: TokenNode::Group(Delimiter::Brace, block), span }) => {
|
||||||
let block = self.block(block, span)?;
|
let block = self.block(block, span)?;
|
||||||
render.push(block);
|
builder.push(block);
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
Some(token) => render.push(token),
|
Some(token) => builder.push(token),
|
||||||
None => return self.error("unexpected end of @while expression"),
|
None => return self.error("unexpected end of @while expression"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -244,14 +244,14 @@ impl Parser {
|
||||||
/// Parses and renders a `@for` expression.
|
/// Parses and renders a `@for` expression.
|
||||||
///
|
///
|
||||||
/// The leading `@for` should already be consumed.
|
/// The leading `@for` should already be consumed.
|
||||||
fn for_expr(&mut self, render: &mut Renderer) -> ParseResult<()> {
|
fn for_expr(&mut self, builder: &mut Builder) -> ParseResult<()> {
|
||||||
loop {
|
loop {
|
||||||
match self.next() {
|
match self.next() {
|
||||||
Some(TokenTree { kind: TokenNode::Term(in_keyword), span }) if in_keyword.as_str() == "in" => {
|
Some(TokenTree { kind: TokenNode::Term(in_keyword), span }) if in_keyword.as_str() == "in" => {
|
||||||
render.push(TokenTree { kind: TokenNode::Term(in_keyword), span });
|
builder.push(TokenTree { kind: TokenNode::Term(in_keyword), span });
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
Some(token) => render.push(token),
|
Some(token) => builder.push(token),
|
||||||
None => return self.error("unexpected end of @for expression"),
|
None => return self.error("unexpected end of @for expression"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -259,10 +259,10 @@ impl Parser {
|
||||||
match self.next() {
|
match self.next() {
|
||||||
Some(TokenTree { kind: TokenNode::Group(Delimiter::Brace, block), span }) => {
|
Some(TokenTree { kind: TokenNode::Group(Delimiter::Brace, block), span }) => {
|
||||||
let block = self.block(block, span)?;
|
let block = self.block(block, span)?;
|
||||||
render.push(block);
|
builder.push(block);
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
Some(token) => render.push(token),
|
Some(token) => builder.push(token),
|
||||||
None => return self.error("unexpected end of @for expression"),
|
None => return self.error("unexpected end of @for expression"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -272,18 +272,18 @@ impl Parser {
|
||||||
/// Parses and renders a `@match` expression.
|
/// Parses and renders a `@match` expression.
|
||||||
///
|
///
|
||||||
/// The leading `@match` should already be consumed.
|
/// The leading `@match` should already be consumed.
|
||||||
fn match_expr(&mut self, render: &mut Renderer) -> ParseResult<()> {
|
fn match_expr(&mut self, builder: &mut Builder) -> ParseResult<()> {
|
||||||
loop {
|
loop {
|
||||||
match self.next() {
|
match self.next() {
|
||||||
Some(TokenTree { kind: TokenNode::Group(Delimiter::Brace, body), span }) => {
|
Some(TokenTree { kind: TokenNode::Group(Delimiter::Brace, body), span }) => {
|
||||||
let body = self.with_input(body).match_arms()?;
|
let body = self.with_input(body).match_arms()?;
|
||||||
render.push(TokenTree {
|
builder.push(TokenTree {
|
||||||
kind: TokenNode::Group(Delimiter::Brace, body),
|
kind: TokenNode::Group(Delimiter::Brace, body),
|
||||||
span,
|
span,
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
Some(token) => render.push(token),
|
Some(token) => builder.push(token),
|
||||||
None => return self.error("unexpected end of @match expression"),
|
None => return self.error("unexpected end of @match expression"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -355,24 +355,24 @@ impl Parser {
|
||||||
/// Parses and renders a `@let` expression.
|
/// Parses and renders a `@let` expression.
|
||||||
///
|
///
|
||||||
/// The leading `@let` should already be consumed.
|
/// The leading `@let` should already be consumed.
|
||||||
fn let_expr(&mut self, render: &mut Renderer) -> ParseResult<()> {
|
fn let_expr(&mut self, builder: &mut Builder) -> ParseResult<()> {
|
||||||
loop {
|
loop {
|
||||||
match self.next() {
|
match self.next() {
|
||||||
Some(token @ TokenTree { kind: TokenNode::Op('=', _), .. }) => {
|
Some(token @ TokenTree { kind: TokenNode::Op('=', _), .. }) => {
|
||||||
render.push(token);
|
builder.push(token);
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
Some(token) => render.push(token),
|
Some(token) => builder.push(token),
|
||||||
None => return self.error("unexpected end of @let expression"),
|
None => return self.error("unexpected end of @let expression"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
loop {
|
loop {
|
||||||
match self.next() {
|
match self.next() {
|
||||||
Some(token @ TokenTree { kind: TokenNode::Op(';', _), .. }) => {
|
Some(token @ TokenTree { kind: TokenNode::Op(';', _), .. }) => {
|
||||||
render.push(token);
|
builder.push(token);
|
||||||
break;
|
break;
|
||||||
},
|
},
|
||||||
Some(token) => render.push(token),
|
Some(token) => builder.push(token),
|
||||||
None => return self.error("unexpected end of @let expression"),
|
None => return self.error("unexpected end of @let expression"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -382,13 +382,13 @@ impl Parser {
|
||||||
/// Parses and renders an element node.
|
/// Parses and renders an element node.
|
||||||
///
|
///
|
||||||
/// The element name should already be consumed.
|
/// The element name should already be consumed.
|
||||||
fn element(&mut self, name: &str, render: &mut Renderer) -> ParseResult<()> {
|
fn element(&mut self, name: &str, builder: &mut Builder) -> ParseResult<()> {
|
||||||
if self.in_attr {
|
if self.in_attr {
|
||||||
return self.error("unexpected element, you silly bumpkin");
|
return self.error("unexpected element, you silly bumpkin");
|
||||||
}
|
}
|
||||||
render.element_open_start(name);
|
builder.element_open_start(name);
|
||||||
self.attrs(render)?;
|
self.attrs(builder)?;
|
||||||
render.element_open_end();
|
builder.element_open_end();
|
||||||
match self.peek() {
|
match self.peek() {
|
||||||
Some(TokenTree { kind: TokenNode::Op(';', _), .. }) |
|
Some(TokenTree { kind: TokenNode::Op(';', _), .. }) |
|
||||||
Some(TokenTree { kind: TokenNode::Op('/', _), .. }) => {
|
Some(TokenTree { kind: TokenNode::Op('/', _), .. }) => {
|
||||||
|
@ -396,15 +396,15 @@ impl Parser {
|
||||||
self.advance();
|
self.advance();
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
self.markup(render)?;
|
self.markup(builder)?;
|
||||||
render.element_close(name);
|
builder.element_close(name);
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Parses and renders the attributes of an element.
|
/// Parses and renders the attributes of an element.
|
||||||
fn attrs(&mut self, render: &mut Renderer) -> ParseResult<()> {
|
fn attrs(&mut self, builder: &mut Builder) -> ParseResult<()> {
|
||||||
let mut classes_static = Vec::new();
|
let mut classes_static = Vec::new();
|
||||||
let mut classes_toggled = Vec::new();
|
let mut classes_toggled = Vec::new();
|
||||||
let mut ids = Vec::new();
|
let mut ids = Vec::new();
|
||||||
|
@ -416,14 +416,14 @@ impl Parser {
|
||||||
// Non-empty attribute
|
// Non-empty attribute
|
||||||
(Ok(name), Some(TokenTree { kind: TokenNode::Op('=', _), .. })) => {
|
(Ok(name), Some(TokenTree { kind: TokenNode::Op('=', _), .. })) => {
|
||||||
self.commit(attempt);
|
self.commit(attempt);
|
||||||
render.attribute_start(&name);
|
builder.attribute_start(&name);
|
||||||
{
|
{
|
||||||
// Parse a value under an attribute context
|
// Parse a value under an attribute context
|
||||||
let in_attr = mem::replace(&mut self.in_attr, true);
|
let in_attr = mem::replace(&mut self.in_attr, true);
|
||||||
self.markup(render)?;
|
self.markup(builder)?;
|
||||||
self.in_attr = in_attr;
|
self.in_attr = in_attr;
|
||||||
}
|
}
|
||||||
render.attribute_end();
|
builder.attribute_end();
|
||||||
},
|
},
|
||||||
// Empty attribute
|
// Empty attribute
|
||||||
(Ok(name), Some(TokenTree { kind: TokenNode::Op('?', _), .. })) => {
|
(Ok(name), Some(TokenTree { kind: TokenNode::Op('?', _), .. })) => {
|
||||||
|
@ -431,14 +431,14 @@ impl Parser {
|
||||||
if let Some((cond, cond_span)) = self.attr_toggler() {
|
if let Some((cond, cond_span)) = self.attr_toggler() {
|
||||||
// Toggle the attribute based on a boolean expression
|
// Toggle the attribute based on a boolean expression
|
||||||
let body = {
|
let body = {
|
||||||
let mut render = self.builder();
|
let mut builder = self.builder();
|
||||||
render.attribute_empty(&name);
|
builder.attribute_empty(&name);
|
||||||
render.build()
|
builder.build()
|
||||||
};
|
};
|
||||||
render.emit_if(cond, cond_span, body);
|
builder.emit_if(cond, cond_span, body);
|
||||||
} else {
|
} else {
|
||||||
// Write the attribute unconditionally
|
// Write the attribute unconditionally
|
||||||
render.attribute_empty(&name);
|
builder.attribute_empty(&name);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
// Class shorthand
|
// Class shorthand
|
||||||
|
@ -463,8 +463,8 @@ impl Parser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if !classes_static.is_empty() || !classes_toggled.is_empty() {
|
if !classes_static.is_empty() || !classes_toggled.is_empty() {
|
||||||
render.attribute_start("class");
|
builder.attribute_start("class");
|
||||||
render.string(&classes_static.join(" "));
|
builder.string(&classes_static.join(" "));
|
||||||
for (i, (cond, cond_span, mut class_name)) in classes_toggled.into_iter().enumerate() {
|
for (i, (cond, cond_span, mut class_name)) in classes_toggled.into_iter().enumerate() {
|
||||||
// If a class comes first in the list, then it shouldn't be
|
// If a class comes first in the list, then it shouldn't be
|
||||||
// prefixed by a space
|
// prefixed by a space
|
||||||
|
@ -472,18 +472,18 @@ impl Parser {
|
||||||
class_name = format!(" {}", class_name);
|
class_name = format!(" {}", class_name);
|
||||||
}
|
}
|
||||||
let body = {
|
let body = {
|
||||||
let mut render = self.builder();
|
let mut builder = self.builder();
|
||||||
render.string(&class_name);
|
builder.string(&class_name);
|
||||||
render.build()
|
builder.build()
|
||||||
};
|
};
|
||||||
render.emit_if(cond, cond_span, body);
|
builder.emit_if(cond, cond_span, body);
|
||||||
}
|
}
|
||||||
render.attribute_end();
|
builder.attribute_end();
|
||||||
}
|
}
|
||||||
if !ids.is_empty() {
|
if !ids.is_empty() {
|
||||||
render.attribute_start("id");
|
builder.attribute_start("id");
|
||||||
render.string(&ids.join(" "));
|
builder.string(&ids.join(" "));
|
||||||
render.attribute_end();
|
builder.attribute_end();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -543,10 +543,10 @@ impl Parser {
|
||||||
/// Parses the given token stream as a Maud expression, returning a block of
|
/// Parses the given token stream as a Maud expression, returning a block of
|
||||||
/// Rust code.
|
/// Rust code.
|
||||||
fn block(&mut self, body: TokenStream, span: Span) -> ParseResult<TokenTree> {
|
fn block(&mut self, body: TokenStream, span: Span) -> ParseResult<TokenTree> {
|
||||||
let mut render = self.builder();
|
let mut builder = self.builder();
|
||||||
self.with_input(body).markups(&mut render)?;
|
self.with_input(body).markups(&mut builder)?;
|
||||||
Ok(TokenTree {
|
Ok(TokenTree {
|
||||||
kind: TokenNode::Group(Delimiter::Brace, render.build()),
|
kind: TokenNode::Group(Delimiter::Brace, builder.build()),
|
||||||
span,
|
span,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue