1use nom::IResult;
2use std::cell::RefCell;
3use std::collections::HashMap;
4use std::rc::Rc;
5
6type ElementMapFn<ELT> = Rc<RefCell<Box<dyn FnMut(ELT) -> ELT>>>;
8
9type ElementFlatMapFn<ELT> = Rc<RefCell<Box<dyn FnMut(ELT) -> Vec<ELT>>>>;
11
12type CustomBlockParserFn =
14 Rc<RefCell<Box<dyn for<'a> FnMut(&'a str) -> IResult<&'a str, Vec<crate::ast::Block>>>>>;
15
16type CustomInlineParserFn =
18 Rc<RefCell<Box<dyn for<'a> FnMut(&'a str) -> IResult<&'a str, Vec<crate::ast::Inline>>>>>;
19
20#[derive(Clone)]
22pub enum ElementBehavior<ELT> {
23 Parse,
25
26 Ignore,
29
30 Skip,
32
33 Map(ElementMapFn<ELT>),
35
36 FlatMap(ElementFlatMapFn<ELT>),
38}
39
40#[derive(Clone)]
42pub struct MarkdownParserConfig {
43 pub(crate) allow_no_space_in_headings: bool,
45
46 pub(crate) html_entities_map: HashMap<String, &'static entities::Entity>,
48
49 pub(crate) block_blockquote_behavior: ElementBehavior<crate::ast::Block>,
51
52 pub(crate) block_github_alert_behavior: ElementBehavior<crate::ast::Block>,
54
55 pub(crate) block_heading_v1_behavior: ElementBehavior<crate::ast::Block>,
57
58 pub(crate) block_heading_v2_behavior: ElementBehavior<crate::ast::Block>,
60
61 pub(crate) block_thematic_break_behavior: ElementBehavior<crate::ast::Block>,
63
64 pub(crate) block_list_behavior: ElementBehavior<crate::ast::Block>,
66
67 pub(crate) block_code_block_behavior: ElementBehavior<crate::ast::Block>,
69
70 pub(crate) block_html_block_behavior: ElementBehavior<crate::ast::Block>,
72
73 pub(crate) block_footnote_definition_behavior: ElementBehavior<crate::ast::Block>,
75
76 pub(crate) block_link_definition_behavior: ElementBehavior<crate::ast::Block>,
78
79 pub(crate) block_table_behavior: ElementBehavior<crate::ast::Block>,
81
82 pub(crate) block_paragraph_behavior: ElementBehavior<crate::ast::Block>,
84
85 pub(crate) inline_autolink_behavior: ElementBehavior<crate::ast::Inline>,
87
88 pub(crate) inline_link_behavior: ElementBehavior<crate::ast::Inline>,
90
91 pub(crate) inline_footnote_reference_behavior: ElementBehavior<crate::ast::Inline>,
93
94 pub(crate) inline_reference_link_behavior: ElementBehavior<crate::ast::Inline>,
96
97 pub(crate) inline_hard_newline_behavior: ElementBehavior<crate::ast::Inline>,
99
100 pub(crate) inline_image_behavior: ElementBehavior<crate::ast::Inline>,
102
103 pub(crate) inline_code_span_behavior: ElementBehavior<crate::ast::Inline>,
105
106 pub(crate) inline_emphasis_behavior: ElementBehavior<crate::ast::Inline>,
108
109 pub(crate) inline_strikethrough_behavior: ElementBehavior<crate::ast::Inline>,
111
112 pub(crate) inline_text_behavior: ElementBehavior<crate::ast::Inline>,
114
115 pub(crate) custom_block_parser: Option<CustomBlockParserFn>,
117
118 pub(crate) custom_inline_parser: Option<CustomInlineParserFn>,
120}
121
122impl Default for MarkdownParserConfig {
123 fn default() -> Self {
124 Self {
125 allow_no_space_in_headings: false,
126 html_entities_map: Self::make_html_entities_map(),
127 block_blockquote_behavior: ElementBehavior::Parse,
128 block_github_alert_behavior: ElementBehavior::Parse,
129 block_heading_v1_behavior: ElementBehavior::Parse,
130 block_heading_v2_behavior: ElementBehavior::Parse,
131 block_thematic_break_behavior: ElementBehavior::Parse,
132 block_list_behavior: ElementBehavior::Parse,
133 block_code_block_behavior: ElementBehavior::Parse,
134 block_html_block_behavior: ElementBehavior::Parse,
135 block_footnote_definition_behavior: ElementBehavior::Parse,
136 block_link_definition_behavior: ElementBehavior::Parse,
137 block_table_behavior: ElementBehavior::Parse,
138 block_paragraph_behavior: ElementBehavior::Parse,
139 inline_autolink_behavior: ElementBehavior::Parse,
140 inline_link_behavior: ElementBehavior::Parse,
141 inline_footnote_reference_behavior: ElementBehavior::Parse,
142 inline_reference_link_behavior: ElementBehavior::Parse,
143 inline_hard_newline_behavior: ElementBehavior::Parse,
144 inline_image_behavior: ElementBehavior::Parse,
145 inline_code_span_behavior: ElementBehavior::Parse,
146 inline_emphasis_behavior: ElementBehavior::Parse,
147 inline_strikethrough_behavior: ElementBehavior::Parse,
148 inline_text_behavior: ElementBehavior::Parse,
149 custom_block_parser: None,
150 custom_inline_parser: None,
151 }
152 }
153}
154
155impl MarkdownParserConfig {
156 fn make_html_entities_map() -> HashMap<String, &'static entities::Entity> {
157 let mut map = HashMap::new();
158 for entity in entities::ENTITIES.iter() {
159 map.insert(entity.entity.to_string(), entity);
160 }
161 map
162 }
163
164 pub fn with_allow_no_space_in_headings(self) -> Self {
166 Self {
167 allow_no_space_in_headings: true,
168 ..self
169 }
170 }
171
172 pub fn with_html_entities_map(
174 self,
175 html_entities_map: HashMap<String, &'static entities::Entity>,
176 ) -> Self {
177 Self {
178 html_entities_map,
179 ..self
180 }
181 }
182
183 pub fn with_block_blockquote_behavior(
185 self,
186 behavior: ElementBehavior<crate::ast::Block>,
187 ) -> Self {
188 Self {
189 block_blockquote_behavior: behavior,
190 ..self
191 }
192 }
193
194 pub fn with_block_github_alert_behavior(
196 self,
197 behavior: ElementBehavior<crate::ast::Block>,
198 ) -> Self {
199 Self {
200 block_github_alert_behavior: behavior,
201 ..self
202 }
203 }
204
205 pub fn with_block_heading_v1_behavior(
207 self,
208 behavior: ElementBehavior<crate::ast::Block>,
209 ) -> Self {
210 Self {
211 block_heading_v1_behavior: behavior,
212 ..self
213 }
214 }
215
216 pub fn with_block_heading_v2_behavior(
218 self,
219 behavior: ElementBehavior<crate::ast::Block>,
220 ) -> Self {
221 Self {
222 block_heading_v2_behavior: behavior,
223 ..self
224 }
225 }
226
227 pub fn with_block_thematic_break_behavior(
229 self,
230 behavior: ElementBehavior<crate::ast::Block>,
231 ) -> Self {
232 Self {
233 block_thematic_break_behavior: behavior,
234 ..self
235 }
236 }
237
238 pub fn with_block_list_behavior(self, behavior: ElementBehavior<crate::ast::Block>) -> Self {
240 Self {
241 block_list_behavior: behavior,
242 ..self
243 }
244 }
245
246 pub fn with_block_code_block_behavior(
248 self,
249 behavior: ElementBehavior<crate::ast::Block>,
250 ) -> Self {
251 Self {
252 block_code_block_behavior: behavior,
253 ..self
254 }
255 }
256
257 pub fn with_block_html_block_behavior(
259 self,
260 behavior: ElementBehavior<crate::ast::Block>,
261 ) -> Self {
262 Self {
263 block_html_block_behavior: behavior,
264 ..self
265 }
266 }
267
268 pub fn with_block_footnote_definition_behavior(
270 self,
271 behavior: ElementBehavior<crate::ast::Block>,
272 ) -> Self {
273 Self {
274 block_footnote_definition_behavior: behavior,
275 ..self
276 }
277 }
278
279 pub fn with_block_link_definition_behavior(
281 self,
282 behavior: ElementBehavior<crate::ast::Block>,
283 ) -> Self {
284 Self {
285 block_link_definition_behavior: behavior,
286 ..self
287 }
288 }
289
290 pub fn with_block_table_behavior(self, behavior: ElementBehavior<crate::ast::Block>) -> Self {
292 Self {
293 block_table_behavior: behavior,
294 ..self
295 }
296 }
297
298 pub fn with_block_paragraph_behavior(
300 self,
301 behavior: ElementBehavior<crate::ast::Block>,
302 ) -> Self {
303 Self {
304 block_paragraph_behavior: behavior,
305 ..self
306 }
307 }
308
309 pub fn with_inline_autolink_behavior(
311 self,
312 behavior: ElementBehavior<crate::ast::Inline>,
313 ) -> Self {
314 Self {
315 inline_autolink_behavior: behavior,
316 ..self
317 }
318 }
319
320 pub fn with_inline_link_behavior(self, behavior: ElementBehavior<crate::ast::Inline>) -> Self {
322 Self {
323 inline_link_behavior: behavior,
324 ..self
325 }
326 }
327
328 pub fn with_inline_footnote_reference_behavior(
330 self,
331 behavior: ElementBehavior<crate::ast::Inline>,
332 ) -> Self {
333 Self {
334 inline_footnote_reference_behavior: behavior,
335 ..self
336 }
337 }
338
339 pub fn with_inline_reference_link_behavior(
341 self,
342 behavior: ElementBehavior<crate::ast::Inline>,
343 ) -> Self {
344 Self {
345 inline_reference_link_behavior: behavior,
346 ..self
347 }
348 }
349
350 pub fn with_inline_hard_newline_behavior(
352 self,
353 behavior: ElementBehavior<crate::ast::Inline>,
354 ) -> Self {
355 Self {
356 inline_hard_newline_behavior: behavior,
357 ..self
358 }
359 }
360
361 pub fn with_inline_image_behavior(self, behavior: ElementBehavior<crate::ast::Inline>) -> Self {
363 Self {
364 inline_image_behavior: behavior,
365 ..self
366 }
367 }
368
369 pub fn with_inline_code_span_behavior(
371 self,
372 behavior: ElementBehavior<crate::ast::Inline>,
373 ) -> Self {
374 Self {
375 inline_code_span_behavior: behavior,
376 ..self
377 }
378 }
379
380 pub fn with_inline_emphasis_behavior(
382 self,
383 behavior: ElementBehavior<crate::ast::Inline>,
384 ) -> Self {
385 Self {
386 inline_emphasis_behavior: behavior,
387 ..self
388 }
389 }
390
391 pub fn with_inline_strikethrough_behavior(
393 self,
394 behavior: ElementBehavior<crate::ast::Inline>,
395 ) -> Self {
396 Self {
397 inline_strikethrough_behavior: behavior,
398 ..self
399 }
400 }
401
402 pub fn with_inline_text_behavior(self, behavior: ElementBehavior<crate::ast::Inline>) -> Self {
404 Self {
405 inline_text_behavior: behavior,
406 ..self
407 }
408 }
409
410 pub fn with_custom_block_parser(self, parser: CustomBlockParserFn) -> Self {
412 Self {
413 custom_block_parser: Some(parser),
414 ..self
415 }
416 }
417
418 pub fn with_custom_inline_parser(self, parser: CustomInlineParserFn) -> Self {
420 Self {
421 custom_inline_parser: Some(parser),
422 ..self
423 }
424 }
425}