unit Unit1;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Buttons, Process, StrUtils, Math;
type
{ TForm1 }
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Edit1: TEdit;
Edit2: TEdit;
Edit3: TEdit;
Memo1: TMemo;
OpenDialog1: TOpenDialog;
SpeedButton1: TSpeedButton;
SpeedButton2: TSpeedButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure SpeedButton1Click(Sender: TObject);
procedure SpeedButton2Click(Sender: TObject);
private
SassProcess: TProcess;
procedure KillProcess;
function GetRelativePath(const BasePath, FullPath: string): string;
public
end;
var
Form1: TForm1;
implementation
{$R *.lfm}
{ TForm1 }
function TForm1.GetRelativePath(const BasePath, FullPath: string): string;
var
BaseList, FileList: TStringArray;
i, CommonIndex, UpLevels: Integer;
RelativePart, NormalizedBase, NormalizedFull: String;
begin
// Normalizacja ścieżek
NormalizedBase := ExcludeTrailingPathDelimiter(ExpandFileName(BasePath));
NormalizedFull := ExpandFileName(FullPath);
// Jeśli ścieżki są na różnych dyskach → pełna ścieżka
if AnsiCompareText(ExtractFileDrive(NormalizedBase), ExtractFileDrive(NormalizedFull)) <> 0 then
Exit(NormalizedFull);
// Jeśli BasePath jest początkiem FullPath → bezpośrednia relatywizacja
if AnsiStartsText(NormalizedBase + PathDelim, NormalizedFull + PathDelim) then
Exit(Copy(NormalizedFull, Length(NormalizedBase) + 2, MaxInt));
// Podział ścieżek na segmenty
BaseList := SplitString(NormalizedBase, PathDelim);
FileList := SplitString(NormalizedFull, PathDelim);
// Znalezienie wspólnego katalogu
CommonIndex := -1;
for i := 0 to Min(High(BaseList), High(FileList)) do
begin
if AnsiCompareText(BaseList[i], FileList[i]) <> 0 then Break;
CommonIndex := i;
end;
// Cofanie się do wspólnego katalogu
UpLevels := Length(BaseList) - CommonIndex - 1;
RelativePart := DupeString('..' + PathDelim, UpLevels);
// Dodanie reszty ścieżki
for i := CommonIndex + 1 to High(FileList) do
begin
RelativePart := RelativePart + FileList[i];
if i < High(FileList) then
RelativePart := RelativePart + PathDelim;
end;
Result := RelativePart;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
DartPath, SnapshotPath, InputPath, OutputPath: string;
begin
DartPath := ExpandFileName(Edit3.Text + 'src' + PathDelim + 'dart.exe');
SnapshotPath := ExpandFileName(Edit3.Text + 'src' + PathDelim + 'sass.snapshot');
SassProcess := TProcess.Create(nil);
SassProcess.Options := [poUsePipes, poStderrToOutPut, poNoConsole];
SassProcess.CurrentDirectory := Form1.Edit3.Text;
SassProcess.Executable := DartPath;
SassProcess.Parameters.Add(SnapshotPath);
SassProcess.Parameters.Add('sass');
SassProcess.Parameters.Add(Edit1.Text);
SassProcess.Parameters.Add(Edit2.Text);
SassProcess.Execute;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
KillProcess;
end;
procedure TForm1.SpeedButton1Click(Sender: TObject);
var
FullPath, ProjectPath: string;
begin
if OpenDialog1.Execute then
begin
FullPath := ExtractFilePath(OpenDialog1.FileName);
ProjectPath := ExtractFileDir(ExcludeTrailingPathDelimiter(FullPath));
Edit3.Text := IncludeTrailingPathDelimiter(ProjectPath);
Edit1.Text := GetRelativePath(Edit3.Text, OpenDialog1.FileName);
end;
end;
procedure TForm1.SpeedButton2Click(Sender: TObject);
begin
OpenDialog1.InitialDir := Edit3.Text;
if OpenDialog1.Execute then
begin
Edit2.Text := GetRelativePath(Edit3.Text, OpenDialog1.FileName);
end;
end;
procedure TForm1.KillProcess;
begin
if Assigned(SassProcess) then
begin
if SassProcess.Running then
SassProcess.Terminate(0);
SassProcess.Free;
SassProcess := nil;
end;
end;
end.