1C-Bitrix
25.700.0
Загрузка...
Поиск...
Не найдено
diff.php
См. документацию.
1
<?
2
namespace
Bitrix\Main\Text;
3
9
10
class
Diff
11
{
12
protected
$upVector
=
array
();
13
protected
$downVector
=
array
();
14
protected
$modifiedA
=
array
();
15
protected
$modifiedB
=
array
();
16
25
public
function
getDiffHtml
(
$a
, $b)
26
{
27
preg_match_all(
"/(<.*?>\\s*|\\s+)([^\\s<]*)/"
,
" "
.
$a
, $matchA);
28
preg_match_all(
"/(<.*?>\\s*|\\s+)([^\\s<]*)/"
,
" "
.$b, $matchB);
29
30
$diffScript = $this->
getDiffScript
($matchA[2], $matchB[2]);
31
if
(empty($diffScript))
32
{
33
// no difference found
34
return
$a
;
35
}
36
37
$positionA = 0;
38
39
$result
=
''
;
40
foreach
($diffScript as $diffItem)
41
{
42
while
($positionA < $diffItem[
'startA'
])
43
{
44
$result
.= $matchA[0][$positionA];
45
$positionA++;
46
}
47
48
//deleted items
49
if
($diffItem[
'deletedA'
] > 0)
50
{
51
$result
.= $matchA[1][$positionA] .
'<s style="color:red">'
. $matchA[2][$positionA];
52
for
(
$i
= 1;
$i
< $diffItem[
'deletedA'
];
$i
++)
53
$result
.= $matchA[0][$positionA +
$i
];
54
55
$result
.=
'</s>'
;
56
$positionA = $positionA + $diffItem[
'deletedA'
];
57
}
58
59
if
($diffItem[
'insertedB'
] > 0)
60
{
61
$result
.= $matchB[1][$diffItem[
'startB'
]] .
'<b style="color:green">'
. $matchB[2][$diffItem[
'startB'
]];
62
for
(
$i
= 1;
$i
< $diffItem[
'insertedB'
];
$i
++)
63
$result
.= $matchB[0][$diffItem[
'startB'
] +
$i
];
64
65
$result
.=
'</b>'
;
66
}
67
}
68
69
while
($positionA <
count
($matchA[0]))
70
{
71
$result
.= $matchA[0][$positionA];
72
$positionA++;
73
}
74
75
return
$result
;
76
}
77
89
public
function
getDiffScript
(
array
$a
,
array
$b)
90
{
91
$this->
init
();
92
$this->
longestCommonSubsequence
($a, 0,
count
(
$a
), $b, 0,
count
($b));
93
return
$this->
createDiff
($a, $b);
94
}
95
101
protected
function
init
()
102
{
103
$this->upVector =
array
();
104
$this->downVector =
array
();
105
$this->modifiedA =
array
();
106
$this->modifiedB =
array
();
107
}
108
120
protected
function
longestCommonSubsequence
(
array
$a
, $lowerA, $upperA,
array
$b, $lowerB, $upperB)
121
{
122
// Skipping equal lines at the start
123
while
($lowerA < $upperA && $lowerB < $upperB &&
$a
[$lowerA] == $b[$lowerB])
124
{
125
$lowerA++;
126
$lowerB++;
127
}
128
129
// Skipping equal lines at the end
130
while
($lowerA < $upperA && $lowerB < $upperB &&
$a
[$upperA - 1] == $b[$upperB - 1])
131
{
132
$upperA--;
133
$upperB--;
134
}
135
136
if
($lowerA === $upperA)
137
{
138
// mark as inserted lines.
139
while
($lowerB < $upperB)
140
{
141
$this->modifiedB[$lowerB++] =
true
;
142
}
143
}
144
else
145
{
146
if
($lowerB === $upperB)
147
{
148
// mark as deleted lines.
149
while
($lowerA < $upperA)
150
{
151
$this->modifiedA[$lowerA++] =
true
;
152
}
153
}
154
else
155
{
156
// Find the middle snake and length of an optimal path for A and B
157
$sms = $this->
shortestMiddleSnake
($a, $lowerA, $upperA, $b, $lowerB, $upperB);
158
159
// The path is from LowerX to (x,y) and (x,y) to UpperX
160
$this->
longestCommonSubsequence
($a, $lowerA, $sms[
'x'
], $b, $lowerB, $sms[
'y'
]);
161
$this->
longestCommonSubsequence
($a, $sms[
'x'
], $upperA, $b, $sms[
'y'
], $upperB);
162
}
163
}
164
}
165
166
179
protected
function
shortestMiddleSnake
(
array
$a
, $lowerA, $upperA,
array
$b, $lowerB, $upperB)
180
{
181
$result
=
array
();
182
183
$downK = $lowerA - $lowerB;
// the k-line to start the forward search
184
$upK = $upperA - $upperB;
// the k-line to start the reverse search
185
186
$delta
= ($upperA - $lowerA) - ($upperB - $lowerB);
187
$oddDelta = (
$delta
& 1) != 0;
188
189
$maxD = (($upperA - $lowerA + $upperB - $lowerB) / 2) + 1;
190
191
// init vectors
192
$this->downVector[$downK + 1] = $lowerA;
193
$this->upVector[$upK - 1] = $upperA;
194
195
for
($d = 0; $d <= $maxD; $d++)
196
{
197
198
// Extend the forward path.
199
for
(
$k
= $downK - $d;
$k
<= $downK + $d;
$k
+= 2)
200
{
201
// find the only or better starting point
202
$x = 0;
203
$y = 0;
204
if
(
$k
== $downK - $d)
205
{
206
$x = $this->downVector[
$k
+ 1];
// down
207
}
208
else
209
{
210
$x = $this->downVector[
$k
- 1] + 1;
// a step to the right
211
if
((
$k
< $downK + $d) && ($this->downVector[
$k
+ 1] >= $x))
212
{
213
$x = $this->downVector[
$k
+ 1];
214
}
// down
215
}
216
$y = $x -
$k
;
217
218
// find the end of the furthest reaching forward D-path in diagonal k.
219
while
(($x < $upperA) && ($y < $upperB) && (
$a
[$x] == $b[$y]))
220
{
221
$x++;
222
$y++;
223
}
224
$this->downVector[
$k
] = $x;
225
226
// overlap ?
227
if
($oddDelta && ($upK - $d <
$k
) && (
$k
< $upK + $d))
228
{
229
if
($this->upVector[
$k
] <= $this->downVector[
$k
])
230
{
231
$result
[
'x'
] = $this->downVector[
$k
];
232
$result
[
'y'
] = $this->downVector[
$k
] -
$k
;
233
return
$result
;
234
}
235
}
236
}
237
238
// Extend the reverse path.
239
for
(
$k
= $upK - $d;
$k
<= $upK + $d;
$k
+= 2)
240
{
241
242
// find the only or better starting point
243
$x = 0;
244
$y = 0;
245
if
(
$k
== $upK + $d)
246
{
247
$x = $this->upVector[
$k
- 1];
// up
248
}
249
else
250
{
251
$x = $this->upVector[
$k
+ 1] - 1;
// left
252
if
((
$k
> $upK - $d) && ($this->upVector[
$k
- 1] < $x))
253
{
254
$x = $this->upVector[
$k
- 1];
255
}
// up
256
}
257
$y = $x -
$k
;
258
259
while
(($x > $lowerA) && ($y > $lowerB) && (
$a
[$x - 1] == $b[$y - 1]))
260
{
261
// diagonal
262
$x--;
263
$y--;
264
}
265
$this->upVector[
$k
] = $x;
266
267
// overlap ?
268
if
(!$oddDelta && ($downK - $d <=
$k
) && (
$k
<= $downK + $d))
269
{
270
if
($this->upVector[
$k
] <= $this->downVector[
$k
])
271
{
272
$result
[
'x'
] = $this->downVector[
$k
];
273
$result
[
'y'
] = $this->downVector[
$k
] -
$k
;
274
return
$result
;
275
}
276
}
277
}
278
}
279
}
280
287
protected
function
createDiff
(
array
$a
,
array
$b)
288
{
289
$indexA = 0;
290
$indexB = 0;
291
$result
=
array
();
292
while
($indexA <
count
(
$a
) || $indexB <
count
($b))
293
{
294
if
(($indexA <
count
(
$a
)) && (empty($this->modifiedA[$indexA])) && ($indexB <
count
($b)) && empty($this->modifiedB[$indexB]))
295
{
296
// equal lines
297
$indexA++;
298
$indexB++;
299
}
300
else
301
{
302
// maybe deleted and/or inserted lines
303
$startA = $indexA;
304
$startB = $indexB;
305
306
while
($indexA <
count
(
$a
) && ($indexB >=
count
($b) || !empty($this->modifiedA[$indexA])))
307
{
308
$indexA++;
309
}
310
311
while
($indexB <
count
($b) && ($indexA >=
count
(
$a
) || !empty($this->modifiedB[$indexB])))
312
{
313
$indexB++;
314
}
315
316
if
(($startA < $indexA) || ($startB < $indexB))
317
{
318
// store a new difference-item
319
$result
[] =
array
(
"startA"
=> $startA,
"startB"
=> $startB,
"deletedA"
=> $indexA - $startA,
"insertedB"
=> $indexB - $startB);
320
}
321
}
322
}
323
return
$result
;
324
}
325
}
Bitrix\Main\Text\Diff
Определения
diff.php:11
Bitrix\Main\Text\Diff\$modifiedA
$modifiedA
Определения
diff.php:14
Bitrix\Main\Text\Diff\getDiffScript
getDiffScript(array $a, array $b)
Определения
diff.php:89
Bitrix\Main\Text\Diff\longestCommonSubsequence
longestCommonSubsequence(array $a, $lowerA, $upperA, array $b, $lowerB, $upperB)
Определения
diff.php:120
Bitrix\Main\Text\Diff\createDiff
createDiff(array $a, array $b)
Определения
diff.php:287
Bitrix\Main\Text\Diff\init
init()
Определения
diff.php:101
Bitrix\Main\Text\Diff\getDiffHtml
getDiffHtml($a, $b)
Определения
diff.php:25
Bitrix\Main\Text\Diff\$upVector
$upVector
Определения
diff.php:12
Bitrix\Main\Text\Diff\shortestMiddleSnake
shortestMiddleSnake(array $a, $lowerA, $upperA, array $b, $lowerB, $upperB)
Определения
diff.php:179
Bitrix\Main\Text\Diff\$modifiedB
$modifiedB
Определения
diff.php:15
Bitrix\Main\Text\Diff\$downVector
$downVector
Определения
diff.php:13
array
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения
file_new.php:804
$result
$result
Определения
get_property_values.php:14
$delta
$delta
Определения
prolog_main_admin.php:363
$i
$i
Определения
factura.php:643
count
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения
waybill.php:936
$a
else $a
Определения
template.php:137
$k
$k
Определения
template_pdf.php:567
bitrix
modules
main
lib
text
diff.php
Создано системой
1.14.0