coderay 0.8.357 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/lib/README +4 -3
  2. data/lib/coderay.rb +2 -1
  3. data/lib/coderay/encoder.rb +41 -15
  4. data/lib/coderay/encoders/_map.rb +3 -1
  5. data/lib/coderay/encoders/comment_filter.rb +43 -0
  6. data/lib/coderay/encoders/div.rb +2 -3
  7. data/lib/coderay/encoders/filter.rb +75 -0
  8. data/lib/coderay/encoders/html.rb +20 -3
  9. data/lib/coderay/encoders/html/css.rb +1 -1
  10. data/lib/coderay/encoders/html/numerization.rb +11 -2
  11. data/lib/coderay/encoders/html/output.rb +10 -1
  12. data/lib/coderay/encoders/json.rb +69 -0
  13. data/lib/coderay/encoders/lines_of_code.rb +90 -0
  14. data/lib/coderay/encoders/page.rb +1 -2
  15. data/lib/coderay/encoders/span.rb +2 -3
  16. data/lib/coderay/encoders/term.rb +137 -0
  17. data/lib/coderay/encoders/text.rb +4 -4
  18. data/lib/coderay/encoders/token_class_filter.rb +84 -0
  19. data/lib/coderay/encoders/xml.rb +1 -0
  20. data/lib/coderay/for_redcloth.rb +9 -4
  21. data/lib/coderay/helpers/file_type.rb +54 -15
  22. data/lib/coderay/helpers/plugin.rb +21 -3
  23. data/lib/coderay/helpers/word_list.rb +19 -4
  24. data/lib/coderay/scanner.rb +33 -2
  25. data/lib/coderay/scanners/_map.rb +10 -4
  26. data/lib/coderay/scanners/c.rb +61 -23
  27. data/lib/coderay/scanners/cpp.rb +228 -0
  28. data/lib/coderay/scanners/css.rb +9 -1
  29. data/lib/coderay/scanners/debug.rb +1 -0
  30. data/lib/coderay/scanners/delphi.rb +2 -2
  31. data/lib/coderay/scanners/diff.rb +1 -0
  32. data/lib/coderay/scanners/groovy.rb +263 -0
  33. data/lib/coderay/scanners/html.rb +9 -2
  34. data/lib/coderay/scanners/java.rb +18 -14
  35. data/lib/coderay/scanners/java_script.rb +42 -13
  36. data/lib/coderay/scanners/json.rb +7 -1
  37. data/lib/coderay/scanners/nitro_xhtml.rb +4 -0
  38. data/lib/coderay/scanners/php.rb +526 -0
  39. data/lib/coderay/scanners/plaintext.rb +4 -1
  40. data/lib/coderay/scanners/python.rb +285 -0
  41. data/lib/coderay/scanners/rhtml.rb +3 -0
  42. data/lib/coderay/scanners/ruby.rb +29 -11
  43. data/lib/coderay/scanners/ruby/patterns.rb +26 -20
  44. data/lib/coderay/scanners/scheme.rb +3 -0
  45. data/lib/coderay/scanners/sql.rb +162 -0
  46. data/lib/coderay/scanners/xml.rb +1 -1
  47. data/lib/coderay/scanners/yaml.rb +4 -1
  48. data/lib/coderay/styles/cycnus.rb +11 -7
  49. data/lib/coderay/token_classes.rb +4 -1
  50. data/lib/coderay/tokens.rb +50 -46
  51. metadata +14 -4
  52. data/lib/coderay/encoders/tokens.rb +0 -44
data/lib/README CHANGED
@@ -18,7 +18,7 @@ And with line numbers.
18
18
  * is what everybody should have on their website
19
19
  * solves all your problems and makes the girls run after you
20
20
 
21
- Version: 0.8.4
21
+ Version: 0.9.1
22
22
  Author:: murphy (Kornelius Kalnbach)
23
23
  Contact:: murphy rubychan de
24
24
  Website:: coderay.rubychan.de[http://coderay.rubychan.de]
@@ -88,10 +88,11 @@ Please report errors in this documentation to <murphy rubychan de>.
88
88
  * Jeremy Hinegardner for finding the shebang-on-empty-file bug in FileType.
89
89
  * Charles Oliver Nutter and Yehuda Katz for helping me benchmark CodeRay on JRuby.
90
90
  * Andreas Neuhaus for pointing out a markup bug in coderay/for_redcloth.
91
+ * 0xf30fc7 for the FileType patch concerning Delphi file extensions.
91
92
  * The folks at redmine.org - thank you for using and fixing CodeRay!
92
93
  * matz and all Ruby gods and gurus
93
94
  * The inventors of: the computer, the internet, the true color display, HTML &
94
- CSS, VIM, RUBY, pizza, microwaves, guitars, scouting, programming, anime,
95
+ CSS, VIM, Ruby, pizza, microwaves, guitars, scouting, programming, anime,
95
96
  manga, coke and green ice tea.
96
97
 
97
98
  Where would we be without all those people?
@@ -107,7 +108,7 @@ Where would we be without all those people?
107
108
  * Subversion[http://subversion.tigris.org/]
108
109
  * Redmine[http://redmine.org/]
109
110
  * Firefox[http://www.mozilla.org/products/firefox/],
110
- Firebug[http://getfirebug.com/], and
111
+ Firebug[http://getfirebug.com/], Safari[http://www.apple.com/safari/], and
111
112
  Thunderbird[http://www.mozilla.org/products/thunderbird/]
112
113
  * RubyGems[http://docs.rubygems.org/] and Rake[http://rake.rubyforge.org/]
113
114
  * TortoiseSVN[http://tortoisesvn.tigris.org/] using Apache via
@@ -132,9 +132,10 @@ module CodeRay
132
132
  # Minor: feature milestone
133
133
  # Teeny: development state, 0 for pre-release
134
134
  # Revision: Subversion Revision number (generated on rake gem:make)
135
- VERSION = '0.8'
135
+ VERSION = '0.9.1'
136
136
 
137
137
  require 'coderay/tokens'
138
+ require 'coderay/token_classes'
138
139
  require 'coderay/scanner'
139
140
  require 'coderay/encoder'
140
141
  require 'coderay/duo'
@@ -1,5 +1,3 @@
1
- require "stringio"
2
-
3
1
  module CodeRay
4
2
 
5
3
  # This module holds the Encoder class and its subclasses.
@@ -126,26 +124,36 @@ module CodeRay
126
124
  @out = ''
127
125
  end
128
126
 
129
- # Called with +text+ and +kind+ of the currently scanned token.
127
+ # Called with +content+ and +kind+ of the currently scanned token.
130
128
  # For simple scanners, it's enougth to implement this method.
131
129
  #
132
130
  # By default, it calls text_token or block_token, depending on
133
- # whether +text+ is a String.
134
- def token text, kind
135
- out =
136
- if text.is_a? ::String
137
- text_token text, kind
138
- elsif text.is_a? ::Symbol
139
- block_token text, kind
131
+ # whether +content+ is a String.
132
+ def token content, kind
133
+ encoded_token =
134
+ if content.is_a? ::String
135
+ text_token content, kind
136
+ elsif content.is_a? ::Symbol
137
+ block_token content, kind
140
138
  else
141
- raise 'Unknown token text type: %p' % text
139
+ raise 'Unknown token content type: %p' % [content]
142
140
  end
143
- @out << out if defined?(@out) && @out
141
+ append_encoded_token_to_output encoded_token
144
142
  end
145
-
143
+
144
+ def append_encoded_token_to_output encoded_token
145
+ @out << encoded_token if encoded_token && defined?(@out) && @out
146
+ end
147
+
148
+ # Called for each text token ([text, kind]), where text is a String.
146
149
  def text_token text, kind
147
150
  end
148
-
151
+
152
+ # Called for each block (non-text) token ([action, kind]),
153
+ # where +action+ is a Symbol.
154
+ #
155
+ # Calls open_token, close_token, begin_line, and end_line according to
156
+ # the value of +action+.
149
157
  def block_token action, kind
150
158
  case action
151
159
  when :open
@@ -160,6 +168,22 @@ module CodeRay
160
168
  raise 'unknown block action: %p' % action
161
169
  end
162
170
  end
171
+
172
+ # Called for each block token at the start of the block ([:open, kind]).
173
+ def open_token kind
174
+ end
175
+
176
+ # Called for each block token end of the block ([:close, kind]).
177
+ def close_token kind
178
+ end
179
+
180
+ # Called for each line token block at the start of the line ([:begin_line, kind]).
181
+ def begin_line kind
182
+ end
183
+
184
+ # Called for each line token block at the end of the line ([:end_line, kind]).
185
+ def end_line kind
186
+ end
163
187
 
164
188
  # Called with merged options after encoding starts.
165
189
  # The return value is the result of encoding, typically @out.
@@ -173,7 +197,9 @@ module CodeRay
173
197
  # TokenStream or a Tokens object.
174
198
  if RUBY_VERSION >= '1.9'
175
199
  def compile tokens, options
176
- tokens.each { |text, kind| token text, kind } # FIXME for Ruby 1.9?
200
+ for text, kind in tokens
201
+ token text, kind
202
+ end
177
203
  end
178
204
  else
179
205
  def compile tokens, options
@@ -1,8 +1,10 @@
1
1
  module CodeRay
2
2
  module Encoders
3
3
 
4
- map :stats => :statistic,
4
+ map \
5
+ :loc => :lines_of_code,
5
6
  :plain => :text,
7
+ :stats => :statistic,
6
8
  :tex => :latex
7
9
 
8
10
  end
@@ -0,0 +1,43 @@
1
+ ($:.unshift '../..'; require 'coderay') unless defined? CodeRay
2
+ module CodeRay
3
+ module Encoders
4
+
5
+ load :token_class_filter
6
+
7
+ class CommentFilter < TokenClassFilter
8
+
9
+ register_for :comment_filter
10
+
11
+ DEFAULT_OPTIONS = superclass::DEFAULT_OPTIONS.merge \
12
+ :exclude => [:comment]
13
+
14
+ end
15
+
16
+ end
17
+ end
18
+
19
+ if $0 == __FILE__
20
+ $VERBOSE = true
21
+ $: << File.join(File.dirname(__FILE__), '..')
22
+ eval DATA.read, nil, $0, __LINE__ + 4
23
+ end
24
+
25
+ __END__
26
+ require 'test/unit'
27
+
28
+ class CommentFilterTest < Test::Unit::TestCase
29
+
30
+ def test_filtering_comments
31
+ tokens = CodeRay.scan <<-RUBY, :ruby
32
+ #!/usr/bin/env ruby
33
+ # a minimal Ruby program
34
+ puts "Hello world!"
35
+ RUBY
36
+ assert_equal <<-RUBY_FILTERED, tokens.comment_filter.text
37
+ #!/usr/bin/env ruby
38
+
39
+ puts "Hello world!"
40
+ RUBY_FILTERED
41
+ end
42
+
43
+ end
@@ -9,10 +9,9 @@ module Encoders
9
9
 
10
10
  register_for :div
11
11
 
12
- DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge({
12
+ DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \
13
13
  :css => :style,
14
- :wrap => :div,
15
- })
14
+ :wrap => :div
16
15
 
17
16
  end
18
17
 
@@ -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
@@ -1,4 +1,4 @@
1
- require "set"
1
+ require 'set'
2
2
 
3
3
  module CodeRay
4
4
  module Encoders
@@ -41,6 +41,12 @@ module Encoders
41
41
  #
42
42
  # Default: nil
43
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
+ #
44
50
  # === :line_numbers
45
51
  # Include line numbers in :table, :inline, :list or nil (no line numbers)
46
52
  #
@@ -56,6 +62,16 @@ module Encoders
56
62
  #
57
63
  # Default: 10
58
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
+ #
59
75
  # === :hint
60
76
  # Include some information into the output using the title attribute.
61
77
  # Can be :info (show token type on mouse-over), :info_long (with full path)
@@ -72,16 +88,16 @@ module Encoders
72
88
  DEFAULT_OPTIONS = {
73
89
  :tab_width => 8,
74
90
 
75
- :level => :xhtml,
76
91
  :css => :class,
77
92
 
78
93
  :style => :cycnus,
79
-
80
94
  :wrap => nil,
95
+ :title => 'CodeRay output',
81
96
 
82
97
  :line_numbers => nil,
83
98
  :line_number_start => 1,
84
99
  :bold_every => 10,
100
+ :highlight_lines => nil,
85
101
 
86
102
  :hint => false,
87
103
  }
@@ -216,6 +232,7 @@ module Encoders
216
232
  @out.css = @css
217
233
  @out.numerize! options[:line_numbers], options
218
234
  @out.wrap! options[:wrap]
235
+ @out.apply_title! options[:title]
219
236
 
220
237
  super
221
238
  end
@@ -27,7 +27,7 @@ module Encoders
27
27
  1.upto(styles.size) do |offset|
28
28
  break if style = cl[styles[offset .. -1]]
29
29
  end
30
- raise 'Style not found: %p' % [styles] if $DEBUG and style.empty?
30
+ $stderr.puts 'Style not found: %p' % [styles] if $DEBUG and style.empty?
31
31
  return style
32
32
  end
33
33
 
@@ -32,9 +32,19 @@ module Encoders
32
32
  #end
33
33
 
34
34
  bold_every = options[:bold_every]
35
+ highlight_lines = options[:highlight_lines]
35
36
  bolding =
36
- if bold_every == false
37
+ if bold_every == false && highlight_lines == nil
37
38
  proc { |line| line.to_s }
39
+ elsif highlight_lines.is_a? Enumerable
40
+ highlight_lines = highlight_lines.to_set
41
+ proc do |line|
42
+ if highlight_lines.include? line
43
+ "<strong class=\"highlighted\">#{line}</strong>" # highlighted line numbers in bold
44
+ else
45
+ line.to_s
46
+ end
47
+ end
38
48
  elsif bold_every.is_a? Integer
39
49
  raise ArgumentError, ":bolding can't be 0." if bold_every == 0
40
50
  proc do |line|
@@ -65,7 +75,6 @@ module Encoders
65
75
  # Because even monospace fonts seem to have different heights when bold,
66
76
  # I make the newline bold, both in the code and the line numbers.
67
77
  # FIXME Still not working perfect for Mr. Internet Exploder
68
- # FIXME Firefox struggles with very long codes (> 200 lines)
69
78
  line_numbers = (start ... start + line_count).to_a.map(&bolding).join("\n")
70
79
  line_numbers << "\n" # also for Mr. MS Internet Exploder :-/
71
80
  line_numbers.gsub!(/\n/) { "<tt>\n</tt>" }
@@ -86,6 +86,11 @@ module Encoders
86
86
  Template.wrap! self, template, 'CONTENT'
87
87
  self
88
88
  end
89
+
90
+ def apply_title! title
91
+ self.sub!(/(<title>)(<\/title>)/) { $1 + title + $2 }
92
+ self
93
+ end
89
94
 
90
95
  def wrap! element, *args
91
96
  return self if not element or element == wrapped_in
@@ -100,6 +105,10 @@ module Encoders
100
105
  wrap! :div if wrapped_in? nil
101
106
  raise "Can't wrap %p in %p" % [wrapped_in, element] unless wrapped_in? :div
102
107
  wrap_in! Output.page_template_for_css(@css)
108
+ if args.first.is_a?(Hash) && title = args.first[:title]
109
+ apply_title! title
110
+ end
111
+ self
103
112
  when nil
104
113
  return self
105
114
  else
@@ -177,7 +186,7 @@ module Encoders
177
186
  <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="de">
178
187
  <head>
179
188
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
180
- <title>CodeRay Output</title>
189
+ <title></title>
181
190
  <style type="text/css">
182
191
  <%CSS%>
183
192
  </style>
@@ -0,0 +1,69 @@
1
+ ($:.unshift '../..'; require 'coderay') unless defined? CodeRay
2
+ module CodeRay
3
+ module Encoders
4
+
5
+ # = JSON Encoder
6
+ class JSON < Encoder
7
+
8
+ register_for :json
9
+ FILE_EXTENSION = 'json'
10
+
11
+ protected
12
+ def setup options
13
+ begin
14
+ require 'json'
15
+ rescue LoadError
16
+ require 'rubygems'
17
+ require 'json'
18
+ end
19
+ @out = []
20
+ end
21
+
22
+ def text_token text, kind
23
+ { :type => 'text', :text => text, :kind => kind }
24
+ end
25
+
26
+ def block_token action, kind
27
+ { :type => 'block', :action => action, :kind => kind }
28
+ end
29
+
30
+ def finish options
31
+ @out.to_json
32
+ end
33
+
34
+ end
35
+
36
+ end
37
+ end
38
+
39
+ if $0 == __FILE__
40
+ $VERBOSE = true
41
+ $: << File.join(File.dirname(__FILE__), '..')
42
+ eval DATA.read, nil, $0, __LINE__ + 4
43
+ end
44
+
45
+ __END__
46
+ require 'test/unit'
47
+ $:.delete '.'
48
+ require 'rubygems' if RUBY_VERSION < '1.9'
49
+
50
+ class JSONEncoderTest < Test::Unit::TestCase
51
+
52
+ def test_json_output
53
+ tokens = CodeRay.scan <<-RUBY, :ruby
54
+ puts "Hello world!"
55
+ RUBY
56
+ require 'json'
57
+ assert_equal [
58
+ {"type"=>"text", "text"=>"puts", "kind"=>"ident"},
59
+ {"type"=>"text", "text"=>" ", "kind"=>"space"},
60
+ {"type"=>"block", "action"=>"open", "kind"=>"string"},
61
+ {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"},
62
+ {"type"=>"text", "text"=>"Hello world!", "kind"=>"content"},
63
+ {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"},
64
+ {"type"=>"block", "action"=>"close", "kind"=>"string"},
65
+ {"type"=>"text", "text"=>"\n", "kind"=>"space"}
66
+ ], JSON.load(tokens.json)
67
+ end
68
+
69
+ end