saminsohag

`IndentMd` and `BlockQuote` fixed.

  1 +## 1.0.16
  2 +
  3 +* `IndentMd` and `BlockQuote` fixed.
  4 +
1 ## 1.0.15 5 ## 1.0.15
2 6
3 * Performance improvements. 7 * Performance improvements.
@@ -126,7 +126,7 @@ packages: @@ -126,7 +126,7 @@ packages:
126 path: ".." 126 path: ".."
127 relative: true 127 relative: true
128 source: path 128 source: path
129 - version: "1.0.9" 129 + version: "1.0.15"
130 http: 130 http:
131 dependency: transitive 131 dependency: transitive
132 description: 132 description:
@@ -2,12 +2,12 @@ import 'package:flutter/material.dart'; @@ -2,12 +2,12 @@ import 'package:flutter/material.dart';
2 2
3 /// A custom widget that adds an indent to the left or right of its child. 3 /// A custom widget that adds an indent to the left or right of its child.
4 /// 4 ///
5 -/// The [IndentWidget] widget is used to create a visual indent in the UI. 5 +/// The [BlockQuoteWidget] widget is used to create a visual indent in the UI.
6 /// It takes a [child] parameter which is the content of the widget, 6 /// It takes a [child] parameter which is the content of the widget,
7 /// a [direction] parameter which specifies the direction of the indent, 7 /// a [direction] parameter which specifies the direction of the indent,
8 /// and a [color] parameter to set the color of the indent. 8 /// and a [color] parameter to set the color of the indent.
9 -class IndentWidget extends StatelessWidget {  
10 - const IndentWidget({ 9 +class BlockQuoteWidget extends StatelessWidget {
  10 + const BlockQuoteWidget({
11 super.key, 11 super.key,
12 required this.child, 12 required this.child,
13 required this.direction, 13 required this.direction,
@@ -128,6 +128,7 @@ class GptMarkdown extends StatelessWidget { @@ -128,6 +128,7 @@ class GptMarkdown extends StatelessWidget {
128 return ClipRRect( 128 return ClipRRect(
129 child: MdWidget( 129 child: MdWidget(
130 tex, 130 tex,
  131 + true,
131 config: GptMarkdownConfig( 132 config: GptMarkdownConfig(
132 textDirection: textDirection, 133 textDirection: textDirection,
133 style: style, 134 style: style,
@@ -5,7 +5,7 @@ abstract class MarkdownComponent { @@ -5,7 +5,7 @@ abstract class MarkdownComponent {
5 static final List<MarkdownComponent> components = [ 5 static final List<MarkdownComponent> components = [
6 CodeBlockMd(), 6 CodeBlockMd(),
7 NewLines(), 7 NewLines(),
8 - IndentMd(), 8 + BlockQuote(),
9 ImageMd(), 9 ImageMd(),
10 ATagMd(), 10 ATagMd(),
11 TableMd(), 11 TableMd(),
@@ -20,7 +20,20 @@ abstract class MarkdownComponent { @@ -20,7 +20,20 @@ abstract class MarkdownComponent {
20 ItalicMd(), 20 ItalicMd(),
21 LatexMath(), 21 LatexMath(),
22 LatexMathMultiLine(), 22 LatexMathMultiLine(),
  23 + HighlightedText(),
  24 + SourceTag(),
  25 + IndentMd(),
  26 + ];
  27 +
  28 + static final List<MarkdownComponent> inlineComponents = [
23 ImageMd(), 29 ImageMd(),
  30 + ATagMd(),
  31 + TableMd(),
  32 + StrikeMd(),
  33 + BoldMd(),
  34 + ItalicMd(),
  35 + LatexMath(),
  36 + LatexMathMultiLine(),
24 HighlightedText(), 37 HighlightedText(),
25 SourceTag(), 38 SourceTag(),
26 ]; 39 ];
@@ -30,10 +43,14 @@ abstract class MarkdownComponent { @@ -30,10 +43,14 @@ abstract class MarkdownComponent {
30 BuildContext context, 43 BuildContext context,
31 String text, 44 String text,
32 final GptMarkdownConfig config, 45 final GptMarkdownConfig config,
  46 + bool includeGlobalComponents,
33 ) { 47 ) {
  48 + var components =
  49 + includeGlobalComponents
  50 + ? MarkdownComponent.components
  51 + : MarkdownComponent.inlineComponents;
34 List<InlineSpan> spans = []; 52 List<InlineSpan> spans = [];
35 - List<String> regexes =  
36 - components.map<String>((e) => e.exp.pattern).toList(); 53 + Iterable<String> regexes = components.map<String>((e) => e.exp.pattern);
37 final combinedRegex = RegExp( 54 final combinedRegex = RegExp(
38 regexes.join("|"), 55 regexes.join("|"),
39 multiLine: true, 56 multiLine: true,
@@ -46,7 +63,7 @@ abstract class MarkdownComponent { @@ -46,7 +63,7 @@ abstract class MarkdownComponent {
46 for (var each in components) { 63 for (var each in components) {
47 var p = each.exp.pattern; 64 var p = each.exp.pattern;
48 var exp = RegExp( 65 var exp = RegExp(
49 - '^$p', 66 + '^$p\$',
50 multiLine: each.exp.isMultiLine, 67 multiLine: each.exp.isMultiLine,
51 dotAll: each.exp.isDotAll, 68 dotAll: each.exp.isDotAll,
52 ); 69 );
@@ -133,7 +150,11 @@ abstract class BlockMd extends MarkdownComponent { @@ -133,7 +150,11 @@ abstract class BlockMd extends MarkdownComponent {
133 var child = build(context, text, config); 150 var child = build(context, text, config);
134 length = min(length, 4); 151 length = min(length, 4);
135 if (length > 0) { 152 if (length > 0) {
136 - child = UnorderedListView(spacing: length * 1.0, child: child); 153 + child = UnorderedListView(
  154 + spacing: length * 1.0,
  155 + textDirection: config.textDirection,
  156 + child: child,
  157 + );
137 } 158 }
138 return WidgetSpan(child: child, alignment: PlaceholderAlignment.middle); 159 return WidgetSpan(child: child, alignment: PlaceholderAlignment.middle);
139 } 160 }
@@ -145,6 +166,40 @@ abstract class BlockMd extends MarkdownComponent { @@ -145,6 +166,40 @@ abstract class BlockMd extends MarkdownComponent {
145 ); 166 );
146 } 167 }
147 168
  169 +/// Indent component
  170 +class IndentMd extends BlockMd {
  171 + @override
  172 + String get expString => (r"^(\ \ +)([^\n]+)$");
  173 + @override
  174 + Widget build(
  175 + BuildContext context,
  176 + String text,
  177 + final GptMarkdownConfig config,
  178 + ) {
  179 + var match = this.exp.firstMatch(text);
  180 + var conf = config.copyWith();
  181 + return Directionality(
  182 + textDirection: config.textDirection,
  183 + child: Row(
  184 + children: [
  185 + Expanded(
  186 + child: config.getRich(
  187 + TextSpan(
  188 + children: MarkdownComponent.generate(
  189 + context,
  190 + match?[2]?.trim() ?? "",
  191 + conf,
  192 + false,
  193 + ),
  194 + ),
  195 + ),
  196 + ),
  197 + ],
  198 + ),
  199 + );
  200 + }
  201 +}
  202 +
148 /// Heading component 203 /// Heading component
149 class HTag extends BlockMd { 204 class HTag extends BlockMd {
150 @override 205 @override
@@ -174,6 +229,7 @@ class HTag extends BlockMd { @@ -174,6 +229,7 @@ class HTag extends BlockMd {
174 context, 229 context,
175 "${match.namedGroup('data')}", 230 "${match.namedGroup('data')}",
176 conf, 231 conf,
  232 + false,
177 )), 233 )),
178 if (match.namedGroup('hash')!.length == 1) ...[ 234 if (match.namedGroup('hash')!.length == 1) ...[
179 const TextSpan( 235 const TextSpan(
@@ -205,8 +261,12 @@ class NewLines extends InlineMd { @@ -205,8 +261,12 @@ class NewLines extends InlineMd {
205 final GptMarkdownConfig config, 261 final GptMarkdownConfig config,
206 ) { 262 ) {
207 return TextSpan( 263 return TextSpan(
208 - text: "\n\n\n\n",  
209 - style: TextStyle(fontSize: 6, color: config.style?.color), 264 + text: "\n\n",
  265 + style: TextStyle(
  266 + fontSize: config.style?.fontSize ?? 14,
  267 + height: 1.15,
  268 + color: config.style?.color,
  269 + ),
210 ); 270 );
211 } 271 }
212 } 272 }
@@ -246,7 +306,7 @@ class CheckBoxMd extends BlockMd { @@ -246,7 +306,7 @@ class CheckBoxMd extends BlockMd {
246 return CustomCb( 306 return CustomCb(
247 value: ("${match?[1]}" == "x"), 307 value: ("${match?[1]}" == "x"),
248 textDirection: config.textDirection, 308 textDirection: config.textDirection,
249 - child: MdWidget("${match?[2]}", config: config), 309 + child: MdWidget("${match?[2]}", false, config: config),
250 ); 310 );
251 } 311 }
252 } 312 }
@@ -267,13 +327,13 @@ class RadioButtonMd extends BlockMd { @@ -267,13 +327,13 @@ class RadioButtonMd extends BlockMd {
267 return CustomRb( 327 return CustomRb(
268 value: ("${match?[1]}" == "x"), 328 value: ("${match?[1]}" == "x"),
269 textDirection: config.textDirection, 329 textDirection: config.textDirection,
270 - child: MdWidget("${match?[2]}", config: config), 330 + child: MdWidget("${match?[2]}", false, config: config),
271 ); 331 );
272 } 332 }
273 } 333 }
274 334
275 -/// Indent  
276 -class IndentMd extends InlineMd { 335 +/// Block quote component
  336 +class BlockQuote extends InlineMd {
277 @override 337 @override
278 bool get inline => false; 338 bool get inline => false;
279 @override 339 @override
@@ -292,7 +352,7 @@ class IndentMd extends InlineMd { @@ -292,7 +352,7 @@ class IndentMd extends InlineMd {
292 // data = data.replaceAll(RegExp(r'\n\ {' '$spaces' '}'), '\n').trim(); 352 // data = data.replaceAll(RegExp(r'\n\ {' '$spaces' '}'), '\n').trim();
293 data = data.trim(); 353 data = data.trim();
294 var child = TextSpan( 354 var child = TextSpan(
295 - children: MarkdownComponent.generate(context, data, config), 355 + children: MarkdownComponent.generate(context, data, config, true),
296 ); 356 );
297 return TextSpan( 357 return TextSpan(
298 children: [ 358 children: [
@@ -301,7 +361,7 @@ class IndentMd extends InlineMd { @@ -301,7 +361,7 @@ class IndentMd extends InlineMd {
301 textDirection: config.textDirection, 361 textDirection: config.textDirection,
302 child: Padding( 362 child: Padding(
303 padding: const EdgeInsets.symmetric(vertical: 2), 363 padding: const EdgeInsets.symmetric(vertical: 2),
304 - child: IndentWidget( 364 + child: BlockQuoteWidget(
305 color: Theme.of(context).colorScheme.onSurfaceVariant, 365 color: Theme.of(context).colorScheme.onSurfaceVariant,
306 direction: config.textDirection, 366 direction: config.textDirection,
307 child: Padding( 367 child: Padding(
@@ -330,7 +390,7 @@ class UnOrderedList extends BlockMd { @@ -330,7 +390,7 @@ class UnOrderedList extends BlockMd {
330 ) { 390 ) {
331 var match = this.exp.firstMatch(text); 391 var match = this.exp.firstMatch(text);
332 392
333 - var child = MdWidget("${match?[1]?.trim()}", config: config); 393 + var child = MdWidget("${match?[1]?.trim()}", false, config: config);
334 394
335 return config.unOrderedListBuilder?.call( 395 return config.unOrderedListBuilder?.call(
336 context, 396 context,
@@ -368,7 +428,7 @@ class OrderedList extends BlockMd { @@ -368,7 +428,7 @@ class OrderedList extends BlockMd {
368 428
369 var no = "${match?[1]}"; 429 var no = "${match?[1]}";
370 430
371 - var child = MdWidget("${match?[2]?.trim()}", config: config); 431 + var child = MdWidget("${match?[2]?.trim()}", false, config: config);
372 return config.orderedListBuilder?.call( 432 return config.orderedListBuilder?.call(
373 context, 433 context,
374 no, 434 no,
@@ -450,7 +510,12 @@ class BoldMd extends InlineMd { @@ -450,7 +510,12 @@ class BoldMd extends InlineMd {
450 const TextStyle(fontWeight: FontWeight.bold), 510 const TextStyle(fontWeight: FontWeight.bold),
451 ); 511 );
452 return TextSpan( 512 return TextSpan(
453 - children: MarkdownComponent.generate(context, "${match?[1]}", conf), 513 + children: MarkdownComponent.generate(
  514 + context,
  515 + "${match?[1]}",
  516 + conf,
  517 + false,
  518 + ),
454 style: conf.style, 519 style: conf.style,
455 ); 520 );
456 } 521 }
@@ -476,7 +541,12 @@ class StrikeMd extends InlineMd { @@ -476,7 +541,12 @@ class StrikeMd extends InlineMd {
476 const TextStyle(decoration: TextDecoration.lineThrough), 541 const TextStyle(decoration: TextDecoration.lineThrough),
477 ); 542 );
478 return TextSpan( 543 return TextSpan(
479 - children: MarkdownComponent.generate(context, "${match?[1]}", conf), 544 + children: MarkdownComponent.generate(
  545 + context,
  546 + "${match?[1]}",
  547 + conf,
  548 + false,
  549 + ),
480 style: conf.style, 550 style: conf.style,
481 ); 551 );
482 } 552 }
@@ -504,7 +574,7 @@ class ItalicMd extends InlineMd { @@ -504,7 +574,7 @@ class ItalicMd extends InlineMd {
504 ), 574 ),
505 ); 575 );
506 return TextSpan( 576 return TextSpan(
507 - children: MarkdownComponent.generate(context, "$data", conf), 577 + children: MarkdownComponent.generate(context, "$data", conf, false),
508 style: conf.style, 578 style: conf.style,
509 ); 579 );
510 } 580 }
@@ -898,6 +968,7 @@ class TableMd extends BlockMd { @@ -898,6 +968,7 @@ class TableMd extends BlockMd {
898 ), 968 ),
899 child: MdWidget( 969 child: MdWidget(
900 (e[index] ?? "").trim(), 970 (e[index] ?? "").trim(),
  971 + false,
901 config: config, 972 config: config,
902 ), 973 ),
903 ), 974 ),
@@ -2,11 +2,19 @@ part of 'gpt_markdown.dart'; @@ -2,11 +2,19 @@ part of 'gpt_markdown.dart';
2 2
3 /// It creates a markdown widget closed to each other. 3 /// It creates a markdown widget closed to each other.
4 class MdWidget extends StatelessWidget { 4 class MdWidget extends StatelessWidget {
5 - const MdWidget(this.exp, {super.key, required this.config}); 5 + const MdWidget(
  6 + this.exp,
  7 + this.includeGlobalComponents, {
  8 + super.key,
  9 + required this.config,
  10 + });
6 11
7 /// The expression to be displayed. 12 /// The expression to be displayed.
8 final String exp; 13 final String exp;
9 14
  15 + /// Whether to include global components.
  16 + final bool includeGlobalComponents;
  17 +
10 /// The configuration of the markdown widget. 18 /// The configuration of the markdown widget.
11 final GptMarkdownConfig config; 19 final GptMarkdownConfig config;
12 20
@@ -28,6 +36,7 @@ class MdWidget extends StatelessWidget { @@ -28,6 +36,7 @@ class MdWidget extends StatelessWidget {
28 // return "\\[$body\\]"; 36 // return "\\[$body\\]";
29 // }), 37 // }),
30 config, 38 config,
  39 + includeGlobalComponents,
31 ), 40 ),
32 ); 41 );
33 return config.getRich( 42 return config.getRich(
1 name: gpt_markdown 1 name: gpt_markdown
2 description: "Powerful Markdown & LaTeX Renderer for Flutter: Rich Text, Math, Tables, Links, and Text Selection. Ideal for ChatGPT, Gemini, and more." 2 description: "Powerful Markdown & LaTeX Renderer for Flutter: Rich Text, Math, Tables, Links, and Text Selection. Ideal for ChatGPT, Gemini, and more."
3 -version: 1.0.15 3 +version: 1.0.16
4 homepage: https://github.com/Infinitix-LLC/gpt_markdown 4 homepage: https://github.com/Infinitix-LLC/gpt_markdown
5 5
6 environment: 6 environment: