Skip to content

PadDecimals doesn't pad whole-number coordinates that had a decimal point in the source #217

Description

@webdevred

Problem

scientificToText (src/JbeamEdit/Core/Node.hs) reconstructs number text from the parsed Scientific value, not from the original source text. For whole-number values it drops the decimal point entirely, 12.0 and 12 both become "12". applyDecimalPadding (src/JbeamEdit/Formatting/Rules.hs) only pads text that already contains a ., so by the time it runs, the information needed to make the right call (did the source actually have a decimal point) is already gone.

This means PadDecimals can't distinguish a coordinate written as 12 from one written as 12.0, both come out unpadded, even though JBFL_DOCS.md explicitly documents 12.0 -> 12.00000 (with PadDecimals: 3, PadAmount: 8) as expected behavior.

Repro

Input:

{"main":{"nodes":[["n1", 12.0, 3.14, 0.5]]}}

Rule:

.*.nodes[*][*] { PadDecimals: 3; PadAmount: 8; }

Result:

["n1",     12,       3.140,    0.500   ]

3.14 and 0.5 pad correctly, since scientificToText's reconstructed text already has a dot for those. 12.0 does not, contradicting the docs' own example.

Root cause

NumberValue already carries the original source text in nvText (used when PreserveNumberFormat: true is set), so the "did the source have a decimal point" signal exists, it's just not consulted on the default (non-preserve) formatting path. formatScalarNode picks nvText vs scientificToText (nvValue nv) based on PreserveNumberFormat, and only the latter feeds into applyDecimalPadding.

Related but distinct

Not the same bug as the one fixed in b002458 (which added the T.any (== '.') node guard to applyDecimalPadding, preventing it from corrupting dot-less integers by over-padding them, e.g. 0 -> 000). That fix is correct and should stay as is. This issue is the opposite direction: values that did have a decimal point in the source under-pad, because the dot-presence signal is discarded before that guard ever sees it.

Suggested direction

Base the padding decision on whether the source had a decimal point (derivable from nvText), not on whether the value-reconstructed default text happens to contain one. A value written as a plain integer in the source (no dot) should stay a plain integer, PadDecimals shouldn't invent a decimal point that wasn't there. A value written with a decimal point should get padded even if it's numerically a whole number.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions