ミラーる
This commit is contained in:
@@ -1,130 +1,130 @@
|
||||
<?php
|
||||
namespace Site\Lib;
|
||||
|
||||
class DiffViewer {
|
||||
private $diffContent;
|
||||
|
||||
public function __construct(string $filePath) {
|
||||
if (!file_exists($filePath)) {
|
||||
throw new \Exception("Diff file not found: $filePath");
|
||||
}
|
||||
$this->diffContent = file_get_contents($filePath);
|
||||
}
|
||||
|
||||
public function displaySideBySide(): string {
|
||||
$lines = explode("\n", $this->diffContent);
|
||||
$fileDiffs = [];
|
||||
$currentFile = null;
|
||||
$hunk = [];
|
||||
$lineNumbers = ['left' => 0, 'right' => 0];
|
||||
$currentLeftLines = [];
|
||||
$currentRightLines = [];
|
||||
|
||||
foreach ($lines as $line) {
|
||||
// ファイルヘッダーの処理
|
||||
if (preg_match('/^---\s+(.+)/', $line, $matches)) {
|
||||
// ファイルを処理する場合、データを保存する
|
||||
if ($currentFile !== null) {
|
||||
$this->processHunk($hunk, $currentLeftLines, $currentRightLines, $lineNumbers);
|
||||
$fileDiffs[$currentFile] = [
|
||||
'leftLines' => $currentLeftLines,
|
||||
'rightLines' => $currentRightLines
|
||||
];
|
||||
$hunk = [];
|
||||
$currentLeftLines = [];
|
||||
$currentRightLines = [];
|
||||
$lineNumbers = ['left' => 0, 'right' => 0];
|
||||
}
|
||||
$currentFile = $matches[1];
|
||||
continue;
|
||||
}
|
||||
if (preg_match('/^\+\+\+\s+(.+)/', $line)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// ハンクヘッダーの処理 (例:@@ -10,6 +10,7 @@)
|
||||
if (preg_match('/^@@\s+-(\d+),\d+\s+\+(\d+),\d+\s+@@/', $line, $matches)) {
|
||||
$this->processHunk($hunk, $currentLeftLines, $currentRightLines, $lineNumbers);
|
||||
$hunk = [];
|
||||
$lineNumbers['left'] = (int)$matches[1];
|
||||
$lineNumbers['right'] = (int)$matches[2];
|
||||
continue;
|
||||
}
|
||||
|
||||
// ハンクでの行列の集まり
|
||||
if (substr($line, 0, 1) === '-' || substr($line, 0, 1) === '+' || substr($line, 0, 1) === ' ') {
|
||||
$hunk[] = $line;
|
||||
}
|
||||
}
|
||||
|
||||
// 最後のハンク・ファイルの処理
|
||||
if ($currentFile !== null) {
|
||||
$this->processHunk($hunk, $currentLeftLines, $currentRightLines, $lineNumbers);
|
||||
$fileDiffs[$currentFile] = [
|
||||
'leftLines' => $currentLeftLines,
|
||||
'rightLines' => $currentRightLines
|
||||
];
|
||||
}
|
||||
|
||||
// 各ファイルにHTMLの出力の作成
|
||||
$html = '';
|
||||
foreach ($fileDiffs as $fileName => $diff) {
|
||||
$html .= "<h2>ファイル: ".htmlspecialchars($fileName)."</h2>\n";
|
||||
$html .= $this->generateHtml($diff['leftLines'], $diff['rightLines']);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
private function processHunk(array $hunk, array &$leftLines, array &$rightLines, array &$lineNumbers): void {
|
||||
foreach ($hunk as $line) {
|
||||
$prefix = substr($line, 0, 1);
|
||||
$content = substr($line, 1);
|
||||
|
||||
if ($prefix === '-') {
|
||||
$leftLines[] = ['content' => htmlspecialchars($content), 'type' => 'removed', 'line' => $lineNumbers['left']];
|
||||
$lineNumbers['left']++;
|
||||
} elseif ($prefix === '+') {
|
||||
$rightLines[] = ['content' => htmlspecialchars($content), 'type' => 'added', 'line' => $lineNumbers['right']];
|
||||
$lineNumbers['right']++;
|
||||
} elseif ($prefix === ' ') {
|
||||
// 両側のコンテキストは同じ行列があるかの確認
|
||||
while ($lineNumbers['left'] < $lineNumbers['right']) {
|
||||
$leftLines[] = ['content' => '', 'type' => 'empty', 'line' => $lineNumbers['left']];
|
||||
$lineNumbers['left']++;
|
||||
}
|
||||
while ($lineNumbers['right'] < $lineNumbers['left']) {
|
||||
$rightLines[] = ['content' => '', 'type' => 'empty', 'line' => $lineNumbers['right']];
|
||||
$lineNumbers['right']++;
|
||||
}
|
||||
$leftLines[] = ['content' => htmlspecialchars($content), 'type' => 'context', 'line' => $lineNumbers['left']];
|
||||
$rightLines[] = ['content' => htmlspecialchars($content), 'type' => 'context', 'line' => $lineNumbers['right']];
|
||||
$lineNumbers['left']++;
|
||||
$lineNumbers['right']++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function generateHtml(array $leftLines, array $rightLines): string {
|
||||
$html = '<table class="diff-table">';
|
||||
$html .= '<tr class="diff-header"><th colspan="2">前</th><th colspan="2">新</th></tr>';
|
||||
|
||||
$maxLines = max(count($leftLines), count($rightLines));
|
||||
for ($i = 0; $i < $maxLines; $i++) {
|
||||
$left = isset($leftLines[$i]) ? $leftLines[$i] : ['content' => '', 'type' => 'empty', 'line' => ''];
|
||||
$right = isset($rightLines[$i]) ? $rightLines[$i] : ['content' => '', 'type' => 'empty', 'line' => ''];
|
||||
|
||||
$html .= '<tr>';
|
||||
// 左(変更前)
|
||||
$html .= '<td class="line-number">' . ($left['line'] ?: ' ') . '</td>';
|
||||
$html .= '<td class="' . $left['type'] . '">' . ($left['content'] ?: ' ') . '</td>';
|
||||
// 右(変更後)
|
||||
$html .= '<td class="line-number">' . ($right['line'] ?: ' ') . '</td>';
|
||||
$html .= '<td class="' . $right['type'] . '">' . ($right['content'] ?: ' ') . '</td>';
|
||||
$html .= '</tr>';
|
||||
}
|
||||
|
||||
$html .= '</table>';
|
||||
return $html;
|
||||
}
|
||||
<?php
|
||||
namespace Site\Lib;
|
||||
|
||||
class DiffViewer {
|
||||
private $diffContent;
|
||||
|
||||
public function __construct(string $filePath) {
|
||||
if (!file_exists($filePath)) {
|
||||
throw new \Exception("Diff file not found: $filePath");
|
||||
}
|
||||
$this->diffContent = file_get_contents($filePath);
|
||||
}
|
||||
|
||||
public function displaySideBySide(): string {
|
||||
$lines = explode("\n", $this->diffContent);
|
||||
$fileDiffs = [];
|
||||
$currentFile = null;
|
||||
$hunk = [];
|
||||
$lineNumbers = ['left' => 0, 'right' => 0];
|
||||
$currentLeftLines = [];
|
||||
$currentRightLines = [];
|
||||
|
||||
foreach ($lines as $line) {
|
||||
// ファイルヘッダーの処理
|
||||
if (preg_match('/^---\s+(.+)/', $line, $matches)) {
|
||||
// ファイルを処理する場合、データを保存する
|
||||
if ($currentFile !== null) {
|
||||
$this->processHunk($hunk, $currentLeftLines, $currentRightLines, $lineNumbers);
|
||||
$fileDiffs[$currentFile] = [
|
||||
'leftLines' => $currentLeftLines,
|
||||
'rightLines' => $currentRightLines
|
||||
];
|
||||
$hunk = [];
|
||||
$currentLeftLines = [];
|
||||
$currentRightLines = [];
|
||||
$lineNumbers = ['left' => 0, 'right' => 0];
|
||||
}
|
||||
$currentFile = $matches[1];
|
||||
continue;
|
||||
}
|
||||
if (preg_match('/^\+\+\+\s+(.+)/', $line)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// ハンクヘッダーの処理 (例:@@ -10,6 +10,7 @@)
|
||||
if (preg_match('/^@@\s+-(\d+),\d+\s+\+(\d+),\d+\s+@@/', $line, $matches)) {
|
||||
$this->processHunk($hunk, $currentLeftLines, $currentRightLines, $lineNumbers);
|
||||
$hunk = [];
|
||||
$lineNumbers['left'] = (int)$matches[1];
|
||||
$lineNumbers['right'] = (int)$matches[2];
|
||||
continue;
|
||||
}
|
||||
|
||||
// ハンクでの行列の集まり
|
||||
if (substr($line, 0, 1) === '-' || substr($line, 0, 1) === '+' || substr($line, 0, 1) === ' ') {
|
||||
$hunk[] = $line;
|
||||
}
|
||||
}
|
||||
|
||||
// 最後のハンク・ファイルの処理
|
||||
if ($currentFile !== null) {
|
||||
$this->processHunk($hunk, $currentLeftLines, $currentRightLines, $lineNumbers);
|
||||
$fileDiffs[$currentFile] = [
|
||||
'leftLines' => $currentLeftLines,
|
||||
'rightLines' => $currentRightLines
|
||||
];
|
||||
}
|
||||
|
||||
// 各ファイルにHTMLの出力の作成
|
||||
$html = '';
|
||||
foreach ($fileDiffs as $fileName => $diff) {
|
||||
$html .= "<h2>ファイル: ".htmlspecialchars($fileName)."</h2>\n";
|
||||
$html .= $this->generateHtml($diff['leftLines'], $diff['rightLines']);
|
||||
}
|
||||
|
||||
return $html;
|
||||
}
|
||||
|
||||
private function processHunk(array $hunk, array &$leftLines, array &$rightLines, array &$lineNumbers): void {
|
||||
foreach ($hunk as $line) {
|
||||
$prefix = substr($line, 0, 1);
|
||||
$content = substr($line, 1);
|
||||
|
||||
if ($prefix === '-') {
|
||||
$leftLines[] = ['content' => htmlspecialchars($content), 'type' => 'removed', 'line' => $lineNumbers['left']];
|
||||
$lineNumbers['left']++;
|
||||
} elseif ($prefix === '+') {
|
||||
$rightLines[] = ['content' => htmlspecialchars($content), 'type' => 'added', 'line' => $lineNumbers['right']];
|
||||
$lineNumbers['right']++;
|
||||
} elseif ($prefix === ' ') {
|
||||
// 両側のコンテキストは同じ行列があるかの確認
|
||||
while ($lineNumbers['left'] < $lineNumbers['right']) {
|
||||
$leftLines[] = ['content' => '', 'type' => 'empty', 'line' => $lineNumbers['left']];
|
||||
$lineNumbers['left']++;
|
||||
}
|
||||
while ($lineNumbers['right'] < $lineNumbers['left']) {
|
||||
$rightLines[] = ['content' => '', 'type' => 'empty', 'line' => $lineNumbers['right']];
|
||||
$lineNumbers['right']++;
|
||||
}
|
||||
$leftLines[] = ['content' => htmlspecialchars($content), 'type' => 'context', 'line' => $lineNumbers['left']];
|
||||
$rightLines[] = ['content' => htmlspecialchars($content), 'type' => 'context', 'line' => $lineNumbers['right']];
|
||||
$lineNumbers['left']++;
|
||||
$lineNumbers['right']++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function generateHtml(array $leftLines, array $rightLines): string {
|
||||
$html = '<table class="diff-table">';
|
||||
$html .= '<tr class="diff-header"><th colspan="2">前</th><th colspan="2">新</th></tr>';
|
||||
|
||||
$maxLines = max(count($leftLines), count($rightLines));
|
||||
for ($i = 0; $i < $maxLines; $i++) {
|
||||
$left = isset($leftLines[$i]) ? $leftLines[$i] : ['content' => '', 'type' => 'empty', 'line' => ''];
|
||||
$right = isset($rightLines[$i]) ? $rightLines[$i] : ['content' => '', 'type' => 'empty', 'line' => ''];
|
||||
|
||||
$html .= '<tr>';
|
||||
// 左(変更前)
|
||||
$html .= '<td class="line-number">' . ($left['line'] ?: ' ') . '</td>';
|
||||
$html .= '<td class="' . $left['type'] . '">' . ($left['content'] ?: ' ') . '</td>';
|
||||
// 右(変更後)
|
||||
$html .= '<td class="line-number">' . ($right['line'] ?: ' ') . '</td>';
|
||||
$html .= '<td class="' . $right['type'] . '">' . ($right['content'] ?: ' ') . '</td>';
|
||||
$html .= '</tr>';
|
||||
}
|
||||
|
||||
$html .= '</table>';
|
||||
return $html;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user