|
- import { MarkdownSerializer } from "prosemirror-markdown";
-
- function backticksFor(node, side) {
- const ticks = /`+/g;
- let m;
- let 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, side) {
- if (link.attrs.title || !/^\w+:/.test(link.attrs.href)) return false;
- const content = parent.child(index + (side < 0 ? -1 : 0));
- if (
- !content.isText ||
- content.text != link.attrs.href ||
- content.marks[content.marks.length - 1] != link
- )
- return false;
- if (index == (side < 0 ? 1 : parent.childCount - 1)) return true;
- const next = parent.child(index + (side < 0 ? -2 : 1));
- return !link.isInSet(next.marks);
- }
-
- export const writeFreelyMarkdownSerializer = new MarkdownSerializer(
- {
- readmore(state, node) {
- state.write("<!--more-->\n");
- state.closeBlock(node);
- },
- blockquote(state, node) {
- state.wrapBlock("> ", null, node, () => state.renderContent(node));
- },
- code_block(state, node) {
- state.write(`\`\`\`${node.attrs.params || ""}\n`);
- state.text(node.textContent, false);
- state.ensureNewLine();
- state.write("```");
- state.closeBlock(node);
- },
- heading(state, node) {
- state.write(`${state.repeat("#", node.attrs.level)} `);
- state.renderInline(node);
- state.closeBlock(node);
- },
- horizontal_rule: function horizontal_rule(state, node) {
- state.write(node.attrs.markup || "---");
- state.closeBlock(node);
- },
- bullet_list(state, node) {
- node.attrs.tight = true;
- state.renderList(node, " ", () => `${node.attrs.bullet || "*"} `);
- },
- ordered_list(state, node) {
- const start = node.attrs.order || 1;
- const maxW = String(start + node.childCount - 1).length;
- const space = state.repeat(" ", maxW + 2);
- state.renderList(node, space, (i) => {
- const 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 || "")}](${state.esc(node.attrs.src)}${
- node.attrs.title ? ` ${state.quote(node.attrs.title)}` : ""
- })`
- );
- },
- hard_break(state, node, parent, index) {
- for (let i = index + 1; i < parent.childCount; i += 1)
- if (parent.child(i).type !== node.type) {
- state.write("\\\n");
- return;
- }
- },
- text(state, node) {
- state.text(node.text || "");
- },
- },
- {
- em: {
- open: "_",
- close: "_",
- mixable: true,
- expelEnclosingWhitespace: true,
- },
- strong: {
- open: "**",
- close: "**",
- mixable: true,
- expelEnclosingWhitespace: true,
- },
- link: {
- open(_state, mark, parent, index) {
- return isPlainURL(mark, parent, index, 1) ? "<" : "[";
- },
- close(state, mark, parent, index) {
- return isPlainURL(mark, parent, index, -1)
- ? ">"
- : `](${state.esc(mark.attrs.href)}${
- mark.attrs.title ? ` ${state.quote(mark.attrs.title)}` : ""
- })`;
- },
- },
- 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,
- },
- }
- );
|