wayver's git archive


an obsidian renderer
git clone https://git.wayver.dev/sable

sable-markdown/src/render/util.rs@main

raw
Date Commit Message Author Files + -
2026-02-23 01:55 initial mvp wayverd 139 17808 0
...

1use pretty::{Arena, DocAllocator, DocBuilder};
2
3pub(super) fn escape(value: &str) -> String {
4    let mut escaped = String::new();
5    for c in value.chars() {
6        match c {
7            '&' => escaped.push_str("&"),
8            '<' => escaped.push_str("&lt;"),
9            '>' => escaped.push_str("&gt;"),
10            '"' => escaped.push_str("&quot;"),
11            '\'' => escaped.push_str("&apos;"),
12            _ => escaped.push(c),
13        }
14    }
15    escaped
16}
17
18pub(super) trait ArenaExt<'a> {
19    fn tag(
20        &'a self,
21        tag: &'static str,
22        attributes: Vec<(String, String)>,
23        inner: DocBuilder<'a, Arena<'a>, ()>,
24    ) -> DocBuilder<'a, Arena<'a>, ()>;
25}
26
27impl<'a> ArenaExt<'a> for Arena<'a> {
28    fn tag(
29        &'a self,
30        tag: &'static str,
31        attributes: Vec<(String, String)>,
32        inner: DocBuilder<'a, Self, ()>,
33    ) -> DocBuilder<'a, Self, ()> {
34        let mut attrs = self.nil();
35        for (key, value) in attributes {
36            let attr = if value.is_empty() {
37                self.text(" ").append(self.text(key))
38            } else {
39                self.text(" ")
40                    .append(self.text(key))
41                    .append(self.text("=\""))
42                    .append(self.text(escape(&value)))
43                    .append(self.text("\""))
44            };
45
46            attrs = attrs.append(attr);
47        }
48        let open_tag = self
49            .text("<")
50            .append(self.text(tag))
51            .append(attrs)
52            .append(self.text(">"));
53        let close_tag = self
54            .text("</")
55            .append(self.text(tag))
56            .append(self.text(">"));
57        open_tag.append(inner).append(close_tag)
58    }
59}
60