saminsohag

fixed some issues and added tableBuilder and underlineText

1 ## 1.1.2 1 ## 1.1.2
2 2
3 -* 🔗 Fixed text decoration color of link markdown component  
4 * 📊 Fixed table column alignment support ([#65](https://github.com/Infinitix-LLC/gpt_markdown/issues/65)) 3 * 📊 Fixed table column alignment support ([#65](https://github.com/Infinitix-LLC/gpt_markdown/issues/65))
  4 +* 🎨 Added `tableBuilder` parameter to customize table rendering
  5 +* 🔗 Fixed text decoration color of link markdown component
5 6
6 ## 1.1.1 7 ## 1.1.1
7 8
@@ -32,7 +32,7 @@ gpt_markdown is a drop-in replacement for flutter_markdown, offering extended su @@ -32,7 +32,7 @@ gpt_markdown is a drop-in replacement for flutter_markdown, offering extended su
32 | 🔗 Links | ✅ | 32 | 🔗 Links | ✅ |
33 | 📱 Selectable | ✅ | 33 | 📱 Selectable | ✅ |
34 | 🧩 Custom components | ✅ | | 34 | 🧩 Custom components | ✅ | |
35 -| 📎 Underline | | 🔜 | 35 +| 📎 Underline | ✅ | |
36 36
37 ## ✨ Key Features 37 ## ✨ Key Features
38 38
@@ -86,6 +86,11 @@ Render a wide variety of content with full Markdown and LaTeX support, including @@ -86,6 +86,11 @@ Render a wide variety of content with full Markdown and LaTeX support, including
86 *Italic text* 86 *Italic text*
87 ``` 87 ```
88 88
  89 +- <u>Underline text</u>
  90 +```
  91 +<u>Underline text</u>
  92 +```
  93 +
89 - heading texts 94 - heading texts
90 95
91 ``` 96 ```
@@ -123,5 +123,28 @@ darkTheme: ThemeData( @@ -123,5 +123,28 @@ darkTheme: ThemeData(
123 ), 123 ),
124 ``` 124 ```
125 125
  126 +Use `tableBuilder` to customize table rendering:
  127 +
  128 +```dart
  129 +GptMarkdown(
  130 + markdownText,
  131 + tableBuilder: (context, tableRows, textStyle, config) {
  132 + return Table(
  133 + border: TableBorder.all(
  134 + width: 1,
  135 + color: Colors.red,
  136 + ),
  137 + children: tableRows.map((e) {
  138 + return TableRow(
  139 + children: e.fields.map((e) {
  140 + return Text(e.data);
  141 + }).toList(),
  142 + );
  143 + }).toList(),
  144 + );
  145 + },
  146 +);
  147 +```
  148 +
126 Please see the [README.md](https://github.com/Infinitix-LLC/gpt_markdown) and also [example](https://github.com/Infinitix-LLC/gpt_markdown/tree/main/example/lib/main.dart) app for more details. 149 Please see the [README.md](https://github.com/Infinitix-LLC/gpt_markdown) and also [example](https://github.com/Infinitix-LLC/gpt_markdown/tree/main/example/lib/main.dart) app for more details.
127 150
@@ -329,6 +329,12 @@ This document was created to test the robustness of Markdown parsers and to ensu @@ -329,6 +329,12 @@ This document was created to test the robustness of Markdown parsers and to ensu
329 329
330 @override 330 @override
331 Widget build(BuildContext context) { 331 Widget build(BuildContext context) {
  332 +// var data = '''|asdfasfd|asdfasf|
  333 +// |---|---|
  334 +// |sohag|asdfasf|
  335 +// |asdfasf|asdfasf|
  336 +// ''';
  337 +
332 return GptMarkdownTheme( 338 return GptMarkdownTheme(
333 gptThemeData: GptMarkdownTheme.of(context).copyWith( 339 gptThemeData: GptMarkdownTheme.of(context).copyWith(
334 highlightColor: Colors.purple, 340 highlightColor: Colors.purple,
@@ -411,6 +417,7 @@ This document was created to test the robustness of Markdown parsers and to ensu @@ -411,6 +417,7 @@ This document was created to test the robustness of Markdown parsers and to ensu
411 ListenableBuilder( 417 ListenableBuilder(
412 listenable: _controller, 418 listenable: _controller,
413 builder: (context, _) { 419 builder: (context, _) {
  420 + var data = _controller.text;
414 return Container( 421 return Container(
415 padding: const EdgeInsets.all(8), 422 padding: const EdgeInsets.all(8),
416 decoration: BoxDecoration( 423 decoration: BoxDecoration(
@@ -440,7 +447,7 @@ This document was created to test the robustness of Markdown parsers and to ensu @@ -440,7 +447,7 @@ This document was created to test the robustness of Markdown parsers and to ensu
440 child: Builder( 447 child: Builder(
441 builder: (context) { 448 builder: (context) {
442 Widget child = GptMarkdown( 449 Widget child = GptMarkdown(
443 - _controller.text, 450 + data,
444 textDirection: _direction, 451 textDirection: _direction,
445 onLinkTap: (url, title) { 452 onLinkTap: (url, title) {
446 debugPrint(url); 453 debugPrint(url);
@@ -614,6 +621,24 @@ This document was created to test the robustness of Markdown parsers and to ensu @@ -614,6 +621,24 @@ This document was created to test the robustness of Markdown parsers and to ensu
614 ), 621 ),
615 ); 622 );
616 }, 623 },
  624 +
  625 + // tableBuilder: (context, tableRows,
  626 + // textStyle, config) {
  627 + // return Table(
  628 + // border: TableBorder.all(
  629 + // width: 1,
  630 + // color: Colors.red,
  631 + // ),
  632 + // children: tableRows.map((e) {
  633 + // return TableRow(
  634 + // children: e.fields.map((e) {
  635 + // return Text(e.data);
  636 + // }).toList(),
  637 + // );
  638 + // }).toList(),
  639 + // );
  640 + // },
  641 +
617 // components: [ 642 // components: [
618 // CodeBlockMd(), 643 // CodeBlockMd(),
619 // NewLines(), 644 // NewLines(),
@@ -49,6 +49,15 @@ typedef LinkBuilder = @@ -49,6 +49,15 @@ typedef LinkBuilder =
49 TextStyle style, 49 TextStyle style,
50 ); 50 );
51 51
  52 +/// A builder function for the table.
  53 +typedef TableBuilder =
  54 + Widget Function(
  55 + BuildContext context,
  56 + List<CustomTableRow> tableRows,
  57 + TextStyle textStyle,
  58 + GptMarkdownConfig config,
  59 + );
  60 +
52 /// A builder function for the highlight. 61 /// A builder function for the highlight.
53 typedef HighlightBuilder = 62 typedef HighlightBuilder =
54 Widget Function(BuildContext context, String text, TextStyle style); 63 Widget Function(BuildContext context, String text, TextStyle style);
@@ -83,6 +92,7 @@ class GptMarkdownConfig { @@ -83,6 +92,7 @@ class GptMarkdownConfig {
83 this.overflow, 92 this.overflow,
84 this.components, 93 this.components,
85 this.inlineComponents, 94 this.inlineComponents,
  95 + this.tableBuilder,
86 }); 96 });
87 97
88 /// The direction of the text. 98 /// The direction of the text.
@@ -142,6 +152,9 @@ class GptMarkdownConfig { @@ -142,6 +152,9 @@ class GptMarkdownConfig {
142 /// The list of inline components. 152 /// The list of inline components.
143 final List<MarkdownComponent>? inlineComponents; 153 final List<MarkdownComponent>? inlineComponents;
144 154
  155 + /// The table builder.
  156 + final TableBuilder? tableBuilder;
  157 +
145 /// A copy of the configuration with the specified parameters. 158 /// A copy of the configuration with the specified parameters.
146 GptMarkdownConfig copyWith({ 159 GptMarkdownConfig copyWith({
147 TextStyle? style, 160 TextStyle? style,
@@ -163,6 +176,7 @@ class GptMarkdownConfig { @@ -163,6 +176,7 @@ class GptMarkdownConfig {
163 final UnOrderedListBuilder? unOrderedListBuilder, 176 final UnOrderedListBuilder? unOrderedListBuilder,
164 final List<MarkdownComponent>? components, 177 final List<MarkdownComponent>? components,
165 final List<MarkdownComponent>? inlineComponents, 178 final List<MarkdownComponent>? inlineComponents,
  179 + final TableBuilder? tableBuilder,
166 }) { 180 }) {
167 return GptMarkdownConfig( 181 return GptMarkdownConfig(
168 style: style ?? this.style, 182 style: style ?? this.style,
@@ -184,6 +198,7 @@ class GptMarkdownConfig { @@ -184,6 +198,7 @@ class GptMarkdownConfig {
184 unOrderedListBuilder: unOrderedListBuilder ?? this.unOrderedListBuilder, 198 unOrderedListBuilder: unOrderedListBuilder ?? this.unOrderedListBuilder,
185 components: components ?? this.components, 199 components: components ?? this.components,
186 inlineComponents: inlineComponents ?? this.inlineComponents, 200 inlineComponents: inlineComponents ?? this.inlineComponents,
  201 + tableBuilder: tableBuilder ?? this.tableBuilder,
187 ); 202 );
188 } 203 }
189 204
@@ -40,6 +40,7 @@ class GptMarkdown extends StatelessWidget { @@ -40,6 +40,7 @@ class GptMarkdown extends StatelessWidget {
40 this.overflow, 40 this.overflow,
41 this.orderedListBuilder, 41 this.orderedListBuilder,
42 this.unOrderedListBuilder, 42 this.unOrderedListBuilder,
  43 + this.tableBuilder,
43 this.components, 44 this.components,
44 this.inlineComponents, 45 this.inlineComponents,
45 this.useDollarSignsForLatex = false, 46 this.useDollarSignsForLatex = false,
@@ -100,6 +101,9 @@ class GptMarkdown extends StatelessWidget { @@ -100,6 +101,9 @@ class GptMarkdown extends StatelessWidget {
100 /// Whether to use dollar signs for LaTeX. 101 /// Whether to use dollar signs for LaTeX.
101 final bool useDollarSignsForLatex; 102 final bool useDollarSignsForLatex;
102 103
  104 + /// The table builder.
  105 + final TableBuilder? tableBuilder;
  106 +
103 /// The list of components. 107 /// The list of components.
104 /// ```dart 108 /// ```dart
105 /// List<MarkdownComponent> components = [ 109 /// List<MarkdownComponent> components = [
@@ -202,6 +206,7 @@ class GptMarkdown extends StatelessWidget { @@ -202,6 +206,7 @@ class GptMarkdown extends StatelessWidget {
202 unOrderedListBuilder: unOrderedListBuilder, 206 unOrderedListBuilder: unOrderedListBuilder,
203 components: components, 207 components: components,
204 inlineComponents: inlineComponents, 208 inlineComponents: inlineComponents,
  209 + tableBuilder: tableBuilder,
205 ), 210 ),
206 ), 211 ),
207 ); 212 );
@@ -1058,6 +1058,36 @@ class TableMd extends BlockMd { @@ -1058,6 +1058,36 @@ class TableMd extends BlockMd {
1058 columnAlignments.add(TextAlign.left); 1058 columnAlignments.add(TextAlign.left);
1059 } 1059 }
1060 1060
  1061 + var tableBuilder = config.tableBuilder;
  1062 +
  1063 + if (tableBuilder != null) {
  1064 + var customTable =
  1065 + List<CustomTableRow?>.generate(value.length, (index) {
  1066 + var isHeader = index == 0;
  1067 + var row = value[index];
  1068 + if (row.isEmpty) {
  1069 + return null;
  1070 + }
  1071 + if (index == 1) {
  1072 + return null;
  1073 + }
  1074 + var fields = List<CustomTableField>.generate(maxCol, (index) {
  1075 + var field = row[index];
  1076 + return CustomTableField(
  1077 + data: field ?? "",
  1078 + alignment: columnAlignments[index],
  1079 + );
  1080 + });
  1081 + return CustomTableRow(isHeader: isHeader, fields: fields);
  1082 + }).nonNulls.toList();
  1083 + return tableBuilder(
  1084 + context,
  1085 + customTable,
  1086 + config.style ?? const TextStyle(),
  1087 + config,
  1088 + );
  1089 + }
  1090 +
1061 final controller = ScrollController(); 1091 final controller = ScrollController();
1062 return Scrollbar( 1092 return Scrollbar(
1063 controller: controller, 1093 controller: controller,
@@ -1195,3 +1225,17 @@ class UnderLineMd extends InlineMd { @@ -1195,3 +1225,17 @@ class UnderLineMd extends InlineMd {
1195 ); 1225 );
1196 } 1226 }
1197 } 1227 }
  1228 +
  1229 +class CustomTableField {
  1230 + final String data;
  1231 + final TextAlign alignment;
  1232 +
  1233 + CustomTableField({required this.data, this.alignment = TextAlign.left});
  1234 +}
  1235 +
  1236 +class CustomTableRow {
  1237 + final bool isHeader;
  1238 + final List<CustomTableField> fields;
  1239 +
  1240 + CustomTableRow({this.isHeader = false, required this.fields});
  1241 +}
1 name: gpt_markdown 1 name: gpt_markdown
2 description: "Powerful Flutter Markdown & LaTeX Renderer: Rich Text, Math, Tables, Links, and Text Selection. Ideal for ChatGPT, Gemini, and more." 2 description: "Powerful Flutter Markdown & LaTeX Renderer: Rich Text, Math, Tables, Links, and Text Selection. Ideal for ChatGPT, Gemini, and more."
3 -version: 1.1.1 3 +version: 1.1.2
4 homepage: https://github.com/Infinitix-LLC/gpt_markdown 4 homepage: https://github.com/Infinitix-LLC/gpt_markdown
5 5
6 environment: 6 environment: