1 {-------------------------------------------------------------------------------
2 The contents of this file are subject to the Mozilla Public License
3 Version 1.1 (the "License"); you may not use this file except in compliance
4 with the License. You may obtain a copy of the License at
5 http://www.mozilla.org/MPL/
6
7 Software distributed under the License is distributed on an "AS IS" basis,
8 WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
9 the specific language governing rights and limitations under the License.
10
11 The Original Code is: SynHighlighterIni.pas, released 2000-04-21.
12 The Original Code is based on the izIniSyn.pas file from the
13 mwEdit component suite by Martin Waldenburg and other developers, the Initial
14 Author of this file is Igor P. Zenkov.
15 All Rights Reserved.
16
17 Contributors to the SynEdit and mwEdit projects are listed in the
18 Contributors.txt file.
19
20 Alternatively, the contents of this file may be used under the terms of the
21 GNU General Public License Version 2 or later (the "GPL"), in which case
22 the provisions of the GPL are applicable instead of those above.
23 If you wish to allow use of your version of this file only under the terms
24 of the GPL and not to allow others to use your version of this file
25 under the MPL, indicate your decision by deleting the provisions above and
26 replace them with the notice and other provisions required by the GPL.
27 If you do not delete the provisions above, a recipient may use your version
28 of this file under either the MPL or the GPL.
29
30 $Id: SynHighlighterIni.pas,v 1.7 2001/11/09 07:46:17 plpolak Exp $
31
32 You may retrieve the latest version of this file at the SynEdit home page,
33 located at http://SynEdit.SourceForge.net
34
35 Known Issues:
36 -------------------------------------------------------------------------------}
37 {
38 @abstract(Provides an Ini-files highlighter for SynEdit)
39 @author(Igor P. Zenkov, converted to SynEdit by Bruno Mikkelsen <btm@scientist.com>)
40 @created(1999-11-02, converted to SynEdit 2000-04-21)
41 @lastmod(2000-04-21)
42 The SynHighlighterIni unit provides SynEdit with an Ini-files highlighter.
43 Thanks to Primoz Gabrijelcic, Martin Waldenburg and Michael Hieke.
44 }
45 unit SynHighlighterIni;
46
47 {$I SynEdit.inc}
48
49 interface
50
51 uses
52 Classes,
53 Graphics,
54 SynEditTypes, SynEditHighlighter;
55
56 type
57 TtkTokenKind = (tkComment, tkText, tkSection, tkKey, tkNull, tkNumber,
58 tkSpace, tkString, tkSymbol, tkUnknown);
59
60 TProcTableProc = procedure of object;
61
62 type
63
64 { TSynIniSyn }
65
66 TSynIniSyn = class(TSynCustomHighlighter)
67 private
68 fLine: PChar;
69 fLineNumber: Integer;
70 fProcTable: array[#0..#255] of TProcTableProc;
71 Run: LongInt;
72 fTokenPos: Integer;
73 FTokenID: TtkTokenKind;
74 fCommentAttri: TSynHighlighterAttributes;
75 fTextAttri: TSynHighlighterAttributes;
76 fSectionAttri: TSynHighlighterAttributes;
77 fKeyAttri: TSynHighlighterAttributes;
78 fNumberAttri: TSynHighlighterAttributes;
79 fSpaceAttri: TSynHighlighterAttributes;
80 fStringAttri: TSynHighlighterAttributes;
81 fSymbolAttri: TSynHighlighterAttributes;
82 procedure SectionOpenProc;
83 procedure KeyProc;
84 procedure CRProc;
85 procedure EqualProc;
86 procedure TextProc;
87 procedure LFProc;
88 procedure NullProc;
89 procedure NumberProc;
90 procedure SemiColonProc;
91 procedure SpaceProc;
92 procedure StringProc; // ""
93 procedure StringProc1; // ''
94 procedure MakeMethodTables;
95 protected
96 {General Stuff}
GetIdentCharsnull97 function GetIdentChars: TSynIdentChars; override;
GetSampleSourcenull98 function GetSampleSource: String; override;
99 public
GetLanguageNamenull100 class function GetLanguageName: string; override;
101 public
102 constructor Create(AOwner: TComponent); override;
GetDefaultAttributenull103 function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
104 override;
GetEolnull105 function GetEol: Boolean; override;
GetTokenIDnull106 function GetTokenID: TtkTokenKind;
107 procedure SetLine(const NewValue: String; LineNumber:Integer); override;
GetTokennull108 function GetToken: String; override;
109 procedure GetTokenEx(out TokenStart: PChar; out TokenLength: integer); override;
GetTokenAttributenull110 function GetTokenAttribute: TSynHighlighterAttributes; override;
GetTokenKindnull111 function GetTokenKind: integer; override;
GetTokenPosnull112 function GetTokenPos: Integer; override;
113 procedure Next; override;
114 published
115 property CommentAttri: TSynHighlighterAttributes read fCommentAttri
116 write fCommentAttri;
117 property TextAttri : TSynHighlighterAttributes read fTextAttri
118 write fTextAttri;
119 property SectionAttri: TSynHighlighterAttributes read fSectionAttri
120 write fSectionAttri;
121 property KeyAttri : TSynHighlighterAttributes read fKeyAttri
122 write fKeyAttri;
123 property NumberAttri : TSynHighlighterAttributes read fNumberAttri
124 write fNumberAttri;
125 property SpaceAttri : TSynHighlighterAttributes read fSpaceAttri
126 write fSpaceAttri;
127 property StringAttri : TSynHighlighterAttributes read fStringAttri
128 write fStringAttri;
129 property SymbolAttri : TSynHighlighterAttributes read fSymbolAttri
130 write fSymbolAttri;
131 end;
132
133 implementation
134
135 uses
136 SynEditStrConst;
137
138 procedure TSynIniSyn.MakeMethodTables;
139 var
140 i: Char;
141 begin
142 for i := #0 to #255 do
143 case i of
144 #0 : fProcTable[i] := @NullProc;
145 #10 {LF}: fProcTable[i] := @LFProc;
146 #13 {CR}: fProcTable[i] := @CRProc;
147 #34 {"} : fProcTable[i] := @StringProc;
148 #39 {'} : fProcTable[i] := @StringProc1;
149 '0'..'9': fProcTable[i] := @NumberProc;
150 #59 {;} : fProcTable[i] := @SemiColonProc;
151 #61 {=} : fProcTable[i] := @EqualProc;
152 #91 {[} : fProcTable[i] := @SectionOpenProc;
153 #1..#9, #11, #12, #14..#32: fProcTable[i] := @SpaceProc;
154 else
155 fProcTable[i] := @TextProc;
156 end;
157 end;
158
159 constructor TSynIniSyn.Create(AOwner: TComponent);
160 begin
161 inherited Create(AOwner);
162 fCommentAttri := TSynHighlighterAttributes.Create(@SYNS_AttrComment);
163 fCommentAttri.Style := [fsItalic];
164 fCommentAttri.Foreground := clGreen;
165 AddAttribute(fCommentAttri);
166 fTextAttri := TSynHighlighterAttributes.Create(@SYNS_AttrText);
167 AddAttribute(fTextAttri);
168 fSectionAttri := TSynHighlighterAttributes.Create(@SYNS_AttrSection);
169 fSectionAttri.Style := [fsBold];
170 AddAttribute(fSectionAttri);
171 fKeyAttri := TSynHighlighterAttributes.Create(@SYNS_AttrKey);
172 fKeyAttri.Foreground := clBlue;
173 AddAttribute(fKeyAttri);
174 fNumberAttri := TSynHighlighterAttributes.Create(@SYNS_AttrNumber);
175 AddAttribute(fNumberAttri);
176 fSpaceAttri := TSynHighlighterAttributes.Create(@SYNS_AttrSpace);
177 AddAttribute(fSpaceAttri);
178 fStringAttri := TSynHighlighterAttributes.Create(@SYNS_AttrString);
179 AddAttribute(fStringAttri);
180 fSymbolAttri := TSynHighlighterAttributes.Create(@SYNS_AttrSymbol);
181 fSymbolAttri.Foreground := clRed;
182 AddAttribute(fSymbolAttri);
183 SetAttributesOnChange(@DefHighlightChange);
184
185 fDefaultFilter := SYNS_FilterINI;
186 MakeMethodTables;
187 end; { Create }
188
189 procedure TSynIniSyn.SetLine(const NewValue: String; LineNumber:Integer);
190 begin
191 inherited;
192 fLine := PChar(NewValue);
193 Run := 0;
194 fLineNumber := LineNumber;
195 Next;
196 end; { SetLine }
197
198 procedure TSynIniSyn.SectionOpenProc;
199 begin
200 // if it is not column 0 mark as tkText and get out of here
201 if Run > 0 then
202 begin
203 fTokenID := tkText;
204 inc(Run);
205 Exit;
206 end;
207
208 // this is column 0 ok it is a Section
209 fTokenID := tkSection;
210 inc(Run);
211 while FLine[Run] <> #0 do
212 case FLine[Run] of
213 ']': begin inc(Run); break end;
214 #10: break;
215 #13: break;
216 else inc(Run);
217 end;
218 end;
219
220 procedure TSynIniSyn.CRProc;
221 begin
222 fTokenID := tkSpace;
223 Case FLine[Run + 1] of
224 #10: inc(Run, 2);
225 else inc(Run);
226 end;
227 end;
228
229 procedure TSynIniSyn.EqualProc;
230 begin
231 inc(Run);
232 fTokenID := tkSymbol;
233 end;
234
235 procedure TSynIniSyn.KeyProc;
236 begin
237 fTokenID := tkKey;
238 inc(Run);
239 while FLine[Run] <> #0 do
240 case FLine[Run] of
241 '=': break;
242 #10: break;
243 #13: break;
244 else inc(Run);
245 end;
246 end;
247
248 procedure TSynIniSyn.TextProc;
249 begin
250 if Run = 0 then
251 KeyProc
252 else begin
253 inc(Run);
254 while (fLine[Run] in [#128..#191]) OR // continued utf8 subcode
255 ((fLine[Run]<>#0) and (fProcTable[fLine[Run]] = @TextProc)) do inc(Run);
256 fTokenID := tkText;
257 //fTokenID := tkText;
258 //inc(Run);
259 end;
260 end;
261
262 procedure TSynIniSyn.LFProc;
263 begin
264 fTokenID := tkSpace;
265 inc(Run);
266 end;
267
268 procedure TSynIniSyn.NullProc;
269 begin
270 fTokenID := tkNull;
271 end;
272
273 procedure TSynIniSyn.NumberProc;
274 begin
275 if Run = 0 then
276 KeyProc
277 else begin
278 inc(Run);
279 fTokenID := tkNumber;
280 while FLine[Run] in ['0'..'9', '.', 'e', 'E'] do inc(Run);
281 if FLine[Run] in ['a'..'z','A'..'Z'] then TextProc;
282 end;
283 end;
284
285 // ;
286 procedure TSynIniSyn.SemiColonProc;
287 begin
288 // if it is not column 0 mark as tkText and get out of here
289 if Run > 0 then
290 begin
291 fTokenID := tkText;
292 inc(Run);
293 Exit;
294 end;
295
296 // this is column 0 ok it is a comment
297 fTokenID := tkComment;
298 inc(Run);
299 while FLine[Run] <> #0 do
300 case FLine[Run] of
301 #10: break;
302 #13: break;
303 else inc(Run);
304 end;
305 end;
306
307 procedure TSynIniSyn.SpaceProc;
308 begin
309 inc(Run);
310 fTokenID := tkSpace;
311 while FLine[Run] in [#1..#9, #11, #12, #14..#32] do inc(Run);
312 end;
313
314 // ""
315 procedure TSynIniSyn.StringProc;
316 begin
317 fTokenID := tkString;
318 if (FLine[Run + 1] = #34) and (FLine[Run + 2] = #34) then inc(Run, 2);
319 repeat
320 case FLine[Run] of
321 #0, #10, #13: break;
322 end;
323 inc(Run);
324 until FLine[Run] = #34;
325 if FLine[Run] <> #0 then inc(Run);
326 end;
327
328 // ''
329 procedure TSynIniSyn.StringProc1;
330 begin
331 fTokenID := tkString;
332 if (FLine[Run + 1] = #39) and (FLine[Run + 2] = #39) then inc(Run, 2);
333 repeat
334 case FLine[Run] of
335 #0, #10, #13: break;
336 end;
337 inc(Run);
338 until FLine[Run] = #39;
339 if FLine[Run] <> #0 then inc(Run);
340 end;
341
342 procedure TSynIniSyn.Next;
343 begin
344 fTokenPos := Run;
345 fProcTable[fLine[Run]];
346 end;
347
TSynIniSyn.GetDefaultAttributenull348 function TSynIniSyn.GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
349 begin
350 case Index of
351 SYN_ATTR_COMMENT: Result := fCommentAttri;
352 SYN_ATTR_KEYWORD: Result := fKeyAttri;
353 SYN_ATTR_STRING: Result := fStringAttri;
354 SYN_ATTR_WHITESPACE: Result := fSpaceAttri;
355 SYN_ATTR_SYMBOL: Result := fSymbolAttri;
356 SYN_ATTR_NUMBER: Result := fNumberAttri;
357 else
358 Result := nil;
359 end;
360 end;
361
GetEolnull362 function TSynIniSyn.GetEol: Boolean;
363 begin
364 Result := fTokenId = tkNull;
365 end;
366
TSynIniSyn.GetTokennull367 function TSynIniSyn.GetToken: String;
368 var
369 Len: LongInt;
370 begin
371 Len := Run - fTokenPos;
372 SetString(Result, (FLine + fTokenPos), Len);
373 end;
374
375 procedure TSynIniSyn.GetTokenEx(out TokenStart: PChar; out TokenLength: integer);
376 begin
377 TokenLength := Run - fTokenPos;
378 TokenStart := FLine + fTokenPos;
379 end;
380
GetTokenIDnull381 function TSynIniSyn.GetTokenID: TtkTokenKind;
382 begin
383 Result := fTokenId;
384 end;
385
GetTokenAttributenull386 function TSynIniSyn.GetTokenAttribute: TSynHighlighterAttributes;
387 begin
388 case fTokenID of
389 tkComment: Result := fCommentAttri;
390 tkText : Result := fTextAttri;
391 tkSection: Result := fSectionAttri;
392 tkKey : Result := fKeyAttri;
393 tkNumber : Result := fNumberAttri;
394 tkSpace : Result := fSpaceAttri;
395 tkString : Result := fStringAttri;
396 tkSymbol : Result := fSymbolAttri;
397 tkUnknown: Result := fTextAttri;
398 else Result := nil;
399 end;
400 end;
401
GetTokenKindnull402 function TSynIniSyn.GetTokenKind: integer;
403 begin
404 Result := Ord(fTokenId);
405 end;
406
GetTokenPosnull407 function TSynIniSyn.GetTokenPos: Integer;
408 begin
409 Result := fTokenPos;
410 end;
411
GetIdentCharsnull412 function TSynIniSyn.GetIdentChars: TSynIdentChars;
413 begin
414 Result := TSynValidStringChars;
415 end;
416
TSynIniSyn.GetLanguageNamenull417 class function TSynIniSyn.GetLanguageName: string;
418 begin
419 Result := SYNS_LangINI;
420 end;
421
GetSampleSourcenull422 function TSynIniSyn.GetSampleSource: String;
423 begin
424 Result := '; Syntax highlighting'#13#10+
425 '[Section]'#13#10+
426 'Key=value'#13#10+
427 'String="Arial"'#13#10+
428 'Number=123456';
429 end;
430
431 initialization
432 RegisterPlaceableHighlighter(TSynIniSyn);
433
434 end.
435