1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace PhpSpellcheck\Spellchecker; |
6
|
|
|
|
7
|
|
|
use PhpSpellcheck\Exception\ProcessHasErrorOutputException; |
8
|
|
|
use PhpSpellcheck\Utils\CommandLine; |
9
|
|
|
use PhpSpellcheck\Utils\IspellParser; |
10
|
|
|
use PhpSpellcheck\Utils\ProcessRunner; |
11
|
|
|
use Symfony\Component\Process\Process; |
12
|
|
|
|
13
|
|
|
class Hunspell implements SpellcheckerInterface |
14
|
|
|
{ |
15
|
|
|
/** |
16
|
|
|
* @var CommandLine |
17
|
|
|
*/ |
18
|
|
|
private $binaryPath; |
19
|
|
|
|
20
|
|
|
public function __construct(CommandLine $binaryPath) |
21
|
6 |
|
{ |
22
|
|
|
$this->binaryPath = $binaryPath; |
23
|
6 |
|
} |
24
|
6 |
|
|
25
|
|
|
/** |
26
|
|
|
* {@inheritdoc} |
27
|
|
|
*/ |
28
|
|
|
public function check( |
29
|
4 |
|
string $text, |
30
|
|
|
array $languages = [], |
31
|
|
|
array $context = [] |
32
|
|
|
): iterable { |
33
|
|
|
$cmd = $this->binaryPath->addArgs(['-i', 'UTF-8']); |
34
|
|
|
$cmd = $cmd->addArg('-a'); |
35
|
|
|
|
36
|
4 |
|
if (!empty($languages)) { |
37
|
|
|
$cmd = $cmd->addArgs(['-d', implode(',', $languages)]); |
38
|
4 |
|
} |
39
|
3 |
|
|
40
|
|
|
$process = new Process($cmd->getArgs()); |
41
|
|
|
// Add prefix characters putting Ispell's type of spellcheckers in terse-mode, |
42
|
4 |
|
// ignoring correct words and thus speeding execution |
43
|
4 |
|
$process->setInput('!' . PHP_EOL . IspellParser::adaptInputForTerseModeProcessing($text) . PHP_EOL . '%'); |
44
|
|
|
|
45
|
|
|
$output = ProcessRunner::run($process)->getOutput(); |
46
|
4 |
|
if ($process->getErrorOutput() !== '') { |
47
|
|
|
throw new ProcessHasErrorOutputException($process->getErrorOutput(), $text, $process->getCommandLine()); |
48
|
|
|
} |
49
|
4 |
|
|
50
|
|
|
return IspellParser::parseMisspellingsFromOutput($output, $context); |
51
|
4 |
|
} |
52
|
4 |
|
|
53
|
1 |
|
public function getBinaryPath(): CommandLine |
54
|
|
|
{ |
55
|
|
|
return $this->binaryPath; |
56
|
3 |
|
} |
57
|
|
|
|
58
|
|
|
/** |
59
|
|
|
* {@inheritdoc} |
60
|
|
|
*/ |
61
|
|
|
public function getSupportedLanguages(): iterable |
62
|
|
|
{ |
63
|
|
|
$languages = []; |
64
|
|
|
$cmd = $this->binaryPath->addArg('-D'); |
65
|
|
|
$process = new Process($cmd->getArgs()); |
66
|
|
|
$output = explode(PHP_EOL, ProcessRunner::run($process)->getErrorOutput()); |
67
|
2 |
|
|
68
|
|
|
foreach ($output as $line) { |
69
|
2 |
|
$line = trim($line); |
70
|
2 |
|
if ('' === $line // Skip empty lines |
71
|
2 |
|
|| \Safe\substr($line, -1) === ':' // Skip headers |
|
|
|
|
72
|
|
|
|| strpos($line, ':') !== false // Skip search path |
73
|
2 |
|
) { |
74
|
2 |
|
continue; |
75
|
2 |
|
} |
76
|
2 |
|
$name = basename($line); |
77
|
2 |
|
if (strpos($name, 'hyph_') === 0) { |
78
|
|
|
// Skip MySpell hyphen files |
79
|
2 |
|
continue; |
80
|
|
|
} |
81
|
2 |
|
$name = \Safe\preg_replace('/\.(aff|dic)$/', '', $name); |
82
|
2 |
|
$languages[$name] = true; |
83
|
|
|
} |
84
|
1 |
|
$languages = array_keys($languages); |
85
|
|
|
\Safe\sort($languages); |
|
|
|
|
86
|
2 |
|
|
87
|
2 |
|
return $languages; |
88
|
|
|
} |
89
|
2 |
|
|
90
|
2 |
|
public static function create(?string $binaryPathAsString = null): self |
91
|
|
|
{ |
92
|
2 |
|
return new self(new CommandLine($binaryPathAsString ?? 'hunspell')); |
93
|
|
|
} |
94
|
|
|
} |
95
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.