unit CSSParser;
interface
type
TCSSItemType = (itHead, itSimple, itLast, itEmptyLast, itComment, itSGMLComment);
TCSSParser = class
private
Final: Boolean;
FItemType: TCSSItemType;
PInitial: PChar;
PFinal: PChar;
PRun: PChar;
FItem: string;
FComment: string;
public
constructor Create(S: string);
function Next: Boolean;
property ItemType: TCSSItemType read FItemType;
property Item: string read FItem;
property Comment: string read FComment;
end;
implementation
function GetTrim(From,Before: PChar): string;
begin
while (From<Before) and (From^<'!') do Inc(From);
Dec(Before);
while (From<Before) and (Before<'!') do Dec(Before);
SetLength(Result, Succ(Before-From));
Move(From^, Pointer(Result)^, Length(Result));
end;
constructor TCSSParser.Create(S: string);
begin
PInitial:=Pointer(S);
PRun:=PInitial;
PFinal:=PInitial+Length(S);
Final:=False;
end;
function TCSSParser.Next: boolean;
var
PLabel: PChar;
PComment: PChar;
label
Loop;
begin
PLabel:=PRun;
Result:=False;
if (PRun=nil) or (PRun>PFinal) then Exit;
Loop:
case PRun^ of
'{':
begin
FItem:=GetTrim(PLabel,PRun);
FItemType:=itHead;
Result:=True;
Inc(PRun);
end;
';':
begin
FItem:=GetTrim(PLabel,PRun);
FItemType:=itSimple;
Result:=True;
Inc(PRun);
end;
'}':
begin
FItem:=GetTrim(PLabel,PRun);
if FItem<>''
then FItemType:=itLast
else FItemType:=itEmptyLast;
Result:=True;
Inc(PRun);
end;
'/': if PRun[1]='*' then
begin
PComment:=PRun;
Inc(PComment);
repeat
Inc(PComment)
until (PComment[1]=#0) or ((PComment[-1]='*') and (PComment[0]='/'));
FItem:=GetTrim(PRun, @PComment[1]);
FItemType:=itComment;
Result:=True;
Inc(PComment);
Move(PComment^, PRun^, Succ(PFinal-PComment));
Dec(PFinal, PComment-PRun);
PRun:=PLabel;
end else
begin
Inc(PRun);
goto Loop;
end;
'<': if (PRun[1]='!') and (PRun[2]='-') and (PRun[3]='-') then
begin
FItem:=GetTrim(PLabel,PRun);
FItemType:=itSGMLComment;
Result:=True;
Inc(PRun,4);
end else
begin
Inc(PRun);
goto Loop;
end;
'-': if (PRun[1]='-') and (PRun[2]='>') then
begin
FItem:=GetTrim(PLabel,PRun);
FItemType:=itSGMLComment;
Result:=True;
Inc(PRun,3);
end else
begin
Inc(PRun);
goto Loop;
end;
#0: if Final then Result:=False else
begin
FItem:=GetTrim(PLabel,PRun);
if FItem=''
then FItemType:=itEmptylast
else FItemType:=itLast;
Result:=True;
Final:=True;
end;
else
begin
Inc(PRun);
goto Loop;
end;
end;
end;
end.