LazUtils: Split long lines in THTML2TextRenderer.

This commit is contained in:
Juha 2024-03-11 01:12:22 +02:00
parent eb6ba60940
commit 103d9f42e1
2 changed files with 30 additions and 10 deletions

View File

@ -31,7 +31,7 @@ type
THTML2TextRenderer = class THTML2TextRenderer = class
private private
fHTML, fOutput: string; fHTML, fOutput: string;
fMaxLines: integer; fMaxLines, fMaxLineLen: Integer;
fLineEndMark: String; // End of line, by default standard LineEnding fLineEndMark: String; // End of line, by default standard LineEnding
fTitleMark: String; // Text at start/end of title text: <div class="title">...</div> fTitleMark: String; // Text at start/end of title text: <div class="title">...</div>
fHorzLine: String; // Text for <hr> tag fHorzLine: String; // Text for <hr> tag
@ -43,7 +43,7 @@ type
fPendingSpace: Boolean; fPendingSpace: Boolean;
fPendingNewLineCnt: Integer; fPendingNewLineCnt: Integer;
fIndentStep: integer; // Increment (in spaces) for each nested HTML level fIndentStep: integer; // Increment (in spaces) for each nested HTML level
fIndent: integer; fIndent, fLineLen: Integer;
fLineCnt, fHtmlLen: Integer; fLineCnt, fHtmlLen: Integer;
p: Integer; p: Integer;
procedure AddNewLine; procedure AddNewLine;
@ -52,6 +52,7 @@ type
function HtmlTag: Boolean; function HtmlTag: Boolean;
function HtmlEntity: Boolean; function HtmlEntity: Boolean;
procedure Reset; procedure Reset;
function SplitLongLine: Boolean;
public public
constructor Create(const aHTML: string); constructor Create(const aHTML: string);
constructor Create(const Stream: TStream); constructor Create(const Stream: TStream);
@ -65,7 +66,8 @@ type
property LinkEndMark: String read fLinkEnd write fLinkEnd; property LinkEndMark: String read fLinkEnd write fLinkEnd;
property ListItemMark: String read fListItemMark write fListItemMark; property ListItemMark: String read fListItemMark write fListItemMark;
property MoreMark: String read fMoreMark write fMoreMark; property MoreMark: String read fMoreMark write fMoreMark;
property IndentStep: integer read fIndentStep write fIndentStep; property MaxLineLen: Integer read fMaxLineLen write fMaxLineLen;
property IndentStep: Integer read fIndentStep write fIndentStep;
end; end;
function RenderHTML2Text(const AHTML: String): String; function RenderHTML2Text(const AHTML: String): String;
@ -107,6 +109,7 @@ begin
//fListItemMark:='⚫ '; //fListItemMark:='⚫ ';
//fListItemMark:='⚪ '; //fListItemMark:='⚪ ';
fMoreMark:='...'; fMoreMark:='...';
fMaxLineLen:=80;
fIndentStep:=2; fIndentStep:=2;
end; end;
@ -114,7 +117,7 @@ constructor THTML2TextRenderer.Create(const Stream: TStream);
var var
s: string; s: string;
begin begin
SetLength(s{%H-},Stream.Size); SetLength(s,Stream.Size);
if s<>'' then if s<>'' then
Stream.Read(s[1],length(s)); Stream.Read(s[1],length(s));
Create(s); // Call the constructor above. Create(s); // Call the constructor above.
@ -132,6 +135,7 @@ begin
fPendingSpace:=False; fPendingSpace:=False;
fPendingNewLineCnt:=0; fPendingNewLineCnt:=0;
fIndent:=0; fIndent:=0;
fLineLen:=0;
fLineCnt:=1; fLineCnt:=1;
end; end;
@ -148,31 +152,47 @@ begin
fPendingNewLineCnt:=1; fPendingNewLineCnt:=1;
end; end;
function THTML2TextRenderer.SplitLongLine: Boolean;
// Split long lines. Return True if actually split.
begin
Result:=fLineLen>fMaxLineLen;
if Result then
AddNewLine;
end;
function THTML2TextRenderer.AddOutput(const aText: String): Boolean; function THTML2TextRenderer.AddOutput(const aText: String): Boolean;
var var
i: Integer; i: Integer;
begin begin
Result:=True; Result:=True;
if fPendingSpace and (fPendingNewLineCnt=0) then if fPendingSpace and (fPendingNewLineCnt=0) and not SplitLongLine then
begin
fOutput:=fOutput+' '; // Don't add space at end of line (before newline) fOutput:=fOutput+' '; // Don't add space at end of line (before newline)
Inc(fLineLen);
end;
fPendingSpace:=False; fPendingSpace:=False;
for i:=0 to fPendingNewLineCnt-1 do for i:=0 to fPendingNewLineCnt-1 do
begin begin
fOutput:=fOutput+fLineEndMark; fOutput:=fOutput+fLineEndMark;
fLineLen:=0;
Inc(fLineCnt); Inc(fLineCnt);
// Return False if max # of lines exceeded.
if fLineCnt>fMaxLines then if fLineCnt>fMaxLines then
begin begin
fOutput:=fOutput+fLineEndMark+fMoreMark; fOutput:=fOutput+fLineEndMark+fMoreMark;
Exit(False); Exit(False); // Return False if max # of lines exceeded.
end; end;
end; end;
if fPendingNewLineCnt>0 then if fPendingNewLineCnt>0 then
begin begin
fOutput:=fOutput+StringOfChar(' ',fIndent*fIndentStep); i:=fIndent*fIndentStep;
fOutput:=fOutput+StringOfChar(' ', i);
Inc(fLineLen, i);
fPendingNewLineCnt:=0; fPendingNewLineCnt:=0;
end; end;
fOutput:=fOutput+aText; fOutput:=fOutput+aText;
Inc(fLineLen, Length(aText));
if aText='.' then // Split also after '.'
SplitLongLine;
end; end;
function THTML2TextRenderer.HtmlTag: Boolean; function THTML2TextRenderer.HtmlTag: Boolean;

View File

@ -460,8 +460,8 @@ begin
LabelText := GetLabelText; LabelText := GetLabelText;
DrawText(DC, PChar(LabelText), Length(LabelText), R, Flags); DrawText(DC, PChar(LabelText), Length(LabelText), R, Flags);
SelectObject(DC, OldFont); SelectObject(DC, OldFont);
AWidth := R.Right - R.Left + 8; // border AWidth := R.Right - R.Left;
AHeight := R.Bottom - R.Top + 8; // border AHeight := R.Bottom - R.Top;
finally finally
ReleaseDC(Parent.Handle, DC); ReleaseDC(Parent.Handle, DC);
end; end;