1
{-------------------------------------------------------------------------------
2
The contents of this file may be used under the terms of the
3
GNU General Public License Version 2 or later (the "GPL")
5
Software distributed under the License is distributed on an "AS IS" basis,
6
WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
7
the specific language governing rights and limitations under the License.
9
The Original Code is: SynHighlighterPo.pp, released 2011-12-17.
13
Contributors to the SynEdit and mwEdit projects are listed in the
14
Contributors.txt file.
17
$Id: SynHighlighterPo.pp,v 0.0.1 bbroersma Exp $
21
-------------------------------------------------------------------------------}
23
@abstract(Provides a po-files highlighter for SynEdit)
24
@author(Bart Broersma)
27
The SynHighlighterPo unit provides SynEdit with an po-files highlighter.
29
unit SynHighlighterPo;
42
SynEditTypes, SynEditHighlighter, SynEditStrConst;
45
TtkTokenKind = (tkComment, tkText, tkKey, tkNull, tkSpace, tkString,
46
tkIdentifier, tkPrevValue, tkFlags, tkUnknown);
48
TProcTableProc = procedure of object;
54
TSynPoSyn = class(TSynCustomHighlighter)
58
fProcTable: array[#0..#255] of TProcTableProc;
61
FTokenID: TtkTokenKind;
62
fCommentAttri: TSynHighlighterAttributes;
63
fTextAttri: TSynHighlighterAttributes;
64
fKeyAttri: TSynHighlighterAttributes;
65
fSpaceAttri: TSynHighlighterAttributes;
66
fStringAttri: TSynHighlighterAttributes;
67
fIdentAttri: TSynHighlighterAttributes;
68
fPrevAttri: TSynHighlighterAttributes;
69
fFlagAttri: TSynHighlighterAttributes;
79
procedure MakeMethodTables;
82
function GetIdentChars: TSynIdentChars; override;
83
function GetSampleSource: String; override;
85
class function GetLanguageName: string; override;
86
function IsKeyword(const AKeyword: string): boolean; override;
88
constructor Create(AOwner: TComponent); override;
89
function GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
91
function GetEol: Boolean; override;
92
function GetTokenID: TtkTokenKind;
93
procedure SetLine(const NewValue: String; LineNumber:Integer); override;
94
function GetToken: String; override;
95
procedure GetTokenEx(out TokenStart: PChar; out TokenLength: integer); override;
96
function GetTokenAttribute: TSynHighlighterAttributes; override;
97
function GetTokenKind: integer; override;
98
function GetTokenPos: Integer; override;
99
procedure Next; override;
101
property CommentAttri: TSynHighlighterAttributes read fCommentAttri
103
property TextAttri : TSynHighlighterAttributes read fTextAttri
105
property KeyAttri : TSynHighlighterAttributes read fKeyAttri
107
property SpaceAttri : TSynHighlighterAttributes read fSpaceAttri
117
PoKeys: array[1..PoKeysCount] of string = (
118
'msgid', 'msgstr', 'msgctxt');
121
procedure TSynPoSyn.MakeMethodTables;
125
for i := #0 to #255 do
127
#0 : fProcTable[i] := @NullProc;
128
#10 {LF}: fProcTable[i] := @LFProc;
129
#13 {CR}: fProcTable[i] := @CRProc;
130
#34 {"} : fProcTable[i] := @StringProc;
131
'A'..'Z', 'a'..'z', '_': fProcTable[I] := @IdentProc;
132
'#' {#} : fProcTable[i] := @HashProc;
133
#1..#9, #11, #12, #14..#32: fProcTable[i] := @SpaceProc;
135
fProcTable[i] := @TextProc;
139
constructor TSynPoSyn.Create(AOwner: TComponent);
141
inherited Create(AOwner);
142
fCommentAttri := TSynHighlighterAttributes.Create(SYNS_AttrComment);
143
fCommentAttri.Style := [fsItalic];
144
fCommentAttri.Foreground := clGreen;
145
AddAttribute(fCommentAttri);
147
fTextAttri := TSynHighlighterAttributes.Create(SYNS_AttrText);
148
AddAttribute(fTextAttri);
150
fKeyAttri := TSynHighlighterAttributes.Create(SYNS_AttrKey);
151
fKeyAttri.Foreground := clBlue;
152
fKeyAttri.Style := [fsBold];
153
AddAttribute(fKeyAttri);
155
fIdentAttri := TSynHighlighterAttributes.Create(SYNS_AttrIdentifier, SYNS_XML_AttrIdentifier);
156
fIdentAttri.Foreground := clGreen;
157
fIdentAttri.Style := [fsBold];
158
AddAttribute(fIdentAttri);
160
fPrevAttri := TSynHighlighterAttributes.Create(SYNS_AttrPrevValue, SYNS_XML_AttrPrevValue);
161
fPrevAttri.Foreground := clOlive;
162
fPrevAttri.Style := [fsItalic];
163
AddAttribute(fPrevAttri);
165
fFlagAttri := TSynHighlighterAttributes.Create(SYNS_AttrFlags, SYNS_XML_AttrFlags);
166
fFlagAttri.Foreground := clTeal;
167
AddAttribute(fFlagAttri);
169
fSpaceAttri := TSynHighlighterAttributes.Create(SYNS_AttrSpace, SYNS_XML_AttrSpace);
170
AddAttribute(fSpaceAttri);
172
fStringAttri := TSynHighlighterAttributes.Create(SYNS_AttrString, SYNS_XML_AttrString);
173
fStringAttri.Foreground := clFuchsia;
174
AddAttribute(fStringAttri);
176
SetAttributesOnChange(@DefHighlightChange);
178
fDefaultFilter := SYNS_FilterPo;
182
procedure TSynPoSyn.SetLine(const NewValue: String; LineNumber:Integer);
185
fLine := PChar(NewValue);
187
fLineNumber := LineNumber;
192
procedure TSynPoSyn.IdentProc;
194
while fLine[Run] in GetIdentChars {['A'..'Z','a'..'z']} do inc(Run);
195
if IsKeyWord(GetToken) then begin
199
else fTokenId := tkUnknown;
202
procedure TSynPoSyn.CRProc;
205
Case FLine[Run + 1] of
212
procedure TSynPoSyn.KeyProc;
216
while FLine[Run] <> #0 do
225
procedure TSynPoSyn.TextProc;
232
while (fLine[Run] in [#128..#191]) OR // continued utf8 subcode
233
((fLine[Run]<>#0) and (fProcTable[fLine[Run]] = @TextProc)) do inc(Run);
239
procedure TSynPoSyn.LFProc;
245
procedure TSynPoSyn.NullProc;
252
procedure TSynPoSyn.SpaceProc;
256
while FLine[Run] in [#1..#9, #11, #12, #14..#32] do inc(Run);
260
procedure TSynPoSyn.StringProc;
262
fTokenID := tkString;
266
'\': if FLine[Run + 1] = #34 then Inc(Run); { \" means a literal " in the line}
269
until FLine[Run] = #34;
270
if FLine[Run] <> #0 then inc(Run);
274
procedure TSynPoSyn.HashProc;
276
// if it is not column 0 mark as tkText and get out of here
284
// this is column 0 --> ok
285
fTokenID := tkComment;
287
while FLine[Run] <> #0 do
291
':': begin if (Run = 1) then fTokenId := tkIdentifier; Inc(Run) end;
292
',': begin if (Run = 1) then fTokenId := tkFlags; Inc(Run) end;
293
'|': begin if (Run = 1) then fTokenId := tkPrevValue; Inc(Run) end;
298
procedure TSynPoSyn.Next;
301
fProcTable[fLine[Run]];
304
function TSynPoSyn.GetDefaultAttribute(Index: integer): TSynHighlighterAttributes;
307
SYN_ATTR_COMMENT: Result := fCommentAttri;
308
SYN_ATTR_KEYWORD: Result := fKeyAttri;
309
SYN_ATTR_STRING: Result := fStringAttri;
310
SYN_ATTR_WHITESPACE: Result := fSpaceAttri;
316
function TSynPoSyn.GetEol: Boolean;
318
Result := fTokenId = tkNull;
321
function TSynPoSyn.GetToken: String;
325
Len := Run - fTokenPos;
326
SetString(Result, (FLine + fTokenPos), Len);
329
procedure TSynPoSyn.GetTokenEx(out TokenStart: PChar; out TokenLength: integer);
331
TokenLength := Run - fTokenPos;
332
TokenStart := FLine + fTokenPos;
335
function TSynPoSyn.GetTokenID: TtkTokenKind;
340
function TSynPoSyn.GetTokenAttribute: TSynHighlighterAttributes;
343
tkComment: Result := fCommentAttri;
344
tkText : Result := fTextAttri;
345
tkKey : Result := fKeyAttri;
346
tkSpace : Result := fSpaceAttri;
347
tkString : Result := fStringAttri;
348
tkIdentifier: Result := fIdentAttri;
349
tkFlags: Result := fFlagAttri;
350
tkPrevValue: Result := fPrevAttri;
351
tkUnknown: Result := fTextAttri;
356
function TSynPoSyn.GetTokenKind: integer;
358
Result := Ord(fTokenId);
361
function TSynPoSyn.GetTokenPos: Integer;
366
function TSynPoSyn.GetIdentChars: TSynIdentChars;
368
Result := inherited GetIdentChars; //TSynValidStringChars;
371
class function TSynPoSyn.GetLanguageName: string;
373
Result := SYNS_LangPo;
376
function TSynPoSyn.GetSampleSource: String;
378
Result := '"Project-Id-Version: \n"' + LineEnding +
379
'"POT-Creation-Date: \n"' + LineEnding +
380
'"MIME-Version: 1.0\n"' + LineEnding +
381
'"Content-Type: text/plain; charset=UTF-8\n"' + LineEnding +
382
'"Content-Transfer-Encoding: 8bit\n"' + LineEnding +
384
'#: lazarusidestrconsts.dlgcochecks' + LineEnding +
385
'#, fuzzy' + LineEnding +
386
'#| msgid "Checks:"' + LineEnding +
387
'msgid "Checks"' + LineEnding +
388
'msgstr "Controleert:"' + LineEnding +
390
'#: lazarusidestrconsts.listemplateeditparamcellhelp' + LineEnding +
391
'msgid ""' + LineEnding +
392
'"Inserts an editable Cell, with a default value\n"' + LineEnding +
393
'"\"\",Sync=n (,S=n), to Sync with a previous cell (n=1 to highest prev cell\n"' + LineEnding +
394
'"\"default\",Sync, to Sync with a previous cell of equal default\n"' + LineEnding +
399
function TSynPoSyn.IsKeyword(const AKeyword: string): boolean;
404
//There are only 3 keywords, so no need to make a hashtable
405
Token := LowerCase(AKeyWord);
406
for i := 1 to PoKeysCount do if (PoKeys[i] = Token) then
414
RegisterPlaceableHighlighter(TSynPoSyn);