Sep 0.7.0 - CSV Escape Support

Sep 0.7.0 has just been released with the following notable changes:

  • 🎁 Add SepWriterOptions.Escape for escape support
  • 🎛️ Add SepWriterOptions.DisableColCountCheck/ColNotSetOption

See v0.7.0 release for all changes and Sep README on GitHub for full details. Below I’ll briefly go over these changes. Escape support is one of the last major features that was missing in Sep compared to other libraries.

Escape Support

Sep now supports escaping by the Escape property on SepWriterOptions which can be set like:

1
2
using var writer = Sep.Writer(o => 
    o with { Escape = true }).ToText();

The result of escaping is shown below in comparison to other popular CSV libraries. All basically do the same, except CsvHelper which also escapes spaces despite this not being necessary.

Input CsvHelper Sylvan Sep¹
· "·" · ·
a a a a
; ";" ";" ";"
, , , ,
" """" """" """"
\r "\r" "\r" "\r"
\n "\n" "\n" "\n"
a"aa"aaa "a""aa""aaa" "a""aa""aaa" "a""aa""aaa"
a;aa;aaa "a;aa;aaa" "a;aa;aaa" "a;aa;aaa"

Separator/delimiter is set to semi-colon ; (default for Sep)

· (middle dot) is whitespace to make this visible

\r, \n are carriage return and line feed special characters to make these visible

¹ Sep with Escape = true in SepWriterOptions

SepWriterOptions.DisableColCountCheck/ColNotSetOption

These new options are for allowing writing CSV files with different columns per row and defining how to handle columns not set. Below is just one example of how this could be used.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
var options = new SepWriterOptions
{
    WriteHeader = false,
    DisableColCountCheck = true,
    ColNotSetOption = SepColNotSetOption.Skip,
};
using var writer = options.ToText();
{
    using var row = writer.NewRow();
    row["A"].Set("R1C1");
    row["B"].Set("R1C2");

}
{
    using var row = writer.NewRow();
    row[0].Set("R2C1");
    row[1].Set("R2C2");
    row[2].Set("R2C3");
    row[3].Set("R2C4");
}
{
    using var row = writer.NewRow();
    row["A"].Set("R3C1");
    row[2].Set("R3C3");
    row[1].Set("R3C2");
}
var expected =
@"R1C1;R1C2
R2C1;R2C2;R2C3;R2C4
R3C1;R3C2;R3C3
";
Assert.AreEqual(expected, writer.ToString());

Note how that each row has different number of columns and that any column not set is skipped. There is also an option for writing an empty column if not set, for example.

For more examples see tests on GitHub.

That’s all!

2025.01.12