summaryrefslogtreecommitdiff
path: root/program/lib/Roundcube/rcube_spellcheck_pspell.php
diff options
context:
space:
mode:
authorThomas Bruederli <thomas@roundcube.net>2013-10-11 15:15:46 +0200
committerThomas Bruederli <thomas@roundcube.net>2013-10-11 15:15:46 +0200
commitbc0a470157518e5c5873872388280fbd711edc6e (patch)
tree0aad279263f08c7d0282c4b89a096ceafc61da61 /program/lib/Roundcube/rcube_spellcheck_pspell.php
parentc856b73c86dcf891c7235ca86f1e2d9456d1e6ff (diff)
Refactor spellchecker class into backend subclasses for better extensibility
Diffstat (limited to 'program/lib/Roundcube/rcube_spellcheck_pspell.php')
-rw-r--r--program/lib/Roundcube/rcube_spellcheck_pspell.php160
1 files changed, 160 insertions, 0 deletions
diff --git a/program/lib/Roundcube/rcube_spellcheck_pspell.php b/program/lib/Roundcube/rcube_spellcheck_pspell.php
new file mode 100644
index 000000000..ce089ed8f
--- /dev/null
+++ b/program/lib/Roundcube/rcube_spellcheck_pspell.php
@@ -0,0 +1,160 @@
+<?php
+
+/*
+ +-----------------------------------------------------------------------+
+ | This file is part of the Roundcube Webmail client |
+ | |
+ | Copyright (C) 2008-2013, The Roundcube Dev Team |
+ | |
+ | Licensed under the GNU General Public License version 3 or |
+ | any later version with exceptions for skins & plugins. |
+ | See the README file for a full license statement. |
+ | |
+ | PURPOSE: |
+ | Spellchecking backend implementation to work with Pspell |
+ +-----------------------------------------------------------------------+
+ | Author: Aleksander Machniak <machniak@kolabsys.com> |
+ | Author: Thomas Bruederli <roundcube@gmail.com> |
+ +-----------------------------------------------------------------------+
+*/
+
+/**
+ * Spellchecking backend implementation to work with Pspell
+ *
+ * @package Framework
+ * @subpackage Utils
+ */
+class rcube_spellcheck_pspell extends rcube_spellcheck_engine
+{
+ private $plink;
+ private $matches = array();
+
+ /**
+ * Initializes PSpell dictionary
+ */
+ private function init()
+ {
+ if (!$this->plink) {
+ if (!extension_loaded('pspell')) {
+ $this->error = "Pspell extension not available";
+ return;
+ }
+
+ $this->plink = pspell_new($this->lang, null, null, RCUBE_CHARSET, PSPELL_FAST);
+ }
+
+ if (!$this->plink) {
+ $this->error = "Unable to load Pspell engine for selected language";
+ }
+ }
+
+ /**
+ * Set content and check spelling
+ *
+ * @see rcube_spellcheck_engine::check()
+ */
+ function check($text)
+ {
+ $this->init();
+
+ if (!$this->plink) {
+ return array();
+ }
+
+ // tokenize
+ $text = preg_split($this->separator, $text, NULL, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
+
+ $diff = 0;
+ $matches = array();
+
+ foreach ($text as $w) {
+ $word = trim($w[0]);
+ $pos = $w[1] - $diff;
+ $len = mb_strlen($word);
+
+ // skip exceptions
+ if ($this->dictionary->is_exception($word)) {
+ }
+ else if (!pspell_check($this->plink, $word)) {
+ $suggestions = pspell_suggest($this->plink, $word);
+
+ if (sizeof($suggestions) > self::MAX_SUGGESTIONS) {
+ $suggestions = array_slice($suggestions, 0, self::MAX_SUGGESTIONS);
+ }
+
+ $matches[] = array($word, $pos, $len, null, $suggestions);
+ }
+
+ $diff += (strlen($word) - $len);
+ }
+
+ $this->matches = $matches;
+ return $matches;
+ }
+
+ /**
+ * Returns suggestions for the specified word
+ *
+ * @see rcube_spellcheck_engine::get_words()
+ */
+ function get_suggestions($word)
+ {
+ $this->init();
+
+ if (!$this->plink) {
+ return array();
+ }
+
+ $suggestions = pspell_suggest($this->plink, $word);
+
+ if (sizeof($suggestions) > self::MAX_SUGGESTIONS)
+ $suggestions = array_slice($suggestions, 0, self::MAX_SUGGESTIONS);
+
+ return is_array($suggestions) ? $suggestions : array();
+ }
+
+ /**
+ * Returns misspelled words
+ *
+ * @see rcube_spellcheck_engine::get_suggestions()
+ */
+ function get_words($text = null)
+ {
+ $result = array();
+
+ if ($text) {
+ // init spellchecker
+ $this->init();
+
+ if (!$this->plink) {
+ return array();
+ }
+
+ // With PSpell we don't need to get suggestions to return misspelled words
+ $text = preg_split($this->separator, $text, NULL, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_OFFSET_CAPTURE);
+
+ foreach ($text as $w) {
+ $word = trim($w[0]);
+
+ // skip exceptions
+ if ($this->dictionary->is_exception($word)) {
+ continue;
+ }
+
+ if (!pspell_check($this->plink, $word)) {
+ $result[] = $word;
+ }
+ }
+
+ return $result;
+ }
+
+ foreach ($this->matches as $m) {
+ $result[] = $m[0];
+ }
+
+ return $result;
+ }
+
+}
+