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