Skip to content

Commit

Permalink
[flutter_markdown] Allow for custom block element (#5815)
Browse files Browse the repository at this point in the history
Fixes problem with adding custom block syntax.

Issue: flutter/flutter#135848
  • Loading branch information
dawidope committed Mar 19, 2024
1 parent da16269 commit bb247f7
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 2 deletions.
5 changes: 5 additions & 0 deletions packages/flutter_markdown/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
## 0.6.22

* Introduces a new `MarkdownElementBuilder.isBlockElement()` method to specify if custom element
is a block.

## 0.6.21+1

* Adds `onSelectionChanged` to the constructors of `Markdown` and `MarkdownBody`.
Expand Down
8 changes: 7 additions & 1 deletion packages/flutter_markdown/lib/src/builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import '_functions_io.dart' if (dart.library.js_interop) '_functions_web.dart';
import 'style_sheet.dart';
import 'widget.dart';

const List<String> _kBlockTags = <String>[
final List<String> _kBlockTags = <String>[
'p',
'h1',
'h2',
Expand Down Expand Up @@ -190,6 +190,12 @@ class MarkdownBuilder implements md.NodeVisitor {
_linkHandlers.clear();
_isInBlockquote = false;

builders.forEach((String key, MarkdownElementBuilder value) {
if (value.isBlockElement()) {
_kBlockTags.add(key);
}
});

_blocks.add(_BlockElement(null));

for (final md.Node node in nodes) {
Expand Down
5 changes: 5 additions & 0 deletions packages/flutter_markdown/lib/src/widget.dart
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ abstract class SyntaxHighlighter {

/// An interface for an element builder.
abstract class MarkdownElementBuilder {
/// For block syntax has to return true.
///
/// By default returns false.
bool isBlockElement() => false;

/// Called when an Element has been reached, before its children have been
/// visited.
void visitElementBefore(md.Element element) {}
Expand Down
2 changes: 1 addition & 1 deletion packages/flutter_markdown/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ description: A Markdown renderer for Flutter. Create rich text output,
formatted with simple Markdown tags.
repository: https://github.com/flutter/packages/tree/main/packages/flutter_markdown
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+flutter_markdown%22
version: 0.6.21+1
version: 0.6.22

environment:
sdk: ^3.3.0
Expand Down
49 changes: 49 additions & 0 deletions packages/flutter_markdown/test/custom_syntax_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,30 @@ void defineTests() {
},
);

testWidgets(
'Custom block element',
(WidgetTester tester) async {
const String blockContent = 'note block';
await tester.pumpWidget(
boilerplate(
Markdown(
data: '[!NOTE] $blockContent',
extensionSet: md.ExtensionSet.none,
blockSyntaxes: <md.BlockSyntax>[NoteSyntax()],
builders: <String, MarkdownElementBuilder>{
'note': NoteBuilder(),
},
),
),
);
final ColoredBox container =
tester.widgetList(find.byType(ColoredBox)).first as ColoredBox;
expect(container.color, Colors.red);
expect(container.child, isInstanceOf<Text>());
expect((container.child! as Text).data, blockContent);
},
);

testWidgets(
'link for wikistyle',
(WidgetTester tester) async {
Expand Down Expand Up @@ -331,3 +355,28 @@ class ImgBuilder extends MarkdownElementBuilder {
return Text('foo', style: preferredStyle);
}
}

class NoteBuilder extends MarkdownElementBuilder {
@override
Widget? visitText(md.Text text, TextStyle? preferredStyle) {
return ColoredBox(
color: Colors.red, child: Text(text.text, style: preferredStyle));
}

@override
bool isBlockElement() {
return true;
}
}

class NoteSyntax extends md.BlockSyntax {
@override
md.Node? parse(md.BlockParser parser) {
final md.Line line = parser.current;
parser.advance();
return md.Element('note', <md.Node>[md.Text(line.content.substring(8))]);
}

@override
RegExp get pattern => RegExp(r'^\[!NOTE] ');
}

0 comments on commit bb247f7

Please sign in to comment.