Skip to content

Commit 926f864

Browse files
authored
Improve visual sample and macro support for Crystal lexer (#1644)
The Crystal lexer does not include a very extensive visual sample. This commit adds a sample based on the one included in the Pygments lexer. As a result of testing with the sample, issues were identified with the lexing of macros and the `{%` and `%}` conditionals. These were fixed.
1 parent ddeab8e commit 926f864

File tree

2 files changed

+687
-40
lines changed

2 files changed

+687
-40
lines changed

lib/rouge/lexers/crystal.rb

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,7 @@ def self.detect?(text)
2525
)xi, Str::Symbol
2626

2727
# special symbols
28-
rule %r(:(?:\*\*|[-+]@|[/\%&\|^`~]|\[\]=?|<<|>>|<=?>|<=?|===?)),
29-
Str::Symbol
28+
rule %r(:(?:===|=?~|\[\][=?]?|\*\*=?|\/\/=?|[=^*/+-]=?|&[&*+-]?=?|\|\|?=?|![=~]?|%=?|<=>|<<?=?|>>?=?|\.\.\.?)), Str::Symbol
3029

3130
rule %r/:'(\\\\|\\'|[^'])*'/, Str::Symbol
3231
rule %r/:"/, Str::Symbol, :simple_sym
@@ -36,7 +35,7 @@ def self.detect?(text)
3635
# %-sigiled strings
3736
# %(abc), %[abc], %<abc>, %.abc., %r.abc., etc
3837
delimiter_map = { '{' => '}', '[' => ']', '(' => ')', '<' => '>' }
39-
rule %r/%([rqswQWxiI])?([^\w\s])/ do |m|
38+
rule %r/%([rqswQWxiI])?([^\w\s}])/ do |m|
4039
open = Regexp.escape(m[2])
4140
close = Regexp.escape(delimiter_map[m[2]] || m[2])
4241
interp = /[rQWxI]/ === m[1]
@@ -79,9 +78,11 @@ def self.detect?(text)
7978
state :strings do
8079
mixin :symbols
8180
rule %r/\b[a-z_]\w*?[?!]?:\s+/, Str::Symbol, :expr_start
82-
rule %r/'(\\\\|\\'|[^'])*'/, Str::Single
8381
rule %r/"/, Str::Double, :simple_string
8482
rule %r/(?<!\.)`/, Str::Backtick, :simple_backtick
83+
rule %r/(')(\\u[a-fA-F0-9]{4}|\\u\{[a-fA-F0-9]{1,6}\}|\\[abefnrtv])?(\\\\|\\'|[^'])*(')/ do
84+
groups Str::Single, Str::Escape, Str::Single, Str::Single
85+
end
8586
end
8687

8788
state :regex_flags do
@@ -154,11 +155,13 @@ def self.detect?(text)
154155
mixin :whitespace
155156
rule %r/__END__/, Comment::Preproc, :end_part
156157

157-
rule %r/0_?[0-7]+(?:_[0-7]+)*/, Num::Oct
158+
rule %r/0o[0-7]+(?:_[0-7]+)*/, Num::Oct
158159
rule %r/0x[0-9A-Fa-f]+(?:_[0-9A-Fa-f]+)*/, Num::Hex
159160
rule %r/0b[01]+(?:_[01]+)*/, Num::Bin
160-
rule %r/\d+\.\d+(e[\+\-]?\d+)?/, Num::Float
161-
rule %r/[\d]+(?:_\d+)*/, Num::Integer
161+
rule %r/\d+\.\d+(e[\+\-]?\d+)?(_f32)?/i, Num::Float
162+
rule %r/\d+(e[\+\-]?\d+)/i, Num::Float
163+
rule %r/\d+_f32/i, Num::Float
164+
rule %r/[\d]+(?:_\d+)*(_[iu]\d+)?/, Num::Integer
162165

163166
rule %r/@\[([^\]]+)\]/, Name::Decorator
164167

@@ -183,7 +186,7 @@ def self.detect?(text)
183186
groups Keyword, Text, Name::Namespace
184187
end
185188

186-
rule %r/(def\b)(\s*)/ do
189+
rule %r/(def|macro\b)(\s*)/ do
187190
groups Keyword, Text
188191
push :funcname
189192
end
@@ -214,6 +217,7 @@ def self.detect?(text)
214217
rule %r/[a-zA-Z_]\w*/, Name, :method_call
215218
rule %r/\*\*|\/\/|>=|<=|<=>|<<?|>>?|=~|={3}|!~|&&?|\|\||\./,
216219
Operator, :expr_start
220+
rule %r/{%|%}/, Punctuation
217221
rule %r/[-+\/*%=<>&!^|~]=?/, Operator, :expr_start
218222
rule(/[?]/) { token Punctuation; push :ternary; push :expr_start }
219223
rule %r<[\[({,:\\;/]>, Punctuation, :expr_start
@@ -346,6 +350,7 @@ def self.detect?(text)
346350
mixin :string_intp
347351
rule %r/\\([\\abefnrstv#"']|x[a-fA-F0-9]{1,2}|[0-7]{1,3})/,
348352
Str::Escape
353+
rule %r/\\u([a-fA-F0-9]{4}|\{[^}]+\})/, Str::Escape
349354
rule %r/\\./, Str::Escape
350355
end
351356

0 commit comments

Comments
 (0)