Modified macros to be able to generate with multiple children (added divisions)
This commit is contained in:
62
src/lib.rs
62
src/lib.rs
@@ -54,25 +54,54 @@ impl Parse for Argument {
|
||||
}
|
||||
|
||||
struct BaseElement {
|
||||
value: Expr,
|
||||
params: Punctuated<Property, Token![,]>,
|
||||
values: Vec<Expr>,
|
||||
params: Vec<Property>,
|
||||
}
|
||||
|
||||
impl Parse for BaseElement {
|
||||
fn parse(input: ParseStream) -> Result<Self> {
|
||||
let value: Expr = input.parse()?;
|
||||
let _ = input.parse::<Token![,]>();
|
||||
let params: Punctuated<Property, Token![,]> = Punctuated::parse_terminated(input)?;
|
||||
Ok(BaseElement { value, params })
|
||||
let mut values = Vec::new();
|
||||
let mut params = Vec::new();
|
||||
while !input.is_empty() {
|
||||
if input.peek(Ident) && input.peek2(Token![=]) {
|
||||
let property: Property = input.parse()?;
|
||||
params.push(property);
|
||||
} else {
|
||||
let value: Expr = input.parse()?;
|
||||
values.push(value);
|
||||
}
|
||||
if input.peek(Token![,]) {
|
||||
input.parse::<Token![,]>()?;
|
||||
}
|
||||
}
|
||||
Ok(BaseElement { values, params })
|
||||
}
|
||||
}
|
||||
|
||||
fn heading(level: &str, item: TokenStream) -> TokenStream {
|
||||
let BaseElement { value, params } = parse_macro_input!(item as BaseElement);
|
||||
#[proc_macro]
|
||||
pub fn paragraph(input: TokenStream) -> TokenStream {
|
||||
base("p", input)
|
||||
}
|
||||
|
||||
#[proc_macro]
|
||||
pub fn division(input: TokenStream) -> TokenStream {
|
||||
base("div", input)
|
||||
}
|
||||
|
||||
fn base(elem: &str, item: TokenStream) -> TokenStream {
|
||||
let BaseElement { values, params } = parse_macro_input!(item as BaseElement);
|
||||
let values = values.iter();
|
||||
let formated_values = if values.len() > 1 {
|
||||
let mut s = "\n".to_string();
|
||||
s.push_str("{}\n".repeat(values.len()).as_str());
|
||||
s
|
||||
} else {
|
||||
"{}".to_string()
|
||||
};
|
||||
|
||||
let expanded = match params.is_empty() {
|
||||
false => {
|
||||
let mut values = Vec::new();
|
||||
let mut options_values = Vec::new();
|
||||
|
||||
let formated_names = params
|
||||
.iter()
|
||||
@@ -80,18 +109,23 @@ fn heading(level: &str, item: TokenStream) -> TokenStream {
|
||||
.collect::<Vec<String>>()
|
||||
.join(" ");
|
||||
|
||||
let format_string = format!("<h{} {formated_names}>{{}}</h{}>", level, level);
|
||||
let format_string =
|
||||
format!("<{} {formated_names}>{}</{}>", elem, formated_values, elem);
|
||||
|
||||
for property in params {
|
||||
values.push(property.value);
|
||||
options_values.push(property.value);
|
||||
}
|
||||
|
||||
quote!(format!(#format_string, #(#values), *, #value))
|
||||
quote!(format!(#format_string, #(#options_values), *, #(#values), *))
|
||||
}
|
||||
true => {
|
||||
let format_string = format!("<h{}>{{}}</h{}>", level, level);
|
||||
quote!(format!(#format_string, #value))
|
||||
let format_string = format!("<{}>{}</{}>", elem, formated_values, elem);
|
||||
quote!(format!(#format_string, #(#values), *))
|
||||
}
|
||||
};
|
||||
TokenStream::from(expanded)
|
||||
}
|
||||
|
||||
fn heading(level: &str, item: TokenStream) -> TokenStream {
|
||||
base(format!("h{level}").as_str(), item)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user