jazzy-0.5.2/0000755000175000017500000000000011620032121012607 5ustar twernertwernerjazzy-0.5.2/CONTRIBUTORS.txt0000644000175000017500000000105710341057332015322 0ustar twernertwernerJazzy Spell Checker could not have been possible without the involvment of the following people. Thanks! Author (Initial contributor) Mindaugas Idzelis (min123 AT gmail DOT com) Other contributors Ben Galbraith (ben AT galbraiths DOT org) Damien Guillaume Robert Gustavsson (robert AT lindesign DOT se) Jason Height (jheight AT chariot DOT net DOT au) Anthony Roy (ajr AT antroy DOT co DOT uk) Stig Tanggaard Don Vail Matthew Demerath (mdemerat AT umich DOT edu | Matthew AT Demerath DOT com) Tony Chan (htchan AT umich DOT edu) jazzy-0.5.2/README.txt0000644000175000017500000000541710253367652014341 0ustar twernertwerner J A Z Z Y : Java Spell Checker What is it? ----------- Jazzy is a 100% pure Java library implementing a spell checking algorithm similar to aspell. It may be used to spell check a variety of sources. The Latest Version ------------------ The latest version is available from the Jazzy project web site ( http://sourceforge.net/projects/jazzy ). Requirements ------------ The following requirements exist for installing Jazzy: o Java Interpreter: A fully compliant Java 1.1 Runtime environment is needed for the core engine of Jazzy to operate. (For example: for use in a servlet) A fully compliant Java 1.3 Runtime environment is needed for the swing components of Jazzy to operate. o Java JFC (Swing components): These GUI extentions are required for proper GUI functionality. However, core spell check functionality can work without Swing Components. Installation Instructions and Documentation ------------------------------------------- There are two ways to install Jazzy. One from a pre packaged version and the other is to compile the sources from CVS. If you have downloaded the source code from CVS, please cd to the jazzy directory and run ant. Building Jazzy From the Source ------------------------------ 1) In order to build the jedit plugin, you will need to have the jedit.jar in your classpath, otherwise you will get a lot of compile errors. All of the build errors relate to the files under src/com/swabunga/spell/jedit/* The easiest way to get jedit.jar onto your machine is to install jedit. You can find it at http://sourceforge.net/projects/jedit 2) In order to build the sample applet spell checker, you will need to sign the jar with "jazzykey". In order to sign the jar, you will need a key called "jazzykey". On some systems, you should be able to run the following command to get the key built: keytool -genkey -alias jazzyKey when prompted for the password, use the same one that's in build.xml (search for "sign") For more information on creating keys, see: http://java.sun.com/docs/books/tutorial/security1.2/toolsign/step3.html 3) The ant target that builds most things is "binary-release", but you may want to build a smaller target. The current default target is "library-all", which may be sufficient if you just want the jar. 4) In order to see the applet demo, you will have to have a web server running. Point it to the www directory to see the index.html page and the applet demo.html page Licensing and legal issues -------------------------- Jazzy is licensed under the LGPL. See LICENSE.txt for license restrictions. jazzy-0.5.2/example2.txt0000644000175000017500000000014007631145136015102 0ustar twernertwerneri luv that yoo are soo shweet! Niether of them were thier frinds. i nevr lovedd you veri muchjazzy-0.5.2/src/0000755000175000017500000000000010341056556013417 5ustar twernertwernerjazzy-0.5.2/src/com/0000755000175000017500000000000010341056556014175 5ustar twernertwernerjazzy-0.5.2/src/com/swabunga/0000755000175000017500000000000010341056556016004 5ustar twernertwernerjazzy-0.5.2/src/com/swabunga/test/0000755000175000017500000000000010341056556016763 5ustar twernertwernerjazzy-0.5.2/src/com/swabunga/test/spell/0000755000175000017500000000000010341056556020102 5ustar twernertwernerjazzy-0.5.2/src/com/swabunga/test/spell/event/0000755000175000017500000000000010341056556021223 5ustar twernertwernerjazzy-0.5.2/src/com/swabunga/test/spell/event/StringWordTokenizerTester.java0000644000175000017500000000522710253371640027254 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.test.spell.event; import junit.framework.*; import junit.textui.*; import com.swabunga.spell.event.*; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; public class StringWordTokenizerTester extends TestCase { StringWordTokenizer texTok; public StringWordTokenizerTester(String name){ super(name); } protected void setUp(){ texTok = new StringWordTokenizer( stringValue(new File("src/com/swabunga/test/spell/event/test.tex")), new TeXWordFinder() ); } protected void tearDown(){ texTok = null; } public void testRead(){ assertTrue(!texTok.getContext().equals("")); } public void testWordA(){ assertEquals("width", texTok.nextWord()); assertEquals("1", texTok.nextWord()); assertEquals("1", texTok.nextWord()); assertEquals("1cm", texTok.nextWord()); assertEquals("1", texTok.nextWord()); assertEquals("Key", texTok.nextWord()); assertEquals("Words", texTok.nextWord()); } public static void main(String[] args){ //System.out.println("No tests currently written for FileWordTokenizerTester."); TestRunner.run(new TestSuite(StringWordTokenizerTester.class)); } private static String stringValue(File inFile) { File stringFile = inFile; StringBuffer out = new StringBuffer(""); try{ BufferedReader in = new BufferedReader(new FileReader(inFile)); char[] c = new char[100]; int count; while ((count = in.read(c, 0, c.length)) != -1){ out.append(c,0,count); } in.close(); } catch(IOException e){ System.err.println("File input error trying to open " + inFile.toString() + " : " + e); } return out.toString(); } } jazzy-0.5.2/src/com/swabunga/test/spell/event/test.tex0000644000175000017500000002551307726050470022734 0ustar twernertwerner% ` in Discrete Space' %{{{ :wrap=soft:maxLineLen=0:folding=explicit::collapseFolds=2: %{{{ Preamble \documentclass[11pt,a4paper]{llncs} \usepackage{xspace} \usepackage[dvipdf]{graphicx} \usepackage{amsfonts} \usepackage{amssymb} \usepackage{amsmath} \usepackage{color} \usepackage{ifthen} \setkeys{Gin}{width=\linewidth} \newcounter{ax} \newenvironment{axioms}[1] {\begin{list}{\bf{(#1\arabic{ax})}}{\usecounter{ax}\setlength{\leftmargin}{1cm} }} {\end{list}} \newcommand{\keywords}[1]{\noindent{\small\textbf{Key Words:} #1}} \newcommand{\oC}{\overline{C}} \newcommand\oK{\overline{K}} \newcommand\Z[1][]{\ensuremath{\mathbb{Z}^{#1}}\xspace} \newcommand\R[1][]{\ensuremath{\mathbb{R}^{#1}}\xspace} \newcommand\cI{\ensuremath{\mathcal{I}}\xspace} \newcommand\cC{\ensuremath{\mathcal{C}}\xspace} \newcommand\cB{\ensuremath{\mathcal{B}}\xspace} \newcommand\cHH{\ensuremath{\mathcal{H}}\xspace} \newenvironment{compbullist} {\begin{itemize} \setlength{\itemsep}{0ex plus0.2ex} \setlength{\parsep}{0ex plus0.2ex}} {\end{itemize}} \newcounter{tabcount} \newcommand{\tab}[1][1]{ \setcounter{tabcount}{#1} \whiledo{\value{tabcount}>0}{\hspace{.5em}\addtocounter{tabcount}{-1}} } \newcounter{algCount} \newenvironment{compactlist}[1][] {\begin{list}{#1\arabic{algCount}.} {\usecounter{algCount} \setlength{\itemsep}{0ex plus0.2ex} \setlength{\parsep}{0.2ex} }} {\end{list}} \newenvironment{algo}[3] {\vspace{2ex} \noindent\textbf{\textsc{Algorithm }} #1 \emph{Input}: \texttt{#2} \emph{Output}: \texttt{#3} \begin{compactlist} \begin{ttfamily}} {\end{ttfamily} \end{compactlist} } %\renewcommand\baselinestretch{1.5} %}}} %{{{ Title page \begin{document} \title{ in Discrete Space} \author{Anthony J. Roy \and John G. Stell} \institute{School of Computing,\\ University of Leeds,\\ Leeds, LS2 9JT, U. K.} \maketitle \begin{abstract} This paper looks at spaces. \end{abstract} \keywords{Simple things heere.} \pagebreak %}}} %********************************************************************* \section{Introduction}%{{{ The concept of a convex region plays an important part in many practical computations in GIS. As an example of the latter, we note that the region-connection calculus was extended~\cite[p287]{CohnGeoInf1997} by adding a one place function which returned the convex hull of a region. axiom. These correspond to convex geometries geometries respectively, the latter giving rise to. We define constructs that give rise to convex geometries. We go on to investigate cell complexes, and see how these give rise to aligned spaces. Several definitions are given, and relationships between these are given. It is important that in the abstract: it is necessary to show how computations can be carried out. We provide some algorithms for the computation of convex hulls of oriented in Section~\ref{algorithms}. A brief introduction to the necessary oriented concepts is provided earlier in Section~\ref{mat}. %}}} %********************************************************************* \section{Coinvexity} %{{{ This serction gives an of convex a very general setting. The conccepts themselves come from the corresponding concepts of convex geometries defined on a vector space over the real numbers. Both concepts are founded from the notion of linear combinations of points in a vector space - the addition of scalar multiples of a set of points. Given a set of vectors $\mathit{v}_{0}, \ldots, \mathit{v}_{k}$, and a set of scalars, $\lambda_{0}, \ldots, \lambda_{k}$, a linear combination of these vectors given the set of scalars is a vector given by $\sum^{k}_{i=0}\lambda_{i}\mathit{v}_{i}$ A \emph{subspace} of a vector space is a subset $S \subset\R[n]$ which contains all linear combinations of points in $S$. Examples are $\R[n]$, the origin $\mathbf{0}$, any line or plane passing through the origin etc. Note that the origin will always be in a subspace, since all scalars can be set to zero. combinations are a subset of the vector combinations, restricted in that the scalars must add up to exactly $1$. This gives rise to the notion of sets, the sets $S \subset\R[n]$ which contains all combinations of points in $S$. The set of sets includes all translations of the set of subspaces - the origin is no longer a necessary element of an set, since the scalars can no longer all be set to zero. An sets is often characterized as a set containing all of the lines through all pairs of points in the set. Convex combinations are again a subset of the combinations, and are restricted further by the condition that not only must the scalars add up to $1$, but they must also lie in the range $[0,1]$. Convex sets are simply sets containing all convex combinations of its members - they are often characterized as sets containing all line segments between each of its pairs of points. It is obvious from the above definitions that linear, and convex sets are closely related, and that indeed linear subsets are subsets, and subsets are convex subsets (though not the reverse in general). The notion of aligned spaces given below is an abstraction of convex and geometries \subsection{Alignment Spaces}\label{align}%{{{ The concept of alignment spaces was introduced by Coppel\cite{Coppel98} as a general axiomatization of . The main focus of his work is on continuous settings, but we show here how the axioms of alignment spaces can be successfully applied to discrete spaces. In Euclidean space a set, $S$, is said to be convex if for every pair of points in $S$ the straight line between them is also in $S$. We can show that this definition does not directly extend to discrete space. If we define a straight line between two points, $a$ and $b$, in \Z[n] as being the set of all points co-linear with those points, and between them. That is, $line(a,b) = \{x\in\Z[n]|x = \lambda a + \gamma b,\;\lambda + \gamma = 1,\;0\leq\lambda,\gamma\}$. Figure~\ref{ex1} shows that such a definition of does not fit with an intuitive notion of convex. In this example, the three points alone are by the naive definition a convex set. The following definition begins to capture some of the properties we would expect a convex set to possess. \begin{definition}[Alignment Space] An \emph{alignment space} is a set $X$ along with a set $\mathcal{C}$ of subsets of $X$ such that the following axioms hold: \begin{description} \item [(A0)] $\varnothing \in \mathcal{C}$\hfill (Empty set)\label{a0} \item [(A1)] $X \in \mathcal{C}$\hfill (Top set)\label{a1} \item [(A2)] $\forall S\subseteq \mathcal{C}, \; S\not= \varnothing \rightarrow \bigcap S \in\mathcal{C}$\hfill (Intersection)\label{a2} \item [(A3)] $\forall S\subseteq \mathcal{C}, \; S\not= \varnothing$ if $S$ is totally ordered by inclusion, then $\bigcup S\in\mathcal{C}$\hfill (Qualified union)\label{a3} \end{description} We call the sets in $\mathcal{C}$ \emph{aligned sets}. The intersection of all aligned sets containing a set $S\subseteq X$ is called the \emph{alignment hull} of $S$, denoted $[S]$. \end{definition} \begin{proposition} Note that the following properties hold of any alignment hull: \begin{description} \item [H0] $[\varnothing]=\varnothing$ \item [H1] $S\subseteq[S]$ \item [H2] $S\subseteq T \rightarrow [S]\subseteq [T]$ \item [H3] $[[S]]=[S]$ \item [H4] $[S] = \bigcup \{[T]: T\subseteq S \text{ and T is finite}\}$ \end{description} \end{proposition} The proof for this proposition can be found in \cite{Coppel98} In brief the axioms state that the entire set is aligned, arbitrary intersections of aligned sets are aligned, and the union of totally ordered sets of aligned sets are also aligned. These are properties we would expect of convex sets. These axioms alone are not enough however, as Figure~\ref{naive_convex_set} shows. \begin{figure} \parbox{.4\textwidth}{\includegraphics[width=.4\textwidth]{graphics/convex1.png} \caption{A `convex' set according to the naive definition.}\label{naive_convex_set} }\hfill \parbox{.4\textwidth}{\includegraphics[width=.4\textwidth]{graphics/example.png} \caption{A subset of $2^X$ that satisfies the alignment axioms.}\label{ex1} }\end{figure} Figure~\ref{ex1} shows two sets of points. Let $\mathcal{C}$ be a set containing these two sets along with their intersection, the entire space $X$ and the empty set. Then, $\mathcal{C}$ satisfies all three axioms, and is hence an aligned space. This is an aligned set, but is not convex in our usual understanding of the concept. %}}} \subsection{Convex Geometries}%{{{ To overcome the problem just mentioned, a further axiom, known as the anti-exchange property, is added. \begin{definition}[Anti-exchange Property] \label{ae} The anti-exchange property is characterized by the following axiom: \begin{description} \item [(AE)] $\forall x,y\in X, \; \forall S\subseteq X,\; \text{ if } x\not= y \text{ and } y\in [S\cup x]\text{ and }y\not\in[S] \text{ then } x\not\in [S\cup y]$\hfill (Anti-exchange) \end{description} \end{definition} Clearly the example in Figure~\ref{ex1} fails to satisfy this additional axiom. Take for example $S$ to be one of the two depicted subsets, and $x$ and $y$ as distinct points not in S then $S\subseteq X,\; x\not= y$ as required, $y\in[S\cup x]$ since $[S\cup x]=X$ ($X$ is the largest aligned set containing $S\cup x$), $y\not\in [S]$ since $S$ is the smallest aligned set containing itself. However, $x\in [S\cup y]$ since $X$ is again the smallest aligned set containing the union of $S$ and $x$. We shall refer to aligned spaces for which the anti-exchange property holds as \emph{convex geometries}, and the alignment hulls in this special case \emph{convex hulls}. Note that the term usually refers to geometries defined with points and segments as primitives (see \cite{Coppel98}), but in this paper we have already seen that such an axiomatization would not be applicable in the case of discrete space. Figure~\ref{ex2} shows an example of a space that satisfies the five axioms A0-A3 and AE. Note that though all axioms are satisfied, there are subsets missing that we would normally consider to be convex. %\com{Perhaps some kind of symmetry axiom is necessary? Can't think at the minute how such a thing would work though...} \begin{figure} \begin{center} \includegraphics[width=.4\textwidth]{graphics/ex2.png} \caption{A convex geometry.}\label{ex2} \end{center} \end{figure} %}}} %}}} %********************************************************************* %Bibliography%{{{ % %GATHER{.bib} % For Gather Purpose Only - same filename as bib file below. %GATHER{.bbl} % Named after this (main) file \nocite{*} % Include this command to include uncited bib entries into the bibliography \bibliographystyle{alpha} \bibliography{} % .bib not required. Full pathname allowed. %}}} \end{document}%}}} jazzy-0.5.2/src/com/swabunga/test/spell/event/FileWordTokenizerTester.java0000644000175000017500000000376210253371640026667 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.test.spell.event; import junit.framework.*; import junit.textui.*; import com.swabunga.spell.event.*; import java.io.File; public class FileWordTokenizerTester extends TestCase { FileWordTokenizer texTok; public FileWordTokenizerTester(String name){ super(name); } protected void setUp(){ texTok = new FileWordTokenizer(new File("src/com/swabunga/test/spell/event/test.tex"), new TeXWordFinder()); } protected void tearDown(){ texTok = null; } public void testRead(){ assertTrue(!texTok.getContext().equals("")); } public void testTeXWordA(){ assertEquals("width", texTok.nextWord()); assertEquals("1", texTok.nextWord()); assertEquals("1", texTok.nextWord()); assertEquals("1cm", texTok.nextWord()); assertEquals("1", texTok.nextWord()); assertEquals("Key", texTok.nextWord()); assertEquals("Words", texTok.nextWord()); } public static void main(String[] args){ //System.out.println("No tests currently written for FileWordTokenizerTester."); TestRunner.run(new TestSuite(FileWordTokenizerTester.class)); } } jazzy-0.5.2/src/com/swabunga/test/spell/event/TeXWordFinderTester.java0000644000175000017500000001151610253371640025741 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.test.spell.event; import junit.framework.*; import junit.textui.*; import com.swabunga.spell.event.*; public class TeXWordFinderTester extends TestCase { public TeXWordFinderTester(String name){ super(name); } protected void setUp(){ } protected void tearDown(){ } public void testWordFindA(){ assertFound("string of words","string"); } public void testWordFindB(){ assertFound("\\string of words","of"); } public void testWordFindC(){ assertFound("\\begin{testing}\nthe text \n\\end{testing}","the"); } public void testWordFindD(){ assertFound("%testing\ntime","time"); } public void testWordFindE(){ assertFound("$testing$time","time"); } public void testWordFindF(){ assertFound("$$testing$$time","time"); } public void testUnaryWordFindA(){ assertFound("a test of words","a"); } public void testUnaryWordFindB(){ assertFound("\\string a test","a"); } public void testUnaryWordFindC(){ assertFound("\\begin{testing}\na test \n\\end{testing}","a"); } public void testUnaryWordFindD(){ assertFound("\\begin{testing}a\n\\end{testing}","a"); } public void testUnaryWordFindE(){ assertFound("%testing\na time","a"); } public void testUnaryWordFindF(){ assertFound("$testing$a time","a"); } public void testUnaryWordFindG(){ assertFound("$$testing$$a time","a"); } public void testUnaryWordFindH(){ assertFound("\\newcommand{not these}\\newcommand{not these}a time","a"); } public void testNoWordsFoundA(){ assertNotFound(""); } public void testNoWordsFoundB(){ assertNotFound("\\string \\of\\words"); } public void testNoWordsFoundC(){ assertNotFound("\\begin{testing}\n\\end{testing}"); } public void testNoWordsFoundD(){ assertNotFound("%testing time"); } public void testNoWordsFoundE(){ assertNotFound("$testing time$"); } public void testNoWordsFoundF(){ assertNotFound("$$testing time$$"); } public void testFindAllWordsA(){ String[] expected = {"This","is","a","simple","test","string"}; assertAllWordsFound("This is a simple test string.", expected); } public void testFindAllWordsB(){ String[] expected = {"is","a","test"}; assertAllWordsFound("\\This is a \\simple test \\string.", expected); } public void testFindAllWordsC(){ String[] expected = {"This","is","a","simple","test","string"}; assertAllWordsFound("This is a simple test string.", expected); } public void testFindAllWordsD(){ String[] expected = {"This","is","a","simple","test","string"}; assertAllWordsFound("This is a simple test string.", expected); } private void assertAllWordsFound(String text, String[] expected){ TeXWordFinder finder = new TeXWordFinder(text); Word found; int wordCount = 0; try{ for (int i = 0; i < expected.length; i++){ found = finder.next(); wordCount++; assertEquals(expected[i],found.getText()); } found = finder.next(); fail("No more words should have been found\nString: '" + found + "'"); }catch(Exception e){ }finally{ assertEquals(expected.length, wordCount); } } private void assertNotFound(String testText){ TeXWordFinder finder = new TeXWordFinder(testText); try{ finder.next(); fail("\nNo words should have been found!\nWordNotFoundException should have been thrown.\nString: " + testText); }catch (Exception e){ } } private void assertFound(String testText, String expected){ TeXWordFinder finder = new TeXWordFinder(testText); Word found = finder.next(); assertEquals(expected,found.getText()); } public static void main(String[] args){ TestRunner.run(new TestSuite(TeXWordFinderTester.class)); } } jazzy-0.5.2/src/com/swabunga/test/spell/event/SpellCheckerTester.java0000644000175000017500000000521110253371640025614 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.test.spell.event; import junit.framework.*; import junit.textui.*; import com.swabunga.spell.event.*; import com.swabunga.spell.engine.*; import java.io.*; import java.util.*; public class SpellCheckerTester extends TestCase implements SpellCheckListener { SpellChecker checker; ArrayList misspelled; public SpellCheckerTester(String name){ super(name); } protected void setUp(){ File dict = new File("dict/english.0"); try{ checker = new SpellChecker(new SpellDictionaryHashMap(dict)); }catch (FileNotFoundException e){ System.err.println("Dictionary File " + dict + " not found! " + e); }catch (IOException ex){ System.err.println("IO problem: " + ex); } FileWordTokenizer texTok = new FileWordTokenizer(new File("src/com/swabunga/test/spell/event/test.tex"), new TeXWordFinder()); misspelled = new ArrayList(); checker.addSpellCheckListener(this); checker.checkSpelling(texTok); } protected void tearDown(){ checker = null; } public void testTeXNext(){ Iterator it = misspelled.iterator(); assertEquals("Anthony", it.next()); assertEquals("Stell", it.next()); assertEquals("Leeds", it.next()); assertEquals("heere", it.next()); assertEquals("Coinvexity", it.next()); assertEquals("serction", it.next()); assertEquals("conccepts", it.next()); } public void spellingError(SpellCheckEvent event){ event.ignoreWord(true); misspelled.add(event.getInvalidWord()); } public static void main(String[] args){ //System.out.println("No tests currently written for FileWordTokenizerTester."); TestRunner.run(new TestSuite(SpellCheckerTester.class)); } } jazzy-0.5.2/src/com/swabunga/util/0000755000175000017500000000000010341056556016761 5ustar twernertwernerjazzy-0.5.2/src/com/swabunga/util/StringUtility.java0000644000175000017500000000272210253371642022457 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.util; public class StringUtility { public static StringBuffer replace(StringBuffer buf, int start, int end, String text) { int len = text.length(); char[] ch = new char[buf.length() + len - (end - start)]; buf.getChars(0, start, ch, 0); text.getChars(0, len, ch, start); buf.getChars(end, buf.length(), ch, start + len); buf.setLength(0); buf.append(ch); return buf; } public static void main(String[] args) { System.out.println(StringUtility.replace(new StringBuffer(args[0]), Integer.parseInt(args[2]), Integer.parseInt(args[3]), args[1])); } } jazzy-0.5.2/src/com/swabunga/util/VectorUtility.java0000644000175000017500000000246610253371642022460 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.util; import java.util.Iterator; import java.util.List; public class VectorUtility { public static List addAll(List dest, List src) { return addAll(dest, src, true); } public static List addAll(List dest, List src, boolean allow_duplicates) { for (Iterator e = src.iterator(); e.hasNext();) { Object o = e.next(); if (allow_duplicates || !dest.contains(o)) dest.add(o); } return dest; } } jazzy-0.5.2/src/com/swabunga/spell/0000755000175000017500000000000010341056556017123 5ustar twernertwernerjazzy-0.5.2/src/com/swabunga/spell/examples/0000755000175000017500000000000010341056556020741 5ustar twernertwernerjazzy-0.5.2/src/com/swabunga/spell/examples/JTextComponentSpellCheckExample.java0000644000175000017500000001054210253371640027775 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * put your module comment here * formatted with JxBeauty (c) johann.langhofer@nextra.at */ package com.swabunga.spell.examples; import com.swabunga.spell.engine.*; import com.swabunga.spell.swing.JTextComponentSpellChecker; import javax.swing.*; import javax.swing.text.JTextComponent; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; /** This class shows an example of how to use the spell checking capability * on a JTextComponent. * * @author Robert Gustavsson (robert@lindesign.se) */ public class JTextComponentSpellCheckExample extends JFrame { private static final String englishDictionary = "dict/english.0"; private static final String englishPhonetic = "dict/phonet.en"; protected SpellDictionary dictionary; JTextComponent text = null; JButton spell = null; public JTextComponentSpellCheckExample(String dictPath, String phonetPath) { File dictFile=null, phonetFile=null; // INIT DICTIONARY if(dictPath==null) dictFile=new File(englishDictionary); else dictFile=new File(dictPath); if(phonetPath!=null) phonetFile=new File(phonetPath); try { dictionary = new SpellDictionaryHashMap(dictFile, phonetFile); //dictionary = new SpellDictionaryDisk(dictFile, phonetFile, true); //dictionary = new GenericSpellDictionary(dictFile, phonetFile); } catch (Exception ex) { ex.printStackTrace(); } // INIT GUI setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); addWindowListener(new WindowAdapter() { public void windowClosed(WindowEvent e) { System.exit(0); } }); initGUI(); pack(); } private void initGUI() { Container frame = getContentPane(); GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); frame.setLayout(gridbag); c.anchor = GridBagConstraints.CENTER; c.fill = GridBagConstraints.BOTH; c.insets = new Insets(5, 5, 5, 5); c.weightx = 1.0; c.weighty = 1.0; text = new JTextArea(10, 40); addToFrame(frame, text, gridbag, c, 0, 0, 1, 1); spell = new JButton("spell"); spell.addActionListener(new ButtonListener()); addToFrame(frame, spell, gridbag, c, 0, 1, 1, 1); } // Helps build gridbaglayout. private void addToFrame(Container f, Component c, GridBagLayout gbl, GridBagConstraints gbc, int x, int y, int w, int h) { gbc.gridx = x; gbc.gridy = y; gbc.gridwidth = w; gbc.gridheight = h; gbl.setConstraints(c, gbc); f.add(c); } public static void main(String[] args) { String dictPath=null, phonetPath=null; if(args.length>0) dictPath=args[0]; if(args.length>1) phonetPath=args[1]; JTextComponentSpellCheckExample d = new JTextComponentSpellCheckExample(dictPath,phonetPath); d.show(); } // INNER CLASSES private class ButtonListener implements ActionListener { public void actionPerformed(ActionEvent e) { Thread t = new SpellThread(); t.start(); } } private class SpellThread extends Thread { public void run() { try { JTextComponentSpellChecker sc = new JTextComponentSpellChecker(dictionary); sc.spellCheck(text); } catch (Exception ex) { ex.printStackTrace(); } } } } jazzy-0.5.2/src/com/swabunga/spell/examples/SwingFormExample.java0000644000175000017500000000343510253371640025034 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.examples; import com.swabunga.spell.swing.JSpellApplet; import javax.swing.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; /** This class shows an example of how to use the spell checking capability * for a text area on a swing form. * * @author Jason Height (jheight@chariot.net.au) */ public class SwingFormExample extends JFrame { public SwingFormExample() { setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); addWindowListener(new WindowAdapter() { public void windowClosed(WindowEvent e) { System.exit(0); } }); JSpellApplet spellapplet = new JSpellApplet(); spellapplet.init(); getContentPane().add(spellapplet); } public static void main(String[] args) { SwingFormExample ex = new SwingFormExample(); System.out.println("Showing form"); ex.setSize(400, 200); ex.setVisible(true); } } jazzy-0.5.2/src/com/swabunga/spell/examples/TextPaneMarkingExample.java0000644000175000017500000001023610253371640026157 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * put your module comment here * formatted with JxBeauty (c) johann.langhofer@nextra.at */ package com.swabunga.spell.examples; import com.swabunga.spell.engine.*; import com.swabunga.spell.swing.JTextComponentSpellChecker; import javax.swing.*; import java.awt.*; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.io.File; /** This class shows an example of how to use the spell checking capability * on a JTextComponent. * * @author Robert Gustavsson (robert@lindesign.se) */ public class TextPaneMarkingExample extends JFrame { private static final String englishDictionary = "dict/dict.sv"; private static final String englishPhonetic = "dict/phonet.sv"; protected SpellDictionary dictionary; JTextPane text = null; JButton spell = null; JTextComponentSpellChecker sc = null; public TextPaneMarkingExample(String dictPath, String phonetPath) { File dictFile=null, phonetFile=null; // INIT DICTIONARY if(dictPath==null) dictFile=new File(englishDictionary); else dictFile=new File(dictPath); if(phonetPath!=null) phonetFile=new File(phonetPath); try { dictionary = new SpellDictionaryHashMap(dictFile, phonetFile); //dictionary = new SpellDictionaryDisk(dictFile, phonetFile, true); //dictionary = new GenericSpellDictionary(dictFile, phonetFile); } catch (Exception ex) { ex.printStackTrace(); } // INIT GUI setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); addWindowListener(new WindowAdapter() { public void windowClosed(WindowEvent e) { System.exit(0); } }); initGUI(); pack(); } private void initGUI() { Container frame = getContentPane(); GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); frame.setLayout(gridbag); c.anchor = GridBagConstraints.CENTER; c.fill = GridBagConstraints.BOTH; c.insets = new Insets(5, 5, 5, 5); c.weightx = 1.0; c.weighty = 1.0; text = new JTextPane(); text.setPreferredSize(new Dimension(300,150)); sc=new JTextComponentSpellChecker(dictionary); sc.startAutoSpellCheck(text); addToFrame(frame, new JScrollPane(text), gridbag, c, 0, 1, 1, 1); JMenuBar menuBar=new JMenuBar(); JMenu menu=null; int menuCount=0; Action[] actions=text.getEditorKit().getActions(); for(int i=0;i0) dictPath=args[0]; if(args.length>1) phonetPath=args[1]; TextPaneMarkingExample d = new TextPaneMarkingExample(dictPath,phonetPath); d.show(); } } jazzy-0.5.2/src/com/swabunga/spell/examples/SpellCheckExample.java0000644000175000017500000000566210253371640025142 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.examples; import com.swabunga.spell.engine.SpellDictionary; import com.swabunga.spell.engine.SpellDictionaryHashMap; import com.swabunga.spell.event.SpellCheckEvent; import com.swabunga.spell.event.SpellCheckListener; import com.swabunga.spell.event.SpellChecker; import com.swabunga.spell.event.StringWordTokenizer; import java.io.BufferedReader; import java.io.File; import java.io.InputStreamReader; import java.util.Iterator; import java.util.List; /** This class shows an example of how to use the spell checking capability. * * @author Jason Height (jheight@chariot.net.au) */ public class SpellCheckExample implements SpellCheckListener { private static String dictFile = "dict/english.0"; private static String phonetFile = "dict/phonet.en"; private SpellChecker spellCheck = null; public SpellCheckExample() { try { SpellDictionary dictionary = new SpellDictionaryHashMap(new File(dictFile), new File(phonetFile)); spellCheck = new SpellChecker(dictionary); spellCheck.addSpellCheckListener(this); BufferedReader in = new BufferedReader(new InputStreamReader(System.in)); while (true) { System.out.print("Enter text to spell check: "); String line = in.readLine(); if (line.length() <= 0) break; spellCheck.checkSpelling(new StringWordTokenizer(line)); } } catch (Exception e) { e.printStackTrace(); } } public void spellingError(SpellCheckEvent event) { List suggestions = event.getSuggestions(); if (suggestions.size() > 0) { System.out.println("MISSPELT WORD: " + event.getInvalidWord()); for (Iterator suggestedWord = suggestions.iterator(); suggestedWord.hasNext();) { System.out.println("\tSuggested Word: " + suggestedWord.next()); } } else { System.out.println("MISSPELT WORD: " + event.getInvalidWord()); System.out.println("\tNo suggestions"); } //Null actions } public static void main(String[] args) { new SpellCheckExample(); } } jazzy-0.5.2/src/com/swabunga/spell/examples/SpellCheckExample2.java0000644000175000017500000000620510253371640025216 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.examples; import com.swabunga.spell.engine.SpellDictionary; import com.swabunga.spell.engine.SpellDictionaryHashMap; import com.swabunga.spell.event.SpellCheckEvent; import com.swabunga.spell.event.SpellCheckListener; import com.swabunga.spell.event.SpellChecker; import com.swabunga.spell.event.StringWordTokenizer; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.util.Iterator; import java.util.List; /** This class shows an example of how to use the spell checking capability. * * @author Jason Height (jheight@chariot.net.au) */ public class SpellCheckExample2 implements SpellCheckListener { private static String dictFile = "dict/english.0"; private SpellChecker spellCheck = null; public SpellCheckExample2(String phoneticFileName) { try { BufferedReader in = new BufferedReader(new FileReader("example2.txt")); File phonetic = null; if (phoneticFileName != null) phonetic = new File(phoneticFileName); SpellDictionary dictionary = new SpellDictionaryHashMap(new File(dictFile), phonetic); spellCheck = new SpellChecker(dictionary); spellCheck.addSpellCheckListener(this); while (true) { String line = in.readLine(); if (line == null || line.length() == -1) break; spellCheck.checkSpelling(new StringWordTokenizer(line)); } } catch (Exception e) { e.printStackTrace(); } } public void spellingError(SpellCheckEvent event) { List suggestions = event.getSuggestions(); if (suggestions.size() > 0) { System.out.println("MISSPELT WORD: " + event.getInvalidWord()); for (Iterator suggestedWord = suggestions.iterator(); suggestedWord.hasNext();) { System.out.println("\tSuggested Word: " + suggestedWord.next()); } } else { System.out.println("MISSPELT WORD: " + event.getInvalidWord()); System.out.println("\tNo suggestions"); } } public static void main(String[] args) { System.out.println("Running spell check against DoubleMeta"); new SpellCheckExample2(null); System.out.println("\n\nRunning spell check against GenericTransformator"); new SpellCheckExample2("dict/phonet.en"); } } jazzy-0.5.2/src/com/swabunga/spell/swing/0000755000175000017500000000000010341056556020252 5ustar twernertwernerjazzy-0.5.2/src/com/swabunga/spell/swing/JSpellDialog.java0000644000175000017500000000506010253371640023423 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.swing; import com.swabunga.spell.event.SpellCheckEvent; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowEvent; import java.awt.event.WindowListener; /** Implementation of a spell check dialog. * * @author Jason Height (jheight@chariot.net.au) */ public class JSpellDialog extends JDialog implements ActionListener, WindowListener { private JSpellForm form = new JSpellForm(); private SpellCheckEvent event = null; public JSpellDialog(Frame owner, String title, boolean modal) { super(owner, title, modal); initialiseDialog(); } public JSpellDialog(Dialog owner, String title, boolean modal) { super(owner, title, modal); initialiseDialog(); } private void initialiseDialog() { getContentPane().add(form); form.addActionListener(this); addWindowListener(this); //setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE); pack(); } public void show(SpellCheckEvent e) { // System.out.println("Show"); this.event = e; form.setSpellEvent(e); show(); } public void actionPerformed(ActionEvent e) { hide(); } public void windowOpened(WindowEvent e) { } /** Cancel the event if the Dialog Close button is pressed*/ public void windowClosing(WindowEvent e) { if (event != null) event.cancel(); } public void windowClosed(WindowEvent e) { } public void windowIconified(WindowEvent e) { } public void windowDeiconified(WindowEvent e) { } public void windowActivated(WindowEvent e) { } public void windowDeactivated(WindowEvent e) { } } jazzy-0.5.2/src/com/swabunga/spell/swing/messages_fr.properties0000644000175000017500000000045507700476544024702 0ustar twernertwernerIGNORE=Ignorer IGNOREALL=Tout Ignorer ADD=Ajouter au dictionnaire REPLACE=Remplacer REPLACEALL=Tout remplacer CANCEL=Fermer SUGGESTIONS=Suggestions INVALIDWORD=Pas dans le dictionnaire COMPLETED=Vrification termine. ADDWORD_1=Ajouter ADDWORD_2=au dictionnaire? ADDWORD_3=Ajouter le mot? jazzy-0.5.2/src/com/swabunga/spell/swing/messages_de.properties0000644000175000017500000000042707700476544024662 0ustar twernertwernerIGNORE=Ignorieren IGNOREALL=Alles ignorieren ADD=Lernen REPLACE=Ersetzen REPLACEALL=Alles ersetzen CANCEL=Schlieen SUGGESTIONS=Vorschlag INVALIDWORD=Nicht gefunden COMPLETED=Rechtschreibung durchgefhrt. ADDWORD_1= ADDWORD_2=hinzufgen? ADDWORD_3=Wort hinzufgen? jazzy-0.5.2/src/com/swabunga/spell/swing/JSpellApplet.java0000644000175000017500000001046110253371640023452 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.swing; import com.swabunga.spell.engine.SpellDictionary; import com.swabunga.spell.engine.SpellDictionaryHashMap; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.*; import java.net.MalformedURLException; import java.net.URL; import java.util.zip.ZipInputStream; /** * @author aim4min * * To change this generated comment edit the template variable "typecomment": * Window>Preferences>Java>Templates. * To enable and disable the creation of type comments go to * Window>Preferences>Java>Code Generation. */ public class JSpellApplet extends JApplet { private static final String dictionaryFile = "dict/english.0.zip"; private SpellDictionary dictionary; JTextArea text = null; JButton spell = null; /** * @see java.awt.Component#paint(Graphics) */ public void paint(Graphics arg0) { super.paint(arg0); } /** * @see java.applet.Applet#init() */ public void init() { super.init(); try { URL resource = null; ZipInputStream zip = null; try { resource = new URL(getCodeBase().toExternalForm() + dictionaryFile); zip = new ZipInputStream(resource.openStream()); /* getCodeBase() throws a NullPointerException when run * outside the context of a browser */ } catch (NullPointerException e) { FileInputStream fin = new FileInputStream(dictionaryFile); zip = new ZipInputStream(fin); } zip.getNextEntry(); dictionary = new SpellDictionaryHashMap(new BufferedReader(new InputStreamReader(zip))); initGUI(); } catch (MalformedURLException e) { e.printStackTrace(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } private void initGUI() { Container frame = getContentPane(); GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); frame.setLayout(gridbag); c.anchor = GridBagConstraints.CENTER; c.fill = GridBagConstraints.BOTH; c.insets = new Insets(5, 5, 5, 5); c.weightx = 1.0; c.weighty = 1.0; text = new JTextArea("The quck brwn dog jmped over the fnce."); text.setLineWrap(true); text.setWrapStyleWord(true); addToFrame(frame, text, gridbag, c, 0, 0, 1, 1); GridBagConstraints spellcon = new GridBagConstraints(); spellcon.anchor = GridBagConstraints.NORTH; spellcon.insets = new Insets(5, 5, 5, 5); spell = new JButton("spell check"); final JTextComponentSpellChecker sc = new JTextComponentSpellChecker(dictionary); spell.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { Thread t = new Thread() { public void run() { try { sc.spellCheck(text); } catch (Exception ex) { ex.printStackTrace(); } } }; t.start(); } }); addToFrame(frame, spell, gridbag, spellcon, 1, 0, 1, 1); } // Helps build gridbaglayout. private void addToFrame(Container f, Component c, GridBagLayout gbl, GridBagConstraints gbc, int x, int y, int w, int h) { gbc.gridx = x; gbc.gridy = y; gbc.gridwidth = w; gbc.gridheight = h; gbl.setConstraints(c, gbc); f.add(c); } } jazzy-0.5.2/src/com/swabunga/spell/swing/autospell/0000755000175000017500000000000010341056556022262 5ustar twernertwernerjazzy-0.5.2/src/com/swabunga/spell/swing/autospell/AutoSpellCheckHandler.java0000644000175000017500000002125110253371640027266 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.swing.autospell; import java.awt.*; import java.util.*; import java.awt.event.*; import javax.swing.*; import javax.swing.text.*; import javax.swing.event.*; import com.swabunga.spell.event.*; import com.swabunga.spell.engine.*; /** * This class handles the actual autospelling by implementing some listeners * on the spellchecked JEditorPane and Document. * * @author Robert Gustavsson (robert@lindesign.se) * */ public class AutoSpellCheckHandler extends MouseAdapter implements DocumentListener, AutoSpellConstants{ private SpellChecker sCheck=null; private Configuration config = Configuration.getConfiguration(); private ResourceBundle messages=null; public AutoSpellCheckHandler(SpellChecker sc){ sCheck=sc; } public AutoSpellCheckHandler(SpellChecker sc, ResourceBundle rs){ this(sc); messages=rs; } public void addJEditorPane(JEditorPane pane){ StyledDocument doc=(StyledDocument)pane.getDocument(); markupSpelling(doc, 0, doc.getLength()-1); doc.addDocumentListener(this); pane.addMouseListener(this); } public void removeJEditorPane(JEditorPane pane){ Document doc=pane.getDocument(); pane.removeMouseListener(this); doc.removeDocumentListener(this); } private void markupSpelling(StyledDocument doc, int start, int end){ int wordStart=-1, wordEnd=-1; String word; DocumentWordTokenizer docTok; Segment seg=new Segment(); docTok=new DocumentWordTokenizer(doc); if(start>0){ docTok.posStartFullWordFrom(start); } while(docTok.hasMoreWords() && docTok.getCurrentWordPosition()<=end){ word=docTok.nextWord(); wordStart=docTok.getCurrentWordPosition(); // Mark non word parts (spaces) as correct if(wordEnd!=-1){ //System.out.println("Space:"+wordEnd+","+wordStart); markAsCorrect(doc, wordEnd, wordStart); } wordEnd=docTok.getCurrentWordEnd(); if(wordEnd>doc.getLength()) wordEnd=doc.getLength()-1; if(wordStart>=wordEnd) continue; //System.out.println("Word:"+wordStart+","+wordEnd); if(sCheck.isCorrect(word) || sCheck.isIgnored(word)){ markAsCorrect(doc, wordStart, wordEnd); }else{ markAsMisspelled(doc, wordStart, wordEnd); } } // Mark the rest (if any) as correct. if(wordEnd=start) doc.setCharacterAttributes(start, end-start, attr, true); } private void handleDocumentChange(DocumentEvent evt){ Element curElem, parElem; StyledDocument doc; int start, end; if(evt.getDocument() instanceof StyledDocument){ doc=(StyledDocument)evt.getDocument(); curElem=doc.getCharacterElement(evt.getOffset()); parElem=curElem.getParentElement(); if(parElem!=null){ start=parElem.getStartOffset(); end=parElem.getEndOffset(); }else{ start=curElem.getStartOffset(); end=curElem.getEndOffset(); } //System.out.println("curElem: "+curElem.getStartOffset()+", "+curElem.getEndOffset()); //System.out.println("parElem: "+parElem.getStartOffset()+", "+parElem.getEndOffset()); //System.out.println("change: "+start+", "+end); markupSpelling(doc,start, end); } } private void showSuggestionPopup(JEditorPane pane, Point p){ StyledDocument doc; JMenuItem item; AttributeSet attr; int pos = pane.viewToModel(p); DocumentWordTokenizer docTok; String word; java.util.List suggestions; JPopupMenu popup; ReplaceListener repList; if (pos >= 0) { doc=(StyledDocument)pane.getDocument(); attr=doc.getCharacterElement(pos).getAttributes(); if(attr.containsAttribute(wordMisspelled, wordMisspelledTrue)){ docTok=new DocumentWordTokenizer(doc); docTok.posStartFullWordFrom(pos); word=docTok.nextWord(); suggestions=sCheck.getSuggestions(word, config.getInteger(Configuration.SPELL_THRESHOLD)); popup=new JPopupMenu(); repList=new ReplaceListener(docTok); for(int i=0;i getLength()) end = getLength(); try { String text = getText(start, end - start); //System.out.println(text); checkoffset = text.indexOf(" "); if (checkoffset == -1) return; checkend = text.lastIndexOf(" "); if (checkend == -1) return; if (checkoffset == checkend) return; checkoffset += 1; checkingline = text.substring(checkoffset, checkend); if (checkingline == null) return; //System.out.println(":" + checkingline + ":"); checkoffset += start; checkend += start; setCharacterAttributes(checkoffset, checkend - checkoffset, normal, true); //System.out.println("" + checkoffset + ":" + (checkend - checkoffset)); StringTokenizer token = new StringTokenizer(checkingline, " "); //errors = new Vector(); while (token.hasMoreTokens()) { String tok = token.nextToken(); tok = clean(tok); if (tok.indexOf("\n") != -1) { String t1 = tok.substring(0, tok.indexOf("\n")); String t2 = tok.substring(tok.indexOf("\n") + 1); if (!dictionary.isCorrect(t1)) { setCharacterAttributes(checkingline.indexOf(t1) + checkoffset, t1.length(), errorstyle, false); } if (!dictionary.isCorrect(t2)) { setCharacterAttributes(checkingline.indexOf(t2) + checkoffset, t2.length(), errorstyle, false); } } else if (tok.indexOf("/") != -1) { String t1 = tok.substring(0, tok.indexOf("/")); String t2 = tok.substring(tok.indexOf("/") + 1); if (!dictionary.isCorrect(t1)) { setCharacterAttributes(checkingline.indexOf(t1) + checkoffset, t1.length(), errorstyle, false); } if (!dictionary.isCorrect(t2)) { setCharacterAttributes(checkingline.indexOf(t2) + checkoffset, t2.length(), errorstyle, false); } } else if (!dictionary.isCorrect(tok)) { System.out.println(tok + tok.length()); setCharacterAttributes(checkingline.indexOf(tok) + checkoffset, tok.length(), errorstyle, false); } } //setAttributes(a, errorstyle); } catch (BadLocationException f) { } } } public void remove(int offset, int len) throws BadLocationException { super.remove(offset, len); if (!checkspelling) return; if (dictionary != null) { int start = offset - 30; int end = offset + 30; if (start < 0) start = 0; if (end > getLength()) end = getLength(); try { String text = getText(start, end - start); //System.out.println(text); checkoffset = text.indexOf(" "); if (checkoffset == -1) return; checkend = text.lastIndexOf(" "); if (checkend == -1) return; if (checkoffset == checkend) return; checkoffset += 1; checkingline = text.substring(checkoffset, checkend); if (checkingline == null) return; //System.out.println(":" + checkingline + ":"); checkoffset += start; checkend += start; setCharacterAttributes(checkoffset, checkend - checkoffset, normal, true); //System.out.println("" + checkoffset + ":" + (checkend - checkoffset)); StringTokenizer token = new StringTokenizer(checkingline, " "); //errors = new Vector(); while (token.hasMoreTokens()) { String tok = token.nextToken(); tok = clean(tok); if (tok.indexOf("\n") != -1) { String t1 = tok.substring(0, tok.indexOf("\n")); String t2 = tok.substring(tok.indexOf("\n") + 1); if (!dictionary.isCorrect(t1)) { setCharacterAttributes(checkingline.indexOf(t1) + checkoffset, t1.length(), errorstyle, false); } if (!dictionary.isCorrect(t2)) { setCharacterAttributes(checkingline.indexOf(t2) + checkoffset, t2.length(), errorstyle, false); } } else if (!dictionary.isCorrect(tok)) { //System.out.println(tok + tok.length()); setCharacterAttributes(checkingline.indexOf(tok) + checkoffset, tok.length(), errorstyle, false); } } //setAttributes(a, errorstyle); } catch (BadLocationException f) { } } } public String clean(String word) { char[] chars = word.toCharArray(); //String wordd = ""; //if(chars.length > 0) int index = chars.length - 1; while (!Character.isLetterOrDigit(chars[index]) && index > 0) { //System.out.println("isocontrol " + word); index--; } word = word.substring(0, index + 1); if (word.endsWith(",") || word.endsWith(";") || word.endsWith(".") || word.endsWith("\n") || word.endsWith("?") || word.endsWith("!")) { return word.substring(0, word.length() - 1); } index = 0; chars = word.toCharArray(); while (!Character.isLetterOrDigit(chars[index]) && index < chars.length - 1) { //System.out.println("isocontrol " + word); index++; } word = word.substring(index); return word; } public void checkSplittedWords(String divider, String line) { } } jazzy-0.5.2/src/com/swabunga/spell/swing/messages_sv.properties0000644000175000017500000000032207631125224024701 0ustar twernertwernerIGNORE=Ignorera IGNOREALL=Ignorera alla ADD=Lgg till i ordlista REPLACE=Byt ut REPLACEALL=Byt ut alla CANCEL=Avbryt SUGGESTIONS=Frslag INVALIDWORD=Inte i ordlistan COMPLETED=Stavningskontroll klar. jazzy-0.5.2/src/com/swabunga/spell/swing/SpellEditorKit.java0000644000175000017500000002124210253371640024010 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.swing; import com.swabunga.spell.engine.SpellDictionary; import com.swabunga.spell.engine.SpellDictionaryHashMap; import com.swabunga.spell.engine.Word; import javax.swing.*; import javax.swing.plaf.TextUI; import javax.swing.text.*; import java.awt.*; import java.awt.event.*; import java.io.File; import java.util.List; /** * * use: * JTextPane pane = new JTextPane(); * pane.setEditorKit(new SpellEditorKit()); * * * * * * @author Stig Tanggaard * April 14, 2002 */ public class SpellEditorKit extends StyledEditorKit { // private static Color replyColor = null; // private static Cursor linkCursor; // private Cursor newCursor; protected static final Cursor linkCursor = Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); protected Cursor defaultCursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR); static SpellDictionary dictionary; public SpellEditorKit(File file) { super(); Object o; try { o = new SpellDictionaryHashMap(file); } catch (Exception f) { o = null; } dictionary = (SpellDictionary) o; } public void install(JEditorPane c) { LinkController adapt = new LinkController(); c.addMouseMotionListener(adapt); c.addMouseListener(adapt); super.install(c); //System.out.println("install stylededitorkit on editorpane"); defaultCursor = c.getCursor(); } public Document createDefaultDocument() { return new SpellCheckedDocument(dictionary); } public class LinkController extends MouseAdapter implements MouseMotionListener { private Element curElem = null; /** * If true, the current element (curElem) represents an image. */ private boolean curElemImage = false; private String href = null; /** This is used by viewToModel to avoid allocing a new array each * time. */ private Position.Bias[] bias = new Position.Bias[1]; /** * Current offset. */ private int curOffset; private int linkoffset = 0; /** * Called for a mouse click event. * If the component is read-only (ie a browser) then * the clicked event is used to drive an attempt to * follow the reference specified by a link. * * @param e the mouse event * @see MouseListener#mouseClicked */ public void mouseClicked(MouseEvent e) { if (e.isPopupTrigger()) return; JEditorPane editor = (JEditorPane) e.getSource(); if (editor.isEditable()) { Point pt = new Point(e.getX(), e.getY()); int pos = editor.viewToModel(pt); if (pos >= 0 && href != null) { //JPopupMenu menu = new JPopupMenu(); SpellCheckedDocument hdoc = (SpellCheckedDocument) editor.getDocument(); Element elem = hdoc.getCharacterElement(pos); try { final String word = hdoc.getText(elem.getStartOffset(), elem.getEndOffset() - elem.getStartOffset()); List list = dictionary.getSuggestions(word, 5); JPopupMenu popup = new JPopupMenu(); int index = 0; ReplaceListener listener = new ReplaceListener(elem.getStartOffset(), elem.getEndOffset() - elem.getStartOffset(), hdoc); while (index < list.size() && index < 5) { Word w = (Word) list.get(index); JMenuItem item = new JMenuItem(w.getWord()); item.setActionCommand(w.getWord()); item.addActionListener(listener); popup.add(item); index++; } JMenuItem item = new JMenuItem("Add word to wordlist"); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { dictionary.addWord(word); } }); popup.add(item); popup.show(editor, e.getX(), e.getY()); //System.out.println("" + elem.getStartOffset() + " count " + elem.getEndOffset()); } catch (BadLocationException f) { System.out.println("" + elem.getStartOffset() + " count " + elem.getElementCount()); } } } href = null; } // ignore the drags public void mouseDragged(MouseEvent e) { } // track the moving of the mouse. public void mouseMoved(MouseEvent e) { int pos = -1; // int offset = 0; JEditorPane editor = (JEditorPane) e.getSource(); //MailEditorKit kit = (MailEditorKit)editor.getEditorKit(); boolean adjustCursor = true; Cursor newCursor = defaultCursor; if (editor.isEditable()) { Point pt = new Point(e.getX(), e.getY()); pos = editor.getUI().viewToModel(editor, pt, bias); if (bias[0] == Position.Bias.Backward && pos > 0) { pos--; } if (pos >= 0 && (editor.getDocument() instanceof SpellCheckedDocument)) { SpellCheckedDocument hdoc = (SpellCheckedDocument) editor.getDocument(); Element elem = hdoc.getCharacterElement(pos); if (!doesElementContainLocation(editor, elem, pos, e.getX(), e.getY())) { elem = null; } if (curElem != elem || curElemImage) { // Element lastElem = curElem; curElem = elem; //String href = null; curElemImage = false; if (elem != null) { AttributeSet a = elem.getAttributes(); //System.out.println( // a.getAttribute(StyleConstants.NameAttribute)); if (a.getAttribute(StyleConstants.NameAttribute) == SpellCheckedDocument.ERROR_STYLE) { newCursor = linkCursor; linkoffset = elem.getStartOffset(); //System.out.println("test + " + pos); try { href = editor.getDocument().getText(elem.getStartOffset(), elem.getEndOffset() - elem.getStartOffset()); } catch (BadLocationException f) { } // offset = elem.getStartOffset(); } else { href = null; } } } else { adjustCursor = false; } curOffset = pos; } } //adjustCursor && if (adjustCursor && editor.getCursor() != newCursor) { editor.setCursor(newCursor); } } /** * Returns true if the View representing e contains * the location x, y. offset * gives the offset into the Document to check for. */ private boolean doesElementContainLocation(JEditorPane editor, Element e, int offset, int x, int y) { if (e != null && offset > 0 && e.getStartOffset() == offset) { try { TextUI ui = editor.getUI(); Shape s1 = ui.modelToView(editor, offset, Position.Bias.Forward); Rectangle r1 = (s1 instanceof Rectangle) ? (Rectangle) s1 : s1.getBounds(); Shape s2 = ui.modelToView(editor, e.getEndOffset(), Position.Bias.Backward); Rectangle r2 = (s2 instanceof Rectangle) ? (Rectangle) s2 : s2.getBounds(); r1.add(r2); return r1.contains(x, y); } catch (BadLocationException ble) { } } return true; } } class ReplaceListener implements ActionListener { int offset; int length; Document doc; public ReplaceListener(int offset, int length, Document doc) { this.offset = offset; this.length = length; this.doc = doc; } public void actionPerformed(ActionEvent e) { try { doc.remove(offset, length); doc.insertString(offset, e.getActionCommand(), null); } catch (BadLocationException f) { } } } } jazzy-0.5.2/src/com/swabunga/spell/swing/JSpellForm.java0000644000175000017500000002320010253371640023123 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * put your module comment here * formatted with JxBeauty (c) johann.langhofer@nextra.at */ /* * Changes 11 Jan 2003 Anthony Roy: * * 1) Changed checkText from a JTextArea to a JTextField (lines 51 and 115) * 2) Altered the ADD_CMD action (Line 196). Now adds the misspelled word to the dictionary unless * a new word is typed which does not match the current suggestion. A confirm dialog is shown. */ package com.swabunga.spell.swing; import com.swabunga.spell.engine.Word; import com.swabunga.spell.event.SpellCheckEvent; import javax.swing.*; import javax.swing.event.EventListenerList; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Locale; import java.util.ResourceBundle; /** Implementation of a spell check form. *

This needs to layed out correctly but for the most part it works.

* * @author Jason Height (jheight@chariot.net.au) */ public class JSpellForm extends JPanel implements ActionListener, ListSelectionListener { /** The Ignore button click action command*/ public static final String IGNORE_CMD = "IGNORE"; /** The Ignore All button click action command*/ public static final String IGNOREALL_CMD = "IGNOREALL"; /** The Add button click action command*/ public static final String ADD_CMD = "ADD"; /** The Replace button click action command*/ public static final String REPLACE_CMD = "REPLACE"; /** The Replace All button click action command*/ public static final String REPLACEALL_CMD = "REPLACEALL"; /** The Cancel button click action command*/ public static final String CANCEL_CMD = "CANCEL"; /** The resource for the Suggestions label*/ private static final String SUGGESTIONS_RES = "SUGGESTIONS"; private static final String INVALIDWORD_RES = "INVALIDWORD"; /** Add word confirm*/ public static final String ADDWORD_1 = "ADDWORD_1"; public static final String ADDWORD_2 = "ADDWORD_2"; public static final String ADDWORD_3 = "ADDWORD_3"; private JLabel wrongWordLabel; /* Accessible GUI Components */ protected JList suggestList; protected JTextField checkText; /* The current spell check event */ protected SpellCheckEvent spellEvent; /** The listener list (holds actionlisteners) */ protected EventListenerList listenerList = new EventListenerList(); protected ResourceBundle messages; /** Panel constructor */ public JSpellForm() { messages = ResourceBundle.getBundle("com.swabunga.spell.swing.messages", Locale.getDefault()); initialiseGUI(); } /** Helper method to create a JButton with a command, a text label and a listener*/ private static final JButton createButton(String command, String text, ActionListener listener) { JButton btn = new JButton(text); btn.setActionCommand(command); btn.addActionListener(listener); return btn; } /** Creates the buttons on the left hand side of the panel*/ protected JPanel makeEastPanel() { JPanel jPanel1 = new JPanel(); BoxLayout layout = new BoxLayout(jPanel1, BoxLayout.Y_AXIS); jPanel1.setLayout(layout); JButton ignoreBtn = createButton(IGNORE_CMD, messages.getString(IGNORE_CMD), this); ignoreBtn.setMaximumSize(new Dimension(Short.MAX_VALUE, Short.MAX_VALUE)); jPanel1.add(ignoreBtn); JButton ignoreAllBtn = createButton(IGNOREALL_CMD, messages.getString(IGNOREALL_CMD), this); ignoreAllBtn.setMaximumSize(new Dimension(Short.MAX_VALUE, Short.MAX_VALUE)); jPanel1.add(ignoreAllBtn); JButton addBtn = createButton(ADD_CMD, messages.getString(ADD_CMD), this); addBtn.setMaximumSize(new Dimension(Short.MAX_VALUE, Short.MAX_VALUE)); jPanel1.add(addBtn); JButton changeBtn = createButton(REPLACE_CMD, messages.getString(REPLACE_CMD), this); changeBtn.setMaximumSize(new Dimension(Short.MAX_VALUE, Short.MAX_VALUE)); jPanel1.add(changeBtn); JButton changeAllBtn = createButton(REPLACEALL_CMD, messages.getString(REPLACEALL_CMD), this); changeAllBtn.setMaximumSize(new Dimension(Short.MAX_VALUE, Short.MAX_VALUE)); jPanel1.add(changeAllBtn); JButton cancelBtn = createButton(CANCEL_CMD, messages.getString(CANCEL_CMD), this); cancelBtn.setMaximumSize(new Dimension(Short.MAX_VALUE, Short.MAX_VALUE)); jPanel1.add(cancelBtn); return jPanel1; } protected JPanel makeCentrePanel() { JPanel jPanel2 = new JPanel(); jPanel2.setLayout(new BoxLayout(jPanel2, BoxLayout.Y_AXIS)); JPanel jPanel3 = new JPanel(); JLabel lbl1 = new JLabel(messages.getString(INVALIDWORD_RES)); wrongWordLabel = new JLabel(""); wrongWordLabel.setForeground(Color.red); //Changed Color.RED to Color.red for 1.3 compatibility. jPanel3.add(lbl1); jPanel3.add(wrongWordLabel); jPanel2.add(jPanel3); checkText = new JTextField(); jPanel2.add(checkText); JLabel lbl2 = new JLabel(messages.getString(SUGGESTIONS_RES)); jPanel2.add(lbl2); suggestList = new JList(); suggestList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); jPanel2.add(new JScrollPane(suggestList)); suggestList.addListSelectionListener(this); return jPanel2; } /** Called by the constructor to initialise the GUI*/ protected void initialiseGUI() { setLayout(new BorderLayout()); this.add(makeEastPanel(), BorderLayout.EAST); this.add(makeCentrePanel(), BorderLayout.CENTER); } /** Register an action listener */ public void addActionListener(ActionListener l) { listenerList.add(ActionListener.class, l); } /** Deregister an action listener*/ public void removeActionListener(ActionListener l) { listenerList.remove(ActionListener.class, l); } protected void fireActionEvent(ActionEvent e) { // Guaranteed to return a non-null array Object[] listeners = listenerList.getListenerList(); // Process the listeners last to first, notifying // those that are interested in this event for (int i = listeners.length - 2; i >= 0; i -= 2) { if (listeners[i] == ActionListener.class) { ((ActionListener) listeners[i + 1]).actionPerformed(e); } } } /** Sets the current spell check event that is being shown to the user*/ public void setSpellEvent(SpellCheckEvent event) { spellEvent = event; DefaultListModel m = new DefaultListModel(); java.util.List suggestions = event.getSuggestions(); for (int i = 0; i < suggestions.size(); i++) { m.addElement(suggestions.get(i)); } suggestList.setModel(m); wrongWordLabel.setText(event.getInvalidWord()); if (m.size() > 0) { suggestList.setSelectedIndex(0); checkText.setText(((Word) m.get(0)).getWord()); } else { checkText.setText(event.getInvalidWord()); } } /** Fired when a value in the list is selected*/ public void valueChanged(ListSelectionEvent e) { if (!e.getValueIsAdjusting()) { Object selectedValue = suggestList.getSelectedValue(); if (selectedValue != null) checkText.setText(selectedValue.toString()); } } /** Fired when a button is selected */ public void actionPerformed(ActionEvent e) { if (IGNORE_CMD.equals(e.getActionCommand())) { spellEvent.ignoreWord(false); } else if (IGNOREALL_CMD.equals(e.getActionCommand())) { spellEvent.ignoreWord(true); } else if (REPLACE_CMD.equals(e.getActionCommand())) { spellEvent.replaceWord(checkText.getText(), false); } else if (REPLACEALL_CMD.equals(e.getActionCommand())) { spellEvent.replaceWord(checkText.getText(), true); } else if (ADD_CMD.equals(e.getActionCommand())) { String inField = checkText.getText(); Object selObj = suggestList.getSelectedValue(); String selected = (selObj == null ? "" : selObj.toString()); String addString = (inField.equals(selected) ? spellEvent.getInvalidWord() : inField); int n = JOptionPane.showConfirmDialog(this, messages.getString(ADDWORD_1) + " '" + addString + "' " + messages.getString(ADDWORD_2), messages.getString(ADDWORD_3), JOptionPane.YES_NO_OPTION); if (n == JOptionPane.YES_OPTION) { spellEvent.addToDictionary(addString); } else { return; } } else if (CANCEL_CMD.equals(e.getActionCommand())) { spellEvent.cancel(); } fireActionEvent(e); } public static void main(String[] args) { try { JSpellForm pane = new JSpellForm(); JFrame frm = new JFrame("Spelling"); frm.getContentPane().add(pane); frm.setSize(300, 300); frm.setVisible(true); frm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } catch (Exception ex) { ex.printStackTrace(); } } } jazzy-0.5.2/src/com/swabunga/spell/engine/0000755000175000017500000000000010341056556020370 5ustar twernertwernerjazzy-0.5.2/src/com/swabunga/spell/engine/DoubleMeta.java0000644000175000017500000006651510255105020023252 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.engine; /** * A phonetic encoding algorithm that takes an English word and computes a phonetic version of it. This * allows for phonetic matches in a spell checker. This class is a port of the C++ DoubleMetaphone() class, * which was intended to return two possible phonetic translations for certain words, although the Java version * only seems to be concerned with one, making the "double" part erroneous. *
* source code for the original C++ can be found * here: http://aspell.sourceforge.net/metaphone/ * DoubleMetaphone does some processing, such as uppercasing, on the input string first to normalize it. Then, to * create the key, the function traverses the input string in a while loop, sending successive characters into a giant * switch statement. Before determining the appropriate pronunciation, the algorithm considers the context * surrounding each character within the input string. *

* Things that were changed: *
The alternate flag could be set to true but was never checked so why bother with it. REMOVED *
Why was this class serializable? *
The primary, in, length and last variables could be initialized and local to the * process method and references passed around the appropriate methods. As such there are * no class variables and this class becomes firstly threadsafe and secondly could be static final. *
The function call SlavoGermaic was called repeatedly in the process function, it is now only called once. * */ public class DoubleMeta implements Transformator { /** * The replace list is used in the getSuggestions method. * All of the letters in the misspelled word are replaced with the characters from * this list to try and generate more suggestions, which implies l*n tries, * if l is the size of the string, and n is the size of this list. * * In addition to that, each of these letters is added to the misspelled word. */ private static char[] replaceList = {'A', 'B', 'X', 'S', 'K', 'J', 'T', 'F', 'H', 'L', 'M', 'N', 'P', 'R', '0'}; private static final String[] myList = {"GN", "KN", "PN", "WR", "PS", ""}; private static final String[] list1 = {"ACH", ""}; private static final String[] list2 = {"BACHER", "MACHER", ""}; private static final String[] list3 = {"CAESAR", ""}; private static final String[] list4 = {"CHIA", ""}; private static final String[] list5 = {"CH", ""}; private static final String[] list6 = {"CHAE", ""}; private static final String[] list7 = {"HARAC", "HARIS", ""}; private static final String[] list8 = {"HOR", "HYM", "HIA", "HEM", ""}; private static final String[] list9 = {"CHORE", ""}; private static final String[] list10 = {"VAN ", "VON ", ""}; private static final String[] list11 = {"SCH", ""}; private static final String[] list12 = {"ORCHES", "ARCHIT", "ORCHID", ""}; private static final String[] list13 = {"T", "S", ""}; private static final String[] list14 = {"A", "O", "U", "E", ""}; private static final String[] list15 = {"L", "R", "N", "M", "B", "H", "F", "V", "W", " ", ""}; private static final String[] list16 = {"MC", ""}; private static final String[] list17 = {"CZ", ""}; private static final String[] list18 = {"WICZ", ""}; private static final String[] list19 = {"CIA", ""}; private static final String[] list20 = {"CC", ""}; private static final String[] list21 = {"I", "E", "H", ""}; private static final String[] list22 = {"HU", ""}; private static final String[] list23 = {"UCCEE", "UCCES", ""}; private static final String[] list24 = {"CK", "CG", "CQ", ""}; private static final String[] list25 = {"CI", "CE", "CY", ""}; // DMV: used by the orininal code which returned two phonetic code, but not the current code // private static final String[] list26 = { // "CIO", "CIE", "CIA", "" // }; private static final String[] list27 = {" C", " Q", " G", ""}; private static final String[] list28 = {"C", "K", "Q", ""}; private static final String[] list29 = {"CE", "CI", ""}; private static final String[] list30 = {"DG", ""}; private static final String[] list31 = {"I", "E", "Y", ""}; private static final String[] list32 = {"DT", "DD", ""}; private static final String[] list33 = {"B", "H", "D", ""}; private static final String[] list34 = {"B", "H", "D", ""}; private static final String[] list35 = {"B", "H", ""}; private static final String[] list36 = {"C", "G", "L", "R", "T", ""}; private static final String[] list37 = {"EY", ""}; private static final String[] list38 = {"LI", ""}; private static final String[] list39 = {"ES", "EP", "EB", "EL", "EY", "IB", "IL", "IN", "IE", "EI", "ER", ""}; private static final String[] list40 = {"ER", ""}; private static final String[] list41 = {"DANGER", "RANGER", "MANGER", ""}; private static final String[] list42 = {"E", "I", ""}; private static final String[] list43 = {"RGY", "OGY", ""}; private static final String[] list44 = {"E", "I", "Y", ""}; private static final String[] list45 = {"AGGI", "OGGI", ""}; private static final String[] list46 = {"VAN ", "VON ", ""}; private static final String[] list47 = {"SCH", ""}; private static final String[] list48 = {"ET", ""}; // DMV: used by the orininal code which returned two phonetic code, but not the current code // private static final String[] list49 = { // "IER ", "" // }; private static final String[] list50 = {"JOSE", ""}; private static final String[] list51 = {"SAN ", ""}; private static final String[] list52 = {"SAN ", ""}; private static final String[] list53 = {"JOSE", ""}; private static final String[] list54 = {"L", "T", "K", "S", "N", "M", "B", "Z", ""}; private static final String[] list55 = {"S", "K", "L", ""}; private static final String[] list56 = {"ILLO", "ILLA", "ALLE", ""}; private static final String[] list57 = {"AS", "OS", ""}; private static final String[] list58 = {"A", "O", ""}; private static final String[] list59 = {"ALLE", ""}; private static final String[] list60 = {"UMB", ""}; private static final String[] list61 = {"ER", ""}; private static final String[] list62 = {"P", "B", ""}; private static final String[] list63 = {"IE", ""}; private static final String[] list64 = {"ME", "MA", ""}; private static final String[] list65 = {"ISL", "YSL", ""}; private static final String[] list66 = {"SUGAR", ""}; private static final String[] list67 = {"SH", ""}; private static final String[] list68 = {"HEIM", "HOEK", "HOLM", "HOLZ", ""}; private static final String[] list69 = {"SIO", "SIA", ""}; private static final String[] list70 = {"SIAN", ""}; private static final String[] list71 = {"M", "N", "L", "W", ""}; private static final String[] list72 = {"Z", ""}; private static final String[] list73 = {"Z", ""}; private static final String[] list74 = {"SC", ""}; private static final String[] list75 = {"OO", "ER", "EN", "UY", "ED", "EM", ""}; private static final String[] list76 = {"ER", "EN", ""}; private static final String[] list77 = {"I", "E", "Y", ""}; private static final String[] list78 = {"AI", "OI", ""}; private static final String[] list79 = {"S", "Z", ""}; private static final String[] list80 = {"TION", ""}; private static final String[] list81 = {"TIA", "TCH", ""}; private static final String[] list82 = {"TH", ""}; private static final String[] list83 = {"TTH", ""}; private static final String[] list84 = {"OM", "AM", ""}; private static final String[] list85 = {"VAN ", "VON ", ""}; private static final String[] list86 = {"SCH", ""}; private static final String[] list87 = {"T", "D", ""}; private static final String[] list88 = {"WR", ""}; private static final String[] list89 = {"WH", ""}; private static final String[] list90 = {"EWSKI", "EWSKY", "OWSKI", "OWSKY", ""}; private static final String[] list91 = {"SCH", ""}; private static final String[] list92 = {"WICZ", "WITZ", ""}; private static final String[] list93 = {"IAU", "EAU", ""}; private static final String[] list94 = {"AU", "OU", ""}; private static final String[] list95 = {"C", "X", ""}; // DMV: used by the orininal code which returned two phonetic code, but not the current code // private static final String[] list96 = { // "ZO", "ZI", "ZA", "" // }; /** * put your documentation comment here * @return */ private final static boolean SlavoGermanic(String in) { if ((in.indexOf("W") > -1) || (in.indexOf("K") > -1) || (in.indexOf("CZ") > -1) || (in.indexOf("WITZ") > -1)) return true; return false; } /** * put your documentation comment here * @param main */ private final static void MetaphAdd(StringBuffer primary, String main) { if (main != null) { primary.append(main); } } private final static void MetaphAdd(StringBuffer primary, char main) { primary.append(main); } /** * put your documentation comment here * @param at * @return */ private final static boolean isVowel(String in, int at, int length) { if ((at < 0) || (at >= length)) return false; char it = in.charAt(at); if ((it == 'A') || (it == 'E') || (it == 'I') || (it == 'O') || (it == 'U') || (it == 'Y')) return true; return false; } /** * put your documentation comment here * @param string * @param start * @param length * @param list * @return */ private final static boolean stringAt(String string, int start, int length, String[] list) { if ((start < 0) || (start >= string.length()) || list.length == 0) return false; String substr = string.substring(start, start + length); for (int i = 0; i < list.length; i++) { if (list[i].equals(substr)) return true; } return false; } /** * Take the given word, and return the best phonetic hash for it. * Vowels are minimized as much as possible, and consenants * that have similiar sounds are converted to the same consenant * for example, 'v' and 'f' are both converted to 'f' * @param word the texte to transform * @return the result of the phonetic transformation */ public final String transform(String word) { StringBuffer primary = new StringBuffer(word.length() + 5); String in = word.toUpperCase() + " "; int current = 0; int length = in.length(); if (length < 1) return ""; int last = length - 1; boolean isSlavoGermaic = SlavoGermanic(in); if (stringAt(in, 0, 2, myList)) current += 1; if (in.charAt(0) == 'X') { MetaphAdd(primary, 'S'); current += 1; } while (current < length) { switch (in.charAt(current)) { case 'A': case 'E': case 'I': case 'O': case 'U': case 'Y': if (current == 0) MetaphAdd(primary, 'A'); current += 1; break; case 'B': MetaphAdd(primary, 'P'); if (in.charAt(current + 1) == 'B') current += 2; else current += 1; break; case '\u00C7': MetaphAdd(primary, 'S'); current += 1; break; case 'C': if ((current > 1) && !isVowel(in, current - 2, length) && stringAt(in, (current - 1), 3, list1) && (in.charAt(current + 2) != 'I') && (in.charAt(current + 2) != 'E') || stringAt(in, (current - 2), 6, list2)) { MetaphAdd(primary, 'K'); current += 2; break; } if ((current == 0) && stringAt(in, current, 6, list3)) { MetaphAdd(primary, 'S'); current += 2; break; } if (stringAt(in, current, 4, list4)) { MetaphAdd(primary, 'K'); current += 2; break; } if (stringAt(in, current, 2, list5)) { if ((current > 0) && stringAt(in, current, 4, list6)) { MetaphAdd(primary, 'K'); current += 2; break; } if ((current == 0) && stringAt(in, (current + 1), 5, list7) || stringAt(in, current + 1, 3, list8) && !stringAt(in, 0, 5, list9)) { MetaphAdd(primary, 'K'); current += 2; break; } if (stringAt(in, 0, 4, list10) || stringAt(in, 0, 3, list11) || stringAt(in, current - 2, 6, list12) || stringAt(in, current + 2, 1, list13) || (stringAt(in, current - 1, 1, list14) || (current == 0)) && stringAt(in, current + 2, 1, list15)) { MetaphAdd(primary, 'K'); } else { if (current > 0) { if (stringAt(in, 0, 2, list16)) MetaphAdd(primary, 'K'); else MetaphAdd(primary, 'X'); } else { MetaphAdd(primary, 'X'); } } current += 2; break; } if (stringAt(in, current, 2, list17) && !stringAt(in, current, 4, list18)) { MetaphAdd(primary, 'S'); current += 2; break; } if (stringAt(in, current, 2, list19)) { MetaphAdd(primary, 'X'); current += 2; break; } if (stringAt(in, current, 2, list20) && !((current == 1) && in.charAt(0) == 'M')) { if (stringAt(in, current + 2, 1, list21) && !stringAt(in, current + 2, 2, list22)) { if (((current == 1) && (in.charAt(current - 1) == 'A')) || stringAt(in, (current - 1), 5, list23)) MetaphAdd(primary, "KS"); else MetaphAdd(primary, 'X'); current += 3; break; } else { MetaphAdd(primary, 'K'); current += 2; break; } } if (stringAt(in, current, 2, list24)) { MetaphAdd(primary, 'K'); current += 2; break; } else if (stringAt(in, current, 2, list25)) { MetaphAdd(primary, 'S'); current += 2; break; } MetaphAdd(primary, 'K'); if (stringAt(in, current + 1, 2, list27)) current += 3; else if (stringAt(in, current + 1, 1, list28) && !stringAt(in, current + 1, 2, list29)) current += 2; else current += 1; break; case 'D': if (stringAt(in, current, 2, list30)) { if (stringAt(in, current + 2, 1, list31)) { MetaphAdd(primary, 'J'); current += 3; break; } else { MetaphAdd(primary, "TK"); current += 2; break; } } MetaphAdd(primary, 'T'); if (stringAt(in, current, 2, list32)) { current += 2; } else { current += 1; } break; case 'F': if (in.charAt(current + 1) == 'F') current += 2; else current += 1; MetaphAdd(primary, 'F'); break; case 'G': if (in.charAt(current + 1) == 'H') { if ((current > 0) && !isVowel(in, current - 1, length)) { MetaphAdd(primary, 'K'); current += 2; break; } if (current < 3) { if (current == 0) { if (in.charAt(current + 2) == 'I') MetaphAdd(primary, 'J'); else MetaphAdd(primary, 'K'); current += 2; break; } } if ((current > 1) && stringAt(in, current - 2, 1, list33) || ((current > 2) && stringAt(in, current - 3, 1, list34)) || ((current > 3) && stringAt(in, current - 4, 1, list35))) { current += 2; break; } else { if ((current > 2) && (in.charAt(current - 1) == 'U') && stringAt(in, current - 3, 1, list36)) { MetaphAdd(primary, 'F'); } else { if ((current > 0) && (in.charAt(current - 1) != 'I')) MetaphAdd(primary, 'K'); } current += 2; break; } } if (in.charAt(current + 1) == 'N') { if ((current == 1) && isVowel(in, 0, length) && !isSlavoGermaic) { MetaphAdd(primary, "KN"); } else { if (!stringAt(in, current + 2, 2, list37) && (in.charAt(current + 1) != 'Y') && !isSlavoGermaic) { MetaphAdd(primary, "N"); } else { MetaphAdd(primary, "KN"); } } current += 2; break; } if (stringAt(in, current + 1, 2, list38) && !isSlavoGermaic) { MetaphAdd(primary, "KL"); current += 2; break; } if ((current == 0) && ((in.charAt(current + 1) == 'Y') || stringAt(in, current + 1, 2, list39))) { MetaphAdd(primary, 'K'); current += 2; break; } if ((stringAt(in, current + 1, 2, list40) || (in.charAt(current + 1) == 'Y')) && !stringAt(in, 0, 6, list41) && !stringAt(in, current - 1, 1, list42) && !stringAt(in, current - 1, 3, list43)) { MetaphAdd(primary, 'K'); current += 2; break; } if (stringAt(in, current + 1, 1, list44) || stringAt(in, current - 1, 4, list45)) { if (stringAt(in, 0, 4, list46) || stringAt(in, 0, 3, list47) || stringAt(in, current + 1, 2, list48)) { MetaphAdd(primary, 'K'); } else { MetaphAdd(primary, 'J'); } current += 2; break; } if (in.charAt(current + 1) == 'G') current += 2; else current += 1; MetaphAdd(primary, 'K'); break; case 'H': if (((current == 0) || isVowel(in, current - 1, length)) && isVowel(in, current + 1, length)) { MetaphAdd(primary, 'H'); current += 2; } else { current += 1; } break; case 'J': if (stringAt(in, current, 4, list50) || stringAt(in, 0, 4, list51)) { if ((current == 0) && (in.charAt(current + 4) == ' ') || stringAt(in, 0, 4, list52)) { MetaphAdd(primary, 'H'); } else { MetaphAdd(primary, 'J'); } current += 1; break; } if ((current == 0) && !stringAt(in, current, 4, list53)) { MetaphAdd(primary, 'J'); } else { if (isVowel(in, current - 1, length) && !isSlavoGermaic && ((in.charAt(current + 1) == 'A') || in.charAt(current + 1) == 'O')) { MetaphAdd(primary, 'J'); } else { if (current == last) { MetaphAdd(primary, 'J'); } else { if (!stringAt(in, current + 1, 1, list54) && !stringAt(in, current - 1, 1, list55)) { MetaphAdd(primary, 'J'); } } } } if (in.charAt(current + 1) == 'J') current += 2; else current += 1; break; case 'K': if (in.charAt(current + 1) == 'K') current += 2; else current += 1; MetaphAdd(primary, 'K'); break; case 'L': if (in.charAt(current + 1) == 'L') { if (((current == (length - 3)) && stringAt(in, current - 1, 4, list56)) || ((stringAt(in, last - 1, 2, list57) || stringAt(in, last, 1, list58)) && stringAt(in, current - 1, 4, list59))) { MetaphAdd(primary, 'L'); current += 2; break; } current += 2; } else current += 1; MetaphAdd(primary, 'L'); break; case 'M': if ((stringAt(in, current - 1, 3, list60) && (((current + 1) == last) || stringAt(in, current + 2, 2, list61))) || (in.charAt(current + 1) == 'M')) current += 2; else current += 1; MetaphAdd(primary, 'M'); break; case 'N': if (in.charAt(current + 1) == 'N') current += 2; else current += 1; MetaphAdd(primary, 'N'); break; case '\u00D1': current += 1; MetaphAdd(primary, 'N'); break; case 'P': if (in.charAt(current + 1) == 'N') { MetaphAdd(primary, 'F'); current += 2; break; } if (stringAt(in, current + 1, 1, list62)) current += 2; else current += 1; MetaphAdd(primary, 'P'); break; case 'Q': if (in.charAt(current + 1) == 'Q') current += 2; else current += 1; MetaphAdd(primary, 'K'); break; case 'R': if ((current == last) && !isSlavoGermaic && stringAt(in, current - 2, 2, list63) && !stringAt(in, current - 4, 2, list64)) { // MetaphAdd(primary, ""); } else MetaphAdd(primary, 'R'); if (in.charAt(current + 1) == 'R') current += 2; else current += 1; break; case 'S': if (stringAt(in, current - 1, 3, list65)) { current += 1; break; } if ((current == 0) && stringAt(in, current, 5, list66)) { MetaphAdd(primary, 'X'); current += 1; break; } if (stringAt(in, current, 2, list67)) { if (stringAt(in, current + 1, 4, list68)) MetaphAdd(primary, 'S'); else MetaphAdd(primary, 'X'); current += 2; break; } if (stringAt(in, current, 3, list69) || stringAt(in, current, 4, list70)) { MetaphAdd(primary, 'S'); current += 3; break; } if (((current == 0) && stringAt(in, current + 1, 1, list71)) || stringAt(in, current + 1, 1, list72)) { MetaphAdd(primary, 'S'); if (stringAt(in, current + 1, 1, list73)) current += 2; else current += 1; break; } if (stringAt(in, current, 2, list74)) { if (in.charAt(current + 2) == 'H') if (stringAt(in, current + 3, 2, list75)) { if (stringAt(in, current + 3, 2, list76)) { MetaphAdd(primary, "X"); } else { MetaphAdd(primary, "SK"); } current += 3; break; } else { MetaphAdd(primary, 'X'); current += 3; break; } if (stringAt(in, current + 2, 1, list77)) { MetaphAdd(primary, 'S'); current += 3; break; } MetaphAdd(primary, "SK"); current += 3; break; } if ((current == last) && stringAt(in, current - 2, 2, list78)) { //MetaphAdd(primary, ""); } else MetaphAdd(primary, 'S'); if (stringAt(in, current + 1, 1, list79)) current += 2; else current += 1; break; case 'T': if (stringAt(in, current, 4, list80)) { MetaphAdd(primary, 'X'); current += 3; break; } if (stringAt(in, current, 3, list81)) { MetaphAdd(primary, 'X'); current += 3; break; } if (stringAt(in, current, 2, list82) || stringAt(in, current, 3, list83)) { if (stringAt(in, (current + 2), 2, list84) || stringAt(in, 0, 4, list85) || stringAt(in, 0, 3, list86)) { MetaphAdd(primary, 'T'); } else { MetaphAdd(primary, '0'); } current += 2; break; } if (stringAt(in, current + 1, 1, list87)) { current += 2; } else current += 1; MetaphAdd(primary, 'T'); break; case 'V': if (in.charAt(current + 1) == 'V') current += 2; else current += 1; MetaphAdd(primary, 'F'); break; case 'W': if (stringAt(in, current, 2, list88)) { MetaphAdd(primary, 'R'); current += 2; break; } if ((current == 0) && (isVowel(in, current + 1, length) || stringAt(in, current, 2, list89))) { MetaphAdd(primary, 'A'); } if (((current == last) && isVowel(in, current - 1, length)) || stringAt(in, current - 1, 5, list90) || stringAt(in, 0, 3, list91)) { MetaphAdd(primary, 'F'); current += 1; break; } if (stringAt(in, current, 4, list92)) { MetaphAdd(primary, "TS"); current += 4; break; } current += 1; break; case 'X': if (!((current == last) && (stringAt(in, current - 3, 3, list93) || stringAt(in, current - 2, 2, list94)))) MetaphAdd(primary, "KS"); if (stringAt(in, current + 1, 1, list95)) current += 2; else current += 1; break; case 'Z': if (in.charAt(current + 1) == 'H') { MetaphAdd(primary, 'J'); current += 2; break; } else { MetaphAdd(primary, 'S'); } if (in.charAt(current + 1) == 'Z') current += 2; else current += 1; break; default: current += 1; } } return primary.toString(); } /** * @see com.swabunga.spell.engine.Transformator#getReplaceList() */ public char[] getReplaceList() { return replaceList; } } jazzy-0.5.2/src/com/swabunga/spell/engine/Transformator.java0000644000175000017500000000433310255105020024060 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.engine; /** * An interface for all Transformators - which take a dictionary word and converts into its * phonetic hash. These phonetic hashes are useful for determining what other words are * similar to it, and then list those words as suggestions. * * @author Robert Gustavsson (robert@lindesign.se) */ public interface Transformator { /** * Take the given word, and return the best phonetic hash for it. * @param word the word to transform * @return the phonetic transformation of the word */ public String transform(String word); /** * gets the list of characters that should be swapped in to the misspelled word * in order to try to find more suggestions. * In general, this list represents all of the unique phonetic characters * for this Transformator. *

* The replace list is used in the getSuggestions method. * All of the letters in the misspelled word are replaced with the characters from * this list to try and generate more suggestions, which implies l*n tries, * if l is the size of the string, and n is the size of this list. *

* In addition to that, each of these letters is added to the misspelled word. *

* @return char[] misspelled words should try replacing with these characters to get more suggestions */ public char[] getReplaceList(); } jazzy-0.5.2/src/com/swabunga/spell/engine/GenericSpellDictionary.java0000644000175000017500000001435010255105020025621 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.engine; import java.io.*; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Vector; /** * The SpellDictionary class holds the instance of the dictionary. *

* This class is thread safe. Derived classes should ensure that this preserved. *

*

* There are many open source dictionary files. For just a few see: * http://wordlist.sourceforge.net/ *

*

* This dictionary class reads words one per line. Make sure that your word list * is formatted in this way (most are). *

*/ public class GenericSpellDictionary extends SpellDictionaryASpell { //tech_monkey: the alphabet / replace list stuff has been moved into the Transformator classes, //since they are so closely tied to how the phonetic transformations are done. // /** // * This replace list is used if no phonetic file is supplied or it doesn't // * contain the alphabet. // */ // protected static final char[] englishAlphabet = /** A field indicating the initial hash map capacity (16KB) for the main * dictionary hash map. Interested to see what the performance of a * smaller initial capacity is like. */ private final static int INITIAL_CAPACITY = 16 * 1024; /** * The hashmap that contains the word dictionary. The map is hashed on the doublemeta * code. The map entry contains a LinkedList of words that have the same double meta code. */ protected HashMap mainDictionary = new HashMap(INITIAL_CAPACITY); /** Holds the dictionary file for appending*/ private File dictFile = null; /** * Dictionary constructor that uses the DoubleMeta class with the * English alphabet. * @param wordList The file containing dictionary as a words list. * @throws java.io.FileNotFoundException when the words list file could not * be located on the system. * @throws java.io.IOException when problems occurs while reading the words * list file */ public GenericSpellDictionary(File wordList) throws FileNotFoundException, IOException { this(wordList, (File) null); } /** * Dictionary constructor that uses an aspell phonetic file to * build the transformation table. * If phonetic is null, then DoubleMeta is used with the English alphabet * @param wordList The file containing dictionary as a words list. * @param phonetic The file containing the phonetic transformation * information. * @throws java.io.FileNotFoundException when the words list or phonetic * file could not be located on the system * @throws java.io.IOException when problems occurs while reading the * words list or phonetic file */ public GenericSpellDictionary(File wordList, File phonetic) throws FileNotFoundException, IOException { super(phonetic); dictFile = wordList; createDictionary(new BufferedReader(new FileReader(wordList))); } /** * Add a word permanently to the dictionary (and the dictionary file). *

This needs to be made thread safe (synchronized)

* @param word The word to add to the dictionary */ public void addWord(String word) { putWord(word); if (dictFile == null) return; try { FileWriter w = new FileWriter(dictFile.toString(), true); // Open with append. w.write(word); w.write("\n"); w.close(); } catch (IOException ex) { System.out.println("Error writing to dictionary file"); } } /** * Constructs the dictionary from a word list file. *

* Each word in the reader should be on a separate line. *

* This is a very slow function. On my machine it takes quite a while to * load the data in. I suspect that we could speed this up quite allot. */ protected void createDictionary(BufferedReader in) throws IOException { String line = ""; while (line != null) { line = in.readLine(); if (line != null) { line = new String(line.toCharArray()); putWord(line); } } } /** * Allocates a word in the dictionary */ protected void putWord(String word) { String code = getCode(word); LinkedList list = (LinkedList) mainDictionary.get(code); if (list != null) { list.add(word); } else { list = new LinkedList(); list.add(word); mainDictionary.put(code, list); } } /** * Returns a list of strings (words) for the code. * @param code The phonetic code we want to find words for * @return the list of words having the same phonetic code */ public List getWords(String code) { //Check the main dictionary. List mainDictResult = (List) mainDictionary.get(code); if (mainDictResult == null) return new Vector(); return mainDictResult; } /** * Returns true if the word is correctly spelled against the current word list. * @param word The word to checked in the dictionary * @return indication if the word is in the dictionary */ public boolean isCorrect(String word) { List possible = getWords(getCode(word)); if (possible.contains(word)) return true; //JMH should we always try the lowercase version. If I dont then capitalised //words are always returned as incorrect. else if (possible.contains(word.toLowerCase())) return true; return false; } } jazzy-0.5.2/src/com/swabunga/spell/engine/GenericTransformator.java0000644000175000017500000003522310255105020025357 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.engine; import com.swabunga.util.StringUtility; import java.io.*; import java.util.HashMap; import java.util.Vector; /** * A Generic implementation of a transformator takes an * * aspell phonetics file and constructs some sort of transformation * table using the inner class TransformationRule. *

* Basically, each transformation rule represent a line in the phonetic file. * One line contains two groups of characters separated by white space(s). * The first group is the match expression. * The match expression describe letters to associate with a syllable. * The second group is the replacement expression giving the phonetic * equivalent of the match expression. * * @see SpellDictionaryASpell SpellDictionaryASpell for information on getting * phonetic files for aspell. * * @author Robert Gustavsson (robert@lindesign.se) */ public class GenericTransformator implements Transformator { /** * This replace list is used if no phonetic file is supplied or it doesn't * contain the alphabet. */ private static final char[] defaultEnglishAlphabet = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}; /** * The alphabet start marker. * @see GenericTransformator#KEYWORD_ALPHBET KEYWORD_ALPHBET */ public static final char ALPHABET_START = '['; /** * The alphabet end marker. * @see GenericTransformator#KEYWORD_ALPHBET KEYWORD_ALPHBET */ public static final char ALPHABET_END = ']'; /** * Phonetic file keyword indicating that a different alphabet is used * for this language. The keyword must be followed an * {@link GenericTransformator#ALPHABET_START ALPHABET_START} marker, * a list of characters defining the alphabet and a * {@link GenericTransformator#ALPHABET_END ALPHABET_END} marker. */ public static final String KEYWORD_ALPHBET = "alphabet"; /** * Phonetic file lines starting with the keywords are skipped. * The key words are: version, followup, collapse_result. * Comments, starting with '#', are also skipped to the end of line. */ public static final String[] IGNORED_KEYWORDS = {"version", "followup", "collapse_result"}; /** * Start a group of characters which can be appended to the match expression * of the phonetic file. */ public static final char STARTMULTI = '('; /** * End a group of characters which can be appended to the match expression * of the phonetic file. */ public static final char ENDMULTI = ')'; /** * During phonetic transformation of a word each numeric character is * replaced by this DIGITCODE. */ public static final String DIGITCODE = "0"; /** * Phonetic file character code indicating that the replace expression * is empty. */ public static final String REPLACEVOID = "_"; private Object[] ruleArray = null; private char[] alphabetString = defaultEnglishAlphabet; /** * Construct a transformation table from the phonetic file * @param phonetic the phonetic file as specified in aspell * @throws java.io.IOException indicates a problem while reading * the phonetic file */ public GenericTransformator(File phonetic) throws IOException { buildRules(new BufferedReader(new FileReader(phonetic))); alphabetString = washAlphabetIntoReplaceList(getReplaceList()); } /** * Construct a transformation table from the phonetic file * @param phonetic the phonetic file as specified in aspell * @param encoding the character set required * @throws java.io.IOException indicates a problem while reading * the phonetic file */ public GenericTransformator(File phonetic, String encoding) throws IOException { buildRules(new BufferedReader(new InputStreamReader(new FileInputStream(phonetic), encoding))); alphabetString = washAlphabetIntoReplaceList(getReplaceList()); } /** * Construct a transformation table from the phonetic file * @param phonetic the phonetic file as specified in aspell. The file is * supplied as a reader. * @throws java.io.IOException indicates a problem while reading * the phonetic information */ public GenericTransformator(Reader phonetic) throws IOException { buildRules(new BufferedReader(phonetic)); alphabetString = washAlphabetIntoReplaceList(getReplaceList()); } /** * Goes through an alphabet and makes sure that only one of those letters * that are coded equally will be in the replace list. * In other words, it removes any letters in the alphabet * that are redundant phonetically. * * This is done to improve speed in the getSuggestion method. * * @param alphabet The complete alphabet to wash. * @return The washed alphabet to be used as replace list. */ private char[] washAlphabetIntoReplaceList(char[] alphabet) { HashMap letters = new HashMap(alphabet.length); for (int i = 0; i < alphabet.length; i++) { String tmp = String.valueOf(alphabet[i]); String code = transform(tmp); if (!letters.containsKey(code)) { letters.put(code, new Character(alphabet[i])); } } Object[] tmpCharacters = letters.values().toArray(); char[] washedArray = new char[tmpCharacters.length]; for (int i = 0; i < tmpCharacters.length; i++) { washedArray[i] = ((Character) tmpCharacters[i]).charValue(); } return washedArray; } /** * Takes out all single character replacements and put them in a char array. * This array can later be used for adding or changing letters in getSuggestion(). * @return char[] An array of chars with replacements characters */ public char[] getCodeReplaceList() { char[] replacements; TransformationRule rule; Vector tmp = new Vector(); if (ruleArray == null) return null; for (int i = 0; i < ruleArray.length; i++) { rule = (TransformationRule) ruleArray[i]; if (rule.getReplaceExp().length() == 1) tmp.addElement(rule.getReplaceExp()); } replacements = new char[tmp.size()]; for (int i = 0; i < tmp.size(); i++) { replacements[i] = ((String) tmp.elementAt(i)).charAt(0); } return replacements; } /** * Builds up an char array with the chars in the alphabet of the language as it was read from the * alphabet tag in the phonetic file. * @return char[] An array of chars representing the alphabet or null if no alphabet was available. */ public char[] getReplaceList() { return alphabetString; } /** * Builds the phonetic code of the word. * @param word the word to transform * @return the phonetic transformation of the word */ public String transform(String word) { if (ruleArray == null) return null; TransformationRule rule; StringBuffer str = new StringBuffer(word.toUpperCase()); int strLength = str.length(); int startPos = 0, add = 1; while (startPos < strLength) { add = 1; if (Character.isDigit(str.charAt(startPos))) { StringUtility.replace(str, startPos, startPos + DIGITCODE.length(), DIGITCODE); startPos += add; continue; } for (int i = 0; i < ruleArray.length; i++) { //System.out.println("Testing rule#:"+i); rule = (TransformationRule) ruleArray[i]; if (rule.startsWithExp() && startPos > 0) continue; if (startPos + rule.lengthOfMatch() > strLength) { continue; } if (rule.isMatching(str, startPos)) { String replaceExp = rule.getReplaceExp(); add = replaceExp.length(); StringUtility.replace(str, startPos, startPos + rule.getTakeOut(), replaceExp); strLength -= rule.getTakeOut(); strLength += add; //System.out.println("Replacing with rule#:"+i+" add="+add); break; } } startPos += add; } //System.out.println(word); //System.out.println(str.toString()); return str.toString(); } // Used to build up the transformastion table. private void buildRules(BufferedReader in) throws IOException { String read = null; Vector ruleList = new Vector(); while ((read = in.readLine()) != null) { buildRule(realTrimmer(read), ruleList); } ruleArray = new TransformationRule[ruleList.size()]; ruleList.copyInto(ruleArray); } // Here is where the real work of reading the phonetics file is done. private void buildRule(String str, Vector ruleList) { if (str.length() < 1) return; for (int i = 0; i < IGNORED_KEYWORDS.length; i++) { if (str.startsWith(IGNORED_KEYWORDS[i])) return; } // A different alphabet is used for this language, will be read into // the alphabetString variable. if (str.startsWith(KEYWORD_ALPHBET)) { int start = str.indexOf(ALPHABET_START); int end = str.lastIndexOf(ALPHABET_END); if (end != -1 && start != -1) { alphabetString = str.substring(++start, end).toCharArray(); } return; } // str contains two groups of characters separated by white space(s). // The fisrt group is the "match expression". The second group is the // "replacement expression" giving the phonetic equivalent of the // "match expression". TransformationRule rule = null; StringBuffer matchExp = new StringBuffer(); StringBuffer replaceExp = new StringBuffer(); boolean start = false, end = false; int takeOutPart = 0, matchLength = 0; boolean match = true, inMulti = false; for (int i = 0; i < str.length(); i++) { if (Character.isWhitespace(str.charAt(i))) { match = false; } else { if (match) { if (!isReservedChar(str.charAt(i))) { matchExp.append(str.charAt(i)); if (!inMulti) { takeOutPart++; matchLength++; } if (str.charAt(i) == STARTMULTI || str.charAt(i) == ENDMULTI) inMulti = !inMulti; } if (str.charAt(i) == '-') takeOutPart--; if (str.charAt(i) == '^') start = true; if (str.charAt(i) == '$') end = true; } else { replaceExp.append(str.charAt(i)); } } } if (replaceExp.toString().equals(REPLACEVOID)) { replaceExp = new StringBuffer(""); //System.out.println("Changing _ to \"\" for "+matchExp.toString()); } rule = new TransformationRule(matchExp.toString(), replaceExp.toString(), takeOutPart, matchLength, start, end); //System.out.println(rule.toString()); ruleList.addElement(rule); } // Chars with special meaning to aspell. Not everyone is implemented here. private boolean isReservedChar(char ch) { if (ch == '<' || ch == '>' || ch == '^' || ch == '$' || ch == '-' || Character.isDigit(ch)) return true; return false; } // Trims off everything we don't care about. private String realTrimmer(String row) { int pos = row.indexOf('#'); if (pos != -1) { row = row.substring(0, pos); } return row.trim(); } // Inner Classes /* * Holds the match string and the replace string and all the rule attributes. * Is responsible for indicating matches. */ private class TransformationRule { private String replace; private char[] match; // takeOut=number of chars to replace; // matchLength=length of matching string counting multies as one. private int takeOut, matchLength; private boolean start, end; // Construktor public TransformationRule(String match, String replace, int takeout, int matchLength, boolean start, boolean end) { this.match = match.toCharArray(); this.replace = replace; this.takeOut = takeout; this.matchLength = matchLength; this.start = start; this.end = end; } /* * Returns true if word from pos and forward matches the match string. * Precondition: wordPos+matchLengthSpellDictionary that doesn't cache any words in memory. Avoids the huge * footprint of SpellDictionaryHashMap at the cost of relatively minor latency. A future version * of this class that implements some caching strategies might be a good idea in the future, if there's any * demand for it. *

* This class makes use of the "classic" Java IO library (java.io). However, it could probably benefit from * the new IO APIs (java.nio) and it is anticipated that a future version of this class, probably called * SpellDictionaryDiskNIO will appear at some point. * * @author Ben Galbraith (ben@galbraiths.org) * @version 0.1 * @since 0.5 */ public class SpellDictionaryDisk extends SpellDictionaryASpell { private final static String DIRECTORY_WORDS = "words"; private final static String DIRECTORY_DB = "db"; private final static String FILE_CONTENTS = "contents"; private final static String FILE_DB = "words.db"; private final static String FILE_INDEX = "words.idx"; /* maximum number of words an index entry can represent */ private final static int INDEX_SIZE_MAX = 200; private File base; private File words; private File db; private Map index; /** * The flag indicating if the initial preparation or loading of the on * disk dictionary is complete. */ protected boolean ready; /* used at time of creation of index to speed up determining the number of words per index entry */ private List indexCodeCache = null; /** * Construct a spell dictionary on disk. * The spell dictionary is created from words list(s) contained in file(s). * A words list file is a file with one word per line. Words list files are * located in a base/words dictionary where base * is the path to words dictionary. The on disk spell * dictionary is created in base/db dictionary and contains * files: *

    *
  • contents list the words files used for spelling.
  • *
  • words.db the content of words files organized as * a database of words.
  • *
  • words.idx an index file to the words.db * file content.
  • *
* The contents file has a list of * filename, size indicating the name and length of each files * in the base/words dictionary. If one of theses files was * changed, added or deleted before the call to the constructor, the process * of producing new or updated words.db and * words.idx files is started again. *

* The spellchecking process is then worked upon the words.db * and words.idx files. *

* * NOTE: Do *not* create two instances of this class pointing to the same base unless * you are sure that a new dictionary does not have to be created. In the future, some sort of * external locking mechanism may be created that handles this scenario gracefully. * * @param base the base directory in which SpellDictionaryDisk can expect to find * its necessary files. * @param phonetic the phonetic file used by the spellchecker. * @param block if a new word db needs to be created, there can be a considerable delay before * the constructor returns. If block is true, this method will block while the db is created * and return when done. If block is false, this method will create a thread to create the new * dictionary and return immediately. * @throws java.io.FileNotFoundException indicates problems locating the * files on the system * @throws java.io.IOException indicates problems reading the files */ public SpellDictionaryDisk(File base, File phonetic, boolean block) throws FileNotFoundException, IOException { super(phonetic); this.ready = false; this.base = base; this.words = new File(base, DIRECTORY_WORDS); this.db = new File(base, DIRECTORY_DB); if (!this.base.exists()) throw new FileNotFoundException("Couldn't find required path '" + this.base + "'"); if (!this.words.exists()) throw new FileNotFoundException("Couldn't find required path '" + this.words + "'"); if (!this.db.exists()) db.mkdirs(); if (newDictionaryFiles()) { if (block) { buildNewDictionaryDatabase(); loadIndex(); ready = true; } else { Thread t = new Thread() { public void run() { try { buildNewDictionaryDatabase(); loadIndex(); ready = true; } catch (Exception e) { e.printStackTrace(); } } }; t.start(); } } else { loadIndex(); ready = true; } } /** * Builds the file words database file and the contents file for the on * disk dictionary. */ protected void buildNewDictionaryDatabase() throws FileNotFoundException, IOException { /* combine all dictionary files into one sorted file */ File sortedFile = buildSortedFile(); /* create the db for the sorted file */ buildCodeDb(sortedFile); sortedFile.delete(); /* build contents file */ buildContentsFile(); } /** * Adds another word to the dictionary. This method is not yet implemented * for this class. * @param word The word to add. */ public void addWord(String word) { throw new UnsupportedOperationException("addWord not yet implemented (sorry)"); } /** * Returns a list of words that have the same phonetic code. * @param code The phonetic code common to the list of words * @return A list of words having the same phonetic code */ public List getWords(String code) { Vector words = new Vector(); int[] posLen = getStartPosAndLen(code); if (posLen != null) { try { InputStream input = new FileInputStream(new File(db, FILE_DB)); input.skip(posLen[0]); byte[] bytes = new byte[posLen[1]]; input.read(bytes, 0, posLen[1]); input.close(); String data = new String(bytes); String[] lines = split(data, "\n"); for (int i = 0; i < lines.length; i++) { String[] s = split(lines[i], ","); if (s[0].equals(code)) words.addElement(s[1]); } } catch (Exception e) { e.printStackTrace(); } } return words; } /** * Indicates if the initial preparation or loading of the on disk dictionary * is complete. * @return the indication that the dictionary initial setup is done. */ public boolean isReady() { return ready; } private boolean newDictionaryFiles() throws FileNotFoundException, IOException { /* load in contents file, which indicates the files and sizes of the last db build */ List contents = new ArrayList(); File c = new File(db, FILE_CONTENTS); if (c.exists()) { BufferedReader reader = null; try { reader = new BufferedReader(new FileReader(c)); String line; while ((line = reader.readLine()) != null) { // format of file should be [filename],[size] String[] s = split(line, ","); contents.add(new FileSize(s[0], Integer.parseInt(s[1]))); } } catch (FileNotFoundException e) { throw e; } catch (IOException e) { throw e; } finally { if (reader != null) reader.close(); } } /* compare this to the actual directory */ boolean changed = false; File[] wordFiles = words.listFiles(); if (contents.size() != wordFiles.length) { // if the size of the contents list and the number of word files are different, it // means we've definitely got to reindex changed = true; } else { // check and make sure that all the word files haven't changed on us for (int i = 0; i < wordFiles.length; i++) { FileSize fs = new FileSize(wordFiles[i].getName(), wordFiles[i].length()); if (!contents.contains(fs)) { changed = true; break; } } } return changed; } private File buildSortedFile() throws FileNotFoundException, IOException { List w = new ArrayList(); /* * read every single word into the list. eeek. if this causes problems, * we may wish to explore disk-based sorting or more efficient memory-based storage */ File[] wordFiles = words.listFiles(); for (int i = 0; i < wordFiles.length; i++) { BufferedReader r = new BufferedReader(new FileReader(wordFiles[i])); String word; while ((word = r.readLine()) != null) { if (!word.equals("")) { w.add(word.trim()); } } r.close(); } Collections.sort(w); // FIXME - error handling for running out of disk space would be nice. File file = File.createTempFile("jazzy", "sorted"); BufferedWriter writer = new BufferedWriter(new FileWriter(file)); String prev = null; for (int i = 0; i < w.size(); i++) { String word = (String) w.get(i); if (prev == null || !prev.equals(word)) { writer.write(word); writer.newLine(); } prev = word; } writer.close(); return file; } private void buildCodeDb(File sortedWords) throws FileNotFoundException, IOException { List codeList = new ArrayList(); BufferedReader reader = new BufferedReader(new FileReader(sortedWords)); String word; while ((word = reader.readLine()) != null) { codeList.add(new CodeWord(this.getCode(word), word)); } reader.close(); Collections.sort(codeList); List index = new ArrayList(); BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File(db, FILE_DB))); String currentCode = null; int currentPosition = 0; int currentLength = 0; for (int i = 0; i < codeList.size(); i++) { CodeWord cw = (CodeWord) codeList.get(i); String thisCode = cw.getCode(); // if (thisCode.length() > 3) thisCode = thisCode.substring(0, 3); thisCode = getIndexCode(thisCode, codeList); String toWrite = cw.getCode() + "," + cw.getWord() + "\n"; byte[] bytes = toWrite.getBytes(); if (currentCode == null) currentCode = thisCode; if (!currentCode.equals(thisCode)) { index.add(new Object[]{currentCode, new int[]{currentPosition, currentLength}}); currentPosition += currentLength; currentLength = bytes.length; currentCode = thisCode; } else { currentLength += bytes.length; } out.write(bytes); } out.close(); // Output the last iteration if (currentCode != null && currentPosition != 0 && currentLength != 0) index.add(new Object[]{currentCode, new int[]{currentPosition, currentLength}}); BufferedWriter writer = new BufferedWriter(new FileWriter(new File(db, FILE_INDEX))); for (int i = 0; i < index.size(); i++) { Object[] o = (Object[]) index.get(i); writer.write(o[0].toString()); writer.write(","); writer.write(String.valueOf(((int[]) o[1])[0])); writer.write(","); writer.write(String.valueOf(((int[]) o[1])[1])); writer.newLine(); } writer.close(); } private void buildContentsFile() throws IOException { File[] wordFiles = words.listFiles(); if (wordFiles.length > 0) { BufferedWriter writer = new BufferedWriter(new FileWriter(new File(db, FILE_CONTENTS))); for (int i = 0; i < wordFiles.length; i++) { writer.write(wordFiles[i].getName()); writer.write(","); writer.write(String.valueOf(wordFiles[i].length())); writer.newLine(); } writer.close(); } else { new File(db, FILE_CONTENTS).delete(); } } /** * Loads the index file from disk. The index file accelerates words lookup * into the dictionary db file. */ protected void loadIndex() throws IOException { index = new HashMap(); File idx = new File(db, FILE_INDEX); BufferedReader reader = new BufferedReader(new FileReader(idx)); String line; while ((line = reader.readLine()) != null) { String[] fields = split(line, ","); index.put(fields[0], new int[]{Integer.parseInt(fields[1]), Integer.parseInt(fields[2])}); } reader.close(); } private int[] getStartPosAndLen(String code) { while (code.length() > 0) { int[] posLen = (int[]) index.get(code); if (posLen == null) { code = code.substring(0, code.length() - 1); } else { return posLen; } } return null; } private String getIndexCode(String code, List codes) { if (indexCodeCache == null) indexCodeCache = new ArrayList(); if (code.length() <= 1) return code; for (int i = 0; i < indexCodeCache.size(); i++) { String c = (String) indexCodeCache.get(i); if (code.startsWith(c)) return c; } int foundSize = -1; boolean cacheable = false; for (int z = 1; z < code.length(); z++) { String thisCode = code.substring(0, z); int count = 0; for (int i = 0; i < codes.size();) { if (i == 0) { i = Collections.binarySearch(codes, new CodeWord(thisCode, "")); if (i < 0) i = 0; } CodeWord cw = (CodeWord) codes.get(i); if (cw.getCode().startsWith(thisCode)) { count++; if (count > INDEX_SIZE_MAX) break; } else if (cw.getCode().compareTo(thisCode) > 0) break; i++; } if (count <= INDEX_SIZE_MAX) { cacheable = true; foundSize = z; break; } } String newCode = (foundSize == -1) ? code : code.substring(0, foundSize); if (cacheable) indexCodeCache.add(newCode); return newCode; } private static String[] split(String input, String delimiter) { StringTokenizer st = new StringTokenizer(input, delimiter); int count = st.countTokens(); String[] out = new String[count]; for (int i = 0; i < count; i++) { out[i] = st.nextToken(); } return out; } private class CodeWord implements Comparable { private String code; private String word; public CodeWord(String code, String word) { this.code = code; this.word = word; } public String getCode() { return code; } public String getWord() { return word; } public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof CodeWord)) return false; final CodeWord codeWord = (CodeWord) o; if (!word.equals(codeWord.word)) return false; return true; } public int hashCode() { return word.hashCode(); } public int compareTo(Object o) { return code.compareTo(((CodeWord) o).getCode()); } } private class FileSize { private String filename; private long size; public FileSize(String filename, long size) { this.filename = filename; this.size = size; } public String getFilename() { return filename; } public long getSize() { return size; } public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof FileSize)) return false; final FileSize fileSize = (FileSize) o; if (size != fileSize.size) return false; if (!filename.equals(fileSize.filename)) return false; return true; } public int hashCode() { int result; result = filename.hashCode(); result = (int) (29 * result + size); return result; } } } jazzy-0.5.2/src/com/swabunga/spell/engine/SpellDictionaryDichoDisk.java0000644000175000017500000001673110255105020026113 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.engine; import java.io.*; import java.util.*; /** * Another implementation of SpellDictionary that doesn't cache any words in memory. Avoids the huge * footprint of SpellDictionaryHashMap at the cost of relatively minor latency. A future version * of this class that implements some caching strategies might be a good idea in the future, if there's any * demand for it. * * This implementation requires a special dictionary file, with "code*word" lines sorted by code. * It's using a dichotomy algorithm to search for words in the dictionary * * @author Damien Guillaume * @version 0.1 */ public class SpellDictionaryDichoDisk extends SpellDictionaryASpell { /** Holds the dictionary file for reading*/ private RandomAccessFile dictFile = null; /** dictionary and phonetic file encoding */ private String encoding = null; /** * Dictionary convenience Constructor. * @param wordList The file containing the words list for the dictionary * @throws java.io.FileNotFoundException indicates problems locating the * words list file on the system * @throws java.io.IOException indicates problems reading the words list * file */ public SpellDictionaryDichoDisk(File wordList) throws FileNotFoundException, IOException { super((File) null); dictFile = new RandomAccessFile(wordList, "r"); } /** * Dictionary convenience Constructor. * @param wordList The file containing the words list for the dictionary * @param encoding Uses the character set encoding specified * @throws java.io.FileNotFoundException indicates problems locating the * words list file on the system * @throws java.io.IOException indicates problems reading the words list * file */ public SpellDictionaryDichoDisk(File wordList, String encoding) throws FileNotFoundException, IOException { super((File) null); this.encoding = encoding; dictFile = new RandomAccessFile(wordList, "r"); } /** * Dictionary constructor that uses an aspell phonetic file to * build the transformation table. * @param wordList The file containing the words list for the dictionary * @param phonetic The file to use for phonetic transformation of the * wordlist. * @throws java.io.FileNotFoundException indicates problems locating the * file on the system * @throws java.io.IOException indicates problems reading the words list * file */ public SpellDictionaryDichoDisk(File wordList, File phonetic) throws FileNotFoundException, IOException { super(phonetic); dictFile = new RandomAccessFile(wordList, "r"); } /** * Dictionary constructor that uses an aspell phonetic file to * build the transformation table. * @param wordList The file containing the words list for the dictionary * @param phonetic The file to use for phonetic transformation of the * wordlist. * @param encoding Uses the character set encoding specified * @throws java.io.FileNotFoundException indicates problems locating the * file on the system * @throws java.io.IOException indicates problems reading the words list * file */ public SpellDictionaryDichoDisk(File wordList, File phonetic, String encoding) throws FileNotFoundException, IOException { super(phonetic, encoding); this.encoding = encoding; dictFile = new RandomAccessFile(wordList, "r"); } /** * Add a word permanently to the dictionary (and the dictionary file). * not implemented ! * @param word The word to add. */ public void addWord(String word) { System.err.println("error: addWord is not implemented for SpellDictionaryDichoDisk"); } /** * Search the dictionary file for the words corresponding to the code * within positions p1 - p2 */ private LinkedList dichoFind(String code, long p1, long p2) throws IOException { //System.out.println("dichoFind("+code+","+p1+","+p2+")"); long pm = (p1 + p2) / 2; dictFile.seek(pm); String l; if (encoding == null) l = dictFile.readLine(); else l = dictReadLine(); pm = dictFile.getFilePointer(); if (encoding == null) l = dictFile.readLine(); else l = dictReadLine(); long pm2 = dictFile.getFilePointer(); if (pm2 >= p2) return(seqFind(code, p1, p2)); int istar = l.indexOf('*'); if (istar == -1) throw new IOException("bad format: no * !"); String testcode = l.substring(0, istar); int comp = code.compareTo(testcode); if (comp < 0) return(dichoFind(code, p1, pm-1)); else if (comp > 0) return(dichoFind(code, pm2, p2)); else { LinkedList l1 = dichoFind(code, p1, pm-1); LinkedList l2 = dichoFind(code, pm2, p2); String word = l.substring(istar+1); l1.add(word); l1.addAll(l2); return(l1); } } private LinkedList seqFind(String code, long p1, long p2) throws IOException { //System.out.println("seqFind("+code+","+p1+","+p2+")"); LinkedList list = new LinkedList(); dictFile.seek(p1); while (dictFile.getFilePointer() < p2) { String l; if (encoding == null) l = dictFile.readLine(); else l = dictReadLine(); int istar = l.indexOf('*'); if (istar == -1) throw new IOException("bad format: no * !"); String testcode = l.substring(0, istar); if (testcode.equals(code)) { String word = l.substring(istar+1); list.add(word); } } return(list); } /** * Read a line of dictFile with a specific encoding */ private String dictReadLine() throws IOException { int max = 255; byte b=0; byte[] buf = new byte[max]; int i=0; try { for (; b != '\n' && b != '\r' && i * Another way to think about this: what are the cheapest operations that would have to be done on the "original" word to end up * with the "similar" word? Each operation has a cost, and these are added up to get the distance. *
* * @see com.swabunga.spell.engine.Configuration#COST_REMOVE_CHAR * @see com.swabunga.spell.engine.Configuration#COST_INSERT_CHAR * @see com.swabunga.spell.engine.Configuration#COST_SUBST_CHARS * @see com.swabunga.spell.engine.Configuration#COST_SWAP_CHARS * */ public class EditDistance { /** * Fetches the spell engine configuration properties. */ public static Configuration config = Configuration.getConfiguration(); /** * get the weights for each possible operation */ static final int costOfDeletingSourceCharacter = config.getInteger(Configuration.COST_REMOVE_CHAR); static final int costOfInsertingSourceCharacter = config.getInteger(Configuration.COST_INSERT_CHAR); static final int costOfSubstitutingLetters = config.getInteger(Configuration.COST_SUBST_CHARS); static final int costOfSwappingLetters = config.getInteger(Configuration.COST_SWAP_CHARS); static final int costOfChangingCase = config.getInteger(Configuration.COST_CHANGE_CASE); /** * Evaluates the distance between two words. * * @param word One word to evaluates * @param similar The other word to evaluates * @return a number representing how easy or complex it is to transform on * word into a similar one. */ public static final int getDistance(String word, String similar) { return getDistance(word,similar,null); } /** * Evaluates the distance between two words. * * @param word One word to evaluates * @param similar The other word to evaluates * @return a number representing how easy or complex it is to transform on * word into a similar one. */ public static final int getDistance(String word, String similar, int[][] matrix) { /* JMH Again, there is no need to have a global class matrix variable * in this class. I have removed it and made the getDistance static final * DMV: I refactored this method to make it more efficient, more readable, and simpler. * I also fixed a bug with how the distance was being calculated. You could get wrong * distances if you compared ("abc" to "ab") depending on what you had setup your * COST_REMOVE_CHAR and EDIT_INSERTION_COST values to - that is now fixed. * WRS: I added a distance for case comparison, so a misspelling of "i" would be closer to "I" than * to "a". */ //Allocate memory outside of the loops. int i; int j; int costOfSubst; int costOfSwap; int costOfDelete; int costOfInsertion; int costOfCaseChange; boolean isSwap; char sourceChar = 0; char otherChar = 0; int a_size = word.length() + 1; int b_size = similar.length() + 1; //Only allocate new memory if we need a bigger matrix. if (matrix == null || matrix.length < a_size || matrix[0].length < b_size) matrix = new int[a_size][b_size]; matrix[0][0] = 0; for (i = 1; i != a_size; ++i) matrix[i][0] = matrix[i - 1][0] + costOfInsertingSourceCharacter; //initialize the first column for (j = 1; j != b_size; ++j) matrix[0][j] = matrix[0][j - 1] + costOfDeletingSourceCharacter; //initalize the first row for (i = 1; i != a_size; ++i) { sourceChar = word.charAt(i-1); for (j = 1; j != b_size; ++j) { otherChar = similar.charAt(j-1); if (sourceChar == otherChar) { matrix[i][j] = matrix[i - 1][j - 1]; //no change required, so just carry the current cost up continue; } costOfSubst = costOfSubstitutingLetters + matrix[i - 1][j - 1]; //if needed, add up the cost of doing a swap costOfSwap = Integer.MAX_VALUE; isSwap = (i != 1) && (j != 1) && sourceChar == similar.charAt(j - 2) && word.charAt(i - 2) == otherChar; if (isSwap) costOfSwap = costOfSwappingLetters + matrix[i - 2][j - 2]; costOfDelete = costOfDeletingSourceCharacter + matrix[i][j - 1]; costOfInsertion = costOfInsertingSourceCharacter + matrix[i - 1][j]; costOfCaseChange = Integer.MAX_VALUE; if (equalIgnoreCase(sourceChar, otherChar)) costOfCaseChange = costOfChangingCase + matrix[i - 1][j - 1]; matrix[i][j] = minimum(costOfSubst, costOfSwap, costOfDelete, costOfInsertion, costOfCaseChange); } } if (false) System.out.println(dumpMatrix(word, similar, matrix)); return matrix[a_size - 1][b_size - 1]; } /** * checks to see if the two charactors are equal ignoring case. * @param ch1 * @param ch2 * @return boolean */ private static boolean equalIgnoreCase(char ch1, char ch2) { if (ch1 == ch2) { return true; } else { return (Character.toLowerCase(ch1) == Character.toLowerCase(ch2)); } } /** * For debugging, this creates a string that represents the matrix. To read the matrix, look at any square. That is the cost to get from * the partial letters along the top to the partial letters along the side. * @param src - the source string that the matrix columns are based on * @param dest - the dest string that the matrix rows are based on * @param matrix - a two dimensional array of costs (distances) * @return String */ static private String dumpMatrix(String src, String dest, int matrix[][]) { StringBuffer s = new StringBuffer(""); int cols = matrix.length -1; int rows = matrix[0].length -1; for (int i = 0; i < cols + 1; i++) { for (int j = 0; j < rows + 1; j++) { if (i == 0 && j == 0) { s.append("\n "); continue; } if (i == 0) { s.append("| "); s.append(dest.charAt(j - 1)); continue; } if (j == 0) { s.append(src.charAt(i - 1)); continue; } String num = Integer.toString(matrix[i - 1][j - 1]); int padding = 4 - num.length(); s.append("|"); for (int k = 0; k < padding; k++) s.append(' '); s.append(num); } s.append('\n'); } return s.toString(); } static private int minimum(int a, int b, int c, int d, int e) { int mi = a; if (b < mi) mi = b; if (c < mi) mi = c; if (d < mi) mi = d; if (e < mi) mi = e; return mi; } /** * For testing edit distances * @param args an array of two strings we want to evaluate their distances. * @throws java.lang.Exception when problems occurs during reading args. */ public static void main(String[] args) throws Exception { BufferedReader stdin = new BufferedReader(new InputStreamReader(System.in)); int[][] matrix = new int[0][0]; while (true) { String input1 = stdin.readLine(); if (input1 == null || input1.length() == 0) break; String input2 = stdin.readLine(); if (input2 == null || input2.length() == 0) break; System.out.println(EditDistance.getDistance(input1, input2,matrix)); } System.out.println("done"); } } jazzy-0.5.2/src/com/swabunga/spell/engine/SpellDictionary.java0000644000175000017500000000762310340363602024340 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.engine; import java.util.List; /** * An interface for all dictionary implementations. It defines the most basic * operations on a dictionary: adding words, checking if a word is correct, and getting a list * of suggestions for misspelled words. */ public interface SpellDictionary { /** * Add a word permanently to the dictionary. * @param word The word to add to the dictionary */ public void addWord(String word); /** * Evaluates if the word is correctly spelled against the dictionary. * @param word The word to verify if it's spelling is OK. * @return Indicates if the word is present in the dictionary. */ public boolean isCorrect(String word); /** * Returns a list of Word objects that are the suggestions to any word. * If the word is correctly spelled, then this method * could return just that one word, or it could still return a list * of words with similar spellings. *
* Each suggested word has a score, which is an integer * that represents how different the suggested word is from the sourceWord. * If the words are the exactly the same, then the score is 0. * You can get the dictionary to only return the most similar words by setting * an appropriately low threshold value. * If you set the threshold value too low, you may get no suggestions for a given word. *

* This method is only needed to provide backward compatibility. * @see #getSuggestions(String, int, int[][]) * * @param sourceWord the string that we want to get a list of spelling suggestions for * @param scoreThreshold Any words that have score less than this number are returned. * @return List a List of suggested words * @see com.swabunga.spell.engine.Word * */ public List getSuggestions(String sourceWord, int scoreThreshold); /** * Returns a list of Word objects that are the suggestions to any word. * If the word is correctly spelled, then this method * could return just that one word, or it could still return a list * of words with similar spellings. *
* Each suggested word has a score, which is an integer * that represents how different the suggested word is from the sourceWord. * If the words are the exactly the same, then the score is 0. * You can get the dictionary to only return the most similar words by setting * an appropriately low threshold value. * If you set the threshold value too low, you may get no suggestions for a given word. *

* @param sourceWord the string that we want to get a list of spelling suggestions for * @param scoreThreshold Any words that have score less than this number are returned. * @param Two dimensional int array used to calculate edit distance. Allocating * this memory outside of the function will greatly improve efficiency. * @return List a List of suggested words * @see com.swabunga.spell.engine.Word */ public List getSuggestions(String sourceWord, int scoreThreshold , int[][] matrix); } jazzy-0.5.2/src/com/swabunga/spell/engine/configuration.properties0000644000175000017500000000063107666624666025400 0ustar twernertwernerEDIT_DEL1=95 EDIT_DEL2=95 EDIT_SWAP=90 EDIT_SUB=100 EDIT_CASE=10 #DMV: the following commented out settings do not seem to be used at all #EDIT_SIMILAR=10 #EDIT_MIN=90 #EDIT_MAX=100 SPELL_THRESHOLD=140 SPELL_IGNOREUPPERCASE=true SPELL_IGNOREMIXEDCASE=false SPELL_IGNOREINTERNETADDRESS=true SPELL_IGNOREDIGITWORDS=true SPELL_IGNOREMULTIPLEWORDS=false SPELL_IGNORESENTENCECAPTILIZATION=true jazzy-0.5.2/src/com/swabunga/spell/engine/Configuration.java0000644000175000017500000001414110255105020024024 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.engine; import java.security.AccessControlException; /** * The various settings used to control how a spell checker works are read from here. * Includes the COST_* constants that decide how to figure the cost of converting one word to * another in the EditDistance class. *

* Also includes SPELL_* constants that control how misspellings are detected, for example, how to handle * mixed-case words, etc. * * @author aim4min * @see EditDistance */ public abstract class Configuration { /** used by EditDistance: the cost of having to remove a character
(integer greater than 0) */ public static final String COST_REMOVE_CHAR = "EDIT_DEL1"; /** used by EditDistance: the cost of having to insert a character
(integer greater than 0)*/ public static final String COST_INSERT_CHAR = "EDIT_DEL2"; /** * used by EditDistance: the cost of having to swap two adjoining characters * for the swap value to ever be used, it should be smaller than the COST_REMOVE_CHAR or COST_INSERT_CHAR values *
(integer greater than 0) */ public static final String COST_SWAP_CHARS = "EDIT_SWAP"; /** * used by EditDistance: the cost of having to change case, for example, from i to I. *
(integer greater than 0) */ public static final String COST_CHANGE_CASE = "EDIT_CASE"; /** * used by EditDistance: the cost of having to substitute one character for another * for the sub value to ever be used, it should be smaller than the COST_REMOVE_CHAR or COST_INSERT_CHAR values *
(integer greater than 0) */ public static final String COST_SUBST_CHARS = "EDIT_SUB"; // public static final String EDIT_SIMILAR = "EDIT_SIMILAR"; //DMV: these does not seem to be used at all // public static final String EDIT_MIN = "EDIT_MIN"; // public static final String EDIT_MAX = "EDIT_MAX"; /** the maximum cost of suggested spelling. Any suggestions that cost more are thrown away *
integer greater than 1) */ public static final String SPELL_THRESHOLD = "SPELL_THRESHOLD"; /** words that are all upper case are not spell checked, example: "CIA"
(boolean) */ public static final String SPELL_IGNOREUPPERCASE = "SPELL_IGNOREUPPERCASE"; /** words that have mixed case are not spell checked, example: "SpellChecker"
(boolean) */ public static final String SPELL_IGNOREMIXEDCASE = "SPELL_IGNOREMIXEDCASE"; /** words that look like an Internet address are not spell checked, example: "http://www.google.com"
(boolean)*/ public static final String SPELL_IGNOREINTERNETADDRESSES = "SPELL_IGNOREINTERNETADDRESS"; /** words that have digits in them are not spell checked, example: "mach5"
(boolean) */ public static final String SPELL_IGNOREDIGITWORDS = "SPELL_IGNOREDIGITWORDS"; /** I don't know what this does. It doesn't seem to be used
(boolean) */ public static final String SPELL_IGNOREMULTIPLEWORDS = "SPELL_IGNOREMULTIPLEWORDS"; /** the first word of a sentence is expected to start with an upper case letter
(boolean) */ public static final String SPELL_IGNORESENTENCECAPITALIZATION = "SPELL_IGNORESENTENCECAPTILIZATION"; /** * Gets one of the integer constants * @param key one of the integer constants defined in this class * @return int value of the setting */ public abstract int getInteger(String key); /** * Gets one of the boolean constants * @param key one of the boolean constants defined in this class * @return boolean value of the setting */ public abstract boolean getBoolean(String key); /** * Sets one of the integer constants * @param key one of the integer constants defined in this class * @param value new integer value of the constant */ public abstract void setInteger(String key, int value); /** * Sets one of the boolean constants * @param key one of the boolean constants defined in this class * @param value new boolean value of this setting */ public abstract void setBoolean(String key, boolean value); /** * gets a new default Configuration * @return Configuration */ public static final Configuration getConfiguration() { try { String config = System.getProperty("jazzy.config"); // added by bd if (config != null && config.length() > 0) return getConfiguration(config); } catch (AccessControlException e) { e.printStackTrace(); } return getConfiguration(null); } /** * Returns a new instance of a Configuration class * @param className - the class to return, must be based on Configuration * @return Configuration */ public static final Configuration getConfiguration(String className) { Configuration result; if (className != null && className.length() > 0) { try { result = (Configuration) Class.forName(className).newInstance(); } catch (InstantiationException e) { result = new PropertyConfiguration(); } catch (IllegalAccessException e) { result = new PropertyConfiguration(); } catch (ClassNotFoundException e) { result = new PropertyConfiguration(); } } else { result = new PropertyConfiguration(); } return result; } } jazzy-0.5.2/src/com/swabunga/spell/engine/SpellDictionaryHashMap.java0000644000175000017500000002535310255105020025573 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* * put your module comment here * formatted with JxBeauty (c) johann.langhofer@nextra.at */ package com.swabunga.spell.engine; import java.io.*; import java.util.Hashtable; import java.util.List; import java.util.Vector; /** * The SpellDictionaryHashMap holds the dictionary *

* This class is thread safe. Derived classes should ensure that this preserved. *

* There are many open source dictionary files. For just a few see: * http://wordlist.sourceforge.net/ *

* This dictionary class reads words one per line. Make sure that your word list * is formatted in this way (most are). *

* Note that you must create the dictionary with a word list for the added * words to persist. */ public class SpellDictionaryHashMap extends SpellDictionaryASpell { /** A field indicating the initial hash map capacity (16KB) for the main * dictionary hash map. Interested to see what the performance of a * smaller initial capacity is like. */ private final static int INITIAL_CAPACITY = 16 * 1024; /** * The hashmap that contains the word dictionary. The map is hashed on the doublemeta * code. The map entry contains a LinkedList of words that have the same double meta code. */ protected Hashtable mainDictionary = new Hashtable(INITIAL_CAPACITY); /** Holds the dictionary file for appending*/ private File dictFile = null; /** * Dictionary Constructor. * @throws java.io.IOException indicates a problem with the file system */ public SpellDictionaryHashMap() throws IOException { super((File) null); } /** * Dictionary Constructor. * @param wordList The file containing the words list for the dictionary * @throws java.io.IOException indicates problems reading the words list * file */ public SpellDictionaryHashMap(Reader wordList) throws IOException { super((File) null); createDictionary(new BufferedReader(wordList)); } /** * Dictionary convenience Constructor. * @param wordList The file containing the words list for the dictionary * @throws java.io.FileNotFoundException indicates problems locating the * words list file on the system * @throws java.io.IOException indicates problems reading the words list * file */ public SpellDictionaryHashMap(File wordList) throws FileNotFoundException, IOException { this(new FileReader(wordList)); dictFile = wordList; } /** * Dictionary constructor that uses an aspell phonetic file to * build the transformation table. * @param wordList The file containing the words list for the dictionary * @param phonetic The file to use for phonetic transformation of the * wordlist. * @throws java.io.FileNotFoundException indicates problems locating the * file on the system * @throws java.io.IOException indicates problems reading the words list * file */ public SpellDictionaryHashMap(File wordList, File phonetic) throws FileNotFoundException, IOException { super(phonetic); dictFile = wordList; createDictionary(new BufferedReader(new FileReader(wordList))); } /** * Dictionary constructor that uses an aspell phonetic file to * build the transformation table. Encoding is used for phonetic file only; * default encoding is used for wordList * @param wordList The file containing the words list for the dictionary * @param phonetic The file to use for phonetic transformation of the * wordlist. * @param phoneticEncoding Uses the character set encoding specified * @throws java.io.FileNotFoundException indicates problems locating the * file on the system * @throws java.io.IOException indicates problems reading the words list * or phonetic information */ public SpellDictionaryHashMap(File wordList, File phonetic, String phoneticEncoding) throws FileNotFoundException, IOException { super(phonetic, phoneticEncoding); dictFile = wordList; createDictionary(new BufferedReader(new FileReader(wordList))); } /** * Dictionary constructor that uses an aspell phonetic file to * build the transformation table. * @param wordList The file containing the words list for the dictionary * @param phonetic The reader to use for phonetic transformation of the * wordlist. * @throws java.io.IOException indicates problems reading the words list * or phonetic information */ public SpellDictionaryHashMap(Reader wordList, Reader phonetic) throws IOException { super(phonetic); dictFile = null; createDictionary(new BufferedReader(wordList)); } /** * Add words from a file to existing dictionary hashmap. * This function can be called as many times as needed to * build the internal word list. Duplicates are not added. *

* Note that adding a dictionary does not affect the target * dictionary file for the addWord method. That is, addWord() continues * to make additions to the dictionary file specified in createDictionary() *

* @param wordList a File object that contains the words, on word per line. * @throws FileNotFoundException * @throws IOException */ public void addDictionary(File wordList) throws FileNotFoundException, IOException { addDictionaryHelper(new BufferedReader(new FileReader(wordList))); } /** * Add words from a Reader to existing dictionary hashmap. * This function can be called as many times as needed to * build the internal word list. Duplicates are not added. *

* Note that adding a dictionary does not affect the target * dictionary file for the addWord method. That is, addWord() continues * to make additions to the dictionary file specified in createDictionary() *

* @param wordList a Reader object that contains the words, on word per line. * @throws IOException */ public void addDictionary(Reader wordList) throws IOException { addDictionaryHelper(new BufferedReader(wordList)); } /** * Add a word permanently to the dictionary (and the dictionary file). *

This needs to be made thread safe (synchronized)

*/ public void addWord(String word) { putWord(word); if (dictFile == null) return; try { FileWriter w = new FileWriter(dictFile.toString(), true); // Open with append. w.write(word); w.write("\n"); w.close(); } catch (IOException ex) { System.out.println("Error writing to dictionary file"); } } /** * Constructs the dictionary from a word list file. *

* Each word in the reader should be on a separate line. *

* This is a very slow function. On my machine it takes quite a while to * load the data in. I suspect that we could speed this up quite allot. */ protected void createDictionary(BufferedReader in) throws IOException { String line = ""; while (line != null) { line = in.readLine(); if (line != null && line.length() > 0) { line = new String(line.toCharArray()); putWord(line); } } } /** * Adds to the existing dictionary from a word list file. If the word * already exists in the dictionary, a new entry is not added. *

* Each word in the reader should be on a separate line. *

* Note: for whatever reason that I haven't yet looked into, the phonetic codes * for a particular word map to a vector of words rather than a hash table. * This is a drag since in order to check for duplicates you have to iterate * through all the words that use the phonetic code. * If the vector-based implementation is important, it may be better * to subclass for the cases where duplicates are bad. */ protected void addDictionaryHelper(BufferedReader in) throws IOException { String line = ""; while (line != null) { line = in.readLine(); if (line != null && line.length() > 0) { line = new String(line.toCharArray()); putWordUnique(line); } } } /** * Allocates a word in the dictionary * @param word The word to add */ protected void putWord(String word) { String code = getCode(word); Vector list = (Vector) mainDictionary.get(code); if (list != null) { list.addElement(word); } else { list = new Vector(); list.addElement(word); mainDictionary.put(code, list); } } /** * Allocates a word, if it is not already present in the dictionary. A word * with a different case is considered the same. * @param word The word to add */ protected void putWordUnique(String word) { String code = getCode(word); Vector list = (Vector) mainDictionary.get(code); if (list != null) { boolean isAlready = false; for (int i = 0; i < list.size(); i++) { if (word.equalsIgnoreCase((String) list.elementAt(i))) { isAlready = true; break; } } if (!isAlready) list.addElement(word); } else { list = new Vector(); list.addElement(word); mainDictionary.put(code, list); } } /** * Returns a list of strings (words) for the code. */ public List getWords(String code) { //Check the main dictionary. Vector mainDictResult = (Vector) mainDictionary.get(code); if (mainDictResult == null) return new Vector(); return mainDictResult; } /** * Returns true if the word is correctly spelled against the current word list. */ public boolean isCorrect(String word) { List possible = getWords(getCode(word)); if (possible.contains(word)) return true; //JMH should we always try the lowercase version. If I dont then capitalised //words are always returned as incorrect. else if (possible.contains(word.toLowerCase())) return true; return false; } } jazzy-0.5.2/src/com/swabunga/spell/engine/PropertyConfiguration.java0000644000175000017500000000614710255105020025600 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.engine; import java.io.*; import java.net.URL; import java.util.Properties; /** * Implementation class to read the properties controlling the spell engine. * The properties are read form the configuration.properties file. * * @author aim4min */ public class PropertyConfiguration extends Configuration { /** * The persistent set of properties supported by the spell engine */ public Properties prop; /** * The name of the file containing spell engine properties */ public URL filename; /** * Constructs and loads spell engine properties configuration. */ public PropertyConfiguration() { prop = new Properties(); try { filename = getClass().getClassLoader().getResource("com/swabunga/spell/engine/configuration.properties"); InputStream in = filename.openStream(); prop.load(in); } catch (Exception e) { System.out.println("Could not load Properties file :\n" + e); } } /** * @see com.swabunga.spell.engine.Configuration#getBoolean(String) */ public boolean getBoolean(String key) { return new Boolean(prop.getProperty(key)).booleanValue(); } /** * @see com.swabunga.spell.engine.Configuration#getInteger(String) */ public int getInteger(String key) { return new Integer(prop.getProperty(key)).intValue(); } /** * @see com.swabunga.spell.engine.Configuration#setBoolean(String, boolean) */ public void setBoolean(String key, boolean value) { String string = null; if (value) string = "true"; else string = "false"; prop.setProperty(key, string); save(); } /** * @see com.swabunga.spell.engine.Configuration#setInteger(String, int) */ public void setInteger(String key, int value) { prop.setProperty(key, Integer.toString(value)); save(); } /** * Writes the property list (key and element pairs) in the * PropertyConfiguration file. */ public void save() { try { File file = new File(filename.getFile()); FileOutputStream fout = new FileOutputStream(file); prop.store(fout, "HEADER"); } catch (FileNotFoundException e) { } catch (IOException e) { } } } jazzy-0.5.2/src/com/swabunga/spell/engine/SpellDictionaryCachedDichoDisk.java0000644000175000017500000001774010253371640027217 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.engine; import java.io.*; import java.util.*; /** * Yet another SpellDictionary this one is based on Damien Guillaume's * Diskbased dictionary but adds a cache to try to improve abit on performance. * * @author Robert Gustavsson * @version 0.01 */ public class SpellDictionaryCachedDichoDisk extends SpellDictionaryDichoDisk { // Only used for testing to measure the effectiveness of the cache. static public int hits=0; static public int codes=0; public static final String JAZZY_DIR=".jazzy"; public static final String PRE_CACHE_FILE_EXT=".pre"; private static int MAX_CACHED=10000; private HashMap suggestionCache=new HashMap(MAX_CACHED); private String preCacheFileName; private String preCacheDir; /** * Dictionary Convienence Constructor. */ public SpellDictionaryCachedDichoDisk(File wordList) throws FileNotFoundException, IOException { super((File) wordList); loadPreCache(wordList); } /** * Dictionary Convienence Constructor. */ public SpellDictionaryCachedDichoDisk(File wordList, String encoding) throws FileNotFoundException, IOException { super(wordList, encoding); loadPreCache(wordList); } /** * Dictionary constructor that uses an aspell phonetic file to * build the transformation table. */ public SpellDictionaryCachedDichoDisk(File wordList, File phonetic) throws FileNotFoundException, IOException { super(wordList, phonetic); loadPreCache(wordList); } /** * Dictionary constructor that uses an aspell phonetic file to * build the transformation table. */ public SpellDictionaryCachedDichoDisk(File wordList, File phonetic, String encoding) throws FileNotFoundException, IOException { super(wordList, phonetic, encoding); loadPreCache(wordList); } /** * Add a word permanantly to the dictionary (and the dictionary file). * not implemented ! */ public void addWord(String word) { System.err.println("error: addWord is not implemented for SpellDictionaryCachedDichoDisk"); } /** * Clears the cache. */ public void clearCache(){ suggestionCache.clear(); } /** * Returns a list of strings (words) for the code. */ public List getWords(String code) { List list; codes++; if(suggestionCache.containsKey(code)){ hits++; list=getCachedList(code); return list; } list=super.getWords(code); addToCache(code,list); return list; } /** * This method returns the cached suggestionlist and also moves the code to * the top of the codeRefQueue to indicate this code has resentlly been * referenced. */ private List getCachedList(String code){ CacheObject obj=(CacheObject)suggestionCache.get(code); obj.setRefTime(); return obj.getSuggestionList(); } /** * Adds a code and it's suggestion list to the cache. */ private void addToCache(String code, List l){ String c=null; String lowestCode=null; long lowestTime=Long.MAX_VALUE; Iterator it; CacheObject obj; if(suggestionCache.size()>=MAX_CACHED){ it=suggestionCache.keySet().iterator(); while(it.hasNext()){ c=(String)it.next(); obj=(CacheObject)suggestionCache.get(c); if(obj.getRefTime()==0){ lowestCode=c; break; } if(lowestTime>obj.getRefTime()){ lowestCode=c; lowestTime=obj.getRefTime(); } } suggestionCache.remove(lowestCode); } suggestionCache.put(code,new CacheObject(l)); } /** * Load the cache from file. The cach file has the same name as the * dico file with the .pre extension added. */ private void loadPreCache(File dicoFile)throws IOException{ String code; List suggestions; long size, time; File preFile; ObjectInputStream in; preCacheDir=System.getProperty("user.home")+"/"+JAZZY_DIR; preCacheFileName=preCacheDir+"/"+dicoFile.getName()+PRE_CACHE_FILE_EXT; //System.out.println(preCacheFileName); preFile=new File(preCacheFileName); if(!preFile.exists()){ System.err.println("No precache file"); return; } //System.out.println("Precaching..."); in=new ObjectInputStream(new FileInputStream(preFile)); try{ size=in.readLong(); for(int i=0;iThis class is now immutable. *

*/ public class Word implements Comparator { private String word; private int score; /** * Constructs a new Word. * @param word The text of a word. * @param score The word's distance cost */ public Word(String word, int score) { this.word = word; this.score = score; } /** * Constructs a new Word. */ public Word() { this.word = ""; this.score = 0; } /** * Compares two words, mostly for the purpose of sorting words. * @param o1 the first word * @param o2 the second word * @return -1 if the first word is more similar to the misspelled word *
1 if the second word is more similar to the misspelled word *
0 if both words are equally similar * */ public int compare(Object o1, Object o2) { if (((Word) o1).getCost() < ((Word) o2).getCost()) return -1; if (((Word) o1).getCost() == ((Word) o2).getCost()) return 0; return 1; } /** * Indicates if this word is equal to another one. * @param o The other word to compare * @return The indication of equality */ public boolean equals(Object o) { if (o instanceof Word) // added by bd return(((Word)o).getWord().equals(getWord())); return false; } /** * gets suggested spelling * @return the actual text of the suggest spelling */ public String getWord() { return word; } /** * sets suggested spelling * @param word The text to set for suggestd spelling */ public void setWord(String word) { this.word = word; } /** * A cost measures how close a match this word was to the original word * @return 0 if an exact match. Higher numbers are worse matches. * @see EditDistance */ public int getCost() { return score; } /** * returns the suggested spelling * @return The word's text */ public String toString() { return word; } } jazzy-0.5.2/src/com/swabunga/spell/engine/SpellDictionaryASpell.java0000644000175000017500000003017610340363602025440 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /* Created by bgalbs on Jan 30, 2003 at 11:45:25 PM */ package com.swabunga.spell.engine; import java.io.File; import java.io.IOException; import java.io.Reader; import java.security.InvalidParameterException; import java.util.*; /** * Container for various methods that any SpellDictionary will use. * This class is based on the original Jazzy aspell port. *

* Derived classes will need words list files as spell checking reference. * Words list file is a dictionary with one word per line. There are many * open source dictionary files, see: * * http://wordlist.sourceforge.net/ *

* You can choose words lists form aspell * many differents languages dictionaries. To grab some, install * aspell and the dictionaries you require. Then run aspell * specifying the name of the dictionary and the words list file to dump it * into, for example: *

 * aspell --master=fr-40 dump master > fr-40.txt
 * 
* Note: the number following the language is the size indicator. A bigger * number gives a more extensive language coverage. Size 40 is more than * adequate for many usages. *

* For some languages, Aspell can also supply you with the phonetic file. * On Windows, go into aspell data directory and copy the * phonetic file corresponding to your language, for example the * fr_phonet.dat for the fr language. The phonetic * file should be in directory /usr/share/aspell on Unix. * * @see GenericTransformator GenericTransformator for information on * phonetic files. */ public abstract class SpellDictionaryASpell implements SpellDictionary { /** The reference to a Transformator, used to transform a word into it's phonetic code. */ protected Transformator tf; /** * Constructs a new SpellDictionaryASpell * @param phonetic The file to use for phonetic transformation of the * words list. If phonetic is null, the the transformation * uses {@link DoubleMeta} transformation. * @throws java.io.IOException indicates problems reading the phonetic * information */ public SpellDictionaryASpell(File phonetic) throws IOException { if (phonetic == null) tf = new DoubleMeta(); else tf = new GenericTransformator(phonetic); } /** * Constructs a new SpellDictionaryASpell * @param phonetic The file to use for phonetic transformation of the * words list. If phonetic is null, the the transformation * uses {@link DoubleMeta} transformation. * @param encoding Uses the character set encoding specified * @throws java.io.IOException indicates problems reading the phonetic * information */ public SpellDictionaryASpell(File phonetic, String encoding) throws IOException { if (phonetic == null) tf = new DoubleMeta(); else tf = new GenericTransformator(phonetic, encoding); } /** * Constructs a new SpellDictionaryASpell * @param phonetic The Reader to use for phonetic transformation of the * words list. If phonetic is null, the the transformation * uses {@link DoubleMeta} transformation. * @throws java.io.IOException indicates problems reading the phonetic * information */ public SpellDictionaryASpell(Reader phonetic) throws IOException { if (phonetic == null) tf = new DoubleMeta(); else tf = new GenericTransformator(phonetic); } /** * Returns a list of Word objects that are the suggestions to an * incorrect word. *

* This method is only needed to provide backward compatibility. * @see #getSuggestions(String, int, int[][]) * @param word Suggestions for given misspelt word * @param threshold The lower boundary of similarity to misspelt word * @return Vector a List of suggestions */ public List getSuggestions(String word, int threshold) { return getSuggestions(word,threshold,null); } /** * Returns a list of Word objects that are the suggestions to an * incorrect word. *

* @param word Suggestions for given misspelt word * @param threshold The lower boundary of similarity to misspelt word * @param matrix Two dimensional int array used to calculate * edit distance. Allocating this memory outside of the function will greatly improve efficiency. * @return Vector a List of suggestions */ public List getSuggestions(String word, int threshold, int[][] matrix) { int i; int j; if(matrix == null) matrix = new int[0][0]; Hashtable nearmisscodes = new Hashtable(); String code = getCode(word); // add all words that have the same phonetics nearmisscodes.put(code, code); Vector phoneticList = getWordsFromCode(word, nearmisscodes); // do some tranformations to pick up more results //interchange nearmisscodes = new Hashtable(); char[] charArray = word.toCharArray(); char a; char b ; for (i = 0; i < word.length() - 1; i++) { a = charArray[i]; b = charArray[i + 1]; charArray[i] = b; charArray[i + 1] = a; String s = getCode(new String(charArray)); nearmisscodes.put(s, s); charArray[i] = a; charArray[i + 1] = b; } char[] replacelist = tf.getReplaceList(); //change charArray = word.toCharArray(); char original; for (i = 0; i < word.length(); i++) { original = charArray[i]; for (j = 0; j < replacelist.length; j++) { charArray[i] = replacelist[j]; String s = getCode(new String(charArray)); nearmisscodes.put(s, s); } charArray[i] = original; } //add charArray = (word += " ").toCharArray(); int iy = charArray.length - 1; while (true) { for (j = 0; j < replacelist.length; j++) { charArray[iy] = replacelist[j]; String s = getCode(new String(charArray)); nearmisscodes.put(s, s); } if (iy == 0) break; charArray[iy] = charArray[iy - 1]; --iy; } //delete word = word.trim(); charArray = word.toCharArray(); char[] charArray2 = new char[charArray.length - 1]; for (int ix = 0; ix < charArray2.length; ix++) { charArray2[ix] = charArray[ix]; } a = charArray[charArray.length - 1]; int ii = charArray2.length; while (true) { String s = getCode(new String(charArray)); nearmisscodes.put(s, s); if (ii == 0) break; b = a; a = charArray2[ii - 1]; charArray2[ii - 1] = b; --ii; } nearmisscodes.remove(code); //already accounted for in phoneticList Vector wordlist = getWordsFromCode(word, nearmisscodes); if (wordlist.size() == 0 && phoneticList.size() == 0) addBestGuess(word, phoneticList, matrix); // We sort a Vector at the end instead of maintaining a // continously sorted TreeSet because everytime you add a collection // to a treeset it has to be resorted. It's better to do this operation // once at the end. Collections.sort(phoneticList, new Word()); //always sort phonetic matches along the top Collections.sort(wordlist, new Word()); //the non-phonetic matches can be listed below phoneticList.addAll(wordlist); return phoneticList; } /** * When we don't come up with any suggestions (probably because the threshold was too strict), * then pick the best guesses from the those words that have the same phonetic code. *

* This method is only needed to provide backward compatibility. * @see addBestGuess(String word, Vector wordList, int[][] matrix) * @param word - the word we are trying spell correct * @param wordList - the linked list that will get the best guess */ private void addBestGuess(String word, Vector wordList) { addBestGuess(word,wordList,null); } /** * When we don't come up with any suggestions (probably because the threshold was too strict), * then pick the best guesses from the those words that have the same phonetic code. * @param word - the word we are trying spell correct * @param Two dimensional array of int used to calculate * edit distance. Allocating this memory outside of the function will greatly improve efficiency. * @param wordList - the linked list that will get the best guess */ private void addBestGuess(String word, Vector wordList, int[][] matrix) { if(matrix == null) matrix = new int[0][0]; if (wordList.size() != 0) throw new InvalidParameterException("the wordList vector must be empty"); int bestScore = Integer.MAX_VALUE; String code = getCode(word); List simwordlist = getWords(code); LinkedList candidates = new LinkedList(); for (Iterator j = simwordlist.iterator(); j.hasNext();) { String similar = (String) j.next(); int distance = EditDistance.getDistance(word, similar, matrix); if (distance <= bestScore) { bestScore = distance; Word goodGuess = new Word(similar, distance); candidates.add(goodGuess); } } //now, only pull out the guesses that had the best score for (Iterator iter = candidates.iterator(); iter.hasNext();) { Word candidate = (Word) iter.next(); if (candidate.getCost() == bestScore) wordList.add(candidate); } } private Vector getWordsFromCode(String word, Hashtable codes) { Configuration config = Configuration.getConfiguration(); Vector result = new Vector(); int[][] matrix = new int[0][0]; final int configDistance = config.getInteger(Configuration.SPELL_THRESHOLD); for (Enumeration i = codes.keys(); i.hasMoreElements();) { String code = (String) i.nextElement(); List simwordlist = getWords(code); for (Iterator iter = simwordlist.iterator(); iter.hasNext();) { String similar = (String) iter.next(); int distance = EditDistance.getDistance(word, similar, matrix); if (distance < configDistance) { Word w = new Word(similar, distance); result.addElement(w); } } } return result; } /** * Returns the phonetic code representing the word. * @param word The word we want the phonetic code. * @return The value of the phonetic code for the word. */ public String getCode(String word) { return tf.transform(word); } /** * Returns a list of words that have the same phonetic code. * @param phoneticCode The phonetic code common to the list of words * @return A list of words having the same phonetic code */ protected abstract List getWords(String phoneticCode); /** * Returns true if the word is correctly spelled against the current word list. */ public boolean isCorrect(String word) { List possible = getWords(getCode(word)); if (possible.contains(word)) return true; //JMH should we always try the lowercase version. If I dont then capitalised //words are always returned as incorrect. else if (possible.contains(word.toLowerCase())) return true; return false; } } jazzy-0.5.2/src/com/swabunga/spell/event/0000755000175000017500000000000010341056556020244 5ustar twernertwernerjazzy-0.5.2/src/com/swabunga/spell/event/WordNotFoundException.java0000644000175000017500000000257710255105016025357 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.event; /** * An exception to indicate that there not enough words as expected. */ public class WordNotFoundException extends RuntimeException { //~ Constructors ............................................................ /** * Creates a new WordNotFoundException object. */ public WordNotFoundException() { super(); } /** * Creates a new WordNotFoundException object. * * @param s a message. */ public WordNotFoundException(String s) { super(s); } } jazzy-0.5.2/src/com/swabunga/spell/event/DefaultWordFinder.java0000644000175000017500000000723010255105016024447 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.event; /** * A basic word finder, which searches text for sequences of letters. * * @author Anthony Roy (ajr@antroy.co.uk) */ public class DefaultWordFinder extends AbstractWordFinder { //~ Instance/static variables ............................................... //~ Constructors ............................................................ /** * Creates a new DefaultWordFinder object. * * @param inText the String to search */ public DefaultWordFinder(String inText) { super(inText); } /** * Creates a new DefaultWordFinder object. */ public DefaultWordFinder() { super(); } //~ Methods ................................................................. /** * This method scans the text from the end of the last word, and returns a * new Word object corresponding to the next word. * * @return the next word. * @throws WordNotFoundException search string contains no more words. */ public Word next() { if (nextWord == null) { throw new WordNotFoundException("No more words found."); } currentWord.copy(nextWord); setSentenceIterator(currentWord); int i = currentWord.getEnd(); boolean finished = false; while (i < text.length() && !finished) { if (isWordChar(i)) { nextWord.setStart(i); int end = getNextWordEnd(text, i); nextWord.setText(text.substring(i, end)); finished = true; } i++; } if (!finished) nextWord = null; return currentWord; } /** * Returns the position in the string after the end of the next word. * Note that this return value should not be used as an index into the string * without checking first that it is in range, since it is possible for the * value text.length() to be returned by this method. */ private int getNextWordEnd(String text, int startPos) { // If we're dealing with a possible 'internet word' we need to provide // some special handling if (SpellChecker.isINETWord(text.substring(startPos))) { for (int i = startPos; i < text.length(); i++) { char ch = text.charAt(i); if (Character.isLetterOrDigit(ch)) continue; if (ch == '\r' || ch == '\n') return i; // Chop off any characters that might be enclosing the 'internet word'. eg ',",),] if (Character.isSpaceChar(ch)) if (i > 0 && Character.isLetterOrDigit(text.charAt(i - 1))) return i; else return i - 1; } return text.length(); } else { for (int i = startPos; i < text.length(); i++) { if (!isWordChar(i)) return i; } return text.length(); } } } jazzy-0.5.2/src/com/swabunga/spell/event/FileWordTokenizer.java0000644000175000017500000000547310255105016024514 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.event; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; /** * This class tokenizes a input file. * *

* Any takers to do this efficiently?? doesn't need to replace any words to * start with. I need this to get an idea of how quick the spell checker is. *

*/ public class FileWordTokenizer extends AbstractWordTokenizer { //~ Instance/static variables ............................................... // private File inFile; //~ Constructors ............................................................ /** * Creates a new FileWordTokenizer object. * * @param inputFile the file to work upon */ public FileWordTokenizer(File inputFile) { super(stringValue(inputFile)); } /** * Creates a new FileWordTokenizer object and associate a WordFinder to it's * processing. * * @param inputFile the file to word upon. * @param finder the specialize processing for words. */ public FileWordTokenizer(File inputFile, WordFinder finder) { super(finder); finder.setText(stringValue(inputFile)); } //~ Methods ................................................................. /** * Replaces the current word token * * @param s the new string * @throws WordNotFoundException current word not yet set. */ public void replaceWord(String s) { } private static String stringValue(File inFile) { File stringFile = inFile; StringBuffer out = new StringBuffer(""); try{ BufferedReader in = new BufferedReader(new FileReader(inFile)); char[] c = new char[100]; int count; while ((count = in.read(c, 0, c.length)) != -1){ out.append(c,0,count); } in.close(); } catch(IOException e){ System.err.println("File input error trying to open " + inFile.toString() + " : " + e); } return out.toString(); } }jazzy-0.5.2/src/com/swabunga/spell/event/SpellChecker.java0000644000175000017500000004641310255105020023444 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.event; import com.swabunga.spell.engine.Configuration; import com.swabunga.spell.engine.SpellDictionary; import com.swabunga.spell.engine.SpellDictionaryHashMap; import com.swabunga.spell.engine.Word; import com.swabunga.util.VectorUtility; import java.io.IOException; import java.util.*; /** * This is the main class for spell checking (using the new event based spell * checking). *

* By default, the class makes a user dictionary to accumulate added words. * Since this user directory has no file assign to persist added words, they * will be retained for the duration of the spell checker instance. * If you set a user dictionary like * {@link com.swabunga.spell.engine.SpellDictionaryHashMap SpellDictionaryHashMap} * to persist the added word, the user dictionary will have the possibility to * grow and be available across differents invocations of the spell checker. * * @author Jason Height (jheight@chariot.net.au) * 19 June 2002 */ public class SpellChecker { /** Flag indicating that the Spell Check completed without any errors present*/ public static final int SPELLCHECK_OK = -1; /** Flag indicating that the Spell Check completed due to user cancellation*/ public static final int SPELLCHECK_CANCEL = -2; private Vector eventListeners = new Vector(); private Vector dictionaries = new Vector(); private SpellDictionary userdictionary; private Configuration config = Configuration.getConfiguration(); /**This variable holds all of the words that are to be always ignored */ private Vector ignoredWords = new Vector(); private Hashtable autoReplaceWords = new Hashtable(); // added caching - bd // For cached operation a separate user dictionary is required private Map cache; private int threshold = 0; private int cacheSize = 0; /** * Constructs the SpellChecker. */ public SpellChecker() { try { userdictionary = new SpellDictionaryHashMap(); } catch (IOException e) { throw new RuntimeException("this exception should never happen because we are using null phonetic file"); } } /** * Constructs the SpellChecker. The default threshold is used * * @param dictionary The dictionary used for looking up words. */ public SpellChecker(SpellDictionary dictionary) { this(); addDictionary(dictionary); } /** * Constructs the SpellChecker with a threshold * * @param dictionary the dictionary used for looking up words. * @param threshold the cost value above which any suggestions are * thrown away */ public SpellChecker(SpellDictionary dictionary, int threshold) { this(dictionary); config.setInteger(Configuration.SPELL_THRESHOLD, threshold); } /** * Accumulates a dictionary at the end of the dictionaries list used * for looking up words. Adding a dictionary give the flexibility to * assign the base language dictionary, then a more technical, then... * * @param dictionary the dictionary to add at the end of the dictionary list. */ public void addDictionary(SpellDictionary dictionary) { if (dictionary == null) { throw new IllegalArgumentException("dictionary must be non-null"); } this.dictionaries.addElement(dictionary); } /** * Registers the user dictionary to which words are added. * * @param dictionary the dictionary to use when the user specify a new word * to add. */ public void setUserDictionary(SpellDictionary dictionary) { userdictionary = dictionary; } /** * Supply the instance of the configuration holding the spell checking engine * parameters. * * @return Current Configuration */ public Configuration getConfiguration() { return config; } /** * Adds a SpellCheckListener to the listeners list. * * @param listener The feature to be added to the SpellCheckListener attribute */ public void addSpellCheckListener(SpellCheckListener listener) { eventListeners.addElement(listener); } /** * Removes a SpellCheckListener from the listeners list. * * @param listener The listener to be removed from the listeners list. */ public void removeSpellCheckListener(SpellCheckListener listener) { eventListeners.removeElement(listener); } /** * Fires off a spell check event to the listeners. * * @param event The event that need to be processed by the spell checking * system. */ protected void fireSpellCheckEvent(SpellCheckEvent event) { for (int i = eventListeners.size() - 1; i >= 0; i--) { ((SpellCheckListener) eventListeners.elementAt(i)).spellingError(event); } } /** * This method clears the words that are currently being remembered as * Ignore All words and Replace All words. */ public void reset() { ignoredWords = new Vector(); autoReplaceWords = new Hashtable(); } /** * Checks the text string. *

* Returns the corrected string. * * @param text The text that need to be spelled checked * @return The text after spell checking * @deprecated use checkSpelling(WordTokenizer) */ public String checkString(String text) { StringWordTokenizer tokens = new StringWordTokenizer(text); checkSpelling(tokens); return tokens.getContext(); } /** * Verifies if the word that is being spell checked contains at least a * digit. * Returns true if this word contains a digit. * * @param word The word to analyze for digit. * @return true if the word contains at least a digit. */ private final static boolean isDigitWord(String word) { for (int i = word.length() - 1; i >= 0; i--) { if (Character.isDigit(word.charAt(i))) { return true; } } return false; } /** * Verifies if the word that is being spell checked contains an Internet * address. The method look for typical protocol or the habitual string * in the word: *

    *
  • http://
  • *
  • ftp://
  • *
  • https://
  • *
  • ftps://
  • *
  • www.
  • *
* * One limitation is that this method cannot currently recognize email * addresses. Since the 'word' that is passed in, may in fact contain * the rest of the document to be checked, it is not (yet!) a good * idea to scan for the @ character. * * @param word The word to analyze for an Internet address. * @return true if this word looks like an Internet address. */ public final static boolean isINETWord(String word) { String lowerCaseWord = word.toLowerCase(); return lowerCaseWord.startsWith("http://") || lowerCaseWord.startsWith("www.") || lowerCaseWord.startsWith("ftp://") || lowerCaseWord.startsWith("https://") || lowerCaseWord.startsWith("ftps://"); } /** * Verifies if the word that is being spell checked contains all * uppercases characters. * * @param word The word to analyze for uppercases characters * @return true if this word contains all upper case characters */ private final static boolean isUpperCaseWord(String word) { for (int i = word.length() - 1; i >= 0; i--) { if (Character.isLowerCase(word.charAt(i))) { return false; } } return true; } /** * Verifies if the word that is being spell checked contains lower and * upper cased characters. Note that a phrase beginning with an upper cased * character is not considered a mixed case word. * * @param word The word to analyze for mixed cases characters * @param startsSentence True if this word is at the start of a sentence * @return true if this word contains mixed case characters */ private final static boolean isMixedCaseWord(String word, boolean startsSentence) { int strLen = word.length(); boolean isUpper = Character.isUpperCase(word.charAt(0)); //Ignore the first character if this word starts the sentence and the first //character was upper cased, since this is normal behaviour if ((startsSentence) && isUpper && (strLen > 1)) isUpper = Character.isUpperCase(word.charAt(1)); if (isUpper) { for (int i = word.length() - 1; i > 0; i--) { if (Character.isLowerCase(word.charAt(i))) { return true; } } } else { for (int i = word.length() - 1; i > 0; i--) { if (Character.isUpperCase(word.charAt(i))) { return true; } } } return false; } /** * This method will fire the spell check event and then handle the event * action that has been selected by the user. * * @param tokenizer Description of the Parameter * @param event The event to handle * @return Returns true if the event action is to cancel the current spell checking, false if the spell checking should continue */ protected boolean fireAndHandleEvent(WordTokenizer tokenizer, SpellCheckEvent event) { fireSpellCheckEvent(event); String word = event.getInvalidWord(); //Work out what to do in response to the event. switch (event.getAction()) { case SpellCheckEvent.INITIAL: break; case SpellCheckEvent.IGNORE: break; case SpellCheckEvent.IGNOREALL: ignoreAll(word); break; case SpellCheckEvent.REPLACE: tokenizer.replaceWord(event.getReplaceWord()); break; case SpellCheckEvent.REPLACEALL: String replaceAllWord = event.getReplaceWord(); if (!autoReplaceWords.containsKey(word)) { autoReplaceWords.put(word, replaceAllWord); } tokenizer.replaceWord(replaceAllWord); break; case SpellCheckEvent.ADDTODICT: String addWord = event.getReplaceWord(); if (!addWord.equals(word)) tokenizer.replaceWord(addWord); userdictionary.addWord(addWord); break; case SpellCheckEvent.CANCEL: return true; default: throw new IllegalArgumentException("Unhandled case."); } return false; } /** * Adds a word to the list of ignored words * @param word The text of the word to ignore */ public void ignoreAll(String word) { if (!ignoredWords.contains(word)) { ignoredWords.addElement(word); } } /** * Adds a word to the user dictionary * @param word The text of the word to add */ public void addToDictionary(String word) { if (!userdictionary.isCorrect(word)) userdictionary.addWord(word); } /** * Indicates if a word is in the list of ignored words * @param word The text of the word check */ public boolean isIgnored(String word){ return ignoredWords.contains(word); } /** * Verifies if the word to analyze is contained in dictionaries. The order * of dictionary lookup is: *
    *
  • The default user dictionary or the one set through * {@link SpellChecker#setUserDictionary}
  • *
  • The dictionary specified at construction time, if any.
  • *
  • Any dictionary in the order they were added through * {@link SpellChecker#addDictionary}
  • *
* * @param word The word to verify that it's spelling is known. * @return true if the word is in a dictionary. */ public boolean isCorrect(String word) { if (userdictionary.isCorrect(word)) return true; for (Enumeration e = dictionaries.elements(); e.hasMoreElements();) { SpellDictionary dictionary = (SpellDictionary) e.nextElement(); if (dictionary.isCorrect(word)) return true; } return false; } /** * Produces a list of suggested word after looking for suggestions in various * dictionaries. The order of dictionary lookup is: *
    *
  • The default user dictionary or the one set through * {@link SpellChecker#setUserDictionary}
  • *
  • The dictionary specified at construction time, if any.
  • *
  • Any dictionary in the order they were added through * {@link SpellChecker#addDictionary}
  • *
* * @param word The word for which we want to gather suggestions * @param threshold the cost value above which any suggestions are * thrown away * @return the list of words suggested */ public List getSuggestions(String word, int threshold) { if (this.threshold != threshold && cache != null) { this.threshold = threshold; cache.clear(); } ArrayList suggestions = null; if (cache != null) suggestions = (ArrayList) cache.get(word); if (suggestions == null) { suggestions = new ArrayList(50); for (Enumeration e = dictionaries.elements(); e.hasMoreElements();) { SpellDictionary dictionary = (SpellDictionary) e.nextElement(); if (dictionary != userdictionary) VectorUtility.addAll(suggestions, dictionary.getSuggestions(word, threshold), false); } if (cache != null && cache.size() < cacheSize) cache.put(word, suggestions); } VectorUtility.addAll(suggestions, userdictionary.getSuggestions(word, threshold), false); suggestions.trimToSize(); return suggestions; } /** * Activates a cache with the maximum number of entries set to 300 */ public void setCache() { setCache(300); } /** * Activates a cache with specified size * @param size - max. number of cache entries (0 to disable chache) */ public void setCache(int size) { cacheSize = size; if (size == 0) cache = null; else cache = new HashMap((size + 2) / 3 * 4); } /** * This method is called to check the spelling of the words that are returned * by the WordTokenizer. *

* For each invalid word the action listeners will be informed with a new * SpellCheckEvent.

* * @param tokenizer The media containing the text to analyze. * @return Either SPELLCHECK_OK, SPELLCHECK_CANCEL or the number of errors found. The number of errors are those that * are found BEFORE any corrections are made. */ public final int checkSpelling(WordTokenizer tokenizer) { int errors = 0; boolean terminated = false; //Keep track of the previous word // String previousWord = null; while (tokenizer.hasMoreWords() && !terminated) { String word = tokenizer.nextWord(); //Check the spelling of the word if (!isCorrect(word)) { if ((config.getBoolean(Configuration.SPELL_IGNOREMIXEDCASE) && isMixedCaseWord(word, tokenizer.isNewSentence())) || (config.getBoolean(Configuration.SPELL_IGNOREUPPERCASE) && isUpperCaseWord(word)) || (config.getBoolean(Configuration.SPELL_IGNOREDIGITWORDS) && isDigitWord(word)) || (config.getBoolean(Configuration.SPELL_IGNOREINTERNETADDRESSES) && isINETWord(word))) { //Null event. Since we are ignoring this word due //to one of the above cases. } else { //We cant ignore this misspelt word //For this invalid word are we ignoring the misspelling? if (!isIgnored(word)) { errors++; //Is this word being automagically replaced if (autoReplaceWords.containsKey(word)) { tokenizer.replaceWord((String) autoReplaceWords.get(word)); } else { //JMH Need to somehow capitalise the suggestions if //ignoreSentenceCapitalisation is not set to true //Fire the event. List suggestions = getSuggestions(word, config.getInteger(Configuration.SPELL_THRESHOLD)); if (capitalizeSuggestions(word, tokenizer)) suggestions = makeSuggestionsCapitalized(suggestions); SpellCheckEvent event = new BasicSpellCheckEvent(word, suggestions, tokenizer); terminated = fireAndHandleEvent(tokenizer, event); } } } } else { //This is a correctly spelt word. However perform some extra checks /* * JMH TBD //Check for multiple words * if (!ignoreMultipleWords &&) { * } */ //Check for capitalisation if (isSupposedToBeCapitalized(word, tokenizer)) { errors++; StringBuffer buf = new StringBuffer(word); buf.setCharAt(0, Character.toUpperCase(word.charAt(0))); Vector suggestion = new Vector(); suggestion.addElement(new Word(buf.toString(), 0)); SpellCheckEvent event = new BasicSpellCheckEvent(word, suggestion, tokenizer); terminated = fireAndHandleEvent(tokenizer, event); } } } if (terminated) return SPELLCHECK_CANCEL; else if (errors == 0) return SPELLCHECK_OK; else return errors; } private List makeSuggestionsCapitalized(List suggestions) { Iterator iterator = suggestions.iterator(); while(iterator.hasNext()) { Word word = (Word)iterator.next(); String suggestion = word.getWord(); StringBuffer stringBuffer = new StringBuffer(suggestion); stringBuffer.setCharAt(0, Character.toUpperCase(suggestion.charAt(0))); word.setWord(stringBuffer.toString()); } return suggestions; } private boolean isSupposedToBeCapitalized(String word, WordTokenizer wordTokenizer) { boolean configCapitalize = !config.getBoolean(Configuration.SPELL_IGNORESENTENCECAPITALIZATION); return configCapitalize && wordTokenizer.isNewSentence() && Character.isLowerCase(word.charAt(0)); } private boolean capitalizeSuggestions(String word, WordTokenizer wordTokenizer) { // if SPELL_IGNORESENTENCECAPITALIZATION and the initial word is capitalized, suggestions should also be capitalized // if !SPELL_IGNORESENTENCECAPITALIZATION, capitalize suggestions only for the first word in a sentence boolean configCapitalize = !config.getBoolean(Configuration.SPELL_IGNORESENTENCECAPITALIZATION); boolean uppercase = Character.isUpperCase(word.charAt(0)); return (configCapitalize && wordTokenizer.isNewSentence()) || (!configCapitalize && uppercase); } } jazzy-0.5.2/src/com/swabunga/spell/event/BasicSpellCheckEvent.java0000644000175000017500000001146510255105016025065 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.event; import java.util.List; /** This event is fired off by the SpellChecker and is passed to the * registered SpellCheckListeners * * @author Jason Height (jheight@chariot.net.au) */ class BasicSpellCheckEvent implements SpellCheckEvent { /**The list holding the suggested Word objects for the misspelt word*/ private List suggestions; /**The misspelt word*/ private String invalidWord; /**The action to be done when the event returns*/ private short action = INITIAL; /**Contains the word to be replaced if the action is REPLACE or REPLACEALL*/ private String replaceWord = null; private String context; private int startPosition; /**Constructs the SpellCheckEvent * @param invalidWord The word that is misspelt * @param suggestions A list of Word objects that are suggested to replace the currently misspelt word * @param tokenizer The reference to the tokenizer that caused this * event to fire. */ public BasicSpellCheckEvent(String invalidWord, List suggestions, WordTokenizer tokenizer) { this.invalidWord = invalidWord; this.suggestions = suggestions; this.context = tokenizer.getContext(); this.startPosition = tokenizer.getCurrentWordPosition(); } /** Returns the list of suggested Word objects * @return A list of words phonetically close to the misspelt word */ public List getSuggestions() { return suggestions; } /** Returns the currently misspelt word * @return The text misspelt */ public String getInvalidWord() { return invalidWord; } /** Returns the context in which the misspelt word is used * @return The text containing the context */ public String getWordContext() { //JMH TBD return null; } /** Returns the start position of the misspelt word in the context * @return The position of the word */ public int getWordContextPosition() { return startPosition; } /** Returns the action type the user has to handle * @return The type of action the event is carrying */ public short getAction() { return action; } /** Returns the text to replace * @return the text of the word to replace */ public String getReplaceWord() { return replaceWord; } /** Set the action to replace the currently misspelt word with the new word * @param newWord The word to replace the currently misspelt word * @param replaceAll If set to true, the SpellChecker will replace all * further occurrences of the misspelt word without firing a SpellCheckEvent. */ public void replaceWord(String newWord, boolean replaceAll) { if (action != INITIAL) throw new IllegalStateException("The action can can only be set once"); if (replaceAll) action = REPLACEALL; else action = REPLACE; replaceWord = newWord; } /** * Set the action it ignore the currently misspelt word. * @param ignoreAll If set to true, the SpellChecker will replace all * further occurrences of the misspelt word without firing a SpellCheckEvent. */ public void ignoreWord(boolean ignoreAll) { if (action != INITIAL) throw new IllegalStateException("The action can can only be set once"); if (ignoreAll) action = IGNOREALL; else action = IGNORE; } /** Set the action to add a new word into the dictionary. This will also replace the * currently misspelt word. * @param newWord The new word to add to the dictionary. */ public void addToDictionary(String newWord) { if (action != INITIAL) throw new IllegalStateException("The action can can only be set once"); action = ADDTODICT; replaceWord = newWord; } /** Set the action to terminate processing of the spellchecker. */ public void cancel() { if (action != INITIAL) throw new IllegalStateException("The action can can only be set once"); action = CANCEL; } }jazzy-0.5.2/src/com/swabunga/spell/event/StringWordTokenizer.java0000644000175000017500000000532610255105016025100 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.event; /** * This class tokenizes a input string. * *

* It also allows for the string to be altered by calls to replaceWord(). The result after the spell * checking is completed is available to the call to getContext. *

* * @author Jason Height (jheight@chariot.net.au) * @author Anthony Roy (ajr@antroy.co.uk) */ public class StringWordTokenizer extends AbstractWordTokenizer { //~ Constructors ............................................................ /** * Creates a new StringWordTokenizer object. * * @param s the string to tokenize. */ public StringWordTokenizer(String s) { super(s); } /** * Creates a new StringWordTokenizer object. * * @param wf the custom WordFinder to use in tokenizing. Note * that the string to tokenize will be encapsulated within the WordFinder. */ public StringWordTokenizer(WordFinder wf) { super(wf); } /** * Creates a new StringWordTokenizer object. * @param s the string to work on * @param finder the custom WordFinder to use in tokenizing. Note * that the string to tokenize will be encapsulated within the WordFinder. */ public StringWordTokenizer(String s, WordFinder finder) { super(finder); finder.setText(s); } //~ Methods ................................................................. /** * * @deprecated use getContext() instead as per the WordTokenizer * interface specification. * @return the final text. */ public String getFinalText() { return getContext(); } /** * Replace the current word in the iteration with the String s. * * @param s the String to replace the current word. * @throws WordNotFoundException current word not yet set. */ public void replaceWord(String s) { finder.replace(s); } }jazzy-0.5.2/src/com/swabunga/spell/event/DocumentWordTokenizer.java0000644000175000017500000002204110255105016025401 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.event; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.Segment; import javax.swing.text.StyledDocument; import javax.swing.text.AttributeSet; import java.text.BreakIterator; /** This class tokenizes a swing document model. It also allows for the * document model to be changed when corrections occur. * * @author Jason Height (jheight@chariot.net.au) */ public class DocumentWordTokenizer implements WordTokenizer { /** Holds the start character position of the current word*/ private int currentWordPos = 0; /** Holds the end character position of the current word*/ private int currentWordEnd = 0; /** Holds the start character position of the next word*/ private int nextWordPos = -1; /** The actual text that is being tokenized*/ private Document document; /** The character iterator over the document*/ private Segment text; /** The cumulative word count that have been processed*/ private int wordCount = 0; /** Flag indicating if there are any more tokens (words) left*/ private boolean moreTokens = true; /** Is this a special case where the currentWordStart, currntWordEnd and * nextWordPos have already been calculated. (see nextWord) */ private boolean first = true; private BreakIterator sentenceIterator; private boolean startsSentence = true; /** * Creates a new DocumentWordTokenizer to work on a document * @param document The document to spell check */ public DocumentWordTokenizer(Document document) { this.document = document; //Create a text segment over the entire document text = new Segment(); sentenceIterator = BreakIterator.getSentenceInstance(); try { document.getText(0, document.getLength(), text); sentenceIterator.setText(text); currentWordPos = getNextWordStart(text, 0); //If the current word pos is -1 then the string was all white space if (currentWordPos != -1) { currentWordEnd = getNextWordEnd(text, currentWordPos); nextWordPos = getNextWordStart(text, currentWordEnd); } else { moreTokens = false; } } catch (BadLocationException ex) { moreTokens = false; } } /** This helper method will return the start character of the next * word in the buffer from the start position */ private static int getNextWordStart(Segment text, int startPos) { if (startPos <= text.getEndIndex()) for (char ch = text.setIndex(startPos); ch != Segment.DONE; ch = text.next()) { if (Character.isLetterOrDigit(ch)) { return text.getIndex(); } } return -1; } /** This helper method will return the end of the next word in the buffer. * */ private static int getNextWordEnd(Segment text, int startPos) { for (char ch = text.setIndex(startPos); ch != Segment.DONE; ch = text.next()) { if (!Character.isLetterOrDigit(ch)) { if (ch == '-' || ch == '\'') { // handle ' and - inside words char ch2 = text.next(); text.previous(); if (ch2 != Segment.DONE && Character.isLetterOrDigit(ch2)) continue; } return text.getIndex(); } } return text.getEndIndex(); } /** * Indicates if there are more words left * @return true if more words can be found in the text. */ public boolean hasMoreWords() { return moreTokens; } /** * Sets the current word position at the start of the word containing * the char at position pos. This way a call to nextWord() will return * this word. * * @param pos position in the word we want to set as current. */ public void posStartFullWordFrom(int pos){ currentWordPos=text.getBeginIndex(); if(pos>text.getEndIndex()) pos=text.getEndIndex(); for (char ch = text.setIndex(pos); ch != Segment.DONE; ch = text.previous()) { if (!Character.isLetterOrDigit(ch)) { if (ch == '-' || ch == '\'') { // handle ' and - inside words char ch2 = text.previous(); text.next(); if (ch2 != Segment.DONE && Character.isLetterOrDigit(ch2)) continue; } currentWordPos=text.getIndex()+1; break; } } //System.out.println("CurPos:"+currentWordPos); if(currentWordPos==0) first=true; moreTokens=true; currentWordEnd = getNextWordEnd(text, currentWordPos); nextWordPos = getNextWordStart(text, currentWordEnd + 1); } /** * Returns the number of word tokens that have been processed thus far * @return the number of words found so far. */ public int getCurrentWordPosition() { return currentWordPos; } /** * Returns an index representing the end location of the current word in the text. * @return index of the end of the current word in the text. */ public int getCurrentWordEnd() { return currentWordEnd; } /** * This returns the next word in the iteration. Note that any implementation should return * the current word, and then replace the current word with the next word found in the * input text (if one exists). * @return the next word in the iteration. */ public String nextWord() { if (!first) { currentWordPos = nextWordPos; currentWordEnd = getNextWordEnd(text, currentWordPos); nextWordPos = getNextWordStart(text, currentWordEnd + 1); } int current = sentenceIterator.current(); if (current == currentWordPos) startsSentence = true; else { startsSentence = false; if (currentWordEnd > current) sentenceIterator.next(); } //The nextWordPos has already been populated String word = null; try { word = document.getText(currentWordPos, currentWordEnd - currentWordPos); } catch (BadLocationException ex) { moreTokens = false; } wordCount++; first = false; if (nextWordPos == -1) moreTokens = false; return word; } /** * Returns the number of word tokens that have been processed thus far * @return the number of words found so far. */ public int getCurrentWordCount() { return wordCount; } /** Replaces the current word token * @param newWord The new word to replace the misspelt one */ public void replaceWord(String newWord) { AttributeSet attr=null; if (currentWordPos != -1) { try { if(document instanceof StyledDocument) attr=((StyledDocument)document).getCharacterElement(currentWordPos).getAttributes(); document.remove(currentWordPos, currentWordEnd - currentWordPos); document.insertString(currentWordPos, newWord, null); //Need to reset the segment document.getText(0, document.getLength(), text); } catch (BadLocationException ex) { throw new RuntimeException(ex.getMessage()); } //Position after the newly replaced word(s) first = true; currentWordPos = getNextWordStart(text, currentWordPos + newWord.length()); if (currentWordPos != -1) { currentWordEnd = getNextWordEnd(text, currentWordPos); nextWordPos = getNextWordStart(text, currentWordEnd); sentenceIterator.setText(text); sentenceIterator.following(currentWordPos); } else moreTokens = false; } } /** Returns the current text that is being tokenized (includes any changes * that have been made) * @return The text, including changes. */ public String getContext() { return text.toString(); } /** Indicates if the current word is at the start of a sentence * @return true if the current word is at the start of a sentence */ public boolean isNewSentence() { // BreakIterator doesn't work when the first word in a sentence is not capitalised, // but we need to check for capitalisation if (startsSentence || currentWordPos < 2) return(true); String textBefore = null; try { textBefore = document.getText(currentWordPos-2, 2); } catch (BadLocationException ex) { return(false); } return(textBefore != null && ".".equals(textBefore.trim())); } }jazzy-0.5.2/src/com/swabunga/spell/event/AbstractWordTokenizer.java0000644000175000017500000001116410255105020025365 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.event; import java.text.BreakIterator; /** * This class tokenizes a input string. * *

* It also allows for the string to be mutated. The result after the spell * checking is completed is available to the call to getFinalText *

* * @author Jason Height(jheight@chariot.net.au) * @author Anthony Roy (ajr@antroy.co.uk) */ public abstract class AbstractWordTokenizer implements WordTokenizer { //~ Instance/static variables ............................................... /** The word being analyzed */ protected Word currentWord; /** The word finder used to filter out words which are non pertinent to * spell checking */ protected WordFinder finder; /** An iterator to work through the sentence */ protected BreakIterator sentenceIterator; /** The cumulative word count that have been processed */ protected int wordCount = 0; //~ Constructors ............................................................ /** * Creates a new AbstractWordTokenizer object. * * @param text the text to process. */ public AbstractWordTokenizer(String text) { this(new DefaultWordFinder(text)); } /** * Creates a new AbstractWordTokenizer object. * * @param wf the custom WordFinder to use in searching for words. */ public AbstractWordTokenizer(WordFinder wf) { this.finder = wf; } //~ Methods ................................................................. /** * Returns the current number of words that have been processed * * @return number of words so far iterated. */ public int getCurrentWordCount() { return wordCount; } /** * Returns the end of the current word in the text * * @return index in string of the end of the current word. * @throws WordNotFoundException current word has not yet been set. */ public int getCurrentWordEnd() { if (currentWord == null) { throw new WordNotFoundException("No Words in current String"); } return currentWord.getEnd(); } /** * Returns the index of the start of the current word in the text * * @return index in string of the start of the current word. * @throws WordNotFoundException current word has not yet been set. */ public int getCurrentWordPosition() { if (currentWord == null) { throw new WordNotFoundException("No Words in current String"); } return currentWord.getStart(); } /** * Returns true if there are more words that can be processed in the string * * @return true if there are further words in the text. */ public boolean hasMoreWords() { return finder.hasNext(); } /** * Returns searches for the next word in the text, and returns that word. * * @return the string representing the current word. * @throws WordNotFoundException search string contains no more words. */ public String nextWord() { currentWord = finder.next(); return currentWord.getText(); } /** * Replaces the current word token * * @param newWord replacement word. * @throws WordNotFoundException current word has not yet been set. */ public abstract void replaceWord(String newWord); /** * Returns the current text that is being tokenized (includes any changes * that have been made) * * @return the text being tokenized. */ public String getContext() { return finder.toString(); } /** * returns true if the current word is at the start of a sentence * * @return true if the current word starts a sentence. * @throws WordNotFoundException current word has not yet been set. */ public boolean isNewSentence() { return finder.startsSentence(); } }jazzy-0.5.2/src/com/swabunga/spell/event/TeXWordFinder.java0000644000175000017500000001311110255105016023556 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ //{{{ package and imports //:folding=explicit: package com.swabunga.spell.event; import java.util.Collection; import java.util.HashSet; /** * A word finder for TeX and LaTeX documents, which searches text for * sequences of letters, but ignores any commands and environments as well * as Math environments. * * @author Anthony Roy (ajr@antroy.co.uk) */ //}}} public class TeXWordFinder extends AbstractWordFinder { //{{{ ~ Instance/static variables ............................................... private boolean IGNORE_COMMENTS = true; private HashSet user_defined_ignores = new HashSet(); private int regex_user_defined_ignores = STRING_EXPR; /** * A type where string expressions are used to define expression to ignore */ public static final int STRING_EXPR = 0; /** * A type where regular expressions are used to define expression to ignore */ public static final int REG_EXPR = 1; // public static final int GLOB_EXPR = 2; //}}} //{{{ ~ Constructors ............................................................ /** * Creates a new DefaultWordFinder object. * * @param inText the text to search. */ public TeXWordFinder(String inText) { super(inText); } /** * Creates a new DefaultWordFinder object. */ public TeXWordFinder() { super(); } //}}} //{{{ ~ Methods ................................................................. /** * This method scans the text from the end of the last word, and returns a * new Word object corresponding to the next word. * * @return the next word. * @throws WordNotFoundException search string contains no more words. */ public Word next() { //{{{ if (!hasNext())//currentWord == null) throw new WordNotFoundException("No more words found."); currentWord.copy(nextWord); setSentenceIterator(currentWord); int i = currentWord.getEnd(); boolean finished = false; boolean started = false; search: while (i < text.length() && !finished) { //{{{ Find words. if (!started && isWordChar(i)) { nextWord.setStart(i++); started = true; continue search; } else if (started) { if (isWordChar(i)) { i++; continue search; } else { nextWord.setText(text.substring(nextWord.getStart(), i)); finished = true; break search; } } //}}} // Ignores should be in order of importance and then specificity. int j = i; // Ignore Comments: j = ignore(j, '%', '\n'); // Ignore Maths: j = ignore(j, "$$", "$$"); j = ignore(j, '$', '$'); // Ignore user defined. j = ignoreUserDefined(j); // Ignore certain command parameters. j = ignore(j, "\\newcommand", "}"); j = ignore(j, "\\documentclass", "}"); j = ignore(j, "\\usepackage", "}"); j = ignore(j, "\\newcounter{", "}"); j = ignore(j, "\\setcounter{", "}"); j = ignore(j, "\\addtocounter{", "}"); j = ignore(j, "\\value{", "}"); j = ignore(j, "\\arabic{", "}"); j = ignore(j, "\\usecounter{", "}"); j = ignore(j, "\\newenvironment", "}"); j = ignore(j, "\\setlength", "}"); j = ignore(j, "\\setkeys", "}"); // Ignore environment names. j = ignore(j, "\\begin{", "}"); j = ignore(j, "\\end{", "}"); if (i != j){ i = j; continue search; } // Ignore commands. j = ignore(j, '\\'); if (i != j){ i = j; continue search; } i++; } if (!started) { nextWord = null; } else if (!finished) { nextWord.setText(text.substring(nextWord.getStart(), i)); } return currentWord; } //}}} /** * This method is used to import a user defined set of either strings or regular expressions to ignore. * @param expressions a collection of Objects whose toString() value should be the expression. Typically String objects. * @param regex is an integer specifying the type of expression to use. e.g. REG_EXPR, STRING_EXPR. */ public void addUserDefinedIgnores(Collection expressions, int regex){ user_defined_ignores.addAll(expressions); regex_user_defined_ignores = regex; } private int ignoreUserDefined(int i){ return i; } /** * Define if comments contents are ignored during spell checking * @param ignore an indication if comments content is to be ignored */ public void setIgnoreComments(boolean ignore) { IGNORE_COMMENTS = ignore; } //}}} } jazzy-0.5.2/src/com/swabunga/spell/event/WordFinder.java0000644000175000017500000000666710255105016023157 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.event; /** *

An interface for objects which take a String as input, and iterates through * the words in the string. *

* *

* When the object is instantiated, and before the first call to next() is made, * the following methods should throw a WordNotFoundException:
* current(), * startsSentence() and replace(). *

* *

A call to next() when hasMoreWords() returns false * should throw a WordNotFoundException.

* @author Jason Height (jheight@chariot.net.au) */ public interface WordFinder { //~ Methods ................................................................. /** * This method returns the text through which the WordFinder is iterating. * The text may have been modified through calls to replace(). * * @return the (possibly modified) text being searched. */ public String getText(); /** * This method resets the text through which the WordFinder iterates. * It must also re-initialize the WordFinder. * * @param newText the new text to search. */ public void setText(String newText); /** * This method should return the Word object representing the current word * in the iteration. * This method should not affect the state of the WordFinder object. * * @return the current Word object. * @throws WordNotFoundException current word has not yet been set. */ public Word current(); /** * Tests the finder to see if any more words are available. * * @return true if more words are available. */ public boolean hasNext(); /** * This method should return the Word object representing the next word * in the iteration (the first word if next() has not yet been called.) * * @return the next Word in the iteration. * @throws WordNotFoundException search string contains no more words. */ public Word next(); /** * This method should replace the current Word object with a Word object * representing the String newWord. * * @param newWord the word to replace the current word with. * @throws WordNotFoundException current word has not yet been set. */ public void replace(String newWord); /** * Indicates if the current word starts a new sentence. * @return true if the current word starts a new sentence. * @throws WordNotFoundException current word has not yet been set. */ public boolean startsSentence(); // public void setText(); } jazzy-0.5.2/src/com/swabunga/spell/event/JavaWordFinder.java0000644000175000017500000000757310255105016023756 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.event; /** * A word finder Java source files, which searches text for sequences of * letters formated as Java comments. * * @author Anthony Roy (ajr@antroy.co.uk) */ public class JavaWordFinder extends AbstractWordFinder { //~ Instance/static variables ............................................... private boolean inComment; //~ Constructors ............................................................ /** * Creates a new JavaWordFinder object. * * @param inText the String to search */ public JavaWordFinder(String inText) { super(inText); } /** * Creates a new JavaWordFinder object. */ public JavaWordFinder() { super(); } //~ Methods ................................................................. /** * This method scans the text from the end of the last word, and returns a * new Word object corresponding to the next word. * * @return the next word. * @throws WordNotFoundException search string contains no more words. */ public Word next() { if (nextWord == null) { throw new WordNotFoundException("No more words found."); } currentWord.copy(nextWord); int current = sentenceIterator.current(); setSentenceIterator(currentWord); int i = currentWord.getEnd(); boolean finished = false; boolean started = false; search: while (i < text.length() && !finished) { i = ignore(i, '@'); i = ignore(i, "", ""); i = ignore(i, "", ""); i = ignore(i, '<', '>'); if (i >= text.length()) break search; char currentLetter = text.charAt(i); if (inComment) { //Reset on new line. if (currentLetter == '\n') { inComment = false; i++; continue search; } else if (!isWordChar(i)) { i++; continue search; } //Find words. while (i < text.length() - 1) { if (!started && isWordChar(i)) { nextWord.setStart(i); started = true; } else if (started && !isWordChar(i)) { nextWord.setText(text.substring(nextWord.getStart(), i)); finished = true; break search; } currentLetter = text.charAt(++i); } } else if (currentLetter == '*') { inComment = true; i++; } else { i++; } } if (!started) { nextWord = null; } else if (!finished) { nextWord.setText(text.substring(nextWord.getStart(), i)); } return currentWord; } /** * Initializes this word finder */ protected void init() { // sentenceIterator = BreakIterator.getSentenceInstance(); // sentenceIterator.setText(text); super.init(); inComment = false; } } jazzy-0.5.2/src/com/swabunga/spell/event/SpellCheckEvent.java0000644000175000017500000000762010255105020024114 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.event; import java.util.List; /** * This event is fired off by the SpellChecker and is passed to the * registered SpellCheckListeners *

* As far as I know, we will only require one implementation of the SpellCheckEvent * (BasicSpellCheckEvent) but I have defined this interface just in case. The * BasicSpellCheckEvent implementation is currently package private. * * @author Jason Height (jheight@chariot.net.au) */ public interface SpellCheckEvent { /** Field indicating that the incorrect word should be ignored*/ public static final short IGNORE = 0; /** Field indicating that the incorrect word should be ignored forever*/ public static final short IGNOREALL = 1; /** Field indicating that the incorrect word should be replaced*/ public static final short REPLACE = 2; /** Field indicating that the incorrect word should be replaced always*/ public static final short REPLACEALL = 3; /** Field indicating that the incorrect word should be added to the dictionary*/ public static final short ADDTODICT = 4; /** Field indicating that the spell checking should be terminated*/ public static final short CANCEL = 5; /** Initial case for the action */ public static final short INITIAL = -1; /** Returns the list of suggested Word objects * @return A list of words phonetically close to the misspelt word */ public List getSuggestions(); /** Returns the currently misspelt word * @return The text misspelt */ public String getInvalidWord(); /** Returns the context in which the misspelt word is used * @return The text containing the context */ public String getWordContext(); /** Returns the start position of the misspelt word in the context * @return The position of the word */ public int getWordContextPosition(); /** Returns the action type the user has to handle * @return The type of action the event is carrying */ public short getAction(); /** Returns the text to replace * @return the text of the word to replace */ public String getReplaceWord(); /** Set the action to replace the currently misspelt word with the new word * @param newWord The word to replace the currently misspelt word * @param replaceAll If set to true, the SpellChecker will replace all * further occurrences of the misspelt word without firing a SpellCheckEvent. */ public void replaceWord(String newWord, boolean replaceAll); /** Set the action it ignore the currently misspelt word. * @param ignoreAll If set to true, the SpellChecker will replace all * further occurrences of the misspelt word without firing a SpellCheckEvent. */ public void ignoreWord(boolean ignoreAll); /** Set the action to add a new word into the dictionary. This will also replace the * currently misspelt word. *@param newWord The new word to add */ public void addToDictionary(String newWord); /** Set the action to terminate processing of the spell checker. */ public void cancel(); }jazzy-0.5.2/src/com/swabunga/spell/event/WordTokenizer.java0000644000175000017500000000770410255105016023713 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.event; /** *

An interface for objects which take a text-based media as input, and iterate through * the words in the text stored in that media. Examples of such media could be Strings, * Documents, Files, TextComponents etc. *

* *

* When the object is instantiated, and before the first call to next() is made, * the following methods should throw a WordNotFoundException:
* getCurrentWordEnd(), getCurrentWordPosition(), * isNewSentence() and replaceWord(). *

* *

A call to next() when hasMoreWords() returns false * should throw a WordNotFoundException.

* @author Jason Height (jheight@chariot.net.au) */ public interface WordTokenizer { //~ Methods ................................................................. /** * Returns the context text that is being tokenized (should include any * changes that have been made). * @return the text being searched. */ public String getContext(); /** * Returns the number of word tokens that have been processed thus far * @return the number of words found so far. */ public int getCurrentWordCount(); /** * Returns an index representing the end location of the current word in the text. * @return index of the end of the current word in the text. * @throws WordNotFoundException current word has not yet been set. */ public int getCurrentWordEnd(); /** * Returns an index representing the start location of the current word in the text. * @return index of the start of the current word in the text. * @throws WordNotFoundException current word has not yet been set. */ public int getCurrentWordPosition(); /** * Returns true if the current word is at the start of a sentence * @return true if the current word starts a sentence. * @throws WordNotFoundException current word has not yet been set. */ public boolean isNewSentence(); /** * Indicates if there are more words left * @return true if more words can be found in the text. */ public boolean hasMoreWords(); /** * This returns the next word in the iteration. Note that any implementation should return * the current word, and then replace the current word with the next word found in the * input text (if one exists). * @return the next word in the iteration. * @throws WordNotFoundException search string contains no more words. */ public String nextWord(); /** * Replaces the current word token * *

* When a word is replaced care should be taken that the WordTokenizer * repositions itself such that the words that were added aren't rechecked. * Of course this is not mandatory, maybe there is a case when an * application doesn't need to do this. *

* @param newWord the string which should replace the current word. * @throws WordNotFoundException current word has not yet been set. */ public void replaceWord(String newWord); }jazzy-0.5.2/src/com/swabunga/spell/event/AbstractWordFinder.java0000644000175000017500000002744610255105020024634 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.event; import java.text.BreakIterator; /** * Defines common methods and behaviour for the various word finding * subclasses. * * @author Anthony Roy (ajr@antroy.co.uk) */ public abstract class AbstractWordFinder implements WordFinder { //~ Instance/static variables ............................................. /** The word being analyzed */ protected Word currentWord; /** The word following the current one */ protected Word nextWord; /** Indicate if the current word starts a new sentence */ protected boolean startsSentence; /** Holds the text to analyze */ protected String text; /** An iterator to work through the sentence */ protected BreakIterator sentenceIterator; //~ Constructors .......................................................... /** * Creates a new AbstractWordFinder object. * * @param inText the String to iterate through. */ public AbstractWordFinder(String inText) { text = inText; setup(); } /** * Creates a new default AbstractWordFinder object. */ public AbstractWordFinder() { text = ""; setup(); } //~ Methods ............................................................... /** * This method scans the text from the end of the last word, and returns * a new Word object corresponding to the next word. * * @return the following word. */ public abstract Word next(); /** * Return the text being searched. May have changed since first set * through calls to replace. * * @return the text being searched. */ public String getText() { return text; } /** * Defines the text to search. * @param newText The text to be analyzed */ public void setText(String newText) { text = newText; setup(); } /** * Returns the current word in the iteration . * * @return the current word. * @throws WordNotFoundException current word has not yet been set. */ public Word current() { if (currentWord == null) { throw new WordNotFoundException("No Words in current String"); } return currentWord; } /** * Indicates if there is some more word to analyze * @return true if there are further words in the string. */ public boolean hasNext() { return nextWord != null; } /** * Replace the current word in the search with a replacement string. * * @param newWord the replacement string. * @throws WordNotFoundException current word has not yet been set. */ public void replace(String newWord) { if (currentWord == null) { throw new WordNotFoundException("No Words in current String"); } StringBuffer sb = new StringBuffer(text.substring(0, currentWord.getStart())); sb.append(newWord); sb.append(text.substring(currentWord.getEnd())); int diff = newWord.length() - currentWord.getText().length(); currentWord.setText(newWord); /* Added Conditional to ensure a NullPointerException is avoided (11 Feb 2003) */ if (nextWord != null) { nextWord.setStart(nextWord.getStart() + diff); } text = sb.toString(); sentenceIterator.setText(text); int start = currentWord.getStart(); sentenceIterator.following(start); startsSentence = sentenceIterator.current() == start; } /** * @return true if the current word starts a new sentence. * @throws WordNotFoundException current word has not yet been set. */ public boolean startsSentence() { if (currentWord == null) { throw new WordNotFoundException("No Words in current String"); } return startsSentence; } /** * Return the text being searched. May have changed since first set * through calls to replace. * * @return the text being searched. */ public String toString() { return text; } /** * Adjusts the sentence iterator and the startSentence flag according to the * currentWord. * @param wd the wd parameter is not presently used. */ protected void setSentenceIterator(Word wd) { int current = sentenceIterator.current(); if (current == currentWord.getStart()) startsSentence = true; else { startsSentence = false; if (currentWord.getEnd() > current) { sentenceIterator.next(); } } } /** * Indicates if the character at the specified position is acceptable as * part of a word. To be acceptable, the character need to be a letter * or a digit. It is also acceptable if the character is one of ''', '@', * '.' or '_' and is preceded and followed by letter or digit. * @param posn The character position to analyze. * @return true if the character is a letter or digit */ //Added more intelligent character recognition (11 Feb '03) protected boolean isWordChar(int posn) { boolean out = false; char curr = text.charAt(posn); if ((posn == 0) || (posn == text.length() - 1)) { return Character.isLetterOrDigit(curr); } char prev = text.charAt(posn - 1); char next = text.charAt(posn + 1); switch (curr) { case '\'': case '@': case '.': case '_': out = (Character.isLetterOrDigit(prev) && Character.isLetterOrDigit(next)); break; default : out = Character.isLetterOrDigit(curr); } return out; } /** * Indicates if the character at the specified character is acceptable as * part of a word. To be acceptable, the character need to be a letter * or a digit or a ' (an apostrophe). * @param c The character to evaluates if it can be part of a word * @return true if the character is a letter, digit or a ' (an apostrophe). */ protected boolean isWordChar(char c) { boolean out = false; if (Character.isLetterOrDigit(c) || (c == '\'')) { out = true; } return out; } /** * Ignores or skip over text starting from the index position specified * if it contains the startIgnore, and until the * first non letter or digit character is encountered or end of text is * detected. * @param index The start position in text. * @param startIgnore The character that should be at index * position to start skipping through. * @return The index position pointing after the skipped characters or the * original index if the ignore condition could not be met. */ protected int ignore(int index, char startIgnore) { return ignore(index, new Character(startIgnore), null); } /** * Ignores or skip over text starting from the index position specified * if it contains the startIgnore, and until the * endIgnore character is encountered or end of text is * detected. * @param index The start position in text. * @param startIgnore The character that should be at index * position to start skipping through. * @param endIgnore The character which mark the end of skipping through. If * the value of endIgnore is null, skipping characters stop * at first non letter or digit character. * @return The index position pointing after the skipped characters or the * original index if the ignore condition could not be met. */ protected int ignore(int index, char startIgnore, char endIgnore) { return ignore(index, new Character(startIgnore), new Character(endIgnore)); } /** * Ignores or skip over text starting from the index position specified * if it contains the startIgnore, and until the * endIgnore character is encountered or end of text is * detected. * @param index The start position in text. * @param startIgnore The character that should be at index * position to start skipping through. * @param endIgnore The character which mark the end of skipping through. If * the value of endIgnore is null, skipping characters stop * at first non letter or digit character. * @return The index position pointing after the skipped characters or the * original index if the ignore condition could not be met. */ protected int ignore(int index, Character startIgnore, Character endIgnore) { int newIndex = index; if (newIndex < text.length()) { Character curChar = new Character(text.charAt(newIndex)); if (curChar.equals(startIgnore)) { newIndex++; while (newIndex < text.length()) { curChar = new Character(text.charAt(newIndex)); if (endIgnore != null && curChar.equals(endIgnore)){ newIndex++; break; } else if (endIgnore == null && !Character.isLetterOrDigit(curChar.charValue())){ break; } newIndex++; } } } return newIndex; } /** * Ignores or skip over text starting from the index position specified * if it contains the startIgnore string, and until the * endIgnore string is encountered or end of text is * detected. * @param index The start position in text. * @param startIgnore The string that should be at index * position to start skipping through. * @param endIgnore The string which mark the end of skipping through. * @return The index position pointing after the skipped characters or the * original index if the ignore condition could not be met. */ protected int ignore(int index, String startIgnore, String endIgnore) { //{{{ int newIndex = index; int len = text.length(); int slen = startIgnore.length(); int elen = endIgnore.length(); if (!((newIndex + slen) >= len)) { String seg = text.substring(newIndex, newIndex + slen); // System.out.println(seg + ":" + seg.length()+ ":" + startIgnore + ":" + slen); if (seg.equals(startIgnore)) { newIndex += slen; cycle: while (true) { if (newIndex == (text.length() - elen)) { break cycle; } String ss = text.substring(newIndex, newIndex + elen); if (ss.equals(endIgnore)) { newIndex += elen; break cycle; } else { newIndex++; } } } } return newIndex; } //}}} /** * Initializes the sentenseIterator */ protected void init() { sentenceIterator = BreakIterator.getSentenceInstance(); sentenceIterator.setText(text); } /** * Defines the starting positions for text analysis */ private void setup() { currentWord = new Word("", 0); nextWord = new Word("", 0); startsSentence = true; init(); try { next(); } catch (WordNotFoundException e) { currentWord = null; nextWord = null; } } } jazzy-0.5.2/src/com/swabunga/spell/event/XMLWordFinder.java0000644000175000017500000000553710304044060023527 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ //:folding=indent: package com.swabunga.spell.event; /** * A word finder for XML or HTML documents, which searches text for sequences * of letters, but ignores the text inside any tags. * * @author Anthony Roy (ajr@antroy.co.uk) */ public class XMLWordFinder extends AbstractWordFinder { //~ Instance/static variables ............................................... //~ Constructors ............................................................ /** * Creates a new DefaultWordFinder object. * * @param inText the text to search. */ public XMLWordFinder(String inText) { super(inText); } //~ Methods ................................................................. /** * This method scans the text from the end of the last word, and returns a * new Word object corresponding to the next word. * * @return the next word. * @throws WordNotFoundException search string contains no more words. */ public Word next() { if (currentWord == null) throw new WordNotFoundException("No more words found."); currentWord.copy(nextWord); setSentenceIterator(currentWord); int i = currentWord.getEnd(); boolean finished = false; boolean started = false; search: /* Find words. */ while (i < text.length() && !finished) { if (!started && isWordChar(i)) { nextWord.setStart(i++); started = true; continue search; } else if (started) { if (isWordChar(i)) { i++; continue search; } else { nextWord.setText(text.substring(nextWord.getStart(), i)); finished = true; break search; } } //Ignore things inside tags. int i2 = ignore(i, '<', '>'); i = (i2 == i ? i + 1 : i2); } if (!started) { nextWord = null; } else if (!finished) { nextWord.setText(text.substring(nextWord.getStart(), i)); } return currentWord; } } jazzy-0.5.2/src/com/swabunga/spell/event/Word.java0000644000175000017500000000620310255105016022011 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.event; /** * Offers basic methods to manipulate a text string representing a word. */ public class Word { //~ Instance/static variables ............................................... private int end; private int start; private String text; //~ Constructors ............................................................ /** * Creates a new Word object. * * @param text the String representing the word. * @param start the start index of the word. */ public Word(String text, int start) { this.text = text; this.start = start; setEnd(); } /** * Creates a new Word object by cloning an existing Word object. * * @param w the word object to clone. */ public Word(Word w) { this.copy(w); } //~ Methods ................................................................. /** * Evaluate the end of word position. * @return the end index of the word. */ public int getEnd() { return end; } /** * Set the start index of the word. * * @param s the start index. */ public void setStart(int s) { start = s; setEnd(); } /** * Evaluate the start of word position. * @return the start index. */ public int getStart() { return start; } /** * Set the text to a new string value. * * @param s the new text */ public void setText(String s) { text = s; setEnd(); } /** * Supply the text string representing the word * @return the String representing the word. */ public String getText() { return text; } /** * Sets the value of this Word to be a copy of another. * * @param w the Word to copy. */ public void copy(Word w) { text = w.toString(); start = w.getStart(); setEnd(); } /** * Evaluate the length of the word. * @return the length of the word. */ public int length() { return text.length(); } /** * Supply the text representing the word. * @return the text representing the word. */ public String toString() { return text; } /** * Set the end index of the word. * */ private void setEnd() { end = start + text.length(); } } jazzy-0.5.2/src/com/swabunga/spell/event/SpellCheckListener.java0000644000175000017500000000236510255105020024621 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package com.swabunga.spell.event; import java.util.EventListener; /** * This is the event based listener interface. * * @author Jason Height (jheight@chariot.net.au) */ public interface SpellCheckListener extends EventListener { /** * Propagates the spelling errors to listeners. * @param event The event to handle */ public void spellingError(SpellCheckEvent event); } jazzy-0.5.2/src/JSpellChecker.java0000644000175000017500000001671210253371642016745 0ustar twernertwerner/* Jazzy - a Java library for Spell Checking Copyright (C) 2001 Mindaugas Idzelis Full text of license can be found in LICENSE.txt This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ import com.swabunga.spell.engine.Configuration; import com.swabunga.spell.engine.SpellDictionaryHashMap; import com.swabunga.spell.event.SpellCheckEvent; import com.swabunga.spell.event.SpellCheckListener; import com.swabunga.spell.event.SpellChecker; import com.swabunga.spell.event.StringWordTokenizer; import java.applet.Applet; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.Hashtable; import java.util.Iterator; import java.util.List; import java.util.StringTokenizer; public class JSpellChecker extends Applet { private class JSpellCheckListener extends Thread implements SpellCheckListener { private JSpellCheckListener(StringWordTokenizer tokens) { log(this.hashCode() + ": JSpellCheckListener.init"); this.tokens = tokens; } public synchronized void spellingError(SpellCheckEvent event) { log(this.hashCode() + ": JSpellCheckListener.spellingError"); JSpellChecker.this.event = event; synchronized (JSpellChecker.this) { JSpellChecker.this.notifyAll(); } try { this.wait(); } catch (InterruptedException e) { } } public boolean done() { return done; } public void run() { log(this.hashCode() + ": JSpellCheckListener.run"); done = false; checker.checkSpelling(this.tokens); done = true; synchronized (JSpellChecker.this) { JSpellChecker.this.notifyAll(); } } private boolean done; private StringWordTokenizer tokens; } public JSpellChecker() { initialized = false; } public void init() { log(this.hashCode() + ": JSpellChecker.init"); String dictionary = getParameter("dictionary"); checker = new SpellChecker(); for (StringTokenizer strtok = new StringTokenizer(dictionary, " ;:"); strtok.hasMoreElements();) { InputStream is = getClass().getResourceAsStream(strtok.nextToken()); try { checker.addDictionary(new SpellDictionaryHashMap(new InputStreamReader(is))); } catch (IOException ex) { ex.printStackTrace(); } } initialized = true; } public void setText(String text) { log(this.hashCode() + ": JSpellChecker.setText(" + text + ")"); if (!initialized) throw new java.lang.IllegalStateException("Spellchecker is loading."); checker.removeSpellCheckListener(listener); tokens = new StringWordTokenizer(text); listener = new JSpellCheckListener(tokens); checker.addSpellCheckListener(listener); checker.reset(); } public void setOptions(int options) { //System.out.println("in " + getClass().getName() + ".setOptions(" + Integer.toBinaryString(options) + ")"); Configuration config = checker.getConfiguration(); for (int i = 1; i <= 0x20000; i = i << 1) { String key = (String) configmap.get(new Integer(i)); if (key != null) config.setBoolean(key, (options & i) > 0); } } public synchronized boolean check() { if (!listener.isAlive()) { listener.start(); try { wait(); } catch (InterruptedException e) { } return listener.done(); } synchronized (listener) { listener.notifyAll(); } try { wait(); } catch (InterruptedException e) { } return listener.done(); } private String getSuggestionList(List suggestions) { String s = ""; for (Iterator i = suggestions.iterator(); i.hasNext();) { com.swabunga.spell.engine.Word element = (com.swabunga.spell.engine.Word) i.next(); s += element.getWord() + "|"; } // for (int i = 0; i < suggestions.size(); i ++) { // s += ((com.swabunga.spell.engine.Word)suggestions.elementAt(i)).getWord() + "|"; // } return s; } public String getSuggestions() { return getSuggestionList(event.getSuggestions()); } public String getSuggestions(String word) { return getSuggestionList(checker.getSuggestions(word, 0)); } public String getMisspelledWord() { if (event != null) return event.getInvalidWord(); return null; } public int getCursorPosition() { if (event != null) return event.getWordContextPosition(); return 0; } public void changeWord(String word, boolean all) { if (event != null) { if (word == null) word = ""; event.replaceWord(word, all); } } public void ignoreWord(boolean all) { if (event != null) { event.ignoreWord(all); } } // private String getText(){ // if (tokens != null) // return tokens.getFinalText(); // return null; // } protected static void log(String s) { System.out.println(s); } private boolean initialized; protected SpellCheckEvent event; protected SpellChecker checker; private StringWordTokenizer tokens; private JSpellCheckListener listener; // private static final int CASE_SENSITIVE = 1; private static final int IGNORE_ALL_CAPS_WORD = 2; private static final int IGNORE_CAPPED_WORD = 4; private static final int IGNORE_MIXED_CASE = 8; private static final int IGNORE_MIXED_DIGITS = 16; // private static final int IGNORE_NON_ALPHA_WORD = 32; private static final int REPORT_DOUBLED_WORD = 64; // private static final int REPORT_MIXED_CASE = 128; // private static final int REPORT_MIXED_DIGITS = 256; // private static final int REPORT_SPELLING = 512; // private static final int REPORT_UNCAPPED = 1024; // private static final int SPLIT_CONTRACTED_WORDS = 2048; // private static final int SPLIT_HYPHENATED_WORDS = 4096; // private static final int SPLIT_WORDS = 8192; // private static final int STRIP_POSSESSIVES = 16384; // private static final int SUGGEST_SPLIT_WORDS = 32768; private static final int IGNORE_DOMAIN_NAMES = 0x10000; // private static final int ALLOW_ACCENTED_CAPS = 0x20000; private static Hashtable configmap; static { configmap = new Hashtable(); configmap.put(new Integer(IGNORE_MIXED_DIGITS), Configuration.SPELL_IGNOREDIGITWORDS); configmap.put(new Integer(IGNORE_DOMAIN_NAMES), Configuration.SPELL_IGNOREINTERNETADDRESSES); configmap.put(new Integer(IGNORE_MIXED_CASE), Configuration.SPELL_IGNOREMIXEDCASE); configmap.put(new Integer(REPORT_DOUBLED_WORD), Configuration.SPELL_IGNOREMULTIPLEWORDS); configmap.put(new Integer(IGNORE_CAPPED_WORD), Configuration.SPELL_IGNORESENTENCECAPITALIZATION); configmap.put(new Integer(IGNORE_ALL_CAPS_WORD), Configuration.SPELL_IGNOREUPPERCASE); } } jazzy-0.5.2/build.xml0000644000175000017500000001643710304044060014446 0ustar twernertwerner jazzy-0.5.2/LICENSE.txt0000644000175000017500000006042010253367652014461 0ustar twernertwerner GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. [This is the first released version of the Lesser GPL. It also counts as the successor of the GNU Library Public License, version 2, hence the version number 2.1.] Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below. When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things. To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it. For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights. We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library. To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others. Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license. Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs. When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library. We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances. For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License. In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system. Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library. The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run. GNU LESSER GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you". A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables. The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".) "Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library. Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does. 1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) The modified work must itself be a software library. b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change. c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License. d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful. (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library. In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices. Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy. This option is useful when you wish to copy part of the code of the Library into a program that is not a library. 4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange. If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code. 5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License. However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables. When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law. If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.) Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself. 6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications. You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things: a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.) b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with. c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution. d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place. e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy. For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute. 7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things: a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above. b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work. 8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it. 10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License. 11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation. 14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS jazzy-0.5.2/www/0000755000175000017500000000000011620032156013443 5ustar twernertwernerjazzy-0.5.2/www/index.html0000644000175000017500000000770510341061706015453 0ustar twernertwerner The Java Open Source Spell Checker



What exactly is Jazzy? Well, for developers, it is a set of APIs (Application Programming Interfaces) that allow you to add spell checking functionality to Java Applications easily. For end-users, Jazzy does not do too much besides spell check things you paste into an applet. Eventually, I plan to create an applet that would be suitable for use in HTML forms that will allow the user to spell check a html textarea before submitting.

Developers:
Author and Initial Contributor: 
	Mindaugas Idzelis
	
Other Contributors:
	Ben Galbraith (ben AT galbraiths ADOT org)
	Damien Guillaume
	Robert Gustavsson (robert AT lindesign ADOT se)
	Jason Height (jheight AT chariot DOT net ADOT au)
	Anthony Roy  (ajr AT antroy ADOT co ADOT uk)
	Stig Tanggaard
	Don Vail
	Matthew Demerath (Matthew AT Demerath ADOT com | mdemerat AT umich ADOT edu) 
	Tony Chan (htchan AT umich ADOT edu)

Text (Articles/books that mention Jazzy)
Eclipse for Java Developers - This is a book by Berthold Daum. There is source code that turns Jazzy into an Eclipse and lets you spell check text files
Link: http://www.bdaum.de/bookeclipsee.HTM

ColdFusion Developers Journal - Talks about how to wrap this Java component with a coldfusion tag that lets you spell check documents on a Cold Fusion server
Link: http://cfdj.sys-con.com/read/42120.htm



Resources (Other projects that use or depend on Jazzy)
If you are using Jazzy in your product, please let us know! You can reach the project administrator at the following email address: aim4min at users.sourceforge.net.

JEdit Plugin - This is a plugin that allows you to spell check documents and Java code in the popular editor program JEdit. Link: http://plugins.jedit.org/plugins/?JazzyPlugin

Ekit - This is a Rich Text and HTML editor written in Java. It uses Jazzy for it's spell checking capabilities.
Link: http://www.hexidec.com/ekit.php

Webhtmleditor - This is a Internet Explorer 5.5+ only web based html editor that uses Jazzy.
Link: http://webhtmleditor.sourceforge.net
It's project page can be found here: http://www.sourceforge.net/projects/webhtmleditor

Roller - This is a Java based Blog (Web-Log) software that has recently added support for spell checking via jazzy.
Link: http://www.rollerweblogger.org/page/project

Sourceforge.net:
    This is a project graciously hosted by sourceforge.net. If you follow this link you will find our "project" page which contains more information about the actual project, including message boards, CVS, and the actual released files.
Sourceforge Project page: http://www.sourceforge.net/projects/jazzy

Demo:
    Click here for a demo.

SourceForge.net Logo jazzy-0.5.2/www/demo.html0000644000175000017500000000310707631174662015276 0ustar twernertwerner

Jazzy -- An Open Source Spell Checker



Demonstration applet:

    This demonstration applet may take a while to start because it is downloading a compressed english dictionary that is about 128K. The actual applet code is around 82K.

Usage:
    Just type in the text area, and when you are ready, click the spell check button.



Feedback:
    Please direct feedback to the forums on the sourceforge project page. Thank you!


jazzy-0.5.2/www/jazzy_logo.png0000644000175000017500000001006407631132756016357 0ustar twernertwernerPNG  IHDRnW<PLTEDHA83B:) -) QJF7}' ":01WA)p#\Rۂ+JGfth ٳ9y0ʨ5f[ƆG˵Pyz`f.6_aIjZĚL~0}x?o{izTiڭ;L0ǻ[Vk{QŇ!AtRNS0UIDATxi{WH2"(.hb4,gol=0`UUՀBuQ)d*>lqۂ?0w @q^&AA? /r۠"()``r.WnS{RscJXL_lkJ}c_EΫRcc4JZ1ՎX, &QYў+*PޮLm58l6v u=6wr10@9-Iimf9.?[ <XAQ4o@v."oo?<ÍMĮVG7Pɘ#k/+PxR bў W%{߇_^ W'8.+Όa!s$IJfv_7QDSG;Ёb%v3"?mPc\H$C(3 VU~lI̎˖>n*GD/)ճ1^֯uqfRZK]G$r(OL L40Ŭ׉`Y؟U08 i{)Y }aȘ=YSL:"h~\)5'΄? /{ ^0k.khb2(?، 276ėyxGa$,9}SO\5bΛoO-obQjZItᝁ0c lkfy Fpw*!Ki K-|[p1K7ڃa:ՓݩpF_ԓC2sJP-Fh_gНBVq:{ K^Ql "RRSh4BJ"&\l$l_Wb! 'Gz?I[qΈd L*)/i >Z q&wcUI"3ui$9vV$f^r^I4 b)>j#mc/f1]jA:XBO(& Yc1x1gXD-d٫Ð;?bdÝޢS*x6G}ɝ$daاcg/:]W]4w]P 0'%OjA)ӧ,ͦ] A4X<1Йnx8adYbdoԌd "T:?mTbץew Ol6[,I(.̙# s9ӤtgcG'&{[(&۲,`EQssnmDr(d֨D?3C ,:iBҽg[ &\hg_L-Llw_{{Nt$P&g`aF SٺK{3'Kmċ rL3R_fliQ:#atmvcvbS_gq5ֽ*.,y)eMJ9_d؎rﴼ13 JG^4740"Q¶P/ebA)0=X|v' ɸlmʸC^dȎHY=vLV{8bυa֌%eq.,/[Cj* )qyzܺ̚fG"߾VI0ڥD$-"e ÓؓBM&'D~as-!VS4˟7b]oh;,rcjA>s-ƛ#N >8e99JDkt:[Vnv)Q:!x\f34p6>&t:a8[dS{nA 0N8Ӯ%L|?휜BsAs"Ad!Ul3hAs30]J!&pQ-.PWfՍpjW9c P̗3tCaX l6 0Gf+Z}?) j8$P$Y S창Qu-*)1`OD`J|ԙ73)=b2?I䚃>A*aٌaJRJGOzZ.e4{j(fyl͢(`L"遲̑#8JmVOql9ģ,&!>)r(؁zI&ۣ<sx{)&r&}~LJ}aG>_O9S>D=(ʿ4v&Y?3ϗ}uE ٟ,O%!Iֿ6ýtPOjZV~אk,PYLWSj=Sbw,M, Y*6+Ͳ`MzRgIW} Cx[k\Z̉Nr+Pʋvn}c' bAU7eiAX_S 7ܮ}aBq uBc(1uާ.+]^7N!$3~L]v[Ǥ[~%{y̿j6qc=孋% ӻLIENDB`jazzy-0.5.2/jedit_build.xml0000644000175000017500000001040710011646414015622 0ustar twernertwerner