summaryrefslogtreecommitdiff
path: root/lib/coderay
diff options
context:
space:
mode:
authormurphy <murphy@rubychan.de>2011-06-22 07:22:23 +0000
committermurphy <murphy@rubychan.de>2011-06-22 07:22:23 +0000
commitd6fe4e777a4f543c8828dbf77e955ab38e6c2803 (patch)
tree7f2a155c7645718f8936e649aee05574cd3d1b54 /lib/coderay
parent90f70ee61e87e137aa192c5db97c382e1ec7d24b (diff)
downloadcoderay-d6fe4e777a4f543c8828dbf77e955ab38e6c2803.tar.gz
#309 Improved highlighting of Ruby inside diffs
Diffstat (limited to 'lib/coderay')
-rw-r--r--lib/coderay/encoders/html.rb12
-rw-r--r--lib/coderay/scanner.rb15
-rw-r--r--lib/coderay/scanners/diff.rb32
-rw-r--r--lib/coderay/scanners/ruby.rb15
-rw-r--r--lib/coderay/scanners/ruby/string_state.rb2
-rw-r--r--lib/coderay/styles/alpha.rb4
-rw-r--r--lib/coderay/tokens.rb9
7 files changed, 56 insertions, 33 deletions
diff --git a/lib/coderay/encoders/html.rb b/lib/coderay/encoders/html.rb
index 67d487c..724f3eb 100644
--- a/lib/coderay/encoders/html.rb
+++ b/lib/coderay/encoders/html.rb
@@ -96,16 +96,16 @@ module Encoders
DEFAULT_OPTIONS = {
:tab_width => 8,
- :css => :class,
+ :css => :class,
:style => :alpha,
- :wrap => nil,
+ :wrap => nil,
:title => 'CodeRay output',
- :line_numbers => nil,
+ :line_numbers => nil,
:line_number_anchors => 'n',
- :line_number_start => 1,
- :bold_every => 10,
- :highlight_lines => nil,
+ :line_number_start => 1,
+ :bold_every => 10,
+ :highlight_lines => nil,
:hint => false,
}
diff --git a/lib/coderay/scanner.rb b/lib/coderay/scanner.rb
index 925acf7..ec2b3aa 100644
--- a/lib/coderay/scanner.rb
+++ b/lib/coderay/scanner.rb
@@ -61,6 +61,8 @@ module CodeRay
KINDS_NOT_LOC = [:comment, :doctype, :docstring]
+ attr_accessor :state
+
class << self
# Normalizes the given code into a string with UNIX newlines, in the
@@ -190,7 +192,14 @@ module CodeRay
else
raise ArgumentError, 'expected String, Array, or nil'
end
- scan_tokens @tokens, options
+
+ begin
+ scan_tokens @tokens, options
+ rescue => e
+ message = "Error in %s#scan_tokens, initial state was: %p" % [self.class, defined?(state) && state]
+ raise_inspect e.message, @tokens, message, 30, e.backtrace
+ end
+
@cached_tokens = @tokens
if source.is_a? Array
@tokens.split_into_parts(*source.map { |part| part.size })
@@ -260,7 +269,7 @@ module CodeRay
end
# Scanner error with additional status information
- def raise_inspect msg, tokens, state = 'No state given!', ambit = 30
+ def raise_inspect msg, tokens, state = self.state || 'No state given!', ambit = 30, backtrace = caller
raise ScanError, <<-EOE % [
@@ -288,7 +297,7 @@ surrounding code:
matched, state, bol?, eos?,
string[pos - ambit, ambit],
string[pos, ambit],
- ]
+ ], backtrace
end
# Shorthand for scan_until(/\z/).
diff --git a/lib/coderay/scanners/diff.rb b/lib/coderay/scanners/diff.rb
index a8a63e9..fd12922 100644
--- a/lib/coderay/scanners/diff.rb
+++ b/lib/coderay/scanners/diff.rb
@@ -11,7 +11,7 @@ module Scanners
DEFAULT_OPTIONS = {
:highlight_code => true,
- :inline_diff => true,
+ :inline_diff => true,
}
protected
@@ -73,7 +73,7 @@ module Scanners
next unless match = scan(/.+/)
encoder.text_token match, :plain
elsif match = scan(/@@(?>[^@\n]*)@@/)
- content_scanner.instance_variable_set(:@state, :initial) unless match?(/\n\+/)
+ content_scanner.state = :initial unless match?(/\n\+/)
content_scanner_entry_state = nil
if check(/\n|$/)
encoder.begin_line line_kind = :change
@@ -106,37 +106,39 @@ module Scanners
encoder.begin_line line_kind = :delete
encoder.text_token match, :delete
if options[:inline_diff] && deleted_lines == 1 && check(/(?>.*)\n\+(?>.*)$(?!\n\+)/)
- if content_scanner.instance_variable_defined?(:@state)
- content_scanner_entry_state = content_scanner.instance_variable_get(:@state)
- end
+ content_scanner_entry_state = content_scanner.state
skip(/(.*)\n\+(.*)$/)
head, deletion, insertion, tail = diff self[1], self[2]
pre, deleted, post = content_scanner.tokenize [head, deletion, tail], :tokens => Tokens.new
encoder.tokens pre
- encoder.begin_group :eyecatcher
- encoder.tokens deleted
- encoder.end_group :eyecatcher
+ unless deleted.empty?
+ encoder.begin_group :eyecatcher
+ encoder.tokens deleted
+ encoder.end_group :eyecatcher
+ end
encoder.tokens post
encoder.end_line line_kind
encoder.text_token "\n", :space
encoder.begin_line line_kind = :insert
encoder.text_token '+', :insert
- content_scanner.instance_variable_set(:@state, content_scanner_entry_state || :initial)
+ content_scanner.state = content_scanner_entry_state || :initial
pre, inserted, post = content_scanner.tokenize [head, insertion, tail], :tokens => Tokens.new
encoder.tokens pre
- encoder.begin_group :eyecatcher
- encoder.tokens inserted
- encoder.end_group :eyecatcher
+ unless inserted.empty?
+ encoder.begin_group :eyecatcher
+ encoder.tokens inserted
+ encoder.end_group :eyecatcher
+ end
encoder.tokens post
elsif match = scan(/.*/)
if options[:highlight_code]
- if deleted_lines == 1 && content_scanner.instance_variable_defined?(:@state)
- content_scanner_entry_state = content_scanner.instance_variable_get(:@state)
+ if deleted_lines == 1
+ content_scanner_entry_state = content_scanner.state
end
content_scanner.tokenize match, :tokens => encoder unless match.empty?
if !match?(/\n-/)
if match?(/\n\+/)
- content_scanner.instance_variable_set(:@state, content_scanner_entry_state || :initial)
+ content_scanner.state = content_scanner_entry_state || :initial
end
content_scanner_entry_state = nil
end
diff --git a/lib/coderay/scanners/ruby.rb b/lib/coderay/scanners/ruby.rb
index 299accc..b3c7de1 100644
--- a/lib/coderay/scanners/ruby.rb
+++ b/lib/coderay/scanners/ruby.rb
@@ -23,8 +23,9 @@ module Scanners
end
def scan_tokens encoder, options
+ state, heredocs = @state
+ heredocs = heredocs.dup if heredocs.is_a?(Array)
- state = @state
if state && state.instance_of?(self.class::StringState)
encoder.begin_group state.type
end
@@ -34,10 +35,15 @@ module Scanners
method_call_expected = false
value_expected = true
- heredocs = nil
inline_block_stack = nil
inline_block_curly_depth = 0
+ if heredocs
+ state = heredocs.shift
+ encoder.begin_group state.type
+ heredocs = nil if heredocs.empty?
+ end
+
# def_object_stack = nil
# def_object_paren_depth = 0
@@ -421,11 +427,14 @@ module Scanners
# cleaning up
if options[:keep_state]
- @state = state
+ heredocs = nil if heredocs && heredocs.empty?
+ @state = state, heredocs
end
+
if state.is_a? self.class::StringState
encoder.end_group state.type
end
+
if inline_block_stack
until inline_block_stack.empty?
state, = *inline_block_stack.pop
diff --git a/lib/coderay/scanners/ruby/string_state.rb b/lib/coderay/scanners/ruby/string_state.rb
index 14127c6..2f398d1 100644
--- a/lib/coderay/scanners/ruby/string_state.rb
+++ b/lib/coderay/scanners/ruby/string_state.rb
@@ -55,7 +55,7 @@ module Scanners
def heredoc_pattern delim, interpreted, indented
# delim = delim.dup # workaround for old Ruby
delim_pattern = Regexp.escape(delim)
- delim_pattern = / \n #{ '(?>[ \t]*)' if indented } #{ Regexp.new delim_pattern } $ /x
+ delim_pattern = / (?:\A|\n) #{ '(?>[ \t]*)' if indented } #{ Regexp.new delim_pattern } $ /x
if interpreted
/ (?= #{delim_pattern}() | \\ | \# [{$@] ) /mx # $1 set == end of heredoc
else
diff --git a/lib/coderay/styles/alpha.rb b/lib/coderay/styles/alpha.rb
index 5747abb..6399d7d 100644
--- a/lib/coderay/styles/alpha.rb
+++ b/lib/coderay/styles/alpha.rb
@@ -141,8 +141,8 @@ table.CodeRay td { padding: 2px 4px; vertical-align: top; }
.head { color: #f8f; background: #505 }
.head .filename { color: white; }
-.ins .eye { background-color: hsla(120,100%,50%,0.2) }
-.del .eye { background-color: hsla(0,100%,50%,0.2) }
+.del .eye { background-color: hsla(0,100%,50%,0.2); border: 1px solid hsla(0,100%,45%,0.5); margin: -1px; border-bottom: none; border-top-left-radius: 5px; border-top-right-radius: 5px; }
+.ins .eye { background-color: hsla(120,100%,50%,0.2); border: 1px solid hsla(120,100%,25%,0.5); margin: -1px; border-top: none; border-bottom-left-radius: 5px; border-bottom-right-radius: 5px; }
.ins .ins { color: #080; background:transparent; font-weight:bold }
.del .del { color: #800; background:transparent; font-weight:bold }
diff --git a/lib/coderay/tokens.rb b/lib/coderay/tokens.rb
index e7da7e8..f6f8845 100644
--- a/lib/coderay/tokens.rb
+++ b/lib/coderay/tokens.rb
@@ -223,12 +223,15 @@ module CodeRay
content_or_kind
end
end
- parts << part.concat(closing)
- part = Tokens.new
+ part.concat closing
+ begin
+ parts << part
+ part = Tokens.new
+ size = sizes[i += 1]
+ end until size.nil? || size > 0
# ...and open them again.
part.concat opened.flatten
part_size = 0
- size = sizes[i += 1]
redo unless content.empty?
else
part << content << item