Just my 2 cents. While this task appears to be simple, it obviously isn't. The trick is to break up the process into 3 sections.
1) Split a string into a token structure.
2) Join the structure into a new structure (formatted to your requirements).
3) Combine both steps 1 & 2 into a utility function.
For something this simple, a TStringList is perfect for the "token structure". An "array of string" is also useful, but lacks many of the TStringList features.
Your step one can be as simple as this: (Note: there are problems with using DelimtedText, which is dependent on your requirements)
procedure MySplit(ADest: TStrings; const ASource: string);
begin
ADest.DelimitedText := ASource; // You can modify this builtin parsing feature later to suit your requirments.
end;
As far as I can see, your step two is something like:
procedure MyJoin(ADest, ASource: TStrings; AIndent, AColWidth: integer);
var
LIndex: integer;
LBuffer: string;
begin
if ASource.Count > 0 then begin
LBuffer := StringOfChar(' ', AIndent) + ASource[0];
for LIndex := 1 to ASource.Count - 1 do begin
if Length(LBuffer) + Length(ASource[LIndex]) > AColWidth then begin
ADest.Add(LBuffer);
LBuffer := StringOfChar(' ', Length(ASource[0]) + AIndent);
end;
LBuffer := LBuffer + ' ' + ASource[LIndex];
end;
ADest.Add(LBuffer);
end;
end;
Therefore your step 3 is:
procedure MyParse(ADest: TStrings; const ASource: string; AIndent, AColWidth: integer);
var
LTemp: TStringList;
begin
LTemp := TStringList.Create;
try
MySplit(LTemp, ASource);
MyJoin(ADest, LTemp, AIndent, AColWidth);
finally
LTemp.Free;
end;
end;
Parsing only gets harder as the syntax becomes more complex. By breaking up the task this way, you prevent your final functionality from becoming impossible to modify and unit test.
Note: MyParse() can now be called to parse a string and append the formatted results to a TMemo. You have already expressed how long your solution took, and how many rewrites it required. Always think about future requirements. Maybe the input string comes from a TIniFile, XML, TDbf, Http encoded, or a TStringGrid user interface. It could be anything. You want to aim for a standard intermediate data structure, so the formatting (encoding) code is separate from your parsing (decoding) code.