@prosekit/extensions 0.0.0-next-20231120040948 → 0.0.0-next-20240421132240
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_tsup-dts-rollup.d.ts +521 -91
- package/dist/chunk-ASTUC4KT.js +111 -0
- package/dist/chunk-DYFRBXUX.js +56 -0
- package/dist/list/style.css +17 -12
- package/dist/prosekit-extensions-autocomplete.js +8 -4
- package/dist/prosekit-extensions-blockquote.d.ts +1 -0
- package/dist/prosekit-extensions-blockquote.js +12 -1
- package/dist/prosekit-extensions-code-block.d.ts +14 -4
- package/dist/prosekit-extensions-code-block.js +171 -75
- package/dist/prosekit-extensions-drop-cursor.d.ts +2 -0
- package/dist/prosekit-extensions-drop-cursor.js +9 -0
- package/dist/prosekit-extensions-enter-rule.d.ts +5 -0
- package/dist/prosekit-extensions-enter-rule.js +8 -0
- package/dist/prosekit-extensions-heading.js +20 -14
- package/dist/prosekit-extensions-image.js +1 -0
- package/dist/prosekit-extensions-input-rule.d.ts +3 -0
- package/dist/prosekit-extensions-input-rule.js +10 -0
- package/dist/prosekit-extensions-link.d.ts +2 -0
- package/dist/prosekit-extensions-link.js +63 -5
- package/dist/prosekit-extensions-list.d.ts +1 -0
- package/dist/prosekit-extensions-list.js +7 -2
- package/dist/prosekit-extensions-mention.d.ts +1 -0
- package/dist/prosekit-extensions-mention.js +15 -2
- package/dist/prosekit-extensions-placeholder.js +4 -1
- package/dist/prosekit-extensions-readonly.d.ts +1 -0
- package/dist/prosekit-extensions-readonly.js +16 -0
- package/dist/prosekit-extensions-table.d.ts +7 -0
- package/dist/prosekit-extensions-table.js +197 -0
- package/dist/prosekit-extensions-virtual-selection.d.ts +1 -0
- package/dist/prosekit-extensions-virtual-selection.js +58 -0
- package/dist/shiki-import-25BJYIO2.js +5 -0
- package/dist/table/style.css +34 -0
- package/dist/virtual-selection/style.css +6 -0
- package/package.json +63 -15
- package/dist/prosekit-extensions-suggestion.d.ts +0 -3
- package/dist/prosekit-extensions-suggestion.js +0 -161
- package/src/index.ts +0 -1
@@ -0,0 +1,111 @@
|
|
1
|
+
// src/enter-rule/index.ts
|
2
|
+
import {
|
3
|
+
Facet,
|
4
|
+
OBJECT_REPLACEMENT_CHARACTER,
|
5
|
+
getNodeType,
|
6
|
+
isTextSelection,
|
7
|
+
pluginFacet
|
8
|
+
} from "@prosekit/core";
|
9
|
+
import { keydownHandler } from "@prosekit/pm/keymap";
|
10
|
+
import {
|
11
|
+
ProseMirrorPlugin
|
12
|
+
} from "@prosekit/pm/state";
|
13
|
+
function defineEnterRule({
|
14
|
+
regex,
|
15
|
+
handler,
|
16
|
+
stop = false
|
17
|
+
}) {
|
18
|
+
const rule = new EnterRule(regex, handler, stop);
|
19
|
+
return enterRule.extension([rule]);
|
20
|
+
}
|
21
|
+
function defineTextBlockEnterRule({
|
22
|
+
regex,
|
23
|
+
type,
|
24
|
+
attrs,
|
25
|
+
stop = true
|
26
|
+
}) {
|
27
|
+
return defineEnterRule({
|
28
|
+
regex,
|
29
|
+
handler: ({ state, from, to, match }) => {
|
30
|
+
const nodeType = getNodeType(state.schema, type);
|
31
|
+
const $start = state.doc.resolve(from);
|
32
|
+
if (!$start.node(-1).canReplaceWith($start.index(-1), $start.indexAfter(-1), nodeType)) {
|
33
|
+
return null;
|
34
|
+
}
|
35
|
+
const nodeAttrs = attrs && typeof attrs === "function" ? attrs(match) : attrs;
|
36
|
+
return state.tr.delete(from, to).setBlockType(from, from, nodeType, nodeAttrs);
|
37
|
+
},
|
38
|
+
stop
|
39
|
+
});
|
40
|
+
}
|
41
|
+
var EnterRule = class {
|
42
|
+
constructor(regex, handler, stop) {
|
43
|
+
this.regex = regex;
|
44
|
+
this.handler = handler;
|
45
|
+
this.stop = stop;
|
46
|
+
}
|
47
|
+
};
|
48
|
+
var enterRule = Facet.define({
|
49
|
+
converter: () => {
|
50
|
+
let rules = [];
|
51
|
+
const command = (state, dispatch, view) => {
|
52
|
+
if (!view)
|
53
|
+
return false;
|
54
|
+
return execRules(view, rules, dispatch);
|
55
|
+
};
|
56
|
+
const handler = keydownHandler({ Enter: command });
|
57
|
+
const plugin = new ProseMirrorPlugin({ props: { handleKeyDown: handler } });
|
58
|
+
const pluginFunc = () => [plugin];
|
59
|
+
return {
|
60
|
+
create: (inputs) => {
|
61
|
+
rules = inputs;
|
62
|
+
return pluginFunc;
|
63
|
+
},
|
64
|
+
update: (inputs) => {
|
65
|
+
rules = inputs;
|
66
|
+
return null;
|
67
|
+
}
|
68
|
+
};
|
69
|
+
},
|
70
|
+
next: pluginFacet
|
71
|
+
});
|
72
|
+
function execRules(view, rules, dispatch) {
|
73
|
+
if (view.composing)
|
74
|
+
return false;
|
75
|
+
const state = view.state;
|
76
|
+
const selection = state.selection;
|
77
|
+
if (!isTextSelection(selection))
|
78
|
+
return false;
|
79
|
+
const $cursor = selection.$cursor;
|
80
|
+
if (!$cursor || $cursor.parent.type.spec.code)
|
81
|
+
return false;
|
82
|
+
const textBefore = $cursor.parent.textBetween(
|
83
|
+
Math.max(0, $cursor.parentOffset - MAX_MATCH),
|
84
|
+
$cursor.parentOffset,
|
85
|
+
null,
|
86
|
+
OBJECT_REPLACEMENT_CHARACTER
|
87
|
+
);
|
88
|
+
for (const rule of rules) {
|
89
|
+
rule.regex.lastIndex = 0;
|
90
|
+
const match = rule.regex.exec(textBefore);
|
91
|
+
const tr = match && rule.handler({
|
92
|
+
state,
|
93
|
+
from: $cursor.pos - match[0].length,
|
94
|
+
to: $cursor.pos,
|
95
|
+
match
|
96
|
+
});
|
97
|
+
if (!tr)
|
98
|
+
continue;
|
99
|
+
dispatch == null ? void 0 : dispatch(tr);
|
100
|
+
if (rule.stop) {
|
101
|
+
return true;
|
102
|
+
}
|
103
|
+
}
|
104
|
+
return false;
|
105
|
+
}
|
106
|
+
var MAX_MATCH = 200;
|
107
|
+
|
108
|
+
export {
|
109
|
+
defineEnterRule,
|
110
|
+
defineTextBlockEnterRule
|
111
|
+
};
|
@@ -0,0 +1,56 @@
|
|
1
|
+
// src/input-rule/index.ts
|
2
|
+
import {
|
3
|
+
Facet,
|
4
|
+
getNodeType,
|
5
|
+
pluginFacet
|
6
|
+
} from "@prosekit/core";
|
7
|
+
import {
|
8
|
+
inputRules,
|
9
|
+
textblockTypeInputRule,
|
10
|
+
wrappingInputRule
|
11
|
+
} from "@prosekit/pm/inputrules";
|
12
|
+
import "@prosekit/pm/model";
|
13
|
+
import "@prosekit/pm/state";
|
14
|
+
function defineInputRule(rule) {
|
15
|
+
return inputRuleFacet.extension([() => rule]);
|
16
|
+
}
|
17
|
+
function defineTextBlockInputRule({
|
18
|
+
regex,
|
19
|
+
type,
|
20
|
+
attrs
|
21
|
+
}) {
|
22
|
+
return inputRuleFacet.extension([
|
23
|
+
({ schema }) => {
|
24
|
+
const nodeType = getNodeType(schema, type);
|
25
|
+
return textblockTypeInputRule(regex, nodeType, attrs);
|
26
|
+
}
|
27
|
+
]);
|
28
|
+
}
|
29
|
+
function defineWrappingInputRule({
|
30
|
+
regex,
|
31
|
+
type,
|
32
|
+
attrs,
|
33
|
+
join
|
34
|
+
}) {
|
35
|
+
return inputRuleFacet.extension([
|
36
|
+
({ schema }) => {
|
37
|
+
const nodeType = getNodeType(schema, type);
|
38
|
+
return wrappingInputRule(regex, nodeType, attrs, join);
|
39
|
+
}
|
40
|
+
]);
|
41
|
+
}
|
42
|
+
var inputRuleFacet = Facet.define({
|
43
|
+
convert: (inputs) => {
|
44
|
+
return (context) => {
|
45
|
+
const rules = inputs.flatMap((callback) => callback(context));
|
46
|
+
return [inputRules({ rules })];
|
47
|
+
};
|
48
|
+
},
|
49
|
+
next: pluginFacet
|
50
|
+
});
|
51
|
+
|
52
|
+
export {
|
53
|
+
defineInputRule,
|
54
|
+
defineTextBlockInputRule,
|
55
|
+
defineWrappingInputRule
|
56
|
+
};
|
package/dist/list/style.css
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/* ../../node_modules/.pnpm/prosemirror-flat-list@0.
|
1
|
+
/* ../../node_modules/.pnpm/prosemirror-flat-list@0.5.0/node_modules/prosemirror-flat-list/dist/style.css */
|
2
2
|
.prosemirror-flat-list {
|
3
3
|
padding: 0;
|
4
4
|
margin-top: 0;
|
@@ -25,25 +25,30 @@
|
|
25
25
|
.prosemirror-flat-list[data-list-kind=bullet] {
|
26
26
|
list-style: disc;
|
27
27
|
}
|
28
|
+
.prosemirror-flat-list[data-list-kind=ordered] {
|
29
|
+
counter-increment: prosemirror-flat-list-counter;
|
30
|
+
}
|
31
|
+
.prosemirror-flat-list[data-list-kind=ordered] > * {
|
32
|
+
contain: style;
|
33
|
+
}
|
28
34
|
.prosemirror-flat-list[data-list-kind=ordered]::before {
|
29
35
|
position: absolute;
|
30
36
|
right: 100%;
|
31
37
|
font-variant-numeric: tabular-nums;
|
32
38
|
content: counter(prosemirror-flat-list-counter, decimal) ". ";
|
33
39
|
}
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
counter-increment: prosemirror-flat-list-counter;
|
38
|
-
}
|
40
|
+
.prosemirror-flat-list[data-list-kind=ordered]:first-child,
|
41
|
+
:not(.prosemirror-flat-list[data-list-kind=ordered]) + .prosemirror-flat-list[data-list-kind=ordered] {
|
42
|
+
counter-reset: prosemirror-flat-list-counter;
|
39
43
|
}
|
40
|
-
@supports
|
41
|
-
.prosemirror-flat-list[data-list-kind=ordered] {
|
42
|
-
counter-
|
43
|
-
counter-increment: prosemirror-flat-list-counter;
|
44
|
+
@supports (counter-set: prosemirror-flat-list-counter 1) {
|
45
|
+
[data-list-order]:is(.prosemirror-flat-list[data-list-kind=ordered]:first-child, :not(.prosemirror-flat-list[data-list-kind=ordered]) + .prosemirror-flat-list[data-list-kind=ordered]) {
|
46
|
+
counter-set: prosemirror-flat-list-counter var(--prosemirror-flat-list-order);
|
44
47
|
}
|
45
|
-
|
46
|
-
|
48
|
+
}
|
49
|
+
@supports not (counter-set: prosemirror-flat-list-counter 1) {
|
50
|
+
[data-list-order]:is(.prosemirror-flat-list[data-list-kind=ordered]:first-child, :not(.prosemirror-flat-list[data-list-kind=ordered]) + .prosemirror-flat-list[data-list-kind=ordered]) {
|
51
|
+
counter-increment: prosemirror-flat-list-counter var(--prosemirror-flat-list-order);
|
47
52
|
}
|
48
53
|
}
|
49
54
|
.prosemirror-flat-list[data-list-kind=task] > .list-marker {
|
@@ -5,6 +5,7 @@ import {
|
|
5
5
|
} from "@prosekit/core";
|
6
6
|
|
7
7
|
// src/autocomplete/plugin.ts
|
8
|
+
import { OBJECT_REPLACEMENT_CHARACTER } from "@prosekit/core";
|
8
9
|
import { Plugin } from "@prosekit/pm/state";
|
9
10
|
import { Decoration, DecorationSet } from "@prosekit/pm/view";
|
10
11
|
|
@@ -22,7 +23,6 @@ function isInsideCode($pos) {
|
|
22
23
|
}
|
23
24
|
return $pos.marks().some((mark) => mark.type.name === "code");
|
24
25
|
}
|
25
|
-
var OBJECT_REPLACEMENT = "\uFFFC";
|
26
26
|
function getPluginState(state) {
|
27
27
|
return pluginKey.getState(state);
|
28
28
|
}
|
@@ -75,10 +75,14 @@ function createAutocompletePlugin({
|
|
75
75
|
const textContent = view.state.doc.textBetween(
|
76
76
|
from,
|
77
77
|
to,
|
78
|
-
|
78
|
+
OBJECT_REPLACEMENT_CHARACTER
|
79
79
|
);
|
80
80
|
const deleteMatch = () => {
|
81
|
-
if (view.state.doc.textBetween(
|
81
|
+
if (view.state.doc.textBetween(
|
82
|
+
from,
|
83
|
+
to,
|
84
|
+
OBJECT_REPLACEMENT_CHARACTER
|
85
|
+
) === textContent) {
|
82
86
|
view.dispatch(view.state.tr.delete(from, to));
|
83
87
|
}
|
84
88
|
};
|
@@ -125,7 +129,7 @@ function calcPluginState(state, rules) {
|
|
125
129
|
Math.max(0, parentOffset - MAX_MATCH),
|
126
130
|
parentOffset,
|
127
131
|
null,
|
128
|
-
|
132
|
+
OBJECT_REPLACEMENT_CHARACTER
|
129
133
|
);
|
130
134
|
for (const rule of rules) {
|
131
135
|
if (!rule.canMatch({ state })) {
|
@@ -1,3 +1,7 @@
|
|
1
|
+
import {
|
2
|
+
defineWrappingInputRule
|
3
|
+
} from "./chunk-DYFRBXUX.js";
|
4
|
+
|
1
5
|
// src/blockquote/index.ts
|
2
6
|
import { defineNodeSpec, union } from "@prosekit/core";
|
3
7
|
function defineBlockquoteSpec() {
|
@@ -12,10 +16,17 @@ function defineBlockquoteSpec() {
|
|
12
16
|
}
|
13
17
|
});
|
14
18
|
}
|
19
|
+
function defineBlockquoteInputRule() {
|
20
|
+
return defineWrappingInputRule({
|
21
|
+
regex: /^>\s/,
|
22
|
+
type: "blockquote"
|
23
|
+
});
|
24
|
+
}
|
15
25
|
function defineBlockquote() {
|
16
|
-
return union([defineBlockquoteSpec()]);
|
26
|
+
return union([defineBlockquoteSpec(), defineBlockquoteInputRule()]);
|
17
27
|
}
|
18
28
|
export {
|
19
29
|
defineBlockquote,
|
30
|
+
defineBlockquoteInputRule,
|
20
31
|
defineBlockquoteSpec
|
21
32
|
};
|
@@ -1,5 +1,15 @@
|
|
1
|
-
export {
|
2
|
-
export {
|
3
|
-
export {
|
4
|
-
export {
|
1
|
+
export { defineCodeBlock_alias_1 as defineCodeBlock } from './_tsup-dts-rollup';
|
2
|
+
export { defineCodeBlockCommands_alias_1 as defineCodeBlockCommands } from './_tsup-dts-rollup';
|
3
|
+
export { defineCodeBlockHighlight_alias_1 as defineCodeBlockHighlight } from './_tsup-dts-rollup';
|
4
|
+
export { HighlightParser_alias_1 as HighlightParser } from './_tsup-dts-rollup';
|
5
|
+
export { defineCodeBlockEnterRule_alias_1 as defineCodeBlockEnterRule } from './_tsup-dts-rollup';
|
6
|
+
export { defineCodeBlockInputRule_alias_1 as defineCodeBlockInputRule } from './_tsup-dts-rollup';
|
7
|
+
export { defineCodeBlockShiki_alias_1 as defineCodeBlockShiki } from './_tsup-dts-rollup';
|
8
|
+
export { defineCodeBlockSpec_alias_1 as defineCodeBlockSpec } from './_tsup-dts-rollup';
|
5
9
|
export { CodeBlockAttrs_alias_1 as CodeBlockAttrs } from './_tsup-dts-rollup';
|
10
|
+
export { shikiBundledLanguagesInfo } from './_tsup-dts-rollup';
|
11
|
+
export { shikiBundledThemesInfo } from './_tsup-dts-rollup';
|
12
|
+
export { ShikiBundledLanguage } from './_tsup-dts-rollup';
|
13
|
+
export { ShikiBundledLanguageInfo } from './_tsup-dts-rollup';
|
14
|
+
export { ShikiBundledTheme } from './_tsup-dts-rollup';
|
15
|
+
export { ShikiBundledThemeInfo } from './_tsup-dts-rollup';
|
@@ -1,55 +1,96 @@
|
|
1
|
-
|
1
|
+
import {
|
2
|
+
defineTextBlockInputRule
|
3
|
+
} from "./chunk-DYFRBXUX.js";
|
4
|
+
import {
|
5
|
+
defineTextBlockEnterRule
|
6
|
+
} from "./chunk-ASTUC4KT.js";
|
7
|
+
|
8
|
+
// src/code-block/code-block.ts
|
9
|
+
import { union } from "@prosekit/core";
|
10
|
+
|
11
|
+
// src/code-block/code-block-commands.ts
|
2
12
|
import {
|
3
13
|
defineCommands,
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
14
|
+
insertNode,
|
15
|
+
setBlockType,
|
16
|
+
setNodeAttrs,
|
17
|
+
toggleNode
|
8
18
|
} from "@prosekit/core";
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
import { PluginKey, ProseMirrorPlugin } from "@prosekit/pm/state";
|
14
|
-
import { DecorationSet } from "@prosekit/pm/view";
|
15
|
-
import { getHighlightDecorations } from "prosemirror-highlightjs";
|
16
|
-
function defineCodeBlockHighlight(options) {
|
17
|
-
const hljs = options.hljs;
|
18
|
-
const plugin = new ProseMirrorPlugin({
|
19
|
-
key,
|
20
|
-
state: {
|
21
|
-
init(_config, state) {
|
22
|
-
const decorations = hljs ? getHighlightDecorations(
|
23
|
-
state.doc,
|
24
|
-
hljs,
|
25
|
-
blockTypes,
|
26
|
-
languageExtractor
|
27
|
-
) : [];
|
28
|
-
return DecorationSet.create(state.doc, decorations);
|
29
|
-
},
|
30
|
-
apply(tr, set) {
|
31
|
-
if (!tr.docChanged) {
|
32
|
-
return set.map(tr.mapping, tr.doc);
|
33
|
-
}
|
34
|
-
const decorations = hljs ? getHighlightDecorations(tr.doc, hljs, blockTypes, languageExtractor) : [];
|
35
|
-
return DecorationSet.create(tr.doc, decorations);
|
36
|
-
}
|
19
|
+
function defineCodeBlockCommands() {
|
20
|
+
return defineCommands({
|
21
|
+
setCodeBlock: (attrs) => {
|
22
|
+
return setBlockType({ type: "codeBlock", attrs });
|
37
23
|
},
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
24
|
+
insertCodeBlock: (attrs) => {
|
25
|
+
return insertNode({ type: "codeBlock", attrs });
|
26
|
+
},
|
27
|
+
toggleCodeBlock: (attrs) => {
|
28
|
+
return toggleNode({ type: "codeBlock", attrs });
|
29
|
+
},
|
30
|
+
setCodeBlockAttrs: (attrs) => {
|
31
|
+
return setNodeAttrs({ type: "codeBlock", attrs });
|
42
32
|
}
|
43
33
|
});
|
44
|
-
return definePlugin(plugin);
|
45
34
|
}
|
46
|
-
|
47
|
-
|
48
|
-
function
|
49
|
-
return
|
35
|
+
|
36
|
+
// src/code-block/code-block-input-rule.ts
|
37
|
+
function defineCodeBlockInputRule() {
|
38
|
+
return defineTextBlockInputRule({
|
39
|
+
regex: /^```(\S*)\s$/,
|
40
|
+
type: "codeBlock",
|
41
|
+
attrs: getAttrs
|
42
|
+
});
|
43
|
+
}
|
44
|
+
function defineCodeBlockEnterRule() {
|
45
|
+
return defineTextBlockEnterRule({
|
46
|
+
regex: /^```(\S*)$/,
|
47
|
+
type: "codeBlock",
|
48
|
+
attrs: getAttrs
|
49
|
+
});
|
50
50
|
}
|
51
|
+
function getAttrs(match) {
|
52
|
+
return { language: match[1] || "" };
|
53
|
+
}
|
54
|
+
|
55
|
+
// src/code-block/code-block-keymap.ts
|
56
|
+
import { defaultBlockAt, defineKeymap } from "@prosekit/core";
|
57
|
+
import { TextSelection } from "@prosekit/pm/state";
|
58
|
+
function defineCodeBlockKeymap() {
|
59
|
+
return defineKeymap({
|
60
|
+
Enter: existCodeBlock
|
61
|
+
});
|
62
|
+
}
|
63
|
+
var existCodeBlock = (state, dispatch) => {
|
64
|
+
if (!state.selection.empty) {
|
65
|
+
return false;
|
66
|
+
}
|
67
|
+
const { $head } = state.selection;
|
68
|
+
const parent = $head.parent;
|
69
|
+
if (parent.isTextblock && parent.type.spec.code && $head.parentOffset === parent.content.size && parent.textContent.endsWith("\n\n")) {
|
70
|
+
const grandParent = $head.node(-1);
|
71
|
+
const insertIndex = $head.indexAfter(-1);
|
72
|
+
const type = defaultBlockAt(grandParent.contentMatchAt(insertIndex));
|
73
|
+
if (!type || !grandParent.canReplaceWith(insertIndex, insertIndex, type)) {
|
74
|
+
return false;
|
75
|
+
}
|
76
|
+
if (dispatch) {
|
77
|
+
const { tr } = state;
|
78
|
+
tr.delete($head.pos - 2, $head.pos);
|
79
|
+
const pos = tr.selection.$head.after();
|
80
|
+
const node = type.createAndFill();
|
81
|
+
if (node) {
|
82
|
+
tr.replaceWith(pos, pos, node);
|
83
|
+
tr.setSelection(TextSelection.near(tr.doc.resolve(pos), 1));
|
84
|
+
dispatch(tr.scrollIntoView());
|
85
|
+
}
|
86
|
+
}
|
87
|
+
return true;
|
88
|
+
}
|
89
|
+
return false;
|
90
|
+
};
|
51
91
|
|
52
|
-
// src/code-block/
|
92
|
+
// src/code-block/code-block-spec.ts
|
93
|
+
import { defineNodeSpec } from "@prosekit/core";
|
53
94
|
function defineCodeBlockSpec() {
|
54
95
|
return defineNodeSpec({
|
55
96
|
name: "codeBlock",
|
@@ -70,49 +111,104 @@ function defineCodeBlockSpec() {
|
|
70
111
|
],
|
71
112
|
toDOM(node) {
|
72
113
|
const attrs = node.attrs;
|
73
|
-
return [
|
74
|
-
"pre",
|
75
|
-
{ "data-language": attrs.language, class: "hljs" },
|
76
|
-
["code", 0]
|
77
|
-
];
|
114
|
+
return ["pre", { "data-language": attrs.language }, ["code", 0]];
|
78
115
|
}
|
79
116
|
});
|
80
117
|
}
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
const getAttrs = (match) => {
|
85
|
-
return { language: match[1] || "" };
|
86
|
-
};
|
87
|
-
return textblockTypeInputRule(/^```(\S*)\s$/, nodeType, getAttrs);
|
88
|
-
});
|
89
|
-
}
|
90
|
-
function defineCodeBlockCommands() {
|
91
|
-
return defineCommands({
|
92
|
-
setCodeBlockLanguage: (language) => (state, dispatch) => {
|
93
|
-
const pos = state.selection.$from.before();
|
94
|
-
const codeBlock = state.doc.nodeAt(pos);
|
95
|
-
if (!codeBlock || codeBlock.type.name !== "codeBlock") {
|
96
|
-
return false;
|
97
|
-
}
|
98
|
-
const { tr } = state;
|
99
|
-
tr.setNodeMarkup(pos, void 0, { language });
|
100
|
-
dispatch == null ? void 0 : dispatch(tr);
|
101
|
-
return true;
|
102
|
-
}
|
103
|
-
});
|
104
|
-
}
|
105
|
-
function defineCodeBlock(options) {
|
118
|
+
|
119
|
+
// src/code-block/code-block.ts
|
120
|
+
function defineCodeBlock() {
|
106
121
|
return union([
|
107
122
|
defineCodeBlockSpec(),
|
108
123
|
defineCodeBlockInputRule(),
|
109
|
-
|
124
|
+
defineCodeBlockEnterRule(),
|
125
|
+
defineCodeBlockKeymap(),
|
110
126
|
defineCodeBlockCommands()
|
111
127
|
]);
|
112
128
|
}
|
129
|
+
|
130
|
+
// src/code-block/code-block-highlight.ts
|
131
|
+
import { definePlugin } from "@prosekit/core";
|
132
|
+
import { createHighlightPlugin } from "prosemirror-highlight";
|
133
|
+
function defineCodeBlockHighlight({
|
134
|
+
parser
|
135
|
+
}) {
|
136
|
+
return definePlugin(
|
137
|
+
createHighlightPlugin({ parser, nodeTypes: ["codeBlock"] })
|
138
|
+
);
|
139
|
+
}
|
140
|
+
|
141
|
+
// src/code-block/shiki-parser.ts
|
142
|
+
import { createParser } from "prosemirror-highlight/shiki";
|
143
|
+
function createHighlighterLoader() {
|
144
|
+
let highlighterPromise;
|
145
|
+
let highlighter;
|
146
|
+
const loadLangs = /* @__PURE__ */ new Set();
|
147
|
+
return function highlighterLoader(lang, options) {
|
148
|
+
if (!highlighterPromise) {
|
149
|
+
highlighterPromise = import("./shiki-import-25BJYIO2.js").then(({ getHighlighter }) => {
|
150
|
+
return getHighlighter(options);
|
151
|
+
}).then((h) => {
|
152
|
+
highlighter = h;
|
153
|
+
});
|
154
|
+
return { promise: highlighterPromise };
|
155
|
+
}
|
156
|
+
if (!highlighter) {
|
157
|
+
return { promise: highlighterPromise };
|
158
|
+
}
|
159
|
+
if (!loadLangs.has(lang)) {
|
160
|
+
const promise = highlighter.loadLanguage(lang).then(() => {
|
161
|
+
loadLangs.add(lang);
|
162
|
+
}).catch((error) => {
|
163
|
+
console.warn(`Failed to load language '${lang}'`, error);
|
164
|
+
});
|
165
|
+
return { promise };
|
166
|
+
}
|
167
|
+
return { highlighter };
|
168
|
+
};
|
169
|
+
}
|
170
|
+
function createLazyParser(highlighterOptions) {
|
171
|
+
let parser;
|
172
|
+
const highlighterLoader = createHighlighterLoader();
|
173
|
+
return function lazyParser(options) {
|
174
|
+
const language = options.language || "";
|
175
|
+
const { highlighter, promise } = highlighterLoader(
|
176
|
+
language,
|
177
|
+
highlighterOptions
|
178
|
+
);
|
179
|
+
if (!highlighter) {
|
180
|
+
return promise || [];
|
181
|
+
}
|
182
|
+
if (!parser) {
|
183
|
+
parser = createParser(highlighter);
|
184
|
+
}
|
185
|
+
return parser(options);
|
186
|
+
};
|
187
|
+
}
|
188
|
+
|
189
|
+
// src/code-block/code-block-shiki.ts
|
190
|
+
function defineCodeBlockShiki({
|
191
|
+
themes = ["one-dark-pro"],
|
192
|
+
langs = ["text"],
|
193
|
+
langAlias = {}
|
194
|
+
} = {}) {
|
195
|
+
const parser = createLazyParser({ themes, langs, langAlias });
|
196
|
+
return defineCodeBlockHighlight({ parser });
|
197
|
+
}
|
198
|
+
|
199
|
+
// src/code-block/shiki-bundle.ts
|
200
|
+
import {
|
201
|
+
bundledLanguagesInfo,
|
202
|
+
bundledThemesInfo
|
203
|
+
} from "shiki";
|
113
204
|
export {
|
114
205
|
defineCodeBlock,
|
115
206
|
defineCodeBlockCommands,
|
207
|
+
defineCodeBlockEnterRule,
|
208
|
+
defineCodeBlockHighlight,
|
116
209
|
defineCodeBlockInputRule,
|
117
|
-
|
210
|
+
defineCodeBlockShiki,
|
211
|
+
defineCodeBlockSpec,
|
212
|
+
bundledLanguagesInfo as shikiBundledLanguagesInfo,
|
213
|
+
bundledThemesInfo as shikiBundledThemesInfo
|
118
214
|
};
|
@@ -0,0 +1,5 @@
|
|
1
|
+
export { defineEnterRule } from './_tsup-dts-rollup';
|
2
|
+
export { defineTextBlockEnterRule } from './_tsup-dts-rollup';
|
3
|
+
export { EnterRuleHandler } from './_tsup-dts-rollup';
|
4
|
+
export { EnterRuleOptions } from './_tsup-dts-rollup';
|
5
|
+
export { TextBlockEnterRuleOptions } from './_tsup-dts-rollup';
|
@@ -1,16 +1,18 @@
|
|
1
|
+
import {
|
2
|
+
defineTextBlockInputRule
|
3
|
+
} from "./chunk-DYFRBXUX.js";
|
4
|
+
|
1
5
|
// src/heading/index.ts
|
2
6
|
import {
|
3
7
|
defineCommands,
|
4
|
-
defineInputRule,
|
5
8
|
defineKeymap,
|
6
9
|
defineNodeSpec,
|
7
|
-
getNodeType,
|
8
10
|
insertNode,
|
9
11
|
setBlockType,
|
10
12
|
toggleNode,
|
11
|
-
union
|
13
|
+
union,
|
14
|
+
withSkipCodeBlock
|
12
15
|
} from "@prosekit/core";
|
13
|
-
import { textblockTypeInputRule } from "@prosekit/pm/inputrules";
|
14
16
|
function defineHeadingSpec() {
|
15
17
|
return defineNodeSpec({
|
16
18
|
name: "heading",
|
@@ -33,22 +35,26 @@ function defineHeadingSpec() {
|
|
33
35
|
}
|
34
36
|
function defineHeadingKeymap() {
|
35
37
|
return defineKeymap({
|
36
|
-
"mod-1":
|
37
|
-
"mod-2":
|
38
|
-
"mod-3":
|
39
|
-
"mod-4":
|
40
|
-
"mod-5":
|
41
|
-
"mod-6":
|
38
|
+
"mod-1": toggleHeadingKeybinding(1),
|
39
|
+
"mod-2": toggleHeadingKeybinding(2),
|
40
|
+
"mod-3": toggleHeadingKeybinding(3),
|
41
|
+
"mod-4": toggleHeadingKeybinding(4),
|
42
|
+
"mod-5": toggleHeadingKeybinding(5),
|
43
|
+
"mod-6": toggleHeadingKeybinding(6)
|
42
44
|
});
|
43
45
|
}
|
46
|
+
function toggleHeadingKeybinding(level) {
|
47
|
+
return withSkipCodeBlock(toggleNode({ type: "heading", attrs: { level } }));
|
48
|
+
}
|
44
49
|
function defineHeadingInputRule() {
|
45
|
-
return
|
46
|
-
|
47
|
-
|
50
|
+
return defineTextBlockInputRule({
|
51
|
+
regex: /^(#{1,6})\s$/,
|
52
|
+
type: "heading",
|
53
|
+
attrs: (match) => {
|
48
54
|
var _a, _b;
|
49
55
|
const level = (_b = (_a = match[1]) == null ? void 0 : _a.length) != null ? _b : 1;
|
50
56
|
return { level };
|
51
|
-
}
|
57
|
+
}
|
52
58
|
});
|
53
59
|
}
|
54
60
|
function defineHeadingCommands() {
|