Prechádzať zdrojové kódy

Merged revisions 10272-10274 via svnmerge from
http://svn.freepascal.org/svn/fpc/trunk

........
r10272 | peter | 2008-02-10 16:55:39 +0100 (Sun, 10 Feb 2008) | 2 lines

* rename scheck to spellcheck
........
r10274 | Almindor | 2008-02-10 17:09:23 +0100 (Sun, 10 Feb 2008) | 2 lines

* update spellcheck unit with new stuff
........

git-svn-id: branches/fixes_2_2@10290 -

peter 17 rokov pred
rodič
commit
bba4ac1a3c

+ 1 - 1
.gitattributes

@@ -872,7 +872,7 @@ packages/aspell/Makefile.fpc svneol=native#text/plain
 packages/aspell/examples/example.pas svneol=native#text/plain
 packages/aspell/fpmake.pp svneol=native#text/plain
 packages/aspell/src/aspell.pp svneol=native#text/plain
-packages/aspell/src/scheck.pp svneol=native#text/plain
+packages/aspell/src/spellcheck.pp svneol=native#text/plain
 packages/bfd/Makefile svneol=native#text/plain
 packages/bfd/Makefile.fpc svneol=native#text/plain
 packages/bfd/fpmake.pp svneol=native#text/plain

+ 54 - 54
packages/aspell/Makefile

@@ -1,5 +1,5 @@
 #
-# Don't edit, this file is generated by FPCMake Version 2.0.0 [2008/01/26]
+# Don't edit, this file is generated by FPCMake Version 2.0.0 [2008/01/22]
 #
 default: all
 MAKEFILETARGETS=i386-linux i386-go32v2 i386-win32 i386-os2 i386-freebsd i386-beos i386-netbsd i386-solaris i386-qnx i386-netware i386-openbsd i386-wdosx i386-darwin i386-emx i386-watcom i386-netwlibc i386-wince i386-embedded i386-symbian m68k-linux m68k-freebsd m68k-netbsd m68k-amiga m68k-atari m68k-openbsd m68k-palmos m68k-embedded powerpc-linux powerpc-netbsd powerpc-amiga powerpc-macos powerpc-darwin powerpc-morphos powerpc-embedded sparc-linux sparc-netbsd sparc-solaris sparc-embedded x86_64-linux x86_64-freebsd x86_64-darwin x86_64-win64 x86_64-embedded arm-linux arm-palmos arm-wince arm-gba arm-nds arm-embedded arm-symbian powerpc64-linux powerpc64-darwin powerpc64-embedded
@@ -243,163 +243,163 @@ PACKAGESDIR:=$(wildcard $(FPCDIR) $(FPCDIR)/packages $(FPCDIR)/packages/base $(F
 override PACKAGE_NAME=aspell
 override PACKAGE_VERSION=1.0.0
 ifeq ($(FULL_TARGET),i386-linux)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),i386-go32v2)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),i386-win32)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),i386-os2)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),i386-freebsd)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),i386-beos)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),i386-netbsd)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),i386-solaris)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),i386-qnx)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),i386-netware)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),i386-openbsd)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),i386-wdosx)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),i386-darwin)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),i386-emx)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),i386-watcom)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),i386-netwlibc)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),i386-wince)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),i386-embedded)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),i386-symbian)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),m68k-linux)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),m68k-freebsd)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),m68k-netbsd)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),m68k-amiga)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),m68k-atari)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),m68k-openbsd)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),m68k-palmos)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),m68k-embedded)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),powerpc-linux)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),powerpc-netbsd)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),powerpc-amiga)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),powerpc-macos)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),powerpc-darwin)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),powerpc-morphos)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),powerpc-embedded)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),sparc-linux)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),sparc-netbsd)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),sparc-solaris)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),sparc-embedded)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),x86_64-linux)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),x86_64-freebsd)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),x86_64-darwin)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),x86_64-win64)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),x86_64-embedded)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),arm-linux)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),arm-palmos)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),arm-wince)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),arm-gba)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),arm-nds)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),arm-embedded)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),arm-symbian)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),powerpc64-linux)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),powerpc64-darwin)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 ifeq ($(FULL_TARGET),powerpc64-embedded)
-override TARGET_UNITS+=aspell scheck
+override TARGET_UNITS+=aspell spellcheck
 endif
 override INSTALL_FPCPACKAGE=y
 ifeq ($(FULL_TARGET),i386-linux)

+ 1 - 1
packages/aspell/Makefile.fpc

@@ -7,7 +7,7 @@ name=aspell
 version=1.0.0
 
 [target]
-units=aspell scheck
+units=aspell spellcheck
 
 [install]
 fpcpackage=y

+ 5 - 2
packages/aspell/fpmake.pp

@@ -16,16 +16,19 @@ begin
 {$ifdef ALLPACKAGES}
     P.Directory:='aspell';
 {$endif ALLPACKAGES}
-    P.Version:='2.0.0';
+    P.Version:='2.2.1';
     P.SourcePath.Add('src');
 
     T:=P.Targets.AddUnit('aspell.pp');
-    T:=P.Targets.AddUnit('scheck.pp');
+    T:=P.Targets.AddUnit('spellcheck.pp');
     with T.Dependencies do
       begin
         AddUnit('aspell');
        end;
 
+    P.Sources.AddSrc('LICENSE');
+    P.Sources.AddSrc('LICENSE.ADDON');
+    
 {$ifndef ALLPACKAGES}
     Run;
     end;

+ 0 - 152
packages/aspell/src/scheck.pp

@@ -1,152 +0,0 @@
-unit sCheck;
-
-{ Simple unit to simplify/OOP-ize pascal-style the aspell interface. Currently
-  very limited, will be expanded eventually. Use like you wish. }
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
-  SysUtils, Aspell;
-
-type
-  TSuggestionArray = array of string;
-  
-  { TSpellCheck }
-
-  TSpellCheck = class
-   protected
-    FSpeller: PAspellSpeller;
-    FMode: string;
-    FEncoding: string;
-    FLanguage: string;
-    procedure SetEncoding(const AValue: string);
-    procedure SetLanguage(const AValue: string);
-    procedure SetMode(const AValue: string);
-    procedure CreateSpeller;
-    procedure FreeSpeller;
-   public
-    constructor Create;
-    destructor Destroy; override;
-    function SpellCheck(const Word: string): TSuggestionArray;
-   public
-    property Mode: string read FMode write SetMode;
-    property Encoding: string read FEncoding write SetEncoding;
-    property Language: string read FLanguage write SetLanguage;
-  end;
-
-implementation
-
-const
-  DEFAULT_ENCODING = 'utf-8';
-  DEFAULT_LANGUAGE = 'en';
-  DEFAULT_MODE     = '';
-
-function GetDefaultLanguage: string;
-begin
-  Result := GetEnvironmentVariable('LANG');
-  if Length(Result) = 0 then
-    Result := DEFAULT_LANGUAGE;
-end;
-
-{ TSpellCheck }
-
-procedure TSpellCheck.SetEncoding(const AValue: string);
-begin
-  FEncoding := aValue;
-  CreateSpeller;
-end;
-
-procedure TSpellCheck.SetLanguage(const AValue: string);
-begin
-  FLanguage := aValue;
-  CreateSpeller;
-end;
-
-procedure TSpellCheck.SetMode(const AValue: string);
-begin
-  FMode := aValue;
-  CreateSpeller;
-end;
-
-procedure TSpellCheck.CreateSpeller;
-var
-  Config: Paspellconfig;
-  Error: Paspellcanhaveerror;
-begin
-  Config := new_aspell_config();
-
-  if Length(FLanguage) > 0 then
-    aspell_config_replace(Config, 'lang', pChar(FLanguage));
-  if Length(FEncoding) > 0 then
-    aspell_config_replace(Config, 'encoding', pChar(FEncoding));
-  if Length(FMode) > 0 then
-    aspell_config_replace(Config, 'mode', pChar(FMode));
-
-  Error := new_aspell_speller(Config);
-
-  delete_aspell_config(Config);
-  FreeSpeller;
-
-  if aspell_error_number(Error) <> 0 then
-    raise Exception.Create('Error on speller creation: ' + aspell_error_message(Error))
-  else
-    FSpeller := to_aspell_speller(Error);
-end;
-
-procedure TSpellCheck.FreeSpeller;
-begin
-  if Assigned(FSpeller) then begin
-    delete_aspell_speller(FSpeller);
-    FSpeller := nil;
-  end;
-end;
-
-constructor TSpellCheck.Create;
-begin
-  FEncoding := DEFAULT_ENCODING;
-  FLanguage := GetDefaultLanguage;
-  FMode := DEFAULT_MODE;
-
-  CreateSpeller;
-end;
-
-destructor TSpellCheck.Destroy;
-begin
-  FreeSpeller;
-end;
-
-function TSpellCheck.SpellCheck(const Word: string): TSuggestionArray;
-var
-  sgs: Paspellwordlist;
-  elm: Paspellstringenumeration;
-  tmp: pChar;
-  i: Integer = 0;
-begin
-  SetLength(Result, 0);
-
-  if aspell_speller_check(FSpeller, pChar(Word), Length(Word)) = 0 then begin
-    sgs := aspell_speller_suggest(FSpeller, pChar(Word), Length(Word));
-    elm := aspell_word_list_elements(sgs);
-
-    repeat
-      if i >= Length(Result) then
-        SetLength(Result, Length(Result) + 10);
-
-      tmp := aspell_string_enumeration_next(elm);
-
-      if tmp <> nil then begin
-        Result[i] := tmp;
-        Inc(i);
-      end;
-    until tmp = nil;
-
-    SetLength(Result, i);
-
-    delete_aspell_string_enumeration(elm);
-  end;
-end;
-
-end.
-

+ 320 - 0
packages/aspell/src/spellcheck.pp

@@ -0,0 +1,320 @@
+unit SpellCheck;
+
+{ Simple unit to simplify/OOP-ize pascal-style the aspell interface. Currently
+  very limited, will be expanded eventually. Use like you wish. }
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+  SysUtils, Classes, Aspell;
+
+type
+  TSuggestionArray = array of string;
+  
+  TWordError = record
+    Word: string; // the word itself
+    Pos: LongWord; // word position in line
+    Length: LongWord; // word length
+    Suggestions: TSuggestionArray; // suggestions for the given word
+  end;
+  
+  TLineErrors = array of TWordError;
+  TLineErrorsArray = array of TLineErrors;
+
+  { TSpeller }
+  { Abstract ancestor, don't use directly }
+
+  TSpeller = class // abstract class, basis for all checkers
+   protected
+    FMode: string;
+    FEncoding: string;
+    FLanguage: string;
+    procedure SetEncoding(const AValue: string);
+    procedure SetLanguage(const AValue: string);
+    procedure SetMode(const AValue: string);
+    procedure CreateSpeller; virtual; abstract;
+    procedure FreeSpeller; virtual; abstract;
+   public
+    constructor Create;
+    destructor Destroy; override;
+   public
+    property Mode: string read FMode write SetMode;
+    property Encoding: string read FEncoding write SetEncoding;
+    property Language: string read FLanguage write SetLanguage;
+  end;
+
+  { TWordSpeller }
+  { Basic spelling class for spelling single words without context }
+  
+  TWordSpeller = class(TSpeller) // class for simple per-word checking
+   private
+    FSpeller: PAspellSpeller;
+   protected
+    procedure CreateSpeller; override;
+    procedure FreeSpeller; override;
+   public
+    function SpellCheck(const Word: string): TSuggestionArray; // use to check single words, parsed out by you
+  end;
+  
+  { TDocumentSpeller }
+  { This speller is used to spellcheck lines or even whole documents.
+    It is usefull when different mode (like "tex") is used so you can pass
+    everything to aspell and let it take care of the context }
+
+  TDocumentSpeller = class(TWordSpeller)
+   private
+    FChecker: PAspellDocumentChecker;
+    FLineErrors: TLineErrorsArray;
+    FNameSuggestions: Boolean;
+    function GetLineErrors(i: Integer): TLineErrors;
+    function GetLineErrorsCount: Integer;
+   protected
+    procedure CreateSpeller; override;
+    procedure FreeSpeller; override;
+    procedure DoNameSuggestions(const Word: string; var aWordError: TWordError);
+   public
+    constructor Create;
+    function CheckLine(const aLine: string): TLineErrors;
+    function CheckDocument(const FileName: string): Integer; // returns number of spelling errors found or -1 for error
+    function CheckDocument(aStringList: TStringList): Integer; // returns number of spelling errors found or -1 for error
+    procedure Reset;
+   public
+    property LineErrors[i: Integer]: TLineErrors read GetLineErrors;
+    property LineErrorsCount: Integer read GetLineErrorsCount;
+    property NameSuggestions: Boolean read FNameSuggestions write FNameSuggestions;
+  end;
+
+implementation
+
+const
+  DEFAULT_ENCODING = 'utf-8';
+  DEFAULT_LANGUAGE = 'en';
+  DEFAULT_MODE     = '';
+
+function GetDefaultLanguage: string;
+begin
+  Result := GetEnvironmentVariable('LANG');
+  if Length(Result) = 0 then
+    Result := DEFAULT_LANGUAGE;
+end;
+
+{ TSpeller }
+
+procedure TSpeller.SetEncoding(const AValue: string);
+begin
+  FEncoding := aValue;
+  CreateSpeller;
+end;
+
+procedure TSpeller.SetLanguage(const AValue: string);
+begin
+  FLanguage := aValue;
+  CreateSpeller;
+end;
+
+procedure TSpeller.SetMode(const AValue: string);
+begin
+  FMode := aValue;
+  CreateSpeller;
+end;
+
+constructor TSpeller.Create;
+begin
+  FEncoding := DEFAULT_ENCODING;
+  FLanguage := GetDefaultLanguage;
+  FMode := DEFAULT_MODE;
+
+  CreateSpeller;
+end;
+
+destructor TSpeller.Destroy;
+begin
+  FreeSpeller;
+end;
+
+{ TWordSpeller }
+
+procedure TWordSpeller.CreateSpeller;
+var
+  Config: Paspellconfig;
+  Error: Paspellcanhaveerror;
+begin
+  Config := new_aspell_config();
+
+  if Length(FLanguage) > 0 then
+    aspell_config_replace(Config, 'lang', pChar(FLanguage));
+  if Length(FEncoding) > 0 then
+    aspell_config_replace(Config, 'encoding', pChar(FEncoding));
+  if Length(FMode) > 0 then
+    aspell_config_replace(Config, 'mode', pChar(FMode));
+
+  Error := new_aspell_speller(Config);
+
+  delete_aspell_config(Config);
+  FreeSpeller;
+
+  if aspell_error_number(Error) <> 0 then
+    raise Exception.Create('Error on speller creation: ' + aspell_error_message(Error))
+  else
+    FSpeller := to_aspell_speller(Error);
+end;
+
+procedure TWordSpeller.FreeSpeller;
+begin
+  if Assigned(FSpeller) then begin
+    delete_aspell_speller(FSpeller);
+    FSpeller := nil;
+  end;
+end;
+
+function TWordSpeller.SpellCheck(const Word: string): TSuggestionArray;
+var
+  sgs: Paspellwordlist;
+  elm: Paspellstringenumeration;
+  tmp: pChar;
+  i: Integer = 0;
+begin
+  SetLength(Result, 0);
+
+  if aspell_speller_check(FSpeller, pChar(Word), Length(Word)) = 0 then begin
+    sgs := aspell_speller_suggest(FSpeller, pChar(Word), Length(Word));
+    elm := aspell_word_list_elements(sgs);
+
+    repeat
+      if i >= Length(Result) then
+        SetLength(Result, Length(Result) + 10);
+
+      tmp := aspell_string_enumeration_next(elm);
+
+      if tmp <> nil then begin
+        Result[i] := tmp;
+        Inc(i);
+      end;
+    until tmp = nil;
+
+    SetLength(Result, i);
+
+    delete_aspell_string_enumeration(elm);
+  end;
+end;
+
+{ TDocumentSpeller }
+
+function TDocumentSpeller.GetLineErrors(i: Integer): TLineErrors;
+begin
+  Result := FLineErrors[i];
+end;
+
+function TDocumentSpeller.GetLineErrorsCount: Integer;
+begin
+  Result := Length(FLineErrors);
+end;
+
+procedure TDocumentSpeller.CreateSpeller;
+var
+  Error: PAspellCanHaveError;
+begin
+  inherited CreateSpeller;
+  
+  Error := new_aspell_document_checker(FSpeller);
+
+  if aspell_error_number(Error) <> 0 then
+    raise Exception.Create('Error on checker creation: ' + aspell_error_message(Error))
+  else
+    FChecker := to_aspell_document_checker(Error);
+end;
+
+procedure TDocumentSpeller.FreeSpeller;
+begin
+  if Assigned(FChecker) then begin
+    delete_aspell_document_checker(FChecker);
+    FChecker := nil;
+  end;
+
+  inherited FreeSpeller;
+end;
+
+procedure TDocumentSpeller.DoNameSuggestions(const Word: string;
+  var aWordError: TWordError);
+begin
+  aWordError.Suggestions := SpellCheck(Word);
+end;
+
+constructor TDocumentSpeller.Create;
+begin
+  inherited Create;
+  
+  FNameSuggestions := True;
+end;
+
+function TDocumentSpeller.CheckLine(const aLine: string): TLineErrors;
+const
+  CHUNK_SIZE = 10;
+var
+  i, Count: Integer;
+  Token: AspellToken;
+begin
+  aspell_document_checker_process(FChecker, pChar(aLine), Length(aLine));
+
+  SetLength(Result, CHUNK_SIZE);
+  i := 0;
+  Count := 0;
+  repeat
+    Token := aspell_document_checker_next_misspelling(FChecker);
+
+    if Token.len > 0 then begin
+      if Length(Result) <= i then
+        SetLength(Result, Length(Result) + CHUNK_SIZE);
+
+      Result[i].Word := Copy(aLine, Token.offset + 1, Token.len);
+      Result[i].Pos := Token.offset + 1; // C goes from 0, we go from 1
+      Result[i].Length := Token.len;
+
+      if FNameSuggestions then
+        DoNameSuggestions(Copy(aLine, Token.offset + 1, Token.len), Result[i]);
+        
+      Inc(Count);
+    end;
+
+    Inc(i);
+  until Token.len = 0;
+  
+  SetLength(Result, Count);
+end;
+
+function TDocumentSpeller.CheckDocument(const FileName: string): Integer;
+var
+  s: TStringList;
+begin
+  Result := 0;
+  if FileExists(FileName) then try
+    s := TStringList.Create;
+    s.LoadFromFile(FileName);
+    Result := CheckDocument(s);
+  finally
+    s.Free;
+  end;
+end;
+
+function TDocumentSpeller.CheckDocument(aStringList: TStringList): Integer;
+var
+  i: Integer;
+begin
+  Result := 0;
+  SetLength(FLineErrors, aStringList.Count);
+
+  for i := 0 to aStringList.Count - 1 do begin
+    FLineErrors[i] := CheckLine(aStringList[i]);
+    Inc(Result, Length(FLineErrors[i]));
+  end;
+end;
+
+procedure TDocumentSpeller.Reset;
+begin
+  aspell_document_checker_reset(FChecker);
+end;
+
+end.
+