mirror of
https://github.com/mdx-js/mdx.git
synced 2024-09-11 15:05:32 +03:00
Add rehype-starry-night
to website
This commit is contained in:
parent
e61be74560
commit
b749d38fd3
40
package-lock.json
generated
40
package-lock.json
generated
@ -77,6 +77,7 @@
|
||||
"rehype-remove-comments": "^6.0.0",
|
||||
"rehype-shift-heading": "^2.0.0",
|
||||
"rehype-slug": "^6.0.0",
|
||||
"rehype-starry-night": "^2.0.0",
|
||||
"rehype-stringify": "^10.0.0",
|
||||
"remark-cli": "^12.0.0",
|
||||
"remark-directive": "^3.0.0",
|
||||
@ -8378,13 +8379,17 @@
|
||||
}
|
||||
},
|
||||
"node_modules/levenshtein-edit-distance": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/levenshtein-edit-distance/-/levenshtein-edit-distance-1.0.0.tgz",
|
||||
"integrity": "sha512-gpgBvPn7IFIAL32f0o6Nsh2g+5uOvkt4eK9epTfgE4YVxBxwVhJ/p1888lMm/u8mXdu1ETLSi6zeEmkBI+0F3w==",
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/levenshtein-edit-distance/-/levenshtein-edit-distance-3.0.1.tgz",
|
||||
"integrity": "sha512-/qMCkZbrAF7jZP/voqlkfNrBtEn0TMdhCK7OEBh/zb39t/c3wCnTjwU1ZvrMfQ3OxB8sBQXIpWRMM6FiQJVG3g==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"levenshtein-edit-distance": "cli.js"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/levn": {
|
||||
@ -11817,6 +11822,16 @@
|
||||
"levenshtein-edit-distance": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/propose/node_modules/levenshtein-edit-distance": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/levenshtein-edit-distance/-/levenshtein-edit-distance-1.0.0.tgz",
|
||||
"integrity": "sha512-gpgBvPn7IFIAL32f0o6Nsh2g+5uOvkt4eK9epTfgE4YVxBxwVhJ/p1888lMm/u8mXdu1ETLSi6zeEmkBI+0F3w==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"levenshtein-edit-distance": "cli.js"
|
||||
}
|
||||
},
|
||||
"node_modules/proto-props": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/proto-props/-/proto-props-2.0.0.tgz",
|
||||
@ -13122,6 +13137,25 @@
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/rehype-starry-night": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/rehype-starry-night/-/rehype-starry-night-2.0.0.tgz",
|
||||
"integrity": "sha512-4wgKT/oIj+utJa3PHrMfEx2FrjNSxgk8yPXlpWvMjPBEyCxcUuvaJOPzQ5AJeaemcneF6HaN8zPWJASvQgWxfg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/hast": "^3.0.0",
|
||||
"@wooorm/starry-night": "^3.0.0",
|
||||
"hast-util-to-string": "^3.0.0",
|
||||
"levenshtein-edit-distance": "^3.0.0",
|
||||
"unist-util-visit-parents": "^6.0.0",
|
||||
"vfile": "^6.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/unified"
|
||||
}
|
||||
},
|
||||
"node_modules/rehype-stringify": {
|
||||
"version": "10.0.0",
|
||||
"resolved": "https://registry.npmjs.org/rehype-stringify/-/rehype-stringify-10.0.0.tgz",
|
||||
|
@ -81,6 +81,7 @@
|
||||
"rehype-remove-comments": "^6.0.0",
|
||||
"rehype-shift-heading": "^2.0.0",
|
||||
"rehype-slug": "^6.0.0",
|
||||
"rehype-starry-night": "^2.0.0",
|
||||
"rehype-stringify": "^10.0.0",
|
||||
"remark-cli": "^12.0.0",
|
||||
"remark-directive": "^3.0.0",
|
||||
|
@ -1,6 +1,5 @@
|
||||
/**
|
||||
* @import {CompileOptions} from '@mdx-js/mdx'
|
||||
* @import {Grammar} from '@wooorm/starry-night'
|
||||
* @import {Program} from 'estree'
|
||||
* @import {ElementContent, Root} from 'hast'
|
||||
* @import {VFile} from 'vfile'
|
||||
@ -17,12 +16,11 @@
|
||||
|
||||
import {pathToFileURL} from 'node:url'
|
||||
import {nodeTypes} from '@mdx-js/mdx'
|
||||
import {common, createStarryNight} from '@wooorm/starry-night'
|
||||
import {common} from '@wooorm/starry-night'
|
||||
import sourceMdx from '@wooorm/starry-night/source.mdx'
|
||||
import sourceTsx from '@wooorm/starry-night/source.tsx'
|
||||
import {valueToEstree} from 'estree-util-value-to-estree'
|
||||
import {h, s} from 'hastscript'
|
||||
import {toString} from 'hast-util-to-string'
|
||||
import {toText} from 'hast-util-to-text'
|
||||
import {analyze} from 'periscopic'
|
||||
import rehypeAutolinkHeadings from 'rehype-autolink-headings'
|
||||
@ -32,6 +30,7 @@ import rehypeInferTitleMeta from 'rehype-infer-title-meta'
|
||||
import rehypeMinifyUrl from 'rehype-minify-url'
|
||||
import rehypeShiftHeading from 'rehype-shift-heading'
|
||||
import rehypeSlug from 'rehype-slug'
|
||||
import rehypeStarryNight from 'rehype-starry-night'
|
||||
import rehypePresetMinify from 'rehype-preset-minify'
|
||||
import rehypeRaw from 'rehype-raw'
|
||||
import remarkFrontmatter from 'remark-frontmatter'
|
||||
@ -324,99 +323,3 @@ function rehypePrettyCodeBlocks() {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// See:
|
||||
// <https://github.com/wooorm/starry-night#example-integrate-with-unified-remark-and-rehype>.
|
||||
/**
|
||||
* @typedef Options
|
||||
* Configuration (optional)
|
||||
* @property {Array<Grammar> | null | undefined} [grammars]
|
||||
* Grammars to support (default: `common`).
|
||||
*/
|
||||
|
||||
/**
|
||||
* Highlight code with `starry-night`.
|
||||
*
|
||||
* @param {Readonly<Options> | null | undefined} options
|
||||
* Configuration (optional).
|
||||
* @returns
|
||||
* Transform.
|
||||
*/
|
||||
function rehypeStarryNight(options) {
|
||||
const settings = options || {}
|
||||
const grammars = settings.grammars || common
|
||||
const starryNightPromise = createStarryNight(grammars)
|
||||
const prefix = 'language-'
|
||||
|
||||
/**
|
||||
* Transform.
|
||||
*
|
||||
* @param {Root} tree
|
||||
* Tree.
|
||||
* @returns {Promise<undefined>}
|
||||
* Nothing.
|
||||
*/
|
||||
return async function (tree) {
|
||||
const starryNight = await starryNightPromise
|
||||
|
||||
visit(tree, 'element', function (node, index, parent) {
|
||||
if (!parent || typeof index !== 'number' || node.tagName !== 'pre') {
|
||||
return
|
||||
}
|
||||
|
||||
const head = node.children[0]
|
||||
|
||||
if (
|
||||
!head ||
|
||||
head.type !== 'element' ||
|
||||
head.tagName !== 'code' ||
|
||||
!head.properties
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
const classes = head.properties.className
|
||||
|
||||
if (!Array.isArray(classes)) return
|
||||
|
||||
const language = classes.find(function (d) {
|
||||
return typeof d === 'string' && d.startsWith(prefix)
|
||||
})
|
||||
|
||||
if (typeof language !== 'string') return
|
||||
|
||||
const name = language.slice(prefix.length)
|
||||
|
||||
const scope = starryNight.flagToScope(name)
|
||||
|
||||
// Maybe warn?
|
||||
if (!scope) {
|
||||
if (name !== 'txt') console.warn('Missing language: %s', name)
|
||||
return
|
||||
}
|
||||
|
||||
const fragment = starryNight.highlight(toString(head), scope)
|
||||
// Cast because we don’t expect doctypes.
|
||||
const children = /** @type {Array<ElementContent>} */ (fragment.children)
|
||||
|
||||
parent.children.splice(index, 1, {
|
||||
type: 'element',
|
||||
tagName: 'pre',
|
||||
properties: {},
|
||||
children: [
|
||||
{
|
||||
type: 'element',
|
||||
tagName: 'code',
|
||||
properties: {
|
||||
className: [
|
||||
'language-' +
|
||||
scope.replace(/^source\./, '').replaceAll('.', '-')
|
||||
]
|
||||
},
|
||||
children
|
||||
}
|
||||
]
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user