Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using SysUtils.WrapText() with strings containing single quotes

I'm trying to use the SysUtils.WrapText() function with a string containing escaped single quotes characters, and I'm getting an unexpected result.

var
  Lines : TStrings;
begin
  Lines := TStringList.Create;
  try
    Lines.Text := WrapText('Can''t format message, message file not found', 15);
    ShowMessage(Lines.Text);
  finally
    Lines.Free;
  end;
end;

It seems that the function doesn't wrap the string at all, if the string contains an apostrophe character.

I've also tried using the #39 code instead of the single quote char but the problem persists. Furthermore I've checked Lines.Count and it's 1.

image

I've tried removing the single quote character:

var
  Lines : TStrings;
begin
  Lines := TStringList.Create;
  try
    Lines.Text := WrapText('Cant format message, message file not found', 15);
    ShowMessage(Lines.Text);
  finally
    Lines.Free;
  end;
end;

And it started wrapping the string as expected:

image

I'm wondering why is this happening, and how should I do for using the WrapText() function with such strings?

like image 567
Fabrizio Avatar asked Mar 29 '19 17:03

Fabrizio


2 Answers

What you describe is intentional behavior.

In Delphi XE and earlier, the WrapText() documentation included this statement:

WrapText does not insert a break into an embedded quoted string (both single quotation marks and double quotation marks are supported).

In Delphi XE2 onwards, that statement is omitted from the documentation, but the behavior is still implemented in the RTL.

I have opened a ticket with Embarcadero about this omission:

RSP-24114: Important clause about embedded quoted strings is missing from WrapText documentation

like image 186
Remy Lebeau Avatar answered Oct 17 '22 10:10

Remy Lebeau


In 10.3.1 the source includes code for handling quote characters, both double and single quotes, which looks to just ignore text between them. So one solution would be to use an apostrophe that is different from the single quote character. A second would to be to avoid using contractions. The start of the function source:

function WrapText(const Line, BreakStr: string; const BreakChars: TSysCharSet;
  MaxCol: Integer): string;
const
  QuoteChars = ['''', '"'];
  FirstIndex = Low(string);
  StrAdjust = 1 - Low(string);
var
...

One option:

    Lines.Text := WrapText('Can`t format message, message file not found', 15);

A second option:

    Lines.Text := WrapText('Cannot format message, message file not found', 15);
like image 3
Brian Avatar answered Oct 17 '22 10:10

Brian