用户要求包括处理大标题<h1>、标题<h3>、加粗,换行转段落,以及安全HTML转换。
以下是一个将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, '<',
'<', [rfReplaceAll]);
Result := StringReplace(Result, '>',
'>', [rfReplaceAll]);
Result := StringReplace(Result, '"',
'"', [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属性来修改标题检测的 字体大小阈值。