Skip to content

Commit

Permalink
Fix #90 - Merged Diff shows result only partially
Browse files Browse the repository at this point in the history
* Renderer doesn't show lines which where added to version 2 of a
  replaced block. Code assumed the same amount of lines in replacement
  blocks at both versions. Now it handles replacement block differently
  when the amount of lines are equal or differs.
* Code cleanup.
* ClassName for lines of replacement blocks are incorrect. Insertion
  is insinuated, but should be replacement.
  • Loading branch information
DigiLive authored and DigiLive committed Mar 27, 2021
1 parent 7eba340 commit acbfd7d
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 30 deletions.
2 changes: 1 addition & 1 deletion example/dark-theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ a, a:visited {
/*
* HTML Merged Diff
*/
.DifferencesMerged td.ChangeInsert {
.DifferencesMerged td.ChangeReplace {
background: #FFDD88;
color: #272822;
}
Expand Down
2 changes: 1 addition & 1 deletion example/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ pre {
/*
* HTML Merged Diff
*/
.DifferencesMerged td.ChangeInsert {
.DifferencesMerged td.ChangeReplace {
background: #FFDD88;
}

Expand Down
83 changes: 55 additions & 28 deletions lib/jblond/Diff/Renderer/Html/Merged.php
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ public function generateSkippedLines(): string

return <<<HTML
<tr>
<th class="$headerClass" title="{$this->lastDeleted}">$marker</th>
<th class="$headerClass" title="$this->lastDeleted">$marker</th>
<td class="Skipped">&hellip;</td>
</tr>
HTML;
Expand All @@ -136,7 +136,7 @@ public function generateLinesEqual(array $changes): string

$html .= <<<HTML
<tr>
<th class="$headerClass" title="{$this->lastDeleted}">$fromLine</th>
<th class="$headerClass" title="$this->lastDeleted">$fromLine</th>
<td>$line</td>
</tr>
HTML;
Expand Down Expand Up @@ -165,7 +165,7 @@ public function generateLinesInsert(array $changes): string

$html .= <<<HTML
<tr>
<th class="$headerClass" title="{$this->lastDeleted}">$toLine</th>
<th class="$headerClass" title="$this->lastDeleted">$toLine</th>
<td><ins>$line</ins></td>
</tr>
HTML;
Expand Down Expand Up @@ -208,41 +208,68 @@ public function generateLinesDelete(array $changes): string
*/
public function generateLinesReplace(array $changes): string
{
$html = '';
$headerClass = '';

foreach ($changes['base']['lines'] as $lineNo => $line) {
$fromLine = $changes['base']['offset'] + $lineNo + 1 + $this->lineOffset;
if (!$lineNo && $this->lastDeleted !== null) {
$headerClass = 'ChangeDelete';
$html = '';
$baseLineCount = count($changes['base']['lines']);
$changedLineCount = count($changes['changed']['lines']);

if (count($changes['base']['lines']) == $changedLineCount) {
// Lines of Version 1 are modified at version 2.
foreach ($changes['base']['lines'] as $lineNo => $line) {
$fromLine = $changes['base']['offset'] + $lineNo + 1 + $this->lineOffset;

// Capture line-parts which are added to the same line at version 2.
$addedParts = [];
preg_match_all('/\x0.*?\x1/', $changes['changed']['lines'][$lineNo], $addedParts, PREG_PATTERN_ORDER);
array_unshift($addedParts[0], '');

// Inline Replacement:
// Concatenate line-parts which are removed at version2 with line-parts which are added at version 2.
$line = preg_replace_callback(
'/\x0.*?\x1/',
function ($removedParts) use ($addedParts) {
$addedPart = str_replace(["\0", "\1"], $this->options['insertMarkers'], next($addedParts[0]));
$removedPart = str_replace(["\0", "\1"], $this->options['deleteMarkers'], $removedParts[0]);

return "$removedPart$addedPart";
},
$line
);

$html .= <<<HTML
<tr>
<th>$fromLine</th>
<td>$line</td>
</tr>
HTML;
}

// Capture added parts.
$addedParts = [];
preg_match_all('/\x0.*?\x1/', $changes['changed']['lines'][$lineNo], $addedParts, PREG_PATTERN_ORDER);
array_unshift($addedParts[0], '');
return $html;
}

// Concatenate removed parts with added parts.
$line = preg_replace_callback(
'/\x0.*?\x1/',
function ($removedParts) use ($addedParts) {
$addedPart = str_replace(["\0", "\1"], $this->options['insertMarkers'], next($addedParts[0]));
$removedPart = str_replace(["\0", "\1"], $this->options['deleteMarkers'], $removedParts[0]);
// More or less lines at version 2. Block of version 1 is replaced by block of version 2.
$title = '';

return "$removedPart$addedPart";
},
$line
);
foreach ($changes['changed']['lines'] as $lineNo => $line) {
$toLine = $changes['changed']['offset'] + $lineNo + 1;

$html .= <<<HTML
if (!$lineNo) {
$title = "Lines replaced at {$this->options['title1']}:\n";
foreach ($changes['base']['lines'] as $baseLineNo => $baseLine) {
$title .= $changes['base']['offset'] + $baseLineNo + 1 . ": $baseLine\n";
}
}

$title = htmlentities($title);
$html .= <<<HTML
<tr>
<th class="$headerClass" title="{$this->lastDeleted}">$fromLine</th>
<td>$line</td>
<th class="ChangeReplace" title="$title">$toLine</th>
<td class="ChangeReplace">$line</td>
</tr>
HTML;
$this->lastDeleted = null;
}

$this->lineOffset = $this->lineOffset + $changedLineCount - $baseLineCount;

return $html;
}

Expand Down

0 comments on commit acbfd7d

Please sign in to comment.