Skip to content

Commit d999362

Browse files
authored
feat: sveltekit integration example (#198)
1 parent 3054ca6 commit d999362

28 files changed

+1018
-94
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,4 @@ _
2121
.tsup
2222
.env
2323
!.env.example
24+
.svelte-kit

.vscode/settings.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"[json]": { "editor.defaultFormatter": "biomejs.biome" },
2727
"[jsonc]": { "editor.defaultFormatter": "biomejs.biome" },
2828
"[astro]": { "editor.defaultFormatter": "astro-build.astro-vscode" },
29-
"[svelte]": { "editor.defaultFormatter": "biomejs.biome" },
29+
"[svelte]": { "editor.defaultFormatter": "svelte.svelte-vscode" },
3030
"files.associations": {
3131
"biome.json": "jsonc",
3232
"*.css": "tailwindcss"
@@ -38,5 +38,8 @@
3838
"**/node_modules": true,
3939
"**/pnpm-lock.yaml": true,
4040
"**/package-lock.json": true
41+
},
42+
"[elixir]": {
43+
"editor.defaultFormatter": "JakeBecker.elixir-ls"
4144
}
4245
}

biome.json

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@
5151
"rules": {
5252
"all": true,
5353
"style": {
54+
"noNamespace": "off",
5455
"noDefaultExport": "off",
5556
"useFragmentSyntax": "off",
5657
"noImplicitBoolean": "off",

examples/astro/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22

33
[rehype-pretty-example-astro.pages.dev](https://rehype-pretty-example-astro.pages.dev/)
44

5-
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://githubbox.com/atomiks/rehype-pretty-code/tree/master/examples/astro)
5+
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://githubbox.com/rehype-pretty/rehype-pretty-code/tree/master/examples/astro)

examples/astro/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@
1515
"@astrojs/mdx": "^2.3.1",
1616
"@astrojs/tailwind": "^5.1.0",
1717
"@rehype-pretty/transformers": "workspace:*",
18-
"astro": "^4.6.3",
1918
"rehype-pretty-code": "workspace:*",
19+
"astro": "^4.6.3",
2020
"shiki": "^1.3.0",
2121
"tailwindcss": "^3.4.3"
2222
},

examples/cdn/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Simple `index.html with CDN Integration Example
2+
3+
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://githubbox.com/rehype-pretty/rehype-pretty-code/tree/master/examples/cdn)

examples/cdn/index.html

+17-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,18 @@
55
<meta charset="UTF-8">
66
<title>Rehype Pretty Code</title>
77
<meta name="viewport" content="width=device-width, initial-scale=1.0">
8-
<style>code,pre{padding:16px 20px;line-height:1.5}::selection{color:#ffcffd;background-color:#000}</style>
8+
<style>
9+
code,
10+
pre {
11+
padding: 10px 20px 10px 20px;
12+
line-height: 1.5
13+
}
14+
15+
::selection {
16+
color: #ffcffd;
17+
background-color: #000
18+
}
19+
</style>
920
</head>
1021

1122
<body style="display: flex; height: 100vh; align-items: center; justify-content: center; background-color: #ffe8fa;">
@@ -18,6 +29,7 @@
1829
import remarkRehype from 'https://esm.run/remark-rehype'
1930
import rehypeStringify from 'https://esm.run/rehype-stringify'
2031
import rehypePrettyCode from 'https://esm.run/rehype-pretty-code'
32+
import { copyButtonTransformer } from 'https://esm.sh/jsr/@rehype-pretty/transformers'
2133

2234
const codeElement = document.querySelector('section#code')
2335

@@ -39,7 +51,10 @@
3951
const processor = await unified()
4052
.use(remarkParse)
4153
.use(remarkRehype)
42-
.use(rehypePrettyCode, { theme: 'rose-pine' })
54+
.use(rehypePrettyCode, {
55+
theme: 'rose-pine',
56+
transformers: [copyButtonTransformer({ visibility: 'always' })]
57+
})
4358
.use(rehypeStringify)
4459
.process("```" + codeSnippet)
4560

examples/sveltekit/.gitignore

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.DS_Store
2+
node_modules
3+
/build
4+
/.svelte-kit
5+
/package
6+
.env
7+
.env.*
8+
!.env.example
9+
vite.config.js.timestamp-*
10+
vite.config.ts.timestamp-*

examples/sveltekit/.npmrc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
engine-strict=true

examples/sveltekit/README.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# [SvelteKit](https://kit.svelte.dev) Integration Example
2+
3+
_v5 x `runes` x TailwindCSS v4_
4+
5+
[![Open with CodeSandbox](https://assets.codesandbox.io/github/button-edit-lime.svg)](https://githubbox.com/rehype-pretty/rehype-pretty-code/tree/master/examples/sveltekit)

examples/sveltekit/package.json

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"name": "example-svelte",
3+
"version": "0.0.0",
4+
"private": true,
5+
"scripts": {
6+
"dev": "vite dev",
7+
"build": "vite build",
8+
"preview": "vite preview",
9+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
10+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch"
11+
},
12+
"dependencies": {
13+
"@rehype-pretty/transformers": "workspace:*",
14+
"@tailwindcss/vite": "4.0.0-alpha.14",
15+
"rehype-pretty-code": "workspace:*",
16+
"rehype-slug": "^6.0.0",
17+
"rehype-stringify": "^10.0.0",
18+
"remark-parse": "^11.0.0",
19+
"tailwindcss": "4.0.0-alpha.14"
20+
},
21+
"devDependencies": {
22+
"@sveltejs/adapter-auto": "^3.2.0",
23+
"@sveltejs/kit": "^2.5.7",
24+
"@sveltejs/vite-plugin-svelte": "^3.1.0",
25+
"magic-string": "^0.30.10",
26+
"svelte": "5.0.0-next.110",
27+
"svelte-check": "^3.6.9",
28+
"tslib": "^2.6.2",
29+
"typescript": "^5.4.5",
30+
"vite": "^5.2.10"
31+
},
32+
"type": "module"
33+
}

examples/sveltekit/src/app.css

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
@import 'tailwindcss';
2+
3+
@theme {
4+
--font-family-display: "MulishVariable", "sans-serif";
5+
}
6+
7+
/* mulish-latin-wght-normal */
8+
@font-face {
9+
font-family: 'MulishVariable';
10+
font-style: normal;
11+
font-display: swap;
12+
font-weight: 200 1000;
13+
src: url(https://cdn.jsdelivr.net/fontsource/fonts/mulish:vf@latest/latin-wght-normal.woff2) format('woff2-variations');
14+
unicode-range: U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;
15+
}

examples/sveltekit/src/app.d.ts

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
declare global {
2+
namespace App {}
3+
}
4+
5+
export type {};

examples/sveltekit/src/app.html

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<link rel="icon" href="%sveltekit.assets%/favicon.ico" />
6+
<meta name="viewport" content="width=device-width, initial-scale=1" />
7+
%sveltekit.head%
8+
</head>
9+
<body data-sveltekit-preload-data="hover">
10+
<div style="display: contents">%sveltekit.body%</div>
11+
</body>
12+
</html>
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { unified } from 'unified';
2+
import remarkParse from 'remark-parse';
3+
import type { Compatible } from 'vfile';
4+
import remarkRehype from 'remark-rehype';
5+
import rehypeStringify from 'rehype-stringify';
6+
import rehypePrettyCode from 'rehype-pretty-code';
7+
import { transformerCopyButton } from '@rehype-pretty/transformers';
8+
9+
export const toHTML = (content: Compatible | undefined) =>
10+
unified()
11+
.use(remarkParse)
12+
.use(remarkRehype)
13+
.use(rehypePrettyCode, {
14+
theme: 'rose-pine',
15+
transformers: [
16+
transformerCopyButton({
17+
visibility: 'always',
18+
feedbackDuration: 2_500,
19+
}),
20+
],
21+
})
22+
.use(rehypeStringify)
23+
.process(content);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
defmodule Fibonacci do
2+
def fib_stream do
3+
Stream.unfold({0, 1}, fn {a, b} -> {a, {b, a + b}} end)
4+
end
5+
end
6+
7+
fib = Fibonacci.fib_stream()
8+
Enum.take(fib, 10)
9+
10+
Enum.each(
11+
Stream.take(fib, 10),
12+
fn x -> IO.inspect(x, label: "Fibonacci") end
13+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
(defun fibonacci-generator (n)
2+
(let ((a 0) (b 1) (next 0))
3+
(loop for i from 1 to n do
4+
(setq next (+ a b))
5+
(setq b a)
6+
(setq a next)
7+
(format t "Fibonacci: ~A~%" a))))
8+
9+
(fibonacci-generator 9) ; Print the first 10 Fibonacci numbers
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
use strict;
2+
use warnings;
3+
4+
my $fib = fibbonaci_sequence();
5+
6+
print $fib->(), "\n"; # 0
7+
print $fib->(), "\n"; # 1
8+
9+
sub fibbonaci_sequence {
10+
my ($a, $b) = (0, 1);
11+
return sub {
12+
my $val = $a;
13+
($a, $b) = ($b, $a + $b);
14+
return $val;
15+
}
16+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export function* fibbonaciSequence() {
2+
let [a, b] = [0, 1];
3+
while (true) {
4+
yield a;
5+
[a, b] = [b, a + b];
6+
}
7+
}
8+
9+
const fib = fibbonaciSequence();
10+
Array.from({ length: 10 }, () => console.log(fib.next().value));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<script lang="ts">
2+
import '$/app.css';
3+
</script>
4+
5+
<svelte:head>
6+
<title>Rehype Pretty Svelte</title>
7+
</svelte:head>
8+
9+
<main class="bg-[#fff5e6] size-full flex flex-col items-center px-2 sm:px-5 py-5 pt-10 min-h-screen min-w-screen">
10+
<slot />
11+
</main>
+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<script lang="ts">
2+
import type { PageData } from './$types.ts';
3+
4+
export let data: PageData;
5+
</script>
6+
7+
<p class="text-4xl font-extrabold mb-3 font-display">{data.title}</p>
8+
9+
<section class="space-y-1 w-full max-w-[600px]">
10+
{#each data.snippets as { code }}
11+
{@html code}
12+
{/each}
13+
</section>
14+
15+
<a
16+
target="_blank"
17+
rel="noopener noreferrer"
18+
href="https://github.com/rehype-pretty/rehype-pretty-code/tree/master/examples/sveltekit"
19+
class="top-0 right-0 absolute p-1 pl-1.5 text-sm text-zinc-900 font-semibold rounded-bl-md bg-[#d89c9c]"
20+
>
21+
source code
22+
</a>
23+
24+
<style>
25+
:global(pre),
26+
:global(code),
27+
:global(figure) {
28+
border-radius: 5px;
29+
overflow-x: scroll;
30+
padding: 5px 6px 6px 6px;
31+
}
32+
33+
:global(figcaption) {
34+
color: #333;
35+
margin-top: 5px;
36+
font-weight: 500;
37+
font-size: 1.1rem;
38+
}
39+
</style>
+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { toHTML } from '$/lib/markdown.ts';
2+
import type { PageLoad } from './$types.ts';
3+
4+
const languageIds = {
5+
pl: 'perl',
6+
lsp: 'lisp',
7+
ex: 'elixir',
8+
ts: 'typescript',
9+
};
10+
11+
export const load = (async (_event) => {
12+
/**
13+
* You can also `fetch` each file individually using `_event.fetch`
14+
*/
15+
const rawSnippets = import.meta.glob('/src/lib/snippets/*', {
16+
query: '?raw',
17+
import: 'default',
18+
});
19+
20+
const parsedSnippets = [];
21+
for await (const [path, snippetPromise] of Object.entries(rawSnippets)) {
22+
const filename = path.split('/').pop();
23+
if (!filename) throw new Error('Invalid filename');
24+
25+
const fileExtension = filename.split('.').pop() as keyof typeof languageIds;
26+
if (!fileExtension) throw new Error('Invalid file extension');
27+
28+
const promise = await snippetPromise();
29+
if (typeof promise !== 'string') throw new Error('Invalid snippet content');
30+
31+
const snippetTitle = filename.split('-').at(-1)?.split('.').at(0);
32+
const processedResult = await toHTML(
33+
`\`\`\`${languageIds[fileExtension]} title="${snippetTitle}"\n${promise}\n\`\`\``,
34+
);
35+
36+
parsedSnippets.push({ filename, code: String(processedResult) });
37+
}
38+
return {
39+
title: 'Fibbonaci Sequence',
40+
snippets: parsedSnippets,
41+
};
42+
}) satisfies PageLoad;

examples/sveltekit/static/favicon.ico

15 KB
Binary file not shown.

examples/sveltekit/svelte.config.js

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import adapter from '@sveltejs/adapter-auto';
2+
import { vitePreprocess } from '@sveltejs/vite-plugin-svelte';
3+
4+
/** @type {import('@sveltejs/kit').Config} */
5+
export default {
6+
extensions: ['.svelte', '.md'],
7+
preprocess: [vitePreprocess()],
8+
kit: {
9+
adapter: adapter(),
10+
alias: {
11+
$: './src',
12+
},
13+
},
14+
};

examples/sveltekit/tsconfig.json

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"extends": ["./.svelte-kit/tsconfig.json"],
3+
"compilerOptions": {
4+
"allowJs": true,
5+
"checkJs": true,
6+
"lib": ["ESNext", "DOM", "DOM.Iterable"],
7+
"esModuleInterop": true,
8+
"forceConsistentCasingInFileNames": true,
9+
"allowImportingTsExtensions": true,
10+
"resolveJsonModule": true,
11+
"skipLibCheck": true,
12+
"sourceMap": true,
13+
"strict": true,
14+
"moduleResolution": "Bundler"
15+
}
16+
}

examples/sveltekit/vite.config.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { defineConfig } from 'vite';
2+
import tailwindcss from '@tailwindcss/vite';
3+
import { sveltekit } from '@sveltejs/kit/vite';
4+
5+
export default defineConfig(() => ({
6+
plugins: [sveltekit(), tailwindcss()],
7+
}));

packages/core/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
"tsup": "^8.0.2",
4747
"tsx": "^4.7.2",
4848
"typescript": "^5.4.5",
49-
"vite": "^5.2.9",
49+
"vite": "^5.2.10",
5050
"vitest": "^1.5.0"
5151
},
5252
"peerDependencies": {

0 commit comments

Comments
 (0)