Skip to content

Commit

Permalink
Merge pull request #86 from JBlond/php-diff-82
Browse files Browse the repository at this point in the history
php-diff-82
  • Loading branch information
JBlond authored Oct 26, 2021
2 parents 3f44195 + 0bf1a08 commit d6b2ef6
Show file tree
Hide file tree
Showing 14 changed files with 419 additions and 50 deletions.
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ $options = [
'ignoreWhitespace' => true,
'ignoreCase' => true,
'context' => 2,
'cliColor' => true // for cli output
'cliColor' => true, // for cli output
'ignoreLines' => Diff::DIFF_IGNORE_LINE_BLANK,
];

// Initialize the diff class.
Expand Down Expand Up @@ -140,7 +141,6 @@ at [jQuery-Merge-for-php-diff](https://github.com/Xiphe/jQuery-Merge-for-php-dif

## Todo

* Ability to ignore blank line changes
* 3 way diff support

## Contributors
Expand Down
26 changes: 26 additions & 0 deletions example/dark-theme.css
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,19 @@ a, a:visited {
background: #EEBB00;
}

.DifferencesSideBySide .ChangeIgnore .Left,
.DifferencesSideBySide .ChangeIgnore .Right {
background: #FBF2BF;
}

.DifferencesSideBySide .ChangeIgnore .Left.Ignore {
background: #4B4C57;
}

.DifferencesSideBySide .ChangeIgnore .Right.Ignore {
background: #4B4C57;
}

/*
* HTML Unified Diff
*/
Expand Down Expand Up @@ -127,6 +140,19 @@ a, a:visited {
color: #272822;
}

.DifferencesUnified .ChangeIgnore .Left,
.DifferencesUnified .ChangeIgnore .Right {
background: #FBF2BF;
}

.DifferencesUnified .ChangeIgnore .Left.Ignore {
background: #4B4C57;
}

.DifferencesUnified .ChangeIgnore .Right.Ignore {
background: #4B4C57;
}

/*
* HTML Merged Diff
*/
Expand Down
1 change: 1 addition & 0 deletions example/example.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
'trimEqual' => false,
'ignoreWhitespace' => true,
'ignoreCase' => true,
'ignoreLines' => Diff::DIFF_IGNORE_LINE_EMPTY,
];

// Choose one of the initializations.
Expand Down
26 changes: 26 additions & 0 deletions example/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,19 @@ pre {
background: #FFDD88;
}

.DifferencesSideBySide .ChangeIgnore .Left,
.DifferencesSideBySide .ChangeIgnore .Right {
background: #FBF2BF;
}

.DifferencesSideBySide .ChangeIgnore .Left.Ignore {
background: #F7F7F7;
}

.DifferencesSideBySide .ChangeIgnore .Right.Ignore {
background: #F7F7F7;
}

.Differences ins,
.Differences del {
text-decoration: none;
Expand Down Expand Up @@ -109,6 +122,19 @@ pre {
background: #EE9999;
}

.DifferencesUnified .ChangeIgnore .Left,
.DifferencesUnified .ChangeIgnore .Right {
background: #FBF2BF;
}

.DifferencesUnified .ChangeIgnore .Left.Ignore {
background: #F7F7F7;
}

.DifferencesUnified .ChangeIgnore .Right.Ignore {
background: #F7F7F7;
}

/*
* HTML Merged Diff
*/
Expand Down
20 changes: 11 additions & 9 deletions lib/jblond/Diff.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
namespace jblond;

use InvalidArgumentException;
use jblond\Diff\ConstantsInterface;
use jblond\Diff\SequenceMatcher;
use jblond\Diff\Similarity;
use OutOfRangeException;
Expand All @@ -26,7 +27,7 @@
* @version 2.3.3
* @link https://github.com/JBlond/php-diff
*/
class Diff
class Diff implements ConstantsInterface
{
/**
* @var array The first version to compare.
Expand All @@ -46,21 +47,22 @@ class Diff
private $groupedCodes;

/**
* @var array<string, string> Associative array containing the default options available
* for the diff class and their default value.
* @var array Associative array containing the default options available for the diff class and their default value.
*
* - context The amount of lines to include around blocks that differ.
* - trimEqual Strip blocks of equal lines from the start and end of the text.
* - ignoreWhitespace When true, tabs and spaces are ignored while comparing.
* The spacing of version1 is leading.
* - ignoreCase When true, character casing is ignored while comparing.
* The casing of version1 is leading.
* - context The amount of lines to include around blocks that differ.
* - trimEqual Strip blocks of equal lines from the start and end of the text.
* - ignoreWhitespace True to ignore differences in tabs and spaces.
* - ignoreCase True to ignore differences in character casing.
* - ignoreLines 0: None.
* 1: Ignore empty lines.
* 2: Ignore blank lines.
*/
private $defaultOptions = [
'context' => 3,
'trimEqual' => true,
'ignoreWhitespace' => false,
'ignoreCase' => false,
'ignoreLines' => self::DIFF_IGNORE_LINE_NONE,
];

/**
Expand Down
33 changes: 33 additions & 0 deletions lib/jblond/Diff/ConstantsInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<?php

namespace jblond\Diff;

/**
* Constant Interface
*
* Defines the library constants which needs to be shared across the different classes.
*
* PHP version 7.2 or greater
*
* @package jblond
* @author Ferry Cools <[email protected]>
* @copyright (c) 2020 Mario Brandt
* @license New BSD License http://www.opensource.org/licenses/bsd-license.php
* @version 2.3.0
* @link https://github.com/JBlond/php-diff
*/
interface ConstantsInterface
{
/**
* Flag to disable ignore of successive empty/blank lines.
*/
public const DIFF_IGNORE_LINE_NONE = 0;
/**
* Flag to ignore empty lines.
*/
public const DIFF_IGNORE_LINE_EMPTY = 1;
/**
* Flag to ignore blank lines. (Lines which contain no or only non printable characters.)
*/
public const DIFF_IGNORE_LINE_BLANK = 2;
}
66 changes: 66 additions & 0 deletions lib/jblond/Diff/Renderer/Html/SideBySide.php
Original file line number Diff line number Diff line change
Expand Up @@ -282,4 +282,70 @@ public function generateDiffFooter(): string
{
return '</table>';
}

/**
* @inheritDoc
*
* @return string Html code representing table rows showing ignored text.
*/
public function generateLinesIgnore(array $changes): string
{
$html = '';

// Is below comparison result ever false?
if (count($changes['base']['lines']) >= count($changes['changed']['lines'])) {
foreach ($changes['base']['lines'] as $lineNo => $line) {
$fromLine = $changes['base']['offset'] + $lineNo + 1;
$toLine = '&nbsp;';
$changedLine = '&nbsp;';
if (isset($changes['changed']['lines'][$lineNo])) {
$toLine = $changes['changed']['offset'] + $lineNo + 1;
$changedLine = $changes['changed']['lines'][$lineNo];
}

$html .= <<<HTML
<tr>
<th>$fromLine</th>
<td class="Left">
<span>$line</span>
</td>
<th>$toLine</th>
<td class="Right Ignore">
<span>$changedLine</span>
</td>
</tr>
HTML;
}

return $html;
}

foreach ($changes['changed']['lines'] as $lineNo => $changedLine) {
$toLine = $changes['changed']['offset'] + $lineNo + 1;
$fromLine = '&nbsp;';
$line = '&nbsp;';
if (isset($changes['base']['lines'][$lineNo])) {
$fromLine = $changes['base']['offset'] + $lineNo + 1;
$line = $changes['base']['lines'][$lineNo];
}

$line = str_replace(["\0", "\1"], $this->options['deleteMarkers'], $line);
$changedLine = str_replace(["\0", "\1"], $this->options['insertMarkers'], $changedLine);

$html .= <<<HTML
<tr>
<th>$fromLine</th>
<td class="Left Ignore">
<span>$line</span>
</td>
<th>$toLine</th>
<td class="Right">
<span>$changedLine</span>
</td>
</tr>
HTML;
}

return $html;
}
}
38 changes: 38 additions & 0 deletions lib/jblond/Diff/Renderer/Html/Unified.php
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,44 @@ public function generateLinesReplace(array $changes): string
return $html;
}

/**
* @inheritDoc
*
* @return string Html code representing table rows showing modified text.
*/
public function generateLinesIgnore(array $changes): string
{
$html = '';

foreach ($changes['base']['lines'] as $lineNo => $line) {
$fromLine = $changes['base']['offset'] + $lineNo + 1;
$html .= <<<HTML
<tr>
<th>$fromLine</th>
<th></th>
<td class="Left Ignore">
<span>$line</span>
</td>
</tr>
HTML;
}

foreach ($changes['changed']['lines'] as $lineNo => $line) {
$toLine = $changes['changed']['offset'] + $lineNo + 1;
$html .= <<<HTML
<tr>
<th></th>
<th>$toLine</th>
<td class="Right Ignore">
<span>$line</span>
</td>
</tr>
HTML;
}

return $html;
}

/**
* @inheritDoc
*
Expand Down
42 changes: 32 additions & 10 deletions lib/jblond/Diff/Renderer/MainRenderer.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,23 @@ public function renderOutput(array $changes, object $subRenderer)
strlen($this->options['equalityMarkers'][1])
);

$deprecationTriggered = false;
foreach ($blocks as $change) {
if (
$subRenderer instanceof MainRenderer &&
!method_exists($subRenderer, 'generateLinesIgnore') &&
$change['tag'] == 'ignore'
) {
if (!$deprecationTriggered) {
trigger_error(
'The use of a subRenderer without method generateLinesIgnore() is deprecated!',
E_USER_DEPRECATED
);
$deprecationTriggered = true;
}
$change['tag'] =
(count($change['base']['lines']) > count($change['changed']['lines'])) ? 'delete' : 'insert';
}
$output .= $subRenderer->generateBlockHeader($change);
switch ($change['tag']) {
case 'equal':
Expand All @@ -80,6 +96,10 @@ public function renderOutput(array $changes, object $subRenderer)
case 'replace':
$output .= $subRenderer->generateLinesReplace($change);
break;
case 'ignore':
// TODO: Keep backward compatible with renderers?
$output .= $subRenderer->generateLinesIgnore($change);
break;
}

$output .= $subRenderer->generateBlockFooter($change);
Expand Down Expand Up @@ -124,12 +144,14 @@ protected function renderSequences(): array
* 4 - The end line in the second sequence.
*
* The different types of tags include:
* replace - The string from $startOld to $endOld in $oldText should be replaced by
* replace - The string in $oldText from $startOld to $endOld, should be replaced by
* the string in $newText from $startNew to $endNew.
* delete - The string in $oldText from $startOld to $endNew should be deleted.
* insert - The string in $newText from $startNew to $endNew should be inserted at $startOld in
* $oldText.
* equal - The two strings with the specified ranges are equal.
* ignore - The string in $oldText from $startOld to $endOld and
* the string in $newText from $startNew to $endNew are different, but considered to be equal.
*/

$blockSizeOld = $endOld - $startOld;
Expand All @@ -146,23 +168,23 @@ protected function renderSequences(): array
$oldBlock = $this->formatLines(array_slice($oldText, $startOld, $blockSizeOld));
$newBlock = $this->formatLines(array_slice($newText, $startNew, $blockSizeNew));

if ($tag == 'equal') {
// Old block equals New block
if ($tag != 'delete' && $tag != 'insert') {
// Old block "equals" New block or is replaced.
$blocks[$lastBlock]['base']['lines'] += $oldBlock;
$blocks[$lastBlock]['changed']['lines'] += $newBlock;
continue;
}

if ($tag == 'replace' || $tag == 'delete') {
// Inline differences or old block doesn't exist in the new text.
if ($tag == 'delete') {
// Block of version1 doesn't exist in version2.
$blocks[$lastBlock]['base']['lines'] += $oldBlock;
continue;
}

if ($tag == 'replace' || $tag == 'insert') {
// Inline differences or the new block doesn't exist in the old text.
$blocks[$lastBlock]['changed']['lines'] += $newBlock;
}
// Block of version2 doesn't exist in version1.
$blocks[$lastBlock]['changed']['lines'] += $newBlock;
}

$changes[] = $blocks;
}

Expand Down Expand Up @@ -291,7 +313,7 @@ public function sequenceToArray(string $pattern, string $sequence): array
* E.g.
* <pre>
* 1234567
* OLd => "abcdefg" Start marker inserted at position 3
* Old => "abcdefg" Start marker inserted at position 3
* New => "ab123fg" End marker inserted at position 6
* </pre>
*
Expand Down
Loading

0 comments on commit d6b2ef6

Please sign in to comment.