use super::TextContext;
use crate::tree::{CodeBlock, ContainerType, DefinitionListItem, Element, ListItem, Tab};
pub fn render_elements(ctx: &mut TextContext, elements: &[Element]) {
debug!("Rendering elements (length {})", elements.len());
for element in elements {
render_element(ctx, element);
}
}
pub fn render_element(ctx: &mut TextContext, element: &Element) {
debug!("Rendering element {}", element.name());
match element {
Element::Container(container) => {
let mut invisible = false;
let add_newlines = match container.ctype() {
ContainerType::Hidden => return,
ContainerType::Invisible => {
ctx.enable_invisible();
invisible = true;
false
}
ContainerType::Div
| ContainerType::Paragraph
| ContainerType::Blockquote
| ContainerType::Header(_) => true,
ContainerType::RubyText => {
ctx.push('(');
false
}
_ => false,
};
if add_newlines {
ctx.add_newline();
}
render_elements(ctx, container.elements());
if container.ctype() == ContainerType::RubyText {
ctx.push(')');
}
if add_newlines {
ctx.add_newline();
}
if invisible {
ctx.disable_invisible();
}
}
Element::Module(_) => {
}
Element::Text(text) | Element::Raw(text) | Element::Email(text) => {
ctx.push_str(text);
}
Element::Variable(name) => {
let value = match ctx.variables().get(name) {
Some(value) => str!(value),
None => format!("{{${name}}}"),
};
debug!(
"Rendering variable (name '{}', value {})",
name.as_ref(),
value,
);
ctx.push_str(&value);
}
Element::Table(table) => {
if !ctx.ends_with_newline() {
ctx.add_newline();
}
for row in &table.rows {
for cell in &row.cells {
render_elements(ctx, &cell.elements);
}
ctx.add_newline();
}
ctx.add_newline();
}
Element::TabView(tabs) => {
for Tab { label, elements } in tabs {
ctx.push_str(label);
ctx.add_newline();
render_elements(ctx, elements);
ctx.add_newline();
}
}
Element::Anchor { elements, .. } => render_elements(ctx, elements),
Element::AnchorName(_) => {
}
Element::Link { link, label, .. } => {
let site = ctx.info().site.as_ref();
ctx.handle().get_link_label(site, link, label, |label| {
ctx.push_str(label);
});
}
Element::Image { .. } => {
}
Element::Audio { .. } => {
}
Element::Video { .. } => {
}
Element::List { items, .. } => {
if !ctx.ends_with_newline() {
ctx.add_newline();
}
for item in items {
match item {
ListItem::SubList { element } => render_element(ctx, element),
ListItem::Elements { elements, .. } => {
if elements.is_empty() {
continue;
}
render_elements(ctx, elements);
ctx.add_newline();
}
}
}
}
Element::DefinitionList(items) => {
for DefinitionListItem {
key_elements,
value_elements,
..
} in items
{
render_elements(ctx, key_elements);
ctx.push(' ');
render_elements(ctx, value_elements);
ctx.add_newline();
}
ctx.add_newline();
}
Element::RadioButton { .. } | Element::CheckBox { .. } => {
}
Element::Collapsible { elements, .. } => {
render_elements(ctx, elements);
}
Element::TableOfContents { .. } => {
}
Element::Footnote
| Element::FootnoteBlock { .. }
| Element::BibliographyCite { .. }
| Element::BibliographyBlock { .. } => {
}
Element::User { name, .. } => ctx.push_str(name),
Element::Date { value, format, .. } => {
ctx.push_str(&value.format_or_default(format.as_deref(), ctx.language()));
}
Element::Color { elements, .. } => render_elements(ctx, elements),
Element::Code(CodeBlock { contents, .. }) => {
ctx.add_newline();
ctx.push_str(contents);
ctx.add_newline();
}
Element::Math { .. } | Element::MathInline { .. } => {
}
Element::EquationReference(name) => {
str_write!(ctx, "[{name}]");
}
Element::Embed(_) | Element::Html { .. } | Element::Iframe { .. } => {
}
Element::Include {
variables,
elements,
..
} => {
debug!(
"Rendering include (variables length {}, elements length {})",
variables.len(),
elements.len(),
);
ctx.variables_mut().push_scope(variables);
render_elements(ctx, elements);
ctx.variables_mut().pop_scope();
}
Element::Style(_) | Element::ClearFloat(_) => {
}
Element::LineBreak => ctx.add_newline(),
Element::LineBreaks(amount) => {
for _ in 0..amount.get() {
ctx.add_newline();
}
}
Element::HorizontalRule => {
}
Element::Partial(_) => panic!("Encountered partial element during parsing"),
}
}