Abdelrazak Younes <you...@lyx.org> writes: > No, I really meant that implementing that in LyX directly is easier > that implementing that in Enchant if it was there already.
If you like coding in Objective C++, yes. But this is really a weird beast. I attach the file from enchant as reference. > I am not sure he was talking about Enchant, maybe about directly > supporting the native spellchecker within LyX. So I guess his problem > is to know how to compile his code. I was talking about the applespell support in enchant. Note that we might be able to turn the file from enchant into a proper backend for our own use. > JMarc, I remember that Stefan did some Mac specific clipboard > enhancement in support, maybe you could give that a look? Uh? JMarc
/* vim: set sw=8: -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ /* enchant * Copyright (C) 2004 Remi Payette * Copyright (C) 2004 Francis James Franklin * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA * 02110-1301, USA. */ #include <glib.h> #include <gmodule.h> #include "applespell_checker.h" AppleSpellChecker::AppleSpellChecker() { // NSLog (@"AppleSpellChecker::AppleSpellChecker"); m_checker = [NSSpellChecker sharedSpellChecker]; m_languages = [[NSMutableDictionary alloc] initWithCapacity:16]; } AppleSpellChecker::~AppleSpellChecker() { // NSLog (@"AppleSpellChecker::~AppleSpellChecker"); if (m_languages) { [m_languages release]; m_languages = 0; } } void AppleSpellChecker::parseConfigFile (const char * configFile) { if (!m_languages || !configFile) return; // NSLog (@"AppleSpellChecker::parseConfigFile: file=\"%s\"", configFile); if (FILE * in = fopen (configFile, "r")) { char line[1024]; char code[1024]; char name[1024]; char lang[1024]; while (fgets (line, sizeof(line), in)) if (sscanf (line, "%s %s %s", code, name, lang) == 3) { NSString * key = [[NSString alloc] initWithUTF8String:code]; NSString * value = [[NSString alloc] initWithUTF8String:name]; NSString * language = [[NSString alloc] initWithUTF8String:lang]; if (key && value) { // NSLog (@"AppleSpellChecker: %@ -> %@ (%@)", key, value, language); [m_languages setObject:value forKey:key]; } if (key) [key release]; if (value) [value release]; if (language) [language release]; } fclose (in); } } NSString * AppleSpellChecker::dictionaryForCode (NSString * code) { if (!m_languages) return 0; return [m_languages objectForKey:code]; } bool AppleSpellChecker::checkWord (const char * word, size_t len, NSString * lang) { // NSLog(@"AppleSpellChecker::checkWord: lang=\"%...@\"", lang); if (!m_checker || !lang) return false; NSString * str = [[NSString alloc] initWithBytes:word length:len encoding:NSUTF8StringEncoding]; if (!str) return false; // NSLog (@"AppleSpellChecker::checkWord: word=\"%...@\"", str); [m_checker setLanguage:lang]; NSRange result = [m_checker checkSpellingOfString:str startingAt:0]; [str release]; return (result.length ? true : false); } char ** AppleSpellChecker::suggestWord (const char * const word, size_t len, size_t * nsug, NSString * lang) { // NSLog (@"AppleSpellChecker::suggestWord: lang=\"%...@\"", lang); if (!m_checker || !word || !len || !nsug || !lang) return 0; *nsug = 0; [m_checker setLanguage:lang]; NSString * str = [[NSString alloc] initWithBytes:word length:len encoding:NSUTF8StringEncoding]; if (!str) return 0; // NSLog (@"AppleSpellChecker::suggestWord: word=\"%...@\"", str); NSArray * result = [m_checker guessesForWord:str]; [str release]; char ** sug = 0; if (unsigned int count = [result count]) { sug = g_new0 (char *, static_cast<size_t>(count) + 1); if (sug) { for (unsigned int i = 0; i < count; i++) { str = [result objectAtIndex:i]; sug[*nsug] = g_strdup ([str UTF8String]); if (sug[*nsug]) *nsug = *nsug + 1; } } } return sug; } NSString * AppleSpellChecker::requestDictionary (const char * const code) { // NSLog (@"AppleSpellChecker::requestDictionary: code=\"%s\"", code); if (!m_checker || !code) return 0; NSString * dictionary = dictionaryForCode ([NSString stringWithUTF8String:code]); if (dictionary) { NSString * language = [m_checker language]; // NSLog (@"AppleSpellChecker::requestDictionary: ld language=\"%...@\", new language=\"%...@\"", language, dictionary); if (![m_checker setLanguage:dictionary]) { // NSLog (@"AppleSpellChecker::requestDictionary: failed to set new language!"); dictionary = 0; } if (language) [m_checker setLanguage:language]; } return dictionary; } /* * Enchant */ static char ** appleSpell_dict_suggest (EnchantDict * me, const char * const word, size_t len, size_t * out_n_suggs) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // NSLog (@"appleSpell_dict_suggest word=\"%s\"", word); if (!me || !word || !len || !out_n_suggs) { if (pool) [pool release]; return 0; } char ** result = 0; if (AppleSpellDictionary * ASD = static_cast<AppleSpellDictionary *>(me->user_data)) { result = ASD->AppleSpell->suggestWord (word, len, out_n_suggs, ASD->DictionaryName); } if (pool) [pool release]; return result; } static int appleSpell_dict_check (EnchantDict * me, const char * const word, size_t len) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // NSLog (@"appleSpell_dict_check"); if (!me || !word || !len) { if (pool) [pool release]; return 0; } int result = 0; if (AppleSpellDictionary * ASD = static_cast<AppleSpellDictionary *>(me->user_data)) { result = ASD->AppleSpell->checkWord (word, len, ASD->DictionaryName); } if (pool) [pool release]; return result; } static EnchantDict * appleSpell_provider_request_dict (EnchantProvider * me, const char * const tag) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // NSLog (@"appleSpell_provider_request_dict"); if (!me || !tag) { if (pool) [pool release]; return 0; } AppleSpellChecker * checker = static_cast<AppleSpellChecker *>(me->user_data); if (!checker) { if (pool) [pool release]; return 0; } EnchantDict * dict = g_new0 (EnchantDict, 1); if (!dict) { if (pool) [pool release]; return 0; } dict->check = appleSpell_dict_check; dict->suggest = appleSpell_dict_suggest; AppleSpellDictionary * ASD = g_new0 (AppleSpellDictionary, 1); if (!ASD) { g_free (dict); if (pool) [pool release]; return 0; } ASD->AppleSpell = checker; ASD->DictionaryName = checker->requestDictionary (tag); if (ASD->DictionaryName) { [ASD->DictionaryName retain]; // NSLog (@"appleSpell_provider_request_dict: providing dictionary \"%...@\"", ASD->DictionaryName); dict->user_data = (void *) ASD; } else { g_free (ASD); g_free (dict); dict = 0; } if (pool) [pool release]; return dict; } static void appleSpell_provider_dispose_dict (EnchantProvider * me, EnchantDict * dict) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // NSLog (@"appleSpell_provider_dispose_dict"); if (dict) { AppleSpellDictionary * ASD = static_cast<AppleSpellDictionary *>(dict->user_data); if (ASD) { [ASD->DictionaryName release]; g_free (ASD); } g_free (dict); } if (pool) [pool release]; } static int appleSpell_provider_dictionary_exists (EnchantProvider * me, const char * const tag) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // NSLog (@"appleSpell_provider_dictionary_exists: tag=\"%s\"", tag); int result = 0; AppleSpellChecker * checker = static_cast<AppleSpellChecker *>(me->user_data); if (checker) result = (checker->requestDictionary (tag) ? 1 : 0); if (pool) [pool release]; return result; } static void appleSpell_provider_dispose (EnchantProvider * me) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // NSLog (@"appleSpell_provider_dispose"); if (me) { AppleSpellChecker * checker = static_cast<AppleSpellChecker *>(me->user_data); if (checker) delete checker; g_free (me); } if (pool) [pool release]; } static const char * appleSpell_provider_identify (EnchantProvider * me) { return "AppleSpell"; } static const char * appleSpell_provider_describe (EnchantProvider * me) { return "AppleSpell Provider"; } static void appleSpell_provider_free_string_list (EnchantProvider * me, char **str_list) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // NSLog (@"appleSpell_provider_free_suggestions"); if (str_list) g_strfreev (str_list); if (pool) [pool release]; } extern "C" { ENCHANT_MODULE_EXPORT (EnchantProvider *) init_enchant_provider (void) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // NSLog (@"init_enchant_provider"); EnchantProvider * provider = g_new0 (EnchantProvider, 1); if (!provider) { if (pool) [pool release]; return 0; } provider->dispose = appleSpell_provider_dispose; provider->request_dict = appleSpell_provider_request_dict; provider->dispose_dict = appleSpell_provider_dispose_dict; provider->dictionary_exists = appleSpell_provider_dictionary_exists; provider->identify = appleSpell_provider_identify; provider->describe = appleSpell_provider_describe; provider->free_string_list = appleSpell_provider_free_string_list; AppleSpellChecker * checker = 0; try { checker = new AppleSpellChecker; } catch (...) { checker = 0; } if (checker) { provider->user_data = (void *) checker; } else { g_free (provider); provider = 0; } if (pool) [pool release]; return provider; } static bool s_bReloadSelf = true; ENCHANT_MODULE_EXPORT (void) configure_enchant_provider (EnchantProvider * me, const char * module_dir) { NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init]; // NSLog (@"configure_enchant_provider"); if (!me || !module_dir) { if (pool) [pool release]; return; } AppleSpellChecker * checker = static_cast<AppleSpellChecker *>(me->user_data); if (checker) { if (s_bReloadSelf) if (gchar * moduleFile = g_build_filename (module_dir, "AppleSpell.so", NULL)) { /* ugly hack :-( * Darwin linker doesn't like unloading Obj-C modules; * reload once to suppress unloading... */ g_module_open (moduleFile, (GModuleFlags) 0); g_free (moduleFile); s_bReloadSelf = false; } if (gchar * configFile = g_build_filename (module_dir, "AppleSpell.config", NULL)) { checker->parseConfigFile (configFile); g_free (configFile); } } if (pool) [pool release]; return; } }