forked from Mirrors/elk
feat: code highlight for tiptap
This commit is contained in:
parent
854d861766
commit
75f49461de
7 changed files with 181 additions and 69 deletions
|
@ -4,8 +4,24 @@ import { NodeViewContent, NodeViewWrapper, nodeViewProps } from '@tiptap/vue-3'
|
||||||
const props = defineProps(nodeViewProps)
|
const props = defineProps(nodeViewProps)
|
||||||
|
|
||||||
const languages = [
|
const languages = [
|
||||||
'js',
|
'c',
|
||||||
'ts',
|
'cpp',
|
||||||
|
'csharp',
|
||||||
|
'css',
|
||||||
|
'dart',
|
||||||
|
'go',
|
||||||
|
'html',
|
||||||
|
'java',
|
||||||
|
'javascript',
|
||||||
|
'jsx',
|
||||||
|
'kotlin',
|
||||||
|
'python',
|
||||||
|
'rust',
|
||||||
|
'svelte',
|
||||||
|
'swift',
|
||||||
|
'tsx',
|
||||||
|
'typescript',
|
||||||
|
'vue',
|
||||||
]
|
]
|
||||||
|
|
||||||
const selectedLanguage = computed({
|
const selectedLanguage = computed({
|
||||||
|
@ -20,8 +36,13 @@ const selectedLanguage = computed({
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<NodeViewWrapper>
|
<NodeViewWrapper>
|
||||||
<div relative my2 class="code-block">
|
<div relative my2>
|
||||||
<select v-model="selectedLanguage" contenteditable="false" absolute top-1 right-1 rounded px2 op0 hover:op100 focus:op100 transition>
|
<select
|
||||||
|
v-model="selectedLanguage"
|
||||||
|
contenteditable="false"
|
||||||
|
absolute top-1 right-1 rounded px2 op0 hover:op100 focus:op100 transition
|
||||||
|
outline-none border="~ base"
|
||||||
|
>
|
||||||
<option :value="null">
|
<option :value="null">
|
||||||
plain
|
plain
|
||||||
</option>
|
</option>
|
||||||
|
@ -29,7 +50,7 @@ const selectedLanguage = computed({
|
||||||
{{ language }}
|
{{ language }}
|
||||||
</option>
|
</option>
|
||||||
</select>
|
</select>
|
||||||
<pre><code><NodeViewContent /></code></pre>
|
<pre class="code-block"><code><NodeViewContent /></code></pre>
|
||||||
</div>
|
</div>
|
||||||
</NodeViewWrapper>
|
</NodeViewWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import type { Highlighter, Lang } from 'shiki-es'
|
import type { Highlighter, Lang } from 'shiki-es'
|
||||||
|
|
||||||
export const shiki = ref<Highlighter>()
|
const shiki = ref<Highlighter>()
|
||||||
|
|
||||||
const registeredLang = ref(new Map<string, boolean>())
|
const registeredLang = ref(new Map<string, boolean>())
|
||||||
let shikiImport: Promise<void> | undefined
|
let shikiImport: Promise<void> | undefined
|
||||||
|
|
||||||
export function highlightCode(code: string, lang: Lang) {
|
export function useHightlighter(lang: Lang) {
|
||||||
if (!shikiImport) {
|
if (!shikiImport) {
|
||||||
shikiImport = import('shiki-es')
|
shikiImport = import('shiki-es')
|
||||||
.then(async (r) => {
|
.then(async (r) => {
|
||||||
|
@ -25,7 +25,7 @@ export function highlightCode(code: string, lang: Lang) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!shiki.value)
|
if (!shiki.value)
|
||||||
return code
|
return undefined
|
||||||
|
|
||||||
if (!registeredLang.value.get(lang)) {
|
if (!registeredLang.value.get(lang)) {
|
||||||
shiki.value.loadLanguage(lang)
|
shiki.value.loadLanguage(lang)
|
||||||
|
@ -37,11 +37,27 @@ export function highlightCode(code: string, lang: Lang) {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
registeredLang.value.set(lang, false)
|
registeredLang.value.set(lang, false)
|
||||||
})
|
})
|
||||||
return code
|
return undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
return shiki.value.codeToHtml(code, {
|
return shiki.value
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useShikiTheme() {
|
||||||
|
return isDark.value ? 'vitesse-dark' : 'vitesse-light'
|
||||||
|
}
|
||||||
|
|
||||||
|
export function highlightCode(code: string, lang: Lang) {
|
||||||
|
const shiki = useHightlighter(lang)
|
||||||
|
if (!shiki)
|
||||||
|
return code
|
||||||
|
|
||||||
|
return shiki.codeToHtml(code, {
|
||||||
lang,
|
lang,
|
||||||
theme: isDark.value ? 'vitesse-dark' : 'vitesse-light',
|
theme: useShikiTheme(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useShiki() {
|
||||||
|
return shiki
|
||||||
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { Extension, VueNodeViewRenderer, useEditor } from '@tiptap/vue-3'
|
import { Extension, useEditor } from '@tiptap/vue-3'
|
||||||
import Placeholder from '@tiptap/extension-placeholder'
|
import Placeholder from '@tiptap/extension-placeholder'
|
||||||
import Document from '@tiptap/extension-document'
|
import Document from '@tiptap/extension-document'
|
||||||
import Paragraph from '@tiptap/extension-paragraph'
|
import Paragraph from '@tiptap/extension-paragraph'
|
||||||
|
@ -10,11 +10,10 @@ import Bold from '@tiptap/extension-bold'
|
||||||
import Italic from '@tiptap/extension-italic'
|
import Italic from '@tiptap/extension-italic'
|
||||||
import Code from '@tiptap/extension-code'
|
import Code from '@tiptap/extension-code'
|
||||||
import { Plugin } from 'prosemirror-state'
|
import { Plugin } from 'prosemirror-state'
|
||||||
import CodeBlock from '@tiptap/extension-code-block'
|
|
||||||
|
|
||||||
import type { Ref } from 'vue'
|
import type { Ref } from 'vue'
|
||||||
import { HashSuggestion, MentionSuggestion } from './tiptap/suggestion'
|
import { HashSuggestion, MentionSuggestion } from './tiptap/suggestion'
|
||||||
import TiptapCodeBlock from '~/components/tiptap/TiptapCodeBlock.vue'
|
import { CodeBlockShiki } from './tiptap/shiki'
|
||||||
|
|
||||||
export interface UseTiptapOptions {
|
export interface UseTiptapOptions {
|
||||||
content: Ref<string | undefined>
|
content: Ref<string | undefined>
|
||||||
|
@ -56,12 +55,7 @@ export function useTiptap(options: UseTiptapOptions) {
|
||||||
CharacterCount.configure({
|
CharacterCount.configure({
|
||||||
limit: characterLimit.value,
|
limit: characterLimit.value,
|
||||||
}),
|
}),
|
||||||
CodeBlock
|
CodeBlockShiki,
|
||||||
.extend({
|
|
||||||
addNodeView() {
|
|
||||||
return VueNodeViewRenderer(TiptapCodeBlock)
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
Extension.create({
|
Extension.create({
|
||||||
name: 'api',
|
name: 'api',
|
||||||
addKeyboardShortcuts() {
|
addKeyboardShortcuts() {
|
||||||
|
|
129
composables/tiptap/shiki.ts
Normal file
129
composables/tiptap/shiki.ts
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
import type { CodeBlockOptions } from '@tiptap/extension-code-block'
|
||||||
|
import CodeBlock from '@tiptap/extension-code-block'
|
||||||
|
import { VueNodeViewRenderer } from '@tiptap/vue-3'
|
||||||
|
|
||||||
|
import { findChildren } from '@tiptap/core'
|
||||||
|
import type { Node as ProsemirrorNode } from 'prosemirror-model'
|
||||||
|
import { Plugin, PluginKey } from 'prosemirror-state'
|
||||||
|
import { Decoration, DecorationSet } from 'prosemirror-view'
|
||||||
|
import TiptapCodeBlock from '~/components/tiptap/TiptapCodeBlock.vue'
|
||||||
|
|
||||||
|
export interface CodeBlockShikiOptions extends CodeBlockOptions {
|
||||||
|
defaultLanguage: string | null | undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CodeBlockShiki = CodeBlock.extend<CodeBlockShikiOptions>({
|
||||||
|
addOptions() {
|
||||||
|
return {
|
||||||
|
...this.parent?.(),
|
||||||
|
defaultLanguage: null,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
addProseMirrorPlugins() {
|
||||||
|
return [
|
||||||
|
...this.parent?.() || [],
|
||||||
|
ProseMirrorShikiPlugin({
|
||||||
|
name: this.name,
|
||||||
|
}),
|
||||||
|
]
|
||||||
|
},
|
||||||
|
|
||||||
|
addNodeView() {
|
||||||
|
return VueNodeViewRenderer(TiptapCodeBlock)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
function getDecorations({
|
||||||
|
doc,
|
||||||
|
name,
|
||||||
|
}: { doc: ProsemirrorNode; name: string }) {
|
||||||
|
const decorations: Decoration[] = []
|
||||||
|
|
||||||
|
findChildren(doc, node => node.type.name === name)
|
||||||
|
.forEach((block) => {
|
||||||
|
let from = block.pos + 1
|
||||||
|
const language = block.node.attrs.language || 'text'
|
||||||
|
|
||||||
|
const shiki = useHightlighter(language)
|
||||||
|
|
||||||
|
if (!shiki)
|
||||||
|
return
|
||||||
|
|
||||||
|
const lines = shiki.codeToThemedTokens(block.node.textContent, language, useShikiTheme())
|
||||||
|
|
||||||
|
lines.forEach((line) => {
|
||||||
|
line.forEach((token) => {
|
||||||
|
const decoration = Decoration.inline(from, from + token.content.length, {
|
||||||
|
style: `color: ${token.color}`,
|
||||||
|
})
|
||||||
|
|
||||||
|
decorations.push(decoration)
|
||||||
|
from += token.content.length
|
||||||
|
})
|
||||||
|
from += 1
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
return DecorationSet.create(doc, decorations)
|
||||||
|
}
|
||||||
|
|
||||||
|
function ProseMirrorShikiPlugin({ name }: { name: string }) {
|
||||||
|
const plugin: Plugin<any> = new Plugin({
|
||||||
|
key: new PluginKey('shiki'),
|
||||||
|
|
||||||
|
state: {
|
||||||
|
init: (_, { doc }) => getDecorations({
|
||||||
|
doc,
|
||||||
|
name,
|
||||||
|
}),
|
||||||
|
apply: (transaction, decorationSet, oldState, newState) => {
|
||||||
|
const oldNodeName = oldState.selection.$head.parent.type.name
|
||||||
|
const newNodeName = newState.selection.$head.parent.type.name
|
||||||
|
const oldNodes = findChildren(oldState.doc, node => node.type.name === name)
|
||||||
|
const newNodes = findChildren(newState.doc, node => node.type.name === name)
|
||||||
|
|
||||||
|
if (
|
||||||
|
transaction.docChanged
|
||||||
|
// Apply decorations if:
|
||||||
|
&& (
|
||||||
|
// selection includes named node,
|
||||||
|
[oldNodeName, newNodeName].includes(name)
|
||||||
|
// OR transaction adds/removes named node,
|
||||||
|
|| newNodes.length !== oldNodes.length
|
||||||
|
// OR transaction has changes that completely encapsulte a node
|
||||||
|
// (for example, a transaction that affects the entire document).
|
||||||
|
// Such transactions can happen during collab syncing via y-prosemirror, for example.
|
||||||
|
|| transaction.steps.some((step) => {
|
||||||
|
// @ts-expect-error cast
|
||||||
|
return step.from !== undefined
|
||||||
|
// @ts-expect-error cast
|
||||||
|
&& step.to !== undefined
|
||||||
|
&& oldNodes.some((node) => {
|
||||||
|
// @ts-expect-error cast
|
||||||
|
return node.pos >= step.from
|
||||||
|
// @ts-expect-error cast
|
||||||
|
&& node.pos + node.node.nodeSize <= step.to
|
||||||
|
})
|
||||||
|
})
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
return getDecorations({
|
||||||
|
doc: transaction.doc,
|
||||||
|
name,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return decorationSet.map(transaction.mapping, transaction.doc)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
props: {
|
||||||
|
decorations(state) {
|
||||||
|
return plugin.getState(state)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
return plugin
|
||||||
|
}
|
|
@ -34,7 +34,6 @@
|
||||||
"@pinia/nuxt": "^0.4.6",
|
"@pinia/nuxt": "^0.4.6",
|
||||||
"@tiptap/extension-character-count": "2.0.0-beta.204",
|
"@tiptap/extension-character-count": "2.0.0-beta.204",
|
||||||
"@tiptap/extension-code-block": "2.0.0-beta.204",
|
"@tiptap/extension-code-block": "2.0.0-beta.204",
|
||||||
"@tiptap/extension-code-block-lowlight": "2.0.0-beta.204",
|
|
||||||
"@tiptap/extension-mention": "2.0.0-beta.204",
|
"@tiptap/extension-mention": "2.0.0-beta.204",
|
||||||
"@tiptap/extension-paragraph": "2.0.0-beta.204",
|
"@tiptap/extension-paragraph": "2.0.0-beta.204",
|
||||||
"@tiptap/extension-placeholder": "2.0.0-beta.204",
|
"@tiptap/extension-placeholder": "2.0.0-beta.204",
|
||||||
|
@ -64,7 +63,6 @@
|
||||||
"js-yaml": "^4.1.0",
|
"js-yaml": "^4.1.0",
|
||||||
"jsdom": "^20.0.3",
|
"jsdom": "^20.0.3",
|
||||||
"lint-staged": "^13.0.4",
|
"lint-staged": "^13.0.4",
|
||||||
"lowlight": "^2.8.0",
|
|
||||||
"lru-cache": "^7.14.1",
|
"lru-cache": "^7.14.1",
|
||||||
"masto": "^4.7.5",
|
"masto": "^4.7.5",
|
||||||
"nuxt": "^3.0.0",
|
"nuxt": "^3.0.0",
|
||||||
|
|
|
@ -14,7 +14,6 @@ specifiers:
|
||||||
'@pinia/nuxt': ^0.4.6
|
'@pinia/nuxt': ^0.4.6
|
||||||
'@tiptap/extension-character-count': 2.0.0-beta.204
|
'@tiptap/extension-character-count': 2.0.0-beta.204
|
||||||
'@tiptap/extension-code-block': 2.0.0-beta.204
|
'@tiptap/extension-code-block': 2.0.0-beta.204
|
||||||
'@tiptap/extension-code-block-lowlight': 2.0.0-beta.204
|
|
||||||
'@tiptap/extension-mention': 2.0.0-beta.204
|
'@tiptap/extension-mention': 2.0.0-beta.204
|
||||||
'@tiptap/extension-paragraph': 2.0.0-beta.204
|
'@tiptap/extension-paragraph': 2.0.0-beta.204
|
||||||
'@tiptap/extension-placeholder': 2.0.0-beta.204
|
'@tiptap/extension-placeholder': 2.0.0-beta.204
|
||||||
|
@ -44,7 +43,6 @@ specifiers:
|
||||||
js-yaml: ^4.1.0
|
js-yaml: ^4.1.0
|
||||||
jsdom: ^20.0.3
|
jsdom: ^20.0.3
|
||||||
lint-staged: ^13.0.4
|
lint-staged: ^13.0.4
|
||||||
lowlight: ^2.8.0
|
|
||||||
lru-cache: ^7.14.1
|
lru-cache: ^7.14.1
|
||||||
masto: ^4.7.5
|
masto: ^4.7.5
|
||||||
nuxt: ^3.0.0
|
nuxt: ^3.0.0
|
||||||
|
@ -86,7 +84,6 @@ devDependencies:
|
||||||
'@pinia/nuxt': 0.4.6_typescript@4.9.3
|
'@pinia/nuxt': 0.4.6_typescript@4.9.3
|
||||||
'@tiptap/extension-character-count': 2.0.0-beta.204
|
'@tiptap/extension-character-count': 2.0.0-beta.204
|
||||||
'@tiptap/extension-code-block': 2.0.0-beta.204
|
'@tiptap/extension-code-block': 2.0.0-beta.204
|
||||||
'@tiptap/extension-code-block-lowlight': 2.0.0-beta.204_czakdrv4w4d5ggkubz4l2tz4ny
|
|
||||||
'@tiptap/extension-mention': 2.0.0-beta.204_ggkstofzpnfxkp3gzsos4mewvi
|
'@tiptap/extension-mention': 2.0.0-beta.204_ggkstofzpnfxkp3gzsos4mewvi
|
||||||
'@tiptap/extension-paragraph': 2.0.0-beta.204
|
'@tiptap/extension-paragraph': 2.0.0-beta.204
|
||||||
'@tiptap/extension-placeholder': 2.0.0-beta.204
|
'@tiptap/extension-placeholder': 2.0.0-beta.204
|
||||||
|
@ -116,7 +113,6 @@ devDependencies:
|
||||||
js-yaml: 4.1.0
|
js-yaml: 4.1.0
|
||||||
jsdom: 20.0.3
|
jsdom: 20.0.3
|
||||||
lint-staged: 13.0.4
|
lint-staged: 13.0.4
|
||||||
lowlight: 2.8.0
|
|
||||||
lru-cache: 7.14.1
|
lru-cache: 7.14.1
|
||||||
masto: 4.7.5
|
masto: 4.7.5
|
||||||
nuxt: 3.0.0_s5ps7njkmjlaqajutnox5ntcla
|
nuxt: 3.0.0_s5ps7njkmjlaqajutnox5ntcla
|
||||||
|
@ -1376,18 +1372,6 @@ packages:
|
||||||
prosemirror-state: 1.4.2
|
prosemirror-state: 1.4.2
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@tiptap/extension-code-block-lowlight/2.0.0-beta.204_czakdrv4w4d5ggkubz4l2tz4ny:
|
|
||||||
resolution: {integrity: sha512-6n2RWlMv7V3NANK+5UfxOMaK83ps8BucleQ/XdNcZuj/glTZco8Z+2E+kazW92c4IFrSgteriYg5ZqC2NBYXrg==}
|
|
||||||
peerDependencies:
|
|
||||||
'@tiptap/core': ^2.0.0-beta.193
|
|
||||||
'@tiptap/extension-code-block': ^2.0.0-beta.193
|
|
||||||
dependencies:
|
|
||||||
'@tiptap/extension-code-block': 2.0.0-beta.204
|
|
||||||
prosemirror-model: 1.18.3
|
|
||||||
prosemirror-state: 1.4.2
|
|
||||||
prosemirror-view: 1.29.1
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@tiptap/extension-code-block/2.0.0-beta.204:
|
/@tiptap/extension-code-block/2.0.0-beta.204:
|
||||||
resolution: {integrity: sha512-IIkZsBT7rxhK7yHnM2LRQfS6i+HNQxU+E6tRtPYF40YSg1xMZSC/xDy0k+NEU/xM6ZVesRofW3voB6svFPPDtw==}
|
resolution: {integrity: sha512-IIkZsBT7rxhK7yHnM2LRQfS6i+HNQxU+E6tRtPYF40YSg1xMZSC/xDy0k+NEU/xM6ZVesRofW3voB6svFPPDtw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -1644,12 +1628,6 @@ packages:
|
||||||
'@types/node': 18.11.10
|
'@types/node': 18.11.10
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@types/hast/2.3.4:
|
|
||||||
resolution: {integrity: sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g==}
|
|
||||||
dependencies:
|
|
||||||
'@types/unist': 2.0.6
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/@types/js-yaml/4.0.5:
|
/@types/js-yaml/4.0.5:
|
||||||
resolution: {integrity: sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==}
|
resolution: {integrity: sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -4508,12 +4486,6 @@ packages:
|
||||||
reusify: 1.0.4
|
reusify: 1.0.4
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/fault/2.0.1:
|
|
||||||
resolution: {integrity: sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==}
|
|
||||||
dependencies:
|
|
||||||
format: 0.2.2
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/fetch-blob/3.2.0:
|
/fetch-blob/3.2.0:
|
||||||
resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
|
resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==}
|
||||||
engines: {node: ^12.20 || >= 14.13}
|
engines: {node: ^12.20 || >= 14.13}
|
||||||
|
@ -4624,11 +4596,6 @@ packages:
|
||||||
mime-types: 2.1.35
|
mime-types: 2.1.35
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/format/0.2.2:
|
|
||||||
resolution: {integrity: sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==}
|
|
||||||
engines: {node: '>=0.4.x'}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/formdata-polyfill/4.0.10:
|
/formdata-polyfill/4.0.10:
|
||||||
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
|
resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==}
|
||||||
engines: {node: '>=12.20.0'}
|
engines: {node: '>=12.20.0'}
|
||||||
|
@ -4966,11 +4933,6 @@ packages:
|
||||||
tslib: 2.4.1
|
tslib: 2.4.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/highlight.js/11.7.0:
|
|
||||||
resolution: {integrity: sha512-1rRqesRFhMO/PRF+G86evnyJkCgaZFOI+Z6kdj15TA18funfoqJXvgPCLSf0SWq3SRfg1j3HlDs8o4s3EGq1oQ==}
|
|
||||||
engines: {node: '>=12.0.0'}
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/hookable/5.4.2:
|
/hookable/5.4.2:
|
||||||
resolution: {integrity: sha512-6rOvaUiNKy9lET1X0ECnyZ5O5kSV0PJbtA5yZUgdEF7fGJEVwSLSislltyt7nFwVVALYHQJtfGeAR2Y0A0uJkg==}
|
resolution: {integrity: sha512-6rOvaUiNKy9lET1X0ECnyZ5O5kSV0PJbtA5yZUgdEF7fGJEVwSLSislltyt7nFwVVALYHQJtfGeAR2Y0A0uJkg==}
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -5771,14 +5733,6 @@ packages:
|
||||||
tslib: 2.4.1
|
tslib: 2.4.1
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/lowlight/2.8.0:
|
|
||||||
resolution: {integrity: sha512-WeExw1IKEkel9ZcYwzpvcFzORIB0IlleTcxJYoEuUgHASuYe/OBYbV6ym/AetG7unNVCBU/SXpgTgs2nT93mhg==}
|
|
||||||
dependencies:
|
|
||||||
'@types/hast': 2.3.4
|
|
||||||
fault: 2.0.1
|
|
||||||
highlight.js: 11.7.0
|
|
||||||
dev: true
|
|
||||||
|
|
||||||
/lru-cache/6.0.0:
|
/lru-cache/6.0.0:
|
||||||
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
|
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
|
|
|
@ -104,7 +104,7 @@ body {
|
||||||
--at-apply: bg-code text-code px1 py0.5 rounded text-0.9em leading-0.8em;
|
--at-apply: bg-code text-code px1 py0.5 rounded text-0.9em leading-0.8em;
|
||||||
}
|
}
|
||||||
pre code {
|
pre code {
|
||||||
--at-apply: bg-transparent px0 py0 rounded-none;
|
--at-apply: bg-transparent px0 py0 rounded-none leading-1.6em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.code-block {
|
.code-block {
|
||||||
|
|
Loading…
Reference in a new issue