1use crate::writer::html::HtmlWriterOptions;
6#[cfg(feature = "gfm")]
7use ecow::EcoString;
8
9#[derive(Debug, Clone)]
11pub struct WriterOptions {
12 pub strict: bool,
14 pub hard_break_spaces: bool,
16 pub indent_spaces: usize,
18 pub list_marker: char,
20 pub thematic_break_char: char,
22 pub emphasis_char: char,
24 pub strong_char: char,
26 pub escape_special_chars: bool,
28 pub trim_paragraph_trailing_hard_breaks: bool,
30
31 #[cfg(feature = "gfm")]
33 pub enable_gfm: bool,
34
35 #[cfg(feature = "gfm")]
37 pub gfm_strikethrough: bool,
38
39 #[cfg(feature = "gfm")]
41 pub gfm_tasklists: bool,
42
43 #[cfg(feature = "gfm")]
45 pub gfm_tables: bool,
46
47 #[cfg(feature = "gfm")]
49 pub gfm_autolinks: bool,
50
51 #[cfg(feature = "gfm")]
53 pub gfm_disallowed_html_tags: Vec<EcoString>,
54
55 pub html_writer_options: Option<HtmlWriterOptions>,
58}
59
60impl Default for WriterOptions {
61 fn default() -> Self {
62 Self {
63 strict: true,
64 hard_break_spaces: false,
65 indent_spaces: 4,
66 list_marker: '-',
67 thematic_break_char: '-',
68 emphasis_char: '_',
69 strong_char: '*',
70 escape_special_chars: false,
71 trim_paragraph_trailing_hard_breaks: true,
72
73 #[cfg(feature = "gfm")]
74 enable_gfm: false,
75
76 #[cfg(feature = "gfm")]
77 gfm_strikethrough: false,
78
79 #[cfg(feature = "gfm")]
80 gfm_tasklists: false,
81
82 #[cfg(feature = "gfm")]
83 gfm_tables: false,
84
85 #[cfg(feature = "gfm")]
86 gfm_autolinks: false,
87
88 #[cfg(feature = "gfm")]
89 gfm_disallowed_html_tags: vec![
90 "title".into(),
91 "textarea".into(),
92 "style".into(),
93 "xmp".into(),
94 "iframe".into(),
95 "noembed".into(),
96 "noframes".into(),
97 "script".into(),
98 "plaintext".into(),
99 ],
100
101 html_writer_options: None,
102 }
103 }
104}
105
106impl WriterOptions {
107 pub fn html_writer_options(mut self, options: Option<HtmlWriterOptions>) -> Self {
109 self.html_writer_options = options;
110 self
111 }
112}
113
114pub struct WriterOptionsBuilder {
116 options: WriterOptions,
117}
118
119impl WriterOptionsBuilder {
120 pub fn new() -> Self {
122 Self {
123 options: WriterOptions::default(),
124 }
125 }
126
127 pub fn strict(mut self, strict: bool) -> Self {
129 self.options.strict = strict;
130 self
131 }
132
133 pub fn hard_break_spaces(mut self, hard_break_spaces: bool) -> Self {
135 self.options.hard_break_spaces = hard_break_spaces;
136 self
137 }
138
139 pub fn indent_spaces(mut self, indent_spaces: usize) -> Self {
141 self.options.indent_spaces = indent_spaces;
142 self
143 }
144
145 pub fn list_marker(mut self, marker: char) -> Self {
147 if marker == '-' || marker == '+' || marker == '*' {
148 self.options.list_marker = marker;
149 }
150 self
151 }
152
153 pub fn escape_special_chars(mut self, escape: bool) -> Self {
155 self.options.escape_special_chars = escape;
156 self
157 }
158
159 pub fn trim_paragraph_trailing_hard_breaks(mut self, trim: bool) -> Self {
161 self.options.trim_paragraph_trailing_hard_breaks = trim;
162 self
163 }
164
165 pub fn thematic_break_char(mut self, char: char) -> Self {
167 if char == '-' || char == '*' || char == '_' {
168 self.options.thematic_break_char = char;
169 }
170 self
171 }
172
173 pub fn emphasis_char(mut self, char: char) -> Self {
175 if char == '_' || char == '*' {
176 self.options.emphasis_char = char;
177 }
178 self
179 }
180
181 pub fn strong_char(mut self, char: char) -> Self {
183 if char == '_' || char == '*' {
184 self.options.strong_char = char;
185 }
186 self
187 }
188
189 #[cfg(feature = "gfm")]
191 pub fn enable_gfm(mut self) -> Self {
192 self.options.enable_gfm = true;
193 self.options.gfm_strikethrough = true;
194 self.options.gfm_tasklists = true;
195 self.options.gfm_tables = true;
196 self.options.gfm_autolinks = true;
197 self
198 }
199
200 #[cfg(feature = "gfm")]
202 pub fn gfm_strikethrough(mut self, enable: bool) -> Self {
203 self.options.gfm_strikethrough = enable;
204 if enable {
205 self.options.enable_gfm = true;
206 }
207 self
208 }
209
210 #[cfg(feature = "gfm")]
212 pub fn gfm_tasklists(mut self, enable: bool) -> Self {
213 self.options.gfm_tasklists = enable;
214 if enable {
215 self.options.enable_gfm = true;
216 }
217 self
218 }
219
220 #[cfg(feature = "gfm")]
222 pub fn gfm_tables(mut self, enable: bool) -> Self {
223 self.options.gfm_tables = enable;
224 if enable {
225 self.options.enable_gfm = true;
226 }
227 self
228 }
229
230 #[cfg(feature = "gfm")]
232 pub fn gfm_autolinks(mut self, enable: bool) -> Self {
233 self.options.gfm_autolinks = enable;
234 if enable {
235 self.options.enable_gfm = true;
236 }
237 self
238 }
239
240 #[cfg(feature = "gfm")]
242 pub fn gfm_disallowed_html_tags(mut self, tags: Vec<EcoString>) -> Self {
243 self.options.gfm_disallowed_html_tags = tags;
244 self
245 }
246
247 pub fn html_writer_options(mut self, options: Option<HtmlWriterOptions>) -> Self {
249 self.options.html_writer_options = options;
250 self
251 }
252
253 pub fn build(self) -> WriterOptions {
255 self.options
256 }
257}
258
259impl Default for WriterOptionsBuilder {
260 fn default() -> Self {
261 Self::new()
262 }
263}