代码装饰
我们提供了一个装饰代码的 API,用来将渲染后指定位置的代码元素包裹在自定义类或前缀中。
ts
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 和 character 都是从 0 开始索引的
start: { line: 1, character: 0 },
end: { line: 1, character: 11 },
properties: { class: 'highlighted-word' }
}
]
})
渲染的结果是(已使用 CSS 样式化):
ts
const x = 10
console.log(x)
你也可以用代码相对偏移位置(以 0 作为索引)来指定位置:
ts
import { codeToHtml } from 'shiki'
const code = `
const x = 10
console.log(x)
`.trim()
// ---cut---
const html = await codeToHtml(code, {
theme: 'vitesse-light',
lang: 'ts',
decorations: [
{
start: 21,
end: 24,
properties: { class: 'highlighted-word' }
}
]
})
这会渲染出:
ts
const x = 10
console.log(x)
在转换器中使用代码装饰
对于一些高级的用例,你可以使用 转换器 API 来完全控制标签和 HAST 树。
如果你想在转换器中添加代码装饰,你可以使用以下的方法:
ts
/* eslint-disable import/no-duplicates */
import { DecorationItem } from 'shiki'
function doSomethingWithCode(code: string): DecorationItem[] {
return []
}
const code: string = ''
// ---cut---
import { ShikiTransformer, codeToHtml } from 'shiki'
const myTransformer: ShikiTransformer = {
name: 'my-transformer',
preprocess(code, options) {
// 用某种方式生成代码装饰
const decorations = doSomethingWithCode(code)
// 确保装饰数组存在
options.decorations ||= []
// 添加代码装饰
options.decorations.push(...decorations)
}
}
const html = await codeToHtml(code, {
theme: 'vitesse-light',
lang: 'ts',
transformers: [
myTransformer
]
})
注意,你只能在 preprocess
钩子添加代码装饰,在往后的钩子中,装饰数组的修改会被忽略。