"use strict"; function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } Object.defineProperty(exports, "__esModule", { value: !0 }); function isPortableTextSpan(node) { return node._type === "span" && "text" in node && typeof node.text == "string" && (typeof node.marks > "u" || Array.isArray(node.marks) && node.marks.every(mark => typeof mark == "string")); } function isPortableTextBlock(node) { return ( // A block doesn't _have_ to be named 'block' - to differentiate between // allowed child types and marks, one might name them differently typeof node._type == "string" && // Toolkit-types like nested spans are @-prefixed node._type[0] !== "@" && ( // `markDefs` isn't _required_ per say, but if it's there, it needs to be an array !("markDefs" in node) || !node.markDefs || Array.isArray(node.markDefs) && // Every mark definition needs to have an `_key` to be mappable in child spans node.markDefs.every(def => typeof def._key == "string")) && // `children` is required and needs to be an array "children" in node && Array.isArray(node.children) && // All children are objects with `_type` (usually spans, but can contain other stuff) node.children.every(child => typeof child == "object" && "_type" in child) ); } function isPortableTextListItemBlock(block) { return isPortableTextBlock(block) && "listItem" in block && typeof block.listItem == "string" && (typeof block.level > "u" || typeof block.level == "number"); } function isPortableTextToolkitList(block) { return block._type === "@list"; } function isPortableTextToolkitSpan(span) { return span._type === "@span"; } function isPortableTextToolkitTextNode(node) { return node._type === "@text"; } const knownDecorators = ["strong", "em", "code", "underline", "strike-through"]; function sortMarksByOccurences(span, index, blockChildren) { if (!isPortableTextSpan(span) || !span.marks) return []; if (!span.marks.length) return []; const marks = span.marks.slice(), occurences = {}; return marks.forEach(mark => { occurences[mark] = 1; for (let siblingIndex = index + 1; siblingIndex < blockChildren.length; siblingIndex++) { const sibling = blockChildren[siblingIndex]; if (sibling && isPortableTextSpan(sibling) && Array.isArray(sibling.marks) && sibling.marks.indexOf(mark) !== -1) occurences[mark]++;else break; } }), marks.sort((markA, markB) => sortMarks(occurences, markA, markB)); } function sortMarks(occurences, markA, markB) { const aOccurences = occurences[markA], bOccurences = occurences[markB]; if (aOccurences !== bOccurences) return bOccurences - aOccurences; const aKnownPos = knownDecorators.indexOf(markA), bKnownPos = knownDecorators.indexOf(markB); return aKnownPos !== bKnownPos ? aKnownPos - bKnownPos : markA.localeCompare(markB); } function buildMarksTree(block) { var _a; const { children, markDefs = [] } = block; if (!children || !children.length) return []; const sortedMarks = children.map(sortMarksByOccurences), rootNode = { _type: "@span", children: [], markType: "" }; let nodeStack = [rootNode]; for (let i = 0; i < children.length; i++) { const span = children[i]; if (!span) continue; const marksNeeded = sortedMarks[i] || []; let pos = 1; if (nodeStack.length > 1) for (pos; pos < nodeStack.length; pos++) { const mark = ((_a = nodeStack[pos]) == null ? void 0 : _a.markKey) || "", index = marksNeeded.indexOf(mark); if (index === -1) break; marksNeeded.splice(index, 1); } nodeStack = nodeStack.slice(0, pos); let currentNode = nodeStack[nodeStack.length - 1]; if (currentNode) { for (const markKey of marksNeeded) { const markDef = markDefs.find(def => def._key === markKey), markType = markDef ? markDef._type : markKey, node = { _type: "@span", _key: span._key, children: [], markDef, markType, markKey }; currentNode.children.push(node), nodeStack.push(node), currentNode = node; } if (isPortableTextSpan(span)) { const lines = span.text.split(` `); for (let line = lines.length; line-- > 1;) lines.splice(line, 0, ` `); currentNode.children = currentNode.children.concat(lines.map(text => ({ _type: "@text", text }))); } else currentNode.children = currentNode.children.concat(span); } } return rootNode.children; } function nestLists(blocks, mode) { const tree = []; let currentList; for (let i = 0; i < blocks.length; i++) { const block = blocks[i]; if (block) { if (!isPortableTextListItemBlock(block)) { tree.push(block), currentList = void 0; continue; } if (!currentList) { currentList = listFromBlock(block, i, mode), tree.push(currentList); continue; } if (blockMatchesList(block, currentList)) { currentList.children.push(block); continue; } if ((block.level || 1) > currentList.level) { const newList = listFromBlock(block, i, mode); if (mode === "html") { const lastListItem = currentList.children[currentList.children.length - 1], newLastChild = _objectSpread(_objectSpread({}, lastListItem), {}, { children: [...lastListItem.children, newList] }); currentList.children[currentList.children.length - 1] = newLastChild; } else currentList.children.push(newList); currentList = newList; continue; } if ((block.level || 1) < currentList.level) { const matchingBranch = tree[tree.length - 1], match = matchingBranch && findListMatching(matchingBranch, block); if (match) { currentList = match, currentList.children.push(block); continue; } currentList = listFromBlock(block, i, mode), tree.push(currentList); continue; } if (block.listItem !== currentList.listItem) { const matchingBranch = tree[tree.length - 1], match = matchingBranch && findListMatching(matchingBranch, { level: block.level || 1 }); if (match && match.listItem === block.listItem) { currentList = match, currentList.children.push(block); continue; } else { currentList = listFromBlock(block, i, mode), tree.push(currentList); continue; } } console.warn("Unknown state encountered for block", block), tree.push(block); } } return tree; } function blockMatchesList(block, list) { return (block.level || 1) === list.level && block.listItem === list.listItem; } function listFromBlock(block, index, mode) { return { _type: "@list", _key: `${block._key || `${index}`}-parent`, mode, level: block.level || 1, listItem: block.listItem, children: [block] }; } function findListMatching(rootNode, matching) { const level = matching.level || 1, style = matching.listItem || "normal", filterOnType = typeof matching.listItem == "string"; if (isPortableTextToolkitList(rootNode) && (rootNode.level || 1) === level && filterOnType && (rootNode.listItem || "normal") === style) return rootNode; if (!("children" in rootNode)) return; const node = rootNode.children[rootNode.children.length - 1]; return node && !isPortableTextSpan(node) ? findListMatching(node, matching) : void 0; } function spanToPlainText(span) { let text = ""; return span.children.forEach(current => { isPortableTextToolkitTextNode(current) ? text += current.text : isPortableTextToolkitSpan(current) && (text += spanToPlainText(current)); }), text; } const leadingSpace = /^\s/, trailingSpace = /\s$/; function toPlainText(block) { const blocks = Array.isArray(block) ? block : [block]; let text = ""; return blocks.forEach((current, index) => { if (!isPortableTextBlock(current)) return; let pad = !1; current.children.forEach(span => { isPortableTextSpan(span) ? (text += pad && text && !trailingSpace.test(text) && !leadingSpace.test(span.text) ? " " : "", text += span.text, pad = !1) : pad = !0; }), index !== blocks.length - 1 && (text += ` `); }), text; } const LIST_NEST_MODE_HTML = "html", LIST_NEST_MODE_DIRECT = "direct"; exports.LIST_NEST_MODE_DIRECT = LIST_NEST_MODE_DIRECT; exports.LIST_NEST_MODE_HTML = LIST_NEST_MODE_HTML; exports.buildMarksTree = buildMarksTree; exports.isPortableTextBlock = isPortableTextBlock; exports.isPortableTextListItemBlock = isPortableTextListItemBlock; exports.isPortableTextSpan = isPortableTextSpan; exports.isPortableTextToolkitList = isPortableTextToolkitList; exports.isPortableTextToolkitSpan = isPortableTextToolkitSpan; exports.isPortableTextToolkitTextNode = isPortableTextToolkitTextNode; exports.nestLists = nestLists; exports.sortMarksByOccurences = sortMarksByOccurences; exports.spanToPlainText = spanToPlainText; exports.toPlainText = toPlainText; //# sourceMappingURL=index.cjs.map