dmc_transform/builtin/
disable_gfm.rs1use crate::pipeline::Transformer;
2use dmc_diagnostic::{Code, metadata::SourceMeta};
3use dmc_parser::ast::*;
4
5#[derive(Default)]
9pub struct DisableGfm;
10
11impl Transformer for DisableGfm {
12 fn name(&self) -> &str {
13 "disable-gfm"
14 }
15 fn transform(
16 &self,
17 doc: &mut Document,
18 _meta: &SourceMeta,
19 _diag_engine: &mut duck_diagnostic::DiagnosticEngine<Code>,
20 ) {
21 Self::rewrite(&mut doc.children);
22 }
23}
24
25impl DisableGfm {
26 fn rewrite(nodes: &mut [Node]) {
29 for node in nodes.iter_mut() {
30 match node {
31 Node::Strikethrough(inner) => {
32 let span = inner.span.clone();
33 Self::rewrite(&mut inner.children);
34 let mut buf = String::from("~~");
35 Self::flatten(&inner.children, &mut buf);
36 buf.push_str("~~");
37 *node = Node::Text(Text { value: buf, span });
38 },
39 Node::Table(t) => {
40 let span = t.span.clone();
41 let mut buf = String::new();
42 for row in &t.children {
43 for (i, cell) in row.cells.iter().enumerate() {
44 if i > 0 {
45 buf.push_str(" | ");
46 }
47 Self::flatten(&cell.children, &mut buf);
48 }
49 buf.push('\n');
50 }
51 *node =
52 Node::Paragraph(Paragraph { children: vec![Node::Text(Text { value: buf, span: span.clone() })], span });
53 },
54 Node::TaskListItem(it) => {
55 let span = it.span.clone();
56 Self::rewrite(&mut it.children);
57 let prefix = if it.checked { "[x] " } else { "[ ] " };
58 let mut new_li = ListItem { children: it.children.clone(), span: span.clone() };
59 if let Some(Node::Paragraph(p)) = new_li.children.first_mut() {
60 p.children.insert(0, Node::Text(Text { value: prefix.into(), span }));
61 } else {
62 new_li.children.insert(0, Node::Text(Text { value: prefix.into(), span }));
63 }
64 *node = Node::ListItem(new_li);
65 },
66 Node::Paragraph(p) => Self::rewrite(&mut p.children),
67 Node::Heading(h) => Self::rewrite(&mut h.children),
68 Node::Bold(i) | Node::Italic(i) => Self::rewrite(&mut i.children),
69 Node::List(l) => Self::rewrite(&mut l.children),
70 Node::ListItem(li) => Self::rewrite(&mut li.children),
71 Node::Blockquote(b) => Self::rewrite(&mut b.children),
72 Node::Link(l) => Self::rewrite(&mut l.children),
73 Node::JsxElement(j) => Self::rewrite(&mut j.children),
74 Node::JsxFragment(f) => Self::rewrite(&mut f.children),
75 _ => {},
76 }
77 }
78 }
79
80 fn flatten(nodes: &[Node], buf: &mut String) {
82 for n in nodes {
83 match n {
84 Node::Text(t) => buf.push_str(&t.value),
85 Node::InlineCode(c) => {
86 buf.push('`');
87 buf.push_str(&c.value);
88 buf.push('`');
89 },
90 Node::Bold(i) => {
91 buf.push_str("**");
92 Self::flatten(&i.children, buf);
93 buf.push_str("**");
94 },
95 Node::Italic(i) => {
96 buf.push('*');
97 Self::flatten(&i.children, buf);
98 buf.push('*');
99 },
100 Node::Link(l) => {
101 buf.push('[');
102 Self::flatten(&l.children, buf);
103 buf.push_str("](");
104 buf.push_str(&l.href);
105 buf.push(')');
106 },
107 _ => {},
108 }
109 }
110 }
111}