diff --git a/examples/lib/stories/rendering/rich_text_example.dart b/examples/lib/stories/rendering/rich_text_example.dart index a6ce405d7d3..b05c5a13707 100644 --- a/examples/lib/stories/rendering/rich_text_example.dart +++ b/examples/lib/stories/rendering/rich_text_example.dart @@ -58,14 +58,24 @@ class RichTextExample extends FlameGame { PlainTextNode('."'), ]), ]), - ParagraphNode.simple( - 'He pushed the thought under instantly. The fallacy was obvious. It ' - 'presupposed that somewhere or other, outside oneself, there was a ' - '"real" world where "real" things happened. But how could there be ' - 'such a world? What knowledge have we of anything, save through our ' - 'own minds? All happenings are in the mind. Whatever happens in all ' - 'minds, truly happens.', - ), + ParagraphNode.group([ + PlainTextNode( + 'He pushed the thought under instantly. The fallacy was obvious. It ' + 'presupposed that somewhere or other, outside oneself, there was a ' + '"', + ), + CodeTextNode.simple('real'), + PlainTextNode( + '" world where "', + ), + CodeTextNode.simple('real'), + PlainTextNode( + '" things happened. But how could there be ' + 'such a world? What knowledge have we of anything, save through our ' + 'own minds? All happenings are in the mind. Whatever happens in all ' + 'minds, truly happens.', + ), + ]), ]); add( diff --git a/packages/flame/lib/src/text/nodes/code_text_node.dart b/packages/flame/lib/src/text/nodes/code_text_node.dart new file mode 100644 index 00000000000..6e53c5e1514 --- /dev/null +++ b/packages/flame/lib/src/text/nodes/code_text_node.dart @@ -0,0 +1,24 @@ +import 'package:flame/src/text/nodes/inline_text_node.dart'; +import 'package:flame/text.dart'; + +class CodeTextNode extends InlineTextNode { + CodeTextNode(this.child); + + CodeTextNode.simple(String text) : child = PlainTextNode(text); + + CodeTextNode.group(List children) + : child = GroupTextNode(children); + + final InlineTextNode child; + + static final defaultStyle = InlineTextStyle(fontFamily: 'monospace'); + + @override + void fillStyles(DocumentStyle stylesheet, InlineTextStyle parentTextStyle) { + style = FlameTextStyle.merge(parentTextStyle, stylesheet.codeText)!; + child.fillStyles(stylesheet, style); + } + + @override + TextNodeLayoutBuilder get layoutBuilder => child.layoutBuilder; +} diff --git a/packages/flame/lib/src/text/styles/document_style.dart b/packages/flame/lib/src/text/styles/document_style.dart index 786cd60b582..bf0a274f1cc 100644 --- a/packages/flame/lib/src/text/styles/document_style.dart +++ b/packages/flame/lib/src/text/styles/document_style.dart @@ -20,6 +20,7 @@ class DocumentStyle extends FlameTextStyle { InlineTextStyle? text, InlineTextStyle? boldText, InlineTextStyle? italicText, + InlineTextStyle? codeText, BlockStyle? paragraph, BlockStyle? header1, BlockStyle? header2, @@ -31,6 +32,7 @@ class DocumentStyle extends FlameTextStyle { _boldText = FlameTextStyle.merge(BoldTextNode.defaultStyle, boldText), _italicText = FlameTextStyle.merge(ItalicTextNode.defaultStyle, italicText), + _codeText = FlameTextStyle.merge(CodeTextNode.defaultStyle, codeText), _paragraph = FlameTextStyle.merge(ParagraphNode.defaultStyle, paragraph), _header1 = FlameTextStyle.merge(HeaderNode.defaultStyleH1, header1), @@ -43,6 +45,7 @@ class DocumentStyle extends FlameTextStyle { final InlineTextStyle? _text; final InlineTextStyle? _boldText; final InlineTextStyle? _italicText; + final InlineTextStyle? _codeText; final BlockStyle? _paragraph; final BlockStyle? _header1; final BlockStyle? _header2; @@ -94,6 +97,7 @@ class DocumentStyle extends FlameTextStyle { InlineTextStyle get text => _text!; InlineTextStyle get boldText => _boldText!; InlineTextStyle get italicText => _italicText!; + InlineTextStyle get codeText => _codeText!; /// Style for [ParagraphNode]s. BlockStyle get paragraph => _paragraph!; @@ -117,6 +121,7 @@ class DocumentStyle extends FlameTextStyle { text: FlameTextStyle.merge(_text, other.text), boldText: FlameTextStyle.merge(_boldText, other.boldText), italicText: FlameTextStyle.merge(_italicText, other.italicText), + codeText: FlameTextStyle.merge(_codeText, other.codeText), background: merge(background, other.background) as BackgroundStyle?, paragraph: merge(paragraph, other.paragraph) as BlockStyle?, header1: merge(header1, other.header1) as BlockStyle?, diff --git a/packages/flame/lib/text.dart b/packages/flame/lib/text.dart index 537b246c9da..ad08ebefde4 100644 --- a/packages/flame/lib/text.dart +++ b/packages/flame/lib/text.dart @@ -14,6 +14,7 @@ export 'src/text/elements/text_painter_text_element.dart' show TextPainterTextElement; export 'src/text/nodes/block_node.dart' show BlockNode; export 'src/text/nodes/bold_text_node.dart' show BoldTextNode; +export 'src/text/nodes/code_text_node.dart' show CodeTextNode; export 'src/text/nodes/column_node.dart' show ColumnNode; export 'src/text/nodes/document_root.dart' show DocumentRoot; export 'src/text/nodes/group_text_node.dart' show GroupTextNode; diff --git a/packages/flame_markdown/lib/flame_markdown.dart b/packages/flame_markdown/lib/flame_markdown.dart index 3d1310f546f..426853faf37 100644 --- a/packages/flame_markdown/lib/flame_markdown.dart +++ b/packages/flame_markdown/lib/flame_markdown.dart @@ -55,6 +55,7 @@ class FlameMarkdown { 'p' => ParagraphNode(child), 'em' || 'i' => ItalicTextNode(child), 'strong' || 'b' => BoldTextNode(child), + 'code' => CodeTextNode(child), _ => throw Exception('Unknown element tag: ${element.tag}'), } as TextNode; } diff --git a/packages/flame_markdown/test/flame_markdown_test.dart b/packages/flame_markdown/test/flame_markdown_test.dart index 18075f8a8da..656bb5fdd82 100644 --- a/packages/flame_markdown/test/flame_markdown_test.dart +++ b/packages/flame_markdown/test/flame_markdown_test.dart @@ -29,6 +29,19 @@ void main() { ]); }); + test('inline code block', () { + final doc = FlameMarkdown.toDocument('Flame: `var game = FlameGame();`'); + + _expectDocument(doc, [ + (node) => _expectParagraph(node, (p) { + _expectGroup(p, [ + (node) => _expectPlain(node, 'Flame: '), + (node) => _expectCode(node, 'var game = FlameGame();'), + ]); + }), + ]); + }); + test('all header levels', () { final doc = FlameMarkdown.toDocument( '# h1\n' @@ -107,6 +120,13 @@ void _expectPlain(InlineTextNode node, String text) { expect(span.text, text); } +void _expectCode(InlineTextNode node, String text) { + expect(node, isA()); + final content = (node as CodeTextNode).child; + expect(content, isA()); + expect((content as PlainTextNode).text, text); +} + void _expectParagraph( BlockNode node, void Function(InlineTextNode) expectChild,