Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MDX: support Markdown inside JSX blocks #7041

Closed
trevordmiller opened this issue Nov 23, 2019 · 35 comments
Closed

MDX: support Markdown inside JSX blocks #7041

trevordmiller opened this issue Nov 23, 2019 · 35 comments
Labels
help wanted We're a small group who can't get to every issue promptly. We’d appreciate help fixing this issue! lang:mdx Issues affecting the MDX extension to Markdown (not general Markdown issues) type:bug Issues identifying ugly output, or a defect in the program

Comments

@trevordmiller
Copy link

trevordmiller commented Nov 23, 2019

According to the commonmark spec, it seems that the example below is valid MDX. However, Prettier is throwing an error.

Prettier 1.19.1
Playground link

--parser mdx

Input:

<CodeSurfer>

```js
console.log(1);
```

</CodeSurfer>

Output:

SyntaxError: Unexpected closing tag "CodeSurfer". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags (1:1)
> 1 | <CodeSurfer>
    | ^
  2 | 
  3 | ```js
  4 | console.log(1);

Expected behavior:

If this is valid MDX it should parse it and format it without an error.

@thorn0
Copy link
Member

thorn0 commented Nov 24, 2019

What did the MDX spec say about this?

@thorn0 thorn0 added the lang:mdx Issues affecting the MDX extension to Markdown (not general Markdown issues) label Nov 24, 2019
@karlhorky
Copy link
Contributor

karlhorky commented Nov 24, 2019

Hm, there is no mention of it from my quick glance at https://github.com/mdx-js/specification, but in the issues there is mdx-js/specification#11, which mentions:

Question:

Is it possible to nest markdown within a JSX tag?

Answer:

This will work if you add newlines between the JSX and Markdown tags

<Reference title='JS Reference'>

My explanation of `this` 

</Reference>

It seems that in Prettier, this example does not work.

Furthermore, it seems as if nesting other Markdown after newlines generally does not work:

<div>

Some `code`

</div>

Error:

SyntaxError: Unexpected closing tag "div". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags (1:1)
> 1 | <div>
    | ^
  2 | 
  3 | Some `code`
  4 | 

This does work using the markdown parser.

@karlhorky
Copy link
Contributor

karlhorky commented Nov 24, 2019

Another mention of it in mdx-js/mdx#628 (admittedly, an RFC):

<Note>

This *is* **markdown**!

</Note>

Motivation:

This approach is currently being used in the wild and in production.

As jxnblk mentioned previously this approach comes with the benefit that it's in the Commonmark Spec.

https://spec.commonmark.org/0.29/#example-136
https://spec.commonmark.org/0.29/#example-137

@karlhorky
Copy link
Contributor

karlhorky commented Nov 24, 2019

cc @pomber maybe worth following along here, since your Code Surfer library is relying upon this approach.

@karlhorky
Copy link
Contributor

One last link: in the Try it editor on the official MDX website, both of the examples work - both the example with the div and the original example with the CodeSurfer component.

@thorn0
Copy link
Member

thorn0 commented Nov 24, 2019

The MDX support in Prettier is really basic. Prettier parses MDX like plain Markdown with the only (I guess) difference that if a JSX block is found, it's passed to Babel. That's it. Things like inline JSX and Markdown inside JSX blocks aren't supported as of now.

@thorn0 thorn0 added the help wanted We're a small group who can't get to every issue promptly. We’d appreciate help fixing this issue! label Nov 24, 2019
@karlhorky
Copy link
Contributor

Prettier parses MDX like plain Markdown

Hm, but the original example actually works with the markdown parser:

Markdown (no errors)

It also isn't true for the div MDX <> Markdown comparison that I posted:

MDX (fails)

Markdown (no errors)

If this case was handled the same as the markdown parser (newlines inside tags), maybe this issue would be fixed.

@karlhorky
Copy link
Contributor

karlhorky commented Nov 25, 2019

Ah, in my comment above I missed your point about "if a JSX block is found, it's passed to Babel"... maybe that's the reason for this inconsistency?

@thorn0 thorn0 added the type:bug Issues identifying ugly output, or a defect in the program label Nov 25, 2019
@pomber
Copy link
Contributor

pomber commented Nov 25, 2019

I think it used to work, at least inside of VS Code. Are there playgrounds for older versions of Prettier?

@thorn0
Copy link
Member

thorn0 commented Nov 25, 2019

@pomber Depends on what you call "to work". It might kind of work again in the next version because of #6949. The SyntaxError should get fixed, but Prettier won't really format JSX blocks with Markdown inside. It'll just leave them as is like it currently does with inline JSX. So if someone here is blocked by this issue, consider installing Prettier directly from GitHub (npm install prettier/prettier) until this fix is released.

To my knowledge, there is no playgrounds for older versions.

@pomber
Copy link
Contributor

pomber commented Nov 25, 2019

Yes, maybe it was just ignoring the JSX's children. That was good enough for me.

BTW, I tried 6949 playground and it's still throwing a similar error.

@thorn0
Copy link
Member

thorn0 commented Nov 25, 2019

It's a different error though. It happens only on the playground.

@Tielem
Copy link

Tielem commented Dec 5, 2019

Subscribing to this issue, since I believe I am running into this as well.

I am creating a Gatsby + MDX template. ESLint and Prettier fail with SyntaxError: Unexpected closing tag "div" ; similar to above. However, building or transpiling works as intended.

I can provide a reference to the project soon.

@karlhorky
Copy link
Contributor

karlhorky commented Dec 22, 2019

Ah, just ran into this again with an existing project, which I believe wasn't erroring out before.

Now any files in the project using the pattern below are not formatted by the Prettier VS Code extension anymore.

Here's an example (using gatsby-remark-embedded-codesandbox):

<details>
  <summary>Solution</summary>

[Solution on CodeSandbox](codesandbox-link://exercises/002-solution/)

</details>

@arayaryoma
Copy link

It seems have fixed by #6949

@karlhorky
Copy link
Contributor

karlhorky commented Dec 31, 2019

Hm, not sure about that. It just throws a different error ("SyntaxError: Unexpected token"):

SyntaxError: Unexpected token (2:34)
  1 | <$><details>
> 2 |   <summary>Solution</summary></$>
    |                                  ^

#6949 Playground

Same problem with the code from the original reported issue too.

@cpboyd
Copy link

cpboyd commented Jan 24, 2020

It seems like there's an issue with using style={{}} on a multi-line tag:

---
title: Contact
---

import { Button } from '@rmwc/button';

# Contact

<Button
  raised
  style={{ margin: '8px' }}
>
  Message Me
</Button>

I'm getting this:
error Parsing error: Unexpected closing tag "Button". It may happen when the tag has already been closed by another tag. For more info see https://www.w3.org/TR/html5/syntax.html#closing-elements-that-have-implied-end-tags

Edit: Also, there's the potential for JSX tags within an attribute that should maybe be considered too, like:

<Button
  raised
  icon={<Icon />}
>
  Message Me
</Button>

It seems to be less related to the attribute and more to do with curly brackets on an attribute.

@JounQin
Copy link
Member

JounQin commented Jan 27, 2020

@cpboyd Please try yarn add -D prettier@prettier/prettier, it's duplicate of #7176

@JounQin
Copy link
Member

JounQin commented Jan 27, 2020

@karlhorky That seems to be a different regression, and we can not simply consider all contents in jsx as jsx... Can you open a specific issue to track it?

cc @thorn0

@karlhorky
Copy link
Contributor

That seems to be a different regression, and we can not simply consider all contents in jsx as jsx... Can you open a specific issue to track it?

@JounQin sure, definitely. Which comment of mine are you referring to? The one about the summary and details with Markdown inside (the one that throws "SyntaxError: Unexpected token")?

I guess because it's a different issue, we will leave @trevordmiller's #7041 open too?

@JounQin
Copy link
Member

JounQin commented Jan 27, 2020

@kachkaev Sorry, after reading the issue content again, it seems actually just as same as yours. And as @thorn0 said at #7041 (comment)

The MDX support in Prettier is really basic.

We need help from @mdx-js team.

@karlhorky
Copy link
Contributor

karlhorky commented Jan 27, 2020

The MDX support in Prettier is really basic.

[To improve this] we need help from @mdx-js team.

This sounds reasonable. Wonder if @johno, @silvenon or @wooorm could help here...

@JounQin
Copy link
Member

JounQin commented Jan 27, 2020

@karlhorky Sorry I was confused this issue with #7176, your issue is same as this one: Markdown content inside jsx block with blank lines.

@wooorm
Copy link
Contributor

wooorm commented Jan 27, 2020

What is the question? If it is whether the following is valid MDX, then yes, it is.

<CodeSurfer>

```js
console.log(1);
```

</CodeSurfer>

@JounQin
Copy link
Member

JounQin commented Jan 27, 2020

@wooorm We're asking help for sharing ideas about maintaining mdx support in prettier.

@karlhorky
Copy link
Contributor

karlhorky commented Jan 27, 2020

Sure, although it has been fixed actually. 🤣

Where has this been fixed? In an unreleased version of Prettier?

Ah actually, thanks to @kachkaev's comment (#7176 (comment)), I just tried adding "prettier": "prettier/prettier" to my devDependencies and it seems to format with all examples here! 🚀

Show gif

Kapture 2020-01-27 at 11 23 34

So it looks like this will be fixed as soon as Prettier 1.20.0 or 1.19.2 is released. 🙌

Workaround for now:

Change your version of Prettier in your package.json to "prettier": "prettier/prettier". If you're using VS Code, this new local version will be picked up automatically by prettier-vscode.

@thorn0 thorn0 changed the title MDX parsing error: Unexpected closing tag MDX: support Markdown inside JSX blocks Feb 27, 2020
@karlhorky
Copy link
Contributor

karlhorky commented Apr 9, 2020

Seems like this change that worked with the Prettier master branch before prettier@2.0 is not a part of the v2 release 😞

Screen Shot 2020-04-09 at 21 15 23

Playground

Screen Shot 2020-04-09 at 21 15 49

Playground

@bsgreenb
Copy link

This issue has been solved for me via npm i -D prettier@latest

@thorn0
Copy link
Member

thorn0 commented May 13, 2020

@bsgreenb It might seem that it works sometimes, but this never was implemented.

In this code

<CodeSurfer>

```js
console.log(1);
```

</CodeSurfer>

the tags aren't parsed as JSX at all. Prettier just leaves them as is, without formatting.

Whereas in this code

<CodeSurfer>
```js
console.log(1);
```
</CodeSurfer>

Prettier parses the tags as JSX, but it doesn't parse the text inside as Markdown.

@Kosai106
Copy link

I just encountered the same issue. Oddly enough, using --require-pragma seems to make the error go away, at least on the Prettier Playground.

That said, I updated Prettier in my repo and that seems to have worked as well in my case.

@karlhorky
Copy link
Contributor

@Kosai106 --require-pragma will ignore all files without a pragma at the top of the file. MDX pragma:

<!-- @prettier -->

So it was just disabling Prettier for that file. If you try with --require-pragma and the pragma above, you'll have the same errors again.

Ref: https://prettier.io/docs/en/options.html#require-pragma

@Kosai106
Copy link

@karlhorky Ah, yeah that would explain it, lol. It was pretty late, I didn't think too much about it.

Like I said however, upgrading the Prettier version seems to have solved the issue on my end.

@kachkaev
Copy link
Member

kachkaev commented Feb 1, 2022

MDX v2 is out:

The example attached to this issue may become pretty common soon 🤔

@kachkaev
Copy link
Member

kachkaev commented Feb 1, 2022

Let’s continue the discussion here:

@kachkaev kachkaev closed this as completed Feb 1, 2022
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 28, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
help wanted We're a small group who can't get to every issue promptly. We’d appreciate help fixing this issue! lang:mdx Issues affecting the MDX extension to Markdown (not general Markdown issues) type:bug Issues identifying ugly output, or a defect in the program
Projects
None yet
Development

No branches or pull requests