diff options
author | Graeme Geldenhuys <graeme@mastermaths.co.za> | 2009-10-14 15:17:19 +0200 |
---|---|---|
committer | Graeme Geldenhuys <graeme@mastermaths.co.za> | 2009-10-14 15:17:19 +0200 |
commit | 0c3ee724d18256689ca58b2f7c518279de456539 (patch) | |
tree | 05d051d1cdae2f59951d7866a9d220d9e6532e23 | |
parent | d7b5d307e6a06601d093e9663a22f8157d25336c (diff) | |
download | fpGUI-0c3ee724d18256689ca58b2f7c518279de456539.tar.xz |
updated TextSearchQuery to latest NevView sources.
-rw-r--r-- | src/TextSearchQuery.pas | 179 |
1 files changed, 125 insertions, 54 deletions
diff --git a/src/TextSearchQuery.pas b/src/TextSearchQuery.pas index d4a7a6ba..444b27f1 100644 --- a/src/TextSearchQuery.pas +++ b/src/TextSearchQuery.pas @@ -3,7 +3,7 @@ Unit TextSearchQuery; {$mode objfpc}{$H+} // NewView - a new OS/2 Help Viewer -// Copyright 2001 Aaron Lawrence (aaronl at consultant dot com) +// Copyright 2003 Aaron Lawrence (aaronl at consultant dot com) // This software is released under the Gnu Public License - see readme.txt Interface @@ -17,75 +17,100 @@ Type ESearchSyntaxError = class( Exception ) end; - TSearchTermCombineMethod = ( cmOr, cmAnd, cmNot ); + TSearchTermCombineMethod = + ( + cmOptional, + cmRequired, + cmExcluded + ); - TSearchTerm = class + TSearchTerm = class(TObject) + public Text: string; + Parts: TStringList; CombineMethod: TSearchTermCombineMethod; + constructor Create( const TheText: string; + const TheCombineMethod: TSearchTermCombineMethod ); + destructor Destroy; override; end; - TTextSearchQuery = class - private - procedure Cleanup; + + TTextSearchQuery = class(TObject) protected Terms: TList; function GetTerm( Index: longint ): TSearchTerm; function GetTermCount: longint; public - constructor Create( SearchString: string ); - destructor Destroy; override; - - property Term[ Index: longint ]: TSearchTerm read GetTerm; - property TermCount: longint read GetTermCount; + constructor Create( const SearchString: string ); + destructor Destroy; override; + property Term[ Index: longint ]: TSearchTerm read GetTerm; + property TermCount: longint read GetTermCount; end; -Implementation + +implementation uses - nvUtilities; -// ACLStringUtility, ACLUtility, Dialogs; + nvUtilities + ,ACLStringUtility + ; + + +const + QueryErrorMissingWord1 = 'No search word given after'; + QueryErrorMissingWord2 = ' before '; -constructor TTextSearchQuery.Create( SearchString: string ); + +constructor TTextSearchQuery.Create( const SearchString: string ); var - SearchWord: string; - RemainingSearchString: string; + TermText: string; CombineMethod: TSearchTermCombineMethod; lTerm: TSearchTerm; + tmpTerms : TStringList; + i : integer; begin inherited Create; Terms := TList.Create; try - RemainingSearchString := Uppercase( SearchString ); - while RemainingSearchString <> '' do + tmpTerms := TStringList.Create; + StrExtractStringsQuoted(tmpTerms, SearchString); + + for i := 0 to tmpTerms.count-1 do begin - SearchWord := ExtractNextValue( RemainingSearchString, ' ' ); + TermText := tmpTerms[i]; - // Check for modifiers + (word must be matched) - // and - (word must not be matched) - case SearchWord[ 1 ] of + // Check for modifiers: + // + word must be matched + // - word must not be matched + case TermText[ 1 ] of '+': - CombineMethod := cmAnd; + CombineMethod := cmRequired; '-': - CombineMethod := cmNot; + CombineMethod := cmExcluded; else - CombineMethod := cmOr; + CombineMethod := cmOptional; end; - if CombineMethod <> cmOr then + + if CombineMethod <> cmOptional then begin // delete + or - - if Length( SearchWord ) = 1 then - raise ESearchSyntaxError.Create( 'No search word given after "' - + SearchWord + '" before "' - + RemainingSearchString - + '"' ); - Delete( SearchWord, 1, 1 ); + if Length( TermText ) = 1 then + if (i < tmpTerms.count-1) then + raise ESearchSyntaxError.Create( QueryErrorMissingWord1 + + StrInDoubleQuotes(TermText) + + QueryErrorMissingWord2 + + StrInDoubleQuotes(tmpTerms[i+1]) ) + else + raise ESearchSyntaxError.Create( QueryErrorMissingWord1 + + StrInDoubleQuotes(TermText)); + Delete( TermText, 1, 1 ); end; - lTerm := TSearchTerm.Create; - lTerm.Text := SearchWord; - lTerm.CombineMethod := CombineMethod; + lTerm := TSearchTerm.Create( TermText, + CombineMethod ); Terms.Add( lTerm ); end; + tmpTerms.Free; except while Terms.Count > 0 do begin @@ -100,38 +125,84 @@ end; destructor TTextSearchQuery.Destroy; begin - Cleanup; + DestroyListObjects( Terms ); + Terms.Free; inherited Destroy; end; -procedure TTextSearchQuery.Cleanup; +function TTextSearchQuery.GetTerm( index: longint ): TSearchTerm; +begin + Result := TSearchTerm(Terms[ Index ]); +end; + +function TTextSearchQuery.GetTermCount: longint; +begin + Result := Terms.Count; +end; + +constructor TSearchTerm.Create( const TheText: string; + const TheCombineMethod: TSearchTermCombineMethod ); var - i: TSearchTerm; + TermParseIndex: longint; + TermChar: char; + TermPart: string; begin - if Assigned(Terms) then + Parts := TStringList.Create; + + Text := TheText; + CombineMethod := TheCombineMethod; + + // Break out each part of the term as IPF does: + // consecutive alphanumeric chars become a "word" + // but each symbol is a separate word, and symbols break + // up alphanumerics into multiple words. e.g. + // CAKE_SAUSAGE becomes three words in IPF, + // one each for "CAKE" "_" and "SAUSAGE" + + TermParseIndex := 1; + while TermParseIndex <= Length( Text ) do begin - while Terms.Count > 0 do + // collect alphanumeric chars + TermPart := ''; + while TermParseIndex <= Length( Text ) do + begin + TermChar := Text[ TermParseIndex ]; + if ( IsAlpha( TermChar ) + or IsDigit( TermChar ) ) then + begin + // alpha numeric, collect it + TermPart := TermPart + TermChar; + inc( TermParseIndex ); + end + else + begin + // not alpha numeric, so stop + break; + end; + end; + if Length( TermPart ) > 0 then begin - i := TSearchTerm(Terms.Last); - Terms.Remove(i); - i.Free; + Parts.Add( TermPart ); // add collected alphanumeric part + end; + + if TermParseIndex <= Length( Text ) then + begin + // must be a symbol, + // each symbol (excluding space) is an individual item + if Text[ TermParseIndex ] <> ' ' then + Parts.Add( Text[ TermParseIndex ] ); + inc( TermParseIndex ); end; - // DestroyListObjects( Terms ); - Terms.Free; end; end; -function TTextSearchQuery.GetTerm( index: longint ): TSearchTerm; +destructor TSearchTerm.Destroy; begin - Result := TSearchTerm(Terms[ Index ]); + Parts.Free; + inherited Destroy; end; -function TTextSearchQuery.GetTermCount: longint; -begin - Result := Terms.Count; -end; -Initialization -End. +end. |