UNPKG

@curvenote/schema

Version:

Schema and markdown parser for @curvenote/editor

82 lines 3.39 kB
import { nodeNames } from '../types'; import { createId } from '../utils'; import { determineCaptionKind } from './utils'; export function modifyTransactionToValidDocState(tr) { const transactions = []; function deleteNode(node, pos) { transactions.push((next) => next.delete(pos, pos + node.nodeSize)); } // State for walk const takenIds = {}; const captionState = { deleteNext: false, kind: null, }; // This checks if the ID has been seen or is invalid, and gives a replacement function ensureIdIsValidOrCreateId(id) { const taken = id ? takenIds[id] : true; if (!id || taken) return { replace: true, id: createId() }; takenIds[id] = true; return { replace: false, id }; } tr.doc.content.descendants((node, pos) => { switch (node.type.name) { case nodeNames.figure: { captionState.deleteNext = false; captionState.kind = determineCaptionKind(node); if (node.childCount === 0) { // Delete the empty figure! deleteNode(node, pos); return false; } // Check that the ID works const { id } = node.attrs; const nextId = ensureIdIsValidOrCreateId(id); if (nextId.replace) { transactions.push((next) => next.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, node.attrs), { id: nextId.id }))); } return true; } case nodeNames.figcaption: { if (captionState.deleteNext) { // Delete the second figure caption transactions.push((next) => next.delete(pos, pos + node.nodeSize)); } else { const { kind } = node.attrs; const { kind: nextKind } = captionState; // Need to get access to the **value**, not the reference if (kind !== nextKind) { // Change the kind and id of the caption transactions.push((next) => next.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, node.attrs), { kind: nextKind }))); } } captionState.deleteNext = true; return false; } case nodeNames.heading: case nodeNames.equation: { const { id } = node.attrs; const nextId = ensureIdIsValidOrCreateId(id); if (nextId.replace) { transactions.push((next) => next.setNodeMarkup(pos, undefined, Object.assign(Object.assign({}, node.attrs), { id: nextId.id }))); } return false; } case nodeNames.table: { if (node.childCount === 0) deleteNode(node, pos); return false; } // Continue to search case nodeNames.aside: case nodeNames.callout: return true; default: return false; } }); const modified = transactions.reverse().reduce((next, chain) => chain(next), tr); return modified; } //# sourceMappingURL=modifyTransactions.js.map