Skip to content

Commit e1a1d6f

Browse files
Merge pull request #10 from stereobooster/d2-support-for-import
d2: support for import
2 parents 8f45f31 + 62cbeeb commit e1a1d6f

File tree

7 files changed

+94
-5
lines changed

7 files changed

+94
-5
lines changed

packages/docs/astro.config.mjs

+2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ const conf = {
1919
// do not use .beoe for Netlify deployments
2020
fsPath: "public/beoe",
2121
webPath: "/beoe",
22+
// for D2
23+
shared: "shared/**/*.d2",
2224
};
2325

2426
// https://astro.build/config

packages/docs/shared/x.d2

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
x: {
2+
shape: circle
3+
}

packages/docs/src/content/docs/diagrams/d2.mdx

+7
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,12 @@ export type D2Options = {
8282
* Renders the diagram to look like it was sketched by hand.
8383
*/
8484
sketch?: boolean;
85+
/**
86+
* @default undefined
87+
* Glob pattern for files to be used for [`import`](https://d2lang.com/tour/imports/).
88+
* `GlobOptions` are from [tinyglobby](https://github.com/SuperchupuDev/tinyglobby#options).
89+
*/
90+
shared?: string | string[] | GlobOptions;
8591
};
8692
```
8793

@@ -106,6 +112,7 @@ Or locally:
106112
- [x] [Support links in connections](https://github.com/terrastruct/d2/pull/1955)
107113
- [x] [JS package](https://github.com/terrastruct/d2/discussions/234#discussioncomment-11286029)
108114
- [x] [Export JSON graph](https://github.com/terrastruct/d2/discussions/2224)
115+
- [x] [support `import`](https://github.com/terrastruct/d2/issues/2301)
109116
- [ ] [Class-based dark mode](https://github.com/terrastruct/d2/pull/1803)
110117
- [ ] [Remove embeded fonts](https://github.com/terrastruct/d2/discussions/132)
111118
- [ ] [Smaller embeded icons](https://github.com/terrastruct/d2/discussions/2223)

packages/docs/src/content/docs/examples/d2-test.md

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,24 @@
11
---
22
title: d2 test
3-
draft: true
43
---
54

5+
## Interesting ones
6+
7+
### Interactive example
8+
9+
```d2 strategy=inline darkScheme=false graphFormat=dagre class=shadow svgo=false
10+
direction: right
11+
a -> b -> c -> d -> e
12+
```
13+
14+
### import
15+
16+
```d2
17+
direction: right
18+
a:@"shared/x.d2"
19+
a -> b
20+
```
21+
622
## containers
723

824
```d2
@@ -282,7 +298,7 @@ a2 -> b -> c -> d -> e
282298

283299
### `strategy=inline`
284300

285-
```d2 strategy=inline darkScheme=false graphFormat=dagre class=shadow svgo=false
301+
```d2 strategy=inline darkScheme=false
286302
direction: right
287303
a -> b -> c -> d -> e
288304
```

packages/rehype-d2/package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
},
3535
"dependencies": {
3636
"@beoe/rehype-code-hook-img": "workspace:*",
37-
"@terrastruct/d2": "^0.1.21"
37+
"@terrastruct/d2": "^0.1.21",
38+
"async-memoize-one": "^1.1.8",
39+
"tinyglobby": "^0.2.10"
3840
},
3941
"devDependencies": {
4042
"@types/hast": "^3.0.4",

packages/rehype-d2/src/d2.ts

+26-2
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,40 @@
11
// @ts-ignore https://github.com/terrastruct/d2/issues/2286
22
import { D2 } from "@terrastruct/d2";
3+
import { glob, GlobOptions } from "tinyglobby";
4+
// @ts-expect-error
5+
import memoizeOne from "async-memoize-one";
6+
import fs from "node:fs/promises";
37

48
export type D2Options = {
59
layout?: "dagre" | "elk";
610
sketch?: boolean;
711
themeID?: number;
812
graphFormat?: "graphology" | "dagre";
13+
shared?: string | string[] | GlobOptions;
914
};
1015

16+
const mGlob = memoizeOne(async (x: string | string[] | GlobOptions) => {
17+
// @ts-expect-error
18+
const paths = await glob(x);
19+
const result: Record<string, string> = Object.create(null);
20+
// probably not the best way to do it, but for small number of files should be ok
21+
await Promise.all(
22+
paths.map((path) =>
23+
fs
24+
.readFile(path, { encoding: "utf-8" })
25+
.then((content) => (result[path] = content))
26+
)
27+
);
28+
return result;
29+
});
30+
1131
export async function d2(code: string, options: D2Options) {
1232
const d2Instance = new D2();
13-
const result = await d2Instance.compile(code, options);
33+
34+
const fs: Record<string, string> = options.shared
35+
? { ...(await mGlob(options.shared)), index: code }
36+
: { index: code };
37+
const result = await d2Instance.compile({ fs }, options);
1438

1539
let data;
1640
if (options.graphFormat) {
@@ -62,6 +86,6 @@ export async function d2(code: string, options: D2Options) {
6286
}
6387
}
6488

65-
const svg = await d2Instance.render(result.diagram, options) as string;
89+
const svg = (await d2Instance.render(result.diagram, options)) as string;
6690
return { svg, data };
6791
}

pnpm-lock.yaml

+35
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)