Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 71 |
|
0.00% |
0 / 13 |
CRAP | |
0.00% |
0 / 1 |
DiffFormatter | |
0.00% |
0 / 70 |
|
0.00% |
0 / 13 |
1122 | |
0.00% |
0 / 1 |
format | |
0.00% |
0 / 38 |
|
0.00% |
0 / 1 |
132 | |||
block | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
42 | |||
startDiff | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
writeOutput | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
endDiff | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 | |||
blockHeader | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
30 | |||
startBlock | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
endBlock | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
lines | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
context | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
added | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
deleted | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
changed | |
0.00% |
0 / 3 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | /** |
3 | * Base for diff rendering classes. Portions taken from phpwiki-1.3.3. |
4 | * |
5 | * Copyright © 2000, 2001 Geoffrey T. Dairiki <dairiki@dairiki.org> |
6 | * You may copy this code freely under the conditions of the GPL. |
7 | * |
8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License as published by |
10 | * the Free Software Foundation; either version 2 of the License, or |
11 | * (at your option) any later version. |
12 | * |
13 | * This program is distributed in the hope that it will be useful, |
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16 | * GNU General Public License for more details. |
17 | * |
18 | * You should have received a copy of the GNU General Public License along |
19 | * with this program; if not, write to the Free Software Foundation, Inc., |
20 | * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
21 | * http://www.gnu.org/copyleft/gpl.html |
22 | * |
23 | * @file |
24 | * @ingroup DifferenceEngine |
25 | */ |
26 | |
27 | namespace Wikimedia\Diff; |
28 | |
29 | use UnexpectedValueException; |
30 | |
31 | /** |
32 | * Base class for diff formatters |
33 | * |
34 | * This class formats the diff in classic diff format. |
35 | * It is intended that this class be customized via inheritance, |
36 | * to obtain fancier outputs. |
37 | * @todo document |
38 | * @ingroup DifferenceEngine |
39 | */ |
40 | abstract class DiffFormatter { |
41 | |
42 | /** @var int Number of leading context "lines" to preserve. |
43 | * |
44 | * This should be left at zero for this class, but subclasses |
45 | * may want to set this to other values. |
46 | */ |
47 | protected $leadingContextLines = 0; |
48 | |
49 | /** @var int Number of trailing context "lines" to preserve. |
50 | * |
51 | * This should be left at zero for this class, but subclasses |
52 | * may want to set this to other values. |
53 | */ |
54 | protected $trailingContextLines = 0; |
55 | |
56 | /** @var string The output buffer; holds the output while it is built. */ |
57 | private $result = ''; |
58 | |
59 | /** |
60 | * Format a diff. |
61 | * |
62 | * @param Diff $diff |
63 | * |
64 | * @return string The formatted output. |
65 | */ |
66 | public function format( $diff ) { |
67 | $xi = $yi = 1; |
68 | $block = false; |
69 | $context = []; |
70 | |
71 | $nlead = $this->leadingContextLines; |
72 | $ntrail = $this->trailingContextLines; |
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 | |
127 | /** |
128 | * @param int $xbeg |
129 | * @param int $xlen |
130 | * @param int $ybeg |
131 | * @param int $ylen |
132 | * @param array &$edits |
133 | */ |
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 | |
156 | /** |
157 | * Writes a string to the output buffer. |
158 | * |
159 | * @param string $text |
160 | */ |
161 | protected function writeOutput( $text ) { |
162 | $this->result .= $text; |
163 | } |
164 | |
165 | /** |
166 | * @return string |
167 | */ |
168 | protected function endDiff() { |
169 | $val = $this->result; |
170 | $this->result = ''; |
171 | |
172 | return $val; |
173 | } |
174 | |
175 | /** |
176 | * @param int $xbeg |
177 | * @param int $xlen |
178 | * @param int $ybeg |
179 | * @param int $ylen |
180 | * |
181 | * @return string |
182 | */ |
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 | |
194 | /** |
195 | * Called at the start of a block of connected edits. |
196 | * This default implementation writes the header and a newline to the output buffer. |
197 | * |
198 | * @param string $header |
199 | */ |
200 | protected function startBlock( $header ) { |
201 | $this->writeOutput( $header . "\n" ); |
202 | } |
203 | |
204 | /** |
205 | * Called at the end of a block of connected edits. |
206 | * This default implementation does nothing. |
207 | */ |
208 | protected function endBlock() { |
209 | } |
210 | |
211 | /** |
212 | * Writes all (optionally prefixed) lines to the output buffer, separated by newlines. |
213 | * |
214 | * @param string[] $lines |
215 | * @param string $prefix |
216 | */ |
217 | protected function lines( $lines, $prefix = ' ' ) { |
218 | foreach ( $lines as $line ) { |
219 | $this->writeOutput( "$prefix $line\n" ); |
220 | } |
221 | } |
222 | |
223 | /** |
224 | * @param string[] $lines |
225 | */ |
226 | protected function context( $lines ) { |
227 | $this->lines( $lines ); |
228 | } |
229 | |
230 | /** |
231 | * @param string[] $lines |
232 | */ |
233 | protected function added( $lines ) { |
234 | $this->lines( $lines, '>' ); |
235 | } |
236 | |
237 | /** |
238 | * @param string[] $lines |
239 | */ |
240 | protected function deleted( $lines ) { |
241 | $this->lines( $lines, '<' ); |
242 | } |
243 | |
244 | /** |
245 | * Writes the two sets of lines to the output buffer, separated by "---" and a newline. |
246 | * |
247 | * @param string[] $orig |
248 | * @param string[] $closing |
249 | */ |
250 | protected function changed( $orig, $closing ) { |
251 | $this->deleted( $orig ); |
252 | $this->writeOutput( "---\n" ); |
253 | $this->added( $closing ); |
254 | } |
255 | |
256 | } |
257 | |
258 | /** @deprecated class alias since 1.41 */ |
259 | class_alias( DiffFormatter::class, 'DiffFormatter' ); |