coderay 0.9.8 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. data/{lib/README → README_INDEX.rdoc} +10 -21
  2. data/Rakefile +6 -6
  3. data/bin/coderay +193 -64
  4. data/lib/coderay.rb +61 -105
  5. data/lib/coderay/duo.rb +17 -21
  6. data/lib/coderay/encoder.rb +100 -112
  7. data/lib/coderay/encoders/_map.rb +12 -7
  8. data/lib/coderay/encoders/comment_filter.rb +12 -30
  9. data/lib/coderay/encoders/count.rb +29 -11
  10. data/lib/coderay/encoders/debug.rb +32 -20
  11. data/lib/coderay/encoders/div.rb +13 -9
  12. data/lib/coderay/encoders/filter.rb +34 -51
  13. data/lib/coderay/encoders/html.rb +155 -161
  14. data/lib/coderay/encoders/html/css.rb +4 -9
  15. data/lib/coderay/encoders/html/numbering.rb +115 -0
  16. data/lib/coderay/encoders/html/output.rb +22 -70
  17. data/lib/coderay/encoders/json.rb +59 -45
  18. data/lib/coderay/encoders/lines_of_code.rb +12 -57
  19. data/lib/coderay/encoders/null.rb +6 -14
  20. data/lib/coderay/encoders/page.rb +13 -9
  21. data/lib/coderay/encoders/span.rb +13 -9
  22. data/lib/coderay/encoders/statistic.rb +58 -39
  23. data/lib/coderay/encoders/terminal.rb +179 -0
  24. data/lib/coderay/encoders/text.rb +31 -17
  25. data/lib/coderay/encoders/token_kind_filter.rb +111 -0
  26. data/lib/coderay/encoders/xml.rb +19 -18
  27. data/lib/coderay/encoders/yaml.rb +37 -9
  28. data/lib/coderay/for_redcloth.rb +4 -4
  29. data/lib/coderay/helpers/file_type.rb +127 -246
  30. data/lib/coderay/helpers/gzip.rb +41 -0
  31. data/lib/coderay/helpers/plugin.rb +241 -306
  32. data/lib/coderay/helpers/word_list.rb +65 -126
  33. data/lib/coderay/scanner.rb +173 -156
  34. data/lib/coderay/scanners/_map.rb +18 -17
  35. data/lib/coderay/scanners/c.rb +63 -77
  36. data/lib/coderay/scanners/clojure.rb +217 -0
  37. data/lib/coderay/scanners/cpp.rb +71 -84
  38. data/lib/coderay/scanners/css.rb +103 -120
  39. data/lib/coderay/scanners/debug.rb +47 -44
  40. data/lib/coderay/scanners/delphi.rb +70 -76
  41. data/lib/coderay/scanners/diff.rb +141 -50
  42. data/lib/coderay/scanners/erb.rb +81 -0
  43. data/lib/coderay/scanners/groovy.rb +104 -113
  44. data/lib/coderay/scanners/haml.rb +168 -0
  45. data/lib/coderay/scanners/html.rb +181 -110
  46. data/lib/coderay/scanners/java.rb +73 -75
  47. data/lib/coderay/scanners/java/builtin_types.rb +2 -0
  48. data/lib/coderay/scanners/java_script.rb +90 -101
  49. data/lib/coderay/scanners/json.rb +40 -53
  50. data/lib/coderay/scanners/php.rb +123 -147
  51. data/lib/coderay/scanners/python.rb +93 -91
  52. data/lib/coderay/scanners/raydebug.rb +66 -0
  53. data/lib/coderay/scanners/ruby.rb +343 -326
  54. data/lib/coderay/scanners/ruby/patterns.rb +40 -106
  55. data/lib/coderay/scanners/ruby/string_state.rb +71 -0
  56. data/lib/coderay/scanners/sql.rb +80 -66
  57. data/lib/coderay/scanners/text.rb +26 -0
  58. data/lib/coderay/scanners/xml.rb +1 -1
  59. data/lib/coderay/scanners/yaml.rb +74 -73
  60. data/lib/coderay/style.rb +10 -7
  61. data/lib/coderay/styles/_map.rb +3 -3
  62. data/lib/coderay/styles/alpha.rb +143 -0
  63. data/lib/coderay/token_kinds.rb +90 -0
  64. data/lib/coderay/tokens.rb +102 -277
  65. data/lib/coderay/tokens_proxy.rb +55 -0
  66. data/lib/coderay/version.rb +3 -0
  67. data/test/functional/basic.rb +200 -18
  68. data/test/functional/examples.rb +130 -0
  69. data/test/functional/for_redcloth.rb +15 -8
  70. data/test/functional/suite.rb +9 -6
  71. metadata +103 -123
  72. data/FOLDERS +0 -53
  73. data/bin/coderay_stylesheet +0 -4
  74. data/lib/coderay/encoders/html/numerization.rb +0 -133
  75. data/lib/coderay/encoders/term.rb +0 -158
  76. data/lib/coderay/encoders/token_class_filter.rb +0 -84
  77. data/lib/coderay/helpers/gzip_simple.rb +0 -123
  78. data/lib/coderay/scanners/nitro_xhtml.rb +0 -136
  79. data/lib/coderay/scanners/plaintext.rb +0 -20
  80. data/lib/coderay/scanners/rhtml.rb +0 -78
  81. data/lib/coderay/scanners/scheme.rb +0 -145
  82. data/lib/coderay/styles/cycnus.rb +0 -152
  83. data/lib/coderay/styles/murphy.rb +0 -134
  84. data/lib/coderay/token_classes.rb +0 -86
  85. data/test/functional/load_plugin_scanner.rb +0 -11
  86. data/test/functional/vhdl.rb +0 -126
  87. data/test/functional/word_list.rb +0 -79
@@ -2,7 +2,7 @@ module CodeRay
2
2
  module Encoders
3
3
 
4
4
  class HTML
5
- class CSS
5
+ class CSS # :nodoc:
6
6
 
7
7
  attr :stylesheet
8
8
 
@@ -20,11 +20,11 @@ module Encoders
20
20
  parse style::TOKEN_COLORS
21
21
  end
22
22
 
23
- def [] *styles
23
+ def get_style styles
24
24
  cl = @classes[styles.first]
25
25
  return '' unless cl
26
26
  style = ''
27
- 1.upto(styles.size) do |offset|
27
+ 1.upto styles.size do |offset|
28
28
  break if style = cl[styles[offset .. -1]]
29
29
  end
30
30
  # warn 'Style not found: %p' % [styles] if style.empty?
@@ -44,7 +44,7 @@ module Encoders
44
44
  ( [^\}]+ )? # $2 = style
45
45
  \s* \} \s*
46
46
  |
47
- ( . ) # $3 = error
47
+ ( [^\n]+ ) # $3 = error
48
48
  /mx
49
49
  def parse stylesheet
50
50
  stylesheet.scan CSS_CLASS_PATTERN do |selectors, style, error|
@@ -63,8 +63,3 @@ 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
@@ -0,0 +1,115 @@
1
+ module CodeRay
2
+ module Encoders
3
+
4
+ class HTML
5
+
6
+ module Numbering # :nodoc:
7
+
8
+ def self.number! output, mode = :table, options = {}
9
+ return self unless mode
10
+
11
+ options = DEFAULT_OPTIONS.merge options
12
+
13
+ start = options[:line_number_start]
14
+ unless start.is_a? Integer
15
+ raise ArgumentError, "Invalid value %p for :line_number_start; Integer expected." % start
16
+ end
17
+
18
+ anchor_prefix = options[:line_number_anchors]
19
+ anchor_prefix = 'line' if anchor_prefix == true
20
+ anchor_prefix = anchor_prefix.to_s[/\w+/] if anchor_prefix
21
+ anchoring =
22
+ if anchor_prefix
23
+ proc do |line|
24
+ line = line.to_s
25
+ anchor = anchor_prefix + line
26
+ "<a href=\"##{anchor}\" name=\"#{anchor}\">#{line}</a>"
27
+ end
28
+ else
29
+ proc { |line| line.to_s } # :to_s.to_proc in Ruby 1.8.7+
30
+ end
31
+
32
+ bold_every = options[:bold_every]
33
+ highlight_lines = options[:highlight_lines]
34
+ bolding =
35
+ if bold_every == false && highlight_lines == nil
36
+ anchoring
37
+ elsif highlight_lines.is_a? Enumerable
38
+ highlight_lines = highlight_lines.to_set
39
+ proc do |line|
40
+ if highlight_lines.include? line
41
+ "<strong class=\"highlighted\">#{anchoring[line]}</strong>" # highlighted line numbers in bold
42
+ else
43
+ anchoring[line]
44
+ end
45
+ end
46
+ elsif bold_every.is_a? Integer
47
+ raise ArgumentError, ":bolding can't be 0." if bold_every == 0
48
+ proc do |line|
49
+ if line % bold_every == 0
50
+ "<strong>#{anchoring[line]}</strong>" # every bold_every-th number in bold
51
+ else
52
+ anchoring[line]
53
+ end
54
+ end
55
+ else
56
+ raise ArgumentError, 'Invalid value %p for :bolding; false or Integer expected.' % bold_every
57
+ end
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
+ case mode
68
+ when :inline
69
+ max_width = (start + line_count).to_s.size
70
+ line_number = start
71
+ nesting = []
72
+ output.gsub!(/^.*$\n?/) do |line|
73
+ line.chomp!
74
+ open = nesting.join
75
+ line.scan(%r!<(/)?span[^>]*>?!) do |close,|
76
+ if close
77
+ nesting.pop
78
+ else
79
+ nesting << $&
80
+ end
81
+ end
82
+ close = '</span>' * nesting.size
83
+
84
+ line_number_text = bolding.call line_number
85
+ indent = ' ' * (max_width - line_number.to_s.size) # TODO: Optimize (10^x)
86
+ line_number += 1
87
+ "<span class=\"line-numbers\">#{indent}#{line_number_text}</span>#{open}#{line}#{close}\n"
88
+ end
89
+
90
+ when :table
91
+ line_numbers = (start ... start + line_count).map(&bolding).join("\n")
92
+ line_numbers << "\n"
93
+ line_numbers_table_template = Output::TABLE.apply('LINE_NUMBERS', line_numbers)
94
+
95
+ output.gsub!(/<\/div>\n/, '</div>')
96
+ output.wrap_in! line_numbers_table_template
97
+ output.wrapped_in = :div
98
+
99
+ when :list
100
+ raise NotImplementedError, 'The :list option is no longer available. Use :table.'
101
+
102
+ else
103
+ raise ArgumentError, 'Unknown value %p for mode: expected one of %p' %
104
+ [mode, [:table, :inline]]
105
+ end
106
+
107
+ output
108
+ end
109
+
110
+ end
111
+
112
+ end
113
+
114
+ end
115
+ end
@@ -3,44 +3,29 @@ module Encoders
3
3
 
4
4
  class HTML
5
5
 
6
- # This module is included in the output String from thew HTML Encoder.
6
+ # This module is included in the output String of the 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: more doc.
13
+ # TODO: Rewrite this without monkey patching.
14
14
  module Output
15
15
 
16
- require 'coderay/encoders/html/numerization.rb'
17
-
18
16
  attr_accessor :css
19
17
 
20
18
  class << self
21
19
 
22
- # This makes Output look like a class.
23
- #
24
- # Example:
25
- #
26
- # a = Output.new '<span class="co">Code</span>'
27
- # a.wrap! :page
28
- def new string, css = CSS.new, element = nil
29
- output = string.clone.extend self
30
- output.wrapped_in = element
31
- output.css = css
32
- output
33
- end
34
-
35
20
  # Raises an exception if an object that doesn't respond to to_str is extended by Output,
36
21
  # to prevent users from misuse. Use Module#remove_method to disable.
37
- def extended o
22
+ def extended o # :nodoc:
38
23
  warn "The Output module is intended to extend instances of String, not #{o.class}." unless o.respond_to? :to_str
39
24
  end
40
25
 
41
- def make_stylesheet css, in_tag = false
26
+ def make_stylesheet css, in_tag = false # :nodoc:
42
27
  sheet = css.stylesheet
43
- sheet = <<-CSS if in_tag
28
+ sheet = <<-'CSS' if in_tag
44
29
  <style type="text/css">
45
30
  #{sheet}
46
31
  </style>
@@ -48,27 +33,13 @@ module Encoders
48
33
  sheet
49
34
  end
50
35
 
51
- def page_template_for_css css
36
+ def page_template_for_css css # :nodoc:
52
37
  sheet = make_stylesheet css
53
38
  PAGE.apply 'CSS', sheet
54
39
  end
55
40
 
56
- # Define a new wrapper. This is meta programming.
57
- def wrapper *wrappers
58
- wrappers.each do |wrapper|
59
- define_method wrapper do |*args|
60
- wrap wrapper, *args
61
- end
62
- define_method "#{wrapper}!".to_sym do |*args|
63
- wrap! wrapper, *args
64
- end
65
- end
66
- end
67
-
68
41
  end
69
42
 
70
- wrapper :div, :span, :page
71
-
72
43
  def wrapped_in? element
73
44
  wrapped_in == element
74
45
  end
@@ -78,10 +49,6 @@ module Encoders
78
49
  end
79
50
  attr_writer :wrapped_in
80
51
 
81
- def wrap_in template
82
- clone.wrap_in! template
83
- end
84
-
85
52
  def wrap_in! template
86
53
  Template.wrap! self, template, 'CONTENT'
87
54
  self
@@ -118,15 +85,13 @@ module Encoders
118
85
  self
119
86
  end
120
87
 
121
- def wrap *args
122
- clone.wrap!(*args)
123
- end
124
-
125
88
  def stylesheet in_tag = false
126
89
  Output.make_stylesheet @css, in_tag
127
90
  end
128
91
 
129
- class Template < String
92
+ #-- don't include the templates in docu
93
+
94
+ class Template < String # :nodoc:
130
95
 
131
96
  def self.wrap! str, template, target
132
97
  target = Regexp.new(Regexp.escape("<%#{target}%>"))
@@ -147,47 +112,34 @@ module Encoders
147
112
  end
148
113
  end
149
114
 
150
- module Simple
151
- def ` str #` <-- for stupid editors
152
- Template.new str
153
- end
154
- end
155
115
  end
156
116
 
157
- extend Template::Simple
117
+ SPAN = Template.new '<span class="CodeRay"><%CONTENT%></span>'
158
118
 
159
- #-- don't include the templates in docu
160
-
161
- SPAN = `<span class="CodeRay"><%CONTENT%></span>`
162
-
163
- DIV = <<-`DIV`
119
+ DIV = Template.new <<-DIV
164
120
  <div class="CodeRay">
165
121
  <div class="code"><pre><%CONTENT%></pre></div>
166
122
  </div>
167
123
  DIV
168
124
 
169
- TABLE = <<-`TABLE`
125
+ TABLE = Template.new <<-TABLE
170
126
  <table class="CodeRay"><tr>
171
- <td class="line_numbers" title="click to toggle" onclick="with (this.firstChild.style) { display = (display == '') ? 'none' : '' }"><pre><%LINE_NUMBERS%></pre></td>
172
- <td class="code"><pre ondblclick="with (this.style) { overflow = (overflow == 'auto' || overflow == '') ? 'visible' : 'auto' }"><%CONTENT%></pre></td>
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>
173
129
  </tr></table>
174
130
  TABLE
175
- # title="double click to expand"
176
-
177
- LIST = <<-`LIST`
178
- <ol class="CodeRay">
179
- <%CONTENT%>
180
- </ol>
181
- LIST
182
131
 
183
- PAGE = <<-`PAGE`
184
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
185
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
186
- <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="de">
132
+ PAGE = Template.new <<-PAGE
133
+ <!DOCTYPE html>
134
+ <html>
187
135
  <head>
188
- <meta http-equiv="content-type" content="text/html; charset=utf-8" />
136
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
189
137
  <title></title>
190
138
  <style type="text/css">
139
+ .CodeRay .line-numbers a {
140
+ text-decoration: inherit;
141
+ color: inherit;
142
+ }
191
143
  <%CSS%>
192
144
  </style>
193
145
  </head>
@@ -1,69 +1,83 @@
1
- ($:.unshift '../..'; require 'coderay') unless defined? CodeRay
2
1
  module CodeRay
3
2
  module Encoders
4
3
 
5
- # = JSON Encoder
4
+ # A simple JSON Encoder.
5
+ #
6
+ # Example:
7
+ # CodeRay.scan('puts "Hello world!"', :ruby).json
8
+ # yields
9
+ # [
10
+ # {"type"=>"text", "text"=>"puts", "kind"=>"ident"},
11
+ # {"type"=>"text", "text"=>" ", "kind"=>"space"},
12
+ # {"type"=>"block", "action"=>"open", "kind"=>"string"},
13
+ # {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"},
14
+ # {"type"=>"text", "text"=>"Hello world!", "kind"=>"content"},
15
+ # {"type"=>"text", "text"=>"\"", "kind"=>"delimiter"},
16
+ # {"type"=>"block", "action"=>"close", "kind"=>"string"},
17
+ # ]
6
18
  class JSON < Encoder
7
19
 
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
+
8
34
  register_for :json
9
35
  FILE_EXTENSION = 'json'
10
36
 
11
37
  protected
12
38
  def setup options
13
- begin
14
- require 'json'
15
- rescue LoadError
16
- require 'rubygems'
17
- require 'json'
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 << ','
18
54
  end
19
- @out = []
55
+
56
+ @out << data.to_json
20
57
  end
21
58
 
59
+ public
22
60
  def text_token text, kind
23
- { :type => 'text', :text => text, :kind => kind }
61
+ append :type => 'text', :text => text, :kind => kind
24
62
  end
25
63
 
26
- def block_token action, kind
27
- { :type => 'block', :action => action, :kind => kind }
64
+ def begin_group kind
65
+ append :type => 'block', :action => 'open', :kind => kind
28
66
  end
29
67
 
30
- def finish options
31
- @out.to_json
68
+ def end_group kind
69
+ append :type => 'block', :action => 'close', :kind => kind
70
+ end
71
+
72
+ def begin_line kind
73
+ append :type => 'block', :action => 'begin_line', :kind => kind
74
+ end
75
+
76
+ def end_line kind
77
+ append :type => 'block', :action => 'end_line', :kind => kind
32
78
  end
33
79
 
34
80
  end
35
81
 
36
82
  end
37
83
  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