1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159
|
<?php
/**
* Copyright 2005-2013 Horde LLC (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.horde.org/licenses/lgpl21.
*
* @category Horde
* @copyright 2005-2013 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package SpellChecker
*/
/**
* A spellcheck driver for the aspell/ispell binary.
*
* @author Chuck Hagenbuch <chuck@horde.org>
* @author Michael Slusarz <slusarz@horde.org>
* @category Horde
* @copyright 2005-2013 Horde LLC
* @license http://www.horde.org/licenses/lgpl21 LGPL 2.1
* @package SpellChecker
*/
class Horde_SpellChecker_Aspell extends Horde_SpellChecker
{
/**
* @param array $args Additional arguments:
* - path: (string) Path to the aspell binary.
*/
public function __construct(array $args = array())
{
parent::__construct(array_merge(array(
'path' => 'aspell'
), $args));
}
/**
*/
public function spellCheck($text)
{
$ret = array(
'bad' => array(),
'suggestions' => array()
);
if ($this->_params['html']) {
$input = strtr($text, "\n", ' ');
} else {
$words = $this->_getWords($text);
if (!count($words)) {
return $ret;
}
$input = implode(' ', $words);
}
// Descriptor array.
$descspec = array(
0 => array('pipe', 'r'),
1 => array('pipe', 'w'),
2 => array('pipe', 'w')
);
$process = proc_open($this->_cmd(), $descspec, $pipes);
if (!is_resource($process)) {
throw new Horde_SpellChecker_Exception('Spellcheck failed. Command line: ' . $this->_cmd());
}
// The '^' character tells aspell to spell check the entire line.
fwrite($pipes[0], '^' . $input);
fclose($pipes[0]);
// Read stdout.
$out = '';
while (!feof($pipes[1])) {
$out .= fread($pipes[1], 8192);
}
fclose($pipes[1]);
// Read stderr.
$err = '';
while (!feof($pipes[2])) {
$err .= fread($pipes[2], 8192);
}
fclose($pipes[2]);
// We can't rely on the return value of proc_close:
// http://bugs.php.net/bug.php?id=29123
proc_close($process);
if (strlen($out) === 0) {
throw new Horde_SpellChecker_Exception('Spellcheck failed. Command line: ' . $this->_cmd());
}
// Parse output.
foreach (array_map('trim', explode("\n", $out)) as $line) {
if (!strlen($line)) {
continue;
}
@list(,$word,) = explode(' ', $line, 3);
if ($this->_inLocalDictionary($word) ||
in_array($word, $ret['bad'])) {
continue;
}
switch ($line[0]) {
case '#':
// Misspelling with no suggestions.
$ret['bad'][] = $word;
$ret['suggestions'][] = array();
break;
case '&':
// Suggestions.
$ret['bad'][] = $word;
$ret['suggestions'][] = array_slice(explode(', ', substr($line, strpos($line, ':') + 2)), 0, $this->_params['maxSuggestions']);
break;
}
}
return $ret;
}
/**
* Create the command line string.
*
* @return string The command to run.
*/
protected function _cmd()
{
$args = array('-a', '--encoding=UTF-8');
switch ($this->_params['suggestMode']) {
case self::SUGGEST_FAST:
$args[] = '--sug-mode=fast';
break;
case self::SUGGEST_SLOW:
$args[] = '--sug-mode=bad-spellers';
break;
default:
$args[] = '--sug-mode=normal';
}
$args[] = '--lang=' . escapeshellarg($this->_params['locale']);
$args[] = '--ignore=' . escapeshellarg(max($this->_params['minLength'] - 1, 0));
if ($this->_params['html']) {
$args[] = '-H';
$args[] = '--rem-html-check=alt';
}
return escapeshellcmd($this->_params['path']) . ' ' .
implode(' ', $args);
}
}
|