🚀 Socket Launch Week Day 5:Introducing Repository Access Permissions and Custom Roles.Learn more
Sign In

@milkdown/transformer

Package Overview
Dependencies
Maintainers
1
Versions
106
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@milkdown/transformer - npm Package Compare versions

Comparing version
7.19.0
to
7.19.1
+378
-431
lib/index.js

@@ -1,437 +0,384 @@

var __typeError = (msg) => {
throw TypeError(msg);
};
var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
var _marks, _hasText, _maybeMerge, _matchTarget, _runNode, _closeNodeAndPush, _addNodeAndPush, _marks2, _matchTarget2, _runProseNode, _runProseMark, _runNode2, _searchType, _maybeMergeChildren, _createMarkdownNode, _moveSpaces, _closeNodeAndPush2, _addNodeAndPush2, _openMark, _closeMark;
import { stackOverFlow, parserMatchError, createNodeInParserFail, serializerMatchError } from "@milkdown/exception";
import { createNodeInParserFail, parserMatchError, serializerMatchError, stackOverFlow } from "@milkdown/exception";
import { Mark } from "@milkdown/prose/model";
class StackElement {
}
class Stack {
constructor() {
this.elements = [];
this.size = () => {
return this.elements.length;
};
this.top = () => {
return this.elements.at(-1);
};
this.push = (node) => {
this.top()?.push(node);
};
this.open = (node) => {
this.elements.push(node);
};
this.close = () => {
const el = this.elements.pop();
if (!el) throw stackOverFlow();
return el;
};
}
}
class ParserStackElement extends StackElement {
constructor(type, content, attrs) {
super();
this.type = type;
this.content = content;
this.attrs = attrs;
}
push(node, ...rest) {
this.content.push(node, ...rest);
}
pop() {
return this.content.pop();
}
static create(type, content, attrs) {
return new ParserStackElement(type, content, attrs);
}
}
const _ParserState = class _ParserState extends Stack {
/// @internal
constructor(schema) {
super();
__privateAdd(this, _marks);
__privateAdd(this, _hasText);
__privateAdd(this, _maybeMerge);
__privateAdd(this, _matchTarget);
__privateAdd(this, _runNode);
__privateAdd(this, _closeNodeAndPush);
__privateAdd(this, _addNodeAndPush);
__privateSet(this, _marks, Mark.none);
__privateSet(this, _hasText, (node) => node.isText);
__privateSet(this, _maybeMerge, (a, b) => {
if (__privateGet(this, _hasText).call(this, a) && __privateGet(this, _hasText).call(this, b) && Mark.sameSet(a.marks, b.marks))
return this.schema.text(a.text + b.text, a.marks);
return void 0;
});
__privateSet(this, _matchTarget, (node) => {
const result = Object.values({
...this.schema.nodes,
...this.schema.marks
}).find((x) => {
const spec = x.spec;
return spec.parseMarkdown.match(node);
});
if (!result) throw parserMatchError(node);
return result;
});
__privateSet(this, _runNode, (node) => {
const type = __privateGet(this, _matchTarget).call(this, node);
const spec = type.spec;
spec.parseMarkdown.runner(this, node, type);
});
this.injectRoot = (node, nodeType, attrs) => {
this.openNode(nodeType, attrs);
this.next(node.children);
return this;
};
this.openNode = (nodeType, attrs) => {
this.open(ParserStackElement.create(nodeType, [], attrs));
return this;
};
__privateSet(this, _closeNodeAndPush, () => {
__privateSet(this, _marks, Mark.none);
const element = this.close();
return __privateGet(this, _addNodeAndPush).call(this, element.type, element.attrs, element.content);
});
this.closeNode = () => {
try {
__privateGet(this, _closeNodeAndPush).call(this);
} catch (e) {
console.error(e);
}
return this;
};
__privateSet(this, _addNodeAndPush, (nodeType, attrs, content) => {
const node = nodeType.createAndFill(attrs, content, __privateGet(this, _marks));
if (!node) throw createNodeInParserFail(nodeType, attrs, content);
this.push(node);
return node;
});
this.addNode = (nodeType, attrs, content) => {
try {
__privateGet(this, _addNodeAndPush).call(this, nodeType, attrs, content);
} catch (e) {
console.error(e);
}
return this;
};
this.openMark = (markType, attrs) => {
const mark = markType.create(attrs);
__privateSet(this, _marks, mark.addToSet(__privateGet(this, _marks)));
return this;
};
this.closeMark = (markType) => {
__privateSet(this, _marks, markType.removeFromSet(__privateGet(this, _marks)));
return this;
};
this.addText = (text) => {
try {
const topElement = this.top();
if (!topElement) throw stackOverFlow();
const prevNode = topElement.pop();
const currNode = this.schema.text(text, __privateGet(this, _marks));
if (!prevNode) {
topElement.push(currNode);
return this;
}
const merged = __privateGet(this, _maybeMerge).call(this, prevNode, currNode);
if (merged) {
topElement.push(merged);
return this;
}
topElement.push(prevNode, currNode);
return this;
} catch (e) {
console.error(e);
return this;
}
};
this.build = () => {
let doc;
do
doc = __privateGet(this, _closeNodeAndPush).call(this);
while (this.size());
return doc;
};
this.next = (nodes = []) => {
[nodes].flat().forEach((node) => __privateGet(this, _runNode).call(this, node));
return this;
};
this.toDoc = () => this.build();
this.run = (remark, markdown) => {
const tree = remark.runSync(
remark.parse(markdown),
markdown
);
this.next(tree);
return this;
};
this.schema = schema;
}
//#region src/utility/stack.ts
var StackElement = class {};
var Stack = class {
constructor() {
this.elements = [];
this.size = () => {
return this.elements.length;
};
this.top = () => {
return this.elements.at(-1);
};
this.push = (node) => {
this.top()?.push(node);
};
this.open = (node) => {
this.elements.push(node);
};
this.close = () => {
const el = this.elements.pop();
if (!el) throw stackOverFlow();
return el;
};
}
};
_marks = new WeakMap();
_hasText = new WeakMap();
_maybeMerge = new WeakMap();
_matchTarget = new WeakMap();
_runNode = new WeakMap();
_closeNodeAndPush = new WeakMap();
_addNodeAndPush = new WeakMap();
_ParserState.create = (schema, remark) => {
const state = new _ParserState(schema);
return (text) => {
state.run(remark, text);
return state.toDoc();
};
//#endregion
//#region src/parser/stack-element.ts
var ParserStackElement = class ParserStackElement extends StackElement {
constructor(type, content, attrs) {
super();
this.type = type;
this.content = content;
this.attrs = attrs;
}
push(node, ...rest) {
this.content.push(node, ...rest);
}
pop() {
return this.content.pop();
}
static create(type, content, attrs) {
return new ParserStackElement(type, content, attrs);
}
};
let ParserState = _ParserState;
const _SerializerStackElement = class _SerializerStackElement extends StackElement {
constructor(type, children, value, props = {}) {
super();
this.type = type;
this.children = children;
this.value = value;
this.props = props;
this.push = (node, ...rest) => {
if (!this.children) this.children = [];
this.children.push(node, ...rest);
};
this.pop = () => this.children?.pop();
}
//#endregion
//#region src/parser/state.ts
var ParserState = class extends Stack {
#marks = Mark.none;
static {
this.create = (schema, remark) => {
const state = new this(schema);
return (text) => {
state.run(remark, text);
return state.toDoc();
};
};
}
constructor(schema) {
super();
this.injectRoot = (node, nodeType, attrs) => {
this.openNode(nodeType, attrs);
this.next(node.children);
return this;
};
this.openNode = (nodeType, attrs) => {
this.open(ParserStackElement.create(nodeType, [], attrs));
return this;
};
this.closeNode = () => {
try {
this.#closeNodeAndPush();
} catch (e) {
console.error(e);
}
return this;
};
this.addNode = (nodeType, attrs, content) => {
try {
this.#addNodeAndPush(nodeType, attrs, content);
} catch (e) {
console.error(e);
}
return this;
};
this.openMark = (markType, attrs) => {
this.#marks = markType.create(attrs).addToSet(this.#marks);
return this;
};
this.closeMark = (markType) => {
this.#marks = markType.removeFromSet(this.#marks);
return this;
};
this.addText = (text) => {
try {
const topElement = this.top();
if (!topElement) throw stackOverFlow();
const prevNode = topElement.pop();
const currNode = this.schema.text(text, this.#marks);
if (!prevNode) {
topElement.push(currNode);
return this;
}
const merged = this.#maybeMerge(prevNode, currNode);
if (merged) {
topElement.push(merged);
return this;
}
topElement.push(prevNode, currNode);
return this;
} catch (e) {
console.error(e);
return this;
}
};
this.build = () => {
let doc;
do
doc = this.#closeNodeAndPush();
while (this.size());
return doc;
};
this.next = (nodes = []) => {
[nodes].flat().forEach((node) => this.#runNode(node));
return this;
};
this.toDoc = () => this.build();
this.run = (remark, markdown) => {
const tree = remark.runSync(remark.parse(markdown), markdown);
this.next(tree);
return this;
};
this.schema = schema;
}
#hasText = (node) => node.isText;
#maybeMerge = (a, b) => {
if (this.#hasText(a) && this.#hasText(b) && Mark.sameSet(a.marks, b.marks)) return this.schema.text(a.text + b.text, a.marks);
};
#matchTarget = (node) => {
const result = Object.values({
...this.schema.nodes,
...this.schema.marks
}).find((x) => {
return x.spec.parseMarkdown.match(node);
});
if (!result) throw parserMatchError(node);
return result;
};
#runNode = (node) => {
const type = this.#matchTarget(node);
type.spec.parseMarkdown.runner(this, node, type);
};
#closeNodeAndPush = () => {
this.#marks = Mark.none;
const element = this.close();
return this.#addNodeAndPush(element.type, element.attrs, element.content);
};
#addNodeAndPush = (nodeType, attrs, content) => {
const node = nodeType.createAndFill(attrs, content, this.#marks);
if (!node) throw createNodeInParserFail(nodeType, attrs, content);
this.push(node);
return node;
};
};
_SerializerStackElement.create = (type, children, value, props = {}) => new _SerializerStackElement(type, children, value, props);
let SerializerStackElement = _SerializerStackElement;
const isFragment = (x) => Object.prototype.hasOwnProperty.call(x, "size");
const _SerializerState = class _SerializerState extends Stack {
/// @internal
constructor(schema) {
super();
__privateAdd(this, _marks2);
__privateAdd(this, _matchTarget2);
__privateAdd(this, _runProseNode);
__privateAdd(this, _runProseMark);
__privateAdd(this, _runNode2);
__privateAdd(this, _searchType);
__privateAdd(this, _maybeMergeChildren);
__privateAdd(this, _createMarkdownNode);
__privateAdd(this, _moveSpaces);
__privateAdd(this, _closeNodeAndPush2);
__privateAdd(this, _addNodeAndPush2);
__privateAdd(this, _openMark);
__privateAdd(this, _closeMark);
__privateSet(this, _marks2, Mark.none);
__privateSet(this, _matchTarget2, (node) => {
const result = Object.values({
...this.schema.nodes,
...this.schema.marks
}).find((x) => {
const spec = x.spec;
return spec.toMarkdown.match(node);
});
if (!result) throw serializerMatchError(node.type);
return result;
});
__privateSet(this, _runProseNode, (node) => {
const type = __privateGet(this, _matchTarget2).call(this, node);
const spec = type.spec;
return spec.toMarkdown.runner(this, node);
});
__privateSet(this, _runProseMark, (mark, node) => {
const type = __privateGet(this, _matchTarget2).call(this, mark);
const spec = type.spec;
return spec.toMarkdown.runner(this, mark, node);
});
__privateSet(this, _runNode2, (node) => {
const { marks } = node;
const getPriority = (x) => x.type.spec.priority ?? 50;
const tmp = [...marks].sort((a, b) => getPriority(a) - getPriority(b));
const unPreventNext = tmp.every((mark) => !__privateGet(this, _runProseMark).call(this, mark, node));
if (unPreventNext) __privateGet(this, _runProseNode).call(this, node);
marks.forEach((mark) => __privateGet(this, _closeMark).call(this, mark));
});
__privateSet(this, _searchType, (child, type) => {
if (child.type === type) return child;
if (child.children?.length !== 1) return child;
const searchNode = (node2) => {
if (node2.type === type) return node2;
if (node2.children?.length !== 1) return null;
const [firstChild] = node2.children;
if (!firstChild) return null;
return searchNode(firstChild);
};
const target = searchNode(child);
if (!target) return child;
const tmp = target.children ? [...target.children] : void 0;
const node = { ...child, children: tmp };
node.children = tmp;
target.children = [node];
return target;
});
__privateSet(this, _maybeMergeChildren, (node) => {
const { children } = node;
if (!children) return node;
node.children = children.reduce((nextChildren, child, index) => {
if (index === 0) return [child];
const last = nextChildren.at(-1);
if (last && last.isMark && child.isMark) {
child = __privateGet(this, _searchType).call(this, child, last.type);
const { children: currChildren, ...currRest } = child;
const { children: prevChildren, ...prevRest } = last;
if (child.type === last.type && currChildren && prevChildren && JSON.stringify(currRest) === JSON.stringify(prevRest)) {
const next = {
...prevRest,
children: [...prevChildren, ...currChildren]
};
return nextChildren.slice(0, -1).concat(__privateGet(this, _maybeMergeChildren).call(this, next));
}
}
return nextChildren.concat(child);
}, []);
return node;
});
__privateSet(this, _createMarkdownNode, (element) => {
const node = {
...element.props,
type: element.type
};
if (element.children) node.children = element.children;
if (element.value) node.value = element.value;
return node;
});
this.openNode = (type, value, props) => {
this.open(SerializerStackElement.create(type, void 0, value, props));
return this;
};
__privateSet(this, _moveSpaces, (element, onPush) => {
let startSpaces = "";
let endSpaces = "";
const children = element.children;
let first = -1;
let last = -1;
const findIndex = (node) => {
if (!node) return;
node.forEach((child, index) => {
if (child.type === "text" && child.value) {
if (first < 0) first = index;
last = index;
}
});
};
if (children) {
findIndex(children);
const lastChild = children?.[last];
const firstChild = children?.[first];
if (lastChild && lastChild.value.endsWith(" ")) {
const text = lastChild.value;
const trimmed = text.trimEnd();
endSpaces = text.slice(trimmed.length);
lastChild.value = trimmed;
}
if (firstChild && firstChild.value.startsWith(" ")) {
const text = firstChild.value;
const trimmed = text.trimStart();
startSpaces = text.slice(0, text.length - trimmed.length);
firstChild.value = trimmed;
}
}
if (startSpaces.length) __privateGet(this, _addNodeAndPush2).call(this, "text", void 0, startSpaces);
const result = onPush();
if (endSpaces.length) __privateGet(this, _addNodeAndPush2).call(this, "text", void 0, endSpaces);
return result;
});
__privateSet(this, _closeNodeAndPush2, (trim = false) => {
const element = this.close();
const onPush = () => __privateGet(this, _addNodeAndPush2).call(this, element.type, element.children, element.value, element.props);
if (trim) return __privateGet(this, _moveSpaces).call(this, element, onPush);
return onPush();
});
this.closeNode = () => {
__privateGet(this, _closeNodeAndPush2).call(this);
return this;
};
__privateSet(this, _addNodeAndPush2, (type, children, value, props) => {
const element = SerializerStackElement.create(type, children, value, props);
const node = __privateGet(this, _maybeMergeChildren).call(this, __privateGet(this, _createMarkdownNode).call(this, element));
this.push(node);
return node;
});
this.addNode = (type, children, value, props) => {
__privateGet(this, _addNodeAndPush2).call(this, type, children, value, props);
return this;
};
__privateSet(this, _openMark, (mark, type, value, props) => {
const isIn = mark.isInSet(__privateGet(this, _marks2));
if (isIn) return this;
__privateSet(this, _marks2, mark.addToSet(__privateGet(this, _marks2)));
return this.openNode(type, value, { ...props, isMark: true });
});
__privateSet(this, _closeMark, (mark) => {
const isIn = mark.isInSet(__privateGet(this, _marks2));
if (!isIn) return;
__privateSet(this, _marks2, mark.type.removeFromSet(__privateGet(this, _marks2)));
__privateGet(this, _closeNodeAndPush2).call(this, true);
});
this.withMark = (mark, type, value, props) => {
__privateGet(this, _openMark).call(this, mark, type, value, props);
return this;
};
this.closeMark = (mark) => {
__privateGet(this, _closeMark).call(this, mark);
return this;
};
this.build = () => {
let doc = null;
do
doc = __privateGet(this, _closeNodeAndPush2).call(this);
while (this.size());
return doc;
};
this.next = (nodes) => {
if (isFragment(nodes)) {
nodes.forEach((node) => {
__privateGet(this, _runNode2).call(this, node);
});
return this;
}
__privateGet(this, _runNode2).call(this, nodes);
return this;
};
this.toString = (remark) => remark.stringify(this.build());
this.run = (tree) => {
this.next(tree);
return this;
};
this.schema = schema;
}
//#endregion
//#region src/serializer/stack-element.ts
var SerializerStackElement = class SerializerStackElement extends StackElement {
constructor(type, children, value, props = {}) {
super();
this.type = type;
this.children = children;
this.value = value;
this.props = props;
this.push = (node, ...rest) => {
if (!this.children) this.children = [];
this.children.push(node, ...rest);
};
this.pop = () => this.children?.pop();
}
static {
this.create = (type, children, value, props = {}) => new SerializerStackElement(type, children, value, props);
}
};
_marks2 = new WeakMap();
_matchTarget2 = new WeakMap();
_runProseNode = new WeakMap();
_runProseMark = new WeakMap();
_runNode2 = new WeakMap();
_searchType = new WeakMap();
_maybeMergeChildren = new WeakMap();
_createMarkdownNode = new WeakMap();
_moveSpaces = new WeakMap();
_closeNodeAndPush2 = new WeakMap();
_addNodeAndPush2 = new WeakMap();
_openMark = new WeakMap();
_closeMark = new WeakMap();
_SerializerState.create = (schema, remark) => {
const state = new _SerializerState(schema);
return (content) => {
state.run(content);
return state.toString(remark);
};
//#endregion
//#region src/serializer/state.ts
var isFragment = (x) => Object.prototype.hasOwnProperty.call(x, "size");
var SerializerState = class extends Stack {
#marks = Mark.none;
static {
this.create = (schema, remark) => {
const state = new this(schema);
return (content) => {
state.run(content);
return state.toString(remark);
};
};
}
constructor(schema) {
super();
this.openNode = (type, value, props) => {
this.open(SerializerStackElement.create(type, void 0, value, props));
return this;
};
this.closeNode = () => {
this.#closeNodeAndPush();
return this;
};
this.addNode = (type, children, value, props) => {
this.#addNodeAndPush(type, children, value, props);
return this;
};
this.withMark = (mark, type, value, props) => {
this.#openMark(mark, type, value, props);
return this;
};
this.closeMark = (mark) => {
this.#closeMark(mark);
return this;
};
this.build = () => {
let doc = null;
do
doc = this.#closeNodeAndPush();
while (this.size());
return doc;
};
this.next = (nodes) => {
if (isFragment(nodes)) {
nodes.forEach((node) => {
this.#runNode(node);
});
return this;
}
this.#runNode(nodes);
return this;
};
this.toString = (remark) => remark.stringify(this.build());
this.run = (tree) => {
this.next(tree);
return this;
};
this.schema = schema;
}
#matchTarget = (node) => {
const result = Object.values({
...this.schema.nodes,
...this.schema.marks
}).find((x) => {
return x.spec.toMarkdown.match(node);
});
if (!result) throw serializerMatchError(node.type);
return result;
};
#runProseNode = (node) => {
return this.#matchTarget(node).spec.toMarkdown.runner(this, node);
};
#runProseMark = (mark, node) => {
return this.#matchTarget(mark).spec.toMarkdown.runner(this, mark, node);
};
#runNode = (node) => {
const { marks } = node;
const getPriority = (x) => x.type.spec.priority ?? 50;
if ([...marks].sort((a, b) => getPriority(a) - getPriority(b)).every((mark) => !this.#runProseMark(mark, node))) this.#runProseNode(node);
marks.forEach((mark) => this.#closeMark(mark));
};
#searchType = (child, type) => {
if (child.type === type) return child;
if (child.children?.length !== 1) return child;
const searchNode = (node) => {
if (node.type === type) return node.value != null ? null : node;
if (node.children?.length !== 1) return null;
const [firstChild] = node.children;
if (!firstChild) return null;
return searchNode(firstChild);
};
const target = searchNode(child);
if (!target) return child;
const tmp = target.children ? [...target.children] : void 0;
const node = {
...child,
children: tmp
};
node.children = tmp;
target.children = [node];
return target;
};
#maybeMergeChildren = (node) => {
const { children } = node;
if (!children) return node;
node.children = children.reduce((nextChildren, child, index) => {
if (index === 0) return [child];
const last = nextChildren.at(-1);
if (last && last.isMark && child.isMark) {
child = this.#searchType(child, last.type);
const { children: currChildren, ...currRest } = child;
const { children: prevChildren, ...prevRest } = last;
if (child.type === last.type && currChildren && prevChildren && JSON.stringify(currRest) === JSON.stringify(prevRest)) {
const next = {
...prevRest,
children: [...prevChildren, ...currChildren]
};
return nextChildren.slice(0, -1).concat(this.#maybeMergeChildren(next));
}
}
return nextChildren.concat(child);
}, []);
return node;
};
#createMarkdownNode = (element) => {
const node = {
...element.props,
type: element.type
};
if (element.children) node.children = element.children;
if (element.value) node.value = element.value;
return node;
};
#moveSpaces = (element, onPush) => {
let startSpaces = "";
let endSpaces = "";
const children = element.children;
let first = -1;
let last = -1;
const findIndex = (node) => {
if (!node) return;
node.forEach((child, index) => {
if (child.type === "text" && child.value) {
if (first < 0) first = index;
last = index;
}
});
};
if (children) {
findIndex(children);
const lastChild = children?.[last];
const firstChild = children?.[first];
if (lastChild && lastChild.value.endsWith(" ")) {
const text = lastChild.value;
const trimmed = text.trimEnd();
endSpaces = text.slice(trimmed.length);
lastChild.value = trimmed;
}
if (firstChild && firstChild.value.startsWith(" ")) {
const text = firstChild.value;
const trimmed = text.trimStart();
startSpaces = text.slice(0, text.length - trimmed.length);
firstChild.value = trimmed;
}
}
if (startSpaces.length) this.#addNodeAndPush("text", void 0, startSpaces);
const result = onPush();
if (endSpaces.length) this.#addNodeAndPush("text", void 0, endSpaces);
return result;
};
#closeNodeAndPush = (trim = false) => {
const element = this.close();
const onPush = () => this.#addNodeAndPush(element.type, element.children, element.value, element.props);
if (trim) return this.#moveSpaces(element, onPush);
return onPush();
};
#addNodeAndPush = (type, children, value, props) => {
const element = SerializerStackElement.create(type, children, value, props);
const node = this.#maybeMergeChildren(this.#createMarkdownNode(element));
this.push(node);
return node;
};
#openMark = (mark, type, value, props) => {
if (mark.isInSet(this.#marks)) return this;
this.#marks = mark.addToSet(this.#marks);
return this.openNode(type, value, {
...props,
isMark: true
});
};
#closeMark = (mark) => {
if (!mark.isInSet(this.#marks)) return;
this.#marks = mark.type.removeFromSet(this.#marks);
this.#closeNodeAndPush(true);
};
};
let SerializerState = _SerializerState;
export {
ParserState,
SerializerState,
Stack,
StackElement
};
//# sourceMappingURL=index.js.map
//#endregion
export { ParserState, SerializerState, Stack, StackElement };
//# sourceMappingURL=index.js.map

@@ -1,1 +0,1 @@

{"version":3,"file":"index.js","sources":["../src/utility/stack.ts","../src/parser/stack-element.ts","../src/parser/state.ts","../src/serializer/stack-element.ts","../src/serializer/state.ts"],"sourcesContent":["import { stackOverFlow } from '@milkdown/exception'\n\n/// The element of the stack, which holds an array of nodes.\nexport abstract class StackElement<Node> {\n /// A method that can `push` a node into the element.\n abstract push(node: Node, ...rest: Node[]): void\n}\n\n/// The stack that is used to store the elements.\n///\n/// > Generally, you don't need to use this class directly.\n///\n/// When using the stack, users can call `stack.open` to push a new element into the stack.\n/// And use `stack.push` to push a node into the top element.\n/// Then use `stack.close` to close the top element and pop it.\n///\n/// For example: `stack.open(A).push(B).push(C).close()` will generate a structure like `A(B, C)`.\nexport class Stack<Node, Element extends StackElement<Node>> {\n protected elements: Element[] = []\n\n /// Get the size of the stack.\n size = (): number => {\n return this.elements.length\n }\n\n /// Get the top element of the stack.\n top = (): Element | undefined => {\n return this.elements.at(-1)\n }\n\n /// Push a node into the top element.\n push = (node: Node): void => {\n this.top()?.push(node)\n }\n\n /// Push a new element.\n open = (node: Element): void => {\n this.elements.push(node)\n }\n\n /// Close the top element and pop it.\n close = (): Element => {\n const el = this.elements.pop()\n if (!el) throw stackOverFlow()\n\n return el\n }\n}\n","import type { Attrs, Node, NodeType } from '@milkdown/prose/model'\n\nimport { StackElement } from '../utility'\n\nexport class ParserStackElement extends StackElement<Node> {\n constructor(\n public type: NodeType,\n public content: Node[],\n public attrs?: Attrs\n ) {\n super()\n }\n\n push(node: Node, ...rest: Node[]) {\n this.content.push(node, ...rest)\n }\n\n pop(): Node | undefined {\n return this.content.pop()\n }\n\n static create(type: NodeType, content: Node[], attrs?: Attrs) {\n return new ParserStackElement(type, content, attrs)\n }\n}\n","import type {\n Attrs,\n MarkType,\n Node,\n NodeType,\n Schema,\n} from '@milkdown/prose/model'\n\nimport {\n createNodeInParserFail,\n parserMatchError,\n stackOverFlow,\n} from '@milkdown/exception'\nimport { Mark } from '@milkdown/prose/model'\n\nimport type {\n MarkSchema,\n MarkdownNode,\n NodeSchema,\n RemarkParser,\n} from '../utility'\nimport type { Parser } from './types'\n\nimport { Stack } from '../utility'\nimport { ParserStackElement } from './stack-element'\n\n/// A state machine for parser. Transform remark AST into prosemirror state.\nexport class ParserState extends Stack<Node, ParserStackElement> {\n /// The schema in current editor.\n readonly schema: Schema\n\n /// @internal\n #marks: readonly Mark[] = Mark.none\n\n /// Create a parser from schema and remark instance.\n ///\n /// ```typescript\n /// const parser = ParserState.create(schema, remark)\n /// const prosemirrorNode = parser(SomeMarkdownText)\n /// ```\n static create = (schema: Schema, remark: RemarkParser): Parser => {\n const state = new this(schema)\n return (text) => {\n state.run(remark, text)\n return state.toDoc()\n }\n }\n\n /// @internal\n constructor(schema: Schema) {\n super()\n this.schema = schema\n }\n\n /// @internal\n #hasText = (node: Node): node is Node & { text: string } => node.isText\n\n /// @internal\n #maybeMerge = (a: Node, b: Node): Node | undefined => {\n if (this.#hasText(a) && this.#hasText(b) && Mark.sameSet(a.marks, b.marks))\n return this.schema.text(a.text + b.text, a.marks)\n\n return undefined\n }\n\n /// @internal\n #matchTarget = (node: MarkdownNode): NodeType | MarkType => {\n const result = Object.values({\n ...this.schema.nodes,\n ...this.schema.marks,\n }).find((x): x is NodeType | MarkType => {\n const spec = x.spec as NodeSchema | MarkSchema\n return spec.parseMarkdown.match(node)\n })\n\n if (!result) throw parserMatchError(node)\n\n return result\n }\n\n /// @internal\n #runNode = (node: MarkdownNode) => {\n const type = this.#matchTarget(node)\n const spec = type.spec as NodeSchema | MarkSchema\n\n spec.parseMarkdown.runner(this, node, type as NodeType & MarkType)\n }\n\n /// Inject root node for prosemirror state.\n injectRoot = (node: MarkdownNode, nodeType: NodeType, attrs?: Attrs) => {\n this.openNode(nodeType, attrs)\n this.next(node.children)\n\n return this\n }\n\n /// Open a new node, the next operations will\n /// add nodes into that new node until `closeNode` is called.\n openNode = (nodeType: NodeType, attrs?: Attrs) => {\n this.open(ParserStackElement.create(nodeType, [], attrs))\n return this\n }\n\n /// @internal\n #closeNodeAndPush = (): Node => {\n this.#marks = Mark.none\n const element = this.close()\n\n return this.#addNodeAndPush(element.type, element.attrs, element.content)\n }\n\n /// Close the current node and push it into the parent node.\n closeNode = () => {\n try {\n this.#closeNodeAndPush()\n } catch (e) {\n console.error(e)\n }\n return this\n }\n\n /// @internal\n #addNodeAndPush = (\n nodeType: NodeType,\n attrs?: Attrs,\n content?: Node[]\n ): Node => {\n const node = nodeType.createAndFill(attrs, content, this.#marks)\n if (!node) throw createNodeInParserFail(nodeType, attrs, content)\n\n this.push(node)\n\n return node\n }\n\n /// Add a node into current node.\n addNode = (nodeType: NodeType, attrs?: Attrs, content?: Node[]) => {\n try {\n this.#addNodeAndPush(nodeType, attrs, content)\n } catch (e) {\n console.error(e)\n }\n return this\n }\n\n /// Open a new mark, the next nodes added will have that mark.\n openMark = (markType: MarkType, attrs?: Attrs) => {\n const mark = markType.create(attrs)\n\n this.#marks = mark.addToSet(this.#marks)\n return this\n }\n\n /// Close a opened mark.\n closeMark = (markType: MarkType) => {\n this.#marks = markType.removeFromSet(this.#marks)\n return this\n }\n\n /// Add a text node into current node.\n addText = (text: string) => {\n try {\n const topElement = this.top()\n if (!topElement) throw stackOverFlow()\n\n const prevNode = topElement.pop()\n const currNode = this.schema.text(text, this.#marks)\n\n if (!prevNode) {\n topElement.push(currNode)\n return this\n }\n\n const merged = this.#maybeMerge(prevNode, currNode)\n if (merged) {\n topElement.push(merged)\n return this\n }\n topElement.push(prevNode, currNode)\n return this\n } catch (e) {\n console.error(e)\n return this\n }\n }\n\n /// @internal\n build = (): Node => {\n let doc: Node | undefined\n\n do doc = this.#closeNodeAndPush()\n while (this.size())\n\n return doc\n }\n\n /// Give the node or node list back to the state and\n /// the state will find a proper runner (by `match` method in parser spec) to handle it.\n next = (nodes: MarkdownNode | MarkdownNode[] = []) => {\n ;[nodes].flat().forEach((node) => this.#runNode(node))\n return this\n }\n\n /// Build the current state into a [prosemirror document](https://prosemirror.net/docs/ref/#model.Document_Structure).\n toDoc = () => this.build()\n\n /// Transform a markdown string into prosemirror state.\n run = (remark: RemarkParser, markdown: string) => {\n const tree = remark.runSync(\n remark.parse(markdown),\n markdown\n ) as MarkdownNode\n this.next(tree)\n\n return this\n }\n}\n","import type { MarkdownNode } from '..'\nimport type { JSONRecord } from '../utility'\n\nimport { StackElement } from '../utility'\n\nexport class SerializerStackElement extends StackElement<MarkdownNode> {\n constructor(\n public type: string,\n public children?: MarkdownNode[],\n public value?: string,\n public props: JSONRecord = {}\n ) {\n super()\n }\n\n static create = (\n type: string,\n children?: MarkdownNode[],\n value?: string,\n props: JSONRecord = {}\n ) => new SerializerStackElement(type, children, value, props)\n\n push = (node: MarkdownNode, ...rest: MarkdownNode[]) => {\n if (!this.children) this.children = []\n\n this.children.push(node, ...rest)\n }\n\n pop = (): MarkdownNode | undefined => this.children?.pop()\n}\n","import type {\n Fragment,\n MarkType,\n Node,\n NodeType,\n Schema,\n} from '@milkdown/prose/model'\n\nimport { serializerMatchError } from '@milkdown/exception'\nimport { Mark } from '@milkdown/prose/model'\n\nimport type {\n JSONRecord,\n MarkSchema,\n MarkdownNode,\n NodeSchema,\n RemarkParser,\n Root,\n} from '../utility'\nimport type { Serializer } from './types'\n\nimport { Stack } from '../utility'\nimport { SerializerStackElement } from './stack-element'\n\nconst isFragment = (x: Node | Fragment): x is Fragment =>\n Object.prototype.hasOwnProperty.call(x, 'size')\n\n/// State for serializer.\n/// Transform prosemirror state into remark AST.\nexport class SerializerState extends Stack<\n MarkdownNode,\n SerializerStackElement\n> {\n /// @internal\n #marks: readonly Mark[] = Mark.none\n /// Get the schema of state.\n readonly schema: Schema\n\n /// Create a serializer from schema and remark instance.\n ///\n /// ```typescript\n /// const serializer = SerializerState.create(schema, remark)\n /// const markdown = parser(prosemirrorDoc)\n /// ```\n static create = (schema: Schema, remark: RemarkParser): Serializer => {\n const state = new this(schema)\n return (content: Node) => {\n state.run(content)\n return state.toString(remark)\n }\n }\n\n /// @internal\n constructor(schema: Schema) {\n super()\n this.schema = schema\n }\n\n /// @internal\n #matchTarget = (node: Node | Mark): NodeType | MarkType => {\n const result = Object.values({\n ...this.schema.nodes,\n ...this.schema.marks,\n }).find((x): x is NodeType | MarkType => {\n const spec = x.spec as NodeSchema | MarkSchema\n return spec.toMarkdown.match(node as Node & Mark)\n })\n\n if (!result) throw serializerMatchError(node.type)\n\n return result\n }\n\n /// @internal\n #runProseNode = (node: Node) => {\n const type = this.#matchTarget(node)\n const spec = type.spec as NodeSchema\n return spec.toMarkdown.runner(this, node)\n }\n\n /// @internal\n #runProseMark = (mark: Mark, node: Node) => {\n const type = this.#matchTarget(mark)\n const spec = type.spec as MarkSchema\n return spec.toMarkdown.runner(this, mark, node)\n }\n\n /// @internal\n #runNode = (node: Node) => {\n const { marks } = node\n const getPriority = (x: Mark) => x.type.spec.priority ?? 50\n const tmp = [...marks].sort((a, b) => getPriority(a) - getPriority(b))\n const unPreventNext = tmp.every((mark) => !this.#runProseMark(mark, node))\n if (unPreventNext) this.#runProseNode(node)\n\n marks.forEach((mark) => this.#closeMark(mark))\n }\n\n /// @internal\n #searchType = (child: MarkdownNode, type: string): MarkdownNode => {\n if (child.type === type) return child\n\n if (child.children?.length !== 1) return child\n\n const searchNode = (node: MarkdownNode): MarkdownNode | null => {\n if (node.type === type) return node\n\n if (node.children?.length !== 1) return null\n\n const [firstChild] = node.children\n if (!firstChild) return null\n\n return searchNode(firstChild)\n }\n\n const target = searchNode(child)\n\n if (!target) return child\n\n const tmp = target.children ? [...target.children] : undefined\n const node = { ...child, children: tmp }\n node.children = tmp\n target.children = [node]\n\n return target\n }\n\n /// @internal\n #maybeMergeChildren = (node: MarkdownNode): MarkdownNode => {\n const { children } = node\n if (!children) return node\n\n node.children = children.reduce((nextChildren, child, index) => {\n if (index === 0) return [child]\n\n const last = nextChildren.at(-1)\n if (last && last.isMark && child.isMark) {\n child = this.#searchType(child, last.type)\n const { children: currChildren, ...currRest } = child\n const { children: prevChildren, ...prevRest } = last\n if (\n child.type === last.type &&\n currChildren &&\n prevChildren &&\n JSON.stringify(currRest) === JSON.stringify(prevRest)\n ) {\n const next = {\n ...prevRest,\n children: [...prevChildren, ...currChildren],\n }\n return nextChildren\n .slice(0, -1)\n .concat(this.#maybeMergeChildren(next))\n }\n }\n return nextChildren.concat(child)\n }, [] as MarkdownNode[])\n\n return node\n }\n\n /// @internal\n #createMarkdownNode = (element: SerializerStackElement) => {\n const node: MarkdownNode = {\n ...element.props,\n type: element.type,\n }\n\n if (element.children) node.children = element.children\n\n if (element.value) node.value = element.value\n\n return node\n }\n\n /// Open a new node, the next operations will\n /// add nodes into that new node until `closeNode` is called.\n openNode = (type: string, value?: string, props?: JSONRecord) => {\n this.open(SerializerStackElement.create(type, undefined, value, props))\n return this\n }\n\n #moveSpaces = (\n element: SerializerStackElement,\n onPush: () => MarkdownNode\n ) => {\n let startSpaces = ''\n let endSpaces = ''\n const children = element.children\n let first = -1\n let last = -1\n const findIndex = (node: MarkdownNode[]) => {\n if (!node) return\n node.forEach((child, index) => {\n if (child.type === 'text' && child.value) {\n if (first < 0) first = index\n\n last = index\n }\n })\n }\n\n if (children) {\n findIndex(children)\n const lastChild = children?.[last] as\n | (MarkdownNode & { value: string })\n | undefined\n const firstChild = children?.[first] as\n | (MarkdownNode & { value: string })\n | undefined\n if (lastChild && lastChild.value.endsWith(' ')) {\n const text = lastChild.value\n const trimmed = text.trimEnd()\n endSpaces = text.slice(trimmed.length)\n lastChild.value = trimmed\n }\n if (firstChild && firstChild.value.startsWith(' ')) {\n const text = firstChild.value\n const trimmed = text.trimStart()\n startSpaces = text.slice(0, text.length - trimmed.length)\n firstChild.value = trimmed\n }\n }\n\n if (startSpaces.length) this.#addNodeAndPush('text', undefined, startSpaces)\n\n const result = onPush()\n\n if (endSpaces.length) this.#addNodeAndPush('text', undefined, endSpaces)\n\n return result\n }\n\n /// @internal\n #closeNodeAndPush = (trim: boolean = false): MarkdownNode => {\n const element = this.close()\n\n const onPush = () =>\n this.#addNodeAndPush(\n element.type,\n element.children,\n element.value,\n element.props\n )\n\n if (trim) return this.#moveSpaces(element, onPush)\n\n return onPush()\n }\n\n /// Close the current node and push it into the parent node.\n closeNode = () => {\n this.#closeNodeAndPush()\n return this\n }\n\n /// @internal\n #addNodeAndPush = (\n type: string,\n children?: MarkdownNode[],\n value?: string,\n props?: JSONRecord\n ): MarkdownNode => {\n const element = SerializerStackElement.create(type, children, value, props)\n const node: MarkdownNode = this.#maybeMergeChildren(\n this.#createMarkdownNode(element)\n )\n this.push(node)\n return node\n }\n\n /// Add a node into current node.\n addNode = (\n type: string,\n children?: MarkdownNode[],\n value?: string,\n props?: JSONRecord\n ) => {\n this.#addNodeAndPush(type, children, value, props)\n return this\n }\n\n /// @internal\n #openMark = (\n mark: Mark,\n type: string,\n value?: string,\n props?: JSONRecord\n ) => {\n const isIn = mark.isInSet(this.#marks)\n\n if (isIn) return this\n\n this.#marks = mark.addToSet(this.#marks)\n return this.openNode(type, value, { ...props, isMark: true })\n }\n\n /// @internal\n #closeMark = (mark: Mark): void => {\n const isIn = mark.isInSet(this.#marks)\n\n if (!isIn) return\n\n this.#marks = mark.type.removeFromSet(this.#marks)\n this.#closeNodeAndPush(true)\n }\n\n /// Open a new mark, the next nodes added will have that mark.\n /// The mark will be closed automatically.\n withMark = (mark: Mark, type: string, value?: string, props?: JSONRecord) => {\n this.#openMark(mark, type, value, props)\n return this\n }\n\n /// Close a opened mark.\n /// In most cases you don't need this because\n /// marks will be closed automatically.\n closeMark = (mark: Mark) => {\n this.#closeMark(mark)\n return this\n }\n\n /// @internal\n build = (): MarkdownNode => {\n let doc: MarkdownNode | null = null\n do doc = this.#closeNodeAndPush()\n while (this.size())\n\n return doc\n }\n\n /// Give the node or node list back to the state and\n /// the state will find a proper runner (by `match` method in serializer spec) to handle it.\n next = (nodes: Node | Fragment) => {\n if (isFragment(nodes)) {\n nodes.forEach((node) => {\n this.#runNode(node)\n })\n return this\n }\n this.#runNode(nodes)\n return this\n }\n\n /// Use a remark parser to serialize current AST stored.\n override toString = (remark: RemarkParser): string =>\n remark.stringify(this.build() as Root)\n\n /// Transform a prosemirror node tree into remark AST.\n run = (tree: Node) => {\n this.next(tree)\n\n return this\n }\n}\n"],"names":["_marks","_matchTarget","_runNode","_closeNodeAndPush","_addNodeAndPush","node"],"mappings":"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"}
{"version":3,"file":"index.js","names":["#closeNodeAndPush","#addNodeAndPush","#marks","#maybeMerge","#runNode","#hasText","#matchTarget","#closeNodeAndPush","#addNodeAndPush","#openMark","#closeMark","#runNode","#matchTarget","#runProseMark","#runProseNode","#searchType","#maybeMergeChildren","#moveSpaces","#createMarkdownNode","#marks"],"sources":["../src/utility/stack.ts","../src/parser/stack-element.ts","../src/parser/state.ts","../src/serializer/stack-element.ts","../src/serializer/state.ts"],"sourcesContent":["import { stackOverFlow } from '@milkdown/exception'\n\n/// The element of the stack, which holds an array of nodes.\nexport abstract class StackElement<Node> {\n /// A method that can `push` a node into the element.\n abstract push(node: Node, ...rest: Node[]): void\n}\n\n/// The stack that is used to store the elements.\n///\n/// > Generally, you don't need to use this class directly.\n///\n/// When using the stack, users can call `stack.open` to push a new element into the stack.\n/// And use `stack.push` to push a node into the top element.\n/// Then use `stack.close` to close the top element and pop it.\n///\n/// For example: `stack.open(A).push(B).push(C).close()` will generate a structure like `A(B, C)`.\nexport class Stack<Node, Element extends StackElement<Node>> {\n protected elements: Element[] = []\n\n /// Get the size of the stack.\n size = (): number => {\n return this.elements.length\n }\n\n /// Get the top element of the stack.\n top = (): Element | undefined => {\n return this.elements.at(-1)\n }\n\n /// Push a node into the top element.\n push = (node: Node): void => {\n this.top()?.push(node)\n }\n\n /// Push a new element.\n open = (node: Element): void => {\n this.elements.push(node)\n }\n\n /// Close the top element and pop it.\n close = (): Element => {\n const el = this.elements.pop()\n if (!el) throw stackOverFlow()\n\n return el\n }\n}\n","import type { Attrs, Node, NodeType } from '@milkdown/prose/model'\n\nimport { StackElement } from '../utility'\n\nexport class ParserStackElement extends StackElement<Node> {\n constructor(\n public type: NodeType,\n public content: Node[],\n public attrs?: Attrs\n ) {\n super()\n }\n\n push(node: Node, ...rest: Node[]) {\n this.content.push(node, ...rest)\n }\n\n pop(): Node | undefined {\n return this.content.pop()\n }\n\n static create(type: NodeType, content: Node[], attrs?: Attrs) {\n return new ParserStackElement(type, content, attrs)\n }\n}\n","import type {\n Attrs,\n MarkType,\n Node,\n NodeType,\n Schema,\n} from '@milkdown/prose/model'\n\nimport {\n createNodeInParserFail,\n parserMatchError,\n stackOverFlow,\n} from '@milkdown/exception'\nimport { Mark } from '@milkdown/prose/model'\n\nimport type {\n MarkSchema,\n MarkdownNode,\n NodeSchema,\n RemarkParser,\n} from '../utility'\nimport type { Parser } from './types'\n\nimport { Stack } from '../utility'\nimport { ParserStackElement } from './stack-element'\n\n/// A state machine for parser. Transform remark AST into prosemirror state.\nexport class ParserState extends Stack<Node, ParserStackElement> {\n /// The schema in current editor.\n readonly schema: Schema\n\n /// @internal\n #marks: readonly Mark[] = Mark.none\n\n /// Create a parser from schema and remark instance.\n ///\n /// ```typescript\n /// const parser = ParserState.create(schema, remark)\n /// const prosemirrorNode = parser(SomeMarkdownText)\n /// ```\n static create = (schema: Schema, remark: RemarkParser): Parser => {\n const state = new this(schema)\n return (text) => {\n state.run(remark, text)\n return state.toDoc()\n }\n }\n\n /// @internal\n constructor(schema: Schema) {\n super()\n this.schema = schema\n }\n\n /// @internal\n #hasText = (node: Node): node is Node & { text: string } => node.isText\n\n /// @internal\n #maybeMerge = (a: Node, b: Node): Node | undefined => {\n if (this.#hasText(a) && this.#hasText(b) && Mark.sameSet(a.marks, b.marks))\n return this.schema.text(a.text + b.text, a.marks)\n\n return undefined\n }\n\n /// @internal\n #matchTarget = (node: MarkdownNode): NodeType | MarkType => {\n const result = Object.values({\n ...this.schema.nodes,\n ...this.schema.marks,\n }).find((x): x is NodeType | MarkType => {\n const spec = x.spec as NodeSchema | MarkSchema\n return spec.parseMarkdown.match(node)\n })\n\n if (!result) throw parserMatchError(node)\n\n return result\n }\n\n /// @internal\n #runNode = (node: MarkdownNode) => {\n const type = this.#matchTarget(node)\n const spec = type.spec as NodeSchema | MarkSchema\n\n spec.parseMarkdown.runner(this, node, type as NodeType & MarkType)\n }\n\n /// Inject root node for prosemirror state.\n injectRoot = (node: MarkdownNode, nodeType: NodeType, attrs?: Attrs) => {\n this.openNode(nodeType, attrs)\n this.next(node.children)\n\n return this\n }\n\n /// Open a new node, the next operations will\n /// add nodes into that new node until `closeNode` is called.\n openNode = (nodeType: NodeType, attrs?: Attrs) => {\n this.open(ParserStackElement.create(nodeType, [], attrs))\n return this\n }\n\n /// @internal\n #closeNodeAndPush = (): Node => {\n this.#marks = Mark.none\n const element = this.close()\n\n return this.#addNodeAndPush(element.type, element.attrs, element.content)\n }\n\n /// Close the current node and push it into the parent node.\n closeNode = () => {\n try {\n this.#closeNodeAndPush()\n } catch (e) {\n console.error(e)\n }\n return this\n }\n\n /// @internal\n #addNodeAndPush = (\n nodeType: NodeType,\n attrs?: Attrs,\n content?: Node[]\n ): Node => {\n const node = nodeType.createAndFill(attrs, content, this.#marks)\n if (!node) throw createNodeInParserFail(nodeType, attrs, content)\n\n this.push(node)\n\n return node\n }\n\n /// Add a node into current node.\n addNode = (nodeType: NodeType, attrs?: Attrs, content?: Node[]) => {\n try {\n this.#addNodeAndPush(nodeType, attrs, content)\n } catch (e) {\n console.error(e)\n }\n return this\n }\n\n /// Open a new mark, the next nodes added will have that mark.\n openMark = (markType: MarkType, attrs?: Attrs) => {\n const mark = markType.create(attrs)\n\n this.#marks = mark.addToSet(this.#marks)\n return this\n }\n\n /// Close a opened mark.\n closeMark = (markType: MarkType) => {\n this.#marks = markType.removeFromSet(this.#marks)\n return this\n }\n\n /// Add a text node into current node.\n addText = (text: string) => {\n try {\n const topElement = this.top()\n if (!topElement) throw stackOverFlow()\n\n const prevNode = topElement.pop()\n const currNode = this.schema.text(text, this.#marks)\n\n if (!prevNode) {\n topElement.push(currNode)\n return this\n }\n\n const merged = this.#maybeMerge(prevNode, currNode)\n if (merged) {\n topElement.push(merged)\n return this\n }\n topElement.push(prevNode, currNode)\n return this\n } catch (e) {\n console.error(e)\n return this\n }\n }\n\n /// @internal\n build = (): Node => {\n let doc: Node | undefined\n\n do doc = this.#closeNodeAndPush()\n while (this.size())\n\n return doc\n }\n\n /// Give the node or node list back to the state and\n /// the state will find a proper runner (by `match` method in parser spec) to handle it.\n next = (nodes: MarkdownNode | MarkdownNode[] = []) => {\n ;[nodes].flat().forEach((node) => this.#runNode(node))\n return this\n }\n\n /// Build the current state into a [prosemirror document](https://prosemirror.net/docs/ref/#model.Document_Structure).\n toDoc = () => this.build()\n\n /// Transform a markdown string into prosemirror state.\n run = (remark: RemarkParser, markdown: string) => {\n const tree = remark.runSync(\n remark.parse(markdown),\n markdown\n ) as MarkdownNode\n this.next(tree)\n\n return this\n }\n}\n","import type { MarkdownNode } from '..'\nimport type { JSONRecord } from '../utility'\n\nimport { StackElement } from '../utility'\n\nexport class SerializerStackElement extends StackElement<MarkdownNode> {\n constructor(\n public type: string,\n public children?: MarkdownNode[],\n public value?: string,\n public props: JSONRecord = {}\n ) {\n super()\n }\n\n static create = (\n type: string,\n children?: MarkdownNode[],\n value?: string,\n props: JSONRecord = {}\n ) => new SerializerStackElement(type, children, value, props)\n\n push = (node: MarkdownNode, ...rest: MarkdownNode[]) => {\n if (!this.children) this.children = []\n\n this.children.push(node, ...rest)\n }\n\n pop = (): MarkdownNode | undefined => this.children?.pop()\n}\n","import type {\n Fragment,\n MarkType,\n Node,\n NodeType,\n Schema,\n} from '@milkdown/prose/model'\n\nimport { serializerMatchError } from '@milkdown/exception'\nimport { Mark } from '@milkdown/prose/model'\n\nimport type {\n JSONRecord,\n MarkSchema,\n MarkdownNode,\n NodeSchema,\n RemarkParser,\n Root,\n} from '../utility'\nimport type { Serializer } from './types'\n\nimport { Stack } from '../utility'\nimport { SerializerStackElement } from './stack-element'\n\nconst isFragment = (x: Node | Fragment): x is Fragment =>\n Object.prototype.hasOwnProperty.call(x, 'size')\n\n/// State for serializer.\n/// Transform prosemirror state into remark AST.\nexport class SerializerState extends Stack<\n MarkdownNode,\n SerializerStackElement\n> {\n /// @internal\n #marks: readonly Mark[] = Mark.none\n /// Get the schema of state.\n readonly schema: Schema\n\n /// Create a serializer from schema and remark instance.\n ///\n /// ```typescript\n /// const serializer = SerializerState.create(schema, remark)\n /// const markdown = parser(prosemirrorDoc)\n /// ```\n static create = (schema: Schema, remark: RemarkParser): Serializer => {\n const state = new this(schema)\n return (content: Node) => {\n state.run(content)\n return state.toString(remark)\n }\n }\n\n /// @internal\n constructor(schema: Schema) {\n super()\n this.schema = schema\n }\n\n /// @internal\n #matchTarget = (node: Node | Mark): NodeType | MarkType => {\n const result = Object.values({\n ...this.schema.nodes,\n ...this.schema.marks,\n }).find((x): x is NodeType | MarkType => {\n const spec = x.spec as NodeSchema | MarkSchema\n return spec.toMarkdown.match(node as Node & Mark)\n })\n\n if (!result) throw serializerMatchError(node.type)\n\n return result\n }\n\n /// @internal\n #runProseNode = (node: Node) => {\n const type = this.#matchTarget(node)\n const spec = type.spec as NodeSchema\n return spec.toMarkdown.runner(this, node)\n }\n\n /// @internal\n #runProseMark = (mark: Mark, node: Node) => {\n const type = this.#matchTarget(mark)\n const spec = type.spec as MarkSchema\n return spec.toMarkdown.runner(this, mark, node)\n }\n\n /// @internal\n #runNode = (node: Node) => {\n const { marks } = node\n const getPriority = (x: Mark) => x.type.spec.priority ?? 50\n const tmp = [...marks].sort((a, b) => getPriority(a) - getPriority(b))\n const unPreventNext = tmp.every((mark) => !this.#runProseMark(mark, node))\n if (unPreventNext) this.#runProseNode(node)\n\n marks.forEach((mark) => this.#closeMark(mark))\n }\n\n /// @internal\n #searchType = (child: MarkdownNode, type: string): MarkdownNode => {\n if (child.type === type) return child\n\n if (child.children?.length !== 1) return child\n\n const searchNode = (node: MarkdownNode): MarkdownNode | null => {\n if (node.type === type) return node.value != null ? null : node\n\n if (node.children?.length !== 1) return null\n\n const [firstChild] = node.children\n if (!firstChild) return null\n\n return searchNode(firstChild)\n }\n\n const target = searchNode(child)\n\n if (!target) return child\n\n const tmp = target.children ? [...target.children] : undefined\n const node = { ...child, children: tmp }\n node.children = tmp\n target.children = [node]\n\n return target\n }\n\n /// @internal\n #maybeMergeChildren = (node: MarkdownNode): MarkdownNode => {\n const { children } = node\n if (!children) return node\n\n node.children = children.reduce((nextChildren, child, index) => {\n if (index === 0) return [child]\n\n const last = nextChildren.at(-1)\n if (last && last.isMark && child.isMark) {\n child = this.#searchType(child, last.type)\n const { children: currChildren, ...currRest } = child\n const { children: prevChildren, ...prevRest } = last\n if (\n child.type === last.type &&\n currChildren &&\n prevChildren &&\n JSON.stringify(currRest) === JSON.stringify(prevRest)\n ) {\n const next = {\n ...prevRest,\n children: [...prevChildren, ...currChildren],\n }\n return nextChildren\n .slice(0, -1)\n .concat(this.#maybeMergeChildren(next))\n }\n }\n return nextChildren.concat(child)\n }, [] as MarkdownNode[])\n\n return node\n }\n\n /// @internal\n #createMarkdownNode = (element: SerializerStackElement) => {\n const node: MarkdownNode = {\n ...element.props,\n type: element.type,\n }\n\n if (element.children) node.children = element.children\n\n if (element.value) node.value = element.value\n\n return node\n }\n\n /// Open a new node, the next operations will\n /// add nodes into that new node until `closeNode` is called.\n openNode = (type: string, value?: string, props?: JSONRecord) => {\n this.open(SerializerStackElement.create(type, undefined, value, props))\n return this\n }\n\n #moveSpaces = (\n element: SerializerStackElement,\n onPush: () => MarkdownNode\n ) => {\n let startSpaces = ''\n let endSpaces = ''\n const children = element.children\n let first = -1\n let last = -1\n const findIndex = (node: MarkdownNode[]) => {\n if (!node) return\n node.forEach((child, index) => {\n if (child.type === 'text' && child.value) {\n if (first < 0) first = index\n\n last = index\n }\n })\n }\n\n if (children) {\n findIndex(children)\n const lastChild = children?.[last] as\n | (MarkdownNode & { value: string })\n | undefined\n const firstChild = children?.[first] as\n | (MarkdownNode & { value: string })\n | undefined\n if (lastChild && lastChild.value.endsWith(' ')) {\n const text = lastChild.value\n const trimmed = text.trimEnd()\n endSpaces = text.slice(trimmed.length)\n lastChild.value = trimmed\n }\n if (firstChild && firstChild.value.startsWith(' ')) {\n const text = firstChild.value\n const trimmed = text.trimStart()\n startSpaces = text.slice(0, text.length - trimmed.length)\n firstChild.value = trimmed\n }\n }\n\n if (startSpaces.length) this.#addNodeAndPush('text', undefined, startSpaces)\n\n const result = onPush()\n\n if (endSpaces.length) this.#addNodeAndPush('text', undefined, endSpaces)\n\n return result\n }\n\n /// @internal\n #closeNodeAndPush = (trim: boolean = false): MarkdownNode => {\n const element = this.close()\n\n const onPush = () =>\n this.#addNodeAndPush(\n element.type,\n element.children,\n element.value,\n element.props\n )\n\n if (trim) return this.#moveSpaces(element, onPush)\n\n return onPush()\n }\n\n /// Close the current node and push it into the parent node.\n closeNode = () => {\n this.#closeNodeAndPush()\n return this\n }\n\n /// @internal\n #addNodeAndPush = (\n type: string,\n children?: MarkdownNode[],\n value?: string,\n props?: JSONRecord\n ): MarkdownNode => {\n const element = SerializerStackElement.create(type, children, value, props)\n const node: MarkdownNode = this.#maybeMergeChildren(\n this.#createMarkdownNode(element)\n )\n this.push(node)\n return node\n }\n\n /// Add a node into current node.\n addNode = (\n type: string,\n children?: MarkdownNode[],\n value?: string,\n props?: JSONRecord\n ) => {\n this.#addNodeAndPush(type, children, value, props)\n return this\n }\n\n /// @internal\n #openMark = (\n mark: Mark,\n type: string,\n value?: string,\n props?: JSONRecord\n ) => {\n const isIn = mark.isInSet(this.#marks)\n\n if (isIn) return this\n\n this.#marks = mark.addToSet(this.#marks)\n return this.openNode(type, value, { ...props, isMark: true })\n }\n\n /// @internal\n #closeMark = (mark: Mark): void => {\n const isIn = mark.isInSet(this.#marks)\n\n if (!isIn) return\n\n this.#marks = mark.type.removeFromSet(this.#marks)\n this.#closeNodeAndPush(true)\n }\n\n /// Open a new mark, the next nodes added will have that mark.\n /// The mark will be closed automatically.\n withMark = (mark: Mark, type: string, value?: string, props?: JSONRecord) => {\n this.#openMark(mark, type, value, props)\n return this\n }\n\n /// Close a opened mark.\n /// In most cases you don't need this because\n /// marks will be closed automatically.\n closeMark = (mark: Mark) => {\n this.#closeMark(mark)\n return this\n }\n\n /// @internal\n build = (): MarkdownNode => {\n let doc: MarkdownNode | null = null\n do doc = this.#closeNodeAndPush()\n while (this.size())\n\n return doc\n }\n\n /// Give the node or node list back to the state and\n /// the state will find a proper runner (by `match` method in serializer spec) to handle it.\n next = (nodes: Node | Fragment) => {\n if (isFragment(nodes)) {\n nodes.forEach((node) => {\n this.#runNode(node)\n })\n return this\n }\n this.#runNode(nodes)\n return this\n }\n\n /// Use a remark parser to serialize current AST stored.\n override toString = (remark: RemarkParser): string =>\n remark.stringify(this.build() as Root)\n\n /// Transform a prosemirror node tree into remark AST.\n run = (tree: Node) => {\n this.next(tree)\n\n return this\n }\n}\n"],"mappings":";;;AAGA,IAAsB,eAAtB,MAAyC;AAczC,IAAa,QAAb,MAA6D;;kBAC3B,EAAE;oBAGb;AACnB,UAAO,KAAK,SAAS;;mBAIU;AAC/B,UAAO,KAAK,SAAS,GAAG,GAAG;;eAIrB,SAAqB;AAC3B,QAAK,KAAK,EAAE,KAAK,KAAK;;eAIhB,SAAwB;AAC9B,QAAK,SAAS,KAAK,KAAK;;qBAIH;GACrB,MAAM,KAAK,KAAK,SAAS,KAAK;AAC9B,OAAI,CAAC,GAAI,OAAM,eAAe;AAE9B,UAAO;;;;;;ACzCX,IAAa,qBAAb,MAAa,2BAA2B,aAAmB;CACzD,YACE,MACA,SACA,OACA;AACA,SAAO;AAJA,OAAA,OAAA;AACA,OAAA,UAAA;AACA,OAAA,QAAA;;CAKT,KAAK,MAAY,GAAG,MAAc;AAChC,OAAK,QAAQ,KAAK,MAAM,GAAG,KAAK;;CAGlC,MAAwB;AACtB,SAAO,KAAK,QAAQ,KAAK;;CAG3B,OAAO,OAAO,MAAgB,SAAiB,OAAe;AAC5D,SAAO,IAAI,mBAAmB,MAAM,SAAS,MAAM;;;;;ACKvD,IAAa,cAAb,cAAiC,MAAgC;CAK/D,SAA0B,KAAK;;iBAQd,QAAgB,WAAiC;GAChE,MAAM,QAAQ,IAAI,KAAK,OAAO;AAC9B,WAAQ,SAAS;AACf,UAAM,IAAI,QAAQ,KAAK;AACvB,WAAO,MAAM,OAAO;;;;CAKxB,YAAY,QAAgB;AAC1B,SAAO;qBAuCK,MAAoB,UAAoB,UAAkB;AACtE,QAAK,SAAS,UAAU,MAAM;AAC9B,QAAK,KAAK,KAAK,SAAS;AAExB,UAAO;;mBAKG,UAAoB,UAAkB;AAChD,QAAK,KAAK,mBAAmB,OAAO,UAAU,EAAE,EAAE,MAAM,CAAC;AACzD,UAAO;;yBAYS;AAChB,OAAI;AACF,UAAA,kBAAwB;YACjB,GAAG;AACV,YAAQ,MAAM,EAAE;;AAElB,UAAO;;kBAkBE,UAAoB,OAAe,YAAqB;AACjE,OAAI;AACF,UAAA,eAAqB,UAAU,OAAO,QAAQ;YACvC,GAAG;AACV,YAAQ,MAAM,EAAE;;AAElB,UAAO;;mBAIG,UAAoB,UAAkB;AAGhD,SAAA,QAFa,SAAS,OAAO,MAAM,CAEhB,SAAS,MAAA,MAAY;AACxC,UAAO;;oBAII,aAAuB;AAClC,SAAA,QAAc,SAAS,cAAc,MAAA,MAAY;AACjD,UAAO;;kBAIE,SAAiB;AAC1B,OAAI;IACF,MAAM,aAAa,KAAK,KAAK;AAC7B,QAAI,CAAC,WAAY,OAAM,eAAe;IAEtC,MAAM,WAAW,WAAW,KAAK;IACjC,MAAM,WAAW,KAAK,OAAO,KAAK,MAAM,MAAA,MAAY;AAEpD,QAAI,CAAC,UAAU;AACb,gBAAW,KAAK,SAAS;AACzB,YAAO;;IAGT,MAAM,SAAS,MAAA,WAAiB,UAAU,SAAS;AACnD,QAAI,QAAQ;AACV,gBAAW,KAAK,OAAO;AACvB,YAAO;;AAET,eAAW,KAAK,UAAU,SAAS;AACnC,WAAO;YACA,GAAG;AACV,YAAQ,MAAM,EAAE;AAChB,WAAO;;;qBAKS;GAClB,IAAI;AAEJ;AAAG,UAAM,MAAA,kBAAwB;UAC1B,KAAK,MAAM;AAElB,UAAO;;eAKD,QAAuC,EAAE,KAAK;AACnD,IAAC,MAAM,CAAC,MAAM,CAAC,SAAS,SAAS,MAAA,QAAc,KAAK,CAAC;AACtD,UAAO;;qBAIK,KAAK,OAAO;cAGnB,QAAsB,aAAqB;GAChD,MAAM,OAAO,OAAO,QAClB,OAAO,MAAM,SAAS,EACtB,SACD;AACD,QAAK,KAAK,KAAK;AAEf,UAAO;;AAnKP,OAAK,SAAS;;CAIhB,YAAY,SAAgD,KAAK;CAGjE,eAAe,GAAS,MAA8B;AACpD,MAAI,MAAA,QAAc,EAAE,IAAI,MAAA,QAAc,EAAE,IAAI,KAAK,QAAQ,EAAE,OAAO,EAAE,MAAM,CACxE,QAAO,KAAK,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM;;CAMrD,gBAAgB,SAA4C;EAC1D,MAAM,SAAS,OAAO,OAAO;GAC3B,GAAG,KAAK,OAAO;GACf,GAAG,KAAK,OAAO;GAChB,CAAC,CAAC,MAAM,MAAgC;AAEvC,UADa,EAAE,KACH,cAAc,MAAM,KAAK;IACrC;AAEF,MAAI,CAAC,OAAQ,OAAM,iBAAiB,KAAK;AAEzC,SAAO;;CAIT,YAAY,SAAuB;EACjC,MAAM,OAAO,MAAA,YAAkB,KAAK;AACvB,OAAK,KAEb,cAAc,OAAO,MAAM,MAAM,KAA4B;;CAmBpE,0BAAgC;AAC9B,QAAA,QAAc,KAAK;EACnB,MAAM,UAAU,KAAK,OAAO;AAE5B,SAAO,MAAA,eAAqB,QAAQ,MAAM,QAAQ,OAAO,QAAQ,QAAQ;;CAc3E,mBACE,UACA,OACA,YACS;EACT,MAAM,OAAO,SAAS,cAAc,OAAO,SAAS,MAAA,MAAY;AAChE,MAAI,CAAC,KAAM,OAAM,uBAAuB,UAAU,OAAO,QAAQ;AAEjE,OAAK,KAAK,KAAK;AAEf,SAAO;;;;;AC/HX,IAAa,yBAAb,MAAa,+BAA+B,aAA2B;CACrE,YACE,MACA,UACA,OACA,QAA2B,EAAE,EAC7B;AACA,SAAO;AALA,OAAA,OAAA;AACA,OAAA,WAAA;AACA,OAAA,QAAA;AACA,OAAA,QAAA;eAYD,MAAoB,GAAG,SAAyB;AACtD,OAAI,CAAC,KAAK,SAAU,MAAK,WAAW,EAAE;AAEtC,QAAK,SAAS,KAAK,MAAM,GAAG,KAAK;;mBAGG,KAAK,UAAU,KAAK;;;iBAZxD,MACA,UACA,OACA,QAAoB,EAAE,KACnB,IAAI,uBAAuB,MAAM,UAAU,OAAO,MAAM;;;;;ACI/D,IAAM,cAAc,MAClB,OAAO,UAAU,eAAe,KAAK,GAAG,OAAO;AAIjD,IAAa,kBAAb,cAAqC,MAGnC;CAEA,SAA0B,KAAK;;iBAUd,QAAgB,WAAqC;GACpE,MAAM,QAAQ,IAAI,KAAK,OAAO;AAC9B,WAAQ,YAAkB;AACxB,UAAM,IAAI,QAAQ;AAClB,WAAO,MAAM,SAAS,OAAO;;;;CAKjC,YAAY,QAAgB;AAC1B,SAAO;mBA2HG,MAAc,OAAgB,UAAuB;AAC/D,QAAK,KAAK,uBAAuB,OAAO,MAAM,KAAA,GAAW,OAAO,MAAM,CAAC;AACvE,UAAO;;yBAwES;AAChB,SAAA,kBAAwB;AACxB,UAAO;;kBAoBP,MACA,UACA,OACA,UACG;AACH,SAAA,eAAqB,MAAM,UAAU,OAAO,MAAM;AAClD,UAAO;;mBA8BG,MAAY,MAAc,OAAgB,UAAuB;AAC3E,SAAA,SAAe,MAAM,MAAM,OAAO,MAAM;AACxC,UAAO;;oBAMI,SAAe;AAC1B,SAAA,UAAgB,KAAK;AACrB,UAAO;;qBAImB;GAC1B,IAAI,MAA2B;AAC/B;AAAG,UAAM,MAAA,kBAAwB;UAC1B,KAAK,MAAM;AAElB,UAAO;;eAKD,UAA2B;AACjC,OAAI,WAAW,MAAM,EAAE;AACrB,UAAM,SAAS,SAAS;AACtB,WAAA,QAAc,KAAK;MACnB;AACF,WAAO;;AAET,SAAA,QAAc,MAAM;AACpB,UAAO;;mBAIY,WACnB,OAAO,UAAU,KAAK,OAAO,CAAS;cAGjC,SAAe;AACpB,QAAK,KAAK,KAAK;AAEf,UAAO;;AAzSP,OAAK,SAAS;;CAIhB,gBAAgB,SAA2C;EACzD,MAAM,SAAS,OAAO,OAAO;GAC3B,GAAG,KAAK,OAAO;GACf,GAAG,KAAK,OAAO;GAChB,CAAC,CAAC,MAAM,MAAgC;AAEvC,UADa,EAAE,KACH,WAAW,MAAM,KAAoB;IACjD;AAEF,MAAI,CAAC,OAAQ,OAAM,qBAAqB,KAAK,KAAK;AAElD,SAAO;;CAIT,iBAAiB,SAAe;AAG9B,SAFa,MAAA,YAAkB,KAAK,CAClB,KACN,WAAW,OAAO,MAAM,KAAK;;CAI3C,iBAAiB,MAAY,SAAe;AAG1C,SAFa,MAAA,YAAkB,KAAK,CAClB,KACN,WAAW,OAAO,MAAM,MAAM,KAAK;;CAIjD,YAAY,SAAe;EACzB,MAAM,EAAE,UAAU;EAClB,MAAM,eAAe,MAAY,EAAE,KAAK,KAAK,YAAY;AAGzD,MAFY,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,MAAM,YAAY,EAAE,GAAG,YAAY,EAAE,CAAC,CAC5C,OAAO,SAAS,CAAC,MAAA,aAAmB,MAAM,KAAK,CAAC,CACvD,OAAA,aAAmB,KAAK;AAE3C,QAAM,SAAS,SAAS,MAAA,UAAgB,KAAK,CAAC;;CAIhD,eAAe,OAAqB,SAA+B;AACjE,MAAI,MAAM,SAAS,KAAM,QAAO;AAEhC,MAAI,MAAM,UAAU,WAAW,EAAG,QAAO;EAEzC,MAAM,cAAc,SAA4C;AAC9D,OAAI,KAAK,SAAS,KAAM,QAAO,KAAK,SAAS,OAAO,OAAO;AAE3D,OAAI,KAAK,UAAU,WAAW,EAAG,QAAO;GAExC,MAAM,CAAC,cAAc,KAAK;AAC1B,OAAI,CAAC,WAAY,QAAO;AAExB,UAAO,WAAW,WAAW;;EAG/B,MAAM,SAAS,WAAW,MAAM;AAEhC,MAAI,CAAC,OAAQ,QAAO;EAEpB,MAAM,MAAM,OAAO,WAAW,CAAC,GAAG,OAAO,SAAS,GAAG,KAAA;EACrD,MAAM,OAAO;GAAE,GAAG;GAAO,UAAU;GAAK;AACxC,OAAK,WAAW;AAChB,SAAO,WAAW,CAAC,KAAK;AAExB,SAAO;;CAIT,uBAAuB,SAAqC;EAC1D,MAAM,EAAE,aAAa;AACrB,MAAI,CAAC,SAAU,QAAO;AAEtB,OAAK,WAAW,SAAS,QAAQ,cAAc,OAAO,UAAU;AAC9D,OAAI,UAAU,EAAG,QAAO,CAAC,MAAM;GAE/B,MAAM,OAAO,aAAa,GAAG,GAAG;AAChC,OAAI,QAAQ,KAAK,UAAU,MAAM,QAAQ;AACvC,YAAQ,MAAA,WAAiB,OAAO,KAAK,KAAK;IAC1C,MAAM,EAAE,UAAU,cAAc,GAAG,aAAa;IAChD,MAAM,EAAE,UAAU,cAAc,GAAG,aAAa;AAChD,QACE,MAAM,SAAS,KAAK,QACpB,gBACA,gBACA,KAAK,UAAU,SAAS,KAAK,KAAK,UAAU,SAAS,EACrD;KACA,MAAM,OAAO;MACX,GAAG;MACH,UAAU,CAAC,GAAG,cAAc,GAAG,aAAa;MAC7C;AACD,YAAO,aACJ,MAAM,GAAG,GAAG,CACZ,OAAO,MAAA,mBAAyB,KAAK,CAAC;;;AAG7C,UAAO,aAAa,OAAO,MAAM;KAChC,EAAE,CAAmB;AAExB,SAAO;;CAIT,uBAAuB,YAAoC;EACzD,MAAM,OAAqB;GACzB,GAAG,QAAQ;GACX,MAAM,QAAQ;GACf;AAED,MAAI,QAAQ,SAAU,MAAK,WAAW,QAAQ;AAE9C,MAAI,QAAQ,MAAO,MAAK,QAAQ,QAAQ;AAExC,SAAO;;CAUT,eACE,SACA,WACG;EACH,IAAI,cAAc;EAClB,IAAI,YAAY;EAChB,MAAM,WAAW,QAAQ;EACzB,IAAI,QAAQ;EACZ,IAAI,OAAO;EACX,MAAM,aAAa,SAAyB;AAC1C,OAAI,CAAC,KAAM;AACX,QAAK,SAAS,OAAO,UAAU;AAC7B,QAAI,MAAM,SAAS,UAAU,MAAM,OAAO;AACxC,SAAI,QAAQ,EAAG,SAAQ;AAEvB,YAAO;;KAET;;AAGJ,MAAI,UAAU;AACZ,aAAU,SAAS;GACnB,MAAM,YAAY,WAAW;GAG7B,MAAM,aAAa,WAAW;AAG9B,OAAI,aAAa,UAAU,MAAM,SAAS,IAAI,EAAE;IAC9C,MAAM,OAAO,UAAU;IACvB,MAAM,UAAU,KAAK,SAAS;AAC9B,gBAAY,KAAK,MAAM,QAAQ,OAAO;AACtC,cAAU,QAAQ;;AAEpB,OAAI,cAAc,WAAW,MAAM,WAAW,IAAI,EAAE;IAClD,MAAM,OAAO,WAAW;IACxB,MAAM,UAAU,KAAK,WAAW;AAChC,kBAAc,KAAK,MAAM,GAAG,KAAK,SAAS,QAAQ,OAAO;AACzD,eAAW,QAAQ;;;AAIvB,MAAI,YAAY,OAAQ,OAAA,eAAqB,QAAQ,KAAA,GAAW,YAAY;EAE5E,MAAM,SAAS,QAAQ;AAEvB,MAAI,UAAU,OAAQ,OAAA,eAAqB,QAAQ,KAAA,GAAW,UAAU;AAExE,SAAO;;CAIT,qBAAqB,OAAgB,UAAwB;EAC3D,MAAM,UAAU,KAAK,OAAO;EAE5B,MAAM,eACJ,MAAA,eACE,QAAQ,MACR,QAAQ,UACR,QAAQ,OACR,QAAQ,MACT;AAEH,MAAI,KAAM,QAAO,MAAA,WAAiB,SAAS,OAAO;AAElD,SAAO,QAAQ;;CAUjB,mBACE,MACA,UACA,OACA,UACiB;EACjB,MAAM,UAAU,uBAAuB,OAAO,MAAM,UAAU,OAAO,MAAM;EAC3E,MAAM,OAAqB,MAAA,mBACzB,MAAA,mBAAyB,QAAQ,CAClC;AACD,OAAK,KAAK,KAAK;AACf,SAAO;;CAeT,aACE,MACA,MACA,OACA,UACG;AAGH,MAFa,KAAK,QAAQ,MAAA,MAAY,CAE5B,QAAO;AAEjB,QAAA,QAAc,KAAK,SAAS,MAAA,MAAY;AACxC,SAAO,KAAK,SAAS,MAAM,OAAO;GAAE,GAAG;GAAO,QAAQ;GAAM,CAAC;;CAI/D,cAAc,SAAqB;AAGjC,MAAI,CAFS,KAAK,QAAQ,MAAA,MAAY,CAE3B;AAEX,QAAA,QAAc,KAAK,KAAK,cAAc,MAAA,MAAY;AAClD,QAAA,iBAAuB,KAAK"}
{
"name": "@milkdown/transformer",
"type": "module",
"version": "7.19.0",
"version": "7.19.1",
"license": "MIT",

@@ -32,4 +32,4 @@ "repository": {

"unified": "^11.0.3",
"@milkdown/exception": "7.19.0",
"@milkdown/prose": "7.19.0"
"@milkdown/exception": "7.19.1",
"@milkdown/prose": "7.19.1"
},

@@ -36,0 +36,0 @@ "scripts": {

@@ -23,2 +23,10 @@ import type { Mark, Schema } from '@milkdown/prose/model'

const inlineCodeMark = {
isInSet: (arr: string[]) => arr.includes('inlineCode'),
addToSet: (arr: string[]) => arr.concat('inlineCode'),
type: {
removeFromSet: (arr: string[]) => arr.filter((x) => x !== 'inlineCode'),
},
} as unknown as Mark
const schema = {

@@ -200,2 +208,46 @@ nodes: {

it('should not corrupt value-based marks during merge', () => {
const state = new SerializerState(schema)
state.openNode('doc')
state.openNode('paragraph')
// Simulate: inlineCode("Hello") followed by bold > inlineCode("World")
state.withMark(inlineCodeMark, 'inlineCode', 'Hello')
state.closeMark(inlineCodeMark)
state.withMark(boldMark, 'bold')
state.withMark(inlineCodeMark, 'inlineCode', 'World')
state.closeMark(inlineCodeMark)
state.closeMark(boldMark)
state.closeNode()
// The bold wrapper around inlineCode should be preserved,
// not restructured by searchType
expect(state.top()).toMatchObject({
type: 'doc',
children: [
{
type: 'paragraph',
children: [
{
type: 'inlineCode',
isMark: true,
value: 'Hello',
},
{
type: 'bold',
isMark: true,
children: [
{
type: 'inlineCode',
isMark: true,
value: 'World',
},
],
},
],
},
],
})
})
it('try to merge marks', () => {

@@ -202,0 +254,0 @@ const state = new SerializerState(schema)

@@ -106,3 +106,3 @@ import type {

const searchNode = (node: MarkdownNode): MarkdownNode | null => {
if (node.type === type) return node
if (node.type === type) return node.value != null ? null : node

@@ -109,0 +109,0 @@ if (node.children?.length !== 1) return null

Sorry, the diff of this file is not supported yet