rouge 3.19.0 → 3.26.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/rouge.rb +1 -0
- data/lib/rouge/cli.rb +32 -2
- data/lib/rouge/demos/augeas +16 -0
- data/lib/rouge/demos/bibtex +12 -0
- data/lib/rouge/demos/brightscript +6 -0
- data/lib/rouge/demos/email +11 -0
- data/lib/rouge/demos/hlsl +20 -0
- data/lib/rouge/demos/j +12 -0
- data/lib/rouge/demos/janet +3 -0
- data/lib/rouge/demos/livescript +15 -0
- data/lib/rouge/demos/ocl +4 -0
- data/lib/rouge/demos/postscript +9 -0
- data/lib/rouge/demos/rescript +26 -0
- data/lib/rouge/demos/ssh +4 -0
- data/lib/rouge/demos/systemd +4 -0
- data/lib/rouge/demos/velocity +9 -0
- data/lib/rouge/demos/zig +6 -0
- data/lib/rouge/formatters/html_line_highlighter.rb +24 -0
- data/lib/rouge/formatters/html_line_table.rb +1 -3
- data/lib/rouge/formatters/html_linewise.rb +2 -3
- data/lib/rouge/lexer.rb +38 -20
- data/lib/rouge/lexers/apex.rb +9 -7
- data/lib/rouge/lexers/augeas.rb +93 -0
- data/lib/rouge/lexers/batchfile.rb +3 -2
- data/lib/rouge/lexers/bibtex.rb +115 -0
- data/lib/rouge/lexers/brightscript.rb +147 -0
- data/lib/rouge/lexers/cmake.rb +10 -0
- data/lib/rouge/lexers/cpp.rb +12 -5
- data/lib/rouge/lexers/crystal.rb +14 -9
- data/lib/rouge/lexers/css.rb +3 -1
- data/lib/rouge/lexers/diff.rb +1 -1
- data/lib/rouge/lexers/docker.rb +2 -2
- data/lib/rouge/lexers/elm.rb +5 -5
- data/lib/rouge/lexers/email.rb +39 -0
- data/lib/rouge/lexers/ghc_core.rb +2 -1
- data/lib/rouge/lexers/graphql.rb +1 -1
- data/lib/rouge/lexers/hack.rb +1 -1
- data/lib/rouge/lexers/haskell.rb +27 -19
- data/lib/rouge/lexers/hlsl.rb +166 -0
- data/lib/rouge/lexers/html.rb +7 -7
- data/lib/rouge/lexers/http.rb +8 -2
- data/lib/rouge/lexers/isbl.rb +2 -2
- data/lib/rouge/lexers/j.rb +244 -0
- data/lib/rouge/lexers/janet.rb +218 -0
- data/lib/rouge/lexers/javascript.rb +11 -5
- data/lib/rouge/lexers/jinja.rb +22 -7
- data/lib/rouge/lexers/jsl.rb +20 -8
- data/lib/rouge/lexers/jsonnet.rb +4 -3
- data/lib/rouge/lexers/jsp.rb +2 -3
- data/lib/rouge/lexers/jsx.rb +47 -59
- data/lib/rouge/lexers/julia.rb +4 -2
- data/lib/rouge/lexers/kotlin.rb +8 -4
- data/lib/rouge/lexers/livescript.rb +310 -0
- data/lib/rouge/lexers/ocaml/common.rb +1 -1
- data/lib/rouge/lexers/ocl.rb +85 -0
- data/lib/rouge/lexers/opentype_feature_file.rb +26 -42
- data/lib/rouge/lexers/perl.rb +27 -7
- data/lib/rouge/lexers/php.rb +274 -128
- data/lib/rouge/lexers/postscript.rb +93 -0
- data/lib/rouge/lexers/powershell.rb +44 -32
- data/lib/rouge/lexers/python.rb +1 -1
- data/lib/rouge/lexers/q.rb +1 -1
- data/lib/rouge/lexers/reasonml.rb +6 -5
- data/lib/rouge/lexers/rego.rb +27 -12
- data/lib/rouge/lexers/rescript.rb +119 -0
- data/lib/rouge/lexers/ruby.rb +1 -1
- data/lib/rouge/lexers/rust.rb +6 -3
- data/lib/rouge/lexers/sass/common.rb +1 -0
- data/lib/rouge/lexers/smarty.rb +1 -1
- data/lib/rouge/lexers/ssh.rb +33 -0
- data/lib/rouge/lexers/systemd.rb +34 -0
- data/lib/rouge/lexers/tsx.rb +10 -3
- data/lib/rouge/lexers/twig.rb +4 -4
- data/lib/rouge/lexers/typescript.rb +1 -12
- data/lib/rouge/lexers/typescript/common.rb +18 -4
- data/lib/rouge/lexers/velocity.rb +71 -0
- data/lib/rouge/lexers/wollok.rb +0 -1
- data/lib/rouge/lexers/xml.rb +5 -3
- data/lib/rouge/lexers/yaml.rb +5 -3
- data/lib/rouge/lexers/zig.rb +139 -0
- data/lib/rouge/regex_lexer.rb +56 -1
- data/lib/rouge/themes/base16.rb +1 -0
- data/lib/rouge/themes/bw.rb +1 -0
- data/lib/rouge/themes/colorful.rb +1 -0
- data/lib/rouge/themes/github.rb +1 -0
- data/lib/rouge/themes/gruvbox.rb +2 -0
- data/lib/rouge/themes/igor_pro.rb +1 -0
- data/lib/rouge/themes/magritte.rb +1 -0
- data/lib/rouge/themes/monokai.rb +1 -0
- data/lib/rouge/themes/pastie.rb +1 -0
- data/lib/rouge/themes/thankful_eyes.rb +1 -0
- data/lib/rouge/themes/tulip.rb +1 -0
- data/lib/rouge/version.rb +1 -1
- metadata +33 -2
@@ -19,6 +19,8 @@ module Rouge
|
|
19
19
|
mimetypes 'application/javascript', 'application/x-javascript',
|
20
20
|
'text/javascript', 'text/x-javascript'
|
21
21
|
|
22
|
+
# Pseudo-documentation: https://stackoverflow.com/questions/1661197/what-characters-are-valid-for-javascript-variable-names
|
23
|
+
|
22
24
|
def self.detect?(text)
|
23
25
|
return 1 if text.shebang?('node')
|
24
26
|
return 1 if text.shebang?('jsc')
|
@@ -138,7 +140,7 @@ module Rouge
|
|
138
140
|
end
|
139
141
|
|
140
142
|
def self.id_regex
|
141
|
-
/[$
|
143
|
+
/[\p{L}\p{Nl}$_][\p{Word}]*/io
|
142
144
|
end
|
143
145
|
|
144
146
|
id = self.id_regex
|
@@ -160,6 +162,10 @@ module Rouge
|
|
160
162
|
push :template_string
|
161
163
|
end
|
162
164
|
|
165
|
+
# special case for the safe navigation operator ?.
|
166
|
+
# so that we don't start detecting a ternary expr
|
167
|
+
rule %r/[?][.]/, Punctuation
|
168
|
+
|
163
169
|
rule %r/[?]/ do
|
164
170
|
token Punctuation
|
165
171
|
push :ternary
|
@@ -225,8 +231,6 @@ module Rouge
|
|
225
231
|
groups Name::Label, Text, Punctuation
|
226
232
|
end
|
227
233
|
|
228
|
-
rule %r/[{}]/, Punctuation
|
229
|
-
|
230
234
|
mixin :expr_start
|
231
235
|
end
|
232
236
|
|
@@ -265,9 +269,11 @@ module Rouge
|
|
265
269
|
|
266
270
|
# template strings
|
267
271
|
state :template_string do
|
268
|
-
rule %r
|
272
|
+
rule %r/[$]{/, Punctuation, :template_string_expr
|
269
273
|
rule %r/`/, Str::Double, :pop!
|
270
|
-
rule %r
|
274
|
+
rule %r/\\[$`]/, Str::Escape
|
275
|
+
rule %r/[^$`\\]+/, Str::Double
|
276
|
+
rule %r/[\\$]/, Str::Double
|
271
277
|
end
|
272
278
|
|
273
279
|
state :template_string_expr do
|
data/lib/rouge/lexers/jinja.rb
CHANGED
@@ -40,6 +40,17 @@ module Rouge
|
|
40
40
|
rule %r/{#/, Comment, :comment
|
41
41
|
rule %r/##.*/, Comment
|
42
42
|
|
43
|
+
# Raw and verbatim
|
44
|
+
rule %r/({%-?)(\s*)(raw|verbatim)(\s*)(-?%})/ do |m|
|
45
|
+
groups Comment::Preproc, Text, Keyword, Text, Comment::Preproc
|
46
|
+
case m[3]
|
47
|
+
when "raw"
|
48
|
+
push :raw
|
49
|
+
when "verbatim"
|
50
|
+
push :verbatim
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
43
54
|
# Statements
|
44
55
|
rule %r/\{\%/ do
|
45
56
|
token Comment::Preproc
|
@@ -114,11 +125,6 @@ module Rouge
|
|
114
125
|
end
|
115
126
|
|
116
127
|
state :statement do
|
117
|
-
rule %r/(raw|verbatim)(\s+)(\%\})/ do
|
118
|
-
groups Keyword, Text, Comment::Preproc
|
119
|
-
goto :raw
|
120
|
-
end
|
121
|
-
|
122
128
|
rule %r/(\w+\.?)/ do |m|
|
123
129
|
if self.class.keywords.include?(m[0])
|
124
130
|
groups Keyword
|
@@ -142,12 +148,21 @@ module Rouge
|
|
142
148
|
end
|
143
149
|
|
144
150
|
state :raw do
|
145
|
-
rule %r
|
151
|
+
rule %r/({%-?)(\s*)(endraw)(\s*)(-?%})/ do
|
146
152
|
groups Comment::Preproc, Text, Keyword, Text, Comment::Preproc
|
147
153
|
pop!
|
148
154
|
end
|
155
|
+
rule %r/[^{]+/, Text
|
156
|
+
rule %r/{/, Text
|
157
|
+
end
|
149
158
|
|
150
|
-
|
159
|
+
state :verbatim do
|
160
|
+
rule %r/({%-?)(\s*)(endverbatim)(\s*)(-?%})/ do
|
161
|
+
groups Comment::Preproc, Text, Keyword, Text, Comment::Preproc
|
162
|
+
pop!
|
163
|
+
end
|
164
|
+
rule %r/[^{]+/, Text
|
165
|
+
rule %r/{/, Text
|
151
166
|
end
|
152
167
|
end
|
153
168
|
end
|
data/lib/rouge/lexers/jsl.rb
CHANGED
@@ -14,22 +14,20 @@ module Rouge
|
|
14
14
|
rule %r/\s+/m, Text::Whitespace
|
15
15
|
|
16
16
|
rule %r(//.*?$), Comment::Single
|
17
|
-
rule %r
|
17
|
+
rule %r'/[*].*', Comment::Multiline, :comment
|
18
18
|
|
19
19
|
# messages
|
20
|
-
rule %r
|
21
|
-
groups Operator, Name::Function, Punctuation
|
22
|
-
end
|
20
|
+
rule %r/<</, Operator, :message
|
23
21
|
|
24
22
|
# covers built-in and custom functions
|
25
23
|
rule %r/([a-z_][\w\s'%.\\]*)(\()/i do |m|
|
26
24
|
groups Keyword, Punctuation
|
27
25
|
end
|
28
26
|
|
29
|
-
rule %r/\b[+-]?(?:[0-9]+(?:\.[0-9]+)?|\.[0-9]+|\.)(?:e[+-]?[0-9]+)?i?\b/i, Num
|
30
|
-
|
31
27
|
rule %r/\d{2}(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d{2}(\d{2})?(:\d{2}:\d{2}(:\d{2}(\.\d*)?)?)?/i, Literal::Date
|
32
28
|
|
29
|
+
rule %r/-?(?:[0-9]+(?:[.][0-9]+)?|[.][0-9]*)(?:e[+-]?[0-9]+)?i?/i, Num
|
30
|
+
|
33
31
|
rule %r/::[a-z_][\w\s'%.\\]*/i, Name::Variable
|
34
32
|
rule %r/:\w+/, Name
|
35
33
|
rule %r/[a-z_][\w\s'%.\\]*/i, Name::Variable
|
@@ -40,15 +38,29 @@ module Rouge
|
|
40
38
|
end
|
41
39
|
rule %r/"/, Str::Double, :dq
|
42
40
|
|
43
|
-
rule %r/[
|
41
|
+
rule %r/[-+*\/!%&<>\|=:`^]/, Operator
|
44
42
|
rule %r/[\[\](){},;]/, Punctuation
|
45
43
|
end
|
46
44
|
|
45
|
+
state :message do
|
46
|
+
rule %r/\s+/m, Text::Whitespace
|
47
|
+
rule %r/[a-z_][\w\s'%.\\]*/i, Name::Function
|
48
|
+
rule %r/[(),;]/, Punctuation, :pop!
|
49
|
+
rule %r/[&|!=<>]/, Operator, :pop!
|
50
|
+
end
|
51
|
+
|
47
52
|
state :dq do
|
48
53
|
rule %r/\\![btrnNf0\\"]/, Str::Escape
|
49
54
|
rule %r/\\/, Str::Double
|
50
55
|
rule %r/"/, Str::Double, :pop!
|
51
|
-
rule %r/[^\\"]
|
56
|
+
rule %r/[^\\"]+/m, Str::Double
|
57
|
+
end
|
58
|
+
|
59
|
+
state :comment do
|
60
|
+
rule %r'/[*]', Comment::Multiline, :comment
|
61
|
+
rule %r'[*]/', Comment::Multiline, :pop!
|
62
|
+
rule %r'[^/*]+', Comment::Multiline
|
63
|
+
rule %r'[/*]', Comment::Multiline
|
52
64
|
end
|
53
65
|
end
|
54
66
|
end
|
data/lib/rouge/lexers/jsonnet.rb
CHANGED
@@ -126,6 +126,7 @@ module Rouge
|
|
126
126
|
|
127
127
|
state :string do
|
128
128
|
rule %r/\\([\\\/bfnrt]|(u[0-9a-fA-F]{4}))/, Str::Escape
|
129
|
+
rule %r/\\./, Str::Escape
|
129
130
|
end
|
130
131
|
|
131
132
|
state :string_double do
|
@@ -137,15 +138,15 @@ module Rouge
|
|
137
138
|
|
138
139
|
state :string_single do
|
139
140
|
mixin :string
|
140
|
-
rule %r/\\'/, Str::Escape
|
141
141
|
rule %r/'/, Str, :pop!
|
142
142
|
rule %r/[^\\']+/, Str
|
143
143
|
end
|
144
144
|
|
145
145
|
state :string_block do
|
146
146
|
mixin :string
|
147
|
-
rule %r
|
148
|
-
rule %r
|
147
|
+
rule %r/[|][|][|]/, Str, :pop!
|
148
|
+
rule %r/[^|\\]+/, Str
|
149
|
+
rule %r/[|]/, Str
|
149
150
|
end
|
150
151
|
end
|
151
152
|
end
|
data/lib/rouge/lexers/jsp.rb
CHANGED
data/lib/rouge/lexers/jsx.rb
CHANGED
@@ -6,97 +6,85 @@ module Rouge
|
|
6
6
|
|
7
7
|
class JSX < Javascript
|
8
8
|
title 'JSX'
|
9
|
-
desc '
|
9
|
+
desc 'An XML-like syntax extension to JavaScript (facebook.github.io/jsx/)'
|
10
10
|
tag 'jsx'
|
11
11
|
aliases 'jsx', 'react'
|
12
12
|
filenames '*.jsx'
|
13
13
|
|
14
14
|
mimetypes 'text/x-jsx', 'application/x-jsx'
|
15
15
|
|
16
|
-
|
16
|
+
start { @html = HTML.new(options); push :expr_start }
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
@embed.reset!
|
21
|
-
@embed.push(:expr_start)
|
22
|
-
push :jsx_embed_root
|
23
|
-
end
|
24
|
-
|
25
|
-
def tag_token(name)
|
26
|
-
name[0] =~ /\p{Lower}/ ? Name::Tag : Name::Class
|
18
|
+
prepend :expr_start do
|
19
|
+
mixin :tag
|
27
20
|
end
|
28
21
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
22
|
+
state :tag do
|
23
|
+
rule %r/</ do
|
24
|
+
token Punctuation
|
25
|
+
push :tag_opening
|
26
|
+
push :element
|
27
|
+
push :element_name
|
28
|
+
end
|
33
29
|
end
|
34
30
|
|
35
|
-
state :
|
36
|
-
rule %r
|
31
|
+
state :tag_opening do
|
32
|
+
rule %r/<\// do
|
37
33
|
token Punctuation
|
38
|
-
goto :
|
34
|
+
goto :element
|
35
|
+
push :element_name
|
39
36
|
end
|
40
|
-
|
37
|
+
mixin :tag
|
41
38
|
rule %r/{/ do
|
42
39
|
token Str::Interpol
|
43
|
-
|
40
|
+
push :interpol
|
41
|
+
push :expr_start
|
44
42
|
end
|
45
|
-
|
46
|
-
rule %r/[^<>{]+/ do
|
43
|
+
rule %r/[^<{]+/ do
|
47
44
|
delegate @html
|
48
45
|
end
|
49
|
-
|
50
|
-
mixin :jsx_tags
|
51
|
-
end
|
52
|
-
|
53
|
-
prepend :expr_start do
|
54
|
-
mixin :jsx_tags
|
55
46
|
end
|
56
47
|
|
57
|
-
state :
|
48
|
+
state :element do
|
58
49
|
mixin :comments_and_whitespace
|
59
|
-
rule %r
|
60
|
-
token
|
50
|
+
rule %r/\/>/ do
|
51
|
+
token Punctuation
|
52
|
+
pop! 2
|
61
53
|
end
|
62
|
-
|
63
|
-
rule %r/[.]/, Punctuation
|
64
|
-
end
|
65
|
-
|
66
|
-
state :jsx_end_tag do
|
67
|
-
mixin :jsx_tag
|
68
54
|
rule %r/>/, Punctuation, :pop!
|
69
|
-
end
|
70
|
-
|
71
|
-
state :jsx_element do
|
72
|
-
rule %r/#{id}=/, Name::Attribute, :jsx_attribute
|
73
|
-
mixin :jsx_tag
|
74
|
-
rule %r/>/ do token Punctuation; goto :jsx_internal end
|
75
|
-
rule %r(/>), Punctuation, :pop!
|
76
|
-
end
|
77
|
-
|
78
|
-
state :jsx_attribute do
|
79
|
-
rule %r/"(\\[\\"]|[^"])*"/, Str::Double, :pop!
|
80
|
-
rule %r/'(\\[\\']|[^'])*'/, Str::Single, :pop!
|
81
55
|
rule %r/{/ do
|
82
56
|
token Str::Interpol
|
83
|
-
|
84
|
-
|
57
|
+
push :interpol
|
58
|
+
push :expr_start
|
85
59
|
end
|
60
|
+
rule %r/\w+/, Name::Attribute
|
61
|
+
rule %r/=/, Punctuation
|
62
|
+
rule %r/(["']).*?(\1)/, Str
|
86
63
|
end
|
87
64
|
|
88
|
-
state :
|
89
|
-
rule %r/[
|
65
|
+
state :element_name do
|
66
|
+
rule %r/[A-Z]\w*/, Name::Class
|
67
|
+
rule %r/\w+/, Name::Tag
|
68
|
+
rule %r/\./, Punctuation
|
69
|
+
rule(//) { pop! }
|
70
|
+
end
|
71
|
+
|
72
|
+
state :interpol do
|
90
73
|
rule %r/}/, Str::Interpol, :pop!
|
91
|
-
|
74
|
+
rule %r/{/ do
|
75
|
+
token Punctuation
|
76
|
+
push :interpol_inner
|
77
|
+
push :statement
|
78
|
+
end
|
79
|
+
mixin :root
|
92
80
|
end
|
93
81
|
|
94
|
-
state :
|
95
|
-
rule %r/
|
96
|
-
|
97
|
-
|
98
|
-
delegate @embed
|
82
|
+
state :interpol_inner do
|
83
|
+
rule %r/}/ do
|
84
|
+
token Punctuation
|
85
|
+
goto :statement
|
99
86
|
end
|
87
|
+
mixin :root
|
100
88
|
end
|
101
89
|
end
|
102
90
|
end
|
data/lib/rouge/lexers/julia.rb
CHANGED
@@ -11,6 +11,8 @@ module Rouge
|
|
11
11
|
filenames '*.jl'
|
12
12
|
mimetypes 'text/x-julia', 'application/x-julia'
|
13
13
|
|
14
|
+
# Documentation: https://docs.julialang.org/en/v1/manual/variables/#Allowed-Variable-Names-1
|
15
|
+
|
14
16
|
def self.detect?(text)
|
15
17
|
return true if text.shebang? 'julia'
|
16
18
|
end
|
@@ -252,13 +254,13 @@ module Rouge
|
|
252
254
|
|
253
255
|
|
254
256
|
state :funcname do
|
255
|
-
rule %r/[
|
257
|
+
rule %r/[\p{L}\p{Nl}\p{S}_][\p{Word}\p{S}\p{Po}!]*/, Name::Function, :pop!
|
256
258
|
rule %r/\([^\s\w{]{1,2}\)/, Operator, :pop!
|
257
259
|
rule %r/[^\s\w{]{1,2}/, Operator, :pop!
|
258
260
|
end
|
259
261
|
|
260
262
|
state :typename do
|
261
|
-
rule %r/[
|
263
|
+
rule %r/[\p{L}\p{Nl}\p{S}_][\p{Word}\p{S}\p{Po}!]*/, Name::Class, :pop!
|
262
264
|
end
|
263
265
|
|
264
266
|
state :stringescape do
|
data/lib/rouge/lexers/kotlin.rb
CHANGED
@@ -53,7 +53,7 @@ module Rouge
|
|
53
53
|
groups Keyword::Declaration, Text
|
54
54
|
push :property
|
55
55
|
end
|
56
|
-
rule %r'(return|continue|break|this|super)(@#{name})
|
56
|
+
rule %r'(return|continue|break|this|super)(@#{name})?\b' do
|
57
57
|
groups Keyword, Name::Decorator
|
58
58
|
end
|
59
59
|
rule %r'\bfun\b', Keyword
|
@@ -65,6 +65,9 @@ module Rouge
|
|
65
65
|
rule %r'/[*].*[*]/', Comment::Multiline # single line block comment
|
66
66
|
rule %r'/[*].*', Comment::Multiline, :comment # multiline block comment
|
67
67
|
rule %r'\n', Text
|
68
|
+
rule %r'(::)(class)' do
|
69
|
+
groups Operator, Keyword
|
70
|
+
end
|
68
71
|
rule %r'::|!!|\?[:.]', Operator
|
69
72
|
rule %r"(\.\.)", Operator
|
70
73
|
# Number literals
|
@@ -130,9 +133,10 @@ module Rouge
|
|
130
133
|
end
|
131
134
|
|
132
135
|
state :comment do
|
133
|
-
rule %r'
|
134
|
-
rule %r'
|
135
|
-
rule %r'
|
136
|
+
rule %r'/[*]', Comment::Multiline, :comment
|
137
|
+
rule %r'[*]/', Comment::Multiline, :pop!
|
138
|
+
rule %r'[^/*]+', Comment::Multiline
|
139
|
+
rule %r'[/*]', Comment::Multiline
|
136
140
|
end
|
137
141
|
end
|
138
142
|
end
|
@@ -0,0 +1,310 @@
|
|
1
|
+
# -*- coding: utf-8 -*- #
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Rouge
|
5
|
+
module Lexers
|
6
|
+
class Livescript < RegexLexer
|
7
|
+
tag 'livescript'
|
8
|
+
aliases 'ls'
|
9
|
+
filenames '*.ls'
|
10
|
+
mimetypes 'text/livescript'
|
11
|
+
|
12
|
+
title 'LiveScript'
|
13
|
+
desc 'LiveScript, a language which compiles to JavaScript (livescript.net)'
|
14
|
+
|
15
|
+
def self.detect?(text)
|
16
|
+
return text.shebang? 'lsc'
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.declarations
|
20
|
+
@declarations ||= Set.new %w(const let var function class extends implements)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.keywords
|
24
|
+
@keywords ||= Set.new %w(
|
25
|
+
loop until for in of while break return continue switch case
|
26
|
+
fallthrough default otherwise when then if unless else throw try
|
27
|
+
catch finally new delete typeof instanceof super by from to til
|
28
|
+
with require do debugger import export yield
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
def self.constants
|
33
|
+
@constants ||= Javascript.constants + %w(yes no on off void)
|
34
|
+
end
|
35
|
+
|
36
|
+
def self.builtins
|
37
|
+
@builtins ||= Javascript.builtins + %w(this it that arguments)
|
38
|
+
end
|
39
|
+
|
40
|
+
def self.loop_control_keywords
|
41
|
+
@loop_control_keywords ||= Set.new %w(break continue)
|
42
|
+
end
|
43
|
+
|
44
|
+
id = /[$a-z_]((-(?=[a-z]))?[a-z0-9_])*/i
|
45
|
+
int_number = /\d[\d_]*/
|
46
|
+
int = /#{int_number}(e[+-]?#{int_number})?[$\w]*/ # the last class matches units
|
47
|
+
|
48
|
+
state :root do
|
49
|
+
rule(%r(^(?=\s|/))) { push :slash_starts_regex }
|
50
|
+
mixin :comments
|
51
|
+
mixin :whitespace
|
52
|
+
|
53
|
+
# list of words
|
54
|
+
rule %r/(<\[)(.*?)(\]>)/m do
|
55
|
+
groups Punctuation, Str, Punctuation
|
56
|
+
end
|
57
|
+
|
58
|
+
# function declarations
|
59
|
+
rule %r/!\s*function\b/, Keyword::Declaration
|
60
|
+
rule %r/!?[-~]>|<[-~]!?/, Keyword::Declaration
|
61
|
+
|
62
|
+
# switch arrow
|
63
|
+
rule %r/(=>)/, Keyword
|
64
|
+
|
65
|
+
# prototype attributes
|
66
|
+
rule %r/(::)(#{id})/ do
|
67
|
+
groups Punctuation, Name::Attribute
|
68
|
+
push :id
|
69
|
+
end
|
70
|
+
rule %r/(::)(#{int})/ do
|
71
|
+
groups Punctuation, Num::Integer
|
72
|
+
push :id
|
73
|
+
end
|
74
|
+
|
75
|
+
# instance attributes
|
76
|
+
rule %r/(@)(#{id})/ do
|
77
|
+
groups Name::Variable::Instance, Name::Attribute
|
78
|
+
push :id
|
79
|
+
end
|
80
|
+
rule %r/([.])(#{id})/ do
|
81
|
+
groups Punctuation, Name::Attribute
|
82
|
+
push :id
|
83
|
+
end
|
84
|
+
rule %r/([.])(\d+)/ do
|
85
|
+
groups Punctuation, Num::Integer
|
86
|
+
push :id
|
87
|
+
end
|
88
|
+
rule %r/#{id}(?=\s*:[^:=])/, Name::Attribute
|
89
|
+
|
90
|
+
# operators
|
91
|
+
rule %r(
|
92
|
+
[+][+]|--|&&|\b(and|x?or|is(nt)?|not)\b(?!-[a-zA-Z]|_)|[|][|]|
|
93
|
+
[.]([|&^]|<<|>>>?)[.]|\\(?=\n)|[.:]=|<<<<?|<[|]|[|]>|
|
94
|
+
(<<|>>|==?|!=?|[-<>+*%^/~?])=?
|
95
|
+
)x, Operator, :slash_starts_regex
|
96
|
+
|
97
|
+
# arguments shorthand
|
98
|
+
rule %r/(&)(#{id})?/ do
|
99
|
+
groups Name::Builtin, Name::Attribute
|
100
|
+
end
|
101
|
+
|
102
|
+
# switch case
|
103
|
+
rule %r/[|]|\bcase(?=\s)/, Keyword, :switch_underscore
|
104
|
+
|
105
|
+
rule %r/@/, Name::Variable::Instance
|
106
|
+
rule %r/[.]{3}/, Punctuation
|
107
|
+
rule %r/:/, Punctuation
|
108
|
+
|
109
|
+
# keywords
|
110
|
+
rule %r/#{id}/ do |m|
|
111
|
+
if self.class.loop_control_keywords.include? m[0]
|
112
|
+
token Keyword
|
113
|
+
push :loop_control
|
114
|
+
next
|
115
|
+
elsif self.class.keywords.include? m[0]
|
116
|
+
token Keyword
|
117
|
+
elsif self.class.constants.include? m[0]
|
118
|
+
token Name::Constant
|
119
|
+
elsif self.class.builtins.include? m[0]
|
120
|
+
token Name::Builtin
|
121
|
+
elsif self.class.declarations.include? m[0]
|
122
|
+
token Keyword::Declaration
|
123
|
+
elsif /^[A-Z]/.match(m[0]) && /[^-][a-z]/.match(m[0])
|
124
|
+
token Name::Class
|
125
|
+
else
|
126
|
+
token Name::Variable
|
127
|
+
end
|
128
|
+
push :id
|
129
|
+
end
|
130
|
+
|
131
|
+
# punctuation and brackets
|
132
|
+
rule %r/\](?=[!?.]|#{id})/, Punctuation, :id
|
133
|
+
rule %r/[{(\[;,]/, Punctuation, :slash_starts_regex
|
134
|
+
rule %r/[})\].]/, Punctuation
|
135
|
+
|
136
|
+
# literals
|
137
|
+
rule %r/#{int_number}[.]#{int}/, Num::Float
|
138
|
+
rule %r/0x[0-9A-Fa-f]+/, Num::Hex
|
139
|
+
rule %r/#{int}/, Num::Integer
|
140
|
+
|
141
|
+
# strings
|
142
|
+
rule %r/"""/ do
|
143
|
+
token Str
|
144
|
+
push do
|
145
|
+
rule %r/"""/, Str, :pop!
|
146
|
+
rule %r/"/, Str
|
147
|
+
mixin :double_strings
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
rule %r/'''/ do
|
152
|
+
token Str
|
153
|
+
push do
|
154
|
+
rule %r/'''/, Str, :pop!
|
155
|
+
rule %r/'/, Str
|
156
|
+
mixin :single_strings
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
rule %r/"/ do
|
161
|
+
token Str
|
162
|
+
push do
|
163
|
+
rule %r/"/, Str, :pop!
|
164
|
+
mixin :double_strings
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
rule %r/'/ do
|
169
|
+
token Str
|
170
|
+
push do
|
171
|
+
rule %r/'/, Str, :pop!
|
172
|
+
mixin :single_strings
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
# words
|
177
|
+
rule %r/\\\S[^\s,;\])}]*/, Str
|
178
|
+
end
|
179
|
+
|
180
|
+
state :code_escape do
|
181
|
+
rule %r(\\(
|
182
|
+
c[A-Z]|
|
183
|
+
x[0-9a-fA-F]{2}|
|
184
|
+
u[0-9a-fA-F]{4}|
|
185
|
+
u\{[0-9a-fA-F]{4}\}
|
186
|
+
))x, Str::Escape
|
187
|
+
end
|
188
|
+
|
189
|
+
state :interpolated_expression do
|
190
|
+
rule %r/}/, Str::Interpol, :pop!
|
191
|
+
mixin :root
|
192
|
+
end
|
193
|
+
|
194
|
+
state :interpolation do
|
195
|
+
# with curly braces
|
196
|
+
rule %r/[#][{]/, Str::Interpol, :interpolated_expression
|
197
|
+
# without curly braces
|
198
|
+
rule %r/(#)(#{id})/ do |m|
|
199
|
+
groups Str::Interpol, (self.class.builtins.include? m[2]) ? Name::Builtin : Name::Variable
|
200
|
+
end
|
201
|
+
end
|
202
|
+
|
203
|
+
state :whitespace do
|
204
|
+
# white space and loop labels
|
205
|
+
rule %r/(\s+?)(?:^([^\S\n]*)(:#{id}))?/m do
|
206
|
+
groups Text, Text, Name::Label
|
207
|
+
end
|
208
|
+
end
|
209
|
+
|
210
|
+
state :whitespace_single_line do
|
211
|
+
rule %r([^\S\n]+), Text
|
212
|
+
end
|
213
|
+
|
214
|
+
state :slash_starts_regex do
|
215
|
+
mixin :comments
|
216
|
+
mixin :whitespace
|
217
|
+
mixin :multiline_regex_begin
|
218
|
+
|
219
|
+
rule %r(
|
220
|
+
/(\\.|[^\[/\\\n]|\[(\\.|[^\]\\\n])*\])+/ # a regex
|
221
|
+
([gimy]+\b|\B)
|
222
|
+
)x, Str::Regex, :pop!
|
223
|
+
|
224
|
+
rule(//) { pop! }
|
225
|
+
end
|
226
|
+
|
227
|
+
state :multiline_regex_begin do
|
228
|
+
rule %r(//) do
|
229
|
+
token Str::Regex
|
230
|
+
goto :multiline_regex
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
state :multiline_regex_end do
|
235
|
+
rule %r(//([gimy]+\b|\B)), Str::Regex, :pop!
|
236
|
+
end
|
237
|
+
|
238
|
+
state :multiline_regex do
|
239
|
+
mixin :multiline_regex_end
|
240
|
+
mixin :regex_comment
|
241
|
+
mixin :interpolation
|
242
|
+
mixin :code_escape
|
243
|
+
rule %r/\\\D/, Str::Escape
|
244
|
+
rule %r/\\\d+/, Name::Variable
|
245
|
+
rule %r/./m, Str::Regex
|
246
|
+
end
|
247
|
+
|
248
|
+
state :regex_comment do
|
249
|
+
rule %r/^#(\s+.*)?$/, Comment::Single
|
250
|
+
rule %r/(\s+)(#)(\s+.*)?$/ do
|
251
|
+
groups Text, Comment::Single, Comment::Single
|
252
|
+
end
|
253
|
+
end
|
254
|
+
|
255
|
+
state :comments do
|
256
|
+
rule %r(/\*.*?\*/)m, Comment::Multiline
|
257
|
+
rule %r/#.*$/, Comment::Single
|
258
|
+
end
|
259
|
+
|
260
|
+
state :switch_underscore do
|
261
|
+
mixin :whitespace_single_line
|
262
|
+
rule %r/_(?=\s*=>|\s+then\b)/, Keyword
|
263
|
+
rule(//) { pop! }
|
264
|
+
end
|
265
|
+
|
266
|
+
state :loop_control do
|
267
|
+
mixin :whitespace_single_line
|
268
|
+
rule %r/#{id}(?=[);\n])/, Name::Label
|
269
|
+
rule(//) { pop! }
|
270
|
+
end
|
271
|
+
|
272
|
+
state :id do
|
273
|
+
rule %r/[!?]|[.](?!=)/, Punctuation
|
274
|
+
rule %r/[{]/ do
|
275
|
+
# destructuring
|
276
|
+
token Punctuation
|
277
|
+
push do
|
278
|
+
rule %r/[,;]/, Punctuation
|
279
|
+
rule %r/#{id}/, Name::Attribute
|
280
|
+
rule %r/#{int}/, Num::Integer
|
281
|
+
mixin :whitespace
|
282
|
+
rule %r/[}]/, Punctuation, :pop!
|
283
|
+
end
|
284
|
+
end
|
285
|
+
rule %r/#{id}/, Name::Attribute
|
286
|
+
rule %r/#{int}/, Num::Integer
|
287
|
+
rule(//) { goto :slash_starts_regex }
|
288
|
+
end
|
289
|
+
|
290
|
+
state :strings do
|
291
|
+
# all strings are multi-line
|
292
|
+
rule %r/[^#\\'"]+/m, Str
|
293
|
+
mixin :code_escape
|
294
|
+
rule %r/\\./, Str::Escape
|
295
|
+
rule %r/#/, Str
|
296
|
+
end
|
297
|
+
|
298
|
+
state :double_strings do
|
299
|
+
rule %r/'/, Str
|
300
|
+
mixin :interpolation
|
301
|
+
mixin :strings
|
302
|
+
end
|
303
|
+
|
304
|
+
state :single_strings do
|
305
|
+
rule %r/"/, Str
|
306
|
+
mixin :strings
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
end
|