Add imageBuilder to config
Add imageBuilder to example Fix file name typo
Showing
5 changed files
with
46 additions
and
30 deletions
| @@ -328,8 +328,15 @@ Markdown and LaTeX can be powerful tools for formatting text and mathematical ex | @@ -328,8 +328,15 @@ Markdown and LaTeX can be powerful tools for formatting text and mathematical ex | ||
| 328 | RegExp(r"align\*"), | 328 | RegExp(r"align\*"), |
| 329 | (match) => "aligned"); | 329 | (match) => "aligned"); |
| 330 | }, | 330 | }, |
| 331 | + imageBuilder: (context, url) { | ||
| 332 | + return Image.network( | ||
| 333 | + url, | ||
| 334 | + width: 100, | ||
| 335 | + height: 100, | ||
| 336 | + ); | ||
| 337 | + }, | ||
| 331 | latexBuilder: | 338 | latexBuilder: |
| 332 | - (contex, tex, textStyle, inline) { | 339 | + (context, tex, textStyle, inline) { |
| 333 | if (tex.contains(r"\begin{tabular}")) { | 340 | if (tex.contains(r"\begin{tabular}")) { |
| 334 | // return table. | 341 | // return table. |
| 335 | String tableString = "|${(RegExp( | 342 | String tableString = "|${(RegExp( |
| @@ -14,6 +14,7 @@ class GptMarkdownConfig { | @@ -14,6 +14,7 @@ class GptMarkdownConfig { | ||
| 14 | this.sourceTagBuilder, | 14 | this.sourceTagBuilder, |
| 15 | this.highlightBuilder, | 15 | this.highlightBuilder, |
| 16 | this.linkBuilder, | 16 | this.linkBuilder, |
| 17 | + this.imageBuilder, | ||
| 17 | this.maxLines, | 18 | this.maxLines, |
| 18 | this.overflow, | 19 | this.overflow, |
| 19 | }); | 20 | }); |
| @@ -55,6 +56,7 @@ class GptMarkdownConfig { | @@ -55,6 +56,7 @@ class GptMarkdownConfig { | ||
| 55 | TextStyle style, | 56 | TextStyle style, |
| 56 | )? | 57 | )? |
| 57 | linkBuilder; | 58 | linkBuilder; |
| 59 | + final Widget Function(BuildContext, String imageUrl)? imageBuilder; | ||
| 58 | 60 | ||
| 59 | GptMarkdownConfig copyWith({ | 61 | GptMarkdownConfig copyWith({ |
| 60 | TextStyle? style, | 62 | TextStyle? style, |
| @@ -95,6 +97,7 @@ class GptMarkdownConfig { | @@ -95,6 +97,7 @@ class GptMarkdownConfig { | ||
| 95 | TextStyle style, | 97 | TextStyle style, |
| 96 | )? | 98 | )? |
| 97 | linkBuilder, | 99 | linkBuilder, |
| 100 | + final Widget Function(BuildContext, String imageUrl)? imageBuilder, | ||
| 98 | }) { | 101 | }) { |
| 99 | return GptMarkdownConfig( | 102 | return GptMarkdownConfig( |
| 100 | style: style ?? this.style, | 103 | style: style ?? this.style, |
| @@ -111,6 +114,7 @@ class GptMarkdownConfig { | @@ -111,6 +114,7 @@ class GptMarkdownConfig { | ||
| 111 | overflow: overflow ?? this.overflow, | 114 | overflow: overflow ?? this.overflow, |
| 112 | highlightBuilder: highlightBuilder ?? this.highlightBuilder, | 115 | highlightBuilder: highlightBuilder ?? this.highlightBuilder, |
| 113 | linkBuilder: linkBuilder ?? this.linkBuilder, | 116 | linkBuilder: linkBuilder ?? this.linkBuilder, |
| 117 | + imageBuilder: imageBuilder ?? this.imageBuilder, | ||
| 114 | ); | 118 | ); |
| 115 | } | 119 | } |
| 116 | 120 |
| 1 | import 'package:flutter/material.dart'; | 1 | import 'package:flutter/material.dart'; |
| 2 | -import 'package:gpt_markdown/custom_widgets/markdow_config.dart'; | 2 | +import 'package:gpt_markdown/custom_widgets/markdown_config.dart'; |
| 3 | 3 | ||
| 4 | import 'package:flutter/foundation.dart'; | 4 | import 'package:flutter/foundation.dart'; |
| 5 | import 'package:flutter_math_fork/flutter_math.dart'; | 5 | import 'package:flutter_math_fork/flutter_math.dart'; |
| @@ -28,6 +28,7 @@ class GptMarkdown extends StatelessWidget { | @@ -28,6 +28,7 @@ class GptMarkdown extends StatelessWidget { | ||
| 28 | this.textDirection = TextDirection.ltr, | 28 | this.textDirection = TextDirection.ltr, |
| 29 | this.latexWorkaround, | 29 | this.latexWorkaround, |
| 30 | this.textAlign, | 30 | this.textAlign, |
| 31 | + this.imageBuilder, | ||
| 31 | this.textScaler, | 32 | this.textScaler, |
| 32 | this.onLinkTab, | 33 | this.onLinkTab, |
| 33 | this.latexBuilder, | 34 | this.latexBuilder, |
| @@ -72,6 +73,7 @@ class GptMarkdown extends StatelessWidget { | @@ -72,6 +73,7 @@ class GptMarkdown extends StatelessWidget { | ||
| 72 | TextStyle style, | 73 | TextStyle style, |
| 73 | )? | 74 | )? |
| 74 | linkBuilder; | 75 | linkBuilder; |
| 76 | + final Widget Function(BuildContext, String imageUrl)? imageBuilder; | ||
| 75 | String _removeExtraLinesInsideBlockLatex(String text) { | 77 | String _removeExtraLinesInsideBlockLatex(String text) { |
| 76 | return text.replaceAllMapped( | 78 | return text.replaceAllMapped( |
| 77 | RegExp(r"\\\[(.*?)\\\]", multiLine: true, dotAll: true), | 79 | RegExp(r"\\\[(.*?)\\\]", multiLine: true, dotAll: true), |
| @@ -120,6 +122,7 @@ class GptMarkdown extends StatelessWidget { | @@ -120,6 +122,7 @@ class GptMarkdown extends StatelessWidget { | ||
| 120 | sourceTagBuilder: sourceTagBuilder, | 122 | sourceTagBuilder: sourceTagBuilder, |
| 121 | highlightBuilder: highlightBuilder, | 123 | highlightBuilder: highlightBuilder, |
| 122 | linkBuilder: linkBuilder, | 124 | linkBuilder: linkBuilder, |
| 125 | + imageBuilder: imageBuilder, | ||
| 123 | ), | 126 | ), |
| 124 | ), | 127 | ), |
| 125 | ); | 128 | ); |
| @@ -755,35 +755,37 @@ class ImageMd extends InlineMd { | @@ -755,35 +755,37 @@ class ImageMd extends InlineMd { | ||
| 755 | width = double.tryParse(size?[1]?.toString().trim() ?? 'a'); | 755 | width = double.tryParse(size?[1]?.toString().trim() ?? 'a'); |
| 756 | height = double.tryParse(size?[2]?.toString().trim() ?? 'a'); | 756 | height = double.tryParse(size?[2]?.toString().trim() ?? 'a'); |
| 757 | } | 757 | } |
| 758 | + late final Widget image; | ||
| 759 | + if (config.imageBuilder != null) { | ||
| 760 | + image = config.imageBuilder!(context, '${match?[2]}'); | ||
| 761 | + } else { | ||
| 762 | + image = Image( | ||
| 763 | + image: NetworkImage("${match?[2]}"), | ||
| 764 | + loadingBuilder: ( | ||
| 765 | + BuildContext context, | ||
| 766 | + Widget child, | ||
| 767 | + ImageChunkEvent? loadingProgress, | ||
| 768 | + ) { | ||
| 769 | + if (loadingProgress == null) { | ||
| 770 | + return child; | ||
| 771 | + } | ||
| 772 | + return CustomImageLoading( | ||
| 773 | + progress: | ||
| 774 | + loadingProgress.expectedTotalBytes != null | ||
| 775 | + ? loadingProgress.cumulativeBytesLoaded / | ||
| 776 | + loadingProgress.expectedTotalBytes! | ||
| 777 | + : 1, | ||
| 778 | + ); | ||
| 779 | + }, | ||
| 780 | + fit: BoxFit.fill, | ||
| 781 | + errorBuilder: (context, error, stackTrace) { | ||
| 782 | + return const CustomImageError(); | ||
| 783 | + }, | ||
| 784 | + ); | ||
| 785 | + } | ||
| 758 | return WidgetSpan( | 786 | return WidgetSpan( |
| 759 | alignment: PlaceholderAlignment.bottom, | 787 | alignment: PlaceholderAlignment.bottom, |
| 760 | - child: SizedBox( | ||
| 761 | - width: width, | ||
| 762 | - height: height, | ||
| 763 | - child: Image( | ||
| 764 | - image: NetworkImage("${match?[2]}"), | ||
| 765 | - loadingBuilder: ( | ||
| 766 | - BuildContext context, | ||
| 767 | - Widget child, | ||
| 768 | - ImageChunkEvent? loadingProgress, | ||
| 769 | - ) { | ||
| 770 | - if (loadingProgress == null) { | ||
| 771 | - return child; | ||
| 772 | - } | ||
| 773 | - return CustomImageLoading( | ||
| 774 | - progress: | ||
| 775 | - loadingProgress.expectedTotalBytes != null | ||
| 776 | - ? loadingProgress.cumulativeBytesLoaded / | ||
| 777 | - loadingProgress.expectedTotalBytes! | ||
| 778 | - : 1, | ||
| 779 | - ); | ||
| 780 | - }, | ||
| 781 | - fit: BoxFit.fill, | ||
| 782 | - errorBuilder: (context, error, stackTrace) { | ||
| 783 | - return const CustomImageError(); | ||
| 784 | - }, | ||
| 785 | - ), | ||
| 786 | - ), | 788 | + child: SizedBox(width: width, height: height, child: image), |
| 787 | ); | 789 | ); |
| 788 | } | 790 | } |
| 789 | } | 791 | } |
-
Please register or login to post a comment