diff --git a/packages/fleather/lib/src/widgets/theme.dart b/packages/fleather/lib/src/widgets/theme.dart index 156c538d..0cb3a73c 100644 --- a/packages/fleather/lib/src/widgets/theme.dart +++ b/packages/fleather/lib/src/widgets/theme.dart @@ -29,7 +29,7 @@ class FleatherTheme extends InheritedWidget { } /// The data from the closest [FleatherTheme] instance that encloses the given - /// context. + /// [context]. /// /// Returns `null` if there is no [FleatherTheme] in the given build context /// and [nullOk] is set to `true`. If [nullOk] is set to `false` (default) @@ -37,8 +37,10 @@ class FleatherTheme extends InheritedWidget { static FleatherThemeData? of(BuildContext context, {bool nullOk = false}) { final widget = context.dependOnInheritedWidgetOfExactType(); if (widget == null && nullOk) return null; - assert(widget != null, - '$FleatherTheme.of() called with a context that does not contain a FleatherTheme.'); + assert( + widget != null, + '${FleatherTheme.of} called with a context that does not contain a $FleatherTheme.', + ); return widget!.data; } } diff --git a/packages/parchment/lib/codecs.dart b/packages/parchment/lib/codecs.dart index 41be299d..73df2219 100644 --- a/packages/parchment/lib/codecs.dart +++ b/packages/parchment/lib/codecs.dart @@ -1,14 +1,18 @@ /// Provides codecs to convert Parchment documents to other formats. library parchment.codecs; -import 'src/codecs/markdown.dart'; import 'src/codecs/html.dart'; +import 'src/codecs/markdown.dart'; -export 'src/codecs/markdown.dart'; export 'src/codecs/html.dart'; +export 'src/codecs/markdown.dart'; /// Markdown codec for Parchment documents. const parchmentMarkdown = ParchmentMarkdownCodec(); +/// Not strict markdown codec for Parchment documents. +const parchmentMarkdownNotStrict = + ParchmentMarkdownCodec(strictEncoding: false); + /// HTML codec for Parchment documents. const parchmentHtml = ParchmentHtmlCodec(); diff --git a/packages/parchment/lib/src/codecs/markdown.dart b/packages/parchment/lib/src/codecs/markdown.dart index c6e314e9..c0f22cd5 100644 --- a/packages/parchment/lib/src/codecs/markdown.dart +++ b/packages/parchment/lib/src/codecs/markdown.dart @@ -1,15 +1,20 @@ import 'dart:convert'; -import 'package:parchment_delta/parchment_delta.dart'; - -import '../document.dart'; -import '../document/attributes.dart'; -import '../document/block.dart'; -import '../document/leaf.dart'; -import '../document/line.dart'; +import '../../parchment.dart'; class ParchmentMarkdownCodec extends Codec { - const ParchmentMarkdownCodec(); + const ParchmentMarkdownCodec({this.strictEncoding = true}); + + /// Whether to strictly stick to the Markdown syntax during the encoding. + /// + /// If this option is enabled, during the encoding, if attributes that are + /// not natively supported by the Markdown syntax exist, an exception will be + /// thrown. Otherwise, they will be converted in the best way possible + /// (for example with HTML tags, plain text or placeholders). + /// + /// Currently supported attributes: + /// - Underline with `...` + final bool strictEncoding; @override Converter get decoder => @@ -17,7 +22,7 @@ class ParchmentMarkdownCodec extends Codec { @override Converter get encoder => - _ParchmentMarkdownEncoder(); + _ParchmentMarkdownEncoder(strict: strictEncoding); } class _ParchmentMarkdownDecoder extends Converter { @@ -354,6 +359,10 @@ class _ParchmentMarkdownDecoder extends Converter { } class _ParchmentMarkdownEncoder extends Converter { + const _ParchmentMarkdownEncoder({required this.strict}); + + final bool strict; + static final simpleBlocks = { ParchmentAttribute.bq: '> ', ParchmentAttribute.ul: '* ', @@ -403,7 +412,16 @@ class _ParchmentMarkdownEncoder extends Converter { ParchmentAttribute? currentBlockAttribute; void handleLine(LineNode node) { - if (node.hasBlockEmbed) return; + if (node.hasBlockEmbed) { + if ((node.children.single as EmbedNode).value == + BlockEmbed.horizontalRule) { + _writeHorizontalLineTag(buffer); + } else { + buffer.write('[object]'); + } + + return; + } for (final attr in node.style.lineAttributes) { if (attr.key == ParchmentAttribute.block.key) { @@ -508,8 +526,12 @@ class _ParchmentMarkdownEncoder extends Converter { // no-op already handled in handleBlock } else if (attribute?.key == ParchmentAttribute.indent.key) { // no-op already handled in handleBlock - } else { + } else if (!strict && attribute?.key == ParchmentAttribute.underline.key) { + _writeUnderlineTag(buffer, close: close); + } else if (strict) { throw ArgumentError('Cannot handle $attribute'); + } else { + _writeObjectTag(buffer); } } @@ -521,6 +543,14 @@ class _ParchmentMarkdownEncoder extends Converter { buffer.write('_'); } + void _writeUnderlineTag(StringBuffer buffer, {bool close = false}) { + if (close) { + buffer.write(''); + } else { + buffer.write(''); + } + } + void _writeInlineCodeTag(StringBuffer buffer) { buffer.write('`'); } @@ -529,8 +559,11 @@ class _ParchmentMarkdownEncoder extends Converter { buffer.write('~~'); } - void _writeLinkTag(StringBuffer buffer, ParchmentAttribute link, - {bool close = false}) { + void _writeLinkTag( + StringBuffer buffer, + ParchmentAttribute link, { + bool close = false, + }) { if (close) { buffer.write('](${link.value})'); } else { @@ -560,4 +593,12 @@ class _ParchmentMarkdownEncoder extends Converter { } } } + + void _writeHorizontalLineTag(StringBuffer buffer) { + buffer.write('---'); + } + + void _writeObjectTag(StringBuffer buffer) { + buffer.write('[object]'); + } } diff --git a/packages/parchment/test/codecs/markdown_test.dart b/packages/parchment/test/codecs/markdown_test.dart index f0f52820..7f1956cc 100644 --- a/packages/parchment/test/codecs/markdown_test.dart +++ b/packages/parchment/test/codecs/markdown_test.dart @@ -144,6 +144,20 @@ void main() { runFor('~~strike through~~\n\n', true); }); + test('underline', () { + final delta = Delta() + ..insert('an ') + ..insert('underlined', ParchmentAttribute.underline.toJson()) + ..insert(' text') + ..insert('\n'); + + final result = + parchmentMarkdownNotStrict.encode(ParchmentDocument.fromDelta(delta)); + final expected = 'an underlined text\n\n'; + + expect(result, expected); + }); + test('intersecting inline styles', () { final markdown = 'This **house _is a_ circus**\n\n'; final document = parchmentMarkdown.decode(markdown);