@@ -108,6 +108,75 @@ impl PreProcessor for Clojure {
108108 }
109109 }
110110
111+ // Handle quote with a list, e.g.: `'(…)`
112+ // and with a vector, e.g.: `'[…]`
113+ b'\'' if matches ! ( cursor. next, b'[' | b'(' ) => {
114+ result[ cursor. pos ] = b' ' ;
115+ cursor. advance ( ) ;
116+ result[ cursor. pos ] = b' ' ;
117+ let end = match cursor. curr {
118+ b'[' => b']' ,
119+ b'(' => b')' ,
120+ _ => unreachable ! ( ) ,
121+ } ;
122+
123+ // Consume until the closing `]`
124+ while cursor. pos < len {
125+ match cursor. curr {
126+ x if x == end => {
127+ result[ cursor. pos ] = b' ' ;
128+ break ;
129+ }
130+
131+ // Consume strings as-is
132+ b'"' => {
133+ result[ cursor. pos ] = b' ' ;
134+ cursor. advance ( ) ;
135+
136+ while cursor. pos < len {
137+ match cursor. curr {
138+ // Escaped character, skip ahead to the next character
139+ b'\\' => cursor. advance_twice ( ) ,
140+
141+ // End of the string
142+ b'"' => {
143+ result[ cursor. pos ] = b' ' ;
144+ break ;
145+ }
146+
147+ // Everything else is valid
148+ _ => cursor. advance ( ) ,
149+ } ;
150+ }
151+ }
152+ _ => { }
153+ } ;
154+
155+ cursor. advance ( ) ;
156+ }
157+ }
158+
159+ // Handle quote with a keyword, e.g.: `'bg-white`
160+ b'\'' if !cursor. next . is_ascii_whitespace ( ) => {
161+ result[ cursor. pos ] = b' ' ;
162+ cursor. advance ( ) ;
163+
164+ while cursor. pos < len {
165+ match cursor. curr {
166+ // End of keyword.
167+ _ if !is_keyword_character ( cursor. curr ) => {
168+ result[ cursor. pos ] = b' ' ;
169+ break ;
170+ }
171+
172+ // Consume everything else.
173+ _ => { }
174+ } ;
175+
176+ cursor. advance ( ) ;
177+ }
178+ }
179+
111180 // Aggressively discard everything else, reducing false positives and preventing
112181 // characters surrounding keywords from producing false negatives.
113182 // E.g.:
@@ -281,4 +350,87 @@ mod tests {
281350 vec ! [ "py-5" , "flex" , "pr-1.5" , "bg-white" , "bg-black" ] ,
282351 ) ;
283352 }
353+
354+ // https://github.com/tailwindlabs/tailwindcss/issues/18882
355+ #[ test]
356+ fn test_extract_from_symbol_list ( ) {
357+ let input = r#"
358+ [:div {:class '[z-1 z-2
359+ z-3 z-4]}]
360+ "# ;
361+ Clojure :: test_extract_contains ( input, vec ! [ "z-1" , "z-2" , "z-3" , "z-4" ] ) ;
362+
363+ // https://github.com/tailwindlabs/tailwindcss/pull/18345#issuecomment-3253403847
364+ let input = r#"
365+ (def hl-class-names '[ring ring-blue-500])
366+
367+ [:div
368+ {:class (cond-> '[input w-full]
369+ textarea? (conj 'textarea)
370+ (seq errors) (concat '[border-red-500 bg-red-100])
371+ highlight? (concat hl-class-names))}]
372+ "# ;
373+ Clojure :: test_extract_contains (
374+ input,
375+ vec ! [
376+ "ring" ,
377+ "ring-blue-500" ,
378+ "input" ,
379+ "w-full" ,
380+ "textarea" ,
381+ "border-red-500" ,
382+ "bg-red-100" ,
383+ ] ,
384+ ) ;
385+
386+ let input = r#"
387+ [:div
388+ {:class '[h-100 lg:h-200 max-w-32 mx-auto py-60
389+ flex flex-col justify-end items-center
390+ lg:flex-row lg:justify-between
391+ bg-cover bg-center bg-no-repeat rounded-3xl overflow-hidden
392+ font-semibold text-gray-900]}]
393+ "# ;
394+ Clojure :: test_extract_contains (
395+ input,
396+ vec ! [
397+ "h-100" ,
398+ "lg:h-200" ,
399+ "max-w-32" ,
400+ "mx-auto" ,
401+ "py-60" ,
402+ "flex" ,
403+ "flex-col" ,
404+ "justify-end" ,
405+ "items-center" ,
406+ "lg:flex-row" ,
407+ "lg:justify-between" ,
408+ "bg-cover" ,
409+ "bg-center" ,
410+ "bg-no-repeat" ,
411+ "rounded-3xl" ,
412+ "overflow-hidden" ,
413+ "font-semibold" ,
414+ "text-gray-900" ,
415+ ] ,
416+ ) ;
417+
418+ // `/` is invalid and requires explicit quoting
419+ let input = r#"
420+ '[p-32 "text-black/50"]
421+ "# ;
422+ Clojure :: test_extract_contains ( input, vec ! [ "p-32" , "text-black/50" ] ) ;
423+
424+ // `[…]` is invalid and requires explicit quoting
425+ let input = r#"
426+ (print '[ring ring-blue-500 "bg-[#0088cc]"])
427+ "# ;
428+ Clojure :: test_extract_contains ( input, vec ! [ "ring" , "ring-blue-500" , "bg-[#0088cc]" ] ) ;
429+
430+ // `'(…)` looks similar to `[…]` but uses parentheses instead of brackets
431+ let input = r#"
432+ (print '(ring ring-blue-500 "bg-[#0088cc]"))
433+ "# ;
434+ Clojure :: test_extract_contains ( input, vec ! [ "ring" , "ring-blue-500" , "bg-[#0088cc]" ] ) ;
435+ }
284436}
0 commit comments