@mirrordown/core 0.1.1 → 0.1.3

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 CHANGED
@@ -1,6 +1,20 @@
1
1
  # Changelog
2
2
 
3
3
 
4
+
5
+
6
+ ## 0.1.3
7
+ <sub>2026-11-02</sub>
8
+
9
+ - *(patch)*
10
+ Add the copy-code plugin set: every fenced and indented code block gets a copy button, in its `<pre>` after the `<code>`, with no wrapper element. The button is an invoker command (`command="--copy"`) aimed at the `<pre>`, which takes an id from a hash of its code (`code-<hash>`, with `-2`, `-3`… for repeats). Each package ships a small client script (`./client`) that copies the block's code, without the newline markdown ends it with, shows a check with "Copied!" in a pill beside it, as GitHub does, and announces it to screen readers; the buttons render `hidden` until it runs, so a page without it shows none. The `icons` and `text` options set the button's icon and text in each state. Write `nocopy` after the fence's language to leave a block without one; a host that highlights first can keep the meta in a `data-meta` attribute on the `<pre>`. Where CSS anchor positioning with `anchor-scope` is supported, the button sits in the block's top corner and shows on hover or focus. The markdown-it, remark and Sätteri plugins emit identical HTML.
11
+
12
+ ## 0.1.2
13
+ <sub>2026-10-28</sub>
14
+
15
+ - *(patch)*
16
+ Add the tab-icons plugin set, a port of vitepress-plugin-group-icons for Mirrordown's tabs: each tab label gets the icon its text matches (a keyword such as `npm`, `pnpm` or `vite` as a whole word, the longest winning, else a file name or extension such as `package.json` or `.ts`), or the one a `[!keyword]` marker at its start names; `[!none]` turns matching off for one label. The icon is an inline `<svg class="markdown-tab-icon" aria-hidden="true">` before the label's text, and the marker comes out of the label and its panel's `aria-label`. It ships group-icons' built-in icons (from VSCode Icons and SVG Logos); the `icons` option adds or replaces them, with light and dark pairs, and `builtin` and `match` turn the built-in icons and matching off. The markdown-it, remark and Sätteri plugins emit identical HTML.
17
+
4
18
  ## 0.1.1
5
19
  <sub>2026-10-28</sub>
6
20
 
package/dist/index.d.mts CHANGED
@@ -388,5 +388,43 @@ export declare const figureProperties: (author?: Properties) => Properties;
388
388
  * Wrap each captioned block of an mdast tree, with its caption, in a `figure` node (`hName: "figure"`, class `markdown-caption`) whose last child is a `figcaption` node. `source` is the document the tree was parsed from: caption lines are found, and placed, by their source lines.
389
389
  */
390
390
  export declare const processCaptions: (root: Root, source: string) => void;
391
- export type { AbbreviationPart, AlertOptions, AlertParagraph, AlertResolver, AlertType, DelimiterMarker, EditableTree, HastElementLike, HastLike, InlineSvgLimits, LineContainer, MermaidAttribute, PhrasingLike, Positioned, ReadAttributes, ScriptSyntax, SpanNodes, SpanTransform, StepsItemNode, StepsListNode, StepsTitleNode, TabsItemNode, TabsLabelNode, TabsListNode, TextLikeNode, TreeNode };
391
+ /** The copy button's class. */
392
+ export declare const COPY_CODE_CLASS = "markdown-copy-code";
393
+ /** The invoker command the button sends its code block. */
394
+ export declare const COPY_CODE_COMMAND = "--copy";
395
+ /** Whether a fence's meta, the info string after its language, turns its block's button off. */
396
+ export declare const copyCodeOptedOut: (meta: string | null | undefined) => boolean;
397
+ /** The text a block copies: its code with line endings normalized and without the newline that ends it. */
398
+ export declare const copyCodeText: (code: string) => string;
399
+ /**
400
+ * A document's code block ids, one per block in document order: `code-` and a hash of the block's text, so a block's id doesn't change when others are edited, with `-2`, `-3`… for repeats of one block. Create one per document.
401
+ */
402
+ export declare const copyCodeIds: () => ((text: string) => string);
403
+ /**
404
+ * A hast `<pre>` holding a code block, as markdown renders one: its only element child is a `<code>`. Returns the text the block copies and its fence's meta, or nothing for another `<pre>` or an empty block. The meta is the `<code>`'s, as remark and Sätteri keep it, or else the `<pre>`'s `data-meta` attribute, where a highlighter that rebuilds the block (such as Astro's Shiki) can keep it.
405
+ */
406
+ export declare const copyCodeBlock: (node: HastLike) => {
407
+ text: string;
408
+ meta: string | undefined;
409
+ } | undefined;
410
+ /** A copy button's states: before its block is copied, and for a moment after. */
411
+ type CopyCodeState = "copy" | "copied";
412
+ /** Options shared by the copy-code plugins for every engine. */
413
+ interface CopyCodeOptions {
414
+ /** The button's icon in each state, as SVG markup. An icon can be replaced but not removed, since it's all the button holds: an empty one keeps the default. Defaults: {@link COPY_CODE_ICONS}. */
415
+ icons?: Partial<Record<CopyCodeState, string>>;
416
+ /**
417
+ * Text shown beside the button in each state, and the button's accessible name; `null` or `""` shows none. Defaults: {@link COPY_CODE_TEXT}, none before copying and `Copied!` after. The copy text shows while the button is hovered or focused.
418
+ */
419
+ text?: Partial<Record<CopyCodeState, string | null>>;
420
+ }
421
+ /** The button's default icon in each state. */
422
+ export declare const COPY_CODE_ICONS: Record<CopyCodeState, string>;
423
+ /** The button's default text in each state, as GitHub shows it: none before copying, `Copied!` after. */
424
+ export declare const COPY_CODE_TEXT: Record<CopyCodeState, string>;
425
+ /**
426
+ * Builds a document's copy buttons under the plugin's options. A button is for the code block whose `<pre>` has the id, and goes in the `<pre>` after its `<code>`. It starts `hidden`: the client script shows it where it can copy, so a page without the script has no button that does nothing. Each state's icon and text are spans marked `data-state`, which the stylesheet shows by the button's `data-copied`; the client script names the copied button by its copied text.
427
+ */
428
+ export declare const createCopyCodeButton: (options?: CopyCodeOptions) => ((id: string) => string);
429
+ export type { AbbreviationPart, AlertOptions, AlertParagraph, AlertResolver, AlertType, CopyCodeOptions, CopyCodeState, DelimiterMarker, EditableTree, HastElementLike, HastLike, InlineSvgLimits, LineContainer, MermaidAttribute, PhrasingLike, Positioned, ReadAttributes, ScriptSyntax, SpanNodes, SpanTransform, StepsItemNode, StepsListNode, StepsTitleNode, TabsItemNode, TabsLabelNode, TabsListNode, TextLikeNode, TreeNode };
392
430
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/escapes.ts","../src/github-alerts/types.ts","../src/github-alerts/icons.ts","../src/github-alerts/index.ts","../src/spans.ts","../src/delimited.ts","../src/kbd.ts","../src/scripts.ts","../src/hast.ts","../src/abbr.ts","../src/steps.ts","../src/tabs.ts","../src/editable.ts","../src/cut-attributes.ts","../src/inline-svg.ts","../src/mermaid-pele.ts","../src/line-containers.ts","../src/caption.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/escapes.ts","../src/github-alerts/types.ts","../src/github-alerts/icons.ts","../src/github-alerts/index.ts","../src/spans.ts","../src/delimited.ts","../src/kbd.ts","../src/scripts.ts","../src/hast.ts","../src/abbr.ts","../src/steps.ts","../src/tabs.ts","../src/editable.ts","../src/cut-attributes.ts","../src/inline-svg.ts","../src/mermaid-pele.ts","../src/line-containers.ts","../src/caption.ts","../src/copy-code.ts"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ import { a as mermaidSource, i as mermaidIdPrefixes, n as mermaidDiagram, o as mermaidSvg, r as mermaidFailure, t as hastAttributes } from "./mermaid-pele-BMyyDozN.mjs";
1
2
  // src/escapes.ts
2
3
  const ASCII_PUNCTUATION = /^[!-/:-@[-`{-~]$/;
3
4
  const ENTITY = /^&(?:#\d+|#x[\da-f]+|[a-z][\da-z]*);/i;
@@ -112,24 +113,24 @@ const DEFAULT_TITLE = {
112
113
  quote: "Quote"
113
114
  };
114
115
  // src/github-alerts/icons.ts
115
- const icon = (path) => `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${path}</svg>`;
116
+ const icon$1 = (path) => `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${path}</svg>`;
116
117
  /** Inline SVG icon markup for each {@link AlertType}. */
117
118
  const ICONS = {
118
- note: icon("<path d=\"M12 20h9\"></path><path d=\"M16.376 3.622a1 1 0 0 1 3.002 3.002L7.368 18.635a2 2 0 0 1-.855.506l-2.872.838a.5.5 0 0 1-.62-.62l.838-2.872a2 2 0 0 1 .506-.854z\"></path>"),
119
- tip: icon("<path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\"></path><path d=\"M9 18h6\"></path><path d=\"M10 22h4\"></path>"),
120
- important: icon("<path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22z\"></path>"),
121
- warning: icon("<path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"></path><path d=\"M12 9v4\"></path><path d=\"M12 17h.01\"></path>"),
122
- caution: icon("<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><path d=\"m4.9 4.9 14.2 14.2\"></path><path d=\"M12 8v4\"></path><path d=\"M12 16h.01\"></path>"),
123
- abstract: icon("<rect width=\"8\" height=\"4\" x=\"8\" y=\"2\" rx=\"1\" ry=\"1\"></rect><path d=\"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\"></path><path d=\"M12 11h4\"></path><path d=\"M12 16h4\"></path><path d=\"M8 11h.01\"></path><path d=\"M8 16h.01\"></path>"),
124
- info: icon("<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><path d=\"M12 16v-4\"></path><path d=\"M12 8h.01\"></path>"),
125
- todo: icon("<path d=\"M8 6h13\"></path><path d=\"M8 12h13\"></path><path d=\"M8 18h13\"></path><path d=\"M3 6h.01\"></path><path d=\"M3 12h.01\"></path><path d=\"M3 18h.01\"></path>"),
126
- success: icon("<path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"></path><path d=\"m9 11 3 3L22 4\"></path>"),
127
- question: icon("<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><path d=\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\"></path><path d=\"M12 17h.01\"></path>"),
128
- failure: icon("<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><path d=\"m15 9-6 6\"></path><path d=\"m9 9 6 6\"></path>"),
129
- danger: icon("<path d=\"M13 2 3 14h9l-1 8 10-12h-9l1-8z\"></path>"),
130
- bug: icon("<path d=\"m8 2 1.88 1.88\"></path><path d=\"M14.12 3.88 16 2\"></path><path d=\"M9 7.13v-1a3.003 3.003 0 1 1 6 0v1\"></path><path d=\"M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6\"></path><path d=\"M12 20v-9\"></path><path d=\"M6.53 9C4.6 8.8 3 7.1 3 5\"></path><path d=\"M6 13H2\"></path><path d=\"M3 21c0-2.1 1.7-3.9 3.8-4\"></path><path d=\"M20.97 5c0 2.1-1.6 3.8-3.5 4\"></path><path d=\"M22 13h-4\"></path><path d=\"M17.2 17c2.1.1 3.8 1.9 3.8 4\"></path>"),
131
- example: icon("<path d=\"M8 6h13\"></path><path d=\"M8 12h13\"></path><path d=\"M8 18h13\"></path><path d=\"M3 6 4 5l1 1-1 1z\"></path><path d=\"M3 12 4 11l1 1-1 1z\"></path><path d=\"M3 18 4 17l1 1-1 1z\"></path>"),
132
- quote: icon("<path d=\"M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z\"></path><path d=\"M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z\"></path>")
119
+ note: icon$1("<path d=\"M12 20h9\"></path><path d=\"M16.376 3.622a1 1 0 0 1 3.002 3.002L7.368 18.635a2 2 0 0 1-.855.506l-2.872.838a.5.5 0 0 1-.62-.62l.838-2.872a2 2 0 0 1 .506-.854z\"></path>"),
120
+ tip: icon$1("<path d=\"M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5\"></path><path d=\"M9 18h6\"></path><path d=\"M10 22h4\"></path>"),
121
+ important: icon$1("<path d=\"M7.9 20A9 9 0 1 0 4 16.1L2 22z\"></path>"),
122
+ warning: icon$1("<path d=\"m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3\"></path><path d=\"M12 9v4\"></path><path d=\"M12 17h.01\"></path>"),
123
+ caution: icon$1("<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><path d=\"m4.9 4.9 14.2 14.2\"></path><path d=\"M12 8v4\"></path><path d=\"M12 16h.01\"></path>"),
124
+ abstract: icon$1("<rect width=\"8\" height=\"4\" x=\"8\" y=\"2\" rx=\"1\" ry=\"1\"></rect><path d=\"M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2\"></path><path d=\"M12 11h4\"></path><path d=\"M12 16h4\"></path><path d=\"M8 11h.01\"></path><path d=\"M8 16h.01\"></path>"),
125
+ info: icon$1("<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><path d=\"M12 16v-4\"></path><path d=\"M12 8h.01\"></path>"),
126
+ todo: icon$1("<path d=\"M8 6h13\"></path><path d=\"M8 12h13\"></path><path d=\"M8 18h13\"></path><path d=\"M3 6h.01\"></path><path d=\"M3 12h.01\"></path><path d=\"M3 18h.01\"></path>"),
127
+ success: icon$1("<path d=\"M22 11.08V12a10 10 0 1 1-5.93-9.14\"></path><path d=\"m9 11 3 3L22 4\"></path>"),
128
+ question: icon$1("<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><path d=\"M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3\"></path><path d=\"M12 17h.01\"></path>"),
129
+ failure: icon$1("<circle cx=\"12\" cy=\"12\" r=\"10\"></circle><path d=\"m15 9-6 6\"></path><path d=\"m9 9 6 6\"></path>"),
130
+ danger: icon$1("<path d=\"M13 2 3 14h9l-1 8 10-12h-9l1-8z\"></path>"),
131
+ bug: icon$1("<path d=\"m8 2 1.88 1.88\"></path><path d=\"M14.12 3.88 16 2\"></path><path d=\"M9 7.13v-1a3.003 3.003 0 1 1 6 0v1\"></path><path d=\"M12 20c-3.3 0-6-2.7-6-6v-3a4 4 0 0 1 4-4h4a4 4 0 0 1 4 4v3c0 3.3-2.7 6-6 6\"></path><path d=\"M12 20v-9\"></path><path d=\"M6.53 9C4.6 8.8 3 7.1 3 5\"></path><path d=\"M6 13H2\"></path><path d=\"M3 21c0-2.1 1.7-3.9 3.8-4\"></path><path d=\"M20.97 5c0 2.1-1.6 3.8-3.5 4\"></path><path d=\"M22 13h-4\"></path><path d=\"M17.2 17c2.1.1 3.8 1.9 3.8 4\"></path>"),
132
+ example: icon$1("<path d=\"M8 6h13\"></path><path d=\"M8 12h13\"></path><path d=\"M8 18h13\"></path><path d=\"M3 6 4 5l1 1-1 1z\"></path><path d=\"M3 12 4 11l1 1-1 1z\"></path><path d=\"M3 18 4 17l1 1-1 1z\"></path>"),
133
+ quote: icon$1("<path d=\"M3 21c3 0 7-1 7-8V5c0-1.25-.756-2.017-2-2H4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2 1 0 1 0 1 1v1c0 1-1 2-2 2s-1 .008-1 1.031V20c0 1 0 1 1 1z\"></path><path d=\"M15 21c3 0 7-1 7-8V5c0-1.25-.757-2.017-2-2h-4c-1.25 0-2 .75-2 1.972V11c0 1.25.75 2 2 2h.75c0 2.25.25 4-2.75 4v3c0 1 0 1 1 1z\"></path>")
133
134
  };
134
135
  // src/github-alerts/index.ts
135
136
  const MARKER_RE = /^\[!([^\]]+)\]([+-])?/;
@@ -2128,7 +2129,7 @@ const editableTree = (root, build, setChildren, setData) => {
2128
2129
  };
2129
2130
  };
2130
2131
  // src/inline-svg.ts
2131
- const hash$1 = (str) => {
2132
+ const hash = (str) => {
2132
2133
  let h = 2166136261;
2133
2134
  for (let i = 0; i < str.length; i++) h = Math.imul(h ^ str.charCodeAt(i), 16777619) >>> 0;
2134
2135
  return h.toString(36);
@@ -2136,7 +2137,7 @@ const hash$1 = (str) => {
2136
2137
  /**
2137
2138
  * The id of a deduplicated SVG's sprite: a hash of its path relative to the document, with `/` separators, so the same document renders the same ids on any machine or OS (an absolute path would leak the build machine into the HTML).
2138
2139
  */
2139
- const svgSpriteId = (relativePath) => `svg-sprite-${hash$1(relativePath)}`;
2140
+ const svgSpriteId = (relativePath) => `svg-sprite-${hash(relativePath)}`;
2140
2141
  const extractSvgParts = (content) => {
2141
2142
  const openTag = /<svg([^>]*?)>/i.exec(content)?.[1] ?? ``;
2142
2143
  return {
@@ -2176,95 +2177,68 @@ const inlineSvgMarkup = (content, alts, relativePath, limits) => {
2176
2177
  return index === 0 ? sprite + use : use;
2177
2178
  });
2178
2179
  };
2179
- // src/mermaid-pele.ts
2180
- /** The class a fenced `mermaid` block's `<code>` takes. */
2181
- const MERMAID_LANGUAGE_CLASS = `language-mermaid`;
2182
- /** The class a `<pre>` holding a diagram written as HTML takes, as Mermaid reads it in the browser. */
2183
- const MERMAID_PRE_CLASS = `mermaid`;
2184
- const hash = (str) => {
2185
- let h = 2166136261;
2186
- for (let i = 0; i < str.length; i++) h = Math.imul(h ^ str.charCodeAt(i), 16777619) >>> 0;
2187
- return h.toString(36);
2188
- };
2189
- /** A diagram's source as Pele reads it: line endings normalized, as markdown-it already has them. */
2190
- const mermaidSource = (text) => text.replace(/\r\n?/g, `\n`);
2191
- /**
2192
- * A document's id prefixes, one per diagram in document order: `prefix`, then a hash of the diagram's source, so a diagram's ids don't change when others are edited, with `-2`, `-3`… for repeats of one diagram. Pele namespaces every id it writes (an accessible title, a gradient) under it. Create one per document.
2193
- */
2194
- const mermaidIdPrefixes = (prefix) => {
2195
- const seen = /* @__PURE__ */ new Map();
2196
- return (source) => {
2197
- const id = `${prefix}-${hash(source)}`;
2198
- const count = (seen.get(id) ?? 0) + 1;
2199
- seen.set(id, count);
2200
- return count === 1 ? id : `${id}-${count}`;
2201
- };
2202
- };
2203
- const escapeAttribute = (value) => value.replace(/&/g, `&amp;`).replace(/"/g, `&quot;`);
2204
- const classes = (value) => value.split(/\s+/).filter((name) => name !== `` && name !== MERMAID_LANGUAGE_CLASS && name !== MERMAID_PRE_CLASS);
2180
+ // src/copy-code.ts
2181
+ /** The copy button's class. */
2182
+ const COPY_CODE_CLASS = "markdown-copy-code";
2183
+ /** The invoker command the button sends its code block. */
2184
+ const COPY_CODE_COMMAND = "--copy";
2185
+ const OPT_OUT = `nocopy`;
2186
+ /** Whether a fence's meta, the info string after its language, turns its block's button off. */
2187
+ const copyCodeOptedOut = (meta) => (meta ?? ``).split(/\s+/).includes(OPT_OUT);
2188
+ /** The text a block copies: its code with line endings normalized and without the newline that ends it. */
2189
+ const copyCodeText = (code) => code.replace(/\r\n?/g, `\n`).replace(/\n$/, ``);
2205
2190
  /**
2206
- * Pele's `<svg>` with the attributes the diagram's element had (from an attribute block such as `{#id .class}`): classes are added after Pele's, a style after Pele's (whose theme variables the diagram needs), and anything else is set, replacing Pele's value. The class that marked the element as a diagram is dropped.
2191
+ * A document's code block ids, one per block in document order: `code-` and a hash of the block's text, so a block's id doesn't change when others are edited, with `-2`, `-3`… for repeats of one block. Create one per document.
2207
2192
  */
2208
- const mermaidSvg = (svg, attributes) => {
2209
- const open = /^<svg\b[^>]*>/.exec(svg)?.[0];
2210
- if (!open || attributes.length === 0) return svg;
2211
- const own = [...open.slice(4, -1).matchAll(/\s([^\s=]+)="([^"]*)"/g)].map(([, name = ``, value = ``]) => [name, value]);
2212
- const merged = new Map(own);
2213
- for (const [name, value] of attributes) {
2214
- const escaped = escapeAttribute(value);
2215
- const current = merged.get(name);
2216
- if (name === `class`) {
2217
- const added = classes(value).map(escapeAttribute).join(` `);
2218
- if (added) merged.set(name, current ? `${current} ${added}` : added);
2219
- } else if (name === `style` && current) merged.set(name, `${current.replace(/;$/, ``)};${escaped}`);
2220
- else merged.set(name, escaped);
2221
- }
2222
- return `<svg${[...merged].map(([name, value]) => ` ${name}="${value}"`).join(``)}>${svg.slice(open.length)}`;
2223
- };
2224
- /** A hast element's properties as attributes; `className` becomes `class`, and other names are kept as the attribute plugins write them. */
2225
- const hastAttributes = (properties) => {
2226
- const text = (value) => typeof value === `string` ? value : typeof value === `number` ? String(value) : value === true ? `` : Array.isArray(value) ? value.map((item) => text(item) ?? ``).join(` `) : void 0;
2227
- const attributes = [];
2228
- for (const [key, value] of Object.entries(properties ?? {})) {
2229
- const written = text(value);
2230
- if (written !== void 0) attributes.push([key === `className` ? `class` : key, written]);
2231
- }
2232
- return attributes;
2233
- };
2234
- const hasClass = (node, name) => {
2235
- const value = node.properties?.className;
2236
- return Array.isArray(value) ? value.includes(name) : typeof value === `string` && value.split(/\s+/).includes(name);
2237
- };
2193
+ const copyCodeIds = () => mermaidIdPrefixes(`code`);
2238
2194
  const textOf = (node) => node.type === `text` ? node.value ?? `` : (node.children ?? []).map(textOf).join(``);
2239
2195
  /**
2240
- * The diagram a `<pre>` holds, as rehype-mermaid finds them: a `<pre>` whose only content (besides whitespace) is a `<code class="language-mermaid">`, which is how a fenced `mermaid` block renders, or a `<pre class="mermaid">`. `element` is the one whose attributes the `<svg>` takes. `undefined` for anything else.
2196
+ * A hast `<pre>` holding a code block, as markdown renders one: its only element child is a `<code>`. Returns the text the block copies and its fence's meta, or nothing for another `<pre>` or an empty block. The meta is the `<code>`'s, as remark and Sätteri keep it, or else the `<pre>`'s `data-meta` attribute, where a highlighter that rebuilds the block (such as Astro's Shiki) can keep it.
2241
2197
  */
2242
- const mermaidDiagram = (pre) => {
2243
- if (pre.tagName !== `pre`) return void 0;
2244
- if (hasClass(pre, MERMAID_PRE_CLASS)) return {
2245
- source: mermaidSource(textOf(pre)),
2246
- element: pre
2198
+ const copyCodeBlock = (node) => {
2199
+ if (node.type !== `element` || node.tagName !== `pre`) return void 0;
2200
+ const elements = (node.children ?? []).filter((child) => child.type === `element`);
2201
+ const [code] = elements;
2202
+ if (elements.length !== 1 || code?.tagName !== `code`) return void 0;
2203
+ const text = copyCodeText(textOf(code));
2204
+ if (text === ``) return void 0;
2205
+ const meta = code.data?.meta ?? node.properties?.dataMeta;
2206
+ return {
2207
+ text,
2208
+ meta: typeof meta === `string` ? meta : void 0
2247
2209
  };
2248
- let code;
2249
- for (const child of pre.children ?? []) {
2250
- if (child.type === `text` && /^\s*$/.test(child.value ?? ``)) continue;
2251
- if (code || child.tagName !== `code`) return void 0;
2252
- code = child;
2253
- }
2254
- return code && hasClass(code, MERMAID_LANGUAGE_CLASS) ? {
2255
- source: mermaidSource(textOf(code)),
2256
- element: code
2257
- } : void 0;
2258
2210
  };
2211
+ const icon = (paths) => `<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">${paths}</svg>`;
2212
+ /** The button's default icon in each state. */
2213
+ const COPY_CODE_ICONS = {
2214
+ copy: icon(`<rect width="14" height="14" x="8" y="8" rx="2" ry="2"></rect><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"></path>`),
2215
+ copied: icon(`<path d="M20 6 9 17l-5-5"></path>`)
2216
+ };
2217
+ /** The button's default text in each state, as GitHub shows it: none before copying, `Copied!` after. */
2218
+ const COPY_CODE_TEXT = {
2219
+ copy: ``,
2220
+ copied: `Copied!`
2221
+ };
2222
+ const DEFAULT_LABEL = `Copy code`;
2223
+ const escape = (value) => value.replace(/&/g, `&amp;`).replace(/</g, `&lt;`).replace(/"/g, `&quot;`);
2259
2224
  /**
2260
- * The error a diagram that failed to render throws: Pele's message, at the document line Pele located the problem on (counting from `line`, the line the diagram's element starts on), or at `line` itself when Pele has no location. The original error is the `cause`.
2225
+ * Builds a document's copy buttons under the plugin's options. A button is for the code block whose `<pre>` has the id, and goes in the `<pre>` after its `<code>`. It starts `hidden`: the client script shows it where it can copy, so a page without the script has no button that does nothing. Each state's icon and text are spans marked `data-state`, which the stylesheet shows by the button's `data-copied`; the client script names the copied button by its copied text.
2261
2226
  */
2262
- const mermaidFailure = (error, line) => {
2263
- const reason = error instanceof Error ? error.message : String(error);
2264
- const within = error instanceof Error && `line` in error && typeof error.line === `number` && error.line > 0 ? error.line : 0;
2265
- const at = line === void 0 ? `` : ` on line ${String(line + within)}`;
2266
- return new Error(`Could not render the mermaid diagram${at}: ${reason}`, { cause: error });
2227
+ const createCopyCodeButton = (options = {}) => {
2228
+ const icons = {
2229
+ ...COPY_CODE_ICONS,
2230
+ ...options.icons
2231
+ };
2232
+ const texts = {
2233
+ ...COPY_CODE_TEXT,
2234
+ ...options.text
2235
+ };
2236
+ const text = (state) => texts[state] ?? ``;
2237
+ const states = [`copy`, `copied`];
2238
+ const content = [...states.map((state) => `<span class="${COPY_CODE_CLASS}-icon" data-state="${state}" aria-hidden="true">${icons[state] || COPY_CODE_ICONS[state]}</span>`), ...states.map((state) => text(state) ? `<span class="${COPY_CODE_CLASS}-text" data-state="${state}" aria-hidden="true">${escape(text(state))}</span>` : ``)].join(``);
2239
+ const label = escape(text(`copy`) || DEFAULT_LABEL);
2240
+ return (id) => `<button type="button" class="${COPY_CODE_CLASS}" command="${COPY_CODE_COMMAND}" commandfor="${id}" aria-label="${label}" hidden>${content}</button>`;
2267
2241
  };
2268
- export { ALERT_ALIASES, CAPTION_CLASS, DEFAULT_TITLE, ICONS, LIGHTBOX_MARKER, containersKept, createAbbreviationScan, createAlertResolver, createDelimitedTransform, createKbdTransform, editableTree, escapedIndices, figureProperties, hastAttributes, headingRank, inlineSvgMarkup, isAlertMarkerLine, isCaptionFigure, isCaptionLine, isEmptyParagraph, isImageParagraph, itemColumns, lightboxDialog, lightboxId, lightboxTrigger, maskEscaped, maskTreeEscapes, mermaidDiagram, mermaidFailure, mermaidIdPrefixes, mermaidSource, mermaidSvg, parseAbbreviations, placeCutAttributes, plainText, processCaptions, processSteps, processStepsInChildren, processTabs, processTabsInChildren, scriptSyntax, sectionize, splitAlertParagraph, startsCaption, stripAttrs, stripCaptionMarker, svgSpriteId, tabLabelText, tabsBlockId, unmaskEscaped };
2242
+ export { ALERT_ALIASES, CAPTION_CLASS, COPY_CODE_CLASS, COPY_CODE_COMMAND, COPY_CODE_ICONS, COPY_CODE_TEXT, DEFAULT_TITLE, ICONS, LIGHTBOX_MARKER, containersKept, copyCodeBlock, copyCodeIds, copyCodeOptedOut, copyCodeText, createAbbreviationScan, createAlertResolver, createCopyCodeButton, createDelimitedTransform, createKbdTransform, editableTree, escapedIndices, figureProperties, hastAttributes, headingRank, inlineSvgMarkup, isAlertMarkerLine, isCaptionFigure, isCaptionLine, isEmptyParagraph, isImageParagraph, itemColumns, lightboxDialog, lightboxId, lightboxTrigger, maskEscaped, maskTreeEscapes, mermaidDiagram, mermaidFailure, mermaidIdPrefixes, mermaidSource, mermaidSvg, parseAbbreviations, placeCutAttributes, plainText, processCaptions, processSteps, processStepsInChildren, processTabs, processTabsInChildren, scriptSyntax, sectionize, splitAlertParagraph, startsCaption, stripAttrs, stripCaptionMarker, svgSpriteId, tabLabelText, tabsBlockId, unmaskEscaped };
2269
2243
 
2270
2244
  //# sourceMappingURL=index.mjs.map