citum_engine/render/
plain.rs1use super::format::OutputFormat;
9use citum_schema::template::WrapPunctuation;
10
11#[derive(Default, Clone)]
12pub struct PlainText;
14
15impl OutputFormat for PlainText {
16 type Output = String;
17
18 fn text(&self, s: &str) -> Self::Output {
19 s.to_string()
20 }
21
22 fn join(&self, items: Vec<Self::Output>, delimiter: &str) -> Self::Output {
23 items.join(delimiter)
24 }
25
26 fn finish(&self, output: Self::Output) -> String {
27 output
28 }
29
30 fn emph(&self, content: Self::Output) -> Self::Output {
31 if content.is_empty() {
32 return content;
33 }
34 format!("_{content}_")
35 }
36
37 fn strong(&self, content: Self::Output) -> Self::Output {
38 if content.is_empty() {
39 return content;
40 }
41 format!("**{content}**")
42 }
43
44 fn small_caps(&self, content: Self::Output) -> Self::Output {
45 content.to_uppercase()
46 }
47
48 fn superscript(&self, content: Self::Output) -> Self::Output {
49 if content.is_empty() {
50 return content;
51 }
52 format!("^{content}^")
53 }
54
55 fn quote(&self, content: Self::Output) -> Self::Output {
56 if content.is_empty() {
57 return content;
58 }
59 format!("\u{201C}{content}\u{201D}")
60 }
61
62 fn affix(&self, prefix: &str, content: Self::Output, suffix: &str) -> Self::Output {
63 format!("{prefix}{content}{suffix}")
64 }
65
66 fn inner_affix(&self, prefix: &str, content: Self::Output, suffix: &str) -> Self::Output {
67 format!("{prefix}{content}{suffix}")
68 }
69
70 fn wrap_punctuation(&self, wrap: &WrapPunctuation, content: Self::Output) -> Self::Output {
71 match wrap {
72 WrapPunctuation::Parentheses => format!("({content})"),
73 WrapPunctuation::Brackets => format!("[{content}]"),
74 WrapPunctuation::Quotes => format!("\u{201C}{content}\u{201D}"),
75 }
76 }
77
78 fn semantic(&self, _class: &str, content: Self::Output) -> Self::Output {
79 content
81 }
82
83 fn annotation(&self, content: Self::Output) -> Self::Output {
84 if content.is_empty() {
85 return content;
86 }
87
88 format!("\n\n{content}")
89 }
90
91 fn link(&self, _url: &str, content: Self::Output) -> Self::Output {
92 content
94 }
95
96 fn entry(
97 &self,
98 _id: &str,
99 content: Self::Output,
100 _url: Option<&str>,
101 _metadata: &super::format::ProcEntryMetadata,
102 ) -> Self::Output {
103 content
104 }
105}
106
107#[cfg(test)]
108mod tests {
109 use super::*;
110
111 #[test]
112 fn small_caps_preserves_empty_text() {
113 let fmt = PlainText;
114
115 assert_eq!(fmt.small_caps(String::new()), "");
116 }
117
118 #[test]
119 fn small_caps_uppercases_plain_text() {
120 let fmt = PlainText;
121
122 assert_eq!(
123 fmt.small_caps("Smith and Lumière".to_string()),
124 "SMITH AND LUMIÈRE"
125 );
126 }
127}