parse static method

List<List<String>> parse(
  1. String content, {
  2. String? delimiter,
})

Parses CSV / TSV text content into a list of row cells: List<List<String>>.

Implementation

static List<List<String>> parse(String content, {String? delimiter}) {
  if (content.isEmpty) return [];

  // Strip BOM if present
  String text = content;
  if (text.startsWith('\uFEFF')) {
    text = text.substring(1);
  }

  final effectiveDelimiter = delimiter ?? detectDelimiter(text);
  final delimiterCode = effectiveDelimiter.codeUnitAt(0);

  final rows = <List<String>>[];
  final currentRow = <String>[];
  final currentCell = StringBuffer();

  bool insideQuote = false;
  int i = 0;
  final length = text.length;

  while (i < length) {
    final charCode = text.codeUnitAt(i);

    if (charCode == 34) {
      // Double quote "
      if (insideQuote) {
        // Check for escaped quote ""
        if (i + 1 < length && text.codeUnitAt(i + 1) == 34) {
          currentCell.write('"');
          i += 2;
          continue;
        } else {
          insideQuote = false;
        }
      } else {
        insideQuote = true;
      }
    } else if (!insideQuote && charCode == delimiterCode) {
      // Delimiter reached
      currentRow.add(currentCell.toString().trim());
      currentCell.clear();
    } else if (!insideQuote && (charCode == 10 || charCode == 13)) {
      // End of line (\n or \r)
      currentRow.add(currentCell.toString().trim());
      currentCell.clear();

      // Check for CRLF \r\n
      if (charCode == 13 && i + 1 < length && text.codeUnitAt(i + 1) == 10) {
        i++;
      }

      // Only add non-empty rows
      if (currentRow.any((c) => c.isNotEmpty)) {
        rows.add(List<String>.from(currentRow));
      }
      currentRow.clear();
    } else {
      currentCell.writeCharCode(charCode);
    }

    i++;
  }

  // Add last cell and row if any content remains
  if (currentCell.isNotEmpty || currentRow.isNotEmpty) {
    currentRow.add(currentCell.toString().trim());
    if (currentRow.any((c) => c.isNotEmpty)) {
      rows.add(List<String>.from(currentRow));
    }
  }

  return rows;
}