1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
|
# -*- coding: utf-8 -*- #
# frozen_string_literal: true
module Rouge
module Lexers
# shared states with SCSS
class SassCommon < RegexLexer
id = /[\w-]+/
state :content_common do
rule %r/@for\b/, Keyword, :for
rule %r/@(debug|warn|if|each|while|else|return|media)/, Keyword, :value
rule %r/(@mixin)(\s+)(#{id})/ do
groups Keyword, Text, Name::Function
push :value
end
rule %r/(@function)(\s+)(#{id})/ do
groups Keyword, Text, Name::Function
push :value
end
rule %r/@extend\b/, Keyword, :selector
rule %r/(@include)(\s+)(#{id})/ do
groups Keyword, Text, Name::Decorator
push :value
end
rule %r/@#{id}/, Keyword, :selector
rule %r/&/, Keyword, :selector
# $variable: assignment
rule %r/([$]#{id})([ \t]*)(:)/ do
groups Name::Variable, Text, Punctuation
push :value
end
end
state :value do
mixin :end_section
rule %r/[ \t]+/, Text
rule %r/[$]#{id}/, Name::Variable
rule %r/url[(]/, Str::Other, :string_url
rule %r/#{id}(?=\s*[(])/, Name::Function
rule %r/%#{id}/, Name::Decorator
# named literals
rule %r/(true|false)\b/, Name::Builtin::Pseudo
rule %r/(and|or|not)\b/, Operator::Word
# colors and numbers
rule %r/#[a-z0-9]{1,6}/i, Num::Hex
rule %r/-?\d+(%|[a-z]+)?/, Num
rule %r/-?\d*\.\d+(%|[a-z]+)?/, Num::Integer
mixin :has_strings
mixin :has_interp
rule %r/[~^*!&%<>\|+=@:,.\/?-]+/, Operator
rule %r/[\[\]()]+/, Punctuation
rule %r(/[*]), Comment::Multiline, :inline_comment
rule %r(//[^\n]*), Comment::Single
# identifiers
rule(id) do |m|
if CSS.builtins.include? m[0]
token Name::Builtin
elsif CSS.constants.include? m[0]
token Name::Constant
else
token Name
end
end
end
state :has_interp do
rule %r/[#][{]/, Str::Interpol, :interpolation
end
state :has_strings do
rule %r/"/, Str::Double, :dq
rule %r/'/, Str::Single, :sq
end
state :interpolation do
rule %r/}/, Str::Interpol, :pop!
mixin :value
end
state :selector do
mixin :end_section
mixin :has_strings
mixin :has_interp
rule %r/[ \t]+/, Text
rule %r/:/, Name::Decorator, :pseudo_class
rule %r/[.]/, Name::Class, :class
rule %r/#/, Name::Namespace, :id
rule %r/%/, Name::Variable, :placeholder
rule id, Name::Tag
rule %r/&/, Keyword
rule %r/[~^*!&\[\]()<>\|+=@:;,.\/?-]/, Operator
end
state :dq do
rule %r/"/, Str::Double, :pop!
mixin :has_interp
rule %r/(\\.|#(?![{])|[^\n"#])+/, Str::Double
end
state :sq do
rule %r/'/, Str::Single, :pop!
mixin :has_interp
rule %r/(\\.|#(?![{])|[^\n'#])+/, Str::Single
end
state :string_url do
rule %r/[)]/, Str::Other, :pop!
rule %r/(\\.|#(?![{])|[^\n)#])+/, Str::Other
mixin :has_interp
end
state :selector_piece do
mixin :has_interp
rule(//) { pop! }
end
state :pseudo_class do
rule id, Name::Decorator
mixin :selector_piece
end
state :class do
rule id, Name::Class
mixin :selector_piece
end
state :id do
rule id, Name::Namespace
mixin :selector_piece
end
state :placeholder do
rule id, Name::Variable
mixin :selector_piece
end
state :for do
rule %r/(from|to|through)/, Operator::Word
mixin :value
end
state :attr_common do
mixin :has_interp
rule id do |m|
if CSS.properties.include? m[0]
token Name::Label
else
token Name::Attribute
end
end
end
state :attribute do
mixin :attr_common
rule %r/([ \t]*)(:)/ do
groups Text, Punctuation
push :value
end
end
state :inline_comment do
rule %r/(\\#|#(?=[^\n{])|\*(?=[^\n\/])|[^\n#*])+/, Comment::Multiline
mixin :has_interp
rule %r([*]/), Comment::Multiline, :pop!
end
end
end
end
|