diff --git a/packages/flutter_markdown/CHANGELOG.md b/packages/flutter_markdown/CHANGELOG.md index 36ff215e015f..b550b9a29fdb 100644 --- a/packages/flutter_markdown/CHANGELOG.md +++ b/packages/flutter_markdown/CHANGELOG.md @@ -1,3 +1,9 @@ +## 0.7.1 + +* Allows for choosing a custom font feature to create superscript in footnotes when the font does not support the `supr` font feature. + * Use the `superscriptFontFeatureTag` property in `MarkdownStyleSheet`. + * For example, for the `Roboto` font which doesn't support `supr`, you can set `numr`. + ## 0.7.0 * **BREAKING CHANGES**: diff --git a/packages/flutter_markdown/lib/src/builder.dart b/packages/flutter_markdown/lib/src/builder.dart index 7bd96b90dfc9..b89ef2e70354 100644 --- a/packages/flutter_markdown/lib/src/builder.dart +++ b/packages/flutter_markdown/lib/src/builder.dart @@ -537,6 +537,8 @@ class MarkdownBuilder implements md.NodeVisitor { style: textSpan.style?.copyWith( fontFeatures: [ const FontFeature.enable('sups'), + if (styleSheet.superscriptFontFeatureTag != null) + FontFeature.enable(styleSheet.superscriptFontFeatureTag!), ], ), ), diff --git a/packages/flutter_markdown/lib/src/style_sheet.dart b/packages/flutter_markdown/lib/src/style_sheet.dart index 7fc16d9881e0..f3b570aeb914 100644 --- a/packages/flutter_markdown/lib/src/style_sheet.dart +++ b/packages/flutter_markdown/lib/src/style_sheet.dart @@ -59,6 +59,7 @@ class MarkdownStyleSheet { this.orderedListAlign = WrapAlignment.start, this.blockquoteAlign = WrapAlignment.start, this.codeblockAlign = WrapAlignment.start, + this.superscriptFontFeatureTag, @Deprecated('Use textScaler instead.') this.textScaleFactor, TextScaler? textScaler, }) : assert( @@ -391,6 +392,7 @@ class MarkdownStyleSheet { WrapAlignment? orderedListAlign, WrapAlignment? blockquoteAlign, WrapAlignment? codeblockAlign, + String? superscriptFontFeatureTag, @Deprecated('Use textScaler instead.') double? textScaleFactor, TextScaler? textScaler, }) { @@ -457,6 +459,8 @@ class MarkdownStyleSheet { orderedListAlign: orderedListAlign ?? this.orderedListAlign, blockquoteAlign: blockquoteAlign ?? this.blockquoteAlign, codeblockAlign: codeblockAlign ?? this.codeblockAlign, + superscriptFontFeatureTag: + superscriptFontFeatureTag ?? this.superscriptFontFeatureTag, textScaler: newTextScaler, textScaleFactor: nextTextScaleFactor, ); @@ -520,6 +524,7 @@ class MarkdownStyleSheet { blockquoteAlign: other.blockquoteAlign, codeblockAlign: other.codeblockAlign, textScaleFactor: other.textScaleFactor, + superscriptFontFeatureTag: other.superscriptFontFeatureTag, // Only one of textScaler and textScaleFactor can be passed. If // other.textScaleFactor is non-null, then the sheet was created with a // textScaleFactor and the textScaler was derived from that, so should be @@ -688,6 +693,10 @@ class MarkdownStyleSheet { @Deprecated('Use textScaler instead.') final double? textScaleFactor; + /// Custom font feature tag for font which does not support `sups' + /// feature to create superscript in footnotes. + final String? superscriptFontFeatureTag; + /// A [Map] from element name to the corresponding [TextStyle] object. Map get styles => _styles; Map _styles; @@ -752,6 +761,7 @@ class MarkdownStyleSheet { other.orderedListAlign == orderedListAlign && other.blockquoteAlign == blockquoteAlign && other.codeblockAlign == codeblockAlign && + other.superscriptFontFeatureTag == superscriptFontFeatureTag && other.textScaler == textScaler; } @@ -811,6 +821,7 @@ class MarkdownStyleSheet { codeblockAlign, textScaler, textScaleFactor, + superscriptFontFeatureTag, ]); } } diff --git a/packages/flutter_markdown/pubspec.yaml b/packages/flutter_markdown/pubspec.yaml index b5e2c9456223..04d24132024a 100644 --- a/packages/flutter_markdown/pubspec.yaml +++ b/packages/flutter_markdown/pubspec.yaml @@ -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.7.0 +version: 0.7.1 environment: sdk: ^3.3.0 diff --git a/packages/flutter_markdown/test/footnote_test.dart b/packages/flutter_markdown/test/footnote_test.dart index 191c2cb62002..3be96c46093d 100644 --- a/packages/flutter_markdown/test/footnote_test.dart +++ b/packages/flutter_markdown/test/footnote_test.dart @@ -158,7 +158,7 @@ void defineTests() { 'superscript textstyle replacing', () { testWidgets( - 'superscript has correct fontfeature', + 'superscript has correct default fontfeature', (WidgetTester tester) async { const String data = 'Foo[^a]\n[^a]: Bar'; await tester.pumpWidget( @@ -184,6 +184,35 @@ void defineTests() { }, ); + testWidgets( + 'superscript has correct custom fontfeature', + (WidgetTester tester) async { + const String data = 'Foo[^a]\n[^a]: Bar'; + await tester.pumpWidget( + boilerplate( + MarkdownBody( + data: data, + styleSheet: + MarkdownStyleSheet(superscriptFontFeatureTag: 'numr'), + ), + ), + ); + + final Iterable widgets = tester.allWidgets; + final Text text = + widgets.firstWhere((Widget widget) => widget is Text) as Text; + + final TextSpan span = text.textSpan! as TextSpan; + final List? children = span.children; + + expect(children, isNotNull); + expect(children!.length, 2); + expect(children[1].style, isNotNull); + expect(children[1].style!.fontFeatures?.length, 2); + expect(children[1].style!.fontFeatures?[1].feature, 'numr'); + }, + ); + testWidgets( 'superscript index has the same font style like text', (WidgetTester tester) async {