Skip to content

Commit 2abcee4

Browse files
committed
wip
1 parent 60dbacd commit 2abcee4

File tree

83 files changed

+760
-576
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

83 files changed

+760
-576
lines changed

README.md

+44-44
Large diffs are not rendered by default.

docs-svelte-kit/eslint.config.mjs

+9-1
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,20 @@ const config = [
4141
'jsdoc/require-jsdoc': 'off',
4242
'@typescript-eslint/no-shadow': 'off',
4343
'no-shadow': 'off',
44+
// SvelteKit's docs usually use const instead of function.
45+
'func-style': 'off',
46+
// SvelteKit sometimes needs to use @sveltejs/kit package's `error` instead of return.
47+
'consistent-return': 'off',
4448
'@typescript-eslint/naming-convention': 'off',
4549
'new-cap': 'off',
4650
complexity: 'off',
4751
'n/no-missing-import': 'off',
4852
'n/file-extension-in-import': 'off',
49-
'n/no-extraneous-import': 'off'
53+
'n/no-extraneous-import': 'off',
54+
// We need to use {@html} for markdown rendering.
55+
'svelte/no-at-html-tags': 'off',
56+
// Delegate it to Svelte compiler's check.
57+
'svelte/valid-compile': 'off'
5058
}
5159
},
5260
{

docs-svelte-kit/package.json

+6-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
"@types/markdown-it": "^14.1.1",
2929
"@types/markdown-it-container": "^2.0.10",
3030
"@types/markdown-it-emoji": "^3.0.1",
31-
"@types/node": "^20.12.12",
31+
"@types/node": "^20.14.11",
3232
"@types/prismjs": "^1.26.4",
3333
"@types/stylus": "^0.48.42",
3434
"@typescript/vfs": "^1.5.0",
@@ -55,9 +55,14 @@
5555
"stylus": "^0.63.0",
5656
"svelte": "^5.0.0-next.112",
5757
"svelte-adapter-ghpages": "0.2.2",
58+
"svelte-preprocess": "^6.0.2",
5859
"util": "^0.12.5",
5960
"vite": "^5.2.11",
6061
"vite-plugin-eslint4b": "^0.4.2",
6162
"vite-plugin-svelte-md": "^0.1.7"
63+
},
64+
"dependencies": {
65+
"@shikijs/markdown-it": "^1.10.3",
66+
"markdown-it": "^14.1.0"
6267
}
6368
}

docs-svelte-kit/src/app.css

+62-57
Original file line numberDiff line numberDiff line change
@@ -1,105 +1,110 @@
1-
@import "@fontsource/fira-mono";
1+
@import '@fontsource/fira-mono';
22

33
:root {
4-
font-family: Arial, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
5-
Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
6-
--font-mono: "Fira Mono", monospace;
7-
--pure-white: #ffffff;
8-
--primary-color: #b9c6d2;
9-
--secondary-color: #676778;
10-
--tertiary-color: #edf0f8;
11-
--accent-color: #ff3e00;
12-
--heading-color: rgba(0, 0, 0, 0.7);
13-
--text-color: #444444;
14-
--background-without-opacity: rgba(255, 255, 255, 0.7);
15-
--column-width: 42rem;
16-
--column-margin-top: 4rem;
4+
font-family: 'Inter', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
5+
'Segoe UI Symbol', 'Noto Color Emoji';
6+
--font-mono: 'Fira Mono', monospace;
7+
--pure-white: #ffffff;
8+
--primary-color: #b9c6d2;
9+
--secondary-color: #676778;
10+
--tertiary-color: #edf0f8;
11+
--accent-color: #ff3e00;
12+
--heading-color: rgba(0, 0, 0, 0.7);
13+
--text-color: #444444;
14+
--background-without-opacity: rgba(255, 255, 255, 0.7);
15+
--column-width: 42rem;
16+
--column-margin-top: 4rem;
1717
}
1818

1919
body {
20-
min-height: 100vh;
21-
margin: 0;
22-
background-color: var(--primary-color);
20+
min-height: 100vh;
21+
margin: 0;
22+
background-color: var(--primary-color);
23+
line-height: 1.5;
2324
}
2425

2526
body::before {
26-
content: "";
27-
width: 80vw;
28-
height: 100vh;
29-
position: absolute;
30-
top: 0;
31-
left: 10vw;
32-
z-index: -1;
33-
background: radial-gradient(
34-
50% 50% at 50% 50%,
35-
var(--pure-white) 0%,
36-
rgba(255, 255, 255, 0) 100%
37-
);
38-
opacity: 0.05;
27+
content: '';
28+
width: 80vw;
29+
height: 100vh;
30+
position: absolute;
31+
top: 0;
32+
left: 10vw;
33+
z-index: -1;
34+
background: radial-gradient(
35+
50% 50% at 50% 50%,
36+
var(--pure-white) 0%,
37+
rgba(255, 255, 255, 0) 100%
38+
);
39+
opacity: 0.05;
3940
}
4041

4142
#svelte {
42-
min-height: 100vh;
43-
display: flex;
44-
flex-direction: column;
43+
min-height: 100vh;
44+
display: flex;
45+
flex-direction: column;
4546
}
4647

4748
h1,
4849
h2,
4950
p {
50-
font-weight: 400;
51-
color: var(--heading-color);
51+
font-weight: 400;
52+
color: var(--heading-color);
5253
}
5354

5455
p {
55-
line-height: 1.5;
56+
line-height: 1.5;
5657
}
5758

5859
a {
59-
color: var(--accent-color);
60-
text-decoration: none;
60+
color: var(--accent-color);
61+
text-decoration: none;
6162
}
6263

6364
a:hover {
64-
text-decoration: underline;
65+
text-decoration: underline;
6566
}
6667

6768
h1 {
68-
font-size: 2rem;
69-
text-align: center;
69+
font-size: 2rem;
70+
text-align: center;
7071
}
7172

7273
h2 {
73-
font-size: 1rem;
74+
font-size: 1rem;
7475
}
7576

7677
pre {
77-
font-size: 16px;
78-
font-family: var(--font-mono);
79-
background-color: rgba(255, 255, 255, 0.45);
80-
border-radius: 3px;
81-
box-shadow: 2px 2px 6px rgb(255 255 255 / 25%);
82-
padding: 0.5em;
83-
overflow-x: auto;
84-
color: var(--text-color);
78+
font-size: 16px;
79+
background-color: rgba(255, 255, 255, 0.45);
80+
border-radius: 3px;
81+
box-shadow: 2px 2px 6px rgb(255 255 255 / 25%);
82+
padding: 0.5em;
83+
overflow-x: auto;
84+
color: var(--text-color);
85+
}
86+
87+
code {
88+
font-family: 'Inter', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
89+
'Segoe UI Symbol', 'Noto Color Emoji' !important;
8590
}
8691

8792
input,
8893
button {
89-
font-size: inherit;
90-
font-family: inherit;
94+
font-size: inherit;
95+
font-family: inherit;
9196
}
9297

9398
button:focus:not(:focus-visible) {
94-
outline: none;
99+
outline: none;
95100
}
96101

97102
@media (min-width: 720px) {
98-
h1 {
99-
font-size: 2.4rem;
100-
}
103+
h1 {
104+
font-size: 2.4rem;
105+
}
101106
}
102107

103108
:target {
104-
scroll-margin-top: 80px;
109+
scroll-margin-top: 80px;
105110
}
+82
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import { readFile } from 'node:fs/promises';
2+
import MarkdownIt from 'markdown-it';
3+
import Shiki from '@shikijs/markdown-it';
4+
5+
function headingRenderer(md: MarkdownIt) {
6+
const buildId = (text: string) => {
7+
return text
8+
.replace(/[^ \-0-9a-z]/gi, '')
9+
.trim()
10+
.replace(/\s+/g, '-')
11+
.toLowerCase();
12+
};
13+
14+
md.renderer.rules.heading_open = function (tokens, idx) {
15+
const tag = tokens[idx].tag;
16+
const text = tokens[idx + 1].content;
17+
const id = buildId(text);
18+
return `<${tag} id=${id} tabindex="-1"><a href="#${id}">#</a>`;
19+
};
20+
}
21+
22+
function noteRenderer(md: MarkdownIt) {
23+
md.renderer.rules.text = function (tokens, idx) {
24+
const text = tokens[idx].content;
25+
const match = /^::: (\S+)(\s.*)?$/.exec(text);
26+
if (match) {
27+
const type = match[1]?.trim();
28+
const title = (match[2] ?? type)?.trim();
29+
return `<div class="custom-block ${type}"><p class="custom-block-title">${title}</p>`;
30+
}
31+
if (text.startsWith(':::')) {
32+
return '</div>';
33+
}
34+
return text;
35+
};
36+
}
37+
38+
const md = MarkdownIt();
39+
md.use(headingRenderer);
40+
md.use(noteRenderer);
41+
md.use(
42+
await Shiki({
43+
themes: {
44+
light: 'vitesse-dark',
45+
dark: 'vitesse-dark'
46+
}
47+
})
48+
);
49+
50+
function removeQuotes(str: string) {
51+
return str.replace(/^["']|["']$/g, '');
52+
}
53+
54+
function extractFrontmatter(markdown: string) {
55+
const match = /---\r?\n([\s\S]+?)\r?\n---/.exec(markdown);
56+
if (!match) return { metadata: {}, body: markdown };
57+
58+
const frontmatter = match[1];
59+
const body = markdown.slice(match[0].length);
60+
61+
const metadata: Record<string, string> = {};
62+
frontmatter.split('\n').forEach((pair) => {
63+
const i = pair.indexOf(':');
64+
metadata[pair.slice(0, i).trim()] = removeQuotes(pair.slice(i + 1).trim());
65+
});
66+
67+
return { metadata, body };
68+
}
69+
70+
function removeComments(markdown: string) {
71+
return markdown.replace(/<!--[\s\S]*?-->/g, '');
72+
}
73+
74+
export async function getParsedMarkdown(
75+
path: string
76+
): Promise<{ metadata: Record<string, string | number>; html: string }> {
77+
const markdown = await readFile(path, 'utf-8');
78+
const { metadata, body } = extractFrontmatter(markdown);
79+
const bodyWithoutComment = removeComments(body);
80+
const html = md.render(bodyWithoutComment);
81+
return { metadata, html };
82+
}

docs-svelte-kit/src/routes/+layout.svelte

+2-2
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@
3131

3232
<Header on:toggleSidebarOpen={handleToggleSidebar} />
3333

34-
<SideMenu {sidebarOpen} hiddenMenu={frontmatter.hiddenMenu} />
34+
<SideMenu {sidebarOpen} hiddenMenu={false} />
3535

3636
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
3737
<main
38-
class:hidden-menu={frontmatter.hiddenMenu}
38+
class:hidden-menu={false}
3939
on:click={sidebarOpen ? resetSidebarOpen : null}
4040
on:keydown={sidebarOpen ? resetSidebarOpen : null}
4141
>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { getParsedMarkdown } from '$lib/server/markdown.js';
2+
import { error } from '@sveltejs/kit';
3+
import type { PageServerLoad } from './$types';
4+
5+
export const load: PageServerLoad = async ({ params }) => {
6+
const content = await getParsedMarkdown(`${process.cwd()}/../docs/${params.slug}.md`);
7+
8+
if (content) {
9+
return { content };
10+
}
11+
12+
error(404, 'Not found');
13+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<script lang="ts">
2+
import type { PageData } from './$types';
3+
export let data: PageData;
4+
</script>
5+
6+
<section data-rule-page>
7+
{@html data.content.html}
8+
</section>
9+
10+
<style global>
11+
section[data-rule-page] > h1 {
12+
display: flex;
13+
justify-content: center;
14+
}
15+
16+
section[data-rule-page] > h1 > a,
17+
h2 > a,
18+
h3 > a,
19+
h4 > a,
20+
h5 > a,
21+
h6 > a {
22+
content: '#';
23+
color: var(--accent-color);
24+
margin-right: 8px;
25+
}
26+
27+
section[data-rule-page] td:nth-child(3) {
28+
width: 42px;
29+
text-align: right;
30+
}
31+
</style>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import { getParsedMarkdown } from '$lib/server/markdown.js';
2+
import { error } from '@sveltejs/kit';
3+
import type { PageServerLoad } from './$types';
4+
5+
export const load: PageServerLoad = async ({ params }) => {
6+
const content = await getParsedMarkdown(`${process.cwd()}/../docs/rules/${params.slug}.md`);
7+
8+
if (content) {
9+
return { content };
10+
}
11+
12+
error(404, 'Not found');
13+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<script lang="ts">
2+
import type { PageData } from './$types';
3+
export let data: PageData;
4+
</script>
5+
6+
<section data-rule-page>
7+
{@html data.content.html}
8+
</section>
9+
10+
<style global>
11+
section[data-rule-page] > h1 {
12+
display: flex;
13+
justify-content: center;
14+
}
15+
16+
section[data-rule-page] > h1 > a,
17+
h2 > a,
18+
h3 > a,
19+
h4 > a,
20+
h5 > a,
21+
h6 > a {
22+
content: '#';
23+
color: var(--accent-color);
24+
margin-right: 8px;
25+
}
26+
</style>

0 commit comments

Comments
 (0)