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_heading_v1_behavior: ElementBehavior<crate::ast::Block>,
54
55 pub(crate) block_heading_v2_behavior: ElementBehavior<crate::ast::Block>,
57
58 pub(crate) block_thematic_break_behavior: ElementBehavior<crate::ast::Block>,
60
61 pub(crate) block_list_behavior: ElementBehavior<crate::ast::Block>,
63
64 pub(crate) block_code_block_behavior: ElementBehavior<crate::ast::Block>,
66
67 pub(crate) block_html_block_behavior: ElementBehavior<crate::ast::Block>,
69
70 pub(crate) block_footnote_definition_behavior: ElementBehavior<crate::ast::Block>,
72
73 pub(crate) block_link_definition_behavior: ElementBehavior<crate::ast::Block>,
75
76 pub(crate) block_table_behavior: ElementBehavior<crate::ast::Block>,
78
79 pub(crate) block_paragraph_behavior: ElementBehavior<crate::ast::Block>,
81
82 pub(crate) inline_autolink_behavior: ElementBehavior<crate::ast::Inline>,
84
85 pub(crate) inline_link_behavior: ElementBehavior<crate::ast::Inline>,
87
88 pub(crate) inline_footnote_reference_behavior: ElementBehavior<crate::ast::Inline>,
90
91 pub(crate) inline_reference_link_behavior: ElementBehavior<crate::ast::Inline>,
93
94 pub(crate) inline_hard_newline_behavior: ElementBehavior<crate::ast::Inline>,
96
97 pub(crate) inline_image_behavior: ElementBehavior<crate::ast::Inline>,
99
100 pub(crate) inline_code_span_behavior: ElementBehavior<crate::ast::Inline>,
102
103 pub(crate) inline_emphasis_behavior: ElementBehavior<crate::ast::Inline>,
105
106 pub(crate) inline_strikethrough_behavior: ElementBehavior<crate::ast::Inline>,
108
109 pub(crate) inline_text_behavior: ElementBehavior<crate::ast::Inline>,
111
112 pub(crate) custom_block_parser: Option<CustomBlockParserFn>,
114
115 pub(crate) custom_inline_parser: Option<CustomInlineParserFn>,
117}
118
119impl Default for MarkdownParserConfig {
120 fn default() -> Self {
121 Self {
122 allow_no_space_in_headings: false,
123 html_entities_map: Self::make_html_entities_map(),
124 block_blockquote_behavior: ElementBehavior::Parse,
125 block_heading_v1_behavior: ElementBehavior::Parse,
126 block_heading_v2_behavior: ElementBehavior::Parse,
127 block_thematic_break_behavior: ElementBehavior::Parse,
128 block_list_behavior: ElementBehavior::Parse,
129 block_code_block_behavior: ElementBehavior::Parse,
130 block_html_block_behavior: ElementBehavior::Parse,
131 block_footnote_definition_behavior: ElementBehavior::Parse,
132 block_link_definition_behavior: ElementBehavior::Parse,
133 block_table_behavior: ElementBehavior::Parse,
134 block_paragraph_behavior: ElementBehavior::Parse,
135 inline_autolink_behavior: ElementBehavior::Parse,
136 inline_link_behavior: ElementBehavior::Parse,
137 inline_footnote_reference_behavior: ElementBehavior::Parse,
138 inline_reference_link_behavior: ElementBehavior::Parse,
139 inline_hard_newline_behavior: ElementBehavior::Parse,
140 inline_image_behavior: ElementBehavior::Parse,
141 inline_code_span_behavior: ElementBehavior::Parse,
142 inline_emphasis_behavior: ElementBehavior::Parse,
143 inline_strikethrough_behavior: ElementBehavior::Parse,
144 inline_text_behavior: ElementBehavior::Parse,
145 custom_block_parser: None,
146 custom_inline_parser: None,
147 }
148 }
149}
150
151impl MarkdownParserConfig {
152 fn make_html_entities_map() -> HashMap<String, &'static entities::Entity> {
153 let mut map = HashMap::new();
154 for entity in entities::ENTITIES.iter() {
155 map.insert(entity.entity.to_string(), entity);
156 }
157 map
158 }
159
160 pub fn with_allow_no_space_in_headings(self) -> Self {
162 Self {
163 allow_no_space_in_headings: true,
164 ..self
165 }
166 }
167
168 pub fn with_html_entities_map(
170 self,
171 html_entities_map: HashMap<String, &'static entities::Entity>,
172 ) -> Self {
173 Self {
174 html_entities_map,
175 ..self
176 }
177 }
178
179 pub fn with_block_blockquote_behavior(
181 self,
182 behavior: ElementBehavior<crate::ast::Block>,
183 ) -> Self {
184 Self {
185 block_blockquote_behavior: behavior,
186 ..self
187 }
188 }
189
190 pub fn with_block_heading_v1_behavior(
192 self,
193 behavior: ElementBehavior<crate::ast::Block>,
194 ) -> Self {
195 Self {
196 block_heading_v1_behavior: behavior,
197 ..self
198 }
199 }
200
201 pub fn with_block_heading_v2_behavior(
203 self,
204 behavior: ElementBehavior<crate::ast::Block>,
205 ) -> Self {
206 Self {
207 block_heading_v2_behavior: behavior,
208 ..self
209 }
210 }
211
212 pub fn with_block_thematic_break_behavior(
214 self,
215 behavior: ElementBehavior<crate::ast::Block>,
216 ) -> Self {
217 Self {
218 block_thematic_break_behavior: behavior,
219 ..self
220 }
221 }
222
223 pub fn with_block_list_behavior(self, behavior: ElementBehavior<crate::ast::Block>) -> Self {
225 Self {
226 block_list_behavior: behavior,
227 ..self
228 }
229 }
230
231 pub fn with_block_code_block_behavior(
233 self,
234 behavior: ElementBehavior<crate::ast::Block>,
235 ) -> Self {
236 Self {
237 block_code_block_behavior: behavior,
238 ..self
239 }
240 }
241
242 pub fn with_block_html_block_behavior(
244 self,
245 behavior: ElementBehavior<crate::ast::Block>,
246 ) -> Self {
247 Self {
248 block_html_block_behavior: behavior,
249 ..self
250 }
251 }
252
253 pub fn with_block_footnote_definition_behavior(
255 self,
256 behavior: ElementBehavior<crate::ast::Block>,
257 ) -> Self {
258 Self {
259 block_footnote_definition_behavior: behavior,
260 ..self
261 }
262 }
263
264 pub fn with_block_link_definition_behavior(
266 self,
267 behavior: ElementBehavior<crate::ast::Block>,
268 ) -> Self {
269 Self {
270 block_link_definition_behavior: behavior,
271 ..self
272 }
273 }
274
275 pub fn with_block_table_behavior(self, behavior: ElementBehavior<crate::ast::Block>) -> Self {
277 Self {
278 block_table_behavior: behavior,
279 ..self
280 }
281 }
282
283 pub fn with_block_paragraph_behavior(
285 self,
286 behavior: ElementBehavior<crate::ast::Block>,
287 ) -> Self {
288 Self {
289 block_paragraph_behavior: behavior,
290 ..self
291 }
292 }
293
294 pub fn with_inline_autolink_behavior(
296 self,
297 behavior: ElementBehavior<crate::ast::Inline>,
298 ) -> Self {
299 Self {
300 inline_autolink_behavior: behavior,
301 ..self
302 }
303 }
304
305 pub fn with_inline_link_behavior(self, behavior: ElementBehavior<crate::ast::Inline>) -> Self {
307 Self {
308 inline_link_behavior: behavior,
309 ..self
310 }
311 }
312
313 pub fn with_inline_footnote_reference_behavior(
315 self,
316 behavior: ElementBehavior<crate::ast::Inline>,
317 ) -> Self {
318 Self {
319 inline_footnote_reference_behavior: behavior,
320 ..self
321 }
322 }
323
324 pub fn with_inline_reference_link_behavior(
326 self,
327 behavior: ElementBehavior<crate::ast::Inline>,
328 ) -> Self {
329 Self {
330 inline_reference_link_behavior: behavior,
331 ..self
332 }
333 }
334
335 pub fn with_inline_hard_newline_behavior(
337 self,
338 behavior: ElementBehavior<crate::ast::Inline>,
339 ) -> Self {
340 Self {
341 inline_hard_newline_behavior: behavior,
342 ..self
343 }
344 }
345
346 pub fn with_inline_image_behavior(self, behavior: ElementBehavior<crate::ast::Inline>) -> Self {
348 Self {
349 inline_image_behavior: behavior,
350 ..self
351 }
352 }
353
354 pub fn with_inline_code_span_behavior(
356 self,
357 behavior: ElementBehavior<crate::ast::Inline>,
358 ) -> Self {
359 Self {
360 inline_code_span_behavior: behavior,
361 ..self
362 }
363 }
364
365 pub fn with_inline_emphasis_behavior(
367 self,
368 behavior: ElementBehavior<crate::ast::Inline>,
369 ) -> Self {
370 Self {
371 inline_emphasis_behavior: behavior,
372 ..self
373 }
374 }
375
376 pub fn with_inline_strikethrough_behavior(
378 self,
379 behavior: ElementBehavior<crate::ast::Inline>,
380 ) -> Self {
381 Self {
382 inline_strikethrough_behavior: behavior,
383 ..self
384 }
385 }
386
387 pub fn with_inline_text_behavior(self, behavior: ElementBehavior<crate::ast::Inline>) -> Self {
389 Self {
390 inline_text_behavior: behavior,
391 ..self
392 }
393 }
394
395 pub fn with_custom_block_parser(self, parser: CustomBlockParserFn) -> Self {
397 Self {
398 custom_block_parser: Some(parser),
399 ..self
400 }
401 }
402
403 pub fn with_custom_inline_parser(self, parser: CustomInlineParserFn) -> Self {
405 Self {
406 custom_inline_parser: Some(parser),
407 ..self
408 }
409 }
410}