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

Investigate the use of shiki as the library for syntax highlighting #1683

Open
Nova38 opened this issue Nov 27, 2024 · 12 comments
Open

Investigate the use of shiki as the library for syntax highlighting #1683

Nova38 opened this issue Nov 27, 2024 · 12 comments
Labels
enhancement New feature or request

Comments

@Nova38
Copy link

Nova38 commented Nov 27, 2024

Proposal

Use shiki, https://shiki.style/, as the syntax highlighting library for mystmd. It uses the same syntax highlighting engine as vscode and has very good tooling.

  • It uses TextMate grammars for its language definitions. Which is the same definitions that are used by vscode and GitHub's linquist among others.
    • The output it produces is very good.
    • there is a large number of high-quality language definitions already defined.
    • It also allows reusing vscode color themes.
  • It is supports being run in a compilation step for static generation and at runtime in the end users browser.
  • It has a extensive API for defining transformations and decorations

Additional notes

It is used in a lot of open source projects

  • Astro
  • Nuxt
  • vitepress
@Nova38 Nova38 added the enhancement New feature or request label Nov 27, 2024
@agoose77
Copy link
Contributor

I recall seeing this mentioned somewhere ... turns out it was you! https://discord.com/channels/1083088970059096114/1083088970059096117/1295937103846314004

@Nova38
Copy link
Author

Nova38 commented Nov 27, 2024

Yep! I finally have some free time to work on some contributions to a few projects, so I wanted to open the floor to see if this is something that would be desired.

I recall seeing this mentioned somewhere ... turns out it was you! https://discord.com/channels/1083088970059096114/1083088970059096117/1295937103846314004

I also forgot to add that it is really easy to add custom languages to shiki as the consumer of the library. I think that might be useful if someone wanted to have syntax highlight for a custom languages (such as if it was a book about language design/compilers and they made up a simple language) (See https://shiki.style/guide/load-lang)

@choldgraf
Copy link
Collaborator

Thanks for this idea @Nova38 ! I wanted to share a few quick questions to help us triage this idea a bit. I promise they're not coming from a place of skepticism - just trying to understand cost/benefit!

  • What's the benefit of using this over the current system we use for syntax highlighting? (in functionality, maintenance cost, long-term outlook, UX, etc?)
  • How much work would it be to implement and then maintain this?
  • Why should this be the most important thing to use maintainer time implementing/reviewing/etc?

@Nova38
Copy link
Author

Nova38 commented Nov 27, 2024

No worries, I completely understand. Those are excellent questions! I will work on writing up those and should have them in a short bit.

To aid the comparison is there a specific package that handles the code directive/syntax highlighting directive? I used the GitHub search to find where https://github.com/react-syntax-highlighter/react-syntax-highlighter was being used, but I am unfamiliar with the codebase and want to make sure I am comparing it to the correct spot. If you know of the top of your head could you point me in the right direction please? If not don't worry about it I'll just keep going through it.

Thanks!

@rowanc1
Copy link
Member

rowanc1 commented Nov 27, 2024

The syntax highlighter is used in the myst-theme package here:

https://github.com/jupyter-book/myst-theme/blob/main/packages/myst-to-react/src/code.tsx#L106

@Nova38
Copy link
Author

Nova38 commented Nov 27, 2024

Here are some of my initial thoughts

  • What's the benefit of using this over the current system we use for syntax highlighting? (in functionality, maintenance cost, long-term outlook, UX, etc?)

  • How much work would it be to implement and then maintain this?

    • Honestly I am not sure how long it would take to implement. It doesn't look like it would take much to add it. To maintain it after the initial setup would probably be minimal. I can make a POC to see what the code will look like. I Think that it might be less work maintaining the current code of the code highlighter.
  • Why should this be the most important thing to use maintainer time implementing/reviewing/etc?

    • It could be used to further expand what mystmd can do with code annotations

@Nova38
Copy link
Author

Nova38 commented Nov 27, 2024

Is there a way to override an existing component and inject different project specific component?

@stevejpurves
Copy link
Contributor

stevejpurves commented Nov 28, 2024

@Nova38 no not on the renderer/theme/react side of things, this is part of the plugin framework that has yet to be fleshed out.

+1 for shikijs being pure ESM though. We've had to wrangle with react-syntax-highlighter at times due to the way it is packaged, trying to be a cjs/esm distribution.

@Nova38
Copy link
Author

Nova38 commented Nov 29, 2024

I am not sure that I entirely follow the question. Are you wanting how it by itself can be adapted into a plugin itself, how it could fit in by themselves exposing parts of it that other plugins could then be able to expand on it and add new features to the code blocks, or is it something else?

@Nova38
Copy link
Author

Nova38 commented Dec 24, 2024

Do you mean about how it allow things like decorations to code blocks be added by plugins. If so then there is actually a really nice api that could definitely be hooked into by the plugin system. They have some documentation about it here https://shiki.style/guide/decorations. I have also included an example they have of using that API directly.

import { codeToHtml } from 'shiki'

const code = `
const x = 10
console.log(x)
`.trim()

const html = await codeToHtml(code, {
  theme: 'vitesse-light',
  lang: 'ts',
  decorations: [ 
    {
      // line and character are 0-indexed
      start: { line: 1, character: 0 },
      end: { line: 1, character: 11 },
      properties: { class: 'highlighted-word' }
    }
  ]
})

And here is the rendered result:

Screenshot_20241223_180751_Vivaldi.jpg

A good example of using what this can allow can be seen in the first party twoslash plugin. https://shiki.style/packages/twoslash

The integrating it into the plugins system could be done by allowing plugins could generate some of the objects passed into the decoration array or by allowing the definition of something like their transformation API (https://shiki.style/packages/transformers)

@Nova38 no not on the renderer/theme/react side of things, this is part of the plugin framework that has yet to be fleshed out.

+1 for shikijs being pure ESM though. We've had to wrangle with react-syntax-highlighter at times due to the way it is packaged, trying to be a cjs/esm distribution.

@Nova38
Copy link
Author

Nova38 commented Dec 24, 2024

Also I was wondering, would it be better to include it in the myst-to-html or its own exetention instead on the react myst theme as it can render to html without needing to load the libraries in the browser. That way it will reduce the amount of JavaScript on the end users page

https://github.com/jupyter-book/mystmd/tree/main/packages/myst-to-html

The syntax highlighter is used in the myst-theme package here:

https://github.com/jupyter-book/myst-theme/blob/main/packages/myst-to-react/src/code.tsx#L106

@choldgraf
Copy link
Collaborator

Just wanted to note that we have very limited bandwidth on the project right now, so there's a good chance that discussions like this will take a while to play out. We appreciate all of this research and consideration here, there's just too much to do and not much time to work on the project :-)

To your last point, I think that this issue might be relevant to the point you're making:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

5 participants