From beb0f8ae9b710a3fb5cb1e6e66c994eed26dc26d Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Tue, 15 Oct 2024 18:17:28 +0100 Subject: [PATCH 1/2] fix: remove twoslash elements --- .../site-kit/src/lib/markdown/renderer.ts | 67 +------------------ 1 file changed, 3 insertions(+), 64 deletions(-) diff --git a/packages/site-kit/src/lib/markdown/renderer.ts b/packages/site-kit/src/lib/markdown/renderer.ts index d5355076bd..b0b738ebb4 100644 --- a/packages/site-kit/src/lib/markdown/renderer.ts +++ b/packages/site-kit/src/lib/markdown/renderer.ts @@ -3,7 +3,6 @@ import { createHash, Hash } from 'node:crypto'; import fs from 'node:fs'; import path from 'node:path'; import ts from 'typescript'; -import * as marked from 'marked'; import { codeToHtml, createCssVariablesTheme } from 'shiki'; import { transformerTwoslash } from '@shikijs/twoslash'; import { SHIKI_LANGUAGE_MAP, slugify, smart_quotes, transform } from './utils'; @@ -186,11 +185,11 @@ const snippets = await create_snippet_cache(); export async function render_content_markdown( filename: string, body: string, - options?: { check?: boolean }, + options: { check?: boolean }, twoslashBanner?: TwoslashBanner ) { const headings: string[] = []; - const { check = true } = options ?? {}; + const { check = true } = options; return await transform(body, { async walkTokens(token) { @@ -659,7 +658,7 @@ async function syntax_highlight({ }); try { - html = await codeToHtml(prelude + redacted, { + html = await codeToHtml('// @noErrors\n' + prelude + redacted, { lang: 'ts', theme, transformers: check @@ -676,66 +675,6 @@ async function syntax_highlight({ }); html = html.replace(/ {27,}/g, () => redactions.shift()!); - - if (check) { - // munge the twoslash output so that it renders sensibly. the order of operations - // here is important — we need to work backwards, to avoid corrupting the offsets - const replacements: Array<{ start: number; end: number; content: string }> = []; - - for (const match of html.matchAll(/
([^]+?)<\/div>/g)) { - const content = await render_content_markdown('', match[1], { check: false }); - - replacements.push({ - start: match.index, - end: match.index + match[0].length, - content: '
' + content + '
' - }); - } - - while (replacements.length > 0) { - const { start, end, content } = replacements.pop()!; - html = html.slice(0, start) + content + html.slice(end); - } - - for (const match of html.matchAll( - /([^]+?)<\/span>([^]+?)<\/span><\/span>/g - )) { - const tag = match[1]; - let value = match[2]; - - let content = `${tag}`; - - if (tag === '@param' || tag === '@throws') { - const words = value.split(' '); - let param = words.shift()!; - value = words.join(' '); - - if (tag === '@throws') { - if (param[0] !== '{' || param[param.length - 1] !== '}') { - throw new Error('TODO robustify @throws handling'); - } - - param = param.slice(1, -1); - } - - content += `${param} `; - } - - content += marked.parseInline(value); - content += ''; - - replacements.push({ - start: match.index, - end: match.index + match[0].length, - content: '
' + content + '
' - }); - } - - while (replacements.length > 0) { - const { start, end, content } = replacements.pop()!; - html = html.slice(0, start) + content + html.slice(end); - } - } } catch (e) { console.error((e as Error).message); console.warn(prelude + redacted); From 313923a7fcf9ac0ea2839861c6838e6ea4aa86ba Mon Sep 17 00:00:00 2001 From: Dominic Gannaway Date: Tue, 15 Oct 2024 18:58:36 +0100 Subject: [PATCH 2/2] oops --- .../site-kit/src/lib/markdown/renderer.ts | 65 ++++++++++++++++++- 1 file changed, 63 insertions(+), 2 deletions(-) diff --git a/packages/site-kit/src/lib/markdown/renderer.ts b/packages/site-kit/src/lib/markdown/renderer.ts index b0b738ebb4..504c101325 100644 --- a/packages/site-kit/src/lib/markdown/renderer.ts +++ b/packages/site-kit/src/lib/markdown/renderer.ts @@ -3,6 +3,7 @@ import { createHash, Hash } from 'node:crypto'; import fs from 'node:fs'; import path from 'node:path'; import ts from 'typescript'; +import * as marked from 'marked'; import { codeToHtml, createCssVariablesTheme } from 'shiki'; import { transformerTwoslash } from '@shikijs/twoslash'; import { SHIKI_LANGUAGE_MAP, slugify, smart_quotes, transform } from './utils'; @@ -185,11 +186,11 @@ const snippets = await create_snippet_cache(); export async function render_content_markdown( filename: string, body: string, - options: { check?: boolean }, + options?: { check?: boolean }, twoslashBanner?: TwoslashBanner ) { const headings: string[] = []; - const { check = true } = options; + const { check = true } = options ?? {}; return await transform(body, { async walkTokens(token) { @@ -675,6 +676,66 @@ async function syntax_highlight({ }); html = html.replace(/ {27,}/g, () => redactions.shift()!); + + if (check) { + // munge the twoslash output so that it renders sensibly. the order of operations + // here is important — we need to work backwards, to avoid corrupting the offsets + const replacements: Array<{ start: number; end: number; content: string }> = []; + + for (const match of html.matchAll(/
([^]+?)<\/div>/g)) { + const content = await render_content_markdown('', match[1], { check: false }); + + replacements.push({ + start: match.index, + end: match.index + match[0].length, + content: '
' + content + '
' + }); + } + + while (replacements.length > 0) { + const { start, end, content } = replacements.pop()!; + html = html.slice(0, start) + content + html.slice(end); + } + + for (const match of html.matchAll( + /([^]+?)<\/span>([^]+?)<\/span><\/span>/g + )) { + const tag = match[1]; + let value = match[2]; + + let content = `${tag}`; + + if (tag === '@param' || tag === '@throws') { + const words = value.split(' '); + let param = words.shift()!; + value = words.join(' '); + + if (tag === '@throws') { + if (param[0] !== '{' || param[param.length - 1] !== '}') { + throw new Error('TODO robustify @throws handling'); + } + + param = param.slice(1, -1); + } + + content += `${param} `; + } + + content += marked.parseInline(value); + content += ''; + + replacements.push({ + start: match.index, + end: match.index + match[0].length, + content: '
' + content + '
' + }); + } + + while (replacements.length > 0) { + const { start, end, content } = replacements.pop()!; + html = html.slice(0, start) + content + html.slice(end); + } + } } catch (e) { console.error((e as Error).message); console.warn(prelude + redacted);