Skip to content

Serializing interleaved Markdown in JSX can lead to a few quirks #1193

@johno

Description

@johno

In Gatsby Recipes we wrap blocks of Markdown with JSX tags in a few spots. After manipulating the AST we then serialize back to MDX. This can cause a few quirks.

Consider the following input:

**Success**!

You're ready to get started!

-   Read the docs: [https://theme-ui.com](https://theme-ui.com)
-   Learn about the theme specification: [https://system-ui.com](https://system-ui.com)

_note:_ if you're running this recipe on the default starter (or any other starter with
base css), you'll need to remove the require to `layout.css` in the `components/layout.js` file
as otherwise they'll override some theme-ui styles.

We manipulate the AST and wrap it up like so:

    const wrappedResourceSteps = resourceSteps.map((step, i) => {
      return {
        type: `mdxBlockElement`,
        name: `RecipeStep`,
        attributes: [
          {
            type: `mdxAttribute`,
            name: `step`,
            value: String(i + 1),
          },
          {
            type: `mdxAttribute`,
            name: `totalSteps`,
            value: String(resourceSteps.length),
          },
        ],
        children: step,
      }
    })

We then result in:

<RecipeStep
  step="4"
  totalSteps="4"
>
  **Success**!

  You're ready to get started!

  -   Read the docs: [https://theme-ui.com](https://theme-ui.com)
  -   Learn about the theme specification: [https://system-ui.com](https://system-ui.com)

  _note:_ if you're running this recipe on the default starter (or any other starter with
  base css), you'll need to remove the require to `layout.css` in the `components/layout.js` file
  as otherwise they'll override some theme-ui styles.
</RecipeStep>

The indention of the "note" paragraph below causes it to be parsed as part of the li so we end up with:

    <ul>
      <li {...{
        "parentName": "ul"
      }}>
        <p {...{
          "parentName": "li"
        }}>{`Read the docs: `}
          <a {...{
            "href": "https://theme-ui.com",
            "parentName": "p"
          }}>{`https://theme-ui.com`}</a></p>
      </li>
      <li {...{
        "parentName": "ul"
      }}>
        <p {...{
          "parentName": "li"
        }}>{`Learn about the theme specification: `}
          <a {...{
            "href": "https://system-ui.com",
            "parentName": "p"
          }}>{`https://system-ui.com`}</a></p>
        <p {...{
          "parentName": "li"
        }}><em {...{
            "parentName": "p"
          }}>{`note:`}</em>
          {` if you're running this recipe on the default starter (or any other starter with
base css), you'll need to remove the require to `}
          <inlineCode {...{
            "parentName": "p"
          }}>{`layout.css`}</inlineCode>
          {` in the `}
          <inlineCode {...{
            "parentName": "p"
          }}>{`components/layout.js`}</inlineCode>
          {` file
as otherwise they'll override some theme-ui styles.`}</p>
      </li>
    </ul>

It seems like when we serialize to MDX we will need to dedent block-based Markdown inside JSX tags, otherwise significant whitespace will be injected that might not be intended. Any thoughts on how to best do this @wooorm?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions