Recent

Author Topic: Unwrapping lines in text  (Read 802 times)

zxandris

  • Full Member
  • ***
  • Posts: 163
Unwrapping lines in text
« on: March 05, 2025, 07:09:21 am »
Hi there,

I'm trying to create a routine that essentially un-wraps something i.e. when a line has a line break but the line directly under it has text.  But not if there is white space.  I think the proper term is repaginating but I'm not sure on that. I currently have :-

Code: Pascal  [Select][+][-]
  1. procedure TfrmMain.actSelectReparagraphExecute(Sender: TObject);
  2. var
  3.    lst, lst2 : TStringList;
  4.    a : Integer;
  5.    txt : String;
  6. begin
  7.      lst := TStringList.create;
  8.      try
  9.         lst.text := GetEditorText;
  10.         lst2 := TStringList.create;
  11.         try
  12.            a := 0;
  13.            if lst.count-1<>-1 then
  14.            begin
  15.                txt := lst[0];
  16.                while a<=lst.count - 1 do
  17.                begin
  18.                     if a+1<lst.count-1 then
  19.                     begin
  20.                          if trim(lst[a+1])<>'' then
  21.                          begin
  22.                              txt := txt + trim(lst[a+1]);
  23. //                             a := succ(a);
  24.                          end else
  25.                          begin
  26.                               lst2.add(txt);
  27.                               lst2.add('');
  28.                               txt := '';
  29.                          end;
  30.                     end else break;
  31.                     a := succ(a);
  32.                     if a>lst.count-1 then break;
  33.                end;
  34.                if txt<>'' then lst2.add(txt);
  35.                setEditorText(lst2.text);
  36.                memEdit.Modified := true;
  37.            end;
  38.         finally
  39.                lst2.free;
  40.         end;
  41.      finally
  42.             lst.free;
  43.      end;
  44.      SetCurrentFocus;
  45. end;
  46.  

Which only appears to work. If I've got say :-
Code: [Select]
This is a test, This is a test, This is a test, This
is a test, This is a test, This is a test, This is
a test, This is a test.

I get :-
Code: [Select]
This is a test, This is a test, This is a test, This is a test, This is a test, This is a test, This is

Which is wrong obviously.  I was hoping someone could help me with this please?

Thanks,

CJ

zxandris

  • Full Member
  • ***
  • Posts: 163
Re: Unwrapping lines in text
« Reply #1 on: March 05, 2025, 07:31:44 am »
Okay so I was a character out which is why it truncated, but I would imagine there is a better way of doing this no?

Code: Pascal  [Select][+][-]
  1. function UnWrapLines(const str : String) : string;
  2. var
  3.    lst, lst2 : TStringList;
  4.    a : Integer;
  5.    txt : String;
  6. begin
  7.      lst := TStringList.create;
  8.      try
  9.         lst.text := str;
  10.         lst2 := TStringList.create;
  11.         try
  12.            a := 0;
  13.            if lst.count-1<>-1 then
  14.            begin
  15.                txt := lst[0];
  16.                while a<=lst.count - 1 do
  17.                begin
  18.                     if a+1<=lst.count-1 then
  19.                     begin
  20.                          if trim(lst[a+1])<>'' then
  21.                          begin
  22.                              txt := txt + lst[a+1];
  23.                          end else
  24.                          begin
  25.                               lst2.add(txt);
  26.                               lst2.add('');
  27.                               txt := '';
  28.                          end;
  29.                     end else break;
  30.                     a := succ(a);
  31.                     if a>lst.count-1 then break;
  32.                end;
  33.                if txt<>'' then lst2.add(txt);
  34.            end;
  35.            if trim(lst2.text)<>'' then result := lst2.text
  36.            else result := '';
  37.         finally
  38.                lst2.free;
  39.         end;
  40.      finally
  41.             lst.free;
  42.      end;
  43. end;
  44.  

As you can see, I made it a function, tidies up my actual code a little lol.  But this seems somehow inelegant, and I would imagine there was a better way.  Is anyone willing to help me improve this?
« Last Edit: March 05, 2025, 07:33:35 am by zxandris »

Roland57

  • Hero Member
  • *****
  • Posts: 528
    • msegui.net
Re: Unwrapping lines in text
« Reply #2 on: March 05, 2025, 07:43:05 am »
Hello!

If ever it can be useful, I use something like this, under Linux, for French text.

Code: Pascal  [Select][+][-]
  1. uses
  2.   RegExpr;
  3.  
  4. const
  5.   CBefore = '\w|à|é|ù|,|\.|:|;|–|\?|!';
  6.   CAfter = '\w|à|â|é|É|ê|œ|«';
  7.  
  8. var
  9.   LText: string;
  10.  
  11. begin
  12.   LText := ReplaceRegExpr('(' + CBefore + ')\x0A(' + CAfter + ')', LText, '$1 $2', TRUE);

« Last Edit: March 05, 2025, 07:46:42 am by Roland57 »
My projects are on Codeberg.

Khrys

  • Sr. Member
  • ****
  • Posts: 342
Re: Unwrapping lines in text
« Reply #3 on: March 05, 2025, 08:01:22 am »
Using a regex like  /([^\n])\n(\S)/  with  /$1 $2/  as the substitution pattern is probably the shortest solution

zxandris

  • Full Member
  • ***
  • Posts: 163
Re: Unwrapping lines in text
« Reply #4 on: March 05, 2025, 08:03:02 am »
I must admit I've never used RegEx.  Is there a good source for information on that.  It seems, from what little I know, to be very useful.

alpine

  • Hero Member
  • *****
  • Posts: 1410
Re: Unwrapping lines in text
« Reply #5 on: March 05, 2025, 08:06:52 am »
If I got your intention right:
Code: Pascal  [Select][+][-]
  1. procedure TfrmMain.actSelectReparagraphExecute(Sender: TObject);
  2. var
  3.    lst, lst2 : TStringList;
  4.    a : Integer;
  5.    txt : String;
  6. begin
  7.    lst := TStringList.create;
  8.    try
  9.       lst.text := GetEditorText;
  10.       lst2 := TStringList.create;
  11.       try
  12.         if lst.count>0 then
  13.         begin
  14.           txt := lst[0];
  15.           a := 1;
  16.           while a<lst.count do
  17.           begin
  18.             if trim(lst[a])<>'' then
  19.               txt := txt + trim(lst[a])
  20.             else
  21.             begin
  22.               if txt<>'' then
  23.               begin
  24.                 lst2.add(txt);
  25.                 lst2.add('');
  26.               end;
  27.               txt := '';
  28.             end;
  29.             a := succ(a);
  30.           end;
  31.           if txt<>'' then lst2.add(txt);
  32.           setEditorText(lst2.text);
  33.           memEdit.Modified := true;
  34.         end;
  35.       finally
  36.         lst2.free;
  37.       end;
  38.    finally
  39.      lst.free;
  40.    end;
  41.    SetCurrentFocus;
  42. end;
"I'm sorry Dave, I'm afraid I can't do that."
—HAL 9000

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Unwrapping lines in text
« Reply #6 on: March 05, 2025, 08:23:10 am »
I leave the separation details for OP (example assumes wrapped lines contains spaces between words, at all times/everywhere).

Code: Pascal  [Select][+][-]
  1. function UnWrapLines(const str : string) : string;
  2. var
  3.   WrappedLines   : TStringList;
  4.   WrappedLine    : string;
  5.   UnwrappedLines : TStringList;
  6.   UnWrappedLine  : string = '';
  7. begin
  8.   Result := '';
  9.   WrappedLines   := TStringList.Create;
  10.   UnWrappedLines := TStringList.Create;
  11.  
  12.   try
  13.     WrappedLines.text := str;
  14.  
  15.     for WrappedLine in WrappedLines do
  16.     begin
  17.       if WrappedLine = '' then
  18.       begin
  19.         UnWrappedLines.Add(UnwrappedLine);
  20.         UnWrappedLines.Add('');
  21.         UnwrappedLine := '';
  22.       end
  23.       else
  24.       begin
  25.         UnwrappedLine := UnwrappedLine + WrappedLine;
  26.       end;
  27.     end;
  28.  
  29. // I forgot about this situation
  30.     if Length(UnwrappedLine) > 0
  31.       then UnWrappedLines.Add(UnwrappedLine);
  32. // end of forgetfulness
  33.  
  34.     result := UnwrappedLines.Text;
  35.   finally
  36.     WrappedLines.Free;
  37.     UnWrappedLines.Free;
  38.   end;
  39. end;
  40.  
« Last Edit: March 05, 2025, 08:36:41 am by TRon »
Today is tomorrow's yesterday.

zxandris

  • Full Member
  • ***
  • Posts: 163
Re: Unwrapping lines in text
« Reply #7 on: March 05, 2025, 08:27:35 am »
Hey there I'm using, as my testing text

Code: [Select]
This is a test, This is a test, This is a test, This
is a test, This is a test, This is a test, This is
a test, This is a test. This is a test, This is a
test, This is a test, This is a test, This is a test,
This is a test, This is a test, This is a test.

And your solution doesn't appear to actually return anything?!  Am I doing it wrong?

I leave the separation details for OP (example assumes wrapped lines contains spaces between words, at all times/everywhere).

Code: Pascal  [Select][+][-]
  1. function UnWrapLines(const str : string) : string;
  2. var
  3.   WrappedLines   : TStringList;
  4.   WrappedLine    : string;
  5.   UnwrappedLines : TStringList;
  6.   UnWrappedLine  : string = '';
  7. begin
  8.   Result := '';
  9.   WrappedLines   := TStringList.Create;
  10.   UnWrappedLines := TStringList.Create;
  11.  
  12.   try
  13.     WrappedLines.text := str;
  14.  
  15.     for WrappedLine in WrappedLines do
  16.     begin
  17.       if WrappedLine = '' then
  18.       begin
  19.         UnWrappedLines.Add(UnwrappedLine);
  20.         UnWrappedLines.Add('');
  21.         UnwrappedLine := '';
  22.       end
  23.       else
  24.       begin
  25.         UnwrappedLine := UnwrappedLine + WrappedLine;
  26.       end;
  27.     end;
  28.     result := UnwrappedLines.Text;
  29.   finally
  30.     WrappedLines.Free;
  31.     UnWrappedLines.Free;
  32.   end;
  33. end;
  34.  

TRon

  • Hero Member
  • *****
  • Posts: 4377
Re: Unwrapping lines in text
« Reply #8 on: March 05, 2025, 08:38:41 am »
And your solution doesn't appear to actually return anything?!  Am I doing it wrong?
Sorry, my bad. I made the assumption there is always and "empty ending" marker

I have fixed my posted code by adding the line
Code: Pascal  [Select][+][-]
  1.     if Length(UnwrappedLine) > 0
  2.       then UnWrappedLines.Add(UnwrappedLine);
  3.  
Today is tomorrow's yesterday.

Roland57

  • Hero Member
  • *****
  • Posts: 528
    • msegui.net
Re: Unwrapping lines in text
« Reply #9 on: March 05, 2025, 11:03:39 am »
My corrected solution, following Khrys' suggestion.

Code: Pascal  [Select][+][-]
  1. uses
  2.   RegExpr;
  3.  
  4. const
  5.   CSample =
  6.   'This is a test.' + LineEnding +
  7.   'This is a test.' + LineEnding + LineEnding +
  8.   'This is a test.' + LineEnding +
  9.   'This is a test.' + LineEnding +
  10.   '  This is a test.';
  11.  
  12.  
  13.   CBefore = '[^\n]'; // One character that is not line ending
  14.   CAfter = '[^\n\s]'; // One character that is neither line ending nor space
  15.  
  16. var
  17.   LText: string;
  18.  
  19. begin
  20.   LText := CSample;
  21.   LText := ReplaceRegExpr('(' + CBefore + ')\n(' + CAfter + ')', LText, '$1 $2', TRUE);
  22.   // Parentheses are for capturing.
  23.   // TRUE => Enable substitution
  24.   WriteLn(LText);
  25. end.
  26.  


Code: Text  [Select][+][-]
  1. [roland@localhost regexpr]$ ./unwrap
  2. This is a test. This is a test.
  3.  
  4. This is a test. This is a test.
  5.   This is a test.
  6.  
My projects are on Codeberg.

 

TinyPortal © 2005-2018