remove ispell and pspell

git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@27472 a592a061-630c-0410-9148-cb99ea01b6c8
This commit is contained in:
André Pönitz 2008-11-15 18:47:25 +00:00
parent e2f312f8f0
commit 8e2f971ada
15 changed files with 79 additions and 1014 deletions

View File

@ -92,7 +92,7 @@ Components to use/build:
one. one.
* gettext=included/system/auto * gettext=included/system/auto
* nls=yes/no whether or not enable natural language support. * nls=yes/no whether or not enable natural language support.
* spell=aspell/pspell/ispell/auto: spell engine * spell=aspell/auto: spell engine
Paths: Most of them will be probed if not specified. Paths: Most of them will be probed if not specified.

View File

@ -24,59 +24,16 @@ AC_DEFUN([CHECK_WITH_ASPELL],
]) ])
# Macro to add for using pspell spellchecker libraries! -*- sh -*-
# @author@: Jürgen Vigna
AC_DEFUN([CHECK_WITH_PSPELL],
[
lyx_use_pspell=true
AC_ARG_WITH(pspell, AC_HELP_STRING([--with-pspell],[use PSpell libraries]))
test "$with_pspell" = "no" && lyx_use_pspell=false
if $lyx_use_pspell ; then
AC_CHECK_HEADERS(pspell/pspell.h,, lyx_use_pspell=false)
AC_CHECK_LIB(pspell, main, LIBS="-lpspell $LIBS", lyx_use_pspell=false)
AC_MSG_CHECKING([whether to use pspell])
if $lyx_use_pspell ; then
AC_MSG_RESULT(yes)
AC_DEFINE(USE_PSPELL, 1, [Define as 1 to use the pspell library])
lyx_flags="$lyx_flags use-pspell"
else
AC_MSG_RESULT(no)
fi
fi
])
### Check if we want spell libraries, prefer new aspell ### Check if we want spell libraries, prefer new aspell
AC_DEFUN([LYX_CHECK_SPELL_ENGINES], AC_DEFUN([LYX_CHECK_SPELL_ENGINES],
[ [
lyx_use_aspell=false lyx_use_aspell=false
lyx_use_pspell=false
lyx_use_ispell=false
dnl Prefer use of the aspell library over pspell.
CHECK_WITH_ASPELL CHECK_WITH_ASPELL
if $lyx_use_aspell ; then : ; else
CHECK_WITH_PSPELL
fi
dnl check for the ability to communicate through unix pipes dnl check for the ability to communicate through unix pipes
dnl with an external ispell process. dnl with an external ispell process.
dnl Do this independent of the existence of the aspell, pspell libraries. dnl Do this independent of the existence of the aspell libraries.
lyx_use_ispell=true lyx_use_ispell=true
AC_LANG_PUSH(C)
AC_CHECK_FUNCS(fork,, [lyx_use_ispell=false])
AC_LANG_POP(C)
AC_MSG_CHECKING([whether to use ispell])
if $lyx_use_ispell ; then
AC_MSG_RESULT(yes)
AC_DEFINE(USE_ISPELL, 1, [Define as 1 to use an external ispell process to check spelling])
lyx_flags="$lyx_flags use-ispell"
else
AC_MSG_RESULT(no)
fi
AM_CONDITIONAL(USE_ASPELL, $lyx_use_aspell) AM_CONDITIONAL(USE_ASPELL, $lyx_use_aspell)
AM_CONDITIONAL(USE_PSPELL, $lyx_use_pspell)
AM_CONDITIONAL(USE_ISPELL, $lyx_use_ispell)
]) ])

View File

@ -810,14 +810,8 @@ else:
# determine headers to use # determine headers to use
spell_opt = ARGUMENTS.get('spell', 'auto') spell_opt = ARGUMENTS.get('spell', 'auto')
env['USE_ASPELL'] = False env['USE_ASPELL'] = False
env['USE_PSPELL'] = False
env['USE_ISPELL'] = False
if spell_opt in ['auto', 'aspell'] and conf.CheckLib(aspell_lib): if spell_opt in ['auto', 'aspell'] and conf.CheckLib(aspell_lib):
spell_engine = 'USE_ASPELL' spell_engine = 'USE_ASPELL'
elif spell_opt in ['auto', 'pspell'] and conf.CheckLib('pspell'):
spell_engine = 'USE_PSPELL'
elif spell_opt in ['auto', 'ispell'] and conf.CheckLib('ispell'):
spell_engine = 'USE_ISPELL'
else: else:
spell_engine = None spell_engine = None
@ -1074,7 +1068,7 @@ char * strerror(int n);
) )
# these keys are needed in env # these keys are needed in env
for key in ['USE_ASPELL', 'USE_PSPELL', 'USE_ISPELL', 'HAVE_FCNTL',\ for key in ['USE_ASPELL', 'HAVE_FCNTL',\
'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB']: 'HAVE_LIBGDI32', 'HAVE_LIBAIKSAURUS', 'AIKSAURUS_LIB']:
# USE_ASPELL etc does not go through result # USE_ASPELL etc does not go through result
if result.has_key(key): if result.has_key(key):
@ -1232,8 +1226,6 @@ libs = [
('HAVE_LIBGDI32', 'gdi32'), ('HAVE_LIBGDI32', 'gdi32'),
('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']), ('HAVE_LIBAIKSAURUS', env['AIKSAURUS_LIB']),
('USE_ASPELL', aspell_lib), ('USE_ASPELL', aspell_lib),
('USE_ISPELL', 'ispell'),
('USE_PSPELL', 'pspell'),
] ]
for lib in libs: for lib in libs:
@ -1634,10 +1626,6 @@ Alias('tex2lyx', tex2lyx)
# #
if env.has_key('USE_ASPELL') and env['USE_ASPELL']: if env.has_key('USE_ASPELL') and env['USE_ASPELL']:
src_post_files.append('ASpell.cpp') src_post_files.append('ASpell.cpp')
elif env.has_key('USE_PSPELL') and env['USE_PSPELL']:
src_post_files.append('PSpell.cpp')
elif env.has_key('USE_ISPELL') and env['USE_ISPELL']:
src_post_files.append('ISpell.cpp')
# msvc requires at least one source file with main() # msvc requires at least one source file with main()
# so I exclude main.cpp from lyxbase # so I exclude main.cpp from lyxbase

View File

@ -437,8 +437,6 @@ src/insetiterator.C src/InsetIterator.cpp
src/insetiterator.h src/InsetIterator.h src/insetiterator.h src/InsetIterator.h
src/InsetList.C src/InsetList.cpp src/InsetList.C src/InsetList.cpp
#src/InsetList.h #src/InsetList.h
src/ispell.C src/ISpell.cpp
src/ispell.h src/ISpell.h
src/kbmap.C src/KbKeyMap.cpp src/kbmap.C src/KbKeyMap.cpp
src/kbmap.h src/KbKeyMap.h src/kbmap.h src/KbKeyMap.h
src/kbsequence.C src/KbSequence.cpp src/kbsequence.C src/KbSequence.cpp
@ -531,8 +529,6 @@ src/pariterator.C src/ParIterator.cpp
src/pariterator.h src/ParIterator.h src/pariterator.h src/ParIterator.h
src/PrinterParams.C src/PrinterParams.cpp src/PrinterParams.C src/PrinterParams.cpp
#src/PrinterParams.h #src/PrinterParams.h
src/pspell.C src/PSpell.cpp
src/pspell.h src/PSpell.h
src/RowList_fwd.h src/RowListFwd.h src/RowList_fwd.h src/RowListFwd.h
src/rowpainter.C src/RowPainter.cpp src/rowpainter.C src/RowPainter.cpp
src/rowpainter.h src/RowPainter.h src/rowpainter.h src/RowPainter.h

View File

@ -1,497 +0,0 @@
/**
* \file ISpell.cpp
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author unknown
* \author Angus Leeming
* \author John Levon
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "ISpell.h"
#include "BufferParams.h"
#include "Encoding.h"
#include "Language.h"
#include "LyXRC.h"
#include "WordLangTuple.h"
#include "support/debug.h"
#include "support/gettext.h"
#include "support/ForkedCalls.h"
#include "support/lstrings.h"
#include "support/unicode.h"
// HP-UX 11.x doesn't have this header
#ifdef HAVE_SYS_SELECT_H
# include <sys/select.h>
#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#endif
using boost::shared_ptr;
using namespace std;
using namespace lyx::support;
namespace lyx {
namespace {
class LaunchIspell : public ForkedProcess
{
public:
///
LaunchIspell(BufferParams const & p, string const & l,
int * in, int * out, int * err)
: params(p), lang(l), pipein(in), pipeout(out), pipeerr(err) {}
///
virtual shared_ptr<ForkedProcess> clone() const {
return shared_ptr<ForkedProcess>(new LaunchIspell(*this));
}
///
int start();
private:
///
virtual int generateChild();
///
BufferParams const & params;
string const & lang;
int * const pipein;
int * const pipeout;
int * const pipeerr;
};
int LaunchIspell::start()
{
command_ = lyxrc.isp_command;
return run(DontWait);
}
int LaunchIspell::generateChild()
{
pid_t isp_pid = fork();
if (isp_pid != 0) {
// failed (-1) or parent process (>0)
return isp_pid;
}
// child process
dup2(pipein[0], STDIN_FILENO);
dup2(pipeout[1], STDOUT_FILENO);
dup2(pipeerr[1], STDERR_FILENO);
close(pipein[0]);
close(pipein[1]);
close(pipeout[0]);
close(pipeout[1]);
close(pipeerr[0]);
close(pipeerr[1]);
char * argv[14];
int argc = 0;
char * tmp = new char[lyxrc.isp_command.length() + 1];
lyxrc.isp_command.copy(tmp, lyxrc.isp_command.length());
tmp[lyxrc.isp_command.length()] = '\0';
argv[argc++] = tmp;
tmp = new char[3];
string("-a").copy(tmp, 2); tmp[2] = '\0'; // pipe mode
argv[argc++] = tmp;
if (lang != "default") {
tmp = new char[3];
string("-d").copy(tmp, 2); tmp[2] = '\0'; // Dictionary file
argv[argc++] = tmp;
tmp = new char[lang.length() + 1];
lang.copy(tmp, lang.length()); tmp[lang.length()] = '\0';
argv[argc++] = tmp;
}
if (lyxrc.isp_accept_compound) {
// Consider run-together words as legal compounds
tmp = new char[3];
string("-C").copy(tmp, 2); tmp[2] = '\0';
argv[argc++] = tmp;
} else {
// Report run-together words with
// missing blanks as errors
tmp = new char[3];
string("-B").copy(tmp, 2); tmp[2] = '\0';
argv[argc++] = tmp;
}
if (lyxrc.isp_use_esc_chars) {
// Specify additional characters that
// can be part of a word
tmp = new char[3];
string("-w").copy(tmp, 2); tmp[2] = '\0';
argv[argc++] = tmp;
// Put the escape chars in ""s
string tms = '"' + lyxrc.isp_esc_chars + '"';
tmp = new char[tms.length() + 1];
tms.copy(tmp, tms.length()); tmp[tms.length()] = '\0';
argv[argc++] = tmp;
}
if (lyxrc.isp_use_pers_dict) {
// Specify an alternate personal dictionary
tmp = new char[3];
string("-p").copy(tmp, 2);
tmp[2]= '\0';
argv[argc++] = tmp;
tmp = new char[lyxrc.isp_pers_dict.length() + 1];
lyxrc.isp_pers_dict.copy(tmp, lyxrc.isp_pers_dict.length());
tmp[lyxrc.isp_pers_dict.length()] = '\0';
argv[argc++] = tmp;
}
if (lyxrc.isp_use_input_encoding &&
params.inputenc != "default") {
string enc = (params.inputenc == "auto")
? params.language->encoding()->latexName()
: params.inputenc;
size_t const n = enc.length();
tmp = new char[3];
string("-T").copy(tmp, 2);
tmp[2] = '\0';
argv[argc++] = tmp; // Input encoding
tmp = new char[n + 1];
enc.copy(tmp, n);
tmp[n] = '\0';
argv[argc++] = tmp;
}
argv[argc++] = 0;
execvp(argv[0], const_cast<char * const *>(argv));
// free the memory used by string::copy in the
// setup of argv
for (int i = 0; i < argc - 1; ++i)
delete[] argv[i];
lyxerr << "LyX: Failed to start ispell!" << endl;
_exit(0);
}
string const to_iconv_encoding(docstring const & s, string const & encoding)
{
if (lyxrc.isp_use_input_encoding) {
vector<char> const encoded =
ucs4_to_eightbit(s.data(), s.length(), encoding);
return string(encoded.begin(), encoded.end());
}
// FIXME UNICODE: we don't need to convert to UTF8, but probably to the locale encoding
return to_utf8(s);
}
docstring const from_iconv_encoding(string const & s, string const & encoding)
{
if (lyxrc.isp_use_input_encoding) {
vector<char_type> const ucs4 =
eightbit_to_ucs4(s.data(), s.length(), encoding);
return docstring(ucs4.begin(), ucs4.end());
}
// FIXME UNICODE: s is not in UTF8, but probably the locale encoding
return from_utf8(s);
}
} // namespace anon
ISpell::ISpell(BufferParams const & params, string const & lang)
: in(0), out(0), inerr(0), str(0)
{
//LYXERR(Debug::GUI, "Created ispell");
encoding = params.encoding().iconvName();
// static due to the setvbuf. Ugly.
static char o_buf[BUFSIZ];
// We need to throw an exception not do this
pipein[0] = pipein[1] = pipeout[0] = pipeout[1]
= pipeerr[0] = pipeerr[1] = -1;
// This is what happens when goto gets banned.
if (pipe(pipein) == -1) {
error_ = _("Can't create pipe for spellchecker.");
return;
}
if (pipe(pipeout) == -1) {
close(pipein[0]);
close(pipein[1]);
error_ = _("Can't create pipe for spellchecker.");
return;
}
if (pipe(pipeerr) == -1) {
close(pipein[0]);
close(pipein[1]);
close(pipeout[0]);
close(pipeout[1]);
error_ = _("Can't create pipe for spellchecker.");
return;
}
if ((out = fdopen(pipein[1], "w")) == 0) {
error_ = _("Can't open pipe for spellchecker.");
return;
}
if ((in = fdopen(pipeout[0], "r")) == 0) {
error_ = _("Can't open pipe for spellchecker.");
return;
}
if ((inerr = fdopen(pipeerr[0], "r")) == 0) {
error_ = _("Can't open pipe for spellchecker.");
return;
}
setvbuf(out, o_buf, _IOLBF, BUFSIZ);
LaunchIspell * li = new LaunchIspell(params, lang, pipein, pipeout, pipeerr);
child_.reset(li);
if (li->start() == -1) {
error_ = _("Could not create an ispell process.\nYou may not have "
"the right languages installed.");
child_.reset(0);
return;
}
// Parent process: Read ispells identification message
bool err_read;
bool error = select(err_read);
if (!error) {
if (!err_read) {
// Set terse mode (silently accept correct words)
fputs("!\n", out);
return;
}
// must have read something from stderr
// FIXME UNICODE: buf is not in UTF8, but probably the locale encoding
error_ = from_utf8(buf);
} else {
// select returned error
error_ = _("The ispell process returned an error.\nPerhaps "
"it has been configured wrongly ?");
}
close(pipein[0]);
close(pipein[1]);
close(pipeout[0]);
close(pipeout[1]);
close(pipeerr[0]);
close(pipeerr[1]);
child_->kill();
child_.reset(0);
}
ISpell::~ISpell()
{
//LYXERR(Debug::GUI, "Killing ispell");
if (in)
fclose(in);
if (inerr)
fclose(inerr);
if (out) {
fputs("#\n", out); // Save personal dictionary
fflush(out);
fclose(out);
}
close(pipein[0]);
close(pipein[1]);
close(pipeout[0]);
close(pipeout[1]);
close(pipeerr[0]);
close(pipeerr[1]);
delete [] str;
}
bool ISpell::select(bool & err_read)
{
fd_set infds;
struct timeval tv;
int retval = 0;
FD_ZERO(&infds);
FD_SET(pipeout[0], &infds);
FD_SET(pipeerr[0], &infds);
tv.tv_sec = 2;
tv.tv_usec = 0;
retval = ::select(SELECT_TYPE_ARG1 (max(pipeout[0], pipeerr[0]) + 1),
SELECT_TYPE_ARG234 (&infds),
0,
0,
SELECT_TYPE_ARG5 (&tv));
// error
if (retval <= 0)
return true;
if (FD_ISSET(pipeerr[0], &infds)) {
fgets(buf, BUFSIZ, inerr);
err_read = true;
return false;
}
fgets(buf, BUFSIZ, in);
err_read = false;
return false;
}
docstring const ISpell::nextMiss()
{
// Well, somebody is a sick fuck.
if (str == 0 || *(e+1) == '\0')
return docstring();
char * b = e + 2;
e = strpbrk(b, ",\n");
*e = '\0';
if (b)
return from_iconv_encoding(b, encoding);
return docstring();
}
bool ISpell::alive()
{
return child_.get() && child_->running();
}
enum ISpell::Result ISpell::check(WordLangTuple const & word)
{
// FIXME Please rewrite to use string.
Result res;
string const encoded = to_iconv_encoding(word.word(), encoding);
if (encoded.empty()) {
error_ = bformat(
_("Could not check word `%1$s' because it could not be converted to encoding `%2$s'."),
word.word(), from_ascii(encoding));
return UNKNOWN_WORD;
}
::fputs(encoded.c_str(), out);
::fputc('\n', out);
bool err_read;
bool error = select(err_read);
if (error) {
error_ = _("Could not communicate with the ispell spellchecker process.");
return UNKNOWN_WORD;
}
if (err_read) {
// FIXME UNICODE: buf is not in UTF8, but probably the locale encoding
error_ = from_utf8(buf);
return UNKNOWN_WORD;
}
// I think we have to check if ispell is still alive here because
// the signal-handler could have disabled blocking on the fd
if (!alive())
return UNKNOWN_WORD;
switch (*buf) {
case '*':
res = OK;
break;
case '+':
res = ROOT;
break;
case '-':
res = COMPOUND_WORD;
break;
case '\n':
res = IGNORED_WORD;
break;
case '#': // Not found, no near misses and guesses
res = UNKNOWN_WORD;
break;
case '?': // Not found, and no near misses, but guesses (guesses are ignored)
case '&': // Not found, but we have near misses
{
res = SUGGESTED_WORDS;
char * p = strpbrk(buf, ":");
str = new char[strlen(p) + 1];
e = str;
strcpy(str, p);
break;
}
default: // This shouldn't happen, but you know Murphy
res = UNKNOWN_WORD;
}
*buf = 0;
if (res != IGNORED_WORD) {
/* wait for ispell to finish */
while (*buf!= '\n')
fgets(buf, 255, in);
}
return res;
}
void ISpell::insert(WordLangTuple const & word)
{
string const encoded = to_iconv_encoding(word.word(), encoding);
if (encoded.empty()) {
error_ = bformat(
_("Could not insert word `%1$s' because it could not be converted to encoding `%2$s'."),
word.word(), from_ascii(encoding));
return;
}
::fputc('*', out); // Insert word in personal dictionary
::fputs(encoded.c_str(), out);
::fputc('\n', out);
}
void ISpell::accept(WordLangTuple const & word)
{
string const encoded = to_iconv_encoding(word.word(), encoding);
if (encoded.empty()) {
error_ = bformat(
_("Could not accept word `%1$s' because it could not be converted to encoding `%2$s'."),
word.word(), from_ascii(encoding));
return;
}
::fputc('@', out); // Accept in this session
::fputs(encoded.c_str(), out);
::fputc('\n', out);
}
docstring const ISpell::error()
{
return error_;
}
} // namespace lyx

View File

@ -1,93 +0,0 @@
// -*- C++ -*-
/**
* \file ISpell.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author unknown
* \author John Levon
*
* Full author contact details are available in file CREDITS.
*/
#ifndef SP_ISPELL_H
#define SP_ISPELL_H
#include "SpellBase.h"
#include "support/docstring.h"
#include <boost/scoped_ptr.hpp>
#include <cstdio>
namespace lyx {
class BufferParams;
namespace support { class ForkedProcess; }
/// i/a spell process-based spellchecker
class ISpell : public SpellBase {
public:
ISpell(BufferParams const & params, std::string const & lang);
~ISpell();
/// return true if the spellchecker instance still exists
virtual bool alive();
/// check the given word and return the result
virtual enum Result check(WordLangTuple const & word);
/// insert the given word into the personal dictionary
virtual void insert(WordLangTuple const & word);
/// accept the given word temporarily
virtual void accept(WordLangTuple const & word);
/// return the next near miss after a SUGGESTED_WORDS result
virtual docstring const nextMiss();
/// give an error message on messy exit
virtual docstring const error();
private:
/// read some data. Returns true on an error. Sets err_read
/// to true if the data was from stderr.
bool select(bool & err_read);
/// instream to communicate with ispell
FILE * in;
/// outstream to communicate with ispell
FILE * out;
/// errstream for ispell
FILE * inerr;
/// pipe fds
int pipein[2];
int pipeout[2];
int pipeerr[2];
/// buffer for reading
char buf[BUFSIZ];
/// spell error
docstring error_;
boost::scoped_ptr<support::ForkedProcess> child_;
/// iconv name of the encoding that is used to communicate with ispell
std::string encoding;
// vileness below ... please FIXME
/// str ???
char * str;
/// e ???
char * e;
};
} // namespace lyx
#endif // ISPELL_H

View File

@ -261,12 +261,12 @@ void LyXRC::setDefaults()
display_graphics = true; display_graphics = true;
// Spellchecker settings: // Spellchecker settings:
use_spell_lib = true; use_spell_lib = true;
isp_command = "ispell"; spellchecker_command = "aspell";
isp_accept_compound = false; spellchecker_accept_compound = false;
isp_use_input_encoding = false; spellchecker_use_input_encoding = false;
isp_use_alt_lang = false; spellchecker_use_alt_lang = false;
isp_use_pers_dict = false; spellchecker_use_pers_dict = false;
isp_use_esc_chars = false; spellchecker_use_esc_chars = false;
use_kbmap = false; use_kbmap = false;
rtl_support = true; rtl_support = true;
visual_cursor = false; visual_cursor = false;
@ -842,19 +842,19 @@ int LyXRC::read(Lexer & lexrc)
break; break;
case RC_SPELL_COMMAND: case RC_SPELL_COMMAND:
if (lexrc.next(true)) if (lexrc.next(true))
isp_command = lexrc.getString(); spellchecker_command = lexrc.getString();
break; break;
case RC_ACCEPT_COMPOUND: case RC_ACCEPT_COMPOUND:
lexrc >> isp_accept_compound; lexrc >> spellchecker_accept_compound;
break; break;
case RC_USE_INP_ENC: case RC_USE_INP_ENC:
lexrc >> isp_use_input_encoding; lexrc >> spellchecker_use_input_encoding;
break; break;
case RC_USE_ALT_LANG: case RC_USE_ALT_LANG:
lexrc >> isp_use_alt_lang; lexrc >> spellchecker_use_alt_lang;
break; break;
case RC_USE_PERS_DICT: case RC_USE_PERS_DICT:
lexrc >> isp_use_pers_dict; lexrc >> spellchecker_use_pers_dict;
break; break;
case RC_USE_TOOLTIP: case RC_USE_TOOLTIP:
lexrc >> use_tooltip; lexrc >> use_tooltip;
@ -863,17 +863,17 @@ int LyXRC::read(Lexer & lexrc)
lexrc >> use_pixmap_cache; lexrc >> use_pixmap_cache;
break; break;
case RC_USE_ESC_CHARS: case RC_USE_ESC_CHARS:
lexrc >> isp_use_esc_chars; lexrc >> spellchecker_use_esc_chars;
break; break;
case RC_ALT_LANG: case RC_ALT_LANG:
lexrc >> isp_alt_lang; lexrc >> spellchecker_alt_lang;
break; break;
case RC_PERS_DICT: case RC_PERS_DICT:
if (lexrc.next()) if (lexrc.next())
isp_pers_dict = os::internal_path(lexrc.getString()); spellchecker_pers_dict = os::internal_path(lexrc.getString());
break; break;
case RC_ESC_CHARS: case RC_ESC_CHARS:
lexrc >> isp_esc_chars; lexrc >> spellchecker_esc_chars;
break; break;
case RC_MAKE_BACKUP: case RC_MAKE_BACKUP:
lexrc >> make_backup; lexrc >> make_backup;
@ -2096,55 +2096,55 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc, string const & name) c
break; break;
case RC_SPELL_COMMAND: case RC_SPELL_COMMAND:
if (ignore_system_lyxrc || if (ignore_system_lyxrc ||
isp_command != system_lyxrc.isp_command) { spellchecker_command != system_lyxrc.spellchecker_command) {
os << "\\spell_command \"" << escapeCommand(isp_command) << "\"\n"; os << "\\spell_command \"" << escapeCommand(spellchecker_command) << "\"\n";
} }
if (tag != RC_LAST) if (tag != RC_LAST)
break; break;
case RC_ACCEPT_COMPOUND: case RC_ACCEPT_COMPOUND:
if (ignore_system_lyxrc || if (ignore_system_lyxrc ||
isp_accept_compound != system_lyxrc.isp_accept_compound) { spellchecker_accept_compound != system_lyxrc.spellchecker_accept_compound) {
os << "\\accept_compound " << convert<string>(isp_accept_compound) os << "\\accept_compound " << convert<string>(spellchecker_accept_compound)
<< '\n'; << '\n';
} }
if (tag != RC_LAST) if (tag != RC_LAST)
break; break;
case RC_USE_ALT_LANG: case RC_USE_ALT_LANG:
if (ignore_system_lyxrc || if (ignore_system_lyxrc ||
isp_use_alt_lang != system_lyxrc.isp_use_alt_lang) { spellchecker_use_alt_lang != system_lyxrc.spellchecker_use_alt_lang) {
os << "\\use_alt_language " << convert<string>(isp_use_alt_lang) os << "\\use_alt_language " << convert<string>(spellchecker_use_alt_lang)
<< '\n'; << '\n';
} }
if (tag != RC_LAST) if (tag != RC_LAST)
break; break;
case RC_ALT_LANG: case RC_ALT_LANG:
if (ignore_system_lyxrc || if (ignore_system_lyxrc ||
isp_alt_lang != system_lyxrc.isp_alt_lang) { spellchecker_alt_lang != system_lyxrc.spellchecker_alt_lang) {
os << "\\alternate_language \"" << isp_alt_lang os << "\\alternate_language \"" << spellchecker_alt_lang
<< "\"\n"; << "\"\n";
} }
if (tag != RC_LAST) if (tag != RC_LAST)
break; break;
case RC_USE_ESC_CHARS: case RC_USE_ESC_CHARS:
if (ignore_system_lyxrc || if (ignore_system_lyxrc ||
isp_use_esc_chars != system_lyxrc.isp_use_esc_chars) { spellchecker_use_esc_chars != system_lyxrc.spellchecker_use_esc_chars) {
os << "\\use_escape_chars " << convert<string>(isp_use_esc_chars) os << "\\use_escape_chars " << convert<string>(spellchecker_use_esc_chars)
<< '\n'; << '\n';
} }
if (tag != RC_LAST) if (tag != RC_LAST)
break; break;
case RC_ESC_CHARS: case RC_ESC_CHARS:
if (ignore_system_lyxrc || if (ignore_system_lyxrc ||
isp_esc_chars != system_lyxrc.isp_esc_chars) { spellchecker_esc_chars != system_lyxrc.spellchecker_esc_chars) {
os << "\\escape_chars \"" << isp_esc_chars << "\"\n"; os << "\\escape_chars \"" << spellchecker_esc_chars << "\"\n";
} }
if (tag != RC_LAST) if (tag != RC_LAST)
break; break;
case RC_USE_PERS_DICT: case RC_USE_PERS_DICT:
if (ignore_system_lyxrc || if (ignore_system_lyxrc ||
isp_use_pers_dict != system_lyxrc.isp_use_pers_dict) { spellchecker_use_pers_dict != system_lyxrc.spellchecker_use_pers_dict) {
os << "\\use_personal_dictionary " os << "\\use_personal_dictionary "
<< convert<string>(isp_use_pers_dict) << convert<string>(spellchecker_use_pers_dict)
<< '\n'; << '\n';
} }
if (tag != RC_LAST) if (tag != RC_LAST)
@ -2164,18 +2164,18 @@ void LyXRC::write(ostream & os, bool ignore_system_lyxrc, string const & name) c
<< '\n'; << '\n';
} }
case RC_PERS_DICT: case RC_PERS_DICT:
if (isp_pers_dict != system_lyxrc.isp_pers_dict) { if (spellchecker_pers_dict != system_lyxrc.spellchecker_pers_dict) {
string const path = os::external_path(isp_pers_dict); string const path = os::external_path(spellchecker_pers_dict);
os << "\\personal_dictionary \"" << path << "\"\n"; os << "\\personal_dictionary \"" << path << "\"\n";
} }
if (tag != RC_LAST) if (tag != RC_LAST)
break; break;
case RC_USE_INP_ENC: case RC_USE_INP_ENC:
if (ignore_system_lyxrc || if (ignore_system_lyxrc ||
isp_use_input_encoding spellchecker_use_input_encoding
!= system_lyxrc.isp_use_input_encoding) { != system_lyxrc.spellchecker_use_input_encoding) {
os << "\\use_input_encoding " os << "\\use_input_encoding "
<< convert<string>(isp_use_input_encoding) << convert<string>(spellchecker_use_input_encoding)
<< '\n'; << '\n';
} }
if (tag != RC_LAST) if (tag != RC_LAST)

View File

@ -308,28 +308,28 @@ public:
unsigned int plaintext_linelen; unsigned int plaintext_linelen;
/// use library instead of process /// use library instead of process
bool use_spell_lib; bool use_spell_lib;
/// Ispell command /// spellchecker command
std::string isp_command; std::string spellchecker_command;
/// Accept compound words in spellchecker? /// Accept compound words in spellchecker?
bool isp_accept_compound; bool spellchecker_accept_compound;
/// Pass input encoding switch to ispell? /// Pass input encoding switch to the spellchecker?
bool isp_use_input_encoding; bool spellchecker_use_input_encoding;
/// Use alternate language? /// Use alternate language?
bool isp_use_alt_lang; bool spellchecker_use_alt_lang;
/// Use personal dictionary? /// Use personal dictionary?
bool isp_use_pers_dict; bool spellchecker_use_pers_dict;
/// Use tooltips? /// Use tooltips?
bool use_tooltip; bool use_tooltip;
/// Use pixmap cache? /// Use pixmap cache?
bool use_pixmap_cache; bool use_pixmap_cache;
/// Use escape chars? /// Use escape chars?
bool isp_use_esc_chars; bool spellchecker_use_esc_chars;
/// Alternate language for ispell /// Alternate language for ispell
std::string isp_alt_lang; std::string spellchecker_alt_lang;
/// Alternate personal dictionary file for ispell /// Alternate personal dictionary file for the spellchecker
std::string isp_pers_dict; std::string spellchecker_pers_dict;
/// Escape characters /// Escape characters
std::string isp_esc_chars; std::string spellchecker_esc_chars;
/// ///
bool use_kbmap; bool use_kbmap;
/// ///

View File

@ -49,12 +49,6 @@ BUILT_SOURCES = $(PCH_FILE)
if USE_ASPELL if USE_ASPELL
ASPELL = ASpell.cpp ASpell_local.h ASPELL = ASpell.cpp ASpell_local.h
endif endif
if USE_PSPELL
PSPELL = PSpell.cpp PSpell.h
endif
if USE_ISPELL
ISPELL = ISpell.cpp ISpell.h
endif
# These four objects are linked as object files as they are not # These four objects are linked as object files as they are not
# referenced within the core and therefore are not picked up # referenced within the core and therefore are not picked up

View File

@ -1,161 +0,0 @@
/**
* \file PSpell.cpp
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Kevin Atkinson
* \author John Levon
*
* Full author contact details are available in file CREDITS.
*/
#include <config.h>
#include "support/debug.h"
#define USE_ORIGINAL_MANAGER_FUNCS 1
// new aspell pspell missing extern "C"
extern "C" {
#include <pspell/PSpell.h>
}
#include "PSpell.h"
#include "WordLangTuple.h"
#include "support/lassert.h"
using namespace std;
using namespace lyx::support;
namespace lyx {
PSpell::PSpell(BufferParams const &, string const & lang)
: els(0), spell_error_object(0)
{
addManager(lang);
LYXERR(Debug::GUI, "created pspell");
}
PSpell::~PSpell()
{
LYXERR(Debug::GUI, "killed pspell");
if (spell_error_object) {
delete_pspell_can_have_error(spell_error_object);
spell_error_object = 0;
}
if (els)
delete_pspell_string_emulation(els);
Managers::iterator it = managers_.begin();
Managers::iterator end = managers_.end();
for (; it != end; ++it) {
pspell_manager_save_all_word_lists(it->second.manager);
delete_pspell_manager(it->second.manager);
delete_pspell_config(it->second.config);
}
}
void PSpell::addManager(string const & lang)
{
PspellConfig * config = new_pspell_config();
pspell_config_replace(config, "language-tag", lang.c_str());
pspell_config_replace(config, "encoding", "utf-8");
PspellCanHaveError * err = new_pspell_manager(config);
if (spell_error_object)
delete_pspell_can_have_error(spell_error_object);
spell_error_object = 0;
if (pspell_error_number(err) == 0) {
Manager m;
m.manager = to_pspell_manager(err);
m.config = config;
managers_[lang] = m;
} else {
spell_error_object = err;
}
}
enum PSpell::Result PSpell::check(WordLangTuple const & word)
{
Result res = UNKNOWN_WORD;
Managers::iterator it = managers_.find(word.lang_code());
if (it == managers_.end()) {
addManager(word.lang_code());
it = managers_.find(word.lang_code());
// FIXME
if (it == managers_.end())
return res;
}
PspellManager * m = it->second.manager;
int word_ok = pspell_manager_check(m, to_utf8(word.word()).c_str());
LASSERT(word_ok != -1, /**/);
if (word_ok) {
res = OK;
} else {
PspellWordList const * sugs =
pspell_manager_suggest(m, to_utf8(word.word()).c_str());
LASSERT(sugs != 0, /**/);
els = pspell_word_list_elements(sugs);
if (pspell_word_list_empty(sugs))
res = UNKNOWN_WORD;
else
res = SUGGESTED_WORDS;
}
return res;
}
void PSpell::insert(WordLangTuple const & word)
{
Managers::iterator it = managers_.find(word.lang_code());
if (it != managers_.end())
pspell_manager_add_to_personal(it->second.manager, to_utf8(word.word()).c_str());
}
void PSpell::accept(WordLangTuple const & word)
{
Managers::iterator it = managers_.find(word.lang_code());
if (it != managers_.end())
pspell_manager_add_to_session(it->second.manager, to_utf8(word.word()).c_str());
}
docstring const PSpell::nextMiss()
{
char const * str = 0;
if (els)
str = pspell_string_emulation_next(els);
if (str)
return from_utf8(str);
return docstring();
}
docstring const PSpell::error()
{
char const * err = 0;
if (spell_error_object && pspell_error_number(spell_error_object) != 0) {
err = pspell_error_message(spell_error_object);
}
if (err)
return from_utf8(err);
return docstring();
}
} // namespace lyx

View File

@ -1,84 +0,0 @@
// -*- C++ -*-
/**
* \file PSpell.h
* This file is part of LyX, the document processor.
* Licence details can be found in the file COPYING.
*
* \author Kevin Atkinson
* \author John Levon
*
* Full author contact details are available in file CREDITS.
*/
#ifndef LYX_PSPELL_H
#define LYX_PSPELL_H
#include "SpellBase.h"
#include <map>
class PspellManager;
class PspellStringEmulation;
class PspellCanHaveError;
class PspellConfig;
namespace lyx {
class BufferParams;
class PSpell : public SpellBase {
public:
/**
* Initialise the spellchecker with the given buffer params and language.
*/
PSpell(BufferParams const & params, std::string const & lang);
virtual ~PSpell();
/**
* return true if the spellchecker instance still exists
* Always true for pspell, since there is no separate process
*/
virtual bool alive() { return true; }
/// check the given word and return the result
virtual enum Result check(WordLangTuple const &);
/// insert the given word into the personal dictionary
virtual void insert(WordLangTuple const &);
/// accept the given word temporarily
virtual void accept(WordLangTuple const &);
/// return the next near miss after a SUGGESTED_WORDS result
virtual docstring const nextMiss();
/// give an error message on messy exit
virtual docstring const error();
private:
/// add a manager of the given language
void addManager(std::string const & lang);
struct Manager {
PspellManager * manager;
PspellConfig * config;
};
typedef std::map<std::string, struct Manager> Managers;
/// the managers
Managers managers_;
/// FIXME
PspellStringEmulation * els;
/// FIXME
PspellCanHaveError * spell_error_object;
};
} // namespace lyx
#endif // LYX_PSPELL_H

View File

@ -1039,12 +1039,8 @@ PrefSpellchecker::PrefSpellchecker(GuiPreferences * form)
setupUi(this); setupUi(this);
connect(persDictionaryPB, SIGNAL(clicked()), this, SLOT(select_dict())); connect(persDictionaryPB, SIGNAL(clicked()), this, SLOT(select_dict()));
#if defined (USE_ISPELL)
connect(spellCommandCO, SIGNAL(activated(int)),
this, SIGNAL(changed()));
#else
spellCommandCO->setEnabled(false); spellCommandCO->setEnabled(false);
#endif
connect(altLanguageED, SIGNAL(textChanged(QString)), connect(altLanguageED, SIGNAL(textChanged(QString)),
this, SIGNAL(changed())); this, SIGNAL(changed()));
connect(escapeCharactersED, SIGNAL(textChanged(QString)), connect(escapeCharactersED, SIGNAL(textChanged(QString)),
@ -1056,16 +1052,10 @@ PrefSpellchecker::PrefSpellchecker(GuiPreferences * form)
connect(inputEncodingCB, SIGNAL(clicked()), connect(inputEncodingCB, SIGNAL(clicked()),
this, SIGNAL(changed())); this, SIGNAL(changed()));
spellCommandCO->addItem(qt_("ispell"));
spellCommandCO->addItem(qt_("aspell")); spellCommandCO->addItem(qt_("aspell"));
spellCommandCO->addItem(qt_("hspell"));
#ifdef USE_PSPELL
spellCommandCO->addItem(qt_("pspell (library)"));
#else
#ifdef USE_ASPELL #ifdef USE_ASPELL
spellCommandCO->addItem(qt_("aspell (library)")); spellCommandCO->addItem(qt_("aspell (library)"));
#endif #endif
#endif
} }
@ -1073,27 +1063,25 @@ void PrefSpellchecker::apply(LyXRC & rc) const
{ {
switch (spellCommandCO->currentIndex()) { switch (spellCommandCO->currentIndex()) {
case 0: case 0:
case 1:
case 2:
rc.use_spell_lib = false; rc.use_spell_lib = false;
rc.isp_command = fromqstr(spellCommandCO->currentText()); rc.spellchecker_command = fromqstr(spellCommandCO->currentText());
break; break;
case 3: case 1:
rc.use_spell_lib = true; rc.use_spell_lib = true;
break; break;
} }
// FIXME: remove isp_use_alt_lang // FIXME: remove spellchecker_use_alt_lang
rc.isp_alt_lang = fromqstr(altLanguageED->text()); rc.spellchecker_alt_lang = fromqstr(altLanguageED->text());
rc.isp_use_alt_lang = !rc.isp_alt_lang.empty(); rc.spellchecker_use_alt_lang = !rc.spellchecker_alt_lang.empty();
// FIXME: remove isp_use_esc_chars // FIXME: remove spellchecker_use_esc_chars
rc.isp_esc_chars = fromqstr(escapeCharactersED->text()); rc.spellchecker_esc_chars = fromqstr(escapeCharactersED->text());
rc.isp_use_esc_chars = !rc.isp_esc_chars.empty(); rc.spellchecker_use_esc_chars = !rc.spellchecker_esc_chars.empty();
// FIXME: remove isp_use_pers_dict // FIXME: remove spellchecker_use_pers_dict
rc.isp_pers_dict = internal_path(fromqstr(persDictionaryED->text())); rc.spellchecker_pers_dict = internal_path(fromqstr(persDictionaryED->text()));
rc.isp_use_pers_dict = !rc.isp_pers_dict.empty(); rc.spellchecker_use_pers_dict = !rc.spellchecker_pers_dict.empty();
rc.isp_accept_compound = compoundWordCB->isChecked(); rc.spellchecker_accept_compound = compoundWordCB->isChecked();
rc.isp_use_input_encoding = inputEncodingCB->isChecked(); rc.spellchecker_use_input_encoding = inputEncodingCB->isChecked();
} }
@ -1101,28 +1089,23 @@ void PrefSpellchecker::update(LyXRC const & rc)
{ {
spellCommandCO->setCurrentIndex(0); spellCommandCO->setCurrentIndex(0);
if (rc.isp_command == "ispell") { if (rc.spellchecker_command == "aspell")
spellCommandCO->setCurrentIndex(0); spellCommandCO->setCurrentIndex(0);
} else if (rc.isp_command == "aspell") {
spellCommandCO->setCurrentIndex(1);
} else if (rc.isp_command == "hspell") {
spellCommandCO->setCurrentIndex(2);
}
if (rc.use_spell_lib) { if (rc.use_spell_lib) {
#if defined(USE_ASPELL) || defined(USE_PSPELL) #if defined(USE_ASPELL)
spellCommandCO->setCurrentIndex(3); spellCommandCO->setCurrentIndex(1);
#endif #endif
} }
// FIXME: remove isp_use_alt_lang // FIXME: remove spellchecker_use_alt_lang
altLanguageED->setText(toqstr(rc.isp_alt_lang)); altLanguageED->setText(toqstr(rc.spellchecker_alt_lang));
// FIXME: remove isp_use_esc_chars // FIXME: remove spellchecker_use_esc_chars
escapeCharactersED->setText(toqstr(rc.isp_esc_chars)); escapeCharactersED->setText(toqstr(rc.spellchecker_esc_chars));
// FIXME: remove isp_use_pers_dict // FIXME: remove spellchecker_use_pers_dict
persDictionaryED->setText(toqstr(external_path(rc.isp_pers_dict))); persDictionaryED->setText(toqstr(external_path(rc.spellchecker_pers_dict)));
compoundWordCB->setChecked(rc.isp_accept_compound); compoundWordCB->setChecked(rc.spellchecker_accept_compound);
inputEncodingCB->setChecked(rc.isp_use_input_encoding); inputEncodingCB->setChecked(rc.spellchecker_use_input_encoding);
} }

View File

@ -34,15 +34,9 @@
#if defined(USE_ASPELL) #if defined(USE_ASPELL)
# include "ASpell_local.h" # include "ASpell_local.h"
#elif defined(USE_PSPELL)
# include "PSpell.h"
#endif #endif
#if defined(USE_ISPELL) #include "SpellBase.h"
# include "ISpell.h"
#else
# include "SpellBase.h"
#endif
#include "frontends/alert.h" #include "frontends/alert.h"
@ -200,26 +194,15 @@ void GuiSpellchecker::partialUpdate(int state)
static SpellBase * createSpeller(BufferParams const & bp) static SpellBase * createSpeller(BufferParams const & bp)
{ {
string lang = (lyxrc.isp_use_alt_lang) string lang = lyxrc.spellchecker_use_alt_lang
? lyxrc.isp_alt_lang ? lyxrc.spellchecker_alt_lang
: bp.language->code(); : bp.language->code();
#if defined(USE_ASPELL) #if defined(USE_ASPELL)
if (lyxrc.use_spell_lib) if (lyxrc.use_spell_lib)
return new ASpell(bp, lang); return new ASpell(bp, lang);
#elif defined(USE_PSPELL)
if (lyxrc.use_spell_lib)
return new PSpell(bp, lang);
#endif #endif
#if defined(USE_ISPELL)
lang = lyxrc.isp_use_alt_lang ?
lyxrc.isp_alt_lang : bp.language->lang();
return new ISpell(bp, lang);
#else
return new SpellBase; return new SpellBase;
#endif
} }
@ -265,7 +248,7 @@ static bool isLetter(DocIterator const & dit)
&& dit.pos() != dit.lastpos() && dit.pos() != dit.lastpos()
&& (dit.paragraph().isLetter(dit.pos()) && (dit.paragraph().isLetter(dit.pos())
// We want to pass the ' and escape chars to ispell // We want to pass the ' and escape chars to ispell
|| contains(from_utf8(lyxrc.isp_esc_chars + '\''), || contains(from_utf8(lyxrc.spellchecker_esc_chars + '\''),
dit.paragraph().getChar(dit.pos()))) dit.paragraph().getChar(dit.pos())))
&& !dit.paragraph().isDeleted(dit.pos()); && !dit.paragraph().isDeleted(dit.pos());
} }

View File

@ -1178,7 +1178,7 @@ bool GuiView::getStatus(FuncRequest const & cmd, FuncStatus & flag)
else if (name == "latexlog") else if (name == "latexlog")
enable = FileName(buf->logName()).isReadableFile(); enable = FileName(buf->logName()).isReadableFile();
else if (name == "spellchecker") else if (name == "spellchecker")
#if defined (USE_ASPELL) || defined (USE_ISPELL) || defined (USE_PSPELL) #if defined (USE_ASPELL)
enable = !buf->isReadonly(); enable = !buf->isReadonly();
#else #else
enable = false; enable = false;

View File

@ -34,7 +34,6 @@ Resources.cpp: Resources.qrc
noinst_LIBRARIES = liblyxqt4.a noinst_LIBRARIES = liblyxqt4.a
liblyxqt4_a_DEPENDENCIES = $(MOCEDFILES) liblyxqt4_a_DEPENDENCIES = $(MOCEDFILES)
#liblyxqt4_a_LIBADD = $(QT4_LIB) $(QT4_LDFLAGS)
AM_CPPFLAGS += \ AM_CPPFLAGS += \
$(QT4_CPPFLAGS) \ $(QT4_CPPFLAGS) \