UNPKG

bitran

Version:

📜 Highly customizable text processor and transpiler.

520 lines (518 loc) • 21.2 kB
import { e as editorName, p as paragraphName, s as spanName } from "./shared-C10h7SVW.js"; import { defineAsyncComponent, defineComponent, renderSlot, openBlock, createElementBlock, Fragment, renderList, createBlock, inject, h, normalizeClass, unref, withAsyncContext, onUnmounted, setBlockTracking, createElementVNode, createVNode, computed, normalizeProps, guardReactiveProps, toDisplayString, ref, onMounted, withCtx, Suspense, resolveDynamicComponent, provide } from "vue"; import { E as ErrorNode, t as textName } from "./shared-B4X4KQeO.js"; import { G as GroupNode } from "./group-HQBJ3zxp.js"; import { B as BlockNode, P as ProductLayout, a as ProductNode } from "./productNode-C0XZsQy2.js"; import "yaml"; import "./index-DiVYKXTv.js"; import { c as createRenderData } from "./renderData-CZkwarYW.js"; function defineProductComponent(componentLoader) { return async () => defineAsyncComponent(componentLoader); } function defineIcon(iconLoader) { return async () => (await iconLoader()).default; } var RenderMode = /* @__PURE__ */ ((RenderMode2) => { RenderMode2[RenderMode2["Client"] = 1] = "Client"; RenderMode2[RenderMode2["Hybrid"] = 2] = "Hybrid"; RenderMode2[RenderMode2["Server"] = 3] = "Server"; return RenderMode2; })(RenderMode || {}); function defineProductRender(render) { return render; } const editor = defineProductRender({ mode: RenderMode.Client, component: defineProductComponent(() => import("./Editor-nBithASK.js")), icon: defineIcon(() => import("./icon-B7JshANc.js")), customLayout: true }); const span = defineProductRender({ mode: RenderMode.Server, component: defineProductComponent(() => import("./Span-D-hMHyBe.js")), icon: defineIcon(() => import("./icon-CNnW3Zkl.js")) }); function defineLanguage(language) { return language; } function defineLanguages(languagesLoader) { const result = {}; for (const [languageCode, languageLoader] of Object.entries(languagesLoader)) result[languageCode] = async () => (await languageLoader()).default; return result; } async function createPhrase(languageCode, languages, context) { let langData = {}; const phrase = (phraseKey, ...args) => { const phrase2 = langData[phraseKey]; if (!phrase2) throw new Error(`Missing phrase "${phraseKey}" in language "${languageCode}"${context ? ` in context "${context}"` : ""}!`); if (typeof phrase2 === "function") return phrase2(...args); return phrase2; }; if (!languageCode) return phrase; if (!languages) return phrase; if (!languages[languageCode]) { console.warn(`Language "${languageCode}" not supported${context ? ` in context "${context}"` : ""}!`); return phrase; } try { const actualLangData = await languages[languageCode](); langData = actualLangData; } catch (error) { console.warn(`Failed to load language "${languageCode}"${context ? ` in context "${context}"` : ""}!`); } return phrase; } const text = defineProductRender({ mode: RenderMode.Server, component: defineProductComponent(() => import("./Text-DRT-CO04.js")), icon: defineIcon(() => import("./icon-RJi-fZYP.js")), languages: defineLanguages({ en: () => import("./en-CC_zC1In.js") }) }); const paragraph = defineProductRender({ mode: RenderMode.Server, component: defineProductComponent(() => import("./Paragraph-BgF1qlQb.js")), icon: defineIcon(() => import("./icon-BPXNrAMB.js")), languages: defineLanguages({ en: () => import("./en-DqK9-6lw.js"), ru: () => import("./ru-CcjRmBQ0.js") }) }); const _sfc_main$b = /* @__PURE__ */ defineComponent({ __name: "RenderWrapper", props: { renderMode: {} }, setup(__props) { return (_ctx, _cache) => { return renderSlot(_ctx.$slots, "default"); }; } }); const globalStateKey = Symbol(); const privateStateKey = Symbol(); const clsPrefix = "bitran"; const cls = new Proxy({}, { get(target, property) { return property ? `${clsPrefix}-${property.toString()}` : ""; } }); const _sfc_main$a = /* @__PURE__ */ defineComponent({ __name: "RenderGroup", props: { node: {} }, setup(__props) { return (_ctx, _cache) => { return openBlock(true), createElementBlock(Fragment, null, renderList(_ctx.node.children, (child) => { return openBlock(), createBlock(_sfc_main$1, { node: child }, null, 8, ["node"]); }), 256); }; } }); function useGlobalState() { return inject(globalStateKey); } function usePrivateState() { return inject(privateStateKey); } function useProduct(node) { const globalState = useGlobalState(); const nodeName = typeof node === "string" ? node : node.name; return { productCore: globalState.bitranCore.products[nodeName], productRender: globalState.bitranRender.products[nodeName] }; } async function getFrontRenderData(node) { var _a; const globalState = useGlobalState(); const { productCore } = useProduct(node); let createdRenderData = (_a = globalState.content.renderData) == null ? void 0 : _a[node.getId()]; createdRenderData || (createdRenderData = await createRenderData("front", node, productCore)); return createdRenderData; } function useRenderData(node) { return node.renderData; } async function prepareProduct(node) { const toReturn = { VNode: null, prepareError: null }; const setError = (error) => { console.error(`Error in ${node.layout} product "${node.name}"! ` + ((error == null ? void 0 : error.message) || error)); toReturn.prepareError = error; }; if (node instanceof ErrorNode) { setError(node.error); return toReturn; } const renderDataPromise = getFrontRenderData(node); const prepareVNodePromise = prepareVNode(node); try { const [createdRenderData, vNode] = await Promise.all([renderDataPromise, prepareVNodePromise]); if (createdRenderData) { if (createdRenderData.status === "error") throw new Error(createdRenderData.errorMessage); node.renderData = createdRenderData == null ? void 0 : createdRenderData.data; } toReturn.VNode = vNode; } catch (error) { setError(error); return toReturn; } return toReturn; } async function prepareVNode(node) { const { productRender } = useProduct(node); return h(await productRender.component(), { node }); } const defaultBlockIcon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 1024 1024">\n <path d="M953.3,260.8c-7.6-17.5-22.6-27.6-40.1-40.1L564.8,15.1c-20.1-9.9-35.1-15.1-52.8-15.1s-40.1,5-55.1,15.1L110.7,220.7c-17.5,7.6-27.6,22.6-40.1,40.1-9.9,20.1-15.1,35.1-15.1,52.6v406.2c0,17.5,5,35.1,15.1,52.8,7.6,17.5,22.6,27.6,40.1,40.1l346,200.6c20.1,9.9,35.1,15.1,52.8,15.1s35.1-5,52.8-15.1l351.2-203.2c17.5-7.6,27.6-22.6,40.1-40.1,9.9-20.1,15.1-35.1,15.1-52.8v-403.7c-.1-17.5-5.2-35.1-15.2-52.6h0ZM451.8,551.8v321l-273.2-165.5v-313.5l273.2,158ZM785.4,285.9l-273.4,155.5-273.4-158L512,127.8l273.4,158ZM848.1,391.1v318.5l-275.8,165.6v-326.1l275.8-158h0Z"/>\n</svg>'; const defaultInlinerIcon = '<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 960 960">\n <path d="M480,960c-15.1,0-27.8-5-38.1-15.3-10.2-10.2-15.3-22.9-15.3-38.1s5-27.8,15.3-38.1c10.2-10.2,22.9-15.3,38.1-15.3s27.8,5,38.1,15.3c10.2,10.2,15.3,22.9,15.3,38.1s-5,27.8-15.3,38.1c-10.2,10.2-22.9,15.3-38.1,15.3ZM266.7,960c-15.1,0-27.8-5-38.1-15.3-10.2-10.2-15.3-22.9-15.3-38.1s5-27.8,15.3-38.1c10.2-10.2,22.9-15.3,38.1-15.3s27.8,5,38.1,15.3c10.2,10.2,15.3,22.9,15.3,38.1s-5,27.8-15.3,38.1c-10.2,10.2-22.9,15.3-38.1,15.3ZM53.3,960c-15.1,0-27.8-5-38.1-15.3-10.2-10.2-15.3-22.9-15.3-38.1s5-27.8,15.3-38.1c10.2-10.2,22.9-15.3,38.1-15.3s27.8,5,38.1,15.3,15.3,22.9,15.3,38.1-5,27.8-15.3,38.1-22.9,15.3-38.1,15.3ZM53.3,746.7c-15.1,0-27.8-5-38.1-15.3-10.2-10.2-15.3-22.9-15.3-38.1s5-27.8,15.3-38.1c10.2-10.2,22.9-15.3,38.1-15.3s27.8,5,38.1,15.3c10.2,10.2,15.3,22.9,15.3,38.1s-5,27.8-15.3,38.1-22.9,15.3-38.1,15.3ZM53.3,533.3c-15.1,0-27.8-5-38.1-15.3-10.2-10.2-15.3-22.9-15.3-38.1s5-27.8,15.3-38.1,22.9-15.3,38.1-15.3,27.8,5,38.1,15.3c10.2,10.2,15.3,22.9,15.3,38.1s-5,27.8-15.3,38.1-22.9,15.3-38.1,15.3ZM53.3,320c-15.1,0-27.8-5-38.1-15.3-10.2-10.2-15.3-22.9-15.3-38.1s5-27.8,15.3-38.1,22.9-15.3,38.1-15.3,27.8,5,38.1,15.3c10.2,10.2,15.3,22.9,15.3,38.1s-5,27.8-15.3,38.1c-10.2,10.2-22.9,15.3-38.1,15.3ZM480,106.7c-15.1,0-27.8-5-38.1-15.3-10.2-10.2-15.3-22.9-15.3-38.1s5-27.8,15.3-38.1c10.2-10.2,22.9-15.3,38.1-15.3s27.8,5,38.1,15.3c10.2,10.2,15.3,22.9,15.3,38.1s-5,27.8-15.3,38.1c-10.2,10.2-22.9,15.3-38.1,15.3ZM266.7,106.7c-15.1,0-27.8-5-38.1-15.3-10.2-10.2-15.3-22.9-15.3-38.1s5-27.8,15.3-38.1c10.2-10.2,22.9-15.3,38.1-15.3s27.8,5,38.1,15.3c10.2,10.2,15.3,22.9,15.3,38.1s-5,27.8-15.3,38.1c-10.2,10.2-22.9,15.3-38.1,15.3ZM53.3,106.7c-15.1,0-27.8-5-38.1-15.3C5,81.2,0,68.5,0,53.3S5,25.5,15.3,15.3C25.5,5,38.2,0,53.3,0s27.8,5,38.1,15.3c10.2,10.2,15.3,22.9,15.3,38.1s-5,27.8-15.3,38.1c-10.2,10.2-22.9,15.3-38.1,15.3ZM693.3,960c-15.1,0-27.8-5-38.1-15.3-10.2-10.2-15.3-22.9-15.3-38.1s5-27.8,15.3-38.1,22.9-15.3,38.1-15.3h53.3V106.7h-53.3c-15.1,0-27.8-5-38.1-15.3-10.2-10.2-15.3-22.9-15.3-38.1s5-27.8,15.3-38.1c10.2-10.2,22.9-15.3,38.1-15.3h213.3c15.1,0,27.8,5,38.1,15.3,10.2,10.2,15.3,22.9,15.3,38.1s-5,27.8-15.3,38.1c-10.2,10.2-22.9,15.3-38.1,15.3h-53.3v746.7h53.3c15.1,0,27.8,5,38.1,15.3,10.2,10.2,15.3,22.9,15.3,38.1s-5,27.8-15.3,38.1c-10.2,10.2-22.9,15.3-38.1,15.3h-213.3Z"/>\n</svg>'; async function useIcon(node) { const nodeName = typeof node === "string" ? node : node.name; const { productCore, productRender } = useProduct(node); const isBlock = productCore.Node.prototype instanceof BlockNode; let svg = isBlock ? defaultBlockIcon : defaultInlinerIcon; const iconFn = productRender == null ? void 0 : productRender.icon; if (iconFn) { try { svg = await iconFn(); } catch { console.warn(`Failed to load icon for product "${nodeName}"! Using the default icon instead!`); } } return svg; } async function useLanguage(node) { const nodeName = typeof node === "string" ? node : node.name; const globalState = useGlobalState(); const { productRender } = useProduct(node); const rawPhraseFn = await createPhrase(globalState.language, productRender.languages, `product:${nodeName}`); const phraseFn = (phraseKey, ...args) => { try { return rawPhraseFn(phraseKey, ...args); } catch { return `{{ ${phraseKey} }}`; } }; return phraseFn; } function useMeta(node) { return node.meta; } function useParseData(node) { return node.parseData; } function usePrettyText() { return useGlobalState().bitranRender.formatText; } const _sfc_main$9 = /* @__PURE__ */ defineComponent({ __name: "BlockFloat", props: { node: {}, position: {} }, setup(__props) { return (_ctx, _cache) => { return openBlock(), createElementBlock("div", { class: normalizeClass([unref(cls).blockFloat, unref(cls)[`blockFloat--${_ctx.position}`]]) }, null, 2); }; } }); const _sfc_main$8 = /* @__PURE__ */ defineComponent({ __name: "ProductIcon", props: { node: {} }, async setup(__props) { let __temp, __restore; const props = __props; const privateState = inject(privateStateKey); const nodeName = typeof props.node === "string" ? props.node : props.node.name; const firstOfType = !(nodeName in privateState.iconCache); const Icon = ([__temp, __restore] = withAsyncContext(async () => (async () => { if (firstOfType) { privateState.iconCache[nodeName] = null; const svg = await useIcon(props.node); return h("svg", { ...parseSvg(svg), id: `bitran-product-icon:${nodeName}` }); } return h("svg", { innerHTML: `<use href="#bitran-product-icon:${nodeName}" />` }); })()), __temp = await __temp, __restore(), __temp); onUnmounted(() => { if (firstOfType) delete privateState.iconCache[nodeName]; }); function parseSvg(svg) { svg = svg.slice(0, -6); const svgOpenMatch = svg.match(new RegExp(`<svg(?=\\s)(?!(?:[^>"\\']|"[^"]*"|\\'[^\\']*\\')*?(?<=\\s)(?:term|range)\\s*=)(?!\\s*\\/?>)\\s+(?:".*?"|\\'.*?\\'|[^>]*?)+>`, "m")); svg = svg.slice(svgOpenMatch[0].length); const attributes = {}; svgOpenMatch[0].replaceAll(/ (.+?)="(.+?)"/gm, (match, attribute, value) => { attributes[attribute] = value; return ""; }); return { ...attributes, innerHTML: svg }; } return (_ctx, _cache) => { return openBlock(), createBlock(unref(Icon)); }; } }); const _sfc_main$7 = /* @__PURE__ */ defineComponent({ __name: "BlockAside", props: { node: {} }, setup(__props) { return (_ctx, _cache) => { return openBlock(), createElementBlock("div", { class: normalizeClass(unref(cls).blockAside) }, [ _cache[0] || (setBlockTracking(-1, true), (_cache[0] = createElementVNode("div", { class: normalizeClass(unref(cls).blockAsideIcon) }, [ createVNode(_sfc_main$8, { node: _ctx.node.name }, null, 8, ["node"]) ], 2)).cacheIndex = 0, setBlockTracking(1), _cache[0]) ], 2); }; } }); const _hoisted_1$1 = ["id"]; const _hoisted_2 = { key: 0 }; const _sfc_main$6 = /* @__PURE__ */ defineComponent({ __name: "Block", props: { node: {} }, async setup(__props) { let __temp, __restore; const props = __props; const globalState = inject(globalStateKey); const { productRender } = useProduct(props.node.name); const { VNode: BlockVNode, prepareError: error } = ([__temp, __restore] = withAsyncContext(() => prepareProduct(props.node)), __temp = await __temp, __restore(), __temp); const id = computed(() => { if (props.node instanceof ErrorNode) return null; return (globalState.scope ? globalState.scope + ":" : "") + props.node.getId(); }); return (_ctx, _cache) => { return openBlock(), createElementBlock("div", { id: id.value, class: normalizeClass(unref(cls).blockContainer) }, [ createVNode(_sfc_main$9, normalizeProps(guardReactiveProps({ node: _ctx.node, position: "above" })), null, 16), unref(productRender).customLayout && !unref(error) ? (openBlock(), createBlock(unref(BlockVNode), { key: 0 })) : (openBlock(), createElementBlock("div", { key: 1, class: normalizeClass([unref(cls).block, !!unref(error) && unref(cls).error]) }, [ createVNode(_sfc_main$7, normalizeProps(guardReactiveProps({ node: _ctx.node })), null, 16), createElementVNode("div", { class: normalizeClass(unref(cls).blockMain) }, [ unref(error) ? (openBlock(), createElementBlock("div", _hoisted_2, toDisplayString(unref(error)), 1)) : (openBlock(), createBlock(unref(BlockVNode), { key: 1 })) ], 2) ], 2)), createVNode(_sfc_main$9, normalizeProps(guardReactiveProps({ node: _ctx.node, position: "below" })), null, 16) ], 10, _hoisted_1$1); }; } }); const _hoisted_1 = { key: 0, style: { "color": "red" } }; const _sfc_main$5 = /* @__PURE__ */ defineComponent({ __name: "Inliner", props: { node: {} }, async setup(__props) { let __temp, __restore; const props = __props; const { VNode: InlinerVNode, prepareError: error } = ([__temp, __restore] = withAsyncContext(() => prepareProduct(props.node)), __temp = await __temp, __restore(), __temp); return (_ctx, _cache) => { return unref(error) ? (openBlock(), createElementBlock("span", _hoisted_1, "Inliner Error — " + toDisplayString(unref(error)), 1)) : (openBlock(), createBlock(unref(InlinerVNode), { key: 1 })); }; } }); const _export_sfc = (sfc, props) => { const target = sfc.__vccOpts || sfc; for (const [key, val] of props) { target[key] = val; } return target; }; const _sfc_main$4 = {}; function _sfc_render$1(_ctx, _cache) { return openBlock(), createElementBlock("div", null, "Block loading..."); } const BlockLoading = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$1]]); const _sfc_main$3 = {}; function _sfc_render(_ctx, _cache) { return openBlock(), createElementBlock("span", null, "Inliner loading..."); } const InlinerLoading = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render]]); const _sfc_main$2 = /* @__PURE__ */ defineComponent({ __name: "RenderProduct", props: { node: {} }, setup(__props) { var _a; const props = __props; const globalState = inject(globalStateKey); const productName = props.node.name; if (!globalState.bitranCore.products[productName]) throw new Error(`Product "${productName}" is not registered in Bitran core!`); if (!globalState.bitranRender.products[productName]) throw new Error(`Product "${productName}" is not registered in Bitran render!`); const renderMode = globalState.editMode ? RenderMode.Client : ((_a = globalState.bitranRender.products[productName]) == null ? void 0 : _a.mode) ?? RenderMode.Client; const RenderWrapper = globalState.bitranRender.RenderWrapper; const loadingVisible = ref(false); onMounted(() => setTimeout(() => loadingVisible.value = true, 500)); const isBlock = props.node.layout === ProductLayout.Block; const _createVNodeWithNode = (component) => h(component, { node: props.node }); const ProductWrapper = _createVNodeWithNode(isBlock ? _sfc_main$6 : _sfc_main$5); const ProductLoading = _createVNodeWithNode(isBlock ? BlockLoading : InlinerLoading); return (_ctx, _cache) => { return openBlock(), createBlock(unref(RenderWrapper), { renderMode: unref(renderMode) }, { default: withCtx(() => [ unref(renderMode) > unref(RenderMode).Client ? (openBlock(), createBlock(unref(ProductWrapper), { key: 0 })) : (openBlock(), createBlock(Suspense, { key: 1 }, { fallback: withCtx(() => [ loadingVisible.value ? (openBlock(), createBlock(unref(ProductLoading), { key: 0 })) : (openBlock(), createBlock(resolveDynamicComponent(isBlock ? "div" : "span"), { key: 1 })) ]), default: withCtx(() => [ createVNode(unref(ProductWrapper)) ]), _: 1 })) ]), _: 1 }, 8, ["renderMode"]); }; } }); const _sfc_main$1 = /* @__PURE__ */ defineComponent({ __name: "Render", props: { node: {} }, setup(__props) { var _a; const props = __props; let RenderComponent; switch (true) { case props.node instanceof GroupNode: RenderComponent = _sfc_main$a; break; case props.node instanceof ErrorNode: case props.node instanceof ProductNode: RenderComponent = _sfc_main$2; break; } if (!RenderComponent) throw new Error(`Can't render unknown node "${((_a = props.node) == null ? void 0 : _a.name) || props.node}"!`); return (_ctx, _cache) => { return openBlock(), createBlock(unref(RenderComponent), { node: _ctx.node }, null, 8, ["node"]); }; } }); const _sfc_main = /* @__PURE__ */ defineComponent({ __name: "Bitran", props: { bitranCore: {}, bitranRender: {}, content: {}, scopeId: {}, editMode: { type: Boolean }, language: {} }, async setup(__props) { let __temp, __restore; const props = __props; provide(globalStateKey, { scope: props.scopeId || "", bitranCore: props.bitranCore, bitranRender: props.bitranRender, content: props.content, editMode: !!props.editMode, language: props.language }); provide(privateStateKey, { iconCache: {} }); const root = ([__temp, __restore] = withAsyncContext(() => props.bitranCore.parser.parse(props.content.biCode)), __temp = await __temp, __restore(), __temp); return (_ctx, _cache) => { return openBlock(), createElementBlock("section", { class: normalizeClass([unref(cls).container, _ctx.editMode && unref(cls).editMode]) }, [ createVNode(_sfc_main$1, { node: unref(root) }, null, 8, ["node"]) ], 2); }; } }); const defaultProductRenders = { [editorName]: editor, [paragraphName]: paragraph, [spanName]: span, [textName]: text }; function createBitranRender(config) { const resolvedConfig = { products: { ...(config == null ? void 0 : config.products) || {}, ...defaultProductRenders } }; return { products: resolvedConfig.products, formatText: config.formatText || ((text2) => text2), RenderWrapper: config.RenderWrapper || _sfc_main$b }; } export { RenderMode as R, _export_sfc as _, _sfc_main$1 as a, usePrettyText as b, cls as c, defineLanguage as d, defaultProductRenders as e, createBitranRender as f, _sfc_main as g, _sfc_main$8 as h, defineIcon as i, defineProductComponent as j, defineLanguages as k, createPhrase as l, defineProductRender as m, prepareVNode as n, globalStateKey as o, prepareProduct as p, privateStateKey as q, useIcon as r, useLanguage as s, useMeta as t, useParseData as u, useProduct as v, getFrontRenderData as w, useRenderData as x, useGlobalState as y, usePrivateState as z }; //# sourceMappingURL=index-C7zkcRZi.js.map