acdc_parser/model/inlines/
converter.rs1use std::fmt::{self, Write};
2
3use crate::{InlineMacro, InlineNode};
4
5pub(crate) fn write_inlines<W: Write + ?Sized>(
22 w: &mut W,
23 inlines: &[InlineNode<'_>],
24) -> fmt::Result {
25 for node in inlines {
26 write_inline_node(w, node)?;
27 }
28 Ok(())
29}
30
31fn write_inline_node<W: Write + ?Sized>(w: &mut W, node: &InlineNode<'_>) -> fmt::Result {
32 match node {
33 InlineNode::PlainText(text) => w.write_str(text.content),
34 InlineNode::RawText(text) => w.write_str(text.content),
35 InlineNode::VerbatimText(text) => w.write_str(text.content),
36 InlineNode::BoldText(bold) => write_inlines(w, &bold.content),
37 InlineNode::ItalicText(italic) => write_inlines(w, &italic.content),
38 InlineNode::MonospaceText(mono) => write_inlines(w, &mono.content),
39 InlineNode::HighlightText(highlight) => write_inlines(w, &highlight.content),
40 InlineNode::SubscriptText(sub) => write_inlines(w, &sub.content),
41 InlineNode::SuperscriptText(sup) => write_inlines(w, &sup.content),
42 InlineNode::CurvedQuotationText(quote) => write_inlines(w, "e.content),
43 InlineNode::CurvedApostropheText(apos) => write_inlines(w, &apos.content),
44 InlineNode::StandaloneCurvedApostrophe(_) => w.write_char('\''),
45 InlineNode::LineBreak(_) => w.write_char(' '),
46 InlineNode::InlineAnchor(_) => Ok(()),
47 InlineNode::Macro(macro_node) => write_inline_macro(w, macro_node),
48 InlineNode::CalloutRef(callout) => write!(w, "<{}>", callout.number),
49 }
50}
51
52fn write_inline_macro<W: Write + ?Sized>(w: &mut W, m: &InlineMacro<'_>) -> fmt::Result {
53 match m {
54 InlineMacro::Link(link) => {
55 if link.text.is_empty() {
56 write!(w, "{}", link.target)
57 } else {
58 write_inlines(w, &link.text)
59 }
60 }
61 InlineMacro::Url(url) => {
62 if url.text.is_empty() {
63 write!(w, "{}", url.target)
64 } else {
65 write_inlines(w, &url.text)
66 }
67 }
68 InlineMacro::Mailto(mailto) => {
69 if mailto.text.is_empty() {
70 write!(w, "{}", mailto.target)
71 } else {
72 write_inlines(w, &mailto.text)
73 }
74 }
75 InlineMacro::Autolink(autolink) => write!(w, "{}", autolink.url),
76 InlineMacro::CrossReference(xref) => {
77 if xref.text.is_empty() {
78 write!(w, "{}", xref.target)
79 } else {
80 write_inlines(w, &xref.text)
81 }
82 }
83 InlineMacro::IndexTerm(index_term) if index_term.is_visible() => {
84 w.write_str(index_term.term())
85 }
86 InlineMacro::Image(_)
87 | InlineMacro::Footnote(_)
88 | InlineMacro::Button(_)
89 | InlineMacro::Pass(_)
90 | InlineMacro::Keyboard(_)
91 | InlineMacro::Menu(_)
92 | InlineMacro::Stem(_)
93 | InlineMacro::Icon(_)
94 | InlineMacro::IndexTerm(_) => Ok(()),
95 }
96}
97
98#[must_use]
104pub fn inlines_to_string(inlines: &[InlineNode<'_>]) -> String {
105 let mut s = String::new();
106 let _ = write_inlines(&mut s, inlines);
108 s
109}