Skip to content

Commit

Permalink
fix: support multiple overridden syntax themes (#1992)
Browse files Browse the repository at this point in the history
Co-authored-by: Dimitri POSTOLOV <dmytropostolov@gmail.com>
Co-authored-by: Dimitri POSTOLOV <en3m@ya.ru>
  • Loading branch information
3 people committed Aug 19, 2023
1 parent 46743ba commit d39102f
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 6 deletions.
1 change: 1 addition & 0 deletions .eslintrc.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ module.exports = {
'prefer-regex-literals': ['error', { disallowRedundantWrapping: true }],
'object-shorthand': ['error', 'always'],
'unicorn/prefer-regexp-test': 'error',
'unicorn/no-array-for-each': 'error',
'@typescript-eslint/prefer-for-of': 'error',
// todo: enable
'@typescript-eslint/no-explicit-any': 'off',
Expand Down
75 changes: 72 additions & 3 deletions docs/pages/docs/guide/syntax-highlighting.mdx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { OptionTable } from 'components/table'
import { Callout } from 'nextra/components'

# Syntax Highlighting

Nextra uses [Shiki](https://shiki.matsu.io) to do syntax highlighting at build
time. Its very reliable and performant. For example, adding this in your
time. It's very reliable and performant. For example, adding this in your
Markdown file:

````md filename="Markdown"
Expand Down Expand Up @@ -182,7 +183,7 @@ Renders:
Check [this list](https://github.com/shikijs/shiki/blob/main/docs/languages.md)
for all supported languages.

## Customize The Theme
## Customize the Theme

Nextra uses CSS variables to define the colors for tokens. You can inject a
[global CSS](https://nextjs.org/docs/basic-features/built-in-css-support#adding-a-global-stylesheet)
Expand Down Expand Up @@ -213,7 +214,7 @@ tokens and you can override any of these:
--shiki-token-parameter: #ff9800;
--shiki-token-function: #b392f0;
--shiki-token-string-expression: #4bb74a;
--shiki-token-punctuation: #bbbbbb;
--shiki-token-punctuation: #bbb;
--shiki-token-link: #ffab70;
}
```
Expand Down Expand Up @@ -303,3 +304,71 @@ Nextra configuration (`next.config.js` file).
]
]}
/>

## Custom Grammar

Shiki accepts a
[VSCode TextMate Grammar](https://code.visualstudio.com/api/language-extensions/syntax-highlight-guide)
for syntax highlighting with custom language grammars.

You can provide these grammars by overriding the `getHighlighter` function in
`mdxOptions.rehypePrettyCodeOptions` option in your Nextra config inside
`next.config.js`:

```js filename="next.config.js" {13-18}
import { BUNDLED_LANGUAGES } from 'shiki'

nextra({
// ... other options
mdxOptions: {
rehypePrettyCodeOptions: {
getHighlighter: options =>
getHighlighter({
...options,
langs: [
...BUNDLED_LANGUAGES,
// custom grammar options, see the Shiki documentation for how to provide these options
{
id: 'my-lang',
scopeName: 'source.my-lang',
aliases: ['mylang'], // Along with id, aliases will be included in the allowed names you can use when writing markdown.
path: '../../public/syntax/grammar.tmLanguage.json'
}
]
})
}
}
})
```

## Custom Themes

Within `mdxOptions.rehypePrettyCodeOptions` you may also provide custom themes
instead of [relying on CSS Variables](/docs/guide/syntax-highlighting):

```js filename="next.config.js" {4}
nextra({
// ... other options
mdxOptions: {
rehypePrettyCodeOptions: {
// VSCode theme or built-in Shiki theme, see Shiki documentation for more information
theme: JSON.parse(
readFileSync('./public/syntax/arctis_light.json', 'utf8')
)
}
}
})
```

### Multiple Themes

Nextra currently doesn't support specifying multiple themes. Because Shiki
renders multiple code blocks for every theme and tags them with an attribute
`data-theme`, e.g. `data-theme="dark"`.

<Callout type="info">
However, in the future, multiple themes will be supported. You can track the
progress in shikiji (newly fork of Shiki)
https://github.com/antfu/shikiji#multiple-themes that already supports
multiple themes without rendering multiple code blocks.
</Callout>
8 changes: 6 additions & 2 deletions packages/nextra-theme-blog/src/utils/get-tags.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,17 @@ interface Page extends MdxFile {

const flattenPageMap = (page: Page, result: PageMapItem[] = []) => {
if (Array.isArray(page.children!)) {
page.children.forEach(p => flattenPageMap(p, result))
for (const p of page.children) {
flattenPageMap(p, result)
}
}
result.push(page)
}

const flattenPageMaps = (pages: Page[], result: PageMapItem[] = []) => {
pages.forEach(v => flattenPageMap(v, result))
for (const v of pages) {
flattenPageMap(v, result)
}
}
export const getStaticTags = (pageMap: PageMapItem[]) => {
const result: MdxFile[] = []
Expand Down
6 changes: 5 additions & 1 deletion packages/nextra/src/mdx-plugins/rehype.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ function visit(node, tagNames, handler) {
handler(node)
return
}
node.children?.forEach(n => visit(n, tagNames, handler))
if ('children' in node) {
for (const n of node.children) {
visit(n, tagNames, handler)
}
}
}

export const parseMeta =
Expand Down

1 comment on commit d39102f

@vercel
Copy link

@vercel vercel bot commented on d39102f Aug 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.