53 public function highlightText( $text, $terms, $contextlines, $contextchars ) {
61 $spat =
"/(\\{\\{)|(\\[\\[[^\\]:]+:)|(\n\\{\\|)";
64 1 =>
'/(\{\{)|(\}\})/',
65 2 =>
'/(\[\[)|(\]\])/',
66 3 =>
"/(\n\\{\\|)|(\n\\|\\})/" ];
70 if ( class_exists(
'Cite' ) ) {
72 $endPatterns[4] =
'/(<ref>)|(<\/ref>)/';
78 $textLen = strlen( $text );
80 while ( $start < $textLen ) {
82 if ( preg_match( $spat, $text,
$matches, PREG_OFFSET_CAPTURE, $start ) ) {
85 if ( $key > 0 && $val[1] != -1 ) {
88 $ns = substr( $val[0], 2, -1 );
90 MediaWikiServices::getInstance()->getContentLanguage()->
97 $epat = $endPatterns[$key];
98 $this->
splitAndAdd( $textExt, $count, substr( $text, $start, $val[1] - $start ) );
106 $offset = $start + 1;
108 while ( preg_match( $epat, $text, $endMatches, PREG_OFFSET_CAPTURE, $offset ) ) {
109 if ( array_key_exists( 2, $endMatches ) ) {
112 $len = strlen( $endMatches[2][0] );
113 $off = $endMatches[2][1];
115 substr( $text, $start, $off + $len - $start ) );
116 $start = $off + $len;
127 $offset = $endMatches[0][1] + strlen( $endMatches[0][0] );
138 $this->
splitAndAdd( $textExt, $count, substr( $text, $start ) );
142 $all = $textExt + $otherExt;
145 foreach ( $terms
as $index =>
$term ) {
147 if ( preg_match(
'/[\x80-\xff]/',
$term ) ) {
148 $terms[$index] = preg_replace_callback(
150 [ $this,
'caseCallback' ],
154 $terms[$index] =
$term;
157 $anyterm = implode(
'|', $terms );
158 $phrase = implode(
"$wgSearchHighlightBoundaries+", $terms );
163 $scale = strlen( $anyterm ) / mb_strlen( $anyterm );
164 $contextchars = intval( $contextchars * $scale );
166 $patPre =
"(^|$wgSearchHighlightBoundaries)";
167 $patPost =
"($wgSearchHighlightBoundaries|$)";
169 $pat1 =
"/(" . $phrase .
")/ui";
170 $pat2 =
"/$patPre(" . $anyterm .
")$patPost/ui";
172 $left = $contextlines;
180 foreach ( $textExt
as $index =>
$line ) {
182 $firstText = $this->
extract(
$line, 0, $contextchars * $contextlines );
191 if ( !preg_match(
"/$patPre" .
$term .
"$patPost/ui", $firstText ) ) {
197 $snippets[$first] = $firstText;
198 $offsets[$first] = 0;
203 $this->
process( $pat1, $textExt, $left, $contextchars, $snippets, $offsets );
205 $this->
process( $pat1, $otherExt, $left, $contextchars, $snippets, $offsets );
207 $this->
process( $pat2, $textExt, $left, $contextchars, $snippets, $offsets );
209 $this->
process( $pat2, $otherExt, $left, $contextchars, $snippets, $offsets );
216 if ( count( $snippets ) == 0 ) {
218 if ( array_key_exists( $first, $all ) ) {
219 $targetchars = $contextchars * $contextlines;
220 $snippets[$first] =
'';
221 $offsets[$first] = 0;
225 if ( array_key_exists( $first, $snippets ) && preg_match( $pat1, $snippets[$first] )
226 && $offsets[$first] < $contextchars * 2 ) {
227 $snippets = [ $first => $snippets[$first] ];
231 $targetchars = intval( ( $contextchars * $contextlines ) / count( $snippets ) );
234 foreach ( $snippets
as $index =>
$line ) {
235 $extended[$index] =
$line;
236 $len = strlen(
$line );
237 if ( $len < $targetchars - 20 ) {
239 if ( $len < strlen( $all[$index] ) ) {
240 $extended[$index] = $this->
extract(
243 $offsets[$index] + $targetchars,
246 $len = strlen( $extended[$index] );
251 while ( $len < $targetchars - 20
252 && array_key_exists( $add, $all )
253 && !array_key_exists( $add, $snippets ) ) {
255 $tt =
"\n" . $this->
extract( $all[$add], 0, $targetchars - $len, $offsets[$add] );
256 $extended[$add] = $tt;
257 $len += strlen( $tt );
264 $snippets = $extended;
267 foreach ( $snippets
as $index =>
$line ) {
270 } elseif (
$last + 1 == $index
271 && $offsets[
$last] + strlen( $snippets[
$last] ) >= strlen( $all[
$last] )
273 $extract .=
" " .
$line;
275 $extract .=
'<b> ... </b>' .
$line;
281 $extract .=
'<b> ... </b>';
286 if ( !isset( $processed[
$term] ) ) {
287 $pat3 =
"/$patPre(" .
$term .
")$patPost/ui";
288 $extract = preg_replace( $pat3,
289 "\\1<span class='searchmatch'>\\2</span>\\3", $extract );
290 $processed[
$term] =
true;
413 function process( $pattern, $extracts, &$linesleft, &$contextchars, &
$out, &$offsets ) {
414 if ( $linesleft == 0 ) {
417 foreach ( $extracts
as $index =>
$line ) {
418 if ( array_key_exists( $index,
$out ) ) {
423 if ( !preg_match( $pattern,
$line, $m, PREG_OFFSET_CAPTURE ) ) {
428 $len = strlen( $m[0][0] );
429 if ( $offset + $len < $contextchars ) {
431 } elseif ( $len > $contextchars ) {
434 $begin = $offset + intval( ( $len - $contextchars ) / 2 );
437 $end = $begin + $contextchars;
442 $offsets[$index] = $posBegin;
444 if ( $linesleft == 0 ) {