annotate core/lib/Drupal/Component/Diff/DiffFormatter.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 4c8ae668cc8c
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Component\Diff;
Chris@0 4
Chris@0 5 use Drupal\Component\Diff\Engine\DiffOpCopy;
Chris@0 6
Chris@0 7 /**
Chris@0 8 * A class to format Diffs
Chris@0 9 *
Chris@0 10 * This class formats the diff in classic diff format.
Chris@0 11 * It is intended that this class be customized via inheritance,
Chris@0 12 * to obtain fancier outputs.
Chris@0 13 * @todo document
Chris@0 14 * @private
Chris@0 15 * @subpackage DifferenceEngine
Chris@0 16 */
Chris@0 17 class DiffFormatter {
Chris@0 18 /**
Chris@0 19 * Should a block header be shown?
Chris@0 20 */
Chris@0 21 public $show_header = TRUE;
Chris@0 22
Chris@0 23 /**
Chris@0 24 * Number of leading context "lines" to preserve.
Chris@0 25 *
Chris@0 26 * This should be left at zero for this class, but subclasses
Chris@0 27 * may want to set this to other values.
Chris@0 28 */
Chris@0 29 public $leading_context_lines = 0;
Chris@0 30
Chris@0 31 /**
Chris@0 32 * Number of trailing context "lines" to preserve.
Chris@0 33 *
Chris@0 34 * This should be left at zero for this class, but subclasses
Chris@0 35 * may want to set this to other values.
Chris@0 36 */
Chris@0 37 public $trailing_context_lines = 0;
Chris@0 38
Chris@0 39 /**
Chris@0 40 * The line stats.
Chris@0 41 *
Chris@0 42 * @var array
Chris@0 43 */
Chris@0 44 protected $line_stats = [
Chris@0 45 'counter' => ['x' => 0, 'y' => 0],
Chris@0 46 'offset' => ['x' => 0, 'y' => 0],
Chris@0 47 ];
Chris@0 48
Chris@0 49 /**
Chris@0 50 * Format a diff.
Chris@0 51 *
Chris@0 52 * @param \Drupal\Component\Diff\Diff $diff
Chris@0 53 * A Diff object.
Chris@0 54 *
Chris@0 55 * @return string
Chris@0 56 * The formatted output.
Chris@0 57 */
Chris@0 58 public function format(Diff $diff) {
Chris@0 59 $xi = $yi = 1;
Chris@0 60 $block = FALSE;
Chris@0 61 $context = [];
Chris@0 62
Chris@0 63 $nlead = $this->leading_context_lines;
Chris@0 64 $ntrail = $this->trailing_context_lines;
Chris@0 65
Chris@0 66 $this->_start_diff();
Chris@0 67
Chris@0 68 foreach ($diff->getEdits() as $edit) {
Chris@0 69 if ($edit->type == 'copy') {
Chris@0 70 if (is_array($block)) {
Chris@0 71 if (sizeof($edit->orig) <= $nlead + $ntrail) {
Chris@0 72 $block[] = $edit;
Chris@0 73 }
Chris@0 74 else {
Chris@0 75 if ($ntrail) {
Chris@0 76 $context = array_slice($edit->orig, 0, $ntrail);
Chris@0 77 $block[] = new DiffOpCopy($context);
Chris@0 78 }
Chris@0 79 $this->_block($x0, $ntrail + $xi - $x0, $y0, $ntrail + $yi - $y0, $block);
Chris@0 80 $block = FALSE;
Chris@0 81 }
Chris@0 82 }
Chris@0 83 $context = $edit->orig;
Chris@0 84 }
Chris@0 85 else {
Chris@0 86 if (!is_array($block)) {
Chris@0 87 $context = array_slice($context, sizeof($context) - $nlead);
Chris@0 88 $x0 = $xi - sizeof($context);
Chris@0 89 $y0 = $yi - sizeof($context);
Chris@0 90 $block = [];
Chris@0 91 if ($context) {
Chris@0 92 $block[] = new DiffOpCopy($context);
Chris@0 93 }
Chris@0 94 }
Chris@0 95 $block[] = $edit;
Chris@0 96 }
Chris@0 97
Chris@0 98 if ($edit->orig) {
Chris@0 99 $xi += sizeof($edit->orig);
Chris@0 100 }
Chris@0 101 if ($edit->closing) {
Chris@0 102 $yi += sizeof($edit->closing);
Chris@0 103 }
Chris@0 104 }
Chris@0 105
Chris@0 106 if (is_array($block)) {
Chris@0 107 $this->_block($x0, $xi - $x0, $y0, $yi - $y0, $block);
Chris@0 108 }
Chris@0 109 $end = $this->_end_diff();
Chris@0 110
Chris@0 111 if (!empty($xi)) {
Chris@0 112 $this->line_stats['counter']['x'] += $xi;
Chris@0 113 }
Chris@0 114 if (!empty($yi)) {
Chris@0 115 $this->line_stats['counter']['y'] += $yi;
Chris@0 116 }
Chris@0 117
Chris@0 118 return $end;
Chris@0 119 }
Chris@0 120
Chris@0 121 protected function _block($xbeg, $xlen, $ybeg, $ylen, &$edits) {
Chris@0 122 $this->_start_block($this->_block_header($xbeg, $xlen, $ybeg, $ylen));
Chris@0 123 foreach ($edits as $edit) {
Chris@0 124 if ($edit->type == 'copy') {
Chris@0 125 $this->_context($edit->orig);
Chris@0 126 }
Chris@0 127 elseif ($edit->type == 'add') {
Chris@0 128 $this->_added($edit->closing);
Chris@0 129 }
Chris@0 130 elseif ($edit->type == 'delete') {
Chris@0 131 $this->_deleted($edit->orig);
Chris@0 132 }
Chris@0 133 elseif ($edit->type == 'change') {
Chris@0 134 $this->_changed($edit->orig, $edit->closing);
Chris@0 135 }
Chris@0 136 else {
Chris@0 137 trigger_error('Unknown edit type', E_USER_ERROR);
Chris@0 138 }
Chris@0 139 }
Chris@0 140 $this->_end_block();
Chris@0 141 }
Chris@0 142
Chris@0 143 protected function _start_diff() {
Chris@0 144 ob_start();
Chris@0 145 }
Chris@0 146
Chris@0 147 protected function _end_diff() {
Chris@0 148 $val = ob_get_contents();
Chris@0 149 ob_end_clean();
Chris@0 150 return $val;
Chris@0 151 }
Chris@0 152
Chris@0 153 protected function _block_header($xbeg, $xlen, $ybeg, $ylen) {
Chris@0 154 if ($xlen > 1) {
Chris@0 155 $xbeg .= "," . ($xbeg + $xlen - 1);
Chris@0 156 }
Chris@0 157 if ($ylen > 1) {
Chris@0 158 $ybeg .= "," . ($ybeg + $ylen - 1);
Chris@0 159 }
Chris@0 160
Chris@0 161 return $xbeg . ($xlen ? ($ylen ? 'c' : 'd') : 'a') . $ybeg;
Chris@0 162 }
Chris@0 163
Chris@0 164 protected function _start_block($header) {
Chris@0 165 if ($this->show_header) {
Chris@0 166 echo $header . "\n";
Chris@0 167 }
Chris@0 168 }
Chris@0 169
Chris@0 170 protected function _end_block() {
Chris@0 171 }
Chris@0 172
Chris@0 173 protected function _lines($lines, $prefix = ' ') {
Chris@0 174 foreach ($lines as $line) {
Chris@0 175 echo "$prefix $line\n";
Chris@0 176 }
Chris@0 177 }
Chris@0 178
Chris@0 179 protected function _context($lines) {
Chris@0 180 $this->_lines($lines);
Chris@0 181 }
Chris@0 182
Chris@0 183 protected function _added($lines) {
Chris@0 184 $this->_lines($lines, '>');
Chris@0 185 }
Chris@0 186
Chris@0 187 protected function _deleted($lines) {
Chris@0 188 $this->_lines($lines, '<');
Chris@0 189 }
Chris@0 190
Chris@0 191 protected function _changed($orig, $closing) {
Chris@0 192 $this->_deleted($orig);
Chris@0 193 echo "---\n";
Chris@0 194 $this->_added($closing);
Chris@0 195 }
Chris@0 196
Chris@0 197 }