source: branches/2.19_branch/NewView/TextSearchQuery.pas@ 324

Last change on this file since 324 was 116, checked in by RBRi, 18 years ago

changed to use StringUtilsUnit

  • Property svn:eol-style set to native
File size: 5.0 KB
Line 
1Unit TextSearchQuery;
2
3// NewView - a new OS/2 Help Viewer
4// Copyright 2003 Aaron Lawrence (aaronl at consultant dot com)
5// This software is released under the Gnu Public License - see readme.txt
6
7Interface
8
9// Encapsulates a parsed search query.
10
11uses
12 Classes,
13 SysUtils;
14
15Type
16 ESearchSyntaxError = class( Exception )
17 end;
18
19 TSearchTermCombineMethod =
20 (
21 cmOptional,
22 cmRequired,
23 cmExcluded
24 );
25
26 TSearchTerm = class
27 Text: string;
28 Parts: TStringList;
29 CombineMethod: TSearchTermCombineMethod;
30
31 constructor Create( const TheText: string;
32 const TheCombineMethod: TSearchTermCombineMethod );
33 destructor Destroy; override;
34 end;
35
36 TTextSearchQuery = class
37 protected
38 Terms: TList;
39 function GetTerm( Index: longint ): TSearchTerm;
40 function GetTermCount: longint;
41 public
42 constructor Create( const SearchString: string );
43 destructor Destroy; override;
44
45 property Term[ Index: longint ]: TSearchTerm read GetTerm;
46 property TermCount: longint read GetTermCount;
47 end;
48
49Implementation
50
51uses
52 ACLUtility,
53 ACLLanguageUnit,
54 CharUtilsUnit,
55 StringUtilsUnit,
56 DebugUnit;
57
58var
59 QueryErrorMissingWord1: string;
60 QueryErrorMissingWord2: string;
61
62Procedure OnLanguageEvent( Language: TLanguageFile;
63 const Apply: boolean );
64begin
65
66 Language.Prefix := 'SearchQuery.';
67 Language.LL( Apply, QueryErrorMissingWord1, 'QueryErrorMissingWord1', 'No search word given after ' );
68 Language.LL( Apply, QueryErrorMissingWord2, 'QueryErrorMissingWord2', ' before ' );
69end;
70
71constructor TTextSearchQuery.Create( const SearchString: string );
72var
73 TermText: string;
74 CombineMethod: TSearchTermCombineMethod;
75 Term: TSearchTerm;
76 tmpTerms : TStringList;
77 i : integer;
78begin
79 Terms := TList.Create;
80 try
81 tmpTerms := TStringList.Create;
82 StrExtractStringsQuoted(tmpTerms, SearchString);
83
84 for i := 0 to tmpTerms.count-1 do
85 begin
86 TermText := tmpTerms[i];
87
88 // Check for modifiers:
89 // + word must be matched
90 // - word must not be matched
91 case TermText[ 1 ] of
92 '+':
93 CombineMethod := cmRequired;
94 '-':
95 CombineMethod := cmExcluded;
96 else
97 CombineMethod := cmOptional;
98 end;
99
100 if CombineMethod <> cmOptional then
101 begin
102 // delete + or -
103 if Length( TermText ) = 1 then
104 if (i < tmpTerms.count-1) then
105 raise ESearchSyntaxError.Create( QueryErrorMissingWord1
106 + StrInDoubleQuotes(TermText)
107 + QueryErrorMissingWord2
108 + StrInDoubleQuotes(tmpTerms[i+1]) )
109 else
110 raise ESearchSyntaxError.Create( QueryErrorMissingWord1
111 + StrInDoubleQuotes(TermText));
112 Delete( TermText, 1, 1 );
113 end;
114
115 Term := TSearchTerm.Create( TermText,
116 CombineMethod );
117 Terms.Add( Term );
118 end;
119 tmpTerms.Destroy;
120 except
121 tmpTerms.Destroy;
122 Destroy; // clean up
123 raise; // reraise exception
124 end;
125end;
126
127destructor TTextSearchQuery.Destroy;
128begin
129 DestroyListObjects( Terms );
130 Terms.Destroy;
131end;
132
133function TTextSearchQuery.GetTerm( index: longint ): TSearchTerm;
134begin
135 Result := Terms[ Index ];
136end;
137
138function TTextSearchQuery.GetTermCount: longint;
139begin
140 Result := Terms.Count;
141end;
142
143constructor TSearchTerm.Create( const TheText: string;
144 const TheCombineMethod: TSearchTermCombineMethod );
145var
146 TermParseIndex: longint;
147 TermChar: char;
148 TermPart: string;
149begin
150 Parts := TStringList.Create;
151
152 Text := TheText;
153 CombineMethod := TheCombineMethod;
154
155 // Break out each part of the term as IPF does:
156 // consecutive alphanumeric chars become a "word"
157 // but each symbol is a separate word, and symbols break
158 // up alphanumerics into multiple words. e.g.
159 // CAKE_SAUSAGE becomes three words in IPF,
160 // one each for "CAKE" "_" and "SAUSAGE"
161
162 TermParseIndex := 1;
163 while TermParseIndex <= Length( Text ) do
164 begin
165 // collect alphanumeric chars
166 TermPart := '';
167 while TermParseIndex <= Length( Text ) do
168 begin
169 TermChar := Text[ TermParseIndex ];
170 if ( CharIsAlpha( TermChar )
171 or CharIsDigit( TermChar ) ) then
172 begin
173 // alpha numeric, collect it
174 TermPart := TermPart + TermChar;
175 inc( TermParseIndex );
176 end
177 else
178 begin
179 // not alpha numeric, so stop
180 break;
181 end;
182 end;
183 if Length( TermPart ) > 0 then
184 begin
185 Parts.Add( TermPart ); // add collected alphanumeric part
186 end;
187
188 if TermParseIndex <= Length( Text ) then
189 begin
190 // must be a symbol,
191 // each symbol (excluding space) is an individual item
192 if Text[ TermParseIndex ] <> ' ' then
193 Parts.Add( Text[ TermParseIndex ] );
194 inc( TermParseIndex );
195 end;
196
197 end;
198
199end;
200
201destructor TSearchTerm.Destroy;
202begin
203 Parts.Destroy;
204end;
205
206Initialization
207 RegisterProcForLanguages( OnLanguageEvent );
208End.
Note: See TracBrowser for help on using the repository browser.