rouge 3.19.0 → 3.26.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/lib/rouge.rb +1 -0
  3. data/lib/rouge/cli.rb +32 -2
  4. data/lib/rouge/demos/augeas +16 -0
  5. data/lib/rouge/demos/bibtex +12 -0
  6. data/lib/rouge/demos/brightscript +6 -0
  7. data/lib/rouge/demos/email +11 -0
  8. data/lib/rouge/demos/hlsl +20 -0
  9. data/lib/rouge/demos/j +12 -0
  10. data/lib/rouge/demos/janet +3 -0
  11. data/lib/rouge/demos/livescript +15 -0
  12. data/lib/rouge/demos/ocl +4 -0
  13. data/lib/rouge/demos/postscript +9 -0
  14. data/lib/rouge/demos/rescript +26 -0
  15. data/lib/rouge/demos/ssh +4 -0
  16. data/lib/rouge/demos/systemd +4 -0
  17. data/lib/rouge/demos/velocity +9 -0
  18. data/lib/rouge/demos/zig +6 -0
  19. data/lib/rouge/formatters/html_line_highlighter.rb +24 -0
  20. data/lib/rouge/formatters/html_line_table.rb +1 -3
  21. data/lib/rouge/formatters/html_linewise.rb +2 -3
  22. data/lib/rouge/lexer.rb +38 -20
  23. data/lib/rouge/lexers/apex.rb +9 -7
  24. data/lib/rouge/lexers/augeas.rb +93 -0
  25. data/lib/rouge/lexers/batchfile.rb +3 -2
  26. data/lib/rouge/lexers/bibtex.rb +115 -0
  27. data/lib/rouge/lexers/brightscript.rb +147 -0
  28. data/lib/rouge/lexers/cmake.rb +10 -0
  29. data/lib/rouge/lexers/cpp.rb +12 -5
  30. data/lib/rouge/lexers/crystal.rb +14 -9
  31. data/lib/rouge/lexers/css.rb +3 -1
  32. data/lib/rouge/lexers/diff.rb +1 -1
  33. data/lib/rouge/lexers/docker.rb +2 -2
  34. data/lib/rouge/lexers/elm.rb +5 -5
  35. data/lib/rouge/lexers/email.rb +39 -0
  36. data/lib/rouge/lexers/ghc_core.rb +2 -1
  37. data/lib/rouge/lexers/graphql.rb +1 -1
  38. data/lib/rouge/lexers/hack.rb +1 -1
  39. data/lib/rouge/lexers/haskell.rb +27 -19
  40. data/lib/rouge/lexers/hlsl.rb +166 -0
  41. data/lib/rouge/lexers/html.rb +7 -7
  42. data/lib/rouge/lexers/http.rb +8 -2
  43. data/lib/rouge/lexers/isbl.rb +2 -2
  44. data/lib/rouge/lexers/j.rb +244 -0
  45. data/lib/rouge/lexers/janet.rb +218 -0
  46. data/lib/rouge/lexers/javascript.rb +11 -5
  47. data/lib/rouge/lexers/jinja.rb +22 -7
  48. data/lib/rouge/lexers/jsl.rb +20 -8
  49. data/lib/rouge/lexers/jsonnet.rb +4 -3
  50. data/lib/rouge/lexers/jsp.rb +2 -3
  51. data/lib/rouge/lexers/jsx.rb +47 -59
  52. data/lib/rouge/lexers/julia.rb +4 -2
  53. data/lib/rouge/lexers/kotlin.rb +8 -4
  54. data/lib/rouge/lexers/livescript.rb +310 -0
  55. data/lib/rouge/lexers/ocaml/common.rb +1 -1
  56. data/lib/rouge/lexers/ocl.rb +85 -0
  57. data/lib/rouge/lexers/opentype_feature_file.rb +26 -42
  58. data/lib/rouge/lexers/perl.rb +27 -7
  59. data/lib/rouge/lexers/php.rb +274 -128
  60. data/lib/rouge/lexers/postscript.rb +93 -0
  61. data/lib/rouge/lexers/powershell.rb +44 -32
  62. data/lib/rouge/lexers/python.rb +1 -1
  63. data/lib/rouge/lexers/q.rb +1 -1
  64. data/lib/rouge/lexers/reasonml.rb +6 -5
  65. data/lib/rouge/lexers/rego.rb +27 -12
  66. data/lib/rouge/lexers/rescript.rb +119 -0
  67. data/lib/rouge/lexers/ruby.rb +1 -1
  68. data/lib/rouge/lexers/rust.rb +6 -3
  69. data/lib/rouge/lexers/sass/common.rb +1 -0
  70. data/lib/rouge/lexers/smarty.rb +1 -1
  71. data/lib/rouge/lexers/ssh.rb +33 -0
  72. data/lib/rouge/lexers/systemd.rb +34 -0
  73. data/lib/rouge/lexers/tsx.rb +10 -3
  74. data/lib/rouge/lexers/twig.rb +4 -4
  75. data/lib/rouge/lexers/typescript.rb +1 -12
  76. data/lib/rouge/lexers/typescript/common.rb +18 -4
  77. data/lib/rouge/lexers/velocity.rb +71 -0
  78. data/lib/rouge/lexers/wollok.rb +0 -1
  79. data/lib/rouge/lexers/xml.rb +5 -3
  80. data/lib/rouge/lexers/yaml.rb +5 -3
  81. data/lib/rouge/lexers/zig.rb +139 -0
  82. data/lib/rouge/regex_lexer.rb +56 -1
  83. data/lib/rouge/themes/base16.rb +1 -0
  84. data/lib/rouge/themes/bw.rb +1 -0
  85. data/lib/rouge/themes/colorful.rb +1 -0
  86. data/lib/rouge/themes/github.rb +1 -0
  87. data/lib/rouge/themes/gruvbox.rb +2 -0
  88. data/lib/rouge/themes/igor_pro.rb +1 -0
  89. data/lib/rouge/themes/magritte.rb +1 -0
  90. data/lib/rouge/themes/monokai.rb +1 -0
  91. data/lib/rouge/themes/pastie.rb +1 -0
  92. data/lib/rouge/themes/thankful_eyes.rb +1 -0
  93. data/lib/rouge/themes/tulip.rb +1 -0
  94. data/lib/rouge/version.rb +1 -1
  95. 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
- /[$a-z_][a-z0-9_]*/io
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/\${/, Punctuation, :template_string_expr
272
+ rule %r/[$]{/, Punctuation, :template_string_expr
269
273
  rule %r/`/, Str::Double, :pop!
270
- rule %r/(\\\\|\\[\$`]|[^\$`]|\$(?!{))*/, Str::Double
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
@@ -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{(\{\%)(\s+)(endverbatim|endraw)(\s+)(\%\})} do
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
- rule %r/(.+?)/m, Text
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
@@ -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(/\*.*?\*/)m, Comment::Multiline
17
+ rule %r'/[*].*', Comment::Multiline, :comment
18
18
 
19
19
  # messages
20
- rule %r/(<<)(.*?)(\(|;)/ do |m|
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/[-+*\/!%&<>\|=:]/, Operator
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/[^\\"]*/m, Str::Double
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
@@ -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/\|\|\|/, Str, :pop!
148
- rule %r/.*/, Str
147
+ rule %r/[|][|][|]/, Str, :pop!
148
+ rule %r/[^|\\]+/, Str
149
+ rule %r/[|]/, Str
149
150
  end
150
151
  end
151
152
  end
@@ -112,9 +112,8 @@ module Rouge
112
112
 
113
113
  state :jsp_interp_literal_start do
114
114
  rule %r/'/, Literal, :pop!
115
- rule %r/[^']*/, Literal
115
+ rule %r/[^']+/, Literal
116
116
  end
117
-
118
117
  end
119
118
  end
120
- end
119
+ end
@@ -6,97 +6,85 @@ module Rouge
6
6
 
7
7
  class JSX < Javascript
8
8
  title 'JSX'
9
- desc 'React JSX (https://facebook.github.io/react/)'
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
- id = Javascript.id_regex
16
+ start { @html = HTML.new(options); push :expr_start }
17
17
 
18
- def start_embed!
19
- @embed ||= JSX.new(options)
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
- start { @html = HTML.new(options) }
30
-
31
- state :jsx_tags do
32
- rule %r/</, Punctuation, :jsx_element
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 :jsx_internal do
36
- rule %r(</) do
31
+ state :tag_opening do
32
+ rule %r/<\// do
37
33
  token Punctuation
38
- goto :jsx_end_tag
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
- start_embed!
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 :jsx_tag do
48
+ state :element do
58
49
  mixin :comments_and_whitespace
59
- rule %r/#{id}/ do |m|
60
- token tag_token(m[0])
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
- pop!
84
- start_embed!
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 :jsx_embed_root do
89
- rule %r/[.][.][.]/, Punctuation
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
- mixin :jsx_embed
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 :jsx_embed do
95
- rule %r/{/ do delegate @embed; push :jsx_embed end
96
- rule %r/}/ do delegate @embed; pop! end
97
- rule %r/[^{}]+/ do
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
@@ -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/[a-zA-Z_]\w*/, Name::Function, :pop!
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/[a-zA-Z_]\w*/, Name::Class, :pop!
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
@@ -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})?' do
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'\s*/[*].*', Comment::Multiline, :comment
134
- rule %r'.*[*]/', Comment::Multiline, :pop!
135
- rule %r'.*', Comment::Multiline
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