Class | CodeRay::Scanners::Diff |
In: |
lib/coderay/scanners/diff.rb
|
Parent: | Scanner |
Scanner for output of the diff command.
Alias: patch
DEFAULT_OPTIONS | = | { :highlight_code => true, :inline_diff => true, } |
# File lib/coderay/scanners/diff.rb, line 21 21: def scan_tokens encoder, options 22: 23: line_kind = nil 24: state = :initial 25: deleted_lines = 0 26: scanners = Hash.new do |h, lang| 27: h[lang] = Scanners[lang].new '', :keep_tokens => true, :keep_state => true 28: end 29: content_scanner = scanners[:plain] 30: content_scanner_entry_state = nil 31: 32: until eos? 33: 34: if match = scan(/\n/) 35: deleted_lines = 0 unless line_kind == :delete 36: if line_kind 37: encoder.end_line line_kind 38: line_kind = nil 39: end 40: encoder.text_token match, :space 41: next 42: end 43: 44: case state 45: 46: when :initial 47: if match = scan(/--- |\+\+\+ |=+|_+/) 48: encoder.begin_line line_kind = :head 49: encoder.text_token match, :head 50: if match = scan(/.*?(?=$|[\t\n\x00]| \(revision)/) 51: encoder.text_token match, :filename 52: if options[:highlight_code] && match != '/dev/null' 53: file_type = FileType.fetch(match, :text) 54: file_type = :text if file_type == :diff 55: content_scanner = scanners[file_type] 56: content_scanner_entry_state = nil 57: end 58: end 59: next unless match = scan(/.+/) 60: encoder.text_token match, :plain 61: elsif match = scan(/Index: |Property changes on: /) 62: encoder.begin_line line_kind = :head 63: encoder.text_token match, :head 64: next unless match = scan(/.+/) 65: encoder.text_token match, :plain 66: elsif match = scan(/Added: /) 67: encoder.begin_line line_kind = :head 68: encoder.text_token match, :head 69: next unless match = scan(/.+/) 70: encoder.text_token match, :plain 71: state = :added 72: elsif match = scan(/\\ .*/) 73: encoder.text_token match, :comment 74: elsif match = scan(/@@(?>[^@\n]*)@@/) 75: content_scanner.state = :initial unless match?(/\n\+/) 76: content_scanner_entry_state = nil 77: if check(/\n|$/) 78: encoder.begin_line line_kind = :change 79: else 80: encoder.begin_group :change 81: end 82: encoder.text_token match[0,2], :change 83: encoder.text_token match[2...-2], :plain 84: encoder.text_token match[-2,2], :change 85: encoder.end_group :change unless line_kind 86: next unless match = scan(/.+/) 87: if options[:highlight_code] 88: content_scanner.tokenize match, :tokens => encoder 89: else 90: encoder.text_token match, :plain 91: end 92: next 93: elsif match = scan(/\+/) 94: encoder.begin_line line_kind = :insert 95: encoder.text_token match, :insert 96: next unless match = scan(/.+/) 97: if options[:highlight_code] 98: content_scanner.tokenize match, :tokens => encoder 99: else 100: encoder.text_token match, :plain 101: end 102: next 103: elsif match = scan(/-/) 104: deleted_lines += 1 105: encoder.begin_line line_kind = :delete 106: encoder.text_token match, :delete 107: if options[:inline_diff] && deleted_lines == 1 && check(/(?>.*)\n\+(?>.*)$(?!\n\+)/) 108: content_scanner_entry_state = content_scanner.state 109: skip(/(.*)\n\+(.*)$/) 110: head, deletion, insertion, tail = diff self[1], self[2] 111: pre, deleted, post = content_scanner.tokenize [head, deletion, tail], :tokens => Tokens.new 112: encoder.tokens pre 113: unless deleted.empty? 114: encoder.begin_group :eyecatcher 115: encoder.tokens deleted 116: encoder.end_group :eyecatcher 117: end 118: encoder.tokens post 119: encoder.end_line line_kind 120: encoder.text_token "\n", :space 121: encoder.begin_line line_kind = :insert 122: encoder.text_token '+', :insert 123: content_scanner.state = content_scanner_entry_state || :initial 124: pre, inserted, post = content_scanner.tokenize [head, insertion, tail], :tokens => Tokens.new 125: encoder.tokens pre 126: unless inserted.empty? 127: encoder.begin_group :eyecatcher 128: encoder.tokens inserted 129: encoder.end_group :eyecatcher 130: end 131: encoder.tokens post 132: elsif match = scan(/.*/) 133: if options[:highlight_code] 134: if deleted_lines == 1 135: content_scanner_entry_state = content_scanner.state 136: end 137: content_scanner.tokenize match, :tokens => encoder unless match.empty? 138: if !match?(/\n-/) 139: if match?(/\n\+/) 140: content_scanner.state = content_scanner_entry_state || :initial 141: end 142: content_scanner_entry_state = nil 143: end 144: else 145: encoder.text_token match, :plain 146: end 147: end 148: next 149: elsif match = scan(/ .*/) 150: if options[:highlight_code] 151: content_scanner.tokenize match, :tokens => encoder 152: else 153: encoder.text_token match, :plain 154: end 155: next 156: elsif match = scan(/.+/) 157: encoder.begin_line line_kind = :comment 158: encoder.text_token match, :plain 159: else 160: raise_inspect 'else case rached' 161: end 162: 163: when :added 164: if match = scan(/ \+/) 165: encoder.begin_line line_kind = :insert 166: encoder.text_token match, :insert 167: next unless match = scan(/.+/) 168: encoder.text_token match, :plain 169: else 170: state = :initial 171: next 172: end 173: end 174: 175: end 176: 177: encoder.end_line line_kind if line_kind 178: 179: encoder 180: end