2011年8月21日星期日

1.2 Add five backends to support hyphenation


including ispell, myspell, zemberek, voikko, uspell
Ø  Hunspell: using seperated dictionary: such as hyph_en_us.dic.  we can download dic from internet
Ø  Libhyphenaiton: the dictionary is provided by author, sometimes limited
Ø  Zemberek: for Turkis
Ø  Voikko: for Finnish

the changes:
1 deleted the unneed connection, such as HSpell
2 add hunspell(myspell) hyphenation code
3 implement hyphenation using hunspell
4 implement hyphenation using Zemberek

======1 deleted the unneed connection, such as HSpell===========
Hebrew don’t need any hyphenation
Yiddish don’t need any hyphenation
=======2 Implement hyphenation using hunspell
In order to use libhyphenation. We need to add files:
hyphen/hnjalloc.h
hyphen/hnjalloc.c
hyphen/hyph_en_US.dic
hyphen/hyphen.c
hyphen/hyphen.gyp
hyphen/hyphen.h
hyphen/hyphen.patch
hyphen/hyphen.tex

========3 Implement hyphenation using Zemberek
 just using dbus_g_proxy_call the same as Spell-Check in Zemberek:
the hyphenation is as following
 char* Zemberek::hyphenate(const char* word)
{
       char* result;
       GError *Error = NULL;
       if (!dbus_g_proxy_call (proxy, "hecele", &Error,
               G_TYPE_STRING,word,G_TYPE_INVALID,
               G_TYPE_STRV, &result,G_TYPE_INVALID)) {
                       g_error_free (Error);
                       return NULL;
       }
       char*result=0;
       return result;
}

1.3 ISpell

I used Libhyphenation in ISpell. The simple code is just like this:
static char *
ispell_dict_hyphenate (EnchantDict * me, const char *const word)
{
ISpellChecker * checker;

checker = (ISpellChecker *) me->user_data;
if(me->tag!="")
  return checker->hyphenate (word,me->tag);
    return checker->hyphenate (word,"en_us");
}
The concrete code in ISpellChecker is :
char *
ISpellChecker::hyphenate(const char * const utf8Word, const char *const tag)
{  //we must choose the right language tag
char* param_value = enchant_broker_get_param (m_broker, "enchant.ispell.hyphenation.dictionary.path");
if(languageMap[tag]!="")
{
string result=Hyphenator(RFC_3066::Language(languageMap[tag]),param_value).hyphenate(utf8Word).c_str();

char* temp=new char[result.length()];
strcpy(temp,result.c_str());
return temp;
}
return NULL;
}

1.4 MySpell

I used Libhyphenate in ISpell. The simple code is just like this:
char*
MySpellChecker::hyphenate (const char* const word, size_t len,char* tag)
{
if(len==-1) len=strlen(word);
if (len > MAXWORDLEN
|| !g_iconv_is_valid(m_translate_in)
|| !g_iconv_is_valid(m_translate_out))
return 0;
char* result=0;
myspell->hyphenate(word,result,tag);
return result;
}
The concrete code in MySpellChecker is :
void Hunspell::hyphenate( const char* const word, char* result, char* tag )
{
HyphenDict *dict;
char buf[BUFSIZE + 1];
char *hyphens=new char[BUFSIZE + 1];
char ** rep;
int * pos;
int * cut;
/* load the hyphenation dictionary */ 
string filePath="hyph_";
filePath+=tag;
filePath+=".dic";
if ((dict = hnj_hyphen_load(filePath.c_str())) == NULL) {
fprintf(stderr, "Couldn't find file %s\n",tag);
fflush(stderr);
exit(1);
}
     int len=strlen(word);
     if (hnj_hyphen_hyphenate2(dict, word, len-1, hyphens, NULL, &rep, &pos, &cut)) {
free(hyphens);
fprintf(stderr, "hyphenation error\n");
exit(1);
}

hnj_hyphen_free(dict);
result=hyphens;
}

1.5 zemberek

The way in Zemberek is same with the two above:
static char*
zemberek_dict_hyphenate (EnchantDict * me, const char *const word)
{
Zemberek *checker;
checker = (Zemberek *) me->user_data;
return checker->hyphenate (word);
}
But the way for the concrete implementation is different from the two. We use zemberek_service
char* Zemberek::hyphenate(const char* word)
{
char* result;
GError *Error = NULL;
if (!dbus_g_proxy_call (proxy, "hecele", &Error,
G_TYPE_STRING,word,G_TYPE_INVALID,
G_TYPE_STRV, &result,G_TYPE_INVALID)) {
g_error_free (Error);
return NULL;
}

char*result=0;
return result;
}

1.6 voikko

The hyphenation implementation in Voikko is easy since Voikko has hyphenaiton’s API.
static char **
voikko_dict_suggest (EnchantDict * me, const char *const word,
     size_t len, size_t * out_n_suggs)
{
char **sugg_arr;
int voikko_handle;

voikko_handle = (long) me->user_data;
sugg_arr = voikko_suggest_cstr(voikko_handle, word);
if (sugg_arr == NULL)
return NULL;
for (*out_n_suggs = 0; sugg_arr[*out_n_suggs] != NULL; (*out_n_suggs)++);
return sugg_arr;
}

1. Hyphenation module in Enchant


1.1 Add hyphenation function in Enchant

Firstly, I add hyphenation method in Enchant:
================the code===========
I think we can combine the hyphenation with spell-checking together, So that we can make the code more flexible. In my opinion, the hyphenation function defines as following:
EnchantDict* enchant_broker_request_dict (EnchantBroker* broker, const
char *const lang); //same as spell-checking
char *enchant_dict_hyphenate(EnchantDict *dict, const char *const word,size_t len);

In order to achieve the function and implement in abstract layer, we need to add hyphenation function in EnchantDict. something like, just as a function pointer:
char* (*hyphenate) (struct str_enchant_dict * me,
                          const char *const word, size_t len,
                          size_t * out_n_suggs);

and the function is implement by the backend. Take “ispell” as example:
static char * ispell_dict_hyphenate (EnchantDict * me, const char *const word,
                    size_t len, size_t * out_n_suggs)
{
       ISpellChecker * checker;
       checker = (ISpellChecker *) me->user_data;
       return checker->hyphenate (word, len, out_n_suggs);
}

Finally, we set the connetion
 dict->hyphenate = ispell_dict_hyphenate;
 dict->suggest = hspell_dict_hyphenate;
dict->suggest = zemberek_dict_hyphenate;

Summary of What I have done in GSoc2011


Summary of What I have done in GSoc2011. 1
1 Hyphenation module in Enchant 3
1.1 Add hyphenation function in Enchant 3
1.2 Add five backends to support hyphenation. 3
1.3 ISpell 5
1.4 MySpell 5
1.5 zemberek. 6
1.6 voikko. 7
1.7 Deploy of enchant in Abiword. 7
1.8 Test in Linux. 8
2 Call the Hyphenation function in Abiword. 8
3 Simple Implementation of Chinese Spell-Check in Enchant. 10
4 Code Re-factor and debug. 10
5. User interface to manage hyphenation. 10
6. How to Support more languages. 11
6.1 How to support more languages in ISpell 12
6.2 How to support more languages in mySepll 13
7. How to extend the enchant function. 13


Until now, my works in GSoc2011 including four parts as following:
1.Hyphenation module in Enchant
Ø  Read and get totally understand the source code of Enchant
Ø  Reuse the abstract layer of Enchant and add Hyphenation function in Enchant, so that we can add more language easily
Ø  Deal with more languages
Ø  Add five backend implementation, including ispell, myspell, zemberek, voikko, uspell
Ø  Deal with the spelling-checking module

2.Call the Hyphenation function in Abiword.
Ø  Find split info using enchant_dict_hyphenate
Ø  Split Text_Run to split word pass the line width and keep their format
Ø  Deal with user's operation(select, delete, cut, paste)
Ø  User can select weather to enable the hyphenation function

3. Simple Implementation of Chinese Spell-Checking in Enchant
Ø  Add a simple spell-check framework for Chinese in Enchant
Ø  Add library to support
Ø  Some survey about Chinese Spell-checking

4. Code Re-factor and debug
Ø  Code Re-factor, include keep the code flexible
Ø  Debug coding problem

5. User interface to manage hyphenation
Ø  Windows, Linux, and Cocoa

6. How to Support more languages
Ø  How to support more languages in ISpell
Ø  How to support more languages in mySepll

7. How to extend the enchant function

2011年8月9日星期二

the works in Enchant

1 add hyphenation function in Enchant
what I have done:
Firstly, I add hyphenation module in Enchant:
================about the code===========
I think we can combine the hyphenation with spell-checking together.
so that we can make the code more flexsible.
In my opinion, we can make code like this:
EnchantDict* enchant_broker_request_dict (EnchantBroker* broker, const
char *const lang); //same as spell-checking
char *enchant_dict_hyphenate(EnchantDict *dict, const char *const
word,size_t len);

===================== 1
In order to achieve this, we need to add  hyphenation function in
EnchantDict. something like:
char **(*hyphenate) (struct str_enchant_dict * me,
                          const char *const word, size_t len,
                          size_t * out_n_suggs);

======================== 2
and the function is implement by the backend.
static char **
ispell_dict_hyphenate (EnchantDict * me, const char *const word,
                    size_t len, size_t * out_n_suggs)
{
       ISpellChecker * checker;

       checker = (ISpellChecker *) me->user_data;
       return checker->hyphenate (word, len, out_n_suggs);
}
 ====================3
 finally, we set the connetion

 dict->hyphenate = ispell_dict_hyphenate;
 dict->suggest = hspell_dict_hyphenate;
dict->suggest = zemberek_dict_hyphenate;

2 add five backends to support hyphenation
  including ispell, myspell, zemberek, voikko, uspell

we all know that Enchant has eight types of backend to support multi-language.
USpell
HSpell
ASpell
MySpell....

but I found that in Abiword. we only use two backends:
libenchant_ispell.dll  libenchant_myspell.dll

another surprising thing is that in the dictionary\ispell I can only
find one dic: american.hash(En_US)
and the hunspell dic is empty~~


the changes:
1 deleted the unneed connection, such as HSpell
2 add hunspell(myspell) hyphenation code
3 implement hyphenation using hunspell
4 implement hyphenation using Zemberek

================1 deleted the unneed connection, such as HSpell===========
Hebrew dont need any hyphenation
Yiddish dont need any hyphenation

====================2  implement hyphenation using hunspell
added files:
hyphen/hnjalloc.h
hyphen/hnjalloc.c
hyphen/hyph_en_US.dic
hyphen/hyphen.c
hyphen/hyphen.gyp
hyphen/hyphen.h
hyphen/hyphen.patch
hyphen/hyphen.tex

need more tests

==================== 3 implement hyphenation using Zemberek
 just using dbus_g_proxy_call:

 char* Zemberek::hyphenate(const char* word)
{
       char* result;
       GError *Error = NULL;
       if (!dbus_g_proxy_call (proxy, "hecele", &Error,
               G_TYPE_STRING,word,G_TYPE_INVALID,
               G_TYPE_STRV, &result,G_TYPE_INVALID)) {
                       g_error_free (Error);
                       return NULL;
       }

       char*result=0;
       return result;
}


The attachment is the updated version today. Now we have four backends
of hyphenantion
1 hunspell: using seperated dic: such as hyph_en_us.dic.
  we can download dic from internet
2 libhyphenaiton: the dic is provided by author, sometimes limited
3 zemberek: for Turkis
4 Voikko: for Finnish


3 the depot of enchant
I just copy the bulid result of enchant:
enchant\bin\Debug\libenchant_myspell.dll ---->
abiword\msvc2008\Debug\lib\enchant\libenchant_myspell.dll
enchant\bin\Debug\libenchant_ispell.dll ---->
abiword\msvc2008\Debug\lib\enchant\libenchant_ispell.dll
enchant\bin\Debug\libenchant.dll ---->abiword\msvc2008\Debug\bin\ibenchant.dll

3 the implementation of the five backends
4 call hyphenation module of enchant to display the hyphenation-result
in abiword
5 after user's operation, refresh the hyphenation-result accordingly
  include user adding new word, delete word, copy word, cut word


6 test in Linux
todo:
1 Fully support hyphenation in Abiword
2 Support more language besides En_us
3 Some tests in Linux(Unix)


Still to improve:
1 code re-factor
2 deal with more language
3 include more user's operation(such as operate with picture may
influence the hyphenation result)

the summary about What I have done in GSoc2011

my works in GSoc2011 including two parts.
1 the hyphenation module in Enchant
 Key: to reuse the abstract layer of Enchant and add Hyphenation function
         we can add more language easy
         Deal with more languages





2  call in Abiword. including:
   split run
   find split info
   deal with user's operation