comparison program/lib/Roundcube/rcube_spellcheck_pspell.php @ 0:4681f974d28b

vanilla 1.3.3 distro, I hope
author Charlie Root
date Thu, 04 Jan 2018 15:52:31 -0500
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4681f974d28b
1 <?php
2
3 /**
4 +-----------------------------------------------------------------------+
5 | This file is part of the Roundcube Webmail client |
6 | |
7 | Copyright (C) 2008-2013, The Roundcube Dev Team |
8 | |
9 | Licensed under the GNU General Public License version 3 or |
10 | any later version with exceptions for skins & plugins. |
11 | See the README file for a full license statement. |
12 | |
13 | PURPOSE: |
14 | Spellchecking backend implementation to work with Pspell |
15 +-----------------------------------------------------------------------+
16 | Author: Aleksander Machniak <machniak@kolabsys.com> |
17 | Author: Thomas Bruederli <roundcube@gmail.com> |
18 +-----------------------------------------------------------------------+
19 */
20
21 /**
22 * Spellchecking backend implementation to work with Pspell
23 *
24 * @package Framework
25 * @subpackage Utils
26 */
27 class rcube_spellcheck_pspell extends rcube_spellcheck_engine
28 {
29 private $plink;
30 private $matches = array();
31
32 /**
33 * Return a list of languages supported by this backend
34 *
35 * @see rcube_spellcheck_engine::languages()
36 */
37 function languages()
38 {
39 $defaults = array('en');
40 $langs = array();
41
42 // get aspell dictionaries
43 exec('aspell dump dicts', $dicts);
44 if (!empty($dicts)) {
45 $seen = array();
46 foreach ($dicts as $lang) {
47 $lang = preg_replace('/-.*$/', '', $lang);
48 $langc = strlen($lang) == 2 ? $lang.'_'.strtoupper($lang) : $lang;
49 if (!$seen[$langc]++)
50 $langs[] = $lang;
51 }
52 $langs = array_unique($langs);
53 }
54 else {
55 $langs = $defaults;
56 }
57
58 return $langs;
59 }
60
61 /**
62 * Initializes PSpell dictionary
63 */
64 private function init()
65 {
66 if (!$this->plink) {
67 if (!extension_loaded('pspell')) {
68 $this->error = "Pspell extension not available";
69 return;
70 }
71
72 $this->plink = pspell_new($this->lang, null, null, RCUBE_CHARSET, PSPELL_FAST);
73 }
74
75 if (!$this->plink) {
76 $this->error = "Unable to load Pspell engine for selected language";
77 }
78 }
79
80 /**
81 * Set content and check spelling
82 *
83 * @see rcube_spellcheck_engine::check()
84 */
85 function check($text)
86 {
87 $this->init();
88
89 if (!$this->plink) {
90 return array();
91 }
92
93 // tokenize
94 $text = preg_split($this->separator, $text, NULL, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
95
96 $diff = 0;
97 $matches = array();
98
99 foreach ($text as $w) {
100 $word = trim($w[0]);
101 $pos = $w[1] - $diff;
102 $len = mb_strlen($word);
103
104 // skip exceptions
105 if ($this->dictionary->is_exception($word)) {
106 }
107 else if (!pspell_check($this->plink, $word)) {
108 $suggestions = pspell_suggest($this->plink, $word);
109
110 if (count($suggestions) > self::MAX_SUGGESTIONS) {
111 $suggestions = array_slice($suggestions, 0, self::MAX_SUGGESTIONS);
112 }
113
114 $matches[] = array($word, $pos, $len, null, $suggestions);
115 }
116
117 $diff += (strlen($word) - $len);
118 }
119
120 $this->matches = $matches;
121 return $matches;
122 }
123
124 /**
125 * Returns suggestions for the specified word
126 *
127 * @see rcube_spellcheck_engine::get_words()
128 */
129 function get_suggestions($word)
130 {
131 $this->init();
132
133 if (!$this->plink) {
134 return array();
135 }
136
137 $suggestions = pspell_suggest($this->plink, $word);
138
139 if (count($suggestions) > self::MAX_SUGGESTIONS)
140 $suggestions = array_slice($suggestions, 0, self::MAX_SUGGESTIONS);
141
142 return is_array($suggestions) ? $suggestions : array();
143 }
144
145 /**
146 * Returns misspelled words
147 *
148 * @see rcube_spellcheck_engine::get_suggestions()
149 */
150 function get_words($text = null)
151 {
152 $result = array();
153
154 if ($text) {
155 // init spellchecker
156 $this->init();
157
158 if (!$this->plink) {
159 return array();
160 }
161
162 // With PSpell we don't need to get suggestions to return misspelled words
163 $text = preg_split($this->separator, $text, NULL, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
164
165 foreach ($text as $w) {
166 $word = trim($w[0]);
167
168 // skip exceptions
169 if ($this->dictionary->is_exception($word)) {
170 continue;
171 }
172
173 if (!pspell_check($this->plink, $word)) {
174 $result[] = $word;
175 }
176 }
177
178 return $result;
179 }
180
181 foreach ($this->matches as $m) {
182 $result[] = $m[0];
183 }
184
185 return $result;
186 }
187 }