8: def scan_tokens tokens, options
9:
10: line_kind = nil
11: state = :initial
12:
13: until eos?
14: kind = match = nil
15:
16: if match = scan(/\n/)
17: if line_kind
18: tokens << [:end_line, line_kind]
19: line_kind = nil
20: end
21: tokens << [match, :space]
22: next
23: end
24:
25: case state
26:
27: when :initial
28: if match = scan(/--- |\+\+\+ |=+|_+/)
29: tokens << [:begin_line, line_kind = :head]
30: tokens << [match, :head]
31: next unless match = scan(/.+/)
32: kind = :plain
33: elsif match = scan(/Index: |Property changes on: /)
34: tokens << [:begin_line, line_kind = :head]
35: tokens << [match, :head]
36: next unless match = scan(/.+/)
37: kind = :plain
38: elsif match = scan(/Added: /)
39: tokens << [:begin_line, line_kind = :head]
40: tokens << [match, :head]
41: next unless match = scan(/.+/)
42: kind = :plain
43: state = :added
44: elsif match = scan(/\\ /)
45: tokens << [:begin_line, line_kind = :change]
46: tokens << [match, :change]
47: next unless match = scan(/.+/)
48: kind = :plain
49: elsif scan(/(@@)((?>[^@\n]*))(@@)/)
50: tokens << [:begin_line, line_kind = :change]
51: tokens << [self[1], :change]
52: tokens << [self[2], :plain]
53: tokens << [self[3], :change]
54: next unless match = scan(/.+/)
55: kind = :plain
56: elsif match = scan(/\+/)
57: tokens << [:begin_line, line_kind = :insert]
58: tokens << [match, :insert]
59: next unless match = scan(/.+/)
60: kind = :plain
61: elsif match = scan(/-/)
62: tokens << [:begin_line, line_kind = :delete]
63: tokens << [match, :delete]
64: next unless match = scan(/.+/)
65: kind = :plain
66: elsif scan(/ .*/)
67: kind = :comment
68: elsif scan(/.+/)
69: tokens << [:begin_line, line_kind = :head]
70: kind = :plain
71: else
72: raise_inspect 'else case rached'
73: end
74:
75: when :added
76: if match = scan(/ \+/)
77: tokens << [:begin_line, line_kind = :insert]
78: tokens << [match, :insert]
79: next unless match = scan(/.+/)
80: kind = :plain
81: else
82: state = :initial
83: next
84: end
85: end
86:
87: match ||= matched
88: if $DEBUG and not kind
89: raise_inspect 'Error token %p in line %d' %
90: [[match, kind], line], tokens
91: end
92: raise_inspect 'Empty token', tokens unless match
93:
94: tokens << [match, kind]
95: end
96:
97: tokens << [:end_line, line_kind] if line_kind
98: tokens
99: end