Skip to content

Commit

Permalink
feat: Add support for strike-through text for flame_markdown
Browse files Browse the repository at this point in the history
  • Loading branch information
luanpotter committed Dec 29, 2024
1 parent 3067da9 commit 2509490
Show file tree
Hide file tree
Showing 9 changed files with 97 additions and 3 deletions.
1 change: 1 addition & 0 deletions .github/.cspell/words_dictionary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ rebalance
refreshable
renderable
rescan
strikethrough # of a text with a horizontal line across
tappable
tappables
toolset
Expand Down
35 changes: 35 additions & 0 deletions packages/flame/lib/src/text/nodes/strikethrough_text_node.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import 'dart:ui';

import 'package:flame/src/text/nodes/inline_text_node.dart';
import 'package:flame/text.dart';

/// An [InlineTextNode] representing a text with a strikethrough line.
///
/// The exact styling can be controlled by the `strikethroughText` property
/// on the document style.
class StrikethroughTextNode extends InlineTextNode {
StrikethroughTextNode(this.child);

StrikethroughTextNode.simple(String text) : child = PlainTextNode(text);

StrikethroughTextNode.group(List<InlineTextNode> children)
: child = GroupTextNode(children);

final InlineTextNode child;

static final defaultStyle = InlineTextStyle(
decoration: TextDecoration.lineThrough,
);

@override
void fillStyles(DocumentStyle stylesheet, InlineTextStyle parentTextStyle) {
style = FlameTextStyle.merge(
parentTextStyle,
stylesheet.strikethroughText,
)!;
child.fillStyles(stylesheet, style);
}

@override
TextNodeLayoutBuilder get layoutBuilder => child.layoutBuilder;
}
11 changes: 11 additions & 0 deletions packages/flame/lib/src/text/styles/document_style.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class DocumentStyle extends FlameTextStyle {
InlineTextStyle? boldText,
InlineTextStyle? italicText,
InlineTextStyle? codeText,
InlineTextStyle? strikethroughText,
BlockStyle? paragraph,
BlockStyle? header1,
BlockStyle? header2,
Expand All @@ -33,6 +34,10 @@ class DocumentStyle extends FlameTextStyle {
_italicText =
FlameTextStyle.merge(ItalicTextNode.defaultStyle, italicText),
_codeText = FlameTextStyle.merge(CodeTextNode.defaultStyle, codeText),
_strikethroughText = FlameTextStyle.merge(
StrikethroughTextNode.defaultStyle,
strikethroughText,
),
_paragraph =
FlameTextStyle.merge(ParagraphNode.defaultStyle, paragraph),
_header1 = FlameTextStyle.merge(HeaderNode.defaultStyleH1, header1),
Expand All @@ -46,6 +51,7 @@ class DocumentStyle extends FlameTextStyle {
final InlineTextStyle? _boldText;
final InlineTextStyle? _italicText;
final InlineTextStyle? _codeText;
final InlineTextStyle? _strikethroughText;
final BlockStyle? _paragraph;
final BlockStyle? _header1;
final BlockStyle? _header2;
Expand Down Expand Up @@ -98,6 +104,7 @@ class DocumentStyle extends FlameTextStyle {
InlineTextStyle get boldText => _boldText!;
InlineTextStyle get italicText => _italicText!;
InlineTextStyle get codeText => _codeText!;
InlineTextStyle get strikethroughText => _strikethroughText!;

/// Style for [ParagraphNode]s.
BlockStyle get paragraph => _paragraph!;
Expand All @@ -122,6 +129,10 @@ class DocumentStyle extends FlameTextStyle {
boldText: FlameTextStyle.merge(_boldText, other.boldText),
italicText: FlameTextStyle.merge(_italicText, other.italicText),
codeText: FlameTextStyle.merge(_codeText, other.codeText),
strikethroughText: FlameTextStyle.merge(
_strikethroughText,
other.strikethroughText,
),
background: merge(background, other.background) as BackgroundStyle?,
paragraph: merge(paragraph, other.paragraph) as BlockStyle?,
header1: merge(header1, other.header1) as BlockStyle?,
Expand Down
1 change: 1 addition & 0 deletions packages/flame/lib/text.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export 'src/text/nodes/inline_text_node.dart' show InlineTextNode;
export 'src/text/nodes/italic_text_node.dart' show ItalicTextNode;
export 'src/text/nodes/paragraph_node.dart' show ParagraphNode;
export 'src/text/nodes/plain_text_node.dart' show PlainTextNode;
export 'src/text/nodes/strikethrough_text_node.dart' show StrikethroughTextNode;
export 'src/text/nodes/text_block_node.dart' show TextBlockNode;
export 'src/text/nodes/text_node.dart' show TextNode;
export 'src/text/renderers/sprite_font_renderer.dart' show SpriteFontRenderer;
Expand Down
2 changes: 1 addition & 1 deletion packages/flame_markdown/example/assets/fire_and_ice.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Fire & Ice

Some say the world will end in **fire**,
Some say the world will ~~end~~ in **fire**,

Some say in *ice*.

Expand Down
11 changes: 10 additions & 1 deletion packages/flame_markdown/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import 'package:flame/game.dart';
import 'package:flame/text.dart';
import 'package:flame_markdown/flame_markdown.dart';
import 'package:flutter/widgets.dart' hide Animation;
import 'package:markdown/markdown.dart';

void main() {
runApp(GameWidget(game: MarkdownGame()));
Expand All @@ -19,7 +20,15 @@ class MarkdownGame extends FlameGame {
final markdown = await Flame.assets.readFile('fire_and_ice.md');
await add(
TextElementComponent.fromDocument(
document: FlameMarkdown.toDocument(markdown),
document: FlameMarkdown.toDocument(
markdown,
document: Document(
encodeHtml: false,
inlineSyntaxes: [
StrikethroughSyntax(),
],
),
),
style: DocumentStyle(
padding: const EdgeInsets.all(16),
),
Expand Down
1 change: 1 addition & 0 deletions packages/flame_markdown/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ dependencies:
flame_markdown: ^0.2.2+3
flutter:
sdk: flutter
markdown: ^7.1.1

dev_dependencies:
flame_lint: ^1.2.1
Expand Down
1 change: 1 addition & 0 deletions packages/flame_markdown/lib/flame_markdown.dart
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class FlameMarkdown {
'em' || 'i' => ItalicTextNode(child),
'strong' || 'b' => BoldTextNode(child),
'code' => CodeTextNode(child),
'del' => StrikethroughTextNode(child),
_ => throw Exception('Unknown element tag: ${element.tag}'),
} as TextNode;
}
Expand Down
37 changes: 36 additions & 1 deletion packages/flame_markdown/test/flame_markdown_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:io';
import 'package:flame/text.dart';
import 'package:flame_markdown/flame_markdown.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:markdown/markdown.dart';

void main() {
group('FlameMarkdown#toDocument', () {
Expand Down Expand Up @@ -71,7 +72,11 @@ void main() {
(node) => _expectHeader(node, 1, 'Fire & Ice'),
(node) => _expectParagraph(node, (p) {
_expectGroup(p, [
(node) => _expectPlain(node, 'Some say the world will end in '),
(node) => _expectPlain(
node,
// note: strike-trough is only parsed if enabled
'Some say the world will ~~end~~ in ',
),
(node) => _expectBold(node, 'fire'),
(node) => _expectPlain(node, ','),
]);
Expand All @@ -97,9 +102,39 @@ void main() {
}),
]);
});

test('strikethrough can be enabled', () {
const markdown = 'Flame ~~will be~~ is a great game engine!';
final doc = FlameMarkdown.toDocument(
markdown,
document: Document(
encodeHtml: false,
inlineSyntaxes: [
StrikethroughSyntax(),
],
),
);

_expectDocument(doc, [
(node) => _expectParagraph(node, (p) {
_expectGroup(p, [
(node) => _expectPlain(node, 'Flame '),
(node) => _expectStrikethrough(node, 'will be'),
(node) => _expectPlain(node, ' is a great game engine!'),
]);
}),
]);
});
});
}

void _expectStrikethrough(InlineTextNode node, String text) {
expect(node, isA<StrikethroughTextNode>());
final content = (node as StrikethroughTextNode).child;
expect(content, isA<PlainTextNode>());
expect((content as PlainTextNode).text, text);
}

void _expectBold(InlineTextNode node, String text) {
expect(node, isA<BoldTextNode>());
final content = (node as BoldTextNode).child;
Expand Down

0 comments on commit 2509490

Please sign in to comment.