[flutter_markdown] add padding for p, h1-h6 (#465)
diff --git a/packages/flutter_markdown/CHANGELOG.md b/packages/flutter_markdown/CHANGELOG.md
index 484fb46..6a6a568 100644
--- a/packages/flutter_markdown/CHANGELOG.md
+++ b/packages/flutter_markdown/CHANGELOG.md
@@ -1,6 +1,8 @@
-## NEXT
+## 0.6.7
-* Fix `unnecessary_import` lint errors.
+ * Fix `unnecessary_import` lint errors.
+ * Added option pPadding
+ * Added options h1Padding - h6Padding
## 0.6.6
diff --git a/packages/flutter_markdown/example/lib/demos/wrap_alignment_demo.dart b/packages/flutter_markdown/example/lib/demos/wrap_alignment_demo.dart
index f1a086e..74faa29 100644
--- a/packages/flutter_markdown/example/lib/demos/wrap_alignment_demo.dart
+++ b/packages/flutter_markdown/example/lib/demos/wrap_alignment_demo.dart
@@ -109,12 +109,19 @@
MarkdownStyleSheet.fromTheme(Theme.of(context)).copyWith(
blockSpacing: _blockSpacing,
textAlign: _wrapAlignment,
+ pPadding: const EdgeInsets.only(bottom: 4.0),
h1Align: _wrapAlignment,
+ h1Padding: const EdgeInsets.only(left: 4.0),
h2Align: _wrapAlignment,
+ h2Padding: const EdgeInsets.only(left: 8.0),
h3Align: _wrapAlignment,
+ h3Padding: const EdgeInsets.only(left: 12.0),
h4Align: _wrapAlignment,
+ h4Padding: const EdgeInsets.only(left: 16.0),
h5Align: _wrapAlignment,
+ h5Padding: const EdgeInsets.only(left: 20.0),
h6Align: _wrapAlignment,
+ h6Padding: const EdgeInsets.only(left: 24.0),
unorderedListAlign: _wrapAlignment,
orderedListAlign: _wrapAlignment,
blockquoteAlign: _wrapAlignment,
diff --git a/packages/flutter_markdown/lib/src/builder.dart b/packages/flutter_markdown/lib/src/builder.dart
index dfa53e6..a9be31f 100644
--- a/packages/flutter_markdown/lib/src/builder.dart
+++ b/packages/flutter_markdown/lib/src/builder.dart
@@ -598,9 +598,11 @@
WrapAlignment blockAlignment = WrapAlignment.start;
TextAlign textAlign = TextAlign.start;
+ EdgeInsets textPadding = EdgeInsets.zero;
if (_isBlockTag(_currentBlockTag)) {
blockAlignment = _wrapAlignmentForBlockTag(_currentBlockTag);
textAlign = _textAlignForBlockTag(_currentBlockTag);
+ textPadding = _textPaddingForBlockTag(_currentBlockTag);
}
final _InlineElement inline = _inlines.single;
@@ -614,7 +616,14 @@
children: mergedInlines,
alignment: blockAlignment,
);
- _addBlockChild(wrap);
+
+ if (textPadding == EdgeInsets.zero) {
+ _addBlockChild(wrap);
+ } else {
+ final Padding padding = Padding(padding: textPadding, child: wrap);
+ _addBlockChild(padding);
+ }
+
_inlines.clear();
}
}
@@ -722,6 +731,26 @@
return WrapAlignment.start;
}
+ EdgeInsets _textPaddingForBlockTag(String? blockTag) {
+ switch (blockTag) {
+ case 'p':
+ return styleSheet.pPadding!;
+ case 'h1':
+ return styleSheet.h1Padding!;
+ case 'h2':
+ return styleSheet.h2Padding!;
+ case 'h3':
+ return styleSheet.h3Padding!;
+ case 'h4':
+ return styleSheet.h4Padding!;
+ case 'h5':
+ return styleSheet.h5Padding!;
+ case 'h6':
+ return styleSheet.h6Padding!;
+ }
+ return EdgeInsets.zero;
+ }
+
/// Combine text spans with equivalent properties into a single span.
TextSpan? _mergeSimilarTextSpans(List<TextSpan>? textSpans) {
if (textSpans == null || textSpans.length < 2) {
diff --git a/packages/flutter_markdown/lib/src/style_sheet.dart b/packages/flutter_markdown/lib/src/style_sheet.dart
index 8916779..d25780b 100644
--- a/packages/flutter_markdown/lib/src/style_sheet.dart
+++ b/packages/flutter_markdown/lib/src/style_sheet.dart
@@ -11,13 +11,20 @@
MarkdownStyleSheet({
this.a,
this.p,
+ this.pPadding,
this.code,
this.h1,
+ this.h1Padding,
this.h2,
+ this.h2Padding,
this.h3,
+ this.h3Padding,
this.h4,
+ this.h4Padding,
this.h5,
+ this.h5Padding,
this.h6,
+ this.h6Padding,
this.em,
this.strong,
this.del,
@@ -81,17 +88,24 @@
return MarkdownStyleSheet(
a: const TextStyle(color: Colors.blue),
p: theme.textTheme.bodyText2,
+ pPadding: EdgeInsets.zero,
code: theme.textTheme.bodyText2!.copyWith(
backgroundColor: theme.cardTheme.color ?? theme.cardColor,
fontFamily: 'monospace',
fontSize: theme.textTheme.bodyText2!.fontSize! * 0.85,
),
h1: theme.textTheme.headline5,
+ h1Padding: EdgeInsets.zero,
h2: theme.textTheme.headline6,
+ h2Padding: EdgeInsets.zero,
h3: theme.textTheme.subtitle1,
+ h3Padding: EdgeInsets.zero,
h4: theme.textTheme.bodyText1,
+ h4Padding: EdgeInsets.zero,
h5: theme.textTheme.bodyText1,
+ h5Padding: EdgeInsets.zero,
h6: theme.textTheme.bodyText1,
+ h6Padding: EdgeInsets.zero,
em: const TextStyle(fontStyle: FontStyle.italic),
strong: const TextStyle(fontWeight: FontWeight.bold),
del: const TextStyle(decoration: TextDecoration.lineThrough),
@@ -145,6 +159,7 @@
: CupertinoColors.link.color,
),
p: theme.textTheme.textStyle,
+ pPadding: EdgeInsets.zero,
code: theme.textTheme.textStyle.copyWith(
backgroundColor: theme.brightness == Brightness.dark
? CupertinoColors.systemGrey6.darkColor
@@ -156,25 +171,31 @@
fontWeight: FontWeight.w500,
fontSize: theme.textTheme.textStyle.fontSize! + 10,
),
+ h1Padding: EdgeInsets.zero,
h2: theme.textTheme.textStyle.copyWith(
fontWeight: FontWeight.w500,
fontSize: theme.textTheme.textStyle.fontSize! + 8,
),
+ h2Padding: EdgeInsets.zero,
h3: theme.textTheme.textStyle.copyWith(
fontWeight: FontWeight.w500,
fontSize: theme.textTheme.textStyle.fontSize! + 6,
),
+ h3Padding: EdgeInsets.zero,
h4: theme.textTheme.textStyle.copyWith(
fontWeight: FontWeight.w500,
fontSize: theme.textTheme.textStyle.fontSize! + 4,
),
+ h4Padding: EdgeInsets.zero,
h5: theme.textTheme.textStyle.copyWith(
fontWeight: FontWeight.w500,
fontSize: theme.textTheme.textStyle.fontSize! + 2,
),
+ h5Padding: EdgeInsets.zero,
h6: theme.textTheme.textStyle.copyWith(
fontWeight: FontWeight.w500,
),
+ h6Padding: EdgeInsets.zero,
em: theme.textTheme.textStyle.copyWith(
fontStyle: FontStyle.italic,
),
@@ -247,17 +268,24 @@
return MarkdownStyleSheet(
a: const TextStyle(color: Colors.blue),
p: theme.textTheme.bodyText2,
+ pPadding: EdgeInsets.zero,
code: theme.textTheme.bodyText2!.copyWith(
backgroundColor: theme.cardTheme.color ?? theme.cardColor,
fontFamily: 'monospace',
fontSize: theme.textTheme.bodyText2!.fontSize! * 0.85,
),
h1: theme.textTheme.headline2,
+ h1Padding: EdgeInsets.zero,
h2: theme.textTheme.headline3,
+ h2Padding: EdgeInsets.zero,
h3: theme.textTheme.headline4,
+ h3Padding: EdgeInsets.zero,
h4: theme.textTheme.headline5,
+ h4Padding: EdgeInsets.zero,
h5: theme.textTheme.headline6,
+ h5Padding: EdgeInsets.zero,
h6: theme.textTheme.subtitle1,
+ h6Padding: EdgeInsets.zero,
em: const TextStyle(fontStyle: FontStyle.italic),
strong: const TextStyle(fontWeight: FontWeight.bold),
del: const TextStyle(decoration: TextDecoration.lineThrough),
@@ -305,13 +333,20 @@
MarkdownStyleSheet copyWith({
TextStyle? a,
TextStyle? p,
+ EdgeInsets? pPadding,
TextStyle? code,
TextStyle? h1,
+ EdgeInsets? h1Padding,
TextStyle? h2,
+ EdgeInsets? h2Padding,
TextStyle? h3,
+ EdgeInsets? h3Padding,
TextStyle? h4,
+ EdgeInsets? h4Padding,
TextStyle? h5,
+ EdgeInsets? h5Padding,
TextStyle? h6,
+ EdgeInsets? h6Padding,
TextStyle? em,
TextStyle? strong,
TextStyle? del,
@@ -350,13 +385,20 @@
return MarkdownStyleSheet(
a: a ?? this.a,
p: p ?? this.p,
+ pPadding: pPadding ?? this.pPadding,
code: code ?? this.code,
h1: h1 ?? this.h1,
+ h1Padding: h1Padding ?? this.h1Padding,
h2: h2 ?? this.h2,
+ h2Padding: h2Padding ?? this.h2Padding,
h3: h3 ?? this.h3,
+ h3Padding: h3Padding ?? this.h3Padding,
h4: h4 ?? this.h4,
+ h4Padding: h4Padding ?? this.h4Padding,
h5: h5 ?? this.h5,
+ h5Padding: h5Padding ?? this.h5Padding,
h6: h6 ?? this.h6,
+ h6Padding: h6Padding ?? this.h6Padding,
em: em ?? this.em,
strong: strong ?? this.strong,
del: del ?? this.del,
@@ -404,13 +446,20 @@
return copyWith(
a: a!.merge(other.a),
p: p!.merge(other.p),
+ pPadding: other.pPadding,
code: code!.merge(other.code),
h1: h1!.merge(other.h1),
+ h1Padding: other.h1Padding,
h2: h2!.merge(other.h2),
+ h2Padding: other.h2Padding,
h3: h3!.merge(other.h3),
+ h3Padding: other.h3Padding,
h4: h4!.merge(other.h4),
+ h4Padding: other.h4Padding,
h5: h5!.merge(other.h5),
+ h5Padding: other.h5Padding,
h6: h6!.merge(other.h6),
+ h6Padding: other.h6Padding,
em: em!.merge(other.em),
strong: strong!.merge(other.strong),
del: del!.merge(other.del),
@@ -454,27 +503,48 @@
/// The [TextStyle] to use for `p` elements.
final TextStyle? p;
+ /// The padding to use for `p` elements.
+ final EdgeInsets? pPadding;
+
/// The [TextStyle] to use for `code` elements.
final TextStyle? code;
/// The [TextStyle] to use for `h1` elements.
final TextStyle? h1;
+ /// The padding to use for `h1` elements.
+ final EdgeInsets? h1Padding;
+
/// The [TextStyle] to use for `h2` elements.
final TextStyle? h2;
+ /// The padding to use for `h2` elements.
+ final EdgeInsets? h2Padding;
+
/// The [TextStyle] to use for `h3` elements.
final TextStyle? h3;
+ /// The padding to use for `h3` elements.
+ final EdgeInsets? h3Padding;
+
/// The [TextStyle] to use for `h4` elements.
final TextStyle? h4;
+ /// The padding to use for `h4` elements.
+ final EdgeInsets? h4Padding;
+
/// The [TextStyle] to use for `h5` elements.
final TextStyle? h5;
+ /// The padding to use for `h5` elements.
+ final EdgeInsets? h5Padding;
+
/// The [TextStyle] to use for `h6` elements.
final TextStyle? h6;
+ /// The padding to use for `h6` elements.
+ final EdgeInsets? h6Padding;
+
/// The [TextStyle] to use for `em` elements.
final TextStyle? em;
@@ -593,13 +663,20 @@
final MarkdownStyleSheet typedOther = other;
return typedOther.a == a &&
typedOther.p == p &&
+ typedOther.pPadding == pPadding &&
typedOther.code == code &&
typedOther.h1 == h1 &&
+ typedOther.h1Padding == h1Padding &&
typedOther.h2 == h2 &&
+ typedOther.h2Padding == h2Padding &&
typedOther.h3 == h3 &&
+ typedOther.h3Padding == h3Padding &&
typedOther.h4 == h4 &&
+ typedOther.h4Padding == h4Padding &&
typedOther.h5 == h5 &&
+ typedOther.h5Padding == h5Padding &&
typedOther.h6 == h6 &&
+ typedOther.h6Padding == h6Padding &&
typedOther.em == em &&
typedOther.strong == strong &&
typedOther.del == del &&
@@ -642,13 +719,20 @@
return hashList(<Object?>[
a,
p,
+ pPadding,
code,
h1,
+ h1Padding,
h2,
+ h2Padding,
h3,
+ h3Padding,
h4,
+ h4Padding,
h5,
+ h5Padding,
h6,
+ h6Padding,
em,
strong,
del,
diff --git a/packages/flutter_markdown/pubspec.yaml b/packages/flutter_markdown/pubspec.yaml
index 51a8b84..0ce150c 100644
--- a/packages/flutter_markdown/pubspec.yaml
+++ b/packages/flutter_markdown/pubspec.yaml
@@ -4,7 +4,7 @@
formatted with simple Markdown tags.
repository: https://github.com/flutter/packages/tree/master/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.6
+version: 0.6.7
environment:
sdk: ">=2.12.0 <3.0.0"
diff --git a/packages/flutter_markdown/test/style_sheet_test.dart b/packages/flutter_markdown/test/style_sheet_test.dart
index 3738362..349e8e6 100644
--- a/packages/flutter_markdown/test/style_sheet_test.dart
+++ b/packages/flutter_markdown/test/style_sheet_test.dart
@@ -302,5 +302,98 @@
);
},
);
+
+ testWidgets(
+ 'check widgets for use stylesheet option h1Padding',
+ (WidgetTester tester) async {
+ const String data = '# Header';
+ const double paddingX = 20.0;
+ final MarkdownStyleSheet style = MarkdownStyleSheet(
+ h1Padding: const EdgeInsets.symmetric(horizontal: paddingX),
+ );
+
+ await tester.pumpWidget(boilerplate(MarkdownBody(
+ data: data,
+ styleSheet: style,
+ )));
+
+ final Iterable<Widget> widgets = tester.allWidgets;
+ expectWidgetTypes(widgets, <Type>[
+ Directionality,
+ MarkdownBody,
+ Column,
+ Padding,
+ Wrap,
+ RichText,
+ ]);
+ expectTextStrings(widgets, <String>['Header']);
+ },
+ );
+
+ testWidgets(
+ 'use stylesheet option pPadding',
+ (WidgetTester tester) async {
+ const double paddingX = 20.0;
+ final MarkdownStyleSheet style = MarkdownStyleSheet(
+ pPadding: const EdgeInsets.symmetric(horizontal: paddingX),
+ );
+
+ await tester.pumpWidget(
+ boilerplate(
+ Markdown(
+ data: 'Test line 1\n\nTest line 2\n\nTest line 3\n# H1',
+ styleSheet: style,
+ ),
+ ),
+ );
+
+ final List<Padding> paddings =
+ tester.widgetList<Padding>(find.byType(Padding)).toList();
+
+ expect(paddings.length, 3);
+ expect(
+ paddings.every(
+ (Padding p) => p.padding.along(Axis.horizontal) == paddingX * 2,
+ ),
+ true,
+ );
+ },
+ );
+
+ testWidgets(
+ 'use stylesheet option h1Padding-h6Padding',
+ (WidgetTester tester) async {
+ const double paddingX = 20.0;
+ final MarkdownStyleSheet style = MarkdownStyleSheet(
+ h1Padding: const EdgeInsets.symmetric(horizontal: paddingX),
+ h2Padding: const EdgeInsets.symmetric(horizontal: paddingX),
+ h3Padding: const EdgeInsets.symmetric(horizontal: paddingX),
+ h4Padding: const EdgeInsets.symmetric(horizontal: paddingX),
+ h5Padding: const EdgeInsets.symmetric(horizontal: paddingX),
+ h6Padding: const EdgeInsets.symmetric(horizontal: paddingX),
+ );
+
+ await tester.pumpWidget(
+ boilerplate(
+ Markdown(
+ data:
+ 'Test\n\n# H1\n## H2\n### H3\n#### H4\n##### H5\n###### H6\n',
+ styleSheet: style,
+ ),
+ ),
+ );
+
+ final List<Padding> paddings =
+ tester.widgetList<Padding>(find.byType(Padding)).toList();
+
+ expect(paddings.length, 6);
+ expect(
+ paddings.every(
+ (Padding p) => p.padding.along(Axis.horizontal) == paddingX * 2,
+ ),
+ true,
+ );
+ },
+ );
});
}