rehype-pretty / rehype-pretty-code

Beautiful code blocks for Markdown or MDX.

Home Page:https://rehype-pretty.pages.dev

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Shiki v1.0

atomiks opened this issue Β· comments

Shikiji was merged back into Shiki. Tracking this so we can upgrade once v1.0 is out of beta: https://github.com/shikijs/shiki/releases

Hello.

Trying to update your great plugin from 0.6.0 to 0.12.6. And don't know if it's related to your latest update.
The idea is to pass somehow raw code string to <pre> as a prop to have copy/paste functionality of raw code.

Now my current approach doesn't work. Maybe you could suggest your official approach. Thank you

I have such an implementation

// INFO: To get code string in <pre> html block in mdx-components
const preProcess = () => (tree) => {
  visit(tree, (node) => {
    if (node?.type === "element" && node?.tagName === "pre") {
      const [codeEl] = node.children;

      if (codeEl.tagName !== "code") return;

      node.__rawString__ = codeEl.children?.[0].value;
      console.log(
        "πŸš€ ~ file: contentlayer.config.js:85 ~ visit ~ node.__rawString__:",
        node.__rawString__
      );

      node.properties = { rawString: codeEl.children?.[0].value };
      console.log("πŸš€ ~ file: contentlayer.config.js:91 ~ visit ~ node:", node);
    }
  });
};

const postProcess = () => (tree) => {
  visit(tree, "element", (node) => {
    if (node?.type === "element" && node?.tagName === "pre") {
      console.log(
        "πŸš€ ~ file: contentlayer.config.js:96 ~ visit ~ node:",
        JSON.stringify(node, null, 4)
      );
      node.properties["__rawString__"] = node.__rawString__;
    }
  });
};



export default makeSource({
  contentDirPath: "./src/content",
  documentTypes: [Doc],
  mdx: {
    remarkPlugins: [remarkGfm],
    rehypePlugins: [
      // INFO: need to ensure that your preProcess is first in your array of plugins
      preProcess,
      rehypeSlug,
      [
        rehypePrettyCode,
        {
          theme: {
            light: "github-light",
            dark: "github-dark-dimmed",
          },
        },
      ],
      [
        rehypeAutolinkHeadings,
   
      // INFO: need to ensure that your postProcess is last in your array of plugins,
      postProcess,
    ],
  },
});

and in mdx-components

  pre: ({
    className,
    __rawString__,
    ...props
  }: React.HTMLAttributes<HTMLPreElement> & { __rawString__?: string }) => {
    console.log(
      "πŸš€ ~ file: mdx-components.tsx:167 ~ __rawString__:",
      __rawString__
    );
    return (
      <div className="relative">
        <pre
          data-theme="github-dark-dimmed github-light"
          className={ className}
          {...props}
        />
        {__rawString__ && (
          <CopyButton
            value={__rawString__}
            className={cn("absolute right-3 top-3")}
          />
        )}
      </div>
    );
  },

Update 1: This approach doesn't work with a new version https://claritydev.net/blog/copy-to-clipboard-button-nextjs-mdx-rehype

I'm not 100% sure, but it may be related to not preserving properties on nodes after highlighting creates new nodes. There was another issue with code.data, which was fixed like so:

https://github.com/atomiks/rehype-pretty-code/blob/5535ddbb6e1774598ccef1e8c29a6c357305141a/src/index.ts#L61

Instead of this single manual check, we can iterate through all properties and re-apply them, including the pre.

Specifically, it's likely these are being blown away:

node.__rawString__ = codeEl.children?.[0].value;
node.properties = { rawString: codeEl.children?.[0].value };
commented

shiki v1.0 is released