Skip to content

Commit a51a014

Browse files
authored
update shiki (#288)
1 parent 0ede395 commit a51a014

File tree

6 files changed

+344
-146
lines changed

6 files changed

+344
-146
lines changed

apps/svelte.dev/package.json

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,6 @@
8282
"prettier-plugin-svelte": "^3.2.4",
8383
"satori": "^0.10.13",
8484
"satori-html": "^0.3.2",
85-
"shiki": "^1.6.4",
86-
"shiki-twoslash": "^3.1.2",
8785
"svelte": "5.0.0-next.260",
8886
"svelte-check": "^4.0.0",
8987
"svelte-preprocess": "^5.1.4",

packages/site-kit/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,10 @@
2626
"@fontsource/eb-garamond": "^5.1.0",
2727
"@fontsource/fira-mono": "^5.1.0",
2828
"@fontsource/fira-sans": "^5.1.0",
29+
"@shikijs/twoslash": "^1.22.0",
2930
"esm-env": "^1.0.0",
3031
"json5": "^2.2.3",
32+
"shiki": "^1.22.0",
3133
"svelte-persisted-store": "^0.9.2"
3234
},
3335
"devDependencies": {
@@ -38,7 +40,6 @@
3840
"marked": "^14.1.2",
3941
"prettier": "^3.3.2",
4042
"prettier-plugin-svelte": "^3.2.4",
41-
"shiki-twoslash": "^3.1.2",
4243
"svelte": "5.0.0-next.260",
4344
"svelte-check": "^4.0.0",
4445
"typescript": "^5.5.4",

packages/site-kit/src/lib/docs/hover.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export function setupDocsHovers() {
99
function over(event: MouseEvent) {
1010
const target = event.target as HTMLElement;
1111

12-
if (target.tagName === 'DATA-LSP') {
12+
if (target.classList?.contains('twoslash-hover')) {
1313
clearTimeout(timeout);
1414

1515
if (tooltip) {
@@ -18,7 +18,7 @@ export function setupDocsHovers() {
1818
}
1919

2020
const rect = target?.getBoundingClientRect();
21-
const html = target?.getAttribute('lsp');
21+
const html = target?.innerHTML;
2222

2323
const x = (rect.left + rect.right) / 2 + window.scrollX;
2424
const y = rect.top + window.scrollY;
@@ -46,7 +46,7 @@ export function setupDocsHovers() {
4646

4747
function out(event: MouseEvent) {
4848
const target = event.target as HTMLElement;
49-
if (target.tagName === 'DATA-LSP') {
49+
if (target.classList?.contains('twoslash-hover')) {
5050
timeout = setTimeout(() => {
5151
unmount(tooltip);
5252
tooltip = null;

packages/site-kit/src/lib/markdown/renderer.ts

Lines changed: 22 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import fs from 'node:fs';
44
import path from 'node:path';
55
import ts from 'typescript';
66
import * as prettier from 'prettier';
7+
import { codeToHtml, createCssVariablesTheme } from 'shiki';
8+
import { transformerTwoslash } from '@shikijs/twoslash';
79
import { SHIKI_LANGUAGE_MAP, escape, normalizeSlugify, smart_quotes, transform } from './utils';
810
import type { Declaration, TypeElement, Modules } from './index';
911

@@ -31,7 +33,12 @@ interface RenderContentOptions {
3133
const METADATA_REGEX =
3234
/(?:<!---\s*|\/\/\/\s*|###\s*)(?<key>file|link|copy):\s*(?<value>.*?)(?:\s*--->|$)\n/gm;
3335

34-
let twoslash_module: typeof import('shiki-twoslash');
36+
const theme = createCssVariablesTheme({
37+
name: 'css-variables',
38+
variablePrefix: '--shiki-',
39+
variableDefaults: {},
40+
fontStyle: true
41+
});
3542

3643
/**
3744
* A super markdown renderer function. Renders svelte and kit docs specific specific markdown code to html.
@@ -126,10 +133,6 @@ export async function render_content_markdown(
126133
resolveTypeLinks
127134
}: RenderContentOptions = {}
128135
) {
129-
twoslash_module ??= await import('shiki-twoslash');
130-
131-
const highlighter = await twoslash_module.createShikiHighlighter({ theme: 'css-variables' });
132-
133136
const { type_links, type_regex } = create_type_links(modules, resolveTypeLinks);
134137
const snippets = await create_snippet_cache(cacheCodeSnippets);
135138

@@ -177,19 +180,17 @@ export async function render_content_markdown(
177180

178181
html += '</div>';
179182

180-
html += syntax_highlight({
183+
html += await syntax_highlight({
181184
filename,
182-
highlighter,
183185
language: token.lang,
184186
source,
185187
twoslashBanner,
186188
options
187189
});
188190

189191
if (converted) {
190-
html += syntax_highlight({
192+
html += await syntax_highlight({
191193
filename,
192-
highlighter,
193194
language: token.lang === 'js' ? 'ts' : token.lang,
194195
source: converted,
195196
twoslashBanner,
@@ -932,32 +933,27 @@ function replace_blank_lines(html: string) {
932933
return html.replaceAll(/<div class='line'>(&nbsp;)?<\/div>/g, '<div class="line">\n</div>');
933934
}
934935

935-
function syntax_highlight({
936+
async function syntax_highlight({
936937
source,
937938
filename,
938939
language,
939-
highlighter,
940940
twoslashBanner,
941941
options
942942
}: {
943943
source: string;
944944
filename: string;
945945
language: string;
946-
highlighter: Awaited<ReturnType<typeof import('shiki-twoslash').createShikiHighlighter>>;
947946
twoslashBanner?: TwoslashBanner;
948947
options: SnippetOptions;
949948
}) {
950949
let html = '';
951950

952951
if (/^(dts|yaml|yml)/.test(language)) {
953952
html = replace_blank_lines(
954-
twoslash_module.renderCodeToHTML(
955-
source,
956-
language === 'dts' ? 'ts' : language,
957-
{ twoslash: false },
958-
{ themeName: 'css-variables' },
959-
highlighter
960-
)
953+
await codeToHtml(source, {
954+
lang: language === 'dts' ? 'ts' : language,
955+
theme
956+
})
961957
);
962958
} else if (/^(js|ts)/.test(language)) {
963959
try {
@@ -974,41 +970,18 @@ function syntax_highlight({
974970
}
975971
}
976972

977-
const twoslash = twoslash_module.runTwoSlash(source, language, {
978-
defaultCompilerOptions: {
979-
allowJs: true,
980-
checkJs: true,
981-
target: ts.ScriptTarget.ES2022,
982-
types: ['svelte', '@sveltejs/kit']
983-
}
973+
html = await codeToHtml(source, {
974+
lang: 'ts',
975+
theme,
976+
transformers: [transformerTwoslash({})]
984977
});
985-
986-
html = twoslash_module.renderCodeToHTML(
987-
twoslash.code,
988-
'ts',
989-
{ twoslash: true },
990-
// @ts-ignore Why shiki-twoslash requires a theme name?
991-
{},
992-
highlighter,
993-
twoslash
994-
);
995978
} catch (e) {
996979
console.error(`Error compiling snippet in ${filename}`);
997980
// @ts-ignore
998981
console.error(e.code);
999982
throw e;
1000983
}
1001984

1002-
// we need to be able to inject the LSP attributes as HTML, not text, so we
1003-
// turn &lt; into &amp;lt;
1004-
html = html.replace(
1005-
/<data-lsp lsp='([^']*)'([^>]*)>(\w+)<\/data-lsp>/g,
1006-
(_, lsp, attrs, name) => {
1007-
if (!lsp) return name;
1008-
return `<data-lsp lsp='${lsp.replace(/&/g, '&amp;')}'${attrs}>${name}</data-lsp>`;
1009-
}
1010-
);
1011-
1012985
html = replace_blank_lines(html);
1013986
} else if (language === 'diff') {
1014987
const lines = source.split('\n').map((content) => {
@@ -1031,8 +1004,9 @@ function syntax_highlight({
10311004
})
10321005
.join('')}</code></pre>`;
10331006
} else {
1034-
const highlighted = highlighter.codeToHtml(source, {
1035-
lang: SHIKI_LANGUAGE_MAP[language as keyof typeof SHIKI_LANGUAGE_MAP]
1007+
const highlighted = await codeToHtml(source, {
1008+
lang: SHIKI_LANGUAGE_MAP[language as keyof typeof SHIKI_LANGUAGE_MAP],
1009+
theme
10361010
});
10371011

10381012
html = replace_blank_lines(highlighted);

packages/site-kit/src/lib/styles/code.css

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,12 @@ html.dark {
5858
display: none;
5959
}
6060

61-
pre.twoslash :where(.error, .error-behind) {
62-
display: none;
63-
}
64-
65-
pre.twoslash data-lsp {
66-
transition: border-color 0.3s;
67-
border-bottom: 1px dotted transparent;
68-
}
61+
pre {
62+
.twoslash-hover {
63+
position: relative;
6964

70-
pre.twoslash:hover data-lsp {
71-
border-color: var(--sk-back-5);
65+
.twoslash-popup-container {
66+
display: none;
67+
}
68+
}
7269
}

0 commit comments

Comments
 (0)