From 430c40c3b00c6cd77e1286db4937501131dc24f3 Mon Sep 17 00:00:00 2001 From: pengzhanbo Date: Fri, 6 Sep 2024 01:21:44 +0800 Subject: [PATCH] perf(plugin-shikiji): update `twoslash` --- .../node/twoslash/renderer-floating-vue.ts | 24 ++++++++++++------- .../src/node/twoslash/rendererTransformer.ts | 24 ++++++++++++++++--- theme/src/client/styles/twoslash.css | 15 +++++++++--- 3 files changed, 48 insertions(+), 15 deletions(-) diff --git a/plugins/plugin-shikiji/src/node/twoslash/renderer-floating-vue.ts b/plugins/plugin-shikiji/src/node/twoslash/renderer-floating-vue.ts index 4c43eb74..36ee4bd3 100644 --- a/plugins/plugin-shikiji/src/node/twoslash/renderer-floating-vue.ts +++ b/plugins/plugin-shikiji/src/node/twoslash/renderer-floating-vue.ts @@ -31,7 +31,7 @@ export function rendererFloatingVue(options: TwoslashFloatingVueRendererOptions classCopyIgnore = 'vp-copy-ignore', classFloatingPanel = 'twoslash-floating', classCode = 'vp-code', - classMarkdown = 'plume-content', + classMarkdown = 'vp-doc', floatingVueTheme = 'twoslash', floatingVueThemeQuery = 'twoslash-query', floatingVueThemeCompletion = 'twoslash-completion', @@ -163,14 +163,20 @@ function renderMarkdown(this: ShikiTransformerContextCommon, md: string): Elemen code: (state, node) => { const lang = node.lang || '' if (lang) { - return this.codeToHast( - node.value, - { - ...this.options, - transformers: [], - lang, - }, - ).children[0] as Element + return { + type: 'element', + tagName: 'code', + properties: {}, + children: this.codeToHast( + node.value, + { + ...this.options, + transformers: [], + lang, + structure: node.value.trim().includes('\n') ? 'classic' : 'inline', + }, + ).children, + } } return defaultHandlers.code(state, node) }, diff --git a/plugins/plugin-shikiji/src/node/twoslash/rendererTransformer.ts b/plugins/plugin-shikiji/src/node/twoslash/rendererTransformer.ts index 34e30347..d09e159f 100644 --- a/plugins/plugin-shikiji/src/node/twoslash/rendererTransformer.ts +++ b/plugins/plugin-shikiji/src/node/twoslash/rendererTransformer.ts @@ -1,6 +1,7 @@ -/* eslint-disable node/prefer-global/process */ +import process from 'node:process' import type { TransformerTwoslashOptions } from '@shikijs/twoslash/core' import { createTransformerFactory } from '@shikijs/twoslash/core' +import type { VueSpecificOptions } from 'twoslash-vue' import { createTwoslasher } from 'twoslash-vue' import type { ShikiTransformer } from 'shiki' import { removeTwoslashNotations } from 'twoslash' @@ -9,7 +10,11 @@ import { rendererFloatingVue } from './renderer-floating-vue.js' export * from './renderer-floating-vue.js' -export interface VitePressPluginTwoslashOptions extends TransformerTwoslashOptions, TwoslashFloatingVueRendererOptions { +interface TransformerTwoslashVueOptions extends TransformerTwoslashOptions { + twoslashOptions?: TransformerTwoslashOptions['twoslashOptions'] & VueSpecificOptions +} + +export interface VitePressPluginTwoslashOptions extends TransformerTwoslashVueOptions, TwoslashFloatingVueRendererOptions { /** * Requires adding `twoslash` to the code block explicitly to run twoslash * @default true @@ -19,6 +24,8 @@ export interface VitePressPluginTwoslashOptions extends TransformerTwoslashOptio /** * Create a Shiki transformer for VitePress to enable twoslash integration + * + * Add this to `markdown.codeTransformers` in `.vitepress/config.ts` */ export function transformerTwoslash(options: VitePressPluginTwoslashOptions = {}): ShikiTransformer { const { @@ -38,7 +45,7 @@ export function transformerTwoslash(options: VitePressPluginTwoslashOptions = {} } const twoslash = createTransformerFactory( - createTwoslasher(), + createTwoslasher(options.twoslashOptions), )({ langs: ['ts', 'tsx', 'js', 'jsx', 'json', 'vue'], renderer: rendererFloatingVue(options), @@ -48,6 +55,10 @@ export function transformerTwoslash(options: VitePressPluginTwoslashOptions = {} explicitTrigger, }) + const trigger = explicitTrigger instanceof RegExp + ? explicitTrigger + : /\btwoslash\b/ + return { ...twoslash, name: '@shiki/vuepress-twoslash', @@ -56,6 +67,13 @@ export function transformerTwoslash(options: VitePressPluginTwoslashOptions = {} if (cleanup) options.transformers?.splice(options.transformers.indexOf(cleanup), 1) + // Disable v-pre for twoslash, because we need render it with FloatingVue + if (!explicitTrigger || options.meta?.__raw?.match(trigger)) { + const vPre = options.transformers?.find(i => i.name === 'vitepress:v-pre') + if (vPre) + options.transformers?.splice(options.transformers.indexOf(vPre), 1) + } + return twoslash.preprocess!.call(this, code, options) }, postprocess(html) { diff --git a/theme/src/client/styles/twoslash.css b/theme/src/client/styles/twoslash.css index 5a17a78c..00e4ebfc 100644 --- a/theme/src/client/styles/twoslash.css +++ b/theme/src/client/styles/twoslash.css @@ -302,13 +302,23 @@ .twoslash-floating .twoslash-popup-error { max-width: 700px; max-height: 500px; - padding: 0 12px !important; + padding: 12px !important; overflow: hidden auto; font-family: var(--twoslash-docs-font); font-size: 0.9em; text-wrap: balance; } +.twoslash-floating .twoslash-popup-docs p:first-child, +.twoslash-floating .twoslash-popup-error p:first-child { + margin-top: 0; +} + +.twoslash-floating .twoslash-popup-docs p:last-child, +.twoslash-floating .twoslash-popup-error p:last-child { + margin-bottom: 0; +} + .twoslash-floating .twoslash-popup-docs { color: var(--twoslash-docs-color); border-top: 1px solid var(--twoslash-border-color); @@ -324,8 +334,7 @@ .twoslash-floating .twoslash-popup-docs p, .twoslash-floating .twoslash-popup-error p { - padding: 6px 0; - margin: 0; + margin: 6px 0; text-wrap: balance; }