rouge 3.6.0 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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