remarkjs/react-markdown

Incorrect Languageless Code Block Rendering in Example

JamesonRGrieve opened this issue · 12 comments

Initial checklist

Affected packages and versions

9.0.X

Link to runnable example

No response

Steps to reproduce

The code component in components no longer accepts inline as a prop. In your example, you are using className to detect whether the code is inline or a block. This produces the below behaviour when no language is provided which deviates from standard Markdown rendering.

Expected behavior

This line.

Should be rendered as above, in a block, even without providing a language. When a language is not provided, className comes through as undefined - the same as an inline code. This can be partially escaped by using .includes('\n') (not shown in the demo code), although that adds complexity.

Actual behavior

Instead, languageless code is rendered like this, even when enclosed in triple quotes when using the demo snippet. Snippet should be updated to include the necessary .includes('\n'), or inline prop should be brought back.

Runtime

Node v17

Package manager

npm 8

OS

Windows

Build and bundle tools

Next.js

@JamesonRGrieve sorry you ran into some confusion.
Which example are you referring to?
I assume https://github.com/remarkjs/react-markdown?tab=readme-ov-file#use-custom-components-syntax-highlight ?

When I copy it in with a code block with no language it works fine https://stackblitz.com/edit/github-6nizfy?file=src%2Fapp.tsx

Hi! Thanks for taking the time to contribute! This has been marked by a maintainer as needing a reproduction: It’s not yet clear whether this is a problem. Here are a couple tips:

  • Thoroughly document how to reproduce the problem, in steps or with code
  • Don’t link to your complete project: make the repro as tiny as possible, preferrably with only the problematic project in question
  • Make sure you’re on the latest versions of projects (and node/npm/yarn!)
  • The best issue report is a failing test proving it

Thanks,
— bb

Hi @ChristianMurphy

Try these two strings in your snippet:

const markdownSourceWorks = '```js\nconsole.log("Hello, World!");\n```';
const markdownSourceDoesntWork = '```\nconsole.log("Hello, World!");\n```';

The first one includes the js language, so it works fine. The second one does not, and it renders as inline despite being a multiline codeblock.

Rendered in GH for reference:

console.log("Hello, World!");
console.log("Hello, World!");

@JamesonRGrieve could you share a runnable example?
I tried the code you shared which is labeled doesn't work and it works in a sandbox https://stackblitz.com/edit/github-6nizfy-nbnz4p?file=src%2Fapp.tsx

My recommendations:

  • make sure you are running the latest version of react-markdown and react-syntax-highlighter
  • make sure you haven't made other unrelated changes which could break the rendering
  • make sure your style sheet isn't changing how code blocks are rendered

@ChristianMurphy It doesn't work in the link you shared either, as previously stated, it is rendering inline instead of as a block. See my previous comment, a multi-line triple-tick code block without a language should be rendered as a block not inline.

https://stackblitz.com/edit/github-6nizfy-xl25qk?file=src%2Fapp.tsx

Major release 8.X.X did not have this problem because of the inline prop. See here.

The logic in that demo doesn't work 100% correctly either, but simply using the inline prop makes it work properly.

It is still a block, it has the <pre> tag wrapping <code>.
But I think what you're getting at is you want it routed to the custom component?
Is that correct?

The entire purpose of the demo code is to separate inline from block rendering, is it not? Hence the use of the inline prop in 8.X.X documentation?

My request is for a simple way to do that again thay doesn't involve querying className for language AND checking for newline characters.

The old inline prop was concise and effective.

The entire purpose of the demo code is to separate inline from block rendering, is it not?

No.
The goal of the demo is to syntax highlight things that can be syntax highlighted.

Hence the use of the inline prop in 8.X.X documentation?

Also no.
The v8 example worked off a markdown syntax tree, that has a concept of inline vs block.
v9 works of the HTML tree, which differentiates using the pre tag or not using the pre tag.

My request is for a simple way to do that again thay doesn't involve querying className for language AND checking for newline characters.

That can be done with a remark plugin which adds an HTML attribute which can be keyed off of.


Taking a step back.
The readme provides an example of syntax highlighting known languages.
You want a different setup with syntax highlighting/blocks for unknown languages.
That is fine, but also not a bug.
I'm closing this as a question, but happy to assist here or preferably in a discussion https://github.com/orgs/remarkjs/discussions

Hi! This was closed. Team: If this was fixed, please add phase/solved. Otherwise, please add one of the no/* labels.

Hi team! I don’t know what’s up as there’s no phase label. Please add one so I know where it’s at.

Thanks,
— bb

code in HTML is “inline”. pre in HTML is “block”. These “inline” vs “block” concepts have something to do with CSS. They are defaults. You can change the CSS.

Markdown has different code things. One generates pre and code, the other only code.
The first also optionally allows a programming language.

Markdown also allows embedded HTML. With react, you’d need to configure that (see the readme), but it’s very much possible to use this project with <code class="language-js"> without a <pre> around it.

The example here is about syntax highlighting. It makes sense that you highlight when you know the language.

You are conflating things that should be separated: whether something is syntax highlighted should not relate to whether something is displayed in CSS as “block” or not.

checking for newline characters.

? you can put newline characters in “inline” code?