Skip to content

Commit 71fdc0d

Browse files
committed
fix(ruby): properly highlight nested %r{} regex
Previously, the Ruby grammar only recognized %r{} regex literals in limited contexts, causing patterns like %r{(\.{2}|\A/)} to break syntax highlighting. This fix: - Adds a top-level REGEXP mode to support all %r{} variations globally - Enables nested brace handling inside %r{...} - Removes redundant %r handling tied to RE_STARTERS_RE - Adds a test case to regexes.txt to prevent regression
1 parent 98b649f commit 71fdc0d

File tree

4 files changed

+26
-16
lines changed

4 files changed

+26
-16
lines changed

CHANGES.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ Core Grammars:
2525
- enh(json) add json5 support [Kerry Shetline][]
2626
- fix(css) `unicode-range` parsing, issue #4253 [Kerry Shetline][]
2727
- fix(csharp) Support digit separators [te-ing][]
28+
- fix(ruby) support nested content in `%r{}` regex literals outside expression contexts [Jacques Erasmus][]
2829

2930
Documentation:
3031

@@ -53,6 +54,7 @@ CONTRIBUTORS
5354
[Thomas Gorissen]: https://github.com/serrynaimo
5455
[te-ing]: https://github.com/te-ing
5556
[Anthony Martin]: https://github.com/anthony-c-martin
57+
[Jacques Erasmus]: https://github.com/j-erasmus
5658

5759

5860
## Version 11.11.1

src/languages/ruby.js

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,27 @@ export default function(hljs) {
227227
]
228228
};
229229

230+
const REGEXP = {
231+
className: 'regexp',
232+
contains: [
233+
hljs.BACKSLASH_ESCAPE,
234+
SUBST,
235+
{
236+
begin: /\{/, end: /\}/,
237+
contains: ['self', hljs.BACKSLASH_ESCAPE, SUBST],
238+
relevance: 0
239+
}
240+
],
241+
illegal: /\n/,
242+
variants: [
243+
{ begin: /%r\{/, end: /\}[a-z]*/ },
244+
{ begin: '%r\\(', end: '\\)[a-z]*' },
245+
{ begin: '%r!', end: '![a-z]*' },
246+
{ begin: '%r\\[', end: '\\][a-z]*' },
247+
{ begin: '/', end: '/[a-z]*' }
248+
]
249+
};
250+
230251
const PARAMS = {
231252
variants: [
232253
{
@@ -324,6 +345,7 @@ export default function(hljs) {
324345
UPPER_CASE_CONSTANT,
325346
CLASS_REFERENCE,
326347
METHOD_DEFINITION,
348+
REGEXP,
327349
{
328350
// swallow namespace qualifiers before symbols
329351
begin: hljs.IDENT_RE + '::' },
@@ -372,22 +394,6 @@ export default function(hljs) {
372394
{
373395
begin: '/',
374396
end: '/[a-z]*'
375-
},
376-
{
377-
begin: /%r\{/,
378-
end: /\}[a-z]*/
379-
},
380-
{
381-
begin: '%r\\(',
382-
end: '\\)[a-z]*'
383-
},
384-
{
385-
begin: '%r!',
386-
end: '![a-z]*'
387-
},
388-
{
389-
begin: '%r\\[',
390-
end: '\\][a-z]*'
391397
}
392398
]
393399
}

test/markup/ruby/regexes.expect.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ str =~ <span class="hljs-regexp">%r{foo|bar|buz$}</span>
33
str =~ <span class="hljs-regexp">%r!foo|bar$!</span>
44
str =~ <span class="hljs-regexp">%r[foo|bar$]</span>
55
str =~ <span class="hljs-regexp">%r(\(foo|bar\)$)</span>
6+
str =~ <span class="hljs-regexp">%r{(\.{2}|\A/)}</span>

test/markup/ruby/regexes.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,4 @@ str =~ %r{foo|bar|buz$}
33
str =~ %r!foo|bar$!
44
str =~ %r[foo|bar$]
55
str =~ %r(\(foo|bar\)$)
6+
str =~ %r{(\.{2}|\A/)}

0 commit comments

Comments
 (0)