MediaWiki master
DiffFormatter.php
Go to the documentation of this file.
1<?php
27namespace Wikimedia\Diff;
28
29use UnexpectedValueException;
30
40abstract class DiffFormatter {
41
47 protected $leadingContextLines = 0;
48
54 protected $trailingContextLines = 0;
55
57 private $result = '';
58
66 public function format( $diff ) {
67 $xi = $yi = 1;
68 $block = false;
69 $context = [];
70
73
74 $this->startDiff();
75
76 // Initialize $x0 and $y0 to prevent IDEs from getting confused.
77 $x0 = $y0 = 0;
78 foreach ( $diff->edits as $edit ) {
79 if ( $edit->type == 'copy' ) {
80 if ( is_array( $block ) ) {
81 if ( count( $edit->orig ) <= $nlead + $ntrail ) {
82 $block[] = $edit;
83 } else {
84 if ( $ntrail ) {
85 $context = array_slice( $edit->orig, 0, $ntrail );
86 $block[] = new DiffOpCopy( $context );
87 }
88 $this->block( $x0, $ntrail + $xi - $x0,
89 $y0, $ntrail + $yi - $y0,
90 $block );
91 $block = false;
92 }
93 }
94 $context = $edit->orig;
95 } else {
96 if ( !is_array( $block ) ) {
97 $context = array_slice( $context, count( $context ) - $nlead );
98 $x0 = $xi - count( $context );
99 $y0 = $yi - count( $context );
100 $block = [];
101 if ( $context ) {
102 $block[] = new DiffOpCopy( $context );
103 }
104 }
105 $block[] = $edit;
106 }
107
108 if ( $edit->orig ) {
109 $xi += count( $edit->orig );
110 }
111 if ( $edit->closing ) {
112 $yi += count( $edit->closing );
113 }
114 }
115
116 if ( is_array( $block ) ) {
117 $this->block( $x0, $xi - $x0,
118 $y0, $yi - $y0,
119 $block );
120 }
121
122 $end = $this->endDiff();
123
124 return $end;
125 }
126
134 protected function block( $xbeg, $xlen, $ybeg, $ylen, &$edits ) {
135 $this->startBlock( $this->blockHeader( $xbeg, $xlen, $ybeg, $ylen ) );
136 foreach ( $edits as $edit ) {
137 if ( $edit->type == 'copy' ) {
138 $this->context( $edit->orig );
139 } elseif ( $edit->type == 'add' ) {
140 $this->added( $edit->closing );
141 } elseif ( $edit->type == 'delete' ) {
142 $this->deleted( $edit->orig );
143 } elseif ( $edit->type == 'change' ) {
144 $this->changed( $edit->orig, $edit->closing );
145 } else {
146 throw new UnexpectedValueException( "Unknown edit type: {$edit->type}" );
147 }
148 }
149 $this->endBlock();
150 }
151
152 protected function startDiff() {
153 $this->result = '';
154 }
155
161 protected function writeOutput( $text ) {
162 $this->result .= $text;
163 }
164
168 protected function endDiff() {
169 $val = $this->result;
170 $this->result = '';
171
172 return $val;
173 }
174
183 protected function blockHeader( $xbeg, $xlen, $ybeg, $ylen ) {
184 if ( $xlen > 1 ) {
185 $xbeg .= ',' . ( $xbeg + $xlen - 1 );
186 }
187 if ( $ylen > 1 ) {
188 $ybeg .= ',' . ( $ybeg + $ylen - 1 );
189 }
190
191 return $xbeg . ( $xlen ? ( $ylen ? 'c' : 'd' ) : 'a' ) . $ybeg;
192 }
193
200 protected function startBlock( $header ) {
201 $this->writeOutput( $header . "\n" );
202 }
203
208 protected function endBlock() {
209 }
210
217 protected function lines( $lines, $prefix = ' ' ) {
218 foreach ( $lines as $line ) {
219 $this->writeOutput( "$prefix $line\n" );
220 }
221 }
222
226 protected function context( $lines ) {
227 $this->lines( $lines );
228 }
229
233 protected function added( $lines ) {
234 $this->lines( $lines, '>' );
235 }
236
240 protected function deleted( $lines ) {
241 $this->lines( $lines, '<' );
242 }
243
250 protected function changed( $orig, $closing ) {
251 $this->deleted( $orig );
252 $this->writeOutput( "---\n" );
253 $this->added( $closing );
254 }
255
256}
257
259class_alias( DiffFormatter::class, 'DiffFormatter' );
Base class for diff formatters.
startBlock( $header)
Called at the start of a block of connected edits.
int $leadingContextLines
Number of leading context "lines" to preserve.
lines( $lines, $prefix=' ')
Writes all (optionally prefixed) lines to the output buffer, separated by newlines.
int $trailingContextLines
Number of trailing context "lines" to preserve.
changed( $orig, $closing)
Writes the two sets of lines to the output buffer, separated by "---" and a newline.
writeOutput( $text)
Writes a string to the output buffer.
endBlock()
Called at the end of a block of connected edits.
block( $xbeg, $xlen, $ybeg, $ylen, &$edits)
format( $diff)
Format a diff.
blockHeader( $xbeg, $xlen, $ybeg, $ylen)
if(!file_exists( $CREDITS)) $lines
$header