markdown_ppp/ast_transform/
generic_transformer.rs1use crate::ast::generic::*;
46
47pub trait GenericTransformer<T> {
52 fn transform_document(&mut self, doc: Document<T>) -> Document<T> {
54 self.walk_transform_document(doc)
55 }
56
57 fn transform_block(&mut self, block: Block<T>) -> Block<T> {
59 self.walk_transform_block(block)
60 }
61
62 fn transform_inline(&mut self, inline: Inline<T>) -> Inline<T> {
64 self.walk_transform_inline(inline)
65 }
66
67 fn transform_table_cell(&mut self, cell: TableCell<T>) -> TableCell<T> {
69 self.walk_transform_table_cell(cell)
70 }
71
72 fn transform_list_item(&mut self, item: ListItem<T>) -> ListItem<T> {
74 self.walk_transform_list_item(item)
75 }
76
77 fn transform_table_row(&mut self, row: TableRow<T>) -> TableRow<T> {
79 self.walk_transform_table_row(row)
80 }
81
82 fn transform_heading(&mut self, heading: Heading<T>) -> Heading<T> {
84 self.walk_transform_heading(heading)
85 }
86
87 fn transform_link(&mut self, link: Link<T>) -> Link<T> {
89 self.walk_transform_link(link)
90 }
91
92 fn transform_image(&mut self, image: Image<T>) -> Image<T> {
94 self.walk_transform_image(image)
95 }
96
97 fn transform_code_block(&mut self, code_block: CodeBlock<T>) -> CodeBlock<T> {
99 self.walk_transform_code_block(code_block)
100 }
101
102 fn transform_footnote_definition(
104 &mut self,
105 footnote: FootnoteDefinition<T>,
106 ) -> FootnoteDefinition<T> {
107 self.walk_transform_footnote_definition(footnote)
108 }
109
110 fn transform_github_alert(&mut self, alert: GitHubAlertNode<T>) -> GitHubAlertNode<T> {
112 self.walk_transform_github_alert(alert)
113 }
114
115 fn expand_document(&mut self, doc: Document<T>) -> Vec<Document<T>> {
121 vec![self.transform_document(doc)]
122 }
123
124 fn expand_block(&mut self, block: Block<T>) -> Vec<Block<T>> {
126 vec![self.transform_block(block)]
127 }
128
129 fn expand_inline(&mut self, inline: Inline<T>) -> Vec<Inline<T>> {
131 vec![self.transform_inline(inline)]
132 }
133
134 fn expand_table_cell(&mut self, cell: TableCell<T>) -> Vec<TableCell<T>> {
136 vec![self.transform_table_cell(cell)]
137 }
138
139 fn expand_list_item(&mut self, item: ListItem<T>) -> Vec<ListItem<T>> {
141 vec![self.transform_list_item(item)]
142 }
143
144 fn expand_table_row(&mut self, row: TableRow<T>) -> Vec<TableRow<T>> {
146 vec![self.transform_table_row(row)]
147 }
148
149 fn expand_heading(&mut self, heading: Heading<T>) -> Vec<Heading<T>> {
151 vec![self.transform_heading(heading)]
152 }
153
154 fn expand_link(&mut self, link: Link<T>) -> Vec<Link<T>> {
156 vec![self.transform_link(link)]
157 }
158
159 fn expand_image(&mut self, image: Image<T>) -> Vec<Image<T>> {
161 vec![self.transform_image(image)]
162 }
163
164 fn expand_code_block(&mut self, code_block: CodeBlock<T>) -> Vec<CodeBlock<T>> {
166 vec![self.transform_code_block(code_block)]
167 }
168
169 fn expand_footnote_definition(
171 &mut self,
172 footnote: FootnoteDefinition<T>,
173 ) -> Vec<FootnoteDefinition<T>> {
174 vec![self.transform_footnote_definition(footnote)]
175 }
176
177 fn expand_github_alert(&mut self, alert: GitHubAlertNode<T>) -> Vec<GitHubAlertNode<T>> {
179 vec![self.transform_github_alert(alert)]
180 }
181
182 fn walk_transform_document(&mut self, mut doc: Document<T>) -> Document<T> {
188 doc.blocks = doc
189 .blocks
190 .into_iter()
191 .map(|block| self.transform_block(block))
192 .collect();
193 doc
194 }
195
196 fn walk_transform_block(&mut self, block: Block<T>) -> Block<T> {
198 match block {
199 Block::Paragraph { content, user_data } => Block::Paragraph {
200 content: content
201 .into_iter()
202 .map(|inline| self.transform_inline(inline))
203 .collect(),
204 user_data,
205 },
206 Block::Heading(heading) => Block::Heading(self.transform_heading(heading)),
207 Block::BlockQuote { blocks, user_data } => Block::BlockQuote {
208 blocks: blocks
209 .into_iter()
210 .map(|block| self.transform_block(block))
211 .collect(),
212 user_data,
213 },
214 Block::List(list) => Block::List(self.transform_list_item_container(list)),
215 Block::Table(table) => Block::Table(self.transform_table(table)),
216 Block::FootnoteDefinition(footnote) => {
217 Block::FootnoteDefinition(self.transform_footnote_definition(footnote))
218 }
219 Block::GitHubAlert(alert) => Block::GitHubAlert(self.transform_github_alert(alert)),
220 Block::Definition(mut def) => {
221 def.label = def
222 .label
223 .into_iter()
224 .map(|inline| self.transform_inline(inline))
225 .collect();
226 Block::Definition(def)
227 }
228 Block::CodeBlock(code_block) => Block::CodeBlock(self.transform_code_block(code_block)),
229 other => other,
231 }
232 }
233
234 fn walk_transform_inline(&mut self, inline: Inline<T>) -> Inline<T> {
236 match inline {
237 Inline::Emphasis { content, user_data } => Inline::Emphasis {
238 content: content
239 .into_iter()
240 .map(|inline| self.transform_inline(inline))
241 .collect(),
242 user_data,
243 },
244 Inline::Strong { content, user_data } => Inline::Strong {
245 content: content
246 .into_iter()
247 .map(|inline| self.transform_inline(inline))
248 .collect(),
249 user_data,
250 },
251 Inline::Strikethrough { content, user_data } => Inline::Strikethrough {
252 content: content
253 .into_iter()
254 .map(|inline| self.transform_inline(inline))
255 .collect(),
256 user_data,
257 },
258 Inline::Link(link) => Inline::Link(self.transform_link(link)),
259 Inline::LinkReference(mut link_ref) => {
260 link_ref.label = link_ref
261 .label
262 .into_iter()
263 .map(|inline| self.transform_inline(inline))
264 .collect();
265 link_ref.text = link_ref
266 .text
267 .into_iter()
268 .map(|inline| self.transform_inline(inline))
269 .collect();
270 Inline::LinkReference(link_ref)
271 }
272 Inline::Image(image) => Inline::Image(self.transform_image(image)),
273 other => other,
275 }
276 }
277
278 fn walk_transform_table_cell(&mut self, cell: TableCell<T>) -> TableCell<T> {
280 cell.into_iter()
281 .map(|inline| self.transform_inline(inline))
282 .collect()
283 }
284
285 fn walk_transform_list_item(&mut self, mut item: ListItem<T>) -> ListItem<T> {
287 item.blocks = item
288 .blocks
289 .into_iter()
290 .map(|block| self.transform_block(block))
291 .collect();
292 item
293 }
294
295 fn walk_transform_table_row(&mut self, row: TableRow<T>) -> TableRow<T> {
297 row.into_iter()
298 .map(|cell| self.transform_table_cell(cell))
299 .collect()
300 }
301
302 fn walk_transform_heading(&mut self, mut heading: Heading<T>) -> Heading<T> {
304 heading.content = heading
305 .content
306 .into_iter()
307 .map(|inline| self.transform_inline(inline))
308 .collect();
309 heading
310 }
311
312 fn walk_transform_link(&mut self, mut link: Link<T>) -> Link<T> {
314 link.children = link
315 .children
316 .into_iter()
317 .map(|inline| self.transform_inline(inline))
318 .collect();
319 link
320 }
321
322 fn walk_transform_image(&mut self, image: Image<T>) -> Image<T> {
324 image
326 }
327
328 fn walk_transform_code_block(&mut self, code_block: CodeBlock<T>) -> CodeBlock<T> {
330 code_block
332 }
333
334 fn walk_transform_footnote_definition(
336 &mut self,
337 mut footnote: FootnoteDefinition<T>,
338 ) -> FootnoteDefinition<T> {
339 footnote.blocks = footnote
340 .blocks
341 .into_iter()
342 .map(|block| self.transform_block(block))
343 .collect();
344 footnote
345 }
346
347 fn walk_transform_github_alert(&mut self, mut alert: GitHubAlertNode<T>) -> GitHubAlertNode<T> {
349 alert.blocks = alert
350 .blocks
351 .into_iter()
352 .map(|block| self.transform_block(block))
353 .collect();
354 alert
355 }
356
357 fn transform_list_item_container(&mut self, mut list: List<T>) -> List<T> {
361 list.items = list
362 .items
363 .into_iter()
364 .map(|item| self.transform_list_item(item))
365 .collect();
366 list
367 }
368
369 fn transform_table(&mut self, mut table: Table<T>) -> Table<T> {
371 table.rows = table
372 .rows
373 .into_iter()
374 .map(|row| self.transform_table_row(row))
375 .collect();
376 table
377 }
378
379 fn walk_expand_document(&mut self, mut doc: Document<T>) -> Vec<Document<T>> {
385 doc.blocks = doc
386 .blocks
387 .into_iter()
388 .flat_map(|block| self.walk_expand_block(block))
389 .collect();
390 vec![doc]
391 }
392
393 fn walk_expand_block(&mut self, block: Block<T>) -> Vec<Block<T>> {
395 let transformed_block = match block {
396 Block::Paragraph { content, user_data } => Block::Paragraph {
397 content: content
398 .into_iter()
399 .flat_map(|inline| self.walk_expand_inline(inline))
400 .collect(),
401 user_data,
402 },
403 Block::Heading(heading) => {
404 let expanded_headings = self.expand_heading(heading);
405 return expanded_headings.into_iter().map(Block::Heading).collect();
406 }
407 Block::BlockQuote { blocks, user_data } => Block::BlockQuote {
408 blocks: blocks
409 .into_iter()
410 .flat_map(|block| self.walk_expand_block(block))
411 .collect(),
412 user_data,
413 },
414 Block::List(list) => {
415 let expanded_list = self.expand_list_container(list);
416 return expanded_list.into_iter().map(Block::List).collect();
417 }
418 Block::Table(table) => {
419 let expanded_table = self.expand_table_container(table);
420 return expanded_table.into_iter().map(Block::Table).collect();
421 }
422 Block::FootnoteDefinition(footnote) => {
423 let expanded_footnotes = self.expand_footnote_definition(footnote);
424 return expanded_footnotes
425 .into_iter()
426 .map(Block::FootnoteDefinition)
427 .collect();
428 }
429 Block::GitHubAlert(alert) => {
430 let expanded_alerts = self.expand_github_alert(alert);
431 return expanded_alerts
432 .into_iter()
433 .map(Block::GitHubAlert)
434 .collect();
435 }
436 Block::Definition(mut def) => {
437 def.label = def
438 .label
439 .into_iter()
440 .flat_map(|inline| self.walk_expand_inline(inline))
441 .collect();
442 Block::Definition(def)
443 }
444 Block::CodeBlock(code_block) => {
445 let expanded_code_blocks = self.expand_code_block(code_block);
446 return expanded_code_blocks
447 .into_iter()
448 .map(Block::CodeBlock)
449 .collect();
450 }
451 other => other,
453 };
454 vec![transformed_block]
455 }
456
457 fn walk_expand_inline(&mut self, inline: Inline<T>) -> Vec<Inline<T>> {
459 let transformed_inline = match inline {
460 Inline::Emphasis { content, user_data } => Inline::Emphasis {
461 content: content
462 .into_iter()
463 .flat_map(|inline| self.walk_expand_inline(inline))
464 .collect(),
465 user_data,
466 },
467 Inline::Strong { content, user_data } => Inline::Strong {
468 content: content
469 .into_iter()
470 .flat_map(|inline| self.walk_expand_inline(inline))
471 .collect(),
472 user_data,
473 },
474 Inline::Strikethrough { content, user_data } => Inline::Strikethrough {
475 content: content
476 .into_iter()
477 .flat_map(|inline| self.walk_expand_inline(inline))
478 .collect(),
479 user_data,
480 },
481 Inline::Link(link) => {
482 let expanded_links = self.expand_link(link);
483 return expanded_links.into_iter().map(Inline::Link).collect();
484 }
485 Inline::LinkReference(mut link_ref) => {
486 link_ref.label = link_ref
487 .label
488 .into_iter()
489 .flat_map(|inline| self.walk_expand_inline(inline))
490 .collect();
491 link_ref.text = link_ref
492 .text
493 .into_iter()
494 .flat_map(|inline| self.walk_expand_inline(inline))
495 .collect();
496 Inline::LinkReference(link_ref)
497 }
498 Inline::Image(image) => {
499 let expanded_images = self.expand_image(image);
500 return expanded_images.into_iter().map(Inline::Image).collect();
501 }
502 other => other,
504 };
505 vec![transformed_inline]
506 }
507
508 fn expand_list_container(&mut self, mut list: List<T>) -> Vec<List<T>> {
512 list.items = list
513 .items
514 .into_iter()
515 .flat_map(|item| self.expand_list_item(item))
516 .collect();
517 vec![list]
518 }
519
520 fn expand_table_container(&mut self, mut table: Table<T>) -> Vec<Table<T>> {
522 table.rows = table
523 .rows
524 .into_iter()
525 .flat_map(|row| self.expand_table_row(row))
526 .collect();
527 vec![table]
528 }
529}
530
531pub trait GenericTransformWith<T> {
533 fn transform_with<Tr: GenericTransformer<T>>(self, transformer: &mut Tr) -> Self;
535}
536
537impl<T> GenericTransformWith<T> for Document<T> {
538 fn transform_with<Tr: GenericTransformer<T>>(self, transformer: &mut Tr) -> Self {
539 transformer.transform_document(self)
540 }
541}
542
543impl<T> GenericTransformWith<T> for Block<T> {
544 fn transform_with<Tr: GenericTransformer<T>>(self, transformer: &mut Tr) -> Self {
545 transformer.transform_block(self)
546 }
547}
548
549impl<T> GenericTransformWith<T> for Inline<T> {
550 fn transform_with<Tr: GenericTransformer<T>>(self, transformer: &mut Tr) -> Self {
551 transformer.transform_inline(self)
552 }
553}
554
555pub trait GenericExpandWith<T> {
557 fn expand_with<Tr: GenericTransformer<T>>(self, transformer: &mut Tr) -> Vec<Self>
559 where
560 Self: Sized;
561}
562
563impl<T> GenericExpandWith<T> for Document<T> {
564 fn expand_with<Tr: GenericTransformer<T>>(self, transformer: &mut Tr) -> Vec<Self> {
565 transformer.walk_expand_document(self)
566 }
567}
568
569impl<T> GenericExpandWith<T> for Block<T> {
570 fn expand_with<Tr: GenericTransformer<T>>(self, transformer: &mut Tr) -> Vec<Self> {
571 transformer.walk_expand_block(self)
572 }
573}
574
575impl<T> GenericExpandWith<T> for Inline<T> {
576 fn expand_with<Tr: GenericTransformer<T>>(self, transformer: &mut Tr) -> Vec<Self> {
577 transformer.walk_expand_inline(self)
578 }
579}