Skip to content

NominalWordWrap breaks lines at no-break spaces and rewrites them as plain spaces: "Total: 100 kg" wraps to "Total: 100" / "kg" #150

Description

@matt-edmondson

What's wrong

BuildAtoms in Extensions/StringExtensions.cs (line 341 at 197654d) splits each segment with segment.Split((char[]?)null, StringSplitOptions.RemoveEmptyEntries). A null separator splits on every char.IsWhiteSpace character, and that set includes the non-breaking spaces U+00A0 (no-break space), U+2007 (figure space) and U+202F (narrow no-break space). Each one becomes an ordinary word boundary, and the output then joins words back together with ' '.

The result is that the wrapper breaks at exactly the places the author marked as unbreakable. It also rewrites the no-break character as U+0020 when no wrap happens at all.

Reproduction (observed on net10.0)

"Total: 100 kg".NominalWordWrap(10f, 1f);
// actual:   ["Total: 100", "kg"]
// expected: ["Total:", "100 kg"]

"a b".NominalWordWrap(100f, 1f);
// actual:   ["a b"]        (U+0020)
// expected: ["a b"]   (U+00A0 kept)

Why it matters

No-break spaces are the standard way to keep a number with its unit, "Mr. Smith" together, or French punctuation spacing ("Bonjour !"). A caller who wraps localized or typographically prepared text gets a unit stranded on its own line. The text also no longer round-trips, even when it fits on one line. The docs only mention collapsing runs of whitespace; they say nothing about non-breaking characters becoming break points.

Suggested fix / acceptance criteria

  • Split only on whitespace that allows a break: char.IsWhiteSpace(c) && c is not ' ' and not ' ' and not ' '. A small manual tokenizer or a precomputed separator array would do it.
  • Keep U+00A0 / U+2007 / U+202F inside the atom text so they are emitted unchanged.
  • Add regression tests for both cases above.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions