flutter 富文本将delta转换成html,以及将html转换成delta
·
目前只支持转换字体颜色、背景颜色、粗体、斜体、删除线、下划线、超链接,剩下的会根据需求持续更新
1、将delta转换成html
delta列子
我们应该转换成下面这个样子
这里需要用到一个组件 QuillDeltaToHtmlConverter,本来可以直接用的,但是不能识别颜色,所以只能重写里面的方法 convert
class CustomQuillDeltaToHtmlConverter extends QuillDeltaToHtmlConverter {
final List<Map<String, dynamic>> delta; // 声明 delta 属性
CustomQuillDeltaToHtmlConverter(
this.delta, // 在构造函数中初始化 delta
ConverterOptions options)
: super(delta, options);
@override
String convert() {
var html = '';
for (var op in delta) {
var attributes = op['attributes'] ?? {};
var text = op['insert'] ?? '';
// 处理颜色
String colorStyle = attributes['color'] != null
? 'style="color: ${attributes['color']};"'
: '';
// 处理背景颜色
String bgColorStyle = attributes['background'] != null
? 'style="background: ${attributes['background']};"'
: '';
// 生成 HTML
if (attributes.isNotEmpty) {
html += '<span $colorStyle>';
html += '<span $bgColorStyle>';
// 检查是否有超链接
if (attributes['link'] != null) {
var link = attributes['link'];
html += '<a href="$link" $colorStyle $bgColorStyle>';
} else {
html += '<span $colorStyle $bgColorStyle>';
}
if (attributes['bold'] == true) html += '<strong>';
if (attributes['italic'] == true) html += '<em>';
if (attributes['underline'] == true) html += '<u>';
if (attributes['strike'] == true) html += '<s>';
html += text;
if (attributes['strike'] == true) html += '</s>';
if (attributes['underline'] == true) html += '</u>';
if (attributes['italic'] == true) html += '</em>';
if (attributes['bold'] == true) html += '</strong>';
html += '</span>';
// 结束链接或 span
if (attributes['link'] != null) {
html += '</a>';
} else {
html += '</span>';
}
} else {
html += text;
}
}
return html.replaceAll('\n', '<br/>'); // 处理换行
}
}
2、将html转换成delta
转换方法
class HtmlToDeltaConverter {
static Delta htmlToDelta(String html) {
final document = html_parser.parse(html);
var delta = Delta();
// 处理节点并合并到 delta 中
for (final node in document.body?.nodes ?? []) {
if (node is dom.Element) {
delta = delta.concat(_parseInlineStyles(node));
}
}
// 检查末尾是否有换行符
if (delta.length == 0 || (delta.last.data != '\n')) {
delta.insert('\n'); // 如果没有换行符,则添加一个
}
return delta;
}
static Delta _parseInlineStyles(dom.Element element,
[Map<String, dynamic>? inheritedStyles]) {
var delta = Delta();
var currentAttributes = _parseElementStyles(element);
// 合并当前样式和继承的样式
if (inheritedStyles != null) {
currentAttributes.addAll(inheritedStyles);
}
for (final node in element.nodes) {
if (node is dom.Text) {
// 合并文本并应用当前的样式
delta.insert(node.text, currentAttributes);
} else if (node is dom.Element) {
if (node.localName == 'br') {
delta.insert('\n');
} else {
// 处理其他内联元素并合并样式
delta = delta.concat(_parseInlineStyles(node, currentAttributes));
}
}
}
return delta;
}
static Map<String, dynamic> _parseElementStyles(dom.Element element) {
final Map<String, dynamic> attributes = {};
// 检查样式
if (element.localName == 'strong') attributes['bold'] = true;
if (element.localName == 'em') attributes['italic'] = true;
if (element.localName == 'u') attributes['underline'] = true;
if (element.localName == 's') attributes['strike'] = true;
// 检查超链接
if (element.localName == 'a') {
final href = element.attributes['href'];
if (href != null) {
attributes['link'] = href; // 添加超链接属性
}
}
var style = element.attributes['style'];
if (style != null) {
final colorValue = _parseColorFromStyle(style, 'color');
if (colorValue != null) attributes['color'] = colorValue;
final bgColorValue = _parseColorFromStyle(style, 'background');
if (bgColorValue != null) attributes['background'] = bgColorValue;
}
return attributes;
}
static String? _parseColorFromStyle(String style, String type) {
// 正则表达式字符串拼接
final colorRegex = '$type:\\s*#([0-9A-Fa-f]{6}|[0-9A-Fa-f]{8})';
final colorMatch = RegExp(colorRegex).firstMatch(style);
if (colorMatch != null) {
return '#${colorMatch.group(1)}'; // 返回完整颜色值
}
// 匹配 rgba() 或 rgb() 格式
final rgbaRegex =
'$type:\\s*rgba?\\(\\s*(\\d+),\\s*(\\d+),\\s*(\\d+)(?:,\\s*([0-9.]+))?\\s*\\)';
final rgbaMatch = RegExp(rgbaRegex).firstMatch(style);
if (rgbaMatch != null) {
final r = int.parse(rgbaMatch.group(1)!);
final g = int.parse(rgbaMatch.group(2)!);
final b = int.parse(rgbaMatch.group(3)!);
return '#${(r << 16 | g << 8 | b).toRadixString(16).padLeft(6, '0')}'; // 转换为十六进制
}
return null; // 如果没有找到任何颜色
}
}
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐


所有评论(0)