Skip to content

Commit 8d56381

Browse files
Detect classes in markdown inline directives (#18967)
Fixes #18071
1 parent d0f7f82 commit 8d56381

File tree

4 files changed

+67
-0
lines changed

4 files changed

+67
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2424
- Show Lightning CSS warnings (if any) when optimizing/minifying ([#18918](https://github.com/tailwindlabs/tailwindcss/pull/18918))
2525
- Use `default` export condition for `@tailwindcss/vite` ([#18948](https://github.com/tailwindlabs/tailwindcss/pull/18948))
2626
- Re-throw errors from PostCSS nodes ([#18373](https://github.com/tailwindlabs/tailwindcss/pull/18373))
27+
- Detect classes in markdown inline directives ([#18967](https://github.com/tailwindlabs/tailwindcss/pull/18967))
2728

2829
## [4.1.13] - 2025-09-03
2930

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
use crate::cursor;
2+
use crate::extractor::pre_processors::pre_processor::PreProcessor;
3+
4+
#[derive(Debug, Default)]
5+
pub struct Markdown;
6+
7+
impl PreProcessor for Markdown {
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+
let mut in_directive = false;
14+
15+
while cursor.pos < len {
16+
match (in_directive, cursor.curr) {
17+
(false, b'{') => {
18+
result[cursor.pos] = b' ';
19+
in_directive = true;
20+
}
21+
(true, b'}') => {
22+
result[cursor.pos] = b' ';
23+
in_directive = false;
24+
}
25+
(true, b'.') => {
26+
result[cursor.pos] = b' ';
27+
}
28+
_ => {}
29+
}
30+
31+
cursor.advance();
32+
}
33+
34+
result
35+
}
36+
}
37+
38+
#[cfg(test)]
39+
mod tests {
40+
use super::Markdown;
41+
use crate::extractor::pre_processors::pre_processor::PreProcessor;
42+
43+
#[test]
44+
fn test_markdown_pre_processor() {
45+
for (input, expected) in [
46+
// Convert dots to spaces inside markdown inline directives
47+
(
48+
":span[Some Text]{.text-gray-500}",
49+
":span[Some Text] text-gray-500 ",
50+
),
51+
(
52+
":span[Some Text]{.text-gray-500.bg-red-500}",
53+
":span[Some Text] text-gray-500 bg-red-500 ",
54+
),
55+
(
56+
":span[Some Text]{#myId .my-class key=val key2='val 2'}",
57+
":span[Some Text] #myId my-class key=val key2='val 2' ",
58+
),
59+
] {
60+
Markdown::test(input, expected);
61+
}
62+
}
63+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ pub mod clojure;
22
pub mod elixir;
33
pub mod haml;
44
pub mod json;
5+
pub mod markdown;
56
pub mod pre_processor;
67
pub mod pug;
78
pub mod razor;
@@ -14,6 +15,7 @@ pub use clojure::*;
1415
pub use elixir::*;
1516
pub use haml::*;
1617
pub use json::*;
18+
pub use markdown::*;
1719
pub use pre_processor::*;
1820
pub use pug::*;
1921
pub use razor::*;

crates/oxide/src/scanner/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -486,6 +486,7 @@ pub fn pre_process_input(content: &[u8], extension: &str) -> Vec<u8> {
486486
"cshtml" | "razor" => Razor.process(content),
487487
"haml" => Haml.process(content),
488488
"json" => Json.process(content),
489+
"md" | "mdx" => Markdown.process(content),
489490
"pug" => Pug.process(content),
490491
"rb" | "erb" => Ruby.process(content),
491492
"slim" | "slang" => Slim.process(content),

0 commit comments

Comments
 (0)