diff options
author | murphy <murphy@rubychan.de> | 2011-06-22 07:22:23 +0000 |
---|---|---|
committer | murphy <murphy@rubychan.de> | 2011-06-22 07:22:23 +0000 |
commit | d6fe4e777a4f543c8828dbf77e955ab38e6c2803 (patch) | |
tree | 7f2a155c7645718f8936e649aee05574cd3d1b54 /lib/coderay | |
parent | 90f70ee61e87e137aa192c5db97c382e1ec7d24b (diff) | |
download | coderay-d6fe4e777a4f543c8828dbf77e955ab38e6c2803.tar.gz |
#309 Improved highlighting of Ruby inside diffs
Diffstat (limited to 'lib/coderay')
-rw-r--r-- | lib/coderay/encoders/html.rb | 12 | ||||
-rw-r--r-- | lib/coderay/scanner.rb | 15 | ||||
-rw-r--r-- | lib/coderay/scanners/diff.rb | 32 | ||||
-rw-r--r-- | lib/coderay/scanners/ruby.rb | 15 | ||||
-rw-r--r-- | lib/coderay/scanners/ruby/string_state.rb | 2 | ||||
-rw-r--r-- | lib/coderay/styles/alpha.rb | 4 | ||||
-rw-r--r-- | lib/coderay/tokens.rb | 9 |
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 |