saminsohag

Enhance table rendering by adding support for column alignment based on header d…

…efinitions. Update CHANGELOG for version 1.1.2 to reflect this new feature.
1 ## 1.1.2 1 ## 1.1.2
2 2
3 * 🔗 Fixed text decoration color of link markdown component 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))
4 5
5 ## 1.1.1 6 ## 1.1.1
6 7
@@ -1013,19 +1013,50 @@ class TableMd extends BlockMd { @@ -1013,19 +1013,50 @@ class TableMd extends BlockMd {
1013 .asMap(), 1013 .asMap(),
1014 ) 1014 )
1015 .toList(); 1015 .toList();
1016 - bool heading = RegExp(  
1017 - r"^\|.*?\|\n\|-[-\\ |]*?-\|$",  
1018 - multiLine: true,  
1019 - ).hasMatch(text.trim()); 1016 +
  1017 + // Check if table has a header and separator row
  1018 + bool hasHeader = value.length >= 2;
  1019 + List<TextAlign> columnAlignments = [];
  1020 +
  1021 + if (hasHeader) {
  1022 + // Parse alignment from the separator row (second row)
  1023 + var separatorRow = value[1];
  1024 + columnAlignments = List.generate(separatorRow.length, (index) {
  1025 + String separator = separatorRow[index] ?? "";
  1026 + separator = separator.trim();
  1027 +
  1028 + // Check for alignment indicators
  1029 + bool hasLeftColon = separator.startsWith(':');
  1030 + bool hasRightColon = separator.endsWith(':');
  1031 +
  1032 + if (hasLeftColon && hasRightColon) {
  1033 + return TextAlign.center;
  1034 + } else if (hasRightColon) {
  1035 + return TextAlign.right;
  1036 + } else if (hasLeftColon) {
  1037 + return TextAlign.left;
  1038 + } else {
  1039 + return TextAlign.left; // Default alignment
  1040 + }
  1041 + });
  1042 + }
  1043 +
1020 int maxCol = 0; 1044 int maxCol = 0;
1021 for (final each in value) { 1045 for (final each in value) {
1022 if (maxCol < each.keys.length) { 1046 if (maxCol < each.keys.length) {
1023 maxCol = each.keys.length; 1047 maxCol = each.keys.length;
1024 } 1048 }
1025 } 1049 }
  1050 +
1026 if (maxCol == 0) { 1051 if (maxCol == 0) {
1027 return Text("", style: config.style); 1052 return Text("", style: config.style);
1028 } 1053 }
  1054 +
  1055 + // Ensure we have alignment for all columns
  1056 + while (columnAlignments.length < maxCol) {
  1057 + columnAlignments.add(TextAlign.left);
  1058 + }
  1059 +
1029 final controller = ScrollController(); 1060 final controller = ScrollController();
1030 return Scrollbar( 1061 return Scrollbar(
1031 controller: controller, 1062 controller: controller,
@@ -1044,17 +1075,22 @@ class TableMd extends BlockMd { @@ -1044,17 +1075,22 @@ class TableMd extends BlockMd {
1044 value 1075 value
1045 .asMap() 1076 .asMap()
1046 .entries 1077 .entries
  1078 + .where((entry) {
  1079 + // Skip the separator row (second row) from rendering
  1080 + if (hasHeader && entry.key == 1) {
  1081 + return false;
  1082 + }
  1083 + return true;
  1084 + })
1047 .map<TableRow>( 1085 .map<TableRow>(
1048 (entry) => TableRow( 1086 (entry) => TableRow(
1049 decoration: 1087 decoration:
1050 - (heading) 1088 + (hasHeader && entry.key == 0)
1051 ? BoxDecoration( 1089 ? BoxDecoration(
1052 color: 1090 color:
1053 - (entry.key == 0)  
1054 - ? Theme.of( 1091 + Theme.of(
1055 context, 1092 context,
1056 - ).colorScheme.surfaceContainerHighest  
1057 - : null, 1093 + ).colorScheme.surfaceContainerHighest,
1058 ) 1094 )
1059 : null, 1095 : null,
1060 children: List.generate(maxCol, (index) { 1096 children: List.generate(maxCol, (index) {
@@ -1065,8 +1101,8 @@ class TableMd extends BlockMd { @@ -1065,8 +1101,8 @@ class TableMd extends BlockMd {
1065 return const SizedBox(); 1101 return const SizedBox();
1066 } 1102 }
1067 1103
1068 - return Center(  
1069 - child: Padding( 1104 + // Apply alignment based on column alignment
  1105 + Widget content = Padding(
1070 padding: const EdgeInsets.symmetric( 1106 padding: const EdgeInsets.symmetric(
1071 horizontal: 8, 1107 horizontal: 8,
1072 vertical: 4, 1108 vertical: 4,
@@ -1077,8 +1113,29 @@ class TableMd extends BlockMd { @@ -1077,8 +1113,29 @@ class TableMd extends BlockMd {
1077 false, 1113 false,
1078 config: config, 1114 config: config,
1079 ), 1115 ),
1080 - ),  
1081 ); 1116 );
  1117 +
  1118 + // Wrap with alignment widget
  1119 + switch (columnAlignments[index]) {
  1120 + case TextAlign.center:
  1121 + content = Center(child: content);
  1122 + break;
  1123 + case TextAlign.right:
  1124 + content = Align(
  1125 + alignment: Alignment.centerRight,
  1126 + child: content,
  1127 + );
  1128 + break;
  1129 + case TextAlign.left:
  1130 + default:
  1131 + content = Align(
  1132 + alignment: Alignment.centerLeft,
  1133 + child: content,
  1134 + );
  1135 + break;
  1136 + }
  1137 +
  1138 + return content;
1082 }), 1139 }),
1083 ), 1140 ),
1084 ) 1141 )