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:
2019-03-01 13:30:20 +00:00
parent 38b8b4f5a6
commit ae306d19ba
2 changed files with 158 additions and 1 deletions

114
xdiff.php
View File

@@ -29,6 +29,14 @@ class xdiff
*/
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.
* @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
* @param string $string1 The first 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
* position $i for $array1 and $j for array2
* Return empty string if no common lines was found