coderay 1.0.0.598.pre → 1.0.0.738.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/coderay +1 -1
- data/lib/coderay.rb +38 -32
- data/lib/coderay/duo.rb +1 -54
- data/lib/coderay/encoder.rb +31 -33
- data/lib/coderay/encoders/_map.rb +4 -2
- data/lib/coderay/encoders/comment_filter.rb +0 -61
- data/lib/coderay/encoders/count.rb +2 -23
- data/lib/coderay/encoders/debug.rb +11 -60
- data/lib/coderay/encoders/filter.rb +0 -46
- data/lib/coderay/encoders/html.rb +83 -91
- data/lib/coderay/encoders/html/css.rb +1 -6
- data/lib/coderay/encoders/html/numbering.rb +18 -21
- data/lib/coderay/encoders/html/output.rb +10 -52
- data/lib/coderay/encoders/json.rb +19 -39
- data/lib/coderay/encoders/lines_of_code.rb +7 -52
- data/lib/coderay/encoders/null.rb +6 -13
- data/lib/coderay/encoders/statistic.rb +30 -93
- data/lib/coderay/encoders/terminal.rb +3 -4
- data/lib/coderay/encoders/text.rb +1 -23
- data/lib/coderay/encoders/token_kind_filter.rb +0 -58
- data/lib/coderay/helpers/file_type.rb +119 -240
- data/lib/coderay/helpers/gzip.rb +41 -0
- data/lib/coderay/helpers/plugin.rb +237 -307
- data/lib/coderay/scanner.rb +112 -88
- data/lib/coderay/scanners/_map.rb +3 -3
- data/lib/coderay/scanners/c.rb +7 -7
- data/lib/coderay/scanners/clojure.rb +204 -0
- data/lib/coderay/scanners/css.rb +10 -20
- data/lib/coderay/scanners/debug.rb +9 -55
- data/lib/coderay/scanners/diff.rb +21 -4
- data/lib/coderay/scanners/html.rb +65 -18
- data/lib/coderay/scanners/java.rb +3 -2
- data/lib/coderay/scanners/java_script.rb +3 -3
- data/lib/coderay/scanners/json.rb +7 -6
- data/lib/coderay/scanners/php.rb +2 -1
- data/lib/coderay/scanners/rhtml.rb +6 -2
- data/lib/coderay/scanners/ruby.rb +193 -193
- data/lib/coderay/scanners/ruby/patterns.rb +15 -82
- data/lib/coderay/scanners/ruby/string_state.rb +71 -0
- data/lib/coderay/scanners/sql.rb +1 -1
- data/lib/coderay/scanners/yaml.rb +4 -2
- data/lib/coderay/styles/_map.rb +2 -2
- data/lib/coderay/styles/alpha.rb +48 -38
- data/lib/coderay/styles/cycnus.rb +2 -1
- data/lib/coderay/token_kinds.rb +88 -86
- data/lib/coderay/tokens.rb +88 -112
- data/test/functional/basic.rb +184 -5
- data/test/functional/examples.rb +4 -4
- data/test/functional/for_redcloth.rb +3 -2
- data/test/functional/suite.rb +7 -6
- metadata +11 -24
- data/lib/coderay/helpers/gzip_simple.rb +0 -123
- data/test/functional/load_plugin_scanner.rb +0 -11
- data/test/functional/vhdl.rb +0 -126
- data/test/functional/word_list.rb +0 -79
@@ -1,7 +1,6 @@
|
|
1
|
-
($:.unshift '../..'; require 'coderay') unless defined? CodeRay
|
2
1
|
module CodeRay
|
3
2
|
module Encoders
|
4
|
-
|
3
|
+
|
5
4
|
# = Debug Encoder
|
6
5
|
#
|
7
6
|
# Fast encoder producing simple debug output.
|
@@ -14,32 +13,31 @@ module Encoders
|
|
14
13
|
#
|
15
14
|
# See also: Scanners::Debug
|
16
15
|
class Debug < Encoder
|
17
|
-
|
16
|
+
|
18
17
|
register_for :debug
|
19
|
-
|
18
|
+
|
20
19
|
FILE_EXTENSION = 'raydebug'
|
21
20
|
|
22
21
|
def initialize options = {}
|
23
22
|
super
|
24
23
|
@opened = []
|
25
24
|
end
|
26
|
-
|
27
|
-
public
|
28
|
-
|
25
|
+
|
29
26
|
def text_token text, kind
|
30
27
|
if kind == :space
|
31
28
|
@out << text
|
32
29
|
else
|
30
|
+
# FIXME: Escape (
|
33
31
|
text = text.gsub(/[)\\]/, '\\\\\0') # escape ) and \
|
34
32
|
@out << kind.to_s << '(' << text << ')'
|
35
33
|
end
|
36
34
|
end
|
37
|
-
|
35
|
+
|
38
36
|
def begin_group kind
|
39
37
|
@opened << kind
|
40
38
|
@out << kind.to_s << '<'
|
41
39
|
end
|
42
|
-
|
40
|
+
|
43
41
|
def end_group kind
|
44
42
|
if @opened.last != kind
|
45
43
|
puts @out
|
@@ -48,63 +46,16 @@ module Encoders
|
|
48
46
|
@opened.pop
|
49
47
|
@out << '>'
|
50
48
|
end
|
51
|
-
|
49
|
+
|
52
50
|
def begin_line kind
|
53
51
|
@out << kind.to_s << '['
|
54
52
|
end
|
55
|
-
|
53
|
+
|
56
54
|
def end_line kind
|
57
55
|
@out << ']'
|
58
56
|
end
|
59
|
-
|
60
|
-
end
|
61
|
-
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
if $0 == __FILE__
|
66
|
-
$VERBOSE = true
|
67
|
-
$: << File.join(File.dirname(__FILE__), '..')
|
68
|
-
eval DATA.read, nil, $0, __LINE__ + 4
|
69
|
-
end
|
70
|
-
|
71
|
-
__END__
|
72
|
-
require 'test/unit'
|
73
|
-
|
74
|
-
class DebugEncoderTest < Test::Unit::TestCase
|
75
|
-
|
76
|
-
def test_creation
|
77
|
-
assert CodeRay::Encoders::Debug < CodeRay::Encoders::Encoder
|
78
|
-
debug = nil
|
79
|
-
assert_nothing_raised do
|
80
|
-
debug = CodeRay.encoder :debug
|
81
|
-
end
|
82
|
-
assert_kind_of CodeRay::Encoders::Encoder, debug
|
83
|
-
end
|
84
|
-
|
85
|
-
TEST_INPUT = CodeRay::Tokens[
|
86
|
-
['10', :integer],
|
87
|
-
['(\\)', :operator],
|
88
|
-
[:begin_group, :string],
|
89
|
-
['test', :content],
|
90
|
-
[:end_group, :string],
|
91
|
-
[:begin_line, :test],
|
92
|
-
["\n", :space],
|
93
|
-
["\n \t", :space],
|
94
|
-
[" \n", :space],
|
95
|
-
["[]", :method],
|
96
|
-
[:end_line, :test],
|
97
|
-
].flatten
|
98
|
-
TEST_OUTPUT = <<-'DEBUG'.chomp
|
99
|
-
integer(10)operator((\\\))string<content(test)>test[
|
100
|
-
|
101
|
-
|
102
|
-
method([])]
|
103
|
-
DEBUG
|
104
|
-
|
105
|
-
def test_filtering_text_tokens
|
106
|
-
assert_equal TEST_OUTPUT, CodeRay::Encoders::Debug.new.encode_tokens(TEST_INPUT)
|
107
|
-
assert_equal TEST_OUTPUT, TEST_INPUT.debug
|
57
|
+
|
108
58
|
end
|
109
59
|
|
110
60
|
end
|
61
|
+
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
($:.unshift '../..'; require 'coderay') unless defined? CodeRay
|
2
1
|
module CodeRay
|
3
2
|
module Encoders
|
4
3
|
|
@@ -51,48 +50,3 @@ module Encoders
|
|
51
50
|
|
52
51
|
end
|
53
52
|
end
|
54
|
-
|
55
|
-
if $0 == __FILE__
|
56
|
-
$VERBOSE = true
|
57
|
-
$: << File.join(File.dirname(__FILE__), '..')
|
58
|
-
eval DATA.read, nil, $0, __LINE__ + 4
|
59
|
-
end
|
60
|
-
|
61
|
-
__END__
|
62
|
-
require 'test/unit'
|
63
|
-
|
64
|
-
class FilterTest < Test::Unit::TestCase
|
65
|
-
|
66
|
-
def test_creation
|
67
|
-
assert CodeRay::Encoders::Filter < CodeRay::Encoders::Encoder
|
68
|
-
filter = nil
|
69
|
-
assert_nothing_raised do
|
70
|
-
filter = CodeRay.encoder :filter
|
71
|
-
end
|
72
|
-
assert_kind_of CodeRay::Encoders::Encoder, filter
|
73
|
-
end
|
74
|
-
|
75
|
-
def test_filtering_text_tokens
|
76
|
-
tokens = CodeRay::Tokens.new
|
77
|
-
10.times do |i|
|
78
|
-
tokens.text_token i.to_s, :index
|
79
|
-
end
|
80
|
-
assert_equal tokens, CodeRay::Encoders::Filter.new.encode_tokens(tokens)
|
81
|
-
assert_equal tokens, tokens.filter
|
82
|
-
end
|
83
|
-
|
84
|
-
def test_filtering_block_tokens
|
85
|
-
tokens = CodeRay::Tokens.new
|
86
|
-
10.times do |i|
|
87
|
-
tokens.begin_group :index
|
88
|
-
tokens.text_token i.to_s, :content
|
89
|
-
tokens.end_group :index
|
90
|
-
tokens.begin_line :index
|
91
|
-
tokens.text_token i.to_s, :content
|
92
|
-
tokens.end_line :index
|
93
|
-
end
|
94
|
-
assert_equal tokens, CodeRay::Encoders::Filter.new.encode_tokens(tokens)
|
95
|
-
assert_equal tokens, tokens.filter
|
96
|
-
end
|
97
|
-
|
98
|
-
end
|
@@ -2,7 +2,7 @@ require 'set'
|
|
2
2
|
|
3
3
|
module CodeRay
|
4
4
|
module Encoders
|
5
|
-
|
5
|
+
|
6
6
|
# = HTML Encoder
|
7
7
|
#
|
8
8
|
# This is CodeRay's most important highlighter:
|
@@ -88,42 +88,43 @@ module Encoders
|
|
88
88
|
#
|
89
89
|
# Default: false
|
90
90
|
class HTML < Encoder
|
91
|
-
|
91
|
+
|
92
92
|
register_for :html
|
93
|
-
|
93
|
+
|
94
94
|
FILE_EXTENSION = 'html'
|
95
|
-
|
95
|
+
|
96
96
|
DEFAULT_OPTIONS = {
|
97
97
|
:tab_width => 8,
|
98
|
-
|
98
|
+
|
99
99
|
:css => :class,
|
100
|
-
|
101
100
|
:style => :alpha,
|
102
101
|
:wrap => nil,
|
103
102
|
:title => 'CodeRay output',
|
104
|
-
|
103
|
+
|
105
104
|
:line_numbers => nil,
|
106
105
|
:line_number_anchors => 'n',
|
107
106
|
:line_number_start => 1,
|
108
107
|
:bold_every => 10,
|
109
108
|
:highlight_lines => nil,
|
110
|
-
|
109
|
+
|
111
110
|
:hint => false,
|
112
111
|
}
|
113
|
-
|
114
|
-
|
115
|
-
|
112
|
+
|
113
|
+
autoload :Output, 'coderay/encoders/html/output'
|
114
|
+
autoload :CSS, 'coderay/encoders/html/css'
|
115
|
+
autoload :Numbering, 'coderay/encoders/html/numbering'
|
116
|
+
|
116
117
|
attr_reader :css
|
117
|
-
|
118
|
+
|
118
119
|
protected
|
119
|
-
|
120
|
+
|
120
121
|
HTML_ESCAPE = { #:nodoc:
|
121
122
|
'&' => '&',
|
122
123
|
'"' => '"',
|
123
124
|
'>' => '>',
|
124
125
|
'<' => '<',
|
125
126
|
}
|
126
|
-
|
127
|
+
|
127
128
|
# This was to prevent illegal HTML.
|
128
129
|
# Strange chars should still be avoided in codes.
|
129
130
|
evil_chars = Array(0x00...0x20) - [?\n, ?\t, ?\s]
|
@@ -133,21 +134,21 @@ module Encoders
|
|
133
134
|
# \x9 (\t) and \xA (\n) not included
|
134
135
|
#HTML_ESCAPE_PATTERN = /[\t&"><\0-\x8\xB-\x1f\x7f-\xff]/
|
135
136
|
HTML_ESCAPE_PATTERN = /[\t"&><\0-\x8\xB-\x1f]/
|
136
|
-
|
137
|
+
|
137
138
|
TOKEN_KIND_TO_INFO = Hash.new do |h, kind|
|
138
139
|
h[kind] =
|
139
140
|
case kind
|
140
|
-
when :pre_constant
|
141
|
+
when :pre_constant # FIXME: rename to :predefined_constant
|
141
142
|
'Predefined constant'
|
142
143
|
else
|
143
144
|
kind.to_s.gsub(/_/, ' ').gsub(/\b\w/) { $&.capitalize }
|
144
145
|
end
|
145
146
|
end
|
146
|
-
|
147
|
-
TRANSPARENT_TOKEN_KINDS = [
|
147
|
+
|
148
|
+
TRANSPARENT_TOKEN_KINDS = Set[
|
148
149
|
:delimiter, :modifier, :content, :escape, :inline_delimiter,
|
149
|
-
]
|
150
|
-
|
150
|
+
]
|
151
|
+
|
151
152
|
# Generate a hint about the given +kinds+ in a +hint+ style.
|
152
153
|
#
|
153
154
|
# +hint+ may be :info, :info_long or :debug.
|
@@ -161,7 +162,7 @@ module Encoders
|
|
161
162
|
title =
|
162
163
|
case hint
|
163
164
|
when :info
|
164
|
-
TOKEN_KIND_TO_INFO[kinds.first]
|
165
|
+
TOKEN_KIND_TO_INFO[Array(kinds).first]
|
165
166
|
when :info_long
|
166
167
|
kinds.map { |kind| TOKEN_KIND_TO_INFO[kind] }.join('/')
|
167
168
|
when :debug
|
@@ -169,71 +170,68 @@ module Encoders
|
|
169
170
|
end
|
170
171
|
title ? " title=\"#{title}\"" : ''
|
171
172
|
end
|
172
|
-
|
173
|
+
|
173
174
|
def setup options
|
174
175
|
super
|
175
176
|
|
176
177
|
@HTML_ESCAPE = HTML_ESCAPE.dup
|
177
178
|
@HTML_ESCAPE["\t"] = ' ' * options[:tab_width]
|
178
179
|
|
179
|
-
@opened = [
|
180
|
+
@opened = []
|
181
|
+
@last_opened = nil
|
180
182
|
@css = CSS.new options[:style]
|
181
183
|
|
182
184
|
hint = options[:hint]
|
183
|
-
if hint
|
185
|
+
if hint && ![:debug, :info, :info_long].include?(hint)
|
184
186
|
raise ArgumentError, "Unknown value %p for :hint; \
|
185
187
|
expected :info, :debug, false, or nil." % hint
|
186
188
|
end
|
187
|
-
|
189
|
+
|
190
|
+
css_classes = TokenKinds
|
188
191
|
case options[:css]
|
189
|
-
|
190
192
|
when :class
|
191
|
-
@
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
193
|
+
@span_for_kind = Hash.new do |h, k|
|
194
|
+
if k.is_a? ::Symbol
|
195
|
+
kind = k_dup = k
|
196
|
+
else
|
197
|
+
kind = k.first
|
198
|
+
k_dup = k.dup
|
199
|
+
end
|
200
|
+
if kind != :space && (hint || css_class = css_classes[kind])
|
201
|
+
title = HTML.token_path_to_hint hint, k if hint
|
202
|
+
css_class ||= css_classes[kind]
|
203
|
+
h[k_dup] = "<span#{title}#{" class=\"#{css_class}\"" if css_class}>"
|
204
|
+
else
|
205
|
+
h[k_dup] = nil
|
206
|
+
end
|
204
207
|
end
|
205
|
-
|
206
208
|
when :style
|
207
|
-
@
|
208
|
-
|
209
|
-
h[k.dup] =
|
210
|
-
if
|
211
|
-
if hint
|
212
|
-
|
213
|
-
|
214
|
-
style = @css[*classes]
|
215
|
-
if style
|
216
|
-
'<span%s style="%s">' % [title, style]
|
217
|
-
end
|
209
|
+
@span_for_kind = Hash.new do |h, k|
|
210
|
+
kind = k.is_a?(Symbol) ? k : k.first
|
211
|
+
h[k.is_a?(Symbol) ? k : k.dup] =
|
212
|
+
if kind != :space && (hint || css_classes[kind])
|
213
|
+
title = HTML.token_path_to_hint hint, k if hint
|
214
|
+
style = @css.get_style Array(k).map { |c| css_classes[c] }
|
215
|
+
"<span#{title}#{" style=\"#{style}\"" if style}>"
|
218
216
|
end
|
219
217
|
end
|
220
|
-
|
221
218
|
else
|
222
219
|
raise ArgumentError, "Unknown value %p for :css." % options[:css]
|
223
|
-
|
224
220
|
end
|
225
221
|
end
|
226
|
-
|
222
|
+
|
227
223
|
def finish options
|
228
|
-
not_needed = @opened.shift
|
229
224
|
unless @opened.empty?
|
230
225
|
warn '%d tokens still open: %p' % [@opened.size, @opened]
|
231
|
-
@out << '</span>'
|
226
|
+
@out << '</span>' while @opened.pop
|
227
|
+
@last_opened = nil
|
232
228
|
end
|
233
229
|
|
234
230
|
@out.extend Output
|
235
231
|
@out.css = @css
|
236
|
-
|
232
|
+
if options[:line_numbers]
|
233
|
+
Numbering.number! @out, options[:line_numbers], options
|
234
|
+
end
|
237
235
|
@out.wrap! options[:wrap]
|
238
236
|
@out.apply_title! options[:title]
|
239
237
|
|
@@ -246,64 +244,58 @@ module Encoders
|
|
246
244
|
if text =~ /#{HTML_ESCAPE_PATTERN}/o
|
247
245
|
text = text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| @HTML_ESCAPE[m] }
|
248
246
|
end
|
249
|
-
@opened
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
text
|
255
|
-
end
|
247
|
+
if style = @span_for_kind[@last_opened ? [kind, *@opened] : kind]
|
248
|
+
@out << style << text << '</span>'
|
249
|
+
else
|
250
|
+
@out << text
|
251
|
+
end
|
256
252
|
end
|
257
253
|
|
258
254
|
# token groups, eg. strings
|
259
255
|
def begin_group kind
|
260
|
-
@opened
|
256
|
+
@out << (@span_for_kind[@last_opened ? [kind, *@opened] : kind] || '<span>')
|
261
257
|
@opened << kind
|
262
|
-
@
|
258
|
+
@last_opened = kind if @options[:css] == :style
|
263
259
|
end
|
264
260
|
|
265
261
|
def end_group kind
|
266
|
-
if $CODERAY_DEBUG
|
262
|
+
if $CODERAY_DEBUG && (@opened.empty? || @opened.last != kind)
|
267
263
|
warn 'Malformed token stream: Trying to close a token (%p) ' \
|
268
264
|
'that is not open. Open are: %p.' % [kind, @opened[1..-1]]
|
269
265
|
end
|
270
|
-
@
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
@opened.pop
|
275
|
-
'</span>'
|
276
|
-
end
|
266
|
+
if @opened.pop
|
267
|
+
@out << '</span>'
|
268
|
+
@last_opened = @opened.last if @last_opened
|
269
|
+
end
|
277
270
|
end
|
278
271
|
|
279
272
|
# whole lines to be highlighted, eg. a deleted line in a diff
|
280
273
|
def begin_line kind
|
281
|
-
@opened
|
282
|
-
|
283
|
-
|
284
|
-
@out <<
|
285
|
-
if style
|
286
|
-
style.sub '<span', '<div'
|
274
|
+
if style = @span_for_kind[@last_opened ? [kind, *@opened] : kind]
|
275
|
+
if style['class="']
|
276
|
+
@out << style.sub('class="', 'class="line ')
|
287
277
|
else
|
288
|
-
'
|
278
|
+
@out << style.sub('>', ' class="line">')
|
289
279
|
end
|
280
|
+
else
|
281
|
+
@out << '<span class="line">'
|
282
|
+
end
|
283
|
+
@opened << kind
|
284
|
+
@last_opened = kind if @options[:css] == :style
|
290
285
|
end
|
291
286
|
|
292
287
|
def end_line kind
|
293
|
-
if $CODERAY_DEBUG
|
288
|
+
if $CODERAY_DEBUG && (@opened.empty? || @opened.last != kind)
|
294
289
|
warn 'Malformed token stream: Trying to close a line (%p) ' \
|
295
290
|
'that is not open. Open are: %p.' % [kind, @opened[1..-1]]
|
296
291
|
end
|
297
|
-
@
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
@opened.pop
|
302
|
-
'</div>'
|
303
|
-
end
|
292
|
+
if @opened.pop
|
293
|
+
@out << '</span>'
|
294
|
+
@last_opened = @opened.last if @last_opened
|
295
|
+
end
|
304
296
|
end
|
305
|
-
|
297
|
+
|
306
298
|
end
|
307
|
-
|
299
|
+
|
308
300
|
end
|
309
301
|
end
|