Skip to content

Proofing segments omit the space consumed by a line wrap, so two correct words are reported as one misspelling #4001

Description

@KevinHzq

What happened?

ProofingProvider.check() receives segment text in which the space consumed by a line wrap is missing. The last word of one line and the first word of the next arrive as one token:

…as discrete problems thereforeobscures the process connecting…

Expected: each segment's text matches the paragraph text.
Actual: at each wrap whose space the painter dropped, the two words are adjacent with no separator.

The document itself is correct. The same paragraph read through the document API (doc.getText({})) is …problems therefore obscures the process…, and it exports correctly. Only the text passed to the provider loses the character.

A dictionary rejects thereforeobscures, and the resulting ProofingIssue paints as two underlines: one on the word ending the line, one on the word starting the next. Both words are spelled correctly.

A provider cannot correct this from the text alone, because a glued token is indistinguishable from a genuine missing space typed by the author.

Steps to reproduce

  1. Load a .docx containing a paragraph long enough to wrap, with a provider that only logs:
new SuperDoc({
  selector: '#editor',
  documents: [{ id: 'doc', type: 'docx', data: file }],
  pagination: true,
  proofing: {
    enabled: true,
    defaultLanguage: 'en-US',
    provider: {
      id: 'log-only',
      getCapabilities: () => ({ issueKinds: ['spelling'] }),
      check: ({ segments }) => {
        console.log(segments.map((s) => s.text));
        return Promise.resolve({ issues: [] });
      },
    },
  },
});
  1. Compare a logged segment against the same paragraph from doc.getText({}).

Frequency: in a 27-page manuscript, 61 wraps across the 538 checked blocks arrived glued, producing 27 distinct non-words (cocaineor, significantlymodify, implicationsfor, participantsaged, unintentionalinjuries, and others).

SuperDoc version

2.12.0 (@superdoc/docx-engine 0.11.0), pagination: true — v2 layout; segment ids read v2-proofing:<n>:<blockId>

Browser

Chrome

Additional context

Related, and possibly intended: text inside .sd-math is painted but absent from the segment. A paragraph reading

…on the multiplicative scale (F (2, 107.04) = 2.62, p = 0.077).

reaches the provider as

…on the multiplicative scale ((2, 107.04) = 2.62, = 0.077).

Two consequences:

  1. Any run excluded this way is never spell-checked, whatever it contains.
  2. A segment is not the concatenation of its painted lines, so a consumer working around the wrap bug cannot align a segment against the page end to end and has to anchor each line boundary separately.

Investigation or proposed fix

The segment text follows the painted lines rather than the model. Each line is a separate .superdoc-line element, and at an affected wrap the consumed space is painted in neither line: it falls into a one-position gap between the two lines' data-pm-* ranges.

line data-pm-startdata-pm-end line text ends next line starts at
1 21305 → 21391 …timulant (space kept) 21391 (contiguous)
2 21391 → 21493 …s that involve (no space) 21494 (pm 21493 painted nowhere)
3 21494 → 21587 …ith increased (space kept) 21587 (contiguous)

Line 2's trailing space is the character the wrap consumed, and it is absent from the segment exactly as it is absent from the paint. Where the painter keeps the trailing space (lines 1 and 3), the segment keeps it.

Building segment text from the block's model text, or re-inserting the whitespace consumed by the wrap, would resolve this.

Activity

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

Metadata

Metadata

Assignees

Labels

status: doneAll linked engineering blockers are marked Done.

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions