Skip to content

Commit 916711c

Browse files
committed
Merge branch 'master' into paint-integration
2 parents 0c98047 + 2e4e83b commit 916711c

32 files changed

+575
-306
lines changed

.gitignore

+3-13
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,15 @@
11
.DS_Store
2-
*.gem
3-
*.rbc
4-
.bundle
5-
.config
2+
.*~
63
coverage
7-
InstalledFiles
8-
lib/bundler/man
94
pkg
10-
rdoc
115
spec/reports
12-
test/tmp
13-
test/version_tmp
14-
tmp
156
doc
167
Gemfile.lock
178
.rvmrc
9+
.ruby-gemset
10+
.ruby-version
1811
test/executable/source.rb.html
1912
test/executable/source.rb.json
2013
test/scanners
2114
bench/test.div.html
22-
diff.html
23-
etc/CodeRay.tmproj
24-
*.swp
2515
old-stuff

.travis.yml

+8-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
11
rvm:
22
- 1.8.7
3-
- 1.9.2
3+
- ree
44
- 1.9.3
5+
- 2.0.0
6+
- ruby-head
57
- jruby-18mode
68
- jruby-19mode
9+
- jruby-head
710
- rbx-18mode
811
- rbx-19mode
9-
- ruby-head # test again later: RedCloth not compiling
10-
- jruby-head
11-
- ree
1212
branches:
1313
only:
1414
- master
15+
matrix:
16+
allow_failures:
17+
- rvm: rbx-18mode
18+
- rvm: rbx-19mode
1519
script: "rake test" # test:scanners"

Changes.textile

+10
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,19 @@ p=. _This files lists all changes in the CodeRay library since the 0.9.8 release
44

55
h2. Changes in 1.1
66

7+
* New scanner: Sass [#93]
78
* Diff scanner: Highlight inline changes in multi-line changes [#99]
9+
* JavaScript scanner: Highlight multi-line comments in diff correctly
810
* Remove double-click toggle handler from HTML table output
11+
* Fixes to CSS scanner (floats, pseudoclasses)
12+
* Plugin does not warn about fallback when default is defined
913
* Display line numbers in HTML @:table@ mode even for single-line code (remove special case) [#41, thanks to Ariejan de Vroom]
14+
* Add .xaml file type [#121, thanks to Kozman Bálint]
15+
* @CodeRay::TokenKinds@ should not be frozen [#130, thanks to Gavin Kistner]
16+
* Override Bootstrap's pre word-break setting for line numbers [#102, thanks to lightswitch05]
17+
* Accept keywords as Ruby 1.9 hash keys [#126]
18+
* New token type @:id@ for CSS/Sass [#27]
19+
* CSS scanner uses @:id@ and @:tag@ now [#27]
1020

1121
h2. Changes in 1.0.9
1222

Gemfile

+6-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
source "http://rubygems.org"
1+
source 'https://rubygems.org'
22

33
# Specify your gem's dependencies in coderay.gemspec
44
gemspec
@@ -9,10 +9,10 @@ gem 'paint', '~> 0.8.4'
99
# Include everything needed to run rake, tests, features, etc.
1010
group :development do
1111
gem "bundler", ">= 1.0.0"
12-
gem "rake", "~> 0.9.2"
12+
gem "rake"
1313
gem "RedCloth", RUBY_PLATFORM == 'java' ? ">= 4.2.7" : ">= 4.0.3"
14-
gem "term-ansicolor"
15-
gem "shoulda-context", "~> 1.0.0" if RUBY_VERSION >= '1.8.7'
16-
gem "json" unless RUBY_VERSION >= '1.9.1'
17-
gem "rdoc" if RUBY_VERSION >= '1.8.7'
14+
gem "term-ansicolor", '~> 1.2.2'
15+
gem "shoulda-context", "~> 1.1.2"
16+
gem "json" if RUBY_VERSION < '1.9'
17+
gem "rdoc"
1818
end

README.markdown

+6-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
# CodeRay [![Build Status](https://travis-ci.org/rubychan/coderay.png)](https://travis-ci.org/rubychan/coderay)
1+
# CodeRay
2+
3+
[![Build Status](https://travis-ci.org/rubychan/coderay.png)](https://travis-ci.org/rubychan/coderay)
4+
[![Gem Version](https://badge.fury.io/rb/coderay.png)](http://badge.fury.io/rb/coderay)
5+
[![Dependency Status](https://gemnasium.com/rubychan/coderay.png)](https://gemnasium.com/rubychan/coderay)
26

37
## About
48

@@ -12,7 +16,7 @@ You put your code in, and you get it back colored; Keywords, strings, floats, co
1216

1317
### Dependencies
1418

15-
CodeRay needs Ruby 1.8.7+ or 1.9.2+. It also runs on Rubinius and JRuby.
19+
CodeRay needs Ruby 1.8.7, 1.9.3 or 2.0. It also runs on JRuby.
1620

1721
## Example Usage
1822

bin/coderay

+1-2
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ when 'highlight', nil
125125
end
126126

127127
if output_file
128-
output_format ||= CodeRay::FileType[output_file]
128+
output_format ||= CodeRay::FileType[output_file] || :plain
129129
else
130130
output_format ||= :terminal_256
131131
end
@@ -143,7 +143,6 @@ when 'highlight', nil
143143
if output_file
144144
File.open output_file, 'w'
145145
else
146-
$stdout.sync = true
147146
$stdout
148147
end
149148
CodeRay.encode(input, input_lang, output_format, :out => file)

lib/coderay/encoders/debug.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@ def initialize options = {}
2424
end
2525

2626
def text_token text, kind
27+
raise 'empty token' if $CODERAY_DEBUG && text.empty?
2728
if kind == :space
2829
@out << text
2930
else
3031
# TODO: Escape (
31-
text = text.gsub(/[)\\]/, '\\\\\0') # escape ) and \
32+
text = text.gsub(/[)\\]/, '\\\\\0') if text.index(/[)\\]/)
3233
@out << kind.to_s << '(' << text << ')'
3334
end
3435
end

lib/coderay/encoders/html.rb

+84-83
Original file line numberDiff line numberDiff line change
@@ -126,22 +126,21 @@ class HTML < Encoder
126126

127127
protected
128128

129-
HTML_ESCAPE = { #:nodoc:
130-
'&' => '&amp;',
131-
'"' => '&quot;',
132-
'>' => '&gt;',
133-
'<' => '&lt;',
134-
}
129+
def self.make_html_escape_hash
130+
{
131+
'&' => '&amp;',
132+
'"' => '&quot;',
133+
'>' => '&gt;',
134+
'<' => '&lt;',
135+
# "\t" => will be set to ' ' * options[:tab_width] during setup
136+
}.tap do |hash|
137+
# Escape ASCII control codes except \x9 == \t and \xA == \n.
138+
(Array(0x00..0x8) + Array(0xB..0x1F)).each { |invalid| hash[invalid.chr] = ' ' }
139+
end
140+
end
135141

136-
# This was to prevent illegal HTML.
137-
# Strange chars should still be avoided in codes.
138-
evil_chars = Array(0x00...0x20) - [?\n, ?\t, ?\s]
139-
evil_chars.each { |i| HTML_ESCAPE[i.chr] = ' ' }
140-
#ansi_chars = Array(0x7f..0xff)
141-
#ansi_chars.each { |i| HTML_ESCAPE[i.chr] = '&#%d;' % i }
142-
# \x9 (\t) and \xA (\n) not included
143-
#HTML_ESCAPE_PATTERN = /[\t&"><\0-\x8\xB-\x1f\x7f-\xff]/
144-
HTML_ESCAPE_PATTERN = /[\t"&><\0-\x8\xB-\x1f]/
142+
HTML_ESCAPE = make_html_escape_hash
143+
HTML_ESCAPE_PATTERN = /[\t"&><\0-\x8\xB-\x1F]/
145144

146145
TOKEN_KIND_TO_INFO = Hash.new do |h, kind|
147146
h[kind] = kind.to_s.gsub(/_/, ' ').gsub(/\b\w/) { $&.capitalize }
@@ -172,59 +171,22 @@ def self.token_path_to_hint hint, kinds
172171
def setup options
173172
super
174173

174+
check_options! options
175+
175176
if options[:wrap] || options[:line_numbers]
176177
@real_out = @out
177178
@out = ''
178179
end
179180

180-
options[:break_lines] = true if options[:line_numbers] == :inline
181-
182181
@break_lines = (options[:break_lines] == true)
183182

184-
@HTML_ESCAPE = HTML_ESCAPE.dup
185-
@HTML_ESCAPE["\t"] = ' ' * options[:tab_width]
183+
@HTML_ESCAPE = HTML_ESCAPE.merge("\t" => ' ' * options[:tab_width])
186184

187185
@opened = []
188186
@last_opened = nil
189187
@css = CSS.new options[:style]
190188

191-
hint = options[:hint]
192-
if hint && ![:debug, :info, :info_long].include?(hint)
193-
raise ArgumentError, "Unknown value %p for :hint; \
194-
expected :info, :info_long, :debug, false, or nil." % hint
195-
end
196-
197-
css_classes = TokenKinds
198-
case options[:css]
199-
when :class
200-
@span_for_kind = Hash.new do |h, k|
201-
if k.is_a? ::Symbol
202-
kind = k_dup = k
203-
else
204-
kind = k.first
205-
k_dup = k.dup
206-
end
207-
if kind != :space && (hint || css_class = css_classes[kind])
208-
title = HTML.token_path_to_hint hint, k if hint
209-
css_class ||= css_classes[kind]
210-
h[k_dup] = "<span#{title}#{" class=\"#{css_class}\"" if css_class}>"
211-
else
212-
h[k_dup] = nil
213-
end
214-
end
215-
when :style
216-
@span_for_kind = Hash.new do |h, k|
217-
kind = k.is_a?(Symbol) ? k : k.first
218-
h[k.is_a?(Symbol) ? k : k.dup] =
219-
if kind != :space && (hint || css_classes[kind])
220-
title = HTML.token_path_to_hint hint, k if hint
221-
style = @css.get_style Array(k).map { |c| css_classes[c] }
222-
"<span#{title}#{" style=\"#{style}\"" if style}>"
223-
end
224-
end
225-
else
226-
raise ArgumentError, "Unknown value %p for :css." % options[:css]
227-
end
189+
@span_for_kinds = make_span_for_kinds(options[:css], options[:hint])
228190

229191
@set_last_opened = options[:hint] || options[:css] == :style
230192
end
@@ -255,20 +217,10 @@ def finish options
255217
public
256218

257219
def text_token text, kind
258-
if text =~ /#{HTML_ESCAPE_PATTERN}/o
259-
text = text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| @HTML_ESCAPE[m] }
260-
end
220+
style = @span_for_kinds[@last_opened ? [kind, *@opened] : kind]
261221

262-
style = @span_for_kind[@last_opened ? [kind, *@opened] : kind]
263-
264-
if @break_lines && (i = text.index("\n")) && (c = @opened.size + (style ? 1 : 0)) > 0
265-
close = '</span>' * c
266-
reopen = ''
267-
@opened.each_with_index do |k, index|
268-
reopen << (@span_for_kind[index > 0 ? [k, *@opened[0 ... index ]] : k] || '<span>')
269-
end
270-
text[i .. -1] = text[i .. -1].gsub("\n", "#{close}\n#{reopen}#{style}")
271-
end
222+
text = text.gsub(/#{HTML_ESCAPE_PATTERN}/o) { |m| @HTML_ESCAPE[m] } if text =~ /#{HTML_ESCAPE_PATTERN}/o
223+
text = break_lines(text, style) if @break_lines && (style || @opened.size > 0) && text.index("\n")
272224

273225
if style
274226
@out << style << text << '</span>'
@@ -279,25 +231,19 @@ def text_token text, kind
279231

280232
# token groups, eg. strings
281233
def begin_group kind
282-
@out << (@span_for_kind[@last_opened ? [kind, *@opened] : kind] || '<span>')
234+
@out << (@span_for_kinds[@last_opened ? [kind, *@opened] : kind] || '<span>')
283235
@opened << kind
284236
@last_opened = kind if @set_last_opened
285237
end
286238

287239
def end_group kind
288-
if $CODERAY_DEBUG && (@opened.empty? || @opened.last != kind)
289-
warn 'Malformed token stream: Trying to close a token (%p) ' \
290-
'that is not open. Open are: %p.' % [kind, @opened[1..-1]]
291-
end
292-
if @opened.pop
293-
@out << '</span>'
294-
@last_opened = @opened.last if @last_opened
295-
end
240+
check_group_nesting 'token group', kind if $CODERAY_DEBUG
241+
close_span
296242
end
297243

298244
# whole lines to be highlighted, eg. a deleted line in a diff
299245
def begin_line kind
300-
if style = @span_for_kind[@last_opened ? [kind, *@opened] : kind]
246+
if style = @span_for_kinds[@last_opened ? [kind, *@opened] : kind]
301247
if style['class="']
302248
@out << style.sub('class="', 'class="line ')
303249
else
@@ -311,16 +257,71 @@ def begin_line kind
311257
end
312258

313259
def end_line kind
314-
if $CODERAY_DEBUG && (@opened.empty? || @opened.last != kind)
315-
warn 'Malformed token stream: Trying to close a line (%p) ' \
316-
'that is not open. Open are: %p.' % [kind, @opened[1..-1]]
260+
check_group_nesting 'line', kind if $CODERAY_DEBUG
261+
close_span
262+
end
263+
264+
protected
265+
266+
def check_options! options
267+
unless [false, nil, :debug, :info, :info_long].include? options[:hint]
268+
raise ArgumentError, "Unknown value %p for :hint; expected :info, :info_long, :debug, false, or nil." % [options[:hint]]
269+
end
270+
271+
unless [:class, :style].include? options[:css]
272+
raise ArgumentError, 'Unknown value %p for :css.' % [options[:css]]
273+
end
274+
275+
options[:break_lines] = true if options[:line_numbers] == :inline
276+
end
277+
278+
def css_class_for_kinds kinds
279+
TokenKinds[kinds.is_a?(Symbol) ? kinds : kinds.first]
280+
end
281+
282+
def style_for_kinds kinds
283+
css_classes = kinds.is_a?(Array) ? kinds.map { |c| TokenKinds[c] } : [TokenKinds[kinds]]
284+
@css.get_style_for_css_classes css_classes
285+
end
286+
287+
def make_span_for_kinds method, hint
288+
Hash.new do |h, kinds|
289+
h[kinds.is_a?(Symbol) ? kinds : kinds.dup] = begin
290+
css_class = css_class_for_kinds(kinds)
291+
title = HTML.token_path_to_hint hint, kinds if hint
292+
293+
if css_class || title
294+
if method == :style
295+
style = style_for_kinds(kinds)
296+
"<span#{title}#{" style=\"#{style}\"" if style}>"
297+
else
298+
"<span#{title}#{" class=\"#{css_class}\"" if css_class}>"
299+
end
300+
end
301+
end
302+
end
303+
end
304+
305+
def check_group_nesting name, kind
306+
if @opened.empty? || @opened.last != kind
307+
warn "Malformed token stream: Trying to close a #{name} (%p) that is not open. Open are: %p." % [kind, @opened[1..-1]]
317308
end
309+
end
310+
311+
def break_lines text, style
312+
reopen = ''
313+
@opened.each_with_index do |k, index|
314+
reopen << (@span_for_kinds[index > 0 ? [k, *@opened[0...index]] : k] || '<span>')
315+
end
316+
text.gsub("\n", "#{'</span>' * @opened.size}#{'</span>' if style}\n#{reopen}#{style}")
317+
end
318+
319+
def close_span
318320
if @opened.pop
319321
@out << '</span>'
320322
@last_opened = @opened.last if @last_opened
321323
end
322324
end
323-
324325
end
325326

326327
end

0 commit comments

Comments
 (0)