diff --git a/.gitignore b/.gitignore index 187adb24..c341f5f4 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -/nbproject/ \ No newline at end of file +/nbproject/ + +.DS_Store \ No newline at end of file diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..a6a32cb8 --- /dev/null +++ b/LICENSE @@ -0,0 +1,27 @@ +Copyright (c) 2009 Chris Boulton +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + - Neither the name of the Chris Boulton nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md index 0110b5c5..b46c46eb 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,8 @@ PHP Diff Class -------------- +[![SensioLabsInsight](https://insight.sensiolabs.com/projects/aa609edb-cdb1-45cf-ad51-afbdab48f6a1/mini.png)](https://insight.sensiolabs.com/projects/aa609edb-cdb1-45cf-ad51-afbdab48f6a1) + Introduction ------------ A comprehensive library for generating differences between @@ -37,8 +39,8 @@ License (BSD License) --------------------- Copyright (c) 2009 Chris Boulton All rights reserved. - -Redistribution and use in source and binary forms, with or without + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - Redistributions of source code must retain the above copyright notice, @@ -46,20 +48,20 @@ modification, are permitted provided that the following conditions are met: - Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - - Neither the name of the Chris Boulton nor the names of its contributors - may be used to endorse or promote products derived from this software + - Neither the name of the Chris Boulton nor the names of its contributors + may be used to endorse or promote products derived from this software without specific prior written permission. ``` -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ``` diff --git a/composer.json b/composer.json index a6b043bb..37714347 100644 --- a/composer.json +++ b/composer.json @@ -1,16 +1,29 @@ { - "name": "chrisboulton/php-diff", - "type": "library", - "description": "A comprehensive library for generating differences between two hashable objects (strings or arrays).", - "authors": [ - { - "name": "Chris Boulton", - "email": "@chrisboulton" - } - ], - "autoload": { - "psr-0": { - "Diff": "lib/" - } - } -} \ No newline at end of file + "name": "tinybox/php-diff", + "license": "BSD-3-Clause", + "type": "library", + "description": "A comprehensive library for generating differences between two hash able objects (strings or arrays).", + "keywords": [ + "php", + "diff" + ], + "repositories": [ + {"type": "composer", "url": "https://packagist.baixing.cn/repo/private/"} + ], + "authors": [ + { + "name": "Chris Boulton" + }, + { + "name": "Mario / JBlond" + }, + { + "name": "TinyBox" + } + ], + "autoload": { + "psr-4": { + "Tinybox\\Diff\\": "lib/" + } + } +} diff --git a/example/a.txt b/example/a.txt index 6f3897b2..ff9edbdb 100644 --- a/example/a.txt +++ b/example/a.txt @@ -7,7 +7,12 @@

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

A heading we'll be removing

+
+构建具有中国特色的医学人才培养体系
+aaa
 
+bbb
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

- \ No newline at end of file + diff --git a/example/b.txt b/example/b.txt index 5918964d..270ac04d 100644 --- a/example/b.txt +++ b/example/b.txt @@ -1,3 +1,4 @@ + @@ -6,7 +7,12 @@

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

+
+构建具有中国的医学人才培养体系
+aaa
 
+bbb
+

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.

Just a small amount of new text...

diff --git a/example/example.php b/example/example.php index 234bc2c8..61a3acd0 100644 --- a/example/example.php +++ b/example/example.php @@ -1,8 +1,7 @@ - + - + PHP LibDiff - Examples @@ -45,6 +44,15 @@ $renderer = new Diff_Renderer_Html_Inline; echo $diff->render($renderer); + ?> +

Simple Diff

+ render($renderer); + ?>

Unified Diff


 		
- \ No newline at end of file + diff --git a/example/styles.css b/example/styles.css index 5454896f..0ee5c3b3 100644 --- a/example/styles.css +++ b/example/styles.css @@ -1,28 +1,33 @@ body { background: #fff; - font-family: Arial; + font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace; font-size: 12px; + border-radius: 3px; } .Differences { width: 100%; border-collapse: collapse; border-spacing: 0; empty-cells: show; + margin-top: 20px; + margin-bottom: 15px; + border: 1px solid #ddd; } .Differences thead th { - text-align: left; - border-bottom: 1px solid #000; - background: #aaa; - color: #000; - padding: 4px; + padding: 5px 10px; + background-color: #f7f7f7; + border-bottom: 1px solid #d8d8d8; + border-top-left-radius: 2px; + border-top-right-radius: 2px; } .Differences tbody th { - text-align: right; - background: #ccc; - width: 4em; + text-align: center; + background: #f7f7f7; + width: 1%; padding: 1px 2px; - border-right: 1px solid #000; + border: solid #eee; + border-width: 0 1px 0 0; vertical-align: top; font-size: 13px; } @@ -87,6 +92,11 @@ body { background: #e99; } +.Differences ins, .Differences del { + text-decoration: none; + white-space: pre-wrap; +} + pre { width: 100%; overflow: auto; diff --git a/lib/Diff.php b/lib/Diff.php index d1eb9da0..bede3853 100644 --- a/lib/Diff.php +++ b/lib/Diff.php @@ -8,10 +8,10 @@ * PHP version 5 * * Copyright (c) 2009 Chris Boulton - * + * * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without + * + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, @@ -19,20 +19,20 @@ * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * - Neither the name of the Chris Boulton nor the names of its contributors - * may be used to endorse or promote products derived from this software + * - Neither the name of the Chris Boulton nor the names of its contributors + * may be used to endorse or promote products derived from this software * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package Diff @@ -67,19 +67,23 @@ class Diff 'context' => 3, 'ignoreNewLines' => false, 'ignoreWhitespace' => false, - 'ignoreCase' => false + 'ignoreCase' => false, + 'title_a'=>'Old Version', + 'title_b'=>'New Version', + 'labelDifferences'=>'Differences' ); /** * @var array Array of the options that have been applied for generating the diff. */ - private $options = array(); + public $options = array(); /** * The constructor. * * @param array $a Array containing the lines of the first string to compare. * @param array $b Array containing the lines for the second string to compare. + * @param array $options Array for the options */ public function __construct($a, $b, $options=array()) { @@ -95,7 +99,8 @@ public function __construct($a, $b, $options=array()) /** * Render a diff using the supplied rendering class and return it. * - * @param object $renderer An instance of the rendering object to use for generating the diff. + * @param \Diff_Renderer_Abstract|object $renderer An instance of the rendering object to use for generating the diff. + * * @return mixed The generated diff. Exact return value depends on the rendered. */ public function render(Diff_Renderer_Abstract $renderer) @@ -176,4 +181,4 @@ public function getGroupedOpcodes() $this->groupedCodes = $sequenceMatcher->getGroupedOpcodes($this->options['context']); return $this->groupedCodes; } -} \ No newline at end of file +} diff --git a/lib/Diff/Renderer/Abstract.php b/lib/Diff/Renderer/Abstract.php index f63c3e7f..828ccf74 100644 --- a/lib/Diff/Renderer/Abstract.php +++ b/lib/Diff/Renderer/Abstract.php @@ -5,10 +5,10 @@ * PHP version 5 * * Copyright (c) 2009 Chris Boulton - * + * * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without + * + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, @@ -16,20 +16,20 @@ * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * - Neither the name of the Chris Boulton nor the names of its contributors - * may be used to endorse or promote products derived from this software + * - Neither the name of the Chris Boulton nor the names of its contributors + * may be used to endorse or promote products derived from this software * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package DiffLib @@ -79,4 +79,4 @@ public function setOptions(array $options) { $this->options = array_merge($this->defaultOptions, $options); } -} \ No newline at end of file +} diff --git a/lib/Diff/Renderer/Html/Array.php b/lib/Diff/Renderer/Html/Array.php index b012fb6b..cf5f9502 100644 --- a/lib/Diff/Renderer/Html/Array.php +++ b/lib/Diff/Renderer/Html/Array.php @@ -5,10 +5,10 @@ * PHP version 5 * * Copyright (c) 2009 Chris Boulton - * + * * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without + * + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, @@ -16,20 +16,20 @@ * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * - Neither the name of the Chris Boulton nor the names of its contributors - * may be used to endorse or promote products derived from this software + * - Neither the name of the Chris Boulton nor the names of its contributors + * may be used to endorse or promote products derived from this software * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package DiffLib @@ -51,6 +51,50 @@ class Diff_Renderer_Html_Array extends Diff_Renderer_Abstract 'tabSize' => 4 ); + /** + * From https://gist.github.com/stemar/8287074 + * @param mixed $string The input string. + * @param mixed $replacement The replacement string. + * @param mixed $start If start is positive, the replacing will begin at the start'th offset into string. If start is negative, the replacing will begin at the start'th character from the end of string. + * @param mixed $length If given and is positive, it represents the length of the portion of string which is to be replaced. If it is negative, it represents the number of characters from the end of string at which to stop replacing. If it is not given, then it will default to strlen( string ); i.e. end the replacing at the end of string. Of course, if length is zero then this function will have the effect of inserting replacement into string at the given start offset. + * @return string The result string is returned. If string is an array then array is returned. + */ + public function mb_substr_replace($string, $replacement, $start, $length=NULL) { + if (is_array($string)) { + $num = count($string); + // $replacement + $replacement = is_array($replacement) ? array_slice($replacement, 0, $num) : array_pad(array($replacement), $num, $replacement); + // $start + if (is_array($start)) { + $start = array_slice($start, 0, $num); + foreach ($start as $key => $value) + $start[$key] = is_int($value) ? $value : 0; + } + else { + $start = array_pad(array($start), $num, $start); + } + // $length + if (!isset($length)) { + $length = array_fill(0, $num, 0); + } + elseif (is_array($length)) { + $length = array_slice($length, 0, $num); + foreach ($length as $key => $value) + $length[$key] = isset($value) ? (is_int($value) ? $value : $num) : 0; + } + else { + $length = array_pad(array($length), $num, $length); + } + // Recursive call + return array_map(__FUNCTION__, $string, $replacement, $start, $length); + } + preg_match_all('/./us', (string)$string, $smatches); + preg_match_all('/./us', (string)$replacement, $rmatches); + if ($length === NULL) $length = mb_strlen($string); + array_splice($smatches['0'], $start, $length, $rmatches[0]); + return join($smatches['0']); + } + /** * Render and return an array structure suitable for generating HTML * based differences. Generally called by subclasses that generate a @@ -83,11 +127,11 @@ public function render() list($start, $end) = $this->getChangeExtent($fromLine, $toLine); if($start != 0 || $end != 0) { $last = $end + strlen($fromLine); - $fromLine = substr_replace($fromLine, "\0", $start, 0); - $fromLine = substr_replace($fromLine, "\1", $last + 1, 0); + $fromLine = $this->mb_substr_replace($fromLine, "\0", $start, 0); + $fromLine = $this->mb_substr_replace($fromLine, "\1", $last + 1, 0); $last = $end + strlen($toLine); - $toLine = substr_replace($toLine, "\0", $start, 0); - $toLine = substr_replace($toLine, "\1", $last + 1, 0); + $toLine = $this->mb_substr_replace($toLine, "\0", $start, 0); + $toLine = $this->mb_substr_replace($toLine, "\1", $last + 1, 0); $a[$i1 + $i] = $fromLine; $b[$j1 + $i] = $toLine; } @@ -177,7 +221,7 @@ protected function formatLines($lines) $lines = array_map(array($this, 'ExpandTabs'), $lines); $lines = array_map(array($this, 'HtmlSafe'), $lines); foreach($lines as &$line) { - $line = preg_replace('# ( +)|^ #e', "\$this->fixSpaces('\\1')", $line); + $line = preg_replace_callback('# ( +)|^ #', array($this, 'fixSpaces'), $line); } return $lines; } @@ -185,19 +229,26 @@ protected function formatLines($lines) /** * Replace a string containing spaces with a HTML representation using  . * - * @param string $spaces The string of spaces. + * @param array $matches The string of spaces. * @return string The HTML representation of the string. */ - function fixSpaces($spaces='') + function fixSpaces($matches) { - $count = strlen($spaces); - if($count == 0) { - return ''; + $buffer = ''; + $count = 0; + foreach($matches as $spaces){ + $count = strlen($spaces); + if($count == 0) { + continue; + } + $div = floor($count / 2); + $mod = $count % 2; + $buffer .= str_repeat('  ', $div).str_repeat(' ', $mod); } $div = floor($count / 2); $mod = $count % 2; - return str_repeat('  ', $div).str_repeat(' ', $mod); + return str_repeat('  ', $div).str_repeat(' ', $mod); } /** @@ -208,7 +259,15 @@ function fixSpaces($spaces='') */ private function expandTabs($line) { - return str_replace("\t", str_repeat(' ', $this->options['tabSize']), $line); + $tabSize = $this->options['tabSize']; + while(($pos = strpos($line, "\t")) !== FALSE){ + $left = substr($line, 0, $pos); + $right = substr($line, $pos + 1); + $length = $tabSize - ($pos % $tabSize); + $spaces = str_repeat(' ', $length); + $line = $left.$spaces.$right; + } + return $line; } /** diff --git a/lib/Diff/Renderer/Html/Inline.php b/lib/Diff/Renderer/Html/Inline.php index 60e8005a..1cb92f5b 100644 --- a/lib/Diff/Renderer/Html/Inline.php +++ b/lib/Diff/Renderer/Html/Inline.php @@ -5,10 +5,10 @@ * PHP version 5 * * Copyright (c) 2009 Chris Boulton - * + * * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without + * + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, @@ -16,20 +16,20 @@ * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * - Neither the name of the Chris Boulton nor the names of its contributors - * may be used to endorse or promote products derived from this software + * - Neither the name of the Chris Boulton nor the names of its contributors + * may be used to endorse or promote products derived from this software * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package DiffLib @@ -74,7 +74,7 @@ public function render() $html .= ''; $html .= '…'; $html .= '…'; - $html .= ' '; + $html .= ' '; $html .= ''; } @@ -97,9 +97,9 @@ public function render() foreach($change['changed']['lines'] as $no => $line) { $toLine = $change['changed']['offset'] + $no + 1; $html .= ''; - $html .= ' '; + $html .= ' '; $html .= ''.$toLine.''; - $html .= ''.$line.' '; + $html .= ''.$line.' '; $html .= ''; } } @@ -109,8 +109,8 @@ public function render() $fromLine = $change['base']['offset'] + $no + 1; $html .= ''; $html .= ''.$fromLine.''; - $html .= ' '; - $html .= ''.$line.' '; + $html .= ' '; + $html .= ''.$line.' '; $html .= ''; } } @@ -120,7 +120,7 @@ public function render() $fromLine = $change['base']['offset'] + $no + 1; $html .= ''; $html .= ''.$fromLine.''; - $html .= ' '; + $html .= ' '; $html .= ''.$line.''; $html .= ''; } @@ -128,8 +128,8 @@ public function render() foreach($change['changed']['lines'] as $no => $line) { $toLine = $change['changed']['offset'] + $no + 1; $html .= ''; + $html .= ' '; $html .= ''.$toLine.''; - $html .= ' '; $html .= ''.$line.''; $html .= ''; } @@ -140,4 +140,4 @@ public function render() $html .= ''; return $html; } -} \ No newline at end of file +} diff --git a/lib/Diff/Renderer/Html/SideBySide.php b/lib/Diff/Renderer/Html/SideBySide.php index 307af1c3..6418b4b6 100644 --- a/lib/Diff/Renderer/Html/SideBySide.php +++ b/lib/Diff/Renderer/Html/SideBySide.php @@ -5,10 +5,10 @@ * PHP version 5 * * Copyright (c) 2009 Chris Boulton - * + * * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without + * + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, @@ -16,20 +16,20 @@ * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * - Neither the name of the Chris Boulton nor the names of its contributors - * may be used to endorse or promote products derived from this software + * - Neither the name of the Chris Boulton nor the names of its contributors + * may be used to endorse or promote products derived from this software * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package DiffLib @@ -69,8 +69,8 @@ public function render() foreach($changes as $i => $blocks) { if($i > 0) { $html .= ''; - $html .= '… '; - $html .= '… '; + $html .= '… '; + $html .= '… '; $html .= ''; } @@ -83,9 +83,9 @@ public function render() $toLine = $change['changed']['offset'] + $no + 1; $html .= ''; $html .= ''.$fromLine.''; - $html .= ''.$line.' '; + $html .= ''.$line.' '; $html .= ''.$toLine.''; - $html .= ''.$line.' '; + $html .= ''.$line.' '; $html .= ''; } } @@ -94,10 +94,10 @@ public function render() foreach($change['changed']['lines'] as $no => $line) { $toLine = $change['changed']['offset'] + $no + 1; $html .= ''; - $html .= ' '; - $html .= ' '; + $html .= ' '; + $html .= ' '; $html .= ''.$toLine.''; - $html .= ''.$line.' '; + $html .= ''.$line.' '; $html .= ''; } } @@ -107,9 +107,9 @@ public function render() $fromLine = $change['base']['offset'] + $no + 1; $html .= ''; $html .= ''.$fromLine.''; - $html .= ''.$line.' '; - $html .= ' '; - $html .= ' '; + $html .= ''.$line.' '; + $html .= ' '; + $html .= ' '; $html .= ''; } } @@ -120,10 +120,10 @@ public function render() $fromLine = $change['base']['offset'] + $no + 1; $html .= ''; $html .= ''.$fromLine.''; - $html .= ''.$line.' '; + $html .= ''.$line.' '; if(!isset($change['changed']['lines'][$no])) { - $toLine = ' '; - $changedLine = ' '; + $toLine = ' '; + $changedLine = ' '; } else { $toLine = $change['base']['offset'] + $no + 1; @@ -137,8 +137,8 @@ public function render() else { foreach($change['changed']['lines'] as $no => $changedLine) { if(!isset($change['base']['lines'][$no])) { - $fromLine = ' '; - $line = ' '; + $fromLine = ' '; + $line = ' '; } else { $fromLine = $change['base']['offset'] + $no + 1; @@ -146,7 +146,7 @@ public function render() } $html .= ''; $html .= ''.$fromLine.''; - $html .= ''.$line.' '; + $html .= ''.$line.' '; $toLine = $change['changed']['offset'] + $no + 1; $html .= ''.$toLine.''; $html .= ''.$changedLine.''; @@ -160,4 +160,4 @@ public function render() $html .= ''; return $html; } -} \ No newline at end of file +} diff --git a/lib/Diff/Renderer/Html/Simple.php b/lib/Diff/Renderer/Html/Simple.php new file mode 100644 index 00000000..372f6aeb --- /dev/null +++ b/lib/Diff/Renderer/Html/Simple.php @@ -0,0 +1,76 @@ +'; + $html .= ''; + $html .= ''; + foreach($changes as $i => $blocks) { + // If this is a separate block, we're condensing code so output ..., + // indicating a significant portion of the code has been collapsed as + // it is the same + if($i > 0) { + $html .= ''; + $html .= '…'; + $html .= '…'; + $html .= ' '; + $html .= ''; + } + + foreach($blocks as $change) { + $html .= ''; + // Added lines only on the right side + if($change['tag'] == 'insert') { + foreach($change['changed']['lines'] as $no => $line) { + $html .= ''; + $html .= ''.$line.' '; + $html .= ''; + } + } + // Show deleted lines only on the left side + else if($change['tag'] == 'delete') { + foreach($change['base']['lines'] as $no => $line) { + $html .= ''; + $html .= ''.$line.' '; + $html .= ''; + } + } + // Show modified lines on both sides + else if($change['tag'] == 'replace') { + foreach($change['base']['lines'] as $no => $line) { + $html .= ''; + $html .= ''.$line.''; + $html .= ''; + } + + foreach($change['changed']['lines'] as $no => $line) { + $html .= ''; + $html .= ''.$line.''; + $html .= ''; + } + } + $html .= ''; + } + } + $html .= ''; + return $html; + } +} diff --git a/lib/Diff/Renderer/Text/Context.php b/lib/Diff/Renderer/Text/Context.php index 1200b01c..1d1ab457 100644 --- a/lib/Diff/Renderer/Text/Context.php +++ b/lib/Diff/Renderer/Text/Context.php @@ -5,10 +5,10 @@ * PHP version 5 * * Copyright (c) 2009 Chris Boulton - * + * * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without + * + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, @@ -16,20 +16,20 @@ * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * - Neither the name of the Chris Boulton nor the names of its contributors - * may be used to endorse or promote products derived from this software + * - Neither the name of the Chris Boulton nor the names of its contributors + * may be used to endorse or promote products derived from this software * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package DiffLib @@ -66,13 +66,13 @@ public function render() foreach($opCodes as $group) { $diff .= "***************\n"; $lastItem = count($group)-1; - $i1 = $group[0][1]; - $i2 = $group[$lastItem][2]; - $j1 = $group[0][3]; - $j2 = $group[$lastItem][4]; + $i1 = $group['0']['1']; + $i2 = $group[$lastItem]['2']; + $j1 = $group['0']['3']; + $j2 = $group[$lastItem]['4']; if($i2 - $i1 >= 2) { - $diff .= '*** '.($group[0][1] + 1).','.$i2." ****\n"; + $diff .= '*** '.($group['0']['1'] + 1).','.$i2." ****\n"; } else { $diff .= '*** '.$i2." ****\n"; @@ -87,7 +87,7 @@ public function render() $hasVisible = false; foreach($group as $code) { - if($code[0] == 'replace' || $code[0] == 'delete') { + if($code['0'] == 'replace' || $code['0'] == 'delete') { $hasVisible = true; break; } @@ -105,7 +105,7 @@ public function render() $hasVisible = false; foreach($group as $code) { - if($code[0] == 'replace' || $code[0] == 'insert') { + if($code['0'] == 'replace' || $code['0'] == 'insert') { $hasVisible = true; break; } @@ -125,4 +125,4 @@ public function render() } return $diff; } -} \ No newline at end of file +} diff --git a/lib/Diff/Renderer/Text/Unified.php b/lib/Diff/Renderer/Text/Unified.php index e94d951d..87cfa20a 100644 --- a/lib/Diff/Renderer/Text/Unified.php +++ b/lib/Diff/Renderer/Text/Unified.php @@ -5,10 +5,10 @@ * PHP version 5 * * Copyright (c) 2009 Chris Boulton - * + * * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without + * + * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * - Redistributions of source code must retain the above copyright notice, @@ -16,20 +16,20 @@ * - Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. - * - Neither the name of the Chris Boulton nor the names of its contributors - * may be used to endorse or promote products derived from this software + * - Neither the name of the Chris Boulton nor the names of its contributors + * may be used to endorse or promote products derived from this software * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * @package DiffLib @@ -55,10 +55,10 @@ public function render() $opCodes = $this->diff->getGroupedOpcodes(); foreach($opCodes as $group) { $lastItem = count($group)-1; - $i1 = $group[0][1]; - $i2 = $group[$lastItem][2]; - $j1 = $group[0][3]; - $j2 = $group[$lastItem][4]; + $i1 = $group['0']['1']; + $i2 = $group[$lastItem]['2']; + $j1 = $group['0']['3']; + $j2 = $group[$lastItem]['4']; if($i1 == 0 && $i2 == 0) { $i1 = -1; @@ -84,4 +84,4 @@ public function render() } return $diff; } -} \ No newline at end of file +} diff --git a/lib/Diff/SequenceMatcher.php b/lib/Diff/SequenceMatcher.php index e819e810..5285ba07 100644 --- a/lib/Diff/SequenceMatcher.php +++ b/lib/Diff/SequenceMatcher.php @@ -67,8 +67,16 @@ class Diff_SequenceMatcher */ private $b2j = array(); + private $juncDict = array(); + private $options = array(); + private $opCodes; + + private $matchingBlocks; + + private $fullBCount; + private $defaultOptions = array( 'ignoreNewLines' => false, 'ignoreWhitespace' => false, @@ -83,6 +91,7 @@ class Diff_SequenceMatcher * @param string|array $a A string or array containing the lines to compare against. * @param string|array $b A string or array containing the lines to compare. * @param string|array $junkCallback Either an array or string that references a callback function (if there is one) to determine 'junk' characters. + * @param array $options */ public function __construct($a, $b, $junkCallback=null, $options) { @@ -207,6 +216,7 @@ private function chainB() * Checks if a particular character is in the junk dictionary * for the list of junk characters. * + * @param string $b * @return boolean $b True if the character is considered junk. False if not. */ private function isBJunk($b) @@ -285,7 +295,7 @@ public function findLongestMatch($alo, $ahi, $blo, $bhi) } while($bestI > $alo && $bestJ > $blo && $this->isBJunk($b[$bestJ - 1]) && - !$this->isLineDifferent($bestI - 1, $bestJ - 1)) { + !$this->linesAreDifferent($bestI - 1, $bestJ - 1)) { --$bestI; --$bestJ; ++$bestSize; @@ -533,18 +543,18 @@ public function getGroupedOpcodes($context=3) ); } - if($opCodes[0][0] == 'equal') { - $opCodes[0] = array( - $opCodes[0][0], - max($opCodes[0][1], $opCodes[0][2] - $context), - $opCodes[0][2], - max($opCodes[0][3], $opCodes[0][4] - $context), - $opCodes[0][4] + if($opCodes['0']['0'] == 'equal') { + $opCodes['0'] = array( + $opCodes['0']['0'], + max($opCodes['0']['1'], $opCodes['0']['2'] - $context), + $opCodes['0']['2'], + max($opCodes['0']['3'], $opCodes['0']['4'] - $context), + $opCodes['0']['4'] ); } $lastItem = count($opCodes) - 1; - if($opCodes[$lastItem][0] == 'equal') { + if($opCodes[$lastItem]['0'] == 'equal') { list($tag, $i1, $i2, $j1, $j2) = $opCodes[$lastItem]; $opCodes[$lastItem] = array( $tag, @@ -582,7 +592,7 @@ public function getGroupedOpcodes($context=3) ); } - if(!empty($group) && !(count($group) == 1 && $group[0][0] == 'equal')) { + if(!empty($group) && !(count($group) == 1 && $group['0']['0'] == 'equal')) { $groups[] = $group; } @@ -595,8 +605,7 @@ public function getGroupedOpcodes($context=3) * * Out of all of the ratio calculation functions, this is the most * expensive to call if getMatchingBlocks or getOpCodes is yet to be - * called. The other calculation methods (quickRatio and realquickRatio) - * can be used to perform quicker calculations but may be less accurate. + * called. * * The ratio is calculated as (2 * number of matches) / total number of * elements in both sequences. @@ -621,57 +630,6 @@ private function ratioReduce($sum, $triple) return $sum + ($triple[count($triple) - 1]); } - /** - * Quickly return an upper bound ratio for the similarity of the strings. - * This is quicker to compute than Ratio(). - * - * @return float The calculated ratio. - */ - private function quickRatio() - { - if($this->fullBCount === null) { - $this->fullBCount = array(); - $bLength = count ($b); - for($i = 0; $i < $bLength; ++$i) { - $char = $this->b[$i]; - $this->fullBCount[$char] = $this->arrayGetDefault($this->fullBCount, $char, 0) + 1; - } - } - - $avail = array(); - $matches = 0; - $aLength = count ($this->a); - for($i = 0; $i < $aLength; ++$i) { - $char = $this->a[$i]; - if(isset($avail[$char])) { - $numb = $avail[$char]; - } - else { - $numb = $this->arrayGetDefault($this->fullBCount, $char, 0); - } - $avail[$char] = $numb - 1; - if($numb > 0) { - ++$matches; - } - } - - $this->calculateRatio($matches, count ($this->a) + count ($this->b)); - } - - /** - * Return an upper bound ratio really quickly for the similarity of the strings. - * This is quicker to compute than Ratio() and quickRatio(). - * - * @return float The calculated ratio. - */ - private function realquickRatio() - { - $aLength = count ($this->a); - $bLength = count ($this->b); - - return $this->calculateRatio(min($aLength, $bLength), $aLength + $bLength); - } - /** * Helper function for calculating the ratio to measure similarity for the strings. * The ratio is defined as being 2 * (number of matches / total length) @@ -729,7 +687,7 @@ private function tupleSort($a, $b) } } - if(count($a) == $count($b)) { + if(count($a) == count($b)) { return 0; } else if(count($a) < count($b)) { @@ -739,4 +697,4 @@ private function tupleSort($a, $b) return 1; } } -} \ No newline at end of file +}