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 <lucas.xu@appflowy.io>
This commit is contained in:
huang12zheng 2023-02-06 15:38:49 +08:00 committed by GitHub
parent 8c0b8a875c
commit 4d5063de6a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 112 additions and 36 deletions

View File

@ -1,6 +1,8 @@
import 'dart:convert';
import 'dart:io';
import 'package:app_flowy/plugins/document/application/share_service.dart';
import 'package:app_flowy/plugins/document/presentation/plugins/parsers/divider_node_parser.dart';
import 'package:app_flowy/plugins/document/presentation/plugins/parsers/math_equation_node_parser.dart';
import 'package:appflowy_backend/protobuf/flowy-document/entities.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-folder/view.pb.dart';
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
@ -48,7 +50,10 @@ class DocShareBloc extends Bloc<DocShareEvent, DocShareState> {
String _convertDocumentToMarkdown(ExportDataPB value) {
final json = jsonDecode(value.data);
final document = Document.fromJson(json);
return documentToMarkdown(document);
return documentToMarkdown(document, customParsers: [
const DividerNodeParser(),
const MathEquationNodeParser(),
]);
}
}

View File

@ -1,5 +1,4 @@
import 'package:appflowy_editor/src/core/document/node.dart';
import 'package:appflowy_editor/src/plugins/markdown/encoder/parser/node_parser.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
class DividerNodeParser extends NodeParser {
const DividerNodeParser();

View File

@ -0,0 +1,13 @@
import 'package:appflowy_editor/appflowy_editor.dart';
class MathEquationNodeParser extends NodeParser {
const MathEquationNodeParser();
@override
String get id => 'math_equation';
@override
String transform(Node node) {
return '\$\$${node.attributes[id]}\$\$';
}
}

View File

@ -5,24 +5,45 @@ import 'dart:convert';
import 'package:appflowy_editor/src/core/document/document.dart';
import 'package:appflowy_editor/src/plugins/markdown/decoder/document_markdown_decoder.dart';
import 'package:appflowy_editor/src/plugins/markdown/encoder/document_markdown_encoder.dart';
import 'package:appflowy_editor/src/plugins/markdown/encoder/parser/image_node_parser.dart';
import 'package:appflowy_editor/src/plugins/markdown/encoder/parser/node_parser.dart';
import 'package:appflowy_editor/src/plugins/markdown/encoder/parser/text_node_parser.dart';
/// Codec used to convert between Markdown and AppFlowy Editor Document.
const AppFlowyEditorMarkdownCodec _kCodec = AppFlowyEditorMarkdownCodec();
Document markdownToDocument(String markdown) {
return _kCodec.decode(markdown);
/// Converts a markdown to [Document].
///
/// [customParsers] is a list of custom parsers that will be used to parse the markdown.
Document markdownToDocument(
String markdown, {
List<NodeParser> customParsers = const [],
}) {
return const AppFlowyEditorMarkdownCodec().decode(markdown);
}
String documentToMarkdown(Document document) {
return _kCodec.encode(document);
/// Converts a [Document] to markdown.
///
/// [customParsers] is a list of custom parsers that will be used to parse the markdown.
String documentToMarkdown(Document document,
{List<NodeParser> customParsers = const []}) {
return AppFlowyEditorMarkdownCodec(encodeParsers: [
...customParsers,
const TextNodeParser(),
const ImageNodeParser(),
]).encode(document);
}
class AppFlowyEditorMarkdownCodec extends Codec<Document, String> {
const AppFlowyEditorMarkdownCodec();
const AppFlowyEditorMarkdownCodec({
this.encodeParsers = const [],
});
final List<NodeParser> encodeParsers;
// TODO: Add support for custom parsers
@override
Converter<String, Document> get decoder => DocumentMarkdownDecoder();
@override
Converter<Document, String> get encoder => DocumentMarkdownEncoder();
Converter<Document, String> get encoder => DocumentMarkdownEncoder(
parsers: encodeParsers,
);
}

View File

@ -1,18 +1,11 @@
import 'dart:convert';
import 'package:appflowy_editor/src/core/document/document.dart';
import 'package:appflowy_editor/src/plugins/markdown/encoder/parser/divider_node_parser.dart';
import 'package:appflowy_editor/src/plugins/markdown/encoder/parser/image_node_parser.dart';
import 'package:appflowy_editor/src/plugins/markdown/encoder/parser/node_parser.dart';
import 'package:appflowy_editor/src/plugins/markdown/encoder/parser/text_node_parser.dart';
class DocumentMarkdownEncoder extends Converter<Document, String> {
DocumentMarkdownEncoder({
this.parsers = const [
TextNodeParser(),
ImageNodeParser(),
DividerNodeParser(),
],
this.parsers = const [],
});
final List<NodeParser> parsers;

View File

@ -114,7 +114,10 @@ void main() async {
test('parser document', () async {
final data = Map<String, Object>.from(json.decode(example));
final document = Document.fromJson(data);
final result = DocumentMarkdownEncoder().convert(document);
final result = DocumentMarkdownEncoder(parsers: [
const TextNodeParser(),
const ImageNodeParser(),
]).convert(document);
expect(result, '''
## 👋 **Welcome to** ***[AppFlowy Editor](appflowy.io)***

View File

@ -1,15 +0,0 @@
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:appflowy_editor/src/plugins/markdown/encoder/parser/divider_node_parser.dart';
import 'package:flutter_test/flutter_test.dart';
void main() async {
group('divider_node_parser.dart', () {
test('parser divider node', () {
final node = Node(
type: 'divider',
);
final result = const DividerNodeParser().transform(node);
expect(result, '---\n');
});
});
}

View File

@ -0,0 +1,57 @@
import 'dart:convert';
import 'package:app_flowy/plugins/document/presentation/plugins/parsers/divider_node_parser.dart';
import 'package:app_flowy/plugins/document/presentation/plugins/parsers/math_equation_node_parser.dart';
import 'package:appflowy_editor/appflowy_editor.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('share markdown', () {
test('math equation', () {
const text = '''
{
"document":{
"type":"editor",
"children":[
{
"type":"math_equation",
"attributes":{
"math_equation":"E = MC^2"
}
}
]
}
}
''';
final document = Document.fromJson(
Map<String, Object>.from(json.decode(text)),
);
final result = documentToMarkdown(document, customParsers: [
const MathEquationNodeParser(),
]);
expect(result, r'$$E = MC^2$$');
});
test('divider', () {
const text = '''
{
"document":{
"type":"editor",
"children":[
{
"type":"divider"
}
]
}
}
''';
final document = Document.fromJson(
Map<String, Object>.from(json.decode(text)),
);
final result = documentToMarkdown(document, customParsers: [
const DividerNodeParser(),
]);
expect(result, '---\n');
});
});
}