File: Aspell.php

package info (click to toggle)
php-horde-spellchecker 2.1.1-4
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 124 kB
  • ctags: 31
  • sloc: xml: 287; php: 171; sh: 3; makefile: 2
file content (159 lines) | stat: -rw-r--r-- 4,391 bytes parent folder | download
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);
    }

}