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
- 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: [] });
},
},
},
});
- 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:
- Any run excluded this way is never spell-checked, whatever it contains.
- 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-start → data-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.
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: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 resultingProofingIssuepaints 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
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 readv2-proofing:<n>:<blockId>Browser
Chrome
Additional context
Related, and possibly intended: text inside
.sd-mathis painted but absent from the segment. A paragraph readingreaches the provider as
Two consequences:
Investigation or proposed fix
The segment text follows the painted lines rather than the model. Each line is a separate
.superdoc-lineelement, 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.data-pm-start→data-pm-end…timulant(space kept)…s that involve(no space)…ith increased(space kept)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.