%% LyX 1.1 created this file. For more info, see http://www.lyx.org/. %% Do not edit unless you really know what you are doing. \documentclass[oneside,english]{book} \usepackage[T1]{fontenc} \usepackage[latin1]{inputenc} \usepackage{geometry} \geometry{verbose,letterpaper,tmargin=0.5in,bmargin=0.5in,lmargin=1.25in,rmargin=1.25in} \usepackage{babel} \setlength\parskip{\medskipamount} \setlength\parindent{0pt} \usepackage{url} \makeatletter %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% LyX specific LaTeX commands. \providecommand{\LyX}{L\kern-.1667em\lower.25em\hbox{Y}\kern-.125emX\@} \newenvironment{LyXParagraphIndent}[1]% { \begin{list}{}{% \setlength\topsep{0pt}% \addtolength{\leftmargin}{#1} \setlength\parsep{0pt plus 1pt}% } \item[] } {\end{list}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Textclass specific LaTeX commands. \newenvironment{lyxcode} {\begin{list}{}{ \setlength{\rightmargin}{\leftmargin} \raggedright \setlength{\itemsep}{0pt} \setlength{\parsep}{0pt} \normalfont\ttfamily}% \item[]} {\end{list}} %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% User specified LaTeX commands. \usepackage{html} \newcommand{\doubledash}{-\hspace{0.1em}-} \newcommand{\doubledashb}{-\/-} \begin{htmlonly} \renewenvironment{lyxcode} {\begin{list}{}{ \setlength{\rightmargin}{\leftmargin} \raggedright \setlength{\itemsep}{0pt} \setlength{\parsep}{0pt} \ttfamily}% \item[] \begin{ttfamily}} {\end{ttfamily} \end{list} } \newenvironment{LyXParagraphIndent}[1]% {\begin{quote}} {\end{quote}} \renewcommand{\LyX}{LyX} \renewcommand{\doubledash}{\rawhtml --\endrawhtml} \renewcommand{\doubledashb}{\rawhtml --\endrawhtml} \end{htmlonly} \makeatother \begin{document} \title{Portable Spell Checker Interface Library} \author{Kevin Atkinson \textit{}\\ \textit{kevina at users sourceforge net}} \date{Version 0.12.2} \maketitle \tableofcontents{} \chapter{Introduction} \section{Goal} The goal of the library is to provide a generic interface to Spell checker libraries installed on the system. \chapter{Getting Started} \section{Obtaining} The latest version of pspell can always be found at the pspell home page at \url{http://pspell.sourceforge.net/} \section{Support} Support for Pspell can be found on the Pspell mailing lists. Instructions for joining the various mailing lists (and an archive of them) can be found off the Pspell home page at \url{http://pspell.sourceforge.net}. \section{Installation} \subsection{Generic Install Instructions} To install the library simply type \begin{lyxcode} ./configure\\ make\\ make~install \end{lyxcode} Then install at least one pspell module. You can find more information about available modules from the Pspell home page. This is all that should be required for Pspell to function properly. If you run into problems you can try disabling the building of shared libraries with \doubledash{}disable-shared and/or the ltdl library which is used for dynamically loading pspell modules with \doubledash{}disable-ltdl. If you do so you will then need to manually link in the necessary modules by doing the following: \begin{lyxcode} cd~modules\\ ./add-modules\\ cd~..\\ make\\ make~install \end{lyxcode} However this has not been known to work properly on most platforms. If you are just installing Pspell so that you can compile and use the Aspell utility then you should be okay as Aspell does not need any of Pspell modules linked in. However, if you are trying to use Pspell with an application that actually used the Pspell library such as PHP, AbiWord or the like then you will likely run into problems. By default a static library is also created you can turn this of by passing the parameter \doubledash{}disable-static to configure. You can control what C and C++ compiler is used by setting the environmental variable CC and CXX respectfully before running configure and you can control what flags are passed to the C and C++ compile via the environmental variable CFLAGS and CXXFLAGS respectfully. \subsection{General Problems} Aspell does not use a released version of GNU Libtool. In previous versions of aspell this will often create problems if you inadvertently modify a file which causes Libtool to be called. However, as of Pspell .12.2 this so no longer be a problem and automake, autoconf, or libtool should not be called unless you specifically call them or if you configure Aspell with \doubledash{}enable-maintainer-mode. If you do notice any of these programs being called (and you did not configure with \doubledash{}enable-maintainer-mode) please let me know about it. If you have a need to modify configure.in or any of the Makefile.am's you should install the multi-language-branch of the CVS version of libtool. \subsection{Problems with Libltdl} Pspell also requires libltdl, Libtool's portable {}``dlopen{}'' wrapper library, in order to function properly. If configure does not find libltdl installed on your system it will generally compile it and install it with the rest of Pspell. However, this can create problems if the compile environment is different than the environment that Pspell runs under. For example if configure was able to find libltdl at compile time but libltdl is no longer visible at runtime you will run into problems. The easiest thing to do here is copy the libltdl library found when compiling Pspell into the library directly Pspell was installed in. Another potently source of problems is the fact that the version of Libltdl found in the Pspell distribution is not the same as the one found in the released version of Libtool. In fact the two, while being source code compatible, are not binary compatible. This should normally not be a problem because if configure finds libltdl already installed on your system it will use that one. However, this might cause problems if the compile environment is different than the environment that Pspell runs under. \subsection{Upgrading from Pspell .11.2} \label{new_size_parm}Pspell .12 breaks binary and source code compatibility with Pspell .11. Many of the PspellManager functions now also have a length parameter specifying the length of the word. A length of -1 means that the string is null terminated. This unfortunately breaks source code compatibility. To upgrade to Pspell .12 either define the variable USE\_ORIGINAL\_MANAGER\_FUNCS before pspell.h in included or simply add a length of -1 after each word passed in. Please see manager.h for the exact phototype of the functions. Defining the variable USE\_ORIGINAL\_MANAGER\_FUNCS will allow your code to work with both Pspell .11 and .12. \section{Helping Out} Right now the area I need the most help in is better shared library support and on the ispell module. If you are interested in helping out please contact me at kevina@users.sourceforge.net. If you wish to work on Pspell you will need the multi-language-branch of the CVS version of libtool. You will also need autoconf and automake. The released version of autoconf has a small bug in it which will cause it to think {}``.C{}'' is the extension of executables. To fix this you need to apply the patch {}``autoconf-exeext.patch{}'' which can be found in the pspell distribution. \chapter{Keeping in Touch} Even though you the LGPL license gives you the right to use Pspell in your application without ever notifying me, Kevin Atkinson, the sole author of Pspell---please don't. If you are using, or planning on using, Pspell in your project please at very least send me an email at kevina at users sourceforge net. It doesn't have to me anything fancy. A simple {}``I am planning on using Pspell in my project X. For more information please see Y.{}'' will suffice. I will greatly appreciate it. I put a lot of unpaid time into Pspell and Aspell and would appreciate simply knowing where it is being used. \chapter{Library Interface} \section{Overview} The Pspell library contains two main classes and several helper classes. The two main classes are PspellConfig and PspellMaster. The PspellConfig class is used to set initial defaults and to change spell checker specific options. The PspellManager class does most of the real work. It is responsible for managing the dictionaries, checking if a word is in the dictionary, and coming up with suggestions among other things. There are many helper classes the important ones are PspellWordList, PspellMutableWordList, Pspell{*}Emulation. The PspellWordList classes is used for accessing the suggestion list, as well as the personal and suggestion word list currently in use. The PspellMutableWordList is used to manage the personal, and perhaps other, word lists. The Pspell{*}Emulation classes are used for iterating through a list. A C and C++ Interface is provided. I recommend using the C interface, even if your program is in C++, to avoid some of the nasty issues associated with C++ linkage. In general one can only use C++ linkage if both the library and the program were created with the same compiler. I may eventually provide C++ wrapper classes, including a few STL like one, for the C library and remove the existing C++ interface all together. The mapping between the C and C++ interface is pretty straightforward and from C++ to C goes as follows: \begin{quote} \_({[}const{]} {*}, ) \end{quote} For example {}``PspellManager::lang\_name() const{}'' would become {}``pspell\_manager\_lang\_name(const PspellManager {*}){}''. Methods that return a bool will instead return an int in the C interface. \section{Usage} To use pspell your application should include {}``pspell/pspell.h{}''. In order to insure that all the necessary libraries are linked in libtool should be used to perform the linking. When using libtool simply linking with {}``-lpspell{}'' should be all that is necessary. When using shared libraries you might be able to simply link {}``-lpspell{}'', but this is not recommended. This version of Pspell uses the CVS version of libtool (multi-language-branch) however released versions of libtool should also work. When your application first starts you should get a new configuration class with the command: \begin{lyxcode} PspellConfig~{*}~spell\_config~=~new\_pspell\_config(); \end{lyxcode} which will create a new PspellConfig class. It is allocated with new and it is your responsibility to delete it with delete\_pspell\_config. The standard C++ delete can be used if the compiler is compatible with the one used to create the Pspell library. Once you have the config class you should set some variables. The most important one is the language variable. To do so use the command: \begin{lyxcode} pspell\_config\_replace(spell\_config,~\char`\"{}language-tag\char`\"{},~\char`\"{}en\_US\char`\"{}); \end{lyxcode} which will set the default language to use to American English. The language is expected to be the standard two letter ISO 639 language code, with an optional two letter ISO 3166 country code after an underscore. You can set the preferred spelling via the {}``spelling{}'' option, any extra info via the {}``jargon{}'' option, and the encoding via the {}``encoding{}'' option. Other things you might want to set is the preferred spell checker to use, the search path for dictionary's, and the like see section \ref{options} for the available options. When ever a new document is created a new PspellManager class should also be created. There should be one manager class per document. To create a new manager class use the new\_pspell\_manager and then cast it up using to\_pspell\_manager like so. \begin{lyxcode} PspellCanHaveError~{*}~possible\_err~=~new\_pspell\_manager(spell\_config);\\ PspellManager~{*}~spell\_checker~=~0;\\ if~(pspell\_error\_number(possible\_err)~!=~0)\\ ~~puts(pspell\_error\_message(possible\_err));\\ else\\ ~~spell\_checker~=~to\_pspell\_manager(possible\_err); \end{lyxcode} which will create a new PspellManager class using the defaults found in spell\_config. If C++ is being used AND the compiler is compatible with the one used to create the Pspell library a normal cast can be used instead of to\_pspell\_manager. If for some reason you want to use different defaults simply clone spell\_config and change the setting like so: \begin{lyxcode} PspellConfig~{*}~spell\_config2~=~pspell\_config\_clone(spell\_config);\\ pspell\_config\_replace(spell\_config2,~\char`\"{}language-tag\char`\"{},\char`\"{}nl\char`\"{});\\ possible\_err~=~new\_pspell\_manager(spell\_config2);\\ delete\_pspell\_config(spell\_config2); \end{lyxcode} Once again in C++ delete\_pspell\_config can be replaced with a simple C++ delete. Once the manager class is created you can use the check method to see if a word in the document is correct like so: \begin{lyxcode} int~correct~=~pspell\_manager\_check(spell\_checker,~,~); \end{lyxcode} can is expected to a const char {*} character string. If the encoding is set to be {}``machine unsigned 16{}'' or {}``machine unsigned 32{}''. is expected to be a cast from either const u16int {*} or const u32int{*} respectfully. U16int and u32int are generally unsigned short and unsigned int respectfully. is the length of the string or -1 if the sting is null terminated. If the string is a cast from const u16int {*} or const u32int {*} then size is the amount of space in bytes the string takes up after being casted to const char {*} and not the true size of the string. Pspell\_manager\_check will return 0 is it is not found and non-zero otherwise. If the word is not correct than the suggest method can be used to come up with likely replacements. \begin{lyxcode} PspellWordList~{*}~suggestions~=~pspell\_manager\_suggest(spell\_checker,~\\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~,~);\\ PspellStringEmulation~{*}~elements~=~pspell\_word\_list\_elements(suggestions);\\ const~char~{*}~word;\\ while~(~(word~=~pspell\_string\_emulation\_next(pspell\_elements)~!=~NULL~)~\{\\ ~~//~add~to~suggestion~list\\ \}\\ delete\_pspell\_string\_emulation(elements); \end{lyxcode} Notice how \texttt{elements} is deleted but \texttt{suggestions} is not. The value returned by suggestions is only valid to the next call to suggest. Once a replacement is made the store\_repl method should be used to communicate the replacement pair back to the spell checker (see section \ref{storerepl} for why). It usage is as follows: \begin{lyxcode} pspell\_manager\_store\_repl(spell\_checker,~\\ ~~~~~~~~~~~~~~~~~~~~~~~~~~,~,\\ ~~~~~~~~~~~~~~~~~~~~~~~~~~,~); \end{lyxcode} If the user decided to add the word to the session or personal dictionary the the word can be be added using the add\_to\_session or add\_to\_personal methods respectfully like so: \begin{lyxcode} pspell\_manager\_add\_to\_session|personal(spell\_checker,~,~); \end{lyxcode} It is better to let the spell checker manage these words rather than doing it your self so that the words have a change of appearing in the suggestion list. Finally, when the document is closed the PspellManager class should be deleted like so. \begin{lyxcode} delete\_pspell\_manager(spell\_checker); \end{lyxcode} The standard C++ delete should NOT be used here because it will not unload any shared libraries pulled in my when the manager class is created. \section{Class Reference} Methods that return a bool generally return false on error and true other wise. To find out what went wrong use the error\_number and error\_message methods. Unless otherwise stated methods that return a const char {*} will return null on error. The charter string returned is only valid until the next method which returns a const char {*} is called. All methods are virtual and abstract, thus these classes are really abstract base classes. Therefore you cannot simply store the object directly. In order to make copies of the objects use the clone and assign methods if they are provided. For the details of the various classes please see the header files. In the future I will generate class references using some automated tool. \section{Available Options\label{options}} The following options are available to control which word list Pspell selects. \begin{description} \item [language-tag~]the language code which consists of the two letter ISO 639 language code and an optional two letter ISO 3166 country code after a dash or underscore. \item [spelling~]the requested spelling for languages with more than one spelling such as English. Known values are {}``american{}'', {}``britsh{}'', and {}``canadian{}''. This information is normally inferred from the language-tag option. For example the language tag {}``en\_GB{}'' will set spelling to {}``british{}''. \item [jargon~]an extra information to distinguish two different words lists that have the same language-tag and spelling. \item [word-list-path~]search path for word list information files \item [module-search-order~]list of available modules, modules that come first on this list have a higher priority \end{description} The following options control the behavior of the selected module. Not all modules support all options. \begin{description} \item [encoding~]encoding that words are expected to be in. Valid values are {}``utf-8{}'', {}``iso8859-{*}{}'', {}``koi8-r{}'', {}``viscii{}'', {}``cp1252{}'', {}``machine unsigned 16{}'', {}``machine unsigned 32{}''. \item [ignore~]ignore all words which are not at least as long as the value for this setting \item [personal~]file name of the personal word list to use. Start it with {}``./{}'' to look for the file in the current directory rather than the home directory. \item [repl~]file name of the replacement word list to use. Start it with {}``./{}'' to look for the file in the current directory rather than the home directory. \item [save-repl~]save the replacement word list on calls to save\_all\_word\_lists. \item [ignore-repl~]ignore calls to Manager::store\_replacement. \item [sug-mode~]the suggestion mode, known values are fast, normal, and bad-spellers \item [run-together~]consider run-together words as legal compounds. \end{description} The following options may be examined to tell exactly what word list or module was selected \begin{description} \item [master]the full path of the word list selected \item [master-flags]any special flags that were passed on to the module \item [module]the module selected \end{description} The options, \textbf{spelling} and \textbf{jargon} can also be examined. options may be set to anything, including in some cases an empty string. options must be set to a valid integer string. options must be set to {}``true{}'' or {}``false{}''. options can not be set directly, you must use the option add-