Flutter中如何将HTML转换为Quill Delta格式?
在Dart中将HTML解析为Quill Delta格式的方案
1. 基于html包手动实现转换逻辑
Dart的html包可以解析HTML节点,你可以遍历解析后的DOM树,将不同标签映射为对应的Delta操作,这是最灵活的自定义方案。
首先添加依赖到pubspec.yaml:
dependencies: html: ^0.15.4 quill_delta: ^1.0.0
然后编写基础转换函数(可扩展更多格式):
import 'package:html/parser.dart' show parse; import 'package:html/dom.dart'; import 'package:quill_delta/quill_delta.dart'; Delta htmlToDelta(String html) { final document = parse(html); final delta = Delta(); void traverse(Node node) { if (node is Text) { delta.insert(node.text); return; } if (node is Element) { final attributes = <String, dynamic>{}; // 映射常见格式标签到Delta属性 switch (node.localName) { case 'strong': case 'b': attributes['bold'] = true; break; case 'em': case 'i': attributes['italic'] = true; break; case 'u': attributes['underline'] = true; break; case 'br': delta.insert('\n'); return; } // 处理子节点 for (final child in node.nodes) { if (attributes.isNotEmpty) { delta.insert('', attributes); } traverse(child); } // 段落标签末尾添加换行 if (node.localName == 'p') { delta.insert('\n'); } } } traverse(document.body!); return delta; }
你可以根据需求扩展这个函数,添加标题、列表、链接等复杂标签的处理逻辑。
2. 逆向改造Quill转HTML的包
如果你已经找到Delta转HTML的包(比如quill_html_converter),可以研究它的源码映射规则,逆向实现HTML到Delta的转换。这类包通常会维护标签与Delta属性的对应表,你可以复用这个映射,反向解析HTML标签生成Delta操作。
比如某包将bold: true映射为<strong>,那你就可以在解析到<strong>标签时,为对应文本添加bold: true的属性。
3. 通过JS库桥接实现
如果需要支持复杂格式,可以借助Quill生态的JS工具(如quill-delta-from-html),通过Dart的JS交互能力调用:
- 添加
flutter_js依赖:
dependencies: flutter_js: ^0.7.0 quill_delta: ^1.0.0
- 编写调用逻辑:
import 'package:flutter_js/flutter_js.dart'; import 'package:quill_delta/quill_delta.dart'; import 'dart:convert'; Future<Delta> htmlToDeltaViaJs(String html) async { final jsRuntime = getJavascriptRuntime(); // 内嵌简化版的HTML转Delta逻辑(实际可替换为完整的quill-delta-from-html代码) final jsCode = ''' function htmlToDelta(html) { const delta = { ops: [] }; const parser = new DOMParser(); const doc = parser.parseFromString(html, 'text/html'); function walk(node) { if (node.nodeType === Node.TEXT_NODE) { delta.ops.push({ insert: node.textContent }); return; } if (node.tagName === 'STRONG') { delta.ops.push({ insert: node.textContent, attributes: { bold: true } }); return; } if (node.tagName === 'P') { Array.from(node.childNodes).forEach(walk); delta.ops.push({ insert: '\\n' }); } } Array.from(doc.body.childNodes).forEach(walk); return JSON.stringify(delta); } '''; jsRuntime.evaluate(jsCode); // 转义HTML中的单引号避免JS语法错误 final escapedHtml = html.replaceAll("'", "\\'"); final result = await jsRuntime.evaluate("htmlToDelta('$escapedHtml')"); final deltaJson = jsonDecode(result.stringResult!); return Delta.fromJson(deltaJson); }
内容的提问来源于stack exchange,提问作者MatthiasMRC
相关产品推荐
相关产品推荐

