coderay 1.0.0 → 1.0.0.598.pre

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 (79) hide show
  1. data/FOLDERS +49 -0
  2. data/Rakefile +6 -5
  3. data/bin/coderay +74 -190
  4. data/bin/coderay_stylesheet +4 -0
  5. data/{README_INDEX.rdoc → lib/README} +20 -10
  6. data/lib/coderay.rb +60 -62
  7. data/lib/coderay/duo.rb +55 -2
  8. data/lib/coderay/encoder.rb +39 -52
  9. data/lib/coderay/encoders/_map.rb +7 -11
  10. data/lib/coderay/encoders/comment_filter.rb +61 -0
  11. data/lib/coderay/encoders/count.rb +26 -11
  12. data/lib/coderay/encoders/debug.rb +60 -11
  13. data/lib/coderay/encoders/div.rb +8 -9
  14. data/lib/coderay/encoders/filter.rb +52 -12
  15. data/lib/coderay/encoders/html.rb +113 -106
  16. data/lib/coderay/encoders/html/css.rb +7 -2
  17. data/lib/coderay/encoders/html/numbering.rb +27 -24
  18. data/lib/coderay/encoders/html/output.rb +58 -15
  19. data/lib/coderay/encoders/json.rb +44 -37
  20. data/lib/coderay/encoders/lines_of_code.rb +56 -9
  21. data/lib/coderay/encoders/null.rb +13 -6
  22. data/lib/coderay/encoders/page.rb +8 -8
  23. data/lib/coderay/encoders/span.rb +9 -10
  24. data/lib/coderay/encoders/statistic.rb +114 -51
  25. data/lib/coderay/encoders/terminal.rb +10 -7
  26. data/lib/coderay/encoders/text.rb +36 -17
  27. data/lib/coderay/encoders/token_kind_filter.rb +58 -1
  28. data/lib/coderay/encoders/xml.rb +11 -13
  29. data/lib/coderay/encoders/yaml.rb +14 -16
  30. data/lib/coderay/for_redcloth.rb +1 -1
  31. data/lib/coderay/helpers/file_type.rb +240 -125
  32. data/lib/coderay/helpers/gzip_simple.rb +123 -0
  33. data/lib/coderay/helpers/plugin.rb +307 -241
  34. data/lib/coderay/helpers/word_list.rb +126 -65
  35. data/lib/coderay/scanner.rb +103 -153
  36. data/lib/coderay/scanners/_map.rb +16 -18
  37. data/lib/coderay/scanners/c.rb +13 -13
  38. data/lib/coderay/scanners/cpp.rb +6 -6
  39. data/lib/coderay/scanners/css.rb +48 -47
  40. data/lib/coderay/scanners/debug.rb +55 -9
  41. data/lib/coderay/scanners/delphi.rb +4 -4
  42. data/lib/coderay/scanners/diff.rb +25 -43
  43. data/lib/coderay/scanners/groovy.rb +2 -2
  44. data/lib/coderay/scanners/html.rb +30 -107
  45. data/lib/coderay/scanners/java.rb +5 -6
  46. data/lib/coderay/scanners/java/builtin_types.rb +0 -2
  47. data/lib/coderay/scanners/java_script.rb +6 -6
  48. data/lib/coderay/scanners/json.rb +6 -7
  49. data/lib/coderay/scanners/nitro_xhtml.rb +136 -0
  50. data/lib/coderay/scanners/php.rb +12 -13
  51. data/lib/coderay/scanners/plaintext.rb +26 -0
  52. data/lib/coderay/scanners/python.rb +4 -4
  53. data/lib/coderay/scanners/{erb.rb → rhtml.rb} +11 -19
  54. data/lib/coderay/scanners/ruby.rb +208 -219
  55. data/lib/coderay/scanners/ruby/patterns.rb +85 -18
  56. data/lib/coderay/scanners/scheme.rb +136 -0
  57. data/lib/coderay/scanners/sql.rb +22 -29
  58. data/lib/coderay/scanners/yaml.rb +10 -11
  59. data/lib/coderay/styles/_map.rb +2 -2
  60. data/lib/coderay/styles/alpha.rb +104 -102
  61. data/lib/coderay/styles/cycnus.rb +143 -0
  62. data/lib/coderay/styles/murphy.rb +123 -0
  63. data/lib/coderay/token_kinds.rb +86 -87
  64. data/lib/coderay/tokens.rb +169 -26
  65. data/test/functional/basic.rb +14 -200
  66. data/test/functional/examples.rb +14 -20
  67. data/test/functional/for_redcloth.rb +8 -15
  68. data/test/functional/load_plugin_scanner.rb +11 -0
  69. data/test/functional/suite.rb +6 -9
  70. data/test/functional/vhdl.rb +126 -0
  71. data/test/functional/word_list.rb +79 -0
  72. metadata +129 -107
  73. data/lib/coderay/helpers/gzip.rb +0 -41
  74. data/lib/coderay/scanners/clojure.rb +0 -217
  75. data/lib/coderay/scanners/haml.rb +0 -168
  76. data/lib/coderay/scanners/ruby/string_state.rb +0 -71
  77. data/lib/coderay/scanners/text.rb +0 -26
  78. data/lib/coderay/tokens_proxy.rb +0 -55
  79. data/lib/coderay/version.rb +0 -3
@@ -20,7 +20,7 @@ module Encoders
20
20
  parse style::TOKEN_COLORS
21
21
  end
22
22
 
23
- def get_style styles
23
+ def [] *styles
24
24
  cl = @classes[styles.first]
25
25
  return '' unless cl
26
26
  style = ''
@@ -44,7 +44,7 @@ module Encoders
44
44
  ( [^\}]+ )? # $2 = style
45
45
  \s* \} \s*
46
46
  |
47
- ( [^\n]+ ) # $3 = error
47
+ ( . ) # $3 = error
48
48
  /mx
49
49
  def parse stylesheet
50
50
  stylesheet.scan CSS_CLASS_PATTERN do |selectors, style, error|
@@ -63,3 +63,8 @@ module Encoders
63
63
 
64
64
  end
65
65
  end
66
+
67
+ if $0 == __FILE__
68
+ require 'pp'
69
+ pp CodeRay::Encoders::HTML::CSS.new
70
+ end
@@ -3,9 +3,9 @@ module Encoders
3
3
 
4
4
  class HTML
5
5
 
6
- module Numbering # :nodoc:
6
+ module Output # :nodoc:
7
7
 
8
- def self.number! output, mode = :table, options = {}
8
+ def number! mode = :table, options = {}
9
9
  return self unless mode
10
10
 
11
11
  options = DEFAULT_OPTIONS.merge options
@@ -26,7 +26,7 @@ module Encoders
26
26
  "<a href=\"##{anchor}\" name=\"#{anchor}\">#{line}</a>"
27
27
  end
28
28
  else
29
- proc { |line| line.to_s } # :to_s.to_proc in Ruby 1.8.7+
29
+ proc { |line| line.to_s }
30
30
  end
31
31
 
32
32
  bold_every = options[:bold_every]
@@ -56,45 +56,37 @@ module Encoders
56
56
  raise ArgumentError, 'Invalid value %p for :bolding; false or Integer expected.' % bold_every
57
57
  end
58
58
 
59
- line_count = output.count("\n")
60
- position_of_last_newline = output.rindex(RUBY_VERSION >= '1.9' ? /\n/ : ?\n)
61
- if position_of_last_newline
62
- after_last_newline = output[position_of_last_newline + 1 .. -1]
63
- ends_with_newline = after_last_newline[/\A(?:<\/span>)*\z/]
64
- line_count += 1 if not ends_with_newline
65
- end
66
-
67
59
  case mode
68
60
  when :inline
69
61
  max_width = (start + line_count).to_s.size
70
62
  line_number = start
71
- nesting = []
72
- output.gsub!(/^.*$\n?/) do |line|
63
+ opened_tags = []
64
+ gsub!(/^.*$\n?/) do |line|
73
65
  line.chomp!
74
- open = nesting.join
66
+ open = opened_tags.join
75
67
  line.scan(%r!<(/)?span[^>]*>?!) do |close,|
76
68
  if close
77
- nesting.pop
69
+ opened_tags.pop
78
70
  else
79
- nesting << $&
71
+ opened_tags << $&
80
72
  end
81
73
  end
82
- close = '</span>' * nesting.size
74
+ close = '</span>' * opened_tags.size
83
75
 
84
76
  line_number_text = bolding.call line_number
85
77
  indent = ' ' * (max_width - line_number.to_s.size) # TODO: Optimize (10^x)
86
78
  line_number += 1
87
- "<span class=\"line-numbers\">#{indent}#{line_number_text}</span>#{open}#{line}#{close}\n"
79
+ "<span class=\"no\">#{indent}#{line_number_text}</span>#{open}#{line}#{close}\n"
88
80
  end
89
81
 
90
82
  when :table
91
- line_numbers = (start ... start + line_count).map(&bolding).join("\n")
83
+ line_numbers = (start ... start + line_count).to_a.map(&bolding).join("\n")
92
84
  line_numbers << "\n"
93
- line_numbers_table_template = Output::TABLE.apply('LINE_NUMBERS', line_numbers)
94
85
 
95
- output.gsub!(/<\/div>\n/, '</div>')
96
- output.wrap_in! line_numbers_table_template
97
- output.wrapped_in = :div
86
+ line_numbers_table_template = TABLE.apply('LINE_NUMBERS', line_numbers)
87
+ gsub!(/<\/div>\n/) { '</div>' }
88
+ wrap_in! line_numbers_table_template
89
+ @wrapped_in = :div
98
90
 
99
91
  when :list
100
92
  raise NotImplementedError, 'The :list option is no longer available. Use :table.'
@@ -104,7 +96,18 @@ module Encoders
104
96
  [mode, [:table, :inline]]
105
97
  end
106
98
 
107
- output
99
+ self
100
+ end
101
+
102
+ def line_count
103
+ line_count = count("\n")
104
+ position_of_last_newline = rindex(?\n)
105
+ if position_of_last_newline
106
+ after_last_newline = self[position_of_last_newline + 1 .. -1]
107
+ ends_with_newline = after_last_newline[/\A(?:<\/span>)*\z/]
108
+ line_count += 1 if not ends_with_newline
109
+ end
110
+ line_count
108
111
  end
109
112
 
110
113
  end
@@ -3,29 +3,42 @@ module Encoders
3
3
 
4
4
  class HTML
5
5
 
6
- # This module is included in the output String of the HTML Encoder.
6
+ # This module is included in the output String from thew HTML Encoder.
7
7
  #
8
8
  # It provides methods like wrap, div, page etc.
9
9
  #
10
10
  # Remember to use #clone instead of #dup to keep the modules the object was
11
11
  # extended with.
12
12
  #
13
- # TODO: Rewrite this without monkey patching.
13
+ # TODO: more doc.
14
14
  module Output
15
15
 
16
16
  attr_accessor :css
17
17
 
18
18
  class << self
19
19
 
20
+ # This makes Output look like a class.
21
+ #
22
+ # Example:
23
+ #
24
+ # a = Output.new '<span class="co">Code</span>'
25
+ # a.wrap! :page
26
+ def new string, css = CSS.new, element = nil
27
+ output = string.clone.extend self
28
+ output.wrapped_in = element
29
+ output.css = css
30
+ output
31
+ end
32
+
20
33
  # Raises an exception if an object that doesn't respond to to_str is extended by Output,
21
34
  # to prevent users from misuse. Use Module#remove_method to disable.
22
- def extended o # :nodoc:
35
+ def extended o
23
36
  warn "The Output module is intended to extend instances of String, not #{o.class}." unless o.respond_to? :to_str
24
37
  end
25
38
 
26
- def make_stylesheet css, in_tag = false # :nodoc:
39
+ def make_stylesheet css, in_tag = false
27
40
  sheet = css.stylesheet
28
- sheet = <<-'CSS' if in_tag
41
+ sheet = <<-CSS if in_tag
29
42
  <style type="text/css">
30
43
  #{sheet}
31
44
  </style>
@@ -33,13 +46,27 @@ module Encoders
33
46
  sheet
34
47
  end
35
48
 
36
- def page_template_for_css css # :nodoc:
49
+ def page_template_for_css css
37
50
  sheet = make_stylesheet css
38
51
  PAGE.apply 'CSS', sheet
39
52
  end
40
53
 
54
+ # Define a new wrapper. This is meta programming.
55
+ def wrapper *wrappers
56
+ wrappers.each do |wrapper|
57
+ define_method wrapper do |*args|
58
+ wrap wrapper, *args
59
+ end
60
+ define_method "#{wrapper}!".to_sym do |*args|
61
+ wrap! wrapper, *args
62
+ end
63
+ end
64
+ end
65
+
41
66
  end
42
67
 
68
+ wrapper :div, :span, :page
69
+
43
70
  def wrapped_in? element
44
71
  wrapped_in == element
45
72
  end
@@ -49,6 +76,10 @@ module Encoders
49
76
  end
50
77
  attr_writer :wrapped_in
51
78
 
79
+ def wrap_in template
80
+ clone.wrap_in! template
81
+ end
82
+
52
83
  def wrap_in! template
53
84
  Template.wrap! self, template, 'CONTENT'
54
85
  self
@@ -85,12 +116,14 @@ module Encoders
85
116
  self
86
117
  end
87
118
 
119
+ def wrap *args
120
+ clone.wrap!(*args)
121
+ end
122
+
88
123
  def stylesheet in_tag = false
89
124
  Output.make_stylesheet @css, in_tag
90
125
  end
91
126
 
92
- #-- don't include the templates in docu
93
-
94
127
  class Template < String # :nodoc:
95
128
 
96
129
  def self.wrap! str, template, target
@@ -112,31 +145,41 @@ module Encoders
112
145
  end
113
146
  end
114
147
 
148
+ module Simple # :nodoc:
149
+ def ` str #` <-- for stupid editors
150
+ Template.new str
151
+ end
152
+ end
115
153
  end
116
154
 
117
- SPAN = Template.new '<span class="CodeRay"><%CONTENT%></span>'
155
+ extend Template::Simple
156
+
157
+ #-- don't include the templates in docu
158
+
159
+ SPAN = `<span class="CodeRay"><%CONTENT%></span>`
118
160
 
119
- DIV = Template.new <<-DIV
161
+ DIV = <<-`DIV`
120
162
  <div class="CodeRay">
121
163
  <div class="code"><pre><%CONTENT%></pre></div>
122
164
  </div>
123
165
  DIV
124
166
 
125
- TABLE = Template.new <<-TABLE
167
+ TABLE = <<-`TABLE`
126
168
  <table class="CodeRay"><tr>
127
- <td class="line-numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><%LINE_NUMBERS%></pre></td>
128
- <td class="code"><pre><%CONTENT%></pre></td>
169
+ <td class="line_numbers" title="double click to toggle" ondblclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><%LINE_NUMBERS%></pre></td>
170
+ <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><%CONTENT%></pre></td>
129
171
  </tr></table>
130
172
  TABLE
173
+ # title="double click to expand"
131
174
 
132
- PAGE = Template.new <<-PAGE
175
+ PAGE = <<-`PAGE`
133
176
  <!DOCTYPE html>
134
177
  <html>
135
178
  <head>
136
179
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
137
180
  <title></title>
138
181
  <style type="text/css">
139
- .CodeRay .line-numbers a {
182
+ .CodeRay .line_numbers a, .CodeRay .no a {
140
183
  text-decoration: inherit;
141
184
  color: inherit;
142
185
  }
@@ -1,3 +1,4 @@
1
+ ($:.unshift '../..'; require 'coderay') unless defined? CodeRay
1
2
  module CodeRay
2
3
  module Encoders
3
4
 
@@ -17,67 +18,73 @@ module Encoders
17
18
  # ]
18
19
  class JSON < Encoder
19
20
 
20
- begin
21
- require 'json'
22
- rescue LoadError
23
- begin
24
- require 'rubygems' unless defined? Gem
25
- gem 'json'
26
- require 'json'
27
- rescue LoadError
28
- $stderr.puts "The JSON encoder needs the JSON library.\n" \
29
- "Please gem install json."
30
- raise
31
- end
32
- end
33
-
34
21
  register_for :json
35
22
  FILE_EXTENSION = 'json'
36
23
 
37
24
  protected
38
25
  def setup options
39
- super
40
-
41
- @first = true
42
- @out << '['
43
- end
44
-
45
- def finish options
46
- @out << ']'
47
- end
48
-
49
- def append data
50
- if @first
51
- @first = false
52
- else
53
- @out << ','
26
+ begin
27
+ require 'json'
28
+ rescue LoadError
29
+ require 'rubygems'
30
+ require 'json'
54
31
  end
55
-
56
- @out << data.to_json
32
+ @out = []
57
33
  end
58
34
 
59
- public
60
35
  def text_token text, kind
61
- append :type => 'text', :text => text, :kind => kind
36
+ @out << { :type => 'text', :text => text, :kind => kind }
62
37
  end
63
38
 
64
39
  def begin_group kind
65
- append :type => 'block', :action => 'open', :kind => kind
40
+ @out << { :type => 'block', :action => 'open', :kind => kind }
66
41
  end
67
42
 
68
43
  def end_group kind
69
- append :type => 'block', :action => 'close', :kind => kind
44
+ @out << { :type => 'block', :action => 'close', :kind => kind }
70
45
  end
71
46
 
72
47
  def begin_line kind
73
- append :type => 'block', :action => 'begin_line', :kind => kind
48
+ @out << { :type => 'block', :action => 'begin_line', :kind => kind }
74
49
  end
75
50
 
76
51
  def end_line kind
77
- append :type => 'block', :action => 'end_line', :kind => kind
52
+ @out << { :type => 'block', :action => 'end_line', :kind => kind }
53
+ end
54
+
55
+ def finish options
56
+ @out.to_json
78
57
  end
79
58
 
80
59
  end
81
60
 
82
61
  end
83
62
  end
63
+
64
+ if $0 == __FILE__
65
+ $VERBOSE = true
66
+ $: << File.join(File.dirname(__FILE__), '..')
67
+ eval DATA.read, nil, $0, __LINE__ + 4
68
+ end
69
+
70
+ __END__
71
+ require 'test/unit'
72
+ $:.delete '.'
73
+ require 'rubygems' if RUBY_VERSION < '1.9'
74
+
75
+ class JSONEncoderTest < Test::Unit::TestCase
76
+
77
+ def test_json_output
78
+ json = CodeRay.scan('puts "Hello world!"', :ruby).json
79
+ assert_equal [
80
+ {"type"=>"text", "text"=>"puts", "kind"=>"ident"},
81
+ {"type"=>"text", "text"=>" ", "kind"=>"space"},
82
+ {"type"=>"block", "action"=>"open", "kind"=>"string"},
83
+ {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"},
84
+ {"type"=>"text", "text"=>"Hello world!", "kind"=>"content"},
85
+ {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"},
86
+ {"type"=>"block", "action"=>"close", "kind"=>"string"},
87
+ ], JSON.load(json)
88
+ end
89
+
90
+ end
@@ -1,3 +1,4 @@
1
+ ($:.unshift '../..'; require 'coderay') unless defined? CodeRay
1
2
  module CodeRay
2
3
  module Encoders
3
4
 
@@ -14,7 +15,7 @@ module Encoders
14
15
  #
15
16
  # A Scanner class should define the token kinds that are not code in the
16
17
  # KINDS_NOT_LOC constant, which defaults to [:comment, :doctype].
17
- class LinesOfCode < TokenKindFilter
18
+ class LinesOfCode < Encoder
18
19
 
19
20
  register_for :lines_of_code
20
21
 
@@ -22,24 +23,70 @@ module Encoders
22
23
 
23
24
  protected
24
25
 
25
- def setup options
26
- if scanner
26
+ def compile tokens, options
27
+ if scanner = tokens.scanner
27
28
  kinds_not_loc = scanner.class::KINDS_NOT_LOC
28
29
  else
29
- warn "Tokens have no associated scanner, counting all nonempty lines." if $VERBOSE
30
+ warn 'Tokens have no scanner.' if $VERBOSE
30
31
  kinds_not_loc = CodeRay::Scanners::Scanner::KINDS_NOT_LOC
31
32
  end
32
-
33
- options[:exclude] = kinds_not_loc
34
-
35
- super options
33
+ code = tokens.token_kind_filter :exclude => kinds_not_loc
34
+ @loc = code.text.scan(NON_EMPTY_LINE).size
36
35
  end
37
36
 
38
37
  def finish options
39
- output @tokens.text.scan(NON_EMPTY_LINE).size
38
+ @loc
40
39
  end
41
40
 
42
41
  end
43
42
 
44
43
  end
45
44
  end
45
+
46
+ if $0 == __FILE__
47
+ $VERBOSE = true
48
+ $: << File.join(File.dirname(__FILE__), '..')
49
+ eval DATA.read, nil, $0, __LINE__ + 4
50
+ end
51
+
52
+ __END__
53
+ require 'test/unit'
54
+
55
+ class LinesOfCodeTest < Test::Unit::TestCase
56
+
57
+ def test_creation
58
+ assert CodeRay::Encoders::LinesOfCode < CodeRay::Encoders::Encoder
59
+ filter = nil
60
+ assert_nothing_raised do
61
+ filter = CodeRay.encoder :loc
62
+ end
63
+ assert_kind_of CodeRay::Encoders::LinesOfCode, filter
64
+ assert_nothing_raised do
65
+ filter = CodeRay.encoder :lines_of_code
66
+ end
67
+ assert_kind_of CodeRay::Encoders::LinesOfCode, filter
68
+ end
69
+
70
+ def test_lines_of_code
71
+ tokens = CodeRay.scan <<-RUBY, :ruby
72
+ #!/usr/bin/env ruby
73
+
74
+ # a minimal Ruby program
75
+ puts "Hello world!"
76
+ RUBY
77
+ assert_equal 1, CodeRay::Encoders::LinesOfCode.new.encode_tokens(tokens)
78
+ assert_equal 1, tokens.lines_of_code
79
+ assert_equal 1, tokens.loc
80
+ end
81
+
82
+ def test_filtering_block_tokens
83
+ tokens = CodeRay::Tokens.new
84
+ tokens.concat ["Hello\n", :world]
85
+ tokens.concat ["Hello\n", :space]
86
+ tokens.concat ["Hello\n", :comment]
87
+ assert_equal 2, CodeRay::Encoders::LinesOfCode.new.encode_tokens(tokens)
88
+ assert_equal 2, tokens.lines_of_code
89
+ assert_equal 2, tokens.loc
90
+ end
91
+
92
+ end