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.
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