Skip to content

Commit 062d635

Browse files
committed
add Clojure/ClojureScript pre processor
1 parent 7005ad7 commit 062d635

File tree

3 files changed

+132
-0
lines changed

3 files changed

+132
-0
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
use crate::cursor;
2+
use crate::extractor::pre_processors::pre_processor::PreProcessor;
3+
4+
#[derive(Debug, Default)]
5+
pub struct Clojure;
6+
7+
impl PreProcessor for Clojure {
8+
fn process(&self, content: &[u8]) -> Vec<u8> {
9+
let len = content.len();
10+
let mut result = content.to_vec();
11+
let mut cursor = cursor::Cursor::new(content);
12+
13+
while cursor.pos < len {
14+
match cursor.curr {
15+
// Consume strings as-is
16+
b'"' => {
17+
let len = cursor.input.len();
18+
cursor.advance();
19+
20+
while cursor.pos < len {
21+
match cursor.curr {
22+
// Escaped character, skip ahead to the next character
23+
b'\\' => cursor.advance_twice(),
24+
25+
// End of the string
26+
b'"' => break,
27+
28+
// Everything else is valid
29+
_ => cursor.advance(),
30+
};
31+
}
32+
}
33+
34+
b':' | b'.' => {
35+
result[cursor.pos] = b' ';
36+
}
37+
38+
// Consume everything else
39+
_ => {}
40+
};
41+
42+
cursor.advance();
43+
}
44+
45+
result
46+
}
47+
}
48+
49+
#[cfg(test)]
50+
mod tests {
51+
use super::Clojure;
52+
use crate::extractor::pre_processors::pre_processor::PreProcessor;
53+
54+
#[test]
55+
fn test_clojure_pre_processor() {
56+
for (input, expected) in [
57+
(":div.flex-1.flex-2", " div flex-1 flex-2"),
58+
(
59+
":.flex-3.flex-4 ;defaults to div",
60+
" flex-3 flex-4 ;defaults to div",
61+
),
62+
("{:class :flex-5.flex-6", "{ class flex-5 flex-6"),
63+
(r#"{:class "flex-7 flex-8"}"#, r#"{ class "flex-7 flex-8"}"#),
64+
(
65+
r#"{:class ["flex-9" :flex-10]}"#,
66+
r#"{ class ["flex-9" flex-10]}"#,
67+
),
68+
(
69+
r#"(dom/div {:class "flex-11 flex-12"})"#,
70+
r#"(dom/div { class "flex-11 flex-12"})"#,
71+
),
72+
("(dom/div :.flex-13.flex-14", "(dom/div flex-13 flex-14"),
73+
] {
74+
Clojure::test(input, expected);
75+
}
76+
}
77+
78+
#[test]
79+
fn test_extract_candidates() {
80+
// https://github.com/luckasRanarison/tailwind-tools.nvim/issues/68#issuecomment-2660951258
81+
let input = r#"
82+
:div.c1.c2
83+
:.c3.c4 ;defaults to div
84+
{:class :c5.c6
85+
{:class "c7 c8"}
86+
{:class ["c9" :c10]}
87+
(dom/div {:class "c11 c12"})
88+
(dom/div :.c13.c14
89+
"#;
90+
91+
Clojure::test_extract_contains(
92+
input,
93+
vec![
94+
"c1", "c2", "c3", "c4", "c5", "c6", "c7", "c8", "c9", "c10", "c11", "c12", "c13",
95+
"c14",
96+
],
97+
);
98+
99+
// Similar structure but using a real classes
100+
let input = r#"
101+
:div.flex-1.flex-2
102+
:.flex-3.flex-4 ;defaults to div
103+
{:class :flex-5.flex-6
104+
{:class "flex-7 flex-8"}
105+
{:class ["flex-9" :flex-10]}
106+
(dom/div {:class "flex-11 flex-12"})
107+
(dom/div :.flex-13.flex-14
108+
"#;
109+
110+
Clojure::test_extract_contains(
111+
input,
112+
vec![
113+
"flex-1", "flex-2", "flex-3", "flex-4", "flex-5", "flex-6", "flex-7", "flex-8",
114+
"flex-9", "flex-10", "flex-11", "flex-12", "flex-13", "flex-14",
115+
],
116+
);
117+
}
118+
119+
#[test]
120+
fn test_special_characters_are_valid_in_strings() {
121+
// In this case the `:` and `.` should not be replaced by ` ` because they are inside a
122+
// string.
123+
let input = r#"
124+
(dom/div {:class "hover:flex px-1.5"})
125+
"#;
126+
127+
Clojure::test_extract_contains(input, vec!["hover:flex", "px-1.5"]);
128+
}
129+
}

crates/oxide/src/extractor/pre_processors/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub mod clojure;
12
pub mod haml;
23
pub mod pre_processor;
34
pub mod pug;
@@ -6,6 +7,7 @@ pub mod ruby;
67
pub mod slim;
78
pub mod svelte;
89

10+
pub use clojure::*;
911
pub use haml::*;
1012
pub use pre_processor::*;
1113
pub use pug::*;

crates/oxide/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,7 @@ pub fn pre_process_input(content: &[u8], extension: &str) -> Vec<u8> {
468468
use crate::extractor::pre_processors::*;
469469

470470
match extension {
471+
"clj" | "cljs" | "cljc" => Clojure.process(content),
471472
"cshtml" | "razor" => Razor.process(content),
472473
"haml" => Haml.process(content),
473474
"pug" => Pug.process(content),

0 commit comments

Comments
 (0)