@void/md 1.0.3 → 1.1.11

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
@@ -475,7 +475,7 @@ export function useFrontmatter() { return useContext(FrontmatterContext) ?? {};
475
475
  islandId
476
476
  };
477
477
  });
478
- const { compile } = await import("./compile-BN4Az3Z3.mjs");
478
+ const { compile } = await import("./compile-B0tLGZa4.mjs");
479
479
  const result = await compile(body, { shiki: options?.shiki });
480
480
  if (adapter === "vue") return {
481
481
  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.0.3",
3
+ "version": "1.1.11",
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.0.3"
56
+ "void": "1.1.11"
57
57
  },
58
58
  "peerDependencies": {
59
59
  "vite": "^8.0.0",
60
- "void": "1.0.3"
60
+ "void": "1.1.11"
61
61
  },
62
62
  "scripts": {
63
63
  "build": "vp pack",