UNPKG

@curvenote/schema

Version:

Schema and markdown parser for @curvenote/editor

124 lines 4.9 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.transformNumericalFootnotes = exports.convertToMdastSnippet = exports.convertToMdast = exports.nodeToMdast = void 0; const prosemirror_model_1 = require("prosemirror-model"); const mystjs_1 = require("mystjs"); const document_1 = require("./document"); const types_1 = require("../../types"); const schemas_1 = require("../../schemas"); const utils_1 = require("../../utils"); /** * This uses the DOMSerializer from prosemirror-model to serialize to html * The document used is a fake one that is passed to react. */ function getSerializer(schema) { const nodes = Object.fromEntries(Object.entries(schema.nodes) .map(([k, nodeType]) => { const { toDOM } = nodeType.spec; if (!toDOM) return undefined; const wrapper = (node) => { const spec = toDOM(node); return [`${node.type.name} ${spec[0]}`, ...spec.slice(1)]; }; return [k, wrapper]; }) .filter((v) => v)); // We must include the text node! if (!nodes.text) nodes.text = (node) => node.text; const marks = Object.fromEntries(Object.entries(schema.marks) .map(([k, markType]) => { const { toDOM } = markType.spec; if (!toDOM) return undefined; const wrapper = (mark, inline) => { const spec = toDOM(mark, inline); return [`${mark.type.name} ${spec[0]}`, ...spec.slice(1)]; }; return [k, wrapper]; }) .filter((v) => v)); return new prosemirror_model_1.DOMSerializer(nodes, marks); } function nodeToMdast(fragment, schema, opts) { if (fragment.length === 0) return []; return fragment.map((node) => { if (node instanceof document_1.Node) { const children = nodeToMdast(node.children, schema, opts); const props = Object.assign(Object.assign({ key: node.id, tag: node.tag, name: node.name }, node.attrs), { children }); if (node.name in types_1.nodeNames) { return schema.nodes[node.name].spec.toMyst(props, opts); } if (node.name in types_1.markNames) { return schema.marks[node.name].spec.toMyst(props, opts); } throw new Error(`Node for "${node.name}" is not defined.`); } const textNode = { type: 'text', value: node.text }; return textNode; }); } exports.nodeToMdast = nodeToMdast; function convertToMdast(node, opts) { const schema = (0, schemas_1.getSchema)(opts.useSchema || 'full'); const serializer = getSerializer(schema); const dom = serializer.serializeFragment(node.content, { document: (0, document_1.createDocument)(), }); const root = { type: 'root', children: nodeToMdast(dom.children, schema, opts) }; const footnotes = (0, mystjs_1.selectAll)('inlineFootnote', root); const footnoteDefinitions = []; footnotes.forEach((footnote) => { const id = (0, utils_1.createId)(); footnoteDefinitions.push({ type: 'footnoteDefinition', identifier: id, label: id, children: footnote.children, }); delete footnote.children; const ref = footnote; ref.type = 'footnoteReference'; ref.identifier = id; ref.label = id; }); root.children.push(...footnoteDefinitions); return root; } exports.convertToMdast = convertToMdast; function convertToMdastSnippet(node, opts) { var _a, _b; if (node.type.name === 'doc') { throw new Error('The requested mdast snippet is a document, use convertToMdast.'); } // If the node is not a top level, wrap it in a document and return that! const schema = (0, schemas_1.getSchema)(opts.useSchema || 'full'); const { doc } = schema.nodes; const wrapped = doc.create({}, [node]); return (_b = (_a = convertToMdast(wrapped, opts)) === null || _a === void 0 ? void 0 : _a.children) === null || _b === void 0 ? void 0 : _b[0]; } exports.convertToMdastSnippet = convertToMdastSnippet; function transformNumericalFootnotes(root) { const defLookup = {}; const defs = (0, mystjs_1.selectAll)('footnoteDefinition', root); defs.forEach((def) => { defLookup[def.identifier] = def; }); const refs = (0, mystjs_1.selectAll)('footnoteReference', root); refs.forEach((ref, index) => { const refDef = defLookup[ref.identifier]; let id = String(index + 1); if (refDef.identifier !== ref.identifier) { id = refDef.identifier; } refDef.identifier = id; refDef.label = id; ref.identifier = id; ref.label = id; }); return root; } exports.transformNumericalFootnotes = transformNumericalFootnotes; //# sourceMappingURL=convertToMdast.js.map