remarkjs / react-markdown

Markdown component for React
https://remarkjs.github.io/react-markdown/
MIT License
13.29k stars 876 forks source link

Incorrect Languageless Code Block Rendering in Example #834

Closed JamesonRGrieve closed 5 months ago

JamesonRGrieve commented 5 months ago

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

ChristianMurphy commented 5 months ago

@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

github-actions[bot] commented 5 months ago

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:

Thanks, — bb

JamesonRGrieve commented 5 months ago

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!");
ChristianMurphy commented 5 months ago

@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

ChristianMurphy commented 5 months ago

My recommendations:

JamesonRGrieve commented 5 months ago

@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.

ChristianMurphy commented 5 months ago

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?

JamesonRGrieve commented 5 months ago

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.

ChristianMurphy commented 5 months ago

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

github-actions[bot] commented 5 months ago

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

github-actions[bot] commented 5 months ago

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

wooorm commented 5 months ago

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?