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

Code block treatment breaks compatibility with some rehype plugins? #139

Open
Tracked by #588
deklanw opened this issue Sep 7, 2020 · 8 comments
Open
Tracked by #588
Labels
assigned Whether or not this bug has been assigned some to some other issues as a subtask or pre-req bug Something isn't working
Milestone

Comments

@deklanw
Copy link

deklanw commented Sep 7, 2020

Was trying to get https://github.com/rsclarke/rehype-shiki to work. It lets you syntax highlight with any VSCode theme. It wasn't working, so I dug into it: it just walks the tree lookiing for pre tags wrapping a code tag.

But, it seems MDsvex is doing something special with @html that breaks this https://github.com/pngwn/MDsveX/blob/master/packages/mdsvex/test/it/code_highlighting.test.ts#L64

I'm just going to use the built-in syntax highlighting for now, but just making a note of this with this issue

@pngwn
Copy link
Owner

pngwn commented Sep 7, 2020

Yeah, this is the cause of #100 as well. Will be fixed in a future version. Highlighting will also be done by Shiki in a future version now that shikijs/shiki#49 is in.

@deklanw
Copy link
Author

deklanw commented Sep 7, 2020

I actually ended up finding this https://github.com/SaraVieira/prism-theme-converter which lets you use VSCode themes with prism.

Why the switch to Shiki? More language support than prism with that issue you linked to?

@pngwn
Copy link
Owner

pngwn commented Sep 7, 2020

Yeah, you can apply any textmate grammar at all which is better than Prism's non-standard grammar (even though they have some similarities) as you don't need to write a new grammar when you're doing something funky.

The other reason is more selfish, the way Prism is built makes it incredibly difficult to work with in various contexts. It is really quite frustrating and makes a mess of my code due to the UMD format that it publishes. shiki is much friendlier in that regard.

@deklanw
Copy link
Author

deklanw commented Sep 7, 2020

Makes sense. Thanks for the explanation.

@pngwn pngwn added the bug Something isn't working label Oct 13, 2020
@pngwn
Copy link
Owner

pngwn commented Mar 21, 2021

The rehype issue is still present (code blocks are transformed via a remark plugin and this would require significant refactoring) but highlighjting with shiki is now possible via a custom highlight function as async highlight functions are now supported.

See the parent post in #205 for an example of what this might look like.

@michaeloliverx
Copy link

I am trying to use https://github.com/shikijs/twoslash which provides syntax highlighting and enriches the JS and TS code with static types (see https://shikijs.github.io/twoslash/ for demo, its really nice).

It doesn't work because of some escaping issue I think.

Here is the raw markdown:

```tsx twoslash
import axios from "axios";
import { useQuery } from "react-query";

import type { UseQueryResult } from "react-query";

type Todo = {
  userId: number;
  id: number;
  title: string;
  completed: boolean;
};

function useTodos(): UseQueryResult<Todo[], Error> {
  return useQuery({
    queryKey: "groups",
    queryFn: async () => {
      const { data } = await axios.get(
        "https://jsonplaceholder.typicode.com/todos"
      );
      return data;
    },
  });
}

export function Todos() {
  const { data } = useTodos();
  if (!data) return null;
  return <div>{data}</div>;
}
```

I get an error coming from twoslash and it shows the code that it received:

'''tsx
import React from 'react'
// ---cut---
import axios from "axios";
import &#123; useQuery &#125; from "react-query";

import type &#123; UseQueryResult &#125; from "react-query";

type Todo = &#123;
  userId: number;
  id: number;
  title: string;
  completed: boolean;
&#125;;

function useTodos(): UseQueryResult&lt;Todo[], Error&gt; &#123;
  return useQuery(&#123;
    queryKey: "groups",
    queryFn: async () =&gt; &#123;
      const &#123; data &#125; = await axios.get(
        "https://jsonplaceholder.typicode.com/todos"
      );
      return data;
    &#125;,
  &#125;);
&#125;

export function Todos() &#123;
  const &#123; data &#125; = useTodos();
  if (!data) return null;
  return &lt;div&gt;&#123;data&#125;&lt;/div&gt;;
&#125;
'''

We got around this in #212 by providing a custom highlight function and using escapeSvelte, it would be nice to be able to support code block plugins without using the custom function.

I created a barebones svelte kit project with this issue happening here: https://github.com/michael0liver/mdsvex-remark-codeblock-issue

@michaeloliverx
Copy link

Okay I got around it again by using the custom highlight function 😄

// svelte.config.js
import preprocess from "svelte-preprocess";
import { mdsvex } from "mdsvex";
import {
  createShikiHighlighter,
  runTwoSlash,
  renderCodeToHTML,
} from "shiki-twoslash";
import { readFileSync } from "fs";

// From https://github.com/whizkydee/vscode-palenight-theme/blob/master/themes/palenight.json
const palenightTheme = JSON.parse(readFileSync("./palenight-theme.json"));

const mdsvexPreprocess = mdsvex({
  extensions: [".svx", ".md"],
  highlight: {
    highlighter: async (code, lang, meta) => {
      const highlighter = await createShikiHighlighter({
        theme: palenightTheme,
      });

      let twoslashResults = null;
      if (meta && meta.includes("twoslash")) {
        twoslashResults = runTwoSlash(code, lang, {});
      }

      const html = renderCodeToHTML(
        code,
        lang,
        meta || [],
        {},
        highlighter,
        twoslashResults
      );

      return `{@html \`${html}\` }`;
    },
  },
});

/** @type {import('@sveltejs/kit').Config} */
const config = {
  preprocess: [mdsvexPreprocess, preprocess()],
  extensions: [".svelte", ".svx"],
  kit: {
    target: "#svelte",
  },
};

export default config;

Working great:
image

@pngwn
Copy link
Owner

pngwn commented Sep 10, 2021

I think this is the same as : #304 and more specifically this: #93 (comment)

@pngwn pngwn added this to mdsvex Oct 16, 2021
@pngwn pngwn moved this to Refine in mdsvex Oct 16, 2021
@pngwn pngwn added this to the 1.0 milestone Oct 16, 2021
@pngwn pngwn mentioned this issue Feb 23, 2024
13 tasks
@pngwn pngwn added the assigned Whether or not this bug has been assigned some to some other issues as a subtask or pre-req label Feb 24, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
assigned Whether or not this bug has been assigned some to some other issues as a subtask or pre-req bug Something isn't working
Projects
No open projects
Status: Refine
Development

No branches or pull requests

3 participants