4 Copyright 2006,2007 $ThePhpWikiProgrammingTeam
6 This file is part of PhpWiki.
8 PhpWiki is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 PhpWiki is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with PhpWiki; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 * SpellCheck is a plugin, used inside the editpage.tmpl (on save or preview)
25 * This could be a userpref option always highlighting words in preview
26 * or it could be an extra button in edit.
28 * The pspell extension is better, because it's easier to store corrections.
29 * Enchant looks more promising, because it supports multiple speller backends.
31 * Currently we do use aspell (via pspell or cmdline) in ispell mode.
32 * Maybe enchant later.
33 * cmdline preparation:
34 do autosplit wikiwords && sed s,^,\^^, $pagename | aspell --lang=$LANG -a
36 sed s,^,\^^, $pagename | aspell --lang=$LANG -a -C
38 & phpwiki 62 30: pipework, paprika, Popek, Phip, Pike, Viki, pike, ...
41 // Those settings should really be defined in config.ini, not here.
42 if (!function_exists('pspell_new_config')) {
43 // old pipe interface:
44 if (!defined('ASPELL_EXE'))
45 define('ASPELL_EXE','aspell');
46 //define('ASPELL_EXE','/usr/local/bin/aspell');
47 //define('ASPELL_EXE','/home/groups/p/ph/phpwiki/bin/aspell');
48 if (!defined('ASPELL_DATA_DIR'))
50 define('ASPELL_DATA_DIR','c:\cygwin\usr\share\aspell');
52 define('ASPELL_DATA_DIR','/usr/share/aspell');
53 //define('ASPELL_DATA_DIR','/home/groups/p/ph/phpwiki/share/highlight');
55 // new library interface through the pspell extension:
56 // "/var/dictionaries/custom.pws"
57 if (!defined('PSPELL_PWL'))
58 define('PSPELL_PWL', ''); // phpwiki-special wordlist
59 // "/var/dictionaries/custom.repl"
60 if (!defined('PSPELL_REPL'))
61 define('PSPELL_REPL', ''); // phpwiki-special replacement list (persistent replacements)
64 class WikiPlugin_SpellCheck
68 return _("Spell Checker");
70 function getDescription () {
71 return _("Check the spelling of a page and make suggestions");
73 function managesValidators() {
76 function getVersion() {
77 return preg_replace("/[Revision: $]/", '',
80 function getDefaultArguments() {
81 return array('pagename' => '[]', // button or preview highlight?
85 function pspell_check ($text, $lang=false) {
87 if ($lang) $lang = $GLOBALS['LANG'];
88 $words = preg_split('/[\W]+?/', $text);
90 $misspelled = $return = array();
91 $pspell_config = pspell_config_create($lang, "", "", $charset,
92 PSPELL_NORMAL|PSPELL_RUN_TOGETHER);
93 //pspell_config_runtogether($pspell_config, true);
95 pspell_config_personal($pspell_config, PSPELL_PWL);
97 pspell_config_repl($pspell_config, PSPELL_REPL);
98 $pspell = pspell_new_config($pspell_config);
100 foreach ($words as $value) {
101 // SplitPagename $value
102 if (!pspell_check($pspell, $value)) {
103 $misspelled[] = $value;
106 foreach ($misspelled as $value) {
107 $return[$value] = pspell_suggest($pspell, $value);
112 function pspell_correct ($text, $corrections) {
116 function run($dbi, $argstr, &$request, $basepage) {
117 extract($this->getArgs($argstr, $request));
118 $page = $dbi->getPage($pagename);
119 $current = $page->getCurrentRevision();
120 $source = $current->getPackedContent();
123 return $this->error(fmt("empty source"));
124 if ($basepage == _("SpellCheck"))
125 return $this->error(fmt("Cannot SpellCheck myself"));
126 $lang = $page->get('lang');
127 if (empty($lang)) $lang = $GLOBALS['LANG'];
129 if (!function_exists('pspell_new_config')) {
130 // use the aspell commandline interface
131 include_once("lib/WikiPluginCached.php");
133 $source = preg_replace("/^/m", "^", $source);
135 $args .= " --data-dir=" . ASPELL_DATA_DIR;
136 // MAYBE TODO: do we have the language dictionary?
137 $args .= " --lang=" . $lang;
138 // use -C or autosplit wikiwords in the text
139 $commandLine = ASPELL_EXE . " -a -C $args ";
140 $cache = new WikiPluginCached;
141 $code = $cache->filterThroughCmd($source, $commandLine);
143 return $this->error(fmt("Couldn't start commandline '%s'",$commandLine));
145 foreach (preg_split("/\n/", $code) as $line) {
146 if (preg_match("/^& (\w+) \d+ \d+: (.+)$/", $line, $m)) {
147 $sugg[$m[1]] = preg_split("/, /", $m[2]);
150 /*$pre = HTML::pre(HTML::raw($code));
151 $pre->setAttr('class','tightenable top bottom');
152 $html->pushContent($pre);*/
154 $sugg = pspell_check($source, $lang);
156 //$html->pushContent(HTML::hr(),HTML::h1(_("Spellcheck")));
157 $page = $request->getPage();
159 $revision = $page->getRevision($version);
161 NoSuchRevision($request, $page, $version);
164 $revision = $page->getCurrentRevision();
166 $GLOBALS['request']->setArg('suggestions', $sugg);
167 include_once("lib/BlockParser.php");
168 $ori_html = TransformText($revision, $revision->get('markup'), $page);
169 $GLOBALS['request']->setArg('suggestions', false);
171 $html->pushContent($ori_html, HTML::hr(), HTML::h1(_("SpellCheck result")));
174 foreach ($sugg as $word => $suggs) {
175 $w = HTML::span(array('class' => 'spell-wrong'), $word);
176 // TODO: optional replace-link. jscript or request button with word replace.
178 foreach ($suggs as $s) {
179 $r->pushContent(HTML::a(array('class' => 'spell-sugg',
180 'href' => "javascript:do_replace('$word','$s')"),
183 $list->pushContent(HTML::li($w, ": ", $r));
185 $html->pushContent($list);
190 // $Log: not supported by cvs2svn $
191 // Revision 1.1 2007/01/20 11:23:26 rurban
192 // New plugin and ActionPage
201 // c-hanging-comment-ender-p: nil
202 // indent-tabs-mode: nil