@scalar/code-highlight 0.1.4 → 0.1.5
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 +6 -0
- package/dist/markdown/markdown.js +2 -2
- package/dist/markdown/markdown.js.map +2 -2
- package/dist/rehype-alert/rehype-alert.d.ts.map +1 -1
- package/dist/rehype-alert/rehype-alert.js.map +2 -2
- package/dist/rehype-highlight/rehype-highlight.d.ts +1 -1
- package/dist/rehype-highlight/rehype-highlight.d.ts.map +1 -1
- package/dist/rehype-highlight/rehype-highlight.js +1 -1
- package/dist/rehype-highlight/rehype-highlight.js.map +2 -2
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -10,8 +10,8 @@ import remarkStringify from "remark-stringify";
|
|
|
10
10
|
import { unified } from "unified";
|
|
11
11
|
import { SKIP, visit } from "unist-util-visit";
|
|
12
12
|
import { standardLanguages } from "../languages/index.js";
|
|
13
|
-
import { rehypeHighlight } from "../rehype-highlight/index.js";
|
|
14
13
|
import { rehypeAlert } from "../rehype-alert/index.js";
|
|
14
|
+
import { rehypeHighlight } from "../rehype-highlight/index.js";
|
|
15
15
|
const transformNodes = (options, ..._ignored) => (tree) => {
|
|
16
16
|
if (!options?.transform || !options?.type) {
|
|
17
17
|
return;
|
|
@@ -32,7 +32,7 @@ function htmlFromMarkdown(markdown, options) {
|
|
|
32
32
|
type: options?.transformType
|
|
33
33
|
}).use(remarkRehype, { allowDangerousHtml: true }).use(rehypeAlert).use(rehypeRaw).use(rehypeSanitize, {
|
|
34
34
|
...defaultSchema,
|
|
35
|
-
// Don
|
|
35
|
+
// Don't prefix the heading ids
|
|
36
36
|
clobberPrefix: "",
|
|
37
37
|
// Makes it even more strict
|
|
38
38
|
tagNames,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/markdown/markdown.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Heading, PhrasingContent, Root, RootContent, Text } from 'mdast'\nimport rehypeExternalLinks from 'rehype-external-links'\nimport rehypeFormat from 'rehype-format'\nimport rehypeRaw from 'rehype-raw'\nimport rehypeSanitize, { defaultSchema } from 'rehype-sanitize'\nimport rehypeStringify from 'rehype-stringify'\nimport remarkGfm from 'remark-gfm'\nimport remarkParse from 'remark-parse'\nimport remarkRehype from 'remark-rehype'\nimport remarkStringify from 'remark-stringify'\nimport { unified } from 'unified'\nimport type { Node } from 'unist'\nimport { SKIP, visit } from 'unist-util-visit'\n\nimport { standardLanguages } from '@/languages'\nimport {
|
|
5
|
-
"mappings": "AACA,OAAO,yBAAyB;AAChC,OAAO,kBAAkB;AACzB,OAAO,eAAe;AACtB,OAAO,kBAAkB,qBAAqB;AAC9C,OAAO,qBAAqB;AAC5B,OAAO,eAAe;AACtB,OAAO,iBAAiB;AACxB,OAAO,kBAAkB;AACzB,OAAO,qBAAqB;AAC5B,SAAS,eAAe;AAExB,SAAS,MAAM,aAAa;AAE5B,SAAS,yBAAyB;AAClC,SAAS,
|
|
4
|
+
"sourcesContent": ["import type { Heading, PhrasingContent, Root, RootContent, Text } from 'mdast'\nimport rehypeExternalLinks from 'rehype-external-links'\nimport rehypeFormat from 'rehype-format'\nimport rehypeRaw from 'rehype-raw'\nimport rehypeSanitize, { defaultSchema } from 'rehype-sanitize'\nimport rehypeStringify from 'rehype-stringify'\nimport remarkGfm from 'remark-gfm'\nimport remarkParse from 'remark-parse'\nimport remarkRehype from 'remark-rehype'\nimport remarkStringify from 'remark-stringify'\nimport { unified } from 'unified'\nimport type { Node } from 'unist'\nimport { SKIP, visit } from 'unist-util-visit'\n\nimport { standardLanguages } from '@/languages'\nimport { rehypeAlert } from '@/rehype-alert'\nimport { rehypeHighlight } from '@/rehype-highlight'\ntype Options = {\n transform?: (node: Record<string, any>) => Record<string, any>\n type?: string\n}\n\n/**\n * Plugin to transform nodes in a Markdown AST\n */\nconst transformNodes =\n (options?: Readonly<Options> | null | undefined, ..._ignored: any[]) =>\n (tree: Node) => {\n if (!options?.transform || !options?.type) {\n return\n }\n\n visit(tree, options?.type, (node) => {\n options?.transform ? options?.transform(node) : node\n\n return SKIP\n })\n\n return\n }\n\n/**\n * Take a Markdown string and generate HTML from it\n */\nexport function htmlFromMarkdown(\n markdown: string,\n options?: {\n removeTags?: string[]\n allowTags?: string[]\n transform?: (node: Record<string, any>) => Record<string, any>\n transformType?: string\n },\n) {\n // Add permitted tags and remove stripped ones\n const removeTags = options?.removeTags ?? []\n const tagNames = [...(defaultSchema.tagNames ?? []), ...(options?.allowTags ?? [])].filter(\n (t) => !removeTags.includes(t),\n )\n\n const html = unified()\n // Parses markdown\n .use(remarkParse)\n // Support autolink literals, footnotes, strikethrough, tables and tasklists\n .use(remarkGfm)\n .use(transformNodes, {\n transform: options?.transform,\n type: options?.transformType,\n })\n // Allows any HTML tags\n .use(remarkRehype, { allowDangerousHtml: true })\n // Adds GitHub alerts\n .use(rehypeAlert)\n // Creates a HTML AST\n .use(rehypeRaw)\n // Removes disallowed tags\n .use(rehypeSanitize, {\n ...defaultSchema,\n // Don't prefix the heading ids\n clobberPrefix: '',\n // Makes it even more strict\n tagNames,\n attributes: {\n ...defaultSchema.attributes,\n abbr: ['title'],\n // Allow alert classes\n div: ['class', ['className', /^markdown-alert(-.*)?$/]],\n },\n })\n // Syntax highlighting\n .use(rehypeHighlight, {\n languages: standardLanguages,\n // Enable auto detection\n detect: true,\n })\n // Adds target=\"_blank\" to external links\n .use(rehypeExternalLinks, { target: '_blank' })\n // Formats the HTML\n .use(rehypeFormat)\n // Converts the HTML AST to a string\n .use(rehypeStringify)\n // Run the pipeline\n .processSync(markdown)\n\n return html.toString()\n}\n\n/**\n * Create a Markdown AST from a string.\n */\nfunction getMarkdownAst(markdown: string): Root {\n return unified().use(remarkParse).use(remarkGfm).parse(markdown)\n}\n\n/**\n * Find all headings of a specific type in a Markdown AST.\n */\nexport function getHeadings(\n markdown: string,\n depth: number = 1,\n): {\n depth: number\n value: string\n}[] {\n const tree = getMarkdownAst(markdown)\n\n const nodes: {\n depth: number\n value: string\n }[] = []\n\n visit(tree, 'heading', (node) => {\n const text = findTextInHeading(node)\n\n if (text) {\n nodes.push({ depth: node.depth ?? depth, value: text.value })\n }\n })\n\n return nodes\n}\n\n/**\n * Find the text in a Markdown node (recursively).\n */\nfunction findTextInHeading(node: Heading | PhrasingContent): Text | null {\n if (node.type === 'text') {\n return node as Text\n }\n\n if ('children' in node && node.children) {\n for (const child of node.children) {\n const text = findTextInHeading(child)\n\n if (text) {\n return text\n }\n }\n }\n\n return null\n}\n\n/**\n * Return multiple Markdown documents. Every heading should be its own document.\n */\nexport function splitContent(markdown: string) {\n const tree = getMarkdownAst(markdown)\n\n /** Sections */\n const sections: RootContent[][] = []\n\n /** Nodes inside a section */\n let nodes: RootContent[] = []\n\n tree.children?.forEach((node) => {\n // If the node is a heading, start a new section\n if (node.type === 'heading') {\n if (nodes.length) {\n sections.push(nodes)\n }\n\n sections.push([node])\n\n nodes = []\n }\n // Otherwise, add the node to the current section\n else {\n nodes.push(node)\n }\n })\n\n // Add any remaining nodes\n if (nodes.length) {\n sections.push(nodes)\n }\n\n return sections.map((section) => createDocument(section))\n}\n\n/**\n * Use remark to create a Markdown document from a list of nodes.\n */\nfunction createDocument(nodes: RootContent[]) {\n // Create the Markdown string\n const markdown = unified().use(remarkStringify).use(remarkGfm).stringify({\n type: 'root',\n children: nodes,\n })\n\n // Remove the whitespace\n return markdown.trim()\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rehype-alert.d.ts","sourceRoot":"","sources":["../../src/rehype-alert/rehype-alert.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"rehype-alert.d.ts","sourceRoot":"","sources":["../../src/rehype-alert/rehype-alert.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAA;AAUjC,wBAAgB,WAAW,WACX,IAAI,UAgGnB"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/rehype-alert/rehype-alert.ts"],
|
|
4
|
-
"sourcesContent": ["import {
|
|
5
|
-
"mappings": "
|
|
4
|
+
"sourcesContent": ["import type { Element } from 'hast'\nimport type { Root } from 'mdast'\nimport { visit } from 'unist-util-visit'\n\nconst ALERT_TYPES = ['note', 'tip', 'important', 'warning', 'caution', 'success'] as const\n\n// Simple whitespace check function\nfunction isWhitespace(node: any): boolean {\n return node.type === 'text' && typeof node.value === 'string' && /^\\s*$/.test(node.value)\n}\n\nexport function rehypeAlert() {\n return (tree: Root) => {\n visit(tree, 'element', (node: Element, index, parent: any) => {\n if (node.tagName !== 'blockquote' || typeof index !== 'number' || !parent || parent.type !== 'root') {\n return\n }\n\n // Find the first non-whitespace child\n const headIndex = node.children.findIndex((child) => !isWhitespace(child))\n if (headIndex === -1) {\n return\n }\n\n const head = node.children[headIndex]\n\n if (!head || head.type !== 'element' || head.tagName !== 'p') {\n return\n }\n\n const text = head.children[0]\n if (!text || text.type !== 'text' || !text.value.startsWith('[!')) {\n return\n }\n\n const end = text.value.indexOf(']')\n if (end === -1) {\n return\n }\n\n // Extract the alert type\n const alertType = text.value.slice(2, end).toLowerCase() as (typeof ALERT_TYPES)[number]\n if (!ALERT_TYPES.includes(alertType)) {\n return\n }\n\n // Remove the blockquote if it's empty\n if (end + 1 === text.value.length) {\n const next = head.children[1]\n if (next) {\n if (next.type !== 'element' || next.tagName !== 'br') {\n return\n }\n if (!head.children[2]) {\n return\n }\n head.children = head.children.slice(2)\n const node = head.children[0]\n if (node && node.type === 'text' && node.value.charAt(0) === '\\n') {\n node.value = node.value.slice(1)\n }\n } else {\n const skipped = headIndex + 1 < node.children.length && isWhitespace(node.children[headIndex + 1])\n const nextIndex = skipped ? headIndex + 2 : headIndex + 1\n if (nextIndex >= node.children.length || node.children[nextIndex].type !== 'element') {\n return\n }\n\n node.children = node.children.slice(nextIndex)\n }\n } else if (\n text.value.charAt(end + 1) === '\\n' &&\n // Check if the next character is a newline or a non-whitespace character\n (end + 2 === text.value.length || !/^\\s*$/.test(text.value.slice(end + 2)))\n ) {\n text.value = text.value.slice(end + 2)\n } else {\n // Remove the alert marker if it's not followed by a newline or a non-whitespace character\n text.value = text.value.replace(/^\\s*\\[!.*?\\]\\s*/, '')\n }\n\n // Extract content from paragraphs to avoid wrapping in <p> tags\n const contentChildren = []\n for (let i = headIndex; i < node.children.length; i++) {\n const child = node.children[i]\n if (child.type === 'element' && child.tagName === 'p' && child.children) {\n contentChildren.push(...child.children)\n } else {\n contentChildren.push(child)\n }\n }\n\n // Replace the blockquote with a div containing the alert\n parent.children[index] = {\n type: 'element',\n tagName: 'div',\n properties: { className: ['markdown-alert', `markdown-alert-${alertType}`] },\n children: [\n {\n type: 'element',\n tagName: 'div',\n properties: { className: ['markdown-alert-content'] },\n children: [{ type: 'text', value: ' ' }, ...contentChildren],\n },\n ],\n }\n })\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["node"]
|
|
7
7
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { Root } from 'hast';
|
|
2
|
-
import {
|
|
2
|
+
import { type LanguageFn, createLowlight } from 'lowlight';
|
|
3
3
|
import type { VFile } from 'vfile';
|
|
4
4
|
type HighlightOptions = {
|
|
5
5
|
/** Optional existing lowlight instance to use */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"rehype-highlight.d.ts","sourceRoot":"","sources":["../../src/rehype-highlight/rehype-highlight.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA2B,IAAI,EAAE,MAAM,MAAM,CAAA;AAEzD,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"rehype-highlight.d.ts","sourceRoot":"","sources":["../../src/rehype-highlight/rehype-highlight.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAA2B,IAAI,EAAE,MAAM,MAAM,CAAA;AAEzD,OAAO,EAAE,KAAK,UAAU,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAE1D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,CAAA;AAIlC,KAAK,gBAAgB,GAAG;IACtB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,UAAU,CAAC,OAAO,cAAc,CAAC,GAAG,SAAS,CAAA;IACxD,2EAA2E;IAC3E,OAAO,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAA;IACrF,2EAA2E;IAC3E,SAAS,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC,GAAG,IAAI,GAAG,SAAS,CAAA;IACnE,yGAAyG;IACzG,SAAS,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,CAAA;IACpD,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAA;IAClC,qFAAqF;IACrF,MAAM,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,GAAG,IAAI,GAAG,SAAS,CAAA;IACjD,qCAAqC;IACrC,MAAM,CAAC,EAAE,OAAO,CAAA;CACjB,CAAA;AAID;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,gBAAgB,CAAC,GAAG,IAAI,GAAG,SAAS,UAuBvE,IAAI,QAAQ,KAAK,UAsDhC"}
|
|
@@ -41,7 +41,7 @@ function rehypeHighlight(options) {
|
|
|
41
41
|
} catch (error) {
|
|
42
42
|
const cause = error;
|
|
43
43
|
if (lang && /Unknown language/.test(cause.message)) {
|
|
44
|
-
file.message(
|
|
44
|
+
file.message(`Cannot highlight as \`${lang}\`, it's not registered`, {
|
|
45
45
|
ancestors: [parent, node],
|
|
46
46
|
cause,
|
|
47
47
|
place: node.position,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/rehype-highlight/rehype-highlight.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Element, ElementContent, Root } from 'hast'\nimport { toText } from 'hast-util-to-text'\nimport {
|
|
5
|
-
"mappings": "AACA,SAAS,cAAc;AACvB,
|
|
4
|
+
"sourcesContent": ["import type { Element, ElementContent, Root } from 'hast'\nimport { toText } from 'hast-util-to-text'\nimport { type LanguageFn, createLowlight } from 'lowlight'\nimport { visit } from 'unist-util-visit'\nimport type { VFile } from 'vfile'\n\nimport { lowlightLanguageMappings } from '../constants'\n\ntype HighlightOptions = {\n /** Optional existing lowlight instance to use */\n lowlight?: ReturnType<typeof createLowlight> | undefined\n /** Register more aliases (optional); passed to `lowlight.registerAlias` */\n aliases?: Readonly<Record<string, ReadonlyArray<string> | string>> | null | undefined\n /** Register languages (default: `common`) passed to `lowlight.register` */\n languages?: Readonly<Record<string, LanguageFn>> | null | undefined\n /** List of language names to not highlight (optional). Note: you can also add `no-highlight` classes. */\n plainText?: ReadonlyArray<string> | null | undefined\n /** Class prefix (default: `'hljs-'`) */\n prefix?: string | null | undefined\n /** Names of languages to check when detecting (default: all registered languages) */\n subset?: ReadonlyArray<string> | null | undefined\n /** Option to autodetect languages */\n detect?: boolean\n}\n\nconst emptyOptions: HighlightOptions = {}\n\n/**\n * Lowlight syntax highlighting plugin for rehype pipelines\n *\n * Derived from: @url https://github.com/rehypejs/rehype-highlight/blob/main/lib/index.js\n */\nexport function rehypeHighlight(options?: Readonly<HighlightOptions> | null | undefined) {\n const settings = options || emptyOptions\n const aliases = settings.aliases\n const detect = options?.detect ?? false\n const languages = settings.languages\n const plainText = settings.plainText\n const prefix = settings.prefix\n const subset = settings.subset\n let name = 'hljs'\n\n // Create a lowlight instance if not provided\n const lowlight = options?.lowlight ?? createLowlight(languages)\n\n if (aliases) {\n lowlight.registerAlias(aliases)\n }\n\n if (prefix) {\n const pos = prefix.indexOf('-')\n name = pos > -1 ? prefix.slice(0, pos) : prefix\n }\n\n /** Transform.*/\n return (tree: Root, file: VFile) => {\n visit(tree, 'element', (node, _, parent) => {\n if (node.tagName !== 'code' || !parent || parent.type !== 'element' || parent.tagName !== 'pre') {\n return\n }\n\n const lang = language(node)\n\n if (lang === 'no-highlight' || (!lang && !detect) || (lang && plainText?.includes(lang))) {\n return\n }\n\n if (!Array.isArray(node.properties.className)) {\n node.properties.className = []\n }\n\n if (!node.properties.className.includes(name)) {\n node.properties.className.unshift(name)\n }\n\n let result: Root | undefined\n\n try {\n result = lang\n ? lowlight.highlight(lang, toText(parent), { prefix })\n : lowlight.highlightAuto(toText(parent), { prefix, subset })\n } catch (error) {\n const cause = error as Error\n\n if (lang && /Unknown language/.test(cause.message)) {\n file.message(`Cannot highlight as \\`${lang}\\`, it's not registered`, {\n ancestors: [parent, node],\n cause,\n place: node.position,\n ruleId: 'missing-language',\n source: 'rehype-highlight',\n })\n\n /* c8 ignore next 5 -- throw arbitrary hljs errors */\n return\n }\n\n throw cause\n }\n\n if (!lang && result.data?.language) {\n node.properties.className.push('language-' + result.data.language)\n }\n\n if (result.children.length > 0) {\n node.children = result.children as Array<ElementContent>\n }\n })\n }\n}\n\n/** Get the programming language of `node` or an empty string */\nfunction language(node: Element) {\n const list = node.properties.className\n\n if (!Array.isArray(list)) {\n return ''\n }\n\n const name: string = list.reduce<string>((result, _item) => {\n if (result) {\n return result\n }\n const item = String(_item)\n\n if (item === 'no-highlight' || item === 'nohighlight') {\n return 'no-highlight'\n }\n if (item.slice(0, 5) === 'lang-') {\n return item.slice(5)\n }\n if (item.slice(0, 9) === 'language-') {\n return item.slice(9)\n }\n\n return result\n }, '')\n\n return lowlightLanguageMappings[name || ''] || name\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,cAAc;AACvB,SAA0B,sBAAsB;AAChD,SAAS,aAAa;AAGtB,SAAS,gCAAgC;AAmBzC,MAAM,eAAiC,CAAC;AAOjC,SAAS,gBAAgB,SAAyD;AACvF,QAAM,WAAW,WAAW;AAC5B,QAAM,UAAU,SAAS;AACzB,QAAM,SAAS,SAAS,UAAU;AAClC,QAAM,YAAY,SAAS;AAC3B,QAAM,YAAY,SAAS;AAC3B,QAAM,SAAS,SAAS;AACxB,QAAM,SAAS,SAAS;AACxB,MAAI,OAAO;AAGX,QAAM,WAAW,SAAS,YAAY,eAAe,SAAS;AAE9D,MAAI,SAAS;AACX,aAAS,cAAc,OAAO;AAAA,EAChC;AAEA,MAAI,QAAQ;AACV,UAAM,MAAM,OAAO,QAAQ,GAAG;AAC9B,WAAO,MAAM,KAAK,OAAO,MAAM,GAAG,GAAG,IAAI;AAAA,EAC3C;AAGA,SAAO,CAAC,MAAY,SAAgB;AAClC,UAAM,MAAM,WAAW,CAAC,MAAM,GAAG,WAAW;AAC1C,UAAI,KAAK,YAAY,UAAU,CAAC,UAAU,OAAO,SAAS,aAAa,OAAO,YAAY,OAAO;AAC/F;AAAA,MACF;AAEA,YAAM,OAAO,SAAS,IAAI;AAE1B,UAAI,SAAS,kBAAmB,CAAC,QAAQ,CAAC,UAAY,QAAQ,WAAW,SAAS,IAAI,GAAI;AACxF;AAAA,MACF;AAEA,UAAI,CAAC,MAAM,QAAQ,KAAK,WAAW,SAAS,GAAG;AAC7C,aAAK,WAAW,YAAY,CAAC;AAAA,MAC/B;AAEA,UAAI,CAAC,KAAK,WAAW,UAAU,SAAS,IAAI,GAAG;AAC7C,aAAK,WAAW,UAAU,QAAQ,IAAI;AAAA,MACxC;AAEA,UAAI;AAEJ,UAAI;AACF,iBAAS,OACL,SAAS,UAAU,MAAM,OAAO,MAAM,GAAG,EAAE,OAAO,CAAC,IACnD,SAAS,cAAc,OAAO,MAAM,GAAG,EAAE,QAAQ,OAAO,CAAC;AAAA,MAC/D,SAAS,OAAO;AACd,cAAM,QAAQ;AAEd,YAAI,QAAQ,mBAAmB,KAAK,MAAM,OAAO,GAAG;AAClD,eAAK,QAAQ,yBAAyB,IAAI,2BAA2B;AAAA,YACnE,WAAW,CAAC,QAAQ,IAAI;AAAA,YACxB;AAAA,YACA,OAAO,KAAK;AAAA,YACZ,QAAQ;AAAA,YACR,QAAQ;AAAA,UACV,CAAC;AAGD;AAAA,QACF;AAEA,cAAM;AAAA,MACR;AAEA,UAAI,CAAC,QAAQ,OAAO,MAAM,UAAU;AAClC,aAAK,WAAW,UAAU,KAAK,cAAc,OAAO,KAAK,QAAQ;AAAA,MACnE;AAEA,UAAI,OAAO,SAAS,SAAS,GAAG;AAC9B,aAAK,WAAW,OAAO;AAAA,MACzB;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAGA,SAAS,SAAS,MAAe;AAC/B,QAAM,OAAO,KAAK,WAAW;AAE7B,MAAI,CAAC,MAAM,QAAQ,IAAI,GAAG;AACxB,WAAO;AAAA,EACT;AAEA,QAAM,OAAe,KAAK,OAAe,CAAC,QAAQ,UAAU;AAC1D,QAAI,QAAQ;AACV,aAAO;AAAA,IACT;AACA,UAAM,OAAO,OAAO,KAAK;AAEzB,QAAI,SAAS,kBAAkB,SAAS,eAAe;AACrD,aAAO;AAAA,IACT;AACA,QAAI,KAAK,MAAM,GAAG,CAAC,MAAM,SAAS;AAChC,aAAO,KAAK,MAAM,CAAC;AAAA,IACrB;AACA,QAAI,KAAK,MAAM,GAAG,CAAC,MAAM,aAAa;AACpC,aAAO,KAAK,MAAM,CAAC;AAAA,IACrB;AAEA,WAAO;AAAA,EACT,GAAG,EAAE;AAEL,SAAO,yBAAyB,QAAQ,EAAE,KAAK;AACjD;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"lowlight",
|
|
17
17
|
"highlightjs"
|
|
18
18
|
],
|
|
19
|
-
"version": "0.1.
|
|
19
|
+
"version": "0.1.5",
|
|
20
20
|
"engines": {
|
|
21
21
|
"node": ">=20"
|
|
22
22
|
},
|
|
@@ -97,8 +97,8 @@
|
|
|
97
97
|
"vfile": "^6.0.1",
|
|
98
98
|
"vite": "5.4.19",
|
|
99
99
|
"vue": "^3.5.12",
|
|
100
|
-
"@scalar/build-tooling": "0.2.
|
|
101
|
-
"@scalar/themes": "0.13.
|
|
100
|
+
"@scalar/build-tooling": "0.2.4",
|
|
101
|
+
"@scalar/themes": "0.13.8"
|
|
102
102
|
},
|
|
103
103
|
"scripts": {
|
|
104
104
|
"build": "scalar-build-esbuild",
|