From f2af5c9c75d692c1f519c827191e0b4d4d12b7e2 Mon Sep 17 00:00:00 2001 From: Vishesh Handa Date: Mon, 13 May 2019 22:36:32 +0200 Subject: [PATCH] Improve markdown to text conversion Use a proper markdown parser to convert the text. This way more of the formatting is correctly removed. --- lib/utils/markdown.dart | 53 +++++++++++++++++++++++++++++++++++ lib/widgets/journal_list.dart | 6 ++-- test/markdown_text_test.dart | 23 +++++++++++++++ 3 files changed, 78 insertions(+), 4 deletions(-) create mode 100644 lib/utils/markdown.dart create mode 100644 test/markdown_text_test.dart diff --git a/lib/utils/markdown.dart b/lib/utils/markdown.dart new file mode 100644 index 00000000..9a525e27 --- /dev/null +++ b/lib/utils/markdown.dart @@ -0,0 +1,53 @@ +import 'dart:core'; + +import 'package:markdown/markdown.dart' as md; + +/// Builds a plain text [String] from parsed Markdown. +class MarkdownBuilder implements md.NodeVisitor { + List _texts = []; + + String build(List nodes) { + _texts.clear(); + + for (md.Node node in nodes) { + node.accept(this); + } + + var stringBuffer = StringBuffer(); + _texts.forEach((String text) { + var t = text.trim(); + if (t.isNotEmpty) { + t = t.replaceAll('\n', ' '); + t = t.trim(); + stringBuffer.write(t); + stringBuffer.write(' '); + } + }); + + var str = stringBuffer.toString(); + return str.substring(0, str.length - 1); + } + + @override + void visitText(md.Text text) { + _texts.add(text.text); + } + + @override + bool visitElementBefore(md.Element element) { + return true; + } + + @override + void visitElementAfter(md.Element element) { + return; + } +} + +String markdownToPlainText(String markdown) { + final List lines = markdown.replaceAll('\r\n', '\n').split('\n'); + var doc = md.Document(encodeHtml: false); + + final MarkdownBuilder builder = MarkdownBuilder(); + return builder.build(doc.parseLines(lines)); +} diff --git a/lib/widgets/journal_list.dart b/lib/widgets/journal_list.dart index 7185b9fb..5d501417 100644 --- a/lib/widgets/journal_list.dart +++ b/lib/widgets/journal_list.dart @@ -4,6 +4,7 @@ import 'package:intl/intl.dart'; import 'package:journal/note.dart'; import 'package:journal/state_container.dart'; import 'package:journal/utils.dart'; +import 'package:journal/utils/markdown.dart'; import 'package:path/path.dart'; typedef void NoteSelectedFunction(int noteIndex); @@ -76,10 +77,7 @@ class JournalList extends StatelessWidget { title = basename(journal.filePath); } - var body = journal.body; - body = body.replaceAll("\n", " "); - body = body.replaceAll("#", ""); - body = body.trim(); + var body = markdownToPlainText(journal.body); var textTheme = Theme.of(context).textTheme; var children = []; diff --git a/test/markdown_text_test.dart b/test/markdown_text_test.dart new file mode 100644 index 00000000..ce3d7d05 --- /dev/null +++ b/test/markdown_text_test.dart @@ -0,0 +1,23 @@ +import 'package:journal/utils/markdown.dart'; +import 'package:test/test.dart'; + +void main() { + group('Markdown To Text', () { + test('Test Headers', () { + var input = '# Hello\nHow are you?'; + expect(markdownToPlainText(input), 'Hello How are you?'); + }); + + test('Itemized LIsts', () { + var input = """Itemized lists +look like: + + * this one + * that one + """; + + expect(markdownToPlainText(input), + 'Itemized lists look like: this one that one'); + }); + }); +}