Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 5 additions & 3 deletions packages/fleather/lib/src/widgets/theme.dart
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,18 @@ 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)
/// then this method asserts.
static FleatherThemeData? of(BuildContext context, {bool nullOk = false}) {
final widget = context.dependOnInheritedWidgetOfExactType<FleatherTheme>();
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;
}
}
Expand Down
8 changes: 6 additions & 2 deletions packages/parchment/lib/codecs.dart
Original file line number Diff line number Diff line change
@@ -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();
67 changes: 54 additions & 13 deletions packages/parchment/lib/src/codecs/markdown.dart
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
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<ParchmentDocument, String> {
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 `<u>...</u>`
final bool strictEncoding;

@override
Converter<String, ParchmentDocument> get decoder =>
_ParchmentMarkdownDecoder();

@override
Converter<ParchmentDocument, String> get encoder =>
_ParchmentMarkdownEncoder();
_ParchmentMarkdownEncoder(strict: strictEncoding);
}

class _ParchmentMarkdownDecoder extends Converter<String, ParchmentDocument> {
Expand Down Expand Up @@ -354,6 +359,10 @@ class _ParchmentMarkdownDecoder extends Converter<String, ParchmentDocument> {
}

class _ParchmentMarkdownEncoder extends Converter<ParchmentDocument, String> {
const _ParchmentMarkdownEncoder({required this.strict});

final bool strict;

static final simpleBlocks = <ParchmentAttribute, String>{
ParchmentAttribute.bq: '> ',
ParchmentAttribute.ul: '* ',
Expand Down Expand Up @@ -403,7 +412,16 @@ class _ParchmentMarkdownEncoder extends Converter<ParchmentDocument, String> {
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) {
Expand Down Expand Up @@ -508,8 +526,12 @@ class _ParchmentMarkdownEncoder extends Converter<ParchmentDocument, String> {
// 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);
}
}

Expand All @@ -521,6 +543,14 @@ class _ParchmentMarkdownEncoder extends Converter<ParchmentDocument, String> {
buffer.write('_');
}

void _writeUnderlineTag(StringBuffer buffer, {bool close = false}) {
if (close) {
buffer.write('</u>');
} else {
buffer.write('<u>');
}
}

void _writeInlineCodeTag(StringBuffer buffer) {
buffer.write('`');
}
Expand All @@ -529,8 +559,11 @@ class _ParchmentMarkdownEncoder extends Converter<ParchmentDocument, String> {
buffer.write('~~');
}

void _writeLinkTag(StringBuffer buffer, ParchmentAttribute<String> link,
{bool close = false}) {
void _writeLinkTag(
StringBuffer buffer,
ParchmentAttribute<String> link, {
bool close = false,
}) {
if (close) {
buffer.write('](${link.value})');
} else {
Expand Down Expand Up @@ -560,4 +593,12 @@ class _ParchmentMarkdownEncoder extends Converter<ParchmentDocument, String> {
}
}
}

void _writeHorizontalLineTag(StringBuffer buffer) {
buffer.write('---');
}

void _writeObjectTag(StringBuffer buffer) {
buffer.write('[object]');
}
}
14 changes: 14 additions & 0 deletions packages/parchment/test/codecs/markdown_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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 <u>underlined</u> text\n\n';

expect(result, expected);
});

test('intersecting inline styles', () {
final markdown = 'This **house _is a_ circus**\n\n';
final document = parchmentMarkdown.decode(markdown);
Expand Down