[v2] Fenced code blocks within JSX elements with indent > 2 parses incorrectly
See original GitHub issueI’ve been playing around a bit more with MDX v2 and encountered what I think is a bug, or at the very least, some surprising behavior. I have the need to render fenced code blocks within table cells. Because of the highly nested structure of a table, and to maintain sane indentation, I’ve placed the code block indented within the <td />
. Unfortunately MDX v2 parses this incorrectly.
Steps to reproduce
For example, here is a simple table with a single cell that outputs a code block in one of the td
s:
<table>
<tbody>
<tr>
<td>
```
console.log(test)
```
</td>
<td>
Some more text
</td>
</tr>
</tbody>
</table>
This parses into an AST like the following:
{
"type": "code",
"lang": null,
"meta": null,
"value": "console.log(test)\n```\n",
"position": {
"start": {
"line": 5,
"column": 1,
"offset": 38
},
"end": {
"line": 8,
"column": 7,
"offset": 94
},
"indent": [
1,
1,
1
]
}
}
Notice how the value
ends with the fence literal and a newline. This results in text that renders to the screen as:
console.log(test)
```
If I remove the indentation in front of the code block, it seems to parse and output the correct text:
Markdown
<table>
<tbody>
<tr>
<td>
```
console.log(test)
```
</td>
<td>
Some more text
</td>
</tr>
</tbody>
</table>
AST
{
"type": "code",
"lang": null,
"meta": null,
"value": "console.log(test)",
"position": {
"start": {
"line": 5,
"column": 1,
"offset": 38
},
"end": {
"line": 7,
"column": 4,
"offset": 63
},
"indent": [
1,
1
]
}
}
Output
console.log(test)
You can see the result of each of these using the playground
Expected behaviour
I would expect that regardless of the indentation, the code block’s value
would result in the same thing.
Is this intentional behavior or a bug? I find it a bit surprising at the least.
Minimal fix
I’ve been able to “fix” this issue by creating my own MDX remark transform:
const visit = require('unist-util-visit');
const INCORRECT_CODE_BLOCK = /`{3,}\n?$/;
const indentedCodeBlock = () => (tree) => {
visit(
tree,
(node) => node.type === 'code' && INCORRECT_CODE_BLOCK.test(node.value),
(codeBlock) => {
codeBlock.value = codeBlock.value.replace(INCORRECT_CODE_BLOCK, '').trim();
}
);
};
This rewrites the value
by removing the additional backticks in the output. Maybe this is the best way to go about this for now? Maybe not?
Any help would be appreciated. Thank you so much!!
Issue Analytics
- State:
- Created 3 years ago
- Reactions:1
- Comments:9 (5 by maintainers)
Top GitHub Comments
Solved this with micromark (https://github.com/micromark/micromark-extension-mdxjs). pulling the new parser into mdx soon
Hi all! I’m going to close this as it landed on the
main
, the (now default) branch we’re using to gear up to the MDX@2 release.The reason is so that it’s more clear which issues still need to be solved already and don’t require further work.
Expect another
next
release soonish, which might include it, or maybe it’s already released as a beta!For more info, see https://github.com/mdx-js/mdx/issues/1041.