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