diff --git a/packages/app/src/components/chat/ChatMessage.vue b/packages/app/src/components/chat/ChatMessage.vue index af8f8b39..55d9d757 100644 --- a/packages/app/src/components/chat/ChatMessage.vue +++ b/packages/app/src/components/chat/ChatMessage.vue @@ -200,6 +200,15 @@ /> +
+ +
+
{ return extractRecipes(props.message.content) }) +const inlineTables = computed(() => { + if (isUser.value) return [] + return extractTables(props.message.content) +}) + const inlineEvents = computed(() => { if (isUser.value) return [] return extractEvents(props.message.content) diff --git a/packages/app/src/components/renderers/InteractiveTable.vue b/packages/app/src/components/renderers/InteractiveTable.vue new file mode 100644 index 00000000..5ff44d03 --- /dev/null +++ b/packages/app/src/components/renderers/InteractiveTable.vue @@ -0,0 +1,134 @@ + + + diff --git a/packages/app/src/composables/useTableExtractor.ts b/packages/app/src/composables/useTableExtractor.ts new file mode 100644 index 00000000..9c8de362 --- /dev/null +++ b/packages/app/src/composables/useTableExtractor.ts @@ -0,0 +1,49 @@ +/** + * Extract markdown tables from text into structured data + * for interactive table rendering. + */ + +export interface TableData { + headers: string[] + rows: string[][] + raw: string +} + +// Matches a markdown table: header row, separator row, data rows +const TABLE_RE = /^(\|[^\n]+\|)\n(\|[\s:|-]+\|)\n((?:\|[^\n]+\|\n?)+)/gm + +export function extractTables(text: string): TableData[] { + const results: TableData[] = [] + let m: RegExpExecArray | null + const re = new RegExp(TABLE_RE.source, TABLE_RE.flags) + + while ((m = re.exec(text)) !== null) { + const headerLine = m[1] + const dataBlock = m[3] + + const headers = parseRow(headerLine) + const rows = dataBlock + .trim() + .split('\n') + .map(parseRow) + .filter((r) => r.length > 0) + + if (headers.length > 0 && rows.length > 0) { + results.push({ headers, rows, raw: m[0] }) + } + } + + return results +} + +function parseRow(line: string): string[] { + return line + .replace(/^\|/, '') + .replace(/\|$/, '') + .split('|') + .map((cell) => cell.trim()) +} + +export function hasTables(text: string): boolean { + return TABLE_RE.test(text) +}