Patch reader
Misschien een nuttig script voor diegene die zich met 'patches' bezig houdt. Je kan er de verschillen in een patch-bestand mee uitlezen. Ikzelf gebruik dit voor een systeem die ik aan het bouwen ben om wijzigingen aan artikelen op mijn site bij te houden. Een uitgebreider script met een toffe class om de patches mee te genereren en op te slaan volgt later. Het script is openbaar deels afkomstig uit het vroegere MyReact forumsoftware, dus mijn credits gaan naar die makers. Als download vind je de functie, een proef-patch, en wat CSS om de HTML mooie duidelijke opmaak mee te geven met het laten zien van de wijzigingen. Doorstreept voor verwijderde tekst, en rood voor aangepaste tekst. Wat is 'patch' nou? In het Linux-besturingssysteem, maar met wat zoeken ook voor Windows geschikt, of in de Windows Subsystem for Linux (WSL), is "patch" een opdracht waarmee we patchbestanden kunnen toepassen op de broncodes of configuratiebestanden. Het patchbestand wordt gebruikt voor software- of sourceupdates. Het verschil tussen de originele en nieuwe bestanden wordt bewaard in dergelijke patch-bestanden en normaal wordt de opdracht "diff" wordt gebruikt om het verschil of de patch te krijgen. Maar dit script visualiseert dit.
<?php
$string = "*** a.txt 2021-01-03 21:04:05.547897800 +0100
--- b.txt 2021-01-03 21:04:05.563893700 +0100
***************
*** 1,4 ****
Huis
! Tuin
Keukendeur
! Bloemetjesgordijn
\ No newline at end of file
--- 1,6 ----
Huis
! Tuintje
Keukendeur
! Raamkozijn
! Bloemetjesgordijn
! Stofzuiger
\ No newline at end of file
";
function diff_styled($diff) {
$diff_pattern = "/\*{3}\s([\d,]+)\s\*{4}\s?(.*)-{3}\s([\d,]+)\s-{4}\s?(.*)$/s";
$line_pattern = "/^[\r\n]?([ \-+!])\s(.*)$/m";
$result = '';
$diff = preg_split("/\*{15}/", htmlentities($diff));
for ($block_nr=1; $block_nr<count($diff); $block_nr++)
{
if (!preg_match($diff_pattern, $diff[$block_nr], $block))
break;
preg_match_all($line_pattern, $block[2], $new, PREG_SET_ORDER);
preg_match_all($line_pattern, $block[4], $old, PREG_SET_ORDER);
$result .= "<pre class=\"diff\"><address>" . diff_lines($block[3], $block[1]) . ":</address>";
$old_line = $new_line = 0;
while ($old_line<count($old) || $new_line<count($new))
{
$match = ($old[$old_line] ? $old[$old_line][1] : " ") . ($new[$new_line] ? $new[$new_line][1] : " ");
switch ($match)
{
case " ":
case " ":
$result .= ($old[$old_line] ? $old[$old_line][2] : $new[$new_line][2]);
$old_line++; $new_line++; break;
case "+ ":
case "! ":
$result .= "<del>" . $old[$old_line][2] . "</del>";
$old_line++; break;
case " -":
case " !":
$result .= "<ins>" . $new[$new_line][2] . "</ins>";
$new_line++; break;
case "!!":
$result .= "<del>" . $old[$old_line][2] . "</del>";
$result .= "<ins>" . $new[$new_line][2] . "</ins>";
$old_line++; $new_line++; break;
default:
$result .= "Error: Unknown '" . $match . "'\n";
$result .= $old[$old_line][2];
$result .= $new[$new_line][2];
$old_line++; $new_line++;
}
}
$result .= "";
}
return $result;
}
function diff_lines($lines_old, $lines_new) {
$lines_old = explode(",", $lines_old);
$lines_new = explode(",", $lines_new);
$lines_start = min($lines_old[0], $lines_new[0]);
$lines_stop = max($lines_old[1], $lines_new[1]);
$lines_count = ($lines_new[1] - $lines_new[0]) - ($lines_old[1] - $lines_old[0]);
#print_r($lines_old);
#print_r($lines_new);
if (!$lines_stop)
$result = sprintf("Regel %u", $lines_start);
else
$result = sprintf("Regels %u t/m %u", $lines_start, $lines_stop);
if ($lines_count)
if ($lines_count == 1 || $lines_count == -1)
$result .= sprintf(" (%+d regel)", $lines_count);
else
$result .= sprintf(" (%+d regels)", $lines_count);
return $result;
}
echo diff_styled($string);
?>
*** a.txt 2021-01-03 21:04:05.547897800 +0100
--- b.txt 2021-01-03 21:04:05.563893700 +0100
***************
*** 1,4 ****
Huis
! Tuin
Keukendeur
! Bloemetjesgordijn
\ No newline at end of file
--- 1,6 ----
Huis
! Tuintje
Keukendeur
! Raamkozijn
! Bloemetjesgordijn
! Stofzuiger
\ No newline at end of file
pre.diff {
overflow: auto;
border: 1px solid #000000;
}
pre.diff ins,
pre.diff del {
display: block;
text-decoration: none;
}
pre.diff ins {
background-color: #88ff88;
}
pre.diff del {
background-color: #ff8888;
}
pre.diff address {
font-style: normal;
border-bottom: 1px solid #000000;
background-color: #eeeeee;
}
Reacties
0