Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

fix: keep backslash-space hard line break (CommonMark 6.7)#1185

Merged
puzrin merged 1 commit into
markdown-it:mastermarkdown-it/markdown-it:masterfrom
spokodev:fix/backslash-space-hard-breakspokodev/markdown-it:fix/backslash-space-hard-breakCopy head branch name to clipboard
Jul 1, 2026
Merged

fix: keep backslash-space hard line break (CommonMark 6.7)#1185
puzrin merged 1 commit into
markdown-it:mastermarkdown-it/markdown-it:masterfrom
spokodev:fix/backslash-space-hard-breakspokodev/markdown-it:fix/backslash-space-hard-breakCopy head branch name to clipboard

Conversation

@spokodev

Copy link
Copy Markdown
Contributor

Problem

A backslash followed by two trailing spaces before a newline should emit a hard line break, but markdown-it downgrades it to a soft break and leaves a stray space.

Repro:

md.render('a\\  \nb')

Expected (matches the CommonMark 0.31.2 reference renderer):

<p>a\<br>
b</p>

Actual on current master:

<p>a\
b</p>

The backslash is kept literal (correct), but the hard line break is gone and a space leaks into the output.

Why

Per CommonMark 0.31.2:

  • Section 6.1: a backslash before a space is a literal backslash; the space is not consumed.
  • Section 6.7: a line ending preceded by two or more spaces is a hard line break.

In lib/rules_inline/escape.mjs, when \ is not followed by a newline, the rule builds a text_special token whose content is the backslash plus the following character, and advances past that character. When the following character is a space, that space gets absorbed into the escape token. lib/rules_inline/newline.mjs then inspects state.pending for trailing spaces and finds only one, so it takes the soft-break branch.

Fix

Special-case a space after the backslash: push a text_special token holding just the literal backslash and leave state.pos pointing at the space, so the space stays in the text stream and two-space hard-break detection still fires.

Controls verified unchanged: a \nb (hard break), a\\\nb (backslash before newline, hard break), x\ y (mid-line literal backslash + space), a\ \nb (single trailing space stays a soft break).

Tests

Added a fixture to test/fixtures/markdown-it/commonmark_extras.txt asserting a\ \nb renders the hard line break. It fails on master (actual <p>a\ \nb</p>) and passes with this change. The full suite is green, including all 652 CommonMark spec examples.

A backslash followed by a space was baking that space into the escape
token, so the newline rule saw only one trailing space and emitted a
soft break instead of the mandated hard line break.

Per CommonMark 0.31.2 section 6.1, a backslash before a space is a
literal backslash and the space is not consumed. Leaving the space in
the text stream lets section 6.7 two-space hard-break detection fire.

Input `a\  \nb` (backslash + two trailing spaces) now renders
`<p>a\<br>\nb</p>` instead of `<p>a\ \nb</p>`.
@puzrin

puzrin commented Jun 29, 2026

Copy link
Copy Markdown
Member

@puzrin puzrin closed this Jun 29, 2026
@spokodev

spokodev commented Jul 1, 2026

Copy link
Copy Markdown
Contributor Author

Thanks for checking. The demo link in your reply uses two backslashes (a\\), where the first backslash escapes the second. That leaves a single literal backslash with both trailing spaces intact, so the hard break renders correctly and the problem is hidden.

The failing case is a single backslash followed by two trailing spaces. On current master (0fbb18b) with your exact demo settings:

md({ linkify: true, typographer: true }).render('a\\  \ns')
// the JS string is: a, one backslash, two spaces, newline, s

Actual:

<p>a\ 
s</p>

Expected (CommonMark 0.31.2 reference renderer):

<p>a\<br>
s</p>

The two trailing spaces collapse to a soft break and a stray space leaks in after the backslash, instead of the hard line break. One-click repro with the single-backslash input: https://markdown-it.github.io/#md3=%7B%22source%22%3A%22a%5C%5C%20%20%5Cns%22%2C%22defaults%22%3A%7B%22html%22%3Afalse%2C%22xhtmlOut%22%3Afalse%2C%22breaks%22%3Afalse%2C%22langPrefix%22%3A%22language-%22%2C%22linkify%22%3Atrue%2C%22typographer%22%3Atrue%2C%22_highlight%22%3Atrue%2C%22_strict%22%3Afalse%2C%22_view%22%3A%22src%22%7D%7D

Root cause is unchanged from the PR: in lib/rules_inline/escape.mjs a backslash before a space builds a text_special token that also consumes the following space, so lib/rules_inline/newline.mjs sees only one trailing space and takes the soft-break branch. I can rebase and re-run the suite if you would like to take another look.

@puzrin puzrin reopened this Jul 1, 2026
@puzrin
puzrin merged commit 56c2404 into markdown-it:master Jul 1, 2026
1 check passed
@puzrin

puzrin commented Jul 1, 2026

Copy link
Copy Markdown
Member

Got it. Thank you.

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.

2 participants

Morty Proxy This is a proxified and sanitized view of the page, visit original site.