#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __ftml_collect_blocks {
() => {
::std::vec::Vec::<$crate::Paragraph>::new()
};
($($tt:tt)*) => {{
let mut __blocks: ::std::vec::Vec<$crate::Paragraph> = ::std::vec::Vec::new();
__ftml_collect_blocks_inner!(__blocks, $($tt)*);
__blocks
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __ftml_collect_blocks_inner {
($vec:ident,) => {};
($vec:ident) => {};
($vec:ident, , $($rest:tt)*) => {
__ftml_collect_blocks_inner!($vec, $($rest)*);
};
($vec:ident, $tag:ident { $($inner:tt)* } $($rest:tt)*) => {{
$vec.push(__ftml_build_block!($tag { $($inner)* }));
__ftml_collect_blocks_inner!($vec, $($rest)*);
}};
($vec:ident, $unexpected:tt $($rest:tt)*) => {{
compile_error!(concat!(
"Unexpected token in FTML block context: ",
stringify!($unexpected)
));
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __ftml_build_block {
(p { $($inner:tt)* }) => {{
$crate::Paragraph::new_text().with_content(__ftml_inline_nodes!($($inner)*))
}};
(h1 { $($inner:tt)* }) => {{
$crate::Paragraph::new_header1().with_content(__ftml_inline_nodes!($($inner)*))
}};
(h2 { $($inner:tt)* }) => {{
$crate::Paragraph::new_header2().with_content(__ftml_inline_nodes!($($inner)*))
}};
(h3 { $($inner:tt)* }) => {{
$crate::Paragraph::new_header3().with_content(__ftml_inline_nodes!($($inner)*))
}};
(code { $($inner:tt)* }) => {{
let __text = __ftml_collect_code_text!($($inner)*);
$crate::Paragraph::new_code_block()
.with_content(::std::vec::Vec::from([$crate::Span::new_text(__text)]))
}};
(quote { $($inner:tt)* }) => {{
$crate::Paragraph::new_quote().with_children(__ftml_collect_blocks!($($inner)*))
}};
(ul { $($inner:tt)* }) => {{
$crate::Paragraph::new_unordered_list().with_entries(__ftml_list_entries!($($inner)*))
}};
(ol { $($inner:tt)* }) => {{
$crate::Paragraph::new_ordered_list().with_entries(__ftml_list_entries!($($inner)*))
}};
(checklist { $($inner:tt)* }) => {{
$crate::Paragraph::new_checklist()
.with_checklist_items(__ftml_checklist_entries!($($inner)*))
}};
($other:ident { $($inner:tt)* }) => {{
compile_error!(concat!("Unknown FTML element: ", stringify!($other)));
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __ftml_collect_code_text {
() => {
::std::string::String::new()
};
($($tt:tt)*) => {{
let mut __text = ::std::string::String::new();
__ftml_collect_code_text_inner!(__text, $($tt)*);
__text
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __ftml_collect_code_text_inner {
($buf:ident,) => {};
($buf:ident) => {};
($buf:ident, , $($rest:tt)*) => {
__ftml_collect_code_text_inner!($buf, $($rest)*);
};
($buf:ident, $lit:literal $($rest:tt)*) => {{
$buf.push_str($lit);
__ftml_collect_code_text_inner!($buf, $($rest)*);
}};
($buf:ident, ($($expr:tt)*) $($rest:tt)*) => {{
$buf.push_str(&::std::string::ToString::to_string(&($($expr)*)));
__ftml_collect_code_text_inner!($buf, $($rest)*);
}};
($buf:ident, $other:tt $($rest:tt)*) => {{
compile_error!(concat!(
"Unsupported token inside FTML code block: ",
stringify!($other)
));
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __ftml_inline_nodes {
() => {
::std::vec::Vec::<$crate::Span>::new()
};
($($tt:tt)*) => {{
let mut __spans: ::std::vec::Vec<$crate::Span> = ::std::vec::Vec::new();
__ftml_inline_nodes_inner!(__spans, $($tt)*);
__spans
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __ftml_inline_nodes_inner {
($vec:ident,) => {};
($vec:ident) => {};
($vec:ident, , $($rest:tt)*) => {
__ftml_inline_nodes_inner!($vec, $($rest)*);
};
($vec:ident, $tag:ident { $($inner:tt)* } $($rest:tt)*) => {{
$vec.push(__ftml_build_inline!($tag { $($inner)* }));
__ftml_inline_nodes_inner!($vec, $($rest)*);
}};
($vec:ident, $lit:literal $($rest:tt)*) => {{
$vec.push($crate::Span::new_text($lit));
__ftml_inline_nodes_inner!($vec, $($rest)*);
}};
($vec:ident, ($($expr:tt)*) $($rest:tt)*) => {{
$vec.push($crate::Span::new_text(($($expr)*)));
__ftml_inline_nodes_inner!($vec, $($rest)*);
}};
($vec:ident, $ident:ident $($rest:tt)*) => {{
$vec.push($crate::Span::new_text($ident));
__ftml_inline_nodes_inner!($vec, $($rest)*);
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __ftml_parse_link_children {
() => {
::std::vec::Vec::<$crate::Span>::new()
};
($($rest:tt)*) => {
__ftml_inline_nodes!($($rest)*)
};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __ftml_link_target {
($target:literal) => {
$target
};
(($($expr:tt)+)) => {
($($expr)+)
};
($target:ident) => {
$target
};
($($path:ident)::+) => {
$($path)::+
};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __ftml_build_inline {
(link { }) => {{
compile_error!("`link { ... }` requires at least a link target");
}};
(link { $target:tt $($rest:tt)* }) => {{
let mut __span = $crate::Span::new_styled($crate::InlineStyle::Link)
.with_link_target(__ftml_link_target!($target));
let __children = __ftml_parse_link_children!($($rest)*);
if !__children.is_empty() {
__span = __span.with_children(__children);
}
__span
}};
(b { $($inner:tt)* }) => {{
$crate::Span::new_styled($crate::InlineStyle::Bold)
.with_children(__ftml_inline_nodes!($($inner)*))
}};
(i { $($inner:tt)* }) => {{
$crate::Span::new_styled($crate::InlineStyle::Italic)
.with_children(__ftml_inline_nodes!($($inner)*))
}};
(u { $($inner:tt)* }) => {{
$crate::Span::new_styled($crate::InlineStyle::Underline)
.with_children(__ftml_inline_nodes!($($inner)*))
}};
(del { $($inner:tt)* }) => {{
$crate::Span::new_styled($crate::InlineStyle::Strike)
.with_children(__ftml_inline_nodes!($($inner)*))
}};
(mark { $($inner:tt)* }) => {{
$crate::Span::new_styled($crate::InlineStyle::Highlight)
.with_children(__ftml_inline_nodes!($($inner)*))
}};
(code { $($inner:tt)* }) => {{
$crate::Span::new_styled($crate::InlineStyle::Code)
.with_children(__ftml_inline_nodes!($($inner)*))
}};
($other:ident { $($inner:tt)* }) => {{
compile_error!(concat!("Unknown FTML inline element: ", stringify!($other)));
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __ftml_list_entries {
() => {
::std::vec::Vec::<::std::vec::Vec<$crate::Paragraph>>::new()
};
($($tt:tt)*) => {{
let mut __entries: ::std::vec::Vec<::std::vec::Vec<$crate::Paragraph>> =
::std::vec::Vec::new();
__ftml_list_entries_inner!(__entries, $($tt)*);
__entries
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __ftml_checklist_entries {
() => {
::std::vec::Vec::<$crate::ChecklistItem>::new()
};
($($tt:tt)*) => {{
let mut __entries: ::std::vec::Vec<$crate::ChecklistItem> = ::std::vec::Vec::new();
__ftml_checklist_entries_inner!(__entries, $($tt)*);
__entries
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __ftml_checklist_entries_inner {
($vec:ident,) => {};
($vec:ident) => {};
($vec:ident, , $($rest:tt)*) => {
__ftml_checklist_entries_inner!($vec, $($rest)*);
};
($vec:ident, todo { $($inner:tt)* } $($rest:tt)*) => {{
let __item = $crate::ChecklistItem::new(false)
.with_content(__ftml_inline_nodes!($($inner)*));
$vec.push(__item);
__ftml_checklist_entries_inner!($vec, $($rest)*);
}};
($vec:ident, done { $($inner:tt)* } $($rest:tt)*) => {{
let __item = $crate::ChecklistItem::new(true)
.with_content(__ftml_inline_nodes!($($inner)*));
$vec.push(__item);
__ftml_checklist_entries_inner!($vec, $($rest)*);
}};
($vec:ident, $other:ident { $($inner:tt)* } $($rest:tt)*) => {{
compile_error!(concat!(
"Expected `todo` or `done` inside checklist, found `",
stringify!($other),
"`"
));
}};
($vec:ident, $unexpected:tt $($rest:tt)*) => {{
compile_error!(concat!(
"Unexpected token inside checklist: ",
stringify!($unexpected)
));
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __ftml_list_entries_inner {
($vec:ident,) => {};
($vec:ident) => {};
($vec:ident, , $($rest:tt)*) => {
__ftml_list_entries_inner!($vec, $($rest)*);
};
($vec:ident, li { $($inner:tt)* } $($rest:tt)*) => {{
$vec.push(__ftml_collect_blocks!($($inner)*));
__ftml_list_entries_inner!($vec, $($rest)*);
}};
($vec:ident, $other:ident { $($inner:tt)* } $($rest:tt)*) => {{
compile_error!(concat!("Expected `li` inside list, found `", stringify!($other), "`"));
}};
($vec:ident, $unexpected:tt $($rest:tt)*) => {{
compile_error!(concat!(
"Unexpected token inside list: ",
stringify!($unexpected)
));
}};
}
#[macro_export(local_inner_macros)]
macro_rules! ftml {
($($tt:tt)*) => {{
let __paragraphs = __ftml_collect_blocks!($($tt)*);
$crate::Document::new().with_paragraphs(__paragraphs)
}};
}