relatica/lib/utils/html_to_edit_text_helper.dart

116 wiersze
2.9 KiB
Dart

import 'package:html/dom.dart';
import 'package:html/parser.dart';
String htmlToSimpleText(String htmlContentFragment) {
final dom = parseFragment(htmlContentFragment);
final segments = dom.nodes
.map((n) => n is Element ? n.elementToEditText() : n.nodeToEditText())
.toList();
return segments.join('');
}
extension NodeTextConverter on Node {
String nodeToEditText() {
if (nodes.isEmpty) {
final stringWithQuotes = toString();
final start = stringWithQuotes.startsWith('"') ? 1 : 0;
final end = stringWithQuotes.endsWith('"')
? stringWithQuotes.length - 1
: stringWithQuotes.length;
return stringWithQuotes.substring(start, end);
}
final convertedNodes = nodes
.map((n) => n is Element ? n.elementToEditText() : n.nodeToEditText())
.toList();
return convertedNodes.join('');
}
}
extension ElementTextConverter on Element {
String elementToEditText({int depth = 0}) {
late final String innerText;
late final String startText;
late final String endText;
switch (localName) {
case 'a':
startText = '';
innerText = htmlLinkToString();
endText = '';
break;
case 'br':
startText = '';
innerText = '';
endText = '\n';
break;
case 'p':
startText = '';
innerText = buildInnerText(depth);
endText = '\n';
break;
case 'em':
startText = '*';
innerText = buildInnerText(depth);
endText = '*';
break;
case 'strong':
startText = '**';
innerText = buildInnerText(depth);
endText = '**';
break;
case 'li':
startText = '\n${buildTabs(depth)}- ';
innerText = buildInnerText(depth);
endText = '';
break;
case 'ul':
startText = '';
innerText = buildInnerText(depth + 1);
endText = '';
break;
default:
startText = '<$localName>';
innerText = buildInnerText(depth);
endText = '</$localName>';
}
return '$startText$innerText$endText';
}
String htmlLinkToString() {
final attrs = attributes['class'] ?? '';
if (attrs.contains('hashtag')) {
return text;
}
if (attrs.contains('mention')) {
final uri = Uri.parse(attributes['href'] ?? '');
final host = uri.host;
final username = text;
return '$username@$host';
}
return attributes['href'] ?? 'No link found';
}
String buildInnerText(int depth) {
if (nodes.isEmpty) {
return '';
}
final convertedNodes = nodes
.map((n) => n is Element
? n.elementToEditText(depth: depth)
: n.nodeToEditText())
.toList();
return convertedNodes.join('');
}
String buildTabs(int depth) => depth == 0
? ''
: List.generate(
depth,
(index) => ' ',
).join('');
}