mirror of
https://github.com/docmost/docmost.git
synced 2026-05-07 06:23:06 +08:00
feat: support pasting markdown (#606)
This commit is contained in:
@@ -36,6 +36,7 @@ import {
|
|||||||
Drawio,
|
Drawio,
|
||||||
Excalidraw,
|
Excalidraw,
|
||||||
Embed,
|
Embed,
|
||||||
|
MarkdownClipboard,
|
||||||
} from "@docmost/editor-ext";
|
} from "@docmost/editor-ext";
|
||||||
import {
|
import {
|
||||||
randomElement,
|
randomElement,
|
||||||
@@ -186,6 +187,9 @@ export const mainExtensions = [
|
|||||||
Embed.configure({
|
Embed.configure({
|
||||||
view: EmbedView,
|
view: EmbedView,
|
||||||
}),
|
}),
|
||||||
|
MarkdownClipboard.configure({
|
||||||
|
transformPastedText: true,
|
||||||
|
}),
|
||||||
] as any;
|
] as any;
|
||||||
|
|
||||||
type CollabExtensions = (provider: HocuspocusProvider, user: IUser) => any[];
|
type CollabExtensions = (provider: HocuspocusProvider, user: IUser) => any[];
|
||||||
|
|||||||
@@ -58,7 +58,6 @@
|
|||||||
"happy-dom": "^15.11.6",
|
"happy-dom": "^15.11.6",
|
||||||
"kysely": "^0.27.4",
|
"kysely": "^0.27.4",
|
||||||
"kysely-migration-cli": "^0.4.2",
|
"kysely-migration-cli": "^0.4.2",
|
||||||
"marked": "^13.0.3",
|
|
||||||
"mime-types": "^2.1.35",
|
"mime-types": "^2.1.35",
|
||||||
"nanoid": "^5.0.9",
|
"nanoid": "^5.0.9",
|
||||||
"nestjs-kysely": "^1.0.0",
|
"nestjs-kysely": "^1.0.0",
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ import { InjectKysely } from 'nestjs-kysely';
|
|||||||
import { KyselyDB } from '@docmost/db/types/kysely.types';
|
import { KyselyDB } from '@docmost/db/types/kysely.types';
|
||||||
import { generateSlugId } from '../../common/helpers';
|
import { generateSlugId } from '../../common/helpers';
|
||||||
import { generateJitteredKeyBetween } from 'fractional-indexing-jittered';
|
import { generateJitteredKeyBetween } from 'fractional-indexing-jittered';
|
||||||
import { markdownToHtml } from './utils/marked.utils';
|
|
||||||
import { TiptapTransformer } from '@hocuspocus/transformer';
|
import { TiptapTransformer } from '@hocuspocus/transformer';
|
||||||
import * as Y from 'yjs';
|
import * as Y from 'yjs';
|
||||||
|
import { markdownToHtml } from "@docmost/editor-ext";
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class ImportService {
|
export class ImportService {
|
||||||
|
|||||||
@@ -65,6 +65,7 @@
|
|||||||
"fractional-indexing-jittered": "^0.9.1",
|
"fractional-indexing-jittered": "^0.9.1",
|
||||||
"ioredis": "^5.4.1",
|
"ioredis": "^5.4.1",
|
||||||
"jszip": "^3.10.1",
|
"jszip": "^3.10.1",
|
||||||
|
"marked": "^13.0.3",
|
||||||
"uuid": "^11.0.3",
|
"uuid": "^11.0.3",
|
||||||
"y-indexeddb": "^9.0.12",
|
"y-indexeddb": "^9.0.12",
|
||||||
"yjs": "^13.6.20"
|
"yjs": "^13.6.20"
|
||||||
|
|||||||
@@ -15,4 +15,4 @@ export * from "./lib/custom-code-block"
|
|||||||
export * from "./lib/drawio";
|
export * from "./lib/drawio";
|
||||||
export * from "./lib/excalidraw";
|
export * from "./lib/excalidraw";
|
||||||
export * from "./lib/embed";
|
export * from "./lib/embed";
|
||||||
|
export * from "./lib/markdown";
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
export * from "./markdown-clipboard";
|
||||||
|
export * from "./utils/marked.utils";
|
||||||
@@ -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;
|
||||||
|
}
|
||||||
+1
-1
@@ -30,7 +30,7 @@ marked.use({
|
|||||||
|
|
||||||
marked.use({ extensions: [calloutExtension, mathBlockExtension, mathInlineExtension] });
|
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 YAML_FONT_MATTER_REGEX = /^\s*---[\s\S]*?---\s*/;
|
||||||
|
|
||||||
const markdown = markdownInput
|
const markdown = markdownInput
|
||||||
Generated
+3
-3
@@ -160,6 +160,9 @@ importers:
|
|||||||
jszip:
|
jszip:
|
||||||
specifier: ^3.10.1
|
specifier: ^3.10.1
|
||||||
version: 3.10.1
|
version: 3.10.1
|
||||||
|
marked:
|
||||||
|
specifier: ^13.0.3
|
||||||
|
version: 13.0.3
|
||||||
uuid:
|
uuid:
|
||||||
specifier: ^11.0.3
|
specifier: ^11.0.3
|
||||||
version: 11.0.3
|
version: 11.0.3
|
||||||
@@ -474,9 +477,6 @@ importers:
|
|||||||
kysely-migration-cli:
|
kysely-migration-cli:
|
||||||
specifier: ^0.4.2
|
specifier: ^0.4.2
|
||||||
version: 0.4.2
|
version: 0.4.2
|
||||||
marked:
|
|
||||||
specifier: ^13.0.3
|
|
||||||
version: 13.0.3
|
|
||||||
mime-types:
|
mime-types:
|
||||||
specifier: ^2.1.35
|
specifier: ^2.1.35
|
||||||
version: 2.1.35
|
version: 2.1.35
|
||||||
|
|||||||
Reference in New Issue
Block a user