Skip to content

Adds support for nested CSS and color rebeccapurple#2150

Draft
dylanbeattie wants to merge 7 commits intorouge-ruby:masterfrom
dylanbeattie:nested-css
Draft

Adds support for nested CSS and color rebeccapurple#2150
dylanbeattie wants to merge 7 commits intorouge-ruby:masterfrom
dylanbeattie:nested-css

Conversation

@dylanbeattie
Copy link

@dylanbeattie dylanbeattie commented Aug 3, 2025

This PR adds support for CSS nesting, which has had baseline support across all major browsers since 2023 (https://caniuse.com/css-nesting) but doesn't seem to be supported in rouge yet.

image

The first pass at this was written using Copilot with Claude Sonnet 4, which got the selector syntax and the actual lexer rule pretty much spot-on; I've moved a few things around, cleaned up a bunch of extraneous test code, fixed up the quote style and indentation and verified it using the rackup visualiser.

I've also added rebeccapurple to the list of CSS colors (https://drafts.csswg.org/css-color/#valdef-color-rebeccapurple)

Improves CSS lexer to correctly highlight nested CSS rules, including those using parent selector references (&), pseudo-classes, and within media queries.

This enhancement provides more accurate syntax highlighting for modern CSS practices, specifically addressing nested structures.
Consolidates CSS lexer specs, improving organization and readability.

Removes redundant test files and cleans up visual samples.
Refactors the CSS nesting example for better readability and conciseness by removing unnecessary styles.
Updates the lexer's list of recognized CSS color keywords to include "rebeccapurple".
@dylanbeattie dylanbeattie marked this pull request as draft August 9, 2025 14:08
@dylanbeattie
Copy link
Author

dylanbeattie commented Aug 9, 2025

Found a bunch of edge cases this doesn't support yet... I've marked the PR as draft until I've figured out how to add support for those. The current version of the lexer doesn't recognise li::marker or li:nth-child(2n)::marker as valid selectors.

ul {
  li::marker {
    color: royalblue;
  }
  li:nth-child(2n)::marker {
    color: crimson;
  }
}

rule %r/}/, Punctuation, :pop!

# Handle nested rules by checking for selectors followed by opening brace
rule %r/(&?(?:[.#:]?#{identifier}|[*&]|:[:]?#{identifier}|\[[^\]]*\]|::?#{identifier})[^{:;]*){/m do |m|
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be simpler to mixin :root here? Or factor out part of :root to mix in?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants