coderay 0.9.8 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/{lib/README → README_INDEX.rdoc} +10 -21
- data/Rakefile +6 -6
- data/bin/coderay +193 -64
- data/lib/coderay.rb +61 -105
- data/lib/coderay/duo.rb +17 -21
- data/lib/coderay/encoder.rb +100 -112
- data/lib/coderay/encoders/_map.rb +12 -7
- data/lib/coderay/encoders/comment_filter.rb +12 -30
- data/lib/coderay/encoders/count.rb +29 -11
- data/lib/coderay/encoders/debug.rb +32 -20
- data/lib/coderay/encoders/div.rb +13 -9
- data/lib/coderay/encoders/filter.rb +34 -51
- data/lib/coderay/encoders/html.rb +155 -161
- data/lib/coderay/encoders/html/css.rb +4 -9
- data/lib/coderay/encoders/html/numbering.rb +115 -0
- data/lib/coderay/encoders/html/output.rb +22 -70
- data/lib/coderay/encoders/json.rb +59 -45
- data/lib/coderay/encoders/lines_of_code.rb +12 -57
- data/lib/coderay/encoders/null.rb +6 -14
- data/lib/coderay/encoders/page.rb +13 -9
- data/lib/coderay/encoders/span.rb +13 -9
- data/lib/coderay/encoders/statistic.rb +58 -39
- data/lib/coderay/encoders/terminal.rb +179 -0
- data/lib/coderay/encoders/text.rb +31 -17
- data/lib/coderay/encoders/token_kind_filter.rb +111 -0
- data/lib/coderay/encoders/xml.rb +19 -18
- data/lib/coderay/encoders/yaml.rb +37 -9
- data/lib/coderay/for_redcloth.rb +4 -4
- data/lib/coderay/helpers/file_type.rb +127 -246
- data/lib/coderay/helpers/gzip.rb +41 -0
- data/lib/coderay/helpers/plugin.rb +241 -306
- data/lib/coderay/helpers/word_list.rb +65 -126
- data/lib/coderay/scanner.rb +173 -156
- data/lib/coderay/scanners/_map.rb +18 -17
- data/lib/coderay/scanners/c.rb +63 -77
- data/lib/coderay/scanners/clojure.rb +217 -0
- data/lib/coderay/scanners/cpp.rb +71 -84
- data/lib/coderay/scanners/css.rb +103 -120
- data/lib/coderay/scanners/debug.rb +47 -44
- data/lib/coderay/scanners/delphi.rb +70 -76
- data/lib/coderay/scanners/diff.rb +141 -50
- data/lib/coderay/scanners/erb.rb +81 -0
- data/lib/coderay/scanners/groovy.rb +104 -113
- data/lib/coderay/scanners/haml.rb +168 -0
- data/lib/coderay/scanners/html.rb +181 -110
- data/lib/coderay/scanners/java.rb +73 -75
- data/lib/coderay/scanners/java/builtin_types.rb +2 -0
- data/lib/coderay/scanners/java_script.rb +90 -101
- data/lib/coderay/scanners/json.rb +40 -53
- data/lib/coderay/scanners/php.rb +123 -147
- data/lib/coderay/scanners/python.rb +93 -91
- data/lib/coderay/scanners/raydebug.rb +66 -0
- data/lib/coderay/scanners/ruby.rb +343 -326
- data/lib/coderay/scanners/ruby/patterns.rb +40 -106
- data/lib/coderay/scanners/ruby/string_state.rb +71 -0
- data/lib/coderay/scanners/sql.rb +80 -66
- data/lib/coderay/scanners/text.rb +26 -0
- data/lib/coderay/scanners/xml.rb +1 -1
- data/lib/coderay/scanners/yaml.rb +74 -73
- data/lib/coderay/style.rb +10 -7
- data/lib/coderay/styles/_map.rb +3 -3
- data/lib/coderay/styles/alpha.rb +143 -0
- data/lib/coderay/token_kinds.rb +90 -0
- data/lib/coderay/tokens.rb +102 -277
- data/lib/coderay/tokens_proxy.rb +55 -0
- data/lib/coderay/version.rb +3 -0
- data/test/functional/basic.rb +200 -18
- data/test/functional/examples.rb +130 -0
- data/test/functional/for_redcloth.rb +15 -8
- data/test/functional/suite.rb +9 -6
- metadata +103 -123
- data/FOLDERS +0 -53
- data/bin/coderay_stylesheet +0 -4
- data/lib/coderay/encoders/html/numerization.rb +0 -133
- data/lib/coderay/encoders/term.rb +0 -158
- data/lib/coderay/encoders/token_class_filter.rb +0 -84
- data/lib/coderay/helpers/gzip_simple.rb +0 -123
- data/lib/coderay/scanners/nitro_xhtml.rb +0 -136
- data/lib/coderay/scanners/plaintext.rb +0 -20
- data/lib/coderay/scanners/rhtml.rb +0 -78
- data/lib/coderay/scanners/scheme.rb +0 -145
- data/lib/coderay/styles/cycnus.rb +0 -152
- data/lib/coderay/styles/murphy.rb +0 -134
- data/lib/coderay/token_classes.rb +0 -86
- data/test/functional/load_plugin_scanner.rb +0 -11
- data/test/functional/vhdl.rb +0 -126
- 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
|
-
|
10
|
-
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
11
13
|
def setup options
|
12
|
-
|
14
|
+
super
|
15
|
+
|
16
|
+
@count = 0
|
13
17
|
end
|
14
|
-
|
15
|
-
def
|
16
|
-
@
|
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
|
-
|
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
|
-
|
32
|
+
@out << kind.to_s << '(' << text << ')'
|
27
33
|
end
|
28
34
|
end
|
29
|
-
|
30
|
-
def
|
31
|
-
|
35
|
+
|
36
|
+
def begin_group kind
|
37
|
+
@opened << kind
|
38
|
+
@out << kind.to_s << '<'
|
32
39
|
end
|
33
|
-
|
34
|
-
def
|
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
|
-
|
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
|
data/lib/coderay/encoders/div.rb
CHANGED
@@ -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
|
14
|
-
:wrap
|
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
|
-
|
24
|
+
super
|
25
|
+
|
26
|
+
@tokens = options[:tokens] || Tokens.new
|
12
27
|
end
|
13
28
|
|
14
|
-
def
|
15
|
-
|
29
|
+
def finish options
|
30
|
+
output @tokens
|
16
31
|
end
|
17
32
|
|
18
|
-
|
19
|
-
true
|
20
|
-
end
|
33
|
+
public
|
21
34
|
|
22
|
-
def
|
23
|
-
|
35
|
+
def text_token text, kind # :nodoc:
|
36
|
+
@tokens.text_token text, kind
|
24
37
|
end
|
25
38
|
|
26
|
-
def
|
27
|
-
|
39
|
+
def begin_group kind # :nodoc:
|
40
|
+
@tokens.begin_group kind
|
28
41
|
end
|
29
42
|
|
30
|
-
|
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
|
-
|
53
|
-
|
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
|
-
|
61
|
-
|
62
|
-
|
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
|
-
|
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,
|
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
|
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
|
92
|
-
|
93
|
-
:
|
94
|
-
:wrap => nil,
|
97
|
+
|
98
|
+
:css => :class,
|
99
|
+
:style => :alpha,
|
100
|
+
:wrap => nil,
|
95
101
|
:title => 'CodeRay output',
|
96
|
-
|
97
|
-
:line_numbers
|
98
|
-
:
|
99
|
-
:
|
100
|
-
:
|
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
|
-
|
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
|
'&' => '&',
|
113
122
|
'"' => '"',
|
114
123
|
'>' => '>',
|
115
124
|
'<' => '<',
|
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
|
129
|
-
h[kind] =
|
130
|
-
|
131
|
-
|
132
|
-
|
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
|
-
]
|
141
|
-
|
142
|
-
# Generate a hint about the given +
|
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,
|
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
|
-
|
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
|
-
|
156
|
+
kinds.reverse.map { |kind| TOKEN_KIND_TO_INFO[kind] }.join('/')
|
152
157
|
when :debug
|
153
|
-
|
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 = [
|
173
|
+
|
174
|
+
@opened = []
|
175
|
+
@last_opened = nil
|
165
176
|
@css = CSS.new options[:style]
|
166
|
-
|
177
|
+
|
167
178
|
hint = options[:hint]
|
168
|
-
if 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
|
-
@
|
177
|
-
|
178
|
-
|
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
|
-
|
191
|
+
kind = k.first
|
192
|
+
k_dup = k.dup
|
200
193
|
end
|
201
|
-
|
202
|
-
|
203
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
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
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
@
|
287
|
-
|
288
|
-
|
289
|
-
|
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
|
-
|
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
|
-
|
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
|