Click here to Skip to main content
Click here to Skip to main content
Add your own
alternative version

Multiple convolution neural networks approach for online handwriting recognition

, 9 Apr 2013
The research focuses on the presentation of word recognition technique for an online handwriting recognition system which uses multiple component neural networks (MCNN) as the exchangeable parts of the classifier.
capital_letter_v2.zip
digit_v2.zip
lower_case_letter_v2.zip
UNIPENviewer_source_code-noexe.zip
UNIPENviewer
DocToolkit
DocToolkit.csproj.user
DocToolkit.snk
obj
Debug
Release
DrawTools
about.bmp
App.ico
bin
Debug
Release
DrawTools.csproj.user
ellipse.bmp
Ellipse.cur
line.bmp
Line.cur
new.bmp
obj
Debug
DrawTools.DrawArea.resources
GenerateResource.read.1.tlog
GenerateResource.write.1.tlog
Release
DrawTools.DrawArea.resources
GenerateResource.read.1.tlog
GenerateResource.write.1.tlog
open.bmp
pencil.bmp
Pencil.cur
pointer.bmp
PolyHandle.cur
rectangle.bmp
Rectangle.cur
save.bmp
NNControl
bin
Debug
Common
NNTesting
NNTraining
obj
Debug
GenerateResource.read.1.tlog
GenerateResource.write.1.tlog
NNControl.Common.UPTemplateControl.resources
NNControl.FlashForm.resources
NNControl.NNTesting.NNTestingControl.resources
NNControl.NNTesting.TextSpellControl.resources
NNControl.NNTraining.ConvolutionForm.resources
NNControl.NNTraining.CreateNetworkForm.resources
NNControl.NNTraining.FullConnectedForm.resources
NNControl.NNTraining.InputLayerForm.resources
NNControl.NNTraining.OutputLayerForm.resources
NNControl.NNTraining.UP_NNTrainingControl.resources
NNControl.Properties.Resources.resources
NNControl.TrainingParametersForm.resources
NNControl.UPViewer.UpImageViewer.resources
UPControl.Common.BaseControl.resources
UPControl.Common.UPTemplateControl.resources
UPControl.FlashForm.resources
UPControl.NNTraining.UP_NNTrainingControl.resources
UPControl.TrainingParametersForm.resources
UPControl.UPViewer.UpImageViewer.resources
UP_NeuralTraining.FlashForm.resources
UP_NeuralTraining.TrainingParametersForm.resources
UP_NeuralTraining.UP_NNTrainingControl.resources
Release
GenerateResource.read.1.tlog
GenerateResource.write.1.tlog
NNControl.Common.UPTemplateControl.resources
NNControl.FlashForm.resources
NNControl.NNTesting.NNTestingControl.resources
NNControl.NNTraining.ConvolutionForm.resources
NNControl.NNTraining.CreateNetworkForm.resources
NNControl.NNTraining.FullConnectedForm.resources
NNControl.NNTraining.InputLayerForm.resources
NNControl.NNTraining.OutputLayerForm.resources
NNControl.NNTraining.UP_NNTrainingControl.resources
NNControl.Properties.Resources.resources
NNControl.TrainingParametersForm.resources
NNControl.UPViewer.UpImageViewer.resources
Properties
Resources
btnBack.png
btnDrag.png
btnFitToScreen.png
btnNext.png
btnOpen.png
btnPreview.png
btnRotate270.png
btnRotate90.png
btnSelect.png
btnZoomIn.png
btnZoomOut.png
circle.png
clear.png
color_line.png
cry.png
document-new.png
Drag.cur
draw_line.png
ellipse.png
export.png
file.png
fingerprint-recognition.png
folder-open.png
folder.png
folders_explorer.png
Grab.cur
home.png
label-link.png
pointer.png
rectangle.png
save_accept.png
script_(stop).gif
smile.png
stock_draw-line.png
Stop sign.png
Upload.png
user-group-new.png
UPViewer
Perceptron
ActivationFunction
ArchiveSerialization
bin
Debug
Common
Connections
Layers
Network
Neurons
obj
Debug
ANN.Perceptron.Common.BaseControl.resources
GenerateResource.read.1.tlog
GenerateResource.write.1.tlog
Neurons.BaseControl.resources
Release
GenerateResource.read.1.tlog
GenerateResource.write.1.tlog
Neurons.BaseControl.resources
Properties
Weights
SpellChecker
bin
Debug
Controls
Dictionary
Affix
Dictionary.bmp
Phonetic
doc
NetSpell.ndoc
Forms
Interactive.bmp
obj
Debug
ResGen.read.1.tlog
ResGen.write.1.tlog
SpellChecker.Dictionary.WordDictionary.resources
SpellChecker.Forms.OptionForm.resources
SpellChecker.MultipleSpelling.resources
SpellChecker.NewSpelling.resources
Spell.snk
Spelling.bmp
UNIPENviewer.suo
UNIPENviewer.v11.suo
UNIPENviewer
bin
Debug
Config
de-DE.dic
en-US.dic
fr-FR.dic
it-IT.dic
UNIPENviewer.vshost.exe.manifest
Release
Config
obj
Debug
GenerateResource.read.1.tlog
GenerateResource.write.1.tlog
UNIPENviewer.MainForm.resources
UNIPENviewer.Properties.Resources.resources
Release
GenerateResource.read.1.tlog
GenerateResource.write.1.tlog
UNIPENviewer.MainForm.resources
UNIPENviewer.Properties.Resources.resources
x86
Debug
GenerateResource.read.1.tlog
GenerateResource.write.1.tlog
UNIPENviewer.Form1.resources
UNIPENviewer.Properties.Resources.resources
Properties
Settings.settings
UPImage
Common
Data
FileFormat
obj
Debug
Release
Properties
UNIPENviewer_source_code.zip
bin
Debug
DocToolkit.dll
DocToolkit.pdb
Release
DocToolkit.dll
DocToolkit.csproj.user
DocToolkit.snk
DesignTimeResolveAssemblyReferencesInput.cache
DocToolkit.dll
DocToolkit.pdb
TempPE
DesignTimeResolveAssemblyReferencesInput.cache
DocToolkit.dll
about.bmp
App.ico
DocToolkit.dll
DocToolkit.pdb
DrawTools.dll
DrawTools.pdb
DocToolkit.dll
DrawTools.dll
DrawTools.csproj.user
ellipse.bmp
Ellipse.cur
line.bmp
Line.cur
new.bmp
DesignTimeResolveAssemblyReferencesInput.cache
DrawTools.csproj.GenerateResource.Cache
DrawTools.csprojResolveAssemblyReference.cache
DrawTools.dll
DrawTools.DrawArea.resources
DrawTools.pdb
GenerateResource.read.1.tlog
GenerateResource.write.1.tlog
ResolveAssemblyReference.cache
TempPE
DesignTimeResolveAssemblyReferencesInput.cache
DrawTools.dll
DrawTools.DrawArea.resources
GenerateResource.read.1.tlog
GenerateResource.write.1.tlog
ResolveAssemblyReference.cache
open.bmp
pencil.bmp
Pencil.cur
pointer.bmp
PolyHandle.cur
rectangle.bmp
Rectangle.cur
Resources
save.bmp
DocToolkit.dll
DocToolkit.pdb
DrawTools-LinhLam.dll
DrawTools-LinhLam.pdb
DrawTools.dll
DrawTools.pdb
NNControl-LinhLam.dll
NNControl-LinhLam.pdb
NNControl.dll
NNControl.pdb
Perceptron.dll
Perceptron.pdb
SpellChecker.dll
SpellChecker.pdb
UP-NeuralTraining.dll
UP-NeuralTraining.pdb
UPImage-LinhLam.dll
UpImage.dll
UpImage.pdb
Release
DocToolkit.dll
DrawTools.dll
Neurons.dll
Neurons.pdb
NNControl.dll
NNControl.pdb
UPImage.dll
UPImage.pdb
DesignTimeResolveAssemblyReferences.cache
DesignTimeResolveAssemblyReferencesInput.cache
GenerateResource.read.1.tlog
GenerateResource.write.1.tlog
NNControl-LinhLam.dll
NNControl-LinhLam.pdb
NNControl.Common.UPTemplateControl.resources
NNControl.csproj.GenerateResource.Cache
NNControl.csprojResolveAssemblyReference.cache
NNControl.dll
NNControl.FlashForm.resources
NNControl.NNTesting.NNTestingControl.resources
NNControl.NNTesting.TextSpellControl.resources
NNControl.NNTraining.ConvolutionForm.resources
NNControl.NNTraining.CreateNetworkForm.resources
NNControl.NNTraining.FullConnectedForm.resources
NNControl.NNTraining.InputLayerForm.resources
NNControl.NNTraining.OutputLayerForm.resources
NNControl.NNTraining.UP_NNTrainingControl.resources
NNControl.pdb
NNControl.Properties.Resources.resources
NNControl.TrainingParametersForm.resources
NNControl.UPViewer.UpImageViewer.resources
ResolveAssemblyReference.cache
TempPE
Properties.Resources.Designer.cs.dll
UP-NeuralTraining.dll
UP-NeuralTraining.pdb
UPControl.Common.BaseControl.resources
UPControl.Common.UPTemplateControl.resources
UPControl.FlashForm.resources
UPControl.NNTraining.UP_NNTrainingControl.resources
UPControl.TrainingParametersForm.resources
UPControl.UPViewer.UpImageViewer.resources
UP_NeuralTraining.FlashForm.resources
UP_NeuralTraining.TrainingParametersForm.resources
UP_NeuralTraining.UP_NNTrainingControl.resources
DesignTimeResolveAssemblyReferences.cache
DesignTimeResolveAssemblyReferencesInput.cache
GenerateResource.read.1.tlog
GenerateResource.write.1.tlog
NNControl.Common.UPTemplateControl.resources
NNControl.dll
NNControl.FlashForm.resources
NNControl.NNTesting.NNTestingControl.resources
NNControl.NNTraining.ConvolutionForm.resources
NNControl.NNTraining.CreateNetworkForm.resources
NNControl.NNTraining.FullConnectedForm.resources
NNControl.NNTraining.InputLayerForm.resources
NNControl.NNTraining.OutputLayerForm.resources
NNControl.NNTraining.UP_NNTrainingControl.resources
NNControl.pdb
NNControl.Properties.Resources.resources
NNControl.TrainingParametersForm.resources
NNControl.UPViewer.UpImageViewer.resources
ResolveAssemblyReference.cache
TempPE
Properties.Resources.Designer.cs.dll
btnBack.png
btnDrag.png
btnFitToScreen.png
btnNext.png
btnOpen.png
btnPreview.png
btnRotate270.png
btnRotate90.png
btnSelect.png
btnZoomIn.png
btnZoomOut.png
circle.png
clear.png
color_line.png
cry.png
document-new.png
Drag.cur
draw_line.png
ellipse.png
export.png
file.png
fingerprint-recognition.png
folder-open.png
folder.png
folders_explorer.png
Grab.cur
home.png
label-link.png
pointer.png
rectangle.png
save_accept.png
script_(stop).gif
smile.png
stock_draw-line.png
Stop sign.png
Upload.png
user-group-new.png
AForgeLibrary.dll
AForgeLibrary.pdb
NeuralNetworkLibrary.dll
NeuralNetworkLibrary.pdb
Perceptron.dll
Perceptron.pdb
SpellChecker.dll
SpellChecker.pdb
UpImage.dll
UpImage.pdb
Release
NeuralNetworkLibrary.dll
NeuralNetworkLibrary.pdb
Neurons.dll
Neurons.pdb
UPImage.dll
UPImage.pdb
ANN.Perceptron.Common.BaseControl.resources
ANN.Perceptron.csproj.GenerateResource.Cache
ANN.Perceptron.csprojResolveAssemblyReference.cache
DesignTimeResolveAssemblyReferencesInput.cache
GenerateResource.read.1.tlog
GenerateResource.write.1.tlog
NeuralNetworkLibrary.dll
NeuralNetworkLibrary.pdb
Neurons.BaseControl.resources
Perceptron.dll
Perceptron.pdb
ResolveAssemblyReference.cache
TempPE
DesignTimeResolveAssemblyReferencesInput.cache
GenerateResource.read.1.tlog
GenerateResource.write.1.tlog
NeuralNetworkLibrary.dll
NeuralNetworkLibrary.pdb
Neurons.BaseControl.resources
Neurons.dll
Neurons.pdb
ResolveAssemblyReference.cache
Service References
SpellChecker.dll
SpellChecker.pdb
Release
Dictionary.bmp
NetSpell.ndoc
Interactive.bmp
DesignTimeResolveAssemblyReferences.cache
DesignTimeResolveAssemblyReferencesInput.cache
NetSpell.SpellChecker.dll
NetSpell.SpellChecker.pdb
ResGen.read.1.tlog
ResGen.write.1.tlog
SpellChecker.csproj.GenerateResource.Cache
SpellChecker.csprojResolveAssemblyReference.cache
SpellChecker.Dictionary.WordDictionary.resources
SpellChecker.dll
SpellChecker.Forms.OptionForm.resources
SpellChecker.MultipleSpelling.resources
SpellChecker.NewSpelling.resources
SpellChecker.pdb
TempPE
Spell.snk
Spelling.bmp
UNIPENviewer.suo
UNIPENviewer.v11.suo
de-DE.dic
DocToolkit.dll
DocToolkit.pdb
DrawTools-LinhLam.dll
DrawTools-LinhLam.pdb
DrawTools.dll
DrawTools.pdb
en-US.dic
fr-FR.dic
it-IT.dic
NNControl-LinhLam.dll
NNControl.dll
NNControl.pdb
Perceptron.dll
Perceptron.pdb
SpellChecker.dll
SpellChecker.pdb
UNIPENviewer-LinhLam.exe
UNIPENviewer-LinhLam.pdb
UNIPENviewer.exe
UNIPENviewer.pdb
UNIPENviewer.vshost.exe
UNIPENviewer.vshost.exe.manifest
UPImage-LinhLam.dll
UPImage-LinhLam.pdb
UpImage.dll
UpImage.pdb
DesignTimeResolveAssemblyReferences.cache
DesignTimeResolveAssemblyReferencesInput.cache
GenerateResource.read.1.tlog
GenerateResource.write.1.tlog
ResolveAssemblyReference.cache
TempPE
Properties.Resources.Designer.cs.dll
UNIPENviewer-LinhLam.exe
UNIPENviewer-LinhLam.pdb
UNIPENviewer.csproj.GenerateResource.Cache
UNIPENviewer.csprojResolveAssemblyReference.cache
UNIPENviewer.exe
UNIPENviewer.MainForm.resources
UNIPENviewer.pdb
UNIPENviewer.Properties.Resources.resources
DesignTimeResolveAssemblyReferencesInput.cache
GenerateResource.read.1.tlog
GenerateResource.write.1.tlog
ResolveAssemblyReference.cache
UNIPENviewer.exe
UNIPENviewer.MainForm.resources
UNIPENviewer.pdb
UNIPENviewer.Properties.Resources.resources
DesignTimeResolveAssemblyReferences.cache
DesignTimeResolveAssemblyReferencesInput.cache
GenerateResource.read.1.tlog
GenerateResource.write.1.tlog
ResolveAssemblyReference.cache
UNIPENviewer.exe
UNIPENviewer.Form1.resources
UNIPENviewer.pdb
UNIPENviewer.Properties.Resources.resources
Settings.settings
bin
Debug
AForgeLibrary.dll
AForgeLibrary.pdb
UPDatabase.dll
UPDatabase.pdb
UpImage-LinhLam.dll
UpImage-LinhLam.pdb
UpImage.dll
UpImage.pdb
UPUnipenLib.dll
UPUnipenLib.pdb
Release
UPImage.dll
UPImage.pdb
DesignTimeResolveAssemblyReferencesInput.cache
TempPE
UPDatabase.dll
UPDatabase.pdb
UpImage-LinhLam-2.pdb
UpImage-LinhLam.dll
UPImage-LinhLam.pdb
UpImage.dll
UpImage.pdb
UPUnipenLib.dll
UPUnipenLib.pdb
DesignTimeResolveAssemblyReferencesInput.cache
UPImage.dll
UPImage.pdb
Word_samples.zip
Word samples
beach.dtl
Bengal.dtl
best.dtl
Brower.dtl
Buy.dtl
Byte byte.dtl
Change.dtl
Color.dtl
Company.dtl
Complet.dtl
copy.dtl
cup.dtl
draw tool.dtl
Eastern.dtl
Eat.dtl
eldest.dtl
Emergency.dtl
English.dtl
File.dtl
Finist.dtl
found nothing.dtl
France.dtl
Future.dtl
help me now.dtl
Hey hello.dtl
Hobby.dtl
How are you.dtl
Huck.dtl
icon.dtl
inker.dtl
Internet.dtl
Link.dtl
load.dtl
Local.dtl
Lonely.dtl
loosen.dtl
love you.dtl
Madden.dtl
Main gate.dtl
Mercy.dtl
Module.dtl
monday.dtl
Moon.dtl
mouse.dtl
my turn.dtl
net spell.dtl
network.dtl
never.dtl
newest.dtl
noted.dtl
Novel.dtl
oldest.dtl
Option.dtl
Pencil.dtl
petro.dtl
Pink.dtl
quick and slow.dtl
Rock.dtl
save.dtl
Sell.dtl
slam.dtl
smart phone.dtl
Strong.dtl
Strongest.dtl
success.dtl
Summer.dtl
Take.dtl
Text.dtl
Took.dtl
Train.dtl
Tuesday.dtl
Valence.dtl
Victory.dtl
viewer.dtl
vintage.dtl
Volume.dtl
water.dtl
Weak.dtl
Window.dtl
Windy.dtl
word expert.dtl
using System;
using System.Diagnostics;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections;
using System.IO;
using System.IO.IsolatedStorage;
using System.Threading;
using System.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Drawing;
using System.Drawing.Design;
using System.Globalization;

using SpellChecker;
using SpellChecker.Dictionary.Affix;
using SpellChecker.Dictionary.Phonetic;

namespace SpellChecker.Dictionary
{

	/// <summary>
	/// The WordDictionary class contains all the logic for managing the word list.
	/// </summary>
	[ToolboxBitmap(typeof(SpellChecker.Dictionary.WordDictionary), "Dictionary.bmp")]
	public class WordDictionary : System.ComponentModel.Component
	{
		private Hashtable _baseWords = new Hashtable();
		private string _copyright = "";
		private string _dictionaryFile = Thread.CurrentThread.CurrentCulture.Name + ".dic";
		private string _dictionaryFolder = "";
		private bool _enableUserFile = true;
		private bool _initialized = false;
		private PhoneticRuleCollection _phoneticRules = new PhoneticRuleCollection();
		private ArrayList _possibleBaseWords = new ArrayList();
		private AffixRuleCollection _prefixRules = new AffixRuleCollection();
		private ArrayList _replaceCharacters = new ArrayList();
		private AffixRuleCollection _suffixRules = new AffixRuleCollection();
		private string _tryCharacters = "";
		private string _userFile = "user.dic";
		private Hashtable _userWords = new Hashtable();
		private System.ComponentModel.Container components = null;

		/// <summary>
		///     Initializes a new instance of the class
		/// </summary>
		public WordDictionary()
		{
			InitializeComponent();
		}

		/// <summary>
		///     Initializes a new instance of the class
		/// </summary>
		public WordDictionary(System.ComponentModel.IContainer container)
		{
			container.Add(this);
			InitializeComponent();
		}

		/// <summary>
		///     Loads the user dictionary file
		/// </summary>
		private void LoadUserFile()
		{
			// load user words
			_userWords.Clear();

			// quit if user file is disabled
			if(!this.EnableUserFile) return;

			string userPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData), "NetSpell");
			string filePath = Path.Combine(userPath, _userFile);

			if (File.Exists(filePath)) 
			{
				TraceWriter.TraceInfo("Loading User Dictionary:{0}", filePath);

				//IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForAssembly();
				//fs = new IsolatedStorageFileStream(_UserFile, FileMode.OpenOrCreate, FileAccess.ReadWrite, isf);
				FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite);
				StreamReader sr = new StreamReader(fs, Encoding.UTF8);

				// read line by line
				while (sr.Peek() >= 0) 
				{
					string tempLine = sr.ReadLine().Trim();
					if (tempLine.Length > 0)
					{
						_userWords.Add(tempLine, tempLine);
					}
				}

				fs.Close();
				sr.Close();
				//isf.Close();

				TraceWriter.TraceInfo("Loaded User Dictionary; Words:{0}", _userWords.Count);
			}
		}

		/// <summary>
		///     Saves the user dictionary file
		/// </summary>
		/// <remarks>
		///		If the file does not exist, it will be created
		/// </remarks>
		private void SaveUserFile()
		{

			// quit if user file is disabled
			if(!this.EnableUserFile) return;

			string userPath = Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.ApplicationData), "NetSpell");
			if (!Directory.Exists(userPath)) Directory.CreateDirectory(userPath);

			string filePath = Path.Combine(userPath, _userFile);

			TraceWriter.TraceInfo("Saving User Dictionary:{0}", filePath);

			//IsolatedStorageFile isf = IsolatedStorageFile.GetUserStoreForAssembly();
			//FileStream fs = new IsolatedStorageFileStream(_UserFile, FileMode.Create, FileAccess.Write, isf);
			FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write);
			StreamWriter sw = new StreamWriter(fs, Encoding.UTF8);
			sw.NewLine = "\n";

			foreach (string tempWord in _userWords.Keys)
			{
				sw.WriteLine(tempWord);
			}
		
			sw.Close();
			fs.Close();
			//isf.Close();

			TraceWriter.TraceInfo("Saved User Dictionary; Words:{0}", _userWords.Count);
		}

		/// <summary>
		///     Verifies the base word has the affix key
		/// </summary>
		/// <param name="word" type="string">
		///     <para>
		///         Base word to check
		///     </para>
		/// </param>
		/// <param name="affixKey" type="string">
		///     <para>
		///         Affix key to check 
		///     </para>
		/// </param>
		/// <returns>
		///     True if word contains affix key
		/// </returns>
		private bool VerifyAffixKey(string word, char affixKey)
		{
			// make sure base word has this affix key
			Word baseWord = (Word)this.BaseWords[word];
			ArrayList keys = new ArrayList(baseWord.AffixKeys.ToCharArray());
			return keys.Contains(affixKey);			
		}

		/// <summary>
		///     Adds a word to the user list
		/// </summary>
		/// <param name="word" type="string">
		///     <para>
		///         The word to add
		///     </para>
		/// </param>
		/// <remarks>
		///		This method is only affects the user word list
		/// </remarks>
		public void Add(string word)
		{
			_userWords.Add(word, word);
			this.SaveUserFile();
		}

		/// <summary>
		///     Clears the user list of words
		/// </summary>
		/// <remarks>
		///		This method is only affects the user word list
		/// </remarks>
		public void Clear()
		{
			_userWords.Clear();
			this.SaveUserFile();
		}

		/// <summary>
		///     Searches all contained word lists for word
		/// </summary>
		/// <param name="word" type="string">
		///     <para>
		///         The word to search for
		///     </para>
		/// </param>
		/// <returns>
		///     Returns true if word is found
		/// </returns>
		public bool Contains(string word)
		{
			// clean up possible base word list
			_possibleBaseWords.Clear();

			// Step 1 Search UserWords
			if (_userWords.Contains(word)) 
			{
				TraceWriter.TraceVerbose("Word Found in User Dictionary: {0}", word);
				return true;  // word found
			}

			// Step 2 Search BaseWords
			if (_baseWords.Contains(word)) 
			{
				TraceWriter.TraceVerbose("Word Found in Base Words: {0}", word);
				return true; // word found
			}

			// Step 3 Remove suffix, Search BaseWords

			// save suffixed words for use when removing prefix
			ArrayList suffixWords = new ArrayList();
			// Add word to suffix word list
			suffixWords.Add(word);

			foreach(AffixRule rule in SuffixRules.Values)
			{	
				foreach(AffixEntry entry in rule.AffixEntries)
				{
					string tempWord = AffixUtility.RemoveSuffix(word, entry);
					if(tempWord != word)
					{
						if (_baseWords.Contains(tempWord))
						{
							if(this.VerifyAffixKey(tempWord, rule.Name[0]))
							{
								TraceWriter.TraceVerbose("Word Found With Base Words: {0}; Suffix Key: {1}", tempWord, rule.Name[0]);
								return true; // word found
							}
						}
						
						if(rule.AllowCombine)
						{
							// saving word to check if it is a word after prefix is removed
							suffixWords.Add(tempWord);
						}
						else 
						{
							// saving possible base words for use in generating suggestions
							_possibleBaseWords.Add(tempWord);
						}
					}
				}
			}
			// saving possible base words for use in generating suggestions
			_possibleBaseWords.AddRange(suffixWords);

			// Step 4 Remove Prefix, Search BaseWords
			foreach(AffixRule rule in PrefixRules.Values)
			{
				foreach(AffixEntry entry in rule.AffixEntries)
				{
					foreach(string suffixWord in suffixWords)
					{
						string tempWord = AffixUtility.RemovePrefix(suffixWord, entry);
						if (tempWord != suffixWord)
						{
							if (_baseWords.Contains(tempWord))
							{
								if(this.VerifyAffixKey(tempWord, rule.Name[0]))
								{
									TraceWriter.TraceVerbose("Word Found With Base Words: {0}; Prefix Key: {1}", tempWord, rule.Name[0]);
									return true; // word found
								}
							}
							
							// saving possible base words for use in generating suggestions
							_possibleBaseWords.Add(tempWord);
						}
					} // suffix word
				} // prefix rule entry
			} // prefix rule
			// word not found 
			TraceWriter.TraceVerbose("Possible Base Words: {0}", _possibleBaseWords.Count);
			return false;
		}

		/// <summary>
		///     Expands an affix compressed base word
		/// </summary>
		/// <param name="word" type="SpellChecker.Dictionary.Word">
		///     <para>
		///         The word to expand
		///     </para>
		/// </param>
		/// <returns>
		///     A System.Collections.ArrayList of words expanded from base word
		/// </returns>
		public ArrayList ExpandWord(Word word)
		{
			ArrayList suffixWords = new ArrayList();
			ArrayList words = new ArrayList();

			suffixWords.Add(word.Text);
			string prefixKeys = "";


			// check suffix keys first
			foreach(char key in word.AffixKeys)
			{
				if (_suffixRules.ContainsKey(key.ToString(CultureInfo.CurrentUICulture)))
				{
					AffixRule rule = _suffixRules[key.ToString(CultureInfo.CurrentUICulture)];
					string tempWord = AffixUtility.AddSuffix(word.Text, rule);
					if (tempWord != word.Text)
					{
						if (rule.AllowCombine) 
						{
							suffixWords.Add(tempWord);
						}
						else 
						{
							words.Add(tempWord);
						}
					}
				}
				else if (_prefixRules.ContainsKey(key.ToString(CultureInfo.CurrentUICulture)))
				{
					prefixKeys += key.ToString(CultureInfo.CurrentUICulture);
				}
			}

			// apply prefixes
			foreach(char key in prefixKeys)
			{
				AffixRule rule = _prefixRules[key.ToString(CultureInfo.CurrentUICulture)];
				// apply prefix to all suffix words
				foreach (string suffixWord in suffixWords)
				{
					string tempWord = AffixUtility.AddPrefix(suffixWord, rule);
					if (tempWord != suffixWord)
					{
						words.Add(tempWord);
					}
				}
			}

			words.AddRange(suffixWords);

			TraceWriter.TraceVerbose("Word Expanded: {0}; Child Words: {1}", word.Text, words.Count);
			return words;
		}

		/// <summary>
		///     Initializes the dictionary by loading and parsing the
		///     dictionary file and the user file.
		/// </summary>
		public void Initialize()
		{
			// clean up data first
			_baseWords.Clear();
			_replaceCharacters.Clear();
			_prefixRules.Clear();
			_suffixRules.Clear();
			_phoneticRules.Clear();
			_tryCharacters = "";
			

			// the following is used to split a line by white space
			Regex _spaceRegx = new Regex(@"[^\s]+", RegexOptions.Compiled);
			MatchCollection partMatches;

			string currentSection = "";
			AffixRule currentRule = null;
			string dictionaryPath = Path.Combine(_dictionaryFolder, _dictionaryFile);

			TraceWriter.TraceInfo("Loading Dictionary:{0}", dictionaryPath);

			// open dictionary file
			FileStream fs = new FileStream(dictionaryPath, FileMode.Open, FileAccess.Read, FileShare.Read);
			StreamReader sr = new StreamReader(fs, Encoding.UTF8);
			
			// read line by line
			while (sr.Peek() >= 0) 
			{
				string tempLine = sr.ReadLine().Trim();
				if (tempLine.Length > 0)
				{
					// check for section flag
					switch (tempLine)
					{
						case "[Copyright]" :
						case "[Try]" : 
						case "[Replace]" : 
						case "[Prefix]" :
						case "[Suffix]" :
						case "[Phonetic]" :
						case "[Words]" :
							// set current section that is being parsed
							currentSection = tempLine;
							break;
						default :		
							// parse line and place in correct object
						switch (currentSection)
						{
							case "[Copyright]" :
								this.Copyright += tempLine + "\r\n";
								break;
							case "[Try]" : // ISpell try chars
								this.TryCharacters += tempLine;
								break;
							case "[Replace]" : // ISpell replace chars
								this.ReplaceCharacters.Add(tempLine);
								break;
							case "[Prefix]" : // MySpell prefix rules
							case "[Suffix]" : // MySpell suffix rules

								// split line by white space
								partMatches = _spaceRegx.Matches(tempLine);
									
								// if 3 parts, then new rule  
								if (partMatches.Count == 3)
								{
									currentRule = new AffixRule();
									
									// part 1 = affix key
									currentRule.Name = partMatches[0].Value;
									// part 2 = combine flag
									if (partMatches[1].Value == "Y") currentRule.AllowCombine = true;
									// part 3 = entry count, not used

									if (currentSection == "[Prefix]")
									{
										// add to prefix collection
										this.PrefixRules.Add(currentRule.Name, currentRule);
									}
									else 
									{
										// add to suffix collection
										this.SuffixRules.Add(currentRule.Name, currentRule);
									}
								}
									//if 4 parts, then entry for current rule
								else if (partMatches.Count == 4)
								{
									// part 1 = affix key
									if (currentRule.Name == partMatches[0].Value)
									{
										AffixEntry entry = new AffixEntry();

										// part 2 = strip char
										if (partMatches[1].Value != "0") entry.StripCharacters = partMatches[1].Value;
										// part 3 = add chars
										entry.AddCharacters = partMatches[2].Value;
										// part 4 = conditions
										AffixUtility.EncodeConditions(partMatches[3].Value, entry);

										currentRule.AffixEntries.Add(entry);
									}
								}	
								break;
							case "[Phonetic]" : // ASpell phonetic rules
								// split line by white space
								partMatches = _spaceRegx.Matches(tempLine);
								if (partMatches.Count >= 2)
								{
									PhoneticRule rule = new PhoneticRule();
									PhoneticUtility.EncodeRule(partMatches[0].Value, ref rule);
									rule.ReplaceString = partMatches[1].Value;
									_phoneticRules.Add(rule);
								}
								break;
							case "[Words]" : // dictionary word list
								// splits word into its parts
								string[] parts = tempLine.Split('/');
								Word tempWord = new Word();
								// part 1 = base word
								tempWord.Text = parts[0];
								// part 2 = affix keys
								if (parts.Length >= 2) tempWord.AffixKeys = parts[1];
								// part 3 = phonetic code
								if (parts.Length >= 3) tempWord.PhoneticCode = parts[2];
								
								this.BaseWords.Add(tempWord.Text, tempWord);
								break;
						} // currentSection swith
							break;
					} //tempLine switch
				} // if templine
			} // read line
			// close files
			sr.Close();
			fs.Close();

			TraceWriter.TraceInfo("Dictionary Loaded BaseWords:{0}; PrefixRules:{1}; SuffixRules:{2}; PhoneticRules:{3}",
				this.BaseWords.Count, this.PrefixRules.Count, this.SuffixRules.Count, this.PhoneticRules.Count);

			this.LoadUserFile();

			_initialized = true;
		}


		/// <summary>
		///     Generates a phonetic code of how the word sounds
		/// </summary>
		/// <param name="word" type="string">
		///     <para>
		///         The word to generated the sound code from
		///     </para>
		/// </param>
		/// <returns>
		///     A code of how the word sounds
		/// </returns>
		public string PhoneticCode(string word)
		{
			string tempWord = word.ToUpper();
			string prevWord = "";
			StringBuilder code = new StringBuilder();

			while (tempWord.Length > 0)
			{
				// save previous word
				prevWord = tempWord;
				foreach (PhoneticRule rule in _phoneticRules)
				{
					bool begining = tempWord.Length == word.Length ? true : false;
					bool ending = rule.ConditionCount == tempWord.Length ? true : false;

					if ((rule.BeginningOnly == begining || !rule.BeginningOnly)
						&& (rule.EndOnly == ending || !rule.EndOnly)
						&& rule.ConditionCount <= tempWord.Length)
					{
						int passCount = 0;
						// loop through conditions
						for (int i = 0;  i < rule.ConditionCount; i++) 
						{
							int charCode = (int)tempWord[i];
							if ((rule.Condition[charCode] & (1 << i)) == (1 << i))
							{
								passCount++; // condition passed
							}
							else 
							{
								break; // rule fails if one condition fails
							}
						}
						// if all condtions passed
						if (passCount == rule.ConditionCount)
						{
							if (rule.ReplaceMode)
							{
								tempWord = rule.ReplaceString + tempWord.Substring(rule.ConditionCount - rule.ConsumeCount);
							}
							else
							{
								if (rule.ReplaceString != "_")
								{
									code.Append(rule.ReplaceString);
								}
								tempWord = tempWord.Substring(rule.ConditionCount - rule.ConsumeCount);
							}
							break;
						}
					} 
				} // for each

				// if no match consume one char
				if (prevWord.Length == tempWord.Length) 
				{
					
					tempWord = tempWord.Substring(1);
				}
			}// while

			return code.ToString();
		}

		/// <summary>
		///     Removes a word from the user list
		/// </summary>
		/// <param name="word" type="string">
		///     <para>
		///         The word to remove
		///     </para>
		/// </param>
		/// <remarks>
		///		This method is only affects the user word list
		/// </remarks>
		public void Remove(string word)
		{
			_userWords.Remove(word);
			this.SaveUserFile();
		}

		/// <summary> 
		/// Clean up any resources being used.
		/// </summary>
		protected override void Dispose( bool disposing )
		{
			if( disposing )
			{
				if(components != null)
				{
					components.Dispose();
				}
			}
			base.Dispose( disposing );
		}

		/// <summary>
		///     The collection of base words for the dictionary
		/// </summary>
		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public Hashtable BaseWords
		{
			get {return _baseWords;}
		}

		/// <summary>
		///     Copyright text for the dictionary
		/// </summary>
		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public string Copyright
		{
			get {return _copyright;}
			set {_copyright = value;}
		}

		/// <summary>
		///     The file name for the main dictionary
		/// </summary>
		[DefaultValue("en-US.dic")]
		[CategoryAttribute("Dictionary")]
		[Description("The file name for the main dictionary")]
		[NotifyParentProperty(true)]
		public string DictionaryFile
		{
			get {return _dictionaryFile;}
			set 
			{
				_dictionaryFile = value;
				if (_dictionaryFile.Length == 0)
				{
					_dictionaryFile = Thread.CurrentThread.CurrentCulture.Name + ".dic";
				}
			}
		}


		/// <summary>
		///     Folder containing the dictionaries
		/// </summary>
		[DefaultValue("")]
		[CategoryAttribute("Dictionary")]
		[Description("The folder containing dictionaries")]
		[Editor(typeof(FolderNameEditor), typeof(UITypeEditor))]
		[NotifyParentProperty(true)]
		public string DictionaryFolder
		{
			get {return _dictionaryFolder;}
			set {_dictionaryFolder = value;}
		}

		/// <summary>
		///     Set this to true to automaticly create a user dictionary when
		///     a word is added.
		/// </summary>
		/// <remarks>
		///		This should be set to false in a web environment
		/// </remarks>
		[DefaultValue(true)]
		[CategoryAttribute("Options")]
		[Description("Set this to true to automaticly create a user dictionary")]
		[NotifyParentProperty(true)]
		public bool EnableUserFile
		{
			get {return _enableUserFile;}
			set {_enableUserFile = value;}
		}


		/// <summary>
		///     True if the dictionary has been initialized
		/// </summary>
		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public bool Initialized
		{
			get {return _initialized;}
		}


		/// <summary>
		///     Collection of phonetic rules for this dictionary
		/// </summary>
		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public PhoneticRuleCollection PhoneticRules
		{
			get {return _phoneticRules;}
		}


		/// <summary>
		///     Collection of affix prefixes for the base words in this dictionary
		/// </summary>
		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public AffixRuleCollection PrefixRules
		{
			get {return _prefixRules;}
		}

		/// <summary>
		///     List of characters to use when generating suggestions using the near miss stratigy
		/// </summary>
		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public ArrayList ReplaceCharacters
		{
			get {return _replaceCharacters;}
		}


		/// <summary>
		///     Collection of affix suffixes for the base words in this dictionary
		/// </summary>
		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public AffixRuleCollection SuffixRules
		{
			get {return _suffixRules;}
		}

		/// <summary>
		///     List of characters to try when generating suggestions using the near miss stratigy
		/// </summary>
		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public string TryCharacters
		{
			get {return _tryCharacters;}
			set {_tryCharacters = value;}
		}

		/// <summary>
		///     The file name for the user word list for this dictionary
		/// </summary>
		[DefaultValue("user.dic")]
		[CategoryAttribute("Dictionary")]
		[Description("The file name for the user word list for this dictionary")]
		[NotifyParentProperty(true)]
		public string UserFile
		{
			get {return _userFile;}
			set {_userFile = value;}
		}

		/// <summary>
		///     List of user entered words in this dictionary
		/// </summary>
		[Browsable(false)]
		[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
		public Hashtable UserWords
		{
			get {return _userWords;}
		}

		/// <summary>
		///     List of text saved from when 'Contains' is called. 
		///     This list is used to generate suggestions from if Contains
		///     doesn't find a word.
		/// </summary>
		/// <remarks>
		///		These are not actual words.
		/// </remarks>
		internal ArrayList PossibleBaseWords
		{
			get {return _possibleBaseWords;}
		}


		#region Component Designer generated code
		/// <summary>
		/// Required method for Designer support - do not modify
		/// the contents of this method with the code editor.
		/// </summary>
		private void InitializeComponent()
		{
			components = new System.ComponentModel.Container();
		}
		#endregion
		
	}

}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Vietdungiitb
Vietnam Maritime University
Vietnam Vietnam
No Biography provided

| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 10 Apr 2013
Article Copyright 2013 by Vietdungiitb
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid