@hyperbook/markdown 0.5.3 → 0.6.0

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/dist/index.cjs.js CHANGED
@@ -35,6 +35,10 @@ var __copyProps = (to, from, except, desc) => {
35
35
  return to;
36
36
  };
37
37
  var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
38
+ // If the importer is in node compatibility mode or this is not an ESM
39
+ // file that has been converted to a CommonJS file using a Babel-
40
+ // compatible transform (i.e. "__esModule" has not been set), then set
41
+ // "default" to the CommonJS "module.exports" for node compatibility.
38
42
  isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
39
43
  mod
40
44
  ));
@@ -165,7 +169,11 @@ function formatUrl(url) {
165
169
  }
166
170
  var doubleSlash = url.split("//");
167
171
  var formatted = doubleSlash.map(
168
- (str) => str.replace(new RegExp("(?<after>:)", "giu"), "$1<wbr>").replace(new RegExp("(?<before>[/~.,\\-_?#%])", "giu"), "<wbr>$1").replace(new RegExp("(?<beforeAndAfter>[=&])", "giu"), "<wbr>$1<wbr>")
172
+ (str) => (
173
+ // Insert a word break opportunity after a colon
174
+ str.replace(new RegExp("(?<after>:)", "giu"), "$1<wbr>").replace(new RegExp("(?<before>[/~.,\\-_?#%])", "giu"), "<wbr>$1").replace(new RegExp("(?<beforeAndAfter>[=&])", "giu"), "<wbr>$1<wbr>")
175
+ )
176
+ // Reconnect the strings with word break opportunities after double slashes
169
177
  ).join("//<wbr>");
170
178
  return formatted;
171
179
  }
@@ -203,7 +211,7 @@ var makeAnchor = (heading) => {
203
211
  anchor = anchor.replace(/ /g, "-");
204
212
  return anchor;
205
213
  };
206
- var Headings = ({ level, children }) => {
214
+ var Headings = ({ level, children, id }) => {
207
215
  var _a;
208
216
  const config = (0, import_provider3.useConfig)();
209
217
  const bookmarksConfig = (_a = config == null ? void 0 : config.elements) == null ? void 0 : _a.bookmarks;
@@ -212,7 +220,7 @@ var Headings = ({ level, children }) => {
212
220
  const label = typeof heading === "string" ? heading : anchor;
213
221
  const [bookmark, toggleBookmark] = (0, import_provider3.useBookmark)(anchor, label);
214
222
  const container = (children2) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
215
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { className: "heading", id: anchor, href: `#${anchor}`, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: children2 }) }),
223
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("a", { className: "heading", id: id != null ? id : anchor, href: `#${id != null ? id : anchor}`, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: children2 }) }),
216
224
  bookmarksConfig !== false && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
217
225
  "button",
218
226
  {
@@ -258,8 +266,6 @@ var import_unist_util_visit = require("unist-util-visit");
258
266
  var remarkRemoveComments = () => (tree) => {
259
267
  const htmlCommentRegex = /<!--([\s\S]*?)-->/g;
260
268
  const handler = (node, index, parent) => {
261
- console.log(node);
262
- console.log(parent);
263
269
  const isComment = node.value.match(htmlCommentRegex);
264
270
  if (isComment) {
265
271
  parent.children.splice(index, 1);
@@ -270,6 +276,34 @@ var remarkRemoveComments = () => (tree) => {
270
276
  (0, import_unist_util_visit.visit)(tree, "jsx", handler);
271
277
  };
272
278
 
279
+ // src/remarkCustomHeadingIds.ts
280
+ var import_unist_util_visit2 = require("unist-util-visit");
281
+ var remarkCustomHeadingIds = () => {
282
+ return function(node) {
283
+ (0, import_unist_util_visit2.visit)(node, "heading", (node2) => {
284
+ let lastChild = node2.children[node2.children.length - 1];
285
+ if (lastChild && lastChild.type === "text") {
286
+ let string = lastChild.value.replace(/ +$/, "");
287
+ let matched = string.match(/ {#([^]+?)}$/);
288
+ if (matched) {
289
+ let id = matched[1];
290
+ if (!!id.length) {
291
+ if (!node2.data) {
292
+ node2.data = {};
293
+ }
294
+ if (!node2.data.hProperties) {
295
+ node2.data.hProperties = {};
296
+ }
297
+ node2.data.id = node2.data.hProperties.id = id;
298
+ string = string.substring(0, matched.index);
299
+ lastChild.value = string;
300
+ }
301
+ }
302
+ }
303
+ });
304
+ };
305
+ };
306
+
273
307
  // src/Markdown.tsx
274
308
  var import_jsx_runtime6 = require("react/jsx-runtime");
275
309
  var Markdown = ({ children }) => {
@@ -295,6 +329,7 @@ var Markdown = ({ children }) => {
295
329
  }),
296
330
  remarkPlugins: [
297
331
  remarkRemoveComments,
332
+ remarkCustomHeadingIds,
298
333
  import_remark_directive.default,
299
334
  import_remark_directive_rehype.default,
300
335
  import_remark_gfm.default,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/index.ts", "../src/Markdown.tsx", "../src/Code.tsx", "../src/Link.tsx", "../src/Table.tsx", "../src/Headings.tsx", "../src/Image.tsx", "../src/remarkRemoveComments.ts"],
4
- "sourcesContent": ["export * from \"./Markdown\";\n", "import ReactMarkdown from \"react-markdown\";\nimport remarkDirective from \"remark-directive\";\nimport remarkDirectiveRehype from \"remark-directive-rehype\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport remarkGemoji from \"remark-gemoji\";\nimport remarkUnwrapImages from \"remark-unwrap-images\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport { useDirectives } from \"@hyperbook/provider\";\nimport { Code } from \"./Code\";\nimport { Link } from \"./Link\";\nimport { Table, Td, Th, Tr } from \"./Table\";\nimport { Headings } from \"./Headings\";\nimport { Image } from \"./Image\";\n\nimport \"./index.css\";\nimport { remarkRemoveComments } from \"./remarkRemoveComments\";\n\nexport type MarkdownProps = {\n children: string;\n};\n\nexport const Markdown = ({ children }: MarkdownProps) => {\n const directives = useDirectives();\n\n return (\n <ReactMarkdown\n className=\"hyperbook-markdown\"\n components={{\n ...directives,\n a: Link,\n code: Code,\n td: Td,\n th: Th,\n table: Table,\n tr: Tr,\n h1: Headings,\n h2: Headings,\n h3: Headings,\n h4: Headings,\n h5: Headings,\n h6: Headings,\n img: Image,\n }}\n remarkPlugins={[\n remarkRemoveComments,\n remarkDirective,\n remarkDirectiveRehype,\n remarkGfm,\n remarkMath,\n remarkGemoji,\n remarkUnwrapImages,\n ]}\n rehypePlugins={[\n rehypeKatex,\n [rehypeHighlight, { ignoreMissing: true, plainText: [\"mermaid\"] }],\n ]}\n skipHtml={false}\n >\n {children}\n </ReactMarkdown>\n );\n};\n", "import { useDirectives } from \"@hyperbook/provider\";\nimport { Fragment, useRef, useState } from \"react\";\nimport { Components } from \"react-markdown\";\n\nconst MdContentCopy = () => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n stroke=\"currentColor\"\n fill=\"currentColor\"\n strokeWidth=\"0\"\n height=\"1em\"\n width=\"1em\"\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\" />\n </svg>\n );\n};\n\nconst MdDone = () => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n stroke=\"currentColor\"\n fill=\"currentColor\"\n strokeWidth=\"0\"\n height=\"1em\"\n width=\"1em\"\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z\" />\n </svg>\n );\n};\n\nconst copyNoNavigator = (text: string) => {\n const isIos = navigator.userAgent.match(/ipad|iphone/i);\n const textarea = document.createElement(\"textarea\");\n\n // create textarea\n textarea.value = text;\n\n // ios will zoom in on the input if the font-size is < 16px\n textarea.style.fontSize = \"20px\";\n document.body.appendChild(textarea);\n\n // select text\n if (isIos) {\n const range = document.createRange();\n range.selectNodeContents(textarea);\n\n const selection = window.getSelection();\n if (selection) {\n selection.removeAllRanges();\n selection.addRange(range);\n }\n textarea.setSelectionRange(0, 999999);\n } else {\n textarea.select();\n }\n\n // copy selection\n document.execCommand(\"copy\");\n\n // cleanup\n document.body.removeChild(textarea);\n};\n\nexport const Code: Components[\"code\"] = ({ children, className, inline }) => {\n const directives = useDirectives();\n if (className === \"language-mermaid\" && directives[\"mermaid\"]) {\n const Mermaid = directives[\"mermaid\"];\n return <Mermaid children={children} />;\n }\n\n const ref = useRef<HTMLElement>(null);\n const [copied, setCopied] = useState(false);\n const copyCode = () => {\n if (ref.current) {\n const text = ref.current.innerText;\n if (navigator.clipboard) {\n navigator.clipboard\n .writeText(text)\n .then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n })\n .catch(() => {\n copyNoNavigator(text);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n });\n } else {\n copyNoNavigator(text);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n }\n }\n };\n\n return inline ? (\n <span className=\"inline\">\n <code ref={ref} className={className}>\n {children}\n </code>\n <button className=\"copy\" onClick={copyCode} aria-label=\"Copy Code\">\n {copied ? <MdDone /> : <MdContentCopy />}\n </button>\n </span>\n ) : (\n <Fragment>\n <code ref={ref} className={className}>\n {children}\n </code>\n <button className=\"copy\" onClick={copyCode} aria-label=\"Copy Code\">\n {copied ? <MdDone /> : <MdContentCopy />}\n </button>\n </Fragment>\n );\n};\n", "import { useLink } from \"@hyperbook/provider\";\nimport { ReactNode } from \"react\";\nimport { Components } from \"react-markdown\";\n\n// see: https://css-tricks.com/better-line-breaks-for-long-urls/\nfunction formatUrl(url: ReactNode) {\n if (typeof url !== \"string\") {\n return url;\n }\n // Split the URL into an array to distinguish double slashes from single slashes\n var doubleSlash = url.split(\"//\");\n\n // Format the strings on either side of double slashes separately\n var formatted = doubleSlash\n .map(\n (str) =>\n // Insert a word break opportunity after a colon\n str\n .replace(/(?<after>:)/giu, \"$1<wbr>\")\n // Before a single slash, tilde, period, comma, hyphen, underline, question mark, number sign, or percent symbol\n .replace(/(?<before>[/~.,\\-_?#%])/giu, \"<wbr>$1\")\n // Before and after an equals sign or ampersand\n .replace(/(?<beforeAndAfter>[=&])/giu, \"<wbr>$1<wbr>\")\n // Reconnect the strings with word break opportunities after double slashes\n )\n .join(\"//<wbr>\");\n\n return formatted;\n}\n\nexport const Link: Components[\"a\"] = ({ href, title, children }) => {\n const L = useLink();\n\n return (\n <L href={href} title={title}>\n {formatUrl(children)}\n </L>\n );\n};\n", "import { ReactNode } from \"react\";\nimport { Components } from \"react-markdown\";\n\nlet tableHeaders: ReactNode[][] = [];\nlet tdIndex = 0;\n\nexport const Table: Components[\"table\"] = ({ children, style }) => {\n tableHeaders = [];\n return <table style={style}>{children}</table>;\n};\n\nexport const Tr: Components[\"tr\"] = ({ children, style }) => {\n tdIndex = 0;\n return <tr style={style}>{children}</tr>;\n};\n\nexport const Td: Components[\"td\"] = ({ children, style }) => {\n return (\n <td data-label={tableHeaders[tdIndex++]} style={style}>\n {children}\n </td>\n );\n};\n\nexport const Th: Components[\"th\"] = ({ children, style }) => {\n tableHeaders.push(children);\n return <th style={style}>{children}</th>;\n};\n", "import { useBookmark, useConfig } from \"@hyperbook/provider\";\nimport { Components } from \"react-markdown\";\n\nexport const makeAnchor = (heading: string) => {\n // If we have a heading, make it lower case\n let anchor = heading.toLowerCase();\n\n // Clean anchor (replace special characters whitespaces).\n // Alternatively, use encodeURIComponent() if you don't care about\n // pretty anchor links\n anchor = anchor.replace(/[^a-zA-Z0-9 ]/g, \"\");\n anchor = anchor.replace(/ /g, \"-\");\n\n return anchor;\n};\n\nexport const Headings: Components[\"h1\"] = ({ level, children }) => {\n const config = useConfig();\n const bookmarksConfig = config?.elements?.bookmarks;\n // Access actual (string) value of heading\n const heading = children?.[0] || \"\";\n\n // If we have a heading, make it lower case\n let anchor = typeof heading === \"string\" ? makeAnchor(heading) : \"\";\n\n const label = typeof heading === \"string\" ? heading : anchor;\n\n const [bookmark, toggleBookmark] = useBookmark(anchor, label);\n\n // Utility\n const container = (children: React.ReactNode): JSX.Element => (\n <>\n <a className=\"heading\" id={anchor} href={`#${anchor}`}>\n <span>{children}</span>\n </a>\n {bookmarksConfig !== false && (\n <button\n className={bookmark ? \"bookmark active\" : \"bookmark\"}\n onClick={() => toggleBookmark()}\n title=\"Bookmark\"\n >\n \uD83D\uDD16\n </button>\n )}\n </>\n );\n\n switch (level) {\n case 1:\n return <h1>{container(children)}</h1>;\n case 2:\n return <h2>{container(children)}</h2>;\n case 3:\n return <h3>{container(children)}</h3>;\n case 4:\n return <h4>{container(children)}</h4>;\n case 5:\n return <h5>{container(children)}</h5>;\n\n default:\n return <h6>{container(children)}</h6>;\n }\n};\n", "import { useMakeUrl } from \"@hyperbook/provider\";\nimport { useState } from \"react\";\nimport { Components } from \"react-markdown\";\n\nexport const Image: Components[\"img\"] = ({ src, title, alt }) => {\n const makeUrl = useMakeUrl();\n const [full, setFull] = useState(false);\n src = makeUrl(src, \"public\");\n\n return (\n <figure className={full ? \"lightbox\" : undefined}>\n <img src={src} alt={alt} onClick={() => setFull((f) => !f)} />\n {title && <figcaption>{title}</figcaption>}\n </figure>\n );\n};\n", "//@ts-nocheck\nimport { visit, SKIP } from \"unist-util-visit\";\nimport { Transformer } from \"unified\";\nimport { BuildVisitor } from \"unist-util-visit/complex-types\";\n\nexport const remarkRemoveComments: () => Transformer = () => (tree) => {\n const htmlCommentRegex = /<!--([\\s\\S]*?)-->/g;\n\n const handler: BuildVisitor = (node, index, parent) => {\n console.log(node);\n console.log(parent);\n const isComment = node.value.match(htmlCommentRegex);\n\n if (isComment) {\n // remove node\n parent.children.splice(index, 1);\n // Do not traverse `node`, continue at the node *now* at `index`. http://unifiedjs.com/learn/recipe/remove-node/\n return [SKIP, index];\n }\n };\n\n visit(tree, \"html\", handler);\n\n visit(tree, \"jsx\", handler);\n};\n"],
5
- "mappings": "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",
6
- "names": ["import_provider", "import_provider", "import_jsx_runtime", "import_jsx_runtime", "import_provider", "import_jsx_runtime", "children", "import_provider", "import_react", "import_jsx_runtime", "import_jsx_runtime", "ReactMarkdown", "remarkDirective", "remarkDirectiveRehype", "remarkGfm", "remarkMath", "remarkGemoji", "remarkUnwrapImages", "rehypeKatex", "rehypeHighlight"]
3
+ "sources": ["../src/index.ts", "../src/Markdown.tsx", "../src/Code.tsx", "../src/Link.tsx", "../src/Table.tsx", "../src/Headings.tsx", "../src/Image.tsx", "../src/remarkRemoveComments.ts", "../src/remarkCustomHeadingIds.ts"],
4
+ "sourcesContent": ["export * from \"./Markdown\";\n", "import ReactMarkdown from \"react-markdown\";\nimport remarkDirective from \"remark-directive\";\nimport remarkDirectiveRehype from \"remark-directive-rehype\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport remarkGemoji from \"remark-gemoji\";\nimport remarkUnwrapImages from \"remark-unwrap-images\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport { useDirectives } from \"@hyperbook/provider\";\nimport { Code } from \"./Code\";\nimport { Link } from \"./Link\";\nimport { Table, Td, Th, Tr } from \"./Table\";\nimport { Headings } from \"./Headings\";\nimport { Image } from \"./Image\";\n\nimport \"./index.css\";\nimport { remarkRemoveComments } from \"./remarkRemoveComments\";\nimport { remarkCustomHeadingIds } from \"./remarkCustomHeadingIds\";\n\nexport type MarkdownProps = {\n children: string;\n};\n\nexport const Markdown = ({ children }: MarkdownProps) => {\n const directives = useDirectives();\n\n return (\n <ReactMarkdown\n className=\"hyperbook-markdown\"\n components={{\n ...directives,\n a: Link,\n code: Code,\n td: Td,\n th: Th,\n table: Table,\n tr: Tr,\n h1: Headings,\n h2: Headings,\n h3: Headings,\n h4: Headings,\n h5: Headings,\n h6: Headings,\n img: Image,\n }}\n remarkPlugins={[\n remarkRemoveComments,\n remarkCustomHeadingIds,\n remarkDirective,\n remarkDirectiveRehype,\n remarkGfm,\n remarkMath,\n remarkGemoji,\n remarkUnwrapImages,\n ]}\n rehypePlugins={[\n rehypeKatex,\n [rehypeHighlight, { ignoreMissing: true, plainText: [\"mermaid\"] }],\n ]}\n skipHtml={false}\n >\n {children}\n </ReactMarkdown>\n );\n};\n", "import { useDirectives } from \"@hyperbook/provider\";\nimport { Fragment, useRef, useState } from \"react\";\nimport { Components } from \"react-markdown\";\n\nconst MdContentCopy = () => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n stroke=\"currentColor\"\n fill=\"currentColor\"\n strokeWidth=\"0\"\n height=\"1em\"\n width=\"1em\"\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\" />\n </svg>\n );\n};\n\nconst MdDone = () => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n stroke=\"currentColor\"\n fill=\"currentColor\"\n strokeWidth=\"0\"\n height=\"1em\"\n width=\"1em\"\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z\" />\n </svg>\n );\n};\n\nconst copyNoNavigator = (text: string) => {\n const isIos = navigator.userAgent.match(/ipad|iphone/i);\n const textarea = document.createElement(\"textarea\");\n\n // create textarea\n textarea.value = text;\n\n // ios will zoom in on the input if the font-size is < 16px\n textarea.style.fontSize = \"20px\";\n document.body.appendChild(textarea);\n\n // select text\n if (isIos) {\n const range = document.createRange();\n range.selectNodeContents(textarea);\n\n const selection = window.getSelection();\n if (selection) {\n selection.removeAllRanges();\n selection.addRange(range);\n }\n textarea.setSelectionRange(0, 999999);\n } else {\n textarea.select();\n }\n\n // copy selection\n document.execCommand(\"copy\");\n\n // cleanup\n document.body.removeChild(textarea);\n};\n\nexport const Code: Components[\"code\"] = ({ children, className, inline }) => {\n const directives = useDirectives();\n if (className === \"language-mermaid\" && directives[\"mermaid\"]) {\n const Mermaid = directives[\"mermaid\"];\n return <Mermaid children={children} />;\n }\n\n const ref = useRef<HTMLElement>(null);\n const [copied, setCopied] = useState(false);\n const copyCode = () => {\n if (ref.current) {\n const text = ref.current.innerText;\n if (navigator.clipboard) {\n navigator.clipboard\n .writeText(text)\n .then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n })\n .catch(() => {\n copyNoNavigator(text);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n });\n } else {\n copyNoNavigator(text);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n }\n }\n };\n\n return inline ? (\n <span className=\"inline\">\n <code ref={ref} className={className}>\n {children}\n </code>\n <button className=\"copy\" onClick={copyCode} aria-label=\"Copy Code\">\n {copied ? <MdDone /> : <MdContentCopy />}\n </button>\n </span>\n ) : (\n <Fragment>\n <code ref={ref} className={className}>\n {children}\n </code>\n <button className=\"copy\" onClick={copyCode} aria-label=\"Copy Code\">\n {copied ? <MdDone /> : <MdContentCopy />}\n </button>\n </Fragment>\n );\n};\n", "import { useLink } from \"@hyperbook/provider\";\nimport { ReactNode } from \"react\";\nimport { Components } from \"react-markdown\";\n\n// see: https://css-tricks.com/better-line-breaks-for-long-urls/\nfunction formatUrl(url: ReactNode) {\n if (typeof url !== \"string\") {\n return url;\n }\n // Split the URL into an array to distinguish double slashes from single slashes\n var doubleSlash = url.split(\"//\");\n\n // Format the strings on either side of double slashes separately\n var formatted = doubleSlash\n .map(\n (str) =>\n // Insert a word break opportunity after a colon\n str\n .replace(/(?<after>:)/giu, \"$1<wbr>\")\n // Before a single slash, tilde, period, comma, hyphen, underline, question mark, number sign, or percent symbol\n .replace(/(?<before>[/~.,\\-_?#%])/giu, \"<wbr>$1\")\n // Before and after an equals sign or ampersand\n .replace(/(?<beforeAndAfter>[=&])/giu, \"<wbr>$1<wbr>\")\n // Reconnect the strings with word break opportunities after double slashes\n )\n .join(\"//<wbr>\");\n\n return formatted;\n}\n\nexport const Link: Components[\"a\"] = ({ href, title, children }) => {\n const L = useLink();\n\n return (\n <L href={href} title={title}>\n {formatUrl(children)}\n </L>\n );\n};\n", "import { ReactNode } from \"react\";\nimport { Components } from \"react-markdown\";\n\nlet tableHeaders: ReactNode[][] = [];\nlet tdIndex = 0;\n\nexport const Table: Components[\"table\"] = ({ children, style }) => {\n tableHeaders = [];\n return <table style={style}>{children}</table>;\n};\n\nexport const Tr: Components[\"tr\"] = ({ children, style }) => {\n tdIndex = 0;\n return <tr style={style}>{children}</tr>;\n};\n\nexport const Td: Components[\"td\"] = ({ children, style }) => {\n return (\n <td data-label={tableHeaders[tdIndex++]} style={style}>\n {children}\n </td>\n );\n};\n\nexport const Th: Components[\"th\"] = ({ children, style }) => {\n tableHeaders.push(children);\n return <th style={style}>{children}</th>;\n};\n", "import { useBookmark, useConfig } from \"@hyperbook/provider\";\nimport { Components } from \"react-markdown\";\n\nexport const makeAnchor = (heading: string) => {\n // If we have a heading, make it lower case\n let anchor = heading.toLowerCase();\n\n // Clean anchor (replace special characters whitespaces).\n // Alternatively, use encodeURIComponent() if you don't care about\n // pretty anchor links\n anchor = anchor.replace(/[^a-zA-Z0-9 ]/g, \"\");\n anchor = anchor.replace(/ /g, \"-\");\n\n return anchor;\n};\n\nexport const Headings: Components[\"h1\"] = ({ level, children, id }) => {\n const config = useConfig();\n const bookmarksConfig = config?.elements?.bookmarks;\n // Access actual (string) value of heading\n const heading = children?.[0] || \"\";\n\n // If we have a heading, make it lower case\n let anchor = typeof heading === \"string\" ? makeAnchor(heading) : \"\";\n\n const label = typeof heading === \"string\" ? heading : anchor;\n\n const [bookmark, toggleBookmark] = useBookmark(anchor, label);\n\n // Utility\n const container = (children: React.ReactNode): JSX.Element => (\n <>\n <a className=\"heading\" id={id ?? anchor} href={`#${id ?? anchor}`}>\n <span>{children}</span>\n </a>\n {bookmarksConfig !== false && (\n <button\n className={bookmark ? \"bookmark active\" : \"bookmark\"}\n onClick={() => toggleBookmark()}\n title=\"Bookmark\"\n >\n \uD83D\uDD16\n </button>\n )}\n </>\n );\n\n switch (level) {\n case 1:\n return <h1>{container(children)}</h1>;\n case 2:\n return <h2>{container(children)}</h2>;\n case 3:\n return <h3>{container(children)}</h3>;\n case 4:\n return <h4>{container(children)}</h4>;\n case 5:\n return <h5>{container(children)}</h5>;\n\n default:\n return <h6>{container(children)}</h6>;\n }\n};\n", "import { useMakeUrl } from \"@hyperbook/provider\";\nimport { useState } from \"react\";\nimport { Components } from \"react-markdown\";\n\nexport const Image: Components[\"img\"] = ({ src, title, alt }) => {\n const makeUrl = useMakeUrl();\n const [full, setFull] = useState(false);\n src = makeUrl(src, \"public\");\n\n return (\n <figure className={full ? \"lightbox\" : undefined}>\n <img src={src} alt={alt} onClick={() => setFull((f) => !f)} />\n {title && <figcaption>{title}</figcaption>}\n </figure>\n );\n};\n", "//@ts-nocheck\nimport { visit, SKIP } from \"unist-util-visit\";\nimport { Transformer } from \"unified\";\nimport { BuildVisitor } from \"unist-util-visit/complex-types\";\n\nexport const remarkRemoveComments: () => Transformer = () => (tree) => {\n const htmlCommentRegex = /<!--([\\s\\S]*?)-->/g;\n\n const handler: BuildVisitor = (node, index, parent) => {\n const isComment = node.value.match(htmlCommentRegex);\n\n if (isComment) {\n // remove node\n parent.children.splice(index, 1);\n // Do not traverse `node`, continue at the node *now* at `index`. http://unifiedjs.com/learn/recipe/remove-node/\n return [SKIP, index];\n }\n };\n\n visit(tree, \"html\", handler);\n\n visit(tree, \"jsx\", handler);\n};\n", "import { visit } from \"unist-util-visit\";\nimport { Transformer } from \"unified\";\n\nexport const remarkCustomHeadingIds: () => Transformer = () => {\n return function (node) {\n visit(node, \"heading\", (node) => {\n let lastChild = node.children[node.children.length - 1];\n if (lastChild && lastChild.type === \"text\") {\n let string = lastChild.value.replace(/ +$/, \"\");\n let matched = string.match(/ {#([^]+?)}$/);\n\n if (matched) {\n let id = matched[1];\n if (!!id.length) {\n if (!node.data) {\n node.data = {};\n }\n if (!node.data.hProperties) {\n node.data.hProperties = {};\n }\n node.data.id = node.data.hProperties.id = id;\n\n string = string.substring(0, matched.index);\n lastChild.value = string;\n }\n }\n }\n });\n };\n};\n"],
5
+ "mappings": "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",
6
+ "names": ["import_provider", "import_provider", "import_jsx_runtime", "import_jsx_runtime", "import_provider", "import_jsx_runtime", "children", "import_provider", "import_react", "import_jsx_runtime", "import_unist_util_visit", "node", "import_jsx_runtime", "ReactMarkdown", "remarkDirective", "remarkDirectiveRehype", "remarkGfm", "remarkMath", "remarkGemoji", "remarkUnwrapImages", "rehypeKatex", "rehypeHighlight"]
7
7
  }
@@ -136,7 +136,11 @@ function formatUrl(url) {
136
136
  }
137
137
  var doubleSlash = url.split("//");
138
138
  var formatted = doubleSlash.map(
139
- (str) => str.replace(new RegExp("(?<after>:)", "giu"), "$1<wbr>").replace(new RegExp("(?<before>[/~.,\\-_?#%])", "giu"), "<wbr>$1").replace(new RegExp("(?<beforeAndAfter>[=&])", "giu"), "<wbr>$1<wbr>")
139
+ (str) => (
140
+ // Insert a word break opportunity after a colon
141
+ str.replace(new RegExp("(?<after>:)", "giu"), "$1<wbr>").replace(new RegExp("(?<before>[/~.,\\-_?#%])", "giu"), "<wbr>$1").replace(new RegExp("(?<beforeAndAfter>[=&])", "giu"), "<wbr>$1<wbr>")
142
+ )
143
+ // Reconnect the strings with word break opportunities after double slashes
140
144
  ).join("//<wbr>");
141
145
  return formatted;
142
146
  }
@@ -174,7 +178,7 @@ var makeAnchor = (heading) => {
174
178
  anchor = anchor.replace(/ /g, "-");
175
179
  return anchor;
176
180
  };
177
- var Headings = ({ level, children }) => {
181
+ var Headings = ({ level, children, id }) => {
178
182
  var _a;
179
183
  const config = useConfig();
180
184
  const bookmarksConfig = (_a = config == null ? void 0 : config.elements) == null ? void 0 : _a.bookmarks;
@@ -183,7 +187,7 @@ var Headings = ({ level, children }) => {
183
187
  const label = typeof heading === "string" ? heading : anchor;
184
188
  const [bookmark, toggleBookmark] = useBookmark(anchor, label);
185
189
  const container = (children2) => /* @__PURE__ */ jsxs2(Fragment2, { children: [
186
- /* @__PURE__ */ jsx4("a", { className: "heading", id: anchor, href: `#${anchor}`, children: /* @__PURE__ */ jsx4("span", { children: children2 }) }),
190
+ /* @__PURE__ */ jsx4("a", { className: "heading", id: id != null ? id : anchor, href: `#${id != null ? id : anchor}`, children: /* @__PURE__ */ jsx4("span", { children: children2 }) }),
187
191
  bookmarksConfig !== false && /* @__PURE__ */ jsx4(
188
192
  "button",
189
193
  {
@@ -229,8 +233,6 @@ import { visit, SKIP } from "unist-util-visit";
229
233
  var remarkRemoveComments = () => (tree) => {
230
234
  const htmlCommentRegex = /<!--([\s\S]*?)-->/g;
231
235
  const handler = (node, index, parent) => {
232
- console.log(node);
233
- console.log(parent);
234
236
  const isComment = node.value.match(htmlCommentRegex);
235
237
  if (isComment) {
236
238
  parent.children.splice(index, 1);
@@ -241,6 +243,34 @@ var remarkRemoveComments = () => (tree) => {
241
243
  visit(tree, "jsx", handler);
242
244
  };
243
245
 
246
+ // src/remarkCustomHeadingIds.ts
247
+ import { visit as visit2 } from "unist-util-visit";
248
+ var remarkCustomHeadingIds = () => {
249
+ return function(node) {
250
+ visit2(node, "heading", (node2) => {
251
+ let lastChild = node2.children[node2.children.length - 1];
252
+ if (lastChild && lastChild.type === "text") {
253
+ let string = lastChild.value.replace(/ +$/, "");
254
+ let matched = string.match(/ {#([^]+?)}$/);
255
+ if (matched) {
256
+ let id = matched[1];
257
+ if (!!id.length) {
258
+ if (!node2.data) {
259
+ node2.data = {};
260
+ }
261
+ if (!node2.data.hProperties) {
262
+ node2.data.hProperties = {};
263
+ }
264
+ node2.data.id = node2.data.hProperties.id = id;
265
+ string = string.substring(0, matched.index);
266
+ lastChild.value = string;
267
+ }
268
+ }
269
+ }
270
+ });
271
+ };
272
+ };
273
+
244
274
  // src/Markdown.tsx
245
275
  import { jsx as jsx6 } from "react/jsx-runtime";
246
276
  var Markdown = ({ children }) => {
@@ -266,6 +296,7 @@ var Markdown = ({ children }) => {
266
296
  }),
267
297
  remarkPlugins: [
268
298
  remarkRemoveComments,
299
+ remarkCustomHeadingIds,
269
300
  remarkDirective,
270
301
  remarkDirectiveRehype,
271
302
  remarkGfm,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/Markdown.tsx", "../src/Code.tsx", "../src/Link.tsx", "../src/Table.tsx", "../src/Headings.tsx", "../src/Image.tsx", "../src/remarkRemoveComments.ts"],
4
- "sourcesContent": ["import ReactMarkdown from \"react-markdown\";\nimport remarkDirective from \"remark-directive\";\nimport remarkDirectiveRehype from \"remark-directive-rehype\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport remarkGemoji from \"remark-gemoji\";\nimport remarkUnwrapImages from \"remark-unwrap-images\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport { useDirectives } from \"@hyperbook/provider\";\nimport { Code } from \"./Code\";\nimport { Link } from \"./Link\";\nimport { Table, Td, Th, Tr } from \"./Table\";\nimport { Headings } from \"./Headings\";\nimport { Image } from \"./Image\";\n\nimport \"./index.css\";\nimport { remarkRemoveComments } from \"./remarkRemoveComments\";\n\nexport type MarkdownProps = {\n children: string;\n};\n\nexport const Markdown = ({ children }: MarkdownProps) => {\n const directives = useDirectives();\n\n return (\n <ReactMarkdown\n className=\"hyperbook-markdown\"\n components={{\n ...directives,\n a: Link,\n code: Code,\n td: Td,\n th: Th,\n table: Table,\n tr: Tr,\n h1: Headings,\n h2: Headings,\n h3: Headings,\n h4: Headings,\n h5: Headings,\n h6: Headings,\n img: Image,\n }}\n remarkPlugins={[\n remarkRemoveComments,\n remarkDirective,\n remarkDirectiveRehype,\n remarkGfm,\n remarkMath,\n remarkGemoji,\n remarkUnwrapImages,\n ]}\n rehypePlugins={[\n rehypeKatex,\n [rehypeHighlight, { ignoreMissing: true, plainText: [\"mermaid\"] }],\n ]}\n skipHtml={false}\n >\n {children}\n </ReactMarkdown>\n );\n};\n", "import { useDirectives } from \"@hyperbook/provider\";\nimport { Fragment, useRef, useState } from \"react\";\nimport { Components } from \"react-markdown\";\n\nconst MdContentCopy = () => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n stroke=\"currentColor\"\n fill=\"currentColor\"\n strokeWidth=\"0\"\n height=\"1em\"\n width=\"1em\"\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\" />\n </svg>\n );\n};\n\nconst MdDone = () => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n stroke=\"currentColor\"\n fill=\"currentColor\"\n strokeWidth=\"0\"\n height=\"1em\"\n width=\"1em\"\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z\" />\n </svg>\n );\n};\n\nconst copyNoNavigator = (text: string) => {\n const isIos = navigator.userAgent.match(/ipad|iphone/i);\n const textarea = document.createElement(\"textarea\");\n\n // create textarea\n textarea.value = text;\n\n // ios will zoom in on the input if the font-size is < 16px\n textarea.style.fontSize = \"20px\";\n document.body.appendChild(textarea);\n\n // select text\n if (isIos) {\n const range = document.createRange();\n range.selectNodeContents(textarea);\n\n const selection = window.getSelection();\n if (selection) {\n selection.removeAllRanges();\n selection.addRange(range);\n }\n textarea.setSelectionRange(0, 999999);\n } else {\n textarea.select();\n }\n\n // copy selection\n document.execCommand(\"copy\");\n\n // cleanup\n document.body.removeChild(textarea);\n};\n\nexport const Code: Components[\"code\"] = ({ children, className, inline }) => {\n const directives = useDirectives();\n if (className === \"language-mermaid\" && directives[\"mermaid\"]) {\n const Mermaid = directives[\"mermaid\"];\n return <Mermaid children={children} />;\n }\n\n const ref = useRef<HTMLElement>(null);\n const [copied, setCopied] = useState(false);\n const copyCode = () => {\n if (ref.current) {\n const text = ref.current.innerText;\n if (navigator.clipboard) {\n navigator.clipboard\n .writeText(text)\n .then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n })\n .catch(() => {\n copyNoNavigator(text);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n });\n } else {\n copyNoNavigator(text);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n }\n }\n };\n\n return inline ? (\n <span className=\"inline\">\n <code ref={ref} className={className}>\n {children}\n </code>\n <button className=\"copy\" onClick={copyCode} aria-label=\"Copy Code\">\n {copied ? <MdDone /> : <MdContentCopy />}\n </button>\n </span>\n ) : (\n <Fragment>\n <code ref={ref} className={className}>\n {children}\n </code>\n <button className=\"copy\" onClick={copyCode} aria-label=\"Copy Code\">\n {copied ? <MdDone /> : <MdContentCopy />}\n </button>\n </Fragment>\n );\n};\n", "import { useLink } from \"@hyperbook/provider\";\nimport { ReactNode } from \"react\";\nimport { Components } from \"react-markdown\";\n\n// see: https://css-tricks.com/better-line-breaks-for-long-urls/\nfunction formatUrl(url: ReactNode) {\n if (typeof url !== \"string\") {\n return url;\n }\n // Split the URL into an array to distinguish double slashes from single slashes\n var doubleSlash = url.split(\"//\");\n\n // Format the strings on either side of double slashes separately\n var formatted = doubleSlash\n .map(\n (str) =>\n // Insert a word break opportunity after a colon\n str\n .replace(/(?<after>:)/giu, \"$1<wbr>\")\n // Before a single slash, tilde, period, comma, hyphen, underline, question mark, number sign, or percent symbol\n .replace(/(?<before>[/~.,\\-_?#%])/giu, \"<wbr>$1\")\n // Before and after an equals sign or ampersand\n .replace(/(?<beforeAndAfter>[=&])/giu, \"<wbr>$1<wbr>\")\n // Reconnect the strings with word break opportunities after double slashes\n )\n .join(\"//<wbr>\");\n\n return formatted;\n}\n\nexport const Link: Components[\"a\"] = ({ href, title, children }) => {\n const L = useLink();\n\n return (\n <L href={href} title={title}>\n {formatUrl(children)}\n </L>\n );\n};\n", "import { ReactNode } from \"react\";\nimport { Components } from \"react-markdown\";\n\nlet tableHeaders: ReactNode[][] = [];\nlet tdIndex = 0;\n\nexport const Table: Components[\"table\"] = ({ children, style }) => {\n tableHeaders = [];\n return <table style={style}>{children}</table>;\n};\n\nexport const Tr: Components[\"tr\"] = ({ children, style }) => {\n tdIndex = 0;\n return <tr style={style}>{children}</tr>;\n};\n\nexport const Td: Components[\"td\"] = ({ children, style }) => {\n return (\n <td data-label={tableHeaders[tdIndex++]} style={style}>\n {children}\n </td>\n );\n};\n\nexport const Th: Components[\"th\"] = ({ children, style }) => {\n tableHeaders.push(children);\n return <th style={style}>{children}</th>;\n};\n", "import { useBookmark, useConfig } from \"@hyperbook/provider\";\nimport { Components } from \"react-markdown\";\n\nexport const makeAnchor = (heading: string) => {\n // If we have a heading, make it lower case\n let anchor = heading.toLowerCase();\n\n // Clean anchor (replace special characters whitespaces).\n // Alternatively, use encodeURIComponent() if you don't care about\n // pretty anchor links\n anchor = anchor.replace(/[^a-zA-Z0-9 ]/g, \"\");\n anchor = anchor.replace(/ /g, \"-\");\n\n return anchor;\n};\n\nexport const Headings: Components[\"h1\"] = ({ level, children }) => {\n const config = useConfig();\n const bookmarksConfig = config?.elements?.bookmarks;\n // Access actual (string) value of heading\n const heading = children?.[0] || \"\";\n\n // If we have a heading, make it lower case\n let anchor = typeof heading === \"string\" ? makeAnchor(heading) : \"\";\n\n const label = typeof heading === \"string\" ? heading : anchor;\n\n const [bookmark, toggleBookmark] = useBookmark(anchor, label);\n\n // Utility\n const container = (children: React.ReactNode): JSX.Element => (\n <>\n <a className=\"heading\" id={anchor} href={`#${anchor}`}>\n <span>{children}</span>\n </a>\n {bookmarksConfig !== false && (\n <button\n className={bookmark ? \"bookmark active\" : \"bookmark\"}\n onClick={() => toggleBookmark()}\n title=\"Bookmark\"\n >\n \uD83D\uDD16\n </button>\n )}\n </>\n );\n\n switch (level) {\n case 1:\n return <h1>{container(children)}</h1>;\n case 2:\n return <h2>{container(children)}</h2>;\n case 3:\n return <h3>{container(children)}</h3>;\n case 4:\n return <h4>{container(children)}</h4>;\n case 5:\n return <h5>{container(children)}</h5>;\n\n default:\n return <h6>{container(children)}</h6>;\n }\n};\n", "import { useMakeUrl } from \"@hyperbook/provider\";\nimport { useState } from \"react\";\nimport { Components } from \"react-markdown\";\n\nexport const Image: Components[\"img\"] = ({ src, title, alt }) => {\n const makeUrl = useMakeUrl();\n const [full, setFull] = useState(false);\n src = makeUrl(src, \"public\");\n\n return (\n <figure className={full ? \"lightbox\" : undefined}>\n <img src={src} alt={alt} onClick={() => setFull((f) => !f)} />\n {title && <figcaption>{title}</figcaption>}\n </figure>\n );\n};\n", "//@ts-nocheck\nimport { visit, SKIP } from \"unist-util-visit\";\nimport { Transformer } from \"unified\";\nimport { BuildVisitor } from \"unist-util-visit/complex-types\";\n\nexport const remarkRemoveComments: () => Transformer = () => (tree) => {\n const htmlCommentRegex = /<!--([\\s\\S]*?)-->/g;\n\n const handler: BuildVisitor = (node, index, parent) => {\n console.log(node);\n console.log(parent);\n const isComment = node.value.match(htmlCommentRegex);\n\n if (isComment) {\n // remove node\n parent.children.splice(index, 1);\n // Do not traverse `node`, continue at the node *now* at `index`. http://unifiedjs.com/learn/recipe/remove-node/\n return [SKIP, index];\n }\n };\n\n visit(tree, \"html\", handler);\n\n visit(tree, \"jsx\", handler);\n};\n"],
5
- "mappings": "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",
6
- "names": ["useDirectives", "jsx", "jsx", "Fragment", "jsx", "jsxs", "children", "useState", "jsx", "jsxs", "jsx", "useDirectives"]
3
+ "sources": ["../src/Markdown.tsx", "../src/Code.tsx", "../src/Link.tsx", "../src/Table.tsx", "../src/Headings.tsx", "../src/Image.tsx", "../src/remarkRemoveComments.ts", "../src/remarkCustomHeadingIds.ts"],
4
+ "sourcesContent": ["import ReactMarkdown from \"react-markdown\";\nimport remarkDirective from \"remark-directive\";\nimport remarkDirectiveRehype from \"remark-directive-rehype\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkMath from \"remark-math\";\nimport remarkGemoji from \"remark-gemoji\";\nimport remarkUnwrapImages from \"remark-unwrap-images\";\nimport rehypeKatex from \"rehype-katex\";\nimport rehypeHighlight from \"rehype-highlight\";\nimport { useDirectives } from \"@hyperbook/provider\";\nimport { Code } from \"./Code\";\nimport { Link } from \"./Link\";\nimport { Table, Td, Th, Tr } from \"./Table\";\nimport { Headings } from \"./Headings\";\nimport { Image } from \"./Image\";\n\nimport \"./index.css\";\nimport { remarkRemoveComments } from \"./remarkRemoveComments\";\nimport { remarkCustomHeadingIds } from \"./remarkCustomHeadingIds\";\n\nexport type MarkdownProps = {\n children: string;\n};\n\nexport const Markdown = ({ children }: MarkdownProps) => {\n const directives = useDirectives();\n\n return (\n <ReactMarkdown\n className=\"hyperbook-markdown\"\n components={{\n ...directives,\n a: Link,\n code: Code,\n td: Td,\n th: Th,\n table: Table,\n tr: Tr,\n h1: Headings,\n h2: Headings,\n h3: Headings,\n h4: Headings,\n h5: Headings,\n h6: Headings,\n img: Image,\n }}\n remarkPlugins={[\n remarkRemoveComments,\n remarkCustomHeadingIds,\n remarkDirective,\n remarkDirectiveRehype,\n remarkGfm,\n remarkMath,\n remarkGemoji,\n remarkUnwrapImages,\n ]}\n rehypePlugins={[\n rehypeKatex,\n [rehypeHighlight, { ignoreMissing: true, plainText: [\"mermaid\"] }],\n ]}\n skipHtml={false}\n >\n {children}\n </ReactMarkdown>\n );\n};\n", "import { useDirectives } from \"@hyperbook/provider\";\nimport { Fragment, useRef, useState } from \"react\";\nimport { Components } from \"react-markdown\";\n\nconst MdContentCopy = () => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n stroke=\"currentColor\"\n fill=\"currentColor\"\n strokeWidth=\"0\"\n height=\"1em\"\n width=\"1em\"\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z\" />\n </svg>\n );\n};\n\nconst MdDone = () => {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n stroke=\"currentColor\"\n fill=\"currentColor\"\n strokeWidth=\"0\"\n height=\"1em\"\n width=\"1em\"\n viewBox=\"0 0 24 24\"\n >\n <path d=\"M0 0h24v24H0z\" fill=\"none\" />\n <path d=\"M9 16.2L4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4L9 16.2z\" />\n </svg>\n );\n};\n\nconst copyNoNavigator = (text: string) => {\n const isIos = navigator.userAgent.match(/ipad|iphone/i);\n const textarea = document.createElement(\"textarea\");\n\n // create textarea\n textarea.value = text;\n\n // ios will zoom in on the input if the font-size is < 16px\n textarea.style.fontSize = \"20px\";\n document.body.appendChild(textarea);\n\n // select text\n if (isIos) {\n const range = document.createRange();\n range.selectNodeContents(textarea);\n\n const selection = window.getSelection();\n if (selection) {\n selection.removeAllRanges();\n selection.addRange(range);\n }\n textarea.setSelectionRange(0, 999999);\n } else {\n textarea.select();\n }\n\n // copy selection\n document.execCommand(\"copy\");\n\n // cleanup\n document.body.removeChild(textarea);\n};\n\nexport const Code: Components[\"code\"] = ({ children, className, inline }) => {\n const directives = useDirectives();\n if (className === \"language-mermaid\" && directives[\"mermaid\"]) {\n const Mermaid = directives[\"mermaid\"];\n return <Mermaid children={children} />;\n }\n\n const ref = useRef<HTMLElement>(null);\n const [copied, setCopied] = useState(false);\n const copyCode = () => {\n if (ref.current) {\n const text = ref.current.innerText;\n if (navigator.clipboard) {\n navigator.clipboard\n .writeText(text)\n .then(() => {\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n })\n .catch(() => {\n copyNoNavigator(text);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n });\n } else {\n copyNoNavigator(text);\n setCopied(true);\n setTimeout(() => setCopied(false), 2000);\n }\n }\n };\n\n return inline ? (\n <span className=\"inline\">\n <code ref={ref} className={className}>\n {children}\n </code>\n <button className=\"copy\" onClick={copyCode} aria-label=\"Copy Code\">\n {copied ? <MdDone /> : <MdContentCopy />}\n </button>\n </span>\n ) : (\n <Fragment>\n <code ref={ref} className={className}>\n {children}\n </code>\n <button className=\"copy\" onClick={copyCode} aria-label=\"Copy Code\">\n {copied ? <MdDone /> : <MdContentCopy />}\n </button>\n </Fragment>\n );\n};\n", "import { useLink } from \"@hyperbook/provider\";\nimport { ReactNode } from \"react\";\nimport { Components } from \"react-markdown\";\n\n// see: https://css-tricks.com/better-line-breaks-for-long-urls/\nfunction formatUrl(url: ReactNode) {\n if (typeof url !== \"string\") {\n return url;\n }\n // Split the URL into an array to distinguish double slashes from single slashes\n var doubleSlash = url.split(\"//\");\n\n // Format the strings on either side of double slashes separately\n var formatted = doubleSlash\n .map(\n (str) =>\n // Insert a word break opportunity after a colon\n str\n .replace(/(?<after>:)/giu, \"$1<wbr>\")\n // Before a single slash, tilde, period, comma, hyphen, underline, question mark, number sign, or percent symbol\n .replace(/(?<before>[/~.,\\-_?#%])/giu, \"<wbr>$1\")\n // Before and after an equals sign or ampersand\n .replace(/(?<beforeAndAfter>[=&])/giu, \"<wbr>$1<wbr>\")\n // Reconnect the strings with word break opportunities after double slashes\n )\n .join(\"//<wbr>\");\n\n return formatted;\n}\n\nexport const Link: Components[\"a\"] = ({ href, title, children }) => {\n const L = useLink();\n\n return (\n <L href={href} title={title}>\n {formatUrl(children)}\n </L>\n );\n};\n", "import { ReactNode } from \"react\";\nimport { Components } from \"react-markdown\";\n\nlet tableHeaders: ReactNode[][] = [];\nlet tdIndex = 0;\n\nexport const Table: Components[\"table\"] = ({ children, style }) => {\n tableHeaders = [];\n return <table style={style}>{children}</table>;\n};\n\nexport const Tr: Components[\"tr\"] = ({ children, style }) => {\n tdIndex = 0;\n return <tr style={style}>{children}</tr>;\n};\n\nexport const Td: Components[\"td\"] = ({ children, style }) => {\n return (\n <td data-label={tableHeaders[tdIndex++]} style={style}>\n {children}\n </td>\n );\n};\n\nexport const Th: Components[\"th\"] = ({ children, style }) => {\n tableHeaders.push(children);\n return <th style={style}>{children}</th>;\n};\n", "import { useBookmark, useConfig } from \"@hyperbook/provider\";\nimport { Components } from \"react-markdown\";\n\nexport const makeAnchor = (heading: string) => {\n // If we have a heading, make it lower case\n let anchor = heading.toLowerCase();\n\n // Clean anchor (replace special characters whitespaces).\n // Alternatively, use encodeURIComponent() if you don't care about\n // pretty anchor links\n anchor = anchor.replace(/[^a-zA-Z0-9 ]/g, \"\");\n anchor = anchor.replace(/ /g, \"-\");\n\n return anchor;\n};\n\nexport const Headings: Components[\"h1\"] = ({ level, children, id }) => {\n const config = useConfig();\n const bookmarksConfig = config?.elements?.bookmarks;\n // Access actual (string) value of heading\n const heading = children?.[0] || \"\";\n\n // If we have a heading, make it lower case\n let anchor = typeof heading === \"string\" ? makeAnchor(heading) : \"\";\n\n const label = typeof heading === \"string\" ? heading : anchor;\n\n const [bookmark, toggleBookmark] = useBookmark(anchor, label);\n\n // Utility\n const container = (children: React.ReactNode): JSX.Element => (\n <>\n <a className=\"heading\" id={id ?? anchor} href={`#${id ?? anchor}`}>\n <span>{children}</span>\n </a>\n {bookmarksConfig !== false && (\n <button\n className={bookmark ? \"bookmark active\" : \"bookmark\"}\n onClick={() => toggleBookmark()}\n title=\"Bookmark\"\n >\n \uD83D\uDD16\n </button>\n )}\n </>\n );\n\n switch (level) {\n case 1:\n return <h1>{container(children)}</h1>;\n case 2:\n return <h2>{container(children)}</h2>;\n case 3:\n return <h3>{container(children)}</h3>;\n case 4:\n return <h4>{container(children)}</h4>;\n case 5:\n return <h5>{container(children)}</h5>;\n\n default:\n return <h6>{container(children)}</h6>;\n }\n};\n", "import { useMakeUrl } from \"@hyperbook/provider\";\nimport { useState } from \"react\";\nimport { Components } from \"react-markdown\";\n\nexport const Image: Components[\"img\"] = ({ src, title, alt }) => {\n const makeUrl = useMakeUrl();\n const [full, setFull] = useState(false);\n src = makeUrl(src, \"public\");\n\n return (\n <figure className={full ? \"lightbox\" : undefined}>\n <img src={src} alt={alt} onClick={() => setFull((f) => !f)} />\n {title && <figcaption>{title}</figcaption>}\n </figure>\n );\n};\n", "//@ts-nocheck\nimport { visit, SKIP } from \"unist-util-visit\";\nimport { Transformer } from \"unified\";\nimport { BuildVisitor } from \"unist-util-visit/complex-types\";\n\nexport const remarkRemoveComments: () => Transformer = () => (tree) => {\n const htmlCommentRegex = /<!--([\\s\\S]*?)-->/g;\n\n const handler: BuildVisitor = (node, index, parent) => {\n const isComment = node.value.match(htmlCommentRegex);\n\n if (isComment) {\n // remove node\n parent.children.splice(index, 1);\n // Do not traverse `node`, continue at the node *now* at `index`. http://unifiedjs.com/learn/recipe/remove-node/\n return [SKIP, index];\n }\n };\n\n visit(tree, \"html\", handler);\n\n visit(tree, \"jsx\", handler);\n};\n", "import { visit } from \"unist-util-visit\";\nimport { Transformer } from \"unified\";\n\nexport const remarkCustomHeadingIds: () => Transformer = () => {\n return function (node) {\n visit(node, \"heading\", (node) => {\n let lastChild = node.children[node.children.length - 1];\n if (lastChild && lastChild.type === \"text\") {\n let string = lastChild.value.replace(/ +$/, \"\");\n let matched = string.match(/ {#([^]+?)}$/);\n\n if (matched) {\n let id = matched[1];\n if (!!id.length) {\n if (!node.data) {\n node.data = {};\n }\n if (!node.data.hProperties) {\n node.data.hProperties = {};\n }\n node.data.id = node.data.hProperties.id = id;\n\n string = string.substring(0, matched.index);\n lastChild.value = string;\n }\n }\n }\n });\n };\n};\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;;;AAAA,OAAO,mBAAmB;AAC1B,OAAO,qBAAqB;AAC5B,OAAO,2BAA2B;AAClC,OAAO,eAAe;AACtB,OAAO,gBAAgB;AACvB,OAAO,kBAAkB;AACzB,OAAO,wBAAwB;AAC/B,OAAO,iBAAiB;AACxB,OAAO,qBAAqB;AAC5B,SAAS,iBAAAA,sBAAqB;;;ACT9B,SAAS,qBAAqB;AAC9B,SAAS,UAAU,QAAQ,gBAAgB;AAKvC,SASE,KATF;AAFJ,IAAM,gBAAgB,MAAM;AAC1B,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,MAAK;AAAA,MACL,aAAY;AAAA,MACZ,QAAO;AAAA,MACP,OAAM;AAAA,MACN,SAAQ;AAAA,MAER;AAAA,4BAAC,UAAK,GAAE,iBAAgB,MAAK,QAAO;AAAA,QACpC,oBAAC,UAAK,GAAE,mIAAkI;AAAA;AAAA;AAAA,EAC5I;AAEJ;AAEA,IAAM,SAAS,MAAM;AACnB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OAAM;AAAA,MACN,QAAO;AAAA,MACP,MAAK;AAAA,MACL,aAAY;AAAA,MACZ,QAAO;AAAA,MACP,OAAM;AAAA,MACN,SAAQ;AAAA,MAER;AAAA,4BAAC,UAAK,GAAE,iBAAgB,MAAK,QAAO;AAAA,QACpC,oBAAC,UAAK,GAAE,sDAAqD;AAAA;AAAA;AAAA,EAC/D;AAEJ;AAEA,IAAM,kBAAkB,CAAC,SAAiB;AACxC,QAAM,QAAQ,UAAU,UAAU,MAAM,cAAc;AACtD,QAAM,WAAW,SAAS,cAAc,UAAU;AAGlD,WAAS,QAAQ;AAGjB,WAAS,MAAM,WAAW;AAC1B,WAAS,KAAK,YAAY,QAAQ;AAGlC,MAAI,OAAO;AACT,UAAM,QAAQ,SAAS,YAAY;AACnC,UAAM,mBAAmB,QAAQ;AAEjC,UAAM,YAAY,OAAO,aAAa;AACtC,QAAI,WAAW;AACb,gBAAU,gBAAgB;AAC1B,gBAAU,SAAS,KAAK;AAAA,IAC1B;AACA,aAAS,kBAAkB,GAAG,MAAM;AAAA,EACtC,OAAO;AACL,aAAS,OAAO;AAAA,EAClB;AAGA,WAAS,YAAY,MAAM;AAG3B,WAAS,KAAK,YAAY,QAAQ;AACpC;AAEO,IAAM,OAA2B,CAAC,EAAE,UAAU,WAAW,OAAO,MAAM;AAC3E,QAAM,aAAa,cAAc;AACjC,MAAI,cAAc,sBAAsB,WAAW,SAAS,GAAG;AAC7D,UAAM,UAAU,WAAW,SAAS;AACpC,WAAO,oBAAC,WAAQ,UAAoB;AAAA,EACtC;AAEA,QAAM,MAAM,OAAoB,IAAI;AACpC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAC1C,QAAM,WAAW,MAAM;AACrB,QAAI,IAAI,SAAS;AACf,YAAM,OAAO,IAAI,QAAQ;AACzB,UAAI,UAAU,WAAW;AACvB,kBAAU,UACP,UAAU,IAAI,EACd,KAAK,MAAM;AACV,oBAAU,IAAI;AACd,qBAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,QACzC,CAAC,EACA,MAAM,MAAM;AACX,0BAAgB,IAAI;AACpB,oBAAU,IAAI;AACd,qBAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,QACzC,CAAC;AAAA,MACL,OAAO;AACL,wBAAgB,IAAI;AACpB,kBAAU,IAAI;AACd,mBAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,MACzC;AAAA,IACF;AAAA,EACF;AAEA,SAAO,SACL,qBAAC,UAAK,WAAU,UACd;AAAA,wBAAC,UAAK,KAAU,WACb,UACH;AAAA,IACA,oBAAC,YAAO,WAAU,QAAO,SAAS,UAAU,cAAW,aACpD,mBAAS,oBAAC,UAAO,IAAK,oBAAC,iBAAc,GACxC;AAAA,KACF,IAEA,qBAAC,YACC;AAAA,wBAAC,UAAK,KAAU,WACb,UACH;AAAA,IACA,oBAAC,YAAO,WAAU,QAAO,SAAS,UAAU,cAAW,aACpD,mBAAS,oBAAC,UAAO,IAAK,oBAAC,iBAAc,GACxC;AAAA,KACF;AAEJ;;;AC1HA,SAAS,eAAe;AAkCpB,gBAAAC,YAAA;AA7BJ,SAAS,UAAU,KAAgB;AACjC,MAAI,OAAO,QAAQ,UAAU;AAC3B,WAAO;AAAA,EACT;AAEA,MAAI,cAAc,IAAI,MAAM,IAAI;AAGhC,MAAI,YAAY,YACb;AAAA,IACC,CAAC;AAAA;AAAA,MAEC,IACG,QAAQ,WAAC,eAAY,KAAG,GAAE,SAAS,EAEnC,QAAQ,WAAC,4BAAwB,KAAG,GAAE,SAAS,EAE/C,QAAQ,WAAC,2BAAwB,KAAG,GAAE,cAAc;AAAA;AAAA;AAAA,EAE3D,EACC,KAAK,SAAS;AAEjB,SAAO;AACT;AAEO,IAAM,OAAwB,CAAC,EAAE,MAAM,OAAO,SAAS,MAAM;AAClE,QAAM,IAAI,QAAQ;AAElB,SACE,gBAAAA,KAAC,KAAE,MAAY,OACZ,oBAAU,QAAQ,GACrB;AAEJ;;;AC9BS,gBAAAC,YAAA;AALT,IAAI,eAA8B,CAAC;AACnC,IAAI,UAAU;AAEP,IAAM,QAA6B,CAAC,EAAE,UAAU,MAAM,MAAM;AACjE,iBAAe,CAAC;AAChB,SAAO,gBAAAA,KAAC,WAAM,OAAe,UAAS;AACxC;AAEO,IAAM,KAAuB,CAAC,EAAE,UAAU,MAAM,MAAM;AAC3D,YAAU;AACV,SAAO,gBAAAA,KAAC,QAAG,OAAe,UAAS;AACrC;AAEO,IAAM,KAAuB,CAAC,EAAE,UAAU,MAAM,MAAM;AAC3D,SACE,gBAAAA,KAAC,QAAG,cAAY,aAAa,SAAS,GAAG,OACtC,UACH;AAEJ;AAEO,IAAM,KAAuB,CAAC,EAAE,UAAU,MAAM,MAAM;AAC3D,eAAa,KAAK,QAAQ;AAC1B,SAAO,gBAAAA,KAAC,QAAG,OAAe,UAAS;AACrC;;;AC3BA,SAAS,aAAa,iBAAiB;AA+BnC,qBAAAC,WAEI,OAAAC,MAFJ,QAAAC,aAAA;AA5BG,IAAM,aAAa,CAAC,YAAoB;AAE7C,MAAI,SAAS,QAAQ,YAAY;AAKjC,WAAS,OAAO,QAAQ,kBAAkB,EAAE;AAC5C,WAAS,OAAO,QAAQ,MAAM,GAAG;AAEjC,SAAO;AACT;AAEO,IAAM,WAA6B,CAAC,EAAE,OAAO,UAAU,GAAG,MAAM;AAhBvE;AAiBE,QAAM,SAAS,UAAU;AACzB,QAAM,mBAAkB,sCAAQ,aAAR,mBAAkB;AAE1C,QAAM,WAAU,qCAAW,OAAM;AAGjC,MAAI,SAAS,OAAO,YAAY,WAAW,WAAW,OAAO,IAAI;AAEjE,QAAM,QAAQ,OAAO,YAAY,WAAW,UAAU;AAEtD,QAAM,CAAC,UAAU,cAAc,IAAI,YAAY,QAAQ,KAAK;AAG5D,QAAM,YAAY,CAACC,cACjB,gBAAAD,MAAAF,WAAA,EACE;AAAA,oBAAAC,KAAC,OAAE,WAAU,WAAU,IAAI,kBAAM,QAAQ,MAAM,IAAI,kBAAM,UACvD,0BAAAA,KAAC,UAAM,UAAAE,WAAS,GAClB;AAAA,IACC,oBAAoB,SACnB,gBAAAF;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,WAAW,oBAAoB;AAAA,QAC1C,SAAS,MAAM,eAAe;AAAA,QAC9B,OAAM;AAAA,QACP;AAAA;AAAA,IAED;AAAA,KAEJ;AAGF,UAAQ,OAAO;AAAA,IACb,KAAK;AACH,aAAO,gBAAAA,KAAC,QAAI,oBAAU,QAAQ,GAAE;AAAA,IAClC,KAAK;AACH,aAAO,gBAAAA,KAAC,QAAI,oBAAU,QAAQ,GAAE;AAAA,IAClC,KAAK;AACH,aAAO,gBAAAA,KAAC,QAAI,oBAAU,QAAQ,GAAE;AAAA,IAClC,KAAK;AACH,aAAO,gBAAAA,KAAC,QAAI,oBAAU,QAAQ,GAAE;AAAA,IAClC,KAAK;AACH,aAAO,gBAAAA,KAAC,QAAI,oBAAU,QAAQ,GAAE;AAAA,IAElC;AACE,aAAO,gBAAAA,KAAC,QAAI,oBAAU,QAAQ,GAAE;AAAA,EACpC;AACF;;;AC9DA,SAAS,kBAAkB;AAC3B,SAAS,YAAAG,iBAAgB;AASrB,SACE,OAAAC,MADF,QAAAC,aAAA;AANG,IAAM,QAA2B,CAAC,EAAE,KAAK,OAAO,IAAI,MAAM;AAC/D,QAAM,UAAU,WAAW;AAC3B,QAAM,CAAC,MAAM,OAAO,IAAIF,UAAS,KAAK;AACtC,QAAM,QAAQ,KAAK,QAAQ;AAE3B,SACE,gBAAAE,MAAC,YAAO,WAAW,OAAO,aAAa,QACrC;AAAA,oBAAAD,KAAC,SAAI,KAAU,KAAU,SAAS,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC,GAAG;AAAA,IAC3D,SAAS,gBAAAA,KAAC,gBAAY,iBAAM;AAAA,KAC/B;AAEJ;;;ACdA,SAAS,OAAO,YAAY;AAIrB,IAAM,uBAA0C,MAAM,CAAC,SAAS;AACrE,QAAM,mBAAmB;AAEzB,QAAM,UAAwB,CAAC,MAAM,OAAO,WAAW;AACrD,UAAM,YAAY,KAAK,MAAM,MAAM,gBAAgB;AAEnD,QAAI,WAAW;AAEb,aAAO,SAAS,OAAO,OAAO,CAAC;AAE/B,aAAO,CAAC,MAAM,KAAK;AAAA,IACrB;AAAA,EACF;AAEA,QAAM,MAAM,QAAQ,OAAO;AAE3B,QAAM,MAAM,OAAO,OAAO;AAC5B;;;ACtBA,SAAS,SAAAE,cAAa;AAGf,IAAM,yBAA4C,MAAM;AAC7D,SAAO,SAAU,MAAM;AACrB,IAAAA,OAAM,MAAM,WAAW,CAACC,UAAS;AAC/B,UAAI,YAAYA,MAAK,SAASA,MAAK,SAAS,SAAS,CAAC;AACtD,UAAI,aAAa,UAAU,SAAS,QAAQ;AAC1C,YAAI,SAAS,UAAU,MAAM,QAAQ,OAAO,EAAE;AAC9C,YAAI,UAAU,OAAO,MAAM,cAAc;AAEzC,YAAI,SAAS;AACX,cAAI,KAAK,QAAQ,CAAC;AAClB,cAAI,CAAC,CAAC,GAAG,QAAQ;AACf,gBAAI,CAACA,MAAK,MAAM;AACd,cAAAA,MAAK,OAAO,CAAC;AAAA,YACf;AACA,gBAAI,CAACA,MAAK,KAAK,aAAa;AAC1B,cAAAA,MAAK,KAAK,cAAc,CAAC;AAAA,YAC3B;AACA,YAAAA,MAAK,KAAK,KAAKA,MAAK,KAAK,YAAY,KAAK;AAE1C,qBAAS,OAAO,UAAU,GAAG,QAAQ,KAAK;AAC1C,sBAAU,QAAQ;AAAA,UACpB;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAAA,EACH;AACF;;;APDI,gBAAAC,YAAA;AAJG,IAAM,WAAW,CAAC,EAAE,SAAS,MAAqB;AACvD,QAAM,aAAaC,eAAc;AAEjC,SACE,gBAAAD;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,YAAY,iCACP,aADO;AAAA,QAEV,GAAG;AAAA,QACH,MAAM;AAAA,QACN,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,IAAI;AAAA,QACJ,KAAK;AAAA,MACP;AAAA,MACA,eAAe;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA,eAAe;AAAA,QACb;AAAA,QACA,CAAC,iBAAiB,EAAE,eAAe,MAAM,WAAW,CAAC,SAAS,EAAE,CAAC;AAAA,MACnE;AAAA,MACA,UAAU;AAAA,MAET;AAAA;AAAA,EACH;AAEJ;",
6
+ "names": ["useDirectives", "jsx", "jsx", "Fragment", "jsx", "jsxs", "children", "useState", "jsx", "jsxs", "visit", "node", "jsx", "useDirectives"]
7
7
  }
@@ -0,0 +1,2 @@
1
+ import { Transformer } from "unified";
2
+ export declare const remarkCustomHeadingIds: () => Transformer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyperbook/markdown",
3
- "version": "0.5.3",
3
+ "version": "0.6.0",
4
4
  "author": "Mike Barkmin",
5
5
  "homepage": "https://github.com/openpatch/hyperbook#readme",
6
6
  "license": "MIT",
@@ -33,16 +33,14 @@
33
33
  },
34
34
  "dependencies": {
35
35
  "@hyperbook/provider": "0.2.1",
36
- "react-markdown": "8.0.4",
36
+ "react-markdown": "8.0.5",
37
37
  "rehype-highlight": "5.0.2",
38
38
  "rehype-katex": "6.0.2",
39
39
  "remark-directive": "2.0.1",
40
40
  "remark-directive-rehype": "0.4.2",
41
41
  "remark-gemoji": "7.0.1",
42
- "remark-gfm": "3.0.1",
43
42
  "remark-math": "5.1.1",
44
43
  "remark-unwrap-images": "3.0.1",
45
- "unified": "^10.1.2",
46
44
  "unist-util-visit": "^4.1.1"
47
45
  },
48
46
  "peerDependencies": {
@@ -51,16 +49,23 @@
51
49
  },
52
50
  "devDependencies": {
53
51
  "@types/hast": "2.3.4",
54
- "@types/react": "18.0.26",
52
+ "@types/react": "18.0.27",
55
53
  "@types/react-dom": "18.0.10",
56
54
  "@types/unist": "2.0.6",
57
55
  "react": "18.2.0",
58
- "react-dom": "18.2.0"
56
+ "react-dom": "18.2.0",
57
+ "rehype-stringify": "^9.0.3",
58
+ "remark-gfm": "3.0.1",
59
+ "remark-parse": "^10.0.1",
60
+ "remark-rehype": "^10.1.0",
61
+ "unified": "^10.1.2",
62
+ "vitest": "^0.27.0"
59
63
  },
60
64
  "scripts": {
61
65
  "prebuild": "rimraf dist",
62
66
  "version": "pnpm build",
63
67
  "lint": "tsc --noEmit",
68
+ "test": "vitest",
64
69
  "build": "pnpm build:pkg && pnpm build:types",
65
70
  "build:pkg": "node ../../scripts/build.mjs && cp -r assets dist/",
66
71
  "build:types": "tsc --project tsconfig.build.json --declaration --emitDeclarationOnly"