Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | 6x 6x 6x 2722x 6x 2023x 1251x 1251x 1629x 1629x 1629x 1629x 410x 410x 410x 410x 410x 5x 5x 5x 1629x 5x 5x 5x 5x 5x 1624x 1503x 1503x 1503x 405x 405x 405x 405x 405x 405x 405x 405x 389x 1503x 1251x 44x 1207x 1207x 1207x 303x 1251x 1251x 1251x 1251x 772x 772x 772x 1386x 772x 772x 772x 6x 637x 637x 637x 637x 637x | import {Slice} from 'json-joy/lib/json-crdt-extensions/peritext/slice/Slice';
import {SliceStacking} from 'json-joy/lib/json-crdt-extensions/peritext/slice/constants';
import {type Block, type Inline, LeafBlock, type Peritext} from 'json-joy/lib/json-crdt-extensions/peritext';
import type {SlateDescendantNode, SlateDocument, SlateElementNode, SlateTextNode} from '../types';
const isText = (node: SlateDescendantNode): node is SlateTextNode => typeof (node as SlateTextNode).text === 'string';
const blockToSlateNode = (block: Block | LeafBlock): SlateElementNode => {
if (block instanceof LeafBlock) {
const children: SlateDescendantNode[] = [];
for (let iterator = block.texts0(), inline: Inline | undefined; (inline = iterator()); ) {
const text = inline.text();
const attr = inline.attr();
const attrKeys = Object.keys(attr);
let atomicSlice: Slice | undefined;
let atomicTag: string | undefined;
for (const tag of attrKeys) {
const stack = attr[tag];
Iif (!stack || stack.length <= 0) continue;
const slice = stack[0].slice;
Iif (!(slice instanceof Slice)) continue;
if (slice.stacking === SliceStacking.Atomic) {
atomicSlice = slice;
atomicTag = tag;
break;
}
}
if (atomicSlice && atomicTag !== undefined) {
const data = atomicSlice.data();
const inlineEl: SlateElementNode = {
type: atomicTag,
children: [{text: ''}],
};
Eif (data && typeof data === 'object' && !Array.isArray(data)) Object.assign(inlineEl, data);
children.push(inlineEl);
continue;
}
if (!text && attrKeys.length === 0) continue;
const textNode: SlateTextNode = {text: text || ''};
const length = attrKeys.length;
ATTRS: for (let i = 0; i < length; i++) {
const tag = attrKeys[i];
const stack = attr[tag];
Iif (!stack || stack.length <= 0) continue ATTRS;
const slice = stack[0].slice;
Iif (!(slice instanceof Slice)) continue ATTRS;
Iif (slice.stacking === SliceStacking.Atomic) continue ATTRS;
const data = slice.data();
if (data && typeof data === 'object' && !Array.isArray(data)) Object.assign(textNode, {[tag]: data});
else textNode[tag] = data !== undefined ? data : true;
}
children.push(textNode);
}
// Slate requires text nodes around inline elements; bracket the run
// with empty text nodes when needed.
if (children.length === 0) {
children.push({text: ''});
} else {
if (!isText(children[0])) children.unshift({text: ''});
if (!isText(children[children.length - 1])) children.push({text: ''});
for (let i = 1; i < children.length; i++) {
Iif (!isText(children[i]) && !isText(children[i - 1])) {
children.splice(i, 0, {text: ''});
i++;
}
}
}
const node: SlateElementNode = {
type: block.tag() + '',
children: children as any,
};
const attr = block.attr();
Eif (typeof attr === 'object') Object.assign(node, attr);
return node;
} else {
const children: SlateElementNode[] = [];
const blockChildren = block.children;
const length = blockChildren.length;
for (let i = 0; i < length; i++) children.push(blockToSlateNode(blockChildren[i]));
const attr = block.attr();
const node: SlateElementNode = {
...(attr && typeof attr === 'object' ? attr : {}),
type: block.tag() + '',
children: children.length ? children : [{text: ''}],
};
return node;
}
};
export const toSlate = (txt: Peritext): SlateDocument => {
txt.refresh();
const block = txt.blocks.root;
const node = blockToSlateNode(block);
const content: SlateDocument = (node?.children ?? []) as SlateDocument;
return content;
};
|