Skip to content

update shiki #288

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions apps/svelte.dev/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,6 @@
"prettier-plugin-svelte": "^3.2.4",
"satori": "^0.10.13",
"satori-html": "^0.3.2",
"shiki": "^1.6.4",
"shiki-twoslash": "^3.1.2",
"svelte": "5.0.0-next.260",
"svelte-check": "^4.0.0",
"svelte-preprocess": "^5.1.4",
Expand Down
3 changes: 2 additions & 1 deletion packages/site-kit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@
"@fontsource/eb-garamond": "^5.1.0",
"@fontsource/fira-mono": "^5.1.0",
"@fontsource/fira-sans": "^5.1.0",
"@shikijs/twoslash": "^1.22.0",
"esm-env": "^1.0.0",
"json5": "^2.2.3",
"shiki": "^1.22.0",
"svelte-persisted-store": "^0.9.2"
},
"devDependencies": {
Expand All @@ -38,7 +40,6 @@
"marked": "^14.1.2",
"prettier": "^3.3.2",
"prettier-plugin-svelte": "^3.2.4",
"shiki-twoslash": "^3.1.2",
"svelte": "5.0.0-next.260",
"svelte-check": "^4.0.0",
"typescript": "^5.5.4",
Expand Down
6 changes: 3 additions & 3 deletions packages/site-kit/src/lib/docs/hover.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export function setupDocsHovers() {
function over(event: MouseEvent) {
const target = event.target as HTMLElement;

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

if (tooltip) {
Expand All @@ -18,7 +18,7 @@ export function setupDocsHovers() {
}

const rect = target?.getBoundingClientRect();
const html = target?.getAttribute('lsp');
const html = target?.innerHTML;

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

function out(event: MouseEvent) {
const target = event.target as HTMLElement;
if (target.tagName === 'DATA-LSP') {
if (target.classList?.contains('twoslash-hover')) {
timeout = setTimeout(() => {
unmount(tooltip);
tooltip = null;
Expand Down
70 changes: 22 additions & 48 deletions packages/site-kit/src/lib/markdown/renderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ import fs from 'node:fs';
import path from 'node:path';
import ts from 'typescript';
import * as prettier from 'prettier';
import { codeToHtml, createCssVariablesTheme } from 'shiki';
import { transformerTwoslash } from '@shikijs/twoslash';
import { SHIKI_LANGUAGE_MAP, escape, normalizeSlugify, smart_quotes, transform } from './utils';
import type { Declaration, TypeElement, Modules } from './index';

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

let twoslash_module: typeof import('shiki-twoslash');
const theme = createCssVariablesTheme({
name: 'css-variables',
variablePrefix: '--shiki-',
variableDefaults: {},
fontStyle: true
});

/**
* A super markdown renderer function. Renders svelte and kit docs specific specific markdown code to html.
Expand Down Expand Up @@ -126,10 +133,6 @@ export async function render_content_markdown(
resolveTypeLinks
}: RenderContentOptions = {}
) {
twoslash_module ??= await import('shiki-twoslash');

const highlighter = await twoslash_module.createShikiHighlighter({ theme: 'css-variables' });

const { type_links, type_regex } = create_type_links(modules, resolveTypeLinks);
const snippets = await create_snippet_cache(cacheCodeSnippets);

Expand Down Expand Up @@ -177,19 +180,17 @@ export async function render_content_markdown(

html += '</div>';

html += syntax_highlight({
html += await syntax_highlight({
filename,
highlighter,
language: token.lang,
source,
twoslashBanner,
options
});

if (converted) {
html += syntax_highlight({
html += await syntax_highlight({
filename,
highlighter,
language: token.lang === 'js' ? 'ts' : token.lang,
source: converted,
twoslashBanner,
Expand Down Expand Up @@ -932,32 +933,27 @@ function replace_blank_lines(html: string) {
return html.replaceAll(/<div class='line'>(&nbsp;)?<\/div>/g, '<div class="line">\n</div>');
}

function syntax_highlight({
async function syntax_highlight({
source,
filename,
language,
highlighter,
twoslashBanner,
options
}: {
source: string;
filename: string;
language: string;
highlighter: Awaited<ReturnType<typeof import('shiki-twoslash').createShikiHighlighter>>;
twoslashBanner?: TwoslashBanner;
options: SnippetOptions;
}) {
let html = '';

if (/^(dts|yaml|yml)/.test(language)) {
html = replace_blank_lines(
twoslash_module.renderCodeToHTML(
source,
language === 'dts' ? 'ts' : language,
{ twoslash: false },
{ themeName: 'css-variables' },
highlighter
)
await codeToHtml(source, {
lang: language === 'dts' ? 'ts' : language,
theme
})
);
} else if (/^(js|ts)/.test(language)) {
try {
Expand All @@ -974,41 +970,18 @@ function syntax_highlight({
}
}

const twoslash = twoslash_module.runTwoSlash(source, language, {
defaultCompilerOptions: {
allowJs: true,
checkJs: true,
target: ts.ScriptTarget.ES2022,
types: ['svelte', '@sveltejs/kit']
}
html = await codeToHtml(source, {
lang: 'ts',
theme,
transformers: [transformerTwoslash({})]
});

html = twoslash_module.renderCodeToHTML(
twoslash.code,
'ts',
{ twoslash: true },
// @ts-ignore Why shiki-twoslash requires a theme name?
{},
highlighter,
twoslash
);
} catch (e) {
console.error(`Error compiling snippet in ${filename}`);
// @ts-ignore
console.error(e.code);
throw e;
}

// we need to be able to inject the LSP attributes as HTML, not text, so we
// turn &lt; into &amp;lt;
html = html.replace(
/<data-lsp lsp='([^']*)'([^>]*)>(\w+)<\/data-lsp>/g,
(_, lsp, attrs, name) => {
if (!lsp) return name;
return `<data-lsp lsp='${lsp.replace(/&/g, '&amp;')}'${attrs}>${name}</data-lsp>`;
}
);

html = replace_blank_lines(html);
} else if (language === 'diff') {
const lines = source.split('\n').map((content) => {
Expand All @@ -1031,8 +1004,9 @@ function syntax_highlight({
})
.join('')}</code></pre>`;
} else {
const highlighted = highlighter.codeToHtml(source, {
lang: SHIKI_LANGUAGE_MAP[language as keyof typeof SHIKI_LANGUAGE_MAP]
const highlighted = await codeToHtml(source, {
lang: SHIKI_LANGUAGE_MAP[language as keyof typeof SHIKI_LANGUAGE_MAP],
theme
});

html = replace_blank_lines(highlighted);
Expand Down
17 changes: 7 additions & 10 deletions packages/site-kit/src/lib/styles/code.css
Original file line number Diff line number Diff line change
Expand Up @@ -58,15 +58,12 @@ html.dark {
display: none;
}

pre.twoslash :where(.error, .error-behind) {
display: none;
}

pre.twoslash data-lsp {
transition: border-color 0.3s;
border-bottom: 1px dotted transparent;
}
pre {
.twoslash-hover {
position: relative;

pre.twoslash:hover data-lsp {
border-color: var(--sk-back-5);
.twoslash-popup-container {
display: none;
}
}
}
Loading
Loading