Skip to content

Commit 19a92b3

Browse files
committed
Replace the substring with multi byte
1 parent cb6e774 commit 19a92b3

File tree

1 file changed

+48
-4
lines changed

1 file changed

+48
-4
lines changed

lib/Diff/Renderer/Html/Array.php

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,50 @@ class Diff_Renderer_Html_Array extends Diff_Renderer_Abstract
5151
'tabSize' => 4
5252
);
5353

54+
/**
55+
* From https://gist.github.com/stemar/8287074
56+
* @param mixed $string The input string.
57+
* @param mixed $replacement The replacement string.
58+
* @param mixed $start If start is positive, the replacing will begin at the start'th offset into string. If start is negative, the replacing will begin at the start'th character from the end of string.
59+
* @param mixed $length If given and is positive, it represents the length of the portion of string which is to be replaced. If it is negative, it represents the number of characters from the end of string at which to stop replacing. If it is not given, then it will default to strlen( string ); i.e. end the replacing at the end of string. Of course, if length is zero then this function will have the effect of inserting replacement into string at the given start offset.
60+
* @return string The result string is returned. If string is an array then array is returned.
61+
*/
62+
public function mb_substr_replace($string, $replacement, $start, $length=NULL) {
63+
if (is_array($string)) {
64+
$num = count($string);
65+
// $replacement
66+
$replacement = is_array($replacement) ? array_slice($replacement, 0, $num) : array_pad(array($replacement), $num, $replacement);
67+
// $start
68+
if (is_array($start)) {
69+
$start = array_slice($start, 0, $num);
70+
foreach ($start as $key => $value)
71+
$start[$key] = is_int($value) ? $value : 0;
72+
}
73+
else {
74+
$start = array_pad(array($start), $num, $start);
75+
}
76+
// $length
77+
if (!isset($length)) {
78+
$length = array_fill(0, $num, 0);
79+
}
80+
elseif (is_array($length)) {
81+
$length = array_slice($length, 0, $num);
82+
foreach ($length as $key => $value)
83+
$length[$key] = isset($value) ? (is_int($value) ? $value : $num) : 0;
84+
}
85+
else {
86+
$length = array_pad(array($length), $num, $length);
87+
}
88+
// Recursive call
89+
return array_map(__FUNCTION__, $string, $replacement, $start, $length);
90+
}
91+
preg_match_all('/./us', (string)$string, $smatches);
92+
preg_match_all('/./us', (string)$replacement, $rmatches);
93+
if ($length === NULL) $length = mb_strlen($string);
94+
array_splice($smatches[0], $start, $length, $rmatches[0]);
95+
return join($smatches[0]);
96+
}
97+
5498
/**
5599
* Render and return an array structure suitable for generating HTML
56100
* based differences. Generally called by subclasses that generate a
@@ -83,11 +127,11 @@ public function render()
83127
list($start, $end) = $this->getChangeExtent($fromLine, $toLine);
84128
if($start != 0 || $end != 0) {
85129
$last = $end + strlen($fromLine);
86-
$fromLine = substr_replace($fromLine, "\0", $start, 0);
87-
$fromLine = substr_replace($fromLine, "\1", $last + 1, 0);
130+
$fromLine = $this->mb_substr_replace($fromLine, "\0", $start, 0);
131+
$fromLine = $this->mb_substr_replace($fromLine, "\1", $last + 1, 0);
88132
$last = $end + strlen($toLine);
89-
$toLine = substr_replace($toLine, "\0", $start, 0);
90-
$toLine = substr_replace($toLine, "\1", $last + 1, 0);
133+
$toLine = $this->mb_substr_replace($toLine, "\0", $start, 0);
134+
$toLine = $this->mb_substr_replace($toLine, "\1", $last + 1, 0);
91135
$a[$i1 + $i] = $fromLine;
92136
$b[$j1 + $i] = $toLine;
93137
}

0 commit comments

Comments
 (0)