David NAISSE

added linkBuilder

@@ -13,6 +13,7 @@ class GptMarkdownConfig { @@ -13,6 +13,7 @@ class GptMarkdownConfig {
13 this.codeBuilder, 13 this.codeBuilder,
14 this.sourceTagBuilder, 14 this.sourceTagBuilder,
15 this.highlightBuilder, 15 this.highlightBuilder,
  16 + this.linkBuilder,
16 this.maxLines, 17 this.maxLines,
17 this.overflow, 18 this.overflow,
18 }); 19 });
@@ -34,6 +35,7 @@ class GptMarkdownConfig { @@ -34,6 +35,7 @@ class GptMarkdownConfig {
34 final int? maxLines; 35 final int? maxLines;
35 final TextOverflow? overflow; 36 final TextOverflow? overflow;
36 final Widget Function(BuildContext context, String text, TextStyle style)? highlightBuilder; 37 final Widget Function(BuildContext context, String text, TextStyle style)? highlightBuilder;
  38 + final Widget Function(BuildContext context, String text, String url, TextStyle style)? linkBuilder;
37 39
38 GptMarkdownConfig copyWith({ 40 GptMarkdownConfig copyWith({
39 TextStyle? style, 41 TextStyle? style,
@@ -54,6 +56,7 @@ class GptMarkdownConfig { @@ -54,6 +56,7 @@ class GptMarkdownConfig {
54 final int? maxLines, 56 final int? maxLines,
55 final TextOverflow? overflow, 57 final TextOverflow? overflow,
56 final Widget Function(BuildContext context, String text, TextStyle style)? highlightBuilder, 58 final Widget Function(BuildContext context, String text, TextStyle style)? highlightBuilder,
  59 + final Widget Function(BuildContext context, String text, String url, TextStyle style)? linkBuilder,
57 }) { 60 }) {
58 return GptMarkdownConfig( 61 return GptMarkdownConfig(
59 style: style ?? this.style, 62 style: style ?? this.style,
@@ -69,6 +72,7 @@ class GptMarkdownConfig { @@ -69,6 +72,7 @@ class GptMarkdownConfig {
69 maxLines: maxLines ?? this.maxLines, 72 maxLines: maxLines ?? this.maxLines,
70 overflow: overflow ?? this.overflow, 73 overflow: overflow ?? this.overflow,
71 highlightBuilder: highlightBuilder ?? this.highlightBuilder, 74 highlightBuilder: highlightBuilder ?? this.highlightBuilder,
  75 + linkBuilder: linkBuilder ?? this.linkBuilder,
72 ); 76 );
73 } 77 }
74 78
@@ -35,6 +35,7 @@ class GptMarkdown extends StatelessWidget { @@ -35,6 +35,7 @@ class GptMarkdown extends StatelessWidget {
35 this.codeBuilder, 35 this.codeBuilder,
36 this.sourceTagBuilder, 36 this.sourceTagBuilder,
37 this.highlightBuilder, 37 this.highlightBuilder,
  38 + this.linkBuilder,
38 this.maxLines, 39 this.maxLines,
39 this.overflow, 40 this.overflow,
40 }); 41 });
@@ -55,6 +56,7 @@ class GptMarkdown extends StatelessWidget { @@ -55,6 +56,7 @@ class GptMarkdown extends StatelessWidget {
55 codeBuilder; 56 codeBuilder;
56 final Widget Function(BuildContext, String, TextStyle)? sourceTagBuilder; 57 final Widget Function(BuildContext, String, TextStyle)? sourceTagBuilder;
57 final Widget Function(BuildContext context, String text, TextStyle style)? highlightBuilder; 58 final Widget Function(BuildContext context, String text, TextStyle style)? highlightBuilder;
  59 + final Widget Function(BuildContext context, String text, String url, TextStyle style)? linkBuilder;
58 60
59 @override 61 @override
60 Widget build(BuildContext context) { 62 Widget build(BuildContext context) {
@@ -96,6 +98,7 @@ class GptMarkdown extends StatelessWidget { @@ -96,6 +98,7 @@ class GptMarkdown extends StatelessWidget {
96 overflow: overflow, 98 overflow: overflow,
97 sourceTagBuilder: sourceTagBuilder, 99 sourceTagBuilder: sourceTagBuilder,
98 highlightBuilder: highlightBuilder, 100 highlightBuilder: highlightBuilder,
  101 + linkBuilder: linkBuilder,
99 ), 102 ),
100 )); 103 ));
101 } 104 }
@@ -733,15 +733,35 @@ class ATagMd extends InlineMd { @@ -733,15 +733,35 @@ class ATagMd extends InlineMd {
733 if (match?[1] == null && match?[2] == null) { 733 if (match?[1] == null && match?[2] == null) {
734 return const TextSpan(); 734 return const TextSpan();
735 } 735 }
  736 +
  737 + final linkText = match?[1] ?? "";
  738 + final url = match?[2] ?? "";
  739 +
  740 + // Use custom builder if provided
  741 + if (config.linkBuilder != null) {
  742 + return WidgetSpan(
  743 + child: GestureDetector(
  744 + onTap: () => config.onLinkTab?.call(url, linkText),
  745 + child: config.linkBuilder!(
  746 + context,
  747 + linkText,
  748 + url,
  749 + config.style ?? const TextStyle(),
  750 + ),
  751 + ),
  752 + );
  753 + }
  754 +
  755 + // Default rendering
736 var theme = GptMarkdownTheme.of(context); 756 var theme = GptMarkdownTheme.of(context);
737 return WidgetSpan( 757 return WidgetSpan(
738 child: LinkButton( 758 child: LinkButton(
739 hoverColor: theme.linkHoverColor, 759 hoverColor: theme.linkHoverColor,
740 color: theme.linkColor, 760 color: theme.linkColor,
741 onPressed: () { 761 onPressed: () {
742 - config.onLinkTab?.call("${match?[2]}", "${match?[1]}"); 762 + config.onLinkTab?.call(url, linkText);
743 }, 763 },
744 - text: match?[1] ?? "", 764 + text: linkText,
745 config: config, 765 config: config,
746 ), 766 ),
747 ); 767 );