UNPKG

json-joy

Version:

Collection of libraries for building collaborative editing apps.

87 lines 3.51 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FromSlate = void 0; const constants_1 = require("../peritext/rga/constants"); const constants_2 = require("../peritext/slice/constants"); const isInline = (node) => typeof node === 'object' && !!node && typeof node.text === 'string'; /** * Converts Slate.js state to a {@link ViewRange} flat string with * annotation ranges, which is the natural view format for a Peritext model. * * Usage: * * ```typescript * FromSlate.convert(node); * ``` */ class FromSlate { constructor() { this.text = ''; this.slices = []; } conv(node, path, nodeDiscriminator) { if (!node || typeof node !== 'object') return; const start = this.text.length; if ('text' in node) { const { text, ...tagMap } = node; this.text += text; const tags = Object.keys(tagMap); if (tags.length) { const end = start + text.length; for (const tag of tags) { const data = tagMap[tag]; const dataEmpty = !data || data === true; const stacking = dataEmpty ? constants_2.SliceStacking.One : constants_2.SliceStacking.Many; const header = (stacking << constants_2.SliceHeaderShift.Stacking) + (constants_1.Anchor.Before << constants_2.SliceHeaderShift.X1Anchor) + (constants_1.Anchor.After << constants_2.SliceHeaderShift.X2Anchor); const slice = [header, start, end, tag]; if (!dataEmpty) slice.push(data); this.slices.push(slice); } } } else { const element = node; const { type, children, ...data } = element; const step = nodeDiscriminator || data ? [type, nodeDiscriminator, data] : type; const length = children?.length ?? 0; const hasNoChildren = length === 0; const isFirstChildInline = isInline(children?.[0]); const doEmitSplitMarker = hasNoChildren || isFirstChildInline; if (doEmitSplitMarker) { this.text += '\n'; const header = (constants_2.SliceStacking.Marker << constants_2.SliceHeaderShift.Stacking) + (constants_1.Anchor.Before << constants_2.SliceHeaderShift.X1Anchor) + (constants_1.Anchor.Before << constants_2.SliceHeaderShift.X2Anchor); const slice = [header, start, start, [...path, step]]; this.slices.push(slice); } if (length > 0) this.cont([...path, step], children); } } 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; discriminator = tag === prevTag ? discriminator + 1 : 0; this.conv(child, path, discriminator); prevTag = tag; } } convert(node) { let length = 0; if (node && (length = node.length) > 0) this.cont([], node); return [this.text, 0, this.slices]; } } exports.FromSlate = FromSlate; FromSlate.convert = (doc) => new FromSlate().convert(doc); //# sourceMappingURL=FromSlate.js.map