feat: support pasting markdown (#606)

This commit is contained in:
Philip Okugbe 2025-01-04 16:57:36 +00:00 committed by GitHub
parent 0cbbcb8eb1
commit 287b833838
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
12 changed files with 56 additions and 7 deletions

View File

@ -36,6 +36,7 @@ import {
Drawio,
Excalidraw,
Embed,
MarkdownClipboard,
} from "@docmost/editor-ext";
import {
randomElement,
@ -186,6 +187,9 @@ export const mainExtensions = [
Embed.configure({
view: EmbedView,
}),
MarkdownClipboard.configure({
transformPastedText: true,
}),
] as any;
type CollabExtensions = (provider: HocuspocusProvider, user: IUser) => any[];

View File

@ -58,7 +58,6 @@
"happy-dom": "^15.11.6",
"kysely": "^0.27.4",
"kysely-migration-cli": "^0.4.2",
"marked": "^13.0.3",
"mime-types": "^2.1.35",
"nanoid": "^5.0.9",
"nestjs-kysely": "^1.0.0",

View File

@ -11,9 +11,9 @@ import { InjectKysely } from 'nestjs-kysely';
import { KyselyDB } from '@docmost/db/types/kysely.types';
import { generateSlugId } from '../../common/helpers';
import { generateJitteredKeyBetween } from 'fractional-indexing-jittered';
import { markdownToHtml } from './utils/marked.utils';
import { TiptapTransformer } from '@hocuspocus/transformer';
import * as Y from 'yjs';
import { markdownToHtml } from "@docmost/editor-ext";
@Injectable()
export class ImportService {

View File

@ -65,6 +65,7 @@
"fractional-indexing-jittered": "^0.9.1",
"ioredis": "^5.4.1",
"jszip": "^3.10.1",
"marked": "^13.0.3",
"uuid": "^11.0.3",
"y-indexeddb": "^9.0.12",
"yjs": "^13.6.20"

View File

@ -15,4 +15,4 @@ export * from "./lib/custom-code-block"
export * from "./lib/drawio";
export * from "./lib/excalidraw";
export * from "./lib/embed";
export * from "./lib/markdown";

View File

@ -0,0 +1,2 @@
export * from "./markdown-clipboard";
export * from "./utils/marked.utils";

View File

@ -0,0 +1,43 @@
// adapted from: https://github.com/aguingand/tiptap-markdown/blob/main/src/extensions/tiptap/clipboard.js - MIT
import { Extension } from "@tiptap/core";
import { Plugin, PluginKey } from "@tiptap/pm/state";
import { DOMParser } from "@tiptap/pm/model";
import { markdownToHtml } from "./utils/marked.utils";
export const MarkdownClipboard = Extension.create({
name: "markdownClipboard",
addOptions() {
return {
transformPastedText: false,
};
},
addProseMirrorPlugins() {
return [
new Plugin({
key: new PluginKey("markdownClipboard"),
props: {
clipboardTextParser: (text, context, plainText) => {
if (plainText || !this.options.transformPastedText) {
return null; // pasting with shift key prevents formatting
}
const parsed = markdownToHtml(text);
return DOMParser.fromSchema(this.editor.schema).parseSlice(
elementFromString(parsed),
{
preserveWhitespace: true,
context,
},
);
},
},
}),
];
},
});
function elementFromString(value) {
// add a wrapper to preserve leading and trailing whitespace
const wrappedValue = `<body>${value}</body>`;
return new window.DOMParser().parseFromString(wrappedValue, "text/html").body;
}

View File

@ -30,7 +30,7 @@ marked.use({
marked.use({ extensions: [calloutExtension, mathBlockExtension, mathInlineExtension] });
export async function markdownToHtml(markdownInput: string): Promise<string> {
export function markdownToHtml(markdownInput: string): string | Promise<string> {
const YAML_FONT_MATTER_REGEX = /^\s*---[\s\S]*?---\s*/;
const markdown = markdownInput

6
pnpm-lock.yaml generated
View File

@ -160,6 +160,9 @@ importers:
jszip:
specifier: ^3.10.1
version: 3.10.1
marked:
specifier: ^13.0.3
version: 13.0.3
uuid:
specifier: ^11.0.3
version: 11.0.3
@ -474,9 +477,6 @@ importers:
kysely-migration-cli:
specifier: ^0.4.2
version: 0.4.2
marked:
specifier: ^13.0.3
version: 13.0.3
mime-types:
specifier: ^2.1.35
version: 2.1.35