summaryrefslogtreecommitdiff
path: root/lib/coderay/scanners/diff.rb
diff options
context:
space:
mode:
authormurphy <murphy@rubychan.de>2010-03-30 22:24:44 +0000
committermurphy <murphy@rubychan.de>2010-03-30 22:24:44 +0000
commit863839251ac1782d7e6750a2e9b1f6dc324edeb4 (patch)
tree3569b19e59bc86e3e9d9e19619823f342d9c0839 /lib/coderay/scanners/diff.rb
parent262e15cea7a1c32e40c6cb42012a1d8dbca2c88b (diff)
downloadcoderay-863839251ac1782d7e6750a2e9b1f6dc324edeb4.tar.gz
Improved Diff scanner - yay! Finally! Still imperfect, but works (see #52).
Diffstat (limited to 'lib/coderay/scanners/diff.rb')
-rw-r--r--lib/coderay/scanners/diff.rb48
1 files changed, 35 insertions, 13 deletions
diff --git a/lib/coderay/scanners/diff.rb b/lib/coderay/scanners/diff.rb
index bfb400b..6ba50ef 100644
--- a/lib/coderay/scanners/diff.rb
+++ b/lib/coderay/scanners/diff.rb
@@ -1,15 +1,24 @@
module CodeRay
module Scanners
+ # Scanner for output of the diff command.
+ #
+ # Alias: +patch+
class Diff < Scanner
register_for :diff
title 'diff output'
+ protected
+
+ require 'coderay/helpers/file_type'
+
def scan_tokens tokens, options
line_kind = nil
state = :initial
+ # TODO: Cache scanners
+ content_lang = nil
until eos?
kind = match = nil
@@ -29,6 +38,10 @@ module Scanners
if match = scan(/--- |\+\+\+ |=+|_+/)
tokens << [:begin_line, line_kind = :head]
tokens << [match, :head]
+ if filename = scan(/.*?(?=$|[\t\n\x00]| \(revision)/)
+ tokens << [filename, :filename]
+ content_lang = FileType.fetch filename, :plaintext
+ end
next unless match = scan(/.+/)
kind = :plain
elsif match = scan(/Index: |Property changes on: /)
@@ -47,25 +60,34 @@ module Scanners
tokens << [match, :change]
next unless match = scan(/.+/)
kind = :plain
- elsif scan(/(@@)((?>[^@\n]*))(@@)/)
- tokens << [:begin_line, line_kind = :change]
- tokens << [self[1], :change]
- tokens << [self[2], :plain]
- tokens << [self[3], :change]
- next unless match = scan(/.+/)
- kind = :plain
+ elsif match = scan(/@@(?>[^@\n]*)@@/)
+ if check(/\n|$/)
+ tokens << [:begin_line, line_kind = :change]
+ else
+ tokens << [:open, :change]
+ end
+ tokens << [match[0,2], :change]
+ tokens << [match[2...-2], :plain] if match.size > 4
+ tokens << [match[-2,2], :change]
+ tokens << [:close, :change] unless line_kind
+ next unless code = scan(/.+/)
+ CodeRay.scan code, content_lang, :tokens => tokens
+ next
elsif match = scan(/\+/)
tokens << [:begin_line, line_kind = :insert]
tokens << [match, :insert]
next unless match = scan(/.+/)
- kind = :plain
+ CodeRay.scan match, content_lang, :tokens => tokens
+ next
elsif match = scan(/-/)
tokens << [:begin_line, line_kind = :delete]
tokens << [match, :delete]
- next unless match = scan(/.+/)
- kind = :plain
- elsif scan(/ .*/)
- kind = :comment
+ next unless code = scan(/.+/)
+ CodeRay.scan code, content_lang, :tokens => tokens
+ next
+ elsif code = scan(/ .*/)
+ CodeRay.scan code, content_lang, :tokens => tokens
+ next
elsif scan(/.+/)
tokens << [:begin_line, line_kind = :head]
kind = :plain
@@ -86,7 +108,7 @@ module Scanners
end
match ||= matched
- if $DEBUG and not kind
+ if $CODERAY_DEBUG and not kind
raise_inspect 'Error token %p in line %d' %
[[match, kind], line], tokens
end