Skip to content
This repository was archived by the owner on Nov 3, 2019. It is now read-only.

Nested markdown content (mdx feature not supported in gatsby-mdx) #169

Closed
craigmcginley opened this issue Oct 4, 2018 · 8 comments
Closed
Labels
help wanted Extra attention is needed

Comments

@craigmcginley
Copy link
Contributor

MDX (runtime) supports wrapping markdown in raw html. I have not been able to get this to work in my own gatsby-mdx project, or kitchen sink examples in this repository. It seems gatsby-mdx will not nest the markdown content, but instead put the raw html wrapper above the markdown content. Could use a second set of eyes to make sure I'm not crazy.

Is this difference because the example by @silvenon uses mdx/runtime? Is there a way we can get gatsby-mdx to support this functionality?

@silvenon
Copy link

silvenon commented Oct 4, 2018

Just to add, the runtime was just a quick way to show that it works, this works in the core as well.

@ChristopherBiscardi
Copy link
Owner

The runtime vs "core" shouldn't have any effect. We also use mdx core to do the initial parsing, running of the pipeline, etc, so unless some node is getting chopped off by a plugin I'd expect any core functionality to work in gatsby-mdx. That said, I do see some funky output because the following input

<div class="things">

> some blockquote

</div>

results in the following output

<div class="things"></div>
<blockquote>
  <p>some blockquote</p>
</blockquote>

and disabling our htmlToJSX plugin fixes the issue. (we originally used the htmlToJSX plugin to patch some mdx core stuff that I think has been since fixed and released so we should get rid of it asap anyway).

I need to do some tests to make sure removing it doesn't break the gatsby-remark-* plugin support.

@ChristopherBiscardi
Copy link
Owner

One thing I'm noticing again is that the jsx nodes, either in mdast or hast, aren't "full nodes" but are jsx fragments like <div> or </div>.

Consider the mdast for this input:
# heading

<div>

> block

</div>
mdast:
{
  "type": "root",
  "children": [
    {
      "type": "heading",
      "depth": 1,
      "children": [
        {
          "type": "text",
          "value": "heading",
          "position": {...}
      ],
      "position": {...}
    },
    {
      "type": "jsx",
      "value": "<div>",
      "position": {...}
    },
    {
      "type": "blockquote",
      "children": [
        {
          "type": "paragraph",
          "children": [
            {
              "type": "text",
              "value": "block",
              "position": {...}
            }
          ],
          "position": {...}
        }
      ],
      "position": {...}
    },
    {
      "type": "jsx",
      "value": "</div>",
      "position": {...}
    }
  ],
  "position": {...}
}

You'll see that the JSX isn't parsed the way I'd expect it to be, but rather as invalid fragments of JSX like

   {
      "type": "jsx",
      "value": "<div>",
      "position": {...}
    }

Everything injected into the tree by a remark plugin as html gets immediately treated as jsx in the mdast to mdxast conversion. This is why we have the htmlToJSX remark plugin in gatsby-mdx, which tries to test for html values and convert it to jsx before this point. My hunch is that it's getting tripped up on the fragments and results in the plugin trying to "complete" opening tags and discarding closing tags.

@ChristopherBiscardi
Copy link
Owner

It seems the official opinion is to not rely on this functionality, so going to deprioritize this for now, but I'd welcome a PR to make the html-to-jsx functionality better. Perhaps we should wrap the gatsby remark plugins in this additional functionality (we already have to wrap them as remark plugins, so it's be an addition to that) so they emit jsx instead of html?

@ChristopherBiscardi ChristopherBiscardi added the help wanted Extra attention is needed label Oct 6, 2018
@chasemccoy
Copy link

I understand not wanting to rely on this (I don't want to either), but in some cases there are no alternatives. For example, I have a page where I want to display two elements side-by-side, but I need the headers to be written in Markdown so that they are included in my table of contents (see #140). If I wrap in a React component, I lose Markdown headers. If I wrap in a plain div with a class, I run into this issue.

@ChristopherBiscardi
Copy link
Owner

@chasemccoy I want to swap the table of contents to be the html approach in that issue but haven't gotten around to it. There's some work in a PR that I need to clean up to render the html out in the graphql schema.

@ChristopherBiscardi
Copy link
Owner

I would accept a PR that fixed this by fixing the htmlToJSX processing for plugins.

@johno
Copy link
Collaborator

johno commented Jan 30, 2019

Going to close this:

@johno johno closed this as completed Jan 30, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

5 participants