function CreateStringSplit(const AString: string; const ACharsPerLine, ALeadingSpace: Integer; const AStripControlChars, AKeepLineBreaks: Boolean; var AOutput: TStringList): Boolean;
var
i: Integer; // loop counter
s, sLead: string; // temp string that be inserted into output
LChar: string; // current char
chars: Integer; // those keep track about used space, in bytes and chars
CanAddChar, IsLineBreak: Boolean; // Bool that represents if we add a char or replace current with a space
begin
// create object if non-existant, beware to nil it where-ever you have declared it(!)
if (AOutput = nil) then
AOutput := TStringList.Create;
// clear current list
AOutput.Clear;
// initialize basics
sLead := '';
for i := 0 to ALeadingSpace do
sLead := sLead + ' ';
s := sLead;
chars := Length(sLead);
// loop over full string
for i := 1 to UTF8Length(AString) do
begin
// increment current used chars
Inc(chars);
// initialize state
CanAddChar := True;
// get current char from string
LChar := UTF8Copy(AString, i, 1);
// check if its a control char
if (AStripControlChars or AKeepLineBreaks) then
begin
// initialize state
IsLineBreak := False;
// do we found a control char?
if (CanAddChar and ((Ord(LChar[1]) < 32) or (Ord(LChar[1]) = 127))) then
begin
// is it a carriage return (CR) ?
if (AKeepLineBreaks and (Ord(LChar[1]) = 13)) then
IsLineBreak := True;
// is it a linefeed (LF) ? (if we already had CR, or one comes next, skip it)
if ((AKeepLineBreaks and (Ord(LChar[1]) = 10)) and ((Pred(i) > 0) and (Ord(UTF8Copy(AString, Pred(i), 1)[1]) <> 13)) and ((Succ(i) <= UTF8Length(AString)) and (Ord(UTF8Copy(AString, Succ(i), 1)[1]) <> 13))) then
IsLineBreak := True;
// forbid usage of current char
if AStripControlChars or IsLineBreak then
CanAddChar := False;
end;
end;
// we found a char to add
if CanAddChar then
begin
// add current char to the string
s := s + LChar;
// did we reached the limit?
if (chars >= ACharsPerLine) then
begin
// add current string to the string list
AOutput.Add(s);
// initialize basics
s := sLead;
chars := Length(s);
end;
end
// not allowed char found
else
// was the not allowed char a linebreak that we wanted to rescue?
if (AKeepLineBreaks and IsLineBreak) then
begin
// add current string to the string list
AOutput.Add(s);
// initialize basics
s := sLead;
chars := Length(s);
end
else
// replace control char with a space
s := s + ' ';
end;
// do not forget to append the last information to list
if (s <> '') then
AOutput.Add(s);
// exit method by telling a success state
Result := (AOutput.Count > 0);
end;