#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __tdoc_collect_blocks {
($mode:ident;) => {
::std::vec::Vec::<$crate::Paragraph>::new()
};
($mode:ident; $($tt:tt)*) => {{
let mut __blocks: ::std::vec::Vec<$crate::Paragraph> = ::std::vec::Vec::new();
__tdoc_collect_blocks_inner!($mode, __blocks, $($tt)*);
__blocks
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __tdoc_collect_blocks_inner {
($mode:ident, $vec:ident,) => {};
($mode:ident, $vec:ident) => {};
($mode:ident, $vec:ident, , $($rest:tt)*) => {
__tdoc_collect_blocks_inner!($mode, $vec, $($rest)*);
};
($mode:ident, $vec:ident, $tag:ident { $($inner:tt)* } $($rest:tt)*) => {{
$vec.push(__tdoc_build_block!($mode, $tag { $($inner)* }));
__tdoc_collect_blocks_inner!($mode, $vec, $($rest)*);
}};
($mode:ident, $vec:ident, $unexpected:tt $($rest:tt)*) => {{
compile_error!(concat!(
"Unexpected token in document block context: ",
stringify!($unexpected)
));
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __tdoc_build_block {
($mode:ident, p { $($inner:tt)* }) => {{
$crate::Paragraph::new_text().with_content(__tdoc_inline_nodes!($($inner)*))
}};
($mode:ident, h1 { $($inner:tt)* }) => {{
$crate::Paragraph::new_header1().with_content(__tdoc_inline_nodes!($($inner)*))
}};
($mode:ident, h2 { $($inner:tt)* }) => {{
$crate::Paragraph::new_header2().with_content(__tdoc_inline_nodes!($($inner)*))
}};
($mode:ident, h3 { $($inner:tt)* }) => {{
$crate::Paragraph::new_header3().with_content(__tdoc_inline_nodes!($($inner)*))
}};
($mode:ident, code { $($inner:tt)* }) => {{
let __text = __tdoc_collect_code_text!($($inner)*);
$crate::Paragraph::new_code_block()
.with_content(::std::vec::Vec::from([$crate::Span::new_text(__text)]))
}};
($mode:ident, quote { $($inner:tt)* }) => {{
$crate::Paragraph::new_quote().with_children(__tdoc_collect_blocks!($mode; $($inner)*))
}};
($mode:ident, ul { $($inner:tt)* }) => {{
$crate::Paragraph::new_unordered_list().with_entries(__tdoc_list_entries!($mode, $($inner)*))
}};
($mode:ident, ol { $($inner:tt)* }) => {{
$crate::Paragraph::new_ordered_list().with_entries(__tdoc_list_entries!($mode, $($inner)*))
}};
($mode:ident, checklist { $($inner:tt)* }) => {{
$crate::Paragraph::new_checklist()
.with_checklist_items(__tdoc_checklist_entries!($($inner)*))
}};
(doc, table { $($inner:tt)* }) => {{
$crate::Paragraph::new_table().with_rows(__tdoc_table_rows!($($inner)*))
}};
(ftml, table { $($inner:tt)* }) => {{
compile_error!(
"`table` is not part of strict FTML; use the `doc!` macro for tables and other extensions"
);
}};
($mode:ident, $other:ident { $($inner:tt)* }) => {{
compile_error!(concat!("Unknown document element: ", stringify!($other)));
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __tdoc_collect_code_text {
() => {
::std::string::String::new()
};
($($tt:tt)*) => {{
let mut __text = ::std::string::String::new();
__tdoc_collect_code_text_inner!(__text, $($tt)*);
__text
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __tdoc_collect_code_text_inner {
($buf:ident,) => {};
($buf:ident) => {};
($buf:ident, , $($rest:tt)*) => {
__tdoc_collect_code_text_inner!($buf, $($rest)*);
};
($buf:ident, $lit:literal $($rest:tt)*) => {{
$buf.push_str($lit);
__tdoc_collect_code_text_inner!($buf, $($rest)*);
}};
($buf:ident, ($($expr:tt)*) $($rest:tt)*) => {{
$buf.push_str(&::std::string::ToString::to_string(&($($expr)*)));
__tdoc_collect_code_text_inner!($buf, $($rest)*);
}};
($buf:ident, $other:tt $($rest:tt)*) => {{
compile_error!(concat!(
"Unsupported token inside code block: ",
stringify!($other)
));
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __tdoc_inline_nodes {
() => {
::std::vec::Vec::<$crate::Span>::new()
};
($($tt:tt)*) => {{
let mut __spans: ::std::vec::Vec<$crate::Span> = ::std::vec::Vec::new();
__tdoc_inline_nodes_inner!(__spans, $($tt)*);
__spans
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __tdoc_inline_nodes_inner {
($vec:ident,) => {};
($vec:ident) => {};
($vec:ident, , $($rest:tt)*) => {
__tdoc_inline_nodes_inner!($vec, $($rest)*);
};
($vec:ident, $tag:ident { $($inner:tt)* } $($rest:tt)*) => {{
$vec.push(__tdoc_build_inline!($tag { $($inner)* }));
__tdoc_inline_nodes_inner!($vec, $($rest)*);
}};
($vec:ident, $lit:literal $($rest:tt)*) => {{
$vec.push($crate::Span::new_text($lit));
__tdoc_inline_nodes_inner!($vec, $($rest)*);
}};
($vec:ident, ($($expr:tt)*) $($rest:tt)*) => {{
$vec.push($crate::Span::new_text(($($expr)*)));
__tdoc_inline_nodes_inner!($vec, $($rest)*);
}};
($vec:ident, $ident:ident $($rest:tt)*) => {{
$vec.push($crate::Span::new_text($ident));
__tdoc_inline_nodes_inner!($vec, $($rest)*);
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __tdoc_parse_link_children {
() => {
::std::vec::Vec::<$crate::Span>::new()
};
($($rest:tt)*) => {
__tdoc_inline_nodes!($($rest)*)
};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __tdoc_link_target {
($target:literal) => {
$target
};
(($($expr:tt)+)) => {
($($expr)+)
};
($target:ident) => {
$target
};
($($path:ident)::+) => {
$($path)::+
};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __tdoc_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(__tdoc_link_target!($target));
let __children = __tdoc_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(__tdoc_inline_nodes!($($inner)*))
}};
(i { $($inner:tt)* }) => {{
$crate::Span::new_styled($crate::InlineStyle::Italic)
.with_children(__tdoc_inline_nodes!($($inner)*))
}};
(u { $($inner:tt)* }) => {{
$crate::Span::new_styled($crate::InlineStyle::Underline)
.with_children(__tdoc_inline_nodes!($($inner)*))
}};
(del { $($inner:tt)* }) => {{
$crate::Span::new_styled($crate::InlineStyle::Strike)
.with_children(__tdoc_inline_nodes!($($inner)*))
}};
(mark { $($inner:tt)* }) => {{
$crate::Span::new_styled($crate::InlineStyle::Highlight)
.with_children(__tdoc_inline_nodes!($($inner)*))
}};
(code { $($inner:tt)* }) => {{
$crate::Span::new_styled($crate::InlineStyle::Code)
.with_children(__tdoc_inline_nodes!($($inner)*))
}};
($other:ident { $($inner:tt)* }) => {{
compile_error!(concat!("Unknown inline element: ", stringify!($other)));
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __tdoc_list_entries {
($mode:ident,) => {
::std::vec::Vec::<::std::vec::Vec<$crate::Paragraph>>::new()
};
($mode:ident, $($tt:tt)*) => {{
let mut __entries: ::std::vec::Vec<::std::vec::Vec<$crate::Paragraph>> =
::std::vec::Vec::new();
__tdoc_list_entries_inner!($mode, __entries, $($tt)*);
__entries
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __tdoc_list_entries_inner {
($mode:ident, $vec:ident,) => {};
($mode:ident, $vec:ident) => {};
($mode:ident, $vec:ident, , $($rest:tt)*) => {
__tdoc_list_entries_inner!($mode, $vec, $($rest)*);
};
($mode:ident, $vec:ident, li { $($inner:tt)* } $($rest:tt)*) => {{
$vec.push(__tdoc_collect_blocks!($mode; $($inner)*));
__tdoc_list_entries_inner!($mode, $vec, $($rest)*);
}};
($mode:ident, $vec:ident, $other:ident { $($inner:tt)* } $($rest:tt)*) => {{
compile_error!(concat!("Expected `li` inside list, found `", stringify!($other), "`"));
}};
($mode:ident, $vec:ident, $unexpected:tt $($rest:tt)*) => {{
compile_error!(concat!(
"Unexpected token inside list: ",
stringify!($unexpected)
));
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __tdoc_checklist_entries {
() => {
::std::vec::Vec::<$crate::ChecklistItem>::new()
};
($($tt:tt)*) => {{
let mut __entries: ::std::vec::Vec<$crate::ChecklistItem> = ::std::vec::Vec::new();
__tdoc_checklist_entries_inner!(__entries, $($tt)*);
__entries
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __tdoc_checklist_entries_inner {
($vec:ident,) => {};
($vec:ident) => {};
($vec:ident, , $($rest:tt)*) => {
__tdoc_checklist_entries_inner!($vec, $($rest)*);
};
($vec:ident, todo { $($inner:tt)* } $($rest:tt)*) => {{
let __item = $crate::ChecklistItem::new(false)
.with_content(__tdoc_inline_nodes!($($inner)*));
$vec.push(__item);
__tdoc_checklist_entries_inner!($vec, $($rest)*);
}};
($vec:ident, done { $($inner:tt)* } $($rest:tt)*) => {{
let __item = $crate::ChecklistItem::new(true)
.with_content(__tdoc_inline_nodes!($($inner)*));
$vec.push(__item);
__tdoc_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! __tdoc_table_rows {
() => {
::std::vec::Vec::<$crate::TableRow>::new()
};
($($tt:tt)*) => {{
let mut __rows: ::std::vec::Vec<$crate::TableRow> = ::std::vec::Vec::new();
__tdoc_table_rows_inner!(__rows, $($tt)*);
__rows
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __tdoc_table_rows_inner {
($vec:ident,) => {};
($vec:ident) => {};
($vec:ident, , $($rest:tt)*) => {
__tdoc_table_rows_inner!($vec, $($rest)*);
};
($vec:ident, row { $($inner:tt)* } $($rest:tt)*) => {{
$vec.push($crate::TableRow::new().with_cells(__tdoc_table_cells!($($inner)*)));
__tdoc_table_rows_inner!($vec, $($rest)*);
}};
($vec:ident, $other:ident { $($inner:tt)* } $($rest:tt)*) => {{
compile_error!(concat!("Expected `row` inside table, found `", stringify!($other), "`"));
}};
($vec:ident, $unexpected:tt $($rest:tt)*) => {{
compile_error!(concat!(
"Unexpected token inside table: ",
stringify!($unexpected)
));
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __tdoc_table_cells {
() => {
::std::vec::Vec::<$crate::TableCell>::new()
};
($($tt:tt)*) => {{
let mut __cells: ::std::vec::Vec<$crate::TableCell> = ::std::vec::Vec::new();
__tdoc_table_cells_inner!(__cells, $($tt)*);
__cells
}};
}
#[doc(hidden)]
#[macro_export(local_inner_macros)]
macro_rules! __tdoc_table_cells_inner {
($vec:ident,) => {};
($vec:ident) => {};
($vec:ident, , $($rest:tt)*) => {
__tdoc_table_cells_inner!($vec, $($rest)*);
};
($vec:ident, th { $($inner:tt)* } $($rest:tt)*) => {{
$vec.push($crate::TableCell::new_header().with_content(__tdoc_inline_nodes!($($inner)*)));
__tdoc_table_cells_inner!($vec, $($rest)*);
}};
($vec:ident, td { $($inner:tt)* } $($rest:tt)*) => {{
$vec.push($crate::TableCell::new_data().with_content(__tdoc_inline_nodes!($($inner)*)));
__tdoc_table_cells_inner!($vec, $($rest)*);
}};
($vec:ident, $other:ident { $($inner:tt)* } $($rest:tt)*) => {{
compile_error!(concat!(
"Expected `th` or `td` inside table row, found `",
stringify!($other),
"`"
));
}};
($vec:ident, $unexpected:tt $($rest:tt)*) => {{
compile_error!(concat!(
"Unexpected token inside table row: ",
stringify!($unexpected)
));
}};
}
#[macro_export(local_inner_macros)]
macro_rules! ftml {
($($tt:tt)*) => {{
let __paragraphs = __tdoc_collect_blocks!(ftml; $($tt)*);
$crate::Document::new().with_paragraphs(__paragraphs)
}};
}
#[macro_export(local_inner_macros)]
macro_rules! doc {
($($tt:tt)*) => {{
let __paragraphs = __tdoc_collect_blocks!(doc; $($tt)*);
$crate::Document::new().with_paragraphs(__paragraphs)
}};
}