diff options
author | murphy <murphy@rubychan.de> | 2008-09-30 16:42:53 +0000 |
---|---|---|
committer | murphy <murphy@rubychan.de> | 2008-09-30 16:42:53 +0000 |
commit | a4bd413ca4e835fd3d1fdc24eebce67cd54231ca (patch) | |
tree | 518d0448cec8093f2f2be22a483535fc642de975 /lib/coderay/scanners/diff.rb | |
parent | a1465d8bdf5637893c079d3a266b46b04e40d364 (diff) | |
download | coderay-a4bd413ca4e835fd3d1fdc24eebce67cd54231ca.tar.gz |
New: *Simple Diff Scanner* (closes #22).
* Highlights unified diffs, especially like the ones svn diff outputs.
* Changes to make highlighting of whole lines were necessary.
* I added two example files.
More changes:
* Added token classes :head, :delete, :insert, and :change along with styles.
* Added two new special token types: :begin_line and :end_line. They mark token groups that explicitly span whole lines and should be highlighted as such.
* The HTML encoder converts these new tokens to DIVs. May need more work.
* The Debug Encoder uses square brackets for line tokens.
* Some cleanups.
Diffstat (limited to 'lib/coderay/scanners/diff.rb')
-rw-r--r-- | lib/coderay/scanners/diff.rb | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/lib/coderay/scanners/diff.rb b/lib/coderay/scanners/diff.rb new file mode 100644 index 0000000..d52458c --- /dev/null +++ b/lib/coderay/scanners/diff.rb @@ -0,0 +1,104 @@ +module CodeRay +module Scanners + + class Diff < Scanner + + register_for :diff + + def scan_tokens tokens, options + + line_kind = nil + state = :initial + + until eos? + kind = match = nil + + if match = scan(/\n/) + if line_kind + tokens << [:end_line, line_kind] + line_kind = nil + end + tokens << [match, :space] + next + end + + case state + + when :initial + if match = scan(/--- |\+\+\+ |=+|_+/) + tokens << [:begin_line, line_kind = :head] + tokens << [match, :head] + next unless match = scan(/.+/) + kind = :plain + elsif match = scan(/Index: |Property changes on: /) + tokens << [:begin_line, line_kind = :head] + tokens << [match, :head] + next unless match = scan(/.+/) + kind = :plain + elsif match = scan(/Added: /) + tokens << [:begin_line, line_kind = :head] + tokens << [match, :head] + next unless match = scan(/.+/) + kind = :plain + state = :added + elsif match = scan(/\\ /) + tokens << [:begin_line, line_kind = :change] + 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(/\+/) + tokens << [:begin_line, line_kind = :insert] + tokens << [match, :insert] + next unless match = scan(/.+/) + kind = :plain + elsif match = scan(/-/) + tokens << [:begin_line, line_kind = :delete] + tokens << [match, :delete] + next unless match = scan(/.+/) + kind = :plain + elsif scan(/ .*/) + kind = :comment + elsif scan(/.+/) + tokens << [:begin_line, line_kind = :head] + kind = :plain + else + raise_inspect 'else case rached' + end + + when :added + if match = scan(/ \+/) + tokens << [:begin_line, line_kind = :insert] + tokens << [match, :insert] + next unless match = scan(/.+/) + kind = :plain + else + state = :initial + next + end + end + + match ||= matched + if $DEBUG and not kind + raise_inspect 'Error token %p in line %d' % + [[match, kind], line], tokens + end + raise_inspect 'Empty token', tokens unless match + + tokens << [match, kind] + end + + tokens << [:end_line, line_kind] if line_kind + tokens + end + + end + +end +end |