diff --git a/core/lib/utils/string_convert.dart b/core/lib/utils/string_convert.dart index 018e27692..595ef1958 100644 --- a/core/lib/utils/string_convert.dart +++ b/core/lib/utils/string_convert.dart @@ -4,6 +4,7 @@ import 'dart:typed_data'; import 'package:core/utils/app_logger.dart'; import 'package:core/domain/exceptions/string_exception.dart'; import 'package:core/utils/mail/named_address.dart'; +import 'package:html/dom.dart'; import 'package:html/parser.dart'; import 'package:http_parser/http_parser.dart'; @@ -198,15 +199,29 @@ class StringConvert { } static String convertHtmlContentToTextContent(String htmlContent) { - String textContent = htmlContent.replaceAll(RegExp(r'<[^>]*>'), ''); + final document = parse(htmlContent); - textContent = textContent - .replaceAll(' ', ' ') - .replaceAll('&', '&') - .replaceAll('<', '<') - .replaceAll('>', '>') - .replaceAll('"', '"') - .replaceAll(''', "'"); + // Each paragraph is surrounded by block tags so we add a /n for each block tag + // Even
are surrounded by block tags so we can ignore
and treat them + // as paragraph + const blockTags = [ + 'p', + 'div', + 'li', + 'section', + 'article', + 'header', + 'footer', + 'h1','h2','h3','h4','h5','h6' + ]; + + for (final tag in blockTags) { + document.querySelectorAll(tag).forEach((element) { + element.append(Text('\n')); + }); + } + + final String textContent = document.body?.text ?? ''; return textContent.trim(); } diff --git a/core/test/utils/string_convert_test.dart b/core/test/utils/string_convert_test.dart index 0141cd32a..b72ab12db 100644 --- a/core/test/utils/string_convert_test.dart +++ b/core/test/utils/string_convert_test.dart @@ -816,4 +816,20 @@ void main() { ); }); }); + + group('StringConvert.convertHtmlContentToTextContent', () { + test('should preserve line breaks between paragraphs', () { + const htmlContent = '

First paragraph

Second paragraph

Third paragraph

'; + final result = StringConvert.convertHtmlContentToTextContent(htmlContent); + + expect(result, 'First paragraph\nSecond paragraph\nThird paragraph'); + }); + + test('should preserve line breaks for br', () { + const htmlContent = '

First paragraph


Second paragraph

'; + final result = StringConvert.convertHtmlContentToTextContent(htmlContent); + + expect(result, 'First paragraph\n\nSecond paragraph'); + }); + }); }