@prosekit/extensions 0.0.7 → 0.0.8

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.
@@ -0,0 +1,27 @@
1
+ import * as _prosekit_core from '@prosekit/core';
2
+ import { HLJSApi } from 'highlight.js';
3
+
4
+ interface CodeBlockAttrs {
5
+ language?: string;
6
+ }
7
+
8
+ declare function addCodeBlockSpec(): _prosekit_core.Extension<{
9
+ NODES: "codeBlock";
10
+ }>;
11
+ declare function addCodeBlockInputRule(): _prosekit_core.Extension<_prosekit_core.ExtensionTyping<string, string, _prosekit_core.CommandArgs>>;
12
+ declare function addCodeBlockCommands(): _prosekit_core.Extension<{
13
+ COMMAND_ARGS: {
14
+ setCodeBlockLanguage: [language: string];
15
+ };
16
+ }>;
17
+ /** @public */
18
+ declare function addCodeBlock(options?: {
19
+ hljs?: HLJSApi;
20
+ }): _prosekit_core.Extension<{
21
+ NODES: "codeBlock";
22
+ COMMAND_ARGS: {
23
+ setCodeBlockLanguage: [language: string];
24
+ };
25
+ }>;
26
+
27
+ export { CodeBlockAttrs, addCodeBlock, addCodeBlockCommands, addCodeBlockInputRule, addCodeBlockSpec };
@@ -0,0 +1,123 @@
1
+ // src/code-block/index.ts
2
+ import {
3
+ addCommands,
4
+ addInputRule,
5
+ addNodeSpec,
6
+ defineExtension,
7
+ getNodeType
8
+ } from "@prosekit/core";
9
+ import { textblockTypeInputRule } from "@prosekit/pm/inputrules";
10
+
11
+ // src/code-block/code-block-highlight.ts
12
+ import { addPlugin } from "@prosekit/core";
13
+ import { PluginKey, ProseMirrorPlugin } from "@prosekit/pm/state";
14
+ import { DecorationSet } from "@prosekit/pm/view";
15
+ import { getHighlightDecorations } from "prosemirror-highlightjs";
16
+ function addCodeBlockHighlight(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
+ }
37
+ },
38
+ props: {
39
+ decorations(state) {
40
+ return key.getState(state);
41
+ }
42
+ }
43
+ });
44
+ return addPlugin({
45
+ plugins: () => {
46
+ return [plugin];
47
+ }
48
+ });
49
+ }
50
+ var key = new PluginKey("prosekit-code-block-highlight");
51
+ var blockTypes = ["codeBlock"];
52
+ function languageExtractor(node) {
53
+ return node.attrs.language || "javascript";
54
+ }
55
+
56
+ // src/code-block/index.ts
57
+ function addCodeBlockSpec() {
58
+ return addNodeSpec({
59
+ name: "codeBlock",
60
+ content: "text*",
61
+ group: "block",
62
+ code: true,
63
+ defining: true,
64
+ marks: "",
65
+ attrs: { language: { default: "" } },
66
+ parseDOM: [
67
+ {
68
+ tag: "pre",
69
+ preserveWhitespace: "full",
70
+ getAttrs: (node) => ({
71
+ language: node.getAttribute("data-language") || ""
72
+ })
73
+ }
74
+ ],
75
+ toDOM(node) {
76
+ const attrs = node.attrs;
77
+ return [
78
+ "pre",
79
+ { "data-language": attrs.language, class: "hljs" },
80
+ ["code", 0]
81
+ ];
82
+ }
83
+ });
84
+ }
85
+ function addCodeBlockInputRule() {
86
+ return addInputRule(({ schema }) => {
87
+ const nodeType = getNodeType(schema, "codeBlock");
88
+ const getAttrs = (match) => {
89
+ return { language: match[1] || "" };
90
+ };
91
+ const inputRule = textblockTypeInputRule(/^```(\S*)\s$/, nodeType, getAttrs);
92
+ return [inputRule];
93
+ });
94
+ }
95
+ function addCodeBlockCommands() {
96
+ return addCommands({
97
+ setCodeBlockLanguage: (language) => (state, dispatch) => {
98
+ const pos = state.selection.$from.before();
99
+ const codeBlock = state.doc.nodeAt(pos);
100
+ if (!codeBlock || codeBlock.type.name !== "codeBlock") {
101
+ return false;
102
+ }
103
+ const { tr } = state;
104
+ tr.setNodeMarkup(pos, void 0, { language });
105
+ dispatch == null ? void 0 : dispatch(tr);
106
+ return true;
107
+ }
108
+ });
109
+ }
110
+ function addCodeBlock(options) {
111
+ return defineExtension([
112
+ addCodeBlockSpec(),
113
+ addCodeBlockInputRule(),
114
+ addCodeBlockHighlight({ hljs: options == null ? void 0 : options.hljs }),
115
+ addCodeBlockCommands()
116
+ ]);
117
+ }
118
+ export {
119
+ addCodeBlock,
120
+ addCodeBlockCommands,
121
+ addCodeBlockInputRule,
122
+ addCodeBlockSpec
123
+ };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prosekit/extensions",
3
3
  "type": "module",
4
- "version": "0.0.7",
4
+ "version": "0.0.8",
5
5
  "private": false,
6
6
  "author": {
7
7
  "name": "ocavue",
@@ -50,6 +50,11 @@
50
50
  "import": "./dist/prosekit-extensions-code.js",
51
51
  "default": "./dist/prosekit-extensions-code.js"
52
52
  },
53
+ "./code-block": {
54
+ "types": "./dist/prosekit-extensions-code-block.d.ts",
55
+ "import": "./dist/prosekit-extensions-code-block.js",
56
+ "default": "./dist/prosekit-extensions-code-block.js"
57
+ },
53
58
  "./heading": {
54
59
  "types": "./dist/prosekit-extensions-heading.d.ts",
55
60
  "import": "./dist/prosekit-extensions-heading.js",
@@ -98,7 +103,9 @@
98
103
  "dependencies": {
99
104
  "@prosekit/core": "^0.0.7",
100
105
  "@prosekit/pm": "^0.0.3",
101
- "prosemirror-flat-list": "^0.4.1"
106
+ "highlight.js": "^11.8.0",
107
+ "prosemirror-flat-list": "^0.4.1",
108
+ "prosemirror-highlightjs": "^0.9.1"
102
109
  },
103
110
  "devDependencies": {
104
111
  "@prosekit/dev": "*",
@@ -128,6 +135,9 @@
128
135
  "code": [
129
136
  "./dist/prosekit-extensions-code.d.ts"
130
137
  ],
138
+ "code-block": [
139
+ "./dist/prosekit-extensions-code-block.d.ts"
140
+ ],
131
141
  "heading": [
132
142
  "./dist/prosekit-extensions-heading.d.ts"
133
143
  ],