mirror of
https://github.com/AppFlowy-IO/AppFlowy.git
synced 2024-08-30 18:12:39 +00:00
feat: add toggle list and callout node parser (#3700)
This commit is contained in:
parent
aa70885b21
commit
7406c5e6a5
@ -4,6 +4,7 @@ import 'package:appflowy/plugins/document/presentation/share/share_button.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:integration_test/integration_test.dart';
|
||||
import 'package:path/path.dart' as p;
|
||||
|
||||
import 'util/mock/mock_file_picker.dart';
|
||||
import 'util/util.dart';
|
||||
|
||||
@ -78,7 +79,7 @@ void main() {
|
||||
});
|
||||
}
|
||||
|
||||
const expectedMarkdown = r'''
|
||||
const expectedMarkdown = '''
|
||||
# Welcome to AppFlowy!
|
||||
## Here are the basics
|
||||
- [ ] Click anywhere and just start typing.
|
||||
@ -105,6 +106,15 @@ fn main() {
|
||||
## Have a question❓
|
||||
> Click `?` at the bottom right for help and support.
|
||||
|
||||
> 🥰
|
||||
>
|
||||
> Like AppFlowy? Follow us:
|
||||
> [GitHub](https://github.com/AppFlowy-IO/AppFlowy)
|
||||
> [Twitter](https://twitter.com/appflowy): @appflowy
|
||||
> [Newsletter](https://blog-appflowy.ghost.io/)
|
||||
>
|
||||
|
||||
|
||||
|
||||
|
||||
''';
|
||||
|
@ -0,0 +1,27 @@
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
|
||||
class CalloutNodeParser extends NodeParser {
|
||||
const CalloutNodeParser();
|
||||
|
||||
@override
|
||||
String get id => CalloutBlockKeys.type;
|
||||
|
||||
@override
|
||||
String transform(Node node, DocumentMarkdownEncoder? encoder) {
|
||||
assert(node.children.isEmpty);
|
||||
final icon = node.attributes[CalloutBlockKeys.icon];
|
||||
final delta = node.delta ?? Delta()
|
||||
..insert('');
|
||||
final String markdown = DeltaMarkdownEncoder()
|
||||
.convert(delta)
|
||||
.split('\n')
|
||||
.map((e) => '> $e')
|
||||
.join('\n');
|
||||
return '''
|
||||
> $icon
|
||||
$markdown
|
||||
|
||||
''';
|
||||
}
|
||||
}
|
@ -7,7 +7,7 @@ class CodeBlockNodeParser extends NodeParser {
|
||||
String get id => 'code_block';
|
||||
|
||||
@override
|
||||
String transform(Node node) {
|
||||
String transform(Node node, DocumentMarkdownEncoder? encoder) {
|
||||
return '```\n${node.attributes['code_block']}\n```';
|
||||
}
|
||||
}
|
||||
|
@ -7,7 +7,7 @@ class DividerNodeParser extends NodeParser {
|
||||
String get id => 'divider';
|
||||
|
||||
@override
|
||||
String transform(Node node) {
|
||||
String transform(Node node, DocumentMarkdownEncoder? encoder) {
|
||||
return '---\n';
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,5 @@
|
||||
export 'callout_node_parser.dart';
|
||||
export 'code_block_node_parser.dart';
|
||||
export 'divider_node_parser.dart';
|
||||
export 'math_equation_node_parser.dart';
|
||||
export 'toggle_list_node_parser.dart';
|
@ -0,0 +1,5 @@
|
||||
export 'callout_node_parser.dart';
|
||||
export 'code_block_node_parser.dart';
|
||||
export 'divider_node_parser.dart';
|
||||
export 'math_equation_node_parser.dart';
|
||||
export 'toggle_list_node_parser.dart';
|
@ -8,7 +8,7 @@ class MathEquationNodeParser extends NodeParser {
|
||||
String get id => MathEquationBlockKeys.type;
|
||||
|
||||
@override
|
||||
String transform(Node node) {
|
||||
String transform(Node node, DocumentMarkdownEncoder? encoder) {
|
||||
return '\$\$${node.attributes[id]}\$\$';
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,44 @@
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/plugins.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
|
||||
enum ToggleListExportStyle {
|
||||
github,
|
||||
markdown,
|
||||
}
|
||||
|
||||
class ToggleListNodeParser extends NodeParser {
|
||||
const ToggleListNodeParser({
|
||||
this.exportStyle = ToggleListExportStyle.markdown,
|
||||
});
|
||||
|
||||
final ToggleListExportStyle exportStyle;
|
||||
|
||||
@override
|
||||
String get id => ToggleListBlockKeys.type;
|
||||
|
||||
@override
|
||||
String transform(Node node, DocumentMarkdownEncoder? encoder) {
|
||||
final delta = node.delta ?? Delta()
|
||||
..insert('');
|
||||
String markdown = DeltaMarkdownEncoder().convert(delta);
|
||||
final details = encoder?.convertNodes(
|
||||
node.children,
|
||||
withIndent: true,
|
||||
);
|
||||
switch (exportStyle) {
|
||||
case ToggleListExportStyle.github:
|
||||
return '''<details>
|
||||
<summary>$markdown</summary>
|
||||
|
||||
$details
|
||||
</details>
|
||||
''';
|
||||
case ToggleListExportStyle.markdown:
|
||||
markdown = '- $markdown\n';
|
||||
if (details != null && details.isNotEmpty) {
|
||||
markdown += details;
|
||||
}
|
||||
return markdown;
|
||||
}
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ export 'openai/widgets/auto_completion_node_widget.dart';
|
||||
export 'openai/widgets/smart_edit_node_widget.dart';
|
||||
export 'openai/widgets/smart_edit_toolbar_item.dart';
|
||||
export 'outline/outline_block_component.dart';
|
||||
export 'parsers/markdown_parsers.dart';
|
||||
export 'table/table_menu.dart';
|
||||
export 'table/table_option_action.dart';
|
||||
export 'toggle/toggle_block_component.dart';
|
||||
|
@ -3,15 +3,21 @@ import 'dart:convert';
|
||||
import 'package:appflowy/generated/locale_keys.g.dart';
|
||||
import 'package:appflowy/plugins/document/application/document_data_pb_extension.dart';
|
||||
import 'package:appflowy/plugins/document/application/prelude.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/parsers/code_block_node_parser.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/parsers/divider_node_parser.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/parsers/math_equation_node_parser.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/parsers/markdown_parsers.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-error/errors.pb.dart';
|
||||
import 'package:appflowy_backend/protobuf/flowy-folder2/view.pb.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:dartz/dartz.dart';
|
||||
import 'package:easy_localization/easy_localization.dart';
|
||||
|
||||
const List<NodeParser> _customParsers = [
|
||||
DividerNodeParser(),
|
||||
MathEquationNodeParser(),
|
||||
CodeBlockNodeParser(),
|
||||
CalloutNodeParser(),
|
||||
ToggleListNodeParser(),
|
||||
];
|
||||
|
||||
enum DocumentExportType {
|
||||
json,
|
||||
markdown,
|
||||
@ -43,11 +49,7 @@ class DocumentExporter {
|
||||
case DocumentExportType.markdown:
|
||||
final markdown = documentToMarkdown(
|
||||
document,
|
||||
customParsers: [
|
||||
const DividerNodeParser(),
|
||||
const MathEquationNodeParser(),
|
||||
const CodeBlockNodeParser(),
|
||||
],
|
||||
customParsers: _customParsers,
|
||||
);
|
||||
return right(markdown);
|
||||
case DocumentExportType.text:
|
||||
|
@ -54,8 +54,8 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: "."
|
||||
ref: d1027c4
|
||||
resolved-ref: d1027c4d83a8cf78227e7d742c050ca945cef23a
|
||||
ref: "9ae85ea"
|
||||
resolved-ref: "9ae85ea162606b79483c49550266c154c0cb500c"
|
||||
url: "https://github.com/AppFlowy-IO/appflowy-editor.git"
|
||||
source: git
|
||||
version: "1.4.4"
|
||||
|
@ -47,7 +47,7 @@ dependencies:
|
||||
appflowy_editor:
|
||||
git:
|
||||
url: https://github.com/AppFlowy-IO/appflowy-editor.git
|
||||
ref: "d1027c4"
|
||||
ref: "9ae85ea"
|
||||
appflowy_popover:
|
||||
path: packages/appflowy_popover
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/parsers/code_block_node_parser.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/parsers/divider_node_parser.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/parsers/math_equation_node_parser.dart';
|
||||
import 'package:appflowy/plugins/document/presentation/editor_plugins/parsers/document_markdown_parsers.dart';
|
||||
import 'package:appflowy_editor/appflowy_editor.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
@ -35,7 +33,7 @@ void main() {
|
||||
);
|
||||
expect(result, r'$$E = MC^2$$');
|
||||
});
|
||||
// Changes
|
||||
|
||||
test('code block', () {
|
||||
const text = '''
|
||||
{
|
||||
@ -63,6 +61,7 @@ void main() {
|
||||
);
|
||||
expect(result, '```\nSome Code\n```');
|
||||
});
|
||||
|
||||
test('divider', () {
|
||||
const text = '''
|
||||
{
|
||||
@ -87,5 +86,73 @@ void main() {
|
||||
);
|
||||
expect(result, '---\n');
|
||||
});
|
||||
|
||||
test('callout', () {
|
||||
const text = '''
|
||||
{
|
||||
"document":{
|
||||
"type":"page",
|
||||
"children":[
|
||||
{
|
||||
"type":"callout",
|
||||
"data":{
|
||||
"icon": "😁",
|
||||
"delta": [
|
||||
{
|
||||
"insert": "Callout"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
''';
|
||||
final document = Document.fromJson(
|
||||
Map<String, Object>.from(json.decode(text)),
|
||||
);
|
||||
final result = documentToMarkdown(
|
||||
document,
|
||||
customParsers: [
|
||||
const CalloutNodeParser(),
|
||||
],
|
||||
);
|
||||
expect(result, '''> 😁
|
||||
> Callout
|
||||
|
||||
''');
|
||||
});
|
||||
|
||||
test('toggle list', () {
|
||||
const text = '''
|
||||
{
|
||||
"document":{
|
||||
"type":"page",
|
||||
"children":[
|
||||
{
|
||||
"type":"toggle_list",
|
||||
"data":{
|
||||
"delta": [
|
||||
{
|
||||
"insert": "Toggle list"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
''';
|
||||
final document = Document.fromJson(
|
||||
Map<String, Object>.from(json.decode(text)),
|
||||
);
|
||||
final result = documentToMarkdown(
|
||||
document,
|
||||
customParsers: [
|
||||
const ToggleListNodeParser(),
|
||||
],
|
||||
);
|
||||
expect(result, '- Toggle list\n');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user