Skip to content

fix: do not add a newline to an empty code block - #4073

Open
Kjubikstronk wants to merge 1 commit into
markedjs:masterfrom
Kjubikstronk:fix-empty-code-block-newline
Open

fix: do not add a newline to an empty code block#4073
Kjubikstronk wants to merge 1 commit into
markedjs:masterfrom
Kjubikstronk:fix-empty-code-block-newline

Conversation

@Kjubikstronk

Copy link
Copy Markdown

Marked version: 18.0.11 (53cb13f)

Markdown flavor: CommonMark

Description

Renderer.code appends a newline unconditionally:

const code = text.replace(other.endingNewline, '') + '\n';

For a code block with no content that turns '' into '\n', so an empty fence renders as <pre><code>\n</code></pre> instead of <pre><code></code></pre>.

The lexer is not involved. new Lexer({gfm: false}).lex('```\n') already gives text: ''.

Expectation


renders `<pre><code></code></pre>`

## Result

renders `<pre><code>\n</code></pre>`

## What was attempted

This fixes four CommonMark examples, all empty fenced code blocks: 126 (unclosed fence), 130 (closed fence), 144 (empty fence with an info string) and 237 (empty fence inside a block quote). I diffed the exact-match failure set across the whole spec before and after: those four move to passing and nothing else changes, in both the CommonMark and GFM runs.

Worth flagging why this went unnoticed, since it applies to more than this bug. `htmlIsEqual` builds `@markedjs/html-differ` with only `ignoreSelfClosingSlash` and `ignoreComments`, so `ignoreWhitespaces` stays at its default of `true`. Whitespace inside `pre`/`code` is significant, so all four of these were already reported as passing and carry no `shouldFail` flag. That also means the spec suite cannot protect this fix, which is why the tests below assert exact output instead.

There is a second, separate case the same blind spot hides: example 318, a fenced block in a list item, expects `b\n\n\n` and gets `b\n\n`. That one is a lexer issue rather than a renderer one, since the code token already comes out as `b\n\n`, so I have left it out of this PR.

## Contributor

- [x] Test(s) exist to ensure functionality and minimize regression (if no tests added, list tests covering this PR); or,
- [ ] no tests required for this PR.
- [ ] If submitting new feature, it has been documented in the appropriate places.

Four tests in `test/unit/marked.test.js` under `empty code block`. Three of them fail without the change and one non-empty case acts as a control. Full spec suite (1789) and unit suite (195) pass.

## Committer

In most cases, this should be a different person than the contributor.

- [ ] CI is green (no forced merge required).
- [ ] Squash and Merge PR following [conventional commit guidelines](https://www.conventionalcommits.org/).

Renderer.code appended a newline unconditionally, so a code block with no
content rendered as <pre><code>\n</code></pre> instead of
<pre><code></code></pre>.

This fixes CommonMark examples 126, 130, 144 and 237. The spec suite did not
catch it because htmlIsEqual leaves html-differ's ignoreWhitespaces at its
default of true, and whitespace inside pre/code is significant, so all four
were already reported as passing.
@vercel

vercel Bot commented Aug 30, 2026

Copy link
Copy Markdown

@Kjubikstronk is attempting to deploy a commit to the MarkedJS Team on Vercel.

A member of the Team first needs to authorize it.

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.

1 participant