GithubHelp home page GithubHelp logo

rsclarke / rehype-shiki Goto Github PK

View Code? Open in Web Editor NEW
31.0 2.0 8.0 464 KB

rehype plugin to highlight code blocks with shiki

License: MIT License

JavaScript 100.00%
rehype shiki rehype-plugin syntax-highlighting

rehype-shiki's Introduction

rehype-shiki

rehype plugin to apply syntax highlighting on code blocks with shiki.

This plugin was based upon rehype-highlight.

Installation

npm:

npm install rehype-shiki

Usage

Say example.html looks as follows:

<h1>Hello World!</h1>

<pre><code class="language-js">var name = "World";
console.warn("Hello, " + name + "!")</code></pre>

...and example.js like this:

var vfile = require('to-vfile')
var report = require('vfile-reporter')
var rehype = require('rehype')
var shiki = require('rehype-shiki')

rehype()
  .data('settings', {fragment: true})
  .use(shiki)
  .process(vfile.readSync('example.html'), function(err, file) {
    console.error(report(err || file))
    console.log(String(file))
  })

Now, running node example yields:

example.html: no issues found
<h1>Hello World!</h1>

<pre style="background: #2e3440"><code class="language-js"><span style="color: #81A1C1">var</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">name</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">=</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">World</span><span style="color: #ECEFF4">"</span><span style="color: #81A1C1">;</span>
<span style="color: #8FBCBB">console</span><span style="color: #ECEFF4">.</span><span style="color: #88C0D0">warn</span><span style="color: #D8DEE9FF">(</span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">Hello, </span><span style="color: #ECEFF4">"</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #D8DEE9">name</span><span style="color: #D8DEE9FF"> </span><span style="color: #81A1C1">+</span><span style="color: #D8DEE9FF"> </span><span style="color: #ECEFF4">"</span><span style="color: #A3BE8C">!</span><span style="color: #ECEFF4">"</span><span style="color: #D8DEE9FF">)</span>
</code></pre>

API

rehype().use(shiki[, options])

Apply syntax highlighting to pre > code using shiki; which tokenises the code block and new hast nodes are subsequently created from (using this plugin).

Configure the language by using the language-foo class on the code element. For example;

<pre><code class="language-js">console.log("Hello world!")</code></pre>

This is in respect to the mdast-util-to-hast code handler.

Shiki does not perform language detection, if unknown, this plugin falls back to the theme's background and text colour (chosen as settings.foreground from the theme file).

options

options.theme

string, default: 'nord' - Name of shiki theme to use, otherwise path to theme file for it to load.

options.useBackground

boolean, default: true - Whether to apply the background theme colour to the pre element.

License

MIT ยฉ @rsclarke

rehype-shiki's People

Contributors

dependabot-preview[bot] avatar marekweb avatar rsclarke avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

rehype-shiki's Issues

Test Cases

Add test cases for markup validity and theme loading options.

How to use VSCode generated json theme file with MDX?

I'm using MDX with Next.js, for the rehype-shiki plugin, I have passed this option

const withMDX = nextMDX({
  extension: /\.mdx?$/,
  options: {
    rehypePlugins: [
      [rehypeShiki, { theme: './color-light.json' }],
      rehypeSlug,
      rehypeAutoLink,
    ],
    remarkPlugins: [remarkImages],
  },
})

But the plugin won't load the theme. Maybe I use wrong json schema?
The json file I generated from VS Code by using command Developer: Generate Color Theme From Current Settings, which its content is

{
  "$schema": "vscode://schemas/color-theme",
  "type": "light",
  "colors": {
    "activityBar.background": "#24292e",
    "activityBar.foreground": "#fafbfc",
    "activityBarBadge.background": "#54a3ff",
    "editor.background": "#ffffff",
    "editor.foreground": "#24292e",
    "editor.lineHighlightBackground": "#fffbdd",
    "editorBracketMatch.background": "#f1f8ff",
    "editorBracketMatch.border": "#c8e1ff",
    "editorGroupHeader.tabsBackground": "#fafbfc",
    "editorGroupHeader.tabsBorder": "#e1e4e8",
    "editorIndentGuide.background": "#eeeeee",
    "editorLineNumber.foreground": "#cccccc",
    "focusBorder": "#fafbfc",
    "inputOption.activeBorder": "#e36209",
    "scrollbar.shadow": "#00000000",
    "sideBar.background": "#fafbfc",
    "sideBar.border": "#e1e4e8",
    "sideBar.foreground": "#586069",
    "sideBarSectionHeader.background": "#f1f2f3",
    "sideBarSectionHeader.foreground": "#24292e",
    "sideBarTitle.foreground": "#24292e",
    "statusBar.background": "#fafbfc",
    "statusBar.border": "#e1e4e8",
    "statusBar.debuggingBackground": "#fafbfc",
    "statusBar.debuggingForeground": "#24292e",
    "statusBar.foreground": "#24292e",
    "statusBar.noFolderBackground": "#fafbfc",
    "statusBar.noFolderForeground": "#24292e",
    "tab.activeBackground": "#ffffff",
    "tab.activeBorder": "#e36209",
    "tab.border": "#e1e4e8",
    "tab.inactiveBackground": "#fafbfc",
    "tab.inactiveForeground": "#586069",
    "titleBar.activeBackground": "#fafbfc",
    "titleBar.border": "#e1e4e8"
  },
  "tokenColors": [
    {
      "scope": [
        "keyword.operator.accessor",
        "meta.group.braces.round.function.arguments",
        "meta.template.expression",
        "markup.fenced_code meta.embedded.block"
      ],
      "settings": {
        "foreground": "#24292eff"
      }
    },
    {
      "scope": "emphasis",
      "settings": {
        "fontStyle": "italic"
      }
    },
    {
      "scope": [
        "strong",
        "markup.heading.markdown",
        "markup.bold.markdown"
      ],
      "settings": {
        "fontStyle": "bold"
      }
    },
    {
      "scope": [
        "markup.italic.markdown"
      ],
      "settings": {
        "fontStyle": "italic"
      }
    },
    {
      "scope": "meta.link.inline.markdown",
      "settings": {
        "fontStyle": "underline",
        "foreground": "#005cc5"
      }
    },
    {
      "scope": [
        "comment",
        "markup.fenced_code",
        "markup.inline"
      ],
      "settings": {
        "foreground": "#6a737d"
      }
    },
    {
      "scope": "string",
      "settings": {
        "foreground": "#032f62"
      }
    },
    {
      "scope": [
        "constant.numeric",
        "constant.language",
        "variable.language.this",
        "variable.other.class",
        "variable.other.constant",
        "meta.property-name",
        "meta.property-value",
        "support"
      ],
      "settings": {
        "foreground": "#005cc5"
      }
    },
    {
      "scope": [
        "keyword",
        "storage.modifier",
        "storage.type",
        "storage.control.clojure",
        "entity.name.function.clojure",
        "support.function.node",
        "support.type.property-name.json",
        "punctuation.separator.key-value",
        "punctuation.definition.template-expression"
      ],
      "settings": {
        "foreground": "#d73a49"
      }
    },
    {
      "scope": "variable.parameter.function",
      "settings": {
        "foreground": "#E27F2D"
      }
    },
    {
      "scope": [
        "entity.name.type",
        "entity.other.inherited-class",
        "meta.function-call",
        "meta.instance.constructor",
        "entity.other.attribute-name",
        "entity.name.function",
        "constant.keyword.clojure"
      ],
      "settings": {
        "foreground": "#6f42c1"
      }
    },
    {
      "scope": [
        "entity.name.tag",
        "string.quoted",
        "string.regexp",
        "string.interpolated",
        "string.template",
        "keyword.other.template"
      ],
      "settings": {
        "foreground": "#22863a"
      }
    },
    {
      "scope": "token.info-token",
      "settings": {
        "foreground": "#316bcd"
      }
    },
    {
      "scope": "token.warn-token",
      "settings": {
        "foreground": "#cd9731"
      }
    },
    {
      "scope": [
        "token.error-token",
        "invalid"
      ],
      "settings": {
        "foreground": "#cd3131"
      }
    },
    {
      "scope": "token.debug-token",
      "settings": {
        "foreground": "#800080"
      }
    },
    {
      "scope": "markup.inserted",
      "settings": {
        "foreground": "#22863a"
      }
    },
    {
      "scope": "markup.deleted",
      "settings": {
        "foreground": "#d73a49"
      }
    },
    {
      "scope": "markup.changed",
      "settings": {
        "foreground": "#005cc5"
      }
    },
    {
      "scope": "meta.diff.header",
      "settings": {
        "foreground": "#6a737d"
      }
    }
  ]
}

Fallback to a default language if unknown

Allow the developer to configure a default language to fallback to if not in the supported list.

For example lets assume the markdown

` ` `term
class test{
    System.out.println("Hello world");
}
` ` `

And I configure a fallback language with something like...

.use(shiki, {fallbackLanguage: 'java')

would result in

<pre><code class="language-java">
class test{
    System.out.println("Hello world");
}
</code></pre>

useBackground option does not work

I found a small issue with the the way the plugin handles the options.

Steps to reproduce:

Attach the plugin, provide {useBackground: false} as the options, and run it on some HTML with a code block.

Expected behavior:

The plugin does not set a background color on the pre tag.

Actual behavior:

The plugin ignores the options and sets a background color on the pre tag

Incompatibility with react

I have been trying to add syntax highlighting in next.js with next-mdx-remote and rehype-shiki
This is my code:

const mdxSource = await serialize(content, {
    mdxOptions: {
      rehypePlugins: [
        [rehypeShiki, { theme: "nord" }],
      ],
    },
    scope: data,
  });

And the page:

<MDXRemote {...source} components={components} />

But I get this error when I first load the page:
image
And it loads correctly when I refresh.
It seems like there's an error with the pre element
I think rehype-shiki will add strings directly to the style attribute which is unsupported in react.
What should I do to convert them to {color: ""}?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.