fix: VSCode markdown pasting (#857)

* fix vscode markdown pasting

* fix markdown -> html formatting
This commit is contained in:
Philip Okugbe 2025-03-10 02:38:22 +00:00 committed by GitHub
parent 061a02ce51
commit fea6518352
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 52 additions and 10 deletions

View File

@ -7,7 +7,7 @@ import { markdownToHtml } from "@docmost/editor-ext";
export const MarkdownClipboard = Extension.create({
name: "markdownClipboard",
priority: 50,
priority: 101,
addOptions() {
return {
@ -19,6 +19,40 @@ export const MarkdownClipboard = Extension.create({
new Plugin({
key: new PluginKey("markdownClipboard"),
props: {
handlePaste: (view, event, slice) => {
if (!event.clipboardData) {
return false;
}
if (this.editor.isActive("codeBlock")) {
return false;
}
const text = event.clipboardData.getData("text/plain");
const vscode = event.clipboardData.getData("vscode-editor-data");
const vscodeData = vscode ? JSON.parse(vscode) : undefined;
const language = vscodeData?.mode;
if (language !== "markdown") {
return false;
}
const { tr } = view.state;
const { from, to } = view.state.selection;
const html = markdownToHtml(text);
const contentNodes = DOMParser.fromSchema(
this.editor.schema,
).parseSlice(elementFromString(html), {
preserveWhitespace: true,
});
tr.replaceRange(from, to, contentNodes);
tr.setMeta('paste', true)
view.dispatch(tr);
return true;
},
clipboardTextParser: (text, context, plainText) => {
const link = find(text, {
defaultProtocol: "http",

View File

@ -1,6 +1,6 @@
import { marked } from 'marked';
import { calloutExtension } from './callout.marked';
import { mathBlockExtension } from './math-block.marked';
import { marked } from "marked";
import { calloutExtension } from "./callout.marked";
import { mathBlockExtension } from "./math-block.marked";
import { mathInlineExtension } from "./math-inline.marked";
marked.use({
@ -8,11 +8,11 @@ marked.use({
// @ts-ignore
list(body: string, isOrdered: boolean, start: number) {
if (isOrdered) {
const startAttr = start !== 1 ? ` start="${start}"` : '';
const startAttr = start !== 1 ? ` start="${start}"` : "";
return `<ol ${startAttr}>\n${body}</ol>\n`;
}
const dataType = body.includes(`<input`) ? ' data-type="taskList"' : '';
const dataType = body.includes(`<input`) ? ' data-type="taskList"' : "";
return `<ul${dataType}>\n${body}</ul>\n`;
},
// @ts-ignore
@ -28,14 +28,22 @@ marked.use({
},
});
marked.use({ extensions: [calloutExtension, mathBlockExtension, mathInlineExtension] });
marked.use({
extensions: [calloutExtension, mathBlockExtension, mathInlineExtension],
});
export function markdownToHtml(markdownInput: string): string | Promise<string> {
export function markdownToHtml(
markdownInput: string,
): string | Promise<string> {
const YAML_FONT_MATTER_REGEX = /^\s*---[\s\S]*?---\s*/;
const markdown = markdownInput
.replace(YAML_FONT_MATTER_REGEX, '')
.replace(YAML_FONT_MATTER_REGEX, "")
.trimStart();
return marked.parse(markdown);
return marked
.options({ breaks: true })
.parse(markdown)
.toString()
.replace(/\n/g, "");
}