mirror of
https://github.com/LukeHagar/website.git
synced 2025-12-06 04:22:07 +00:00
feat: markdoc
This commit is contained in:
12
markdoc.config.json
Normal file
12
markdoc.config.json
Normal file
@@ -0,0 +1,12 @@
|
||||
[
|
||||
{
|
||||
"id": "appwrite",
|
||||
"path": "src/",
|
||||
"schema": {
|
||||
"path": ".svelte-kit/markdoc_schema.js",
|
||||
"type": "esm",
|
||||
"property": "default",
|
||||
"watch": true
|
||||
}
|
||||
}
|
||||
]
|
||||
10
package.json
10
package.json
@@ -27,21 +27,23 @@
|
||||
"eslint": "^8.28.0",
|
||||
"eslint-config-prettier": "^8.5.0",
|
||||
"eslint-plugin-svelte": "^2.30.0",
|
||||
"oslllo-svg-fixer": "^2.2.0",
|
||||
"prettier": "^2.8.0",
|
||||
"prettier-plugin-svelte": "^2.10.1",
|
||||
"sass": "^1.65.1",
|
||||
"svelte": "^4.0.5",
|
||||
"svelte-check": "^3.4.3",
|
||||
"svelte-markdoc-preprocess": "^0.3.0",
|
||||
"svelte-sequential-preprocessor": "^2.0.1",
|
||||
"svgtofont": "^3.22.0",
|
||||
"tslib": "^2.4.1",
|
||||
"typescript": "^5.0.0",
|
||||
"vite": "^4.4.2",
|
||||
"vitest": "^0.32.2",
|
||||
"oslllo-svg-fixer": "^2.2.0",
|
||||
"svgtofont": "^3.22.0"
|
||||
"vitest": "^0.32.2"
|
||||
},
|
||||
"type": "module",
|
||||
"dependencies": {
|
||||
"@fontsource/inter": "^5.0.8"
|
||||
"@fontsource/inter": "^5.0.8",
|
||||
"highlight.js": "^11.8.0"
|
||||
}
|
||||
}
|
||||
|
||||
87
pnpm-lock.yaml
generated
87
pnpm-lock.yaml
generated
@@ -8,6 +8,12 @@ dependencies:
|
||||
'@fontsource/inter':
|
||||
specifier: ^5.0.8
|
||||
version: 5.0.8
|
||||
highlight.js:
|
||||
specifier: ^11.8.0
|
||||
version: 11.8.0
|
||||
shiki:
|
||||
specifier: ^0.14.4
|
||||
version: 0.14.4
|
||||
|
||||
devDependencies:
|
||||
'@melt-ui/pp':
|
||||
@@ -58,6 +64,9 @@ devDependencies:
|
||||
svelte-check:
|
||||
specifier: ^3.4.3
|
||||
version: 3.5.0(postcss@8.4.27)(sass@1.65.1)(svelte@4.2.0)
|
||||
svelte-markdoc-preprocess:
|
||||
specifier: ^0.3.0
|
||||
version: 0.3.0
|
||||
svelte-sequential-preprocessor:
|
||||
specifier: ^2.0.1
|
||||
version: 2.0.1
|
||||
@@ -799,6 +808,21 @@ packages:
|
||||
'@jridgewell/sourcemap-codec': 1.4.15
|
||||
dev: true
|
||||
|
||||
/@markdoc/markdoc@0.3.2:
|
||||
resolution: {integrity: sha512-D0SaanaSkTIARvQu+zQqPEpKcvYUBR/mfac9e8JzS89P7eXhiNWPonUN7avRS1saZHpIQWIRote97qT+jGk5Gw==}
|
||||
engines: {node: '>=14.7.0'}
|
||||
peerDependencies:
|
||||
'@types/react': '*'
|
||||
react: '*'
|
||||
peerDependenciesMeta:
|
||||
'@types/react':
|
||||
optional: true
|
||||
react:
|
||||
optional: true
|
||||
optionalDependencies:
|
||||
'@types/markdown-it': 12.2.3
|
||||
dev: true
|
||||
|
||||
/@melt-ui/pp@0.1.2(@melt-ui/svelte@0.40.0)(svelte@4.2.0):
|
||||
resolution: {integrity: sha512-GZeqp7UWLNZUC2dJpREnZrWMR88vy27WO7C3cIBz4KW3/CFD19FjNkd3VbSRfcRryrMkdnEs9nu2VUa8/0u58w==}
|
||||
engines: {pnpm: '>=8.6.3'}
|
||||
@@ -1134,6 +1158,25 @@ packages:
|
||||
'@types/node': 20.5.0
|
||||
dev: true
|
||||
|
||||
/@types/linkify-it@3.0.3:
|
||||
resolution: {integrity: sha512-pTjcqY9E4nOI55Wgpz7eiI8+LzdYnw3qxXCfHyBDdPbYvbyLgWLJGh8EdPvqawwMK1Uo1794AUkkR38Fr0g+2g==}
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@types/markdown-it@12.2.3:
|
||||
resolution: {integrity: sha512-GKMHFfv3458yYy+v/N8gjufHO6MSZKCOXpZc5GXIWWy8uldwfmPn98vp81gZ5f9SVw8YYBctgfJ22a2d7AOMeQ==}
|
||||
requiresBuild: true
|
||||
dependencies:
|
||||
'@types/linkify-it': 3.0.3
|
||||
'@types/mdurl': 1.0.2
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@types/mdurl@1.0.2:
|
||||
resolution: {integrity: sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA==}
|
||||
dev: true
|
||||
optional: true
|
||||
|
||||
/@types/node@16.9.1:
|
||||
resolution: {integrity: sha512-QpLcX9ZSsq3YYUUnD3nFDY8H7wctAhQj/TFKL8Ya8v5fMm3CFXxo8zStsLAl780ltoYoo1WvKUVGBQK+1ifr7g==}
|
||||
dev: true
|
||||
@@ -1422,6 +1465,10 @@ packages:
|
||||
engines: {node: '>=12'}
|
||||
dev: true
|
||||
|
||||
/ansi-sequence-parser@1.1.1:
|
||||
resolution: {integrity: sha512-vJXt3yiaUL4UU546s3rPXlsry/RnM730G1+HkpKE012AN0sx1eOrxSu95oKDIonskeLTijMgqWZ3uDEe3NFvyg==}
|
||||
dev: false
|
||||
|
||||
/ansi-styles@4.3.0:
|
||||
resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
|
||||
engines: {node: '>=8'}
|
||||
@@ -2723,6 +2770,15 @@ packages:
|
||||
kind-of: 4.0.0
|
||||
dev: true
|
||||
|
||||
/highlight.js@11.8.0:
|
||||
resolution: {integrity: sha512-MedQhoqVdr0U6SSnWPzfiadUcDHfN/Wzq25AkXiQv9oiOO/sG0S7XkvpFIqWBl9Yq1UYyYOOVORs5UW2XlPyzg==}
|
||||
engines: {node: '>=12.0.0'}
|
||||
dev: false
|
||||
|
||||
/html-escaper@3.0.3:
|
||||
resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==}
|
||||
dev: true
|
||||
|
||||
/htmlparser2@8.0.2:
|
||||
resolution: {integrity: sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==}
|
||||
dependencies:
|
||||
@@ -3056,7 +3112,6 @@ packages:
|
||||
|
||||
/jsonc-parser@3.2.0:
|
||||
resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==}
|
||||
dev: true
|
||||
|
||||
/jsonfile@6.1.0:
|
||||
resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
|
||||
@@ -4155,6 +4210,15 @@ packages:
|
||||
engines: {node: '>=8'}
|
||||
dev: true
|
||||
|
||||
/shiki@0.14.4:
|
||||
resolution: {integrity: sha512-IXCRip2IQzKwxArNNq1S+On4KPML3Yyn8Zzs/xRgcgOWIr8ntIK3IKzjFPfjy/7kt9ZMjc+FItfqHRBg8b6tNQ==}
|
||||
dependencies:
|
||||
ansi-sequence-parser: 1.1.1
|
||||
jsonc-parser: 3.2.0
|
||||
vscode-oniguruma: 1.7.0
|
||||
vscode-textmate: 8.0.0
|
||||
dev: false
|
||||
|
||||
/siginfo@2.0.0:
|
||||
resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==}
|
||||
dev: true
|
||||
@@ -4459,6 +4523,19 @@ packages:
|
||||
svelte: 4.2.0
|
||||
dev: true
|
||||
|
||||
/svelte-markdoc-preprocess@0.3.0:
|
||||
resolution: {integrity: sha512-o1VisVNqRdeCTjYbhxtpsxGquujKT3Ksnk4ttdPxi2dWKFBO1IvtxGKiDudVMMI+s3mcsbu/uA/0bYfeqsf+DQ==}
|
||||
dependencies:
|
||||
'@markdoc/markdoc': 0.3.2
|
||||
html-escaper: 3.0.3
|
||||
js-yaml: 4.1.0
|
||||
svelte: 4.2.0
|
||||
typescript: 5.1.6
|
||||
transitivePeerDependencies:
|
||||
- '@types/react'
|
||||
- react
|
||||
dev: true
|
||||
|
||||
/svelte-preprocess@5.0.4(postcss@8.4.27)(sass@1.65.1)(svelte@4.2.0)(typescript@5.1.6):
|
||||
resolution: {integrity: sha512-ABia2QegosxOGsVlsSBJvoWeXy1wUKSfF7SWJdTjLAbx/Y3SrVevvvbFNQqrSJw89+lNSsM58SipmZJ5SRi5iw==}
|
||||
engines: {node: '>= 14.10.0'}
|
||||
@@ -5015,6 +5092,14 @@ packages:
|
||||
- terser
|
||||
dev: true
|
||||
|
||||
/vscode-oniguruma@1.7.0:
|
||||
resolution: {integrity: sha512-L9WMGRfrjOhgHSdOYgCt/yRMsXzLDJSL7BPrOZt73gU0iWO4mpqzqQzOz5srxqTvMBaR0XZTSrVWo4j55Rc6cA==}
|
||||
dev: false
|
||||
|
||||
/vscode-textmate@8.0.0:
|
||||
resolution: {integrity: sha512-AFbieoL7a5LMqcnOF04ji+rpXadgOXnZsxQr//r83kLPr7biP7am3g9zbaZIaBGwBRWeSvoMD4mgPdX3e4NWBg==}
|
||||
dev: false
|
||||
|
||||
/which@2.0.2:
|
||||
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
|
||||
engines: {node: '>= 8'}
|
||||
|
||||
206
src/markdoc/layouts/Tutorial.svelte
Normal file
206
src/markdoc/layouts/Tutorial.svelte
Normal file
@@ -0,0 +1,206 @@
|
||||
<script context="module" lang="ts">
|
||||
import { writable, type Writable } from 'svelte/store';
|
||||
|
||||
export type LayoutContext = Writable<
|
||||
Record<string, {
|
||||
text: string;
|
||||
step?: number;
|
||||
}>
|
||||
>;
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { Docs } from '$lib/layouts';
|
||||
import Sidebar from '$routes/docs/Sidebar.svelte';
|
||||
import { getContext, setContext } from 'svelte';
|
||||
|
||||
export let title: string;
|
||||
export let difficulty: string;
|
||||
export let readtime: string;
|
||||
|
||||
setContext<LayoutContext>('headings', writable({}));
|
||||
|
||||
const headings = getContext<LayoutContext>('headings');
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{title}</title>
|
||||
</svelte:head>
|
||||
|
||||
<Docs variant="two-side-navs">
|
||||
<Sidebar />
|
||||
<main class="u-contents">
|
||||
<article class="aw-article u-contents">
|
||||
<header class="aw-article-header">
|
||||
<div class="aw-article-header-start u-flex-vertical aw-u-cross-start">
|
||||
<button
|
||||
class="
|
||||
aw-button is-text aw-is-only-mobile
|
||||
aw-u-padding-block-0 aw-u-padding-inline-start-0 aw-u-padding-inline-end-12"
|
||||
aria-label="previous page"
|
||||
>
|
||||
<span class="icon-cheveron-left" aria-hidden="true" />
|
||||
</button>
|
||||
<ul class="aw-metadata aw-caption-400">
|
||||
{#if difficulty}
|
||||
<li>{difficulty}</li>
|
||||
{/if}
|
||||
{#if readtime}
|
||||
<li>{readtime} min</li>
|
||||
{/if}
|
||||
</ul>
|
||||
<div class="u-position-relative u-flex u-cross-center">
|
||||
<button
|
||||
class="
|
||||
aw-button is-text is-icon aw-u-cross-center aw-u-size-40
|
||||
u-position-absolute u-inset-inline-start-0 aw-u-translate-x-negative"
|
||||
aria-label="previous page"
|
||||
>
|
||||
<span
|
||||
class="icon-cheveron-left aw-u-font-size-24 aw-u-color-text-primary"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
</button>
|
||||
<h1 class="aw-title">{title}</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div class="aw-article-header-end" />
|
||||
</header>
|
||||
<div class="aw-article-content">
|
||||
<slot />
|
||||
|
||||
<section class="aw-content-footer">
|
||||
<header class="aw-content-footer-header">
|
||||
<div class="aw-content-footer-header-start">
|
||||
<h5 class="aw-main-body-500 aw-u-color-text-primary">Was this page helpful?</h5>
|
||||
<div class="u-flex u-gap-8">
|
||||
<input
|
||||
class="aw-radio-button is-like"
|
||||
type="radio"
|
||||
aria-label="Helpful"
|
||||
name="happy"
|
||||
/>
|
||||
<input
|
||||
class="aw-radio-button is-dislike"
|
||||
type="radio"
|
||||
aria-label="UnHelpful"
|
||||
name="happy"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="aw-content-footer-header-end">
|
||||
<ul class="aw-metadata aw-caption-400">
|
||||
<li>Last updated on July 16, 2023</li>
|
||||
<li>
|
||||
<button class="">
|
||||
<!-- TODO: wait for implement icons in website -->
|
||||
<span class="icon-edit" aria-hidden="true" />
|
||||
<span>Update on GitHub</span>
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
<div class="aw-card is-transparent" style="--card-padding:1rem">
|
||||
<label for="message">
|
||||
<span class="aw-u-color-text-primary">What did you like?</span>
|
||||
<span class="">(optional)</span>
|
||||
</label>
|
||||
<textarea
|
||||
class="aw-input-text u-margin-block-start-8"
|
||||
id="message"
|
||||
placeholder="Write your message"
|
||||
/>
|
||||
<div class="u-flex u-main-end u-margin-block-start-16">
|
||||
<button class="aw-button is-text">
|
||||
<span class="">Cancel</span>
|
||||
</button>
|
||||
<button class="aw-button">
|
||||
<span class="">Submit</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<aside class="aw-references-menu aw-u-padding-inline-start-24">
|
||||
<div class="aw-references-menu-content">
|
||||
<div class="u-flex u-main-space-between u-cross-center u-gap-16">
|
||||
<h5 class="aw-references-menu-title aw-eyebrow">On This Page</h5>
|
||||
</div>
|
||||
<ol class="aw-references-menu-list">
|
||||
{#each Object.entries($headings) as [id, heading]}
|
||||
<li class="aw-references-menu-item">
|
||||
<a href={`#${id}`} class="aw-references-menu-link">
|
||||
{#if heading.step !== undefined}
|
||||
<span class="aw-numeric-badge">{heading.step}</span>
|
||||
{/if}
|
||||
<span class="aw-caption-400">{heading.text}</span>
|
||||
</a>
|
||||
</li>
|
||||
{/each}
|
||||
</ol>
|
||||
<div class="u-sep-block-start u-padding-block-start-20">
|
||||
<a class="aw-button is-text u-main-start aw-u-padding-inline-0" href=".">
|
||||
<span class="icon-arrow-up" aria-hidden="true" />
|
||||
<span class="aw-sub-body-500">Back to top</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
</article>
|
||||
</main>
|
||||
<footer class="aw-main-footer u-margin-block-start-48 u-small">
|
||||
<div class="aw-main-footer-grid-1">
|
||||
<ul class="aw-main-footer-grid-1-column-1 u-flex u-gap-8">
|
||||
<li>
|
||||
<button class="aw-icon-button" aria-label="Appwrite on Discord">
|
||||
<span class="icon-discord" aria-hidden="true" />
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button class="aw-icon-button" aria-label="Appwrite GitHub">
|
||||
<span class="icon-github" aria-hidden="true" />
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button class="aw-icon-button" aria-label="Appwrite on Twitter">
|
||||
<span class="icon-twitter" aria-hidden="true" />
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button class="aw-icon-button" aria-label="Appwrite on LinkedIn">
|
||||
<span class="icon-linkedin" aria-hidden="true" />
|
||||
</button>
|
||||
</li>
|
||||
<li>
|
||||
<button class="aw-icon-button" aria-label="Appwrite YouTube">
|
||||
<span class="icon-youtube" aria-hidden="true" />
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="aw-main-footer-grid-1-column-2">
|
||||
<div class="aw-select is-colored">
|
||||
<button class="physical-select">
|
||||
<span class="icon-moon" aria-hidden="true" />
|
||||
<span>Dark</span>
|
||||
</button>
|
||||
<span class="icon-cheveron-down" aria-hidden="true" />
|
||||
</div>
|
||||
</div>
|
||||
<ul class="aw-main-footer-grid-1-column-3 aw-main-footer-links">
|
||||
<li>
|
||||
<a href=".">Supports</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href=".">Status</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href=".">Changelog</a>
|
||||
</li>
|
||||
</ul>
|
||||
<div class="aw-main-footer-grid-1-column-4 aw-main-footer-copyright">
|
||||
Copyright © 2023 Appwrite
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</Docs>
|
||||
5
src/markdoc/nodes/Code.svelte
Normal file
5
src/markdoc/nodes/Code.svelte
Normal file
@@ -0,0 +1,5 @@
|
||||
<script lang="ts">
|
||||
export let content: string;
|
||||
</script>
|
||||
|
||||
<span class="aw-inline-code">{@html content}</span>
|
||||
81
src/markdoc/nodes/Fence.svelte
Normal file
81
src/markdoc/nodes/Fence.svelte
Normal file
@@ -0,0 +1,81 @@
|
||||
<script context="module" lang="ts">
|
||||
import 'highlight.js/styles/panda-syntax-dark.css';
|
||||
import hljs from 'highlight.js/lib/core';
|
||||
import dart from 'highlight.js/lib/languages/dart';
|
||||
import javascript from 'highlight.js/lib/languages/javascript';
|
||||
import typescript from 'highlight.js/lib/languages/typescript';
|
||||
import xml from 'highlight.js/lib/languages/xml';
|
||||
import shell from 'highlight.js/lib/languages/shell';
|
||||
import markdown from 'highlight.js/lib/languages/markdown';
|
||||
import json from 'highlight.js/lib/languages/json';
|
||||
import swift from 'highlight.js/lib/languages/swift';
|
||||
import php from 'highlight.js/lib/languages/php';
|
||||
import { getContext, hasContext } from 'svelte';
|
||||
import type { CodeContext } from '../tags/MultiCode.svelte';
|
||||
|
||||
hljs.registerLanguage('dart', dart);
|
||||
hljs.registerLanguage('js', javascript);
|
||||
hljs.registerLanguage('ts', typescript);
|
||||
hljs.registerLanguage('xml', xml);
|
||||
hljs.registerLanguage('html', xml);
|
||||
hljs.registerLanguage('sh', shell);
|
||||
hljs.registerLanguage('md', markdown);
|
||||
hljs.registerLanguage('json', json);
|
||||
hljs.registerLanguage('swift', swift);
|
||||
hljs.registerLanguage('php', php);
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
export let content: string;
|
||||
export let language: string;
|
||||
export let process: boolean;
|
||||
|
||||
const insideMultiCode = hasContext('multi-code');
|
||||
const selected = insideMultiCode ? getContext<CodeContext>('multi-code').selected : null;
|
||||
|
||||
if (insideMultiCode) {
|
||||
getContext<CodeContext>('multi-code').snippets.update((n) => {
|
||||
n.add(language);
|
||||
|
||||
return n;
|
||||
});
|
||||
}
|
||||
|
||||
const result = process ? hljs.highlight(content, { language: language ?? 'sh' }).value : content;
|
||||
</script>
|
||||
|
||||
{#if insideMultiCode}
|
||||
{#if $selected === language}
|
||||
<pre><code class={`language-${language}`}>{@html result}</code></pre>
|
||||
{/if}
|
||||
{:else}
|
||||
<section class="aw-code-snippet" aria-label="code-snippet panel">
|
||||
<header class="aw-code-snippet-header">
|
||||
<div class="aw-code-snippet-header-start">
|
||||
<div class="u-flex u-gap-16">
|
||||
<div class="aw-tag"><span class="text">Default</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="aw-code-snippet-header-end">
|
||||
<ul class="buttons-list u-flex u-gap-8">
|
||||
<li class="buttons-list-item u-flex u-cross-child-scenter">
|
||||
<div class="aw-select">
|
||||
<select>
|
||||
<option value="Web SDK">Web SDK</option>
|
||||
</select>
|
||||
<span class="icon-cheveron-down" aria-hidden="true" />
|
||||
</div>
|
||||
</li>
|
||||
<li class="buttons-list-item aw-u-padding-inline-start-20">
|
||||
<button class="aw-icon-button" aria-label="copy code from code-snippet"
|
||||
><span class="icon-duplicate" aria-hidden="true" /></button
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
<div class="aw-code-snippet-content">
|
||||
<pre><code class={`language-${language}`}>{@html result}</code></pre>
|
||||
</div>
|
||||
</section>
|
||||
{/if}
|
||||
34
src/markdoc/nodes/Heading.svelte
Normal file
34
src/markdoc/nodes/Heading.svelte
Normal file
@@ -0,0 +1,34 @@
|
||||
<script lang="ts">
|
||||
import { getContext, hasContext, onMount } from 'svelte';
|
||||
import type { LayoutContext } from '../layouts/Tutorial.svelte';
|
||||
|
||||
export let level: number;
|
||||
export let id: string | undefined = undefined;
|
||||
export let step: number | undefined = undefined;
|
||||
|
||||
const tag = `h${level}`;
|
||||
let element: HTMLElement | undefined;
|
||||
|
||||
$: if (element && hasContext('headings')) {
|
||||
getContext<LayoutContext>('headings').update((n) => {
|
||||
if (id === undefined) {
|
||||
return n;
|
||||
}
|
||||
n[id] = {
|
||||
step,
|
||||
text: element?.textContent ?? ''
|
||||
};
|
||||
|
||||
return n;
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<svelte:element
|
||||
this={tag}
|
||||
{id}
|
||||
bind:this={element}
|
||||
class="aw-main-body-500 aw-u-color-text-primary"
|
||||
>
|
||||
<slot />
|
||||
</svelte:element>
|
||||
9
src/markdoc/nodes/Image.svelte
Normal file
9
src/markdoc/nodes/Image.svelte
Normal file
@@ -0,0 +1,9 @@
|
||||
<script lang="ts">
|
||||
export let src: string;
|
||||
export let alt: string;
|
||||
export let title: string;
|
||||
</script>
|
||||
|
||||
<div class="aw-media">
|
||||
<img {src} {alt} {title} loading="lazy" />
|
||||
</div>
|
||||
6
src/markdoc/nodes/Link.svelte
Normal file
6
src/markdoc/nodes/Link.svelte
Normal file
@@ -0,0 +1,6 @@
|
||||
<script lang="ts">
|
||||
export let href: string;
|
||||
export let title: string;
|
||||
</script>
|
||||
|
||||
<a class="aw-link" {href} {title}><slot /></a>
|
||||
5
src/markdoc/nodes/List.svelte
Normal file
5
src/markdoc/nodes/List.svelte
Normal file
@@ -0,0 +1,5 @@
|
||||
<script lang="ts">
|
||||
export let ordered: boolean;
|
||||
</script>
|
||||
|
||||
<svelte:element this={ordered ? 'ol' : 'ul'} class="aw-list"><slot /></svelte:element>
|
||||
1
src/markdoc/nodes/Paragraph.svelte
Normal file
1
src/markdoc/nodes/Paragraph.svelte
Normal file
@@ -0,0 +1 @@
|
||||
<p class="aw-paragraph-md"><slot /></p>
|
||||
7
src/markdoc/nodes/Table.svelte
Normal file
7
src/markdoc/nodes/Table.svelte
Normal file
@@ -0,0 +1,7 @@
|
||||
<div class="aw-table-wrapper">
|
||||
<div class="aw-table-scroll">
|
||||
<table class="aw-table">
|
||||
<slot />
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
3
src/markdoc/nodes/Tbody.svelte
Normal file
3
src/markdoc/nodes/Tbody.svelte
Normal file
@@ -0,0 +1,3 @@
|
||||
<tbody class="aw-table-body">
|
||||
<slot />
|
||||
</tbody>
|
||||
7
src/markdoc/nodes/Td.svelte
Normal file
7
src/markdoc/nodes/Td.svelte
Normal file
@@ -0,0 +1,7 @@
|
||||
<script lang="ts">
|
||||
export let align: string;
|
||||
</script>
|
||||
|
||||
<td class="aw-table-col">
|
||||
<slot />
|
||||
</td>
|
||||
11
src/markdoc/nodes/Th.svelte
Normal file
11
src/markdoc/nodes/Th.svelte
Normal file
@@ -0,0 +1,11 @@
|
||||
<script lang="ts">
|
||||
import type { HTMLThAttributes } from 'svelte/elements';
|
||||
|
||||
export let align: HTMLThAttributes['align'] = undefined;
|
||||
</script>
|
||||
|
||||
<th class="aw-table-head-col" {align}>
|
||||
<span class="aw-eyebrow">
|
||||
<slot />
|
||||
</span>
|
||||
</th>
|
||||
3
src/markdoc/nodes/Thead.svelte
Normal file
3
src/markdoc/nodes/Thead.svelte
Normal file
@@ -0,0 +1,3 @@
|
||||
<thead class="aw-table-header">
|
||||
<slot />
|
||||
</thead>
|
||||
3
src/markdoc/nodes/Tr.svelte
Normal file
3
src/markdoc/nodes/Tr.svelte
Normal file
@@ -0,0 +1,3 @@
|
||||
<tr class="aw-table-row">
|
||||
<slot />
|
||||
</tr>
|
||||
15
src/markdoc/nodes/_Module.svelte
Normal file
15
src/markdoc/nodes/_Module.svelte
Normal file
@@ -0,0 +1,15 @@
|
||||
<script context="module">
|
||||
export { default as Code } from './Code.svelte';
|
||||
export { default as Fence } from './Fence.svelte';
|
||||
export { default as Heading } from './Heading.svelte';
|
||||
export { default as List } from './List.svelte';
|
||||
export { default as Paragraph } from './Paragraph.svelte';
|
||||
export { default as Image } from './Image.svelte';
|
||||
export { default as Link } from './Link.svelte';
|
||||
export { default as Table } from './Table.svelte';
|
||||
export { default as Tbody } from './Tbody.svelte';
|
||||
export { default as Td } from './Td.svelte';
|
||||
export { default as Th } from './Th.svelte';
|
||||
export { default as Thead } from './Thead.svelte';
|
||||
export { default as Tr } from './Tr.svelte';
|
||||
</script>
|
||||
55
src/markdoc/tags/MultiCode.svelte
Normal file
55
src/markdoc/tags/MultiCode.svelte
Normal file
@@ -0,0 +1,55 @@
|
||||
<script context="module" lang="ts">
|
||||
import type { Writable } from 'svelte/store';
|
||||
export type CodeContext = {
|
||||
selected: Writable<string | null>;
|
||||
snippets: Writable<Set<string>>;
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { getContext, setContext } from 'svelte';
|
||||
import { writable } from 'svelte/store';
|
||||
|
||||
setContext<CodeContext>('multi-code', {
|
||||
selected: writable(null),
|
||||
snippets: writable(new Set())
|
||||
});
|
||||
|
||||
const { snippets, selected } = getContext<CodeContext>('multi-code');
|
||||
|
||||
snippets.subscribe(n => {
|
||||
if ($selected === null && n.size > 0) {
|
||||
$selected = Array.from(n)[0];
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<section class="aw-code-snippet" aria-label="code-snippet panel">
|
||||
<header class="aw-code-snippet-header">
|
||||
<div class="aw-code-snippet-header-start">
|
||||
<div class="u-flex u-gap-16">
|
||||
<div class="aw-tag"><span class="text">Default</span></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="aw-code-snippet-header-end">
|
||||
<ul class="buttons-list u-flex u-gap-8">
|
||||
<li class="buttons-list-item u-flex u-cross-child-scenter">
|
||||
<div class="aw-select">
|
||||
<select bind:value={$selected}>
|
||||
{#each Array.from($snippets) as language}
|
||||
<option value={language}>{language}</option>
|
||||
{/each}
|
||||
</select>
|
||||
<span class="icon-cheveron-down" aria-hidden="true" />
|
||||
</div>
|
||||
</li>
|
||||
<li class="buttons-list-item aw-u-padding-inline-start-20">
|
||||
<button class="aw-icon-button" aria-label="copy code from code-snippet"
|
||||
><span class="icon-duplicate" aria-hidden="true" /></button
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</header>
|
||||
<div class="aw-code-snippet-content"><slot /></div>
|
||||
</section>
|
||||
19
src/markdoc/tags/Section.svelte
Normal file
19
src/markdoc/tags/Section.svelte
Normal file
@@ -0,0 +1,19 @@
|
||||
<script lang="ts">
|
||||
import Heading from '../nodes/Heading.svelte';
|
||||
|
||||
export let id: string;
|
||||
export let step: number;
|
||||
export let title: string;
|
||||
</script>
|
||||
|
||||
<section class="aw-article-content-section is-with-line">
|
||||
<section class="aw-article-content-sub-section">
|
||||
<header class="aw-article-content-header">
|
||||
<span class="aw-numeric-badge">{step}</span>
|
||||
<Heading level={2} {id} {step}>
|
||||
{title}
|
||||
</Heading>
|
||||
</header>
|
||||
<slot />
|
||||
</section>
|
||||
</section>
|
||||
4
src/markdoc/tags/_Module.svelte
Normal file
4
src/markdoc/tags/_Module.svelte
Normal file
@@ -0,0 +1,4 @@
|
||||
<script context="module">
|
||||
export { default as Section } from './Section.svelte';
|
||||
export { default as MultiCode } from './MultiCode.svelte';
|
||||
</script>
|
||||
168
src/routes/test/+page.markdoc
Normal file
168
src/routes/test/+page.markdoc
Normal file
@@ -0,0 +1,168 @@
|
||||
---
|
||||
title: Hello world
|
||||
difficulty: beginner
|
||||
readtime: 3
|
||||
---
|
||||
|
||||
Text can be **bold**, _italic_, ~~strikethrough~~or a [link to another page](#).
|
||||
|
||||
There should be whitespace between paragraphs.
|
||||
|
||||
There should be whitespace between paragraphs. We recommend including a README, or a file with information about your project.
|
||||
|
||||
# Header 1 {% #header-1 %}
|
||||
|
||||
This is a normal paragraph following a header. GitHub is a code hosting platform for version control and collaboration. It lets you and others work together on projects from anywhere.
|
||||
|
||||
## Header 2 {% #header-2 %}
|
||||
|
||||
> This is a blockquote following a header.
|
||||
>
|
||||
> When something is important enough, you do it even if the odds are not in your favor.
|
||||
|
||||
### Header 3 {% #header-3 %}
|
||||
|
||||
This is a fenced codeblock:
|
||||
|
||||
```js
|
||||
// Javascript code with syntax highlighting.
|
||||
const cars = ["BMW", "Volvo", "Mini"];
|
||||
let text = "";
|
||||
|
||||
for (let x of cars) {
|
||||
text += x + " ";
|
||||
}
|
||||
```
|
||||
|
||||
And you can also have `inline code`.
|
||||
|
||||
#### Header 4
|
||||
|
||||
* This is an unordered list following a header.
|
||||
* This is an unordered list following a header.
|
||||
* This is an unordered list following a header.
|
||||
|
||||
##### Header 5
|
||||
|
||||
1. This is an ordered list following a header.
|
||||
1. This is an ordered list following a header.
|
||||
1. This is an ordered list following a header.
|
||||
|
||||
###### Header 6
|
||||
|
||||
This is a nice table:
|
||||
|
||||
| head1 | head two | three |
|
||||
| ----------------- | ----------------- | ----------------- |
|
||||
| ok | good swedish fish | nice |
|
||||
| out of stock | good and plenty | nice |
|
||||
| ok | good `oreos` | hmm |
|
||||
| ok | good `zoute` drop | yumm |
|
||||
|
||||
### There's a horizontal rule below this.
|
||||
|
||||
---
|
||||
|
||||
### And a nested list:
|
||||
|
||||
- level 1 item
|
||||
- level 2 item
|
||||
- level 2 item
|
||||
- level 3 item
|
||||
- level 3 item
|
||||
- level 1 item
|
||||
- level 2 item
|
||||
- level 2 item
|
||||
- level 2 item
|
||||
- level 1 item
|
||||
- level 2 item
|
||||
- level 2 item
|
||||
- level 1 item
|
||||
|
||||
### Image
|
||||
|
||||

|
||||
|
||||
{% section #featured-products-1 step=1 title="Featured products 1" %}
|
||||
Lorem ipsum dolor sit amet consectetur. Id nisi quam nisl iaculis semper nibh egestas ut. Dictum tortor arcu feugiat metus pellentesque posuere.
|
||||
{% /section %}
|
||||
|
||||
{% section #featured-products-2 step=2 title="Featured products 2" %}
|
||||
Lorem ipsum dolor sit amet consectetur. Id nisi quam nisl iaculis semper nibh egestas ut. Dictum tortor arcu feugiat metus pellentesque posuere.
|
||||
|
||||
## Sub title
|
||||
|
||||
{% multicode %}
|
||||
```js
|
||||
const sdk = require('node-appwrite');
|
||||
|
||||
const client = new sdk.Client();
|
||||
const users = new sdk.Users(client);
|
||||
|
||||
client
|
||||
.setEndpoint('https://cloud.appwrite.io/v1')
|
||||
.setProject('5df5acd0d48c2')
|
||||
.setKey('919c2d18fb5d4...a2ae413da83346ad2');
|
||||
|
||||
const promise = users.create('[USER_ID]');
|
||||
|
||||
promise.then(function (response) {
|
||||
console.log(response);
|
||||
}, function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
```
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
use Appwrite\Client;
|
||||
use Appwrite\Services\Users;
|
||||
|
||||
$client = new Client();
|
||||
|
||||
$client
|
||||
->setEndpoint('https://cloud.appwrite.io/v1')
|
||||
->setProject('5df5acd0d48c2')
|
||||
->setKey('919c2d18fb5d4...a2ae413da83346ad2');
|
||||
|
||||
$users = new Users($client);
|
||||
|
||||
$result = $users->create('[USER_ID]');
|
||||
```
|
||||
|
||||
```swift
|
||||
import Appwrite
|
||||
|
||||
func main() async throws {
|
||||
let client = Client()
|
||||
.setEndpoint("https://cloud.appwrite.io/v1")
|
||||
.setProject("5df5acd0d48c2")
|
||||
.setKey("919c2d18fb5d4...a2ae413da83346ad2")
|
||||
|
||||
let users = Users(client)
|
||||
let user = try await users.create(
|
||||
userId: "[USER_ID]"
|
||||
)
|
||||
|
||||
print(String(describing: user)
|
||||
}
|
||||
```
|
||||
{% /multicode %}
|
||||
|
||||
## Sub title
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur. Id nisi quam nisl iaculis semper nibh egestas ut. Dictum tortor arcu feugiat metus pellentesque posuere.
|
||||
{% /section %}
|
||||
|
||||
{% section #featured-products-3 step=3 title="Featured products 3" %}
|
||||
Lorem ipsum dolor sit amet consectetur. Id nisi quam nisl iaculis semper nibh egestas ut. Dictum tortor arcu feugiat metus pellentesque posuere.
|
||||
|
||||
## Sub title
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur. Id nisi quam nisl iaculis semper nibh egestas ut. Dictum tortor arcu feugiat metus pellentesque posuere.
|
||||
|
||||
## Sub title
|
||||
|
||||
Lorem ipsum dolor sit amet consectetur. Id nisi quam nisl iaculis semper nibh egestas ut. Dictum tortor arcu feugiat metus pellentesque posuere.
|
||||
{% /section %}
|
||||
@@ -1,12 +1,32 @@
|
||||
import { dirname, join } from "path";
|
||||
import { fileURLToPath } from "url";
|
||||
import { vitePreprocess } from '@sveltejs/kit/vite';
|
||||
import { preprocessMeltUI } from '@melt-ui/pp';
|
||||
import { markdoc } from 'svelte-markdoc-preprocess';
|
||||
import sequence from 'svelte-sequential-preprocessor';
|
||||
import adapter from '@sveltejs/adapter-auto';
|
||||
import { vitePreprocess } from '@sveltejs/kit/vite';
|
||||
|
||||
function absoulute (path) {
|
||||
return join(dirname(fileURLToPath(import.meta.url)), path)
|
||||
}
|
||||
|
||||
/** @type {import('@sveltejs/kit').Config}*/
|
||||
const config = {
|
||||
// Consult https://kit.svelte.dev/docs/integrations#preprocessors
|
||||
// for more information about preprocessors
|
||||
preprocess: sequence([vitePreprocess(), preprocessMeltUI()]),
|
||||
preprocess: sequence([
|
||||
vitePreprocess(),
|
||||
markdoc({
|
||||
generateSchema: true,
|
||||
nodes: absoulute('./src/markdoc/nodes/_Module.svelte'),
|
||||
tags: absoulute('./src/markdoc/tags/_Module.svelte'),
|
||||
layouts: {
|
||||
default: absoulute('./src/markdoc/layouts/Tutorial.svelte'),
|
||||
}
|
||||
}),
|
||||
preprocessMeltUI()
|
||||
]),
|
||||
extensions: ['.markdoc', '.svelte'],
|
||||
kit: {
|
||||
// adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list.
|
||||
// If your environment is not supported or you settled on a specific environment, switch out the adapter.
|
||||
|
||||
Reference in New Issue
Block a user