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