xdiff : side by side support with screen width parameter
git-svn-id: https://svn.fournier38.fr/svn/ProgSVN/trunk@5062 bf3deb0d-5f1a-0410-827f-c0cc1f45334c
This commit is contained in:
@@ -8,7 +8,6 @@
|
|||||||
class test_xdiff extends PHPUnit_Framework_TestCase
|
class test_xdiff extends PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
// Declaration of $string1 and $string2
|
// Declaration of $string1 and $string2
|
||||||
// Taken from
|
|
||||||
// {{{
|
// {{{
|
||||||
private $string1 = "This part of the
|
private $string1 = "This part of the
|
||||||
document has stayed the
|
document has stayed the
|
||||||
@@ -336,4 +335,48 @@ to this document.
|
|||||||
$this->setExpectedException ();
|
$this->setExpectedException ();
|
||||||
$res = $xdiff->diffFile ("/tmp/test_xdiff1", "/tmp/test_xdiffNOTEXISTS");
|
$res = $xdiff->diffFile ("/tmp/test_xdiff1", "/tmp/test_xdiffNOTEXISTS");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function test_diffFile_sideBySide_1 ()
|
||||||
|
{
|
||||||
|
file_put_contents ("/tmp/test_xdiff1", $this->string1);
|
||||||
|
file_put_contents ("/tmp/test_xdiff2", $this->string2);
|
||||||
|
$xdiff = new xdiff ("sideBySide");
|
||||||
|
$res = $xdiff->diffFile ("/tmp/test_xdiff1", "/tmp/test_xdiff2");
|
||||||
|
$this->assertSame ($res,
|
||||||
|
" > This is an important
|
||||||
|
> notice! It should
|
||||||
|
> therefore be located at
|
||||||
|
> the beginning of this
|
||||||
|
> document!
|
||||||
|
>
|
||||||
|
This part of the This part of the
|
||||||
|
document has stayed the document has stayed the
|
||||||
|
same from version to same from version to
|
||||||
|
version. It shouldn't version. It shouldn't
|
||||||
|
be shown if it doesn't be shown if it doesn't
|
||||||
|
change. Otherwise, that change. Otherwise, that
|
||||||
|
would not be helping to would not be helping to
|
||||||
|
compress the size of the compress the size of the
|
||||||
|
changes. changes.
|
||||||
|
|
||||||
|
This paragraph contains <
|
||||||
|
text that is outdated. <
|
||||||
|
It will be deleted in the <
|
||||||
|
near future. <
|
||||||
|
<
|
||||||
|
It is important to spell It is important to spell
|
||||||
|
check this dokument. On | check this document. On
|
||||||
|
the other hand, a the other hand, a
|
||||||
|
misspelled word isn't misspelled word isn't
|
||||||
|
the end of the world. the end of the world.
|
||||||
|
Nothing in the rest of Nothing in the rest of
|
||||||
|
this paragraph needs to this paragraph needs to
|
||||||
|
be changed. Things can be changed. Things can
|
||||||
|
be added after it. be added after it.
|
||||||
|
>
|
||||||
|
> This paragraph contains
|
||||||
|
> important new additions
|
||||||
|
> to this document.
|
||||||
|
");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
114
xdiff.php
114
xdiff.php
@@ -29,6 +29,14 @@ class xdiff
|
|||||||
*/
|
*/
|
||||||
private $output = null;
|
private $output = null;
|
||||||
|
|
||||||
|
/** Define the size of one column in side by side mode
|
||||||
|
* 62 chars by default
|
||||||
|
* The maximum width used on screen is 2*$s2sWidth+2 (134 by default)
|
||||||
|
* The value must validate $s2sWidth = 8 * X - 2 (with X is integer), like
|
||||||
|
* 6, 14, 22, 30, 38, 46, 54, 62, 70, 78, 86, 94, 102
|
||||||
|
*/
|
||||||
|
private $s2sWidth = 62;
|
||||||
|
|
||||||
/** The constructor allow to choose the output.
|
/** The constructor allow to choose the output.
|
||||||
* @param string $output The output mode [normal|unified]
|
* @param string $output The output mode [normal|unified]
|
||||||
*/
|
*/
|
||||||
@@ -43,6 +51,24 @@ class xdiff
|
|||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
|
/** Allow to set the side by side width to the maximum allowed by screenWidth
|
||||||
|
* @param integer $screenWidth The maximum width of the screen
|
||||||
|
*/
|
||||||
|
public function setScreenWidth ($screenWidth)
|
||||||
|
// {{{
|
||||||
|
{
|
||||||
|
for ($x = 20 ; $x > 0 ; $x--)
|
||||||
|
{
|
||||||
|
$s2sWidth = 8 * $x - 2;
|
||||||
|
if (2*$s2sWidth+2 <= $screenWidth)
|
||||||
|
{
|
||||||
|
$this->s2sWidth = $s2sWidth;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
/** Compute the differences between two strings $string1 and $string2
|
/** Compute the differences between two strings $string1 and $string2
|
||||||
* @param string $string1 The first string to compare
|
* @param string $string1 The first string to compare
|
||||||
* @param string $string2 The second string to compare
|
* @param string $string2 The second string to compare
|
||||||
@@ -356,6 +382,94 @@ class xdiff
|
|||||||
}
|
}
|
||||||
// }}}
|
// }}}
|
||||||
|
|
||||||
|
/** Return a string like "diff -y" (Side by Side)
|
||||||
|
* @param array $diffArray The diff array analyzed by diffArray method
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
private function displaySideBySide ($diffArray)
|
||||||
|
// {{{
|
||||||
|
{
|
||||||
|
$d = "";
|
||||||
|
$i = 0 ;
|
||||||
|
while ($i < count ($diffArray))
|
||||||
|
{
|
||||||
|
$diff = $diffArray[$i];
|
||||||
|
$i++;
|
||||||
|
if ($diff["type"] === "Equal")
|
||||||
|
{
|
||||||
|
foreach ($diff["chunk"] as $line)
|
||||||
|
$d .= $this->side ($line, $line);
|
||||||
|
}
|
||||||
|
elseif ($diff["type"] === "Append")
|
||||||
|
{
|
||||||
|
foreach ($diff["chunk"] as $line)
|
||||||
|
$d .= $this->side ("", $line, ">");
|
||||||
|
}
|
||||||
|
elseif ($diff["type"] === "Delete")
|
||||||
|
{
|
||||||
|
foreach ($diff["chunk"] as $line)
|
||||||
|
$d .= $this->side ($line, "", "<");
|
||||||
|
}
|
||||||
|
elseif ($diff["type"] === "Change")
|
||||||
|
{
|
||||||
|
$x = 0;
|
||||||
|
$y = 0;
|
||||||
|
while (key_exists ($x, $diff["chunk1"]) ||
|
||||||
|
key_exists ($y, $diff["chunk2"]))
|
||||||
|
{
|
||||||
|
$side1 = (key_exists ($x, $diff["chunk1"])) ?
|
||||||
|
$diff["chunk1"][$x] : "";
|
||||||
|
$side2 = (key_exists ($y, $diff["chunk2"])) ?
|
||||||
|
$diff["chunk2"][$y] : "";
|
||||||
|
$d .= $this->side ($side1, $side2, "|");
|
||||||
|
if ($side1 !== "")
|
||||||
|
$x++;
|
||||||
|
if ($side2 !== "")
|
||||||
|
$y++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $d;
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
|
/** Return a string sideBySide. Used by displaySideBySide for each line
|
||||||
|
* @param string $side1 The string to be displayed on side1
|
||||||
|
* @param string $side2 The string to be displayed on side2
|
||||||
|
* @param string|null $symbol The symbol used to present the diff (<>|)
|
||||||
|
*/
|
||||||
|
private function side ($side1, $side2, $symbol = null)
|
||||||
|
// {{{
|
||||||
|
{
|
||||||
|
$d = "";
|
||||||
|
if (! is_string ($side1))
|
||||||
|
throw new \Exception ("XDiff : side1 parameter not a string");
|
||||||
|
if (! is_string ($side2))
|
||||||
|
throw new \Exception ("XDiff : side2 parameter not a string");
|
||||||
|
if (trim ($symbol) === "")
|
||||||
|
$symbol = null;
|
||||||
|
$side1 = mb_substr (rtrim ($side1), 0, $this->s2sWidth - 1);
|
||||||
|
$side2 = mb_substr (rtrim ($side2), 0, $this->s2sWidth - 1);
|
||||||
|
$d .= $side1;
|
||||||
|
$nbtabs = floor ((1 + $this->s2sWidth - mb_strlen ($side1)) / 8);
|
||||||
|
if ($symbol !== null || $side2 !== "")
|
||||||
|
$d .= str_repeat ("\t", $nbtabs);
|
||||||
|
if ($side1 !== "" && $symbol === null)
|
||||||
|
$d .= "\t";
|
||||||
|
elseif ($symbol !== null)
|
||||||
|
{
|
||||||
|
if (mb_strlen ($side1) < $this->s2sWidth - 1)
|
||||||
|
$d .= str_repeat (" ", 5);
|
||||||
|
$d .= " ".$symbol;
|
||||||
|
}
|
||||||
|
if ($symbol !== null && $side2 !== "")
|
||||||
|
$d .= "\t";
|
||||||
|
$d .= $side2;
|
||||||
|
$d .= "\n";
|
||||||
|
return $d;
|
||||||
|
}
|
||||||
|
// }}}
|
||||||
|
|
||||||
/** This function return the next common part between both arrays starting at
|
/** This function return the next common part between both arrays starting at
|
||||||
* position $i for $array1 and $j for array2
|
* position $i for $array1 and $j for array2
|
||||||
* Return empty string if no common lines was found
|
* Return empty string if no common lines was found
|
||||||
|
|||||||
Reference in New Issue
Block a user