use super::escape::{Escape, escape_markdown};
use super::{CLOSE, Ctx, Formatter, OPEN, Out, SPACE};
use crate::ast::{Node, Value};
impl Formatter<'_> {
pub(super) fn image(&mut self, node: &Node<'_>, no: Ctx, out: &mut Out) {
out.text("!");
out.text("[");
if let Some(alt) = node.get("alt") {
self.value(alt, no, out);
}
out.text("]");
out.text("(");
self.destination(node.get("src"), no, out);
self.title(node, out);
out.text(")");
}
pub(super) fn link(&mut self, node: &Node<'_>, no: Ctx, out: &mut Out) {
let children = self.collect_children(node, no).joined();
let has_title = node.get("title").is_some_and(Value::is_truthy);
if !has_title
&& let Some(Value::String(href)) = node.get("href")
&& children == *href
{
out.text(format!("<{href}>"));
return;
}
out.text("[");
out.text(children);
out.text("]");
out.text("(");
self.destination(node.get("href"), no, out);
self.title(node, out);
out.text(")");
}
pub(super) fn text(&mut self, node: &Node<'_>, ctx: Ctx, no: Ctx, out: &mut Out) {
match node.get("content") {
Some(value @ (Value::Variable(_) | Value::Function(_))) => {
out.text(format!("{OPEN}{SPACE}"));
self.value(value, no, out);
out.text(format!("{SPACE}{CLOSE}"));
}
Some(other) => {
let content = self.text_of(other);
let class = if ctx.parent_wraps {
Escape::Wrapping
} else {
Escape::Block
};
out.text(escape_markdown(&content, class));
}
None => {}
}
}
pub(super) fn code(&mut self, node: &Node<'_>, no: Ctx, out: &mut Out) {
out.text("`");
let mut inner = Out::default();
if let Some(content) = node.get("content") {
self.value(content, no, &mut inner);
}
out.text(inner.joined().trim().to_owned());
out.text("`");
}
pub(super) fn wrapped(&mut self, node: &Node<'_>, ctx: Ctx, default: &str, out: &mut Out) {
let marker = match node.get("marker") {
Some(Value::String(marker)) => marker.clone(),
_ => default.to_owned(),
};
out.text(marker.clone());
out.text(self.inline_text(node, ctx));
out.text(marker);
}
fn destination(&mut self, value: Option<&Value>, ctx: Ctx, out: &mut Out) {
match value {
Some(Value::String(text)) => out.text(escape_markdown(text, Escape::Parens)),
Some(other) => self.value(other, ctx, out),
None => {}
}
}
fn title(&mut self, node: &Node<'_>, out: &mut Out) {
let Some(title) = node.get("title").filter(|value| value.is_truthy()) else {
return;
};
let title = self.text_of(title);
out.text(format!("{SPACE}\"{title}\""));
}
}