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