Skip to content

Commit 5d1fb5c

Browse files
authored
tidy up some stuff in site-kit (#314)
* tidy up some stuff in site-kit * just get rid of this stuff for now, it's not gonna get implemented before launch and i'm not really sure it's desirable anyway * tidy up * remove some junk * simplify
1 parent 5a771a6 commit 5d1fb5c

File tree

6 files changed

+32
-146
lines changed

6 files changed

+32
-146
lines changed

apps/svelte.dev/src/lib/server/renderer.ts

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,7 @@
1-
import { renderContentMarkdown } from '@sveltejs/site-kit/markdown';
1+
import { render_content_markdown } from '@sveltejs/site-kit/markdown';
22

33
export const render_content = (filename: string, body: string) =>
4-
renderContentMarkdown(filename, body, {
5-
cacheCodeSnippets: true,
6-
7-
// TODO these didn't work for a while in the old sites, too, investigate bringing back this functionality at some point
8-
// resolveTypeLinks: (module_name, type_name) => {
9-
// return {
10-
// page: `/docs/${slugify(module_name)}`,
11-
// slug: `types-${slugify(type_name)}`
12-
// };
13-
// },
14-
4+
render_content_markdown(filename, body, {
155
twoslashBanner: (filename, source) => {
166
// TODO these are copied from Svelte and SvelteKit - adjust for new filenames
177
const injected = [];

apps/svelte.dev/src/routes/content.json/+server.ts

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { index, docs as _docs, examples } from '$lib/server/content';
22
import { json } from '@sveltejs/kit';
3-
import { markedTransform, normalizeSlugify, removeMarkdown } from '@sveltejs/site-kit/markdown';
3+
import { transform, slugify, clean } from '@sveltejs/site-kit/markdown';
44
import type { Block } from '@sveltejs/site-kit/search';
55
import { get_slug } from '../tutorial/[...slug]/content.server';
66

@@ -31,14 +31,14 @@ async function content() {
3131

3232
for (const document of docs) {
3333
const { slug, body, metadata } = document;
34-
const breadcrumbs = document.breadcrumbs.map((x) => removeMarkdown(x.title));
34+
const breadcrumbs = document.breadcrumbs.map((x) => clean(x.title));
3535

3636
const sections = body.trim().split(/^## /m);
3737
const intro = sections?.shift()?.trim()!;
3838
const rank = +metadata.rank;
3939

4040
blocks.push({
41-
breadcrumbs: [...breadcrumbs, removeMarkdown(metadata.title ?? '')],
41+
breadcrumbs: [...breadcrumbs, clean(metadata.title ?? '')],
4242
href: get_href([slug]),
4343
content: await plaintext(intro),
4444
rank
@@ -57,8 +57,8 @@ async function content() {
5757
const intro = subsections?.shift()?.trim();
5858
if (intro) {
5959
blocks.push({
60-
breadcrumbs: [...breadcrumbs, removeMarkdown(metadata.title), removeMarkdown(h2)],
61-
href: get_href([slug, normalizeSlugify(h2)]),
60+
breadcrumbs: [...breadcrumbs, clean(metadata.title), clean(h2)],
61+
href: get_href([slug, slugify(h2)]),
6262
content: await plaintext(intro),
6363
rank
6464
});
@@ -73,13 +73,8 @@ async function content() {
7373
}
7474

7575
blocks.push({
76-
breadcrumbs: [
77-
...breadcrumbs,
78-
removeMarkdown(metadata.title),
79-
removeMarkdown(h2),
80-
removeMarkdown(h3)
81-
],
82-
href: get_href([slug, normalizeSlugify(h2) + '-' + normalizeSlugify(h3)]),
76+
breadcrumbs: [...breadcrumbs, clean(metadata.title), clean(h2), clean(h3)],
77+
href: get_href([slug, slugify(h2) + '-' + slugify(h3)]),
8378
content: await plaintext(lines.join('\n').trim()),
8479
rank
8580
});
@@ -107,7 +102,7 @@ async function plaintext(markdown: string) {
107102
const inline = ({ text }: any) => text;
108103

109104
return (
110-
await markedTransform(markdown, {
105+
await transform(markdown, {
111106
code: ({ text }) => {
112107
const raw = text.split('// ---cut---\n').pop() ?? '';
113108

apps/svelte.dev/src/routes/tutorial/[...slug]/content.server.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import 'prismjs/components/prism-typescript.js';
66
import 'prism-svelte';
77
import { read } from '$app/server';
88
import { index } from '$lib/server/content';
9-
import { markedTransform } from '@sveltejs/site-kit/markdown';
9+
import { transform } from '@sveltejs/site-kit/markdown';
1010
import type { Exercise, ExerciseStub, PartStub, Scope } from '$lib/tutorial';
1111
import { error } from '@sveltejs/kit';
1212
import { text_files } from './shared';
@@ -263,7 +263,7 @@ export async function load_exercise(slug: string): Promise<Exercise> {
263263
prev: prev && { slug: prev.slug },
264264
next,
265265
markdown: exercise.body,
266-
html: await markedTransform(exercise.body, {
266+
html: await transform(exercise.body, {
267267
...default_renderer,
268268
codespan: ({ text }) =>
269269
filenames.size > 1 && filenames.has(text)

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

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,8 @@
1-
export { render_content_markdown as renderContentMarkdown } from './renderer';
1+
export { render_content_markdown } from './renderer';
22

3-
export {
4-
extract_frontmatter as extractFrontmatter,
5-
transform as markedTransform,
6-
normalizeSlugify,
7-
slugify,
8-
removeMarkdown,
9-
escape
10-
} from './utils';
3+
export { transform, slugify, clean } from './utils';
114

5+
// TODO none of these really belong here
126
export type Modules = Array<{
137
name?: string;
148
comment?: string;

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

Lines changed: 5 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import ts from 'typescript';
66
import * as prettier from 'prettier';
77
import { codeToHtml, createCssVariablesTheme } from 'shiki';
88
import { transformerTwoslash } from '@shikijs/twoslash';
9-
import { SHIKI_LANGUAGE_MAP, escape, normalizeSlugify, smart_quotes, transform } from './utils';
9+
import { SHIKI_LANGUAGE_MAP, slugify, smart_quotes, transform } from './utils';
1010
import type { Modules } from './index';
1111
import { fileURLToPath } from 'node:url';
1212

@@ -23,13 +23,6 @@ type TwoslashBanner = (
2323
options: SnippetOptions
2424
) => string;
2525

26-
interface RenderContentOptions {
27-
twoslashBanner?: TwoslashBanner;
28-
modules?: Modules;
29-
cacheCodeSnippets?: boolean;
30-
resolveTypeLinks?: Parameters<typeof create_type_links>['1'];
31-
}
32-
3326
// Supports js, svelte, yaml files
3427
const METADATA_REGEX =
3528
/(?:<!---\s*|\/\/\/\s*|###\s*)(?<key>file|link|copy):\s*(?<value>.*?)(?:\s*--->|$)\n/gm;
@@ -120,35 +113,18 @@ const theme = createCssVariablesTheme({
120113
* @param {string} body
121114
* @param {object} options
122115
* @param {TwoslashBanner} [options.twoslashBanner] - A function that returns a string to be prepended to the code snippet before running the code with twoslash. Helps in adding imports from svelte or sveltekit or whichever modules are being globally referenced in all or most code snippets.
123-
* @param {import('.').Modules} [options.modules] Module info generated from type-gen script. Used to create type links and type information blocks
124-
* @param {boolean} [options.cacheCodeSnippets] Whether to cache code snippets or not. Defaults to true.
125-
* @param {Parameters<typeof create_type_links>['1']} [options.resolveTypeLinks] Resolve types into its slugs(used on the page itself).
126116
*/
127117
export async function render_content_markdown(
128118
filename: string,
129119
body: string,
130-
{
131-
twoslashBanner,
132-
modules = [],
133-
cacheCodeSnippets = false,
134-
resolveTypeLinks
135-
}: RenderContentOptions = {}
120+
{ twoslashBanner }: { twoslashBanner?: TwoslashBanner } = {}
136121
) {
137-
const { type_links, type_regex } = create_type_links(modules, resolveTypeLinks);
138-
const snippets = await create_snippet_cache(cacheCodeSnippets);
122+
const snippets = await create_snippet_cache(true);
139123

140124
const headings: string[] = [];
141125

142-
// this is a bit hacky, but it allows us to prevent type declarations
143-
// from linking to themselves
144-
let current = '';
145-
146126
return await transform(body, {
147127
async walkTokens(token) {
148-
if (token.type === 'heading') {
149-
current = token.text;
150-
}
151-
152128
if (token.type === 'code') {
153129
if (snippets.get(token.text)) return;
154130

@@ -199,25 +175,6 @@ export async function render_content_markdown(
199175

200176
html += '</div>';
201177

202-
// TODO this is currently disabled, we don't have access to `modules`
203-
if (type_regex) {
204-
type_regex.lastIndex = 0;
205-
206-
html = html.replace(type_regex, (match, prefix, name, pos, str) => {
207-
const char_after = str.slice(pos + match.length, pos + match.length + 1);
208-
209-
if (!options.link || name === current || /(\$|\d|\w)/.test(char_after)) {
210-
// we don't want e.g. RequestHandler to link to RequestHandler
211-
return match;
212-
}
213-
214-
const link = type_links?.get(name)
215-
? `<a href="${type_links.get(name)?.relativeURL}">${name}</a>`
216-
: '';
217-
return `${prefix || ''}${link}`;
218-
});
219-
}
220-
221178
// Save everything locally now
222179
snippets.save(token.text, html);
223180
}
@@ -236,7 +193,7 @@ export async function render_content_markdown(
236193
heading({ tokens, depth, raw }) {
237194
const text = this.parser!.parseInline(tokens);
238195

239-
headings[depth - 1] = normalizeSlugify(raw);
196+
headings[depth - 1] = slugify(raw);
240197
headings.length = depth;
241198
const slug = headings.filter(Boolean).join('-');
242199
return `<h${depth} id="${slug}">${text.replace(
@@ -247,20 +204,6 @@ export async function render_content_markdown(
247204
code({ text }) {
248205
return snippets.get(text);
249206
},
250-
codespan({ text }) {
251-
return (
252-
'<code>' +
253-
(type_regex
254-
? text.replace(type_regex, (_, prefix, name) => {
255-
const link = type_links?.get(name)
256-
? `<a href="${type_links.get(name)?.relativeURL}">${name}</a>`
257-
: '';
258-
return `${prefix || ''}${link}`;
259-
})
260-
: text) +
261-
'</code>'
262-
);
263-
},
264207
blockquote(token) {
265208
let content = this.parser?.parse(token.tokens) ?? '';
266209
if (content.includes('[!LEGACY]')) {
@@ -756,7 +699,7 @@ async function syntax_highlight({
756699

757700
return {
758701
type,
759-
content: escape(content)
702+
content: content.replace(/</g, '&lt;')
760703
};
761704
});
762705

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

Lines changed: 12 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,6 @@
11
import { Marked, Renderer, type TokenizerObject, type MarkedExtension } from 'marked';
22
import json5 from 'json5';
33

4-
const escapeTest = /[&<>"']/;
5-
const escapeReplace = /[&<>"']/g;
6-
const escapeTestNoEncode = /[<>"']|&(?!#?\w+;)/;
7-
const escapeReplaceNoEncode = /[<>"']|&(?!#?\w+;)/g;
8-
const escapeReplacements = {
9-
'&': '&amp;',
10-
'<': '&lt;',
11-
'>': '&gt;',
12-
'"': '&quot;',
13-
"'": '&#39;'
14-
};
15-
16-
/**
17-
* @param {string} ch
18-
*/
19-
const getEscapeReplacement = (ch: string) =>
20-
escapeReplacements[ch as keyof typeof escapeReplacements];
21-
224
export const SHIKI_LANGUAGE_MAP = {
235
bash: 'bash',
246
env: 'bash',
@@ -33,30 +15,10 @@ export const SHIKI_LANGUAGE_MAP = {
3315
'': ''
3416
};
3517

36-
export function escape(html: string, encode = false) {
37-
if (encode) {
38-
if (escapeTest.test(html)) {
39-
return html.replace(escapeReplace, getEscapeReplacement);
40-
}
41-
} else {
42-
if (escapeTestNoEncode.test(html)) {
43-
return html.replace(escapeReplaceNoEncode, getEscapeReplacement);
44-
}
45-
}
46-
47-
return html;
48-
}
49-
50-
export function slugify(title: string) {
51-
return title
52-
.replace(/&.+;/g, '')
53-
.replace(/[^a-zA-Z0-9-$(.):]/g, '-')
54-
.replace(/-{2,}/g, '-')
55-
.replace(/^-/, '')
56-
.replace(/-$/, '');
57-
}
58-
59-
export function removeMarkdown(markdown: string) {
18+
/**
19+
* Strip styling/links etc from markdown
20+
*/
21+
export function clean(markdown: string) {
6022
return markdown
6123
.replace(/\*\*(.+?)\*\*/g, '$1') // bold
6224
.replace(/_(.+?)_/g, '$1') // Italics
@@ -69,12 +31,14 @@ export function removeMarkdown(markdown: string) {
6931
.trim();
7032
}
7133

72-
export function removeHTMLEntities(html: string) {
73-
return html.replace(/&.+?;/g, '');
74-
}
75-
76-
export const normalizeSlugify = (str: string) => {
77-
return slugify(removeHTMLEntities(removeMarkdown(str))).replace(/(<([^>]+)>)/gi, '');
34+
export const slugify = (str: string) => {
35+
return clean(str)
36+
.replace(/&.+;/g, '')
37+
.replace(/[^a-zA-Z0-9-$(.):]/g, '-')
38+
.replace(/-{2,}/g, '-')
39+
.replace(/^-/, '')
40+
.replace(/-$/, '')
41+
.replace(/(<([^>]+)>)/gi, '');
7842
};
7943

8044
export function smart_quotes(str: string, html: boolean = false) {

0 commit comments

Comments
 (0)