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: SynHighlighterXML.pas, released 2000-11-20.
12 The Initial Author of this file is Jeff Rafter.
13 All Rights Reserved.
14
15 Contributors to the SynEdit and mwEdit projects are listed in the
16 Contributors.txt file.
17
18 Alternatively, the contents of this file may be used under the terms of the
19 GNU General Public License Version 2 or later (the "GPL"), in which case
20 the provisions of the GPL are applicable instead of those above.
21 If you wish to allow use of your version of this file only under the terms
22 of the GPL and not to allow others to use your version of this file
23 under the MPL, indicate your decision by deleting the provisions above and
24 replace them with the notice and other provisions required by the GPL.
25 If you do not delete the provisions above, a recipient may use your version
26 of this file under either the MPL or the GPL.
27
28 $Id$
29
30 You may retrieve the latest version of this file at the SynEdit home page,
31 located at http://SynEdit.SourceForge.net
32
33 History:
34 -------------------------------------------------------------------------------
35 2000-11-30 Removed mHashTable and MakeIdentTable per Michael Hieke
36
37 Known Issues:
38 - Nothing is really constrained (properly) to valid name chars
39 - Entity Refs are not constrained to valid name chars
40 - Support for "Combining Chars and Extender Chars" in names are lacking
41 - The internal DTD is not parsed (and not handled correctly)
42 -------------------------------------------------------------------------------}
43
44 {
45 @abstract(Provides an XML highlighter for SynEdit)
46 @author(Jeff Rafter-- Phil 4:13, based on SynHighlighterHTML by Hideo Koiso)
47 @created(2000-11-17)
48 @lastmod(2001-03-12)
49 The SynHighlighterXML unit provides SynEdit with an XML highlighter.
50 }
51
52 unit SynHighlighterXML;
53
54 interface
55
56 {$I SynEdit.inc}
57
58 uses
59 Classes, Graphics, SynEditTypes, SynEditHighlighter,
60 SynEditHighlighterFoldBase, SynEditHighlighterXMLBase, SynEditStrConst;
61
62 type
63 TtkTokenKind = (tkAposAttrValue, tkAposEntityRef, tkAttribute, tkCDATA,
64 tkComment, tkElement, tkEntityRef, tkEqual, tkNull, tkProcessingInstruction,
65 tkQuoteAttrValue, tkQuoteEntityRef, tkSpace, tkSymbol, tkText,
66 //
67 tknsAposAttrValue, tknsAposEntityRef, tknsAttribute, tknsEqual,
68 tknsQuoteAttrValue, tknsQuoteEntityRef,
69 //These are unused at the moment
70 tkDocType
71 {tkDocTypeAposAttrValue, tkDocTypeAposEntityRef, tkDocTypeAttribute,
72 tkDocTypeElement, tkDocTypeEqual tkDocTypeQuoteAttrValue,
73 tkDocTypeQuoteEntityRef}
74 );
75
76 TRangeState = (rsAposAttrValue, rsAPosEntityRef, rsAttribute, rsCDATA,
77 rsComment, rsElement, rsCloseElement, rsOpenElement, rsEntityRef, rsEqual, rsProcessingInstruction,
78 rsQuoteAttrValue, rsQuoteEntityRef, rsText,
79 //
80 rsnsAposAttrValue, rsnsAPosEntityRef, rsnsEqual, rsnsQuoteAttrValue,
81 rsnsQuoteEntityRef,
82 //These are unused at the moment
83 rsDocType, rsDocTypeSquareBraces //ek 2001-11-11
84 {rsDocTypeAposAttrValue, rsDocTypeAposEntityRef, rsDocTypeAttribute,
85 rsDocTypeElement, rsDocTypeEqual, rsDocTypeQuoteAttrValue,
86 rsDocTypeQuoteEntityRef}
87 );
88
89 TXmlCodeFoldBlockType = (
90 cfbtXmlNode, // <foo>...</node>
91 cfbtXmlComment, // <!-- -->
92 cfbtXmlCData, // <![CDATA[ ]]>
93 cfbtXmlDocType, // <!DOCTYPE
94 cfbtXmlProcess, // <?
95 // internal types / not configurable
96 cfbtXmlNone
97 );
98
99 type
100
101 TProcTableProc = procedure of object;
102
103 { TSynXMLSyn }
104
105 TSynXMLSyn = class(TSynCustomXmlHighlighter)
106 private
107 fRange: TRangeState;
108 fLine: PChar;
109 Run: Longint;
110 fTokenPos: Integer;
111 fTokenID: TtkTokenKind;
112 fLineNumber: Integer;
113 fElementAttri: TSynHighlighterAttributes;
114 fSpaceAttri: TSynHighlighterAttributes;
115 fTextAttri: TSynHighlighterAttributes;
116 fEntityRefAttri: TSynHighlighterAttributes;
117 fProcessingInstructionAttri: TSynHighlighterAttributes;
118 fCDATAAttri: TSynHighlighterAttributes;
119 fCommentAttri: TSynHighlighterAttributes;
120 fDocTypeAttri: TSynHighlighterAttributes;
121 fAttributeAttri: TSynHighlighterAttributes;
122 fnsAttributeAttri: TSynHighlighterAttributes;
123 fAttributeValueAttri: TSynHighlighterAttributes;
124 fnsAttributeValueAttri: TSynHighlighterAttributes;
125 fSymbolAttri: TSynHighlighterAttributes;
126 fProcTable: array[#0..#255] of TProcTableProc;
127 FWantBracesParsed: Boolean;
128 procedure NullProc;
129 procedure CarriageReturnProc;
130 procedure LineFeedProc;
131 procedure SpaceProc;
132 procedure LessThanProc;
133 procedure GreaterThanProc;
134 procedure CommentProc;
135 procedure ProcessingInstructionProc;
136 procedure DocTypeProc;
137 procedure CDATAProc;
138 procedure TextProc;
139 procedure ElementProc;
140 procedure AttributeProc;
141 procedure QAttributeValueProc;
142 procedure AAttributeValueProc;
143 procedure EqualProc;
144 procedure IdentProc;
145 procedure MakeMethodTables;
NextTokenIsnull146 function NextTokenIs(T: String): Boolean;
147 procedure EntityRefProc;
148 procedure QEntityRefProc;
149 procedure AEntityRefProc;
150 protected
GetIdentCharsnull151 function GetIdentChars: TSynIdentChars; override;
GetSampleSourcenull152 function GetSampleSource : String; override;
153 protected
154 // folding
155 procedure CreateRootCodeFoldBlock; override;
156
StartXmlCodeFoldBlocknull157 function StartXmlCodeFoldBlock(ABlockType: TXmlCodeFoldBlockType): TSynCustomCodeFoldBlock;
StartXmlNodeCodeFoldBlocknull158 function StartXmlNodeCodeFoldBlock(ABlockType: TXmlCodeFoldBlockType;
159 OpenPos: Integer; AName: String): TSynCustomCodeFoldBlock;
160 procedure EndXmlNodeCodeFoldBlock(ClosePos: Integer = -1; AName: String = '');
TopXmlCodeFoldBlockTypenull161 function TopXmlCodeFoldBlockType(DownIndex: Integer = 0): TXmlCodeFoldBlockType;
162
GetFoldConfigInstancenull163 function GetFoldConfigInstance(Index: Integer): TSynCustomFoldConfig; override;
GetFoldConfigCountnull164 function GetFoldConfigCount: Integer; override;
GetFoldConfigInternalCountnull165 function GetFoldConfigInternalCount: Integer; override;
166 public
GetLanguageNamenull167 class function GetLanguageName: string; override;
168 public
169 constructor Create(AOwner: TComponent); override;
GetDefaultAttributenull170 function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
171 override;
GetEolnull172 function GetEol: Boolean; override;
GetRangenull173 function GetRange: Pointer; override;
GetTokenIDnull174 function GetTokenID: TtkTokenKind;
175 procedure SetLine(const NewValue: string; LineNumber:Integer); override;
GetTokennull176 function GetToken: string; override;
177 procedure GetTokenEx(out TokenStart: PChar; out TokenLength: integer); override;
GetTokenAttributenull178 function GetTokenAttribute: TSynHighlighterAttributes; override;
GetTokenKindnull179 function GetTokenKind: integer; override;
GetTokenPosnull180 function GetTokenPos: Integer; override;
181 procedure Next; override;
182 procedure SetRange(Value: Pointer); override;
183 procedure ReSetRange; override;
184 property IdentChars;
185 published
186 property ElementAttri: TSynHighlighterAttributes read fElementAttri
187 write fElementAttri;
188 property AttributeAttri: TSynHighlighterAttributes read fAttributeAttri
189 write fAttributeAttri;
190 property NamespaceAttributeAttri: TSynHighlighterAttributes
191 read fnsAttributeAttri write fnsAttributeAttri;
192 property AttributeValueAttri: TSynHighlighterAttributes
193 read fAttributeValueAttri write fAttributeValueAttri;
194 property NamespaceAttributeValueAttri: TSynHighlighterAttributes
195 read fnsAttributeValueAttri write fnsAttributeValueAttri;
196 property TextAttri: TSynHighlighterAttributes read fTextAttri
197 write fTextAttri;
198 property CDATAAttri: TSynHighlighterAttributes read fCDATAAttri
199 write fCDATAAttri;
200 property EntityRefAttri: TSynHighlighterAttributes read fEntityRefAttri
201 write fEntityRefAttri;
202 property ProcessingInstructionAttri: TSynHighlighterAttributes
203 read fProcessingInstructionAttri write fProcessingInstructionAttri;
204 property CommentAttri: TSynHighlighterAttributes read fCommentAttri
205 write fCommentAttri;
206 property DocTypeAttri: TSynHighlighterAttributes read fDocTypeAttri
207 write fDocTypeAttri;
208 property SpaceAttri: TSynHighlighterAttributes read fSpaceAttri
209 write fSpaceAttri;
210 property SymbolAttri: TSynHighlighterAttributes read fSymbolAttri
211 write fSymbolAttri;
212 property WantBracesParsed : Boolean read FWantBracesParsed
213 write FWantBracesParsed default True;
214 end;
215
216 implementation
217
218 const
219 NameChars : set of char = ['0'..'9', 'a'..'z', 'A'..'Z', '_', '.', ':', '-'];
220
221 constructor TSynXMLSyn.Create(AOwner: TComponent);
222 begin
223 inherited Create(AOwner);
224
225 fElementAttri:= TSynHighlighterAttributes.Create(@SYNS_AttrElementName, SYNS_XML_AttrElementName);
226 fTextAttri:= TSynHighlighterAttributes.Create(@SYNS_AttrText, SYNS_XML_AttrText);
227 fSpaceAttri:= TSynHighlighterAttributes.Create(@SYNS_AttrWhitespace, SYNS_XML_AttrWhitespace);
228 fEntityRefAttri:= TSynHighlighterAttributes.Create(@SYNS_AttrEntityReference, SYNS_XML_AttrEntityReference);
229 fProcessingInstructionAttri:= TSynHighlighterAttributes.Create(@SYNS_AttrProcessingInstr, SYNS_XML_AttrProcessingInstr);
230 fCDATAAttri:= TSynHighlighterAttributes.Create(@SYNS_AttrCDATASection, SYNS_XML_AttrCDATASection);
231 fCommentAttri:= TSynHighlighterAttributes.Create(@SYNS_AttrComment, SYNS_XML_AttrComment);
232 fDocTypeAttri:= TSynHighlighterAttributes.Create(@SYNS_AttrDOCTYPESection, SYNS_XML_AttrDOCTYPESection);
233 fAttributeAttri:= TSynHighlighterAttributes.Create(@SYNS_AttrAttributeName, SYNS_XML_AttrAttributeName);
234 fnsAttributeAttri:= TSynHighlighterAttributes.Create(@SYNS_AttrNamespaceAttrName, SYNS_XML_AttrNamespaceAttrName);
235 fAttributeValueAttri:= TSynHighlighterAttributes.Create(@SYNS_AttrAttributeValue, SYNS_XML_AttrAttributeValue);
236 fnsAttributeValueAttri:= TSynHighlighterAttributes.Create(@SYNS_AttrNamespaceAttrValue, SYNS_XML_AttrNamespaceAttrValue);
237 fSymbolAttri:= TSynHighlighterAttributes.Create(@SYNS_AttrSymbol, SYNS_XML_AttrSymbol);
238
239 fElementAttri.Foreground:= clMaroon;
240 fElementAttri.Style:= [fsBold];
241
242 fDocTypeAttri.Foreground:= clblue;
243 fDocTypeAttri.Style:= [fsItalic];
244
245 fCDATAAttri.Foreground:= clOlive;
246 fCDATAAttri.Style:= [fsItalic];
247
248 fEntityRefAttri.Foreground:= clblue;
249 fEntityRefAttri.Style:= [fsbold];
250
251 fProcessingInstructionAttri.Foreground:= clblue;
252 fProcessingInstructionAttri.Style:= [];
253
254 fTextAttri.Foreground:= clBlack;
255 fTextAttri.Style:= [fsBold];
256
257 fAttributeAttri.Foreground:= clMaroon;
258 fAttributeAttri.Style:= [];
259
260 fnsAttributeAttri.Foreground:= clRed;
261 fnsAttributeAttri.Style:= [];
262
263 fAttributeValueAttri.Foreground:= clNavy;
264 fAttributeValueAttri.Style:= [fsBold];
265
266 fnsAttributeValueAttri.Foreground:= clRed;
267 fnsAttributeValueAttri.Style:= [fsBold];
268
269 fCommentAttri.Background:= clSilver;
270 fCommentAttri.Foreground:= clGray;
271 fCommentAttri.Style:= [fsbold, fsItalic];
272
273 fSymbolAttri.Foreground:= clblue;
274 fSymbolAttri.Style:= [];
275
276 AddAttribute(fSymbolAttri);
277 AddAttribute(fProcessingInstructionAttri);
278 AddAttribute(fDocTypeAttri);
279 AddAttribute(fCommentAttri);
280 AddAttribute(fElementAttri);
281 AddAttribute(fAttributeAttri);
282 AddAttribute(fnsAttributeAttri);
283 AddAttribute(fAttributeValueAttri);
284 AddAttribute(fnsAttributeValueAttri);
285 AddAttribute(fEntityRefAttri);
286 AddAttribute(fCDATAAttri);
287 AddAttribute(fSpaceAttri);
288 AddAttribute(fTextAttri);
289
290 SetAttributesOnChange(@DefHighlightChange);
291
292 MakeMethodTables;
293 fRange := rsText;
294 fDefaultFilter := SYNS_FilterXML;
295 end;
296
297 procedure TSynXMLSyn.MakeMethodTables;
298 var
299 i: Char;
300 begin
301 for i:= #0 To #255 do begin
302 case i of
303 #0:
304 begin
305 fProcTable[i] := @NullProc;
306 end;
307 #10:
308 begin
309 fProcTable[i] := @LineFeedProc;
310 end;
311 #13:
312 begin
313 fProcTable[i] := @CarriageReturnProc;
314 end;
315 #1..#9, #11, #12, #14..#32:
316 begin
317 fProcTable[i] := @SpaceProc;
318 end;
319 '<':
320 begin
321 fProcTable[i] := @LessThanProc;
322 end;
323 '>':
324 begin
325 fProcTable[i] := @GreaterThanProc;
326 end;
327 else
328 fProcTable[i] := @IdentProc;
329 end;
330 end;
331 end;
332
333 procedure TSynXMLSyn.SetLine(const NewValue: string;
334 LineNumber:Integer);
335 begin
336 inherited;
337 fLine := PChar(NewValue);
338 Run := 0;
339 fLineNumber := LineNumber;
340 Next;
341 end;
342
343 procedure TSynXMLSyn.NullProc;
344 begin
345 fTokenID := tkNull;
346 end;
347
348 procedure TSynXMLSyn.CarriageReturnProc;
349 begin
350 fTokenID := tkSpace;
351 Inc(Run);
352 if fLine[Run] = #10 then Inc(Run);
353 end;
354
355 procedure TSynXMLSyn.LineFeedProc;
356 begin
357 fTokenID := tkSpace;
358 Inc(Run);
359 end;
360
361 procedure TSynXMLSyn.SpaceProc;
362 begin
363 Inc(Run);
364 fTokenID := tkSpace;
365 while fLine[Run] <= #32 do begin
366 if fLine[Run] in [#0, #9, #10, #13] then break;
367 Inc(Run);
368 end;
369 end;
370
371 procedure TSynXMLSyn.LessThanProc;
372 begin
373 Inc(Run);
374 if (fLine[Run] = '/') then begin
375 Inc(Run);
376 fTokenID := tkSymbol;
377 fRange := rsCloseElement;
378 exit;
379 end;
380
381 if (fLine[Run] = '!') then
382 begin
383 if NextTokenIs('--') then begin
384 fTokenID := tkSymbol;
385 fRange := rsComment;
386 StartXmlCodeFoldBlock(cfbtXmlComment);
387 Inc(Run, 3);
388 end else if NextTokenIs('DOCTYPE') then begin
389 fTokenID := tkDocType;
390 fRange := rsDocType;
391 StartXmlCodeFoldBlock(cfbtXmlDocType);
392 Inc(Run, 7);
393 end else if NextTokenIs('[CDATA[') then begin
394 fTokenID := tkCDATA;
395 fRange := rsCDATA;
396 StartXmlCodeFoldBlock(cfbtXmlCData);
397 Inc(Run, 7);
398 end else begin
399 fTokenID := tkSymbol;
400 fRange := rsElement;
401 Inc(Run);
402 end;
403 end else if fLine[Run]= '?' then begin
404 fTokenID := tkProcessingInstruction;
405 fRange := rsProcessingInstruction;
406 StartXmlCodeFoldBlock(cfbtXmlProcess);
407 Inc(Run);
408 end else begin
409 fTokenID := tkSymbol;
410 fRange := rsOpenElement;
411 end;
412 end;
413
414 procedure TSynXMLSyn.GreaterThanProc;
415 begin
416 if (Run > 0) and (fLine[Run - 1] = '/') then
417 if TopXmlCodeFoldBlockType = cfbtXmlNode then
418 EndXmlNodeCodeFoldBlock;
419
420 fTokenId := tkSymbol;
421 fRange:= rsText;
422 Inc(Run);
423 end;
424
425 procedure TSynXMLSyn.CommentProc;
426 begin
427 if (fLine[Run] = '-') and (fLine[Run + 1] = '-') and
428 (fLine[Run + 2] = '>')
429 then begin
430 fTokenID := tkSymbol;
431 fRange:= rsText;
432 Inc(Run, 3);
433 if TopXmlCodeFoldBlockType = cfbtXmlComment then
434 EndXmlCodeFoldBlock;
435 Exit;
436 end;
437
438 fTokenID := tkComment;
439
440 if (fLine[Run] In [#0, #10, #13]) then begin
441 fProcTable[fLine[Run]]();
442 Exit;
443 end;
444
445 while not (fLine[Run] in [#0, #10, #13]) do begin
446 if (fLine[Run] = '-') and (fLine[Run + 1] = '-') and (fLine[Run + 2] = '>')
447 then begin
448 fRange := rsComment;
449 break;
450 end;
451 Inc(Run);
452 end;
453 end;
454
455 procedure TSynXMLSyn.ProcessingInstructionProc;
456 begin
457 fTokenID := tkProcessingInstruction;
458 if (fLine[Run] In [#0, #10, #13]) then begin
459 fProcTable[fLine[Run]]();
460 Exit;
461 end;
462
463 while not (fLine[Run] in [#0, #10, #13]) do begin
464 if (fLine[Run] = '>') and (fLine[Run - 1] = '?')
465 then begin
466 fRange := rsText;
467 Inc(Run);
468 if TopXmlCodeFoldBlockType = cfbtXmlProcess then
469 EndXmlCodeFoldBlock;
470 break;
471 end;
472 Inc(Run);
473 end;
474 end;
475
476 procedure TSynXMLSyn.DocTypeProc; //ek 2001-11-11
477 begin
478 fTokenID := tkDocType;
479
480 if (fLine[Run] In [#0, #10, #13]) then begin
481 fProcTable[fLine[Run]]();
482 Exit;
483 end;
484
485 case fRange of
486 rsDocType:
487 begin
488 while not (fLine[Run] in [#0, #10, #13]) do
489 begin
490 case fLine[Run] of
491 '[': begin
492 while True do
493 begin
494 inc(Run);
495 case fLine[Run] of
496 ']':
497 begin
498 Inc(Run);
499 Exit;
500 end;
501 #0, #10, #13:
502 begin
503 fRange:=rsDocTypeSquareBraces;
504 Exit;
505 end;
506 end;
507 end;
508 end;
509 '>': begin
510 fRange := rsAttribute;
511 if TopXmlCodeFoldBlockType = cfbtXmlDocType then
512 EndXmlCodeFoldBlock;
513 Inc(Run);
514 Break;
515 end;
516 end;
517 inc(Run);
518 end;
519 end;
520 rsDocTypeSquareBraces:
521 begin
522 while not (fLine[Run] in [#0, #10, #13]) do
523 begin
524 if (fLine[Run]=']') then
525 begin
526 fRange := rsDocType;
527 Inc(Run);
528 Exit;
529 end;
530 inc(Run);
531 end;
532 end;
533 end;
534 end;
535
536 procedure TSynXMLSyn.CDATAProc;
537 begin
538 fTokenID := tkCDATA;
539 if (fLine[Run] In [#0, #10, #13]) then
540 begin
541 fProcTable[fLine[Run]]();
542 Exit;
543 end;
544
545 while not (fLine[Run] in [#0, #10, #13]) do
546 begin
547 if (Run >= 2) and (fLine[Run] = '>') and (fLine[Run - 1] = ']') and
548 (fLine[Run - 2] = ']')
549 then begin
550 fRange := rsText;
551 Inc(Run);
552 if TopXmlCodeFoldBlockType = cfbtXmlCData then
553 EndXmlCodeFoldBlock;
554 break;
555 end;
556 Inc(Run);
557 end;
558 end;
559
560 procedure TSynXMLSyn.ElementProc;
561 var
562 NameStart: LongInt;
563 begin
564 if fLine[Run] = '/' then
565 Inc(Run);
566 NameStart := Run;
567 while (fLine[Run] in NameChars) do Inc(Run);
568
569 if fRange = rsOpenElement then
570 StartXmlNodeCodeFoldBlock(cfbtXmlNode, NameStart, Copy(fLine, NameStart + 1, Run - NameStart));
571
572 if fRange = rsCloseElement then
573 EndXmlNodeCodeFoldBlock(NameStart, Copy(fLine, NameStart + 1, Run - NameStart)); // TODO: defer until ">" reached
574
575 fRange := rsAttribute;
576 fTokenID := tkElement;
577 end;
578
579 procedure TSynXMLSyn.AttributeProc;
580 begin
581 //Check if we are starting on a closing quote
582 if (fLine[Run] in [#34, #39]) then
583 begin
584 fTokenID := tkSymbol;
585 fRange := rsAttribute;
586 Inc(Run);
587 Exit;
588 end;
589 //Read the name
590 while (fLine[Run] in NameChars) do Inc(Run);
591 //Check if this is an xmlns: attribute
592 if (Pos('xmlns', GetToken) > 0) then begin
593 fTokenID := tknsAttribute;
594 fRange := rsnsEqual;
595 end else begin
596 fTokenID := tkAttribute;
597 fRange := rsEqual;
598 end;
599 end;
600
601 procedure TSynXMLSyn.EqualProc;
602 begin
603 if fRange = rsnsEqual then
604 fTokenID := tknsEqual
605 else
606 fTokenID := tkEqual;
607
608 while not (fLine[Run] in [#0, #10, #13]) do
609 begin
610 if (fLine[Run] = '/') then
611 begin
612 fTokenID := tkSymbol;
613 fRange := rsElement;
614 Inc(Run);
615 Exit;
616 end else if (fLine[Run] = #34) then
617 begin
618 if fRange = rsnsEqual then
619 fRange := rsnsQuoteAttrValue
620 else
621 fRange := rsQuoteAttrValue;
622 Inc(Run);
623 Exit;
624 end else if (fLine[Run] = #39) then
625 begin
626 if fRange = rsnsEqual then
627 fRange := rsnsAPosAttrValue
628 else
629 fRange := rsAPosAttrValue;
630 Inc(Run);
631 Exit;
632 end;
633 Inc(Run);
634 end;
635 end;
636
637 procedure TSynXMLSyn.QAttributeValueProc;
638 begin
639 if fRange = rsnsQuoteAttrValue then
640 fTokenID := tknsQuoteAttrValue
641 else
642 fTokenID := tkQuoteAttrValue;
643
644 while not (fLine[Run] in [#0, #10, #13, '&', #34]) do Inc(Run);
645
646 if fLine[Run] = '&' then
647 begin
648 if fRange = rsnsQuoteAttrValue then
649 fRange := rsnsQuoteEntityRef
650 else
651 fRange := rsQuoteEntityRef;
652 Exit;
653 end else if fLine[Run] <> #34 then
654 begin
655 Exit;
656 end;
657
658 fRange := rsAttribute;
659 end;
660
661 procedure TSynXMLSyn.AAttributeValueProc;
662 begin
663 if fRange = rsnsAPosAttrValue then
664 fTokenID := tknsAPosAttrValue
665 else
666 fTokenID := tkAPosAttrValue;
667
668 while not (fLine[Run] in [#0, #10, #13, '&', #39]) do Inc(Run);
669
670 if fLine[Run] = '&' then
671 begin
672 if fRange = rsnsAPosAttrValue then
673 fRange := rsnsAPosEntityRef
674 else
675 fRange := rsAPosEntityRef;
676 Exit;
677 end else if fLine[Run] <> #39 then
678 begin
679 Exit;
680 end;
681
682 fRange := rsAttribute;
683 end;
684
685 procedure TSynXMLSyn.TextProc;
686 const StopSet = [#0..#31, '<', '&'];
687 begin
688 if fLine[Run] in (StopSet - ['&']) then begin
689 fProcTable[fLine[Run]]();
690 exit;
691 end;
692
693 fTokenID := tkText;
694 while not (fLine[Run] in StopSet) do Inc(Run);
695
696 if (fLine[Run] = '&') then begin
697 fRange := rsEntityRef;
698 Exit;
699 end;
700 end;
701
702 procedure TSynXMLSyn.EntityRefProc;
703 begin
704 fTokenID := tkEntityRef;
705 fRange := rsEntityRef;
706 while not (fLine[Run] in [#0..#32, ';']) do Inc(Run);
707 if (fLine[Run] = ';') then Inc(Run);
708 fRange := rsText;
709 end;
710
711 procedure TSynXMLSyn.QEntityRefProc;
712 begin
713 if fRange = rsnsQuoteEntityRef then
714 fTokenID := tknsQuoteEntityRef
715 else
716 fTokenID := tkQuoteEntityRef;
717
718 while not (fLine[Run] in [#0..#32, ';']) do Inc(Run);
719 if (fLine[Run] = ';') then Inc(Run);
720
721 if fRange = rsnsQuoteEntityRef then
722 fRange := rsnsQuoteAttrValue
723 else
724 fRange := rsQuoteAttrValue;
725 end;
726
727 procedure TSynXMLSyn.AEntityRefProc;
728 begin
729 if fRange = rsnsAPosEntityRef then
730 fTokenID := tknsAPosEntityRef
731 else
732 fTokenID := tkAPosEntityRef;
733
734 while not (fLine[Run] in [#0..#32, ';']) do Inc(Run);
735 if (fLine[Run] = ';') then Inc(Run);
736
737 if fRange = rsnsAPosEntityRef then
738 fRange := rsnsAPosAttrValue
739 else
740 fRange := rsAPosAttrValue;
741 end;
742
GetFoldConfigInstancenull743 function TSynXMLSyn.GetFoldConfigInstance(Index: Integer): TSynCustomFoldConfig;
744 begin
745 Result := inherited GetFoldConfigInstance(Index);
746 Result.Enabled := True;
747 if TXmlCodeFoldBlockType(Index) in [cfbtXmlNode] then begin
748 Result.SupportedModes := Result.SupportedModes + [fmMarkup];
749 Result.Modes := Result.Modes + [fmMarkup];
750 end;
751 end;
752
753 procedure TSynXMLSyn.IdentProc;
754 begin
755 case fRange of
756 rsElement, rsOpenElement, rsCloseElement:
757 begin
758 ElementProc();
759 end;
760 rsAttribute:
761 begin
762 AttributeProc();
763 end;
764 rsEqual, rsnsEqual:
765 begin
766 EqualProc();
767 end;
768 rsQuoteAttrValue, rsnsQuoteAttrValue:
769 begin
770 QAttributeValueProc();
771 end;
772 rsAposAttrValue, rsnsAPosAttrValue:
773 begin
774 AAttributeValueProc();
775 end;
776 rsQuoteEntityRef, rsnsQuoteEntityRef:
777 begin
778 QEntityRefProc();
779 end;
780 rsAposEntityRef, rsnsAPosEntityRef:
781 begin
782 AEntityRefProc();
783 end;
784 rsEntityRef:
785 begin
786 EntityRefProc();
787 end;
788 else ;
789 end;
790 end;
791
792 procedure TSynXMLSyn.Next;
793 begin
794 fTokenPos := Run;
795 case fRange of
796 rsText:
797 begin
798 TextProc();
799 end;
800 rsComment:
801 begin
802 CommentProc();
803 end;
804 rsProcessingInstruction:
805 begin
806 ProcessingInstructionProc();
807 end;
808 rsDocType, rsDocTypeSquareBraces: //ek 2001-11-11
809 begin
810 DocTypeProc();
811 end;
812 rsCDATA:
813 begin
814 CDATAProc();
815 end;
816 else
817 fProcTable[fLine[Run]]();
818 end;
819 end;
820
TSynXMLSyn.NextTokenIsnull821 function TSynXMLSyn.NextTokenIs(T : String) : Boolean;
822 var I, Len : Integer;
823 begin
824 Result:= True;
825 Len:= Length(T);
826 for I:= 1 to Len do
827 if (fLine[Run + I] <> T[I]) then
828 begin
829 Result:= False;
830 Break;
831 end;
832 end;
833
GetDefaultAttributenull834 function TSynXMLSyn.GetDefaultAttribute(
835 Index: integer): TSynHighlighterAttributes;
836 begin
837 case Index of
838 SYN_ATTR_COMMENT: Result := fCommentAttri;
839 SYN_ATTR_IDENTIFIER: Result := fAttributeAttri;
840 SYN_ATTR_KEYWORD: Result := fElementAttri;
841 SYN_ATTR_WHITESPACE: Result := fSpaceAttri;
842 SYN_ATTR_SYMBOL: Result := fSymbolAttri;
843 else
844 Result := nil;
845 end;
846 end;
847
GetEolnull848 function TSynXMLSyn.GetEol: Boolean;
849 begin
850 Result := fTokenId = tkNull;
851 end;
852
TSynXMLSyn.GetTokennull853 function TSynXMLSyn.GetToken: string;
854 var
855 len: Longint;
856 begin
857 Result := '';
858 Len := (Run - fTokenPos);
859 SetString(Result, (FLine + fTokenPos), len);
860 end;
861
862 procedure TSynXMLSyn.GetTokenEx(out TokenStart: PChar;
863 out TokenLength: integer);
864 begin
865 TokenLength:=Run-fTokenPos;
866 TokenStart:=FLine + fTokenPos;
867 end;
868
GetTokenIDnull869 function TSynXMLSyn.GetTokenID: TtkTokenKind;
870 begin
871 Result := fTokenId;
872 end;
873
TSynXMLSyn.GetTokenAttributenull874 function TSynXMLSyn.GetTokenAttribute: TSynHighlighterAttributes;
875 begin
876 case fTokenID of
877 tkElement: Result:= fElementAttri;
878 tkAttribute: Result:= fAttributeAttri;
879 tknsAttribute: Result:= fnsAttributeAttri;
880 tkEqual: Result:= fSymbolAttri;
881 tknsEqual: Result:= fSymbolAttri;
882 tkQuoteAttrValue: Result:= fAttributeValueAttri;
883 tkAPosAttrValue: Result:= fAttributeValueAttri;
884 tknsQuoteAttrValue: Result:= fnsAttributeValueAttri;
885 tknsAPosAttrValue: Result:= fnsAttributeValueAttri;
886 tkText: Result:= fTextAttri;
887 tkCDATA: Result:= fCDATAAttri;
888 tkEntityRef: Result:= fEntityRefAttri;
889 tkQuoteEntityRef: Result:= fEntityRefAttri;
890 tkAposEntityRef: Result:= fEntityRefAttri;
891 tknsQuoteEntityRef: Result:= fEntityRefAttri;
892 tknsAposEntityRef: Result:= fEntityRefAttri;
893 tkProcessingInstruction: Result:= fProcessingInstructionAttri;
894 tkComment: Result:= fCommentAttri;
895 tkDocType: Result:= fDocTypeAttri;
896 tkSymbol: Result:= fSymbolAttri;
897 tkSpace: Result:= fSpaceAttri;
898 else
899 Result := nil;
900 end;
901 end;
902
TSynXMLSyn.GetTokenKindnull903 function TSynXMLSyn.GetTokenKind: integer;
904 begin
905 Result := Ord(fTokenId);
906 end;
907
GetTokenPosnull908 function TSynXMLSyn.GetTokenPos: Integer;
909 begin
910 Result := fTokenPos;
911 end;
912
GetRangenull913 function TSynXMLSyn.GetRange: Pointer;
914 begin
915 CodeFoldRange.RangeType:=Pointer(PtrUInt(Integer(fRange)));
916 Result := inherited;
917 end;
918
919 procedure TSynXMLSyn.SetRange(Value: Pointer);
920 begin
921 inherited;
922 fRange := TRangeState(Integer(PtrUInt(CodeFoldRange.RangeType)));
923 end;
924
925 procedure TSynXMLSyn.ReSetRange;
926 begin
927 inherited;
928 fRange:= rsText;
929 end;
930
GetIdentCharsnull931 function TSynXMLSyn.GetIdentChars: TSynIdentChars;
932 begin
933 Result := ['0'..'9', 'a'..'z', 'A'..'Z', '_', '.', '-'] + TSynSpecialChars;
934 end;
935
TSynXMLSyn.GetLanguageNamenull936 class function TSynXMLSyn.GetLanguageName: string;
937 begin
938 Result := SYNS_LangXML;
939 end;
940
GetSampleSourcenull941 function TSynXMLSyn.GetSampleSource: String;
942 begin
943 Result:= '<?xml version="1.0"?>'#13#10+
944 '<!DOCTYPE root ['#13#10+
945 ' ]>'#13#10+
946 '<!-- Comment -->'#13#10+
947 '<root version="&test;">'#13#10+
948 ' <![CDATA[ **CDATA section** ]]>'#13#10+
949 '</root>';
950 end;
951
952 procedure TSynXMLSyn.CreateRootCodeFoldBlock;
953 begin
954 inherited CreateRootCodeFoldBlock;
955 RootCodeFoldBlock.InitRootBlockType(Pointer(PtrInt(cfbtXmlNone)));
956 end;
957
StartXmlCodeFoldBlocknull958 function TSynXMLSyn.StartXmlCodeFoldBlock(ABlockType: TXmlCodeFoldBlockType): TSynCustomCodeFoldBlock;
959 begin
960 Result := inherited StartXmlCodeFoldBlock(ord(ABlockType));
961 end;
962
StartXmlNodeCodeFoldBlocknull963 function TSynXMLSyn.StartXmlNodeCodeFoldBlock(ABlockType: TXmlCodeFoldBlockType;
964 OpenPos: Integer; AName: String): TSynCustomCodeFoldBlock;
965 begin
966 if not FFoldConfig[ord(cfbtXmlNode)].Enabled then exit(nil);
967 Result := inherited StartXmlNodeCodeFoldBlock(ord(ABlockType), OpenPos, AName);
968 end;
969
970 procedure TSynXMLSyn.EndXmlNodeCodeFoldBlock(ClosePos: Integer; AName: String);
971 begin
972 if not FFoldConfig[ord(cfbtXmlNode)].Enabled then exit;
973 inherited EndXmlNodeCodeFoldBlock(ClosePos, AName);
974 end;
975
TSynXMLSyn.TopXmlCodeFoldBlockTypenull976 function TSynXMLSyn.TopXmlCodeFoldBlockType(DownIndex: Integer): TXmlCodeFoldBlockType;
977 begin
978 Result := TXmlCodeFoldBlockType(PtrUInt(TopCodeFoldBlockType(DownIndex)));
979 end;
980
TSynXMLSyn.GetFoldConfigCountnull981 function TSynXMLSyn.GetFoldConfigCount: Integer;
982 begin
983 // excluded cfbtXmlNone
984 Result := ord(high(TXmlCodeFoldBlockType)) - ord(low(TXmlCodeFoldBlockType));
985 end;
986
TSynXMLSyn.GetFoldConfigInternalCountnull987 function TSynXMLSyn.GetFoldConfigInternalCount: Integer;
988 begin
989 // excluded cfbtXmlNone;
990 Result := ord(high(TXmlCodeFoldBlockType)) - ord(low(TXmlCodeFoldBlockType)) + 1;
991 end;
992
993 initialization
994 RegisterPlaceableHighlighter(TSynXMLSyn);
995
996 end.
997
998