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
@@ -1,17 +1,13 @@
1
1
  module CodeRay
2
2
  module Encoders
3
-
3
+
4
4
  map \
5
- :loc => :lines_of_code,
6
- :plain => :text,
7
- :plaintext => :text,
5
+ :loc => :lines_of_code,
6
+ :term => :terminal,
7
+ :plain => :text,
8
8
  :remove_comments => :comment_filter,
9
- :stats => :statistic,
10
- :term => :terminal,
11
- :tty => :terminal,
12
- :yml => :yaml
13
-
14
- # No default because Tokens#nonsense should raise NoMethodError.
15
-
9
+ :stats => :statistic,
10
+ :tex => :latex
11
+
16
12
  end
17
13
  end
@@ -1,3 +1,4 @@
1
+ ($:.unshift '../..'; require 'coderay') unless defined? CodeRay
1
2
  module CodeRay
2
3
  module Encoders
3
4
 
@@ -23,3 +24,63 @@ module Encoders
23
24
 
24
25
  end
25
26
  end
27
+
28
+ if $0 == __FILE__
29
+ $VERBOSE = true
30
+ $: << File.join(File.dirname(__FILE__), '..')
31
+ eval DATA.read, nil, $0, __LINE__ + 4
32
+ end
33
+
34
+ __END__
35
+ require 'test/unit'
36
+
37
+ class CommentFilterTest < Test::Unit::TestCase
38
+
39
+ def test_filtering_comments
40
+ tokens = CodeRay.scan <<-RUBY, :ruby
41
+ #!/usr/bin/env ruby
42
+ # a minimal Ruby program
43
+ puts "Hello world!"
44
+ RUBY
45
+ assert_equal <<-RUBY_FILTERED, tokens.comment_filter.text
46
+ #!/usr/bin/env ruby
47
+
48
+ puts "Hello world!"
49
+ RUBY_FILTERED
50
+ end
51
+
52
+ def test_filtering_docstrings
53
+ tokens = CodeRay.scan <<-PYTHON, :python
54
+ '''
55
+ Assuming this is file mymodule.py then this string, being the
56
+ first statement in the file will become the mymodule modules
57
+ docstring when the file is imported
58
+ '''
59
+
60
+ class Myclass():
61
+ """
62
+ The class's docstring
63
+ """
64
+
65
+ def mymethod(self):
66
+ '''The method's docstring'''
67
+
68
+ def myfunction():
69
+ """The function's docstring"""
70
+ PYTHON
71
+ assert_equal <<-PYTHON_FILTERED.chomp, tokens.comment_filter.text
72
+
73
+
74
+ class Myclass():
75
+
76
+
77
+ def mymethod(self):
78
+
79
+
80
+ def myfunction():
81
+
82
+
83
+ PYTHON_FILTERED
84
+ end
85
+
86
+ end
@@ -1,3 +1,4 @@
1
+ ($:.unshift '../..'; require 'coderay') unless defined? CodeRay
1
2
  module CodeRay
2
3
  module Encoders
3
4
 
@@ -11,23 +12,15 @@ module Encoders
11
12
  protected
12
13
 
13
14
  def setup options
14
- super
15
-
16
- @count = 0
15
+ @out = 0
17
16
  end
18
17
 
19
- def finish options
20
- output @count
21
- end
22
-
23
- public
24
-
25
18
  def text_token text, kind
26
- @count += 1
19
+ @out += 1
27
20
  end
28
21
 
29
22
  def begin_group kind
30
- @count += 1
23
+ @out += 1
31
24
  end
32
25
  alias end_group begin_group
33
26
  alias begin_line begin_group
@@ -37,3 +30,25 @@ module Encoders
37
30
 
38
31
  end
39
32
  end
33
+
34
+ if $0 == __FILE__
35
+ $VERBOSE = true
36
+ $: << File.join(File.dirname(__FILE__), '..')
37
+ eval DATA.read, nil, $0, __LINE__ + 4
38
+ end
39
+
40
+ __END__
41
+ require 'test/unit'
42
+
43
+ class CountTest < Test::Unit::TestCase
44
+
45
+ def test_count
46
+ tokens = CodeRay.scan <<-RUBY.strip, :ruby
47
+ #!/usr/bin/env ruby
48
+ # a minimal Ruby program
49
+ puts "Hello world!"
50
+ RUBY
51
+ assert_equal 9, tokens.encode_with(:count)
52
+ end
53
+
54
+ end
@@ -1,6 +1,7 @@
1
+ ($:.unshift '../..'; require 'coderay') unless defined? CodeRay
1
2
  module CodeRay
2
3
  module Encoders
3
-
4
+
4
5
  # = Debug Encoder
5
6
  #
6
7
  # Fast encoder producing simple debug output.
@@ -13,31 +14,32 @@ module Encoders
13
14
  #
14
15
  # See also: Scanners::Debug
15
16
  class Debug < Encoder
16
-
17
+
17
18
  register_for :debug
18
-
19
+
19
20
  FILE_EXTENSION = 'raydebug'
20
21
 
21
22
  def initialize options = {}
22
23
  super
23
24
  @opened = []
24
25
  end
25
-
26
+
27
+ public
28
+
26
29
  def text_token text, kind
27
30
  if kind == :space
28
31
  @out << text
29
32
  else
30
- # TODO: Escape (
31
33
  text = text.gsub(/[)\\]/, '\\\\\0') # escape ) and \
32
34
  @out << kind.to_s << '(' << text << ')'
33
35
  end
34
36
  end
35
-
37
+
36
38
  def begin_group kind
37
39
  @opened << kind
38
40
  @out << kind.to_s << '<'
39
41
  end
40
-
42
+
41
43
  def end_group kind
42
44
  if @opened.last != kind
43
45
  puts @out
@@ -46,16 +48,63 @@ module Encoders
46
48
  @opened.pop
47
49
  @out << '>'
48
50
  end
49
-
51
+
50
52
  def begin_line kind
51
53
  @out << kind.to_s << '['
52
54
  end
53
-
55
+
54
56
  def end_line kind
55
57
  @out << ']'
56
58
  end
57
-
59
+
58
60
  end
59
-
61
+
62
+ end
63
+ end
64
+
65
+ if $0 == __FILE__
66
+ $VERBOSE = true
67
+ $: << File.join(File.dirname(__FILE__), '..')
68
+ eval DATA.read, nil, $0, __LINE__ + 4
60
69
  end
70
+
71
+ __END__
72
+ require 'test/unit'
73
+
74
+ class DebugEncoderTest < Test::Unit::TestCase
75
+
76
+ def test_creation
77
+ assert CodeRay::Encoders::Debug < CodeRay::Encoders::Encoder
78
+ debug = nil
79
+ assert_nothing_raised do
80
+ debug = CodeRay.encoder :debug
81
+ end
82
+ assert_kind_of CodeRay::Encoders::Encoder, debug
83
+ end
84
+
85
+ TEST_INPUT = CodeRay::Tokens[
86
+ ['10', :integer],
87
+ ['(\\)', :operator],
88
+ [:begin_group, :string],
89
+ ['test', :content],
90
+ [:end_group, :string],
91
+ [:begin_line, :test],
92
+ ["\n", :space],
93
+ ["\n \t", :space],
94
+ [" \n", :space],
95
+ ["[]", :method],
96
+ [:end_line, :test],
97
+ ].flatten
98
+ TEST_OUTPUT = <<-'DEBUG'.chomp
99
+ integer(10)operator((\\\))string<content(test)>test[
100
+
101
+
102
+ method([])]
103
+ DEBUG
104
+
105
+ def test_filtering_text_tokens
106
+ assert_equal TEST_OUTPUT, CodeRay::Encoders::Debug.new.encode_tokens(TEST_INPUT)
107
+ assert_equal TEST_OUTPUT, TEST_INPUT.debug
108
+ end
109
+
61
110
  end
@@ -1,23 +1,22 @@
1
1
  module CodeRay
2
2
  module Encoders
3
-
3
+
4
4
  load :html
5
5
 
6
6
  # Wraps HTML output into a DIV element, using inline styles by default.
7
7
  #
8
8
  # See Encoders::HTML for available options.
9
9
  class Div < HTML
10
-
10
+
11
11
  FILE_EXTENSION = 'div.html'
12
-
12
+
13
13
  register_for :div
14
-
14
+
15
15
  DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \
16
- :css => :style,
17
- :wrap => :div,
18
- :line_numbers => false
19
-
16
+ :css => :style,
17
+ :wrap => :div
18
+
20
19
  end
21
-
20
+
22
21
  end
23
22
  end
@@ -1,3 +1,4 @@
1
+ ($:.unshift '../..'; require 'coderay') unless defined? CodeRay
1
2
  module CodeRay
2
3
  module Encoders
3
4
 
@@ -21,38 +22,77 @@ module Encoders
21
22
 
22
23
  protected
23
24
  def setup options
24
- super
25
-
26
- @tokens = options[:tokens] || Tokens.new
27
- end
28
-
29
- def finish options
30
- output @tokens
25
+ @out = options[:tokens] || Tokens.new
31
26
  end
32
27
 
33
28
  public
34
29
 
35
30
  def text_token text, kind # :nodoc:
36
- @tokens.text_token text, kind
31
+ @out.text_token text, kind
37
32
  end
38
33
 
39
34
  def begin_group kind # :nodoc:
40
- @tokens.begin_group kind
35
+ @out.begin_group kind
41
36
  end
42
37
 
43
38
  def begin_line kind # :nodoc:
44
- @tokens.begin_line kind
39
+ @out.begin_line kind
45
40
  end
46
41
 
47
42
  def end_group kind # :nodoc:
48
- @tokens.end_group kind
43
+ @out.end_group kind
49
44
  end
50
45
 
51
46
  def end_line kind # :nodoc:
52
- @tokens.end_line kind
47
+ @out.end_line kind
53
48
  end
54
49
 
55
50
  end
56
51
 
57
52
  end
58
53
  end
54
+
55
+ if $0 == __FILE__
56
+ $VERBOSE = true
57
+ $: << File.join(File.dirname(__FILE__), '..')
58
+ eval DATA.read, nil, $0, __LINE__ + 4
59
+ end
60
+
61
+ __END__
62
+ require 'test/unit'
63
+
64
+ class FilterTest < Test::Unit::TestCase
65
+
66
+ def test_creation
67
+ assert CodeRay::Encoders::Filter < CodeRay::Encoders::Encoder
68
+ filter = nil
69
+ assert_nothing_raised do
70
+ filter = CodeRay.encoder :filter
71
+ end
72
+ assert_kind_of CodeRay::Encoders::Encoder, filter
73
+ end
74
+
75
+ def test_filtering_text_tokens
76
+ tokens = CodeRay::Tokens.new
77
+ 10.times do |i|
78
+ tokens.text_token i.to_s, :index
79
+ end
80
+ assert_equal tokens, CodeRay::Encoders::Filter.new.encode_tokens(tokens)
81
+ assert_equal tokens, tokens.filter
82
+ end
83
+
84
+ def test_filtering_block_tokens
85
+ tokens = CodeRay::Tokens.new
86
+ 10.times do |i|
87
+ tokens.begin_group :index
88
+ tokens.text_token i.to_s, :content
89
+ tokens.end_group :index
90
+ tokens.begin_line :index
91
+ tokens.text_token i.to_s, :content
92
+ tokens.end_line :index
93
+ end
94
+ assert_equal tokens, CodeRay::Encoders::Filter.new.encode_tokens(tokens)
95
+ assert_equal tokens, tokens.filter
96
+ end
97
+
98
+ end
@@ -2,7 +2,7 @@ require 'set'
2
2
 
3
3
  module CodeRay
4
4
  module Encoders
5
-
5
+
6
6
  # = HTML Encoder
7
7
  #
8
8
  # This is CodeRay's most important highlighter:
@@ -21,6 +21,7 @@ module Encoders
21
21
  # :line_numbers => :inline,
22
22
  # :css => :style
23
23
  # )
24
+ # #-> <span class="no">1</span> <span style="color:#036; font-weight:bold;">Some</span> code
24
25
  #
25
26
  # == Options
26
27
  #
@@ -87,43 +88,42 @@ module Encoders
87
88
  #
88
89
  # Default: false
89
90
  class HTML < Encoder
90
-
91
+
91
92
  register_for :html
92
-
93
- FILE_EXTENSION = 'snippet.html'
94
-
93
+
94
+ FILE_EXTENSION = 'html'
95
+
95
96
  DEFAULT_OPTIONS = {
96
97
  :tab_width => 8,
97
-
98
- :css => :class,
98
+
99
+ :css => :class,
100
+
99
101
  :style => :alpha,
100
- :wrap => nil,
102
+ :wrap => nil,
101
103
  :title => 'CodeRay output',
102
-
103
- :line_numbers => nil,
104
+
105
+ :line_numbers => nil,
104
106
  :line_number_anchors => 'n',
105
- :line_number_start => 1,
106
- :bold_every => 10,
107
- :highlight_lines => nil,
108
-
107
+ :line_number_start => 1,
108
+ :bold_every => 10,
109
+ :highlight_lines => nil,
110
+
109
111
  :hint => false,
110
112
  }
111
-
112
- autoload :Output, 'coderay/encoders/html/output'
113
- autoload :CSS, 'coderay/encoders/html/css'
114
- autoload :Numbering, 'coderay/encoders/html/numbering'
115
-
113
+
114
+ helper :output, :numbering, :css
115
+
116
116
  attr_reader :css
117
-
117
+
118
118
  protected
119
-
119
+
120
120
  HTML_ESCAPE = { #:nodoc:
121
121
  '&' => '&amp;',
122
122
  '"' => '&quot;',
123
123
  '>' => '&gt;',
124
124
  '<' => '&lt;',
125
125
  }
126
-
126
+
127
127
  # This was to prevent illegal HTML.
128
128
  # Strange chars should still be avoided in codes.
129
129
  evil_chars = Array(0x00...0x20) - [?\n, ?\t, ?\s]
@@ -133,109 +133,110 @@ module Encoders
133
133
  # \x9 (\t) and \xA (\n) not included
134
134
  #HTML_ESCAPE_PATTERN = /[\t&"><\0-\x8\xB-\x1f\x7f-\xff]/
135
135
  HTML_ESCAPE_PATTERN = /[\t"&><\0-\x8\xB-\x1f]/
136
-
136
+
137
137
  TOKEN_KIND_TO_INFO = Hash.new do |h, kind|
138
- h[kind] = kind.to_s.gsub(/_/, ' ').gsub(/\b\w/) { $&.capitalize }
138
+ h[kind] =
139
+ case kind
140
+ when :pre_constant
141
+ 'Predefined constant'
142
+ else
143
+ kind.to_s.gsub(/_/, ' ').gsub(/\b\w/) { $&.capitalize }
144
+ end
139
145
  end
140
-
141
- TRANSPARENT_TOKEN_KINDS = Set[
146
+
147
+ TRANSPARENT_TOKEN_KINDS = [
142
148
  :delimiter, :modifier, :content, :escape, :inline_delimiter,
143
- ]
144
-
149
+ ].to_set
150
+
145
151
  # Generate a hint about the given +kinds+ in a +hint+ style.
146
152
  #
147
153
  # +hint+ may be :info, :info_long or :debug.
148
154
  def self.token_path_to_hint hint, kinds
149
- kinds = Array kinds
155
+ # FIXME: TRANSPARENT_TOKEN_KINDS?
156
+ # if TRANSPARENT_TOKEN_KINDS.include? kinds.first
157
+ # kinds = kinds[1..-1]
158
+ # else
159
+ # kinds = kinds[1..-1] + kinds.first
160
+ # end
150
161
  title =
151
162
  case hint
152
163
  when :info
153
- kinds = kinds[1..-1] if TRANSPARENT_TOKEN_KINDS.include? kinds.first
154
164
  TOKEN_KIND_TO_INFO[kinds.first]
155
165
  when :info_long
156
- kinds.reverse.map { |kind| TOKEN_KIND_TO_INFO[kind] }.join('/')
166
+ kinds.map { |kind| TOKEN_KIND_TO_INFO[kind] }.join('/')
157
167
  when :debug
158
168
  kinds.inspect
159
169
  end
160
170
  title ? " title=\"#{title}\"" : ''
161
171
  end
162
-
172
+
163
173
  def setup options
164
174
  super
165
175
 
166
- if options[:wrap] || options[:line_numbers]
167
- @real_out = @out
168
- @out = ''
169
- end
170
-
171
176
  @HTML_ESCAPE = HTML_ESCAPE.dup
172
177
  @HTML_ESCAPE["\t"] = ' ' * options[:tab_width]
173
178
 
174
- @opened = []
175
- @last_opened = nil
179
+ @opened = [nil]
176
180
  @css = CSS.new options[:style]
177
181
 
178
182
  hint = options[:hint]
179
- if hint && ![:debug, :info, :info_long].include?(hint)
183
+ if hint and not [:debug, :info, :info_long].include? hint
180
184
  raise ArgumentError, "Unknown value %p for :hint; \
181
- expected :info, :info_long, :debug, false, or nil." % hint
185
+ expected :info, :debug, false, or nil." % hint
182
186
  end
183
-
184
- css_classes = TokenKinds
187
+
185
188
  case options[:css]
189
+
186
190
  when :class
187
- @span_for_kind = Hash.new do |h, k|
188
- if k.is_a? ::Symbol
189
- kind = k_dup = k
190
- else
191
- kind = k.first
192
- k_dup = k.dup
193
- end
194
- if kind != :space && (hint || css_class = css_classes[kind])
195
- title = HTML.token_path_to_hint hint, k if hint
196
- css_class ||= css_classes[kind]
197
- h[k_dup] = "<span#{title}#{" class=\"#{css_class}\"" if css_class}>"
198
- else
199
- h[k_dup] = nil
200
- end
191
+ @css_style = Hash.new do |h, k|
192
+ c = Tokens::AbbreviationForKind[k.first]
193
+ h[k.dup] =
194
+ if c != :NO_HIGHLIGHT or (hint && k.first != :space)
195
+ if hint
196
+ title = HTML.token_path_to_hint hint, k
197
+ end
198
+ if c == :NO_HIGHLIGHT
199
+ '<span%s>' % [title]
200
+ else
201
+ '<span%s class="%s">' % [title, c]
202
+ end
203
+ end
201
204
  end
205
+
202
206
  when :style
203
- @span_for_kind = Hash.new do |h, k|
204
- kind = k.is_a?(Symbol) ? k : k.first
205
- h[k.is_a?(Symbol) ? k : k.dup] =
206
- if kind != :space && (hint || css_classes[kind])
207
- title = HTML.token_path_to_hint hint, k if hint
208
- style = @css.get_style Array(k).map { |c| css_classes[c] }
209
- "<span#{title}#{" style=\"#{style}\"" if style}>"
207
+ @css_style = Hash.new do |h, k|
208
+ classes = k.map { |c| Tokens::AbbreviationForKind[c] }
209
+ h[k.dup] =
210
+ if classes.first != :NO_HIGHLIGHT or (hint && k.first != :space)
211
+ if hint
212
+ title = HTML.token_path_to_hint hint, k
213
+ end
214
+ style = @css[*classes]
215
+ if style
216
+ '<span%s style="%s">' % [title, style]
217
+ end
210
218
  end
211
219
  end
220
+
212
221
  else
213
222
  raise ArgumentError, "Unknown value %p for :css." % options[:css]
223
+
214
224
  end
215
-
216
- @set_last_opened = options[:hint] || options[:css] == :style
217
225
  end
218
-
226
+
219
227
  def finish options
228
+ not_needed = @opened.shift
220
229
  unless @opened.empty?
221
- warn '%d tokens still open: %p' % [@opened.size, @opened] if $CODERAY_DEBUG
222
- @out << '</span>' while @opened.pop
223
- @last_opened = nil
230
+ warn '%d tokens still open: %p' % [@opened.size, @opened]
231
+ @out << '</span>' * @opened.size
224
232
  end
225
233
 
226
234
  @out.extend Output
227
235
  @out.css = @css
228
- if options[:line_numbers]
229
- Numbering.number! @out, options[:line_numbers], options
230
- end
236
+ @out.number! options[:line_numbers], options
231
237
  @out.wrap! options[:wrap]
232
238
  @out.apply_title! options[:title]
233
239
 
234
- if defined?(@real_out) && @real_out
235
- @real_out << @out
236
- @out = @real_out
237
- end
238
-
239
240
  super
240
241
  end
241
242
 
@@ -245,58 +246,64 @@ module Encoders
245
246
  if text =~ /#{HTML_ESCAPE_PATTERN}/o
246
247
  text = text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| @HTML_ESCAPE[m] }
247
248
  end
248
- if style = @span_for_kind[@last_opened ? [kind, *@opened] : kind]
249
- @out << style << text << '</span>'
250
- else
251
- @out << text
252
- end
249
+ @opened[0] = kind
250
+ @out <<
251
+ if style = @css_style[@opened]
252
+ style + text + '</span>'
253
+ else
254
+ text
255
+ end
253
256
  end
254
257
 
255
258
  # token groups, eg. strings
256
259
  def begin_group kind
257
- @out << (@span_for_kind[@last_opened ? [kind, *@opened] : kind] || '<span>')
260
+ @opened[0] = kind
258
261
  @opened << kind
259
- @last_opened = kind if @set_last_opened
262
+ @out << (@css_style[@opened] || '<span>')
260
263
  end
261
264
 
262
265
  def end_group kind
263
- if $CODERAY_DEBUG && (@opened.empty? || @opened.last != kind)
266
+ if $CODERAY_DEBUG and (@opened.size == 1 or @opened.last != kind)
264
267
  warn 'Malformed token stream: Trying to close a token (%p) ' \
265
268
  'that is not open. Open are: %p.' % [kind, @opened[1..-1]]
266
269
  end
267
- if @opened.pop
268
- @out << '</span>'
269
- @last_opened = @opened.last if @last_opened
270
- end
270
+ @out <<
271
+ if @opened.empty?
272
+ '' # nothing to close
273
+ else
274
+ @opened.pop
275
+ '</span>'
276
+ end
271
277
  end
272
278
 
273
279
  # whole lines to be highlighted, eg. a deleted line in a diff
274
280
  def begin_line kind
275
- if style = @span_for_kind[@last_opened ? [kind, *@opened] : kind]
276
- if style['class="']
277
- @out << style.sub('class="', 'class="line ')
281
+ @opened[0] = kind
282
+ style = @css_style[@opened]
283
+ @opened << kind
284
+ @out <<
285
+ if style
286
+ style.sub '<span', '<div'
278
287
  else
279
- @out << style.sub('>', ' class="line">')
288
+ '<div>'
280
289
  end
281
- else
282
- @out << '<span class="line">'
283
- end
284
- @opened << kind
285
- @last_opened = kind if @options[:css] == :style
286
290
  end
287
291
 
288
292
  def end_line kind
289
- if $CODERAY_DEBUG && (@opened.empty? || @opened.last != kind)
293
+ if $CODERAY_DEBUG and (@opened.size == 1 or @opened.last != kind)
290
294
  warn 'Malformed token stream: Trying to close a line (%p) ' \
291
295
  'that is not open. Open are: %p.' % [kind, @opened[1..-1]]
292
296
  end
293
- if @opened.pop
294
- @out << '</span>'
295
- @last_opened = @opened.last if @last_opened
296
- end
297
+ @out <<
298
+ if @opened.empty?
299
+ '' # nothing to close
300
+ else
301
+ @opened.pop
302
+ '</div>'
303
+ end
297
304
  end
298
-
305
+
299
306
  end
300
-
307
+
301
308
  end
302
309
  end