build method
Builds the table widget from parsed Markdown text.
This method splits the input text into rows, trims and maps cells by index, determining max columns
for consistent layout. It constructs TR rows with TD cells containing MdWidget for recursive rendering,
skipping separator (dashes) or empty rows. Wraps in SingleChildScrollView and Scrollbar for horizontal
overflow handling. Inputs: context, raw text, and GptMarkdownConfig for styling; outputs a fully styled,
scrollable table. Logic ensures no empty tables are rendered, with theme-integrated borders for ArcaneTheme
consistency. Efficient for large tables, as parsing is O(n) and no unnecessary allocations occur.
Implementation
@override
Widget build(
BuildContext context,
String text,
final GptMarkdownConfig config,
) {
final List<Map<int, String>> value = text
.split('\n')
.map<Map<int, String>>(
(e) => e
.trim()
.split('|')
.where((element) => element.isNotEmpty)
.toList()
.asMap(),
)
.toList();
int maxCol = 0;
for (final each in value) {
if (maxCol < each.keys.length) {
maxCol = each.keys.length;
}
}
if (maxCol == 0) {
return Text("", style: config.style);
}
final controller = ScrollController();
return Scrollbar(
controller: controller,
child: SingleChildScrollView(
controller: controller,
scrollDirection: Axis.horizontal,
child: StaticTable(
border: TableBorder(
borderRadius: Theme.of(context).borderRadiusMd,
bottom: BorderSide(
width: 1, color: Theme.of(context).colorScheme.border),
left: BorderSide(
width: 1, color: Theme.of(context).colorScheme.border),
right: BorderSide(
width: 1, color: Theme.of(context).colorScheme.border),
top: BorderSide(
width: 1, color: Theme.of(context).colorScheme.border)),
rows: [
...value
.asMap()
.entries
.map((i) => TR(
column: List.generate(maxCol, (index) {
var e = i.value;
String data = e[index] ?? "";
if (RegExp(r"^:?--+:?$").hasMatch(data.trim()) ||
data.trim().isEmpty) {
return null;
}
return TD(MdWidget(
context,
(e[index] ?? "").trim(),
false,
config: config,
));
}).whereType<TD>().toList()))
.where((tr) => tr.column.isNotEmpty)
]),
),
);
}