ClosedXML / ClosedXML/ClosedXML.Parser
ToR1C1 emits negative offsets with culture NegativeSign (U+2212); ToA1 can't parse them — R1C1 round-trip fails under sv-SE/fi-FI/nb-NO
- Dominant language
- C#
- Stars
- 14
- Forks
- 8
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
`FormulaConverter.ToR1C1` serialises negative relative offsets using the current thread culture's `NumberFormat.NegativeSign`. Under cultures whose negative sign is the Unicode MINUS SIGN `U+2212` (sv-SE, fi-FI, nb-NO, …), it emits e.g. `RC[−1]` using `U+2212`. The R1C1 reader (`ToA1` → `CellFormulaR1C1`), however, only accepts the ASCII hyphen-minus `-` (`U+002D`), so it can't parse the string the writer just produced — the round-trip throws `ParsingException`.
## Minimal repro (ClosedXML.Parser 2.0.0)
```csharp
using System.Globalization;
using System.Threading;
using ClosedXML.Parser;
Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("sv-SE"); // NegativeSign = U+2212
// R1C1 form of "=A1/B1" stored in cell C1:
string r1c1 = FormulaConverter.ToR1C1("A1/B1", row: 1, col: 3);
// => "RC[−2]/RC[−1]" (the offsets use U+2212, not ASCII '-')
string a1 = FormulaConverter.ToA1(r1c1, row: 1, col: 3);
// throws ClosedXML.Parser.ParsingException:
// The formula `RC[−2]/RC[−1]` wasn't parsed correctly.
// The expression `RC` was parsed, but the rest `[−2]/RC[−1]` wasn't.
```
Under `en-US` / `InvariantCulture` the same code emits `RC[-2]/RC[-1]` with ASCII `-` and round-trips fine.
## Current vs expected
- **Current:** the R1C1 writer's output is culture-dependent and is not always re-readable by the R1C1 reader.
- **Expected:** R1C1 offsets are a serialization/machine format, so the writer should emit the invariant ASCII `-` regardless of thread culture (and/or the reader should accept `U+2212`). Either one makes the round-trip culture-independent.
## Real-world impact (via ClosedXML 0.105.0)
This surfaces when simply *loading* a workbook. ClosedXML expands shared formulas at load by converting the master to R1C1 and back to A1 per dependent cell, so loading any `.xlsx` containing a shared formula with a negative relative reference (e.g. `=B2-A2` filled down a column — very common) throws on a thread whose culture uses `U+2212`:
```
ClosedXML.Parser.ParsingException: The formula `RC[−2]/RC[−1]` wasn't parsed correctly...
at ClosedXML.Parser.FormulaConverter.ToA1(String formulaR1C1, Int32 row, Int32 col)
at ClosedXML.Excel.XLWorkbook.SetCellFormula(...)
at ClosedXML.Excel.XLWorkbook.LoadCell(...)
...
at ClosedXML.Excel.XLWorkbook..ctor(Stream stream)
```
## Environment
- ClosedXML.Parser 2.0.0 (didn't spot a related fix on `main`, though it looks mid-rewrite for 3.0)
- Reproduced through ClosedXML 0.105.0
- .NET 10
- Affected cultures: any whose `NumberFormat.NegativeSign` is `U+2212` — e.g. sv-SE, fi-FI, nb-NO
Happy to open a PR if a fix direction is welcome — my guess is emitting the invariant `-` in the R1C1 reference writer is the smaller change.
Contributor guide
No contributing guide indexed for this repository
Assessment
This issue has not been assessed yet.