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
@@ -1,21 +1,39 @@
1
1
  module CodeRay
2
2
  module Encoders
3
-
3
+
4
+ # Returns the number of tokens.
5
+ #
6
+ # Text and block tokens are counted.
4
7
  class Count < Encoder
5
-
6
- include Streamable
8
+
7
9
  register_for :count
8
-
9
- protected
10
-
10
+
11
+ protected
12
+
11
13
  def setup options
12
- @out = 0
14
+ super
15
+
16
+ @count = 0
13
17
  end
14
-
15
- def token text, kind
16
- @out += 1
18
+
19
+ def finish options
20
+ output @count
17
21
  end
22
+
23
+ public
24
+
25
+ def text_token text, kind
26
+ @count += 1
27
+ end
28
+
29
+ def begin_group kind
30
+ @count += 1
31
+ end
32
+ alias end_group begin_group
33
+ alias begin_line begin_group
34
+ alias end_line begin_group
35
+
18
36
  end
19
-
37
+
20
38
  end
21
39
  end
@@ -1,6 +1,6 @@
1
1
  module CodeRay
2
2
  module Encoders
3
-
3
+
4
4
  # = Debug Encoder
5
5
  #
6
6
  # Fast encoder producing simple debug output.
@@ -10,40 +10,52 @@ module Encoders
10
10
  # You cannot fully restore the tokens information from the
11
11
  # output, because consecutive :space tokens are merged.
12
12
  # Use Tokens#dump for caching purposes.
13
+ #
14
+ # See also: Scanners::Debug
13
15
  class Debug < Encoder
14
-
15
- include Streamable
16
+
16
17
  register_for :debug
17
-
18
+
18
19
  FILE_EXTENSION = 'raydebug'
19
-
20
- protected
20
+
21
+ def initialize options = {}
22
+ super
23
+ @opened = []
24
+ end
25
+
21
26
  def text_token text, kind
22
27
  if kind == :space
23
- text
28
+ @out << text
24
29
  else
30
+ # TODO: Escape (
25
31
  text = text.gsub(/[)\\]/, '\\\\\0') # escape ) and \
26
- "#{kind}(#{text})"
32
+ @out << kind.to_s << '(' << text << ')'
27
33
  end
28
34
  end
29
-
30
- def open_token kind
31
- "#{kind}<"
35
+
36
+ def begin_group kind
37
+ @opened << kind
38
+ @out << kind.to_s << '<'
32
39
  end
33
-
34
- def close_token kind
35
- ">"
40
+
41
+ def end_group kind
42
+ if @opened.last != kind
43
+ puts @out
44
+ raise "we are inside #{@opened.inspect}, not #{kind}"
45
+ end
46
+ @opened.pop
47
+ @out << '>'
36
48
  end
37
-
49
+
38
50
  def begin_line kind
39
- "#{kind}["
51
+ @out << kind.to_s << '['
40
52
  end
41
-
53
+
42
54
  def end_line kind
43
- "]"
55
+ @out << ']'
44
56
  end
45
-
57
+
46
58
  end
47
-
59
+
48
60
  end
49
61
  end
@@ -1,19 +1,23 @@
1
1
  module CodeRay
2
2
  module Encoders
3
-
3
+
4
4
  load :html
5
-
5
+
6
+ # Wraps HTML output into a DIV element, using inline styles by default.
7
+ #
8
+ # See Encoders::HTML for available options.
6
9
  class Div < HTML
7
-
10
+
8
11
  FILE_EXTENSION = 'div.html'
9
-
12
+
10
13
  register_for :div
11
-
14
+
12
15
  DEFAULT_OPTIONS = HTML::DEFAULT_OPTIONS.merge \
13
- :css => :style,
14
- :wrap => :div
15
-
16
+ :css => :style,
17
+ :wrap => :div,
18
+ :line_numbers => false
19
+
16
20
  end
17
-
21
+
18
22
  end
19
23
  end
@@ -1,75 +1,58 @@
1
- ($:.unshift '../..'; require 'coderay') unless defined? CodeRay
2
1
  module CodeRay
3
2
  module Encoders
4
3
 
4
+ # A Filter encoder has another Tokens instance as output.
5
+ # It can be subclass to select, remove, or modify tokens in the stream.
6
+ #
7
+ # Subclasses of Filter are called "Filters" and can be chained.
8
+ #
9
+ # == Options
10
+ #
11
+ # === :tokens
12
+ #
13
+ # The Tokens object which will receive the output.
14
+ #
15
+ # Default: Tokens.new
16
+ #
17
+ # See also: TokenKindFilter
5
18
  class Filter < Encoder
6
19
 
7
20
  register_for :filter
8
21
 
9
22
  protected
10
23
  def setup options
11
- @out = Tokens.new
24
+ super
25
+
26
+ @tokens = options[:tokens] || Tokens.new
12
27
  end
13
28
 
14
- def text_token text, kind
15
- [text, kind] if include_text_token? text, kind
29
+ def finish options
30
+ output @tokens
16
31
  end
17
32
 
18
- def include_text_token? text, kind
19
- true
20
- end
33
+ public
21
34
 
22
- def block_token action, kind
23
- [action, kind] if include_block_token? action, kind
35
+ def text_token text, kind # :nodoc:
36
+ @tokens.text_token text, kind
24
37
  end
25
38
 
26
- def include_block_token? action, kind
27
- true
39
+ def begin_group kind # :nodoc:
40
+ @tokens.begin_group kind
28
41
  end
29
42
 
30
- end
31
-
32
- end
33
- end
34
-
35
- if $0 == __FILE__
36
- $VERBOSE = true
37
- $: << File.join(File.dirname(__FILE__), '..')
38
- eval DATA.read, nil, $0, __LINE__ + 4
39
- end
40
-
41
- __END__
42
- require 'test/unit'
43
-
44
- class FilterTest < Test::Unit::TestCase
45
-
46
- def test_creation
47
- assert CodeRay::Encoders::Filter < CodeRay::Encoders::Encoder
48
- filter = nil
49
- assert_nothing_raised do
50
- filter = CodeRay.encoder :filter
43
+ def begin_line kind # :nodoc:
44
+ @tokens.begin_line kind
51
45
  end
52
- assert_kind_of CodeRay::Encoders::Encoder, filter
53
- end
54
-
55
- def test_filtering_text_tokens
56
- tokens = CodeRay::Tokens.new
57
- 10.times do |i|
58
- tokens << [i.to_s, :index]
46
+
47
+ def end_group kind # :nodoc:
48
+ @tokens.end_group kind
59
49
  end
60
- assert_equal tokens, CodeRay::Encoders::Filter.new.encode_tokens(tokens)
61
- assert_equal tokens, tokens.filter
62
- end
63
-
64
- def test_filtering_block_tokens
65
- tokens = CodeRay::Tokens.new
66
- 10.times do |i|
67
- tokens << [:open, :index]
68
- tokens << [i.to_s, :content]
69
- tokens << [:close, :index]
50
+
51
+ def end_line kind # :nodoc:
52
+ @tokens.end_line kind
70
53
  end
71
- assert_equal tokens, CodeRay::Encoders::Filter.new.encode_tokens(tokens)
72
- assert_equal tokens, tokens.filter
54
+
73
55
  end
74
56
 
75
57
  end
58
+ 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,12 +21,12 @@ 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
25
24
  #
26
25
  # == Options
27
26
  #
28
27
  # === :tab_width
29
28
  # Convert \t characters to +n+ spaces (a number.)
29
+ #
30
30
  # Default: 8
31
31
  #
32
32
  # === :css
@@ -48,10 +48,18 @@ module Encoders
48
48
  # Default: 'CodeRay output'
49
49
  #
50
50
  # === :line_numbers
51
- # Include line numbers in :table, :inline, :list or nil (no line numbers)
51
+ # Include line numbers in :table, :inline, or nil (no line numbers)
52
52
  #
53
53
  # Default: nil
54
54
  #
55
+ # === :line_number_anchors
56
+ # Adds anchors and links to the line numbers. Can be false (off), true (on),
57
+ # or a prefix string that will be prepended to the anchor name.
58
+ #
59
+ # The prefix must consist only of letters, digits, and underscores.
60
+ #
61
+ # Default: true, default prefix name: "line"
62
+ #
55
63
  # === :line_number_start
56
64
  # Where to start with line number counting.
57
65
  #
@@ -74,47 +82,48 @@ module Encoders
74
82
  #
75
83
  # === :hint
76
84
  # Include some information into the output using the title attribute.
77
- # Can be :info (show token type on mouse-over), :info_long (with full path)
85
+ # Can be :info (show token kind on mouse-over), :info_long (with full path)
78
86
  # or :debug (via inspect).
79
87
  #
80
88
  # Default: false
81
89
  class HTML < Encoder
82
-
83
- include Streamable
90
+
84
91
  register_for :html
85
-
86
- FILE_EXTENSION = 'html'
87
-
92
+
93
+ FILE_EXTENSION = 'snippet.html'
94
+
88
95
  DEFAULT_OPTIONS = {
89
96
  :tab_width => 8,
90
-
91
- :css => :class,
92
-
93
- :style => :cycnus,
94
- :wrap => nil,
97
+
98
+ :css => :class,
99
+ :style => :alpha,
100
+ :wrap => nil,
95
101
  :title => 'CodeRay output',
96
-
97
- :line_numbers => nil,
98
- :line_number_start => 1,
99
- :bold_every => 10,
100
- :highlight_lines => nil,
101
-
102
+
103
+ :line_numbers => nil,
104
+ :line_number_anchors => 'n',
105
+ :line_number_start => 1,
106
+ :bold_every => 10,
107
+ :highlight_lines => nil,
108
+
102
109
  :hint => false,
103
110
  }
104
-
105
- helper :output, :css
106
-
111
+
112
+ autoload :Output, 'coderay/encoders/html/output'
113
+ autoload :CSS, 'coderay/encoders/html/css'
114
+ autoload :Numbering, 'coderay/encoders/html/numbering'
115
+
107
116
  attr_reader :css
108
-
117
+
109
118
  protected
110
-
119
+
111
120
  HTML_ESCAPE = { #:nodoc:
112
121
  '&' => '&amp;',
113
122
  '"' => '&quot;',
114
123
  '>' => '&gt;',
115
124
  '<' => '&lt;',
116
125
  }
117
-
126
+
118
127
  # This was to prevent illegal HTML.
119
128
  # Strange chars should still be avoided in codes.
120
129
  evil_chars = Array(0x00...0x20) - [?\n, ?\t, ?\s]
@@ -124,185 +133,170 @@ module Encoders
124
133
  # \x9 (\t) and \xA (\n) not included
125
134
  #HTML_ESCAPE_PATTERN = /[\t&"><\0-\x8\xB-\x1f\x7f-\xff]/
126
135
  HTML_ESCAPE_PATTERN = /[\t"&><\0-\x8\xB-\x1f]/
127
-
128
- TOKEN_KIND_TO_INFO = Hash.new { |h, kind|
129
- h[kind] =
130
- case kind
131
- when :pre_constant
132
- 'Predefined constant'
133
- else
134
- kind.to_s.gsub(/_/, ' ').gsub(/\b\w/) { $&.capitalize }
135
- end
136
- }
137
-
138
- TRANSPARENT_TOKEN_KINDS = [
136
+
137
+ TOKEN_KIND_TO_INFO = Hash.new do |h, kind|
138
+ h[kind] = kind.to_s.gsub(/_/, ' ').gsub(/\b\w/) { $&.capitalize }
139
+ end
140
+
141
+ TRANSPARENT_TOKEN_KINDS = Set[
139
142
  :delimiter, :modifier, :content, :escape, :inline_delimiter,
140
- ].to_set
141
-
142
- # Generate a hint about the given +classes+ in a +hint+ style.
143
+ ]
144
+
145
+ # Generate a hint about the given +kinds+ in a +hint+ style.
143
146
  #
144
147
  # +hint+ may be :info, :info_long or :debug.
145
- def self.token_path_to_hint hint, classes
148
+ def self.token_path_to_hint hint, kinds
149
+ kinds = Array kinds
146
150
  title =
147
151
  case hint
148
152
  when :info
149
- TOKEN_KIND_TO_INFO[classes.first]
153
+ kinds = kinds[1..-1] if TRANSPARENT_TOKEN_KINDS.include? kinds.first
154
+ TOKEN_KIND_TO_INFO[kinds.first]
150
155
  when :info_long
151
- classes.reverse.map { |kind| TOKEN_KIND_TO_INFO[kind] }.join('/')
156
+ kinds.reverse.map { |kind| TOKEN_KIND_TO_INFO[kind] }.join('/')
152
157
  when :debug
153
- classes.inspect
158
+ kinds.inspect
154
159
  end
155
160
  title ? " title=\"#{title}\"" : ''
156
161
  end
157
-
162
+
158
163
  def setup options
159
164
  super
160
-
165
+
166
+ if options[:wrap] || options[:line_numbers]
167
+ @real_out = @out
168
+ @out = ''
169
+ end
170
+
161
171
  @HTML_ESCAPE = HTML_ESCAPE.dup
162
172
  @HTML_ESCAPE["\t"] = ' ' * options[:tab_width]
163
-
164
- @opened = [nil]
173
+
174
+ @opened = []
175
+ @last_opened = nil
165
176
  @css = CSS.new options[:style]
166
-
177
+
167
178
  hint = options[:hint]
168
- if hint and not [:debug, :info, :info_long].include? hint
179
+ if hint && ![:debug, :info, :info_long].include?(hint)
169
180
  raise ArgumentError, "Unknown value %p for :hint; \
170
- expected :info, :debug, false, or nil." % hint
181
+ expected :info, :info_long, :debug, false, or nil." % hint
171
182
  end
172
-
183
+
184
+ css_classes = TokenKinds
173
185
  case options[:css]
174
-
175
186
  when :class
176
- @css_style = Hash.new do |h, k|
177
- c = CodeRay::Tokens::ClassOfKind[k.first]
178
- if c == :NO_HIGHLIGHT and not hint
179
- h[k.dup] = false
180
- else
181
- title = if hint
182
- HTML.token_path_to_hint(hint, k[1..-1] << k.first)
183
- else
184
- ''
185
- end
186
- if c == :NO_HIGHLIGHT
187
- h[k.dup] = '<span%s>' % [title]
188
- else
189
- h[k.dup] = '<span%s class="%s">' % [title, c]
190
- end
191
- end
192
- end
193
-
194
- when :style
195
- @css_style = Hash.new do |h, k|
196
- if k.is_a? ::Array
197
- styles = k.dup
187
+ @span_for_kind = Hash.new do |h, k|
188
+ if k.is_a? ::Symbol
189
+ kind = k_dup = k
198
190
  else
199
- styles = [k]
191
+ kind = k.first
192
+ k_dup = k.dup
200
193
  end
201
- classes = styles.map { |c| Tokens::ClassOfKind[c] }
202
- if classes.first == :NO_HIGHLIGHT and not hint
203
- h[k] = false
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}>"
204
198
  else
205
- styles.shift if TRANSPARENT_TOKEN_KINDS.include? styles.first
206
- title = HTML.token_path_to_hint hint, styles
207
- style = @css[*classes]
208
- h[k] =
209
- if style
210
- '<span%s style="%s">' % [title, style]
211
- else
212
- false
213
- end
199
+ h[k_dup] = nil
214
200
  end
215
201
  end
216
-
202
+ 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}>"
210
+ end
211
+ end
217
212
  else
218
213
  raise ArgumentError, "Unknown value %p for :css." % options[:css]
219
-
220
214
  end
215
+
216
+ @set_last_opened = options[:hint] || options[:css] == :style
221
217
  end
222
-
218
+
223
219
  def finish options
224
- @opened.shift
225
- @out << '</span>' * @opened.size
226
220
  unless @opened.empty?
227
- warn '%d tokens still open: %p' % [@opened.size, @opened]
221
+ warn '%d tokens still open: %p' % [@opened.size, @opened] if $CODERAY_DEBUG
222
+ @out << '</span>' while @opened.pop
223
+ @last_opened = nil
228
224
  end
229
-
225
+
230
226
  @out.extend Output
231
227
  @out.css = @css
232
- @out.numerize! options[:line_numbers], options
228
+ if options[:line_numbers]
229
+ Numbering.number! @out, options[:line_numbers], options
230
+ end
233
231
  @out.wrap! options[:wrap]
234
232
  @out.apply_title! options[:title]
235
-
236
- super
237
- end
238
-
239
- def token text, type = :plain
240
- case text
241
233
 
242
- when nil
243
- # raise 'Token with nil as text was given: %p' % [[text, type]]
244
-
245
- when String
246
- if text =~ /#{HTML_ESCAPE_PATTERN}/o
247
- text = text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| @HTML_ESCAPE[m] }
248
- end
249
- @opened[0] = type
250
- if text != "\n" && style = @css_style[@opened]
251
- @out << style << text << '</span>'
252
- else
253
- @out << text
254
- end
255
-
256
-
257
- # token groups, eg. strings
258
- when :open
259
- @opened[0] = type
260
- @out << (@css_style[@opened] || '<span>')
261
- @opened << type
262
- when :close
263
- if @opened.empty?
264
- # nothing to close
265
- else
266
- if $CODERAY_DEBUG and (@opened.size == 1 or @opened.last != type)
267
- raise 'Malformed token stream: Trying to close a token (%p) \
268
- that is not open. Open are: %p.' % [type, @opened[1..-1]]
269
- end
270
- @out << '</span>'
271
- @opened.pop
272
- end
234
+ if defined?(@real_out) && @real_out
235
+ @real_out << @out
236
+ @out = @real_out
237
+ end
273
238
 
274
- # whole lines to be highlighted, eg. a deleted line in a diff
275
- when :begin_line
276
- @opened[0] = type
277
- if style = @css_style[@opened]
278
- if style['class="']
279
- @out << style.sub('class="', 'class="line ')
280
- else
281
- @out << style.sub('>', ' class="line">')
282
- end
283
- else
284
- @out << '<span class="line">'
285
- end
286
- @opened << type
287
- when :end_line
288
- if @opened.empty?
289
- # nothing to close
239
+ super
240
+ end
241
+
242
+ public
243
+
244
+ def text_token text, kind
245
+ if text =~ /#{HTML_ESCAPE_PATTERN}/o
246
+ text = text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| @HTML_ESCAPE[m] }
247
+ end
248
+ if style = @span_for_kind[@last_opened ? [kind, *@opened] : kind]
249
+ @out << style << text << '</span>'
250
+ else
251
+ @out << text
252
+ end
253
+ end
254
+
255
+ # token groups, eg. strings
256
+ def begin_group kind
257
+ @out << (@span_for_kind[@last_opened ? [kind, *@opened] : kind] || '<span>')
258
+ @opened << kind
259
+ @last_opened = kind if @set_last_opened
260
+ end
261
+
262
+ def end_group kind
263
+ if $CODERAY_DEBUG && (@opened.empty? || @opened.last != kind)
264
+ warn 'Malformed token stream: Trying to close a token (%p) ' \
265
+ 'that is not open. Open are: %p.' % [kind, @opened[1..-1]]
266
+ end
267
+ if @opened.pop
268
+ @out << '</span>'
269
+ @last_opened = @opened.last if @last_opened
270
+ end
271
+ end
272
+
273
+ # whole lines to be highlighted, eg. a deleted line in a diff
274
+ 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 ')
290
278
  else
291
- if $CODERAY_DEBUG and (@opened.size == 1 or @opened.last != type)
292
- raise 'Malformed token stream: Trying to close a line (%p) \
293
- that is not open. Open are: %p.' % [type, @opened[1..-1]]
294
- end
295
- @out << '</span>'
296
- @opened.pop
279
+ @out << style.sub('>', ' class="line">')
297
280
  end
298
-
299
281
  else
300
- raise 'unknown token kind: %p' % [text]
301
-
282
+ @out << '<span class="line">'
302
283
  end
284
+ @opened << kind
285
+ @last_opened = kind if @options[:css] == :style
303
286
  end
304
-
287
+
288
+ def end_line kind
289
+ if $CODERAY_DEBUG && (@opened.empty? || @opened.last != kind)
290
+ warn 'Malformed token stream: Trying to close a line (%p) ' \
291
+ 'that is not open. Open are: %p.' % [kind, @opened[1..-1]]
292
+ end
293
+ if @opened.pop
294
+ @out << '</span>'
295
+ @last_opened = @opened.last if @last_opened
296
+ end
297
+ end
298
+
305
299
  end
306
-
300
+
307
301
  end
308
302
  end