Skip to content

[tsdoc] Preserve line breaks before inline nodes in TSDocEmitter - #494

Merged
Ian Clanton-Thuon (iclanton) merged 1 commit into
microsoft:mainfrom
spencerbeggs:fix/issue-493
Sep 29, 2026
Merged

Ian Clanton-Thuon (iclanton) merged 1 commit into
microsoft:mainfrom
spencerbeggs:fix/issue-493

Conversation

@spencerbeggs

Copy link
Copy Markdown
Contributor

Summary

Fixes #493.

Since 0.17.0, TSDocEmitter drops a line break that comes immediately before an inline node (code span, {@link} tag, HTML element) and puts no space in its place, so the adjacent words are joined:

Input Before After
policy is⏎`"fail"`. policy is`"fail"`. policy is⏎`"fail"`.
see the⏎{@link Foo} thing. see the{@link Foo} thing. see the⏎{@link Foo} thing.
{@link Foo}⏎`` x `` end. {@link Foo}`x` end. {@link Foo}⏎`x` end.

API Extractor writes this output to the docComment field of .api.json, so the damaged text reaches every downstream consumer of the model.

Cause

TrimSpacesTransform.pushAccumulatedText() splits the accumulated text on \n and emits a DocSoftBreak only before a nonempty line. When the text ends in a soft break ("policy is\n"), the trailing empty line is skipped, and the soft break goes with it. The inline node is then pushed directly after the text. Before #443, soft breaks were emitted as spaces, which hid the problem.

Fix

pushAccumulatedText() now takes a followedByInlineNode flag. When the text is flushed before an inline node and ends with a line break, the trailing DocSoftBreak is kept. When the text is flushed at the end of a paragraph, the trailing break is still dropped as before, so DocNodeTransforms.trimSpacesInParagraph() returns the same result in every other case. The existing DocNodeTransforms snapshot does not change.

Testing

  • Added 05 Emit soft breaks before inline nodes to TSDocEmitter.test.ts. It covers a line break before a code span, a {@link} tag, an HTML element, and between two inline nodes. It also covers the two cases that already worked (a break between plain words and a break after a code span) so they stay fixed. The test fails on main and passes with this change.
  • rush build --to @microsoft/tsdoc: all 17 test suites pass.
  • Ran the repro script from TSDocEmitter 0.17.0 drops the line break before a code span or {@link}, joining words #493 against the built output; all four cases now match the 0.16.0 wording, with the line breaks kept.
  • Added a patch change file for @microsoft/tsdoc.

Signed-off-by: C. Spencer Beggs spencer@beggs.codes

Since 0.17.0, TrimSpacesTransform dropped a soft break that immediately
preceded an inline node such as a code span, {@link} tag, or HTML element.
pushAccumulatedText() only emitted a DocSoftBreak ahead of a nonempty line,
so text ending in a line break lost it and was joined to the following node
(e.g. "policy is`fail`").

Emit the trailing soft break when the accumulated text is flushed ahead of
an inline node. The trailing break at the end of a paragraph is still
discarded, so the output of trimSpacesInParagraph() is otherwise unchanged.

Fixes microsoft#493

Signed-off-by: C. Spencer Beggs <spencer@beggs.codes>
@iclanton
Ian Clanton-Thuon (iclanton) merged commit 55f0c87 into microsoft:main Sep 29, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

TSDocEmitter 0.17.0 drops the line break before a code span or {@link}, joining words

2 participants