文章详细内容

用delphi写一个类,把TRichEdit的内容,转换成html格式片段。

用户要求包括处理大标题<h1>、标题<h3>、加粗,换行转段落,以及安全HTML转换。


绿色破解吧(https://www.ucrack.top/)2025年04月24日讯息:

以下是一个将TRichEdit内容转换为HTML格式的Delphi类实现,支持大 标题(h1)、标题(h3)、加粗、换行转换为段落,并确保HTML安 全:

```delphi
unit RichEditToHtml;

interface

uses
System.SysUtils, System.Classes, Vcl.ComCtrls, Winapi.Messages, Winapi.Windows;

type
TRichEditToHtmlConverter = class
private
FH1FontSize: Integer; // Twips (1/20 point)
FH3FontSize: Integer;
function EscapeHtml(const Text: string): string;
function GetParagraphTag(RichEdit: TRichEdit; ParagraphIndex: Integer): string;
function ProcessParagraph(RichEdit: TRichEdit; ParagraphIndex: Integer): string;
public
constructor Create;
function Convert(RichEdit: TRichEdit): string;
property H1FontSize: Integer read FH1FontSize write FH1FontSize;
property H3FontSize: Integer read FH3FontSize write FH3FontSize;
end;

implementation

{ TRichEditToHtmlConverter }

constructor TRichEditToHtmlConverter.Create;
begin
// Default sizes in twips (24pt = 24*20 = 480, 18pt = 360)
FH1FontSize := 480;
FH3FontSize := 360;
end;

function TRichEditToHtmlConverter.Convert(RichEdit: TRichEdit): string;
var
i: Integer;
html: TStringBuilder;
begin
if not Assigned(RichEdit) then
Exit('');

html := TStringBuilder.Create;
try
for i := 0 to RichEdit.Lines.Count - 1 do
begin
html.Append (ProcessParagraph(RichEdit, i));
end;
Result := html.ToString;
finally
html.Free;
end;
end;

function TRichEditToHtmlConverter.EscapeHtml(const Text: string): string;
begin
Result := Text;
Result := StringReplace(Result, '&', '&', [rfReplaceAll]);
Result := StringReplace(Result, '<', '&lt;', [rfReplaceAll]);
Result := StringReplace(Result, '>', '&gt;', [rfReplaceAll]);
Result := StringReplace(Result, '"', '&quot;', [rfReplaceAll]);
Result := StringReplace(Result, '''', '& #39;', [rfReplaceAll]);
end;

function TRichEditToHtmlConverter.GetParagraphTag(RichEdit: TRichEdit; ParagraphIndex: Integer): string;
var
charFormat: TCharFormat2;
startPos: Integer;
begin
startPos := SendMessage (RichEdit.Handle, EM_LINEINDEX, ParagraphIndex, 0);
if startPos = -1 then Exit('p');

RichEdit.SelStart := startPos;
RichEdit.SelLength := 1;

FillChar(charFormat, SizeOf(charFormat), 0);
charFormat.cbSize := SizeOf(charFormat);
SendMessage(RichEdit.Handle, EM_GETCHARFORMAT, SCF_SELECTION, LPARAM(@charFormat));

if (charFormat.dwMask and CFM_SIZE) <> 0 then
begin
if charFormat.yHeight >= FH1FontSize then
Exit('h1')
else if charFormat.yHeight >= FH3FontSize then
Exit('h3');
end;
Result := 'p';
end;

function TRichEditToHtmlConverter.ProcessParagraph(RichEdit: TRichEdit; ParagraphIndex: Integer): string;
var
paraText: string;
startPos, i: Integer;
currentBold: Boolean;
htmlContent: TStringBuilder;
charFormat: TCharFormat2;
tag: string;
begin
paraText := RichEdit.Lines[ParagraphIndex];
if paraText = '' then Exit('');

tag := GetParagraphTag(RichEdit, ParagraphIndex);
startPos := SendMessage(RichEdit.Handle, EM_LINEINDEX, ParagraphIndex, 0);
if startPos = -1 then Exit('');

htmlContent := TStringBuilder.Create;
try
currentBold := False;
for i := 0 to Length(paraText) - 1 do
begin
RichEdit.SelStart := startPos + i;
RichEdit.SelLength := 1;

FillChar(charFormat, SizeOf(charFormat), 0);
charFormat.cbSize := SizeOf(charFormat);
SendMessage (RichEdit.Handle, EM_GETCHARFORMAT, SCF_SELECTION, LPARAM (@charFormat));

// Handle bold formatting
if (charFormat.dwMask and CFM_BOLD) <> 0 then
begin
if ((charFormat.dwEffects and CFE_BOLD) <> 0) <> currentBold then
begin
if currentBold then
htmlContent.Append('</b>')
else
htmlContent.Append('<b>');
currentBold := not currentBold;
end;
end;

// Add escaped character
htmlContent.Append(EscapeHtml (paraText[i+1]));
end;

// Close remaining tags
if currentBold then
htmlContent.Append('</b>');

// Wrap in paragraph tag
Result := Format('<%s>%s</% s>' + sLineBreak, [tag, htmlContent.ToString, tag]);
finally
htmlContent.Free;
end;
end;

end.
```

使用示例:

```delphi
// 使用示例
procedure TForm1.Button1Click(Sender: TObject);
var
converter: TRichEditToHtmlConverter;
html: string;
begin
converter := TRichEditToHtmlConverter.Create;
try
// 可选:自定义字体大小(单位:twips)
// converter.H1FontSize := 480; // 24pt
// converter.H3FontSize := 360; // 18pt

html := converter.Convert(RichEdit1);
Memo1.Text := html;
finally
converter.Free;
end;
end;
```

特性说明:
1. 标题检测:根据段落首字符的字体大小自动检测 h1/h3
2. 格式处理:自动处理加粗文本并正确嵌套标签
3. 安全 转换:自动转义HTML特殊字符
4. 段落处理:自动将每个文本段落 转换为HTML段落
5. 可配置性:允许自定义标题字体大小阈值

注意事项:
1. 字体大小单位使用twips(1/20磅),默认h1为 24pt(480twips),h3为18pt(360twips)
2. 段落检测基于TRichEdit的 Lines属性
3. 自动处理未闭合的格式标签
4. 支持混合格式文本 (如部分加粗的段落)

您可以根据需要调整H1FontSize和H3FontSize属性来修改标题检测的 字体大小阈值。