giga-fast-rb 0.0.1
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.
- checksums.yaml +7 -0
- data/coderay-1.1.3/MIT-LICENSE +22 -0
- data/coderay-1.1.3/README_INDEX.rdoc +123 -0
- data/coderay-1.1.3/bin/coderay +215 -0
- data/coderay-1.1.3/lib/coderay/duo.rb +81 -0
- data/coderay-1.1.3/lib/coderay/encoders/_map.rb +17 -0
- data/coderay-1.1.3/lib/coderay/encoders/comment_filter.rb +25 -0
- data/coderay-1.1.3/lib/coderay/encoders/count.rb +39 -0
- data/coderay-1.1.3/lib/coderay/encoders/debug.rb +49 -0
- data/coderay-1.1.3/lib/coderay/encoders/debug_lint.rb +63 -0
- data/coderay-1.1.3/lib/coderay/encoders/div.rb +23 -0
- data/coderay-1.1.3/lib/coderay/encoders/encoder.rb +190 -0
- data/coderay-1.1.3/lib/coderay/encoders/filter.rb +58 -0
- data/coderay-1.1.3/lib/coderay/encoders/html/css.rb +65 -0
- data/coderay-1.1.3/lib/coderay/encoders/html/numbering.rb +108 -0
- data/coderay-1.1.3/lib/coderay/encoders/html/output.rb +164 -0
- data/coderay-1.1.3/lib/coderay/encoders/html.rb +333 -0
- data/coderay-1.1.3/lib/coderay/encoders/json.rb +83 -0
- data/coderay-1.1.3/lib/coderay/encoders/lines_of_code.rb +45 -0
- data/coderay-1.1.3/lib/coderay/encoders/lint.rb +59 -0
- data/coderay-1.1.3/lib/coderay/encoders/null.rb +18 -0
- data/coderay-1.1.3/lib/coderay/encoders/page.rb +24 -0
- data/coderay-1.1.3/lib/coderay/encoders/span.rb +23 -0
- data/coderay-1.1.3/lib/coderay/encoders/statistic.rb +95 -0
- data/coderay-1.1.3/lib/coderay/encoders/terminal.rb +195 -0
- data/coderay-1.1.3/lib/coderay/encoders/text.rb +46 -0
- data/coderay-1.1.3/lib/coderay/encoders/token_kind_filter.rb +111 -0
- data/coderay-1.1.3/lib/coderay/encoders/xml.rb +72 -0
- data/coderay-1.1.3/lib/coderay/encoders/yaml.rb +50 -0
- data/coderay-1.1.3/lib/coderay/encoders.rb +18 -0
- data/coderay-1.1.3/lib/coderay/for_redcloth.rb +95 -0
- data/coderay-1.1.3/lib/coderay/helpers/file_type.rb +151 -0
- data/coderay-1.1.3/lib/coderay/helpers/plugin.rb +55 -0
- data/coderay-1.1.3/lib/coderay/helpers/plugin_host.rb +221 -0
- data/coderay-1.1.3/lib/coderay/helpers/word_list.rb +72 -0
- data/coderay-1.1.3/lib/coderay/scanners/_map.rb +24 -0
- data/coderay-1.1.3/lib/coderay/scanners/c.rb +189 -0
- data/coderay-1.1.3/lib/coderay/scanners/clojure.rb +217 -0
- data/coderay-1.1.3/lib/coderay/scanners/cpp.rb +217 -0
- data/coderay-1.1.3/lib/coderay/scanners/css.rb +196 -0
- data/coderay-1.1.3/lib/coderay/scanners/debug.rb +75 -0
- data/coderay-1.1.3/lib/coderay/scanners/delphi.rb +144 -0
- data/coderay-1.1.3/lib/coderay/scanners/diff.rb +221 -0
- data/coderay-1.1.3/lib/coderay/scanners/erb.rb +81 -0
- data/coderay-1.1.3/lib/coderay/scanners/go.rb +208 -0
- data/coderay-1.1.3/lib/coderay/scanners/groovy.rb +268 -0
- data/coderay-1.1.3/lib/coderay/scanners/haml.rb +168 -0
- data/coderay-1.1.3/lib/coderay/scanners/html.rb +275 -0
- data/coderay-1.1.3/lib/coderay/scanners/java/builtin_types.rb +421 -0
- data/coderay-1.1.3/lib/coderay/scanners/java.rb +174 -0
- data/coderay-1.1.3/lib/coderay/scanners/java_script.rb +236 -0
- data/coderay-1.1.3/lib/coderay/scanners/json.rb +98 -0
- data/coderay-1.1.3/lib/coderay/scanners/lua.rb +280 -0
- data/coderay-1.1.3/lib/coderay/scanners/php.rb +527 -0
- data/coderay-1.1.3/lib/coderay/scanners/python.rb +287 -0
- data/coderay-1.1.3/lib/coderay/scanners/raydebug.rb +75 -0
- data/coderay-1.1.3/lib/coderay/scanners/ruby/patterns.rb +178 -0
- data/coderay-1.1.3/lib/coderay/scanners/ruby/string_state.rb +79 -0
- data/coderay-1.1.3/lib/coderay/scanners/ruby.rb +477 -0
- data/coderay-1.1.3/lib/coderay/scanners/sass.rb +232 -0
- data/coderay-1.1.3/lib/coderay/scanners/scanner.rb +337 -0
- data/coderay-1.1.3/lib/coderay/scanners/sql.rb +169 -0
- data/coderay-1.1.3/lib/coderay/scanners/taskpaper.rb +36 -0
- data/coderay-1.1.3/lib/coderay/scanners/text.rb +26 -0
- data/coderay-1.1.3/lib/coderay/scanners/xml.rb +17 -0
- data/coderay-1.1.3/lib/coderay/scanners/yaml.rb +140 -0
- data/coderay-1.1.3/lib/coderay/scanners.rb +27 -0
- data/coderay-1.1.3/lib/coderay/styles/_map.rb +7 -0
- data/coderay-1.1.3/lib/coderay/styles/alpha.rb +153 -0
- data/coderay-1.1.3/lib/coderay/styles/style.rb +18 -0
- data/coderay-1.1.3/lib/coderay/styles.rb +15 -0
- data/coderay-1.1.3/lib/coderay/token_kinds.rb +85 -0
- data/coderay-1.1.3/lib/coderay/tokens.rb +164 -0
- data/coderay-1.1.3/lib/coderay/tokens_proxy.rb +55 -0
- data/coderay-1.1.3/lib/coderay/version.rb +3 -0
- data/coderay-1.1.3/lib/coderay.rb +284 -0
- data/giga-fast-rb.gemspec +12 -0
- metadata +117 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
module CodeRay
|
|
2
|
+
module Scanners
|
|
3
|
+
|
|
4
|
+
class Go < Scanner
|
|
5
|
+
|
|
6
|
+
register_for :go
|
|
7
|
+
file_extension 'go'
|
|
8
|
+
|
|
9
|
+
# http://golang.org/ref/spec#Keywords
|
|
10
|
+
KEYWORDS = [
|
|
11
|
+
'break', 'default', 'func', 'interface', 'select',
|
|
12
|
+
'case', 'defer', 'go', 'map', 'struct',
|
|
13
|
+
'chan', 'else', 'goto', 'package', 'switch',
|
|
14
|
+
'const', 'fallthrough', 'if', 'range', 'type',
|
|
15
|
+
'continue', 'for', 'import', 'return', 'var',
|
|
16
|
+
] # :nodoc:
|
|
17
|
+
|
|
18
|
+
# http://golang.org/ref/spec#Types
|
|
19
|
+
PREDEFINED_TYPES = [
|
|
20
|
+
'bool',
|
|
21
|
+
'uint8', 'uint16', 'uint32', 'uint64',
|
|
22
|
+
'int8', 'int16', 'int32', 'int64',
|
|
23
|
+
'float32', 'float64',
|
|
24
|
+
'complex64', 'complex128',
|
|
25
|
+
'byte', 'rune', 'string', 'error',
|
|
26
|
+
'uint', 'int', 'uintptr',
|
|
27
|
+
] # :nodoc:
|
|
28
|
+
|
|
29
|
+
PREDEFINED_CONSTANTS = [
|
|
30
|
+
'nil', 'iota',
|
|
31
|
+
'true', 'false',
|
|
32
|
+
] # :nodoc:
|
|
33
|
+
|
|
34
|
+
PREDEFINED_FUNCTIONS = %w[
|
|
35
|
+
append cap close complex copy delete imag len
|
|
36
|
+
make new panic print println real recover
|
|
37
|
+
] # :nodoc:
|
|
38
|
+
|
|
39
|
+
IDENT_KIND = WordList.new(:ident).
|
|
40
|
+
add(KEYWORDS, :keyword).
|
|
41
|
+
add(PREDEFINED_TYPES, :predefined_type).
|
|
42
|
+
add(PREDEFINED_CONSTANTS, :predefined_constant).
|
|
43
|
+
add(PREDEFINED_FUNCTIONS, :predefined) # :nodoc:
|
|
44
|
+
|
|
45
|
+
ESCAPE = / [rbfntv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc:
|
|
46
|
+
UNICODE_ESCAPE = / u[a-fA-F0-9]{4} | U[a-fA-F0-9]{8} /x # :nodoc:
|
|
47
|
+
|
|
48
|
+
protected
|
|
49
|
+
|
|
50
|
+
def scan_tokens encoder, options
|
|
51
|
+
|
|
52
|
+
state = :initial
|
|
53
|
+
label_expected = true
|
|
54
|
+
case_expected = false
|
|
55
|
+
label_expected_before_preproc_line = nil
|
|
56
|
+
in_preproc_line = false
|
|
57
|
+
|
|
58
|
+
until eos?
|
|
59
|
+
|
|
60
|
+
case state
|
|
61
|
+
|
|
62
|
+
when :initial
|
|
63
|
+
|
|
64
|
+
if match = scan(/ \s+ | \\\n /x)
|
|
65
|
+
if in_preproc_line && match != "\\\n" && match.index(?\n)
|
|
66
|
+
in_preproc_line = false
|
|
67
|
+
case_expected = false
|
|
68
|
+
label_expected = label_expected_before_preproc_line
|
|
69
|
+
end
|
|
70
|
+
encoder.text_token match, :space
|
|
71
|
+
|
|
72
|
+
elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx)
|
|
73
|
+
encoder.text_token match, :comment
|
|
74
|
+
|
|
75
|
+
elsif match = scan(/ <?- (?![\d.]) | [+*=<>?:;,!&^|()\[\]{}~%]+ | \/=? | \.(?!\d) /x)
|
|
76
|
+
if case_expected
|
|
77
|
+
label_expected = true if match == ':'
|
|
78
|
+
case_expected = false
|
|
79
|
+
end
|
|
80
|
+
encoder.text_token match, :operator
|
|
81
|
+
|
|
82
|
+
elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x)
|
|
83
|
+
kind = IDENT_KIND[match]
|
|
84
|
+
if kind == :ident && label_expected && !in_preproc_line && scan(/:(?!:)/)
|
|
85
|
+
kind = :label
|
|
86
|
+
label_expected = false
|
|
87
|
+
match << matched
|
|
88
|
+
else
|
|
89
|
+
label_expected = false
|
|
90
|
+
if kind == :keyword
|
|
91
|
+
case match
|
|
92
|
+
when 'case', 'default'
|
|
93
|
+
case_expected = true
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
encoder.text_token match, kind
|
|
98
|
+
|
|
99
|
+
elsif match = scan(/L?"/)
|
|
100
|
+
encoder.begin_group :string
|
|
101
|
+
if match[0] == ?L
|
|
102
|
+
encoder.text_token 'L', :modifier
|
|
103
|
+
match = '"'
|
|
104
|
+
end
|
|
105
|
+
encoder.text_token match, :delimiter
|
|
106
|
+
state = :string
|
|
107
|
+
|
|
108
|
+
elsif match = scan(/ ` ([^`]+)? (`)? /x)
|
|
109
|
+
encoder.begin_group :shell
|
|
110
|
+
encoder.text_token '`', :delimiter
|
|
111
|
+
encoder.text_token self[1], :content if self[1]
|
|
112
|
+
encoder.text_token self[2], :delimiter if self[2]
|
|
113
|
+
encoder.end_group :shell
|
|
114
|
+
|
|
115
|
+
elsif match = scan(/ \# \s* if \s* 0 /x)
|
|
116
|
+
match << scan_until(/ ^\# (?:elif|else|endif) .*? $ | \z /xm) unless eos?
|
|
117
|
+
encoder.text_token match, :comment
|
|
118
|
+
|
|
119
|
+
elsif match = scan(/#[ \t]*(\w*)/)
|
|
120
|
+
encoder.text_token match, :preprocessor
|
|
121
|
+
in_preproc_line = true
|
|
122
|
+
label_expected_before_preproc_line = label_expected
|
|
123
|
+
state = :include_expected if self[1] == 'include'
|
|
124
|
+
|
|
125
|
+
elsif match = scan(/ L?' (?: [^\'\n\\] | \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) )? '? /ox)
|
|
126
|
+
label_expected = false
|
|
127
|
+
encoder.text_token match, :char
|
|
128
|
+
|
|
129
|
+
elsif match = scan(/\$/)
|
|
130
|
+
encoder.text_token match, :ident
|
|
131
|
+
|
|
132
|
+
elsif match = scan(/-?\d*(\.\d*)?([eE][+-]?\d+)?i/)
|
|
133
|
+
label_expected = false
|
|
134
|
+
encoder.text_token match, :imaginary
|
|
135
|
+
|
|
136
|
+
elsif match = scan(/-?0[xX][0-9A-Fa-f]+/)
|
|
137
|
+
label_expected = false
|
|
138
|
+
encoder.text_token match, :hex
|
|
139
|
+
|
|
140
|
+
elsif match = scan(/-?(?:0[0-7]+)(?![89.eEfF])/)
|
|
141
|
+
label_expected = false
|
|
142
|
+
encoder.text_token match, :octal
|
|
143
|
+
|
|
144
|
+
elsif match = scan(/-?(?:\d*\.\d+|\d+\.)(?:[eE][+-]?\d+)?|\d+[eE][+-]?\d+/)
|
|
145
|
+
label_expected = false
|
|
146
|
+
encoder.text_token match, :float
|
|
147
|
+
|
|
148
|
+
elsif match = scan(/-?(?:\d+)(?![.eEfF])L?L?/)
|
|
149
|
+
label_expected = false
|
|
150
|
+
encoder.text_token match, :integer
|
|
151
|
+
|
|
152
|
+
else
|
|
153
|
+
encoder.text_token getch, :error
|
|
154
|
+
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
when :string
|
|
158
|
+
if match = scan(/[^\\\n"]+/)
|
|
159
|
+
encoder.text_token match, :content
|
|
160
|
+
elsif match = scan(/"/)
|
|
161
|
+
encoder.text_token match, :delimiter
|
|
162
|
+
encoder.end_group :string
|
|
163
|
+
state = :initial
|
|
164
|
+
label_expected = false
|
|
165
|
+
elsif match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
|
|
166
|
+
encoder.text_token match, :char
|
|
167
|
+
elsif match = scan(/ \\ /x)
|
|
168
|
+
encoder.text_token match, :error
|
|
169
|
+
elsif match = scan(/$/)
|
|
170
|
+
encoder.end_group :string
|
|
171
|
+
state = :initial
|
|
172
|
+
label_expected = false
|
|
173
|
+
else
|
|
174
|
+
raise_inspect "else case \" reached; %p not handled." % peek(1), encoder
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
when :include_expected
|
|
178
|
+
if match = scan(/<[^>\n]+>?|"[^"\n\\]*(?:\\.[^"\n\\]*)*"?/)
|
|
179
|
+
encoder.text_token match, :include
|
|
180
|
+
state = :initial
|
|
181
|
+
|
|
182
|
+
elsif match = scan(/\s+/)
|
|
183
|
+
encoder.text_token match, :space
|
|
184
|
+
state = :initial if match.index ?\n
|
|
185
|
+
|
|
186
|
+
else
|
|
187
|
+
state = :initial
|
|
188
|
+
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
else
|
|
192
|
+
raise_inspect 'Unknown state', encoder
|
|
193
|
+
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
if state == :string
|
|
199
|
+
encoder.end_group :string
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
encoder
|
|
203
|
+
end
|
|
204
|
+
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
end
|
|
208
|
+
end
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
module CodeRay
|
|
2
|
+
module Scanners
|
|
3
|
+
|
|
4
|
+
load :java
|
|
5
|
+
|
|
6
|
+
# Scanner for Groovy.
|
|
7
|
+
class Groovy < Java
|
|
8
|
+
|
|
9
|
+
register_for :groovy
|
|
10
|
+
|
|
11
|
+
# TODO: check list of keywords
|
|
12
|
+
GROOVY_KEYWORDS = %w[
|
|
13
|
+
as assert def in
|
|
14
|
+
] # :nodoc:
|
|
15
|
+
KEYWORDS_EXPECTING_VALUE = WordList.new.add %w[
|
|
16
|
+
case instanceof new return throw typeof while as assert in
|
|
17
|
+
] # :nodoc:
|
|
18
|
+
GROOVY_MAGIC_VARIABLES = %w[ it ] # :nodoc:
|
|
19
|
+
|
|
20
|
+
IDENT_KIND = Java::IDENT_KIND.dup.
|
|
21
|
+
add(GROOVY_KEYWORDS, :keyword).
|
|
22
|
+
add(GROOVY_MAGIC_VARIABLES, :local_variable) # :nodoc:
|
|
23
|
+
|
|
24
|
+
ESCAPE = / [bfnrtv$\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x # :nodoc:
|
|
25
|
+
UNICODE_ESCAPE = / u[a-fA-F0-9]{4} /x # :nodoc: no 4-byte unicode chars? U[a-fA-F0-9]{8}
|
|
26
|
+
REGEXP_ESCAPE = / [bfnrtv\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} | \d | [bBdDsSwW\/] /x # :nodoc:
|
|
27
|
+
|
|
28
|
+
# TODO: interpretation inside ', ", /
|
|
29
|
+
STRING_CONTENT_PATTERN = {
|
|
30
|
+
"'" => /(?>\\[^\\'\n]+|[^\\'\n]+)+/,
|
|
31
|
+
'"' => /[^\\$"\n]+/,
|
|
32
|
+
"'''" => /(?>[^\\']+|'(?!''))+/,
|
|
33
|
+
'"""' => /(?>[^\\$"]+|"(?!""))+/,
|
|
34
|
+
'/' => /[^\\$\/\n]+/,
|
|
35
|
+
} # :nodoc:
|
|
36
|
+
|
|
37
|
+
protected
|
|
38
|
+
|
|
39
|
+
def setup
|
|
40
|
+
@state = :initial
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def scan_tokens encoder, options
|
|
44
|
+
state = options[:state] || @state
|
|
45
|
+
inline_block_stack = []
|
|
46
|
+
inline_block_paren_depth = nil
|
|
47
|
+
string_delimiter = nil
|
|
48
|
+
import_clause = class_name_follows = last_token = after_def = false
|
|
49
|
+
value_expected = true
|
|
50
|
+
|
|
51
|
+
until eos?
|
|
52
|
+
|
|
53
|
+
case state
|
|
54
|
+
|
|
55
|
+
when :initial
|
|
56
|
+
|
|
57
|
+
if match = scan(/ \s+ | \\\n /x)
|
|
58
|
+
encoder.text_token match, :space
|
|
59
|
+
if match.index ?\n
|
|
60
|
+
import_clause = after_def = false
|
|
61
|
+
value_expected = true unless value_expected
|
|
62
|
+
end
|
|
63
|
+
next
|
|
64
|
+
|
|
65
|
+
elsif match = scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx)
|
|
66
|
+
value_expected = true
|
|
67
|
+
after_def = false
|
|
68
|
+
encoder.text_token match, :comment
|
|
69
|
+
|
|
70
|
+
elsif bol? && match = scan(/ \#!.* /x)
|
|
71
|
+
encoder.text_token match, :doctype
|
|
72
|
+
|
|
73
|
+
elsif import_clause && match = scan(/ (?!as) #{IDENT} (?: \. #{IDENT} )* (?: \.\* )? /ox)
|
|
74
|
+
after_def = value_expected = false
|
|
75
|
+
encoder.text_token match, :include
|
|
76
|
+
|
|
77
|
+
elsif match = scan(/ #{IDENT} | \[\] /ox)
|
|
78
|
+
kind = IDENT_KIND[match]
|
|
79
|
+
value_expected = (kind == :keyword) && KEYWORDS_EXPECTING_VALUE[match]
|
|
80
|
+
if last_token == '.'
|
|
81
|
+
kind = :ident
|
|
82
|
+
elsif class_name_follows
|
|
83
|
+
kind = :class
|
|
84
|
+
class_name_follows = false
|
|
85
|
+
elsif after_def && check(/\s*[({]/)
|
|
86
|
+
kind = :method
|
|
87
|
+
after_def = false
|
|
88
|
+
elsif kind == :ident && last_token != '?' && check(/:/)
|
|
89
|
+
kind = :key
|
|
90
|
+
else
|
|
91
|
+
class_name_follows = true if match == 'class' || (import_clause && match == 'as')
|
|
92
|
+
import_clause = match == 'import'
|
|
93
|
+
after_def = true if match == 'def'
|
|
94
|
+
end
|
|
95
|
+
encoder.text_token match, kind
|
|
96
|
+
|
|
97
|
+
elsif match = scan(/;/)
|
|
98
|
+
import_clause = after_def = false
|
|
99
|
+
value_expected = true
|
|
100
|
+
encoder.text_token match, :operator
|
|
101
|
+
|
|
102
|
+
elsif match = scan(/\{/)
|
|
103
|
+
class_name_follows = after_def = false
|
|
104
|
+
value_expected = true
|
|
105
|
+
encoder.text_token match, :operator
|
|
106
|
+
if !inline_block_stack.empty?
|
|
107
|
+
inline_block_paren_depth += 1
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
# TODO: ~'...', ~"..." and ~/.../ style regexps
|
|
111
|
+
elsif match = scan(/ \.\.<? | \*?\.(?!\d)@? | \.& | \?:? | [,?:(\[] | -[->] | \+\+ |
|
|
112
|
+
&& | \|\| | \*\*=? | ==?~ | <=?>? | [-+*%^~&|>=!]=? | <<<?=? | >>>?=? /x)
|
|
113
|
+
value_expected = true
|
|
114
|
+
value_expected = :regexp if match == '~'
|
|
115
|
+
after_def = false
|
|
116
|
+
encoder.text_token match, :operator
|
|
117
|
+
|
|
118
|
+
elsif match = scan(/ [)\]}] /x)
|
|
119
|
+
value_expected = after_def = false
|
|
120
|
+
if !inline_block_stack.empty? && match == '}'
|
|
121
|
+
inline_block_paren_depth -= 1
|
|
122
|
+
if inline_block_paren_depth == 0 # closing brace of inline block reached
|
|
123
|
+
encoder.text_token match, :inline_delimiter
|
|
124
|
+
encoder.end_group :inline
|
|
125
|
+
state, string_delimiter, inline_block_paren_depth = inline_block_stack.pop
|
|
126
|
+
next
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
encoder.text_token match, :operator
|
|
130
|
+
|
|
131
|
+
elsif check(/[\d.]/)
|
|
132
|
+
after_def = value_expected = false
|
|
133
|
+
if match = scan(/0[xX][0-9A-Fa-f]+/)
|
|
134
|
+
encoder.text_token match, :hex
|
|
135
|
+
elsif match = scan(/(?>0[0-7]+)(?![89.eEfF])/)
|
|
136
|
+
encoder.text_token match, :octal
|
|
137
|
+
elsif match = scan(/\d+[fFdD]|\d*\.\d+(?:[eE][+-]?\d+)?[fFdD]?|\d+[eE][+-]?\d+[fFdD]?/)
|
|
138
|
+
encoder.text_token match, :float
|
|
139
|
+
elsif match = scan(/\d+[lLgG]?/)
|
|
140
|
+
encoder.text_token match, :integer
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
elsif match = scan(/'''|"""/)
|
|
144
|
+
after_def = value_expected = false
|
|
145
|
+
state = :multiline_string
|
|
146
|
+
encoder.begin_group :string
|
|
147
|
+
string_delimiter = match
|
|
148
|
+
encoder.text_token match, :delimiter
|
|
149
|
+
|
|
150
|
+
# TODO: record.'name' syntax
|
|
151
|
+
elsif match = scan(/["']/)
|
|
152
|
+
after_def = value_expected = false
|
|
153
|
+
state = match == '/' ? :regexp : :string
|
|
154
|
+
encoder.begin_group state
|
|
155
|
+
string_delimiter = match
|
|
156
|
+
encoder.text_token match, :delimiter
|
|
157
|
+
|
|
158
|
+
elsif value_expected && match = scan(/\//)
|
|
159
|
+
after_def = value_expected = false
|
|
160
|
+
encoder.begin_group :regexp
|
|
161
|
+
state = :regexp
|
|
162
|
+
string_delimiter = '/'
|
|
163
|
+
encoder.text_token match, :delimiter
|
|
164
|
+
|
|
165
|
+
elsif match = scan(/ @ #{IDENT} /ox)
|
|
166
|
+
after_def = value_expected = false
|
|
167
|
+
encoder.text_token match, :annotation
|
|
168
|
+
|
|
169
|
+
elsif match = scan(/\//)
|
|
170
|
+
after_def = false
|
|
171
|
+
value_expected = true
|
|
172
|
+
encoder.text_token match, :operator
|
|
173
|
+
|
|
174
|
+
else
|
|
175
|
+
encoder.text_token getch, :error
|
|
176
|
+
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
when :string, :regexp, :multiline_string
|
|
180
|
+
if match = scan(STRING_CONTENT_PATTERN[string_delimiter])
|
|
181
|
+
encoder.text_token match, :content
|
|
182
|
+
|
|
183
|
+
elsif match = scan(state == :multiline_string ? /'''|"""/ : /["'\/]/)
|
|
184
|
+
encoder.text_token match, :delimiter
|
|
185
|
+
if state == :regexp
|
|
186
|
+
# TODO: regexp modifiers? s, m, x, i?
|
|
187
|
+
modifiers = scan(/[ix]+/)
|
|
188
|
+
encoder.text_token modifiers, :modifier if modifiers && !modifiers.empty?
|
|
189
|
+
end
|
|
190
|
+
state = :string if state == :multiline_string
|
|
191
|
+
encoder.end_group state
|
|
192
|
+
string_delimiter = nil
|
|
193
|
+
after_def = value_expected = false
|
|
194
|
+
state = :initial
|
|
195
|
+
next
|
|
196
|
+
|
|
197
|
+
elsif (state == :string || state == :multiline_string) &&
|
|
198
|
+
(match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox))
|
|
199
|
+
if string_delimiter[0] == ?' && !(match == "\\\\" || match == "\\'")
|
|
200
|
+
encoder.text_token match, :content
|
|
201
|
+
else
|
|
202
|
+
encoder.text_token match, :char
|
|
203
|
+
end
|
|
204
|
+
elsif state == :regexp && match = scan(/ \\ (?: #{REGEXP_ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
|
|
205
|
+
encoder.text_token match, :char
|
|
206
|
+
|
|
207
|
+
elsif match = scan(/ \$ #{IDENT} /mox)
|
|
208
|
+
encoder.begin_group :inline
|
|
209
|
+
encoder.text_token '$', :inline_delimiter
|
|
210
|
+
match = match[1..-1]
|
|
211
|
+
encoder.text_token match, IDENT_KIND[match]
|
|
212
|
+
encoder.end_group :inline
|
|
213
|
+
next
|
|
214
|
+
elsif match = scan(/ \$ \{ /x)
|
|
215
|
+
encoder.begin_group :inline
|
|
216
|
+
encoder.text_token match, :inline_delimiter
|
|
217
|
+
inline_block_stack << [state, string_delimiter, inline_block_paren_depth]
|
|
218
|
+
inline_block_paren_depth = 1
|
|
219
|
+
state = :initial
|
|
220
|
+
next
|
|
221
|
+
|
|
222
|
+
elsif match = scan(/ \$ /mx)
|
|
223
|
+
encoder.text_token match, :content
|
|
224
|
+
|
|
225
|
+
elsif match = scan(/ \\. /mx)
|
|
226
|
+
encoder.text_token match, :content # TODO: Shouldn't this be :error?
|
|
227
|
+
|
|
228
|
+
elsif match = scan(/ \\ | \n /x)
|
|
229
|
+
encoder.end_group state == :regexp ? :regexp : :string
|
|
230
|
+
encoder.text_token match, :error
|
|
231
|
+
after_def = value_expected = false
|
|
232
|
+
state = :initial
|
|
233
|
+
|
|
234
|
+
else
|
|
235
|
+
raise_inspect "else case \" reached; %p not handled." % peek(1), encoder
|
|
236
|
+
|
|
237
|
+
end
|
|
238
|
+
|
|
239
|
+
else
|
|
240
|
+
raise_inspect 'Unknown state', encoder
|
|
241
|
+
|
|
242
|
+
end
|
|
243
|
+
|
|
244
|
+
last_token = match unless [:space, :comment, :doctype].include? kind
|
|
245
|
+
|
|
246
|
+
end
|
|
247
|
+
|
|
248
|
+
if [:multiline_string, :string, :regexp].include? state
|
|
249
|
+
encoder.end_group state == :regexp ? :regexp : :string
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
if options[:keep_state]
|
|
253
|
+
@state = state
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
until inline_block_stack.empty?
|
|
257
|
+
state, = *inline_block_stack.pop
|
|
258
|
+
encoder.end_group :inline
|
|
259
|
+
encoder.end_group state == :regexp ? :regexp : :string
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
encoder
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
end
|
|
268
|
+
end
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
module CodeRay
|
|
2
|
+
module Scanners
|
|
3
|
+
|
|
4
|
+
load :ruby
|
|
5
|
+
load :html
|
|
6
|
+
load :java_script
|
|
7
|
+
|
|
8
|
+
class HAML < Scanner
|
|
9
|
+
|
|
10
|
+
register_for :haml
|
|
11
|
+
title 'HAML Template'
|
|
12
|
+
|
|
13
|
+
KINDS_NOT_LOC = HTML::KINDS_NOT_LOC
|
|
14
|
+
|
|
15
|
+
protected
|
|
16
|
+
|
|
17
|
+
def setup
|
|
18
|
+
super
|
|
19
|
+
@ruby_scanner = CodeRay.scanner :ruby, :tokens => @tokens, :keep_tokens => true
|
|
20
|
+
@embedded_ruby_scanner = CodeRay.scanner :ruby, :tokens => @tokens, :keep_tokens => true, :state => @ruby_scanner.interpreted_string_state
|
|
21
|
+
@html_scanner = CodeRay.scanner :html, :tokens => @tokens, :keep_tokens => true
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def scan_tokens encoder, options
|
|
25
|
+
|
|
26
|
+
match = nil
|
|
27
|
+
code = ''
|
|
28
|
+
|
|
29
|
+
until eos?
|
|
30
|
+
|
|
31
|
+
if bol?
|
|
32
|
+
if match = scan(/!!!.*/)
|
|
33
|
+
encoder.text_token match, :doctype
|
|
34
|
+
next
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
if match = scan(/(?>( *)(\/(?!\[if)|-\#|:javascript|:ruby|:\w+) *)(?=\n)/)
|
|
38
|
+
encoder.text_token match, :comment
|
|
39
|
+
|
|
40
|
+
code = self[2]
|
|
41
|
+
if match = scan(/(?:\n+#{self[1]} .*)+/)
|
|
42
|
+
case code
|
|
43
|
+
when '/', '-#'
|
|
44
|
+
encoder.text_token match, :comment
|
|
45
|
+
when ':javascript'
|
|
46
|
+
# TODO: recognize #{...} snippets inside JavaScript
|
|
47
|
+
@java_script_scanner ||= CodeRay.scanner :java_script, :tokens => @tokens, :keep_tokens => true
|
|
48
|
+
@java_script_scanner.tokenize match, :tokens => encoder
|
|
49
|
+
when ':ruby'
|
|
50
|
+
@ruby_scanner.tokenize match, :tokens => encoder
|
|
51
|
+
when /:\w+/
|
|
52
|
+
encoder.text_token match, :comment
|
|
53
|
+
else
|
|
54
|
+
raise 'else-case reached: %p' % [code]
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
if match = scan(/ +/)
|
|
60
|
+
encoder.text_token match, :space
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
if match = scan(/\/.*/)
|
|
64
|
+
encoder.text_token match, :comment
|
|
65
|
+
next
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
if match = scan(/\\/)
|
|
69
|
+
encoder.text_token match, :plain
|
|
70
|
+
if match = scan(/.+/)
|
|
71
|
+
@html_scanner.tokenize match, :tokens => encoder
|
|
72
|
+
end
|
|
73
|
+
next
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
tag = false
|
|
77
|
+
|
|
78
|
+
if match = scan(/%[-\w:]+\/?/)
|
|
79
|
+
encoder.text_token match, :tag
|
|
80
|
+
# if match = scan(/( +)(.+)/)
|
|
81
|
+
# encoder.text_token self[1], :space
|
|
82
|
+
# @embedded_ruby_scanner.tokenize self[2], :tokens => encoder
|
|
83
|
+
# end
|
|
84
|
+
tag = true
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
while match = scan(/([.#])[-\w]*\w/)
|
|
88
|
+
encoder.text_token match, self[1] == '#' ? :constant : :class
|
|
89
|
+
tag = true
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
if tag && match = scan(/(\()([^)]+)?(\))?/)
|
|
93
|
+
# TODO: recognize title=@title, class="widget_#{@widget.number}"
|
|
94
|
+
encoder.text_token self[1], :plain
|
|
95
|
+
@html_scanner.tokenize self[2], :tokens => encoder, :state => :attribute if self[2]
|
|
96
|
+
encoder.text_token self[3], :plain if self[3]
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
if tag && match = scan(/\{/)
|
|
100
|
+
encoder.text_token match, :plain
|
|
101
|
+
|
|
102
|
+
code = ''
|
|
103
|
+
level = 1
|
|
104
|
+
while true
|
|
105
|
+
code << scan(/([^\{\},\n]|, *\n?)*/)
|
|
106
|
+
case match = getch
|
|
107
|
+
when '{'
|
|
108
|
+
level += 1
|
|
109
|
+
code << match
|
|
110
|
+
when '}'
|
|
111
|
+
level -= 1
|
|
112
|
+
if level > 0
|
|
113
|
+
code << match
|
|
114
|
+
else
|
|
115
|
+
break
|
|
116
|
+
end
|
|
117
|
+
when "\n", ",", nil
|
|
118
|
+
break
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
@ruby_scanner.tokenize code, :tokens => encoder unless code.empty?
|
|
122
|
+
|
|
123
|
+
encoder.text_token match, :plain if match
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
if tag && match = scan(/(\[)([^\]\n]+)?(\])?/)
|
|
127
|
+
encoder.text_token self[1], :plain
|
|
128
|
+
@ruby_scanner.tokenize self[2], :tokens => encoder if self[2]
|
|
129
|
+
encoder.text_token self[3], :plain if self[3]
|
|
130
|
+
end
|
|
131
|
+
|
|
132
|
+
if tag && match = scan(/\//)
|
|
133
|
+
encoder.text_token match, :tag
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
if scan(/(>?<?[-=]|[&!]=|(& |!)|~)( *)([^,\n\|]+(?:(, *|\|(?=.|\n.*\|$))\n?[^,\n\|]*)*)?/)
|
|
137
|
+
encoder.text_token self[1] + self[3], :plain
|
|
138
|
+
if self[4]
|
|
139
|
+
if self[2]
|
|
140
|
+
@embedded_ruby_scanner.tokenize self[4], :tokens => encoder
|
|
141
|
+
else
|
|
142
|
+
@ruby_scanner.tokenize self[4], :tokens => encoder
|
|
143
|
+
end
|
|
144
|
+
end
|
|
145
|
+
elsif match = scan(/((?:<|><?)(?![!?\/\w]))?(.+)?/)
|
|
146
|
+
encoder.text_token self[1], :plain if self[1]
|
|
147
|
+
# TODO: recognize #{...} snippets
|
|
148
|
+
@html_scanner.tokenize self[2], :tokens => encoder if self[2]
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
elsif match = scan(/.+/)
|
|
152
|
+
@html_scanner.tokenize match, :tokens => encoder
|
|
153
|
+
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
if match = scan(/\n/)
|
|
157
|
+
encoder.text_token match, :space
|
|
158
|
+
end
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
encoder
|
|
162
|
+
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
end
|
|
168
|
+
end
|