@@ -22,7 +22,7 @@ def scan_tokens encoder, options
22
22
23
23
line_kind = nil
24
24
state = :initial
25
- deleted_lines = 0
25
+ deleted_lines_count = 0
26
26
scanners = Hash . new do |h , lang |
27
27
h [ lang ] = Scanners [ lang ] . new '' , :keep_tokens => true , :keep_state => true
28
28
end
@@ -32,7 +32,7 @@ def scan_tokens encoder, options
32
32
until eos?
33
33
34
34
if match = scan ( /\n / )
35
- deleted_lines = 0 unless line_kind == :delete
35
+ deleted_lines_count = 0 unless line_kind == :delete
36
36
if line_kind
37
37
encoder . end_line line_kind
38
38
line_kind = nil
@@ -101,37 +101,59 @@ def scan_tokens encoder, options
101
101
end
102
102
next
103
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
104
+ deleted_lines_count += 1
105
+ if options [ :inline_diff ] && deleted_lines_count == 1 && ( changed_lines_count = 1 + check ( /(?>.*(?: \n \- .*)*)/ ) . count ( " \n " ) ) && match? ( /(?>.*(?: \n \- .*){ #{ changed_lines_count - 1 } }(?: \n \+ .*){ #{ changed_lines_count } })$(?! \n \+ )/ )
106
+ deleted_lines = Array . new ( changed_lines_count ) { | i | skip ( / \n \- / ) if i > 0 ; scan ( /.*/ ) }
107
+ inserted_lines = Array . new ( changed_lines_count ) { | i | skip ( / \n \+ / ) ; scan ( /.*/ ) }
108
+
109
+ deleted_lines_tokenized = [ ]
110
+ inserted_lines_tokenized = [ ]
111
+ for deleted_line , inserted_line in deleted_lines . zip ( inserted_lines )
112
+ pre , deleted_part , inserted_part , post = diff deleted_line , inserted_line
113
+ content_scanner_entry_state = content_scanner . state
114
+ deleted_lines_tokenized << content_scanner . tokenize ( [ pre , deleted_part , post ] , :tokens => Tokens . new )
115
+ content_scanner . state = content_scanner_entry_state || :initial
116
+ inserted_lines_tokenized << content_scanner . tokenize ( [ pre , inserted_part , post ] , :tokens => Tokens . new )
117
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
118
+
119
+ for pre , deleted_part , post in deleted_lines_tokenized
120
+ encoder . begin_line :delete
121
+ encoder . text_token '-' , :delete
122
+ encoder . tokens pre
123
+ unless deleted_part . empty?
124
+ encoder . begin_group :eyecatcher
125
+ encoder . tokens deleted_part
126
+ encoder . end_group :eyecatcher
127
+ end
128
+ encoder . tokens post
129
+ encoder . end_line :delete
130
+ encoder . text_token "\n " , :space
131
+ end
132
+
133
+ for pre , inserted_part , post in inserted_lines_tokenized
134
+ encoder . begin_line :insert
135
+ encoder . text_token '+' , :insert
136
+ encoder . tokens pre
137
+ unless inserted_part . empty?
138
+ encoder . begin_group :eyecatcher
139
+ encoder . tokens inserted_part
140
+ encoder . end_group :eyecatcher
141
+ end
142
+ encoder . tokens post
143
+ changed_lines_count -= 1
144
+ if changed_lines_count > 0
145
+ encoder . end_line :insert
146
+ encoder . text_token "\n " , :space
147
+ end
130
148
end
131
- encoder . tokens post
149
+
150
+ line_kind = :insert
151
+
132
152
elsif match = scan ( /.*/ )
153
+ encoder . begin_line line_kind = :delete
154
+ encoder . text_token '-' , :delete
133
155
if options [ :highlight_code ]
134
- if deleted_lines == 1
156
+ if deleted_lines_count == 1
135
157
content_scanner_entry_state = content_scanner . state
136
158
end
137
159
content_scanner . tokenize match , :tokens => encoder unless match . empty?
0 commit comments