Handle Ruby %w syntax in Slim pre processing (#17557)

This PR fixes an issue where the Ruby `%w[…]` syntax causes utilities to
not be properly extracted.

This PR will now ensure that it does get extracted correctly.

Given this input:
```slim
div[
  class=%w[bg-blue-500 w-10 h-10]
]
div[
  class=%w[w-10 bg-green-500 h-10]
]
```

Before this PR, we extracted everything but the `bg-blue-500`. The
`w-10` was extracted but not because of the second div, but because of
the first one.

Fixes: #17542

## Test plan

1. Added a test to ensure it's working correctly.

Looking at the extractor tool, you can see that it now gets extracted
correctly. Top is before, bottom is with this change.

<img width="1199" alt="image"
src="https://github.com/user-attachments/assets/028d9abd-8917-438c-a423-88ba887b7f97"
/>
This commit is contained in:
Robin Malfait 2025-04-04 17:21:35 +02:00 • committed by GitHub
parent e085977844
commit 7d317251f2
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 48 additions and 0 deletions

View file

@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Show warning when using unsupported bare value data type in `--value(…)` ([#17464](https://github.com/tailwindlabs/tailwindcss/pull/17464))
- PostCSS: Resolve an issue where changes to the input CSS file showed outdated content when using Turbopack ([#17554](https://github.com/tailwindlabs/tailwindcss/pull/17554))
- Handle Ruby `%w` syntax in Slim pre processing ([#17557](https://github.com/tailwindlabs/tailwindcss/pull/17557))
## [4.1.2] - 2025-04-03

View file

@ -56,6 +56,28 @@ impl PreProcessor for Slim {
}
}
// Handle Ruby syntax with `%w[]` arrays embedded in Slim directly.
//
// E.g.:
//
// ```
// div [
// class=%w[bg-blue-500 w-10 h-10]
// ]
// ```
b'%' if matches!(cursor.next, b'w' | b'W')
&& matches!(cursor.input.get(cursor.pos + 2), Some(b'[' | b'(' | b'{')) =>
{
result[cursor.pos] = b' '; // Replace `%`
cursor.advance();
result[cursor.pos] = b' '; // Replace `w`
cursor.advance();
result[cursor.pos] = b' '; // Replace `[` or `(` or `{`
bracket_stack.push(cursor.curr);
cursor.advance(); // Move past the bracket
continue;
}
// Any `[` preceded by an alphanumeric value will not be part of a candidate.
//
// E.g.:
@ -281,4 +303,29 @@ mod tests {
"#;
Slim::test_extract_contains(input, vec!["flex", "items-center"]);
}
// https://github.com/tailwindlabs/tailwindcss/issues/17542
#[test]
fn test_embedded_ruby_percent_w_extraction() {
let input = r#"
div[
class=%w[bg-blue-500 w-10 h-10]
]
div[
class=%w[w-10 bg-green-500 h-10]
]
"#;
let expected = r#"
div
class= bg-blue-500 w-10 h-10]
]
div
class= w-10 bg-green-500 h-10]
]
"#;
Slim::test(input, expected);
Slim::test_extract_contains(input, vec!["bg-blue-500", "bg-green-500", "w-10", "h-10"]);
}
}