@nu-appdev/northwestern-starlight-theme 1.4.0 → 1.5.1
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/CHANGELOG.md +35 -1
- package/README.md +8 -12
- package/config.ts +343 -0
- package/dist/config.d.ts +99 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/expressive-code.d.ts +21 -0
- package/dist/expressive-code.d.ts.map +1 -0
- package/dist/index.d.ts +123 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/legacy-html-redirects.d.ts +72 -0
- package/dist/legacy-html-redirects.d.ts.map +1 -0
- package/dist/mermaid.d.ts +97 -0
- package/dist/mermaid.d.ts.map +1 -0
- package/dist/src/config-schema.d.ts +161 -0
- package/dist/src/config-schema.d.ts.map +1 -0
- package/dist/src/rehype-table-scroll.d.ts +10 -0
- package/dist/src/rehype-table-scroll.d.ts.map +1 -0
- package/expressive-code.ts +35 -0
- package/index.ts +55 -44
- package/legacy-html-redirects.ts +168 -0
- package/mermaid.ts +22 -12
- package/package.json +26 -8
- package/src/config-schema.ts +285 -0
- package/src/og/endpoint.ts +49 -39
- package/src/og/render.ts +260 -0
- package/src/rehype-table-scroll.ts +7 -0
- package/src/styles/content.css +18 -17
- package/src/styles/typography.css +2 -2
- package/src/virtual.d.ts +1 -0
- package/expressive-code.mjs +0 -18
package/src/og/endpoint.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { getCollection } from "astro:content";
|
|
2
2
|
import config from "virtual:northwestern-theme/config";
|
|
3
|
-
import {
|
|
3
|
+
import { renderOGImage } from "./render";
|
|
4
4
|
|
|
5
5
|
const siteTitle = config.ogImage.siteTitle;
|
|
6
6
|
const logoPath = config.ogImage.logoPath;
|
|
7
|
+
const resvgWasmPath = config.ogImage.resvgWasmPath;
|
|
7
8
|
const docs = await getCollection("docs");
|
|
8
9
|
let changelogs: typeof docs = [];
|
|
9
10
|
try {
|
|
@@ -11,43 +12,52 @@ try {
|
|
|
11
12
|
} catch {}
|
|
12
13
|
const pages = Object.fromEntries([...docs, ...changelogs].map((entry) => [entry.id, entry]));
|
|
13
14
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
15
|
+
function getImageOptions(path: string, page: (typeof docs)[number]) {
|
|
16
|
+
const isIndex = path === "index";
|
|
17
|
+
const isChangelogVersion = path.startsWith("changelog/version/");
|
|
18
|
+
const title = isIndex ? siteTitle : isChangelogVersion ? `Changelog\n${page.data.title}` : page.data.title;
|
|
19
|
+
return {
|
|
20
|
+
resvgWasmPath,
|
|
21
|
+
title,
|
|
22
|
+
description: page.data.description,
|
|
23
|
+
logo: { path: logoPath, size: [80] as [number] },
|
|
24
|
+
bgGradient: [[64, 31, 104]] as [number, number, number][],
|
|
25
|
+
padding: [60, 220] as [number, number],
|
|
26
|
+
border: {
|
|
27
|
+
color: [164, 149, 195] as [number, number, number],
|
|
28
|
+
width: 12,
|
|
29
|
+
},
|
|
30
|
+
font: {
|
|
31
|
+
title: {
|
|
32
|
+
families: ["Poppins"],
|
|
33
|
+
weight: "Bold" as const,
|
|
34
|
+
size: isChangelogVersion ? 64 : 56,
|
|
35
|
+
lineHeight: 1.3,
|
|
36
|
+
color: [255, 255, 255] as [number, number, number],
|
|
31
37
|
},
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
lineHeight: 1.3,
|
|
38
|
-
color: [255, 255, 255],
|
|
39
|
-
},
|
|
40
|
-
description: {
|
|
41
|
-
families: ["Akkurat Pro"],
|
|
42
|
-
size: 28,
|
|
43
|
-
lineHeight: 1.5,
|
|
44
|
-
color: [182, 172, 209],
|
|
45
|
-
},
|
|
38
|
+
description: {
|
|
39
|
+
families: ["Akkurat Pro"],
|
|
40
|
+
size: 32,
|
|
41
|
+
lineHeight: 1.5,
|
|
42
|
+
color: [182, 172, 209] as [number, number, number],
|
|
46
43
|
},
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
}
|
|
44
|
+
},
|
|
45
|
+
fonts: [
|
|
46
|
+
"https://common.northwestern.edu/v8/css/fonts/Poppins-Bold.woff",
|
|
47
|
+
"https://common.northwestern.edu/v8/css/fonts/AkkuratProRegular.woff",
|
|
48
|
+
],
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export function getStaticPaths() {
|
|
53
|
+
return Object.entries(pages).map(([pagePath, page]) => ({
|
|
54
|
+
params: { slug: `${pagePath}.png` },
|
|
55
|
+
props: { imageOptions: getImageOptions(pagePath, page) },
|
|
56
|
+
}));
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export async function GET({ props }: { props: { imageOptions: ReturnType<typeof getImageOptions> } }) {
|
|
60
|
+
return new Response(await renderOGImage(props.imageOptions), {
|
|
61
|
+
headers: { "Content-Type": "image/png" },
|
|
62
|
+
});
|
|
63
|
+
}
|
package/src/og/render.ts
ADDED
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
import fs from "node:fs/promises";
|
|
2
|
+
import { initWasm, Resvg } from "@resvg/resvg-wasm";
|
|
3
|
+
import satori from "satori";
|
|
4
|
+
|
|
5
|
+
type RGBColor = [r: number, g: number, b: number];
|
|
6
|
+
type FontWeight = string;
|
|
7
|
+
|
|
8
|
+
interface FontConfig {
|
|
9
|
+
color?: RGBColor;
|
|
10
|
+
size?: number;
|
|
11
|
+
weight?: FontWeight;
|
|
12
|
+
lineHeight?: number;
|
|
13
|
+
families?: string[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface OGImageOptions {
|
|
17
|
+
resvgWasmPath: string;
|
|
18
|
+
title: string;
|
|
19
|
+
description?: string;
|
|
20
|
+
logo?: {
|
|
21
|
+
path: string;
|
|
22
|
+
size?: [width?: number, height?: number];
|
|
23
|
+
};
|
|
24
|
+
bgGradient?: RGBColor[];
|
|
25
|
+
border?: {
|
|
26
|
+
color?: RGBColor;
|
|
27
|
+
width?: number;
|
|
28
|
+
};
|
|
29
|
+
padding?: number | [vertical: number, horizontal: number];
|
|
30
|
+
font?: {
|
|
31
|
+
title?: FontConfig;
|
|
32
|
+
description?: FontConfig;
|
|
33
|
+
};
|
|
34
|
+
fonts?: string[];
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const [width, height] = [1200, 630];
|
|
38
|
+
|
|
39
|
+
let wasmInitialized = false;
|
|
40
|
+
async function ensureWasm(wasmPath: string) {
|
|
41
|
+
if (wasmInitialized) return;
|
|
42
|
+
await initWasm(fs.readFile(wasmPath));
|
|
43
|
+
wasmInitialized = true;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const fontWeightMap: Record<string, number> = {
|
|
47
|
+
Normal: 400,
|
|
48
|
+
Bold: 700,
|
|
49
|
+
ExtraBold: 800,
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
function toFontWeight(weight: string): number {
|
|
53
|
+
return fontWeightMap[weight] ?? 400;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function decodeText(text: string) {
|
|
57
|
+
return text
|
|
58
|
+
.replaceAll("&", "&")
|
|
59
|
+
.replaceAll("<", "<")
|
|
60
|
+
.replaceAll(">", ">")
|
|
61
|
+
.replaceAll(""", '"')
|
|
62
|
+
.replaceAll("'", "'");
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
function rgbToCSS(rgb: RGBColor): string {
|
|
66
|
+
return `rgb(${rgb[0]}, ${rgb[1]}, ${rgb[2]})`;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const fontCache = new Map<string, ArrayBuffer>();
|
|
70
|
+
|
|
71
|
+
/**
|
|
72
|
+
* Load a font from disk or a remote URL for OG image rendering.
|
|
73
|
+
*
|
|
74
|
+
* @internal
|
|
75
|
+
*/
|
|
76
|
+
export async function loadFont(url: string): Promise<ArrayBuffer> {
|
|
77
|
+
const cached = fontCache.get(url);
|
|
78
|
+
if (cached) return cached;
|
|
79
|
+
let buffer: ArrayBuffer;
|
|
80
|
+
if (/^https?:\/\//.test(url)) {
|
|
81
|
+
let response: Response;
|
|
82
|
+
try {
|
|
83
|
+
response = await fetch(url);
|
|
84
|
+
} catch (error) {
|
|
85
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
86
|
+
throw new Error(`[northwestern-starlight-theme] Failed to fetch OG font from ${url}: ${message}`, {
|
|
87
|
+
cause: error,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (!response.ok) {
|
|
92
|
+
const statusText = response.statusText ? ` ${response.statusText}` : "";
|
|
93
|
+
throw new Error(
|
|
94
|
+
`[northwestern-starlight-theme] Failed to fetch OG font from ${url}: HTTP ${response.status}${statusText}`,
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
buffer = await response.arrayBuffer();
|
|
99
|
+
} else {
|
|
100
|
+
const file = await fs.readFile(url);
|
|
101
|
+
buffer = file.buffer.slice(file.byteOffset, file.byteOffset + file.byteLength);
|
|
102
|
+
}
|
|
103
|
+
fontCache.set(url, buffer);
|
|
104
|
+
return buffer;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
const logoCache = new Map<string, string>();
|
|
108
|
+
|
|
109
|
+
async function loadLogoDataURL(filePath: string): Promise<string> {
|
|
110
|
+
const cached = logoCache.get(filePath);
|
|
111
|
+
if (cached) return cached;
|
|
112
|
+
const buffer = await fs.readFile(filePath);
|
|
113
|
+
const ext = filePath.split(".").pop()?.toLowerCase() ?? "png";
|
|
114
|
+
const mime = ext === "svg" ? "image/svg+xml" : `image/${ext}`;
|
|
115
|
+
const dataURL = `data:${mime};base64,${buffer.toString("base64")}`;
|
|
116
|
+
logoCache.set(filePath, dataURL);
|
|
117
|
+
return dataURL;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export async function renderOGImage({
|
|
121
|
+
resvgWasmPath,
|
|
122
|
+
title,
|
|
123
|
+
description = "",
|
|
124
|
+
bgGradient = [[0, 0, 0]],
|
|
125
|
+
border: borderConfig = {},
|
|
126
|
+
padding: rawPadding = 80,
|
|
127
|
+
logo,
|
|
128
|
+
font: fontConfig = {},
|
|
129
|
+
fonts: fontUrls = ["https://api.fontsource.org/v1/fonts/noto-sans/latin-400-normal.ttf"],
|
|
130
|
+
}: OGImageOptions) {
|
|
131
|
+
const decodedTitle = decodeText(title);
|
|
132
|
+
const decodedDescription = description ? decodeText(description) : "";
|
|
133
|
+
|
|
134
|
+
const [vPad, hPad] = Array.isArray(rawPadding) ? rawPadding : [rawPadding, rawPadding];
|
|
135
|
+
const borderColor = borderConfig.color ?? [255, 255, 255];
|
|
136
|
+
const borderWidth = borderConfig.width ?? 0;
|
|
137
|
+
|
|
138
|
+
const titleFont = {
|
|
139
|
+
families: fontConfig.title?.families ?? ["Noto Sans"],
|
|
140
|
+
size: fontConfig.title?.size ?? 70,
|
|
141
|
+
weight: fontConfig.title?.weight ?? "Normal",
|
|
142
|
+
lineHeight: fontConfig.title?.lineHeight ?? 1,
|
|
143
|
+
color: fontConfig.title?.color ?? ([255, 255, 255] as RGBColor),
|
|
144
|
+
};
|
|
145
|
+
const descFont = {
|
|
146
|
+
families: fontConfig.description?.families ?? ["Noto Sans"],
|
|
147
|
+
size: fontConfig.description?.size ?? 40,
|
|
148
|
+
weight: fontConfig.description?.weight ?? "Normal",
|
|
149
|
+
lineHeight: fontConfig.description?.lineHeight ?? 1.3,
|
|
150
|
+
color: fontConfig.description?.color ?? ([255, 255, 255] as RGBColor),
|
|
151
|
+
};
|
|
152
|
+
|
|
153
|
+
const fontData = await Promise.all(fontUrls.map(loadFont));
|
|
154
|
+
const satoriFont = fontUrls.map((url, i) => {
|
|
155
|
+
const name = url.includes("Poppins") ? "Poppins" : url.includes("Akkurat") ? "Akkurat Pro" : "Noto Sans";
|
|
156
|
+
return { name, data: fontData[i], weight: 400 as const };
|
|
157
|
+
});
|
|
158
|
+
|
|
159
|
+
const logoDataURL = logo ? await loadLogoDataURL(logo.path) : undefined;
|
|
160
|
+
const logoW = logo?.size?.[0] ?? 60;
|
|
161
|
+
const logoH = logo?.size?.[1] ?? logoW;
|
|
162
|
+
|
|
163
|
+
const bgStart = rgbToCSS(bgGradient[0]);
|
|
164
|
+
const bgEnd = bgGradient.length > 1 ? rgbToCSS(bgGradient[bgGradient.length - 1]) : bgStart;
|
|
165
|
+
|
|
166
|
+
const element = {
|
|
167
|
+
type: "div",
|
|
168
|
+
props: {
|
|
169
|
+
style: {
|
|
170
|
+
display: "flex",
|
|
171
|
+
flexDirection: "column",
|
|
172
|
+
alignItems: "center",
|
|
173
|
+
justifyContent: "center",
|
|
174
|
+
width: "100%",
|
|
175
|
+
height: "100%",
|
|
176
|
+
background: `linear-gradient(to bottom, ${bgStart}, ${bgEnd})`,
|
|
177
|
+
padding: `${vPad}px ${hPad}px`,
|
|
178
|
+
paddingLeft: `${hPad + borderWidth}px`,
|
|
179
|
+
borderLeft: borderWidth ? `${borderWidth}px solid ${rgbToCSS(borderColor)}` : undefined,
|
|
180
|
+
},
|
|
181
|
+
children: [
|
|
182
|
+
...(logoDataURL
|
|
183
|
+
? [
|
|
184
|
+
{
|
|
185
|
+
type: "img",
|
|
186
|
+
props: {
|
|
187
|
+
src: logoDataURL,
|
|
188
|
+
width: logoW,
|
|
189
|
+
height: logoH,
|
|
190
|
+
style: { marginBottom: "32px" },
|
|
191
|
+
},
|
|
192
|
+
},
|
|
193
|
+
]
|
|
194
|
+
: []),
|
|
195
|
+
{
|
|
196
|
+
type: "div",
|
|
197
|
+
props: {
|
|
198
|
+
style: {
|
|
199
|
+
display: "flex",
|
|
200
|
+
flexDirection: "column",
|
|
201
|
+
alignItems: "center",
|
|
202
|
+
justifyContent: "center",
|
|
203
|
+
textAlign: "center",
|
|
204
|
+
width: "100%",
|
|
205
|
+
},
|
|
206
|
+
children: [
|
|
207
|
+
{
|
|
208
|
+
type: "div",
|
|
209
|
+
props: {
|
|
210
|
+
style: {
|
|
211
|
+
fontFamily: titleFont.families[0],
|
|
212
|
+
fontSize: `${titleFont.size}px`,
|
|
213
|
+
fontWeight: toFontWeight(titleFont.weight),
|
|
214
|
+
lineHeight: titleFont.lineHeight,
|
|
215
|
+
color: rgbToCSS(titleFont.color),
|
|
216
|
+
whiteSpace: "pre-wrap",
|
|
217
|
+
textAlign: "center",
|
|
218
|
+
},
|
|
219
|
+
children: decodedTitle,
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
...(decodedDescription
|
|
223
|
+
? [
|
|
224
|
+
{
|
|
225
|
+
type: "div",
|
|
226
|
+
props: {
|
|
227
|
+
style: {
|
|
228
|
+
fontFamily: descFont.families[0],
|
|
229
|
+
fontSize: `${descFont.size}px`,
|
|
230
|
+
fontWeight: toFontWeight(descFont.weight),
|
|
231
|
+
lineHeight: descFont.lineHeight,
|
|
232
|
+
color: rgbToCSS(descFont.color),
|
|
233
|
+
marginTop: "24px",
|
|
234
|
+
textAlign: "center",
|
|
235
|
+
maxWidth: "560px",
|
|
236
|
+
},
|
|
237
|
+
children: decodedDescription,
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
]
|
|
241
|
+
: []),
|
|
242
|
+
],
|
|
243
|
+
},
|
|
244
|
+
},
|
|
245
|
+
],
|
|
246
|
+
},
|
|
247
|
+
};
|
|
248
|
+
|
|
249
|
+
const svg = await satori(element as any, {
|
|
250
|
+
width,
|
|
251
|
+
height,
|
|
252
|
+
fonts: satoriFont,
|
|
253
|
+
});
|
|
254
|
+
await ensureWasm(resvgWasmPath);
|
|
255
|
+
const resvg = new Resvg(svg, {
|
|
256
|
+
fitTo: { mode: "width", value: width },
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
return Buffer.from(resvg.render().asPng());
|
|
260
|
+
}
|
|
@@ -7,6 +7,11 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { Element, Nodes, Root } from "hast";
|
|
9
9
|
|
|
10
|
+
function isScrollWrapper(node: Element): boolean {
|
|
11
|
+
const classes = node.properties?.className;
|
|
12
|
+
return Array.isArray(classes) && classes.includes("nu-table-scroll");
|
|
13
|
+
}
|
|
14
|
+
|
|
10
15
|
function walk(node: Nodes) {
|
|
11
16
|
if (!("children" in node)) return;
|
|
12
17
|
for (let i = 0; i < node.children.length; i++) {
|
|
@@ -24,6 +29,8 @@ function walk(node: Nodes) {
|
|
|
24
29
|
children: [child as Element],
|
|
25
30
|
};
|
|
26
31
|
node.children[i] = wrapper;
|
|
32
|
+
} else if (child.type === "element" && isScrollWrapper(child as Element)) {
|
|
33
|
+
// Already wrapped — skip to avoid double-wrapping
|
|
27
34
|
} else {
|
|
28
35
|
walk(child as Nodes);
|
|
29
36
|
}
|
package/src/styles/content.css
CHANGED
|
@@ -178,7 +178,8 @@
|
|
|
178
178
|
|
|
179
179
|
.starlight-aside {
|
|
180
180
|
padding: 1rem 1.25rem;
|
|
181
|
-
border:
|
|
181
|
+
border: none !important;
|
|
182
|
+
border-inline-start: 3px solid var(--sl-color-asides-border) !important;
|
|
182
183
|
}
|
|
183
184
|
|
|
184
185
|
.starlight-aside__title {
|
|
@@ -195,50 +196,50 @@
|
|
|
195
196
|
|
|
196
197
|
.starlight-aside--note {
|
|
197
198
|
--sl-color-asides-text-accent: color-mix(in srgb, var(--nu-blue), black 30%);
|
|
198
|
-
--sl-color-asides-border:
|
|
199
|
-
background-color: rgb(80 145 205 /
|
|
199
|
+
--sl-color-asides-border: #5091cd;
|
|
200
|
+
background-color: rgb(80 145 205 / 8%) !important;
|
|
200
201
|
}
|
|
201
202
|
|
|
202
203
|
.starlight-aside--tip {
|
|
203
204
|
--sl-color-asides-text-accent: color-mix(in srgb, var(--nu-dark-green), black 18%);
|
|
204
|
-
--sl-color-asides-border:
|
|
205
|
-
background-color: rgb(0 134 86 /
|
|
205
|
+
--sl-color-asides-border: #008656;
|
|
206
|
+
background-color: rgb(0 134 86 / 8%) !important;
|
|
206
207
|
}
|
|
207
208
|
|
|
208
209
|
.starlight-aside--caution {
|
|
209
210
|
--sl-color-asides-text-accent: color-mix(in srgb, var(--nu-dark-gold), black 24%);
|
|
210
|
-
--sl-color-asides-border:
|
|
211
|
-
background-color: rgb(255 197 32 /
|
|
211
|
+
--sl-color-asides-border: #ffc520;
|
|
212
|
+
background-color: rgb(255 197 32 / 10%) !important;
|
|
212
213
|
}
|
|
213
214
|
|
|
214
215
|
.starlight-aside--danger {
|
|
215
216
|
--sl-color-asides-text-accent: color-mix(in srgb, var(--nu-dark-orange), black 18%);
|
|
216
|
-
--sl-color-asides-border:
|
|
217
|
-
background-color: rgb(239 85 63 /
|
|
217
|
+
--sl-color-asides-border: #ef553f;
|
|
218
|
+
background-color: rgb(239 85 63 / 8%) !important;
|
|
218
219
|
}
|
|
219
220
|
|
|
220
221
|
:root:not([data-theme="light"]) .starlight-aside--note {
|
|
221
222
|
--sl-color-asides-text-accent: #93c5fd;
|
|
222
|
-
--sl-color-asides-border:
|
|
223
|
-
background-color: rgb(80 145 205 /
|
|
223
|
+
--sl-color-asides-border: #93c5fd;
|
|
224
|
+
background-color: rgb(80 145 205 / 10%) !important;
|
|
224
225
|
}
|
|
225
226
|
|
|
226
227
|
:root:not([data-theme="light"]) .starlight-aside--tip {
|
|
227
228
|
--sl-color-asides-text-accent: #6ee7b7;
|
|
228
|
-
--sl-color-asides-border:
|
|
229
|
-
background-color: rgb(0 134 86 /
|
|
229
|
+
--sl-color-asides-border: #6ee7b7;
|
|
230
|
+
background-color: rgb(0 134 86 / 10%) !important;
|
|
230
231
|
}
|
|
231
232
|
|
|
232
233
|
:root:not([data-theme="light"]) .starlight-aside--caution {
|
|
233
234
|
--sl-color-asides-text-accent: #fde68a;
|
|
234
|
-
--sl-color-asides-border:
|
|
235
|
-
background-color: rgb(255 197 32 /
|
|
235
|
+
--sl-color-asides-border: #fde68a;
|
|
236
|
+
background-color: rgb(255 197 32 / 12%) !important;
|
|
236
237
|
}
|
|
237
238
|
|
|
238
239
|
:root:not([data-theme="light"]) .starlight-aside--danger {
|
|
239
240
|
--sl-color-asides-text-accent: #fca5a5;
|
|
240
|
-
--sl-color-asides-border:
|
|
241
|
-
background-color: rgb(239 85 63 /
|
|
241
|
+
--sl-color-asides-border: #fca5a5;
|
|
242
|
+
background-color: rgb(239 85 63 / 10%) !important;
|
|
242
243
|
}
|
|
243
244
|
|
|
244
245
|
.sl-link-button {
|
package/src/virtual.d.ts
CHANGED
package/expressive-code.mjs
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { pluginLineNumbers } from "@expressive-code/plugin-line-numbers";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @param {import("@astrojs/starlight/expressive-code").StarlightExpressiveCodeOptions} [config]
|
|
5
|
-
* @returns {import("@astrojs/starlight/expressive-code").StarlightExpressiveCodeOptions}
|
|
6
|
-
*/
|
|
7
|
-
export function northwesternExpressiveCode(config = {}) {
|
|
8
|
-
const { defaultProps, plugins, ...rest } = config;
|
|
9
|
-
|
|
10
|
-
return {
|
|
11
|
-
...rest,
|
|
12
|
-
plugins: [pluginLineNumbers(), ...(plugins ?? [])],
|
|
13
|
-
defaultProps: {
|
|
14
|
-
showLineNumbers: false,
|
|
15
|
-
...(defaultProps ?? {}),
|
|
16
|
-
},
|
|
17
|
-
};
|
|
18
|
-
}
|