Skip to content

fix: a digit-led right sheet name is read as a sheet range end, not a range operand - #63

Open
gthb wants to merge 1 commit into
borgar:masterfrom
gthb:digit-led-range-operator-endpoint
Open

fix: a digit-led right sheet name is read as a sheet range end, not a range operand#63
gthb wants to merge 1 commit into
borgar:masterfrom
gthb:digit-led-range-operator-endpoint

Conversation

@gthb

@gthb gthb commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

Sheet1:1!A1 is read as the sheet range Sheet1..1, and fixRanges writes it back as 'Sheet1:1'!A1. This differs from Excel, which reads the unquoted pair as a range operation joining the defined name Sheet1 to '1'!A1, and stores it as Sheet1:'1'!A1.

Fix this so a digit-led right name makes the colon a range operator, with two exceptions that keep the sheet range:

  • the left name is an integer, which can't be the range operator's left operand: 1:5!A1
  • the whole prefix is quoted, whatever the right name: 'Sheet1:1'!A1

Both lexing paths get the rule, mergeRefTokens for tokenize and pExtendedContext for parseA1Ref, which had disagreed about Jan:2020plan!A1.

Test changes:

  • Two existing tests asserted the old reading on the premise that Excel "will parse and convert them to quoted"; Excel quotes only the endpoint.
  • A:8 and B:8 were dropped as duplicates of X:1.
  • Jan:2020plan!A1 is pinned as a known failure: until fix: a sheet name that begins with digits is lexed as a number and a name #62 lands, 2020plan lexes as the number 2020 and the name plan, so fixRanges never sees the endpoint as a prefix.

… range operand

Sheet1:1!A1 was read as the sheet range Sheet1..1, and fixRanges wrote it
back as 'Sheet1:1'!A1. Excel reads the unquoted pair as a range operation
joining the name Sheet1 to '1'!A1, and stores it as Sheet1:'1'!A1. The two
name different sheets, so the normalization changed the reference.

A digit-led right name now makes the colon a range operator, unless the
left name is an integer, which cannot be the range operator's left operand:
1:5!A1 is still a sheet range. Quoting the whole prefix, 'Sheet1:1'!A1, is
a sheet range whatever the right name is.

Both lexing paths needed the rule, mergeRefTokens for tokenize and
pExtendedContext for parseA1Ref, which had disagreed about Jan:2020plan!A1.

Two existing tests asserted the old reading on the premise that Excel "will
parse and convert them to quoted"; Excel quotes only the endpoint. The A:8
and B:8 cases were dropped as duplicates of X:1. Pinned as a known failure:
Jan:2020plan!A1 still lexes 2020plan as the number 2020 followed by the name
plan, so fixRanges cannot quote an endpoint it never sees as a prefix.
gthb added a commit to gthb/fx that referenced this pull request Sep 3, 2026
borgar#63 rewrites the body of the digit-leading test and appends a new block
right after it. Keeping master's title on that test, and putting this
branch's new test next to the quoted-RHS test it belongs with, lets the
two branches merge without conflict.

No change to what is asserted.
Comment thread lib/fixRanges.spec.ts
Comment on lines +145 to +146
test.fails('a digit-leading second sheet name goes to the range operator even when not all digits', () => {
// Fails today because 2020plan is lexed as the number 2020 followed by the name plan.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flips to passing when #62 is merged.

Suggested change
test.fails('a digit-leading second sheet name goes to the range operator even when not all digits', () => {
// Fails today because 2020plan is lexed as the number 2020 followed by the name plan.
test('a digit-leading second sheet name goes to the range operator even when not all digits', () => {

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant