diff --git a/dist/index.js b/dist/index.js index d0c5616..daba525 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1,5 +1,3 @@ -import { escapeHTML } from '@quartz-community/utils'; - // node_modules/hast-util-to-string/lib/index.js function toString(node) { if ("children" in node) { @@ -21,6 +19,14 @@ function all(node) { } return result.join(""); } +"function" == typeof Promise ? Promise.prototype.then.bind(Promise.resolve()) : setTimeout, Math.random().toString(8); + +// node_modules/@quartz-community/utils/dist/index.js +function escapeHTML(unsafe) { + return unsafe.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """).replaceAll("'", "'"); +} + +// src/transformer.ts var defaultOptions = { descriptionLength: 150, maxDescriptionLength: 300, diff --git a/dist/index.js.map b/dist/index.js.map index ee19bc5..4c313b2 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"sources":["../node_modules/hast-util-to-string/lib/index.js","../src/transformer.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @import {Nodes, Parents} from 'hast'\n */\n\n/**\n * Get the plain-text value of a hast node.\n *\n * @param {Nodes} node\n * Node to serialize.\n * @returns {string}\n * Serialized node.\n */\nexport function toString(node) {\n // “The concatenation of data of all the Text node descendants of the context\n // object, in tree order.”\n if ('children' in node) {\n return all(node)\n }\n\n // “Context object’s data.”\n return 'value' in node ? node.value : ''\n}\n\n/**\n * @param {Nodes} node\n * Node.\n * @returns {string}\n * Serialized node.\n */\nfunction one(node) {\n if (node.type === 'text') {\n return node.value\n }\n\n return 'children' in node ? all(node) : ''\n}\n\n/**\n * @param {Parents} node\n * Node.\n * @returns {string}\n * Serialized node.\n */\nfunction all(node) {\n let index = -1\n /** @type {Array} */\n const result = []\n\n while (++index < node.children.length) {\n result[index] = one(node.children[index])\n }\n\n return result.join('')\n}\n","import type { Root as HTMLRoot } from \"hast\";\nimport { toString } from \"hast-util-to-string\";\nimport type { QuartzTransformerPlugin } from \"@quartz-community/types\";\nimport { escapeHTML } from \"@quartz-community/utils\";\nimport type { VFile } from \"vfile\";\n\nexport interface DescriptionOptions {\n descriptionLength: number;\n maxDescriptionLength: number;\n replaceExternalLinks: boolean;\n}\n\nconst defaultOptions: DescriptionOptions = {\n descriptionLength: 150,\n maxDescriptionLength: 300,\n replaceExternalLinks: true,\n};\n\nconst urlRegex = new RegExp(\n /(https?:\\/\\/)?(?([\\da-z.-]+)\\.([a-z.]{2,6})(:\\d+)?)(?[/\\w.-]*)(\\?[/\\w.=&;-]*)?/,\n \"g\",\n);\n\nexport const Description: QuartzTransformerPlugin> = (userOpts) => {\n const opts = { ...defaultOptions, ...userOpts };\n return {\n name: \"Description\",\n htmlPlugins() {\n return [\n () => {\n return async (tree: HTMLRoot, file: VFile) => {\n let frontMatterDescription = (\n file.data.frontmatter as Record | undefined\n )?.description as string | undefined;\n let text = escapeHTML(toString(tree));\n\n if (opts.replaceExternalLinks) {\n frontMatterDescription = frontMatterDescription?.replace(\n urlRegex,\n \"$\" + \"$\",\n );\n text = text.replace(urlRegex, \"$\" + \"$\");\n }\n\n if (frontMatterDescription) {\n file.data.description = frontMatterDescription;\n file.data.text = text;\n return;\n }\n\n const desc = text;\n const sentences = desc.replace(/\\s+/g, \" \").split(/\\.\\s/);\n let finalDesc = \"\";\n let sentenceIdx = 0;\n\n while (sentenceIdx < sentences.length) {\n const sentence = sentences[sentenceIdx];\n if (!sentence) break;\n\n const currentSentence = sentence.endsWith(\".\") ? sentence : sentence + \".\";\n const nextLength = finalDesc.length + currentSentence.length + (finalDesc ? 1 : 0);\n\n if (nextLength <= opts.descriptionLength || sentenceIdx === 0) {\n finalDesc += (finalDesc ? \" \" : \"\") + currentSentence;\n sentenceIdx++;\n } else {\n break;\n }\n }\n\n file.data.description =\n finalDesc.length > opts.maxDescriptionLength\n ? finalDesc.slice(0, opts.maxDescriptionLength) + \"...\"\n : finalDesc;\n file.data.text = text;\n };\n },\n ];\n },\n };\n};\n"]} \ No newline at end of file +{"version":3,"sources":["../node_modules/hast-util-to-string/lib/index.js","../node_modules/preact/src/component.js","../node_modules/preact/src/diff/props.js","../node_modules/preact/src/create-context.js","../node_modules/@quartz-community/utils/src/emoji.ts","../src/transformer.ts"],"names":["Promise","prototype","then","bind","resolve","setTimeout","Math","random","toString"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @import {Nodes, Parents} from 'hast'\n */\n\n/**\n * Get the plain-text value of a hast node.\n *\n * @param {Nodes} node\n * Node to serialize.\n * @returns {string}\n * Serialized node.\n */\nexport function toString(node) {\n // “The concatenation of data of all the Text node descendants of the context\n // object, in tree order.”\n if ('children' in node) {\n return all(node)\n }\n\n // “Context object’s data.”\n return 'value' in node ? node.value : ''\n}\n\n/**\n * @param {Nodes} node\n * Node.\n * @returns {string}\n * Serialized node.\n */\nfunction one(node) {\n if (node.type === 'text') {\n return node.value\n }\n\n return 'children' in node ? all(node) : ''\n}\n\n/**\n * @param {Parents} node\n * Node.\n * @returns {string}\n * Serialized node.\n */\nfunction all(node) {\n let index = -1\n /** @type {Array} */\n const result = []\n\n while (++index < node.children.length) {\n result[index] = one(node.children[index])\n }\n\n return result.join('')\n}\n","import { assign } from './util';\nimport { diff, commitRoot } from './diff/index';\nimport options from './options';\nimport { Fragment } from './create-element';\nimport { MODE_HYDRATE, NULL } from './constants';\n\n/**\n * Base Component class. Provides `setState()` and `forceUpdate()`, which\n * trigger rendering\n * @param {object} props The initial component props\n * @param {object} context The initial context from parent components'\n * getChildContext\n */\nexport function BaseComponent(props, context) {\n\tthis.props = props;\n\tthis.context = context;\n}\n\n/**\n * Update component state and schedule a re-render.\n * @this {import('./internal').Component}\n * @param {object | ((s: object, p: object) => object)} update A hash of state\n * properties to update with new values or a function that given the current\n * state and props returns a new partial state\n * @param {() => void} [callback] A function to be called once component state is\n * updated\n */\nBaseComponent.prototype.setState = function (update, callback) {\n\t// only clone state when copying to nextState the first time.\n\tlet s;\n\tif (this._nextState != NULL && this._nextState != this.state) {\n\t\ts = this._nextState;\n\t} else {\n\t\ts = this._nextState = assign({}, this.state);\n\t}\n\n\tif (typeof update == 'function') {\n\t\t// Some libraries like `immer` mark the current state as readonly,\n\t\t// preventing us from mutating it, so we need to clone it. See #2716\n\t\tupdate = update(assign({}, s), this.props);\n\t}\n\n\tif (update) {\n\t\tassign(s, update);\n\t}\n\n\t// Skip update if updater function returned null\n\tif (update == NULL) return;\n\n\tif (this._vnode) {\n\t\tif (callback) {\n\t\t\tthis._stateCallbacks.push(callback);\n\t\t}\n\t\tenqueueRender(this);\n\t}\n};\n\n/**\n * Immediately perform a synchronous re-render of the component\n * @this {import('./internal').Component}\n * @param {() => void} [callback] A function to be called after component is\n * re-rendered\n */\nBaseComponent.prototype.forceUpdate = function (callback) {\n\tif (this._vnode) {\n\t\t// Set render mode so that we can differentiate where the render request\n\t\t// is coming from. We need this because forceUpdate should never call\n\t\t// shouldComponentUpdate\n\t\tthis._force = true;\n\t\tif (callback) this._renderCallbacks.push(callback);\n\t\tenqueueRender(this);\n\t}\n};\n\n/**\n * Accepts `props` and `state`, and returns a new Virtual DOM tree to build.\n * Virtual DOM is generally constructed via [JSX](https://jasonformat.com/wtf-is-jsx).\n * @param {object} props Props (eg: JSX attributes) received from parent\n * element/component\n * @param {object} state The component's current state\n * @param {object} context Context object, as returned by the nearest\n * ancestor's `getChildContext()`\n * @returns {ComponentChildren | void}\n */\nBaseComponent.prototype.render = Fragment;\n\n/**\n * @param {import('./internal').VNode} vnode\n * @param {number | null} [childIndex]\n */\nexport function getDomSibling(vnode, childIndex) {\n\tif (childIndex == NULL) {\n\t\t// Use childIndex==null as a signal to resume the search from the vnode's sibling\n\t\treturn vnode._parent\n\t\t\t? getDomSibling(vnode._parent, vnode._index + 1)\n\t\t\t: NULL;\n\t}\n\n\tlet sibling;\n\tfor (; childIndex < vnode._children.length; childIndex++) {\n\t\tsibling = vnode._children[childIndex];\n\n\t\tif (sibling != NULL && sibling._dom != NULL) {\n\t\t\t// Since updateParentDomPointers keeps _dom pointer correct,\n\t\t\t// we can rely on _dom to tell us if this subtree contains a\n\t\t\t// rendered DOM node, and what the first rendered DOM node is\n\t\t\treturn sibling._dom;\n\t\t}\n\t}\n\n\t// If we get here, we have not found a DOM node in this vnode's children.\n\t// We must resume from this vnode's sibling (in it's parent _children array)\n\t// Only climb up and search the parent if we aren't searching through a DOM\n\t// VNode (meaning we reached the DOM parent of the original vnode that began\n\t// the search)\n\treturn typeof vnode.type == 'function' ? getDomSibling(vnode) : NULL;\n}\n\n/**\n * Trigger in-place re-rendering of a component.\n * @param {import('./internal').Component} component The component to rerender\n */\nfunction renderComponent(component) {\n\tif (component._parentDom && component._dirty) {\n\t\tlet oldVNode = component._vnode,\n\t\t\toldDom = oldVNode._dom,\n\t\t\tcommitQueue = [],\n\t\t\trefQueue = [],\n\t\t\tnewVNode = assign({}, oldVNode);\n\t\tnewVNode._original = oldVNode._original + 1;\n\t\tif (options.vnode) options.vnode(newVNode);\n\n\t\tdiff(\n\t\t\tcomponent._parentDom,\n\t\t\tnewVNode,\n\t\t\toldVNode,\n\t\t\tcomponent._globalContext,\n\t\t\tcomponent._parentDom.namespaceURI,\n\t\t\toldVNode._flags & MODE_HYDRATE ? [oldDom] : NULL,\n\t\t\tcommitQueue,\n\t\t\toldDom == NULL ? getDomSibling(oldVNode) : oldDom,\n\t\t\t!!(oldVNode._flags & MODE_HYDRATE),\n\t\t\trefQueue\n\t\t);\n\n\t\tnewVNode._original = oldVNode._original;\n\t\tnewVNode._parent._children[newVNode._index] = newVNode;\n\t\tcommitRoot(commitQueue, newVNode, refQueue);\n\t\toldVNode._dom = oldVNode._parent = null;\n\n\t\tif (newVNode._dom != oldDom) {\n\t\t\tupdateParentDomPointers(newVNode);\n\t\t}\n\t}\n}\n\n/**\n * @param {import('./internal').VNode} vnode\n */\nfunction updateParentDomPointers(vnode) {\n\tif ((vnode = vnode._parent) != NULL && vnode._component != NULL) {\n\t\tvnode._dom = vnode._component.base = NULL;\n\t\tvnode._children.some(child => {\n\t\t\tif (child != NULL && child._dom != NULL) {\n\t\t\t\treturn (vnode._dom = vnode._component.base = child._dom);\n\t\t\t}\n\t\t});\n\n\t\treturn updateParentDomPointers(vnode);\n\t}\n}\n\n/**\n * The render queue\n * @type {Array}\n */\nlet rerenderQueue = [];\n\n/*\n * The value of `Component.debounce` must asynchronously invoke the passed in callback. It is\n * important that contributors to Preact can consistently reason about what calls to `setState`, etc.\n * do, and when their effects will be applied. See the links below for some further reading on designing\n * asynchronous APIs.\n * * [Designing APIs for Asynchrony](https://blog.izs.me/2013/08/designing-apis-for-asynchrony)\n * * [Callbacks synchronous and asynchronous](https://blog.ometer.com/2011/07/24/callbacks-synchronous-and-asynchronous/)\n */\n\nlet prevDebounce;\n\nconst defer =\n\ttypeof Promise == 'function'\n\t\t? Promise.prototype.then.bind(Promise.resolve())\n\t\t: setTimeout;\n\n/**\n * Enqueue a rerender of a component\n * @param {import('./internal').Component} c The component to rerender\n */\nexport function enqueueRender(c) {\n\tif (\n\t\t(!c._dirty &&\n\t\t\t(c._dirty = true) &&\n\t\t\trerenderQueue.push(c) &&\n\t\t\t!process._rerenderCount++) ||\n\t\tprevDebounce != options.debounceRendering\n\t) {\n\t\tprevDebounce = options.debounceRendering;\n\t\t(prevDebounce || defer)(process);\n\t}\n}\n\n/**\n * @param {import('./internal').Component} a\n * @param {import('./internal').Component} b\n */\nconst depthSort = (a, b) => a._vnode._depth - b._vnode._depth;\n\n/** Flush the render queue by rerendering all queued components */\nfunction process() {\n\ttry {\n\t\tlet c,\n\t\t\tl = 1;\n\n\t\t// Don't update `renderCount` yet. Keep its value non-zero to prevent unnecessary\n\t\t// process() calls from getting scheduled while `queue` is still being consumed.\n\t\twhile (rerenderQueue.length) {\n\t\t\t// Keep the rerender queue sorted by (depth, insertion order). The queue\n\t\t\t// will initially be sorted on the first iteration only if it has more than 1 item.\n\t\t\t//\n\t\t\t// New items can be added to the queue e.g. when rerendering a provider, so we want to\n\t\t\t// keep the order from top to bottom with those new items so we can handle them in a\n\t\t\t// single pass\n\t\t\tif (rerenderQueue.length > l) {\n\t\t\t\trerenderQueue.sort(depthSort);\n\t\t\t}\n\n\t\t\tc = rerenderQueue.shift();\n\t\t\tl = rerenderQueue.length;\n\n\t\t\trenderComponent(c);\n\t\t}\n\t} finally {\n\t\trerenderQueue.length = process._rerenderCount = 0;\n\t}\n}\n\nprocess._rerenderCount = 0;\n","import { IS_NON_DIMENSIONAL, NULL, SVG_NAMESPACE } from '../constants';\nimport options from '../options';\n\n// Per-instance unique key for event clock stamps. Each Preact copy on the page\n// gets its own random suffix so that `_dispatched` / `_attached` properties on\n// shared event objects and handler functions cannot collide across instances.\n// ~1 in 60M collision odds - if you have that many praect versions on the page,\n// you deserve some weird bugs.\n// In 11 we can replace this with a\n// Symbol\nlet _id = Math.random().toString(8),\n\tEVENT_DISPATCHED = '__d' + _id,\n\tEVENT_ATTACHED = '__a' + _id;\n\nfunction setStyle(style, key, value) {\n\tif (key[0] == '-') {\n\t\tstyle.setProperty(key, value == NULL ? '' : value);\n\t} else if (value == NULL) {\n\t\tstyle[key] = '';\n\t} else if (typeof value != 'number' || IS_NON_DIMENSIONAL.test(key)) {\n\t\tstyle[key] = value;\n\t} else {\n\t\tstyle[key] = value + 'px';\n\t}\n}\n\nconst CAPTURE_REGEX = /(PointerCapture)$|Capture$/i;\n\n// A logical clock to solve issues like https://github.com/preactjs/preact/issues/3927.\n// When the DOM performs an event it leaves micro-ticks in between bubbling up which means that\n// an event can trigger on a newly reated DOM-node while the event bubbles up.\n//\n// Originally inspired by Vue\n// (https://github.com/vuejs/core/blob/caeb8a68811a1b0f79/packages/runtime-dom/src/modules/events.ts#L90-L101),\n// but modified to use a logical clock instead of Date.now() in case event handlers get attached\n// and events get dispatched during the same millisecond.\n//\n// The clock is incremented after each new event dispatch. This allows 1 000 000 new events\n// per second for over 280 years before the value reaches Number.MAX_SAFE_INTEGER (2**53 - 1).\nlet eventClock = 0;\n\n/**\n * Set a property value on a DOM node\n * @param {import('../internal').PreactElement} dom The DOM node to modify\n * @param {string} name The name of the property to set\n * @param {*} value The value to set the property to\n * @param {*} oldValue The old value the property had\n * @param {string} namespace Whether or not this DOM node is an SVG node or not\n */\nexport function setProperty(dom, name, value, oldValue, namespace) {\n\tlet useCapture;\n\n\to: if (name == 'style') {\n\t\tif (typeof value == 'string') {\n\t\t\tdom.style.cssText = value;\n\t\t} else {\n\t\t\tif (typeof oldValue == 'string') {\n\t\t\t\tdom.style.cssText = oldValue = '';\n\t\t\t}\n\n\t\t\tif (oldValue) {\n\t\t\t\tfor (name in oldValue) {\n\t\t\t\t\tif (!(value && name in value)) {\n\t\t\t\t\t\tsetStyle(dom.style, name, '');\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (value) {\n\t\t\t\tfor (name in value) {\n\t\t\t\t\tif (!oldValue || value[name] != oldValue[name]) {\n\t\t\t\t\t\tsetStyle(dom.style, name, value[name]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t// Benchmark for comparison: https://esbench.com/bench/574c954bdb965b9a00965ac6\n\telse if (name[0] == 'o' && name[1] == 'n') {\n\t\tuseCapture = name != (name = name.replace(CAPTURE_REGEX, '$1'));\n\t\tconst lowerCaseName = name.toLowerCase();\n\n\t\t// Infer correct casing for DOM built-in events:\n\t\tif (lowerCaseName in dom || name == 'onFocusOut' || name == 'onFocusIn')\n\t\t\tname = lowerCaseName.slice(2);\n\t\telse name = name.slice(2);\n\n\t\tif (!dom._listeners) dom._listeners = {};\n\t\tdom._listeners[name + useCapture] = value;\n\n\t\tif (value) {\n\t\t\tif (!oldValue) {\n\t\t\t\tvalue[EVENT_ATTACHED] = eventClock;\n\t\t\t\tdom.addEventListener(\n\t\t\t\t\tname,\n\t\t\t\t\tuseCapture ? eventProxyCapture : eventProxy,\n\t\t\t\t\tuseCapture\n\t\t\t\t);\n\t\t\t} else {\n\t\t\t\tvalue[EVENT_ATTACHED] = oldValue[EVENT_ATTACHED];\n\t\t\t}\n\t\t} else {\n\t\t\tdom.removeEventListener(\n\t\t\t\tname,\n\t\t\t\tuseCapture ? eventProxyCapture : eventProxy,\n\t\t\t\tuseCapture\n\t\t\t);\n\t\t}\n\t} else {\n\t\tif (namespace == SVG_NAMESPACE) {\n\t\t\t// Normalize incorrect prop usage for SVG:\n\t\t\t// - xlink:href / xlinkHref --> href (xlink:href was removed from SVG and isn't needed)\n\t\t\t// - className --> class\n\t\t\tname = name.replace(/xlink(H|:h)/, 'h').replace(/sName$/, 's');\n\t\t} else if (\n\t\t\tname != 'width' &&\n\t\t\tname != 'height' &&\n\t\t\tname != 'href' &&\n\t\t\tname != 'list' &&\n\t\t\tname != 'form' &&\n\t\t\t// Default value in browsers is `-1` and an empty string is\n\t\t\t// cast to `0` instead\n\t\t\tname != 'tabIndex' &&\n\t\t\tname != 'download' &&\n\t\t\tname != 'rowSpan' &&\n\t\t\tname != 'colSpan' &&\n\t\t\tname != 'role' &&\n\t\t\tname != 'popover' &&\n\t\t\tname in dom\n\t\t) {\n\t\t\ttry {\n\t\t\t\tdom[name] = value == NULL ? '' : value;\n\t\t\t\t// labelled break is 1b smaller here than a return statement (sorry)\n\t\t\t\tbreak o;\n\t\t\t} catch (e) {}\n\t\t}\n\n\t\t// aria- and data- attributes have no boolean representation.\n\t\t// A `false` value is different from the attribute not being\n\t\t// present, so we can't remove it. For non-boolean aria\n\t\t// attributes we could treat false as a removal, but the\n\t\t// amount of exceptions would cost too many bytes. On top of\n\t\t// that other frameworks generally stringify `false`.\n\n\t\tif (typeof value == 'function') {\n\t\t\t// never serialize functions as attribute values\n\t\t} else if (value != NULL && (value !== false || name[4] == '-')) {\n\t\t\tdom.setAttribute(name, name == 'popover' && value == true ? '' : value);\n\t\t} else {\n\t\t\tdom.removeAttribute(name);\n\t\t}\n\t}\n}\n\n/**\n * Create an event proxy function.\n * @param {boolean} useCapture Is the event handler for the capture phase.\n * @private\n */\nfunction createEventProxy(useCapture) {\n\t/**\n\t * Proxy an event to hooked event handlers\n\t * @param {import('../internal').PreactEvent} e The event object from the browser\n\t * @private\n\t */\n\treturn function (e) {\n\t\tif (this._listeners) {\n\t\t\tconst eventHandler = this._listeners[e.type + useCapture];\n\t\t\tif (e[EVENT_DISPATCHED] == NULL) {\n\t\t\t\te[EVENT_DISPATCHED] = eventClock++;\n\n\t\t\t\t// When `e[EVENT_DISPATCHED]` is smaller than the time when the targeted event\n\t\t\t\t// handler was attached we know we have bubbled up to an element that was added\n\t\t\t\t// during patching the DOM.\n\t\t\t} else if (e[EVENT_DISPATCHED] < eventHandler[EVENT_ATTACHED]) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\treturn eventHandler(options.event ? options.event(e) : e);\n\t\t}\n\t};\n}\n\nconst eventProxy = createEventProxy(false);\nconst eventProxyCapture = createEventProxy(true);\n","import { enqueueRender } from './component';\nimport { NULL } from './constants';\n\nexport let i = 0;\n\nexport function createContext(defaultValue) {\n\tfunction Context(props) {\n\t\tif (!this.getChildContext) {\n\t\t\t/** @type {Set | null} */\n\t\t\tlet subs = new Set();\n\t\t\tlet ctx = {};\n\t\t\tctx[Context._id] = this;\n\n\t\t\tthis.getChildContext = () => ctx;\n\n\t\t\tthis.componentWillUnmount = () => {\n\t\t\t\tsubs = NULL;\n\t\t\t};\n\n\t\t\tthis.shouldComponentUpdate = function (_props) {\n\t\t\t\t// @ts-expect-error even\n\t\t\t\tif (this.props.value != _props.value) {\n\t\t\t\t\tsubs.forEach(c => {\n\t\t\t\t\t\tc._force = true;\n\t\t\t\t\t\tenqueueRender(c);\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t};\n\n\t\t\tthis.sub = c => {\n\t\t\t\tsubs.add(c);\n\t\t\t\tlet old = c.componentWillUnmount;\n\t\t\t\tc.componentWillUnmount = () => {\n\t\t\t\t\tif (subs) {\n\t\t\t\t\t\tsubs.delete(c);\n\t\t\t\t\t}\n\t\t\t\t\tif (old) old.call(c);\n\t\t\t\t};\n\t\t\t};\n\t\t}\n\n\t\treturn props.children;\n\t}\n\n\tContext._id = '__cC' + i++;\n\tContext._defaultValue = defaultValue;\n\n\t/** @type {import('./internal').FunctionComponent} */\n\tContext.Consumer = (props, contextValue) => {\n\t\treturn props.children(contextValue);\n\t};\n\n\t// we could also get rid of _contextRef entirely\n\tContext.Provider =\n\t\tContext._contextRef =\n\t\tContext.Consumer.contextType =\n\t\t\tContext;\n\n\treturn Context;\n}\n","const U200D = String.fromCharCode(8205);\nconst UFE0Fg = /\\uFE0F/g;\n\nexport function getIconCode(char: string): string {\n return toCodePoint(char.indexOf(U200D) < 0 ? char.replace(UFE0Fg, \"\") : char);\n}\n\nfunction toCodePoint(unicodeSurrogates: string): string {\n const r: string[] = [];\n let c = 0,\n p = 0,\n i = 0;\n\n while (i < unicodeSurrogates.length) {\n c = unicodeSurrogates.charCodeAt(i++);\n if (p) {\n r.push((65536 + ((p - 55296) << 10) + (c - 56320)).toString(16));\n p = 0;\n } else if (55296 <= c && c <= 56319) {\n p = c;\n } else {\n r.push(c.toString(16));\n }\n }\n return r.join(\"-\");\n}\n","import type { Root as HTMLRoot } from \"hast\";\nimport { toString } from \"hast-util-to-string\";\nimport type { QuartzTransformerPlugin } from \"@quartz-community/types\";\nimport { escapeHTML } from \"@quartz-community/utils\";\nimport type { VFile } from \"vfile\";\n\nexport interface DescriptionOptions {\n descriptionLength: number;\n maxDescriptionLength: number;\n replaceExternalLinks: boolean;\n}\n\nconst defaultOptions: DescriptionOptions = {\n descriptionLength: 150,\n maxDescriptionLength: 300,\n replaceExternalLinks: true,\n};\n\nconst urlRegex = new RegExp(\n /(https?:\\/\\/)?(?([\\da-z.-]+)\\.([a-z.]{2,6})(:\\d+)?)(?[/\\w.-]*)(\\?[/\\w.=&;-]*)?/,\n \"g\",\n);\n\nexport const Description: QuartzTransformerPlugin> = (userOpts) => {\n const opts = { ...defaultOptions, ...userOpts };\n return {\n name: \"Description\",\n htmlPlugins() {\n return [\n () => {\n return async (tree: HTMLRoot, file: VFile) => {\n let frontMatterDescription = (\n file.data.frontmatter as Record | undefined\n )?.description as string | undefined;\n let text = escapeHTML(toString(tree));\n\n if (opts.replaceExternalLinks) {\n frontMatterDescription = frontMatterDescription?.replace(\n urlRegex,\n \"$\" + \"$\",\n );\n text = text.replace(urlRegex, \"$\" + \"$\");\n }\n\n if (frontMatterDescription) {\n file.data.description = frontMatterDescription;\n file.data.text = text;\n return;\n }\n\n const desc = text;\n const sentences = desc.replace(/\\s+/g, \" \").split(/\\.\\s/);\n let finalDesc = \"\";\n let sentenceIdx = 0;\n\n while (sentenceIdx < sentences.length) {\n const sentence = sentences[sentenceIdx];\n if (!sentence) break;\n\n const currentSentence = sentence.endsWith(\".\") ? sentence : sentence + \".\";\n const nextLength = finalDesc.length + currentSentence.length + (finalDesc ? 1 : 0);\n\n if (nextLength <= opts.descriptionLength || sentenceIdx === 0) {\n finalDesc += (finalDesc ? \" \" : \"\") + currentSentence;\n sentenceIdx++;\n } else {\n break;\n }\n }\n\n file.data.description =\n finalDesc.length > opts.maxDescriptionLength\n ? finalDesc.slice(0, opts.maxDescriptionLength) + \"...\"\n : finalDesc;\n file.data.text = text;\n };\n },\n ];\n },\n };\n};\n"]} \ No newline at end of file