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

Preserve whitespace in code blocks #226

Merged
merged 3 commits into from
Sep 4, 2018
Merged

Preserve whitespace in code blocks #226

merged 3 commits into from
Sep 4, 2018

Conversation

silvenon
Copy link
Contributor

I'm trying to write a test that reproduces #221. The idea is to mount the component exported by the fixture and use textContent to check if whitespace in the code block is preserved.

I'm having difficulties trying to load the module compiled by webpack as a React component and mounting it. Webpack gives me an object with a source text, but I'm not sure how to parse it as a Node module. If someone has an idea, let me know. 😅

P. S. I'm not 100% certain that this is really an MDX issue, but the fact that I can't reproduce it without it suggests that it is.

@vercel
Copy link

vercel bot commented Aug 18, 2018

This pull request is automatically deployed with Now.

To access deployments, click Details below or on the icon next to each push.

@silvenon
Copy link
Contributor Author

I realized I could test this easily with runtime, so nvm, I think I got it. 😉

@silvenon
Copy link
Contributor Author

silvenon commented Aug 18, 2018

Ok, I managed to reproduce this in a test! Now MDX runtime also accepts mdPlugins, hastPlugins and compilers. Feedback on this API change would be welcome.

@hugmanrique
Copy link
Contributor

So would moving the prism plugin to compilers fix the issue? What's the main difference between mdPlugins and this new option?

@silvenon
Copy link
Contributor Author

silvenon commented Aug 24, 2018

hastPlugins operate on rehype tree, while compilers operate on JSX strings. Notice that between applying these two sets of plugins the tree is converted to JSX. @mapbox/rehype-prism can only work on rehype, so I think it has to stay in hastPlugins.

I get lost pretty easily when working with unified because I haven't mastered it yet, but I'll continue trying to figure out where this is failing.

@silvenon silvenon changed the title [WIP] Preserve whitespace in code blocks Preserve whitespace in code blocks Aug 26, 2018
@silvenon
Copy link
Contributor Author

silvenon commented Aug 26, 2018

I figured it out! In the process of converting to JSX there was an exception with newlines introduced by #180. I added an exception to that exception (exceptionception) and converted newlines to JSX text nodes only for code inside <pre> tags.

This works, I've been using it locally.

@ifyoumakeit because you have a deeper understanding of that part of the code, could you take a look at this?

@ifyoumakeit
Copy link
Contributor

I can definitely can take a look!

children = node.children.map(childNode => {
const childOptions = {
...options,
preserveNewlines: preserveNewlines || node.tagName === 'pre',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 I think this makes sense, as long as there's information about this default behavior somewhere.

Copy link
Contributor

@ifyoumakeit ifyoumakeit left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! ⛱

I noted this in a comment, but I would just make sure this is well documented and not buried in the code.

@silvenon
Copy link
Contributor Author

@ifyoumakeit thanks a lot! I’ll make sure to at least add comments.

@alexkrolick could you be more specific? What problem would these changes solve for you?

@alexkrolick
Copy link

Actually I might be me misinterpreting the problem. I thought this would fix the fact that newlines inside render functions are interpreted as MD blocks instead of as JS code to evaluate. You can see how the formatting in my link requires adding comments or semicolons anywhere you want a blank line.

@silvenon
Copy link
Contributor Author

silvenon commented Aug 27, 2018

This PR unfortunately won't take care of that, it's for fenced code blocks only. We're aware of the issue you mentioned, though.

The advantage of the toContain() matcher is apparent on test failure;
Jest will print out the actual vs. expected, instead of only giving you
the information that it failed.
In order to avoid issues like React warnings caused by text nodes in
tables, we didn't convert text nodes consisting solely of one newline
into text nodes. This caused some newlines inside fenced code blocks to
be lost because, unlike in HTML, in React we have to explicitly create
text nodes, which is important whitespace-sensitive tags like <pre>.

These changes convert all newlines in <pre> tags into text nodes.

Fixes #221.
@silvenon
Copy link
Contributor Author

silvenon commented Aug 27, 2018

Done! Polished it up a bit and added more comments to clarify what's going on.

I also updated all mdx tests to use the toContain() matcher because it really improves debugging experience in tests, for example you get transparent errors like this:

    Expected string:
      "export default ({components, ...props}) => <MDXTag name=\"wrapper\"  components={components}><MDXTag name=\"p\" components={components}><MDXTag name=\"inlineCode\" components={components} parentName=\"p\">{`<div>`}</MDXTag></MDXTag></MDXTag>"
    To contain value:
      "<MDXTag name=\"inlineCode\" components={components} parentName=\"p\">{`<b>`}</MDXTag>"

@johno ready when you are. 😉

@johno
Copy link
Member

johno commented Sep 4, 2018

Thanks all, this is amazing!

@johno johno merged commit e883828 into mdx-js:master Sep 4, 2018
@@ -97,7 +103,7 @@ it('Should render elements without wrapping blank new lines', async () => {
| :--- | :---- |
| Col1 | Col2 |`)

expect(result.includes('{`\n`}')).toBe(false)
expect(result).not.toContain('{`\n`}')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💅

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tenor

@silvenon silvenon deleted the code-blocks-whitespace branch September 5, 2018 13:58
@devongovett
Copy link
Contributor

Can we get this released?

@johno
Copy link
Member

johno commented Sep 7, 2018

Now published as 0.15.1, apologies on the delay.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

6 participants