Add lib/csv.claro from Claro v1.17.26 zip

This commit is contained in:
RayPals
2026-06-01 00:55:41 +02:00
parent c4cc4e4990
commit 6dab515b3f
+121
View File
@@ -0,0 +1,121 @@
# Claro Standard Library: csv (RFC4180-ish)
# Use: IMPORT "lib/csv.claro" AS csv
# read(text, sep) -> LIST of rows (each row is LIST of fields)
# write(rows, sep) -> TEXT (quotes fields when needed)
#
# Supports:
# - quoted fields: "a,b"
# - escaped quotes inside quoted fields: ""
# - newlines inside quoted fields
EXPORT ALL
TEACH _needs_quote TAKES field, sep
FIND sep IN field AS p1
FIND "\"\n\"" IN field AS p2
FIND "\""\r\"" IN field AS p3
FIND "\""\"\"" IN field AS p4
IF (p1 != 0) OR (p2 != 0) OR (p3 != 0) OR (p4 != 0)
RETURN YES
ENDIF
RETURN NO
LEARNED
TEACH _escape_quotes TAKES field
# Replace " with ""
SET out TO ""
LENGTH field AS L
FOR i FROM 1 TO L
SUBSTR field FROM i LEN 1 AS ch
IF ch = "\""\"\""
SET out TO out + "\""\"\"" + "\""\"\""
ELSE
SET out TO out + ch
ENDIF
DONE
RETURN out
LEARNED
TEACH write TAKES rows, sep
SET out TO ""
FOR EACH row IN rows
SET line TO ""
SET first TO YES
FOR EACH field IN row
SET f TO field
CALL _needs_quote WITH f, sep
IF RESULT = YES
CALL _escape_quotes WITH f
SET f TO "\""\"\"" + RESULT + "\""\"\""
ENDIF
IF first = YES
SET line TO f
SET first TO NO
ELSE
SET line TO line + sep + f
ENDIF
DONE
SET out TO out + line + "\n"
DONE
RETURN out
LEARNED
TEACH read TAKES text, sep
# State machine CSV parser
SET rows TO LIST
SET row TO LIST
SET cur TO ""
SET inq TO NO
LENGTH text AS L
FOR i FROM 1 TO L
SUBSTR text FROM i LEN 1 AS ch
IF inq = YES
IF ch = "\""\"\""
# quote or escaped quote?
IF i < L
SUBSTR text FROM (i + 1) LEN 1 AS nx
IF nx = "\""\"\""
SET cur TO cur + "\""\"\""
SET i TO (i + 1)
ELSE
SET inq TO NO
ENDIF
ELSE
SET inq TO NO
ENDIF
ELSE
SET cur TO cur + ch
ENDIF
ELSE
IF ch = "\""\"\""
SET inq TO YES
ELSE
IF ch = sep
ADD cur TO row
SET cur TO ""
ELSE
IF ch = "\n"
ADD cur TO row
ADD row TO rows
SET row TO LIST
SET cur TO ""
ELSE
IF ch != "\r"
SET cur TO cur + ch
ENDIF
ENDIF
ENDIF
ENDIF
ENDIF
DONE
# final field / row
ADD cur TO row
# avoid adding a trailing empty row from final newline
IF (L > 0)
ADD row TO rows
ENDIF
RETURN rows
LEARNED