]> git.lyx.org Git - lyx.git/commitdiff
Support for new GNU aspell library. Final pspell fix ups.
authorJohn Levon <levon@movementarian.org>
Wed, 26 Mar 2003 01:20:25 +0000 (01:20 +0000)
committerJohn Levon <levon@movementarian.org>
Wed, 26 Mar 2003 01:20:25 +0000 (01:20 +0000)
git-svn-id: svn://svn.lyx.org/lyx/lyx-devel/trunk@6578 a592a061-630c-0410-9148-cb99ea01b6c8

16 files changed:
ChangeLog
autogen.sh
config/ChangeLog
config/Makefile.am
config/aspell.m4 [new file with mode: 0644]
config/configure.ac
config/configure.in
config/pspell.m4
src/ChangeLog
src/Makefile.am
src/aspell.C [new file with mode: 0644]
src/aspell_local.h [new file with mode: 0644]
src/frontends/controllers/ChangeLog
src/frontends/controllers/ControlSpellchecker.C
src/lyxrc.C
src/lyxrc.h

index 3371bb754602e1e4407adeada798336865ff8f1f..2433626cbe2941657cc08ff7b8df5dcc6dfa089b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2003-03-25  John Levon  <levon@movementarian.org>
+
+       * autogen.sh: add aspell.m4
+
 2003-03-12  Kayvan Sylvan  <kayvan@sylvan.com>
 
        * autogen.sh (ACINCLUDE_FILES): Added cygwin.m4
index 7583232366f898ba1479c5764646804ff2d5ed3c..1b567a9fc2f924d10a145708aab919c47d46daf7 100755 (executable)
@@ -4,7 +4,7 @@ ACLOCAL="aclocal"
 AUTOHEADER="autoheader"
 AUTOMAKE="automake -a -c --foreign"
 AUTOCONF="autoconf"
-ACINCLUDE_FILES="lyxinclude.m4 libtool.m4 codeset.m4 gettext.m4 glibc21.m4 iconv.m4 isc-posix.m4 lcmessage.m4 progtest.m4 xforms.m4 qt.m4 gtk--.m4 gnome--.m4 gnome.m4 pspell.m4 cygwin.m4 pkg.m4"
+ACINCLUDE_FILES="lyxinclude.m4 libtool.m4 codeset.m4 gettext.m4 glibc21.m4 iconv.m4 isc-posix.m4 lcmessage.m4 progtest.m4 xforms.m4 qt.m4 gtk--.m4 gnome--.m4 gnome.m4 aspell.m4 pspell.m4 cygwin.m4 pkg.m4"
 
 # Discover what version of autoconf we are using.
 autoversion=`$AUTOCONF --version | head -n 1`
index 3ebcf25abfe2285b2cae282ae8e58de9186bd790..f6da773e92de929e1152da9c82ae297e62b620c6 100644 (file)
@@ -1,3 +1,13 @@
+2003-03-25  John Levon  <levon@movementarian.org>
+
+       * Makefile.am:
+       * aspell.m4: add
+
+       * pspell.m4: some more fixes
+
+       * configure.in:
+       * configure.ac: prefer new aspell to pspell
+
 2003-03-25  John Levon  <levon@movementarian.org>
 
        * pspell.m4: fix up the tests again
index 8ac9f4f78646652df9a89643161135269b7a0dba..77f2de8c6eccc06f7acb79289f88def233e88f61 100644 (file)
@@ -4,4 +4,4 @@ EXTRA_DIST = common.am codeset.m4 libtool.m4 gettext.m4 \
        lyxinclude.m4 lyxinclude25x.m4 lyxinclude213.m4 \
        glibc21.m4 iconv.m4 isc-posix.m4 lcmessage.m4 progtest.m4 \
        qt.m4 gtk--.m4 gnome--.m4 gnome.m4 pkg.m4 xforms.m4 pspell.m4 \
-       relyx_configure.ac relyx_configure.in cygwin.m4
+       aspell.m4 relyx_configure.ac relyx_configure.in cygwin.m4
diff --git a/config/aspell.m4 b/config/aspell.m4
new file mode 100644 (file)
index 0000000..ac3c1c4
--- /dev/null
@@ -0,0 +1,30 @@
+# Macro to add for using aspell spellchecker libraries!     -*- sh -*-
+
+# Only checks for "new" aspell, > 0.50
+
+AC_DEFUN(CHECK_WITH_ASPELL,
+[
+    AC_ARG_WITH(aspell,
+       AC_HELP_STRING([--with-aspell],[use ASpell libraries]),
+       [
+           case "$withval" in
+               y*) USING_ASPELL="yes";;
+               *) USING_ASPELL="no";;
+           esac
+           ],
+       [
+           USING_ASPELL="yes"
+           ])
+
+    if test "$USING_ASPELL" = "yes" ; then
+       AC_CHECK_HEADERS(aspell.h aspell/aspell.h, USING_ASPELL="yes", USING_ASPELL="no")
+       AC_CHECK_LIB(aspell, new_aspell_config, LIBS="-laspell $LIBS"; USING_ASPELL="yes", USING_ASPELL="no")
+
+       if test "$USING_ASPELL" = "yes"; then
+           AC_DEFINE(USE_ASPELL, 1, [Define as 1 to use the aspell library])
+           lyx_flags="$lyx_flags use-aspell"
+       fi
+    fi
+    AC_MSG_CHECKING([whether to use aspell])
+    AC_MSG_RESULT($USING_ASPELL)
+    ])
index 9013b53a8a8b692177436660427f5b4476b2a3bb..47933ddfb0e8e12bcc7457d79107f3d34a3ff827 100644 (file)
@@ -128,8 +128,11 @@ AC_LIBTOOL_WIN32_DLL
 #AM_PROG_LIBTOOL
 LYX_PROG_LIBTOOL
 
-### Check if we want pspell libraries
-CHECK_WITH_PSPELL
+### Check if we want spell libraries, prefer new aspell
+CHECK_WITH_ASPELL
+if test "$USING_ASPELL" != "yes"; then
+       CHECK_WITH_PSPELL
+fi
 
 ### Check for some Cygwin-specific details.
 CHECK_WITH_CYGWIN
index a86afef443da8e9814af28a133b5ac35bb1b868d..bc9caf7a690c52184a83ca4c504fe60151c4c8b6 100644 (file)
@@ -131,8 +131,11 @@ AC_LIBTOOL_WIN32_DLL
 #AM_PROG_LIBTOOL
 LYX_PROG_LIBTOOL
 
-### Check if we want pspell libraries
-CHECK_WITH_PSPELL
+### Check if we want spell libraries, prefer new aspell
+CHECK_WITH_ASPELL
+if test "$USING_ASPELL" != "yes"; then
+       CHECK_WITH_PSPELL
+fi
 
 ### Check for some Cygwin-specific details.
 CHECK_WITH_CYGWIN
index 0b8b420ff3495e2f13c9d87a8e435af1e30ebe41..6afd1a91b10efe099d21d8504df2d2274d447a60 100644 (file)
@@ -7,23 +7,23 @@ AC_DEFUN(CHECK_WITH_PSPELL,
        AC_HELP_STRING([--with-pspell],[use PSpell libraries]),
        [
            case "$withval" in
-               y*) TRY_PSPELL="yes";;
-               *) TRY_PSPELL="no";;
+               y*) USING_PSPELL="yes";;
+               *) USING_PSPELL="no";;
            esac
            ],
        [
-           TRY_PSPELL="yes"
+           USING_PSPELL="yes"
            ])
 
-    if test "$TRY_PSPELL" = "yes" ; then
-       AC_CHECK_HEADERS(pspell.h pspell/pspell.h, break, USE_PSPELL=no)
-       AC_CHECK_LIB(pspell, main)
+    if test "$USING_PSPELL" = "yes" ; then
+       AC_CHECK_HEADERS(pspell/pspell.h, USING_PSPELL="yes", USING_PSPELL="no")
+       AC_CHECK_LIB(pspell, main, LIBS="-lpspell $LIBS"; USING_PSPELL="yes", USING_PSPELL="no")
 
-       if test "$TRY_PSPELL" = "yes"; then
+       if test "$USING_PSPELL" = "yes"; then
            AC_DEFINE(USE_PSPELL, 1, [Define as 1 to use the pspell library])
            lyx_flags="$lyx_flags use-pspell"
        fi
     fi
     AC_MSG_CHECKING([whether to use pspell])
-    AC_MSG_RESULT($TRY_PSPELL)
+    AC_MSG_RESULT($USING_PSPELL)
     ])
index 8c8e8575947e738dde881c7f70e949960276d872..2e44592b79e82350a43f149f1cf05dc6d8b9bde7 100644 (file)
@@ -1,3 +1,13 @@
+2003-03-25  John Levon  <levon@movementarian.org>
+
+       * Makefile.am:
+       * aspell_local.h:
+       * aspell.C: add new aspell support
+
+       * lyxrc.h:
+       * lyxrc.C: Make use_pspell be use_spell_lib. Always
+       have it accessible.
+
 2003-03-25  Angus Leeming  <leeming@lyx.org>
 
        * lfuns.h:
index c68ef22729b2d50a64f9acaae17aa7a09e314877..78234a1bd43d30c70f064c4b4b113095169441b0 100644 (file)
@@ -87,6 +87,8 @@ lyx_SOURCES = \
        ToolbarDefaults.C \
        ToolbarDefaults.h \
        WordLangTuple.h \
+       aspell.C \
+       aspell_local.h \
        author.C \
        author.h \
        boost.C \
diff --git a/src/aspell.C b/src/aspell.C
new file mode 100644 (file)
index 0000000..a59ff56
--- /dev/null
@@ -0,0 +1,147 @@
+/**
+ * \file aspell.C
+ * Copyright 2001 the LyX Team
+ * Read the file COPYING
+ *
+ * \author Kevin Atkinson
+ * \author John Levon <levon@movementarian.org>
+ */
+
+#include <config.h>
+
+#ifdef USE_ASPELL
+
+#include "support/LAssert.h"
+#include "debug.h"
+
+#include <aspell.h>
+
+#include "aspell_local.h"
+#include "WordLangTuple.h"
+
+using std::endl;
+
+ASpell::ASpell(BufferParams const &, string const & lang)
+       : els(0), spell_error_object(0)
+{
+       addSpeller(lang);
+}
+
+
+ASpell::~ASpell()
+{
+       if (spell_error_object) {
+               delete_aspell_can_have_error(spell_error_object);
+               spell_error_object = 0;
+       }
+
+       if (els)
+               delete_aspell_string_enumeration(els);
+
+       Spellers::iterator it = spellers_.begin();
+       Spellers::iterator end = spellers_.end();
+
+       for (; it != end; ++it) {
+               aspell_speller_save_all_word_lists(it->second.speller);
+               delete_aspell_speller(it->second.speller);
+               delete_aspell_config(it->second.config);
+       }
+}
+
+
+void ASpell::addSpeller(string const & lang)
+{
+       AspellConfig * config = new_aspell_config();
+       aspell_config_replace(config, "language-tag", lang.c_str());
+       AspellCanHaveError * err = new_aspell_speller(config);
+       if (spell_error_object)
+               delete_aspell_can_have_error(spell_error_object);
+       spell_error_object = 0;
+
+       if (aspell_error_number(err) == 0) {
+               Speller m;
+               m.speller = to_aspell_speller(err);
+               m.config = config;
+               spellers_[lang] = m;
+       } else {
+               spell_error_object = err;
+       }
+}
+
+
+enum ASpell::Result ASpell::check(WordLangTuple const & word)
+{
+       Result res = UNKNOWN;
+
+       Spellers::iterator it = spellers_.find(word.lang_code());
+       if (it == spellers_.end()) {
+               addSpeller(word.lang_code());
+               it = spellers_.find(word.lang_code());
+               // FIXME
+               if (it == spellers_.end())
+                       return res;
+       }
+
+       AspellSpeller * m = it->second.speller;
+
+       int word_ok = aspell_speller_check(m, word.word().c_str(), -1);
+       lyx::Assert(word_ok != -1);
+
+       if (word_ok) {
+               res = OK;
+       } else {
+               AspellWordList const * sugs =
+                       aspell_speller_suggest(m, word.word().c_str(), -1);
+               lyx::Assert(sugs != 0);
+               els = aspell_word_list_elements(sugs);
+               if (aspell_word_list_empty(sugs))
+                       res = UNKNOWN;
+               else
+                       res = MISSED;
+       }
+       return res;
+}
+
+
+void ASpell::insert(WordLangTuple const & word)
+{
+       Spellers::iterator it = spellers_.find(word.lang_code());
+       if (it != spellers_.end())
+               aspell_speller_add_to_personal(it->second.speller, word.word().c_str(), -1);
+}
+
+
+void ASpell::accept(WordLangTuple const & word)
+{
+       Spellers::iterator it = spellers_.find(word.lang_code());
+       if (it != spellers_.end())
+               aspell_speller_add_to_session(it->second.speller, word.word().c_str(), -1);
+}
+
+
+string const ASpell::nextMiss()
+{
+       char const * str = 0;
+
+       if (els)
+               str = aspell_string_enumeration_next(els);
+       if (str)
+               return str;
+       return "";
+}
+
+
+string const ASpell::error()
+{
+       char const * err = 0;
+
+       if (spell_error_object && aspell_error_number(spell_error_object) != 0) {
+               err = aspell_error_message(spell_error_object);
+       }
+
+       if (err)
+               return err;
+       return "";
+}
+
+#endif // USE_ASPELL
diff --git a/src/aspell_local.h b/src/aspell_local.h
new file mode 100644 (file)
index 0000000..c256bc0
--- /dev/null
@@ -0,0 +1,75 @@
+/**
+ * \file aspell_local.h
+ * Copyright 2001 the LyX Team
+ * Read the file COPYING
+ *
+ * \author Kevin Atkinson
+ * \author John Levon <levon@movementarian.org>
+ */
+
+#ifndef LYX_ASPELL_H
+#define LYX_ASPELL_H
+
+#include <map>
+
+#include "SpellBase.h"
+
+class AspellSpeller;
+class AspellStringEnumeration;
+class AspellCanHaveError;
+class AspellConfig;
+
+class BufferParams;
+
+
+class ASpell : public SpellBase {
+public:
+       /**
+        * Initialise the spellchecker with the given buffer params and language.
+        */
+       ASpell(BufferParams const & params, string const & lang);
+
+       virtual ~ASpell();
+
+       /**
+        * return true if the spellchecker instance still exists
+        * Always true for aspell, 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 MISSED result
+       virtual string const nextMiss();
+
+       /// give an error message on messy exit
+       virtual string const error();
+
+private:
+       /// add a speller of the given language
+       void addSpeller(string const & lang);
+
+       struct Speller {
+               AspellSpeller * speller;
+               AspellConfig * config;
+       };
+
+       typedef std::map<string, struct Speller> Spellers;
+
+       /// the spellers
+       Spellers spellers_;
+
+       /// FIXME
+       AspellStringEnumeration * els;
+       /// FIXME
+       AspellCanHaveError * spell_error_object;
+};
+
+#endif // ASPELL_H
index 57385d97670920ebf08208696cdb155c6394a71a..86027b25041363a4ad732e2900f2e8490f02e696 100644 (file)
@@ -1,3 +1,7 @@
+2003-03-25  John Levon  <levon@movementarian.org>
+
+       * ControlSpellchecker.C: support for new aspell
+
 2003-03-25  Angus Leeming  <leeming@lyx.org>
 
        * ControlLog.[Ch]:
index 2cb547189cfea64a792db473281dc2dc2c9619aa..3cfba26973819552bf17fd37be74c1c0a586aa5b 100644 (file)
 #include "ispell.h"
 #ifdef USE_PSPELL
 # include "pspell.h"
+#else
+#ifdef USE_ASPELL
+# include "aspell_local.h"
+#endif
 #endif
 
 #include "frontends/Alert.h"
@@ -55,6 +59,30 @@ void ControlSpellchecker::clearParams()
        endSession();
 }
 
+namespace {
+
+SpellBase * getSpeller(BufferParams const & bp)
+{
+       string lang = (lyxrc.isp_use_alt_lang)
+                     ? lyxrc.isp_alt_lang
+                     : bp.language->code();
+
+#ifdef USE_ASPELL
+       if (lyxrc.use_spell_lib)
+               return new ASpell(bp, lang);
+#endif
+#ifdef USE_PSPELL
+       if (lyxrc.use_spell_lib)
+               return new PSpell(bp, lang);
+#endif
+
+       lang = (lyxrc.isp_use_alt_lang) ?
+               lyxrc.isp_alt_lang : bp.language->lang();
+
+       return new ISpell(bp, lang);
+}
+
+}
 
 void ControlSpellchecker::startSession()
 {
@@ -66,23 +94,7 @@ void ControlSpellchecker::startSession()
                return;
        }
 
-       // create spell object
-       string tmp;
-#ifdef USE_PSPELL
-       if (lyxrc.use_pspell) {
-               tmp = (lyxrc.isp_use_alt_lang) ?
-                       lyxrc.isp_alt_lang : buffer()->params.language->code();
-
-               speller_.reset(new PSpell(buffer()->params, tmp));
-       } else {
-#endif
-               tmp = (lyxrc.isp_use_alt_lang) ?
-                       lyxrc.isp_alt_lang : buffer()->params.language->lang();
-
-               speller_.reset(new ISpell(buffer()->params, tmp));
-#ifdef USE_PSPELL
-       }
-#endif
+       speller_.reset(getSpeller(buffer()->params));
 
        // reset values to initial
        newval_ = 0.0;
index b59080a5c17873ddbd2943d11350b41b6d708d96..1f9e957160b276b947a339ec1607600474a3ef91 100644 (file)
@@ -141,9 +141,9 @@ keyword_item lyxrcTags[] = {
        { "\\use_escape_chars", LyXRC::RC_USE_ESC_CHARS },
        { "\\use_input_encoding", LyXRC::RC_USE_INP_ENC },
        { "\\use_personal_dictionary", LyXRC::RC_USE_PERS_DICT },
-#ifdef USE_PSPELL
-       { "\\use_pspell", LyXRC::RC_USE_PSPELL },
-#endif
+       // compatibility with versions older than 1.4.0 only
+       { "\\use_pspell", LyXRC::RC_USE_SPELL_LIB },
+       { "\\use_spell_lib", LyXRC::RC_USE_SPELL_LIB },
        { "\\use_tempdir", LyXRC::RC_USETEMPDIR },
        { "\\user_email", LyXRC::RC_USER_EMAIL },
        { "\\user_name", LyXRC::RC_USER_NAME },
@@ -227,9 +227,7 @@ void LyXRC::setDefaults() {
        backupdir_path.erase();
        display_graphics = grfx::ColorDisplay;
        // Spellchecker settings:
-#ifdef USE_PSPELL
-       use_pspell = true;
-#endif
+       use_spell_lib = true;
        isp_command = "ispell";
        isp_accept_compound = false;
        isp_use_input_encoding = false;
@@ -879,13 +877,11 @@ int LyXRC::read(string const & filename)
                        }
                        break;
                        // Spellchecker settings:
-#ifdef USE_PSPELL
-               case RC_USE_PSPELL:
+               case RC_USE_SPELL_LIB:
                        if (lexrc.next()) {
-                               use_pspell = lexrc.getBool();
+                               use_spell_lib = lexrc.getBool();
                        }
                        break;
-#endif
                case RC_SPELL_COMMAND:
                        if (lexrc.next()) {
                                isp_command = lexrc.getString();
@@ -1628,12 +1624,10 @@ void LyXRC::output(ostream & os) const
                os << "\n#\n"
                   << "# SPELLCHECKER SECTION ##############################\n"
                   << "#\n\n";
-#ifdef USE_PSPELL
-       case RC_USE_PSPELL:
-               if (use_pspell != system_lyxrc.use_pspell) {
-                       os << "\\use_pspell " << tostr(use_pspell) << '\n';
+       case RC_USE_SPELL_LIB:
+               if (use_spell_lib != system_lyxrc.use_spell_lib) {
+                       os << "\\use_spell_lib " << tostr(use_spell_lib) << '\n';
                }
-#endif
        case RC_SPELL_COMMAND:
                if (isp_command != system_lyxrc.isp_command) {
                        os << "\\spell_command \"" << isp_command << "\"\n";
index 532f00a6c427b9f2c979e44aec5842e35f997790..406a26d493e9928f97ecbe5f458093f13bcb68ff 100644 (file)
@@ -118,9 +118,7 @@ enum LyXRCTags {
        RC_PREVIEW,
        RC_PREVIEW_HASHED_LABELS,
        RC_PREVIEW_SCALE_FACTOR,
-#ifdef USE_PSPELL
-       RC_USE_PSPELL,
-#endif
+       RC_USE_SPELL_LIB,
        RC_USER_NAME,
        RC_USER_EMAIL,
        RC_LAST
@@ -280,10 +278,9 @@ enum LyXRCTags {
        string ascii_roff_command;
        ///
        unsigned int ascii_linelen;
+       /// use library instead of process
+       bool use_spell_lib;
        /// Ispell command
-#ifdef USE_PSPELL
-       bool use_pspell;
-#endif
        string isp_command;
        /// Accept compound words in spellchecker?
        bool isp_accept_compound;