source: trunk/NewView/TextSearchQuery.pas@ 33

Last change on this file since 33 was 33, checked in by RBRi, 19 years ago

more uses cleanup

  • Property svn:eol-style set to native
File size: 4.9 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 ACLStringUtility,
53 ACLUtility,
54 ACLLanguageUnit;
55
56var
57 QueryErrorMissingWord1: string;
58 QueryErrorMissingWord2: string;
59
60Procedure OnLanguageEvent( Language: TLanguageFile;
61 const Apply: boolean );
62begin
63
64 Language.Prefix := 'SearchQuery.';
65 Language.LL( Apply, QueryErrorMissingWord1, 'QueryErrorMissingWord1', 'No search word given after ' );
66 Language.LL( Apply, QueryErrorMissingWord2, 'QueryErrorMissingWord2', ' before ' );
67end;
68
69constructor TTextSearchQuery.Create( const SearchString: string );
70var
71 TermText: string;
72 CombineMethod: TSearchTermCombineMethod;
73 Term: TSearchTerm;
74 ParseIndex: longint;
75begin
76 Terms := TList.Create;
77 try
78 ParseIndex := 1;
79 while ParseIndex <= Length( SearchString ) do
80 begin
81 GetNextQuotedValue( SearchString,
82 ParseIndex,
83 TermText,
84 DoubleQuote );
85
86 // Check for modifiers:
87 // + word must be matched
88 // - word must not be matched
89 case TermText[ 1 ] of
90 '+':
91 CombineMethod := cmRequired;
92 '-':
93 CombineMethod := cmExcluded;
94 else
95 CombineMethod := cmOptional;
96 end;
97
98 if CombineMethod <> cmOptional then
99 begin
100 // delete + or -
101 if Length( TermText ) = 1 then
102 raise ESearchSyntaxError.Create( QueryErrorMissingWord1
103 + StrDoubleQuote( TermText )
104 + QueryErrorMissingWord2
105 + StrDoubleQuote( StrRightFrom( SearchString,
106 ParseIndex ) ) );
107 Delete( TermText, 1, 1 );
108 end;
109
110 Term := TSearchTerm.Create( TermText,
111 CombineMethod );
112 Terms.Add( Term );
113 end;
114 except
115 Destroy; // clean up
116 raise; // reraise exception
117 end;
118end;
119
120destructor TTextSearchQuery.Destroy;
121begin
122 DestroyListObjects( Terms );
123 Terms.Destroy;
124end;
125
126function TTextSearchQuery.GetTerm( index: longint ): TSearchTerm;
127begin
128 Result := Terms[ Index ];
129end;
130
131function TTextSearchQuery.GetTermCount: longint;
132begin
133 Result := Terms.Count;
134end;
135
136constructor TSearchTerm.Create( const TheText: string;
137 const TheCombineMethod: TSearchTermCombineMethod );
138var
139 TermParseIndex: longint;
140 TermChar: char;
141 TermPart: string;
142begin
143 Parts := TStringList.Create;
144
145 Text := TheText;
146 CombineMethod := TheCombineMethod;
147
148 // Break out each part of the term as IPF does:
149 // consecutive alphanumeric chars become a "word"
150 // but each symbol is a separate word, and symbols break
151 // up alphanumerics into multiple words. e.g.
152 // CAKE_SAUSAGE becomes three words in IPF,
153 // one each for "CAKE" "_" and "SAUSAGE"
154
155 TermParseIndex := 1;
156 while TermParseIndex <= Length( Text ) do
157 begin
158 // collect alphanumeric chars
159 TermPart := '';
160 while TermParseIndex <= Length( Text ) do
161 begin
162 TermChar := Text[ TermParseIndex ];
163 if ( IsAlpha( TermChar )
164 or IsDigit( TermChar ) ) then
165 begin
166 // alpha numeric, collect it
167 TermPart := TermPart + TermChar;
168 inc( TermParseIndex );
169 end
170 else
171 begin
172 // not alpha numeric, so stop
173 break;
174 end;
175 end;
176 if Length( TermPart ) > 0 then
177 begin
178 Parts.Add( TermPart ); // add collected alphanumeric part
179 end;
180
181 if TermParseIndex <= Length( Text ) then
182 begin
183 // must be a symbol,
184 // each symbol (excluding space) is an individual item
185 if Text[ TermParseIndex ] <> ' ' then
186 Parts.Add( Text[ TermParseIndex ] );
187 inc( TermParseIndex );
188 end;
189
190 end;
191
192end;
193
194destructor TSearchTerm.Destroy;
195begin
196 Parts.Destroy;
197end;
198
199Initialization
200 RegisterProcForLanguages( OnLanguageEvent );
201End.
Note: See TracBrowser for help on using the repository browser.