Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
3 / 3
CRAP
100.00% covered (success)
100.00%
1 / 1
Snippet
100.00% covered (success)
100.00%
17 / 17
100.00% covered (success)
100.00%
3 / 3
9
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
5
 text
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 html
100.00% covered (success)
100.00%
5 / 5
100.00% covered (success)
100.00%
1 / 1
3
1<?php
2
3declare(strict_types=1);
4
5namespace Cosray\Fulltext;
6
7use Cosray\Markup;
8
9final readonly class Snippet
10{
11    /** @var list<array{text: string, match: bool}> */
12    public array $segments;
13
14    public function __construct(string $headline)
15    {
16        $segments = [];
17        $match = false;
18        foreach (preg_split(
19            '/([\x01\x02])/',
20            $headline,
21            flags: PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY,
22        ) ?: [] as $part) {
23            if ($part === "\x01" || $part === "\x02") {
24                $match = $part === "\x01";
25            } else {
26                $segments[] = ['text' => $part, 'match' => $match];
27            }
28        }
29        $this->segments = $segments;
30    }
31
32    public function text(): string
33    {
34        return implode('', array_column($this->segments, 'text'));
35    }
36
37    public function html(): Markup
38    {
39        $html = '';
40        foreach ($this->segments as $segment) {
41            $text = htmlspecialchars($segment['text'], ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
42            $html .= $segment['match'] ? '<mark>' . $text . '</mark>' : $text;
43        }
44        return new Markup($html);
45    }
46}