Create New Item
Item Type
File
Folder
Item Name
Search file in folder and subfolders...
Are you sure want to rename?
gilour
/
vendor
/
jfcherng
/
php-diff
/
src
/
Renderer
/
Html
:
Inline.php
Advanced Search
Upload
New Item
Settings
Back
Back Up
Advanced Editor
Save
<?php declare(strict_types=1); namespace Jfcherng\Diff\Renderer\Html; use Jfcherng\Diff\SequenceMatcher; /** * Inline HTML diff generator. */ final class Inline extends AbstractHtml { /** * {@inheritdoc} */ public const INFO = [ 'desc' => 'Inline', 'type' => 'Html', ]; /** * {@inheritdoc} */ protected function redererChanges(array $changes): string { if (empty($changes)) { return $this->getResultForIdenticals(); } $wrapperClasses = [ ...$this->options['wrapperClasses'], 'diff', 'diff-html', 'diff-inline', ]; return '<table class="' . implode(' ', $wrapperClasses) . '">' . $this->renderTableHeader() . $this->renderTableHunks($changes) . '</table>'; } /** * Renderer the table header. */ protected function renderTableHeader(): string { if (!$this->options['showHeader']) { return ''; } $colspan = $this->options['lineNumbers'] ? '' : ' colspan="2"'; return '<thead>' . '<tr>' . ( $this->options['lineNumbers'] ? '<th>' . $this->_('old_version') . '</th>' . '<th>' . $this->_('new_version') . '</th>' . '<th></th>' // diff symbol column : '' ) . '<th' . $colspan . '>' . $this->_('differences') . '</th>' . '</tr>' . '</thead>'; } /** * Renderer the table separate block. */ protected function renderTableSeparateBlock(): string { $colspan = $this->options['lineNumbers'] ? '4' : '2'; return '<tbody class="skipped">' . '<tr>' . '<td colspan="' . $colspan . '"></td>' . '</tr>' . '</tbody>'; } /** * Renderer table hunks. * * @param array[][] $hunks each hunk has many blocks */ protected function renderTableHunks(array $hunks): string { $ret = ''; foreach ($hunks as $i => $hunk) { if ($i > 0 && $this->options['separateBlock']) { $ret .= $this->renderTableSeparateBlock(); } foreach ($hunk as $block) { $ret .= $this->renderTableBlock($block); } } return $ret; } /** * Renderer the table block. * * @param array $block the block */ protected function renderTableBlock(array $block): string { switch ($block['tag']) { case SequenceMatcher::OP_EQ: $content = $this->renderTableBlockEqual($block); break; case SequenceMatcher::OP_INS: $content = $this->renderTableBlockInsert($block); break; case SequenceMatcher::OP_DEL: $content = $this->renderTableBlockDelete($block); break; case SequenceMatcher::OP_REP: $content = $this->renderTableBlockReplace($block); break; default: $content = ''; } return '<tbody class="change change-' . self::TAG_CLASS_MAP[$block['tag']] . '">' . $content . '</tbody>'; } /** * Renderer the table block: equal. * * @param array $block the block */ protected function renderTableBlockEqual(array $block): string { $ret = ''; // note that although we are in a OP_EQ situation, // the old and the new may not be exactly the same // because of ignoreCase, ignoreWhitespace, etc foreach ($block['new']['lines'] as $no => $newLine) { // we could only pick either the old or the new to show // here we pick the new one to let the user know what it is now $ret .= $this->renderTableRow( 'new', SequenceMatcher::OP_EQ, $newLine, $block['old']['offset'] + $no + 1, $block['new']['offset'] + $no + 1, ); } return $ret; } /** * Renderer the table block: insert. * * @param array $block the block */ protected function renderTableBlockInsert(array $block): string { $ret = ''; foreach ($block['new']['lines'] as $no => $newLine) { $ret .= $this->renderTableRow( 'new', SequenceMatcher::OP_INS, $newLine, null, $block['new']['offset'] + $no + 1, ); } return $ret; } /** * Renderer the table block: delete. * * @param array $block the block */ protected function renderTableBlockDelete(array $block): string { $ret = ''; foreach ($block['old']['lines'] as $no => $oldLine) { $ret .= $this->renderTableRow( 'old', SequenceMatcher::OP_DEL, $oldLine, $block['old']['offset'] + $no + 1, null, ); } return $ret; } /** * Renderer the table block: replace. * * @param array $block the block */ protected function renderTableBlockReplace(array $block): string { return $this->renderTableBlockDelete($block) . $this->renderTableBlockInsert($block); } /** * Renderer a content row of the output table. * * @param string $tdClass the <td> class * @param int $op the operation * @param string $line the line * @param null|int $oldLineNum the old line number * @param null|int $newLineNum the new line number */ protected function renderTableRow( string $tdClass, int $op, string $line, ?int $oldLineNum, ?int $newLineNum ): string { return '<tr data-type="' . self::SYMBOL_MAP[$op] . '">' . ( $this->options['lineNumbers'] ? $this->renderLineNumberColumns($oldLineNum, $newLineNum) : '' ) . '<th class="sign ' . self::TAG_CLASS_MAP[$op] . '">' . self::SYMBOL_MAP[$op] . '</th>' . '<td class="' . $tdClass . '">' . $line . '</td>' . '</tr>'; } /** * Renderer the line number columns. * * @param null|int $oldLineNum The old line number * @param null|int $newLineNum The new line number */ protected function renderLineNumberColumns(?int $oldLineNum, ?int $newLineNum): string { return ( isset($oldLineNum) ? '<th class="n-old">' . $oldLineNum . '</th>' : '<th></th>' ) . ( isset($newLineNum) ? '<th class="n-new">' . $newLineNum . '</th>' : '<th></th>' ); } }