@@ -112,7 +112,7 @@ public function generateSkippedLines(): string
112112
113113 return <<<HTML
114114<tr>
115- <th class=" $ headerClass" title=" { $ this ->lastDeleted } "> $ marker</th>
115+ <th class=" $ headerClass" title=" $ this ->lastDeleted "> $ marker</th>
116116 <td class="Skipped">…</td>
117117</tr>
118118HTML ;
@@ -125,18 +125,19 @@ public function generateSkippedLines(): string
125125 */
126126 public function generateLinesEqual (array $ changes ): string
127127 {
128- $ html = '' ;
129- $ headerClass = '' ;
128+ $ html = '' ;
130129
131130 foreach ($ changes ['base ' ]['lines ' ] as $ lineNo => $ line ) {
132- $ fromLine = $ changes ['base ' ]['offset ' ] + $ lineNo + 1 + $ this ->lineOffset ;
131+ $ fromLine = $ changes ['base ' ]['offset ' ] + $ lineNo + 1 + $ this ->lineOffset ;
132+ $ headerClass = '' ;
133+
133134 if (!$ lineNo && $ this ->lastDeleted !== null ) {
134135 $ headerClass = 'ChangeDelete ' ;
135136 }
136137
137138 $ html .= <<<HTML
138139<tr>
139- <th class=" $ headerClass" title=" { $ this ->lastDeleted } "> $ fromLine</th>
140+ <th class=" $ headerClass" title=" $ this ->lastDeleted "> $ fromLine</th>
140141 <td> $ line</td>
141142</tr>
142143HTML ;
@@ -153,19 +154,19 @@ public function generateLinesEqual(array $changes): string
153154 */
154155 public function generateLinesInsert (array $ changes ): string
155156 {
156- $ html = '' ;
157- $ headerClass = '' ;
157+ $ html = '' ;
158158
159159 foreach ($ changes ['changed ' ]['lines ' ] as $ lineNo => $ line ) {
160160 $ this ->lineOffset ++;
161- $ toLine = $ changes ['base ' ]['offset ' ] + $ this ->lineOffset ;
161+ $ toLine = $ changes ['base ' ]['offset ' ] + $ this ->lineOffset ;
162+ $ headerClass = '' ;
162163 if (!$ lineNo && $ this ->lastDeleted !== null ) {
163164 $ headerClass = 'ChangeDelete ' ;
164165 }
165166
166167 $ html .= <<<HTML
167168<tr>
168- <th class=" $ headerClass" title=" { $ this ->lastDeleted } "> $ toLine</th>
169+ <th class=" $ headerClass" title=" $ this ->lastDeleted "> $ toLine</th>
169170 <td><ins> $ line</ins></td>
170171</tr>
171172HTML ;
@@ -185,7 +186,7 @@ public function generateLinesDelete(array $changes): string
185186 {
186187 $ this ->lineOffset -= count ($ changes ['base ' ]['lines ' ]);
187188
188- $ title = "Lines deleted at {$ this ->options ['title2 ' ]}: \n" ;
189+ $ title = "Lines of { $ this -> options [ ' title1 ' ]} deleted at {$ this ->options ['title2 ' ]}: \n" ;
189190
190191 foreach ($ changes ['base ' ]['lines ' ] as $ lineNo => $ line ) {
191192 $ fromLine = $ changes ['base ' ]['offset ' ] + $ lineNo + 1 ;
@@ -196,7 +197,7 @@ public function generateLinesDelete(array $changes): string
196197TEXT ;
197198 }
198199
199- $ this ->lastDeleted = $ title ;
200+ $ this ->lastDeleted = htmlentities ( $ title) ;
200201
201202 return '' ;
202203 }
@@ -208,41 +209,68 @@ public function generateLinesDelete(array $changes): string
208209 */
209210 public function generateLinesReplace (array $ changes ): string
210211 {
211- $ html = '' ;
212- $ headerClass = '' ;
213-
214- foreach ($ changes ['base ' ]['lines ' ] as $ lineNo => $ line ) {
215- $ fromLine = $ changes ['base ' ]['offset ' ] + $ lineNo + 1 + $ this ->lineOffset ;
216- if (!$ lineNo && $ this ->lastDeleted !== null ) {
217- $ headerClass = 'ChangeDelete ' ;
212+ $ html = '' ;
213+ $ baseLineCount = count ($ changes ['base ' ]['lines ' ]);
214+ $ changedLineCount = count ($ changes ['changed ' ]['lines ' ]);
215+
216+ if (count ($ changes ['base ' ]['lines ' ]) == $ changedLineCount ) {
217+ // Lines of Version 1 are modified at version 2.
218+ foreach ($ changes ['base ' ]['lines ' ] as $ lineNo => $ line ) {
219+ $ fromLine = $ changes ['base ' ]['offset ' ] + $ lineNo + 1 + $ this ->lineOffset ;
220+
221+ // Capture line-parts which are added to the same line at version 2.
222+ $ addedParts = [];
223+ preg_match_all ('/\x0.*?\x1/ ' , $ changes ['changed ' ]['lines ' ][$ lineNo ], $ addedParts , PREG_PATTERN_ORDER );
224+ array_unshift ($ addedParts [0 ], '' );
225+
226+ // Inline Replacement:
227+ // Concatenate line-parts which are removed at version2 with line-parts which are added at version 2.
228+ $ line = preg_replace_callback (
229+ '/\x0.*?\x1/ ' ,
230+ function ($ removedParts ) use ($ addedParts ) {
231+ $ addedPart = str_replace (["\0" , "\1" ], $ this ->options ['insertMarkers ' ], next ($ addedParts [0 ]));
232+ $ removedPart = str_replace (["\0" , "\1" ], $ this ->options ['deleteMarkers ' ], $ removedParts [0 ]);
233+
234+ return "$ removedPart$ addedPart " ;
235+ },
236+ $ line
237+ );
238+
239+ $ html .= <<<HTML
240+ <tr>
241+ <th> $ fromLine</th>
242+ <td> $ line</td>
243+ </tr>
244+ HTML ;
218245 }
219246
220- // Capture added parts.
221- $ addedParts = [];
222- preg_match_all ('/\x0.*?\x1/ ' , $ changes ['changed ' ]['lines ' ][$ lineNo ], $ addedParts , PREG_PATTERN_ORDER );
223- array_unshift ($ addedParts [0 ], '' );
247+ return $ html ;
248+ }
224249
225- // Concatenate removed parts with added parts.
226- $ line = preg_replace_callback (
227- '/\x0.*?\x1/ ' ,
228- function ($ removedParts ) use ($ addedParts ) {
229- $ addedPart = str_replace (["\0" , "\1" ], $ this ->options ['insertMarkers ' ], next ($ addedParts [0 ]));
230- $ removedPart = str_replace (["\0" , "\1" ], $ this ->options ['deleteMarkers ' ], $ removedParts [0 ]);
250+ // More or less lines at version 2. Block of version 1 is replaced by block of version 2.
251+ $ title = '' ;
231252
232- return "$ removedPart$ addedPart " ;
233- },
234- $ line
235- );
253+ foreach ($ changes ['changed ' ]['lines ' ] as $ lineNo => $ line ) {
254+ $ toLine = $ changes ['changed ' ]['offset ' ] + $ lineNo + 1 ;
236255
237- $ html .= <<<HTML
256+ if (!$ lineNo ) {
257+ $ title = "Lines replaced at {$ this ->options ['title1 ' ]}: \n" ;
258+ foreach ($ changes ['base ' ]['lines ' ] as $ baseLineNo => $ baseLine ) {
259+ $ title .= $ changes ['base ' ]['offset ' ] + $ baseLineNo + 1 . ": $ baseLine \n" ;
260+ }
261+ }
262+
263+ $ title = htmlentities ($ title );
264+ $ html .= <<<HTML
238265<tr>
239- <th class=" $ headerClass " title=" { $ this -> lastDeleted } "> $ fromLine </th>
240- <td> $ line</td>
266+ <th class="ChangeReplace " title=" $ title "> $ toLine </th>
267+ <td class="ChangeReplace" > $ line</td>
241268</tr>
242269HTML ;
243- $ this ->lastDeleted = null ;
244270 }
245271
272+ $ this ->lineOffset = $ this ->lineOffset + $ changedLineCount - $ baseLineCount ;
273+
246274 return $ html ;
247275 }
248276
0 commit comments