This will highlight words that are found across one or more passages of text. (This example uses 3).
The passages are passed in as an array.
$passages = [
'passage one',
'passage two'
];
Keywords are also passed as an array.
$words = [
'throne',
'judgment'
];
Words that share the same meaning are grouped as an array. These words will also be highlighted with the same color.
$words = [
'throne',
['pride', 'proud'],
'judgment'
];
This example will also re-cycle the colors. For example, if you have a selection of 5 colors but 6 words are matched, the sixth word will be highlighted using the first color!
function highlight($passages, array $words, array $colors, $ignoreCase = false)
{
$wordToColor = [];
$colorIdx = 0;
$highlighted = [];
foreach ($passages as $passage) {
foreach ($words as $wordGroup) {
if (is_array($wordGroup)) {
$re = '~\\b('.implode('|', $wordGroup).')\\b~';
} else {
$re = '~\\b('.$wordGroup.')\\b~';
}
if ($ignoreCase) {
$re .= 'i';
}
$passage = preg_replace_callback($re, function ($m) use ($re, $colors, &$wordToColor, &$colorIdx) {
$word = $m[0];
if (!isset($wordToColor[$re])) {
$wordToColor[$re] = $colors[$colorIdx];
$colorIdx = $colorIdx < count($colors) - 1 ? $colorIdx + 1 : 0;
}
$color = $wordToColor[$re];
return sprintf('<b style="color:%s">%s</b>', $color, $word);
}, $passage);
}
$highlighted[] = $passage;
}
return $highlighted;
}
$passages = [
'Once more unto the breach, dear friends, once more. Or close the wall up with our English dead.',
'On, on, you noblest English, whose blood is fet from fathers of war-proof!',
"Follow your spirit, and upon this charge cry 'God for Harry, England, and Saint George!"
];
$words = [
'once more',
'god',
['england', 'english'],
'blood',
'spirit',
];
$colors = ['red', 'green', 'blue', 'yellow'];
$highlighted = highlight($passages, $words, $colors, true);
$p = array_reduce($highlighted, function ($html, $passage) {
return $html .= "<p>$passage</p>";
}, '');
echo <<< EOF_HTML
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Highlight</title>
<style>
p {
margin: 16px;
}
</style>
</head>
<body>
$p
</body>
</html>
EOF_HTML;