From fda4852a92a7cb6f2d51e0292d9bb13bbf560d2c Mon Sep 17 00:00:00 2001 From: DigiLive Date: Wed, 22 Jul 2020 21:26:28 +0200 Subject: [PATCH] Resolve #52 and fixes. - HTML renderer Inline, SideBySide and Unified return false when there's nothing to render. - Text renderer Context, InlineCli and Unified return false when there's nothing to render. Main renderer returns false when there's nothing to render. - Text renderer InlineCli renders line-ending `\n` instead of `PHP_EOL`. - Added missing docBlock content. - Updated docBlock of the SubRenderer Interface. - Added method Diff::isIdentical(). - Updated README.md to reflect Diff::isIdentical(). --- README.md | 22 ++-- example/example.php | 106 +++++++++--------- lib/jblond/Diff.php | 38 +++++-- lib/jblond/Diff/Renderer/Html/Inline.php | 4 +- lib/jblond/Diff/Renderer/Html/SideBySide.php | 4 +- lib/jblond/Diff/Renderer/Html/Unified.php | 4 +- lib/jblond/Diff/Renderer/MainRenderer.php | 14 +-- .../Diff/Renderer/SubRendererInterface.php | 4 +- lib/jblond/Diff/Renderer/Text/Context.php | 6 +- lib/jblond/Diff/Renderer/Text/InlineCli.php | 14 +-- lib/jblond/Diff/Renderer/Text/Unified.php | 6 +- lib/jblond/Diff/SequenceMatcher.php | 1 + 12 files changed, 125 insertions(+), 98 deletions(-) diff --git a/README.md b/README.md index 9115a8c7..f2374221 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ## Introduction A comprehensive library for generating differences between two hashable objects (strings or arrays). -Generated differences can be rendered in all of the standard formats including: +Generated differences can be rendered in all the standard formats including: * Unified * Context @@ -35,8 +35,8 @@ use jblond\Diff\Renderer\Html\SideBySide; // Installed via composer... require 'vendor/autoload.php'; -$a = file_get_contents(dirname(__FILE__).'/a.txt'); -$b = file_get_contents(dirname(__FILE__).'/b.txt'); +$sampleA = file_get_contents(dirname(__FILE__).'/a.txt'); +$sampleB = file_get_contents(dirname(__FILE__).'/b.txt'); // Options for generating the diff. $options = [ @@ -47,20 +47,26 @@ $options = [ ]; // Initialize the diff class. -$diff = new Diff($a, $b /*, $options */); +$diff = new Diff($sampleA, $sampleB /*, $options */); // Choose Renderer. $renderer = new SideBySide([ - 'title1' => 'Custom title for OLD version', - 'title2' => 'Custom title for NEW version', + 'title1' => 'Custom title for sample A', + 'title2' => 'Custom title for sample B', ]); -// Show it. +// Show the output of the difference renderer. echo $diff->Render($renderer); + +// Alternative +// Show the differences or a message. +echo $diff->isIdentical() ? 'No differences found.' : '
' . htmlspecialchars($diff->render($renderer)) . '
' ; + ``` ### Example Output -A quick usage example can be found in the `example/` directory and under example.php. Included is a light theme and a dark theme. +File `example.php` contains a quick demo and can be found in the `example/` directory. +Included is a light and a dark theme. #### HTML Side By Side Example diff --git a/example/example.php b/example/example.php index f3637528..caebc983 100644 --- a/example/example.php +++ b/example/example.php @@ -23,73 +23,73 @@ ]; // Choose one of the initializations. -$diff = new Diff($sampleA, $sampleB); // Initialize the diff class with default options. -//$diff = new Diff($a, $b, $customOptions); // Initialize the diff class with custom options. +$diff = new Diff($sampleA, $sampleB); // Initialize the diff class with default options. +//$diff = new Diff($sampleA, $sampleB, $customOptions); // Initialize the diff class with custom options. ?> - - - PHP LibDiff - Examples - - - - -

PHP LibDiff - Examples

- -
- -

HTML Side by Side Diff

- - + + PHP LibDiff - Examples + + + + +

PHP LibDiff - Examples

+ +
+ +

HTML Side by Side Diff

+ + Render($renderer); - ?> - -

HTML Inline Diff

- - isIdentical() ? 'No differences found.' : $diff->Render($renderer); + ?> +

HTML Inline Diff

+ render($renderer); - ?> + echo $diff->isIdentical() ? 'No differences found.' : $diff->Render($renderer); + ?> -

HTML Unified Diff

- HTML Unified Diff + {$diff->render($renderer)}"; - ?> + echo $diff->isIdentical() ? 'No differences found.' : '
' . $diff->Render($renderer) . '
'; + ?> -

Text Unified Diff

- Text Unified Diff + ' . htmlspecialchars($diff->render($renderer)) . ''; - ?> + echo $diff->isIdentical() ? + 'No differences found.' : '
' . htmlspecialchars($diff->render($renderer)) . '
'; + ?> -

Text Context Diff

- Text Context Diff + ' . htmlspecialchars($diff->render($renderer)) . ''; - ?> - + echo $diff->isIdentical() ? + 'No differences found.' : '
' . htmlspecialchars($diff->render($renderer)) . '
'; + ?> + diff --git a/lib/jblond/Diff.php b/lib/jblond/Diff.php index f35001f4..63868c96 100644 --- a/lib/jblond/Diff.php +++ b/lib/jblond/Diff.php @@ -21,14 +21,14 @@ * * PHP version 7.2 or greater * - * @package jblond - * @author Chris Boulton - * @author Mario Brandt - * @author Ferry Cools + * @package jblond + * @author Chris Boulton + * @author Mario Brandt + * @author Ferry Cools * @copyright (c) 2020 Mario Brandt - * @license New BSD License http://www.opensource.org/licenses/bsd-license.php - * @version 2.1.1 - * @link https://github.com/JBlond/php-diff + * @license New BSD License http://www.opensource.org/licenses/bsd-license.php + * @version 2.1.1 + * @link https://github.com/JBlond/php-diff */ class Diff { @@ -73,6 +73,10 @@ class Diff * @see Diff::setOptions() */ private $options = []; + /** + * @var bool True when compared versions are identical, False otherwise. + */ + private $identical; /** * The constructor. @@ -169,9 +173,9 @@ public function getVersion2(): array * Render a diff-view using a rendering class and get its results. * * @param object|Context|Unified|UnifiedHtml|Inline|SideBySide $renderer An instance of the rendering object, - * used for generating the diff-view. + * used for generating the diff-view. * - * @return mixed The generated diff-view. The type of the return value depends on the applied rendereder. + * @return mixed The generated diff-view. The type of the return value depends on the applied renderer. */ public function render(object $renderer) { @@ -221,6 +225,20 @@ public function getArrayRange(array $array, int $start = 0, $end = null): array return array_slice($array, $start, $length); } + /** + * Get if the compared versions are identical or have differences. + * + * @return bool True when identical. + */ + public function isIdentical(): bool + { + if ($this->getGroupedOpCodes() === null) { + $this->getGroupedOpCodes(); + } + + return $this->identical; + } + /** * Generate a list of the compiled and grouped op-codes for the differences between two strings. * @@ -240,6 +258,8 @@ public function getGroupedOpCodes(): array //Get and cache the grouped op-codes. $sequenceMatcher = new SequenceMatcher($this->version1, $this->version2, $this->options); $this->groupedCodes = $sequenceMatcher->getGroupedOpCodes(); + $opCodes = $sequenceMatcher->getOpCodes(); + $this->identical = count($opCodes) == 1 && $opCodes[0][0] == 'equal'; return $this->groupedCodes; } diff --git a/lib/jblond/Diff/Renderer/Html/Inline.php b/lib/jblond/Diff/Renderer/Html/Inline.php index 9937c51a..767d5f7c 100644 --- a/lib/jblond/Diff/Renderer/Html/Inline.php +++ b/lib/jblond/Diff/Renderer/Html/Inline.php @@ -57,9 +57,9 @@ public function __construct(array $options = []) /** * Render and return a diff-view with changes between the two sequences displayed inline (under each other). * - * @return string The generated inline diff-view. + * @return string|false The generated diff-view or false when there's no difference. */ - public function render(): string + public function render() { $changes = parent::renderSequences(); diff --git a/lib/jblond/Diff/Renderer/Html/SideBySide.php b/lib/jblond/Diff/Renderer/Html/SideBySide.php index d406ce89..4dcd829b 100644 --- a/lib/jblond/Diff/Renderer/Html/SideBySide.php +++ b/lib/jblond/Diff/Renderer/Html/SideBySide.php @@ -57,9 +57,9 @@ public function __construct(array $options = []) /** * Render a and return diff-view with changes between the two sequences displayed side by side. * - * @return string The generated side by side diff-view. + * @return string|false The generated diff-view or false when there's no difference. */ - public function render(): string + public function render() { $changes = parent::renderSequences(); diff --git a/lib/jblond/Diff/Renderer/Html/Unified.php b/lib/jblond/Diff/Renderer/Html/Unified.php index 42164d59..bb971822 100644 --- a/lib/jblond/Diff/Renderer/Html/Unified.php +++ b/lib/jblond/Diff/Renderer/Html/Unified.php @@ -57,9 +57,9 @@ public function __construct(array $options = []) /** * Render a and return diff-view with changes between the two sequences (under each other). * - * @return string The generated unified diff-view. + * @return string|false The generated diff-view or false when there's no difference. */ - public function render(): string + public function render() { $changes = parent::renderSequences(); diff --git a/lib/jblond/Diff/Renderer/MainRenderer.php b/lib/jblond/Diff/Renderer/MainRenderer.php index c44c1b15..942eaafe 100644 --- a/lib/jblond/Diff/Renderer/MainRenderer.php +++ b/lib/jblond/Diff/Renderer/MainRenderer.php @@ -21,7 +21,7 @@ class MainRenderer extends MainRendererAbstract { /** - * @var int + * @var int Character count of the line marker with the most characters. */ protected $maxLineMarkerWidth = 0; /** @@ -31,20 +31,20 @@ class MainRenderer extends MainRendererAbstract private $lastTag; /** - * Generate a string representation of changes between the "old and "new" sequences. + * Generate a string representation of changes between version1 and version2. * * This method is called by the renderers which extends this class. * - * @param array $changes Contains the op-codes about the differences between "old and "new". + * @param array $changes Contains the op-codes about the differences between version1 and version2. * @param object $subRenderer Renderer which is subClass of this class. * - * @return string Representation of the differences. + * @return string|false String representation of the differences or false when versions are identical. */ - public function renderOutput(array $changes, object $subRenderer): string + public function renderOutput(array $changes, object $subRenderer) { if (!$changes) { - //No changes between "old" and "new" - return 'No differences found.'; + //No changes between version1 and version2 + return false; } $output = $subRenderer->generateDiffHeader(); diff --git a/lib/jblond/Diff/Renderer/SubRendererInterface.php b/lib/jblond/Diff/Renderer/SubRendererInterface.php index f9c84e68..cad6f87e 100644 --- a/lib/jblond/Diff/Renderer/SubRendererInterface.php +++ b/lib/jblond/Diff/Renderer/SubRendererInterface.php @@ -21,9 +21,9 @@ interface SubRendererInterface /** * Render and return a diff-view with changes between two sequences. * - * @return string The generated diff-view. + * @return string|false The generated diff-view or false when there's no difference. */ - public function render(): string; + public function render(); /** * Generate a string representation of the start of a diff view. diff --git a/lib/jblond/Diff/Renderer/Text/Context.php b/lib/jblond/Diff/Renderer/Text/Context.php index 63f086f7..ed9d52ec 100644 --- a/lib/jblond/Diff/Renderer/Text/Context.php +++ b/lib/jblond/Diff/Renderer/Text/Context.php @@ -37,11 +37,11 @@ class Context extends MainRendererAbstract * * @link https://www.gnu.org/software/diffutils/manual/html_node/Detailed-Context.html#Detailed-Context * - * @return string The generated context diff-view. + * @return string|false The generated diff-view or false when there's no difference. */ - public function render(): string + public function render() { - $diff = ''; + $diff = false; $opCodes = $this->diff->getGroupedOpCodes(); foreach ($opCodes as $group) { diff --git a/lib/jblond/Diff/Renderer/Text/InlineCli.php b/lib/jblond/Diff/Renderer/Text/InlineCli.php index 5629fac2..cb411989 100644 --- a/lib/jblond/Diff/Renderer/Text/InlineCli.php +++ b/lib/jblond/Diff/Renderer/Text/InlineCli.php @@ -45,9 +45,9 @@ public function __construct(array $options = []) /** * Render a and return diff-view with changes between the two sequences displayed inline. * - * @return string The generated diff-view. + * @return string|false The generated diff-view or false when there's no difference. */ - public function render(): string + public function render() { $changes = parent::renderSequences(); @@ -84,7 +84,7 @@ public function generateBlockHeader($changes): string */ public function generateSkippedLines(): string { - return '...' . PHP_EOL; + return "...\n"; } /** @@ -100,7 +100,7 @@ public function generateLinesEqual(array $changes): string $padding = str_repeat(' ', $this->maxLineMarkerWidth - strlen($this->options['equalityMarkers'][0])); foreach ($changes['base']['lines'] as $line) { - $returnValue .= $this->options['equalityMarkers'][0] . $padding . '|' . $line . PHP_EOL; + $returnValue .= $this->options['equalityMarkers'][0] . $padding . '|' . $line . "\n"; } return $returnValue; @@ -124,7 +124,7 @@ public function generateLinesInsert(array $changes): string [$fgColor, $bgColor] = $this->options['insertColors']; $line = $colorize->getColoredString($line, $fgColor, $bgColor); } - $returnValue .= $this->options['insertMarkers'][0] . $padding . '|' . $line . PHP_EOL; + $returnValue .= $this->options['insertMarkers'][0] . $padding . '|' . $line . "\n"; } return $returnValue; @@ -148,7 +148,7 @@ public function generateLinesDelete(array $changes): string [$fgColor, $bgColor] = $this->options['deleteColors']; $line = $colorize->getColoredString($line, $fgColor, $bgColor); } - $returnValue .= $this->options['deleteMarkers'][0] . $padding . '|' . $line . PHP_EOL; + $returnValue .= $this->options['deleteMarkers'][0] . $padding . '|' . $line . "\n"; } return $returnValue; @@ -172,7 +172,7 @@ public function generateLinesReplace(array $changes): string $this->options['insertColors'] ); - $returnValue .= implode(PHP_EOL, $changes['base']['lines']) . PHP_EOL; + $returnValue .= implode("\n", $changes['base']['lines']) . "\n"; return $returnValue; } diff --git a/lib/jblond/Diff/Renderer/Text/Unified.php b/lib/jblond/Diff/Renderer/Text/Unified.php index 50a1c58a..cbd00103 100644 --- a/lib/jblond/Diff/Renderer/Text/Unified.php +++ b/lib/jblond/Diff/Renderer/Text/Unified.php @@ -28,11 +28,11 @@ class Unified extends MainRendererAbstract /** * Render and return a unified diff. * - * @return string The unified diff. + * @return string|false The generated diff-view or false when there's no difference. */ - public function render(): string + public function render() { - $diff = ''; + $diff = false; $opCodes = $this->diff->getGroupedOpCodes(); foreach ($opCodes as $group) { $lastItem = count($group) - 1; diff --git a/lib/jblond/Diff/SequenceMatcher.php b/lib/jblond/Diff/SequenceMatcher.php index b1359428..62a6ffc4 100644 --- a/lib/jblond/Diff/SequenceMatcher.php +++ b/lib/jblond/Diff/SequenceMatcher.php @@ -481,6 +481,7 @@ function ($aArray, $bArray) { public function getOpCodes(): array { if (!empty($this->opCodes)) { + //Return the cached results. return $this->opCodes; }