Skip to content

Commit 81857fb

Browse files
committed
📝 Add basic docs site with content from ReadMe
1 parent 49791f0 commit 81857fb

34 files changed

+2605
-660
lines changed

.gitignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
1+
# Built files
12
dist
3+
.svelte-kit
4+
build
5+
6+
# Dependencies
27
node_modules
38
.npmrc
49

10+
# Test files
511
coverage
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import Markdoc from '@markdoc/markdoc'
2+
3+
const fence = {
4+
render: 'CodeBlock',
5+
attributes: {
6+
content: {
7+
type: String,
8+
},
9+
language: {
10+
type: String,
11+
},
12+
process: {
13+
...Markdoc.nodes.fence.attributes.process,
14+
default: false
15+
},
16+
},
17+
async transform(node, config) {
18+
const attributes = node.transformAttributes(config)
19+
const children = node.transformChildren(config)
20+
const code =
21+
children.length > 0
22+
? children.join()
23+
: attributes.content
24+
25+
const codeWithoutEmptyLastLine = code.replace(/\n$/, '')
26+
27+
return new Markdoc.Tag(this.render, {
28+
lang: attributes.language,
29+
code: codeWithoutEmptyLastLine,
30+
})
31+
},
32+
}
33+
34+
export default fence
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import fence from './fence.js'
2+
3+
const nodes = {
4+
fence,
5+
}
6+
7+
export default nodes

packages/docs/package.json

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
{
2+
"name": "collier.cz",
3+
"version": "1.0.0",
4+
"scripts": {
5+
"dev": "vite dev",
6+
"dev:open": "vite dev --open",
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+
"lint": "prettier . --check && eslint .",
12+
"format": "prettier --write .",
13+
"test": "vitest run",
14+
"test:coverage": "vitest run --coverage"
15+
},
16+
"devDependencies": {
17+
"@fontsource/fira-mono": "^5.1.0",
18+
"@markdoc/markdoc": "^0.5.2",
19+
"@sveltejs/adapter-static": "^3.0.6",
20+
"@sveltejs/kit": "2.6.0",
21+
"@sveltejs/vite-plugin-svelte": "^5.1.0",
22+
"@tailwindcss/typography": "^0.5.15",
23+
"@types/eslint": "^9.6.1",
24+
"@types/eslint-config-prettier": "^6.11.3",
25+
"@types/eslint__js": "^8.42.3",
26+
"@types/node": "^22.15.32",
27+
"@vitest/coverage-v8": "^2.1.8",
28+
"autoprefixer": "^10.4.20",
29+
"globals": "^15.14.0",
30+
"markdoc-svelte": "file:../markdoc-svelte",
31+
"shiki": "^1.24.3",
32+
"svelte": "^5.15.0",
33+
"svelte-check": "^4.1.1",
34+
"svelte-preprocess": "^6.0.3",
35+
"tailwindcss": "^3.4.17",
36+
"typescript": "^5.7.2",
37+
"vite": "^6.3.5",
38+
"vitest": "^2.1.8"
39+
},
40+
"type": "module"
41+
}

packages/docs/src/app.css

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
@tailwind base;
2+
@tailwind components;
3+
@tailwind utilities;

packages/docs/src/app.html

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<!doctype html>
2+
<html lang="en">
3+
<head>
4+
<meta charset="utf-8" />
5+
<meta name="viewport" content="width=device-width, initial-scale=1" />
6+
%sveltekit.head%
7+
</head>
8+
<body data-sveltekit-preload-data="hover">
9+
<div style="display: contents">%sveltekit.body%</div>
10+
</body>
11+
</html>
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
---
2+
title: Customize Markdoc
3+
---
4+
5+
To add additional features to the syntax of your files, customize your Markdoc schema.
6+
You can add the following extensions:
7+
8+
- [Nodes](#nodes)
9+
- [Tags](#tags)
10+
- [Variables](#variables)
11+
- [Functions](#functions)
12+
- [Partials](#partials)
13+
14+
You can customize schema in two ways:
15+
16+
- **For a single extension** or simple extensions, pass directly to the preprocessor options.
17+
- **For multiple extensions at once** or more complex configurations,
18+
create a configuration folder with schema definitions.
19+
20+
For each extension (such as `nodes`),
21+
schema definitions passed directly overwrite configuration from a folder.
22+
23+
## Direct definitions
24+
25+
To define any of the extension points directly,
26+
pass it to the preprocessor options as the name of the extension.
27+
For example, to define a `$site.name` variable, pass the following:
28+
29+
```javascript
30+
import { markdocPreprocess } from "markdoc-svelte";
31+
32+
/** @type {import('@sveltejs/kit').Config} */
33+
const config = {
34+
extensions: [".svelte", ".mdoc"],
35+
preprocess: [
36+
markdocPreprocess({
37+
variables: {
38+
site: {
39+
name: "Markdoc Svelte",
40+
},
41+
},
42+
}),
43+
],
44+
};
45+
```
46+
47+
## Configuration folder
48+
49+
For multiple extensions or more complex configurations, create a folder with your entire Markdoc schema.
50+
51+
By default, the preprocessor looks for a schema in the `./markdoc` and `./src/markdoc` directories.
52+
53+
Define each extension point as a single file
54+
or as a directory with an `index.ts` or `index.js` file that exports it.
55+
Partials must be a directory holding Markdoc files.
56+
57+
All extension points are optional.
58+
59+
Example structure:
60+
61+
```
62+
markdoc
63+
├── functions.ts
64+
├── nodes
65+
│ ├── heading.ts
66+
│ ├── index.ts
67+
│ └── callout.ts
68+
├── partials
69+
│ ├── content.mdoc
70+
│ └── more-content.mdoc
71+
├── tags.ts
72+
└── variables.ts
73+
```
74+
75+
For example, create custom nodes in `markdoc/nodes.ts`:
76+
77+
```typescript
78+
import type { Config } from "markdoc-svelte";
79+
import { Markdoc } from "markdoc-svelte";
80+
81+
const nodes: Config["nodes"] = {
82+
image: {
83+
render: "EnhancedImage",
84+
attributes: {
85+
...Markdoc.nodes.image.attributes, // Include the default image attributes
86+
},
87+
},
88+
};
89+
90+
export default nodes;
91+
```
92+
93+
Or create an index file to export all custom nodes from `markdoc/nodes/index.ts`
94+
(remember to use [relative imports](#relative-imports)):
95+
96+
```typescript
97+
import image from "./image.ts";
98+
import link from "./link.ts";
99+
import paragraph from "./paragraph.ts";
100+
import type { Config } from "markdoc-svelte";
101+
102+
const nodes: Config["nodes"] = {
103+
image,
104+
link,
105+
paragraph,
106+
};
107+
108+
export default nodes;
109+
```
110+
111+
## Relative imports
112+
113+
You can use relative imports to import definitions from either `.js` or `.ts` files.
114+
Just remember to include the file extension.
115+
116+
For example, if you define custom functions in `src/lib/functions.js`,
117+
add them to your schema as follows:
118+
119+
```javascript
120+
import { markdocPreprocess } from "markdoc-svelte";
121+
import functions from "./src/lib/functions.js";
122+
123+
/** @type {import('@sveltejs/kit').Config} */
124+
const config = {
125+
preprocess: [
126+
markdocPreprocess({
127+
functions: functions,
128+
}),
129+
],
130+
};
131+
```
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
title: Enhanced images
3+
---
4+
5+
Use the [enhanced-img plugin](https://svelte.dev/docs/kit/images#sveltejs-enhanced-img) with images in your files processed by `markdown-svelte`.
6+
To do so, customize the default images Node with a custom Svelte component.
7+
See an example [custom node](../schema/nodes).
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
title: Index page example
3+
---
4+
5+
Each processed page exports a slug based on the file name.
6+
This is a convenient way to generate an index page without reaching into the document.
7+
8+
Glob import these slugs as data for your index page.
9+
For example, if all of your pages end with the extension `.md`,
10+
Add the following to `src/routes/blog/+page.ts`:
11+
12+
```typescript
13+
import type { MarkdocModule } from "markdoc-svelte";
14+
15+
import type { PageLoad } from "./$types";
16+
17+
const markdownModules = import.meta.glob("$lib/markdown/*.md");
18+
19+
export const load: PageLoad = async () => {
20+
const content = await Promise.all(
21+
Object.values(markdownModules).map(async (importModule) => {
22+
// Dynamically import each module
23+
const module = (await importModule()) as MarkdocModule;
24+
// Pass only slug and frontmatter to the page data
25+
return {
26+
slug: module.slug,
27+
frontmatter: module.frontmatter,
28+
};
29+
}),
30+
);
31+
return { content };
32+
};
33+
```
34+
35+
Then use this data to build an index page at `src/routes/blog/+page.svelte`:
36+
37+
```svelte
38+
<script lang="ts">
39+
import type { PageProps } from './$types';
40+
41+
let { data }: PageProps = $props();
42+
const { content } = data;
43+
</script>
44+
45+
<h1>Table of Contents</h1>
46+
<ul>
47+
{#each content as item, i (item.slug)}
48+
<li class={'item-' + i}>
49+
<a href="/{item.slug}">
50+
<h2>{item.frontmatter?.title || item.slug}</h2>
51+
{#if item.frontmatter?.description}
52+
<span>{item.frontmatter.description}</span>
53+
{/if}
54+
{#if item.frontmatter?.published}
55+
<span>{item.frontmatter.published}</span>
56+
{/if}
57+
</a>
58+
</li>
59+
{/each}
60+
</ul>
61+
```
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
title: Table of contents
3+
---
4+
5+
Each proccessed page automatically exports a `headings` property with all headings on the page and IDs for each.
6+
Add IDs with [annotations](https://markdoc.dev/docs/syntax#annotations) or they are generated automatically.
7+
Use this list to generate a table of contents for the page, as in the following example:
8+
9+
```svelte
10+
<script lang="ts">
11+
import type { PageProps } from './$types';
12+
13+
let { data }: PageProps = $props();
14+
const { frontmatter, headings } = data.page;
15+
16+
// Filter only h1 and h2 headings
17+
const filteredHeadings = headings?.filter((heading) => heading.level <= 2) ?? [];
18+
</script>
19+
20+
<svelte:head>
21+
<title>{data.page.frontmatter?.title ?? 'Undefined title'}</title>
22+
</svelte:head>
23+
24+
{#if filteredHeadings.length > 0}
25+
<ul>
26+
{#each filteredHeadings as heading}
27+
<li>
28+
<a href={`#${heading.id}`}>{heading.text}</a>
29+
</li>
30+
{/each}
31+
</ul>
32+
{/if}
33+
34+
<data.page.default />
35+
```

0 commit comments

Comments
 (0)