coderay-beta 0.9.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.
- data/FOLDERS +53 -0
- data/LICENSE +504 -0
- data/bin/coderay +82 -0
- data/bin/coderay_stylesheet +4 -0
- data/lib/README +129 -0
- data/lib/coderay.rb +320 -0
- data/lib/coderay/duo.rb +85 -0
- data/lib/coderay/encoder.rb +213 -0
- data/lib/coderay/encoders/_map.rb +11 -0
- data/lib/coderay/encoders/comment_filter.rb +43 -0
- data/lib/coderay/encoders/count.rb +21 -0
- data/lib/coderay/encoders/debug.rb +49 -0
- data/lib/coderay/encoders/div.rb +19 -0
- data/lib/coderay/encoders/filter.rb +75 -0
- data/lib/coderay/encoders/html.rb +305 -0
- data/lib/coderay/encoders/html/css.rb +70 -0
- data/lib/coderay/encoders/html/numerization.rb +133 -0
- data/lib/coderay/encoders/html/output.rb +206 -0
- data/lib/coderay/encoders/json.rb +69 -0
- data/lib/coderay/encoders/lines_of_code.rb +90 -0
- data/lib/coderay/encoders/null.rb +26 -0
- data/lib/coderay/encoders/page.rb +20 -0
- data/lib/coderay/encoders/span.rb +19 -0
- data/lib/coderay/encoders/statistic.rb +77 -0
- data/lib/coderay/encoders/term.rb +137 -0
- data/lib/coderay/encoders/text.rb +32 -0
- data/lib/coderay/encoders/token_class_filter.rb +84 -0
- data/lib/coderay/encoders/xml.rb +71 -0
- data/lib/coderay/encoders/yaml.rb +22 -0
- data/lib/coderay/for_redcloth.rb +85 -0
- data/lib/coderay/helpers/file_type.rb +240 -0
- data/lib/coderay/helpers/gzip_simple.rb +123 -0
- data/lib/coderay/helpers/plugin.rb +349 -0
- data/lib/coderay/helpers/word_list.rb +138 -0
- data/lib/coderay/scanner.rb +284 -0
- data/lib/coderay/scanners/_map.rb +23 -0
- data/lib/coderay/scanners/c.rb +203 -0
- data/lib/coderay/scanners/cpp.rb +228 -0
- data/lib/coderay/scanners/css.rb +210 -0
- data/lib/coderay/scanners/debug.rb +62 -0
- data/lib/coderay/scanners/delphi.rb +150 -0
- data/lib/coderay/scanners/diff.rb +105 -0
- data/lib/coderay/scanners/groovy.rb +263 -0
- data/lib/coderay/scanners/html.rb +182 -0
- data/lib/coderay/scanners/java.rb +176 -0
- data/lib/coderay/scanners/java/builtin_types.rb +419 -0
- data/lib/coderay/scanners/java_script.rb +224 -0
- data/lib/coderay/scanners/json.rb +112 -0
- data/lib/coderay/scanners/nitro_xhtml.rb +136 -0
- data/lib/coderay/scanners/php.rb +526 -0
- data/lib/coderay/scanners/plaintext.rb +21 -0
- data/lib/coderay/scanners/python.rb +285 -0
- data/lib/coderay/scanners/rhtml.rb +74 -0
- data/lib/coderay/scanners/ruby.rb +404 -0
- data/lib/coderay/scanners/ruby/patterns.rb +238 -0
- data/lib/coderay/scanners/scheme.rb +145 -0
- data/lib/coderay/scanners/sql.rb +162 -0
- data/lib/coderay/scanners/xml.rb +17 -0
- data/lib/coderay/scanners/yaml.rb +144 -0
- data/lib/coderay/style.rb +20 -0
- data/lib/coderay/styles/_map.rb +7 -0
- data/lib/coderay/styles/cycnus.rb +151 -0
- data/lib/coderay/styles/murphy.rb +132 -0
- data/lib/coderay/token_classes.rb +86 -0
- data/lib/coderay/tokens.rb +391 -0
- data/lib/term/ansicolor.rb +220 -0
- metadata +123 -0
@@ -0,0 +1,150 @@
|
|
1
|
+
module CodeRay
|
2
|
+
module Scanners
|
3
|
+
|
4
|
+
class Delphi < Scanner
|
5
|
+
|
6
|
+
register_for :delphi
|
7
|
+
file_extension 'pas'
|
8
|
+
|
9
|
+
RESERVED_WORDS = [
|
10
|
+
'and', 'array', 'as', 'at', 'asm', 'at', 'begin', 'case', 'class',
|
11
|
+
'const', 'constructor', 'destructor', 'dispinterface', 'div', 'do',
|
12
|
+
'downto', 'else', 'end', 'except', 'exports', 'file', 'finalization',
|
13
|
+
'finally', 'for', 'function', 'goto', 'if', 'implementation', 'in',
|
14
|
+
'inherited', 'initialization', 'inline', 'interface', 'is', 'label',
|
15
|
+
'library', 'mod', 'nil', 'not', 'object', 'of', 'or', 'out', 'packed',
|
16
|
+
'procedure', 'program', 'property', 'raise', 'record', 'repeat',
|
17
|
+
'resourcestring', 'set', 'shl', 'shr', 'string', 'then', 'threadvar',
|
18
|
+
'to', 'try', 'type', 'unit', 'until', 'uses', 'var', 'while', 'with',
|
19
|
+
'xor', 'on'
|
20
|
+
]
|
21
|
+
|
22
|
+
DIRECTIVES = [
|
23
|
+
'absolute', 'abstract', 'assembler', 'at', 'automated', 'cdecl',
|
24
|
+
'contains', 'deprecated', 'dispid', 'dynamic', 'export',
|
25
|
+
'external', 'far', 'forward', 'implements', 'local',
|
26
|
+
'near', 'nodefault', 'on', 'overload', 'override',
|
27
|
+
'package', 'pascal', 'platform', 'private', 'protected', 'public',
|
28
|
+
'published', 'read', 'readonly', 'register', 'reintroduce',
|
29
|
+
'requires', 'resident', 'safecall', 'stdcall', 'stored', 'varargs',
|
30
|
+
'virtual', 'write', 'writeonly'
|
31
|
+
]
|
32
|
+
|
33
|
+
IDENT_KIND = CaseIgnoringWordList.new(:ident).
|
34
|
+
add(RESERVED_WORDS, :reserved).
|
35
|
+
add(DIRECTIVES, :directive)
|
36
|
+
|
37
|
+
NAME_FOLLOWS = CaseIgnoringWordList.new(false).
|
38
|
+
add(%w(procedure function .))
|
39
|
+
|
40
|
+
private
|
41
|
+
def scan_tokens tokens, options
|
42
|
+
|
43
|
+
state = :initial
|
44
|
+
last_token = ''
|
45
|
+
|
46
|
+
until eos?
|
47
|
+
|
48
|
+
kind = nil
|
49
|
+
match = nil
|
50
|
+
|
51
|
+
if state == :initial
|
52
|
+
|
53
|
+
if scan(/ \s+ /x)
|
54
|
+
tokens << [matched, :space]
|
55
|
+
next
|
56
|
+
|
57
|
+
elsif scan(%r! \{ \$ [^}]* \}? | \(\* \$ (?: .*? \*\) | .* ) !mx)
|
58
|
+
tokens << [matched, :preprocessor]
|
59
|
+
next
|
60
|
+
|
61
|
+
elsif scan(%r! // [^\n]* | \{ [^}]* \}? | \(\* (?: .*? \*\) | .* ) !mx)
|
62
|
+
tokens << [matched, :comment]
|
63
|
+
next
|
64
|
+
|
65
|
+
elsif match = scan(/ <[>=]? | >=? | :=? | [-+=*\/;,@\^|\(\)\[\]] | \.\. /x)
|
66
|
+
kind = :operator
|
67
|
+
|
68
|
+
elsif match = scan(/\./)
|
69
|
+
kind = :operator
|
70
|
+
if last_token == 'end'
|
71
|
+
tokens << [match, kind]
|
72
|
+
next
|
73
|
+
end
|
74
|
+
|
75
|
+
elsif match = scan(/ [A-Za-z_][A-Za-z_0-9]* /x)
|
76
|
+
kind = NAME_FOLLOWS[last_token] ? :ident : IDENT_KIND[match]
|
77
|
+
|
78
|
+
elsif match = scan(/ ' ( [^\n']|'' ) (?:'|$) /x)
|
79
|
+
tokens << [:open, :char]
|
80
|
+
tokens << ["'", :delimiter]
|
81
|
+
tokens << [self[1], :content]
|
82
|
+
tokens << ["'", :delimiter]
|
83
|
+
tokens << [:close, :char]
|
84
|
+
next
|
85
|
+
|
86
|
+
elsif match = scan(/ ' /x)
|
87
|
+
tokens << [:open, :string]
|
88
|
+
state = :string
|
89
|
+
kind = :delimiter
|
90
|
+
|
91
|
+
elsif scan(/ \# (?: \d+ | \$[0-9A-Fa-f]+ ) /x)
|
92
|
+
kind = :char
|
93
|
+
|
94
|
+
elsif scan(/ \$ [0-9A-Fa-f]+ /x)
|
95
|
+
kind = :hex
|
96
|
+
|
97
|
+
elsif scan(/ (?: \d+ ) (?![eE]|\.[^.]) /x)
|
98
|
+
kind = :integer
|
99
|
+
|
100
|
+
elsif scan(/ \d+ (?: \.\d+ (?: [eE][+-]? \d+ )? | [eE][+-]? \d+ ) /x)
|
101
|
+
kind = :float
|
102
|
+
|
103
|
+
else
|
104
|
+
kind = :error
|
105
|
+
getch
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
elsif state == :string
|
110
|
+
if scan(/[^\n']+/)
|
111
|
+
kind = :content
|
112
|
+
elsif scan(/''/)
|
113
|
+
kind = :char
|
114
|
+
elsif scan(/'/)
|
115
|
+
tokens << ["'", :delimiter]
|
116
|
+
tokens << [:close, :string]
|
117
|
+
state = :initial
|
118
|
+
next
|
119
|
+
elsif scan(/\n/)
|
120
|
+
tokens << [:close, :string]
|
121
|
+
kind = :error
|
122
|
+
state = :initial
|
123
|
+
else
|
124
|
+
raise "else case \' reached; %p not handled." % peek(1), tokens
|
125
|
+
end
|
126
|
+
|
127
|
+
else
|
128
|
+
raise 'else-case reached', tokens
|
129
|
+
|
130
|
+
end
|
131
|
+
|
132
|
+
match ||= matched
|
133
|
+
if $DEBUG and not kind
|
134
|
+
raise_inspect 'Error token %p in line %d' %
|
135
|
+
[[match, kind], line], tokens, state
|
136
|
+
end
|
137
|
+
raise_inspect 'Empty token', tokens unless match
|
138
|
+
|
139
|
+
last_token = match
|
140
|
+
tokens << [match, kind]
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
tokens
|
145
|
+
end
|
146
|
+
|
147
|
+
end
|
148
|
+
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module CodeRay
|
2
|
+
module Scanners
|
3
|
+
|
4
|
+
class Diff < Scanner
|
5
|
+
|
6
|
+
register_for :diff
|
7
|
+
title 'diff output'
|
8
|
+
|
9
|
+
def scan_tokens tokens, options
|
10
|
+
|
11
|
+
line_kind = nil
|
12
|
+
state = :initial
|
13
|
+
|
14
|
+
until eos?
|
15
|
+
kind = match = nil
|
16
|
+
|
17
|
+
if match = scan(/\n/)
|
18
|
+
if line_kind
|
19
|
+
tokens << [:end_line, line_kind]
|
20
|
+
line_kind = nil
|
21
|
+
end
|
22
|
+
tokens << [match, :space]
|
23
|
+
next
|
24
|
+
end
|
25
|
+
|
26
|
+
case state
|
27
|
+
|
28
|
+
when :initial
|
29
|
+
if match = scan(/--- |\+\+\+ |=+|_+/)
|
30
|
+
tokens << [:begin_line, line_kind = :head]
|
31
|
+
tokens << [match, :head]
|
32
|
+
next unless match = scan(/.+/)
|
33
|
+
kind = :plain
|
34
|
+
elsif match = scan(/Index: |Property changes on: /)
|
35
|
+
tokens << [:begin_line, line_kind = :head]
|
36
|
+
tokens << [match, :head]
|
37
|
+
next unless match = scan(/.+/)
|
38
|
+
kind = :plain
|
39
|
+
elsif match = scan(/Added: /)
|
40
|
+
tokens << [:begin_line, line_kind = :head]
|
41
|
+
tokens << [match, :head]
|
42
|
+
next unless match = scan(/.+/)
|
43
|
+
kind = :plain
|
44
|
+
state = :added
|
45
|
+
elsif match = scan(/\\ /)
|
46
|
+
tokens << [:begin_line, line_kind = :change]
|
47
|
+
tokens << [match, :change]
|
48
|
+
next unless match = scan(/.+/)
|
49
|
+
kind = :plain
|
50
|
+
elsif scan(/(@@)((?>[^@\n]*))(@@)/)
|
51
|
+
tokens << [:begin_line, line_kind = :change]
|
52
|
+
tokens << [self[1], :change]
|
53
|
+
tokens << [self[2], :plain]
|
54
|
+
tokens << [self[3], :change]
|
55
|
+
next unless match = scan(/.+/)
|
56
|
+
kind = :plain
|
57
|
+
elsif match = scan(/\+/)
|
58
|
+
tokens << [:begin_line, line_kind = :insert]
|
59
|
+
tokens << [match, :insert]
|
60
|
+
next unless match = scan(/.+/)
|
61
|
+
kind = :plain
|
62
|
+
elsif match = scan(/-/)
|
63
|
+
tokens << [:begin_line, line_kind = :delete]
|
64
|
+
tokens << [match, :delete]
|
65
|
+
next unless match = scan(/.+/)
|
66
|
+
kind = :plain
|
67
|
+
elsif scan(/ .*/)
|
68
|
+
kind = :comment
|
69
|
+
elsif scan(/.+/)
|
70
|
+
tokens << [:begin_line, line_kind = :head]
|
71
|
+
kind = :plain
|
72
|
+
else
|
73
|
+
raise_inspect 'else case rached'
|
74
|
+
end
|
75
|
+
|
76
|
+
when :added
|
77
|
+
if match = scan(/ \+/)
|
78
|
+
tokens << [:begin_line, line_kind = :insert]
|
79
|
+
tokens << [match, :insert]
|
80
|
+
next unless match = scan(/.+/)
|
81
|
+
kind = :plain
|
82
|
+
else
|
83
|
+
state = :initial
|
84
|
+
next
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
match ||= matched
|
89
|
+
if $DEBUG and not kind
|
90
|
+
raise_inspect 'Error token %p in line %d' %
|
91
|
+
[[match, kind], line], tokens
|
92
|
+
end
|
93
|
+
raise_inspect 'Empty token', tokens unless match
|
94
|
+
|
95
|
+
tokens << [match, kind]
|
96
|
+
end
|
97
|
+
|
98
|
+
tokens << [:end_line, line_kind] if line_kind
|
99
|
+
tokens
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,263 @@
|
|
1
|
+
module CodeRay
|
2
|
+
module Scanners
|
3
|
+
|
4
|
+
load :java
|
5
|
+
|
6
|
+
class Groovy < Java
|
7
|
+
|
8
|
+
include Streamable
|
9
|
+
register_for :groovy
|
10
|
+
|
11
|
+
# TODO: Check this!
|
12
|
+
GROOVY_KEYWORDS = %w[
|
13
|
+
as assert def in
|
14
|
+
]
|
15
|
+
KEYWORDS_EXPECTING_VALUE = WordList.new.add %w[
|
16
|
+
case instanceof new return throw typeof while as assert in
|
17
|
+
]
|
18
|
+
GROOVY_MAGIC_VARIABLES = %w[ it ]
|
19
|
+
|
20
|
+
IDENT_KIND = Java::IDENT_KIND.dup.
|
21
|
+
add(GROOVY_KEYWORDS, :keyword).
|
22
|
+
add(GROOVY_MAGIC_VARIABLES, :local_variable)
|
23
|
+
|
24
|
+
ESCAPE = / [bfnrtv$\n\\'"] | x[a-fA-F0-9]{1,2} | [0-7]{1,3} /x
|
25
|
+
UNICODE_ESCAPE = / u[a-fA-F0-9]{4} /x # 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
|
27
|
+
|
28
|
+
# TODO: interpretation inside ', ", /
|
29
|
+
STRING_CONTENT_PATTERN = {
|
30
|
+
"'" => /(?>\\[^\\'\n]+|[^\\'\n]+)+/,
|
31
|
+
'"' => /[^\\$"\n]+/,
|
32
|
+
"'''" => /(?>[^\\']+|'(?!''))+/,
|
33
|
+
'"""' => /(?>[^\\$"]+|"(?!""))+/,
|
34
|
+
'/' => /[^\\$\/\n]+/,
|
35
|
+
}
|
36
|
+
|
37
|
+
def scan_tokens tokens, options
|
38
|
+
|
39
|
+
state = :initial
|
40
|
+
inline_block_stack = []
|
41
|
+
inline_block_paren_depth = nil
|
42
|
+
string_delimiter = nil
|
43
|
+
import_clause = class_name_follows = last_token = after_def = false
|
44
|
+
value_expected = true
|
45
|
+
|
46
|
+
until eos?
|
47
|
+
|
48
|
+
kind = nil
|
49
|
+
match = nil
|
50
|
+
|
51
|
+
case state
|
52
|
+
|
53
|
+
when :initial
|
54
|
+
|
55
|
+
if match = scan(/ \s+ | \\\n /x)
|
56
|
+
tokens << [match, :space]
|
57
|
+
if match.index ?\n
|
58
|
+
import_clause = after_def = false
|
59
|
+
value_expected = true unless value_expected
|
60
|
+
end
|
61
|
+
next
|
62
|
+
|
63
|
+
elsif scan(%r! // [^\n\\]* (?: \\. [^\n\\]* )* | /\* (?: .*? \*/ | .* ) !mx)
|
64
|
+
value_expected = true
|
65
|
+
after_def = false
|
66
|
+
kind = :comment
|
67
|
+
|
68
|
+
elsif bol? && scan(/ \#!.* /x)
|
69
|
+
kind = :doctype
|
70
|
+
|
71
|
+
elsif import_clause && scan(/ (?!as) #{IDENT} (?: \. #{IDENT} )* (?: \.\* )? /ox)
|
72
|
+
after_def = value_expected = false
|
73
|
+
kind = :include
|
74
|
+
|
75
|
+
elsif match = scan(/ #{IDENT} | \[\] /ox)
|
76
|
+
kind = IDENT_KIND[match]
|
77
|
+
value_expected = (kind == :keyword) && KEYWORDS_EXPECTING_VALUE[match]
|
78
|
+
if last_token == '.'
|
79
|
+
kind = :ident
|
80
|
+
elsif class_name_follows
|
81
|
+
kind = :class
|
82
|
+
class_name_follows = false
|
83
|
+
elsif after_def && check(/\s*[({]/)
|
84
|
+
kind = :method
|
85
|
+
after_def = false
|
86
|
+
elsif kind == :ident && last_token != '?' && check(/:/)
|
87
|
+
kind = :key
|
88
|
+
else
|
89
|
+
class_name_follows = true if match == 'class' || (import_clause && match == 'as')
|
90
|
+
import_clause = match == 'import'
|
91
|
+
after_def = true if match == 'def'
|
92
|
+
end
|
93
|
+
|
94
|
+
elsif scan(/;/)
|
95
|
+
import_clause = after_def = false
|
96
|
+
value_expected = true
|
97
|
+
kind = :operator
|
98
|
+
|
99
|
+
elsif scan(/\{/)
|
100
|
+
class_name_follows = after_def = false
|
101
|
+
value_expected = true
|
102
|
+
kind = :operator
|
103
|
+
if !inline_block_stack.empty?
|
104
|
+
inline_block_paren_depth += 1
|
105
|
+
end
|
106
|
+
|
107
|
+
# TODO: ~'...', ~"..." and ~/.../ style regexps
|
108
|
+
elsif match = scan(/ \.\.<? | \*?\.(?!\d)@? | \.& | \?:? | [,?:(\[] | -[->] | \+\+ |
|
109
|
+
&& | \|\| | \*\*=? | ==?~ | <=?>? | [-+*%^~&|>=!]=? | <<<?=? | >>>?=? /x)
|
110
|
+
value_expected = true
|
111
|
+
value_expected = :regexp if match == '~'
|
112
|
+
after_def = false
|
113
|
+
kind = :operator
|
114
|
+
|
115
|
+
elsif match = scan(/ [)\]}] /x)
|
116
|
+
value_expected = after_def = false
|
117
|
+
if !inline_block_stack.empty? && match == '}'
|
118
|
+
inline_block_paren_depth -= 1
|
119
|
+
if inline_block_paren_depth == 0 # closing brace of inline block reached
|
120
|
+
tokens << [match, :inline_delimiter]
|
121
|
+
tokens << [:close, :inline]
|
122
|
+
state, string_delimiter, inline_block_paren_depth = inline_block_stack.pop
|
123
|
+
next
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
elsif check(/[\d.]/)
|
128
|
+
after_def = value_expected = false
|
129
|
+
if scan(/0[xX][0-9A-Fa-f]+/)
|
130
|
+
kind = :hex
|
131
|
+
elsif scan(/(?>0[0-7]+)(?![89.eEfF])/)
|
132
|
+
kind = :oct
|
133
|
+
elsif scan(/\d+[fFdD]|\d*\.\d+(?:[eE][+-]?\d+)?[fFdD]?|\d+[eE][+-]?\d+[fFdD]?/)
|
134
|
+
kind = :float
|
135
|
+
elsif scan(/\d+[lLgG]?/)
|
136
|
+
kind = :integer
|
137
|
+
end
|
138
|
+
|
139
|
+
elsif match = scan(/'''|"""/)
|
140
|
+
after_def = value_expected = false
|
141
|
+
state = :multiline_string
|
142
|
+
tokens << [:open, :string]
|
143
|
+
string_delimiter = match
|
144
|
+
kind = :delimiter
|
145
|
+
|
146
|
+
# TODO: record.'name'
|
147
|
+
elsif match = scan(/["']/)
|
148
|
+
after_def = value_expected = false
|
149
|
+
state = match == '/' ? :regexp : :string
|
150
|
+
tokens << [:open, state]
|
151
|
+
string_delimiter = match
|
152
|
+
kind = :delimiter
|
153
|
+
|
154
|
+
elsif value_expected && (match = scan(/\//))
|
155
|
+
after_def = value_expected = false
|
156
|
+
tokens << [:open, :regexp]
|
157
|
+
state = :regexp
|
158
|
+
string_delimiter = '/'
|
159
|
+
kind = :delimiter
|
160
|
+
|
161
|
+
elsif scan(/ @ #{IDENT} /ox)
|
162
|
+
after_def = value_expected = false
|
163
|
+
kind = :annotation
|
164
|
+
|
165
|
+
elsif scan(/\//)
|
166
|
+
after_def = false
|
167
|
+
value_expected = true
|
168
|
+
kind = :operator
|
169
|
+
|
170
|
+
else
|
171
|
+
getch
|
172
|
+
kind = :error
|
173
|
+
|
174
|
+
end
|
175
|
+
|
176
|
+
when :string, :regexp, :multiline_string
|
177
|
+
if scan(STRING_CONTENT_PATTERN[string_delimiter])
|
178
|
+
kind = :content
|
179
|
+
|
180
|
+
elsif match = scan(state == :multiline_string ? /'''|"""/ : /["'\/]/)
|
181
|
+
tokens << [match, :delimiter]
|
182
|
+
if state == :regexp
|
183
|
+
# TODO: regexp modifiers? s, m, x, i?
|
184
|
+
modifiers = scan(/[ix]+/)
|
185
|
+
tokens << [modifiers, :modifier] if modifiers && !modifiers.empty?
|
186
|
+
end
|
187
|
+
state = :string if state == :multiline_string
|
188
|
+
tokens << [:close, state]
|
189
|
+
string_delimiter = nil
|
190
|
+
after_def = value_expected = false
|
191
|
+
state = :initial
|
192
|
+
next
|
193
|
+
|
194
|
+
elsif (state == :string || state == :multiline_string) &&
|
195
|
+
(match = scan(/ \\ (?: #{ESCAPE} | #{UNICODE_ESCAPE} ) /mox))
|
196
|
+
if string_delimiter[0] == ?' && !(match == "\\\\" || match == "\\'")
|
197
|
+
kind = :content
|
198
|
+
else
|
199
|
+
kind = :char
|
200
|
+
end
|
201
|
+
elsif state == :regexp && scan(/ \\ (?: #{REGEXP_ESCAPE} | #{UNICODE_ESCAPE} ) /mox)
|
202
|
+
kind = :char
|
203
|
+
|
204
|
+
elsif match = scan(/ \$ #{IDENT} /mox)
|
205
|
+
tokens << [:open, :inline]
|
206
|
+
tokens << ['$', :inline_delimiter]
|
207
|
+
match = match[1..-1]
|
208
|
+
tokens << [match, IDENT_KIND[match]]
|
209
|
+
tokens << [:close, :inline]
|
210
|
+
next
|
211
|
+
elsif match = scan(/ \$ \{ /x)
|
212
|
+
tokens << [:open, :inline]
|
213
|
+
tokens << ['${', :inline_delimiter]
|
214
|
+
inline_block_stack << [state, string_delimiter, inline_block_paren_depth]
|
215
|
+
inline_block_paren_depth = 1
|
216
|
+
state = :initial
|
217
|
+
next
|
218
|
+
|
219
|
+
elsif scan(/ \$ /mx)
|
220
|
+
kind = :content
|
221
|
+
|
222
|
+
elsif scan(/ \\. /mx)
|
223
|
+
kind = :content
|
224
|
+
|
225
|
+
elsif scan(/ \\ | \n /x)
|
226
|
+
tokens << [:close, state]
|
227
|
+
kind = :error
|
228
|
+
after_def = value_expected = false
|
229
|
+
state = :initial
|
230
|
+
|
231
|
+
else
|
232
|
+
raise_inspect "else case \" reached; %p not handled." % peek(1), tokens
|
233
|
+
end
|
234
|
+
|
235
|
+
else
|
236
|
+
raise_inspect 'Unknown state', tokens
|
237
|
+
|
238
|
+
end
|
239
|
+
|
240
|
+
match ||= matched
|
241
|
+
if $DEBUG and not kind
|
242
|
+
raise_inspect 'Error token %p in line %d' %
|
243
|
+
[[match, kind], line], tokens
|
244
|
+
end
|
245
|
+
raise_inspect 'Empty token', tokens unless match
|
246
|
+
|
247
|
+
last_token = match unless [:space, :comment, :doctype].include? kind
|
248
|
+
|
249
|
+
tokens << [match, kind]
|
250
|
+
|
251
|
+
end
|
252
|
+
|
253
|
+
if [:multiline_string, :string, :regexp].include? state
|
254
|
+
tokens << [:close, state]
|
255
|
+
end
|
256
|
+
|
257
|
+
tokens
|
258
|
+
end
|
259
|
+
|
260
|
+
end
|
261
|
+
|
262
|
+
end
|
263
|
+
end
|