Showing
7 changed files
with
112 additions
and
10 deletions
| @@ -3,6 +3,8 @@ | @@ -3,6 +3,8 @@ | ||
| 3 | * `IndentMd` and `BlockQuote` fixed. | 3 | * `IndentMd` and `BlockQuote` fixed. |
| 4 | * Baseline of bloc type component is fixed. | 4 | * Baseline of bloc type component is fixed. |
| 5 | * block quote support improved. | 5 | * block quote support improved. |
| 6 | +* custom components support added. | ||
| 7 | +* `Table` syntax improved. | ||
| 6 | 8 | ||
| 7 | ## 1.0.15 | 9 | ## 1.0.15 |
| 8 | 10 |
| @@ -21,15 +21,16 @@ A comprehensive Flutter package for rendering rich Markdown and LaTeX content in | @@ -21,15 +21,16 @@ A comprehensive Flutter package for rendering rich Markdown and LaTeX content in | ||
| 21 | | ➖ Horizontal Line | ✅ | | | 21 | | ➖ Horizontal Line | ✅ | | |
| 22 | | 🔢 Latex Math | ✅ | | | 22 | | 🔢 Latex Math | ✅ | | |
| 23 | | ↩️ Indent | ✅ | | 23 | | ↩️ Indent | ✅ | |
| 24 | +| ↩️ BlockQuote | ✅ | | ||
| 24 | | 🖼️ Image | ✅ | | 25 | | 🖼️ Image | ✅ | |
| 25 | | ✨ Highlighted Text | ✅ | | 26 | | ✨ Highlighted Text | ✅ | |
| 26 | -| ✂️ Striked Text | ✅ | | 27 | +| ✂️ Strike Text | ✅ | |
| 27 | | 🔵 Bold Text | ✅ | | 28 | | 🔵 Bold Text | ✅ | |
| 28 | | 📜 Italic Text | ✅ | | 29 | | 📜 Italic Text | ✅ | |
| 29 | | 🔗 Links | ✅ | | 30 | | 🔗 Links | ✅ | |
| 30 | | 📱 Selectable | ✅ | | 31 | | 📱 Selectable | ✅ | |
| 32 | +| 🧩 Custom components | ✅ | | | ||
| 31 | | 📎 Underline | | 🔜 | | 33 | | 📎 Underline | | 🔜 | |
| 32 | -| 🧩 Custom components | | 🔜 | | ||
| 33 | 34 | ||
| 34 | ## ✨ Key Features | 35 | ## ✨ Key Features |
| 35 | 36 |
| @@ -586,6 +586,40 @@ This document was created to test the robustness of Markdown parsers and to ensu | @@ -586,6 +586,40 @@ This document was created to test the robustness of Markdown parsers and to ensu | ||
| 586 | ), | 586 | ), |
| 587 | ); | 587 | ); |
| 588 | }, | 588 | }, |
| 589 | + components: [ | ||
| 590 | + CodeBlockMd(), | ||
| 591 | + NewLines(), | ||
| 592 | + BlockQuote(), | ||
| 593 | + ImageMd(), | ||
| 594 | + ATagMd(), | ||
| 595 | + TableMd(), | ||
| 596 | + HTag(), | ||
| 597 | + UnOrderedList(), | ||
| 598 | + OrderedList(), | ||
| 599 | + RadioButtonMd(), | ||
| 600 | + CheckBoxMd(), | ||
| 601 | + HrLine(), | ||
| 602 | + StrikeMd(), | ||
| 603 | + BoldMd(), | ||
| 604 | + ItalicMd(), | ||
| 605 | + LatexMath(), | ||
| 606 | + LatexMathMultiLine(), | ||
| 607 | + HighlightedText(), | ||
| 608 | + SourceTag(), | ||
| 609 | + IndentMd(), | ||
| 610 | + ], | ||
| 611 | + inlineComponents: [ | ||
| 612 | + ImageMd(), | ||
| 613 | + ATagMd(), | ||
| 614 | + TableMd(), | ||
| 615 | + StrikeMd(), | ||
| 616 | + BoldMd(), | ||
| 617 | + ItalicMd(), | ||
| 618 | + LatexMath(), | ||
| 619 | + LatexMathMultiLine(), | ||
| 620 | + HighlightedText(), | ||
| 621 | + SourceTag(), | ||
| 622 | + ], | ||
| 589 | // codeBuilder: (context, name, code, closed) { | 623 | // codeBuilder: (context, name, code, closed) { |
| 590 | // return Padding( | 624 | // return Padding( |
| 591 | // padding: const EdgeInsets.symmetric( | 625 | // padding: const EdgeInsets.symmetric( |
| @@ -31,7 +31,7 @@ class BlockQuoteWidget extends StatelessWidget { | @@ -31,7 +31,7 @@ class BlockQuoteWidget extends StatelessWidget { | ||
| 31 | Widget build(BuildContext context) { | 31 | Widget build(BuildContext context) { |
| 32 | return Row( | 32 | return Row( |
| 33 | children: [ | 33 | children: [ |
| 34 | - Expanded( | 34 | + Flexible( |
| 35 | child: CustomPaint( | 35 | child: CustomPaint( |
| 36 | foregroundPainter: BlockQuotePainter(color, direction, width), | 36 | foregroundPainter: BlockQuotePainter(color, direction, width), |
| 37 | child: child, | 37 | child: child, |
| 1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
| 2 | +import 'package:gpt_markdown/gpt_markdown.dart'; | ||
| 2 | 3 | ||
| 3 | /// A builder function for the ordered list. | 4 | /// A builder function for the ordered list. |
| 4 | typedef OrderedListBuilder = | 5 | typedef OrderedListBuilder = |
| @@ -80,6 +81,8 @@ class GptMarkdownConfig { | @@ -80,6 +81,8 @@ class GptMarkdownConfig { | ||
| 80 | this.imageBuilder, | 81 | this.imageBuilder, |
| 81 | this.maxLines, | 82 | this.maxLines, |
| 82 | this.overflow, | 83 | this.overflow, |
| 84 | + this.components, | ||
| 85 | + this.inlineComponents, | ||
| 83 | }); | 86 | }); |
| 84 | 87 | ||
| 85 | /// The direction of the text. | 88 | /// The direction of the text. |
| @@ -133,6 +136,12 @@ class GptMarkdownConfig { | @@ -133,6 +136,12 @@ class GptMarkdownConfig { | ||
| 133 | /// The image builder. | 136 | /// The image builder. |
| 134 | final ImageBuilder? imageBuilder; | 137 | final ImageBuilder? imageBuilder; |
| 135 | 138 | ||
| 139 | + /// The list of components. | ||
| 140 | + final List<MarkdownComponent>? components; | ||
| 141 | + | ||
| 142 | + /// The list of inline components. | ||
| 143 | + final List<MarkdownComponent>? inlineComponents; | ||
| 144 | + | ||
| 136 | /// A copy of the configuration with the specified parameters. | 145 | /// A copy of the configuration with the specified parameters. |
| 137 | GptMarkdownConfig copyWith({ | 146 | GptMarkdownConfig copyWith({ |
| 138 | TextStyle? style, | 147 | TextStyle? style, |
| @@ -152,6 +161,8 @@ class GptMarkdownConfig { | @@ -152,6 +161,8 @@ class GptMarkdownConfig { | ||
| 152 | final ImageBuilder? imageBuilder, | 161 | final ImageBuilder? imageBuilder, |
| 153 | final OrderedListBuilder? orderedListBuilder, | 162 | final OrderedListBuilder? orderedListBuilder, |
| 154 | final UnOrderedListBuilder? unOrderedListBuilder, | 163 | final UnOrderedListBuilder? unOrderedListBuilder, |
| 164 | + final List<MarkdownComponent>? components, | ||
| 165 | + final List<MarkdownComponent>? inlineComponents, | ||
| 155 | }) { | 166 | }) { |
| 156 | return GptMarkdownConfig( | 167 | return GptMarkdownConfig( |
| 157 | style: style ?? this.style, | 168 | style: style ?? this.style, |
| @@ -171,6 +182,8 @@ class GptMarkdownConfig { | @@ -171,6 +182,8 @@ class GptMarkdownConfig { | ||
| 171 | imageBuilder: imageBuilder ?? this.imageBuilder, | 182 | imageBuilder: imageBuilder ?? this.imageBuilder, |
| 172 | orderedListBuilder: orderedListBuilder ?? this.orderedListBuilder, | 183 | orderedListBuilder: orderedListBuilder ?? this.orderedListBuilder, |
| 173 | unOrderedListBuilder: unOrderedListBuilder ?? this.unOrderedListBuilder, | 184 | unOrderedListBuilder: unOrderedListBuilder ?? this.unOrderedListBuilder, |
| 185 | + components: components ?? this.components, | ||
| 186 | + inlineComponents: inlineComponents ?? this.inlineComponents, | ||
| 174 | ); | 187 | ); |
| 175 | } | 188 | } |
| 176 | 189 |
| @@ -40,6 +40,8 @@ class GptMarkdown extends StatelessWidget { | @@ -40,6 +40,8 @@ class GptMarkdown extends StatelessWidget { | ||
| 40 | this.overflow, | 40 | this.overflow, |
| 41 | this.orderedListBuilder, | 41 | this.orderedListBuilder, |
| 42 | this.unOrderedListBuilder, | 42 | this.unOrderedListBuilder, |
| 43 | + this.components, | ||
| 44 | + this.inlineComponents, | ||
| 43 | }); | 45 | }); |
| 44 | 46 | ||
| 45 | /// The direction of the text. | 47 | /// The direction of the text. |
| @@ -94,6 +96,50 @@ class GptMarkdown extends StatelessWidget { | @@ -94,6 +96,50 @@ class GptMarkdown extends StatelessWidget { | ||
| 94 | /// The unordered list builder. | 96 | /// The unordered list builder. |
| 95 | final UnOrderedListBuilder? unOrderedListBuilder; | 97 | final UnOrderedListBuilder? unOrderedListBuilder; |
| 96 | 98 | ||
| 99 | + /// The list of components. | ||
| 100 | + /// ```dart | ||
| 101 | + /// List<MarkdownComponent> components = [ | ||
| 102 | + /// CodeBlockMd(), | ||
| 103 | + /// NewLines(), | ||
| 104 | + /// BlockQuote(), | ||
| 105 | + /// ImageMd(), | ||
| 106 | + /// ATagMd(), | ||
| 107 | + /// TableMd(), | ||
| 108 | + /// HTag(), | ||
| 109 | + /// UnOrderedList(), | ||
| 110 | + /// OrderedList(), | ||
| 111 | + /// RadioButtonMd(), | ||
| 112 | + /// CheckBoxMd(), | ||
| 113 | + /// HrLine(), | ||
| 114 | + /// StrikeMd(), | ||
| 115 | + /// BoldMd(), | ||
| 116 | + /// ItalicMd(), | ||
| 117 | + /// LatexMath(), | ||
| 118 | + /// LatexMathMultiLine(), | ||
| 119 | + /// HighlightedText(), | ||
| 120 | + /// SourceTag(), | ||
| 121 | + /// IndentMd(), | ||
| 122 | + /// ]; | ||
| 123 | + /// ``` | ||
| 124 | + final List<MarkdownComponent>? components; | ||
| 125 | + | ||
| 126 | + /// The list of inline components. | ||
| 127 | + /// ```dart | ||
| 128 | + /// List<MarkdownComponent> inlineComponents = [ | ||
| 129 | + /// ImageMd(), | ||
| 130 | + /// ATagMd(), | ||
| 131 | + /// TableMd(), | ||
| 132 | + /// StrikeMd(), | ||
| 133 | + /// BoldMd(), | ||
| 134 | + /// ItalicMd(), | ||
| 135 | + /// LatexMath(), | ||
| 136 | + /// LatexMathMultiLine(), | ||
| 137 | + /// HighlightedText(), | ||
| 138 | + /// SourceTag(), | ||
| 139 | + /// ]; | ||
| 140 | + /// ``` | ||
| 141 | + final List<MarkdownComponent>? inlineComponents; | ||
| 142 | + | ||
| 97 | /// A method to remove extra lines inside block LaTeX. | 143 | /// A method to remove extra lines inside block LaTeX. |
| 98 | // String _removeExtraLinesInsideBlockLatex(String text) { | 144 | // String _removeExtraLinesInsideBlockLatex(String text) { |
| 99 | // return text.replaceAllMapped( | 145 | // return text.replaceAllMapped( |
| @@ -147,6 +193,8 @@ class GptMarkdown extends StatelessWidget { | @@ -147,6 +193,8 @@ class GptMarkdown extends StatelessWidget { | ||
| 147 | imageBuilder: imageBuilder, | 193 | imageBuilder: imageBuilder, |
| 148 | orderedListBuilder: orderedListBuilder, | 194 | orderedListBuilder: orderedListBuilder, |
| 149 | unOrderedListBuilder: unOrderedListBuilder, | 195 | unOrderedListBuilder: unOrderedListBuilder, |
| 196 | + components: components, | ||
| 197 | + inlineComponents: inlineComponents, | ||
| 150 | ), | 198 | ), |
| 151 | ), | 199 | ), |
| 152 | ); | 200 | ); |
| @@ -2,7 +2,7 @@ part of 'gpt_markdown.dart'; | @@ -2,7 +2,7 @@ part of 'gpt_markdown.dart'; | ||
| 2 | 2 | ||
| 3 | /// Markdown components | 3 | /// Markdown components |
| 4 | abstract class MarkdownComponent { | 4 | abstract class MarkdownComponent { |
| 5 | - static List<MarkdownComponent> get components => [ | 5 | + static final List<MarkdownComponent> components = [ |
| 6 | CodeBlockMd(), | 6 | CodeBlockMd(), |
| 7 | NewLines(), | 7 | NewLines(), |
| 8 | BlockQuote(), | 8 | BlockQuote(), |
| @@ -25,7 +25,7 @@ abstract class MarkdownComponent { | @@ -25,7 +25,7 @@ abstract class MarkdownComponent { | ||
| 25 | IndentMd(), | 25 | IndentMd(), |
| 26 | ]; | 26 | ]; |
| 27 | 27 | ||
| 28 | - static List<MarkdownComponent> get inlineComponents => [ | 28 | + static final List<MarkdownComponent> inlineComponents = [ |
| 29 | ImageMd(), | 29 | ImageMd(), |
| 30 | ATagMd(), | 30 | ATagMd(), |
| 31 | TableMd(), | 31 | TableMd(), |
| @@ -47,8 +47,8 @@ abstract class MarkdownComponent { | @@ -47,8 +47,8 @@ abstract class MarkdownComponent { | ||
| 47 | ) { | 47 | ) { |
| 48 | var components = | 48 | var components = |
| 49 | includeGlobalComponents | 49 | includeGlobalComponents |
| 50 | - ? MarkdownComponent.components | ||
| 51 | - : MarkdownComponent.inlineComponents; | 50 | + ? config.components ?? MarkdownComponent.components |
| 51 | + : config.inlineComponents ?? MarkdownComponent.inlineComponents; | ||
| 52 | List<InlineSpan> spans = []; | 52 | List<InlineSpan> spans = []; |
| 53 | Iterable<String> regexes = components.map<String>((e) => e.exp.pattern); | 53 | Iterable<String> regexes = components.map<String>((e) => e.exp.pattern); |
| 54 | final combinedRegex = RegExp( | 54 | final combinedRegex = RegExp( |
| @@ -134,7 +134,7 @@ abstract class BlockMd extends MarkdownComponent { | @@ -134,7 +134,7 @@ abstract class BlockMd extends MarkdownComponent { | ||
| 134 | child: child, | 134 | child: child, |
| 135 | ); | 135 | ); |
| 136 | } | 136 | } |
| 137 | - child = Row(children: [Expanded(child: child)]); | 137 | + child = Row(children: [Flexible(child: child)]); |
| 138 | return WidgetSpan( | 138 | return WidgetSpan( |
| 139 | child: child, | 139 | child: child, |
| 140 | alignment: PlaceholderAlignment.baseline, | 140 | alignment: PlaceholderAlignment.baseline, |
| @@ -165,7 +165,7 @@ class IndentMd extends BlockMd { | @@ -165,7 +165,7 @@ class IndentMd extends BlockMd { | ||
| 165 | textDirection: config.textDirection, | 165 | textDirection: config.textDirection, |
| 166 | child: Row( | 166 | child: Row( |
| 167 | children: [ | 167 | children: [ |
| 168 | - Expanded( | 168 | + Flexible( |
| 169 | child: config.getRich( | 169 | child: config.getRich( |
| 170 | TextSpan( | 170 | TextSpan( |
| 171 | children: MarkdownComponent.generate( | 171 | children: MarkdownComponent.generate( |
| @@ -322,7 +322,11 @@ class BlockQuote extends InlineMd { | @@ -322,7 +322,11 @@ class BlockQuote extends InlineMd { | ||
| 322 | @override | 322 | @override |
| 323 | RegExp get exp => | 323 | RegExp get exp => |
| 324 | // RegExp(r"(?<=\n\n)(\ +)(.+?)(?=\n\n)", dotAll: true, multiLine: true); | 324 | // RegExp(r"(?<=\n\n)(\ +)(.+?)(?=\n\n)", dotAll: true, multiLine: true); |
| 325 | - RegExp(r"(?:(?:^|\n)\ *>[^\n]+)+", dotAll: true, multiLine: true); | 325 | + RegExp( |
| 326 | + r"(?:(?:^)\ *>[^\n]+)(?:(?:\n)\ *>[^\n]+)*", | ||
| 327 | + dotAll: true, | ||
| 328 | + multiLine: true, | ||
| 329 | + ); | ||
| 326 | 330 | ||
| 327 | @override | 331 | @override |
| 328 | InlineSpan span( | 332 | InlineSpan span( |
-
Please register or login to post a comment