markdown_code_runner/
standardize.rs1use once_cell::sync::Lazy;
4use regex::Regex;
5
6static STANDARDIZE_PATTERN: Lazy<Regex> =
8 Lazy::new(|| Regex::new(r"^(```\w+)\s+markdown-code-runner(?:\s+\S+=\S+)*\s*$").unwrap());
9
10pub fn standardize_code_fences(content: &str) -> String {
26 let mut result = String::new();
27 for line in content.lines() {
28 if let Some(caps) = STANDARDIZE_PATTERN.captures(line) {
29 result.push_str(&caps[1]);
30 } else {
31 result.push_str(line);
32 }
33 result.push('\n');
34 }
35 if !content.ends_with('\n') && result.ends_with('\n') {
37 result.pop();
38 }
39 result
40}
41
42#[cfg(test)]
43mod tests {
44 use super::*;
45
46 #[test]
47 fn test_standardize_basic() {
48 let content = "```python markdown-code-runner\nprint('hello')\n```";
49 let expected = "```python\nprint('hello')\n```";
50 assert_eq!(standardize_code_fences(content), expected);
51 }
52
53 #[test]
54 fn test_standardize_with_options() {
55 let content = "```python markdown-code-runner filename=test.py debug=true\ncode here\n```";
56 let expected = "```python\ncode here\n```";
57 assert_eq!(standardize_code_fences(content), expected);
58 }
59
60 #[test]
61 fn test_standardize_multiple() {
62 let content = r#"```python markdown-code-runner
63first
64```
65text
66```bash markdown-code-runner
67second
68```
69more text
70```rust markdown-code-runner filename=test.rs
71third
72```"#;
73 let expected = r#"```python
74first
75```
76text
77```bash
78second
79```
80more text
81```rust
82third
83```"#;
84 assert_eq!(standardize_code_fences(content), expected);
85 }
86
87 #[test]
88 fn test_standardize_preserves_text_references() {
89 let content =
90 "Using `markdown-code-runner` is easy.\n```python markdown-code-runner\ncode\n```";
91 let expected = "Using `markdown-code-runner` is easy.\n```python\ncode\n```";
92 assert_eq!(standardize_code_fences(content), expected);
93 }
94
95 #[test]
96 fn test_standardize_leaves_normal_fences() {
97 let content = "```python\ncode\n```\n```javascript\nmore\n```";
98 assert_eq!(standardize_code_fences(content), content);
99 }
100}