coderay-beta 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. data/FOLDERS +53 -0
  2. data/LICENSE +504 -0
  3. data/bin/coderay +82 -0
  4. data/bin/coderay_stylesheet +4 -0
  5. data/lib/README +129 -0
  6. data/lib/coderay.rb +320 -0
  7. data/lib/coderay/duo.rb +85 -0
  8. data/lib/coderay/encoder.rb +213 -0
  9. data/lib/coderay/encoders/_map.rb +11 -0
  10. data/lib/coderay/encoders/comment_filter.rb +43 -0
  11. data/lib/coderay/encoders/count.rb +21 -0
  12. data/lib/coderay/encoders/debug.rb +49 -0
  13. data/lib/coderay/encoders/div.rb +19 -0
  14. data/lib/coderay/encoders/filter.rb +75 -0
  15. data/lib/coderay/encoders/html.rb +305 -0
  16. data/lib/coderay/encoders/html/css.rb +70 -0
  17. data/lib/coderay/encoders/html/numerization.rb +133 -0
  18. data/lib/coderay/encoders/html/output.rb +206 -0
  19. data/lib/coderay/encoders/json.rb +69 -0
  20. data/lib/coderay/encoders/lines_of_code.rb +90 -0
  21. data/lib/coderay/encoders/null.rb +26 -0
  22. data/lib/coderay/encoders/page.rb +20 -0
  23. data/lib/coderay/encoders/span.rb +19 -0
  24. data/lib/coderay/encoders/statistic.rb +77 -0
  25. data/lib/coderay/encoders/term.rb +137 -0
  26. data/lib/coderay/encoders/text.rb +32 -0
  27. data/lib/coderay/encoders/token_class_filter.rb +84 -0
  28. data/lib/coderay/encoders/xml.rb +71 -0
  29. data/lib/coderay/encoders/yaml.rb +22 -0
  30. data/lib/coderay/for_redcloth.rb +85 -0
  31. data/lib/coderay/helpers/file_type.rb +240 -0
  32. data/lib/coderay/helpers/gzip_simple.rb +123 -0
  33. data/lib/coderay/helpers/plugin.rb +349 -0
  34. data/lib/coderay/helpers/word_list.rb +138 -0
  35. data/lib/coderay/scanner.rb +284 -0
  36. data/lib/coderay/scanners/_map.rb +23 -0
  37. data/lib/coderay/scanners/c.rb +203 -0
  38. data/lib/coderay/scanners/cpp.rb +228 -0
  39. data/lib/coderay/scanners/css.rb +210 -0
  40. data/lib/coderay/scanners/debug.rb +62 -0
  41. data/lib/coderay/scanners/delphi.rb +150 -0
  42. data/lib/coderay/scanners/diff.rb +105 -0
  43. data/lib/coderay/scanners/groovy.rb +263 -0
  44. data/lib/coderay/scanners/html.rb +182 -0
  45. data/lib/coderay/scanners/java.rb +176 -0
  46. data/lib/coderay/scanners/java/builtin_types.rb +419 -0
  47. data/lib/coderay/scanners/java_script.rb +224 -0
  48. data/lib/coderay/scanners/json.rb +112 -0
  49. data/lib/coderay/scanners/nitro_xhtml.rb +136 -0
  50. data/lib/coderay/scanners/php.rb +526 -0
  51. data/lib/coderay/scanners/plaintext.rb +21 -0
  52. data/lib/coderay/scanners/python.rb +285 -0
  53. data/lib/coderay/scanners/rhtml.rb +74 -0
  54. data/lib/coderay/scanners/ruby.rb +404 -0
  55. data/lib/coderay/scanners/ruby/patterns.rb +238 -0
  56. data/lib/coderay/scanners/scheme.rb +145 -0
  57. data/lib/coderay/scanners/sql.rb +162 -0
  58. data/lib/coderay/scanners/xml.rb +17 -0
  59. data/lib/coderay/scanners/yaml.rb +144 -0
  60. data/lib/coderay/style.rb +20 -0
  61. data/lib/coderay/styles/_map.rb +7 -0
  62. data/lib/coderay/styles/cycnus.rb +151 -0
  63. data/lib/coderay/styles/murphy.rb +132 -0
  64. data/lib/coderay/token_classes.rb +86 -0
  65. data/lib/coderay/tokens.rb +391 -0
  66. data/lib/term/ansicolor.rb +220 -0
  67. 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
+ '&' => '&amp;',
113
+ '"' => '&quot;',
114
+ '>' => '&gt;',
115
+ '<' => '&lt;',
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