From 937398805434e925d85757fdead7c2db3a7c19f0 Mon Sep 17 00:00:00 2001 From: Vishesh Handa Date: Mon, 10 Feb 2020 16:03:48 +0100 Subject: [PATCH] Checklist: Implement serialization back into Note --- lib/core/checklist.dart | 111 +++++++++++++++++++++++++++++---------- test/checklist_test.dart | 32 ++++++++++- 2 files changed, 113 insertions(+), 30 deletions(-) diff --git a/lib/core/checklist.dart b/lib/core/checklist.dart index c95cf2b0..8b00a287 100644 --- a/lib/core/checklist.dart +++ b/lib/core/checklist.dart @@ -1,29 +1,55 @@ -import 'package:flutter/material.dart'; import 'package:markdown/markdown.dart' as md; import 'package:gitjournal/core/note.dart'; class ChecklistItem { - bool checked; - String text; md.Element element; - ChecklistItem({ - @required this.checked, - @required this.text, - @required this.element, - }); + bool get checked { + return element.attributes['checked'] != "false"; + } + + set checked(bool val) { + element.attributes['checked'] = val.toString(); + } + + String get text { + return element.attributes['text']; + } + + set text(String val) { + element.attributes['text'] = val; + } + + ChecklistItem.fromMarkdownElement(this.element); @override String toString() => 'ChecklistItem: $checked $text'; } class Checklist { - Note note; + Note _note; List items; + List nodes; - Checklist(this.note) { - items = ChecklistBuilder().parse(note.body); + Checklist(this._note) { + var doc = md.Document( + encodeHtml: false, + inlineSyntaxes: [TaskListSyntax()], + extensionSet: md.ExtensionSet.gitHubFlavored, + ); + + nodes = doc.parseInline(_note.body); + items = ChecklistBuilder().build(nodes); + } + + Note get note { + if (nodes.isEmpty) return _note; + + var renderer = CustomRenderer(); + _note.body = renderer.render(nodes); + + return _note; } } @@ -62,19 +88,12 @@ class ChecklistBuilder implements md.NodeVisitor { void visitText(md.Text text) {} @override - void visitElementAfter(md.Element element) { - final String tag = element.tag; + void visitElementAfter(md.Element el) { + final String tag = el.tag; if (tag == 'input') { - var el = element; if (el is md.Element && el.attributes['type'] == 'checkbox') { - bool val = el.attributes['checked'] != 'false'; - var item = ChecklistItem( - checked: val, - text: el.attributes['text'], - element: el, - ); - list.add(item); + list.add(ChecklistItem.fromMarkdownElement(el)); } } } @@ -87,15 +106,49 @@ class ChecklistBuilder implements md.NodeVisitor { return list; } +} - List parse(String text) { - var doc = md.Document( - encodeHtml: false, - inlineSyntaxes: [TaskListSyntax()], - extensionSet: md.ExtensionSet.gitHubFlavored, - ); +class CustomRenderer implements md.NodeVisitor { + StringBuffer buffer; - var nodes = doc.parseInline(text); - return build(nodes); + @override + bool visitElementBefore(md.Element element) { + return true; + } + + @override + void visitText(md.Text text) { + buffer.write(text.text); + } + + @override + void visitElementAfter(md.Element element) { + final String tag = element.tag; + + if (tag == 'input') { + var el = element; + if (el is md.Element && el.attributes['type'] == 'checkbox') { + bool val = el.attributes['checked'] != 'false'; + if (val) { + if (el.attributes['xUpperCase'] != 'false') { + buffer.write('[x] '); + } else { + buffer.write('[X] '); + } + } else { + buffer.write('[ ] '); + } + buffer.write(el.attributes['text']); + } + } + } + + String render(List nodes) { + buffer = StringBuffer(); + + for (final node in nodes) { + node.accept(this); + } + return buffer.toString(); } } diff --git a/test/checklist_test.dart b/test/checklist_test.dart index 4d5f0ded..fd32c1b4 100644 --- a/test/checklist_test.dart +++ b/test/checklist_test.dart @@ -30,7 +30,7 @@ How are you doing? [ ] item 1 [x] item 2 -[X] item 3 +[x] item 3 [ ] item 4 Booga Wooga @@ -55,6 +55,36 @@ Booga Wooga expect(checklist.items[1].text, "item 2"); expect(checklist.items[2].text, "item 3"); expect(checklist.items[3].text, "item 4"); + + // + // Serialization + // + + checklist.items[0].checked = true; + checklist.items[1].checked = false; + checklist.items[1].text = "Foo"; + + await checklist.note.save(); + + var expectedContent = """--- +title: Foo +modified: 2017-02-15T22:41:19+01:00 +--- + +# Title 1 + +How are you doing? + +[x] item 1 +[ ] Foo +[X] item 3 +[ ] item 4 + +Booga Wooga +"""; + + var actualContent = File(notePath).readAsStringSync(); + expect(actualContent, equals(expectedContent)); }); }); }