Skip to content

Commit f389a36

Browse files
committed
Fix critical CSV parsing bug with commas in content
- Replace simple split(',') with proper CSV parser that handles quoted fields - New parseCSVLine() function respects quote boundaries - Handles escaped quotes and commas within quoted fields correctly - Fixes issue where content like 'Increase funding, improve access' was truncated - Newsrooms can now use commas freely in questions, options, and candidate answers - Maintains backward compatibility with existing sheets
1 parent 1559339 commit f389a36

1 file changed

Lines changed: 38 additions & 2 deletions

File tree

src/lib/sheets.ts

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,11 +154,12 @@ function parseCSV(csvText: string): any[] {
154154
const lines = csvText.split('\n').filter(line => line.trim());
155155
if (lines.length === 0) return [];
156156

157-
const headers = lines[0].split(',').map(h => h.replace(/"/g, '').trim());
157+
// Parse headers with proper CSV handling
158+
const headers = parseCSVLine(lines[0]);
158159
const rows = [];
159160

160161
for (let i = 1; i < lines.length; i++) {
161-
const values = lines[i].split(',').map(v => v.replace(/"/g, '').trim());
162+
const values = parseCSVLine(lines[i]);
162163
const row: any = {};
163164
headers.forEach((header, index) => {
164165
row[header] = values[index] || '';
@@ -169,6 +170,41 @@ function parseCSV(csvText: string): any[] {
169170
return rows;
170171
}
171172

173+
// Proper CSV line parsing that handles quoted fields with commas
174+
function parseCSVLine(line: string): string[] {
175+
const result = [];
176+
let current = '';
177+
let inQuotes = false;
178+
179+
for (let i = 0; i < line.length; i++) {
180+
const char = line[i];
181+
const nextChar = line[i + 1];
182+
183+
if (char === '"') {
184+
if (inQuotes && nextChar === '"') {
185+
// Escaped quote
186+
current += '"';
187+
i++; // Skip next quote
188+
} else {
189+
// Toggle quote state
190+
inQuotes = !inQuotes;
191+
}
192+
} else if (char === ',' && !inQuotes) {
193+
// Field delimiter outside quotes
194+
result.push(current.trim());
195+
current = '';
196+
} else {
197+
// Regular character
198+
current += char;
199+
}
200+
}
201+
202+
// Add final field
203+
result.push(current.trim());
204+
205+
return result;
206+
}
207+
172208
export async function fetchSheetDataSVO(sheetId: string | null): Promise<QuizDataSVO> {
173209
if (!sheetId || !isValidSheetId(sheetId)) {
174210
throw new Error('Valid Google Sheet ID required. Format: 1ayBgqVYpBirba1Scg8zgYlrmk4K61HrxgvrsYJO7G7Y');

0 commit comments

Comments
 (0)