You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
TextRun#text= does nothing on a run with more than one w:t #197
TextRun#text= only writes when the run has exactly one w:t, or none (it creates one in that case). If the run has two or more, it silently does nothing:
# lib/docx/containers/text_run.rbdeftext=(content)if@text_nodes.size == 1@text_nodes.first.content=contentelsif@text_nodes.empty?
...
end# 2+ text nodes: no-opreset_textend
Such runs are valid and common:
LibreOffice and macOS textutil keep one run with w:t, w:br/w:tab, w:t.
A hyperlink with several runs is wrapped as a single TextRun (w:t|w:r/w:t).
This also affects Paragraph#text= (single-run paragraphs) and Bookmark#insert_text_before/after. It was the main cause of #187. That issue is being fixed separately by making Paragraph#substitute work on w:t nodes, so it no longer depends on text=.
Proposed behavior: write the whole content into the first w:t and empty the others. A plain string can't say where the breaks and tabs inside the run should go, so they end up after the text. Document that, and point users to Paragraph#substitute when they need breaks to stay in place.
Plan update: I'm going with a slightly different fix from the one proposed above.
TextRun#text= will replace the run's text from its first w:t through its last one. The new text goes into the first w:t. The other w:t, and any w:br / w:tab / w:cr between them, are removed. Breaks outside that range stay, for example a page break (<w:br w:type="page"/>) at the end of the run, as does everything else (w:rPr, drawings, fields).
I chose this over "fill the first w:t and leave the breaks after the text" because #text never includes breaks or tabs. A plain string can't say where they belong, so keeping them would only move them to the end of the line. With this approach the run reads and renders as exactly what was assigned. It also matches Paragraph#text=, which already replaces all runs when a paragraph has more than one. Runs with a single w:t behave as before.
Bookmark#insert_text_before/after currently use run.text = .... With the change above, that would delete the adjacent run's line breaks just to add a few characters. So they will write into the w:t right next to the bookmark instead: the end of the preceding run, or the start of the following one. That leaves the rest of that run as it is. Today these calls do nothing on such runs, so this fixes them too.
For edits that need line breaks to stay in place, Paragraph#substitute (#199) is the right tool.
Activity
satoryu commentedon Oct 17, 2026
Plan update: I'm going with a slightly different fix from the one proposed above.
TextRun#text=will replace the run's text from its firstw:tthrough its last one. The new text goes into the firstw:t. The otherw:t, and anyw:br/w:tab/w:crbetween them, are removed. Breaks outside that range stay, for example a page break (<w:br w:type="page"/>) at the end of the run, as does everything else (w:rPr, drawings, fields).I chose this over "fill the first
w:tand leave the breaks after the text" because#textnever includes breaks or tabs. A plain string can't say where they belong, so keeping them would only move them to the end of the line. With this approach the run reads and renders as exactly what was assigned. It also matchesParagraph#text=, which already replaces all runs when a paragraph has more than one. Runs with a singlew:tbehave as before.Bookmark#insert_text_before/aftercurrently userun.text = .... With the change above, that would delete the adjacent run's line breaks just to add a few characters. So they will write into thew:tright next to the bookmark instead: the end of the preceding run, or the start of the following one. That leaves the rest of that run as it is. Today these calls do nothing on such runs, so this fixes them too.For edits that need line breaks to stay in place,
Paragraph#substitute(#199) is the right tool.