coderay 1.0.0 → 1.0.0.598.pre

Sign up to get free protection for your applications and to get access to all the features.
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