Passed
Push — master ( 3faf2f...2fb681 )
by Philippe
01:49
created

IspellParser::parseMisspellingsFromOutput()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 44
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 26
c 1
b 0
f 0
nc 5
nop 2
dl 0
loc 44
rs 9.1928
1
<?php
2
3
declare(strict_types=1);
4
5
namespace PhpSpellcheck\Utils;
6
7
use PhpSpellcheck\Misspelling;
8
9
class IspellParser
10
{
11
    /**
12
     * @param string $output assumed to be generated from an input on which {@see IspellParser::adaptInputForTerseModeProcessing()} has been applied
13
     * @param array<mixed> $context
14
     *
15
     * @return iterable<Misspelling>
16
     */
17
    public static function parseMisspellingsFromOutput(string $output, array $context = []): iterable
18
    {
19
        $lines = explode(PHP_EOL, $output);
20
        $lineNumber = 1;
21
        foreach ($lines as $line) {
22
            $line = trim($line);
23
            if ('' === $line) {
24
                ++$lineNumber;
25
                // Go to the next line
26
                continue;
27
            }
28
29
            switch ($line[0]) {
30
                case '#':
31
                    [, $word, $offset] = explode(' ', $line);
32
                    yield new Misspelling(
33
                        $word,
34
                        /**
35
                         * a `^` character is added to each line while sending text as input so it needs to
36
                         * account for that. {@see IspellParser::adaptInputForTerseModeProcessing}.
37
                         */
38
                        trim($offset) - 1,
39
                        $lineNumber,
40
                        [],
41
                        $context
42
                    );
43
44
                    break;
45
                case '&':
46
                    $parts = explode(':', $line);
47
                    [, $word, , $offset] = explode(' ', $parts[0]);
48
                    yield new Misspelling(
49
                        $word,
50
                        /**
51
                         * a `^` character is added to each line while sending text as input so it needs to
52
                         * account for that. {@see IspellParser::adaptInputForTerseModeProcessing}.
53
                         */
54
                        trim($offset) - 1,
55
                        $lineNumber,
56
                        explode(', ', trim($parts[1])),
57
                        $context
58
                    );
59
60
                    break;
61
            }
62
        }
63
    }
64
65
    /**
66
     * Preprocess the source text so that aspell/ispell pipe mode instruction is ignored.
67
     *
68
     * In pipe mode some special characters at the beginning of the line are instructions for aspell/ispell
69
     * {@link http://aspell.net/man-html/Through-A-Pipe.html#Through-A-Pipe}.
70
     *
71
     * Spellchecker must not interpret them, so it escapes them using the ^ symbol.
72
     */
73
    public static function adaptInputForTerseModeProcessing(string $input): string
74
    {
75
        return preg_replace('/^/m', '^', $input);
76
    }
77
}
78