IspellParser   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 68
Duplicated Lines 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 28
c 2
b 0
f 0
dl 0
loc 68
rs 10
wmc 6

2 Methods

Rating   Name   Duplication   Size   Complexity  
A parseMisspellingsFromOutput() 0 45 5
A adaptInputForTerseModeProcessing() 0 3 1
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
26
                // Go to the next line
27
                continue;
28
            }
29
30
            switch ($line[0]) {
31
                case '#':
32
                    [, $word, $offset] = explode(' ', $line);
33
                    yield new Misspelling(
34
                        $word,
35
                        /**
36
                         * a `^` character is added to each line while sending text as input so it needs to
37
                         * account for that. {@see IspellParser::adaptInputForTerseModeProcessing}.
38
                         */
39
                        (int) trim($offset) - 1,
40
                        $lineNumber,
41
                        [],
42
                        $context
43
                    );
44
45
                    break;
46
                case '&':
47
                    $parts = explode(':', $line);
48
                    [, $word, , $offset] = explode(' ', $parts[0]);
49
                    yield new Misspelling(
50
                        $word,
51
                        /**
52
                         * a `^` character is added to each line while sending text as input so it needs to
53
                         * account for that. {@see IspellParser::adaptInputForTerseModeProcessing}.
54
                         */
55
                        (int) trim($offset) - 1,
56
                        $lineNumber,
57
                        explode(', ', trim($parts[1])),
58
                        $context
59
                    );
60
61
                    break;
62
            }
63
        }
64
    }
65
66
    /**
67
     * Preprocess the source text so that aspell/ispell pipe mode instruction is ignored.
68
     *
69
     * In pipe mode some special characters at the beginning of the line are instructions for aspell/ispell
70
     * {@link http://aspell.net/man-html/Through-A-Pipe.html#Through-A-Pipe}.
71
     *
72
     * Spellchecker must not interpret them, so it escapes them using the ^ symbol.
73
     */
74
    public static function adaptInputForTerseModeProcessing(string $input): string
75
    {
76
        return \Safe\preg_replace('/^/m', '^', $input);
77
    }
78
}
79