UNPKG

json-joy

Version:

Collection of libraries for building collaborative editing apps.

89 lines 3.39 kB
import { Anchor } from '../peritext/rga/constants'; import { SliceHeaderShift, SliceStacking } from '../peritext/slice/constants'; /** * Converts ProseMirror raw nodes to a {@link ViewRange} flat string with * annotation ranges, which is the natural view format for a Peritext model. * * Usage: * * ```typescript * FromPm.convert(node); * ``` */ export class FromPm { static convert = (node) => new FromPm().convert(node); text = ''; slices = []; conv(node, path, nodeDiscriminator) { const text = this.text; const start = text.length; let inlineText = ''; const type = node.type.name; if (type === 'text' && (inlineText = node.text || '')) { this.text += inlineText; } else { const content = node.content?.content; const data = node.attrs; const step = nodeDiscriminator || data ? [type, nodeDiscriminator, data] : type; const length = content?.length ?? 0; const hasNoChildren = length === 0; const isFirstChildInline = content?.[0]?.type.name === 'text'; const doEmitSplitMarker = hasNoChildren || isFirstChildInline; if (doEmitSplitMarker) { this.text += '\n'; const header = (SliceStacking.Marker << SliceHeaderShift.Stacking) + (Anchor.Before << SliceHeaderShift.X1Anchor) + (Anchor.Before << SliceHeaderShift.X2Anchor); const slice = [header, start, start, [...path, step]]; this.slices.push(slice); } if (length > 0) this.cont([...path, step], content); } const marks = node.marks; let length = 0; if (marks && (length = marks.length) > 0) { const end = start + inlineText.length; for (let i = 0; i < length; i++) { const mark = marks[i]; const type = mark.type.name; const data = mark.attrs; let dataEmpty = true; for (const _ in data) { dataEmpty = false; break; } const stacking = dataEmpty ? SliceStacking.One : SliceStacking.Many; const header = (stacking << SliceHeaderShift.Stacking) + (Anchor.Before << SliceHeaderShift.X1Anchor) + (Anchor.After << SliceHeaderShift.X2Anchor); const slice = [header, start, end, type]; if (!dataEmpty) slice.push(data); this.slices.push(slice); } } } cont(path, content) { let prevTag = ''; let discriminator = 0; const length = content.length; for (let i = 0; i < length; i++) { const child = content[i]; const tag = child.type.name; discriminator = tag === prevTag ? discriminator + 1 : 0; this.conv(child, path, discriminator); prevTag = tag; } } convert(node) { const content = node.content?.content; let length = 0; if (content && (length = content.length) > 0) this.cont([], content); const view = [this.text, 0, this.slices]; return view; } } //# sourceMappingURL=FromPm.js.map