Skip to content

Commit

Permalink
add docs
Browse files Browse the repository at this point in the history
  • Loading branch information
dimaMachina committed Aug 19, 2023
1 parent 1c8120f commit dfdd8bf
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 53 deletions.
47 changes: 11 additions & 36 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 @@ -361,39 +362,13 @@ nextra({

### Multiple Themes

Provide a record of themes to the `theme` option instead to provide 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"`.

```js filename="next.config.js" {6-11}
nextra({
// ... other options
mdxOptions: {
rehypePrettyCodeOptions: {
theme: {
dark: JSON.parse(
readFileSync('./public/syntax/arctis_dark.json', 'utf8')
),
light: JSON.parse(
readFileSync('./public/syntax/arctis_light.json', 'utf8')
)
}
}
}
})
```

Since syntax highlighting is done at build-time, a code block will be rendered
for every theme and tagged with an attribute `data-theme`, e.g. `data-theme="dark"{:css}`.

You can use CSS to show and hide these code blocks accordingly:

```css filename="global.css"
/* hide code blocks */
html[class~='dark'] .nextra-code-block:has([data-theme='light']),
html[class~='light'] .nextra-code-block:has([data-theme='dark']),
/* hide inline code blocks */
html[class~='dark'] code[data-theme='light'],
html[class~='light'] code[data-theme='dark'] {
display: none;
}
```
<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>
29 changes: 12 additions & 17 deletions packages/nextra/src/mdx-plugins/rehype.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
// @ts-nocheck
import { CODE_BLOCK_FILENAME_REGEX } from '../constants'

function visit(node, tagNames, handler, parent, idx) {
function visit(node, tagNames, handler) {
if (tagNames.includes(node.tagName)) {
handler(node, parent, idx)
handler(node)
return
}
if ('children' in node) {
for (const [i, n] of node.children.entries()) {
visit(n, tagNames, handler, node, i)
for (const n of node.children) {
visit(n, tagNames, handler)
}
}
}
Expand All @@ -31,19 +31,14 @@ export const parseMeta =
}

export const attachMeta = () => tree => {
visit(tree, ['div', 'pre'], (node, parent, idx) => {
const children =
'data-rehype-pretty-code-fragment' in node.properties
? node.children.map(child => ({ ...node, ...child }))
: [node]

for (const node of children) {
node.properties.filename = node.__nextra_filename
node.properties.hasCopyCode = node.__nextra_hasCopyCode
visit(tree, ['div', 'pre'], node => {
if ('data-rehype-pretty-code-fragment' in node.properties) {
// remove <div data-rehype-pretty-code-fragment /> element that wraps <pre /> element
// because we'll wrap with our own <div />
Object.assign(node, node.children[0])
}
// if this is a <div data-rehype-pretty-code-fragment /> element,
// this flattens children that wraps <pre /> element(s) into sibling nodes
// because we'll wrap with our own <div />
parent.children.splice(idx, 1, ...children)

node.properties.filename = node.__nextra_filename
node.properties.hasCopyCode = node.__nextra_hasCopyCode
})
}

0 comments on commit dfdd8bf

Please sign in to comment.