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,75 @@
|
|
1
|
+
($:.unshift '../..'; require 'coderay') unless defined? CodeRay
|
2
|
+
module CodeRay
|
3
|
+
module Encoders
|
4
|
+
|
5
|
+
class Filter < Encoder
|
6
|
+
|
7
|
+
register_for :filter
|
8
|
+
|
9
|
+
protected
|
10
|
+
def setup options
|
11
|
+
@out = Tokens.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def text_token text, kind
|
15
|
+
[text, kind] if include_text_token? text, kind
|
16
|
+
end
|
17
|
+
|
18
|
+
def include_text_token? text, kind
|
19
|
+
true
|
20
|
+
end
|
21
|
+
|
22
|
+
def block_token action, kind
|
23
|
+
[action, kind] if include_block_token? action, kind
|
24
|
+
end
|
25
|
+
|
26
|
+
def include_block_token? action, kind
|
27
|
+
true
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
if $0 == __FILE__
|
36
|
+
$VERBOSE = true
|
37
|
+
$: << File.join(File.dirname(__FILE__), '..')
|
38
|
+
eval DATA.read, nil, $0, __LINE__ + 4
|
39
|
+
end
|
40
|
+
|
41
|
+
__END__
|
42
|
+
require 'test/unit'
|
43
|
+
|
44
|
+
class FilterTest < Test::Unit::TestCase
|
45
|
+
|
46
|
+
def test_creation
|
47
|
+
assert CodeRay::Encoders::Filter < CodeRay::Encoders::Encoder
|
48
|
+
filter = nil
|
49
|
+
assert_nothing_raised do
|
50
|
+
filter = CodeRay.encoder :filter
|
51
|
+
end
|
52
|
+
assert_kind_of CodeRay::Encoders::Encoder, filter
|
53
|
+
end
|
54
|
+
|
55
|
+
def test_filtering_text_tokens
|
56
|
+
tokens = CodeRay::Tokens.new
|
57
|
+
10.times do |i|
|
58
|
+
tokens << [i.to_s, :index]
|
59
|
+
end
|
60
|
+
assert_equal tokens, CodeRay::Encoders::Filter.new.encode_tokens(tokens)
|
61
|
+
assert_equal tokens, tokens.filter
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_filtering_block_tokens
|
65
|
+
tokens = CodeRay::Tokens.new
|
66
|
+
10.times do |i|
|
67
|
+
tokens << [:open, :index]
|
68
|
+
tokens << [i.to_s, :content]
|
69
|
+
tokens << [:close, :index]
|
70
|
+
end
|
71
|
+
assert_equal tokens, CodeRay::Encoders::Filter.new.encode_tokens(tokens)
|
72
|
+
assert_equal tokens, tokens.filter
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,305 @@
|
|
1
|
+
require "set"
|
2
|
+
|
3
|
+
module CodeRay
|
4
|
+
module Encoders
|
5
|
+
|
6
|
+
# = HTML Encoder
|
7
|
+
#
|
8
|
+
# This is CodeRay's most important highlighter:
|
9
|
+
# It provides save, fast XHTML generation and CSS support.
|
10
|
+
#
|
11
|
+
# == Usage
|
12
|
+
#
|
13
|
+
# require 'coderay'
|
14
|
+
# puts CodeRay.scan('Some /code/', :ruby).html #-> a HTML page
|
15
|
+
# puts CodeRay.scan('Some /code/', :ruby).html(:wrap => :span)
|
16
|
+
# #-> <span class="CodeRay"><span class="co">Some</span> /code/</span>
|
17
|
+
# puts CodeRay.scan('Some /code/', :ruby).span #-> the same
|
18
|
+
#
|
19
|
+
# puts CodeRay.scan('Some code', :ruby).html(
|
20
|
+
# :wrap => nil,
|
21
|
+
# :line_numbers => :inline,
|
22
|
+
# :css => :style
|
23
|
+
# )
|
24
|
+
# #-> <span class="no">1</span> <span style="color:#036; font-weight:bold;">Some</span> code
|
25
|
+
#
|
26
|
+
# == Options
|
27
|
+
#
|
28
|
+
# === :tab_width
|
29
|
+
# Convert \t characters to +n+ spaces (a number.)
|
30
|
+
# Default: 8
|
31
|
+
#
|
32
|
+
# === :css
|
33
|
+
# How to include the styles; can be :class or :style.
|
34
|
+
#
|
35
|
+
# Default: :class
|
36
|
+
#
|
37
|
+
# === :wrap
|
38
|
+
# Wrap in :page, :div, :span or nil.
|
39
|
+
#
|
40
|
+
# You can also use Encoders::Div and Encoders::Span.
|
41
|
+
#
|
42
|
+
# Default: nil
|
43
|
+
#
|
44
|
+
# === :title
|
45
|
+
#
|
46
|
+
# The title of the HTML page (works only when :wrap is set to :page.)
|
47
|
+
#
|
48
|
+
# Default: 'CodeRay output'
|
49
|
+
#
|
50
|
+
# === :line_numbers
|
51
|
+
# Include line numbers in :table, :inline, :list or nil (no line numbers)
|
52
|
+
#
|
53
|
+
# Default: nil
|
54
|
+
#
|
55
|
+
# === :line_number_start
|
56
|
+
# Where to start with line number counting.
|
57
|
+
#
|
58
|
+
# Default: 1
|
59
|
+
#
|
60
|
+
# === :bold_every
|
61
|
+
# Make every +n+-th number appear bold.
|
62
|
+
#
|
63
|
+
# Default: 10
|
64
|
+
#
|
65
|
+
# === :highlight_lines
|
66
|
+
#
|
67
|
+
# Highlights certain line numbers.
|
68
|
+
# Can be any Enumerable, typically just an Array or Range, of numbers.
|
69
|
+
#
|
70
|
+
# Bolding is deactivated when :highlight_lines is set. It only makes sense
|
71
|
+
# in combination with :line_numbers.
|
72
|
+
#
|
73
|
+
# Default: nil
|
74
|
+
#
|
75
|
+
# === :hint
|
76
|
+
# Include some information into the output using the title attribute.
|
77
|
+
# Can be :info (show token type on mouse-over), :info_long (with full path)
|
78
|
+
# or :debug (via inspect).
|
79
|
+
#
|
80
|
+
# Default: false
|
81
|
+
class HTML < Encoder
|
82
|
+
|
83
|
+
include Streamable
|
84
|
+
register_for :html
|
85
|
+
|
86
|
+
FILE_EXTENSION = 'html'
|
87
|
+
|
88
|
+
DEFAULT_OPTIONS = {
|
89
|
+
:tab_width => 8,
|
90
|
+
|
91
|
+
:css => :class,
|
92
|
+
|
93
|
+
:style => :cycnus,
|
94
|
+
:wrap => nil,
|
95
|
+
:title => 'CodeRay output',
|
96
|
+
|
97
|
+
:line_numbers => nil,
|
98
|
+
:line_number_start => 1,
|
99
|
+
:bold_every => 10,
|
100
|
+
:highlight_lines => nil,
|
101
|
+
|
102
|
+
:hint => false,
|
103
|
+
}
|
104
|
+
|
105
|
+
helper :output, :css
|
106
|
+
|
107
|
+
attr_reader :css
|
108
|
+
|
109
|
+
protected
|
110
|
+
|
111
|
+
HTML_ESCAPE = { #:nodoc:
|
112
|
+
'&' => '&',
|
113
|
+
'"' => '"',
|
114
|
+
'>' => '>',
|
115
|
+
'<' => '<',
|
116
|
+
}
|
117
|
+
|
118
|
+
# This was to prevent illegal HTML.
|
119
|
+
# Strange chars should still be avoided in codes.
|
120
|
+
evil_chars = Array(0x00...0x20) - [?\n, ?\t, ?\s]
|
121
|
+
evil_chars.each { |i| HTML_ESCAPE[i.chr] = ' ' }
|
122
|
+
#ansi_chars = Array(0x7f..0xff)
|
123
|
+
#ansi_chars.each { |i| HTML_ESCAPE[i.chr] = '&#%d;' % i }
|
124
|
+
# \x9 (\t) and \xA (\n) not included
|
125
|
+
#HTML_ESCAPE_PATTERN = /[\t&"><\0-\x8\xB-\x1f\x7f-\xff]/
|
126
|
+
HTML_ESCAPE_PATTERN = /[\t"&><\0-\x8\xB-\x1f]/
|
127
|
+
|
128
|
+
TOKEN_KIND_TO_INFO = Hash.new { |h, kind|
|
129
|
+
h[kind] =
|
130
|
+
case kind
|
131
|
+
when :pre_constant
|
132
|
+
'Predefined constant'
|
133
|
+
else
|
134
|
+
kind.to_s.gsub(/_/, ' ').gsub(/\b\w/) { $&.capitalize }
|
135
|
+
end
|
136
|
+
}
|
137
|
+
|
138
|
+
TRANSPARENT_TOKEN_KINDS = [
|
139
|
+
:delimiter, :modifier, :content, :escape, :inline_delimiter,
|
140
|
+
].to_set
|
141
|
+
|
142
|
+
# Generate a hint about the given +classes+ in a +hint+ style.
|
143
|
+
#
|
144
|
+
# +hint+ may be :info, :info_long or :debug.
|
145
|
+
def self.token_path_to_hint hint, classes
|
146
|
+
title =
|
147
|
+
case hint
|
148
|
+
when :info
|
149
|
+
TOKEN_KIND_TO_INFO[classes.first]
|
150
|
+
when :info_long
|
151
|
+
classes.reverse.map { |kind| TOKEN_KIND_TO_INFO[kind] }.join('/')
|
152
|
+
when :debug
|
153
|
+
classes.inspect
|
154
|
+
end
|
155
|
+
title ? " title=\"#{title}\"" : ''
|
156
|
+
end
|
157
|
+
|
158
|
+
def setup options
|
159
|
+
super
|
160
|
+
|
161
|
+
@HTML_ESCAPE = HTML_ESCAPE.dup
|
162
|
+
@HTML_ESCAPE["\t"] = ' ' * options[:tab_width]
|
163
|
+
|
164
|
+
@opened = [nil]
|
165
|
+
@css = CSS.new options[:style]
|
166
|
+
|
167
|
+
hint = options[:hint]
|
168
|
+
if hint and not [:debug, :info, :info_long].include? hint
|
169
|
+
raise ArgumentError, "Unknown value %p for :hint; \
|
170
|
+
expected :info, :debug, false, or nil." % hint
|
171
|
+
end
|
172
|
+
|
173
|
+
case options[:css]
|
174
|
+
|
175
|
+
when :class
|
176
|
+
@css_style = Hash.new do |h, k|
|
177
|
+
c = CodeRay::Tokens::ClassOfKind[k.first]
|
178
|
+
if c == :NO_HIGHLIGHT and not hint
|
179
|
+
h[k.dup] = false
|
180
|
+
else
|
181
|
+
title = if hint
|
182
|
+
HTML.token_path_to_hint(hint, k[1..-1] << k.first)
|
183
|
+
else
|
184
|
+
''
|
185
|
+
end
|
186
|
+
if c == :NO_HIGHLIGHT
|
187
|
+
h[k.dup] = '<span%s>' % [title]
|
188
|
+
else
|
189
|
+
h[k.dup] = '<span%s class="%s">' % [title, c]
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
when :style
|
195
|
+
@css_style = Hash.new do |h, k|
|
196
|
+
if k.is_a? ::Array
|
197
|
+
styles = k.dup
|
198
|
+
else
|
199
|
+
styles = [k]
|
200
|
+
end
|
201
|
+
type = styles.first
|
202
|
+
classes = styles.map { |c| Tokens::ClassOfKind[c] }
|
203
|
+
if classes.first == :NO_HIGHLIGHT and not hint
|
204
|
+
h[k] = false
|
205
|
+
else
|
206
|
+
styles.shift if TRANSPARENT_TOKEN_KINDS.include? styles.first
|
207
|
+
title = HTML.token_path_to_hint hint, styles
|
208
|
+
style = @css[*classes]
|
209
|
+
h[k] =
|
210
|
+
if style
|
211
|
+
'<span%s style="%s">' % [title, style]
|
212
|
+
else
|
213
|
+
false
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
else
|
219
|
+
raise ArgumentError, "Unknown value %p for :css." % options[:css]
|
220
|
+
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
def finish options
|
225
|
+
not_needed = @opened.shift
|
226
|
+
@out << '</span>' * @opened.size
|
227
|
+
unless @opened.empty?
|
228
|
+
warn '%d tokens still open: %p' % [@opened.size, @opened]
|
229
|
+
end
|
230
|
+
|
231
|
+
@out.extend Output
|
232
|
+
@out.css = @css
|
233
|
+
@out.numerize! options[:line_numbers], options
|
234
|
+
@out.wrap! options[:wrap]
|
235
|
+
@out.apply_title! options[:title]
|
236
|
+
|
237
|
+
super
|
238
|
+
end
|
239
|
+
|
240
|
+
def token text, type = :plain
|
241
|
+
case text
|
242
|
+
|
243
|
+
when nil
|
244
|
+
# raise 'Token with nil as text was given: %p' % [[text, type]]
|
245
|
+
|
246
|
+
when String
|
247
|
+
if text =~ /#{HTML_ESCAPE_PATTERN}/o
|
248
|
+
text = text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| @HTML_ESCAPE[m] }
|
249
|
+
end
|
250
|
+
@opened[0] = type
|
251
|
+
if text != "\n" && style = @css_style[@opened]
|
252
|
+
@out << style << text << '</span>'
|
253
|
+
else
|
254
|
+
@out << text
|
255
|
+
end
|
256
|
+
|
257
|
+
|
258
|
+
# token groups, eg. strings
|
259
|
+
when :open
|
260
|
+
@opened[0] = type
|
261
|
+
@out << (@css_style[@opened] || '<span>')
|
262
|
+
@opened << type
|
263
|
+
when :close
|
264
|
+
if @opened.empty?
|
265
|
+
# nothing to close
|
266
|
+
else
|
267
|
+
if $DEBUG and (@opened.size == 1 or @opened.last != type)
|
268
|
+
raise 'Malformed token stream: Trying to close a token (%p) \
|
269
|
+
that is not open. Open are: %p.' % [type, @opened[1..-1]]
|
270
|
+
end
|
271
|
+
@out << '</span>'
|
272
|
+
@opened.pop
|
273
|
+
end
|
274
|
+
|
275
|
+
# whole lines to be highlighted, eg. a deleted line in a diff
|
276
|
+
when :begin_line
|
277
|
+
@opened[0] = type
|
278
|
+
if style = @css_style[@opened]
|
279
|
+
@out << style.sub('<span', '<div')
|
280
|
+
else
|
281
|
+
@out << '<div>'
|
282
|
+
end
|
283
|
+
@opened << type
|
284
|
+
when :end_line
|
285
|
+
if @opened.empty?
|
286
|
+
# nothing to close
|
287
|
+
else
|
288
|
+
if $DEBUG and (@opened.size == 1 or @opened.last != type)
|
289
|
+
raise 'Malformed token stream: Trying to close a line (%p) \
|
290
|
+
that is not open. Open are: %p.' % [type, @opened[1..-1]]
|
291
|
+
end
|
292
|
+
@out << '</div>'
|
293
|
+
@opened.pop
|
294
|
+
end
|
295
|
+
|
296
|
+
else
|
297
|
+
raise 'unknown token kind: %p' % [text]
|
298
|
+
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
end
|
303
|
+
|
304
|
+
end
|
305
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module CodeRay
|
2
|
+
module Encoders
|
3
|
+
|
4
|
+
class HTML
|
5
|
+
class CSS
|
6
|
+
|
7
|
+
attr :stylesheet
|
8
|
+
|
9
|
+
def CSS.load_stylesheet style = nil
|
10
|
+
CodeRay::Styles[style]
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize style = :default
|
14
|
+
@classes = Hash.new
|
15
|
+
style = CSS.load_stylesheet style
|
16
|
+
@stylesheet = [
|
17
|
+
style::CSS_MAIN_STYLES,
|
18
|
+
style::TOKEN_COLORS.gsub(/^(?!$)/, '.CodeRay ')
|
19
|
+
].join("\n")
|
20
|
+
parse style::TOKEN_COLORS
|
21
|
+
end
|
22
|
+
|
23
|
+
def [] *styles
|
24
|
+
cl = @classes[styles.first]
|
25
|
+
return '' unless cl
|
26
|
+
style = ''
|
27
|
+
1.upto(styles.size) do |offset|
|
28
|
+
break if style = cl[styles[offset .. -1]]
|
29
|
+
end
|
30
|
+
$stderr.puts 'Style not found: %p' % [styles] if $DEBUG and style.empty?
|
31
|
+
return style
|
32
|
+
end
|
33
|
+
|
34
|
+
private
|
35
|
+
|
36
|
+
CSS_CLASS_PATTERN = /
|
37
|
+
( # $1 = selectors
|
38
|
+
(?:
|
39
|
+
(?: \s* \. [-\w]+ )+
|
40
|
+
\s* ,?
|
41
|
+
)+
|
42
|
+
)
|
43
|
+
\s* \{ \s*
|
44
|
+
( [^\}]+ )? # $2 = style
|
45
|
+
\s* \} \s*
|
46
|
+
|
|
47
|
+
( . ) # $3 = error
|
48
|
+
/mx
|
49
|
+
def parse stylesheet
|
50
|
+
stylesheet.scan CSS_CLASS_PATTERN do |selectors, style, error|
|
51
|
+
raise "CSS parse error: '#{error.inspect}' not recognized" if error
|
52
|
+
for selector in selectors.split(',')
|
53
|
+
classes = selector.scan(/[-\w]+/)
|
54
|
+
cl = classes.pop
|
55
|
+
@classes[cl] ||= Hash.new
|
56
|
+
@classes[cl][classes] = style.to_s.strip.delete(' ').chomp(';')
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
if $0 == __FILE__
|
68
|
+
require 'pp'
|
69
|
+
pp CodeRay::Encoders::HTML::CSS.new
|
70
|
+
end
|