fix: resolve TypeScript errors in frontend build

This commit is contained in:
Hiro
2026-03-30 23:16:07 +00:00
parent b733306773
commit 24925e1acb
2941 changed files with 418042 additions and 49 deletions

966
node_modules/prosemirror-markdown/dist/index.cjs generated vendored Normal file
View File

@@ -0,0 +1,966 @@
'use strict';
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
var prosemirrorModel = require('prosemirror-model');
var MarkdownIt = require('markdown-it');
var schema = new prosemirrorModel.Schema({
nodes: {
doc: {
content: "block+"
},
paragraph: {
content: "inline*",
group: "block",
parseDOM: [{
tag: "p"
}],
toDOM: function toDOM() {
return ["p", 0];
}
},
blockquote: {
content: "block+",
group: "block",
parseDOM: [{
tag: "blockquote"
}],
toDOM: function toDOM() {
return ["blockquote", 0];
}
},
horizontal_rule: {
group: "block",
parseDOM: [{
tag: "hr"
}],
toDOM: function toDOM() {
return ["div", ["hr"]];
}
},
heading: {
attrs: {
level: {
"default": 1
}
},
content: "(text | image)*",
group: "block",
defining: true,
parseDOM: [{
tag: "h1",
attrs: {
level: 1
}
}, {
tag: "h2",
attrs: {
level: 2
}
}, {
tag: "h3",
attrs: {
level: 3
}
}, {
tag: "h4",
attrs: {
level: 4
}
}, {
tag: "h5",
attrs: {
level: 5
}
}, {
tag: "h6",
attrs: {
level: 6
}
}],
toDOM: function toDOM(node) {
return ["h" + node.attrs.level, 0];
}
},
code_block: {
content: "text*",
group: "block",
code: true,
defining: true,
marks: "",
attrs: {
params: {
"default": ""
}
},
parseDOM: [{
tag: "pre",
preserveWhitespace: "full",
getAttrs: function getAttrs(node) {
return {
params: node.getAttribute("data-params") || ""
};
}
}],
toDOM: function toDOM(node) {
return ["pre", node.attrs.params ? {
"data-params": node.attrs.params
} : {}, ["code", 0]];
}
},
ordered_list: {
content: "list_item+",
group: "block",
attrs: {
order: {
"default": 1
},
tight: {
"default": false
}
},
parseDOM: [{
tag: "ol",
getAttrs: function getAttrs(dom) {
return {
order: dom.hasAttribute("start") ? +dom.getAttribute("start") : 1,
tight: dom.hasAttribute("data-tight")
};
}
}],
toDOM: function toDOM(node) {
return ["ol", {
start: node.attrs.order == 1 ? null : node.attrs.order,
"data-tight": node.attrs.tight ? "true" : null
}, 0];
}
},
bullet_list: {
content: "list_item+",
group: "block",
attrs: {
tight: {
"default": false
}
},
parseDOM: [{
tag: "ul",
getAttrs: function getAttrs(dom) {
return {
tight: dom.hasAttribute("data-tight")
};
}
}],
toDOM: function toDOM(node) {
return ["ul", {
"data-tight": node.attrs.tight ? "true" : null
}, 0];
}
},
list_item: {
content: "block+",
defining: true,
parseDOM: [{
tag: "li"
}],
toDOM: function toDOM() {
return ["li", 0];
}
},
text: {
group: "inline"
},
image: {
inline: true,
attrs: {
src: {},
alt: {
"default": null
},
title: {
"default": null
}
},
group: "inline",
draggable: true,
parseDOM: [{
tag: "img[src]",
getAttrs: function getAttrs(dom) {
return {
src: dom.getAttribute("src"),
title: dom.getAttribute("title"),
alt: dom.getAttribute("alt")
};
}
}],
toDOM: function toDOM(node) {
return ["img", node.attrs];
}
},
hard_break: {
inline: true,
group: "inline",
selectable: false,
parseDOM: [{
tag: "br"
}],
toDOM: function toDOM() {
return ["br"];
}
}
},
marks: {
em: {
parseDOM: [{
tag: "i"
}, {
tag: "em"
}, {
style: "font-style=italic"
}, {
style: "font-style=normal",
clearMark: function clearMark(m) {
return m.type.name == "em";
}
}],
toDOM: function toDOM() {
return ["em"];
}
},
strong: {
parseDOM: [{
tag: "strong"
}, {
tag: "b",
getAttrs: function getAttrs(node) {
return node.style.fontWeight != "normal" && null;
}
}, {
style: "font-weight=400",
clearMark: function clearMark(m) {
return m.type.name == "strong";
}
}, {
style: "font-weight",
getAttrs: function getAttrs(value) {
return /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null;
}
}],
toDOM: function toDOM() {
return ["strong"];
}
},
link: {
attrs: {
href: {},
title: {
"default": null
}
},
inclusive: false,
parseDOM: [{
tag: "a[href]",
getAttrs: function getAttrs(dom) {
return {
href: dom.getAttribute("href"),
title: dom.getAttribute("title")
};
}
}],
toDOM: function toDOM(node) {
return ["a", node.attrs];
}
},
code: {
code: true,
parseDOM: [{
tag: "code"
}],
toDOM: function toDOM() {
return ["code"];
}
}
}
});
function maybeMerge(a, b) {
if (a.isText && b.isText && prosemirrorModel.Mark.sameSet(a.marks, b.marks)) return a.withText(a.text + b.text);
}
var MarkdownParseState = function () {
function MarkdownParseState(schema, tokenHandlers) {
_classCallCheck(this, MarkdownParseState);
this.schema = schema;
this.tokenHandlers = tokenHandlers;
this.stack = [{
type: schema.topNodeType,
attrs: null,
content: [],
marks: prosemirrorModel.Mark.none
}];
}
_createClass(MarkdownParseState, [{
key: "top",
value: function top() {
return this.stack[this.stack.length - 1];
}
}, {
key: "push",
value: function push(elt) {
if (this.stack.length) this.top().content.push(elt);
}
}, {
key: "addText",
value: function addText(text) {
if (!text) return;
var top = this.top(),
nodes = top.content,
last = nodes[nodes.length - 1];
var node = this.schema.text(text, top.marks),
merged;
if (last && (merged = maybeMerge(last, node))) nodes[nodes.length - 1] = merged;else nodes.push(node);
}
}, {
key: "openMark",
value: function openMark(mark) {
var top = this.top();
top.marks = mark.addToSet(top.marks);
}
}, {
key: "closeMark",
value: function closeMark(mark) {
var top = this.top();
top.marks = mark.removeFromSet(top.marks);
}
}, {
key: "parseTokens",
value: function parseTokens(toks) {
for (var i = 0; i < toks.length; i++) {
var tok = toks[i];
var handler = this.tokenHandlers[tok.type];
if (!handler) throw new Error("Token type `" + tok.type + "` not supported by Markdown parser");
handler(this, tok, toks, i);
}
}
}, {
key: "addNode",
value: function addNode(type, attrs, content) {
var top = this.top();
var node = type.createAndFill(attrs, content, top ? top.marks : []);
if (!node) return null;
this.push(node);
return node;
}
}, {
key: "openNode",
value: function openNode(type, attrs) {
this.stack.push({
type: type,
attrs: attrs,
content: [],
marks: prosemirrorModel.Mark.none
});
}
}, {
key: "closeNode",
value: function closeNode() {
var info = this.stack.pop();
return this.addNode(info.type, info.attrs, info.content);
}
}]);
return MarkdownParseState;
}();
function attrs(spec, token, tokens, i) {
if (spec.getAttrs) return spec.getAttrs(token, tokens, i);else if (spec.attrs instanceof Function) return spec.attrs(token);else return spec.attrs;
}
function noCloseToken(spec, type) {
return spec.noCloseToken || type == "code_inline" || type == "code_block" || type == "fence";
}
function withoutTrailingNewline(str) {
return str[str.length - 1] == "\n" ? str.slice(0, str.length - 1) : str;
}
function noOp() {}
function tokenHandlers(schema, tokens) {
var handlers = Object.create(null);
var _loop = function _loop() {
var spec = tokens[type];
if (spec.block) {
var nodeType = schema.nodeType(spec.block);
if (noCloseToken(spec, type)) {
handlers[type] = function (state, tok, tokens, i) {
state.openNode(nodeType, attrs(spec, tok, tokens, i));
state.addText(withoutTrailingNewline(tok.content));
state.closeNode();
};
} else {
handlers[type + "_open"] = function (state, tok, tokens, i) {
return state.openNode(nodeType, attrs(spec, tok, tokens, i));
};
handlers[type + "_close"] = function (state) {
return state.closeNode();
};
}
} else if (spec.node) {
var _nodeType = schema.nodeType(spec.node);
handlers[type] = function (state, tok, tokens, i) {
return state.addNode(_nodeType, attrs(spec, tok, tokens, i));
};
} else if (spec.mark) {
var markType = schema.marks[spec.mark];
if (noCloseToken(spec, type)) {
handlers[type] = function (state, tok, tokens, i) {
state.openMark(markType.create(attrs(spec, tok, tokens, i)));
state.addText(withoutTrailingNewline(tok.content));
state.closeMark(markType);
};
} else {
handlers[type + "_open"] = function (state, tok, tokens, i) {
return state.openMark(markType.create(attrs(spec, tok, tokens, i)));
};
handlers[type + "_close"] = function (state) {
return state.closeMark(markType);
};
}
} else if (spec.ignore) {
if (noCloseToken(spec, type)) {
handlers[type] = noOp;
} else {
handlers[type + "_open"] = noOp;
handlers[type + "_close"] = noOp;
}
} else {
throw new RangeError("Unrecognized parsing spec " + JSON.stringify(spec));
}
};
for (var type in tokens) {
_loop();
}
handlers.text = function (state, tok) {
return state.addText(tok.content);
};
handlers.inline = function (state, tok) {
return state.parseTokens(tok.children);
};
handlers.softbreak = handlers.softbreak || function (state) {
return state.addText(" ");
};
return handlers;
}
var MarkdownParser = function () {
function MarkdownParser(schema, tokenizer, tokens) {
_classCallCheck(this, MarkdownParser);
this.schema = schema;
this.tokenizer = tokenizer;
this.tokens = tokens;
this.tokenHandlers = tokenHandlers(schema, tokens);
}
_createClass(MarkdownParser, [{
key: "parse",
value: function parse(text) {
var markdownEnv = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var state = new MarkdownParseState(this.schema, this.tokenHandlers),
doc;
state.parseTokens(this.tokenizer.parse(text, markdownEnv));
do {
doc = state.closeNode();
} while (state.stack.length);
return doc || this.schema.topNodeType.createAndFill();
}
}]);
return MarkdownParser;
}();
function listIsTight(tokens, i) {
while (++i < tokens.length) if (tokens[i].type != "list_item_open") return tokens[i].hidden;
return false;
}
var defaultMarkdownParser = new MarkdownParser(schema, MarkdownIt("commonmark", {
html: false
}), {
blockquote: {
block: "blockquote"
},
paragraph: {
block: "paragraph"
},
list_item: {
block: "list_item"
},
bullet_list: {
block: "bullet_list",
getAttrs: function getAttrs(_, tokens, i) {
return {
tight: listIsTight(tokens, i)
};
}
},
ordered_list: {
block: "ordered_list",
getAttrs: function getAttrs(tok, tokens, i) {
return {
order: +tok.attrGet("start") || 1,
tight: listIsTight(tokens, i)
};
}
},
heading: {
block: "heading",
getAttrs: function getAttrs(tok) {
return {
level: +tok.tag.slice(1)
};
}
},
code_block: {
block: "code_block",
noCloseToken: true
},
fence: {
block: "code_block",
getAttrs: function getAttrs(tok) {
return {
params: tok.info || ""
};
},
noCloseToken: true
},
hr: {
node: "horizontal_rule"
},
image: {
node: "image",
getAttrs: function getAttrs(tok) {
return {
src: tok.attrGet("src"),
title: tok.attrGet("title") || null,
alt: tok.children[0] && tok.children[0].content || null
};
}
},
hardbreak: {
node: "hard_break"
},
em: {
mark: "em"
},
strong: {
mark: "strong"
},
link: {
mark: "link",
getAttrs: function getAttrs(tok) {
return {
href: tok.attrGet("href"),
title: tok.attrGet("title") || null
};
}
},
code_inline: {
mark: "code",
noCloseToken: true
}
});
var blankMark = {
open: "",
close: "",
mixable: true
};
var MarkdownSerializer = function () {
function MarkdownSerializer(nodes, marks) {
var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
_classCallCheck(this, MarkdownSerializer);
this.nodes = nodes;
this.marks = marks;
this.options = options;
}
_createClass(MarkdownSerializer, [{
key: "serialize",
value: function serialize(content) {
var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
options = Object.assign({}, this.options, options);
var state = new MarkdownSerializerState(this.nodes, this.marks, options);
state.renderContent(content);
return state.out;
}
}]);
return MarkdownSerializer;
}();
var defaultMarkdownSerializer = new MarkdownSerializer({
blockquote: function blockquote(state, node) {
state.wrapBlock("> ", null, node, function () {
return state.renderContent(node);
});
},
code_block: function code_block(state, node) {
var backticks = node.textContent.match(/`{3,}/gm);
var fence = backticks ? backticks.sort().slice(-1)[0] + "`" : "```";
state.write(fence + (node.attrs.params || "") + "\n");
state.text(node.textContent, false);
state.write("\n");
state.write(fence);
state.closeBlock(node);
},
heading: function heading(state, node) {
state.write(state.repeat("#", node.attrs.level) + " ");
state.renderInline(node, false);
state.closeBlock(node);
},
horizontal_rule: function horizontal_rule(state, node) {
state.write(node.attrs.markup || "---");
state.closeBlock(node);
},
bullet_list: function bullet_list(state, node) {
state.renderList(node, " ", function () {
return (node.attrs.bullet || "*") + " ";
});
},
ordered_list: function ordered_list(state, node) {
var start = node.attrs.order || 1;
var maxW = String(start + node.childCount - 1).length;
var space = state.repeat(" ", maxW + 2);
state.renderList(node, space, function (i) {
var nStr = String(start + i);
return state.repeat(" ", maxW - nStr.length) + nStr + ". ";
});
},
list_item: function list_item(state, node) {
state.renderContent(node);
},
paragraph: function paragraph(state, node) {
state.renderInline(node);
state.closeBlock(node);
},
image: function image(state, node) {
state.write("![" + state.esc(node.attrs.alt || "") + "](" + node.attrs.src.replace(/[\(\)]/g, "\\$&") + (node.attrs.title ? ' "' + node.attrs.title.replace(/"/g, '\\"') + '"' : "") + ")");
},
hard_break: function hard_break(state, node, parent, index) {
for (var i = index + 1; i < parent.childCount; i++) if (parent.child(i).type != node.type) {
state.write("\\\n");
return;
}
},
text: function text(state, node) {
state.text(node.text, !state.inAutolink);
}
}, {
em: {
open: "*",
close: "*",
mixable: true,
expelEnclosingWhitespace: true
},
strong: {
open: "**",
close: "**",
mixable: true,
expelEnclosingWhitespace: true
},
link: {
open: function open(state, mark, parent, index) {
state.inAutolink = isPlainURL(mark, parent, index);
return state.inAutolink ? "<" : "[";
},
close: function close(state, mark, parent, index) {
var inAutolink = state.inAutolink;
state.inAutolink = undefined;
return inAutolink ? ">" : "](" + mark.attrs.href.replace(/[\(\)"]/g, "\\$&") + (mark.attrs.title ? " \"".concat(mark.attrs.title.replace(/"/g, '\\"'), "\"") : "") + ")";
},
mixable: true
},
code: {
open: function open(_state, _mark, parent, index) {
return backticksFor(parent.child(index), -1);
},
close: function close(_state, _mark, parent, index) {
return backticksFor(parent.child(index - 1), 1);
},
escape: false
}
});
function backticksFor(node, side) {
var ticks = /`+/g,
m,
len = 0;
if (node.isText) while (m = ticks.exec(node.text)) len = Math.max(len, m[0].length);
var result = len > 0 && side > 0 ? " `" : "`";
for (var i = 0; i < len; i++) result += "`";
if (len > 0 && side < 0) result += " ";
return result;
}
function isPlainURL(link, parent, index) {
if (link.attrs.title || !/^\w+:/.test(link.attrs.href)) return false;
var content = parent.child(index);
if (!content.isText || content.text != link.attrs.href || content.marks[content.marks.length - 1] != link) return false;
return index == parent.childCount - 1 || !link.isInSet(parent.child(index + 1).marks);
}
var MarkdownSerializerState = function () {
function MarkdownSerializerState(nodes, marks, options) {
_classCallCheck(this, MarkdownSerializerState);
this.nodes = nodes;
this.marks = marks;
this.options = options;
this.delim = "";
this.out = "";
this.closed = null;
this.inAutolink = undefined;
this.atBlockStart = false;
this.inTightList = false;
if (typeof this.options.tightLists == "undefined") this.options.tightLists = false;
if (typeof this.options.hardBreakNodeName == "undefined") this.options.hardBreakNodeName = "hard_break";
}
_createClass(MarkdownSerializerState, [{
key: "flushClose",
value: function flushClose() {
var size = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 2;
if (this.closed) {
if (!this.atBlank()) this.out += "\n";
if (size > 1) {
var delimMin = this.delim;
var trim = /\s+$/.exec(delimMin);
if (trim) delimMin = delimMin.slice(0, delimMin.length - trim[0].length);
for (var i = 1; i < size; i++) this.out += delimMin + "\n";
}
this.closed = null;
}
}
}, {
key: "getMark",
value: function getMark(name) {
var info = this.marks[name];
if (!info) {
if (this.options.strict !== false) throw new Error("Mark type `".concat(name, "` not supported by Markdown renderer"));
info = blankMark;
}
return info;
}
}, {
key: "wrapBlock",
value: function wrapBlock(delim, firstDelim, node, f) {
var old = this.delim;
this.write(firstDelim != null ? firstDelim : delim);
this.delim += delim;
f();
this.delim = old;
this.closeBlock(node);
}
}, {
key: "atBlank",
value: function atBlank() {
return /(^|\n)$/.test(this.out);
}
}, {
key: "ensureNewLine",
value: function ensureNewLine() {
if (!this.atBlank()) this.out += "\n";
}
}, {
key: "write",
value: function write(content) {
this.flushClose();
if (this.delim && this.atBlank()) this.out += this.delim;
if (content) this.out += content;
}
}, {
key: "closeBlock",
value: function closeBlock(node) {
this.closed = node;
}
}, {
key: "text",
value: function text(_text) {
var escape = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
var lines = _text.split("\n");
for (var i = 0; i < lines.length; i++) {
this.write();
if (!escape && lines[i][0] == "[" && /(^|[^\\])\!$/.test(this.out)) this.out = this.out.slice(0, this.out.length - 1) + "\\!";
this.out += escape ? this.esc(lines[i], this.atBlockStart) : lines[i];
if (i != lines.length - 1) this.out += "\n";
}
}
}, {
key: "render",
value: function render(node, parent, index) {
if (this.nodes[node.type.name]) {
this.nodes[node.type.name](this, node, parent, index);
} else {
if (this.options.strict !== false) {
throw new Error("Token type `" + node.type.name + "` not supported by Markdown renderer");
} else if (!node.type.isLeaf) {
if (node.type.inlineContent) this.renderInline(node);else this.renderContent(node);
if (node.isBlock) this.closeBlock(node);
}
}
}
}, {
key: "renderContent",
value: function renderContent(parent) {
var _this = this;
parent.forEach(function (node, _, i) {
return _this.render(node, parent, i);
});
}
}, {
key: "renderInline",
value: function renderInline(parent) {
var _this2 = this;
var fromBlockStart = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
this.atBlockStart = fromBlockStart;
var active = [],
trailing = "";
var progress = function progress(node, offset, index) {
var marks = node ? node.marks : [];
if (node && node.type.name === _this2.options.hardBreakNodeName) marks = marks.filter(function (m) {
if (index + 1 == parent.childCount) return false;
var next = parent.child(index + 1);
return m.isInSet(next.marks) && (!next.isText || /\S/.test(next.text));
});
var leading = trailing;
trailing = "";
if (node && node.isText && marks.some(function (mark) {
var info = _this2.getMark(mark.type.name);
return info && info.expelEnclosingWhitespace && !mark.isInSet(active);
})) {
var _exec = /^(\s*)(.*)$/m.exec(node.text),
_exec2 = _slicedToArray(_exec, 3),
_ = _exec2[0],
lead = _exec2[1],
rest = _exec2[2];
if (lead) {
leading += lead;
node = rest ? node.withText(rest) : null;
if (!node) marks = active;
}
}
if (node && node.isText && marks.some(function (mark) {
var info = _this2.getMark(mark.type.name);
return info && info.expelEnclosingWhitespace && !_this2.isMarkAhead(parent, index + 1, mark);
})) {
var _exec3 = /^(.*?)(\s*)$/m.exec(node.text),
_exec4 = _slicedToArray(_exec3, 3),
_2 = _exec4[0],
_rest = _exec4[1],
trail = _exec4[2];
if (trail) {
trailing = trail;
node = _rest ? node.withText(_rest) : null;
if (!node) marks = active;
}
}
var inner = marks.length ? marks[marks.length - 1] : null;
var noEsc = inner && _this2.getMark(inner.type.name).escape === false;
var len = marks.length - (noEsc ? 1 : 0);
outer: for (var i = 0; i < len; i++) {
var mark = marks[i];
if (!_this2.getMark(mark.type.name).mixable) break;
for (var j = 0; j < active.length; j++) {
var other = active[j];
if (!_this2.getMark(other.type.name).mixable) break;
if (mark.eq(other)) {
if (i > j) marks = marks.slice(0, j).concat(mark).concat(marks.slice(j, i)).concat(marks.slice(i + 1, len));else if (j > i) marks = marks.slice(0, i).concat(marks.slice(i + 1, j)).concat(mark).concat(marks.slice(j, len));
continue outer;
}
}
}
var keep = 0;
while (keep < Math.min(active.length, len) && marks[keep].eq(active[keep])) ++keep;
while (keep < active.length) _this2.text(_this2.markString(active.pop(), false, parent, index), false);
if (leading) _this2.text(leading);
if (node) {
while (active.length < len) {
var add = marks[active.length];
active.push(add);
_this2.text(_this2.markString(add, true, parent, index), false);
_this2.atBlockStart = false;
}
if (noEsc && node.isText) _this2.text(_this2.markString(inner, true, parent, index) + node.text + _this2.markString(inner, false, parent, index + 1), false);else _this2.render(node, parent, index);
_this2.atBlockStart = false;
}
if ((node === null || node === void 0 ? void 0 : node.isText) && node.nodeSize > 0) {
_this2.atBlockStart = false;
}
};
parent.forEach(progress);
progress(null, 0, parent.childCount);
this.atBlockStart = false;
}
}, {
key: "renderList",
value: function renderList(node, delim, firstDelim) {
var _this3 = this;
if (this.closed && this.closed.type == node.type) this.flushClose(3);else if (this.inTightList) this.flushClose(1);
var isTight = typeof node.attrs.tight != "undefined" ? node.attrs.tight : this.options.tightLists;
var prevTight = this.inTightList;
this.inTightList = isTight;
node.forEach(function (child, _, i) {
if (i && isTight) _this3.flushClose(1);
_this3.wrapBlock(delim, firstDelim(i), node, function () {
return _this3.render(child, node, i);
});
});
this.inTightList = prevTight;
}
}, {
key: "esc",
value: function esc(str) {
var startOfLine = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
str = str.replace(/[`*\\~\[\]_]/g, function (m, i) {
return m == "_" && i > 0 && i + 1 < str.length && str[i - 1].match(/\w/) && str[i + 1].match(/\w/) ? m : "\\" + m;
});
if (startOfLine) str = str.replace(/^(\+[ ]|[\-*>])/, "\\$&").replace(/^(\s*)(#{1,6})(\s|$)/, '$1\\$2$3').replace(/^(\s*\d+)\.\s/, "$1\\. ");
if (this.options.escapeExtraCharacters) str = str.replace(this.options.escapeExtraCharacters, "\\$&");
return str;
}
}, {
key: "quote",
value: function quote(str) {
var wrap = str.indexOf('"') == -1 ? '""' : str.indexOf("'") == -1 ? "''" : "()";
return wrap[0] + str + wrap[1];
}
}, {
key: "repeat",
value: function repeat(str, n) {
var out = "";
for (var i = 0; i < n; i++) out += str;
return out;
}
}, {
key: "markString",
value: function markString(mark, open, parent, index) {
var info = this.getMark(mark.type.name);
var value = open ? info.open : info.close;
return typeof value == "string" ? value : value(this, mark, parent, index);
}
}, {
key: "getEnclosingWhitespace",
value: function getEnclosingWhitespace(text) {
return {
leading: (text.match(/^(\s+)/) || [undefined])[0],
trailing: (text.match(/(\s+)$/) || [undefined])[0]
};
}
}, {
key: "isMarkAhead",
value: function isMarkAhead(parent, index, mark) {
for (;; index++) {
if (index >= parent.childCount) return false;
var next = parent.child(index);
if (next.type.name != this.options.hardBreakNodeName) return mark.isInSet(next.marks);
index++;
}
}
}]);
return MarkdownSerializerState;
}();
exports.MarkdownParser = MarkdownParser;
exports.MarkdownSerializer = MarkdownSerializer;
exports.MarkdownSerializerState = MarkdownSerializerState;
exports.defaultMarkdownParser = defaultMarkdownParser;
exports.defaultMarkdownSerializer = defaultMarkdownSerializer;
exports.schema = schema;

335
node_modules/prosemirror-markdown/dist/index.d.cts generated vendored Normal file
View File

@@ -0,0 +1,335 @@
import { Schema, Attrs, Node, Mark } from 'prosemirror-model';
import MarkdownIt from 'markdown-it';
import Token from 'markdown-it/lib/token.mjs';
/**
Document schema for the data model used by CommonMark.
*/
declare const schema: Schema<"blockquote" | "image" | "text" | "paragraph" | "code_block" | "doc" | "horizontal_rule" | "heading" | "ordered_list" | "bullet_list" | "list_item" | "hard_break", "link" | "code" | "em" | "strong">;
/**
Object type used to specify how Markdown tokens should be parsed.
*/
interface ParseSpec {
/**
This token maps to a single node, whose type can be looked up
in the schema under the given name. Exactly one of `node`,
`block`, or `mark` must be set.
*/
node?: string;
/**
This token (unless `noCloseToken` is true) comes in `_open`
and `_close` variants (which are appended to the base token
name provides a the object property), and wraps a block of
content. The block should be wrapped in a node of the type
named to by the property's value. If the token does not have
`_open` or `_close`, use the `noCloseToken` option.
*/
block?: string;
/**
This token (again, unless `noCloseToken` is true) also comes
in `_open` and `_close` variants, but should add a mark
(named by the value) to its content, rather than wrapping it
in a node.
*/
mark?: string;
/**
Attributes for the node or mark. When `getAttrs` is provided,
it takes precedence.
*/
attrs?: Attrs | null;
/**
A function used to compute the attributes for the node or mark
that takes a [markdown-it
token](https://markdown-it.github.io/markdown-it/#Token) and
returns an attribute object.
*/
getAttrs?: (token: Token, tokenStream: Token[], index: number) => Attrs | null;
/**
Indicates that the [markdown-it
token](https://markdown-it.github.io/markdown-it/#Token) has
no `_open` or `_close` for the nodes. This defaults to `true`
for `code_inline`, `code_block` and `fence`.
*/
noCloseToken?: boolean;
/**
When true, ignore content for the matched token.
*/
ignore?: boolean;
}
/**
A configuration of a Markdown parser. Such a parser uses
[markdown-it](https://github.com/markdown-it/markdown-it) to
tokenize a file, and then runs the custom rules it is given over
the tokens to create a ProseMirror document tree.
*/
declare class MarkdownParser {
/**
The parser's document schema.
*/
readonly schema: Schema;
/**
This parser's markdown-it tokenizer.
*/
readonly tokenizer: MarkdownIt;
/**
The value of the `tokens` object used to construct this
parser. Can be useful to copy and modify to base other parsers
on.
*/
readonly tokens: {
[name: string]: ParseSpec;
};
/**
Create a parser with the given configuration. You can configure
the markdown-it parser to parse the dialect you want, and provide
a description of the ProseMirror entities those tokens map to in
the `tokens` object, which maps token names to descriptions of
what to do with them. Such a description is an object, and may
have the following properties:
*/
constructor(
/**
The parser's document schema.
*/
schema: Schema,
/**
This parser's markdown-it tokenizer.
*/
tokenizer: MarkdownIt,
/**
The value of the `tokens` object used to construct this
parser. Can be useful to copy and modify to base other parsers
on.
*/
tokens: {
[name: string]: ParseSpec;
});
/**
Parse a string as [CommonMark](http://commonmark.org/) markup,
and create a ProseMirror document as prescribed by this parser's
rules.
The second argument, when given, is passed through to the
[Markdown
parser](https://markdown-it.github.io/markdown-it/#MarkdownIt.parse).
*/
parse(text: string, markdownEnv?: Object): Node;
}
/**
A parser parsing unextended [CommonMark](http://commonmark.org/),
without inline HTML, and producing a document in the basic schema.
*/
declare const defaultMarkdownParser: MarkdownParser;
type MarkSerializerSpec = {
/**
The string that should appear before a piece of content marked
by this mark, either directly or as a function that returns an
appropriate string.
*/
open: string | ((state: MarkdownSerializerState, mark: Mark, parent: Node, index: number) => string);
/**
The string that should appear after a piece of content marked by
this mark.
*/
close: string | ((state: MarkdownSerializerState, mark: Mark, parent: Node, index: number) => string);
/**
When `true`, this indicates that the order in which the mark's
opening and closing syntax appears relative to other mixable
marks can be varied. (For example, you can say `**a *b***` and
`*a **b***`, but not `` `a *b*` ``.)
*/
mixable?: boolean;
/**
When enabled, causes the serializer to move enclosing whitespace
from inside the marks to outside the marks. This is necessary
for emphasis marks as CommonMark does not permit enclosing
whitespace inside emphasis marks, see:
http:spec.commonmark.org/0.26/#example-330
*/
expelEnclosingWhitespace?: boolean;
/**
Can be set to `false` to disable character escaping in a mark. A
non-escaping mark has to have the highest precedence (must
always be the innermost mark).
*/
escape?: boolean;
};
/**
A specification for serializing a ProseMirror document as
Markdown/CommonMark text.
*/
declare class MarkdownSerializer {
/**
The node serializer functions for this serializer.
*/
readonly nodes: {
[node: string]: (state: MarkdownSerializerState, node: Node, parent: Node, index: number) => void;
};
/**
The mark serializer info.
*/
readonly marks: {
[mark: string]: MarkSerializerSpec;
};
readonly options: {
/**
Extra characters can be added for escaping. This is passed
directly to String.replace(), and the matching characters are
preceded by a backslash.
*/
escapeExtraCharacters?: RegExp;
/**
Specify the node name of hard breaks.
Defaults to "hard_break"
*/
hardBreakNodeName?: string;
/**
By default, the serializer raises an error when it finds a
node or mark type for which no serializer is defined. Set
this to `false` to make it just ignore such elements,
rendering only their content.
*/
strict?: boolean;
};
/**
Construct a serializer with the given configuration. The `nodes`
object should map node names in a given schema to function that
take a serializer state and such a node, and serialize the node.
*/
constructor(
/**
The node serializer functions for this serializer.
*/
nodes: {
[node: string]: (state: MarkdownSerializerState, node: Node, parent: Node, index: number) => void;
},
/**
The mark serializer info.
*/
marks: {
[mark: string]: MarkSerializerSpec;
}, options?: {
/**
Extra characters can be added for escaping. This is passed
directly to String.replace(), and the matching characters are
preceded by a backslash.
*/
escapeExtraCharacters?: RegExp;
/**
Specify the node name of hard breaks.
Defaults to "hard_break"
*/
hardBreakNodeName?: string;
/**
By default, the serializer raises an error when it finds a
node or mark type for which no serializer is defined. Set
this to `false` to make it just ignore such elements,
rendering only their content.
*/
strict?: boolean;
});
/**
Serialize the content of the given node to
[CommonMark](http://commonmark.org/).
*/
serialize(content: Node, options?: {
/**
Whether to render lists in a tight style. This can be overridden
on a node level by specifying a tight attribute on the node.
Defaults to false.
*/
tightLists?: boolean;
}): string;
}
/**
A serializer for the [basic schema](https://prosemirror.net/docs/ref/#schema).
*/
declare const defaultMarkdownSerializer: MarkdownSerializer;
/**
This is an object used to track state and expose
methods related to markdown serialization. Instances are passed to
node and mark serialization methods (see `toMarkdown`).
*/
declare class MarkdownSerializerState {
/**
The options passed to the serializer.
*/
readonly options: {
tightLists?: boolean;
escapeExtraCharacters?: RegExp;
hardBreakNodeName?: string;
strict?: boolean;
};
/**
Render a block, prefixing each line with `delim`, and the first
line in `firstDelim`. `node` should be the node that is closed at
the end of the block, and `f` is a function that renders the
content of the block.
*/
wrapBlock(delim: string, firstDelim: string | null, node: Node, f: () => void): void;
/**
Ensure the current content ends with a newline.
*/
ensureNewLine(): void;
/**
Prepare the state for writing output (closing closed paragraphs,
adding delimiters, and so on), and then optionally add content
(unescaped) to the output.
*/
write(content?: string): void;
/**
Close the block for the given node.
*/
closeBlock(node: Node): void;
/**
Add the given text to the document. When escape is not `false`,
it will be escaped.
*/
text(text: string, escape?: boolean): void;
/**
Render the given node as a block.
*/
render(node: Node, parent: Node, index: number): void;
/**
Render the contents of `parent` as block nodes.
*/
renderContent(parent: Node): void;
/**
Render the contents of `parent` as inline content.
*/
renderInline(parent: Node, fromBlockStart?: boolean): void;
/**
Render a node's content as a list. `delim` should be the extra
indentation added to all lines except the first in an item,
`firstDelim` is a function going from an item index to a
delimiter for the first line of the item.
*/
renderList(node: Node, delim: string, firstDelim: (index: number) => string): void;
/**
Escape the given string so that it can safely appear in Markdown
content. If `startOfLine` is true, also escape characters that
have special meaning only at the start of the line.
*/
esc(str: string, startOfLine?: boolean): string;
/**
Repeat the given string `n` times.
*/
repeat(str: string, n: number): string;
/**
Get the markdown string for a given opening or closing mark.
*/
markString(mark: Mark, open: boolean, parent: Node, index: number): string;
/**
Get leading and trailing whitespace from a string. Values of
leading or trailing property of the return object will be undefined
if there is no match.
*/
getEnclosingWhitespace(text: string): {
leading?: string;
trailing?: string;
};
}
export { MarkdownParser, MarkdownSerializer, MarkdownSerializerState, type ParseSpec, defaultMarkdownParser, defaultMarkdownSerializer, schema };

335
node_modules/prosemirror-markdown/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,335 @@
import { Schema, Attrs, Node, Mark } from 'prosemirror-model';
import MarkdownIt from 'markdown-it';
import Token from 'markdown-it/lib/token.mjs';
/**
Document schema for the data model used by CommonMark.
*/
declare const schema: Schema<"blockquote" | "image" | "text" | "paragraph" | "code_block" | "doc" | "horizontal_rule" | "heading" | "ordered_list" | "bullet_list" | "list_item" | "hard_break", "link" | "code" | "em" | "strong">;
/**
Object type used to specify how Markdown tokens should be parsed.
*/
interface ParseSpec {
/**
This token maps to a single node, whose type can be looked up
in the schema under the given name. Exactly one of `node`,
`block`, or `mark` must be set.
*/
node?: string;
/**
This token (unless `noCloseToken` is true) comes in `_open`
and `_close` variants (which are appended to the base token
name provides a the object property), and wraps a block of
content. The block should be wrapped in a node of the type
named to by the property's value. If the token does not have
`_open` or `_close`, use the `noCloseToken` option.
*/
block?: string;
/**
This token (again, unless `noCloseToken` is true) also comes
in `_open` and `_close` variants, but should add a mark
(named by the value) to its content, rather than wrapping it
in a node.
*/
mark?: string;
/**
Attributes for the node or mark. When `getAttrs` is provided,
it takes precedence.
*/
attrs?: Attrs | null;
/**
A function used to compute the attributes for the node or mark
that takes a [markdown-it
token](https://markdown-it.github.io/markdown-it/#Token) and
returns an attribute object.
*/
getAttrs?: (token: Token, tokenStream: Token[], index: number) => Attrs | null;
/**
Indicates that the [markdown-it
token](https://markdown-it.github.io/markdown-it/#Token) has
no `_open` or `_close` for the nodes. This defaults to `true`
for `code_inline`, `code_block` and `fence`.
*/
noCloseToken?: boolean;
/**
When true, ignore content for the matched token.
*/
ignore?: boolean;
}
/**
A configuration of a Markdown parser. Such a parser uses
[markdown-it](https://github.com/markdown-it/markdown-it) to
tokenize a file, and then runs the custom rules it is given over
the tokens to create a ProseMirror document tree.
*/
declare class MarkdownParser {
/**
The parser's document schema.
*/
readonly schema: Schema;
/**
This parser's markdown-it tokenizer.
*/
readonly tokenizer: MarkdownIt;
/**
The value of the `tokens` object used to construct this
parser. Can be useful to copy and modify to base other parsers
on.
*/
readonly tokens: {
[name: string]: ParseSpec;
};
/**
Create a parser with the given configuration. You can configure
the markdown-it parser to parse the dialect you want, and provide
a description of the ProseMirror entities those tokens map to in
the `tokens` object, which maps token names to descriptions of
what to do with them. Such a description is an object, and may
have the following properties:
*/
constructor(
/**
The parser's document schema.
*/
schema: Schema,
/**
This parser's markdown-it tokenizer.
*/
tokenizer: MarkdownIt,
/**
The value of the `tokens` object used to construct this
parser. Can be useful to copy and modify to base other parsers
on.
*/
tokens: {
[name: string]: ParseSpec;
});
/**
Parse a string as [CommonMark](http://commonmark.org/) markup,
and create a ProseMirror document as prescribed by this parser's
rules.
The second argument, when given, is passed through to the
[Markdown
parser](https://markdown-it.github.io/markdown-it/#MarkdownIt.parse).
*/
parse(text: string, markdownEnv?: Object): Node;
}
/**
A parser parsing unextended [CommonMark](http://commonmark.org/),
without inline HTML, and producing a document in the basic schema.
*/
declare const defaultMarkdownParser: MarkdownParser;
type MarkSerializerSpec = {
/**
The string that should appear before a piece of content marked
by this mark, either directly or as a function that returns an
appropriate string.
*/
open: string | ((state: MarkdownSerializerState, mark: Mark, parent: Node, index: number) => string);
/**
The string that should appear after a piece of content marked by
this mark.
*/
close: string | ((state: MarkdownSerializerState, mark: Mark, parent: Node, index: number) => string);
/**
When `true`, this indicates that the order in which the mark's
opening and closing syntax appears relative to other mixable
marks can be varied. (For example, you can say `**a *b***` and
`*a **b***`, but not `` `a *b*` ``.)
*/
mixable?: boolean;
/**
When enabled, causes the serializer to move enclosing whitespace
from inside the marks to outside the marks. This is necessary
for emphasis marks as CommonMark does not permit enclosing
whitespace inside emphasis marks, see:
http:spec.commonmark.org/0.26/#example-330
*/
expelEnclosingWhitespace?: boolean;
/**
Can be set to `false` to disable character escaping in a mark. A
non-escaping mark has to have the highest precedence (must
always be the innermost mark).
*/
escape?: boolean;
};
/**
A specification for serializing a ProseMirror document as
Markdown/CommonMark text.
*/
declare class MarkdownSerializer {
/**
The node serializer functions for this serializer.
*/
readonly nodes: {
[node: string]: (state: MarkdownSerializerState, node: Node, parent: Node, index: number) => void;
};
/**
The mark serializer info.
*/
readonly marks: {
[mark: string]: MarkSerializerSpec;
};
readonly options: {
/**
Extra characters can be added for escaping. This is passed
directly to String.replace(), and the matching characters are
preceded by a backslash.
*/
escapeExtraCharacters?: RegExp;
/**
Specify the node name of hard breaks.
Defaults to "hard_break"
*/
hardBreakNodeName?: string;
/**
By default, the serializer raises an error when it finds a
node or mark type for which no serializer is defined. Set
this to `false` to make it just ignore such elements,
rendering only their content.
*/
strict?: boolean;
};
/**
Construct a serializer with the given configuration. The `nodes`
object should map node names in a given schema to function that
take a serializer state and such a node, and serialize the node.
*/
constructor(
/**
The node serializer functions for this serializer.
*/
nodes: {
[node: string]: (state: MarkdownSerializerState, node: Node, parent: Node, index: number) => void;
},
/**
The mark serializer info.
*/
marks: {
[mark: string]: MarkSerializerSpec;
}, options?: {
/**
Extra characters can be added for escaping. This is passed
directly to String.replace(), and the matching characters are
preceded by a backslash.
*/
escapeExtraCharacters?: RegExp;
/**
Specify the node name of hard breaks.
Defaults to "hard_break"
*/
hardBreakNodeName?: string;
/**
By default, the serializer raises an error when it finds a
node or mark type for which no serializer is defined. Set
this to `false` to make it just ignore such elements,
rendering only their content.
*/
strict?: boolean;
});
/**
Serialize the content of the given node to
[CommonMark](http://commonmark.org/).
*/
serialize(content: Node, options?: {
/**
Whether to render lists in a tight style. This can be overridden
on a node level by specifying a tight attribute on the node.
Defaults to false.
*/
tightLists?: boolean;
}): string;
}
/**
A serializer for the [basic schema](https://prosemirror.net/docs/ref/#schema).
*/
declare const defaultMarkdownSerializer: MarkdownSerializer;
/**
This is an object used to track state and expose
methods related to markdown serialization. Instances are passed to
node and mark serialization methods (see `toMarkdown`).
*/
declare class MarkdownSerializerState {
/**
The options passed to the serializer.
*/
readonly options: {
tightLists?: boolean;
escapeExtraCharacters?: RegExp;
hardBreakNodeName?: string;
strict?: boolean;
};
/**
Render a block, prefixing each line with `delim`, and the first
line in `firstDelim`. `node` should be the node that is closed at
the end of the block, and `f` is a function that renders the
content of the block.
*/
wrapBlock(delim: string, firstDelim: string | null, node: Node, f: () => void): void;
/**
Ensure the current content ends with a newline.
*/
ensureNewLine(): void;
/**
Prepare the state for writing output (closing closed paragraphs,
adding delimiters, and so on), and then optionally add content
(unescaped) to the output.
*/
write(content?: string): void;
/**
Close the block for the given node.
*/
closeBlock(node: Node): void;
/**
Add the given text to the document. When escape is not `false`,
it will be escaped.
*/
text(text: string, escape?: boolean): void;
/**
Render the given node as a block.
*/
render(node: Node, parent: Node, index: number): void;
/**
Render the contents of `parent` as block nodes.
*/
renderContent(parent: Node): void;
/**
Render the contents of `parent` as inline content.
*/
renderInline(parent: Node, fromBlockStart?: boolean): void;
/**
Render a node's content as a list. `delim` should be the extra
indentation added to all lines except the first in an item,
`firstDelim` is a function going from an item index to a
delimiter for the first line of the item.
*/
renderList(node: Node, delim: string, firstDelim: (index: number) => string): void;
/**
Escape the given string so that it can safely appear in Markdown
content. If `startOfLine` is true, also escape characters that
have special meaning only at the start of the line.
*/
esc(str: string, startOfLine?: boolean): string;
/**
Repeat the given string `n` times.
*/
repeat(str: string, n: number): string;
/**
Get the markdown string for a given opening or closing mark.
*/
markString(mark: Mark, open: boolean, parent: Node, index: number): string;
/**
Get leading and trailing whitespace from a string. Values of
leading or trailing property of the return object will be undefined
if there is no match.
*/
getEnclosingWhitespace(text: string): {
leading?: string;
trailing?: string;
};
}
export { MarkdownParser, MarkdownSerializer, MarkdownSerializerState, type ParseSpec, defaultMarkdownParser, defaultMarkdownSerializer, schema };

878
node_modules/prosemirror-markdown/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,878 @@
import { Schema, Mark } from 'prosemirror-model';
import MarkdownIt from 'markdown-it';
/**
Document schema for the data model used by CommonMark.
*/
const schema = new Schema({
nodes: {
doc: {
content: "block+"
},
paragraph: {
content: "inline*",
group: "block",
parseDOM: [{ tag: "p" }],
toDOM() { return ["p", 0]; }
},
blockquote: {
content: "block+",
group: "block",
parseDOM: [{ tag: "blockquote" }],
toDOM() { return ["blockquote", 0]; }
},
horizontal_rule: {
group: "block",
parseDOM: [{ tag: "hr" }],
toDOM() { return ["div", ["hr"]]; }
},
heading: {
attrs: { level: { default: 1 } },
content: "(text | image)*",
group: "block",
defining: true,
parseDOM: [{ tag: "h1", attrs: { level: 1 } },
{ tag: "h2", attrs: { level: 2 } },
{ tag: "h3", attrs: { level: 3 } },
{ tag: "h4", attrs: { level: 4 } },
{ tag: "h5", attrs: { level: 5 } },
{ tag: "h6", attrs: { level: 6 } }],
toDOM(node) { return ["h" + node.attrs.level, 0]; }
},
code_block: {
content: "text*",
group: "block",
code: true,
defining: true,
marks: "",
attrs: { params: { default: "" } },
parseDOM: [{ tag: "pre", preserveWhitespace: "full", getAttrs: node => ({ params: node.getAttribute("data-params") || "" }) }],
toDOM(node) { return ["pre", node.attrs.params ? { "data-params": node.attrs.params } : {}, ["code", 0]]; }
},
ordered_list: {
content: "list_item+",
group: "block",
attrs: { order: { default: 1 }, tight: { default: false } },
parseDOM: [{ tag: "ol", getAttrs(dom) {
return { order: dom.hasAttribute("start") ? +dom.getAttribute("start") : 1,
tight: dom.hasAttribute("data-tight") };
} }],
toDOM(node) {
return ["ol", { start: node.attrs.order == 1 ? null : node.attrs.order,
"data-tight": node.attrs.tight ? "true" : null }, 0];
}
},
bullet_list: {
content: "list_item+",
group: "block",
attrs: { tight: { default: false } },
parseDOM: [{ tag: "ul", getAttrs: dom => ({ tight: dom.hasAttribute("data-tight") }) }],
toDOM(node) { return ["ul", { "data-tight": node.attrs.tight ? "true" : null }, 0]; }
},
list_item: {
content: "block+",
defining: true,
parseDOM: [{ tag: "li" }],
toDOM() { return ["li", 0]; }
},
text: {
group: "inline"
},
image: {
inline: true,
attrs: {
src: {},
alt: { default: null },
title: { default: null }
},
group: "inline",
draggable: true,
parseDOM: [{ tag: "img[src]", getAttrs(dom) {
return {
src: dom.getAttribute("src"),
title: dom.getAttribute("title"),
alt: dom.getAttribute("alt")
};
} }],
toDOM(node) { return ["img", node.attrs]; }
},
hard_break: {
inline: true,
group: "inline",
selectable: false,
parseDOM: [{ tag: "br" }],
toDOM() { return ["br"]; }
}
},
marks: {
em: {
parseDOM: [
{ tag: "i" }, { tag: "em" },
{ style: "font-style=italic" },
{ style: "font-style=normal", clearMark: m => m.type.name == "em" }
],
toDOM() { return ["em"]; }
},
strong: {
parseDOM: [
{ tag: "strong" },
{ tag: "b", getAttrs: node => node.style.fontWeight != "normal" && null },
{ style: "font-weight=400", clearMark: m => m.type.name == "strong" },
{ style: "font-weight", getAttrs: value => /^(bold(er)?|[5-9]\d{2,})$/.test(value) && null }
],
toDOM() { return ["strong"]; }
},
link: {
attrs: {
href: {},
title: { default: null }
},
inclusive: false,
parseDOM: [{ tag: "a[href]", getAttrs(dom) {
return { href: dom.getAttribute("href"), title: dom.getAttribute("title") };
} }],
toDOM(node) { return ["a", node.attrs]; }
},
code: {
code: true,
parseDOM: [{ tag: "code" }],
toDOM() { return ["code"]; }
}
}
});
// @ts-ignore
function maybeMerge(a, b) {
if (a.isText && b.isText && Mark.sameSet(a.marks, b.marks))
return a.withText(a.text + b.text);
}
// Object used to track the context of a running parse.
class MarkdownParseState {
constructor(schema, tokenHandlers) {
this.schema = schema;
this.tokenHandlers = tokenHandlers;
this.stack = [{ type: schema.topNodeType, attrs: null, content: [], marks: Mark.none }];
}
top() {
return this.stack[this.stack.length - 1];
}
push(elt) {
if (this.stack.length)
this.top().content.push(elt);
}
// Adds the given text to the current position in the document,
// using the current marks as styling.
addText(text) {
if (!text)
return;
let top = this.top(), nodes = top.content, last = nodes[nodes.length - 1];
let node = this.schema.text(text, top.marks), merged;
if (last && (merged = maybeMerge(last, node)))
nodes[nodes.length - 1] = merged;
else
nodes.push(node);
}
// Adds the given mark to the set of active marks.
openMark(mark) {
let top = this.top();
top.marks = mark.addToSet(top.marks);
}
// Removes the given mark from the set of active marks.
closeMark(mark) {
let top = this.top();
top.marks = mark.removeFromSet(top.marks);
}
parseTokens(toks) {
for (let i = 0; i < toks.length; i++) {
let tok = toks[i];
let handler = this.tokenHandlers[tok.type];
if (!handler)
throw new Error("Token type `" + tok.type + "` not supported by Markdown parser");
handler(this, tok, toks, i);
}
}
// Add a node at the current position.
addNode(type, attrs, content) {
let top = this.top();
let node = type.createAndFill(attrs, content, top ? top.marks : []);
if (!node)
return null;
this.push(node);
return node;
}
// Wrap subsequent content in a node of the given type.
openNode(type, attrs) {
this.stack.push({ type: type, attrs: attrs, content: [], marks: Mark.none });
}
// Close and return the node that is currently on top of the stack.
closeNode() {
let info = this.stack.pop();
return this.addNode(info.type, info.attrs, info.content);
}
}
function attrs(spec, token, tokens, i) {
if (spec.getAttrs)
return spec.getAttrs(token, tokens, i);
// For backwards compatibility when `attrs` is a Function
else if (spec.attrs instanceof Function)
return spec.attrs(token);
else
return spec.attrs;
}
// Code content is represented as a single token with a `content`
// property in Markdown-it.
function noCloseToken(spec, type) {
return spec.noCloseToken || type == "code_inline" || type == "code_block" || type == "fence";
}
function withoutTrailingNewline(str) {
return str[str.length - 1] == "\n" ? str.slice(0, str.length - 1) : str;
}
function noOp() { }
function tokenHandlers(schema, tokens) {
let handlers = Object.create(null);
for (let type in tokens) {
let spec = tokens[type];
if (spec.block) {
let nodeType = schema.nodeType(spec.block);
if (noCloseToken(spec, type)) {
handlers[type] = (state, tok, tokens, i) => {
state.openNode(nodeType, attrs(spec, tok, tokens, i));
state.addText(withoutTrailingNewline(tok.content));
state.closeNode();
};
}
else {
handlers[type + "_open"] = (state, tok, tokens, i) => state.openNode(nodeType, attrs(spec, tok, tokens, i));
handlers[type + "_close"] = state => state.closeNode();
}
}
else if (spec.node) {
let nodeType = schema.nodeType(spec.node);
handlers[type] = (state, tok, tokens, i) => state.addNode(nodeType, attrs(spec, tok, tokens, i));
}
else if (spec.mark) {
let markType = schema.marks[spec.mark];
if (noCloseToken(spec, type)) {
handlers[type] = (state, tok, tokens, i) => {
state.openMark(markType.create(attrs(spec, tok, tokens, i)));
state.addText(withoutTrailingNewline(tok.content));
state.closeMark(markType);
};
}
else {
handlers[type + "_open"] = (state, tok, tokens, i) => state.openMark(markType.create(attrs(spec, tok, tokens, i)));
handlers[type + "_close"] = state => state.closeMark(markType);
}
}
else if (spec.ignore) {
if (noCloseToken(spec, type)) {
handlers[type] = noOp;
}
else {
handlers[type + "_open"] = noOp;
handlers[type + "_close"] = noOp;
}
}
else {
throw new RangeError("Unrecognized parsing spec " + JSON.stringify(spec));
}
}
handlers.text = (state, tok) => state.addText(tok.content);
handlers.inline = (state, tok) => state.parseTokens(tok.children);
handlers.softbreak = handlers.softbreak || (state => state.addText(" "));
return handlers;
}
/**
A configuration of a Markdown parser. Such a parser uses
[markdown-it](https://github.com/markdown-it/markdown-it) to
tokenize a file, and then runs the custom rules it is given over
the tokens to create a ProseMirror document tree.
*/
class MarkdownParser {
/**
Create a parser with the given configuration. You can configure
the markdown-it parser to parse the dialect you want, and provide
a description of the ProseMirror entities those tokens map to in
the `tokens` object, which maps token names to descriptions of
what to do with them. Such a description is an object, and may
have the following properties:
*/
constructor(
/**
The parser's document schema.
*/
schema,
/**
This parser's markdown-it tokenizer.
*/
tokenizer,
/**
The value of the `tokens` object used to construct this
parser. Can be useful to copy and modify to base other parsers
on.
*/
tokens) {
this.schema = schema;
this.tokenizer = tokenizer;
this.tokens = tokens;
this.tokenHandlers = tokenHandlers(schema, tokens);
}
/**
Parse a string as [CommonMark](http://commonmark.org/) markup,
and create a ProseMirror document as prescribed by this parser's
rules.
The second argument, when given, is passed through to the
[Markdown
parser](https://markdown-it.github.io/markdown-it/#MarkdownIt.parse).
*/
parse(text, markdownEnv = {}) {
let state = new MarkdownParseState(this.schema, this.tokenHandlers), doc;
state.parseTokens(this.tokenizer.parse(text, markdownEnv));
do {
doc = state.closeNode();
} while (state.stack.length);
return doc || this.schema.topNodeType.createAndFill();
}
}
function listIsTight(tokens, i) {
while (++i < tokens.length)
if (tokens[i].type != "list_item_open")
return tokens[i].hidden;
return false;
}
/**
A parser parsing unextended [CommonMark](http://commonmark.org/),
without inline HTML, and producing a document in the basic schema.
*/
const defaultMarkdownParser = new MarkdownParser(schema, MarkdownIt("commonmark", { html: false }), {
blockquote: { block: "blockquote" },
paragraph: { block: "paragraph" },
list_item: { block: "list_item" },
bullet_list: { block: "bullet_list", getAttrs: (_, tokens, i) => ({ tight: listIsTight(tokens, i) }) },
ordered_list: { block: "ordered_list", getAttrs: (tok, tokens, i) => ({
order: +tok.attrGet("start") || 1,
tight: listIsTight(tokens, i)
}) },
heading: { block: "heading", getAttrs: tok => ({ level: +tok.tag.slice(1) }) },
code_block: { block: "code_block", noCloseToken: true },
fence: { block: "code_block", getAttrs: tok => ({ params: tok.info || "" }), noCloseToken: true },
hr: { node: "horizontal_rule" },
image: { node: "image", getAttrs: tok => ({
src: tok.attrGet("src"),
title: tok.attrGet("title") || null,
alt: tok.children[0] && tok.children[0].content || null
}) },
hardbreak: { node: "hard_break" },
em: { mark: "em" },
strong: { mark: "strong" },
link: { mark: "link", getAttrs: tok => ({
href: tok.attrGet("href"),
title: tok.attrGet("title") || null
}) },
code_inline: { mark: "code", noCloseToken: true }
});
const blankMark = { open: "", close: "", mixable: true };
/**
A specification for serializing a ProseMirror document as
Markdown/CommonMark text.
*/
class MarkdownSerializer {
/**
Construct a serializer with the given configuration. The `nodes`
object should map node names in a given schema to function that
take a serializer state and such a node, and serialize the node.
*/
constructor(
/**
The node serializer functions for this serializer.
*/
nodes,
/**
The mark serializer info.
*/
marks, options = {}) {
this.nodes = nodes;
this.marks = marks;
this.options = options;
}
/**
Serialize the content of the given node to
[CommonMark](http://commonmark.org/).
*/
serialize(content, options = {}) {
options = Object.assign({}, this.options, options);
let state = new MarkdownSerializerState(this.nodes, this.marks, options);
state.renderContent(content);
return state.out;
}
}
/**
A serializer for the [basic schema](https://prosemirror.net/docs/ref/#schema).
*/
const defaultMarkdownSerializer = new MarkdownSerializer({
blockquote(state, node) {
state.wrapBlock("> ", null, node, () => state.renderContent(node));
},
code_block(state, node) {
// Make sure the front matter fences are longer than any dash sequence within it
const backticks = node.textContent.match(/`{3,}/gm);
const fence = backticks ? (backticks.sort().slice(-1)[0] + "`") : "```";
state.write(fence + (node.attrs.params || "") + "\n");
state.text(node.textContent, false);
// Add a newline to the current content before adding closing marker
state.write("\n");
state.write(fence);
state.closeBlock(node);
},
heading(state, node) {
state.write(state.repeat("#", node.attrs.level) + " ");
state.renderInline(node, false);
state.closeBlock(node);
},
horizontal_rule(state, node) {
state.write(node.attrs.markup || "---");
state.closeBlock(node);
},
bullet_list(state, node) {
state.renderList(node, " ", () => (node.attrs.bullet || "*") + " ");
},
ordered_list(state, node) {
let start = node.attrs.order || 1;
let maxW = String(start + node.childCount - 1).length;
let space = state.repeat(" ", maxW + 2);
state.renderList(node, space, i => {
let nStr = String(start + i);
return state.repeat(" ", maxW - nStr.length) + nStr + ". ";
});
},
list_item(state, node) {
state.renderContent(node);
},
paragraph(state, node) {
state.renderInline(node);
state.closeBlock(node);
},
image(state, node) {
state.write("![" + state.esc(node.attrs.alt || "") + "](" + node.attrs.src.replace(/[\(\)]/g, "\\$&") +
(node.attrs.title ? ' "' + node.attrs.title.replace(/"/g, '\\"') + '"' : "") + ")");
},
hard_break(state, node, parent, index) {
for (let i = index + 1; i < parent.childCount; i++)
if (parent.child(i).type != node.type) {
state.write("\\\n");
return;
}
},
text(state, node) {
state.text(node.text, !state.inAutolink);
}
}, {
em: { open: "*", close: "*", mixable: true, expelEnclosingWhitespace: true },
strong: { open: "**", close: "**", mixable: true, expelEnclosingWhitespace: true },
link: {
open(state, mark, parent, index) {
state.inAutolink = isPlainURL(mark, parent, index);
return state.inAutolink ? "<" : "[";
},
close(state, mark, parent, index) {
let { inAutolink } = state;
state.inAutolink = undefined;
return inAutolink ? ">"
: "](" + mark.attrs.href.replace(/[\(\)"]/g, "\\$&") + (mark.attrs.title ? ` "${mark.attrs.title.replace(/"/g, '\\"')}"` : "") + ")";
},
mixable: true
},
code: { open(_state, _mark, parent, index) { return backticksFor(parent.child(index), -1); },
close(_state, _mark, parent, index) { return backticksFor(parent.child(index - 1), 1); },
escape: false }
});
function backticksFor(node, side) {
let ticks = /`+/g, m, len = 0;
if (node.isText)
while (m = ticks.exec(node.text))
len = Math.max(len, m[0].length);
let result = len > 0 && side > 0 ? " `" : "`";
for (let i = 0; i < len; i++)
result += "`";
if (len > 0 && side < 0)
result += " ";
return result;
}
function isPlainURL(link, parent, index) {
if (link.attrs.title || !/^\w+:/.test(link.attrs.href))
return false;
let content = parent.child(index);
if (!content.isText || content.text != link.attrs.href || content.marks[content.marks.length - 1] != link)
return false;
return index == parent.childCount - 1 || !link.isInSet(parent.child(index + 1).marks);
}
/**
This is an object used to track state and expose
methods related to markdown serialization. Instances are passed to
node and mark serialization methods (see `toMarkdown`).
*/
class MarkdownSerializerState {
/**
@internal
*/
constructor(
/**
@internal
*/
nodes,
/**
@internal
*/
marks,
/**
The options passed to the serializer.
*/
options) {
this.nodes = nodes;
this.marks = marks;
this.options = options;
/**
@internal
*/
this.delim = "";
/**
@internal
*/
this.out = "";
/**
@internal
*/
this.closed = null;
/**
@internal
*/
this.inAutolink = undefined;
/**
@internal
*/
this.atBlockStart = false;
/**
@internal
*/
this.inTightList = false;
if (typeof this.options.tightLists == "undefined")
this.options.tightLists = false;
if (typeof this.options.hardBreakNodeName == "undefined")
this.options.hardBreakNodeName = "hard_break";
}
/**
@internal
*/
flushClose(size = 2) {
if (this.closed) {
if (!this.atBlank())
this.out += "\n";
if (size > 1) {
let delimMin = this.delim;
let trim = /\s+$/.exec(delimMin);
if (trim)
delimMin = delimMin.slice(0, delimMin.length - trim[0].length);
for (let i = 1; i < size; i++)
this.out += delimMin + "\n";
}
this.closed = null;
}
}
/**
@internal
*/
getMark(name) {
let info = this.marks[name];
if (!info) {
if (this.options.strict !== false)
throw new Error(`Mark type \`${name}\` not supported by Markdown renderer`);
info = blankMark;
}
return info;
}
/**
Render a block, prefixing each line with `delim`, and the first
line in `firstDelim`. `node` should be the node that is closed at
the end of the block, and `f` is a function that renders the
content of the block.
*/
wrapBlock(delim, firstDelim, node, f) {
let old = this.delim;
this.write(firstDelim != null ? firstDelim : delim);
this.delim += delim;
f();
this.delim = old;
this.closeBlock(node);
}
/**
@internal
*/
atBlank() {
return /(^|\n)$/.test(this.out);
}
/**
Ensure the current content ends with a newline.
*/
ensureNewLine() {
if (!this.atBlank())
this.out += "\n";
}
/**
Prepare the state for writing output (closing closed paragraphs,
adding delimiters, and so on), and then optionally add content
(unescaped) to the output.
*/
write(content) {
this.flushClose();
if (this.delim && this.atBlank())
this.out += this.delim;
if (content)
this.out += content;
}
/**
Close the block for the given node.
*/
closeBlock(node) {
this.closed = node;
}
/**
Add the given text to the document. When escape is not `false`,
it will be escaped.
*/
text(text, escape = true) {
let lines = text.split("\n");
for (let i = 0; i < lines.length; i++) {
this.write();
// Escape exclamation marks in front of links
if (!escape && lines[i][0] == "[" && /(^|[^\\])\!$/.test(this.out))
this.out = this.out.slice(0, this.out.length - 1) + "\\!";
this.out += escape ? this.esc(lines[i], this.atBlockStart) : lines[i];
if (i != lines.length - 1)
this.out += "\n";
}
}
/**
Render the given node as a block.
*/
render(node, parent, index) {
if (this.nodes[node.type.name]) {
this.nodes[node.type.name](this, node, parent, index);
}
else {
if (this.options.strict !== false) {
throw new Error("Token type `" + node.type.name + "` not supported by Markdown renderer");
}
else if (!node.type.isLeaf) {
if (node.type.inlineContent)
this.renderInline(node);
else
this.renderContent(node);
if (node.isBlock)
this.closeBlock(node);
}
}
}
/**
Render the contents of `parent` as block nodes.
*/
renderContent(parent) {
parent.forEach((node, _, i) => this.render(node, parent, i));
}
/**
Render the contents of `parent` as inline content.
*/
renderInline(parent, fromBlockStart = true) {
this.atBlockStart = fromBlockStart;
let active = [], trailing = "";
let progress = (node, offset, index) => {
let marks = node ? node.marks : [];
// Remove marks from `hard_break` that are the last node inside
// that mark to prevent parser edge cases with new lines just
// before closing marks.
if (node && node.type.name === this.options.hardBreakNodeName)
marks = marks.filter(m => {
if (index + 1 == parent.childCount)
return false;
let next = parent.child(index + 1);
return m.isInSet(next.marks) && (!next.isText || /\S/.test(next.text));
});
let leading = trailing;
trailing = "";
// If whitespace has to be expelled from the node, adjust
// leading and trailing accordingly.
if (node && node.isText && marks.some(mark => {
let info = this.getMark(mark.type.name);
return info && info.expelEnclosingWhitespace && !mark.isInSet(active);
})) {
let [_, lead, rest] = /^(\s*)(.*)$/m.exec(node.text);
if (lead) {
leading += lead;
node = rest ? node.withText(rest) : null;
if (!node)
marks = active;
}
}
if (node && node.isText && marks.some(mark => {
let info = this.getMark(mark.type.name);
return info && info.expelEnclosingWhitespace && !this.isMarkAhead(parent, index + 1, mark);
})) {
let [_, rest, trail] = /^(.*?)(\s*)$/m.exec(node.text);
if (trail) {
trailing = trail;
node = rest ? node.withText(rest) : null;
if (!node)
marks = active;
}
}
let inner = marks.length ? marks[marks.length - 1] : null;
let noEsc = inner && this.getMark(inner.type.name).escape === false;
let len = marks.length - (noEsc ? 1 : 0);
// Try to reorder 'mixable' marks, such as em and strong, which
// in Markdown may be opened and closed in different order, so
// that order of the marks for the token matches the order in
// active.
outer: for (let i = 0; i < len; i++) {
let mark = marks[i];
if (!this.getMark(mark.type.name).mixable)
break;
for (let j = 0; j < active.length; j++) {
let other = active[j];
if (!this.getMark(other.type.name).mixable)
break;
if (mark.eq(other)) {
if (i > j)
marks = marks.slice(0, j).concat(mark).concat(marks.slice(j, i)).concat(marks.slice(i + 1, len));
else if (j > i)
marks = marks.slice(0, i).concat(marks.slice(i + 1, j)).concat(mark).concat(marks.slice(j, len));
continue outer;
}
}
}
// Find the prefix of the mark set that didn't change
let keep = 0;
while (keep < Math.min(active.length, len) && marks[keep].eq(active[keep]))
++keep;
// Close the marks that need to be closed
while (keep < active.length)
this.text(this.markString(active.pop(), false, parent, index), false);
// Output any previously expelled trailing whitespace outside the marks
if (leading)
this.text(leading);
// Open the marks that need to be opened
if (node) {
while (active.length < len) {
let add = marks[active.length];
active.push(add);
this.text(this.markString(add, true, parent, index), false);
this.atBlockStart = false;
}
// Render the node. Special case code marks, since their content
// may not be escaped.
if (noEsc && node.isText)
this.text(this.markString(inner, true, parent, index) + node.text +
this.markString(inner, false, parent, index + 1), false);
else
this.render(node, parent, index);
this.atBlockStart = false;
}
// After the first non-empty text node is rendered, the end of output
// is no longer at block start.
//
// FIXME: If a non-text node writes something to the output for this
// block, the end of output is also no longer at block start. But how
// can we detect that?
if ((node === null || node === void 0 ? void 0 : node.isText) && node.nodeSize > 0) {
this.atBlockStart = false;
}
};
parent.forEach(progress);
progress(null, 0, parent.childCount);
this.atBlockStart = false;
}
/**
Render a node's content as a list. `delim` should be the extra
indentation added to all lines except the first in an item,
`firstDelim` is a function going from an item index to a
delimiter for the first line of the item.
*/
renderList(node, delim, firstDelim) {
if (this.closed && this.closed.type == node.type)
this.flushClose(3);
else if (this.inTightList)
this.flushClose(1);
let isTight = typeof node.attrs.tight != "undefined" ? node.attrs.tight : this.options.tightLists;
let prevTight = this.inTightList;
this.inTightList = isTight;
node.forEach((child, _, i) => {
if (i && isTight)
this.flushClose(1);
this.wrapBlock(delim, firstDelim(i), node, () => this.render(child, node, i));
});
this.inTightList = prevTight;
}
/**
Escape the given string so that it can safely appear in Markdown
content. If `startOfLine` is true, also escape characters that
have special meaning only at the start of the line.
*/
esc(str, startOfLine = false) {
str = str.replace(/[`*\\~\[\]_]/g, (m, i) => m == "_" && i > 0 && i + 1 < str.length && str[i - 1].match(/\w/) && str[i + 1].match(/\w/) ? m : "\\" + m);
if (startOfLine)
str = str.replace(/^(\+[ ]|[\-*>])/, "\\$&").replace(/^(\s*)(#{1,6})(\s|$)/, '$1\\$2$3').replace(/^(\s*\d+)\.\s/, "$1\\. ");
if (this.options.escapeExtraCharacters)
str = str.replace(this.options.escapeExtraCharacters, "\\$&");
return str;
}
/**
@internal
*/
quote(str) {
let wrap = str.indexOf('"') == -1 ? '""' : str.indexOf("'") == -1 ? "''" : "()";
return wrap[0] + str + wrap[1];
}
/**
Repeat the given string `n` times.
*/
repeat(str, n) {
let out = "";
for (let i = 0; i < n; i++)
out += str;
return out;
}
/**
Get the markdown string for a given opening or closing mark.
*/
markString(mark, open, parent, index) {
let info = this.getMark(mark.type.name);
let value = open ? info.open : info.close;
return typeof value == "string" ? value : value(this, mark, parent, index);
}
/**
Get leading and trailing whitespace from a string. Values of
leading or trailing property of the return object will be undefined
if there is no match.
*/
getEnclosingWhitespace(text) {
return {
leading: (text.match(/^(\s+)/) || [undefined])[0],
trailing: (text.match(/(\s+)$/) || [undefined])[0]
};
}
/**
@internal
*/
isMarkAhead(parent, index, mark) {
for (;; index++) {
if (index >= parent.childCount)
return false;
let next = parent.child(index);
if (next.type.name != this.options.hardBreakNodeName)
return mark.isInSet(next.marks);
index++;
}
}
}
export { MarkdownParser, MarkdownSerializer, MarkdownSerializerState, defaultMarkdownParser, defaultMarkdownSerializer, schema };