Permalink
Browse files

#309 Improved highlighting of Ruby inside diffs

  • Loading branch information...
1 parent 90f70ee commit d6fe4e777a4f543c8828dbf77e955ab38e6c2803 @korny korny committed Jun 22, 2011
View
@@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>currentDocument</key>
- <string>../lib/coderay/scanners/ruby.rb</string>
+ <string>../lib/coderay/tokens.rb</string>
<key>documents</key>
<array>
<dict>
@@ -17,6 +17,8 @@
<string>../lib</string>
</dict>
<dict>
+ <key>expanded</key>
+ <true/>
<key>name</key>
<string>bin</string>
<key>regexFolderFilter</key>
@@ -109,6 +111,8 @@
<date>2011-05-23T23:35:00Z</date>
</dict>
<dict>
+ <key>expanded</key>
+ <true/>
<key>name</key>
<string>executable</string>
<key>regexFolderFilter</key>
@@ -176,54 +180,116 @@
<key>firstVisibleLine</key>
<integer>3</integer>
</dict>
- <key>../lib/coderay/scanners/ruby.rb</key>
+ <key>../lib/coderay/encoders/html.rb</key>
<dict>
<key>caret</key>
<dict>
<key>column</key>
- <integer>39</integer>
+ <integer>22</integer>
<key>line</key>
- <integer>83</integer>
+ <integer>99</integer>
</dict>
<key>firstVisibleColumn</key>
<integer>0</integer>
<key>firstVisibleLine</key>
- <integer>71</integer>
+ <integer>78</integer>
</dict>
- <key>../lib/coderay/scanners/ruby/patterns.rb</key>
+ <key>../lib/coderay/scanner.rb</key>
<dict>
<key>caret</key>
<dict>
<key>column</key>
- <integer>28</integer>
+ <integer>31</integer>
<key>line</key>
- <integer>28</integer>
+ <integer>204</integer>
</dict>
+ <key>columnSelection</key>
+ <false/>
<key>firstVisibleColumn</key>
<integer>0</integer>
<key>firstVisibleLine</key>
+ <integer>177</integer>
+ <key>selectFrom</key>
+ <dict>
+ <key>column</key>
+ <integer>18</integer>
+ <key>line</key>
+ <integer>204</integer>
+ </dict>
+ <key>selectTo</key>
+ <dict>
+ <key>column</key>
+ <integer>34</integer>
+ <key>line</key>
+ <integer>204</integer>
+ </dict>
+ </dict>
+ <key>../lib/coderay/scanners/diff.rb</key>
+ <dict>
+ <key>caret</key>
+ <dict>
+ <key>column</key>
+ <integer>52</integer>
+ <key>line</key>
+ <integer>110</integer>
+ </dict>
+ <key>columnSelection</key>
+ <false/>
+ <key>firstVisibleColumn</key>
<integer>0</integer>
+ <key>firstVisibleLine</key>
+ <integer>86</integer>
+ <key>selectFrom</key>
+ <dict>
+ <key>column</key>
+ <integer>48</integer>
+ <key>line</key>
+ <integer>110</integer>
+ </dict>
+ <key>selectTo</key>
+ <dict>
+ <key>column</key>
+ <integer>52</integer>
+ <key>line</key>
+ <integer>110</integer>
+ </dict>
</dict>
- <key>../lib/coderay/scanners/scheme.rb</key>
+ <key>../lib/coderay/tokens.rb</key>
<dict>
<key>caret</key>
<dict>
<key>column</key>
- <integer>32</integer>
+ <integer>36</integer>
<key>line</key>
- <integer>21</integer>
+ <integer>244</integer>
</dict>
<key>firstVisibleColumn</key>
<integer>0</integer>
<key>firstVisibleLine</key>
+ <integer>206</integer>
+ </dict>
+ <key>../test/unit/tokens.rb</key>
+ <dict>
+ <key>caret</key>
+ <dict>
+ <key>column</key>
+ <integer>26</integer>
+ <key>line</key>
+ <integer>72</integer>
+ </dict>
+ <key>firstVisibleColumn</key>
<integer>0</integer>
+ <key>firstVisibleLine</key>
+ <integer>63</integer>
</dict>
</dict>
<key>openDocuments</key>
<array>
- <string>../lib/coderay/scanners/scheme.rb</string>
- <string>../lib/coderay/scanners/ruby/patterns.rb</string>
- <string>../lib/coderay/scanners/ruby.rb</string>
+ <string>../lib/coderay/encoders/html.rb</string>
+ <string>../lib/coderay/scanners/diff.rb</string>
+ <string>../lib/coderay/scanner.rb</string>
+ <string>../lib/coderay/tokens.rb</string>
+ <string>../test/unit/tokens.rb</string>
</array>
<key>showFileHierarchyDrawer</key>
<true/>
@@ -96,16 +96,16 @@ class HTML < Encoder
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,
}
@@ -61,6 +61,8 @@ class Scanner < StringScanner
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 @@ def tokenize source = nil, options = {}
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 @@ def reset_instance
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 @@ def raise_inspect msg, tokens, state = 'No state given!', ambit = 30
matched, state, bol?, eos?,
string[pos - ambit, ambit],
string[pos, ambit],
- ]
+ ], backtrace
end
# Shorthand for scan_until(/\z/).
@@ -11,7 +11,7 @@ class Diff < Scanner
DEFAULT_OPTIONS = {
:highlight_code => true,
- :inline_diff => true,
+ :inline_diff => true,
}
protected
@@ -73,7 +73,7 @@ def scan_tokens encoder, options
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 @@ def scan_tokens encoder, options
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
@@ -23,8 +23,9 @@ def setup
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 @@ def scan_tokens encoder, options
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 @@ def scan_tokens encoder, options
# 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
@@ -55,7 +55,7 @@ def initialize kind, interpreted, delim, heredoc = false
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
@@ -141,8 +141,8 @@ class Alpha < Style
.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 }
@@ -223,12 +223,15 @@ def split_into_parts *sizes
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
Oops, something went wrong.

0 comments on commit d6fe4e7

Please sign in to comment.