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

1 participant