source: trunk/NewView/TextSearchQuery.pas@ 18

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

+ newview source

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