mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: delta to markdown
This commit is contained in:
parent
ab664ebb2f
commit
c85ab276e9
@ -111,6 +111,47 @@ class _MyHomePageState extends State<MyHomePage> {
|
||||
if (!darkMode) ...lightEditorStyleExtension,
|
||||
if (!darkMode) ...lightPlguinStyleExtension,
|
||||
]);
|
||||
final delta = Delta();
|
||||
delta.add(TextInsert('Hello '));
|
||||
delta.add(
|
||||
TextInsert(
|
||||
'World',
|
||||
attributes: {
|
||||
BuiltInAttributeKey.bold: true,
|
||||
BuiltInAttributeKey.italic: true,
|
||||
},
|
||||
),
|
||||
);
|
||||
delta.add(
|
||||
TextInsert(
|
||||
' ',
|
||||
),
|
||||
);
|
||||
delta.add(
|
||||
TextInsert(
|
||||
'Again',
|
||||
attributes: {
|
||||
BuiltInAttributeKey.italic: true,
|
||||
},
|
||||
),
|
||||
);
|
||||
delta.add(
|
||||
TextInsert(
|
||||
' ',
|
||||
),
|
||||
);
|
||||
delta.add(
|
||||
TextInsert(
|
||||
'Again',
|
||||
attributes: {
|
||||
BuiltInAttributeKey.href: 'https://google.com',
|
||||
BuiltInAttributeKey.italic: true,
|
||||
BuiltInAttributeKey.bold: true,
|
||||
BuiltInAttributeKey.strikethrough: true,
|
||||
},
|
||||
),
|
||||
);
|
||||
final result = DeltaMarkdownEncoder().convert(delta);
|
||||
return Container(
|
||||
color: darkMode ? Colors.black : Colors.white,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
|
@ -33,3 +33,4 @@ export 'src/render/selection_menu/selection_menu_widget.dart';
|
||||
export 'src/l10n/l10n.dart';
|
||||
export 'src/render/style/plugin_styles.dart';
|
||||
export 'src/render/style/editor_style.dart';
|
||||
export 'src/plugins/markdown/delta_markdown_encoder.dart';
|
||||
|
@ -0,0 +1,88 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
|
||||
/// A [Delta] encoder that encodes a [Delta] to Markdown.
|
||||
///
|
||||
/// Only support inline styles, like bold, italic, underline, strike, code.
|
||||
class DeltaMarkdownEncoder extends Converter<Delta, String> {
|
||||
@override
|
||||
String convert(Delta input) {
|
||||
final buffer = StringBuffer();
|
||||
final iterator = input.iterator;
|
||||
while (iterator.moveNext()) {
|
||||
final op = iterator.current;
|
||||
if (op is TextInsert) {
|
||||
final attributes = op.attributes;
|
||||
if (attributes != null) {
|
||||
buffer.write(_prefixSyntax(attributes));
|
||||
buffer.write(op.text);
|
||||
buffer.write(_suffixSyntax(attributes));
|
||||
} else {
|
||||
buffer.write(op.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
String _prefixSyntax(Attributes attributes) {
|
||||
var syntax = '';
|
||||
|
||||
if (attributes[BuiltInAttributeKey.bold] == true &&
|
||||
attributes[BuiltInAttributeKey.italic] == true) {
|
||||
syntax += '***';
|
||||
} else if (attributes[BuiltInAttributeKey.bold] == true) {
|
||||
syntax += '**';
|
||||
} else if (attributes[BuiltInAttributeKey.italic] == true) {
|
||||
syntax += '_';
|
||||
}
|
||||
|
||||
if (attributes[BuiltInAttributeKey.strikethrough] == true) {
|
||||
syntax += '~~';
|
||||
}
|
||||
if (attributes[BuiltInAttributeKey.underline] == true) {
|
||||
syntax += '<u>';
|
||||
}
|
||||
if (attributes[BuiltInAttributeKey.code] == true) {
|
||||
syntax += '`';
|
||||
}
|
||||
|
||||
if (attributes[BuiltInAttributeKey.href] != null) {
|
||||
syntax += '[';
|
||||
}
|
||||
|
||||
return syntax;
|
||||
}
|
||||
|
||||
String _suffixSyntax(Attributes attributes) {
|
||||
var syntax = '';
|
||||
|
||||
if (attributes[BuiltInAttributeKey.href] != null) {
|
||||
syntax += '](${attributes[BuiltInAttributeKey.href]})';
|
||||
}
|
||||
|
||||
if (attributes[BuiltInAttributeKey.code] == true) {
|
||||
syntax += '`';
|
||||
}
|
||||
|
||||
if (attributes[BuiltInAttributeKey.underline] == true) {
|
||||
syntax += '</u>';
|
||||
}
|
||||
|
||||
if (attributes[BuiltInAttributeKey.strikethrough] == true) {
|
||||
syntax += '~~';
|
||||
}
|
||||
|
||||
if (attributes[BuiltInAttributeKey.bold] == true &&
|
||||
attributes[BuiltInAttributeKey.italic] == true) {
|
||||
syntax += '***';
|
||||
} else if (attributes[BuiltInAttributeKey.bold] == true) {
|
||||
syntax += '**';
|
||||
} else if (attributes[BuiltInAttributeKey.italic] == true) {
|
||||
syntax += '_';
|
||||
}
|
||||
|
||||
return syntax;
|
||||
}
|
||||
}
|
@ -0,0 +1 @@
|
||||
|
@ -27,6 +27,7 @@ dependencies:
|
||||
intl:
|
||||
flutter_localizations:
|
||||
sdk: flutter
|
||||
markdown: ^6.0.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
@ -0,0 +1,100 @@
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() async {
|
||||
group('delta_markdown_encoder.dart', () {
|
||||
test('bold', () {
|
||||
final delta = Delta(operations: [
|
||||
TextInsert('Welcome to '),
|
||||
TextInsert('AppFlowy', attributes: {
|
||||
BuiltInAttributeKey.bold: true,
|
||||
}),
|
||||
]);
|
||||
final result = DeltaMarkdownEncoder().convert(delta);
|
||||
expect(result, 'Welcome to **AppFlowy**');
|
||||
});
|
||||
|
||||
test('italic', () {
|
||||
final delta = Delta(operations: [
|
||||
TextInsert('Welcome to '),
|
||||
TextInsert('AppFlowy', attributes: {
|
||||
BuiltInAttributeKey.italic: true,
|
||||
}),
|
||||
]);
|
||||
final result = DeltaMarkdownEncoder().convert(delta);
|
||||
expect(result, 'Welcome to _AppFlowy_');
|
||||
});
|
||||
|
||||
test('underline', () {
|
||||
final delta = Delta(operations: [
|
||||
TextInsert('Welcome to '),
|
||||
TextInsert('AppFlowy', attributes: {
|
||||
BuiltInAttributeKey.underline: true,
|
||||
}),
|
||||
]);
|
||||
final result = DeltaMarkdownEncoder().convert(delta);
|
||||
expect(result, 'Welcome to <u>AppFlowy</u>');
|
||||
});
|
||||
|
||||
test('strikethrough', () {
|
||||
final delta = Delta(operations: [
|
||||
TextInsert('Welcome to '),
|
||||
TextInsert('AppFlowy', attributes: {
|
||||
BuiltInAttributeKey.strikethrough: true,
|
||||
}),
|
||||
]);
|
||||
final result = DeltaMarkdownEncoder().convert(delta);
|
||||
expect(result, 'Welcome to ~~AppFlowy~~');
|
||||
});
|
||||
|
||||
test('href', () {
|
||||
final delta = Delta(operations: [
|
||||
TextInsert('Welcome to '),
|
||||
TextInsert('AppFlowy', attributes: {
|
||||
BuiltInAttributeKey.href: 'https://appflowy.io',
|
||||
}),
|
||||
]);
|
||||
final result = DeltaMarkdownEncoder().convert(delta);
|
||||
expect(result, 'Welcome to [AppFlowy](https://appflowy.io)');
|
||||
});
|
||||
|
||||
test('code', () {
|
||||
final delta = Delta(operations: [
|
||||
TextInsert('Welcome to '),
|
||||
TextInsert('AppFlowy', attributes: {
|
||||
BuiltInAttributeKey.code: true,
|
||||
}),
|
||||
]);
|
||||
final result = DeltaMarkdownEncoder().convert(delta);
|
||||
expect(result, 'Welcome to `AppFlowy`');
|
||||
});
|
||||
|
||||
test('composition', () {
|
||||
final delta = Delta(operations: [
|
||||
TextInsert('Welcome', attributes: {
|
||||
BuiltInAttributeKey.code: true,
|
||||
BuiltInAttributeKey.italic: true,
|
||||
BuiltInAttributeKey.bold: true,
|
||||
BuiltInAttributeKey.underline: true,
|
||||
}),
|
||||
TextInsert(' '),
|
||||
TextInsert('to', attributes: {
|
||||
BuiltInAttributeKey.italic: true,
|
||||
BuiltInAttributeKey.bold: true,
|
||||
BuiltInAttributeKey.strikethrough: true,
|
||||
}),
|
||||
TextInsert(' '),
|
||||
TextInsert('AppFlowy', attributes: {
|
||||
BuiltInAttributeKey.href: 'https://appflowy.io',
|
||||
BuiltInAttributeKey.bold: true,
|
||||
BuiltInAttributeKey.italic: true,
|
||||
}),
|
||||
]);
|
||||
final result = DeltaMarkdownEncoder().convert(delta);
|
||||
expect(
|
||||
result,
|
||||
'***<u>`Welcome`</u>*** ***~~to~~*** ***[AppFlowy](https://appflowy.io)***',
|
||||
);
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Reference in New Issue
Block a user