Skip to content

Commit 4d5063d

Browse files
fix: add a encoder for math, #1795 (#1803)
* fix: add a encoder for math, #1795 * feat: support customzie the node parser for exporting markdown * chore: fix flutter analyze --------- Co-authored-by: Lucas.Xu <[email protected]>
1 parent 8c0b8a8 commit 4d5063d

File tree

8 files changed

+113
-37
lines changed

8 files changed

+113
-37
lines changed

frontend/app_flowy/lib/plugins/document/application/share_bloc.dart

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import 'dart:convert';
22
import 'dart:io';
33
import 'package:app_flowy/plugins/document/application/share_service.dart';
4+
import 'package:app_flowy/plugins/document/presentation/plugins/parsers/divider_node_parser.dart';
5+
import 'package:app_flowy/plugins/document/presentation/plugins/parsers/math_equation_node_parser.dart';
46
import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart';
57
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
68
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
@@ -48,7 +50,10 @@ class DocShareBloc extends Bloc<DocShareEvent, DocShareState> {
4850
String _convertDocumentToMarkdown(ExportDataPB value) {
4951
final json = jsonDecode(value.data);
5052
final document = Document.fromJson(json);
51-
return documentToMarkdown(document);
53+
return documentToMarkdown(document, customParsers: [
54+
const DividerNodeParser(),
55+
const MathEquationNodeParser(),
56+
]);
5257
}
5358
}
5459

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
1-
import 'package:appflowy_editor/src/core/document/node.dart';
2-
import 'package:appflowy_editor/src/plugins/markdown/encoder/parser/node_parser.dart';
1+
import 'package:appflowy_editor/appflowy_editor.dart';
32

43
class DividerNodeParser extends NodeParser {
54
const DividerNodeParser();
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import 'package:appflowy_editor/appflowy_editor.dart';
2+
3+
class MathEquationNodeParser extends NodeParser {
4+
const MathEquationNodeParser();
5+
6+
@override
7+
String get id => 'math_equation';
8+
9+
@override
10+
String transform(Node node) {
11+
return '\$\$${node.attributes[id]}\$\$';
12+
}
13+
}

frontend/app_flowy/packages/appflowy_editor/lib/src/plugins/markdown/document_markdown.dart

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,45 @@ import 'dart:convert';
55
import 'package:appflowy_editor/src/core/document/document.dart';
66
import 'package:appflowy_editor/src/plugins/markdown/decoder/document_markdown_decoder.dart';
77
import 'package:appflowy_editor/src/plugins/markdown/encoder/document_markdown_encoder.dart';
8-
9-
/// Codec used to convert between Markdown and AppFlowy Editor Document.
10-
const AppFlowyEditorMarkdownCodec _kCodec = AppFlowyEditorMarkdownCodec();
11-
12-
Document markdownToDocument(String markdown) {
13-
return _kCodec.decode(markdown);
8+
import 'package:appflowy_editor/src/plugins/markdown/encoder/parser/image_node_parser.dart';
9+
import 'package:appflowy_editor/src/plugins/markdown/encoder/parser/node_parser.dart';
10+
import 'package:appflowy_editor/src/plugins/markdown/encoder/parser/text_node_parser.dart';
11+
12+
/// Converts a markdown to [Document].
13+
///
14+
/// [customParsers] is a list of custom parsers that will be used to parse the markdown.
15+
Document markdownToDocument(
16+
String markdown, {
17+
List<NodeParser> customParsers = const [],
18+
}) {
19+
return const AppFlowyEditorMarkdownCodec().decode(markdown);
1420
}
1521

16-
String documentToMarkdown(Document document) {
17-
return _kCodec.encode(document);
22+
/// Converts a [Document] to markdown.
23+
///
24+
/// [customParsers] is a list of custom parsers that will be used to parse the markdown.
25+
String documentToMarkdown(Document document,
26+
{List<NodeParser> customParsers = const []}) {
27+
return AppFlowyEditorMarkdownCodec(encodeParsers: [
28+
...customParsers,
29+
const TextNodeParser(),
30+
const ImageNodeParser(),
31+
]).encode(document);
1832
}
1933

2034
class AppFlowyEditorMarkdownCodec extends Codec<Document, String> {
21-
const AppFlowyEditorMarkdownCodec();
35+
const AppFlowyEditorMarkdownCodec({
36+
this.encodeParsers = const [],
37+
});
38+
39+
final List<NodeParser> encodeParsers;
2240

41+
// TODO: Add support for custom parsers
2342
@override
2443
Converter<String, Document> get decoder => DocumentMarkdownDecoder();
2544

2645
@override
27-
Converter<Document, String> get encoder => DocumentMarkdownEncoder();
46+
Converter<Document, String> get encoder => DocumentMarkdownEncoder(
47+
parsers: encodeParsers,
48+
);
2849
}

frontend/app_flowy/packages/appflowy_editor/lib/src/plugins/markdown/encoder/document_markdown_encoder.dart

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,11 @@
11
import 'dart:convert';
22

33
import 'package:appflowy_editor/src/core/document/document.dart';
4-
import 'package:appflowy_editor/src/plugins/markdown/encoder/parser/divider_node_parser.dart';
5-
import 'package:appflowy_editor/src/plugins/markdown/encoder/parser/image_node_parser.dart';
64
import 'package:appflowy_editor/src/plugins/markdown/encoder/parser/node_parser.dart';
7-
import 'package:appflowy_editor/src/plugins/markdown/encoder/parser/text_node_parser.dart';
85

96
class DocumentMarkdownEncoder extends Converter<Document, String> {
107
DocumentMarkdownEncoder({
11-
this.parsers = const [
12-
TextNodeParser(),
13-
ImageNodeParser(),
14-
DividerNodeParser(),
15-
],
8+
this.parsers = const [],
169
});
1710

1811
final List<NodeParser> parsers;

frontend/app_flowy/packages/appflowy_editor/test/plugins/markdown/encoder/document_markdown_encoder_test.dart

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,10 @@ void main() async {
114114
test('parser document', () async {
115115
final data = Map<String, Object>.from(json.decode(example));
116116
final document = Document.fromJson(data);
117-
final result = DocumentMarkdownEncoder().convert(document);
117+
final result = DocumentMarkdownEncoder(parsers: [
118+
const TextNodeParser(),
119+
const ImageNodeParser(),
120+
]).convert(document);
118121
expect(result, '''
119122
## 👋 **Welcome to** ***[AppFlowy Editor](appflowy.io)***
120123

frontend/app_flowy/packages/appflowy_editor/test/plugins/markdown/encoder/parser/divider_node_parser_test.dart

Lines changed: 0 additions & 15 deletions
This file was deleted.
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import 'dart:convert';
2+
3+
import 'package:app_flowy/plugins/document/presentation/plugins/parsers/divider_node_parser.dart';
4+
import 'package:app_flowy/plugins/document/presentation/plugins/parsers/math_equation_node_parser.dart';
5+
import 'package:appflowy_editor/appflowy_editor.dart';
6+
import 'package:flutter_test/flutter_test.dart';
7+
8+
void main() {
9+
group('share markdown', () {
10+
test('math equation', () {
11+
const text = '''
12+
{
13+
"document":{
14+
"type":"editor",
15+
"children":[
16+
{
17+
"type":"math_equation",
18+
"attributes":{
19+
"math_equation":"E = MC^2"
20+
}
21+
}
22+
]
23+
}
24+
}
25+
''';
26+
final document = Document.fromJson(
27+
Map<String, Object>.from(json.decode(text)),
28+
);
29+
final result = documentToMarkdown(document, customParsers: [
30+
const MathEquationNodeParser(),
31+
]);
32+
expect(result, r'$$E = MC^2$$');
33+
});
34+
35+
test('divider', () {
36+
const text = '''
37+
{
38+
"document":{
39+
"type":"editor",
40+
"children":[
41+
{
42+
"type":"divider"
43+
}
44+
]
45+
}
46+
}
47+
''';
48+
final document = Document.fromJson(
49+
Map<String, Object>.from(json.decode(text)),
50+
);
51+
final result = documentToMarkdown(document, customParsers: [
52+
const DividerNodeParser(),
53+
]);
54+
expect(result, '---\n');
55+
});
56+
});
57+
}

0 commit comments

Comments
 (0)