@mralfarrakhan/svork 0.7.1-alpha → 0.8.0-alpha
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +99 -37
- package/dist/index.mjs +10 -2
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
# Svork
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Svelte 5 preprocessors for content files.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- `svelteMarkdown` — Markdown with Svelte interop
|
|
6
|
+
- `svelteTypst` — Typst documents compiled to Svelte components
|
|
7
|
+
|
|
8
|
+
---
|
|
6
9
|
|
|
7
10
|
## Install
|
|
8
11
|
|
|
@@ -10,22 +13,30 @@ It is intended for blog/content pages where Markdown should stay ergonomic while
|
|
|
10
13
|
bun add -D @mralfarrakhan/svork
|
|
11
14
|
```
|
|
12
15
|
|
|
13
|
-
|
|
16
|
+
For Typst support, also install the compiler:
|
|
17
|
+
|
|
18
|
+
```sh
|
|
19
|
+
bun add -D @myriaddreamin/typst-ts-node-compiler
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## svelteMarkdown
|
|
14
25
|
|
|
15
|
-
|
|
26
|
+
Markdown files with frontmatter, scripts, components, and inline expressions.
|
|
16
27
|
|
|
17
|
-
|
|
28
|
+
### Setup
|
|
18
29
|
|
|
19
30
|
```js
|
|
20
|
-
import { svelteMarkdown } from "svork";
|
|
31
|
+
import { svelteMarkdown } from "@mralfarrakhan/svork";
|
|
21
32
|
|
|
22
33
|
export default {
|
|
23
34
|
preprocess: [svelteMarkdown()],
|
|
24
|
-
extensions: [".
|
|
35
|
+
extensions: [".svelte", ".md"],
|
|
25
36
|
};
|
|
26
37
|
```
|
|
27
38
|
|
|
28
|
-
|
|
39
|
+
### Usage
|
|
29
40
|
|
|
30
41
|
```svelte
|
|
31
42
|
---
|
|
@@ -35,7 +46,6 @@ author: Budi
|
|
|
35
46
|
|
|
36
47
|
<script lang="ts">
|
|
37
48
|
import Badge from "./Badge.svelte";
|
|
38
|
-
|
|
39
49
|
const label = "New";
|
|
40
50
|
</script>
|
|
41
51
|
|
|
@@ -46,55 +56,107 @@ author: Budi
|
|
|
46
56
|
Hello, {metadata.author}.
|
|
47
57
|
```
|
|
48
58
|
|
|
49
|
-
Frontmatter is exported as `metadata` from
|
|
59
|
+
Frontmatter is exported as `metadata` from a module script:
|
|
50
60
|
|
|
51
|
-
```
|
|
52
|
-
export const metadata = {
|
|
53
|
-
title: "Hello",
|
|
54
|
-
author: "Budi",
|
|
55
|
-
};
|
|
61
|
+
```ts
|
|
62
|
+
export const metadata = { title: "Hello", author: "Budi" };
|
|
56
63
|
```
|
|
57
64
|
|
|
58
|
-
|
|
65
|
+
### Options
|
|
59
66
|
|
|
60
67
|
```ts
|
|
61
68
|
type SvelteMarkdownOptions = {
|
|
62
|
-
extensions?: string[];
|
|
69
|
+
extensions?: string[]; // default: [".md"]
|
|
63
70
|
remarkPlugins?: PluggableList;
|
|
64
71
|
rehypePlugins?: PluggableList;
|
|
65
72
|
};
|
|
66
73
|
```
|
|
67
74
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
Example with common unified plugins:
|
|
75
|
+
Example with plugins:
|
|
71
76
|
|
|
72
77
|
```js
|
|
73
78
|
import rehypeExpressiveCode from "rehype-expressive-code";
|
|
74
79
|
import remarkGfm from "remark-gfm";
|
|
75
|
-
|
|
80
|
+
|
|
81
|
+
svelteMarkdown({
|
|
82
|
+
remarkPlugins: [remarkGfm],
|
|
83
|
+
rehypePlugins: [[rehypeExpressiveCode, { themes: ["github-light"] }]],
|
|
84
|
+
})
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Behavior
|
|
88
|
+
|
|
89
|
+
- Parses source with Svelte before Markdown so Svelte spans are protected.
|
|
90
|
+
- Hides code spans and fenced blocks from the Svelte parse — `{`, `}`, component-like text inside code stay as code.
|
|
91
|
+
- Preserves instance scripts, module scripts, components, and inline expression tags.
|
|
92
|
+
- Runs `remarkPlugins` and `rehypePlugins` through the unified pipeline.
|
|
93
|
+
- Escapes remaining text and attribute braces after rehype plugins run.
|
|
94
|
+
- Emits unsupported Svelte syntax as text: `{#if}`, `{#each}`, `{#snippet}`, `{@html}`, `{@render}`, and directives on lowercase elements.
|
|
95
|
+
- Falls back to Markdown-only processing with metadata export when Svelte parsing fails.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## svelteTypst
|
|
100
|
+
|
|
101
|
+
Full Typst documents compiled to Svelte components at build time.
|
|
102
|
+
|
|
103
|
+
### Setup
|
|
104
|
+
|
|
105
|
+
```js
|
|
106
|
+
import { svelteTypst } from "@mralfarrakhan/svork";
|
|
76
107
|
|
|
77
108
|
export default {
|
|
78
|
-
preprocess: [
|
|
79
|
-
|
|
80
|
-
remarkPlugins: [remarkGfm],
|
|
81
|
-
rehypePlugins: [[rehypeExpressiveCode, { themes: ["github-light"] }]],
|
|
82
|
-
}),
|
|
83
|
-
],
|
|
84
|
-
extensions: [".svelte", ".md"],
|
|
109
|
+
preprocess: [svelteTypst()],
|
|
110
|
+
extensions: [".svelte", ".typ"],
|
|
85
111
|
};
|
|
86
112
|
```
|
|
87
113
|
|
|
88
|
-
|
|
114
|
+
### Usage
|
|
115
|
+
|
|
116
|
+
```typst
|
|
117
|
+
#metadata((
|
|
118
|
+
title: "My Post",
|
|
119
|
+
date: "2026-01-01",
|
|
120
|
+
)) <frontmatter>
|
|
121
|
+
|
|
122
|
+
= Section Heading
|
|
123
|
+
|
|
124
|
+
A paragraph with *bold* and _italic_ text.
|
|
125
|
+
|
|
126
|
+
== Subsection
|
|
127
|
+
|
|
128
|
+
More content. A footnote.#footnote[Footnote content here.]
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Metadata is exported from a module script:
|
|
89
132
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
133
|
+
```ts
|
|
134
|
+
export const metadata = { title: "My Post", date: "2026-01-01" };
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### Options
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
type SvelteTypstOptions = {
|
|
141
|
+
extensions?: string[]; // default: [".typ"]
|
|
142
|
+
rehypePlugins?: PluggableList;
|
|
143
|
+
compileArgs?: CompileArgs; // passed to NodeCompiler.create()
|
|
144
|
+
};
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
`compileArgs` accepts `fontArgs`, `workspace`, and `inputs` from `@myriaddreamin/typst-ts-node-compiler`.
|
|
148
|
+
|
|
149
|
+
### Behavior
|
|
150
|
+
|
|
151
|
+
- Compiles Typst source with `typst-ts-node-compiler` at build time (no runtime dependency).
|
|
152
|
+
- Extracts metadata via `#metadata((...)) <frontmatter>` label. Values must be JSON-serializable.
|
|
153
|
+
- Runs `rehypePlugins` on the HTML output. Headings are root-level tree children, so plugins like `rehype-sectionize` work correctly.
|
|
154
|
+
- Seeds `vfile.data.fm` with extracted metadata before running plugins — plugins can read and augment it.
|
|
155
|
+
- Escapes braces in output for Svelte safety.
|
|
156
|
+
- No Svelte expressions or components inside `.typ` files — Typst owns the document syntax.
|
|
157
|
+
- Heading levels are offset by one: `= Heading` → `<h2>`, `== Heading` → `<h3>`. Typst reserves `<h1>` for the document title.
|
|
158
|
+
|
|
159
|
+
---
|
|
98
160
|
|
|
99
161
|
## Development
|
|
100
162
|
|
package/dist/index.mjs
CHANGED
|
@@ -7,6 +7,7 @@ import remarkRehype from "remark-rehype";
|
|
|
7
7
|
import rehypeRaw from "rehype-raw";
|
|
8
8
|
import rehypeStringify from "rehype-stringify";
|
|
9
9
|
import yaml from "js-yaml";
|
|
10
|
+
import { resolve } from "path";
|
|
10
11
|
import { NodeCompiler } from "@myriaddreamin/typst-ts-node-compiler";
|
|
11
12
|
//#region \0rolldown/runtime.js
|
|
12
13
|
var __create = Object.create;
|
|
@@ -11379,7 +11380,9 @@ const svelteTypst = (options) => {
|
|
|
11379
11380
|
markup: async ({ content, filename }) => {
|
|
11380
11381
|
if (!filename || !hasWantedExt(filename)) return;
|
|
11381
11382
|
const c = getCompiler();
|
|
11382
|
-
const
|
|
11383
|
+
const absolutePath = resolve(filename);
|
|
11384
|
+
c.addSource(absolutePath, content);
|
|
11385
|
+
const compiled = c.compileHtml({ mainFilePath: absolutePath });
|
|
11383
11386
|
if (compiled.hasError()) {
|
|
11384
11387
|
compiled.printErrors();
|
|
11385
11388
|
throw new Error(`[svelteTypst] Compilation failed for ${filename}`);
|
|
@@ -11402,7 +11405,12 @@ const svelteTypst = (options) => {
|
|
|
11402
11405
|
throw new Error(`[svelteTypst] HTML rendering failed for ${filename}`);
|
|
11403
11406
|
}
|
|
11404
11407
|
const htmlOutput = htmlExec.result;
|
|
11405
|
-
const
|
|
11408
|
+
const parsed = fromParse5(parseFragment(htmlOutput.body()));
|
|
11409
|
+
const outerDiv = parsed.children.find((c) => c.tagName === "div");
|
|
11410
|
+
const bodyRoot = outerDiv ? {
|
|
11411
|
+
type: "root",
|
|
11412
|
+
children: outerDiv.children
|
|
11413
|
+
} : parsed;
|
|
11406
11414
|
const vfile = new VFile();
|
|
11407
11415
|
vfile.data.fm = { ...metadata };
|
|
11408
11416
|
const transformed = await rehypeProcessor.run(bodyRoot, vfile);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mralfarrakhan/svork",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.
|
|
4
|
+
"version": "0.8.0-alpha",
|
|
5
5
|
"description": "Svelte utilities for writing blog",
|
|
6
6
|
"author": "mralfarrakhan <alfarrakhan@gmail.com",
|
|
7
7
|
"license": "AGPL-3.0-or-later",
|
|
@@ -51,8 +51,8 @@
|
|
|
51
51
|
"rehype-slug": "^6.0.0",
|
|
52
52
|
"remark-gfm": "^4.0.1",
|
|
53
53
|
"shiki": "^4.1.0",
|
|
54
|
-
"svelte": "^5.55.
|
|
55
|
-
"tsdown": "^0.22.
|
|
54
|
+
"svelte": "^5.55.10",
|
|
55
|
+
"tsdown": "^0.22.1",
|
|
56
56
|
"typescript": "^6.0.3",
|
|
57
57
|
"unified": "^11.0.5",
|
|
58
58
|
"vitest": "^4.1.7"
|