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) ...lightEditorStyleExtension,
|
||||||
if (!darkMode) ...lightPlguinStyleExtension,
|
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(
|
return Container(
|
||||||
color: darkMode ? Colors.black : Colors.white,
|
color: darkMode ? Colors.black : Colors.white,
|
||||||
width: MediaQuery.of(context).size.width,
|
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/l10n/l10n.dart';
|
||||||
export 'src/render/style/plugin_styles.dart';
|
export 'src/render/style/plugin_styles.dart';
|
||||||
export 'src/render/style/editor_style.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:
|
intl:
|
||||||
flutter_localizations:
|
flutter_localizations:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
markdown: ^6.0.1
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
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