Seven Parsers, One Interface: How TAFNE Handles Every Table Format
TLDR
Supporting diverse data formats (HTML, CSV, TSV, Markdown, JSON, ASCII art, SQLINSERT statements) through a single input interface requires combining semantic declaration parsers with pattern-matching heuristic parsers. Dispatching inputs to dedicated normalization functions produces standardized HTML tables without data loss.
| Format Classification | Input Types Supported | Structural Extraction Method | Output Target |
|---|---|---|---|
| Semantic Declarative | HTML, JSON | Direct DOM / Key-value mapping | Normalized <table> string |
| Heuristic Pattern-Matching | CSV, TSV, ASCII, Markdown, SQL | Regex pattern & delimiter scans | Normalized <table> string |
Normalizing unstructured data requires combining heuristic pattern matching with semantic extraction
Building a table editor that accepts arbitrary pastes requires handling both structured data (like JSON or HTML fragments) and informal text conventions (like Markdown pipe tables or SQL scripts).
We divided our parsing layer into two strategies:
- Semantic Parsers: Rely on explicit syntax markup (tags or object keys).
- Heuristic Parsers: Infer boundaries using delimiters or string pattern matching.
Dispatching inputs through a centralized switch router normalizes all data into a canonical format
All input strings pass through a centralized dispatcher (parseInput()), converting incoming payloads into standardized HTML table structures:
PARSER DISPATCH ARCHITECTURE:
[Raw Input String] + [Format Type] │ ▼ ┌────────────────────────────────┐ │ Central Dispatcher │ │ parseInput(text, type) │ └────────────────┬───────────────┘ │ ┌──────────────┬──────────┼──────────┬──────────────┐ ▼ ▼ ▼ ▼ ▼ [HTML Parser] [JSON Parser] [CSV/TSV] [SQL Parser] [Markdown] │ │ │ │ │ │ │ │ │ │ └──────────────┴──────────┼──────────┴──────────────┘ │ ▼ [Normalized HTML <table> String]
Here is the implementation of the centralized switch dispatch logic:
// Centralized multi-format table parsing dispatcher
export function parseInput(rawText, formatType) {
switch (formatType) {
case 'html': return parseHtmlInput(rawText);
case 'json': return parseJsonInput(rawText);
case 'csv': return parseCsvInput(rawText);
case 'markdown': return parseMarkdownInput(rawText);
case 'sql': return parseSqlInput(rawText);
case 'ascii': return parseAsciiInput(rawText);
default: return parseTextInput(rawText); // Tab/space fallback
}
}
// Example SQL parser extracting INSERT queries function parseSqlInput(sqlString) { const insertRegex = /INSERT\s+INTO\s+\S+\s\(([^)]+)\)\sVALUES\s*\(([^)]+)\)/gi; let match; const rows = []; let headers = null;
while ((match = insertRegex.exec(sqlString)) !== null) { if (!headers) { headers = match[1].split(',').map(h => h.trim().replace(/[`"']/g, '')); } const values = match[2].split(',').map(v => v.trim().replace(/^'|'$/g, '')); rows.push(values); } return buildHtmlTableString(headers, rows); }
By decoupling input parsing from the main canvas UI, the editor treats all imported sources as standardized tabular HTML data.
Rule of thumb: Normalize heterogeneous input formats into a canonical HTML representation through a centralized parser dispatcher.