@void/md 1.1.0 → 1.1.12

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.
@@ -162,13 +162,24 @@ function extractLang(info) {
162
162
  return /^[a-zA-Z0-9-_]+/.exec(info)?.[0].replace(/-vue$/, "").replace(/^vue-html$/, "template").replace(/^ansi$/, "") || "";
163
163
  }
164
164
  /**
165
+ * Copies the code next to a clicked copy button, without removed diff lines
166
+ * and without the empty last line that Shiki adds.
167
+ * Markdown pages are island pages and always load as full documents, so this
168
+ * classic inline script runs once per page load and adds one delegated
169
+ * listener. The body must not contain `<`, so neither island tag matching nor
170
+ * the HTML parser sees a tag in it.
171
+ */
172
+ const CODE_COPY_SCRIPT = "<script>window.__voidMdCopy||(window.__voidMdCopy=1,document.addEventListener(\"click\",e=>{const b=e.target instanceof Element&&e.target.closest(\"div[class*='language-']>button.copy\"),p=b&&b.parentElement.querySelector(\"pre\");if(!p||!navigator.clipboard)return;const t=Array.from(p.querySelectorAll(\".line:not(.diff.remove)\"),l=>l.textContent);t[t.length-1]===\"\"&&t.pop();navigator.clipboard.writeText(t.join(\"\\n\")).then(()=>{b.classList.add(\"copied\");setTimeout(()=>b.classList.remove(\"copied\"),2e3)},()=>{})}))<\/script>";
173
+ /**
165
174
  * Wraps fenced code blocks with a language label and copy button.
175
+ * Sets `env.codeCopy` so the page gets {@link CODE_COPY_SCRIPT}.
166
176
  * Ported from VitePress.
167
177
  */
168
178
  function preWrapperPlugin(md) {
169
179
  const fence = md.renderer.rules.fence;
170
180
  md.renderer.rules.fence = async (...args) => {
171
- const [tokens, idx] = args;
181
+ const [tokens, idx, , env] = args;
182
+ env.codeCopy = true;
172
183
  const token = tokens[idx];
173
184
  token.info = token.info.replace(/\[.*\]/, "");
174
185
  const active = / active( |$)/.test(token.info) ? " active" : "";
@@ -290,11 +301,14 @@ async function compile(source, options) {
290
301
  const env = {};
291
302
  const tokens = compiler.parse(content, env);
292
303
  const headings = extractHeadings(tokens);
304
+ let html = await compiler.renderer.renderAsync(tokens, compiler.options, env);
305
+ if (env.codeCopy) html += CODE_COPY_SCRIPT;
306
+ const title = frontmatter.title ?? headings.find((heading) => heading.depth === 1)?.text ?? "";
293
307
  return {
294
- html: await compiler.renderer.renderAsync(tokens, compiler.options, env),
308
+ html,
295
309
  frontmatter,
296
310
  headings,
297
- title: frontmatter.title ?? headings.find((heading) => heading.depth === 1)?.text ?? ""
311
+ title
298
312
  };
299
313
  }
300
314
  //#endregion
package/dist/index.d.mts CHANGED
@@ -1,3 +1,3 @@
1
1
  import { FrontmatterContext, setFrontmatter, useFrontmatter } from "./runtime/index.mjs";
2
- import { n as MdPage } from "./plugin-DcZ5SZxg.mjs";
2
+ import { n as MdPage } from "./plugin-ieYHo6qp.mjs";
3
3
  export { FrontmatterContext, type MdPage, setFrontmatter, useFrontmatter };
@@ -17,6 +17,11 @@ type CompileOptions = Readonly<{
17
17
  light: string;
18
18
  dark: string;
19
19
  };
20
+ /**
21
+ * @deprecated Has no effect. Code block languages load on demand from
22
+ * Shiki's bundled languages. Remove this option. Removed in the next major
23
+ * version.
24
+ */
20
25
  langs?: ReadonlyArray<string>;
21
26
  };
22
27
  }>;
package/dist/plugin.d.mts CHANGED
@@ -1,2 +1,2 @@
1
- import { a as ScriptExtraction, i as IslandImport, n as MdPage, o as CompileOptions, r as voidMarkdown, s as CompileResult, t as MarkdownOptions } from "./plugin-DcZ5SZxg.mjs";
1
+ import { a as ScriptExtraction, i as IslandImport, n as MdPage, o as CompileOptions, r as voidMarkdown, s as CompileResult, t as MarkdownOptions } from "./plugin-ieYHo6qp.mjs";
2
2
  export { type CompileOptions, type CompileResult, type IslandImport, MarkdownOptions, MdPage, type ScriptExtraction, voidMarkdown };
package/dist/plugin.mjs CHANGED
@@ -438,8 +438,9 @@ import { inject } from "vue";
438
438
  export function useFrontmatter() { return inject("__void_frontmatter", {}); }
439
439
  `;
440
440
  if (adapter === "react") return `
441
- import { createContext, useContext } from "react";
442
- export const FrontmatterContext = createContext({});
441
+ import { useContext } from "react";
442
+ import { FrontmatterContext } from "@void/react";
443
+ export { FrontmatterContext };
443
444
  export function useFrontmatter() { return useContext(FrontmatterContext) ?? {}; }
444
445
  `;
445
446
  if (adapter === "svelte") return `
@@ -449,8 +450,9 @@ export function setFrontmatter(frontmatter) { setContext(FRONTMATTER_KEY, frontm
449
450
  export function useFrontmatter() { return getContext(FRONTMATTER_KEY) ?? {}; }
450
451
  `;
451
452
  if (adapter === "solid") return `
452
- import { createContext, useContext } from "solid-js";
453
- export const FrontmatterContext = createContext({});
453
+ import { useContext } from "solid-js";
454
+ import { FrontmatterContext } from "@void/solid";
455
+ export { FrontmatterContext };
454
456
  export function useFrontmatter() { return useContext(FrontmatterContext) ?? {}; }
455
457
  `;
456
458
  throw new Error("void-md: Adapter is not initialized.");
@@ -475,7 +477,7 @@ export function useFrontmatter() { return useContext(FrontmatterContext) ?? {};
475
477
  islandId
476
478
  };
477
479
  });
478
- const { compile } = await import("./compile-BN4Az3Z3.mjs");
480
+ const { compile } = await import("./compile-B0tLGZa4.mjs");
479
481
  const result = await compile(body, { shiki: options?.shiki });
480
482
  if (adapter === "vue") return {
481
483
  code: emitVueComponent(result, islands),
@@ -1,5 +1,15 @@
1
1
  //#region src/runtime/index.d.ts
2
2
  export declare function useFrontmatter(): Record<string, unknown>;
3
+ /**
4
+ * @deprecated Internal to generated Markdown components and not available with
5
+ * every framework adapter. Use `useFrontmatter()`. Removed in the next major
6
+ * version.
7
+ */
3
8
  export declare const FrontmatterContext: Record<string, unknown> | null;
9
+ /**
10
+ * @deprecated Internal to generated Markdown components and not available with
11
+ * every framework adapter. Use `useFrontmatter()`. Removed in the next major
12
+ * version.
13
+ */
4
14
  export declare function setFrontmatter(_frontmatter: Record<string, unknown>): void;
5
15
  //#endregion
@@ -2,7 +2,17 @@
2
2
  function useFrontmatter() {
3
3
  return {};
4
4
  }
5
+ /**
6
+ * @deprecated Internal to generated Markdown components and not available with
7
+ * every framework adapter. Use `useFrontmatter()`. Removed in the next major
8
+ * version.
9
+ */
5
10
  const FrontmatterContext = null;
11
+ /**
12
+ * @deprecated Internal to generated Markdown components and not available with
13
+ * every framework adapter. Use `useFrontmatter()`. Removed in the next major
14
+ * version.
15
+ */
6
16
  function setFrontmatter(_frontmatter) {}
7
17
  //#endregion
8
18
  export { FrontmatterContext, setFrontmatter, useFrontmatter };
@@ -75,6 +75,14 @@
75
75
  center / 60% no-repeat;
76
76
  }
77
77
 
78
+ .void-md div[class*='language-'] .copy.copied {
79
+ opacity: 1;
80
+ }
81
+
82
+ .void-md div[class*='language-'] .copy.copied::before {
83
+ mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='currentColor' stroke-width='2'%3E%3Cpath d='M20 6 9 17l-5-5'/%3E%3C/svg%3E");
84
+ }
85
+
78
86
  /* Shiki dual theme — keep inline light colors, only swap in dark mode */
79
87
  .void-md pre.shiki.shiki-themes {
80
88
  background-color: var(--shiki-light-bg, #fff) !important;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@void/md",
3
- "version": "1.1.0",
3
+ "version": "1.1.12",
4
4
  "description": "Markdown pages with layouts and interactive islands for Void.",
5
5
  "homepage": "https://void.cloud",
6
6
  "bugs": {
@@ -53,11 +53,11 @@
53
53
  "@types/node": "^26.6.5",
54
54
  "vite": "npm:@voidzero-dev/vite-plus-core@1.2.0",
55
55
  "vite-plus": "1.2.0",
56
- "void": "1.1.0"
56
+ "void": "1.1.12"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "vite": "^8.0.0",
60
- "void": "1.1.0"
60
+ "void": "1.1.12"
61
61
  },
62
62
  "scripts": {
63
63
  "build": "vp pack",