timlrx/rehype-prism-plus

Issues with providing highlighted lines

Fox32 opened this issue · 8 comments

Fox32 commented

I have trouble to use the highlighted lines and showLineNumbers feature.

```js {1,3-4} showLineNumbers
function fancyAlert(arg) {
  if (arg) {
    $.facebox({ div: '#foo' })
  }
}
```

In general the line numbers work, if I force showLineNumbers on plugin creation. I'm using next-mdx-remote.

I played around a little bit and build myself a small plugin that prints the HAST before rehype-prism-plus is executed. I'm not a rehype or remark expert at all! This is what my HAST looks like:

{
  type: 'element',
  tagName: 'code',
  properties: {
    className: [ 'language-js' ],
    metastring: '{1,3-4} showLineNumbers',
    '{1,3-4}': true,
    showLineNumbers: true
  },
  children: [
    {
      type: 'text',
      value: 'function fancyAlert(arg) {\n' +
        '  if (arg) {\n' +
        "    $.facebox({ div: '#foo' })\n" +
        '  }\n' +
        '}\n'
    }
  ],
  position: {
    start: { line: 6, column: 1, offset: 40 },
    end: { line: 12, column: 4, offset: 150 }
  }
}

The issue seems to be, that a property called data is expected that should contain the meta, but instead I have a metastring property as part of properties.

I have no idea if that problem is on my side, or incompatible packages, or if we should just fix it here (by supporting both).
For now I solve this using a plugin on my side, that I run before this plugin:

const fixMetaPlugin = (options = {}) => {
  return (tree) => {
    visit(tree, 'element', visitor);
  };

  function visitor(node, index, parent) {
    if (!parent || parent.tagName !== 'pre' || node.tagName !== 'code') {
      return;
    }

    node.data = { ...node.data, meta: node.properties.metastring };
  }
};

Yes, the issue is highlighted here as well: #18

next-mdx-remote is using mdx v1 which is slightly different in format than xdm or mdx v2. Thanks for figuring it out and finding a work around! Will include that info in the readme as well to avoid confusion from future users.

I think it is best to use that work around and wait for next-mdx-remote to upgrade to mdx v2 or use mdx-bundler.

Fox32 commented

Ah perfect, then it's best to wait for it. For everyone else having the issue now the workaround above should be sufficient.

Feel free to close this issue once it's mentioned in the readme.

Updated readme with the workaround.

@Fox32 Do you have an example of using and applying this plugin? I attempted to add, but not getting the linenumbers to show up. @timlrx , is there a reference guide for migrating from next-mdx-remote to mdx-bundler anywhere?

Take a look at an example of using the plugin with mdx-bundler over here - https://github.com/timlrx/tailwind-nextjs-starter-blog/blob/master/lib/mdx.js#L85

Here is an example with showLineNumbers.

No, I do not have a migration guide but the code above should give you a good idea of what's needed to get mdx-bundler working.

@timlrx Got it working, thanks so much!

hi @timlrx , This is a great rehype plugins.
I'm using next-mdx-remote and next 13 with app directory
how can I pass a file name to code block like the following example from next.js blog?

image

I want to do it like so

`\`\`ts filename="@/store/atom.ts"
import { atom } from 'jotai'

const foodsAtom = useAtom(["Banana", "Apple"])
`\`\`

but in my CodeBlock component, I didn't receive the filename props

Hi @rizkimcitra , i just commenting to share my solution if you haven't solved it yet. I am also using next-mdx-remote.

I suggest you try using rehype-mdx-code-props.

Below is an example of some of the code I applied.

import rehypeMdxCodeProps from "rehype-mdx-code-props";

serialize(source.trim(), {
  parseFrontmatter: true,
  mdxOptions: {
    remarkPlugins: [remarkGfm, remarkBreaks],
    rehypePlugins: [
      rehypeSlug,
      rehypePrism,
      [rehypeAutolinkHeadings, { properties: { className: ["anchor"] } }],
      rehypeMdxCodeProps,
    ],
    format: "mdx",
    development: process.env.NODE_ENV !== "production",
  },
});

Note that rehypeMdxCodeProps must be added to the array as the last element for other plugins to work.

Additionally, if you get a token related error during compile, you can fix the part where you specify the attributes of the codeblock in key=value format.

Hope this helps you solve your problem :)

Hi @timlrx , I commented on an issue that has already been resolved, I just wanted to make helpful. I apologize if it was intrusive.

This comment is a translation. There may be something incorrect.