use std::fmt::{self, Write};
use crate::{InlineMacro, InlineNode};
pub(crate) fn write_inlines<W: Write + ?Sized>(
w: &mut W,
inlines: &[InlineNode<'_>],
) -> fmt::Result {
for node in inlines {
write_inline_node(w, node)?;
}
Ok(())
}
fn write_inline_node<W: Write + ?Sized>(w: &mut W, node: &InlineNode<'_>) -> fmt::Result {
match node {
InlineNode::PlainText(text) => w.write_str(text.content),
InlineNode::RawText(text) => w.write_str(text.content),
InlineNode::VerbatimText(text) => w.write_str(text.content),
InlineNode::BoldText(bold) => write_inlines(w, &bold.content),
InlineNode::ItalicText(italic) => write_inlines(w, &italic.content),
InlineNode::MonospaceText(mono) => write_inlines(w, &mono.content),
InlineNode::HighlightText(highlight) => write_inlines(w, &highlight.content),
InlineNode::SubscriptText(sub) => write_inlines(w, &sub.content),
InlineNode::SuperscriptText(sup) => write_inlines(w, &sup.content),
InlineNode::CurvedQuotationText(quote) => write_inlines(w, "e.content),
InlineNode::CurvedApostropheText(apos) => write_inlines(w, &apos.content),
InlineNode::StandaloneCurvedApostrophe(_) => w.write_char('\''),
InlineNode::LineBreak(_) => w.write_char(' '),
InlineNode::InlineAnchor(_) => Ok(()),
InlineNode::Macro(macro_node) => write_inline_macro(w, macro_node),
InlineNode::CalloutRef(callout) => write!(w, "<{}>", callout.number),
}
}
fn write_inline_macro<W: Write + ?Sized>(w: &mut W, m: &InlineMacro<'_>) -> fmt::Result {
match m {
InlineMacro::Link(link) => {
if link.text.is_empty() {
write!(w, "{}", link.target)
} else {
write_inlines(w, &link.text)
}
}
InlineMacro::Url(url) => {
if url.text.is_empty() {
write!(w, "{}", url.target)
} else {
write_inlines(w, &url.text)
}
}
InlineMacro::Mailto(mailto) => {
if mailto.text.is_empty() {
write!(w, "{}", mailto.target)
} else {
write_inlines(w, &mailto.text)
}
}
InlineMacro::Autolink(autolink) => write!(w, "{}", autolink.url),
InlineMacro::CrossReference(xref) => {
if xref.text.is_empty() {
write!(w, "{}", xref.target)
} else {
write_inlines(w, &xref.text)
}
}
InlineMacro::IndexTerm(index_term) if index_term.is_visible() => {
w.write_str(index_term.term())
}
InlineMacro::Image(_)
| InlineMacro::Footnote(_)
| InlineMacro::Button(_)
| InlineMacro::Pass(_)
| InlineMacro::Keyboard(_)
| InlineMacro::Menu(_)
| InlineMacro::Stem(_)
| InlineMacro::Icon(_)
| InlineMacro::IndexTerm(_) => Ok(()),
}
}
#[must_use]
pub fn inlines_to_string(inlines: &[InlineNode<'_>]) -> String {
let mut s = String::new();
let _ = write_inlines(&mut s, inlines);
s
}