rouge 3.6.0 → 3.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/lib/rouge/demos/ada +26 -0
  4. data/lib/rouge/demos/armasm +12 -0
  5. data/lib/rouge/demos/batchfile +3 -0
  6. data/lib/rouge/demos/bbcbasic +6 -0
  7. data/lib/rouge/demos/cmhg +8 -0
  8. data/lib/rouge/demos/cuda +11 -0
  9. data/lib/rouge/demos/cython +6 -0
  10. data/lib/rouge/demos/epp +4 -0
  11. data/lib/rouge/demos/gdscript +18 -0
  12. data/lib/rouge/demos/hocon +8 -0
  13. data/lib/rouge/demos/mason +22 -0
  14. data/lib/rouge/demos/msgtrans +4 -0
  15. data/lib/rouge/demos/opentype_feature_file +6 -0
  16. data/lib/rouge/demos/plist +1 -132
  17. data/lib/rouge/demos/reasonml +12 -0
  18. data/lib/rouge/demos/sas +13 -0
  19. data/lib/rouge/formatters/html_line_table.rb +3 -1
  20. data/lib/rouge/formatters/tex.rb +14 -12
  21. data/lib/rouge/guessers/disambiguation.rb +12 -0
  22. data/lib/rouge/lexers/ada.rb +162 -0
  23. data/lib/rouge/lexers/armasm.rb +145 -0
  24. data/lib/rouge/lexers/batchfile.rb +164 -0
  25. data/lib/rouge/lexers/bbcbasic.rb +112 -0
  26. data/lib/rouge/lexers/cmhg.rb +34 -0
  27. data/lib/rouge/lexers/console.rb +1 -1
  28. data/lib/rouge/lexers/cpp.rb +4 -1
  29. data/lib/rouge/lexers/cuda.rb +35 -0
  30. data/lib/rouge/lexers/cython.rb +151 -0
  31. data/lib/rouge/lexers/epp.rb +51 -0
  32. data/lib/rouge/lexers/escape.rb +3 -0
  33. data/lib/rouge/lexers/gdscript.rb +171 -0
  34. data/lib/rouge/lexers/gherkin.rb +4 -2
  35. data/lib/rouge/lexers/graphql.rb +10 -3
  36. data/lib/rouge/lexers/handlebars.rb +14 -3
  37. data/lib/rouge/lexers/hocon.rb +86 -0
  38. data/lib/rouge/lexers/html.rb +2 -2
  39. data/lib/rouge/lexers/igorpro.rb +1 -1
  40. data/lib/rouge/lexers/json.rb +43 -5
  41. data/lib/rouge/lexers/julia.rb +1 -1
  42. data/lib/rouge/lexers/make.rb +39 -12
  43. data/lib/rouge/lexers/mason.rb +115 -0
  44. data/lib/rouge/lexers/msgtrans.rb +26 -0
  45. data/lib/rouge/lexers/ocaml.rb +12 -48
  46. data/lib/rouge/lexers/ocaml/common.rb +53 -0
  47. data/lib/rouge/lexers/opentype_feature_file.rb +113 -0
  48. data/lib/rouge/lexers/php.rb +31 -9
  49. data/lib/rouge/lexers/php/builtins.rb +181 -174
  50. data/lib/rouge/lexers/plain_text.rb +1 -1
  51. data/lib/rouge/lexers/puppet.rb +2 -2
  52. data/lib/rouge/lexers/r.rb +2 -3
  53. data/lib/rouge/lexers/reasonml.rb +65 -0
  54. data/lib/rouge/lexers/rust.rb +12 -9
  55. data/lib/rouge/lexers/sas.rb +563 -0
  56. data/lib/rouge/lexers/sed.rb +1 -1
  57. data/lib/rouge/lexers/smarty.rb +10 -10
  58. data/lib/rouge/tex_theme_renderer.rb +5 -1
  59. data/lib/rouge/themes/magritte.rb +3 -3
  60. data/lib/rouge/themes/thankful_eyes.rb +1 -1
  61. data/lib/rouge/themes/tulip.rb +1 -1
  62. data/lib/rouge/version.rb +1 -1
  63. data/rouge.gemspec +4 -3
  64. metadata +38 -5
@@ -0,0 +1,112 @@
1
+ # -*- coding: utf-8 -*- #
2
+ # frozen_string_literal: true
3
+
4
+ module Rouge
5
+ module Lexers
6
+ class BBCBASIC < RegexLexer
7
+ title "BBCBASIC"
8
+ desc "BBC BASIC syntax"
9
+ tag 'bbcbasic'
10
+ filenames '*,fd1'
11
+
12
+ def self.punctuation
13
+ @punctuation ||= %w(
14
+ [,;'~] SPC TAB
15
+ )
16
+ end
17
+
18
+ def self.function
19
+ @function ||= %w(
20
+ ABS ACS ADVAL ASC ASN ATN BEATS BEAT BGET# CHR\$ COS COUNT DEG DIM
21
+ EOF# ERL ERR EVAL EXP EXT# FN GET\$# GET\$ GET HIMEM INKEY\$ INKEY
22
+ INSTR INT LEFT\$ LEN LN LOG LOMEM MID\$ OPENIN OPENOUT OPENUP PAGE
23
+ POINT POS PTR# RAD REPORT\$ RIGHT\$ RND SGN SIN SQR STR\$ STRING\$ SUM
24
+ SUMLEN TAN TEMPO TIME\$ TIME TOP USR VAL VPOS
25
+ )
26
+ end
27
+
28
+ def self.statement
29
+ @statement ||= %w(
30
+ BEATS BPUT# CALL CASE CHAIN CLEAR CLG CLOSE# CLS COLOR COLOUR DATA
31
+ ELSE ENDCASE ENDIF ENDPROC ENDWHILE END ENVELOPE FOR GCOL GOSUB GOTO
32
+ IF INSTALL LET LIBRARY MODE NEXT OFF OF ON ORIGIN OSCI OTHERWISE
33
+ OVERLAY PLOT PRINT# PRINT PROC QUIT READ REPEAT REPORT RETURN SOUND
34
+ STEP STEREO STOP SWAP SYS THEN TINT TO VDU VOICES VOICE UNTIL WAIT
35
+ WHEN WHILE WIDTH
36
+ )
37
+ end
38
+
39
+ def self.operator
40
+ @operator ||= %w(
41
+ << <= <> < >= >>> >> > [-!$()*+/=?^|] AND DIV EOR MOD NOT OR
42
+ )
43
+ end
44
+
45
+ def self.constant
46
+ @constant ||= %w(
47
+ FALSE TRUE
48
+ )
49
+ end
50
+
51
+ state :expression do
52
+ rule %r/#{BBCBASIC.function.join('|')}/o, Name::Builtin # function or pseudo-variable
53
+ rule %r/#{BBCBASIC.operator.join('|')}/o, Operator
54
+ rule %r/#{BBCBASIC.constant.join('|')}/o, Name::Constant
55
+ rule %r/"[^"]*"/o, Literal::String
56
+ rule %r/[a-z_`][\w`]*[$%]?/io, Name::Variable
57
+ rule %r/@%/o, Name::Variable
58
+ rule %r/[\d.]+/o, Literal::Number
59
+ rule %r/%[01]+/o, Literal::Number::Bin
60
+ rule %r/&[\h]+/o, Literal::Number::Hex
61
+ end
62
+
63
+ state :root do
64
+ rule %r/(:+)( *)(\*)(.*)/ do
65
+ groups Punctuation, Text, Keyword, Text # CLI command
66
+ end
67
+ rule %r/(\n+ *)(\*)(.*)/ do
68
+ groups Text, Keyword, Text # CLI command
69
+ end
70
+ rule %r/(ELSE|OTHERWISE|REPEAT|THEN)( *)(\*)(.*)/ do
71
+ groups Keyword, Text, Keyword, Text # CLI command
72
+ end
73
+ rule %r/[ \n]+/o, Text
74
+ rule %r/:+/o, Punctuation
75
+ rule %r/[\[]/o, Keyword, :assembly1
76
+ rule %r/REM *>.*/o, Comment::Special
77
+ rule %r/REM.*/o, Comment
78
+ rule %r/(?:#{BBCBASIC.statement.join('|')}|CIRCLE(?: *FILL)?|DEF *(?:FN|PROC)|DRAW(?: *BY)?|DIM(?!\()|ELLIPSE(?: *FILL)?|ERROR(?: *EXT)?|FILL(?: *BY)?|INPUT(?:#| *LINE)?|LINE(?: *INPUT)?|LOCAL(?: *DATA| *ERROR)?|MOUSE(?: *COLOUR| *OFF| *ON| *RECTANGLE| *STEP| *TO)?|MOVE(?: *BY)?|ON(?! *ERROR)|ON *ERROR *(?:LOCAL|OFF)?|POINT(?: *BY)?(?!\()|RECTANGE(?: *FILL)?|RESTORE(?: *DATA| *ERROR)?|TRACE(?: *CLOSE| *ENDPROC| *OFF| *STEP(?: *FN| *ON| *PROC)?| *TO)?)/o, Keyword
79
+ mixin :expression
80
+ rule %r/#{BBCBASIC.punctuation.join('|')}/o, Punctuation
81
+ end
82
+
83
+ # Assembly statements are parsed as
84
+ # {label} {directive|opcode |']' {expressions}} {comment}
85
+ # Technically, you don't need whitespace between opcodes and arguments,
86
+ # but this is rare in uncrunched source and trying to enumerate all
87
+ # possible opcodes here is impractical so we colour it as though
88
+ # the whitespace is required. Opcodes and directives can only easily be
89
+ # distinguished from the symbols that make up expressions by looking at
90
+ # their position within the statement. Similarly, ']' is treated as a
91
+ # keyword at the start of a statement or as punctuation elsewhere. This
92
+ # requires a two-state state machine.
93
+
94
+ state :assembly1 do
95
+ rule %r/ +/o, Text
96
+ rule %r/]/o, Keyword, :pop!
97
+ rule %r/[:\n]/o, Punctuation
98
+ rule %r/\.[a-z_`][\w`]*%? */io, Name::Label
99
+ rule %r/(?:REM|;)[^:\n]*/o, Comment
100
+ rule %r/[^ :\n]+/o, Keyword, :assembly2
101
+ end
102
+
103
+ state :assembly2 do
104
+ rule %r/ +/o, Text
105
+ rule %r/[:\n]/o, Punctuation, :pop!
106
+ rule %r/(?:REM|;)[^:\n]*/o, Comment, :pop!
107
+ mixin :expression
108
+ rule %r/[!#,@\[\]^{}]/, Punctuation
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,34 @@
1
+ # -*- coding: utf-8 -*- #
2
+ # frozen_string_literal: true
3
+
4
+ module Rouge
5
+ module Lexers
6
+ class CMHG < RegexLexer
7
+ title "CMHG"
8
+ desc "RISC OS C module header generator source file"
9
+ tag 'cmhg'
10
+ filenames '*.cmhg'
11
+
12
+ def self.preproc_keyword
13
+ @preproc_keyword ||= %w(
14
+ define elif else endif error if ifdef ifndef include line pragma undef warning
15
+ )
16
+ end
17
+
18
+ state :root do
19
+ rule %r/;[^\n]*/, Comment
20
+ rule %r/^([ \t]*)(#[ \t]*(?:(?:#{CMHG.preproc_keyword.join('|')})(?:[ \t].*)?)?)(?=\n)/ do
21
+ groups Text, Comment::Preproc
22
+ end
23
+ rule %r/[-a-z]+:/, Keyword::Declaration
24
+ rule %r/[a-z_]\w+/i, Name::Entity
25
+ rule %r/"[^"]*"/, Literal::String
26
+ rule %r/(?:&|0x)\h+/, Literal::Number::Hex
27
+ rule %r/\d+/, Literal::Number
28
+ rule %r/[,\/()]/, Punctuation
29
+ rule %r/[ \t]+/, Text
30
+ rule %r/\n+/, Text
31
+ end
32
+ end
33
+ end
34
+ end
@@ -116,7 +116,7 @@ module Rouge
116
116
  # before we pass to the lang lexer so it can determine where
117
117
  # the "real" beginning of the line is
118
118
  $' =~ /\A\s*/
119
- yield Text, $& unless $&.empty?
119
+ yield Text::Whitespace, $& unless $&.empty?
120
120
 
121
121
  lang_lexer.continue_lex($', &output)
122
122
  elsif comment_regex =~ input[0].strip
@@ -17,7 +17,7 @@ module Rouge
17
17
  '*.cc', '*.hh',
18
18
  '*.cxx', '*.hxx',
19
19
  '*.pde', '*.ino',
20
- '*.tpp'
20
+ '*.tpp', '*.h'
21
21
  mimetypes 'text/x-c++hdr', 'text/x-c++src'
22
22
 
23
23
  def self.keywords
@@ -58,9 +58,11 @@ module Rouge
58
58
 
59
59
  prepend :statements do
60
60
  rule %r/class\b/, Keyword, :classname
61
+ rule %r/\d+(\.\d+)?(?:h|(?:min)|s|(?:ms)|(?:us)|(?:ns))/, Num::Other
61
62
  rule %r((#{dq}[.]#{dq}?|[.]#{dq})(e[+-]?#{dq}[lu]*)?)i, Num::Float
62
63
  rule %r(#{dq}e[+-]?#{dq}[lu]*)i, Num::Float
63
64
  rule %r/0x\h('?\h)*[lu]*/i, Num::Hex
65
+ rule %r/0b[01]+(?:_[01]+)*/, Num::Bin
64
66
  rule %r/0[0-7]('?[0-7])*[lu]*/i, Num::Oct
65
67
  rule %r/#{dq}[lu]*/i, Num::Integer
66
68
  rule %r/\bnullptr\b/, Name::Builtin
@@ -72,6 +74,7 @@ module Rouge
72
74
 
73
75
  # template specification
74
76
  rule %r/\s*(?=>)/m, Text, :pop!
77
+ rule %r/[.]{3}/, Operator
75
78
  mixin :whitespace
76
79
  end
77
80
  end
@@ -0,0 +1,35 @@
1
+ # -*- coding: utf-8 -*- #
2
+
3
+ module Rouge
4
+ module Lexers
5
+ load_lexer 'cpp.rb'
6
+
7
+ class CUDA < Cpp
8
+ title "CUDA"
9
+ desc "Compute Unified Device Architecture, used for programming with NVIDIA GPU"
10
+
11
+ tag 'cuda'
12
+ filenames '*.cu', '*.cuh'
13
+
14
+ def self.keywords
15
+ @keywords ||= super + Set.new(%w(
16
+ __global__ __device__ __host__ __noinline__ __forceinline__
17
+ __constant__ __shared__ __managed__ __restrict__
18
+ ))
19
+ end
20
+
21
+ def self.keywords_type
22
+ @keywords_type ||= super + Set.new(%w(
23
+ char1 char2 char3 char4 uchar1 uchar2 uchar3 uchar4
24
+ short1 short2 short3 short4 ushort1 ushort2 ushort3 ushort4
25
+ int1 int2 int3 int4 uint1 uint2 uint3 uint4
26
+ long1 long2 long3 long4 ulong1 ulong2 ulong3 ulong4
27
+ longlong1 longlong2 longlong3 longlong4
28
+ ulonglong1 ulonglong2 ulonglong3 ulonglong4
29
+ float1 float2 float3 float4 double1 double2 double3 double4
30
+ dim3
31
+ ))
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,151 @@
1
+ # -*- coding: utf-8 -*- #
2
+ # frozen_string_literal: true
3
+
4
+ module Rouge
5
+ module Lexers
6
+ load_lexer 'python.rb'
7
+
8
+ class Cython < Python
9
+ title "Cython"
10
+ desc "Cython and Pyrex source code (cython.org)"
11
+ tag 'cython'
12
+ aliases 'pyx', 'pyrex'
13
+ filenames '*.pyx', '*.pxd', '*.pxi'
14
+ mimetypes 'text/x-cython', 'application/x-cython'
15
+
16
+ def initialize(opts = {})
17
+ super opts
18
+ @indentation = nil
19
+ end
20
+
21
+ def self.keywords
22
+ @keywords ||= super + %w(
23
+ by except? fused gil nogil
24
+ )
25
+ end
26
+
27
+ def self.c_keywords
28
+ @ckeywords ||= %w(
29
+ public readonly extern api inline enum union
30
+ )
31
+ end
32
+
33
+ identifier = /[a-z_]\w*/i
34
+ dotted_identifier = /[a-z_.][\w.]*/i
35
+
36
+ prepend :root do
37
+ rule %r/cp?def|ctypedef/ do
38
+ token Keyword
39
+ push :c_definitions
40
+ push :c_start
41
+ end
42
+
43
+ rule %r/(from)((?:\\\s|\s)+)(#{dotted_identifier})((?:\\\s|\s)+)(cimport)/ do
44
+ groups Keyword::Namespace,
45
+ Text,
46
+ Name::Namespace,
47
+ Text,
48
+ Keyword::Namespace
49
+ end
50
+
51
+ rule %r/(cimport)(\s+)(#{dotted_identifier})/ do
52
+ groups Keyword::Namespace, Text, Name::Namespace
53
+ end
54
+
55
+ rule %r/(struct)((?:\\\s|\s)+)/ do
56
+ groups Keyword, Text
57
+ push :classname
58
+ end
59
+
60
+ mixin :func_call_fix
61
+
62
+ rule %r/[(,]/, Punctuation, :c_start
63
+ end
64
+
65
+ prepend :classname do
66
+ rule %r/(?:\\\s|\s)+/, Text
67
+ end
68
+
69
+ prepend :funcname do
70
+ rule %r/(?:\\\s|\s)+/, Text
71
+ end
72
+ # This is a fix for the way that function calls are lexed in the Python
73
+ # lexer. This should be moved to the Python lexer once confirmed that it
74
+ # does not cause any regressions.
75
+ state :func_call_fix do
76
+ rule %r/#{identifier}(?=\()/ do |m|
77
+ if self.class.keywords.include? m[0]
78
+ token Keyword
79
+ elsif self.class.exceptions.include? m[0]
80
+ token Name::Builtin
81
+ elsif self.class.builtins.include? m[0]
82
+ token Name::Builtin
83
+ elsif self.class.builtins_pseudo.include? m[0]
84
+ token Name::Builtin::Pseudo
85
+ else
86
+ token Name::Function
87
+ end
88
+ end
89
+ end
90
+
91
+ # The Cython lexer adds three states to those already in the Python lexer.
92
+ # Calls to `cdef`, `cpdef` and `ctypedef` move the lexer into the :c_start
93
+ # state. The primary purpose of this state is to highlight datatypes. Once
94
+ # this has been done, the lexer moves to the :c_definitions state where
95
+ # the majority of text in a definition is lexed. Finally, newlines cause
96
+ # the lexer to move to :c_indent. This state is used to check whether we
97
+ # have moved out of a C block.
98
+
99
+ state :c_start do
100
+ rule %r/[^\S\n]+/, Text
101
+
102
+ rule %r/cp?def|ctypedef/, Keyword
103
+
104
+ rule %r/(?:un)?signed/, Keyword::Type
105
+
106
+ # This rule matches identifiers that could be type declarations. The
107
+ # lookahead matches (1) pointers, (2) arrays and (3) variable names.
108
+ rule %r/#{identifier}(?=(?:\*+)|(?:[ \t]*\[)|(?:[ \t]+\w))/ do |m|
109
+ if self.class.keywords.include? m[0]
110
+ token Keyword
111
+ pop!
112
+ elsif %w(def).include? m[0]
113
+ token Keyword
114
+ goto :funcname
115
+ elsif %w(struct class).include? m[0]
116
+ token Keyword::Reserved
117
+ goto :classname
118
+ elsif self.class.c_keywords.include? m[0]
119
+ token Keyword::Reserved
120
+ else
121
+ token Keyword::Type
122
+ pop!
123
+ end
124
+ end
125
+
126
+ rule(//) { pop! }
127
+ end
128
+
129
+ state :c_definitions do
130
+ rule %r/\n/, Text, :c_indent
131
+ mixin :root
132
+ end
133
+
134
+ state :c_indent do
135
+ rule %r/[ \t]+/ do |m|
136
+ token Text
137
+ goto :c_start
138
+
139
+ if @indentation.nil?
140
+ @indentation = m[0]
141
+ elsif @indentation.length > m[0].length
142
+ @indentation = nil
143
+ pop! 2 # Pop :c_start and :c_definitions
144
+ end
145
+ end
146
+
147
+ rule(//) { @indentation = nil; reset_stack }
148
+ end
149
+ end
150
+ end
151
+ end
@@ -0,0 +1,51 @@
1
+ # -*- coding: utf-8 -*- #
2
+
3
+ module Rouge
4
+ module Lexers
5
+ class EPP < TemplateLexer
6
+ title "EPP"
7
+ desc "Embedded Puppet template files"
8
+
9
+ tag 'epp'
10
+
11
+ filenames '*.epp'
12
+
13
+ def initialize(opts={})
14
+ super(opts)
15
+ @parent = lexer_option(:parent) { PlainText.new(opts) }
16
+ @puppet_lexer = Puppet.new(opts)
17
+ end
18
+
19
+ start do
20
+ parent.reset!
21
+ @puppet_lexer.reset!
22
+ end
23
+
24
+ open = /<%%|<%=|<%#|(<%-|<%)(\s*\|)?/
25
+ close = /%%>|(\|\s*)?(-%>|%>)/
26
+
27
+ state :root do
28
+ rule %r/<%#/, Comment, :comment
29
+
30
+ rule open, Comment::Preproc, :puppet
31
+
32
+ rule %r/.+?(?=#{open})|.+/m do
33
+ delegate parent
34
+ end
35
+ end
36
+
37
+ state :comment do
38
+ rule close, Comment, :pop!
39
+ rule %r/.+?(?=#{close})|.+/m, Comment
40
+ end
41
+
42
+ state :puppet do
43
+ rule close, Comment::Preproc, :pop!
44
+
45
+ rule %r/.+?(?=#{close})|.+/m do
46
+ delegate @puppet_lexer
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1,3 +1,6 @@
1
+ # -*- coding: utf-8 -*- #
2
+ # frozen_string_literal: true
3
+
1
4
  module Rouge
2
5
  module Lexers
3
6
  class Escape < Lexer
@@ -0,0 +1,171 @@
1
+ # -*- coding: utf-8 -*- #
2
+ # frozen_string_literal: true
3
+
4
+ module Rouge
5
+ module Lexers
6
+ class GDScript < RegexLexer
7
+ title "GDScript"
8
+ desc "The Godot Engine programming language (https://godotengine.org/)"
9
+ tag 'gdscript'
10
+ aliases 'gd', 'gdscript'
11
+ filenames '*.gd'
12
+ mimetypes 'text/x-gdscript', 'application/x-gdscript'
13
+
14
+ def self.keywords
15
+ @keywords = %w(
16
+ and in not or as breakpoint class class_name extends is func setget
17
+ signal tool const enum export onready static var break continue
18
+ if elif else for pass return match while remote master puppet
19
+ remotesync mastersync puppetsync
20
+ ).join('|')
21
+ end
22
+
23
+ # Reserved for future implementation
24
+ def self.keywords_reserved
25
+ @keywords_reserved = %w(
26
+ do switch case
27
+ ).join('|')
28
+ end
29
+
30
+ def self.builtins
31
+ builtins = %w(
32
+ Color8 ColorN abs acos asin assert atan atan2 bytes2var ceil char
33
+ clamp convert cos cosh db2linear decimals dectime deg2rad dict2inst
34
+ ease exp floor fmod fposmod funcref hash inst2dict instance_from_id
35
+ is_inf is_nan lerp linear2db load log max min nearest_po2 pow
36
+ preload print print_stack printerr printraw prints printt rad2deg
37
+ rand_range rand_seed randf randi randomize range round seed sign
38
+ sin sinh sqrt stepify str str2var tan tan tanh type_exist typeof
39
+ var2bytes var2str weakref yield
40
+ ).join('|')
41
+ end
42
+
43
+ def self.builtins_type
44
+ @builtins_type = %w(
45
+ bool int float String Vector2 Rect2 Transform2D Vector3 AABB
46
+ Plane Quat Basis Transform Color RID Object NodePath Dictionary
47
+ Array PoolByteArray PoolIntArray PoolRealArray PoolStringArray
48
+ PoolVector2Array PoolVector3Array PoolColorArray null
49
+ ).join('|')
50
+ end
51
+
52
+ state :root do
53
+ rule %r/\n/, Text
54
+ rule %r/[^\S\n]+/, Text
55
+ rule %r/#.*/, Comment::Single
56
+ rule %r/[\[\]{}:(),;]/, Punctuation
57
+ rule %r/\\\n/, Text
58
+ rule %r/(in|and|or|not)\b/, Operator::Word
59
+ rule %r/!=|==|<<|>>|&&|\+=|-=|\*=|\/=|%=|&=|\|=|\|\||[-~+\/*%=<>&^.!|$]/, Operator
60
+ rule %r/(func)((?:\s|\\)+)/ do
61
+ groups Keyword, Text
62
+ push :funcname
63
+ end
64
+ rule %r/(class)((?:\s|\\)+)/ do
65
+ groups Keyword, Text
66
+ push :classname
67
+ end
68
+ mixin :keywords
69
+ mixin :builtins
70
+ rule %r/"""/, Str::Double, :escape_tdqs
71
+ rule %r/'''/, Str::Double, :escape_tsqs
72
+ rule %r/"/, Str::Double, :escape_dqs
73
+ rule %r/'/, Str::Double, :escape_sqs
74
+ mixin :name
75
+ mixin :numbers
76
+ end
77
+
78
+ state :keywords do
79
+ rule %r/\b(#{GDScript.keywords})\b/, Keyword
80
+ rule %r/\b(#{GDScript.keywords_reserved})\b/, Keyword::Reserved
81
+ end
82
+
83
+ state :builtins do
84
+ rule %r/\b(#{GDScript.builtins})\b/, Name::Builtin
85
+ rule %r/\b((self|false|true)|(PI|TAU|NAN|INF))\b/, Name::Builtin::Pseudo
86
+ rule %r/\b(#{GDScript.builtins_type})\b/, Keyword::Type
87
+ end
88
+
89
+ state :numbers do
90
+ rule %r/(\d+\.\d*|\d*\.\d+)([eE][+-]?[0-9]+)?j?/, Num::Float
91
+ rule %r/\d+[eE][+-]?[0-9]+j?/, Num::Float
92
+ rule %r/0[xX][a-fA-F0-9]+/, Num::Hex
93
+ rule %r/\d+j?/, Num::Integer
94
+ end
95
+
96
+ state :name do
97
+ rule %r/[a-zA-Z_]\w*/, Name
98
+ end
99
+
100
+ state :funcname do
101
+ rule %r/[a-zA-Z_]\w*/, Name::Function, :pop!
102
+ end
103
+
104
+ state :classname do
105
+ rule %r/[a-zA-Z_]\w*/, Name::Class, :pop!
106
+ end
107
+
108
+ state :string_escape do
109
+ rule %r/\\([\\abfnrtv"\']|\n|N\{.*?\}|u[a-fA-F0-9]{4}|U[a-fA-F0-9]{8}|x[a-fA-F0-9]{2}|[0-7]{1,3})/, Str::Escape
110
+ end
111
+
112
+ state :strings_single do
113
+ rule %r/%(\(\w+\))?[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?[hlL]?[E-GXc-giorsux%]/, Str::Interpol
114
+ rule %r/[^\\'%\n]+/, Str::Single
115
+ rule %r/["\\]/, Str::Single
116
+ rule %r/%/, Str::Single
117
+ end
118
+
119
+ state :strings_double do
120
+ rule %r/%(\(\w+\))?[-#0 +]*([0-9]+|[*])?(\.([0-9]+|[*]))?[hlL]?[E-GXc-giorsux%]/, Str::Interpol
121
+ rule %r/[^\\"%\n]+/, Str::Double
122
+ rule %r/['\\]/, Str::Double
123
+ rule %r/%/, Str::Double
124
+ end
125
+
126
+ state :dqs do
127
+ rule %r/"/, Str::Double, :pop!
128
+ rule %r/\\\\|\\"|\\\n/, Str::Escape
129
+ mixin :strings_double
130
+ end
131
+
132
+ state :escape_dqs do
133
+ mixin :string_escape
134
+ mixin :dqs
135
+ end
136
+
137
+ state :sqs do
138
+ rule %r/'/, Str::Single, :pop!
139
+ rule %r/\\\\|\\'|\\\n/, Str::Escape
140
+ mixin :strings_single
141
+ end
142
+
143
+ state :escape_sqs do
144
+ mixin :string_escape
145
+ mixin :sqs
146
+ end
147
+
148
+ state :tdqs do
149
+ rule %r/"""/, Str::Double, :pop!
150
+ mixin :strings_double
151
+ rule %r/\n/, Str::Double
152
+ end
153
+
154
+ state :escape_tdqs do
155
+ mixin :string_escape
156
+ mixin :tdqs
157
+ end
158
+
159
+ state :tsqs do
160
+ rule %r/'''/, Str::Single, :pop!
161
+ mixin :strings_single
162
+ rule %r/\n/, Str::Single
163
+ end
164
+
165
+ state :escape_tsqs do
166
+ mixin :string_escape
167
+ mixin :tsqs
168
+ end
169
+ end
170
+ end
171
+ end