coderay 0.9.8 → 1.0.0

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