extractTextOnly (google-docs-addon/Code.gs:200) accumulates document text with no separator between children:
const childText = child.asText ? child.asText() : null;
if (childText) {
text += childText.getText();
}
A paragraph's getText() carries no trailing newline, so real paragraph breaks disappear from the string. googleDocsEditorAPI.getParagraphs then reconstructs paragraphs by splitting that text on \n:
const text = `${ctx.beforeCursor || ''}${ctx.selectedText || ''}${ctx.afterCursor || ''}`;
return text.split('\n');
The result is inverted: it splits at soft line breaks inside a paragraph (which do survive as \n) and joins across the real paragraph boundaries.
Impact
Paragraphs are the coordinate system for the whole My Words feature — view's [n] numbering, insert/move targeting, and every ParagraphSplice. On Google Docs that coordinate system does not correspond to the document.
It also corrupts the word-bank corpus independently of any editing: with no separator, the last word of one paragraph and the first word of the next fuse into a single token (…decidedThe next…), which is a word the writer never wrote, while their real boundary adjacency is lost.
Anything reading getDocText for context — not just My Words — sees the same run-together text.
Fix
Join children with \n in extractTextOnly, and keep getParagraphs's split in agreement with it. Worth deciding at the same time whether soft line breaks should be paragraph boundaries for view purposes (probably not) — if not, they need distinguishing from real breaks rather than both arriving as \n.
Confidence
Read from source; not executed. Apps Script can't be run from the dev container, so this wants confirming in a live document before or alongside the fix — including whether Element.asText() on a PARAGRAPH child succeeds or throws into the catch (e) { continue; } above it, which would mean whole paragraphs are being skipped rather than merely joined.
Found while making text matching typography-tolerant (#587); not caused by it.
extractTextOnly(google-docs-addon/Code.gs:200) accumulates document text with no separator between children:A paragraph's
getText()carries no trailing newline, so real paragraph breaks disappear from the string.googleDocsEditorAPI.getParagraphsthen reconstructs paragraphs by splitting that text on\n:The result is inverted: it splits at soft line breaks inside a paragraph (which do survive as
\n) and joins across the real paragraph boundaries.Impact
Paragraphs are the coordinate system for the whole My Words feature —
view's[n]numbering,insert/movetargeting, and everyParagraphSplice. On Google Docs that coordinate system does not correspond to the document.It also corrupts the word-bank corpus independently of any editing: with no separator, the last word of one paragraph and the first word of the next fuse into a single token (
…decidedThe next…), which is a word the writer never wrote, while their real boundary adjacency is lost.Anything reading
getDocTextfor context — not just My Words — sees the same run-together text.Fix
Join children with
\ninextractTextOnly, and keepgetParagraphs's split in agreement with it. Worth deciding at the same time whether soft line breaks should be paragraph boundaries forviewpurposes (probably not) — if not, they need distinguishing from real breaks rather than both arriving as\n.Confidence
Read from source; not executed. Apps Script can't be run from the dev container, so this wants confirming in a live document before or alongside the fix — including whether
Element.asText()on aPARAGRAPHchild succeeds or throws into thecatch (e) { continue; }above it, which would mean whole paragraphs are being skipped rather than merely joined.Found while making text matching typography-tolerant (#587); not caused by it.